prizmkit 1.1.1 → 1.1.4

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 (119) hide show
  1. package/bundled/VERSION.json +3 -3
  2. package/bundled/adapters/claude/agent-adapter.js +18 -0
  3. package/bundled/adapters/claude/command-adapter.js +1 -27
  4. package/bundled/agents/prizm-dev-team-critic.md +2 -0
  5. package/bundled/agents/prizm-dev-team-dev.md +2 -0
  6. package/bundled/agents/prizm-dev-team-reviewer.md +2 -0
  7. package/bundled/dev-pipeline/README.md +63 -63
  8. package/bundled/dev-pipeline/assets/feature-list-example.json +1 -1
  9. package/bundled/dev-pipeline/assets/prizm-dev-team-integration.md +1 -1
  10. package/bundled/dev-pipeline/{launch-daemon.sh → launch-feature-daemon.sh} +33 -33
  11. package/bundled/dev-pipeline/launch-refactor-daemon.sh +454 -0
  12. package/bundled/dev-pipeline/lib/branch.sh +1 -1
  13. package/bundled/dev-pipeline/reset-feature.sh +3 -3
  14. package/bundled/dev-pipeline/reset-refactor.sh +312 -0
  15. package/bundled/dev-pipeline/{retry-bug.sh → retry-bugfix.sh} +47 -59
  16. package/bundled/dev-pipeline/retry-feature.sh +41 -54
  17. package/bundled/dev-pipeline/retry-refactor.sh +358 -0
  18. package/bundled/dev-pipeline/run-bugfix.sh +41 -0
  19. package/bundled/dev-pipeline/{run.sh → run-feature.sh} +64 -31
  20. package/bundled/dev-pipeline/run-refactor.sh +787 -0
  21. package/bundled/dev-pipeline/scripts/generate-bootstrap-prompt.py +398 -10
  22. package/bundled/dev-pipeline/scripts/generate-bugfix-prompt.py +124 -0
  23. package/bundled/dev-pipeline/scripts/generate-refactor-prompt.py +419 -0
  24. package/bundled/dev-pipeline/scripts/init-refactor-pipeline.py +393 -0
  25. package/bundled/dev-pipeline/scripts/update-refactor-status.py +726 -0
  26. package/bundled/dev-pipeline/templates/agent-prompts/critic-code-challenge.md +13 -0
  27. package/bundled/dev-pipeline/templates/agent-prompts/critic-plan-challenge.md +7 -0
  28. package/bundled/dev-pipeline/templates/agent-prompts/dev-fix.md +7 -0
  29. package/bundled/dev-pipeline/templates/agent-prompts/dev-implement.md +27 -0
  30. package/bundled/dev-pipeline/templates/agent-prompts/dev-resume.md +5 -0
  31. package/bundled/dev-pipeline/templates/agent-prompts/reviewer-analyze.md +5 -0
  32. package/bundled/dev-pipeline/templates/agent-prompts/reviewer-review.md +12 -0
  33. package/bundled/dev-pipeline/templates/bootstrap-tier1.md +33 -2
  34. package/bundled/dev-pipeline/templates/bootstrap-tier2.md +13 -9
  35. package/bundled/dev-pipeline/templates/bootstrap-tier3.md +16 -12
  36. package/bundled/dev-pipeline/templates/bugfix-bootstrap-prompt.md +22 -4
  37. package/bundled/dev-pipeline/templates/feature-list-schema.json +1 -1
  38. package/bundled/dev-pipeline/templates/refactor-list-schema.json +159 -0
  39. package/bundled/dev-pipeline/templates/sections/ac-verification-checklist.md +13 -0
  40. package/bundled/dev-pipeline/templates/sections/checkpoint-system.md +36 -0
  41. package/bundled/dev-pipeline/templates/sections/failure-log-check.md +2 -1
  42. package/bundled/dev-pipeline/templates/sections/feature-context.md +1 -1
  43. package/bundled/dev-pipeline/templates/sections/phase-analyze-agent.md +11 -7
  44. package/bundled/dev-pipeline/templates/sections/phase-analyze-full.md +11 -7
  45. package/bundled/dev-pipeline/templates/sections/phase-browser-verification.md +5 -1
  46. package/bundled/dev-pipeline/templates/sections/phase-commit-full.md +3 -0
  47. package/bundled/dev-pipeline/templates/sections/phase-commit.md +3 -0
  48. package/bundled/dev-pipeline/templates/sections/phase-context-snapshot-agent-suffix.md +3 -0
  49. package/bundled/dev-pipeline/templates/sections/phase-context-snapshot-lite-suffix.md +3 -0
  50. package/bundled/dev-pipeline/templates/sections/phase-critic-code.md +11 -10
  51. package/bundled/dev-pipeline/templates/sections/phase-critic-plan-full.md +12 -10
  52. package/bundled/dev-pipeline/templates/sections/phase-critic-plan.md +11 -9
  53. package/bundled/dev-pipeline/templates/sections/phase-deploy-verification.md +3 -0
  54. package/bundled/dev-pipeline/templates/sections/phase-implement-agent.md +10 -10
  55. package/bundled/dev-pipeline/templates/sections/phase-implement-full.md +12 -16
  56. package/bundled/dev-pipeline/templates/sections/phase-implement-lite.md +3 -0
  57. package/bundled/dev-pipeline/templates/sections/phase-plan-agent.md +3 -0
  58. package/bundled/dev-pipeline/templates/sections/phase-plan-lite.md +3 -0
  59. package/bundled/dev-pipeline/templates/sections/phase-review-agent.md +11 -13
  60. package/bundled/dev-pipeline/templates/sections/phase-review-full.md +12 -20
  61. package/bundled/dev-pipeline/templates/sections/phase-specify-plan-full.md +3 -0
  62. package/bundled/dev-pipeline/templates/sections/phase0-init.md +3 -0
  63. package/bundled/dev-pipeline/templates/sections/phase0-test-baseline.md +3 -0
  64. package/bundled/dev-pipeline/templates/sections/resume-header.md +4 -1
  65. package/bundled/dev-pipeline/templates/sections/test-failure-recovery.md +75 -0
  66. package/bundled/rules/prizm/prizm-commit-workflow.md +1 -0
  67. package/bundled/rules/prizm/prizm-documentation.md +15 -15
  68. package/bundled/rules/prizm/prizm-progressive-loading.md +2 -1
  69. package/bundled/skills/_metadata.json +33 -6
  70. package/bundled/skills/app-planner/SKILL.md +105 -320
  71. package/bundled/skills/app-planner/assets/app-design-guide.md +101 -0
  72. package/bundled/skills/app-planner/references/frontend-design-guide.md +1 -1
  73. package/bundled/skills/app-planner/references/project-brief-guide.md +49 -80
  74. package/bundled/skills/bug-fix-workflow/SKILL.md +2 -2
  75. package/bundled/skills/bug-planner/SKILL.md +68 -5
  76. package/bundled/skills/bug-planner/scripts/validate-bug-list.py +3 -2
  77. package/bundled/skills/bugfix-pipeline-launcher/SKILL.md +19 -5
  78. package/bundled/skills/{dev-pipeline-launcher → feature-pipeline-launcher}/SKILL.md +32 -32
  79. package/bundled/skills/feature-planner/SKILL.md +337 -0
  80. package/bundled/skills/{app-planner → feature-planner}/assets/evaluation-guide.md +4 -4
  81. package/bundled/skills/{app-planner → feature-planner}/assets/planning-guide.md +3 -171
  82. package/bundled/skills/{app-planner → feature-planner}/references/browser-interaction.md +6 -5
  83. package/bundled/skills/feature-planner/references/decomposition-patterns.md +75 -0
  84. package/bundled/skills/{app-planner → feature-planner}/references/error-recovery.md +8 -8
  85. package/bundled/skills/{app-planner → feature-planner}/references/incremental-feature-planning.md +1 -1
  86. package/bundled/skills/{app-planner/references/new-app-planning.md → feature-planner/references/new-project-planning.md} +1 -1
  87. package/bundled/skills/{app-planner → feature-planner}/scripts/validate-and-generate.py +4 -4
  88. package/bundled/skills/feature-workflow/SKILL.md +23 -23
  89. package/bundled/skills/prizm-kit/SKILL.md +1 -3
  90. package/bundled/skills/prizm-kit/assets/project-memory-template.md +4 -2
  91. package/bundled/skills/prizmkit-analyze/SKILL.md +2 -5
  92. package/bundled/skills/prizmkit-code-review/SKILL.md +2 -2
  93. package/bundled/skills/prizmkit-committer/SKILL.md +32 -8
  94. package/bundled/skills/prizmkit-deploy/SKILL.md +1 -5
  95. package/bundled/skills/prizmkit-implement/SKILL.md +5 -51
  96. package/bundled/skills/prizmkit-init/SKILL.md +7 -78
  97. package/bundled/skills/prizmkit-plan/SKILL.md +1 -12
  98. package/bundled/skills/prizmkit-prizm-docs/SKILL.md +13 -28
  99. package/bundled/skills/prizmkit-prizm-docs/assets/PRIZM-SPEC.md +52 -1
  100. package/bundled/skills/prizmkit-retrospective/SKILL.md +12 -117
  101. package/bundled/skills/recovery-workflow/SKILL.md +168 -316
  102. package/bundled/skills/recovery-workflow/evals/evals.json +29 -13
  103. package/bundled/skills/recovery-workflow/scripts/detect-recovery-state.py +232 -274
  104. package/bundled/skills/refactor-pipeline-launcher/SKILL.md +352 -0
  105. package/bundled/skills/refactor-planner/SKILL.md +436 -0
  106. package/bundled/skills/refactor-planner/assets/planning-guide.md +292 -0
  107. package/bundled/skills/refactor-planner/references/behavior-preservation.md +301 -0
  108. package/bundled/skills/refactor-planner/references/refactor-scoping-guide.md +221 -0
  109. package/bundled/skills/refactor-planner/scripts/validate-and-generate-refactor.py +786 -0
  110. package/bundled/skills/refactor-workflow/SKILL.md +299 -319
  111. package/bundled/team/prizm-dev-team.json +1 -1
  112. package/package.json +1 -1
  113. package/src/clean.js +3 -3
  114. package/src/scaffold.js +6 -6
  115. package/bundled/skills/prizmkit-plan/assets/spec-template.md +0 -56
  116. package/bundled/skills/prizmkit-plan/references/clarify-guide.md +0 -67
  117. package/src/config.js +0 -504
  118. package/src/prompts.js +0 -210
  119. /package/bundled/skills/{dev-pipeline-launcher → feature-pipeline-launcher}/scripts/preflight-check.py +0 -0
