@deepstorm/cli 0.2.4 → 0.3.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/dist/cli.js CHANGED
@@ -6757,6 +6757,10 @@ function cleanInstalled(targetDir) {
6757
6757
  }
6758
6758
  }
6759
6759
  }
6760
+ const hooksJson = path2.join(targetDir, ".claude", "hooks.json");
6761
+ if (fs6.existsSync(hooksJson)) {
6762
+ fs6.rmSync(hooksJson, { force: true });
6763
+ }
6760
6764
  const hooksDir = path2.join(targetDir, ".claude", "hooks");
6761
6765
  if (fs6.existsSync(hooksDir)) {
6762
6766
  fs6.rmSync(hooksDir, { recursive: true, force: true });
@@ -7003,12 +7007,11 @@ async function runSetup(reader, targetDir, cliDir2, options, registry2) {
7003
7007
  }
7004
7008
  if (shouldInstallGlobalHooks(tools, reader)) {
7005
7009
  const hooksSrcDir = path6.join(cliDir2, "hooks");
7006
- const targetHooksDir = path6.join(targetDir, ".claude", "hooks");
7007
- const destHooksJson = path6.join(targetHooksDir, "hooks.json");
7010
+ const destHooksJson = path6.join(targetDir, ".claude", "hooks.json");
7008
7011
  for (const tool of tools) {
7009
7012
  const toolHooksJsonPath = path6.join(hooksSrcDir, `${tool}-hooks.json`);
7010
7013
  if (fs10.existsSync(toolHooksJsonPath)) {
7011
- ensureDir(targetHooksDir);
7014
+ ensureDir(path6.join(targetDir, ".claude"));
7012
7015
  const incoming = JSON.parse(fs10.readFileSync(toolHooksJsonPath, "utf-8"));
7013
7016
  mergeHooks(destHooksJson, incoming);
7014
7017
  }
@@ -8338,12 +8341,11 @@ function loadRegistryFromCliDir(cliDir2) {
8338
8341
  }
8339
8342
  function mergeToolHooksJson(toolNames, cliDir2, targetDir) {
8340
8343
  const hooksSrcDir = path18.join(cliDir2, "hooks");
8341
- const targetHooksDir = path18.join(targetDir, ".claude", "hooks");
8342
- const destHooksJson = path18.join(targetHooksDir, "hooks.json");
8344
+ const destHooksJson = path18.join(targetDir, ".claude", "hooks.json");
8343
8345
  for (const tool of toolNames) {
8344
8346
  const toolHooksJsonPath = path18.join(hooksSrcDir, `${tool}-hooks.json`);
8345
8347
  if (fs20.existsSync(toolHooksJsonPath)) {
8346
- ensureDir(targetHooksDir);
8348
+ ensureDir(path18.join(targetDir, ".claude"));
8347
8349
  const incoming = JSON.parse(fs20.readFileSync(toolHooksJsonPath, "utf-8"));
8348
8350
  mergeHooks(destHooksJson, incoming);
8349
8351
  }
@@ -5,7 +5,7 @@
5
5
  "hooks": [
6
6
  {
7
7
  "type": "command",
8
- "command": "bash ./reef-intent-detect.sh"
8
+ "command": "bash .claude/hooks/reef-intent-detect.sh"
9
9
  }
10
10
  ]
11
11
  }
@@ -16,7 +16,7 @@
16
16
  "hooks": [
17
17
  {
18
18
  "type": "command",
19
- "command": "bash ./reef-block-dangerous.sh"
19
+ "command": "bash .claude/hooks/reef-block-dangerous.sh"
20
20
  }
21
21
  ]
22
22
  },
@@ -25,7 +25,7 @@
25
25
  "hooks": [
26
26
  {
27
27
  "type": "command",
28
- "command": "bash ./reef-protect-files.sh"
28
+ "command": "bash .claude/hooks/reef-protect-files.sh"
29
29
  },
30
30
  {
31
31
  "type": "prompt",
@@ -41,7 +41,7 @@
41
41
  "hooks": [
42
42
  {
43
43
  "type": "command",
44
- "command": "bash ./reef-auto-format.sh"
44
+ "command": "bash .claude/hooks/reef-auto-format.sh"
45
45
  }
46
46
  ]
47
47
  },
@@ -50,7 +50,7 @@
50
50
  "hooks": [
51
51
  {
52
52
  "type": "command",
53
- "command": "bash ./reef-run-tests.sh",
53
+ "command": "bash .claude/hooks/reef-run-tests.sh",
54
54
  "if": "Edit(*.ts)|Write(*.ts)",
55
55
  "async": true,
56
56
  "statusMessage": "Running tests..."
@@ -63,7 +63,7 @@
63
63
  "hooks": [
64
64
  {
65
65
  "type": "command",
66
- "command": "bash ./reef-run-tests.sh"
66
+ "command": "bash .claude/hooks/reef-run-tests.sh"
67
67
  }
68
68
  ]
69
69
  }
@@ -5,7 +5,7 @@
5
5
  "hooks": [
6
6
  {
7
7
  "type": "command",
8
- "command": "bash ./sweep-mcp-hook.sh"
8
+ "command": "bash .claude/hooks/sweep-mcp-hook.sh"
9
9
  }
10
10
  ]
11
11
  }
@@ -5,7 +5,7 @@
5
5
  "hooks": [
6
6
  {
7
7
  "type": "command",
8
- "command": "bash ./tide-session-preload.sh"
8
+ "command": "bash .claude/hooks/tide-session-preload.sh"
9
9
  }
10
10
  ]
11
11
  }
@@ -39,7 +39,82 @@ git status --short
39
39
 
40
40
  若无任何变更则提示用户并退出。
41
41
 
42
- ### 2. 审查待提交文件
42
+ ### 2. 分支名与任务相关性检查
43
+
44
+ 在审查待提交文件之前,先检查当前分支是否与待提交的任务相关。如果当前在 `main`/`master` 分支上则**必须**创建新分支;如果分支名与任务内容明显不匹配(如命名随意、与 OpenSpec 任务不符),建议创建新分支。
45
+
46
+ ```bash
47
+ BRANCH=$(git branch --show-current)
48
+ echo "当前分支: $BRANCH"
49
+
50
+ # 检测是否需要创建新分支
51
+ MUST_NEW_BRANCH=false
52
+
53
+ # 条件一:在 main 或 master 上必须创建新分支
54
+ if [ "$BRANCH" = "main" ] || [ "$BRANCH" = "master" ]; then
55
+ echo "⚠️ 当前在 $BRANCH 分支上,不允许直接提交,必须创建新分支"
56
+ MUST_NEW_BRANCH=true
57
+ fi
58
+
59
+ # 条件二:检查分支名是否包含 temp、wip、test、tmp、dev 等临时名称
60
+ TEMP_PATTERN='^(temp|wip|test|tmp|dev)(/.*)?$'
61
+ if echo "$BRANCH" | grep -qE "$TEMP_PATTERN"; then
62
+ echo "⚠️ 当前分支名 ($BRANCH) 看起来是临时分支,建议创建有意义的新分支"
63
+ fi
64
+
65
+ # 收集 OpenSpec 任务上下文
66
+ for dir in openspec/changes/*/; do
67
+ if [ -f "$dir/proposal.md" ]; then
68
+ TASK_NAME=$(basename "$dir")
69
+ echo "发现 OpenSpec 任务: $TASK_NAME"
70
+ fi
71
+ done
72
+ ```
73
+
74
+ **判断规则(LLM 自行推理执行):**
75
+
76
+ 1. **如果 MUST_NEW_BRANCH=true**(当前在 main/master):
77
+ - 直接进入步骤 3「创建新分支」,无需询问用户
78
+ 2. **如果分支名明显不相关**(如 `temp-xxx`、`test-foo`、或随意命名与当前变更毫无关联):
79
+ - 向用户说明:「当前分支 $BRANCH 与待提交的变更内容似乎不匹配,是否创建一个新分支?」
80
+ - 用户同意 → 进入步骤 3「创建新分支」
81
+ - 用户不同意 → 继续当前分支
82
+ 3. **如果分支名合理**(如与 OpenSpec 任务同名,或包含功能描述的 kebab-case):
83
+ - 直接继续
84
+
85
+ ### 3. 创建新分支
86
+
87
+ 当需要创建新分支时,按以下逻辑确定分支名:
88
+
89
+ **分支名生成规则(优先级从高到低):**
90
+ 1. **OpenSpec 任务名**:如果检测到 `openspec/changes/<task>/proposal.md`,使用 `<task>` 作为分支名
91
+ 2. **用户输入**:询问用户想要的分支名
92
+ 3. **AI 推导**:根据变更内容总结生成 kebab-case 分支名(例如 `feat/add-user-auth`、`fix/login-timeout`)
93
+
94
+ ```bash
95
+ # 暂存当前未提交变更
96
+ STASHED=false
97
+ if [ -n "$(git status --porcelain)" ]; then
98
+ git stash push -m "reef-commit-auto-stash"
99
+ STASHED=true
100
+ fi
101
+
102
+ # 创建并切换到新分支(基于 main)
103
+ git checkout main
104
+ git pull origin main 2>/dev/null || true
105
+ git checkout -b <new-branch-name>
106
+
107
+ # 恢复暂存的变更
108
+ if [ "$STASHED" = true ]; then
109
+ git stash pop
110
+ fi
111
+
112
+ echo "✅ 已切换到新分支: <new-branch-name>"
113
+ ```
114
+
115
+ > **注意**:创建新分支后,后续步骤(审查文件、范围检查、测试等)在新分支上继续执行。
116
+
117
+ ### 4. 审查待提交文件
43
118
 
44
119
  展示变更清单,检查敏感文件:
45
120
 
@@ -49,7 +124,7 @@ git diff --stat
49
124
 
50
125
  如包含 `.env`、凭据、证书或大型二进制文件,让用户确认或排除后再继续。
51
126
 
52
- ### 2.4 分支范围检查
127
+ ### 5. 分支范围检查
53
128
 
54
129
  检查当前分支是否涉及多个业务领域。如果跨领域,给出拆分建议并中止提交。
55
130
 
@@ -68,7 +143,7 @@ if [ -f "$SCOPE_HOOK" ]; then
68
143
  fi
69
144
  ```
70
145
 
71
- ### 2.5 运行单元测试
146
+ ### 6. 运行单元测试
72
147
 
73
148
  ```bash
74
149
  git status --short
@@ -84,7 +159,7 @@ git status --short
84
159
  - 测试全部通过 → 继续
85
160
  - 任一测试失败 → 提示用户修复后再提交
86
161
 
87
- ### 3. 收集上下文
162
+ ### 7. 收集上下文
88
163
 
89
164
  ```bash
90
165
  BRANCH=$(git branch --show-current)
@@ -97,24 +172,24 @@ grep -iE '(issue|jira|lc-|proj-)' "openspec/changes/$BRANCH/proposal.md" 2>/dev/
97
172
  git log "$FORK_POINT"..HEAD --format="%B" 2>/dev/null | grep -ioP '[A-Z]+-\d+' | head -1
98
173
  ```
99
174
 
100
- ### 4. 生成提交信息
175
+ ### 8. 生成提交信息
101
176
 
102
177
  **标题:** 优先 OpenSpec proposal 标题 → 分支名(kebab-case 转中文)→ 变更总结。依赖更新用 `更新 {依赖} 至 {版本}`,问题修复用 `解决{问题描述}的问题`。
103
178
 
104
179
  **正文:** 中/复杂变更用 `本次提交改动如下:` + 3-6 条要点。尾部隔空行加 `JIRA: {完整 URL}`(优先从 proposal.md/jira-start 元数据中获取 JIRA 链接),如有 PRD 链接加 `Ref: {URL}`。
105
180
 
106
- ### 5. 展示并确认
181
+ ### 9. 展示并确认
107
182
 
108
183
  展示完整提交信息,用户确认即可提交;支持 `--amend` 合并;用户可要求修改后重新生成。
109
184
 
110
- ### 6. 执行提交
185
+ ### 10. 执行提交
111
186
 
112
187
  ```bash
113
188
  git add -A && git commit -m "<完整提交信息>"
114
189
  # 用户要求 amend 时: git commit --amend -m "<完整提交信息>"
115
190
  ```
116
191
 
117
- ### 7. 推送(仅在用户要求时)
192
+ ### 11. 推送(仅在用户要求时)
118
193
 
119
194
  ```bash
120
195
  # 新提交(有远程跟踪):git push
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deepstorm/cli",
3
- "version": "0.2.4",
3
+ "version": "0.3.0",
4
4
  "description": "DeepStorm CLI — 一键配置项目开发环境",
5
5
  "license": "MIT",
6
6
  "author": "billkang",