prizmkit 1.1.82 → 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.
@@ -1,5 +1,5 @@
1
1
  {
2
- "frameworkVersion": "1.1.82",
3
- "bundledAt": "2026-06-30T03:07:55.258Z",
4
- "bundledFrom": "c12c40b"
2
+ "frameworkVersion": "1.1.83",
3
+ "bundledAt": "2026-06-30T06:54:40.455Z",
4
+ "bundledFrom": "74dab7e"
5
5
  }
@@ -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[@]}" > "$log_path" 2>&1 &
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" > "$log_path" 2>&1 &
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" > "$log_path" 2>&1 &
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[@]}" > "$log_path" 2>&1
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" > "$log_path" 2>&1
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" > "$log_path" 2>&1
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,8 +199,20 @@ 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
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
188
216
  elif [[ $growth -le 0 && $child_growth -eq 0 ]]; then
189
217
  stale_seconds=$((stale_seconds + heartbeat_interval))
190
218
  else
@@ -192,7 +220,9 @@ PY
192
220
  fi
193
221
 
194
222
  local size_display
195
- if [[ $cur_size -gt 1048576 ]]; then
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 [[ $growth -gt 0 || $child_growth -gt 0 ]]; then
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
 
@@ -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
 
@@ -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 [[ $growth -eq 0 && $child_growth -eq 0 ]]; then
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 [[ $cur_size -gt 1048576 ]]; then
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 [[ $growth -gt 0 || $child_growth -gt 0 ]]; then
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}"
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.1.82",
2
+ "version": "1.1.83",
3
3
  "skills": {
4
4
  "prizm-kit": {
5
5
  "description": "Full-lifecycle dev toolkit. Covers spec-driven development, Prizm context docs, code quality, debugging, deployment, and knowledge management.",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prizmkit",
3
- "version": "1.1.82",
3
+ "version": "1.1.83",
4
4
  "description": "Create a new PrizmKit-powered project with clean initialization — no framework dev files, just what you need.",
5
5
  "type": "module",
6
6
  "bin": {