@rpamis/comet 0.1.7 → 0.2.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 (67) hide show
  1. package/README.md +45 -13
  2. package/assets/manifest.json +2 -0
  3. package/assets/skills/comet/SKILL.md +214 -219
  4. package/assets/skills/comet/scripts/comet-archive.sh +8 -2
  5. package/assets/skills/comet/scripts/comet-guard.sh +32 -22
  6. package/assets/skills/comet/scripts/comet-state.sh +496 -0
  7. package/assets/skills/comet-archive/SKILL.md +6 -19
  8. package/assets/skills/comet-build/SKILL.md +16 -23
  9. package/assets/skills/comet-design/SKILL.md +7 -23
  10. package/assets/skills/comet-hotfix/SKILL.md +136 -167
  11. package/assets/skills/comet-open/SKILL.md +9 -31
  12. package/assets/skills/comet-tweak/SKILL.md +122 -154
  13. package/assets/skills/comet-verify/SKILL.md +11 -33
  14. package/assets/skills-zh/comet/SKILL.md +87 -92
  15. package/assets/skills-zh/comet-archive/SKILL.md +63 -76
  16. package/assets/skills-zh/comet-build/SKILL.md +153 -160
  17. package/assets/skills-zh/comet-design/SKILL.md +91 -107
  18. package/assets/skills-zh/comet-hotfix/SKILL.md +18 -49
  19. package/assets/skills-zh/comet-open/SKILL.md +70 -92
  20. package/assets/skills-zh/comet-tweak/SKILL.md +19 -51
  21. package/assets/skills-zh/comet-verify/SKILL.md +114 -136
  22. package/dist/cli/index.js +28 -1
  23. package/dist/cli/index.js.map +1 -1
  24. package/dist/commands/doctor.d.ts +6 -0
  25. package/dist/commands/doctor.d.ts.map +1 -0
  26. package/dist/commands/doctor.js +168 -0
  27. package/dist/commands/doctor.js.map +1 -0
  28. package/dist/commands/init.d.ts +9 -0
  29. package/dist/commands/init.d.ts.map +1 -0
  30. package/dist/commands/init.js +183 -0
  31. package/dist/commands/init.js.map +1 -0
  32. package/dist/commands/status.d.ts +6 -0
  33. package/dist/commands/status.d.ts.map +1 -0
  34. package/dist/commands/status.js +89 -0
  35. package/dist/commands/status.js.map +1 -0
  36. package/dist/commands/update.d.ts +8 -0
  37. package/dist/commands/update.d.ts.map +1 -0
  38. package/dist/commands/update.js +47 -0
  39. package/dist/commands/update.js.map +1 -0
  40. package/dist/core/detect.d.ts +8 -0
  41. package/dist/core/detect.d.ts.map +1 -0
  42. package/dist/core/detect.js +73 -0
  43. package/dist/core/detect.js.map +1 -0
  44. package/dist/core/openspec.d.ts +5 -0
  45. package/dist/core/openspec.d.ts.map +1 -0
  46. package/dist/core/openspec.js +58 -0
  47. package/dist/core/openspec.js.map +1 -0
  48. package/dist/core/platforms.d.ts.map +1 -1
  49. package/dist/core/platforms.js +6 -1
  50. package/dist/core/platforms.js.map +1 -1
  51. package/dist/core/skills.d.ts +22 -0
  52. package/dist/core/skills.d.ts.map +1 -0
  53. package/dist/core/skills.js +59 -0
  54. package/dist/core/skills.js.map +1 -0
  55. package/dist/core/superpowers.d.ts +5 -0
  56. package/dist/core/superpowers.d.ts.map +1 -0
  57. package/dist/core/superpowers.js +60 -0
  58. package/dist/core/superpowers.js.map +1 -0
  59. package/dist/core/types.d.ts +2 -0
  60. package/dist/core/types.d.ts.map +1 -0
  61. package/dist/core/types.js +2 -0
  62. package/dist/core/types.js.map +1 -0
  63. package/package.json +61 -50
  64. package/dist/core/init.d.ts +0 -14
  65. package/dist/core/init.d.ts.map +0 -1
  66. package/dist/core/init.js +0 -492
  67. package/dist/core/init.js.map +0 -1
