prizmkit 1.1.7 → 1.1.9

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 (132) hide show
  1. package/bundled/VERSION.json +3 -3
  2. package/bundled/adapters/codebuddy/skill-adapter.js +21 -7
  3. package/bundled/agents/prizm-dev-team-reviewer.md +53 -173
  4. package/bundled/dev-pipeline/.env.example +45 -0
  5. package/bundled/dev-pipeline/README.md +64 -64
  6. package/bundled/dev-pipeline/SCHEMA_ANALYSIS.md +535 -0
  7. package/bundled/dev-pipeline/assets/feature-list-example.json +0 -1
  8. package/bundled/dev-pipeline/launch-bugfix-daemon.sh +64 -18
  9. package/bundled/dev-pipeline/launch-feature-daemon.sh +15 -12
  10. package/bundled/dev-pipeline/launch-refactor-daemon.sh +64 -18
  11. package/bundled/dev-pipeline/lib/branch.sh +6 -1
  12. package/bundled/dev-pipeline/lib/common.sh +71 -0
  13. package/bundled/dev-pipeline/lib/heartbeat.sh +2 -2
  14. package/bundled/dev-pipeline/reset-bug.sh +10 -9
  15. package/bundled/dev-pipeline/reset-feature.sh +9 -8
  16. package/bundled/dev-pipeline/reset-refactor.sh +10 -9
  17. package/bundled/dev-pipeline/retry-bugfix.sh +67 -29
  18. package/bundled/dev-pipeline/retry-feature.sh +54 -18
  19. package/bundled/dev-pipeline/retry-refactor.sh +112 -29
  20. package/bundled/dev-pipeline/run-bugfix.sh +281 -59
  21. package/bundled/dev-pipeline/run-feature.sh +53 -18
  22. package/bundled/dev-pipeline/run-refactor.sh +392 -66
  23. package/bundled/dev-pipeline/scripts/check-session-status.py +24 -1
  24. package/bundled/dev-pipeline/scripts/cleanup-logs.py +2 -2
  25. package/bundled/dev-pipeline/scripts/detect-stuck.py +195 -85
  26. package/bundled/dev-pipeline/scripts/generate-bootstrap-prompt.py +57 -33
  27. package/bundled/dev-pipeline/scripts/generate-bugfix-prompt.py +25 -9
  28. package/bundled/dev-pipeline/scripts/generate-refactor-prompt.py +104 -17
  29. package/bundled/dev-pipeline/scripts/init-bugfix-pipeline.py +34 -9
  30. package/bundled/dev-pipeline/scripts/init-pipeline.py +10 -10
  31. package/bundled/dev-pipeline/scripts/init-refactor-pipeline.py +19 -8
  32. package/bundled/dev-pipeline/scripts/parse-stream-progress.py +1 -5
  33. package/bundled/dev-pipeline/scripts/patch-completion-notes.py +191 -0
  34. package/bundled/dev-pipeline/scripts/update-bug-status.py +167 -22
  35. package/bundled/dev-pipeline/scripts/update-feature-status.py +104 -62
  36. package/bundled/dev-pipeline/scripts/update-refactor-status.py +351 -21
  37. package/bundled/dev-pipeline/templates/agent-prompts/dev-fix.md +1 -1
  38. package/bundled/dev-pipeline/templates/agent-prompts/reviewer-review.md +7 -11
  39. package/bundled/dev-pipeline/templates/bootstrap-prompt.md +41 -7
  40. package/bundled/dev-pipeline/templates/bootstrap-tier1.md +27 -3
  41. package/bundled/dev-pipeline/templates/bootstrap-tier2.md +43 -19
  42. package/bundled/dev-pipeline/templates/bootstrap-tier3.md +54 -26
  43. package/bundled/dev-pipeline/templates/bug-fix-list-schema.json +6 -15
  44. package/bundled/dev-pipeline/templates/bugfix-bootstrap-prompt.md +36 -25
  45. package/bundled/dev-pipeline/templates/feature-list-schema.json +109 -31
  46. package/bundled/dev-pipeline/templates/refactor-bootstrap-prompt.md +270 -0
  47. package/bundled/dev-pipeline/templates/refactor-list-schema.json +11 -3
  48. package/bundled/dev-pipeline/templates/sections/context-budget-rules.md +3 -1
  49. package/bundled/dev-pipeline/templates/sections/critical-paths-agent.md +1 -0
  50. package/bundled/dev-pipeline/templates/sections/feature-context.md +2 -0
  51. package/bundled/dev-pipeline/templates/sections/phase-commit-full.md +29 -2
  52. package/bundled/dev-pipeline/templates/sections/phase-commit.md +22 -0
  53. package/bundled/dev-pipeline/templates/sections/phase-deploy-verification.md +2 -2
  54. package/bundled/dev-pipeline/templates/sections/phase-review-agent.md +8 -6
  55. package/bundled/dev-pipeline/templates/sections/phase-review-full.md +7 -5
  56. package/bundled/dev-pipeline/templates/sections/phase-specify-plan-full.md +3 -3
  57. package/bundled/skills/_metadata.json +5 -22
  58. package/bundled/skills/app-planner/SKILL.md +98 -72
  59. package/bundled/skills/app-planner/assets/app-design-guide.md +1 -1
  60. package/bundled/skills/app-planner/references/architecture-decisions.md +1 -1
  61. package/bundled/skills/app-planner/references/project-brief-guide.md +69 -66
  62. package/bundled/skills/bug-fix-workflow/SKILL.md +52 -9
  63. package/bundled/skills/bug-planner/SKILL.md +139 -197
  64. package/bundled/skills/bug-planner/assets/bug-confirmation-template.md +43 -0
  65. package/bundled/skills/bug-planner/references/critic-and-verification.md +44 -0
  66. package/bundled/skills/bug-planner/references/error-recovery.md +73 -0
  67. package/bundled/skills/bug-planner/references/input-formats.md +53 -0
  68. package/bundled/skills/bug-planner/references/schema-validation.md +25 -0
  69. package/bundled/skills/bug-planner/references/severity-rules.md +16 -0
  70. package/bundled/skills/bug-planner/scripts/validate-bug-list.py +4 -8
  71. package/bundled/skills/bugfix-pipeline-launcher/SKILL.md +34 -39
  72. package/bundled/skills/feature-pipeline-launcher/SKILL.md +49 -36
  73. package/bundled/skills/feature-pipeline-launcher/scripts/preflight-check.py +3 -3
  74. package/bundled/skills/feature-planner/SKILL.md +53 -142
  75. package/bundled/skills/feature-planner/assets/evaluation-guide.md +1 -1
  76. package/bundled/skills/feature-planner/assets/planning-guide.md +21 -5
  77. package/bundled/skills/feature-planner/references/browser-interaction.md +2 -4
  78. package/bundled/skills/feature-planner/references/completeness-review.md +57 -0
  79. package/bundled/skills/feature-planner/references/error-recovery.md +16 -35
  80. package/bundled/skills/feature-planner/references/incremental-feature-planning.md +1 -1
  81. package/bundled/skills/feature-planner/references/new-project-planning.md +2 -2
  82. package/bundled/skills/feature-planner/scripts/validate-and-generate.py +19 -20
  83. package/bundled/skills/feature-workflow/SKILL.md +24 -25
  84. package/bundled/skills/prizm-kit/SKILL.md +39 -49
  85. package/bundled/skills/prizmkit-code-review/SKILL.md +51 -64
  86. package/bundled/skills/prizmkit-code-review/rules/dimensions.md +85 -0
  87. package/bundled/skills/prizmkit-code-review/rules/fix-strategy.md +11 -11
  88. package/bundled/skills/prizmkit-committer/SKILL.md +3 -31
  89. package/bundled/skills/prizmkit-deploy/SKILL.md +34 -31
  90. package/bundled/skills/prizmkit-deploy/assets/deploy-template.md +1 -1
  91. package/bundled/skills/prizmkit-implement/SKILL.md +35 -68
  92. package/bundled/skills/prizmkit-init/SKILL.md +112 -65
  93. package/bundled/skills/prizmkit-init/assets/project-brief-template.md +82 -0
  94. package/bundled/skills/prizmkit-plan/SKILL.md +120 -79
  95. package/bundled/skills/prizmkit-plan/assets/plan-template.md +28 -18
  96. package/bundled/skills/prizmkit-plan/assets/spec-template.md +28 -11
  97. package/bundled/skills/prizmkit-plan/references/clarify-guide.md +3 -3
  98. package/bundled/skills/prizmkit-plan/references/verification-checklist.md +60 -0
  99. package/bundled/skills/prizmkit-prizm-docs/SKILL.md +10 -81
  100. package/bundled/skills/prizmkit-prizm-docs/assets/{PRIZM-SPEC.md → prizm-docs-format.md} +41 -526
  101. package/bundled/skills/prizmkit-prizm-docs/references/op-init.md +46 -0
  102. package/bundled/skills/prizmkit-prizm-docs/references/op-rebuild.md +16 -0
  103. package/bundled/skills/prizmkit-prizm-docs/references/op-status.md +14 -0
  104. package/bundled/skills/prizmkit-prizm-docs/references/op-update.md +19 -0
  105. package/bundled/skills/prizmkit-prizm-docs/references/op-validate.md +17 -0
  106. package/bundled/skills/prizmkit-retrospective/SKILL.md +27 -65
  107. package/bundled/skills/prizmkit-retrospective/references/knowledge-injection-steps.md +3 -4
  108. package/bundled/skills/prizmkit-retrospective/references/structural-sync-steps.md +7 -25
  109. package/bundled/skills/recovery-workflow/SKILL.md +22 -22
  110. package/bundled/skills/recovery-workflow/evals/evals.json +5 -5
  111. package/bundled/skills/recovery-workflow/scripts/detect-recovery-state.py +43 -10
  112. package/bundled/skills/refactor-pipeline-launcher/SKILL.md +48 -40
  113. package/bundled/skills/refactor-planner/SKILL.md +43 -61
  114. package/bundled/skills/refactor-planner/scripts/validate-and-generate-refactor.py +17 -17
  115. package/bundled/skills/refactor-workflow/SKILL.md +23 -24
  116. package/bundled/team/prizm-dev-team.json +1 -1
  117. package/bundled/{skills/prizm-kit/assets → templates}/project-memory-template.md +1 -1
  118. package/package.json +1 -1
  119. package/src/clean.js +3 -4
  120. package/src/gitignore-template.js +7 -9
  121. package/src/scaffold.js +14 -5
  122. package/bundled/dev-pipeline/templates/agent-prompts/reviewer-analyze.md +0 -5
  123. package/bundled/dev-pipeline/templates/sections/phase-analyze-agent.md +0 -19
  124. package/bundled/dev-pipeline/templates/sections/phase-analyze-full.md +0 -19
  125. package/bundled/skills/app-planner/references/project-conventions.md +0 -93
  126. package/bundled/skills/prizmkit-analyze/SKILL.md +0 -207
  127. package/bundled/skills/prizmkit-code-review/rules/dimensions-bugfix.md +0 -25
  128. package/bundled/skills/prizmkit-code-review/rules/dimensions-feature.md +0 -43
  129. package/bundled/skills/prizmkit-code-review/rules/dimensions-refactor.md +0 -25
  130. package/bundled/skills/prizmkit-implement/references/deploy-guide-protocol.md +0 -69
  131. package/bundled/skills/prizmkit-verify/SKILL.md +0 -281
  132. package/bundled/skills/prizmkit-verify/scripts/verify-light.py +0 -402
