@pome-sh/cli 0.28.0 → 0.29.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.
- package/dist/build-info.json +3 -3
- package/dist/{checks-XPLJ2MKP.js → checks-JR4OEKZM.js} +3 -3
- package/dist/chunk-B7PA7UDX.js +105 -0
- package/dist/{chunk-D5PXUPG4.js → chunk-E7WJ3SRP.js} +4 -1
- package/dist/{chunk-MOZU3NOM.js → chunk-IYMDPMMZ.js} +2 -2
- package/dist/{chunk-JW3DHRNX.js → chunk-MRCYOSBM.js} +24 -5
- package/dist/{chunk-IK2F7ZA3.js → chunk-S6JLWI4S.js} +1 -1
- package/dist/{chunk-JE4H5ODK.js → chunk-SRG22BIH.js} +12 -9
- package/dist/{chunk-QOMNBXMQ.js → chunk-VO2XUPZC.js} +1 -1
- package/dist/{chunk-CWNRE2OU.js → chunk-XAQGX7K2.js} +3 -3
- package/dist/{runDemo-YY5F6FP2.js → runDemo-GBPVF5AA.js} +6 -6
- package/dist/{runTrialGroup-TPDWP2LN.js → runTrialGroup-XEBG225L.js} +7 -6
- package/dist/{seed-3ZTWKLBE.js → seed-F7RNI55S.js} +1 -1
- package/dist/src/cli/main.js +40 -20
- package/dist/{src-JRBHNT4Y.js → src-5YCI6VIR.js} +2 -2
- package/dist/twinHarness-CUVRO5IV.js +6 -0
- package/dist/twinSeed-MOQXJDEG.js +48 -0
- package/dist/{twinStart-PDL53BY5.js → twinStart-ZDWFU6M4.js} +46 -42
- package/package.json +1 -1
- package/dist/twinHarness-YOVJR72F.js +0 -6
- /package/dist/{chunk-G6GOCYIT.js → chunk-Q5NBPR57.js} +0 -0
package/dist/build-info.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"package": "pome-sh",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"git_sha": "
|
|
5
|
-
"build_time": "2026-08-
|
|
3
|
+
"version": "0.29.0",
|
|
4
|
+
"git_sha": "b065b0336a80c35d63c53bed262be6b037bfec76",
|
|
5
|
+
"build_time": "2026-08-26T21:23:55.631Z"
|
|
6
6
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { findManifestPath, readManifest } from './chunk-
|
|
1
|
+
import { findManifestPath, readManifest } from './chunk-VO2XUPZC.js';
|
|
2
2
|
import { getAvailablePort } from './chunk-XDU6TD4O.js';
|
|
3
|
-
import './chunk-
|
|
3
|
+
import './chunk-E7WJ3SRP.js';
|
|
4
4
|
import { buildEgressAllowlist } from './chunk-CBFKZZBR.js';
|
|
5
5
|
import './chunk-6KJC4BTO.js';
|
|
6
6
|
import './chunk-SG6ZTIMT.js';
|
|
@@ -183,7 +183,7 @@ async function checkTwinReachable(_configDir) {
|
|
|
183
183
|
});
|
|
184
184
|
let harness;
|
|
185
185
|
try {
|
|
186
|
-
const { bootTwin } = await import('./twinHarness-
|
|
186
|
+
const { bootTwin } = await import('./twinHarness-CUVRO5IV.js');
|
|
187
187
|
harness = await bootTwin({
|
|
188
188
|
twin: "github",
|
|
189
189
|
seedState: void 0,
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { isTwinName, TWIN_REGISTRY, TWIN_NAMES } from './chunk-SRG22BIH.js';
|
|
2
|
+
import { readFileSync } from 'node:fs';
|
|
3
|
+
import { parse } from 'yaml';
|
|
4
|
+
|
|
5
|
+
function readSeedFileText(path, flag = "--seed") {
|
|
6
|
+
try {
|
|
7
|
+
return readFileSync(path, "utf8");
|
|
8
|
+
} catch (err) {
|
|
9
|
+
throw new Error(`${flag}: cannot read ${path}: ${err.message}`);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
function parseSeedFileText(raw, origin) {
|
|
13
|
+
let parsed;
|
|
14
|
+
try {
|
|
15
|
+
parsed = parse(raw);
|
|
16
|
+
} catch (err) {
|
|
17
|
+
throw new Error(`${origin} is not valid JSON or YAML: ${err.message}`);
|
|
18
|
+
}
|
|
19
|
+
if (Array.isArray(parsed)) {
|
|
20
|
+
throw new Error(`${origin} is not a seed file: its top level is an array, not an object.`);
|
|
21
|
+
}
|
|
22
|
+
if (parsed === null || typeof parsed !== "object") {
|
|
23
|
+
throw new Error(
|
|
24
|
+
`${origin} is not a seed file: its top level is ${parsed === null ? "null" : typeof parsed}, not an object.`
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
const { _meta, ...rest } = parsed;
|
|
28
|
+
const keys = Object.keys(rest);
|
|
29
|
+
const twinKeys = keys.filter((key) => isTwinName(key));
|
|
30
|
+
if (twinKeys.length === 0) return { shape: "flat", seed: rest };
|
|
31
|
+
if (twinKeys.length !== keys.length) {
|
|
32
|
+
const others = keys.filter((key) => !isTwinName(key));
|
|
33
|
+
throw new Error(
|
|
34
|
+
`${origin} mixes twin ids (${twinKeys.join(", ")}) with other keys (${others.join(", ")}). A seed file is either one twin's flat seed or a per-twin envelope { <twin>: <seed> }, not both.`
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
return { shape: "envelope", byTwin: rest };
|
|
38
|
+
}
|
|
39
|
+
function twinsNamedBy(file) {
|
|
40
|
+
if (file.shape === "flat") return [];
|
|
41
|
+
return Object.keys(file.byTwin).filter((key) => isTwinName(key));
|
|
42
|
+
}
|
|
43
|
+
function soleTwinOf(file) {
|
|
44
|
+
const named = twinsNamedBy(file);
|
|
45
|
+
return named.length === 1 ? named[0] : void 0;
|
|
46
|
+
}
|
|
47
|
+
async function seedFieldsFor(twin) {
|
|
48
|
+
return TWIN_REGISTRY[twin].seedFields();
|
|
49
|
+
}
|
|
50
|
+
async function seedForTwin(file, twin, origin, opts = {}) {
|
|
51
|
+
if (file.shape === "flat") return parseWith(twin, file.seed, origin, file);
|
|
52
|
+
assertOnlyAsked(file, opts.asked, origin);
|
|
53
|
+
const named = twinsNamedBy(file);
|
|
54
|
+
if (!(twin in file.byTwin)) {
|
|
55
|
+
throw new Error(
|
|
56
|
+
`${origin} declares no ${twin} seed (it names ${named.join(", ")}). Add a "${twin}" key, or start the twin it names.`
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
return parseWith(twin, file.byTwin[twin], `${origin} ("${twin}")`, file);
|
|
60
|
+
}
|
|
61
|
+
async function seedsForTwins(file, twins, origin) {
|
|
62
|
+
if (file.shape === "flat") {
|
|
63
|
+
if (twins.length !== 1) {
|
|
64
|
+
throw new Error(
|
|
65
|
+
`${origin} is a flat seed and this sandbox has ${twins.length} twins (${twins.join(", ")}), so nothing says which one it is for. Wrap it in a per-twin envelope: { "${twins[0] ?? "<twin>"}": { \u2026 } }.`
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
return { [twins[0]]: await parseWith(twins[0], file.seed, origin, file) };
|
|
69
|
+
}
|
|
70
|
+
assertOnlyAsked(file, twins, origin);
|
|
71
|
+
const out = {};
|
|
72
|
+
for (const twin of twins) {
|
|
73
|
+
if (twin in file.byTwin) {
|
|
74
|
+
out[twin] = await parseWith(twin, file.byTwin[twin], `${origin} ("${twin}")`, file);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return out;
|
|
78
|
+
}
|
|
79
|
+
function assertOnlyAsked(file, asked, origin) {
|
|
80
|
+
if (asked === void 0 || file.shape !== "envelope") return;
|
|
81
|
+
const extras = twinsNamedBy(file).filter((twin) => !asked.includes(twin));
|
|
82
|
+
if (extras.length === 0) return;
|
|
83
|
+
throw new Error(
|
|
84
|
+
`${origin} names ${extras.join(", ")}, which this command was not asked for (asked: ${asked.length ? asked.join(", ") : "none"}). Add --twin for each, or remove them from the file.`
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
async function parseWith(twin, seed, where, file) {
|
|
88
|
+
try {
|
|
89
|
+
return await TWIN_REGISTRY[twin].parseSeed(seed);
|
|
90
|
+
} catch (err) {
|
|
91
|
+
const hint = file.shape === "flat" ? await notSeedFieldsHint(twin, file.seed) : "";
|
|
92
|
+
throw new Error(`${where} is not a seed this twin can boot: ${err.message}${hint}`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
async function notSeedFieldsHint(twin, seed) {
|
|
96
|
+
if (seed === null || typeof seed !== "object" || Array.isArray(seed)) return "";
|
|
97
|
+
const keys = Object.keys(seed);
|
|
98
|
+
if (keys.length === 0) return "";
|
|
99
|
+
const fields = new Set(await seedFieldsFor(twin));
|
|
100
|
+
if (keys.some((key) => fields.has(key))) return "";
|
|
101
|
+
return `
|
|
102
|
+
None of its top-level keys (${keys.join(", ")}) is a field of the ${twin} seed. If this file is a per-twin envelope, its keys must be twin ids: ${TWIN_NAMES.join(", ")}.`;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export { parseSeedFileText, readSeedFileText, seedForTwin, seedsForTwins, soleTwinOf, twinsNamedBy };
|
|
@@ -736,6 +736,9 @@ z.record(
|
|
|
736
736
|
z.string(),
|
|
737
737
|
z.record(z.string(), z.unknown())
|
|
738
738
|
);
|
|
739
|
+
function isMultiTwinSeedEnvelope(twins) {
|
|
740
|
+
return twins.length > 1;
|
|
741
|
+
}
|
|
739
742
|
var taskClassSchema = z.enum(["conformance", "restraint", "adversarial"]);
|
|
740
743
|
var taskConfigSchema = z.object({
|
|
741
744
|
twins: z.array(z.string()).default(["github"]),
|
|
@@ -1264,4 +1267,4 @@ function exitCodeFor(err) {
|
|
|
1264
1267
|
return 2;
|
|
1265
1268
|
}
|
|
1266
1269
|
|
|
1267
|
-
export { HostedAuthError, HostedDiscardRefusedError, HostedOrchError, HostedQuotaError, HostedTrialError, HostedUsageError, MOUNTED_TWINS, SLUG_RE, agentResponseSchema, createEvalSessionResponseSchema, createSessionResponseSchema, criterionSchema, deriveAgentSlug, exitCodeFor, finalizeResponseSchema, manifestSchema, sessionPublicSchema, submitResultResponseSchema };
|
|
1270
|
+
export { HostedAuthError, HostedDiscardRefusedError, HostedOrchError, HostedQuotaError, HostedTrialError, HostedUsageError, MOUNTED_TWINS, SLUG_RE, agentResponseSchema, createEvalSessionResponseSchema, createSessionResponseSchema, criterionSchema, deriveAgentSlug, exitCodeFor, finalizeResponseSchema, isMultiTwinSeedEnvelope, manifestSchema, sessionPublicSchema, submitResultResponseSchema };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { parseTaskFile, seedStateForTwin, runAgentCommand, writeRunArtifactsCore } from './chunk-
|
|
2
|
-
import { createRecorder, bootTwin } from './chunk-
|
|
1
|
+
import { parseTaskFile, seedStateForTwin, runAgentCommand, writeRunArtifactsCore } from './chunk-XAQGX7K2.js';
|
|
2
|
+
import { createRecorder, bootTwin } from './chunk-S6JLWI4S.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,6 +1,7 @@
|
|
|
1
|
-
import { createHostedClient, perTwinReturnedByCloud, parseTaskFile, runAgentCommand, writeRunArtifactsCore, toTwinHttpEvent, redactJsonl, uploadRunBlobs, scoreFromFinalizeResponse, scoreStatus, evaluationCounts } from './chunk-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { createHostedClient, perTwinReturnedByCloud, parseTaskFile, runAgentCommand, writeRunArtifactsCore, toTwinHttpEvent, redactJsonl, uploadRunBlobs, scoreFromFinalizeResponse, scoreStatus, evaluationCounts } from './chunk-XAQGX7K2.js';
|
|
2
|
+
import { readSeedFileText, parseSeedFileText, soleTwinOf, seedsForTwins } from './chunk-B7PA7UDX.js';
|
|
3
|
+
import { readManifest, normalizeManifestTwins } from './chunk-VO2XUPZC.js';
|
|
4
|
+
import { MOUNTED_TWINS, HostedAuthError, HostedDiscardRefusedError, HostedQuotaError, HostedOrchError, HostedTrialError, agentResponseSchema, isMultiTwinSeedEnvelope } from './chunk-E7WJ3SRP.js';
|
|
4
5
|
import { redactSecrets, redactEvent } from './chunk-SG6ZTIMT.js';
|
|
5
6
|
import { randomUUID, createHash } from 'node:crypto';
|
|
6
7
|
import { rm, readFile, stat, mkdir, writeFile, chmod, mkdtemp, readdir, rename } from 'node:fs/promises';
|
|
@@ -697,8 +698,22 @@ function normalizeSessionTwins(raw) {
|
|
|
697
698
|
}
|
|
698
699
|
return deduped;
|
|
699
700
|
}
|
|
701
|
+
async function resolveSessionSeed(seedPath, requestedTwins) {
|
|
702
|
+
const raw = readSeedFileText(seedPath, "pome sandbox create --seed");
|
|
703
|
+
const origin = `--seed ${seedPath}`;
|
|
704
|
+
const file = parseSeedFileText(raw, origin);
|
|
705
|
+
const twins = normalizeSessionTwins(
|
|
706
|
+
requestedTwins.length > 0 ? requestedTwins : [soleTwinOf(file) ?? ""].filter(Boolean)
|
|
707
|
+
);
|
|
708
|
+
const byTwin = await seedsForTwins(file, twins, origin);
|
|
709
|
+
return {
|
|
710
|
+
twins,
|
|
711
|
+
seed: isMultiTwinSeedEnvelope(twins) ? byTwin : byTwin[twins[0]]
|
|
712
|
+
};
|
|
713
|
+
}
|
|
700
714
|
async function runSessionCreate(opts) {
|
|
701
|
-
const
|
|
715
|
+
const resolvedSeed = opts.seedPath === void 0 ? void 0 : await resolveSessionSeed(opts.seedPath, opts.twins);
|
|
716
|
+
const twins = resolvedSeed?.twins ?? normalizeSessionTwins(opts.twins);
|
|
702
717
|
const creds = await resolveCredentials({ apiBaseUrl: opts.apiBaseUrl });
|
|
703
718
|
const client = createHostedClient({
|
|
704
719
|
baseUrl: creds.apiBaseUrl,
|
|
@@ -713,7 +728,8 @@ async function runSessionCreate(opts) {
|
|
|
713
728
|
taskSource: "# ..\n",
|
|
714
729
|
idempotencyKey: randomUUID(),
|
|
715
730
|
agentId: identity.agentId,
|
|
716
|
-
agentVersion: identity.agentVersion
|
|
731
|
+
agentVersion: identity.agentVersion,
|
|
732
|
+
...resolvedSeed ? { seed: resolvedSeed.seed } : {}
|
|
717
733
|
});
|
|
718
734
|
if (opts.secretsFile) {
|
|
719
735
|
await writeSecretsFile(opts.secretsFile, formatEnvExport(session, twins));
|
|
@@ -736,6 +752,9 @@ async function runSessionCreate(opts) {
|
|
|
736
752
|
}
|
|
737
753
|
console.error(`Session: ${session.session_id}`);
|
|
738
754
|
console.error(`Expires: ${session.expires_at}`);
|
|
755
|
+
if (opts.seedPath !== void 0) {
|
|
756
|
+
console.error(`Seed: ${opts.seedPath} (replaces the default for ${twins.join(", ")}).`);
|
|
757
|
+
}
|
|
739
758
|
let printedAny = false;
|
|
740
759
|
const mcpFromCloud = perTwinReturnedByCloud(session);
|
|
741
760
|
for (const twin of twins) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { TWIN_NAMES, isTwinName, TWIN_REGISTRY } from './chunk-
|
|
1
|
+
import { TWIN_NAMES, isTwinName, TWIN_REGISTRY } from './chunk-SRG22BIH.js';
|
|
2
2
|
import { createFileBackedRecorderStore, createRecorderStore } from './chunk-E665XWYU.js';
|
|
3
3
|
|
|
4
4
|
// src/recorder/recorder.ts
|
|
@@ -30,10 +30,9 @@ var TWIN_REGISTRY = {
|
|
|
30
30
|
envName: "GITHUB",
|
|
31
31
|
defaultPort: 3333,
|
|
32
32
|
version: package_default.version,
|
|
33
|
-
|
|
34
|
-
// when no seed is supplied — the pre-existing standalone behavior.
|
|
35
|
-
defaultSeed: async () => void 0,
|
|
33
|
+
defaultSeed: async () => (await import('./seed-BG5HMSBM.js')).defaultSeedState(),
|
|
36
34
|
parseSeed: async (input) => (await import('./seed-BG5HMSBM.js')).parseSeed(input),
|
|
35
|
+
seedFields: async () => Object.keys((await import('./seed-BG5HMSBM.js')).seedSchema.shape),
|
|
37
36
|
async boot({ seedState, runId, recorder }) {
|
|
38
37
|
const {
|
|
39
38
|
createGitHubCloneApp,
|
|
@@ -60,8 +59,9 @@ var TWIN_REGISTRY = {
|
|
|
60
59
|
envName: "SLACK",
|
|
61
60
|
defaultPort: 3333,
|
|
62
61
|
version: package_default2.version,
|
|
63
|
-
defaultSeed: async () => (await import('./
|
|
62
|
+
defaultSeed: async () => (await import('./seed-IIMBJHAJ.js')).defaultSeedState(),
|
|
64
63
|
parseSeed: async (input) => (await import('./seed-IIMBJHAJ.js')).parseSeed(input),
|
|
64
|
+
seedFields: async () => Object.keys((await import('./seed-IIMBJHAJ.js')).seedSchema.shape),
|
|
65
65
|
async boot({ seedState, runId, recorder }) {
|
|
66
66
|
const { createSlackTwinApp, openSlackTwinDatabase, SlackDomain } = await import('./src-SKCWAMVQ.js');
|
|
67
67
|
const db = openSlackTwinDatabase(":memory:");
|
|
@@ -86,8 +86,9 @@ var TWIN_REGISTRY = {
|
|
|
86
86
|
envName: "STRIPE",
|
|
87
87
|
defaultPort: 3333,
|
|
88
88
|
version: package_default3.version,
|
|
89
|
-
defaultSeed: async () => (await import('./
|
|
89
|
+
defaultSeed: async () => (await import('./seed-YWDTT2WL.js')).defaultSeed(),
|
|
90
90
|
parseSeed: async (input) => (await import('./seed-YWDTT2WL.js')).parseSeed(input),
|
|
91
|
+
seedFields: async () => Object.keys((await import('./seed-YWDTT2WL.js')).seedSchema.shape),
|
|
91
92
|
async boot({ seedState, runId, recorder, twinBaseUrl }) {
|
|
92
93
|
const stripeTwin = await import('./src-PW7U25ZX.js');
|
|
93
94
|
const { createApp } = await import('./server-DMLORMOV.js');
|
|
@@ -131,8 +132,9 @@ var TWIN_REGISTRY = {
|
|
|
131
132
|
portEnvName: "GMAIL_TWIN_PORT",
|
|
132
133
|
tokenEnvName: "POME_GMAIL_TOKEN",
|
|
133
134
|
version: package_default4.version,
|
|
134
|
-
defaultSeed: async () => (await import('./
|
|
135
|
+
defaultSeed: async () => (await import('./seed-NR6RUKXV.js')).defaultSeedState(),
|
|
135
136
|
parseSeed: async (input) => (await import('./seed-NR6RUKXV.js')).parseSeed(input),
|
|
137
|
+
seedFields: async () => Object.keys((await import('./seed-NR6RUKXV.js')).gmailSeedSchema.shape),
|
|
136
138
|
async boot({ seedState, runId, recorder }) {
|
|
137
139
|
const { createGmailTwinApp, GmailDomain, openGmailTwinDatabase, parseSeed } = await import('./src-KSLAF3I4.js');
|
|
138
140
|
const db = openGmailTwinDatabase(":memory:");
|
|
@@ -153,8 +155,9 @@ var TWIN_REGISTRY = {
|
|
|
153
155
|
portEnvName: "LINEAR_TWIN_PORT",
|
|
154
156
|
tokenEnvName: "POME_LINEAR_TOKEN",
|
|
155
157
|
version: package_default5.version,
|
|
156
|
-
defaultSeed: async () => (await import('./
|
|
157
|
-
parseSeed: async (input) => (await import('./seed-
|
|
158
|
+
defaultSeed: async () => (await import('./seed-F7RNI55S.js')).defaultSeedState(),
|
|
159
|
+
parseSeed: async (input) => (await import('./seed-F7RNI55S.js')).parseSeed(input),
|
|
160
|
+
seedFields: async () => Object.keys((await import('./seed-F7RNI55S.js')).linearSeedSchema.shape),
|
|
158
161
|
async boot({ seedState, runId, recorder }) {
|
|
159
162
|
const {
|
|
160
163
|
createLinearTwinApp,
|
|
@@ -162,7 +165,7 @@ var TWIN_REGISTRY = {
|
|
|
162
165
|
LinearDomain,
|
|
163
166
|
openLinearTwinDatabase,
|
|
164
167
|
parseSeed
|
|
165
|
-
} = await import('./src-
|
|
168
|
+
} = await import('./src-5YCI6VIR.js');
|
|
166
169
|
const db = openLinearTwinDatabase(":memory:");
|
|
167
170
|
const seed = parseSeed(seedState);
|
|
168
171
|
const domain = new LinearDomain(db);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { HostedOrchError, manifestSchema, deriveAgentSlug, SLUG_RE } from './chunk-
|
|
1
|
+
import { HostedOrchError, manifestSchema, deriveAgentSlug, SLUG_RE } from './chunk-E7WJ3SRP.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';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { gmailSeedSchema, defaultSeedState } from './chunk-3T5XN64P.js';
|
|
2
|
-
import { linearSeedSchema, defaultSeedState as defaultSeedState$1 } from './chunk-
|
|
3
|
-
import { isTwinName, TWIN_REGISTRY } from './chunk-
|
|
4
|
-
import { criterionSchema, finalizeResponseSchema, HostedDiscardRefusedError, HostedOrchError, HostedAuthError, HostedQuotaError, submitResultResponseSchema, createEvalSessionResponseSchema, createSessionResponseSchema, sessionPublicSchema } from './chunk-
|
|
2
|
+
import { linearSeedSchema, defaultSeedState as defaultSeedState$1 } from './chunk-Q5NBPR57.js';
|
|
3
|
+
import { isTwinName, TWIN_REGISTRY } from './chunk-SRG22BIH.js';
|
|
4
|
+
import { criterionSchema, finalizeResponseSchema, HostedDiscardRefusedError, HostedOrchError, HostedAuthError, HostedQuotaError, submitResultResponseSchema, createEvalSessionResponseSchema, createSessionResponseSchema, sessionPublicSchema } from './chunk-E7WJ3SRP.js';
|
|
5
5
|
import { seedSchema, parseSeed, defaultSeedState as defaultSeedState$2 } from './chunk-HJX25USP.js';
|
|
6
6
|
import { toTwinHttpEventRow } from './chunk-E665XWYU.js';
|
|
7
7
|
import { redactEvent, redactSecrets } from './chunk-SG6ZTIMT.js';
|
|
@@ -1,14 +1,14 @@
|
|
|
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-
|
|
4
|
-
import { createHostedClient, parseTaskFile, uploadRunBlobs, scoreFromFinalizeResponse, scoreStatus, outcomeOf } from './chunk-
|
|
3
|
+
import { runTask, demoTaskPath, DEMO_TASK_NAME, DEMO_REPO } from './chunk-IYMDPMMZ.js';
|
|
4
|
+
import { createHostedClient, parseTaskFile, uploadRunBlobs, scoreFromFinalizeResponse, scoreStatus, outcomeOf } from './chunk-XAQGX7K2.js';
|
|
5
5
|
import './chunk-NW7HGA2K.js';
|
|
6
6
|
import './chunk-3T5XN64P.js';
|
|
7
|
-
import './chunk-
|
|
8
|
-
import { bootTwin } from './chunk-
|
|
9
|
-
import './chunk-
|
|
7
|
+
import './chunk-Q5NBPR57.js';
|
|
8
|
+
import { bootTwin } from './chunk-S6JLWI4S.js';
|
|
9
|
+
import './chunk-SRG22BIH.js';
|
|
10
10
|
import { getAvailablePort } from './chunk-XDU6TD4O.js';
|
|
11
|
-
import { HostedQuotaError, HostedOrchError } from './chunk-
|
|
11
|
+
import { HostedQuotaError, HostedOrchError } from './chunk-E7WJ3SRP.js';
|
|
12
12
|
import './chunk-CBFKZZBR.js';
|
|
13
13
|
import './chunk-HJX25USP.js';
|
|
14
14
|
import './chunk-E665XWYU.js';
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { newGroupId, criterionPhrase } from './chunk-RGZBC7NF.js';
|
|
2
|
-
import { runTaskHosted, resolveRunAgentIdentity } from './chunk-
|
|
3
|
-
import { createHostedClient, parseTaskFile, outcomeOf } from './chunk-
|
|
2
|
+
import { runTaskHosted, resolveRunAgentIdentity } from './chunk-MRCYOSBM.js';
|
|
3
|
+
import { createHostedClient, parseTaskFile, outcomeOf } from './chunk-XAQGX7K2.js';
|
|
4
|
+
import './chunk-B7PA7UDX.js';
|
|
4
5
|
import './chunk-NW7HGA2K.js';
|
|
5
6
|
import './chunk-3T5XN64P.js';
|
|
6
|
-
import './chunk-
|
|
7
|
-
import './chunk-
|
|
8
|
-
import './chunk-
|
|
9
|
-
import { HostedQuotaError, HostedTrialError } from './chunk-
|
|
7
|
+
import './chunk-Q5NBPR57.js';
|
|
8
|
+
import './chunk-SRG22BIH.js';
|
|
9
|
+
import './chunk-VO2XUPZC.js';
|
|
10
|
+
import { HostedQuotaError, HostedTrialError } from './chunk-E7WJ3SRP.js';
|
|
10
11
|
import './chunk-HJX25USP.js';
|
|
11
12
|
import './chunk-E665XWYU.js';
|
|
12
13
|
import './chunk-6KJC4BTO.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { defaultSeedState, linearSeedSchema, loadSeedFromEnv, parseSeed } from './chunk-
|
|
1
|
+
export { defaultSeedState, linearSeedSchema, loadSeedFromEnv, parseSeed } from './chunk-Q5NBPR57.js';
|
package/dist/src/cli/main.js
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
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-
|
|
3
|
-
import { assetPath, runTask, resolvePackageRoot, DEMO_TASK_NAME, demoTaskPath } from '../../chunk-
|
|
4
|
-
import { parseTaskFile, scoreStatus, runScoreLine, readLatestRun, readMetaSummary, outcomeOf, readConfigTwins, scoreCountsSummary, markerFor, criterionMarkerLabel, twinSkipSuffix, readCodeCriteria, createHostedClient, toTwinHttpEvent, redactJsonl, scoreFromFinalizeResponse, parseGitHubSeedState, uploadRunBlobs, isPreSatisfied } from '../../chunk-
|
|
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-MRCYOSBM.js';
|
|
3
|
+
import { assetPath, runTask, resolvePackageRoot, DEMO_TASK_NAME, demoTaskPath } from '../../chunk-IYMDPMMZ.js';
|
|
4
|
+
import { parseTaskFile, scoreStatus, runScoreLine, readLatestRun, readMetaSummary, outcomeOf, readConfigTwins, scoreCountsSummary, markerFor, criterionMarkerLabel, twinSkipSuffix, readCodeCriteria, createHostedClient, toTwinHttpEvent, redactJsonl, scoreFromFinalizeResponse, parseGitHubSeedState, uploadRunBlobs, isPreSatisfied } from '../../chunk-XAQGX7K2.js';
|
|
5
|
+
import '../../chunk-B7PA7UDX.js';
|
|
5
6
|
import '../../chunk-NW7HGA2K.js';
|
|
6
7
|
import { GMAIL_CHECKS } from '../../chunk-JM6VS62R.js';
|
|
7
8
|
import '../../chunk-3T5XN64P.js';
|
|
8
9
|
import { LINEAR_CHECKS } from '../../chunk-XBT6ZLBG.js';
|
|
9
|
-
import '../../chunk-
|
|
10
|
-
import '../../chunk-
|
|
11
|
-
import { TWIN_NAME_LIST, isTwinName, createGitHubSmokeApp } from '../../chunk-
|
|
12
|
-
import { readManifest, writeManifest, MANIFEST_JSON, readRequiredManifest, normalizeManifestTwins } from '../../chunk-
|
|
10
|
+
import '../../chunk-Q5NBPR57.js';
|
|
11
|
+
import '../../chunk-S6JLWI4S.js';
|
|
12
|
+
import { TWIN_NAME_LIST, isTwinName, createGitHubSmokeApp } from '../../chunk-SRG22BIH.js';
|
|
13
|
+
import { readManifest, writeManifest, MANIFEST_JSON, readRequiredManifest, normalizeManifestTwins } from '../../chunk-VO2XUPZC.js';
|
|
13
14
|
import '../../chunk-XDU6TD4O.js';
|
|
14
|
-
import { MOUNTED_TWINS, deriveAgentSlug, exitCodeFor, HostedUsageError, HostedOrchError, HostedAuthError, HostedQuotaError } from '../../chunk-
|
|
15
|
+
import { MOUNTED_TWINS, deriveAgentSlug, exitCodeFor, HostedUsageError, HostedOrchError, HostedAuthError, HostedQuotaError } from '../../chunk-E7WJ3SRP.js';
|
|
15
16
|
import '../../chunk-CBFKZZBR.js';
|
|
16
17
|
import { TAPE_ASSERTABLE_TOOLS } from '../../chunk-C4BVTUA3.js';
|
|
17
18
|
import { seedSchema } from '../../chunk-HJX25USP.js';
|
|
@@ -4652,7 +4653,7 @@ var DEFAULT_AGENT_COMMAND = `node ${DEFAULT_AGENT_FILE}`;
|
|
|
4652
4653
|
var MANIFEST_SCHEMA_URL = "https://pome.sh/schemas/v1/pome.json";
|
|
4653
4654
|
var MAX_UNREADABLE_PATHS_SHOWN = 5;
|
|
4654
4655
|
function readPackageVersion() {
|
|
4655
|
-
if ("0.
|
|
4656
|
+
if ("0.29.0".length > 0) return "0.29.0";
|
|
4656
4657
|
try {
|
|
4657
4658
|
const here = dirname(fileURLToPath(import.meta.url));
|
|
4658
4659
|
const candidates = [
|
|
@@ -4896,7 +4897,7 @@ function createProgram() {
|
|
|
4896
4897
|
const session = program.command("session").alias("sandbox").description(
|
|
4897
4898
|
"Hosted sandbox sessions (same API as the dashboard Twins page \u2014 requires login)"
|
|
4898
4899
|
);
|
|
4899
|
-
session.command("create").description("Create a hosted sandbox session for one or more twins and print its connection info").
|
|
4900
|
+
session.command("create").description("Create a hosted sandbox session for one or more twins and print its connection info").option(
|
|
4900
4901
|
"--twin <name>",
|
|
4901
4902
|
// The enumeration is derived, never typed: this line is the public
|
|
4902
4903
|
// discovery surface for which twins exist, and a hand-written copy of the
|
|
@@ -4904,8 +4905,17 @@ function createProgram() {
|
|
|
4904
4905
|
// stays editorial — github+gmail is the pairing bundled task 27 exercises —
|
|
4905
4906
|
// and `session-twin-help.test.ts` runs the twins it names through the same
|
|
4906
4907
|
// validator, so it cannot rot either.
|
|
4907
|
-
|
|
4908
|
+
//
|
|
4909
|
+
// No longer `requiredOption`: a `--seed` file whose envelope names exactly
|
|
4910
|
+
// one twin already says which twin the sandbox is for. Commander would
|
|
4911
|
+
// reject the invocation before the action runs, so the check moved into
|
|
4912
|
+
// `runSessionCreate`, which fails with the same "No twin specified"
|
|
4913
|
+
// sentence when neither source supplies one.
|
|
4914
|
+
`${SESSION_TWIN_NAMES.join(" | ")}. Repeat the flag for a multi-twin session (e.g. --twin github --twin gmail). Optional when --seed names exactly one twin.`,
|
|
4908
4915
|
(value, previous = []) => [...previous, value]
|
|
4916
|
+
).option(
|
|
4917
|
+
"--seed <path>",
|
|
4918
|
+
"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>`."
|
|
4909
4919
|
).option(
|
|
4910
4920
|
"--api-url <url>",
|
|
4911
4921
|
"Control-plane URL",
|
|
@@ -4928,10 +4938,11 @@ function createProgram() {
|
|
|
4928
4938
|
}
|
|
4929
4939
|
await runSessionCreate({
|
|
4930
4940
|
apiBaseUrl: opts.apiUrl,
|
|
4931
|
-
twins: opts.twin,
|
|
4941
|
+
twins: opts.twin ?? [],
|
|
4932
4942
|
showSecrets: opts.showSecrets,
|
|
4933
4943
|
format,
|
|
4934
|
-
secretsFile: opts.secretsFile
|
|
4944
|
+
secretsFile: opts.secretsFile,
|
|
4945
|
+
seedPath: opts.seed
|
|
4935
4946
|
});
|
|
4936
4947
|
} catch (err) {
|
|
4937
4948
|
console.error(friendlyHostedError(err));
|
|
@@ -5103,7 +5114,7 @@ function createProgram() {
|
|
|
5103
5114
|
return;
|
|
5104
5115
|
}
|
|
5105
5116
|
{
|
|
5106
|
-
const { runDoctorChecks } = await import('../../checks-
|
|
5117
|
+
const { runDoctorChecks } = await import('../../checks-JR4OEKZM.js');
|
|
5107
5118
|
const { renderDoctorReport } = await import('../../render-ZQQ4UMNO.js');
|
|
5108
5119
|
const doctorReport = await runDoctorChecks({ mode: useLocal ? "full" : "hosted" });
|
|
5109
5120
|
if (!doctorReport.ok) {
|
|
@@ -5141,7 +5152,7 @@ function createProgram() {
|
|
|
5141
5152
|
taskForRuns.config.runs
|
|
5142
5153
|
);
|
|
5143
5154
|
if (k > 1) {
|
|
5144
|
-
const { runTrialGroup } = await import('../../runTrialGroup-
|
|
5155
|
+
const { runTrialGroup } = await import('../../runTrialGroup-XEBG225L.js');
|
|
5145
5156
|
const fileForRerun = relative(process.cwd(), file);
|
|
5146
5157
|
const rerunCommand = defaultTask ? options.trials !== void 0 ? `pome run -n ${k}` : "pome run" : `pome run ${fileForRerun && !fileForRerun.startsWith("..") ? fileForRerun : file} -n ${k}`;
|
|
5147
5158
|
const groupResult = await runTrialGroup({
|
|
@@ -5235,7 +5246,7 @@ function createProgram() {
|
|
|
5235
5246
|
process.exitCode = 5;
|
|
5236
5247
|
return;
|
|
5237
5248
|
}
|
|
5238
|
-
const { runDemo } = await import('../../runDemo-
|
|
5249
|
+
const { runDemo } = await import('../../runDemo-GBPVF5AA.js');
|
|
5239
5250
|
const result = await runDemo({
|
|
5240
5251
|
apiBase: opts.apiUrl.replace(/\/$/, ""),
|
|
5241
5252
|
dashboardBase: process.env.POME_DASHBOARD_URL ?? DEFAULT_DASHBOARD_URL,
|
|
@@ -5253,7 +5264,7 @@ function createProgram() {
|
|
|
5253
5264
|
program.command("doctor").description(
|
|
5254
5265
|
"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."
|
|
5255
5266
|
).action(async () => {
|
|
5256
|
-
const { runDoctorChecks } = await import('../../checks-
|
|
5267
|
+
const { runDoctorChecks } = await import('../../checks-JR4OEKZM.js');
|
|
5257
5268
|
const { renderDoctorReport } = await import('../../render-ZQQ4UMNO.js');
|
|
5258
5269
|
const report = await runDoctorChecks();
|
|
5259
5270
|
for (const line of renderDoctorReport(report, { passNote: true })) console.error(line);
|
|
@@ -5423,18 +5434,27 @@ function createProgram() {
|
|
|
5423
5434
|
);
|
|
5424
5435
|
});
|
|
5425
5436
|
const twin = program.command("twin").description("Manage local twins");
|
|
5426
|
-
twin.command("start").argument(
|
|
5437
|
+
twin.command("start").argument(
|
|
5438
|
+
"[name]",
|
|
5439
|
+
`Twin name (${TWIN_NAME_LIST.join(" | ")}). Optional when --seed names exactly one twin.`
|
|
5440
|
+
).option(
|
|
5427
5441
|
"--port <port>",
|
|
5428
5442
|
"Port to bind (default: $PORT, else GMAIL_TWIN_PORT/3336 for gmail, else 3333)"
|
|
5429
5443
|
).option(
|
|
5430
5444
|
"--seed <path>",
|
|
5431
|
-
"Boot this twin
|
|
5445
|
+
"Boot this twin from a JSON or YAML seed file instead of its default. A seed REPLACES the default; it does not merge. Takes the per-twin envelope { <twin>: { \u2026 } } or one twin's flat seed. Overrides POME_SEED_JSON."
|
|
5432
5446
|
).description(
|
|
5433
5447
|
"Start a standalone twin as a long-lived foreground server (Ctrl-C to stop)"
|
|
5434
5448
|
).action(async (name, options) => {
|
|
5435
|
-
const { runTwinStartCommand } = await import('../../twinStart-
|
|
5449
|
+
const { runTwinStartCommand } = await import('../../twinStart-ZDWFU6M4.js');
|
|
5436
5450
|
await runTwinStartCommand(name, options);
|
|
5437
5451
|
});
|
|
5452
|
+
twin.command("seed").argument("<name...>", `Twin name (${TWIN_NAME_LIST.join(" | ")}). Repeat for one file covering several.`).option("--out <path>", "Write to this file instead of stdout. Refuses to overwrite.").description(
|
|
5453
|
+
"Print a starter seed file for a twin, generated from the twin's own starting state"
|
|
5454
|
+
).action(async (names, options) => {
|
|
5455
|
+
const { runTwinSeedCommand } = await import('../../twinSeed-MOQXJDEG.js');
|
|
5456
|
+
await runTwinSeedCommand(names, options);
|
|
5457
|
+
});
|
|
5438
5458
|
twin.command("reset").argument("[name]", "Twin name (default: github)", "github").description("Reset standalone twin state").action(async (name) => {
|
|
5439
5459
|
if (!isTwinName(name)) {
|
|
5440
5460
|
throw new Error(`Unknown twin '${name}'. Supported: ${TWIN_NAME_LIST.join(", ")}.`);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { LINEAR_CHECKS } from './chunk-XBT6ZLBG.js';
|
|
2
|
-
import { MCP_PAGE_MAX, defaultSeedState, linearSeedSchema, notFound, badUserInput, MCP_PAGE_DEFAULT, DEFAULT_LINEAR_EMAIL, RELAY_PAGE_MAX, RELAY_PAGE_DEFAULT, STATE_EXPORT_CAP, parseSeed, DEFAULT_LINEAR_CLOCK, LINEAR_PROVIDER_TOKEN_PREFIX, DEFAULT_LINEAR_SID, DEFAULT_SCOPES, linearErrorEnvelope, unauthorizedEnvelope, unsupportedEnvelope, forbiddenEnvelope, assertWebhookUrl, ACCESS_TOKEN_TTL_SECONDS, OAUTH_CODE_TTL_SECONDS, TITLE_MAX_BYTES, BODY_MAX_BYTES, LinearTwinError, GRAPHQL_QUERY_MAX_BYTES, GRAPHQL_SELECTION_DEPTH_MAX } from './chunk-
|
|
3
|
-
export { DEFAULT_LINEAR_CLOCK, DEFAULT_LINEAR_EMAIL, DEFAULT_LINEAR_PORT, DEFAULT_LINEAR_SID, DEFAULT_LINEAR_TOKEN, LINEAR_PROVIDER_TOKEN_PREFIX, LinearTwinError, STATE_EXPORT_CAP, assertWebhookUrl, defaultSeedState, linearErrorEnvelope, linearSeedSchema, loadSeedFromEnv, parseSeed, unauthorizedEnvelope, unsupportedEnvelope, webhookUrlError } from './chunk-
|
|
2
|
+
import { MCP_PAGE_MAX, defaultSeedState, linearSeedSchema, notFound, badUserInput, MCP_PAGE_DEFAULT, DEFAULT_LINEAR_EMAIL, RELAY_PAGE_MAX, RELAY_PAGE_DEFAULT, STATE_EXPORT_CAP, parseSeed, DEFAULT_LINEAR_CLOCK, LINEAR_PROVIDER_TOKEN_PREFIX, DEFAULT_LINEAR_SID, DEFAULT_SCOPES, linearErrorEnvelope, unauthorizedEnvelope, unsupportedEnvelope, forbiddenEnvelope, assertWebhookUrl, ACCESS_TOKEN_TTL_SECONDS, OAUTH_CODE_TTL_SECONDS, TITLE_MAX_BYTES, BODY_MAX_BYTES, LinearTwinError, GRAPHQL_QUERY_MAX_BYTES, GRAPHQL_SELECTION_DEPTH_MAX } from './chunk-Q5NBPR57.js';
|
|
3
|
+
export { DEFAULT_LINEAR_CLOCK, DEFAULT_LINEAR_EMAIL, DEFAULT_LINEAR_PORT, DEFAULT_LINEAR_SID, DEFAULT_LINEAR_TOKEN, LINEAR_PROVIDER_TOKEN_PREFIX, LinearTwinError, STATE_EXPORT_CAP, assertWebhookUrl, defaultSeedState, linearErrorEnvelope, linearSeedSchema, loadSeedFromEnv, parseSeed, unauthorizedEnvelope, unsupportedEnvelope, webhookUrlError } from './chunk-Q5NBPR57.js';
|
|
4
4
|
import './chunk-JWJYNAWI.js';
|
|
5
5
|
import { routeInputDeclarer, mountDeclaredRoute, UndeclaredInputError } from './chunk-IZFM7W2V.js';
|
|
6
6
|
import { loadMcpToolFixture, deriveMcpToolTable, openTwinDatabase, defineTwin, createApp } from './chunk-E665XWYU.js';
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { TWIN_NAMES, isTwinName, TWIN_REGISTRY } from './chunk-SRG22BIH.js';
|
|
2
|
+
import { writeFile } from 'node:fs/promises';
|
|
3
|
+
|
|
4
|
+
async function generateSeedFile(twins) {
|
|
5
|
+
if (twins.length === 0) {
|
|
6
|
+
throw new Error(`No twin specified. Pass at least one of: ${TWIN_NAMES.join(", ")}.`);
|
|
7
|
+
}
|
|
8
|
+
for (const twin of twins) {
|
|
9
|
+
if (!isTwinName(twin)) {
|
|
10
|
+
throw new Error(`Unknown twin '${twin}'. Supported: ${TWIN_NAMES.join(", ")}.`);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
const duplicates = twins.filter((twin, i) => twins.indexOf(twin) !== i);
|
|
14
|
+
if (duplicates.length > 0) {
|
|
15
|
+
throw new Error(`A seed file has one entry per twin, and this one is named twice: ${[...new Set(duplicates)].join(", ")}.`);
|
|
16
|
+
}
|
|
17
|
+
const envelope = {};
|
|
18
|
+
for (const twin of twins) {
|
|
19
|
+
const entry = TWIN_REGISTRY[twin];
|
|
20
|
+
envelope[twin] = await entry.parseSeed(await entry.defaultSeed());
|
|
21
|
+
}
|
|
22
|
+
return `${JSON.stringify(envelope, null, 2)}
|
|
23
|
+
`;
|
|
24
|
+
}
|
|
25
|
+
async function writeSeedFile(path, text) {
|
|
26
|
+
try {
|
|
27
|
+
await writeFile(path, text, { flag: "wx" });
|
|
28
|
+
} catch (err) {
|
|
29
|
+
if (err.code === "EEXIST") {
|
|
30
|
+
throw new Error(
|
|
31
|
+
`${path} already exists \u2014 delete it or pass a different --out. A seed file is authored content once it is on disk.`
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
throw err;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
async function runTwinSeedCommand(names, options = {}) {
|
|
38
|
+
const text = await generateSeedFile(names);
|
|
39
|
+
if (options.out === void 0) {
|
|
40
|
+
process.stdout.write(text);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
await writeSeedFile(options.out, text);
|
|
44
|
+
console.error(`Wrote ${options.out} \u2014 the ${names.join(" + ")} starting seed.`);
|
|
45
|
+
console.error(`Boot it: pome twin start ${names[0]} --seed ${options.out}`);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export { generateSeedFile, runTwinSeedCommand, writeSeedFile };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { readSeedFileText, seedForTwin, parseSeedFileText, soleTwinOf, twinsNamedBy } from './chunk-B7PA7UDX.js';
|
|
2
|
+
import { bootTwin } from './chunk-S6JLWI4S.js';
|
|
3
|
+
import { TWIN_REGISTRY, isTwinName, TWIN_NAMES, defaultPortFor } from './chunk-SRG22BIH.js';
|
|
3
4
|
import './chunk-E665XWYU.js';
|
|
4
5
|
import './chunk-6KJC4BTO.js';
|
|
5
6
|
import './chunk-SG6ZTIMT.js';
|
|
@@ -10,7 +11,6 @@ import { mkdir, writeFile } from 'node:fs/promises';
|
|
|
10
11
|
import { join } from 'node:path';
|
|
11
12
|
import { serve } from '@hono/node-server';
|
|
12
13
|
import { sign } from 'hono/jwt';
|
|
13
|
-
import { parse } from 'yaml';
|
|
14
14
|
|
|
15
15
|
var STANDALONE_SID = "standalone";
|
|
16
16
|
function resolveStandaloneAuthSecret(twin, env = process.env) {
|
|
@@ -35,59 +35,59 @@ function resolveStandaloneAuthSecret(twin, env = process.env) {
|
|
|
35
35
|
}
|
|
36
36
|
return { secret: randomBytes(32).toString("hex"), source: "ephemeral" };
|
|
37
37
|
}
|
|
38
|
-
async function resolveStandaloneSeed(twin, seedPath, env = process.env) {
|
|
39
|
-
const entry = TWIN_REGISTRY[twin];
|
|
38
|
+
async function resolveStandaloneSeed(twin, seedPath, env = process.env, seedText) {
|
|
40
39
|
if (seedPath !== void 0) {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
raw = readFileSync(seedPath, "utf8");
|
|
44
|
-
} catch (err) {
|
|
45
|
-
throw new Error(
|
|
46
|
-
`pome twin start --seed: cannot read ${seedPath}: ${err.message}`
|
|
47
|
-
);
|
|
48
|
-
}
|
|
40
|
+
const raw = seedText ?? readSeedFileText(seedPath, "pome twin start --seed");
|
|
41
|
+
const origin = `--seed ${seedPath}`;
|
|
49
42
|
return {
|
|
50
|
-
seedState: await
|
|
43
|
+
seedState: await seedForTwin(parseSeedFileText(raw, origin), twin, origin),
|
|
51
44
|
source: "file",
|
|
52
45
|
path: seedPath
|
|
53
46
|
};
|
|
54
47
|
}
|
|
55
48
|
const fromEnv = env.POME_SEED_JSON;
|
|
56
49
|
if (fromEnv !== void 0 && fromEnv !== "") {
|
|
57
|
-
return {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
50
|
+
return {
|
|
51
|
+
seedState: await seedForTwin(
|
|
52
|
+
parseSeedFileText(fromEnv, "POME_SEED_JSON"),
|
|
53
|
+
twin,
|
|
54
|
+
"POME_SEED_JSON"
|
|
55
|
+
),
|
|
56
|
+
source: "env"
|
|
57
|
+
};
|
|
65
58
|
}
|
|
66
|
-
return
|
|
59
|
+
return { seedState: await TWIN_REGISTRY[twin].defaultSeed(), source: "default" };
|
|
67
60
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
61
|
+
function resolveStandaloneTwin(name, seedPath, seedText) {
|
|
62
|
+
if (name !== void 0) {
|
|
63
|
+
if (!isTwinName(name)) {
|
|
64
|
+
throw new Error(`Unknown twin '${name}'. Supported: ${TWIN_NAMES.join(", ")}.`);
|
|
65
|
+
}
|
|
66
|
+
return name;
|
|
74
67
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
68
|
+
if (seedPath === void 0 || seedText === void 0) {
|
|
69
|
+
throw new Error(
|
|
70
|
+
`pome twin start: name a twin (${TWIN_NAMES.join(", ")}), or pass a --seed file whose envelope names exactly one.`
|
|
71
|
+
);
|
|
79
72
|
}
|
|
73
|
+
const origin = `--seed ${seedPath}`;
|
|
74
|
+
const file = parseSeedFileText(seedText, origin);
|
|
75
|
+
const sole = soleTwinOf(file);
|
|
76
|
+
if (sole !== void 0) return sole;
|
|
77
|
+
const named = twinsNamedBy(file);
|
|
78
|
+
throw new Error(
|
|
79
|
+
named.length === 0 ? `${origin} is a flat seed, so it does not name a twin. Pass the name: pome twin start <${TWIN_NAMES.join("|")}> --seed ${seedPath}` : `${origin} names ${named.length} twins (${named.join(", ")}), so it does not say which one to start. Pass the name: pome twin start ${named[0]} --seed ${seedPath}`
|
|
80
|
+
);
|
|
80
81
|
}
|
|
81
|
-
async function runTwinStartCommand(
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
82
|
+
async function runTwinStartCommand(nameArg, options) {
|
|
83
|
+
const seedText = options.seed === void 0 ? void 0 : readSeedFileText(options.seed, "pome twin start --seed");
|
|
84
|
+
const name = resolveStandaloneTwin(nameArg, options.seed, seedText);
|
|
85
85
|
const portRaw = options.port ?? defaultPortFor(name, process.env);
|
|
86
86
|
const port = Number(portRaw);
|
|
87
87
|
if (!Number.isInteger(port) || port < 1 || port > 65535) {
|
|
88
88
|
throw new Error(`pome twin start: invalid --port "${portRaw}"`);
|
|
89
89
|
}
|
|
90
|
-
const world = await resolveStandaloneSeed(name, options.seed);
|
|
90
|
+
const world = await resolveStandaloneSeed(name, options.seed, process.env, seedText);
|
|
91
91
|
const resolved = resolveStandaloneAuthSecret(name);
|
|
92
92
|
process.env.TWIN_AUTH_SECRET = resolved.secret;
|
|
93
93
|
const baseUrl = `http://127.0.0.1:${port}`;
|
|
@@ -130,11 +130,15 @@ async function runTwinStartCommand(name, options) {
|
|
|
130
130
|
}
|
|
131
131
|
console.log(`Pome ${name} twin listening at ${restUrl}`);
|
|
132
132
|
if (world.source === "file") {
|
|
133
|
-
console.log(`
|
|
133
|
+
console.log(`Seed: ${world.path} (replaces the ${name} twin's default).`);
|
|
134
134
|
} else if (world.source === "env") {
|
|
135
|
-
console.log(
|
|
135
|
+
console.log(
|
|
136
|
+
`Seed: POME_SEED_JSON (replaces the ${name} twin's default; --seed <path> overrides it).`
|
|
137
|
+
);
|
|
136
138
|
} else {
|
|
137
|
-
console.log(
|
|
139
|
+
console.log(
|
|
140
|
+
`Seed: the ${name} twin's default (pass --seed <path>, or write one with \`pome twin seed ${name}\`).`
|
|
141
|
+
);
|
|
138
142
|
}
|
|
139
143
|
if (resolved.source === "persisted") {
|
|
140
144
|
console.log(
|
|
@@ -161,4 +165,4 @@ async function runTwinStartCommand(name, options) {
|
|
|
161
165
|
process.once("SIGTERM", shutdown);
|
|
162
166
|
}
|
|
163
167
|
|
|
164
|
-
export { resolveStandaloneAuthSecret, resolveStandaloneSeed, runTwinStartCommand };
|
|
168
|
+
export { resolveStandaloneAuthSecret, resolveStandaloneSeed, resolveStandaloneTwin, runTwinStartCommand };
|
package/package.json
CHANGED
|
File without changes
|