@pome-sh/cli 0.35.3 → 0.36.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/dist/build-info.json +3 -3
  2. package/dist/{checks-TC6O2HZE.js → checks-BKMTBJSO.js} +7 -3
  3. package/dist/chunk-2K6BJ3PI.js +140 -0
  4. package/dist/{chunk-Q5NBPR57.js → chunk-3FZY376K.js} +9 -1
  5. package/dist/{chunk-T73VMABH.js → chunk-5NPGY73F.js} +2 -2
  6. package/dist/{chunk-4EPOCS3X.js → chunk-77EGSHLT.js} +4 -4
  7. package/dist/{chunk-NAU4UZOE.js → chunk-AEFXTGW3.js} +2 -2
  8. package/dist/{chunk-D3NCOYBV.js → chunk-BS47AE55.js} +24 -50
  9. package/dist/{chunk-L7XARKMM.js → chunk-DFOQGAKS.js} +1 -1
  10. package/dist/{chunk-CF6EIU2U.js → chunk-FBSA5L36.js} +1 -1
  11. package/dist/{chunk-VOHTQV4J.js → chunk-HRAD7MRX.js} +1 -1
  12. package/dist/{chunk-HJX25USP.js → chunk-NBOQN5VX.js} +51 -18
  13. package/dist/{chunk-533VIN3J.js → chunk-NNXVR46L.js} +7 -150
  14. package/dist/{chunk-3T5XN64P.js → chunk-PASFBRK4.js} +9 -1
  15. package/dist/{chunk-CNG6DQWX.js → chunk-RPPF2KDQ.js} +22 -22
  16. package/dist/{chunk-DWOCTCSE.js → chunk-VPXIGCZW.js} +1 -1
  17. package/dist/{chunk-ZDS25NS5.js → chunk-YBWG5JK2.js} +17 -9
  18. package/dist/{runDemo-EBSKTX6V.js → runDemo-B2SXM4OC.js} +12 -10
  19. package/dist/{runTrialGroup-WZ3CUKYB.js → runTrialGroup-FZUMQLDH.js} +13 -11
  20. package/dist/{seed-F7RNI55S.js → seed-5HQC3FVZ.js} +1 -1
  21. package/dist/{seed-BG5HMSBM.js → seed-BHJKPKUC.js} +1 -1
  22. package/dist/seed-E6SA4NKZ.js +2 -0
  23. package/dist/{seed-IIMBJHAJ.js → seed-SYJXLGWF.js} +1 -1
  24. package/dist/{seed-NR6RUKXV.js → seed-W3R53GHH.js} +1 -1
  25. package/dist/{server-FBKFPGR4.js → server-GDK4TBTL.js} +2 -2
  26. package/dist/src/cli/main.js +24 -22
  27. package/dist/{src-5SOF4PDV.js → src-FUPOFZI4.js} +4 -4
  28. package/dist/{src-ANO374BX.js → src-SNSK5ENY.js} +4 -4
  29. package/dist/{src-DO3BEABU.js → src-UY4Y75BD.js} +48 -5
  30. package/dist/{src-AMLUIPYO.js → src-V3RUKDMQ.js} +396 -6
  31. package/dist/{src-YGMRIKFV.js → src-Z4C4SSDR.js} +4 -4
  32. package/dist/twinHarness-ATYQTDA5.js +6 -0
  33. package/dist/{twinSeed-2MRVMNIT.js → twinSeed-7M4GOIBS.js} +1 -1
  34. package/dist/{twinStart-2ZNLS3ON.js → twinStart-2LICNC4D.js} +5 -5
  35. package/package.json +1 -1
  36. package/tasks/19-stripe-rerefund-persuasion.md +5 -3
  37. package/tasks/19-stripe-rerefund-persuasion.seed.json +0 -1
  38. package/dist/chunk-SLTBPJKZ.js +0 -522
  39. package/dist/seed-YWDTT2WL.js +0 -2
  40. package/dist/twinHarness-2OFWSVPK.js +0 -6
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "package": "pome-sh",
3
- "version": "0.35.3",
4
- "git_sha": "76f126bc15b2467859785d59555570627963259e",
5
- "build_time": "2026-08-29T21:46:38.757Z"
3
+ "version": "0.36.0",
4
+ "git_sha": "81d35ce632f8cd4a8009cad184514b5e688d3c17",
5
+ "build_time": "2026-08-29T23:53:46.865Z"
6
6
  }
