run402-mcp 4.88.0 → 4.90.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.
Files changed (51) hide show
  1. package/README.md +33 -90
  2. package/dist/tools/app-up.d.ts.map +1 -1
  3. package/dist/tools/app-up.js +6 -1
  4. package/dist/tools/app-up.js.map +1 -1
  5. package/package.json +5 -3
  6. package/schemas/release-spec.v1.json +540 -138
  7. package/sdk/README.md +11 -5
  8. package/sdk/dist/errors.d.ts +1 -0
  9. package/sdk/dist/errors.d.ts.map +1 -1
  10. package/sdk/dist/errors.js +1 -1
  11. package/sdk/dist/errors.js.map +1 -1
  12. package/sdk/dist/index.d.ts +8 -0
  13. package/sdk/dist/index.d.ts.map +1 -1
  14. package/sdk/dist/index.js +8 -0
  15. package/sdk/dist/index.js.map +1 -1
  16. package/sdk/dist/namespaces/deploy.types.d.ts +12 -0
  17. package/sdk/dist/namespaces/deploy.types.d.ts.map +1 -1
  18. package/sdk/dist/namespaces/deploy.types.js.map +1 -1
  19. package/sdk/dist/namespaces/live.d.ts +33 -0
  20. package/sdk/dist/namespaces/live.d.ts.map +1 -0
  21. package/sdk/dist/namespaces/live.js +220 -0
  22. package/sdk/dist/namespaces/live.js.map +1 -0
  23. package/sdk/dist/namespaces/live.types.d.ts +78 -0
  24. package/sdk/dist/namespaces/live.types.d.ts.map +1 -0
  25. package/sdk/dist/namespaces/live.types.js +8 -0
  26. package/sdk/dist/namespaces/live.types.js.map +1 -0
  27. package/sdk/dist/namespaces/projects.d.ts.map +1 -1
  28. package/sdk/dist/namespaces/projects.js +1 -0
  29. package/sdk/dist/namespaces/projects.js.map +1 -1
  30. package/sdk/dist/namespaces/projects.types.d.ts +2 -1
  31. package/sdk/dist/namespaces/projects.types.d.ts.map +1 -1
  32. package/sdk/dist/node/gitvault-degraded-read.js +1 -1
  33. package/sdk/dist/node/gitvault-degraded-read.js.map +1 -1
  34. package/sdk/dist/node/gitvault-snapshot.d.ts.map +1 -1
  35. package/sdk/dist/node/gitvault-snapshot.js +9 -3
  36. package/sdk/dist/node/gitvault-snapshot.js.map +1 -1
  37. package/sdk/dist/node/index.d.ts +1 -0
  38. package/sdk/dist/node/index.d.ts.map +1 -1
  39. package/sdk/dist/node/index.js +1 -0
  40. package/sdk/dist/node/index.js.map +1 -1
  41. package/sdk/dist/node/paid-fetch.d.ts.map +1 -1
  42. package/sdk/dist/node/paid-fetch.js +9 -1
  43. package/sdk/dist/node/paid-fetch.js.map +1 -1
  44. package/sdk/dist/node/workflow-output.d.ts +10 -0
  45. package/sdk/dist/node/workflow-output.d.ts.map +1 -0
  46. package/sdk/dist/node/workflow-output.js +112 -0
  47. package/sdk/dist/node/workflow-output.js.map +1 -0
  48. package/sdk/dist/scoped.d.ts +11 -0
  49. package/sdk/dist/scoped.d.ts.map +1 -1
  50. package/sdk/dist/scoped.js +18 -0
  51. package/sdk/dist/scoped.js.map +1 -1
package/README.md CHANGED
@@ -5,9 +5,9 @@
5
5
  <h1 align="center">run402: full-stack backend infrastructure for AI agents</h1>
6
6
 
7
7
  <p align="center">
8
- Postgres, auth, storage, serverless functions and atomic deploys &mdash;
9
- provisioned, operated and paid for by an agent through a typed SDK, a CLI
10
- or an MCP server. No cloud console, no signup. Open source.
8
+ Postgres, auth, storage, serverless functions and staged deploys &mdash;
9
+ provisioned, operated and paid for by an agent through the CLI, with a typed SDK for scripting
10
+ and MCP for tool-native hosts. No cloud console, no signup. Open source.
11
11
  </p>
12
12
 
