superpowers-zh 1.3.0 → 1.6.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.
Files changed (49) hide show
  1. package/.claude-plugin/marketplace.json +3 -3
  2. package/.claude-plugin/plugin.json +2 -2
  3. package/.codex-plugin/plugin.json +1 -1
  4. package/.cursor-plugin/plugin.json +2 -2
  5. package/.pi/extensions/superpowers.ts +121 -0
  6. package/CLAUDE.md +1 -1
  7. package/README.md +77 -34
  8. package/RELEASE-NOTES.zh.md +150 -0
  9. package/assets/qr-wechat.jpg +0 -0
  10. package/assets/sponsors/5cookie-code.png +0 -0
  11. package/bin/superpowers-zh.js +69 -18
  12. package/docs/README.antigravity.md +7 -7
  13. package/docs/README.kimi.md +86 -0
  14. package/docs/README.openclaw.md +7 -4
  15. package/docs/README.pi.md +54 -0
  16. package/docs/README.qoder.md +95 -0
  17. package/docs/README.trae.md +6 -4
  18. package/gemini-extension.json +1 -1
  19. package/hooks/hooks-cursor.json +1 -1
  20. package/hooks/session-start +4 -12
  21. package/package.json +18 -5
  22. package/skills/brainstorming/SKILL.md +5 -0
  23. package/skills/brainstorming/scripts/frame-template.html +25 -26
  24. package/skills/brainstorming/scripts/helper.js +101 -22
  25. package/skills/brainstorming/scripts/server.cjs +428 -43
  26. package/skills/brainstorming/scripts/start-server.sh +76 -20
  27. package/skills/brainstorming/scripts/stop-server.sh +74 -9
  28. package/skills/chinese-code-review/SKILL.md +5 -0
  29. package/skills/chinese-commit-conventions/SKILL.md +5 -0
  30. package/skills/chinese-documentation/SKILL.md +5 -0
  31. package/skills/chinese-git-workflow/SKILL.md +5 -0
  32. package/skills/dispatching-parallel-agents/SKILL.md +5 -0
  33. package/skills/executing-plans/SKILL.md +7 -2
  34. package/skills/finishing-a-development-branch/SKILL.md +112 -32
  35. package/skills/mcp-builder/SKILL.md +5 -0
  36. package/skills/receiving-code-review/SKILL.md +5 -0
  37. package/skills/requesting-code-review/SKILL.md +13 -10
  38. package/skills/requesting-code-review/code-reviewer.md +124 -104
  39. package/skills/subagent-driven-development/SKILL.md +5 -0
  40. package/skills/systematic-debugging/SKILL.md +5 -0
  41. package/skills/test-driven-development/SKILL.md +5 -0
  42. package/skills/using-git-worktrees/SKILL.md +104 -97
  43. package/skills/using-superpowers/SKILL.md +6 -1
  44. package/skills/using-superpowers/references/pi-tools.md +28 -0
  45. package/skills/using-superpowers/references/qoder-tools.md +43 -0
  46. package/skills/verification-before-completion/SKILL.md +5 -0
  47. package/skills/workflow-runner/SKILL.md +5 -0
  48. package/skills/writing-plans/SKILL.md +5 -0
  49. package/skills/writing-skills/SKILL.md +5 -0
@@ -11,6 +11,9 @@
11
11
  # --host <bind-host> Host/interface to bind (default: 127.0.0.1).
12
12
  # Use 0.0.0.0 in remote/containerized environments.
13
13
  # --url-host <host> Hostname shown in returned URL JSON.
14
+ # --idle-timeout-minutes <n> Shut down after n minutes idle (default 240 = 4h).
15
+ # --open Auto-open the browser on the first screen (use only
16
+ # after the user approves the visual companion).
14
17
  # --foreground Run server in the current terminal (no backgrounding).
15
18
  # --background Force background mode (overrides Codex auto-foreground).
16
19
 
@@ -22,6 +25,7 @@ FOREGROUND="false"
22
25
  FORCE_BACKGROUND="false"
23
26
  BIND_HOST="127.0.0.1"
24
27
  URL_HOST=""
28
+ IDLE_TIMEOUT_MINUTES=""
25
29
  while [[ $# -gt 0 ]]; do
26
30
  case "$1" in
27
31
  --project-dir)
@@ -36,6 +40,14 @@ while [[ $# -gt 0 ]]; do
36
40
  URL_HOST="$2"
37
41
  shift 2
38
42
  ;;
43
+ --idle-timeout-minutes)
44
+ IDLE_TIMEOUT_MINUTES="$2"
45
+ shift 2
46
+ ;;
47
+ --open)
48
+ export BRAINSTORM_OPEN=1
49
+ shift
50
+ ;;
39
51
  --foreground|--no-daemon)
