@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 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: projectName.replace(/[_-]/g, "").toLowerCase(),
6357
- groupId: "com.example",
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 = `${ctx.groupId}.${ctx.packageName}`.replace(/[.-]/g, ".");
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 --check \u68C0\u67E5\u6700\u65B0\u7248\u672C\uFF09`
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` 技能,阅读 `quick-reference.md` 和必要示例。
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
- 加载 `reef:reef-style-backend` 技能,逐项检查所有规范要求。**未通过不得提交。**
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` 技能,阅读 `quick-reference.md` 和必要示例。
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
- 加载 `reef:reef-style-frontend` 技能,逐项检查所有规范要求。**未通过不得提交。**
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
- 2. 执行后置验证:buildlint → test
41
- 3. 如果验证失败修复 重新验证 通过后才标完成
42
- 4. 如果发现复杂度超预期 → 暂停并向用户建议升级为 tdd mode
43
- 5. 标记 task 为完成
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
- **必须运行** `node scripts/flow-selector.mjs` 进行选择。
116
+ 不使用 `@inquirer/checkbox` 交互选择器(在 Claude Code 环境中 TTY/TUI 不可靠),改为**对话式选择**:
119
117
 
120
- 1. 先检查 `scripts/flow-selector.mjs` 是否存在
121
- 2. 运行 `node scripts/flow-selector.mjs`
122
- 3. 脚本自动检测 TTY 可用性:
123
- - **TTY 可用** → 展示 `@inquirer/checkbox` 勾选列表(空格勾选、回车确认、a=全选)
124
- - **TTY 不可用** → 自动回退到 **readline 文本输入模式**(序号选择、逗号分隔、输入 a 全选)
125
- - 也可通过 `--text` 强制文本模式、`--tui` 强制 checkbox 模式
126
- 4. 读取 `.sweep-selection.json` 获取选中结果
127
- 5. 列出将要执行的文件,让用户确认后开始执行(**以下为示例格式,实际内容根据项目动态生成**)
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 — 基于 @inquirer/checkbox 的层级选择工具
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.1",
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.1"
19
+ "@deepstorm/pilot": "^0.9.2"
20
20
  },
21
21
  "devDependencies": {
22
22
  "@types/node": "^22.0.0",