13
13
  [![Tests](https://github.com/kychee-com/run402/actions/workflows/test.yml/badge.svg)](https://github.com/kychee-com/run402/actions/workflows/test.yml)
@@ -18,7 +18,7 @@
18
18
  [![npm: @run402/functions](https://img.shields.io/npm/v/@run402/functions?label=%40run402%2Ffunctions)](https://www.npmjs.com/package/@run402/functions)
19
19
  [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)
20
20
 
21
- **Run402 is open-source backend infrastructure for AI agents and coding agents** — a backend-as-a-service addressed to a machine rather than to a person. An autonomous agent provisions a Postgres database, user auth, file storage, serverless functions and site hosting, ships them in one atomic deploy, and pays for the usage itself. Comparable in surface to Supabase, Firebase or Vercel; different in that there is no dashboard to sign into and no human-issued API key to copy.
21
+ **Run402 is open-source backend infrastructure for AI agents and coding agents** — a backend-as-a-service addressed to a machine rather than to a person. An autonomous agent provisions a Postgres database, user auth, file storage, serverless functions and site hosting, ships them through one staged deployment workflow, and pays for the usage itself. Comparable in surface to Supabase, Firebase or Vercel; different in that there is no dashboard to sign into and no human-issued API key to copy.
22
22
 
23
23
  This is the backend Kychee's open products run on. We needed a layer an agent can drive end to end, with room for whatever each app turns out to need, and nothing off the shelf had all of it, so we built it and opened it the same way we open the apps: this repo holds the agent surfaces (MIT), [`run402-core`](https://github.com/kychee-com/run402-core) holds the full backend (Apache-2.0), and [kysigned](https://github.com/kychee-com/kysigned) is the first product running on it.
24
24
 
@@ -28,28 +28,33 @@ One call to [run402](https://run402.com) gives an agent a full Postgres database
28
28
 
29
29
  An autonomous agent may remain the legitimate owner of the org-of-one it creates. People may join through explicit co-ownership. Agents entering somebody else's organization receive bounded authority instead of borrowing a human account. Different keys. Equal standing. Explicit authority.
30
30
 
31
- This monorepo ships every surface an agent can pick up:
31
+ **Use the CLI by default** to provision, deploy, inspect and recover. Use the typed, opinionated SDK when writing programmatic TypeScript/JavaScript workflows; shell scripts and CI can keep using CLI. MCP serves MCP-native hosts, and direct HTTP supports deliberate lower-level integrations.
32
+
33
+ This monorepo ships these interfaces:
32
34
 
33
35
  | Surface | Use when… |
34
36
  |---------|-----------|
35
- | [`@run402/sdk`](./sdk/) | Calling run402 from TypeScript: typed kernel, isomorphic (Node 22 / Deno / Bun / V8 isolates) with a Node entry that auto-loads the local keystore + allowance + x402 / Lightning fetch |
36
37
  | [`run402` CLI](./cli/) | Terminal, scripts, CI, agent-controlled shells: JSON in, JSON out, exit code on failure |
38
+ | [`@run402/sdk`](./sdk/) | Calling run402 from TypeScript: typed kernel, isomorphic (Node 22 / Deno / Bun / V8 isolates) with a Node entry that auto-loads the local keystore + allowance + x402 / Lightning fetch |
37
39
  | [`run402-mcp`](./src/) | Claude Desktop, Cursor, Cline, Claude Code: core run402 operations as MCP tools |
38
40
  | [OpenClaw skill](./openclaw/) | OpenClaw agents (no MCP server required) |
39
41
  | [Run402 for Buzz](./buzz/) | Buzz people and agents: install from run402.com, preflight/link one agent's dedicated identities, deploy a contextual demo, then offer human co-ownership through a normal HTTPS/passkey handoff; Buzz remains unchanged |
40
42
  | [`@run402/functions`](https://www.npmjs.com/package/@run402/functions) | Imported _inside_ deployed functions (`db(req?)`, `adminDb()`, `auth.user()`, `email`, `ai`, `assets`) and for TypeScript autocomplete in your editor. Source lives in the public [`run402-core`](https://github.com/kychee-com/run402-core) repo under `packages/functions`; run402 Cloud consumes the published npm package when it bundles function zips. |
41
43
  | [`@run402/astro`](./astro/) | Astro integration for SSR, ISR cache, hosted auth components, and image variants |
42
44
 
43
- These interfaces share a single typed kernel where appropriate: `@run402/sdk`. MCP tools, CLI subcommands, and OpenClaw scripts are thin shims over SDK calls. `@run402/functions` is the in-function helper that runs inside deployed code; the npm package on the registry is the artifact Cloud bundles. `@run402/astro` layers the SDK and functions runtime into Astro's build and SSR flow. Pick whichever interface fits your runtime.
45
+ These interfaces share a single typed kernel where appropriate: `@run402/sdk`. MCP tools, CLI subcommands, and OpenClaw scripts are thin shims over SDK calls. `@run402/functions` is the in-function helper that runs inside deployed code; the npm package on the registry is the artifact Cloud bundles. `@run402/astro` layers the SDK and functions runtime into Astro's build and SSR flow. The HTTP API is the foundation; the SDK owns shared client workflows and orchestration; CLI and MCP expose them in machine-friendly forms. Native SDK/MCP references explain intentional alternatives.
46
+
47
+ Deployment summaries share the SDK workflow view. CLI writes redacted detail under `.run402/diagnostics/`; MCP retains it through `expand_result`. Typed SDK callers keep the full result. Snapshot collection excludes platform runtime files automatically.
44
48
 
45
49
  ## 30-second start
46
50
 
51
+ First create the complete `run402.json` and `index.html` from [Your first deploy](https://docs.run402.com/start/first-deploy/). Run these commands in that application directory; `--name` requests a new project.
52
+
47
53
  ```bash
48
54
  npm install -g run402@latest
49
55
  run402 up --name my-app -y # bootstrap allowance/tier/project/link, then deploy manifest
50
56
  run402 up verify # rerun app HTTP verification without deploying
51
57
  run402 up --verify # deploy, then wait for gateway/edge coherence
52
- run402 subdomains claim my-app # → https://my-app.run402.com
53
58
  ```
54
59
 
55
60
  That's a real Postgres database + a deployed static site, paid for autonomously with testnet USDC.
@@ -112,36 +117,13 @@ Helpers normalize to the same `ReleaseSpec` as JSON manifests. `dir()` walks det
112
117
 
113
118
  ### Paste-and-go assets: content-addressed URLs with SRI
114
119
 
115
- `assets.put()` returns an `AssetRef` whose `scriptTag()` / `linkTag()` / `imgTag()` emitters produce HTML with the URL, the SRI integrity hash, and modern best-practice attributes (`defer`, `loading="lazy"`, `decoding="async"`, `crossorigin`) already wired. The URL is content-addressed (`pr-<public_id>.run402.com/_blob/<key>-<8hex>.<ext>`), served through the CDN, and never needs invalidation:
116
-
117
- ```ts
118
- import { run402 } from "@run402/sdk/node";
119
- const r = run402();
120
- const p = await r.project(projectId);
120
+ Upload files with the CLI. Keep the returned AssetRef, including immutable identity and image variants, when saving references in application data. Do not reconstruct content hashes or variant URLs yourself.
121
121
 
122
- const logo = await p.assets.put("logo.png", { bytes: pngBytes });
123
- const app = await p.assets.put("app.js", { content: jsSource });
124
- const style = await p.assets.put("app.css", { content: css });
125
-
126
- const html = `
127
- <!doctype html>
128
- <html>
129
- <head>${style.linkTag()}${app.scriptTag({ type: "module" })}</head>
130
- <body>${logo.imgTag("Company logo")}</body>
131
- </html>
132
- `;
122
+ ```bash
123
+ run402 assets put ./logo.png ./app.js ./app.css --project prj_example
133
124
  ```
134
125
 
135
- Binary files must enter the SDK as bytes. In Node, use `readFile(path)` without
136
- an encoding; in browsers, use `File.arrayBuffer()`. Never read PNG, WASM,
137
- fonts, audio, video, archives, or other binary formats as UTF-8 and then hash
138
- or re-encode the resulting string: CAS can verify only the bytes it receives.
139
- The SDK rejects string sources for known binary keys/MIME types with
140
- `BINARY_CONTENT_REQUIRES_BYTES` before making a request. Directory helpers
141
- such as `fileSetFromDir`, `dir`, and `assets.uploadDir` are byte-safe by
142
- construction.
143
-
144
- `immutable: true` is the default: the SDK computes the SHA-256 client-side, the gateway returns a content-hashed URL, and the browser refuses execution on byte mismatch. No cache-invalidation choreography, no waiting, no integrity-attribute construction.
126
+ Use a manifest asset slice when these files must activate with a release. See the [storage guide](https://docs.run402.com/build/storage/) and [native SDK AssetRef helpers](https://docs.run402.com/sdk/patterns/) for HTML emitters and programmatic composition. Binary files must remain bytes; never read them as UTF-8 before uploading.
145
127
 
146
128
  ### Dark-by-default tables + the expose manifest
147
129
 
@@ -173,37 +155,23 @@ run402 projects get-expose <project_id>
173
155
 
174
156
  Built-in policies: `user_owns_rows` (rows where `owner_column = auth.uid()`; with `force_owner_on_insert: true` a BEFORE INSERT trigger sets it), `public_read_authenticated_write` (anyone reads, any authenticated user writes), `public_read_write_UNRESTRICTED` (fully open; requires `i_understand_this_is_unrestricted: true`), and `custom` (escape hatch: your own `CREATE POLICY` SQL).
175
157
 
176
- Use `run402 projects validate-expose` or the MCP `validate_manifest` tool for a non-mutating feedback loop before applying. Optional migration SQL is used only to check manifest references; it is not executed as a PostgreSQL dry run, and this does not validate deploy manifests.
158
+ Use `run402 projects validate-expose` for a non-mutating feedback loop before applying. Optional migration SQL is used only to check manifest references; it is not executed as a PostgreSQL dry run, and this does not validate deploy manifests.
177
159
 
178
160
  **Auth-as-SDLC:** put the same JSON under `database.expose` in your v2 `ReleaseSpec`. The gateway validates it against your migration SQL during deploy and rejects mismatches with a structured `errors` array listing every violation.
179
161
 
180
- ### Slick deploys: `deployDir` + plan/commit + progress
181
-
182
- `deployDir` walks a local directory, hashes every file client-side, asks the gateway _which_ bytes it doesn't already have, and PUTs only those. Re-deploying an unchanged tree returns immediately with `bytes_uploaded: 0`.
183
-
184
- ```ts
185
- import { run402 } from "@run402/sdk/node";
186
-
187
- const r = run402();
188
- const { url, bytes_uploaded, bytes_total } = await r.sites.deployDir({
189
- project: projectId,
190
- dir: "./dist",
191
- onEvent: (e) => process.stderr.write(JSON.stringify(e) + "\n"),
192
- });
193
- ```
194
-
195
- Progress events stream over `onEvent` (or stderr from the CLI) as unified
196
- `DeployEvent` JSON objects from the v2 deploy primitive.
162
+ ### Directory deployment (advanced primitive)
197
163
 
198
- CLI:
164
+ For a standalone static directory on an existing project:
199
165
 
200
166
  ```bash
201
- run402 sites deploy-dir ./dist --project prj_… > result.json 2> events.log
167
+ run402 sites deploy-dir ./dist --project prj_example > result.json 2> events.log
202
168
  ```
203
169
 
170
+ Use `run402 up` for a complete application with a deploy manifest. The SDK owns file hashing, upload deduplication and release orchestration; the CLI renders progress and the result.
171
+
204
172
  ### Same-origin web routes: static site + function ingress
205
173
 
206
- Apply-v1 routes and static public paths are release resources: they activate atomically with the site, functions, migrations, secrets, and subdomains in the same `deploy apply`. Release static asset paths such as `events.html` are distinct from browser-visible public static paths such as `/events`. Use `site.public_paths` for ordinary clean static URLs; keep routes for function ingress and exact, method-aware static aliases.
174
+ Apply-v1 routes and static public paths are release resources: the release pointer activates after the required deployment stages in `deploy apply`. Applied migrations and external side effects are not rolled back by changing that pointer. Release static asset paths such as `events.html` are distinct from browser-visible public static paths such as `/events`. Use `site.public_paths` for ordinary clean static URLs; keep routes for function ingress and exact, method-aware static aliases.
207
175
 
208
176
  ```json
209
177
  {
@@ -247,7 +215,7 @@ Apply-v1 routes and static public paths are release resources: they activate ato
247
215
 
248
216
  Omit `routes` or pass `routes: null` to carry forward base routes. Use `routes: { "replace": [] }` to clear the route table. Route entries are an ordered `replace` list, not a path-keyed map. Function targets use `{ "type": "function", "name": "<materialized function name>" }`. Static route targets use exact patterns only, methods `["GET"]` or `["GET","HEAD"]`, and `{ "pattern": "/events", "methods": ["GET","HEAD"], "target": { "type": "static", "file": "events.html" } }` where `file` is a release static asset path, not a public path, URL, CAS hash, rewrite, or redirect. Use static route targets for method-aware aliases such as static `GET /login` plus function `POST /login`; in explicit public path mode the backing asset can stay private by filename. Direct `/functions/v1/:name` calls remain API-key protected; browser-routed paths are public same-origin ingress.
249
217
 
250
- Function routes can charge a fixed tenant x402 price before the handler runs by adding `pricing: { "mode": "always", "amount_usd_micros": 250000, "pay_to": "org_default_payout" }` to the route entry. `250000` is $0.25 per matching action. The portable ReleaseSpec contract also accepts `receipt: "on_fulfillment"` on a priced function route; a compatible host then requires the function to return `payment.fulfilled(response)` before it authors a receipt. Run402-hosted advertising remains gated off until the standard delegated-signer carrier is available—receipt intent never silently downgrades. Omit `networks` for production mainnet only; include `"testnet"` explicitly for testnet acceptance. Static aliases cannot be priced, direct function invocation is not monetized, and service/admin keys do not bypass a priced browser route. The owning org must have a resolvable payout wallet: set it with `r.org(orgId).setPayoutWallet({ walletAddress })`, `run402 org payout-wallet <org_id> <wallet_address>`, or MCP `set_org_payout_wallet`. Conditional credit systems should expose one fixed-price route such as `POST /api/credits`, then keep the rest of the app behind unpriced routes and app-local authorization.
218
+ Function routes can charge a fixed tenant x402 price before the handler runs by adding `pricing: { "mode": "always", "amount_usd_micros": 250000, "pay_to": "org_default_payout" }` to the route entry. `250000` is $0.25 per matching action. The portable ReleaseSpec contract also accepts `receipt: "on_fulfillment"` on a priced function route; a compatible host then requires the function to return `payment.fulfilled(response)` before it authors a receipt. Run402-hosted advertising remains gated off until the standard delegated-signer carrier is available—receipt intent never silently downgrades. Omit `networks` for production mainnet only; include `"testnet"` explicitly for testnet acceptance. Static aliases cannot be priced, direct function invocation is not monetized, and service/admin keys do not bypass a priced browser route. The owning org must have a resolvable payout wallet: set it with `run402 org payout-wallet <org_id> <wallet_address>`. Conditional credit systems should expose one fixed-price route such as `POST /api/credits`, then keep the rest of the app behind unpriced routes and app-local authorization.
251
219
 
252
220
  Matching is exact or final-prefix-wildcard only. `/admin` and `/admin/` are exact trailing-slash equivalents; `/admin/*` matches children but not `/admin`, `/admin/`, `/admin.css`, or `/administrator`, so deploy both `/admin` and `/admin/*` for a routed section root. Query strings are ignored for matching and preserved in the handler's full public `req.url`. Exact routes beat prefix routes; longest prefix wins; method-compatible dynamic routes beat static assets. A `POST /login` route can coexist with static `GET /login` HTML. Unsafe method mismatch returns `405`, and matched dynamic route failures fail closed instead of falling back to static files.
253
221
 
@@ -326,22 +294,7 @@ export default async (req: Request) => {
326
294
  };
327
295
  ```
328
296
 
329
- `adminDb().sql(query, params?)` runs raw parameterized SQL and always bypasses RLS. It returns a flat `Promise<Record<string, unknown>[]>` (just the rows, no envelope):
330
-
331
- ```ts
332
- import { adminDb, auth } from "@run402/functions";
333
-
334
- export default async (req: Request) => {
335
- const user = await auth.requireUser();
336
-
337
- const rows = await adminDb().sql(
338
- "SELECT count(*)::int AS n FROM items WHERE user_id = $1",
339
- [user.id],
340
- );
341
- const n = (rows[0]?.n as number | undefined) ?? 0;
342
- return Response.json({ count: n });
343
- };
344
- ```
297
+ `adminDb().sql(query, params?)` runs raw parameterized SQL and always bypasses RLS. The current runtime returns the gateway envelope, including `rows` and `row_count`; read `result.rows`, not `result[0]`. Older helper typings incorrectly described a bare array. See the [owning runtime reference](https://github.com/kychee-com/run402-core/tree/main/packages/functions#admindbsqlquery-params--raw-sql-bypassrls) and match local helper types to the runtime version used by your deployment.
345
298
 
346
299
  `@run402/functions` is auto-bundled into deployed code; install it in your editor for full TypeScript autocomplete (also works at build time for static-site generation with `RUN402_SERVICE_KEY` + `RUN402_PROJECT_ID` set).
347
300
 
@@ -349,13 +302,10 @@ export default async (req: Request) => {
349
302
 
350
303
  `assets.put(key, source, opts?)` uploads bytes from inside a deployed function through the same CAS-backed apply substrate as deploy-time assets. It uses `RUN402_SERVICE_KEY`, accepts a string, `Uint8Array`, or `{ content | bytes }`, and returns an SDK-compatible `AssetRef` with mutable and immutable URLs.
351
304
 
352
- **Calling from outside a function entirely** (raw `curl`/`fetch` from CI scripts, bash bootstrappers, non-TS runtimes): service-key writes go to `/admin/v1/rest/<table>`, not `/rest/v1/*`. The gateway 403s service-role tokens on `/rest/v1/*` so a leaked key can't silently bypass RLS, which means `curl ... > /dev/null` against the wrong path looks like success but writes nothing. SQL-shaped admin work uses `POST /projects/v1/admin/:id/sql` (or `run402 projects sql`).
305
+ **Operating data from outside a function:** use the CLI with an explicit project. For deliberate HTTP integrations, the [native HTTP reference](https://run402.com/llms-full.txt) distinguishes administrative REST from caller-scoped REST. Never expose a service key to the browser.
353
306
 
354
307
  ```bash
355
- curl -X POST https://api.run402.com/admin/v1/rest/audit \
356
- -H "Authorization: Bearer $RUN402_SERVICE_KEY" \
357
- -H "Content-Type: application/json" \
358
- -d '{"event":"seed","ts":"2026-04-30"}'
308
+ run402 projects sql prj_example "SELECT count(*) FROM audit"
359
309
  ```
360
310
 
361
311
  ### repos: your repository history, encrypted before it leaves the machine
@@ -424,14 +374,7 @@ Before `snapshot` reports that anything landed, the client compares every finali
424
374
 
425
375
  From the SDK, with identical semantics — vault reads run anywhere, and the verbs that touch a git working tree or the on-disk keystore are Node-only:
426
376
 
427
- ```ts
428
- import { run402 } from "@run402/sdk/node";
429
- const r = run402();
430
-
431
- const vault = await r.gitvault.forProject(projectId); // cold restart: no local state needed
432
- const pushed = await r.gitvault.push({ project_id: projectId, snapshot: { message: "wip" } });
433
- const state = await r.gitvault.verify({ project_id: projectId });
434
- ```
377
+ For typed repository automation, see the [native SDK gitvault reference](https://docs.run402.com/sdk/resources/).
435
378
 
436
379
  **The encrypted second remote — the zero-migration pattern.** Keep GitHub/GitLab as the primary (collaboration, CI, reviews, unchanged) and add GitVault as the second remote: `git remote add gitvault run402::<org_id>/<project_id>` + `git push gitvault --all`, and a complete, continuously updated copy of your history exists that the storage provider itself cannot read. The reason this matters, said plainly and as capability rather than accusation: a host that can READ private repositories can — under a future policy, an acquisition, a training pipeline, a subpoena, or a breach — index them, train models on them, or hand them to someone who will. Run402 cannot decrypt your gitvault or repository history. Deployment artifacts remain a disclosed plaintext custody boundary.
437
380
 
@@ -491,12 +434,12 @@ Two entry points:
491
434
  import { run402 } from "@run402/sdk/node";
492
435
 
493
436
  const r = run402();
494
- const project = await r.projects.provision({ tier: "prototype" });
495
- const p = await r.project(project.project_id);
496
- await p.assets.put("hello.txt", { content: "hi" });
437
+ // Prepare the complete first-deploy manifest and referenced app files.
438
+ const result = await r.up({ name: "my-app", manifest: "run402.json" }, { approval: "yes" });
439
+ console.log(result);
497
440
  ```
498
441
 
499
- The SDK is organised into focused namespaces: `actions` (Node recursive action runner), `pay` (bounded arbitrary-URL x402 buyer), `projects`, `snapshots`, `branches`, `archives`, `assets`, `cache`, `ci`, `sites`, `functions`, `jobs`, `secrets`, `subdomains`, `domains`, `email` (+ `webhooks`), `auth`, `apps`, `tier`, `billing`, `contracts`, `ai`, `allowance`, `service`, `admin`, `operator` (the human/email operator session: browser-delegated `login` + `overview` across every wallet that verified your email), `wallets` (signed server-side wallet label), `orgs` (org-owned control plane + `r.org(id)` sub-client), `grants` (per-project capability grants), and `identityLinks` (public, protocol-discriminated human/agent Nostr attribution), plus the `r.project(id).apply` hero for atomic mixed writes (release slices + assets slice via `/apply/v1/*`). Every operation throws a typed `Run402Error` subclass on failure: `PaymentRequired`, `PaymentBuyerError`, `ProjectNotFound`, `Unauthorized`, `ApiError`, `NetworkError`, `LocalError`, `Run402DeployError`. `apply()` automatically re-plans safe current-base `BASE_RELEASE_CONFLICT` races and emits `apply.retry` progress events. See [`sdk/README.md`](./sdk/README.md).
442
+ The SDK is organised into focused namespaces: `actions` (Node recursive action runner), `pay` (bounded arbitrary-URL x402 buyer), `projects`, `snapshots`, `branches`, `archives`, `assets`, `cache`, `ci`, `sites`, `functions`, `jobs`, `secrets`, `subdomains`, `domains`, `email` (+ `webhooks`), `auth`, `apps`, `tier`, `billing`, `contracts`, `ai`, `allowance`, `service`, `admin`, `operator` (the human/email operator session: browser-delegated `login` + `overview` across every wallet that verified your email), `wallets` (signed server-side wallet label), `orgs` (org-owned control plane + `r.org(id)` sub-client), `grants` (per-project capability grants), and `identityLinks` (public, protocol-discriminated human/agent Nostr attribution), plus `const project = await r.project(id); await project.apply(spec)` for staged multi-resource writes (release slices + assets slice via `/apply/v1/*`). Every operation throws a typed `Run402Error` subclass on failure: `PaymentRequired`, `PaymentBuyerError`, `ProjectNotFound`, `Unauthorized`, `ApiError`, `NetworkError`, `LocalError`, `Run402DeployError`. `apply()` automatically re-plans safe current-base `BASE_RELEASE_CONFLICT` races and emits `apply.retry` progress events. See [`sdk/README.md`](./sdk/README.md).
500
443
 
501
444
  ## Buzz/Nostr identity links
502
445
 
@@ -1 +1 @@
1
- {"version":3,"file":"app-up.d.ts","sourceRoot":"","sources":["../../src/tools/app-up.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;CAgBvB,CAAC;AAEF,KAAK,SAAS,GAAG;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAEvF,wBAAsB,WAAW,CAAC,IAAI,EAAE;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,GAAG,MAAM,CAAC;IACtC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,SAAS,CAAC;IAC5C,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GAAG,OAAO,CAAC,SAAS,CAAC,CA6BrB"}
1
+ {"version":3,"file":"app-up.d.ts","sourceRoot":"","sources":["../../src/tools/app-up.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;CAgBvB,CAAC;AAEF,KAAK,SAAS,GAAG;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAEvF,wBAAsB,WAAW,CAAC,IAAI,EAAE;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,GAAG,MAAM,CAAC;IACtC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,SAAS,CAAC;IAC5C,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GAAG,OAAO,CAAC,SAAS,CAAC,CAgCrB"}
@@ -1,3 +1,5 @@
1
+ import { storeResult } from "../result-store.js";
2
+ import { prepareWorkflowOutput } from "@run402/sdk/node";
1
3
  import { z } from "zod";
2
4
  import { getSdk } from "../sdk.js";
3
5
  import { mapSdkError } from "../errors.js";
@@ -41,7 +43,10 @@ export async function handleAppUp(args) {
41
43
  return {
42
44
  content: [{
43
45
  type: "text",
44
- text: JSON.stringify(result.result?.app_result ?? result, null, 2),
46
+ text: JSON.stringify(prepareWorkflowOutput(result, args.dir ?? process.cwd(), { storeDetails: (detail) => {
47
+ const stored = storeResult("app_up", [detail], { shown: 0 });
48
+ return stored.ref ? { ref: stored.ref, next_action: { type: "expand_result", ref: stored.ref, why: "Read the redacted detail for this execution with expand_result." } } : null;
49
+ } }), null, 2),
45
50
  }],
46
51
  };
47
52
  }
@@ -1 +1 @@
1
- {"version":3,"file":"app-up.js","sourceRoot":"","sources":["../../src/tools/app-up.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"app-up.js","sourceRoot":"","sources":["../../src/tools/app-up.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACnC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sFAAsF,CAAC;IAC9H,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,mDAAmD,CAAC;IACzF,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sCAAsC,CAAC;IAClF,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,wFAAwF,CAAC;IAClI,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,wDAAwD,CAAC;IAC7F,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,gDAAgD,CAAC;IAClH,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,8FAA8F,CAAC;IACxI,GAAG,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,uEAAuE,CAAC;IAC7G,WAAW,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,mDAAmD,CAAC;IACjG,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,uDAAuD,CAAC;IACpH,UAAU,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,0BAA0B,CAAC;IAClG,iBAAiB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,mDAAmD,CAAC;IACvG,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,4DAA4D,CAAC;IAC7G,WAAW,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,ubAAub,CAAC;IACre,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,slBAAslB,CAAC;CACppB,CAAC;AAIF,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAgBjC;IACC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,MAAM,EAAE,CAAC,EAAE,CAAC;YAC/B,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACjD,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACjE,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,SAAS,EAAE,IAAI,CAAC,UAAU;YAC1B,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,cAAc,EAAE,IAAI,CAAC,eAAe;YACpC,UAAU,EAAE,IAAI,CAAC,WAAW;YAC5B,WAAW,EAAE,IAAI,CAAC,aAAa;YAC/B,SAAS,EAAE,IAAI,CAAC,UAAU;YAC1B,eAAe,EAAE,IAAI,CAAC,iBAAiB;SACxC,EAAE;YACD,MAAM,EAAE,IAAI,CAAC,OAAO,KAAK,IAAI;YAC7B,QAAQ,EAAE,IAAI,CAAC,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO;SAC9C,CAAC,CAAC;QACH,OAAO;YACL,OAAO,EAAE,CAAC;oBACR,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,qBAAqB,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,EAAE,EAAE,YAAY,EAAE,CAAC,MAAM,EAAE,EAAE;4BACvG,MAAM,MAAM,GAAG,WAAW,CAAC,QAAQ,EAAE,CAAC,MAAM,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;4BAC7D,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,WAAW,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,iEAAiE,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;wBAClL,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;iBACf,CAAC;SACH,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,WAAW,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC;IAC5C,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "run402-mcp",
3
- "version": "4.88.0",
3
+ "version": "4.90.0",
4
4
  "packageManager": "npm@11.19.0",
5
5
  "mcpName": "com.run402/mcp",
6
6
  "description": "MCP server for Run402 — full-stack backend infrastructure for AI agents: Postgres, auth, storage, serverless functions and atomic deploys. Paid with x402/MPP. Includes $0.03 image generation.",
@@ -34,14 +34,15 @@
34
34
  "test:buzz-installer": "node buzz/install-smoke.mjs",
35
35
  "test:sync": "node --test --import tsx sync.test.ts examples/tenant-x402-wallet-stats/example.test.mjs examples/static-config-js/example.test.mjs",
36
36
  "test:run402-app-schema-drift": "node scripts/check-run402-app-schema-drift.mjs",
37
- "test:docs": "node scripts/check-typed-config-docs.mjs && npm run check:docs --workspace=@run402/sdk -- --skip-build",
37
+ "test:docs": "node scripts/check-typed-config-docs.mjs && npm run check:docs --workspace=@run402/sdk -- --skip-build && npm run test:docs:quality",
38
38
  "test": "npm run build && node scripts/build-agent-skills-index.mjs --check && node scripts/build-gitvault-surface.mjs --check && node --experimental-test-module-mocks --test --import tsx SKILL.test.ts sync.test.ts buzz/setup.test.mjs buzz/helper.test.mjs buzz/package.test.mjs scripts/build-agent-skills-index.test.mjs scripts/build-agent-flat-docs.test.mjs scripts/build-gitvault-surface.test.mjs examples/tenant-x402-wallet-stats/example.test.mjs examples/static-config-js/example.test.mjs 'core/src/**/*.test.ts' 'sdk/src/**/*.test.ts' 'src/**/*.test.ts' && node --test cli-core-target.test.mjs && node --experimental-test-module-mocks --test cli-up-argv.test.mjs cli-up-repo-compose.test.mjs cli-repos-surface.test.mjs cli-gitvault-retired.test.mjs cli-projects-gitvault-scaffold.test.mjs cli-identity-link.test.mjs cli-identity-link-matrix.test.mjs cli-redeem.test.mjs cli-rooms-context-session-key.test.mjs cli-messages-wait.test.mjs cli-rooms-invite-key-leak.test.mjs cli-rooms-join-arrival.test.mjs cli/lib/buzz.test.mjs && node --test cli-help-listing.test.mjs cli-module-references.test.mjs cli-output-contract.test.mjs cli-json-noop-contract.test.mjs cli-e2e.test.mjs cli-help.test.mjs cli-provision-active.test.mjs cli-typed-config-modes.test.mjs cli-argv.test.mjs cli-gitvault-retired.test.mjs cli-conventions-gate.test.mjs cli-doctor.test.mjs cli-rest-diagnostics.test.mjs cli-credentials.test.mjs paid-stack-deps.test.mjs profile-guidance.test.mjs settlement-disclosure.test.mjs cli-suggestions-gate.test.mjs cli-env.test.mjs cli-wallets.test.mjs cli-org.test.mjs cli-org-context.test.mjs cli-image-org.test.mjs cli-harness-context.test.mjs cli-ci.test.mjs cli-deploy-ci.test.mjs cli-operator-loopback.test.mjs cli-gitvault-remote-helper.test.mjs cli-gitvault-daemon.test.mjs cli-deploy-gitvault-lane.test.mjs cli/lib/buzz-doctor-contract.test.mjs cli/lib/buzz-doctor.test.mjs cli/lib/diagnostic-telemetry.test.mjs cli/lib/doctor-source-scan.test.mjs cli/lib/errors.test.mjs cli/lib/path-lookup.test.mjs cli/lib/pay.test.mjs cli/lib/up.test.mjs cli/lib/deploy-rehearse-discovery.test.mjs cli/lib/update-check.test.mjs cli-bootstrap-next-actions.test.mjs cli-sdk-errors-room-invite-hint.test.mjs && npm run test:docs",
39
39
  "test:e2e": "npm run build && node --test cli-core-target.test.mjs && node --experimental-test-module-mocks --test cli-repos-surface.test.mjs cli-gitvault-retired.test.mjs cli-up-repo-compose.test.mjs cli-projects-gitvault-scaffold.test.mjs cli-identity-link.test.mjs cli-identity-link-matrix.test.mjs cli-redeem.test.mjs cli-rooms-context-session-key.test.mjs cli-messages-wait.test.mjs cli-rooms-invite-key-leak.test.mjs cli-rooms-join-arrival.test.mjs && node --test cli-help-listing.test.mjs cli-module-references.test.mjs cli-output-contract.test.mjs cli-json-noop-contract.test.mjs cli-e2e.test.mjs cli-help.test.mjs cli-provision-active.test.mjs cli-typed-config-modes.test.mjs cli-argv.test.mjs cli-gitvault-retired.test.mjs cli-conventions-gate.test.mjs cli-doctor.test.mjs cli-rest-diagnostics.test.mjs cli-credentials.test.mjs paid-stack-deps.test.mjs profile-guidance.test.mjs settlement-disclosure.test.mjs cli-suggestions-gate.test.mjs cli-env.test.mjs cli-wallets.test.mjs cli-org.test.mjs cli-org-context.test.mjs cli-image-org.test.mjs cli-harness-context.test.mjs cli-ci.test.mjs cli-deploy-ci.test.mjs cli-operator-loopback.test.mjs cli-gitvault-remote-helper.test.mjs cli-gitvault-daemon.test.mjs cli-deploy-gitvault-lane.test.mjs cli/lib/buzz-doctor-contract.test.mjs cli/lib/buzz-doctor.test.mjs cli/lib/diagnostic-telemetry.test.mjs cli/lib/doctor-source-scan.test.mjs cli/lib/errors.test.mjs cli/lib/path-lookup.test.mjs cli/lib/up.test.mjs cli/lib/update-check.test.mjs cli-bootstrap-next-actions.test.mjs cli-sdk-errors-room-invite-hint.test.mjs",
40
40
  "test:help": "npm run build && node --test cli-help.test.mjs",
41
41
  "test:integration": "node --test --import tsx core/src/siwx-integration.integ.ts",
42
42
  "test:integration:full": "node --test --import tsx cli-integration.test.ts",
43
43
  "test:integration:mcp": "node --test --import tsx mcp-integration.test.ts",
44
- "test:integration:fullstack": "npm run build && node --test --import tsx fullstack-integration.test.ts"
44
+ "test:integration:fullstack": "npm run build && node --test --import tsx fullstack-integration.test.ts",
45
+ "test:docs:quality": "node scripts/documentation-inventory.mjs && node scripts/check-doc-examples.mjs && node scripts/build-error-docs.mjs --check && node scripts/build-reference-schemas.mjs --check && node --test --import tsx scripts/documentation-quality.test.mjs scripts/documentation-examples.test.ts"
45
46
  },
46
47
  "keywords": [
47
48
  "mcp",
@@ -90,6 +91,7 @@
90
91
  "devDependencies": {
91
92
  "@run402/functions": "^3.7.0",
92
93
  "@types/node": "^22.0.0",
94
+ "ajv": "8.18.0",
93
95
  "tsx": "^4.19.0",
94
96
  "typescript": "^6.0.3",
95
97
  "yaml": "^2.8.2"