create-cmpnnt
用於在文式 org-babel 風格專案中建立新元件(cmpnnt)——指令、程序、子命令、Yew 元件或整個 crate 的技能。此風格記錄於 ~/.claude/CLAUDE.md。範例取自實際檔案 code/ads-back(crates/api/create-card.org、crates/api/retrve-card.org、crates/cli/main.org、crates/svc/main.org、根目錄 config.org、env.org)。
步驟 0 — 判斷變體
預設情況下(沒有明確參數時),根據使用者要求本身判斷變體;若不夠明確,則透過 AskUserQuestion 提出釐清問題,而非默默猜測:
- A. 在現有 crate 中新增程序/指令 — 典型情況(例如在
crates/api中新增rocket處理器、在crates/db中新增庫函式)。一個新的 org 檔案,無需修改config.org。 - B. 新增現有
CLI的子命令 — 新建<子命令>.org檔案(模組)並寫入該 crate 現有的main.org(mod、Command:Елементи、Варіанти)。 - C.
Yew元件(ads-front)— 結構接近crates/app/marker.org:包含「屬性」章節,內含元件屬性和Html區塊。採用相同骨架(宣告前於定義、一個關注點一個標題),但區塊用語不同。 - D. 新建 crate(「聯邦
cargo」)— 當元件邏輯上不屬於任何現有 crate 時。除了元件本身,還需要新 crate 的config.org、env.org、main.org,並在根目錄config.org中註冊(見步驟 4)。
不要「以防萬一」指定變體 D——僅在使用者明確要求新建 crate,或沒有任何現有 crate 邏輯上適合(且經使用者確認)時使用。
步驟 1 — org 檔案的語言
語言取決於具體情況,並非固定不變。在建立檔案前,請查看目標目錄中相鄰 org 檔案的語言(code/ads-back/env.org 為英文,多數 crates/api/*.org 為烏克蘭文):如果目錄有明確的多數語言,則使用該語言;如果是新目錄或相鄰檔案的語言不明確,則提出一個問題詢問使用者,不要猜測。
步驟 2 — 共用骨架(所有變體)
無論哪種變體,每個帶有自有 :tangle 目標的新 org 檔案:
-
#+title: ...— 元件名稱(使用步驟 1 決定的語言)。 -
如有需要,加入指向規格的段落(
[[https://...][специфікацію]]),如create-card.org所示。 -
第一個標題(
* Модуль/* Файл/* Крейт— 名稱參考同一目錄中的相鄰檔案,不嚴格固定),包含骨架區塊:#+begin_src rust :noweb yes :mkdirp yes :tangle src/ІМ'Я_ФАЙЛУ.rs <<Декларації>> <<Визначення>> #+end_src -
骨架之後緊接
* Виконавець章節(適用於程序/指令),包含兩個區塊::noweb-ref Декларації(匯入,包括來自ads_api的Request/Response類型)和:noweb-ref Визначення(函式本身pub fn run(...),其主體主要包含<<Дії>>內的db::cnnctn().transaction(...),如果需要事務)。 -
每個後續的邏輯細節(檢查、取得欄位、插入表格等)都使用單獨的
*/**標題,並帶有各自的:noweb-ref Декларації(如果需要新的use)和:noweb-ref Дії— 按此順序(宣告在使用之前,與其他部分一致)。不要將所有邏輯集中在一個區塊中——每個具意義的步驟都應該有自己的標題,如create-card.org(一個程序有超過 15 個獨立標題)。 -
如果一個步驟產生了輔助函式(例如
create-card.org中的upsert_phone),則使用自己的:noweb-ref Визначення作為函式簽名,主體透過自己的命名noweb-ref(upsert-phone:Дії)實現,並使用**/***子標題來區分其中的每個動作。
變體 B(CLI 子命令)的差別在於沒有新的骨架區塊——取而代之的是,在現有的 main.org 中新增三個 noweb 區塊,而無需新的骨架標題::noweb-ref Декларації(mod нова_підкоманда;)、:noweb-sep ",\n" :noweb-ref Command:Елементи(Command 列舉的變體及其參數欄位)以及 :noweb yes :noweb-sep ",\n" :noweb-ref Варіанти(Command::Варіант { ... } => crate::модуль::run(...))——每個都在各自的 * 標題下,以動作命名(例如 * Створення організації),而實現本身則在根據共用骨架建立的單獨子命令 org 檔案中(步驟 2,變體 A)。
變體 C(Yew 元件)的差別在於章節名稱:使用「Властивості」(struct ...Props,一個屬性對應一個 ** 子章節,:noweb-sep ",\n" :noweb-ref ІмʼяProps:Властивості),以及「Компонент」章節(#[function_component(...)],主體包含 <<Ім'я:Стан>>、<<Ім'я:Ефекти>>、<<Ім'я:Обробники>>、html! { <<Ім'я:Html>> })。請查看 code/ads-front/crates/app/marker.org 作為此變體的實際範例。
步驟 3 — 典型的 main 函式(變體 D,起始)
新 crate 的 main.org 首版應儘量簡單——沒有錯誤處理、沒有 Result、沒有 async、沒有 logger/env 初始化,除非有具體需求:
#+title: НАЗВА КРЕЙТА
* Файл
#+begin_src rust :noweb yes :mkdirp yes :tangle src/main.rs
<<Декларації>>
<<Визначення>>
fn main() {
<<Дії>>
}
#+end_src
<<Дії>> 最初可以是完全空的(新 crate 尚未執行任何操作)——這是正常的起始步驟,後續的標題會逐步填充它,如同 crates/cli/main.org/crates/svc/main.org。錯誤處理(Result、?)、async、dotenv/env_logger 初始化等,應在之後透過單獨的標題添加,僅當特定步驟實際需要時——不要預先添加。
步驟 4 — 新 crate:config.org 與聯邦 config.org 中的註冊
-
crates/НАЗВА/config.org— crate 的檔案(參見crates/cli/config.org範例):#+title: =Cargo=-файл * Файл #+begin_src toml :noweb yes :tangle Cargo.toml [package] name = "НАЗВА" version = "0.1.0" edition = "2021" [dependencies] <<Залежності>> #+end_src每個相依性使用單獨的
* =назва_крейта=標題,並帶有:noweb-ref Залежності(назва = { workspace = true }),按CLAUDE.md的規則排序(第三方 →forge→ 專案 crate,否則按字母順序)。* Версія =Rust=/* Локальна конфігурація(rust-toolchain.toml/.cargo/config.toml)區塊僅在此目錄已有此慣例時才從相鄰的config.org複製——如果沒有 crate 這樣做,則不要「以防萬一」添加。如果複製了這些區塊,檔案會變成多重目標(多個不同的:tangle),因此所有 noweb 區塊(包括Залежності)都應使用前綴名稱(Cargo:Залежності、config:Визначення等,參見 CLAUDE.md)——如同下面的根目錄config.org。 -
在根目錄
config.org(工作區)中新增* =НАЗВА=標題,包含兩個區塊——類似根目錄中的* =db=/* =api=章節:#+begin_src toml :noweb-sep ",\n" :noweb-ref Cargo:Крейти "crates/НАЗВА" #+end_src #+begin_src toml :noweb-ref Cargo:Залежності НАЗВА = { path = "crates/НАЗВА" } #+end_src -
env.org— 如果新 crate 沒有引入自己的環境變數,則無需修改。如果引入了,且專案已有共用的根目錄env.org,則在其中新增一個帶有自己:noweb-ref的新*章節(如* Database access/* =JWT= parameters),而不是建立單獨的檔案。僅當新 crate 是獨立部署(擁有自己的.env,而非同一個進程)且沒有共用的env.org時,才建立單獨的env.org。在任何情況下,第一個env.org都可以完全沒有具體變數(можна взагалі без значень, тільки головний файл)——僅作為骨架:#+title: =dotenv= file * Configuration file #+begin_src conf :noweb yes :tangle .env.example <<Визначення>> #+end_src並在後續實際變數出現時,透過具體的
* =Х= parameters章節逐步填充。
步驟 5 — 每次修改後的檢查
在每次對 org 原始檔進行重大編輯後:
- 實際透過
emacsclient --eval進行tangle(切勿手動撰寫.rs/.toml/.env.example的內容——參見相關的全局規則)。 cargo check -p КРЕЙТ(對於ads-front添加--target wasm32-unknown-unknown)——零警告和錯誤。- 對修改後的檔案執行
org-lint技能,並立即修正「ПЕВНІ」發現的項目,「потребує перевірки」的項目則進行審查。 - 對於剛撰寫/修改的散文,透過同一個
emacsclient執行(font-lock-ensure)和org-fill-paragraph,不要手動操作。
在完成上述四個步驟之前,請勿將元件顯示為準備就緒。