@kraftapps-ai/kai 1.8.6 → 1.9.0
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 +46 -59
- package/package.json +1 -1
package/kai
CHANGED
|
@@ -61,11 +61,25 @@ MEMORY_FILE=".kai/memory.md"
|
|
|
61
61
|
LOOP_SCRIPT=".kai/loop.sh"
|
|
62
62
|
|
|
63
63
|
|
|
64
|
-
# ── Ensure .kai/
|
|
64
|
+
# ── Ensure .kai/ and Playwright artifacts are git-ignored ─
|
|
65
65
|
|
|
66
66
|
mkdir -p .kai
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
|
|
68
|
+
# Add to project .gitignore (not just .kai/.gitignore) to prevent tracking
|
|
69
|
+
if [ -f ".gitignore" ]; then
|
|
70
|
+
for pattern in ".kai/" ".playwright-mcp/"; do
|
|
71
|
+
grep -qxF "$pattern" .gitignore 2>/dev/null || echo "$pattern" >> .gitignore
|
|
72
|
+
done
|
|
73
|
+
else
|
|
74
|
+
printf '%s\n' ".kai/" ".playwright-mcp/" > .gitignore
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
# Untrack .kai/ files if they were committed before the gitignore existed
|
|
78
|
+
if git ls-files --cached .kai/ 2>/dev/null | grep -q .; then
|
|
79
|
+
git rm -r --cached .kai/ > /dev/null 2>&1 || true
|
|
80
|
+
fi
|
|
81
|
+
if git ls-files --cached .playwright-mcp/ 2>/dev/null | grep -q .; then
|
|
82
|
+
git rm -r --cached .playwright-mcp/ > /dev/null 2>&1 || true
|
|
69
83
|
fi
|
|
70
84
|
|
|
71
85
|
# ── Auto-init if needed ───────────────────────────────
|
|
@@ -230,12 +244,6 @@ LOOP_MCP_ARGS="--mcp-config .kai/loop-mcp.json"
|
|
|
230
244
|
# Cap Node.js memory to prevent test runners from consuming all RAM
|
|
231
245
|
export NODE_OPTIONS="--max-old-space-size=2048"
|
|
232
246
|
|
|
233
|
-
# Stream output live when running in a tmux pane
|
|
234
|
-
KAI_STREAM=false
|
|
235
|
-
if [ -n "${TMUX:-}" ]; then
|
|
236
|
-
KAI_STREAM=true
|
|
237
|
-
fi
|
|
238
|
-
|
|
239
247
|
WORKER_PROMPT='You are an autonomous AI developer specializing in Shopify app and theme development.
|
|
240
248
|
|
|
241
249
|
## Your Shopify expertise
|
|
@@ -338,51 +346,37 @@ while :; do
|
|
|
338
346
|
|
|
339
347
|
start_time=$(date +%s)
|
|
340
348
|
|
|
341
|
-
#
|
|
349
|
+
# jq filter for streaming claude output — shows tool calls, text, and results
|
|
350
|
+
STREAM_FILTER='
|
|
351
|
+
if .type == "assistant" then
|
|
352
|
+
([.message.content[] |
|
|
353
|
+
if .type == "tool_use" then "⚡ " + .name + ": " + (.input.command // .input.file_path // .input.pattern // "" | tostring | .[0:150])
|
|
354
|
+
elif .type == "text" then .text
|
|
355
|
+
else empty end
|
|
356
|
+
] | join("\n"))
|
|
357
|
+
elif .type == "user" and .tool_use_result then
|
|
358
|
+
" → " + (.tool_use_result.stdout // "" | .[0:200] | gsub("\n"; " "))
|
|
359
|
+
elif .type == "result" then
|
|
360
|
+
"✅ Done (" + (.duration_ms / 1000 | tostring | .[0:5]) + "s, $" + (.total_cost_usd | tostring | .[0:6]) + ")"
|
|
361
|
+
else empty end'
|
|
362
|
+
|
|
363
|
+
# Stream worker output live
|
|
342
364
|
set +e
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
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)
|
|
365
|
+
claude -p --output-format stream-json --verbose --dangerously-skip-permissions $LOOP_MCP_ARGS \
|
|
366
|
+
--system-prompt "$WORKER_PROMPT" $context_files 2>&1 | \
|
|
367
|
+
tee .kai/worker-stream.tmp | \
|
|
368
|
+
jq --unbuffered -r "$STREAM_FILTER" 2>/dev/null
|
|
369
|
+
exit_code=${PIPESTATUS[0]}
|
|
370
|
+
result=$(jq -r 'select(.type == "result") | .result // empty' .kai/worker-stream.tmp 2>/dev/null)
|
|
373
371
|
set -e
|
|
374
372
|
|
|
375
373
|
elapsed=$(( $(date +%s) - start_time ))
|
|
376
374
|
|
|
377
375
|
if [ $exit_code -ne 0 ]; then
|
|
378
|
-
echo " Worker failed (code ${exit_code}).
|
|
379
|
-
echo "$result" | tail -10
|
|
380
|
-
echo " Restarting..."
|
|
376
|
+
echo " Worker failed (code ${exit_code}). Restarting..."
|
|
381
377
|
continue
|
|
382
378
|
fi
|
|
383
379
|
|
|
384
|
-
echo "$result" | tail -20
|
|
385
|
-
|
|
386
380
|
if [[ "$result" == *"<promise>COMPLETE</promise>"* ]]; then
|
|
387
381
|
echo "All stories complete after $iteration iterations!"
|
|
388
382
|
exit 0
|
|
@@ -391,7 +385,8 @@ while :; do
|
|
|
391
385
|
# Review
|
|
392
386
|
STORY_PASSES=$(jq -r --arg id "$NEXT_ID" '.userStories[] | select(.id == $id) | .passes' "$PRD_FILE")
|
|
393
387
|
if [ "$STORY_PASSES" = "true" ]; then
|
|
394
|
-
echo "
|
|
388
|
+
echo ""
|
|
389
|
+
echo " 📋 Reviewing story #${NEXT_ID}..."
|
|
395
390
|
last_commit=$(git log --oneline -1 2>/dev/null || echo "no git")
|
|
396
391
|
ACCEPTANCE=$(jq -r --arg id "$NEXT_ID" '.userStories[] | select(.id == $id) | .acceptanceCriteria | join("\n- ")' "$PRD_FILE")
|
|
397
392
|
|
|
@@ -406,21 +401,13 @@ If ANY fails: REVIEW_FAIL: [reason]
|
|
|
406
401
|
If all pass: REVIEW_PASS"
|
|
407
402
|
|
|
408
403
|
set +e
|
|
409
|
-
claude -p --dangerously-skip-permissions $LOOP_MCP_ARGS
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
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)
|
|
404
|
+
claude -p --output-format stream-json --verbose --dangerously-skip-permissions $LOOP_MCP_ARGS \
|
|
405
|
+
"$REVIEW_PROMPT" 2>&1 | \
|
|
406
|
+
tee .kai/review-stream.tmp | \
|
|
407
|
+
jq --unbuffered -r "$STREAM_FILTER" 2>/dev/null
|
|
408
|
+
review=$(jq -r 'select(.type == "result") | .result // empty' .kai/review-stream.tmp 2>/dev/null)
|
|
420
409
|
set -e
|
|
421
410
|
|
|
422
|
-
echo "$review" | tail -5
|
|
423
|
-
|
|
424
411
|
if [[ "$review" == *"REVIEW_FAIL"* ]]; then
|
|
425
412
|
jq --arg id "$NEXT_ID" '(.userStories[] | select(.id == $id)).passes = false' "$PRD_FILE" > "${PRD_FILE}.tmp" && mv "${PRD_FILE}.tmp" "$PRD_FILE"
|
|
426
413
|
echo "REVIEW FEEDBACK: $review" >> "$PROGRESS_FILE"
|