run402 4.102.0 → 4.103.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/cli.mjs CHANGED
@@ -384,24 +384,6 @@ switch (cmd) {
384
384
  await run(sub, rest);
385
385
  break;
386
386
  }
387
- // `message` is RESERVED, not merely renamed: it is being kept free for
388
- // addressed agent/human messaging. Aliasing it to feedback would cement the
389
- // old meaning on the exact noun that is about to mean something else.
390
- case "message": {
391
- const { fail } = await import("./lib/sdk-errors.mjs");
392
- fail({
393
- code: "COMMAND_REMOVED",
394
- message: "`run402 message` was renamed to `run402 feedback`.",
395
- hint: "run402 feedback send \"<text>\"",
396
- details: { was: "message", now: "feedback", reserved: "the `message` noun is reserved for addressed agent/human messaging" },
397
- next_actions: [
398
- { type: "edit_request", command: "run402 feedback send \"<text>\"", why: "Send feedback to the Run402 developers." },
399
- { type: "edit_request", command: "run402 messages send \"<text>\"", why: "Message the other agents working in this room." },
400
- { type: "edit_request", command: "run402 escalations raise \"<text>\"", why: "Page a human and wait for a named one to take it." },
401
- ],
402
- });
403
- break;
404
- }
405
387
  case "agent": {
406
388
  const { run } = await import("./lib/agent.mjs");
407
389
  await run(sub, rest);
@@ -472,11 +454,6 @@ switch (cmd) {
472
454
  await run(sub, rest);
473
455
  break;
474
456
  }
475
- case "notifications": {
476
- const { run } = await import("./lib/notifications.mjs");
477
- await run(sub, rest);
478
- break;
479
- }
480
457
  case "webhook-secret": {
481
458
  const { run } = await import("./lib/webhook-secret.mjs");
482
459
  await run(sub, rest);
@@ -484,28 +484,4 @@ export const COMMAND_MANIFEST = [
484
484
  // completeness check against cli.mjs's dispatch switch.
485
485
  export const SKIPPED_FAMILIES = {
486
486
  "dev": "interactive wrapper that spawns `astro dev`",
487
- // RESERVED, not dispatched: every `run402 message …` fails with
488
- // COMMAND_REMOVED pointing at `feedback send` / `messages send` /
489
- // `escalations raise`. It has no subcommands to manifest because it takes
490
- // none — the noun is being held for addressed agent/human messaging.
491
- "message": "reserved noun; fails with COMMAND_REMOVED (renamed to `feedback`)",
492
- // Split into `deliveries` / `contacts` / `subscriptions`; every subcommand
493
- // answers COMMAND_REMOVED naming its successor.
494
- "notifications": "reserved group; split by legible-cli-surface",
495
- };
496
-
497
- /**
498
- * SUBCOMMAND spellings kept alive only to answer `COMMAND_REMOVED`.
499
- *
500
- * A retired spelling still needs a `case` branch — that branch IS the redirect,
501
- * and without it a caller gets a generic "unknown subcommand" instead of being
502
- * told where the verb went. But it is not a command: it dispatches nothing and
503
- * belongs in no capability mapping, so the inventory gate must not demand one.
504
- *
505
- * The family-level equivalent is SKIPPED_FAMILIES above. This exists because
506
- * some spellings are retired INSIDE a family rather than as a whole family,
507
- * which the family list cannot express.
508
- */
509
- export const RESERVED_SUBCOMMANDS = {
510
- "escalations:contacts": "merged into `contacts` — the ladder and Telegram channels are one question",
511
487
  };
package/lib/contacts.mjs CHANGED
@@ -83,7 +83,7 @@ async function preferences(args) {
83
83
  }
84
84
 
85
85
  if (positionals[0] !== "set") {
86
- fail({ code: "BAD_USAGE", message: "Usage: run402 notifications preferences [set <key>=<value> ...]" });
86
+ fail({ code: "BAD_USAGE", message: "Usage: run402 contacts preferences [set <key>=<value> ...]" });
87
87
  }
88
88
 
89
89
  // SET — parse remaining positional args as key=value
@@ -171,7 +171,7 @@ async function channelsConnect(args) {
171
171
  if (positionals.length === 0) {
172
172
  fail({
173
173
  code: "BAD_USAGE",
174
- message: "Usage: run402 notifications channels connect telegram [--label <name>]",
174
+ message: "Usage: run402 contacts connect telegram [--label <name>]",
175
175
  });
176
176
  }
177
177
  if (positionals[0] !== "telegram") {
@@ -209,7 +209,7 @@ async function channelsConnect(args) {
209
209
  return;
210
210
  }
211
211
  console.error("Timed out waiting for you to tap the link — the connect code has expired.");
212
- console.error("Run `run402 notifications channels connect telegram` again for a fresh link.");
212
+ console.error("Run `run402 contacts connect telegram` again for a fresh link.");
213
213
  console.log(JSON.stringify({ ...pending, connected: false, timed_out: true }, null, 2));
214
214
  process.exit(1);
215
215
  }
@@ -229,7 +229,7 @@ async function channelsRevoke(args) {
229
229
  const [bindingId] = requirePositionalCount(a, [], {
230
230
  min: 1,
231
231
  max: 1,
232
- command: "run402 notifications channels revoke <binding_id>",
232
+ command: "run402 contacts rm <contact_id>",
233
233
  missing: "Missing <binding_id>.",
234
234
  });
235
235
  walletAuthHeaders("/agent/v1/notifications/channels/telegram");
@@ -264,8 +264,8 @@ async function runChannels(args) {
264
264
  await channelsRevoke(rest);
265
265
  return;
266
266
  }
267
- failUnknownSubcommand("notifications channels", channelsAction, {
268
- hint: "Run `run402 notifications channels --help` for usage.",
267
+ failUnknownSubcommand("contacts", channelsAction, {
268
+ hint: "Run `run402 contacts --help` for usage.",
269
269
  });
270
270
  }
271
271
 
@@ -226,24 +226,6 @@ async function resolveCmd(args) {
226
226
  }
227
227
  }
228
228
 
229
- async function contacts(args) {
230
- // Merged into `run402 contacts` (legible-cli-surface D4): the escalation
231
- // ladder and Telegram channels were the same idea — "where a human is
232
- // reachable" — under two names, and neither spelling suggested the other
233
- // existed. Reserved, not aliased.
234
- const [sub] = Array.isArray(args) ? args : [];
235
- fail({
236
- code: "COMMAND_REMOVED",
237
- message: "`run402 escalations contacts` moved to `run402 contacts`.",
238
- hint: sub === "remove" ? "run402 contacts rm <contact_id>" : `run402 contacts ${sub ?? "list"}`,
239
- details: {
240
- was: `escalations contacts${sub ? ` ${sub}` : ""}`,
241
- now: "contacts",
242
- why: "the paging ladder and Telegram channels are one question — where a human is reachable",
243
- },
244
- });
245
- }
246
-
247
229
  export async function run(sub, args) {
248
230
  const argv = Array.isArray(args) ? args : [];
249
231
  if (!sub || hasHelp([sub, ...argv])) {
@@ -266,15 +248,8 @@ export async function run(sub, args) {
266
248
  case "resolve":
267
249
  await resolveCmd(argv);
268
250
  break;
269
- case "contacts":
270
- await contacts(argv);
271
- break;
272
251
  default:
273
252
  failUnknownSubcommand("escalations", sub, {
274
- // `contacts` is a nested group, so it has no manifest row of its own —
275
- // without this it would be missing from the suggestion list a lost
276
- // agent reads.
277
- extraSubcommands: ["contacts"],
278
253
  hint: "Run `run402 escalations --help` for usage.",
279
254
  });
280
255
  }
package/lib/projects.mjs CHANGED
@@ -653,31 +653,6 @@ async function current() {
653
653
  console.log(JSON.stringify(out, null, 2));
654
654
  }
655
655
 
656
- function commandMoved(name) {
657
- fail({
658
- code: "COMMAND_MOVED",
659
- message: `run402 projects ${name} moved to the explicit local credential-cache surface.`,
660
- hint: "Use `run402 credentials project-keys status/export --project <project_id>`.",
661
- details: {
662
- old_command: `projects ${name}`,
663
- new_command: name === "keys" ? "credentials project-keys export --reveal" : "credentials project-keys status",
664
- source: "local_cache",
665
- },
666
- next_actions: [
667
- {
668
- type: "run_command",
669
- command: "run402 credentials project-keys status --project <project_id>",
670
- why: "Inspect cached key presence without revealing secrets.",
671
- },
672
- {
673
- type: "run_command",
674
- command: "run402 credentials project-keys export --project <project_id> --reveal",
675
- why: "Reveal cached project keys only when you explicitly need secret material.",
676
- },
677
- ],
678
- });
679
- }
680
-
681
656
  async function sqlCmd(projectId, args = []) {
682
657
  let file = null;
683
658
  let query = null;
@@ -970,8 +945,6 @@ export async function run(sub, args) {
970
945
  case "rename": { const { projectId, rest } = resolveProjectSelector(args, { rejectBareFirst: true, valueFlags: FLAGS_BY_SUB.rename.values }); await rename(projectId, rest); break; }
971
946
  case "tenant-payments": { const { projectId, rest } = resolveProjectSelector(args, { rejectBareFirst: true, valueFlags: FLAGS_BY_SUB["tenant-payments"].values }); await tenantPayments(projectId, rest); break; }
972
947
  case "get": { const { projectId } = resolveProjectSelector(args, { rejectBareFirst: true }); await get(projectId); break; }
973
- case "info": commandMoved("info"); break;
974
- case "keys": commandMoved("keys"); break;
975
948
  case "sql": { const { projectId, rest } = resolveProjectSelector(args, { maxBarePositionals: 1, valueFlags: FLAGS_BY_SUB.sql.values, rejectBareFirstWhenFlagPresent: ["--file"] }); await sqlCmd(projectId, rest); break; }
976
949
  case "rest": { const { projectId, rest: restArgs } = resolveProjectSelector(args, { valueFlags: FLAGS_BY_SUB.rest.values }); await rest(projectId, restArgs); break; }
977
950
  case "usage": { const { projectId } = resolveProjectSelector(args, { rejectBareFirst: true }); await usage(projectId); break; }
@@ -119,7 +119,7 @@ async function rulesRm(args) {
119
119
  const [ruleId] = requirePositionalCount(a, [], {
120
120
  min: 1,
121
121
  max: 1,
122
- command: "run402 notifications rules rm <rule_id>",
122
+ command: "run402 subscriptions rm <subscription_id>",
123
123
  missing: "Missing <rule_id>.",
124
124
  });
125
125
  walletAuthHeaders("/agent/v1/notifications/rules");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "run402",
3
- "version": "4.102.0",
3
+ "version": "4.103.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": {
@@ -1,5 +1,5 @@
1
1
  {
2
- "surface_version": "4.102.0",
2
+ "surface_version": "4.103.0",
3
3
  "verbs": [
4
4
  "repos create",
5
5
  "repos list",
@@ -1,70 +0,0 @@
1
- /**
2
- * `run402 notifications` — tombstone dispatcher. Delivery RECORDS and the
3
- * CONFIGURATION producing them live under separate nouns:
4
- *
5
- * notifications list|get -> deliveries list|get
6
- * notifications channels -> contacts (merged with escalations contacts)
7
- * notifications rules -> subscriptions
8
- * notifications preferences -> contacts preferences
9
- *
10
- * Reserved, not aliased: each subcommand names its successor so one failed
11
- * call teaches the new model, where an alias would teach the old one forever.
12
- */
13
- import { fail } from "./sdk-errors.mjs";
14
- import { hasHelp } from "./argparse.mjs";
15
-
16
- const MOVED = {
17
- list: "deliveries list",
18
- get: "deliveries get",
19
- channels: "contacts",
20
- rules: "subscriptions",
21
- preferences: "contacts preferences",
22
- test: "contacts preferences",
23
- };
24
-
25
- const HELP = `run402 notifications — SPLIT into three nouns
26
-
27
- Usage:
28
- run402 deliveries <list|get> delivery records — did it land
29
- run402 contacts <list|add|connect|rm|preferences|test>
30
- where a human is reachable
31
- run402 subscriptions <add|list|rm> which events go where
32
-
33
- The group mixed delivery RECORDS with the CONFIGURATION that produces them.
34
- Where everything went:
35
-
36
- notifications list|get -> run402 deliveries list|get
37
- notifications channels -> run402 contacts (merged with the
38
- escalation paging ladder — one question:
39
- where is a human reachable)
40
- notifications rules -> run402 subscriptions
41
- notifications preferences -> run402 contacts preferences
42
- notifications test -> run402 contacts test
43
-
44
- Run \`run402 deliveries --help\`, \`run402 contacts --help\`, or
45
- \`run402 subscriptions --help\`.
46
- `;
47
-
48
- export async function run(sub, args) {
49
- // `--help` is a QUESTION, and the most useful answer to "help me with
50
- // notifications" is where everything moved — not a failure. Actually
51
- // invoking a moved subcommand still fails, naming its successor.
52
- if (!sub || hasHelp([sub, ...(Array.isArray(args) ? args : [])])) {
53
- console.log(HELP);
54
- process.exit(0);
55
- }
56
- const now = MOVED[sub];
57
- fail({
58
- code: "COMMAND_REMOVED",
59
- message: now
60
- ? `\`run402 notifications ${sub}\` moved to \`run402 ${now}\`.`
61
- : "`run402 notifications` was split into `deliveries`, `contacts` and `subscriptions`.",
62
- hint: now ? `run402 ${now}` : "run402 deliveries --help | run402 contacts --help | run402 subscriptions --help",
63
- details: {
64
- was: `notifications${sub ? ` ${sub}` : ""}`,
65
- now: now ?? null,
66
- why: "the group mixed delivery RECORDS with the CONFIGURATION that produces them",
67
- moved: MOVED,
68
- },
69
- });
70
- }