dsh-superpower 6.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.
Files changed (60) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +334 -0
  3. package/cordis.patch.yml +3 -0
  4. package/lib/superpowers.d.ts +44 -0
  5. package/lib/superpowers.d.ts.map +1 -0
  6. package/lib/superpowers.js +291 -0
  7. package/lib/superpowers.js.map +1 -0
  8. package/package.json +62 -0
  9. package/skills/brainstorming/SKILL.md +207 -0
  10. package/skills/brainstorming/scripts/frame-template.html +213 -0
  11. package/skills/brainstorming/scripts/helper.js +167 -0
  12. package/skills/brainstorming/scripts/server.cjs +723 -0
  13. package/skills/brainstorming/scripts/start-server.sh +209 -0
  14. package/skills/brainstorming/scripts/stop-server.sh +120 -0
  15. package/skills/brainstorming/spec-document-reviewer-prompt.md +47 -0
  16. package/skills/brainstorming/visual-companion.md +293 -0
  17. package/skills/dispatching-parallel-agents/SKILL.md +167 -0
  18. package/skills/executing-plans/SKILL.md +64 -0
  19. package/skills/finishing-a-development-branch/SKILL.md +202 -0
  20. package/skills/receiving-code-review/SKILL.md +205 -0
  21. package/skills/requesting-code-review/SKILL.md +95 -0
  22. package/skills/requesting-code-review/code-reviewer.md +169 -0
  23. package/skills/subagent-driven-development/SKILL.md +347 -0
  24. package/skills/subagent-driven-development/implementer-prompt.md +133 -0
  25. package/skills/subagent-driven-development/re-review-prompt.md +84 -0
  26. package/skills/subagent-driven-development/scripts/review-package +46 -0
  27. package/skills/subagent-driven-development/scripts/sdd-workspace +40 -0
  28. package/skills/subagent-driven-development/scripts/task-brief +41 -0
  29. package/skills/subagent-driven-development/task-reviewer-prompt.md +129 -0
  30. package/skills/systematic-debugging/CREATION-LOG.md +119 -0
  31. package/skills/systematic-debugging/SKILL.md +283 -0
  32. package/skills/systematic-debugging/condition-based-waiting-example.ts +158 -0
  33. package/skills/systematic-debugging/condition-based-waiting.md +116 -0
  34. package/skills/systematic-debugging/defense-in-depth.md +122 -0
  35. package/skills/systematic-debugging/find-polluter.sh +72 -0
  36. package/skills/systematic-debugging/root-cause-tracing.md +169 -0
  37. package/skills/systematic-debugging/test-academic.md +14 -0
  38. package/skills/systematic-debugging/test-pressure-1.md +58 -0
  39. package/skills/systematic-debugging/test-pressure-2.md +68 -0
  40. package/skills/systematic-debugging/test-pressure-3.md +69 -0
  41. package/skills/test-driven-development/SKILL.md +322 -0
  42. package/skills/test-driven-development/writing-good-tests.md +145 -0
  43. package/skills/using-git-worktrees/SKILL.md +167 -0
  44. package/skills/using-superpowers/SKILL.md +64 -0
  45. package/skills/using-superpowers/references/antigravity-tools.md +23 -0
  46. package/skills/using-superpowers/references/codex-tools.md +108 -0
  47. package/skills/using-superpowers/references/dsh-tools.md +47 -0
  48. package/skills/using-superpowers/references/gemini-tools.md +63 -0
  49. package/skills/using-superpowers/references/hermes-tools.md +56 -0
  50. package/skills/using-superpowers/references/pi-tools.md +16 -0
  51. package/skills/verification-before-completion/SKILL.md +120 -0
  52. package/skills/writing-plans/SKILL.md +160 -0
  53. package/skills/writing-plans/plan-document-reviewer-prompt.md +49 -0
  54. package/skills/writing-skills/SKILL.md +679 -0
  55. package/skills/writing-skills/anthropic-best-practices.md +1146 -0
  56. package/skills/writing-skills/examples/CLAUDE_MD_TESTING.md +188 -0
  57. package/skills/writing-skills/graphviz-conventions.dot +172 -0
  58. package/skills/writing-skills/persuasion-principles.md +187 -0
  59. package/skills/writing-skills/render-graphs.js +169 -0
  60. package/skills/writing-skills/testing-skills-with-subagents.md +384 -0
