run402 2.15.3 → 2.16.1

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 CHANGED
@@ -66,7 +66,7 @@ run402 subdomains claim my-app # → my-app.run402.com (auto-reas
66
66
  ```
67
67
 
68
68
  `deploy-dir` hashes each file client-side and only uploads bytes the gateway doesn't already have. Re-deploying an unchanged tree returns immediately with `bytes_uploaded: 0`. Progress events stream to stderr.
69
- Release inspection commands print `{ status: "ok", release: ... }` or `{ status: "ok", diff: ... }`; use them after deploys to compare release inventory without starting another mutation. Inventories include `release_generation`, `static_manifest_sha256`, and nullable `static_manifest_metadata`; diffs include `static_assets` counters such as unchanged/changed/added/removed and CAS byte reuse. `deploy diagnose` / `deploy resolve --url` print URL-first diagnostics with `would_serve`, `diagnostic_status`, `match`, warnings, and next steps; host misses are successful diagnostic calls with `would_serve: false`. Stable-host resolve fields can include `authorization_result`, `cas_object`, `response_variant`, `allow`, `route_pattern`, `target_type`, `target_name`, and `target_file`.
69
+ Release inspection commands print `{ release: ... }` or `{ diff: ... }` (raw payload, no envelope — see the "Output Contract" section in [llms-cli.txt](llms-cli.txt)); use them after deploys to compare release inventory without starting another mutation. Inventories include `release_generation`, `static_manifest_sha256`, and nullable `static_manifest_metadata`; diffs include `static_assets` counters such as unchanged/changed/added/removed and CAS byte reuse. `deploy diagnose` / `deploy resolve --url` print URL-first diagnostics with `would_serve`, `diagnostic_status`, `match`, warnings, and next steps; host misses are successful diagnostic calls with `would_serve: false`. Stable-host resolve fields can include `authorization_result`, `cas_object`, `response_variant`, `allow`, `route_pattern`, `target_type`, `target_name`, and `target_file`.
70
70
 
71
71
  ### GitHub Actions OIDC deploys
72
72
 
package/lib/ai.mjs CHANGED
@@ -151,7 +151,7 @@ async function translate(args) {
151
151
 
152
152
  try {
153
153
  const data = await getSdk().ai.translate(projectId, { text, to, from: from ?? undefined, context: context ?? undefined });
154
- console.log(JSON.stringify({ status: "ok", text: data.text, from: data.from, to: data.to }));
154
+ console.log(JSON.stringify({ text: data.text, from: data.from, to: data.to }));
155
155
  } catch (err) {
156
156
  reportSdkError(err);
157
157
  }
@@ -194,7 +194,7 @@ async function moderate(args) {
194
194
 
195
195
  try {
196
196
  const data = await getSdk().ai.moderate(projectId, text);
197
- console.log(JSON.stringify({ status: "ok", flagged: data.flagged, categories: data.categories, category_scores: data.category_scores }));
197
+ console.log(JSON.stringify({ flagged: data.flagged, categories: data.categories, category_scores: data.category_scores }));
198
198
  } catch (err) {
199
199
  reportSdkError(err);
200
200
  }
@@ -216,7 +216,7 @@ async function usage(args) {
216
216
 
217
217
  try {
218
218
  const data = await getSdk().ai.usage(projectId);
219
- console.log(JSON.stringify({ status: "ok", ...data }));
219
+ console.log(JSON.stringify(data));
220
220
  } catch (err) {
221
221
  reportSdkError(err);
222
222
  }
package/lib/allowance.mjs CHANGED
@@ -82,23 +82,24 @@ async function status() {
82
82
  try {
83
83
  const data = await getSdk().allowance.status();
84
84
  if (!data.configured) {
85
- console.log(JSON.stringify({ status: "no_wallet", message: "No agent allowance found. Run: run402 allowance create" }));
86
- process.exit(1);
85
+ console.log(JSON.stringify({ wallet: null, hint: "Run: run402 allowance create" }));
86
+ return;
87
87
  }
88
88
  // Preserve CLI's rail field (SDK doesn't surface it; read from local allowance).
89
89
  const w = readAllowance();
90
90
  console.log(JSON.stringify({
91
- status: "ok",
92
- address: data.address,
93
- created: data.created,
94
- configured: data.configured,
95
- // GH-109: `funded` used to leak an on-disk marker that only tracks
96
- // faucet invocation, not actual pay-readiness. Renamed to `faucet_used`
97
- // to match its real semantics. For a true "can this account pay right
98
- // now" check, use `run402 allowance balance`.
99
- faucet_used: !!data.faucet_used,
100
- rail: w?.rail || "x402",
101
- path: data.path ?? ALLOWANCE_FILE,
91
+ wallet: {
92
+ address: data.address,
93
+ created: data.created,
94
+ configured: data.configured,
95
+ // GH-109: `funded` used to leak an on-disk marker that only tracks
96
+ // faucet invocation, not actual pay-readiness. Renamed to `faucet_used`
97
+ // to match its real semantics. For a true "can this account pay right
98
+ // now" check, use `run402 allowance balance`.
99
+ faucet_used: !!data.faucet_used,
100
+ rail: w?.rail || "x402",
101
+ path: data.path ?? ALLOWANCE_FILE,
102
+ },
102
103
  }));
103
104
  } catch (err) {
104
105
  reportSdkError(err);
@@ -109,9 +110,9 @@ async function create() {
109
110
  try {
110
111
  const result = await getSdk().allowance.create();
111
112
  console.log(JSON.stringify({
112
- status: "ok",
113
113
  address: result.address,
114
- message: `Agent allowance created. Stored locally at ${result.path ?? ALLOWANCE_FILE}`,
114
+ path: result.path ?? ALLOWANCE_FILE,
115
+ created: true,
115
116
  }));
116
117
  } catch (err) {
117
118
  const msg = (err instanceof Error) ? err.message : String(err);
@@ -199,7 +200,7 @@ async function fund() {
199
200
  }
200
201
 
201
202
  saveAllowance({ ...w, funded: true, lastFaucet: new Date().toISOString() });
202
- console.log(JSON.stringify({ status: "ok", message: "Faucet request sent but balance not yet confirmed", ...data }));
203
+ console.log(JSON.stringify({ ...data, balance_confirmed: false, hint: "Faucet request sent but on-chain balance not yet confirmed" }));
203
204
  }
204
205
 
205
206
  async function readUsdcBalance(client, usdc, address) {
package/lib/apps.mjs CHANGED
@@ -276,7 +276,7 @@ async function update(projectId, versionId, args) {
276
276
  if (parsedArgs.includes("--no-fork")) opts.fork_allowed = false;
277
277
  try {
278
278
  await getSdk().apps.updateVersion(positionals[0], positionals[1], opts);
279
- console.log(JSON.stringify({ status: "ok", project_id: positionals[0], version_id: positionals[1] }));
279
+ console.log(JSON.stringify({ project_id: positionals[0], version_id: positionals[1], updated: true }));
280
280
  } catch (err) {
281
281
  reportSdkError(err);
282
282
  }
@@ -294,7 +294,7 @@ async function deleteVersion(projectId, versionId, args = []) {
294
294
  }
295
295
  try {
296
296
  await getSdk().apps.deleteVersion(positionals[0], positionals[1]);
297
- console.log(JSON.stringify({ status: "ok", message: `Version ${positionals[1]} deleted.` }));
297
+ console.log(JSON.stringify({ project_id: positionals[0], version_id: positionals[1], deleted: true }));
298
298
  } catch (err) {
299
299
  reportSdkError(err);
300
300
  }
package/lib/assets.mjs CHANGED
@@ -505,7 +505,7 @@ async function get(projectId, argv) {
505
505
 
506
506
  mkdirSync(dirname(resolvePath(opts.output)), { recursive: true });
507
507
  await pipeline(res.body, createWriteStream(opts.output));
508
- console.log(JSON.stringify({ status: "ok", key, output: opts.output }));
508
+ console.log(JSON.stringify({ key, project_id: resolvedId, output: opts.output }));
509
509
  }
510
510
 
511
511
  // ---------------------------------------------------------------------------
@@ -548,7 +548,7 @@ async function rm(projectId, argv) {
548
548
 
549
549
  try {
550
550
  await getSdk().assets.rm(resolvedId, key);
551
- console.log(JSON.stringify({ status: "ok", key }));
551
+ console.log(JSON.stringify({ key, project_id: resolvedId, deleted: true }));
552
552
  } catch (err) {
553
553
  reportSdkError(err);
554
554
  }
package/lib/auth.mjs CHANGED
@@ -351,7 +351,7 @@ async function magicLink(args) {
351
351
  intent: intent ?? undefined,
352
352
  clientState: state ?? undefined,
353
353
  });
354
- console.log(JSON.stringify({ status: "ok", email, redirect_url: redirect, intent: intent || "signin" }));
354
+ console.log(JSON.stringify({ email, redirect_url: redirect, intent: intent || "signin", sent: true }));
355
355
  } catch (err) {
356
356
  reportSdkError(err);
357
357
  }
@@ -380,7 +380,7 @@ async function createUser(args) {
380
380
  redirectUrl: redirectUrl ?? undefined,
381
381
  clientState: clientState ?? undefined,
382
382
  });
383
- console.log(JSON.stringify({ status: "ok", ...data }));
383
+ console.log(JSON.stringify(data));
384
384
  } catch (err) {
385
385
  reportSdkError(err);
386
386
  }
@@ -407,7 +407,7 @@ async function inviteUser(args) {
407
407
  isAdmin,
408
408
  clientState: clientState ?? undefined,
409
409
  });
410
- console.log(JSON.stringify({ status: "ok", ...data }));
410
+ console.log(JSON.stringify(data));
411
411
  } catch (err) {
412
412
  reportSdkError(err);
413
413
  }
@@ -423,7 +423,7 @@ async function verify(args) {
423
423
 
424
424
  try {
425
425
  const data = await getSdk().auth.verifyMagicLink(projectId, token);
426
- console.log(JSON.stringify({ status: "ok", ...data }));
426
+ console.log(JSON.stringify(data));
427
427
  } catch (err) {
428
428
  reportSdkError(err);
429
429
  }
@@ -448,7 +448,7 @@ async function setPassword(args) {
448
448
  newPassword,
449
449
  currentPassword: currentPassword ?? undefined,
450
450
  });
451
- console.log(JSON.stringify({ status: "ok" }));
451
+ console.log(JSON.stringify({ project_id: projectId, password_set: true }));
452
452
  } catch (err) {
453
453
  reportSdkError(err);
454
454
  }
@@ -496,7 +496,7 @@ async function settings(args) {
496
496
  require_passkey_for_project_admin: requireAdminPasskey,
497
497
  };
498
498
  const data = await getSdk().auth.settings(projectId, patch);
499
- console.log(JSON.stringify({ status: "ok", ...patch, ...data }));
499
+ console.log(JSON.stringify({ ...patch, ...data }));
500
500
  } catch (err) {
501
501
  reportSdkError(err);
502
502
  }
@@ -534,7 +534,7 @@ async function passkeyRegisterVerify(args) {
534
534
  response,
535
535
  label: label ?? undefined,
536
536
  });
537
- console.log(JSON.stringify({ status: "ok", ...data }));
537
+ console.log(JSON.stringify(data));
538
538
  } catch (err) {
539
539
  reportSdkError(err);
540
540
  }
@@ -566,7 +566,7 @@ async function passkeyLoginVerify(args) {
566
566
  challengeId,
567
567
  response,
568
568
  });
569
- console.log(JSON.stringify({ status: "ok", ...data }));
569
+ console.log(JSON.stringify(data));
570
570
  } catch (err) {
571
571
  reportSdkError(err);
572
572
  }
@@ -595,7 +595,7 @@ async function deletePasskey(args) {
595
595
  accessToken,
596
596
  passkeyId,
597
597
  });
598
- console.log(JSON.stringify({ status: "ok", passkey_id: passkeyId }));
598
+ console.log(JSON.stringify({ passkey_id: passkeyId, deleted: true }));
599
599
  } catch (err) {
600
600
  reportSdkError(err);
601
601
  }
package/lib/billing.mjs CHANGED
@@ -275,7 +275,7 @@ async function autoRecharge(args) {
275
275
  enabled: state === "on",
276
276
  threshold,
277
277
  });
278
- console.log(JSON.stringify({ status: "ok", billing_account_id: accountId, enabled: state === "on" }));
278
+ console.log(JSON.stringify({ billing_account_id: accountId, enabled: state === "on", updated: true }));
279
279
  } catch (err) {
280
280
  reportSdkError(err);
281
281
  }
package/lib/ci.mjs CHANGED
@@ -346,7 +346,6 @@ async function linkGithub(args) {
346
346
  mkdirSync(dirname(absWorkflowPath), { recursive: true });
347
347
  writeFileSync(absWorkflowPath, workflow, { encoding: "utf8", mode: 0o644 });
348
348
  console.log(JSON.stringify({
349
- status: "ok",
350
349
  binding_id: binding.id,
351
350
  project_id: projectId,
352
351
  provider: CI_GITHUB_ACTIONS_PROVIDER,
@@ -383,7 +382,7 @@ async function list(args) {
383
382
  const project = resolveProjectId(flags.project);
384
383
  try {
385
384
  const result = await getSdk({ disablePaidFetch: true }).ci.listBindings({ project });
386
- console.log(JSON.stringify({ status: "ok", project_id: project, ...result }, null, 2));
385
+ console.log(JSON.stringify({ project_id: project, ...result }, null, 2));
387
386
  } catch (err) {
388
387
  reportSdkError(err);
389
388
  }
@@ -401,8 +400,8 @@ async function revoke(args) {
401
400
  try {
402
401
  const binding = await getSdk({ disablePaidFetch: true }).ci.revokeBinding(bindingId);
403
402
  console.log(JSON.stringify({
404
- status: "ok",
405
403
  binding,
404
+ revoked: true,
406
405
  revocation_residuals: [
407
406
  "Revocation stops future CI gateway requests.",
408
407
  "Revocation does not undo already-deployed code, stop in-flight deploy operations, rotate exfiltrated keys, or remove deployed functions.",
@@ -435,7 +434,7 @@ async function setAssetScopes(args) {
435
434
  bindingId,
436
435
  scopes,
437
436
  );
438
- console.log(JSON.stringify({ status: "ok", binding }, null, 2));
437
+ console.log(JSON.stringify({ binding }, null, 2));
439
438
  } catch (err) {
440
439
  reportSdkError(err);
441
440
  }
package/lib/contracts.mjs CHANGED
@@ -266,7 +266,7 @@ async function setRecovery(projectId, walletId, args) {
266
266
  if (address) validateEvmAddress(address, "--address");
267
267
  try {
268
268
  await getSdk().contracts.setRecovery(projectId, walletId, clear ? null : address);
269
- console.log(JSON.stringify({ status: "ok", wallet_id: walletId, recovery_address: clear ? null : address }));
269
+ console.log(JSON.stringify({ wallet_id: walletId, recovery_address: clear ? null : address, updated: true }));
270
270
  } catch (err) {
271
271
  reportSdkError(err);
272
272
  }
@@ -287,7 +287,7 @@ async function setAlert(projectId, walletId, args) {
287
287
  validateWeiFlag("--threshold-wei", threshold);
288
288
  try {
289
289
  await getSdk().contracts.setLowBalanceAlert(projectId, walletId, threshold);
290
- console.log(JSON.stringify({ status: "ok", wallet_id: walletId, threshold_wei: threshold }));
290
+ console.log(JSON.stringify({ wallet_id: walletId, threshold_wei: threshold, updated: true }));
291
291
  } catch (err) {
292
292
  reportSdkError(err);
293
293
  }
package/lib/deploy-v2.mjs CHANGED
@@ -255,7 +255,7 @@ Options:
255
255
  --method <method> HTTP method to diagnose (default: GET)
256
256
 
257
257
  Do not combine --url with --host or --path. Successful diagnostic misses still
258
- exit 0 with status: "ok"; inspect would_serve and diagnostic_status.
258
+ exit 0; inspect would_serve and diagnostic_status in the result payload.
259
259
  `;
