@pome-sh/cli 0.36.1 → 0.38.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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "package": "pome-sh",
3
- "version": "0.36.1",
4
- "git_sha": "f47a76e4951781e34bc063b31b2b1c1bb400802b",
5
- "build_time": "2026-08-30T00:32:59.132Z"
3
+ "version": "0.38.0",
4
+ "git_sha": "cf682a4d73f8a19d38a0d6a934fdef5eae82bb50",
5
+ "build_time": "2026-08-30T04:48:25.959Z"
6
6
  }
@@ -735,21 +735,11 @@ async function runSessionCreate(opts) {
735
735
  await writeSecretsFile(opts.secretsFile, formatEnvExport(session, twins));
736
736
  console.error(`Wrote sandbox secrets to ${opts.secretsFile} (mode 0600).`);
737
737
  }
738
- if (opts.format === "json") {
738
+ if (opts.json) {
739
739
  const payload = redactSession(session);
740
740
  console.log(JSON.stringify(payload, null, 2));
741
741
  return;
742
742
  }
743
- if (opts.format === "env") {
744
- if (opts.secretsFile) {
745
- return;
746
- }
747
- console.error(
748
- "Refusing to print environment exports. Use --secrets-file <path> to write them to a 0600 file."
749
- );
750
- process.exitCode = 2;
751
- return;
752
- }
753
743
  console.error(`Sandbox: ${session.session_id}`);
754
744
  console.error(`Expires: ${session.expires_at}`);
755
745
  if (opts.seedPath !== void 0) {
@@ -797,7 +787,7 @@ async function runSessionList(opts) {
797
787
  const all = await client.listSessions({ limit: fetchLimit });
798
788
  const filtered = all.filter((r) => matchesStateFilter(r.state, opts.state));
799
789
  const rows = filtered.slice(0, opts.limit);
800
- if (opts.format === "json") {
790
+ if (opts.json) {
801
791
  console.log(JSON.stringify(rows, null, 2));
802
792
  return;
803
793
  }
@@ -1,5 +1,5 @@
1
1
  import { newGroupId } from './chunk-JNXZBK3O.js';
2
- import { runTaskHosted, resolveRunAgentIdentity } from './chunk-77EGSHLT.js';
2
+ import { runTaskHosted, resolveRunAgentIdentity } from './chunk-3NQUFSIX.js';
3
3
  import { createHostedClient, parseTaskFile, outcomeOf, isNarrated, criterionPhrase, narratorReadingLines } from './chunk-BS47AE55.js';
4
4
  import './chunk-VPXIGCZW.js';
5
5
  import './chunk-NW7HGA2K.js';
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { DEFAULT_CONTROL_PLANE_URL, DEFAULT_DASHBOARD_URL, clearLocalCredentials, friendlyHostedError, SESSION_TWIN_NAMES, runSessionCreate, runSessionList, runSessionStop, resolveCredentials, runTaskHosted, discoverRunSet, VERDICT_ARTIFACT_VERSION, persistCredentialsAfterLogin, DEFAULT_DOCS_SITE_ORIGIN, resolveSeams, resolveCachedAgentId, readLinkCache, postAgentResolver, writeLinkCache, ensurePomeGitignored } from '../../chunk-77EGSHLT.js';
2
+ import { DEFAULT_CONTROL_PLANE_URL, DEFAULT_DASHBOARD_URL, clearLocalCredentials, friendlyHostedError, SESSION_TWIN_NAMES, runSessionCreate, runSessionList, runSessionStop, resolveCredentials, runTaskHosted, discoverRunSet, VERDICT_ARTIFACT_VERSION, persistCredentialsAfterLogin, DEFAULT_DOCS_SITE_ORIGIN, resolveSeams, resolveCachedAgentId, readLinkCache, postAgentResolver, writeLinkCache, ensurePomeGitignored } from '../../chunk-3NQUFSIX.js';
3
3
  import { assetPath, runTask, resolvePackageRoot, DEMO_TASK_NAME, demoTaskPath } from '../../chunk-AEFXTGW3.js';
4
4
  import { parseTaskFile, scoreStatus, runScoreLine, narratorReadingLines, readLatestRun, readMetaSummary, outcomeOf, readConfigTwins, scoreCountsSummary, criterionRowLine, readCodeCriteria, createHostedClient, toTwinHttpEvent, redactJsonl, scoreFromFinalizeResponse, parseGitHubSeedState, uploadRunBlobs, isPreSatisfied } from '../../chunk-BS47AE55.js';
5
5
  import '../../chunk-VPXIGCZW.js';
@@ -12,7 +12,7 @@ import '../../chunk-5NPGY73F.js';
12
12
  import { TWIN_NAME_LIST, isTwinName, createGitHubSmokeApp } from '../../chunk-RPPF2KDQ.js';
13
13
  import { readManifest, writeManifest, MANIFEST_JSON, readRequiredManifest, normalizeManifestTwins } from '../../chunk-DFOQGAKS.js';
14
14
  import '../../chunk-XDU6TD4O.js';
15
- import { MOUNTED_TWINS, deriveAgentSlug, exitCodeFor, HostedUsageError, HostedOrchError, HostedAuthError, HostedQuotaError } from '../../chunk-NNXVR46L.js';
15
+ import { MOUNTED_TWINS, deriveAgentSlug, exitCodeFor, HostedUsageError, HostedOrchError } from '../../chunk-NNXVR46L.js';
16
16
  import '../../chunk-CBFKZZBR.js';
17
17
  import { TAPE_ASSERTABLE_TOOLS } from '../../chunk-C4BVTUA3.js';
18
18
  import { seedSchema } from '../../chunk-NBOQN5VX.js';
@@ -727,99 +727,6 @@ async function compileSeed(prose, opts = {}) {
727
727
  durationMs
728
728
  };
729
729
  }
730
- var DEFAULT_TIMEOUT_MS = 6e4;
731
- var responseSchema = z.object({
732
- seed: z.unknown(),
733
- source_hash: z.string(),
734
- model: z.string(),
735
- compiled_at: z.string(),
736
- cached: z.boolean().optional(),
737
- // Server can return usage metadata for transparency. Optional — older
738
- // server versions or cache-hit responses may omit it.
739
- input_tokens: z.number().int().nonnegative().optional(),
740
- output_tokens: z.number().int().nonnegative().optional(),
741
- cost_cents: z.number().nonnegative().optional()
742
- });
743
- var errorBodySchema = z.object({
744
- error: z.object({
745
- type: z.string().optional(),
746
- message: z.string().optional(),
747
- request_id: z.string().optional()
748
- }).optional()
749
- });
750
- async function compileSeedHosted(prose, opts) {
751
- const creds = await resolveCredentials({ apiBaseUrl: opts.apiBaseUrl });
752
- const t0 = Date.now();
753
- const controller = new AbortController();
754
- const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
755
- const timer = setTimeout(() => controller.abort(), timeoutMs);
756
- let res;
757
- try {
758
- res = await fetch(`${creds.apiBaseUrl}/v1/scenarios/compile-seed`, {
759
- method: "POST",
760
- headers: {
761
- "content-type": "application/json",
762
- "x-api-key": creds.apiKey,
763
- "user-agent": "pome-cli"
764
- },
765
- body: JSON.stringify({
766
- prose,
767
- twin: opts.twin ?? "github",
768
- scenario_path: opts.taskPath
769
- }),
770
- signal: controller.signal
771
- });
772
- } catch (err) {
773
- throw new HostedOrchError(
774
- `Could not reach the Pome control plane at ${creds.apiBaseUrl}: ${err.message}`
775
- );
776
- } finally {
777
- clearTimeout(timer);
778
- }
779
- const durationMs = Date.now() - t0;
780
- if (!res.ok) {
781
- await throwForStatus(res);
782
- }
783
- let parsed;
784
- try {
785
- const body = await res.json();
786
- parsed = responseSchema.parse(body);
787
- } catch (err) {
788
- throw new HostedOrchError(
789
- `Control plane returned a response we could not parse: ${err.message}`
790
- );
791
- }
792
- const seed = parseGitHubSeedState(parsed.seed);
793
- return {
794
- seed,
795
- inputTokens: parsed.input_tokens ?? 0,
796
- outputTokens: parsed.output_tokens ?? 0,
797
- model: parsed.model,
798
- durationMs
799
- };
800
- }
801
- async function throwForStatus(res) {
802
- let body = {};
803
- try {
804
- body = errorBodySchema.parse(await res.json());
805
- } catch {
806
- }
807
- const detail = body.error?.message ?? `HTTP ${res.status}`;
808
- const requestId = body.error?.request_id ?? res.headers.get("x-request-id") ?? void 0;
809
- if (res.status === 401 || res.status === 403) {
810
- throw new HostedAuthError(`Authentication failed: ${detail}`, requestId);
811
- }
812
- if (res.status === 402 || res.status === 429) {
813
- throw new HostedQuotaError(`Quota or rate limit hit: ${detail}`, requestId);
814
- }
815
- if (res.status === 502) {
816
- throw new HostedOrchError(
817
- `Pome's hosted seed compiler hit a temporary capacity limit. Drop \`--hosted\` (or set ANTHROPIC_API_KEY then re-run \`pome compile-seeds --force\`) to compile locally via BYOK, or retry in a minute.`,
818
- requestId
819
- );
820
- }
821
- throw new HostedOrchError(`Compile-seed failed (HTTP ${res.status}): ${detail}`, requestId);
822
- }
823
730
 
824
731
  // src/task/seed-verifier.ts
825
732
  async function verifySeedWithTwin(seed) {
@@ -853,14 +760,15 @@ async function runCompileSeeds(target, opts) {
853
760
  const stamp = statusStamp(r.status);
854
761
  const tail = r.message ? ` \u2014 ${r.message}` : "";
855
762
  const cost = r.inputTokens !== void 0 ? ` (${r.inputTokens} in / ${r.outputTokens} out, ${r.durationMs}ms)` : "";
856
- console.error(`${stamp} ${r.path}${tail}${cost}`);
763
+ const line = `${stamp} ${r.path}${tail}${cost}`;
764
+ if (r.status === "error") console.error(line);
765
+ else console.log(line);
857
766
  }
858
767
  const errors = results.filter((r) => r.status === "error");
859
768
  if (errors.length > 0) {
860
769
  console.error(`
861
770
  ${errors.length} error(s).`);
862
- const worstHosted = errors.reduce((max, r) => Math.max(max, r.exitCode ?? 0), 0);
863
- return worstHosted > 0 ? worstHosted : 1;
771
+ return 1;
864
772
  }
865
773
  return 0;
866
774
  }
@@ -900,7 +808,7 @@ async function compileOne(taskPath, opts) {
900
808
  message: `hand-authored seed left untouched (${sidecarPath}) \u2014 delete it or drop its _meta to recompile`
901
809
  };
902
810
  }
903
- if (!opts.force && !opts.hosted && existsSync(sidecarPath)) {
811
+ if (!opts.force && existsSync(sidecarPath)) {
904
812
  const cached = await readSidecarMeta(sidecarPath);
905
813
  if (cached && cached.source_hash === proseHash && cached.model === COMPILER_MODEL) {
906
814
  return { path: taskPath, status: "skipped-cached", message: `up-to-date (${sidecarPath})` };
@@ -908,13 +816,12 @@ async function compileOne(taskPath, opts) {
908
816
  }
909
817
  let result;
910
818
  try {
911
- result = opts.hosted ? await compileSeedHosted(seedText, { apiBaseUrl: opts.apiBaseUrl, taskPath }) : await compileSeed(seedText);
819
+ result = await compileSeed(seedText);
912
820
  } catch (err) {
913
821
  return {
914
822
  path: taskPath,
915
823
  status: "error",
916
- message: `compile failed: ${err.message}`,
917
- exitCode: opts.hosted ? exitCodeFor(err) : void 0
824
+ message: `compile failed: ${err.message}`
918
825
  };
919
826
  }
920
827
  try {
@@ -1222,8 +1129,13 @@ function bold2(s) {
1222
1129
  return useColor2() ? `\x1B[1m${s}\x1B[0m` : s;
1223
1130
  }
1224
1131
  async function runTasksCommand(twinArg, opts) {
1132
+ if (!opts.copy && (opts.force || opts.dest)) {
1133
+ console.error("`--force` and `--dest` only do anything with `--copy`.");
1134
+ process.exitCode = 2;
1135
+ return;
1136
+ }
1225
1137
  if (!twinArg) {
1226
- if (opts.copy || opts.force || opts.dest) {
1138
+ if (opts.copy) {
1227
1139
  console.error("Specify a twin to copy from, e.g. `pome tasks github --copy`.");
1228
1140
  process.exitCode = 2;
1229
1141
  return;
@@ -1278,11 +1190,9 @@ function printTwinTasks(twin) {
1278
1190
  `Copy locally: \`pome tasks ${twin.id} --copy\` (or \`--copy --dest <dir>\`).`
1279
1191
  )
1280
1192
  );
1281
- console.log(
1282
- dim2(
1283
- `Run one: \`pome run tasks/${runnable[0]?.filename ?? "01-bug-happy-path.md"}\`.`
1284
- )
1285
- );
1193
+ if (runnable[0]) {
1194
+ console.log(dim2(`Run one: \`pome run tasks/${runnable[0].filename}\`.`));
1195
+ }
1286
1196
  }
1287
1197
  async function copyTwinTasks(twin, opts) {
1288
1198
  const root = resolvePackageRoot(import.meta.url);
@@ -1302,14 +1212,18 @@ async function copyTwinTasks(twin, opts) {
1302
1212
  destDir,
1303
1213
  force: opts.force
1304
1214
  });
1215
+ const written = outcome.copied.length + outcome.overwritten.length;
1305
1216
  console.log(
1306
1217
  bold2(
1307
- `Copied ${outcome.copied.length} ${twin.label} task${outcome.copied.length === 1 ? "" : "s"} into ${opts.destDir}/.`
1218
+ `Copied ${written} ${twin.label} task${written === 1 ? "" : "s"} into ${opts.destDir}/.`
1308
1219
  )
1309
1220
  );
1310
1221
  for (const file of outcome.copied) {
1311
1222
  console.log(` ${dim2("+")} ${file}`);
1312
1223
  }
1224
+ for (const file of outcome.overwritten) {
1225
+ console.log(` ${dim2("~")} ${file} ${dim2("(overwritten)")}`);
1226
+ }
1313
1227
  for (const file of outcome.skipped) {
1314
1228
  console.log(
1315
1229
  ` ${dim2("-")} ${file} ${dim2("(exists \u2014 pass --force to overwrite)")}`
@@ -1325,7 +1239,7 @@ async function copyTwinTasks(twin, opts) {
1325
1239
  return;
1326
1240
  }
1327
1241
  console.log("");
1328
- const first = outcome.copied[0] ?? outcome.skipped[0];
1242
+ const first = runnableTasks(twin)[0]?.filename;
1329
1243
  if (first) {
1330
1244
  console.log(
1331
1245
  dim2(`Next: \`pome run ${opts.destDir}/${first}\`.`)
@@ -1333,7 +1247,7 @@ async function copyTwinTasks(twin, opts) {
1333
1247
  }
1334
1248
  }
1335
1249
  async function copyTaskFiles(input) {
1336
- const outcome = { copied: [], skipped: [], missingSources: [] };
1250
+ const outcome = { copied: [], overwritten: [], skipped: [], missingSources: [] };
1337
1251
  for (const task of input.tasks) {
1338
1252
  const src = join(input.sourceDir, task.filename);
1339
1253
  const dest = join(input.destDir, task.filename);
@@ -1341,22 +1255,24 @@ async function copyTaskFiles(input) {
1341
1255
  outcome.missingSources.push(task.filename);
1342
1256
  continue;
1343
1257
  }
1344
- if (existsSync(dest) && !input.force) {
1258
+ const destExists = existsSync(dest);
1259
+ if (destExists && !input.force) {
1345
1260
  outcome.skipped.push(task.filename);
1346
1261
  } else {
1347
1262
  await copyFile(src, dest);
1348
- outcome.copied.push(task.filename);
1263
+ (destExists ? outcome.overwritten : outcome.copied).push(task.filename);
1349
1264
  }
1350
1265
  const sidecar = task.filename.replace(/\.md$/i, ".seed.json");
1351
1266
  const sidecarSrc = join(input.sourceDir, sidecar);
1352
1267
  const sidecarDest = join(input.destDir, sidecar);
1353
1268
  if (!existsSync(sidecarSrc)) continue;
1354
- if (existsSync(sidecarDest) && !input.force) {
1269
+ const sidecarExists = existsSync(sidecarDest);
1270
+ if (sidecarExists && !input.force) {
1355
1271
  outcome.skipped.push(sidecar);
1356
1272
  continue;
1357
1273
  }
1358
1274
  await copyFile(sidecarSrc, sidecarDest);
1359
- outcome.copied.push(sidecar);
1275
+ (sidecarExists ? outcome.overwritten : outcome.copied).push(sidecar);
1360
1276
  }
1361
1277
  return outcome;
1362
1278
  }
@@ -3391,11 +3307,19 @@ function formatSkewRefusal(twin, findings) {
3391
3307
 
3392
3308
  // src/cli/checks-add.ts
3393
3309
  function parseArgFlags(pairs) {
3394
- const args = {};
3310
+ const args = /* @__PURE__ */ Object.create(null);
3395
3311
  for (const pair2 of pairs) {
3396
3312
  const eq = pair2.indexOf("=");
3397
- if (eq <= 0) return { error: `--arg must be key=value, got ${JSON.stringify(pair2)}` };
3398
- args[pair2.slice(0, eq)] = pair2.slice(eq + 1);
3313
+ if (eq <= 0) {
3314
+ console.error(`--arg must be key=value, got ${JSON.stringify(pair2)}`);
3315
+ return null;
3316
+ }
3317
+ const key = pair2.slice(0, eq);
3318
+ if (Object.hasOwn(args, key)) {
3319
+ console.error(`--arg ${key} given twice. Pass each parameter once.`);
3320
+ return null;
3321
+ }
3322
+ args[key] = pair2.slice(eq + 1);
3399
3323
  }
3400
3324
  return args;
3401
3325
  }
@@ -3454,9 +3378,10 @@ async function pickInteractively(source, seams) {
3454
3378
  }
3455
3379
  return picked;
3456
3380
  }
3457
- async function promptArgs(def, seams) {
3458
- const args = {};
3381
+ async function promptArgs(def, seams, known) {
3382
+ const args = { ...known };
3459
3383
  for (const name of templateSlots(def.template).params) {
3384
+ if (args[name] !== void 0) continue;
3460
3385
  const type = def.params[name];
3461
3386
  const valid = new RegExp(`^${type.pattern}$`);
3462
3387
  for (let attempt = 0; attempt < 3; attempt += 1) {
@@ -3468,7 +3393,10 @@ async function promptArgs(def, seams) {
3468
3393
  }
3469
3394
  console.error(` not a valid ${name} \u2014 it should look like ${type.example}`);
3470
3395
  }
3471
- if (args[name] === void 0) return { error: `Gave up on \`${name}\` after three tries.` };
3396
+ if (args[name] === void 0) {
3397
+ console.error(`Gave up on \`${name}\` after three tries.`);
3398
+ return null;
3399
+ }
3472
3400
  }
3473
3401
  return args;
3474
3402
  }
@@ -3486,8 +3414,10 @@ async function runChecksAddCommand(file, opts) {
3486
3414
  if (opts.check) {
3487
3415
  picked = findCheck(opts.check);
3488
3416
  if (!picked) {
3417
+ const twins = readConfigTwins(source);
3418
+ const declared = twins.flatMap((twin2) => [...checksFor(twin2)]).map((c) => c.id);
3489
3419
  console.error(
3490
- `Unknown check "${opts.check}". Run \`pome checks <twin>\` to see the declared set; github declares: ${checksFor("github").map((c) => c.id).join(", ")}.`
3420
+ `Unknown check "${opts.check}". Run \`pome checks <twin>\` to see the declared set; this task's twins (${twins.join(", ")}) declare: ${declared.join(", ") || "none"}.`
3491
3421
  );
3492
3422
  process.exitCode = 2;
3493
3423
  return;
@@ -3496,14 +3426,25 @@ async function runChecksAddCommand(file, opts) {
3496
3426
  picked = await pickInteractively(source, seams);
3497
3427
  if (!picked) return;
3498
3428
  }
3499
- const parsed = opts.check ? parseArgFlags(opts.arg) : await promptArgs(picked, seams);
3500
- if ("error" in parsed) {
3501
- console.error(parsed.error);
3429
+ const fromFlags = parseArgFlags(opts.arg);
3430
+ if (!fromFlags) {
3431
+ process.exitCode = 2;
3432
+ return;
3433
+ }
3434
+ const args = opts.check ? fromFlags : await promptArgs(picked, seams, fromFlags);
3435
+ if (!args) {
3502
3436
  process.exitCode = 2;
3503
3437
  return;
3504
3438
  }
3505
- const args = parsed;
3506
3439
  const slots = templateSlots(picked.template).params;
3440
+ const extra = Object.keys(args).filter((key) => !slots.includes(key));
3441
+ if (extra.length > 0) {
3442
+ console.error(
3443
+ `${picked.id} does not declare: ${extra.map((k) => JSON.stringify(k)).join(", ")}. It takes: ${slots.join(", ")}.`
3444
+ );
3445
+ process.exitCode = 2;
3446
+ return;
3447
+ }
3507
3448
  for (const name of slots) {
3508
3449
  const type = picked.params[name];
3509
3450
  const value = args[name];
@@ -3520,14 +3461,6 @@ async function runChecksAddCommand(file, opts) {
3520
3461
  return;
3521
3462
  }
3522
3463
  }
3523
- const extra = Object.keys(args).filter((key) => !slots.includes(key));
3524
- if (extra.length > 0) {
3525
- console.error(
3526
- `${picked.id} does not declare: ${extra.join(", ")}. It takes: ${slots.join(", ")}.`
3527
- );
3528
- process.exitCode = 2;
3529
- return;
3530
- }
3531
3464
  const twin = twinOf(picked.id);
3532
3465
  const fetchRemote = opts.fetchRemote ?? (async (t) => liveFetch(
3533
3466
  await resolveCredentials({
@@ -4642,7 +4575,7 @@ function firstSentence(description) {
4642
4575
  function resolveExampleRef(env = process.env) {
4643
4576
  const override = env.POME_EXAMPLE_REF?.trim();
4644
4577
  if (override) return override;
4645
- const baked = "f47a76e4951781e34bc063b31b2b1c1bb400802b".trim() ;
4578
+ const baked = "cf682a4d73f8a19d38a0d6a934fdef5eae82bb50".trim() ;
4646
4579
  return FULL_SHA.test(baked) ? baked : "main";
4647
4580
  }
4648
4581
  function rawUrlFor(example, file, ref) {
@@ -4991,13 +4924,12 @@ async function loadTrialEvents(runDir) {
4991
4924
 
4992
4925
  // src/cli/main.ts
4993
4926
  var PACKAGE_VERSION = readPackageVersion();
4994
- var SESSION_CREATE_FORMATS = /* @__PURE__ */ new Set(["text", "json", "env"]);
4995
4927
  var DEFAULT_AGENT_FILE = "examples/agents/scripted-triage-agent.ts";
4996
4928
  var DEFAULT_AGENT_COMMAND = `node ${DEFAULT_AGENT_FILE}`;
4997
4929
  var MANIFEST_SCHEMA_URL = "https://pome.sh/schemas/v1/pome.json";
4998
4930
  var MAX_UNREADABLE_PATHS_SHOWN = 5;
4999
4931
  function readPackageVersion() {
5000
- if ("0.36.1".length > 0) return "0.36.1";
4932
+ if ("0.38.0".length > 0) return "0.38.0";
5001
4933
  try {
5002
4934
  const here = dirname(fileURLToPath(import.meta.url));
5003
4935
  const candidates = [
@@ -5214,22 +5146,10 @@ function createProgram() {
5214
5146
  checks.command("lint").argument("<file...>", "Task markdown file(s) \u2014 shell globs work: tasks/*.md").description("Report [code] criteria that bind no declared check, so are never graded").action(async (files) => {
5215
5147
  await runChecksLintCommand(files);
5216
5148
  });
5217
- program.command("compile-seeds").summary("Compile a task's seed state to JSON").argument("[target]", "Task .md file or directory (defaults to ./tasks)").option("--force", "Recompile even if the sidecar's source hash matches", false).option(
5218
- "--hosted",
5219
- "Compile via the Pome control plane instead of calling Anthropic directly (uses your Pome API key; no ANTHROPIC_API_KEY needed)",
5220
- false
5221
- ).option(
5222
- "--api-url <url>",
5223
- "Control-plane base URL (only relevant with --hosted).",
5224
- process.env.POME_API_URL ?? DEFAULT_CONTROL_PLANE_URL
5225
- ).description(
5226
- "Compile prose `## Seed State` sections into sidecar .seed.json files (local: ANTHROPIC_API_KEY; --hosted: routes through Pome cloud)"
5149
+ program.command("compile-seeds").summary("Compile prose seed state to JSON via Claude").argument("[target]", "Task .md file or directory (defaults to ./tasks)").option("--force", "Recompile even if the sidecar's source hash matches", false).description(
5150
+ "Compile prose `## Seed State` sections into sidecar .seed.json files \u2014 one Claude call per file, billed to your ANTHROPIC_API_KEY"
5227
5151
  ).action(async (target, opts) => {
5228
- const code = await runCompileSeeds(target, {
5229
- force: opts.force,
5230
- hosted: opts.hosted,
5231
- apiBaseUrl: opts.apiUrl
5232
- });
5152
+ const code = await runCompileSeeds(target, { force: opts.force });
5233
5153
  if (code !== 0) process.exitCode = code;
5234
5154
  });
5235
5155
  const register = program.command("register").summary("Register an agent with Pome").description(
@@ -5293,23 +5213,13 @@ function createProgram() {
5293
5213
  ).option(
5294
5214
  "--secrets-file <path>",
5295
5215
  "Write shell exports containing session secrets to a local file with mode 0600"
5296
- ).option(
5297
- "--format <fmt>",
5298
- "Output format: text, json, or env. env writes the exports to --secrets-file instead of printing them.",
5299
- "text"
5300
- ).action(
5216
+ ).option("--json", "Print the sandbox as JSON instead of the human summary.", false).action(
5301
5217
  async (opts) => {
5302
5218
  try {
5303
- const format = opts.format.trim().toLowerCase();
5304
- if (!SESSION_CREATE_FORMATS.has(format)) {
5305
- console.error("Unknown session create format. Use one of: text, json, env.");
5306
- process.exitCode = 2;
5307
- return;
5308
- }
5309
5219
  await runSessionCreate({
5310
5220
  apiBaseUrl: opts.apiUrl,
5311
5221
  twins: opts.twin ?? [],
5312
- format,
5222
+ json: opts.json,
5313
5223
  secretsFile: opts.secretsFile,
5314
5224
  seedPath: opts.seed
5315
5225
  });
@@ -5327,7 +5237,7 @@ function createProgram() {
5327
5237
  "--state <state>",
5328
5238
  "Filter by sandbox state: running, ready, done, expired, or all. `running` also matches the server-side `ready` state, the way the dashboard shows them in one column.",
5329
5239
  "running"
5330
- ).option("--format <fmt>", "Output format: text or json", "text").action(
5240
+ ).option("--json", "Print the sandboxes as JSON.", false).action(
5331
5241
  async (opts) => {
5332
5242
  const validStates = [
5333
5243
  "running",
@@ -5348,7 +5258,7 @@ function createProgram() {
5348
5258
  apiBaseUrl: opts.apiUrl,
5349
5259
  limit: Number.parseInt(opts.limit, 10) || 20,
5350
5260
  state: opts.state,
5351
- format: opts.format
5261
+ json: opts.json
5352
5262
  });
5353
5263
  } catch (err) {
5354
5264
  console.error(friendlyHostedError(err));
@@ -5514,7 +5424,7 @@ function createProgram() {
5514
5424
  taskForRuns.config.runs
5515
5425
  );
5516
5426
  if (k > 1) {
5517
- const { runTrialGroup } = await import('../../runTrialGroup-FZUMQLDH.js');
5427
+ const { runTrialGroup } = await import('../../runTrialGroup-YACZ2WTV.js');
5518
5428
  const fileForRerun = relative(process.cwd(), file);
5519
5429
  const rerunCommand = defaultTask ? options.trials !== void 0 ? `pome run -n ${k}` : "pome run" : `pome run ${fileForRerun && !fileForRerun.startsWith("..") ? fileForRerun : file} -n ${k}`;
5520
5430
  const groupResult = await runTrialGroup({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pome-sh/cli",
3
- "version": "0.36.1",
3
+ "version": "0.38.0",
4
4
  "description": "Test AI agents against digital twins of real SaaS APIs. Records tool-call traces and scores them on pome.sh.",
5
5
  "keywords": [
6
6
  "ai",