agentera 3.0.0-dev.4 → 3.0.0-dev.5

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.
Files changed (118) hide show
  1. package/bundle/.agentera-npx-bundle.json +1 -1
  2. package/bundle/references/cli/agent-ready-state-contract.yaml +5 -5
  3. package/bundle/references/cli/bundle-skill-vocabulary.yaml +1 -1
  4. package/bundle/references/cli/capability-instruction-contract.yaml +98 -57
  5. package/bundle/references/cli/routing-execution-vocabulary.yaml +6 -6
  6. package/bundle/references/cli/update-channels.yaml +17 -2
  7. package/bundle/references/cli/vocabulary-index.yaml +3 -3
  8. package/bundle/references/cli/vocabulary.md +22 -16
  9. package/bundle/registry.json +1 -1
  10. package/bundle/skills/agentera/SKILL.md +38 -21
  11. package/bundle/skills/agentera/agents/dokumentera.toml +1 -1
  12. package/bundle/skills/agentera/agents/hej.toml +1 -1
  13. package/bundle/skills/agentera/agents/inspektera.toml +1 -1
  14. package/bundle/skills/agentera/agents/inspirera.toml +1 -1
  15. package/bundle/skills/agentera/agents/optimera.toml +1 -1
  16. package/bundle/skills/agentera/agents/orkestrera.toml +1 -1
  17. package/bundle/skills/agentera/agents/planera.toml +1 -1
  18. package/bundle/skills/agentera/agents/profilera.toml +1 -1
  19. package/bundle/skills/agentera/agents/realisera.toml +1 -1
  20. package/bundle/skills/agentera/agents/resonera.toml +1 -1
  21. package/bundle/skills/agentera/agents/visionera.toml +1 -1
  22. package/bundle/skills/agentera/agents/visualisera.toml +1 -1
  23. package/bundle/skills/agentera/capabilities/orkestrera/schemas/validation.yaml +26 -13
  24. package/bundle/skills/agentera/capability_schema_contract.yaml +33 -14
  25. package/bundle/skills/agentera/references/contract.md +2 -2
  26. package/bundle/skills/agentera/schemas/artifacts/decisions.yaml +1 -1
  27. package/bundle/skills/agentera/schemas/artifacts/progress.yaml +15 -36
  28. package/bundle/skills/agentera/schemas/artifacts/todo.yaml +14 -0
  29. package/bundle/skills/hej/SKILL.md +1 -1
  30. package/dist/capabilities/dokumentera/instructions.js +6 -0
  31. package/dist/capabilities/dokumentera/instructions.js.map +1 -0
  32. package/dist/capabilities/hej/instructions.js +6 -0
  33. package/dist/capabilities/hej/instructions.js.map +1 -0
  34. package/dist/capabilities/index.js +38 -0
  35. package/dist/capabilities/index.js.map +1 -0
  36. package/dist/capabilities/inspektera/instructions.js +6 -0
  37. package/dist/capabilities/inspektera/instructions.js.map +1 -0
  38. package/dist/capabilities/inspirera/instructions.js +6 -0
  39. package/dist/capabilities/inspirera/instructions.js.map +1 -0
  40. package/dist/capabilities/optimera/instructions.js +6 -0
  41. package/dist/capabilities/optimera/instructions.js.map +1 -0
  42. package/dist/capabilities/orkestrera/instructions.js +6 -0
  43. package/dist/capabilities/orkestrera/instructions.js.map +1 -0
  44. package/dist/capabilities/planera/instructions.js +6 -0
  45. package/dist/capabilities/planera/instructions.js.map +1 -0
  46. package/dist/capabilities/profilera/instructions.js +6 -0
  47. package/dist/capabilities/profilera/instructions.js.map +1 -0
  48. package/dist/capabilities/realisera/instructions.js +6 -0
  49. package/dist/capabilities/realisera/instructions.js.map +1 -0
  50. package/dist/capabilities/resonera/instructions.js +6 -0
  51. package/dist/capabilities/resonera/instructions.js.map +1 -0
  52. package/dist/capabilities/visionera/instructions.js +6 -0
  53. package/dist/capabilities/visionera/instructions.js.map +1 -0
  54. package/dist/capabilities/visualisera/instructions.js +6 -0
  55. package/dist/capabilities/visualisera/instructions.js.map +1 -0
  56. package/dist/cli/capabilityContext.js +92 -26
  57. package/dist/cli/capabilityContext.js.map +1 -1
  58. package/dist/cli/commands/capability.js +1 -8
  59. package/dist/cli/commands/capability.js.map +1 -1
  60. package/dist/cli/commands/doctor.js +14 -2
  61. package/dist/cli/commands/doctor.js.map +1 -1
  62. package/dist/cli/commands/state.js +22 -11
  63. package/dist/cli/commands/state.js.map +1 -1
  64. package/dist/cli/commands/validate.js +12 -2
  65. package/dist/cli/commands/validate.js.map +1 -1
  66. package/dist/cli/dispatch.js +470 -172
  67. package/dist/cli/dispatch.js.map +1 -1
  68. package/dist/cli/errors.js +53 -0
  69. package/dist/cli/errors.js.map +1 -0
  70. package/dist/cli/help.js +1 -1
  71. package/dist/cli/help.js.map +1 -1
  72. package/dist/cli/orientation.js +9 -6
  73. package/dist/cli/orientation.js.map +1 -1
  74. package/dist/cli/stateQuery.js +7 -0
  75. package/dist/cli/stateQuery.js.map +1 -1
  76. package/dist/cli/todoMarkdown.js +33 -0
  77. package/dist/cli/todoMarkdown.js.map +1 -0
  78. package/dist/hooks/common.js +0 -2
  79. package/dist/hooks/common.js.map +1 -1
  80. package/dist/hooks/validateArtifact.js +10 -8
  81. package/dist/hooks/validateArtifact.js.map +1 -1
  82. package/dist/registries/capabilityContract.js +12 -11
  83. package/dist/registries/capabilityContract.js.map +1 -1
  84. package/dist/registries/evaluatorHandoffContract.js +171 -0
  85. package/dist/registries/evaluatorHandoffContract.js.map +1 -0
  86. package/dist/setup/codex.js +146 -5
  87. package/dist/setup/codex.js.map +1 -1
  88. package/dist/upgrade/migrateArtifactsV1ToV2.js +0 -1
  89. package/dist/upgrade/migrateArtifactsV1ToV2.js.map +1 -1
  90. package/dist/upgrade/nextMajorDoctor.js +121 -0
  91. package/dist/upgrade/nextMajorDoctor.js.map +1 -0
  92. package/dist/upgrade/runtimeMigration.js +19 -3
  93. package/dist/upgrade/runtimeMigration.js.map +1 -1
  94. package/dist/upgrade/versionResolution.js +4 -4
  95. package/dist/upgrade/versionResolution.js.map +1 -1
  96. package/dist/validate/appHomeContract.js +1 -1
  97. package/dist/validate/appHomeContract.js.map +1 -1
  98. package/dist/validate/capability.js +11 -3
  99. package/dist/validate/capability.js.map +1 -1
  100. package/package.json +3 -3
  101. package/bundle/skills/agentera/capabilities/dokumentera/instructions.md +0 -428
  102. package/bundle/skills/agentera/capabilities/hej/instructions.md +0 -331
  103. package/bundle/skills/agentera/capabilities/inspektera/instructions.md +0 -514
  104. package/bundle/skills/agentera/capabilities/inspirera/instructions.md +0 -280
  105. package/bundle/skills/agentera/capabilities/optimera/instructions.md +0 -437
  106. package/bundle/skills/agentera/capabilities/orkestrera/instructions.md +0 -433
  107. package/bundle/skills/agentera/capabilities/planera/instructions.md +0 -368
  108. package/bundle/skills/agentera/capabilities/profilera/instructions.md +0 -419
  109. package/bundle/skills/agentera/capabilities/realisera/instructions.md +0 -403
  110. package/bundle/skills/agentera/capabilities/resonera/instructions.md +0 -329
  111. package/bundle/skills/agentera/capabilities/visionera/instructions.md +0 -309
  112. package/bundle/skills/agentera/capabilities/visualisera/instructions.md +0 -400
  113. package/dist/cli/commands/backfill.js +0 -84
  114. package/dist/cli/commands/backfill.js.map +0 -1
  115. package/dist/core/git.js +0 -43
  116. package/dist/core/git.js.map +0 -1
  117. package/dist/state/progressCommit.js +0 -289
  118. package/dist/state/progressCommit.js.map +0 -1
