@rune-kit/rune 2.1.1 → 2.2.1

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 (157) hide show
  1. package/README.md +40 -34
  2. package/compiler/__tests__/pack-split.test.js +145 -0
  3. package/compiler/adapters/antigravity.js +1 -1
  4. package/compiler/adapters/codex.js +77 -0
  5. package/compiler/adapters/cursor.js +1 -1
  6. package/compiler/adapters/generic.js +1 -1
  7. package/compiler/adapters/index.js +4 -0
  8. package/compiler/adapters/opencode.js +86 -0
  9. package/compiler/adapters/windsurf.js +1 -1
  10. package/compiler/bin/rune.js +10 -7
  11. package/compiler/doctor.js +42 -0
  12. package/compiler/emitter.js +64 -10
  13. package/compiler/parser.js +42 -3
  14. package/compiler/transformer.js +10 -6
  15. package/compiler/transforms/branding.js +1 -1
  16. package/compiler/transforms/compliance.js +40 -0
  17. package/extensions/ai-ml/PACK.md +38 -474
  18. package/extensions/ai-ml/skills/ai-agents.md +172 -0
  19. package/extensions/ai-ml/skills/code-sandbox.md +187 -0
  20. package/extensions/ai-ml/skills/deep-research.md +146 -0
  21. package/extensions/ai-ml/skills/embedding-search.md +66 -0
  22. package/extensions/ai-ml/skills/fine-tuning-guide.md +74 -0
  23. package/extensions/ai-ml/skills/llm-architect.md +125 -0
  24. package/extensions/ai-ml/skills/llm-integration.md +64 -0
  25. package/extensions/ai-ml/skills/prompt-patterns.md +72 -0
  26. package/extensions/ai-ml/skills/rag-patterns.md +66 -0
  27. package/extensions/ai-ml/skills/web-extraction.md +114 -0
  28. package/extensions/analytics/PACK.md +19 -484
  29. package/extensions/analytics/skills/ab-testing.md +72 -0
  30. package/extensions/analytics/skills/dashboard-patterns.md +83 -0
  31. package/extensions/analytics/skills/data-validation.md +68 -0
  32. package/extensions/analytics/skills/funnel-analysis.md +81 -0
  33. package/extensions/analytics/skills/sql-patterns.md +57 -0
  34. package/extensions/analytics/skills/statistical-analysis.md +79 -0
  35. package/extensions/analytics/skills/tracking-setup.md +71 -0
  36. package/extensions/backend/PACK.md +44 -618
  37. package/extensions/backend/skills/api-patterns.md +84 -0
  38. package/extensions/backend/skills/async-pipeline.md +193 -0
  39. package/extensions/backend/skills/auth-patterns.md +97 -0
  40. package/extensions/backend/skills/background-jobs.md +133 -0
  41. package/extensions/backend/skills/caching-patterns.md +108 -0
  42. package/extensions/backend/skills/cli-generation.md +133 -0
  43. package/extensions/backend/skills/database-patterns.md +87 -0
  44. package/extensions/backend/skills/middleware-patterns.md +104 -0
  45. package/extensions/chrome-ext/PACK.md +19 -921
  46. package/extensions/chrome-ext/skills/cws-preflight.md +143 -0
  47. package/extensions/chrome-ext/skills/cws-publish.md +104 -0
  48. package/extensions/chrome-ext/skills/ext-ai-integration.md +251 -0
  49. package/extensions/chrome-ext/skills/ext-messaging.md +139 -0
  50. package/extensions/chrome-ext/skills/ext-storage.md +133 -0
  51. package/extensions/chrome-ext/skills/mv3-scaffold.md +164 -0
  52. package/extensions/content/PACK.md +43 -335
  53. package/extensions/content/skills/blog-patterns.md +88 -0
  54. package/extensions/content/skills/cms-integration.md +131 -0
  55. package/extensions/content/skills/content-scoring.md +107 -0
  56. package/extensions/content/skills/i18n.md +83 -0
  57. package/extensions/content/skills/mdx-authoring.md +137 -0
  58. package/extensions/content/skills/reference.md +1014 -0
  59. package/extensions/content/skills/seo-patterns.md +67 -0
  60. package/extensions/content/skills/video-repurpose.md +153 -0
  61. package/extensions/devops/PACK.md +38 -457
  62. package/extensions/devops/skills/chaos-testing.md +67 -0
  63. package/extensions/devops/skills/ci-cd.md +75 -0
  64. package/extensions/devops/skills/docker.md +58 -0
  65. package/extensions/devops/skills/edge-serverless.md +163 -0
  66. package/extensions/devops/skills/infra-as-code.md +158 -0
  67. package/extensions/devops/skills/kubernetes.md +110 -0
  68. package/extensions/devops/skills/monitoring.md +57 -0
  69. package/extensions/devops/skills/server-setup.md +64 -0
  70. package/extensions/devops/skills/ssl-domain.md +42 -0
  71. package/extensions/ecommerce/PACK.md +62 -226
  72. package/extensions/ecommerce/skills/cart-system.md +79 -0
  73. package/extensions/ecommerce/skills/inventory-mgmt.md +102 -0
  74. package/extensions/ecommerce/skills/order-management.md +126 -0
  75. package/extensions/ecommerce/skills/payment-integration.md +472 -0
  76. package/extensions/ecommerce/skills/shopify-dev.md +69 -0
  77. package/extensions/ecommerce/skills/subscription-billing.md +93 -0
  78. package/extensions/ecommerce/skills/tax-compliance.md +117 -0
  79. package/extensions/gamedev/PACK.md +66 -317
  80. package/extensions/gamedev/skills/asset-pipeline.md +74 -0
  81. package/extensions/gamedev/skills/audio-system.md +129 -0
  82. package/extensions/gamedev/skills/camera-system.md +87 -0
  83. package/extensions/gamedev/skills/ecs.md +98 -0
  84. package/extensions/gamedev/skills/game-loops.md +72 -0
  85. package/extensions/gamedev/skills/input-system.md +199 -0
  86. package/extensions/gamedev/skills/multiplayer.md +180 -0
  87. package/extensions/gamedev/skills/particles.md +105 -0
  88. package/extensions/gamedev/skills/physics-engine.md +89 -0
  89. package/extensions/gamedev/skills/scene-management.md +146 -0
  90. package/extensions/gamedev/skills/threejs-patterns.md +90 -0
  91. package/extensions/gamedev/skills/webgl.md +71 -0
  92. package/extensions/mobile/PACK.md +56 -223
  93. package/extensions/mobile/skills/app-store-connect.md +152 -0
  94. package/extensions/mobile/skills/app-store-prep.md +66 -0
  95. package/extensions/mobile/skills/deep-linking.md +109 -0
  96. package/extensions/mobile/skills/flutter.md +60 -0
  97. package/extensions/mobile/skills/ios-build-pipeline.md +142 -0
  98. package/extensions/mobile/skills/native-bridge.md +66 -0
  99. package/extensions/mobile/skills/ota-updates.md +97 -0
  100. package/extensions/mobile/skills/push-notifications.md +111 -0
  101. package/extensions/mobile/skills/react-native.md +82 -0
  102. package/extensions/saas/PACK.md +26 -720
  103. package/extensions/saas/skills/billing-integration.md +121 -0
  104. package/extensions/saas/skills/feature-flags.md +130 -0
  105. package/extensions/saas/skills/multi-tenant.md +103 -0
  106. package/extensions/saas/skills/onboarding-flow.md +139 -0
  107. package/extensions/saas/skills/subscription-flow.md +95 -0
  108. package/extensions/saas/skills/team-management.md +144 -0
  109. package/extensions/security/PACK.md +10 -448
  110. package/extensions/security/skills/api-security.md +140 -0
  111. package/extensions/security/skills/compliance.md +68 -0
  112. package/extensions/security/skills/owasp-audit.md +64 -0
  113. package/extensions/security/skills/pentest-patterns.md +77 -0
  114. package/extensions/security/skills/secret-mgmt.md +65 -0
  115. package/extensions/security/skills/supply-chain.md +65 -0
  116. package/extensions/trading/PACK.md +18 -535
  117. package/extensions/trading/skills/chart-components.md +55 -0
  118. package/extensions/trading/skills/experiment-loop.md +125 -0
  119. package/extensions/trading/skills/fintech-patterns.md +47 -0
  120. package/extensions/trading/skills/indicator-library.md +58 -0
  121. package/extensions/trading/skills/quant-analysis.md +111 -0
  122. package/extensions/trading/skills/realtime-data.md +58 -0
  123. package/extensions/trading/skills/trade-logic.md +104 -0
  124. package/extensions/ui/PACK.md +34 -853
  125. package/extensions/ui/skills/a11y-audit.md +91 -0
  126. package/extensions/ui/skills/animation-patterns.md +106 -0
  127. package/extensions/ui/skills/component-patterns.md +75 -0
  128. package/extensions/ui/skills/design-decision.md +98 -0
  129. package/extensions/ui/skills/design-system.md +68 -0
  130. package/extensions/ui/skills/landing-patterns.md +155 -0
  131. package/extensions/ui/skills/palette-picker.md +162 -0
  132. package/extensions/ui/skills/react-health.md +90 -0
  133. package/extensions/ui/skills/type-system.md +125 -0
  134. package/extensions/ui/skills/web-vitals.md +153 -0
  135. package/extensions/zalo/PACK.md +117 -0
  136. package/extensions/zalo/skills/zalo-oa-mcp.md +317 -0
  137. package/extensions/zalo/skills/zalo-oa-messaging.md +429 -0
  138. package/extensions/zalo/skills/zalo-oa-setup.md +236 -0
  139. package/extensions/zalo/skills/zalo-oa-webhook.md +189 -0
  140. package/extensions/zalo/skills/zalo-personal-messaging.md +194 -0
  141. package/extensions/zalo/skills/zalo-personal-setup.md +153 -0
  142. package/extensions/zalo/skills/zalo-rate-guard.md +219 -0
  143. package/package.json +5 -2
  144. package/skills/brainstorm/SKILL.md +63 -1
  145. package/skills/cook/SKILL.md +89 -6
  146. package/skills/debug/SKILL.md +5 -0
  147. package/skills/fix/SKILL.md +5 -0
  148. package/skills/mcp-builder/SKILL.md +48 -1
  149. package/skills/neural-memory/SKILL.md +362 -0
  150. package/skills/plan/SKILL.md +3 -0
  151. package/skills/rescue/SKILL.md +5 -0
  152. package/skills/review/SKILL.md +44 -5
  153. package/skills/review-intake/SKILL.md +17 -1
  154. package/skills/skill-router/SKILL.md +106 -8
  155. package/skills/team/SKILL.md +24 -1
  156. package/skills/test/SKILL.md +18 -0
  157. package/skills/verification/SKILL.md +40 -1
