@layers/amba 1.1.0 → 4.0.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@layers/amba",
3
- "version": "1.1.0",
3
+ "version": "4.0.2",
4
4
  "description": "amba — agent-native backend-as-a-service. Functions, collections, storage, AI, email, queues, sites — one CLI to spin up your project and ship to production. `npx @layers/amba init` to start.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -8,6 +8,7 @@
8
8
  },
9
9
  "files": [
10
10
  "dist",
11
+ "skill-bundle",
11
12
  "README.md"
12
13
  ],
13
14
  "publishConfig": {
@@ -48,7 +49,8 @@
48
49
  "tsdown": "^0.12.5",
49
50
  "typescript": "^5.8.3",
50
51
  "vitest": "^3.2.4",
51
- "@layers/amba-mcp": "1.0.1"
52
+ "@layers/amba-mcp": "4.0.2",
53
+ "@layers/amba-shared": "4.0.2"
52
54
  },
53
55
  "scripts": {
54
56
  "build": "tsdown && tsc --emitDeclarationOnly",
@@ -0,0 +1,324 @@
1
+ ---
2
+ name: amba
3
+ description: Wire Amba (auth, push, gamification, economy, social, content) into this app. Use when the user types /amba or says "set up amba", "add a backend", "add streaks/achievements/leaderboards/currency/friends/messaging/feeds/push" to an existing app, "build a fitness/social/marketplace/dating/etc. app" with amba, "integrate amba into this app", or "read amba.dev/llms.txt".
4
+ homepage: https://docs.amba.dev
5
+ metadata: {"requires":{"env":["AMBA_PROJECT_ID"],"mcp":["amba"]}}
6
+ ---
7
+
8
+ # amba
9
+
10
+ You're wiring Amba into this codebase. Amba is a backend-as-a-service: auth, push, gamification, in-app economy, social, content, analytics. One Amba project = one isolated database + one set of API keys + a hosted MCP at `mcp.amba.dev` for agent-driven provisioning. The runtime traffic goes through an SDK (`@layers/amba-*` on npm, `Amba` on SPM/Maven/pub.dev). The provisioning traffic — what you're about to do — goes through the MCP tools listed below.
11
+
12
+ Your job is to take the user from "I have an app" to "Amba is wired in and the features are real" in one pass, without 12 follow-up questions. The journey below is the standard playbook. Don't deviate without a reason.
13
+
14
+ ## Step 0 — Ensure provisioning
15
+
16
+ Check whether a project exists in this directory:
17
+
18
+ 1. **Read `.env.local`.** If `AMBA_PROJECT_ID` exists AND `AMBA_CLIENT_KEY` exists, call `amba_developer_me` to verify the credential. If verify succeeds, capture `project_id` and proceed to Step 1.
19
+
20
+ 2. **Else read `~/.amba/credentials.json`.** If a developer credential exists, call `amba_developer_me` to verify. If verify succeeds, call `amba_projects_create` with:
21
+ - `name` = basename of `cwd` (e.g. `my-fitness-app`)
22
+ - `platform` = `"all"` (let the SDK detect; we can refine later)
23
+
24
+ Take the returned `project_id`. Call `amba_api_keys_create` twice — once with `key_type: "client"` and once with `key_type: "server"` — to mint the two keys for `environment: "development"`. Write all three values into `.env.local` (see "Writing .env.local" below). Skip ahead to Step 1.
25
+
26
+ 3. **Else (no creds anywhere):** call `amba_developer_signup`. This is the only MCP tool you can call pre-auth — it mints a PAT + project + client/server keys in one round trip, no browser, no email verification. The CLI's sandbox flow uses the same call. Use these args:
27
+ - `email` = `sandbox-<unix-seconds>-<6char-nonce>@layers.com`
28
+ - `password` = random 32-char base64url string
29
+ - `name` = `"amba-sandbox-agent"`
30
+
31
+ The response shape (taken straight from `apps/api/src/routes/auth/developer.ts:477-495`):
32
+
33
+ ```json
34
+ {
35
+ "data": {
36
+ "pat": "amb_dpat_…",
37
+ "developer": { "id": "…", "email": "…", "tier": "agent_sandbox" },
38
+ "project": {
39
+ "project_id": "…",
40
+ "client_key": "amb_dev_ck_…",
41
+ "server_key": "amb_dev_sk_…",
42
+ "provisioning_status": "provisioning",
43
+ "verify_url": "https://app.amba.dev/verify?token=…",
44
+ "verify_token": "…"
45
+ }
46
+ }
47
+ }
48
+ ```
49
+
50
+ Persist:
51
+ - `pat` → `~/.amba/credentials.json` (chmod `0600`). The CLI writes
52
+ the new versioned shape and keeps the legacy `access_token`
53
+ mirror so older `loadCredentials` readers still work:
54
+ ```json
55
+ {
56
+ "version": 1,
57
+ "developer_id": "<from /developer/me>",
58
+ "email": "<sandbox email>",
59
+ "pat": "<pat>",
60
+ "api_url": "https://api.amba.dev",
61
+ "source": "sandbox-init",
62
+ "created_at": "<now ISO 8601>",
63
+ "access_token": "<pat>",
64
+ "refresh_token": "",
65
+ "expires_at": "2099-12-31T00:00:00.000Z"
66
+ }
67
+ ```
68
+ - `project_id`, `client_key`, `server_key`, `api_url` → `.env.local` in cwd (see "Writing .env.local"). The CLI also persists per-project state at `<cwd>/.amba/project.json` with `{ version: 1, project_id, project_name, environment, client_key, server_key, api_url, wired_surfaces: [], created_at, updated_at }`.
69
+
70
+ The project status is `"provisioning"` immediately after signup; the per-tenant DB activates within ~5 seconds. Don't block — your next SDK or MCP call may briefly retry, that's fine. If you want to be polite, call `amba_projects_get_provisioning_status({ project_id })` once and proceed when it returns `"active"` (or after 15s, whichever first).
71
+
72
+ > **If you don't see Amba MCP tools available** (no `mcp__amba__*` in your tool list), Amba's MCP server isn't wired into your agent's tool surface this session. Run `npx -y @layers/amba init` via your bash tool — it provisions the account/project, writes `.env.local`, installs this skill, and wires the MCP entry into the user's agent config so the typed tools light up on the next agent launch.
73
+ >
74
+ > Do not pause to ask the user about restarting. You have **three** working paths for admin operations in this session, in order of preference:
75
+ >
76
+ > 1. **POST JSON-RPC directly to `https://mcp.amba.dev/mcp`** (recommended — full 178-tool surface, no client wiring needed). Amba's MCP is plain HTTP, not stdio. Read the PAT from `~/.amba/credentials.json` (`.pat` field), then `curl` (or `fetch`) the endpoint:
77
+ > ```bash
78
+ > PAT=$(jq -r .pat ~/.amba/credentials.json)
79
+ > curl -sS https://mcp.amba.dev/mcp \
80
+ > -H "Authorization: Bearer $PAT" \
81
+ > -H "Content-Type: application/json" \
82
+ > -H "Accept: application/json" \
83
+ > -H "MCP-Protocol-Version: 2025-03-26" \
84
+ > -d '{
85
+ > "jsonrpc":"2.0","id":"1","method":"tools/call",
86
+ > "params":{"name":"amba_currencies_create","arguments":{"project_id":"…","name":"coins","display_name":"Coins"}}
87
+ > }'
88
+ > ```
89
+ > The response is the standard MCP envelope `{"jsonrpc":"2.0","id":"1","result":{"content":[{"type":"text","text":"<JSON body>"}]}}`. You construct calls by hand the same way you would with typed tools — every `amba_*` tool name from the catalog works. This is the same wire the typed-tool surface uses; you just skip the client-side configuration loop.
90
+ > 2. **The `amba` CLI via bash.** Already authenticated via `~/.amba/credentials.json`. Coverage: `amba projects {list,create,update,show,delete}`, `amba collections {create,alter,list,drop}`, `amba functions {deploy,list,delete,schedule,dev,logs,consume}`, `amba push test`, `amba secrets {set,list,unset}`, `amba config {list,set}`, `amba sites <subcommands>`, `amba seed`, `amba status --detailed`, `amba logs tail`, `amba analytics export`, `amba schema export`, `amba ai <subcommands>`, `amba db migrate`, `amba billing {status,upgrade,portal,set-ceiling}`, `amba claim <email>` (sandbox → verified_free magic link). Run `amba --help` once if you need to see the full subcommand surface. Use this when you want a typed wrapper for a common op; the JSON-RPC path is strictly more flexible.
91
+ > 3. **Wait for next agent launch.** The MCP entry is already persisted; on the next launch, `mcp__amba__*` tools appear automatically.
92
+ >
93
+ > A SEPARATE case: if Amba MCP IS wired in this session but the inbound Bearer is stale (e.g., the user just ran `amba_developer_signup` and got a fresh PAT), pass `pat: "<the new PAT>"` as an inline argument on every subsequent `amba_*` tool call to override the inbound Bearer for that one call. This only helps when the `mcp__amba__*` tools already exist in your tool list — it does not summon them into existence.
94
+
95
+ ### Writing `.env.local`
96
+
97
+ Append (or merge in-place) this stanza, in cwd:
98
+
99
+ ```
100
+ # Amba SDK configuration
101
+ AMBA_PROJECT_ID=<project_id>
102
+ AMBA_CLIENT_KEY=<client_key>
103
+ AMBA_SERVER_KEY=<server_key>
104
+ AMBA_API_URL=https://api.amba.dev
105
+ ```
106
+
107
+ If the file already has an `AMBA_PROJECT_ID=` line, replace the Amba lines in place. Otherwise append.
108
+
109
+ `.env.local` is gitignored by every modern framework — that's the safety boundary for `AMBA_SERVER_KEY`. The CLI writes both keys here for symmetry with how the SDKs read them (server code reads `AMBA_SERVER_KEY`; client code reads `AMBA_CLIENT_KEY`). **Never embed `AMBA_SERVER_KEY` in code that ships to end users** — keep it strictly behind your server boundary. If you're shipping into a non-gitignored env file or a runtime config that ships to clients, route `AMBA_SERVER_KEY` to your hosting platform's secret manager (Vercel envs, Fly.io secrets, AWS Secrets Manager, etc.) instead.
110
+
111
+ ## Step 1 — Classify the app
112
+
113
+ Look at the codebase. You're trying to pick one of ten presets in 30 seconds, not write a treatise. Inputs:
114
+
115
+ - `README.md` — what does the user say the app is?
116
+ - `package.json` / `pubspec.yaml` / `build.gradle.kts` / `Package.swift` — what framework / dependencies?
117
+ - Top-level directories: `screens/`, `views/`, `components/`, `lib/widgets/`, `app/`, `src/pages/`
118
+ - Screen/view filenames — `WorkoutScreen`, `MatchView`, `LessonPage`, `CartView`, `ProductDetail`, `ChatThread`
119
+
120
+ Pick the closest match:
121
+
122
+ | Preset | When | Default Amba surfaces |
123
+ | --- | --- | --- |
124
+ | **fitness** | health/fitness tracker (workouts, steps, meditation) | identity (Apple+Google), push, XP, achievements, streaks, leaderboards, content (daily tips) |
125
+ | **social** | social network / community (friends, feeds, groups) | identity, push, friends, groups, feeds, messaging, moderation, content |
126
+ | **marketplace** | commerce / marketplace (catalog, stores, payments) | identity, push, catalog, stores, currencies (loyalty), reviews, segments |
127
+ | **productivity** | productivity / SaaS tool (collaboration, milestones) | identity (Apple+Google+OTP), push, collections, achievements, content (changelog), segments |
128
+ | **education** | education / learning app (courses, progress, rewards) | identity, push, XP, achievements, streaks, leaderboards, content (lessons), onboarding |
129
+ | **game** | game / casual gaming | identity (anon-first), push, XP, achievements, currencies, inventory, leaderboards, challenges, stores |
130
+ | **dating** | dating / matching app | identity (phone-OTP), push, friends (matches), messaging, moderation (heavy), reviews |
131
+ | **content_creator** | content platform (feeds, subscriptions, tips) | identity, push, feeds, content, currencies (tips), referrals, stores (subscriptions) |
132
+ | **ai_chatbot** | AI / chatbot / assistant app | identity, push, AI prompts, currencies (credits), content (system prompts), onboarding |
133
+ | **custom** | none of the above | pick features individually |
134
+
135
+ Detection heuristics, in priority order:
136
+ 1. Filename match in `screens/` or `views/` (highest signal).
137
+ 2. Dependency in `package.json` — `react-native-health` → fitness, `@stream-io/*` → social or dating, `@stripe/*` → marketplace, `revenuecat` → marketplace or content_creator.
138
+ 3. README copy — "fitness", "habit", "match", "chat", "store", "subscription".
139
+ 4. App / project name — `MyHabitTracker`, `MealPrep`, `Trivia`.
140
+
141
+ If two presets tie, prefer the one that the user's filenames match more closely. If still tied or no signal, fall back to **custom** and let the user pick.
142
+
143
+ ## Step 2 — Confirm with the user
144
+
145
+ Use your native ask-user mechanism — `AskUserQuestion` in Claude Code; MCP elicitation if the client supports it; otherwise present as a chat multi-choice. Be concise. Quote the surfaces from the table above so they know what they're getting.
146
+
147
+ **Question 1: classification + scope**
148
+
149
+ > I'm reading this as a **{kind}** app. I'd wire up: **{surfaces}**. Sound right?
150
+ >
151
+ > 1. Yes, wire it up as proposed (Recommended)
152
+ > 2. Same kind but I want to pick features individually
153
+ > 3. Wrong kind — let me pick from the list
154
+ > 4. Custom — I'll pick features manually
155
+
156
+ If the user picks 1, go to Step 3. If 2 or 4, follow up with a multi-select of surfaces. If 3, present the table again and pick a different preset.
157
+
158
+ **Question 2 (preset-specific):** see "Common follow-ups" in the per-surface `references/<surface>.md` files. Examples:
159
+
160
+ - **fitness / game / education** — leaderboard scope? (all-time, weekly, daily, none)
161
+ - **game / content_creator** — virtual currency name? (`gold`, `gems`, `coins`, `credits` — defaults to `coins`)
162
+ - **content_creator** — monetization? (tips, subscriptions, both)
163
+ - **dating** — phone OTP or email-only? (phone strongly recommended)
164
+ - **ai_chatbot** — daily free credit cap?
165
+
166
+ Batch the follow-ups into one or two multi-choice rounds. Don't drip-feed 6 separate questions.
167
+
168
+ ## Step 3 — Wire it up
169
+
170
+ For each surface in the confirmed set, read the relevant reference file and execute its procedure:
171
+
172
+ - **identity** (auth, anonymous/Apple/Google/OTP/magic-link, link/unlink) → `references/identity.md`
173
+ - **engagement** (push, segments, content libraries, onboarding flows, deeplinks, referrals, tracked links) → `references/engagement.md`
174
+ - **gamification** (XP rules, achievements, streaks, leaderboards, challenges) → `references/gamification.md`
175
+ - **economy** (currencies, catalog, stores, inventory) → `references/economy.md`
176
+ - **social** (friends, groups, feeds, messaging, moderation, reviews) → `references/social.md`
177
+ - **infrastructure** (collections / DB tables, functions, analytics, AI prompts) → `references/infrastructure.md`
178
+
179
+ Each reference file has, in order:
180
+
181
+ 1. **Overview** — one paragraph.
182
+ 2. **MCP tools** — exact tool names with example args you can copy.
183
+ 3. **SDK init per stack** — one block each for Expo, React Native, web, iOS Swift, Android Kotlin, Flutter.
184
+ 4. **Common follow-ups** — multi-choice prompts to ask the user.
185
+ 5. **Re-run behavior** — how to detect existing resources and offer extensions.
186
+
187
+ The general flow for every surface:
188
+
189
+ 1. **Detect stack.** Look at `package.json`, `pubspec.yaml`, `build.gradle.kts`, `ios/*.xcodeproj`. The detection rules:
190
+ - `pubspec.yaml` present → Flutter.
191
+ - `package.json` with `expo` → Expo.
192
+ - `package.json` with `react-native` (no `expo`) → bare React Native.
193
+ - `package.json` with `react` (no `react-native`) → web (or Next.js — same SDK).
194
+ - `Package.swift` or `*.xcodeproj` only → iOS Swift.
195
+ - `build.gradle.kts` or `build.gradle` with `com.android.application` → Android Kotlin.
196
+ - Multiple (e.g. `ios/` + `android/` inside an Expo repo) → Expo wins.
197
+
198
+ 2. **Create resources via MCP.** Call the `amba_<surface>_create` tools to mint the definitions (currencies, achievements, leaderboards, streaks, segments, push campaigns, etc.). Always include `project_id` from `.env.local`. Always show the user the tool call before you make destructive changes (creating a resource isn't destructive — but creating 30 of them is noisy).
199
+
200
+ 3. **Write SDK init code.** Drop the per-stack snippet (from `references/<surface>.md`) into the user's entry file. Detection:
201
+ - Expo / React Native: `app/_layout.tsx`, `App.tsx`, `index.js` (in that order)
202
+ - web / Next.js: `app/layout.tsx`, `pages/_app.tsx`, `src/main.tsx`, `src/App.tsx`
203
+ - iOS Swift: `Sources/<App>/<App>App.swift`, `App/AppDelegate.swift`
204
+ - Android Kotlin: `app/src/main/java/.../<App>.kt` (the `Application` subclass — create one if missing)
205
+ - Flutter: `lib/main.dart`
206
+
207
+ Always make additive edits — `await Amba.configure(...)` next to existing init, not replacing it. Never refactor existing auth or storage code; if the user has Firebase Auth or Supabase, leave it. Amba's auth is opt-in per call.
208
+
209
+ 4. **Run the project's existing test command** to confirm nothing broke. Detection:
210
+ - `package.json` `scripts.test` → `npm test` (or `pnpm test` if `pnpm-lock.yaml` present)
211
+ - `pubspec.yaml` → `flutter test`
212
+ - `build.gradle.kts` → `./gradlew test` (skip on first wire-up — slow)
213
+ - iOS — skip (need a simulator).
214
+
215
+ If tests fail because of your edits, undo the offending edit and surface a clear error. If they fail for unrelated reasons (pre-existing red), note it and proceed.
216
+
217
+ 5. **Track progress.** After wiring each surface, append to `.amba/wired.json` (create the directory if missing):
218
+
219
+ ```json
220
+ {
221
+ "surfaces": {
222
+ "gamification": {
223
+ "wired_at": "2026-05-26T17:00:00Z",
224
+ "resources": {
225
+ "achievements": ["first_workout", "streak_master_7"],
226
+ "streaks": ["daily_workout"],
227
+ "leaderboards": ["weekly_xp"]
228
+ }
229
+ }
230
+ }
231
+ }
232
+ ```
233
+
234
+ This is what the re-run check reads in Step 0 / on a second invocation.
235
+
236
+ ## Step 4 — Report
237
+
238
+ Tell the user a structured summary. Use this exact shape so they can skim it fast:
239
+
240
+ ```
241
+ Amba is wired in. Here's what changed:
242
+
243
+ DONE
244
+ - identity: Apple + Google sign-in available; signInAnonymously() called at app start
245
+ files touched: lib/main.dart
246
+ - gamification: 3 achievements, 1 streak, 1 leaderboard created
247
+ resources: first_workout, week_warrior, century_club / daily_workout / weekly_xp
248
+ files touched: lib/main.dart (added Amba.streaks.qualify on workout_completed)
249
+ - engagement: push registration wired; default segment "active_users" created
250
+ files touched: lib/main.dart, lib/notification_service.dart
251
+
252
+ SKIPPED (low signal — re-run with /amba <feature> if you want them)
253
+ - economy: no in-app currency UI found in your screens
254
+ - social: no friends/feed surfaces found
255
+
256
+ NEEDS YOUR INPUT
257
+ - Apple Sign In: add the "Sign in with Apple" capability in Xcode > Signing & Capabilities.
258
+ - Google Sign In: paste your Google OAuth client ID into amba_projects_update({ google_oauth_client_id: "..." }).
259
+ - APNs / FCM: you'll need to upload credentials in the Amba console (app.amba.dev) before push delivers.
260
+
261
+ NEXT STEPS
262
+ - Run the app on device: `flutter run`
263
+ - Trigger a workout in your existing flow — watch the achievement unlock + XP land
264
+ - Open https://app.amba.dev to see the user pour in
265
+ ```
266
+
267
+ Be specific. List the resources by key, not "some achievements". List the files by path. If something needs the user's input (third-party credentials, OAuth client IDs, push certs), say it clearly with the exact next action.
268
+
269
+ ## Stance (read this once)
270
+
271
+ - **Don't ask which surfaces to use.** Classify, then confirm in one multi-choice. The taxonomy is the whole point.
272
+ - **Default to additive, non-breaking changes.** Don't refactor existing auth, storage, or networking code. Drop in `await Amba.configure(...)` next to whatever the user already has.
273
+ - **Never create resources without the user's confirmation in Step 2.** A 3rd-party "convenience" achievement called `first_login` is debt.
274
+ - **If something is genuinely ambiguous** (leaderboard scope, currency real-money vs virtual, dating phone vs email), ask via a follow-up multi-choice. Don't guess and don't paragraph-it.
275
+ - **clientKey vs serverKey.** `AMBA_CLIENT_KEY` (`amb_dev_ck_…` in dev, `amb_live_ck_…` in prod) ships to user devices. `AMBA_SERVER_KEY` (`amb_dev_sk_…` / `amb_live_sk_…`) never does — only into server `.env` or a secret manager. Mixing them is the #1 security mistake; if you're writing into a file that ships with the app binary, it's the client key, period.
276
+ - **Don't print the PAT in chat output.** It's in `~/.amba/credentials.json` and that's enough. Showing it to the user is fine *once*, but don't echo it on every re-run.
277
+ - **For the full MCP tool catalog beyond what's in `references/`**, read the resource `amba://setup` from the MCP server — it's the long-form companion to this skill.
278
+
279
+ ## Re-running
280
+
281
+ If you're invoked a second time on the same project:
282
+
283
+ 1. **Read `.amba/wired.json`** — this lists already-wired surfaces and the resources you created. If absent, treat the project as un-wired and run the full journey.
284
+
285
+ 2. **Re-check `.env.local`.** If `AMBA_PROJECT_ID` is missing or `amba_developer_me` rejects the PAT, re-run Step 0. (A PAT in `~/.amba/credentials.json` from a different machine, or a manually-rotated one, will surface here.)
286
+
287
+ 3. **Ask scoped questions only.** If `wired.json` shows gamification was already wired, don't re-ask about leaderboards — offer to extend:
288
+
289
+ > Gamification is already wired (3 achievements, 1 streak, 1 leaderboard). Want to:
290
+ >
291
+ > 1. Add more achievements
292
+ > 2. Add a new leaderboard
293
+ > 3. Add a new streak
294
+ > 4. Wire another surface (push, currencies, friends…)
295
+ > 5. Nothing right now
296
+
297
+ 4. **Never re-create existing resources.** Call `amba_list_<surface>` (e.g. `amba_list_achievements`) first; if a key collides, skip it or `amba_<surface>_update` instead of `_create`.
298
+
299
+ 5. **Update `wired.json` after extending.** Append to `resources.*` arrays — don't replace.
300
+
301
+ ## Quick reference — bootstrap call shape
302
+
303
+ ```
304
+ // Step 0 path C: no credentials anywhere
305
+ mcp__amba__amba_developer_signup({
306
+ email: "sandbox-1748275200-a3b9z2@layers.com",
307
+ password: "<32 random base64url chars>",
308
+ name: "amba-sandbox-agent"
309
+ })
310
+ // → { data: { pat, project: { project_id, client_key, server_key, verify_url, … } } }
311
+
312
+ // Step 0 path B: have a PAT, no project
313
+ mcp__amba__amba_developer_me({})
314
+ // → { data: { id, email, tier, … } }
315
+ mcp__amba__amba_projects_create({
316
+ name: "my-fitness-app",
317
+ platform: "all"
318
+ })
319
+ // → { data: { id, … } }
320
+ mcp__amba__amba_api_keys_create({ project_id, key_type: "client", environment: "development" })
321
+ mcp__amba__amba_api_keys_create({ project_id, key_type: "server", environment: "development" })
322
+ ```
323
+
324
+ You're ready. Start at Step 0.