@kraftapps-ai/kai 1.8.4 → 1.8.6

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 (2) hide show
  1. package/kai +56 -19
  2. package/package.json +1 -1
package/kai CHANGED
@@ -338,25 +338,51 @@ while :; do
338
338
 
339
339
  start_time=$(date +%s)
340
340
 
341
+ # Run worker in background with heartbeat monitor
341
342
  set +e
342
- if [ "$KAI_STREAM" = true ]; then
343
- claude -p --dangerously-skip-permissions $LOOP_MCP_ARGS --system-prompt "$WORKER_PROMPT" $context_files 2>&1 | tee .kai/worker-output.tmp
344
- exit_code=${PIPESTATUS[0]}
345
- result=$(cat .kai/worker-output.tmp)
346
- else
347
- result=$(claude -p --dangerously-skip-permissions $LOOP_MCP_ARGS --system-prompt "$WORKER_PROMPT" $context_files)
348
- exit_code=$?
349
- echo "$result" | tail -20
350
- fi
343
+ touch .kai/worker-heartbeat
344
+ claude -p --dangerously-skip-permissions $LOOP_MCP_ARGS --system-prompt "$WORKER_PROMPT" $context_files > .kai/worker-output.tmp 2>&1 &
345
+ worker_pid=$!
346
+
347
+ echo " Worker started (PID $worker_pid)"
348
+ while kill -0 $worker_pid 2>/dev/null; do
349
+ sleep 30
350
+ elapsed_now=$(( $(date +%s) - start_time ))
351
+ mins=$((elapsed_now / 60))
352
+ secs=$((elapsed_now % 60))
353
+
354
+ # Detect what's running
355
+ activity=""
356
+ pgrep -f "vitest" > /dev/null 2>&1 && activity="running tests"
357
+ pgrep -f "esbuild" > /dev/null 2>&1 && activity="${activity:+$activity + }building"
358
+ pgrep -f "npm run build" > /dev/null 2>&1 && activity="${activity:+$activity + }building"
359
+ [ -z "$activity" ] && activity="thinking"
360
+
361
+ # Show recently changed files
362
+ changed=$(find . \( -name '*.ts' -o -name '*.tsx' -o -name '*.php' -o -name '*.less' -o -name '*.css' -o -name '*.json' \) \
363
+ -not -path './node_modules/*' -not -path './.kai/*' -not -path './vendor/*' \
364
+ -newer .kai/worker-heartbeat -printf '%f\n' 2>/dev/null | sort -u | head -5 | tr '\n' ', ')
365
+
366
+ echo " [${mins}m${secs}s] ${activity}${changed:+ | files: ${changed%,}}"
367
+ touch .kai/worker-heartbeat
368
+ done
369
+
370
+ wait $worker_pid
371
+ exit_code=$?
372
+ result=$(cat .kai/worker-output.tmp)
351
373
  set -e
352
374
 
353
375
  elapsed=$(( $(date +%s) - start_time ))
354
376
 
355
377
  if [ $exit_code -ne 0 ]; then
356
- echo "Failed (code ${exit_code}). Restarting..."
378
+ echo " Worker failed (code ${exit_code}). Last output:"
379
+ echo "$result" | tail -10
380
+ echo " Restarting..."
357
381
  continue
358
382
  fi
359
383
 
384
+ echo "$result" | tail -20
385
+
360
386
  if [[ "$result" == *"<promise>COMPLETE</promise>"* ]]; then
361
387
  echo "All stories complete after $iteration iterations!"
362
388
  exit 0
@@ -365,6 +391,7 @@ while :; do
365
391
  # Review
366
392
  STORY_PASSES=$(jq -r --arg id "$NEXT_ID" '.userStories[] | select(.id == $id) | .passes' "$PRD_FILE")
367
393
  if [ "$STORY_PASSES" = "true" ]; then
394
+ echo " Reviewing story #${NEXT_ID}..."
368
395
  last_commit=$(git log --oneline -1 2>/dev/null || echo "no git")
