ai-spec-tool 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/README.md +8 -1
  2. package/assets/.agents/skills/bugfix/SKILL.md +33 -17
  3. package/assets/.agents/skills/plan/SKILL.md +39 -319
  4. package/assets/.agents/skills/plan/assets/templates/plan.md +47 -0
  5. package/assets/.agents/skills/plan-executor/SKILL.md +88 -305
  6. package/assets/.agents/skills/plan-executor/assets/templates/module-plan.md +26 -0
  7. package/assets/.agents/skills/plan-executor/assets/templates/project-plan.md +24 -0
  8. package/assets/.agents/skills/plan-executor/assets/templates/summary-module.md +17 -0
  9. package/assets/.agents/skills/plan-executor/assets/templates/summary-plan.md +18 -0
  10. package/assets/.agents/skills/plan-executor/assets/templates/summary-project.md +16 -0
  11. package/assets/.agents/skills/rules-creator/SKILL.md +25 -5
  12. package/assets/.agents/skills/rules-creator/assets/architecture-gen.md +59 -210
  13. package/assets/.agents/skills/rules-creator/assets/conventions-gen.md +85 -0
  14. package/assets/.agents/skills/rules-creator/assets/glossary-gen.md +46 -0
  15. package/assets/.agents/skills/rules-creator/assets/interface-gen.md +62 -0
  16. package/assets/.agents/skills/rules-creator/assets/ui-architecture-gen.md +35 -286
  17. package/assets/.agents/skills/rules-creator/assets/ui-template-gen.md +24 -114
  18. package/assets/.agents/skills/spec-executor/SKILL.md +53 -109
  19. package/assets/AGENTS.md +14 -30
  20. package/assets/docs/_shared/adr/README.md +4 -0
  21. package/assets/docs/_shared/conventions.md +37 -0
  22. package/assets/docs/_shared/glossary.md +4 -0
  23. package/assets/docs/architecture/README.md +6 -0
  24. package/assets/docs/plan/README.md +11 -0
  25. package/assets/docs/plan/index.yaml +2 -0
  26. package/assets/docs/plan/summary.md +2 -0
  27. package/assets/docs/requirements/README.md +5 -0
  28. package/assets/docs/requirements/index.yaml +2 -0
  29. package/assets/docs/specs/README.md +6 -0
  30. package/bin/ai-spec-tool.js +60 -10
  31. package/package.json +1 -1
  32. package/assets/.agents/skills/rules-creator/assets/naming-rule-gen.md +0 -77
  33. package/assets/.agents/skills/rules-creator/assets/vision-gen.md +0 -613
@@ -1,122 +1,66 @@
1
1
  ---
2
2
  name: spec-executor
3
- description: 执行已进入 processing 状态的 plan,按 execution_steps 读取 module spec 并落实到代码,同时更新 spec/plan 文件后缀
3
+ description: 执行 processing 状态的 plan,按 module-plan 修改代码并更新 module-spec
4
4
  ---
5
5
 