40
52
  FOREGROUND="true"
41
53
  shift
@@ -59,6 +71,29 @@ if [[ -z "$URL_HOST" ]]; then
59
71
  fi
60
72
  fi
61
73
 
74
+ if [[ -n "$IDLE_TIMEOUT_MINUTES" ]]; then
75
+ if ! [[ "$IDLE_TIMEOUT_MINUTES" =~ ^[0-9]+$ ]] || [[ "$IDLE_TIMEOUT_MINUTES" -lt 1 ]]; then
76
+ echo "{\"error\": \"--idle-timeout-minutes must be a positive integer\"}"
77
+ exit 1
78
+ fi
79
+ export BRAINSTORM_IDLE_TIMEOUT_MS=$(( IDLE_TIMEOUT_MINUTES * 60 * 1000 ))
80
+ fi
81
+
82
+ is_windows_like_shell() {
83
+ case "${OSTYPE:-}" in
84
+ msys*|cygwin*|mingw*) return 0 ;;
85
+ esac
86
+ if [[ -n "${MSYSTEM:-}" ]]; then
87
+ return 0
88
+ fi
89
+ local uname_s
90
+ uname_s="$(uname -s 2>/dev/null || true)"
91
+ case "$uname_s" in
92
+ MSYS*|MINGW*|CYGWIN*) return 0 ;;
93
+ esac
94
+ return 1
95
+ }
96
+
62
97
  # Some environments reap detached/background processes. Auto-foreground when detected.
63
98
  if [[ -n "${CODEX_CI:-}" && "$FOREGROUND" != "true" && "$FORCE_BACKGROUND" != "true" ]]; then
64
99
  FOREGROUND="true"
@@ -66,28 +101,45 @@ fi
66
101
 
67
102
  # Windows/Git Bash reaps nohup background processes. Auto-foreground when detected.
68
103
  if [[ "$FOREGROUND" != "true" && "$FORCE_BACKGROUND" != "true" ]]; then
69
- case "${OSTYPE:-}" in
70
- msys*|cygwin*|mingw*) FOREGROUND="true" ;;
71
- esac
72
- if [[ -n "${MSYSTEM:-}" ]]; then
104
+ if is_windows_like_shell; then
73
105
  FOREGROUND="true"
74
106
  fi
75
107
  fi
76
108
 
109
+ # Session files (server.log, server-info, .last-token) embed the session key —
110
+ # keep everything this script and the server create owner-only.
111
+ umask 077
112
+
77
113
  # Generate unique session directory
78
114
  SESSION_ID="$$-$(date +%s)"
79
115
 
80
116
  if [[ -n "$PROJECT_DIR" ]]; then
81
- SCREEN_DIR="${PROJECT_DIR}/.superpowers/brainstorm/${SESSION_ID}"
117
+ SESSION_DIR="${PROJECT_DIR}/.superpowers/brainstorm/${SESSION_ID}"
118
+ # Persist the bound port and key per project so a restart reuses them and an
119
+ # already-open browser tab reconnects to the same URL with a valid cookie.
120
+ export BRAINSTORM_PORT_FILE="${PROJECT_DIR}/.superpowers/brainstorm/.last-port"
121
+ export BRAINSTORM_TOKEN_FILE="${PROJECT_DIR}/.superpowers/brainstorm/.last-token"
82
122
  else
83
- SCREEN_DIR="/tmp/brainstorm-${SESSION_ID}"
123
+ SESSION_DIR="/tmp/brainstorm-${SESSION_ID}"
84
124
  fi
85
125
 
86
- PID_FILE="${SCREEN_DIR}/.server.pid"
87
- LOG_FILE="${SCREEN_DIR}/.server.log"
126
+ STATE_DIR="${SESSION_DIR}/state"
127
+ PID_FILE="${STATE_DIR}/server.pid"
128
+ LOG_FILE="${STATE_DIR}/server.log"
129
+ SERVER_ID_FILE="${STATE_DIR}/server-instance-id"
88
130
 
