A-ISL 编译(代理内编译器)
你从 ISL 生成 bin-<stackId>/ 目录(默认栈 react-js → bin-react-js)。构建器 / 队列 / 包 / 锁定 / 预检查 CLI 都允许使用。付费的 isl-generator / Gemini / OpenAI 禁止使用。
适用于任何加载此技能的编码代理(Cursor、Claude Code、GitHub Copilot ……)。在仓库根目录使用相同的 npm 运行时。
用户请求门(不可协商)
对 bin 目录的修改仅通过编译进行,且仅当用户明确请求时才执行。
- 仅当用户明确请求编译(例如
compila、/a-isl-compile、“构建 bin”、“重新生成实现”、“对……运行编译”)时,才进入此技能或在bin-*下写入。 - 仅规范消息、自然语言功能想法或 UX 调整没有明确的编译请求,不得触发实现写入——应将其发送到 a-isl-spec-author(或规范阶段)并停止。
- 不要在规范编辑后自动编译“因为演示会崩溃”或“为了完成循环”。
- 实现文件夹仅通过此编译工作流(包 → 写入 → 锁定)更新。除非用户明确要求一次性例外,否则不要将
bin-*下的临时补丁视为 A-ISL 路径。 - 如果用户未要求编译:拒绝编辑
bin-*,并说明需要显式编译请求。
何时使用
- 用户完成规范阶段并要求构建/编译/重新生成
- 对齐项目的
bin-<stack>/到更新的*.isl.md因为用户请求了编译
硬性约束
- 不要运行付费生成器或 API 代码生成客户端。
- 你根据包的
targetPath将每个实现文件写入栈 bin 目录(完整代码,无 TODO 存根)。 - 仅更新
gen-lock.json不是编译——仅在bin-<stack>/下进行实际写入后锁定。 - 如果 ISL 歧义或矛盾:停止并告知用户返回 a-isl-spec-author。不要自行发明需求。
- 不要在编译期间打开
vendor/isl-spec/(仅限规范代理),除非用户明确要求。 - 优先通过
queue --next+ 轻量包一次处理一个单元。默认情况下,不要加载完整的队列 JSON 或完整的.build.md。
输出目录
默认:bin-<stackId> 位于规范文件旁(例如 --stack react-js → bin-react-js)。如有需要,可使用 --bin 覆盖。同一工作区可同时容纳 bin-react-js 和 bin-csharp。
低令牌工作流(默认)
preflight → builder (一次) → 循环: queue --next → packet → [测试然后] 写入实现 → (批量) lock
→ (可选) npm run verify
0. 预检查(一次)
npm run preflight -- --root examples/connect-four-workspace
仅结构/图/代码检查门——不证明实现正确性。如果失败,请在编译前修复规范/代码检查。
1. 构建器(每批次一次)
npm run builder -- examples/connect-four-workspace
拓扑顺序位于 build/build-manifest.json(由脚本管理)。你不能发明编译顺序。
2. 仅下一个单元
npm run queue -- --root examples/connect-four-workspace --next
在循环中每次调用队列/包时传递 --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
# 或者按名称包:
npm run packet -- --root <project> --only dungeon --stack react-js
--only 可重复使用。令牌:单元基名(dungeon)、dungeon.isl.md 或 ./dungeon。队列 JSON 中原因:force-only。当仅请求子集时,不要使用工作区范围的 --force。
使用 next.buildFile / next.targetPath。如果 next 为 null,停止(队列为空)。
仅当用户要求概览时才使用完整的 --json 队列。
3. 轻量包(默认上下文)
npm run packet -- --root examples/connect-four-workspace --build-file "<abs.build.md>"
# 或者
npm run packet -- --root examples/connect-four-workspace --next
包包含:此单元的 SOURCE markdown、目标路径、栈约束子集、同一 bin-<stack>/ 中依赖文件的路径。
它排除内联的 .ref.md 内容。
从包写入文件(参见下面的 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 = 用法/路径/栈错误。 - 读取标准输出 JSON:使用
candidates[selected](signatureText、leadingContext、enclosingType、每个候选的kind)。不要自行发明正则表达式或打开整个依赖文件来搜索签名。 - 模式和
callSymbol位于栈配置中(declaration-patterns.ts/stacks.config.ts)——技能只能调用此 CLI。 - 路径必须在
--workspace和bin-*段下解析(符号链接转义 → 退出码 3)。
3b. EXT-001 生成测试(当规范选择时)
可验证的场景 = 同时具有 `id: …` 和 - Call: … 的测试场景(参见 docs/isl-agent-profile.md)。规范作者决定;任何角色都可以选择加入。
每个单元,同一轮次:
- 如果 SOURCE 有 ≥1 个合格场景:先覆盖生成的测试文件(路径 = 实现基名 +
stack.verify.testSuffix,位于同一bin-<stack>/下,例如domain-sheet.test.js/domain-sheet.Tests.cs)。仅从规范场景 + 签名断言;通过stack.verify.callSymbol映射Call到符号(stacks.config.ts中的as-is|pascal-case|snake-case)。react-js 领域/逻辑: 每个 Call 必须是一个命名导出;测试必须import { <Call> } from "./<file>"——永远不要import Unit from …; Unit().<Call>()。如果工作区有bench/call-map.json,则从"<unit>.<Call>"解析export并导入该名称(与冻结分数的相同契约)。不要为仅散文场景发明测试用例;在测试文件写入之前不要打开/编辑实现文件。 - 然后写入实现到
targetPath,使其满足这些测试和契约。react-js 领域/逻辑: 每个能力使用export function <Call>/export const <Call>;禁止默认导出工厂包装能力。 - 如果零合格场景:仅写入实现;如果存在先前为该单元生成的测试文件,则删除它。领域/逻辑仍然使用命名能力导出。
- 验证失败时:你可以
--only重新编译仅实现(保留测试文件)。不得重写测试使它们通过(包括将命名导入更改为默认工厂)。如果场景/Call/预期看起来错误→停止并将用户发送给 a-isl-spec-author。 - 在领域/逻辑(或其他合格)批次之后,你可以建议
npm run verify -- --root <project> --stack <id>;不要求全部绿色才锁定。锁定保持为构建哈希缓存。
规范更改后的完整单元重新编译:根据当前规范重新生成整个测试文件,然后实现(不是与旧测试的合并)。
4. 锁定(尽可能批量)
在 1-5 步成功写入之后:
npm run lock -- --root examples/connect-four-workspace --build-file "<abs1>" --build-file "<abs2>"
5. 按复杂度的代理批处理(上下文管理)
一个编译多个单元的长时间代理会话往往会导致实现不足(特别是后续或较大包,因为上下文被之前的 bin 内容填满)。优先:
| 单元类型 | 如何编译 |
|---|---|
| 叶子/小 | 同一代理,批量几个 queue --next → 写入 → 锁定 |
| 重量级/枢纽 | 新代理 / 新聊天:--only <unit> → 包 → 实现 SOURCE 中的每个能力 → 锁定 |
| 修复(审查/试玩后) | 新代理 + 仅作用于失败单元的 --only |
如果满足以下任一条件,将单元视为重量级(与栈无关):
- 长 SOURCE / 一个
.isl.md中有许多####能力 - 高扇入:许多其他单元引用它,或者它引用许多依赖
- 协调大部分图(外壳/外观/会话边界)的表示或逻辑
- 该单元的包或先前编译有遗漏 Flow 的历史
默认情况下不要为每个叶子派生一个代理(成本高)。不要在不刷新枢纽的情况下在一个代理中运行整个大型工作区。
对重量级单元的提示:仓库根目录、--stack、--only <unit>、“实现 SOURCE 中的每个能力;不遗漏 Flow。”遵循 agent-skills/a-isl-compile/SKILL.md(或主机副本,位于 .cursor/skills、.claude/skills 或 .github/skills 下)。
升级处理表(当轻量访问不足时)
| 情况 | 操作 |
|---|---|
| 包正常、依赖 bin 存在、ISL 清晰 | 仅轻量 → 写入文件 |
包退出 / missingDependencyBins | 停止 — 修复队列/顺序;不要发明 API |
| 需要依赖的确切声明/签名 | npm run lookup-decl(EXT-002);使用 JSON selected — 不要发明 API |
lookup-decl 退出码 2(no_match) | 重新检查规范 Call/名称 + 依赖路径;不要发明签名 |
| 包不完整 / 无 SOURCE 标记 | 读取此单元的 fullBuildFile 一次 |
| ISL 歧义 / 矛盾 | 停止 → 规范代理;不深入 vendor |
| 用户请求完整重新构建审查 | 允许 --force / 完整队列 --json |
每单元写入规则
每个生成文件的头部:
/**
* 请勿直接编辑此文件
* ----------------------------------
* 此文件由 ISL 编译器生成。
* 源文件:<basename-of-.isl.md>
* 请编辑 ISL 文件。
*/
遵循栈规则(默认 react-js)。完整实现——无 TODO 存根。
路径
| 工具 | 入口 |
|---|---|
| 预检查 | npm run preflight -- --root <project> |
| 构建器 | npm run builder -- <project> |
| 下一个队列 | npm run queue -- --root <project> --next |
| 包 | npm run packet -- --root <project> --next |
| 锁定 | npm run lock -- --root <project> --build-file <abs>… |
| 验证 | npm run verify -- --root <project> [--stack <id>] [--only <unit>] |
| 声明查找 | `npm run lookup-decl -- --stack --name --file |
| 代码检查 | npm run lint -- <file.isl.md> |