@noodleseed/agent-kit 0.13.0 → 0.15.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/README.md +3 -3
- package/manifest.json +575 -5
- package/package.json +1 -1
- package/skills/claude-code/SKILL.md +7 -2
- package/skills/claude-code/examples/acme-bistro/README.md +51 -0
- package/skills/claude-code/examples/acme-bistro/design/UX-Document.md +435 -0
- package/skills/claude-code/examples/acme-bistro/design/api-contract.md +161 -0
- package/skills/claude-code/examples/acme-bistro/design/wireframe.html +573 -0
- package/skills/claude-code/examples/acme-bistro/noodle.json +5 -0
- package/skills/claude-code/examples/acme-bistro/package.json +20 -0
- package/skills/claude-code/examples/acme-bistro/src/helpers.ts +7 -0
- package/skills/claude-code/examples/acme-bistro/src/server.ts +149 -0
- package/skills/claude-code/examples/acme-bistro/src/views/menu-cart.tsx +159 -0
- package/skills/claude-code/examples/acme-bistro/src/views/widget-style.css +228 -0
- package/skills/claude-code/examples/acme-bistro/test/server.test.ts +21 -0
- package/skills/claude-code/examples/acme-bistro/vitest.config.ts +7 -0
- package/skills/claude-code/examples/acme-discovery/README.md +85 -0
- package/skills/claude-code/examples/acme-discovery/design/UX-Document.md +441 -0
- package/skills/claude-code/examples/acme-discovery/design/wireframe.html +670 -0
- package/skills/claude-code/examples/acme-discovery/noodle.json +5 -0
- package/skills/claude-code/examples/acme-discovery/package.json +20 -0
- package/skills/claude-code/examples/acme-discovery/src/helpers.ts +7 -0
- package/skills/claude-code/examples/acme-discovery/src/server.ts +202 -0
- package/skills/claude-code/examples/acme-discovery/src/views/discovery-carousel.tsx +155 -0
- package/skills/claude-code/examples/acme-discovery/src/views/widget-style.css +207 -0
- package/skills/claude-code/examples/acme-discovery/test/server.test.ts +24 -0
- package/skills/claude-code/examples/acme-discovery/vitest.config.ts +7 -0
- package/skills/claude-code/examples/acme-tasks/README.md +80 -0
- package/skills/claude-code/examples/acme-tasks/design/UX-Document.md +277 -0
- package/skills/claude-code/examples/acme-tasks/design/wireframe.html +603 -0
- package/skills/claude-code/examples/acme-tasks/noodle.json +5 -0
- package/skills/claude-code/examples/acme-tasks/package.json +20 -0
- package/skills/claude-code/examples/acme-tasks/src/helpers.ts +6 -0
- package/skills/claude-code/examples/acme-tasks/src/server.ts +141 -0
- package/skills/claude-code/examples/acme-tasks/src/views/task-list.tsx +177 -0
- package/skills/claude-code/examples/acme-tasks/src/views/widget-style.css +227 -0
- package/skills/claude-code/examples/acme-tasks/test/server.test.ts +22 -0
- package/skills/claude-code/examples/acme-tasks/vitest.config.ts +7 -0
- package/skills/claude-code/examples/food-ordering/README.md +82 -0
- package/skills/claude-code/examples/food-ordering/noodle.json +5 -0
- package/skills/claude-code/examples/food-ordering/package.json +22 -0
- package/skills/claude-code/examples/food-ordering/src/helpers.ts +34 -0
- package/skills/claude-code/examples/food-ordering/src/server.ts +412 -0
- package/skills/claude-code/examples/food-ordering/src/views/capabilities-card.tsx +155 -0
- package/skills/claude-code/examples/food-ordering/src/views/ordering-flow.tsx +659 -0
- package/skills/claude-code/examples/food-ordering/src/views/widget-style.css +682 -0
- package/skills/claude-code/examples/food-ordering/test/server.test.ts +58 -0
- package/skills/claude-code/examples/food-ordering/vitest.config.ts +30 -0
- package/skills/claude-code/examples/hello/README.md +13 -0
- package/skills/claude-code/examples/hello/noodle.json +5 -0
- package/skills/claude-code/examples/hello/package.json +16 -0
- package/skills/claude-code/examples/hello/src/server.ts +29 -0
- package/skills/claude-code/examples/hello/test/server.test.ts +8 -0
- package/skills/claude-code/examples/weather/README.md +54 -0
- package/skills/claude-code/examples/weather/noodle.json +4 -0
- package/skills/claude-code/examples/weather/package.json +16 -0
- package/skills/claude-code/examples/weather/src/server.ts +190 -0
- package/skills/claude-code/examples/weather/test/server.test.ts +8 -0
- package/skills/claude-code/references/chatgpt-compliance.md +63 -0
- package/skills/claude-code/references/connect-an-api.md +76 -0
- package/skills/claude-code/references/examples.md +16 -4
- package/skills/claude-code/references/experience-design.md +142 -0
- package/skills/codex/SKILL.md +7 -2
- package/skills/codex/examples/acme-bistro/README.md +51 -0
- package/skills/codex/examples/acme-bistro/design/UX-Document.md +435 -0
- package/skills/codex/examples/acme-bistro/design/api-contract.md +161 -0
- package/skills/codex/examples/acme-bistro/design/wireframe.html +573 -0
- package/skills/codex/examples/acme-bistro/noodle.json +5 -0
- package/skills/codex/examples/acme-bistro/package.json +20 -0
- package/skills/codex/examples/acme-bistro/src/helpers.ts +7 -0
- package/skills/codex/examples/acme-bistro/src/server.ts +149 -0
- package/skills/codex/examples/acme-bistro/src/views/menu-cart.tsx +159 -0
- package/skills/codex/examples/acme-bistro/src/views/widget-style.css +228 -0
- package/skills/codex/examples/acme-bistro/test/server.test.ts +21 -0
- package/skills/codex/examples/acme-bistro/vitest.config.ts +7 -0
- package/skills/codex/examples/acme-discovery/README.md +85 -0
- package/skills/codex/examples/acme-discovery/design/UX-Document.md +441 -0
- package/skills/codex/examples/acme-discovery/design/wireframe.html +670 -0
- package/skills/codex/examples/acme-discovery/noodle.json +5 -0
- package/skills/codex/examples/acme-discovery/package.json +20 -0
- package/skills/codex/examples/acme-discovery/src/helpers.ts +7 -0
- package/skills/codex/examples/acme-discovery/src/server.ts +202 -0
- package/skills/codex/examples/acme-discovery/src/views/discovery-carousel.tsx +155 -0
- package/skills/codex/examples/acme-discovery/src/views/widget-style.css +207 -0
- package/skills/codex/examples/acme-discovery/test/server.test.ts +24 -0
- package/skills/codex/examples/acme-discovery/vitest.config.ts +7 -0
- package/skills/codex/examples/acme-tasks/README.md +80 -0
- package/skills/codex/examples/acme-tasks/design/UX-Document.md +277 -0
- package/skills/codex/examples/acme-tasks/design/wireframe.html +603 -0
- package/skills/codex/examples/acme-tasks/noodle.json +5 -0
- package/skills/codex/examples/acme-tasks/package.json +20 -0
- package/skills/codex/examples/acme-tasks/src/helpers.ts +6 -0
- package/skills/codex/examples/acme-tasks/src/server.ts +141 -0
- package/skills/codex/examples/acme-tasks/src/views/task-list.tsx +177 -0
- package/skills/codex/examples/acme-tasks/src/views/widget-style.css +227 -0
- package/skills/codex/examples/acme-tasks/test/server.test.ts +22 -0
- package/skills/codex/examples/acme-tasks/vitest.config.ts +7 -0
- package/skills/codex/examples/food-ordering/README.md +82 -0
- package/skills/codex/examples/food-ordering/noodle.json +5 -0
- package/skills/codex/examples/food-ordering/package.json +22 -0
- package/skills/codex/examples/food-ordering/src/helpers.ts +34 -0
- package/skills/codex/examples/food-ordering/src/server.ts +412 -0
- package/skills/codex/examples/food-ordering/src/views/capabilities-card.tsx +155 -0
- package/skills/codex/examples/food-ordering/src/views/ordering-flow.tsx +659 -0
- package/skills/codex/examples/food-ordering/src/views/widget-style.css +682 -0
- package/skills/codex/examples/food-ordering/test/server.test.ts +58 -0
- package/skills/codex/examples/food-ordering/vitest.config.ts +30 -0
- package/skills/codex/examples/hello/README.md +13 -0
- package/skills/codex/examples/hello/noodle.json +5 -0
- package/skills/codex/examples/hello/package.json +16 -0
- package/skills/codex/examples/hello/src/server.ts +29 -0
- package/skills/codex/examples/hello/test/server.test.ts +8 -0
- package/skills/codex/examples/weather/README.md +54 -0
- package/skills/codex/examples/weather/noodle.json +4 -0
- package/skills/codex/examples/weather/package.json +16 -0
- package/skills/codex/examples/weather/src/server.ts +190 -0
- package/skills/codex/examples/weather/test/server.test.ts +8 -0
- package/skills/codex/references/chatgpt-compliance.md +63 -0
- package/skills/codex/references/connect-an-api.md +76 -0
- package/skills/codex/references/examples.md +16 -4
- package/skills/codex/references/experience-design.md +142 -0
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# Acme Bistro — Recommended API Shapes
|
|
2
|
+
|
|
3
|
+
**For Acme Bistro Engineering.** Concrete request/response JSON for each tool the ChatGPT App calls, so your backend can implement exactly what the app needs. These are a starting point for the contract, not a final spec — field names and envelopes can shift to match Acme's platform conventions, as long as the semantics below are preserved.
|
|
4
|
+
|
|
5
|
+
> **The backend owns pricing, inventory, and payment.** The widget sums line items for *display only*; the amount that reaches checkout is recomputed and enforced by Acme at `pay.acme.example`. The MCP server never sees a card number, a CVV, or a stored payment method — payment is the single off-app step. Keep pricing, availability, and the signed checkout link server-side.
|
|
6
|
+
|
|
7
|
+
The app maps to four tools:
|
|
8
|
+
|
|
9
|
+
| Tool | Kind | Job |
|
|
10
|
+
|------|------|-----|
|
|
11
|
+
| `show_menu` | `toolWithWidget` (read-only) | Return the menu + render the `MenuCart` widget |
|
|
12
|
+
| `add_to_cart` | `toolForWidget` (local write) | Reflect a natural-language addition into the visible cart |
|
|
13
|
+
| `remove_from_cart` | `toolForWidget` (local write) | Remove one unit of an item |
|
|
14
|
+
| `create_checkout` | model-visible `tool` (open-link) | Mint the signed, expiring payment link |
|
|
15
|
+
|
|
16
|
+
Menu item IDs are the stable enum: `stone_pizza`, `roast_bowl`, `house_salad`, `lemon_tart`, `sparkling`.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## 1. `show_menu` — menu + widget
|
|
21
|
+
|
|
22
|
+
The one read. Returns the full menu (small enough to render without pagination) plus a status line the model can speak.
|
|
23
|
+
|
|
24
|
+
**Request**
|
|
25
|
+
```json
|
|
26
|
+
{
|
|
27
|
+
"customer": "Guest"
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
**Response**
|
|
32
|
+
```json
|
|
33
|
+
{
|
|
34
|
+
"status": "Acme Bistro menu is ready for Guest. Build the order here; pay at checkout.",
|
|
35
|
+
"customer": "Guest",
|
|
36
|
+
"items": [
|
|
37
|
+
{ "id": "stone_pizza", "name": "Stone-baked Margherita", "price": 14, "kind": "Mains" },
|
|
38
|
+
{ "id": "roast_bowl", "name": "Harvest Roast Bowl", "price": 13, "kind": "Mains" },
|
|
39
|
+
{ "id": "house_salad", "name": "House Garden Salad", "price": 11, "kind": "Starters" },
|
|
40
|
+
{ "id": "lemon_tart", "name": "Lemon Tart", "price": 8, "kind": "Desserts" },
|
|
41
|
+
{ "id": "sparkling", "name": "Sparkling Water", "price": 4, "kind": "Drinks" }
|
|
42
|
+
]
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**Notes.**
|
|
47
|
+
- `price` is a whole-dollar USD number in v1. If Acme moves to cents or a currency field, keep one canonical numeric price per item so the widget's sum and the checkout total agree.
|
|
48
|
+
- `items[]` is the authoritative menu — the model must not invent dishes or prices outside this list.
|
|
49
|
+
- **Extensibility:** Acme may add fields (`description`, `available`, `dietary_tags`, `image_url`) without breaking the app, as long as `id`, `name`, `price`, and `kind` remain. If `available: false` is added, the widget should disable that row's `+` button.
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## 2. `add_to_cart` — reflect a natural-language addition
|
|
54
|
+
|
|
55
|
+
Called when the diner says *"add two margheritas"* — the model fills `item` and `quantity` from language. The cart is session-local in the widget; this tool echoes the resolved selection so the model can speak it back.
|
|
56
|
+
|
|
57
|
+
**Request**
|
|
58
|
+
```json
|
|
59
|
+
{
|
|
60
|
+
"customer": "Guest",
|
|
61
|
+
"item": "stone_pizza",
|
|
62
|
+
"quantity": 2,
|
|
63
|
+
"notes": ""
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**Response**
|
|
68
|
+
```json
|
|
69
|
+
{
|
|
70
|
+
"status": "Added 2 × stone_pizza for Guest.",
|
|
71
|
+
"item": "stone_pizza",
|
|
72
|
+
"quantity": 2,
|
|
73
|
+
"notes": ""
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
**Notes.**
|
|
78
|
+
- `quantity` is an integer ≥ 1 (defaults to 1). `item` must be one of the five menu IDs; reject unknown IDs.
|
|
79
|
+
- `notes` is a free-text per-item request ("no basil"); optional, defaults to empty.
|
|
80
|
+
- **If Acme makes this server-authoritative** (rather than widget-local), return the updated line and a running subtotal so the frontend can render without a second call — e.g. add `line_total` and `cart_subtotal`. For v1 the widget owns the running total, so the minimal echo above is sufficient.
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## 3. `remove_from_cart` — remove one unit
|
|
85
|
+
|
|
86
|
+
Called by the widget's `−` button or by language ("drop a margherita"). Removes one unit of the item.
|
|
87
|
+
|
|
88
|
+
**Request**
|
|
89
|
+
```json
|
|
90
|
+
{
|
|
91
|
+
"customer": "Guest",
|
|
92
|
+
"item": "stone_pizza"
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**Response**
|
|
97
|
+
```json
|
|
98
|
+
{
|
|
99
|
+
"status": "Removed stone_pizza for Guest.",
|
|
100
|
+
"item": "stone_pizza"
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
**Notes.**
|
|
105
|
+
- Removing decrements by one; the widget deletes the line when its quantity reaches zero.
|
|
106
|
+
- No error if the item isn't in the cart — the operation is idempotent from the model's view (the widget guards the `−` button when quantity is 0).
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## 4. `create_checkout` — mint the signed payment link
|
|
111
|
+
|
|
112
|
+
The one handoff. The widget computes the total (live React) and passes a url-safe cart token plus the numeric total; the tool returns a **signed, expiring** deep link to Acme's PCI-scoped checkout. **No card data is exchanged here** — the diner enters their card on `pay.acme.example`.
|
|
113
|
+
|
|
114
|
+
**Request**
|
|
115
|
+
```json
|
|
116
|
+
{
|
|
117
|
+
"customer": "Guest",
|
|
118
|
+
"cartToken": "stone_pizzax2-lemon_tartx1-sparklingx1",
|
|
119
|
+
"total": 40
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
**Response**
|
|
124
|
+
```json
|
|
125
|
+
{
|
|
126
|
+
"status": "Ready to pay for Guest's order.",
|
|
127
|
+
"summary": "Guest's Acme Bistro order · 40 USD",
|
|
128
|
+
"checkoutUrl": "https://pay.acme.example/checkout?cart=stone_pizzax2-lemon_tartx1-sparklingx1&total=40&src=chatgpt",
|
|
129
|
+
"expires_at": "2026-07-09T18:15:00-07:00"
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
**Notes.**
|
|
134
|
+
- **`checkoutUrl` must be signed server-side.** The `cart` and `total` query params are a convenience for rehydration and display — Acme's checkout must **recompute pricing from the cart token and enforce its own total**, never trusting the client-supplied `total`. Treat the incoming `total` as a display hint to reconcile, not as the charge amount.
|
|
135
|
+
- **`expires_at`** bounds the link (proposed 15-minute window). An expired link should land on a "cart expired — start again" page, not charge a stale total. The runnable app returns `status`, `summary`, and `checkoutUrl`; adding `expires_at` is the recommended production extension so the model can tell the diner how long the link is good for.
|
|
136
|
+
- **`src=chatgpt`** is the attribution parameter — carry it through to Acme's order record so ChatGPT-sourced revenue is measurable against the web channel.
|
|
137
|
+
- **Cart token format.** The app emits a human-readable `<id>x<qty>-<id>x<qty>` token. For production, consider an **opaque server-minted token** (the client passes a cart handle; Acme resolves it to the authoritative lines) to remove any incentive to tamper with the token or `total` before re-validation.
|
|
138
|
+
- **`handoff.allowedDomains`** in the server (`https://pay.acme.example`, `https://acme.example`) is what lets the compiler derive the ChatGPT redirect domain, so the link opens without a safe-link warning. Any new payment domain must be added there.
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## Validation & ownership summary
|
|
143
|
+
|
|
144
|
+
The backend must own and enforce:
|
|
145
|
+
|
|
146
|
+
1. **Pricing** — the authoritative per-item price and the order total; the widget sum is display-only.
|
|
147
|
+
2. **Inventory** — item availability at menu-read and at checkout; a sold-out item should not reach a paid order.
|
|
148
|
+
3. **Payment** — all card capture on `pay.acme.example`, inside Acme's PCI scope. The MCP server is never in the payment path.
|
|
149
|
+
4. **Link integrity** — server-side signing of `checkoutUrl`, an enforced `expires_at`, and recomputation of the total from the cart token before charging.
|
|
150
|
+
|
|
151
|
+
Everything before payment — menu, cart, total, and minting the link — is the ChatGPT App's job. Everything at and after payment is Acme's.
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## Open questions for Acme engineering
|
|
156
|
+
|
|
157
|
+
1. **Cart token shape** — keep the readable `idxN-idxN` form, or move to an opaque server handle to prevent client-side tampering?
|
|
158
|
+
2. **Signing scheme & expiry** — HMAC, JWT, or signed query params, and what default expiry window (proposed 15 min)?
|
|
159
|
+
3. **Currency & precision** — stay whole-dollar USD, or introduce cents / a `currency` field? The widget and checkout total must agree.
|
|
160
|
+
4. **Server-authoritative cart** — should `add_to_cart` / `remove_from_cart` become backend-owned (returning subtotals), or stay widget-local for v1?
|
|
161
|
+
5. **Post-payment visibility** — expose a webhook or polling endpoint so a later chat turn can confirm order status? Out of scope for v1.
|