run402 4.93.2 → 4.95.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 +61 -59
- package/cli.mjs +40 -47
- package/core-dist/config.js +52 -18
- package/core-dist/control-plane-session.js +31 -6
- package/core-dist/keystore.js +7 -7
- package/core-dist/profiles.js +9 -7
- package/core-dist/{allowance-auth.js → wallet-auth.js} +15 -15
- package/{sdk/core-dist/allowance.js → core-dist/wallet.js} +20 -20
- package/{sdk/core-dist/write-auth-session.js → core-dist/write-approvals.js} +19 -19
- package/gitvault-surface.json +2 -2
- package/lib/admin.mjs +6 -6
- package/lib/agent.mjs +20 -18
- package/lib/ai.mjs +5 -5
- package/lib/approve.mjs +81 -0
- package/lib/apps.mjs +12 -12
- package/lib/archives.mjs +371 -8
- package/lib/argparse.mjs +5 -5
- package/lib/assets.mjs +14 -14
- package/lib/auth.mjs +34 -34
- package/lib/billing.mjs +6 -6
- package/lib/branches.mjs +7 -7
- package/lib/buzz-doctor.mjs +2 -2
- package/lib/buzz-notifications.mjs +5 -5
- package/lib/buzz.mjs +3 -3
- package/lib/buzz.test.mjs +1 -1
- package/lib/cache.mjs +1 -1
- package/lib/cdn.mjs +2 -2
- package/lib/ci.mjs +12 -12
- package/lib/claims.mjs +2 -2
- package/lib/cold-start.mjs +21 -21
- package/lib/command-manifest.mjs +55 -70
- package/lib/config.mjs +28 -28
- package/lib/contacts.mjs +16 -16
- package/lib/contracts.mjs +12 -12
- package/lib/credentials.mjs +33 -33
- package/lib/daemon-path.mjs +1 -1
- package/lib/delegates.mjs +14 -14
- package/lib/deliveries.mjs +6 -6
- package/lib/deploy-rehearse-discovery.test.mjs +7 -7
- package/lib/deploy-v2.mjs +241 -193
- package/lib/deploy.mjs +21 -53
- package/lib/dev.mjs +3 -3
- package/lib/doctor-source-scan.mjs +1 -1
- package/lib/doctor.mjs +63 -63
- package/lib/domains.mjs +27 -27
- package/lib/email.mjs +38 -38
- package/lib/errors.mjs +40 -24
- package/lib/escalations.mjs +5 -5
- package/lib/events.mjs +32 -25
- package/lib/feedback.mjs +12 -12
- package/lib/functions.mjs +34 -34
- package/lib/gitvault-daemon.mjs +1 -1
- package/lib/gitvault-scaffold.mjs +2 -2
- package/lib/gitvault.mjs +2 -2
- package/lib/grants.mjs +7 -7
- package/lib/image.mjs +10 -10
- package/lib/init.mjs +69 -69
- package/lib/jobs.mjs +15 -15
- package/lib/lightning-wallet.mjs +28 -28
- package/lib/live.mjs +1 -1
- package/lib/login.mjs +207 -0
- package/lib/logout.mjs +53 -0
- package/lib/logs.mjs +8 -8
- package/lib/messages.mjs +5 -5
- package/lib/next-actions.mjs +16 -16
- package/lib/org-context.mjs +13 -13
- package/lib/{org.mjs → orgs.mjs} +215 -167
- package/lib/pay.mjs +1 -1
- package/lib/projects.mjs +70 -84
- package/lib/redeem.mjs +7 -8
- package/lib/remote-helper-session.mjs +12 -12
- package/lib/repos.mjs +83 -83
- package/lib/rooms.mjs +105 -69
- package/lib/sdk-errors.mjs +10 -5
- package/lib/sdk.mjs +3 -3
- package/lib/secrets.mjs +13 -13
- package/lib/service.mjs +5 -5
- package/lib/session-proofs.mjs +21 -0
- package/lib/sign-in.mjs +296 -0
- package/lib/sites.mjs +22 -22
- package/lib/snapshots.mjs +10 -10
- package/lib/stats.mjs +2 -2
- package/lib/status.mjs +25 -25
- package/lib/subdomains.mjs +30 -30
- package/lib/subscriptions.mjs +10 -10
- package/lib/tier.mjs +29 -22
- package/lib/transfer.mjs +59 -86
- package/lib/up.mjs +14 -14
- package/lib/wallet-context.mjs +4 -4
- package/lib/wallet-context.test.mjs +3 -3
- package/lib/wallets.mjs +197 -32
- package/lib/webhook-secret.mjs +6 -6
- package/lib/webhooks.mjs +8 -8
- package/lib/whoami.mjs +102 -0
- package/package.json +1 -1
- package/sdk/core-dist/config.js +52 -18
- package/sdk/core-dist/control-plane-session.js +31 -6
- package/sdk/core-dist/keystore.js +7 -7
- package/sdk/core-dist/profiles.js +9 -7
- package/sdk/core-dist/{allowance-auth.js → wallet-auth.js} +15 -15
- package/{core-dist/allowance.js → sdk/core-dist/wallet.js} +20 -20
- package/{core-dist/write-auth-session.js → sdk/core-dist/write-approvals.js} +19 -19
- package/sdk/dist/actions.d.ts +4 -4
- package/sdk/dist/actions.d.ts.map +1 -1
- package/sdk/dist/app-up.d.ts +2 -2
- package/sdk/dist/app-up.d.ts.map +1 -1
- package/sdk/dist/config.d.ts +1 -2
- package/sdk/dist/config.d.ts.map +1 -1
- package/sdk/dist/config.js.map +1 -1
- package/sdk/dist/control-plane-credentials.d.ts +8 -8
- package/sdk/dist/control-plane-credentials.js +7 -7
- package/sdk/dist/credentials.d.ts +20 -20
- package/sdk/dist/credentials.d.ts.map +1 -1
- package/sdk/dist/credentials.js +1 -1
- package/sdk/dist/errors.d.ts +26 -28
- package/sdk/dist/errors.d.ts.map +1 -1
- package/sdk/dist/errors.js +35 -38
- package/sdk/dist/errors.js.map +1 -1
- package/sdk/dist/index.d.ts +29 -16
- package/sdk/dist/index.d.ts.map +1 -1
- package/sdk/dist/index.js +30 -17
- package/sdk/dist/index.js.map +1 -1
- package/sdk/dist/kernel.d.ts +1 -1
- package/sdk/dist/kernel.d.ts.map +1 -1
- package/sdk/dist/kernel.js +10 -9
- package/sdk/dist/kernel.js.map +1 -1
- package/sdk/dist/namespaces/admin.d.ts +52 -121
- package/sdk/dist/namespaces/admin.d.ts.map +1 -1
- package/sdk/dist/namespaces/admin.js +41 -45
- package/sdk/dist/namespaces/admin.js.map +1 -1
- package/sdk/dist/namespaces/agent.d.ts +2 -2
- package/sdk/dist/namespaces/agent.d.ts.map +1 -1
- package/sdk/dist/namespaces/agent.js +2 -2
- package/sdk/dist/namespaces/agent.js.map +1 -1
- package/sdk/dist/namespaces/ai.d.ts +2 -2
- package/sdk/dist/namespaces/ai.js +3 -3
- package/sdk/dist/namespaces/ai.js.map +1 -1
- package/sdk/dist/namespaces/assets.js +1 -1
- package/sdk/dist/namespaces/assets.js.map +1 -1
- package/sdk/dist/namespaces/billing.d.ts +6 -3
- package/sdk/dist/namespaces/billing.d.ts.map +1 -1
- package/sdk/dist/namespaces/billing.js.map +1 -1
- package/sdk/dist/namespaces/buzz-notifications.types.d.ts +1 -1
- package/sdk/dist/namespaces/buzz.d.ts +2 -2
- package/sdk/dist/namespaces/buzz.d.ts.map +1 -1
- package/sdk/dist/namespaces/buzz.js +2 -2
- package/sdk/dist/namespaces/buzz.js.map +1 -1
- package/sdk/dist/namespaces/buzz.types.d.ts +2 -2
- package/sdk/dist/namespaces/buzz.types.d.ts.map +1 -1
- package/sdk/dist/namespaces/ci.js +3 -3
- package/sdk/dist/namespaces/ci.js.map +1 -1
- package/sdk/dist/namespaces/credentials.types.d.ts +1 -1
- package/sdk/dist/namespaces/deploy.d.ts +1 -1
- package/sdk/dist/namespaces/deploy.d.ts.map +1 -1
- package/sdk/dist/namespaces/deploy.js +31 -32
- package/sdk/dist/namespaces/deploy.js.map +1 -1
- package/sdk/dist/namespaces/deploy.types.d.ts +6 -6
- package/sdk/dist/namespaces/deploy.types.d.ts.map +1 -1
- package/sdk/dist/namespaces/domains.d.ts +10 -2
- package/sdk/dist/namespaces/domains.d.ts.map +1 -1
- package/sdk/dist/namespaces/domains.js +10 -5
- package/sdk/dist/namespaces/domains.js.map +1 -1
- package/sdk/dist/namespaces/errors.js +1 -1
- package/sdk/dist/namespaces/escalations.d.ts +1 -1
- package/sdk/dist/namespaces/escalations.js +1 -1
- package/sdk/dist/namespaces/escalations.types.d.ts +2 -2
- package/sdk/dist/namespaces/escalations.types.d.ts.map +1 -1
- package/sdk/dist/namespaces/events.types.d.ts +1 -1
- package/sdk/dist/namespaces/functions.d.ts +1 -1
- package/sdk/dist/namespaces/functions.js +2 -2
- package/sdk/dist/namespaces/functions.js.map +1 -1
- package/sdk/dist/namespaces/gitvault.crypto.d.ts +1 -1
- package/sdk/dist/namespaces/gitvault.d.ts +26 -26
- package/sdk/dist/namespaces/gitvault.d.ts.map +1 -1
- package/sdk/dist/namespaces/gitvault.js +113 -113
- package/sdk/dist/namespaces/gitvault.js.map +1 -1
- package/sdk/dist/namespaces/me.d.ts +120 -0
- package/sdk/dist/namespaces/me.d.ts.map +1 -0
- package/sdk/dist/namespaces/me.js +34 -0
- package/sdk/dist/namespaces/me.js.map +1 -0
- package/sdk/dist/namespaces/org.d.ts +108 -6
- package/sdk/dist/namespaces/org.d.ts.map +1 -1
- package/sdk/dist/namespaces/org.js +63 -7
- package/sdk/dist/namespaces/org.js.map +1 -1
- package/sdk/dist/namespaces/org.types.d.ts +29 -9
- package/sdk/dist/namespaces/org.types.d.ts.map +1 -1
- package/sdk/dist/namespaces/pay.js +3 -3
- package/sdk/dist/namespaces/pay.js.map +1 -1
- package/sdk/dist/namespaces/projects.d.ts +9 -9
- package/sdk/dist/namespaces/projects.js +15 -15
- package/sdk/dist/namespaces/projects.js.map +1 -1
- package/sdk/dist/namespaces/projects.types.d.ts +28 -12
- package/sdk/dist/namespaces/projects.types.d.ts.map +1 -1
- package/sdk/dist/namespaces/rooms.d.ts +7 -7
- package/sdk/dist/namespaces/rooms.js +17 -17
- package/sdk/dist/namespaces/rooms.js.map +1 -1
- package/sdk/dist/namespaces/rooms.types.d.ts +9 -9
- package/sdk/dist/namespaces/rooms.types.d.ts.map +1 -1
- package/sdk/dist/namespaces/service.d.ts +1 -1
- package/sdk/dist/namespaces/service.js +1 -1
- package/sdk/dist/namespaces/{operator-session.d.ts → session.d.ts} +135 -51
- package/sdk/dist/namespaces/session.d.ts.map +1 -0
- package/sdk/dist/namespaces/{operator-session.js → session.js} +118 -30
- package/sdk/dist/namespaces/session.js.map +1 -0
- package/sdk/dist/namespaces/subdomains.d.ts +5 -5
- package/sdk/dist/namespaces/subdomains.d.ts.map +1 -1
- package/sdk/dist/namespaces/subdomains.js +6 -6
- package/sdk/dist/namespaces/subdomains.js.map +1 -1
- package/sdk/dist/namespaces/tier.d.ts +44 -21
- package/sdk/dist/namespaces/tier.d.ts.map +1 -1
- package/sdk/dist/namespaces/tier.js +7 -7
- package/sdk/dist/namespaces/tier.js.map +1 -1
- package/sdk/dist/namespaces/transfers.d.ts +119 -85
- package/sdk/dist/namespaces/transfers.d.ts.map +1 -1
- package/sdk/dist/namespaces/transfers.js +31 -38
- package/sdk/dist/namespaces/transfers.js.map +1 -1
- package/sdk/dist/namespaces/vouchers.d.ts +9 -10
- package/sdk/dist/namespaces/vouchers.d.ts.map +1 -1
- package/sdk/dist/namespaces/vouchers.js +4 -5
- package/sdk/dist/namespaces/vouchers.js.map +1 -1
- package/sdk/dist/namespaces/wallets.d.ts +72 -3
- package/sdk/dist/namespaces/wallets.d.ts.map +1 -1
- package/sdk/dist/namespaces/wallets.js +141 -3
- package/sdk/dist/namespaces/wallets.js.map +1 -1
- package/sdk/dist/namespaces/write-approval.d.ts +101 -0
- package/sdk/dist/namespaces/write-approval.d.ts.map +1 -0
- package/sdk/dist/namespaces/write-approval.js +62 -0
- package/sdk/dist/namespaces/write-approval.js.map +1 -0
- package/sdk/dist/node/actions-node.d.ts +3 -3
- package/sdk/dist/node/actions-node.d.ts.map +1 -1
- package/sdk/dist/node/actions-node.js +44 -44
- package/sdk/dist/node/actions-node.js.map +1 -1
- package/sdk/dist/node/assets-node.js +6 -6
- package/sdk/dist/node/assets-node.js.map +1 -1
- package/sdk/dist/node/{bearer-claim-key.d.ts → bearer-redeem-key.d.ts} +12 -12
- package/sdk/dist/node/bearer-redeem-key.d.ts.map +1 -0
- package/sdk/dist/node/{bearer-claim-key.js → bearer-redeem-key.js} +21 -21
- package/sdk/dist/node/bearer-redeem-key.js.map +1 -0
- package/sdk/dist/node/ci.d.ts +1 -1
- package/sdk/dist/node/ci.d.ts.map +1 -1
- package/sdk/dist/node/ci.js +6 -6
- package/sdk/dist/node/ci.js.map +1 -1
- package/sdk/dist/node/credentials.d.ts +18 -17
- package/sdk/dist/node/credentials.d.ts.map +1 -1
- package/sdk/dist/node/credentials.js +29 -28
- package/sdk/dist/node/credentials.js.map +1 -1
- package/sdk/dist/node/deploy-manifest.d.ts +3 -5
- package/sdk/dist/node/deploy-manifest.d.ts.map +1 -1
- package/sdk/dist/node/deploy-manifest.js +3 -12
- package/sdk/dist/node/deploy-manifest.js.map +1 -1
- package/sdk/dist/node/funding-recovery.d.ts +1 -1
- package/sdk/dist/node/funding-recovery.d.ts.map +1 -1
- package/sdk/dist/node/funding-recovery.js +1 -1
- package/sdk/dist/node/funding-recovery.js.map +1 -1
- package/sdk/dist/node/gitvault-apply.d.ts +1 -1
- package/sdk/dist/node/gitvault-apply.d.ts.map +1 -1
- package/sdk/dist/node/gitvault-apply.js +1 -1
- package/sdk/dist/node/gitvault-apply.js.map +1 -1
- package/sdk/dist/node/gitvault-handoff.d.ts +22 -22
- package/sdk/dist/node/gitvault-handoff.d.ts.map +1 -1
- package/sdk/dist/node/gitvault-handoff.js +45 -45
- package/sdk/dist/node/gitvault-handoff.js.map +1 -1
- package/sdk/dist/node/gitvault-prewarm.js +7 -7
- package/sdk/dist/node/gitvault-prewarm.js.map +1 -1
- package/sdk/dist/node/gitvault-restore.d.ts +1 -1
- package/sdk/dist/node/gitvault-restore.js +1 -1
- package/sdk/dist/node/index.d.ts +16 -16
- package/sdk/dist/node/index.d.ts.map +1 -1
- package/sdk/dist/node/index.js +15 -15
- package/sdk/dist/node/index.js.map +1 -1
- package/sdk/dist/node/manifest-export.js +2 -2
- package/sdk/dist/node/manifest-export.js.map +1 -1
- package/sdk/dist/node/org-adopt.d.ts +49 -0
- package/sdk/dist/node/org-adopt.d.ts.map +1 -0
- package/sdk/dist/node/org-adopt.js +77 -0
- package/sdk/dist/node/org-adopt.js.map +1 -0
- package/sdk/dist/node/paid-fetch.d.ts +7 -7
- package/sdk/dist/node/paid-fetch.d.ts.map +1 -1
- package/sdk/dist/node/paid-fetch.js +54 -54
- package/sdk/dist/node/paid-fetch.js.map +1 -1
- package/sdk/dist/node/preflight.d.ts +1 -1
- package/sdk/dist/node/preflight.d.ts.map +1 -1
- package/sdk/dist/node/preflight.js +1 -1
- package/sdk/dist/node/preflight.js.map +1 -1
- package/sdk/dist/node/sites-node.js +1 -1
- package/sdk/dist/node/sites-node.js.map +1 -1
- package/sdk/dist/node/source-scan.d.ts +1 -1
- package/sdk/dist/node/source-scan.js +2 -2
- package/sdk/dist/node/source-scan.js.map +1 -1
- package/sdk/dist/scoped.d.ts +11 -11
- package/sdk/dist/scoped.d.ts.map +1 -1
- package/sdk/dist/scoped.js +5 -5
- package/sdk/dist/scoped.js.map +1 -1
- package/core-dist/operator-session.js +0 -154
- package/lib/allowance.mjs +0 -355
- package/lib/cloud.mjs +0 -256
- package/lib/core.mjs +0 -123
- package/lib/operator-proofs.mjs +0 -22
- package/lib/operator.mjs +0 -771
- package/sdk/core-dist/operator-session.js +0 -154
- package/sdk/dist/namespaces/allowance.d.ts +0 -79
- package/sdk/dist/namespaces/allowance.d.ts.map +0 -1
- package/sdk/dist/namespaces/allowance.js +0 -149
- package/sdk/dist/namespaces/allowance.js.map +0 -1
- package/sdk/dist/namespaces/operator-session.d.ts.map +0 -1
- package/sdk/dist/namespaces/operator-session.js.map +0 -1
- package/sdk/dist/namespaces/operator.d.ts +0 -359
- package/sdk/dist/namespaces/operator.d.ts.map +0 -1
- package/sdk/dist/namespaces/operator.js +0 -272
- package/sdk/dist/namespaces/operator.js.map +0 -1
- package/sdk/dist/node/bearer-claim-key.d.ts.map +0 -1
- package/sdk/dist/node/bearer-claim-key.js.map +0 -1
- package/sdk/dist/node/operator-claim.d.ts +0 -49
- package/sdk/dist/node/operator-claim.d.ts.map +0 -1
- package/sdk/dist/node/operator-claim.js +0 -77
- package/sdk/dist/node/operator-claim.js.map +0 -1
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
Command-line interface for [Run402](https://run402.com) — provision Postgres databases, deploy static sites, run Node 22 serverless functions, host content-addressed CDN assets, send email, sign on-chain. Paid autonomously with x402 (USDC on Base) or MPP (pathUSD on Tempo, or sats over Bitcoin Lightning). **Prototype tier is free on testnet.**
|
|
6
6
|
|
|
7
|
-
The CLI lets an agent act as its own first-class Run402 principal rather than borrowing a human account. Identity records who invoked an action; organization roles, grants, delegates, freshness, and spend policy determine what that principal may do. People remain first-class owners and
|
|
7
|
+
The CLI lets an agent act as its own first-class Run402 principal rather than borrowing a human account. Identity records who invoked an action; organization roles, grants, delegates, freshness, and spend policy determine what that principal may do. People remain first-class owners and members without having to run the CLI themselves.
|
|
8
8
|
|
|
9
9
|
For the full CLI reference (every flag, every subcommand) start at **<https://docs.run402.com/llms-cli.txt>** — the index holds the first-deploy contract and links one fetchable `/llms-cli-<slice>.txt` per topic (deploy, commands, repos, orgs, functions, assets, ops, errors, frontend, platform); <https://docs.run402.com/llms-cli-full.txt> is the whole reference as one document.
|
|
10
10
|
|
|
@@ -25,8 +25,8 @@ npx -y run402@latest <command>
|
|
|
25
25
|
## 30-second start
|
|
26
26
|
|
|
27
27
|
```bash
|
|
28
|
-
run402 up --name my-app -y # bootstrap
|
|
29
|
-
run402 subdomains
|
|
28
|
+
run402 up --name my-app -y # bootstrap wallet/tier/project/link, then deploy
|
|
29
|
+
run402 subdomains add my-app # → https://my-app.run402.com
|
|
30
30
|
```
|
|
31
31
|
|
|
32
32
|
That's a real Postgres database + a deployed static site, paid for autonomously with testnet USDC.
|
|
@@ -51,13 +51,13 @@ run402 up verify --project prj_...
|
|
|
51
51
|
run402 up --nested -y # app root inside another repo: its own nested repo + run402 remote
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
-
`up` is a thin CLI shim over the Node SDK action runner. It discovers `run402.json`, `run402.deploy.json`, then `app.json`. A `run402.json` carrying the app schema/app markers uses the app-install graph; a release-shaped `run402.json` is normalized through the same ReleaseSpec path as `deploy
|
|
54
|
+
`up` is a thin CLI shim over the Node SDK action runner. It discovers `run402.json`, `run402.deploy.json`, then `app.json`. A `run402.json` carrying the app schema/app markers uses the app-install graph; a release-shaped `run402.json` is normalized through the same ReleaseSpec path as `run402 deploy` for compatibility. It validates the deploy input before any mutation, resolves the project as `--project` → `.run402/project.json` → manifest `project_id` → approved creation from `--name` → approved active-project fallback, then applies the manifest. `--name` is creation/link metadata only; it is not a manifest field and never renames an existing project. When everything is already configured, plain `run402 up` deploys. Non-interactive recursive prerequisites/local writes require `-y/--yes`.
|
|
55
55
|
|
|
56
56
|
For app manifests with `verify.http[]`, `up` runs HTTP checks after deploy. Fresh Run402 edge sentinel misses (`x-run402-edge` or sentinel JSON bodies) become `propagation_pending` with diagnostics instead of hard failure while the host binding is still converging. Use `--propagation-budget-s <seconds>` to tune the default 120 second wait, `--no-propagation-wait` to return immediately, and `run402 up verify` to rerun the same checks without upload, deploy, project creation, or resource mutation.
|
|
57
57
|
|
|
58
|
-
For typed `run402.deploy.ts` configs, pass `--manifest` explicitly because TypeScript/JavaScript configs execute local code. Use `--check` for local-only import/normalize/file validation, `--print-spec` to inspect the normalized `ReleaseSpec`, `--plan` for a gateway-reviewed non-deploying plan, and `--require-plan <plan_id>` to apply only that reviewed intent. Warning flags are not used with `--require-plan`; the reviewed plan binds the exact warning/destructive set. Run402 Core skips Cloud
|
|
58
|
+
For typed `run402.deploy.ts` configs, pass `--manifest` explicitly because TypeScript/JavaScript configs execute local code. Use `--check` for local-only import/normalize/file validation, `--print-spec` to inspect the normalized `ReleaseSpec`, `--plan` for a gateway-reviewed non-deploying plan, and `--require-plan <plan_id>` to apply only that reviewed intent. Warning flags are not used with `--require-plan`; the reviewed plan binds the exact warning/destructive set. Run402 Core skips Cloud wallet/tier prerequisites and fails closed when no Core project is selected.
|
|
59
59
|
|
|
60
|
-
Every mode (and `deploy
|
|
60
|
+
Every mode (and `run402 deploy`) verifies the files the manifest references before any gateway call: migration `sql_path`/`sql_file`, function `source`/`files`, site `{ path }` entries and `dir()` targets, `assets.put` sources. A missing one is `MANIFEST_FILE_MISSING` (`details.missing[]` = `{ field_path, path, kind }`, one `create_file` next action per file). With no manifest in the working directory, `UP_MANIFEST_REQUIRED` looks one directory down (`details.nearby_manifests[]`, a leading `run_in_directory` next action such as `run402 up --check --dir <dir>`); `--manifest <path>` to a missing file is a typed `MANIFEST_NOT_FOUND` with a `create_manifest` next action. An app root that lies inside another repository is never scaffolded into it: the skip carries a `create_nested_repo` next action, and `--nested` gives the app its own nested repository (`git init -b main`, the `run402` remote, the first push) plus exactly one line in the enclosing repository's local `.git/info/exclude`, nothing else touched. `up` also sets this principal's display name when it has none: `RUN402_AGENT_NAME` (overrides an existing name), else the detected client (`claude-code`, `codex`, `cursor`, `grok`, or `RUN402_CLIENT=<name>` for one with no marker), and `result.identity` reports `detected` plus `detection: { applied, reason }` either way.
|
|
61
61
|
|
|
62
62
|
### repos — host-blind encrypted git repos (zero deploy ceremony)
|
|
63
63
|
|
|
@@ -78,19 +78,19 @@ run402 repos delete --project prj_xyz --force # refuses without --force while th
|
|
|
78
78
|
|
|
79
79
|
A hosted git remote, encrypted before it leaves the machine — no deploy, no manifest, no app. `origin` is claimed additively — an existing `origin` is never touched, the run402 remote falls back to `run402` instead. A directory inside another repository is never scaffolded into that repository: the skip carries a `create_nested_repo` next action, `--nested` makes it its own nested repository (one line appended to the enclosing repository's local `.git/info/exclude`, nothing else touched), and `create` prints a `git push` next action only for a remote it actually added. Every mutating `repos` verb (`create`, `rename`, `delete`, `snapshot`, `policy`, `mirror`, `gc`, `handoff`, `resume`, `invite`, `join`) is CLI/OpenClaw-only by design — no MCP tool exists or will exist for them (one-shot recovery receipts, immutable generations, irreversible delete, single-use bearer keys). Three READ-ONLY tools do exist — `repos_view`, `repos_list_heads`, `repos_fsck` — teaching only `repos` spellings. See `run402 repos --help` for the full tiered surface (common: `create`/`view`/`list`; occasional: `snapshot`/`mirror`/`recover`/`handoff`/`resume`/`invite`/`join`; lifecycle: `rename`/`delete`; maintenance: `fsck`/`gc`/`access`/`policy`), and the CLI reference's `repos` section for the terminal-loss statement and the progressive backup warning.
|
|
80
80
|
|
|
81
|
-
**Handoff / resume.** `run402 repos handoff [--note-file <path>]` captures the actual working tree (staged/unstaged/untracked, like `git stash push -u`) into the vault and mints a single-use bearer key (`kgh1_…`, printed to stdout exactly once); `run402 repos resume <kgh1_…>` claims it on another machine, clones fresh, and reapplies the exact dirty state with `git stash apply --index`. No shared keystore, no shared
|
|
81
|
+
**Handoff / resume.** `run402 repos handoff [--note-file <path>]` captures the actual working tree (staged/unstaged/untracked, like `git stash push -u`) into the vault and mints a single-use bearer key (`kgh1_…`, printed to stdout exactly once); `run402 repos resume <kgh1_…>` claims it on another machine, clones fresh, and reapplies the exact dirty state with `git stash apply --index`. No shared keystore, no shared wallet — the key is the whole handoff. On a wallet with no active tier, `resume` first folds the same cold-start chain `create` does (wallet → faucet → one x402 prototype payment); `--no-init` opts out, and the claim itself never waits on it. Sensitive untracked files (`.env`, `*.pem`, SSH/AWS/GPG dirs, …) are excluded from capture by default (`--include-sensitive <glob>` re-admits one). See the reference `run402.com/llms-cli.txt` for the full note-schema and flag reference.
|
|
82
82
|
|
|
83
83
|
**Invite / join.** The second claim kind beside handoff/resume: a Handoff passes the work on and the sender stops; an Invite grows the team while the sender keeps working. `run402 repos invite [--room <key>] [--note-file <path>]` captures the checkpoint exactly like `handoff` — the inviter's own worktree, index, branch, refs, and access are all untouched — registers the inviter's presence in a coordination room (the project's default room, or `--room <key>` for a named org room), mints a single-use bearer key (`kgi1_…`, printed to stdout exactly once), and posts ONE room message naming the checkpoint (never the key). `run402 repos join <kgi1_…>` folds the SAME cold-start chain `resume` does before the claim, clones fresh, restores the exact dirty state, pins the invite's room locally, registers its own presence, posts ONE arrival message, and reports the inviter (name, labels, liveness), the room's other live presences, and the last few messages. `run402 messages wait` is the room's blocking read from there — the agent's ear, never an error on silence. Neither `invite` nor `join` has an MCP tool, same reasoning as `handoff`/`resume`.
|
|
84
84
|
|
|
85
|
-
**Named addressing.** `run402
|
|
85
|
+
**Named addressing.** `run402 orgs slug <slug>` (owner-only, small one-time fee) sets an org's globally-unique, address-form slug, after which `run402::<slug>/<name>` addresses any repo under it — `git push` to a name that doesn't exist yet push-to-creates it. `run402 repos rename <name> [--project <project_id>]` claims the per-org-unique `<name>` half explicitly (no fee); `repos create` claims one automatically, best-effort, when the org already has a slug. Also CLI/SDK-only — no MCP tool.
|
|
86
86
|
|
|
87
|
-
###
|
|
87
|
+
### Wallet
|
|
88
88
|
|
|
89
89
|
```bash
|
|
90
|
-
run402
|
|
91
|
-
run402
|
|
92
|
-
run402
|
|
93
|
-
run402
|
|
90
|
+
run402 wallets new default # generate the local wallet without funding it
|
|
91
|
+
run402 wallets fund # request testnet USDC from the faucet
|
|
92
|
+
run402 wallets balance # mainnet + testnet USDC, plus the organization's allowance
|
|
93
|
+
run402 wallets current # the active wallet's address (for funding), rail, and file path
|
|
94
94
|
```
|
|
95
95
|
|
|
96
96
|
### Promo codes
|
|
@@ -100,9 +100,9 @@ run402 redeem R402-K8F3-Q2W9 # any time, before or after `run402 init`
|
|
|
100
100
|
run402 init --voucher R402-K8F3-Q2W9 # same redemption, folded into setup
|
|
101
101
|
```
|
|
102
102
|
|
|
103
|
-
A promo code
|
|
103
|
+
A promo code adds to the organization's allowance, which settles tiers and
|
|
104
104
|
priced calls with no on-chain payment. Case-insensitive, hyphens optional.
|
|
105
|
-
Retrying is safe — a repeat returns the original result and never
|
|
105
|
+
Retrying is safe — a repeat returns the original result and never adds twice.
|
|
106
106
|
A bad code never blocks `init`; it warns and records `voucher_error` in the JSON
|
|
107
107
|
summary.
|
|
108
108
|
|
|
@@ -144,25 +144,25 @@ reconciliation.
|
|
|
144
144
|
### Database
|
|
145
145
|
|
|
146
146
|
```bash
|
|
147
|
-
run402 projects sql <
|
|
148
|
-
run402 projects validate-expose <
|
|
149
|
-
run402 projects apply-expose <
|
|
150
|
-
run402 projects rest <
|
|
151
|
-
run402 projects schema <
|
|
147
|
+
run402 projects sql <project_id> "CREATE TABLE items (id serial PRIMARY KEY, …)"
|
|
148
|
+
run402 projects validate-expose <project_id> --file manifest.json # check auth manifest, no mutation
|
|
149
|
+
run402 projects apply-expose <project_id> --file manifest.json # declare what's reachable
|
|
150
|
+
run402 projects rest <project_id> items "select=*&order=id.desc&limit=10"
|
|
151
|
+
run402 projects schema <project_id> # introspect tables + RLS
|
|
152
152
|
```
|
|
153
153
|
|
|
154
154
|
### Static sites
|
|
155
155
|
|
|
156
156
|
```bash
|
|
157
157
|
run402 sites deploy-dir ./dist # incremental upload (plan/commit transport)
|
|
158
|
-
run402 deploy
|
|
159
|
-
run402
|
|
158
|
+
run402 deploy --manifest app.json # deploy only (`run402 up` does missing setup first, then this)
|
|
159
|
+
run402 deploy status op_... --project prj_...
|
|
160
160
|
run402 deploy verify op_... --project prj_... --wait
|
|
161
|
-
run402 deploy
|
|
162
|
-
run402 deploy
|
|
163
|
-
run402 deploy
|
|
164
|
-
run402 deploy resolve --
|
|
165
|
-
run402 subdomains
|
|
161
|
+
run402 deploy releases active # inspect current-live release inventory
|
|
162
|
+
run402 deploy releases diff --from empty --to active
|
|
163
|
+
run402 deploy resolve https://example.com/events --project prj_123 --method GET
|
|
164
|
+
run402 deploy resolve --url https://example.com/events?utm=x#hero --project prj_123 --method GET
|
|
165
|
+
run402 subdomains add my-app # → my-app.run402.com (auto-reassigns on next deploy)
|
|
166
166
|
```
|
|
167
167
|
|
|
168
168
|
For pointer-swap recovery, verify the returned operation before declaring the public rollback complete:
|
|
@@ -175,13 +175,13 @@ run402 deploy verify --operation OPERATION_ID --wait
|
|
|
175
175
|
Promote success means the origin pointer is active; mutable public URLs may still be converging. The result's `edge.state` reports convergence, and `edge.verify_url` is the direct operation-scoped HTTP verification endpoint.
|
|
176
176
|
|
|
177
177
|
`deploy-dir` hashes each file client-side and only uploads bytes the gateway doesn't already have. Re-deploying an unchanged tree returns immediately with `bytes_uploaded: 0`. Progress events stream to stderr.
|
|
178
|
-
Release inspection commands print `{ release: ... }` or `{ diff: ... }` (raw payload, no envelope — see the "Output Contract" section in [llms-cli.txt](llms-cli.txt)); use them after deploys to compare release inventory without starting another mutation. `deploy verify` prints the canonical edge-coherence report and exits 2 when the report is valid but not yet coherent. Inventories include `release_generation`, `static_manifest_sha256`, and nullable `static_manifest_metadata`; diffs include `static_assets` counters such as unchanged/changed/added/removed and CAS byte reuse. `deploy
|
|
178
|
+
Release inspection commands print `{ release: ... }` or `{ diff: ... }` (raw payload, no envelope — see the "Output Contract" section in [llms-cli.txt](llms-cli.txt)); use them after deploys to compare release inventory without starting another mutation. `deploy verify` prints the canonical edge-coherence report and exits 2 when the report is valid but not yet coherent. Inventories include `release_generation`, `static_manifest_sha256`, and nullable `static_manifest_metadata`; diffs include `static_assets` counters such as unchanged/changed/added/removed and CAS byte reuse. `deploy resolve <url>` (or `--url` / `--host` + `--path`) prints URL diagnostics with `would_serve`, `diagnostic_status`, `match`, warnings, `edge_propagation`, and next steps; host misses are successful diagnostic calls with `would_serve: false`. Stable-host resolve fields can include `authorization_result`, `cas_object`, `response_variant`, `allow`, `route_pattern`, `target_type`, `target_name`, `target_file`, and `edge_propagation` (`settled`, `propagating`, or `sync_pending`).
|
|
179
179
|
|
|
180
|
-
For database-bearing changes,
|
|
180
|
+
For database-bearing changes, rehearsal happens before commit without a flag: `run402 deploy --manifest app.json --json` (or `run402 up`) creates a contained branch, applies the candidate plan there, runs checks, and stops on a failed rehearsal; `--no-rehearse` skips it and `run402 deploy rehearse <plan_id>` rehearses a persisted plan by hand. The automatic rehearsal inside `up` / `deploy` reports `rehearsal: { status: "skipped", reason }` when there is nothing to protect: `no_live_release` on a first deploy, `no_migrations`, or `migrations_unchanged` when every migration is already applied with an identical checksum (a page-only redeploy that still carries its migrations ships in seconds). `PUBLIC_ROUTED_FUNCTION` is informational (`requires_confirmation: false`) and needs no `--allow-warning`; only warnings with `requires_confirmation: true` do. Manual restore points live under `run402 snapshots create|list|get|restore|delete`; temporary data branches live under `run402 branches create|list|renew|delete`.
|
|
181
181
|
|
|
182
182
|
### GitHub Actions OIDC deploys
|
|
183
183
|
|
|
184
|
-
Link once from a local shell that has your Run402
|
|
184
|
+
Link once from a local shell that has your Run402 wallet, then commit the generated workflow and manifest:
|
|
185
185
|
|
|
186
186
|
```bash
|
|
187
187
|
run402 ci link github --project prj_... --manifest run402.deploy.json
|
|
@@ -203,10 +203,10 @@ jobs:
|
|
|
203
203
|
steps:
|
|
204
204
|
- uses: actions/checkout@v4
|
|
205
205
|
- name: Deploy to run402
|
|
206
|
-
run: npx --yes run402@3.7.5 deploy
|
|
206
|
+
run: npx --yes run402@3.7.5 deploy --manifest 'run402.deploy.json' --project 'prj_...'
|
|
207
207
|
```
|
|
208
208
|
|
|
209
|
-
CI deploys can ship `site`, `functions`, `database`, and absent/current `base` changes. Route declarations are allowed only when the binding was linked with covering `--route-scope` patterns (`/admin` exact, `/api/*` final wildcard); no scopes means no CI route authority. Keep secrets, domains, subdomains, checks, non-current base changes, and out-of-scope routes in a local `run402 deploy
|
|
209
|
+
CI deploys can ship `site`, `functions`, `database`, and absent/current `base` changes. Route declarations are allowed only when the binding was linked with covering `--route-scope` patterns (`/admin` exact, `/api/*` final wildcard); no scopes means no CI route authority. Keep secrets, domains, subdomains, checks, non-current base changes, and out-of-scope routes in a local `run402 deploy` where the full wallet-backed authority is present.
|
|
210
210
|
|
|
211
211
|
### Storage (paste-and-go CDN assets)
|
|
212
212
|
|
|
@@ -223,18 +223,18 @@ The returned `cdn_url` is content-addressed (`pr-<public_id>.run402.com/_blob/<k
|
|
|
223
223
|
### Functions
|
|
224
224
|
|
|
225
225
|
```bash
|
|
226
|
-
run402 functions deploy <
|
|
226
|
+
run402 functions deploy <project_id> my-fn --file fn.ts \
|
|
227
227
|
--timeout 30 --memory 256 \
|
|
228
228
|
--schedule "*/15 * * * *" \
|
|
229
229
|
--deps "stripe,zod@^3"
|
|
230
|
-
run402 functions logs <
|
|
231
|
-
run402 functions logs --request-id req_abc123 --project <
|
|
232
|
-
run402 functions logs my-fn --project <
|
|
233
|
-
run402 logs --request-id req_abc123 --project <
|
|
234
|
-
run402 functions invoke my-fn --project <
|
|
235
|
-
run402 functions invoke paid-fn --project <
|
|
236
|
-
run402 functions rebuild <
|
|
237
|
-
run402 functions rebuild <
|
|
230
|
+
run402 functions logs <project_id> my-fn --tail 100 --request-id req_abc123 --follow
|
|
231
|
+
run402 functions logs --request-id req_abc123 --project <project_id> # <name> optional with --request-id: every function is searched
|
|
232
|
+
run402 functions logs my-fn --project <project_id> --all # include the Lambda INIT_START / REPORT lines
|
|
233
|
+
run402 logs --request-id req_abc123 --project <project_id> # the x-run402-request-id response header, no function name needed
|
|
234
|
+
run402 functions invoke my-fn --project <project_id> --body-file request.json
|
|
235
|
+
run402 functions invoke paid-fn --project <project_id> --body-file request.json --idempotency-key paid:call:123 --wait
|
|
236
|
+
run402 functions rebuild <project_id> my-fn # refresh ONE function onto the current runtime
|
|
237
|
+
run402 functions rebuild <project_id> --all # refresh every function in the project
|
|
238
238
|
```
|
|
239
239
|
|
|
240
240
|
Log reads are app-first: every entry carries `origin: "app" | "platform"`, the Lambda runtime lines (INIT_START, START/END/REPORT RequestId, billed duration) are hidden by default (`--app`), `--platform` shows only them and `--all` the raw stream; `hidden` counts what was dropped and a `hint` explains an empty result. `--request-id` accepts `req_`, `fnrun_`, and `fnatt_` ids, `--since` takes an ISO timestamp or epoch ms, and `run402 logs` rejects unknown flags.
|
|
@@ -253,15 +253,15 @@ import { db, adminDb, auth, email, ai } from "@run402/functions";
|
|
|
253
253
|
|
|
254
254
|
### Same-origin web routes
|
|
255
255
|
|
|
256
|
-
`run402 deploy
|
|
256
|
+
`run402 deploy` accepts `site.public_paths` for clean static browser URLs and `routes.replace` for function ingress or exact method-aware static aliases. Release asset paths such as `events.html` are distinct from public paths such as `/events`: prefer `{ "site": { "replace": { "events.html": { "data": "<h1>Events</h1>" } }, "public_paths": { "mode": "explicit", "replace": { "/events": { "asset": "events.html" } } } } }` for ordinary clean static URLs. In explicit mode `/events.html` is not public unless separately declared; `mode: "implicit"` restores filename-derived reachability and can widen access. `site.embedding.frame_ancestors` (catalog keys, e.g. `["localhost"]`, never raw origins) lets the named embedders put the site in an iframe: the gateway sends `Content-Security-Policy: frame-ancestors http://localhost:* http://127.0.0.1:*` and drops `X-Frame-Options` on every response of the host; omitted on a later apply carries the previous declaration forward, `null` returns to deny, unknown keys fail `INVALID_SPEC` naming the valid ones, and `/_run402/config.json` discloses the effective policy cross-origin so an embedder can check before framing. `routes.replace` is an array of route entries, not a path-keyed map. Use exact `/admin` plus final-wildcard `/admin/*` for a routed section root, narrow `/api/*` methods such as `["GET","POST","OPTIONS"]`, POST-only `/login` function routes, and exact static route targets like `{ "pattern": "/events", "methods": ["GET","HEAD"], "target": { "type": "static", "file": "events.html" } }` only for route-table alias behavior. Static route `file` is a release asset path, not a public path, URL, CAS hash, rewrite, or redirect. Recipe — static home page + SPA shell: a root alias `{ "pattern": "/", "target": { "type": "static", "file": "home.html" } }` (with `home.html` at the site root) serves real static bytes at `GET /` (`route_static_alias`) while unmatched app routes keep the `index.html` shell (`spa_fallback`); expect non-blocking `STATIC_ALIAS_SHADOWS_STATIC_PATH` (warn) / `STATIC_ALIAS_DUPLICATE_CANONICAL_URL` (info) plan lints and verify with `run402 deploy resolve --url https://<your-site>/ --method GET`. Routed functions use Node 22 Fetch Request -> Response; `req.url` is the full public URL on managed subdomains, deployment hosts, and verified custom domains. Direct `/functions/v1/:name` remains API-key protected. Known resolve literals include `host_missing`, `manifest_missing`, `active_release_missing`, `unsupported_manifest_version`, `path_error`, `none`, `static_exact`, `static_index`, `spa_fallback`, `spa_fallback_missing`, `route_function`, `route_static_alias`, and `route_method_miss`; known `authorization_result` values include `authorized`, `not_public`, `not_applicable`, `manifest_missing`, `target_missing`, `active_release_missing`, `unsupported_manifest_version`, `path_error`, `missing_cas_object`, `unfinalized_or_deleting_cas_object`, `size_mismatch`, and `unauthorized_cas_object`. Known `fallback_state` values include `active_release_missing`, `unsupported_manifest_version`, and `negative_cache_hit`; preserve unknown future strings. Release inventories may include `static_public_paths` with `public_path`, `asset_path`, `reachability_authority`, and `direct`; resolve may return the same reachability fields plus `authorization_result`, `cas_object`, `response_variant`, and route/static fields like `allow`, `route_pattern`, `target_type`, `target_name`, and `target_file`. Static route target warnings include `STATIC_ALIAS_SHADOWS_STATIC_PATH`, `STATIC_ALIAS_RELATIVE_ASSET_RISK`, `STATIC_ALIAS_DUPLICATE_CANONICAL_URL`, `STATIC_ALIAS_EXTENSIONLESS_NON_HTML`, and `STATIC_ALIAS_TABLE_NEAR_LIMIT`; inspect active routes, `static_public_paths`, and the backing `asset_path`. Runtime route failure codes to branch on: `ROUTE_MANIFEST_LOAD_FAILED`, `ROUTED_INVOKE_WORKER_SECRET_MISSING`, `ROUTED_INVOKE_AUTH_FAILED`, `ROUTED_ROUTE_STALE`, `ROUTE_METHOD_NOT_ALLOWED`, and `ROUTED_RESPONSE_TOO_LARGE`.
|
|
257
257
|
|
|
258
258
|
### Secrets
|
|
259
259
|
|
|
260
260
|
```bash
|
|
261
|
-
run402 secrets set <
|
|
262
|
-
printf %s "$OPENAI_API_KEY" | run402 secrets set <
|
|
263
|
-
run402 secrets list <
|
|
264
|
-
run402 deploy
|
|
261
|
+
run402 secrets set <project_id> OPENAI_API_KEY --file ./.secrets/openai-key
|
|
262
|
+
printf %s "$OPENAI_API_KEY" | run402 secrets set <project_id> OPENAI_API_KEY --stdin
|
|
263
|
+
run402 secrets list <project_id>
|
|
264
|
+
run402 deploy --manifest run402.deploy.json # manifest uses secrets.require, not values
|
|
265
265
|
```
|
|
266
266
|
|
|
267
267
|
Secret values are write-only. `list` returns keys and timestamps only; deploy manifests should declare dependencies with `secrets.require` and never contain values.
|
|
@@ -289,7 +289,7 @@ run402 email send --to user@example.com --subject "Welcome" --html "<h1>Hi</h1>"
|
|
|
289
289
|
run402 email send --to user@example.com --template notification --var project_name="My App"
|
|
290
290
|
```
|
|
291
291
|
|
|
292
|
-
For Run402 Core, use the same commands after `run402 init --api-base=http://my-core:4020`.
|
|
292
|
+
For Run402 Core, use the same commands after `run402 init --api-base=http://my-core:4020`. Whoever runs the Core gateway must configure an outbound provider such as SES first; `run402 email mailboxes` surfaces `provider_readiness`, `can_send`, `send_blocked_reason`, and `next_actions` when setup is missing. Core's first email slice supports raw outbound mail with attachments; managed templates, inbound reply handling, sender-domain automation, and delivery operations may remain Cloud-only until the Core gateway adds those capabilities.
|
|
293
293
|
|
|
294
294
|
### Image generation
|
|
295
295
|
|
|
@@ -323,18 +323,18 @@ run402 doctor # { ok, blocking[], warnings[], checks[] }
|
|
|
323
323
|
run402 doctor --refresh # live npm check for a newer run402
|
|
324
324
|
```
|
|
325
325
|
|
|
326
|
-
`ok` is structural: `true` exactly when `blocking[]` is empty. Every check carries `severity: "blocking" | "advisory" | "info"`; advisory findings (an unbound
|
|
326
|
+
`ok` is structural: `true` exactly when `blocking[]` is empty. Every check carries `severity: "blocking" | "advisory" | "info"`; advisory findings (an unbound contact passkey, a degraded recovery posture on another org, a stale CLI, gitvault gaps) land in `warnings[]` without changing `ok` or the exit code. The `tier` check's `status` is a fixed vocabulary (`ok | inactive | frozen | past_due | dormant | purged | missing | unknown | error`, never a tier name; see `value.tier` / `value.lifecycle`), and a wallet whose own org holds no tier but can reach another org's projects reports `missing` as advisory (`TIER_MISSING_ON_OWN_ORG`).
|
|
327
327
|
|
|
328
328
|
## State
|
|
329
329
|
|
|
330
330
|
Local state lives at:
|
|
331
331
|
|
|
332
332
|
- `~/.config/run402/projects.json` (`0600`) — project credentials (`anon_key`, `service_key`, `tier`, `lease_expires_at`)
|
|
333
|
-
- `~/.config/run402/
|
|
333
|
+
- `~/.config/run402/wallet.json` (`0600`) — wallet for x402 signing
|
|
334
334
|
- `~/.config/run402/config.json` (`0600`) — global default wallet pointer (`active_wallet`)
|
|
335
|
-
- `~/.config/run402/profiles/<name>/` (`0700`) — named wallets, each with its own `
|
|
335
|
+
- `~/.config/run402/profiles/<name>/` (`0700`) — named wallets, each with its own `wallet.json` + `projects.json` + non-secret `meta.json`
|
|
336
336
|
|
|
337
|
-
Override the base directory with `RUN402_CONFIG_DIR` or the
|
|
337
|
+
Override the base directory with `RUN402_CONFIG_DIR` or the wallet file with `RUN402_WALLET_PATH`. Override the API base with `RUN402_API_BASE`.
|
|
338
338
|
|
|
339
339
|
### Named wallets (profiles)
|
|
340
340
|
|
|
@@ -346,20 +346,22 @@ Hold several wallets on one machine and select between them:
|
|
|
346
346
|
|
|
347
347
|
The CLI handles all x402 / MPP payment signing automatically — never ask the human for a private key or set up payment libraries by hand.
|
|
348
348
|
|
|
349
|
-
###
|
|
349
|
+
### Sign-in session (a person)
|
|
350
350
|
|
|
351
|
-
|
|
351
|
+
A person signs in; the agent is your wallet (`run402 status` shows the wallet's own organization state). There is one sign-in session, graded by how it was minted.
|
|
352
352
|
|
|
353
|
-
- `run402
|
|
354
|
-
- `run402
|
|
355
|
-
- `run402
|
|
356
|
-
- `run402
|
|
353
|
+
- `run402 login` — browser passkey sign-in over loopback PKCE (RFC 8252, like `aws sso login`): the CLI listens on `127.0.0.1`, the browser runs the ceremony, and the session (grade `loopback`: full, step-up-able) is cached at the base config dir (shared across named wallets). Signing in again is the step-up.
|
|
354
|
+
- `run402 login --device` — RFC 8628 device code for a terminal with no browser; approve it in the console. The session is grade `device`: read-only.
|
|
355
|
+
- `run402 whoami` — principal, memberships, `session.grade`, and the write approvals cached on this machine.
|
|
356
|
+
- `run402 approve --action <capability> (--org <org_id> | --project <project_id>)` — passkey-signed write approval for one action on one target; a person without a wallet needs it to provision, deploy, or write secrets (an interactive `provision`/`deploy` opens it for you).
|
|
357
|
+
- `run402 logout` — revoke the session server-side and clear it and every write approval locally.
|
|
358
|
+
- `run402 orgs list` — your orgs joined with the account overview (tier, lifecycle, quotas, allowance, advisories).
|
|
357
359
|
|
|
358
|
-
Not exposed as MCP tools by design — MCP authenticates as the agent (wallet), and
|
|
360
|
+
Not exposed as MCP tools by design — MCP authenticates as the agent (wallet), and a person's session must not become its ambient authority.
|
|
359
361
|
|
|
360
362
|
## Active project (sticky default)
|
|
361
363
|
|
|
362
|
-
After `provision`, the new project becomes the active one. `run402 projects use <
|
|
364
|
+
After `provision`, the new project becomes the active one. `run402 projects use <project_id>` switches it. Most commands that take `<project_id>` default to the active project when omitted.
|
|
363
365
|
|
|
364
366
|
## Help
|
|
365
367
|
|
package/cli.mjs
CHANGED
|
@@ -31,20 +31,18 @@ Usage:
|
|
|
31
31
|
Commands, grouped by when you reach for them:
|
|
32
32
|
|
|
33
33
|
SET UP — get an agent funded and entitled
|
|
34
|
-
init Set up
|
|
34
|
+
init Set up the local wallet, funding, and check tier status (x402 default)
|
|
35
35
|
init mpp Set up with MPP payment rail (Tempo Moderato testnet)
|
|
36
|
-
wallets Manage
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
redeem Redeem a promo code for run402 credit
|
|
36
|
+
wallets Manage local wallets (list, current, new, use, fund, balance, import)
|
|
37
|
+
tier Manage your tier and its lease (status, set)
|
|
38
|
+
redeem Redeem a promo code into your organization's allowance
|
|
40
39
|
pay Call an arbitrary x402-priced URL with a bounded payment
|
|
41
40
|
|
|
42
41
|
BUILD & SHIP — the app and everything it serves
|
|
43
42
|
up Provision/link/deploy the current app with SDK orchestration
|
|
44
43
|
projects Manage projects (provision, list, get, sql, delete)
|
|
45
44
|
repos Host-blind encrypted git repos: create/view/list, snapshot/mirror/recover, fsck/gc/access/policy (repo aliases repos)
|
|
46
|
-
deploy
|
|
47
|
-
apply Alias for deploy apply; supports --rehearse for migration rehearsal
|
|
45
|
+
deploy Deploy a release; subcommands inspect and steer deploys (requires active tier)
|
|
48
46
|
functions Manage serverless functions (deploy, invoke, logs, list, delete)
|
|
49
47
|
secrets Manage project secrets (set, list, delete)
|
|
50
48
|
sites Deploy static sites
|
|
@@ -57,7 +55,7 @@ OPERATE — what happened, and is it healthy
|
|
|
57
55
|
live Change hints for live tables as NDJSON (SSE; --once for one held read)
|
|
58
56
|
errors Grouped error fingerprints + a promote/revert verdict (release-baselined)
|
|
59
57
|
logs Fetch function logs by request id (--request-id req_...)
|
|
60
|
-
status Show full account state (
|
|
58
|
+
status Show full account state (wallet, allowance, tier, projects)
|
|
61
59
|
doctor Health and config diagnostics (JSON by default; includes --buzz preflight)
|
|
62
60
|
service Run402 service health and availability (status, health)
|
|
63
61
|
snapshots Create/list/restore/delete project data snapshots
|
|
@@ -74,17 +72,20 @@ AUTHORITY — who may act, and with what credential
|
|
|
74
72
|
credentials Manage local credential material (project-keys)
|
|
75
73
|
delegates Scoped deploy credentials for agents (create, list, revoke, rotate)
|
|
76
74
|
grants Per-project capability grants for agent/CI principals (create, revoke)
|
|
77
|
-
|
|
75
|
+
orgs Organizations, members, invites & audit (list, get, members, invite, audit)
|
|
78
76
|
identity Public proof-backed external agent identity links
|
|
79
77
|
auth Manage project user authentication (magic link, passwords, settings)
|
|
80
78
|
ci Link GitHub Actions OIDC deploy bindings
|
|
81
|
-
|
|
79
|
+
login Sign in as a person (browser passkey; --device for a read-only session)
|
|
80
|
+
logout End your sign-in session and clear it from this machine
|
|
81
|
+
whoami Who this CLI acts as: principal, memberships, session grade (--set-name sets your name)
|
|
82
|
+
approve Write approval for one action on one target (provision, deploy, secrets)
|
|
82
83
|
|
|
83
84
|
DELIVER — reach a human when something happens
|
|
84
85
|
deliveries Did a notification actually land (list, get)
|
|
85
86
|
contacts Where a human is reachable — paging ladder + Telegram (list, add, connect, rm, preferences)
|
|
86
87
|
subscriptions Which events go where (add, list, rm)
|
|
87
|
-
webhook-secret Rotate
|
|
88
|
+
webhook-secret Rotate your webhook signing secret
|
|
88
89
|
email Send template-based emails from your project
|
|
89
90
|
|
|
90
91
|
PLATFORM — everything else, and the things still finding a home
|
|
@@ -92,9 +93,8 @@ PLATFORM — everything else, and the things still finding a home
|
|
|
92
93
|
billing Email organizations, Stripe tier checkout, email packs
|
|
93
94
|
contracts KMS signers ($0.04/day rental + $0.000005/sign)
|
|
94
95
|
jobs Submit and inspect platform-managed jobs
|
|
95
|
-
transfer
|
|
96
|
-
cloud
|
|
97
|
-
archives Inspect and verify portable project archives locally
|
|
96
|
+
transfer Project transfer to a wallet, an email, or an owned org (init, preview, list, accept, cancel)
|
|
97
|
+
archives Portable project archives (create, status, download --target cloud; inspect, verify; import --target core)
|
|
98
98
|
gitvault RETIRED — moved to repos (repo-surface-consolidation); every spelling answers COMMAND_MOVED/COMMAND_REMOVED
|
|
99
99
|
source-access RETIRED — moved into repos (recovery-bundle + access); every spelling answers COMMAND_MOVED
|
|
100
100
|
buzz Buzz human/community/agent control-plane workflows
|
|
@@ -104,7 +104,6 @@ PLATFORM — everything else, and the things still finding a home
|
|
|
104
104
|
cdn CloudFront CDN diagnostics (wait-fresh) for public asset URLs
|
|
105
105
|
cache Inspect and invalidate the SSR origin cache (inspect, invalidate)
|
|
106
106
|
agent Manage agent identity (contact info)
|
|
107
|
-
core Local Run402 Core import helpers
|
|
108
107
|
dev Run Astro dev with Run402 env + credentials in scope
|
|
109
108
|
|
|
110
109
|
Global options (any command):
|
|
@@ -115,15 +114,14 @@ Run 'run402 <command> --help' for detailed usage of each command.
|
|
|
115
114
|
|
|
116
115
|
Examples:
|
|
117
116
|
run402 up --name my-app -y
|
|
118
|
-
run402
|
|
119
|
-
run402
|
|
117
|
+
run402 init
|
|
118
|
+
run402 wallets fund
|
|
120
119
|
run402 pay https://seller.example/resource --max-usd 0.05
|
|
121
|
-
run402 deploy
|
|
122
|
-
run402 apply --manifest app.json --rehearse --json
|
|
120
|
+
run402 deploy --manifest app.json
|
|
123
121
|
run402 snapshots list --project prj_...
|
|
124
122
|
run402 branches create --project prj_... --ttl-days 7 --json
|
|
125
|
-
run402
|
|
126
|
-
run402
|
|
123
|
+
run402 archives create --project <project_id> --target cloud --wait --output ./project.r402ar --json
|
|
124
|
+
run402 archives import ./project.r402ar --target core --name imported-project --env-file ./required.env --json
|
|
127
125
|
run402 jobs submit --file job.json
|
|
128
126
|
run402 projects list
|
|
129
127
|
run402 projects sql "SELECT * FROM users LIMIT 5" --project <project_id>
|
|
@@ -134,7 +132,7 @@ Examples:
|
|
|
134
132
|
Getting started:
|
|
135
133
|
run402 init Set up with x402 (Base Sepolia)
|
|
136
134
|
run402 init mpp Set up with MPP (Tempo Moderato)
|
|
137
|
-
run402 tier set prototype
|
|
135
|
+
run402 tier set prototype Set a tier (prototype is free)
|
|
138
136
|
run402 up --name my-app -y Create and deploy this app (explicit destination)
|
|
139
137
|
run402 ci link github --project prj_... --manifest run402.deploy.json
|
|
140
138
|
`;
|
|
@@ -219,11 +217,6 @@ switch (cmd) {
|
|
|
219
217
|
await run(sub, rest);
|
|
220
218
|
break;
|
|
221
219
|
}
|
|
222
|
-
case "allowance": {
|
|
223
|
-
const { run } = await import("./lib/allowance.mjs");
|
|
224
|
-
await run(sub, rest);
|
|
225
|
-
break;
|
|
226
|
-
}
|
|
227
220
|
case "tier": {
|
|
228
221
|
const { run } = await import("./lib/tier.mjs");
|
|
229
222
|
await run(sub, rest);
|
|
@@ -247,11 +240,6 @@ switch (cmd) {
|
|
|
247
240
|
await run(sub, rest);
|
|
248
241
|
break;
|
|
249
242
|
}
|
|
250
|
-
case "apply": {
|
|
251
|
-
const { runDeployV2 } = await import("./lib/deploy-v2.mjs");
|
|
252
|
-
await runDeployV2("apply", [sub, ...rest].filter(Boolean));
|
|
253
|
-
break;
|
|
254
|
-
}
|
|
255
243
|
case "snapshots": {
|
|
256
244
|
const { run } = await import("./lib/snapshots.mjs");
|
|
257
245
|
await run(sub, rest);
|
|
@@ -267,21 +255,11 @@ switch (cmd) {
|
|
|
267
255
|
await run(sub, rest);
|
|
268
256
|
break;
|
|
269
257
|
}
|
|
270
|
-
case "cloud": {
|
|
271
|
-
const { run } = await import("./lib/cloud.mjs");
|
|
272
|
-
await run(sub, rest);
|
|
273
|
-
break;
|
|
274
|
-
}
|
|
275
258
|
case "archives": {
|
|
276
259
|
const { run } = await import("./lib/archives.mjs");
|
|
277
260
|
await run(sub, rest);
|
|
278
261
|
break;
|
|
279
262
|
}
|
|
280
|
-
case "core": {
|
|
281
|
-
const { run } = await import("./lib/core.mjs");
|
|
282
|
-
await run(sub, rest);
|
|
283
|
-
break;
|
|
284
|
-
}
|
|
285
263
|
case "deploy": {
|
|
286
264
|
const { run } = await import("./lib/deploy.mjs");
|
|
287
265
|
await run([sub, ...rest].filter(Boolean));
|
|
@@ -297,8 +275,8 @@ switch (cmd) {
|
|
|
297
275
|
await run(sub, rest);
|
|
298
276
|
break;
|
|
299
277
|
}
|
|
300
|
-
case "
|
|
301
|
-
const { run } = await import("./lib/
|
|
278
|
+
case "orgs": {
|
|
279
|
+
const { run } = await import("./lib/orgs.mjs");
|
|
302
280
|
await run(sub, rest);
|
|
303
281
|
break;
|
|
304
282
|
}
|
|
@@ -450,9 +428,24 @@ switch (cmd) {
|
|
|
450
428
|
await run(sub, rest);
|
|
451
429
|
break;
|
|
452
430
|
}
|
|
453
|
-
case "
|
|
454
|
-
const { run } = await import("./lib/
|
|
455
|
-
await run(sub, rest);
|
|
431
|
+
case "login": {
|
|
432
|
+
const { run } = await import("./lib/login.mjs");
|
|
433
|
+
await run([sub, ...rest].filter(Boolean));
|
|
434
|
+
break;
|
|
435
|
+
}
|
|
436
|
+
case "logout": {
|
|
437
|
+
const { run } = await import("./lib/logout.mjs");
|
|
438
|
+
await run([sub, ...rest].filter(Boolean));
|
|
439
|
+
break;
|
|
440
|
+
}
|
|
441
|
+
case "whoami": {
|
|
442
|
+
const { run } = await import("./lib/whoami.mjs");
|
|
443
|
+
await run([sub, ...rest].filter(Boolean));
|
|
444
|
+
break;
|
|
445
|
+
}
|
|
446
|
+
case "approve": {
|
|
447
|
+
const { run } = await import("./lib/approve.mjs");
|
|
448
|
+
await run([sub, ...rest].filter(Boolean));
|
|
456
449
|
break;
|
|
457
450
|
}
|
|
458
451
|
case "source-access": {
|
package/core-dist/config.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { homedir } from "node:os";
|
|
2
2
|
import { dirname, join } from "node:path";
|
|
3
|
-
import { existsSync, renameSync, mkdirSync, chmodSync, readFileSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { existsSync, renameSync, mkdirSync, chmodSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
|
|
4
4
|
import { randomBytes } from "node:crypto";
|
|
5
5
|
import { describeRejectedValue } from "./redact.js";
|
|
6
6
|
export const DEFAULT_API_BASE = "https://api.run402.com";
|
|
@@ -118,7 +118,7 @@ export function getProfilesDir() {
|
|
|
118
118
|
* The effective config directory for the *active* wallet. The `default` wallet
|
|
119
119
|
* resolves to the base dir (zero migration for existing single-wallet
|
|
120
120
|
* installs); any named wallet resolves to `{base}/profiles/<name>`. Because
|
|
121
|
-
* keystore,
|
|
121
|
+
* keystore, wallet, and meta paths all derive from this, switching the
|
|
122
122
|
* profile env var moves the whole wallet bundle atomically — and the SDK/MCP
|
|
123
123
|
* inherit profile selection for free.
|
|
124
124
|
*/
|
|
@@ -232,27 +232,61 @@ export function isCoreApiTarget() {
|
|
|
232
232
|
return true;
|
|
233
233
|
return false;
|
|
234
234
|
}
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
235
|
+
/**
|
|
236
|
+
* The file that holds a wallet's key, in the base config dir (the `default`
|
|
237
|
+
* wallet) and in each `profiles/<name>/` directory.
|
|
238
|
+
*/
|
|
239
|
+
export const WALLET_FILE_NAME = "wallet.json";
|
|
240
|
+
/** The name the wallet key file had before it was `wallet.json`. */
|
|
241
|
+
const PREVIOUS_WALLET_FILE_NAME = "allowance.json";
|
|
242
|
+
const walletFilesMovedFor = new Set();
|
|
243
|
+
/**
|
|
244
|
+
* One-time local move of the wallet key file to its current name: in the base
|
|
245
|
+
* config dir and every `profiles/<name>/` directory, `allowance.json` is
|
|
246
|
+
* renamed to `wallet.json` (an atomic same-directory rename) when
|
|
247
|
+
* `wallet.json` is absent, then tightened to 0600. A directory that already
|
|
248
|
+
* holds `wallet.json` is left untouched. Runs once per base dir per process;
|
|
249
|
+
* nothing reads the previous name afterwards.
|
|
250
|
+
*/
|
|
251
|
+
export function moveWalletFiles() {
|
|
252
|
+
const base = getConfigBaseDir();
|
|
253
|
+
if (walletFilesMovedFor.has(base))
|
|
254
|
+
return;
|
|
255
|
+
walletFilesMovedFor.add(base);
|
|
256
|
+
const dirs = [base];
|
|
257
|
+
try {
|
|
258
|
+
for (const entry of readdirSync(join(base, "profiles"), { withFileTypes: true })) {
|
|
259
|
+
if (entry.isDirectory())
|
|
260
|
+
dirs.push(join(base, "profiles", entry.name));
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
catch {
|
|
264
|
+
// No profiles directory yet.
|
|
265
|
+
}
|
|
266
|
+
for (const dir of dirs) {
|
|
267
|
+
const from = join(dir, PREVIOUS_WALLET_FILE_NAME);
|
|
268
|
+
const to = join(dir, WALLET_FILE_NAME);
|
|
269
|
+
if (existsSync(to) || !existsSync(from))
|
|
270
|
+
continue;
|
|
271
|
+
try {
|
|
272
|
+
renameSync(from, to);
|
|
273
|
+
}
|
|
274
|
+
catch {
|
|
275
|
+
continue;
|
|
276
|
+
}
|
|
248
277
|
try {
|
|
249
|
-
chmodSync(
|
|
278
|
+
chmodSync(to, 0o600);
|
|
250
279
|
}
|
|
251
280
|
catch {
|
|
252
281
|
// Best-effort (e.g. Windows / exotic filesystems). Read-time self-heal
|
|
253
|
-
// in
|
|
282
|
+
// in readWallet() is the backstop.
|
|
254
283
|
}
|
|
255
284
|
}
|
|
256
|
-
|
|
285
|
+
}
|
|
286
|
+
export function getWalletPath() {
|
|
287
|
+
if (process.env.RUN402_WALLET_PATH)
|
|
288
|
+
return process.env.RUN402_WALLET_PATH;
|
|
289
|
+
moveWalletFiles();
|
|
290
|
+
return join(getConfigDir(), WALLET_FILE_NAME);
|
|
257
291
|
}
|
|
258
292
|
//# sourceMappingURL=config.js.map
|