@pome-sh/cli 0.23.27 → 0.23.29

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.23.27",
4
- "git_sha": "87e466ebca9fffe55fab831bbb52efaf68dce110",
5
- "build_time": "2026-08-12T21:42:53.518Z"
3
+ "version": "0.23.29",
4
+ "git_sha": "f1aa1307727adb257885627f637b11c2d0e9da08",
5
+ "build_time": "2026-08-12T22:17:57.239Z"
6
6
  }
@@ -183,7 +183,7 @@ async function checkTwinReachable(_configDir) {
183
183
  });
184
184
  let harness;
185
185
  try {
186
- const { bootTwin } = await import('./twinHarness-H73PEFYS.js');
186
+ const { bootTwin } = await import('./twinHarness-PGM2DMPD.js');
187
187
  harness = await bootTwin({
188
188
  twin: "github",
189
189
  seedState: void 0,
@@ -1,6 +1,6 @@
1
1
  // ../packages/twin-github/package.json
2
2
  var package_default = {
3
- version: "0.10.8"};
3
+ version: "0.10.9"};
4
4
 
5
5
  // ../packages/twin-slack/package.json
6
6
  var package_default2 = {
@@ -39,7 +39,7 @@ var TWIN_REGISTRY = {
39
39
  defaultSeedState,
40
40
  GitHubDomain,
41
41
  openGitHubCloneDatabase
42
- } = await import('./src-VQOLQJJT.js');
42
+ } = await import('./src-P7IX3RY3.js');
43
43
  const db = openGitHubCloneDatabase();
44
44
  const domain = new GitHubDomain(db);
45
45
  domain.seed(seedState === void 0 ? defaultSeedState() : seedState);
@@ -59,9 +59,9 @@ var TWIN_REGISTRY = {
59
59
  envName: "SLACK",
60
60
  defaultPort: 3333,
61
61
  version: package_default2.version,
62
- defaultSeed: async () => (await import('./src-V7ODQ4NG.js')).defaultSeedState(),
62
+ defaultSeed: async () => (await import('./src-6RAKZPHK.js')).defaultSeedState(),
63
63
  async boot({ seedState, runId, recorder }) {
64
- const { createSlackTwinApp, openSlackTwinDatabase, SlackDomain } = await import('./src-V7ODQ4NG.js');
64
+ const { createSlackTwinApp, openSlackTwinDatabase, SlackDomain } = await import('./src-6RAKZPHK.js');
65
65
  const db = openSlackTwinDatabase(":memory:");
66
66
  const domain = new SlackDomain(db);
67
67
  domain.applySeed(seedState);
@@ -173,7 +173,7 @@ var TWIN_REGISTRY = {
173
173
  }
174
174
  };
175
175
  async function createGitHubSmokeApp() {
176
- const { createGitHubCloneApp } = await import('./src-VQOLQJJT.js');
176
+ const { createGitHubCloneApp } = await import('./src-P7IX3RY3.js');
177
177
  return createGitHubCloneApp();
178
178
  }
179
179
  function defaultPortFor(twin, env = process.env) {
@@ -1,7 +1,7 @@
1
1
  import { getAvailablePort } from './chunk-XDU6TD4O.js';
2
2
  import { buildEgressAllowlist, readBlockedEgress } from './chunk-CBFKZZBR.js';
3
- import { parseTaskFile, seedStateForTwin, runAgentCommand, writeRunArtifactsCore } from './chunk-XKBL7JKK.js';
4
- import { createRecorder, bootTwin } from './chunk-FGNIWUEU.js';
3
+ import { parseTaskFile, seedStateForTwin, runAgentCommand, writeRunArtifactsCore } from './chunk-VF3SUHN7.js';
4
+ import { createRecorder, bootTwin } from './chunk-LE43GGA6.js';
5
5
  import { eventSchema } from './chunk-VBATFCWR.js';
6
6
  import { redactSecrets, redactEvent } from './chunk-SG6ZTIMT.js';
7
7
  import { serve } from '@hono/node-server';
@@ -1,5 +1,5 @@
1
1
  import { readManifest, normalizeManifestTwins } from './chunk-ABM3CMQB.js';
2
- import { createHostedClient, perTwinReturnedByCloud, parseTaskFile, runAgentCommand, writeRunArtifactsCore, toTwinHttpEvent, redactJsonl, uploadRunBlobs, scoreFromFinalizeResponse, scoreStatus, evaluationCounts } from './chunk-XKBL7JKK.js';
2
+ import { createHostedClient, perTwinReturnedByCloud, parseTaskFile, runAgentCommand, writeRunArtifactsCore, toTwinHttpEvent, redactJsonl, uploadRunBlobs, scoreFromFinalizeResponse, scoreStatus, evaluationCounts } from './chunk-VF3SUHN7.js';
3
3
  import { MOUNTED_TWINS, HostedAuthError, HostedDiscardRefusedError, HostedQuotaError, HostedOrchError, HostedTrialError, agentResponseSchema } from './chunk-X66JOOO7.js';
4
4
  import { redactSecrets, redactEvent } from './chunk-SG6ZTIMT.js';
5
5
  import { existsSync } from 'node:fs';
@@ -1,4 +1,4 @@
1
- import { TWIN_NAMES, isTwinName, TWIN_REGISTRY } from './chunk-CC2N4JGQ.js';
1
+ import { TWIN_NAMES, isTwinName, TWIN_REGISTRY } from './chunk-AVVHHLTG.js';
2
2
  import { createFileBackedRecorderStore, createRecorderStore } from './chunk-OW7VVW6X.js';
3
3
 
4
4
  // src/recorder/recorder.ts
@@ -2,7 +2,7 @@ import { criterionSchema, finalizeResponseSchema, HostedDiscardRefusedError, Hos
2
2
  import { seedSchema, parseSeed, defaultSeedState as defaultSeedState$2 } from './chunk-KIUIKAVU.js';
3
3
  import { gmailSeedSchema, defaultSeedState } from './chunk-NJ246QPJ.js';
4
4
  import { linearSeedSchema, defaultSeedState as defaultSeedState$1 } from './chunk-ZKID2HS3.js';
5
- import { isTwinName, TWIN_REGISTRY } from './chunk-CC2N4JGQ.js';
5
+ import { isTwinName, TWIN_REGISTRY } from './chunk-AVVHHLTG.js';
6
6
  import { toTwinHttpEventRow } from './chunk-OW7VVW6X.js';
7
7
  import { redactEvent, redactSecrets } from './chunk-SG6ZTIMT.js';
8
8
  import { mkdir, appendFile, writeFile, readFile } from 'node:fs/promises';
@@ -1,16 +1,16 @@
1
1
  import { newGroupId, reassuranceBox, twinReadyLine, trialsHeaderLine, trialLine, summaryLines, evaluatingLine, criterionPhrase } from './chunk-RGZBC7NF.js';
2
2
  import { DemoCapacityError, capacityLabel, parseCapacityMarker, capacityKindFrom } from './chunk-ZX4WNSZ5.js';
3
- import { runTask, demoTaskPath, DEMO_TASK_NAME, DEMO_REPO } from './chunk-QIVE6VJE.js';
3
+ import { runTask, demoTaskPath, DEMO_TASK_NAME, DEMO_REPO } from './chunk-EF64GSHI.js';
4
4
  import { getAvailablePort } from './chunk-XDU6TD4O.js';
5
5
  import './chunk-CBFKZZBR.js';
6
- import { createHostedClient, parseTaskFile, uploadRunBlobs, scoreFromFinalizeResponse, scoreStatus, outcomeOf } from './chunk-XKBL7JKK.js';
6
+ import { createHostedClient, parseTaskFile, uploadRunBlobs, scoreFromFinalizeResponse, scoreStatus, outcomeOf } from './chunk-VF3SUHN7.js';
7
7
  import './chunk-NW7HGA2K.js';
8
8
  import { HostedQuotaError, HostedOrchError } from './chunk-X66JOOO7.js';
9
9
  import './chunk-KIUIKAVU.js';
10
10
  import './chunk-NJ246QPJ.js';
11
11
  import './chunk-ZKID2HS3.js';
12
- import { bootTwin } from './chunk-FGNIWUEU.js';
13
- import './chunk-CC2N4JGQ.js';
12
+ import { bootTwin } from './chunk-LE43GGA6.js';
13
+ import './chunk-AVVHHLTG.js';
14
14
  import './chunk-OW7VVW6X.js';
15
15
  import './chunk-VBATFCWR.js';
16
16
  import './chunk-SG6ZTIMT.js';
@@ -1,13 +1,13 @@
1
1
  import { newGroupId, criterionPhrase } from './chunk-RGZBC7NF.js';
2
- import { runTaskHosted, resolveRunAgentIdentity } from './chunk-4LODFVKV.js';
2
+ import { runTaskHosted, resolveRunAgentIdentity } from './chunk-FYCS4EBW.js';
3
3
  import './chunk-ABM3CMQB.js';
4
- import { createHostedClient, parseTaskFile, outcomeOf } from './chunk-XKBL7JKK.js';
4
+ import { createHostedClient, parseTaskFile, outcomeOf } from './chunk-VF3SUHN7.js';
5
5
  import './chunk-NW7HGA2K.js';
6
6
  import { HostedQuotaError, HostedTrialError } from './chunk-X66JOOO7.js';
7
7
  import './chunk-KIUIKAVU.js';
8
8
  import './chunk-NJ246QPJ.js';
9
9
  import './chunk-ZKID2HS3.js';
10
- import './chunk-CC2N4JGQ.js';
10
+ import './chunk-AVVHHLTG.js';
11
11
  import './chunk-OW7VVW6X.js';
12
12
  import './chunk-VBATFCWR.js';
13
13
  import './chunk-SG6ZTIMT.js';
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
- import { DEFAULT_CONTROL_PLANE_URL, DEFAULT_DASHBOARD_URL, clearLocalCredentials, friendlyHostedError, runSessionCreate, runSessionList, runSessionStop, resolveCredentials, runTaskHosted, discoverRunSet, VERDICT_ARTIFACT_VERSION, persistCredentialsAfterLogin, DEFAULT_DOCS_SITE_ORIGIN, resolveSeams, resolveCachedAgentId, readLinkCache, postAgentResolver, writeLinkCache, ensurePomeGitignored } from '../../chunk-4LODFVKV.js';
2
+ import { DEFAULT_CONTROL_PLANE_URL, DEFAULT_DASHBOARD_URL, clearLocalCredentials, friendlyHostedError, runSessionCreate, runSessionList, runSessionStop, resolveCredentials, runTaskHosted, discoverRunSet, VERDICT_ARTIFACT_VERSION, persistCredentialsAfterLogin, DEFAULT_DOCS_SITE_ORIGIN, resolveSeams, resolveCachedAgentId, readLinkCache, postAgentResolver, writeLinkCache, ensurePomeGitignored } from '../../chunk-FYCS4EBW.js';
3
3
  import { readManifest, writeManifest, MANIFEST_JSON, readRequiredManifest, normalizeManifestTwins } from '../../chunk-ABM3CMQB.js';
4
- import { assetPath, runTask, resolvePackageRoot, DEMO_TASK_NAME, demoTaskPath } from '../../chunk-QIVE6VJE.js';
4
+ import { assetPath, runTask, resolvePackageRoot, DEMO_TASK_NAME, demoTaskPath } from '../../chunk-EF64GSHI.js';
5
5
  import '../../chunk-XDU6TD4O.js';
6
6
  import '../../chunk-CBFKZZBR.js';
7
- import { parseTaskFile, scoreStatus, runScoreLine, readLatestRun, readMetaSummary, outcomeOf, readConfigTwins, scoreCountsSummary, markerFor, criterionMarkerLabel, twinSkipSuffix, readCodeCriteria, createHostedClient, toTwinHttpEvent, redactJsonl, scoreFromFinalizeResponse, parseGitHubSeedState, uploadRunBlobs, isPreSatisfied } from '../../chunk-XKBL7JKK.js';
7
+ import { parseTaskFile, scoreStatus, runScoreLine, readLatestRun, readMetaSummary, outcomeOf, readConfigTwins, scoreCountsSummary, markerFor, criterionMarkerLabel, twinSkipSuffix, readCodeCriteria, createHostedClient, toTwinHttpEvent, redactJsonl, scoreFromFinalizeResponse, parseGitHubSeedState, uploadRunBlobs, isPreSatisfied } from '../../chunk-VF3SUHN7.js';
8
8
  import '../../chunk-NW7HGA2K.js';
9
9
  import { MOUNTED_TWINS, deriveAgentSlug, exitCodeFor, HostedUsageError, HostedOrchError, HostedAuthError, HostedQuotaError } from '../../chunk-X66JOOO7.js';
10
10
  import { TAPE_ASSERTABLE_TOOLS } from '../../chunk-FKZZWWYC.js';
@@ -15,8 +15,8 @@ import '../../chunk-NJ246QPJ.js';
15
15
  import { LINEAR_CHECKS } from '../../chunk-XBT6ZLBG.js';
16
16
  import '../../chunk-ZKID2HS3.js';
17
17
  import { oneOf, defineCheck, repoRef, VACUITY_SENTINEL_NUMBER, childStatePath, VACUITY_SENTINEL, statePath, templateSlots, renderCheck, checksDigest, checkPattern, checkNearMissPattern } from '../../chunk-JWJYNAWI.js';
18
- import '../../chunk-FGNIWUEU.js';
19
- import { TWIN_NAME_LIST, isTwinName, createGitHubSmokeApp } from '../../chunk-CC2N4JGQ.js';
18
+ import '../../chunk-LE43GGA6.js';
19
+ import { TWIN_NAME_LIST, isTwinName, createGitHubSmokeApp } from '../../chunk-AVVHHLTG.js';
20
20
  import '../../chunk-OW7VVW6X.js';
21
21
  import { isLegacyEventRow, eventSchema } from '../../chunk-VBATFCWR.js';
22
22
  import { redactEvent, redactSecrets } from '../../chunk-SG6ZTIMT.js';
@@ -850,7 +850,7 @@ async function throwForStatus(res) {
850
850
 
851
851
  // src/task/seed-verifier.ts
852
852
  async function verifySeedWithTwin(seed) {
853
- const { GitHubDomain, openGitHubCloneDatabase } = await import('../../src-VQOLQJJT.js');
853
+ const { GitHubDomain, openGitHubCloneDatabase } = await import('../../src-P7IX3RY3.js');
854
854
  const db = openGitHubCloneDatabase(":memory:");
855
855
  try {
856
856
  new GitHubDomain(db).seed(seed);
@@ -4541,7 +4541,7 @@ var DEFAULT_AGENT_COMMAND = `node ${DEFAULT_AGENT_FILE}`;
4541
4541
  var MANIFEST_SCHEMA_URL = "https://pome.sh/schemas/v1/pome.json";
4542
4542
  var MAX_UNREADABLE_PATHS_SHOWN = 5;
4543
4543
  function readPackageVersion() {
4544
- if ("0.23.27".length > 0) return "0.23.27";
4544
+ if ("0.23.29".length > 0) return "0.23.29";
4545
4545
  try {
4546
4546
  const here = dirname(fileURLToPath(import.meta.url));
4547
4547
  const candidates = [
@@ -4996,7 +4996,7 @@ function createProgram() {
4996
4996
  return;
4997
4997
  }
4998
4998
  {
4999
- const { runDoctorChecks } = await import('../../checks-WHR4ALIJ.js');
4999
+ const { runDoctorChecks } = await import('../../checks-BA5CVCD3.js');
5000
5000
  const { renderDoctorReport } = await import('../../render-ZQQ4UMNO.js');
5001
5001
  const doctorReport = await runDoctorChecks({ mode: useLocal ? "full" : "hosted" });
5002
5002
  if (!doctorReport.ok) {
@@ -5034,7 +5034,7 @@ function createProgram() {
5034
5034
  taskForRuns.config.runs
5035
5035
  );
5036
5036
  if (k > 1) {
5037
- const { runTrialGroup } = await import('../../runTrialGroup-LBNWOZPA.js');
5037
+ const { runTrialGroup } = await import('../../runTrialGroup-BATEKFUD.js');
5038
5038
  const fileForRerun = relative(process.cwd(), file);
5039
5039
  const rerunCommand = defaultTask ? options.trials !== void 0 ? `pome run -n ${k}` : "pome run" : `pome run ${fileForRerun && !fileForRerun.startsWith("..") ? fileForRerun : file} -n ${k}`;
5040
5040
  const groupResult = await runTrialGroup({
@@ -5128,7 +5128,7 @@ function createProgram() {
5128
5128
  process.exitCode = 5;
5129
5129
  return;
5130
5130
  }
5131
- const { runDemo } = await import('../../runDemo-HFISTHIE.js');
5131
+ const { runDemo } = await import('../../runDemo-PGNPREIG.js');
5132
5132
  const result = await runDemo({
5133
5133
  apiBase: opts.apiUrl.replace(/\/$/, ""),
5134
5134
  dashboardBase: process.env.POME_DASHBOARD_URL ?? DEFAULT_DASHBOARD_URL,
@@ -5146,7 +5146,7 @@ function createProgram() {
5146
5146
  program.command("doctor").description(
5147
5147
  "Check the agent\u2194twin wiring: pome.json (or pome.yaml) present + valid, the local twin boots + serves, requests routed to the twin (not a hardcoded production host), egress floor active. On failure prints one named cause (file:line where knowable) + one concrete fix and exits non-zero."
5148
5148
  ).action(async () => {
5149
- const { runDoctorChecks } = await import('../../checks-WHR4ALIJ.js');
5149
+ const { runDoctorChecks } = await import('../../checks-BA5CVCD3.js');
5150
5150
  const { renderDoctorReport } = await import('../../render-ZQQ4UMNO.js');
5151
5151
  const report = await runDoctorChecks();
5152
5152
  for (const line of renderDoctorReport(report, { passNote: true })) console.error(line);
@@ -5322,7 +5322,7 @@ function createProgram() {
5322
5322
  ).description(
5323
5323
  "Start a standalone twin as a long-lived foreground server (Ctrl-C to stop)"
5324
5324
  ).action(async (name, options) => {
5325
- const { runTwinStartCommand } = await import('../../twinStart-HJX7TYZL.js');
5325
+ const { runTwinStartCommand } = await import('../../twinStart-SK7WAZZZ.js');
5326
5326
  await runTwinStartCommand(name, options);
5327
5327
  });
5328
5328
  twin.command("reset").argument("[name]", "Twin name (default: github)", "github").description("Reset standalone twin state").action(async (name) => {
@@ -1075,6 +1075,9 @@ function sanitizeJsonString(raw, fallback) {
1075
1075
  return fallback;
1076
1076
  }
1077
1077
  }
1078
+ function jsonStringOrArrayField(value, fallback) {
1079
+ return typeof value === "string" ? sanitizeJsonString(value, fallback) : JSON.stringify(value);
1080
+ }
1078
1081
  function normalizeReactionName(raw) {
1079
1082
  return raw.trim().replace(/^:|:$/g, "");
1080
1083
  }
@@ -1111,8 +1114,8 @@ function chatPostMessage(domain, args, actor, onDelta = NOOP3) {
1111
1114
  slackError("not_in_channel", 400);
1112
1115
  }
1113
1116
  const ts = domain.allocMessageTs(channel.id);
1114
- const blocks = args.blocks ? sanitizeJsonString(args.blocks, "[]") : "[]";
1115
- const attachments = args.attachments ? sanitizeJsonString(args.attachments, "[]") : "[]";
1117
+ const blocks = args.blocks ? jsonStringOrArrayField(args.blocks, "[]") : "[]";
1118
+ const attachments = args.attachments ? jsonStringOrArrayField(args.attachments, "[]") : "[]";
1116
1119
  const subtype = author.is_bot ? "bot_message" : null;
1117
1120
  const botId = author.is_bot ? author.id : null;
1118
1121
  const appId = author.is_bot ? "A_POME" : null;
@@ -1150,8 +1153,8 @@ function chatUpdate(domain, args, actor, onDelta = NOOP3) {
1150
1153
  const out = domain.db.transaction(() => {
1151
1154
  const updatedTs = domain.allocMessageTs(channel.id);
1152
1155
  const newText = args.text ?? before.text;
1153
- const newBlocks = args.blocks ? sanitizeJsonString(args.blocks, before.blocks_json) : before.blocks_json;
1154
- const newAttachments = args.attachments ? sanitizeJsonString(args.attachments, before.attachments_json) : before.attachments_json;
1156
+ const newBlocks = args.blocks ? jsonStringOrArrayField(args.blocks, before.blocks_json) : before.blocks_json;
1157
+ const newAttachments = args.attachments ? jsonStringOrArrayField(args.attachments, before.attachments_json) : before.attachments_json;
1155
1158
  domain.db.prepare(`UPDATE messages SET text = ?, blocks_json = ?, attachments_json = ?, edited_user_id = ?, edited_ts = ? WHERE channel_id = ? AND ts = ?`).run(newText, newBlocks, newAttachments, acting.id, updatedTs, channel.id, args.ts);
1156
1159
  const after = domain.requireMessageRow(channel.id, args.ts);
1157
1160
  onDelta({ before, after });
@@ -1197,7 +1200,7 @@ function chatScheduleMessage(domain, args, actor, onDelta = NOOP3) {
1197
1200
  const now = nowUnix();
1198
1201
  const out = domain.db.transaction(() => {
1199
1202
  domain.db.prepare(`INSERT INTO scheduled_messages (id, channel_id, user_id, text, thread_ts, post_at, date_created, blocks_json)
1200
- VALUES (?, ?, ?, ?, ?, ?, ?, ?)`).run(id, channel.id, acting.id, args.text, args.thread_ts ?? null, args.post_at, now, args.blocks ? sanitizeJsonString(args.blocks, "[]") : "[]");
1203
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)`).run(id, channel.id, acting.id, args.text, args.thread_ts ?? null, args.post_at, now, args.blocks ? jsonStringOrArrayField(args.blocks, "[]") : "[]");
1201
1204
  const row = domain.requireScheduledMessage(id);
1202
1205
  onDelta({ before: null, after: row });
1203
1206
  return {
@@ -2305,6 +2308,7 @@ var optionalInteger = () => integerInput().optional();
2305
2308
  var zeroIfAbsent = () => integerInput().default(0);
2306
2309
  var opaque = () => z.unknown().optional();
2307
2310
  var jsonStringOrObject = () => z.union([z.string(), z.record(z.string(), z.unknown())]).optional().transform((value) => value ? value : void 0);
2311
+ var jsonStringOrArray = () => z.union([z.string(), z.array(z.record(z.string(), z.unknown()))]).optional().transform((value) => value ? value : void 0);
2308
2312
  var SLACK_READS = {
2309
2313
  authTest: slackRead("/auth.test", {}),
2310
2314
  conversationsList: slackRead("/conversations.list", {
@@ -2420,8 +2424,8 @@ var SLACK_WRITES = {
2420
2424
  chatPostMessage: slackWrite("/chat.postMessage", {
2421
2425
  channel: emptyIfAbsent(),
2422
2426
  text: absentIfEmpty(),
2423
- blocks: absentIfEmpty(),
2424
- attachments: absentIfEmpty(),
2427
+ blocks: jsonStringOrArray(),
2428
+ attachments: jsonStringOrArray(),
2425
2429
  thread_ts: absentIfEmpty(),
2426
2430
  reply_broadcast: falseIfAbsent(),
2427
2431
  icon_emoji: absentIfEmpty(),
@@ -2433,8 +2437,8 @@ var SLACK_WRITES = {
2433
2437
  channel: emptyIfAbsent(),
2434
2438
  ts: emptyIfAbsent(),
2435
2439
  text: absentIfEmpty(),
2436
- blocks: absentIfEmpty(),
2437
- attachments: absentIfEmpty()
2440
+ blocks: jsonStringOrArray(),
2441
+ attachments: jsonStringOrArray()
2438
2442
  }),
2439
2443
  chatDelete: slackWrite("/chat.delete", {
2440
2444
  channel: emptyIfAbsent(),
@@ -2445,7 +2449,7 @@ var SLACK_WRITES = {
2445
2449
  text: emptyIfAbsent(),
2446
2450
  post_at: zeroIfAbsent(),
2447
2451
  thread_ts: absentIfEmpty(),
2448
- blocks: absentIfEmpty()
2452
+ blocks: jsonStringOrArray()
2449
2453
  }),
2450
2454
  chatDeleteScheduledMessage: slackWrite("/chat.deleteScheduledMessage", {
2451
2455
  channel: emptyIfAbsent(),
@@ -715,8 +715,13 @@ function githubError(message, status, errors, documentationUrl) {
715
715
  function notFound(message = "Not Found") {
716
716
  throw new TwinError(message, 404);
717
717
  }
718
- function conflict(message) {
719
- throw new TwinError(message, 409);
718
+ function conflict(message, documentationUrl) {
719
+ throw new TwinError(message, 409, void 0, documentationUrl);
720
+ }
721
+ function missingRequestField(field, documentationUrl) {
722
+ throw new TwinError(`Invalid request.
723
+
724
+ "${field}" wasn't supplied.`, 422, void 0, documentationUrl);
720
725
  }
721
726
  function validationFailed(field, code, value) {
722
727
  throw new TwinError("Validation Failed", 422, [
@@ -2551,6 +2556,11 @@ function listCommits(domain, input) {
2551
2556
  }
2552
2557
  return paginate(rows, input.page, input.per_page ?? input.perPage).map((commit) => commitJson(commit, repo));
2553
2558
  }
2559
+ var CONTENTS_PUT_DOC = "https://docs.github.com/rest/repos/contents#create-or-update-file-contents";
2560
+ var CONTENTS_DELETE_DOC = "https://docs.github.com/rest/repos/contents#delete-a-file";
2561
+ function shaConflict(path, sha, documentationUrl) {
2562
+ conflict(`${path} does not match ${sha}`, documentationUrl);
2563
+ }
2554
2564
  function createOrUpdateFile(domain, input, options = {}, onDelta) {
2555
2565
  const repo = domain.requireRepo(input.owner, input.repo);
2556
2566
  const branch = input.branch ?? repo.default_branch;
@@ -2561,10 +2571,12 @@ function createOrUpdateFile(domain, input, options = {}, onDelta) {
2561
2571
  const path = normalizePath(input.path);
2562
2572
  const existing = domain.getFile(repo.id, branch, path);
2563
2573
  before = existing ? fileState(existing, repo) : null;
2564
- if (existing && !input.sha)
2565
- validationFailed("sha", "missing", path);
2566
- if (existing && input.sha !== existing.sha)
2567
- validationFailed("sha", "invalid", input.sha);
2574
+ if (existing) {
2575
+ if (!input.sha)
2576
+ missingRequestField("sha", CONTENTS_PUT_DOC);
2577
+ if (input.sha !== existing.sha)
2578
+ shaConflict(path, input.sha, CONTENTS_PUT_DOC);
2579
+ }
2568
2580
  const commit = domain.commitFiles(repo, branch, input.message, [{ path, content: input.content }], options.actor ?? "pome-agent");
2569
2581
  const file = domain.getFile(repo.id, branch, path);
2570
2582
  afterFile = file;
@@ -2664,9 +2676,9 @@ function deleteFile(domain, input, options = {}, onDelta) {
2664
2676
  if (!existing)
2665
2677
  notFound("Not Found");
2666
2678
  if (!input.sha)
2667
- validationFailed("sha", "missing", path);
2679
+ missingRequestField("sha", CONTENTS_DELETE_DOC);
2668
2680
  if (input.sha !== existing.sha)
2669
- validationFailed("sha", "invalid", input.sha);
2681
+ shaConflict(path, input.sha, CONTENTS_DELETE_DOC);
2670
2682
  before = fileState(existing, repo);
2671
2683
  return domain.commitFiles(repo, branch, input.message, [{ path, content: "", delete: true }], options.actor ?? "pome-agent");
2672
2684
  });
@@ -0,0 +1,5 @@
1
+ export { UnsupportedTwinError, bootTwin } from './chunk-LE43GGA6.js';
2
+ export { STRIPE_LOCAL_ACCOUNT_ID } from './chunk-AVVHHLTG.js';
3
+ import './chunk-OW7VVW6X.js';
4
+ import './chunk-VBATFCWR.js';
5
+ import './chunk-SG6ZTIMT.js';
@@ -1,5 +1,5 @@
1
- import { bootTwin } from './chunk-FGNIWUEU.js';
2
- import { isTwinName, TWIN_NAMES, defaultPortFor, TWIN_REGISTRY } from './chunk-CC2N4JGQ.js';
1
+ import { bootTwin } from './chunk-LE43GGA6.js';
2
+ import { isTwinName, TWIN_NAMES, defaultPortFor, TWIN_REGISTRY } from './chunk-AVVHHLTG.js';
3
3
  import './chunk-OW7VVW6X.js';
4
4
  import './chunk-VBATFCWR.js';
5
5
  import './chunk-SG6ZTIMT.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pome-sh/cli",
3
- "version": "0.23.27",
3
+ "version": "0.23.29",
4
4
  "description": "Digital-twin testing for AI agents \u2014 run tasks against resettable local or hosted twins and record tool-call traces for evaluation on pome.sh.",
5
5
  "keywords": [
6
6
  "ai",
@@ -1,5 +0,0 @@
1
- export { UnsupportedTwinError, bootTwin } from './chunk-FGNIWUEU.js';
2
- export { STRIPE_LOCAL_ACCOUNT_ID } from './chunk-CC2N4JGQ.js';
3
- import './chunk-OW7VVW6X.js';
4
- import './chunk-VBATFCWR.js';
5
- import './chunk-SG6ZTIMT.js';