@@ -1,242 +1,58 @@
1
1
  ---
2
2
  name: "@rune/ecommerce"
3
- description: E-commerce patterns — Shopify development, payment integration, shopping cart, and inventory management.
3
+ description: E-commerce patterns — Shopify development, payment integration, subscription billing, shopping cart, inventory management, order lifecycle, and tax compliance.
4
4
  metadata:
5
5
  author: runedev
6
- version: "0.1.0"
6
+ version: "0.3.0"
7
7
  layer: L4
8
8
  price: "$12"
9
9
  target: E-commerce developers
10
+ format: split
10
11
  ---
11
12
 
12
13
  # @rune/ecommerce
13
14
 
14
15
  ## Purpose
15
16
 
16
- E-commerce codebases fail at the seams between systems: payment intents that succeed but order records that don't get created, inventory counts that go negative during flash sales, carts that lose items when users sign in, and Shopify themes that break on metafield updates. This pack addresses the full order lifecycle — storefront to payment to fulfillment — with patterns that handle the race conditions, state machines, and distributed system problems that every commerce platform eventually hits.
17
+ E-commerce codebases fail at the seams between systems: payment intents that succeed but order records that don't get created, inventory counts that go negative during flash sales, subscription proration that charges the wrong amount mid-cycle, tax calculations that use cart-time rates instead of checkout-time rates, carts that lose items when users sign in, and webhook handlers that process the same event twice. This pack addresses the full order lifecycle — storefront to payment to fulfillment — with patterns that handle the race conditions, state machines, and distributed system problems that every commerce platform eventually hits.
17
18
 
