@kraftapps-ai/kai 1.5.5 → 1.6.4
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 +60 -98
- package/package.json +1 -1
package/kai
CHANGED
|
@@ -17,17 +17,9 @@ fi
|
|
|
17
17
|
|
|
18
18
|
PRD_FILE=".kai/stories.json"
|
|
19
19
|
PROGRESS_FILE=".kai/progress.txt"
|
|
20
|
-
PROMPT_FILE=".kai/PROMPT.md"
|
|
21
20
|
MEMORY_FILE=".kai/memory.md"
|
|
22
|
-
SESSION_FILE=".kai/session_id"
|
|
23
21
|
LOOP_SCRIPT=".kai/loop.sh"
|
|
24
22
|
|
|
25
|
-
# ── Handle --new flag ─────────────────────────────────
|
|
26
|
-
|
|
27
|
-
if [ "${1:-}" = "--new" ]; then
|
|
28
|
-
rm -f "$SESSION_FILE"
|
|
29
|
-
shift
|
|
30
|
-
fi
|
|
31
23
|
|
|
32
24
|
# ── Ensure .kai/ is git-ignored ───────────────────────
|
|
33
25
|
|
|
@@ -61,36 +53,6 @@ if [ ! -f "$PRD_FILE" ]; then
|
|
|
61
53
|
EOF
|
|
62
54
|
|
|
63
55
|
echo "# Kai Progress Log" > "$PROGRESS_FILE"
|
|
64
|
-
|
|
65
|
-
cat > "$PROMPT_FILE" << 'EOF'
|
|
66
|
-
# Project Context
|
|
67
|
-
|
|
68
|
-
Add your project-specific context here. The more you provide, the better Kai performs.
|
|
69
|
-
|
|
70
|
-
## Shopify Store
|
|
71
|
-
<!-- Kai auto-detects store info from shopify.app.toml and .env -->
|
|
72
|
-
<!-- Only fill this in if auto-detection doesn't work for your setup -->
|
|
73
|
-
<!-- Store domain: your-store.myshopify.com -->
|
|
74
|
-
<!-- App handle: your-app-handle -->
|
|
75
|
-
|
|
76
|
-
## Tech stack
|
|
77
|
-
<!-- e.g., Remix + TypeScript, Next.js, Ruby on Rails -->
|
|
78
|
-
|
|
79
|
-
## Build command
|
|
80
|
-
<!-- e.g., npm run build, shopify app build -->
|
|
81
|
-
|
|
82
|
-
## Test command
|
|
83
|
-
<!-- e.g., npm test, shopify app test -->
|
|
84
|
-
|
|
85
|
-
## Dev command
|
|
86
|
-
<!-- e.g., npm run dev, shopify app dev -->
|
|
87
|
-
|
|
88
|
-
## Project structure
|
|
89
|
-
<!-- Key directories and files -->
|
|
90
|
-
|
|
91
|
-
## Conventions
|
|
92
|
-
<!-- Coding style, naming, patterns -->
|
|
93
|
-
EOF
|
|
94
56
|
fi
|
|
95
57
|
|
|
96
58
|
# Init memory file if it doesn't exist
|
|
@@ -121,6 +83,7 @@ fi
|
|
|
121
83
|
# Track what's already configured
|
|
122
84
|
playwright_available=false
|
|
123
85
|
shopify_dev_available=false
|
|
86
|
+
mantle_available=false
|
|
124
87
|
|
|
125
88
|
for config in \
|
|
126
89
|
".mcp.json" \
|
|
@@ -130,6 +93,7 @@ for config in \
|
|
|
130
93
|
if [ -f "$config" ]; then
|
|
131
94
|
grep -q "playwright" "$config" 2>/dev/null && playwright_available=true
|
|
132
95
|
grep -q "shopify-dev" "$config" 2>/dev/null && shopify_dev_available=true
|
|
96
|
+
grep -q "mantle" "$config" 2>/dev/null && mantle_available=true
|
|
133
97
|
fi
|
|
134
98
|
done
|
|
135
99
|
|
|
@@ -145,7 +109,7 @@ fi
|
|
|
145
109
|
|
|
146
110
|
# Build MCP config with all needed servers
|
|
147
111
|
needs_mcp_update=false
|
|
148
|
-
if [ "$playwright_available" = false ] || [ "$shopify_dev_available" = false ]; then
|
|
112
|
+
if [ "$playwright_available" = false ] || [ "$shopify_dev_available" = false ] || [ "$mantle_available" = false ]; then
|
|
149
113
|
needs_mcp_update=true
|
|
150
114
|
fi
|
|
151
115
|
|
|
@@ -164,11 +128,18 @@ if [ "$needs_mcp_update" = true ]; then
|
|
|
164
128
|
mcp_config=$(echo "$mcp_config" | jq '.mcpServers["shopify-dev-mcp"] = {"command": "npx", "args": ["-y", "@shopify/dev-mcp@latest"]}')
|
|
165
129
|
fi
|
|
166
130
|
|
|
131
|
+
if [ "$mantle_available" = false ] && ! echo "$mcp_config" | grep -q "mantle"; then
|
|
132
|
+
echo "Setting up Mantle MCP (billing, subscriptions, analytics)..."
|
|
133
|
+
mcp_config=$(echo "$mcp_config" | jq '.mcpServers["mantle-foundations"] = {"url": "https://mcp.heymantle.com/foundations"}')
|
|
134
|
+
mcp_config=$(echo "$mcp_config" | jq '.mcpServers["mantle-core"] = {"url": "https://mcp.heymantle.com/core"}')
|
|
135
|
+
fi
|
|
136
|
+
|
|
167
137
|
echo "$mcp_config" > .mcp.json
|
|
168
138
|
else
|
|
169
139
|
echo "Setting up MCP servers..."
|
|
170
140
|
echo " - Playwright (browser testing)"
|
|
171
141
|
echo " - Shopify Dev MCP (docs, GraphQL schemas, Liquid validation)"
|
|
142
|
+
echo " - Mantle MCP (billing, subscriptions, analytics)"
|
|
172
143
|
|
|
173
144
|
cat > .mcp.json << 'MCPEOF'
|
|
174
145
|
{
|
|
@@ -180,6 +151,12 @@ if [ "$needs_mcp_update" = true ]; then
|
|
|
180
151
|
"shopify-dev-mcp": {
|
|
181
152
|
"command": "npx",
|
|
182
153
|
"args": ["-y", "@shopify/dev-mcp@latest"]
|
|
154
|
+
},
|
|
155
|
+
"mantle-foundations": {
|
|
156
|
+
"url": "https://mcp.heymantle.com/foundations"
|
|
157
|
+
},
|
|
158
|
+
"mantle-core": {
|
|
159
|
+
"url": "https://mcp.heymantle.com/core"
|
|
183
160
|
}
|
|
184
161
|
}
|
|
185
162
|
}
|
|
@@ -197,7 +174,6 @@ set -e
|
|
|
197
174
|
|
|
198
175
|
PRD_FILE=".kai/stories.json"
|
|
199
176
|
PROGRESS_FILE=".kai/progress.txt"
|
|
200
|
-
PROMPT_FILE=".kai/PROMPT.md"
|
|
201
177
|
|
|
202
178
|
WORKER_PROMPT='You are an autonomous AI developer specializing in Shopify app and theme development.
|
|
203
179
|
|
|
@@ -255,7 +231,7 @@ You are an expert Shopify developer. You have access to the Shopify Dev MCP tool
|
|
|
255
231
|
| "Skip review" | Simple code has bugs. | Always self-review. |
|
|
256
232
|
| "I know the API" | APIs change. Schema is truth. | Introspect first. |'
|
|
257
233
|
|
|
258
|
-
context_files="@${
|
|
234
|
+
context_files="@${PRD_FILE} @${PROGRESS_FILE}"
|
|
259
235
|
if [ -f ".kai/context.txt" ]; then
|
|
260
236
|
while IFS= read -r file; do
|
|
261
237
|
[ -n "$file" ] && [ -f "$file" ] && context_files="$context_files @${file}"
|
|
@@ -357,23 +333,25 @@ $(jq -r '.userStories[] | "- [\(if .passes then "DONE" else "TODO" end)] #\(.id)
|
|
|
357
333
|
fi
|
|
358
334
|
fi
|
|
359
335
|
|
|
360
|
-
project_context=""
|
|
361
|
-
[ -f "$PROMPT_FILE" ] && project_context="
|
|
362
|
-
|
|
363
|
-
Project context (.kai/PROMPT.md):
|
|
364
|
-
$(cat "$PROMPT_FILE")"
|
|
365
|
-
|
|
366
336
|
progress=""
|
|
367
|
-
[ -f "$PROGRESS_FILE" ] && [ "$(wc -l < "$PROGRESS_FILE")" -gt 2 ]
|
|
337
|
+
if [ -f "$PROGRESS_FILE" ] && [ "$(wc -l < "$PROGRESS_FILE")" -gt 2 ]; then
|
|
338
|
+
progress="
|
|
368
339
|
|
|
369
340
|
Recent progress (.kai/progress.txt):
|
|
370
|
-
$(tail -
|
|
341
|
+
$(tail -15 "$PROGRESS_FILE")"
|
|
342
|
+
fi
|
|
371
343
|
|
|
344
|
+
# Only inject memory if it has real content (not just the default template)
|
|
372
345
|
memory=""
|
|
373
|
-
[ -f "$MEMORY_FILE" ]
|
|
346
|
+
if [ -f "$MEMORY_FILE" ]; then
|
|
347
|
+
stripped_mem=$(sed 's/<!--.*-->//g' "$MEMORY_FILE" | sed '/^$/N;/^\n$/d')
|
|
348
|
+
if echo "$stripped_mem" | grep -qvE '^(#|$)'; then
|
|
349
|
+
memory="
|
|
374
350
|
|
|
375
351
|
## Kai Memory (from previous sessions)
|
|
376
352
|
$(cat "$MEMORY_FILE")"
|
|
353
|
+
fi
|
|
354
|
+
fi
|
|
377
355
|
|
|
378
356
|
dev_name=$(git config user.name 2>/dev/null || echo "")
|
|
379
357
|
dev_greeting=""
|
|
@@ -382,17 +360,7 @@ The developer's name is: ${dev_name}"
|
|
|
382
360
|
|
|
383
361
|
# ── Build Claude args ─────────────────────────────────
|
|
384
362
|
|
|
385
|
-
CLAUDE_ARGS="--dangerously-skip-permissions"
|
|
386
|
-
|
|
387
|
-
# Session persistence: reuse the same session ID per repo
|
|
388
|
-
if [ -f "$SESSION_FILE" ]; then
|
|
389
|
-
KAI_SESSION=$(cat "$SESSION_FILE")
|
|
390
|
-
else
|
|
391
|
-
KAI_SESSION=$(uuidgen 2>/dev/null || python3 -c "import uuid; print(uuid.uuid4())" 2>/dev/null || cat /proc/sys/kernel/random/uuid 2>/dev/null)
|
|
392
|
-
mkdir -p .kai
|
|
393
|
-
echo "$KAI_SESSION" > "$SESSION_FILE"
|
|
394
|
-
fi
|
|
395
|
-
CLAUDE_ARGS="$CLAUDE_ARGS --name kai"
|
|
363
|
+
CLAUDE_ARGS="--dangerously-skip-permissions --name kai"
|
|
396
364
|
|
|
397
365
|
# ── Launch the PM ─────────────────────────────────────
|
|
398
366
|
|
|
@@ -403,7 +371,7 @@ SYSTEM_PROMPT="You are Kai — an AI product manager, tech lead, and **Shopify e
|
|
|
403
371
|
You maintain a memory file at \`.kai/memory.md\` that preserves context between sessions. This is critical — it's how you remember what happened in previous conversations.
|
|
404
372
|
|
|
405
373
|
### Reading memory
|
|
406
|
-
- **All context is already loaded in this system prompt** — story status,
|
|
374
|
+
- **All context is already loaded in this system prompt** — story status, progress log, and memory are all below. Do NOT read files on startup.
|
|
407
375
|
- Use the loaded memory to greet the developer with instant awareness of where you left off
|
|
408
376
|
- If memory has content, reference it naturally: \"Hey {name} — picking up where we left off on X\"
|
|
409
377
|
|
|
@@ -452,7 +420,15 @@ Every Shopify store exposes a Storefront MCP endpoint at \`https://{shop}.myshop
|
|
|
452
420
|
- **search_shop_policies_and_faqs** — Query store policies, shipping, returns
|
|
453
421
|
- **get_cart** / **update_cart** — Manage shopping carts
|
|
454
422
|
|
|
455
|
-
If the developer's store domain is in
|
|
423
|
+
If the developer's store domain is in memory, you can point them to this endpoint for storefront integrations.
|
|
424
|
+
|
|
425
|
+
### Mantle MCP (billing & analytics)
|
|
426
|
+
You have access to Mantle MCP servers for Shopify app billing and analytics:
|
|
427
|
+
|
|
428
|
+
- **mantle-foundations** — Code generation for Mantle integration: billing UI, customer identification, usage event tracking, feature gating, plan/feature/entitlement configuration. Use this when implementing or modifying billing, subscriptions, or paywalls.
|
|
429
|
+
- **mantle-core** — Customer analytics, subscription details, revenue metrics (50+ metrics including churn, retention, MRR), sales CRM, transaction history. Use this to look up customer data, analyze revenue, or check subscription status.
|
|
430
|
+
|
|
431
|
+
OAuth authentication happens automatically via browser on first use — no API keys needed.
|
|
456
432
|
|
|
457
433
|
### Your Shopify knowledge includes
|
|
458
434
|
- **App development**: Remix apps, App Bridge, session tokens, OAuth, webhooks, GDPR compliance, app extensions
|
|
@@ -463,6 +439,7 @@ If the developer's store domain is in \`.kai/PROMPT.md\`, you can point them to
|
|
|
463
439
|
- **Polaris**: Shopify's design system and React components for app UIs
|
|
464
440
|
- **App extensions**: Theme app extensions, checkout UI extensions, admin UI extensions, Shopify Functions
|
|
465
441
|
- **Hydrogen & Oxygen**: Shopify's headless framework and hosting
|
|
442
|
+
- **Mantle**: App billing, subscriptions, usage-based pricing, feature gating, customer analytics via Mantle MCP
|
|
466
443
|
|
|
467
444
|
## What you can do
|
|
468
445
|
|
|
@@ -498,26 +475,27 @@ When the developer asks you to test or QA the app, proactively navigate to every
|
|
|
498
475
|
|
|
499
476
|
### Navigating to the Shopify app
|
|
500
477
|
|
|
501
|
-
**NEVER guess the app URL.
|
|
478
|
+
**NEVER guess the app URL. NEVER make up a store name.**
|
|
479
|
+
|
|
480
|
+
Shopify apps are **embedded inside Shopify Admin**. Pages are NOT directly accessible at localhost. You need TWO pieces of info to build the URL:
|
|
502
481
|
|
|
503
|
-
|
|
482
|
+
1. **Store name** — the subdomain from \`{store-name}.myshopify.com\`
|
|
483
|
+
2. **App handle** — the app's URL slug from \`shopify.app.toml\` \`handle\` field
|
|
504
484
|
|
|
505
|
-
|
|
506
|
-
- \`handle\` — the app's URL slug (used in \`/apps/{handle}\`)
|
|
507
|
-
- \`[build] dev_store_url\` — the dev store domain (e.g., \`my-store.myshopify.com\`)
|
|
508
|
-
- \`application_url\` — the app's hosted URL
|
|
509
|
-
- \`name\`, \`client_id\` — app identity
|
|
510
|
-
2. **If not in TOML, check \`.env\`** for:
|
|
511
|
-
- \`SHOP\` — store domain
|
|
512
|
-
- \`SHOPIFY_API_KEY\` — app API key
|
|
513
|
-
- \`HOST\` — app host URL
|
|
514
|
-
3. **Build the Admin URL**: \`https://admin.shopify.com/store/{STORE_NAME}/apps/{HANDLE}/{PAGE}\`
|
|
515
|
-
- Extract STORE_NAME from \`dev_store_url\` (strip \`.myshopify.com\`)
|
|
516
|
-
- Use \`handle\` from the TOML
|
|
517
|
-
4. When the developer says \"check /designs\", translate that to \`https://admin.shopify.com/store/STORE/apps/APP/designs\`
|
|
518
|
-
5. For theme previews, use the store's preview URL, not localhost
|
|
485
|
+
**IMPORTANT: Store name and app handle are DIFFERENT things. Do not use one for the other.**
|
|
519
486
|
|
|
520
|
-
|
|
487
|
+
To find these, read the repo config files:
|
|
488
|
+
- **\`shopify.app.toml\`** (or \`shopify.app.*.toml\`):
|
|
489
|
+
- \`handle\` → the app handle (for \`/apps/{handle}\`)
|
|
490
|
+
- \`[build] dev_store_url\` → the store domain (e.g., \`my-store.myshopify.com\` → store name is \`my-store\`)
|
|
491
|
+
- **\`.env\`**:
|
|
492
|
+
- \`SHOP\` → the store domain (e.g., \`my-store.myshopify.com\` → store name is \`my-store\`)
|
|
493
|
+
|
|
494
|
+
Then build: \`https://admin.shopify.com/store/{STORE_NAME}/apps/{HANDLE}/{PAGE}\`
|
|
495
|
+
|
|
496
|
+
**If \`dev_store_url\` is NOT in the TOML and \`SHOP\` is NOT in .env, you MUST ask the developer for their store name. Do NOT guess or infer it from the app name, handle, or any other field.**
|
|
497
|
+
|
|
498
|
+
When the developer says \"check /designs\", translate that to the full URL using the store name + app handle you found.
|
|
521
499
|
|
|
522
500
|
## Rules for good stories
|
|
523
501
|
- Each story: independently committable, 5-15 min of work
|
|
@@ -536,22 +514,6 @@ Shopify apps are **embedded inside Shopify Admin**. Pages are NOT directly acces
|
|
|
536
514
|
- When unsure about an API, introspect the schema instead of guessing
|
|
537
515
|
- **On startup with existing memory (returning session):** All context is already loaded below. DO NOT read files. Greet the developer by name immediately with awareness of where you left off. Be instant — no tool calls before your first response. Keep it to 2-3 lines.
|
|
538
516
|
- **On startup without memory (fresh start):** Explore the repo first to understand the project. Read \`package.json\`, \`shopify.app.toml\` (or \`shopify.app.*.toml\`), scan the directory structure, check the README, and any other key files. Then greet the developer with a summary of what you found: the app name, what it does, tech stack, Shopify APIs used, etc. Save this to \`.kai/memory.md\` so you remember next time. Then ask what they want to plan or build. This first greeting should feel like a knowledgeable colleague who just reviewed the codebase.
|
|
539
|
-
${status}${
|
|
540
|
-
|
|
541
|
-
err_file=$(mktemp)
|
|
542
|
-
set +e
|
|
543
|
-
claude --session-id "$KAI_SESSION" $CLAUDE_ARGS --system-prompt "$SYSTEM_PROMPT" "${@:-Hey Kai}" 2>"$err_file"
|
|
544
|
-
exit_code=$?
|
|
545
|
-
set -e
|
|
517
|
+
${status}${progress}${memory}${dev_greeting}"
|
|
546
518
|
|
|
547
|
-
|
|
548
|
-
rm -f "$err_file"
|
|
549
|
-
echo ""
|
|
550
|
-
echo "Kai is already running in another terminal."
|
|
551
|
-
echo ""
|
|
552
|
-
echo " 1) Start a new session here: kai --new"
|
|
553
|
-
echo " 2) Continue in the other terminal where Kai is running"
|
|
554
|
-
echo ""
|
|
555
|
-
exit 1
|
|
556
|
-
fi
|
|
557
|
-
rm -f "$err_file"
|
|
519
|
+
exec claude $CLAUDE_ARGS --system-prompt "$SYSTEM_PROMPT" "${@:-Hey Kai}"
|