xwang 0.0.1

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 (55) hide show
  1. package/assets/skills/xwang/SKILL.md +112 -0
  2. package/assets/skills/xwang/scripts/xwang-env.sh +48 -0
  3. package/assets/skills/xwang/scripts/xwang-guard.sh +530 -0
  4. package/assets/skills/xwang/scripts/xwang-state.sh +374 -0
  5. package/assets/skills/xwang-archive/SKILL.md +86 -0
  6. package/assets/skills/xwang-build/REFERENCE.md +94 -0
  7. package/assets/skills/xwang-build/SKILL.md +113 -0
  8. package/assets/skills/xwang-design/SKILL.md +104 -0
  9. package/assets/skills/xwang-hotfix/SKILL.md +102 -0
  10. package/assets/skills/xwang-open/SKILL.md +108 -0
  11. package/assets/skills/xwang-open/scripts/xwang-open-check.sh +197 -0
  12. package/assets/skills/xwang-tweak/SKILL.md +99 -0
  13. package/assets/skills/xwang-verify/SKILL.md +112 -0
  14. package/bin/xwang.js +3 -0
  15. package/dist/cli/index.d.ts +2 -0
  16. package/dist/cli/index.d.ts.map +1 -0
  17. package/dist/cli/index.js +30 -0
  18. package/dist/cli/index.js.map +1 -0
  19. package/dist/commands/init.d.ts +9 -0
  20. package/dist/commands/init.d.ts.map +1 -0
  21. package/dist/commands/init.js +238 -0
  22. package/dist/commands/init.js.map +1 -0
  23. package/dist/core/detect.d.ts +6 -0
  24. package/dist/core/detect.d.ts.map +1 -0
  25. package/dist/core/detect.js +74 -0
  26. package/dist/core/detect.js.map +1 -0
  27. package/dist/core/mattpocock.d.ts +6 -0
  28. package/dist/core/mattpocock.d.ts.map +1 -0
  29. package/dist/core/mattpocock.js +82 -0
  30. package/dist/core/mattpocock.js.map +1 -0
  31. package/dist/core/openspec.d.ts +3 -0
  32. package/dist/core/openspec.d.ts.map +1 -0
  33. package/dist/core/openspec.js +178 -0
  34. package/dist/core/openspec.js.map +1 -0
  35. package/dist/core/package-manager.d.ts +8 -0
  36. package/dist/core/package-manager.d.ts.map +1 -0
  37. package/dist/core/package-manager.js +62 -0
  38. package/dist/core/package-manager.js.map +1 -0
  39. package/dist/core/platforms.d.ts +22 -0
  40. package/dist/core/platforms.d.ts.map +1 -0
  41. package/dist/core/platforms.js +23 -0
  42. package/dist/core/platforms.js.map +1 -0
  43. package/dist/core/superpowers.d.ts +5 -0
  44. package/dist/core/superpowers.d.ts.map +1 -0
  45. package/dist/core/superpowers.js +75 -0
  46. package/dist/core/superpowers.js.map +1 -0
  47. package/dist/core/types.d.ts +2 -0
  48. package/dist/core/types.d.ts.map +1 -0
  49. package/dist/core/types.js +2 -0
  50. package/dist/core/types.js.map +1 -0
  51. package/dist/utils/file-system.d.ts +5 -0
  52. package/dist/utils/file-system.d.ts.map +1 -0
  53. package/dist/utils/file-system.js +41 -0
  54. package/dist/utils/file-system.js.map +1 -0
  55. package/package.json +50 -0