6
- # 前置依赖(强制)
7
-
8
- ## 依赖的规范文件(必须全部存在)
9
- - docs/global/vision.md
10
- - docs/global/architecture.md
11
- - docs/global/naming-rule.md
12
-
13
- ## 依赖检查流程(不可跳过)
14
- - 你必须先尝试读取并理解所有依赖文件内容
15
- - 若任何依赖文件无法读取 / 不存在 / 内容为空:
16
- - **只能输出以下内容(禁止输出任何其他文字)**
17
- > 缺少依赖[<依赖名称>]
18
- > 回复「Y」开始创建依赖
19
- - 下一次 run 必须使用 skill: rules-creator
20
- - 若所有依赖均存在,才可继续
21
-
22
- ---
23
-
24
- # Prompt:Processing Plan Code Executor
25
-
26
- 你是「Spec Executor」。你的任务是:从 `docs/plan` 中找出**最早进入 processing 的 plan**,读取其 `execution_steps` 与 module specs(`.update.md`),并**按步骤修改代码**。每完成一个 module 的变更,就把对应 spec 文件从 `.update.md` 改名为 `.md`;当所有模块完成后,把 plan 从 `.processing.md` 改为 `.done.md`。
27
-
28
- ---
29
-
30
- ## 1) 选择要执行的 plan(强制)
31
-
32
- 1. 扫描 `./docs/plan/` 下所有 `*.processing.md`
33
- 2. 若不存在:**停止并输出**
34
- > 未发现可执行的 plan(.processing.md)
35
- 3. 若存在多个:
36
- - **优先使用文件名 index**(如 `001-xxx.processing.md`)判断最老 → 取最小 index
37
- - 若无 index 可用,则以文件修改时间最早者为准
6
+ # 前置依赖检查(统一规则)
7
+
8
+ ## 依赖清单(必须存在且非占位)
9
+ - `docs/plan/*/plan.processing.md`
10
+ - `docs/_shared/conventions.md`
11
+ - `docs/_shared/glossary.md`
12
+ - 若 plan 含 `source_interface`:必须读取 `docs/requirements/<spec-id>.md`
13
+ - `docs/architecture/<project>/architecture.md`
14
+ - `docs/architecture/<project>/layer_rules.yaml`
15
+ - `docs/plan/<plan-id>/projects/<project>/project-plan.md`
16
+ - `docs/plan/<plan-id>/projects/<project>/modules/<module>-plan.md`
17
+ - 若 module 为 UI Component,需额外存在:
18
+ - `docs/specs/<project>/components/<module>-rules.md`
19
+ - `docs/architecture/<project>/ui/design-tokens.md`
20
+ - `docs/architecture/<project>/ui/layout-and-responsive.md`
21
+ - `docs/architecture/<project>/ui/patterns.md`
22
+
23
+ ## 缺失判定
24
+ 文件不存在 / 内容为空 / 首行含 `AI-SPEC-TOOL:PLACEHOLDER`
25
+
26
+ ## 缺失时唯一输出
27
+ <<<
28
+ 缺少依赖[<path>]
29
+
30
+ 【下一步】请选择一项:
31
+ 1. 开始创建依赖
32
+ 请回复:1
33
+ >>>
34
+ 用户回复 `1` 后切换 `rules-creator` 生成缺失文件。
38
35
 
39
36
  ---
40
37
 
41
- ## 2) 读取 plan 并建立执行清单(强制)
42
-
43
- 从选定的 plan 文件中读取:
44
- - `intent`(理解目标)
45
- - `modules[]`(知道涉及哪些 module / type)
46
- - `execution_steps`(执行顺序)
47
-
48
- **硬规则:**
49
- - `execution_steps` 必须为有序列表(1. 2. 3.)
50
- - **每一步只能提到一个 module**
51
- - `execution_steps` 必须覆盖 plan 中所有 `modules[]`
52
- - 若任一规则不满足:**停止并要求补齐 plan**
38
+ # 1) 选择要执行的 plan(强制,流程[1/3])
39
+ - 优先读取 `docs/plan/index.yaml` 取得 processing plan
40
+ - 若 index 缺失或未记录 processing plan:再扫描 `docs/plan/*/plan.processing.md`
41
+ - 若不存在:输出 `未发现可执行的 plan(plan.processing.md)`
53
42
 
54
43
  ---
55
44
 
56
- ## 3) 定位与校验 module spec(强制)
57
-
58
- 对每个 `execution_steps` 中提到的 module
59
-
60
- 1. 推导 module spec 路径:
61
- `./docs/spec/<module-type>/<module-name>.update.md`
62
- 2. 读取 spec 的 YAML frontmatter,**必须包含**:
63
- - `module name`
64
- - `module type`
65
- - `source plan`
66
- 3. `source plan` 匹配规则:
67
- - 去除后缀的 plan 基名要等于`source plan`除后缀的 plan 基名(如 `001-多语言内容管理`)
68
- 4. 若 spec 不存在或 frontmatter 不一致:**停止并要求修正**
45
+ # 2) 执行步骤(强制,流程[2/3])
46
+ 对 `execution_steps` 的每个 `<project>/<module>`:
47
+ 1. 将 `<module>-plan.md` `<module>-plan.processing.md`
48
+ 2. 读取对应 `module-plan`
49
+ 3. 按约束修改代码
50
+ 4. 更新/生成 `docs/specs/<project>/<module>-spec.md`
51
+ - 必须写入 `last_updated_plan: <plan-id>`
52
+ - 必须写入 `source_interface: <path>`
53
+ 5. module 为 UI Component:
54
+ - 必须确认 module-plan 内有 UI 规范引用
55
+ - 必要时更新 `<module>-rules.md`
56
+ 6. `<module>-plan.processing.md` `<module>-plan.done.md`
57
+
58
+ 完成所有模块后:
59
+ - 将 `plan.processing.md` → `plan.done.md`
69
60
 