@@ -0,0 +1,312 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ # ============================================================
5
+ # dev-pipeline/reset-refactor.sh - Reset a failed/stuck refactor
6
+ #
7
+ # Clears all state and artifacts for a refactor so it can be
8
+ # re-executed from scratch by the pipeline.
9
+ #
10
+ # Usage:
11
+ # ./reset-refactor.sh <refactor-id|range> [options] [refactor-list.json]
12
+ #
13
+ # Refactor selection:
14
+ # R-007 Single refactor
15
+ # R-008:R-013 Range of refactors (inclusive)
16
+ # --auto-skipped All refactors with auto_skipped status
17
+ # --failed All refactors with failed status
18
+ # --stalled All non-completed refactors (failed + auto_skipped)
19
+ #
20
+ # Options:
21
+ # --clean Also delete session history and .prizmkit/specs/{slug}/ artifacts
22
+ # --run After reset, immediately retry via pipeline (only with single refactor)
23
+ #
24
+ # Examples:
25
+ # ./reset-refactor.sh R-007 # Reset status only
26
+ # ./reset-refactor.sh R-007 --clean # Reset + delete artifacts
27
+ # ./reset-refactor.sh R-008:R-013 --clean # Reset range
28
+ # ./reset-refactor.sh --auto-skipped # Reset all auto_skipped
29
+ # ./reset-refactor.sh --failed --clean # Reset all failed + clean
30
+ # ./reset-refactor.sh --stalled --clean # Reset all non-completed
31
+ # ./reset-refactor.sh R-007 --clean --run # Reset + delete + retry
32
+ # ./reset-refactor.sh R-007 --clean my-refactors.json # Custom refactor list
33
+ # ============================================================
34
+
35
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
36
+ STATE_DIR="$SCRIPT_DIR/refactor-state"
37
+ SCRIPTS_DIR="$SCRIPT_DIR/scripts"
38
+
39
+ # Colors
40
+ RED='\033[0;31m'
41
+ GREEN='\033[0;32m'
42
+ YELLOW='\033[1;33m'
43
+ BLUE='\033[0;34m'
44
+ BOLD='\033[1m'
45
+ NC='\033[0m'
46
+
47
+ log_info() { echo -e "${BLUE}[INFO]${NC} $*"; }
48
+ log_warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
49
+ log_error() { echo -e "${RED}[ERROR]${NC} $*"; }
50
+ log_success() { echo -e "${GREEN}[OK]${NC} $*"; }
51
+
52
+ # ============================================================
53
+ # Parse args
54
+ # ============================================================
55
+
56
+ REFACTOR_ID=""
57
+ REFACTOR_RANGE=""
58
+ REFACTOR_LIST=""
59
+ DO_CLEAN=false
60
+ DO_RUN=false
61
+ FILTER_MODE=""
62
+
63
+ for arg in "$@"; do
64
+ case "$arg" in
65
+ --clean) DO_CLEAN=true ;;
66
+ --run) DO_RUN=true ;;
67
+ --auto-skipped) FILTER_MODE="auto_skipped" ;;
68
+ --failed) FILTER_MODE="failed" ;;
69
+ --stalled) FILTER_MODE="stalled" ;;
70
+ -h|--help)
71
+ echo "Usage: $0 <refactor-id|range> [--clean] [--run] [--auto-skipped|--failed|--stalled] [refactor-list.json]"
72
+ echo ""
73
+ echo " refactor-id Single refactor (e.g. R-007)"
74
+ echo " R-008:R-013 Range of refactors (inclusive)"
75
+ echo " --auto-skipped Reset all auto_skipped refactors"
76
+ echo " --failed Reset all failed refactors"
77
+ echo " --stalled Reset all non-completed (failed + auto_skipped)"
78
+ echo " --clean Delete session history and .prizmkit artifacts"
79
+ echo " --run Retry immediately after reset (single refactor only)"
80
+ echo " refactor-list.json Path to refactor list (default: refactor-list.json)"
81
+ exit 0
82
+ ;;
83
+ R-*:R-*|r-*:r-*) REFACTOR_RANGE="$arg" ;;
84
+ R-*|r-*) REFACTOR_ID="$arg" ;;
85
+ *) REFACTOR_LIST="$arg" ;;
86
+ esac
87
+ done
88
+
89
+ if [[ -z "$REFACTOR_ID" && -z "$REFACTOR_RANGE" && -z "$FILTER_MODE" ]]; then
90
+ echo "Usage: $0 <refactor-id|range> [--clean] [--run] [--auto-skipped|--failed|--stalled] [refactor-list.json]"
91
+ echo ""
92
+ echo " refactor-id Single refactor (e.g. R-007)"
93
+ echo " R-008:R-013 Range of refactors (inclusive)"
94
+ echo " --auto-skipped Reset all auto_skipped refactors"
95
+ echo " --failed Reset all failed refactors"
96
+ echo " --stalled Reset all non-completed (failed + auto_skipped)"
97
+ echo " --clean Delete session history and .prizmkit artifacts"
98
+ echo " --run Retry immediately after reset (single refactor only)"
99
+ echo " refactor-list.json Path to refactor list (default: refactor-list.json)"
100
+ exit 1
101
+ fi
102
+
103
+ REFACTOR_LIST="${REFACTOR_LIST:-refactor-list.json}"
104
+
105
+ # Resolve absolute path
106
+ if [[ ! "$REFACTOR_LIST" = /* ]]; then
107
+ REFACTOR_LIST="$(pwd)/$REFACTOR_LIST"
108
+ fi
109
+
110
+ # ============================================================
111
+ # Validation
112
+ # ============================================================
113
+
114
+ if [[ ! -f "$REFACTOR_LIST" ]]; then
115
+ log_error "Refactor list not found: $REFACTOR_LIST"
116
+ exit 1
117
+ fi
118
+
119
+ if [[ ! -f "$STATE_DIR/pipeline.json" ]]; then
120
+ log_error "No pipeline state found. Run './run-refactor.sh run' first to initialize."
121
+ exit 1
122
+ fi
123
+
124
+ # ============================================================
125
+ # Resolve refactor IDs to process
126
+ # ============================================================
127
+
128
+ REFACTOR_IDS=()
129
+
130
+ if [[ -n "$FILTER_MODE" ]]; then
131
+ # Filter by status from refactor-state/refactors/*/status.json
132
+ while IFS= read -r rid; do
133
+ [[ -n "$rid" ]] && REFACTOR_IDS+=("$rid")
134
+ done < <(python3 -c "
135
+ import json, os, sys
136
+ state_dir = '$STATE_DIR'
137
+ filter_mode = '$FILTER_MODE'
138
+ refactors_dir = os.path.join(state_dir, 'refactors')
139
+ if not os.path.isdir(refactors_dir):
140
+ sys.exit(0)
141
+ for rid in sorted(os.listdir(refactors_dir)):
142
+ status_file = os.path.join(refactors_dir, rid, 'status.json')
143
+ if not os.path.isfile(status_file):
144
+ continue
145
+ with open(status_file) as f:
146
+ status = json.load(f).get('status', '')
147
+ if filter_mode == 'auto_skipped' and status == 'auto_skipped':
148
+ print(rid)
149
+ elif filter_mode == 'failed' and status == 'failed':
150
+ print(rid)
151
+ elif filter_mode == 'stalled' and status in ('failed', 'auto_skipped'):
152
+ print(rid)
153
+ " 2>/dev/null)
154
+
155
+ if [[ ${#REFACTOR_IDS[@]} -eq 0 ]]; then
156
+ log_info "No refactors found with status: $FILTER_MODE"
157
+ exit 0
158
+ fi
159
+ log_info "Found ${#REFACTOR_IDS[@]} refactor(s) matching --$FILTER_MODE: ${REFACTOR_IDS[*]}"
160
+
161
+ elif [[ -n "$REFACTOR_RANGE" ]]; then
162
+ # Parse range R-NNN:R-MMM
163
+ RANGE_START="${REFACTOR_RANGE%%:*}"
164
+ RANGE_END="${REFACTOR_RANGE##*:}"
165
+ START_NUM=$(echo "$RANGE_START" | sed 's/[Rr]-//' | sed 's/^0*//')
166
+ END_NUM=$(echo "$RANGE_END" | sed 's/[Rr]-//' | sed 's/^0*//')
167
+
168
+ if [[ -z "$START_NUM" || -z "$END_NUM" || "$START_NUM" -gt "$END_NUM" ]]; then
169
+ log_error "Invalid range: $REFACTOR_RANGE (start must be <= end)"
170
+ exit 1
171
+ fi
172
+
173
+ for ((i=START_NUM; i<=END_NUM; i++)); do
174
+ REFACTOR_IDS+=("R-$(printf '%03d' "$i")")
175
+ done
176
+ log_info "Range $REFACTOR_RANGE -> ${REFACTOR_IDS[*]}"
177
+
178
+ else
179
+ REFACTOR_IDS=("$REFACTOR_ID")
180
+ fi
181
+
182
+ # --run only works with single refactor
183
+ if [[ "$DO_RUN" == true && ${#REFACTOR_IDS[@]} -gt 1 ]]; then
184
+ log_warn "--run is only supported for single refactor reset. Use './run-refactor.sh run' to resume pipeline after batch reset."
185
+ DO_RUN=false
186
+ fi
187
+
188
+ # ============================================================
189
+ # Process each refactor
190
+ # ============================================================
191
+
192
+ PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
193
+ RESET_COUNT=0
194
+ FAIL_COUNT=0
195
+
196
+ for CUR_REFACTOR_ID in "${REFACTOR_IDS[@]}"; do
197
+
198
+ # Get refactor info from refactor list
199
+ REFACTOR_INFO=$(python3 -c "
200
+ import json, sys, re
201
+ with open('$REFACTOR_LIST') as f:
202
+ data = json.load(f)
203
+ for item in data.get('refactors', []):
204
+ if item.get('id') == '$CUR_REFACTOR_ID':
205
+ title = item.get('title', '')
206
+ # Compute slug
207
+ numeric = '$CUR_REFACTOR_ID'.replace('R-', '').replace('r-', '').zfill(3)
208
+ slug = title.lower()
209
+ slug = re.sub(r'[^a-z0-9\s-]', '', slug)
210
+ slug = re.sub(r'[\s]+', '-', slug.strip())
211
+ slug = re.sub(r'-+', '-', slug).strip('-')
212
+ slug = '{}-{}'.format(numeric, slug)
213
+ print(json.dumps({'title': title, 'slug': slug, 'status': item.get('status', 'unknown')}))
214
+ sys.exit(0)
215
+ sys.exit(1)
216
+ " 2>/dev/null) || {
217
+ log_warn "Refactor $CUR_REFACTOR_ID not found in $REFACTOR_LIST -- skipping"
218
+ FAIL_COUNT=$((FAIL_COUNT + 1))
219
+ continue
220
+ }
221
+
222
+ REFACTOR_TITLE=$(echo "$REFACTOR_INFO" | python3 -c "import sys,json; print(json.load(sys.stdin)['title'])")
223
+ REFACTOR_SLUG=$(echo "$REFACTOR_INFO" | python3 -c "import sys,json; print(json.load(sys.stdin)['slug'])")
224
+
225
+ # -- Show current state --
226
+ echo ""
227
+ echo -e "${BOLD}════════════════════════════════════════════════════${NC}"
228
+ echo -e "${BOLD} Reset: $CUR_REFACTOR_ID — $REFACTOR_TITLE${NC}"
229
+ echo -e "${BOLD}════════════════════════════════════════════════════${NC}"
230
+
231
+ STATUS_FILE="$STATE_DIR/refactors/$CUR_REFACTOR_ID/status.json"
232
+ if [[ -f "$STATUS_FILE" ]]; then
233
+ CURRENT_STATUS=$(python3 -c "import json; d=json.load(open('$STATUS_FILE')); print(d.get('status','?'))")
234
+ CURRENT_RETRY=$(python3 -c "import json; d=json.load(open('$STATUS_FILE')); print(d.get('retry_count',0))")
235
+ SESSION_COUNT=$(python3 -c "import json; d=json.load(open('$STATUS_FILE')); print(len(d.get('sessions',[])))")
236
+ log_info "Current status: $CURRENT_STATUS (retry $CURRENT_RETRY, $SESSION_COUNT sessions)"
237
+ else
238
+ log_info "No status file found (never executed)"
239
+ fi
240
+
241
+ SPECS_DIR="$PROJECT_ROOT/.prizmkit/specs/$REFACTOR_SLUG"
242
+ SPECS_COUNT=0
243
+ if [[ -d "$SPECS_DIR" ]]; then
244
+ SPECS_COUNT=$(find "$SPECS_DIR" -type f 2>/dev/null | wc -l | tr -d ' ')
245
+ log_info "PrizmKit artifacts: $SPECS_COUNT files in .prizmkit/specs/$REFACTOR_SLUG/"
246
+ fi
247
+
248
+ SESSIONS_DIR="$STATE_DIR/refactors/$CUR_REFACTOR_ID/sessions"
249
+ SESSIONS_COUNT=0
250
+ if [[ -d "$SESSIONS_DIR" ]]; then
251
+ SESSIONS_COUNT=$(find "$SESSIONS_DIR" -mindepth 1 -maxdepth 1 -type d 2>/dev/null | wc -l | tr -d ' ')
252
+ log_info "Session history: $SESSIONS_COUNT session(s)"
253
+ fi
254
+
255
+ echo -e "${BOLD}════════════════════════════════════════════════════${NC}"
256
+
257
+ # -- Execute reset --
258
+ if [[ "$DO_CLEAN" == true ]]; then
259
+ log_info "Cleaning $CUR_REFACTOR_ID (reset + delete artifacts)..."
260
+ RESULT=$(python3 "$SCRIPTS_DIR/update-refactor-status.py" \
261
+ --refactor-list "$REFACTOR_LIST" \
262
+ --state-dir "$STATE_DIR" \
263
+ --refactor-id "$CUR_REFACTOR_ID" \
264
+ --project-root "$PROJECT_ROOT" \
265
+ --action clean 2>&1)
266
+ else
267
+ log_info "Resetting $CUR_REFACTOR_ID status..."
268
+ RESULT=$(python3 "$SCRIPTS_DIR/update-refactor-status.py" \
269
+ --refactor-list "$REFACTOR_LIST" \
270
+ --state-dir "$STATE_DIR" \
271
+ --refactor-id "$CUR_REFACTOR_ID" \
272
+ --action reset 2>&1)
273
+ fi
274
+
275
+ # Check for errors
276
+ 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
277
+ RESET_COUNT=$((RESET_COUNT + 1))
278
+ if [[ "$DO_CLEAN" == true ]]; then
279
+ log_success "$CUR_REFACTOR_ID cleaned: status -> pending, $SESSIONS_COUNT session(s) deleted, $SPECS_COUNT artifact(s) deleted"
280
+ else
281
+ log_success "$CUR_REFACTOR_ID reset: status -> pending, retry count -> 0"
282
+ fi
283
+ else
284
+ ERROR_MSG=$(echo "$RESULT" | python3 -c "import sys,json; print(json.load(sys.stdin).get('error','unknown'))" 2>/dev/null || echo "$RESULT")
285
+ log_error "Reset $CUR_REFACTOR_ID failed: $ERROR_MSG"
286
+ FAIL_COUNT=$((FAIL_COUNT + 1))
287
+ fi
288
+
289
+ done
290
+
291
+ # ============================================================
292
+ # Summary
293
+ # ============================================================
294
+
295
+ echo ""
296
+ echo -e "${BOLD}════════════════════════════════════════════════════${NC}"
297
+ echo -e "${BOLD} Reset complete: $RESET_COUNT succeeded, $FAIL_COUNT failed${NC}"
298
+ echo -e "${BOLD}════════════════════════════════════════════════════${NC}"
299
+
300
+ echo ""
301
+ echo -e "${BOLD}Next steps:${NC}"
302
+ if [[ "$DO_RUN" == true && ${#REFACTOR_IDS[@]} -eq 1 ]]; then
303
+ log_info "Auto-retrying ${REFACTOR_IDS[0]}..."
304
+ echo ""
305
+ exec "$SCRIPT_DIR/retry-refactor.sh" "${REFACTOR_IDS[0]}" "$REFACTOR_LIST"
306
+ else
307
+ log_info " ./dev-pipeline/run-refactor.sh run refactor-list.json # Resume pipeline from first pending"
308
+ if [[ ${#REFACTOR_IDS[@]} -eq 1 ]]; then
309
+ log_info " ./dev-pipeline/retry-refactor.sh ${REFACTOR_IDS[0]} # Retry single refactor"
310
+ fi
311
+ fi
312
+ echo ""
@@ -2,19 +2,19 @@
2
2
  set -euo pipefail
3
3
 
4
4
  # ============================================================
5
- # dev-pipeline/retry-bug.sh - Retry a single failed bug fix
5
+ # dev-pipeline/retry-bugfix.sh - Retry a single failed bug fix
6
6
  #
7
7
  # Runs exactly ONE AI CLI session for the specified bug, then exits.
8
8
  # Use this to manually retry a failed bug without restarting
9
9
  # the full bugfix pipeline.
10
10
  #
11
11
  # Usage:
12
- # ./retry-bug.sh <bug-id> [bug-fix-list.json]
12
+ # ./retry-bugfix.sh <bug-id> [bug-fix-list.json]
13
13
  #
14
14
  # Examples:
15
- # ./retry-bug.sh B-001
16
- # ./retry-bug.sh B-001 bug-fix-list.json
17
- # SESSION_TIMEOUT=3600 ./retry-bug.sh B-001
15
+ # ./retry-bugfix.sh B-001
16
+ # ./retry-bugfix.sh B-001 bug-fix-list.json
17
+ # SESSION_TIMEOUT=3600 ./retry-bugfix.sh B-001
18
18
  # ============================================================
19
19
 
20
20
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
@@ -23,68 +23,22 @@ SCRIPTS_DIR="$SCRIPT_DIR/scripts"
23
23
 
24
24
  SESSION_TIMEOUT=${SESSION_TIMEOUT:-0}
25
25
  HEARTBEAT_INTERVAL=${HEARTBEAT_INTERVAL:-30}
26
+ AUTO_PUSH=${AUTO_PUSH:-0}
27
+ DEV_BRANCH=${DEV_BRANCH:-""}
26
28
 
27
- # AI CLI detection: AI_CLI env > .prizmkit/config.json > CODEBUDDY_CLI > auto-detect
28
- if [[ -n "${AI_CLI:-}" ]]; then
29
- CLI_CMD="$AI_CLI"
30
- elif [[ -f ".prizmkit/config.json" ]]; then
31
- _config_cli=$(python3 -c "
32
- import json, sys
33
- try:
34
- with open('.prizmkit/config.json') as f:
35
- d = json.load(f)
36
- v = d.get('ai_cli', '')
37
- if v: print(v)
38
- except: pass
39
- " 2>/dev/null || true)
40
- CLI_CMD="${_config_cli:-}"
41
- if [[ -z "$CLI_CMD" ]]; then
42
- if [[ -n "${CODEBUDDY_CLI:-}" ]]; then CLI_CMD="$CODEBUDDY_CLI"
43
- elif command -v cbc &>/dev/null; then CLI_CMD="cbc"
44
- elif command -v claude &>/dev/null; then CLI_CMD="claude"
45
- else echo "ERROR: No AI CLI found. Set AI_CLI or configure .prizmkit/config.json" >&2; exit 1
46
- fi
47
- fi
48
- elif [[ -n "${CODEBUDDY_CLI:-}" ]]; then
49
- CLI_CMD="$CODEBUDDY_CLI"
50
- elif command -v cbc &>/dev/null; then
51
- CLI_CMD="cbc"
52
- elif command -v claude &>/dev/null; then
53
- CLI_CMD="claude"
54
- else
55
- echo "ERROR: No AI CLI found. Install CodeBuddy (cbc) or Claude Code (claude), or set AI_CLI." >&2
56
- exit 1
57
- fi
58
-
59
- # Platform detection
60
- if [[ -n "${PRIZMKIT_PLATFORM:-}" ]]; then
61
- PLATFORM="$PRIZMKIT_PLATFORM"
62
- elif [[ "$CLI_CMD" == *"claude"* ]]; then
63
- PLATFORM="claude"
64
- else
65
- PLATFORM="codebuddy"
66
- fi
67
- export PRIZMKIT_PLATFORM="$PLATFORM"
29
+ # Source shared libraries (CLI/platform detection + logs + deps)
30
+ source "$SCRIPT_DIR/lib/common.sh"
31
+ prizm_detect_cli_and_platform
68
32
 
69
33
  # Source shared heartbeat library
70
34
  source "$SCRIPT_DIR/lib/heartbeat.sh"
71
35
 
36
+ # Source shared branch library
37
+ source "$SCRIPT_DIR/lib/branch.sh"
38
+
72
39
  # Detect stream-json support
73
40
  detect_stream_json_support "$CLI_CMD"
74
41
 
75
- # Colors
76
- RED='\033[0;31m'
77
- GREEN='\033[0;32m'
78
- YELLOW='\033[1;33m'
79
- BLUE='\033[0;34m'
80
- BOLD='\033[1m'
81
- NC='\033[0m'
82
-
83
- log_info() { echo -e "${BLUE}[INFO]${NC} $(date '+%Y-%m-%d %H:%M:%S') $*"; }
84
- log_warn() { echo -e "${YELLOW}[WARN]${NC} $(date '+%Y-%m-%d %H:%M:%S') $*"; }
85
- log_error() { echo -e "${RED}[ERROR]${NC} $(date '+%Y-%m-%d %H:%M:%S') $*"; }
86
- log_success() { echo -e "${GREEN}[SUCCESS]${NC} $(date '+%Y-%m-%d %H:%M:%S') $*"; }
87
-
88
42
  # ============================================================
89
43
  # Args
90
44
  # ============================================================
@@ -98,6 +52,9 @@ if [[ $# -lt 1 ]]; then
98
52
  echo "Environment Variables:"
99
53
  echo " SESSION_TIMEOUT Timeout in seconds (default: 0 = no limit)"
100
54
  echo " HEARTBEAT_INTERVAL Heartbeat interval in seconds (default: 30)"
55
+ echo " AI_CLI AI CLI command (auto-detected: cbc or claude)"
56
+ echo " AUTO_PUSH Auto-push to remote after fix (default: 0)"
57
+ echo " DEV_BRANCH Custom dev branch name (default: auto-generated)"
101
58
  exit 1
102
59
  fi
103
60
 
@@ -166,6 +123,9 @@ sys.exit(1)
166
123
  PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
167
124
  ORIGINAL_BRANCH=$(git -C "$PROJECT_ROOT" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "main")
168
125
 
126
+ # Branch tracking (for cleanup on interrupt)
127
+ _DEV_BRANCH_NAME=""
128
+
169
129
  log_info "Cleaning $BUG_ID artifacts for full restart..."
170
130
  python3 "$SCRIPTS_DIR/update-bug-status.py" \
171
131
  --bug-list "$BUG_LIST" \
@@ -202,6 +162,15 @@ python3 "$SCRIPTS_DIR/generate-bugfix-prompt.py" \
202
162
  # Run single AI CLI session
203
163
  # ============================================================
204
164
 
165
+ # Branch lifecycle: create and checkout bugfix branch
166
+ _branch_name="${DEV_BRANCH:-bugfix/${BUG_ID}-$(date +%s)}"
167
+ if branch_create "$PROJECT_ROOT" "$_branch_name" "$ORIGINAL_BRANCH"; then
168
+ _DEV_BRANCH_NAME="$_branch_name"
169
+ log_info "Dev branch: $_branch_name"
170
+ else
171
+ log_warn "Failed to create branch; running session on current branch"
172
+ fi
173
+
205
174
  echo ""
206
175
  echo -e "${BOLD}════════════════════════════════════════════════════${NC}"
207
176
  echo -e "${BOLD} Retry Bug Fix: $BUG_ID — $BUG_TITLE${NC}"
@@ -295,6 +264,10 @@ cleanup() {
295
264
  stop_progress_parser "$PARSER_PID"
296
265
  wait "$CLI_PID" 2>/dev/null || true
297
266
  [[ -n "$WATCHER_PID" ]] && wait "$WATCHER_PID" 2>/dev/null || true
267
+ if [[ -n "$_DEV_BRANCH_NAME" ]]; then
268
+ log_info "Development was on branch: $_DEV_BRANCH_NAME"
269
+ log_info "Original branch was: $ORIGINAL_BRANCH"
270
+ fi
298
271
  log_info "Session log: $SESSION_LOG"
299
272
  exit 130
300
273
  }
@@ -380,6 +353,15 @@ if [[ "$SESSION_STATUS" == "success" ]]; then
380
353
  fi
381
354
  fi
382
355
 
356
+ # ── Merge dev branch back to original on success ────────────────────
357
+ if [[ "$SESSION_STATUS" == "success" && -n "$_DEV_BRANCH_NAME" ]]; then
358
+ if branch_merge "$PROJECT_ROOT" "$_DEV_BRANCH_NAME" "$ORIGINAL_BRANCH" "$AUTO_PUSH"; then
359
+ _DEV_BRANCH_NAME=""
360
+ else
361
+ log_warn "Auto-merge failed — dev branch preserved: $_DEV_BRANCH_NAME"
362
+ fi
363
+ fi
364
+
383
365
  # Update bug status
384
366
  python3 "$SCRIPTS_DIR/update-bug-status.py" \
385
367
  --bug-list "$BUG_LIST" \
@@ -390,6 +372,12 @@ python3 "$SCRIPTS_DIR/update-bug-status.py" \
390
372
  --max-retries 999 \
391
373
  --action update >/dev/null 2>&1 || true
392
374
 
375
+ # Commit bug-fix-list.json status update (pipeline management commit)
376
+ if ! git -C "$PROJECT_ROOT" diff --quiet "$BUG_LIST" 2>/dev/null; then
377
+ git -C "$PROJECT_ROOT" add "$BUG_LIST"
378
+ git -C "$PROJECT_ROOT" commit --no-verify -m "chore($BUG_ID): update bug status" 2>/dev/null || true
379
+ fi
380
+
393
381
  echo ""
394
382
  if [[ "$SESSION_STATUS" == "success" ]]; then
395
383
  log_success "════════════════════════════════════════════════════"
@@ -24,66 +24,23 @@ SCRIPTS_DIR="$SCRIPT_DIR/scripts"
24
24
  SESSION_TIMEOUT=${SESSION_TIMEOUT:-0}
25
25
  HEARTBEAT_INTERVAL=${HEARTBEAT_INTERVAL:-30}
26
26
 
27
- # AI CLI detection: AI_CLI env > .prizmkit/config.json > CODEBUDDY_CLI > auto-detect
28
- if [[ -n "${AI_CLI:-}" ]]; then
29
- CLI_CMD="$AI_CLI"
30
- elif [[ -f ".prizmkit/config.json" ]]; then
31
- _config_cli=$(python3 -c "
32
- import json, sys
33
- try:
34
- with open('.prizmkit/config.json') as f:
35
- d = json.load(f)
36
- v = d.get('ai_cli', '')
37
- if v: print(v)
38
- except: pass
39
- " 2>/dev/null || true)
40
- CLI_CMD="${_config_cli:-}"
41
- if [[ -z "$CLI_CMD" ]]; then
42
- if [[ -n "${CODEBUDDY_CLI:-}" ]]; then CLI_CMD="$CODEBUDDY_CLI"
43
- elif command -v cbc &>/dev/null; then CLI_CMD="cbc"
44
- elif command -v claude &>/dev/null; then CLI_CMD="claude"
45
- else echo "ERROR: No AI CLI found. Set AI_CLI or configure .prizmkit/config.json" >&2; exit 1
46
- fi
47
- fi
48
- elif [[ -n "${CODEBUDDY_CLI:-}" ]]; then
49
- CLI_CMD="$CODEBUDDY_CLI"
50
- elif command -v cbc &>/dev/null; then
51
- CLI_CMD="cbc"
52
- elif command -v claude &>/dev/null; then
53
- CLI_CMD="claude"
54
- else
55
- echo "ERROR: No AI CLI found. Install CodeBuddy (cbc) or Claude Code (claude), or set AI_CLI." >&2
56
- exit 1
57
- fi
58
-
59
- # Platform detection
60
- if [[ -n "${PRIZMKIT_PLATFORM:-}" ]]; then
61
- PLATFORM="$PRIZMKIT_PLATFORM"
62
- elif [[ "$CLI_CMD" == *"claude"* ]]; then
63
- PLATFORM="claude"
64
- else
65
- PLATFORM="codebuddy"
66
- fi
67
- export PRIZMKIT_PLATFORM="$PLATFORM"
27
+ # Source shared common helpers (CLI/platform detection + logs + deps)
28
+ source "$SCRIPT_DIR/lib/common.sh"
29
+ prizm_detect_cli_and_platform
68
30
 
69
31
  # Source shared heartbeat library
70
32
  source "$SCRIPT_DIR/lib/heartbeat.sh"
71
33
 
34
+ # Source shared branch library
35
+ source "$SCRIPT_DIR/lib/branch.sh"
36
+
72
37
  # Detect stream-json support
73
38
  detect_stream_json_support "$CLI_CMD"
74
39
 
75
- # Colors
76
- RED='\033[0;31m'
77
- GREEN='\033[0;32m'
78
- YELLOW='\033[1;33m'
79
- BLUE='\033[0;34m'
80
- BOLD='\033[1m'
81
- NC='\033[0m'
82
-
83
- log_info() { echo -e "${BLUE}[INFO]${NC} $(date '+%Y-%m-%d %H:%M:%S') $*"; }
84
- log_warn() { echo -e "${YELLOW}[WARN]${NC} $(date '+%Y-%m-%d %H:%M:%S') $*"; }
85
- log_error() { echo -e "${RED}[ERROR]${NC} $(date '+%Y-%m-%d %H:%M:%S') $*"; }
86
- log_success() { echo -e "${GREEN}[SUCCESS]${NC} $(date '+%Y-%m-%d %H:%M:%S') $*"; }
40
+ # Branch tracking
41
+ _ORIGINAL_BRANCH=""
42
+ _DEV_BRANCH_NAME=""
43
+ AUTO_PUSH=${AUTO_PUSH:-0}
87
44
 
88
45
  # ============================================================
89
46
  # Args
@@ -120,7 +77,7 @@ if [[ ! -f "$FEATURE_LIST" ]]; then
120
77
  fi
121
78
 
122
79
  if [[ ! -f "$STATE_DIR/pipeline.json" ]]; then
123
- log_error "No pipeline state found. Run './run.sh run' first to initialize."
80
+ log_error "No pipeline state found. Run './run-feature.sh run' first to initialize."
124
81
  exit 1
125
82
  fi
126
83
 
@@ -150,6 +107,7 @@ sys.exit(1)
150
107
 
151
108
  PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
152
109
  ORIGINAL_BRANCH=$(git -C "$PROJECT_ROOT" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "main")
110
+ _ORIGINAL_BRANCH="$ORIGINAL_BRANCH"
153
111
  FEATURE_SLUG=$(FEATURE_ID="$FEATURE_ID" FEATURE_TITLE="$FEATURE_TITLE" python3 -c "
154
112
  import os, re
155
113
  fid = os.environ['FEATURE_ID'].replace('F-', '').replace('f-', '').zfill(3)
@@ -232,6 +190,15 @@ log_info "Log: $SESSION_DIR/logs/session.log"
232
190
  echo -e "${BOLD}════════════════════════════════════════════════════${NC}"
233
191
  echo ""
234
192
 
193
+ # Create per-feature dev branch (consistent with run-feature.sh behavior)
194
+ _feature_branch="${DEV_BRANCH:-dev/${FEATURE_ID}-retry-$(date +%Y%m%d%H%M)}"
195
+ if branch_create "$PROJECT_ROOT" "$_feature_branch" "$_ORIGINAL_BRANCH"; then
196
+ _DEV_BRANCH_NAME="$_feature_branch"
197
+ log_info "Dev branch: $_feature_branch"
198
+ else
199
+ log_warn "Failed to create dev branch; running on current branch"
200
+ fi
201
+
235
202
  SESSION_LOG="$SESSION_DIR/logs/session.log"
236
203
  PROGRESS_JSON="$SESSION_DIR/logs/progress.json"
237
204
 
@@ -409,6 +376,26 @@ python3 "$SCRIPTS_DIR/update-feature-status.py" \
409
376
  --max-retries 999 \
410
377
  --action update >/dev/null 2>&1 || true
411
378
 
379
+ # Commit feature-list.json status update (pipeline management commit)
380
+ if ! git -C "$PROJECT_ROOT" diff --quiet "$FEATURE_LIST" 2>/dev/null; then
381
+ git -C "$PROJECT_ROOT" add "$FEATURE_LIST"
382
+ git -C "$PROJECT_ROOT" commit --no-verify -m "chore($FEATURE_ID): update feature status" 2>/dev/null || true
383
+ fi
384
+
385
+ # Merge dev branch back to original on success
386
+ if [[ "$SESSION_STATUS" == "success" && -n "$_DEV_BRANCH_NAME" ]]; then
387
+ if branch_merge "$PROJECT_ROOT" "$_DEV_BRANCH_NAME" "$_ORIGINAL_BRANCH" "$AUTO_PUSH"; then
388
+ _DEV_BRANCH_NAME=""
389
+ else
390
+ log_warn "Auto-merge failed — dev branch preserved: $_DEV_BRANCH_NAME"
391
+ fi
392
+ elif [[ -n "$_DEV_BRANCH_NAME" ]]; then
393
+ # Session failed — return to original branch, preserve dev branch for inspection
394
+ git -C "$PROJECT_ROOT" checkout "$_ORIGINAL_BRANCH" 2>/dev/null || true
395
+ log_warn "Session failed — dev branch preserved for inspection: $_DEV_BRANCH_NAME"
396
+ _DEV_BRANCH_NAME=""
397
+ fi
398
+
412
399
  echo ""
413
400
  if [[ "$SESSION_STATUS" == "success" ]]; then
414
401
  log_success "════════════════════════════════════════════════════"