@rpamis/comet 0.3.4 → 0.3.6

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 CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 rpamis
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2026 rpamis
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -309,6 +309,7 @@ All states and execution phases are updated via scripts, and each phase verifies
309
309
  workflow: full
310
310
  phase: build
311
311
  build_mode: subagent-driven-development
312
+ build_pause: null
312
313
  isolation: branch
313
314
  verify_mode: null
314
315
  design_doc: docs/superpowers/specs/YYYY-MM-DD-topic-design.md
@@ -325,7 +326,7 @@ handoff_context: openspec/changes/<name>/.comet/handoff/design-context.json
325
326
  handoff_hash: <sha256>
326
327
  ```
327
328
 
328
- In full workflow, `build_mode`, `isolation`, and `verify_mode` may temporarily be `null`; `build_mode` and `isolation` must be resolved before `build → verify`. `verification_report` stays `null` until verification writes a report, and `verify-pass` requires that report to exist plus `branch_status: handled`. Fields after `archived` in the example are optional or script-derived: `direct_override` is only needed for full-workflow direct builds, project commands may be absent unless configured, and `handoff_context` / `handoff_hash` are recorded by `comet-handoff.sh` before leaving design. Projects can configure `build_command` / `verify_command` in the change or repo root, and guard will run those commands first and print failure output.
329
+ In full workflow, `build_mode`, `build_pause`, `isolation`, and `verify_mode` may temporarily be `null`; `build_mode` and `isolation` must be resolved before `build → verify`. `build_pause` records an internal build-phase pause point: `null` means no pause, while `plan-ready` means the plan has been generated and the user paused before choosing isolation and execution mode. It is not an execution mode and must not be written into `build_mode`. `verification_report` stays `null` until verification writes a report, and `verify-pass` requires that report to exist plus `branch_status: handled`. Fields after `archived` in the example are optional or script-derived: `direct_override` is only needed for full-workflow direct builds, project commands may be absent unless configured, and `handoff_context` / `handoff_hash` are recorded by `comet-handoff.sh` before leaving design. Projects can configure `build_command` / `verify_command` in the change or repo root, and guard will run those commands first and print failure output.
329
330
 
330
331
  </details>
331
332
 
@@ -355,6 +356,7 @@ Comet ensures agent execution reliability through automated state transitions:
355
356
  4. **Build Decision Enforcement** — Guard and state transitions both block skipped build choices
356
357
  - `isolation` must be `branch` or `worktree`
357
358
  - `build_mode` must be selected before leaving build
359
+ - `build_pause: plan-ready` is a recoverable pause after plan generation, not a `build_mode`
358
360
  - Full workflow `build_mode: direct` requires `direct_override: true`
359
361
 
360
362
  5. **Verification Evidence** — Guard enforces proof before phase advance
@@ -419,13 +421,23 @@ Track our development progress and upcoming features on the [Comet Roadmap](http
419
421
  ## Contributors
420
422
 
421
423
  <a href="https://github.com/rpamis/comet/graphs/contributors">
422
- <img src="https://contrib.rocks/image?repo=rpamis/comet&max=999&columns=12&anon=1" />
424
+ <img src="https://contrib.rocks/image?repo=rpamis/comet&columns=12&anon=1" />
423
425
  </a>
424
426
 
425
427
  ## License
426
428
 
427
429
  [MIT](LICENSE)
428
430
 
431
+ ## Community
432
+
433
+ <p align="center">
434
+ <img src="https://github.com/rpamis/comet/blob/master/img/wechat.jpg" alt="WeChat Group" width="200" />
435
+ &nbsp;&nbsp;&nbsp;&nbsp;
436
+ <img src="https://github.com/rpamis/comet/blob/master/img/qq.jpg" alt="QQ Group" width="200" />
437
+ </p>
438
+
439
+ <p align="center">WeChat Group &nbsp;&nbsp;|&nbsp;&nbsp; QQ Group</p>
440
+
429
441
  ## Reference
430
442
 
431
443
  [LINUX DO - 新的理想型社区](https://linux.do/)
@@ -53,9 +53,13 @@ Prefer reading `openspec/changes/<name>/.comet.yaml`. If not available, fall bac
53
53
  **Resume rules**:
54
54
  - On every context resume, rerun Step 0 and Step 1; do not trust conversation history for phase detection
55
55
  - 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 whether `build_mode` and `isolation` are set; if any fields are unset, return to `/comet-build` corresponding step to supplement before executing; if both are set, read the next unchecked task from tasks.md and continue
57
- - 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 `bash "$COMET_STATE" transition <name> verify-fail` and invoke `/comet-build`
58
- - If `phase: open` but proposal/design/tasks are complete, first run `bash "$COMET_GUARD" <change-name> open --apply` to repair state, then continue detection
56
+ - If `phase: build`, first check `build_pause`, `plan`, `build_mode`, and `isolation`:
57
+ - If `build_pause: plan-ready` and the plan file exists, return to the `/comet-build` plan-ready resume point, prompt the user to continue choosing isolation and execution method, and do not regenerate the plan
58
+ - If `build_pause: plan-ready` but the plan file is missing, return to `/comet-build` to handle corrupted state or regenerate the plan
59
+ - If `build_mode` or `isolation` is unset, return to the corresponding `/comet-build` step to supplement before executing
60
+ - If both are set, read the next unchecked task from tasks.md and continue
61
+ - 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`
62
+ - 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
59
63
  - If `phase: archive`, only invoke `/comet-archive`; after archive succeeds, the change moves to the archive directory, so do not run guard against the old active directory
