prizmkit 1.1.81 → 1.1.83
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundled/VERSION.json +3 -3
- package/bundled/dev-pipeline/lib/common.sh +20 -6
- package/bundled/dev-pipeline/lib/heartbeat.sh +36 -4
- package/bundled/dev-pipeline/run-bugfix.sh +4 -0
- package/bundled/dev-pipeline/run-feature.sh +7 -3
- package/bundled/dev-pipeline/run-refactor.sh +4 -0
- package/bundled/dev-pipeline/templates/bootstrap-tier1.md +2 -5
- package/bundled/dev-pipeline/templates/bootstrap-tier2.md +2 -5
- package/bundled/dev-pipeline/templates/bootstrap-tier3.md +2 -5
- package/bundled/dev-pipeline/templates/sections/failure-capture.md +0 -5
- package/bundled/dev-pipeline-windows/lib/heartbeat.sh +36 -4
- package/bundled/skills/_metadata.json +1 -1
- package/package.json +1 -1
package/bundled/VERSION.json
CHANGED
|
@@ -403,6 +403,13 @@ prizm_start_ai_session() {
|
|
|
403
403
|
|
|
404
404
|
unset CLAUDECODE 2>/dev/null || true
|
|
405
405
|
|
|
406
|
+
# Write the prompt to log before launching (defense against stdout truncation)
|
|
407
|
+
echo "=== PRIZMKIT SESSION START ===" > "$log_path"
|
|
408
|
+
echo "Prompt: $prompt_path" >> "$log_path"
|
|
409
|
+
echo "Model: ${model:-default}" >> "$log_path"
|
|
410
|
+
echo "Started at: $(date -u +%Y-%m-%dT%H:%M:%SZ)" >> "$log_path"
|
|
411
|
+
echo "--- OUTPUT BELOW ---" >> "$log_path"
|
|
412
|
+
|
|
406
413
|
local session_platform
|
|
407
414
|
session_platform="$(_prizm_session_platform)"
|
|
408
415
|
|
|
@@ -421,7 +428,7 @@ prizm_start_ai_session() {
|
|
|
421
428
|
if [[ -n "$model" ]]; then
|
|
422
429
|
claude_args+=(--model "$model")
|
|
423
430
|
fi
|
|
424
|
-
"$CLI_CMD" "${claude_args[@]}"
|
|
431
|
+
"$CLI_CMD" "${claude_args[@]}" >> "$log_path" 2>&1 &
|
|
425
432
|
;;
|
|
426
433
|
codex)
|
|
427
434
|
local codex_args=(--ask-for-approval never --sandbox danger-full-access)
|
|
@@ -440,7 +447,7 @@ prizm_start_ai_session() {
|
|
|
440
447
|
if [[ -n "${PRIZMKIT_EFFORT:-}" ]]; then
|
|
441
448
|
codex_args+=(--config "model_reasoning_effort=$PRIZMKIT_EFFORT")
|
|
442
449
|
fi
|
|
443
|
-
"$CLI_CMD" "${codex_args[@]}" - < "$prompt_path"
|
|
450
|
+
"$CLI_CMD" "${codex_args[@]}" - < "$prompt_path" >> "$log_path" 2>&1 &
|
|
444
451
|
;;
|
|
445
452
|
*)
|
|
446
453
|
local cb_args=(--print -y)
|
|
@@ -456,7 +463,7 @@ prizm_start_ai_session() {
|
|
|
456
463
|
if [[ -n "$model" ]]; then
|
|
457
464
|
cb_args+=(--model "$model")
|
|
458
465
|
fi
|
|
459
|
-
"$CLI_CMD" "${cb_args[@]}" < "$prompt_path"
|
|
466
|
+
"$CLI_CMD" "${cb_args[@]}" < "$prompt_path" >> "$log_path" 2>&1 &
|
|
460
467
|
;;
|
|
461
468
|
esac
|
|
462
469
|
PRIZM_AI_PID=$!
|
|
@@ -938,6 +945,13 @@ prizm_run_ai_session() {
|
|
|
938
945
|
|
|
939
946
|
unset CLAUDECODE 2>/dev/null || true
|
|
940
947
|
|
|
948
|
+
# Write preamble before launching (defense against stdout truncation)
|
|
949
|
+
echo "=== PRIZMKIT SESSION START ===" > "$log_path"
|
|
950
|
+
echo "Prompt: $prompt_path" >> "$log_path"
|
|
951
|
+
echo "Model: ${model:-default}" >> "$log_path"
|
|
952
|
+
echo "Started at: $(date -u +%Y-%m-%dT%H:%M:%SZ)" >> "$log_path"
|
|
953
|
+
echo "--- OUTPUT BELOW ---" >> "$log_path"
|
|
954
|
+
|
|
941
955
|
local session_platform
|
|
942
956
|
session_platform="$(_prizm_session_platform)"
|
|
943
957
|
|
|
@@ -950,7 +964,7 @@ prizm_run_ai_session() {
|
|
|
950
964
|
if [[ -n "$model" ]]; then
|
|
951
965
|
claude_args+=(--model "$model")
|
|
952
966
|
fi
|
|
953
|
-
"$CLI_CMD" "${claude_args[@]}"
|
|
967
|
+
"$CLI_CMD" "${claude_args[@]}" >> "$log_path" 2>&1
|
|
954
968
|
;;
|
|
955
969
|
codex)
|
|
956
970
|
local codex_args=(--ask-for-approval never --sandbox danger-full-access)
|
|
@@ -969,7 +983,7 @@ prizm_run_ai_session() {
|
|
|
969
983
|
if [[ -n "${PRIZMKIT_EFFORT:-}" ]]; then
|
|
970
984
|
codex_args+=(--config "model_reasoning_effort=$PRIZMKIT_EFFORT")
|
|
971
985
|
fi
|
|
972
|
-
"$CLI_CMD" "${codex_args[@]}" - < "$prompt_path"
|
|
986
|
+
"$CLI_CMD" "${codex_args[@]}" - < "$prompt_path" >> "$log_path" 2>&1
|
|
973
987
|
;;
|
|
974
988
|
*)
|
|
975
989
|
local cb_args=(--print -y)
|
|
@@ -979,7 +993,7 @@ prizm_run_ai_session() {
|
|
|
979
993
|
if [[ -n "$model" ]]; then
|
|
980
994
|
cb_args+=(--model "$model")
|
|
981
995
|
fi
|
|
982
|
-
"$CLI_CMD" "${cb_args[@]}" < "$prompt_path"
|
|
996
|
+
"$CLI_CMD" "${cb_args[@]}" < "$prompt_path" >> "$log_path" 2>&1
|
|
983
997
|
;;
|
|
984
998
|
esac
|
|
985
999
|
}
|
|
@@ -41,6 +41,7 @@ start_heartbeat() {
|
|
|
41
41
|
(
|
|
42
42
|
local elapsed=0
|
|
43
43
|
local prev_size=0
|
|
44
|
+
local prev_max_size=0
|
|
44
45
|
local prev_child_activity_signature=""
|
|
45
46
|
local stale_seconds=0
|
|
46
47
|
while kill -0 "$cli_pid" 2>/dev/null; do
|
|
@@ -48,13 +49,28 @@ start_heartbeat() {
|
|
|
48
49
|
elapsed=$((elapsed + heartbeat_interval))
|
|
49
50
|
kill -0 "$cli_pid" 2>/dev/null || break
|
|
50
51
|
|
|
51
|
-
# Get log file size
|
|
52
|
+
# Get log file size. If session_log was truncated (e.g. by subagent
|
|
53
|
+
# stdout redirection severing the file descriptor), detect and flag it.
|
|
52
54
|
local cur_size=0
|
|
53
55
|
if [[ -f "$session_log" ]]; then
|
|
54
56
|
cur_size=$(wc -c < "$session_log" 2>/dev/null || echo 0)
|
|
55
57
|
cur_size=$(echo "$cur_size" | tr -d ' ')
|
|
56
58
|
fi
|
|
57
59
|
|
|
60
|
+
# Detect log truncation: size dropped to 0 or near-zero after previously
|
|
61
|
+
# accumulating significant content (>100KB). This indicates the file was
|
|
62
|
+
# unlinked/truncated by something outside our control while the AI CLI
|
|
63
|
+
# process is still running.
|
|
64
|
+
local log_truncated=false
|
|
65
|
+
if [[ $cur_size -lt 1024 && $prev_max_size -gt 102400 ]]; then
|
|
66
|
+
log_truncated=true
|
|
67
|
+
fi
|
|
68
|
+
# Track the maximum size we've seen for truncation detection
|
|
69
|
+
local prev_max_size=$prev_max_size
|
|
70
|
+
if [[ $cur_size -gt $prev_max_size ]]; then
|
|
71
|
+
prev_max_size=$cur_size
|
|
72
|
+
fi
|
|
73
|
+
|
|
58
74
|
local growth=$((cur_size - prev_size))
|
|
59
75
|
prev_size=$cur_size
|
|
60
76
|
|
|
@@ -183,16 +199,30 @@ PY
|
|
|
183
199
|
# tool while child transcripts keep growing, so child activity counts.
|
|
184
200
|
# Error loops bypass normal growth-as-progress because the log is only
|
|
185
201
|
# growing with repeated failed reads or wasted calls.
|
|
202
|
+
#
|
|
203
|
+
# When the main session log has been truncated (e.g. by subagent stdout
|
|
204
|
+
# redirection severing the file descriptor), use child activity as the
|
|
205
|
+
# primary progress signal — the parent process is still running and children
|
|
206
|
+
# are still producing output, so this is not a true stall.
|
|
186
207
|
if [[ "$error_loop_detected" == "true" ]]; then
|
|
187
208
|
stale_seconds=$effective_stale_kill_threshold
|
|
188
|
-
elif [[ $
|
|
209
|
+
elif [[ "$log_truncated" == "true" ]]; then
|
|
210
|
+
# Log truncated: rely on child growth and CLI process liveness.
|
|
211
|
+
# Don't increment staleness — the process is still working.
|
|
212
|
+
if [[ $child_growth -gt 0 ]]; then
|
|
213
|
+
stale_seconds=0
|
|
214
|
+
fi
|
|
215
|
+
# If neither log nor children grow, this is a real stall
|
|
216
|
+
elif [[ $growth -le 0 && $child_growth -eq 0 ]]; then
|
|
189
217
|
stale_seconds=$((stale_seconds + heartbeat_interval))
|
|
190
218
|
else
|
|
191
219
|
stale_seconds=0
|
|
192
220
|
fi
|
|
193
221
|
|
|
194
222
|
local size_display
|
|
195
|
-
if
|
|
223
|
+
if $log_truncated; then
|
|
224
|
+
size_display="${cur_size}B/TRUNCATED(from ${prev_max_size}B)"
|
|
225
|
+
elif [[ $cur_size -gt 1048576 ]]; then
|
|
196
226
|
size_display="$((cur_size / 1048576))MB"
|
|
197
227
|
elif [[ $cur_size -gt 1024 ]]; then
|
|
198
228
|
size_display="$((cur_size / 1024))KB"
|
|
@@ -219,7 +249,9 @@ PY
|
|
|
219
249
|
local secs=$((elapsed % 60))
|
|
220
250
|
|
|
221
251
|
local status_icon
|
|
222
|
-
if
|
|
252
|
+
if $log_truncated; then
|
|
253
|
+
status_icon="${RED}⚠${NC}"
|
|
254
|
+
elif [[ $growth -gt 0 || $child_growth -gt 0 ]]; then
|
|
223
255
|
status_icon="${GREEN}▶${NC}"
|
|
224
256
|
else
|
|
225
257
|
status_icon="${YELLOW}⏸${NC}"
|
|
@@ -159,6 +159,10 @@ spawn_and_wait_session() {
|
|
|
159
159
|
local final_size=$(wc -c < "$session_log" 2>/dev/null | tr -d ' ')
|
|
160
160
|
local final_lines=$(wc -l < "$session_log" 2>/dev/null | tr -d ' ')
|
|
161
161
|
log_info "Session log: $final_lines lines, $((final_size / 1024))KB"
|
|
162
|
+
if [[ "$final_size" -lt 1024 && "$exit_code" -eq 0 ]]; then
|
|
163
|
+
log_warn "Session log was truncated during execution (subagent stdout redirection may have severed it)"
|
|
164
|
+
log_warn "Proceeding with exit-code-only outcome detection — child transcripts and git state are still valid"
|
|
165
|
+
fi
|
|
162
166
|
fi
|
|
163
167
|
log_info "exit_code=$exit_code"
|
|
164
168
|
|
|
@@ -174,6 +174,10 @@ spawn_and_wait_session() {
|
|
|
174
174
|
local final_size=$(wc -c < "$session_log" 2>/dev/null | tr -d ' ')
|
|
175
175
|
local final_lines=$(wc -l < "$session_log" 2>/dev/null | tr -d ' ')
|
|
176
176
|
log_info "Session log: $final_lines lines, $((final_size / 1024))KB"
|
|
177
|
+
if [[ "$final_size" -lt 1024 && "$exit_code" -eq 0 ]]; then
|
|
178
|
+
log_warn "Session log was truncated during execution (subagent stdout redirection may have severed it)"
|
|
179
|
+
log_warn "Proceeding with exit-code-only outcome detection — child transcripts and git state are still valid"
|
|
180
|
+
fi
|
|
177
181
|
fi
|
|
178
182
|
log_info "exit_code=$exit_code"
|
|
179
183
|
|
|
@@ -990,7 +994,7 @@ else:
|
|
|
990
994
|
|
|
991
995
|
# Commit feature status update on the original branch (after guaranteed return)
|
|
992
996
|
if ! git -C "$_proj_root" diff --quiet "$feature_list" 2>/dev/null; then
|
|
993
|
-
git -C "$_proj_root" add "$feature_list"
|
|
997
|
+
git -C "$_proj_root" add "$feature_list" 2>/dev/null || true
|
|
994
998
|
git -C "$_proj_root" commit --no-verify -m "chore($feature_id): update feature status" 2>/dev/null || true
|
|
995
999
|
fi
|
|
996
1000
|
|
|
@@ -1424,7 +1428,7 @@ DEPLOY_PROMPT_EOF
|
|
|
1424
1428
|
|
|
1425
1429
|
# Commit feature status update on the original branch (after guaranteed return)
|
|
1426
1430
|
if ! git -C "$_proj_root" diff --quiet "$feature_list" 2>/dev/null; then
|
|
1427
|
-
git -C "$_proj_root" add "$feature_list"
|
|
1431
|
+
git -C "$_proj_root" add "$feature_list" 2>/dev/null || true
|
|
1428
1432
|
git -C "$_proj_root" commit --no-verify -m "chore($feature_id): update feature status" 2>/dev/null || true
|
|
1429
1433
|
fi
|
|
1430
1434
|
|
|
@@ -1636,7 +1640,7 @@ case "${1:-run}" in
|
|
|
1636
1640
|
|
|
1637
1641
|
# Commit the status change
|
|
1638
1642
|
if ! git diff --quiet "$_unskip_feature_list" 2>/dev/null; then
|
|
1639
|
-
git add "$_unskip_feature_list"
|
|
1643
|
+
git add "$_unskip_feature_list" 2>/dev/null || true
|
|
1640
1644
|
git commit -m "chore: unskip auto-skipped features" 2>/dev/null || true
|
|
1641
1645
|
fi
|
|
1642
1646
|
;;
|
|
@@ -161,6 +161,10 @@ spawn_and_wait_session() {
|
|
|
161
161
|
local final_size=$(wc -c < "$session_log" 2>/dev/null | tr -d ' ')
|
|
162
162
|
local final_lines=$(wc -l < "$session_log" 2>/dev/null | tr -d ' ')
|
|
163
163
|
log_info "Session log: $final_lines lines, $((final_size / 1024))KB"
|
|
164
|
+
if [[ "$final_size" -lt 1024 && "$exit_code" -eq 0 ]]; then
|
|
165
|
+
log_warn "Session log was truncated during execution (subagent stdout redirection may have severed it)"
|
|
166
|
+
log_warn "Proceeding with exit-code-only outcome detection — child transcripts and git state are still valid"
|
|
167
|
+
fi
|
|
164
168
|
fi
|
|
165
169
|
log_info "exit_code=$exit_code"
|
|
166
170
|
|
|
@@ -418,11 +418,6 @@ If you encounter an unrecoverable error, context overflow, or are about to exit
|
|
|
418
418
|
|
|
419
419
|
2. This file is intentionally lightweight — write it BEFORE context runs out.
|
|
420
420
|
|
|
421
|
-
**Lifecycle**: failure-log.md is a temporary cross-session artifact. Do NOT commit it to git. After a successful session (all phases complete + commit done), delete it:
|
|
422
|
-
```bash
|
|
423
|
-
rm -f .prizmkit/specs/{{FEATURE_SLUG}}/failure-log.md
|
|
424
|
-
```
|
|
425
|
-
|
|
426
421
|
## Reminders
|
|
427
422
|
|
|
428
423
|
- Tier 1: you handle everything directly — no subagents needed
|
|
@@ -432,3 +427,5 @@ rm -f .prizmkit/specs/{{FEATURE_SLUG}}/failure-log.md
|
|
|
432
427
|
- Do NOT run `git add`/`git commit` during Phase 1-3 — all changes are committed once in Phase 4
|
|
433
428
|
- If any files remain after the commit, amend the existing commit — do NOT create a follow-up commit
|
|
434
429
|
- When staging files, always use explicit file names — NEVER use `git add -A` or `git add .`
|
|
430
|
+
- **NEVER delete, modify, or touch any file under `.prizmkit/state/`** — those are pipeline runtime files managed by the runner
|
|
431
|
+
- NEVER run `rm -rf`, `git clean`, or any destructive filesystem operations
|
|
@@ -534,11 +534,6 @@ If you encounter an unrecoverable error, context overflow, or are about to exit
|
|
|
534
534
|
|
|
535
535
|
2. This file is intentionally lightweight — write it BEFORE context runs out.
|
|
536
536
|
|
|
537
|
-
**Lifecycle**: failure-log.md is a temporary cross-session artifact. Do NOT commit it to git. After a successful session (all phases complete + commit done), delete it:
|
|
538
|
-
```bash
|
|
539
|
-
rm -f .prizmkit/specs/{{FEATURE_SLUG}}/failure-log.md
|
|
540
|
-
```
|
|
541
|
-
|
|
542
537
|
## Reminders
|
|
543
538
|
|
|
544
539
|
- Tier 2: orchestrator builds context+plan, Analyzer checks consistency, Dev implements, Reviewer reviews+tests — use direct Agent spawn for agents
|
|
@@ -546,6 +541,8 @@ rm -f .prizmkit/specs/{{FEATURE_SLUG}}/failure-log.md
|
|
|
546
541
|
- context-snapshot.md is append-only: orchestrator writes Sections 1-4, Dev appends Implementation Log, Reviewer appends Review Notes
|
|
547
542
|
- Gate checks enforce Implementation Log and Review Notes are written before proceeding
|
|
548
543
|
- Do NOT use `run_in_background=true` when spawning subagents
|
|
544
|
+
- **NEVER delete, modify, or touch any file under `.prizmkit/state/`** — those are pipeline runtime files managed by the runner
|
|
545
|
+
- NEVER run `rm -rf`, `git clean`, or any destructive filesystem operations
|
|
549
546
|
- `/prizmkit-committer` is mandatory, and must not be replaced with manual git commit commands
|
|
550
547
|
- Do NOT run `git add`/`git commit` during Phase 1-5 — all changes are committed once in Phase 6
|
|
551
548
|
- If any files remain after the commit, amend the existing commit — do NOT create a follow-up commit
|
|
@@ -612,11 +612,6 @@ If you encounter an unrecoverable error, context overflow, or are about to exit
|
|
|
612
612
|
|
|
613
613
|
2. This file is intentionally lightweight — write it BEFORE context runs out.
|
|
614
614
|
|
|
615
|
-
**Lifecycle**: failure-log.md is a temporary cross-session artifact. Do NOT commit it to git. After a successful session (all phases complete + commit done), delete it:
|
|
616
|
-
```bash
|
|
617
|
-
rm -f .prizmkit/specs/{{FEATURE_SLUG}}/failure-log.md
|
|
618
|
-
```
|
|
619
|
-
|
|
620
615
|
## Reminders
|
|
621
616
|
|
|
622
617
|
- Tier 3: full team — Dev (implementation) → Reviewer (review + test) — spawn agents directly via Agent tool
|
|
@@ -624,6 +619,8 @@ rm -f .prizmkit/specs/{{FEATURE_SLUG}}/failure-log.md
|
|
|
624
619
|
- Gate checks enforce Implementation Log and Review Notes are written before proceeding
|
|
625
620
|
- Do NOT use `run_in_background=true` when spawning agents
|
|
626
621
|
- Commit phase must use `/prizmkit-committer`; do NOT replace with manual git commit commands
|
|
622
|
+
- **NEVER delete, modify, or touch any file under `.prizmkit/state/`** — those are pipeline runtime files managed by the runner
|
|
623
|
+
- NEVER run `rm -rf`, `git clean`, or any destructive filesystem operations
|
|
627
624
|
- Do NOT run `git add`/`git commit` during Phase 1-5 — all changes are committed once in Phase 6
|
|
628
625
|
- If any files remain after the commit, amend the existing commit — do NOT create a follow-up commit
|
|
629
626
|
- When staging files, always use explicit file names — NEVER use `git add -A` or `git add .`
|
|
@@ -14,8 +14,3 @@ If you encounter an unrecoverable error, context overflow, or are about to exit
|
|
|
14
14
|
```
|
|
15
15
|
|
|
16
16
|
2. This file is intentionally lightweight — write it BEFORE context runs out.
|
|
17
|
-
|
|
18
|
-
**Lifecycle**: failure-log.md is a temporary cross-session artifact. Do NOT commit it to git. After a successful session (all phases complete + commit done), delete it:
|
|
19
|
-
```bash
|
|
20
|
-
rm -f .prizmkit/specs/{{FEATURE_SLUG}}/failure-log.md
|
|
21
|
-
```
|
|
@@ -41,6 +41,7 @@ start_heartbeat() {
|
|
|
41
41
|
(
|
|
42
42
|
local elapsed=0
|
|
43
43
|
local prev_size=0
|
|
44
|
+
local prev_max_size=0
|
|
44
45
|
local prev_child_activity_signature=""
|
|
45
46
|
local stale_seconds=0
|
|
46
47
|
while kill -0 "$cli_pid" 2>/dev/null; do
|
|
@@ -48,13 +49,28 @@ start_heartbeat() {
|
|
|
48
49
|
elapsed=$((elapsed + heartbeat_interval))
|
|
49
50
|
kill -0 "$cli_pid" 2>/dev/null || break
|
|
50
51
|
|
|
51
|
-
# Get log file size
|
|
52
|
+
# Get log file size. If session_log was truncated (e.g. by subagent
|
|
53
|
+
# stdout redirection severing the file descriptor), detect and flag it.
|
|
52
54
|
local cur_size=0
|
|
53
55
|
if [[ -f "$session_log" ]]; then
|
|
54
56
|
cur_size=$(wc -c < "$session_log" 2>/dev/null || echo 0)
|
|
55
57
|
cur_size=$(echo "$cur_size" | tr -d ' ')
|
|
56
58
|
fi
|
|
57
59
|
|
|
60
|
+
# Detect log truncation: size dropped to 0 or near-zero after previously
|
|
61
|
+
# accumulating significant content (>100KB). This indicates the file was
|
|
62
|
+
# unlinked/truncated by something outside our control while the AI CLI
|
|
63
|
+
# process is still running.
|
|
64
|
+
local log_truncated=false
|
|
65
|
+
if [[ $cur_size -lt 1024 && $prev_max_size -gt 102400 ]]; then
|
|
66
|
+
log_truncated=true
|
|
67
|
+
fi
|
|
68
|
+
# Track the maximum size we've seen for truncation detection
|
|
69
|
+
local prev_max_size=$prev_max_size
|
|
70
|
+
if [[ $cur_size -gt $prev_max_size ]]; then
|
|
71
|
+
prev_max_size=$cur_size
|
|
72
|
+
fi
|
|
73
|
+
|
|
58
74
|
local growth=$((cur_size - prev_size))
|
|
59
75
|
prev_size=$cur_size
|
|
60
76
|
|
|
@@ -183,16 +199,30 @@ PY
|
|
|
183
199
|
# tool while child transcripts keep growing, so child activity counts.
|
|
184
200
|
# Error loops bypass normal growth-as-progress because the log is only
|
|
185
201
|
# growing with repeated failed reads or wasted calls.
|
|
202
|
+
#
|
|
203
|
+
# When the main session log has been truncated (e.g. by subagent stdout
|
|
204
|
+
# redirection severing the file descriptor), use child activity as the
|
|
205
|
+
# primary progress signal — the parent process is still running and children
|
|
206
|
+
# are still producing output, so this is not a true stall.
|
|
186
207
|
if [[ "$error_loop_detected" == "true" ]]; then
|
|
187
208
|
stale_seconds=$effective_stale_kill_threshold
|
|
188
|
-
elif [[ $
|
|
209
|
+
elif [[ "$log_truncated" == "true" ]]; then
|
|
210
|
+
# Log truncated: rely on child growth and CLI process liveness.
|
|
211
|
+
# Don't increment staleness — the process is still working.
|
|
212
|
+
if [[ $child_growth -gt 0 ]]; then
|
|
213
|
+
stale_seconds=0
|
|
214
|
+
fi
|
|
215
|
+
# If neither log nor children grow, this is a real stall
|
|
216
|
+
elif [[ $growth -le 0 && $child_growth -eq 0 ]]; then
|
|
189
217
|
stale_seconds=$((stale_seconds + heartbeat_interval))
|
|
190
218
|
else
|
|
191
219
|
stale_seconds=0
|
|
192
220
|
fi
|
|
193
221
|
|
|
194
222
|
local size_display
|
|
195
|
-
if
|
|
223
|
+
if $log_truncated; then
|
|
224
|
+
size_display="${cur_size}B/TRUNCATED(from ${prev_max_size}B)"
|
|
225
|
+
elif [[ $cur_size -gt 1048576 ]]; then
|
|
196
226
|
size_display="$((cur_size / 1048576))MB"
|
|
197
227
|
elif [[ $cur_size -gt 1024 ]]; then
|
|
198
228
|
size_display="$((cur_size / 1024))KB"
|
|
@@ -219,7 +249,9 @@ PY
|
|
|
219
249
|
local secs=$((elapsed % 60))
|
|
220
250
|
|
|
221
251
|
local status_icon
|
|
222
|
-
if
|
|
252
|
+
if $log_truncated; then
|
|
253
|
+
status_icon="${RED}⚠${NC}"
|
|
254
|
+
elif [[ $growth -gt 0 || $child_growth -gt 0 ]]; then
|
|
223
255
|
status_icon="${GREEN}▶${NC}"
|
|
224
256
|
else
|
|
225
257
|
status_icon="${YELLOW}⏸${NC}"
|