@kraftapps-ai/kai 1.8.3 → 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 +67 -23
- package/package.json +1 -1
package/kai
CHANGED
|
@@ -227,6 +227,9 @@ PRD_FILE=".kai/stories.json"
|
|
|
227
227
|
PROGRESS_FILE=".kai/progress.txt"
|
|
228
228
|
LOOP_MCP_ARGS="--mcp-config .kai/loop-mcp.json"
|
|
229
229
|
|
|
230
|
+
# Cap Node.js memory to prevent test runners from consuming all RAM
|
|
231
|
+
export NODE_OPTIONS="--max-old-space-size=2048"
|
|
232
|
+
|
|
230
233
|
# Stream output live when running in a tmux pane
|
|
231
234
|
KAI_STREAM=false
|
|
232
235
|
if [ -n "${TMUX:-}" ]; then
|
|
@@ -265,11 +268,15 @@ You are an expert Shopify developer. You have access to the Shopify Dev MCP tool
|
|
|
265
268
|
2. Read .kai/progress.txt for context on previous work.
|
|
266
269
|
3. **PLAN before coding.** List files and changes before touching code.
|
|
267
270
|
4. If the story involves Shopify APIs, call `learn_shopify_api` then use `introspect_graphql_schema` and `search_docs_chunks` to understand the right approach.
|
|
268
|
-
5. **WRITE FAILING TESTS FIRST.** For each acceptance criterion, write a test that verifies it. Run the
|
|
269
|
-
6. **Implement ONLY enough code to make the tests pass (green).** No more, no less.
|
|
271
|
+
5. **WRITE FAILING TESTS FIRST.** For each acceptance criterion, write a test that verifies it. Run ONLY the relevant test file(s) — they MUST fail (red). If a test already passes, your test is not testing the right thing.
|
|
272
|
+
6. **Implement ONLY enough code to make the tests pass (green).** No more, no less. Run only the relevant test file(s) to verify.
|
|
270
273
|
7. **Refactor** if needed — clean up while keeping tests green.
|
|
271
|
-
8.
|
|
274
|
+
8. **Final validation ONCE:** Run the full test suite ONE TIME at the end. Also validate GraphQL with `validate_graphql_codeblocks`, validate Liquid with `validate_theme_codeblocks`.
|
|
272
275
|
9. **SELF-REVIEW.** For each acceptance criterion, cite the test that covers it AND evidence it passes (file, line, command output). No "should work" or "probably".
|
|
276
|
+
|
|
277
|
+
## IMPORTANT: Resource management
|
|
278
|
+
- **NEVER run the full test suite repeatedly.** Run targeted tests during development (e.g., `npx vitest run path/to/test.ts`). Only run the full suite ONCE as a final check before committing.
|
|
279
|
+
- **Always use `npx vitest run`** (not `npx vitest` without `run`) — watch mode will hang forever.
|
|
273
280
|
10. Commit with a descriptive message.
|
|
274
281
|
11. Update .kai/stories.json: set `passes` to `true`.
|
|
275
282
|
12. Append to .kai/progress.txt.
|
|
@@ -278,7 +285,7 @@ You are an expert Shopify developer. You have access to the Shopify Dev MCP tool
|
|
|
278
285
|
- ONE STORY PER LOOP.
|
|
279
286
|
- **TDD is mandatory.** Tests first, then implementation. No exceptions.
|
|
280
287
|
- No placeholders. Fully implement or report BLOCKED.
|
|
281
|
-
- Do not break existing functionality. Run the
|
|
288
|
+
- Do not break existing functionality. Run the full test suite ONCE at the end as a final check.
|
|
282
289
|
- ALWAYS validate GraphQL and Liquid code using the MCP tools before marking complete.
|
|
283
290
|
- If ALL stories have `passes: true`, output: <promise>COMPLETE</promise>
|
|
284
291
|
|
|
@@ -331,25 +338,51 @@ while :; do
|
|
|
331
338
|
|
|
332
339
|
start_time=$(date +%s)
|
|
333
340
|
|
|
341
|
+
# Run worker in background with heartbeat monitor
|
|
334
342
|
set +e
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
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)
|
|
344
373
|
set -e
|
|
345
374
|
|
|
346
375
|
elapsed=$(( $(date +%s) - start_time ))
|
|
347
376
|
|
|
348
377
|
if [ $exit_code -ne 0 ]; then
|
|
349
|
-
echo "
|
|
378
|
+
echo " Worker failed (code ${exit_code}). Last output:"
|
|
379
|
+
echo "$result" | tail -10
|
|
380
|
+
echo " Restarting..."
|
|
350
381
|
continue
|
|
351
382
|
fi
|
|
352
383
|
|
|
384
|
+
echo "$result" | tail -20
|
|
385
|
+
|
|
353
386
|
if [[ "$result" == *"<promise>COMPLETE</promise>"* ]]; then
|
|
354
387
|
echo "All stories complete after $iteration iterations!"
|
|
355
388
|
exit 0
|
|
@@ -358,6 +391,7 @@ while :; do
|
|
|
358
391
|
# Review
|
|
359
392
|
STORY_PASSES=$(jq -r --arg id "$NEXT_ID" '.userStories[] | select(.id == $id) | .passes' "$PRD_FILE")
|
|
360
393
|
if [ "$STORY_PASSES" = "true" ]; then
|
|
394
|
+
echo " Reviewing story #${NEXT_ID}..."
|
|
361
395
|
last_commit=$(git log --oneline -1 2>/dev/null || echo "no git")
|
|
362
396
|
ACCEPTANCE=$(jq -r --arg id "$NEXT_ID" '.userStories[] | select(.id == $id) | .acceptanceCriteria | join("\n- ")' "$PRD_FILE")
|
|
363
397
|
|
|
@@ -372,15 +406,21 @@ If ANY fails: REVIEW_FAIL: [reason]
|
|
|
372
406
|
If all pass: REVIEW_PASS"
|
|
373
407
|
|
|
374
408
|
set +e
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
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)
|
|
382
420
|
set -e
|
|
383
421
|
|
|
422
|
+
echo "$review" | tail -5
|
|
423
|
+
|
|
384
424
|
if [[ "$review" == *"REVIEW_FAIL"* ]]; then
|
|
385
425
|
jq --arg id "$NEXT_ID" '(.userStories[] | select(.id == $id)).passes = false' "$PRD_FILE" > "${PRD_FILE}.tmp" && mv "${PRD_FILE}.tmp" "$PRD_FILE"
|
|
386
426
|
echo "REVIEW FEEDBACK: $review" >> "$PROGRESS_FILE"
|
|
@@ -452,12 +492,16 @@ The developer's name is: ${dev_name}"
|
|
|
452
492
|
|
|
453
493
|
# ── Build loop run instructions for PM ────────────────
|
|
454
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
|
+
|
|
455
497
|
if [ "$KAI_TMUX" = true ] || [ -n "${TMUX:-}" ]; then
|
|
456
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\`
|
|
457
499
|
The dev loop output streams live in the right tmux pane. You can also check \`tail -f .kai/loop.log\`.
|
|
458
|
-
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}"
|
|
459
502
|
else
|
|
460
|
-
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}"
|
|
461
505
|
fi
|
|
462
506
|
|
|
463
507
|
# ── Build Claude args ─────────────────────────────────
|