18
19
  ## Triggers
19
20
 
20
21
  - Auto-trigger: when `shopify.app.toml`, `*.liquid`, `cart`, `checkout`, `stripe` in payment context, `inventory` schema detected
21
22
  - `/rune shopify-dev` — audit Shopify theme or app architecture
22
23
  - `/rune payment-integration` — set up or audit payment flows
24
+ - `/rune subscription-billing` — set up or audit recurring billing
23
25
  - `/rune cart-system` — build or audit cart architecture
24
26
  - `/rune inventory-mgmt` — audit inventory tracking and stock management
27
+ - `/rune order-management` — audit order lifecycle and fulfillment
28
+ - `/rune tax-compliance` — set up or audit tax calculation
25
29
  - Called by `cook` (L1) when e-commerce project detected
26
30
  - Called by `launch` (L1) when preparing storefront for production
27
31
 
28
32
  ## Skills Included
29
33
 
30
- ### shopify-dev
31
-
32
- Shopify development patterns — Liquid templates, Shopify API, Hydrogen/Remix storefronts, metafields, theme architecture.
33
-
34
- #### Workflow
35
-
36
- **Step 1 Detect Shopify architecture**
37
- Use Glob to find `shopify.app.toml`, `*.liquid`, `remix.config.*`, `hydrogen.config.*`. Use Grep to find Storefront API queries (`#graphql`), Admin API calls, and metafield references. Classify: theme app extension, custom app, or Hydrogen storefront.
38
-
39
- **Step 2 — Audit theme and API usage**
40
- Check for: Liquid templates without `| escape` filter (XSS), Storefront API queries without pagination, hardcoded product IDs, missing metafield type validation, theme sections without `schema` blocks, and deprecated API version usage.
41
-
42
- **Step 3 Emit optimized patterns**
43
- For Hydrogen: emit typed Storefront API loader with proper caching. For theme: emit section schema with metafield integration. For apps: emit webhook handler with HMAC verification.
44
-
45
- #### Example
46
-
47
- ```typescript
48
- // Hydrogen typed Storefront API loader with caching
49
- import { json, type LoaderFunctionArgs } from '@shopify/remix-oxygen';
50
-
51
- const PRODUCT_QUERY = `#graphql
52
- query Product($handle: String!) {
53
- product(handle: $handle) {
54
- id title description
55
- variants(first: 10) {
56
- nodes { id title price { amount currencyCode } availableForSale }
57
- }
58
- metafield(namespace: "custom", key: "care_instructions") { value type }
59
- }
60
- }
61
- ` as const;
62
-
63
- export async function loader({ params, context }: LoaderFunctionArgs) {
64
- const { product } = await context.storefront.query(PRODUCT_QUERY, {
65
- variables: { handle: params.handle! },
66
- cache: context.storefront.CacheLong(),
67
- });
68
- if (!product) throw new Response('Not Found', { status: 404 });
69
- return json({ product });
70
- }
71
- ```
72
-
73
- ---
74
-
75
- ### payment-integration
76
-
77
- Payment integration — Stripe Payment Intents, 3D Secure, webhook handling, refunds, PCI compliance.
78
-
79
- #### Workflow
80
-
81
- **Step 1 — Detect payment setup**
82
- Use Grep to find `stripe`, `paypal`, `@stripe/stripe-js`, payment-related endpoints. Read checkout handlers and webhook processors to understand: payment flow type, webhook events handled, and error recovery.
83
-
84
- **Step 2 — Audit payment security**
85
- Check for: missing idempotency keys on payment creation, webhook signature not verified, payment amount calculated client-side (manipulation risk), no 3D Secure handling, secret keys in client bundle, and missing failed payment recovery flow.
86
-
87
- **Step 3 — Emit robust payment flow**
88
- Emit: server-side Payment Intent creation with idempotency, 3D Secure handling, comprehensive webhook handler, and refund flow with audit trail.
89
-
90
- #### Example
91
-
92
- ```typescript
93
- // Stripe Payment Intent — server-side, idempotent, 3DS-ready
94
- import Stripe from 'stripe';
95
- const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);
96
-
97
- app.post('/api/checkout', async (req, res) => {
98
- const { cartId, paymentMethodId } = req.body;
99
- const cart = await cartService.getVerified(cartId); // server-side price calculation
100
-
101
- const intent = await stripe.paymentIntents.create({
102
- amount: cart.totalInCents, // ALWAYS server-calculated
103
- currency: cart.currency,
104
- payment_method: paymentMethodId,
105
- confirm: true,
106
- return_url: `${process.env.APP_URL}/checkout/complete`,
107
- metadata: { cartId, userId: req.user.id },
108
- idempotencyKey: `checkout-${cartId}-${Date.now()}`,
109
- });
110
-
111
- if (intent.status === 'requires_action') {
112
- return res.json({ requiresAction: true, clientSecret: intent.client_secret });
113
- }
114
- if (intent.status === 'succeeded') {
115
- await orderService.create(cart, intent.id);
116
- return res.json({ success: true, orderId: intent.metadata.orderId });
117
- }
118
- res.status(400).json({ error: { code: 'PAYMENT_FAILED', message: 'Payment could not be processed' } });
119
- });
120
- ```
121
-
122
- ---
123
-
124
- ### cart-system
125
-
126
- Shopping cart architecture — state management, persistent carts, guest checkout, coupon/discount engine, tax calculation.
127
-
128
- #### Workflow
129
-
130
- **Step 1 — Detect cart architecture**
131
- Use Grep to find cart state: `cartStore`, `useCart`, `addToCart`, `localStorage.*cart`, `session.*cart`. Read cart-related components and API routes to understand: client vs server cart, persistence strategy, and discount handling.
132
-
133
- **Step 2 — Audit cart integrity**
134
- Check for: cart total calculated client-side only (price manipulation), no cart TTL (stale carts), missing guest-to-authenticated cart merge, race conditions on concurrent cart updates, coupons validated client-side, and no stock check at add-to-cart time.
135
-
136
- **Step 3 — Emit cart patterns**
137
- Emit: server-authoritative cart with client cache, guest-to-auth merge flow, coupon validation middleware, and optimistic UI with server reconciliation.
138
-
139
- #### Example
140
-
141
- ```typescript
142
- // Server-authoritative cart with Zustand client cache
143
- import { create } from 'zustand';
144
- import { persist } from 'zustand/middleware';
145
-
146
- interface CartStore {
147
- items: CartItem[];
148
- cartId: string | null;
149
- addItem: (productId: string, variantId: string, qty: number) => Promise<void>;
150
- mergeGuestCart: (userId: string) => Promise<void>;
151
- }
152
-
153
- const useCart = create<CartStore>()(persist((set, get) => ({
154
- items: [], cartId: null,
155
-
156
- addItem: async (productId, variantId, qty) => {
157
- // Optimistic update
158
- set(state => ({ items: [...state.items, { productId, variantId, qty, pending: true }] }));
159
- // Server reconciliation (validates stock, calculates price)
160
- const cart = await fetch('/api/cart/add', {
161
- method: 'POST',
162
- body: JSON.stringify({ cartId: get().cartId, productId, variantId, qty }),
163
- }).then(r => r.json());
164
- set({ items: cart.items, cartId: cart.id }); // server is source of truth
165
- },
166
-
167
- mergeGuestCart: async (userId) => {
168
- const { cartId } = get();
169
- if (!cartId) return;
170
- const merged = await fetch('/api/cart/merge', {
171
- method: 'POST', body: JSON.stringify({ guestCartId: cartId, userId }),
172
- }).then(r => r.json());
173
- set({ items: merged.items, cartId: merged.id });
174
- },
175
- }), { name: 'cart-storage' }));
176
- ```
177
-
178
- ---
179
-
180
- ### inventory-mgmt
181
-
182
- Inventory management — stock tracking with optimistic locking, variant management, low stock alerts, backorder handling.
183
-
184
- #### Workflow
185
-
186
- **Step 1 — Detect inventory model**
187
- Use Grep to find stock-related code: `stock`, `inventory`, `quantity`, `variant`, `warehouse`, `sku`. Read schema files to understand: single vs multi-warehouse, variant structure, and reservation model.
188
-
189
- **Step 2 — Audit stock integrity**
190
- Check for: stock decremented without transaction (oversell risk), no optimistic locking on concurrent updates, inventory checked at cart-add but not at checkout (stale check), missing low-stock alerts, and no backorder handling for out-of-stock items.
191
-
192
- **Step 3 — Emit inventory patterns**
193
- Emit: atomic stock reservation with optimistic locking (version field), reservation expiry for abandoned checkouts, low-stock alert trigger, and backorder queue.
194
-
195
- #### Example
196
-
197
- ```typescript
198
- // Atomic stock reservation with optimistic locking (Prisma)
199
- async function reserveStock(variantId: string, qty: number, orderId: string) {
200
- const MAX_RETRIES = 3;
201
- for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {
202
- const variant = await prisma.variant.findUniqueOrThrow({ where: { id: variantId } });
203
-
204
- if (variant.stock < qty && !variant.allowBackorder) {
205
- throw new Error(`Insufficient stock: ${variant.stock} available, ${qty} requested`);
206
- }
207
-
208
- try {
209
- const updated = await prisma.variant.update({
210
- where: { id: variantId, version: variant.version }, // optimistic lock
211
- data: {
212
- stock: { decrement: qty },
213
- version: { increment: 1 },
214
- reservations: { create: { orderId, qty, expiresAt: addMinutes(new Date(), 15) } },
215
- },
216
- });
217
-
218
- if (updated.stock <= updated.lowStockThreshold) {
219
- await alertService.trigger('LOW_STOCK', { variantId, currentStock: updated.stock });
220
- }
221
- return updated;
222
- } catch (e) {
223
- if (attempt === MAX_RETRIES - 1) throw new Error('Stock reservation failed: concurrent modification');
224
- }
225
- }
226
- }
227
- ```
228
-
229
- ---
230
-
231
- ## Connections
232
-
233
- ```
234
- Calls → sentinel (L2): PCI compliance audit on payment code
235
- Calls → db (L2): schema design for orders, inventory, carts
236
- Called By ← cook (L1): when e-commerce project detected
237
- Called By ← launch (L1): pre-launch checkout verification
238
- Called By ← review (L2): when payment or cart code under review
239
- ```
34
+ | Skill | Model | Description |
35
+ |-------|-------|-------------|
36
+ | [shopify-dev](skills/shopify-dev.md) | sonnet | Shopify theme, Hydrogen, app architecture — Liquid templates, Storefront API, metafields, webhook HMAC verification. |
37
+ | [payment-integration](skills/payment-integration.md) | sonnet | Stripe, 3DS, webhooks, fraud detection, multi-currency, Vietnamese gateways (SePay, VNPay, MoMo). |
38
+ | [subscription-billing](skills/subscription-billing.md) | sonnet | Trials, proration, dunning, plan changes mid-cycle, usage-based billing, cancellation flows. |
39
+ | [cart-system](skills/cart-system.md) | sonnet | Persistent carts, guest-to-auth merge, server-authoritative totals, coupon engine. |
40
+ | [inventory-mgmt](skills/inventory-mgmt.md) | sonnet | Atomic stock with optimistic locking, reservations, low-stock alerts, backorder handling. |
41
+ | [order-management](skills/order-management.md) | sonnet | State machine, fulfillment, refund/return flows, reconciliation, webhook fan-out. |
42
+ | [tax-compliance](skills/tax-compliance.md) | sonnet | Tax APIs, EU VAT reverse charge, digital goods tax, audit trail per order line item. |
43
+
44
+ ## Common Workflows
45
+
46
+ | Workflow | Skills Involved | Description |
47
+ |----------|----------------|-------------|
48
+ | Full checkout | cart-system → tax-compliance → payment-integration → order-management | Complete purchase from cart to confirmation |
49
+ | Flash sale | inventory-mgmt → cart-system → payment-integration | High-concurrency stock control |
50
+ | Subscription signup | cart-system → payment-integration → subscription-billing | Free trial with payment method upfront |
51
+ | Plan upgrade | subscription-billing → payment-integration → tax-compliance | Mid-cycle upgrade with proration invoice |
52
+ | Order cancellation | order-management inventory-mgmt payment-integration | Cancel + release stock + issue refund |
53
+ | New market launch | tax-compliance payment-integration (multi-currency) → shopify-dev | Localization, VAT, FX pricing |
54
+ | Fraud review | payment-integration (fraud patterns) → order-management | Risk scoring before order fulfilment |
55
+ | Product catalog | shopify-dev → inventory-mgmt | Variant structure + stock sync |
240
56
 
