@zenalexa/unicli 0.207.1 → 0.208.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.
Files changed (72) hide show
  1. package/AGENTS.md +4 -4
  2. package/README.md +30 -17
  3. package/dist/browser/observe.d.ts +80 -0
  4. package/dist/browser/observe.d.ts.map +1 -0
  5. package/dist/browser/observe.js +144 -0
  6. package/dist/browser/observe.js.map +1 -0
  7. package/dist/browser/snapshot.d.ts.map +1 -1
  8. package/dist/browser/snapshot.js +29 -9
  9. package/dist/browser/snapshot.js.map +1 -1
  10. package/dist/cli.d.ts.map +1 -1
  11. package/dist/cli.js +53 -2
  12. package/dist/cli.js.map +1 -1
  13. package/dist/commands/eval.d.ts +112 -0
  14. package/dist/commands/eval.d.ts.map +1 -0
  15. package/dist/commands/eval.js +485 -0
  16. package/dist/commands/eval.js.map +1 -0
  17. package/dist/commands/mcp.d.ts +16 -0
  18. package/dist/commands/mcp.d.ts.map +1 -0
  19. package/dist/commands/mcp.js +135 -0
  20. package/dist/commands/mcp.js.map +1 -0
  21. package/dist/commands/operate.d.ts.map +1 -1
  22. package/dist/commands/operate.js +66 -1
  23. package/dist/commands/operate.js.map +1 -1
  24. package/dist/commands/skills.d.ts +91 -0
  25. package/dist/commands/skills.d.ts.map +1 -0
  26. package/dist/commands/skills.js +266 -0
  27. package/dist/commands/skills.js.map +1 -0
  28. package/dist/commands/usage.d.ts +17 -0
  29. package/dist/commands/usage.d.ts.map +1 -0
  30. package/dist/commands/usage.js +87 -0
  31. package/dist/commands/usage.js.map +1 -0
  32. package/dist/discovery/loader.d.ts +8 -1
  33. package/dist/discovery/loader.d.ts.map +1 -1
  34. package/dist/discovery/loader.js +100 -6
  35. package/dist/discovery/loader.js.map +1 -1
  36. package/dist/engine/update-check.js +1 -1
  37. package/dist/engine/update-check.js.map +1 -1
  38. package/dist/engine/yaml-runner.d.ts.map +1 -1
  39. package/dist/engine/yaml-runner.js +35 -1
  40. package/dist/engine/yaml-runner.js.map +1 -1
  41. package/dist/main.d.ts +1 -4
  42. package/dist/main.d.ts.map +1 -1
  43. package/dist/main.js +1 -4
  44. package/dist/main.js.map +1 -1
  45. package/dist/manifest.json +117 -1
  46. package/dist/mcp/server.d.ts +19 -6
  47. package/dist/mcp/server.d.ts.map +1 -1
  48. package/dist/mcp/server.js +401 -115
  49. package/dist/mcp/server.js.map +1 -1
  50. package/dist/permissions/sensitive-paths.d.ts +92 -0
  51. package/dist/permissions/sensitive-paths.d.ts.map +1 -0
  52. package/dist/permissions/sensitive-paths.js +174 -0
  53. package/dist/permissions/sensitive-paths.js.map +1 -0
  54. package/dist/runtime/usage-ledger.d.ts +86 -0
  55. package/dist/runtime/usage-ledger.d.ts.map +1 -0
  56. package/dist/runtime/usage-ledger.js +173 -0
  57. package/dist/runtime/usage-ledger.js.map +1 -0
  58. package/package.json +8 -7
  59. package/src/adapters/autoagent/eval-run.yaml +36 -0
  60. package/src/adapters/cua/bench-list.yaml +20 -0
  61. package/src/adapters/cua/bench-run.yaml +32 -0
  62. package/src/adapters/godot/project-run.yaml +31 -0
  63. package/src/adapters/godot/scene-export.yaml +39 -0
  64. package/src/adapters/hermes/sessions-search.yaml +61 -0
  65. package/src/adapters/hermes/skills-list.yaml +30 -0
  66. package/src/adapters/hermes/skills-read.yaml +46 -0
  67. package/src/adapters/motion-studio/component-get.yaml +35 -0
  68. package/src/adapters/openharness/memory-read.yaml +51 -0
  69. package/src/adapters/openharness/skills-list.yaml +28 -0
  70. package/src/adapters/renderdoc/capture-list.yaml +42 -0
  71. package/src/adapters/renderdoc/frame-export.yaml +32 -0
  72. package/src/adapters/stagehand/wrap-observe.yaml +42 -0
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Eval harness — declarative regression suite for adapters.
3
+ *
4
+ * unicli eval list # list available evals
5
+ * unicli eval run smoke/bilibili # run one eval file
6
+ * unicli eval run --all smoke/ # run a directory
7
+ * unicli eval ci --since 7d # run only adapters touched in N days
8
+ *
9
+ * Eval files are YAML, located at:
10
+ * - `evals/` (bundled with the npm package)
11
+ * - `~/.unicli/evals/` (user-local)
12
+ *
13
+ * Format:
14
+ * name: bilibili-smoke
15
+ * adapter: bilibili
16
+ * cases:
17
+ * - command: rank
18
+ * args: {}
19
+ * judges:
20
+ * - { type: arrayMinLength, path: data, min: 5 }
21
+ * - { type: contains, field: data[0].title, value: "" }
22
+ *
23
+ * Why this exists:
24
+ * v0.207 shipped the eval *primitive* (`src/engine/repair/eval.ts`).
25
+ * v0.208 ships the *content*: a starter catalog so the self-repair loop
26
+ * has measurable baselines. Without baselines, claimed improvements are
27
+ * noise. The CLI command is the on-ramp; the YAML files are the data.
28
+ */
29
+ import type { Command } from "commander";
30
+ /** Bundled evals ship in the package — resolved relative to dist/src. */
31
+ declare const BUNDLED_EVALS_DIR: string;
32
+ declare const USER_EVALS_DIR: string;
33
+ export interface EvalCase {
34
+ command: string;
35
+ args?: Record<string, string | number | boolean>;
36
+ /** Optional pre-canned positional values */
37
+ positional?: Array<string | number>;
38
+ judges: Judge[];
39
+ }
40
+ export type Judge = {
41
+ type: "arrayMinLength";
42
+ path?: string;
43
+ min: number;
44
+ } | {
45
+ type: "contains";
46
+ field?: string;
47
+ value: string;
48
+ } | {
49
+ type: "nonEmpty";
50
+ } | {
51
+ type: "matchesPattern";
52
+ pattern: string;
53
+ } | {
54
+ type: "exitCode";
55
+ equals: number;
56
+ };
57
+ export interface EvalFile {
58
+ name: string;
59
+ adapter: string;
60
+ description?: string;
61
+ cases: EvalCase[];
62
+ }
63
+ export interface CaseResult {
64
+ case: EvalCase;
65
+ passed: boolean;
66
+ output?: string;
67
+ exitCode?: number;
68
+ error?: string;
69
+ judgeResults: Array<{
70
+ judge: Judge;
71
+ passed: boolean;
72
+ reason?: string;
73
+ }>;
74
+ }
75
+ export interface EvalRunResult {
76
+ file: EvalFile;
77
+ passed: number;
78
+ total: number;
79
+ cases: CaseResult[];
80
+ }
81
+ /** Return every eval file path discovered across bundled + user directories. */
82
+ export declare function discoverEvalFiles(): Array<{
83
+ path: string;
84
+ relative: string;
85
+ }>;
86
+ /** Load + parse one eval file. Throws on YAML errors so callers can report. */
87
+ export declare function loadEvalFile(file: string): EvalFile;
88
+ /**
89
+ * Apply one judge to a (parsed JSON) output. The output may be an array
90
+ * (Uni-CLI's normal shape) or an object (less common). The judge logic
91
+ * intentionally treats both shapes uniformly via path resolution.
92
+ */
93
+ export declare function applyJudge(parsedOutput: unknown, rawOutput: string, exitCode: number, judge: Judge): {
94
+ passed: boolean;
95
+ reason?: string;
96
+ };
97
+ export declare function runCase(adapter: string, c: EvalCase, options?: {
98
+ timeout?: number;
99
+ cliCommand?: string;
100
+ }): CaseResult;
101
+ export declare function runEvalFile(file: EvalFile, options?: {
102
+ timeout?: number;
103
+ cliCommand?: string;
104
+ }): EvalRunResult;
105
+ export declare function registerEvalCommand(program: Command): void;
106
+ export { BUNDLED_EVALS_DIR, USER_EVALS_DIR };
107
+ /**
108
+ * Helper used only by tests: ensure user evals directory exists. Not used
109
+ * by production code paths.
110
+ */
111
+ export declare function ensureUserEvalsDir(): string;
112
+ //# sourceMappingURL=eval.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eval.d.ts","sourceRoot":"","sources":["../../src/commands/eval.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,485 @@
1
+ /**
2
+ * Eval harness — declarative regression suite for adapters.
3
+ *
4
+ * unicli eval list # list available evals
5
+ * unicli eval run smoke/bilibili # run one eval file
6
+ * unicli eval run --all smoke/ # run a directory
7
+ * unicli eval ci --since 7d # run only adapters touched in N days
8
+ *
9
+ * Eval files are YAML, located at:
10
+ * - `evals/` (bundled with the npm package)
11
+ * - `~/.unicli/evals/` (user-local)
12
+ *
13
+ * Format:
14
+ * name: bilibili-smoke
15
+ * adapter: bilibili
16
+ * cases:
17
+ * - command: rank
18
+ * args: {}
19
+ * judges:
20
+ * - { type: arrayMinLength, path: data, min: 5 }
21
+ * - { type: contains, field: data[0].title, value: "" }
22
+ *
23
+ * Why this exists:
24
+ * v0.207 shipped the eval *primitive* (`src/engine/repair/eval.ts`).
25
+ * v0.208 ships the *content*: a starter catalog so the self-repair loop
26
+ * has measurable baselines. Without baselines, claimed improvements are
27
+ * noise. The CLI command is the on-ramp; the YAML files are the data.
28
+ */
29
+ import { readFileSync, readdirSync, existsSync, statSync, mkdirSync, } from "node:fs";
30
+ import { join, resolve, dirname, basename, extname, relative } from "node:path";
31
+ import { homedir } from "node:os";
32
+ import { fileURLToPath } from "node:url";
33
+ import { spawnSync } from "node:child_process";
34
+ import yaml from "js-yaml";
35
+ import chalk from "chalk";
36
+ const __dirname = dirname(fileURLToPath(import.meta.url));
37
+ /** Bundled evals ship in the package — resolved relative to dist/src. */
38
+ const BUNDLED_EVALS_DIR = join(__dirname, "..", "..", "evals");
39
+ const USER_EVALS_DIR = join(homedir(), ".unicli", "evals");
40
+ // ── Discovery ───────────────────────────────────────────────────────────────
41
+ /** Walk a directory recursively and return all .yaml/.yml file paths. */
42
+ function walkEvalDir(dir) {
43
+ if (!existsSync(dir))
44
+ return [];
45
+ const out = [];
46
+ const stack = [dir];
47
+ while (stack.length) {
48
+ const current = stack.pop();
49
+ for (const entry of readdirSync(current)) {
50
+ const full = join(current, entry);
51
+ const st = statSync(full);
52
+ if (st.isDirectory()) {
53
+ stack.push(full);
54
+ }
55
+ else if (extname(entry) === ".yaml" || extname(entry) === ".yml") {
56
+ out.push(full);
57
+ }
58
+ }
59
+ }
60
+ return out;
61
+ }
62
+ /** Return every eval file path discovered across bundled + user directories. */
63
+ export function discoverEvalFiles() {
64
+ const result = [];
65
+ for (const root of [BUNDLED_EVALS_DIR, USER_EVALS_DIR]) {
66
+ for (const file of walkEvalDir(root)) {
67
+ result.push({
68
+ path: file,
69
+ relative: relative(root, file).replace(/\.(yaml|yml)$/, ""),
70
+ });
71
+ }
72
+ }
73
+ return result;
74
+ }
75
+ /** Load + parse one eval file. Throws on YAML errors so callers can report. */
76
+ export function loadEvalFile(file) {
77
+ const raw = readFileSync(file, "utf-8");
78
+ const parsed = yaml.load(raw);
79
+ if (!parsed.name || !parsed.adapter || !Array.isArray(parsed.cases)) {
80
+ throw new Error(`Invalid eval file ${file}: missing one of name/adapter/cases`);
81
+ }
82
+ return parsed;
83
+ }
84
+ // ── Judge engine ────────────────────────────────────────────────────────────
85
+ /**
86
+ * Read a dotted path out of a JSON-like value, supporting `[N]` array
87
+ * subscripts. Returns undefined if any segment misses.
88
+ *
89
+ * pickPath({a:{b:[{c:1},{c:2}]}}, "a.b[1].c") → 2
90
+ */
91
+ function pickPath(value, path) {
92
+ if (!path)
93
+ return value;
94
+ const tokens = path.split(/[.[\]]+/).filter(Boolean);
95
+ let current = value;
96
+ for (const tok of tokens) {
97
+ if (current === null || current === undefined)
98
+ return undefined;
99
+ if (/^\d+$/.test(tok)) {
100
+ const idx = parseInt(tok, 10);
101
+ if (!Array.isArray(current))
102
+ return undefined;
103
+ current = current[idx];
104
+ }
105
+ else {
106
+ if (typeof current !== "object")
107
+ return undefined;
108
+ current = current[tok];
109
+ }
110
+ }
111
+ return current;
112
+ }
113
+ /**
114
+ * Apply one judge to a (parsed JSON) output. The output may be an array
115
+ * (Uni-CLI's normal shape) or an object (less common). The judge logic
116
+ * intentionally treats both shapes uniformly via path resolution.
117
+ */
118
+ export function applyJudge(parsedOutput, rawOutput, exitCode, judge) {
119
+ switch (judge.type) {
120
+ case "exitCode":
121
+ return {
122
+ passed: exitCode === judge.equals,
123
+ reason: `exit ${exitCode} vs expected ${judge.equals}`,
124
+ };
125
+ case "nonEmpty":
126
+ return {
127
+ passed: rawOutput.trim().length > 0,
128
+ reason: rawOutput.trim().length > 0 ? undefined : "output empty",
129
+ };
130
+ case "matchesPattern":
131
+ try {
132
+ return {
133
+ passed: new RegExp(judge.pattern).test(rawOutput),
134
+ reason: undefined,
135
+ };
136
+ }
137
+ catch {
138
+ return { passed: false, reason: `bad regex ${judge.pattern}` };
139
+ }
140
+ case "contains": {
141
+ const target = judge.field
142
+ ? pickPath(parsedOutput, judge.field)
143
+ : rawOutput;
144
+ const haystack = typeof target === "string" ? target : JSON.stringify(target);
145
+ return {
146
+ passed: haystack !== undefined && haystack.includes(judge.value),
147
+ reason: undefined,
148
+ };
149
+ }
150
+ case "arrayMinLength": {
151
+ const target = judge.path
152
+ ? pickPath(parsedOutput, judge.path)
153
+ : parsedOutput;
154
+ if (!Array.isArray(target)) {
155
+ return {
156
+ passed: false,
157
+ reason: `path ${judge.path ?? "(root)"} not array`,
158
+ };
159
+ }
160
+ return {
161
+ passed: target.length >= judge.min,
162
+ reason: target.length >= judge.min
163
+ ? undefined
164
+ : `${target.length} < ${judge.min}`,
165
+ };
166
+ }
167
+ }
168
+ }
169
+ // ── Runner ──────────────────────────────────────────────────────────────────
170
+ /**
171
+ * Run one case by shelling out to `unicli <adapter> <command> --format json`.
172
+ * The shell-out path is intentional — we test the same surface area users
173
+ * (and agents) hit, including the formatter and the exit code.
174
+ *
175
+ * Why exec rather than calling runPipeline directly?
176
+ * - Eval is a regression harness. If runPipeline drifts behind the CLI's
177
+ * argument parsing, an in-process call would mask the bug.
178
+ * - The bundled `unicli` script may not exist in dev; in that case the
179
+ * runner falls back to `npx tsx src/main.ts`.
180
+ */
181
+ function buildCliInvocation(adapter, c) {
182
+ const args = [adapter, c.command];
183
+ if (c.positional) {
184
+ for (const p of c.positional)
185
+ args.push(String(p));
186
+ }
187
+ for (const [k, v] of Object.entries(c.args ?? {})) {
188
+ args.push(`--${k}`, String(v));
189
+ }
190
+ args.push("--format", "json");
191
+ return args;
192
+ }
193
+ /**
194
+ * Parse a CLI command string into [executable, ...prefixArgs]. Supports the
195
+ * common case where `UNICLI_BIN` is a single word ("unicli") and the less
196
+ * common case where it's a dev invocation ("npx tsx src/main.ts"). Tokens
197
+ * are split on whitespace — we do NOT attempt to honor shell quoting rules,
198
+ * because that would reintroduce the class of bugs this function exists to
199
+ * prevent. If you need spaces in the executable path, move the quoted parts
200
+ * into a wrapper script instead.
201
+ */
202
+ function parseCliCommand(cliCommand) {
203
+ const tokens = cliCommand.trim().split(/\s+/).filter(Boolean);
204
+ if (tokens.length === 0) {
205
+ return { executable: "unicli", prefixArgs: [] };
206
+ }
207
+ return { executable: tokens[0], prefixArgs: tokens.slice(1) };
208
+ }
209
+ export function runCase(adapter, c, options = {}) {
210
+ const timeout = options.timeout ?? 30_000;
211
+ const cliCommand = options.cliCommand ?? process.env.UNICLI_BIN ?? "unicli";
212
+ const { executable, prefixArgs } = parseCliCommand(cliCommand);
213
+ const cliArgs = buildCliInvocation(adapter, c);
214
+ let rawOutput = "";
215
+ let exitCode = 0;
216
+ let runErr;
217
+ // spawnSync takes an argv array, so nothing in the args passes through a
218
+ // shell. Positional values with spaces, quotes, or shell metachars
219
+ // (`;`, `$(...)`, backticks) are literal argv elements, not shell syntax.
220
+ const result = spawnSync(executable, [...prefixArgs, ...cliArgs], {
221
+ encoding: "utf-8",
222
+ timeout,
223
+ stdio: ["ignore", "pipe", "pipe"],
224
+ // Prevent child from inheriting stdin, and capture both stdout + stderr.
225
+ });
226
+ if (result.error) {
227
+ runErr = result.error.message;
228
+ exitCode = 1;
229
+ }
230
+ else {
231
+ rawOutput = typeof result.stdout === "string" ? result.stdout : "";
232
+ exitCode = result.status ?? 1;
233
+ if (exitCode !== 0 && result.stderr) {
234
+ runErr = String(result.stderr);
235
+ }
236
+ }
237
+ let parsedOutput;
238
+ try {
239
+ parsedOutput = JSON.parse(rawOutput);
240
+ }
241
+ catch {
242
+ parsedOutput = undefined;
243
+ }
244
+ const judgeResults = c.judges.map((j) => {
245
+ const r = applyJudge(parsedOutput, rawOutput, exitCode, j);
246
+ return { judge: j, passed: r.passed, reason: r.reason };
247
+ });
248
+ const passed = judgeResults.every((r) => r.passed);
249
+ return {
250
+ case: c,
251
+ passed,
252
+ output: rawOutput.slice(0, 2000),
253
+ exitCode,
254
+ error: runErr,
255
+ judgeResults,
256
+ };
257
+ }
258
+ export function runEvalFile(file, options = {}) {
259
+ const cases = [];
260
+ let passed = 0;
261
+ for (const c of file.cases) {
262
+ const r = runCase(file.adapter, c, options);
263
+ cases.push(r);
264
+ if (r.passed)
265
+ passed++;
266
+ }
267
+ return {
268
+ file,
269
+ passed,
270
+ total: file.cases.length,
271
+ cases,
272
+ };
273
+ }
274
+ export function registerEvalCommand(program) {
275
+ const evalCmd = program
276
+ .command("eval")
277
+ .description("Run declarative eval suites against adapters");
278
+ evalCmd
279
+ .command("list")
280
+ .description("List discovered eval files (bundled + ~/.unicli/evals/)")
281
+ .option("--json", "Output as JSON")
282
+ .action((opts) => {
283
+ const files = discoverEvalFiles();
284
+ if (opts.json) {
285
+ console.log(JSON.stringify(files.map((f) => ({ name: f.relative, path: f.path })), null, 2));
286
+ return;
287
+ }
288
+ console.log(chalk.bold(`${files.length} eval file(s):`));
289
+ for (const f of files) {
290
+ console.log(` ${chalk.cyan(f.relative)} ${chalk.dim(f.path)}`);
291
+ }
292
+ });
293
+ evalCmd
294
+ .command("run [target]")
295
+ .description("Run one eval file or a directory (use with --all). target may be relative or absolute.")
296
+ .option("--all", "Run all evals in the target directory recursively")
297
+ .option("--timeout <ms>", "Per-case timeout", "30000")
298
+ .option("--cli <command>", "CLI command to test (default: unicli)")
299
+ .option("--json", "Output as JSON")
300
+ .action(async (target, opts) => {
301
+ const cliCommand = opts.cli ?? process.env.UNICLI_BIN ?? "unicli";
302
+ const timeout = parseInt(opts.timeout ?? "30000", 10) || 30_000;
303
+ const filesToRun = [];
304
+ const all = discoverEvalFiles();
305
+ if (!target) {
306
+ if (!opts.all) {
307
+ console.error(chalk.red("Specify a target or pass --all."));
308
+ process.exit(2);
309
+ }
310
+ filesToRun.push(...all.map((f) => f.path));
311
+ }
312
+ else if (opts.all) {
313
+ // Treat target as a directory. Two cases:
314
+ // 1. Relative name like "smoke" or "smoke/" → match f.relative prefix
315
+ // 2. Absolute or file:// path → resolve and match f.path prefix
316
+ const resolvedTarget = resolve(target);
317
+ const isExistingAbs = target.startsWith("/") || target.startsWith("~/");
318
+ for (const f of all) {
319
+ const relativeMatch = f.relative === target ||
320
+ f.relative.startsWith(`${target.replace(/\/$/, "")}/`);
321
+ const absoluteMatch = isExistingAbs &&
322
+ (f.path === resolvedTarget ||
323
+ f.path.startsWith(`${resolvedTarget.replace(/\/$/, "")}/`));
324
+ if (relativeMatch || absoluteMatch) {
325
+ filesToRun.push(f.path);
326
+ }
327
+ }
328
+ }
329
+ else {
330
+ // Treat target as a file (with or without extension)
331
+ const candidate = all.find((f) => f.relative === target ||
332
+ f.relative === target.replace(/\.(yaml|yml)$/, ""));
333
+ if (candidate) {
334
+ filesToRun.push(candidate.path);
335
+ }
336
+ else if (existsSync(resolve(target))) {
337
+ filesToRun.push(resolve(target));
338
+ }
339
+ }
340
+ if (filesToRun.length === 0) {
341
+ console.error(chalk.red(`No eval files matched: ${target ?? "(none)"}`));
342
+ process.exit(2);
343
+ }
344
+ let passedTotal = 0;
345
+ let totalTotal = 0;
346
+ const fileResults = [];
347
+ for (const path of filesToRun) {
348
+ let evalFile;
349
+ try {
350
+ evalFile = loadEvalFile(path);
351
+ }
352
+ catch (err) {
353
+ console.error(chalk.red(`Failed to load ${path}: ${err.message}`));
354
+ continue;
355
+ }
356
+ const result = runEvalFile(evalFile, { timeout, cliCommand });
357
+ fileResults.push(result);
358
+ passedTotal += result.passed;
359
+ totalTotal += result.total;
360
+ if (!opts.json) {
361
+ const ratio = `${result.passed}/${result.total}`;
362
+ const tag = result.passed === result.total
363
+ ? chalk.green(ratio)
364
+ : chalk.red(ratio);
365
+ console.log(` ${tag} ${basename(path)} (${evalFile.adapter})`);
366
+ for (const c of result.cases) {
367
+ const dot = c.passed ? chalk.green("✓") : chalk.red("✗");
368
+ console.log(` ${dot} ${c.case.command}`);
369
+ if (!c.passed) {
370
+ for (const j of c.judgeResults.filter((j) => !j.passed)) {
371
+ console.log(` ${chalk.red("·")} ${j.judge.type} — ${j.reason ?? "fail"}`);
372
+ }
373
+ }
374
+ }
375
+ }
376
+ }
377
+ if (opts.json) {
378
+ console.log(JSON.stringify({
379
+ score: passedTotal,
380
+ total: totalTotal,
381
+ files: fileResults.map((r) => ({
382
+ name: r.file.name,
383
+ adapter: r.file.adapter,
384
+ passed: r.passed,
385
+ total: r.total,
386
+ cases: r.cases.map((c) => ({
387
+ command: c.case.command,
388
+ passed: c.passed,
389
+ exit: c.exitCode,
390
+ failures: c.judgeResults
391
+ .filter((j) => !j.passed)
392
+ .map((j) => ({ judge: j.judge.type, reason: j.reason })),
393
+ })),
394
+ })),
395
+ }, null, 2));
396
+ }
397
+ else {
398
+ console.log();
399
+ console.log(chalk.bold(`SCORE=${passedTotal}/${totalTotal}`));
400
+ }
401
+ // Exit non-zero on any failure for CI integration
402
+ process.exit(passedTotal === totalTotal ? 0 : 1);
403
+ });
404
+ evalCmd
405
+ .command("ci")
406
+ .description("Run evals for adapters touched within a recent git window")
407
+ .option("--since <window>", "Window (e.g. 7d, 24h)", "7d")
408
+ .option("--json", "Output as JSON")
409
+ .action((opts) => {
410
+ // Best-effort: list adapters changed in the window via `git log`. We
411
+ // intentionally tolerate non-git workspaces by skipping the filter.
412
+ // `since` is passed as an argv element, not interpolated into a shell
413
+ // string, so hostile values cannot escape into git or sh.
414
+ const since = opts.since ?? "7d";
415
+ const touchedAdapters = new Set();
416
+ // Validate `since` matches a safe shape before passing to git — git
417
+ // accepts a wide range of time specs, but we restrict to digits + unit
418
+ // letters to avoid surprising behavior from pathological input.
419
+ if (/^[0-9]+(d|h|m|s|w)?$|^[0-9]{4}-[0-9]{2}-[0-9]{2}$/.test(since)) {
420
+ const git = spawnSync("git", [
421
+ "log",
422
+ `--since=${since}`,
423
+ "--name-only",
424
+ "--pretty=format:",
425
+ "--",
426
+ "src/adapters",
427
+ ], { encoding: "utf-8", stdio: ["ignore", "pipe", "ignore"] });
428
+ if (!git.error && git.status === 0) {
429
+ const out = typeof git.stdout === "string" ? git.stdout : "";
430
+ for (const line of out.split("\n")) {
431
+ const m = line.match(/^src\/adapters\/([^/]+)\//);
432
+ if (m)
433
+ touchedAdapters.add(m[1]);
434
+ }
435
+ }
436
+ }
437
+ const all = discoverEvalFiles();
438
+ const filtered = touchedAdapters.size > 0
439
+ ? all.filter((f) => {
440
+ try {
441
+ const file = loadEvalFile(f.path);
442
+ return touchedAdapters.has(file.adapter);
443
+ }
444
+ catch {
445
+ return false;
446
+ }
447
+ })
448
+ : [];
449
+ if (filtered.length === 0) {
450
+ if (opts.json) {
451
+ console.log(JSON.stringify({ matched: 0, score: 0, total: 0 }));
452
+ }
453
+ else {
454
+ console.log(chalk.dim(`No evals match adapters touched in the last ${since}. Skipping.`));
455
+ }
456
+ process.exit(0);
457
+ }
458
+ let passed = 0;
459
+ let total = 0;
460
+ for (const f of filtered) {
461
+ const file = loadEvalFile(f.path);
462
+ const r = runEvalFile(file);
463
+ passed += r.passed;
464
+ total += r.total;
465
+ }
466
+ if (opts.json) {
467
+ console.log(JSON.stringify({ matched: filtered.length, score: passed, total }));
468
+ }
469
+ else {
470
+ console.log(chalk.bold(`SCORE=${passed}/${total}`));
471
+ }
472
+ process.exit(passed === total ? 0 : 1);
473
+ });
474
+ }
475
+ // Re-export for tests / programmatic use
476
+ export { BUNDLED_EVALS_DIR, USER_EVALS_DIR };
477
+ /**
478
+ * Helper used only by tests: ensure user evals directory exists. Not used
479
+ * by production code paths.
480
+ */
481
+ export function ensureUserEvalsDir() {
482
+ mkdirSync(USER_EVALS_DIR, { recursive: true });
483
+ return USER_EVALS_DIR;
484
+ }
485
+ //# sourceMappingURL=eval.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eval.js","sourceRoot":"","sources":["../../src/commands/eval.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * MCP gateway CLI — wrapper around src/mcp/server.ts.
3
+ *
4
+ * unicli mcp serve [--transport stdio|http] [--port 19826] [--lazy]
5
+ * unicli mcp health # list registered tools (no server)
6
+ *
7
+ * `serve` shells out to the same `src/mcp/server.ts` entry point as
8
+ * `npm run mcp` so the two paths share exactly one implementation.
9
+ *
10
+ * `health` is intentionally fast and offline: it loads adapters into the
11
+ * registry and prints the same tool list the server would build, without
12
+ * binding stdio or HTTP. Useful as a Claude Desktop / Cursor pre-flight.
13
+ */
14
+ import type { Command } from "commander";
15
+ export declare function registerMcpCommand(program: Command): void;
16
+ //# sourceMappingURL=mcp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../src/commands/mcp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA0CzC,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA+GzD"}