@kraftapps-ai/kai 1.5.4 → 1.6.2

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 +78 -65
  2. package/package.json +1 -1
package/kai CHANGED
@@ -17,7 +17,6 @@ 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
21
  SESSION_FILE=".kai/session_id"
23
22
  LOOP_SCRIPT=".kai/loop.sh"
@@ -61,36 +60,6 @@ if [ ! -f "$PRD_FILE" ]; then
61
60
  EOF
62
61
 
63
62
  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
63
  fi
95
64
 
96
65
  # Init memory file if it doesn't exist
@@ -121,6 +90,7 @@ fi
121
90
  # Track what's already configured
122
91
  playwright_available=false
123
92
  shopify_dev_available=false
93
+ mantle_available=false
124
94
 
125
95
  for config in \
126
96
  ".mcp.json" \
@@ -130,6 +100,7 @@ for config in \
130
100
  if [ -f "$config" ]; then
131
101
  grep -q "playwright" "$config" 2>/dev/null && playwright_available=true
132
102
  grep -q "shopify-dev" "$config" 2>/dev/null && shopify_dev_available=true
103
+ grep -q "mantle" "$config" 2>/dev/null && mantle_available=true
133
104
  fi
134
105
  done
135
106
 
@@ -145,7 +116,7 @@ fi
145
116
 
146
117
  # Build MCP config with all needed servers
147
118
  needs_mcp_update=false
148
- if [ "$playwright_available" = false ] || [ "$shopify_dev_available" = false ]; then
119
+ if [ "$playwright_available" = false ] || [ "$shopify_dev_available" = false ] || [ "$mantle_available" = false ]; then
149
120
  needs_mcp_update=true
150
121
  fi
151
122
 
@@ -164,11 +135,18 @@ if [ "$needs_mcp_update" = true ]; then
164
135
  mcp_config=$(echo "$mcp_config" | jq '.mcpServers["shopify-dev-mcp"] = {"command": "npx", "args": ["-y", "@shopify/dev-mcp@latest"]}')
165
136
  fi
166
137
 
138
+ if [ "$mantle_available" = false ] && ! echo "$mcp_config" | grep -q "mantle"; then
139
+ echo "Setting up Mantle MCP (billing, subscriptions, analytics)..."
140
+ mcp_config=$(echo "$mcp_config" | jq '.mcpServers["mantle-foundations"] = {"url": "https://mcp.heymantle.com/foundations"}')
141
+ mcp_config=$(echo "$mcp_config" | jq '.mcpServers["mantle-core"] = {"url": "https://mcp.heymantle.com/core"}')
142
+ fi
143
+
167
144
  echo "$mcp_config" > .mcp.json
168
145
  else
169
146
  echo "Setting up MCP servers..."
170
147
  echo " - Playwright (browser testing)"
171
148
  echo " - Shopify Dev MCP (docs, GraphQL schemas, Liquid validation)"
149
+ echo " - Mantle MCP (billing, subscriptions, analytics)"
172
150
 
173
151
  cat > .mcp.json << 'MCPEOF'
174
152
  {
@@ -180,6 +158,12 @@ if [ "$needs_mcp_update" = true ]; then
180
158
  "shopify-dev-mcp": {
181
159
  "command": "npx",
182
160
  "args": ["-y", "@shopify/dev-mcp@latest"]
161
+ },
162
+ "mantle-foundations": {
163
+ "url": "https://mcp.heymantle.com/foundations"
164
+ },
165
+ "mantle-core": {
166
+ "url": "https://mcp.heymantle.com/core"
183
167
  }
184
168
  }
185
169
  }
@@ -197,7 +181,6 @@ set -e
197
181
 
198
182
  PRD_FILE=".kai/stories.json"
199
183
  PROGRESS_FILE=".kai/progress.txt"
200
- PROMPT_FILE=".kai/PROMPT.md"
201
184
 
202
185
  WORKER_PROMPT='You are an autonomous AI developer specializing in Shopify app and theme development.
203
186
 
@@ -255,7 +238,7 @@ You are an expert Shopify developer. You have access to the Shopify Dev MCP tool
255
238
  | "Skip review" | Simple code has bugs. | Always self-review. |
256
239
  | "I know the API" | APIs change. Schema is truth. | Introspect first. |'
257
240
 