60
64
 
61
65
  **Step 2: Phase Determination** (check in order, first match wins)
@@ -92,7 +96,7 @@ If metadata conflicts with file state, use verifiable file state as source of tr
92
96
  |----------|----------|
93
97
  | `openspec list --json` fails | Check if openspec is installed, prompt user to run `openspec init` |
94
98
  | 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 `bash $COMET_STATE set` then continue |
99
+ | `.comet.yaml` malformed or missing | Use file state as source of truth, correct with `"$COMET_BASH" "$COMET_STATE" set` then continue |
96
100
  | Build/test fails | Return to build phase for fixes, do not enter verify |
97
101
  | Incomplete change directory structure | Fill missing files according to `comet-open` artifact requirements |
98
102
 
@@ -103,19 +107,30 @@ A single `/comet` invocation starts from the detected phase and advances to the
103
107
 
104
108
  Flow chain: open → design → build → verify → archive
105
109
 
106
- **Continuous execution requirement**: starting from the detected phase, the agent must automatically continue through all later phases. Auto-advancing only applies at transition points without user decisions. When encountering user decision points, must pause and wait for the user's explicit response. Must not use recommendation rules, defaults, or historical preferences to substitute for user confirmation.
110
+ **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 AskUserQuestion tool 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
111
 
108
- **Decision points are blocking points**: whenever reaching any of the following nodes, the current `/comet` invocation must stop. Only after the user explicitly chooses can the corresponding state fields be written and operations executed, then auto-advance resumes.
112
+ **Decision points are blocking points**: whenever reaching any of the following nodes, the current `/comet` invocation must stop, **using the AskUserQuestion tool to wait for the user's choice**. Only after the user explicitly chooses can the corresponding state fields be written and operations executed, then auto-advance resumes.
109
113
 
110
114
  Nodes requiring user participation (pause only at these nodes):
111
- 1. Confirm design approach during brainstorming
112
- 2. Select workflow configuration during build phase (isolation + execution method, single interaction)
113
- 3. Decide to fix or accept deviation when verify fails (including Spec drift handling)
114
- 4. Choose branch handling method for finishing-branch
115
- 5. Encounter upgrade conditions (hotfix/tweak full workflow)
116
- 6. Build phase scope expansion requiring redesign or new change split
117
-
118
- Agents should not skip these decision points; other unambiguous phase transitions must proceed automatically, must not exit midway.
115
+ 1. Open phase proposal/design/tasks review and confirmation
116
+ 2. Confirm design approach during brainstorming
117
+ 3. Plan-ready pause choice during build phase, followed by workflow configuration selection (isolation + execution method)
118
+ 4. Decide to fix or accept deviation when verify fails (including Spec drift handling)
119
+ 5. Choose branch handling method for finishing-branch
120
+ 6. Encounter upgrade conditions (hotfix/tweak full workflow)
121
+ 7. Build phase scope expansion requiring redesign or new change split
122
+
123
+ Agents should not skip these decision points; other unambiguous phase transitions must proceed automatically, must not exit midway. At decision points, **text output must NOT substitute for tool-based waiting — must explicitly obtain the user's choice via AskUserQuestion before continuing**.
124
+
125
+ **Red Flags** — when these thoughts appear, STOP and check:
126
+
127
+ | Agent Thought | Actual Risk |
128
+ |--------------|-------------|
129
+ | "The user would probably agree with this approach" | Cannot decide for the user — use AskUserQuestion |
130
+ | "This is a small change, confirmation isn't needed" | Decision points have no size exception — blocking points must wait |
131
+ | "The user chose A last time, so A again" | Historical preference cannot substitute for current confirmation |
132
+ | "I explained the plan and the user didn't object" | No objection ≠ consent — must use tool to get explicit choice |
133
+ | "The flow has reached this point, should be fine" | Verification not passed ≠ passed — check verify_result |
119
134
  </IMPORTANT>