@@ -8,23 +8,24 @@ set -euo pipefail
8
8
  # log consolidation, and lifecycle commands.
9
9
  #
10
10
  # Usage:
11
- # ./launch-bugfix-daemon.sh start [bug-fix-list.json] [--env "KEY=VAL ..."]
11
+ # ./launch-bugfix-daemon.sh start [.prizmkit/plans/bug-fix-list.json] [--mode <mode>] [--critic] [--env "KEY=VAL ..."]
12
12
  # ./launch-bugfix-daemon.sh stop
13
13
  # ./launch-bugfix-daemon.sh status
14
14
  # ./launch-bugfix-daemon.sh logs [--lines N] [--follow]
15
- # ./launch-bugfix-daemon.sh restart [bug-fix-list.json] [--env "KEY=VAL ..."]
15
+ # ./launch-bugfix-daemon.sh restart [.prizmkit/plans/bug-fix-list.json] [--mode <mode>] [--critic] [--env "KEY=VAL ..."]
16
16
  #
17
17
  # NOTE:
18
18
  # In AI skill sessions, always use this daemon wrapper.
19
19
  # Do NOT call `run-bugfix.sh run ...` directly, because foreground sessions may be killed by CLI timeout.
20
20
  #
21
21
  # Files managed:
22
- # bugfix-state/.pipeline.pid - PID of the background run-bugfix.sh process
23
- # bugfix-state/pipeline-daemon.log - Consolidated stdout+stderr
22
+ # .prizmkit/state/bugfix/.pipeline.pid - PID of the background run-bugfix.sh process
23
+ # .prizmkit/state/bugfix/pipeline-daemon.log - Consolidated stdout+stderr
24
24
  # ============================================================
