@ambasada/skills 0.3.0 → 0.4.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ambasada/skills",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Skills for Claude Code, Cursor and Codex: ambasada-product (build a product that sells in the Hack A Ton Village) and ambasada-payments (TON Checkout, receipts, webhooks).",
5
5
  "type": "module",
6
6
  "files": [
@@ -68,6 +68,25 @@ const { keys, used_bytes } = await village.store.list("cart:");
68
68
  HTTP: `GET|PUT|DELETE /v1/store/:key` (PUT body = the JSON value), `GET /v1/store?prefix=`;
69
69
  `POST /v1/product/deploy` (what `ambasada deploy` calls), `GET /v1/product`, `DELETE /v1/product`.
70
70
 
71
+ ## Sign in with Ambasada
72
+
73
+ People sign in to your hosted product with their Ambasada ID. There is nothing to set up: `ambasada deploy`
74
+ injects `AMBASADA_AUTH_CLIENT_ID`, `AMBASADA_AUTH_CLIENT_SECRET` and `AMBASADA_AUTH_ISSUER`, and `ambasada dev`
75
+ injects fake ones (the mock signs you in as "Fake Visitor"). The templates already have the routes and a
76
+ header button.
77
+
78
+ ```ts
79
+ // GET /api/auth/login?returnTo=/ GET /api/auth/callback GET /api/auth/logout
80
+ return village.auth.login(req, { returnTo: "/", email: false }); // email: true asks for it on the consent screen
81
+ return village.auth.callback(req); // sets an HttpOnly session cookie
82
+ return village.auth.logout(req);
83
+ const user = await village.auth.user(req); // null, or { id, name, avatar_url, builder, builder_since, member_since, pass, email? }
84
+ ```
85
+
86
+ `user.id` (`user_…`) is stable: key your data by it (``village.store.set(`user:${user.id}`, …)``).
87
+ `pass` is `"builder" | "visitor" | "staff" | null` for the current event. Server code only; the browser asks
88
+ `/api/auth/me`. It works on `https://<slug>.ambasada.dev` and under `ambasada dev`, not with `--own` hosting.
89
+
71
90
  ## Errors
72
91
 
73
92
  `{ "error": { "code", "message", call_id?, charged?: false, refunded?, approval_id? } }`. The SDK throws
@@ -14,6 +14,8 @@ my-shop/
14
14
  app/api/webhook/route.ts checkout.paid arrives here, signed: deliver here
15
15
  app/api/receipt/route.ts verifies a pay.js receipt from the browser
16
16
  app/api/translate/route.ts the paid offering: agents call it with a receipt
17
+ app/api/auth/*/route.ts Sign in with Ambasada: login, callback, logout, me
18
+ app/account.tsx the header: "Sign in with Ambasada", or the person's name and avatar
17
19
  lib/ambasada.ts the Village client for server code (reads the Worker env)
18
20
  offerings.ts what agents can buy: name, price, endpoint, input and output
19
21
  agent/agent.md your agent's instructions, in plain English
@@ -48,6 +50,23 @@ where `env` comes from `getCloudflareContext()` (deployed); under `next dev` the
48
50
  It reads `AMBASADA_API_KEY`, `AMBASADA_API_URL`, `AMBASADA_COMPANY`, `AMBASADA_WEBHOOK_SECRET`.
49
51
  Everything the client can do is in the ambasada-payments skill.
50
52
 
53
+ ## Who is signed in
54
+
55
+ Every hosted product gets **Sign in with Ambasada** (Ambasada ID) for free: no keys, no settings.
56
+ The template's header already has the button. In server code:
57
+
58
+ ```ts
59
+ import { currentUser } from "../lib/ambasada.ts";
60
+
61
+ const user = await currentUser(); // null, or { id, name, avatar_url, builder, pass, member_since, … }
62
+ if (!user) redirect("/api/auth/login?returnTo=/orders");
63
+ await ambasada().store.set(`orders:${user.id}`, orders); // key per-person data by user.id
64
+ ```
65
+
66
+ In a route handler, `ambasada().auth.user(req)` does the same. Client components fetch `/api/auth/me`.
67
+ Ask for the email only if you need it: `/api/auth/login` calls `auth.login(req, { email: true })`.
68
+ Don't build your own login or accounts table, and don't add Clerk, Auth.js or Supabase Auth.
69
+
51
70
  ## Next.js: allowed and banned
52
71
 
53
72
  Allowed, and enough for any product here:
@@ -93,7 +112,8 @@ File URLs are public: don't put private data in them.
93
112
 
94
113
  - Local: `.env` in the project (Cloudflare's `.dev.vars` works too). The template writes it with test
95
114
  values for `ambasada dev`. Both are in `.gitignore`; keep them there.
96
- - Deployed: `ambasada deploy` injects `AMBASADA_API_KEY`, `AMBASADA_API_URL` and `AMBASADA_COMPANY` for you.
115
+ - Deployed: `ambasada deploy` injects `AMBASADA_API_KEY`, `AMBASADA_API_URL`, `AMBASADA_COMPANY` and the
116
+ Sign in with Ambasada credentials (`AMBASADA_AUTH_*`) for you.
97
117
  With `--own`, set them yourself: `npx wrangler secret put AMBASADA_API_KEY`.
98
118
  - Other services' keys (an OpenAI key, say): same place, read on the server only.
99
119
  - Anything named `NEXT_PUBLIC_*` is copied into the browser. Never put a key there.