run402 4.42.0 → 4.43.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/lib/command-manifest.mjs +6 -3
- package/lib/deploy-v2.mjs +27 -4
- package/lib/next-actions.mjs +5 -2
- package/lib/repos.mjs +466 -117
- package/lib/stats.mjs +57 -0
- package/package.json +1 -1
- package/sdk/dist/index.d.ts +10 -1
- package/sdk/dist/index.d.ts.map +1 -1
- package/sdk/dist/index.js +11 -0
- package/sdk/dist/index.js.map +1 -1
- package/sdk/dist/kernel.d.ts +31 -0
- package/sdk/dist/kernel.d.ts.map +1 -1
- package/sdk/dist/kernel.js +116 -3
- package/sdk/dist/kernel.js.map +1 -1
- package/sdk/dist/namespaces/gitvault.crypto.d.ts +178 -5
- package/sdk/dist/namespaces/gitvault.crypto.d.ts.map +1 -1
- package/sdk/dist/namespaces/gitvault.crypto.js +266 -7
- package/sdk/dist/namespaces/gitvault.crypto.js.map +1 -1
- package/sdk/dist/namespaces/gitvault.d.ts +103 -1
- package/sdk/dist/namespaces/gitvault.d.ts.map +1 -1
- package/sdk/dist/namespaces/gitvault.js +175 -7
- package/sdk/dist/namespaces/gitvault.js.map +1 -1
- package/sdk/dist/namespaces/gitvault.types.d.ts +184 -9
- package/sdk/dist/namespaces/gitvault.types.d.ts.map +1 -1
- package/sdk/dist/namespaces/gitvault.types.js +2 -1
- package/sdk/dist/namespaces/gitvault.types.js.map +1 -1
- package/sdk/dist/node/gitvault-apply.d.ts +8 -0
- package/sdk/dist/node/gitvault-apply.d.ts.map +1 -1
- package/sdk/dist/node/gitvault-apply.js +1 -0
- package/sdk/dist/node/gitvault-apply.js.map +1 -1
- package/sdk/dist/node/gitvault-deploy.d.ts +13 -0
- package/sdk/dist/node/gitvault-deploy.d.ts.map +1 -1
- package/sdk/dist/node/gitvault-deploy.js +28 -0
- package/sdk/dist/node/gitvault-deploy.js.map +1 -1
- package/sdk/dist/node/gitvault-keystore.d.ts +54 -4
- package/sdk/dist/node/gitvault-keystore.d.ts.map +1 -1
- package/sdk/dist/node/gitvault-keystore.js +20 -0
- package/sdk/dist/node/gitvault-keystore.js.map +1 -1
- package/sdk/dist/node/gitvault-publication.d.ts +328 -4
- package/sdk/dist/node/gitvault-publication.d.ts.map +1 -1
- package/sdk/dist/node/gitvault-publication.js +560 -14
- package/sdk/dist/node/gitvault-publication.js.map +1 -1
- package/sdk/dist/node/gitvault-snapshot.d.ts +40 -7
- package/sdk/dist/node/gitvault-snapshot.d.ts.map +1 -1
- package/sdk/dist/node/gitvault-snapshot.js +67 -19
- package/sdk/dist/node/gitvault-snapshot.js.map +1 -1
package/lib/command-manifest.mjs
CHANGED
|
@@ -280,10 +280,13 @@ export const COMMAND_MANIFEST = [
|
|
|
280
280
|
{ path: ["repos", "mirror"], positionals: [p("destination", { required: false })], projectScoped: true, legacyPositionalProject: false, minimalArgs: [], runStyle: "sub", skipBehavioral: "reads/writes mirror destination config beside the keystore and may move real bytes into a customer-owned bucket" },
|
|
281
281
|
{ path: ["repos", "fsck"], positionals: [], projectScoped: true, legacyPositionalProject: false, minimalArgs: [], runStyle: "sub", skipBehavioral: "walks the live head chain and materializes the ref map against the keystore's local pins" },
|
|
282
282
|
{ path: ["repos", "gc"], positionals: [], projectScoped: true, legacyPositionalProject: false, minimalArgs: [], runStyle: "sub", skipBehavioral: "publishes a checkpoint under a maintenance lease and materializes the live vault head to enumerate retention roots" },
|
|
283
|
-
// `access repair`
|
|
284
|
-
// one
|
|
283
|
+
// `access repair`/`revoke-key`/`declare-exposure` are nested sub-verb
|
|
284
|
+
// literals — one manifest entry each, all dispatched through the ONE
|
|
285
|
+
// `run("access", ...)` case in repos.mjs.
|
|
285
286
|
{ path: ["repos", "access"], positionals: [], projectScoped: true, legacyPositionalProject: false, minimalArgs: [], runStyle: "sub", skipBehavioral: "reads the live org encryption-key directory + vault envelope recipients" },
|
|
286
|
-
{ path: ["repos", "access", "repair"], positionals: [], projectScoped: true, legacyPositionalProject: false, minimalArgs: [], runStyle: "sub", skipBehavioral: "
|
|
287
|
+
{ path: ["repos", "access", "repair"], positionals: [], projectScoped: true, legacyPositionalProject: false, minimalArgs: ["--recipient-state-version", "0", "--recipient-revocation-version", "0"], runStyle: "sub", skipBehavioral: "owner+step-up-gated epoch rotation (D193-D203, rev 42) — samples a fresh epoch key and re-seals a live vault's recipients" },
|
|
288
|
+
{ path: ["repos", "access", "revoke-key"], positionals: [p("principal_id")], projectScoped: true, legacyPositionalProject: false, minimalArgs: ["prin_00000000000000000000000000000000"], runStyle: "sub", skipBehavioral: "owner+step-up-gated: declares a recipient's key revoked (org-scoped watermark) and drives a real epoch rotation off it" },
|
|
289
|
+
{ path: ["repos", "access", "declare-exposure"], positionals: [], projectScoped: true, legacyPositionalProject: false, minimalArgs: [], runStyle: "sub", skipBehavioral: "owner+step-up-gated: declares this vault's epoch secret exposed, forcing every subsequent ordinary push to refuse until a rotation lands" },
|
|
287
290
|
{ path: ["repos", "recover"], positionals: [p("source")], projectScoped: false, legacyPositionalProject: false, minimalArgs: ["s3://example-mirror-bucket", "--out", "__SCRATCH_DIR__/recover-out"], runStyle: "sub", skipBehavioral: "materializes a git repository from a mirror source, offline, with no server call" },
|
|
288
291
|
{ path: ["errors"], positionals: [p("fingerprint_id", { required: false })], projectScoped: true, legacyPositionalProject: false, minimalArgs: [], runStyle: "merged" },
|
|
289
292
|
|
package/lib/deploy-v2.mjs
CHANGED
|
@@ -41,6 +41,7 @@ import { loadLiveControlPlaneSession } from "../core-dist/control-plane-session.
|
|
|
41
41
|
import { withAutoApprove } from "./operator.mjs";
|
|
42
42
|
import { editRequestAction, nextAction, retryAction } from "./next-actions.mjs";
|
|
43
43
|
import { createUpdateCheckScheduler, emitUpdateNotice } from "./update-check.mjs";
|
|
44
|
+
import { sdkStats, printVerboseStats } from "./stats.mjs";
|
|
44
45
|
|
|
45
46
|
const APPLY_HELP = `run402 deploy apply — Unified deploy primitive (v1.34+)
|
|
46
47
|
|
|
@@ -106,9 +107,16 @@ Options:
|
|
|
106
107
|
--final-only Alias for --quiet; final success/error envelope is still preserved
|
|
107
108
|
--allow-warning <code> Continue past this reviewed warning code (repeatable)
|
|
108
109
|
--allow-warnings Continue past plan warnings that require confirmation
|
|
110
|
+
--allow-dirty gitvault-required projects only: capture a dirty
|
|
111
|
+
work tree as-is instead of refusing
|
|
112
|
+
SNAPSHOT_DIRTY_TREE. The result discloses exactly
|
|
113
|
+
what was swept in, printed to stderr too — even
|
|
114
|
+
this override never captures silently.
|
|
115
|
+
-v, --verbose Print one stderr summary line of this call's
|
|
116
|
+
request stats (round trips, wire time, bytes)
|
|
109
117
|
|
|
110
118
|
Output:
|
|
111
|
-
stdout: { "release_id": "rel_...", "operation_id": "op_...", "urls": {...}, "warnings": [...] }
|
|
119
|
+
stdout: { "release_id": "rel_...", "operation_id": "op_...", "urls": {...}, "warnings": [...], "stats": {...} }
|
|
112
120
|
stderr: one JSON event per line (suppressed with --quiet or --final-only)
|
|
113
121
|
|
|
114
122
|
Secrets:
|
|
@@ -654,8 +662,10 @@ function parseApplyArgs(args) {
|
|
|
654
662
|
planFingerprint: null,
|
|
655
663
|
rehearsalTeardown: "keep",
|
|
656
664
|
commitAfterRehearse: false,
|
|
665
|
+
allowDirty: false,
|
|
666
|
+
verbose: false,
|
|
657
667
|
};
|
|
658
|
-
const allowedFlags = ["--manifest", "--spec", "--dir", "--project", "--quiet", "--final-only", "--json", "--allow-warning", "--allow-warnings", "--check", "--print-spec", "--plan", "--rehearse", "--teardown", "--commit", "--require-plan", "--plan-fingerprint", "--help", "-h"];
|
|
668
|
+
const allowedFlags = ["--manifest", "--spec", "--dir", "--project", "--quiet", "--final-only", "--json", "--allow-warning", "--allow-warnings", "--check", "--print-spec", "--plan", "--rehearse", "--teardown", "--commit", "--require-plan", "--plan-fingerprint", "--allow-dirty", "-v", "--verbose", "--help", "-h"];
|
|
659
669
|
|
|
660
670
|
for (let i = 0; i < args.length; i++) {
|
|
661
671
|
const arg = args[i];
|
|
@@ -723,6 +733,8 @@ function parseApplyArgs(args) {
|
|
|
723
733
|
if (arg === "--quiet" || arg === "--final-only") { opts.quiet = true; continue; }
|
|
724
734
|
if (arg === "--json") { continue; }
|
|
725
735
|
if (arg === "--allow-warnings") { opts.allowWarnings = true; continue; }
|
|
736
|
+
if (arg === "--allow-dirty") { opts.allowDirty = true; continue; }
|
|
737
|
+
if (arg === "-v" || arg === "--verbose") { opts.verbose = true; continue; }
|
|
726
738
|
if (arg === "--check") { setApplyMode(opts, "check", "--check"); continue; }
|
|
727
739
|
if (arg === "--print-spec") { setApplyMode(opts, "printSpec", "--print-spec"); continue; }
|
|
728
740
|
if (arg === "--plan") { setApplyMode(opts, "plan", "--plan"); continue; }
|
|
@@ -1247,9 +1259,10 @@ async function applyCmd(args) {
|
|
|
1247
1259
|
// not `required` runs the same `apply()` this line always ran, with the
|
|
1248
1260
|
// same options object; a `required` one captures, publishes, mints an
|
|
1249
1261
|
// activation token, and commits with it.
|
|
1262
|
+
const sdk = getSdk(sdkOpts);
|
|
1250
1263
|
const outcome = await withAutoApprove(() =>
|
|
1251
1264
|
applyWithGitvault({
|
|
1252
|
-
sdk
|
|
1265
|
+
sdk,
|
|
1253
1266
|
spec: releaseSpec,
|
|
1254
1267
|
apply: {
|
|
1255
1268
|
onEvent: makeStderrEventWriter(opts.quiet),
|
|
@@ -1259,13 +1272,15 @@ async function applyCmd(args) {
|
|
|
1259
1272
|
...(requiredPlan ? { requiredPlan } : {}),
|
|
1260
1273
|
},
|
|
1261
1274
|
target: isCoreApiTarget() ? "core" : "cloud",
|
|
1275
|
+
...(opts.allowDirty ? { allowDirty: true } : {}),
|
|
1262
1276
|
// The `gitvault_commit` line is printed ALWAYS, and to stderr, so
|
|
1263
1277
|
// `run402 deploy apply | jq` stays clean (the pipe contract).
|
|
1264
1278
|
onCommitLine: (line) => { if (!opts.quiet) process.stderr.write(`${line}\n`); },
|
|
1265
1279
|
}),
|
|
1266
1280
|
);
|
|
1267
1281
|
if (!outcome.gitvault) {
|
|
1268
|
-
console.log(JSON.stringify(outcome.deploy, null, 2));
|
|
1282
|
+
console.log(JSON.stringify({ ...outcome.deploy, stats: sdkStats(sdk) }, null, 2));
|
|
1283
|
+
printVerboseStats(opts.verbose, sdk);
|
|
1269
1284
|
return;
|
|
1270
1285
|
}
|
|
1271
1286
|
const vaulted = outcome.gitvault;
|
|
@@ -1290,6 +1305,7 @@ async function applyCmd(args) {
|
|
|
1290
1305
|
...("reconcile_recipients" in vaulted ? { reconcile_recipients: vaulted.reconcile_recipients } : {}),
|
|
1291
1306
|
next_actions: vaulted.next_actions,
|
|
1292
1307
|
deploy: outcome.deploy,
|
|
1308
|
+
stats: sdkStats(sdk),
|
|
1293
1309
|
}, null, 2));
|
|
1294
1310
|
// Design D6: the mirror result is reported BESIDE the vault outcome
|
|
1295
1311
|
// above, on its own stderr line — a mirror failure never blocks the
|
|
@@ -1299,6 +1315,13 @@ async function applyCmd(args) {
|
|
|
1299
1315
|
} else if (vaulted.mirror_push?.outcome === "failed") {
|
|
1300
1316
|
console.error(`mirror: dual-push FAILED (deploy is unaffected) — ${vaulted.mirror_push.error ?? "see mirror_push.summary.errors"}`);
|
|
1301
1317
|
}
|
|
1318
|
+
// Dirty-tree disclosure (Tal's decision, "help people not make
|
|
1319
|
+
// mistakes"): even an explicit --allow-dirty override never captures
|
|
1320
|
+
// silently — name every modified/staged and untracked-not-ignored path
|
|
1321
|
+
// that got swept into this deploy's capture.
|
|
1322
|
+
for (const p of vaulted.snapshot?.modified_captured ?? []) console.error(`captured (modified): ${p}`);
|
|
1323
|
+
for (const p of vaulted.snapshot?.untracked_captured ?? []) console.error(`captured (untracked): ${p}`);
|
|
1324
|
+
printVerboseStats(opts.verbose, sdk);
|
|
1302
1325
|
// A non-activating outcome is a failed deploy even though it resolved
|
|
1303
1326
|
// rather than threw: the five outcomes are a result type, not an error
|
|
1304
1327
|
// channel, so the exit code has to carry the verdict.
|
package/lib/next-actions.mjs
CHANGED
|
@@ -70,12 +70,15 @@ export function deployAction() {
|
|
|
70
70
|
/**
|
|
71
71
|
* `repos create` (and `gitvault init`) on an org with no claimed slug: the
|
|
72
72
|
* response's `address: null` had no pointer to WHY, or to the named-addressing
|
|
73
|
-
* feature at all (kychee-com/run402#560).
|
|
73
|
+
* feature at all (kychee-com/run402#560). Owner-only. Wording deliberately
|
|
74
|
+
* omits a price: the first slug per org is free, and renames/re-claims cost
|
|
75
|
+
* $1 — a gateway change lands the fee separately, so this stays true under
|
|
76
|
+
* both the old and new pricing rule.
|
|
74
77
|
*/
|
|
75
78
|
export function claimOrgSlugAction() {
|
|
76
79
|
return nextAction("claim_org_slug", {
|
|
77
80
|
command: "run402 org slug <slug>",
|
|
78
|
-
why: "This organization has no claimed slug yet, so its repos have no run402::<slug>/<name> address.
|
|
81
|
+
why: "This organization has no claimed slug yet, so its repos have no run402::<slug>/<name> address. Owner-only.",
|
|
79
82
|
});
|
|
80
83
|
}
|
|
81
84
|
|