run402 4.83.0 → 4.85.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/gitvault-surface.json +1 -1
- package/lib/deploy-v2.mjs +30 -68
- package/lib/doctor-source-scan.mjs +2 -547
- package/lib/doctor.mjs +28 -8
- package/lib/sdk-errors.mjs +7 -0
- package/lib/status.mjs +1 -1
- package/lib/up.mjs +29 -10
- package/lib/update-check.mjs +20 -10
- package/lib/update-check.test.mjs +57 -5
- package/package.json +1 -1
- package/sdk/dist/actions.d.ts +19 -4
- package/sdk/dist/actions.d.ts.map +1 -1
- package/sdk/dist/config.d.ts +1 -1
- package/sdk/dist/config.d.ts.map +1 -1
- package/sdk/dist/config.js.map +1 -1
- package/sdk/dist/index.d.ts +2 -0
- package/sdk/dist/index.d.ts.map +1 -1
- package/sdk/dist/index.js +2 -0
- package/sdk/dist/index.js.map +1 -1
- package/sdk/dist/namespaces/deploy.d.ts.map +1 -1
- package/sdk/dist/namespaces/deploy.js +2 -1
- package/sdk/dist/namespaces/deploy.js.map +1 -1
- package/sdk/dist/namespaces/deploy.types.d.ts +6 -0
- package/sdk/dist/namespaces/deploy.types.d.ts.map +1 -1
- package/sdk/dist/namespaces/edge-evidence.d.ts +22 -0
- package/sdk/dist/namespaces/edge-evidence.d.ts.map +1 -0
- package/sdk/dist/namespaces/edge-evidence.js +38 -0
- package/sdk/dist/namespaces/edge-evidence.js.map +1 -0
- package/sdk/dist/namespaces/projects.d.ts.map +1 -1
- package/sdk/dist/namespaces/projects.js +9 -7
- package/sdk/dist/namespaces/projects.js.map +1 -1
- package/sdk/dist/node/actions-node.d.ts.map +1 -1
- package/sdk/dist/node/actions-node.js +73 -58
- package/sdk/dist/node/actions-node.js.map +1 -1
- package/sdk/dist/node/app-scope.d.ts +24 -0
- package/sdk/dist/node/app-scope.d.ts.map +1 -0
- package/sdk/dist/node/app-scope.js +47 -0
- package/sdk/dist/node/app-scope.js.map +1 -0
- package/sdk/dist/node/deploy-manifest.d.ts +6 -0
- package/sdk/dist/node/deploy-manifest.d.ts.map +1 -1
- package/sdk/dist/node/deploy-manifest.js +61 -0
- package/sdk/dist/node/deploy-manifest.js.map +1 -1
- package/sdk/dist/node/index.d.ts +5 -0
- package/sdk/dist/node/index.d.ts.map +1 -1
- package/sdk/dist/node/index.js +5 -0
- package/sdk/dist/node/index.js.map +1 -1
- package/sdk/dist/node/manifest-export.d.ts +5 -0
- package/sdk/dist/node/manifest-export.d.ts.map +1 -0
- package/sdk/dist/node/manifest-export.js +78 -0
- package/sdk/dist/node/manifest-export.js.map +1 -0
- package/sdk/dist/node/preflight.d.ts +65 -0
- package/sdk/dist/node/preflight.d.ts.map +1 -0
- package/sdk/dist/node/preflight.js +23 -0
- package/sdk/dist/node/preflight.js.map +1 -0
- package/sdk/dist/node/source-scan.d.ts +73 -0
- package/sdk/dist/node/source-scan.d.ts.map +1 -0
- package/sdk/dist/node/source-scan.js +552 -0
- package/sdk/dist/node/source-scan.js.map +1 -0
- package/sdk/dist/rest-diagnostics.d.ts +15 -0
- package/sdk/dist/rest-diagnostics.d.ts.map +1 -0
- package/sdk/dist/rest-diagnostics.js +19 -0
- package/sdk/dist/rest-diagnostics.js.map +1 -0
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# run402 CLI
|
|
2
2
|
|
|
3
|
-
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. **Prototype tier is free on testnet.**
|
|
3
|
+
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.**
|
|
4
4
|
|
|
5
5
|
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 collaborators without becoming routine CLI operators.
|
|
6
6
|
|
|
@@ -293,7 +293,7 @@ For Run402 Core, use the same commands after `run402 init --api-base=http://my-c
|
|
|
293
293
|
run402 image generate "a serif logo" --aspect square --output logo.png
|
|
294
294
|
```
|
|
295
295
|
|
|
296
|
-
$0.03 per image via x402.
|
|
296
|
+
$0.03 per image via x402, MPP on Tempo, or Bitcoin Lightning.
|
|
297
297
|
|
|
298
298
|
### On-chain (KMS signers)
|
|
299
299
|
|
|
@@ -340,7 +340,7 @@ Hold several wallets on one machine and select between them:
|
|
|
340
340
|
- Select per-command with `--wallet <name>` (alias `--profile`), the `RUN402_WALLET` env var, or a per-directory `.run402.json` (commit-safe — holds only a name) resolved by walking up the tree. Precedence: flag > env > binding > `wallets use` default > `default`. A conflicting env + binding is a hard error.
|
|
341
341
|
- The active wallet name shows in `run402 status` and `run402 wallets current`.
|
|
342
342
|
|
|
343
|
-
The CLI handles all x402 payment signing automatically — never ask the human for a private key or set up payment libraries by hand.
|
|
343
|
+
The CLI handles all x402 / MPP payment signing automatically — never ask the human for a private key or set up payment libraries by hand.
|
|
344
344
|
|
|
345
345
|
### Operator (human / email session)
|
|
346
346
|
|
package/gitvault-surface.json
CHANGED
package/lib/deploy-v2.mjs
CHANGED
|
@@ -33,6 +33,10 @@ import {
|
|
|
33
33
|
normalizeDeployManifest,
|
|
34
34
|
normalizeDeployResolveRequest,
|
|
35
35
|
resolveDeploymentTarget,
|
|
36
|
+
resolveApplicationScope,
|
|
37
|
+
scanDeploymentSources,
|
|
38
|
+
serializeDeployManifest,
|
|
39
|
+
describeLocalPreflight,
|
|
36
40
|
} from "#sdk/node";
|
|
37
41
|
import { getSdk } from "./sdk.mjs";
|
|
38
42
|
import { reportSdkError, fail } from "./sdk-errors.mjs";
|
|
@@ -48,8 +52,8 @@ import { sdkStats, printVerboseStats } from "./stats.mjs";
|
|
|
48
52
|
const APPLY_HELP = `run402 deploy apply — Unified deploy primitive (v1.34+)
|
|
49
53
|
|
|
50
54
|
Usage:
|
|
51
|
-
run402 deploy apply --manifest <path> [--project <id>] [--check|--print-spec|--plan|--require-plan <id>] [--no-rehearse] [--quiet|--final-only] [--json]
|
|
52
|
-
run402 deploy apply --spec '<json>' [--project <id>] [--check|--print-spec|--plan|--require-plan <id>] [--no-rehearse] [--quiet|--final-only] [--json]
|
|
55
|
+
run402 deploy apply --manifest <path> [--project <id>] [--check|--print-spec|--print-manifest|--plan|--require-plan <id>] [--no-rehearse] [--quiet|--final-only] [--json]
|
|
56
|
+
run402 deploy apply --spec '<json>' [--project <id>] [--check|--print-spec|--print-manifest|--plan|--require-plan <id>] [--no-rehearse] [--quiet|--final-only] [--json]
|
|
53
57
|
run402 deploy apply --dir <build-output> [--manifest <path>] [--project <id>]
|
|
54
58
|
cat spec.json | run402 deploy apply [--project <id>]
|
|
55
59
|
|
|
@@ -98,7 +102,9 @@ Options:
|
|
|
98
102
|
@run402/astro installed in the project.
|
|
99
103
|
--project <id> Override project_id from the manifest
|
|
100
104
|
--check Validate and normalize locally. No gateway calls or uploads.
|
|
101
|
-
--print-spec
|
|
105
|
+
--print-spec Advanced SDK-native inspection JSON, not authoring input.
|
|
106
|
+
--print-manifest Export snake_case authoring JSON relative to the original manifest
|
|
107
|
+
directory. Unsupported constructs fail; no gateway calls or uploads.
|
|
102
108
|
--plan Ask the gateway for a reviewed plan. No upload or commit.
|
|
103
109
|
--no-rehearse Skip the automatic rehearsal. By default a migration-bearing plan
|
|
104
110
|
against a project with a live release is rehearsed on a contained
|
|
@@ -769,7 +775,7 @@ function parseApplyArgs(args) {
|
|
|
769
775
|
allowDirty: false,
|
|
770
776
|
verbose: false,
|
|
771
777
|
};
|
|
772
|
-
const allowedFlags = ["--manifest", "--spec", "--dir", "--project", "--quiet", "--final-only", "--json", "--allow-warning", "--allow-warnings", "--check", "--print-spec", "--plan", "--no-rehearse", "--require-plan", "--plan-fingerprint", "--allow-dirty", "-v", "--verbose", "--help", "-h"];
|
|
778
|
+
const allowedFlags = ["--manifest", "--spec", "--dir", "--project", "--quiet", "--final-only", "--json", "--allow-warning", "--allow-warnings", "--check", "--print-spec", "--print-manifest", "--plan", "--no-rehearse", "--require-plan", "--plan-fingerprint", "--allow-dirty", "-v", "--verbose", "--help", "-h"];
|
|
773
779
|
|
|
774
780
|
for (let i = 0; i < args.length; i++) {
|
|
775
781
|
const arg = args[i];
|
|
@@ -832,6 +838,7 @@ function parseApplyArgs(args) {
|
|
|
832
838
|
if (arg === "-v" || arg === "--verbose") { opts.verbose = true; continue; }
|
|
833
839
|
if (arg === "--check") { setApplyMode(opts, "check", "--check"); continue; }
|
|
834
840
|
if (arg === "--print-spec") { setApplyMode(opts, "printSpec", "--print-spec"); continue; }
|
|
841
|
+
if (arg === "--print-manifest") { setApplyMode(opts, "printManifest", "--print-manifest"); continue; }
|
|
835
842
|
if (arg === "--plan") { setApplyMode(opts, "plan", "--plan"); continue; }
|
|
836
843
|
if (arg === "--no-rehearse") { opts.noRehearse = true; continue; }
|
|
837
844
|
if (typeof arg === "string" && arg.startsWith("-")) {
|
|
@@ -1168,6 +1175,7 @@ async function applyCmd(args) {
|
|
|
1168
1175
|
? await loadDeployManifest(manifestPath, {
|
|
1169
1176
|
|
|
1170
1177
|
...(defaultProject ? { defaultProject } : {}),
|
|
1178
|
+
validateFiles: true,
|
|
1171
1179
|
})
|
|
1172
1180
|
: await normalizeDeployManifest(spec, {
|
|
1173
1181
|
baseDir: manifestPath ? dirname(manifestPath) : process.cwd(),
|
|
@@ -1178,14 +1186,16 @@ async function applyCmd(args) {
|
|
|
1178
1186
|
reportSdkError(err);
|
|
1179
1187
|
}
|
|
1180
1188
|
|
|
1189
|
+
const applicationScope = await resolveApplicationScope({ dir: opts.dir, manifest: manifestPath ?? undefined });
|
|
1181
1190
|
const releaseSpec = normalizedManifest.spec;
|
|
1191
|
+
let target;
|
|
1182
1192
|
try {
|
|
1183
|
-
|
|
1184
|
-
appRoot:
|
|
1193
|
+
target = await resolveDeploymentTarget({
|
|
1194
|
+
appRoot: applicationScope.app_root,
|
|
1185
1195
|
manifestPath: manifestPath ?? undefined, projectId: opts.project || undefined, environmentProjectId: process.env.RUN402_PROJECT_ID || undefined,
|
|
1186
1196
|
manifestProjectId: manifestProject || (releaseSpec.project === "prj_up_preflight_placeholder" ? undefined : releaseSpec.project),
|
|
1187
1197
|
targetKind: isCoreApiTarget() ? "core" : "cloud", apiBase: API,
|
|
1188
|
-
allowUnresolved: opts.mode === "check" || opts.mode === "printSpec",
|
|
1198
|
+
allowUnresolved: opts.mode === "check" || opts.mode === "printSpec" || opts.mode === "printManifest",
|
|
1189
1199
|
});
|
|
1190
1200
|
if (target.project_id) releaseSpec.project = target.project_id;
|
|
1191
1201
|
} catch (err) { reportSdkError(err); }
|
|
@@ -1203,77 +1213,29 @@ async function applyCmd(args) {
|
|
|
1203
1213
|
reportSdkError(err);
|
|
1204
1214
|
}
|
|
1205
1215
|
|
|
1216
|
+
if (process.env.RUN402_DEPLOY_SKIP_SCAN !== "1") {
|
|
1217
|
+
const scan = scanDeploymentSources(releaseSpec, manifestPath ? dirname(manifestPath) : resolve(opts.dir || process.cwd()), opts.dir ? resolve(opts.dir) : undefined);
|
|
1218
|
+
if (scan.errors.length) fail({ code: "R402_AUTH_PREFLIGHT_FAILED", message: "Source scan blocked this application. Fix the reported findings, or explicitly override with RUN402_DEPLOY_SKIP_SCAN=1.", details: scan });
|
|
1219
|
+
}
|
|
1220
|
+
|
|
1206
1221
|
if (opts.mode === "check") {
|
|
1207
1222
|
console.log(JSON.stringify({
|
|
1208
1223
|
ok: true,
|
|
1209
1224
|
mode: "check",
|
|
1210
|
-
project_id:
|
|
1211
|
-
|
|
1225
|
+
project_id: target.project_id,
|
|
1226
|
+
...describeLocalPreflight({ entryPoint: "deploy apply", appRoot: manifestPath ? dirname(manifestPath) : resolve(opts.dir || process.cwd()), manifestPath, authoring: normalizedManifest.manifest, spec: releaseSpec, target, apiBase: API }),
|
|
1212
1227
|
}, null, 2));
|
|
1213
1228
|
return;
|
|
1214
1229
|
}
|
|
1230
|
+
if (opts.mode === "printManifest") {
|
|
1231
|
+
try { console.log(JSON.stringify(serializeDeployManifest(normalizedManifest, manifestPath ? dirname(manifestPath) : process.cwd(), opts.project || process.env.RUN402_PROJECT_ID), null, 2)); } catch (err) { reportSdkError(err); }
|
|
1232
|
+
return;
|
|
1233
|
+
}
|
|
1215
1234
|
if (opts.mode === "printSpec") {
|
|
1216
|
-
console.log(JSON.stringify(releaseSpec, null, 2));
|
|
1235
|
+
console.log(JSON.stringify({ ...releaseSpec, project: target.project_id ?? undefined }, null, 2));
|
|
1217
1236
|
return;
|
|
1218
1237
|
}
|
|
1219
1238
|
|
|
1220
|
-
// Pre-flight source scan (auth-aware-ssr Section 9). Bypass via
|
|
1221
|
-
// RUN402_DEPLOY_SKIP_SCAN=1 — useful for forcing a deploy when
|
|
1222
|
-
// the scanner has a false positive that the operator has confirmed
|
|
1223
|
-
// is fine. Hits with severity `error` fail the deploy.
|
|
1224
|
-
//
|
|
1225
|
-
// Scope: a `--dir` (Astro SSR build) deploy walks that dir —
|
|
1226
|
-
// it IS the artifact. A manifest/spec/stdin deploy scans ONLY the
|
|
1227
|
-
// on-disk source files the manifest actually references, resolved
|
|
1228
|
-
// against the manifest's baseDir. We must NOT walk cwd/src for a
|
|
1229
|
-
// manifest deploy: running from inside an unrelated source tree (e.g.
|
|
1230
|
-
// the gateway monorepo, which legitimately has dozens of `getUser`
|
|
1231
|
-
// references) would otherwise block a deploy of one unrelated HTML file.
|
|
1232
|
-
if (!isNonApplyingMode(opts.mode) && process.env.RUN402_DEPLOY_SKIP_SCAN !== "1") {
|
|
1233
|
-
try {
|
|
1234
|
-
const { scanSourceTree, scanSourceFiles, SCAN_SEVERITY } = await import(
|
|
1235
|
-
"./doctor-source-scan.mjs"
|
|
1236
|
-
);
|
|
1237
|
-
const scannableExt = /\.(?:ts|tsx|js|jsx|mjs|cjs|astro)$/;
|
|
1238
|
-
let findings;
|
|
1239
|
-
if (opts.dir) {
|
|
1240
|
-
const scanRoot = isAbsolute(opts.dir)
|
|
1241
|
-
? opts.dir
|
|
1242
|
-
: resolve(process.cwd(), opts.dir);
|
|
1243
|
-
findings = scanSourceTree(scanRoot, { cwd: process.cwd() });
|
|
1244
|
-
} else {
|
|
1245
|
-
const baseDir = manifestPath ? dirname(manifestPath) : process.cwd();
|
|
1246
|
-
const files = collectManifestSourceFiles(spec ?? normalizedManifest.manifest, baseDir).filter(
|
|
1247
|
-
(p) => scannableExt.test(p) && existsSync(p),
|
|
1248
|
-
);
|
|
1249
|
-
findings = files.length > 0
|
|
1250
|
-
? scanSourceFiles(files, { cwd: process.cwd() })
|
|
1251
|
-
: [];
|
|
1252
|
-
}
|
|
1253
|
-
const errorFindings = findings.filter((f) => f.severity === SCAN_SEVERITY.ERROR);
|
|
1254
|
-
if (errorFindings.length > 0) {
|
|
1255
|
-
const summary = errorFindings.slice(0, 10).map((f) => {
|
|
1256
|
-
const loc = f.line ? `${f.file}:${f.line}` : f.file;
|
|
1257
|
-
return ` ${f.code} ${loc}\n ${f.message}${f.canonical_name ? `\n fix: ${f.canonical_name}` : ""}`;
|
|
1258
|
-
}).join("\n");
|
|
1259
|
-
const more = errorFindings.length > 10 ? `\n ...and ${errorFindings.length - 10} more` : "";
|
|
1260
|
-
fail({
|
|
1261
|
-
code: "R402_AUTH_PREFLIGHT_FAILED",
|
|
1262
|
-
message: `Source scan blocked deploy: ${errorFindings.length} R402_AUTH_* finding(s). Run \`run402 doctor\` for the full list. Bypass with RUN402_DEPLOY_SKIP_SCAN=1 if you're sure.`,
|
|
1263
|
-
details: { findings: errorFindings, summary: `${summary}${more}` },
|
|
1264
|
-
});
|
|
1265
|
-
}
|
|
1266
|
-
} catch (err) {
|
|
1267
|
-
if (err && typeof err === "object" && err.code === "R402_AUTH_PREFLIGHT_FAILED") {
|
|
1268
|
-
throw err;
|
|
1269
|
-
}
|
|
1270
|
-
// Scanner crashed — warn but don't block. The scanner is a safety
|
|
1271
|
-
// net; the deploy should proceed if it can't read the source tree.
|
|
1272
|
-
console.warn(
|
|
1273
|
-
`[deploy] source scan skipped: ${err instanceof Error ? err.message : String(err)}`,
|
|
1274
|
-
);
|
|
1275
|
-
}
|
|
1276
|
-
}
|
|
1277
1239
|
|
|
1278
1240
|
let sdkOpts;
|
|
1279
1241
|
const delegateToken = delegateTokenFromEnv();
|
|
@@ -1388,7 +1350,7 @@ async function applyCmd(args) {
|
|
|
1388
1350
|
}
|
|
1389
1351
|
|
|
1390
1352
|
function isNonApplyingMode(mode) {
|
|
1391
|
-
return mode === "check" || mode === "printSpec" || mode === "plan";
|
|
1353
|
+
return mode === "check" || mode === "printSpec" || mode === "printManifest" || mode === "plan";
|
|
1392
1354
|
}
|
|
1393
1355
|
|
|
1394
1356
|
function hasGithubActionsOidcEnv(env = process.env) {
|