@eigenpal/cli 0.4.17 → 0.5.2

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/cli.js CHANGED
@@ -1019,7 +1019,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
1019
1019
  this._exitCallback = (err) => {
1020
1020
  if (err.code !== "commander.executeSubCommandAsync") {
1021
1021
  throw err;
1022
- } else {}
1022
+ }
1023
1023
  };
1024
1024
  }
1025
1025
  return this;
@@ -20343,7 +20343,7 @@ function finalize(ctx, schema) {
20343
20343
  result.$schema = "http://json-schema.org/draft-07/schema#";
20344
20344
  } else if (ctx.target === "draft-04") {
20345
20345
  result.$schema = "http://json-schema.org/draft-04/schema#";
20346
- } else if (ctx.target === "openapi-3.0") {} else {}
20346
+ } else if (ctx.target === "openapi-3.0") {}
20347
20347
  if (ctx.external?.uri) {
20348
20348
  const id = ctx.external.registry.get(schema)?.id;
20349
20349
  if (!id)
@@ -20604,7 +20604,7 @@ var formatMap, stringProcessor = (schema, ctx, _json, _params) => {
20604
20604
  if (val === undefined) {
20605
20605
  if (ctx.unrepresentable === "throw") {
20606
20606
  throw new Error("Literal `undefined` cannot be represented in JSON Schema");
20607
- } else {}
20607
+ }
20608
20608
  } else if (typeof val === "bigint") {
20609
20609
  if (ctx.unrepresentable === "throw") {
20610
20610
  throw new Error("BigInt literals cannot be represented in JSON Schema");
@@ -27388,7 +27388,7 @@ var require_tracestate_impl = __commonJS((exports) => {
27388
27388
  const value = listMember.slice(i + 1, part.length);
27389
27389
  if ((0, tracestate_validators_1.validateKey)(key) && (0, tracestate_validators_1.validateValue)(value)) {
27390
27390
  agg.set(key, value);
27391
- } else {}
27391
+ }
27392
27392
  }
27393
27393
  return agg;
27394
27394
  }, new Map);
@@ -67182,72 +67182,6 @@ var init_workflow = __esm(() => {
67182
67182
  });
67183
67183
  });
67184
67184
 
67185
- // ../types/src/workflow/eval-config.ts
67186
- function parseEvalConfig(raw) {
67187
- return EvalConfigSchema.parse(raw ?? {});
67188
- }
67189
- function parseEvalConfigForForm(raw) {
67190
- return EvalConfigFormSchema.parse(raw ?? {});
67191
- }
67192
- function isValidJudgeModel(model) {
67193
- return JUDGE_MODEL_IDS.includes(model);
67194
- }
67195
- function resolveConcurrency(value, defaultNum) {
67196
- const clamp = (n) => Math.min(MAX_CONCURRENCY, Math.max(1, n));
67197
- if (value == null) {
67198
- const d2 = clamp(defaultNum);
67199
- return { executions: d2, judge: d2 };
67200
- }
67201
- if (typeof value === "number") {
67202
- const d2 = clamp(value);
67203
- return { executions: d2, judge: d2 };
67204
- }
67205
- return {
67206
- executions: clamp(value.executions ?? defaultNum),
67207
- judge: clamp(value.judge ?? defaultNum)
67208
- };
67209
- }
67210
- var JUDGE_MODEL_IDS, JudgeModelSchema, DEFAULT_JUDGE_MODEL = "gpt-5.2", DEFAULT_CONCURRENCY = 3, ConcurrencySchema, JudgeConfigSchema, JudgeConfigFormSchema, EvalConfigSchema, EvalConfigFormSchema, MAX_CONCURRENCY = 50, EVAL_CONFIG_FORM_KEYS, EVAL_CONFIG_FIELD_DEFINITIONS;
67211
- var init_eval_config = __esm(() => {
67212
- init_zod();
67213
- JUDGE_MODEL_IDS = ["gpt-4o", "gpt-4o-mini", "gpt-5.2"];
67214
- JudgeModelSchema = exports_external.enum(JUDGE_MODEL_IDS);
67215
- ConcurrencySchema = exports_external.union([
67216
- exports_external.number().int().min(1),
67217
- exports_external.object({
67218
- executions: exports_external.number().int().min(1),
67219
- judge: exports_external.number().int().min(1)
67220
- })
67221
- ]);
67222
- JudgeConfigSchema = exports_external.object({
67223
- prompt: exports_external.string().default(""),
67224
- model: JudgeModelSchema.default(DEFAULT_JUDGE_MODEL),
67225
- run: exports_external.boolean().default(true)
67226
- });
67227
- JudgeConfigFormSchema = exports_external.object({
67228
- prompt: exports_external.string().default(""),
67229
- model: exports_external.string().default(DEFAULT_JUDGE_MODEL),
67230
- run: exports_external.boolean().default(true)
67231
- });
67232
- EvalConfigSchema = exports_external.object({
67233
- concurrency: ConcurrencySchema.default(DEFAULT_CONCURRENCY),
67234
- judge: JudgeConfigSchema.prefault({}),
67235
- defaultOverrides: exports_external.array(exports_external.string()).default([])
67236
- });
67237
- EvalConfigFormSchema = exports_external.object({
67238
- concurrency: ConcurrencySchema.default(DEFAULT_CONCURRENCY),
67239
- judge: JudgeConfigFormSchema.prefault({}),
67240
- defaultOverrides: exports_external.array(exports_external.string()).default([])
67241
- });
67242
- EVAL_CONFIG_FORM_KEYS = ["judge"];
67243
- EVAL_CONFIG_FIELD_DEFINITIONS = {
67244
- judge: {
67245
- label: "AI review",
67246
- description: "Optional automated check: an AI compares each run to the expected result using your instructions."
67247
- }
67248
- };
67249
- });
67250
-
67251
67185
  // ../types/src/workflow/expected-output.ts
67252
67186
  var ExpectedDocumentRefSchema, ExpectedDocumentsValueSchema, ExpectedOutputSchema, ExpectedOutputFilesSchema;