70
61
  ---
71
62
 
72
- ## 4) 执行代码修改(强制)
73
-
74
- `execution_steps` 顺序逐一处理 module:
75
-
76
- 1. 阅读该 module 的 `.update.md` spec(只用于理解职责与边界)
77
- 2. 根据 plan 的 intent + rules + flows + spec 要求修改代码
78
- - **必须遵守 docs/global/architecture.md 的依赖规则与目录落点**
79
- - **不得违背 spec 的「不做什么 / 禁止依赖 / 禁止扩充方向」**
80
- 3. 若当前模块属于 UI 显示组件类型(见 `docs/global/ui/module-ui-types.md`):
81
- - 执行前必须读取对应的 Component Rules
82
- - 必须遵守 `docs/global/ui/design-tokens.md`、`layout-and-responsive.md`、`patterns.md` 的约束
83
- - 若缺失任一 UI 规范文件:**停止并要求补齐**
84
- - 若存在 `docs/global/ui/accessibility.md`:**应遵守其约束**(可选)
85
- - **必须逐条对照 `docs/global/ui/patterns.md` 的「交互模式」并落实到实现**
86
- - 若 Component Rules 未覆盖或与 patterns 冲突:**停止并要求先补齐 Component Rules / patterns**
87
- 4. 每完成一个 module 的代码改动:
88
- - 将该 module spec 文件从
89
- `<module-name>.update.md` → `<module-name>.md`
90
-
91
- > 说明:如果模块不存在,需要创建其对应目录与基础结构;若已存在,只修改必要部分。
92
-
93
- ---
94
-
95
- ## 5) 完成收尾(强制)
96
-
97
- 当所有 module 都完成并已改名为 `.md`:
98
- - 将 plan 文件从
99
- `<plan>.processing.md` → `<plan>.done.md`
100
-
101
- ---
102
-
103
- ## 6) 对话输出(唯一允许的文字输出)
104
-
105
- 完成后,只允许输出以下结构:
106
-
107
- > 已完成 Plan 执行:
108
- > `<plan文件名>`(需为可点击超链接)
109
- >
110
- > 已完成 Module:
111
- > 1.`<module spec 文件名>`
112
- > 2.`<module spec 文件名>`
113
- > 3.`<module spec 文件名>`
114
-
115
- ---
116
-
117
- ## 7) 失败时的输出(强制)
118
-
119
- 若因缺失文件或规则不满足而停止,只允许输出:
120
-
121
- > 无法执行:<原因>
122
- > 请修正后再执行。
63
+ # 3) 对话输出(唯一允许的文字输出,流程[3/3])
64
+ - 输出已完成的 plan 路径
65
+ - 输出已完成的 module spec 路径
66
+ - 提示下一步选项:进入 plan
package/assets/AGENTS.md CHANGED
@@ -1,30 +1,14 @@
1
- 你必须先分析用户在开发专案中的需求类型,并严格分类:
2
-
3
- - plan执行(plan-executor)
4
- 用户想要执行plan文件
5
- `./docs/plan`为plan文件路径,去里面找用户描述的plan
6
- 1.若plan文件后缀为.processing.md
7
- 使用 skill: spec-executor
8
- 2.若plan文件后缀为.done.md
9
- 回复用户 > plan已完成
10
- 3.若plan文件后缀为.md
11
- 使用 skill: plan-executor
12
-
13
- - 规则文件创建(rules-creator)
14
- 用户想要生成规则文件
15
- → 使用 skill: rules-creator
16
-
17
- - 异常修复(bugfix)
18
- 用户提供报错信息或描述异常行为
19
- → 使用 skill: bugfix
20
-
21
- - 功能增修(update)
22
- 用户希望修改或新增功能
23
- - 若该功能不需要建立一个目前不存在的系统 → 直接修改代码与对应 spec
24
- - 若该功能需要建立一个新的系统/修改已有系统就可以 → 使用 skill: plan
25
-
26
- - 系统规划(plan)
27
- 用户明确需要一个新的系统、模块或功能体系
28
- → 使用 skill: plan
29
-
30
- 若意图并非以上,直接回答用户即可
1
+ 先判断需求类型,再选择对应 skill(精简路由):
2
+
3
+ - 执行 Plan:
4
+ - 有 `docs/plan/<plan-id>/plan.processing.md` → `spec-executor`
5
+ - 有 `docs/plan/<plan-id>/plan.done.md` → 回复“此 plan 已完成”
6
+ - 有 `docs/plan/<plan-id>/plan.md` → `plan-executor`
7
+ - 生成/补齐规则文件 `rules-creator`
8
+ - 异常修复 → `bugfix`
9
+ - **进入 plan 模式的严格条件**:
10
+ - 只有当用户明确说“要 plan/规划/制定计划/产出 Plan”才进入 `plan`
11
+ - 用户仅说“要新功能/需求/改动”时,先讨论澄清,不自动进入 `plan`
12
+ - 若功能与接口讨论已清晰无疑虑,再**提议**用户是否需要进入 `plan`
13
+ - 若已完成接口/DB 规格讨论,可先生成 Interface 规格书(rules-creator → interface)
14
+ - 其他 → 直接回答
@@ -0,0 +1,4 @@
1
+ <!-- AI-SPEC-TOOL:PLACEHOLDER -->
2
+ # ADR
3
+
4
+ 架构决策记录存放于此目录。
@@ -0,0 +1,37 @@
1
+ <!-- AI-SPEC-TOOL:PLACEHOLDER -->
2
+ # 通用规范(Conventions)
3
+
4
+ (由 rules-creator 生成)
5
+
6
+ ## 计划执行流程
7
+ - 生成多个 `project-plan.md` 后:先给出每个 project 的简短摘要,询问是否修改,确认后继续。
8
+ - 生成多个 `<module>-plan.md` 后:先给出每个 module 的简短摘要,询问是否修改,确认后才可进入 spec-executor。
9
+ - 所有多题澄清必须标注进度:`问题[当前/总数]`。
10
+ - 所有关键流程阶段必须标注进度:`流程[当前/总数]`。
11
+ - 优先使用 `docs/plan/index.yaml` 作为计划索引;若不存在再扫描目录。
12
+ - 生成 plan / project-plan / module-plan 后应产出对应 `summary.md` 以降低后续读取成本。
13
+ - summary 文件路径建议:
14
+ - `docs/plan/<plan-id>/summary.md`
15
+ - `docs/plan/<plan-id>/projects/<project>/summary.md`
16
+ - `docs/plan/<plan-id>/projects/<project>/modules/<module>.summary.md`
17
+ - summary 模板参考:
18
+ - `assets/templates/summary-plan.md`
19
+ - `assets/templates/summary-project.md`
20
+ - `assets/templates/summary-module.md`
21
+ - 若存在 Interface 规格书:
22
+ - 其路径必须写入 `plan.md / project-plan.md / module-plan.md`
23
+ - 最终写入每个 `module-spec.md` 的 frontmatter
24
+
25
+ ## Interface 规格书
26
+ - 位置:`docs/requirements/<spec-id>.md`
27
+ - 索引:`docs/requirements/index.yaml`
28
+ - 命名:`001-支付流程` 形式
29
+
30
+ ## 规格书优先规则
31
+ - 当接口与 DB 细节讨论已清晰,可先生成 Interface 规格书,再进入 plan。
32
+
33
+ ### 进度标识示例
34
+ - `问题[1/4] 这次变更的目标是什么?`
35
+ - `问题[2/4] 这次的成功标准有哪些?`
36
+ - `流程[1/3] 读取 plan 并建立执行清单`
37
+ - `流程[2/3] 生成 project-plan 与 module-plan`
@@ -0,0 +1,4 @@
1
+ <!-- AI-SPEC-TOOL:PLACEHOLDER -->
2
+ # 术语表(Glossary)
3
+
4
+ (由 rules-creator 生成)
@@ -0,0 +1,6 @@
1
+ <!-- AI-SPEC-TOOL:PLACEHOLDER -->
2
+ # Architecture 目录
3
+
4
+ 每个 project 各自维护架构与依赖规则:
5
+ - `docs/architecture/<project>/architecture.md`
6
+ - `docs/architecture/<project>/layer_rules.yaml`
@@ -0,0 +1,11 @@
1
+ <!-- AI-SPEC-TOOL:PLACEHOLDER -->
2
+ # Plan 目录
3
+
4
+ 此目录用于存放每次变更的 Plan:
5
+ `docs/plan/<plan-id>/plan.md`
6
+
7
+ 索引文件:
8
+ `docs/plan/index.yaml`
9
+
10
+ 若存在 Interface 规格书:
11
+ `docs/requirements/<spec-id>.md`
@@ -0,0 +1,2 @@
1
+ # AI-SPEC-TOOL:PLACEHOLDER
2
+ plans: []
@@ -0,0 +1,2 @@
1
+ <!-- AI-SPEC-TOOL:PLACEHOLDER -->
2
+ # Plan Summary
@@ -0,0 +1,5 @@
1
+ <!-- AI-SPEC-TOOL:PLACEHOLDER -->
2
+ # Requirements (Interface Specs)
3
+
4
+ 规格书存放于:
5
+ `docs/requirements/<spec-id>.md`
@@ -0,0 +1,2 @@
1
+ # AI-SPEC-TOOL:PLACEHOLDER
2
+ requirements: []
@@ -0,0 +1,6 @@
1
+ <!-- AI-SPEC-TOOL:PLACEHOLDER -->
2
+ # Specs 目录
3
+
4
+ 每个 project 的 module spec 与 component rules 将放在:
5
+ - `docs/specs/<project>/<module>-spec.md`
6
+ - `docs/specs/<project>/components/<module>-rules.md`
@@ -2,10 +2,12 @@
2
2
 