@@ -182,30 +182,40 @@ guard_archive() {
182
182
  }
183
183
 
184
184
  apply_state_update() {
185
- local yaml="$CHANGE_DIR/.comet.yaml"
185
+ local state_sh="$SCRIPT_DIR/comet-state.sh"
186
186
  local p="$1"
187
187
 
188
- case "$p" in
189
- open)
190
- sed -i 's/^phase:.*/phase: design/' "$yaml"
191
- ;;
192
- design)
193
- sed -i 's/^phase:.*/phase: build/' "$yaml"
194
- ;;
195
- build)
196
- sed -i 's/^phase:.*/phase: verify/' "$yaml"
197
- sed -i 's/^verify_result:.*/verify_result: pending/' "$yaml"
198
- ;;
199
- verify)
200
- sed -i 's/^phase:.*/phase: archive/' "$yaml"
201
- sed -i 's/^verify_result:.*/verify_result: pass/' "$yaml"
202
- if ! grep -q '^verified_at:' "$yaml" 2>/dev/null; then
203
- echo "verified_at: $(date +%Y-%m-%d)" >> "$yaml"
204
- else
205
- sed -i "s/^verified_at:.*/verified_at: $(date +%Y-%m-%d)/" "$yaml"
206
- fi
207
- ;;
208
- esac
188
+ if [ -f "$state_sh" ]; then
189
+ case "$p" in
190
+ open) bash "$state_sh" set "$CHANGE" phase design ;;
191
+ design) bash "$state_sh" set "$CHANGE" phase build ;;
192
+ build)
193
+ bash "$state_sh" set "$CHANGE" phase verify
194
+ bash "$state_sh" set "$CHANGE" verify_result pending
195
+ ;;
196
+ verify)
197
+ bash "$state_sh" set "$CHANGE" phase archive
198
+ bash "$state_sh" set "$CHANGE" verify_result pass
199
+ bash "$state_sh" set "$CHANGE" verified_at "$(date +%Y-%m-%d)"
200
+ ;;
201
+ esac
202
+ else
203
+ local yaml="$CHANGE_DIR/.comet.yaml"
204
+ case "$p" in
205
+ open) sed -i 's/^phase:.*/phase: design/' "$yaml" ;;
206
+ design) sed -i 's/^phase:.*/phase: build/' "$yaml" ;;
207
+ build) sed -i 's/^phase:.*/phase: verify/' "$yaml"; sed -i 's/^verify_result:.*/verify_result: pending/' "$yaml" ;;
208
+ verify)
209
+ sed -i 's/^phase:.*/phase: archive/' "$yaml"
210
+ sed -i 's/^verify_result:.*/verify_result: pass/' "$yaml"
211
+ if ! grep -q '^verified_at:' "$yaml" 2>/dev/null; then
212
+ echo "verified_at: $(date +%Y-%m-%d)" >> "$yaml"
213
+ else
214
+ sed -i "s/^verified_at:.*/verified_at: $(date +%Y-%m-%d)/" "$yaml"
215
+ fi
216
+ ;;
217
+ esac
218
+ fi
209
219
  }
210
220
 
211
221
  # --- Main ---