369
396
  ACCEPTANCE=$(jq -r --arg id "$NEXT_ID" '.userStories[] | select(.id == $id) | .acceptanceCriteria | join("\n- ")' "$PRD_FILE")
370
397
 
@@ -379,15 +406,21 @@ If ANY fails: REVIEW_FAIL: [reason]
379
406
  If all pass: REVIEW_PASS"
380
407
 
381
408
  set +e
382
- if [ "$KAI_STREAM" = true ]; then
383
- claude -p --dangerously-skip-permissions $LOOP_MCP_ARGS "$REVIEW_PROMPT" 2>&1 | tee .kai/review-output.tmp
384
- review=$(cat .kai/review-output.tmp)
385
- else
386
- review=$(claude -p --dangerously-skip-permissions $LOOP_MCP_ARGS "$REVIEW_PROMPT")
387
- echo "$review" | tail -5
388
- fi
409
+ claude -p --dangerously-skip-permissions $LOOP_MCP_ARGS "$REVIEW_PROMPT" > .kai/review-output.tmp 2>&1 &
410
+ review_pid=$!
411
+
412
+ while kill -0 $review_pid 2>/dev/null; do
413
+ sleep 15
414
+ elapsed_now=$(( $(date +%s) - start_time ))
415
+ echo " [${elapsed_now}s] reviewing..."
416
+ done
417
+
418
+ wait $review_pid
419
+ review=$(cat .kai/review-output.tmp)
389
420
  set -e
390
421
 
422
+ echo "$review" | tail -5
423
+
391
424
  if [[ "$review" == *"REVIEW_FAIL"* ]]; then
392
425
  jq --arg id "$NEXT_ID" '(.userStories[] | select(.id == $id)).passes = false' "$PRD_FILE" > "${PRD_FILE}.tmp" && mv "${PRD_FILE}.tmp" "$PRD_FILE"
393
426
  echo "REVIEW FEEDBACK: $review" >> "$PROGRESS_FILE"
@@ -459,12 +492,16 @@ The developer's name is: ${dev_name}"
459
492
 
460
493
  # ── Build loop run instructions for PM ────────────────
461
494
 
495
+ LOOP_MONITOR="After starting the loop, IMMEDIATELY run \`/loop 5m\` with a prompt that reads .kai/stories.json and .kai/progress.txt to check progress, then report a brief status update to the developer (e.g., \"Story #X complete, working on #Y, 3 remaining\"). Stop the /loop when all stories are done or the loop has stopped."
496
+
462
497
  if [ "$KAI_TMUX" = true ] || [ -n "${TMUX:-}" ]; then
463
498
  LOOP_INSTRUCTIONS="To run implementation, execute: \`tmux send-keys -t ${KAI_TMUX_SESSION}:0.1 '.kai/loop.sh 2>&1 | tee .kai/loop.log' Enter\`
464
499
  The dev loop output streams live in the right tmux pane. You can also check \`tail -f .kai/loop.log\`.
465
- To stop the loop: \`tmux send-keys -t ${KAI_TMUX_SESSION}:0.1 C-c\`"
500
+ To stop the loop: \`tmux send-keys -t ${KAI_TMUX_SESSION}:0.1 C-c\`
501
+ ${LOOP_MONITOR}"
466
502
  else
467
- LOOP_INSTRUCTIONS="To run implementation, execute: \`nohup .kai/loop.sh > .kai/loop.log 2>&1 &\` then monitor with \`tail -f .kai/loop.log\`"
503
+ LOOP_INSTRUCTIONS="To run implementation, execute: \`nohup .kai/loop.sh > .kai/loop.log 2>&1 &\` then monitor with \`tail -f .kai/loop.log\`
504
+ ${LOOP_MONITOR}"
468
505
  fi
469
506
 
470
507
  # ── Build Claude args ─────────────────────────────────
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kraftapps-ai/kai",
3
- "version": "1.8.4",
3
+ "version": "1.8.6",
4
4
  "description": "Autonomous AI developer loop for Claude Code",
5
5
  "bin": {
6
6
  "kai": "kai"