3
3
  const fs = require("fs");
4
4
  const path = require("path");
5
+ const readline = require("readline");
5
6
 
6
7
  const ASSET_ROOT = path.resolve(__dirname, "..", "assets");
7
8
  const TEMPLATE_AGENTS = path.join(ASSET_ROOT, "AGENTS.md");
8
9
  const TEMPLATE_AGENTS_DIR = path.join(ASSET_ROOT, ".agents");
10
+ const TEMPLATE_DOCS_DIR = path.join(ASSET_ROOT, "docs");
9
11
 
10
12
  const START = "<!-- AI-SPEC-TOOL:START -->";
11
13
  const END = "<!-- AI-SPEC-TOOL:END -->";
@@ -32,7 +34,7 @@ function nextIncomingPath(destPath) {
32
34
  return `${candidate}.${i}`;
33
35
  }
34
36
 
35
- function copyFileSafe(srcPath, destPath, report) {
37
+ function copyFileSafe(srcPath, destPath, report, options) {
36
38
  if (!fs.existsSync(destPath)) {
37
39
  ensureDir(path.dirname(destPath));
38
40
  fs.copyFileSync(srcPath, destPath);
@@ -43,12 +45,17 @@ function copyFileSafe(srcPath, destPath, report) {
43
45
  report.skipped.push(destPath);
44
46
  return;
45
47
  }
48
+ if (options.force) {
49
+ fs.copyFileSync(srcPath, destPath);
50
+ report.updated.push(destPath);
51
+ return;
52
+ }
46
53
  const incoming = nextIncomingPath(destPath);
47
54
  fs.copyFileSync(srcPath, incoming);
48
55
  report.conflicts.push({ target: destPath, incoming });
49
56
  }
50
57
 
51
- function copyDirSafe(srcDir, destDir, report) {
58
+ function copyDirSafe(srcDir, destDir, report, options) {
52
59
  ensureDir(destDir);
53
60
  const entries = fs.readdirSync(srcDir, { withFileTypes: true });
54
61
  entries.forEach((entry) => {
@@ -56,15 +63,42 @@ function copyDirSafe(srcDir, destDir, report) {
56
63
  const src = path.join(srcDir, entry.name);
57
64
  const dest = path.join(destDir, entry.name);
58
65
  if (entry.isDirectory()) {
59
- copyDirSafe(src, dest, report);
66
+ copyDirSafe(src, dest, report, options);
60
67
  return;
61
68
  }
62
69
  if (entry.isFile()) {
63
- copyFileSafe(src, dest, report);
70
+ copyFileSafe(src, dest, report, options);
64
71
  }
65
72
  });
66
73
  }
67
74
 
75
+ function askYesNo(prompt) {
76
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
77
+ return new Promise((resolve) => {
78
+ rl.question(prompt, (answer) => {
79
+ rl.close();
80
+ const normalized = String(answer || "").trim().toLowerCase();
81
+ resolve(normalized === "y" || normalized === "yes");
82
+ });
83
+ });
84
+ }
85
+
86
+ async function resolveConflictsInteractively(report, options) {
87
+ if (!report.conflicts.length || !options.ask) return;
88
+ if (!process.stdin.isTTY) return;
89
+
90
+ for (const conflict of report.conflicts) {
91
+ const prompt = `Overwrite ${conflict.target} with incoming? (y/N) `;
92
+ const yes = await askYesNo(prompt);
93
+ if (yes) {
94
+ fs.copyFileSync(conflict.incoming, conflict.target);
95
+ report.updated.push(conflict.target);
96
+ report.conflictsResolved.push(conflict.target);
97
+ fs.unlinkSync(conflict.incoming);
98
+ }
99
+ }
100
+ }
101
+
68
102
  function updateAgentsMd(targetPath, report) {
69
103
  const template = readFile(TEMPLATE_AGENTS).trimEnd();
70
104
  const block = `${START}\n${template}\n${END}\n`;
@@ -99,7 +133,7 @@ function updateAgentsMd(targetPath, report) {
99
133
  report.updated.push(targetPath);
100
134
  }
101
135
 
102
- function init() {
136
+ async function init(options) {
103
137
  const cwd = process.cwd();
104
138
  const targetAgents = path.join(cwd, "AGENTS.md");
105
139
  const targetAgentsDir = path.join(cwd, ".agents");
@@ -108,7 +142,8 @@ function init() {
108
142
  added: [],
109
143
  updated: [],
110
144
  skipped: [],
111
- conflicts: []
145
+ conflicts: [],
146
+ conflictsResolved: []
112
147
  };
113
148
 
114
149
  if (!fs.existsSync(TEMPLATE_AGENTS) || !fs.existsSync(TEMPLATE_AGENTS_DIR)) {
@@ -116,14 +151,22 @@ function init() {
116
151
  process.exit(1);
117
152
  }
118
153
 
119
- copyDirSafe(TEMPLATE_AGENTS_DIR, targetAgentsDir, report);
154
+ copyDirSafe(TEMPLATE_AGENTS_DIR, targetAgentsDir, report, options);
155
+ if (fs.existsSync(TEMPLATE_DOCS_DIR)) {
156
+ const targetDocsDir = path.join(cwd, "docs");
157
+ copyDirSafe(TEMPLATE_DOCS_DIR, targetDocsDir, report, options);
158
+ }
120
159
  updateAgentsMd(targetAgents, report);
160
+ await resolveConflictsInteractively(report, options);
121
161
 
122
162
  console.log("ai-spec-tool init complete.");
123
163
  console.log(`Added: ${report.added.length}`);
124
164
  console.log(`Updated: ${report.updated.length}`);
125
165
  console.log(`Skipped: ${report.skipped.length}`);
126
166
  console.log(`Conflicts: ${report.conflicts.length}`);
167
+ if (report.conflictsResolved.length) {
168
+ console.log(`Resolved: ${report.conflictsResolved.length}`);
169
+ }
127
170
 
128
171
  if (report.conflicts.length) {
129
172
  console.log("\nConflicts (new versions saved as .incoming):");
@@ -134,13 +177,20 @@ function init() {
134
177
  }
135
178
 
136
179
  function main() {
137
- const [command] = process.argv.slice(2);
180
+ const [command, ...args] = process.argv.slice(2);
181
+ const options = {
182
+ force: args.includes("--force"),
183
+ ask: args.includes("--ask")
184
+ };
138
185
  if (!command || command === "help" || command === "--help" || command === "-h") {
139
- console.log("ai-spec-tool\n\nUsage:\n ai-spec-tool init\n");
186
+ console.log("ai-spec-tool\n\nUsage:\n ai-spec-tool init [--force|--ask]\n");
140
187
  return;
141
188
  }
142
189
  if (command === "init") {
143
- init();
190
+ init(options).catch((err) => {
191
+ console.error(err?.message || err);
192
+ process.exit(1);
193
+ });
144
194
  return;
145
195
  }
146
196
  console.error(`Unknown command: ${command}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-spec-tool",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Installable agents + rules for AI spec workflows",
5
5
  "bin": {
6
6
  "ai-spec-tool": "bin/ai-spec-tool.js"
@@ -1,77 +0,0 @@
1
- # Naming Rule File Generator (Spec)
2
-
3
- ## 0) 生成目标(不可变,不询问用户)
4
- - 输出文件:./docs/global/naming-rule.md
5
- - 输出格式:Markdown
6
- - 语言:中文为主
7
-
8
- ---
9
-
10
- ## 1) 交互入口(优先确认默认方案)
11
-
12
- ### 1.0 默认方案确认(必须最先执行)
13
-
14
- 在开始任何详细询问前,**先询问用户一句话**:
15
-
16
- > 现在开始创建命名规范\n是否使用默认方案?
17
-
18
- 并同时简要展示默认方案内容:
19
-
20
- - 文件 / 目录:kebab-case
21
- - 变量 / 函数:camelCase
22
- - 类 / 构造类型:PascalCase
23
- - 缩写策略:允许常见缩写(API / URL / DB / ID)
24
-
25
- 回答「Y」或「N」
26
-
27
- #### 用户响应处理规则
28
- - 若用户回答「Y/y/是 / 使用默认 / OK」:
29
- - 直接使用默认推荐值
30
- - 跳过所有后续询问
31
- - 进入生成流程(第 3 节)
32
- - 若用户回答「N/n/否 / 自定义 / 调整」:
33
- - 进入第 1.1 节,逐项询问
34
-
35
- ---
36
-
37
- ## 1.1 必问项(仅在用户拒绝默认方案时执行)
38
-
39
- 请依次询问以下问题,用户只需回复选项编号或关键字:
40
-
41
- **Q1. 文件 / 目录命名风格**
42
- - A) kebab-case(推荐)
43
- - B) snake_case
44
- - C) camelCase(不推荐)
45
- - D) PascalCase(不推荐)
46
-
47
- **Q2. 变量 / 函数命名风格**
48
- - A) camelCase(推荐)
49
- - B) snake_case
50
- - C) kebab-case(不推荐)
51
-
52
- **Q3. 类 / 构造类型命名风格**
53
- - A) PascalCase(推荐)
54
- - B) camelCase
55
- - C) snake_case
56
-
57
- **Q4. 缩写策略(防止风格漂移)**
58
- - A) 不允许随意缩写(必须写全)
59
- - B) 允许常见缩写(API / URL / DB / ID)
60
-
61
- ---
62
-
63
- ## 1.2 用户回答不足时的处理
64
- - 若只回答部分问题:继续追问未回答项
65
- - 若回答“随便 / 你定”:使用默认推荐值,并在生成结果中说明
66
- - 避免开放式问题,始终优先使用选项
67
-
68
- ---
69
-
70
- ## 2) 默认推荐值(与 1.0 展示内容保持一致)
71
- - 文件 / 目录:kebab-case
72
- - 变量 / 函数:camelCase
73
- - 类 / 构造类型:PascalCase
74
- - 缩写策略:允许常见缩写(API / URL / DB / ID)
75
- - 测试文件:*.test.ts / *.spec.ts
76
- - React 组件:PascalCase.tsx
77
- - Hook:useXxx