@@ -0,0 +1,496 @@
1
+ #!/bin/bash
2
+ # Comet State — unified interface for .comet.yaml state management
3
+ # Usage: comet-state.sh <subcommand> <change-name> [args...]
4
+ #
5
+ # Subcommands:
6
+ # init <change-name> <workflow> — Initialize .comet.yaml with workflow defaults
7
+ # get <change-name> <field> — Read a field value from .comet.yaml
8
+ # set <change-name> <field> <val> — Update a field value
9
+ # check <phase> <change-name> — Verify entry requirements for a phase
10
+ # scale <change-name> — Assess and set verification mode based on metrics
11
+ #
12
+ # Workflows: full, hotfix, tweak
13
+ # Phases for check: open, design, build, verify, archive
14
+
15
+ set -euo pipefail
16
+
17
+ # --- Color output helpers ---
18
+
19
+ red() { echo -e "\033[31m$1\033[0m" >&2; }
20
+ green() { echo -e "\033[32m$1\033[0m" >&2; }
21
+ yellow() { echo -e "\033[33m$1\033[0m" >&2; }
22
+
23
+ # --- Script location ---
24
+
25
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
26
+
27
+ # --- Input validation ---
28
+
29
+ validate_change_name() {
30
+ local name="$1"
31
+ # Reject empty names
32
+ if [ -z "$name" ]; then
33
+ red "ERROR: Change name cannot be empty" >&2
34
+ exit 1
35
+ fi
36
+ # Only allow alphanumeric, hyphens, and underscores
37
+ if [[ ! "$name" =~ ^[a-zA-Z0-9_-]+$ ]]; then
38
+ red "ERROR: Invalid change name: '$name'" >&2
39
+ red "Valid characters: a-z, A-Z, 0-9, -, _" >&2
40
+ exit 1
41
+ fi
42
+ # Reject path traversal attempts
43
+ if [[ "$name" =~ \.\. ]]; then
44
+ red "ERROR: Change name cannot contain '..' (path traversal not allowed)" >&2
45
+ exit 1
46
+ fi
47
+ }
48
+
49
+ validate_enum() {
50
+ local value="$1"
51
+ shift
52
+ local valid_values=("$@")
53
+
54
+ for valid in "${valid_values[@]}"; do
55
+ if [ "$value" = "$valid" ]; then
56
+ return 0
57
+ fi
58
+ done
59
+
60
+ red "ERROR: Invalid value: '$value'" >&2
61
+ red "Valid values: ${valid_values[*]}" >&2
62
+ exit 1
63
+ }
64
+
65
+ # --- Helper functions ---
66
+
67
+ yaml_field() {
68
+ local field="$1"
69
+ local yaml_file="$2"
70
+ if [ -f "$yaml_file" ]; then
71
+ grep "^${field}:" "$yaml_file" | sed "s/^${field}: *//" | tr -d '"' | tr -d "'"
72
+ fi
73
+ }
74
+
75
+ file_nonempty() {
76
+ [ -f "$1" ] && [ -s "$1" ]
77
+ }
78
+
79
+ # --- Subcommands ---
80
+
81
+ cmd_init() {
82
+ local change_name="$1"
83
+ local workflow="$2"
84
+
85
+ validate_change_name "$change_name"
86
+ validate_enum "$workflow" "full" "hotfix" "tweak"
87
+
88
+ local change_dir="openspec/changes/$change_name"
89
+ local yaml_file="$change_dir/.comet.yaml"
90
+
91
+ # Check if .comet.yaml already exists
92
+ if [ -f "$yaml_file" ]; then
93
+ red "ERROR: .comet.yaml already exists at $yaml_file"
94
+ exit 1
95
+ fi
96
+
97
+ # Create change directory if it doesn't exist
98
+ mkdir -p "$change_dir"
99
+
100
+ # Set workflow-appropriate defaults
101
+ local phase build_mode isolation verify_mode
102
+
103
+ case "$workflow" in
104
+ full)
105
+ phase="design"
106
+ build_mode="null"
107
+ isolation="null"
108
+ verify_mode="null"
109
+ ;;
110
+ hotfix|tweak)
111
+ phase="build"
112
+ build_mode="direct"
113
+ isolation="branch"
114
+ verify_mode="light"
115
+ ;;
116
+ esac
117
+
118
+ # Write .comet.yaml
119
+ cat > "$yaml_file" <<EOF
120
+ workflow: $workflow
121
+ phase: $phase
122
+ build_mode: $build_mode
123
+ isolation: $isolation
124
+ verify_mode: $verify_mode
125
+ design_doc: null
126
+ plan: null
127
+ verify_result: pending
128
+ verified_at: null
129
+ archived: false
130
+ EOF
131
+
132
+ green "Initialized: $yaml_file (workflow=$workflow)"
133
+ }
134
+
135
+ cmd_get() {
136
+ local change_name="$1"
137
+ local field="$2"
138
+
139
+ validate_change_name "$change_name"
140
+
141
+ local change_dir="openspec/changes/$change_name"
142
+ local yaml_file="$change_dir/.comet.yaml"
143
+
144
+ # Check if .comet.yaml exists
145
+ if [ ! -f "$yaml_file" ]; then
146
+ red "ERROR: .comet.yaml not found at $yaml_file"
147
+ exit 1
148
+ fi
149
+
150
+ # Read and output the field value
151
+ local value
152
+ value=$(yaml_field "$field" "$yaml_file")
153
+ echo "${value:-}"
154
+ }
155
+
156
+ cmd_set() {
157
+ local change_name="$1"
158
+ local field="$2"
159
+ local value="$3"
160
+
161
+ validate_change_name "$change_name"
162
+
163
+ local change_dir="openspec/changes/$change_name"
164
+ local yaml_file="$change_dir/.comet.yaml"
165
+
166
+ # Check if .comet.yaml exists
167
+ if [ ! -f "$yaml_file" ]; then
168
+ red "ERROR: .comet.yaml not found at $yaml_file"
169
+ exit 1
170
+ fi
171
+
172
+ # Validate field name
173
+ case "$field" in
174
+ workflow|phase|build_mode|isolation|verify_mode|verify_result|archived|design_doc|plan|verified_at)
175
+ # Valid field
176
+ ;;
177
+ *)
178
+ red "ERROR: Unknown field: '$field'" >&2
179
+ red "Valid fields: workflow, phase, design_doc, plan, build_mode, isolation, verify_mode, verify_result, verified_at, archived" >&2
180
+ exit 1
181
+ ;;
182
+ esac
183
+
184
+ # Validate enum values
185
+ case "$field" in
186
+ workflow)
187
+ validate_enum "$value" "full" "hotfix" "tweak"
188
+ ;;
189
+ phase)
190
+ validate_enum "$value" "design" "build" "verify" "archive"
191
+ ;;
192
+ build_mode)
193
+ validate_enum "$value" "subagent-driven-development" "executing-plans" "direct"
194
+ ;;
195
+ isolation)
196
+ validate_enum "$value" "branch" "worktree"
197
+ ;;
198
+ verify_mode)
199
+ validate_enum "$value" "light" "full"
200
+ ;;
201
+ verify_result)
202
+ validate_enum "$value" "pending" "pass" "fail"
203
+ ;;
204
+ archived)
205
+ validate_enum "$value" "true" "false"
206
+ ;;
207
+ design_doc|plan|verified_at)
208
+ # No validation for path fields and date fields
209
+ ;;
210
+ esac
211
+
212
+ # Write or update the field
213
+ if grep -q "^${field}:" "$yaml_file"; then
214
+ # Field exists, replace it
215
+ sed -i "s/^${field}:.*/${field}: ${value}/" "$yaml_file"
216
+ else
217
+ # Field doesn't exist, append it
218
+ echo "${field}: ${value}" >> "$yaml_file"
219
+ fi
220
+
221
+ green "[SET] ${field}=${value}"
222
+ }
223
+
224
+ # --- Check helpers for entry verification ---
225
+
226
+ CHECK_BLOCK=0
227
+
228
+ check_pass() {
229
+ local msg="$1"
230
+ echo " $(green "[PASS]") $msg"
231
+ }
232
+
233
+ check_fail() {
234
+ local msg="$1"
235
+ echo " $(red "[FAIL]") $msg"
236
+ CHECK_BLOCK=1
237
+ }
238
+
239
+ check_nonempty() {
240
+ local desc="$1"
241
+ local path="$1"
242
+ if file_nonempty "$path"; then
243
+ check_pass "$desc non-empty"
244
+ else
245
+ check_fail "$desc missing or empty"
246
+ fi
247
+ }
248
+
249
+ check_yaml_is() {
250
+ local field="$1"
251
+ local expected="$2"
252
+ local change_name="$3"
253
+ local actual
254
+ actual=$(cmd_get "$change_name" "$field")
255
+ if [ "$actual" = "$expected" ]; then
256
+ check_pass "${field}=${actual} (expected: ${expected})"
257
+ else
258
+ check_fail "${field}=${actual} (expected: ${expected})"
259
+ fi
260
+ }
261
+
262
+ check_yaml_empty() {
263
+ local field="$1"
264
+ local change_name="$2"
265
+ local value
266
+ value=$(cmd_get "$change_name" "$field")
267
+ if [ -z "$value" ] || [ "$value" = "null" ]; then
268
+ check_pass "${field} is empty/null"
269
+ else
270
+ check_fail "${field}=${value} (expected: empty/null)"
271
+ fi
272
+ }
273
+
274
+ check_file_not_exists() {
275
+ local desc="$1"
276
+ local path="$2"
277
+ if [ ! -f "$path" ]; then
278
+ check_pass "$desc does not exist"
279
+ else
280
+ check_fail "$desc exists (should not exist)"
281
+ fi
282
+ }
283
+
284
+ cmd_check() {
285
+ local phase="$1"
286
+ local change_name="$2"
287
+
288
+ validate_change_name "$change_name"
289
+ validate_enum "$phase" "open" "design" "build" "verify" "archive"
290
+
291
+ local change_dir="openspec/changes/$change_name"
292
+ local yaml_file="$change_dir/.comet.yaml"
293
+ local proposal_file="$change_dir/proposal.md"
294
+ local design_file="$change_dir/design.md"
295
+ local tasks_file="$change_dir/tasks.md"
296
+
297
+ echo "=== Entry Check: comet-${phase} ==="
298
+
299
+ # For non-open phases, .comet.yaml must exist
300
+ if [ "$phase" != "open" ]; then
301
+ if [ ! -f "$yaml_file" ]; then
302
+ red "ERROR: .comet.yaml not found at $yaml_file"
303
+ exit 1
304
+ fi
305
+ fi
306
+
307
+ # Phase-specific checks
308
+ case "$phase" in
309
+ open)
310
+ check_file_not_exists ".comet.yaml" "$yaml_file"
311
+ check_nonempty "proposal.md" "$proposal_file"
312
+ check_nonempty "design.md" "$design_file"
313
+ check_nonempty "tasks.md" "$tasks_file"
314
+ ;;
315
+ design)
316
+ check_pass ".comet.yaml exists"
317
+ check_yaml_is "phase" "design" "$change_name"
318
+ check_yaml_is "workflow" "full" "$change_name"
319
+ check_yaml_empty "design_doc" "$change_name"
320
+ check_nonempty "proposal.md" "$proposal_file"
321
+ check_nonempty "design.md" "$design_file"
322
+ check_nonempty "tasks.md" "$tasks_file"
323
+ ;;
324
+ build)
325
+ check_pass ".comet.yaml exists"
326
+ check_yaml_is "phase" "build" "$change_name"
327
+ # Check design_doc is non-null and file exists
328
+ local design_doc
329
+ design_doc=$(cmd_get "$change_name" "design_doc")
330
+ if [ -n "$design_doc" ] && [ "$design_doc" != "null" ] && [ -f "$change_dir/$design_doc" ]; then
331
+ check_pass "design_doc=${design_doc} (file exists)"
332
+ else
333
+ check_fail "design_doc=${design_doc} (expected: non-null and file exists)"
334
+ fi
335
+ check_nonempty "proposal.md" "$proposal_file"
336
+ check_nonempty "tasks.md" "$tasks_file"
337
+ ;;
338
+ verify)
339
+ check_pass ".comet.yaml exists"
340
+ check_yaml_is "phase" "verify" "$change_name"
341
+ # Check verify_result is pending or null
342
+ local verify_result
343
+ verify_result=$(cmd_get "$change_name" "verify_result")
344
+ if [ "$verify_result" = "pending" ] || [ -z "$verify_result" ] || [ "$verify_result" = "null" ]; then
345
+ check_pass "verify_result=${verify_result} (expected: pending or null)"
346
+ else
347
+ check_fail "verify_result=${verify_result} (expected: pending or null)"
348
+ fi
349
+ ;;
350
+ archive)
351
+ check_pass ".comet.yaml exists"
352
+ check_yaml_is "phase" "archive" "$change_name"
353
+ check_yaml_is "verify_result" "pass" "$change_name"
354
+ # Check archived is NOT true
355
+ local archived
356
+ archived=$(cmd_get "$change_name" "archived")
357
+ if [ "$archived" != "true" ]; then
358
+ check_pass "archived=${archived} (expected: not true)"
359
+ else
360
+ check_fail "archived=${archived} (expected: not true)"
361
+ fi
362
+ ;;
363
+ *)
364
+ red "ERROR: Unknown phase for check: $phase"
365
+ exit 1
366
+ ;;
367
+ esac
368
+
369
+ echo ""
370
+ if [ "$CHECK_BLOCK" -eq 1 ]; then
371
+ red "BLOCKED — fix failing checks before proceeding"
372
+ exit 1
373
+ else
374
+ green "ALL CHECKS PASSED — ready to proceed"
375
+ exit 0
376
+ fi
377
+ }
378
+
379
+ cmd_scale() {
380
+ local change_name="$1"
381
+
382
+ validate_change_name "$change_name"
383
+
384
+ local change_dir="openspec/changes/$change_name"
385
+ local yaml_file="$change_dir/.comet.yaml"
386
+
387
+ # Verify .comet.yaml exists
388
+ if [ ! -f "$yaml_file" ]; then
389
+ red "ERROR: .comet.yaml not found at $yaml_file"
390
+ exit 1
391
+ fi
392
+
393
+ # Read metrics
394
+ # 1. Task count: count lines matching `- [` in tasks.md
395
+ local tasks_file="$change_dir/tasks.md"
396
+ local task_count=0
397
+ if [ -f "$tasks_file" ]; then
398
+ task_count=$(grep -c '^\- \[' "$tasks_file" 2>/dev/null || echo "0")
399
+ fi
400
+
401
+ # 2. Delta spec count: count files named spec.md under specs/*/spec.md
402
+ local delta_spec_count=0
403
+ if [ -d "$change_dir/specs" ]; then
404
+ delta_spec_count=$(find "$change_dir/specs" -name "spec.md" -type f 2>/dev/null | wc -l | tr -d ' ')
405
+ fi
406
+
407
+ # 3. Changed files: from git diff --stat HEAD
408
+ local changed_files=0
409
+ if git rev-parse --git-dir > /dev/null 2>&1; then
410
+ # Extract the number before "file" in the last line
411
+ local stat_output
412
+ stat_output=$(git diff --stat HEAD 2>/dev/null | tail -1)
413
+ if [[ "$stat_output" =~ ([0-9]+)\ file ]]; then
414
+ changed_files="${BASH_REMATCH[1]}"
415
+ fi
416
+ fi
417
+
418
+ # Decision rules
419
+ local result="light"
420
+ if [ "$task_count" -gt 3 ] || [ "$delta_spec_count" -gt 1 ] || [ "$changed_files" -gt 5 ]; then
421
+ result="full"
422
+ fi
423
+
424
+ # Output assessment to stderr
425
+ echo "=== Scale Assessment: $change_name ===" >&2
426
+ echo " Tasks: $task_count (threshold: 3)" >&2
427
+ echo " Delta specs: $delta_spec_count capabilities (threshold: 1)" >&2
428
+ echo " Changed files: $changed_files (threshold: 5)" >&2
429
+ echo " → Result: $result" >&2
430
+
431
+ # Update verify_mode in .comet.yaml
432
+ sed -i "s/^verify_mode:.*/verify_mode: $result/" "$yaml_file"
433
+
434
+ green "[SCALE] verify_mode=$result"
435
+ }
436
+
437
+ # --- Main ---
438
+
439
+ SUBCOMMAND="${1:-}"
440
+ shift || true
441
+
442
+ case "$SUBCOMMAND" in
443
+ init)
444
+ if [ $# -lt 2 ]; then
445
+ red "Usage: comet-state.sh init <change-name> <workflow>" >&2
446
+ red "Workflows: full, hotfix, tweak" >&2
447
+ exit 1
448
+ fi
449
+ cmd_init "$@"
450
+ ;;
451
+ get)
452
+ if [ $# -lt 2 ]; then
453
+ red "Usage: comet-state.sh get <change-name> <field>" >&2
454
+ exit 1
455
+ fi
456
+ cmd_get "$@"
457
+ ;;
458
+ set)
459
+ if [ $# -lt 3 ]; then
460
+ red "Usage: comet-state.sh set <change-name> <field> <value>" >&2
461
+ exit 1
462
+ fi
463
+ cmd_set "$@"
464
+ ;;
465
+ check)
466
+ if [ $# -lt 2 ]; then
467
+ red "Usage: comet-state.sh check <phase> <change-name>" >&2
468
+ red "Phases: open, design, build, verify, archive" >&2
469
+ exit 1
470
+ fi
471
+ cmd_check "$@"
472
+ ;;
473
+ scale)
474
+ if [ $# -lt 1 ]; then
475
+ red "Usage: comet-state.sh scale <change-name>" >&2
476
+ exit 1
477
+ fi
478
+ cmd_scale "$@"
479
+ ;;
480
+ *)
481
+ red "Unknown subcommand: $SUBCOMMAND" >&2
482
+ echo "" >&2
483
+ echo "Usage: comet-state.sh <subcommand> <change-name> [args...]" >&2
484
+ echo "" >&2
485
+ echo "Subcommands:" >&2
486
+ echo " init <change-name> <workflow> — Initialize .comet.yaml with workflow defaults" >&2
487
+ echo " get <change-name> <field> — Read a field value from .comet.yaml" >&2
488
+ echo " set <change-name> <field> <val> — Update a field value in .comet.yaml" >&2
489
+ echo " check <phase> <change-name> — Verify entry requirements for a phase" >&2
490
+ echo " scale <change-name> — Assess and set verification mode based on metrics" >&2
491
+ echo "" >&2
492
+ echo "Workflows: full, hotfix, tweak" >&2
493
+ echo "Phases for check: open, design, build, verify, archive" >&2
494
+ exit 1
495
+ ;;
496
+ esac
@@ -15,34 +15,21 @@ description: "Comet Phase 5: Archive. Invoke with /comet-archive. Sync delta spe
15
15
 