@@ -0,0 +1,374 @@
1
+ #!/bin/bash
2
+ # xwang State — unified interface for xwang change state management
3
+ # Usage: xwang-state.sh <subcommand> <change-name> [args...]
4
+ #
5
+ # Subcommands:
6
+ # init <change-name> <workflow> — Initialize .xwang.yaml with workflow defaults
7
+ #
8
+ # Workflows: full, quick
9
+ # State phases: design, build, verify, archive (open is checked but not recorded)
10
+
11
+ set -euo pipefail
12
+
13
+ # --- Color output helpers ---
14
+
15
+ red() { echo -e "\033[31m$1\033[0m" >&2; }
16
+ green() { echo -e "\033[32m$1\033[0m" >&2; }
17
+ yellow() { echo -e "\033[33m$1\033[0m" >&2; }
18
+
19
+ # --- Script location ---
20
+
21
+ # shellcheck disable=SC2034
22
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
23
+
24
+ # --- Input validation ---
25
+
26
+ validate_change_name() {
27
+ local name="$1"
28
+ if [ -z "$name" ]; then
29
+ red "ERROR: Change name cannot be empty" >&2
30
+ exit 1
31
+ fi
32
+ if [[ ! "$name" =~ ^[a-zA-Z0-9_-]+$ ]]; then
33
+ red "ERROR: Invalid change name: '$name'" >&2
34
+ red "Valid characters: a-z, A-Z, 0-9, -, _" >&2
35
+ exit 1
36
+ fi
37
+ if [[ "$name" =~ \.\. ]]; then
38
+ red "ERROR: Change name cannot contain '..' (path traversal not allowed)" >&2
39
+ exit 1
40
+ fi
41
+ }
42
+
43
+ validate_enum() {
44
+ local value="$1"
45
+ shift
46
+ local valid_values=("$@")
47
+
48
+ for valid in "${valid_values[@]}"; do
49
+ if [ "$value" = "$valid" ]; then
50
+ return 0
51
+ fi
52
+ done
53
+
54
+ red "ERROR: Invalid value: '$value'" >&2
55
+ red "Valid values: ${valid_values[*]}" >&2
56
+ exit 1
57
+ }
58
+
59
+ # --- Helper functions ---
60
+
61
+ yaml_file_for() {
62
+ local change_name="$1"
63
+ echo "openspec/changes/$change_name/.xwang.yaml"
64
+ }
65
+
66
+ change_dir_for() {
67
+ local change_name="$1"
68
+ echo "openspec/changes/$change_name"
69
+ }
70
+
71
+ yaml_field() {
72
+ local field="$1"
73
+ local yaml_file="$2"
74
+ if [ -f "$yaml_file" ]; then
75
+ local value
76
+ value=$(grep "^${field}:" "$yaml_file" 2>/dev/null | sed "s/^${field}: *//" || true)
77
+ value=$(strip_inline_comment "$value")
78
+ strip_wrapping_quotes "$value"
79
+ fi
80
+ }
81
+
82
+ strip_inline_comment() {
83
+ local value="$1"
84
+ printf '%s\n' "$value" | awk -v squote="'" '
85
+ {
86
+ out = ""
87
+ quote = ""
88
+ for (i = 1; i <= length($0); i++) {
89
+ c = substr($0, i, 1)
90
+ if (quote == "") {
91
+ if (c == "\"" || c == squote) {
92
+ quote = c
93
+ } else if (c == "#" && (i == 1 || substr($0, i - 1, 1) ~ /[[:space:]]/)) {
94
+ sub(/[[:space:]]+$/, "", out)
95
+ print out
96
+ next
97
+ }
98
+ } else if (c == quote) {
99
+ quote = ""
100
+ }
101
+ out = out c
102
+ }
103
+ print out
104
+ }
105
+ '
106
+ }
107
+
108
+ strip_wrapping_quotes() {
109
+ local value="$1"
110
+ case "$value" in
111
+ \"*\")
112
+ printf '%s\n' "${value:1:${#value}-2}"
113
+ ;;
114
+ \'*\')
115
+ printf '%s\n' "${value:1:${#value}-2}"
116
+ ;;
117
+ *)
118
+ printf '%s\n' "$value"
119
+ ;;
120
+ esac
121
+ }
122
+
123
+ replace_yaml_field() {
124
+ local yaml_file="$1"
125
+ local field="$2"
126
+ local value="$3"
127
+ local tmp_file
128
+
129
+ tmp_file=$(mktemp)
130
+ chmod 600 "$tmp_file"
131
+ awk -v field="$field" -v value="$value" '
132
+ index($0, field ":") == 1 { $0 = field ": " value }
133
+ { buf[NR] = $0; keys[NR] = $0; sub(/:.*$/, "", keys[NR]); n = NR }
134
+ END {
135
+ for (i = 1; i <= n; i++) last[keys[i]] = i
136
+ for (i = 1; i <= n; i++) if (last[keys[i]] == i) print buf[i]
137
+ }
138
+ ' "$yaml_file" > "$tmp_file"
139
+ mv "$tmp_file" "$yaml_file"
140
+ }
141
+
142
+ validate_path_field() {
143
+ local value="$1"
144
+ local field="$2"
145
+ if [ -z "$value" ] || [ "$value" = "null" ]; then
146
+ return 0
147
+ fi
148
+ case "$value" in
149
+ /*|~*|[A-Za-z]:*|\\*)
150
+ red "ERROR: $field must be a relative path within the repo: '$value'" >&2
151
+ exit 1
152
+ ;;
153
+ esac
154
+ if [[ "$value" =~ \.\. ]]; then
155
+ red "ERROR: $field cannot contain '..' (path traversal not allowed): '$value'" >&2
156
+ exit 1
157
+ fi
158
+ }
159
+
160
+ # --- Subcommands ---
161
+
162
+ cmd_init() {
163
+ local change_name="$1"
164
+ local workflow="$2"
165
+
166
+ validate_change_name "$change_name"
167
+ validate_enum "$workflow" "full" "quick" "tweak"
168
+
169
+ local change_dir yaml_file
170
+ change_dir=$(change_dir_for "$change_name")
171
+ yaml_file=$(yaml_file_for "$change_name")
172
+
173
+ # Check if .xwang.yaml already exists
174
+ if [ -f "$yaml_file" ]; then
175
+ red "ERROR: .xwang.yaml already exists at $yaml_file"
176
+ exit 1
177
+ fi
178
+
179
+ # Create change directory if it doesn't exist
180
+ mkdir -p "$change_dir"
181
+
182
+ # Set workflow-appropriate defaults
183
+ local phase design_doc plan build_mode tdd_mode isolation
184
+ # open 阶段只做检查,实际状态记录从 design 开始
185
+ phase="design"
186
+ design_doc="null"
187
+ plan="null"
188
+ build_mode="null"
189
+ tdd_mode="null"
190
+ isolation="null"
191
+
192
+ case "$workflow" in
193
+ full)
194
+ ;;
195
+ quick|tweak)
196
+ # Quick/Tweak workflow skips design phase, starts directly at build
197
+ phase="build"
198
+ build_mode="direct"
199
+ tdd_mode="direct"
200
+ isolation="branch"
201
+ ;;
202
+ esac
203
+
204
+ # Record current HEAD as base_ref for later diff reference
205
+ local base_ref="null"
206
+ if git rev-parse --verify HEAD >/dev/null 2>&1; then
207
+ base_ref=$(git rev-parse HEAD 2>/dev/null || echo "null")
208
+ fi
209
+
210
+ cat > "$yaml_file" <<EOF
211
+ workflow: $workflow
212
+ phase: $phase
213
+ design_doc: $design_doc
214
+ plan: $plan
215
+ base_ref: $base_ref
216
+ isolation: $isolation
217
+ build_mode: $build_mode
218
+ build_pause: null
219
+ tdd_mode: $tdd_mode
220
+ subagent_dispatch: null
221
+ direct_override: false
222
+ verify_mode: null
223
+ verify_result: pending
224
+ verification_report: null
225
+ branch_status: pending
226
+ archived: false
227
+ created_at: $(date -u +%Y-%m-%d)
228
+ updated_at: null
229
+ EOF
230
+
231
+ green "Initialized: $yaml_file (workflow=$workflow)"
232
+ }
233
+
234
+ cmd_get() {
235
+ local change_name="$1"
236
+ local field="$2"
237
+
238
+ validate_change_name "$change_name"
239
+
240
+ local yaml_file
241
+ yaml_file=$(yaml_file_for "$change_name")
242
+
243
+ if [ ! -f "$yaml_file" ]; then
244
+ red "ERROR: .xwang.yaml not found at $yaml_file"
245
+ exit 1
246
+ fi
247
+
248
+ local value
249
+ value=$(yaml_field "$field" "$yaml_file")
250
+ echo "${value:-}"
251
+ }
252
+
253
+ cmd_set() {
254
+ local change_name="$1"
255
+ local field="$2"
256
+ local value="$3"
257
+
258
+ validate_change_name "$change_name"
259
+
260
+ local yaml_file
261
+ yaml_file=$(yaml_file_for "$change_name")
262
+
263
+ if [ ! -f "$yaml_file" ]; then
264
+ red "ERROR: .xwang.yaml not found at $yaml_file"
265
+ exit 1
266
+ fi
267
+
268
+ case "$field" in
269
+ workflow|phase|design_doc|plan|base_ref|isolation|build_mode|build_pause|tdd_mode|subagent_dispatch|direct_override|verify_mode|verify_result|verification_report|branch_status|archived|created_at|updated_at|build_command|verify_command)
270
+ # Valid field
271
+ ;;
272
+ *)
273
+ red "ERROR: Unknown field: '$field'" >&2
274
+ red "Valid fields: workflow, phase, design_doc, plan, base_ref, isolation, build_mode, build_pause, tdd_mode, subagent_dispatch, direct_override, verify_mode, verify_result, verification_report, branch_status, archived, created_at, updated_at, build_command, verify_command" >&2
275
+ exit 1
276
+ ;;
277
+ esac
278
+
279
+ case "$field" in
280
+ workflow)
281
+ validate_enum "$value" "full" "quick" "tweak"
282
+ ;;
283
+ phase)
284
+ validate_enum "$value" "design" "build" "verify" "archive"
285
+ ;;
286
+ isolation)
287
+ validate_enum "$value" "branch" "worktree"
288
+ ;;
289
+ build_mode)
290
+ validate_enum "$value" "subagent-driven-development" "executing-plans" "direct"
291
+ ;;
292
+ build_pause)
293
+ validate_enum "$value" "null" "plan-ready"
294
+ ;;
295
+ tdd_mode)
296
+ validate_enum "$value" "tdd" "direct"
297
+ ;;
298
+ subagent_dispatch)
299
+ validate_enum "$value" "null" "confirmed"
300
+ ;;
301
+ direct_override|archived)
302
+ validate_enum "$value" "true" "false"
303
+ ;;
304
+ verify_mode)
305
+ validate_enum "$value" "light" "full"
306
+ ;;
307
+ verify_result)
308
+ validate_enum "$value" "pending" "pass" "fail"
309
+ ;;
310
+ branch_status)
311
+ validate_enum "$value" "pending" "handled"
312
+ ;;
313
+ design_doc|plan|verification_report)
314
+ validate_path_field "$value" "$field"
315
+ ;;
316
+ esac
317
+
318
+ if grep -q "^${field}:" "$yaml_file"; then
319
+ replace_yaml_field "$yaml_file" "$field" "$value"
320
+ else
321
+ echo "${field}: ${value}" >> "$yaml_file"
322
+ fi
323
+
324
+ # Automatically update updated_at when other fields change
325
+ if [ "$field" != "updated_at" ] && [ "$field" != "created_at" ]; then
326
+ replace_yaml_field "$yaml_file" "updated_at" "$(date -u +%Y-%m-%d)"
327
+ fi
328
+
329
+ green "[SET] ${field}=${value}"
330
+ }
331
+
332
+ # --- Main ---
333
+
334
+ SUBCOMMAND="${1:-}"
335
+ shift || true
336
+
337
+ case "$SUBCOMMAND" in
338
+ init)
339
+ if [ $# -lt 2 ]; then
340
+ red "Usage: xwang-state.sh init <change-name> <workflow>" >&2
341
+ red "Workflows: full, quick, tweak" >&2
342
+ exit 1
343
+ fi
344
+ cmd_init "$@"
345
+ ;;
346
+ get)
347
+ if [ $# -lt 2 ]; then
348
+ red "Usage: xwang-state.sh get <change-name> <field>" >&2
349
+ exit 1
350
+ fi
351
+ cmd_get "$@"
352
+ ;;
353
+ set)
354
+ if [ $# -lt 3 ]; then
355
+ red "Usage: xwang-state.sh set <change-name> <field> <value>" >&2
356
+ exit 1
357
+ fi
358
+ cmd_set "$@"
359
+ ;;
360
+ *)
361
+ red "Unknown subcommand: $SUBCOMMAND" >&2
362
+ echo "" >&2
363
+ echo "Usage: xwang-state.sh <subcommand> <change-name> [args...]" >&2
364
+ echo "" >&2
365
+ echo "Subcommands:" >&2
366
+ echo " init <change-name> <workflow> — Initialize .xwang.yaml with workflow defaults" >&2
367
+ echo " get <change-name> <field> — Read a field value from .xwang.yaml" >&2
368
+ echo " set <change-name> <field> <val> — Update a field value in .xwang.yaml" >&2
369
+ echo "" >&2
370
+ echo "Workflows: full, quick, tweak" >&2
371
+ echo "State phases: design, build, verify, archive (open is checked but not recorded)" >&2
372
+ exit 1
373
+ ;;
374
+ esac
@@ -0,0 +1,86 @@
1
+ ---
2
+ name: xwang-archive
3
+ description: 启动 xwang 项目阶段5:归档。在 verify 完成后按 OpenSpec delta 语义合并主 spec、移动 change 到归档目录,并将 `.xwang.yaml` 标记为已归档。当用户触发 xwang 阶段5、开始归档、xwang-archive,或在 xwang-verify 完成后要求归档时使用。
4
+ ---
5
+
6
+ # xwang-archive
7
+
8
+ ## 前置条件
9
+
10
+ - 当前 change 的 `.xwang.yaml` 中 `phase` 为 `archive`
11
+ - `verification_report` 指向已存在的验证报告文件
12
+ - `branch_status` 为 `handled`
13
+
14
+ ## Quick start
15
+
16
+ 当用户触发 xwang 阶段5时:
17
+
18
+ 1. 确定 change 名称 `<name>`:优先使用用户提供的名称;若未提供,从 `openspec/changes/` 下选择 phase 为 `archive` 的 change。
19
+ 2. 读取 `.xwang.yaml` 确认当前 phase 为 `archive`,且验证报告、分支状态已记录。
20
+ 3. 向用户展示归档摘要,并**暂停等待用户确认**是否立即归档。
21
+ 4. 用户确认后,调用 `/openspec-archive-change` 按 delta 语义合并主 spec 并移动 change 到归档目录。
22
+ 5. 调用 `xwang-state.sh set <name> archived true`。
23
+ 6. 向用户汇报归档结果与新路径。
24
+
25
+ ## Workflows
26
+
27
+ 开始前先定位 xwang 脚本:
28
+
29
+ ```bash
30
+ XWANG_ENV="${XWANG_ENV:-$(find . "$HOME"/.*/skills "$HOME/.config" -path '*/xwang/scripts/xwang-env.sh' -type f -print -quit 2>/dev/null)}"
31
+ if [ -z "$XWANG_ENV" ]; then
32
+ echo "ERROR: xwang-env.sh not found. Ensure the xwang skill is installed." >&2
33
+ return 1
34
+ fi
35
+ . "$XWANG_ENV"
36
+ ```
37
+
38
+ ### Step 1:入口确认
39
+
40
+ - [ ] 获取 `<name>`:用户未提供时,选择 `.xwang.yaml` 中 `phase: archive` 的 change。
41
+ - [ ] 读取 `openspec/changes/<name>/.xwang.yaml`,确认:
42
+ - `phase` 为 `archive`
43
+ - `verification_report` 非空且文件存在
44
+ - `branch_status` 为 `handled`
45
+ - [ ] 若入口条件不满足,提示用户先完成 `/xwang-verify`。
46
+
47
+ ### Step 2:归档前最终确认(阻塞点)
48
+
49
+ - [ ] 向用户展示简短摘要:
50
+ - change 名称
51
+ - 验证报告路径和结论
52
+ - 分支处理状态
53
+ - 本次归档将执行的不可逆动作:按 OpenSpec delta 语义合并主 spec、移动 change 到 `openspec/changes/archive/` 目录、将 `.xwang.yaml` 标记为 `archived: true`
54
+ - [ ] **必须使用当前平台可用的用户输入/确认机制暂停并等待用户选择**:
55
+ - **确认归档**:立即执行归档
56
+ - **需要调整或重新验证**:不执行归档;调用 `"$XWANG_STATE" set <name> phase verify` 回到 verify,再调用 `/xwang-verify`
57
+ - **暂不归档**:不执行归档,保留当前 `phase: archive` 状态,等待用户稍后再次调用 `/xwang-archive`
58
+ - [ ] 只有用户选择「确认归档」后才继续 Step 3。
59
+
60
+ ### Step 3:执行归档
61
+
62
+ - [ ] 调用 `/openspec-archive-change <name>`(或等价的 OpenSpec archive 命令)按 delta 语义合并主 spec 并移动 change 到归档目录。
63
+ - [ ] 如归档命令返回非零退出码,报告错误并停止。
64
+ - [ ] 归档成功后,确认 change 目录已移动到 `openspec/changes/archive/YYYY-MM-DD-<name>/`(或 OpenSpec 默认归档路径)。
65
+
66
+ ### Step 4:标记归档状态
67
+
68
+ - [ ] 对归档后的 `.xwang.yaml` 调用 `"$XWANG_STATE" set <name> archived true`。
69
+ - [ ] **归档完整性守护**:调用 `"$XWANG_GUARD" <name> archive` 校验归档后的退出条件(`archived: true`、必要文档存在且 tasks 已勾选)。
70
+ - [ ] 如需,在 PRD 和 plan 文件前置元数据中标注 `archived-with: <name>` 和 `status: archived`。
71
+ - [ ] 向用户汇报归档完成、新目录路径与生命周期闭环状态。
72
+
73
+ ## 退出条件
74
+
75
+ - 归档命令执行成功
76
+ - 归档目录存在
77
+ - `.xwang.yaml` 中 `archived: true`
78
+
79
+ ## 完成
80
+
81
+ xwang 流程全部完成。如需开始新工作,调用 `/xwang` 或 `/xwang-open`。
82
+
83
+ ## Advanced features
84
+
85
+ - **预览归档**:调用 `/openspec-archive-change` 时如支持 `--dry-run`,可先预览再执行。
86
+ - **从 archive 恢复**:如需重新验证,先 `set <name> phase verify`,再调用 `/xwang-verify`。
@@ -0,0 +1,94 @@
1
+ # xwang-build 参考
2
+
3
+ ## xwang 三阶段流程
4
+
5
+ | 阶段 | Skill | 职责 | 主要产物 |
6
+ |------|-------|------|----------|
7
+ | 1 | *(待定义)* | *(待定义)* | *(待定义)* |
8
+ | 2 | `xwang-design` | 深度设计、澄清需求、产出 PRD 与 OpenSpec change | `docs/mattpocock/<name>-prd.md`、`openspec/changes/<name>/**` |
9
+ | 3 | `xwang-build` | 基于设计产物制定实现计划 | `docs/superpowers/plans/YYYY-MM-DD-<name>.md` |
10
+
11
+ ## 阶段2产物结构
12
+
13
+ ```
14
+ project/
15
+ ├── docs/mattpocock/
16
+ │ └── <name>-prd.md # 中文 PRD
17
+ └── openspec/changes/<name>/
18
+ ├── .openspec.yaml # change 元数据
19
+ ├── proposal.md # 变更提案
20
+ ├── design.md # 设计决策
21
+ ├── tasks.md # 任务清单
22
+ └── specs/
23
+ ├── <capability-1>/
24
+ │ └── spec.md # capability 详细规格
25
+ └── <capability-2>/
26
+ └── spec.md
27
+ ```
28
+
29
+ ## 读取顺序与用途
30
+
31
+ 1. **PRD** (`docs/mattpocock/<name>-prd.md`)
32
+ - 需求总览、目标用户、验收标准。
33
+ - 用于把握整体目标。
34
+
35
+ 2. **proposal.md**
36
+ - Why / What Changes / Capabilities / Impact。
37
+ - 用于识别需要实现哪些 capability。
38
+
39
+ 3. **design.md**
40
+ - Context / Goals & Non-Goals / Decisions / Risks。
41
+ - 用于理解架构决策与约束。
42
+
43
+ 4. **tasks.md**
44
+ - OpenSpec 生成的初始任务列表。
45
+ - 作为 writing-plans 的输入参考,但不直接照抄;需重新按 writing-plans 粒度拆分。
46
+
47
+ 5. **specs/\*/spec.md**
48
+ - 每个 capability 的 ADDED Requirements、Scenarios。
49
+ - 用于确保计划覆盖所有验收场景。
50
+
51
+ ## 与 writing-plans 的衔接
52
+
53
+ - 调用 `/writing-plans` 前,需将上述文档内容汇总到当前对话上下文。
54
+ - 明确告知 writing-plans:
55
+ - 计划保存路径为 `docs/superpowers/plans/YYYY-MM-DD-<name>.md`。
56
+ - 需要覆盖所有 `specs/` 下的 capability。
57
+ - 遵循项目的现有代码风格与目录结构。
58
+
59
+ ## 失败处理
60
+
61
+ - 若 `openspec/changes/` 不存在或为空:提示用户先运行 `/xwang-design`。
62
+ - 若指定 `<name>` 的 change 不存在:列出可用 change 名称让用户选择。
63
+ - 若缺少 PRD 或核心 spec:仍可基于现有文档生成计划,但需向用户说明缺失内容。
64
+
65
+ ## 执行计划
66
+
67
+ 选择工作方式后进入执行阶段。
68
+
69
+ ### executing-plans 模式
70
+
71
+ 1. 使用 Skill 工具加载 Superpowers `executing-plans` 技能,ARGUMENTS 包含:`Language: 使用触发本次工作流的用户请求语言输出`。
72
+ 2. 若 `tdd_mode: tdd`,在执行第一个任务前加载 Superpowers `test-driven-development` 技能一次。
73
+ 3. 按计划执行任务,勾选 plan 中对应任务。
74
+ 4. 若任务映射到 `openspec/changes/<name>/tasks.md`,同步将对应 OpenSpec 任务从 `- [ ]` 改为 `- [x]`。
75
+ 5. 所有任务完成后,加载 Superpowers `requesting-code-review` 技能请求代码审查。
76
+
77
+ ### subagent-driven-development 模式
78
+
79
+ 1. 主窗口只负责协调,不得在当前主窗口直接运行 `subagent-driven-development` 技能。
80
+ 2. 把下一个未完成任务派发到后台 subagent,prompt 必须包含:
81
+ - Language 约束:`Language: 使用触发本次工作流的用户请求语言输出`
82
+ - TDD 硬约束(若 `tdd_mode: tdd`):"You MUST follow TDD: for each task, write a failing test first, watch it fail, then write minimal code to pass. No production code without a failing test first."
83
+ - 持久化勾选要求:任务完成后立即勾选 Superpowers plan 中对应任务;若映射到 OpenSpec tasks.md,同步勾选对应 OpenSpec 任务。
84
+ 3. subagent 自行加载 `subagent-driven-development` 并按其指引完成实现、检查与提交。
85
+
86
+ ### 异常调试
87
+
88
+ 执行任务期间若出现崩溃、异常行为、测试失败或构建失败,立即加载 Superpowers `systematic-debugging` 技能。完成根因调查前不得提出或实施源码修复。
89
+
90
+ ### 计划任务勾选要求
91
+
92
+ - 不得只更新内置 Todo 或对话内 checklist。
93
+ - 必须持久化到 `docs/superpowers/plans/YYYY-MM-DD-<name>.md`。
94
+ - 若 plan 任务映射到 OpenSpec tasks.md,也同步更新 `openspec/changes/<name>/tasks.md`。
@@ -0,0 +1,113 @@
1
+ ---
2
+ name: xwang-build
3
+ description: 启动 xwang 项目阶段3:基于 xwang-design 生成的 PRD 与 OpenSpec 各 spec 文档,通过 subagent 制定实现计划并自动选择执行方式实施。Use when 用户触发 xwang 阶段3、开始构建、xwang-build,或在 xwang-design 完成后要求自动制定并执行实施计划。
4
+ ---
5
+
6
+ # xwang-build
7
+
8
+ ## Quick start
9
+
10
+ 当用户触发 xwang 阶段3时:
11
+
12
+ 1. 确定 change 名称 `<name>`:优先使用用户提供的名称;若未提供,从 `openspec/changes/` 下选择最近修改的 change 目录。
13
+ 2. 读取阶段2产物:PRD、proposal、design、tasks 以及 `specs/` 下所有 `spec.md`。
14
+ 3. 通过 subagent 加载 `/writing-plans` 制定计划,避免占用主 session 上下文。
15
+ 4. 计划保存到 `docs/superpowers/plans/YYYY-MM-DD-<name>.md`,文件头包含 change、design-doc、base-ref 元数据。
16
+ 5. 计划完成后自动选择工作方式:任务数 ≥ 3 用 `subagent-driven-development`,≤ 2 用 `executing-plans`;默认 `tdd_mode: tdd`。
17
+ 6. 自动创建工作区隔离(branch 或 worktree),然后进入执行阶段。
18
+
19
+ ## Workflows
20
+
21
+ 开始前先定位 xwang 脚本:
22
+
23
+ ```bash
24
+ XWANG_ENV="${XWANG_ENV:-$(find . "$HOME"/.*/skills "$HOME/.config" -path '*/xwang/scripts/xwang-env.sh' -type f -print -quit 2>/dev/null)}"
25
+ if [ -z "$XWANG_ENV" ]; then
26
+ echo "ERROR: xwang-env.sh not found. Ensure the xwang skill is installed." >&2
27
+ return 1
28
+ fi
29
+ . "$XWANG_ENV"
30
+ ```
31
+
32
+
33
+ - [ ] 确认用户要启动 xwang 阶段3(关键词:xwang-build、xwang 阶段3、开始构建、制定计划)。
34
+ - [ ] 获取 `<name>`:用户未提供时,读取 `openspec/changes/` 目录,按修改时间选择最新的 change。
35
+ - [ ] 验证 `openspec/changes/<name>/` 与 `docs/mattpocock/<name>-prd.md` 存在;缺失时提示用户先运行 `/xwang-design`。
36
+ - [ ] 读取以下文档作为 plan 输入:
37
+ - `docs/mattpocock/<name>-prd.md`
38
+ - `docs/mattpocock/<name>-prd.md`
39
+ - `docs/mattpocock/<name>-prd.md`
40
+ - `openspec/changes/<name>/proposal.md`
41
+ - `openspec/changes/<name>/design.md`
42
+ - `openspec/changes/<name>/tasks.md`
43
+ - `openspec/changes/<name>/specs/*/spec.md`
44
+
45
+ ### Step 2:制定计划(Subagent Offload)
46
+
47
+ 通过 subagent 创建实施计划,避免 planning skill 占用主 session 上下文。
48
+
49
+ - [ ] 记录当前提交作为 `base-ref`:`git rev-parse HEAD`。
50
+ - [ ] 派发 subagent,指令如下:
51
+ - 你是实施计划专家。基于以下输入创建实施计划,**全程必须使用中文输出**(包括计划条目、任务拆分、代码注释、矛盾分析、给用户的选择题和推荐理由)。不得输出英文。
52
+ - 立即使用 Skill 工具加载 Superpowers `writing-plans` 技能,ARGUMENTS 必须包含:`Language: 中文`。
53
+ - 读取 `docs/mattpocock/<name>-prd.md`(需求总览)。
54
+ - 读取 `openspec/changes/<name>/proposal.md`、`design.md`、`tasks.md`。
55
+ - 读取 `openspec/changes/<name>/specs/*/spec.md`(所有 capability 规格)。
56
+ - 按 `writing-plans` 技能指引创建计划,保存至 `docs/superpowers/plans/YYYY-MM-DD-<name>.md`。
57
+ - **计划文件头必须包含关联元数据**:
58
+ ```yaml
59
+ ---
60
+ change: <name>
61
+ design-doc: openspec/changes/<name>/design.md
62
+ base-ref: <git rev-parse HEAD>
63
+ ---
64
+ ```
65
+ - 如果计划中不同任务之间存在矛盾或不一致,必须停下来用中文向用户说明矛盾点、列出选项并给出推荐,等待用户明确选择后再继续。
66
+ - [ ] Subagent 完成后:
67
+ - 若返回有效文件路径且文件存在,记录为 plan。
68
+ - 若 subagent 失败或返回路径无效,在主 session 内联加载 `/writing-plans` 创建计划(降级回退)。
69
+
70
+ ### Step 3:plan-ready 检查点
71
+
72
+ - [ ] 计划写入后,向用户汇报计划路径与任务概览。
73
+ - [ ] 默认自动继续进入 Step 4 选择工作方式并执行。
74
+ - [ ] 若用户明确要求暂停,可记录 `plan-ready` 暂停状态;恢复时若 plan 文件存在,不重新运行 `writing-plans`,直接进入 Step 4。
75
+
76
+ ### Step 4:自动选择工作方式
77
+
78
+ 本步骤由 skill 根据 plan 自动选择工作方式,无需用户决策。
79
+
80
+ - [ ] 默认设置 `tdd_mode: tdd`。
81
+ - [ ] 读取已生成的 plan 文件,统计任务数量(例如统计 `### Task N:` 或任务勾选项数量)。
82
+ - [ ] 自动选择执行方式:
83
+ - 任务数 ≥ 3 → `build_mode: subagent-driven-development`
84
+ - 任务数 ≤ 2 → `build_mode: executing-plans`
85
+ - [ ] 若选择 `subagent-driven-development`,确认当前平台存在真实后台 subagent / Task / multi-agent 调度能力;若不存在,降级为 `executing-plans`。
86
+ - [ ] 自动选择工作区隔离方式:
87
+ - 默认 `isolation: branch`
88
+ - 若当前工作树存在未提交改动 → `isolation: worktree`
89
+ - [ ] 执行隔离:
90
+ - **branch**:按 `feature/YYYYMMDD/<name>` 格式创建分支,直接执行 `git checkout -b <branch>`。
91
+ - **worktree**:使用 Skill 工具加载 Superpowers `using-git-worktrees` 技能创建隔离工作区。若 plan 文件尚未提交,先提交计划再创建 worktree。
92
+ - [ ] 记录最终选择:isolation、build_mode、tdd_mode,并向用户简要说明自动选择理由。
93
+ - [ ] 进入执行阶段。详见 [REFERENCE.md#执行计划](REFERENCE.md#执行计划)。
94
+
95
+ ### Step 5:build 完成后进入 verify
96
+
97
+ build 阶段全部任务执行完毕且代码已提交后:
98
+
99
+ - [ ] 确认 `openspec/changes/<name>/tasks.md` 和 `docs/superpowers/plans/YYYY-MM-DD-<name>.md` 中所有任务已勾选。
100
+ - [ ] 确认 `plan`、`isolation`、`build_mode`、`tdd_mode` 已正确写入 `.xwang.yaml`。
101
+ - [ ] **默认选择保持分支不变(稍后处理),无需用户确认**:调用 `"$XWANG_STATE" set <name> branch_status handled`。
102
+ - [ ] 如果 plan 文件路径尚未写入 `.xwang.yaml`,调用 `"$XWANG_STATE" set <name> plan docs/superpowers/plans/YYYY-MM-DD-<name>.md`。
103
+ - [ ] **阶段出口守护(build → verify)**:调用 `"$XWANG_GUARD" <name> build --apply` 校验 build 阶段退出条件,通过后会自动将 `.xwang.yaml` 的 `phase` 推进到 `verify`。
104
+ - [ ] **自动进入 verify 阶段**:汇报完成后,直接调用 `/xwang-verify` 继续阶段4,无需等待用户确认。
105
+ - [ ] 向用户汇报最终状态文件路径、当前 phase 与分支处理状态。
106
+
107
+ ## Advanced features
108
+
109
+ - **指定 change 名称**:用户可直接提供 `<name>`,例如 `/xwang-build auth-flow`。
110
+ - **从 plan-ready 恢复**:用户再次调用 `/xwang-build` 时,若检测到未完成的 plan-ready 暂停,先确认 plan 文件存在,然后直接进入 Step 4。
111
+ - **跳过计划直接执行**:仅在用户明确要求且已记录显式 override 时允许,否则必须完成计划制定。
112
+ - **覆盖 TDD 模式**:默认 `tdd_mode: tdd`;用户明确要求 `direct` 模式时,可设置为 `direct`。
113
+ - **多 capability 聚合**:`specs/` 目录下通常包含多个 capability 的 spec,确保全部读取并体现在计划中。