A-ISL 編譯(代理內編譯器)
你從 ISL 生成 bin-<stackId>/(預設 stack react-js → bin-react-js)。允許使用 Builder / queue / packet / lock / preflight CLI。禁止使用付費 isl-generator / Gemini / OpenAI。
可與任何載入此技能的編碼代理(Cursor、Claude Code、GitHub Copilot 等)搭配使用。使用與專案根目錄相同的 npm 執行環境。
用戶請求閘道(不可協商)
對 bin 的修改僅能透過 compile 進行,且必須是用戶明確請求。
- 僅當人類明確要求編譯(例如
compila、/a-isl-compile、“build bin”、“regenerate implementation”、“run compile for …”)時,才進入此技能 / 寫入bin-*。 - 僅包含規格訊息、自然語言功能想法或 UX 調整但沒有明確編譯請求的訊息,不得觸發實作寫入——請將它們發送給 a-isl-spec-author(或規格階段)並停止。
- 請勿在規格編輯後「因為示範會壞掉」或「為了完成循環」而自動編譯。
- 實作資料夾僅透過此 Compile 工作流程(packet → write → lock)更新。請勿將
bin-*下的臨時修補視為 A-ISL 路徑,除非人類明確要求一次性例外。 - 如果人類尚未要求編譯:拒絕編輯
bin-*並告知他們需要明確的編譯請求。
使用時機
- 人類完成規格階段並要求建置/編譯/重新生成
- 因人類要求 Compile,將專案的
bin-<stack>/與更新後的*.isl.md對齊
嚴格限制
- 不要執行付費生成器或 API 程式碼生成客戶端。
- 你根據 packet 的
targetPath在 stack bin 目錄下撰寫每個實作檔案(完整程式碼,無 TODO 佔位)。 - 僅更新
gen-lock.json不是編譯——僅在bin-<stack>/下實際寫入後才鎖定。 - 如果 ISL 模糊或矛盾:停止並告知用戶返回 a-isl-spec-author。請勿發明需求。
- 請勿在 Compile 期間開啟
vendor/isl-spec/(僅限 Spec Agent),除非用戶明確要求。 - 偏好透過
queue --next+ 輕量 packet 一次處理一個單元。預設情況下不要載入完整的 queue JSON 或完整的.build.md。
輸出目錄
預設:bin-<stackId> 位於規格旁(例如 --stack react-js → bin-react-js)。必要時使用 --bin 覆蓋。同一個工作區可以同時容納 bin-react-js 和 bin-csharp。
低 token 工作流程(預設)
preflight → builder (一次) → 循環: queue --next → packet → [測試後] 寫入 impl → (批次) lock
→ (可選) npm run verify
0. Preflight(一次)
npm run preflight -- --root examples/connect-four-workspace
僅結構/圖表/lint 檢查——不驗證實作正確性。如果失敗,請在編譯前修復 Spec/lint。
1. Builder(每批次一次)
npm run builder -- examples/connect-four-workspace
拓撲順序位於 build/build-manifest.json(腳本擁有)。你不要發明編譯順序。
2. 僅下一個單元
npm run queue -- --root examples/connect-four-workspace --next
在循環中的每次 queue/packet 呼叫傳遞 --stack <id>(預設 react-js → bin-react-js/):
npm run queue -- --root <project> --next --stack blazor
npm run packet -- --root <project> --next --stack blazor
ID:react-js、blazor、winforms、csharp(僅函式庫)、python、python-fastapi。可選 --bin <path> 覆蓋輸出資料夾。
針對性重新編譯——當人類要求重新生成一個或幾個單元時(鎖定會跳過它們):
npm run queue -- --root <project> --next --only dungeon --stack react-js
npm run packet -- --root <project> --next --only dungeon --stack react-js
# 或按名稱 packet:
npm run packet -- --root <project> --only dungeon --stack react-js
--only 可以重複。Token:單元基礎名稱(dungeon)、dungeon.isl.md 或 ./dungeon。queue JSON 中的理由:force-only。當僅請求子集時,不要使用工作區範圍的 --force。
使用 next.buildFile / next.targetPath。如果 next 是 null,則停止(佇列為空)。
僅當人類要求概覽時才使用完整的 --json 佇列。
3. 輕量 packet(預設上下文)
npm run packet -- --root examples/connect-four-workspace --build-file "<abs.build.md>"
# 或
npm run packet -- --root examples/connect-four-workspace --next
Packet 包含:此單元的 SOURCE markdown、目標路徑、stack 約束子集、同一 bin-<stack>/ 中依賴檔案的路徑。
它排除內嵌的 .ref.md 區塊。
從 packet 寫入檔案(請參閱下面的 EXT-001 順序)。從列出的路徑匯入真實的依賴模組。
3a. 依賴宣告查詢 (EXT-002)
當你在寫入此單元前需要依賴符號(方法/函數/類型)的確切宣告時:
npm run lookup-decl -- --stack <id> --name <SpecOrCallName> --file <abs-or-rel-bin-path> [--workspace <project>]
# 或掃描 bin 資料夾(生成的 *.test.* / *.Tests.cs 會被跳過,除非使用 --include-tests):
npm run lookup-decl -- --stack <id> --name <Name> --dir <bin-<stack>> --workspace <project>
- 退出碼 0 = 命中,2 =
no_match,3 = 用法/路徑/stack 錯誤。 - 讀取 stdout JSON:使用
candidates[selected](signatureText、leadingContext、enclosingType,每個候選項的kind)。不要發明正則表達式或開啟整個依賴檔案來搜尋簽名。 - 模式和
callSymbol位於 stack 配置中(declaration-patterns.ts/stacks.config.ts)——技能只能調用此 CLI。 - 路徑必須解析到
--workspace和bin-*片段下(符號連結逃逸 → 退出碼 3)。
3b. EXT-001 生成的測試(當 Spec 選擇加入時)
可驗證情境 = 同時具有 `id: …` 和 - Call: … 的測試場景(請參見 docs/isl-agent-profile.md)。Spec Author 決定;任何角色都可以選擇加入。
每個單元,同一回合:
- 如果 SOURCE 有 ≥1 個合格情境:先覆蓋生成的測試檔案(路徑 = 實作基礎名稱 +
stack.verify.testSuffix,位於同一bin-<stack>/下,例如domain-sheet.test.js/domain-sheet.Tests.cs)。僅從 Spec 場景 + Signature 斷言;將Call映射到stack.verify.callSymbol(as-is|pascal-case|snake-case,位於stacks.config.ts)。react-js Domain/Logic: 每個 Call 必須是命名匯出;測試必須import { <Call> } from "./<file>"——永遠不要import Unit from …; Unit().<Call>()。如果工作區有bench/call-map.json,從"<unit>.<Call>"解析export並匯入該名稱(與凍結分數相同的契約)。不要為純文字場景發明案例;不要在測試檔案寫入前開啟/編輯 impl 檔案。 - 然後在
targetPath寫入 impl,使其能滿足那些測試和 Contract。react-js Domain/Logic: 為每個 Capability 使用export function <Call>/export const <Call>;禁止使用預設匯出工廠包裝 capabilities。 - 如果沒有任何合格情境:僅寫入 impl;如果該單元仍有先前生成的測試檔案,則刪除它。Domain/Logic 仍使用命名 capability 匯出。
- 如果 verify 失敗:你可以
--only重新編譯 僅 impl(保留測試檔案)。不得重寫測試以使其通過(包括將命名匯入改為預設工廠)。如果情境/Call/預期結果看起來有誤 → 停止並將用戶發送給 a-isl-spec-author。 - 在 Domain/Logic(或其他合格)批次之後,你可以建議
npm run verify -- --root <project> --stack <id>;不要要求綠色通過才能鎖定。Lock 僅作為建置雜湊快取。
規格變更後的完整單元重新編譯:根據目前 Spec 重新生成整個測試檔案,然後 impl(不是與舊測試合併)。
4. Lock(盡可能批次處理)
成功寫入 1–5 後:
npm run lock -- --root examples/connect-four-workspace --build-file "<abs1>" --build-file "<abs2>"
5. 按複雜度區分的代理批次處理(上下文衛生)
一個長時間的代理會話編譯許多單元,往往會導致後期或大型 packet 實作不足(上下文被先前的 bin 填滿)。偏好:
| 單元類型 | 編譯方式 |
|---|---|
| 葉節點/小型 | 同一代理,批次處理幾個 queue --next → 寫入 → lock |
| 重量/樞紐 | 新代理 / 新對話:--only <unit> → packet → 實作 SOURCE 中的每個 capability → lock |
| 修復(審查/遊玩測試後) | 新代理 + 僅對失敗的單元使用 --only |
如果滿足以下任一條件,則將單元視為重量級(與 stack 無關):
- 一個
.isl.md中有較長的 SOURCE / 許多####capabilities - 高扇入:許多其他單元引用它,或它引用許多依賴
- 協調圖表中很大一部分的簡報或邏輯(shell / facade / session boundary)
- 該單元的 Packet 或先前的編譯有省略 Flow 的歷史
不要預設為每個葉節點啟動一個代理(成本)。不要在一個代理中執行整個大型工作區而不在樞紐處重新整理。
針對重量級單元的提示:專案根目錄、--stack、--only <unit>、“實作 SOURCE 中的每個 capability;不省略任何 Flow。”遵循 agent-skills/a-isl-compile/SKILL.md(或主機副本,位於 .cursor/skills、.claude/skills 或 .github/skills)。
升級表(當輕量存取不足時)
| 情境 | 動作 |
|---|---|
| Packet 正常、依賴 bin 存在、ISL 明確 | 僅輕量 → 寫入檔案 |
Packet 退出 / missingDependencyBins | 停止——修正 queue/順序;不要發明 API |
| 需要依賴的確切宣告/簽名 | npm run lookup-decl (EXT-002);使用 JSON selected——不要發明 API |
lookup-decl 退出碼 2 (no_match) | 重新檢查 Spec Call/名稱 + 依賴路徑;不要發明簽名 |
| Packet 不完整 / 沒有 SOURCE 標記 | 讀取此單元的 fullBuildFile 一次 |
| 模糊/矛盾的 ISL | 停止 → Spec Agent;不要深入 vendor |
| 人類要求完整重建審計 | 允許使用 --force / 完整 queue --json |
單元寫入規則
每個生成的檔案上的標頭:
/**
* DO NOT EDIT THIS FILE DIRECTLY
* ----------------------------------
* This file was generated by ISL Compiler.
* Source: <basename-of-.isl.md>
* Edit the ISL file instead.
*/
遵循 stack 規則(預設 react-js)。完整實作——無 TODO 佔位。
路徑
| 工具 | 入口 |
|---|---|
| Preflight | npm run preflight -- --root <project> |
| Builder | npm run builder -- <project> |
| Queue next | npm run queue -- --root <project> --next |
| Packet | npm run packet -- --root <project> --next |
| Lock | npm run lock -- --root <project> --build-file <abs>… |
| Verify | npm run verify -- --root <project> [--stack <id>] [--only <unit>] |
| Lookup decl | `npm run lookup-decl -- --stack --name --file |
| Lint | npm run lint -- <file.isl.md> |