260
260
 
261
261
  export async function runDeployV2(sub, args) {
@@ -509,7 +509,7 @@ async function applyCmd(args) {
509
509
  allowWarnings: opts.allowWarnings,
510
510
  allowWarningCodes: opts.allowWarningCodes,
511
511
  });
512
- console.log(JSON.stringify({ status: "ok", ...result }, null, 2));
512
+ console.log(JSON.stringify(result, null, 2));
513
513
  } catch (err) {
514
514
  reportDeployApplyError(err, useGithubActionsOidc);
515
515
  }
@@ -832,7 +832,7 @@ async function resumeCmd(args) {
832
832
  const result = await getSdk()._applyEngine.resume(opts.operationId, {
833
833
  onEvent: makeStderrEventWriter(opts.quiet),
834
834
  });
835
- console.log(JSON.stringify({ status: "ok", ...result }, null, 2));
835
+ console.log(JSON.stringify(result, null, 2));
836
836
  } catch (err) {
837
837
  reportSdkError(err);
838
838
  }
@@ -860,7 +860,7 @@ async function listCmd(args) {
860
860
  const sdkOpts = { project };
861
861
  if (opts.limit !== null) sdkOpts.limit = opts.limit;
862
862
  const result = await getSdk()._applyEngine.list(sdkOpts);
863
- console.log(JSON.stringify({ status: "ok", ...result }, null, 2));
863
+ console.log(JSON.stringify(result, null, 2));
864
864
  } catch (err) {
865
865
  reportSdkError(err);
866
866
  }
