@pome-sh/cli 0.39.1 → 0.40.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.39.1",
4
- "git_sha": "ad57e84671dd2e6a2fb0dc3b66a78d97b95ed1c7",
5
- "build_time": "2026-08-30T05:08:05.900Z"
3
+ "version": "0.40.0",
4
+ "git_sha": "18ff79b115d837fa3081e5925664bd24f5843c8c",
5
+ "build_time": "2026-08-30T05:50:34.377Z"
6
6
  }
@@ -440,7 +440,7 @@ function mapHttpError(status, json) {
440
440
  }
441
441
  if (status === 404) {
442
442
  return new HostedOrchError(
443
- err?.message ?? "POST /v1/agents is not available at this API URL. Upgrade pome-cloud or check that --api-url/POME_API_URL points at a version that supports agent registration."
443
+ err?.message ?? "POST /v1/agents returned 404 \u2014 check that --api-url/POME_API_URL points at a Pome control plane."
444
444
  );
445
445
  }
446
446
  return new HostedOrchError(err?.message ?? `POST /v1/agents \u2192 HTTP ${status}`);
@@ -1,5 +1,5 @@
1
1
  import { newGroupId } from './chunk-JNXZBK3O.js';
2
- import { runTaskHosted, resolveRunAgentIdentity } from './chunk-3NQUFSIX.js';
2
+ import { runTaskHosted, resolveRunAgentIdentity } from './chunk-G7252TQ3.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-3NQUFSIX.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-G7252TQ3.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';
@@ -4575,7 +4575,7 @@ function firstSentence(description) {
4575
4575
  function resolveExampleRef(env = process.env) {
4576
4576
  const override = env.POME_EXAMPLE_REF?.trim();
4577
4577
  if (override) return override;
4578
- const baked = "ad57e84671dd2e6a2fb0dc3b66a78d97b95ed1c7".trim() ;
4578
+ const baked = "18ff79b115d837fa3081e5925664bd24f5843c8c".trim() ;
4579
4579
  return FULL_SHA.test(baked) ? baked : "main";
4580
4580
  }
4581
4581
  function rawUrlFor(example, file, ref) {
@@ -4929,7 +4929,7 @@ var DEFAULT_AGENT_COMMAND = `node ${DEFAULT_AGENT_FILE}`;
4929
4929
  var MANIFEST_SCHEMA_URL = "https://pome.sh/schemas/v1/pome.json";
4930
4930
  var MAX_UNREADABLE_PATHS_SHOWN = 5;
4931
4931
  function readPackageVersion() {
4932
- if ("0.39.1".length > 0) return "0.39.1";
4932
+ if ("0.40.0".length > 0) return "0.40.0";
4933
4933
  try {
4934
4934
  const here = dirname(fileURLToPath(import.meta.url));
4935
4935
  const candidates = [
@@ -4947,8 +4947,16 @@ function readPackageVersion() {
4947
4947
  }
4948
4948
  return "0.0.0";
4949
4949
  }
4950
+ function globals(cmd) {
4951
+ return cmd.optsWithGlobals();
4952
+ }
4950
4953
  function createProgram() {
4951
4954
  const program = new Command();
4955
+ program.configureHelp({ showGlobalOptions: true }).option(
4956
+ "--api-url <url>",
4957
+ "Control-plane base URL.",
4958
+ process.env.POME_API_URL ?? DEFAULT_CONTROL_PLANE_URL
4959
+ ).option("--artifacts-dir <dir>", "Directory for run artifacts", "runs");
4952
4960
  program.name("pome").description(
4953
4961
  "Test AI agents against digital twins of real SaaS APIs. Runs are recorded to app.pome.sh. Start with `pome demo`."
4954
4962
  ).version(PACKAGE_VERSION).showHelpAfterError("(add --help for usage)");
@@ -5060,10 +5068,6 @@ function createProgram() {
5060
5068
  console.error(postInitMessage);
5061
5069
  });
5062
5070
  program.command("login").summary("Sign in and save an API key").description("Sign in with Clerk and store a hosted team API key (macOS Keychain or ~/.pome/credentials.json)").option(
5063
- "--api-url <url>",
5064
- "Control-plane base URL.",
5065
- process.env.POME_API_URL ?? DEFAULT_CONTROL_PLANE_URL
5066
- ).option(
5067
5071
  "--dashboard-url <url>",
5068
5072
  "App URL for Clerk sign-in (must serve /cli/login).",
5069
5073
  process.env.POME_DASHBOARD_URL ?? DEFAULT_DASHBOARD_URL
@@ -5072,8 +5076,8 @@ function createProgram() {
5072
5076
  "Label for the API key minted by this login.",
5073
5077
  "pome login"
5074
5078
  ).action(
5075
- async (options) => {
5076
- await loginWithClerk(options);
5079
+ async (options, cmd) => {
5080
+ await loginWithClerk({ ...options, apiUrl: globals(cmd).apiUrl });
5077
5081
  }
5078
5082
  );
5079
5083
  program.command("logout").summary("Delete the saved API key").description("Remove locally stored hosted credentials (Keychain entry and/or ~/.pome/credentials.json)").action(async () => {
@@ -5130,17 +5134,13 @@ function createProgram() {
5130
5134
  "One per declared parameter. Repeat the flag.",
5131
5135
  (value, previous = []) => [...previous, value],
5132
5136
  []
5133
- ).option(
5134
- "--api-url <url>",
5135
- "Control-plane URL",
5136
- process.env.POME_API_URL ?? DEFAULT_CONTROL_PLANE_URL
5137
5137
  ).description(
5138
5138
  "Add one [code] criterion by picking a declared check \u2014 pome writes the English"
5139
- ).action(async (file, opts) => {
5139
+ ).action(async (file, opts, cmd) => {
5140
5140
  await runChecksAddCommand(file, {
5141
5141
  check: opts.check,
5142
5142
  arg: opts.arg,
5143
- apiBaseUrl: opts.apiUrl
5143
+ apiBaseUrl: globals(cmd).apiUrl
5144
5144
  });
5145
5145
  });
5146
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) => {
@@ -5156,10 +5156,6 @@ function createProgram() {
5156
5156
  "Register a cloud entity (agent, ...) and link this project to it"
5157
5157
  );
5158
5158
  register.command("agent").argument("<name>", 'Human-readable agent name (e.g. "triage-bot")').option(
5159
- "--api-url <url>",
5160
- "Control-plane URL",
5161
- process.env.POME_API_URL ?? DEFAULT_CONTROL_PLANE_URL
5162
- ).option(
5163
5159
  "--force",
5164
5160
  "Re-resolve the agent even when .pome/link.json already links one",
5165
5161
  false
@@ -5169,10 +5165,10 @@ function createProgram() {
5169
5165
  ).description(
5170
5166
  "Create a cloud agent under the current team and write agent.slug to pome.json"
5171
5167
  ).action(
5172
- async (name, opts) => {
5168
+ async (name, opts, cmd) => {
5173
5169
  try {
5174
5170
  await runRegisterAgent({
5175
- apiBaseUrl: opts.apiUrl,
5171
+ apiBaseUrl: globals(cmd).apiUrl,
5176
5172
  dashboardBaseUrl: process.env.POME_DASHBOARD_URL ?? DEFAULT_DASHBOARD_URL,
5177
5173
  name,
5178
5174
  force: opts.force,
@@ -5206,18 +5202,14 @@ function createProgram() {
5206
5202
  ).option(
5207
5203
  "--seed <path>",
5208
5204
  "Start the sandbox from a JSON or YAML seed file instead of each twin's default. A seed REPLACES the default; it does not merge. Same file `pome twin start --seed` takes; write one with `pome twin seed <name>`."
5209
- ).option(
5210
- "--api-url <url>",
5211
- "Control-plane URL",
5212
- process.env.POME_API_URL ?? DEFAULT_CONTROL_PLANE_URL
5213
5205
  ).option(
5214
5206
  "--secrets-file <path>",
5215
5207
  "Write shell exports containing session secrets to a local file with mode 0600"
5216
5208
  ).option("--json", "Print the sandbox as JSON instead of the human summary.", false).action(
5217
- async (opts) => {
5209
+ async (opts, cmd) => {
5218
5210
  try {
5219
5211
  await runSessionCreate({
5220
- apiBaseUrl: opts.apiUrl,
5212
+ apiBaseUrl: globals(cmd).apiUrl,
5221
5213
  twins: opts.twin ?? [],
5222
5214
  json: opts.json,
5223
5215
  secretsFile: opts.secretsFile,
@@ -5229,16 +5221,12 @@ function createProgram() {
5229
5221
  }
5230
5222
  }
5231
5223
  );
5232
- session.command("list").description("List hosted sandboxes (defaults to --state running, like the dashboard)").option(
5233
- "--api-url <url>",
5234
- "Control-plane URL",
5235
- process.env.POME_API_URL ?? DEFAULT_CONTROL_PLANE_URL
5236
- ).option("--limit <n>", "Max rows", "20").option(
5224
+ session.command("list").description("List hosted sandboxes (defaults to --state running, like the dashboard)").option("--limit <n>", "Max rows", "20").option(
5237
5225
  "--state <state>",
5238
5226
  "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.",
5239
5227
  "running"
5240
5228
  ).option("--json", "Print the sandboxes as JSON.", false).action(
5241
- async (opts) => {
5229
+ async (opts, cmd) => {
5242
5230
  const validStates = [
5243
5231
  "running",
5244
5232
  "ready",
@@ -5255,7 +5243,7 @@ function createProgram() {
5255
5243
  }
5256
5244
  try {
5257
5245
  await runSessionList({
5258
- apiBaseUrl: opts.apiUrl,
5246
+ apiBaseUrl: globals(cmd).apiUrl,
5259
5247
  limit: Number.parseInt(opts.limit, 10) || 20,
5260
5248
  state: opts.state,
5261
5249
  json: opts.json
@@ -5267,18 +5255,14 @@ function createProgram() {
5267
5255
  }
5268
5256
  );
5269
5257
  session.command("stop").description("Stop a hosted sandbox").argument("<session-id>", "Sandbox id (ses_\u2026)").option(
5270
- "--api-url <url>",
5271
- "Control-plane URL",
5272
- process.env.POME_API_URL ?? DEFAULT_CONTROL_PLANE_URL
5273
- ).option(
5274
5258
  "--discard",
5275
5259
  "Confirm destroying a session whose run has not been graded",
5276
5260
  false
5277
5261
  ).action(
5278
- async (sessionId, opts) => {
5262
+ async (sessionId, opts, cmd) => {
5279
5263
  try {
5280
5264
  await runSessionStop({
5281
- apiBaseUrl: opts.apiUrl,
5265
+ apiBaseUrl: globals(cmd).apiUrl,
5282
5266
  sessionId,
5283
5267
  discard: opts.discard === true
5284
5268
  });
@@ -5295,10 +5279,6 @@ function createProgram() {
5295
5279
  ).option("--agent <command>", "Command that starts your agent.").option(
5296
5280
  "-n, --trials <count>",
5297
5281
  "Number of trials to run as one group, 1 to 20. Hosted only; defaults to the task's `runs` field."
5298
- ).option("--artifacts-dir <dir>", "Directory for run artifacts", "runs").option(
5299
- "--api-url <url>",
5300
- "Control-plane base URL.",
5301
- process.env.POME_API_URL ?? DEFAULT_CONTROL_PLANE_URL
5302
5282
  ).option("--agent-model <name>", "Informational; model name recorded on the run.", "unknown").option(
5303
5283
  "--agent-version <version>",
5304
5284
  "Override the manifest's agent.version."
@@ -5311,7 +5291,8 @@ function createProgram() {
5311
5291
  ).description(
5312
5292
  "Run a task, or every task in a directory, and print the score. With no path, runs the demo task Pome copies into your project on first use. Refuses to start when `pome doctor` fails, and there is no --force. See `pome docs cli-run` for trial groups and exit codes."
5313
5293
  ).action(
5314
- async (target, options) => {
5294
+ async (target, options, cmd) => {
5295
+ const { apiUrl, artifactsDir } = globals(cmd);
5315
5296
  let trialsFlag;
5316
5297
  if (options.trials !== void 0) {
5317
5298
  try {
@@ -5400,7 +5381,7 @@ function createProgram() {
5400
5381
  }
5401
5382
  }
5402
5383
  try {
5403
- hostedCreds = useLocal ? null : await resolveCredentials({ apiBaseUrl: options.apiUrl });
5384
+ hostedCreds = useLocal ? null : await resolveCredentials({ apiBaseUrl: apiUrl });
5404
5385
  } catch (err) {
5405
5386
  const code = exitCodeFor(err);
5406
5387
  console.error(err instanceof Error ? err.message : String(err));
@@ -5424,7 +5405,7 @@ function createProgram() {
5424
5405
  taskForRuns.config.runs
5425
5406
  );
5426
5407
  if (k > 1) {
5427
- const { runTrialGroup } = await import('../../runTrialGroup-YACZ2WTV.js');
5408
+ const { runTrialGroup } = await import('../../runTrialGroup-I6FCP2L5.js');
5428
5409
  const fileForRerun = relative(process.cwd(), file);
5429
5410
  const rerunCommand = defaultTask ? options.trials !== void 0 ? `pome run -n ${k}` : "pome run" : `pome run ${fileForRerun && !fileForRerun.startsWith("..") ? fileForRerun : file} -n ${k}`;
5430
5411
  const groupResult = await runTrialGroup({
@@ -5432,7 +5413,7 @@ function createProgram() {
5432
5413
  agentCommand,
5433
5414
  agentCommandSource: options.agent ? "--agent" : configCommand ? "pome.json" : "built-in default",
5434
5415
  trials: k,
5435
- artifactsDir: options.artifactsDir,
5416
+ artifactsDir,
5436
5417
  hosted: {
5437
5418
  baseUrl: hostedCreds.apiBaseUrl,
5438
5419
  apiKey: hostedCreds.apiKey
@@ -5450,7 +5431,7 @@ function createProgram() {
5450
5431
  const result = await runTaskHosted({
5451
5432
  taskPath: file,
5452
5433
  agentCommand,
5453
- artifactsDir: options.artifactsDir,
5434
+ artifactsDir,
5454
5435
  hosted: { baseUrl: hostedCreds.apiBaseUrl, apiKey: hostedCreds.apiKey },
5455
5436
  agentModel: options.agentModel,
5456
5437
  agentVersion: options.agentVersion
@@ -5478,7 +5459,7 @@ function createProgram() {
5478
5459
  const result = await runTask({
5479
5460
  taskPath: file,
5480
5461
  agentCommand,
5481
- artifactsDir: options.artifactsDir,
5462
+ artifactsDir,
5482
5463
  // Commander negates --no-* flags: `--no-capture` → `capture: false`.
5483
5464
  noCapture: options.capture === false
5484
5465
  });
@@ -5505,16 +5486,12 @@ function createProgram() {
5505
5486
  );
5506
5487
  program.command("demo").summary("Run a sample task, no account needed").description(
5507
5488
  "Zero-auth first-run demo: boots a local GitHub twin, runs the bundled demo agent for 5 isolated trials (model calls via pome's anonymous demo gateway), and prints per-trial verdicts evaluated in Pome cloud. No signup, no API keys; ends with a no-login preview link."
5508
- ).option(
5509
- "--api-url <url>",
5510
- "Control-plane base URL.",
5511
- process.env.POME_API_BASE ?? process.env.POME_API_URL ?? DEFAULT_CONTROL_PLANE_URL
5512
5489
  ).option(
5513
5490
  "--trials <n>",
5514
5491
  "Number of trials to run, 1 to 10",
5515
5492
  "5"
5516
- ).option("--artifacts-dir <dir>", "Directory for run artifacts", "runs").action(
5517
- async (opts) => {
5493
+ ).action(
5494
+ async (opts, cmd) => {
5518
5495
  const trials = Number.parseInt(opts.trials, 10);
5519
5496
  if (!Number.isInteger(trials) || trials < 1 || trials > 10) {
5520
5497
  console.error(`Invalid --trials "${opts.trials}" (expected 1-10).`);
@@ -5523,10 +5500,10 @@ function createProgram() {
5523
5500
  }
5524
5501
  const { runDemo } = await import('../../runDemo-B2SXM4OC.js');
5525
5502
  const result = await runDemo({
5526
- apiBase: opts.apiUrl.replace(/\/$/, ""),
5503
+ apiBase: globals(cmd).apiUrl.replace(/\/$/, ""),
5527
5504
  dashboardBase: process.env.POME_DASHBOARD_URL ?? DEFAULT_DASHBOARD_URL,
5528
5505
  trials,
5529
- artifactsDir: opts.artifactsDir
5506
+ artifactsDir: globals(cmd).artifactsDir
5530
5507
  });
5531
5508
  process.exitCode = result.exitCode;
5532
5509
  }
@@ -5548,29 +5525,21 @@ function createProgram() {
5548
5525
  program.command("eval").summary("Score a trace recorded earlier").argument(
5549
5526
  "[run-dir]",
5550
5527
  "Existing run directory (runs/<task>/<run-id>). Omit to use <artifacts-dir>/latest.json."
5551
- ).option(
5552
- "--artifacts-dir <dir>",
5553
- "Directory whose latest.json picks the run when no run dir is given.",
5554
- "runs"
5555
5528
  ).option(
5556
5529
  "--agent <slug>",
5557
5530
  "Agent identity for the eval session. Defaults to agent.slug from pome.json."
5558
5531
  ).option(
5559
5532
  "--task <name>",
5560
5533
  "Task name recorded on the eval session. Defaults to meta.json's `scenario` slug (a legacy key name; then title)."
5561
- ).option(
5562
- "--api-url <url>",
5563
- "Control-plane base URL.",
5564
- process.env.POME_API_URL ?? DEFAULT_CONTROL_PLANE_URL
5565
5534
  ).description(
5566
5535
  "Upload an existing raw trace directory to Pome cloud for evaluation and print the authoritative score (capture/eval split \u2014 no local scoring; requires a control plane with POST /v1/eval-sessions)"
5567
5536
  ).action(
5568
- async (runDir, opts) => {
5569
- await runEvalCommand(runDir, opts);
5537
+ async (runDir, opts, cmd) => {
5538
+ await runEvalCommand(runDir, { ...opts, ...globals(cmd) });
5570
5539
  }
5571
5540
  );
5572
- program.command("inspect").argument("<run>", "Run id, run directory, or latest").option("--artifacts-dir <dir>", "Directory for run artifacts", "runs").description("Print a human-readable run report").action(async (run, options) => {
5573
- const latest = run === "latest" ? await readLatestRun(options.artifactsDir) : void 0;
5541
+ program.command("inspect").argument("<run>", "Run id, run directory, or latest").description("Print a human-readable run report").action(async (run, _options, cmd) => {
5542
+ const latest = run === "latest" ? await readLatestRun(globals(cmd).artifactsDir) : void 0;
5574
5543
  const runDir = latest?.run_dir ?? resolve(run);
5575
5544
  const eventsResult = await readEventsJsonl(runDir);
5576
5545
  const meta = await readMetaSummary(runDir);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pome-sh/cli",
3
- "version": "0.39.1",
3
+ "version": "0.40.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",