241
57
  ## Tech Stack Support
242
58
 
@@ -246,35 +62,55 @@ Called By ← review (L2): when payment or cart code under review
246
62
  | Custom | Next.js 16 / SvelteKit | Stripe | Most flexible |
247
63
  | Headless | Any frontend | Stripe / PayPal | API-first commerce |
248
64
  | Medusa.js | Next.js | Stripe / PayPal | Open-source alternative |
65
+ | Saleor | React / Next.js | Stripe / Braintree | GraphQL-first |
249
66
 
250
- ## Constraints
67
+ ## Connections
251
68
 
252
- 1. MUST calculate all prices server-side — never trust client-submitted amounts for payment.
253
- 2. MUST use idempotency keys on all payment creation API calls — prevent double charges.
254
- 3. MUST use optimistic locking or database transactions for inventory updates — prevent overselling.
255
- 4. MUST verify webhook signatures before processing any payment events.
256
- 5. MUST validate coupons and discounts server-side client-side validation is bypassable.
69
+ ```
70
+ Calls sentinel (L2): PCI compliance audit on payment code, webhook security
71
+ Calls db (L2): schema design for orders, inventory, carts, subscriptions
72
+ Calls perf (L2): audit checkout page load, cart update latency
73
+ Calls verification (L3): run payment flow integration tests
74
+ Called By ← cook (L1): when e-commerce project detected
75
+ Called By ← launch (L1): pre-launch checkout verification
76
+ Called By ← review (L2): when payment or cart code under review
77
+ Called By ← ba (L2): requirements elicitation for e-commerce features
78
+ ```
257
79
 