@@ -0,0 +1,209 @@
1
+ #!/usr/bin/env bash
2
+ # Start the brainstorm server and output connection info
3
+ # Usage: start-server.sh [--project-dir <path>] [--host <bind-host>] [--url-host <display-host>] [--foreground] [--background]
4
+ #
5
+ # Starts server on a random high port, outputs JSON with URL.
6
+ # Each session gets its own directory to avoid conflicts.
7
+ #
8
+ # Options:
9
+ # --project-dir <path> Store session files under <path>/.superpowers/brainstorm/
10
+ # instead of /tmp. Files persist after server stops.
11
+ # --host <bind-host> Host/interface to bind (default: 127.0.0.1).
12
+ # Use 0.0.0.0 in remote/containerized environments.
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).
17
+ # --foreground Run server in the current terminal (no backgrounding).
18
+ # --background Force background mode (overrides Codex auto-foreground).
19
+
20
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
21
+
22
+ # Parse arguments
23
+ PROJECT_DIR=""
24
+ FOREGROUND="false"
25
+ FORCE_BACKGROUND="false"
26
+ BIND_HOST="127.0.0.1"
27
+ URL_HOST=""
28
+ IDLE_TIMEOUT_MINUTES=""
29
+ while [[ $# -gt 0 ]]; do
30
+ case "$1" in
31
+ --project-dir)
32
+ PROJECT_DIR="$2"
33
+ shift 2
34
+ ;;
35
+ --host)
36
+ BIND_HOST="$2"
37
+ shift 2
38
+ ;;
39
+ --url-host)
40
+ URL_HOST="$2"
41
+ shift 2
42
+ ;;
43
+ --idle-timeout-minutes)
44
+ IDLE_TIMEOUT_MINUTES="$2"
45
+ shift 2
46
+ ;;
47
+ --open)
48
+ export BRAINSTORM_OPEN=1
49
+ shift
50
+ ;;
51
+ --foreground|--no-daemon)
52
+ FOREGROUND="true"
53
+ shift
54
+ ;;
55
+ --background|--daemon)
56
+ FORCE_BACKGROUND="true"
57
+ shift
58
+ ;;
59
+ *)
60
+ echo "{\"error\": \"Unknown argument: $1\"}"
61
+ exit 1
62
+ ;;
63
+ esac
64
+ done
65
+
66
+ if [[ -z "$URL_HOST" ]]; then
67
+ if [[ "$BIND_HOST" == "127.0.0.1" || "$BIND_HOST" == "localhost" ]]; then
68
+ URL_HOST="localhost"
69
+ else
70
+ URL_HOST="$BIND_HOST"
71
+ fi
72
+ fi
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
+
97
+ # Some environments reap detached/background processes. Auto-foreground when detected.
98
+ if [[ -n "${CODEX_CI:-}" && "$FOREGROUND" != "true" && "$FORCE_BACKGROUND" != "true" ]]; then
99
+ FOREGROUND="true"
100
+ fi
101
+
102
+ # Windows/Git Bash reaps nohup background processes. Auto-foreground when detected.
103
+ if [[ "$FOREGROUND" != "true" && "$FORCE_BACKGROUND" != "true" ]]; then
104
+ if is_windows_like_shell; then
105
+ FOREGROUND="true"
106
+ fi
107
+ fi
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
+
113
+ # Generate unique session directory
114
+ SESSION_ID="$$-$(date +%s)"
115
+
116
+ if [[ -n "$PROJECT_DIR" ]]; then
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"
122
+ else
123
+ SESSION_DIR="/tmp/brainstorm-${SESSION_ID}"
124
+ fi
125
+
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"
130
+
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
143
+
144
+ # Kill any existing server
145
+ if [[ -f "$PID_FILE" ]]; then
146
+ old_pid=$(cat "$PID_FILE")
147
+ kill "$old_pid" 2>/dev/null
148
+ rm -f "$PID_FILE"
149
+ fi
150
+
151
+ cd "$SCRIPT_DIR" || exit 1
152
+
153
+ # Resolve the harness PID (grandparent of this script).
154
+ # $PPID is the ephemeral shell the harness spawned to run us — it dies
155
+ # when this script exits. The harness itself is $PPID's parent.
156
+ OWNER_PID="$(ps -o ppid= -p "$PPID" 2>/dev/null | tr -d ' ')"
157
+ if [[ -z "$OWNER_PID" || "$OWNER_PID" == "1" ]]; then
158
+ OWNER_PID="$PPID"
159
+ fi
160
+
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
168
+
169
+ # Foreground mode for environments that reap detached/background processes.
170
+ if [[ "$FOREGROUND" == "true" ]]; then
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"
175
+ exit $?
176
+ fi
177
+
178
+ # Start server, capturing output to log file
179
+ # Use nohup to survive shell exit; disown to remove from job table
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 &
181
+ SERVER_PID=$!
182
+ disown "$SERVER_PID" 2>/dev/null
183
+ echo "$SERVER_PID" > "$PID_FILE"
184
+
185
+ # Wait for server-started message (check log file)
186
+ for _ in {1..50}; do
187
+ if grep -q "server-started" "$LOG_FILE" 2>/dev/null; then
188
+ # Verify server is still alive after a short window (catches process reapers)
189
+ alive="true"
190
+ for _ in {1..20}; do
191
+ if ! kill -0 "$SERVER_PID" 2>/dev/null; then
192
+ alive="false"
193
+ break
194
+ fi
195
+ sleep 0.1
196
+ done
197
+ if [[ "$alive" != "true" ]]; then
198
+ echo "{\"error\": \"Server started but was killed. Retry in a persistent terminal with: $SCRIPT_DIR/start-server.sh${PROJECT_DIR:+ --project-dir $PROJECT_DIR} --host $BIND_HOST --url-host $URL_HOST --foreground\"}"
199
+ exit 1
200
+ fi
201
+ grep "server-started" "$LOG_FILE" | head -1
202
+ exit 0
203
+ fi
204
+ sleep 0.1
205
+ done
206
+
207
+ # Timeout - server didn't start
208
+ echo '{"error": "Server failed to start within 5 seconds"}'
209
+ exit 1
@@ -0,0 +1,120 @@
1
+ #!/usr/bin/env bash
2
+ # Stop the brainstorm server and clean up
3
+ # Usage: stop-server.sh <session_dir>
4
+ #
5
+ # Kills the server process. Only deletes session directory if it's
6
+ # under /tmp (ephemeral). Persistent directories (.superpowers/) are
7
+ # kept so mockups can be reviewed later.
8
+
9
+ SESSION_DIR="$1"
10
+
11
+ if [[ -z "$SESSION_DIR" ]]; then
12
+ echo '{"error": "Usage: stop-server.sh <session_dir>"}'
13
+ exit 1
14
+ fi
15
+
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
+ }
72
+
73
+ if [[ -f "$PID_FILE" ]]; then
74
+ pid=$(cat "$PID_FILE")
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
+
85
+ # Try to stop gracefully, fallback to force if still alive
86
+ kill "$pid" 2>/dev/null || true
87
+
88
+ # Wait for graceful shutdown (up to ~2s)
89
+ for _ in {1..20}; do
90
+ if ! kill -0 "$pid" 2>/dev/null; then
91
+ break
92
+ fi
93
+ sleep 0.1
94
+ done
95
+
96
+ # If still running, escalate to SIGKILL
97
+ if kill -0 "$pid" 2>/dev/null; then
98
+ kill -9 "$pid" 2>/dev/null || true
99
+
100
+ # Give SIGKILL a moment to take effect
101
+ sleep 0.1
102
+ fi
103
+
104
+ if kill -0 "$pid" 2>/dev/null; then
105
+ echo '{"status": "failed", "error": "process still running"}'
106
+ exit 1
107
+ fi
108
+
109
+ rm -f "$PID_FILE" "$SERVER_ID_FILE" "${STATE_DIR}/server.log"
110
+ mark_stopped "stop-server.sh"
111
+
112
+ # Only delete ephemeral /tmp directories
113
+ if [[ "$SESSION_DIR" == /tmp/* ]]; then
114
+ rm -rf "$SESSION_DIR"
115
+ fi
116
+
117
+ echo '{"status": "stopped"}'
118
+ else
119
+ echo '{"status": "not_running"}'
120
+ fi
@@ -0,0 +1,47 @@
1
+ # Spec 文档审查提示词模板
2
+
3
+ 在派发 Spec 文档审查子代理时使用本模板。
4
+
5
+ **目标:** 验证 Spec 是否完整、一致且已就绪,可进入实现规划阶段。
6
+
7
+ **派发时机:** Spec 文档已写入 docs/superpowers/specs/ 之后
8
+
9
+ ```
10
+ Subagent (general-purpose):
11
+ description: "Review spec document"
12
+ prompt: |
13
+ 你是一名 Spec 文档审查员,请验证该 Spec 是否完整且已就绪,可进入规划阶段。
14
+
15
+ **待审查 Spec:** [SPEC_FILE_PATH]
16
+
17
+ ## 检查项
18
+
19
+ | 类别 | 检查内容 |
20
+ |----------|------------------|
21
+ | 完整性 | TODO、占位符、"TBD"、未完成的章节 |
22
+ | 一致性 | 内部矛盾、相互冲突的需求 |
23
+ | 清晰度 | 需求是否模糊到可能导致实现错误 |
24
+ | 范围 | 是否聚焦于单一规划——未涵盖多个独立子系统 |
25
+ | YAGNI | 未被要求的功能、过度设计 |
26
+
27
+ ## 判定标准
28
+
29
+ **仅标记会在实现规划阶段引发实际问题的缺陷。**
30
+ 缺失章节、矛盾之处,或模糊到可能产生两种不同解读的需求——这些才算问题。措辞上的细微优化、风格偏好以及“某些章节不如其他章节详细”不算问题。
31
+
32
+ 除非存在会导致规划缺陷的严重缺口,否则应予以通过。
33
+
34
+ ## 输出格式
35
+
36
+ ## Spec 审查
37
+
38
+ **状态:** 已通过 | 发现问题
39
+
40
+ **问题(如有):**
41
+ - [章节 X]:[具体问题] - [对规划的影响]
42
+
43
+ **建议(仅供参考,不影响通过结论):**
44
+ - [改进建议]
45
+ ```
46
+
47
+ **审查员返回:** 状态、问题(如有)、建议
@@ -0,0 +1,293 @@
1
+ # 可视化辅助指南
2
+
3
+ 基于浏览器的可视化头脑风暴辅助工具,用于展示原型、图表和选项。
4
+
5
+ ## 何时使用
6
+
7
+ 按问题逐个判断,而非按会话判断。判断标准:**用户看图是否比看文字更易理解?**
8
+
9
+ **内容本身是可视化的场景,适合使用浏览器:**
10
+
11
+ - **界面原型** — 线框图、布局、导航结构、组件设计
12
+ - **架构图** — 系统组件、数据流、关系图谱
13
+ - **并排可视化对比** — 对比两种布局、两种配色方案、两种设计方向
14
+ - **设计打磨** — 问题涉及外观与质感、间距、视觉层级
15
+ - **空间关系** — 状态机、流程图、实体关系等以图形方式呈现
16
+
17
+ **内容为文本或表格的场景,适合使用终端:**
18
+
19
+ - **需求与范围问题** — “X 是什么意思?”,“哪些功能在范围内?”
20
+ - **概念性的 A/B/C 选择** — 在文字描述的方案之间做选择
21
+ - **权衡清单** — 优缺点、对比表格
22
+ - **技术决策** — API 设计、数据建模、架构方案选型
23
+ - **澄清性问题** — 任何答案是文字而非视觉偏好的问题
24
+
25
+ 一个*关于*界面主题的问题并不自动等同于可视化问题。“你想要哪种向导?”是概念性问题——使用终端。“这些向导布局中哪一个更合适?”是可视化问题——使用浏览器。
26
+
27
+ ## 工作原理
28
+
29
+ 服务器监听目录中的 HTML 文件,并将最新的文件提供给浏览器。你将 HTML 内容写入 `screen_dir`,用户在浏览器中即可看到,并可点击选择选项。选择结果会记录到 `state_dir/events`,你在下一轮对话中读取即可。
30
+
31
+ **内容片段与完整文档:** 如果你的 HTML 文件以 `<!DOCTYPE` 或 `<html` 开头,服务器将原样提供(仅注入辅助脚本)。否则,服务器会自动将你的内容包裹到框架模板中——添加页头、CSS 主题、连接状态及所有交互基础设施。**默认编写内容片段。** 仅在需要完全控制页面时才编写完整文档。
32
+
33
+ ## 启动会话
34
+
35
+ ```bash
36
+ # Start AFTER the user approves the companion. --open auto-opens their browser on
37
+ # the first screen; --project-dir persists mockups and enables same-port restart.
38
+ scripts/start-server.sh --project-dir /path/to/project --open
39
+
40
+ # Returns: {"type":"server-started","port":52341,
41
+ # "url":"http://localhost:52341/?key=ab12…",
42
+ # "screen_dir":"/path/to/project/.superpowers/brainstorm/12345-1706000000/content",
43
+ # "state_dir":"/path/to/project/.superpowers/brainstorm/12345-1706000000/state"}
44
+ ```
45
+
46
+ 保存响应中的 `screen_dir` 和 `state_dir`。使用 `--open` 时,浏览器会在你推送首屏时自动打开——你无需让用户手动打开,但仍需分享 URL 作为备用方案(无头/远程环境无法自动打开)。
47
+
48
+ **URL 中包含会话密钥(`?key=…`)。** 服务器会拒绝任何不带该密钥的请求,因此务必向用户提供 `url` 字段中的**完整** URL——不要去除查询字符串,也不要只给裸的 `http://host:port`。该密钥用于控制 HTTP 和 WebSocket 访问,防止随意的浏览器标签页或同一网络中的其他机器读取页面或注入事件。首次加载后,浏览器会通过 Cookie 记住该密钥,因此重新加载和访问 `/files/*` 资源时无需重复携带。
49
+
50
+ **查找连接信息:** 服务器会将启动时的 JSON 写入 `$STATE_DIR/server-info`。如果你在后台启动了服务器且未捕获标准输出,可读取该文件以获取 URL 和端口。使用 `--project-dir` 时,请在 `<project>/.superpowers/brainstorm/` 下查找会话目录。
51
+
52
+ **注意:** 将项目根目录作为 `--project-dir` 传入,这样原型会持久化到 `.superpowers/brainstorm/` 并在服务器重启后依然保留。若不传,文件会写入 `/tmp` 并被清理。如果 `.gitignore` 中尚未包含 `.superpowers/`,请提醒用户添加。
53
+
54
+ **按平台启动服务器:**
55
+
56
+ **Claude Code:**
57
+ ```bash
58
+ # Default mode works — the script backgrounds the server itself.
59
+ scripts/start-server.sh --project-dir /path/to/project --open
60
+ ```
61
+
62
+ 在 Windows 上,脚本会自动检测并切换到前台模式(会阻塞工具调用)。请在 Bash 工具调用上使用 `run_in_background: true`,使服务器在对话轮次之间保持运行,然后在下一轮读取 `$STATE_DIR/server-info` 以获取 URL 和端口。
63
+
64
+ **Codex:**
65
+ ```bash
66
+ # Codex reaps background processes. The script auto-detects CODEX_CI and
67
+ # switches to foreground mode. Run it normally — no extra flags needed.
68
+ scripts/start-server.sh --project-dir /path/to/project --open
69
+ ```
70
+
71
+ **Gemini CLI:**
72
+ ```bash
73
+ # Use --foreground and set is_background: true on your shell tool call
74
+ # so the process survives across turns
75
+ scripts/start-server.sh --project-dir /path/to/project --open --foreground
76
+ ```
77
+
78
+ **Copilot CLI:**
79
+ ```bash
80
+ # Start it with Copilot CLI's non-blocking/background shell mechanism so the
81
+ # server survives across turns. Keep --foreground so the harness, not the
82
+ # script, owns backgrounding. The launcher is a .sh, so invoke it via bash
83
+ # (on Windows, call Git Bash's bash.exe from the PowerShell tool).
84
+ bash scripts/start-server.sh --project-dir /path/to/project --open --foreground
85
+ ```
86
+
87
+ **其他环境:** 服务器必须在后台持续运行并跨越对话轮次。如果你的环境会回收 detached 进程,请使用 `--foreground` 并通过平台提供的后台执行机制来启动命令。
88
+
89
+ 如果 URL 在你的浏览器中无法访问(在远程/容器化环境中很常见),请绑定非回环地址:
90
+
91
+ ```bash
92
+ scripts/start-server.sh \
93
+ --project-dir /path/to/project \
94
+ --host 0.0.0.0 \
95
+ --url-host localhost
96
+ ```
97
+
98
+ 使用 `--url-host` 控制返回的 URL JSON 中显示的主机名。
99
+
100
+ ## 循环流程
101
+
102
+ 1. **检查服务器是否存活**,然后**向 `screen_dir` 写入 HTML 新文件**:
103
+ - **必须:在引用 URL 或推送页面前确认服务器存活。** 检查 `$STATE_DIR/server-info` 是否存在且 `$STATE_DIR/server-stopped` 是否不存在。如果已关闭,请使用**相同的 `--project-dir`** 通过 `start-server.sh` 重启——它会复用同一端口,用户的已打开标签页会自动重连(服务器宕机期间会显示“已暂停”遮罩),无需发送新 URL。服务器在空闲 4 小时后自动退出(可通过 `--idle-timeout-minutes` 配置)。
104
+ - 使用语义化文件名:`platform.html`、`visual-style.html`、`layout.html`
105
+ - **不要复用文件名**——每个页面都使用全新文件
106
+ - 使用你的文件创建工具——**不要使用 cat/heredoc**(会在终端产生大量噪音)
107
+ - 服务器自动提供最新的文件
108
+
109
+ 2. **告知用户预期内容并结束本轮:**
110
+ - 提醒他们 URL(每一步都要,不只是第一步)
111
+ - 简要文字概括屏幕内容(例如:“正在展示首页的 3 种布局方案”)
112
+ - 请他们在终端中回应:“请查看后告诉我你的想法。如果愿意,可以点击选择一个选项。”
113
+
114
+ 3. **在你的下一轮**——用户在终端回应后:
115
+ - 如果存在,读取 `$STATE_DIR/events`——其中包含用户在浏览器中的交互(点击、选择),以 JSON 行格式记录
116
+ - 将其与用户的终端文本合并,以获得完整信息
117
+ - 终端消息是主要反馈;`state_dir/events` 提供结构化的交互数据
118
+
119
+ 4. **迭代或推进**——如果反馈改变了当前页面,写入新文件(例如 `layout-v2.html`)。仅在当前步骤已确认后再进入下一步。
120
+
121
+ 5. **回到终端时卸载**——当下一步不需要浏览器时(例如澄清问题、权衡讨论),推送一个等待页面以清除过时内容:
122
+
123
+ ```html
124
+ <!-- filename: waiting.html (or waiting-2.html, etc.) -->
125
+ <div style="display:flex;align-items:center;justify-content:center;min-height:60vh">
126
+ <p class="subtitle">Continuing in terminal...</p>
127
+ </div>
128
+ ```
129
+
130
+ 这样可避免用户在对话已推进后仍盯着已解决的选择。当下一个可视化问题出现时,像往常一样推送新的内容文件即可。
131
+
132
+ 6. 重复上述流程直至完成。
133
+
134
+ ## 编写内容片段
135
+
136
+ 只需编写页面内部的内容。服务器会自动将其包裹到框架模板中(页头、主题 CSS、连接状态及所有交互基础设施)。
137
+
138
+ **最小示例:**
139
+
140
+ ```html
141
+ <h2>Which layout works better?</h2>
142
+ <p class="subtitle">Consider readability and visual hierarchy</p>
143
+
144
+ <div class="options">
145
+ <div class="option" data-choice="a" onclick="toggleSelect(this)">
146
+ <div class="letter">A</div>
147
+ <div class="content">
148
+ <h3>Single Column</h3>
149
+ <p>Clean, focused reading experience</p>
150
+ </div>
151
+ </div>
152
+ <div class="option" data-choice="b" onclick="toggleSelect(this)">
153
+ <div class="letter">B</div>
154
+ <div class="content">
155
+ <h3>Two Column</h3>
156
+ <p>Sidebar navigation with main content</p>
157
+ </div>
158
+ </div>
159
+ </div>
160
+ ```
161
+
162
+ 就是这样。无需 `<html>`、CSS 或 `<script>` 标签。服务器会提供所有这些。
163
+
164
+ ## 可用 CSS 类
165
+
166
+ 框架模板为你的内容提供以下 CSS 类:
167
+
168
+ ### 选项(A/B/C 选择)
169
+
170
+ ```html
171
+ <div class="options">
172
+ <div class="option" data-choice="a" onclick="toggleSelect(this)">
173
+ <div class="letter">A</div>
174
+ <div class="content">
175
+ <h3>Title</h3>
176
+ <p>Description</p>
177
+ </div>
178
+ </div>
179
+ </div>
180
+ ```
181
+
182
+ **多选:** 在容器上添加 `data-multiselect` 以允许用户选择多个选项。每次点击都会切换项目的选中样式。
183
+
184
+ ```html
185
+ <div class="options" data-multiselect>
186
+ <!-- same option markup — users can select/deselect multiple -->
187
+ </div>
188
+ ```
189
+
190
+ ### 卡片(视觉设计)
191
+
192
+ ```html
193
+ <div class="cards">
194
+ <div class="card" data-choice="design1" onclick="toggleSelect(this)">
195
+ <div class="card-image"><!-- mockup content --></div>
196
+ <div class="card-body">
197
+ <h3>Name</h3>
198
+ <p>Description</p>
199
+ </div>
200
+ </div>
201
+ </div>
202
+ ```
203
+
204
+ ### 原型容器
205
+
206
+ ```html
207
+ <div class="mockup">
208
+ <div class="mockup-header">Preview: Dashboard Layout</div>
209
+ <div class="mockup-body"><!-- your mockup HTML --></div>
210
+ </div>
211
+ ```
212
+
213
+ ### 分栏视图(并排)
214
+
215
+ ```html
216
+ <div class="split">
217
+ <div class="mockup"><!-- left --></div>
218
+ <div class="mockup"><!-- right --></div>
219
+ </div>
220
+ ```
221
+
222
+ ### 优缺点
223
+
224
+ ```html
225
+ <div class="pros-cons">
226
+ <div class="pros"><h4>Pros</h4><ul><li>Benefit</li></ul></div>
227
+ <div class="cons"><h4>Cons</h4><ul><li>Drawback</li></ul></div>
228
+ </div>
229
+ ```
230
+
231
+ ### 模拟元素(线框图构建块)
232
+
233
+ ```html
234
+ <div class="mock-nav">Logo | Home | About | Contact</div>
235
+ <div style="display: flex;">
236
+ <div class="mock-sidebar">Navigation</div>
237
+ <div class="mock-content">Main content area</div>
238
+ </div>
239
+ <button class="mock-button">Action Button</button>
240
+ <input class="mock-input" placeholder="Input field">
241
+ <div class="placeholder">Placeholder area</div>
242
+ ```
243
+
244
+ ### 排版与区块
245
+
246
+ - `h2` — 页面标题
247
+ - `h3` — 区块标题
248
+ - `.subtitle` — 标题下方的次级文本
249
+ - `.section` — 带底部边距的内容块
250
+ - `.label` — 小号大写标签文本
251
+
252
+ ## 浏览器事件格式
253
+
254
+ 当用户在浏览器中点击选项时,其交互会被记录到 `$STATE_DIR/events`(每行一个 JSON 对象)。当你推送新页面时,该文件会自动清空。
255
+
256
+ ```jsonl
257
+ {"type":"click","choice":"a","text":"Option A - Simple Layout","timestamp":1706000101}
258
+ {"type":"click","choice":"c","text":"Option C - Complex Grid","timestamp":1706000108}
259
+ {"type":"click","choice":"b","text":"Option B - Hybrid","timestamp":1706000115}
260
+ ```
261
+
262
+ 完整的事件流展示了用户的探索路径——他们在确定前可能会点击多个选项。最后一个 `choice` 事件通常是最终选择,但点击模式可能揭示犹豫或偏好,值得进一步询问。
263
+
264
+ 如果 `$STATE_DIR/events` 不存在,说明用户未与浏览器交互——仅使用其终端文本即可。
265
+
266
+ ## 设计建议
267
+
268
+ - **根据问题匹配保真度**——布局问题用线框图,视觉打磨问题再做精细化
269
+ - **在每页上说明问题**——“哪种布局更显专业?”而非仅仅“选一个”
270
+ - **先迭代再推进**——如果反馈改变了当前页面,先写一个新版本
271
+ - **每屏最多 2-4 个选项**
272
+ - **在重要场景使用真实内容**——例如摄影作品集应使用真实图片(Unsplash)。占位内容会掩盖设计问题。
273
+ - **保持原型简洁**——聚焦布局与结构,而非像素级完美
274
+
275
+ ## 文件命名
276
+
277
+ - 使用语义化名称:`platform.html`、`visual-style.html`、`layout.html`
278
+ - 不要复用文件名——每个页面必须是新文件
279
+ - 迭代时:追加版本后缀,如 `layout-v2.html`、`layout-v3.html`
280
+ - 服务器按修改时间提供最新的文件
281
+
282
+ ## 清理
283
+
284
+ ```bash
285
+ scripts/stop-server.sh $SESSION_DIR
286
+ ```
287
+
288
+ 如果会话使用了 `--project-dir`,原型文件会保留在 `.superpowers/brainstorm/` 中以便后续查阅。仅 `/tmp` 会话在停止时会被删除。
289
+
290
+ ## 参考
291
+
292
+ - 框架模板(CSS 参考):`scripts/frame-template.html`
293
+ - 辅助脚本(客户端):`scripts/helper.js`