25
25
 
26
26
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
27
- STATE_DIR="$SCRIPT_DIR/bugfix-state"
27
+ PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
28
+ STATE_DIR="${PROJECT_ROOT}/.prizmkit/state/bugfix"
28
29
  PID_FILE="$STATE_DIR/.pipeline.pid"
29
30
  LOG_FILE="$STATE_DIR/pipeline-daemon.log"
30
31
  RUN_SCRIPT="$SCRIPT_DIR/run-bugfix.sh"
@@ -92,12 +93,37 @@ cmd_start() {
92
93
  while [[ $# -gt 0 ]]; do
93
94
  case "$1" in
94
95
  --env) shift; env_overrides="${1:-}"; shift ;;
96
+ --mode)
97
+ shift
98
+ if [[ $# -eq 0 ]]; then
99
+ log_error "--mode requires a value (lite|standard|full)"
100
+ exit 1
101
+ fi
102
+ case "$1" in
103
+ lite|standard|full)
104
+ PIPELINE_MODE="$1"
105
+ ;;
106
+ *)
107
+ log_error "Invalid mode: $1 (must be lite, standard, or full)"
108
+ exit 1
109
+ ;;
110
+ esac
111
+ shift
112
+ ;;
113
+ --critic)
114
+ ENABLE_CRITIC=true
115
+ shift
116
+ ;;
117
+ --no-critic)
118
+ ENABLE_CRITIC=false
119
+ shift
120
+ ;;
95
121
  *) bug_list="$1"; shift ;;
96
122
  esac
97
123
  done
98
124
 
99
125
  if [[ -z "$bug_list" ]]; then
100
- bug_list="bug-fix-list.json"
126
+ bug_list=".prizmkit/plans/bug-fix-list.json"
101
127
  fi
