@deepstorm/cli 0.9.1 → 0.9.2
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/dist/cli.js +8 -5
- package/dist/skills/reef-gen-backend/SKILL.md.tmpl +10 -4
- package/dist/skills/reef-gen-frontend/SKILL.md.tmpl +10 -4
- package/dist/skills/reef-start/SKILL.md.tmpl +1 -0
- package/dist/skills/reef-start/references/stage-4-implementation.md +9 -5
- package/dist/skills/reef-start/references/superpowers-gate.md +3 -0
- package/dist/skills/sweep-run/SKILL.md +22 -14
- package/dist/skills/sweep-run/scripts/flow-selector.mjs +58 -1
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -6351,10 +6351,11 @@ async function promptContinueSetup(targetDir, projectName, registry2) {
|
|
|
6351
6351
|
}
|
|
6352
6352
|
function buildContext(opts) {
|
|
6353
6353
|
const projectName = opts.projectName || "project";
|
|
6354
|
+
const packageName = projectName.replace(/[_-]/g, "").toLowerCase();
|
|
6354
6355
|
return {
|
|
6355
6356
|
projectName,
|
|
6356
|
-
packageName
|
|
6357
|
-
groupId:
|
|
6357
|
+
packageName,
|
|
6358
|
+
groupId: `com.${packageName}`,
|
|
6358
6359
|
frontend: opts.frontend || false,
|
|
6359
6360
|
backend: opts.backend || false,
|
|
6360
6361
|
uiLib: opts.uiLib || false,
|
|
@@ -6822,7 +6823,7 @@ tasks.withType<Test> {
|
|
|
6822
6823
|
useJUnitPlatform()
|
|
6823
6824
|
}
|
|
6824
6825
|
`);
|
|
6825
|
-
const appPackage =
|
|
6826
|
+
const appPackage = ctx.groupId.replace(/[.-]/g, ".");
|
|
6826
6827
|
const appDir = `src/main/java/${appPackage.replace(/\./g, "/")}`;
|
|
6827
6828
|
ensureDir2(path2.join(projectDir, appDir));
|
|
6828
6829
|
writeTemplate(projectDir, `${appDir}/Application.java`, `package ${appPackage};
|
|
@@ -6917,6 +6918,8 @@ logging:
|
|
|
6917
6918
|
${ctx.packageName}: DEBUG
|
|
6918
6919
|
`);
|
|
6919
6920
|
if (hasLiquibase) {
|
|
6921
|
+
const now = /* @__PURE__ */ new Date();
|
|
6922
|
+
const ts = now.toISOString().replace(/\D/g, "").slice(0, 12);
|
|
6920
6923
|
ensureDir2(path2.join(projectDir, "src/main/resources/db/changelog"));
|
|
6921
6924
|
writeTemplate(projectDir, "src/main/resources/db/changelog/db.changelog-master.xml", `<?xml version="1.0" encoding="UTF-8"?>
|
|
6922
6925
|
<databaseChangeLog
|
|
@@ -6925,7 +6928,7 @@ logging:
|
|
|
6925
6928
|
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
|
|
6926
6929
|
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
|
|
6927
6930
|
|
|
6928
|
-
<changeSet id="001" author="deepstorm">
|
|
6931
|
+
<changeSet id="${ts}-001" author="deepstorm">
|
|
6929
6932
|
<createTable tableName="flyway_schema_history">
|
|
6930
6933
|
<column name="version" type="VARCHAR(50)"/>
|
|
6931
6934
|
</createTable>
|
|
@@ -9979,7 +9982,7 @@ function runDoctor(targetDir) {
|
|
|
9979
9982
|
checks.push({
|
|
9980
9983
|
name: "CLI \u7248\u672C",
|
|
9981
9984
|
status: "pass",
|
|
9982
|
-
message: `v${version}\uFF08\u8FD0\u884C deepstorm update
|
|
9985
|
+
message: `v${version}\uFF08\u8FD0\u884C deepstorm update \u68C0\u67E5\u6700\u65B0\u7248\u672C\uFF09`
|
|
9983
9986
|
});
|
|
9984
9987
|
let hasDeepStorm = false;
|
|
9985
9988
|
if (!fs25.existsSync(settingsPath)) {
|
|
@@ -30,9 +30,15 @@ git diff "$FORK_POINT"..HEAD --diff-filter=M --name-only
|
|
|
30
30
|
|
|
31
31
|
**规则**:不凭空写新文件。先读一个真实存在的同类文件,理解模式后再动手。写新模块时参考已有模块的完整实现。
|
|
32
32
|
|
|
33
|
-
### 2.
|
|
33
|
+
### 2. 🔴 加载编码规范(硬性门禁)
|
|
34
34
|
|
|
35
|
-
加载 `reef:reef-style-backend`
|
|
35
|
+
> **必须先通过 Skill tool 加载 `reef:reef-style-backend`,阅读 `quick-reference.md` 了解核心编码规范,并根据当前变更类型阅读对应的维度规范文件(如 `spring-boot.md`、`hibernate.md`、`fastapi-quick-reference.md`、`pytest-testing.md` 等)。完成后方可进入后续代码编写步骤。未加载 code-style 技能不得编写代码,否则视为违反工作流纪律。**
|
|
36
|
+
|
|
37
|
+
加载完成后,AI MUST 输出以下声明:
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
✅ [CODE-STYLE] 已加载后端编码规范(quick-reference + 必要维度规范),所有新增/修改代码将遵循项目编码规范。
|
|
41
|
+
```
|
|
36
42
|
|
|
37
43
|
涉及库/框架 API 用法时,使用 context7 获取最新文档:`resolve-library-id` → `query-docs`。
|
|
38
44
|
|
|
@@ -83,6 +89,6 @@ ruff check . && mypy . && python -m pytest
|
|
|
83
89
|
```
|
|
84
90
|
{{/if}}
|
|
85
91
|
|
|
86
|
-
### {{#if reef.backend.java.dbMigration.styleRef}}6{{else}}{{#if reef.backend.python.dbMigration.styleRef}}6{{else}}5{{/if}}{{/if}}.
|
|
92
|
+
### {{#if reef.backend.java.dbMigration.styleRef}}6{{else}}{{#if reef.backend.python.dbMigration.styleRef}}6{{else}}5{{/if}}{{/if}}. 🔴 提交前自检(后置检查)
|
|
87
93
|
|
|
88
|
-
|
|
94
|
+
重新加载 `reef:reef-style-backend` 技能,逐项对照所有规范要求检查本变更中的每处代码修改。**检查未通过不得提交。**
|
|
@@ -31,9 +31,15 @@ git diff "$FORK_POINT"..HEAD --diff-filter=M --name-only
|
|
|
31
31
|
|
|
32
32
|
**规则**:不凭空写新文件。先读一个真实存在的同类文件,理解模式后再动手。
|
|
33
33
|
|
|
34
|
-
### 2.
|
|
34
|
+
### 2. 🔴 加载编码规范(硬性门禁)
|
|
35
35
|
|
|
36
|
-
加载 `reef:reef-style-frontend
|
|
36
|
+
> **必须先通过 Skill tool 加载 `reef:reef-style-frontend`,阅读 `quick-reference.md` 了解核心编码规范,并根据当前变更类型阅读对应的维度规范文件(框架规范、UI 组件库规范、CSS 方案、TypeScript 配置、测试框架等)。完成后方可进入后续代码编写步骤。未加载 code-style 技能不得编写代码,否则视为违反工作流纪律。**
|
|
37
|
+
|
|
38
|
+
加载完成后,AI MUST 输出以下声明:
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
✅ [CODE-STYLE] 已加载前端编码规范(quick-reference + 必要维度规范),所有新增/修改代码将遵循项目编码规范。
|
|
42
|
+
```
|
|
37
43
|
|
|
38
44
|
涉及库/框架 API 用法时,使用 context7 获取最新文档:`resolve-library-id` → `query-docs`。
|
|
39
45
|
|
|
@@ -79,6 +85,6 @@ git diff "$FORK_POINT"..HEAD --diff-filter=M --name-only
|
|
|
79
85
|
{{reef.frontend.framework.formatCmd}} lint && {{reef.frontend.framework.formatCmd}} typecheck && {{reef.frontend.framework.formatCmd}} test
|
|
80
86
|
```
|
|
81
87
|
|
|
82
|
-
### {{#if reef.frontend.framework.sourcePath}}6{{else}}5{{/if}}.
|
|
88
|
+
### {{#if reef.frontend.framework.sourcePath}}6{{else}}5{{/if}}. 🔴 提交前自检(后置检查)
|
|
83
89
|
|
|
84
|
-
|
|
90
|
+
重新加载 `reef:reef-style-frontend` 技能,逐项对照所有规范要求检查本变更中的每处代码修改。**检查未通过不得提交。**
|
|
@@ -377,6 +377,7 @@ openspec instructions tasks --change "$CHANGE" --json
|
|
|
377
377
|
### 流程
|
|
378
378
|
|
|
379
379
|
1. **调用 Skill 工具** — 根据 tasks.md 的任务范围,加载可能适用的 superpowers:
|
|
380
|
+
- `reef:reef-style-backend` 或 `reef:reef-style-frontend`(如果 tasks 涉及后端/前端**代码改动**,**必须**加载对应 code-style 技能,未加载不得进入阶段四)
|
|
380
381
|
- `superpowers:test-driven-development`(如果 tasks 涉及 TypeScript/Java/Python 等代码改动)
|
|
381
382
|
- `superpowers:verification-before-completion`
|
|
382
383
|
- 根据 tasks.md 内容判断是否适用其他 superpowers
|
|
@@ -36,11 +36,14 @@ PLAN_FILE="docs/superpowers/plans/$(date +%Y-%m-%d)-$CHANGE.md"
|
|
|
36
36
|
适用于:文档修改、配置文件调整、SKILL.md 流程修改、测试框架搭建、简单重构(测试覆盖充分)
|
|
37
37
|
|
|
38
38
|
```
|
|
39
|
-
1.
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
39
|
+
1. 🔴 确认 code-style 已加载 — 检查 `reef:reef-style-backend` 或 `reef:reef-style-frontend` 是否已通过 Skill tool 加载
|
|
40
|
+
- 已加载 → 进入步骤 2
|
|
41
|
+
- 未加载 → 暂停并先通过 Skill tool 加载对应技能,阅读 quick-reference.md 后再继续
|
|
42
|
+
2. 直接实现代码变更
|
|
43
|
+
3. 执行后置验证:build → lint → test
|
|
44
|
+
4. 如果验证失败 → 修复 → 重新验证 → 通过后才标完成
|
|
45
|
+
5. 如果发现复杂度超预期 → 暂停并向用户建议升级为 tdd mode
|
|
46
|
+
6. ✅ 标记 task 为完成
|
|
44
47
|
```
|
|
45
48
|
|
|
46
49
|
> **⚠️ Plan mode 风险预警:** plan mode 不要求前置测试,但**后置验证不可跳过**。如果 build/lint/test 任何一步失败,该 task **不得**被标记为完成。
|
|
@@ -50,6 +53,7 @@ PLAN_FILE="docs/superpowers/plans/$(date +%Y-%m-%d)-$CHANGE.md"
|
|
|
50
53
|
适用于:新增业务逻辑、Bug 修复、权限/安全变更、资金/幂等性变更、状态机/并发逻辑
|
|
51
54
|
|
|
52
55
|
**🔴 RED — 先写测试**
|
|
56
|
+
- 先确认 code-style 已加载:检查 `reef:reef-style-backend` 或 `reef:reef-style-frontend` 是否已通过 Skill tool 加载,未加载则先加载
|
|
53
57
|
- 根据 spec 的 Scenario 编写单元测试
|
|
54
58
|
- 运行测试,确认失败(红)
|
|
55
59
|
- 如果测试意外通过了,说明测试写的太弱,需改进
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
| 技能 | 类型 | 对本变更的要求 |
|
|
17
17
|
|------|------|---------------|
|
|
18
18
|
| {skill-name} | {类型} | {要求描述} |
|
|
19
|
+
| `reef:reef-style-backend` / `reef:reef-style-frontend` | 🟢 **Code Style** | 所有新增/修改的代码必须遵循项目编码规范,加载后阅读 `quick-reference.md` 和必要维度规范 |
|
|
19
20
|
|
|
20
21
|
### Plan Mode 纪律确认
|
|
21
22
|
|
|
@@ -39,6 +40,7 @@
|
|
|
39
40
|
| 技能 | 类型 | 对本变更的要求 |
|
|
40
41
|
|------|------|---------------|
|
|
41
42
|
| test-driven-development | 🔴 **Rigid** | 每个代码行为改动必须先写测试、看失败、再写实现 |
|
|
43
|
+
| `reef:reef-style-backend` / `reef:reef-style-frontend` | 🟢 **Code Style** | 所有新增/修改的代码必须遵循项目编码规范,加载后阅读 `quick-reference.md` 和必要维度规范 |
|
|
42
44
|
|
|
43
45
|
### TDD 纪律确认
|
|
44
46
|
|
|
@@ -57,6 +59,7 @@
|
|
|
57
59
|
- [ ] 📝 **实现计划已生成**(superpowers:writing-plans 完成,存于 `docs/superpowers/plans/`)
|
|
58
60
|
- [ ] 用户已审阅并批准所有 SDD 文档及实现计划
|
|
59
61
|
- [ ] 🔍 **Superpowers 技能已加载**(Skill 工具已调用)
|
|
62
|
+
- [ ] 🎨 **Code-Style 技能已加载**(`reef:reef-style-backend`/`reef:reef-style-frontend` 已通过 Skill 工具加载并阅读规范)
|
|
60
63
|
- [ ] 🚨 **Rigid 纪律已向用户声明并获得确认**
|
|
61
64
|
- [ ] Path A 检查项:Git 分支已从 main 岔出
|
|
62
65
|
- [ ] Path B 检查项:OpenSpec change 已创建,brainstorming 文件已产出
|
|
@@ -24,8 +24,6 @@ deepstorm:
|
|
|
24
24
|
/sweep-run flows/login.flow.md # 单文件
|
|
25
25
|
/sweep-run flows/login.flow.md --flow L02 # 单 Flow
|
|
26
26
|
/sweep-run --env staging # 指定测试环境
|
|
27
|
-
/sweep-run --text # 强制使用文本输入模式选择(不启动 TTY checkbox)
|
|
28
|
-
/sweep-run --all --text # 全量 + 文本模式
|
|
29
27
|
```
|
|
30
28
|
|
|
31
29
|
### 执行模式说明
|
|
@@ -113,18 +111,30 @@ fi
|
|
|
113
111
|
|
|
114
112
|
根据用户输入参数或交互选择,确定要执行的 .flow.md 文件列表。
|
|
115
113
|
|
|
116
|
-
#### 2.1 交互模式(无参数)
|
|
114
|
+
#### 2.1 交互模式(无参数) — 对话式选择
|
|
117
115
|
|
|
118
|
-
|
|
116
|
+
不使用 `@inquirer/checkbox` 交互选择器(在 Claude Code 环境中 TTY/TUI 不可靠),改为**对话式选择**:
|
|
119
117
|
|
|
120
|
-
1.
|
|
121
|
-
2.
|
|
122
|
-
3.
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
118
|
+
1. 运行 `node scripts/flow-selector.mjs --list` 获取可用 .flow.md 文件列表
|
|
119
|
+
2. 检查输出是否为有效 JSON(含 `files[]`),若脚本报错则提示用户后退出
|
|
120
|
+
3. 在消息中直接列出可用文件供用户选择,参考格式:
|
|
121
|
+
|
|
122
|
+
```markdown
|
|
123
|
+
📋 可用测试模块:
|
|
124
|
+
|
|
125
|
+
1. user-system/register(3 个用例:L01-L03)
|
|
126
|
+
2. user-system/login(2 个用例:L01-L02)
|
|
127
|
+
3. tasks/crud(4 个用例:T01-T04)
|
|
128
|
+
|
|
129
|
+
请选择:全部执行 / 输入序号(如 1,3) / 输入模块名
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
4. 等待用户在聊天中回复选择
|
|
133
|
+
5. 根据用户选择,直接写入 `.sweep-selection.json`:
|
|
134
|
+
- **全部执行** → `{"type":"all"}`
|
|
135
|
+
- **指定文件全部 Flow** → `{"type":"selection","files":[{"file":"/abs/path/to/file.flow.md","flows":[],"all":true}]}`
|
|
136
|
+
- **指定文件的特定 Flow** → `{"type":"selection","files":[{"file":"/abs/path/to/file.flow.md","flows":["L01"],"all":false}]}`
|
|
137
|
+
6. 输出选中文件的总览,确认后继续执行(**以下为示例格式,实际内容根据项目动态生成**):
|
|
128
138
|
|
|
129
139
|
```
|
|
130
140
|
选中的模块:user-system, tasks
|
|
@@ -147,8 +157,6 @@ fi
|
|
|
147
157
|
| `--env {env}` | 切换目标环境 | `/sweep-run --all --env staging` |
|
|
148
158
|
| `--browser` | 打开浏览器窗口逐步骤调试 | `/sweep-run --all --browser` |
|
|
149
159
|
| `--no-parallel` | 使用批量但不并行 | `/sweep-run --all --no-parallel` |
|
|
150
|
-
| `--text` | 强制文本输入模式选择(跳过 TTY checkbox) | `/sweep-run --text` |
|
|
151
|
-
| `--tui` | 强制 TUI checkbox 模式 | `/sweep-run --tui` |
|
|
152
160
|
|
|
153
161
|
#### 2.3 文件不存在处理
|
|
154
162
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Sweep Flow Selector —
|
|
4
|
+
* Sweep Flow Selector — 交互/非交互式选择工具
|
|
5
5
|
*
|
|
6
6
|
* 支持选择粒度:
|
|
7
7
|
* 1. 模块级别(eg. user-system)
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
* 将选中结果写入 .sweep-selection.json 并输出到 stdout。
|
|
14
14
|
*
|
|
15
15
|
* 使用方式:
|
|
16
|
+
* node scripts/flow-selector.mjs --list # 非交互:列出可用文件(JSON)
|
|
16
17
|
* node scripts/flow-selector.mjs # 自动检测 TTY(checkbox 或文本回退)
|
|
17
18
|
* node scripts/flow-selector.mjs --tui # 强制 TUI checkbox 模式
|
|
18
19
|
* node scripts/flow-selector.mjs --text # 强制文本输入模式
|
|
@@ -142,6 +143,45 @@ function scanFlowFiles(dir) {
|
|
|
142
143
|
return result;
|
|
143
144
|
}
|
|
144
145
|
|
|
146
|
+
// ── 非交互模式:构建文件列表 JSON ─────────────────────────
|
|
147
|
+
|
|
148
|
+
function buildFileList(baseFlowsDir) {
|
|
149
|
+
const topologyPath = join(baseFlowsDir, 'topology.yaml');
|
|
150
|
+
const files = [];
|
|
151
|
+
|
|
152
|
+
if (existsSync(topologyPath)) {
|
|
153
|
+
const yaml = readFileSync(topologyPath, 'utf-8');
|
|
154
|
+
const modules = parseTopology(yaml);
|
|
155
|
+
|
|
156
|
+
function walkModules(mods, prefix = '') {
|
|
157
|
+
for (const mod of mods) {
|
|
158
|
+
const path = prefix ? `${prefix}/${mod.name}` : mod.name;
|
|
159
|
+
if (mod.children && mod.children.length > 0) {
|
|
160
|
+
walkModules(mod.children, path);
|
|
161
|
+
} else {
|
|
162
|
+
const flowFile = resolveFlowFile(path, baseFlowsDir);
|
|
163
|
+
if (flowFile) {
|
|
164
|
+
const content = readFileSync(flowFile, 'utf-8');
|
|
165
|
+
const flows = parseFlows(content);
|
|
166
|
+
files.push({ file: flowFile, relative: path, flows });
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
walkModules(modules);
|
|
172
|
+
} else {
|
|
173
|
+
const scanned = scanFlowFiles(baseFlowsDir);
|
|
174
|
+
for (const file of scanned) {
|
|
175
|
+
const content = readFileSync(file, 'utf-8');
|
|
176
|
+
const flows = parseFlows(content);
|
|
177
|
+
const rel = relative(baseFlowsDir, file);
|
|
178
|
+
files.push({ file, relative: rel, flows });
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return { files, totalFiles: files.length, totalFlows: files.reduce((s, f) => s + f.flows.length, 0) };
|
|
183
|
+
}
|
|
184
|
+
|
|
145
185
|
// ── 构建 Choice 树 ──────────────────────────────────────────
|
|
146
186
|
|
|
147
187
|
function buildChoicesWithFlows(modules, baseFlowsDir, prefix = '') {
|
|
@@ -341,6 +381,22 @@ async function main() {
|
|
|
341
381
|
const cliArgs = process.argv.slice(2);
|
|
342
382
|
const forceText = cliArgs.includes('--text');
|
|
343
383
|
const forceTui = cliArgs.includes('--tui');
|
|
384
|
+
const listMode = cliArgs.includes('--list');
|
|
385
|
+
|
|
386
|
+
// ── 非交互模式:直接输出可用文件列表 JSON ──────────────
|
|
387
|
+
if (listMode) {
|
|
388
|
+
if (!existsSync(BASE_FLOWS_DIR)) {
|
|
389
|
+
console.error(JSON.stringify({ error: 'flows/ 目录不存在' }));
|
|
390
|
+
process.exit(1);
|
|
391
|
+
}
|
|
392
|
+
const list = buildFileList(BASE_FLOWS_DIR);
|
|
393
|
+
if (list.files.length === 0) {
|
|
394
|
+
console.error(JSON.stringify({ error: '没有找到任何 .flow.md 文件' }));
|
|
395
|
+
process.exit(1);
|
|
396
|
+
}
|
|
397
|
+
console.log(JSON.stringify(list, null, 2));
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
344
400
|
|
|
345
401
|
try {
|
|
346
402
|
let modules = [];
|
|
@@ -471,6 +527,7 @@ export {
|
|
|
471
527
|
buildChoicesWithFlows,
|
|
472
528
|
normalizeSelection,
|
|
473
529
|
buildFlatFileChoices,
|
|
530
|
+
buildFileList,
|
|
474
531
|
askTextSelection,
|
|
475
532
|
isTtyAvailable,
|
|
476
533
|
getCheckbox,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepstorm/cli",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.2",
|
|
4
4
|
"description": "DeepStorm CLI — 一键配置项目开发环境",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "billkang",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"dotenv": "^17.4.2",
|
|
17
17
|
"handlebars": "^4.7.8",
|
|
18
18
|
"js-yaml": "^4.1.0",
|
|
19
|
-
"@deepstorm/pilot": "^0.9.
|
|
19
|
+
"@deepstorm/pilot": "^0.9.2"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"@types/node": "^22.0.0",
|