@pome-sh/cli 0.26.13 → 0.28.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 (36) hide show
  1. package/dist/build-info.json +3 -3
  2. package/dist/{checks-3LVRPHOK.js → checks-XPLJ2MKP.js} +3 -3
  3. package/dist/{chunk-NJ246QPJ.js → chunk-3T5XN64P.js} +35 -33
  4. package/dist/chunk-CF6EIU2U.js +51 -0
  5. package/dist/{chunk-ANKO3RCB.js → chunk-CWNRE2OU.js} +26 -9
  6. package/dist/{chunk-BZO3YCJS.js → chunk-D5PXUPG4.js} +33 -1
  7. package/dist/{chunk-CFXEETE3.js → chunk-E665XWYU.js} +2 -49
  8. package/dist/{chunk-IZIZC7ZW.js → chunk-G6GOCYIT.js} +23 -21
  9. package/dist/{chunk-QXQAVKTE.js → chunk-HJX25USP.js} +14 -1
  10. package/dist/{chunk-KIXYRPVY.js → chunk-IK2F7ZA3.js} +2 -2
  11. package/dist/{chunk-EIUCTFQV.js → chunk-JE4H5ODK.js} +16 -11
  12. package/dist/{chunk-6IVXTU67.js → chunk-JW3DHRNX.js} +6 -5
  13. package/dist/{chunk-FQGR7KDT.js → chunk-MOZU3NOM.js} +2 -2
  14. package/dist/{chunk-CXGMLUZ4.js → chunk-QOMNBXMQ.js} +1 -1
  15. package/dist/chunk-SLTBPJKZ.js +522 -0
  16. package/dist/chunk-ZDS25NS5.js +141 -0
  17. package/dist/{runDemo-XO5R5QTM.js → runDemo-YY5F6FP2.js} +11 -10
  18. package/dist/{runTrialGroup-CLJJOO4J.js → runTrialGroup-TPDWP2LN.js} +10 -9
  19. package/dist/seed-3ZTWKLBE.js +1 -0
  20. package/dist/seed-BG5HMSBM.js +1 -0
  21. package/dist/seed-IIMBJHAJ.js +1 -0
  22. package/dist/seed-NR6RUKXV.js +1 -0
  23. package/dist/seed-YWDTT2WL.js +2 -0
  24. package/dist/server-DMLORMOV.js +4 -0
  25. package/dist/src/cli/main.js +33 -23
  26. package/dist/{src-JJNS46T6.js → src-56Y2R7ZQ.js} +4 -3
  27. package/dist/{src-Q4JNJE5S.js → src-JRBHNT4Y.js} +4 -3
  28. package/dist/{src-GWA7QVQS.js → src-KSLAF3I4.js} +4 -3
  29. package/dist/{src-FXRQSKBK.js → src-PW7U25ZX.js} +6 -518
  30. package/dist/{src-L6F5YXSP.js → src-SKCWAMVQ.js} +5 -138
  31. package/dist/twinHarness-YOVJR72F.js +6 -0
  32. package/dist/{twinStart-WIT4UVAC.js → twinStart-PDL53BY5.js} +58 -5
  33. package/package.json +1 -1
  34. package/dist/server-TK5YBK6E.js +0 -3
  35. package/dist/twinHarness-6NVAKIOB.js +0 -5
  36. package/dist/{run-CFA4LZWQ.js → run-WONFTZS3.js} +1 -1
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "package": "pome-sh",
3
- "version": "0.26.13",
4
- "git_sha": "74c1f2f7f0c5e290bf94cae208a6f88e1c0b9ed2",
5
- "build_time": "2026-08-25T12:39:52.951Z"
3
+ "version": "0.28.0",
4
+ "git_sha": "fe45f413881e8c19ab370dd63e03fbf118ac8edb",
5
+ "build_time": "2026-08-26T19:10:23.010Z"
6
6
  }
@@ -1,7 +1,7 @@
1
- import { findManifestPath, readManifest } from './chunk-CXGMLUZ4.js';
1
+ import { findManifestPath, readManifest } from './chunk-QOMNBXMQ.js';
2
2
  import { getAvailablePort } from './chunk-XDU6TD4O.js';
3
+ import './chunk-D5PXUPG4.js';
3
4
  import { buildEgressAllowlist } from './chunk-CBFKZZBR.js';
4
- import './chunk-BZO3YCJS.js';
5
5
  import './chunk-6KJC4BTO.js';
6
6
  import './chunk-SG6ZTIMT.js';
7
7
  import { serve } from '@hono/node-server';
@@ -183,7 +183,7 @@ async function checkTwinReachable(_configDir) {
183
183
  });
184
184
  let harness;