120
135
 
121
136
  ---
@@ -160,6 +175,7 @@ design_doc: docs/superpowers/specs/YYYY-MM-DD-topic-design.md
160
175
  plan: docs/superpowers/plans/YYYY-MM-DD-feature.md
161
176
  base_ref: a1b2c3d4e5f6...
162
177
  build_mode: subagent-driven-development
178
+ build_pause: null
163
179
  isolation: branch
164
180
  verify_mode: light
165
181
  verify_result: pending
@@ -178,6 +194,7 @@ archived: false
178
194
  | `plan` | Associated Superpowers Plan path, can be empty |
179
195
  | `base_ref` | Git commit SHA recorded at init, used for scale assessment. Serves as fallback when no plan exists |
180
196
  | `build_mode` | Selected execution method, can be empty |
197
+ | `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 |
181
198
  | `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` |
182
199
  | `verify_mode` | `light` or `full`, can be empty |
183
200
  | `verify_result` | `pending`, `pass`, or `fail` |
@@ -199,6 +216,7 @@ State-machine hard constraints:
199
216
  - Before `build → verify`, `isolation` must be `branch` or `worktree`
200
217
  - Before `build → verify`, `build_mode` must be selected
201
218
  - `build_mode: direct` is allowed by default only for `hotfix` / `tweak`; full workflow requires `direct_override: true`
219
+ - `build_pause` is not an execution method and must not be written to `build_mode`
202
220
  - These constraints are enforced by both `comet-guard.sh build --apply` and `comet-state.sh transition <name> build-complete`
203
221
 
204
222
  ### Script Location
@@ -224,24 +242,24 @@ fi
224
242
  **Auto state update**: Guard supports `--apply` flag, automatically updating `.comet.yaml` state fields after checks pass:
225
243
 
226
244
  ```bash
227
- bash "$COMET_GUARD" <change-name> <phase> --apply
245
+ "$COMET_BASH" "$COMET_GUARD" <change-name> <phase> --apply
228
246
  ```
229
247
 
230
248
  `--apply` delegates to `comet-state transition`. Use these semantic events when state changes need to be expressed directly:
231
249
 
232
250
  ```bash
233
- bash "$COMET_STATE" transition <change-name> open-complete
234
- bash "$COMET_STATE" transition <change-name> design-complete
235
- bash "$COMET_STATE" transition <change-name> build-complete
236
- bash "$COMET_STATE" transition <change-name> verify-pass
237
- bash "$COMET_STATE" transition <change-name> verify-fail
238
- bash "$COMET_STATE" transition <archive-name> archived
251
+ "$COMET_BASH" "$COMET_STATE" transition <change-name> open-complete
252
+ "$COMET_BASH" "$COMET_STATE" transition <change-name> design-complete
253
+ "$COMET_BASH" "$COMET_STATE" transition <change-name> build-complete
254
+ "$COMET_BASH" "$COMET_STATE" transition <change-name> verify-pass
255
+ "$COMET_BASH" "$COMET_STATE" transition <change-name> verify-fail
256
+ "$COMET_BASH" "$COMET_STATE" transition <archive-name> archived
239
257
  ```
240
258
 
241
259
  **Archive script**: Complete all archive steps in one command:
242
260
 
243
261
  ```bash
