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.
Files changed (47) 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 +9 -5
  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/recovery-workflow/SKILL.md +3 -3
  40. package/bundled/skills/refactor-pipeline-launcher/SKILL.md +4 -15
  41. package/package.json +1 -1
  42. package/bundled/dev-pipeline/retry-bugfix.sh +0 -429
  43. package/bundled/dev-pipeline/retry-feature.sh +0 -445
  44. package/bundled/dev-pipeline/retry-refactor.sh +0 -441
  45. package/bundled/dev-pipeline/templates/sections/failure-log-check.md +0 -9
  46. package/bundled/dev-pipeline/templates/sections/resume-header.md +0 -5
  47. package/bundled/dev-pipeline/templates/sections/test-failure-recovery.md +0 -75
@@ -227,7 +227,7 @@ Detect user intent from their message, then follow the corresponding workflow:
227
227
  **If foreground**: Pipeline runs to completion in the terminal. After it finishes:
228
228
  - Summarize results: total refactors, succeeded, failed, skipped
229
229
  - If all succeeded: each refactor session has already run `prizmkit-retrospective` internally. Ask user what's next.
230
- - If some failed: show failed refactor IDs and suggest `retry-refactor.sh <R-XXX>` or `reset-refactor.sh <R-XXX> --clean --run`
230
+ - If some failed: show failed refactor IDs and suggest `reset-refactor.sh <R-XXX> --clean --run` for a fresh retry
231
231
 
232
232
  **If background daemon**:
233
233
  1. Verify launch:
@@ -315,25 +315,14 @@ Detect user intent from their message, then follow the corresponding workflow:
315
315
 
316
316
  #### Intent E: Retry Single Refactor
317
317
 
318
- When user says "retry R-001":
319
-
320
- ```bash
321
- dev-pipeline/retry-refactor.sh R-001 .prizmkit/plans/refactor-list.json
322
- ```
323
-
324
- When user says "clean retry R-001" or "retry R-001 from scratch":
318
+ When user says "retry R-001" or "clean retry R-001":
325
319
 
326
320
  ```bash
327
321
  dev-pipeline/reset-refactor.sh R-001 --clean --run .prizmkit/plans/refactor-list.json
328
322
  ```
329
323
 
330
- Environment variables (optional):
331
- ```bash
332
- SESSION_TIMEOUT=3600 STRICT_BEHAVIOR_CHECK=1 dev-pipeline/retry-refactor.sh R-001 .prizmkit/plans/refactor-list.json
333
- ```
334
-
335
324
  Notes:
336
- - `retry-refactor.sh` runs exactly one refactor session and exits. It **preserves prior session artifacts and checkpoint state** reads `retry_count` and `resume_from_phase` from `status.json` so the AI session can resume from where it left off. For a full clean retry, use `dev-pipeline/reset-refactor.sh <R-XXX> --clean --run`.
325
+ - `reset-refactor.sh --clean --run` performs a full clean (deletes session history and artifacts) before retryingthis gives a fresh start.
337
326
  - Keep pipeline daemon mode for main run management (`launch-refactor-daemon.sh`).
338
327
 
339
328
  ---
@@ -350,7 +339,7 @@ Notes:
350
339
  | Refactor pipeline already running | Show status, ask if user wants to stop and restart |
351
340
  | PID file stale (process dead) | `launch-refactor-daemon.sh` auto-cleans, retry start |
352
341
  | Launch failed (process died immediately) | Show last 20 lines of log: `tail -20 .prizmkit/state/refactor/pipeline-daemon.log` |
353
- | Refactor stuck/blocked | Use `retry-refactor.sh <R-XXX>` to retry; use `reset-refactor.sh <R-XXX> --clean --run` for fresh start |
342
+ | Refactor stuck/blocked | Use `reset-refactor.sh <R-XXX> --clean --run` for a fresh retry |
354
343
  | All refactors blocked/failed | Show status, suggest recovery: `dev-pipeline/reset-refactor.sh <R-XXX> --clean --run .prizmkit/plans/refactor-list.json` |
355
344
  | Permission denied on script | Run `chmod +x dev-pipeline/launch-refactor-daemon.sh dev-pipeline/run-refactor.sh` |
