prizmkit 1.1.10 → 1.1.13

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 (50) hide show
  1. package/bundled/VERSION.json +3 -3
  2. package/bundled/dev-pipeline/README.md +10 -46
  3. package/bundled/dev-pipeline/reset-bug.sh +84 -10
  4. package/bundled/dev-pipeline/reset-feature.sh +86 -10
  5. package/bundled/dev-pipeline/reset-refactor.sh +68 -4
  6. package/bundled/dev-pipeline/scripts/generate-bootstrap-prompt.py +47 -46
  7. package/bundled/dev-pipeline/scripts/generate-bugfix-prompt.py +7 -12
  8. package/bundled/dev-pipeline/scripts/generate-refactor-prompt.py +124 -20
  9. package/bundled/dev-pipeline/scripts/utils.py +20 -0
  10. package/bundled/dev-pipeline/templates/agent-prompts/dev-implement.md +13 -7
  11. package/bundled/dev-pipeline/templates/bootstrap-tier1.md +62 -66
  12. package/bundled/dev-pipeline/templates/bootstrap-tier2.md +37 -40
  13. package/bundled/dev-pipeline/templates/bootstrap-tier3.md +35 -48
  14. package/bundled/dev-pipeline/templates/bugfix-bootstrap-prompt.md +135 -182
  15. package/bundled/dev-pipeline/templates/feature-list-schema.json +6 -21
  16. package/bundled/dev-pipeline/templates/refactor-bootstrap-prompt.md +9 -9
  17. package/bundled/dev-pipeline/templates/sections/context-budget-rules.md +1 -1
  18. package/bundled/dev-pipeline/templates/sections/feature-context.md +4 -0
  19. package/bundled/dev-pipeline/templates/sections/phase-browser-verification.md +41 -24
  20. package/bundled/dev-pipeline/templates/sections/phase-commit-full.md +4 -12
  21. package/bundled/dev-pipeline/templates/sections/phase-deploy-verification.md +9 -17
  22. package/bundled/dev-pipeline/templates/sections/phase-implement-lite.md +1 -1
  23. package/bundled/dev-pipeline/templates/sections/phase-plan-agent.md +3 -2
  24. package/bundled/dev-pipeline/templates/sections/phase-plan-lite.md +4 -2
  25. package/bundled/dev-pipeline/templates/sections/phase-specify-plan-full.md +0 -18
  26. package/bundled/dev-pipeline/templates/sections/session-context.md +1 -2
  27. package/bundled/dev-pipeline/templates/sections/test-failure-recovery-agent.md +75 -0
  28. package/bundled/dev-pipeline/templates/sections/test-failure-recovery-lite.md +66 -0
  29. package/bundled/skills/_metadata.json +1 -1
  30. package/bundled/skills/bugfix-pipeline-launcher/SKILL.md +3 -8
  31. package/bundled/skills/feature-pipeline-launcher/SKILL.md +4 -16
  32. package/bundled/skills/feature-planner/SKILL.md +8 -4
  33. package/bundled/skills/feature-planner/assets/planning-guide.md +16 -11
  34. package/bundled/skills/feature-planner/references/browser-interaction.md +9 -8
  35. package/bundled/skills/feature-planner/references/completeness-review.md +1 -1
  36. package/bundled/skills/feature-planner/references/error-recovery.md +1 -1
  37. package/bundled/skills/feature-planner/references/incremental-feature-planning.md +1 -1
  38. package/bundled/skills/feature-planner/scripts/validate-and-generate.py +10 -7
  39. package/bundled/skills/feature-workflow/SKILL.md +61 -34
  40. package/bundled/skills/prizmkit-retrospective/references/structural-sync-steps.md +3 -7
  41. package/bundled/skills/recovery-workflow/SKILL.md +3 -3
  42. package/bundled/skills/refactor-pipeline-launcher/SKILL.md +4 -15
  43. package/bundled/skills/refactor-workflow/SKILL.md +72 -66
  44. package/package.json +1 -1
  45. package/bundled/dev-pipeline/retry-bugfix.sh +0 -429
  46. package/bundled/dev-pipeline/retry-feature.sh +0 -445
  47. package/bundled/dev-pipeline/retry-refactor.sh +0 -441
  48. package/bundled/dev-pipeline/templates/sections/failure-log-check.md +0 -9
  49. package/bundled/dev-pipeline/templates/sections/resume-header.md +0 -5
  50. package/bundled/dev-pipeline/templates/sections/test-failure-recovery.md +0 -75
@@ -1,5 +1,5 @@
1
1
  {
2
- "frameworkVersion": "1.1.10",
3
- "bundledAt": "2026-04-08T15:25:57.526Z",
4
- "bundledFrom": "a243cb1"
2
+ "frameworkVersion": "1.1.13",
3
+ "bundledAt": "2026-04-09T09:50:44.583Z",
4
+ "bundledFrom": "fea93ab"
5
5
  }
