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.
- package/bundled/VERSION.json +3 -3
- package/bundled/adapters/codebuddy/skill-adapter.js +21 -7
- package/bundled/agents/prizm-dev-team-reviewer.md +53 -173
- package/bundled/dev-pipeline/.env.example +45 -0
- package/bundled/dev-pipeline/README.md +64 -64
- package/bundled/dev-pipeline/SCHEMA_ANALYSIS.md +535 -0
- package/bundled/dev-pipeline/assets/feature-list-example.json +0 -1
- package/bundled/dev-pipeline/launch-bugfix-daemon.sh +64 -18
- package/bundled/dev-pipeline/launch-feature-daemon.sh +15 -12
- package/bundled/dev-pipeline/launch-refactor-daemon.sh +64 -18
- package/bundled/dev-pipeline/lib/branch.sh +6 -1
- package/bundled/dev-pipeline/lib/common.sh +71 -0
- package/bundled/dev-pipeline/lib/heartbeat.sh +2 -2
- package/bundled/dev-pipeline/reset-bug.sh +10 -9
- package/bundled/dev-pipeline/reset-feature.sh +9 -8
- package/bundled/dev-pipeline/reset-refactor.sh +10 -9
- package/bundled/dev-pipeline/retry-bugfix.sh +67 -29
- package/bundled/dev-pipeline/retry-feature.sh +54 -18
- package/bundled/dev-pipeline/retry-refactor.sh +112 -29
- package/bundled/dev-pipeline/run-bugfix.sh +281 -59
- package/bundled/dev-pipeline/run-feature.sh +53 -18
- package/bundled/dev-pipeline/run-refactor.sh +392 -66
- package/bundled/dev-pipeline/scripts/check-session-status.py +24 -1
- package/bundled/dev-pipeline/scripts/cleanup-logs.py +2 -2
- package/bundled/dev-pipeline/scripts/detect-stuck.py +195 -85
- package/bundled/dev-pipeline/scripts/generate-bootstrap-prompt.py +57 -33
- package/bundled/dev-pipeline/scripts/generate-bugfix-prompt.py +25 -9
- package/bundled/dev-pipeline/scripts/generate-refactor-prompt.py +104 -17
- package/bundled/dev-pipeline/scripts/init-bugfix-pipeline.py +34 -9
- package/bundled/dev-pipeline/scripts/init-pipeline.py +10 -10
- package/bundled/dev-pipeline/scripts/init-refactor-pipeline.py +19 -8
- package/bundled/dev-pipeline/scripts/parse-stream-progress.py +1 -5
- package/bundled/dev-pipeline/scripts/patch-completion-notes.py +191 -0
- package/bundled/dev-pipeline/scripts/update-bug-status.py +167 -22
- package/bundled/dev-pipeline/scripts/update-feature-status.py +104 -62
- package/bundled/dev-pipeline/scripts/update-refactor-status.py +351 -21
- package/bundled/dev-pipeline/templates/agent-prompts/dev-fix.md +1 -1
- package/bundled/dev-pipeline/templates/agent-prompts/reviewer-review.md +7 -11
- package/bundled/dev-pipeline/templates/bootstrap-prompt.md +41 -7
- package/bundled/dev-pipeline/templates/bootstrap-tier1.md +27 -3
- package/bundled/dev-pipeline/templates/bootstrap-tier2.md +43 -19
- package/bundled/dev-pipeline/templates/bootstrap-tier3.md +54 -26
- package/bundled/dev-pipeline/templates/bug-fix-list-schema.json +6 -15
- package/bundled/dev-pipeline/templates/bugfix-bootstrap-prompt.md +36 -25
- package/bundled/dev-pipeline/templates/feature-list-schema.json +109 -31
- package/bundled/dev-pipeline/templates/refactor-bootstrap-prompt.md +270 -0
- package/bundled/dev-pipeline/templates/refactor-list-schema.json +11 -3
- package/bundled/dev-pipeline/templates/sections/context-budget-rules.md +3 -1
- package/bundled/dev-pipeline/templates/sections/critical-paths-agent.md +1 -0
- package/bundled/dev-pipeline/templates/sections/feature-context.md +2 -0
- package/bundled/dev-pipeline/templates/sections/phase-commit-full.md +29 -2
- package/bundled/dev-pipeline/templates/sections/phase-commit.md +22 -0
- package/bundled/dev-pipeline/templates/sections/phase-deploy-verification.md +2 -2
- package/bundled/dev-pipeline/templates/sections/phase-review-agent.md +8 -6
- package/bundled/dev-pipeline/templates/sections/phase-review-full.md +7 -5
- package/bundled/dev-pipeline/templates/sections/phase-specify-plan-full.md +3 -3
- package/bundled/skills/_metadata.json +5 -22
- package/bundled/skills/app-planner/SKILL.md +98 -72
- package/bundled/skills/app-planner/assets/app-design-guide.md +1 -1
- package/bundled/skills/app-planner/references/architecture-decisions.md +1 -1
- package/bundled/skills/app-planner/references/project-brief-guide.md +69 -66
- package/bundled/skills/bug-fix-workflow/SKILL.md +52 -9
- package/bundled/skills/bug-planner/SKILL.md +139 -197
- package/bundled/skills/bug-planner/assets/bug-confirmation-template.md +43 -0
- package/bundled/skills/bug-planner/references/critic-and-verification.md +44 -0
- package/bundled/skills/bug-planner/references/error-recovery.md +73 -0
- package/bundled/skills/bug-planner/references/input-formats.md +53 -0
- package/bundled/skills/bug-planner/references/schema-validation.md +25 -0
- package/bundled/skills/bug-planner/references/severity-rules.md +16 -0
- package/bundled/skills/bug-planner/scripts/validate-bug-list.py +4 -8
- package/bundled/skills/bugfix-pipeline-launcher/SKILL.md +34 -39
- package/bundled/skills/feature-pipeline-launcher/SKILL.md +49 -36
- package/bundled/skills/feature-pipeline-launcher/scripts/preflight-check.py +3 -3
- package/bundled/skills/feature-planner/SKILL.md +53 -142
- package/bundled/skills/feature-planner/assets/evaluation-guide.md +1 -1
- package/bundled/skills/feature-planner/assets/planning-guide.md +21 -5
- package/bundled/skills/feature-planner/references/browser-interaction.md +2 -4
- package/bundled/skills/feature-planner/references/completeness-review.md +57 -0
- package/bundled/skills/feature-planner/references/error-recovery.md +16 -35
- package/bundled/skills/feature-planner/references/incremental-feature-planning.md +1 -1
- package/bundled/skills/feature-planner/references/new-project-planning.md +2 -2
- package/bundled/skills/feature-planner/scripts/validate-and-generate.py +19 -20
- package/bundled/skills/feature-workflow/SKILL.md +24 -25
- package/bundled/skills/prizm-kit/SKILL.md +39 -49
- package/bundled/skills/prizmkit-code-review/SKILL.md +51 -64
- package/bundled/skills/prizmkit-code-review/rules/dimensions.md +85 -0
- package/bundled/skills/prizmkit-code-review/rules/fix-strategy.md +11 -11
- package/bundled/skills/prizmkit-committer/SKILL.md +3 -31
- package/bundled/skills/prizmkit-deploy/SKILL.md +34 -31
- package/bundled/skills/prizmkit-deploy/assets/deploy-template.md +1 -1
- package/bundled/skills/prizmkit-implement/SKILL.md +35 -68
- package/bundled/skills/prizmkit-init/SKILL.md +112 -65
- package/bundled/skills/prizmkit-init/assets/project-brief-template.md +82 -0
- package/bundled/skills/prizmkit-plan/SKILL.md +120 -79
- package/bundled/skills/prizmkit-plan/assets/plan-template.md +28 -18
- package/bundled/skills/prizmkit-plan/assets/spec-template.md +28 -11
- package/bundled/skills/prizmkit-plan/references/clarify-guide.md +3 -3
- package/bundled/skills/prizmkit-plan/references/verification-checklist.md +60 -0
- package/bundled/skills/prizmkit-prizm-docs/SKILL.md +10 -81
- package/bundled/skills/prizmkit-prizm-docs/assets/{PRIZM-SPEC.md → prizm-docs-format.md} +41 -526
- package/bundled/skills/prizmkit-prizm-docs/references/op-init.md +46 -0
- package/bundled/skills/prizmkit-prizm-docs/references/op-rebuild.md +16 -0
- package/bundled/skills/prizmkit-prizm-docs/references/op-status.md +14 -0
- package/bundled/skills/prizmkit-prizm-docs/references/op-update.md +19 -0
- package/bundled/skills/prizmkit-prizm-docs/references/op-validate.md +17 -0
- package/bundled/skills/prizmkit-retrospective/SKILL.md +27 -65
- package/bundled/skills/prizmkit-retrospective/references/knowledge-injection-steps.md +3 -4
- package/bundled/skills/prizmkit-retrospective/references/structural-sync-steps.md +7 -25
- package/bundled/skills/recovery-workflow/SKILL.md +22 -22
- package/bundled/skills/recovery-workflow/evals/evals.json +5 -5
- package/bundled/skills/recovery-workflow/scripts/detect-recovery-state.py +43 -10
- package/bundled/skills/refactor-pipeline-launcher/SKILL.md +48 -40
- package/bundled/skills/refactor-planner/SKILL.md +43 -61
- package/bundled/skills/refactor-planner/scripts/validate-and-generate-refactor.py +17 -17
- package/bundled/skills/refactor-workflow/SKILL.md +23 -24
- package/bundled/team/prizm-dev-team.json +1 -1
- package/bundled/{skills/prizm-kit/assets → templates}/project-memory-template.md +1 -1
- package/package.json +1 -1
- package/src/clean.js +3 -4
- package/src/gitignore-template.js +7 -9
- package/src/scaffold.js +14 -5
- package/bundled/dev-pipeline/templates/agent-prompts/reviewer-analyze.md +0 -5
- package/bundled/dev-pipeline/templates/sections/phase-analyze-agent.md +0 -19
- package/bundled/dev-pipeline/templates/sections/phase-analyze-full.md +0 -19
- package/bundled/skills/app-planner/references/project-conventions.md +0 -93
- package/bundled/skills/prizmkit-analyze/SKILL.md +0 -207
- package/bundled/skills/prizmkit-code-review/rules/dimensions-bugfix.md +0 -25
- package/bundled/skills/prizmkit-code-review/rules/dimensions-feature.md +0 -43
- package/bundled/skills/prizmkit-code-review/rules/dimensions-refactor.md +0 -25
- package/bundled/skills/prizmkit-implement/references/deploy-guide-protocol.md +0 -69
- package/bundled/skills/prizmkit-verify/SKILL.md +0 -281
- 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
|
|
23
|
-
#
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
23
|
-
#
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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, '
|
|
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'], '
|
|
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
|
|
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(
|
|
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
|
}
|