16
16
  ### 0. Entry State Verification (Entry Check)
17
17
 
18
- Before performing any operations, read and verify the current state:
18
+ Execute entry verification:
19
19
 
20
- **Checklist:**
21
- 1. `openspec/changes/<name>/.comet.yaml` exists
22
- 2. `phase` field value is `"archive"`
23
- 3. `verify_result` field value is `"pass"`
24
- 4. `archived` field is `"false"` or null (not yet archived)
25
-
26
- **Verification method:**
27
- - `cat openspec/changes/<name>/.comet.yaml` to read all fields
28
- - If `verify_result` is not `"pass"`, must complete verification first
29
-
30
- **Failure output:**
31
- ```
32
- [HARD STOP] Entry check failed for comet-archive
33
- Expected: phase=archive, verify_result=pass, archived=false|null
34
- Actual: phase=<actual-value>, verify_result=<actual-value>, archived=<actual-value>
35
- Suggestion: Run comet-verify first, or this change was already archived.
20
+ ```bash
21
+ COMET_STATE="${COMET_STATE:-$(find . -path '*/comet/scripts/comet-state.sh' -type f -print -quit)}"
22
+ bash "$COMET_STATE" check <name> archive
36
23
  ```
37
24
 
38
- Proceed to Step 1 only after verification passes.
25
+ Proceed to Step 1 after verification passes. The script outputs specific failure reasons when verification fails.
39
26
 
40
27
  ### 1. Execute Archive
41
28
 
42
29
  Run the archive script to automatically complete all steps:
43
30
 
44
31
  ```bash