89
- # Create fresh session directory
90
- mkdir -p "$SCREEN_DIR"
131
+ # Create fresh session directory with content and state peers
132
+ mkdir -p "${SESSION_DIR}/content" "$STATE_DIR"
133
+
134
+ SERVER_ID=""
135
+ if [[ -r /dev/urandom ]]; then
136
+ SERVER_ID="$(od -An -N24 -tx1 /dev/urandom 2>/dev/null | tr -d ' \n' || true)"
137
+ fi
138
+ if ! [[ "$SERVER_ID" =~ ^[A-Za-z0-9_-]{32,64}$ ]]; then
139
+ SERVER_ID="$(printf '%08x%08x%08x%08x' "$$" "$(date +%s)" "${RANDOM:-0}" "${RANDOM:-0}")"
140
+ fi
141
+ printf '%s\n' "$SERVER_ID" > "$SERVER_ID_FILE"
142
+ chmod 600 "$SERVER_ID_FILE" 2>/dev/null || true
91
143
 
92
144
  # Kill any existing server
93
145
  if [[ -f "$PID_FILE" ]]; then
@@ -96,7 +148,7 @@ if [[ -f "$PID_FILE" ]]; then
96
148
  rm -f "$PID_FILE"
97
149
  fi
98
150
 
99
- cd "$SCRIPT_DIR"
151
+ cd "$SCRIPT_DIR" || exit 1
100
152
 
101
153
  # Resolve the harness PID (grandparent of this script).
102
154
  # $PPID is the ephemeral shell the harness spawned to run us — it dies
@@ -106,28 +158,32 @@ if [[ -z "$OWNER_PID" || "$OWNER_PID" == "1" ]]; then
106
158
  OWNER_PID="$PPID"
107
159
  fi
108
160
 
109
- # On Windows/MSYS2, the MSYS2 PID namespace is invisible to Node.js.
110
- # Skip owner-PID monitoring — the 30-minute idle timeout prevents orphans.
111
- case "${OSTYPE:-}" in
112
- msys*|cygwin*|mingw*) OWNER_PID="" ;;
113
- esac
161
+ # Windows/MSYS2: Node.js cannot see POSIX PIDs from the MSYS2 namespace.
162
+ # Passing a PID node cannot verify causes server to log owner-pid-invalid
163
+ # and self-terminate at the 60-second lifecycle check. Clear it so the
164
+ # watchdog is disabled and the idle timeout becomes the only shutdown trigger.
165
+ if is_windows_like_shell; then
166
+ OWNER_PID=""
167
+ fi
114
168
 
115
169
  # Foreground mode for environments that reap detached/background processes.
116
170
  if [[ "$FOREGROUND" == "true" ]]; then
117
- echo "$$" > "$PID_FILE"
118
- env BRAINSTORM_DIR="$SCREEN_DIR" BRAINSTORM_HOST="$BIND_HOST" BRAINSTORM_URL_HOST="$URL_HOST" BRAINSTORM_OWNER_PID="$OWNER_PID" node server.cjs
171
+ env BRAINSTORM_DIR="$SESSION_DIR" BRAINSTORM_HOST="$BIND_HOST" BRAINSTORM_URL_HOST="$URL_HOST" BRAINSTORM_OWNER_PID="$OWNER_PID" node server.cjs "--brainstorm-server-id=$SERVER_ID" &
172
+ SERVER_PID=$!
173
+ echo "$SERVER_PID" > "$PID_FILE"
174
+ wait "$SERVER_PID"
119
175
  exit $?
120
176
  fi
121
177
 
122
178
  # Start server, capturing output to log file
123
179
  # Use nohup to survive shell exit; disown to remove from job table
124
- nohup env BRAINSTORM_DIR="$SCREEN_DIR" BRAINSTORM_HOST="$BIND_HOST" BRAINSTORM_URL_HOST="$URL_HOST" BRAINSTORM_OWNER_PID="$OWNER_PID" node server.cjs > "$LOG_FILE" 2>&1 &
180
+ nohup env BRAINSTORM_DIR="$SESSION_DIR" BRAINSTORM_HOST="$BIND_HOST" BRAINSTORM_URL_HOST="$URL_HOST" BRAINSTORM_OWNER_PID="$OWNER_PID" node server.cjs "--brainstorm-server-id=$SERVER_ID" > "$LOG_FILE" 2>&1 &
125
181
  SERVER_PID=$!
126
182
  disown "$SERVER_PID" 2>/dev/null
127
183
  echo "$SERVER_PID" > "$PID_FILE"
128
184
 
129
185
  # Wait for server-started message (check log file)