185
185
  try {
186
- const { bootTwin } = await import('./twinHarness-6NVAKIOB.js');
186
+ const { bootTwin } = await import('./twinHarness-YOVJR72F.js');
187
187
  harness = await bootTwin({
188
188
  twin: "github",
189
189
  seedState: void 0,
@@ -1,6 +1,6 @@
1
1
  import { z, ZodError } from 'zod';
2
2
 
3
- // ../packages/twin-gmail/dist/src/errors.js
3
+ // ../packages/twin-gmail/dist/src/seed.js
4
4
  var GmailError = class extends Error {
5
5
  status;
6
6
  reason;
@@ -111,6 +111,40 @@ function googleStatus(status) {
111
111
  return "INTERNAL";
112
112
  }
113
113
 
114
+ // ../packages/twin-gmail/dist/src/faults.js
115
+ var KNOWN_FAULT_NAMES = ["rate-limited"];
116
+ var gmailFaultSchema = z.object({
117
+ name: z.enum(KNOWN_FAULT_NAMES),
118
+ target: z.string().min(1).max(128).default("messages.send"),
119
+ succeedFirst: z.number().int().nonnegative().max(1e3).default(2),
120
+ throttleFor: z.number().int().positive().max(1e3).default(3),
121
+ retryAfterSeconds: z.number().int().positive().max(3600).default(1)
122
+ }).strict();
123
+ function checkFault(db, operation) {
124
+ const fault = readFaults(db).find((f) => f.target === operation);
125
+ if (!fault)
126
+ return;
127
+ const calls = bumpFaultCounter(db, operation);
128
+ if (calls > fault.succeedFirst && calls <= fault.succeedFirst + fault.throttleFor) {
129
+ throw new GmailError(429, "rateLimitExceeded", `Rate limit exceeded for ${operation}. Retry after ${fault.retryAfterSeconds}s.`);
130
+ }
131
+ }
132
+ function readFaults(db) {
133
+ const row = db.prepare("SELECT value FROM gmail_config WHERE key = 'faults'").get();
134
+ if (!row)
135
+ return [];
136
+ try {
137
+ return JSON.parse(row.value);
138
+ } catch {
139
+ return [];
140
+ }
141
+ }
142
+ function bumpFaultCounter(db, operation) {
143
+ db.prepare("INSERT INTO fault_counters(operation, calls) VALUES (?, 1) ON CONFLICT(operation) DO UPDATE SET calls = calls + 1").run(operation);
144
+ const row = db.prepare("SELECT calls FROM fault_counters WHERE operation = ?").get(operation);
145
+ return row.calls;
146
+ }
147
+
114
148
  // ../packages/twin-gmail/dist/src/search-parse.js
115
149
  var MAX_QUERY_BYTES = 4096;
116
150
  var MAX_TOKENS = 256;
@@ -415,38 +449,6 @@ function tokenize(query) {
415
449
  function makeImplicitOr(node) {
416
450
  return node.type === "and" ? { type: "or", children: node.children } : node;
417
451
  }
418
- var KNOWN_FAULT_NAMES = ["rate-limited"];
419
- var gmailFaultSchema = z.object({
420
- name: z.enum(KNOWN_FAULT_NAMES),
421
- target: z.string().min(1).max(128).default("messages.send"),
422
- succeedFirst: z.number().int().nonnegative().max(1e3).default(2),
423
- throttleFor: z.number().int().positive().max(1e3).default(3),
424
- retryAfterSeconds: z.number().int().positive().max(3600).default(1)
425
- }).strict();
426
- function checkFault(db, operation) {
427
- const fault = readFaults(db).find((f) => f.target === operation);
428
- if (!fault)
429
- return;
430
- const calls = bumpFaultCounter(db, operation);
431
- if (calls > fault.succeedFirst && calls <= fault.succeedFirst + fault.throttleFor) {
432
- throw new GmailError(429, "rateLimitExceeded", `Rate limit exceeded for ${operation}. Retry after ${fault.retryAfterSeconds}s.`);
433
- }
434
- }
435
- function readFaults(db) {
436
- const row = db.prepare("SELECT value FROM gmail_config WHERE key = 'faults'").get();
437
- if (!row)
438
- return [];
439
- try {
440
- return JSON.parse(row.value);
441
- } catch {
442
- return [];
443
- }
444
- }
445
- function bumpFaultCounter(db, operation) {
446
- db.prepare("INSERT INTO fault_counters(operation, calls) VALUES (?, 1) ON CONFLICT(operation) DO UPDATE SET calls = calls + 1").run(operation);
447
- const row = db.prepare("SELECT calls FROM fault_counters WHERE operation = ?").get(operation);
448
- return row.calls;
449
- }
450
452
 
451
453
  // ../packages/twin-gmail/dist/src/seed.js
452
454
  var email = z.string().trim().email().transform((value) => value.toLowerCase());
@@ -0,0 +1,51 @@
1
+ import { z } from 'zod';
2
+
3
+ // ../packages/sdk/dist/failure-injection-rules.js
4
+ var FAILURE_INJECTION_OVERRIDE_KEY = "failureInjectionOverride";
5
+ var failureInjectionRuleSchema = z.object({
6
+ method: z.string().min(1).transform((s) => s.toUpperCase()),
7
+ path: z.string().min(1),
8
+ attempt: z.number().int().positive(),
9
+ mode: z.enum(["before_handler", "after_handler"]).default("after_handler"),
10
+ status: z.number().int().min(100).max(599),
11
+ body: z.unknown()
12
+ });
13
+ function createFailureInjectionStore() {
14
+ let rules = [];
15
+ const counters = /* @__PURE__ */ new Map();
16
+ const tuplesWithRules = /* @__PURE__ */ new Set();
17
+ function tupleKey(method, path) {
18
+ return `${method.toUpperCase()}\0${path}`;
19
+ }
20
+ function counterKey(accountId, method, path) {
21
+ return `${accountId}\0${method.toUpperCase()}\0${path}`;
22
+ }
23
+ function rebuildIndex() {
24
+ tuplesWithRules.clear();
25
+ for (const r of rules)
26
+ tuplesWithRules.add(tupleKey(r.method, r.path));
27
+ }
28
+ return {
29
+ setRules(next) {
30
+ rules = next.slice();
31
+ counters.clear();
32
+ rebuildIndex();
33
+ },
34
+ clear() {
35
+ rules = [];
36
+ counters.clear();
37
+ tuplesWithRules.clear();
38
+ },
39
+ matchAndConsume(accountId, method, path) {
40
+ const tk = tupleKey(method, path);
41
+ if (!tuplesWithRules.has(tk))
42
+ return null;
43
+ const ck = counterKey(accountId, method, path);
44
+ const count = (counters.get(ck) ?? 0) + 1;
45
+ counters.set(ck, count);
46
+ return rules.find((r) => r.method.toUpperCase() === method.toUpperCase() && r.path === path && r.attempt === count) ?? null;
47
+ }
48
+ };
49
+ }
50
+
51
+ export { FAILURE_INJECTION_OVERRIDE_KEY, createFailureInjectionStore, failureInjectionRuleSchema };
@@ -1,9 +1,9 @@
1
- import { criterionSchema, finalizeResponseSchema, HostedDiscardRefusedError, HostedOrchError, HostedAuthError, HostedQuotaError, submitResultResponseSchema, createEvalSessionResponseSchema, createSessionResponseSchema, sessionPublicSchema } from './chunk-BZO3YCJS.js';
2
- import { seedSchema, parseSeed, defaultSeedState as defaultSeedState$2 } from './chunk-QXQAVKTE.js';
3
- import { gmailSeedSchema, defaultSeedState } from './chunk-NJ246QPJ.js';
4
- import { linearSeedSchema, defaultSeedState as defaultSeedState$1 } from './chunk-IZIZC7ZW.js';
5
- import { isTwinName, TWIN_REGISTRY } from './chunk-EIUCTFQV.js';
6
- import { toTwinHttpEventRow } from './chunk-CFXEETE3.js';
1
+ import { gmailSeedSchema, defaultSeedState } from './chunk-3T5XN64P.js';
2
+ import { linearSeedSchema, defaultSeedState as defaultSeedState$1 } from './chunk-G6GOCYIT.js';
3
+ import { isTwinName, TWIN_REGISTRY } from './chunk-JE4H5ODK.js';
4
+ import { criterionSchema, finalizeResponseSchema, HostedDiscardRefusedError, HostedOrchError, HostedAuthError, HostedQuotaError, submitResultResponseSchema, createEvalSessionResponseSchema, createSessionResponseSchema, sessionPublicSchema } from './chunk-D5PXUPG4.js';
5
+ import { seedSchema, parseSeed, defaultSeedState as defaultSeedState$2 } from './chunk-HJX25USP.js';
6
+ import { toTwinHttpEventRow } from './chunk-E665XWYU.js';
7
7
  import { redactEvent, redactSecrets } from './chunk-SG6ZTIMT.js';
8
8
  import { mkdir, appendFile, writeFile, readFile } from 'node:fs/promises';
9
9
  import { existsSync } from 'node:fs';
@@ -1255,6 +1255,8 @@ function normalizeAgentSdk(value) {
1255
1255
 
1256
1256
  // ../packages/wire/dist/run-completeness.js
1257
1257
  var PRE_SATISFIED_REASON = "already_true_in_seed";
1258
+ var ADVISORY_SCORE_STATE = "advisory";
1259
+ var ABSTAINED_SCORE_STATE = "abstained";
1258
1260
 
1259
1261
  // src/hosted/evalResultView.ts
1260
1262
  function outcomeOf(result) {
@@ -1265,6 +1267,9 @@ function outcomeOf(result) {
1265
1267
  function isPreSatisfied(result) {
1266
1268
  return result.skipped && result.reason === PRE_SATISFIED_REASON;
1267
1269
  }
1270
+ function isNarrated(result) {
1271
+ return result.skipped && (result.score_state === ADVISORY_SCORE_STATE || result.score_state === ABSTAINED_SCORE_STATE);
1272
+ }
1268
1273
  function scoreStatus(score, passThreshold) {
1269
1274
  if (!score.evaluated || !score.can_pass) return "incomplete";
1270
1275
  return score.satisfaction >= passThreshold ? "pass" : "fail";
@@ -1296,12 +1301,16 @@ function criteriaWord(n) {
1296
1301
  }
1297
1302
  function evaluationCounts(score) {
1298
1303
  const evaluated = score.total_required;
1299
- const notEvaluated = score.skipped + score.errored - score.preSatisfied;
1304
+ const exempt = score.preSatisfied + score.advisory + score.abstained;
1305
+ const notEvaluated = score.skipped + score.errored - exempt;
1300
1306
  return {
1301
1307
  evaluated,
1302
1308
  notEvaluated,
1303
1309
  preSatisfied: score.preSatisfied,
1304
- total: evaluated + notEvaluated + score.preSatisfied
1310
+ // `total` counts every exemption, not just `preSatisfied`, so it still
1311
+ // names every criterion the run recorded — the reason `outcomeOf` keeps
1312
+ // narrator rows inside `skipped` rather than returning their state raw.
1313
+ total: evaluated + notEvaluated + exempt
1305
1314
  };
1306
1315
  }
1307
1316
  function scoreCountsSummary(score) {
@@ -1486,8 +1495,14 @@ function scoreFromFinalizeResponse(finalized) {
1486
1495
  const preSatisfied = results.filter(
1487
1496
  (r) => outcomeOf(r) === "skipped" && isPreSatisfied(r)
1488
1497
  ).length;
1498
+ const advisory = results.filter(
1499
+ (r) => isNarrated(r) && !isPreSatisfied(r) && r.score_state === ADVISORY_SCORE_STATE
1500
+ ).length;
1501
+ const abstained = results.filter(
1502
+ (r) => isNarrated(r) && !isPreSatisfied(r) && r.score_state === ABSTAINED_SCORE_STATE
1503
+ ).length;
1489
1504
  const totalRequired = passed + failed;
1490
- const unresolvedAbstentions = skipped - preSatisfied + errored;
1505
+ const unresolvedAbstentions = skipped - preSatisfied - advisory - abstained + errored;
1491
1506
  return {
1492
1507
  satisfaction: finalized.score,
1493
1508
  passed,
@@ -1495,6 +1510,8 @@ function scoreFromFinalizeResponse(finalized) {
1495
1510
  skipped,
1496
1511
  errored,
1497
1512
  preSatisfied,
1513
+ advisory,
1514
+ abstained,
1498
1515
  total_required: totalRequired,
1499
1516
  evaluated: hasCriteriaResults ? totalRequired > 0 : true,
1500
1517
  can_pass: hasCriteriaResults ? totalRequired > 0 && unresolvedAbstentions === 0 : true,
@@ -91,8 +91,40 @@ var baseCriterionResultSchema = z.object({
91
91
  passed: z.boolean(),
92
92
  skipped: z.boolean(),
93
93
  // true if [code] fell back to [model] but the judge was unreachable, etc.
94
- reason: z.string()
94
+ reason: z.string(),
95
95
  // human-readable evidence
96
+ // Why this row is out of the denominator, when `skipped` alone is too coarse.
97
+ // The two values that carry meaning here are `ADVISORY_SCORE_STATE` and
98
+ // `ABSTAINED_SCORE_STATE` (`@pome-sh/wire/run-completeness`), which the
99
+ // narrator stamps on a `[model]` row it read but had no authority to score.
100
+ //
101
+ // NOT NAMED `outcome`: `hosted/evalResultView.ts`'s display model has
102
+ // reserved that key on this same object for a disjoint vocabulary
103
+ // (`passed | failed | skipped | errored`) since long before the narrator, and
104
+ // reserved it for the CLOUD to fill. A cloud writing `advisory` into it would
105
+ // hand `outcomeOf` a value outside its own union and render an advisory row
106
+ // with the skipped glyph.
107
+ //
108
+ // ON THE BASE AND NOT ON ONE ARM, for the mirror image of the reason the arm
109
+ // order below is what it is: an advisory row carries no `confidence` /
110
+ // `judge_model`, so it fails the probabilistic arm and lands on the
111
+ // DETERMINISTIC one — whose `.extend({})` is a plain `z.object` and would
112
+ // strip an unknown key. Declared on one arm, the state would be discarded
113
+ // before any consumer could read it, and the run would keep reading
114
+ // INCOMPLETE with the exemption sitting there correct and dead.
115
+ //
116
+ // `z.string()` AND NOT THE CLOSED ENUM pome-cloud declares for the same
117
+ // field, because the two sides of it have opposite jobs. pome-cloud PRODUCES
118
+ // it and validates what it serves; the CLI CONSUMES it, and
119
+ // `finalizeResponseSchema` is deliberately a tolerant reader (its own comment
120
+ // says so: cloud may emit additive keys "that older/newer CLIs strip rather
121
+ // than reject"). A closed enum here would turn a cloud that adds a third
122
+ // score state into a hard parse failure of the ENTIRE /finalize response —
123
+ // an unreadable run instead of an unrecognised field. The closed vocabulary
124
+ // is applied by the PREDICATE that reads it (`isNarrated`), exactly as
125
+ // `reason` is a plain string and `PRE_SATISFIED_REASON` is a comparison, so
126
+ // an unrecognised spelling is not exempted from anything.
127
+ score_state: z.string().optional()
96
128
  });
97
129
  var deterministicCriterionResultSchema = baseCriterionResultSchema.extend({
98
130
  // [code] adds nothing further; criterion.type === "code" identifies it.
@@ -1,4 +1,5 @@
1
1
  import { redactSecrets, redactEvent } from './chunk-SG6ZTIMT.js';
2
+ import { FAILURE_INJECTION_OVERRIDE_KEY } from './chunk-CF6EIU2U.js';
2
3
  import { Hono } from 'hono';
3
4
  import { z } from 'zod';
4
5
  import { mkdirSync, openSync, createWriteStream, closeSync, writeFileSync, rmSync, readFileSync, fsync } from 'node:fs';
@@ -1391,54 +1392,6 @@ function ok(body, mutation = false) {
1391
1392
  function created(body) {
1392
1393
  return { status: 201, body, mutation: true };
1393
1394
  }
1394
- var FAILURE_INJECTION_OVERRIDE_KEY = "failureInjectionOverride";
1395
- var failureInjectionRuleSchema = z.object({
1396
- method: z.string().min(1).transform((s) => s.toUpperCase()),
1397
- path: z.string().min(1),
1398
- attempt: z.number().int().positive(),
1399
- mode: z.enum(["before_handler", "after_handler"]).default("after_handler"),
1400
- status: z.number().int().min(100).max(599),
1401
- body: z.unknown()
1402
- });
1403
- function createFailureInjectionStore() {
1404
- let rules = [];
1405
- const counters = /* @__PURE__ */ new Map();
1406
- const tuplesWithRules = /* @__PURE__ */ new Set();
1407
- function tupleKey(method, path) {
1408
- return `${method.toUpperCase()}\0${path}`;
1409
- }
1410
- function counterKey(accountId, method, path) {
1411
- return `${accountId}\0${method.toUpperCase()}\0${path}`;
1412
- }
1413
- function rebuildIndex() {
1414
- tuplesWithRules.clear();
1415
- for (const r of rules)
1416
- tuplesWithRules.add(tupleKey(r.method, r.path));
1417
- }
1418
- return {
1419
- setRules(next) {
1420
- rules = next.slice();
1421
- counters.clear();
1422
- rebuildIndex();
1423
- },
1424
- clear() {
1425
- rules = [];
1426
- counters.clear();
1427
- tuplesWithRules.clear();
1428
- },
1429
- matchAndConsume(accountId, method, path) {
1430
- const tk = tupleKey(method, path);
1431
- if (!tuplesWithRules.has(tk))
1432
- return null;
1433
- const ck = counterKey(accountId, method, path);
1434
- const count = (counters.get(ck) ?? 0) + 1;
1435
- counters.set(ck, count);
1436
- return rules.find((r) => r.method.toUpperCase() === method.toUpperCase() && r.path === path && r.attempt === count) ?? null;
1437
- }
1438
- };
1439
- }
1440
-
1441
- // ../packages/sdk/dist/failure-injection.js
1442
1395
  function failureInjectionMiddleware(store, options) {
1443
1396
  return async (c, next) => {
1444
1397
  const session = c.get("session");
@@ -1771,4 +1724,4 @@ function unregisterServeShutdown(close) {
1771
1724
  serveShutdownHooks.delete(close);
1772
1725
  }
1773
1726
 
1774
- export { FAILURE_INJECTION_OVERRIDE_KEY, POME_RECORDER_EVENTS_PATH, PROVIDER_SHAPED_TEAM_ID, TwinBootError, TwinError, UnknownToolError, bearerAuth, createAdminGate, createApp, createFailureInjectionStore, createFileBackedRecorderStore, createRecorderHandle, createRecorderStore, created, defineTwin, deriveMcpToolTable, ensureTwinAuthSecret, failureInjectionMiddleware, failureInjectionRuleSchema, formTokenResolver, isLoopbackHost, loadMcpToolFixture, mintProviderToken, ok, openTwinDatabase, queryTokenResolver, recordedRequestHeaders, requireAdminAuth, resolveAuthSecret, resolveRecorderStore, serve, setClientIp, setRecordedTool, toTwinHttpEventRow, twinBuildInfo, typeDisagreements, verifyProviderToken };
1727
+ export { POME_RECORDER_EVENTS_PATH, PROVIDER_SHAPED_TEAM_ID, TwinBootError, TwinError, UnknownToolError, bearerAuth, createAdminGate, createApp, createFileBackedRecorderStore, createRecorderHandle, createRecorderStore, created, defineTwin, deriveMcpToolTable, ensureTwinAuthSecret, failureInjectionMiddleware, formTokenResolver, isLoopbackHost, loadMcpToolFixture, mintProviderToken, ok, openTwinDatabase, queryTokenResolver, recordedRequestHeaders, requireAdminAuth, resolveAuthSecret, resolveRecorderStore, serve, setClientIp, setRecordedTool, toTwinHttpEventRow, twinBuildInfo, typeDisagreements, verifyProviderToken };
@@ -1,6 +1,26 @@
1
1
  import { z, ZodError } from 'zod';
2
2
 
3
- // ../packages/twin-linear/dist/src/errors.js
3
+ // ../packages/twin-linear/dist/src/seed.js
4
+
5
+ // ../packages/twin-linear/dist/src/types.js
6
+ var DEFAULT_LINEAR_CLOCK = "2026-07-21T00:00:00.000Z";
7
+ var DEFAULT_LINEAR_EMAIL = "admin@pome-twin.test";
8
+ var DEFAULT_LINEAR_TOKEN = "lin_test_admin";
9
+ var LINEAR_PROVIDER_TOKEN_PREFIX = "lin_pome_";
10
+ var DEFAULT_LINEAR_SID = "standalone";
11
+ var DEFAULT_LINEAR_PORT = 3337;
12
+ var DEFAULT_SCOPES = ["read", "write", "issues:create", "comments:create", "admin"];
13
+ var TITLE_MAX_BYTES = 512;
14
+ var BODY_MAX_BYTES = 65536;
15
+ var GRAPHQL_QUERY_MAX_BYTES = 1e5;
16
+ var GRAPHQL_SELECTION_DEPTH_MAX = 20;
17
+ var MCP_PAGE_DEFAULT = 50;
18
+ var MCP_PAGE_MAX = 250;
19
+ var RELAY_PAGE_DEFAULT = 50;
20
+ var RELAY_PAGE_MAX = 250;
21
+ var STATE_EXPORT_CAP = 2e3;
22
+ var OAUTH_CODE_TTL_SECONDS = 600;
23
+ var ACCESS_TOKEN_TTL_SECONDS = 3600;
4
24
  var LinearTwinError = class extends Error {
5
25
  status;
6
26
  code;
@@ -130,26 +150,6 @@ function notFound(message) {
130
150
  throw new LinearTwinError(404, "NOT_FOUND", message);
131
151
  }
132
152
 
133
- // ../packages/twin-linear/dist/src/types.js
134
- var DEFAULT_LINEAR_CLOCK = "2026-07-21T00:00:00.000Z";
135
- var DEFAULT_LINEAR_EMAIL = "admin@pome-twin.test";
136
- var DEFAULT_LINEAR_TOKEN = "lin_test_admin";
137
- var LINEAR_PROVIDER_TOKEN_PREFIX = "lin_pome_";
138
- var DEFAULT_LINEAR_SID = "standalone";
139
- var DEFAULT_LINEAR_PORT = 3337;
140
- var DEFAULT_SCOPES = ["read", "write", "issues:create", "comments:create", "admin"];
141
- var TITLE_MAX_BYTES = 512;
142
- var BODY_MAX_BYTES = 65536;
143
- var GRAPHQL_QUERY_MAX_BYTES = 1e5;
144
- var GRAPHQL_SELECTION_DEPTH_MAX = 20;
145
- var MCP_PAGE_DEFAULT = 50;
146
- var MCP_PAGE_MAX = 250;
147
- var RELAY_PAGE_DEFAULT = 50;
148
- var RELAY_PAGE_MAX = 250;
149
- var STATE_EXPORT_CAP = 2e3;
150
- var OAUTH_CODE_TTL_SECONDS = 600;
151
- var ACCESS_TOKEN_TTL_SECONDS = 3600;
152
-
153
153
  // ../packages/twin-linear/dist/src/webhook-url.js
154
154
  function webhookUrlError(url) {
155
155
  let parsed;
@@ -172,6 +172,8 @@ function assertWebhookUrl(url) {
172
172
  badUserInput(error);
173
173
  return url;
174
174
  }
175
+
176
+ // ../packages/twin-linear/dist/src/seed.js
175
177
  var datetime = z.string().datetime({ offset: true });
176
178
  var email = z.string().trim().email().transform((v) => v.toLowerCase());
177
179
  var id = z.string().min(1).max(128);
@@ -214,6 +214,19 @@ function normalizeLegacyIssueAssignee(issue) {
214
214
  }
215
215
  return issue;
216
216
  }
217
+ function loadSeedFromEnv(env = process.env) {
218
+ const raw = env.POME_SEED_JSON;
219
+ if (raw === void 0 || raw === "") {
220
+ return parseSeed(defaultSeedState());
221
+ }
222
+ let parsed;
223
+ try {
224
+ parsed = JSON.parse(raw);
225
+ } catch (err) {
226
+ throw new Error(`POME_SEED_JSON is not valid JSON: ${err.message}`);
227
+ }
228
+ return parseSeed(parsed);
229
+ }
217
230
  function defaultSeedState() {
218
231
  return {
219
232
  users: [
@@ -252,4 +265,4 @@ function defaultSeedState() {
252
265
  };
253
266
  }
254
267
 
255
- export { defaultSeedState, parseSeed, seedSchema };
268
+ export { defaultSeedState, loadSeedFromEnv, parseSeed, seedSchema };
@@ -1,5 +1,5 @@
1
- import { TWIN_NAMES, isTwinName, TWIN_REGISTRY } from './chunk-EIUCTFQV.js';
2
- import { createFileBackedRecorderStore, createRecorderStore } from './chunk-CFXEETE3.js';
1
+ import { TWIN_NAMES, isTwinName, TWIN_REGISTRY } from './chunk-JE4H5ODK.js';
2
+ import { createFileBackedRecorderStore, createRecorderStore } from './chunk-E665XWYU.js';
3
3
 
4
4
  // src/recorder/recorder.ts
5
5
  function createRecorder(options = {}) {
@@ -33,13 +33,14 @@ var TWIN_REGISTRY = {
33
33
  // The github twin's own `defaultSeedState()` is applied by `boot` below
34
34
  // when no seed is supplied — the pre-existing standalone behavior.
35
35
  defaultSeed: async () => void 0,
36
+ parseSeed: async (input) => (await import('./seed-BG5HMSBM.js')).parseSeed(input),
36
37
  async boot({ seedState, runId, recorder }) {
37
38
  const {
38
39
  createGitHubCloneApp,
39
40
  defaultSeedState,
40
41
  GitHubDomain,
41
42
  openGitHubCloneDatabase
42
- } = await import('./src-JJNS46T6.js');
43
+ } = await import('./src-56Y2R7ZQ.js');
43
44
  const db = openGitHubCloneDatabase();
44
45
  const domain = new GitHubDomain(db);
45
46
  domain.seed(seedState === void 0 ? defaultSeedState() : seedState);
@@ -59,9 +60,10 @@ var TWIN_REGISTRY = {
59
60
  envName: "SLACK",
60
61
  defaultPort: 3333,
61
62
  version: package_default2.version,
62
- defaultSeed: async () => (await import('./src-L6F5YXSP.js')).defaultSeedState(),
63
+ defaultSeed: async () => (await import('./src-SKCWAMVQ.js')).defaultSeedState(),
64
+ parseSeed: async (input) => (await import('./seed-IIMBJHAJ.js')).parseSeed(input),
63
65
  async boot({ seedState, runId, recorder }) {
64
- const { createSlackTwinApp, openSlackTwinDatabase, SlackDomain } = await import('./src-L6F5YXSP.js');
66
+ const { createSlackTwinApp, openSlackTwinDatabase, SlackDomain } = await import('./src-SKCWAMVQ.js');
65
67
  const db = openSlackTwinDatabase(":memory:");
66
68
  const domain = new SlackDomain(db);
67
69
  domain.applySeed(seedState);
@@ -84,10 +86,11 @@ var TWIN_REGISTRY = {
84
86
  envName: "STRIPE",
85
87
  defaultPort: 3333,
86
88
  version: package_default3.version,
87
- defaultSeed: async () => (await import('./src-FXRQSKBK.js')).defaultSeed(),
89
+ defaultSeed: async () => (await import('./src-PW7U25ZX.js')).defaultSeed(),
90
+ parseSeed: async (input) => (await import('./seed-YWDTT2WL.js')).parseSeed(input),
88
91
  async boot({ seedState, runId, recorder, twinBaseUrl }) {
89
- const stripeTwin = await import('./src-FXRQSKBK.js');
90
- const { createApp } = await import('./server-TK5YBK6E.js');
92
+ const stripeTwin = await import('./src-PW7U25ZX.js');
93
+ const { createApp } = await import('./server-DMLORMOV.js');
91
94
  const {
92
95
  applySeed: applyStripeSeed,
93
96
  createTwinStripeApp,
@@ -128,9 +131,10 @@ var TWIN_REGISTRY = {
128
131
  portEnvName: "GMAIL_TWIN_PORT",
129
132
  tokenEnvName: "POME_GMAIL_TOKEN",
130
133
  version: package_default4.version,
131
- defaultSeed: async () => (await import('./src-GWA7QVQS.js')).defaultSeedState(),
134
+ defaultSeed: async () => (await import('./src-KSLAF3I4.js')).defaultSeedState(),
135
+ parseSeed: async (input) => (await import('./seed-NR6RUKXV.js')).parseSeed(input),
132
136
  async boot({ seedState, runId, recorder }) {
133
- const { createGmailTwinApp, GmailDomain, openGmailTwinDatabase, parseSeed } = await import('./src-GWA7QVQS.js');
137
+ const { createGmailTwinApp, GmailDomain, openGmailTwinDatabase, parseSeed } = await import('./src-KSLAF3I4.js');
134
138
  const db = openGmailTwinDatabase(":memory:");
135
139
  const seed = parseSeed(seedState);
136
140
  const domain = new GmailDomain(db);
@@ -149,7 +153,8 @@ var TWIN_REGISTRY = {
149
153
  portEnvName: "LINEAR_TWIN_PORT",
150
154
  tokenEnvName: "POME_LINEAR_TOKEN",
151
155
  version: package_default5.version,
152
- defaultSeed: async () => (await import('./src-Q4JNJE5S.js')).defaultSeedState(),
156
+ defaultSeed: async () => (await import('./src-JRBHNT4Y.js')).defaultSeedState(),
157
+ parseSeed: async (input) => (await import('./seed-3ZTWKLBE.js')).parseSeed(input),
153
158
  async boot({ seedState, runId, recorder }) {
154
159
  const {
155
160
  createLinearTwinApp,
@@ -157,7 +162,7 @@ var TWIN_REGISTRY = {
157
162
  LinearDomain,
158
163
  openLinearTwinDatabase,
159
164
  parseSeed
160
- } = await import('./src-Q4JNJE5S.js');
165
+ } = await import('./src-JRBHNT4Y.js');
161
166
  const db = openLinearTwinDatabase(":memory:");
162
167
  const seed = parseSeed(seedState);
163
168
  const domain = new LinearDomain(db);
@@ -173,7 +178,7 @@ var TWIN_REGISTRY = {
173
178
  }
174
179
  };
175
180
  async function createGitHubSmokeApp() {
176
- const { createGitHubCloneApp } = await import('./src-JJNS46T6.js');
181
+ const { createGitHubCloneApp } = await import('./src-56Y2R7ZQ.js');
177
182
  return createGitHubCloneApp();
178
183
  }
179
184
  function defaultPortFor(twin, env = process.env) {
@@ -1,6 +1,6 @@
1
- import { readManifest, normalizeManifestTwins } from './chunk-CXGMLUZ4.js';
2
- import { createHostedClient, perTwinReturnedByCloud, parseTaskFile, runAgentCommand, writeRunArtifactsCore, toTwinHttpEvent, redactJsonl, uploadRunBlobs, scoreFromFinalizeResponse, scoreStatus, evaluationCounts } from './chunk-ANKO3RCB.js';
3
- import { MOUNTED_TWINS, HostedAuthError, HostedDiscardRefusedError, HostedQuotaError, HostedOrchError, HostedTrialError, agentResponseSchema } from './chunk-BZO3YCJS.js';
1
+ import { createHostedClient, perTwinReturnedByCloud, parseTaskFile, runAgentCommand, writeRunArtifactsCore, toTwinHttpEvent, redactJsonl, uploadRunBlobs, scoreFromFinalizeResponse, scoreStatus, evaluationCounts } from './chunk-CWNRE2OU.js';
2
+ import { readManifest, normalizeManifestTwins } from './chunk-QOMNBXMQ.js';
3
+ import { MOUNTED_TWINS, HostedAuthError, HostedDiscardRefusedError, HostedQuotaError, HostedOrchError, HostedTrialError, agentResponseSchema } from './chunk-D5PXUPG4.js';
4
4
  import { redactSecrets, redactEvent } from './chunk-SG6ZTIMT.js';
5
5
  import { randomUUID, createHash } from 'node:crypto';
6
6
  import { rm, readFile, stat, mkdir, writeFile, chmod, mkdtemp, readdir, rename } from 'node:fs/promises';
@@ -612,7 +612,8 @@ var DEFAULT_DOCS_SITE_ORIGIN = "https://docs.pome.sh";
612
612
  function ensureMcpSuffix(url) {
613
613
  return /\/mcp\/?$/.test(url) ? url : `${url.replace(/\/$/, "")}/mcp`;
614
614
  }
615
- var ALLOWED_TWINS = /* @__PURE__ */ new Set([...MOUNTED_TWINS, "gmail", "linear"]);
615
+ var ALLOWED_TWINS = new Set(MOUNTED_TWINS);
616
+ var SESSION_TWIN_NAMES = [...ALLOWED_TWINS];
616
617
  function redactSession(res) {
617
618
  const pcIn = res.provider_credentials;
618
619
  const pcOut = {};
@@ -1248,4 +1249,4 @@ async function abandonBestEffort(client, sessionId, errorCode) {
1248
1249
  }
1249
1250
  }
1250
1251
 
1251
- export { DEFAULT_CONTROL_PLANE_URL, DEFAULT_DASHBOARD_URL, DEFAULT_DOCS_SITE_ORIGIN, VERDICT_ARTIFACT_VERSION, clearLocalCredentials, discoverRunSet, ensurePomeGitignored, friendlyHostedError, persistCredentialsAfterLogin, postAgentResolver, readLinkCache, resolveCachedAgentId, resolveCredentials, resolveRunAgentIdentity, resolveSeams, runSessionCreate, runSessionList, runSessionStop, runTaskHosted, writeLinkCache };
1252
+ export { DEFAULT_CONTROL_PLANE_URL, DEFAULT_DASHBOARD_URL, DEFAULT_DOCS_SITE_ORIGIN, SESSION_TWIN_NAMES, VERDICT_ARTIFACT_VERSION, clearLocalCredentials, discoverRunSet, ensurePomeGitignored, friendlyHostedError, persistCredentialsAfterLogin, postAgentResolver, readLinkCache, resolveCachedAgentId, resolveCredentials, resolveRunAgentIdentity, resolveSeams, runSessionCreate, runSessionList, runSessionStop, runTaskHosted, writeLinkCache };
@@ -1,7 +1,7 @@
1
+ import { parseTaskFile, seedStateForTwin, runAgentCommand, writeRunArtifactsCore } from './chunk-CWNRE2OU.js';
2
+ import { createRecorder, bootTwin } from './chunk-IK2F7ZA3.js';
1
3
  import { getAvailablePort } from './chunk-XDU6TD4O.js';
2
4
  import { buildEgressAllowlist, readBlockedEgress } from './chunk-CBFKZZBR.js';
3
- import { parseTaskFile, seedStateForTwin, runAgentCommand, writeRunArtifactsCore } from './chunk-ANKO3RCB.js';
4
- import { createRecorder, bootTwin } from './chunk-KIXYRPVY.js';
5
5
  import { eventSchema } from './chunk-6KJC4BTO.js';
6
6
  import { redactSecrets, redactEvent } from './chunk-SG6ZTIMT.js';
7
7
  import { serve } from '@hono/node-server';
@@ -1,4 +1,4 @@
1
- import { HostedOrchError, manifestSchema, deriveAgentSlug, SLUG_RE } from './chunk-BZO3YCJS.js';
1
+ import { HostedOrchError, manifestSchema, deriveAgentSlug, SLUG_RE } from './chunk-D5PXUPG4.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';