45
- COMET_ARCHIVE=$(find . -path '*/comet/scripts/comet-archive.sh' -type f -print -quit)
32
+ COMET_ARCHIVE="${COMET_ARCHIVE:-$(find . -path '*/comet/scripts/comet-archive.sh' -type f -print -quit)}"
46
33
  bash "$COMET_ARCHIVE" "<change-name>"
47
34
  ```
48
35
 
@@ -14,29 +14,14 @@ description: "Comet Phase 3: Plan and Build. Invoke with /comet-build. Create pl
14
14
 
15
15
  ### 0. Entry State Verification (Entry Check)
16
16
 
17
- Before performing any operations, read and verify the current state:
17
+ Execute entry verification:
18
18
 
19
- **Checklist:**
20
- 1. `openspec/changes/<name>/.comet.yaml` exists
21
- 2. `phase` field value is `"build"`
22
- 3. `design_doc` field is non-null and non-empty
23
- 4. File referenced by `design_doc` exists (e.g., `docs/superpowers/specs/YYYY-MM-DD-topic-design.md`)
24
- 5. `openspec/changes/<name>/proposal.md` exists and is non-empty
25
- 6. `openspec/changes/<name>/tasks.md` exists and is non-empty
26
-
27
- **Verification method:**
28
- - `cat openspec/changes/<name>/.comet.yaml` to read all fields
29
- - Use `ls` or `test -f` to confirm design_doc file exists
30
-
31
- **Failure output:**
32
- ```
33
- [HARD STOP] Entry check failed for comet-build
34
- Expected: phase=build, design_doc=<path> exists
35
- Actual: phase=<actual-value>, design_doc=<actual-value or file does not exist>
36
- Suggestion: Run comet-design first, or verify design_doc file exists.
19
+ ```bash
20
+ COMET_STATE="${COMET_STATE:-$(find . -path '*/comet/scripts/comet-state.sh' -type f -print -quit)}"
21
+ bash "$COMET_STATE" check <name> build
37
22
  ```