258
- context_files="@${PROMPT_FILE} @${PRD_FILE} @${PROGRESS_FILE}"
241
+ context_files="@${PRD_FILE} @${PROGRESS_FILE}"
259
242
  if [ -f ".kai/context.txt" ]; then
260
243
  while IFS= read -r file; do
261
244
  [ -n "$file" ] && [ -f "$file" ] && context_files="$context_files @${file}"
@@ -357,23 +340,25 @@ $(jq -r '.userStories[] | "- [\(if .passes then "DONE" else "TODO" end)] #\(.id)
357
340
  fi
358
341
  fi
359
342
 
360
- project_context=""
361
- [ -f "$PROMPT_FILE" ] && project_context="
362
-
363
- Project context (.kai/PROMPT.md):
364
- $(cat "$PROMPT_FILE")"
365
-
366
343
  progress=""
367
- [ -f "$PROGRESS_FILE" ] && [ "$(wc -l < "$PROGRESS_FILE")" -gt 2 ] && progress="
344
+ if [ -f "$PROGRESS_FILE" ] && [ "$(wc -l < "$PROGRESS_FILE")" -gt 2 ]; then
345
+ progress="
368
346
 
369
347
  Recent progress (.kai/progress.txt):
370
- $(tail -30 "$PROGRESS_FILE")"
348
+ $(tail -15 "$PROGRESS_FILE")"
349
+ fi
371
350
 
351
+ # Only inject memory if it has real content (not just the default template)
372
352
  memory=""
373
- [ -f "$MEMORY_FILE" ] && memory="
353
+ if [ -f "$MEMORY_FILE" ]; then
354
+ stripped_mem=$(sed 's/<!--.*-->//g' "$MEMORY_FILE" | sed '/^$/N;/^\n$/d')
355
+ if echo "$stripped_mem" | grep -qvE '^(#|$)'; then
356
+ memory="
374
357
 
375
358
  ## Kai Memory (from previous sessions)
376
359
  $(cat "$MEMORY_FILE")"
360
+ fi
361
+ fi
377
362
 
378
363
  dev_name=$(git config user.name 2>/dev/null || echo "")
379
364
  dev_greeting=""
@@ -392,18 +377,18 @@ else
392
377
  mkdir -p .kai
393
378
  echo "$KAI_SESSION" > "$SESSION_FILE"
394
379
  fi
395
- CLAUDE_ARGS="$CLAUDE_ARGS --session-id $KAI_SESSION --name kai"
380
+ CLAUDE_ARGS="$CLAUDE_ARGS --name kai"
396
381
 
397
382
  # ── Launch the PM ─────────────────────────────────────
398
383
 
399
- exec claude $CLAUDE_ARGS --system-prompt "You are Kai — an AI product manager, tech lead, and **Shopify expert**. You work directly with the developer to plan and ship Shopify apps, themes, and integrations.
384
+ SYSTEM_PROMPT="You are Kai — an AI product manager, tech lead, and **Shopify expert**. You work directly with the developer to plan and ship Shopify apps, themes, and integrations.
400
385
 
401
386
  ## Session persistence
402
387
 
403
388
  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
389
 
405
390
  ### Reading memory
406
- - **All context is already loaded in this system prompt** — story status, project context, progress log, and memory are all below. Do NOT read files on startup.
391
+ - **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
392
  - Use the loaded memory to greet the developer with instant awareness of where you left off
408
393
  - If memory has content, reference it naturally: \"Hey {name} — picking up where we left off on X\"
409
394
 
@@ -452,7 +437,15 @@ Every Shopify store exposes a Storefront MCP endpoint at \`https://{shop}.myshop
452
437
  - **search_shop_policies_and_faqs** — Query store policies, shipping, returns
453
438
  - **get_cart** / **update_cart** — Manage shopping carts
454
439
 
455
- If the developer's store domain is in \`.kai/PROMPT.md\`, you can point them to this endpoint for storefront integrations.
440
+ If the developer's store domain is in memory, you can point them to this endpoint for storefront integrations.
441
+
442
+ ### Mantle MCP (billing & analytics)
443
+ You have access to Mantle MCP servers for Shopify app billing and analytics:
444
+
445
+ - **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.
446
+ - **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.
447
+
448
+ OAuth authentication happens automatically via browser on first use — no API keys needed.
456
449
 
457
450
  ### Your Shopify knowledge includes
458
451
  - **App development**: Remix apps, App Bridge, session tokens, OAuth, webhooks, GDPR compliance, app extensions
@@ -463,6 +456,7 @@ If the developer's store domain is in \`.kai/PROMPT.md\`, you can point them to
463
456
  - **Polaris**: Shopify's design system and React components for app UIs
464
457
  - **App extensions**: Theme app extensions, checkout UI extensions, admin UI extensions, Shopify Functions
465
458
  - **Hydrogen & Oxygen**: Shopify's headless framework and hosting
459
+ - **Mantle**: App billing, subscriptions, usage-based pricing, feature gating, customer analytics via Mantle MCP
466
460
 
467
461
  ## What you can do
468
462
 
@@ -498,26 +492,27 @@ When the developer asks you to test or QA the app, proactively navigate to every
498
492
 
499
493
  ### Navigating to the Shopify app
500
494
 
501
- **NEVER guess the app URL. Auto-detect it from the repo.**
495
+ **NEVER guess the app URL. NEVER make up a store name.**
496
+
497
+ Shopify apps are **embedded inside Shopify Admin**. Pages are NOT directly accessible at localhost. You need TWO pieces of info to build the URL:
498
+
499
+ 1. **Store name** — the subdomain from \`{store-name}.myshopify.com\`
500
+ 2. **App handle** — the app's URL slug from \`shopify.app.toml\` \`handle\` field
501
+
502
+ **IMPORTANT: Store name and app handle are DIFFERENT things. Do not use one for the other.**
502
503
 
503
- Shopify apps are **embedded inside Shopify Admin**. Pages are NOT directly accessible at localhost. Before navigating, you MUST read the repo config files to build the correct URL:
504
+ To find these, read the repo config files:
505
+ - **\`shopify.app.toml\`** (or \`shopify.app.*.toml\`):
506
+ - \`handle\` → the app handle (for \`/apps/{handle}\`)
507
+ - \`[build] dev_store_url\` → the store domain (e.g., \`my-store.myshopify.com\` → store name is \`my-store\`)
508
+ - **\`.env\`**:
509
+ - \`SHOP\` → the store domain (e.g., \`my-store.myshopify.com\` → store name is \`my-store\`)
504
510
 
505
- 1. **Read \`shopify.app.toml\`** (or \`shopify.app.*.toml\`) to get:
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
511
+ Then build: \`https://admin.shopify.com/store/{STORE_NAME}/apps/{HANDLE}/{PAGE}\`
519
512
 
520
- **Do NOT ask the developer for store info if it can be found in these files. Only ask as a last resort if none of the config files exist.**
513
+ **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.**
514
+
515
+ When the developer says \"check /designs\", translate that to the full URL using the store name + app handle you found.
521
516
 
522
517
  ## Rules for good stories
523
518
  - Each story: independently committable, 5-15 min of work
@@ -536,4 +531,22 @@ Shopify apps are **embedded inside Shopify Admin**. Pages are NOT directly acces
536
531
  - When unsure about an API, introspect the schema instead of guessing
537
532
  - **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
533
  - **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}${project_context}${progress}${memory}${dev_greeting}" "${@:-Hey Kai}"
534
+ ${status}${progress}${memory}${dev_greeting}"
535
+
536
+ err_file=$(mktemp)
537
+ set +e
538
+ claude --session-id "$KAI_SESSION" $CLAUDE_ARGS --system-prompt "$SYSTEM_PROMPT" "${@:-Hey Kai}" 2>"$err_file"
539
+ exit_code=$?
540
+ set -e
541
+
542
+ if [ $exit_code -ne 0 ] && grep -qi "already in use" "$err_file" 2>/dev/null; then
543
+ rm -f "$err_file"
544
+ echo ""
545
+ echo "Kai is already running in another terminal."
546
+ echo ""
547
+ echo " 1) Start a new session here: kai --new"
548
+ echo " 2) Continue in the other terminal where Kai is running"
549
+ echo ""
550
+ exit 1
551
+ fi
552
+ rm -f "$err_file"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kraftapps-ai/kai",
3
- "version": "1.5.4",
3
+ "version": "1.6.2",
4
4
  "description": "Autonomous AI developer loop for Claude Code",
5
5
  "bin": {
6
6
  "kai": "kai"