@@ -1,9 +1,13 @@
1
- import { findManifestPath, readManifest } from './chunk-L7XARKMM.js';
1
+ import { findManifestPath, readManifest } from './chunk-DFOQGAKS.js';
2
2
  import { getAvailablePort } from './chunk-XDU6TD4O.js';
3
- import './chunk-533VIN3J.js';
3
+ import './chunk-NNXVR46L.js';
4
4
  import { buildEgressAllowlist } from './chunk-CBFKZZBR.js';
5
+ import './chunk-NBOQN5VX.js';
6
+ import './chunk-YBWG5JK2.js';
5
7
  import './chunk-6KJC4BTO.js';
6
8
  import './chunk-SG6ZTIMT.js';
9
+ import './chunk-2K6BJ3PI.js';
10
+ import './chunk-FBSA5L36.js';
7
11
  import { serve } from '@hono/node-server';
8
12
  import { randomUUID, randomBytes } from 'node:crypto';
9
13
  import { basename, dirname, relative, join } from 'node:path';
@@ -183,7 +187,7 @@ async function checkTwinReachable(_configDir) {
183
187
  });
184
188
  let harness;
185
189
  try {
186
- const { bootTwin } = await import('./twinHarness-2OFWSVPK.js');
190
+ const { bootTwin } = await import('./twinHarness-ATYQTDA5.js');
187
191
  harness = await bootTwin({
188
192
  twin: "github",
189
193
  seedState: void 0,
@@ -0,0 +1,140 @@
1
+ import { failureInjectionRuleSchema } from './chunk-FBSA5L36.js';
2
+ import { z } from 'zod';
3
+
4
+ var DEFAULT_SID = "default";
5
+ var DEFAULT_API_KEY = "sk_test_pome_default";
6
+ var PI_STATUSES = [
7
+ "requires_payment_method",
8
+ "requires_confirmation",
9
+ "requires_action",
10
+ "processing",
11
+ "requires_capture",
12
+ "canceled",
13
+ "succeeded"
14
+ ];
15
+ var CHARGE_STATUSES = ["pending", "succeeded", "failed"];
16
+ var REFUND_STATUSES = ["succeeded", "pending", "failed", "canceled"];
17
+ var BALANCE_TX_STATUSES = ["pending", "available"];
18
+ var paymentIntentSeedSchema = z.strictObject({
19
+ id: z.string().min(1),
20
+ account_id: z.string().min(1),
21
+ amount: z.number().int(),
22
+ currency: z.string().min(1),
23
+ status: z.enum(PI_STATUSES),
24
+ payment_method_types: z.array(z.string()).default(["crypto"]),
25
+ next_action: z.unknown().nullable().optional(),
26
+ latest_charge_id: z.string().nullable().optional(),
27
+ capture_method: z.string().default("automatic"),
28
+ confirmation_method: z.string().default("automatic"),
29
+ idempotency_key: z.string().nullable().optional(),
30
+ metadata: z.record(z.string(), z.string()).default({}),
31
+ crypto_deposit: z.unknown().nullable().optional(),
32
+ client_secret: z.string().min(1),
33
+ created: z.number().int(),
34
+ updated: z.number().int(),
35
+ canceled_at: z.number().int().nullable().optional(),
36
+ captured_at: z.number().int().nullable().optional()
37
+ });
38
+ var chargeSeedSchema = z.strictObject({
39
+ id: z.string().min(1),
40
+ account_id: z.string().min(1),
41
+ payment_intent_id: z.string().min(1),
42
+ amount: z.number().int(),
43
+ amount_captured: z.number().int().default(0),
44
+ amount_refunded: z.number().int().default(0),
45
+ status: z.enum(CHARGE_STATUSES),
46
+ balance_transaction_id: z.string().nullable().optional(),
47
+ captured: z.boolean().default(true),
48
+ currency: z.string().min(1),
49
+ created: z.number().int()
50
+ });
51
+ var refundSeedSchema = z.strictObject({
52
+ id: z.string().min(1),
53
+ account_id: z.string().min(1),
54
+ charge_id: z.string().min(1),
55
+ payment_intent_id: z.string().min(1),
56
+ amount: z.number().int(),
57
+ currency: z.string().min(1),
58
+ status: z.enum(REFUND_STATUSES),
59
+ reason: z.string().nullable().optional(),
60
+ balance_transaction_id: z.string().nullable().optional(),
61
+ idempotency_key: z.string().nullable().optional(),
62
+ created: z.number().int()
63
+ });
64
+ var balanceTransactionSeedSchema = z.strictObject({
65
+ id: z.string().min(1),
66
+ account_id: z.string().min(1),
67
+ type: z.string().min(1),
68
+ amount: z.number().int(),
69
+ fee: z.number().int().default(0),
70
+ net: z.number().int(),
71
+ currency: z.string().min(1),
72
+ source_id: z.string().nullable().optional(),
73
+ source_type: z.string().nullable().optional(),
74
+ available_on: z.number().int(),
75
+ status: z.enum(BALANCE_TX_STATUSES).default("available"),
76
+ created: z.number().int()
77
+ });
78
+ var seedSchema = z.strictObject({
79
+ api_keys: z.array(z.strictObject({
80
+ key: z.string().min(1),
81
+ sid: z.string().min(1),
82
+ account_id: z.string().min(1).optional()
83
+ })).default([]),
84
+ failure_injection: z.array(failureInjectionRuleSchema).default([]),
85
+ payment_intents: z.array(paymentIntentSeedSchema).default([]),
86
+ charges: z.array(chargeSeedSchema).default([]),
87
+ refunds: z.array(refundSeedSchema).default([]),
88
+ balance_transactions: z.array(balanceTransactionSeedSchema).default([])
89
+ });
90
+ function withoutSidecarMeta(input) {
91
+ if (!input || typeof input !== "object" || Array.isArray(input))
92
+ return input;
93
+ if (!("_meta" in input))
94
+ return input;
95
+ const { _meta, ...rest } = input;
96
+ return rest;
97
+ }
98
+ function parseSeed(input) {
99
+ return seedSchema.parse(withoutSidecarMeta(input));
100
+ }
101
+ function loadSeedFromEnv(env = process.env) {
102
+ const raw = env.POME_SEED_JSON;
103
+ if (raw === void 0 || raw === "") {
104
+ return defaultSeed();
105
+ }
106
+ let parsed;
107
+ try {
108
+ parsed = JSON.parse(raw);
109
+ } catch (err) {
110
+ throw new Error(`POME_SEED_JSON is not valid JSON: ${err.message}`);
111
+ }
112
+ const unwrapped = unwrapStripeSeed(parsed);
113
+ return parseSeed(unwrapped);
114
+ }
115
+ function unwrapStripeSeed(value) {
116
+ if (value && typeof value === "object" && !Array.isArray(value)) {
117
+ const stripeKey = value.stripe;
118
+ if (stripeKey && typeof stripeKey === "object" && !Array.isArray(stripeKey)) {
119
+ const inner = stripeKey.seed;
120
+ if (inner !== void 0) {
121
+ return inner;
122
+ }
123
+ }
124
+ }
125
+ return value;
126
+ }
127
+ function defaultSeed() {
128
+ return {
129
+ api_keys: [
130
+ { key: DEFAULT_API_KEY, sid: DEFAULT_SID, account_id: `acct_${DEFAULT_SID}` }
131
+ ],
132
+ failure_injection: [],
133
+ payment_intents: [],
134
+ charges: [],
135
+ refunds: [],
136
+ balance_transactions: []
137
+ };
138
+ }
139
+
140
+ export { DEFAULT_API_KEY, DEFAULT_SID, defaultSeed, loadSeedFromEnv, parseSeed, seedSchema };
@@ -422,8 +422,16 @@ var linearSeedSchema = z.object({
422
422
  }
423
423
  }
424
424
  });
425
+ function withoutSidecarMeta(input) {
426
+ if (!input || typeof input !== "object" || Array.isArray(input))
427
+ return input;
428
+ if (!("_meta" in input))
429
+ return input;
430
+ const { _meta, ...rest } = input;
431
+ return rest;
432
+ }
425
433
  function parseSeed(input) {
426
- return linearSeedSchema.parse(input);
434
+ return linearSeedSchema.parse(withoutSidecarMeta(input));
427
435
  }
428
436
  function loadSeedFromEnv(env = process.env) {
429
437
  const raw = env.POME_SEED_JSON;
@@ -1,5 +1,5 @@
1
- import { TWIN_NAMES, isTwinName, TWIN_REGISTRY } from './chunk-CNG6DQWX.js';
2
- import { createFileBackedRecorderStore, createRecorderStore } from './chunk-VOHTQV4J.js';
1
+ import { TWIN_NAMES, isTwinName, TWIN_REGISTRY } from './chunk-RPPF2KDQ.js';
2
+ import { createFileBackedRecorderStore, createRecorderStore } from './chunk-HRAD7MRX.js';
3
3
 
4
4
  // src/recorder/recorder.ts
5
5
  function createRecorder(options = {}) {
@@ -1,7 +1,7 @@
1
- import { createHostedClient, perTwinReturnedByCloud, parseTaskFile, runAgentCommand, writeRunArtifactsCore, toTwinHttpEvent, redactJsonl, uploadRunBlobs, scoreFromFinalizeResponse, scoreStatus, evaluationCounts } from './chunk-D3NCOYBV.js';
2
- import { readSeedFileText, parseSeedFileText, soleTwinOf, seedsForTwins } from './chunk-DWOCTCSE.js';
3
- import { readManifest, normalizeManifestTwins } from './chunk-L7XARKMM.js';
4
- import { MOUNTED_TWINS, HostedAuthError, HostedDiscardRefusedError, HostedQuotaError, HostedOrchError, HostedTrialError, agentResponseSchema, isMultiTwinSeedEnvelope } from './chunk-533VIN3J.js';
1
+ import { createHostedClient, perTwinReturnedByCloud, parseTaskFile, runAgentCommand, writeRunArtifactsCore, toTwinHttpEvent, redactJsonl, uploadRunBlobs, scoreFromFinalizeResponse, scoreStatus, evaluationCounts } from './chunk-BS47AE55.js';
2
+ import { readSeedFileText, parseSeedFileText, soleTwinOf, seedsForTwins } from './chunk-VPXIGCZW.js';
3
+ import { readManifest, normalizeManifestTwins } from './chunk-DFOQGAKS.js';
4
+ import { MOUNTED_TWINS, HostedAuthError, HostedDiscardRefusedError, HostedQuotaError, HostedOrchError, HostedTrialError, agentResponseSchema, isMultiTwinSeedEnvelope } from './chunk-NNXVR46L.js';
5
5
  import { redactSecrets, redactEvent } from './chunk-SG6ZTIMT.js';
6
6
  import { randomUUID, createHash } from 'node:crypto';
7
7
  import { rm, readFile, stat, mkdir, writeFile, chmod, mkdtemp, readdir, rename } from 'node:fs/promises';
@@ -1,5 +1,5 @@
1
- import { parseTaskFile, seedStateForTwin, runAgentCommand, writeRunArtifactsCore } from './chunk-D3NCOYBV.js';
2
- import { createRecorder, bootTwin } from './chunk-T73VMABH.js';
1
+ import { parseTaskFile, seedStateForTwin, runAgentCommand, writeRunArtifactsCore } from './chunk-BS47AE55.js';
2
+ import { createRecorder, bootTwin } from './chunk-5NPGY73F.js';
3
3
  import { getAvailablePort } from './chunk-XDU6TD4O.js';
4
4
  import { buildEgressAllowlist, readBlockedEgress } from './chunk-CBFKZZBR.js';
5
5
  import { eventSchema } from './chunk-6KJC4BTO.js';
@@ -1,10 +1,12 @@
1
- import { gmailSeedSchema, defaultSeedState } from './chunk-3T5XN64P.js';
2
- import { linearSeedSchema, defaultSeedState as defaultSeedState$1 } from './chunk-Q5NBPR57.js';
3
- import { isTwinName, TWIN_REGISTRY } from './chunk-CNG6DQWX.js';
4
- import { criterionSchema, normalizeTaskConfigKeys, finalizeResponseSchema, HostedDiscardRefusedError, HostedOrchError, HostedAuthError, HostedQuotaError, submitResultResponseSchema, createEvalSessionResponseSchema, createSessionResponseSchema, sessionPublicSchema } from './chunk-533VIN3J.js';
5
- import { seedSchema, parseSeed, defaultSeedState as defaultSeedState$2 } from './chunk-HJX25USP.js';
6
- import { toTwinHttpEventRow } from './chunk-VOHTQV4J.js';
1
+ import { gmailSeedSchema, defaultSeedState } from './chunk-PASFBRK4.js';
2
+ import { linearSeedSchema, defaultSeedState as defaultSeedState$1 } from './chunk-3FZY376K.js';
3
+ import { isTwinName, TWIN_REGISTRY } from './chunk-RPPF2KDQ.js';
4
+ import { criterionSchema, normalizeTaskConfigKeys, finalizeResponseSchema, HostedDiscardRefusedError, HostedOrchError, HostedAuthError, HostedQuotaError, submitResultResponseSchema, createEvalSessionResponseSchema, createSessionResponseSchema, sessionPublicSchema } from './chunk-NNXVR46L.js';
5
+ import { seedSchema as seedSchema$1, parseSeed, defaultSeedState as defaultSeedState$2 } from './chunk-NBOQN5VX.js';
6
+ import { seedSchema } from './chunk-YBWG5JK2.js';
7
+ import { toTwinHttpEventRow } from './chunk-HRAD7MRX.js';
7
8
  import { redactEvent, redactSecrets } from './chunk-SG6ZTIMT.js';
9
+ import { seedSchema as seedSchema$2 } from './chunk-2K6BJ3PI.js';
8
10
  import { mkdir, appendFile, writeFile, readFile } from 'node:fs/promises';
9
11
  import { existsSync } from 'node:fs';
10
12
  import { join, basename, extname } from 'node:path';
@@ -145,7 +147,7 @@ function normalizeLegacyIssueAssignee(issue) {
145
147
  return issue;
146
148
  }
147
149
  function parseGitHubSeedState(input) {
148
- const seed = seedSchema.parse(parseSeed(normalizeLegacyGitHubSeed(input)));
150
+ const seed = seedSchema$1.parse(parseSeed(normalizeLegacyGitHubSeed(input)));
149
151
  if (seed.repositories.length === 0) {
150
152
  throw new Error("GitHub seed must contain at least one repository");
151
153
  }
@@ -165,41 +167,12 @@ var taskConfigSchema = z.preprocess(
165
167
  passThreshold: z.number().min(0).max(100).default(100)
166
168
  })
167
169
  );
168
- var stripeFailureInjectionRuleSchema = z.object({
169
- method: z.string().min(1),
170
- path: z.string().min(1),
171
- attempt: z.number().int().positive(),
172
- mode: z.enum(["before_handler", "after_handler"]).default("after_handler"),
173
- status: z.number().int().min(100).max(599),
174
- body: z.unknown()
175
- });
176
- var stripeSeedStateSchema = z.object({
177
- api_keys: z.array(
178
- z.object({
179
- key: z.string().min(1).default("sk_test_pome_default"),
180
- sid: z.string().min(1).default("default"),
181
- account_id: z.string().min(1).optional()
182
- })
183
- ).default([]),
184
- failure_injection: z.array(stripeFailureInjectionRuleSchema).default([]),
185
- payment_intents: z.array(z.record(z.string(), z.unknown())).default([]),
186
- charges: z.array(z.record(z.string(), z.unknown())).default([]),
187
- refunds: z.array(z.record(z.string(), z.unknown())).default([]),
188
- balance_transactions: z.array(z.record(z.string(), z.unknown())).default([])
189
- }).strict();
190
- var slackSeedStateSchema = z.object({
191
- team: z.record(z.string(), z.unknown()).optional(),
192
- users: z.array(z.record(z.string(), z.unknown())).default([]),
193
- channels: z.array(z.record(z.string(), z.unknown())).default([]),
194
- files: z.array(z.record(z.string(), z.unknown())).default([]),
195
- emoji: z.array(z.record(z.string(), z.unknown())).default([])
196
- }).strict();
197
170
  var seedStateSchema = z.union([
198
171
  gmailSeedSchema,
199
- slackSeedStateSchema,
200
- linearSeedSchema,
201
172
  seedSchema,
202
- stripeSeedStateSchema
173
+ linearSeedSchema,
174
+ seedSchema$1,
175
+ seedSchema$2
203
176
  ]);
204
177
  var seedEnvelopeSchema = z.record(z.string(), seedStateSchema);
205
178
  var taskSchema = z.object({
@@ -346,21 +319,22 @@ function buildSeedEnvelope(raw, twins) {
346
319
  }
347
320
  return envelope;
348
321
  }
349
- function parseSeedForTwin(twin, input) {
350
- if (twin === "stripe") return stripeSeedStateSchema.parse(input);
351
- if (twin === "slack") return slackSeedStateSchema.parse(input);
322
+ function parseSeedForTwin(twin, raw) {
323
+ const input = stripSidecarMeta(raw);
324
+ if (twin === "stripe") return seedSchema$2.parse(input);
325
+ if (twin === "slack") return seedSchema.parse(input);
352
326
  if (twin === "gmail") return gmailSeedSchema.parse(input);
353
327
  if (twin === "linear") return linearSeedSchema.parse(input);
354
328
  return parseGitHubSeedState(input);
355
329
  }
356
330
  function defaultSeedForTwin(twin) {
357
331
  if (twin === "stripe") {
358
- return stripeSeedStateSchema.parse({
332
+ return seedSchema$2.parse({
359
333
  api_keys: [{ key: "sk_test_pome_default", sid: "default", account_id: "acct_default" }]
360
334
  });
361
335
  }
362
336
  if (twin === "slack") {
363
- return slackSeedStateSchema.parse({});
337
+ return seedSchema.parse({});
364
338
  }
365
339
  if (twin === "gmail") {
366
340
  return gmailSeedSchema.parse(defaultSeedState());
@@ -368,7 +342,7 @@ function defaultSeedForTwin(twin) {
368
342
  if (twin === "linear") {
369
343
  return linearSeedSchema.parse(defaultSeedState$1());
370
344
  }
371
- return seedSchema.parse(defaultSeedState$2());
345
+ return seedSchema$1.parse(defaultSeedState$2());
372
346
  }
373
347
  function missingSidecarMessage(taskPath) {
374
348
  const pathLabel = taskPath ?? "<task>.md";
@@ -481,20 +455,20 @@ function parseFencedYaml(input) {
481
455
  return parse(stripFence(input));
482
456
  }
483
457
  function parseSeedStateForTask(input, config) {
484
- if (isStripeOnly(config.twins)) return stripeSeedStateSchema.parse(input);
485
- if (isSlackOnly(config.twins)) return slackSeedStateSchema.parse(input);
458
+ if (isStripeOnly(config.twins)) return seedSchema$2.parse(input);
459
+ if (isSlackOnly(config.twins)) return seedSchema.parse(input);
486
460
  if (isGmailOnly(config.twins)) return gmailSeedSchema.parse(input);
487
461
  if (isLinearOnly(config.twins)) return linearSeedSchema.parse(input);
488
462
  return parseGitHubSeedState(input);
489
463
  }
490
464
  function defaultSeedStateForConfig(twins) {
491
465
  if (isStripeOnly(twins)) {
492
- return stripeSeedStateSchema.parse({
466
+ return seedSchema$2.parse({
493
467
  api_keys: [{ key: "sk_test_pome_default", sid: "default", account_id: "acct_default" }]
494
468
  });
495
469
  }
496
470
  if (isSlackOnly(twins)) {
497
- return slackSeedStateSchema.parse({});
471
+ return seedSchema.parse({});
498
472
  }
499
473
  if (isGmailOnly(twins)) {
500
474
  return gmailSeedSchema.parse(defaultSeedState());
@@ -502,7 +476,7 @@ function defaultSeedStateForConfig(twins) {
502
476
  if (isLinearOnly(twins)) {
503
477
  return linearSeedSchema.parse(defaultSeedState$1());
504
478
  }
505
- return seedSchema.parse(defaultSeedState$2());
479
+ return seedSchema$1.parse(defaultSeedState$2());
506
480
  }
507
481
  function isStripeOnly(twins) {
508
482
  return twins.length === 1 && twins[0] === "stripe";
@@ -1,4 +1,4 @@
1
- import { HostedOrchError, manifestSchema, deriveAgentSlug, SLUG_RE } from './chunk-533VIN3J.js';
1
+ import { HostedOrchError, manifestSchema, deriveAgentSlug, SLUG_RE } from './chunk-NNXVR46L.js';
2
2
  import { readFile, writeFile } from 'node:fs/promises';
3
3
  import { resolve, join, dirname } from 'node:path';
4
4
  import { stringify, parse } from 'yaml';
@@ -2,7 +2,7 @@ import { z } from 'zod';
2
2
 
3
3
  // ../packages/sdk/dist/failure-injection-rules.js
4
4
  var FAILURE_INJECTION_OVERRIDE_KEY = "failureInjectionOverride";
5
- var failureInjectionRuleSchema = z.object({
5
+ var failureInjectionRuleSchema = z.strictObject({
6
6
  method: z.string().min(1).transform((s) => s.toUpperCase()),
7
7
  path: z.string().min(1),
8
8
  attempt: z.number().int().positive(),
@@ -1,5 +1,5 @@
1
1
  import { redactSecrets, redactEvent } from './chunk-SG6ZTIMT.js';
2
- import { FAILURE_INJECTION_OVERRIDE_KEY } from './chunk-CF6EIU2U.js';
2
+ import { FAILURE_INJECTION_OVERRIDE_KEY } from './chunk-FBSA5L36.js';
3
3
  import { Hono } from 'hono';
4
4
  import { z } from 'zod';
5
5
  import { mkdirSync, openSync, createWriteStream, closeSync, writeFileSync, rmSync, readFileSync, fsync } from 'node:fs';
@@ -1,20 +1,20 @@
1
1
  import { z } from 'zod';
2
2
 
3
3
  // ../packages/twin-github/dist/src/seed.js
4
- var seedSchema = z.object({
5
- users: z.array(z.object({
4
+ var seedSchema = z.strictObject({
5
+ users: z.array(z.strictObject({
6
6
  login: z.string().min(1),
7
7
  type: z.enum(["User", "Organization"]).default("User"),
8
8
  name: z.string().default("")
9
9
  })).default([]),
10
- repositories: z.array(z.object({
10
+ repositories: z.array(z.strictObject({
11
11
  owner: z.string().min(1),
12
12
  name: z.string().min(1),
13
13
  description: z.string().default(""),
14
14
  private: z.boolean().default(false),
15
15
  default_branch: z.string().min(1).default("main"),
16
16
  collaborators: z.array(z.string().min(1)).default([]),
17
- labels: z.array(z.object({
17
+ labels: z.array(z.strictObject({
18
18
  name: z.string().min(1),
19
19
  color: z.string().default("ededed"),
20
20
  description: z.string().default("")
@@ -34,7 +34,7 @@ var seedSchema = z.object({
34
34
  // remove. Refusing it keeps "the seed asked for a rename" and "the twin
35
35
  // serves a rename" the same statement. The content comes from the source
36
36
  // path, which the domain resolves on the branch the move happens on.
37
- files: z.array(z.object({
37
+ files: z.array(z.strictObject({
38
38
  path: z.string().min(1),
39
39
  content: z.string().optional(),
40
40
  branch: z.string().optional(),
@@ -68,11 +68,13 @@ var seedSchema = z.object({
68
68
  // Milestones, tags and releases are repository-level entities the
69
69
  // twin already SERVES (`GET /milestones`, `/tags`, `/releases`,
70
70
  // `/releases/latest`, `/releases/tags/:tag`) and the seed could not
71
- // express. Zod strips unknown keys, so a seed naming one reached the
71
+ // express. Zod stripped unknown keys, so a seed naming one reached the
72
72
  // domain as nothing at all and those routes could only ever answer `[]`
73
73
  // — a shape of infidelity no shape-diff can see, because an empty array
74
- // on both sides compares zero elements.
75
- milestones: z.array(z.object({
74
+ // on both sides compares zero elements. That silence is what `strictObject`
75
+ // closes for the general case (F-1689); this entry is the instance that
76
+ // was found first.
77
+ milestones: z.array(z.strictObject({
76
78
  // Assigned sequentially from 1 in seed order when omitted, the way
77
79
  // `nextMilestoneNumber` hands them out. Honored when given, so a
78
80
  // seed that pins `PATCH /milestones/2` addresses the milestone it
@@ -89,11 +91,11 @@ var seedSchema = z.object({
89
91
  // name or a SHA — and defaults to the repository's default-branch head. A
90
92
  // release whose `tag_name` matches an entry here reuses that tag rather
91
93
  // than minting a second one: `createRelease` looks the tag up first.
92
- tags: z.array(z.object({
94
+ tags: z.array(z.strictObject({
93
95
  name: z.string().min(1),
94
96
  target: z.string().min(1).optional()
95
97
  })).default([]),
96
- releases: z.array(z.object({
98
+ releases: z.array(z.strictObject({
97
99
  tag_name: z.string().min(1),
98
100
  // Nullable upstream, so an absent `name` means `null` — not `""`.
99
101
  name: z.string().optional(),
@@ -103,7 +105,7 @@ var seedSchema = z.object({
103
105
  prerelease: z.boolean().default(false),
104
106
  author: z.string().min(1).optional()
105
107
  })).default([]),
106
- issues: z.array(z.object({
108
+ issues: z.array(z.strictObject({
107
109
  number: z.number().int().positive().optional(),
108
110
  title: z.string().min(1),
109
111
  body: z.string().default(""),
@@ -116,12 +118,12 @@ var seedSchema = z.object({
116
118
  // stamps every comment `pome-agent`: a world in which the agent
117
119
  // under test wrote every comment on the issue it is being asked to
118
120
  // read is not one worth testing against.
119
- comments: z.array(z.object({
121
+ comments: z.array(z.strictObject({
120
122
  body: z.string().min(1),
121
123
  author: z.string().min(1).optional()
122
124
  })).default([])
123
125
  })).default([]),
124
- pull_requests: z.array(z.object({
126
+ pull_requests: z.array(z.strictObject({
125
127
  number: z.number().int().positive().optional(),
126
128
  title: z.string().min(1),
127
129
  body: z.string().default(""),
@@ -131,7 +133,7 @@ var seedSchema = z.object({
131
133
  author: z.string().min(1).optional(),
132
134
  // Reviews seeded on this PR. `state` mirrors GitHub's review
133
135
  // state enum; `author` must exist in the user/collaborator set.
134
- reviews: z.array(z.object({
136
+ reviews: z.array(z.strictObject({
135
137
  author: z.string().min(1),
136
138
  state: z.enum(["APPROVED", "CHANGES_REQUESTED", "COMMENTED"]).default("APPROVED"),
137
139
  body: z.string().default("")
@@ -139,7 +141,7 @@ var seedSchema = z.object({
139
141
  // Commit statuses applied to this PR's head SHA. Wired into the
140
142
  // commit_statuses table so get_pull_request_status and the merge
141
143
  // path see them without needing a separate setup call.
142
- statuses: z.array(z.object({
144
+ statuses: z.array(z.strictObject({
143
145
  context: z.string().min(1).default("ci/build"),
144
146
  state: z.enum(["error", "failure", "pending", "success"]).default("success"),
145
147
  description: z.string().default("")
@@ -151,7 +153,7 @@ var seedSchema = z.object({
151
153
  // keeps all three apart: `reviews[].body` is the prose on a review
152
154
  // verdict, `review_comments[]` below is anchored to a file and
153
155
  // line, and THIS one is the timeline.
154
- comments: z.array(z.object({
156
+ comments: z.array(z.strictObject({
155
157
  body: z.string().min(1),
156
158
  author: z.string().min(1).optional()
157
159
  })).default([]),
@@ -161,7 +163,7 @@ var seedSchema = z.object({
161
163
  // `line` must exist in it: a seeded review comment is one
162
164
  // `POST /pulls/:n/comments` could have produced, not a row only the
163
165
  // seeder can make.
164
- review_comments: z.array(z.object({
166
+ review_comments: z.array(z.strictObject({
165
167
  body: z.string().min(1),
166
168
  path: z.string().min(1),
167
169
  line: z.number().int().positive().default(1),
@@ -169,10 +171,41 @@ var seedSchema = z.object({
169
171
  author: z.string().min(1).optional()
170
172
  })).default([])
171
173
  })).default([])
174
+ }).superRefine((repo, ctx) => {
175
+ const claimed = /* @__PURE__ */ new Map();
176
+ const entries = [
177
+ ["issues", repo.issues ?? []],
178
+ ["pull_requests", repo.pull_requests ?? []]
179
+ ];
180
+ for (const [field, rows] of entries) {
181
+ for (const [index, row] of rows.entries()) {
182
+ if (row.number === void 0)
183
+ continue;
184
+ const where = `${field}[${index}]`;
185
+ const first = claimed.get(row.number);
186
+ if (first === void 0) {
187
+ claimed.set(row.number, where);
188
+ continue;
189
+ }
190
+ ctx.addIssue({
191
+ code: "custom",
192
+ path: [field, index, "number"],
193
+ message: `number ${row.number} is claimed by both ${first} and ${where} in ${repo.owner}/${repo.name}. Issues and pull requests share one per-repo counter, so a number names one entity or the other.`
194
+ });
195
+ }
196
+ }
172
197
  }))
173
198
  });
199
+ function withoutSidecarMeta(input) {
200
+ if (!input || typeof input !== "object" || Array.isArray(input))
201
+ return input;
202
+ if (!("_meta" in input))
203
+ return input;
204
+ const { _meta, ...rest } = input;
205
+ return rest;
206
+ }
174
207
  function parseSeed(input) {
175
- const seed = seedSchema.parse(normalizeLegacyGitHubSeed(input));
208
+ const seed = seedSchema.parse(normalizeLegacyGitHubSeed(withoutSidecarMeta(input)));
176
209
  if (seed.repositories.length === 0) {
177
210
  throw new Error("GitHub seed must contain at least one repository");
178
211
  }