130
- for i in {1..50}; do
186
+ for _ in {1..50}; do
131
187
  if grep -q "server-started" "$LOG_FILE" 2>/dev/null; then
132
188
  # Verify server is still alive after a short window (catches process reapers)
133
189
  alive="true"
@@ -1,28 +1,92 @@
1
1
  #!/usr/bin/env bash
2
2
  # Stop the brainstorm server and clean up
3
- # Usage: stop-server.sh <screen_dir>
3
+ # Usage: stop-server.sh <session_dir>
4
4
  #
5
5
  # Kills the server process. Only deletes session directory if it's
6
6
  # under /tmp (ephemeral). Persistent directories (.superpowers/) are
7
7
  # kept so mockups can be reviewed later.
8
8
 
9
- SCREEN_DIR="$1"
9
+ SESSION_DIR="$1"
10
10
 
11
- if [[ -z "$SCREEN_DIR" ]]; then
12
- echo '{"error": "Usage: stop-server.sh <screen_dir>"}'
11
+ if [[ -z "$SESSION_DIR" ]]; then
12
+ echo '{"error": "Usage: stop-server.sh <session_dir>"}'
13
13
  exit 1
14
14
  fi
15
15
 
16
- PID_FILE="${SCREEN_DIR}/.server.pid"
16
+ STATE_DIR="${SESSION_DIR}/state"
17
+ PID_FILE="${STATE_DIR}/server.pid"
18
+ SERVER_ID_FILE="${STATE_DIR}/server-instance-id"
19
+
20
+ mark_stopped() {
21
+ local reason="$1"
22
+ rm -f "${STATE_DIR}/server-info"
23
+ printf '{"reason":"%s","timestamp":%s}\n' "$reason" "$(date +%s)" > "${STATE_DIR}/server-stopped"
24
+ }
25
+
26
+ read_expected_server_id() {
27
+ [[ -f "$SERVER_ID_FILE" ]] || return 1
28
+ local id
29
+ id="$(tr -d '\r\n' < "$SERVER_ID_FILE" 2>/dev/null || true)"
30
+ [[ "$id" =~ ^[A-Za-z0-9_-]{32,64}$ ]] || return 1
31
+ printf '%s\n' "$id"
32
+ }
33
+
34
+ command_line_for_pid() {
35
+ local pid="$1"
36
+ if [[ -r "/proc/$pid/cmdline" ]]; then
37
+ tr '\0' '\n' < "/proc/$pid/cmdline" 2>/dev/null || true
38
+ return 0
39
+ fi
40
+ ps -ww -p "$pid" -o command= 2>/dev/null || ps -f -p "$pid" 2>/dev/null | sed '1d' || true
41
+ }
42
+
43
+ command_has_server_id() {
44
+ local pid="$1"
45
+ local expected="$2"
46
+ local expected_arg="--brainstorm-server-id=$expected"
47
+ if [[ -r "/proc/$pid/cmdline" ]]; then
48
+ local arg
49
+ while IFS= read -r -d '' arg || [[ -n "$arg" ]]; do
50
+ [[ "$arg" == "$expected_arg" ]] && return 0
51
+ done < "/proc/$pid/cmdline"
52
+ return 1
53
+ fi
54
+ local command_line
55
+ command_line="$(command_line_for_pid "$pid")"
56
+ [[ -n "$command_line" ]] || return 1
57
+ case " $command_line " in
58
+ *" $expected_arg "*) return 0 ;;
59
+ *) return 1 ;;
60
+ esac
61
+ }
62
+
63
+ # Confirm a PID has this session's per-start instance id, not just a familiar
64
+ # process name. Ambiguous or legacy metadata fails closed as stale_pid.
65
+ is_brainstorm_server() {
66
+ kill -0 "$1" 2>/dev/null || return 1
67
+ local expected_id
68
+ expected_id="$(read_expected_server_id)" || return 1
69
+ command_has_server_id "$1" "$expected_id" || return 1
70
+ return 0
71
+ }
17
72
 
18
73
  if [[ -f "$PID_FILE" ]]; then
19
74
  pid=$(cat "$PID_FILE")
20
75
 
76
+ # Refuse to signal a PID we can't prove is our server. A stale pid file may
77
+ # point at an unrelated process after a reboot/PID wraparound.
78
+ if ! is_brainstorm_server "$pid"; then
79
+ rm -f "$PID_FILE" "$SERVER_ID_FILE"
80
+ mark_stopped "stale_pid"
81
+ echo '{"status": "stale_pid"}'
82
+ exit 0
83
+ fi
84
+
21
85
  # Try to stop gracefully, fallback to force if still alive
