run402 4.73.4 → 4.75.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.
@@ -1,5 +1,5 @@
1
1
  {
2
- "surface_version": "4.73.4",
2
+ "surface_version": "4.75.0",
3
3
  "verbs": [
4
4
  "repos create",
5
5
  "repos list",
package/lib/billing.mjs CHANGED
@@ -12,6 +12,7 @@ Subcommands:
12
12
  create-email <email> Create an email organization
13
13
  link-wallet [<org_id>] <wallet_address> Link a wallet to an email organization
14
14
  checkout <identifier> --product <p> Create an org checkout
15
+ topup <identifier> --sats <n> [--wait] Top up the cash balance over Lightning (a bolt11 invoice; no node, no Stripe)
15
16
  auto-recharge [<org_id>] <on|off> [--threshold <n>]
16
17
  balance <identifier> Balance by organization id (UUID), wallet (0x...), or email
17
18
  history <identifier> [--limit <n>] Ledger history by organization id (UUID), wallet, or email
@@ -21,6 +22,7 @@ Examples:
21
22
  run402 billing checkout 00000000-0000-4000-8000-000000000001 --product tier --tier hobby
22
23
  run402 billing checkout 0x1234... --product email-pack
23
24
  run402 billing checkout 0x1234... --product balance-topup --amount 5000000
25
+ run402 billing topup 0x1234... --sats 2000 --wait
24
26
  run402 billing auto-recharge org_abc on --threshold 2000
25
27
  run402 billing balance user@example.com
26
28
  `;
@@ -208,6 +210,62 @@ async function checkout(args) {
208
210
  }
209
211
  }
210
212
 
213
+ // lightning-cash-topup: "top up N sats" → one invoice, optionally waited on.
214
+ // stdout stays one JSON doc per step (the pipe contract); the human-facing
215
+ // invoice line and the receipt go to stderr.
216
+ async function topup(args) {
217
+ const parsedArgs = normalizeArgv(args);
218
+ const valueFlags = ["--sats", "--timeout", "--idempotency-key"];
219
+ assertKnownFlags(parsedArgs, [...valueFlags, "--wait", "--help", "-h"], valueFlags);
220
+ const positionals = positionalArgs(parsedArgs, valueFlags);
221
+ const identifier = positionals[0];
222
+ if (!identifier || positionals.length > 1) {
223
+ fail({ code: "BAD_USAGE", message: "Usage: run402 billing topup <identifier> --sats <n> [--wait]", hint: "run402 billing topup 0x1234... --sats 2000 --wait" });
224
+ }
225
+ const satsRaw = flagValue(parsedArgs, "--sats");
226
+ const sats = Number(satsRaw);
227
+ if (satsRaw === null || !Number.isSafeInteger(sats) || sats <= 0) {
228
+ fail({ code: "BAD_FLAG", message: "--sats must be a positive whole number of satoshis (100–1000000).", details: { flag: "--sats" } });
229
+ }
230
+ const timeoutRaw = flagValue(parsedArgs, "--timeout");
231
+ const timeoutMs = timeoutRaw === null ? 600_000 : Number(timeoutRaw) * 1000;
232
+ if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
233
+ fail({ code: "BAD_FLAG", message: "--timeout must be a positive number of seconds.", details: { flag: "--timeout" } });
234
+ }
235
+ try {
236
+ const sdk = getSdk();
237
+ const org = await sdk.billing.lookupOrganization(identifier);
238
+ const created = await sdk.billing.createLightningTopup(org.org_id, {
239
+ amountSats: sats,
240
+ idempotencyKey: flagValue(parsedArgs, "--idempotency-key") ?? undefined,
241
+ });
242
+ console.log(JSON.stringify(created, null, 2));
243
+ console.error(`Invoice for ${created.amount_sats} sats (≈ $${(created.amount_usd_micros / 1_000_000).toFixed(2)} at the quoted rate), expires ${created.invoice_expires_at}.`);
244
+ console.error(`Pay it from any Lightning wallet:\n lightning:${created.bolt11}`);
245
+ if (!parsedArgs.includes("--wait")) {
246
+ console.error(`Then read it: run402 billing topup is one-shot; poll GET /orgs/v1/${org.org_id}/checkouts/${created.topup_id} (or rerun with --wait).`);
247
+ return;
248
+ }
249
+ let announced = false;
250
+ const final = await sdk.billing.waitForTopup(org.org_id, created.topup_id, {
251
+ timeoutMs,
252
+ onPoll: () => { if (!announced) { announced = true; console.error("Waiting for the payment…"); } },
253
+ });
254
+ console.log(JSON.stringify(final, null, 2));
255
+ if (final.status === "paid" || final.status === "paid_late") {
256
+ console.error(`Received — ${final.amount_sats} sats credited $${(final.amount_usd_micros / 1_000_000).toFixed(2)} to the balance${final.status === "paid_late" ? " (paid after the invoice expired; still credited)" : ""}.`);
257
+ } else if (final.status === "expired") {
258
+ console.error("The invoice expired unpaid. Mint a fresh one with the same command.");
259
+ process.exitCode = 2;
260
+ } else {
261
+ console.error("Timed out still pending — a payment that lands later still credits (up to an hour after expiry); poll the top-up.");
262
+ process.exitCode = 2;
263
+ }
264
+ } catch (err) {
265
+ reportSdkError(err);
266
+ }
267
+ }
268
+
211
269
  async function createEmail(args) {
212
270
  const parsedArgs = normalizeArgv(args);
213
271
  assertKnownFlags(parsedArgs, ["--help", "-h"]);
@@ -353,6 +411,7 @@ export async function run(sub, args) {
353
411
  case "create-email": await createEmail(args); break;
354
412
  case "link-wallet": await linkWallet(args); break;
355
413
  case "checkout": await checkout(args); break;
414
+ case "topup": await topup(args); break;
356
415
  case "auto-recharge": await autoRecharge(args); break;
357
416
  case "balance": await balance(args); break;
358
417
  case "history": await history(args); break;
package/lib/buzz.mjs CHANGED
@@ -26,7 +26,7 @@ Canonical workflows:
26
26
  --org the Run402 organization id as "run402 org whoami" returns it (a UUID)
27
27
  --deployment-context-file JSON with exactly these five non-empty strings, and no others:
28
28
  project_id, release_id, live_url, source_revision, verified_at
29
- run402 buzz install --org <org_id> --community <buzz:community:host> --authority <hex-pubkey>
29
+ run402 buzz install --org <org_id> --community <buzz:community:host> [--authority <hex-pubkey>]
30
30
  run402 buzz enroll --installation <buzzci_id> --identity-link <idlnk_id> --grants-file <json> --expires-at <ISO-8601>
31
31
 
32
32
  Explicit consent/decision commands:
@@ -34,7 +34,7 @@ Explicit consent/decision commands:
34
34
  run402 buzz adopt offer cancel <buzzhao_id>
35
35
  run402 buzz adopt complete <buzzha_id> --event-file <owner-event.json>
36
36
  run402 buzz adopt cancel <buzzha_id>
37
- run402 buzz install activate <buzzci_id> --proof-file <authority-proof.json>
37
+ run402 buzz install activate <buzzci_id> --invite <link|code> (a one-use invite minted in Buzz Desktop; no key leaves Desktop)
38
38
  run402 buzz install update <buzzci_id> --policy-file <policy.json> --policy-revision <n> --default <true|false>
39
39
  run402 buzz install revoke <buzzci_id>
40
40
  run402 buzz approve <buzzae_id> --grants-file <json> --descriptor-revision <n> --policy-revision <n>
@@ -199,12 +199,15 @@ async function install(args) {
199
199
  const [operation, ...rest] = args;
200
200
  if (operation === "activate") {
201
201
  const a = normalizeArgv(rest);
202
- const values = ["--proof-file", "--idempotency-key"];
202
+ const values = ["--invite", "--idempotency-key"];
203
203
  assertKnownFlags(a, values, values);
204
- const [id] = requirePositionalCount(a, values, { min: 1, max: 1, command: "run402 buzz install activate <buzzci_id> --proof-file <json>" });
205
- const proof = readJsonFile(requiredFlag(a, "--proof-file"), "--proof-file");
204
+ const [id] = requirePositionalCount(a, values, { min: 1, max: 1, command: "run402 buzz install activate <buzzci_id> --invite <link|code>" });
205
+ // The invite is a one-use bearer artifact: it goes to the gateway once
206
+ // and is never echoed. A bare code, an https://<relay>/invite/<code>
207
+ // link, or a buzz://join?relay=…&code=… link are all accepted.
208
+ const invite = requiredFlag(a, "--invite");
206
209
  const key = flagValue(a, "--idempotency-key") ?? undefined;
207
- return invoke(() => getSdk().buzz.communityInstallations.activate(id, proof, key));
210
+ return invoke(() => getSdk().buzz.communityInstallations.activate(id, invite, key));
208
211
  }
209
212
  if (operation === "revoke") {
210
213
  const a = normalizeArgv(rest);
@@ -252,13 +255,13 @@ async function install(args) {
252
255
  const a = normalizeArgv(args);
253
256
  const values = ["--org", "--community", "--authority", "--policy-file", "--idempotency-key"];
254
257
  assertKnownFlags(a, values, values);
255
- requirePositionalCount(a, values, { min: 0, max: 0, command: "run402 buzz install [--org <org_id>] --community <subject> --authority <hex>" });
258
+ requirePositionalCount(a, values, { min: 0, max: 0, command: "run402 buzz install [--org <org_id>] --community <subject> [--authority <hex>]" });
256
259
  const policyFile = flagValue(a, "--policy-file");
257
260
  const organizationId = await resolveOrgId(a, { cmd: "buzz" });
258
261
  return invoke(() => getSdk().buzz.install({
259
262
  organizationId,
260
263
  buzzCommunitySubject: requiredFlag(a, "--community"),
261
- buzzCommunityAuthoritySubject: requiredFlag(a, "--authority"),
264
+ buzzCommunityAuthoritySubject: flagValue(a, "--authority") ?? undefined,
262
265
  enrollmentPolicy: policyFile ? readJsonFile(policyFile, "--policy-file") : undefined,
263
266
  idempotencyKey: flagValue(a, "--idempotency-key") ?? undefined,
264
267
  }));
package/lib/buzz.test.mjs CHANGED
@@ -194,6 +194,26 @@ describe("run402 buzz CLI", () => {
194
194
  assert.match(stderr.join("\n"), /pending/);
195
195
  });
196
196
 
197
+ it("installs without naming a Buzz authority and activates through the invite front door", async () => {
198
+ const calls = [];
199
+ sdk = {
200
+ buzz: {
201
+ install: async (input) => { calls.push(["install", input]); return { status: "pending", installation_identity: { pubkey: "ab".repeat(32) }, next_actions: [{ type: "mint_buzz_invite" }] }; },
202
+ communityInstallations: {
203
+ activate: async (id, invite, key) => { calls.push(["activate", id, invite, key]); return { status: "active", bot_mode: "attested" }; },
204
+ },
205
+ },
206
+ };
207
+ await run("install", ["--org", "22222222-2222-4222-8222-222222222222", "--community", "buzz:community:acme.communities.buzz.xyz"]);
208
+ assert.equal(calls[0][0], "install");
209
+ assert.equal(calls[0][1].buzzCommunitySubject, "buzz:community:acme.communities.buzz.xyz");
210
+ assert.equal(calls[0][1].buzzCommunityAuthoritySubject, undefined);
211
+ assert.equal(JSON.parse(stdout[0]).next_actions[0].type, "mint_buzz_invite");
212
+ await run("install", ["activate", `buzzci_${"2".repeat(32)}`, "--invite", "https://acme.communities.buzz.xyz/invite/v2.abcdefghij", "--idempotency-key", "activate-1"]);
213
+ assert.deepEqual(calls[1], ["activate", `buzzci_${"2".repeat(32)}`, "https://acme.communities.buzz.xyz/invite/v2.abcdefghij", "activate-1"]);
214
+ assert.equal(JSON.parse(stdout[1]).bot_mode, "attested");
215
+ });
216
+
197
217
  it("discovers descriptors by community without authentication", async () => {
198
218
  let observed;
199
219
  sdk = {
@@ -182,7 +182,7 @@ export const COMMAND_MANIFEST = [
182
182
 
183
183
  // ── deploy (unified deploy v2) ───────────────────────────────────────────
184
184
  { path: ["deploy", "apply"], positionals: [], projectScoped: true, legacyPositionalProject: false, minimalArgs: ["--spec", "{}", "--check"], runStyle: "deployV2" },
185
- { path: ["deploy", "rehearse"], positionals: [p("plan_id")], projectScoped: true, legacyPositionalProject: false, minimalArgs: ["plan_gate1"], runStyle: "deployV2" },
185
+ { path: ["deploy", "rehearse"], positionals: [p("plan_id", { required: false })], projectScoped: true, legacyPositionalProject: false, minimalArgs: ["plan_gate1"], runStyle: "deployV2" },
186
186
  { path: ["deploy", "promote"], positionals: [p("release_id")], projectScoped: true, legacyPositionalProject: false, minimalArgs: ["rel_gate1"], runStyle: "deployV2" },
187
187
  { path: ["deploy", "resume"], positionals: [p("operation_id")], projectScoped: true, legacyPositionalProject: false, minimalArgs: ["op_gate1"], runStyle: "deployV2" },
188
188
  { path: ["deploy", "list"], positionals: [], projectScoped: true, legacyPositionalProject: false, minimalArgs: [], runStyle: "deployV2" },
@@ -453,6 +453,7 @@ export const COMMAND_MANIFEST = [
453
453
  { path: ["billing", "create-email"], positionals: [p("email")], projectScoped: false, legacyPositionalProject: false, minimalArgs: ["gate@example.com"] },
454
454
  { path: ["billing", "link-wallet"], positionals: [p("org_id", { required: false })], projectScoped: false, orgScoped: true, legacyPositionalProject: false, minimalArgs: [GATE_ORG, "0x1111111111111111111111111111111111111111"] },
455
455
  { path: ["billing", "checkout"], positionals: [p("identifier")], projectScoped: false, legacyPositionalProject: false, minimalArgs: ["00000000-0000-4000-8000-000000000001", "--product", "email-pack"] },
456
+ { path: ["billing", "topup"], positionals: [p("identifier")], projectScoped: false, legacyPositionalProject: false, minimalArgs: ["00000000-0000-4000-8000-000000000001", "--sats", "2000"] },
456
457
  { path: ["billing", "auto-recharge"], positionals: [p("org_id", { required: false })], projectScoped: false, orgScoped: true, legacyPositionalProject: false, minimalArgs: [GATE_ORG, "--state", "on"] },
457
458
  { path: ["billing", "balance"], positionals: [p("identifier")], projectScoped: false, legacyPositionalProject: false, minimalArgs: ["gate@example.com"] },
458
459
  { path: ["billing", "history"], positionals: [p("identifier")], projectScoped: false, legacyPositionalProject: false, minimalArgs: ["gate@example.com"] },
@@ -0,0 +1,25 @@
1
+ import { describe, it } from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
4
+ import { join } from "node:path";
5
+ import { tmpdir } from "node:os";
6
+ import { discoverRehearseManifest } from "./deploy-v2.mjs";
7
+
8
+ describe("deploy rehearse — manifest discovery (the way up does it)", () => {
9
+ it("prefers run402.json, then run402.deploy.json, then app.json, then executable configs", () => {
10
+ const dir = mkdtempSync(join(tmpdir(), "run402-rehearse-discover-"));
11
+ try {
12
+ assert.equal(discoverRehearseManifest(dir), null);
13
+ writeFileSync(join(dir, "run402.deploy.ts"), "export default {}");
14
+ assert.equal(discoverRehearseManifest(dir), join(dir, "run402.deploy.ts"));
15
+ writeFileSync(join(dir, "app.json"), "{}");
16
+ assert.equal(discoverRehearseManifest(dir), join(dir, "app.json"));
17
+ writeFileSync(join(dir, "run402.deploy.json"), "{}");
18
+ assert.equal(discoverRehearseManifest(dir), join(dir, "run402.deploy.json"));
19
+ writeFileSync(join(dir, "run402.json"), "{}");
20
+ assert.equal(discoverRehearseManifest(dir), join(dir, "run402.json"));
21
+ } finally {
22
+ rmSync(dir, { recursive: true, force: true });
23
+ }
24
+ });
25
+ });
package/lib/deploy-v2.mjs CHANGED
@@ -228,19 +228,28 @@ Output:
228
228
  stderr: one JSON poll progress line per attempt when --wait is set
229
229
  `;
230
230
 
231
- const REHEARSE_HELP = `run402 deploy rehearse — Run a persisted plan on a contained branch
231
+ const REHEARSE_HELP = `run402 deploy rehearse — Run a plan on a contained branch (ADVANCED; rehearsal is automatic in up / deploy apply)
232
232
 
233
233
  Usage:
234
- run402 deploy rehearse <plan_id> [--project <id>] [--teardown on_pass|keep|always] [--json]
234
+ run402 deploy rehearse [<plan_id>] [--manifest <path>] [--project <id>] [--teardown on_pass|keep|always] [--json]
235
235
 
236
236
  Options:
237
+ <plan_id> An already-persisted plan. Its bytes must be uploaded; when
238
+ the gateway answers REHEARSAL_CONTENT_MISSING the manifest
239
+ in the current directory (or --manifest) is used to upload
240
+ them and the rehearsal is retried. If facts changed since
241
+ that plan, a fresh reviewed plan is created and rehearsed
242
+ instead — the result names which plan was rehearsed.
243
+ --manifest <path> Plan from this manifest (run402.json, run402.deploy.json,
244
+ app.json, or an executable config), upload its bytes, then
245
+ rehearse. Without <plan_id> the manifest is discovered in
246
+ the current directory the same way run402 up does.
237
247
  --teardown <mode> on_pass (default: passed rehearsals delete their branch;
238
- failed rehearsals keep it), keep, always. When omitted,
239
- the gateway default (on_pass) applies.
248
+ failed rehearsals keep it), keep, always.
249
+ --project <id> Project for operator-approval metadata and project resolution.
240
250
 
241
- Rehearsal is automatic in \`run402 up\` / \`run402 deploy apply\` for a
242
- migration-bearing plan against a project with a live release; this verb is the
243
- primitive for rehearsing an already-persisted plan without committing.
251
+ Nothing is committed. The result carries the rehearsal report and the exact
252
+ bound commit command (run402 deploy apply --require-plan <plan_id>).
244
253
  `;
245
254
 
246
255
  const RELEASE_HELP = `run402 deploy release — Inspect deploy release inventory and diffs
@@ -356,14 +365,52 @@ export async function runDeployV2(sub, args) {
356
365
  });
357
366
  }
358
367
 
368
+ const REHEARSE_MANIFEST_CANDIDATES = ["run402.json", "run402.deploy.json", "app.json", "run402.deploy.ts", "run402.deploy.mts", "run402.deploy.js", "run402.deploy.mjs"];
369
+
370
+ /** The manifest `deploy rehearse` would plan from in `dir`, discovered the way `up` does, or null. */
371
+ export function discoverRehearseManifest(dir = process.cwd()) {
372
+ for (const name of REHEARSE_MANIFEST_CANDIDATES) {
373
+ const candidate = resolve(dir, name);
374
+ if (existsSync(candidate)) return candidate;
375
+ }
376
+ return null;
377
+ }
378
+
379
+ async function loadReleaseSpecForRehearse(manifestPath, project) {
380
+ const executable = EXECUTABLE_MANIFEST_EXTENSIONS.has(extname(manifestPath).toLowerCase());
381
+ let normalized;
382
+ try {
383
+ if (executable) {
384
+ normalized = await loadDeployManifest(manifestPath, { ...(project ? { project } : {}) });
385
+ } else {
386
+ const spec = JSON.parse(readFileSync(manifestPath, "utf-8"));
387
+ rejectLegacySecretManifest(spec, { source: "manifest", path: manifestPath });
388
+ const defaultProject = project || spec?.project || spec?.project_id ? undefined : resolveProjectId(null);
389
+ normalized = await normalizeDeployManifest(spec, {
390
+ baseDir: dirname(manifestPath),
391
+ ...(project ? { project } : {}),
392
+ ...(defaultProject ? { defaultProject } : {}),
393
+ });
394
+ }
395
+ } catch (err) {
396
+ reportSdkError(err);
397
+ }
398
+ return normalized;
399
+ }
400
+
401
+ function isContentMissing(err) {
402
+ const code = err?.code ?? err?.body?.code ?? err?.envelope?.code;
403
+ return code === "REHEARSAL_CONTENT_MISSING";
404
+ }
405
+
359
406
  async function rehearseCmd(rawArgs) {
360
407
  const args = normalizeArgv(rawArgs);
361
408
  if (args.includes("--help") || args.includes("-h")) {
362
409
  console.log(REHEARSE_HELP);
363
410
  return;
364
411
  }
365
- const valueFlags = new Set(["--project", "--teardown"]);
366
- const allowedFlags = ["--project", "--teardown", "--json", "--help", "-h"];
412
+ const valueFlags = new Set(["--project", "--teardown", "--manifest"]);
413
+ const allowedFlags = ["--project", "--teardown", "--manifest", "--json", "--help", "-h"];
367
414
  const positionals = [];
368
415
  for (let i = 0; i < args.length; i += 1) {
369
416
  const arg = args[i];
@@ -382,9 +429,23 @@ async function rehearseCmd(rawArgs) {
382
429
  }
383
430
  positionals.push(arg);
384
431
  }
385
- const planId = positionals[0];
386
- if (!planId || positionals.length > 1) {
387
- fail({ code: "BAD_USAGE", message: "Usage: run402 deploy rehearse <plan_id> [--project <id>] [--teardown on_pass|keep|always] [--json]" });
432
+ if (positionals.length > 1) {
433
+ fail({ code: "BAD_USAGE", message: "Usage: run402 deploy rehearse [<plan_id>] [--manifest <path>] [--project <id>] [--teardown on_pass|keep|always] [--json]" });
434
+ }
435
+ const givenPlanId = positionals[0] ?? null;
436
+ const explicitManifest = flagValue(args, "--manifest");
437
+ const manifestPath = explicitManifest
438
+ ? (isAbsolute(explicitManifest) ? explicitManifest : resolve(process.cwd(), explicitManifest))
439
+ : discoverRehearseManifest();
440
+ if (explicitManifest && !existsSync(manifestPath)) {
441
+ fail({ code: "BAD_USAGE", message: `Manifest not found: ${manifestPath}`, details: { flag: "--manifest", path: explicitManifest } });
442
+ }
443
+ if (!givenPlanId && !manifestPath) {
444
+ fail({
445
+ code: "BAD_USAGE",
446
+ message: "Nothing to rehearse: pass a <plan_id>, or run from a directory with a manifest (run402.json, run402.deploy.json, app.json), or pass --manifest <path>.",
447
+ details: { searched: REHEARSE_MANIFEST_CANDIDATES },
448
+ });
388
449
  }
389
450
  // When --teardown is absent, omit it from the request body entirely — the
390
451
  // gateway defaults to on_pass (passed rehearsals delete their branch).
@@ -394,23 +455,63 @@ async function rehearseCmd(rawArgs) {
394
455
  }
395
456
  const project = flagValue(args, "--project") ?? undefined;
396
457
  // A delegate is a complete deploy credential and the gateway explicitly
397
- // supports rehearsing with one walletAuthOrCiSession routes a delegate
398
- // bearer through delegateDeployAuth("project.deploy"), and the route rejects
399
- // only CI sessions (REHEARSAL_CI_UNSUPPORTED), whose own next_action reads
400
- // "Rehearse with a wallet, control-plane session, or scoped agent delegate."
401
- // Without this branch the CLI refuses locally with NO_ALLOWANCE and tells the
402
- // caller to run `run402 init` — a wrong remedy for a holder who has no wallet
403
- // by design, and the same misleading-error shape we removed from the payment
404
- // path in 4.11.2. Rehearsal is the SAFE path; never make it the harder one.
458
+ // supports rehearsing with one (the route rejects only CI sessions).
459
+ // Rehearsal is the SAFE path; never make it the harder one.
405
460
  if (!isCoreApiTarget() && !loadLiveControlPlaneSession() && !delegateTokenFromEnv()) {
406
- allowanceAuthHeaders(`/apply/v1/plans/${planId}/rehearse`);
461
+ allowanceAuthHeaders(`/apply/v1/plans/${givenPlanId ?? "_"}/rehearse`);
462
+ }
463
+ const sdk = getSdk();
464
+ const emit = makeStderrEventWriter(false);
465
+
466
+ // Plan from the manifest, upload its bytes, and hand back the persisted
467
+ // plan id to rehearse. Used when no plan id was given, and as the recovery
468
+ // for a plan whose bytes were never uploaded.
469
+ async function planAndUpload() {
470
+ const normalized = await loadReleaseSpecForRehearse(manifestPath, project);
471
+ const planned = await sdk._applyEngine.plan(normalized.spec, {
472
+ idempotencyKey: normalized.idempotencyKey,
473
+ mode: "reviewedPlan",
474
+ });
475
+ const planId = planned.plan.plan_id;
476
+ if (!planId) {
477
+ fail({ code: "DRY_RUN_PLAN_NOT_COMMITTABLE", message: "Rehearsal requires a persisted plan_id, but the plan response did not include one.", details: { project_id: normalized.spec.project } });
478
+ }
479
+ await sdk._applyEngine.upload(planned.plan, {
480
+ project: normalized.spec.project,
481
+ byteReaders: planned.byteReaders,
482
+ onEvent: emit,
483
+ });
484
+ return { planId, plan: planned.plan, projectId: normalized.spec.project };
407
485
  }
486
+
408
487
  try {
409
- const rehearsal = await withAutoApprove(() =>
410
- getSdk()._applyEngine.rehearse(planId, { project, teardown }),
411
- );
488
+ let planId = givenPlanId;
489
+ let replanned = null;
490
+ let rehearsal;
491
+ if (!planId) {
492
+ const fresh = await planAndUpload();
493
+ planId = fresh.planId;
494
+ rehearsal = await withAutoApprove(() => sdk._applyEngine.rehearse(planId, { project: project ?? fresh.projectId, teardown }));
495
+ } else {
496
+ try {
497
+ rehearsal = await withAutoApprove(() => sdk._applyEngine.rehearse(planId, { project, teardown }));
498
+ } catch (err) {
499
+ if (!isContentMissing(err) || !manifestPath) throw err;
500
+ // The plan's bytes were never uploaded (a --plan-only plan). Plan from
501
+ // the manifest to get byte readers, upload, and retry. When facts
502
+ // changed since the given plan the fresh plan is the one rehearsed,
503
+ // and the result says so — never silently substituted.
504
+ const fresh = await planAndUpload();
505
+ if (fresh.planId !== givenPlanId) replanned = { original_plan_id: givenPlanId, plan_id: fresh.planId, why: "plan facts changed since the given plan; a fresh reviewed plan was created, its bytes uploaded, and that plan rehearsed" };
506
+ planId = fresh.planId;
507
+ rehearsal = await withAutoApprove(() => sdk._applyEngine.rehearse(planId, { project: project ?? fresh.projectId, teardown }));
508
+ }
509
+ }
412
510
  console.log(JSON.stringify({
413
511
  ok: rehearsal.report.status === "passed",
512
+ plan_id: planId,
513
+ ...(manifestPath ? { manifest_path: manifestPath } : {}),
514
+ ...(replanned ? { replanned } : {}),
414
515
  rehearsal,
415
516
  commit_command: `run402 deploy apply --require-plan ${planId}`,
416
517
  }, null, 2));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "run402",
3
- "version": "4.73.4",
3
+ "version": "4.75.0",
4
4
  "description": "CLI for Run402 — full-stack backend infrastructure for AI agents: Postgres, auth, storage, serverless functions and atomic deploys. Paid with x402/MPP. Includes $0.03 image generation.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -70,17 +70,22 @@ export interface Run402UpActionInput {
70
70
  * project with a live release gets. Default false. */
71
71
  noRehearse?: boolean;
72
72
  /** Explicit display name to set on the principal when it has none yet.
73
- * Omitted: the detected client name (`claude-code`, `codex`, `cursor`,
74
- * or `agent`) is used and reported as `identity.source: "detected"`. */
73
+ * Omitted: `RUN402_AGENT_NAME` when set, else a specifically detected
74
+ * client (`claude-code`, `codex`, `cursor`) reported as `identity.source:
75
+ * "detected"`; when nothing is known no name is written and the result
76
+ * says `identity.source: "undetected"`. */
75
77
  identityName?: string;
76
78
  }
77
79
  /** How `up` resolved the principal's display name (first-deploy-agent-dx). */
78
80
  export interface Run402UpIdentity {
79
81
  display_name: string | null;
80
- /** `existing`: already set; `explicit`: set now from `identityName`;
81
- * `detected`: set now from the detected client; `unavailable`: could not
82
- * be read or set (never fails the deploy). */
83
- source: "existing" | "explicit" | "detected" | "unavailable";
82
+ /** `existing`: already set; `explicit`: set now from `identityName` or
83
+ * `RUN402_AGENT_NAME`; `detected`: set now from a specifically detected
84
+ * client (`claude-code`, `codex`, `cursor`); `undetected`: nothing known
85
+ * and nothing persisted a guess is never written as a name (the room
86
+ * presence is `agent` for coordination only); `unavailable`: could not be
87
+ * read or set (never fails the deploy). */
88
+ source: "existing" | "explicit" | "detected" | "undetected" | "unavailable";
84
89
  /** The project room presence `up` registered under that name, when it could. */
85
90
  presence?: {
86
91
  presence_id: string;
@@ -1 +1 @@
1
- {"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"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"}
@@ -56,6 +56,51 @@ export interface CreateCheckoutResult {
56
56
  checkout_url: string;
57
57
  topup_id: string;
58
58
  }
59
+ /**
60
+ * A Lightning cash top-up (lightning-cash-topup). `amount_usd_micros` is a
61
+ * QUOTE fixed at mint (`usd_value_is_quote: true`) and is what settlement
62
+ * credits. Never carries the provider's credential.
63
+ */
64
+ export interface LightningTopup {
65
+ org_id: string;
66
+ product: "balance_topup";
67
+ rail: "lightning";
68
+ topup_id: string;
69
+ /** The payable invoice, verbatim. */
70
+ bolt11: string | null;
71
+ payment_hash: string | null;
72
+ amount_sats: number | null;
73
+ amount_usd_micros: number;
74
+ usd_value_is_quote: true;
75
+ quoted_rate: {
76
+ usd_per_btc: number;
77
+ source: string;
78
+ observed_at: string;
79
+ amount_sats: number;
80
+ } | null;
81
+ invoice_expires_at: string | null;
82
+ status: "pending" | "paid" | "paid_late" | "expired";
83
+ paid_at: string | null;
84
+ credited_ledger_id: string | null;
85
+ created_at: string | null;
86
+ next_actions: Array<{
87
+ type: string;
88
+ method: string;
89
+ path: string;
90
+ why: string;
91
+ }>;
92
+ }
93
+ export interface CreateLightningTopupOptions {
94
+ /** Whole satoshis, 100–1,000,000. */
95
+ amountSats: number;
96
+ /** Replay-safe create: the same key returns the same top-up. */
97
+ idempotencyKey?: string;
98
+ }
99
+ export interface WaitForTopupOptions {
100
+ pollMs?: number;
101
+ timeoutMs?: number;
102
+ onPoll?: (state: LightningTopup) => void;
103
+ }
59
104
  export interface EmailOrganization {
60
105
  id: string;
61
106
  email: string;
@@ -92,6 +137,11 @@ export type CreateCheckoutOptions = {
92
137
  amountUsdMicros: number;
93
138
  successUrl?: string;
94
139
  cancelUrl?: string;
140
+ } | {
141
+ /** lightning-cash-topup: a bolt11 invoice instead of a Stripe session. */
142
+ product?: "balance_topup";
143
+ rail: "lightning";
144
+ amountSats: number;
95
145
  } | {
96
146
  product: "tier";
97
147
  tier: ProjectTier;
@@ -149,6 +199,19 @@ export declare class Billing {
149
199
  getHistory(identifier: OrganizationIdentifier, opts?: BillingHistoryOptions): Promise<BillingHistoryResult>;
150
200
  /** Create a Stripe checkout URL for an organization. */
151
201
  createCheckout(organizationId: string, checkout: CreateCheckoutOptions): Promise<CreateCheckoutResult>;
202
+ /**
203
+ * lightning-cash-topup: mint a bolt11 invoice that tops up the org's cash
204
+ * balance when paid. No funds move at creation; any active org member or a
205
+ * delegate for one of the org's projects may call it.
206
+ */
207
+ createLightningTopup(organizationId: string, options: CreateLightningTopupOptions): Promise<LightningTopup>;
208
+ /** Read one top-up (the waiting client's poll). */
209
+ getTopup(organizationId: string, topupId: string): Promise<LightningTopup>;
210
+ /**
211
+ * Poll a top-up until it is paid, paid late, or expired (or the timeout
212
+ * elapses, in which case the last observed state is returned).
213
+ */
214
+ waitForTopup(organizationId: string, topupId: string, options?: WaitForTopupOptions): Promise<LightningTopup>;
152
215
  /** Create an email-only (no-wallet) organization. Sends a verification email. */
153
216
  createEmailOrganization(email: string): Promise<EmailOrganization>;
154
217
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"billing.d.ts","sourceRoot":"","sources":["../../src/namespaces/billing.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"billing.d.ts","sourceRoot":"","sources":["../../src/namespaces/billing.ts"],"names":[],"mappings":"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"}