102
128
  if [[ ! "$bug_list" = /* ]]; then
103
129
  bug_list="$(cd "$(dirname "$bug_list")" 2>/dev/null && pwd)/$(basename "$bug_list")"
@@ -105,7 +131,7 @@ cmd_start() {
105
131
 
106
132
  if [[ ! -f "$bug_list" ]]; then
107
133
  log_error "Bug fix list not found: $bug_list"
108
- log_error "Run the bug-planner skill first to generate bug-fix-list.json"
134
+ log_error "Run the bug-planner skill first to generate .prizmkit/plans/bug-fix-list.json"
109
135
  exit 2
110
136
  fi
111
137
 
@@ -165,6 +191,9 @@ cmd_start() {
165
191
  echo ""
166
192
  } >> "$LOG_FILE"
167
193
 
194
+ [[ -n "${PIPELINE_MODE:-}" ]] && export PIPELINE_MODE
195
+ [[ -n "${ENABLE_CRITIC:-}" ]] && export ENABLE_CRITIC
196
+
168
197
  if [[ -n "$env_cmd" ]]; then
169
198
  nohup $env_cmd "$RUN_SCRIPT" run "$bug_list" >> "$LOG_FILE" 2>&1 &
170
199
  else
@@ -173,11 +202,12 @@ cmd_start() {
173
202
  local pipeline_pid=$!
174
203
  disown "$pipeline_pid" 2>/dev/null || true
175
204
 
176
- echo "$pipeline_pid" > "$PID_FILE"
205
+ echo "$pipeline_pid" > "${PID_FILE}.tmp"
206
+ mv "${PID_FILE}.tmp" "$PID_FILE"
177
207
 
208
+ # Write start metadata (atomic)
178
209
  python3 -c "
179
- import json
180
- from datetime import datetime
210
+ import json, os
181
211
  data = {
182
212
  'pid': $pipeline_pid,
183
213
  'pipeline_type': 'bugfix',
@@ -186,8 +216,11 @@ data = {
186
216
  'env_overrides': '$env_overrides',
187
217
  'log_file': '$LOG_FILE'
188
218
  }
189
- with open('$STATE_DIR/.pipeline-meta.json', 'w') as f:
219
+ target = os.path.join('$STATE_DIR', '.pipeline-meta.json')
220
+ tmp = target + '.tmp'
221
+ with open(tmp, 'w') as f:
190
222
  json.dump(data, f, indent=2)
223
+ os.replace(tmp, target)
191
224
  " 2>/dev/null || true
192
225
 
193
226
  sleep 2
@@ -233,7 +266,10 @@ cmd_stop() {
233
266
  fi
234
267
 
235
268
  log_info "Stopping bugfix pipeline (PID: $pid)..."
236
- kill -TERM "$pid" 2>/dev/null || true
269
+
270
+ # Kill the entire process group to include child processes (claude-internal, etc.)
271
+ # First try SIGTERM to the process group (negative PID)
272
+ kill -TERM -- -"$pid" 2>/dev/null || kill -TERM "$pid" 2>/dev/null || true
237
273
 
238
274
  local waited=0
239
275
  while [[ $waited -lt 30 ]]; do
@@ -244,9 +280,10 @@ cmd_stop() {
244
280
  waited=$((waited + 1))
245
281
  done
246
282
 
283
+ # Force kill if still alive (process group first, then individual)
247
284
  if kill -0 "$pid" 2>/dev/null; then
248
285
  log_warn "Process did not exit after 30s, sending SIGKILL..."
249
- kill -9 "$pid" 2>/dev/null || true
286
+ kill -9 -- -"$pid" 2>/dev/null || kill -9 "$pid" 2>/dev/null || true
250
287
  sleep 1
251
288
  fi
252
289
 
@@ -341,7 +378,7 @@ import json, os
341
378
  bl = json.load(open('$bug_list_path'))
342
379
  bugs = bl.get('bugs', [])
343
380
  total = len(bugs)
344
- counts = {'completed': 0, 'in_progress': 0, 'failed': 0, 'pending': 0, 'needs_info': 0}
381
+ counts = {'completed': 0, 'in_progress': 0, 'failed': 0, 'pending': 0, 'needs_info': 0, 'skipped': 0}
345
382
  for bug in bugs:
346
383
  bid = bug.get('id', '')
347
384
  sp = os.path.join('$STATE_DIR', 'bugs', bid, 'status.json')
@@ -355,7 +392,7 @@ for bug in bugs:
355
392
  else:
356
393
  counts['pending'] += 1
357
394
  pct = round(counts['completed'] / total * 100, 1) if total > 0 else 0
358
- print(json.dumps({'total': total, 'completed': counts['completed'], 'in_progress': counts['in_progress'], 'failed': counts['failed'], 'pending': counts['pending'], 'needs_info': counts['needs_info'], 'percent': pct}))
395
+ print(json.dumps({'total': total, 'completed': counts['completed'], 'in_progress': counts['in_progress'], 'failed': counts['failed'], 'pending': counts['pending'], 'needs_info': counts['needs_info'], 'skipped': counts['skipped'], 'percent': pct}))
359
396
  " 2>/dev/null || echo "")
360
397
  fi
361
398
 
@@ -415,17 +452,26 @@ show_help() {
415
452
  Usage: launch-bugfix-daemon.sh <command> [options]
416
453
 
417
454
  Commands:
418
- start [bug-fix-list.json] [--env "K=V ..."] Start bugfix pipeline in background
455
+ start [.prizmkit/plans/bug-fix-list.json] [--mode <mode>] [--critic] [--env "K=V ..."] Start bugfix pipeline in background
419
456
  stop Gracefully stop pipeline
420
457
  status Check if pipeline is running
421
458
  logs [--lines N] [--follow] View pipeline logs
422
- restart [bug-fix-list.json] [--env "K=V ..."] Stop + start pipeline
459
+ restart [.prizmkit/plans/bug-fix-list.json] [--mode <mode>] [--critic] [--env "K=V ..."] Stop + start pipeline
423
460
  help Show this help
424
461
 
462
+ Options:
463
+ --mode <lite|standard|full> Override pipeline mode for all bugs
464
+ --critic Enable adversarial critic review for all bugs
465
+ --no-critic Disable adversarial critic review for all bugs
466
+ --env "KEY=VAL ..." Set environment variables
467
+
425
468
  Examples:
426
- ./launch-bugfix-daemon.sh start # Start with default bug-fix-list.json
469
+ ./launch-bugfix-daemon.sh start # Start with default .prizmkit/plans/bug-fix-list.json
427
470
  ./launch-bugfix-daemon.sh start my-bugs.json # Start with custom bug list
471
+ ./launch-bugfix-daemon.sh start --mode full # Full mode for complex bugs
472
+ ./launch-bugfix-daemon.sh start --critic # Enable adversarial critic review
428
473
  ./launch-bugfix-daemon.sh start --env "MAX_RETRIES=5"
474
+ ./launch-bugfix-daemon.sh start .prizmkit/plans/bug-fix-list.json --mode full --critic --env "VERBOSE=1"
429
475
  ./launch-bugfix-daemon.sh status # Check if running (JSON on stdout)
430
476
  ./launch-bugfix-daemon.sh logs --follow # Live log tailing
431
477
  ./launch-bugfix-daemon.sh stop # Graceful shutdown
@@ -8,23 +8,24 @@ set -euo pipefail
8
8
  # log consolidation, and lifecycle commands.
9
9
  #
10
10
  # Usage:
11
- # ./launch-feature-daemon.sh start [feature-list.json] [--mode <mode>] [--env "KEY=VAL ..."]
11
+ # ./launch-feature-daemon.sh start [.prizmkit/plans/feature-list.json] [--mode <mode>] [--env "KEY=VAL ..."]
12
12
  # ./launch-feature-daemon.sh stop
13
13
  # ./launch-feature-daemon.sh status
14
14
  # ./launch-feature-daemon.sh logs [--lines N] [--follow]
15
- # ./launch-feature-daemon.sh restart [feature-list.json] [--mode <mode>] [--env "KEY=VAL ..."]
15
+ # ./launch-feature-daemon.sh restart [.prizmkit/plans/feature-list.json] [--mode <mode>] [--env "KEY=VAL ..."]
16
16
  #
17
17
  # NOTE:
18
18
  # In AI skill sessions, always use this daemon wrapper.
19
19
  # Do NOT call `run-feature.sh run ...` directly, because foreground sessions may be killed by CLI timeout.
20
20
  #
21
21
  # Files managed:
22
- # state/.pipeline.pid - PID of the background run-feature.sh process
23
- # state/pipeline-daemon.log - Consolidated stdout+stderr from run-feature.sh
22
+ # .prizmkit/state/features/.pipeline.pid - PID of the background run-feature.sh process
23
+ # .prizmkit/state/features/pipeline-daemon.log - Consolidated stdout+stderr from run-feature.sh
24
24
  # ============================================================
25
25
 
26
26
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
27
- STATE_DIR="$SCRIPT_DIR/state"
27
+ PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
28
+ STATE_DIR="${PROJECT_ROOT}/.prizmkit/state/features"
28
29
  PID_FILE="$STATE_DIR/.pipeline.pid"
29
30
  LOG_FILE="$STATE_DIR/pipeline-daemon.log"
30
31
  RUN_SCRIPT="$SCRIPT_DIR/run-feature.sh"
@@ -151,7 +152,7 @@ cmd_start() {
151
152
 
152
153
  # Default feature list
153
154
  if [[ -z "$feature_list" ]]; then
154
- feature_list="feature-list.json"
155
+ feature_list=".prizmkit/plans/feature-list.json"
155
156
  fi
156
157
 
157
158
  # Resolve to absolute path
@@ -162,7 +163,7 @@ cmd_start() {
162
163
  # Validate feature list
163
164
  if [[ ! -f "$feature_list" ]]; then
164
165
  log_error "Feature list not found: $feature_list"
165
- log_error "Run the feature-planner skill first to generate feature-list.json"
166
+ log_error "Run the feature-planner skill first to generate .prizmkit/plans/feature-list.json"
166
167
  exit 2
167
168
  fi
168
169
 
@@ -480,7 +481,7 @@ feature_list_path, state_dir = sys.argv[1], sys.argv[2]
480
481
  fl = load_json(feature_list_path)
481
482
  features = fl.get('features', [])
482
483
  total = len(features)
483
- counts = {'completed': 0, 'in_progress': 0, 'failed': 0, 'pending': 0, 'skipped': 0}
484
+ counts = {'completed': 0, 'in_progress': 0, 'failed': 0, 'pending': 0, 'skipped': 0, 'auto_skipped': 0}
484
485
  for feat in features:
485
486
  fid = feat.get('id', '')
486
487
  sp = os.path.join(state_dir, 'features', fid, 'status.json')
@@ -501,6 +502,8 @@ print(json.dumps({
501
502
  'in_progress': counts['in_progress'],
502
503
  'failed': counts['failed'],
503
504
  'pending': counts['pending'],
505
+ 'skipped': counts['skipped'],
506
+ 'auto_skipped': counts['auto_skipped'],
504
507
  'percent': pct
505
508
  }))
506
509
  " "$feature_list_path" "$STATE_DIR" 2>/dev/null || echo "")
@@ -582,11 +585,11 @@ show_help() {
582
585
  Usage: launch-feature-daemon.sh <command> [options]
583
586
 
584
587
  Commands:
585
- start [feature-list.json] [--mode <mode>] [--features <filter>] [--env "K=V ..."] Start pipeline in background
588
+ start [.prizmkit/plans/feature-list.json] [--mode <mode>] [--features <filter>] [--env "K=V ..."] Start pipeline in background
586
589
  stop Gracefully stop pipeline
587
590
  status Check if pipeline is running
588
591
  logs [--lines N] [--follow] View pipeline logs
589
- restart [feature-list.json] [--mode <mode>] [--features <filter>] [--env "K=V ..."] Stop + start pipeline
592
+ restart [.prizmkit/plans/feature-list.json] [--mode <mode>] [--features <filter>] [--env "K=V ..."] Stop + start pipeline
590
593
  help Show this help
591
594
 
592
595
  Options:
@@ -597,14 +600,14 @@ Options:
597
600
  --env "KEY=VAL ..." Set environment variables
598
601
 
599
602
  Examples:
600
- ./launch-feature-daemon.sh start # Start with default feature-list.json
603
+ ./launch-feature-daemon.sh start # Start with default .prizmkit/plans/feature-list.json
601
604
  ./launch-feature-daemon.sh start my-features.json # Start with custom feature list
602
605
  ./launch-feature-daemon.sh start --features F-001:F-005 # Run only features F-001 through F-005
603
606
  ./launch-feature-daemon.sh start --features F-001,F-003,F-007 # Run specific features
604
607
  ./launch-feature-daemon.sh start --mode full # Full mode for complex features
605
608
  ./launch-feature-daemon.sh start --critic # Enable adversarial critic review
606
609
  ./launch-feature-daemon.sh start --env "MAX_RETRIES=5 SESSION_TIMEOUT=7200"
607
- ./launch-feature-daemon.sh start feature-list.json --mode full --critic --env "VERBOSE=1"
610
+ ./launch-feature-daemon.sh start .prizmkit/plans/feature-list.json --mode full --critic --env "VERBOSE=1"
608
611
  ./launch-feature-daemon.sh status # Check if running (JSON on stdout)
609
612
  ./launch-feature-daemon.sh logs --follow # Live log tailing
610
613
  ./launch-feature-daemon.sh logs --lines 100 # Last 100 lines
@@ -8,23 +8,24 @@ set -euo pipefail
8
8
  # log consolidation, and lifecycle commands.
9
9
  #
10
10
  # Usage:
11
- # ./launch-refactor-daemon.sh start [refactor-list.json] [--env "KEY=VAL ..."]
11
+ # ./launch-refactor-daemon.sh start [.prizmkit/plans/refactor-list.json] [--mode <mode>] [--critic] [--env "KEY=VAL ..."]
12
12
  # ./launch-refactor-daemon.sh stop
13
13
  # ./launch-refactor-daemon.sh status
14
14
  # ./launch-refactor-daemon.sh logs [--lines N] [--follow]
15
- # ./launch-refactor-daemon.sh restart [refactor-list.json] [--env "KEY=VAL ..."]
15
+ # ./launch-refactor-daemon.sh restart [.prizmkit/plans/refactor-list.json] [--mode <mode>] [--critic] [--env "KEY=VAL ..."]
16
16
  #
17
17
  # NOTE:
18
18
  # In AI skill sessions, always use this daemon wrapper.
19
19
  # Do NOT call `run-refactor.sh run ...` directly, because foreground sessions may be killed by CLI timeout.
20
20
  #
21
21
  # Files managed:
22
- # refactor-state/.pipeline.pid - PID of the background run-refactor.sh process
23
- # refactor-state/pipeline-daemon.log - Consolidated stdout+stderr
22
+ # .prizmkit/state/refactor/.pipeline.pid - PID of the background run-refactor.sh process
23
+ # .prizmkit/state/refactor/pipeline-daemon.log - Consolidated stdout+stderr
24
24
  # ============================================================
25
25
 
26
26
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
27
- STATE_DIR="$SCRIPT_DIR/refactor-state"
27
+ PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
28
+ STATE_DIR="${PROJECT_ROOT}/.prizmkit/state/refactor"
28
29
  PID_FILE="$STATE_DIR/.pipeline.pid"
29
30
  LOG_FILE="$STATE_DIR/pipeline-daemon.log"
30
31
  RUN_SCRIPT="$SCRIPT_DIR/run-refactor.sh"
@@ -92,12 +93,37 @@ cmd_start() {
92
93
  while [[ $# -gt 0 ]]; do
93
94
  case "$1" in
94
95
  --env) shift; env_overrides="${1:-}"; shift ;;
96
+ --mode)
97
+ shift
98
+ if [[ $# -eq 0 ]]; then
99
+ log_error "--mode requires a value (lite|standard|full)"
100
+ exit 1
101
+ fi
102
+ case "$1" in
103
+ lite|standard|full)
104
+ PIPELINE_MODE="$1"
105
+ ;;
106
+ *)
107
+ log_error "Invalid mode: $1 (must be lite, standard, or full)"
108
+ exit 1
109
+ ;;
110
+ esac
111
+ shift
112
+ ;;
113
+ --critic)
114
+ ENABLE_CRITIC=true
115
+ shift
116
+ ;;
117
+ --no-critic)
118
+ ENABLE_CRITIC=false
119
+ shift
120
+ ;;
95
121
  *) refactor_list="$1"; shift ;;
96
122
  esac
97
123
  done
98
124
 
99
125
  if [[ -z "$refactor_list" ]]; then
100
- refactor_list="refactor-list.json"
126
+ refactor_list=".prizmkit/plans/refactor-list.json"
101
127
  fi
102
128
  if [[ ! "$refactor_list" = /* ]]; then
103
129
  refactor_list="$(cd "$(dirname "$refactor_list")" 2>/dev/null && pwd)/$(basename "$refactor_list")"
@@ -105,7 +131,7 @@ cmd_start() {
105
131
 
106
132
  if [[ ! -f "$refactor_list" ]]; then
107
133
  log_error "Refactor list not found: $refactor_list"
108
- log_error "Run the refactor-planner skill first to generate refactor-list.json"
134
+ log_error "Run the refactor-planner skill first to generate .prizmkit/plans/refactor-list.json"
109
135
  exit 2
110
136
  fi
111
137
 
@@ -165,6 +191,9 @@ cmd_start() {
165
191
  echo ""
166
192
  } >> "$LOG_FILE"
167
193
 
194
+ [[ -n "${PIPELINE_MODE:-}" ]] && export PIPELINE_MODE
195
+ [[ -n "${ENABLE_CRITIC:-}" ]] && export ENABLE_CRITIC
196
+
168
197
  if [[ -n "$env_cmd" ]]; then
169
198
  nohup $env_cmd "$RUN_SCRIPT" run "$refactor_list" >> "$LOG_FILE" 2>&1 &
170
199
  else
@@ -173,11 +202,12 @@ cmd_start() {
173
202
  local pipeline_pid=$!
174
203
  disown "$pipeline_pid" 2>/dev/null || true
175
204
 
176
- echo "$pipeline_pid" > "$PID_FILE"
205
+ echo "$pipeline_pid" > "${PID_FILE}.tmp"
206
+ mv "${PID_FILE}.tmp" "$PID_FILE"
177
207
 
208
+ # Write start metadata (atomic)
178
209
  python3 -c "
179
- import json
180
- from datetime import datetime
210
+ import json, os
181
211
  data = {
182
212
  'pid': $pipeline_pid,
183
213
  'pipeline_type': 'refactor',
@@ -186,8 +216,11 @@ data = {
186
216
  'env_overrides': '$env_overrides',
187
217
  'log_file': '$LOG_FILE'
188
218
  }
189
- with open('$STATE_DIR/.pipeline-meta.json', 'w') as f:
219
+ target = os.path.join('$STATE_DIR', '.pipeline-meta.json')
220
+ tmp = target + '.tmp'
221
+ with open(tmp, 'w') as f:
190
222
  json.dump(data, f, indent=2)
223
+ os.replace(tmp, target)
191
224
  " 2>/dev/null || true
192
225
 
193
226
  sleep 2
@@ -233,7 +266,10 @@ cmd_stop() {
233
266
  fi
234
267
 
235
268
  log_info "Stopping refactor pipeline (PID: $pid)..."
236
- kill -TERM "$pid" 2>/dev/null || true
269
+
270
+ # Kill the entire process group to include child processes (claude-internal, etc.)
271
+ # First try SIGTERM to the process group (negative PID)
272
+ kill -TERM -- -"$pid" 2>/dev/null || kill -TERM "$pid" 2>/dev/null || true
237
273
 
238
274
  local waited=0
239
275
  while [[ $waited -lt 30 ]]; do
@@ -244,9 +280,10 @@ cmd_stop() {
244
280
  waited=$((waited + 1))
245
281
  done
246
282
 
283
+ # Force kill if still alive (process group first, then individual)
247
284
  if kill -0 "$pid" 2>/dev/null; then
248
285
  log_warn "Process did not exit after 30s, sending SIGKILL..."
249
- kill -9 "$pid" 2>/dev/null || true
286
+ kill -9 -- -"$pid" 2>/dev/null || kill -9 "$pid" 2>/dev/null || true
250
287
  sleep 1
251
288
  fi
252
289
 
@@ -341,7 +378,7 @@ import json, os
341
378
  bl = json.load(open('$refactor_list_path'))
342
379
  items = bl.get('refactors', [])
343
380
  total = len(items)
344
- counts = {'completed': 0, 'in_progress': 0, 'failed': 0, 'pending': 0, 'needs_info': 0}
381
+ counts = {'completed': 0, 'in_progress': 0, 'failed': 0, 'pending': 0, 'skipped': 0, 'auto_skipped': 0}
345
382
  for item in items:
346
383
  rid = item.get('id', '')
347
384
  sp = os.path.join('$STATE_DIR', 'refactors', rid, 'status.json')
@@ -355,7 +392,7 @@ for item in items:
355
392
  else:
356
393
  counts['pending'] += 1
357
394
  pct = round(counts['completed'] / total * 100, 1) if total > 0 else 0
358
- print(json.dumps({'total': total, 'completed': counts['completed'], 'in_progress': counts['in_progress'], 'failed': counts['failed'], 'pending': counts['pending'], 'needs_info': counts['needs_info'], 'percent': pct}))
395
+ print(json.dumps({'total': total, 'completed': counts['completed'], 'in_progress': counts['in_progress'], 'failed': counts['failed'], 'pending': counts['pending'], 'skipped': counts['skipped'], 'auto_skipped': counts['auto_skipped'], 'percent': pct}))
359
396
  " 2>/dev/null || echo "")
360
397
  fi
361
398
 
@@ -415,18 +452,27 @@ show_help() {
415
452
  Usage: launch-refactor-daemon.sh <command> [options]
416
453
 
417
454
  Commands:
418
- start [refactor-list.json] [--env "K=V ..."] Start refactor pipeline in background
455
+ start [.prizmkit/plans/refactor-list.json] [--mode <mode>] [--critic] [--env "K=V ..."] Start refactor pipeline in background
419
456
  stop Gracefully stop pipeline
420
457
  status Check if pipeline is running
421
458
  logs [--lines N] [--follow] View pipeline logs
422
- restart [refactor-list.json] [--env "K=V ..."] Stop + start pipeline
459
+ restart [.prizmkit/plans/refactor-list.json] [--mode <mode>] [--critic] [--env "K=V ..."] Stop + start pipeline
423
460
  help Show this help
424
461
 
462
+ Options:
463
+ --mode <lite|standard|full> Override pipeline mode for all refactors
464
+ --critic Enable adversarial critic review for all refactors
465
+ --no-critic Disable adversarial critic review for all refactors
466
+ --env "KEY=VAL ..." Set environment variables
467
+
425
468
  Examples:
426
- ./launch-refactor-daemon.sh start # Start with default refactor-list.json
469
+ ./launch-refactor-daemon.sh start # Start with default .prizmkit/plans/refactor-list.json
427
470
  ./launch-refactor-daemon.sh start my-refactors.json # Start with custom refactor list
471
+ ./launch-refactor-daemon.sh start --mode full # Full mode for complex refactors
472
+ ./launch-refactor-daemon.sh start --critic # Enable adversarial critic review
428
473
  ./launch-refactor-daemon.sh start --env "MAX_RETRIES=5"
429
474
  ./launch-refactor-daemon.sh start --env "STRICT_BEHAVIOR_CHECK=0"
475
+ ./launch-refactor-daemon.sh start .prizmkit/plans/refactor-list.json --mode full --critic --env "VERBOSE=1"
430
476
  ./launch-refactor-daemon.sh status # Check if running (JSON on stdout)
431
477
  ./launch-refactor-daemon.sh logs --follow # Live log tailing
432
478
  ./launch-refactor-daemon.sh stop # Graceful shutdown
@@ -99,7 +99,12 @@ branch_merge() {
99
99
  local remaining_dirty
100
100
  remaining_dirty=$(git -C "$project_root" status --porcelain 2>/dev/null || true)
101
101
  if [[ -n "$remaining_dirty" ]]; then
102
- git -C "$project_root" stash push --include-untracked -m "pipeline-merge-stash" 2>/dev/null && had_stash=true || true
102
+ if git -C "$project_root" stash push --include-untracked -m "pipeline-merge-stash" 2>/dev/null; then
103
+ had_stash=true
104
+ else
105
+ log_warn "git stash failed — uncommitted changes may not be preserved during merge"
106
+ had_stash=false
107
+ fi
103
108
  fi
104
109
 
105
110
  # Step 2: Rebase dev branch onto original to make it fast-forwardable.
@@ -23,6 +23,70 @@ log_warn() { echo -e "${YELLOW}[WARN]${NC} $(date '+%Y-%m-%d %H:%M:%S') $*
23
23
  log_error() { echo -e "${RED}[ERROR]${NC} $(date '+%Y-%m-%d %H:%M:%S') $*"; }
24
24
  log_success() { echo -e "${GREEN}[SUCCESS]${NC} $(date '+%Y-%m-%d %H:%M:%S') $*"; }
25
25
 
26
+ # ============================================================
27
+ # .env file loading
28
+ # ============================================================
29
+
30
+ # Load .env file if it exists. Does NOT override already-set env vars.
31
+ # Supports: KEY=VALUE, KEY="VALUE", KEY='VALUE', comments (#), empty lines.
32
+ # If the file does not exist, silently continues (no error).
33
+ prizm_load_env() {
34
+ local env_file="${1:-.env}"
35
+ [[ -f "$env_file" ]] || return 0
36
+
37
+ while IFS= read -r line || [[ -n "$line" ]]; do
38
+ # Skip empty lines and comments
39
+ [[ -z "$line" || "$line" =~ ^[[:space:]]*# ]] && continue
40
+ # Remove inline comments (not inside quotes)
41
+ line="${line%%#*}"
42
+ # Trim whitespace
43
+ line="$(echo "$line" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')"
44
+ [[ -z "$line" ]] && continue
45
+ # Parse KEY=VALUE
46
+ if [[ "$line" =~ ^([A-Za-z_][A-Za-z0-9_]*)=(.*)$ ]]; then
47
+ local key="${BASH_REMATCH[1]}"
48
+ local val="${BASH_REMATCH[2]}"
49
+ # Strip surrounding quotes
50
+ val="${val#\"}" ; val="${val%\"}"
51
+ val="${val#\'}" ; val="${val%\'}"
52
+ # Only set if not already defined in environment
53
+ if [[ -z "${!key+x}" ]]; then
54
+ export "$key=$val"
55
+ fi
56
+ fi
57
+ done < "$env_file"
58
+ }
59
+
60
+ # ============================================================
61
+ # Test mode: bootstrap prompt logging
62
+ # ============================================================
63
+
64
+ # Log bootstrap prompt content when PRIZMKIT_ENV=test.
65
+ # Called after prompt generation, before AI CLI session spawn.
66
+ # Usage: prizm_log_bootstrap_prompt <prompt_path> <item_id>
67
+ prizm_log_bootstrap_prompt() {
68
+ local prompt_path="$1"
69
+ local item_id="$2"
70
+
71
+ [[ "${PRIZMKIT_ENV:-}" == "test" ]] || return 0
72
+ [[ -f "$prompt_path" ]] || return 0
73
+
74
+ local lines size
75
+ lines=$(wc -l < "$prompt_path" 2>/dev/null | tr -d ' ')
76
+ size=$(wc -c < "$prompt_path" 2>/dev/null | tr -d ' ')
77
+
78
+ echo ""
79
+ echo -e "${MAGENTA}[TEST]${NC} ════════════════════════════════════════════════════"
80
+ echo -e "${MAGENTA}[TEST]${NC} Bootstrap Prompt for $item_id"
81
+ echo -e "${MAGENTA}[TEST]${NC} Lines: $lines | Size: $((size / 1024))KB"
82
+ echo -e "${MAGENTA}[TEST]${NC} Path: $prompt_path"
83
+ echo -e "${MAGENTA}[TEST]${NC} ════════════════════════════════════════════════════"
84
+ cat "$prompt_path"
85
+ echo ""
86
+ echo -e "${MAGENTA}[TEST]${NC} ════════════════════════ END ═══════════════════════"
87
+ echo ""
88
+ }
89
+
26
90
  # Detect AI CLI + platform.
27
91
  # Priority:
28
92
  # AI_CLI env > .prizmkit/config.json > CODEBUDDY_CLI > auto-detect(cbc/claude) > error
@@ -32,6 +96,13 @@ log_success() { echo -e "${GREEN}[SUCCESS]${NC} $(date '+%Y-%m-%d %H:%M:%S') $*"
32
96
  # PLATFORM
33
97
  # PRIZMKIT_PLATFORM
34
98
  prizm_detect_cli_and_platform() {
99
+ # Load .env from project root if it exists (does not override existing env vars)
100
+ local _env_root
101
+ _env_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." 2>/dev/null && pwd)" || true
102
+ if [[ -n "$_env_root" ]]; then
103
+ prizm_load_env "$_env_root/.env"
104
+ fi
105
+
35
106
  local _raw_cli=""
36
107
 
37
108
  if [[ -n "${AI_CLI:-}" ]]; then
@@ -73,7 +73,7 @@ start_heartbeat() {
73
73
  phase=$(python3 -c "
74
74
  import json, sys
75
75
  try:
76
- with open('$progress_json') as f:
76
+ with open(sys.argv[1]) as f:
77
77
  d = json.load(f)
78
78
  parts = []
79
79
  if d.get('current_phase'):
@@ -85,7 +85,7 @@ try:
85
85
  print(' | '.join(parts))
86
86
  except Exception:
87
87
  sys.exit(1)
88
- " 2>/dev/null) && {
88
+ " "$progress_json" 2>/dev/null) && {
89
89
  echo -e " ${status_icon} ${BLUE}[HEARTBEAT]${NC} ${mins}m${secs}s | log: ${size_display} | ${phase}"
90
90
  continue
91
91
  }