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.
@@ -1,5 +1,5 @@
1
1
  {
2
- "frameworkVersion": "1.1.81",
3
- "bundledAt": "2026-06-29T17:31:12.809Z",
4
- "bundledFrom": "65df08d"
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,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}"
@@ -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 [[ $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.81",
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.81",
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": {