run402 4.7.0 → 4.9.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/cli.mjs +6 -6
- package/lib/admin.mjs +17 -24
- package/lib/apps.mjs +68 -50
- package/lib/argparse.mjs +68 -1
- package/lib/assets.mjs +6 -8
- package/lib/billing.mjs +15 -11
- package/lib/branches.mjs +20 -17
- package/lib/ci.mjs +2 -0
- package/lib/cloud.mjs +25 -18
- package/lib/command-manifest.mjs +352 -0
- package/lib/contracts.mjs +47 -10
- package/lib/deploy-v2.mjs +21 -8
- package/lib/functions.mjs +99 -54
- package/lib/grants.mjs +39 -20
- package/lib/jobs.mjs +15 -9
- package/lib/notifications.mjs +431 -11
- package/lib/org.mjs +86 -48
- package/lib/projects.mjs +67 -38
- package/lib/secrets.mjs +98 -40
- package/lib/snapshots.mjs +20 -18
- package/lib/wallets.mjs +4 -3
- package/lib/webhook-secret.mjs +6 -0
- package/package.json +1 -1
- package/sdk/dist/namespaces/admin.d.ts +254 -4
- package/sdk/dist/namespaces/admin.d.ts.map +1 -1
- package/sdk/dist/namespaces/admin.js +134 -4
- package/sdk/dist/namespaces/admin.js.map +1 -1
- package/sdk/dist/namespaces/projects.d.ts +2 -1
- package/sdk/dist/namespaces/projects.d.ts.map +1 -1
- package/sdk/dist/namespaces/projects.js +8 -12
- package/sdk/dist/namespaces/projects.js.map +1 -1
package/lib/deploy-v2.mjs
CHANGED
|
@@ -34,7 +34,7 @@ import {
|
|
|
34
34
|
import { getSdk } from "./sdk.mjs";
|
|
35
35
|
import { reportSdkError, fail } from "./sdk-errors.mjs";
|
|
36
36
|
import { API, allowanceAuthHeaders, getActiveProjectId, resolveProjectId, isCoreApiTarget } from "./config.mjs";
|
|
37
|
-
import { normalizeArgv } from "./argparse.mjs";
|
|
37
|
+
import { flagValue, normalizeArgv } from "./argparse.mjs";
|
|
38
38
|
import { loadLiveControlPlaneSession } from "../core-dist/control-plane-session.js";
|
|
39
39
|
import { withAutoApprove } from "./operator.mjs";
|
|
40
40
|
import { editRequestAction, nextAction, retryAction } from "./next-actions.mjs";
|
|
@@ -220,7 +220,12 @@ Output:
|
|
|
220
220
|
const REHEARSE_HELP = `run402 deploy rehearse — Run a persisted plan on a contained branch
|
|
221
221
|
|
|
222
222
|
Usage:
|
|
223
|
-
run402 deploy rehearse <plan_id> [--project <id>] [--teardown keep|
|
|
223
|
+
run402 deploy rehearse <plan_id> [--project <id>] [--teardown on_pass|keep|always] [--json]
|
|
224
|
+
|
|
225
|
+
Options:
|
|
226
|
+
--teardown <mode> on_pass (default: passed rehearsals delete their branch;
|
|
227
|
+
failed rehearsals keep it), keep, always. When omitted,
|
|
228
|
+
the gateway default (on_pass) applies.
|
|
224
229
|
|
|
225
230
|
Use \`run402 apply --manifest app.json --rehearse --json\` for the canonical
|
|
226
231
|
one-shot plan → upload → rehearse report flow.
|
|
@@ -367,11 +372,13 @@ async function rehearseCmd(rawArgs) {
|
|
|
367
372
|
}
|
|
368
373
|
const planId = positionals[0];
|
|
369
374
|
if (!planId || positionals.length > 1) {
|
|
370
|
-
fail({ code: "BAD_USAGE", message: "Usage: run402 deploy rehearse <plan_id> [--project <id>] [--teardown keep|
|
|
375
|
+
fail({ code: "BAD_USAGE", message: "Usage: run402 deploy rehearse <plan_id> [--project <id>] [--teardown on_pass|keep|always] [--json]" });
|
|
371
376
|
}
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
377
|
+
// When --teardown is absent, omit it from the request body entirely — the
|
|
378
|
+
// gateway defaults to on_pass (passed rehearsals delete their branch).
|
|
379
|
+
const teardown = flagValue(args, "--teardown") ?? undefined;
|
|
380
|
+
if (teardown !== undefined && !["keep", "on_pass", "always"].includes(teardown)) {
|
|
381
|
+
fail({ code: "BAD_USAGE", message: "--teardown must be one of: on_pass, keep, always", details: { flag: "--teardown", value: teardown } });
|
|
375
382
|
}
|
|
376
383
|
const project = flagValue(args, "--project") ?? undefined;
|
|
377
384
|
if (!isCoreApiTarget() && !loadLiveControlPlaneSession()) {
|
|
@@ -482,6 +489,7 @@ function parsePromoteArgs(args) {
|
|
|
482
489
|
"--allow-warnings",
|
|
483
490
|
"--quiet",
|
|
484
491
|
"--final-only",
|
|
492
|
+
"--json",
|
|
485
493
|
"--help",
|
|
486
494
|
"-h",
|
|
487
495
|
];
|
|
@@ -513,6 +521,7 @@ function parsePromoteArgs(args) {
|
|
|
513
521
|
opts.quiet = true;
|
|
514
522
|
continue;
|
|
515
523
|
}
|
|
524
|
+
if (arg === "--json") { continue; }
|
|
516
525
|
if (arg === "--allow-warnings") {
|
|
517
526
|
opts.allowWarnings = true;
|
|
518
527
|
continue;
|
|
@@ -1856,6 +1865,7 @@ async function diagnoseCmd(args) {
|
|
|
1856
1865
|
for (let i = 0; i < args.length; i++) {
|
|
1857
1866
|
const arg = args[i];
|
|
1858
1867
|
if (arg === "--help" || arg === "-h") { console.log(DIAGNOSE_HELP); process.exit(0); }
|
|
1868
|
+
if (arg === "--json") { continue; }
|
|
1859
1869
|
if (arg === "--project" && args[i + 1]) { opts.project = args[++i]; continue; }
|
|
1860
1870
|
if (arg === "--method" && args[i + 1]) { opts.method = args[++i]; continue; }
|
|
1861
1871
|
if (arg?.startsWith("--project=")) { opts.project = arg.slice("--project=".length); continue; }
|
|
@@ -1890,6 +1900,7 @@ async function resolveCmd(args) {
|
|
|
1890
1900
|
for (let i = 0; i < args.length; i++) {
|
|
1891
1901
|
const arg = args[i];
|
|
1892
1902
|
if (arg === "--help" || arg === "-h") { console.log(RESOLVE_HELP); process.exit(0); }
|
|
1903
|
+
if (arg === "--json") { continue; }
|
|
1893
1904
|
if (arg === "--project" && args[i + 1]) { opts.project = args[++i]; continue; }
|
|
1894
1905
|
if (arg === "--url" && args[i + 1]) { opts.url = args[++i]; continue; }
|
|
1895
1906
|
if (arg === "--host" && args[i + 1]) { opts.host = args[++i]; continue; }
|
|
@@ -1979,9 +1990,11 @@ function redactResolveInput(input) {
|
|
|
1979
1990
|
function parseDeploySubcommandArgs(rawArgs, { command, help, valueFlags = [], booleanFlags = [] }) {
|
|
1980
1991
|
const args = normalizeArgv(rawArgs);
|
|
1981
1992
|
const valueFlagSet = new Set(valueFlags);
|
|
1982
|
-
|
|
1993
|
+
// CLI-wide convention: --json is accepted by every deploy subcommand (a
|
|
1994
|
+
// no-op where stdout is already JSON).
|
|
1995
|
+
const booleanFlagSet = new Set([...booleanFlags, "--json"]);
|
|
1983
1996
|
const numericFlagSet = new Set(["--limit", "--site-limit", "--timeout"]);
|
|
1984
|
-
const allowedFlags = new Set([...valueFlags, ...booleanFlags, "--help", "-h"]);
|
|
1997
|
+
const allowedFlags = new Set([...valueFlags, ...booleanFlags, "--json", "--help", "-h"]);
|
|
1985
1998
|
const flags = {};
|
|
1986
1999
|
const positionals = [];
|
|
1987
2000
|
|
package/lib/functions.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import { readFileSync } from "fs";
|
|
|
2
2
|
import { findProject, API } from "./config.mjs";
|
|
3
3
|
import { getSdk } from "./sdk.mjs";
|
|
4
4
|
import { reportSdkError, fail } from "./sdk-errors.mjs";
|
|
5
|
-
import { assertKnownFlags, hasHelp, normalizeArgv, parseIntegerFlag, validateRegularFile } from "./argparse.mjs";
|
|
5
|
+
import { assertKnownFlags, hasHelp, normalizeArgv, parseIntegerFlag, resolveProjectSelector, validateRegularFile } from "./argparse.mjs";
|
|
6
6
|
import { cliCommandAction } from "./next-actions.mjs";
|
|
7
7
|
|
|
8
8
|
const FUNCTION_LOG_REQUEST_ID_RE = /^(?:req|fnrun|fnatt)_[A-Za-z0-9_-]{4,128}$/;
|
|
@@ -15,47 +15,52 @@ Usage:
|
|
|
15
15
|
run402 functions <subcommand> [args...]
|
|
16
16
|
|
|
17
17
|
Subcommands:
|
|
18
|
-
deploy <
|
|
18
|
+
deploy <name> --file <file> [--project <id>] [--timeout <s>] [--memory <mb>] [--deps <pkg,...>] [--schedule <cron>]
|
|
19
19
|
Deploy a function to a project
|
|
20
|
-
invoke <
|
|
20
|
+
invoke <name> [--project <id>] [--method <M>] [--body <json>] [--idempotency-key <key>] [--wait] [--timeout-ms <ms>] [--poll-interval-ms <ms>] [--raw]
|
|
21
21
|
Invoke a deployed function. Default
|
|
22
22
|
wraps the SDK result as JSON on stdout.
|
|
23
23
|
--raw prints the response body verbatim
|
|
24
24
|
(string body → text + newline, JSON
|
|
25
25
|
body → pretty-printed JSON).
|
|
26
|
-
logs <
|
|
26
|
+
logs <name> [--project <id>] [--tail <n>] [--since <ts>] [--request-id <req_...>] [--follow]
|
|
27
27
|
Get function logs
|
|
28
28
|
runs <action> ... Create, inspect, cancel, redrive, and
|
|
29
29
|
wait for durable function runs
|
|
30
|
-
update <
|
|
30
|
+
update <name> [--project <id>] [--schedule <cron>] [--schedule-remove] [--timeout <s>] [--memory <mb>]
|
|
31
31
|
Update function schedule or config without re-deploying
|
|
32
|
-
rebuild
|
|
32
|
+
rebuild [<name>] [--all] [--project <id>]
|
|
33
|
+
Refresh function(s) onto the current platform
|
|
33
34
|
runtime (re-bundles from stored source; no
|
|
34
35
|
source change). Pass <name> for one function
|
|
35
36
|
or --all for every function in the project.
|
|
36
|
-
list <id>
|
|
37
|
-
delete <
|
|
37
|
+
list [--project <id>] List all functions for a project
|
|
38
|
+
delete <name> [--project <id>] Delete a function
|
|
39
|
+
|
|
40
|
+
Legacy (still supported): a leading prj_... positional selects the project,
|
|
41
|
+
e.g. run402 functions deploy prj_abc123 stripe-webhook --file handler.ts
|
|
38
42
|
|
|
39
43
|
Examples:
|
|
40
|
-
run402 functions deploy
|
|
41
|
-
run402 functions deploy
|
|
42
|
-
run402 functions deploy
|
|
43
|
-
run402 functions invoke
|
|
44
|
-
run402 functions logs
|
|
45
|
-
run402 functions logs
|
|
46
|
-
run402 functions logs
|
|
47
|
-
run402 functions logs
|
|
48
|
-
run402 functions runs create
|
|
49
|
-
run402 functions runs get prj_abc123
|
|
50
|
-
run402 functions update
|
|
51
|
-
run402 functions update
|
|
52
|
-
run402 functions update
|
|
53
|
-
run402 functions rebuild
|
|
54
|
-
run402 functions rebuild
|
|
55
|
-
run402 functions list prj_abc123
|
|
56
|
-
run402 functions delete
|
|
44
|
+
run402 functions deploy stripe-webhook --file handler.ts --project prj_abc123
|
|
45
|
+
run402 functions deploy send-reminders --file remind.ts --schedule '*/15 * * * *'
|
|
46
|
+
run402 functions deploy send-reminders --file remind.ts --schedule '' # remove schedule
|
|
47
|
+
run402 functions invoke stripe-webhook --body '{"event":"test"}' --project prj_abc123
|
|
48
|
+
run402 functions logs stripe-webhook --tail 100
|
|
49
|
+
run402 functions logs stripe-webhook --since 2026-03-29T14:00:00Z
|
|
50
|
+
run402 functions logs stripe-webhook --request-id req_abc123
|
|
51
|
+
run402 functions logs stripe-webhook --follow
|
|
52
|
+
run402 functions runs create worker --event-type reminder.send --idempotency-key reminder:123 --delay 10m
|
|
53
|
+
run402 functions runs get fnrun_abc123 --project prj_abc123
|
|
54
|
+
run402 functions update send-reminders --schedule '0 */4 * * *'
|
|
55
|
+
run402 functions update send-reminders --schedule-remove
|
|
56
|
+
run402 functions update my-func --timeout 15 --memory 256
|
|
57
|
+
run402 functions rebuild stripe-webhook --project prj_abc123
|
|
58
|
+
run402 functions rebuild --all
|
|
59
|
+
run402 functions list --project prj_abc123
|
|
60
|
+
run402 functions delete stripe-webhook --project prj_abc123
|
|
57
61
|
|
|
58
62
|
Notes:
|
|
63
|
+
- --project defaults to the active project ('run402 projects use')
|
|
59
64
|
- Code must export a default async function: export default async (req: Request) => Response
|
|
60
65
|
- Deploy may require payment if the project lease has expired
|
|
61
66
|
- 'rebuild' is opt-in and never changes your source: it re-bundles the stored
|
|
@@ -67,13 +72,16 @@ const SUB_HELP = {
|
|
|
67
72
|
deploy: `run402 functions deploy — Deploy a function to a project
|
|
68
73
|
|
|
69
74
|
Usage:
|
|
75
|
+
run402 functions deploy <name> --file <file> [--project <id>] [options]
|
|
76
|
+
|
|
77
|
+
Legacy (still supported):
|
|
70
78
|
run402 functions deploy <project_id> <name> --file <file> [options]
|
|
71
79
|
|
|
72
80
|
Arguments:
|
|
73
|
-
<project_id> Target project ID
|
|
74
81
|
<name> Function name (used in the invoke URL path)
|
|
75
82
|
|
|
76
83
|
Options:
|
|
84
|
+
--project <id> Target project ID (defaults to the active project)
|
|
77
85
|
--file <file> Required: path to the function source file
|
|
78
86
|
--timeout <s> Runtime timeout in seconds
|
|
79
87
|
--memory <mb> Memory in MB
|
|
@@ -109,13 +117,16 @@ Examples:
|
|
|
109
117
|
invoke: `run402 functions invoke — Invoke a deployed function
|
|
110
118
|
|
|
111
119
|
Usage:
|
|
120
|
+
run402 functions invoke <name> [--project <id>] [options]
|
|
121
|
+
|
|
122
|
+
Legacy (still supported):
|
|
112
123
|
run402 functions invoke <project_id> <name> [options]
|
|
113
124
|
|
|
114
125
|
Arguments:
|
|
115
|
-
<project_id> Target project ID
|
|
116
126
|
<name> Function name
|
|
117
127
|
|
|
118
128
|
Options:
|
|
129
|
+
--project <id> Target project ID (defaults to the active project)
|
|
119
130
|
--method <M> HTTP method (default POST)
|
|
120
131
|
--body <json> Request body (ignored for GET/HEAD)
|
|
121
132
|
--idempotency-key <key>
|
|
@@ -151,13 +162,16 @@ Examples:
|
|
|
151
162
|
logs: `run402 functions logs — Fetch or tail function logs
|
|
152
163
|
|
|
153
164
|
Usage:
|
|
165
|
+
run402 functions logs <name> [--project <id>] [options]
|
|
166
|
+
|
|
167
|
+
Legacy (still supported):
|
|
154
168
|
run402 functions logs <project_id> <name> [options]
|
|
155
169
|
|
|
156
170
|
Arguments:
|
|
157
|
-
<project_id> Target project ID
|
|
158
171
|
<name> Function name
|
|
159
172
|
|
|
160
173
|
Options:
|
|
174
|
+
--project <id> Target project ID (defaults to the active project)
|
|
161
175
|
--tail <n> Number of most-recent entries (default 50, max 1000)
|
|
162
176
|
--since <ts> ISO timestamp or epoch ms; only entries after this
|
|
163
177
|
--request-id <id> Only entries correlated to this req_, fnrun_, or fnatt_ id
|
|
@@ -175,12 +189,15 @@ Examples:
|
|
|
175
189
|
runs: `run402 functions runs — Manage durable function runs
|
|
176
190
|
|
|
177
191
|
Usage:
|
|
178
|
-
run402 functions runs create <
|
|
179
|
-
run402 functions runs list <
|
|
180
|
-
run402 functions runs get <
|
|
181
|
-
run402 functions runs logs <
|
|
182
|
-
run402 functions runs cancel <
|
|
183
|
-
run402 functions runs redrive <
|
|
192
|
+
run402 functions runs create <function_name> --event-type <type> --idempotency-key <key> [--project <id>] [options]
|
|
193
|
+
run402 functions runs list <function_name> [--project <id>] [options]
|
|
194
|
+
run402 functions runs get <run_id> [--project <id>]
|
|
195
|
+
run402 functions runs logs <run_id> [--project <id>] [--tail <n>] [--since <ts>]
|
|
196
|
+
run402 functions runs cancel <run_id> [--project <id>]
|
|
197
|
+
run402 functions runs redrive <run_id> [--project <id>] [options]
|
|
198
|
+
|
|
199
|
+
Legacy (still supported): a leading prj_... positional selects the project,
|
|
200
|
+
e.g. run402 functions runs get <project_id> <run_id>
|
|
184
201
|
|
|
185
202
|
Create options:
|
|
186
203
|
--payload-json <json> Inline JSON object payload
|
|
@@ -211,13 +228,16 @@ Examples:
|
|
|
211
228
|
update: `run402 functions update — Update function config without re-deploying
|
|
212
229
|
|
|
213
230
|
Usage:
|
|
231
|
+
run402 functions update <name> [--project <id>] [options]
|
|
232
|
+
|
|
233
|
+
Legacy (still supported):
|
|
214
234
|
run402 functions update <project_id> <name> [options]
|
|
215
235
|
|
|
216
236
|
Arguments:
|
|
217
|
-
<project_id> Target project ID
|
|
218
237
|
<name> Function name
|
|
219
238
|
|
|
220
239
|
Options:
|
|
240
|
+
--project <id> Target project ID (defaults to the active project)
|
|
221
241
|
--schedule <cron> New cron schedule (pass '' to clear)
|
|
222
242
|
--schedule-remove Explicitly remove the schedule
|
|
223
243
|
--timeout <s> Runtime timeout in seconds
|
|
@@ -234,14 +254,18 @@ Examples:
|
|
|
234
254
|
rebuild: `run402 functions rebuild — Refresh function(s) onto the current platform runtime
|
|
235
255
|
|
|
236
256
|
Usage:
|
|
257
|
+
run402 functions rebuild <name> [--project <id>]
|
|
258
|
+
run402 functions rebuild --all [--project <id>]
|
|
259
|
+
|
|
260
|
+
Legacy (still supported):
|
|
237
261
|
run402 functions rebuild <project_id> <name>
|
|
238
262
|
run402 functions rebuild <project_id> --all
|
|
239
263
|
|
|
240
264
|
Arguments:
|
|
241
|
-
<project_id> Target project ID
|
|
242
265
|
<name> Function name to rebuild (omit when using --all)
|
|
243
266
|
|
|
244
267
|
Options:
|
|
268
|
+
--project <id> Target project ID (defaults to the active project)
|
|
245
269
|
--all Rebuild every function in the project
|
|
246
270
|
|
|
247
271
|
What it does:
|
|
@@ -273,25 +297,33 @@ Examples:
|
|
|
273
297
|
list: `run402 functions list — List all functions for a project
|
|
274
298
|
|
|
275
299
|
Usage:
|
|
300
|
+
run402 functions list [--project <id>]
|
|
301
|
+
|
|
302
|
+
Legacy (still supported):
|
|
276
303
|
run402 functions list <project_id>
|
|
277
304
|
|
|
278
|
-
|
|
279
|
-
<
|
|
305
|
+
Options:
|
|
306
|
+
--project <id> Target project ID (defaults to the active project)
|
|
280
307
|
|
|
281
308
|
Examples:
|
|
282
|
-
run402 functions list prj_abc123
|
|
309
|
+
run402 functions list --project prj_abc123
|
|
283
310
|
`,
|
|
284
311
|
delete: `run402 functions delete — Delete a function from a project
|
|
285
312
|
|
|
286
313
|
Usage:
|
|
314
|
+
run402 functions delete <name> [--project <id>]
|
|
315
|
+
|
|
316
|
+
Legacy (still supported):
|
|
287
317
|
run402 functions delete <project_id> <name>
|
|
288
318
|
|
|
289
319
|
Arguments:
|
|
290
|
-
<project_id> Target project ID
|
|
291
320
|
<name> Function name to delete
|
|
292
321
|
|
|
322
|
+
Options:
|
|
323
|
+
--project <id> Target project ID (defaults to the active project)
|
|
324
|
+
|
|
293
325
|
Examples:
|
|
294
|
-
run402 functions delete
|
|
326
|
+
run402 functions delete stripe-webhook --project prj_abc123
|
|
295
327
|
`,
|
|
296
328
|
};
|
|
297
329
|
|
|
@@ -514,12 +546,21 @@ async function runs(action, args = []) {
|
|
|
514
546
|
console.log(SUB_HELP.runs);
|
|
515
547
|
process.exit(0);
|
|
516
548
|
}
|
|
517
|
-
|
|
518
|
-
if (
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
549
|
+
const KNOWN_ACTIONS = new Set(["create", "list", "get", "logs", "cancel", "redrive"]);
|
|
550
|
+
if (!KNOWN_ACTIONS.has(action)) {
|
|
551
|
+
fail({
|
|
552
|
+
code: "BAD_USAGE",
|
|
553
|
+
message: `Unknown functions runs action: ${action}`,
|
|
554
|
+
hint: "run402 functions runs <create|list|get|logs|cancel|redrive> ...",
|
|
555
|
+
});
|
|
556
|
+
}
|
|
557
|
+
const { projectId, rest } = resolveProjectSelector(args);
|
|
558
|
+
if (action === "create") return runsCreate(projectId, rest[0], rest.slice(1));
|
|
559
|
+
if (action === "list") return runsList(projectId, rest[0], rest.slice(1));
|
|
560
|
+
if (action === "get") return runsGet(projectId, rest[0], rest.slice(1));
|
|
561
|
+
if (action === "logs") return runsLogs(projectId, rest[0], rest.slice(1));
|
|
562
|
+
if (action === "cancel") return runsCancel(projectId, rest[0], rest.slice(1));
|
|
563
|
+
if (action === "redrive") return runsRedrive(projectId, rest[0], rest.slice(1));
|
|
523
564
|
fail({
|
|
524
565
|
code: "BAD_USAGE",
|
|
525
566
|
message: `Unknown functions runs action: ${action}`,
|
|
@@ -837,15 +878,19 @@ export async function run(sub, args) {
|
|
|
837
878
|
console.log(SUB_HELP[sub] || HELP);
|
|
838
879
|
process.exit(0);
|
|
839
880
|
}
|
|
881
|
+
// Project selection (CLI-wide convention): `--project <id>` wins, else a
|
|
882
|
+
// legacy leading `prj_...` positional, else the active project. Computed
|
|
883
|
+
// lazily so unknown subcommands never trip project resolution.
|
|
884
|
+
const select = () => resolveProjectSelector(args);
|
|
840
885
|
switch (sub) {
|
|
841
|
-
case "deploy": await deploy(
|
|
842
|
-
case "invoke": await invoke(
|
|
843
|
-
case "logs": await logs(
|
|
886
|
+
case "deploy": { const { projectId, rest } = select(); await deploy(projectId, rest[0], rest.slice(1)); break; }
|
|
887
|
+
case "invoke": { const { projectId, rest } = select(); await invoke(projectId, rest[0], rest.slice(1)); break; }
|
|
888
|
+
case "logs": { const { projectId, rest } = select(); await logs(projectId, rest[0], rest.slice(1)); break; }
|
|
844
889
|
case "runs": await runs(args[0], args.slice(1)); break;
|
|
845
|
-
case "update": await update(
|
|
846
|
-
case "rebuild": await rebuild(
|
|
847
|
-
case "list": await list(
|
|
848
|
-
case "delete": await deleteFunction(
|
|
890
|
+
case "update": { const { projectId, rest } = select(); await update(projectId, rest[0], rest.slice(1)); break; }
|
|
891
|
+
case "rebuild": { const { projectId, rest } = select(); await rebuild(projectId, rest); break; }
|
|
892
|
+
case "list": { const { projectId, rest } = select(); await list(projectId, rest); break; }
|
|
893
|
+
case "delete": { const { projectId, rest } = select(); await deleteFunction(projectId, rest[0], rest.slice(1)); break; }
|
|
849
894
|
default:
|
|
850
895
|
fail({ code: "UNKNOWN_SUBCOMMAND", message: `Unknown functions subcommand: ${sub}`, hint: "Run `run402 functions --help` for usage.", details: { command: "functions", subcommand: sub } });
|
|
851
896
|
}
|
package/lib/grants.mjs
CHANGED
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
assertKnownFlags,
|
|
6
6
|
flagValue,
|
|
7
7
|
requirePositionalCount,
|
|
8
|
+
resolveProjectSelector,
|
|
8
9
|
} from "./argparse.mjs";
|
|
9
10
|
|
|
10
11
|
const HELP = `run402 grants — per-project capability grants (agent/CI principals)
|
|
@@ -13,11 +14,15 @@ Usage:
|
|
|
13
14
|
run402 grants <subcommand> [args...]
|
|
14
15
|
|
|
15
16
|
Subcommands:
|
|
16
|
-
create <
|
|
17
|
+
create <wallet> --capability <cap> [--project <id>] [--policy <json>] [--expires <iso8601>]
|
|
17
18
|
Issue a capability grant (owner of the project's org)
|
|
18
|
-
revoke <
|
|
19
|
+
revoke <grant_id> [--project <id>]
|
|
19
20
|
Revoke a capability grant
|
|
20
21
|
|
|
22
|
+
Legacy (still supported):
|
|
23
|
+
run402 grants create <project_id> <wallet> <capability> [...]
|
|
24
|
+
run402 grants revoke <project_id> <grant_id>
|
|
25
|
+
|
|
21
26
|
Notes:
|
|
22
27
|
- Grants let a non-member wallet (an agent or CI principal) act on ONE project,
|
|
23
28
|
without making it a broad org member. Mutations require owner of the project's org.
|
|
@@ -25,23 +30,26 @@ Notes:
|
|
|
25
30
|
- JSON in, JSON out.
|
|
26
31
|
|
|
27
32
|
Examples:
|
|
28
|
-
run402 grants create
|
|
29
|
-
run402 grants create
|
|
30
|
-
run402 grants revoke prj_abc
|
|
33
|
+
run402 grants create 0xf39Fd6...92266 --capability deploy --project prj_abc
|
|
34
|
+
run402 grants create 0xf39Fd6...92266 --capability functions:write --expires 2026-12-31T00:00:00Z
|
|
35
|
+
run402 grants revoke grt_xyz --project prj_abc
|
|
31
36
|
`;
|
|
32
37
|
|
|
33
38
|
const SUB_HELP = {
|
|
34
39
|
create: `run402 grants create — issue a per-project capability grant
|
|
35
40
|
|
|
36
41
|
Usage:
|
|
37
|
-
run402 grants create <
|
|
42
|
+
run402 grants create <wallet> --capability <cap> [--project <id>] [--policy <json>] [--expires <iso8601>]
|
|
43
|
+
|
|
44
|
+
Legacy (still supported):
|
|
45
|
+
run402 grants create <project_id> <wallet> <capability> [options]
|
|
38
46
|
|
|
39
47
|
Arguments:
|
|
40
|
-
<project_id> Project to grant access to
|
|
41
48
|
<wallet> EVM address or named wallet the grant is issued to
|
|
42
|
-
<capability> e.g. deploy, functions:write
|
|
43
49
|
|
|
44
50
|
Options:
|
|
51
|
+
--project <id> Project to grant access to (defaults to the active project)
|
|
52
|
+
--capability <cap> e.g. deploy, functions:write (alternative to the legacy positional)
|
|
45
53
|
--policy <json> Capability-scoping policy object (gateway-interpreted)
|
|
46
54
|
--expires <iso8601> Expiry timestamp; omit for a non-expiring grant
|
|
47
55
|
|
|
@@ -50,23 +58,33 @@ Requires you to be an owner of the project's org.
|
|
|
50
58
|
revoke: `run402 grants revoke — revoke a per-project capability grant
|
|
51
59
|
|
|
52
60
|
Usage:
|
|
61
|
+
run402 grants revoke <grant_id> [--project <id>]
|
|
62
|
+
|
|
63
|
+
Legacy (still supported):
|
|
53
64
|
run402 grants revoke <project_id> <grant_id>
|
|
54
65
|
|
|
55
66
|
Requires you to be an owner of the project's org.
|
|
56
67
|
`,
|
|
57
68
|
};
|
|
58
69
|
|
|
70
|
+
const CREATE_VALUE_FLAGS = ["--project", "--capability", "--policy", "--expires"];
|
|
71
|
+
|
|
59
72
|
async function create(args) {
|
|
60
73
|
const a = normalizeArgv(args);
|
|
61
|
-
assertKnownFlags(a, [
|
|
74
|
+
assertKnownFlags(a, [...CREATE_VALUE_FLAGS, "--help", "-h"], CREATE_VALUE_FLAGS);
|
|
62
75
|
const policyRaw = flagValue(a, "--policy");
|
|
63
76
|
const expiresAt = flagValue(a, "--expires");
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
77
|
+
const capabilityFlag = flagValue(a, "--capability");
|
|
78
|
+
const { projectId, rest } = resolveProjectSelector(a, { valueFlags: CREATE_VALUE_FLAGS });
|
|
79
|
+
const expected = capabilityFlag ? 1 : 2;
|
|
80
|
+
const pos = requirePositionalCount(rest, CREATE_VALUE_FLAGS, {
|
|
81
|
+
min: expected,
|
|
82
|
+
max: expected,
|
|
83
|
+
command: "run402 grants create <wallet> --capability <cap> [--project <id>] [--policy <json>] [--expires <iso8601>]",
|
|
84
|
+
missing: capabilityFlag ? "Missing <wallet>." : "Missing <wallet> and/or <capability>.",
|
|
69
85
|
});
|
|
86
|
+
const wallet = pos[0];
|
|
87
|
+
const capability = capabilityFlag ?? pos[1];
|
|
70
88
|
const policy = policyRaw != null ? parseFlagJson("--policy", policyRaw) : undefined;
|
|
71
89
|
try {
|
|
72
90
|
const res = await getSdk().grants.create(projectId, {
|
|
@@ -83,12 +101,13 @@ async function create(args) {
|
|
|
83
101
|
|
|
84
102
|
async function revoke(args) {
|
|
85
103
|
const a = normalizeArgv(args);
|
|
86
|
-
assertKnownFlags(a, ["--help", "-h"]);
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
104
|
+
assertKnownFlags(a, ["--project", "--help", "-h"], ["--project"]);
|
|
105
|
+
const { projectId, rest } = resolveProjectSelector(a, { valueFlags: ["--project"] });
|
|
106
|
+
const [grantId] = requirePositionalCount(rest, ["--project"], {
|
|
107
|
+
min: 1,
|
|
108
|
+
max: 1,
|
|
109
|
+
command: "run402 grants revoke <grant_id> [--project <id>]",
|
|
110
|
+
missing: "Missing <grant_id>.",
|
|
92
111
|
});
|
|
93
112
|
try {
|
|
94
113
|
console.log(JSON.stringify(await getSdk().grants.revoke(projectId, grantId), null, 2));
|
package/lib/jobs.mjs
CHANGED
|
@@ -27,7 +27,7 @@ Subcommands:
|
|
|
27
27
|
logs <job_id> Read job logs
|
|
28
28
|
cancel <job_id> Cancel a queued or running job
|
|
29
29
|
purge Purge all job runs for the project
|
|
30
|
-
artifacts get <job_id> <
|
|
30
|
+
artifacts get <job_id> --file <name> Download a completed job's artifact (legacy: <job_id> <file>)
|
|
31
31
|
|
|
32
32
|
Examples:
|
|
33
33
|
run402 jobs submit --file job.json
|
|
@@ -120,6 +120,9 @@ recorded filenames on a given run.
|
|
|
120
120
|
"artifacts get": `run402 jobs artifacts get — Download a completed job's artifact
|
|
121
121
|
|
|
122
122
|
Usage:
|
|
123
|
+
run402 jobs artifacts get <job_id> --file <name> --output <path> [--project <id>]
|
|
124
|
+
|
|
125
|
+
Legacy (still supported):
|
|
123
126
|
run402 jobs artifacts get <job_id> <file> --output <path> [--project <id>]
|
|
124
127
|
|
|
125
128
|
Options:
|
|
@@ -355,24 +358,27 @@ async function artifactsGet(args = []) {
|
|
|
355
358
|
process.exit(0);
|
|
356
359
|
}
|
|
357
360
|
const parsed = normalizeArgv(args);
|
|
358
|
-
const valueFlags = ["--project", "--output", "-o"];
|
|
359
|
-
assertKnownFlags(parsed, ["--project", "--output", "-o", "--help", "-h"], valueFlags);
|
|
361
|
+
const valueFlags = ["--project", "--output", "-o", "--file"];
|
|
362
|
+
assertKnownFlags(parsed, ["--project", "--output", "-o", "--file", "--help", "-h"], valueFlags);
|
|
363
|
+
const fileFlag = flagValue(parsed, "--file");
|
|
364
|
+
const expected = fileFlag ? 1 : 2;
|
|
360
365
|
const positionals = positionalArgs(parsed, valueFlags);
|
|
361
|
-
if (positionals.length <
|
|
366
|
+
if (positionals.length < expected) {
|
|
362
367
|
fail({
|
|
363
368
|
code: "BAD_USAGE",
|
|
364
369
|
message: "Missing job_id and/or artifact filename.",
|
|
365
|
-
hint: "Use `run402 jobs artifacts get <job_id> <
|
|
370
|
+
hint: "Use `run402 jobs artifacts get <job_id> --file <name> --output <path>`.",
|
|
366
371
|
});
|
|
367
372
|
}
|
|
368
|
-
if (positionals.length >
|
|
373
|
+
if (positionals.length > expected) {
|
|
369
374
|
fail({
|
|
370
375
|
code: "BAD_USAGE",
|
|
371
|
-
message: `Unexpected argument: ${positionals[
|
|
372
|
-
hint: "Use `run402 jobs artifacts get <job_id> <
|
|
376
|
+
message: `Unexpected argument: ${positionals[expected]}`,
|
|
377
|
+
hint: "Use `run402 jobs artifacts get <job_id> --file <name> --output <path>`.",
|
|
373
378
|
});
|
|
374
379
|
}
|
|
375
|
-
const
|
|
380
|
+
const jobId = positionals[0];
|
|
381
|
+
const filename = fileFlag ?? positionals[1];
|
|
376
382
|
const output = flagValue(parsed, "--output") ?? flagValue(parsed, "-o");
|
|
377
383
|
if (!output) {
|
|
378
384
|
fail({
|