258
80
  ## Sharp Edges
259
81
 
260
82
  | Failure Mode | Severity | Mitigation |
261
83
  |---|---|---|
262
- | Double charge from retried Payment Intent without idempotency key | CRITICAL | Always pass idempotencyKey derived from cartId; check for existing successful intent before creating new one |
84
+ | Double charge from retried Payment Intent without idempotency key | CRITICAL | Derive idempotencyKey from `cartId-v${version}`, not timestamp; check for existing succeeded intent |
85
+ | Webhook signature fails because `req.body` is parsed JSON instead of raw bytes | CRITICAL | Use `express.raw({ type: 'application/json' })` for webhook route; verify with `req.body` as Buffer |
263
86
  | Overselling during flash sale (stock goes negative) | CRITICAL | Use optimistic locking with version field; serializable isolation for high-contention items |
264
- | Webhook processes `payment_intent.succeeded` but order creation fails (payment taken, no order) | HIGH | Wrap order creation in transaction; implement reconciliation job that matches intents to orders |
87
+ | Payment succeeded but order creation fails (money taken, no order record) | HIGH | Wrap in transaction; run reconciliation job matching payment intents to orders every hour |
88
+ | Same webhook processed twice creates duplicate orders | HIGH | Store `event.id` in database; check before processing; wrap in transaction |
265
89
  | Guest cart items lost on login (separate cart created for auth user) | HIGH | Implement cart merge in auth callback; prefer server cart state over local |