38
23
 
39
- Proceed to Step 1 only after verification passes.
24
+ Proceed to Step 1 after verification passes. The script outputs specific failure reasons when verification fails.
40
25
 
41
26
  ### 1. Create Plan
42
27
 
@@ -59,7 +44,7 @@ design-doc: docs/superpowers/specs/YYYY-MM-DD-<topic>-design.md
59
44
  Record plan path:
60
45
 
61
46
  ```bash
62
- sed -i 's|^plan:.*|plan: docs/superpowers/plans/YYYY-MM-DD-feature.md|' openspec/changes/<name>/.comet.yaml
47
+ bash "$COMET_STATE" set <name> plan docs/superpowers/plans/YYYY-MM-DD-feature.md
63
48
  ```
64
49
 
65
50
  No manual phase update needed — guard auto-transitions when exit conditions are met.
@@ -77,7 +62,11 @@ Plan has been written to the current branch. Before starting execution, choose w
77
62
  - Change involves ≤ 3 files → Recommend A
78
63
  - Need parallel development, current branch has uncommitted work → Recommend B
79
64
 
80
- After user selection, update `isolation` in `openspec/changes/<name>/.comet.yaml`. `isolation` only allows one of the following values:
65
+ After user selection, update `isolation` field. `isolation` only allows one of the following values:
66
+
67
+ ```bash
68
+ bash "$COMET_STATE" set <name> isolation <value>
69
+ ```
81
70
 
82
71
  - `branch`
83
72
  - `worktree`
@@ -103,7 +92,11 @@ Present plan summary to user (task count, involved modules), then ask for execut
103
92
  - Task count ≤ 2 and no cross-module dependencies → Recommend B
104
93
  - From hotfix path → Recommend B
105
94
 
106
- After user selection, update `build_mode` in `openspec/changes/<name>/.comet.yaml`. `build_mode` only allows one of the following values:
95
+ After user selection, update `build_mode` field. `build_mode` only allows one of the following values:
96
+
97
+ ```bash
98
+ bash "$COMET_STATE" set <name> build_mode <value>
99
+ ```
107
100
 
108
101
  - `subagent-driven-development`
109
102
  - `executing-plans`