@pome-sh/cli 0.43.1 → 0.44.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/README.md +0 -1
- package/dist/build-info.json +3 -3
- package/dist/{checks-V442KL5O.js → checks-BOOQNOGJ.js} +4 -3
- package/dist/chunk-26UAPLHK.js +191 -0
- package/dist/{chunk-64AWQJ7R.js → chunk-3T4FUF43.js} +1 -1
- package/dist/chunk-4LQ4IJOC.js +1 -0
- package/dist/chunk-7ULGZG7X.js +132 -0
- package/dist/{chunk-5KFDRR53.js → chunk-7VZBAHQ2.js} +2 -2
- package/dist/{chunk-A6AM6KS4.js → chunk-G3YRDMBE.js} +11 -70
- package/dist/{chunk-CS7O2ZXB.js → chunk-M7ATJ423.js} +5 -190
- package/dist/{chunk-4DXTT3RV.js → chunk-RYAQ2ZYA.js} +7 -7
- package/dist/{chunk-GQSNU3YP.js → chunk-ZVKPZHFQ.js} +1 -1
- package/dist/{runTrialGroup-HYGGBLMM.js → runTrialGroup-I3PC2AST.js} +7 -5
- package/dist/{server-2WHSHTUD.js → server-GECKG2H6.js} +1 -1
- package/dist/src/cli/main.js +69 -138
- package/dist/{src-G6CMFUR6.js → src-252X4AEZ.js} +1 -1
- package/dist/{src-DBOHIQNB.js → src-CV7QDV5E.js} +1 -1
- package/dist/{src-FRPUTB2H.js → src-D3PKLT54.js} +1 -1
- package/dist/{src-SJDGRXC5.js → src-LPTWNBO5.js} +1 -1
- package/dist/{src-VBXONWR3.js → src-P5MEPJY4.js} +1 -1
- package/dist/twinHarness-YDGIGB4P.js +6 -0
- package/dist/{twinSeed-J7UAY3GM.js → twinSeed-ADWQ62CA.js} +1 -1
- package/dist/twinStart-E5R26SF4.js +422 -0
- package/dist/twinTape-3XNU3GRW.js +418 -0
- package/examples/agents/mcp-loop-agent.ts +0 -6
- package/package.json +1 -1
- package/dist/twinHarness-33MAVAXV.js +0 -6
- package/dist/twinStart-3Q74IURZ.js +0 -187
package/dist/src/cli/main.js
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { DEFAULT_CONTROL_PLANE_URL, DEFAULT_DASHBOARD_URL, clearLocalCredentials, friendlyHostedError, SESSION_TWIN_NAMES, runSessionCreate, runSessionList, runSessionStop, resolveCredentials, parseTaskFile, runTaskHosted, scoreStatus, runScoreLine, narratorReadingLines, readLatestRun, readMetaSummary, discoverRunSet, outcomeOf, persistCredentialsAfterLogin, DEFAULT_DOCS_SITE_ORIGIN, resolveSeams, readConfigTwins, resolveCachedAgentId, readLinkCache, seedStateForTwin, runAgentCommand, scoreCountsSummary, criterionRowLine, readCodeCriteria, postAgentResolver, writeLinkCache, ensurePomeGitignored, writeRunArtifactsCore, createHostedClient, redactJsonl, scoreFromFinalizeResponse, parseGitHubSeedState, uploadRunBlobs, isPreSatisfied } from '../../chunk-
|
|
3
|
-
import '../../chunk-
|
|
2
|
+
import { DEFAULT_CONTROL_PLANE_URL, DEFAULT_DASHBOARD_URL, clearLocalCredentials, friendlyHostedError, SESSION_TWIN_NAMES, runSessionCreate, runSessionList, runSessionStop, resolveCredentials, parseTaskFile, runTaskHosted, scoreStatus, runScoreLine, narratorReadingLines, readLatestRun, readMetaSummary, discoverRunSet, outcomeOf, persistCredentialsAfterLogin, DEFAULT_DOCS_SITE_ORIGIN, resolveSeams, readConfigTwins, resolveCachedAgentId, readLinkCache, seedStateForTwin, runAgentCommand, scoreCountsSummary, criterionRowLine, readCodeCriteria, postAgentResolver, writeLinkCache, ensurePomeGitignored, writeRunArtifactsCore, createHostedClient, redactJsonl, scoreFromFinalizeResponse, parseGitHubSeedState, uploadRunBlobs, isPreSatisfied } from '../../chunk-G3YRDMBE.js';
|
|
3
|
+
import '../../chunk-ZVKPZHFQ.js';
|
|
4
|
+
import '../../chunk-4LQ4IJOC.js';
|
|
4
5
|
import '../../chunk-NW7HGA2K.js';
|
|
5
6
|
import { GMAIL_CHECKS } from '../../chunk-JM6VS62R.js';
|
|
6
7
|
import '../../chunk-PASFBRK4.js';
|
|
7
8
|
import { LINEAR_CHECKS } from '../../chunk-TSOSDKXP.js';
|
|
8
9
|
import '../../chunk-3FZY376K.js';
|
|
9
|
-
import { createRecorder, bootTwin } from '../../chunk-
|
|
10
|
-
import { TWIN_NAME_LIST, TWIN_REGISTRY, createGitHubSmokeApp } from '../../chunk-
|
|
10
|
+
import { createRecorder, bootTwin } from '../../chunk-3T4FUF43.js';
|
|
11
|
+
import { TWIN_NAME_LIST, TWIN_REGISTRY, createGitHubSmokeApp } from '../../chunk-RYAQ2ZYA.js';
|
|
11
12
|
import { getAvailablePort } from '../../chunk-XDU6TD4O.js';
|
|
12
|
-
import {
|
|
13
|
+
import { readManifest, writeManifest, MANIFEST_JSON, exitCodeFor, readRequiredManifest, HostedUsageError, HostedOrchError, normalizeManifestTwins } from '../../chunk-26UAPLHK.js';
|
|
14
|
+
import { MOUNTED_TWINS, deriveAgentSlug } from '../../chunk-M7ATJ423.js';
|
|
13
15
|
import { buildEgressAllowlist, readBlockedEgress } from '../../chunk-CBFKZZBR.js';
|
|
14
16
|
import { TAPE_ASSERTABLE_TOOLS } from '../../chunk-C4BVTUA3.js';
|
|
15
17
|
import { seedSchema } from '../../chunk-NBOQN5VX.js';
|
|
@@ -17,14 +19,14 @@ import { SLACK_CHECKS } from '../../chunk-2ZGVDTJC.js';
|
|
|
17
19
|
import { oneOf, defineCheck, repoRef, VACUITY_SENTINEL_NUMBER, childStatePath, VACUITY_SENTINEL, statePath, templateSlots, renderCheck, checksDigest, checkPattern, checkNearMissPattern } from '../../chunk-JWJYNAWI.js';
|
|
18
20
|
import '../../chunk-YBWG5JK2.js';
|
|
19
21
|
import '../../chunk-TWURH7YM.js';
|
|
20
|
-
import { eventSchema, isLegacyEventRow } from '../../chunk-
|
|
22
|
+
import { eventSchema, isLegacyEventRow } from '../../chunk-7VZBAHQ2.js';
|
|
21
23
|
import { redactSecrets, redactEvent } from '../../chunk-SG6ZTIMT.js';
|
|
22
24
|
import '../../chunk-2K6BJ3PI.js';
|
|
23
25
|
import '../../chunk-FBSA5L36.js';
|
|
24
26
|
import { Command } from 'commander';
|
|
25
27
|
import { existsSync, readFileSync, realpathSync, statSync, constants } from 'node:fs';
|
|
26
28
|
import { mkdir, readFile, writeFile, readdir, copyFile, stat, cp } from 'node:fs/promises';
|
|
27
|
-
import { dirname, resolve, join, basename, relative,
|
|
29
|
+
import { dirname, resolve, join, basename, relative, extname } from 'node:path';
|
|
28
30
|
import { fileURLToPath } from 'node:url';
|
|
29
31
|
import { serve } from '@hono/node-server';
|
|
30
32
|
import { randomBytes, randomUUID, createHash } from 'node:crypto';
|
|
@@ -322,78 +324,6 @@ function makeShutdown(child, graceMs) {
|
|
|
322
324
|
return done;
|
|
323
325
|
};
|
|
324
326
|
}
|
|
325
|
-
function resolveTwinHttpParents(rows) {
|
|
326
|
-
const eventIdByToolUseId = /* @__PURE__ */ new Map();
|
|
327
|
-
for (const row of rows) {
|
|
328
|
-
if (row.kind === "ToolUseEvent") eventIdByToolUseId.set(row.tool_use_id, row.event_id);
|
|
329
|
-
}
|
|
330
|
-
if (eventIdByToolUseId.size === 0) return rows;
|
|
331
|
-
return rows.map((row) => {
|
|
332
|
-
if (row.kind !== "TwinHttpEvent") return row;
|
|
333
|
-
if (row.parent_event_id != null) return row;
|
|
334
|
-
const causingToolUseId = row.tool_call_id ?? row.correlation_id ?? null;
|
|
335
|
-
if (causingToolUseId === null) return row;
|
|
336
|
-
const parentEventId = eventIdByToolUseId.get(causingToolUseId);
|
|
337
|
-
return parentEventId === void 0 ? row : { ...row, parent_event_id: parentEventId };
|
|
338
|
-
});
|
|
339
|
-
}
|
|
340
|
-
async function mergeAdapterSignalsIntoEvents(signalsPath, eventsJsonlPath) {
|
|
341
|
-
let rawSignals;
|
|
342
|
-
try {
|
|
343
|
-
rawSignals = await readFile(signalsPath, "utf8");
|
|
344
|
-
} catch {
|
|
345
|
-
return { appended: 0, dropped: 0 };
|
|
346
|
-
}
|
|
347
|
-
let dropped = 0;
|
|
348
|
-
const signalRows = [];
|
|
349
|
-
for (const line of rawSignals.split("\n")) {
|
|
350
|
-
if (line.length === 0) continue;
|
|
351
|
-
let parsed;
|
|
352
|
-
try {
|
|
353
|
-
parsed = JSON.parse(line);
|
|
354
|
-
} catch {
|
|
355
|
-
dropped += 1;
|
|
356
|
-
continue;
|
|
357
|
-
}
|
|
358
|
-
const result = eventSchema.safeParse(parsed);
|
|
359
|
-
if (!result.success) {
|
|
360
|
-
dropped += 1;
|
|
361
|
-
continue;
|
|
362
|
-
}
|
|
363
|
-
signalRows.push(redactEvent(result.data));
|
|
364
|
-
}
|
|
365
|
-
if (signalRows.length === 0) return { appended: 0, dropped };
|
|
366
|
-
let rawEvents;
|
|
367
|
-
try {
|
|
368
|
-
rawEvents = await readFile(eventsJsonlPath, "utf8");
|
|
369
|
-
} catch {
|
|
370
|
-
rawEvents = "";
|
|
371
|
-
}
|
|
372
|
-
const eventRows = [];
|
|
373
|
-
const unparseablePassthrough = [];
|
|
374
|
-
for (const line of rawEvents.split("\n")) {
|
|
375
|
-
if (line.length === 0) continue;
|
|
376
|
-
let parsed;
|
|
377
|
-
try {
|
|
378
|
-
parsed = JSON.parse(line);
|
|
379
|
-
} catch {
|
|
380
|
-
unparseablePassthrough.push(line);
|
|
381
|
-
continue;
|
|
382
|
-
}
|
|
383
|
-
const result = eventSchema.safeParse(parsed);
|
|
384
|
-
if (result.success) {
|
|
385
|
-
eventRows.push(redactEvent(result.data));
|
|
386
|
-
} else {
|
|
387
|
-
unparseablePassthrough.push(line);
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
const merged = resolveTwinHttpParents(eventRows.concat(signalRows));
|
|
391
|
-
merged.sort((a, b) => a.ts < b.ts ? -1 : a.ts > b.ts ? 1 : 0);
|
|
392
|
-
const sortedJsonl = merged.map((r) => JSON.stringify(r)).join("\n");
|
|
393
|
-
const head = unparseablePassthrough.length > 0 ? unparseablePassthrough.join("\n") + "\n" : "";
|
|
394
|
-
await writeFile(eventsJsonlPath, head + sortedJsonl + "\n");
|
|
395
|
-
return { appended: signalRows.length, dropped };
|
|
396
|
-
}
|
|
397
327
|
|
|
398
328
|
// src/runner/runTaskCore.ts
|
|
399
329
|
async function writeRunNoScore(input) {
|
|
@@ -428,9 +358,6 @@ async function runTask(options) {
|
|
|
428
358
|
const writeRun = writeRunNoScore;
|
|
429
359
|
const runDir = join(artifactsDir, scenario.slug, runId);
|
|
430
360
|
await mkdir(runDir, { recursive: true });
|
|
431
|
-
const signalsPath = join(runDir, "signals.jsonl");
|
|
432
|
-
await writeFile(signalsPath, "");
|
|
433
|
-
const signalsPathForEnv = sep === "\\" ? signalsPath.replace(/\\/g, "/") : signalsPath;
|
|
434
361
|
const eventsJsonlPath = join(runDir, "events.jsonl");
|
|
435
362
|
await writeFile(eventsJsonlPath, "");
|
|
436
363
|
const egressAllowHosts = buildEgressAllowlist(process.env, {
|
|
@@ -525,7 +452,6 @@ async function runTask(options) {
|
|
|
525
452
|
POME_AUTH_TOKEN: token,
|
|
526
453
|
POME_RUN_ID: runId,
|
|
527
454
|
POME_ARTIFACTS_DIR: runDir,
|
|
528
|
-
POME_ADAPTER_SIGNALS_PATH: signalsPathForEnv,
|
|
529
455
|
...options.extraAgentEnv ?? {},
|
|
530
456
|
...proxyEnv
|
|
531
457
|
};
|
|
@@ -575,7 +501,6 @@ async function runTask(options) {
|
|
|
575
501
|
stateInitial,
|
|
576
502
|
stateFinal: stateFinal2
|
|
577
503
|
});
|
|
578
|
-
await mergeAdapterSignalsIntoEvents(signalsPath, eventsJsonlPath);
|
|
579
504
|
void exitCode2;
|
|
580
505
|
const blockedEgress2 = await collectBlockedEgress();
|
|
581
506
|
return { scenario, runId, artifacts: artifacts2, agent: preflight, exitCode: 3, blockedEgress: blockedEgress2 };
|
|
@@ -601,7 +526,6 @@ async function runTask(options) {
|
|
|
601
526
|
stateInitial,
|
|
602
527
|
stateFinal
|
|
603
528
|
});
|
|
604
|
-
await mergeAdapterSignalsIntoEvents(signalsPath, eventsJsonlPath);
|
|
605
529
|
const blockedEgress = await collectBlockedEgress();
|
|
606
530
|
return { scenario, runId, artifacts, agent, exitCode, blockedEgress };
|
|
607
531
|
} finally {
|
|
@@ -1187,7 +1111,7 @@ function extractJsonPayload(text) {
|
|
|
1187
1111
|
|
|
1188
1112
|
// src/task/seed-verifier.ts
|
|
1189
1113
|
async function verifySeedWithTwin(seed) {
|
|
1190
|
-
const { GitHubDomain, openGitHubCloneDatabase } = await import('../../src-
|
|
1114
|
+
const { GitHubDomain, openGitHubCloneDatabase } = await import('../../src-252X4AEZ.js');
|
|
1191
1115
|
const db = openGitHubCloneDatabase(":memory:");
|
|
1192
1116
|
try {
|
|
1193
1117
|
new GitHubDomain(db).seed(seed);
|
|
@@ -4093,13 +4017,13 @@ function validateJsonl(name, raw) {
|
|
|
4093
4017
|
`pome eval: ${name} is corrupt \u2014 line ${i + 1} is not valid JSON.`
|
|
4094
4018
|
);
|
|
4095
4019
|
}
|
|
4096
|
-
if (
|
|
4020
|
+
if (isLegacyEventRow(parsed)) {
|
|
4097
4021
|
throw new HostedUsageError(
|
|
4098
4022
|
`pome eval: events.jsonl line ${i + 1} has no "kind" \u2014 it was recorded before the unified event shape, and the control plane refuses it. Re-run the task to record the trace again.`
|
|
4099
4023
|
);
|
|
4100
4024
|
}
|
|
4101
4025
|
}
|
|
4102
|
-
if (
|
|
4026
|
+
if (nonEmpty === 0) {
|
|
4103
4027
|
throw new HostedUsageError(
|
|
4104
4028
|
"pome eval: events.jsonl is empty \u2014 the run captured no trace to evaluate."
|
|
4105
4029
|
);
|
|
@@ -4120,24 +4044,12 @@ async function readRunDirArtifacts(runDir) {
|
|
|
4120
4044
|
parseJsonFile("state_initial.json", stateInitialJson);
|
|
4121
4045
|
const stateFinalJson = await readRequiredFile(runDir, "state_final.json");
|
|
4122
4046
|
parseJsonFile("state_final.json", stateFinalJson);
|
|
4123
|
-
let signalsJsonl = null;
|
|
4124
|
-
try {
|
|
4125
|
-
signalsJsonl = await readFile(join(runDir, "signals.jsonl"), "utf8");
|
|
4126
|
-
} catch (err) {
|
|
4127
|
-
if (err.code !== "ENOENT") {
|
|
4128
|
-
throw new HostedUsageError(
|
|
4129
|
-
`pome eval: signals.jsonl could not be read: ${err instanceof Error ? err.message : String(err)}`
|
|
4130
|
-
);
|
|
4131
|
-
}
|
|
4132
|
-
}
|
|
4133
|
-
if (signalsJsonl !== null) validateJsonl("signals.jsonl", signalsJsonl);
|
|
4134
4047
|
return {
|
|
4135
4048
|
runDir,
|
|
4136
4049
|
meta,
|
|
4137
4050
|
eventsJsonl,
|
|
4138
4051
|
stateInitialJson,
|
|
4139
4052
|
stateFinalJson,
|
|
4140
|
-
signalsJsonl,
|
|
4141
4053
|
metaJson: metaRaw
|
|
4142
4054
|
};
|
|
4143
4055
|
}
|
|
@@ -4239,7 +4151,6 @@ async function runEval(options) {
|
|
|
4239
4151
|
stateFinalJson: JSON.stringify(
|
|
4240
4152
|
redactSecrets(JSON.parse(artifacts.stateFinalJson))
|
|
4241
4153
|
),
|
|
4242
|
-
signalsJsonl: redactJsonl(artifacts.signalsJsonl ?? ""),
|
|
4243
4154
|
// D18.1 — already validated as parseable JSON in readRunDirArtifacts.
|
|
4244
4155
|
// Re-serialize with the SAME formatting writeRunArtifactsCore's writeJson
|
|
4245
4156
|
// uses (2-space indent + trailing newline) so the bytes `pome eval`
|
|
@@ -4284,8 +4195,7 @@ async function runEval(options) {
|
|
|
4284
4195
|
expectedBehavior: "",
|
|
4285
4196
|
traceStorageKey: keys.eventsKey ?? void 0,
|
|
4286
4197
|
stateInitialStorageKey: keys.stateInitialKey ?? void 0,
|
|
4287
|
-
stateFinalStorageKey: keys.stateFinalKey ?? void 0
|
|
4288
|
-
signalsStorageKey: keys.signalsKey ?? void 0
|
|
4198
|
+
stateFinalStorageKey: keys.stateFinalKey ?? void 0
|
|
4289
4199
|
});
|
|
4290
4200
|
}
|
|
4291
4201
|
let finalized;
|
|
@@ -4961,7 +4871,7 @@ function firstSentence(description) {
|
|
|
4961
4871
|
function resolveExampleRef(env = process.env) {
|
|
4962
4872
|
const override = env.POME_EXAMPLE_REF?.trim();
|
|
4963
4873
|
if (override) return override;
|
|
4964
|
-
const baked = "
|
|
4874
|
+
const baked = "a80259dcddd5ec6f1a16dba3a6f252539996ebb7".trim() ;
|
|
4965
4875
|
return FULL_SHA.test(baked) ? baked : "main";
|
|
4966
4876
|
}
|
|
4967
4877
|
function rawUrlFor(example, file, ref) {
|
|
@@ -5324,7 +5234,7 @@ var DEFAULT_AGENT_COMMAND = `node ${DEFAULT_AGENT_FILE}`;
|
|
|
5324
5234
|
var MANIFEST_SCHEMA_URL = "https://pome.sh/schemas/v1/pome.json";
|
|
5325
5235
|
var MAX_UNREADABLE_PATHS_SHOWN = 5;
|
|
5326
5236
|
function readPackageVersion() {
|
|
5327
|
-
if ("0.
|
|
5237
|
+
if ("0.44.0".length > 0) return "0.44.0";
|
|
5328
5238
|
try {
|
|
5329
5239
|
const here = dirname(fileURLToPath(import.meta.url));
|
|
5330
5240
|
const candidates = [
|
|
@@ -5728,7 +5638,7 @@ function createProgram() {
|
|
|
5728
5638
|
return;
|
|
5729
5639
|
}
|
|
5730
5640
|
{
|
|
5731
|
-
const { runDoctorChecks } = await import('../../checks-
|
|
5641
|
+
const { runDoctorChecks } = await import('../../checks-BOOQNOGJ.js');
|
|
5732
5642
|
const { renderDoctorReport } = await import('../../render-ZQQ4UMNO.js');
|
|
5733
5643
|
const doctorReport = await runDoctorChecks({ mode: useLocal ? "full" : "hosted" });
|
|
5734
5644
|
if (!doctorReport.ok) {
|
|
@@ -5766,7 +5676,7 @@ function createProgram() {
|
|
|
5766
5676
|
taskForRuns.config.runs
|
|
5767
5677
|
);
|
|
5768
5678
|
if (k > 1) {
|
|
5769
|
-
const { runTrialGroup } = await import('../../runTrialGroup-
|
|
5679
|
+
const { runTrialGroup } = await import('../../runTrialGroup-I3PC2AST.js');
|
|
5770
5680
|
const fileForRerun = relative(process.cwd(), file);
|
|
5771
5681
|
const rerunCommand = defaultTask ? options.trials !== void 0 ? `pome run -n ${k}` : "pome run" : `pome run ${fileForRerun && !fileForRerun.startsWith("..") ? fileForRerun : file} -n ${k}`;
|
|
5772
5682
|
const groupResult = await runTrialGroup({
|
|
@@ -5848,7 +5758,7 @@ function createProgram() {
|
|
|
5848
5758
|
program.command("doctor").summary("Check the agent and twin wiring").description(
|
|
5849
5759
|
"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."
|
|
5850
5760
|
).action(async () => {
|
|
5851
|
-
const { runDoctorChecks } = await import('../../checks-
|
|
5761
|
+
const { runDoctorChecks } = await import('../../checks-BOOQNOGJ.js');
|
|
5852
5762
|
const { renderDoctorReport } = await import('../../render-ZQQ4UMNO.js');
|
|
5853
5763
|
const report = await runDoctorChecks();
|
|
5854
5764
|
for (const line of renderDoctorReport(report, { passNote: true })) console.error(line);
|
|
@@ -5999,64 +5909,85 @@ function createProgram() {
|
|
|
5999
5909
|
})
|
|
6000
5910
|
);
|
|
6001
5911
|
});
|
|
6002
|
-
const twin = program.command("twin").summary("Run a twin on this machine").description(
|
|
5912
|
+
const twin = program.command("twin").summary("Run a twin on this machine").description(
|
|
5913
|
+
"Start a twin on this machine, print its status, show its tape, or write a starter seed file"
|
|
5914
|
+
);
|
|
6003
5915
|
twin.command("start").argument(
|
|
6004
|
-
"[
|
|
6005
|
-
`Twin
|
|
5916
|
+
"[names...]",
|
|
5917
|
+
`Twin names (${TWIN_NAME_LIST.join(" | ")}). One, or several to boot together (each on its own port). Optional when --seed names exactly one twin.`
|
|
6006
5918
|
).option(
|
|
6007
5919
|
"--port <port>",
|
|
6008
5920
|
// Built from the registry rather than restated: the per-twin overrides
|
|
6009
5921
|
// are the registry's to add, and this text went stale when linear's did.
|
|
6010
5922
|
`Port to bind (default: $PORT, else ${TWIN_NAME_LIST.filter(
|
|
6011
5923
|
(twin2) => TWIN_REGISTRY[twin2].portEnvName
|
|
6012
|
-
).map((twin2) => `${TWIN_REGISTRY[twin2].portEnvName}/${TWIN_REGISTRY[twin2].defaultPort} for ${twin2}`).join(", ")}, otherwise 3333)
|
|
5924
|
+
).map((twin2) => `${TWIN_REGISTRY[twin2].portEnvName}/${TWIN_REGISTRY[twin2].defaultPort} for ${twin2}`).join(", ")}, otherwise 3333). With several twins: the first twin's port; the rest take the next free ports above it. Without it, each twin takes its default port, else the next free one.`
|
|
6013
5925
|
).option(
|
|
6014
5926
|
"--seed <path>",
|
|
6015
|
-
"Boot
|
|
5927
|
+
"Boot from a JSON or YAML seed file instead of the default. A seed REPLACES the default; it does not merge. Takes the per-twin envelope { <twin>: { \u2026 } } or one twin's flat seed (several twins need the envelope, one entry per named twin). Overrides POME_SEED_JSON."
|
|
6016
5928
|
).description(
|
|
6017
|
-
"Start
|
|
6018
|
-
).action(async (
|
|
6019
|
-
const { runTwinStartCommand } = await import('../../twinStart-
|
|
6020
|
-
await runTwinStartCommand(
|
|
5929
|
+
"Start one or more standalone twins as a long-lived foreground server (Ctrl-C to stop)"
|
|
5930
|
+
).action(async (names, options) => {
|
|
5931
|
+
const { runTwinStartCommand } = await import('../../twinStart-E5R26SF4.js');
|
|
5932
|
+
await runTwinStartCommand(names, options);
|
|
6021
5933
|
});
|
|
6022
5934
|
twin.command("new-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.").summary("Print a new starter seed file for a twin").description(
|
|
6023
5935
|
"Print a new starter seed file for a twin, generated from the twin's own starting state. One twin is flat, several are the per-twin envelope. Boot it with `twin start <twin> --seed`, seed a sandbox with `sandbox create --twin <twin> --seed`, or drop it beside a task as <task>.seed.json"
|
|
6024
5936
|
).action(async (names, options) => {
|
|
6025
|
-
const { runTwinSeedCommand } = await import('../../twinSeed-
|
|
5937
|
+
const { runTwinSeedCommand } = await import('../../twinSeed-ADWQ62CA.js');
|
|
6026
5938
|
await runTwinSeedCommand(names, options);
|
|
6027
5939
|
});
|
|
6028
|
-
twin.command("status").summary("Say whether the local
|
|
6029
|
-
"Say whether
|
|
5940
|
+
twin.command("status").summary("Say whether the local twins are running").description(
|
|
5941
|
+
"Say whether each twin `pome twin start` booted here is still running, and print its paste-able env lines"
|
|
6030
5942
|
).action(async () => {
|
|
6031
5943
|
const statusPath = ".pome/twin-status.json";
|
|
6032
5944
|
if (!existsSync(statusPath)) {
|
|
6033
5945
|
console.log("No standalone twin status found.");
|
|
6034
5946
|
return;
|
|
6035
5947
|
}
|
|
6036
|
-
|
|
6037
|
-
let
|
|
5948
|
+
const { standaloneStatusEntries } = await import('../../twinStart-E5R26SF4.js');
|
|
5949
|
+
let entries;
|
|
6038
5950
|
try {
|
|
6039
|
-
|
|
6040
|
-
|
|
6041
|
-
|
|
5951
|
+
entries = standaloneStatusEntries(JSON.parse(await readFile(statusPath, "utf8"))).map(
|
|
5952
|
+
(status) => ({ ...status, origin: new URL(status.rest_url).origin })
|
|
5953
|
+
);
|
|
5954
|
+
if (entries.length === 0 || entries.some((status) => status.name === "")) {
|
|
5955
|
+
throw new Error("no twins");
|
|
5956
|
+
}
|
|
6042
5957
|
} catch {
|
|
6043
5958
|
throw new Error(
|
|
6044
5959
|
`pome twin status: ${statusPath} is unreadable \u2014 start a twin with \`pome twin start <${TWIN_NAME_LIST.join("|")}>\`.`
|
|
6045
5960
|
);
|
|
6046
5961
|
}
|
|
6047
|
-
const
|
|
6048
|
-
|
|
6049
|
-
|
|
6050
|
-
|
|
6051
|
-
|
|
6052
|
-
|
|
6053
|
-
|
|
6054
|
-
|
|
6055
|
-
|
|
6056
|
-
|
|
6057
|
-
|
|
6058
|
-
|
|
6059
|
-
|
|
5962
|
+
for (const [index, status] of entries.entries()) {
|
|
5963
|
+
const running = await fetch(`${status.origin}/healthz`, {
|
|
5964
|
+
signal: AbortSignal.timeout(1e3)
|
|
5965
|
+
}).then(
|
|
5966
|
+
async (res) => res.ok && (await res.json().catch(() => ({}))).twin === status.name,
|
|
5967
|
+
() => false
|
|
5968
|
+
);
|
|
5969
|
+
if (index > 0) console.log("");
|
|
5970
|
+
console.log(
|
|
5971
|
+
running ? `${status.name} twin \u2014 running` : `${status.name} twin \u2014 not running (stale ${statusPath})`
|
|
5972
|
+
);
|
|
5973
|
+
const envName = TWIN_REGISTRY[status.name]?.envName ?? status.name.toUpperCase();
|
|
5974
|
+
console.log(`POME_${envName}_REST_URL=${status.rest_url}`);
|
|
5975
|
+
console.log(`POME_${envName}_MCP_URL=${status.mcp_url}`);
|
|
5976
|
+
console.log(`POME_AUTH_TOKEN=${status.auth_token}`);
|
|
5977
|
+
}
|
|
5978
|
+
});
|
|
5979
|
+
twin.command("tape").argument(
|
|
5980
|
+
"[name]",
|
|
5981
|
+
`Twin name (${TWIN_NAME_LIST.join(" | ")}). Optional when one twin is recorded in .pome/twin-status.json.`
|
|
5982
|
+
).option(
|
|
5983
|
+
"--diff",
|
|
5984
|
+
"Also print the state diff since the twin booted \u2014 its seed, default or --seed \u2014 per collection: added, changed, removed.",
|
|
5985
|
+
false
|
|
5986
|
+
).option("--json", "Print the tape (and the diff, with --diff) as one JSON envelope.", false).summary("Show what the agent did on a local twin").description(
|
|
5987
|
+
"Print the running twin's tape: one line per request with status, fidelity and whether state changed, so a call that claimed success but landed nothing stands out. Reads the twin's address and token from .pome/twin-status.json; no account, no hosted call."
|
|
5988
|
+
).action(async (name, options) => {
|
|
5989
|
+
const { runTwinTapeCommand } = await import('../../twinTape-3XNU3GRW.js');
|
|
5990
|
+
await runTwinTapeCommand(name, options);
|
|
6060
5991
|
});
|
|
6061
5992
|
program.command("capture-server").summary("Record the agent's model calls").description(
|
|
6062
5993
|
"Boot an HTTP CONNECT-tunnel proxy that appends one LlmCallEvent per tunnel to events.jsonl. Spawned by `pome run`; agent traffic flows via HTTPS_PROXY."
|
|
@@ -3,7 +3,7 @@ import { defaultSeedState, parseSeed } from './chunk-NBOQN5VX.js';
|
|
|
3
3
|
export { defaultSeedState, parseSeed, seedSchema } from './chunk-NBOQN5VX.js';
|
|
4
4
|
import { routeInputDeclarer, integerInput, mountDeclaredRoute, UndeclaredInputError, MalformedBodyError } from './chunk-IZFM7W2V.js';
|
|
5
5
|
import { loadMcpToolFixture, defineTwin, twinBuildInfo, deriveMcpToolTable, UnknownToolError, openTwinDatabase, createApp, typeDisagreements } from './chunk-TWURH7YM.js';
|
|
6
|
-
import './chunk-
|
|
6
|
+
import './chunk-7VZBAHQ2.js';
|
|
7
7
|
import './chunk-SG6ZTIMT.js';
|
|
8
8
|
import './chunk-FBSA5L36.js';
|
|
9
9
|
import { z, ZodError } from 'zod';
|
|
@@ -4,7 +4,7 @@ export { DEFAULT_GMAIL_AGENT_EMAIL, GmailError, SEARCH_MAILBOX_MESSAGE_BUDGET, a
|
|
|
4
4
|
import './chunk-JWJYNAWI.js';
|
|
5
5
|
import { routeInputDeclarer, integerInput, booleanInput, repeatedInput, mountDeclaredRoute, UndeclaredInputError, MalformedBodyError } from './chunk-IZFM7W2V.js';
|
|
6
6
|
import { loadMcpToolFixture, deriveMcpToolTable, defineTwin, openTwinDatabase, createApp } from './chunk-TWURH7YM.js';
|
|
7
|
-
import './chunk-
|
|
7
|
+
import './chunk-7VZBAHQ2.js';
|
|
8
8
|
import './chunk-SG6ZTIMT.js';
|
|
9
9
|
import './chunk-FBSA5L36.js';
|
|
10
10
|
import { createHash, createHmac, timingSafeEqual, randomBytes } from 'node:crypto';
|
|
@@ -4,7 +4,7 @@ export { DEFAULT_LINEAR_CLOCK, DEFAULT_LINEAR_EMAIL, DEFAULT_LINEAR_PORT, DEFAUL
|
|
|
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-TWURH7YM.js';
|
|
7
|
-
import './chunk-
|
|
7
|
+
import './chunk-7VZBAHQ2.js';
|
|
8
8
|
import './chunk-SG6ZTIMT.js';
|
|
9
9
|
import './chunk-FBSA5L36.js';
|
|
10
10
|
import { createHmac, timingSafeEqual, createHash, randomBytes } from 'node:crypto';
|
|
@@ -4,7 +4,7 @@ import { defaultSeedState, parseSeed } from './chunk-YBWG5JK2.js';
|
|
|
4
4
|
export { defaultSeedState, loadSeedFromEnv, parseSeed, seedSchema } from './chunk-YBWG5JK2.js';
|
|
5
5
|
import { routeInputDeclarer, booleanInput, integerInput, mountDeclaredRoute, UndeclaredInputError } from './chunk-IZFM7W2V.js';
|
|
6
6
|
import { loadMcpToolFixture, defineTwin, queryTokenResolver, formTokenResolver, deriveMcpToolTable, UnknownToolError, openTwinDatabase, createApp, typeDisagreements } from './chunk-TWURH7YM.js';
|
|
7
|
-
import './chunk-
|
|
7
|
+
import './chunk-7VZBAHQ2.js';
|
|
8
8
|
import './chunk-SG6ZTIMT.js';
|
|
9
9
|
import './chunk-FBSA5L36.js';
|
|
10
10
|
import { z, ZodError } from 'zod';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { routeInputDeclarer, bracketedQuery, integerInput, booleanInput, mountDeclaredRoute, UndeclaredInputError } from './chunk-IZFM7W2V.js';
|
|
2
2
|
import { loadMcpToolFixture, openTwinDatabase, defineTwin, twinBuildInfo, deriveMcpToolTable, failureInjectionMiddleware, createApp, recordedRequestHeaders, UnknownToolError } from './chunk-TWURH7YM.js';
|
|
3
|
-
import './chunk-
|
|
3
|
+
import './chunk-7VZBAHQ2.js';
|
|
4
4
|
import './chunk-SG6ZTIMT.js';
|
|
5
5
|
import { defaultSeed, seedSchema } from './chunk-2K6BJ3PI.js';
|
|
6
6
|
export { DEFAULT_API_KEY, DEFAULT_SID, defaultSeed, loadSeedFromEnv, parseSeed, seedSchema } from './chunk-2K6BJ3PI.js';
|