266
- | Tax calculated at cart time but rate changed by checkout (wrong amount charged) | MEDIUM | Recalculate tax at payment creation time, not at cart add time |
90
+ | Subscription proration charges wrong amount on mid-cycle plan change | HIGH | Explicitly set `proration_behavior`; preview proration with `stripe.invoices.retrieveUpcoming` |
91
+ | Trial-to-paid conversion fails silently (no payment method on file) | HIGH | Require payment method at trial signup; set `missing_payment_method: 'cancel'` in trial settings |
92
+ | Tax calculated at cart time but rate changed by checkout (wrong amount charged) | MEDIUM | Recalculate tax at payment creation time using shipping address, not cart-add time |
267
93
  | Liquid template outputs unescaped metafield content (XSS in Shopify theme) | HIGH | Always use `| escape` filter on user-generated metafield values |
94
+ | Cancelled order stock not returned to inventory | MEDIUM | Use order state machine with side effects — cancellation always triggers `releaseOrderReservations` |
95
+ | Reservation never expires for abandoned checkout (stock locked forever) | MEDIUM | Run reservation expiry job every 5 minutes; default reservation TTL = 15 minutes |
96
+ | Stolen card fraud passes payment but triggers chargeback later | HIGH | Apply fraud scoring before confirmation; hold high-risk orders for manual review |
97
+ | FX rate stale on multi-currency display — user sees wrong price | MEDIUM | Cache FX rates max 15 minutes; show rate timestamp to user; always charge in store base currency |
268
98
 
269
99
  ## Done When
270
100
 
271
- - Checkout flow completes end-to-end: cart → payment → order confirmation
101
+ - Checkout flow completes end-to-end: cart → tax → payment → order confirmation
102
+ - Subscription lifecycle handles trial → active → past_due → cancelled with proper dunning
272
103
  - Inventory accurately tracks stock with no overselling under concurrent load
273
- - Webhooks are idempotent and handle all payment lifecycle events
104
+ - Order state machine enforces valid transitions with side effects (stock release, refunds, notifications)
105
+ - Webhooks are idempotent, signature-verified, and handle all payment/subscription lifecycle events
106
+ - Tax calculated at checkout with audit trail stored per order line item
274
107
  - Guest-to-authenticated cart merge works without data loss
275
- - All prices and discounts validated server-side
108
+ - All prices, discounts, and coupons validated server-side
109
+ - Reconciliation job catches payment/order mismatches
110
+ - Fraud scoring applied to all orders; high-risk orders flagged for review
111
+ - Multi-currency display works with cached FX rates; charges always in base currency
276
112
  - Structured report emitted for each skill invoked
277
113
 
278
114
  ## Cost Profile
279
115
 
