run402 4.96.0 → 4.98.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/cli.mjs +1 -7
- package/core-dist/binding-file.js +28 -1
- package/core-dist/wallet.js +3 -3
- package/lib/auth.mjs +1 -2
- package/lib/buzz-doctor.mjs +21 -806
- package/lib/buzz-doctor.test.mjs +7 -6
- package/lib/buzz.mjs +1 -1
- package/lib/buzz.test.mjs +13 -2
- package/lib/command-manifest.mjs +3 -6
- package/lib/credentials.mjs +4 -4
- package/lib/deploy-v2.mjs +27 -27
- package/lib/doctor.mjs +72 -811
- package/lib/errors.mjs +1 -1
- package/lib/events.mjs +1 -1
- package/lib/grants.mjs +148 -46
- package/lib/init.mjs +35 -576
- package/lib/logs.mjs +1 -1
- package/lib/org-context.mjs +39 -376
- package/lib/orgs.mjs +22 -106
- package/lib/projects.mjs +2 -3
- package/lib/repos.mjs +6 -6
- package/lib/rooms.mjs +1 -2
- package/lib/sdk-errors.mjs +26 -0
- package/lib/sites.mjs +5 -5
- package/lib/status.mjs +14 -154
- package/lib/up.mjs +1 -2
- package/lib/vault-scaffold.mjs +2 -3
- package/lib/vault-target.mjs +14 -141
- package/lib/wallet-context.mjs +61 -227
- package/lib/wallets.mjs +47 -310
- package/package.json +1 -2
- package/sdk/core-dist/binding-file.js +28 -1
- package/sdk/core-dist/wallet.js +3 -3
- package/sdk/dist/errors.d.ts +25 -3
- package/sdk/dist/errors.d.ts.map +1 -1
- package/sdk/dist/errors.js +46 -4
- package/sdk/dist/errors.js.map +1 -1
- package/sdk/dist/grant-key-credentials.d.ts +38 -0
- package/sdk/dist/grant-key-credentials.d.ts.map +1 -0
- package/sdk/dist/grant-key-credentials.js +42 -0
- package/sdk/dist/grant-key-credentials.js.map +1 -0
- package/sdk/dist/index.d.ts +25 -17
- package/sdk/dist/index.d.ts.map +1 -1
- package/sdk/dist/index.js +18 -14
- package/sdk/dist/index.js.map +1 -1
- package/sdk/dist/kernel.d.ts +34 -0
- package/sdk/dist/kernel.d.ts.map +1 -1
- package/sdk/dist/kernel.js +15 -1
- package/sdk/dist/kernel.js.map +1 -1
- package/sdk/dist/namespaces/admin.d.ts.map +1 -1
- package/sdk/dist/namespaces/admin.js +8 -0
- 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 +4 -0
- package/sdk/dist/namespaces/agent.js.map +1 -1
- package/sdk/dist/namespaces/agent.types.d.ts +5 -0
- package/sdk/dist/namespaces/agent.types.d.ts.map +1 -1
- package/sdk/dist/namespaces/apps.d.ts.map +1 -1
- package/sdk/dist/namespaces/apps.js +2 -0
- package/sdk/dist/namespaces/apps.js.map +1 -1
- package/sdk/dist/namespaces/auth.d.ts.map +1 -1
- package/sdk/dist/namespaces/auth.js +9 -0
- package/sdk/dist/namespaces/auth.js.map +1 -1
- package/sdk/dist/namespaces/billing.d.ts +1 -1
- package/sdk/dist/namespaces/billing.js +1 -1
- package/sdk/dist/namespaces/branches.d.ts.map +1 -1
- package/sdk/dist/namespaces/branches.js +2 -0
- package/sdk/dist/namespaces/branches.js.map +1 -1
- package/sdk/dist/namespaces/buzz.js +1 -1
- package/sdk/dist/namespaces/buzz.js.map +1 -1
- package/sdk/dist/namespaces/ci.d.ts.map +1 -1
- package/sdk/dist/namespaces/ci.js +2 -0
- package/sdk/dist/namespaces/ci.js.map +1 -1
- package/sdk/dist/namespaces/credentials.d.ts +4 -27
- package/sdk/dist/namespaces/credentials.d.ts.map +1 -1
- package/sdk/dist/namespaces/credentials.js +33 -4
- package/sdk/dist/namespaces/credentials.js.map +1 -1
- package/sdk/dist/namespaces/deploy.js +5 -5
- package/sdk/dist/namespaces/deploy.js.map +1 -1
- package/sdk/dist/namespaces/domains.d.ts +1 -1
- package/sdk/dist/namespaces/domains.js +1 -1
- package/sdk/dist/namespaces/errors.d.ts +1 -1
- package/sdk/dist/namespaces/errors.js +2 -2
- package/sdk/dist/namespaces/escalations.d.ts +2 -2
- package/sdk/dist/namespaces/escalations.d.ts.map +1 -1
- package/sdk/dist/namespaces/escalations.js +4 -2
- package/sdk/dist/namespaces/escalations.js.map +1 -1
- package/sdk/dist/namespaces/escalations.types.d.ts +3 -3
- package/sdk/dist/namespaces/escalations.types.d.ts.map +1 -1
- package/sdk/dist/namespaces/events.d.ts +1 -1
- package/sdk/dist/namespaces/events.js +1 -1
- package/sdk/dist/namespaces/functions.js +1 -1
- package/sdk/dist/namespaces/functions.js.map +1 -1
- package/sdk/dist/namespaces/grants.d.ts +43 -9
- package/sdk/dist/namespaces/grants.d.ts.map +1 -1
- package/sdk/dist/namespaces/grants.js +103 -10
- package/sdk/dist/namespaces/grants.js.map +1 -1
- package/sdk/dist/namespaces/grants.types.d.ts +120 -15
- package/sdk/dist/namespaces/grants.types.d.ts.map +1 -1
- package/sdk/dist/namespaces/grants.types.js +12 -3
- package/sdk/dist/namespaces/grants.types.js.map +1 -1
- package/sdk/dist/namespaces/identity-links.types.d.ts +2 -2
- package/sdk/dist/namespaces/identity-links.types.d.ts.map +1 -1
- package/sdk/dist/namespaces/live.d.ts +0 -16
- package/sdk/dist/namespaces/live.d.ts.map +1 -1
- package/sdk/dist/namespaces/live.js +19 -0
- package/sdk/dist/namespaces/live.js.map +1 -1
- package/sdk/dist/namespaces/me.d.ts.map +1 -1
- package/sdk/dist/namespaces/me.js +3 -0
- package/sdk/dist/namespaces/me.js.map +1 -1
- package/sdk/dist/namespaces/org.d.ts +1 -1
- package/sdk/dist/namespaces/org.d.ts.map +1 -1
- package/sdk/dist/namespaces/org.js +4 -1
- package/sdk/dist/namespaces/org.js.map +1 -1
- package/sdk/dist/namespaces/projects.d.ts +1 -1
- package/sdk/dist/namespaces/projects.d.ts.map +1 -1
- package/sdk/dist/namespaces/projects.js +6 -1
- package/sdk/dist/namespaces/projects.js.map +1 -1
- package/sdk/dist/namespaces/repos.d.ts.map +1 -1
- package/sdk/dist/namespaces/repos.js +7 -2
- package/sdk/dist/namespaces/repos.js.map +1 -1
- package/sdk/dist/namespaces/rooms.d.ts +3 -3
- package/sdk/dist/namespaces/rooms.d.ts.map +1 -1
- package/sdk/dist/namespaces/rooms.js +6 -3
- package/sdk/dist/namespaces/rooms.js.map +1 -1
- package/sdk/dist/namespaces/session.d.ts.map +1 -1
- package/sdk/dist/namespaces/session.js +18 -0
- package/sdk/dist/namespaces/session.js.map +1 -1
- package/sdk/dist/namespaces/transfers.d.ts.map +1 -1
- package/sdk/dist/namespaces/transfers.js +3 -0
- package/sdk/dist/namespaces/transfers.js.map +1 -1
- package/sdk/dist/namespaces/wallets.d.ts.map +1 -1
- package/sdk/dist/namespaces/wallets.js +2 -0
- package/sdk/dist/namespaces/wallets.js.map +1 -1
- package/sdk/dist/namespaces/write-approval.d.ts.map +1 -1
- package/sdk/dist/namespaces/write-approval.js +3 -0
- package/sdk/dist/namespaces/write-approval.js.map +1 -1
- package/sdk/dist/node/actions-node.d.ts.map +1 -1
- package/sdk/dist/node/actions-node.js +3 -0
- package/sdk/dist/node/actions-node.js.map +1 -1
- package/sdk/dist/node/buzz-doctor-contract.d.ts +155 -0
- package/sdk/dist/node/buzz-doctor-contract.d.ts.map +1 -0
- package/sdk/dist/node/buzz-doctor-contract.js +385 -0
- package/sdk/dist/node/buzz-doctor-contract.js.map +1 -0
- package/sdk/dist/node/buzz-doctor.d.ts +155 -0
- package/sdk/dist/node/buzz-doctor.d.ts.map +1 -0
- package/sdk/dist/node/buzz-doctor.js +810 -0
- package/sdk/dist/node/buzz-doctor.js.map +1 -0
- package/sdk/dist/node/credentials.d.ts +18 -13
- package/sdk/dist/node/credentials.d.ts.map +1 -1
- package/sdk/dist/node/credentials.js +13 -13
- package/sdk/dist/node/credentials.js.map +1 -1
- package/sdk/dist/node/diagnostics.d.ts +45 -0
- package/sdk/dist/node/diagnostics.d.ts.map +1 -0
- package/sdk/dist/node/diagnostics.js +67 -0
- package/sdk/dist/node/diagnostics.js.map +1 -0
- package/sdk/dist/node/doctor.d.ts +101 -0
- package/sdk/dist/node/doctor.d.ts.map +1 -0
- package/sdk/dist/node/doctor.js +618 -0
- package/sdk/dist/node/doctor.js.map +1 -0
- package/sdk/dist/node/index.d.ts +61 -9
- package/sdk/dist/node/index.d.ts.map +1 -1
- package/sdk/dist/node/index.js +37 -2
- package/sdk/dist/node/index.js.map +1 -1
- package/sdk/dist/node/init.d.ts +137 -0
- package/sdk/dist/node/init.d.ts.map +1 -0
- package/sdk/dist/node/init.js +507 -0
- package/sdk/dist/node/init.js.map +1 -0
- package/sdk/dist/node/lightning-wallet.d.ts +61 -0
- package/sdk/dist/node/lightning-wallet.d.ts.map +1 -0
- package/sdk/dist/node/lightning-wallet.js +126 -0
- package/sdk/dist/node/lightning-wallet.js.map +1 -0
- package/sdk/dist/node/local-actions.d.ts +23 -0
- package/sdk/dist/node/local-actions.d.ts.map +1 -0
- package/sdk/dist/node/local-actions.js +38 -0
- package/sdk/dist/node/local-actions.js.map +1 -0
- package/sdk/dist/node/org-context.d.ts +169 -0
- package/sdk/dist/node/org-context.d.ts.map +1 -0
- package/sdk/dist/node/org-context.js +403 -0
- package/sdk/dist/node/org-context.js.map +1 -0
- package/sdk/dist/node/status.d.ts +62 -0
- package/sdk/dist/node/status.d.ts.map +1 -0
- package/sdk/dist/node/status.js +132 -0
- package/sdk/dist/node/status.js.map +1 -0
- package/sdk/dist/node/vault-target.d.ts +49 -0
- package/sdk/dist/node/vault-target.d.ts.map +1 -0
- package/sdk/dist/node/vault-target.js +109 -0
- package/sdk/dist/node/vault-target.js.map +1 -0
- package/sdk/dist/node/wallets.d.ts +242 -0
- package/sdk/dist/node/wallets.d.ts.map +1 -0
- package/sdk/dist/node/wallets.js +484 -0
- package/sdk/dist/node/wallets.js.map +1 -0
- package/sdk/dist/project-auth-classification.d.ts +8 -8
- package/sdk/dist/project-auth-classification.d.ts.map +1 -1
- package/sdk/dist/project-auth-classification.js +7 -7
- package/sdk/dist/project-auth-classification.js.map +1 -1
- package/sdk/dist/scoped.d.ts +6 -14
- package/sdk/dist/scoped.d.ts.map +1 -1
- package/sdk/dist/scoped.js +10 -21
- package/sdk/dist/scoped.js.map +1 -1
- package/sdk/dist/secret-gate.d.ts +377 -0
- package/sdk/dist/secret-gate.d.ts.map +1 -0
- package/sdk/dist/secret-gate.js +273 -0
- package/sdk/dist/secret-gate.js.map +1 -0
- package/vault-surface.json +1 -1
- package/fixtures/buzz-v0.5.2-cli-capabilities.json +0 -92
- package/fixtures/run402-buzz-doctor-v1-contract.json +0 -140
- package/lib/buzz-doctor-contract.mjs +0 -97
- package/lib/buzz-doctor-contract.test.mjs +0 -134
- package/lib/delegates.mjs +0 -189
- package/lib/lightning-wallet.mjs +0 -115
- package/sdk/dist/delegate-credentials.d.ts +0 -37
- package/sdk/dist/delegate-credentials.d.ts.map +0 -1
- package/sdk/dist/delegate-credentials.js +0 -41
- package/sdk/dist/delegate-credentials.js.map +0 -1
- package/sdk/dist/namespaces/delegates.d.ts +0 -50
- package/sdk/dist/namespaces/delegates.d.ts.map +0 -1
- package/sdk/dist/namespaces/delegates.js +0 -99
- package/sdk/dist/namespaces/delegates.js.map +0 -1
- package/sdk/dist/namespaces/delegates.types.d.ts +0 -88
- package/sdk/dist/namespaces/delegates.types.d.ts.map +0 -1
- package/sdk/dist/namespaces/delegates.types.js +0 -10
- package/sdk/dist/namespaces/delegates.types.js.map +0 -1
package/lib/buzz-doctor.test.mjs
CHANGED
|
@@ -5,15 +5,16 @@ import { join } from "node:path";
|
|
|
5
5
|
import { describe, it } from "node:test";
|
|
6
6
|
import { bech32 } from "@scure/base";
|
|
7
7
|
import {
|
|
8
|
-
|
|
8
|
+
BUZZ_DOCTOR_CHECK_ORDER,
|
|
9
|
+
BUZZ_DOCTOR_CONTRACT,
|
|
9
10
|
BUZZ_DOCTOR_MIN_RUN402_VERSION,
|
|
10
11
|
BUZZ_DOCTOR_REPAIR_MATRIX,
|
|
11
12
|
isPublicAddress,
|
|
12
13
|
normalizeNostrSubject,
|
|
13
|
-
parseBuzzDoctorArgs,
|
|
14
14
|
pinnedLookup,
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
validateBuzzDoctorReport,
|
|
16
|
+
} from "#sdk/node";
|
|
17
|
+
import { buildBuzzDoctorReport, parseBuzzDoctorArgs } from "./buzz-doctor.mjs";
|
|
17
18
|
|
|
18
19
|
const SUBJECT = "6b6951a5738dfe576d0c44bf7a5f8afe655005a156f9d3e648d81437c3f5ebbf";
|
|
19
20
|
const OTHER_SUBJECT = "a".repeat(64);
|
|
@@ -72,7 +73,7 @@ function healthyDependencies(overrides = {}) {
|
|
|
72
73
|
runCommand,
|
|
73
74
|
lookup: async () => [{ address: "93.184.216.34", family: 4 }],
|
|
74
75
|
pinnedRelayRead: async () => ({ ok: true, status: 200, elapsed_ms: 4 }),
|
|
75
|
-
originProbe: async () => ({
|
|
76
|
+
originProbe: async () => ({ reachable: true, classification: "ok", status: 200, elapsed_ms: 3 }),
|
|
76
77
|
updateCheck: async () => ({ name: "cli_update", status: "ok" }),
|
|
77
78
|
getActiveProfile: () => "buzz-fizz",
|
|
78
79
|
profileExistsImpl: () => true,
|
|
@@ -154,7 +155,7 @@ describe("Buzz doctor bounded zero-mutation runner", () => {
|
|
|
154
155
|
}
|
|
155
156
|
return commandError();
|
|
156
157
|
};
|
|
157
|
-
dependencies.originProbe = async () => ({
|
|
158
|
+
dependencies.originProbe = async () => ({ reachable: false, classification: "http", status: 503, error: "http_503", elapsed_ms: 3 });
|
|
158
159
|
dependencies.lookup = async () => [
|
|
159
160
|
{ address: "93.184.216.34", family: 4 },
|
|
160
161
|
{ address: "127.0.0.1", family: 4 },
|
package/lib/buzz.mjs
CHANGED
|
@@ -67,7 +67,7 @@ Advanced recovery reads:
|
|
|
67
67
|
Security:
|
|
68
68
|
- JSON stdout only; progress and pending-state advice go to stderr.
|
|
69
69
|
- This command never accepts an nsec, private key, mnemonic, seed, service key,
|
|
70
|
-
|
|
70
|
+
grant key, recovery code, or payment material.
|
|
71
71
|
- Buzz signatures are public evidence. Run402 authority still comes only from
|
|
72
72
|
human/agent principals, org membership, and project grants.
|
|
73
73
|
- Every command in this group has zero spend impact.
|
package/lib/buzz.test.mjs
CHANGED
|
@@ -7,11 +7,22 @@ import { afterEach, beforeEach, describe, it, mock } from "node:test";
|
|
|
7
7
|
let sdk;
|
|
8
8
|
const authModes = [];
|
|
9
9
|
|
|
10
|
+
// Organization resolution is real (the `--org` flag resolves locally); every
|
|
11
|
+
// other namespace is the test's fake, and `authModes` records the auth mode of
|
|
12
|
+
// each client that reaches one.
|
|
13
|
+
const { run402: realSdk } = await import("../sdk/dist/node/index.js");
|
|
10
14
|
mock.module("./sdk.mjs", {
|
|
11
15
|
namedExports: {
|
|
12
16
|
getSdk: (options = {}) => {
|
|
13
|
-
|
|
14
|
-
return
|
|
17
|
+
let recorded = false;
|
|
18
|
+
return new Proxy({}, {
|
|
19
|
+
get(_target, prop) {
|
|
20
|
+
if (prop === "orgs") return realSdk({ surface: "cli", disablePaidFetch: true }).orgs;
|
|
21
|
+
if (!recorded) authModes.push(options.authMode ?? "default");
|
|
22
|
+
recorded = true;
|
|
23
|
+
return sdk?.[prop];
|
|
24
|
+
},
|
|
25
|
+
});
|
|
15
26
|
},
|
|
16
27
|
},
|
|
17
28
|
});
|
package/lib/command-manifest.mjs
CHANGED
|
@@ -235,13 +235,10 @@ export const COMMAND_MANIFEST = [
|
|
|
235
235
|
|
|
236
236
|
// ── grants ───────────────────────────────────────────────────────────────
|
|
237
237
|
{ path: ["grants", "create"], positionals: [p("wallet")], projectScoped: true, legacyPositionalProject: true, minimalArgs: ["0x1111111111111111111111111111111111111111", "--capability", "deploy"] },
|
|
238
|
+
{ path: ["grants", "list"], positionals: [], projectScoped: true, legacyPositionalProject: true, minimalArgs: [] },
|
|
238
239
|
{ path: ["grants", "revoke"], positionals: [p("grant_id")], projectScoped: true, legacyPositionalProject: true, minimalArgs: ["grt_gate1"] },
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
{ path: ["delegates", "create"], legacyPositionalProject: false, positionals: [], projectScoped: true, minimalArgs: ["--grant", "11111111-1111-1111-1111-111111111111"] },
|
|
242
|
-
{ path: ["delegates", "list"], legacyPositionalProject: false, positionals: [], projectScoped: true, minimalArgs: [] },
|
|
243
|
-
{ path: ["delegates", "revoke"], legacyPositionalProject: false, positionals: [p("delegate_id")], projectScoped: true, minimalArgs: ["dlg_gate1"] },
|
|
244
|
-
{ path: ["delegates", "rotate"], legacyPositionalProject: false, positionals: [p("delegate_id")], projectScoped: true, minimalArgs: ["dlg_gate1"] },
|
|
240
|
+
{ path: ["grants", "revoke-key"], positionals: [p("key_id")], projectScoped: true, legacyPositionalProject: true, minimalArgs: ["key_gate1"] },
|
|
241
|
+
{ path: ["grants", "rotate-key"], positionals: [p("key_id")], projectScoped: true, legacyPositionalProject: true, minimalArgs: ["key_gate1"] },
|
|
245
242
|
|
|
246
243
|
// ── events / live ────────────────────────────────────────────────────────
|
|
247
244
|
{ path: ["events", "list"], positionals: [], projectScoped: true, legacyPositionalProject: false, minimalArgs: [], runStyle: "sub" },
|
package/lib/credentials.mjs
CHANGED
|
@@ -39,7 +39,7 @@ Project credentials (on the gateway — named, revocable, rotatable):
|
|
|
39
39
|
Revoke immediately, freeing the name
|
|
40
40
|
token [--project <project_id>] [--kind <anon|service>]
|
|
41
41
|
Mint a SHORT-LIVED token. Works with only a
|
|
42
|
-
|
|
42
|
+
grant key — the unattended recovery path.
|
|
43
43
|
|
|
44
44
|
Local cache (on this machine):
|
|
45
45
|
project-keys Manage the local project-key cache
|
|
@@ -49,7 +49,7 @@ Notes:
|
|
|
49
49
|
plus a fresh step-up, so a scoped agent credential can never escalate
|
|
50
50
|
itself into a permanent root. Authenticate with a wallet (SIWX) or a
|
|
51
51
|
sign-in session ('run402 login').
|
|
52
|
-
- 'token' is the exception: a
|
|
52
|
+
- 'token' is the exception: a grant key can mint one with no human present.
|
|
53
53
|
- Secrets are returned EXACTLY ONCE and are never recoverable. Full JSON goes
|
|
54
54
|
to stdout so you can pipe it; the warnings go to stderr.
|
|
55
55
|
|
|
@@ -106,7 +106,7 @@ Usage:
|
|
|
106
106
|
The secret is printed ONCE, on stdout, inside the JSON. Pipe it:
|
|
107
107
|
run402 credentials issue --kind service --name ci | jq -r .secret
|
|
108
108
|
|
|
109
|
-
Requires owner membership on the project's org plus a fresh step-up. A
|
|
109
|
+
Requires owner membership on the project's org plus a fresh step-up. A grant key
|
|
110
110
|
can NEVER do this; use 'run402 credentials token' instead.
|
|
111
111
|
`,
|
|
112
112
|
list: `run402 credentials list — list a project's credentials
|
|
@@ -157,7 +157,7 @@ Usage:
|
|
|
157
157
|
run402 credentials token [--project <project_id>] [--kind <anon|service>]
|
|
158
158
|
|
|
159
159
|
The cold-restart recovery path, and the ONE credential call an agent can make
|
|
160
|
-
with no human present: a
|
|
160
|
+
with no human present: a grant key is accepted here. There is no step-up because
|
|
161
161
|
there is nobody to prompt, and what you get back expires, so it cannot become a
|
|
162
162
|
durable root. Defaults to --kind service.
|
|
163
163
|
`,
|
package/lib/deploy-v2.mjs
CHANGED
|
@@ -44,7 +44,7 @@ import {
|
|
|
44
44
|
import { getSdk } from "./sdk.mjs";
|
|
45
45
|
import { reportSdkError, fail } from "./sdk-errors.mjs";
|
|
46
46
|
import { API, walletAuthHeaders, getActiveProjectId, resolveProjectId, isCoreApiTarget, updateProject } from "./config.mjs";
|
|
47
|
-
import {
|
|
47
|
+
import { grantKeyFromEnv } from "#sdk/node";
|
|
48
48
|
import { flagValue, normalizeArgv } from "./argparse.mjs";
|
|
49
49
|
import { loadLiveControlPlaneSession } from "../core-dist/control-plane-session.js";
|
|
50
50
|
import { withAutoApprove } from "./sign-in.mjs";
|
|
@@ -486,10 +486,10 @@ async function rehearseCmd(rawArgs) {
|
|
|
486
486
|
fail({ code: "BAD_USAGE", message: "--teardown must be one of: on_pass, keep, always", details: { flag: "--teardown", value: teardown } });
|
|
487
487
|
}
|
|
488
488
|
const project = flagValue(args, "--project") ?? undefined;
|
|
489
|
-
// A
|
|
489
|
+
// A grant key is a complete deploy credential and the gateway explicitly
|
|
490
490
|
// supports rehearsing with one (the route rejects only CI sessions).
|
|
491
491
|
// Rehearsal is the SAFE path; never make it the harder one.
|
|
492
|
-
if (!isCoreApiTarget() && !loadLiveControlPlaneSession() && !
|
|
492
|
+
if (!isCoreApiTarget() && !loadLiveControlPlaneSession() && !grantKeyFromEnv()) {
|
|
493
493
|
walletAuthHeaders(`/apply/v1/plans/${givenPlanId ?? "_"}/rehearse`);
|
|
494
494
|
}
|
|
495
495
|
const sdk = getSdk();
|
|
@@ -723,9 +723,9 @@ async function promoteCmd(args) {
|
|
|
723
723
|
|
|
724
724
|
// Preserve the aggressive early-exit when no local wallet is configured
|
|
725
725
|
// — same as apply.
|
|
726
|
-
// A
|
|
726
|
+
// A grant key holds `deploy` and the gateway accepts it on this route; refusing
|
|
727
727
|
// locally would tell a wallet-less holder to run `run402 init` (see 4.11.2).
|
|
728
|
-
if (!
|
|
728
|
+
if (!grantKeyFromEnv()) walletAuthHeaders("/apply/v1/releases");
|
|
729
729
|
|
|
730
730
|
try {
|
|
731
731
|
// Call the engine directly (matches the pattern used by apply / resume
|
|
@@ -1295,20 +1295,20 @@ async function deployCmd(args) {
|
|
|
1295
1295
|
|
|
1296
1296
|
|
|
1297
1297
|
let sdkOpts;
|
|
1298
|
-
const
|
|
1298
|
+
const grantKey = grantKeyFromEnv();
|
|
1299
1299
|
if (useGithubActionsOidc) {
|
|
1300
1300
|
sdkOpts = {
|
|
1301
1301
|
credentials: githubActionsCredentials({ projectId: releaseSpec.project_id, apiBase: API }),
|
|
1302
1302
|
disablePaidFetch: true,
|
|
1303
1303
|
};
|
|
1304
|
-
} else if (
|
|
1305
|
-
// A
|
|
1304
|
+
} else if (grantKey) {
|
|
1305
|
+
// A grant key is a complete, self-contained deploy credential: the owner
|
|
1306
1306
|
// minted it with their wallet and handed it over, so this process needs no
|
|
1307
1307
|
// wallet of its own. Skipping the guard is the point — an agent that
|
|
1308
1308
|
// lost its local state (or never had a wallet) can still deploy. Paid fetch
|
|
1309
|
-
// is disabled for the same reason it is under CI: a
|
|
1309
|
+
// is disabled for the same reason it is under CI: a grant key authorizes
|
|
1310
1310
|
// deploys, not spending.
|
|
1311
|
-
sdkOpts = {
|
|
1311
|
+
sdkOpts = { grantKey, disablePaidFetch: true };
|
|
1312
1312
|
} else if (!isCoreApiTarget() && !loadLiveControlPlaneSession()) {
|
|
1313
1313
|
// Aggressive early exit when no local wallet is configured — unless a
|
|
1314
1314
|
// wallet-less person is deploying via their sign-in session
|
|
@@ -1766,9 +1766,9 @@ async function resumeCmd(args) {
|
|
|
1766
1766
|
emitDeployUpdateNotice("resume", args, { quiet: opts.quiet });
|
|
1767
1767
|
const project = resolveProjectId(opts.project);
|
|
1768
1768
|
|
|
1769
|
-
// A
|
|
1769
|
+
// A grant key holds `deploy` and the gateway accepts it on this route; refusing
|
|
1770
1770
|
// locally would tell a wallet-less holder to run `run402 init` (see 4.11.2).
|
|
1771
|
-
if (!
|
|
1771
|
+
if (!grantKeyFromEnv()) walletAuthHeaders("/apply/v1/operations");
|
|
1772
1772
|
|
|
1773
1773
|
try {
|
|
1774
1774
|
const result = await getSdk({ disablePaidFetch: true })._applyEngine.resume(opts.operationId, {
|
|
@@ -1794,9 +1794,9 @@ async function statusCmd(args) {
|
|
|
1794
1794
|
missing: "Missing <operation_id>.",
|
|
1795
1795
|
});
|
|
1796
1796
|
const project = resolveProjectId(parsed.flags["--project"] ?? null);
|
|
1797
|
-
// A
|
|
1797
|
+
// A grant key holds `deploy` and the gateway accepts it on this route; refusing
|
|
1798
1798
|
// locally would tell a wallet-less holder to run `run402 init` (see 4.11.2).
|
|
1799
|
-
if (!
|
|
1799
|
+
if (!grantKeyFromEnv()) walletAuthHeaders("/apply/v1/operations");
|
|
1800
1800
|
|
|
1801
1801
|
try {
|
|
1802
1802
|
const result = await getSdk()._applyEngine.status(operationId, { project });
|
|
@@ -1822,24 +1822,24 @@ async function listCmd(args) {
|
|
|
1822
1822
|
};
|
|
1823
1823
|
|
|
1824
1824
|
const project = resolveProjectId(opts.project);
|
|
1825
|
-
// NOT ungated for
|
|
1825
|
+
// NOT ungated for grant keys, deliberately: /apply/v1/operations (list) is
|
|
1826
1826
|
// `apikeyAuth` only — unlike get/events/resume/promote, which accept a
|
|
1827
|
-
//
|
|
1827
|
+
// grant-key bearer. Listing every operation on a project is broader than
|
|
1828
1828
|
// the per-operation reads a deploy credential is scoped to. If this is
|
|
1829
1829
|
// ever widened, widen the ROUTE first, then this guard.
|
|
1830
1830
|
//
|
|
1831
1831
|
// The refusal is correct; the REMEDY must still be honest. Falling through
|
|
1832
|
-
// to NO_WALLET would tell a
|
|
1832
|
+
// to NO_WALLET would tell a grant-key holder to run `run402 init`, which
|
|
1833
1833
|
// is wrong for a credential that is wallet-less by design — the same
|
|
1834
1834
|
// misleading-remedy shape removed from the payment path in 4.11.2.
|
|
1835
|
-
if (
|
|
1835
|
+
if (grantKeyFromEnv()) {
|
|
1836
1836
|
fail({
|
|
1837
|
-
code: "
|
|
1838
|
-
message: "Listing deploy operations is not available to a
|
|
1839
|
-
hint: "Use `run402 deploy status <operation_id>`, `deploy events <operation_id>` or `deploy verify <operation_id>` for a specific operation, which a
|
|
1840
|
-
details: { command: "deploy list", credential: "
|
|
1837
|
+
code: "GRANT_KEY_SCOPE_INSUFFICIENT",
|
|
1838
|
+
message: "Listing deploy operations is not available to a grant key.",
|
|
1839
|
+
hint: "Use `run402 deploy status <operation_id>`, `deploy events <operation_id>` or `deploy verify <operation_id>` for a specific operation, which a grant key CAN read. A full listing needs the project apikey or the owner wallet.",
|
|
1840
|
+
details: { command: "deploy list", credential: "grant_key", route: "GET /apply/v1/operations" },
|
|
1841
1841
|
next_actions: [
|
|
1842
|
-
{ type: "run_command", command: "run402 deploy status <operation_id>", why: "Per-operation reads are within a
|
|
1842
|
+
{ type: "run_command", command: "run402 deploy status <operation_id>", why: "Per-operation reads are within a grant key's deploy scope." },
|
|
1843
1843
|
],
|
|
1844
1844
|
});
|
|
1845
1845
|
}
|
|
@@ -1870,9 +1870,9 @@ async function eventsCmd(args) {
|
|
|
1870
1870
|
const opts = { operationId, project: parsed.flags["--project"] ?? null };
|
|
1871
1871
|
|
|
1872
1872
|
const project = resolveProjectId(opts.project);
|
|
1873
|
-
// A
|
|
1873
|
+
// A grant key holds `deploy` and the gateway accepts it on this route; refusing
|
|
1874
1874
|
// locally would tell a wallet-less holder to run `run402 init` (see 4.11.2).
|
|
1875
|
-
if (!
|
|
1875
|
+
if (!grantKeyFromEnv()) walletAuthHeaders("/apply/v1/operations");
|
|
1876
1876
|
|
|
1877
1877
|
try {
|
|
1878
1878
|
const result = await getSdk()._applyEngine.events(opts.operationId, { project });
|
|
@@ -1916,9 +1916,9 @@ async function verifyCmd(args) {
|
|
|
1916
1916
|
? 60
|
|
1917
1917
|
: parsePositiveInt(parsed.flags["--timeout"], "--timeout");
|
|
1918
1918
|
|
|
1919
|
-
// A
|
|
1919
|
+
// A grant key holds `deploy` and the gateway accepts it on this route; refusing
|
|
1920
1920
|
// locally would tell a wallet-less holder to run `run402 init` (see 4.11.2).
|
|
1921
|
-
if (!
|
|
1921
|
+
if (!grantKeyFromEnv()) walletAuthHeaders("/apply/v1/operations");
|
|
1922
1922
|
|
|
1923
1923
|
try {
|
|
1924
1924
|
let result;
|