@@ -1,6 +1,5 @@
1
1
  import { cmdPrime } from "./commands/prime.js";
2
2
  import { cmdLint } from "./commands/lint.js";
3
- import { cmdBackfill } from "./commands/backfill.js";
4
3
  import { cmdState, isPortedStateCommand } from "./commands/state.js";
5
4
  import { COMMAND_FILTERS } from "./stateQuery.js";
6
5
  import { cmdQuery } from "./commands/query.js";
@@ -18,12 +17,73 @@ import { HookCliAdapter } from "../hooks/validateArtifact.js";
18
17
  import fsForHooks from "node:fs";
19
18
  import { usageMain } from "../analytics/usageStats.js";
20
19
  import { validatePathValue } from "./argvalidate.js";
20
+ import { emitInvalidInput, } from "./errors.js";
21
21
  import { cmdCapability, CAPABILITY_ROUTING_NAMES } from "./commands/capability.js";
22
22
  import { printCommandHelp, printDoctorHelp, printTopLevelHelp, printUpgradeHelp, splitHelpArgs, wantsHelp, } from "./help.js";
23
23
  import { cmdValidate, cmdValidateCapability, cmdValidateCapabilityContract, cmdValidateArtifact, cmdValidateDescriptors, isDelegatedValidateFamily, } from "./commands/validate.js";
24
24
  function emitDeprecationAlias(legacy, canonical, err) {
25
25
  err(`Deprecation: agentera ${legacy} is deprecated; use agentera ${canonical}\n`);
26
26
  }
27
+ /**
28
+ * Map a legacy parse-error string (the kind returned by `parse*Args`) to the
29
+ * canonical invalid-input envelope body. Lets the parse functions keep their
30
+ * simple `{ error: string }` shape while every surface's error path still
31
+ * funnels through `emitInvalidInput` for the frozen envelope contract.
32
+ */
33
+ function classifyParseError(raw) {
34
+ const required = /^the following arguments are required: (.+)$/.exec(raw);
35
+ if (required) {
36
+ return { class: "missing_argument", message: raw };
37
+ }
38
+ const unrecognized = /^unrecognized arguments: (.+)$/.exec(raw);
39
+ if (unrecognized) {
40
+ return { class: "unrecognized_argument", message: raw };
41
+ }
42
+ const choice = /^argument (--[\w-]+): invalid choice: '([^']+)' \(choose from (.+)\)$/.exec(raw);
43
+ if (choice) {
44
+ const validValues = [...choice[3].matchAll(/'([^']+)'/g)].map((m) => m[1]);
45
+ return {
46
+ class: "invalid_choice",
47
+ message: raw,
48
+ valid_values: validValues,
49
+ };
50
+ }
51
+ const intBad = /^argument (--[\w-]+): invalid int value: '([^']+)'$/.exec(raw);
52
+ if (intBad) {
53
+ return { class: "invalid_int", message: raw };
54
+ }
55
+ const mutex = /^argument (--[\w-]+): not allowed with argument (--[\w-]+)$/.exec(raw);
56
+ if (mutex) {
57
+ return { class: "mutually_exclusive", message: raw };
58
+ }
59
+ return { class: "unrecognized_argument", message: raw };
60
+ }
61
+ /** Coerce the loose `string` format field on parsed args to the literal union. */
62
+ function asEnvelopeFormat(format) {
63
+ return format === "json" ? "json" : "text";
64
+ }
65
+ /**
66
+ * Scan a top-level argv slice for `--format json` (or `--format=json`) so
67
+ * main() can decide whether to route its error envelope to stdout or stderr.
68
+ * Unknown format values fall through to "text" — the user will discover the
69
+ * mis-spelling when the underlying command runs.
70
+ */
71
+ function detectTopLevelFormat(args) {
72
+ for (let i = 0; i < args.length; i++) {
73
+ const a = args[i];
74
+ if (a === "--format") {
75
+ const v = args[++i];
76
+ if (v === "json" || v === "text" || v === "yaml")
77
+ return v === "json" ? "json" : "text";
78
+ }
79
+ else if (a.startsWith("--format=")) {
80
+ const v = a.slice("--format=".length);
81
+ if (v === "json" || v === "text" || v === "yaml")
82
+ return v === "json" ? "json" : "text";
83
+ }
84
+ }
85
+ return "text";
86
+ }
27
87
  /** Minimal flag parser for the `lint` command surface. */