67253
67187
  var init_expected_output = __esm(() => {
@@ -67464,7 +67398,6 @@ var init_workflow2 = __esm(() => {
67464
67398
  init_actions();
67465
67399
  init_steps();
67466
67400
  init_workflow();
67467
- init_eval_config();
67468
67401
  init_expected_output();
67469
67402
  init_local_meta();
67470
67403
  init_email_trigger();
@@ -68378,12 +68311,9 @@ __export(exports_src, {
68378
68311
  runInputKey: () => runInputKey,
68379
68312
  rootS3Path: () => rootS3Path,
68380
68313
  resolveEffectiveMimeType: () => resolveEffectiveMimeType,
68381
- resolveConcurrency: () => resolveConcurrency,
68382
68314
  requiresSpecializedParser: () => requiresSpecializedParser,
68383
68315
  parseStepType: () => parseStepType,
68384
68316
  parseFileKey: () => parseFileKey,
68385
- parseEvalConfigForForm: () => parseEvalConfigForForm,
68386
- parseEvalConfig: () => parseEvalConfig,
68387
68317
  noopTracingContext: () => noopTracingContext,
68388
68318
  mapOCRAttributes: () => mapOCRAttributes,
68389
68319
  mapLLMAttributes: () => mapLLMAttributes,
@@ -68393,7 +68323,6 @@ __export(exports_src, {
68393
68323
  judgeScoreJson: () => judgeScoreJson,
68394
68324
  judgeLabelJson: () => judgeLabelJson,
68395
68325
  isWorkflowResult: () => isWorkflowResult,
68396
- isValidJudgeModel: () => isValidJudgeModel,
68397
68326
  isTerminalExecutionStatus: () => isTerminalExecutionStatus,
68398
68327
  isStepCategory: () => isStepCategory,
68399
68328
  isOutputSchemaUnknown: () => isOutputSchemaUnknown,
@@ -68546,10 +68475,8 @@ __export(exports_src, {
68546
68475
  LayoutElementTypeSchema: () => LayoutElementTypeSchema,
68547
68476
  LayoutElementSchema: () => LayoutElementSchema,
68548
68477
  LLM_JUDGE_PROMPT_MIN_LENGTH: () => LLM_JUDGE_PROMPT_MIN_LENGTH,
68549
- JudgeModelSchema: () => JudgeModelSchema,
68550
68478
  JudgeModeSchema: () => JudgeModeSchema,
68551
68479
  JsonSchemaSchema: () => JsonSchemaSchema,
68552
- JUDGE_MODEL_IDS: () => JUDGE_MODEL_IDS,
68553
68480
  IfStepSchema: () => IfStepSchema,
68554
68481
  INPUT_KINDS: () => INPUT_KINDS,
68555
68482
  ID_PREFIXES: () => ID_PREFIXES,
@@ -68582,7 +68509,6 @@ __export(exports_src, {
68582
68509
  EvalOverridesSchema: () => EvalOverridesSchema,
68583
68510
  EvalExampleMetaSchema: () => EvalExampleMetaSchema,
68584
68511
  EvalConfigYamlSchema: () => EvalConfigYamlSchema,
68585
- EvalConfigSchema: () => EvalConfigSchema,
68586
68512
  EmailTriggerMethodSchema: () => EmailTriggerMethodSchema,
68587
68513
  Eigenpal: () => Eigenpal,
68588
68514
  EXECUTION_TYPES: () => EXECUTION_TYPES,
@@ -68596,8 +68522,6 @@ __export(exports_src, {
68596
68522
  EXECUTION_AGENT_QUEUED_STATUSES: () => EXECUTION_AGENT_QUEUED_STATUSES,
68597
68523
  EXECUTION_AGENT_METRICS_STATUSES: () => EXECUTION_AGENT_METRICS_STATUSES,
68598
68524
  EXECUTION_AGENT_CANCEL_REQUESTABLE_STATUSES: () => EXECUTION_AGENT_CANCEL_REQUESTABLE_STATUSES,
68599
- EVAL_CONFIG_FORM_KEYS: () => EVAL_CONFIG_FORM_KEYS,
68600
- EVAL_CONFIG_FIELD_DEFINITIONS: () => EVAL_CONFIG_FIELD_DEFINITIONS,
68601
68525
  ERROR_HINTS: () => ERROR_HINTS,
68602
68526
  DocumentParserOutputSchema: () => DocumentParserOutputSchema,
68603
68527
  DocumentParserInputSchema: () => DocumentParserInputSchema,
@@ -68610,7 +68534,6 @@ __export(exports_src, {
68610
68534
  DURABLE_EXECUTION_TYPES: () => DURABLE_EXECUTION_TYPES,
68611
68535
  DETERMINISTIC_TEMPERATURE: () => DETERMINISTIC_TEMPERATURE,
68612
68536
  DEFAULT_PAGE_SIZE: () => DEFAULT_PAGE_SIZE,
68613
- DEFAULT_CONCURRENCY: () => DEFAULT_CONCURRENCY,
68614
68537
  DATASET_NAME_PATTERN: () => DATASET_NAME_PATTERN,
68615
68538
  CustomScriptConfigSchema: () => CustomScriptConfigSchema,
68616
68539
  CreateWorkflowDefinitionSchema: () => CreateWorkflowDefinitionSchema,
@@ -181229,7 +181152,7 @@ import { fileURLToPath as fileURLToPath6 } from "url";
181229
181152
  // package.json
181230
181153
  var package_default = {
181231
181154
  name: "@eigenpal/cli",
181232
- version: "0.4.17",
181155
+ version: "0.5.2",
181233
181156
  description: "Eigenpal CLI — author and run document workflows from your terminal. Agent-ready.",
181234
181157
  keywords: [
181235
181158
  "eigenpal",
@@ -181304,7 +181227,9 @@ var package_default = {
181304
181227
 
181305
181228
  // src/commands/agent.ts
181306
181229
  var import_yaml = __toESM(require_dist(), 1);
181307
- import { existsSync as existsSync2, promises as fs } from "node:fs";
181230
+ import { spawnSync } from "node:child_process";
181231
+ import { createHash } from "node:crypto";
181232
+ import { existsSync as existsSync2, promises as fs, readFileSync as readFileSync2 } from "node:fs";
181308
181233
  import path from "node:path";
181309
181234
  import { createInterface } from "node:readline/promises";
181310
181235
 
@@ -181387,6 +181312,15 @@ class ApiClient {
181387
181312
  });
181388
181313
  return this.handleResponse(res, url);
181389
181314
  }
181315
+ async put(path, body) {
181316
+ const url = `${this.baseUrl}${path}`;
181317
+ const res = await fetch(url, {
181318
+ method: "PUT",
181319
+ headers: this.headers({ "Content-Type": "application/json" }),
181320
+ body: body !== undefined ? JSON.stringify(body) : undefined
181321
+ });
181322
+ return this.handleResponse(res, url);
181323
+ }
181390
181324
  async patch(path, body) {
181391
181325
  const url = `${this.baseUrl}${path}`;
181392
181326
  const res = await fetch(url, {
@@ -181948,6 +181882,7 @@ Examples:
181948
181882
  Version flags are intentionally unsupported for agents in this release.
181949
181883
  `).action(action(pushAgent));
181950
181884
  withBaseUrl(agent.command("pull <agent-id-or-slug>")).description("Download an agent project as agent.yaml, agent/, and dataset/.").option("--out <dir>", "Output directory").action(action(pullAgent));
181885
+ registerAgentFileCommands(agent);
181951
181886
  addJsonFlag(agent.command("validate [dir]")).description("Validate a local agent project layout.").action(action(validateAgentCommand));
181952
181887
  registerDatasetCommands(agent);
181953
181888
  registerExecutionCommands(agent);
@@ -181957,6 +181892,16 @@ Version flags are intentionally unsupported for agents in this release.
181957
181892
  registerComingSoon(agent, "evaluators", "Agent evaluators are reserved for future workflow-style evaluators.");
181958
181893
  registerComingSoon(agent, "versions", "Agent versions are coming soon.");
181959
181894
  }
181895
+ function registerAgentFileCommands(agent) {
181896
+ const file2 = agent.command("file").description("List, download, and upload individual live agent files.").action(() => {
181897
+ process.stderr.write("`eigenpal agent file` requires a subcommand. Run `eigenpal agent file --help`.\n");
181898
+ process.exit(2);
181899
+ });
181900
+ addJsonFlag(withBaseUrl(file2.command("list <agent-id-or-slug>"))).description("List live files for an agent.").option("--path <prefix>", "Only list files beneath this relative path").action(action(listAgentFiles));
181901
+ addJsonFlag(withBaseUrl(file2.command("get <agent-id-or-slug> <remote-path>"))).description("Download one live agent file.").option("--out <file>", "Output file path").action(action(getAgentFile));
181902
+ addJsonFlag(withBaseUrl(file2.command("put <agent-id-or-slug> <remote-path> <local-path>"))).description("Upload one local file into the live agent namespace.").option("--dry-run", "Validate local file and remote path without uploading").option("--preview", "Compare remote and local file without uploading").action(action(putAgentFile));
181903
+ addJsonFlag(withBaseUrl(file2.command("diff <agent-id-or-slug> <remote-path> <local-path>"))).description("Compare one live agent file against a local file.").action(action(diffAgentFile));
181904
+ }
181960
181905
  function registerDatasetCommands(agent) {
181961
181906
  const dataset = agent.command("dataset").description("Manage an agent dataset.").action(() => {
181962
181907
  process.stderr.write("`eigenpal agent dataset` requires a subcommand. Run `eigenpal agent dataset --help`.\n");
@@ -181973,8 +181918,24 @@ function registerExecutionCommands(agent) {
181973
181918
  process.exit(2);
181974
181919
  });
181975
181920
  addJsonFlag(withBaseUrl(execution.command("run <agent-id-or-slug>"))).description("Start one agent execution.").option("--input-json <json>", "JSON input object").option("--input-file <path>", "Input file to upload as multipart form-data").option("--wait", "Poll until the execution reaches a terminal status").action(action(runExecution));
181976
- addJsonFlag(withBaseUrl(execution.command("get <execution-id>"))).description("Get one agent execution.").option("--include <parts>", "Comma-separated extra parts, e.g. files").action(action(getExecution));
181977
- addJsonFlag(withPagination(withBaseUrl(execution.command("list <agent-id-or-slug>")), 50)).description("List agent executions.").option("--status <status>", "Filter by status").action(action(listExecutions));
181921
+ addJsonFlag(withBaseUrl(execution.command("get <execution-id>"))).description("Get one agent execution.").option("--include <parts>", "Comma-separated extra parts: feedback,expected,files,trace,issues", "feedback").action(action(getExecution));
181922
+ addJsonFlag(withBaseUrl(execution.command("rerun <execution-id>"))).description("Create a new execution from a previous execution's stored input snapshot.").option("--wait", "Poll until the rerun reaches a terminal status").option("--interval <seconds>", "Polling interval in seconds", intArg, 2).option("--max-wait <seconds>", "Maximum wait before exiting 2", intArg, 1800).action(action(rerunExecution));
181923
+ const list = addJsonFlag(withPagination(withBaseUrl(execution.command("list <agent-id-or-slug>")), 50)).description("List agent executions.").option("--status <status>", "Filter by status").option("--batch-id <id>", "Filter by experiment batch id").option("--example-name <name>", "Filter by exact dataset example name").option("--example-name-contains <q>", "Filter by substring in example name").option("--created-after <time>", "Filter by created-at lower bound").option("--created-before <time>", "Filter by created-at upper bound").option("--completed-after <time>", "Filter by completed-at lower bound").option("--completed-before <time>", "Filter by completed-at upper bound").option("--feedback-status <open|resolved|ignored>", "Filter by feedback status").option("--feedback-rating <pass|fail|partial|none>", "Filter by feedback rating").option("--feedback-body-contains <q>", "Filter by feedback body substring").option("--feedback-created-after <time>", "Filter by feedback created-at lower bound").option("--feedback-created-before <time>", "Filter by feedback created-at upper bound").option("--feedback-updated-after <time>", "Filter by feedback updated-at lower bound").option("--feedback-updated-before <time>", "Filter by feedback updated-at upper bound").option("--feedback-resolved-after <time>", "Filter by feedback resolved-at lower bound").option("--feedback-resolved-before <time>", "Filter by feedback resolved-at upper bound").option("--has-feedback", "Only executions with feedback").option("--no-feedback", "Only executions without feedback").option("--has-expected", "Only executions with expected JSON or files").option("--has-expected-json", "Only executions with expected.json").option("--has-expected-files", "Only executions with expected files").option("--promoted-to-example", "Only executions promoted to dataset examples").option("--promoted-example-name <name>", "Filter by promoted dataset example name").option("--since-last-resolved", "Only executions created after the latest resolved feedback").option("--include <parts>", "Comma-separated extra parts: feedback,expected,files").option("--compact", "Return/print compact triage rows without full output payloads").option("--sort <field>", "Sort by createdAt, completedAt, status, or exampleName").option("--order <asc|desc>", "Sort direction").option("--scan-limit <n>", "Feedback scan window for feedback filters", intArg).action(action(listExecutions));
181924
+ list.addHelpText("after", `
181925
+ Examples:
181926
+ $ eigenpal agent execution list incorporator --feedback-rating fail --since-last-resolved --include feedback,expected
181927
+ $ eigenpal agent execution list activities --has-expected-files --created-after 2026-05-01
181928
+ `);
181929
+ withBaseUrl(execution.command("pull <execution-id>")).description("Download execution feedback, expected artifacts, files, and metadata.").option("--out <dir>", "Output directory").option("--include <parts>", "Comma-separated parts: feedback,expected,files,output,input,metadata,issues,trace,all", "feedback,expected").option("--json", "Output a JSON summary of written artifacts").action(action(pullExecution));
181930
+ addJsonFlag(withBaseUrl(execution.command("compare <reference-execution-id> <execution-id>"))).description("Compare one execution against another execution. PDF/DOCX text comparison uses pdftotext/python3 and reports byte fallbacks.").option("--baseline", "Compare actual outputs from both executions instead of expected artifacts").option("--out <dir>", "Write comparison artifacts to this directory").option("--normalize-dates", "Normalize YYYYMMDD and YYYY-MM-DD tokens in filenames/text").option("--fail-on-diff", "Exit 1 when comparison status is fail").action(action(compareExecution));
181931
+ const artifacts = execution.command("artifacts").description("Inspect execution artifact inventory.").action(() => {
181932
+ process.stderr.write("`eigenpal agent execution artifacts` requires a subcommand. Run `eigenpal agent execution artifacts --help`.\n");
181933
+ process.exit(2);
181934
+ });
181935
+ addJsonFlag(withBaseUrl(artifacts.command("list <execution-id>"))).description("List available execution artifacts without downloading them.").action(action(listExecutionArtifacts));
181936
+ withBaseUrl(execution.command("trace <execution-id>")).description("Print raw trace.jsonl for an execution, or write it with --out.").option("--out <file>", "Output file path").action(action(traceExecution));
181937
+ registerExecutionFeedbackCommands(execution);
181938
+ registerExecutionExpectedCommands(execution);
181978
181939
  addJsonFlag(withBaseUrl(execution.command("watch <execution-id>"))).description("Watch an execution until it reaches a terminal status.").option("--interval <seconds>", "Polling interval in seconds", intArg, 2).option("--max-wait <seconds>", "Maximum wait before exiting 2", intArg, 1800).action(action(watchExecutionCommand));
181979
181940
  addJsonFlag(withBaseUrl(execution.command("cancel <execution-id>"))).description("Cancel an agent execution.").option("--yes", "Required in non-interactive environments").action(action(cancelExecution));
181980
181941
  }
@@ -181990,6 +181951,27 @@ function registerExperimentCommands(agent) {
181990
181951
  addJsonFlag(withBaseUrl(experiment.command("compare <batch-id-a> <batch-id-b>"))).description("Compare two experiment batches.").option("--sort <mode>", "Accepted for compatibility; sorting happens client-side later").option("--regression-threshold <n>", "Accepted for compatibility", intArg).action(action(compareExperiments));
181991
181952
  addJsonFlag(withBaseUrl(experiment.command("cancel <agent-id-or-slug> <batch-id>"))).description("Cancel every active execution in an experiment.").option("--yes", "Required in non-interactive environments").action(action(cancelExperiment));
181992
181953
  }
181954
+ function registerExecutionFeedbackCommands(execution) {
181955
+ const feedback = execution.command("feedback").description("Update or clear feedback attached to an agent execution.").action(() => {
181956
+ process.stderr.write("`eigenpal agent execution feedback` requires a subcommand. Run `eigenpal agent execution feedback --help`.\n");
181957
+ process.exit(2);
181958
+ });
181959
+ addJsonFlag(withBaseUrl(feedback.command("update <execution-id>"))).description("Edit feedback state, rating, message, or expected JSON for an execution.").option("--status <open|resolved|ignored>", "Set feedback status").option("--rating <pass|fail|partial|none>", "Set feedback rating").option("--message <text>", "Set feedback message body").option("--message-file <path>", "Read feedback message body from a file").option("--expected-json <json>", "Set structured expected JSON").option("--expected-json-file <path>", "Read structured expected JSON from a file").option("--clear-message", "Clear the feedback message body").option("--clear-rating", "Clear feedback rating").option("--clear-expected-json", "Delete structured expected JSON").action(action(updateExecutionFeedback));
181960
+ addJsonFlag(withBaseUrl(feedback.command("resolve <execution-id>"))).description("Mark execution feedback as resolved.").option("--message <text>", "Set feedback message body").option("--message-file <path>", "Read feedback message body from a file").action(action((executionId, opts) => updateExecutionFeedback(executionId, { ...opts, status: "resolved" })));
181961
+ addJsonFlag(withBaseUrl(feedback.command("clear <execution-id>"))).description("Delete feedback, expected.json, and expected files for an execution.").option("--yes", "Required in non-interactive environments").action(action(clearExecutionFeedback));
181962
+ }
181963
+ function registerExecutionExpectedCommands(execution) {
181964
+ const expected = execution.command("expected").description("Manage expected artifacts attached to an agent execution.").action(() => {
181965
+ process.stderr.write("`eigenpal agent execution expected` requires a subcommand. Run `eigenpal agent execution expected --help`.\n");
181966
+ process.exit(2);
181967
+ });
181968
+ addJsonFlag(withBaseUrl(expected.command("list <execution-id>"))).description("List expected JSON and files attached to an execution.").action(action(listExecutionExpected));
181969
+ withBaseUrl(expected.command("pull <execution-id>")).description("Download expected JSON and files attached to an execution.").option("--out <dir>", "Output directory").action(action(pullExecutionExpected));
181970
+ addJsonFlag(withBaseUrl(expected.command("upload <execution-id> <file>"))).description("Upload a local file as an expected artifact.").option("--name <name>", "Expected artifact name").action(action(uploadExecutionExpected));
181971
+ addJsonFlag(withBaseUrl(expected.command("copy-output <execution-id> <output-file>"))).description("Copy a generated output file into expected artifacts.").option("--name <name>", "Expected artifact name").action(action(copyOutputToExpected));
181972
+ addJsonFlag(withBaseUrl(expected.command("rename <execution-id> <old-name> <new-name>"))).description("Rename an expected artifact.").action(action(renameExecutionExpected));
181973
+ addJsonFlag(withBaseUrl(expected.command("delete <execution-id> <name>"))).description("Delete an expected artifact.").option("--yes", "Required in non-interactive environments").action(action(deleteExecutionExpected));
181974
+ }
181993
181975
  function registerSessionCommands(agent) {
181994
181976
  const session = agent.command("session").description("Manage agent builder sessions.").action(() => {
181995
181977
  process.stderr.write("`eigenpal agent session` requires a subcommand. Run `eigenpal agent session --help`.\n");
@@ -182108,6 +182090,55 @@ async function pullAgent(agentId, opts) {
182108
182090
  await pullDataset(agentId, { ...opts, out: path.join(out, DATASET_DIR) });
182109
182091
  success2(`Pulled agent to ${ui.bold(out)}`);
182110
182092
  }
182093
+ async function listAgentFiles(agentId, opts) {
182094
+ const client = buildClient(opts);
182095
+ const payload = await client.get(`/api/v1/agents/${encodeURIComponent(agentId)}/files`, {
182096
+ ...opts.path ? { prefix: opts.path } : {}
182097
+ });
182098
+ if (opts.json)
182099
+ return printJson(payload);
182100
+ console.log(table((payload.files ?? []).map((name) => ({ name })), [{ key: "name", header: "PATH" }]));
182101
+ }
182102
+ async function getAgentFile(agentId, remotePath, opts) {
182103
+ const client = buildClient(opts);
182104
+ const payload = await client.get(`/api/v1/agents/${encodeURIComponent(agentId)}/files`, {
182105
+ path: remotePath
182106
+ });
182107
+ if (opts.json)
182108
+ return printJson(payload);
182109
+ const out = path.resolve(opts.out ?? payload.path);
182110
+ await writeBase64File(out, payload.contentBase64);
182111
+ success2(`Downloaded ${payload.path} to ${ui.bold(out)}`);
182112
+ }
182113
+ async function putAgentFile(agentId, remotePath, localPath, opts) {
182114
+ const absolute = path.resolve(localPath);
182115
+ const data = await fs.readFile(absolute);
182116
+ if (opts.dryRun) {
182117
+ const payload2 = { ok: true, dryRun: true, path: remotePath, bytes: data.length };
182118
+ if (opts.json)
182119
+ return printJson(payload2);
182120
+ success2(`Validated ${remotePath} from ${ui.bold(absolute)} (${data.length} bytes)`);
182121
+ return;
182122
+ }
182123
+ if (opts.preview) {
182124
+ const report = await buildAgentFileDiff(agentId, remotePath, absolute, opts);
182125
+ if (opts.json)
182126
+ return printJson(report);
182127
+ renderAgentFileDiff(report);
182128
+ return;
182129
+ }
182130
+ const client = buildClient(opts);
182131
+ const payload = await client.put(`/api/v1/agents/${encodeURIComponent(agentId)}/files?path=${encodeURIComponent(remotePath)}`, { contentBase64: data.toString("base64") });
182132
+ if (opts.json)
182133
+ return printJson(payload);
182134
+ success2(`Uploaded ${remotePath} from ${ui.bold(absolute)}`);
182135
+ }
182136
+ async function diffAgentFile(agentId, remotePath, localPath, opts) {
182137
+ const report = await buildAgentFileDiff(agentId, remotePath, path.resolve(localPath), opts);
182138
+ if (opts.json)
182139
+ return printJson(report);
182140
+ renderAgentFileDiff(report);
182141
+ }
182111
182142
  async function validateAgentCommand(dir = ".", opts) {
182112
182143
  const result = await validateAgentProject(path.resolve(dir));
182113
182144
  if (opts.json)
@@ -182184,18 +182215,302 @@ async function getExecution(executionId, opts) {
182184
182215
  });
182185
182216
  renderExecutionPayload(payload, opts);
182186
182217
  }
182187
- async function listExecutions(agentId, opts) {
182218
+ async function rerunExecution(executionId, opts) {
182188
182219
  const client = buildClient(opts);
182189
- const payload = await client.get(`/api/v1/agents/${encodeURIComponent(agentId)}/executions`, compactParams(opts));
182220
+ let payload = await client.post(`/api/v1/agents/executions/${encodeURIComponent(executionId)}/rerun`, {});
182221
+ const rerunId = String(payload.executionId ?? "");
182222
+ if (opts.wait && rerunId) {
182223
+ payload = await pollExecution(client, rerunId, opts.interval, opts.maxWait);
182224
+ return renderExecutionPayload(payload, opts);
182225
+ }
182190
182226
  if (opts.json)
182191
182227
  return printJson(payload);
182192
- console.log(table(payload.executions, [
182228
+ success2(`Started rerun ${ui.bold(rerunId)} from ${executionId}`);
182229
+ }
182230
+ async function pullExecution(executionId, opts) {
182231
+ const client = buildClient(opts);
182232
+ const include = new Set(opts.include.split(",").map((part) => part.trim()).filter(Boolean));
182233
+ if (include.has("all")) {
182234
+ include.add("feedback");
182235
+ include.add("expected");
182236
+ include.add("files");
182237
+ include.add("input");
182238
+ include.add("output");
182239
+ include.add("metadata");
182240
+ include.add("issues");
182241
+ include.add("trace");
182242
+ }
182243
+ const payload = await client.get(`/api/v1/agents/executions/${encodeURIComponent(executionId)}`, { include: [...include].join(",") });
182244
+ const execution = payload.execution;
182245
+ if (!execution)
182246
+ throw new Error(`Execution ${executionId} not found`);
182247
+ const out = path.resolve(opts.out ?? path.join(".eigenpal", "artifacts", "executions", executionId));
182248
+ await fs.mkdir(out, { recursive: true });
182249
+ const written = [];
182250
+ const skipped = [];
182251
+ const writeJsonArtifact = async (name, value) => {
182252
+ await fs.writeFile(path.join(out, name), JSON.stringify(value, null, 2));
182253
+ written.push(name);
182254
+ };
182255
+ await writeJsonArtifact("execution.json", execution);
182256
+ const feedback = execution.feedback;
182257
+ if (include.has("feedback") && feedback) {
182258
+ await fs.writeFile(path.join(out, "feedback.md"), serializeCliFeedback(feedback));
182259
+ written.push("feedback.md");
182260
+ } else if (include.has("feedback")) {
182261
+ skipped.push("feedback");
182262
+ }
182263
+ if (include.has("expected")) {
182264
+ written.push(...await writeExpectedArtifacts(client, executionId, out, execution));
182265
+ }
182266
+ if (include.has("files") || include.has("output")) {
182267
+ written.push(...await writeListedFiles(client, executionId, out, "output", execution.resultFiles));
182268
+ }
182269
+ if (include.has("files") || include.has("input")) {
182270
+ written.push(...await writeListedFiles(client, executionId, out, "input", execution.inputFiles));
182271
+ if (execution.inputJson) {
182272
+ await writeJsonArtifact("input.json", execution.inputJson);
182273
+ } else {
182274
+ skipped.push("input.json");
182275
+ }
182276
+ }
182277
+ if (include.has("files") || include.has("metadata")) {
182278
+ if (execution.metadata) {
182279
+ await writeJsonArtifact("metadata.json", execution.metadata);
182280
+ } else {
182281
+ skipped.push("metadata.json");
182282
+ }
182283
+ }
182284
+ if (include.has("files") || include.has("issues")) {
182285
+ const file2 = await writeDiagnosticFile(client, executionId, out, "issues", "issues.md", execution.issueFiles);
182286
+ if (file2)
182287
+ written.push(file2);
182288
+ else
182289
+ skipped.push("issues.md");
182290
+ }
182291
+ if (include.has("files") || include.has("trace")) {
182292
+ const file2 = await writeDiagnosticFile(client, executionId, out, "trace", "trace.jsonl", execution.traceFiles);
182293
+ if (file2)
182294
+ written.push(file2);
182295
+ else
182296
+ skipped.push("trace.jsonl");
182297
+ }
182298
+ const summary = {
182299
+ executionId,
182300
+ out,
182301
+ written,
182302
+ skipped,
182303
+ counts: {
182304
+ written: written.length,
182305
+ skipped: skipped.length
182306
+ }
182307
+ };
182308
+ if (opts.json)
182309
+ return printJson(summary);
182310
+ success2(`Pulled execution ${executionId} to ${out}`);
182311
+ dim(`Wrote ${written.length} artifact${written.length === 1 ? "" : "s"}${skipped.length ? `; skipped missing ${skipped.join(", ")}` : ""}`);
182312
+ }
182313
+ async function listExecutionArtifacts(executionId, opts) {
182314
+ const client = buildClient(opts);
182315
+ const payload = await client.get(`/api/v1/agents/executions/${encodeURIComponent(executionId)}`, { include: "expected,files,input,output,issues,trace,metadata" });
182316
+ const execution = payload.execution;
182317
+ if (!execution)
182318
+ throw new Error(`Execution ${executionId} not found`);
182319
+ const artifacts = executionArtifactInventory(execution);
182320
+ if (opts.json)
182321
+ return printJson({ executionId, artifacts });
182322
+ console.log(table(artifacts, [
182323
+ { key: "kind", header: "KIND" },
182324
+ { key: "name", header: "NAME" },
182325
+ { key: "present", header: "PRESENT" }
182326
+ ]));
182327
+ }
182328
+ async function traceExecution(executionId, opts) {
182329
+ const client = buildClient(opts);
182330
+ const text = await downloadTraceText(client, executionId);
182331
+ if (!opts.out) {
182332
+ process.stdout.write(text);
182333
+ return;
182334
+ }
182335
+ const out = path.resolve(opts.out);
182336
+ await fs.mkdir(path.dirname(out), { recursive: true });
182337
+ await fs.writeFile(out, text);
182338
+ success2(`Downloaded trace for ${executionId} to ${ui.bold(out)}`);
182339
+ }
182340
+ async function compareExecution(referenceId, executionId, opts) {
182341
+ const client = buildClient(opts);
182342
+ const targetPayload = await client.get(`/api/v1/agents/executions/${encodeURIComponent(executionId)}`, { include: "files,output" });
182343
+ const target = targetPayload.execution;
182344
+ if (!target)
182345
+ throw new Error(`Execution ${executionId} not found`);
182346
+ const mode = opts.baseline ? "baseline" : "expected";
182347
+ const reference = (await client.get(`/api/v1/agents/executions/${encodeURIComponent(referenceId)}`, {
182348
+ include: mode === "baseline" ? "files,output" : "expected"
182349
+ })).execution;
182350
+ if (!reference)
182351
+ throw new Error(`Reference execution ${referenceId} not found`);
182352
+ const out = path.resolve(opts.out ?? path.join(".eigenpal", "artifacts", "comparisons", `${referenceId}..${executionId}`));
182353
+ await fs.mkdir(out, { recursive: true });
182354
+ const warnings = [];
182355
+ if (mode === "expected" && reference.expected == null && fileNames(reference.expectedFiles).length === 0) {
182356
+ warnings.push(`Reference execution ${referenceId} has no expected JSON or expected files; comparison has no baseline artifacts. Use --baseline to compare actual outputs.`);
182357
+ }
182358
+ const jsonDiffs = diffJson(mode === "baseline" ? reference.output : reference.expected, target.output);
182359
+ const expectedFiles = mode === "baseline" ? fileNames(reference.resultFiles).filter((name) => name !== "issues.md" && name !== "trace.jsonl") : fileNames(reference.expectedFiles);
182360
+ const outputFiles = fileNames(target.resultFiles).filter((name) => name !== "issues.md" && name !== "trace.jsonl");
182361
+ const inventory = compareFileInventory(expectedFiles, outputFiles, Boolean(opts.normalizeDates));
182362
+ const textDifferences = await compareMatchedFileText(client, { executionId: referenceId, kind: mode === "baseline" ? "output" : "expected" }, { executionId, kind: "output" }, out, inventory.matched, Boolean(opts.normalizeDates));
182363
+ const report = {
182364
+ status: jsonDiffs.length === 0 && inventory.missing.length === 0 && inventory.extra.length === 0 && textDifferences.every((diff) => diff.status === "match" || diff.status === "binary-match") ? "pass" : "fail",
182365
+ executionId,
182366
+ comparedWith: referenceId,
182367
+ mode,
182368
+ warnings,
182369
+ jsonDifferences: jsonDiffs,
182370
+ matchedFiles: inventory.matched,
182371
+ missingFiles: inventory.missing,
182372
+ extraFiles: inventory.extra,
182373
+ textDifferences
182374
+ };
182375
+ await fs.writeFile(path.join(out, "comparison.json"), JSON.stringify(report, null, 2));
182376
+ if (opts.json) {
182377
+ printJson(report);
182378
+ } else {
182379
+ renderComparisonReport(report);
182380
+ }
182381
+ dim(`Comparison artifacts written to ${ui.bold(out)}`);
182382
+ if (opts.failOnDiff && report.status === "fail")
182383
+ process.exit(1);
182384
+ }
182385
+ async function listExecutions(agentId, opts) {
182386
+ const client = buildClient(opts);
182387
+ const params = buildExecutionListParams(opts);
182388
+ const payload = await client.get(`/api/v1/agents/${encodeURIComponent(agentId)}/executions`, params);
182389
+ const rows = opts.compact ? payload.executions.map(compactExecutionRow) : payload.executions;
182390
+ if (opts.json)
182391
+ return printJson({ ...payload, executions: rows });
182392
+ if (payload.scanLimited) {
182393
+ warn("Feedback/expected filters scanned only the first matching window. Increase --scan-limit or narrow DB filters for a fuller result.");
182394
+ }
182395
+ if (payload.noResolvedAnchor) {
182396
+ warn("No resolved feedback anchor was found in the scan window; --since-last-resolved returned no rows.");
182397
+ }
182398
+ console.log(table(rows, [
182193
182399
  { key: "id", header: "ID" },
182194
182400
  { key: "status", header: "STATUS" },
182195
182401
  { key: "exampleId", header: "EXAMPLE" },
182402
+ {
182403
+ key: "feedback",
182404
+ header: "FEEDBACK",
182405
+ format: (value) => value && typeof value === "object" ? `${String(value.rating ?? "")}/${String(value.status ?? "")}` : ""
182406
+ },
182196
182407
  { key: "createdAt", header: "CREATED", format: formatTimestamp }
182197
182408
  ]));
182198
182409
  }
182410
+ function buildExecutionListParams(opts) {
182411
+ return compactParams({
182412
+ ...opts,
182413
+ feedback: undefined,
182414
+ noFeedback: opts.noFeedback ?? (opts.feedback === false ? true : undefined)
182415
+ });
182416
+ }
182417
+ async function updateExecutionFeedback(executionId, opts) {
182418
+ const client = buildClient(opts);
182419
+ const body = {};
182420
+ if (opts.status)
182421
+ body.status = opts.status;
182422
+ if (opts.rating)
182423
+ body.rating = opts.rating === "none" ? null : opts.rating;
182424
+ if (opts.clearRating)
182425
+ body.rating = null;
182426
+ if (opts.messageFile)
182427
+ body.body = await fs.readFile(opts.messageFile, "utf-8");
182428
+ if (opts.message !== undefined)
182429
+ body.body = opts.message;
182430
+ if (opts.clearMessage)
182431
+ body.body = "";
182432
+ if (opts.expectedJsonFile)
182433
+ body.expected = JSON.parse(await fs.readFile(opts.expectedJsonFile, "utf-8"));
182434
+ if (opts.expectedJson !== undefined)
182435
+ body.expected = JSON.parse(opts.expectedJson);
182436
+ if (opts.clearExpectedJson)
182437
+ body.expected = null;
182438
+ const payload = await client.patch(`/api/v1/agents/executions/${encodeURIComponent(executionId)}/feedback`, body);
182439
+ renderGeneric(payload, opts, `Updated feedback for ${executionId}`);
182440
+ }
182441
+ function compactExecutionRow(execution) {
182442
+ const feedback = execution.feedback && typeof execution.feedback === "object" ? execution.feedback : null;
182443
+ return {
182444
+ id: execution.id,
182445
+ status: execution.status,
182446
+ exampleId: execution.exampleId,
182447
+ feedback: feedback ? {
182448
+ rating: feedback.rating ?? null,
182449
+ status: feedback.status ?? null,
182450
+ updatedAt: feedback.updatedAt ?? null
182451
+ } : null,
182452
+ hasExpectedJson: execution.expected != null,
182453
+ expectedFileCount: Array.isArray(execution.expectedFiles) ? execution.expectedFiles.length : undefined,
182454
+ createdAt: execution.createdAt,
182455
+ completedAt: execution.completedAt
182456
+ };
182457
+ }
182458
+ async function clearExecutionFeedback(executionId, opts) {
182459
+ if (!(opts.yes || await confirmTyped(executionId, "clear feedback artifacts"))) {
182460
+ throw new Error("Clear cancelled");
182461
+ }
182462
+ const client = buildClient(opts);
182463
+ const payload = await client.delete(`/api/v1/agents/executions/${encodeURIComponent(executionId)}/feedback`);
182464
+ renderGeneric(payload, opts, `Cleared feedback for ${executionId}`);
182465
+ }
182466
+ async function listExecutionExpected(executionId, opts) {
182467
+ const client = buildClient(opts);
182468
+ const payload = await client.get(`/api/v1/agents/executions/${encodeURIComponent(executionId)}/expected`);
182469
+ if (opts.json)
182470
+ return printJson(payload);
182471
+ console.log(table(payload.files ?? [], [{ key: "name", header: "NAME" }]));
182472
+ if (payload.expected != null)
182473
+ dim("expected.json present");
182474
+ }
182475
+ async function pullExecutionExpected(executionId, opts) {
182476
+ const client = buildClient(opts);
182477
+ const payload = await client.get(`/api/v1/agents/executions/${encodeURIComponent(executionId)}/expected`);
182478
+ const out = path.resolve(opts.out ?? path.join(executionId, "expected"));
182479
+ await fs.mkdir(out, { recursive: true });
182480
+ if (payload.expected != null) {
182481
+ await fs.writeFile(path.join(out, "expected.json"), JSON.stringify(payload.expected, null, 2));
182482
+ }
182483
+ await downloadExpectedFiles(client, executionId, out, payload.files);
182484
+ success2(`Pulled expected artifacts for ${executionId} to ${out}`);
182485
+ }
182486
+ async function uploadExecutionExpected(executionId, file2, opts) {
182487
+ const client = buildClient(opts);
182488
+ const form = new FormData;
182489
+ const data = await fs.readFile(file2);
182490
+ form.append("file", new Blob([data]), path.basename(file2));
182491
+ if (opts.name)
182492
+ form.append("name", opts.name);
182493
+ const payload = await client.postFormData(`/api/v1/agents/executions/${encodeURIComponent(executionId)}/expected`, form);
182494
+ renderGeneric(payload, opts, `Uploaded expected file for ${executionId}`);
182495
+ }
182496
+ async function copyOutputToExpected(executionId, outputFile, opts) {
182497
+ const client = buildClient(opts);
182498
+ const payload = await client.post(`/api/v1/agents/executions/${encodeURIComponent(executionId)}/expected`, { outputFileName: outputFile, ...opts.name ? { expectedName: opts.name } : {} });
182499
+ renderGeneric(payload, opts, `Copied output file to expected for ${executionId}`);
182500
+ }
182501
+ async function renameExecutionExpected(executionId, oldName, newName, opts) {
182502
+ const client = buildClient(opts);
182503
+ const payload = await client.patch(`/api/v1/agents/executions/${encodeURIComponent(executionId)}/expected/${encodeURIComponent(oldName)}`, { name: newName });
182504
+ renderGeneric(payload, opts, `Renamed expected file for ${executionId}`);
182505
+ }
182506
+ async function deleteExecutionExpected(executionId, name, opts) {
182507
+ if (!(opts.yes || await confirmTyped(name, "delete expected file"))) {
182508
+ throw new Error("Delete cancelled");
182509
+ }
182510
+ const client = buildClient(opts);
182511
+ await client.delete(`/api/v1/agents/executions/${encodeURIComponent(executionId)}/expected/${encodeURIComponent(name)}`);
182512
+ renderGeneric({ ok: true }, opts, `Deleted expected file ${name}`);
182513
+ }
182199
182514
  async function watchExecutionCommand(executionId, opts) {
182200
182515
  const client = buildClient(opts);
182201
182516
  const payload = await pollExecution(client, executionId, opts.interval, opts.maxWait);
@@ -182410,6 +182725,336 @@ async function buildAgentExecutionRunFormData(inputFile, inputJson) {
182410
182725
  form.append("_json", inputJson);
182411
182726
  return form;
182412
182727
  }
182728
+ function serializeCliFeedback(feedback) {
182729
+ const keys = [
182730
+ "rating",
182731
+ "status",
182732
+ "createdAt",
182733
+ "createdBy",
182734
+ "createdByEmail",
182735
+ "updatedAt",
182736
+ "resolvedAt",
182737
+ "resolvedBy",
182738
+ "resolvedByEmail",
182739
+ "resolvedBySessionId",
182740
+ "promotedExampleName"
182741
+ ];
182742
+ const frontmatter = keys.map((key) => `${key}: ${feedback[key] ?? ""}`).join(`
182743
+ `);
182744
+ return `---
182745
+ ${frontmatter}
182746
+ ---
182747
+
182748
+ ${String(feedback.body ?? "").trim()}
182749
+ `;
182750
+ }
182751
+ async function writeExpectedArtifacts(client, executionId, out, execution) {
182752
+ const written = [];
182753
+ const expectedDir = path.join(out, "expected");
182754
+ await fs.mkdir(expectedDir, { recursive: true });
182755
+ if (execution.expected != null) {
182756
+ await fs.writeFile(path.join(out, "expected.json"), JSON.stringify(execution.expected, null, 2));
182757
+ written.push("expected.json");
182758
+ }
182759
+ written.push(...(await downloadExpectedFiles(client, executionId, expectedDir, execution.expectedFiles)).map((name) => `expected/${name}`));
182760
+ return written;
182761
+ }
182762
+ async function downloadExpectedFiles(client, executionId, out, files) {
182763
+ const rows = Array.isArray(files) ? files : [];
182764
+ const written = await Promise.all(rows.map(async (file2) => {
182765
+ const name = String(file2.name ?? "");
182766
+ if (!name || name.includes("/") || name.includes(".."))
182767
+ return null;
182768
+ const response = await client.getStream(`/api/v1/agents/executions/${encodeURIComponent(executionId)}/expected/${encodeURIComponent(name)}`);
182769
+ await fs.mkdir(out, { recursive: true });
182770
+ await fs.writeFile(path.join(out, name), Buffer.from(await response.arrayBuffer()));
182771
+ return name;
182772
+ }));
182773
+ return written.filter((name) => Boolean(name));
182774
+ }
182775
+ async function writeListedFiles(client, executionId, out, kind, files) {
182776
+ const rows = Array.isArray(files) ? files : [];
182777
+ const targetDir = path.join(out, kind);
182778
+ await fs.mkdir(targetDir, { recursive: true });
182779
+ const written = await Promise.all(rows.map(async (file2) => {
182780
+ const name = String(file2.name ?? "");
182781
+ if (!name || name.includes("/") || name.includes(".."))
182782
+ return null;
182783
+ const response = await client.getStream(`/api/v1/agents/executions/${encodeURIComponent(executionId)}/files/${kind}/${encodeURIComponent(name)}`);
182784
+ await fs.writeFile(path.join(targetDir, name), Buffer.from(await response.arrayBuffer()));
182785
+ return `${kind}/${name}`;
182786
+ }));
182787
+ return written.filter((name) => Boolean(name));
182788
+ }
182789
+ async function writeDiagnosticFile(client, executionId, out, kind, filename, files) {
182790
+ const rows = Array.isArray(files) ? files : [];
182791
+ const exists = rows.some((file2) => String(file2.name ?? "") === filename);
182792
+ if (!exists)
182793
+ return null;
182794
+ const response = await client.getStream(`/api/v1/agents/executions/${encodeURIComponent(executionId)}/files/${kind}/${filename}`);
182795
+ await fs.writeFile(path.join(out, filename), Buffer.from(await response.arrayBuffer()));
182796
+ return filename;
182797
+ }
182798
+ async function downloadTraceText(client, executionId) {
182799
+ const response = await client.getStream(`/api/v1/agents/executions/${encodeURIComponent(executionId)}/files/trace/trace.jsonl`);
182800
+ return Buffer.from(await response.arrayBuffer()).toString("utf-8");
182801
+ }
182802
+ function diffJson(expected, actual, basePath = "$") {
182803
+ if (expected === undefined || expected === null)
182804
+ return [];
182805
+ if (Object.is(expected, actual))
182806
+ return [];
182807
+ if (expected && actual && typeof expected === "object" && typeof actual === "object" && !Array.isArray(expected) && !Array.isArray(actual)) {
182808
+ const keys = new Set([...Object.keys(expected), ...Object.keys(actual)]);
182809
+ return [...keys].flatMap((key) => {
182810
+ const next = `${basePath}.${key}`;
182811
+ if (!(key in actual))
182812
+ return [{ path: next, type: "missing" }];
182813
+ if (!(key in expected))
182814
+ return [{ path: next, type: "extra" }];
182815
+ return diffJson(expected[key], actual[key], next);
182816
+ });
182817
+ }
182818
+ if (Array.isArray(expected) && Array.isArray(actual)) {
182819
+ const diffs = [];
182820
+ const max = Math.max(expected.length, actual.length);
182821
+ for (let index = 0;index < max; index += 1) {
182822
+ const next = `${basePath}[${index}]`;
182823
+ if (index >= actual.length)
182824
+ diffs.push({ path: next, type: "missing" });
182825
+ else if (index >= expected.length)
182826
+ diffs.push({ path: next, type: "extra" });
182827
+ else
182828
+ diffs.push(...diffJson(expected[index], actual[index], next));
182829
+ }
182830
+ return diffs;
182831
+ }
182832
+ return [
182833
+ {
182834
+ path: basePath,
182835
+ type: "changed",
182836
+ expected: JSON.stringify(expected),
182837
+ actual: JSON.stringify(actual)
182838
+ }
182839
+ ];
182840
+ }
182841
+ function fileNames(files) {
182842
+ return (Array.isArray(files) ? files : []).map((file2) => String(file2.name ?? "")).filter(Boolean).sort();
182843
+ }
182844
+ function executionArtifactInventory(execution) {
182845
+ const rows = [
182846
+ { kind: "metadata", name: "execution.json", present: "yes" }
182847
+ ];
182848
+ if (execution.inputJson != null)
182849
+ rows.push({ kind: "input", name: "input.json", present: "yes" });
182850
+ if (execution.metadata != null)
182851
+ rows.push({ kind: "metadata", name: "metadata.json", present: "yes" });
182852
+ if (execution.expected != null)
182853
+ rows.push({ kind: "expected", name: "expected.json", present: "yes" });
182854
+ for (const name of fileNames(execution.inputFiles))
182855
+ rows.push({ kind: "input", name, present: "yes" });
182856
+ for (const name of fileNames(execution.resultFiles).filter((name2) => name2 !== "issues.md" && name2 !== "trace.jsonl")) {
182857
+ rows.push({ kind: "output", name, present: "yes" });
182858
+ }
182859
+ for (const name of fileNames(execution.expectedFiles)) {
182860
+ rows.push({ kind: "expected", name, present: "yes" });
182861
+ }
182862
+ for (const name of fileNames(execution.issueFiles))
182863
+ rows.push({ kind: "issues", name, present: "yes" });
182864
+ for (const name of fileNames(execution.traceFiles))
182865
+ rows.push({ kind: "trace", name, present: "yes" });
182866
+ return rows.sort((a, b) => `${a.kind}/${a.name}`.localeCompare(`${b.kind}/${b.name}`));
182867
+ }
182868
+ async function buildAgentFileDiff(agentId, remotePath, localPath, opts) {
182869
+ const client = buildClient(opts);
182870
+ const local = await fs.readFile(localPath);
182871
+ let remote = null;
182872
+ let serverPath = remotePath;
182873
+ try {
182874
+ const payload = await client.get(`/api/v1/agents/${encodeURIComponent(agentId)}/files`, {
182875
+ path: remotePath
182876
+ });
182877
+ serverPath = String(payload.path ?? remotePath);
182878
+ remote = Buffer.from(String(payload.contentBase64 ?? ""), "base64");
182879
+ } catch (err) {
182880
+ if (!(err instanceof ApiError) || err.status !== 404)
182881
+ throw err;
182882
+ }
182883
+ const localHash = createHash("sha256").update(local).digest("hex");
182884
+ const remoteHash = remote ? createHash("sha256").update(remote).digest("hex") : null;
182885
+ const status = !remote ? "remote-missing" : localHash === remoteHash ? "match" : "different";
182886
+ return {
182887
+ agentId,
182888
+ path: serverPath,
182889
+ localPath,
182890
+ status,
182891
+ localBytes: local.length,
182892
+ remoteBytes: remote?.length ?? null,
182893
+ localSha256: localHash,
182894
+ remoteSha256: remoteHash,
182895
+ textPreview: remote && isLikelyText(local) && isLikelyText(remote) ? buildTextDiffPreview(remote.toString("utf-8"), local.toString("utf-8")) : null
182896
+ };
182897
+ }
182898
+ function renderAgentFileDiff(report) {
182899
+ const label = `File ${report.status}`;
182900
+ if (report.status === "match")
182901
+ success2(label);
182902
+ else
182903
+ error51(label);
182904
+ console.log(table([
182905
+ { item: "Remote path", value: report.path },
182906
+ { item: "Local bytes", value: String(report.localBytes) },
182907
+ { item: "Remote bytes", value: String(report.remoteBytes ?? "missing") },
182908
+ { item: "Local sha256", value: report.localSha256.slice(0, 12) },
182909
+ { item: "Remote sha256", value: report.remoteSha256?.slice(0, 12) ?? "missing" }
182910
+ ], [
182911
+ { key: "item", header: "ITEM" },
182912
+ { key: "value", header: "VALUE" }
182913
+ ]));
182914
+ if (report.textPreview?.length) {
182915
+ console.log(report.textPreview.join(`
182916
+ `));
182917
+ }
182918
+ }
182919
+ function isLikelyText(buffer) {
182920
+ return !buffer.includes(0);
182921
+ }
182922
+ function buildTextDiffPreview(remoteText, localText) {
182923
+ if (remoteText === localText)
182924
+ return [];
182925
+ const remoteLines = remoteText.split(/\r?\n/);
182926
+ const localLines = localText.split(/\r?\n/);
182927
+ const max = Math.max(remoteLines.length, localLines.length);
182928
+ const preview = [];
182929
+ for (let index = 0;index < max && preview.length < 12; index += 1) {
182930
+ if (remoteLines[index] === localLines[index])
182931
+ continue;
182932
+ preview.push(`-${remoteLines[index] ?? ""}`);
182933
+ preview.push(`+${localLines[index] ?? ""}`);
182934
+ }
182935
+ return preview;
182936
+ }
182937
+ function normalizeGeneratedTokens(value) {
182938
+ return value.replace(/\d{4}-\d{2}-\d{2}/g, "<date>").replace(/\d{8}/g, "<date>");
182939
+ }
182940
+ function compareFileInventory(expected, output, normalizeDates) {
182941
+ const normalize = (value) => normalizeDates ? normalizeGeneratedTokens(value) : value;
182942
+ const outputByNormalized = new Map(output.map((name) => [normalize(name), name]));
182943
+ const expectedByNormalized = new Map(expected.map((name) => [normalize(name), name]));
182944
+ const matched = expected.map((expectedName) => {
182945
+ const outputName = outputByNormalized.get(normalize(expectedName));
182946
+ return outputName ? { expected: expectedName, output: outputName } : null;
182947
+ }).filter((match) => Boolean(match));
182948
+ return {
182949
+ matched,
182950
+ missing: expected.filter((name) => !outputByNormalized.has(normalize(name))),
182951
+ extra: output.filter((name) => !expectedByNormalized.has(normalize(name)))
182952
+ };
182953
+ }
182954
+ async function compareMatchedFileText(client, left, right, out, matched, normalizeDates) {
182955
+ const expectedDir = path.join(out, "expected");
182956
+ const outputDir = path.join(out, "output");
182957
+ await fs.mkdir(expectedDir, { recursive: true });
182958
+ await fs.mkdir(outputDir, { recursive: true });
182959
+ const diffs = [];
182960
+ for (const pair of matched) {
182961
+ const expectedPath = path.join(expectedDir, pair.expected);
182962
+ const outputPath = path.join(outputDir, pair.output);
182963
+ await downloadStreamToFile(client, executionFileUrl(left, pair.expected), expectedPath);
182964
+ await downloadStreamToFile(client, executionFileUrl(right, pair.output), outputPath);
182965
+ const expectedText = extractComparableText(expectedPath);
182966
+ const outputText = extractComparableText(outputPath);
182967
+ if (expectedText.text == null || outputText.text == null) {
182968
+ const [expectedBuffer, outputBuffer] = await Promise.all([
182969
+ fs.readFile(expectedPath),
182970
+ fs.readFile(outputPath)
182971
+ ]);
182972
+ const expectedHash = createHash("sha256").update(expectedBuffer).digest("hex");
182973
+ const outputHash = createHash("sha256").update(outputBuffer).digest("hex");
182974
+ diffs.push({
182975
+ ...pair,
182976
+ status: expectedBuffer.length === outputBuffer.length && expectedHash === outputHash ? "binary-match" : "binary-different",
182977
+ expectedBytes: expectedBuffer.length,
182978
+ outputBytes: outputBuffer.length,
182979
+ expectedSha256: expectedHash,
182980
+ outputSha256: outputHash,
182981
+ textExtraction: {
182982
+ expected: expectedText.reason ?? null,
182983
+ output: outputText.reason ?? null
182984
+ }
182985
+ });
182986
+ continue;
182987
+ }
182988
+ const normalize = (value) => normalizeDates ? normalizeGeneratedTokens(value).trim() : value.trim();
182989
+ diffs.push({
182990
+ ...pair,
182991
+ status: normalize(expectedText.text) === normalize(outputText.text) ? "match" : "text-different"
182992
+ });
182993
+ }
182994
+ return diffs;
182995
+ }
182996
+ function executionFileUrl(side, name) {
182997
+ const executionId = encodeURIComponent(side.executionId);
182998
+ const filename = encodeURIComponent(name);
182999
+ return side.kind === "expected" ? `/api/v1/agents/executions/${executionId}/expected/${filename}` : `/api/v1/agents/executions/${executionId}/files/output/${filename}`;
183000
+ }
183001
+ async function downloadStreamToFile(client, url2, target) {
183002
+ await fs.mkdir(path.dirname(target), { recursive: true });
183003
+ const response = await client.getStream(url2);
183004
+ await fs.writeFile(target, Buffer.from(await response.arrayBuffer()));
183005
+ }
183006
+ function extractComparableText(file2) {
183007
+ const ext = path.extname(file2).toLowerCase();
183008
+ if ([".txt", ".md", ".json", ".csv", ".xml"].includes(ext)) {
183009
+ return { text: readFileSync2(file2, "utf8") };
183010
+ }
183011
+ if (ext === ".pdf") {
183012
+ const result = spawnSync("pdftotext", [file2, "-"], { encoding: "utf8" });
183013
+ return result.status === 0 ? { text: result.stdout } : { text: null, reason: textExtractionFallbackReason("pdftotext", result) };
183014
+ }
183015
+ if (ext === ".docx") {
183016
+ const script = "import re,sys,zipfile; z=zipfile.ZipFile(sys.argv[1]); x=z.read('word/document.xml').decode('utf-8','ignore'); print(re.sub('<[^>]+>',' ',x))";
183017
+ const result = spawnSync("python3", ["-c", script, file2], { encoding: "utf8" });
183018
+ return result.status === 0 ? { text: result.stdout } : { text: null, reason: textExtractionFallbackReason("python3", result) };
183019
+ }
183020
+ return { text: null, reason: `No text extractor for ${ext || "extensionless"} files` };
183021
+ }
183022
+ function textExtractionFallbackReason(tool, result) {
183023
+ if (result.error)
183024
+ return `${tool} unavailable; compared bytes instead`;
183025
+ return `${tool} could not extract text; compared bytes instead`;
183026
+ }
183027
+ function renderComparisonReport(report) {
183028
+ const header = `Comparison ${report.status}`;
183029
+ if (report.status === "pass") {
183030
+ success2(header);
183031
+ } else {
183032
+ error51(header);
183033
+ }
183034
+ for (const warning of report.warnings ?? []) {
183035
+ dim(`warning: ${warning}`);
183036
+ }
183037
+ console.log(table([
183038
+ { item: "JSON differences", count: report.jsonDifferences.length },
183039
+ { item: "Matched files", count: report.matchedFiles.length },
183040
+ { item: "Missing files", count: report.missingFiles.length },
183041
+ { item: "Extra files", count: report.extraFiles.length },
183042
+ {
183043
+ item: "Text differences",
183044
+ count: report.textDifferences.filter((diff) => diff.status === "text-different").length
183045
+ }
183046
+ ], [
183047
+ { key: "item", header: "ITEM" },
183048
+ { key: "count", header: "COUNT" }
183049
+ ]));
183050
+ for (const diff of report.textDifferences) {
183051
+ const textExtraction = diff.textExtraction;
183052
+ const reasons = [textExtraction?.expected, textExtraction?.output].filter((value) => typeof value === "string" && value.length > 0).filter((value, index, values) => values.indexOf(value) === index);
183053
+ for (const reason of reasons) {
183054
+ dim(`warning: ${String(diff.expected)} vs ${String(diff.output)}: ${reason}`);
183055
+ }
183056
+ }
183057
+ }
182413
183058
  async function readAgentYaml(root) {
182414
183059
  const file2 = path.join(root, AGENT_YAML);
182415
183060
  const raw = await fs.readFile(file2, "utf-8");
@@ -182490,7 +183135,7 @@ function renderGeneric(payload, opts, message) {
182490
183135
  function compactParams(opts) {
182491
183136
  const params = {};
182492
183137
  for (const [key, value] of Object.entries(opts)) {
182493
- if (value === undefined || value === null || key === "json" || key === "baseUrl" || key === "yes")
183138
+ if (value === undefined || value === null || key === "json" || key === "baseUrl" || key === "yes" || key === "compact")
182494
183139
  continue;
182495
183140
  params[key] = String(value);
182496
183141
  }
@@ -183007,7 +183652,7 @@ import {
183007
183652
  existsSync as existsSync3,
183008
183653
  mkdirSync as mkdirSync2,
183009
183654
  readdirSync,
183010
- readFileSync as readFileSync2,
183655
+ readFileSync as readFileSync3,
183011
183656
  statSync,
183012
183657
  writeFileSync as writeFileSync2
183013
183658
  } from "node:fs";
@@ -183105,7 +183750,7 @@ function copyTemplate(src, dst, projectName) {
183105
183750
  }
183106
183751
  mkdirSync2(dirname2(targetPath), { recursive: true });
183107
183752
  if (isTextFile(sourcePath)) {
183108
- const text = readFileSync2(sourcePath, "utf-8").replaceAll(PLACEHOLDER, projectName);
183753
+ const text = readFileSync3(sourcePath, "utf-8").replaceAll(PLACEHOLDER, projectName);
183109
183754
  writeFileSync2(targetPath, text);
183110
183755
  } else {
183111
183756
  copyFileSync(sourcePath, targetPath);
@@ -183137,12 +183782,12 @@ function isTextFile(path2) {
183137
183782
 
183138
183783
  // src/commands/skill.ts
183139
183784
  init_dist4();
183140
- import { createHash } from "node:crypto";
183785
+ import { createHash as createHash2 } from "node:crypto";
183141
183786
  import {
183142
183787
  existsSync as existsSync4,
183143
183788
  lstatSync,
183144
183789
  mkdirSync as mkdirSync3,
183145
- readFileSync as readFileSync3,
183790
+ readFileSync as readFileSync4,
183146
183791
  readdirSync as readdirSync2,
183147
183792
  rmSync,
183148
183793
  rmdirSync,
@@ -183236,7 +183881,7 @@ function resolveSkillTarget(opts) {
183236
183881
  return opts.target ?? defaultClaudeTarget();
183237
183882
  }
183238
183883
  function sha256(buffer) {
183239
- return createHash("sha256").update(buffer).digest("hex");
183884
+ return createHash2("sha256").update(buffer).digest("hex");
183240
183885
  }
183241
183886
  var CLI_VERSION_PLACEHOLDER = "__CLI_VERSION__";
183242
183887
  function templateSourceFile(relativePath, bytes, cliVersion) {
@@ -183260,7 +183905,7 @@ async function installSkill(opts) {
183260
183905
  for (const relativePath of sourceFiles) {
183261
183906
  const sourcePath = join3(source, relativePath);
183262
183907
  const targetPath = join3(target, relativePath);
183263
- const sourceBytes = templateSourceFile(relativePath, readFileSync3(sourcePath), cliVersion);
183908
+ const sourceBytes = templateSourceFile(relativePath, readFileSync4(sourcePath), cliVersion);
183264
183909
  const sourceHash = sha256(sourceBytes);
183265
183910
  if (!existsSync4(targetPath)) {
183266
183911
  mkdirSync3(dirname3(targetPath), { recursive: true });
@@ -183268,7 +183913,7 @@ async function installSkill(opts) {
183268
183913
  written += 1;
183269
183914
  continue;
183270
183915
  }
183271
- const targetBytes = readFileSync3(targetPath);
183916
+ const targetBytes = readFileSync4(targetPath);
183272
183917
  const targetHash = sha256(targetBytes);
183273
183918
  if (targetHash === sourceHash) {
183274
183919
  skipped += 1;
@@ -183299,7 +183944,7 @@ async function installSkill(opts) {
183299
183944
  const targetPath = join3(target, relativePath);
183300
183945
  if (!existsSync4(targetPath))
183301
183946
  continue;
183302
- manifestEntries.push({ path: relativePath, sha256: sha256(readFileSync3(targetPath)) });
183947
+ manifestEntries.push({ path: relativePath, sha256: sha256(readFileSync4(targetPath)) });
183303
183948
  }
183304
183949
  const manifest = {
183305
183950
  cliVersion,
@@ -183340,7 +183985,7 @@ async function uninstallSkill(opts) {
183340
183985
  }
183341
183986
  if (!existsSync4(path2))
183342
183987
  continue;
183343
- const currentHash = sha256(readFileSync3(path2));
183988
+ const currentHash = sha256(readFileSync4(path2));
183344
183989
  if (currentHash !== entry.sha256 && !opts.yes) {
183345
183990
  kept += 1;
183346
183991
  continue;
@@ -183570,7 +184215,7 @@ function readManifest(target) {
183570
184215
  if (!existsSync4(path2))
183571
184216
  return null;
183572
184217
  try {
183573
- return JSON.parse(readFileSync3(path2, "utf-8"));
184218
+ return JSON.parse(readFileSync4(path2, "utf-8"));
183574
184219
  } catch {
183575
184220
  return null;
183576
184221
  }
@@ -183584,7 +184229,7 @@ function readCliVersion() {
183584
184229
  ];
183585
184230
  for (const candidate of candidates) {
183586
184231
  if (existsSync4(candidate)) {
183587
- const pkg = JSON.parse(readFileSync3(candidate, "utf-8"));
184232
+ const pkg = JSON.parse(readFileSync4(candidate, "utf-8"));
183588
184233
  if (pkg.version)
183589
184234
  return pkg.version;
183590
184235
  }
@@ -184386,8 +185031,8 @@ import path15 from "node:path";
184386
185031
  import { createInterface as createInterface3 } from "node:readline/promises";
184387
185032
 
184388
185033
  // src/lib/format-eigenpal.ts
184389
- import { spawnSync } from "child_process";
184390
- import { existsSync as existsSync5, readFileSync as readFileSync4 } from "fs";
185034
+ import { spawnSync as spawnSync2 } from "child_process";
185035
+ import { existsSync as existsSync5, readFileSync as readFileSync5 } from "fs";
184391
185036
  import { join as join4, resolve as resolve3 } from "path";
184392
185037
  var PRETTRC_NAMES = [
184393
185038
  ".prettierrc",
@@ -184408,7 +185053,7 @@ function hasPrettierConfig(cwd) {
184408
185053
  const pkgPath = join4(cwd, "package.json");
184409
185054
  if (!existsSync5(pkgPath))
184410
185055
  return false;
184411
- const raw = readFileSync4(pkgPath, "utf-8");
185056
+ const raw = readFileSync5(pkgPath, "utf-8");
184412
185057
  const pkg = JSON.parse(raw);
184413
185058
  return pkg != null && typeof pkg === "object" && "prettier" in pkg;
184414
185059
  } catch {
@@ -184423,7 +185068,7 @@ function formatEigenpalDirIfAvailable(dir) {
184423
185068
  if (!hasPrettierConfig(cwd))
184424
185069
  return;
184425
185070
  const runner = typeof Bun !== "undefined" ? "bunx" : "npx";
184426
- spawnSync(runner, ["prettier", "--write", absDir], {
185071
+ spawnSync2(runner, ["prettier", "--write", absDir], {
184427
185072
  cwd,
184428
185073
  stdio: "ignore",
184429
185074
  shell: false
@@ -184509,7 +185154,7 @@ import { existsSync as existsSync7, readdirSync as readdirSync4, rmSync as rmSyn
184509
185154
  import { basename, join as join7 } from "path";
184510
185155
 
184511
185156
  // src/lib/payload.ts
184512
- import { existsSync as existsSync6, readdirSync as readdirSync3, readFileSync as readFileSync5, statSync as statSync2 } from "fs";
185157
+ import { existsSync as existsSync6, readdirSync as readdirSync3, readFileSync as readFileSync6, statSync as statSync2 } from "fs";
184513
185158
  import { join as join6 } from "path";
184514
185159
 
184515
185160
  // src/lib/fs-helpers.ts
@@ -184566,7 +185211,7 @@ function getExampleNames(dir, exampleNamesFilter) {
184566
185211
  function readInput(exampleDir) {
184567
185212
  const argsPath = join6(exampleDir, "input", "arguments.json");
184568
185213
  const inputDir = join6(exampleDir, "input");
184569
- const scalars = JSON.parse(readFileSync5(argsPath, "utf-8"));
185214
+ const scalars = JSON.parse(readFileSync6(argsPath, "utf-8"));
184570
185215
  const files = [];
184571
185216
  for (const entry of readdirSync3(inputDir)) {
184572
185217
  const full = join6(inputDir, entry);
@@ -184577,7 +185222,7 @@ function readInput(exampleDir) {
184577
185222
  files.push({
184578
185223
  argument: entry,
184579
185224
  filename,
184580
- content: readFileSync5(join6(full, filename)),
185225
+ content: readFileSync6(join6(full, filename)),
184581
185226
  mimeType: guessMimeType(filename)
184582
185227
  });
184583
185228
  }
@@ -184588,7 +185233,7 @@ function readOverrides(exampleDir) {
184588
185233
  const metaPath = join6(exampleDir, "meta.json");
184589
185234
  if (!existsSync6(metaPath))
184590
185235
  return null;
184591
- const raw = JSON.parse(readFileSync5(metaPath, "utf-8"));
185236
+ const raw = JSON.parse(readFileSync6(metaPath, "utf-8"));
184592
185237
  const ov = raw.overrides;
184593
185238
  if (ov && typeof ov === "object" && "steps" in ov && typeof ov.steps === "object") {
184594
185239
  return ov;
@@ -184845,18 +185490,18 @@ async function watchExecution(opts) {
184845
185490
  import { join as join11 } from "path";
184846
185491
 
184847
185492
  // src/lib/execution-artifacts.ts
184848
- import { existsSync as existsSync8, mkdirSync as mkdirSync4, readdirSync as readdirSync5, readFileSync as readFileSync7, writeFileSync as writeFileSync5 } from "fs";
185493
+ import { existsSync as existsSync8, mkdirSync as mkdirSync4, readdirSync as readdirSync5, readFileSync as readFileSync8, writeFileSync as writeFileSync5 } from "fs";
184849
185494
  import { join as join10 } from "path";
184850
185495
 
184851
185496
  // src/lib/format.ts
184852
- import { readFileSync as readFileSync6, writeFileSync as writeFileSync4 } from "fs";
185497
+ import { readFileSync as readFileSync7, writeFileSync as writeFileSync4 } from "fs";
184853
185498
  import { extname as extname3, resolve as resolve5 } from "path";
184854
185499
  var PRETTIER_EXTENSIONS = new Set([".json", ".yaml", ".yml"]);
184855
185500
  async function formatFileIfAvailable(filepath) {
184856
185501
  if (!PRETTIER_EXTENSIONS.has(extname3(filepath)))
184857
185502
  return;
184858
185503
  try {
184859
- const content = readFileSync6(filepath, "utf-8");
185504
+ const content = readFileSync7(filepath, "utf-8");
184860
185505
  const prettier = await Promise.resolve().then(() => (init_prettier(), exports_prettier));
184861
185506
  const formatted = await prettier.format(content, {
184862
185507
  filepath: resolve5(filepath)
@@ -185025,7 +185670,7 @@ function createProgressLines(options8) {
185025
185670
  // src/commands/exec.ts
185026
185671
  var POLL_INTERVAL_MS = 2000;
185027
185672
  var MAX_POLL_MS = 5 * 60 * 1000;
185028
- var DEFAULT_CONCURRENCY2 = 3;
185673
+ var DEFAULT_CONCURRENCY = 3;
185029
185674
  async function pollExecution2(client, executionId) {
185030
185675
  const start = Date.now();
185031
185676
  while (Date.now() - start < MAX_POLL_MS) {
@@ -185041,8 +185686,8 @@ async function runExec(client, dir, workflowIdOrSlug, exampleNames, options8 = {
185041
185686
  const names = getExampleNames(dir, exampleNames.length ? exampleNames : undefined);
185042
185687
  if (names.length === 0)
185043
185688
  throw new Error("No matching eval examples found.");
185044
- const requested = options8.concurrencyOverride ?? DEFAULT_CONCURRENCY2;
185045
- const requestedValid = Number.isFinite(requested) && requested > 0 ? requested : DEFAULT_CONCURRENCY2;
185689
+ const requested = options8.concurrencyOverride ?? DEFAULT_CONCURRENCY;
185690
+ const requestedValid = Number.isFinite(requested) && requested > 0 ? requested : DEFAULT_CONCURRENCY;
185046
185691
  const concurrency = Math.max(1, Math.min(requestedValid, names.length));
185047
185692
  const evalBaseDir = resolveEvalBaseDir(dir);
185048
185693
  if (!evalBaseDir)
@@ -185623,7 +186268,7 @@ function parseWorkflow(yaml) {
185623
186268
  }
185624
186269
  // src/commands/validate.ts
185625
186270
  var import_yaml5 = __toESM(require_dist(), 1);
185626
- import { existsSync as existsSync9, readdirSync as readdirSync6, readFileSync as readFileSync8, statSync as statSync5 } from "fs";
186271
+ import { existsSync as existsSync9, readdirSync as readdirSync6, readFileSync as readFileSync9, statSync as statSync5 } from "fs";
185627
186272
  import { join as join12, resolve as resolve6 } from "path";
185628
186273
  var NAME_RE = /^[a-z0-9][a-z0-9-_]*$/;
185629
186274
  function isDirSafe(path15, issues, field) {
@@ -185641,7 +186286,7 @@ function validateWorkflowYaml(path15) {
185641
186286
  if (!existsSync9(path15)) {
185642
186287
  return [{ field: path15, message: "File not found." }];
185643
186288
  }
185644
- const text = readFileSync8(path15, "utf-8");
186289
+ const text = readFileSync9(path15, "utf-8");
185645
186290
  try {
185646
186291
  parseWorkflow(text);
185647
186292
  return [];
@@ -185663,7 +186308,7 @@ function validateEvaluatorsYaml(path15) {
185663
186308
  if (!existsSync9(path15)) {
185664
186309
  return [{ field: path15, message: "File not found." }];
185665
186310
  }
185666
- const text = readFileSync8(path15, "utf-8");
186311
+ const text = readFileSync9(path15, "utf-8");
185667
186312
  let parsed;
185668
186313
  try {
185669
186314
  parsed = import_yaml5.parse(text);
@@ -185715,7 +186360,7 @@ function validateDatasetFolder(root2) {
185715
186360
  }
185716
186361
  let args;
185717
186362
  try {
185718
- const parsed = JSON.parse(readFileSync8(argsPath, "utf-8"));
186363
+ const parsed = JSON.parse(readFileSync9(argsPath, "utf-8"));
185719
186364
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
185720
186365
  issues.push({
185721
186366
  field: `examples/${exampleName}/input/arguments.json`,
@@ -185773,7 +186418,7 @@ function validateDatasetFolder(root2) {
185773
186418
  if (existsSync9(expectedPath)) {
185774
186419
  let parsed;
185775
186420
  try {
185776
- parsed = JSON.parse(readFileSync8(expectedPath, "utf-8"));
186421
+ parsed = JSON.parse(readFileSync9(expectedPath, "utf-8"));
185777
186422
  } catch {
185778
186423
  issues.push({
185779
186424
  field: `examples/${exampleName}/expected/output.json`,
@@ -186316,7 +186961,7 @@ async function readDirAsZip(dir) {
186316
186961
  }
186317
186962
  return zipSync(tree);
186318
186963
  }
186319
- async function downloadStreamToFile(client, path16, outFile) {
186964
+ async function downloadStreamToFile2(client, path16, outFile) {
186320
186965
  const res = await client.getStream(path16);
186321
186966
  const buf = Buffer.from(await res.arrayBuffer());
186322
186967
  if (outFile) {
@@ -186620,7 +187265,7 @@ function registerDatasetCommands2(parent) {
186620
187265
  const pullCmd = dataset.command("pull <workflow-id>").description(descriptionFor("workflow_get_dataset")).option("--out <zip>", "Write the dataset ZIP to this path. When omitted, the binary streams to stdout.");
186621
187266
  withBaseUrl(pullCmd).action(action(async (workflow2, opts) => {
186622
187267
  const { client, workflowId } = await buildClientForWorkflow(workflow2, opts);
186623
- await downloadStreamToFile(client, `/api/v1/workflows/${workflowId}/dataset/export`, opts.out);
187268
+ await downloadStreamToFile2(client, `/api/v1/workflows/${workflowId}/dataset/export`, opts.out);
186624
187269
  }));
186625
187270
  const pushCmd = dataset.command("push <workflow-id>").description(descriptionFor("workflow_set_dataset")).requiredOption("--file <path>", "Path to a dataset ZIP file or a dataset/ folder (folder is zipped in memory before upload)").option("--mode <append|replace>", "Import mode (default: append)", "append").option("--yes", "Skip the destructive confirmation prompt for --mode replace (use in CI)", false).addHelpText("after", `
186626
187271
  Examples:
@@ -187069,7 +187714,7 @@ Behavior:
187069
187714
  const params = new URLSearchParams({ format: opts.format });
187070
187715
  if (batchId)
187071
187716
  params.set("batchId", batchId);
187072
- await downloadStreamToFile(client, `/api/v1/workflows/${workflowId}/eval-results/export?${params.toString()}`, opts.out);
187717
+ await downloadStreamToFile2(client, `/api/v1/workflows/${workflowId}/eval-results/export?${params.toString()}`, opts.out);
187073
187718
  }));
187074
187719
  const compareCmd = experiment.command("compare <batchIdA> <batchIdB>").description("Diff eval scores between two experiment batches.").option("--sort <abs-delta-desc|delta-asc|delta-desc|name>", "Row sort order (default: biggest movers first)", "abs-delta-desc").option("--regression-threshold <n>", "Δ below this is flagged as a regression (default 0.05)", Number.parseFloat, 0.05).addHelpText("after", `
187075
187720
  Examples:
@@ -187157,7 +187802,7 @@ Behavior:
187157
187802
  return;
187158
187803
  const params = new URLSearchParams({ format: opts.format, batchId });
187159
187804
  try {
187160
- await downloadStreamToFile(client, `/api/v1/workflows/${workflowId}/eval-results/export?${params.toString()}`, dest);
187805
+ await downloadStreamToFile2(client, `/api/v1/workflows/${workflowId}/eval-results/export?${params.toString()}`, dest);
187161
187806
  } catch (err2) {
187162
187807
  error51(`Watch finished but pulling results failed: ${err2 instanceof Error ? err2.message : String(err2)}. Re-run \`experiment results <wf> <batch>\` to retry.`);
187163
187808
  process.exit(1);
@@ -187358,6 +188003,39 @@ function registerStepTypeCommands(parent) {
187358
188003
  });
187359
188004
  }
187360
188005
 
188006
+ // src/lib/command-aliases.ts
188007
+ var CONVENTION_ALIASES = new Map([
188008
+ ["artifacts", "artifact"],
188009
+ ["execution", "exec"],
188010
+ ["experiment", "exp"],
188011
+ ["feedback", "fb"],
188012
+ ["list", "ls"],
188013
+ ["compare", "diff"]
188014
+ ]);
188015
+ function applyCommandAliasConventions(root2) {
188016
+ for (const command of root2.commands) {
188017
+ applySiblingAliases(command.parent ?? root2);
188018
+ applyCommandAliasConventions(command);
188019
+ }
188020
+ }
188021
+ function applySiblingAliases(parent) {
188022
+ const reserved = new Set;
188023
+ for (const sibling of parent.commands) {
188024
+ reserved.add(sibling.name());
188025
+ for (const alias of sibling.aliases())
188026
+ reserved.add(alias);
188027
+ }
188028
+ for (const command of parent.commands) {
188029
+ const alias = CONVENTION_ALIASES.get(command.name());
188030
+ if (!alias || command.aliases().includes(alias))
188031
+ continue;
188032
+ if (reserved.has(alias))
188033
+ continue;
188034
+ command.aliases([...command.aliases(), alias]);
188035
+ reserved.add(alias);
188036
+ }
188037
+ }
188038
+
187361
188039
  // src/lib/logo.ts
187362
188040
  var LOGO_WIDTH = 22;
187363
188041
  var LOGO_LINES = [
@@ -187803,6 +188481,7 @@ skillCmd.command("list").description("Show every tool that has an Eigenpal skill
187803
188481
  process.exit(1);
187804
188482
  }
187805
188483
  });
188484
+ applyCommandAliasConventions(program2);
187806
188485
  function isEntryPoint() {
187807
188486
  const argv1 = process.argv[1];
187808
188487
  if (!argv1)