@@ -885,7 +885,7 @@ async function eventsCmd(args) {
885
885
 
886
886
  try {
887
887
  const result = await getSdk()._applyEngine.events(opts.operationId, { project });
888
- console.log(JSON.stringify({ status: "ok", ...result }, null, 2));
888
+ console.log(JSON.stringify(result, null, 2));
889
889
  } catch (err) {
890
890
  reportSdkError(err);
891
891
  }
@@ -933,7 +933,7 @@ async function releaseGetCmd(args) {
933
933
  const sdkOpts = { project, releaseId: opts.releaseId };
934
934
  if (opts.siteLimit !== null) sdkOpts.siteLimit = opts.siteLimit;
935
935
  const release = await getSdk()._applyEngine.getRelease(sdkOpts);
936
- console.log(JSON.stringify({ status: "ok", release }, null, 2));
936
+ console.log(JSON.stringify({ release }, null, 2));
937
937
  } catch (err) {
938
938
  reportSdkError(err);
939
939
  }
@@ -962,7 +962,7 @@ async function releaseActiveCmd(args) {
962
962
  const sdkOpts = { project };
963
963
  if (opts.siteLimit !== null) sdkOpts.siteLimit = opts.siteLimit;
964
964
  const release = await getSdk()._applyEngine.getActiveRelease(sdkOpts);
965
- console.log(JSON.stringify({ status: "ok", release }, null, 2));
965
+ console.log(JSON.stringify({ release }, null, 2));
966
966
  } catch (err) {
967
967
  reportSdkError(err);
968
968
  }
@@ -1005,7 +1005,7 @@ async function releaseDiffCmd(args) {
1005
1005
  const sdkOpts = { project, from: opts.from, to: opts.to };
1006
1006
  if (opts.limit !== null) sdkOpts.limit = opts.limit;
1007
1007
  const diff = await getSdk()._applyEngine.diff(sdkOpts);
1008
- console.log(JSON.stringify({ status: "ok", diff }, null, 2));
1008
+ console.log(JSON.stringify({ diff }, null, 2));
1009
1009
  } catch (err) {
1010
1010
  reportSdkError(err);
1011
1011
  }
@@ -1106,7 +1106,6 @@ async function printResolveEnvelope(input) {
1106
1106
  const resolution = await getSdk()._applyEngine.resolve(input);
1107
1107
  const summary = buildDeployResolveSummary(resolution, request);
1108
1108
  console.log(JSON.stringify({
1109
- status: "ok",
1110
1109
  would_serve: summary.would_serve,
1111
1110
  diagnostic_status: summary.diagnostic_status,
1112
1111
  match: summary.match,
package/lib/domains.mjs CHANGED
@@ -193,7 +193,7 @@ async function deleteDomain(args) {
193
193
  const projectId = resolveProjectId(project);
194
194
  try {
195
195
  await getSdk().domains.remove(domain, { projectId });
196
- console.log(JSON.stringify({ status: "ok", message: `Domain '${domain}' released.` }));
196
+ console.log(JSON.stringify({ domain, project_id: projectId, released: true }));
197
197
  } catch (err) {
198
198
  reportSdkError(err);
199
199
  }
package/lib/email.mjs CHANGED
@@ -222,7 +222,7 @@ async function create(args) {
222
222
 
223
223
  try {
224
224
  const data = await getSdk().email.createMailbox(projectId, slug);
225
- console.log(JSON.stringify({ status: "ok", mailbox_id: data.mailbox_id, address: data.address, slug: data.slug }));
225
+ console.log(JSON.stringify({ mailbox_id: data.mailbox_id, address: data.address, slug: data.slug, created: true }));
226
226
  } catch (err) {
227
227
  reportSdkError(err);
228
228
  }
@@ -254,7 +254,7 @@ async function send(args) {
254
254
  text: text ?? undefined,
255
255
  from_name: fromName ?? undefined,
256
256
  });
257
- console.log(JSON.stringify({ status: "ok", message_id: data.message_id, to: data.to, template: data.template, subject: data.subject }));
257
+ console.log(JSON.stringify({ message_id: data.message_id, to: data.to, template: data.template, subject: data.subject, sent: true }));
258
258
  } catch (err) {
259
259
  reportSdkError(err);
260
260
  }
@@ -317,7 +317,7 @@ async function getRaw(args) {
317
317
  if (outputFile) {
318
318
  const { writeFileSync } = await import("node:fs");
319
319
  writeFileSync(outputFile, buf);
320
- console.log(JSON.stringify({ status: "ok", message_id: messageId, bytes: buf.length, output: outputFile }));
320
+ console.log(JSON.stringify({ message_id: messageId, bytes: buf.length, output: outputFile }));
321
321
  } else {
322
322
  process.stdout.write(buf);
323
323
  }
@@ -375,7 +375,7 @@ async function reply(args) {
375
375
  from_name: fromName ?? undefined,
376
376
  in_reply_to: messageId,
377
377
  });
378
- console.log(JSON.stringify({ status: "ok", message_id: data.message_id, to: data.to, subject: replySubject, in_reply_to: messageId }));
378
+ console.log(JSON.stringify({ message_id: data.message_id, to: data.to, subject: replySubject, in_reply_to: messageId, sent: true }));
379
379
  } catch (err) {
380
380
  reportSdkError(err);
381
381
  }
@@ -396,7 +396,7 @@ async function deleteMailbox(args) {
396
396
 
397
397
  try {
398
398
  const data = await getSdk().email.deleteMailbox(projectId, positional ?? undefined);
399
- console.log(JSON.stringify({ status: "ok", mailbox_id: data.mailbox_id, address: data.address, deleted: true }));
399
+ console.log(JSON.stringify({ mailbox_id: data.mailbox_id, address: data.address, deleted: true }));
400
400
  } catch (err) {
401
401
  reportSdkError(err);
402
402
  }
@@ -407,7 +407,7 @@ async function status(args) {
407
407
  const projectId = resolveProjectId(strictFlagValue(args, "--project"));
408
408
  try {
409
409
  const mb = await getSdk().email.getMailbox(projectId);
410
- console.log(JSON.stringify({ status: "ok", mailbox_id: mb.mailbox_id, address: mb.address, slug: mb.slug }));
410
+ console.log(JSON.stringify({ mailbox_id: mb.mailbox_id, address: mb.address, slug: mb.slug }));
411
411
  } catch (err) {
412
412
  reportSdkError(err);
413
413
  }
package/lib/functions.mjs CHANGED
@@ -411,7 +411,7 @@ async function deleteFunction(projectId, name, args = []) {
411
411
  assertNoExtraPositionals(args, "run402 functions delete <project_id> <name>");
412
412
  try {
413
413
  await getSdk().functions.delete(projectId, name);
414
- console.log(JSON.stringify({ status: "ok", message: `Function '${name}' deleted.` }));
414
+ console.log(JSON.stringify({ name, project_id: projectId, deleted: true }));
415
415
  } catch (err) {
416
416
  reportSdkError(err);
417
417
  }
package/lib/image.mjs CHANGED
@@ -103,9 +103,9 @@ export async function run(sub, args) {
103
103
  if (opts.output) {
104
104
  const buf = Buffer.from(data.image, "base64");
105
105
  writeFileSync(opts.output, buf);
106
- console.log(JSON.stringify({ status: "ok", file: opts.output, size: buf.length, aspect: data.aspect }));
106
+ console.log(JSON.stringify({ file: opts.output, size: buf.length, aspect: data.aspect }));
107
107
  } else {
108
- console.log(JSON.stringify({ status: "ok", aspect: data.aspect, content_type: data.content_type, image: data.image }));
108
+ console.log(JSON.stringify({ aspect: data.aspect, content_type: data.content_type, image: data.image }));
109
109
  }
110
110
  } catch (err) {
111
111
  reportSdkError(err);
@@ -250,9 +250,9 @@ export const POST: APIRoute = async ({ request }) => {
250
250
  console.log(
251
251
  JSON.stringify(
252
252
  {
253
- status: "ok",
254
253
  dir: targetDir,
255
254
  files_created: files.map((f) => f.path),
255
+ created: true,
256
256
  next_steps: [
257
257
  `cd ${positionals[0] ?? "."}`,
258
258
  "npm install",
package/lib/init.mjs CHANGED
@@ -1,5 +1,6 @@
1
1
  import { readAllowance, saveAllowance, loadKeyStore, CONFIG_DIR } from "./config.mjs";
2
2
  import { getSdk } from "./sdk.mjs";
3
+ import { fail } from "./sdk-errors.mjs";
3
4
  import { mkdirSync } from "fs";
4
5
 
5
6
  const USDC_ABI = [{ name: "balanceOf", type: "function", stateMutability: "view", inputs: [{ name: "account", type: "address" }], outputs: [{ name: "", type: "uint256" }] }];
@@ -67,13 +68,11 @@ export async function run(args = []) {
67
68
 
68
69
  const existingAllowance = readAllowance();
69
70
  if (existingAllowance?.rail && existingAllowance.rail !== requestedRail && !switchRailConfirmed) {
70
- console.error(JSON.stringify({
71
- status: "error",
71
+ fail({
72
72
  code: "RAIL_SWITCH_REQUIRES_CONFIRM",
73
73
  message: `Already on rail '${existingAllowance.rail}'. Pass --switch-rail to switch to '${requestedRail}'.`,
74
74
  details: { current_rail: existingAllowance.rail, requested_rail: requestedRail },
75
- }));
76
- process.exit(1);
75
+ });
77
76
  }
78
77
 
79
78
  // In --json mode, human-readable lines go to stderr so stdout stays clean for
package/lib/message.mjs CHANGED
@@ -69,9 +69,8 @@ async function send(text) {
69
69
  try {
70
70
  await getSdk().admin.sendMessage(text);
71
71
  console.log(JSON.stringify({
72
- status: "ok",
73
- message: "Message sent to Run402 developers.",
74
72
  bytes_sent: bytes,
73
+ sent: true,
75
74
  }));
76
75
  } catch (err) {
77
76
  reportSdkError(err);
package/lib/projects.mjs CHANGED
@@ -346,7 +346,7 @@ async function validateExpose(args = []) {
346
346
  ...(project ? { project } : {}),
347
347
  ...(migration !== null && migration !== undefined ? { migrationSql: migration } : {}),
348
348
  });
349
- console.log(JSON.stringify({ status: "ok", ...data }, null, 2));
349
+ console.log(JSON.stringify(data, null, 2));
350
350
  } catch (err) {
351
351
  reportSdkError(err);
352
352
  }
@@ -364,7 +364,7 @@ async function getExpose(projectId) {
364
364
  async function list() {
365
365
  const store = loadKeyStore();
366
366
  const entries = Object.entries(store.projects);
367
- if (entries.length === 0) { console.log(JSON.stringify({ status: "ok", projects: [], message: "No projects yet." })); return; }
367
+ if (entries.length === 0) { console.log(JSON.stringify([])); return; }
368
368
  const activeId = store.active_project_id;
369
369
  console.log(JSON.stringify(entries.map(([id, p]) => ({ project_id: id, active: id === activeId, site_url: p.site_url })), null, 2));
370
370
  }
@@ -500,7 +500,7 @@ async function use(projectId) {
500
500
  }
501
501
  try {
502
502
  await getSdk().projects.use(projectId);
503
- console.log(JSON.stringify({ status: "ok", active_project_id: projectId }));
503
+ console.log(JSON.stringify({ active_project_id: projectId, set: true }));
504
504
  } catch (err) {
505
505
  reportSdkError(err);
506
506
  }
@@ -532,7 +532,7 @@ async function promoteUser(projectId, email) {
532
532
  }
533
533
  try {
534
534
  await getSdk().projects.promoteUser(projectId, email);
535
- console.log(JSON.stringify({ status: "ok", email }));
535
+ console.log(JSON.stringify({ project_id: projectId, email, promoted: true }));
536
536
  } catch (err) {
537
537
  reportSdkError(err);
538
538
  }
@@ -548,7 +548,7 @@ async function demoteUser(projectId, email) {
548
548
  }
549
549
  try {
550
550
  await getSdk().projects.demoteUser(projectId, email);
551
- console.log(JSON.stringify({ status: "ok", email }));
551
+ console.log(JSON.stringify({ project_id: projectId, email, demoted: true }));
552
552
  } catch (err) {
553
553
  reportSdkError(err);
554
554
  }
@@ -557,17 +557,15 @@ async function demoteUser(projectId, email) {
557
557
  async function deleteProject(projectId, args = []) {
558
558
  const confirmed = Array.isArray(args) && args.includes("--confirm");
559
559
  if (!confirmed) {
560
- console.error(JSON.stringify({
561
- status: "error",
560
+ fail({
562
561
  code: "CONFIRMATION_REQUIRED",
563
562
  message: `Destructive: deleting project ${projectId} drops all DB schemas, functions, subdomains, mailbox, blobs, and secrets. This is irreversible. Re-run with --confirm to proceed.`,
564
563
  details: { project_id: projectId, destroys: ["schemas", "functions", "subdomains", "mailbox", "blobs", "secrets"] },
565
- }));
566
- process.exit(1);
564
+ });
567
565
  }
568
566
  try {
569
567
  await getSdk().projects.delete(projectId);
570
- console.log(JSON.stringify({ status: "ok", message: `Project ${projectId} deleted.` }));
568
+ console.log(JSON.stringify({ project_id: projectId, deleted: true }));
571
569
  } catch (err) {
572
570
  reportSdkError(err);
573
571
  }
package/lib/secrets.mjs CHANGED
@@ -129,7 +129,7 @@ async function set(projectId, key, args = []) {
129
129
  }
130
130
  try {
131
131
  await getSdk().secrets.set(projectId, key, val);
132
- console.log(JSON.stringify({ status: "ok", message: `Secret '${key}' set for project ${projectId}.` }));
132
+ console.log(JSON.stringify({ key, project_id: projectId, set: true }));
133
133
  } catch (err) {
134
134
  reportSdkError(err);
135
135
  }
@@ -200,7 +200,7 @@ async function deleteSecret(projectId, key, args = []) {
200
200
  }
201
201
  try {
202
202
  await getSdk().secrets.delete(projectId, key);
203
- console.log(JSON.stringify({ status: "ok", message: `Secret '${key}' deleted.` }));
203
+ console.log(JSON.stringify({ key, project_id: projectId, deleted: true }));
204
204
  } catch (err) {
205
205
  reportSdkError(err);
206
206
  }
@@ -160,7 +160,7 @@ async function remove(args) {
160
160
  const projectId = resolveProjectId(parseFlag(args, "--project"));
161
161
  try {
162
162
  await getSdk().senderDomain.remove(projectId);
163
- console.log(JSON.stringify({ status: "ok" }));
163
+ console.log(JSON.stringify({ project_id: projectId, removed: true }));
164
164
  } catch (err) {
165
165
  reportSdkError(err);
166
166
  }
@@ -192,7 +192,7 @@ async function inboundToggle(action, args) {
192
192
  console.log(JSON.stringify(data, null, 2));
193
193
  } else {
194
194
  await getSdk().senderDomain.disableInbound(projectId, domain);
195
- console.log(JSON.stringify({ status: "ok", domain }));
195
+ console.log(JSON.stringify({ project_id: projectId, domain, inbound_enabled: false }));
196
196
  }
197
197
  } catch (err) {
198
198
  reportSdkError(err);
package/lib/sites.mjs CHANGED
@@ -207,11 +207,10 @@ async function deploy(args) {
207
207
  for (let i = 0; i < parsedArgs.length; i++) {
208
208
  if (parsedArgs[i] === "--help" || parsedArgs[i] === "-h") { console.log(HELP); process.exit(0); }
209
209
  if (parsedArgs[i] === "--inherit") {
210
- console.error(JSON.stringify({
211
- status: "error",
210
+ fail({
211
+ code: "BAD_FLAG",
212
212
  message: "--inherit is removed; the SDK now uploads only changed files automatically.",
213
- }));
214
- process.exit(1);
213
+ });
215
214
  }
216
215
  }
217
216
  if (opts.target !== undefined) failUnsupportedTarget();
@@ -304,8 +303,7 @@ async function deployDir(args) {
304
303
  !opts.confirmPrune &&
305
304
  !opts.dryRun
306
305
  ) {
307
- console.error(JSON.stringify({
308
- status: "error",
306
+ fail({
309
307
  code: "PRUNE_CONFIRMATION_REQUIRED",
310
308
  message:
311
309
  `sites deploy-dir would replace the entire site with ${fileCount} ` +
@@ -317,8 +315,7 @@ async function deployDir(args) {
317
315
  threshold: SMALL_DIR_THRESHOLD,
318
316
  dir: opts.dir,
319
317
  },
320
- }));
321
- process.exit(1);
318
+ });
322
319
  }
323
320
 
324
321
  if (opts.dryRun) {
@@ -328,7 +325,6 @@ async function deployDir(args) {
328
325
  site: { replace: fileSet },
329
326
  }, { dryRun: true });
330
327
  console.log(JSON.stringify({
331
- status: "ok",
332
328
  dry_run: true,
333
329
  local_file_count: fileCount,
334
330
  plan_id: plan.plan_id,
@@ -355,7 +351,7 @@ async function deployDir(args) {
355
351
  if (data.deployment_id) {
356
352
  updateProject(projectId, { last_deployment_id: data.deployment_id });
357
353
  }
358
- console.log(JSON.stringify({ status: "ok", ...data }, null, 2));
354
+ console.log(JSON.stringify(data, null, 2));
359
355
  } catch (err) {
360
356
  reportSdkError(err);
361
357
  }