280
- ~8,000–14,000 tokens per full pack run (all 4 skills). Individual skill: ~2,000–4,000 tokens. Sonnet default. Use haiku for detection scans; escalate to sonnet for payment flow and inventory pattern generation.
116
+ ~14,000–26,000 tokens per full pack run (all 7 skills). Individual skill: ~2,000–4,000 tokens. Sonnet default. Use haiku for detection scans; escalate to sonnet for payment flow, subscription lifecycle, and order state machine generation.
@@ -0,0 +1,79 @@
1
+ ---
2
+ name: "cart-system"
3
+ pack: "@rune/ecommerce"
4
+ description: "Shopping cart architecture — state management, persistent carts, guest checkout, coupon/discount engine, guest-to-auth cart merge."
5
+ model: sonnet
6
+ tools: [Read, Edit, Write, Grep, Glob, Bash]
7
+ ---
8
+
9
+ # cart-system
10
+
11
+ Shopping cart architecture — state management, persistent carts, guest checkout, coupon/discount engine, guest-to-auth cart merge.
12
+
13
+ #### Workflow
14
+
15
+ **Step 1 — Detect cart architecture**
16
+ Use Grep to find cart state: `cartStore`, `useCart`, `addToCart`, `localStorage.*cart`, `session.*cart`. Read cart-related components and API routes to understand: client vs server cart, persistence strategy, and discount handling.
17
+
18
+ **Step 2 — Audit cart integrity**
19
+ Check for:
20
+ - Cart total calculated client-side only (price manipulation — attacker changes localStorage price)
21
+ - No cart TTL (stale carts hold inventory reservations indefinitely)
22
+ - Missing guest-to-authenticated cart merge (items lost on login)
23
+ - Race conditions on concurrent cart updates (two tabs adding items, last write wins)
24
+ - Coupons validated client-side (attacker applies any discount code)
25
+ - No stock check at add-to-cart time (user adds 100 items, stock is 3)
26
+ - Cart stored in localStorage only (lost on device switch, no cross-device)
27
+
28
+ **Step 3 — Emit cart patterns**
29
+ Emit: server-authoritative cart with client cache, guest-to-auth merge flow, coupon validation middleware, and optimistic UI with server reconciliation.
30
+
31
+ #### Example
32
+
33
+ ```typescript
34
+ // Server-authoritative cart with Zustand client cache
35
+ import { create } from 'zustand';
36
+ import { persist } from 'zustand/middleware';
37
+
38
+ interface CartStore {
39
+ items: CartItem[];
40
+ cartId: string | null;
41
+ addItem: (productId: string, variantId: string, qty: number) => Promise<void>;
42
+ mergeGuestCart: (userId: string) => Promise<void>;
43
+ }
44
+
45
+ const useCart = create<CartStore>()(persist((set, get) => ({
46
+ items: [], cartId: null,
47
+
48
+ addItem: async (productId, variantId, qty) => {
49
+ // Optimistic update (show item immediately)
50
+ set(state => ({ items: [...state.items, { productId, variantId, qty, pending: true }] }));
51
+ // Server reconciliation (validates stock, calculates price, applies discounts)
52
+ const cart = await fetch('/api/cart/add', {
53
+ method: 'POST',
54
+ body: JSON.stringify({ cartId: get().cartId, productId, variantId, qty }),
55
+ }).then(r => r.json());
56
+ set({ items: cart.items, cartId: cart.id }); // server is source of truth
57
+ },
58
+
59
+ mergeGuestCart: async (userId) => {
60
+ const { cartId } = get();
61
+ if (!cartId) return;
62
+ const merged = await fetch('/api/cart/merge', {
63
+ method: 'POST', body: JSON.stringify({ guestCartId: cartId, userId }),
64
+ }).then(r => r.json());
65
+ set({ items: merged.items, cartId: merged.id });
66
+ },
67
+ }), { name: 'cart-storage' }));
68
+
69
+ // Server — coupon validation (NEVER trust client)
70
+ app.post('/api/cart/apply-coupon', async (req, res) => {
71
+ const { cartId, code } = req.body;
72
+ const coupon = await couponService.validate(code); // checks: exists, not expired, usage limit
73
+ if (!coupon) return res.status(400).json({ error: 'INVALID_COUPON' });
74
+
75
+ const cart = await cartService.applyCoupon(cartId, coupon);
76
+ // Recalculate totals server-side after discount
77
+ res.json({ cart: cartService.calculateTotals(cart) });
78
+ });
79
+ ```
@@ -0,0 +1,102 @@
1
+ ---
2
+ name: "inventory-mgmt"
3
+ pack: "@rune/ecommerce"
4
+ description: "Inventory management — stock tracking with optimistic locking, variant management, low stock alerts, backorder handling, reservation expiry."
5
+ model: sonnet
6
+ tools: [Read, Edit, Write, Grep, Glob, Bash]
7
+ ---
8
+
9
+ # inventory-mgmt
10
+
11
+ Inventory management — stock tracking with optimistic locking, variant management, low stock alerts, backorder handling, reservation expiry.
12
+
13
+ #### Workflow
14
+
15
+ **Step 1 — Detect inventory model**
16
+ Use Grep to find stock-related code: `stock`, `inventory`, `quantity`, `variant`, `warehouse`, `sku`. Read schema files to understand: single vs multi-warehouse, variant structure, and reservation model.
17
+
18
+ **Step 2 — Audit stock integrity**
19
+ Check for:
20
+ - Stock decremented without transaction (oversell risk under concurrent load)
21
+ - No optimistic locking on concurrent updates (version field or `FOR UPDATE` lock)
22
+ - Inventory checked at cart-add but not at checkout (stale check — stock sold out between add and pay)
23
+ - Missing low-stock alerts (ops team discovers stockout from customer complaints)
24
+ - No reservation expiry for abandoned checkouts (stock locked forever)
25
+ - No backorder handling for out-of-stock items (zero stock = hard error vs queue)
26
+ - Flash sale race condition: 10 users checkout simultaneously with 3 items left = 7 oversold orders
27
+
28
+ **Step 3 — Emit inventory patterns**
29
+ Emit: atomic stock reservation with optimistic locking (version field), reservation expiry job for abandoned checkouts, low-stock alert trigger, and backorder queue.
30
+
31
+ #### Example
32
+
33
+ ```typescript
34
+ // Atomic stock reservation with optimistic locking (Prisma)
35
+ async function reserveStock(variantId: string, qty: number, orderId: string) {
36
+ const MAX_RETRIES = 3;
37
+ for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {
38
+ const variant = await prisma.variant.findUniqueOrThrow({ where: { id: variantId } });
39
+
40
+ if (variant.stock < qty && !variant.allowBackorder) {
41
+ throw new Error(`Insufficient stock: ${variant.stock} available, ${qty} requested`);
42
+ }
43
+
44
+ try {
45
+ const updated = await prisma.variant.update({
46
+ where: { id: variantId, version: variant.version }, // optimistic lock
47
+ data: {
48
+ stock: { decrement: qty },
49
+ version: { increment: 1 },
50
+ reservations: { create: { orderId, qty, expiresAt: addMinutes(new Date(), 15) } },
51
+ },
52
+ });
53
+
54
+ if (updated.stock <= updated.lowStockThreshold) {
55
+ await alertService.trigger('LOW_STOCK', { variantId, currentStock: updated.stock });
56
+ }
57
+ return updated;
58
+ } catch (e) {
59
+ if (attempt === MAX_RETRIES - 1) throw new Error('Stock reservation failed: concurrent modification');
60
+ }
61
+ }
62
+ }
63
+
64
+ // Reservation expiry job — release stock from abandoned checkouts
65
+ async function releaseExpiredReservations() {
66
+ const expired = await prisma.reservation.findMany({
67
+ where: { expiresAt: { lt: new Date() }, status: 'PENDING' },
68
+ });
69
+
70
+ for (const reservation of expired) {
71
+ await prisma.$transaction([
72
+ prisma.variant.update({
73
+ where: { id: reservation.variantId },
74
+ data: { stock: { increment: reservation.qty } },
75
+ }),
76
+ prisma.reservation.update({
77
+ where: { id: reservation.id },
78
+ data: { status: 'EXPIRED' },
79
+ }),
80
+ ]);
81
+ }
82
+ }
83
+
84
+ // Inventory webhook — push stock changes to external systems (3PL, ERP)
85
+ async function emitInventoryWebhook(variantId: string, newStock: number, event: string) {
86
+ const variant = await prisma.variant.findUniqueOrThrow({
87
+ where: { id: variantId },
88
+ include: { product: true },
89
+ });
90
+ const payload = {
91
+ event, // 'STOCK_UPDATED' | 'LOW_STOCK' | 'OUT_OF_STOCK'
92
+ sku: variant.sku,
93
+ variantId,
94
+ productId: variant.productId,
95
+ stock: newStock,
96
+ threshold: variant.lowStockThreshold,
97
+ timestamp: new Date().toISOString(),
98
+ };
99
+ // Fan-out to all registered webhook endpoints
100
+ await webhookFanOut(payload, 'inventory.*');
101
+ }
102
+ ```
@@ -0,0 +1,126 @@
1
+ ---
2
+ name: "order-management"
3
+ pack: "@rune/ecommerce"
4
+ description: "Order lifecycle — state machine, fulfillment workflows, refund/return flows, email notifications, reconciliation, webhook fan-out."
5
+ model: sonnet
6
+ tools: [Read, Edit, Write, Grep, Glob, Bash]
7
+ ---
8
+
9
+ # order-management
10
+
11
+ Order lifecycle — state machine, fulfillment workflows, refund/return flows, email notifications, reconciliation, webhook fan-out.
12
+
13
+ #### Workflow
14
+
15
+ **Step 1 — Detect order model**
16
+ Use Grep to find: `order`, `fulfillment`, `shipment`, `refund`, `return`, `order_status`, `OrderStatus`. Read schema to understand: order states, fulfillment model (self-ship, 3PL, dropship), and refund handling.
17
+
18
+ **Step 2 — Audit order lifecycle**
19
+ Check for:
20
+ - No explicit state machine: order status updated with raw string assignment (typos, invalid transitions)
21
+ - Missing reconciliation: payment succeeded but order creation failed (payment taken, no order)
22
+ - Partial fulfillment not handled: multi-item order with one item backordered
23
+ - Refund without inventory return: money refunded but stock not incremented back
24
+ - No email notifications on state transitions (customer has no visibility)
25
+ - Cancellation after partial fulfillment: must refund only unfulfilled items
26
+
27
+ **Step 3 — Emit order patterns**
28
+ Emit: typed state machine with valid transitions, reconciliation job, partial fulfillment handler, and refund flow with inventory return.
29
+
30
+ #### Example
31
+
32
+ ```typescript
33
+ // Order state machine with valid transitions
34
+ type OrderStatus = 'pending' | 'confirmed' | 'processing' | 'partially_shipped' |
35
+ 'shipped' | 'delivered' | 'cancelled' | 'refunded';
36
+
37
+ const VALID_TRANSITIONS: Record<OrderStatus, OrderStatus[]> = {
38
+ pending: ['confirmed', 'cancelled'],
39
+ confirmed: ['processing', 'cancelled'],
40
+ processing: ['partially_shipped', 'shipped', 'cancelled'],
41
+ partially_shipped: ['shipped', 'cancelled'],
42
+ shipped: ['delivered', 'refunded'],
43
+ delivered: ['refunded'],
44
+ cancelled: [],
45
+ refunded: [],
46
+ };
47
+
48
+ async function transitionOrder(orderId: string, newStatus: OrderStatus) {
49
+ const order = await prisma.order.findUniqueOrThrow({ where: { id: orderId } });
50
+ const currentStatus = order.status as OrderStatus;
51
+
52
+ if (!VALID_TRANSITIONS[currentStatus]?.includes(newStatus)) {
53
+ throw new Error(`Invalid transition: ${currentStatus} → ${newStatus}`);
54
+ }
55
+
56
+ const updated = await prisma.$transaction(async (tx) => {
57
+ const result = await tx.order.update({
58
+ where: { id: orderId },
59
+ data: {
60
+ status: newStatus,
61
+ statusHistory: { push: { from: currentStatus, to: newStatus, at: new Date() } },
62
+ },
63
+ });
64
+
65
+ // Side effects per transition
66
+ if (newStatus === 'cancelled') {
67
+ await releaseOrderReservations(tx, orderId);
68
+ }
69
+ if (newStatus === 'refunded') {
70
+ await processRefund(tx, orderId);
71
+ await returnInventory(tx, orderId);
72
+ }
73
+
74
+ return result;
75
+ });
76
+
77
+ // Notifications (outside transaction — don't block on email)
78
+ await notificationService.orderStatusChanged(updated);
79
+ return updated;
80
+ }
81
+
82
+ // Reconciliation job — find payments without orders
83
+ async function reconcilePayments() {
84
+ const recentIntents = await stripe.paymentIntents.list({
85
+ created: { gte: Math.floor(Date.now() / 1000) - 3600 }, // last hour
86
+ limit: 100,
87
+ });
88
+
89
+ for (const intent of recentIntents.data) {
90
+ if (intent.status !== 'succeeded') continue;
91
+ const cartId = intent.metadata.cartId;
92
+ const order = await prisma.order.findFirst({ where: { paymentIntentId: intent.id } });
93
+
94
+ if (!order) {
95
+ // Payment succeeded but order not created — create it now
96
+ await orderService.createFromIntent(intent);
97
+ await alertService.trigger('RECONCILED_ORDER', { intentId: intent.id, cartId });
98
+ }
99
+ }
100
+ }
101
+
102
+ // Webhook fan-out for order status changes — notify 3PLs, ERPs, analytics
103
+ async function webhookFanOut(payload: Record<string, unknown>, topic: string) {
104
+ const endpoints = await db.webhookEndpoint.findMany({
105
+ where: { topics: { has: topic }, active: true },
106
+ });
107
+ await Promise.allSettled(
108
+ endpoints.map(ep =>
109
+ fetch(ep.url, {
110
+ method: 'POST',
111
+ headers: {
112
+ 'Content-Type': 'application/json',
113
+ 'X-Rune-Signature': signPayload(payload, ep.secret),
114
+ 'X-Rune-Topic': topic,
115
+ 'X-Rune-Timestamp': String(Date.now()),
116
+ },
117
+ body: JSON.stringify(payload),
118
+ signal: AbortSignal.timeout(5000),
119
+ }).catch(err => {
120
+ // Log failure but don't throw — one bad endpoint shouldn't block others
121
+ console.error(`Webhook delivery failed for ${ep.url}:`, err.message);
122
+ })
123
+ )
124
+ );
125
+ }
126
+ ```