28
88
  function parseLintArgs(argv) {
29
89
  const args = { artifact: "", file: null, text: null, strict: false, format: "text" };
@@ -69,73 +129,21 @@ function parseLintArgs(argv) {
69
129
  return args;
70
130
  }
71
131
  function runLint(argv, io, prog = "agentera lint") {
72
- const err = io.err ?? ((t) => process.stderr.write(t));
73
132
  const parsed = parseLintArgs(argv);
74
133
  if ("error" in parsed) {
75
- err(`${prog}: error: ${parsed.error}\n`);
76
- return 2;
134
+ return emitInvalidInput(io, {
135
+ format: "text",
136
+ body: classifyParseError(parsed.error),
137
+ });
77
138
  }
78
139
  try {
79
140
  return cmdLint(parsed, io);
80
141
  }
81
142
  catch (exc) {
82
- err(`Error: ${exc.message}\n`);
83
- return 2;
84
- }
85
- }
86
- function parseBackfillArgs(argv) {
87
- const args = { project: null, mode: "check", commit: null, cycle: null, format: "text" };
88
- for (let i = 0; i < argv.length; i++) {
89
- const a = argv[i];
90
- const value = (name) => {
91
- if (a === name)
92
- return argv[++i];
93
- if (a.startsWith(name + "="))
94
- return a.slice(name.length + 1);
95
- return null;
96
- };
97
- let v;
98
- if ((v = value("--project")) !== null)
99
- args.project = v;
100
- else if ((v = value("--mode")) !== null) {
101
- if (v !== "check" && v !== "fix") {
102
- return { error: `argument --mode: invalid choice: '${v}' (choose from 'check', 'fix')` };
103
- }
104
- args.mode = v;
105
- }
106
- else if ((v = value("--commit")) !== null)
107
- args.commit = v;
108
- else if ((v = value("--cycle")) !== null) {
109
- const n = Number(v);
110
- if (!Number.isInteger(n))
111
- return { error: `argument --cycle: invalid int value: '${v}'` };
112
- args.cycle = n;
113
- }
114
- else if ((v = value("--format")) !== null) {
115
- if (v !== "text" && v !== "json") {
116
- return { error: `argument --format: invalid choice: '${v}' (choose from 'text', 'json')` };
117
- }
118
- args.format = v;
119
- }
120
- else {
121
- return { error: `unrecognized arguments: ${a}` };
122
- }
123
- }
124
- return args;
125
- }
126
- function runBackfill(argv, io, prog = "agentera backfill") {
127
- const err = io.err ?? ((t) => process.stderr.write(t));
128
- const parsed = parseBackfillArgs(argv);
129
- if ("error" in parsed) {
130
- err(`${prog}: error: ${parsed.error}\n`);
131
- return 2;
132
- }
133
- try {
134
- return cmdBackfill(parsed, io);
135
- }
136
- catch (exc) {
137
- err(`Error: ${exc.message}\n`);
138
- return 2;
143
+ return emitInvalidInput(io, {
144
+ format: asEnvelopeFormat(parsed.format),
145
+ body: { class: "unsupported_target", message: exc.message },
146
+ });
139
147
  }
140
148
  }
141
149
  function parseStateArgs(command, argv) {
@@ -191,13 +199,22 @@ function parseStateArgs(command, argv) {
191
199
  return args;
192
200
  }
193
201
  function runState(command, argv, io, prog) {
194
- const err = io.err ?? ((t) => process.stderr.write(t));
195
202
  const parsed = parseStateArgs(command, argv);
196
203
  if ("error" in parsed) {
197
- err(`${prog}: error: ${parsed.error}\n`);
198
- return 2;
204
+ return emitInvalidInput(io, {
205
+ format: "text",
206
+ body: classifyParseError(parsed.error),
207
+ });
208
+ }
209
+ try {
210
+ return cmdState(parsed, io);
211
+ }
212
+ catch (exc) {
213
+ return emitInvalidInput(io, {
214
+ format: asEnvelopeFormat(parsed.format),
215
+ body: { class: "unsupported_target", message: exc.message },
216
+ });
199
217
  }
200
- return cmdState(parsed, io);
201
218
  }
202
219
  function parseQueryArgs(argv) {
203
220
  const args = {
@@ -255,22 +272,27 @@ function parseQueryArgs(argv) {
255
272
  return args;
256
273
  }
257
274
  function runQuery(argv, io, prog) {
258
- const err = io.err ?? ((t) => process.stderr.write(t));
259
275
  const parsed = parseQueryArgs(argv);
260
276
  if ("error" in parsed) {
261
- err(`${prog}: error: ${parsed.error}\n`);
262
- return 2;
277
+ return emitInvalidInput(io, {
278
+ format: "text",
279
+ body: classifyParseError(parsed.error),
280
+ });
263
281
  }
264
282
  try {
265
283
  return cmdQuery(parsed, io);
266
284
  }
267
285
  catch (exc) {
268
- err(`Error: ${exc.message}\n`);
269
- return 2;
286
+ return emitInvalidInput(io, {
287
+ format: asEnvelopeFormat(parsed.format),
288
+ body: { class: "unsupported_target", message: exc.message },
289
+ });
270
290
  }
271
291
  }
272
292
  function compactModeOf(argv) {
273
293
  for (let i = 0; i < argv.length; i++) {
294
+ if (argv[i] === "--apply")
295
+ return "fix";
274
296
  if (argv[i] === "--mode")
275
297
  return argv[i + 1] ?? "check";
276
298
  if (argv[i].startsWith("--mode="))
@@ -290,7 +312,10 @@ function parseCompactArgs(argv) {
290
312
  return null;
291
313
  };
292
314
  let v;
293
- if ((v = value("--project")) !== null)
315
+ if (a === "--apply") {
316
+ args.mode = "fix";
317
+ }
318
+ else if ((v = value("--project")) !== null)
294
319
  args.project = v;
295
320
  else if ((v = value("--mode")) !== null) {
296
321
  if (v !== "check" && v !== "fix") {
@@ -310,22 +335,24 @@ function parseCompactArgs(argv) {
310
335
  return args;
311
336
  }
312
337
  function runCompact(argv, io, prog) {
313
- const err = io.err ?? ((t) => process.stderr.write(t));
314
338
  const parsed = parseCompactArgs(argv);
315
339
  if ("error" in parsed) {
316
- err(`${prog}: error: ${parsed.error}\n`);
317
- return 2;
340
+ return emitInvalidInput(io, {
341
+ format: "text",
342
+ body: classifyParseError(parsed.error),
343
+ });
318
344
  }
319
345
  try {
320
346
  return cmdCompact(parsed, io);
321
347
  }
322
348
  catch (exc) {
323
- err(`Error: ${exc.message}\n`);
324
- return 2;
349
+ return emitInvalidInput(io, {
350
+ format: asEnvelopeFormat(parsed.format),
351
+ body: { class: "unsupported_target", message: exc.message },
352
+ });
325
353
  }
326
354
  }
327
355
  function runValidate(argv, io, prog) {
328
- const err = io.err ?? ((t) => process.stderr.write(t));
329
356
  let family = null;
330
357
  let capabilityTarget = null;
331
358
  let artifactFlag = null;
@@ -337,16 +364,28 @@ function runValidate(argv, io, prog) {
337
364
  if (a === "--format") {
338
365
  const v = argv[++i];
339
366
  if (v !== "text" && v !== "json") {
340
- err(`${prog}: error: argument --format: invalid choice: '${v}' (choose from 'text', 'json')\n`);
341
- return 2;
367
+ return emitInvalidInput(io, {
368
+ format,
369
+ body: {
370
+ class: "invalid_choice",
371
+ message: `argument --format: invalid choice: '${v}' (choose from 'text', 'json')`,
372
+ valid_values: ["text", "json"],
373
+ },
374
+ });
342
375
  }
343
376
  format = v;
344
377
  }
345
378
  else if (a.startsWith("--format=")) {
346
379
  const v = a.slice("--format=".length);
347
380
  if (v !== "text" && v !== "json") {
348
- err(`${prog}: error: argument --format: invalid choice: '${v}' (choose from 'text', 'json')\n`);
349
- return 2;
381
+ return emitInvalidInput(io, {
382
+ format,
383
+ body: {
384
+ class: "invalid_choice",
385
+ message: `argument --format: invalid choice: '${v}' (choose from 'text', 'json')`,
386
+ valid_values: ["text", "json"],
387
+ },
388
+ });
350
389
  }
351
390
  format = v;
352
391
  }
@@ -360,8 +399,13 @@ function runValidate(argv, io, prog) {
360
399
  cwdFlag = a === "--cwd" ? argv[++i] : a.slice("--cwd=".length);
361
400
  }
362
401
  else if (a.startsWith("--")) {
363
- err(`${prog}: error: unrecognized arguments: ${a}\n`);
364
- return 2;
402
+ return emitInvalidInput(io, {
403
+ format,
404
+ body: {
405
+ class: "unrecognized_argument",
406
+ message: `unrecognized arguments: ${a}`,
407
+ },
408
+ });
365
409
  }
366
410
  else if (family === null) {
367
411
  family = a;
@@ -370,19 +414,45 @@ function runValidate(argv, io, prog) {
370
414
  capabilityTarget = a;
371
415
  }
372
416
  else {
373
- err(`${prog}: error: unrecognized arguments: ${a}\n`);
374
- return 2;
417
+ return emitInvalidInput(io, {
418
+ format,
419
+ body: {
420
+ class: "unrecognized_argument",
421
+ message: `unrecognized arguments: ${a}`,
422
+ },
423
+ });
375
424
  }
376
425
  }
377
426
  if (family === null) {
378
- err(`${prog}: error: the following arguments are required: validate_family\n`);
379
- return 2;
427
+ return emitInvalidInput(io, {
428
+ format,
429
+ body: {
430
+ class: "missing_argument",
431
+ message: "the following arguments are required: validate_family",
432
+ valid_values: [
433
+ "cross-capability",
434
+ "lifecycle-adapters",
435
+ "app-home-contract",
436
+ "capability",
437
+ "capability-contract",
438
+ "descriptors",
439
+ "artifact",
440
+ ],
441
+ example: "agentera check validate cross-capability",
442
+ },
443
+ });
380
444
  }
381
445
  try {
382
446
  if (family === "capability") {
383
447
  if (capabilityTarget === null) {
384
- err(`${prog} capability: error: the following arguments are required: target\n`);
385
- return 2;
448
+ return emitInvalidInput(io, {
449
+ format,
450
+ body: {
451
+ class: "missing_argument",
452
+ message: "the following arguments are required: target",
453
+ example: "agentera check validate capability planera",
454
+ },
455
+ });
386
456
  }
387
457
  return cmdValidateCapability(capabilityTarget, { format }, io);
388
458
  }
@@ -394,24 +464,48 @@ function runValidate(argv, io, prog) {
394
464
  }
395
465
  if (family === "artifact") {
396
466
  if (artifactFlag === null) {
397
- err(`${prog} artifact: error: the following arguments are required: --artifact\n`);
398
- return 2;
467
+ return emitInvalidInput(io, {
468
+ format,
469
+ body: {
470
+ class: "missing_argument",
471
+ message: "the following arguments are required: --artifact",
472
+ example: "agentera check validate artifact --artifact PLAN.md",
473
+ },
474
+ });
399
475
  }
400
476
  return cmdValidateArtifact({ artifact: artifactFlag, file: fileFlag, cwd: cwdFlag, format }, io);
401
477
  }
402
478
  if (isDelegatedValidateFamily(family)) {
403
479
  return cmdValidate(family, { format }, io);
404
480
  }
405
- err(`agentera: validate family not yet ported: ${family}\n`);
406
- return 1;
481
+ return emitInvalidInput(io, {
482
+ format,
483
+ body: {
484
+ class: "unsupported_target",
485
+ message: `validate family not yet ported: ${family}`,
486
+ valid_values: [
487
+ "cross-capability",
488
+ "lifecycle-adapters",
489
+ "app-home-contract",
490
+ "capability",
491
+ "capability-contract",
492
+ "descriptors",
493
+ "artifact",
494
+ ],
495
+ },
496
+ });
407
497
  }
408
498
  catch (exc) {
409
- err(`Error: ${exc.message}\n`);
410
- return 2;
499
+ return emitInvalidInput(io, {
500
+ format,
501
+ body: {
502
+ class: "unsupported_target",
503
+ message: exc.message,
504
+ },
505
+ });
411
506
  }
412
507
  }
413
508
  function runSchema(argv, io, prog) {
414
- const err = io.err ?? ((t) => process.stderr.write(t));
415
509
  let format = "json";
416
510
  for (let i = 0; i < argv.length; i++) {
417
511
  const a = argv[i];
@@ -421,12 +515,20 @@ function runSchema(argv, io, prog) {
421
515
  else if (a.startsWith("--format="))
422
516
  v = a.slice("--format=".length);
423
517
  else {
424
- err(`${prog}: error: unrecognized arguments: ${a}\n`);
425
- return 2;
518
+ return emitInvalidInput(io, {
519
+ format: asEnvelopeFormat(format),
520
+ body: { class: "unrecognized_argument", message: `unrecognized arguments: ${a}` },
521
+ });
426
522
  }
427
523
  if (v !== "json" && v !== "yaml") {
428
- err(`${prog}: error: argument --format: invalid choice: '${v}' (choose from 'json', 'yaml')\n`);
429
- return 2;
524
+ return emitInvalidInput(io, {
525
+ format: asEnvelopeFormat(format),
526
+ body: {
527
+ class: "invalid_choice",
528
+ message: `argument --format: invalid choice: '${v}' (choose from 'json', 'yaml')`,
529
+ valid_values: ["json", "yaml"],
530
+ },
531
+ });
430
532
  }
431
533
  format = v;
432
534
  }
@@ -434,12 +536,13 @@ function runSchema(argv, io, prog) {
434
536
  return cmdSchema({ format }, io);
435
537
  }
436
538
  catch (exc) {
437
- err(`Error: ${exc.message}\n`);
438
- return 2;
539
+ return emitInvalidInput(io, {
540
+ format: asEnvelopeFormat(format),
541
+ body: { class: "unsupported_target", message: exc.message },
542
+ });
439
543
  }
440
544
  }
441
545
  function runCapability(command, argv, io, prog) {
442
- const err = io.err ?? ((t) => process.stderr.write(t));
443
546
  let format = "text";
444
547
  for (let i = 0; i < argv.length; i++) {
445
548
  const a = argv[i];
@@ -455,19 +558,34 @@ function runCapability(command, argv, io, prog) {
455
558
  continue;
456
559
  }
457
560
  else {
458
- err(`${prog}: error: unrecognized arguments: ${a}\n`);
459
- return 2;
561
+ return emitInvalidInput(io, {
562
+ format: asEnvelopeFormat(format),
563
+ body: { class: "unrecognized_argument", message: `unrecognized arguments: ${a}` },
564
+ });
460
565
  }
461
566
  if (v !== "text" && v !== "json" && v !== "yaml") {
462
- err(`${prog}: error: argument --format: invalid choice: '${v}' (choose from 'text', 'json', 'yaml')\n`);
463
- return 2;
567
+ return emitInvalidInput(io, {
568
+ format: asEnvelopeFormat(format),
569
+ body: {
570
+ class: "invalid_choice",
571
+ message: `argument --format: invalid choice: '${v}' (choose from 'text', 'json', 'yaml')`,
572
+ valid_values: ["text", "json", "yaml"],
573
+ },
574
+ });
464
575
  }
465
576
  format = v;
466
577
  }
467
- return cmdCapability(command, { format }, io);
578
+ try {
579
+ return cmdCapability(command, { format }, io);
580
+ }
581
+ catch (exc) {
582
+ return emitInvalidInput(io, {
583
+ format: asEnvelopeFormat(format),
584
+ body: { class: "unsupported_target", message: exc.message },
585
+ });
586
+ }
468
587
  }
469
588
  function runPrime(command, argv, io, prog) {
470
- const err = io.err ?? ((t) => process.stderr.write(t));
471
589
  const args = { command, guidance: false, context: null, dashboard: false, orientation: false, format: "text" };
472
590
  for (let i = 0; i < argv.length; i++) {
473
591
  const a = argv[i];
@@ -485,8 +603,14 @@ function runPrime(command, argv, io, prog) {
485
603
  else if (a === "--format" || a.startsWith("--format=")) {
486
604
  v = a === "--format" ? argv[++i] : a.slice("--format=".length);
487
605
  if (v !== "text" && v !== "json" && v !== "yaml") {
488
- err(`${prog}: error: argument --format: invalid choice: '${v}' (choose from 'text', 'json', 'yaml')\n`);
489
- return 2;
606
+ return emitInvalidInput(io, {
607
+ format: asEnvelopeFormat(args.format),
608
+ body: {
609
+ class: "invalid_choice",
610
+ message: `argument --format: invalid choice: '${v}' (choose from 'text', 'json', 'yaml')`,
611
+ valid_values: ["text", "json", "yaml"],
612
+ },
613
+ });
490
614
  }
491
615
  args.format = v;
492
616
  }
@@ -497,25 +621,38 @@ function runPrime(command, argv, io, prog) {
497
621
  args.fields = a.slice("--fields=".length);
498
622
  }
499
623
  else {
500
- err(`${prog}: error: unrecognized arguments: ${a}\n`);
501
- return 2;
624
+ return emitInvalidInput(io, {
625
+ format: asEnvelopeFormat(args.format),
626
+ body: { class: "unrecognized_argument", message: `unrecognized arguments: ${a}` },
627
+ });
502
628
  }
503
629
  }
504
- return cmdPrime(args, io);
630
+ try {
631
+ return cmdPrime(args, io);
632
+ }
633
+ catch (exc) {
634
+ return emitInvalidInput(io, {
635
+ format: asEnvelopeFormat(args.format),
636
+ body: { class: "unsupported_target", message: exc.message },
637
+ });
638
+ }
505
639
  }
506
640
  function runGate(argv, io, prog) {
507
- const err = io.err ?? ((t) => process.stderr.write(t));
508
641
  const parsed = parseCompactArgs(argv);
509
642
  if ("error" in parsed) {
510
- err(`${prog}: error: ${parsed.error}\n`);
511
- return 2;
643
+ return emitInvalidInput(io, {
644
+ format: "text",
645
+ body: classifyParseError(parsed.error),
646
+ });
512
647
  }
513
648
  try {
514
649
  return cmdGate(parsed, io);
515
650
  }
516
651
  catch (exc) {
517
- err(`Error: ${exc.message}\n`);
518
- return 2;
652
+ return emitInvalidInput(io, {
653
+ format: asEnvelopeFormat(parsed.format),
654
+ body: { class: "unsupported_target", message: exc.message },
655
+ });
519
656
  }
520
657
  }
521
658
  function runDoctor(argv, io, prog) {
@@ -558,8 +695,14 @@ function runDoctor(argv, io, prog) {
558
695
  args.expectCommand.push(v);
559
696
  else if ((v = value("--format")) !== null) {
560
697
  if (v !== "text" && v !== "json") {
561
- err(`${prog}: error: argument --format: invalid choice: '${v}' (choose from 'text', 'json')\n`);
562
- return 2;
698
+ return emitInvalidInput(io, {
699
+ format: asEnvelopeFormat(args.format),
700
+ body: {
701
+ class: "invalid_choice",
702
+ message: `argument --format: invalid choice: '${v}' (choose from 'text', 'json')`,
703
+ valid_values: ["text", "json"],
704
+ },
705
+ });
563
706
  }
564
707
  args.format = v;
565
708
  }
@@ -570,15 +713,25 @@ function runDoctor(argv, io, prog) {
570
713
  else if (a === "--allow-live-model")
571
714
  args.allowLiveModel = true;
572
715
  else {
573
- err(`${prog}: error: unrecognized arguments: ${a}\n`);
574
- return 2;
716
+ return emitInvalidInput(io, {
717
+ format: asEnvelopeFormat(args.format),
718
+ body: { class: "unrecognized_argument", message: `unrecognized arguments: ${a}` },
719
+ });
575
720
  }
576
721
  }
577
722
  if (jsonFlag) {
578
723
  emitDeprecationAlias("doctor --json", "doctor --format json", err);
579
724
  args.format = "json";
580
725
  }
581
- return cmdDoctor(args, io);
726
+ try {
727
+ return cmdDoctor(args, io);
728
+ }
729
+ catch (exc) {
730
+ return emitInvalidInput(io, {
731
+ format: asEnvelopeFormat(args.format),
732
+ body: { class: "unsupported_target", message: exc.message },
733
+ });
734
+ }
582
735
  }
583
736
  function readStdin() {
584
737
  try {
@@ -608,8 +761,20 @@ function runHook(name, argv, io) {
608
761
  return rc;
609
762
  }
610
763
  default:
611
- err(`agentera hook: unknown hook '${name}'\n`);
612
- return 2;
764
+ return emitInvalidInput(io, {
765
+ format: "text",
766
+ body: {
767
+ class: "unsupported_target",
768
+ message: `unknown hook '${name}'`,
769
+ valid_values: [
770
+ "session-start",
771
+ "session-stop",
772
+ "cursor-session-start",
773
+ "cursor-pre-tool-use",
774
+ "validate-artifact",
775
+ ],
776
+ },
777
+ });
613
778
  }
614
779
  }
615
780
  function runUsage(argv, io, prog) {
@@ -635,8 +800,10 @@ function runUsage(argv, io, prog) {
635
800
  else if ((v = value("--project")) !== null)
636
801
  project = v;
637
802
  else {
638
- realErr(`${prog}: error: unrecognized arguments: ${a}\n`);
639
- return 2;
803
+ return emitInvalidInput(io, {
804
+ format: asEnvelopeFormat(format),
805
+ body: { class: "unrecognized_argument", message: `unrecognized arguments: ${a}` },
806
+ });
640
807
  }
641
808
  }
642
809
  if (corpus !== null) {
@@ -644,16 +811,26 @@ function runUsage(argv, io, prog) {
644
811
  validatePathValue(corpus, "path");
645
812
  }
646
813
  catch (e) {
647
- realErr(`${prog}: error: argument --corpus: ${e.message}\n`);
648
- return 2;
814
+ return emitInvalidInput(io, {
815
+ format: asEnvelopeFormat(format),
816
+ body: {
817
+ class: "invalid_format",
818
+ message: `argument --corpus: ${e.message}`,
819
+ },
820
+ });
649
821
  }
650
822
  }
651
823
  if (format !== "text" && format !== "json") {
652
- const syntax = "agentera usage [--format text|json] [--corpus PATH] [--project VALUE]";
653
- const example = "agentera usage --format json --project agentera";
654
- realErr(`Error: unsupported usage format '${format}'; valid formats: text, json. ` +
655
- `Syntax: ${syntax}. Example: ${example}\n`);
656
- return 2;
824
+ return emitInvalidInput(io, {
825
+ format: asEnvelopeFormat(format),
826
+ body: {
827
+ class: "invalid_choice",
828
+ message: `unsupported usage format '${format}'; valid formats: text, json.`,
829
+ valid_values: ["text", "json"],
830
+ syntax: "agentera usage [--format text|json] [--corpus PATH] [--project VALUE]",
831
+ example: "agentera usage --format json --project agentera",
832
+ },
833
+ });
657
834
  }
658
835
  const engineArgv = [];
659
836
  if (corpus !== null)
@@ -709,15 +886,26 @@ function runUpgrade(argv, io, prog) {
709
886
  args.channel = v;
710
887
  else if ((v = value("--target-major")) !== null) {
711
888
  void v;
712
- err(`${prog}: error: --target-major was removed; use --channel with dry-run preview then --yes\n`);
713
- return 2;
889
+ return emitInvalidInput(io, {
890
+ format: asEnvelopeFormat(args.format),
891
+ body: {
892
+ class: "unsupported_target",
893
+ message: "--target-major was removed; use --channel with dry-run preview then --yes",
894
+ },
895
+ });
714
896
  }
715
897
  else if ((v = value("--runtime")) !== null)
716
898
  void v; // accepted; orchestrator uses fixture runtimes
717
899
  else if ((v = value("--only")) !== null) {
718
900
  if (v !== "artifacts" && v !== "runtime" && v !== "cleanup") {
719
- err(`${prog}: error: argument --only: invalid choice: '${v}' (choose from 'artifacts', 'runtime', 'cleanup')\n`);
720
- return 2;
901
+ return emitInvalidInput(io, {
902
+ format: asEnvelopeFormat(args.format),
903
+ body: {
904
+ class: "invalid_choice",
905
+ message: `argument --only: invalid choice: '${v}' (choose from 'artifacts', 'runtime', 'cleanup')`,
906
+ valid_values: ["artifacts", "runtime", "cleanup"],
907
+ },
908
+ });
721
909
  }
722
910
  args.only.push(v);
723
911
  }
@@ -735,22 +923,37 @@ function runUpgrade(argv, io, prog) {
735
923
  jsonFlag = true;
736
924
  else if ((v = value("--format")) !== null) {
737
925
  if (v !== "text" && v !== "json") {
738
- err(`${prog}: error: argument --format: invalid choice: '${v}' (choose from 'text', 'json')\n`);
739
- return 2;
926
+ return emitInvalidInput(io, {
927
+ format: asEnvelopeFormat(args.format),
928
+ body: {
929
+ class: "invalid_choice",
930
+ message: `argument --format: invalid choice: '${v}' (choose from 'text', 'json')`,
931
+ valid_values: ["text", "json"],
932
+ },
933
+ });
740
934
  }
741
935
  args.format = v;
742
936
  }
743
937
  else {
744
- err(`${prog}: error: unrecognized arguments: ${a}\n`);
745
- return 2;
938
+ return emitInvalidInput(io, {
939
+ format: asEnvelopeFormat(args.format),
940
+ body: { class: "unrecognized_argument", message: `unrecognized arguments: ${a}` },
941
+ });
746
942
  }
747
943
  }
748
944
  if (jsonFlag)
749
945
  args.format = "json";
750
- return cmdUpgrade(args, io);
946
+ try {
947
+ return cmdUpgrade(args, io);
948
+ }
949
+ catch (exc) {
950
+ return emitInvalidInput(io, {
951
+ format: asEnvelopeFormat(args.format),
952
+ body: { class: "unsupported_target", message: exc.message },
953
+ });
954
+ }
751
955
  }
752
956
  function runVerify(argv, io, prog) {
753
- const err = io.err ?? ((t) => process.stderr.write(t));
754
957
  const args = {
755
958
  family: null,
756
959
  target: null,
@@ -776,8 +979,14 @@ function runVerify(argv, io, prog) {
776
979
  let v;
777
980
  if ((v = value("--format")) !== null) {
778
981
  if (v !== "text" && v !== "json") {
779
- err(`${prog}: error: argument --format: invalid choice: '${v}' (choose from 'text', 'json')\n`);
780
- return 2;
982
+ return emitInvalidInput(io, {
983
+ format: asEnvelopeFormat(args.format),
984
+ body: {
985
+ class: "invalid_choice",
986
+ message: `argument --format: invalid choice: '${v}' (choose from 'text', 'json')`,
987
+ valid_values: ["text", "json"],
988
+ },
989
+ });
781
990
  }
782
991
  args.format = v;
783
992
  }
@@ -794,8 +1003,10 @@ function runVerify(argv, io, prog) {
794
1003
  else if (a === "--dry-run")
795
1004
  args.dryRun = true;
796
1005
  else if (a.startsWith("--")) {
797
- err(`${prog}: error: unrecognized arguments: ${a}\n`);
798
- return 2;
1006
+ return emitInvalidInput(io, {
1007
+ format: asEnvelopeFormat(args.format),
1008
+ body: { class: "unrecognized_argument", message: `unrecognized arguments: ${a}` },
1009
+ });
799
1010
  }
800
1011
  else {
801
1012
  positionals.push(a);
@@ -804,10 +1015,17 @@ function runVerify(argv, io, prog) {
804
1015
  args.family = positionals[0] ?? null;
805
1016
  args.target = positionals[1] ?? null;
806
1017
  args.fixtures = positionals.slice(2);
807
- return cmdVerify(args, io);
1018
+ try {
1019
+ return cmdVerify(args, io);
1020
+ }
1021
+ catch (exc) {
1022
+ return emitInvalidInput(io, {
1023
+ format: asEnvelopeFormat(args.format),
1024
+ body: { class: "unsupported_target", message: exc.message },
1025
+ });
1026
+ }
808
1027
  }
809
1028
  function runReport(argv, io, prog) {
810
- const err = io.err ?? ((t) => process.stderr.write(t));
811
1029
  const args = {
812
1030
  action: null,
813
1031
  format: "text",
@@ -833,8 +1051,14 @@ function runReport(argv, io, prog) {
833
1051
  args.project = v;
834
1052
  else if ((v = value("--consent")) !== null) {
835
1053
  if (v !== "local-history") {
836
- err(`${prog}: error: argument --consent: invalid choice: '${v}' (choose from 'local-history')\n`);
837
- return 2;
1054
+ return emitInvalidInput(io, {
1055
+ format: asEnvelopeFormat(args.format),
1056
+ body: {
1057
+ class: "invalid_choice",
1058
+ message: `argument --consent: invalid choice: '${v}' (choose from 'local-history')`,
1059
+ valid_values: ["local-history"],
1060
+ },
1061
+ });
838
1062
  }
839
1063
  args.consent = v;
840
1064
  }
@@ -867,15 +1091,25 @@ function runReport(argv, io, prog) {
867
1091
  else if (a === "--dry-run")
868
1092
  args.dryRun = true;
869
1093
  else if (a.startsWith("--")) {
870
- err(`${prog}: error: unrecognized arguments: ${a}\n`);
871
- return 2;
1094
+ return emitInvalidInput(io, {
1095
+ format: asEnvelopeFormat(args.format),
1096
+ body: { class: "unrecognized_argument", message: `unrecognized arguments: ${a}` },
1097
+ });
872
1098
  }
873
1099
  else {
874
1100
  positionals.push(a);
875
1101
  }
876
1102
  }
877
1103
  args.action = positionals[0] ?? null;
878
- return cmdReport(args, io);
1104
+ try {
1105
+ return cmdReport(args, io);
1106
+ }
1107
+ catch (exc) {
1108
+ return emitInvalidInput(io, {
1109
+ format: asEnvelopeFormat(args.format),
1110
+ body: { class: "unsupported_target", message: exc.message },
1111
+ });
1112
+ }
879
1113
  }
880
1114
  export function main(argv, io = {}) {
881
1115
  const err = io.err ?? ((t) => process.stderr.write(t));
@@ -893,8 +1127,13 @@ export function main(argv, io = {}) {
893
1127
  out(text + "\n");
894
1128
  return 0;
895
1129
  }
896
- err(`agentera: unknown or not-yet-ported command: ${command}\n`);
897
- return 1;
1130
+ return emitInvalidInput(io, {
1131
+ format: "text",
1132
+ body: {
1133
+ class: "unsupported_target",
1134
+ message: `unknown or not-yet-ported command: ${command}`,
1135
+ },
1136
+ });
898
1137
  }
899
1138
  switch (command) {
900
1139
  case "prime":
@@ -916,8 +1155,20 @@ export function main(argv, io = {}) {
916
1155
  case "hook": {
917
1156
  const name = rest[0];
918
1157
  if (!name) {
919
- err("agentera hook: error: the following arguments are required: hook_name\n");
920
- return 2;
1158
+ return emitInvalidInput(io, {
1159
+ format: "text",
1160
+ body: {
1161
+ class: "missing_argument",
1162
+ message: "the following arguments are required: hook_name",
1163
+ valid_values: [
1164
+ "session-start",
1165
+ "session-stop",
1166
+ "cursor-session-start",
1167
+ "cursor-pre-tool-use",
1168
+ "validate-artifact",
1169
+ ],
1170
+ },
1171
+ });
921
1172
  }
922
1173
  return runHook(name, rest.slice(1), io);
923
1174
  }
@@ -935,8 +1186,14 @@ export function main(argv, io = {}) {
935
1186
  case "check": {
936
1187
  const sub = rest[0];
937
1188
  if (!sub) {
938
- err("agentera check: error: the following arguments are required: check_command\n");
939
- return 2;
1189
+ return emitInvalidInput(io, {
1190
+ format: "text",
1191
+ body: {
1192
+ class: "missing_argument",
1193
+ message: "the following arguments are required: check_command",
1194
+ valid_values: ["validate", "verify", "lint", "compact"],
1195
+ },
1196
+ });
940
1197
  }
941
1198
  if (sub === "validate")
942
1199
  return runValidate(rest.slice(1), io, "agentera check validate");
@@ -944,8 +1201,6 @@ export function main(argv, io = {}) {
944
1201
  return runVerify(rest.slice(1), io, "agentera check verify");
945
1202
  if (sub === "lint")
946
1203
  return runLint(rest.slice(1), io, "agentera check lint");
947
- if (sub === "backfill")
948
- return runBackfill(rest.slice(1), io, "agentera check backfill");
949
1204
  if (sub === "compact") {
950
1205
  const subArgs = rest.slice(1);
951
1206
  const mode = compactModeOf(subArgs);
@@ -953,21 +1208,59 @@ export function main(argv, io = {}) {
953
1208
  return runCompact(subArgs, io, "agentera check compact");
954
1209
  return runGate(subArgs, io, "agentera check compact");
955
1210
  }
956
- err(`agentera: unknown or not-yet-ported check subcommand: ${sub}\n`);
957
- return 1;
1211
+ return emitInvalidInput(io, {
1212
+ format: "text",
1213
+ body: {
1214
+ class: "unsupported_target",
1215
+ message: `unknown or not-yet-ported check subcommand: ${sub}`,
1216
+ valid_values: ["validate", "verify", "lint", "compact"],
1217
+ },
1218
+ });
958
1219
  }
959
1220
  case "state": {
960
1221
  const sub = rest[0];
961
1222
  if (!sub) {
962
- err("agentera state: error: the following arguments are required: state_command\n");
963
- return 2;
1223
+ return emitInvalidInput(io, {
1224
+ format: "text",
1225
+ body: {
1226
+ class: "missing_argument",
1227
+ message: "the following arguments are required: state_command",
1228
+ valid_values: [
1229
+ "progress",
1230
+ "plan",
1231
+ "health",
1232
+ "docs",
1233
+ "objective",
1234
+ "experiments",
1235
+ "todo",
1236
+ "decisions",
1237
+ "query",
1238
+ ],
1239
+ },
1240
+ });
964
1241
  }
965
1242
  if (sub === "query")
966
1243
  return runQuery(rest.slice(1), io, "agentera state query");
967
1244
  if (isPortedStateCommand(sub))
968
1245
  return runState(sub, rest.slice(1), io, `agentera state ${sub}`);
969
- err(`agentera: unknown or not-yet-ported state subcommand: ${sub}\n`);
970
- return 1;
1246
+ return emitInvalidInput(io, {
1247
+ format: "text",
1248
+ body: {
1249
+ class: "unsupported_target",
1250
+ message: `unknown or not-yet-ported state subcommand: ${sub}`,
1251
+ valid_values: [
1252
+ "progress",
1253
+ "plan",
1254
+ "health",
1255
+ "docs",
1256
+ "objective",
1257
+ "experiments",
1258
+ "todo",
1259
+ "decisions",
1260
+ "query",
1261
+ ],
1262
+ },
1263
+ });
971
1264
  }
972
1265
  case "query":
973
1266
  emitDeprecationAlias("query", "state query", err);
@@ -989,8 +1282,13 @@ export function main(argv, io = {}) {
989
1282
  emitDeprecationAlias(command, `state ${command}`, err);
990
1283
  return runState(command, rest, io, `agentera ${command}`);
991
1284
  }
992
- err(`agentera: unknown or not-yet-ported command: ${command ?? "(none)"}\n`);
993
- return 1;
1285
+ return emitInvalidInput(io, {
1286
+ format: "text",
1287
+ body: {
1288
+ class: "unsupported_target",
1289
+ message: `unknown or not-yet-ported command: ${command ?? "(none)"}`,
1290
+ },
1291
+ });
994
1292
  }
995
1293
  }
996
1294
  //# sourceMappingURL=dispatch.js.map