@sverka/arena 0.2.25 → 0.2.27

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/dist/bin.d.mts CHANGED
@@ -1,7 +1,8 @@
1
1
  //#region src/bin.d.ts
2
2
  /**
3
3
  * sverka-arena — CLI for the agent arena: run the benchmark matrix, render
4
- * saved results, check the environment. Spec: specs/49-arena-cli.
4
+ * saved results, check the environment, publish to the results registry
5
+ * and render the leaderboard. Specs: 49-arena-cli, 56-arena-eval-service.
5
6
  */
6
7
  interface Io {
7
8
  out(s: string): void;
@@ -15,6 +16,27 @@ export declare function filterTasks<T extends {
15
16
  } | {
16
17
  missing: string[];
17
18
  };
19
+ /**
20
+ * Strip embedded credentials (scheme://user:pass@host) before a registry
21
+ * ref is printed to stderr — CI logs retain that output. Exported for
22
+ * tests.
23
+ */
24
+ export declare function redactRegistryRef(ref: string): string;
25
+ /**
26
+ * The `sverka-arena publish` retry hint printed when `run --publish`
27
+ * fails — args are shell-quoted so the line survives a copy-paste. A
28
+ * --registry ref carrying embedded credentials is never echoed (even
29
+ * redacted it is unusable); the user re-supplies it via ARENA_REGISTRY.
30
+ * Exported for tests.
31
+ */
32
+ export declare function publishRetryHint(opts: {
33
+ saved: string;
34
+ pack: string;
35
+ agent: string;
36
+ sverkaVersion: string;
37
+ config?: string;
38
+ registry?: string;
39
+ }): string;
18
40
  /** Entry point — exported for tests; bin calls it with process.argv. */
19
41
  export declare function main(argv: readonly string[], io?: Io): Promise<number>;
20
42
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"bin.d.mts","names":[],"sources":["../src/bin.ts"],"mappings":";;;;;UAiBU;EACR,IAAI;EACJ,IAAI;;;wBA6HU,YAAY;EAAY;GACtC,OAAO,KACP;EACG,OAAO;;EAAU;;;wBA6FA,KACpB,yBACA,KAAI,KACH"}
1
+ {"version":3,"file":"bin.d.mts","names":[],"sources":["../src/bin.ts"],"mappings":";;;;;;UA0BU;EACR,IAAI;EACJ,IAAI;;;wBA2MU,YAAY;EAAY;GACtC,OAAO,KACP;EACG,OAAO;;EAAU;;;;;;;wBAoCN,kBAAkB;;;;;;;;wBAgBlB,iBAAiB;EAC/B;EACA;EACA;EACA;EACA;EACA;;;wBAkUoB,KACpB,yBACA,KAAI,KACH"}
package/dist/bin.mjs CHANGED
@@ -1,20 +1,33 @@
1
1
  #!/usr/bin/env node
2
- import { a as renderReport, c as loadArenaConfig, i as writeAggregateReport, o as ArenaError, p as runArena } from "./aggregate-report-BkLMmG16.mjs";
2
+ import { D as writeAggregateReport, I as runArena, M as resolveAdapter, O as renderReport, _ as openRegistry, a as buildBoard, d as publishFile, f as publishResult, i as resolvePack, j as loadArenaConfig, k as ArenaError, n as lintPack, o as renderBoard, s as renderBoardHtml, t as initPack, x as reindexRegistry } from "./pack-DoL1QL1y.mjs";
3
3
  import { readFile } from "node:fs/promises";
4
- import { existsSync } from "node:fs";
4
+ import { existsSync, readFileSync, writeFileSync } from "node:fs";
5
5
  import { delimiter, join, resolve } from "node:path";
6
6
  import process from "node:process";
7
7
  //#region src/bin.ts
8
8
  /**
9
9
  * sverka-arena — CLI for the agent arena: run the benchmark matrix, render
10
- * saved results, check the environment. Spec: specs/49-arena-cli.
10
+ * saved results, check the environment, publish to the results registry
11
+ * and render the leaderboard. Specs: 49-arena-cli, 56-arena-eval-service.
11
12
  */
12
13
  const USAGE = `usage: sverka-arena <command> [options]
13
14
 
14
15
  commands:
15
16
  run [--config <path>] [--out <dir>] [--format json|text] [--task <id>]...
17
+ [--pack <ref>] [--publish --registry <ref>]
16
18
  report <results.json> [--format json|text|html] [--out <file.html>]
17
19
  doctor [--config <path>] [--format json|text]
20
+ publish <results.json> --pack <name> --registry <ref>
21
+ [--config <path>] [--agent <id>] [--sverka-version <v>] [--trace <file>]...
22
+ [--format json|text]
23
+ board --registry <ref> [--pack <name>] [--agent <id>] [--since <date>]
24
+ [--format json|text|html] [--out <file.html>]
25
+ pack init <name> [--dir <parent>] | lint <dir> [--format json|text]
26
+ reindex --registry <ref> [--format json|text]
27
+
28
+ registry refs: <dir> | file://<dir> | <git-url> | git::<url> | s3://<bucket>/<prefix>
29
+ pack refs: <dir> | <git-url> | <name> (packs/<name>/ inside --registry)
30
+ env: ARENA_REGISTRY (registry ref), ARENA_REGISTRY_TOKEN (https bearer)
18
31
  `;