@@ -80,33 +80,7 @@ If `.prizmkit/plans/feature-list.json` path is omitted, defaults to `.prizmkit/p
80
80
 
81
81
  ---
82
82
 
83
- ### `retry-feature.sh` — Retry Single Failed Feature
84
-
85
- Runs exactly ONE AI CLI session for a specified feature, then exits.
86
-
87
- ```bash
88
- ./retry-feature.sh <feature-id> [.prizmkit/plans/feature-list.json]
89
- ```
90
-
91
- **What it does:**
92
- 1. Cleans feature artifacts for a fresh restart
93
- 2. Generates a fresh bootstrap prompt
94
- 3. Runs exactly one AI CLI session with heartbeat monitoring
95
- 4. Updates feature status based on the result
96
- 5. Exits (does not continue to other features)
97
-
98
- **Examples:**
99
-
100
- ```bash
101
- ./dev-pipeline/retry-feature.sh F-007
102
- ./dev-pipeline/retry-feature.sh F-007 .prizmkit/plans/feature-list.json
103
- SESSION_TIMEOUT=7200 ./dev-pipeline/retry-feature.sh F-007
104
- MODEL=claude-opus-4.6 ./dev-pipeline/retry-feature.sh F-007
105
- ```
106
-
107
- ---
108
-
109
- ### `reset-feature.sh` — Reset Failed/Stuck Feature
83
+ ### `reset-feature.sh` — Reset & Retry Failed/Stuck Feature
110
84
 
111
85
  Resets a feature's state so it can be re-executed from scratch.
112
86
 
@@ -117,7 +91,7 @@ Resets a feature's state so it can be re-executed from scratch.
117
91
  | Flag | Description |
118
92
  |------|-------------|
119
93
  | `--clean` | Delete session history + `.prizmkit/specs/{slug}/` artifacts |
120
- | `--run` | Immediately retry after reset (calls `retry-feature.sh`) |
94
+ | `--run` | Immediately run after reset |
121
95
 
122
96
  **What gets cleaned with `--clean`:**
123
97
  - `state/features/F-XXX/sessions/` — all session logs and prompts
@@ -209,16 +183,6 @@ Processes bugs by: **severity** (critical > high > medium > low) then **priority
209
183
 
210
184
  ---
211
185
 
212
- ### `retry-bugfix.sh` — Retry Single Failed Bug
213
-
214
- ```bash
215
- ./retry-bugfix.sh <bug-id> [.prizmkit/plans/bug-fix-list.json]
216
- ```
217
-
218
- Same behavior as `retry-feature.sh` but for bugs. Cleans bug artifacts, generates bugfix prompt, runs one session, updates status.
219
-
220
- ---
221
-
222
186
  ### `launch-bugfix-daemon.sh` — Bug-Fix Pipeline Daemon
223
187
 
224
188
  Identical interface to `launch-feature-daemon.sh` but manages `run-bugfix.sh` in background.
@@ -325,7 +289,7 @@ python3 scripts/generate-bootstrap-prompt.py \
325
289
  { "success": true, "output_path": "/absolute/path/prompt.md", "model": "claude-sonnet-4.6" }
326
290
  ```
327
291
 
328
- The `model` field is extracted from the feature's `"model"` field in .prizmkit/plans/feature-list.json (empty string if not specified). Used by `run-feature.sh` and `retry-feature.sh` to set `--model` on the AI CLI.
292
+ The `model` field is extracted from the feature's `"model"` field in .prizmkit/plans/feature-list.json (empty string if not specified). Used by `run-feature.sh` to set `--model` on the AI CLI.
329
293
 
330
294
  **Conditional blocks resolved:**
331
295
  - `{{IF_RESUME}}` / `{{IF_FRESH_START}}` — Resume vs fresh start
