newbee-sdd 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 +167 -0
- package/SKILL.md +128 -0
- package/bin/newbee-sdd.js +120 -0
- package/lib/index.js +12 -0
- package/lib/installer.js +178 -0
- package/lib/updater.js +40 -0
- package/lib/verifier.js +197 -0
- package/package.json +39 -0
- package/references/architecture-guide.md +45 -0
- package/references/checklists.md +75 -0
- package/references/schemes.md +54 -0
- package/references/stages.md +75 -0
- package/scripts/newbee-sdd-check.ps1 +242 -0
- package/templates/CONVENTIONS.md +23 -0
- package/templates/INDEX.md +11 -0
- package/templates/plan.md +74 -0
- package/templates/spec.md +59 -0
- package/templates/tasks.md +28 -0
- package/upgrade.md +46 -0
package/README.md
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# newbee-sdd
|
|
2
|
+
|
|
3
|
+
> **规格驱动开发(Spec-Driven Development)通用规范与多宿主工具套件**
|
|
4
|
+
> 规格先行 · 全链路 ID 双向追溯 · S/L 双轨制 · Fresh-Context 独立审查
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 📖 核心理念
|
|
9
|
+
|
|
10
|
+
**「规格是唯一事实来源,代码是规格的可再生产物。」**
|
|
11
|
+
|
|
12
|
+
在 AI 编码时代,很多开发者陷入了“让 AI 自由发挥、反复打补丁”的泥潭。`newbee-sdd` 提供了一套工业级的规格开发方法论:
|
|
13
|
+
1. **先厘清、后架构、再编码**:通过结构化的规格与验收标准约束 AI,拒绝隐式假设。
|
|
14
|
+
2. **S/L 双轨同构(一脉相承)**:小功能 S 轨单文件极速闭环;大系统 L 轨展开全套架构方案与防御性设计,支持平滑无损升轨。
|
|
15
|
+
3. **全链路 ID 闭环**:`REQ`(需求)↔ `RULE`(规则)↔ `TC`(用例)↔ `TASK`(任务),机器自动化对账,无漏网之鱼。
|
|
16
|
+
4. **多宿主(Multi-Harness)原生兼容**:一套核心资产,同时无缝支持 **dsh**、**OpenCode**、**Claude Code**、**Cursor**、**Codex**。
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## 🚀 快速上手
|
|
21
|
+
|
|
22
|
+
### 1. 一键分发安装到本机开发工具
|
|
23
|
+
|
|
24
|
+
无需全局安装,使用 `npx` 即可将 `newbee-sdd` 规范挂载到您的开发工具中:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
# 一键安装到本机所有支持的环境(自动检测 dsh / OpenCode / Claude Code / Cursor / Codex)
|
|
28
|
+
npx newbee-sdd install
|
|
29
|
+
|
|
30
|
+
# 或者仅安装到指定宿主:
|
|
31
|
+
npx newbee-sdd install opencode
|
|
32
|
+
npx newbee-sdd install claude
|
|
33
|
+
npx newbee-sdd install dsh
|
|
34
|
+
npx newbee-sdd install cursor
|
|
35
|
+
npx newbee-sdd install codex
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### 2. 在工程中初始化规格骨架
|
|
39
|
+
|
|
40
|
+
在需要开启规格驱动的项目根目录下执行:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
npx newbee-sdd init
|
|
44
|
+
```
|
|
45
|
+
将在当前目录生成标准 `newbee-specs/` 目录结构与标准模板文件。
|
|
46
|
+
|
|
47
|
+
### 3. 运行零 Token 机器自动化校验
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
npx newbee-sdd verify
|
|
51
|
+
```
|
|
52
|
+
自动扫描当前工程规格,校验 `REQ ↔ RULE ↔ TC ↔ TASK` 闭环覆盖度,检查模糊词与未追溯标记 `[untracked]`。
|
|
53
|
+
|
|
54
|
+
### 4. 一键无痛升级
|
|
55
|
+
|
|
56
|
+
当 `newbee-sdd` 发布新版本时,升级只需一行命令:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
npx newbee-sdd update
|
|
60
|
+
```
|
|
61
|
+
> **安全声明**:升级仅同步引擎规范、模板和校验脚本,**绝不触碰或改动您项目既有的任何业务规格工件!**
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## 🛠️ CLI 命令速查
|
|
66
|
+
|
|
67
|
+
| 命令 | 别名 | 说明 |
|
|
68
|
+
|---|---|---|
|
|
69
|
+
| `npx newbee-sdd install [target]` | `i` | 安装/挂载规范到指定宿主或全部宿主 |
|
|
70
|
+
| `npx newbee-sdd update` | `u` | 一键无痛升级所有已安装宿主的规范定义 |
|
|
71
|
+
| `npx newbee-sdd verify` | `v` / `check` | 运行纯 Node.js 跨平台追溯链机器自动化校验 |
|
|
72
|
+
| `npx newbee-sdd init` | — | 在当前项目中初始化 `newbee-specs` 模板结构 |
|
|
73
|
+
| `npx newbee-sdd --version` | `-v` | 查看当前发布版本 |
|
|
74
|
+
| `npx newbee-sdd --help` | `-h` | 查看帮助文档 |
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## 🎯 宿主(Harness)支持矩阵与使用指南
|
|
79
|
+
|
|
80
|
+
| 宿主工具 | 安装路径与形式 | 运行机制与唤起方式 |
|
|
81
|
+
|:---|:---|:---|
|
|
82
|
+
| **OpenCode** | `~/.config/opencode/skills/newbee-sdd/` | **原生 Skill**:对话中直接提需求或输入 `/newbee-sdd` 唤起;支持 `subagent` 独立复审 |
|
|
83
|
+
| **Claude Code** | `~/.claude/skills/newbee-sdd/` | **官方 Skill**:在对话中说「使用 newbee-sdd 规划...」或输入 `/newbee-sdd` 唤起 |
|
|
84
|
+
| **DeepSeek Harness (dsh)** | `~/.agents/skills/newbee-sdd/` | **深度集成**:挂载 `subagent` 复审、`exit_plan_mode` 批准与本地 PowerShell 脚本 |
|
|
85
|
+
| **Cursor** | `~/.cursor/rules/newbee-sdd.mdc` | **Rules 规则约束**:在 Composer / Chat 中提需求,AI 自动按 S/L 轨生成规范与 ID |
|
|
86
|
+
| **Codex / Copilot** | `~/.codex/skills/newbee-sdd/` | **指令约束**:约束输出严格遵循 REQ/RULE/TC 契约 |
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## 💡 常用实战对话范例(怎么跟 AI 说)
|
|
91
|
+
|
|
92
|
+
安装成功后,您可以在各大 AI 编程助手中直接用自然语言与它交互:
|
|
93
|
+
|
|
94
|
+
### 1. 开启一个新功能规格(S 轨敏捷模式)
|
|
95
|
+
> **你对 AI 说**:
|
|
96
|
+
> *“我要为用户中心加一个『修改绑定手机号』的功能,比较简单,请按 newbee-sdd 的 S 轨为我生成 spec.md。”*
|
|
97
|
+
> **AI 的行为**:自动提炼背景,列出 `REQ-001`(带 GWT 验收条件)、`RULE-001`(验证码过期规则)与 `TC-001`(测试用例),并在 `newbee-specs/`(或当前目录)产出完整单文件规格。
|
|
98
|
+
|
|
99
|
+
### 2. 开启一个复杂系统设计(L 轨深度模式)
|
|
100
|
+
> **你对 AI 说**:
|
|
101
|
+
> *“我们要重构分布式对账结算系统,涉及外部支付渠道和高并发防重,请按 newbee-sdd 的 L 轨走完整流程。”*
|
|
102
|
+
> **AI 的行为**:
|
|
103
|
+
> 1. 先进行需求澄清,确认待决问题(Open Questions);
|
|
104
|
+
> 2. 生成 `spec.md` 并等待你批准(`status: approved`);
|
|
105
|
+
> 3. 产出 `plan.md`,绘制 C4 模块图,设计超时/重试/幂等防御方案;
|
|
106
|
+
> 4. 产出 `tasks.md`,拆解出带拓扑排序的微任务与 RTM 追溯矩阵。
|
|
107
|
+
|
|
108
|
+
### 3. 要求独立复审(审查门禁)
|
|
109
|
+
> **你对 AI 说**:
|
|
110
|
+
> *“请帮我按照 newbee-sdd 的 checklists,严格复审当前的 spec.md。”*
|
|
111
|
+
> **AI 的行为**:在 OpenCode 等工具中会自动调用 `subagent` 开启全新独立上下文,逐项核对可验证性、模糊词与覆盖率,输出结构化的 FIND 缺陷报告(APPROVE / REQUEST-CHANGES)。
|
|
112
|
+
|
|
113
|
+
### 4. 本地终端一键机器对账
|
|
114
|
+
> 在终端直接执行:
|
|
115
|
+
> ```bash
|
|
116
|
+
> npx newbee-sdd verify
|
|
117
|
+
> ```
|
|
118
|
+
> 0 Token 消耗,纯 Node.js 秒级对账全链路 ID 是否闭环。
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## 📐 S/L 轨道体系
|
|
123
|
+
|
|
124
|
+
| 维度 | S 轨(Small - 敏捷紧凑模式) | L 轨(Large - 工业深度流水线) |
|
|
125
|
+
|---|---|---|
|
|
126
|
+
| **适用场景** | 单模块、工作量 ≤ 1 天、无新外部依赖 | 跨模块、涉及高并发/NFR、新增外部集成 |
|
|
127
|
+
| **产出工件** | 单一 `spec.md` 一档闭环 | `spec.md` → `plan.md` (C4/防御设计) → `tasks.md` |
|
|
128
|
+
| **审查机制** | 规则自查 + 机器校验(`verify`) | Fresh-Context 独立子代理复审 + 机器校验 + 人工冻结 |
|
|
129
|
+
| **升轨机制** | — | **平滑无损**:S 轨写到中途可直接解包展开为 L 轨,ID 保持不变 |
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## 🔗 ID 追溯体系与铁律
|
|
134
|
+
|
|
135
|
+
全链路采用统一 ID 体系保障可追溯性:
|
|
136
|
+
* `REQ-###`:功能需求(含 Given/When/Then 验收条件)
|
|
137
|
+
* `NFR-###`:非功能需求(量化指标 + 量测方式)
|
|
138
|
+
* `RULE-###`:业务规则约束
|
|
139
|
+
* `DEC-###`:关键决策记录(含 Context 与 Consequences)
|
|
140
|
+
* `MOD-###`:系统模块与职责划分(单一职责)
|
|
141
|
+
* `TC-###`:测试用例(100% 覆盖 REQ 与 RULE)
|
|
142
|
+
* `TASK-###`:拆解任务(单人 0.5~2 天,可独立验收)
|
|
143
|
+
* `FIND-###`:审查发现问题(强制二选一:转正为 ID 追踪 或 负责人书面豁免)
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## 📦 发布到 npm
|
|
148
|
+
|
|
149
|
+
在发布之前,可进行本地测试:
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
# 本地测试 CLI
|
|
153
|
+
node bin/newbee-sdd.js --help
|
|
154
|
+
|
|
155
|
+
# 验证机器检查功能
|
|
156
|
+
node bin/newbee-sdd.js verify
|
|
157
|
+
|
|
158
|
+
# 发布到 npm 官方仓库
|
|
159
|
+
npm publish --access public
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## 👤 作者与许可证
|
|
165
|
+
|
|
166
|
+
* **Author**: qieb
|
|
167
|
+
* **License**: MIT
|
package/SKILL.md
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: newbee-sdd
|
|
3
|
+
description: "规格驱动开发工作流(newbee 流派):规格先行、全链路ID双向追溯(REQ↔RULE↔TC↔TASK)、S/L双轨制(S轨单文件spec / L轨spec+plan+tasks全套)、Fresh-Context客观审查与自动化机器对账。支持 dsh, OpenCode, Claude Code, Cursor, Codex 等多宿主环境。USE FOR: 用户提出新系统/新功能想法、要求编写规格/技术方案/任务拆解、说 spec/plan/tasks/review、在项目中开发新功能。DO NOT USE FOR: 修复已知 Bug 与单行微小改动(走项目既有流程);检测到项目已有自有 SDD 规范且用户未显式点名时主动让位。"
|
|
4
|
+
license: MIT
|
|
5
|
+
metadata:
|
|
6
|
+
author: qieb
|
|
7
|
+
version: "1.0.0"
|
|
8
|
+
scheme: "newbee-sdd v1"
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# newbee-sdd:规格驱动开发(newbee 流派)
|
|
12
|
+
|
|
13
|
+
规格是唯一事实来源,代码是规格的可再生产物。本规范遵循“薄内核”原则:主入口定义生命周期、质量门禁与铁律契约,细致清单沉淀于 `references/`,标准模板在 `templates/`,自动化检查通过 CLI / 脚本保证。
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## 触发契约(三道门禁,按序执行)
|
|
18
|
+
|
|
19
|
+
1. **用户显示意图最高**:用户点名 newbee-sdd → 立即执行;用户声明「按项目既有规范」→ 本规范完全不介入。
|
|
20
|
+
2. **存量让位声明**:若检测到项目存在自有 SDD 规范(如已有 `specs/`、`spec/`、`docs/sdd/`、项目 AGENTS.md 另有声明)且用户未明确点名 → 主动让位,仅报告「检测到项目有自有规格方案,newbee-sdd 待命」。
|
|
21
|
+
3. **Stage 0 确认**:已加载但发现未知或冲突方案痕迹,且用户未明确指示 → 在写入任何新文件之前先向用户确认,绝不猜测。
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Stage 0:方案地图(写入任何文件之前必做)
|
|
26
|
+
|
|
27
|
+
1. **全景扫描**:扫描项目根目录是否存在:`newbee-specs/`、`.newbee-specs-path`、`specs/`、`spec/`、`docs/sdd/`、`spec.md`。
|
|
28
|
+
2. **输出三行报告**:
|
|
29
|
+
- 自有正本状况(保护不改动)
|
|
30
|
+
- 项目定制规范(`CONVENTIONS.md`,按其要求执行)
|
|
31
|
+
- newbee 默认生效项(其余规则)
|
|
32
|
+
3. **工件根解析**:
|
|
33
|
+
- 若项目根目录有 `.newbee-specs-path`(包含单行绝对路径)→ 以其指向为准;若指向无效 → **明确报错停下(fail-loud)**。
|
|
34
|
+
- 若无上述声明 → 默认使用 `<项目根>\newbee-specs\` 或既有规格目录。
|
|
35
|
+
4. **断点续跑与编号**:新功能夹层编号取现有最大编号 + 1(如 `001-xxx`);已有工件按 `scheme: newbee-sdd v1` 进行领地认领,不重复创建。
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## 轨道选择(S 轨与 L 轨一脉相承)
|
|
40
|
+
|
|
41
|
+
S 轨与 L 轨共享同一元模型与追溯体系,差异仅在展开粒度:
|
|
42
|
+
|
|
43
|
+
| 轨道 | 判定标准 | 交付工件 | 核心门禁 |
|
|
44
|
+
|---|---|---|---|
|
|
45
|
+
| **S 轨 (Small)** | 单模块/子项目、工作量 ≤ 1 天、无新增外部依赖 | `spec.md` 一档闭环 | 结构自查 + 机器校验(`verify`) |
|
|
46
|
+
| **L 轨 (Large)** | 跨模块、有 NFR 性能要求、新增外部依赖集成 | `spec.md` → `plan.md` → `tasks.md` | 独立 Fresh-Context 评审 + 机器校验 + 人工冻结 |
|
|
47
|
+
|
|
48
|
+
> **平滑升轨机制**:S 轨写到中途如发现复杂度提升,可直接将各章节展开为 L 轨的独立工件,已有 `REQ/RULE/TC` 标号无需变更,平滑无损。
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## 阶段与门禁(L 轨走全流程;S 轨完成 1-2 即闭环)
|
|
53
|
+
|
|
54
|
+
| 阶段 | 阶段名称 | 核心交付工件 | 质量门禁与准出条件 |
|
|
55
|
+
|---|---|---|---|
|
|
56
|
+
| **1** | 需求澄清与规格制定 | `spec.md`(REQ+GWT 验收条件、RULE、DEC、TC 全链路闭环) | Fresh-Context 独立复审 + 机器自动化校验(`verify`) |
|
|
57
|
+
| **2** | 用户评审与需求冻结 | spec.md 状态更新为 `approved` | 用户明确确认并批准,需求正式定格 |
|
|
58
|
+
| **3** | 技术方案与架构设计 | `plan.md`(选型评分矩阵、C4 组件图、外部依赖失败模式) | 关键架构选型向用户确认 |
|
|
59
|
+
| **4** | 任务拆解与 RTM 建立 | `tasks.md`(TASK 清单、依赖拓扑、RTM 矩阵) | 机器校验覆反对账(100% 覆盖) |
|
|
60
|
+
| **5** | 编码实施与代码审查 | 业务代码 + RTM 实现状态回填 | 任务粒度完成 → 代码四维审查(Bug/性能/安全/可维护性) |
|
|
61
|
+
| **6** | 收尾与全链路对账 | 状态更新为 `done`;更新 `INDEX.md` 索引表 | RTM 全闭环,无孤立待决缺陷 |
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## 多宿主(Multi-Harness)机制挂载与自适应
|
|
66
|
+
|
|
67
|
+
| 宿主工具 | 特色能力与挂载机制 | 降级机制 |
|
|
68
|
+
|---|---|---|
|
|
69
|
+
| **OpenCode** | 通过 `subagent` 工具执行 Fresh-Context 独立复审;利用机器脚本自动核验 | 无 subagent 时降级为分步自查 |
|
|
70
|
+
| **Claude Code** | 官方 Skill 原生驱动;可调用独立子会话进行代码审查 | 遵循标准指令流 |
|
|
71
|
+
| **dsh (DeepSeek Harness)** | 挂载 `subagent` 复审、`exit_plan_mode` 批准、`goal` 工具跨会话追踪 | 标准命令行对账 |
|
|
72
|
+
| **Cursor** | 作为 `.cursorrules` / `.mdc` 系统规则,严格约束生成格式与追溯 ID | 提示词驱动自检 |
|
|
73
|
+
| **Codex / Copilot** | 作为 Agent 指令或项目规范,约束输出符合 REQ/RULE 契约 | 纯提示词标准模式 |
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## 核心铁律(不可被覆盖的质量契约)
|
|
78
|
+
|
|
79
|
+
1. **身份行契约**:工件头部必须包含 `scheme: newbee-sdd v1`,校验工具依此辨识身份。
|
|
80
|
+
2. **全链路追溯 ID 闭环**:`REQ ↔ RULE ↔ TC ↔ TASK` 必须双向可追;未追溯内容标记 `[untracked]` 并需人工裁决。
|
|
81
|
+
3. **报错不回退(fail-loud)**:配置错误、指针失效时直接报错停下,绝不静默回退猜测。
|
|
82
|
+
4. **写审分离原则**:在支持的宿主中,复审必须使用全新上下文(Fresh Context),审者不得既当运动员又当裁判员。
|
|
83
|
+
5. **门禁只严不宽**:项目 `CONVENTIONS.md` 只允许对标准进行加严,绝不允许削减核心门禁。
|
|
84
|
+
6. **编号终身制**:REQ/RULE/TC 标号一旦生效不可更改或复用;废弃条目标注 `superseded`,历史有迹可循。
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## 状态机规范
|
|
89
|
+
|
|
90
|
+
功能夹层的生命周期状态标记在 `spec.md` 的 frontmatter 中:
|
|
91
|
+
|
|
92
|
+
```text
|
|
93
|
+
draft (草稿) ──▶ approved (已冻结) ──▶ implementing (实施中) ──▶ done (已完成)
|
|
94
|
+
│ │
|
|
95
|
+
└───▶ blocked (阻断) ───┘
|
|
96
|
+
│
|
|
97
|
+
deprecated (已废弃,夹层保留)
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
- `approved`:需求冻结,除修复笔误外,业务变更加写变更记录。
|
|
101
|
+
- `implementing`:实施中仅允许回填 tasks 进度与 RTM 提交哈希,不擅改 spec/plan 内容。
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## 常用命令与辅助工具
|
|
106
|
+
|
|
107
|
+
项目安装本 npm 包后,可在终端直接使用:
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
# 校验当前项目规格的追溯闭环性与无歧义性(零 Token 消耗)
|
|
111
|
+
npx newbee-sdd verify
|
|
112
|
+
|
|
113
|
+
# 在当前工程快速初始化 newbee-specs 结构
|
|
114
|
+
npx newbee-sdd init
|
|
115
|
+
|
|
116
|
+
# 一键将规范升级同步至本机所有支持的宿主环境
|
|
117
|
+
npx newbee-sdd update
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## 卸载与无痕治理
|
|
123
|
+
|
|
124
|
+
- **卸载**:运行 `npx newbee-sdd uninstall` 或直接删除对应工具的 skill 目录;项目内的 `newbee-specs/` 属于用户数据资产,永久完整保留。
|
|
125
|
+
- **治理档位**:
|
|
126
|
+
- **A 档(默认推荐)**:`newbee-specs/` 纳入本地 git 管理,若不希望提交远端可在 `.gitignore` 排除。
|
|
127
|
+
- **B 档**:完全不纳入版本控制(用户自担数据丢失风险)。
|
|
128
|
+
- **C 档**:通过 `.newbee-specs-path` 将工件存储在代码仓外部的专用目录。
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const { installAll, installToTarget, getTargets } = require('../lib/installer');
|
|
6
|
+
const { update } = require('../lib/updater');
|
|
7
|
+
const { verify } = require('../lib/verifier');
|
|
8
|
+
|
|
9
|
+
const PACKAGE_ROOT = path.resolve(__dirname, '..');
|
|
10
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(PACKAGE_ROOT, 'package.json'), 'utf8'));
|
|
11
|
+
|
|
12
|
+
const args = process.argv.slice(2);
|
|
13
|
+
const command = args[0] ? args[0].toLowerCase() : 'help';
|
|
14
|
+
|
|
15
|
+
function printBanner() {
|
|
16
|
+
console.log(`
|
|
17
|
+
╔═══════════════════════════════════════════════════════════╗
|
|
18
|
+
║ newbee-sdd v${pkg.version} ║
|
|
19
|
+
║ 规格驱动开发工作流 · S/L双轨制 · 全链路ID追溯 ║
|
|
20
|
+
║ 支持 dsh / OpenCode / Claude Code / Cursor / Codex ║
|
|
21
|
+
╚═══════════════════════════════════════════════════════════╝
|
|
22
|
+
`);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function printHelp() {
|
|
26
|
+
printBanner();
|
|
27
|
+
console.log(`使用方法:
|
|
28
|
+
npx newbee-sdd <命令> [选项]
|
|
29
|
+
|
|
30
|
+
常用命令:
|
|
31
|
+
install, i [目标] 安装规范到指定或全部宿主 (opencode, claude, dsh, cursor, codex)
|
|
32
|
+
update, u 一键无痛升级已安装的规范与脚本 (不改动您的已有项目工件)
|
|
33
|
+
verify, v 机器校验当前项目的追溯链闭环 (REQ ↔ RULE ↔ TC ↔ TASK)
|
|
34
|
+
init 在当前工程初始化 newbee-specs 目录结构与标准模板
|
|
35
|
+
version, -v 查看当前版本号
|
|
36
|
+
help, -h 查看此帮助文档
|
|
37
|
+
|
|
38
|
+
示例:
|
|
39
|
+
npx newbee-sdd install # 一键分发到全部支持的宿主工具
|
|
40
|
+
npx newbee-sdd install opencode # 仅安装到 OpenCode
|
|
41
|
+
npx newbee-sdd update # 一键升级最新规则
|
|
42
|
+
npx newbee-sdd verify # 零 Token 自动化校验当前项目规格
|
|
43
|
+
npx newbee-sdd init # 在当前项目新建规格骨架
|
|
44
|
+
`);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function initProject(targetDir = process.cwd()) {
|
|
48
|
+
console.log(`\n📁 正在初始化 newbee-sdd 规格骨架: ${targetDir}`);
|
|
49
|
+
const specsDir = path.join(targetDir, 'newbee-specs');
|
|
50
|
+
if (!fs.existsSync(specsDir)) {
|
|
51
|
+
fs.mkdirSync(specsDir, { recursive: true });
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// 复制模板
|
|
55
|
+
const templatesDir = path.join(PACKAGE_ROOT, 'templates');
|
|
56
|
+
if (fs.existsSync(templatesDir)) {
|
|
57
|
+
const tpls = fs.readdirSync(templatesDir);
|
|
58
|
+
for (const tpl of tpls) {
|
|
59
|
+
const src = path.join(templatesDir, tpl);
|
|
60
|
+
const dest = path.join(specsDir, tpl);
|
|
61
|
+
if (!fs.existsSync(dest)) {
|
|
62
|
+
fs.copyFileSync(src, dest);
|
|
63
|
+
console.log(` + 生成模板: newbee-specs/${tpl}`);
|
|
64
|
+
} else {
|
|
65
|
+
console.log(` - 已存在,跳过覆盖: newbee-specs/${tpl}`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
console.log(`\n🎉 初始化完成!您可以在 newbee-specs/ 中开始编写规格。\n`);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
switch (command) {
|
|
74
|
+
case 'install':
|
|
75
|
+
case 'i': {
|
|
76
|
+
const target = args[1];
|
|
77
|
+
if (target) {
|
|
78
|
+
installToTarget(target.toLowerCase(), PACKAGE_ROOT);
|
|
79
|
+
} else {
|
|
80
|
+
installAll(PACKAGE_ROOT);
|
|
81
|
+
}
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
case 'update':
|
|
86
|
+
case 'u': {
|
|
87
|
+
update(PACKAGE_ROOT);
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
case 'verify':
|
|
92
|
+
case 'v':
|
|
93
|
+
case 'check': {
|
|
94
|
+
const res = verify(process.cwd());
|
|
95
|
+
if (!res.ok) {
|
|
96
|
+
process.exitCode = 1;
|
|
97
|
+
}
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
case 'init': {
|
|
102
|
+
initProject(process.cwd());
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
case 'version':
|
|
107
|
+
case '-v':
|
|
108
|
+
case '--version': {
|
|
109
|
+
console.log(`v${pkg.version}`);
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
case 'help':
|
|
114
|
+
case '-h':
|
|
115
|
+
case '--help':
|
|
116
|
+
default: {
|
|
117
|
+
printHelp();
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
}
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const { verify, findSpecsDir } = require('./verifier');
|
|
2
|
+
const { installAll, installToTarget, getTargets } = require('./installer');
|
|
3
|
+
const { update } = require('./updater');
|
|
4
|
+
|
|
5
|
+
module.exports = {
|
|
6
|
+
verify,
|
|
7
|
+
findSpecsDir,
|
|
8
|
+
installAll,
|
|
9
|
+
installToTarget,
|
|
10
|
+
getTargets,
|
|
11
|
+
update
|
|
12
|
+
};
|
package/lib/installer.js
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const os = require('os');
|
|
4
|
+
|
|
5
|
+
const HOME = os.homedir();
|
|
6
|
+
const RECORD_FILE = path.join(HOME, '.newbee-sdd-installed.json');
|
|
7
|
+
|
|
8
|
+
// 定义 5 大宿主目标路径
|
|
9
|
+
function getTargets(baseDir) {
|
|
10
|
+
return {
|
|
11
|
+
opencode: {
|
|
12
|
+
name: 'OpenCode',
|
|
13
|
+
type: 'skill',
|
|
14
|
+
path: path.join(HOME, '.config', 'opencode', 'skills', 'newbee-sdd'),
|
|
15
|
+
desc: 'OpenCode 全局 Skill 目录'
|
|
16
|
+
},
|
|
17
|
+
claude: {
|
|
18
|
+
name: 'Claude Code',
|
|
19
|
+
type: 'skill',
|
|
20
|
+
path: path.join(HOME, '.claude', 'skills', 'newbee-sdd'),
|
|
21
|
+
desc: 'Claude Code 官方 Skill 目录'
|
|
22
|
+
},
|
|
23
|
+
dsh: {
|
|
24
|
+
name: 'DeepSeek Harness (dsh)',
|
|
25
|
+
type: 'skill',
|
|
26
|
+
path: path.join(HOME, '.agents', 'skills', 'newbee-sdd'),
|
|
27
|
+
desc: 'dsh / agents 官方 Skill 目录'
|
|
28
|
+
},
|
|
29
|
+
cursor: {
|
|
30
|
+
name: 'Cursor Rules',
|
|
31
|
+
type: 'rule',
|
|
32
|
+
path: path.join(HOME, '.cursor', 'rules', 'newbee-sdd.mdc'),
|
|
33
|
+
desc: 'Cursor 全局或系统 Rules 规范文件'
|
|
34
|
+
},
|
|
35
|
+
codex: {
|
|
36
|
+
name: 'Codex / Copilot',
|
|
37
|
+
type: 'skill',
|
|
38
|
+
path: path.join(HOME, '.codex', 'skills', 'newbee-sdd'),
|
|
39
|
+
desc: 'Codex / Copilot 规范目录'
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* 递归复制目录内容
|
|
46
|
+
*/
|
|
47
|
+
function copyDirSync(src, dest) {
|
|
48
|
+
if (!fs.existsSync(dest)) {
|
|
49
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const entries = fs.readdirSync(src, { withFileTypes: true });
|
|
53
|
+
for (const entry of entries) {
|
|
54
|
+
const srcPath = path.join(src, entry.name);
|
|
55
|
+
const destPath = path.join(dest, entry.name);
|
|
56
|
+
|
|
57
|
+
if (entry.isDirectory()) {
|
|
58
|
+
if (entry.name !== 'node_modules' && entry.name !== '.git') {
|
|
59
|
+
copyDirSync(srcPath, destPath);
|
|
60
|
+
}
|
|
61
|
+
} else {
|
|
62
|
+
fs.copyFileSync(srcPath, destPath);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* 安装核心资产到目标
|
|
69
|
+
*/
|
|
70
|
+
function installToTarget(targetKey, packageRoot) {
|
|
71
|
+
const targets = getTargets(packageRoot);
|
|
72
|
+
const target = targets[targetKey];
|
|
73
|
+
if (!target) {
|
|
74
|
+
throw new Error(`未知的安装目标: ${targetKey}`);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
console.log(`📦 正在为 [${target.name}] 安装 newbee-sdd...`);
|
|
78
|
+
|
|
79
|
+
if (target.type === 'skill') {
|
|
80
|
+
// 复制整个 skill 核心 (SKILL.md, references/, templates/, scripts/)
|
|
81
|
+
if (!fs.existsSync(target.path)) {
|
|
82
|
+
fs.mkdirSync(target.path, { recursive: true });
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// 复制文件
|
|
86
|
+
const filesToCopy = ['SKILL.md', 'upgrade.md', 'README.md'];
|
|
87
|
+
for (const file of filesToCopy) {
|
|
88
|
+
const srcFile = path.join(packageRoot, file);
|
|
89
|
+
if (fs.existsSync(srcFile)) {
|
|
90
|
+
fs.copyFileSync(srcFile, path.join(target.path, file));
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// 复制文件夹
|
|
95
|
+
const dirsToCopy = ['references', 'templates', 'scripts'];
|
|
96
|
+
for (const dir of dirsToCopy) {
|
|
97
|
+
const srcDir = path.join(packageRoot, dir);
|
|
98
|
+
if (fs.existsSync(srcDir)) {
|
|
99
|
+
copyDirSync(srcDir, path.join(target.path, dir));
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
} else if (target.type === 'rule') {
|
|
103
|
+
// 为 Cursor 产出适配的 .mdc 规则文件
|
|
104
|
+
const ruleDir = path.dirname(target.path);
|
|
105
|
+
if (!fs.existsSync(ruleDir)) {
|
|
106
|
+
fs.mkdirSync(ruleDir, { recursive: true });
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const skillContent = fs.readFileSync(path.join(packageRoot, 'SKILL.md'), 'utf8');
|
|
110
|
+
const mdcHeader = `---
|
|
111
|
+
description: 规格驱动开发(newbee-sdd):S/L双轨制、ID追溯链(REQ/RULE/TC/TASK)
|
|
112
|
+
globs: **/*
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
`;
|
|
116
|
+
fs.writeFileSync(target.path, mdcHeader + skillContent, 'utf8');
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
console.log(` ✅ 安装成功 -> ${target.path}`);
|
|
120
|
+
recordInstalledTarget(targetKey, target.path);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* 记录已安装的目标
|
|
125
|
+
*/
|
|
126
|
+
function recordInstalledTarget(key, installedPath) {
|
|
127
|
+
let records = {};
|
|
128
|
+
if (fs.existsSync(RECORD_FILE)) {
|
|
129
|
+
try {
|
|
130
|
+
records = JSON.parse(fs.readFileSync(RECORD_FILE, 'utf8'));
|
|
131
|
+
} catch (e) {
|
|
132
|
+
records = {};
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
records[key] = {
|
|
136
|
+
path: installedPath,
|
|
137
|
+
installedAt: new Date().toISOString()
|
|
138
|
+
};
|
|
139
|
+
fs.writeFileSync(RECORD_FILE, JSON.stringify(records, null, 2), 'utf8');
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* 获取安装记录
|
|
144
|
+
*/
|
|
145
|
+
function getInstalledRecords() {
|
|
146
|
+
if (!fs.existsSync(RECORD_FILE)) return {};
|
|
147
|
+
try {
|
|
148
|
+
return JSON.parse(fs.readFileSync(RECORD_FILE, 'utf8'));
|
|
149
|
+
} catch (e) {
|
|
150
|
+
return {};
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* 全量安装到所有支持的目标
|
|
156
|
+
*/
|
|
157
|
+
function installAll(packageRoot) {
|
|
158
|
+
const targets = getTargets(packageRoot);
|
|
159
|
+
console.log(`\n🚀 开始多环境分发 newbee-sdd 规范...`);
|
|
160
|
+
console.log(`📋 支持平台: OpenCode, Claude Code, dsh, Cursor, Codex\n`);
|
|
161
|
+
|
|
162
|
+
for (const key of Object.keys(targets)) {
|
|
163
|
+
try {
|
|
164
|
+
installToTarget(key, packageRoot);
|
|
165
|
+
} catch (err) {
|
|
166
|
+
console.error(` ❌ [${targets[key].name}] 安装遇到问题: ${err.message}`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
console.log(`\n🎉 安装完成!所有平台已全部挂载 newbee-sdd 规范。\n`);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
module.exports = {
|
|
174
|
+
getTargets,
|
|
175
|
+
installToTarget,
|
|
176
|
+
installAll,
|
|
177
|
+
getInstalledRecords
|
|
178
|
+
};
|
package/lib/updater.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const { getTargets, installToTarget, getInstalledRecords } = require('./installer');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* 执行无痛升级逻辑
|
|
7
|
+
*/
|
|
8
|
+
function update(packageRoot) {
|
|
9
|
+
console.log(`\n🔄 [newbee-sdd] 正在检查已安装的宿主环境与升级规则...`);
|
|
10
|
+
|
|
11
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(packageRoot, 'package.json'), 'utf8'));
|
|
12
|
+
console.log(`📌 当前最新发布版本: v${pkg.version}`);
|
|
13
|
+
|
|
14
|
+
const records = getInstalledRecords();
|
|
15
|
+
const installedKeys = Object.keys(records);
|
|
16
|
+
|
|
17
|
+
if (installedKeys.length === 0) {
|
|
18
|
+
console.log(`💡 未检测到历史安装记录,将自动扫描并执行首次分发...`);
|
|
19
|
+
const { installAll } = require('./installer');
|
|
20
|
+
installAll(packageRoot);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
console.log(`🎯 发现已挂载的宿主目标: ${installedKeys.join(', ')}`);
|
|
25
|
+
console.log(`🛡️ 安全声明: 升级仅同步规范定义、模板与校验脚本,绝不触碰您项目已有的 specs/ 工件!\n`);
|
|
26
|
+
|
|
27
|
+
for (const key of installedKeys) {
|
|
28
|
+
try {
|
|
29
|
+
installToTarget(key, packageRoot);
|
|
30
|
+
} catch (e) {
|
|
31
|
+
console.error(` ❌ 更新 ${key} 失败: ${e.message}`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
console.log(`\n🎉 [newbee-sdd] 所有宿主已成功无痛升级至 v${pkg.version}!\n`);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
module.exports = {
|
|
39
|
+
update
|
|
40
|
+
};
|