19
32
  function flagValue(argv, i) {
20
33
  const val = argv[i + 1];
@@ -28,15 +41,25 @@ function parseFormat(val) {
28
41
  function parseArgs(argv) {
29
42
  const positional = [];
30
43
  let config = "arena.config.ts";
44
+ let configSet = false;
31
45
  let out;
32
46
  let format = "text";
33
47
  let command;
34
48
  const tasks = [];
49
+ const traces = [];
50
+ let pack;
51
+ let registry;
52
+ let agent;
53
+ let sverkaVersion;
54
+ let since;
55
+ let dir;
56
+ let publish = false;
35
57
  for (let i = 0; i < argv.length; i++) {
36
58
  const arg = argv[i];
37
59
  switch (arg) {
38
60
  case "--config":
39
61
  config = flagValue(argv, i);
62
+ configSet = true;
40
63
  i += 1;
41
64
  break;
42
65
  case "--out":
@@ -51,6 +74,37 @@ function parseArgs(argv) {
51
74
  tasks.push(flagValue(argv, i));
52
75
  i += 1;
53
76
  break;
77
+ case "--pack":
78
+ pack = flagValue(argv, i);
79
+ i += 1;
80
+ break;
81
+ case "--registry":
82
+ registry = flagValue(argv, i);
83
+ i += 1;
84
+ break;
85
+ case "--agent":
86
+ agent = flagValue(argv, i);
87
+ i += 1;
88
+ break;
89
+ case "--sverka-version":
90
+ sverkaVersion = flagValue(argv, i);
91
+ i += 1;
92
+ break;
93
+ case "--since":
94
+ since = flagValue(argv, i);
95
+ i += 1;
96
+ break;
97
+ case "--dir":
98
+ dir = flagValue(argv, i);
99
+ i += 1;
100
+ break;
101
+ case "--trace":
102
+ traces.push(flagValue(argv, i));
103
+ i += 1;
104
+ break;
105
+ case "--publish":
106
+ publish = true;
107
+ break;
54
108
  default:
55
109
  if (arg.startsWith("--")) throw new ArenaError(`unknown option '${arg}'`, "CONFIG_INVALID");
56
110
  if (command === void 0) command = arg;
@@ -61,9 +115,18 @@ function parseArgs(argv) {
61
115
  command,
62
116
  positional,
63
117
  config,
118
+ configSet,
64
119
  out,
65
120
  format,
66
- tasks
121
+ tasks,
122
+ pack,
123
+ registry,
124
+ agent,
125
+ sverkaVersion,
126
+ since,
127
+ dir,
128
+ traces,
129
+ publish
67
130
  };
68
131
  }
69
132
  function which(bin) {
@@ -111,12 +174,95 @@ function filterTasks(tasks, ids) {
111
174
  const wanted = new Set(ids);
112
175
  return { tasks: uniq.filter((t) => wanted.has(t.id)) };
113
176
  }
177
+ /** Version of @sverka/arena itself — the sverkaVersion stamp on docs. */
178
+ function arenaVersion() {
179
+ try {
180
+ return JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8")).version ?? "0.0.0";
181
+ } catch {
182
+ return "0.0.0";
183
+ }
184
+ }
185
+ function registryRef(args) {
186
+ return args.registry ?? process.env["ARENA_REGISTRY"];
187
+ }
188
+ /**
189
+ * Strip embedded credentials (scheme://user:pass@host) before a registry
190
+ * ref is printed to stderr — CI logs retain that output. Exported for
191
+ * tests.
192
+ */
193
+ function redactRegistryRef(ref) {
194
+ return ref.replace(/(\/\/)[^/\s]+@/, "$1***@");
195
+ }
196
+ /** POSIX single-quote escaping — `'`, with `'\''` per embedded quote. */
197
+ function shQuote(s) {
198
+ return `'${s.replace(/'/g, `'\\''`)}'`;
199
+ }
200
+ /**
201
+ * The `sverka-arena publish` retry hint printed when `run --publish`
202
+ * fails — args are shell-quoted so the line survives a copy-paste. A
203
+ * --registry ref carrying embedded credentials is never echoed (even
204
+ * redacted it is unusable); the user re-supplies it via ARENA_REGISTRY.
205
+ * Exported for tests.
206
+ */
207
+ function publishRetryHint(opts) {
208
+ const retry = [
209
+ `sverka-arena publish ${shQuote(opts.saved)}`,
210
+ `--pack ${shQuote(opts.pack)}`,
211
+ `--agent ${shQuote(opts.agent)}`,
212
+ `--sverka-version ${shQuote(opts.sverkaVersion)}`
213
+ ];
214
+ if (opts.config !== void 0) retry.push(`--config ${shQuote(opts.config)}`);
215
+ let note = "";
216
+ if (opts.registry !== void 0) {
217
+ if (redactRegistryRef(opts.registry) === opts.registry) retry.push(`--registry ${shQuote(opts.registry)}`);
218
+ else note = "\nnote: the registry ref carries credentials — set ARENA_REGISTRY to the original ref before retrying";
219
+ }
220
+ return `retry with: ${retry.join(" ")}${note}`;
221
+ }
222
+ /** Bearer token for private https registries — env only, never argv. */
223
+ function registryToken() {
224
+ return process.env["ARENA_REGISTRY_TOKEN"];
225
+ }
226
+ function registryOpts() {
227
+ const token = registryToken();
228
+ return token !== void 0 ? { token } : {};
229
+ }
230
+ function requireRegistry(args) {
231
+ const ref = registryRef(args);
232
+ if (ref === void 0) throw new ArenaError("no registry — pass --registry <ref> or set ARENA_REGISTRY", "CONFIG_INVALID");
233
+ return openRegistry(ref, registryOpts());
234
+ }
114
235
  async function cmdRun(args, io) {
115
236
  if (args.format === "html") {
116
237
  io.err("run: --format html is only supported by 'report'\n");
117
238
  return 2;
118
239
  }
119
- const config = await loadArenaConfig(args.config);
240
+ const publishRegistry = args.publish ? requireRegistry(args) : void 0;
241
+ let pack;
242
+ let config;
243
+ if (args.pack !== void 0) {
244
+ const regRef = registryRef(args);
245
+ pack = await resolvePack(args.pack, {
246
+ ...regRef !== void 0 ? { registry: regRef } : {},
247
+ ...registryOpts()
248
+ });
249
+ io.err(`pack '${pack.name}': ${pack.tasks.length} task(s) from ${pack.dir}\n`);
250
+ if (existsSync(resolve(args.config)) || args.configSet) {
251
+ config = await loadArenaConfig(args.config);
252
+ config.tasks = pack.tasks;
253
+ if (config.repetitions === void 0 && pack.defaults.repetitions !== void 0) config.repetitions = pack.defaults.repetitions;
254
+ } else config = {
255
+ agent: resolveAdapter("devin"),
256
+ models: [{
257
+ id: "devin-default",
258
+ name: "Devin default"
259
+ }],
260
+ plugins: [],
261
+ tasks: pack.tasks,
262
+ outputDir: resolve(pack.defaults.outputDir ?? ".arena"),
263
+ ...pack.defaults.repetitions !== void 0 ? { repetitions: pack.defaults.repetitions } : {}
264
+ };
265
+ } else config = await loadArenaConfig(args.config);
120
266
  if (args.out !== void 0) config.outputDir = resolve(args.out);
121
267
  const filtered = filterTasks(config.tasks, args.tasks);
122
268
  if ("missing" in filtered) {
@@ -127,6 +273,122 @@ async function cmdRun(args, io) {
127
273
  const result = await runArena(config);
128
274
  if (args.format === "json") io.out(JSON.stringify(result, null, 2) + "\n");
129
275
  else io.out(renderReport(result) + "\n");
276
+ if (publishRegistry !== void 0) {
277
+ const sverkaVersion = args.sverkaVersion ?? arenaVersion();
278
+ try {
279
+ const paths = await publishResult(result, publishRegistry, {
280
+ pack: pack?.name ?? "default",
281
+ agent: config.agent.id,
282
+ sverkaVersion,
283
+ prompts: Object.fromEntries(config.tasks.map((t) => [t.id, t.prompt]))
284
+ });
285
+ for (const p of paths) io.err(`published ${p}\n`);
286
+ } catch (err) {
287
+ const saved = join(config.outputDir, "results.json");
288
+ io.err(`publish failed — results saved at ${saved}\n` + publishRetryHint({
289
+ saved,
290
+ pack: pack?.name ?? "default",
291
+ agent: config.agent.id,
292
+ sverkaVersion,
293
+ ...args.configSet ? { config: args.config } : {},
294
+ ...args.registry !== void 0 ? { registry: args.registry } : {}
295
+ }) + "\n");
296
+ throw err;
297
+ }
298
+ }
299
+ return 0;
300
+ }
301
+ async function cmdPublish(args, io) {
302
+ const file = args.positional[0];
303
+ if (file === void 0) {
304
+ io.err("publish: missing <results.json> path\n");
305
+ return 2;
306
+ }
307
+ const registry = requireRegistry(args);
308
+ let raw;
309
+ try {
310
+ raw = JSON.parse(await readFile(resolve(file), "utf8"));
311
+ } catch (err) {
312
+ io.err(`publish: cannot read '${file}': ${err instanceof Error ? err.message : String(err)}\n`);
313
+ return 2;
314
+ }
315
+ const isMatrix = typeof raw === "object" && raw !== null && raw.schema !== "arena.result/v1" && Array.isArray(raw.results);
316
+ let agent = args.agent;
317
+ const prompts = {};
318
+ if (existsSync(resolve(args.config))) try {
319
+ const cfg = await loadArenaConfig(args.config);
320
+ agent ??= cfg.agent.id;
321
+ for (const t of cfg.tasks) prompts[t.id] = t.prompt;
322
+ } catch {}
323
+ if (isMatrix && (args.pack === void 0 || agent === void 0)) {
324
+ io.err(`publish: matrix results.json requires --pack <name> and --agent <id> (or --config with an agent)\n`);
325
+ return 2;
326
+ }
327
+ const paths = await publishFile(file, registry, {
328
+ pack: args.pack ?? "default",
329
+ agent: agent ?? "unknown",
330
+ sverkaVersion: args.sverkaVersion ?? arenaVersion(),
331
+ prompts,
332
+ traces: args.traces
333
+ });
334
+ if (args.format === "json") io.out(JSON.stringify({ published: paths }, null, 2) + "\n");
335
+ else for (const p of paths) io.out(`published ${p}\n`);
336
+ return 0;
337
+ }
338
+ async function cmdBoard(args, io) {
339
+ const results = await requireRegistry(args).list({
340
+ ...args.pack !== void 0 ? { pack: args.pack } : {},
341
+ ...args.agent !== void 0 ? { agent: args.agent } : {},
342
+ ...args.since !== void 0 ? { since: args.since } : {}
343
+ });
344
+ const cohorts = buildBoard(results);
345
+ if (args.format === "json") io.out(JSON.stringify(cohorts, null, 2) + "\n");
346
+ else if (args.format === "html") {
347
+ const out = args.out ?? "arena-board.html";
348
+ writeFileSync(resolve(out), renderBoardHtml(cohorts), "utf8");
349
+ io.out(`leaderboard written to ${out}\n`);
350
+ } else io.out(renderBoard(cohorts) + "\n");
351
+ return 0;
352
+ }
353
+ async function cmdPack(args, io) {
354
+ const sub = args.positional[0];
355
+ if (sub === "init") {
356
+ const name = args.positional[1];
357
+ if (name === void 0) {
358
+ io.err("pack init: missing <name>\n");
359
+ return 2;
360
+ }
361
+ const dir = join(args.dir ?? process.cwd(), name);
362
+ await initPack(dir, name);
363
+ io.out(`pack '${name}' scaffolded at ${dir}\n`);
364
+ return 0;
365
+ }
366
+ if (sub === "lint") {
367
+ const dir = args.positional[1];
368
+ if (dir === void 0) {
369
+ io.err("pack lint: missing <dir>\n");
370
+ return 2;
371
+ }
372
+ const { errors, warnings } = await lintPack(resolve(dir));
373
+ if (args.format === "json") io.out(JSON.stringify({
374
+ errors,
375
+ warnings
376
+ }, null, 2) + "\n");
377
+ else {
378
+ for (const w of warnings) io.out(`warn ${w}\n`);
379
+ for (const e of errors) io.out(`error ${e}\n`);
380
+ if (errors.length === 0) io.out(`pack '${dir}': ok\n`);
381
+ }
382
+ return errors.length === 0 ? 0 : 1;
383
+ }
384
+ io.err(`pack: unknown subcommand '${sub ?? ""}' — init|lint\n`);
385
+ return 2;
386
+ }
387
+ async function cmdReindex(args, io) {
388
+ const registry = requireRegistry(args);
389
+ const { runs } = await reindexRegistry(registry);
390
+ if (args.format === "json") io.out(JSON.stringify({ runs }, null, 2) + "\n");
391
+ else io.out(`index.json rebuilt — ${runs} run(s) indexed\n`);
130
392
  return 0;
131
393
  }
132
394
  function doctorChecks(config) {
@@ -185,6 +447,10 @@ async function main(argv, io = defaultIo) {
185
447
  return 2;
186
448
  }
187
449
  return args.command === "report" ? await cmdReport(args, io) : await cmdDoctor(args, io);
450
+ case "publish": return await cmdPublish(args, io);
451
+ case "board": return await cmdBoard(args, io);
452
+ case "pack": return await cmdPack(args, io);
453
+ case "reindex": return await cmdReindex(args, io);
188
454
  default:
189
455
  io.err(`unknown command '${args.command}'\n`);
190
456
  io.err(USAGE);
@@ -192,8 +458,10 @@ async function main(argv, io = defaultIo) {
192
458
  }
193
459
  } catch (err) {
194
460
  if (err instanceof ArenaError) {
461
+ const code = err.code === "REGISTRY_UNAVAILABLE" || err.code === "PUBLISH_CONFLICT" ? 3 : 2;
195
462
  io.err(`error: ${err.message}\n`);
196
- return 2;
463
+ if (err.cause !== void 0) io.err(`cause: ${err.cause instanceof Error ? err.cause.message : String(err.cause)}\n`);
464
+ return code;
197
465
  }
198
466
  io.err(`error: ${err instanceof Error ? err.message : String(err)}\n`);
199
467
  return 3;
@@ -204,6 +472,6 @@ if (import.meta.url === `file://${process.argv[1]}`) {
204
472
  process.exit(code);
205
473
  }
206
474
  //#endregion
207
- export { filterTasks, main };
475
+ export { filterTasks, main, publishRetryHint, redactRegistryRef };
208
476
 
209
477
  //# sourceMappingURL=bin.mjs.map
package/dist/bin.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"bin.mjs","names":[],"sources":["../src/bin.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * sverka-arena — CLI for the agent arena: run the benchmark matrix, render\n * saved results, check the environment. Spec: specs/49-arena-cli.\n */\n\nimport process from \"node:process\";\nimport { readFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { delimiter, join, resolve } from \"node:path\";\n\nimport type { ArenaResult } from \"./types.js\";\nimport { ArenaError, loadArenaConfig } from \"./config.js\";\nimport { renderReport } from \"./report.js\";\nimport { writeAggregateReport } from \"./aggregate-report.js\";\nimport { runArena } from \"./runner.js\";\n\ninterface Io {\n out(s: string): void;\n err(s: string): void;\n}\n\ntype Format = \"text\" | \"json\" | \"html\";\n\ninterface ParsedArgs {\n command: string | undefined;\n positional: string[];\n config: string;\n out: string | undefined;\n format: Format;\n tasks: string[];\n}\n\nconst USAGE = `usage: sverka-arena <command> [options]\n\ncommands:\n run [--config <path>] [--out <dir>] [--format json|text] [--task <id>]...\n report <results.json> [--format json|text|html] [--out <file.html>]\n doctor [--config <path>] [--format json|text]\n`;\n\nfunction flagValue(argv: readonly string[], i: number): string {\n const val = argv[i + 1];\n if (val === undefined || val.startsWith(\"--\")) {\n throw new ArenaError(`${argv[i]} requires a value`, \"CONFIG_INVALID\");\n }\n return val;\n}\n\nfunction parseFormat(val: string): Format {\n if (val !== \"json\" && val !== \"text\" && val !== \"html\") {\n throw new ArenaError(`invalid --format '${val}'`, \"CONFIG_INVALID\");\n }\n return val;\n}\n\nfunction parseArgs(argv: readonly string[]): ParsedArgs {\n const positional: string[] = [];\n let config = \"arena.config.ts\";\n let out: string | undefined;\n let format: \"text\" | \"json\" | \"html\" = \"text\";\n let command: string | undefined;\n const tasks: string[] = [];\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i]!;\n switch (arg) {\n case \"--config\":\n config = flagValue(argv, i);\n i += 1;\n break;\n case \"--out\":\n out = flagValue(argv, i);\n i += 1;\n break;\n case \"--format\":\n format = parseFormat(flagValue(argv, i));\n i += 1;\n break;\n case \"--task\":\n tasks.push(flagValue(argv, i));\n i += 1;\n break;\n default:\n if (arg.startsWith(\"--\")) {\n throw new ArenaError(`unknown option '${arg}'`, \"CONFIG_INVALID\");\n }\n if (command === undefined) command = arg;\n else positional.push(arg);\n }\n }\n return { command, positional, config, out, format, tasks };\n}\n\nfunction which(bin: string): boolean {\n const exts =\n process.platform === \"win32\"\n ? [\"\", ...(process.env.PATHEXT ?? \".EXE;.CMD;.BAT\").split(\";\")]\n : [\"\"];\n for (const dir of (process.env.PATH ?? \"\").split(delimiter)) {\n if (exts.some((ext) => existsSync(join(dir, bin + ext)))) return true;\n }\n return false;\n}\n\nasync function cmdReport(args: ParsedArgs, io: Io): Promise<number> {\n const file = args.positional[0];\n if (file === undefined) {\n io.err(\"report: missing <results.json> path\");\n return 2;\n }\n let result: ArenaResult;\n try {\n result = JSON.parse(await readFile(file, \"utf8\")) as ArenaResult;\n } catch (err) {\n io.err(\n `report: cannot read '${file}': ${err instanceof Error ? err.message : String(err)}`,\n );\n return 2;\n }\n if (\n !Array.isArray(result.aggregates) ||\n !Array.isArray(result.analysis) ||\n !Array.isArray(result.results) ||\n result.config === undefined ||\n !Array.isArray(result.config.models)\n ) {\n io.err(`report: '${file}' is not a sverka-arena results file\\n`);\n return 2;\n }\n if (args.format === \"json\") {\n io.out(JSON.stringify(result, null, 2) + \"\\n\");\n } else if (args.format === \"html\") {\n const out = args.out ?? \"arena-report.html\";\n writeAggregateReport(result, resolve(out), {\n command: `sverka-arena report ${file} --format html`,\n });\n io.out(`report written to ${out}\\n`);\n } else {\n io.out(renderReport(result) + \"\\n\");\n }\n return 0;\n}\n\n/** Filter config tasks by --task ids; duplicate ids collapse to one. */\nexport function filterTasks<T extends { id: string }>(\n tasks: T[],\n ids: string[],\n): { tasks: T[] } | { missing: string[] } {\n const seen = new Set<string>();\n const uniq = tasks.filter((t) => {\n if (seen.has(t.id)) return false;\n seen.add(t.id);\n return true;\n });\n if (ids.length === 0) return { tasks: uniq };\n const known = new Set(uniq.map((t) => t.id));\n const missing = ids.filter((id) => !known.has(id));\n if (missing.length > 0) return { missing };\n const wanted = new Set(ids);\n return { tasks: uniq.filter((t) => wanted.has(t.id)) };\n}\n\nasync function cmdRun(args: ParsedArgs, io: Io): Promise<number> {\n if (args.format === \"html\") {\n io.err(\"run: --format html is only supported by 'report'\\n\");\n return 2;\n }\n const config = await loadArenaConfig(args.config);\n if (args.out !== undefined) config.outputDir = resolve(args.out);\n const filtered = filterTasks(config.tasks, args.tasks);\n if (\"missing\" in filtered) {\n io.err(\n `run: unknown --task '${filtered.missing.join(\"', '\")}' (config defines: ${[...new Set(config.tasks.map((t) => t.id))].join(\", \")})\\n`,\n );\n return 2;\n }\n config.tasks = filtered.tasks;\n const result = await runArena(config);\n if (args.format === \"json\") {\n io.out(JSON.stringify(result, null, 2) + \"\\n\");\n } else {\n io.out(renderReport(result) + \"\\n\");\n }\n return 0;\n}\n\ninterface DoctorCheck {\n name: string;\n ok: boolean;\n detail: string;\n}\n\nfunction doctorChecks(\n config: Awaited<ReturnType<typeof loadArenaConfig>>,\n): DoctorCheck[] {\n const agentOnPath = which(config.agent.id);\n const checks: DoctorCheck[] = [\n {\n name: `agent binary: ${config.agent.id}`,\n ok: agentOnPath,\n detail: agentOnPath ? \"on PATH\" : \"not found on PATH\",\n },\n ];\n const models = config.judge\n ? [...config.models, config.judge.model]\n : config.models;\n for (const m of models) {\n if (m.envVar === undefined) continue;\n checks.push({\n name: `env: ${m.envVar} (model ${m.id})`,\n ok: process.env[m.envVar] !== undefined,\n detail: process.env[m.envVar] !== undefined ? \"set\" : \"not set\",\n });\n }\n return checks;\n}\n\nasync function cmdDoctor(args: ParsedArgs, io: Io): Promise<number> {\n if (args.format === \"html\") {\n io.err(\"doctor: --format html is only supported by 'report'\\n\");\n return 2;\n }\n const checks = doctorChecks(await loadArenaConfig(args.config));\n\n if (args.format === \"json\") {\n io.out(JSON.stringify({ checks }, null, 2) + \"\\n\");\n } else {\n for (const chk of checks) {\n io.out(`${chk.ok ? \"ok\" : \"FAIL\"} ${chk.name} — ${chk.detail}\\n`);\n }\n }\n return checks.every((chk) => chk.ok) ? 0 : 1;\n}\n\nconst defaultIo: Io = {\n out: (s) => process.stdout.write(s),\n err: (s) => process.stderr.write(s),\n};\n\n/** Entry point — exported for tests; bin calls it with process.argv. */\nexport async function main(\n argv: readonly string[],\n io: Io = defaultIo,\n): Promise<number> {\n let args: ParsedArgs;\n try {\n args = parseArgs(argv);\n } catch (err) {\n io.err((err instanceof Error ? err.message : String(err)) + \"\\n\");\n io.err(USAGE);\n return 2;\n }\n\n if (args.command === undefined) {\n io.err(USAGE);\n return 2;\n }\n\n try {\n switch (args.command) {\n case \"run\":\n return await cmdRun(args, io);\n case \"report\":\n case \"doctor\":\n if (args.tasks.length > 0) {\n io.err(`${args.command}: --task is only supported by 'run'\\n`);\n return 2;\n }\n return args.command === \"report\"\n ? await cmdReport(args, io)\n : await cmdDoctor(args, io);\n default:\n io.err(`unknown command '${args.command}'\\n`);\n io.err(USAGE);\n return 2;\n }\n } catch (err) {\n if (err instanceof ArenaError) {\n io.err(`error: ${err.message}\\n`);\n return 2;\n }\n io.err(`error: ${err instanceof Error ? err.message : String(err)}\\n`);\n return 3;\n }\n}\n\n// Run when invoked directly (not imported by tests).\nif (import.meta.url === `file://${process.argv[1]}`) {\n const code = await main(process.argv.slice(2));\n process.exit(code);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"bin.mjs","names":[],"sources":["../src/bin.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * sverka-arena — CLI for the agent arena: run the benchmark matrix, render\n * saved results, check the environment, publish to the results registry\n * and render the leaderboard. Specs: 49-arena-cli, 56-arena-eval-service.\n */\n\nimport process from \"node:process\";\nimport { readFile } from \"node:fs/promises\";\nimport { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { delimiter, join, resolve } from \"node:path\";\n\nimport type { ArenaResult } from \"./types.js\";\nimport { ArenaError, loadArenaConfig, resolveAdapter } from \"./config.js\";\nimport { renderReport } from \"./report.js\";\nimport { writeAggregateReport } from \"./aggregate-report.js\";\nimport { runArena } from \"./runner.js\";\nimport {\n openRegistry,\n reindexRegistry,\n type ArenaRegistry,\n} from \"./registry.js\";\nimport { publishFile, publishResult } from \"./publish.js\";\nimport { buildBoard, renderBoard, renderBoardHtml } from \"./board.js\";\nimport { initPack, lintPack, resolvePack, type TaskPack } from \"./pack.js\";\n\ninterface Io {\n out(s: string): void;\n err(s: string): void;\n}\n\ntype Format = \"text\" | \"json\" | \"html\";\n\ninterface ParsedArgs {\n command: string | undefined;\n positional: string[];\n config: string;\n configSet: boolean;\n out: string | undefined;\n format: Format;\n tasks: string[];\n pack: string | undefined;\n registry: string | undefined;\n agent: string | undefined;\n sverkaVersion: string | undefined;\n since: string | undefined;\n dir: string | undefined;\n traces: string[];\n publish: boolean;\n}\n\nconst USAGE = `usage: sverka-arena <command> [options]\n\ncommands:\n run [--config <path>] [--out <dir>] [--format json|text] [--task <id>]...\n [--pack <ref>] [--publish --registry <ref>]\n report <results.json> [--format json|text|html] [--out <file.html>]\n doctor [--config <path>] [--format json|text]\n publish <results.json> --pack <name> --registry <ref>\n [--config <path>] [--agent <id>] [--sverka-version <v>] [--trace <file>]...\n [--format json|text]\n board --registry <ref> [--pack <name>] [--agent <id>] [--since <date>]\n [--format json|text|html] [--out <file.html>]\n pack init <name> [--dir <parent>] | lint <dir> [--format json|text]\n reindex --registry <ref> [--format json|text]\n\nregistry refs: <dir> | file://<dir> | <git-url> | git::<url> | s3://<bucket>/<prefix>\npack refs: <dir> | <git-url> | <name> (packs/<name>/ inside --registry)\nenv: ARENA_REGISTRY (registry ref), ARENA_REGISTRY_TOKEN (https bearer)\n`;\n\nfunction flagValue(argv: readonly string[], i: number): string {\n const val = argv[i + 1];\n if (val === undefined || val.startsWith(\"--\")) {\n throw new ArenaError(`${argv[i]} requires a value`, \"CONFIG_INVALID\");\n }\n return val;\n}\n\nfunction parseFormat(val: string): Format {\n if (val !== \"json\" && val !== \"text\" && val !== \"html\") {\n throw new ArenaError(`invalid --format '${val}'`, \"CONFIG_INVALID\");\n }\n return val;\n}\n\nfunction parseArgs(argv: readonly string[]): ParsedArgs {\n const positional: string[] = [];\n let config = \"arena.config.ts\";\n let configSet = false;\n let out: string | undefined;\n let format: \"text\" | \"json\" | \"html\" = \"text\";\n let command: string | undefined;\n const tasks: string[] = [];\n const traces: string[] = [];\n let pack: string | undefined;\n let registry: string | undefined;\n let agent: string | undefined;\n let sverkaVersion: string | undefined;\n let since: string | undefined;\n let dir: string | undefined;\n let publish = false;\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i]!;\n switch (arg) {\n case \"--config\":\n config = flagValue(argv, i);\n configSet = true;\n i += 1;\n break;\n case \"--out\":\n out = flagValue(argv, i);\n i += 1;\n break;\n case \"--format\":\n format = parseFormat(flagValue(argv, i));\n i += 1;\n break;\n case \"--task\":\n tasks.push(flagValue(argv, i));\n i += 1;\n break;\n case \"--pack\":\n pack = flagValue(argv, i);\n i += 1;\n break;\n case \"--registry\":\n registry = flagValue(argv, i);\n i += 1;\n break;\n case \"--agent\":\n agent = flagValue(argv, i);\n i += 1;\n break;\n case \"--sverka-version\":\n sverkaVersion = flagValue(argv, i);\n i += 1;\n break;\n case \"--since\":\n since = flagValue(argv, i);\n i += 1;\n break;\n case \"--dir\":\n dir = flagValue(argv, i);\n i += 1;\n break;\n case \"--trace\":\n traces.push(flagValue(argv, i));\n i += 1;\n break;\n case \"--publish\":\n publish = true;\n break;\n default:\n if (arg.startsWith(\"--\")) {\n throw new ArenaError(`unknown option '${arg}'`, \"CONFIG_INVALID\");\n }\n if (command === undefined) command = arg;\n else positional.push(arg);\n }\n }\n return {\n command,\n positional,\n config,\n configSet,\n out,\n format,\n tasks,\n pack,\n registry,\n agent,\n sverkaVersion,\n since,\n dir,\n traces,\n publish,\n };\n}\n\nfunction which(bin: string): boolean {\n const exts =\n process.platform === \"win32\"\n ? [\"\", ...(process.env.PATHEXT ?? \".EXE;.CMD;.BAT\").split(\";\")]\n : [\"\"];\n for (const dir of (process.env.PATH ?? \"\").split(delimiter)) {\n if (exts.some((ext) => existsSync(join(dir, bin + ext)))) return true;\n }\n return false;\n}\n\nasync function cmdReport(args: ParsedArgs, io: Io): Promise<number> {\n const file = args.positional[0];\n if (file === undefined) {\n io.err(\"report: missing <results.json> path\");\n return 2;\n }\n let result: ArenaResult;\n try {\n result = JSON.parse(await readFile(file, \"utf8\")) as ArenaResult;\n } catch (err) {\n io.err(\n `report: cannot read '${file}': ${err instanceof Error ? err.message : String(err)}`,\n );\n return 2;\n }\n if (\n !Array.isArray(result.aggregates) ||\n !Array.isArray(result.analysis) ||\n !Array.isArray(result.results) ||\n result.config === undefined ||\n !Array.isArray(result.config.models)\n ) {\n io.err(`report: '${file}' is not a sverka-arena results file\\n`);\n return 2;\n }\n if (args.format === \"json\") {\n io.out(JSON.stringify(result, null, 2) + \"\\n\");\n } else if (args.format === \"html\") {\n const out = args.out ?? \"arena-report.html\";\n writeAggregateReport(result, resolve(out), {\n command: `sverka-arena report ${file} --format html`,\n });\n io.out(`report written to ${out}\\n`);\n } else {\n io.out(renderReport(result) + \"\\n\");\n }\n return 0;\n}\n\n/** Filter config tasks by --task ids; duplicate ids collapse to one. */\nexport function filterTasks<T extends { id: string }>(\n tasks: T[],\n ids: string[],\n): { tasks: T[] } | { missing: string[] } {\n const seen = new Set<string>();\n const uniq = tasks.filter((t) => {\n if (seen.has(t.id)) return false;\n seen.add(t.id);\n return true;\n });\n if (ids.length === 0) return { tasks: uniq };\n const known = new Set(uniq.map((t) => t.id));\n const missing = ids.filter((id) => !known.has(id));\n if (missing.length > 0) return { missing };\n const wanted = new Set(ids);\n return { tasks: uniq.filter((t) => wanted.has(t.id)) };\n}\n\n/** Version of @sverka/arena itself — the sverkaVersion stamp on docs. */\nfunction arenaVersion(): string {\n try {\n const pkg = JSON.parse(\n readFileSync(new URL(\"../package.json\", import.meta.url), \"utf8\"),\n ) as { version?: string };\n return pkg.version ?? \"0.0.0\";\n } catch {\n return \"0.0.0\";\n }\n}\n\nfunction registryRef(args: ParsedArgs): string | undefined {\n return args.registry ?? process.env[\"ARENA_REGISTRY\"];\n}\n\n/**\n * Strip embedded credentials (scheme://user:pass@host) before a registry\n * ref is printed to stderr — CI logs retain that output. Exported for\n * tests.\n */\nexport function redactRegistryRef(ref: string): string {\n return ref.replace(/(\\/\\/)[^/\\s]+@/, \"$1***@\");\n}\n\n/** POSIX single-quote escaping — `'`, with `'\\''` per embedded quote. */\nfunction shQuote(s: string): string {\n return `'${s.replace(/'/g, `'\\\\''`)}'`;\n}\n\n/**\n * The `sverka-arena publish` retry hint printed when `run --publish`\n * fails — args are shell-quoted so the line survives a copy-paste. A\n * --registry ref carrying embedded credentials is never echoed (even\n * redacted it is unusable); the user re-supplies it via ARENA_REGISTRY.\n * Exported for tests.\n */\nexport function publishRetryHint(opts: {\n saved: string;\n pack: string;\n agent: string;\n sverkaVersion: string;\n config?: string;\n registry?: string;\n}): string {\n const retry = [\n `sverka-arena publish ${shQuote(opts.saved)}`,\n `--pack ${shQuote(opts.pack)}`,\n `--agent ${shQuote(opts.agent)}`,\n `--sverka-version ${shQuote(opts.sverkaVersion)}`,\n ];\n if (opts.config !== undefined) retry.push(`--config ${shQuote(opts.config)}`);\n let note = \"\";\n if (opts.registry !== undefined) {\n if (redactRegistryRef(opts.registry) === opts.registry) {\n retry.push(`--registry ${shQuote(opts.registry)}`);\n } else {\n note =\n \"\\nnote: the registry ref carries credentials — set ARENA_REGISTRY to the original ref before retrying\";\n }\n }\n return `retry with: ${retry.join(\" \")}${note}`;\n}\n\n/** Bearer token for private https registries — env only, never argv. */\nfunction registryToken(): string | undefined {\n return process.env[\"ARENA_REGISTRY_TOKEN\"];\n}\n\nfunction registryOpts(): { token?: string } {\n const token = registryToken();\n return token !== undefined ? { token } : {};\n}\n\nfunction requireRegistry(args: ParsedArgs): ArenaRegistry {\n const ref = registryRef(args);\n if (ref === undefined) {\n throw new ArenaError(\n \"no registry — pass --registry <ref> or set ARENA_REGISTRY\",\n \"CONFIG_INVALID\",\n );\n }\n return openRegistry(ref, registryOpts());\n}\n\nasync function cmdRun(args: ParsedArgs, io: Io): Promise<number> {\n if (args.format === \"html\") {\n io.err(\"run: --format html is only supported by 'report'\\n\");\n return 2;\n }\n // Fail fast — a missing registry must fail before the matrix runs.\n const publishRegistry = args.publish ? requireRegistry(args) : undefined;\n let pack: TaskPack | undefined;\n let config: Awaited<ReturnType<typeof loadArenaConfig>>;\n if (args.pack !== undefined) {\n const regRef = registryRef(args);\n pack = await resolvePack(args.pack, {\n ...(regRef !== undefined ? { registry: regRef } : {}),\n ...registryOpts(),\n });\n io.err(\n `pack '${pack.name}': ${pack.tasks.length} task(s) from ${pack.dir}\\n`,\n );\n const configExists = existsSync(resolve(args.config));\n if (configExists || args.configSet) {\n config = await loadArenaConfig(args.config);\n config.tasks = pack.tasks as typeof config.tasks;\n if (\n config.repetitions === undefined &&\n pack.defaults.repetitions !== undefined\n ) {\n config.repetitions = pack.defaults.repetitions;\n }\n } else {\n // No config — synthesize a minimal one so shared packs run standalone.\n config = {\n agent: resolveAdapter(\"devin\"),\n models: [{ id: \"devin-default\", name: \"Devin default\" }],\n plugins: [],\n tasks: pack.tasks as typeof config.tasks,\n outputDir: resolve(pack.defaults.outputDir ?? \".arena\"),\n ...(pack.defaults.repetitions !== undefined\n ? { repetitions: pack.defaults.repetitions }\n : {}),\n };\n }\n } else {\n config = await loadArenaConfig(args.config);\n }\n if (args.out !== undefined) config.outputDir = resolve(args.out);\n const filtered = filterTasks(config.tasks, args.tasks);\n if (\"missing\" in filtered) {\n io.err(\n `run: unknown --task '${filtered.missing.join(\"', '\")}' (config defines: ${[...new Set(config.tasks.map((t) => t.id))].join(\", \")})\\n`,\n );\n return 2;\n }\n config.tasks = filtered.tasks;\n const result = await runArena(config);\n if (args.format === \"json\") {\n io.out(JSON.stringify(result, null, 2) + \"\\n\");\n } else {\n io.out(renderReport(result) + \"\\n\");\n }\n if (publishRegistry !== undefined) {\n // Resolved once so a publish retry stamps the same version — pinning\n // it keeps the run in its original comparison cohort.\n const sverkaVersion = args.sverkaVersion ?? arenaVersion();\n try {\n const paths = await publishResult(result, publishRegistry, {\n pack: pack?.name ?? \"default\",\n agent: config.agent.id,\n sverkaVersion,\n prompts: Object.fromEntries(\n config.tasks.map((t) => [t.id, t.prompt] as const),\n ),\n });\n for (const p of paths) io.err(`published ${p}\\n`);\n } catch (err) {\n // The matrix already ran — point at the saved results.json so the\n // user can retry `sverka-arena publish` without re-running it.\n // An env-sourced registry ref is inherited on retry; an explicit\n // ref is echoed only when it carries no credentials.\n const saved = join(config.outputDir, \"results.json\");\n io.err(\n `publish failed — results saved at ${saved}\\n` +\n publishRetryHint({\n saved,\n pack: pack?.name ?? \"default\",\n agent: config.agent.id,\n sverkaVersion,\n ...(args.configSet ? { config: args.config } : {}),\n ...(args.registry !== undefined ? { registry: args.registry } : {}),\n }) +\n \"\\n\",\n );\n throw err;\n }\n }\n return 0;\n}\n\n// ─── publish ─────────────────────────────────────────────────────────\n\nasync function cmdPublish(args: ParsedArgs, io: Io): Promise<number> {\n const file = args.positional[0];\n if (file === undefined) {\n io.err(\"publish: missing <results.json> path\\n\");\n return 2;\n }\n const registry = requireRegistry(args);\n\n let raw: { schema?: string; results?: unknown };\n try {\n raw = JSON.parse(await readFile(resolve(file), \"utf8\")) as typeof raw;\n } catch (err) {\n io.err(\n `publish: cannot read '${file}': ${err instanceof Error ? err.message : String(err)}\\n`,\n );\n return 2;\n }\n const isMatrix =\n typeof raw === \"object\" &&\n raw !== null &&\n raw.schema !== \"arena.result/v1\" &&\n Array.isArray(raw.results);\n\n // Matrix files need pack+agent context; v1 docs carry their own.\n // --agent may still come from a config file's `agent` field.\n let agent = args.agent;\n const prompts: Record<string, string> = {};\n if (existsSync(resolve(args.config))) {\n try {\n const cfg = await loadArenaConfig(args.config);\n agent ??= cfg.agent.id;\n for (const t of cfg.tasks) prompts[t.id] = t.prompt;\n } catch {\n /* config optional for publish */\n }\n }\n if (isMatrix && (args.pack === undefined || agent === undefined)) {\n io.err(\n `publish: matrix results.json requires --pack <name> and --agent <id> (or --config with an agent)\\n`,\n );\n return 2;\n }\n const paths = await publishFile(file, registry, {\n pack: args.pack ?? \"default\",\n agent: agent ?? \"unknown\",\n sverkaVersion: args.sverkaVersion ?? arenaVersion(),\n prompts,\n traces: args.traces,\n });\n if (args.format === \"json\") {\n io.out(JSON.stringify({ published: paths }, null, 2) + \"\\n\");\n } else {\n for (const p of paths) io.out(`published ${p}\\n`);\n }\n return 0;\n}\n\n// ─── board ───────────────────────────────────────────────────────────\n\nasync function cmdBoard(args: ParsedArgs, io: Io): Promise<number> {\n const registry = requireRegistry(args);\n const results = await registry.list({\n ...(args.pack !== undefined ? { pack: args.pack } : {}),\n ...(args.agent !== undefined ? { agent: args.agent } : {}),\n ...(args.since !== undefined ? { since: args.since } : {}),\n });\n const cohorts = buildBoard(results);\n if (args.format === \"json\") {\n io.out(JSON.stringify(cohorts, null, 2) + \"\\n\");\n } else if (args.format === \"html\") {\n const out = args.out ?? \"arena-board.html\";\n writeFileSync(resolve(out), renderBoardHtml(cohorts), \"utf8\");\n io.out(`leaderboard written to ${out}\\n`);\n } else {\n io.out(renderBoard(cohorts) + \"\\n\");\n }\n return 0;\n}\n\n// ─── pack ────────────────────────────────────────────────────────────\n\nasync function cmdPack(args: ParsedArgs, io: Io): Promise<number> {\n const sub = args.positional[0];\n if (sub === \"init\") {\n const name = args.positional[1];\n if (name === undefined) {\n io.err(\"pack init: missing <name>\\n\");\n return 2;\n }\n const dir = join(args.dir ?? process.cwd(), name);\n await initPack(dir, name);\n io.out(`pack '${name}' scaffolded at ${dir}\\n`);\n return 0;\n }\n if (sub === \"lint\") {\n const dir = args.positional[1];\n if (dir === undefined) {\n io.err(\"pack lint: missing <dir>\\n\");\n return 2;\n }\n const { errors, warnings } = await lintPack(resolve(dir));\n if (args.format === \"json\") {\n io.out(JSON.stringify({ errors, warnings }, null, 2) + \"\\n\");\n } else {\n for (const w of warnings) io.out(`warn ${w}\\n`);\n for (const e of errors) io.out(`error ${e}\\n`);\n if (errors.length === 0) io.out(`pack '${dir}': ok\\n`);\n }\n return errors.length === 0 ? 0 : 1;\n }\n io.err(`pack: unknown subcommand '${sub ?? \"\"}' — init|lint\\n`);\n return 2;\n}\n\n// ─── reindex ─────────────────────────────────────────────────────────\n\nasync function cmdReindex(args: ParsedArgs, io: Io): Promise<number> {\n const registry = requireRegistry(args);\n const { runs } = await reindexRegistry(registry);\n if (args.format === \"json\") {\n io.out(JSON.stringify({ runs }, null, 2) + \"\\n\");\n } else {\n io.out(`index.json rebuilt — ${runs} run(s) indexed\\n`);\n }\n return 0;\n}\n\ninterface DoctorCheck {\n name: string;\n ok: boolean;\n detail: string;\n}\n\nfunction doctorChecks(\n config: Awaited<ReturnType<typeof loadArenaConfig>>,\n): DoctorCheck[] {\n const agentOnPath = which(config.agent.id);\n const checks: DoctorCheck[] = [\n {\n name: `agent binary: ${config.agent.id}`,\n ok: agentOnPath,\n detail: agentOnPath ? \"on PATH\" : \"not found on PATH\",\n },\n ];\n const models = config.judge\n ? [...config.models, config.judge.model]\n : config.models;\n for (const m of models) {\n if (m.envVar === undefined) continue;\n checks.push({\n name: `env: ${m.envVar} (model ${m.id})`,\n ok: process.env[m.envVar] !== undefined,\n detail: process.env[m.envVar] !== undefined ? \"set\" : \"not set\",\n });\n }\n return checks;\n}\n\nasync function cmdDoctor(args: ParsedArgs, io: Io): Promise<number> {\n if (args.format === \"html\") {\n io.err(\"doctor: --format html is only supported by 'report'\\n\");\n return 2;\n }\n const checks = doctorChecks(await loadArenaConfig(args.config));\n\n if (args.format === \"json\") {\n io.out(JSON.stringify({ checks }, null, 2) + \"\\n\");\n } else {\n for (const chk of checks) {\n io.out(`${chk.ok ? \"ok\" : \"FAIL\"} ${chk.name} — ${chk.detail}\\n`);\n }\n }\n return checks.every((chk) => chk.ok) ? 0 : 1;\n}\n\nconst defaultIo: Io = {\n out: (s) => process.stdout.write(s),\n err: (s) => process.stderr.write(s),\n};\n\n/** Entry point — exported for tests; bin calls it with process.argv. */\nexport async function main(\n argv: readonly string[],\n io: Io = defaultIo,\n): Promise<number> {\n let args: ParsedArgs;\n try {\n args = parseArgs(argv);\n } catch (err) {\n io.err((err instanceof Error ? err.message : String(err)) + \"\\n\");\n io.err(USAGE);\n return 2;\n }\n\n if (args.command === undefined) {\n io.err(USAGE);\n return 2;\n }\n\n try {\n switch (args.command) {\n case \"run\":\n return await cmdRun(args, io);\n case \"report\":\n case \"doctor\":\n if (args.tasks.length > 0) {\n io.err(`${args.command}: --task is only supported by 'run'\\n`);\n return 2;\n }\n return args.command === \"report\"\n ? await cmdReport(args, io)\n : await cmdDoctor(args, io);\n case \"publish\":\n return await cmdPublish(args, io);\n case \"board\":\n return await cmdBoard(args, io);\n case \"pack\":\n return await cmdPack(args, io);\n case \"reindex\":\n return await cmdReindex(args, io);\n default:\n io.err(`unknown command '${args.command}'\\n`);\n io.err(USAGE);\n return 2;\n }\n } catch (err) {\n if (err instanceof ArenaError) {\n const code =\n err.code === \"REGISTRY_UNAVAILABLE\" || err.code === \"PUBLISH_CONFLICT\"\n ? 3\n : 2;\n io.err(`error: ${err.message}\\n`);\n if (err.cause !== undefined) {\n io.err(\n `cause: ${err.cause instanceof Error ? err.cause.message : String(err.cause)}\\n`,\n );\n }\n return code;\n }\n io.err(`error: ${err instanceof Error ? err.message : String(err)}\\n`);\n return 3;\n }\n}\n\n// Run when invoked directly (not imported by tests).\nif (import.meta.url === `file://${process.argv[1]}`) {\n const code = await main(process.argv.slice(2));\n process.exit(code);\n}\n"],"mappings":"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"}