@@ -569,7 +533,7 @@ Also exports: `log_info`, `log_warn`, `log_error`, `log_success` (with timestamp
569
533
  | Variable | Default | Used By | Description |
570
534
  |----------|---------|---------|-------------|
571
535
  | `MAX_RETRIES` | `3` | run-feature.sh | Max retry attempts per feature before marking as failed |
572
- | `SESSION_TIMEOUT` | `0` (none) | run-feature.sh, retry-feature.sh, run-bugfix.sh, retry-bugfix.sh | Timeout in seconds per AI CLI session. 0 = no timeout |
536
+ | `SESSION_TIMEOUT` | `0` (none) | run-feature.sh, run-bugfix.sh | Timeout in seconds per AI CLI session. 0 = no timeout |
573
537
  | `PIPELINE_MODE` | (auto) | run-feature.sh, launch-feature-daemon.sh | Override mode for all features: `lite\|standard\|full` |
574
538
  | `ENABLE_CRITIC` | `false` | run-feature.sh, launch-feature-daemon.sh | Enable adversarial critic review: `true\|false` |
575
539
  | `DEV_BRANCH` | auto-generated | run-feature.sh | Custom git branch name (default: `dev/{feature-id}-{timestamp}`) |
@@ -581,15 +545,15 @@ Also exports: `log_info`, `log_warn`, `log_error`, `log_success` (with timestamp
581
545
  |----------|---------|---------|-------------|
582
546
  | `AI_CLI` | auto-detect | all shell scripts | AI CLI command name. Auto-detects `cbc` or `claude` |
583
547
  | `PRIZMKIT_PLATFORM` | auto-detect | all shell scripts | Force platform: `codebuddy` or `claude` |
584
- | `MODEL` | (none) | run-feature.sh, retry-feature.sh, run-bugfix.sh, retry-bugfix.sh | AI model fallback. Overridden by per-feature `model` field. See [Model Selection](#model-selection) |
548
+ | `MODEL` | (none) | run-feature.sh, run-bugfix.sh | AI model fallback. Overridden by per-feature `model` field. See [Model Selection](#model-selection) |
585
549
  | `CODEBUDDY_CLI` | (deprecated) | all shell scripts | Legacy alias for `AI_CLI`. Prefer `AI_CLI` |
586
- | `VERBOSE` | `0` | run-feature.sh, retry-feature.sh | Set to `1` to enable `--verbose` on AI CLI |
550
+ | `VERBOSE` | `0` | run-feature.sh | Set to `1` to enable `--verbose` on AI CLI |
587
551
 
588
552
  ### Monitoring & Logging
589
553
 
590
554
  | Variable | Default | Used By | Description |
591
555
  |----------|---------|---------|-------------|
592
- | `HEARTBEAT_INTERVAL` | `30` | run-feature.sh, retry-feature.sh | Seconds between heartbeat log output |
556
+ | `HEARTBEAT_INTERVAL` | `30` | run-feature.sh | Seconds between heartbeat log output |
593
557
  | `HEARTBEAT_STALE_THRESHOLD` | `600` | run-feature.sh | Seconds before a session is considered stale/stuck |
594
558
  | `LOG_CLEANUP_ENABLED` | `1` | run-feature.sh | Run log cleanup before pipeline execution |
595
559
  | `LOG_RETENTION_DAYS` | `14` | run-feature.sh | Delete logs older than N days |
@@ -643,7 +607,7 @@ Specify a model for individual features in `.prizmkit/plans/feature-list.json`:
643
607
  MODEL=claude-sonnet-4.6 ./dev-pipeline/run-feature.sh run .prizmkit/plans/feature-list.json
644
608
 
645
609
  # Retry with Opus
646
- MODEL=claude-opus-4.6 ./dev-pipeline/retry-feature.sh F-007
610
+ MODEL=claude-opus-4.6 ./dev-pipeline/reset-feature.sh F-007 --clean --run
647
611
 
648
612
  # Test which model the CLI is using
649
613
  MODEL=claude-sonnet-4.6 ./dev-pipeline/run-feature.sh test-cli
@@ -890,11 +854,11 @@ run-bugfix.sh main loop
890
854
  ```
891
855
  dev-pipeline/
892
856
  +-- run-feature.sh # Main pipeline runner (features)
893
- +-- retry-feature.sh # Retry single failed feature
857
+ +-- reset-feature.sh # Reset & retry failed feature
894
858
  +-- reset-feature.sh # Reset/clean feature for re-execution
895
859
  +-- launch-feature-daemon.sh # Background daemon for feature pipeline
896
860
  +-- run-bugfix.sh # Bug-fix pipeline runner
897
- +-- retry-bugfix.sh # Retry single failed bug
861
+ +-- reset-bugfix.sh # Reset & retry failed bug
898
862
  +-- launch-bugfix-daemon.sh # Background daemon for bugfix pipeline
899
863
  +-- README.md # This file
900
864
  +-- .gitignore # Ignores .prizmkit/state/, __pycache__/
@@ -4,8 +4,12 @@ set -euo pipefail
4
4
  # ============================================================
5
5
  # dev-pipeline/reset-bug.sh - Reset a failed/stuck bug fix
6
6
  #
7
- # Clears all state and artifacts for a bug so it can be
8
- # re-executed from scratch by the pipeline.
7
+ # Resets status and discards uncommitted working tree changes on
8
+ # the bugfix branch, then returns to the original branch. Session
9
+ # history and .prizmkit artifacts are preserved for debugging.
10
+ #
11
+ # With --clean, also deletes session history, .prizmkit/bugfix/
12
+ # artifacts, and the bugfix branch itself.
9
13
  #
10
14
  # Usage:
11
15
  # ./reset-bug.sh <bug-id|range> [options] [.prizmkit/plans/bug-fix-list.json]
@@ -18,12 +22,18 @@ set -euo pipefail
18
22
  # --stalled All non-completed bugs (failed + auto_skipped)
19
23
  #
20
24
  # Options:
21
- # --clean Also delete session history and .prizmkit/bugfix/{BUG_ID}/ artifacts
25
+ # --clean Also delete session history, .prizmkit/bugfix/{BUG_ID}/ artifacts, and bugfix branch
22
26
  # --run After reset, immediately retry via pipeline (only with single bug)
23
27
  #
28
+ # Normal reset (no --clean):
29
+ # - Resets status → pending, retry_count → 0
30
+ # - Discards uncommitted changes on bugfix branch (git checkout -- . && git clean -fd)
31
+ # - Returns to default branch (main/master)
32
+ # - Preserves bugfix branch, session history, and .prizmkit artifacts for debugging
33
+ #
24
34
  # Examples:
25
- # ./reset-bug.sh B-007 # Reset status only
26
- # ./reset-bug.sh B-007 --clean # Reset + delete artifacts
35
+ # ./reset-bug.sh B-007 # Reset status + discard changes
36
+ # ./reset-bug.sh B-007 --clean # Reset + delete everything
27
37
  # ./reset-bug.sh B-008:B-013 --clean # Reset range
28
38
  # ./reset-bug.sh --auto-skipped # Reset all auto_skipped
29
39
  # ./reset-bug.sh --failed --clean # Reset all failed + clean
@@ -76,7 +86,7 @@ for arg in "$@"; do
76
86
  echo " --auto-skipped Reset all auto_skipped bugs"
77
87
  echo " --failed Reset all failed bugs"
78
88
  echo " --stalled Reset all non-completed (failed + auto_skipped)"
79
- echo " --clean Delete session history and .prizmkit artifacts"
89
+ echo " --clean Delete session history, .prizmkit artifacts, and bugfix branch"
80
90
  echo " --run Retry immediately after reset (single bug only)"
81
91
  echo " .prizmkit/plans/bug-fix-list.json Path to bug fix list (default: .prizmkit/plans/bug-fix-list.json)"
82
92
  exit 0
@@ -194,6 +204,18 @@ PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
194
204
  RESET_COUNT=0
195
205
  FAIL_COUNT=0
196
206
 
207
+ # Detect default branch (main or master)
208
+ DEFAULT_BRANCH=$(git -C "$PROJECT_ROOT" symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@' || echo "")
209
+ if [[ -z "$DEFAULT_BRANCH" ]]; then
210
+ if git -C "$PROJECT_ROOT" rev-parse --verify main >/dev/null 2>&1; then
211
+ DEFAULT_BRANCH="main"
212
+ elif git -C "$PROJECT_ROOT" rev-parse --verify master >/dev/null 2>&1; then
213
+ DEFAULT_BRANCH="master"
214
+ else
215
+ DEFAULT_BRANCH=$(git -C "$PROJECT_ROOT" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "main")
216
+ fi
217
+ fi
218
+
197
219
  for CUR_BUG_ID in "${BUG_IDS[@]}"; do
198
220
 
199
221
  # Get bug info from bug fix list
@@ -247,6 +269,58 @@ sys.exit(1)
247
269
 
248
270
  echo -e "${BOLD}════════════════════════════════════════════════════${NC}"
249
271
 
272
+ # ── Git cleanup: discard dev branch changes ──
273
+ # Find dev branches matching this bug (pattern: bugfix/{BUG_ID}-*)
274
+ DEV_BRANCHES=$(git -C "$PROJECT_ROOT" branch --list "bugfix/${CUR_BUG_ID}-*" 2>/dev/null | sed 's/^[* ]*//')
275
+ CURRENT_BRANCH=$(git -C "$PROJECT_ROOT" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "")
276
+
277
+ if [[ -n "$DEV_BRANCHES" ]]; then
278
+ while IFS= read -r branch; do
279
+ [[ -z "$branch" ]] && continue
280
+ if [[ "$CURRENT_BRANCH" == "$branch" ]]; then
281
+ # We're on the dev branch — discard uncommitted changes and return to default
282
+ log_info "Discarding uncommitted changes on dev branch: $branch"
283
+ git -C "$PROJECT_ROOT" reset HEAD 2>/dev/null || true
284
+ git -C "$PROJECT_ROOT" checkout -- . 2>/dev/null || true
285
+ git -C "$PROJECT_ROOT" clean -fd 2>/dev/null || true
286
+ log_info "Switching to $DEFAULT_BRANCH..."
287
+ if ! git -C "$PROJECT_ROOT" checkout "$DEFAULT_BRANCH" 2>/dev/null; then
288
+ log_warn "Failed to checkout $DEFAULT_BRANCH — staying on $branch"
289
+ else
290
+ CURRENT_BRANCH="$DEFAULT_BRANCH"
291
+ fi
292
+ else
293
+ # Not on the dev branch — discard its uncommitted changes
294
+ _stashed=false
295
+ _dirty=""
296
+ _dirty=$(git -C "$PROJECT_ROOT" status --porcelain 2>/dev/null || true)
297
+ if [[ -n "$_dirty" ]]; then
298
+ git -C "$PROJECT_ROOT" stash push --include-untracked -m "reset-bug-temp" 2>/dev/null && _stashed=true
299
+ fi
300
+ if git -C "$PROJECT_ROOT" checkout "$branch" 2>/dev/null; then
301
+ log_info "Discarding uncommitted changes on dev branch: $branch"
302
+ git -C "$PROJECT_ROOT" reset HEAD 2>/dev/null || true
303
+ git -C "$PROJECT_ROOT" checkout -- . 2>/dev/null || true
304
+ git -C "$PROJECT_ROOT" clean -fd 2>/dev/null || true
305
+ git -C "$PROJECT_ROOT" checkout "$CURRENT_BRANCH" 2>/dev/null || true
306
+ else
307
+ log_warn "Could not checkout $branch to discard changes"
308
+ fi
309
+ [[ "$_stashed" == true ]] && git -C "$PROJECT_ROOT" stash pop 2>/dev/null || true
310
+ fi
311
+ # Only delete the dev branch in --clean mode
312
+ if [[ "$DO_CLEAN" == true ]]; then
313
+ if git -C "$PROJECT_ROOT" branch -D "$branch" 2>/dev/null; then
314
+ log_success "Deleted dev branch: $branch"
315
+ else
316
+ log_warn "Failed to delete branch: $branch"
317
+ fi
318
+ else
319
+ log_info "Dev branch preserved for debugging: $branch"
320
+ fi
321
+ done <<< "$DEV_BRANCHES"
322
+ fi
323
+
250
324
  # -- Execute reset --
251
325
  if [[ "$DO_CLEAN" == true ]]; then
252
326
  log_info "Cleaning $CUR_BUG_ID (reset + delete artifacts)..."
@@ -269,9 +343,9 @@ sys.exit(1)
269
343
  if echo "$RESULT" | python3 -c "import sys,json; d=json.load(sys.stdin); sys.exit(0 if 'error' not in d else 1)" 2>/dev/null; then
270
344
  RESET_COUNT=$((RESET_COUNT + 1))
271
345
  if [[ "$DO_CLEAN" == true ]]; then
272
- log_success "$CUR_BUG_ID cleaned: status -> pending, $SESSIONS_COUNT session(s) deleted, $BUGFIX_COUNT artifact(s) deleted"
346
+ log_success "$CUR_BUG_ID cleaned: status -> pending, $SESSIONS_COUNT session(s) deleted, $BUGFIX_COUNT artifact(s) deleted, dev branch deleted"
273
347
  else
274
- log_success "$CUR_BUG_ID reset: status -> pending, retry count -> 0"
348
+ log_success "$CUR_BUG_ID reset: status -> pending, retry count -> 0, dev branch discarded"
275
349
  fi
276
350
  else
277
351
  ERROR_MSG=$(echo "$RESULT" | python3 -c "import sys,json; print(json.load(sys.stdin).get('error','unknown'))" 2>/dev/null || echo "$RESULT")
@@ -295,11 +369,11 @@ echo -e "${BOLD}Next steps:${NC}"
295
369
  if [[ "$DO_RUN" == true && ${#BUG_IDS[@]} -eq 1 ]]; then
296
370
  log_info "Auto-retrying ${BUG_IDS[0]}..."
297
371
  echo ""
298
- exec "$SCRIPT_DIR/retry-bugfix.sh" "${BUG_IDS[0]}" "$BUG_LIST"
372
+ exec "$SCRIPT_DIR/run-bugfix.sh" run "${BUG_IDS[0]}" "$BUG_LIST"
299
373
  else
300
374
  log_info " ./dev-pipeline/run-bugfix.sh run .prizmkit/plans/bug-fix-list.json # Resume pipeline from first pending"
301
375
  if [[ ${#BUG_IDS[@]} -eq 1 ]]; then
302
- log_info " ./dev-pipeline/retry-bugfix.sh ${BUG_IDS[0]} # Retry single bug"
376
+ log_info " ./dev-pipeline/run-bugfix.sh run ${BUG_IDS[0]} # Run single bug"
303
377
  fi
304
378
  fi
305
379
  echo ""
@@ -4,8 +4,12 @@ set -euo pipefail
4
4
  # ============================================================
5
5
  # dev-pipeline/reset-feature.sh - Reset a failed/stuck feature
6
6
  #
7
- # Clears all state and artifacts for a feature so it can be
8
- # re-executed from scratch by the pipeline.
7
+ # Resets status and discards uncommitted working tree changes on
8
+ # the dev branch, then returns to the original branch. Session
9
+ # history and .prizmkit artifacts are preserved for debugging.
10
+ #
11
+ # With --clean, also deletes session history, .prizmkit/specs/
12
+ # artifacts, and the dev branch itself.
9
13
  #
10
14
  # Usage:
11
15
  # ./reset-feature.sh <feature-id|range> [options] [.prizmkit/plans/feature-list.json]
@@ -18,12 +22,18 @@ set -euo pipefail
18
22
  # --stalled All non-completed features (failed + auto_skipped)
19
23
  #
20
24
  # Options:
21
- # --clean Also delete session history and .prizmkit/specs/{slug}/ artifacts
25
+ # --clean Also delete session history, .prizmkit/specs/{slug}/ artifacts, and dev branch
22
26
  # --run After reset, immediately retry via pipeline (only with single feature)
23
27
  #
28
+ # Normal reset (no --clean):
29
+ # - Resets status → pending, retry_count → 0
30
+ # - Discards uncommitted changes on dev branch (git checkout -- . && git clean -fd)
31
+ # - Returns to default branch (main/master)
32
+ # - Preserves dev branch, session history, and .prizmkit artifacts for debugging
33
+ #
24
34
  # Examples:
25
- # ./reset-feature.sh F-007 # Reset status only
26
- # ./reset-feature.sh F-007 --clean # Reset + delete artifacts
35
+ # ./reset-feature.sh F-007 # Reset status + discard changes
36
+ # ./reset-feature.sh F-007 --clean # Reset + delete everything
27
37
  # ./reset-feature.sh F-008:F-013 --clean # Reset range
28
38
  # ./reset-feature.sh --auto-skipped # Reset all auto_skipped
29
39
  # ./reset-feature.sh --failed --clean # Reset all failed + clean
@@ -76,7 +86,7 @@ for arg in "$@"; do
76
86
  echo " --auto-skipped Reset all auto_skipped features"
77
87
  echo " --failed Reset all failed features"
78
88
  echo " --stalled Reset all non-completed (failed + auto_skipped)"
79
- echo " --clean Delete session history and .prizmkit artifacts"
89
+ echo " --clean Delete session history, .prizmkit artifacts, and dev branch"
80
90
  echo " --run Retry immediately after reset (single feature only)"
81
91
  echo " .prizmkit/plans/feature-list.json Path to feature list (default: .prizmkit/plans/feature-list.json)"
82
92
  exit 0
@@ -194,6 +204,19 @@ PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
194
204
  RESET_COUNT=0
195
205
  FAIL_COUNT=0
196
206
 
207
+ # Detect default branch (main or master)
208
+ DEFAULT_BRANCH=$(git -C "$PROJECT_ROOT" symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@' || echo "")
209
+ if [[ -z "$DEFAULT_BRANCH" ]]; then
210
+ # Fallback: check if main or master exists
211
+ if git -C "$PROJECT_ROOT" rev-parse --verify main >/dev/null 2>&1; then
212
+ DEFAULT_BRANCH="main"
213
+ elif git -C "$PROJECT_ROOT" rev-parse --verify master >/dev/null 2>&1; then
214
+ DEFAULT_BRANCH="master"
215
+ else
216
+ DEFAULT_BRANCH=$(git -C "$PROJECT_ROOT" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "main")
217
+ fi
218
+ fi
219
+
197
220
  for CUR_FEATURE_ID in "${FEATURE_IDS[@]}"; do
198
221
 
199
222
  # Get feature info from feature list
@@ -255,6 +278,59 @@ sys.exit(1)
255
278
 
256
279
  echo -e "${BOLD}════════════════════════════════════════════════════${NC}"
257
280
 
281
+ # ── Git cleanup: discard dev branch changes ──
282
+ # Find dev branches matching this feature (pattern: dev/{FEATURE_ID}-*)
283
+ DEV_BRANCHES=$(git -C "$PROJECT_ROOT" branch --list "dev/${CUR_FEATURE_ID}-*" 2>/dev/null | sed 's/^[* ]*//')
284
+ CURRENT_BRANCH=$(git -C "$PROJECT_ROOT" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "")
285
+
286
+ if [[ -n "$DEV_BRANCHES" ]]; then
287
+ while IFS= read -r branch; do
288
+ [[ -z "$branch" ]] && continue
289
+ if [[ "$CURRENT_BRANCH" == "$branch" ]]; then
290
+ # We're on the dev branch — discard uncommitted changes and return to default
291
+ log_info "Discarding uncommitted changes on dev branch: $branch"
292
+ git -C "$PROJECT_ROOT" reset HEAD 2>/dev/null || true
293
+ git -C "$PROJECT_ROOT" checkout -- . 2>/dev/null || true
294
+ git -C "$PROJECT_ROOT" clean -fd 2>/dev/null || true
295
+ log_info "Switching to $DEFAULT_BRANCH..."
296
+ if ! git -C "$PROJECT_ROOT" checkout "$DEFAULT_BRANCH" 2>/dev/null; then
297
+ log_warn "Failed to checkout $DEFAULT_BRANCH — staying on $branch"
298
+ else
299
+ CURRENT_BRANCH="$DEFAULT_BRANCH"
300
+ fi
301
+ else
302
+ # Not on the dev branch — discard its uncommitted changes
303
+ # Temporarily switch, discard, switch back
304
+ _stashed=false
305
+ _dirty=""
306
+ _dirty=$(git -C "$PROJECT_ROOT" status --porcelain 2>/dev/null || true)
307
+ if [[ -n "$_dirty" ]]; then
308
+ git -C "$PROJECT_ROOT" stash push --include-untracked -m "reset-feature-temp" 2>/dev/null && _stashed=true
309
+ fi
310
+ if git -C "$PROJECT_ROOT" checkout "$branch" 2>/dev/null; then
311
+ log_info "Discarding uncommitted changes on dev branch: $branch"
312
+ git -C "$PROJECT_ROOT" reset HEAD 2>/dev/null || true
313
+ git -C "$PROJECT_ROOT" checkout -- . 2>/dev/null || true
314
+ git -C "$PROJECT_ROOT" clean -fd 2>/dev/null || true
315
+ git -C "$PROJECT_ROOT" checkout "$CURRENT_BRANCH" 2>/dev/null || true
316
+ else
317
+ log_warn "Could not checkout $branch to discard changes"
318
+ fi
319
+ [[ "$_stashed" == true ]] && git -C "$PROJECT_ROOT" stash pop 2>/dev/null || true
320
+ fi
321
+ # Only delete the dev branch in --clean mode
322
+ if [[ "$DO_CLEAN" == true ]]; then
323
+ if git -C "$PROJECT_ROOT" branch -D "$branch" 2>/dev/null; then
324
+ log_success "Deleted dev branch: $branch"
325
+ else
326
+ log_warn "Failed to delete branch: $branch"
327
+ fi
328
+ else
329
+ log_info "Dev branch preserved for debugging: $branch"
330
+ fi
331
+ done <<< "$DEV_BRANCHES"
332
+ fi
333
+
258
334
  # ── Execute reset ──
259
335
  if [[ "$DO_CLEAN" == true ]]; then
260
336
  log_info "Cleaning $CUR_FEATURE_ID (reset + delete artifacts)..."
@@ -278,9 +354,9 @@ sys.exit(1)
278
354
  if echo "$RESULT" | python3 -c "import sys,json; d=json.load(sys.stdin); sys.exit(0 if 'error' not in d else 1)" 2>/dev/null; then
279
355
  RESET_COUNT=$((RESET_COUNT + 1))
280
356
  if [[ "$DO_CLEAN" == true ]]; then
281
- log_success "$CUR_FEATURE_ID cleaned: status → pending, $SESSIONS_COUNT session(s) deleted, $SPECS_COUNT artifact(s) deleted"
357
+ log_success "$CUR_FEATURE_ID cleaned: status → pending, $SESSIONS_COUNT session(s) deleted, $SPECS_COUNT artifact(s) deleted, dev branch deleted"
282
358
  else
283
- log_success "$CUR_FEATURE_ID reset: status → pending, retry count → 0"
359
+ log_success "$CUR_FEATURE_ID reset: status → pending, retry count → 0, dev branch discarded"
284
360
  fi
285
361
  else
286
362
  ERROR_MSG=$(echo "$RESULT" | python3 -c "import sys,json; print(json.load(sys.stdin).get('error','unknown'))" 2>/dev/null || echo "$RESULT")
@@ -304,11 +380,11 @@ echo -e "${BOLD}Next steps:${NC}"
304
380
  if [[ "$DO_RUN" == true && ${#FEATURE_IDS[@]} -eq 1 ]]; then
305
381
  log_info "Auto-retrying ${FEATURE_IDS[0]}..."
306
382
  echo ""
307
- exec "$SCRIPT_DIR/retry-feature.sh" "${FEATURE_IDS[0]}" "$FEATURE_LIST"
383
+ exec "$SCRIPT_DIR/run-feature.sh" run "${FEATURE_IDS[0]}" "$FEATURE_LIST"
308
384
  else
309
385
  log_info " ./dev-pipeline/run-feature.sh run .prizmkit/plans/feature-list.json # Resume pipeline from first pending"
310
386
  if [[ ${#FEATURE_IDS[@]} -eq 1 ]]; then
311
- log_info " ./dev-pipeline/retry-feature.sh ${FEATURE_IDS[0]} # Retry single feature"
387
+ log_info " ./dev-pipeline/run-feature.sh run ${FEATURE_IDS[0]} # Run single feature"
312
388
  fi
313
389
  fi
314
390
  echo ""
@@ -194,6 +194,18 @@ PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
194
194
  RESET_COUNT=0
195
195
  FAIL_COUNT=0
196
196
 
197
+ # Detect default branch (main or master)
198
+ DEFAULT_BRANCH=$(git -C "$PROJECT_ROOT" symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@' || echo "")
199
+ if [[ -z "$DEFAULT_BRANCH" ]]; then
200
+ if git -C "$PROJECT_ROOT" rev-parse --verify main >/dev/null 2>&1; then
201
+ DEFAULT_BRANCH="main"
202
+ elif git -C "$PROJECT_ROOT" rev-parse --verify master >/dev/null 2>&1; then
203
+ DEFAULT_BRANCH="master"
204
+ else
205
+ DEFAULT_BRANCH=$(git -C "$PROJECT_ROOT" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "main")
206
+ fi
207
+ fi
208
+
197
209
  for CUR_REFACTOR_ID in "${REFACTOR_IDS[@]}"; do
198
210
 
199
211
  # Get refactor info from refactor list
@@ -255,6 +267,58 @@ sys.exit(1)
255
267
 
256
268
  echo -e "${BOLD}════════════════════════════════════════════════════${NC}"
257
269
 
270
+ # ── Git cleanup: discard dev branch changes ──
271
+ # Find dev branches matching this refactor (pattern: refactor/{REFACTOR_ID}-*)
272
+ DEV_BRANCHES=$(git -C "$PROJECT_ROOT" branch --list "refactor/${CUR_REFACTOR_ID}-*" 2>/dev/null | sed 's/^[* ]*//')
273
+ CURRENT_BRANCH=$(git -C "$PROJECT_ROOT" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "")
274
+
275
+ if [[ -n "$DEV_BRANCHES" ]]; then
276
+ while IFS= read -r branch; do
277
+ [[ -z "$branch" ]] && continue
278
+ if [[ "$CURRENT_BRANCH" == "$branch" ]]; then
279
+ # We're on the dev branch — discard uncommitted changes and return to default
280
+ log_info "Discarding uncommitted changes on dev branch: $branch"
281
+ git -C "$PROJECT_ROOT" reset HEAD 2>/dev/null || true
282
+ git -C "$PROJECT_ROOT" checkout -- . 2>/dev/null || true
283
+ git -C "$PROJECT_ROOT" clean -fd 2>/dev/null || true
284
+ log_info "Switching to $DEFAULT_BRANCH..."
285
+ if ! git -C "$PROJECT_ROOT" checkout "$DEFAULT_BRANCH" 2>/dev/null; then
286
+ log_warn "Failed to checkout $DEFAULT_BRANCH — staying on $branch"
287
+ else
288
+ CURRENT_BRANCH="$DEFAULT_BRANCH"
289
+ fi
290
+ else
291
+ # Not on the dev branch — discard its uncommitted changes
292
+ _stashed=false
293
+ _dirty=""
294
+ _dirty=$(git -C "$PROJECT_ROOT" status --porcelain 2>/dev/null || true)
295
+ if [[ -n "$_dirty" ]]; then
296
+ git -C "$PROJECT_ROOT" stash push --include-untracked -m "reset-refactor-temp" 2>/dev/null && _stashed=true
297
+ fi
298
+ if git -C "$PROJECT_ROOT" checkout "$branch" 2>/dev/null; then
299
+ log_info "Discarding uncommitted changes on dev branch: $branch"
300
+ git -C "$PROJECT_ROOT" reset HEAD 2>/dev/null || true
301
+ git -C "$PROJECT_ROOT" checkout -- . 2>/dev/null || true
302
+ git -C "$PROJECT_ROOT" clean -fd 2>/dev/null || true
303
+ git -C "$PROJECT_ROOT" checkout "$CURRENT_BRANCH" 2>/dev/null || true
304
+ else
305
+ log_warn "Could not checkout $branch to discard changes"
306
+ fi
307
+ [[ "$_stashed" == true ]] && git -C "$PROJECT_ROOT" stash pop 2>/dev/null || true
308
+ fi
309
+ # Only delete the dev branch in --clean mode
310
+ if [[ "$DO_CLEAN" == true ]]; then
311
+ if git -C "$PROJECT_ROOT" branch -D "$branch" 2>/dev/null; then
312
+ log_success "Deleted dev branch: $branch"
313
+ else
314
+ log_warn "Failed to delete branch: $branch"
315
+ fi
316
+ else
317
+ log_info "Dev branch preserved for debugging: $branch"
318
+ fi
319
+ done <<< "$DEV_BRANCHES"
320
+ fi
321
+
258
322
  # -- Execute reset --
259
323
  if [[ "$DO_CLEAN" == true ]]; then
260
324
  log_info "Cleaning $CUR_REFACTOR_ID (reset + delete artifacts)..."
@@ -277,9 +341,9 @@ sys.exit(1)
277
341
  if echo "$RESULT" | python3 -c "import sys,json; d=json.load(sys.stdin); sys.exit(0 if 'error' not in d else 1)" 2>/dev/null; then
278
342
  RESET_COUNT=$((RESET_COUNT + 1))
279
343
  if [[ "$DO_CLEAN" == true ]]; then
280
- log_success "$CUR_REFACTOR_ID cleaned: status -> pending, $SESSIONS_COUNT session(s) deleted, $SPECS_COUNT artifact(s) deleted"
344
+ log_success "$CUR_REFACTOR_ID cleaned: status -> pending, $SESSIONS_COUNT session(s) deleted, $SPECS_COUNT artifact(s) deleted, dev branch deleted"
281
345
  else
282
- log_success "$CUR_REFACTOR_ID reset: status -> pending, retry count -> 0"
346
+ log_success "$CUR_REFACTOR_ID reset: status -> pending, retry count -> 0, dev branch discarded"
283
347
  fi
284
348
  else
285
349
  ERROR_MSG=$(echo "$RESULT" | python3 -c "import sys,json; print(json.load(sys.stdin).get('error','unknown'))" 2>/dev/null || echo "$RESULT")
@@ -303,11 +367,11 @@ echo -e "${BOLD}Next steps:${NC}"
303
367
  if [[ "$DO_RUN" == true && ${#REFACTOR_IDS[@]} -eq 1 ]]; then
304
368
  log_info "Auto-retrying ${REFACTOR_IDS[0]}..."
305
369
  echo ""
306
- exec "$SCRIPT_DIR/retry-refactor.sh" "${REFACTOR_IDS[0]}" "$REFACTOR_LIST"
370
+ exec "$SCRIPT_DIR/run-refactor.sh" run "${REFACTOR_IDS[0]}" "$REFACTOR_LIST"
307
371
  else
308
372
  log_info " ./dev-pipeline/run-refactor.sh run .prizmkit/plans/refactor-list.json # Resume pipeline from first pending"
309
373
  if [[ ${#REFACTOR_IDS[@]} -eq 1 ]]; then
310
- log_info " ./dev-pipeline/retry-refactor.sh ${REFACTOR_IDS[0]} # Retry single refactor"
374
+ log_info " ./dev-pipeline/run-refactor.sh run ${REFACTOR_IDS[0]} # Run single refactor"
311
375
  fi
312
376
  fi
313
377
  echo ""