prizmkit 1.1.9 → 1.1.12
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/bundled/VERSION.json +3 -3
- package/bundled/dev-pipeline/README.md +10 -46
- package/bundled/dev-pipeline/reset-bug.sh +84 -10
- package/bundled/dev-pipeline/reset-feature.sh +86 -10
- package/bundled/dev-pipeline/reset-refactor.sh +68 -4
- package/bundled/dev-pipeline/scripts/generate-bootstrap-prompt.py +47 -46
- package/bundled/dev-pipeline/scripts/generate-bugfix-prompt.py +7 -12
- package/bundled/dev-pipeline/scripts/generate-refactor-prompt.py +124 -20
- package/bundled/dev-pipeline/scripts/utils.py +20 -0
- package/bundled/dev-pipeline/templates/agent-prompts/dev-implement.md +13 -7
- package/bundled/dev-pipeline/templates/bootstrap-tier1.md +62 -66
- package/bundled/dev-pipeline/templates/bootstrap-tier2.md +37 -40
- package/bundled/dev-pipeline/templates/bootstrap-tier3.md +35 -48
- package/bundled/dev-pipeline/templates/bugfix-bootstrap-prompt.md +135 -182
- package/bundled/dev-pipeline/templates/feature-list-schema.json +6 -21
- package/bundled/dev-pipeline/templates/refactor-bootstrap-prompt.md +9 -9
- package/bundled/dev-pipeline/templates/sections/context-budget-rules.md +1 -1
- package/bundled/dev-pipeline/templates/sections/feature-context.md +4 -0
- package/bundled/dev-pipeline/templates/sections/phase-browser-verification.md +41 -24
- package/bundled/dev-pipeline/templates/sections/phase-commit-full.md +4 -12
- package/bundled/dev-pipeline/templates/sections/phase-deploy-verification.md +9 -17
- package/bundled/dev-pipeline/templates/sections/phase-implement-lite.md +1 -1
- package/bundled/dev-pipeline/templates/sections/phase-plan-agent.md +3 -2
- package/bundled/dev-pipeline/templates/sections/phase-plan-lite.md +4 -2
- package/bundled/dev-pipeline/templates/sections/phase-specify-plan-full.md +0 -18
- package/bundled/dev-pipeline/templates/sections/session-context.md +1 -2
- package/bundled/dev-pipeline/templates/sections/test-failure-recovery-agent.md +75 -0
- package/bundled/dev-pipeline/templates/sections/test-failure-recovery-lite.md +66 -0
- package/bundled/skills/_metadata.json +1 -1
- package/bundled/skills/bugfix-pipeline-launcher/SKILL.md +3 -8
- package/bundled/skills/feature-pipeline-launcher/SKILL.md +4 -16
- package/bundled/skills/feature-planner/SKILL.md +9 -5
- package/bundled/skills/feature-planner/assets/planning-guide.md +16 -11
- package/bundled/skills/feature-planner/references/browser-interaction.md +9 -8
- package/bundled/skills/feature-planner/references/completeness-review.md +1 -1
- package/bundled/skills/feature-planner/references/error-recovery.md +1 -1
- package/bundled/skills/feature-planner/references/incremental-feature-planning.md +1 -1
- package/bundled/skills/feature-planner/scripts/validate-and-generate.py +10 -7
- package/bundled/skills/recovery-workflow/SKILL.md +3 -3
- package/bundled/skills/refactor-pipeline-launcher/SKILL.md +4 -15
- package/package.json +1 -1
- package/bundled/dev-pipeline/retry-bugfix.sh +0 -429
- package/bundled/dev-pipeline/retry-feature.sh +0 -445
- package/bundled/dev-pipeline/retry-refactor.sh +0 -441
- package/bundled/dev-pipeline/templates/sections/failure-log-check.md +0 -9
- package/bundled/dev-pipeline/templates/sections/resume-header.md +0 -5
- package/bundled/dev-pipeline/templates/sections/test-failure-recovery.md +0 -75
package/bundled/VERSION.json
CHANGED
|
@@ -80,33 +80,7 @@ If `.prizmkit/plans/feature-list.json` path is omitted, defaults to `.prizmkit/p
|
|
|
80
80
|
|
|
81
81
|
---
|
|
82
82
|
|
|
83
|
-
### `
|
|
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
|
|
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`
|
|
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,
|
|
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,
|
|
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
|
|
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
|
|
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/
|
|
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
|
-
+--
|
|
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
|
-
+--
|
|
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
|
-
#
|
|
8
|
-
#
|
|
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
|
|
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
|
|
26
|
-
# ./reset-bug.sh B-007 --clean # Reset + delete
|
|
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
|
|
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/
|
|
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/
|
|
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
|
-
#
|
|
8
|
-
#
|
|
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
|
|
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
|
|
26
|
-
# ./reset-feature.sh F-007 --clean # Reset + delete
|
|
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
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
374
|
+
log_info " ./dev-pipeline/run-refactor.sh run ${REFACTOR_IDS[0]} # Run single refactor"
|
|
311
375
|
fi
|
|
312
376
|
fi
|
|
313
377
|
echo ""
|