@alenfitz/spec-copilot 1.0.0

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.
package/README.md ADDED
@@ -0,0 +1,112 @@
1
+ # @alenfitz/spec-copilot
2
+
3
+ **Spec-Driven Development Framework** — One package, six AI coding tools. Turn AI coding from "black-box YOLO" into "white-box step-by-step."
4
+
5
+ [中文文档](./README.zh-CN.md)
6
+
7
+ ---
8
+
9
+ ## Supported Tools
10
+
11
+ | Tool | Prompt File | Commands |
12
+ |------|-----------|----------|
13
+ | **opencode** | `AGENTS.md` | `.opencode/commands/` (native) |
14
+ | **Claude Code** | `CLAUDE.md` | `.claude/commands/` (native) |
15
+ | **Cursor** | `.cursor/rules/spec-copilot.mdc` | Prompt routing |
16
+ | **Windsurf** | `.windsurf/rules/spec-copilot.md` | Prompt routing |
17
+ | **GitHub Copilot** | `.github/copilot-instructions.md` | Prompt routing |
18
+ | **Cline** | `.clinerules/spec-copilot.md` | Prompt routing |
19
+
20
+ ## Quick Start
21
+
22
+ ```bash
23
+ # Install — specify your tool
24
+ npx @alenfitz/spec-copilot install --tool cursor
25
+ npx @alenfitz/spec-copilot install --tool claude-code
26
+ npx @alenfitz/spec-copilot install --tool windsurf
27
+ # ... any of: opencode, claude-code, cursor, windsurf, copilot, cline
28
+
29
+ # Verify
30
+ npx @alenfitz/spec-copilot doctor
31
+ ```
32
+
33
+ The framework auto-detects your tool on subsequent commands (`update`, `doctor`, etc.).
34
+
35
+ ## How It Works
36
+
37
+ 1. **Spec First (No Spec, No Code)** — AI evaluates complexity, asks questions, generates spec in segments. No confirmed spec, no code written.
38
+ 2. **Task Rhythm** — AI completes one atomic task, shows proof, commits immediately, then **waits for you to say "continue."**
39
+ 3. **Knowledge Flywheel** — Pitfalls are logged and archived into a tag-indexed knowledge base. Next requirement reads past experience.
40
+
41
+ ## Commands
42
+
43
+ | Command | When | Output |
44
+ |---------|------|--------|
45
+ | `/spec:init` | First time setup | Fills `rules/project-context.md` |
46
+ | `/spec:bootstrap` | New empty project | Tech stack selection + scaffolding |
47
+ | `/spec:propose <req>` | New requirement | `spec.md` (+ `tasks.md` if complex) |
48
+ | `/spec:flow <req>` | Auto mode (simple/medium) | Full pipeline: propose → archive |
49
+ | `/spec:apply <name>` | After spec confirmed | Code committed task by task |
50
+ | `/spec:smoke <name>` | After /spec:apply | Build + API smoke test |
51
+ | `/spec:review <name>` | After /spec:smoke | Spec compliance + code quality report |
52
+ | `/spec:fix <name>` | After review issues | Fix commits + doc sync |
53
+ | `/spec:archive <name>` | After review passes | Knowledge captured, merge prompt |
54
+ | `/spec:hotfix <desc>` | Production incident | Minimal fix on hotfix branch |
55
+ | `/spec:test <name>` | Need automated tests | Test code + run results |
56
+
57
+ ## CLI Commands
58
+
59
+ ```bash
60
+ npx @alenfitz/spec-copilot install --tool <name> # Install framework
61
+ npx @alenfitz/spec-copilot update [--force] # Upgrade framework
62
+ npx @alenfitz/spec-copilot gate <name> <phase> # Phase gate check
63
+ npx @alenfitz/spec-copilot lint <name> # Spec completeness check
64
+ npx @alenfitz/spec-copilot doctor # Health check
65
+ npx @alenfitz/spec-copilot uninstall --confirm # Remove framework
66
+ ```
67
+
68
+ ## What Gets Installed
69
+
70
+ ```
71
+ your-project/
72
+ ├── <tool-specific prompt file> ← AI reads this
73
+ ├── <tool-specific commands/> ← Native commands (if supported)
74
+
75
+ └── spec_copilot/
76
+ ├── commands/ ← 11 command definitions
77
+ ├── rules/
78
+ │ ├── coding-style.md ← Universal coding standards
79
+ │ ├── security.md ← Security red lines
80
+ │ ├── project-context.md ← Your project's tech context
81
+ │ └── domain-rules.md ← Business rules (you fill this)
82
+ ├── stack-adapters/
83
+ │ ├── _template.md ← Template for new tech stacks
84
+ │ └── spring-boot-vue3.md ← Built-in adapter (example)
85
+ ├── knowledge/index.md ← Tag-indexed knowledge base
86
+ ├── changes/templates/ ← spec.md / tasks.md / log.md
87
+ ├── archives/ ← Completed requirements
88
+ └── scripts/ ← Lint, gate, hook scripts
89
+ ```
90
+
91
+ ## Complexity Tiers
92
+
93
+ | Tier | Criteria | What's Required |
94
+ |------|----------|----------------|
95
+ | 🟢 Simple | No API/schema/core flow/new dependency changes | Direct conversation, no spec |
96
+ | 🟡 Medium | New APIs, non-core schema, new dependency | Spec (2-segment confirmation) |
97
+ | 🔴 Complex | New subsystem, core flow, core schema, concurrency | Spec + tasks + knowledge |
98
+
99
+ ## Upgrade Safety
100
+
101
+ - **Overwritten**: coding-style.md, security.md, templates, scripts, commands, built-in adapters
102
+ - **Skipped by default**: prompt file (use `--force`)
103
+ - **Never touched**: project-context.md, domain-rules.md, knowledge/, changes/, archives/, custom adapters
104
+
105
+ ## Related Packages
106
+
107
+ - [`@alenfitz/opencode-copilot`](https://www.npmjs.com/package/@alenfitz/opencode-copilot) — opencode-only version
108
+ - [`@alenfitz/spec-driven-dev`](https://www.npmjs.com/package/@alenfitz/spec-driven-dev) — Claude Code-only version (legacy)
109
+
110
+ ## License
111
+
112
+ MIT
@@ -0,0 +1,112 @@
1
+ # @alenfitz/spec-copilot
2
+
3
+ **渐进式 Spec 编码框架** — 一个包,六种 AI 编码工具。让 AI 编码从"黑盒一把梭"变成"白盒分步推进"。
4
+
5
+ [English](./README.md)
6
+
7
+ ---
8
+
9
+ ## 支持工具
10
+
11
+ | 工具 | 提示词文件 | 命令方式 |
12
+ |------|-----------|---------|
13
+ | **opencode** | `AGENTS.md` | `.opencode/commands/`(原生) |
14
+ | **Claude Code** | `CLAUDE.md` | `.claude/commands/`(原生) |
15
+ | **Cursor** | `.cursor/rules/spec-copilot.mdc` | Prompt 路由 |
16
+ | **Windsurf** | `.windsurf/rules/spec-copilot.md` | Prompt 路由 |
17
+ | **GitHub Copilot** | `.github/copilot-instructions.md` | Prompt 路由 |
18
+ | **Cline** | `.clinerules/spec-copilot.md` | Prompt 路由 |
19
+
20
+ ## 快速开始
21
+
22
+ ```bash
23
+ # 安装 — 指定你的工具
24
+ npx @alenfitz/spec-copilot install --tool cursor
25
+ npx @alenfitz/spec-copilot install --tool claude-code
26
+ npx @alenfitz/spec-copilot install --tool windsurf
27
+ # 可选: opencode, claude-code, cursor, windsurf, copilot, cline
28
+
29
+ # 验证安装
30
+ npx @alenfitz/spec-copilot doctor
31
+ ```
32
+
33
+ 后续命令(`update`、`doctor` 等)自动识别已安装的工具。
34
+
35
+ ## 核心理念
36
+
37
+ 1. **Spec 先行(No Spec, No Code)** — AI 评估复杂度、逐条澄清、分段生成 spec,确认才写代码。
38
+ 2. **Task 节奏可控** — AI 完成一个原子任务就停下来,展示验证证据,立即 commit,等你说"继续"才推进。
39
+ 3. **知识飞轮** — 每个需求的踩坑记录归档到带 tag 分类的知识库,下个需求自动读取。
40
+
41
+ ## 命令速查
42
+
43
+ | 命令 | 何时用 | 产出 |
44
+ |------|-------|------|
45
+ | `/spec:init` | 首次接入项目 | 填充 `rules/project-context.md` |
46
+ | `/spec:bootstrap` | 新空项目 | 栈选型 + 脚手架搭建 |
47
+ | `/spec:propose <需求>` | 有新需求 | `spec.md`(复杂需求 + `tasks.md`) |
48
+ | `/spec:flow <需求>` | 全自动模式(🟢/🟡) | 完整流水线:propose → archive |
49
+ | `/spec:apply <变更名>` | spec 确认后 | 逐 task 提交的代码 |
50
+ | `/spec:smoke <变更名>` | /spec:apply 完成后 | 编译 + 接口冒烟报告 |
51
+ | `/spec:review <变更名>` | /spec:smoke 通过后 | Spec 合规 + 代码质量审查报告 |
52
+ | `/spec:fix <变更名>` | review 有问题 | 修复 commit + 文档同步 |
53
+ | `/spec:archive <变更名>` | review 通过后 | 知识沉淀 + 分支合并提示 |
54
+ | `/spec:hotfix <描述>` | 线上故障 | 最小修复 + hotfix 分支 |
55
+ | `/spec:test <变更名>` | 补自动化测试 | 测试代码 + 运行报告 |
56
+
57
+ ## CLI 命令
58
+
59
+ ```bash
60
+ npx @alenfitz/spec-copilot install --tool <name> # 安装框架
61
+ npx @alenfitz/spec-copilot update [--force] # 升级框架
62
+ npx @alenfitz/spec-copilot gate <变更名> <phase> # 阶段门禁检查
63
+ npx @alenfitz/spec-copilot lint <变更名> # Spec 完整性检查
64
+ npx @alenfitz/spec-copilot doctor # 检查安装状态
65
+ npx @alenfitz/spec-copilot uninstall --confirm # 移除框架
66
+ ```
67
+
68
+ ## 安装后的目录结构
69
+
70
+ ```
71
+ 你的项目/
72
+ ├── <工具专属提示词文件> ← AI 读取
73
+ ├── <工具专属命令目录/> ← 原生命令(如支持)
74
+
75
+ └── spec_copilot/
76
+ ├── commands/ ← 11 个命令定义
77
+ ├── rules/
78
+ │ ├── coding-style.md ← 编码通用规范
79
+ │ ├── security.md ← 安全红线
80
+ │ ├── project-context.md ← 项目技术上下文(/spec:init 填充)
81
+ │ └── domain-rules.md ← 业务领域规则(你来填)
82
+ ├── stack-adapters/
83
+ │ ├── _template.md ← 新栈适配模板
84
+ │ └── spring-boot-vue3.md ← 内置适配(示例)
85
+ ├── knowledge/index.md ← 带 tag 索引的知识库
86
+ ├── changes/templates/ ← spec.md / tasks.md / log.md 模板
87
+ ├── archives/ ← 已归档的需求
88
+ └── scripts/ ← Lint、门禁、Hook 脚本
89
+ ```
90
+
91
+ ## 复杂度分级
92
+
93
+ | 级别 | 判定标准(按影响面) | 需要什么 |
94
+ |------|-----------------|---------|
95
+ | 🟢 简单 | 不改 API / 不改表 / 不改核心流程 / 不引入新依赖 | 直接对话 |
96
+ | 🟡 中等 | 新增接口 / 改表非核心字段 / 新依赖 | spec(两段确认) |
97
+ | 🔴 复杂 | 新子系统 / 核心流程 / 核心表结构 / 并发事务 | spec + tasks + knowledge |
98
+
99
+ ## 升级安全性
100
+
101
+ - **会覆盖**:coding-style.md、security.md、模板、脚本、命令、内置栈适配
102
+ - **默认跳过**:提示词文件(使用 `--force` 覆盖)
103
+ - **绝不覆盖**:project-context.md、domain-rules.md、knowledge/、changes/、archives/、自定义栈适配
104
+
105
+ ## 相关包
106
+
107
+ - [`@alenfitz/opencode-copilot`](https://www.npmjs.com/package/@alenfitz/opencode-copilot) — opencode 专属版
108
+ - [`@alenfitz/spec-driven-dev`](https://www.npmjs.com/package/@alenfitz/spec-driven-dev) — Claude Code 专属版(旧版)
109
+
110
+ ## License
111
+
112
+ MIT
@@ -0,0 +1,218 @@
1
+ /**
2
+ * Tool adapters — 每个 AI 编码工具的适配配置
3
+ *
4
+ * 每个 adapter 定义:
5
+ * - promptPath: 提示词文件相对项目根目录的路径
6
+ * - commandsDir: 原生命令目录(null = 无原生命令支持)
7
+ * - detect(projectRoot): 自动检测该工具是否在使用
8
+ * - formatPrompt(content): 将通用 prompt 转换为工具专属格式
9
+ * - formatCommand(content, meta): 将通用命令转换为工具专属格式
10
+ * - cleanupPaths: uninstall 时需清理的路径(相对项目根)
11
+ */
12
+
13
+ const fs = require('fs');
14
+ const path = require('path');
15
+
16
+ // ─── 命令路由模板(无原生命令的工具追加到 prompt 末尾) ───────
17
+
18
+ function buildCommandRoutingSection() {
19
+ return `
20
+
21
+ ---
22
+
23
+ ## 命令路由
24
+
25
+ 当用户输入以下命令时,读取对应文件并按其指令执行:
26
+
27
+ | 命令 | 读取文件 |
28
+ |------|---------|
29
+ | \`/spec:init\` | \`spec_copilot/commands/spec:init.md\` |
30
+ | \`/spec:bootstrap\` | \`spec_copilot/commands/spec:bootstrap.md\` |
31
+ | \`/spec:propose <需求>\` | \`spec_copilot/commands/spec:propose.md\` |
32
+ | \`/spec:flow <需求>\` | \`spec_copilot/commands/spec:flow.md\` |
33
+ | \`/spec:apply <变更名>\` | \`spec_copilot/commands/spec:apply.md\` |
34
+ | \`/spec:smoke <变更名>\` | \`spec_copilot/commands/spec:smoke.md\` |
35
+ | \`/spec:review <变更名>\` | \`spec_copilot/commands/spec:review.md\` |
36
+ | \`/spec:fix <变更名>\` | \`spec_copilot/commands/spec:fix.md\` |
37
+ | \`/spec:test <变更名>\` | \`spec_copilot/commands/spec:test.md\` |
38
+ | \`/spec:archive <变更名>\` | \`spec_copilot/commands/spec:archive.md\` |
39
+ | \`/spec:hotfix <描述>\` | \`spec_copilot/commands/spec:hotfix.md\` |
40
+
41
+ 用户输入命令后,**立即**读取对应文件并执行,不需要再次确认。
42
+ 将 \`<需求>\`、\`<变更名>\`、\`<描述>\` 替换为用户在命令后提供的参数。
43
+ `;
44
+ }
45
+
46
+ // ─── Adapters ───────────────────────────────────────────────
47
+
48
+ const adapters = {
49
+
50
+ // ─── opencode ────────────────────────────────────────────
51
+ opencode: {
52
+ name: 'opencode',
53
+ displayName: 'opencode',
54
+ description: 'opencode CLI (github.com/opencode-ai/opencode)',
55
+ promptPath: 'AGENTS.md',
56
+ commandsDir: '.opencode/commands',
57
+ hasNativeCommands: true,
58
+
59
+ detect(projectRoot) {
60
+ return fs.existsSync(path.join(projectRoot, '.opencode')) ||
61
+ fs.existsSync(path.join(projectRoot, 'opencode.json'));
62
+ },
63
+
64
+ formatPrompt(content) {
65
+ return content;
66
+ },
67
+
68
+ formatCommand(content, _meta) {
69
+ return content; // opencode uses same format as our command files
70
+ },
71
+
72
+ cleanupPaths: ['AGENTS.md', '.opencode/commands'],
73
+ },
74
+
75
+ // ─── Claude Code ─────────────────────────────────────────
76
+ 'claude-code': {
77
+ name: 'claude-code',
78
+ displayName: 'Claude Code',
79
+ description: 'Claude Code CLI (Anthropic)',
80
+ promptPath: 'CLAUDE.md',
81
+ commandsDir: '.claude/commands',
82
+ hasNativeCommands: true,
83
+
84
+ detect(projectRoot) {
85
+ return fs.existsSync(path.join(projectRoot, '.claude')) ||
86
+ fs.existsSync(path.join(projectRoot, 'CLAUDE.md'));
87
+ },
88
+
89
+ formatPrompt(content) {
90
+ return content;
91
+ },
92
+
93
+ formatCommand(content, _meta) {
94
+ return content; // Claude Code uses same frontmatter format
95
+ },
96
+
97
+ cleanupPaths: ['CLAUDE.md', '.claude/commands'],
98
+ },
99
+
100
+ // ─── Cursor ──────────────────────────────────────────────
101
+ cursor: {
102
+ name: 'cursor',
103
+ displayName: 'Cursor',
104
+ description: 'Cursor IDE (.cursor/rules/*.mdc)',
105
+ promptPath: '.cursor/rules/spec-copilot.mdc',
106
+ commandsDir: null, // commands go to spec_copilot/commands/
107
+ hasNativeCommands: false,
108
+
109
+ detect(projectRoot) {
110
+ return fs.existsSync(path.join(projectRoot, '.cursor')) ||
111
+ fs.existsSync(path.join(projectRoot, '.cursorrules'));
112
+ },
113
+
114
+ formatPrompt(content) {
115
+ const frontmatter = [
116
+ '---',
117
+ 'description: "Spec-Driven Development Framework — AI 编码协作规范"',
118
+ 'alwaysApply: true',
119
+ '---',
120
+ '',
121
+ ].join('\n');
122
+ return frontmatter + content + buildCommandRoutingSection();
123
+ },
124
+
125
+ formatCommand(content, _meta) {
126
+ return content; // stored in spec_copilot/commands/, not tool-specific
127
+ },
128
+
129
+ cleanupPaths: ['.cursor/rules/spec-copilot.mdc'],
130
+ },
131
+
132
+ // ─── Windsurf ────────────────────────────────────────────
133
+ windsurf: {
134
+ name: 'windsurf',
135
+ displayName: 'Windsurf',
136
+ description: 'Windsurf IDE (.windsurf/rules/)',
137
+ promptPath: '.windsurf/rules/spec-copilot.md',
138
+ commandsDir: null,
139
+ hasNativeCommands: false,
140
+
141
+ detect(projectRoot) {
142
+ return fs.existsSync(path.join(projectRoot, '.windsurf')) ||
143
+ fs.existsSync(path.join(projectRoot, '.windsurfrules'));
144
+ },
145
+
146
+ formatPrompt(content) {
147
+ return content + buildCommandRoutingSection();
148
+ },
149
+
150
+ formatCommand(content, _meta) {
151
+ return content;
152
+ },
153
+
154
+ cleanupPaths: ['.windsurf/rules/spec-copilot.md'],
155
+ },
156
+
157
+ // ─── GitHub Copilot ──────────────────────────────────────
158
+ copilot: {
159
+ name: 'copilot',
160
+ displayName: 'GitHub Copilot',
161
+ description: 'GitHub Copilot (.github/copilot-instructions.md)',
162
+ promptPath: '.github/copilot-instructions.md',
163
+ commandsDir: null,
164
+ hasNativeCommands: false,
165
+
166
+ detect(projectRoot) {
167
+ return fs.existsSync(path.join(projectRoot, '.github', 'copilot-instructions.md'));
168
+ },
169
+
170
+ formatPrompt(content) {
171
+ return content + buildCommandRoutingSection();
172
+ },
173
+
174
+ formatCommand(content, _meta) {
175
+ return content;
176
+ },
177
+
178
+ cleanupPaths: ['.github/copilot-instructions.md'],
179
+ },
180
+
181
+ // ─── Cline ───────────────────────────────────────────────
182
+ cline: {
183
+ name: 'cline',
184
+ displayName: 'Cline',
185
+ description: 'Cline VSCode extension (.clinerules/)',
186
+ promptPath: '.clinerules/spec-copilot.md',
187
+ commandsDir: null,
188
+ hasNativeCommands: false,
189
+
190
+ detect(projectRoot) {
191
+ return fs.existsSync(path.join(projectRoot, '.clinerules')) ||
192
+ fs.existsSync(path.join(projectRoot, '.cline'));
193
+ },
194
+
195
+ formatPrompt(content) {
196
+ return content + buildCommandRoutingSection();
197
+ },
198
+
199
+ formatCommand(content, _meta) {
200
+ return content;
201
+ },
202
+
203
+ cleanupPaths: ['.clinerules/spec-copilot.md'],
204
+ },
205
+
206
+ };
207
+
208
+ /** 自动检测项目中使用的工具 */
209
+ function detectTools(projectRoot) {
210
+ return Object.values(adapters).filter(a => a.detect(projectRoot));
211
+ }
212
+
213
+ /** 获取所有支持的工具名 */
214
+ function supportedTools() {
215
+ return Object.keys(adapters);
216
+ }
217
+
218
+ module.exports = { adapters, detectTools, supportedTools, buildCommandRoutingSection };