244
- bash "$COMET_ARCHIVE" <change-name>
262
+ "$COMET_BASH" "$COMET_ARCHIVE" <change-name>
245
263
  ```
246
264
 
247
265
  After loading comet, agents should run the variable assignments above once, then reuse `$COMET_GUARD`, `$COMET_STATE`, `$COMET_HANDOFF`, `$COMET_ARCHIVE` throughout the session.
@@ -5,6 +5,8 @@
5
5
 
6
6
  set -euo pipefail
7
7
 
8
+ COMET_BASH="${COMET_BASH:-${BASH:-bash}}"
9
+
8
10
  red() { echo -e "\033[31m$1\033[0m" >&2; }
9
11
  green() { echo -e "\033[32m$1\033[0m" >&2; }
10
12
  yellow() { echo -e "\033[33m$1\033[0m" >&2; }
@@ -70,7 +72,7 @@ echo "=== Comet Archive: $CHANGE ===" >&2
70
72
  yaml_field() {
71
73
  local field="$1"
72
74
  if [ -f "$STATE_SH" ]; then
73
- bash "$STATE_SH" get "$CHANGE" "$field" 2>/dev/null
75
+ "$COMET_BASH" "$STATE_SH" get "$CHANGE" "$field" 2>/dev/null
74
76
  else
75
77
  if [ -f "$YAML" ]; then
76
78
  local value
@@ -270,7 +272,7 @@ if [ "$DRY_RUN" -eq 1 ]; then
270
272
  step_dry_run "Would set archived: true in $ARCHIVE_YAML"
271
273
  else
272
274
  if [ -f "$ARCHIVE_YAML" ]; then
273
- bash "$STATE_SH" transition "$ARCHIVE_NAME" archived >/dev/null
275
+ "$COMET_BASH" "$STATE_SH" transition "$ARCHIVE_NAME" archived >/dev/null
274
276
  step_ok "archived: true"
275
277
  else
276
278
  step_fail "archived: true (.comet.yaml not found after move)"
@@ -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 -f _comet_env_fail
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 -f _comet_env_fail _comet_env_abort
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
@@ -7,6 +7,8 @@
7
7
 
8
8
  set -euo pipefail
9
9
 
10
+ COMET_BASH="${COMET_BASH:-${BASH:-bash}}"
11
+
10
12
  red() { echo -e "\033[31m$1\033[0m" >&2; }
11
13
  green() { echo -e "\033[32m$1\033[0m" >&2; }
12
14
  warn() { echo -e "\033[33m$1\033[0m" >&2; }
@@ -181,7 +183,7 @@ is_windows_bash() {
181
183
  run_command_string() {
182
184
  local command="$1"
183
185
  echo "+ $command" >&2
184
- bash -lc "$command"
186
+ "$COMET_BASH" -lc "$command"
185
187
  }
186
188
 
187
189
  hash_stream() {
@@ -240,8 +242,8 @@ preflight() {
240
242
  local validate_script
241
243
  validate_script="$SCRIPT_DIR/comet-yaml-validate.sh"
242
244
  if [ -f "$validate_script" ]; then
243
- if ! bash "$validate_script" "$CHANGE" 2>/dev/null; then
244
- bash "$validate_script" "$CHANGE"
245
+ if ! "$COMET_BASH" "$validate_script" "$CHANGE" 2>/dev/null; then
246
+ "$COMET_BASH" "$validate_script" "$CHANGE" || true
245
247
  red "FATAL: .comet.yaml schema validation failed"
246
248
  exit 1
247
249
  fi
@@ -300,7 +302,7 @@ isolation_selected() {
300
302
  *)
301
303
  echo "isolation must be branch or worktree, got '${isolation:-null}'" >&2
302
304
  echo "Next: ask the user to choose branch or worktree, create the chosen isolation, then run:" >&2
303
- echo " bash \"\$COMET_STATE\" set $CHANGE isolation <branch|worktree>" >&2
305
+ echo " \"\$COMET_BASH\" \"\$COMET_STATE\" set $CHANGE isolation <branch|worktree>" >&2
304
306
  return 1
305
307
  ;;
306
308
  esac
@@ -313,8 +315,8 @@ build_mode_selected() {
313
315
  subagent-driven-development|executing-plans|direct) return 0 ;;
314
316
  *)
315
317
  echo "build_mode must be selected before leaving build, got '${build_mode:-null}'" >&2
316
- echo "Next: ask the user to choose an implementation mode, then run:" >&2
317
- echo " bash \"\$COMET_STATE\" set $CHANGE build_mode <subagent-driven-development|executing-plans>" >&2
318
+ echo "Next: ask the user to choose an execution mode, then run:" >&2
319
+ echo " \"\$COMET_BASH\" \"\$COMET_STATE\" set $CHANGE build_mode <subagent-driven-development|executing-plans>" >&2
318
320
  return 1
319
321
  ;;
320
322
  esac
@@ -336,7 +338,7 @@ build_mode_allowed_for_workflow() {
336
338
  return 0
337
339
  fi
338
340
  echo "build_mode=direct is only allowed for hotfix/tweak unless direct_override: true is recorded" >&2
339
- echo "Next: switch build_mode to executing-plans or subagent-driven-development, or stop and ask the user for an explicit direct override." >&2
341
+ echo "Next: choose executing-plans or subagent-driven-development, or stop and ask the user for an explicit direct override." >&2
340
342
  return 1
341
343
  ;;
342
344
  esac
@@ -367,7 +369,7 @@ design_handoff_context_valid() {
367
369
 
368
370
  if [ -z "$context" ] || [ "$context" = "null" ]; then
369
371
  echo "handoff_context is missing from .comet.yaml" >&2
370
- echo "Next: run bash \"\$COMET_HANDOFF\" $CHANGE design --write before invoking Superpowers." >&2
372
+ echo "Next: run \"\$COMET_BASH\" \"\$COMET_HANDOFF\" $CHANGE design --write before invoking Superpowers." >&2
371
373
  return 1
372
374
  fi
373
375
  if [ ! -s "$context" ]; then
@@ -545,10 +547,10 @@ apply_state_update() {
545
547
 
546
548
  if [ -f "$state_sh" ]; then
547
549
  case "$p" in
548
- open) bash "$state_sh" transition "$CHANGE" open-complete ;;
549
- design) bash "$state_sh" transition "$CHANGE" design-complete ;;
550
- build) bash "$state_sh" transition "$CHANGE" build-complete ;;
551
- verify) bash "$state_sh" transition "$CHANGE" verify-pass ;;
550
+ open) "$COMET_BASH" "$state_sh" transition "$CHANGE" open-complete ;;
551
+ design) "$COMET_BASH" "$state_sh" transition "$CHANGE" design-complete ;;
552
+ build) "$COMET_BASH" "$state_sh" transition "$CHANGE" build-complete ;;
553
+ verify) "$COMET_BASH" "$state_sh" transition "$CHANGE" verify-pass ;;
552
554
  esac
553
555
  else
554
556
  red "FATAL: comet-state.sh not found; cannot apply state transition"
@@ -4,6 +4,8 @@
4
4
 
5
5
  set -euo pipefail
6
6
 
7
+ COMET_BASH="${COMET_BASH:-${BASH:-bash}}"
8
+
7
9
  red() { echo -e "\033[31m$1\033[0m" >&2; }
8
10
  green() { echo -e "\033[32m$1\033[0m" >&2; }
9
11
 
@@ -249,8 +251,8 @@ write_markdown_context "$CONTEXT_MD"
249
251
  write_json_context "$CONTEXT_JSON"
250
252
 
251
253
  if [ -x "$STATE_SH" ] || [ -f "$STATE_SH" ]; then
252
- bash "$STATE_SH" set "$CHANGE" handoff_context "$CONTEXT_JSON" >/dev/null
253
- bash "$STATE_SH" set "$CHANGE" handoff_hash "$CONTEXT_HASH" >/dev/null
254
+ "$COMET_BASH" "$STATE_SH" set "$CHANGE" handoff_context "$CONTEXT_JSON" >/dev/null
255
+ "$COMET_BASH" "$STATE_SH" set "$CHANGE" handoff_hash "$CONTEXT_HASH" >/dev/null
254
256
  else
255
257
  red "ERROR: comet-state.sh not found; cannot record handoff fields"
256
258
  exit 1