356
345
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prizmkit",
3
- "version": "1.1.9",
3
+ "version": "1.1.12",
4
4
  "description": "Create a new PrizmKit-powered project with clean initialization — no framework dev files, just what you need.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,429 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
-
4
- # ============================================================
5
- # dev-pipeline/retry-bugfix.sh - Retry a single failed bug fix
6
- #
7
- # Runs exactly ONE AI CLI session for the specified bug, then exits.
8
- # Use this to manually retry a failed bug without restarting
9
- # the full bugfix pipeline.
10
- #
11
- # Usage:
12
- # ./retry-bugfix.sh <bug-id> [.prizmkit/plans/bug-fix-list.json]
13
- #
14
- # Examples:
15
- # ./retry-bugfix.sh B-001
16
- # ./retry-bugfix.sh B-001 .prizmkit/plans/bug-fix-list.json
17
- # SESSION_TIMEOUT=3600 ./retry-bugfix.sh B-001
18
- # ============================================================
19
-
20
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
21
- PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
22
- STATE_DIR="${PROJECT_ROOT}/.prizmkit/state/bugfix"
23
- SCRIPTS_DIR="$SCRIPT_DIR/scripts"
24
-
25
- SESSION_TIMEOUT=${SESSION_TIMEOUT:-0}
26
- HEARTBEAT_INTERVAL=${HEARTBEAT_INTERVAL:-30}
27
- AUTO_PUSH=${AUTO_PUSH:-0}
28
- DEV_BRANCH=${DEV_BRANCH:-""}
29
-
30
- # Source shared libraries (CLI/platform detection + logs + deps)
31
- source "$SCRIPT_DIR/lib/common.sh"
32
- prizm_detect_cli_and_platform
33
-
34
- # Source shared heartbeat library
35
- source "$SCRIPT_DIR/lib/heartbeat.sh"
36
-
37
- # Source shared branch library
38
- source "$SCRIPT_DIR/lib/branch.sh"
39
-
40
- # Detect stream-json support
41
- detect_stream_json_support "$CLI_CMD"
42
-
43
- # ============================================================
44
- # Args
45
- # ============================================================
46
-
47
- if [[ $# -lt 1 ]]; then
48
- echo "Usage: $0 <bug-id> [.prizmkit/plans/bug-fix-list.json]"
49
- echo ""
50
- echo " bug-id Bug to retry (e.g. B-001)"
51
- echo " bug-fix-list.json Path to bug fix list (default: .prizmkit/plans/bug-fix-list.json)"
52
- echo ""
53
- echo "Environment Variables:"
54
- echo " SESSION_TIMEOUT Timeout in seconds (default: 0 = no limit)"
55
- echo " HEARTBEAT_INTERVAL Heartbeat interval in seconds (default: 30)"
56
- echo " AI_CLI AI CLI command (auto-detected: cbc or claude)"
57
- echo " AUTO_PUSH Auto-push to remote after fix (default: 0)"
58
- echo " DEV_BRANCH Custom dev branch name (default: auto-generated)"
59
- exit 1
60
- fi
61
-
62
- BUG_ID="$1"
63
- BUG_LIST="${2:-.prizmkit/plans/bug-fix-list.json}"
64
-
65
- if [[ ! "$BUG_LIST" = /* ]]; then
66
- BUG_LIST="$(pwd)/$BUG_LIST"
67
- fi
68
-
69
- # ============================================================
70
- # Validation
71
- # ============================================================
72
-
73
- if [[ ! -f "$BUG_LIST" ]]; then
74
- log_error "Bug fix list not found: $BUG_LIST"
75
- exit 1
76
- fi
77
-
78
- if ! command -v jq &>/dev/null; then
79
- log_error "jq is required. Install with: brew install jq"
80
- exit 1
81
- fi
82
-
83
- # Initialize state if needed
84
- if [[ ! -f "$STATE_DIR/pipeline.json" ]]; then
85
- log_info "Initializing bugfix pipeline state..."
86
- python3 "$SCRIPTS_DIR/init-bugfix-pipeline.py" \
87
- --bug-list "$BUG_LIST" \
88
- --state-dir "$STATE_DIR" >/dev/null 2>&1 || {
89
- log_error "Failed to initialize bugfix pipeline state"
90
- exit 1
91
- }
92
- fi
93
-
94
- # Verify bug exists
95
- BUG_TITLE=$(python3 -c "
96
- import json, sys
97
- with open('$BUG_LIST') as f:
98
- data = json.load(f)
99
- for bug in data.get('bugs', []):
100
- if bug.get('id') == '$BUG_ID':
101
- print(bug.get('title', ''))
102
- sys.exit(0)
103
- sys.exit(1)
104
- " 2>/dev/null) || {
105
- log_error "Bug $BUG_ID not found in $BUG_LIST"
106
- exit 1
107
- }
108
-
109
- BUG_SEVERITY=$(python3 -c "
110
- import json, sys
111
- with open('$BUG_LIST') as f:
112
- data = json.load(f)
113
- for bug in data.get('bugs', []):
114
- if bug.get('id') == '$BUG_ID':
115
- print(bug.get('severity', 'medium'))
116
- sys.exit(0)
117
- sys.exit(1)
118
- " 2>/dev/null) || BUG_SEVERITY="medium"
119
-
120
- # ============================================================
121
- # Clean bug artifacts + reset status for a full restart
122
- # ============================================================
123
-
124
- PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
125
- ORIGINAL_BRANCH=$(git -C "$PROJECT_ROOT" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "main")
126
-
127
- # Branch tracking (for cleanup on interrupt)
128
- _DEV_BRANCH_NAME=""
129
-
130
- log_info "Reading retry state for $BUG_ID..."
131
- RETRY_COUNT=$(python3 -c "
132
- import json, os
133
- status_path = os.path.join('$STATE_DIR', 'bugs', '$BUG_ID', 'status.json')
134
- if os.path.isfile(status_path):
135
- with open(status_path) as f:
136
- d = json.load(f)
137
- print(d.get('retry_count', 0))
138
- else:
139
- print(0)
140
- " 2>/dev/null || echo "0")
141
- RESUME_PHASE=$(python3 -c "
142
- import json, os
143
- status_path = os.path.join('$STATE_DIR', 'bugs', '$BUG_ID', 'status.json')
144
- if os.path.isfile(status_path):
145
- with open(status_path) as f:
146
- d = json.load(f)
147
- print(d.get('resume_from_phase') or 'null')
148
- else:
149
- print('null')
150
- " 2>/dev/null || echo "null")
151
- log_info "Retry count: $RETRY_COUNT, Resume phase: $RESUME_PHASE"
152
-
153
- # ============================================================
154
- # Generate bootstrap prompt
155
- # ============================================================
156
-
157
- RUN_ID=$(jq -r '.run_id' "$STATE_DIR/pipeline.json")
158
- SESSION_ID="${BUG_ID}-$(date +%Y%m%d%H%M%S)"
159
- SESSION_DIR="$STATE_DIR/bugs/$BUG_ID/sessions/$SESSION_ID"
160
- mkdir -p "$SESSION_DIR/logs"
161
-
162
- BOOTSTRAP_PROMPT="$SESSION_DIR/bootstrap-prompt.md"
163
-
164
- log_info "Generating bugfix bootstrap prompt..."
165
- GEN_ARGS=(
166
- --bug-list "$BUG_LIST"
167
- --bug-id "$BUG_ID"
168
- --session-id "$SESSION_ID"
169
- --run-id "$RUN_ID"
170
- --retry-count "$RETRY_COUNT"
171
- --resume-phase "$RESUME_PHASE"
172
- --state-dir "$STATE_DIR"
173
- --output "$BOOTSTRAP_PROMPT"
174
- )
175
-
176
- # Support PIPELINE_MODE env var
177
- if [[ -n "${PIPELINE_MODE:-}" ]]; then
178
- GEN_ARGS+=(--mode "$PIPELINE_MODE")
179
- fi
180
-
181
- # Support ENABLE_CRITIC env var
182
- if [[ "${ENABLE_CRITIC:-}" == "true" || "${ENABLE_CRITIC:-}" == "1" ]]; then
183
- GEN_ARGS+=(--critic "true")
184
- elif [[ "${ENABLE_CRITIC:-}" == "false" || "${ENABLE_CRITIC:-}" == "0" ]]; then
185
- GEN_ARGS+=(--critic "false")
186
- fi
187
-
188
- GEN_OUTPUT=$(python3 "$SCRIPTS_DIR/generate-bugfix-prompt.py" "${GEN_ARGS[@]}" 2>/dev/null) || {
189
- log_error "Failed to generate bootstrap prompt"
190
- exit 1
191
- }
192
- BUG_MODEL=$(echo "$GEN_OUTPUT" | python3 -c "import json,sys; print(json.load(sys.stdin).get('model',''))" 2>/dev/null || echo "")
193
-
194
- # ============================================================
195
- # Run single AI CLI session
196
- # ============================================================
197
-
198
- # Branch lifecycle: create and checkout bugfix branch
199
- _branch_name="${DEV_BRANCH:-bugfix/${BUG_ID}-$(date +%s)}"
200
- if branch_create "$PROJECT_ROOT" "$_branch_name" "$ORIGINAL_BRANCH"; then
201
- _DEV_BRANCH_NAME="$_branch_name"
202
- log_info "Dev branch: $_branch_name"
203
- else
204
- log_warn "Failed to create branch; running session on current branch"
205
- fi
206
-
207
- echo ""
208
- echo -e "${BOLD}════════════════════════════════════════════════════${NC}"
209
- echo -e "${BOLD} Retry Bug Fix: $BUG_ID — $BUG_TITLE${NC}"
210
- echo -e "${BOLD} Severity: $BUG_SEVERITY${NC}"
211
- echo -e "${BOLD}════════════════════════════════════════════════════${NC}"
212
- log_info "CLI: $CLI_CMD (platform: $PLATFORM)"
213
- EFFECTIVE_MODEL="${BUG_MODEL:-${MODEL:-}}"
214
- if [[ -n "$EFFECTIVE_MODEL" ]]; then
215
- log_info "Model: $EFFECTIVE_MODEL"
216
- else
217
- log_info "Model: (CLI default)"
218
- fi
219
- if [[ $SESSION_TIMEOUT -gt 0 ]]; then
220
- log_info "Session timeout: ${SESSION_TIMEOUT}s"
221
- else
222
- log_info "Session timeout: none"
223
- fi
224
- log_info "Prompt: $BOOTSTRAP_PROMPT"
225
- log_info "Log: $SESSION_DIR/logs/session.log"
226
- echo -e "${BOLD}════════════════════════════════════════════════════${NC}"
227
- echo ""
228
-
229
- SESSION_LOG="$SESSION_DIR/logs/session.log"
230
- PROGRESS_JSON="$SESSION_DIR/logs/progress.json"
231
-
232
- # Build stream-json flag
233
- STREAM_JSON_FLAG=""
234
- if [[ "$USE_STREAM_JSON" == "true" ]]; then
235
- STREAM_JSON_FLAG="--output-format stream-json"
236
- fi
237
-
238
- # claude-internal requires --verbose when using stream-json with -p/--print
239
- VERBOSE_FLAG=""
240
- if [[ "$USE_STREAM_JSON" == "true" ]]; then
241
- VERBOSE_FLAG="--verbose"
242
- fi
243
-
244
- # Spawn AI CLI session — model priority: bug.model > $MODEL env > none
245
- EFFECTIVE_MODEL="${BUG_MODEL:-${MODEL:-}}"
246
- MODEL_FLAG=""
247
- if [[ -n "$EFFECTIVE_MODEL" ]]; then
248
- MODEL_FLAG="--model $EFFECTIVE_MODEL"
249
- fi
250
-
251
- unset CLAUDECODE 2>/dev/null || true
252
-
253
- # Log bootstrap prompt in test mode
254
- prizm_log_bootstrap_prompt "$BOOTSTRAP_PROMPT" "$BUG_ID"
255
-
256
- case "$CLI_CMD" in
257
- *claude*)
258
- # Claude Code: prompt via -p argument, --dangerously-skip-permissions for auto-accept
259
- "$CLI_CMD" \
260
- -p "$(cat "$BOOTSTRAP_PROMPT")" \
261
- --dangerously-skip-permissions \
262
- $VERBOSE_FLAG \
263
- $STREAM_JSON_FLAG \
264
- $MODEL_FLAG \
265
- > "$SESSION_LOG" 2>&1 &
266
- ;;
267
- *)
268
- # CodeBuddy (cbc) and others: prompt via stdin
269
- "$CLI_CMD" \
270
- --print \
271
- -y \
272
- $STREAM_JSON_FLAG \
273
- $MODEL_FLAG \
274
- < "$BOOTSTRAP_PROMPT" \
275
- > "$SESSION_LOG" 2>&1 &
276
- ;;
277
- esac
278
- CLI_PID=$!
279
-
280
- # Start progress parser (no-op if stream-json not supported)
281
- start_progress_parser "$SESSION_LOG" "$PROGRESS_JSON" "$SCRIPTS_DIR"
282
- PARSER_PID="${_PARSER_PID:-}"
283
-
284
- # Timeout watchdog
285
- WATCHER_PID=""
286
- if [[ $SESSION_TIMEOUT -gt 0 ]]; then
287
- ( sleep "$SESSION_TIMEOUT" && kill -TERM "$CLI_PID" 2>/dev/null ) &
288
- WATCHER_PID=$!
289
- fi
290
-
291
- # Heartbeat
292
- start_heartbeat "$CLI_PID" "$SESSION_LOG" "$PROGRESS_JSON" "$HEARTBEAT_INTERVAL"
293
- HEARTBEAT_PID="${_HEARTBEAT_PID:-}"
294
-
295
- # Ctrl+C cleanup
296
- cleanup() {
297
- echo ""
298
- log_warn "Interrupted. Killing session..."
299
- kill "$CLI_PID" 2>/dev/null || true
300
- [[ -n "$WATCHER_PID" ]] && kill "$WATCHER_PID" 2>/dev/null || true
301
- stop_heartbeat "$HEARTBEAT_PID"
302
- stop_progress_parser "$PARSER_PID"
303
- wait "$CLI_PID" 2>/dev/null || true
304
- [[ -n "$WATCHER_PID" ]] && wait "$WATCHER_PID" 2>/dev/null || true
305
- if [[ -n "$_DEV_BRANCH_NAME" ]]; then
306
- log_info "Development was on branch: $_DEV_BRANCH_NAME"
307
- log_info "Original branch was: $ORIGINAL_BRANCH"
308
- fi
309
- log_info "Session log: $SESSION_LOG"
310
- exit 130
311
- }
312
- trap cleanup SIGINT SIGTERM
313
-
314
- # Wait
315
- EXIT_CODE=0
316
- if wait "$CLI_PID" 2>/dev/null; then
317
- EXIT_CODE=0
318
- else
319
- EXIT_CODE=$?
320
- fi
321
-
322
- # Cleanup background processes
323
- [[ -n "$WATCHER_PID" ]] && kill "$WATCHER_PID" 2>/dev/null || true
324
- stop_heartbeat "$HEARTBEAT_PID"
325
- stop_progress_parser "$PARSER_PID"
326
- [[ -n "$WATCHER_PID" ]] && wait "$WATCHER_PID" 2>/dev/null || true
327
-
328
- [[ $EXIT_CODE -eq 143 ]] && EXIT_CODE=124
329
-
330
- # ============================================================
331
- # Check result
332
- # ============================================================
333
-
334
- echo ""
335
- if [[ -f "$SESSION_LOG" ]]; then
336
- FINAL_LINES=$(wc -l < "$SESSION_LOG" 2>/dev/null | tr -d ' ')
337
- FINAL_SIZE=$(wc -c < "$SESSION_LOG" 2>/dev/null | tr -d ' ')
338
- log_info "Session log: $FINAL_LINES lines, $((FINAL_SIZE / 1024))KB"
339
- fi
340
- log_info "exit_code=$EXIT_CODE"
341
-
342
- # ── Determine session outcome from observable signals ──────────────
343
- PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
344
- DEFAULT_BRANCH="$ORIGINAL_BRANCH"
345
-
346
- if [[ $EXIT_CODE -eq 124 ]]; then
347
- log_warn "Session timed out after ${SESSION_TIMEOUT}s"
348
- SESSION_STATUS="timed_out"
349
- elif [[ $EXIT_CODE -ne 0 ]]; then
350
- log_warn "Session exited with code $EXIT_CODE"
351
- SESSION_STATUS="crashed"
352
- else
353
- # Exit code 0 — check if the session produced commits
354
- HAS_COMMITS=""
355
- if git -C "$PROJECT_ROOT" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
356
- HAS_COMMITS=$(git -C "$PROJECT_ROOT" log "${DEFAULT_BRANCH}..HEAD" --oneline 2>/dev/null | head -1)
357
- fi
358
-
359
- if [[ -n "$HAS_COMMITS" ]]; then
360
- SESSION_STATUS="success"
361
- else
362
- UNCOMMITTED=$(git -C "$PROJECT_ROOT" status --porcelain 2>/dev/null | head -1 || true)
363
- if [[ -n "$UNCOMMITTED" ]]; then
364
- log_warn "Session exited cleanly but produced no commits (uncommitted changes found) — auto-committing..."
365
- git -C "$PROJECT_ROOT" add -A 2>/dev/null || true
366
- if git -C "$PROJECT_ROOT" commit --no-verify -m "chore($BUG_ID): auto-commit session work" 2>/dev/null; then
367
- log_info "Auto-commit succeeded"
368
- SESSION_STATUS="success"
369
- else
370
- log_warn "Auto-commit failed — no changes to commit"
371
- SESSION_STATUS="crashed"
372
- fi
373
- else
374
- log_warn "Session exited cleanly but produced no commits and no changes"
375
- SESSION_STATUS="crashed"
376
- fi
377
- fi
378
- fi
379
-
380
- # ── Post-success validation ──────────────────────────────────────────
381
- if [[ "$SESSION_STATUS" == "success" ]]; then
382
- if git -C "$PROJECT_ROOT" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
383
- DIRTY_FILES=$(git -C "$PROJECT_ROOT" status --porcelain 2>/dev/null || true)
384
- if [[ -n "$DIRTY_FILES" ]]; then
385
- log_info "Auto-committing remaining session artifacts..."
386
- git -C "$PROJECT_ROOT" add -A 2>/dev/null || true
387
- git -C "$PROJECT_ROOT" commit --no-verify --amend --no-edit -a 2>/dev/null \
388
- || git -C "$PROJECT_ROOT" commit --no-verify -m "chore($BUG_ID): include remaining session artifacts" 2>/dev/null \
389
- || true
390
- fi
391
- fi
392
- fi
393
-
394
- # ── Merge dev branch back to original on success ────────────────────
395
- if [[ "$SESSION_STATUS" == "success" && -n "$_DEV_BRANCH_NAME" ]]; then
396
- if branch_merge "$PROJECT_ROOT" "$_DEV_BRANCH_NAME" "$ORIGINAL_BRANCH" "$AUTO_PUSH"; then
397
- _DEV_BRANCH_NAME=""
398
- else
399
- log_warn "Auto-merge failed — dev branch preserved: $_DEV_BRANCH_NAME"
400
- fi
401
- fi
402
-
403
- # Update bug status
404
- python3 "$SCRIPTS_DIR/update-bug-status.py" \
405
- --bug-list "$BUG_LIST" \
406
- --state-dir "$STATE_DIR" \
407
- --bug-id "$BUG_ID" \
408
- --session-status "$SESSION_STATUS" \
409
- --session-id "$SESSION_ID" \
410
- --max-retries 999 \
411
- --action update >/dev/null 2>&1 || true
412
-
413
- # Commit bug-fix-list.json status update (pipeline management commit)
414
- if ! git -C "$PROJECT_ROOT" diff --quiet "$BUG_LIST" 2>/dev/null; then
415
- git -C "$PROJECT_ROOT" add "$BUG_LIST"
416
- git -C "$PROJECT_ROOT" commit --no-verify -m "chore($BUG_ID): update bug status" 2>/dev/null || true
417
- fi
418
-
419
- echo ""
420
- if [[ "$SESSION_STATUS" == "success" ]]; then
421
- log_success "════════════════════════════════════════════════════"
422
- log_success " $BUG_ID fixed successfully!"
423
- log_success "════════════════════════════════════════════════════"
424
- else
425
- log_error "════════════════════════════════════════════════════"
426
- log_error " $BUG_ID result: $SESSION_STATUS"
427
- log_error " Review log: $SESSION_LOG"
428
- log_error "════════════════════════════════════════════════════"
429
- fi