@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.
- package/kai +56 -19
- 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
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
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 "
|
|
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
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
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 ─────────────────────────────────
|