@rpamis/comet 0.3.5 → 0.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.md +180 -56
- package/assets/manifest.json +11 -1
- package/assets/skills/comet/SKILL.md +59 -24
- package/assets/skills/comet/reference/dirty-worktree.md +1 -0
- package/assets/skills/comet/rules/comet-phase-guard.md +90 -0
- package/assets/skills/comet/scripts/comet-archive.sh +75 -57
- package/assets/skills/comet/scripts/comet-env.sh +57 -2
- package/assets/skills/comet/scripts/comet-guard.sh +187 -29
- package/assets/skills/comet/scripts/comet-handoff.sh +137 -8
- package/assets/skills/comet/scripts/comet-hook-guard.sh +260 -0
- package/assets/skills/comet/scripts/comet-state.sh +312 -25
- package/assets/skills/comet/scripts/comet-yaml-validate.sh +26 -1
- package/assets/skills/comet-archive/SKILL.md +45 -12
- package/assets/skills/comet-build/SKILL.md +159 -33
- package/assets/skills/comet-design/SKILL.md +129 -23
- package/assets/skills/comet-hotfix/SKILL.md +57 -15
- package/assets/skills/comet-open/SKILL.md +90 -17
- package/assets/skills/comet-tweak/SKILL.md +40 -15
- package/assets/skills/comet-verify/SKILL.md +64 -25
- package/assets/skills-zh/comet/SKILL.md +63 -25
- package/assets/skills-zh/comet/reference/dirty-worktree.md +2 -1
- package/assets/skills-zh/comet-archive/SKILL.md +46 -13
- package/assets/skills-zh/comet-build/SKILL.md +161 -35
- package/assets/skills-zh/comet-design/SKILL.md +132 -25
- package/assets/skills-zh/comet-hotfix/SKILL.md +53 -15
- package/assets/skills-zh/comet-open/SKILL.md +90 -17
- package/assets/skills-zh/comet-tweak/SKILL.md +36 -15
- package/assets/skills-zh/comet-verify/SKILL.md +64 -27
- package/bin/comet.js +3 -3
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +22 -0
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/init.d.ts +5 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +64 -9
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +60 -1
- package/dist/commands/update.js.map +1 -1
- package/dist/core/codegraph.d.ts +9 -0
- package/dist/core/codegraph.d.ts.map +1 -0
- package/dist/core/codegraph.js +96 -0
- package/dist/core/codegraph.js.map +1 -0
- package/dist/core/platforms.d.ts +10 -0
- package/dist/core/platforms.d.ts.map +1 -1
- package/dist/core/platforms.js +163 -15
- package/dist/core/platforms.js.map +1 -1
- package/dist/core/skills.d.ts +34 -1
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js +360 -1
- package/dist/core/skills.js.map +1 -1
- package/package.json +3 -1
- package/scripts/postinstall.js +44 -44
|
@@ -20,6 +20,10 @@ Superpowers handles HOW — technical design, planning, execution, closing
|
|
|
20
20
|
|
|
21
21
|
Agents need only read this section for decision-making. Refer to the Reference Appendix as needed.
|
|
22
22
|
|
|
23
|
+
### Output Language Rule
|
|
24
|
+
|
|
25
|
+
Use the language of the user request that triggered this workflow as the default output language. When resuming an existing change with a clear dominant artifact language, preserve that language unless the user explicitly asks to switch.
|
|
26
|
+
|
|
23
27
|
### Automatic Phase Detection
|
|
24
28
|
|
|
25
29
|
**Step 0: Active Change Discovery and Intent Detection**
|
|
@@ -53,15 +57,22 @@ Prefer reading `openspec/changes/<name>/.comet.yaml`. If not available, fall bac
|
|
|
53
57
|
**Resume rules**:
|
|
54
58
|
- On every context resume, rerun Step 0 and Step 1; do not trust conversation history for phase detection
|
|
55
59
|
- If there is an active change and the worktree has uncommitted changes, handle them through `comet/reference/dirty-worktree.md`. That protocol defines checks, attribution, and prohibitions; this file does not repeat them
|
|
56
|
-
- If `phase: build`, first check
|
|
57
|
-
- If `
|
|
58
|
-
- If `
|
|
59
|
-
- If `
|
|
60
|
+
- If `phase: build`, first check `build_pause`, `plan`, `build_mode`, and `isolation` (see details below):
|
|
61
|
+
- If `build_pause: plan-ready` but `isolation` and `build_mode` are already set, treat as stale pause: first output `[COMET] Detected stale pause (build_pause=plan-ready but isolation/build_mode already set), auto-clearing and continuing`, then run `"$COMET_BASH" "$COMET_STATE" set <name> build_pause null`, then read the next unchecked task from tasks.md and resume execution per `build_mode`
|
|
62
|
+
- If `build_pause: plan-ready` and the plan file exists, but `isolation` or `build_mode` is not yet set, return to the `/comet-build` plan-ready resume point, prompt the user to choose isolation and execution method, and do not regenerate the plan
|
|
63
|
+
- If `build_pause: plan-ready` but the plan file is missing, return to `/comet-build` to handle corrupted state or regenerate the plan
|
|
64
|
+
- If `build_mode`, `isolation`, or `tdd_mode` is unset, return to the corresponding `/comet-build` step to supplement before executing
|
|
65
|
+
- If all are set, read the next unchecked task from tasks.md and continue:
|
|
66
|
+
- If `build_mode: subagent-driven-development`, do not execute tasks directly in the main window; return to `/comet-build`'s background subagent dispatch rules, main window only coordinates
|
|
67
|
+
- Other execution modes follow `/comet-build`'s corresponding rules
|
|
68
|
+
- If `phase: verify` and `verify_result: fail`, enter the verification failure decision blocking point: pause and ask the user to fix or accept deviation; only after the user chooses fix, run `"$COMET_BASH" "$COMET_STATE" transition <name> verify-fail` and invoke `/comet-build`
|
|
69
|
+
- If `phase: open` but proposal/design/tasks are complete, first run `"$COMET_BASH" "$COMET_GUARD" <change-name> open --apply` to repair state, then continue detection
|
|
70
|
+
- If `phase: archive`, only invoke `/comet-archive`; `/comet-archive` must first wait for final archive confirmation. After archive succeeds, the change moves to the archive directory, so do not run guard against the old active directory
|
|
60
71
|
|
|
61
72
|
**Step 2: Phase Determination** (check in order, first match wins)
|
|
62
73
|
|
|
63
74
|
1. `archived: true` or change moved to archive → Workflow complete
|
|
64
|
-
2. `verify_result: pass` and `archived` is not `true` → Invoke `/comet-archive`
|
|
75
|
+
2. `verify_result: pass` and `archived` is not `true` → Invoke `/comet-archive` (first perform final archive confirmation)
|
|
65
76
|
3. `verify_result: fail` → Enter verification failure decision blocking point (pause and ask fix or accept deviation; only after user chooses fix, run `verify-fail` then `/comet-build`)
|
|
66
77
|
4. `phase: verify` or tasks.md all checked → Invoke `/comet-verify`
|
|
67
78
|
5. `phase: build` or has Design Doc but plan/execution incomplete → Route by workflow: `hotfix` → `/comet-hotfix`, `tweak` → `/comet-tweak`, `full` → `/comet-build`
|
|
@@ -85,6 +96,8 @@ If metadata conflicts with file state, use verifiable file state as source of tr
|
|
|
85
96
|
- Cross-module coordination required
|
|
86
97
|
- **5+** new test cases needed
|
|
87
98
|
- Config item additions or deletions (not value changes)
|
|
99
|
+
- New capability needed
|
|
100
|
+
- Delta spec needed (existing spec affected)
|
|
88
101
|
|
|
89
102
|
### Error Handling Quick Reference
|
|
90
103
|
|
|
@@ -92,7 +105,7 @@ If metadata conflicts with file state, use verifiable file state as source of tr
|
|
|
92
105
|
|----------|----------|
|
|
93
106
|
| `openspec list --json` fails | Check if openspec is installed, prompt user to run `openspec init` |
|
|
94
107
|
| Sub-skill unavailable | Stop workflow, prompt to install or enable the corresponding skill |
|
|
95
|
-
| `.comet.yaml` malformed or missing | Use file state as source of truth, correct with `
|
|
108
|
+
| `.comet.yaml` malformed or missing | Use file state as source of truth, correct with `"$COMET_BASH" "$COMET_STATE" set` then continue |
|
|
96
109
|
| Build/test fails | Return to build phase for fixes, do not enter verify |
|
|
97
110
|
| Incomplete change directory structure | Fill missing files according to `comet-open` artifact requirements |
|
|
98
111
|
|
|
@@ -103,26 +116,30 @@ A single `/comet` invocation starts from the detected phase and advances to the
|
|
|
103
116
|
|
|
104
117
|
Flow chain: open → design → build → verify → archive
|
|
105
118
|
|
|
106
|
-
**Continuous execution requirement**: starting from the detected phase, the agent automatically continues through all later phases. But **auto-advancing only applies at transition points without user decisions**. When encountering user decision points, **must use the
|
|
119
|
+
**Continuous execution requirement**: starting from the detected phase, the agent automatically continues through all later phases. But **auto-advancing only applies at transition points without user decisions**. When encountering user decision points, **must use the current platform's available user input/confirmation mechanism to pause and wait for the user's explicit response**. Must not use recommendation rules, defaults, or historical preferences to substitute for user confirmation, and must not just output a text prompt and then continue executing.
|
|
107
120
|
|
|
108
|
-
**
|
|
121
|
+
**Distinguish phase advancement vs automatic handoff**: each sub-skill runs phase guard `--apply` before exit to advance the `.comet.yaml` `phase` field. This step **always happens** and is not controlled by `auto_transition`. After that, the sub-skill runs `"$COMET_BASH" "$COMET_STATE" next <name>` to resolve the next action: when `auto_transition` is not `false`, output is `NEXT: auto` (auto-invoke next skill); when `auto_transition` is `false`, output is `NEXT: manual` (do not invoke next skill, show a manual run hint). Therefore `auto_transition` **only controls next skill invocation, not phase advancement**. Regardless of `auto_transition`, user decision points below remain blocking.
|
|
122
|
+
|
|
123
|
+
**Decision points are blocking points**: whenever reaching any of the following nodes, the current `/comet` invocation must stop, **using the current platform's available user input/confirmation mechanism to wait for the user's choice**. If the current platform has no structured question tool, ask clear options in the conversation and stop the workflow, waiting for the user's reply before continuing. Only after the user explicitly chooses can the corresponding state fields be written and operations executed, then auto-advance resumes.
|
|
109
124
|
|
|
110
125
|
Nodes requiring user participation (pause only at these nodes):
|
|
111
126
|
1. Open phase proposal/design/tasks review and confirmation
|
|
112
127
|
2. Confirm design approach during brainstorming
|
|
113
|
-
3.
|
|
128
|
+
3. Plan-ready pause choice during build phase, followed by workflow configuration selection (isolation + execution method + TDD mode)
|
|
114
129
|
4. Decide to fix or accept deviation when verify fails (including Spec drift handling)
|
|
115
130
|
5. Choose branch handling method for finishing-branch
|
|
116
|
-
6.
|
|
117
|
-
7.
|
|
131
|
+
6. Archive phase final confirmation before running the archive script
|
|
132
|
+
7. Encounter upgrade conditions (hotfix/tweak → full workflow)
|
|
133
|
+
8. Build phase scope expansion requiring redesign or new change split
|
|
134
|
+
9. Open phase large PRD requiring confirmation to split into multiple changes
|
|
118
135
|
|
|
119
|
-
Agents should not skip these decision points; other unambiguous phase transitions must proceed automatically, must not exit midway. At decision points, **
|
|
136
|
+
Agents should not skip these decision points; other unambiguous phase transitions must proceed automatically, must not exit midway. At decision points, **must not skip user confirmation or choose automatically — must explicitly obtain the user's choice through the current platform's available user input/confirmation mechanism before continuing**.
|
|
120
137
|
|
|
121
138
|
**Red Flags** — when these thoughts appear, STOP and check:
|
|
122
139
|
|
|
123
140
|
| Agent Thought | Actual Risk |
|
|
124
141
|
|--------------|-------------|
|
|
125
|
-
| "The user would probably agree with this approach" | Cannot decide for the user — use
|
|
142
|
+
| "The user would probably agree with this approach" | Cannot decide for the user — use the current platform's user input/confirmation mechanism |
|
|
126
143
|
| "This is a small change, confirmation isn't needed" | Decision points have no size exception — blocking points must wait |
|
|
127
144
|
| "The user chose A last time, so A again" | Historical preference cannot substitute for current confirmation |
|
|
128
145
|
| "I explained the plan and the user didn't object" | No objection ≠ consent — must use tool to get explicit choice |
|
|
@@ -171,6 +188,9 @@ design_doc: docs/superpowers/specs/YYYY-MM-DD-topic-design.md
|
|
|
171
188
|
plan: docs/superpowers/plans/YYYY-MM-DD-feature.md
|
|
172
189
|
base_ref: a1b2c3d4e5f6...
|
|
173
190
|
build_mode: subagent-driven-development
|
|
191
|
+
build_pause: null
|
|
192
|
+
subagent_dispatch: confirmed
|
|
193
|
+
tdd_mode: tdd
|
|
174
194
|
isolation: branch
|
|
175
195
|
verify_mode: light
|
|
176
196
|
verify_result: pending
|
|
@@ -189,8 +209,12 @@ archived: false
|
|
|
189
209
|
| `plan` | Associated Superpowers Plan path, can be empty |
|
|
190
210
|
| `base_ref` | Git commit SHA recorded at init, used for scale assessment. Serves as fallback when no plan exists |
|
|
191
211
|
| `build_mode` | Selected execution method, can be empty |
|
|
212
|
+
| `build_pause` | Internal build-phase pause point. `null` means no pause; `plan-ready` means the plan has been generated and the user chose to pause for switching models |
|
|
213
|
+
| `subagent_dispatch` | `null` or `confirmed`. Only when the current platform has confirmed real background subagent / Task / multi-agent dispatch capability can `build_mode: subagent-driven-development` be written and used to leave the build phase |
|
|
214
|
+
| `tdd_mode` | `tdd` or `direct`. Must be selected before full workflow leaves build phase. `tdd` enforces writing a failing test first for each task; `direct` does not enforce TDD. hotfix/tweak default to `direct` |
|
|
192
215
|
| `isolation` | `branch` or `worktree`, workspace isolation method. Full workflow init may leave this as `null`, but only until `/comet-build` Step 3; hotfix/tweak default to `branch` |
|
|
193
216
|
| `verify_mode` | `light` or `full`, can be empty |
|
|
217
|
+
| `auto_transition` | `true` or `false`. `false` pauses only the next skill invocation; it does not block phase updates |
|
|
194
218
|
| `verify_result` | `pending`, `pass`, or `fail` |
|
|
195
219
|
| `verification_report` | Verification report file path; must point to an existing file before verify can pass |
|
|
196
220
|
| `branch_status` | `pending` or `handled`; set to `handled` after branch handling completes |
|
|
@@ -209,12 +233,15 @@ Optional fields:
|
|
|
209
233
|
State-machine hard constraints:
|
|
210
234
|
- Before `build → verify`, `isolation` must be `branch` or `worktree`
|
|
211
235
|
- Before `build → verify`, `build_mode` must be selected
|
|
236
|
+
- `build_mode: subagent-driven-development` must also have `subagent_dispatch: confirmed`
|
|
237
|
+
- Before full workflow leaves build phase, `tdd_mode` must be selected as `tdd` or `direct`
|
|
212
238
|
- `build_mode: direct` is allowed by default only for `hotfix` / `tweak`; full workflow requires `direct_override: true`
|
|
239
|
+
- `build_pause` is not an execution method and must not be written to `build_mode`
|
|
213
240
|
- These constraints are enforced by both `comet-guard.sh build --apply` and `comet-state.sh transition <name> build-complete`
|
|
214
241
|
|
|
215
242
|
### Script Location
|
|
216
243
|
|
|
217
|
-
Comet scripts are distributed in `comet/scripts/`. **Do not hardcode paths** — locate once, cache in env vars:
|
|
244
|
+
Comet scripts are distributed in `comet/scripts/`. **Do not hardcode paths** — locate once, cache in env vars. This block is a standard boilerplate repeated in every sub-skill for independent loadability; changes must be kept in sync across all files (boilerplate version: `v2`, update this version when changing to help locate files needing sync):
|
|
218
245
|
|
|
219
246
|
```bash
|
|
220
247
|
COMET_ENV="${COMET_ENV:-$(find . "$HOME"/.*/skills "$HOME/.config" "$HOME/.gemini" -path '*/comet/scripts/comet-env.sh' -type f -print -quit 2>/dev/null)}"
|
|
@@ -235,24 +262,32 @@ fi
|
|
|
235
262
|
**Auto state update**: Guard supports `--apply` flag, automatically updating `.comet.yaml` state fields after checks pass:
|
|
236
263
|
|
|
237
264
|
```bash
|
|
238
|
-
|
|
265
|
+
"$COMET_BASH" "$COMET_GUARD" <change-name> <phase> --apply
|
|
239
266
|
```
|
|
240
267
|
|
|
241
268
|
`--apply` delegates to `comet-state transition`. Use these semantic events when state changes need to be expressed directly:
|
|
242
269
|
|
|
243
270
|
```bash
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
271
|
+
"$COMET_BASH" "$COMET_STATE" transition <change-name> open-complete
|
|
272
|
+
"$COMET_BASH" "$COMET_STATE" transition <change-name> design-complete
|
|
273
|
+
"$COMET_BASH" "$COMET_STATE" transition <change-name> build-complete
|
|
274
|
+
"$COMET_BASH" "$COMET_STATE" transition <change-name> verify-pass
|
|
275
|
+
"$COMET_BASH" "$COMET_STATE" transition <change-name> verify-fail
|
|
276
|
+
"$COMET_BASH" "$COMET_STATE" transition <archive-name> archived
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
**Resolve next action**: after guard-based phase advancement, use the `next` subcommand to determine whether to auto-invoke the next skill:
|
|
280
|
+
|
|
281
|
+
```bash
|
|
282
|
+
"$COMET_BASH" "$COMET_STATE" next <change-name>
|
|
250
283
|
```
|
|
251
284
|
|
|
285
|
+
Output format: `NEXT: auto|manual|done` + `SKILL: <skill-name>` (omitted for `done`) + `HINT` (for `manual` only). With `auto_transition: false`, output is `manual`, which pauses only the next skill invocation and does not affect the already-applied phase advancement.
|
|
286
|
+
|
|
252
287
|
**Archive script**: Complete all archive steps in one command:
|
|
253
288
|
|
|
254
289
|
```bash
|
|
255
|
-
|
|
290
|
+
"$COMET_BASH" "$COMET_ARCHIVE" <change-name>
|
|
256
291
|
```
|
|
257
292
|
|
|
258
293
|
After loading comet, agents should run the variable assignments above once, then reuse `$COMET_GUARD`, `$COMET_STATE`, `$COMET_HANDOFF`, `$COMET_ARCHIVE` throughout the session.
|
|
@@ -272,7 +307,7 @@ openspec/ # OpenSpec — WHAT
|
|
|
272
307
|
│ │ ├── .comet/handoff/ # Script-generated phase handoff packages
|
|
273
308
|
│ │ └── tasks.md # Task checklist
|
|
274
309
|
│ └── archive/YYYY-MM-DD-<name>/ # Archived
|
|
275
|
-
└── specs/<capability>/spec.md # Main specs (
|
|
310
|
+
└── specs/<capability>/spec.md # Main specs (merged from delta semantics at archive)
|
|
276
311
|
|
|
277
312
|
docs/superpowers/ # Superpowers — HOW
|
|
278
313
|
├── specs/YYYY-MM-DD-<topic>-design.md # Design doc (technical RFC, mark status at archive)
|
|
@@ -286,7 +321,7 @@ docs/superpowers/ # Superpowers — HOW
|
|
|
286
321
|
3. **Handoff packages are generated by scripts** — OpenSpec → Superpowers context must be generated through `comet-handoff.sh` as compact traceable excerpts (use `--full` when needed), and validated by guard for source/hash/mode
|
|
287
322
|
4. **Keep tasks.md in sync** — Check off each completed task
|
|
288
323
|
5. **Commit frequently** — One commit per task, message reflects design intent
|
|
289
|
-
6. **Verify before archive** —
|
|
324
|
+
6. **Verify before archive confirmation** — Enter `/comet-archive` only after `/comet-verify` passes, but wait for final user confirmation before running the archive script
|
|
290
325
|
7. **Classify incremental updates** — Small edits, medium brainstorming, large new changes
|
|
291
326
|
8. **Plan must associate with change** — File header contains `change:` and `design-doc:` metadata
|
|
292
327
|
9. **Archive closure** — design doc and plan must mark `archived-with` status
|
|
@@ -20,6 +20,7 @@ When needed, inspect `git diff`, `git diff --cached`, and newly created file con
|
|
|
20
20
|
## 2. Core Rules
|
|
21
21
|
|
|
22
22
|
- The user may not say which files they changed. If the worktree is dirty, including new files shown as `??` in Git status, assume changes may come from the user or mixed sources.
|
|
23
|
+
- **Build artifact exclusion**: `??` files matching `.gitignore` patterns (e.g., `node_modules/`, `dist/`, `__pycache__/`, `*.o`, `target/`, `build/`) are automatically skipped during attribution and not treated as user changes.
|
|
23
24
|
- A dirty worktree is code evidence only. It does not automatically advance `.comet.yaml` `phase` or check off `tasks.md`; Comet state may advance only after attribution, verification, required document synchronization, and the relevant phase guard.
|
|
24
25
|
|
|
25
26
|
## 3. Attribution
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Comet 阶段感知(防漂移规则)
|
|
2
|
+
|
|
3
|
+
> 此规则每轮注入,防止长上下文时遗忘 Comet 流程状态。
|
|
4
|
+
> Hook 平台额外执行 `comet-hook-guard.sh` 进行硬性拦截;
|
|
5
|
+
> 此 Rule 是所有平台通用的软性防线。
|
|
6
|
+
|
|
7
|
+
## 全局规则
|
|
8
|
+
|
|
9
|
+
### 阶段感知(最高优先级)
|
|
10
|
+
|
|
11
|
+
有活跃 comet change 时(`openspec/changes/<name>/.comet.yaml` 存在),**每次开始执行操作前**必须读取 `phase` 字段确认当前阶段。
|
|
12
|
+
|
|
13
|
+
**阶段与允许操作:**
|
|
14
|
+
|
|
15
|
+
| 阶段 | 允许 | 禁止 |
|
|
16
|
+
|------|------|------|
|
|
17
|
+
| `open` | 创建 proposal/design/tasks, 运行 guard | 写源代码 |
|
|
18
|
+
| `design` | brainstorming, 创建 Design Doc, 运行 guard | 写源代码 |
|
|
19
|
+
| `build` | 写源代码、测试、执行计划 | 跳过用户确认点 |
|
|
20
|
+
| `verify` | 验证、branch handling | 跳过失败处理 |
|
|
21
|
+
| `archive` | 确认归档、运行归档脚本 | 写源代码 |
|
|
22
|
+
|
|
23
|
+
### Skill 调用(不可用普通对话替代)
|
|
24
|
+
|
|
25
|
+
以下操作必须通过 Skill 工具加载,Skill 不可用时应停止流程并提示安装:
|
|
26
|
+
|
|
27
|
+
- **brainstorming** — design 阶段、build 阶段中等规模 spec 变更
|
|
28
|
+
- **writing-plans** — build 阶段创建实现计划
|
|
29
|
+
- **executing-plans** / **subagent-driven-development** — build 阶段执行
|
|
30
|
+
- **test-driven-development** — build 阶段 `tdd_mode: tdd` 时,第一个 task 前
|
|
31
|
+
- **systematic-debugging** — 遇到崩溃/测试失败/构建失败时
|
|
32
|
+
- **verification-before-completion** — verify 阶段
|
|
33
|
+
- **using-git-worktrees** — build 阶段选择 worktree 隔离时
|
|
34
|
+
|
|
35
|
+
### 脚本执行(不可跳过)
|
|
36
|
+
|
|
37
|
+
- **阶段退出**: `comet-guard <name> <phase> --apply`(必须看到 ALL CHECKS PASSED)
|
|
38
|
+
- **压缩恢复**: `comet-state check <name> <phase> --recover`
|
|
39
|
+
- **状态更新**: 关键操作后通过 `comet-state set` 更新字段,禁止手工编辑 .comet.yaml
|
|
40
|
+
- **handoff 生成**: `comet-handoff <name> design --write`(禁止手写摘要)
|
|
41
|
+
|
|
42
|
+
### 用户确认(不可自动跳过)
|
|
43
|
+
|
|
44
|
+
以下决策点必须暂停等待用户明确选择,不得根据推荐规则自动填写:
|
|
45
|
+
|
|
46
|
+
- **open**: 需求澄清完成确认、artifact 评审确认
|
|
47
|
+
- **design**: brainstorming 方案确认(确认前不得创建 Design Doc)
|
|
48
|
+
- **build**: plan-ready 暂停、isolation/build_mode/tdd_mode 选择、spec 大规模变更确认
|
|
49
|
+
- **verify**: 验证失败处理策略、branch handling 选择
|
|
50
|
+
- **archive**: 归档前最终确认
|
|
51
|
+
|
|
52
|
+
## Design 阶段专项
|
|
53
|
+
|
|
54
|
+
1. 第一个脚本操作 = `comet-handoff <name> design --write`(未生成 handoff 禁止加载 brainstorming)
|
|
55
|
+
2. brainstorming in progress: incrementally update brainstorm-summary.md(每轮澄清或方案迭代后增量更新恢复检查点,未确认内容标注为待确认/候选)
|
|
56
|
+
3. brainstorming 完成后下一步 = brainstorm-summary.md 定稿 → Design Doc → guard
|
|
57
|
+
4. active compaction gate: brainstorm-summary.md 定稿后、创建 Design Doc 前,优先触发宿主平台原生上下文压缩;无法程序化触发时暂停提示用户手动压缩或确认继续
|
|
58
|
+
5. **绝对不能直接开始写实现代码** — 必须先创建 Design Doc 并通过 guard
|
|
59
|
+
|
|
60
|
+
## Build 阶段专项
|
|
61
|
+
|
|
62
|
+
1. plan 创建后必须询问用户选择继续或暂停(`build_pause` 机制)
|
|
63
|
+
2. 每个 task 完成后必须: tasks.md 打勾 → git commit(不得积攒)
|
|
64
|
+
3. 遇到失败必须加载 **systematic-debugging** skill,根因未定位前不得提出源码修复
|
|
65
|
+
4. spec 变更分级: 小改直接编辑 | 中改加载 brainstorming | 大改暂停等用户确认拆分
|
|
66
|
+
|
|
67
|
+
## Verify 阶段专项
|
|
68
|
+
|
|
69
|
+
1. 第一步运行 `comet-state scale <name>` 确定验证级别
|
|
70
|
+
2. 验证失败后列出失败项等用户选择,CRITICAL 必须修
|
|
71
|
+
3. 连续 3 次失败后必须让用户选择接受偏差或继续修
|
|
72
|
+
|
|
73
|
+
## 上下文压缩恢复
|
|
74
|
+
|
|
75
|
+
如果怀疑发生上下文压缩(之前对话被摘要、找不到之前讨论的内容),立即运行:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
"$COMET_BASH" "$COMET_STATE" check <name> <phase> --recover
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
按脚本输出的 **Recovery action** 决定下一步。
|
|
82
|
+
|
|
83
|
+
## 阶段退出后自动过渡
|
|
84
|
+
|
|
85
|
+
guard `--apply` 成功后,必须调用下一阶段的 skill:
|
|
86
|
+
|
|
87
|
+
- open → `comet-design`(full)/ `comet-build`(hotfix/tweak)
|
|
88
|
+
- design → `comet-build`
|
|
89
|
+
- build → `comet-verify`
|
|
90
|
+
- verify → `comet-archive`
|
|
@@ -5,6 +5,9 @@
|
|
|
5
5
|
|
|
6
6
|
set -euo pipefail
|
|
7
7
|
|
|
8
|
+
COMET_BASH="${COMET_BASH:-${BASH:-bash}}"
|
|
9
|
+
COMET_OPENSPEC="${COMET_OPENSPEC:-openspec}"
|
|
10
|
+
|
|
8
11
|
red() { echo -e "\033[31m$1\033[0m" >&2; }
|
|
9
12
|
green() { echo -e "\033[32m$1\033[0m" >&2; }
|
|
10
13
|
yellow() { echo -e "\033[33m$1\033[0m" >&2; }
|
|
@@ -37,9 +40,9 @@ validate_change_name "$CHANGE"
|
|
|
37
40
|
|
|
38
41
|
CHANGE_DIR="openspec/changes/$CHANGE"
|
|
39
42
|
YAML="$CHANGE_DIR/.comet.yaml"
|
|
40
|
-
SCRIPT_DIR="$(cd "$(dirname "$
|
|
43
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd -P)"
|
|
41
44
|
STATE_SH="$SCRIPT_DIR/comet-state.sh"
|
|
42
|
-
TODAY=$(date +%Y-%m-%d)
|
|
45
|
+
TODAY=$(date -u +%Y-%m-%d)
|
|
43
46
|
ARCHIVE_NAME="${TODAY}-${CHANGE}"
|
|
44
47
|
ARCHIVE_DIR="openspec/changes/archive/${ARCHIVE_NAME}"
|
|
45
48
|
|
|
@@ -70,7 +73,7 @@ echo "=== Comet Archive: $CHANGE ===" >&2
|
|
|
70
73
|
yaml_field() {
|
|
71
74
|
local field="$1"
|
|
72
75
|
if [ -f "$STATE_SH" ]; then
|
|
73
|
-
|
|
76
|
+
"$COMET_BASH" "$STATE_SH" get "$CHANGE" "$field" 2>/dev/null
|
|
74
77
|
else
|
|
75
78
|
if [ -f "$YAML" ]; then
|
|
76
79
|
local value
|
|
@@ -156,45 +159,7 @@ fi
|
|
|
156
159
|
|
|
157
160
|
step_ok "Archive target available"
|
|
158
161
|
|
|
159
|
-
# --- Step 4:
|
|
160
|
-
|
|
161
|
-
sync_delta_specs() {
|
|
162
|
-
local delta_root="$CHANGE_DIR/specs"
|
|
163
|
-
if [ ! -d "$delta_root" ]; then
|
|
164
|
-
return 0
|
|
165
|
-
fi
|
|
166
|
-
|
|
167
|
-
for delta_spec_dir in "$delta_root"/*/; do
|
|
168
|
-
[ -d "$delta_spec_dir" ] || continue
|
|
169
|
-
local capability
|
|
170
|
-
capability=$(basename "$delta_spec_dir")
|
|
171
|
-
local delta_spec="$delta_spec_dir/spec.md"
|
|
172
|
-
local main_spec="openspec/specs/$capability/spec.md"
|
|
173
|
-
|
|
174
|
-
if [ ! -f "$delta_spec" ]; then
|
|
175
|
-
continue
|
|
176
|
-
fi
|
|
177
|
-
|
|
178
|
-
if [ "$DRY_RUN" -eq 1 ]; then
|
|
179
|
-
step_dry_run "Would sync: $capability → $main_spec"
|
|
180
|
-
continue
|
|
181
|
-
fi
|
|
182
|
-
|
|
183
|
-
if [ ! -f "$main_spec" ]; then
|
|
184
|
-
mkdir -p "openspec/specs/$capability"
|
|
185
|
-
elif ! cmp -s "$main_spec" "$delta_spec"; then
|
|
186
|
-
yellow " [DIFF] Delta spec differs from main spec before sync: $capability"
|
|
187
|
-
diff -u "$main_spec" "$delta_spec" >&2 || true
|
|
188
|
-
fi
|
|
189
|
-
cp "$delta_spec" "$main_spec"
|
|
190
|
-
|
|
191
|
-
step_ok "Delta spec synced: $capability → openspec/specs/$capability/spec.md"
|
|
192
|
-
done
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
sync_delta_specs
|
|
196
|
-
|
|
197
|
-
# --- Step 5: Annotate design doc frontmatter ---
|
|
162
|
+
# --- Step 4: Prepare document frontmatter annotation ---
|
|
198
163
|
|
|
199
164
|
annotate_frontmatter() {
|
|
200
165
|
local file="$1"
|
|
@@ -212,6 +177,7 @@ annotate_frontmatter() {
|
|
|
212
177
|
if head -1 "$file" | grep -q '^---'; then
|
|
213
178
|
local tmp_file
|
|
214
179
|
tmp_file=$(mktemp)
|
|
180
|
+
chmod 600 "$tmp_file"
|
|
215
181
|
awk -v archive="$ARCHIVE_NAME" -v extra="$extra_fields" '
|
|
216
182
|
/^archived-with:/ { next }
|
|
217
183
|
NR==1 && /^---/ { print; next }
|
|
@@ -226,6 +192,7 @@ annotate_frontmatter() {
|
|
|
226
192
|
else
|
|
227
193
|
local tmp_file
|
|
228
194
|
tmp_file=$(mktemp)
|
|
195
|
+
chmod 600 "$tmp_file"
|
|
229
196
|
{
|
|
230
197
|
echo "---"
|
|
231
198
|
echo "archived-with: $ARCHIVE_NAME"
|
|
@@ -242,27 +209,78 @@ annotate_frontmatter() {
|
|
|
242
209
|
step_ok "Annotated: $file"
|
|
243
210
|
}
|
|
244
211
|
|
|
245
|
-
|
|
246
|
-
annotate_frontmatter "$DESIGN_DOC" "status: final"
|
|
247
|
-
fi
|
|
212
|
+
# --- Step 5: Run OpenSpec archive for delta merge and move ---
|
|
248
213
|
|
|
249
|
-
|
|
214
|
+
verify_main_specs_clean() {
|
|
215
|
+
if [ ! -d "openspec/specs" ]; then
|
|
216
|
+
return 0
|
|
217
|
+
fi
|
|
250
218
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
219
|
+
local found=0
|
|
220
|
+
local matches
|
|
221
|
+
for spec_file in openspec/specs/*/spec.md; do
|
|
222
|
+
[ -f "$spec_file" ] || continue
|
|
223
|
+
matches=$(grep -nE '^## (ADDED|MODIFIED|REMOVED|RENAMED) Requirements$' "$spec_file" 2>/dev/null || true)
|
|
224
|
+
if [ -n "$matches" ]; then
|
|
225
|
+
red "FATAL: delta-only section heading leaked into main spec: $spec_file"
|
|
226
|
+
printf '%s\n' "$matches" >&2
|
|
227
|
+
found=1
|
|
228
|
+
fi
|
|
229
|
+
done
|
|
254
230
|
|
|
255
|
-
|
|
231
|
+
if [ "$found" -ne 0 ]; then
|
|
232
|
+
return 1
|
|
233
|
+
fi
|
|
234
|
+
return 0
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
resolve_archive_dir() {
|
|
238
|
+
if [ -d "$ARCHIVE_DIR" ]; then
|
|
239
|
+
return 0
|
|
240
|
+
fi
|
|
241
|
+
# Fallback: search for any directory matching *-$CHANGE in archive
|
|
242
|
+
local found
|
|
243
|
+
found=$(find "openspec/changes/archive" -maxdepth 1 -mindepth 1 -type d -name "*-$CHANGE" 2>/dev/null | head -1 || true)
|
|
244
|
+
if [ -n "$found" ]; then
|
|
245
|
+
ARCHIVE_DIR="$found"
|
|
246
|
+
ARCHIVE_NAME=$(basename "$found")
|
|
247
|
+
return 0
|
|
248
|
+
fi
|
|
249
|
+
return 1
|
|
250
|
+
}
|
|
256
251
|
|
|
257
252
|
if [ "$DRY_RUN" -eq 1 ]; then
|
|
258
|
-
step_dry_run "Would
|
|
253
|
+
step_dry_run "Would run OpenSpec archive: $CHANGE"
|
|
259
254
|
else
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
255
|
+
if ! command -v "$COMET_OPENSPEC" >/dev/null 2>&1; then
|
|
256
|
+
red "FATAL: OpenSpec CLI not found: $COMET_OPENSPEC"
|
|
257
|
+
red "Install OpenSpec or set COMET_OPENSPEC to the openspec executable."
|
|
258
|
+
exit 1
|
|
259
|
+
fi
|
|
260
|
+
|
|
261
|
+
"$COMET_OPENSPEC" archive "$CHANGE" --yes >&2
|
|
262
|
+
if ! resolve_archive_dir; then
|
|
263
|
+
step_fail "OpenSpec archive output not found"
|
|
264
|
+
exit 1
|
|
265
|
+
else
|
|
266
|
+
step_ok "OpenSpec archive completed: $ARCHIVE_DIR"
|
|
267
|
+
fi
|
|
268
|
+
|
|
269
|
+
verify_main_specs_clean
|
|
270
|
+
step_ok "Main specs verified clean"
|
|
271
|
+
fi
|
|
272
|
+
|
|
273
|
+
# --- Step 6: Annotate design doc and plan frontmatter ---
|
|
274
|
+
|
|
275
|
+
if [ -n "$DESIGN_DOC" ] && [ "$DESIGN_DOC" != "null" ]; then
|
|
276
|
+
annotate_frontmatter "$DESIGN_DOC" "status: final"
|
|
277
|
+
fi
|
|
278
|
+
|
|
279
|
+
if [ -n "$PLAN_PATH" ] && [ "$PLAN_PATH" != "null" ]; then
|
|
280
|
+
annotate_frontmatter "$PLAN_PATH" ""
|
|
263
281
|
fi
|
|
264
282
|
|
|
265
|
-
# --- Step
|
|
283
|
+
# --- Step 7: Mark archived via comet-state transition ---
|
|
266
284
|
|
|
267
285
|
ARCHIVE_YAML="$ARCHIVE_DIR/.comet.yaml"
|
|
268
286
|
|
|
@@ -270,14 +288,14 @@ if [ "$DRY_RUN" -eq 1 ]; then
|
|
|
270
288
|
step_dry_run "Would set archived: true in $ARCHIVE_YAML"
|
|
271
289
|
else
|
|
272
290
|
if [ -f "$ARCHIVE_YAML" ]; then
|
|
273
|
-
|
|
291
|
+
"$COMET_BASH" "$STATE_SH" transition "$ARCHIVE_NAME" archived >/dev/null
|
|
274
292
|
step_ok "archived: true"
|
|
275
293
|
else
|
|
276
294
|
step_fail "archived: true (.comet.yaml not found after move)"
|
|
277
295
|
fi
|
|
278
296
|
fi
|
|
279
297
|
|
|
280
|
-
# --- Step
|
|
298
|
+
# --- Step 8: Print summary ---
|
|
281
299
|
|
|
282
300
|
echo "" >&2
|
|
283
301
|
if [ "$DRY_RUN" -eq 1 ]; then
|
|
@@ -17,15 +17,65 @@ export COMET_HANDOFF="${COMET_HANDOFF:-${_comet_script_dir}/comet-handoff.sh}"
|
|
|
17
17
|
export COMET_ARCHIVE="${COMET_ARCHIVE:-${_comet_script_dir}/comet-archive.sh}"
|
|
18
18
|
export COMET_YAML_VALIDATE="${COMET_YAML_VALIDATE:-${_comet_script_dir}/comet-yaml-validate.sh}"
|
|
19
19
|
|
|
20
|
+
_comet_bash_is_usable() {
|
|
21
|
+
local _comet_bash_candidate="$1"
|
|
22
|
+
if [ -z "$_comet_bash_candidate" ]; then
|
|
23
|
+
return 1
|
|
24
|
+
fi
|
|
25
|
+
case "$_comet_bash_candidate" in
|
|
26
|
+
*/Windows/System32/bash.exe|*/windows/system32/bash.exe|*\\Windows\\System32\\bash.exe|*\\windows\\system32\\bash.exe)
|
|
27
|
+
return 1
|
|
28
|
+
;;
|
|
29
|
+
esac
|
|
30
|
+
"$_comet_bash_candidate" -lc 'printf comet-bash-ok' >/dev/null 2>&1
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
_comet_resolve_bash() {
|
|
34
|
+
local _comet_bash_candidate
|
|
35
|
+
|
|
36
|
+
if _comet_bash_is_usable "${COMET_BASH:-}"; then
|
|
37
|
+
printf '%s\n' "$COMET_BASH"
|
|
38
|
+
return 0
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
if _comet_bash_is_usable "${BASH:-}"; then
|
|
42
|
+
printf '%s\n' "$BASH"
|
|
43
|
+
return 0
|
|
44
|
+
fi
|
|
45
|
+
|
|
46
|
+
_comet_bash_candidate="$(command -v sh 2>/dev/null | awk '{ sub(/\/sh(\.exe)?$/, "/bash.exe"); print }')"
|
|
47
|
+
if _comet_bash_is_usable "$_comet_bash_candidate"; then
|
|
48
|
+
printf '%s\n' "$_comet_bash_candidate"
|
|
49
|
+
return 0
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
_comet_bash_candidate="$(command -v bash 2>/dev/null || true)"
|
|
53
|
+
if _comet_bash_is_usable "$_comet_bash_candidate"; then
|
|
54
|
+
printf '%s\n' "$_comet_bash_candidate"
|
|
55
|
+
return 0
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
return 1
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
COMET_BASH="$(_comet_resolve_bash || true)"
|
|
62
|
+
export COMET_BASH
|
|
63
|
+
|
|
20
64
|
_comet_env_fail() {
|
|
21
65
|
echo "ERROR: Comet scripts not found. Ensure the comet skill is installed completely." >&2
|
|
22
66
|
echo "Expected path pattern: */comet/scripts/comet-*.sh under project or platform skill directories" >&2
|
|
23
67
|
}
|
|
24
68
|
|
|
69
|
+
_comet_bash_fail() {
|
|
70
|
+
echo "ERROR: usable bash not found. Install Git Bash or set COMET_BASH to a working bash executable." >&2
|
|
71
|
+
echo "Windows WSL launcher bash.exe is not supported for Comet scripts." >&2
|
|
72
|
+
}
|
|
73
|
+
|
|
25
74
|
_comet_env_abort() {
|
|
26
75
|
local _comet_env_was_sourced="$_comet_env_sourced"
|
|
27
76
|
unset _comet_env_source _comet_script_dir _comet_script _comet_env_missing _comet_env_sourced
|
|
28
|
-
unset
|
|
77
|
+
unset _comet_bash_candidate
|
|
78
|
+
unset -f _comet_env_fail _comet_bash_fail _comet_bash_is_usable _comet_resolve_bash
|
|
29
79
|
if [ "$_comet_env_was_sourced" -eq 1 ]; then
|
|
30
80
|
unset -f _comet_env_abort
|
|
31
81
|
return 1
|
|
@@ -34,6 +84,10 @@ _comet_env_abort() {
|
|
|
34
84
|
}
|
|
35
85
|
|
|
36
86
|
_comet_env_missing=0
|
|
87
|
+
if [ -z "$COMET_BASH" ]; then
|
|
88
|
+
_comet_bash_fail
|
|
89
|
+
_comet_env_missing=1
|
|
90
|
+
fi
|
|
37
91
|
for _comet_script in \
|
|
38
92
|
"$COMET_GUARD" \
|
|
39
93
|
"$COMET_STATE" \
|
|
@@ -51,5 +105,6 @@ if [ "$_comet_env_missing" -ne 0 ]; then
|
|
|
51
105
|
_comet_env_abort
|
|
52
106
|
else
|
|
53
107
|
unset _comet_env_source _comet_script_dir _comet_script _comet_env_missing _comet_env_sourced
|
|
54
|
-
unset
|
|
108
|
+
unset _comet_bash_candidate
|
|
109
|
+
unset -f _comet_env_fail _comet_bash_fail _comet_bash_is_usable _comet_resolve_bash _comet_env_abort
|
|
55
110
|
fi
|