Community程式設計與開發github.com

create-cmpnnt:在org-babel文式Rust專案中建立新元件

在採用org-babel文式風格的Rust專案(如ads-back、ads-front)中,建立新的元件、指令、程序、CLI子命令、Yew元件、模組或crate,並遵循預定義的模式(一個指令一個org檔案、宣告前於定義的noweb區塊、每個關注點一個標題)。

create-cmpnnt:在org-babel文式Rust專案中建立新元件 是什麼?

此技能專門為以org-babel文式程式設計風格管理的Rust專案建立新元件。它支援四種不同情境:在現有crate中新增程序/指令(A)、在CLI中新增子命令(B)、新增Yew元件(C)以及建立全新的crate(D)。使用者提出要求後,技能會先判斷合適的變體,再根據目標目錄中現有org檔案的語言來決定新檔案使用的語言(烏克蘭語、英語或詢問使用者)。每個新檔案都遵循統一的骨架:包含`:tangle`目標的單一org檔案,結構上分為「宣告」和「定義」兩大部分,每個邏輯步驟對應各自的標題和noweb區塊,確保關注點分離。對於新crate,技能還會處理工作區`config.org`的註冊、建立最小`main.org`、以及管理相依性與環境變數。最後,每次編輯後都會自動執行`emacsclient`進行tangle、`cargo check`確保無錯誤與警告、執行`org-lint`檢查,並對散文進行格式調整,以維持專案的品質標準。

相容平台✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/EugineKosenko/majordom/tree/HEAD/skills/create-cmpnnt

Installed? Explore more 程式設計與開發 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

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 檔案:

  1. #+title: ... — 元件名稱(使用步驟 1 決定的語言)。

  2. 如有需要,加入指向規格的段落([[https://...][специфікацію]]),如 create-card.org 所示。

  3. 第一個標題(* Модуль / * Файл / * Крейт — 名稱參考同一目錄中的相鄰檔案,不嚴格固定),包含骨架區塊:

    #+begin_src rust :noweb yes :mkdirp yes :tangle src/ІМ'Я_ФАЙЛУ.rs
      <<Декларації>>
    
      <<Визначення>>
    #+end_src
    
  4. 骨架之後緊接 * Виконавець 章節(適用於程序/指令),包含兩個區塊::noweb-ref Декларації(匯入,包括來自 ads_api 的 Request/Response 類型)和 :noweb-ref Визначення(函式本身 pub fn run(...),其主體主要包含 <<Дії>> 內的 db::cnnctn().transaction(...),如果需要事務)。

  5. 每個後續的邏輯細節(檢查、取得欄位、插入表格等)都使用單獨的 */** 標題,並帶有各自的 :noweb-ref Декларації(如果需要新的 use)和 :noweb-ref Дії — 按此順序(宣告在使用之前,與其他部分一致)。不要將所有邏輯集中在一個區塊中——每個具意義的步驟都應該有自己的標題,如 create-card.org(一個程序有超過 15 個獨立標題)。

  6. 如果一個步驟產生了輔助函式(例如 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 中的註冊

  1. 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。

  2. 在根目錄 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
    
  3. 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 原始檔進行重大編輯後:

  1. 實際透過 emacsclient --eval 進行 tangle(切勿手動撰寫 .rs/.toml/.env.example 的內容——參見相關的全局規則)。
  2. cargo check -p КРЕЙТ(對於 ads-front 添加 --target wasm32-unknown-unknown)——零警告和錯誤。
  3. 對修改後的檔案執行 org-lint 技能,並立即修正「ПЕВНІ」發現的項目,「потребує перевірки」的項目則進行審查。
  4. 對於剛撰寫/修改的散文,透過同一個 emacsclient 執行 (font-lock-ensure) 和 org-fill-paragraph,不要手動操作。

在完成上述四個步驟之前,請勿將元件顯示為準備就緒。

Individual skills in this repo

This repo contains 4 individual skills — each has its own dedicated page.

EugineKosenko/majordom

Analyse a Figma .fig file kept in a project's spcfctn/ui/draft. Unpacks and decodes it offline (kiwi), breaks it into sections, screens, text rows and rasters, writes the analysis to spcfctn/ui/*.md, then fetches the author's comments through the figma MCP by link, binds them to screens by geometry, checks that the comments agree with the content of the file and asks the user to clarify what does not. Use when the user asks to analyse, decode or re-read a .fig file or Figma wireframes, or to refresh spcfctn/ui after a new export.

EugineKosenko/majordom

Керування сесіями claude-code-ide.el у живому Emacs через emacsclient headless — старт/continue/resume без блокуючих запитів, безпечна зупинка, перемикання permission-mode і auto-accept, навігація в інтерактивних picker'ах. Використовуй, коли сесія "Мажордом" має підняти, продовжити, зупинити чи інспектувати сесію claude-code-ide для іншого проєкту.

EugineKosenko/majordom

Bootstrap a new project in this user's standard layout — .claude-root, .dir-locals.el (root: org-link abbreviation), code/, spcfctn/code/ (with its own git repository) and a .claude/ directory with its own git repository and a CLAUDE.md that fixes the project's prose language and its short two-letter project code (chosen by the user from options the agent proposes) — and translate any files already present into that language. Use whenever the user asks to create, start, set up, initialise or "оформити" a new project (or to bring an existing bare directory to the standard layout).

EugineKosenko/majordom

Check org/md prose in this user's projects against the prose-formatting conventions in ~/.claude/rules/org-babel.md (~...~ vs =...= markup, acronym casing, /.../ glossary terms, real org-links vs italics/plain text, spaces around / between two markups, trailing newline, fill-column). Use proactively right after editing prose paragraphs in an .org or .md file (in place of manually re-deriving each rule from memory), and whenever the user explicitly asks to check/lint org rules or compares the request to running clippy.

相關技能