22
86
  kill "$pid" 2>/dev/null || true
23
87
 
24
88
  # Wait for graceful shutdown (up to ~2s)
25
- for i in {1..20}; do
89
+ for _ in {1..20}; do
26
90
  if ! kill -0 "$pid" 2>/dev/null; then
27
91
  break
28
92
  fi
@@ -42,11 +106,12 @@ if [[ -f "$PID_FILE" ]]; then
42
106
  exit 1
43
107
  fi
44
108
 
45
- rm -f "$PID_FILE" "${SCREEN_DIR}/.server.log"
109
+ rm -f "$PID_FILE" "$SERVER_ID_FILE" "${STATE_DIR}/server.log"
110
+ mark_stopped "stop-server.sh"
46
111
 
47
112
  # Only delete ephemeral /tmp directories
48
- if [[ "$SCREEN_DIR" == /tmp/* ]]; then
49
- rm -rf "$SCREEN_DIR"
113
+ if [[ "$SESSION_DIR" == /tmp/* ]]; then
114
+ rm -rf "$SESSION_DIR"
50
115
  fi
51
116
 
52
117
  echo '{"status": "stopped"}'
@@ -1,6 +1,11 @@
1
1
  ---
2
2
  name: chinese-code-review
3
3
  description: 中文 review 沟通参考——话术模板、分级标注(必须修复/建议修改/仅供参考)、国内团队常见反模式应对。仅在用户显式 /chinese-code-review 时调用,不要根据上下文自动触发。
4
+ version: "1.0.0"
5
+ license: MIT
6
+ metadata:
7
+ hermes:
8
+ tags: [code-review, chinese]
4
9
  ---
5
10
 
6
11
  # 中文代码审查规范
@@ -1,6 +1,11 @@
1
1
  ---
2
2
  name: chinese-commit-conventions
3
3
  description: 中文 commit 与 changelog 配置参考——Conventional Commits 中文适配、commitlint/husky/commitizen 中文模板、conventional-changelog 中文配置。仅在用户显式 /chinese-commit-conventions 时调用,不要根据上下文自动触发。
4
+ version: "1.0.0"
5
+ license: MIT
6
+ metadata:
7
+ hermes:
8
+ tags: [git, chinese]
4
9
  ---
5
10
 
6
11
  # 中文 Git 提交规范
@@ -1,6 +1,11 @@
1
1
  ---
2
2
  name: chinese-documentation
3
3
  description: 中文文档排版参考——中英文空格、全半角标点、术语保留、链接格式、中文文案排版指北约定。仅在用户显式 /chinese-documentation 时调用,不要根据上下文自动触发。
4
+ version: "1.0.0"
5
+ license: MIT
6
+ metadata:
7
+ hermes:
8
+ tags: [documentation, chinese]
4
9
  ---
5
10
 
6
11
  # 中文技术文档写作规范
@@ -1,6 +1,11 @@
1
1
  ---
2
2
  name: chinese-git-workflow
3
3
  description: 国内 Git 平台配置参考——Gitee、Coding.net、极狐 GitLab、CNB 的 SSH/HTTPS/凭据/CI 接入差异与镜像同步配置。仅在用户显式 /chinese-git-workflow 时调用,不要根据上下文自动触发。
4
+ version: "1.0.0"
5
+ license: MIT
6
+ metadata:
7
+ hermes:
8
+ tags: [git, chinese]
4
9
  ---
5
10
 
6
11
  # 国内 Git 工作流规范
@@ -1,6 +1,11 @@
1
1
  ---
2
2
  name: dispatching-parallel-agents
3
3
  description: 当面对 2 个以上可以独立进行、无共享状态或顺序依赖的任务时使用
4
+ version: "1.0.0"
5
+ license: MIT
6
+ metadata:
7
+ hermes:
8
+ tags: [agents, parallel]
4
9
  ---
5
10
 
6
11
  # 并行分派智能体
@@ -1,6 +1,11 @@
1
1
  ---
2
2
  name: executing-plans
3
3
  description: 当你有一份书面实现计划需要在单独的会话中执行,并设有审查检查点时使用
4
+ version: "1.0.0"
5
+ license: MIT
6
+ metadata:
7
+ hermes:
8
+ tags: [execution, planning]
4
9
  ---
5
10
 
6
11
  # 执行计划
@@ -80,8 +85,8 @@ $ git commit -m "feat: 添加用户输入验证(任务 2/5)"
80
85
  --- 任务 2/5 完成 ---
81
86
  ```
82
87
 
83
- **批量审查检查点:**
84
- - 每完成 3 个任务后,暂停回顾:整体方向还对吗?有没有偏离计划?
88
+ **持续自查:**
89
+ - 执行过程中持续留意:整体方向还对吗?有没有偏离计划?
85
90
  - 如果发现前面的实现有问题,先修复再继续,不要带着问题往下走
86
91
 
87
92
  ### 步骤 3:处理常见异常
@@ -1,6 +1,11 @@
1
1
  ---
2
2
  name: finishing-a-development-branch
3
3
  description: 当实现完成、所有测试通过、需要决定如何集成工作时使用——通过提供合并、PR 或清理等结构化选项来引导开发工作的收尾
4
+ version: "1.0.0"
5
+ license: MIT
6
+ metadata:
7
+ hermes:
8
+ tags: [git, workflow]
4
9
  ---
5
10
 
6
11
  # 完成开发分支
@@ -9,7 +14,7 @@ description: 当实现完成、所有测试通过、需要决定如何集成工
9
14
 
10
15
  通过提供清晰的选项并执行所选工作流来引导开发工作的收尾。
11
16
 
12
- **核心原则:** 验证测试 → 展示选项 → 执行选择 → 清理。
17
+ **核心原则:** 验证测试 → 检测环境 → 展示选项 → 执行选择 → 清理。
13
18
 
14
19
  **开始时宣布:** "我正在使用 finishing-a-development-branch 技能来完成这项工作。"
15
20
 
@@ -25,6 +30,7 @@ npm test / cargo test / pytest / go test ./...
25
30
  ```
26
31
 
27
32
  **如果测试失败:**
33
+
28
34
  ```
29
35
  测试失败(<N> 个失败)。必须先修复才能继续:
30
36
 
@@ -37,7 +43,24 @@ npm test / cargo test / pytest / go test ./...
37
43
 
38
44
  **如果测试通过:** 继续步骤 2。
39
45
 
40
- ### 步骤 2:确定基础分支
46
+ ### 步骤 2:检测环境
47
+
48
+ **在展示选项之前,先确定工作区状态:**
49
+
50
+ ```bash
51
+ GIT_DIR=$(cd "$(git rev-parse --git-dir)" 2>/dev/null && pwd -P)
52
+ GIT_COMMON=$(cd "$(git rev-parse --git-common-dir)" 2>/dev/null && pwd -P)
53
+ ```
54
+
55
+ 这决定了展示哪种菜单、以及清理方式:
56
+
57
+ | 状态 | 菜单 | 清理 |
58
+ |------|------|------|
59
+ | `GIT_DIR == GIT_COMMON`(普通仓库) | 标准 4 个选项 | 无 worktree 可清理 |
60
+ | `GIT_DIR != GIT_COMMON`,命名分支 | 标准 4 个选项 | 按来源判断(见步骤 6) |
61
+ | `GIT_DIR != GIT_COMMON`,分离 HEAD | 收敛 3 个选项(无合并) | 无清理(由外部管理) |
62
+
63
+ ### 步骤 3:确定基础分支
41
64
 
42
65
  ```bash
43
66
  # 尝试常见的基础分支
@@ -46,9 +69,9 @@ git merge-base HEAD main 2>/dev/null || git merge-base HEAD master 2>/dev/null
46
69
 
47
70
  或者询问:"这个分支是从 main 分出来的——对吗?"
48
71
 
49
- ### 步骤 3:展示选项
72
+ ### 步骤 4:展示选项
50
73
 
51
- 展示以下 4 个选项:
74
+ **普通仓库和命名分支 worktree —— 准确展示以下 4 个选项:**
52
75
 
53
76
  ```
54
77
  实现已完成。你想怎么做?
@@ -61,30 +84,45 @@ git merge-base HEAD main 2>/dev/null || git merge-base HEAD master 2>/dev/null
61
84
  选哪个?
62
85
  ```
63
86
 
64
- **不要添加解释** - 保持选项简洁。
87
+ **分离 HEAD —— 准确展示以下 3 个选项:**
88
+
89
+ ```
90
+ 实现已完成。你在分离 HEAD 上(由外部管理的工作区)。
91
+
92
+ 1. 作为新分支推送并创建 Pull Request
93
+ 2. 保持现状(我稍后处理)
94
+ 3. 丢弃这项工作
95
+
96
+ 选哪个?
97
+ ```
98
+
99
+ **不要添加解释** —— 保持选项简洁。
65
100
 
66
- ### 步骤 4:执行选择
101
+ ### 步骤 5:执行选择
67
102
 
68
103
  #### 选项 1:本地合并
69
104
 
70
105
  ```bash
71
- # 切换到基础分支
72
- git checkout <base-branch>
106
+ # 切到主仓库根目录,保证 CWD 安全
107
+ MAIN_ROOT=$(git -C "$(git rev-parse --git-common-dir)/.." rev-parse --show-toplevel)
108
+ cd "$MAIN_ROOT"
73
109
 
74
- # 拉取最新代码
110
+ # 先合并 —— 在删除任何东西之前先验证合并成功
111
+ git checkout <base-branch>
75
112
  git pull
76
-
77
- # 合并功能分支
78
113
  git merge <feature-branch>
79
114
 
80
115
  # 在合并结果上验证测试
81
116
  <test command>
82
117
 
83
- # 如果测试通过
84
- git branch -d <feature-branch>
118
+ # 合并成功之后再:清理 worktree(步骤 6),然后删除分支
85
119
  ```
86
120
 
87
- 然后:清理工作树(步骤 5)
121
+ 然后:清理 worktree(步骤 6),再删除分支:
122
+
123
+ ```bash
124
+ git branch -d <feature-branch>
125
+ ```
88
126
 
89
127
  #### 选项 2:推送并创建 PR
90
128
 
@@ -103,7 +141,7 @@ EOF
103
141
  )"
104
142
  ```
105
143
 
106
- 然后:清理工作树(步骤 5)
144
+ **不要清理 worktree** —— 用户在 PR 反馈迭代时还需要它存活。
107
145
 
108
146
  #### 选项 3:保持现状
109
147
 
@@ -114,6 +152,7 @@ EOF
114
152
  #### 选项 4:丢弃
115
153
 
116
154
  **先确认:**
155
+
117
156
  ```
118
157
  这将永久删除:
119
158
  - 分支 <name>
@@ -126,28 +165,40 @@ EOF
126
165
  等待精确的确认。
127
166
 
128
167
  确认后:
168
+
129
169
  ```bash
130
- git checkout <base-branch>
131
- git branch -D <feature-branch>
170
+ MAIN_ROOT=$(git -C "$(git rev-parse --git-common-dir)/.." rev-parse --show-toplevel)
171
+ cd "$MAIN_ROOT"
132
172
  ```
133
173
 
134
- 然后:清理工作树(步骤 5)
174
+ 然后:清理 worktree(步骤 6),再强制删除分支:
175
+
176
+ ```bash
177
+ git branch -D <feature-branch>
178
+ ```
135
179
 
136
- ### 步骤 5:清理工作树
180
+ ### 步骤 6:清理工作区
137
181
 
138
- **对于选项 1、2、4:**
182
+ **只对选项 1 和 4 执行。** 选项 2 和 3 始终保留 worktree。
139
183
 
140
- 检查是否在工作树中:
141
184
  ```bash
142
- git worktree list | grep $(git branch --show-current)
185
+ GIT_DIR=$(cd "$(git rev-parse --git-dir)" 2>/dev/null && pwd -P)
186
+ GIT_COMMON=$(cd "$(git rev-parse --git-common-dir)" 2>/dev/null && pwd -P)
187
+ WORKTREE_PATH=$(git rev-parse --show-toplevel)
143
188
  ```
144
189
 
145
- 如果是:
190
+ **如果 `GIT_DIR == GIT_COMMON`:** 普通仓库,无 worktree 可清理。结束。
191
+
192
+ **如果 worktree 路径在 `.worktrees/` 或 `worktrees/` 之下:** 这是 Superpowers 创建的 worktree —— 我们负责清理。
193
+
146
194
  ```bash
147
- git worktree remove <worktree-path>
195
+ MAIN_ROOT=$(git -C "$(git rev-parse --git-common-dir)/.." rev-parse --show-toplevel)
196
+ cd "$MAIN_ROOT"
197
+ git worktree remove "$WORKTREE_PATH"
198
+ git worktree prune # 自愈:清理任何过期的注册记录
148
199
  ```
149
200
 
150
- **对于选项 3:** 保留工作树。
201
+ **否则:** 这个工作区由宿主环境(harness)管理。**不要**移除它。如果你的平台提供了工作区退出工具,用它。否则原样保留工作区。
151
202
 
152
203
  ## 快速参考
153
204
 
@@ -161,40 +212,69 @@ git worktree remove <worktree-path>
161
212
  ## 常见错误
162
213
 
163
214
  **跳过测试验证**
215
+
164
216
  - **问题:** 合并损坏的代码、创建失败的 PR
165
217
  - **修复:** 在提供选项前始终验证测试
166
218
 
167
219
  **开放式问题**
220
+
168
221
  - **问题:** "接下来该做什么?" → 含糊不清
169
- - **修复:** 准确展示 4 个结构化选项
222
+ - **修复:** 准确展示 4 个结构化选项(分离 HEAD 时是 3 个)
223
+
224
+ **为选项 2 清理 worktree**
170
225
 
171
- **自动清理工作树**
172
- - **问题:** 在可能还需要工作树时就删除了(选项 2、3)
226
+ - **问题:** 删掉用户 PR 迭代还需要的 worktree
173
227
  - **修复:** 只在选项 1 和 4 时清理
174
228
 
229
+ **先删分支再删 worktree**
230
+
231
+ - **问题:** `git branch -d` 失败,因为 worktree 还引用着该分支
232
+ - **修复:** 先合并,再删 worktree,最后删分支
233
+
234
+ **在 worktree 内部跑 `git worktree remove`**
235
+
236
+ - **问题:** 当 CWD 在被删除的 worktree 内时,命令静默失败
237
+ - **修复:** 跑 `git worktree remove` 前先 `cd` 到主仓库根目录
238
+
239
+ **清理 harness 拥有的 worktree**
240
+
241
+ - **问题:** 移除 harness 创建的 worktree 会造成幻影状态
242
+ - **修复:** 只清理 `.worktrees/` 或 `worktrees/` 下的 worktree
243
+
175
244
  **丢弃时不确认**
245
+
176
246
  - **问题:** 意外删除工作成果
177
- - **修复:** 要求输入 "discard" 确认
247
+ - **修复:** 要求输入 'discard' 确认
178
248
 
179
249
  ## 红线
180
250
 
181
251
  **绝不:**
252
+
182
253
  - 在测试失败时继续
183
- - 合并前不验证测试结果
254
+ - 合并前不验证合并结果上的测试
184
255
  - 不确认就删除工作成果
185
256
  - 未经明确请求就强制推送
257
+ - 在确认合并成功之前移除 worktree
258
+ - 清理不是你创建的 worktree(按来源判断)
259
+ - 在 worktree 内部跑 `git worktree remove`
186
260
 
187
261
  **始终:**
262
+
188
263
  - 在提供选项前验证测试
189
- - 准确展示 4 个选项
264
+ - 展示菜单前检测环境
265
+ - 准确展示 4 个选项(分离 HEAD 时是 3 个)
190
266
  - 选项 4 要求输入确认
191
- - 只在选项 1 和 4 时清理工作树
267
+ - 只在选项 1 和 4 时清理 worktree
268
+ - 移除 worktree 前 `cd` 到主仓库根目录
269
+ - 移除后跑 `git worktree prune`
192
270
 
193
271
  ## 集成
194
272
 
195
273
  **被以下技能调用:**
274
+
196
275
  - **subagent-driven-development**(步骤 7)- 所有任务完成后
197
276
  - **executing-plans**(步骤 5)- 所有批次完成后
198
277
 
199
278
  **配合使用:**
279
+
200
280
  - **using-git-worktrees** - 清理由该技能创建的工作树
@@ -1,6 +1,11 @@
1
1
  ---
2
2
  name: mcp-builder
3
3
  description: MCP 服务器构建方法论 — 系统化构建生产级 MCP 工具,让 AI 助手连接外部能力
4
+ version: "1.0.0"
5
+ license: MIT
6
+ metadata:
7
+ hermes:
8
+ tags: [mcp, development]
4
9
  ---
5
10
 
6
11
  # MCP 服务器构建
@@ -1,6 +1,11 @@
1
1
  ---
2
2
  name: receiving-code-review
3
3
  description: 收到代码审查反馈后、实施建议之前使用,尤其当反馈不明确或技术上有疑问时——需要技术严谨性和验证,而非敷衍附和或盲目执行
4
+ version: "1.0.0"
5
+ license: MIT
6
+ metadata:
7
+ hermes:
8
+ tags: [code-review]
4
9
  ---
5
10
 
6
11
  # 接收代码审查