@pome-sh/cli 0.43.1 → 0.45.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 +1 -1
- package/dist/build-info.json +3 -3
- package/dist/{checks-V442KL5O.js → checks-RDU56OGI.js} +4 -3
- package/dist/chunk-26UAPLHK.js +191 -0
- package/dist/chunk-4LQ4IJOC.js +1 -0
- package/dist/{chunk-5KFDRR53.js → chunk-7VZBAHQ2.js} +2 -2
- package/dist/chunk-AGZOWSLG.js +142 -0
- package/dist/{chunk-4DXTT3RV.js → chunk-BXYPNEJY.js} +7 -7
- package/dist/{chunk-GQSNU3YP.js → chunk-DX2KCFJM.js} +1 -1
- package/dist/{chunk-64AWQJ7R.js → chunk-EZYVICDB.js} +1 -1
- package/dist/{chunk-A6AM6KS4.js → chunk-HEEFOMSZ.js} +11 -70
- package/dist/{chunk-CS7O2ZXB.js → chunk-M7ATJ423.js} +5 -190
- package/dist/{runTrialGroup-HYGGBLMM.js → runTrialGroup-MMTTTDWY.js} +7 -5
- package/dist/{server-2WHSHTUD.js → server-GECKG2H6.js} +1 -1
- package/dist/src/cli/main.js +246 -174
- package/dist/{src-G6CMFUR6.js → src-46YGR2WY.js} +1 -7
- 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-STAXYPD3.js} +18 -2
- package/dist/twinHarness-I2JGKQYD.js +6 -0
- package/dist/{twinSeed-J7UAY3GM.js → twinSeed-ZFZO7BL7.js} +1 -1
- package/dist/twinStart-XN3BYOUF.js +422 -0
- package/dist/twinTape-5P3HQ27N.js +418 -0
- package/examples/agents/mcp-loop-agent.ts +0 -6
- package/package.json +30 -24
- package/dist/twinHarness-33MAVAXV.js +0 -6
- package/dist/twinStart-3Q74IURZ.js +0 -187
package/dist/src/cli/main.js
CHANGED
|
@@ -1,30 +1,32 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
import '../../chunk-
|
|
2
|
+
import { getAvailablePort } from '../../chunk-XDU6TD4O.js';
|
|
3
|
+
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-HEEFOMSZ.js';
|
|
4
|
+
import '../../chunk-4LQ4IJOC.js';
|
|
5
|
+
import { readManifest, writeManifest, MANIFEST_JSON, exitCodeFor, readRequiredManifest, HostedUsageError, HostedOrchError, normalizeManifestTwins } from '../../chunk-26UAPLHK.js';
|
|
6
|
+
import { MOUNTED_TWINS, deriveAgentSlug } from '../../chunk-M7ATJ423.js';
|
|
4
7
|
import '../../chunk-NW7HGA2K.js';
|
|
5
8
|
import { GMAIL_CHECKS } from '../../chunk-JM6VS62R.js';
|
|
6
9
|
import '../../chunk-PASFBRK4.js';
|
|
7
10
|
import { LINEAR_CHECKS } from '../../chunk-TSOSDKXP.js';
|
|
8
11
|
import '../../chunk-3FZY376K.js';
|
|
9
|
-
import { createRecorder, bootTwin } from '../../chunk-64AWQJ7R.js';
|
|
10
|
-
import { TWIN_NAME_LIST, TWIN_REGISTRY, createGitHubSmokeApp } from '../../chunk-4DXTT3RV.js';
|
|
11
|
-
import { getAvailablePort } from '../../chunk-XDU6TD4O.js';
|
|
12
|
-
import { MOUNTED_TWINS, readManifest, deriveAgentSlug, writeManifest, MANIFEST_JSON, exitCodeFor, readRequiredManifest, HostedUsageError, HostedOrchError, normalizeManifestTwins } from '../../chunk-CS7O2ZXB.js';
|
|
13
12
|
import { buildEgressAllowlist, readBlockedEgress } from '../../chunk-CBFKZZBR.js';
|
|
13
|
+
import '../../chunk-DX2KCFJM.js';
|
|
14
|
+
import { createRecorder, bootTwin } from '../../chunk-EZYVICDB.js';
|
|
15
|
+
import { TWIN_NAME_LIST, TWIN_REGISTRY, createGitHubSmokeApp } from '../../chunk-BXYPNEJY.js';
|
|
14
16
|
import { TAPE_ASSERTABLE_TOOLS } from '../../chunk-C4BVTUA3.js';
|
|
15
17
|
import { seedSchema } from '../../chunk-NBOQN5VX.js';
|
|
16
18
|
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
|
-
import {
|
|
27
|
-
import { dirname, resolve, join, basename, relative,
|
|
28
|
+
import { readFile, mkdir, writeFile, readdir, copyFile, stat, open, unlink, chmod, cp } from 'node:fs/promises';
|
|
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';
|
|
@@ -35,6 +37,7 @@ import { createInterface } from 'node:readline';
|
|
|
35
37
|
import { z } from 'zod';
|
|
36
38
|
import Anthropic from '@anthropic-ai/sdk';
|
|
37
39
|
import { createRequire } from 'node:module';
|
|
40
|
+
import { homedir } from 'node:os';
|
|
38
41
|
|
|
39
42
|
async function readEventsJsonl(runDir) {
|
|
40
43
|
const file = resolve(runDir, "events.jsonl");
|
|
@@ -322,78 +325,6 @@ function makeShutdown(child, graceMs) {
|
|
|
322
325
|
return done;
|
|
323
326
|
};
|
|
324
327
|
}
|
|
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
328
|
|
|
398
329
|
// src/runner/runTaskCore.ts
|
|
399
330
|
async function writeRunNoScore(input) {
|
|
@@ -428,9 +359,6 @@ async function runTask(options) {
|
|
|
428
359
|
const writeRun = writeRunNoScore;
|
|
429
360
|
const runDir = join(artifactsDir, scenario.slug, runId);
|
|
430
361
|
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
362
|
const eventsJsonlPath = join(runDir, "events.jsonl");
|
|
435
363
|
await writeFile(eventsJsonlPath, "");
|
|
436
364
|
const egressAllowHosts = buildEgressAllowlist(process.env, {
|
|
@@ -525,7 +453,6 @@ async function runTask(options) {
|
|
|
525
453
|
POME_AUTH_TOKEN: token,
|
|
526
454
|
POME_RUN_ID: runId,
|
|
527
455
|
POME_ARTIFACTS_DIR: runDir,
|
|
528
|
-
POME_ADAPTER_SIGNALS_PATH: signalsPathForEnv,
|
|
529
456
|
...options.extraAgentEnv ?? {},
|
|
530
457
|
...proxyEnv
|
|
531
458
|
};
|
|
@@ -575,7 +502,6 @@ async function runTask(options) {
|
|
|
575
502
|
stateInitial,
|
|
576
503
|
stateFinal: stateFinal2
|
|
577
504
|
});
|
|
578
|
-
await mergeAdapterSignalsIntoEvents(signalsPath, eventsJsonlPath);
|
|
579
505
|
void exitCode2;
|
|
580
506
|
const blockedEgress2 = await collectBlockedEgress();
|
|
581
507
|
return { scenario, runId, artifacts: artifacts2, agent: preflight, exitCode: 3, blockedEgress: blockedEgress2 };
|
|
@@ -601,7 +527,6 @@ async function runTask(options) {
|
|
|
601
527
|
stateInitial,
|
|
602
528
|
stateFinal
|
|
603
529
|
});
|
|
604
|
-
await mergeAdapterSignalsIntoEvents(signalsPath, eventsJsonlPath);
|
|
605
530
|
const blockedEgress = await collectBlockedEgress();
|
|
606
531
|
return { scenario, runId, artifacts, agent, exitCode, blockedEgress };
|
|
607
532
|
} finally {
|
|
@@ -1187,7 +1112,7 @@ function extractJsonPayload(text) {
|
|
|
1187
1112
|
|
|
1188
1113
|
// src/task/seed-verifier.ts
|
|
1189
1114
|
async function verifySeedWithTwin(seed) {
|
|
1190
|
-
const { GitHubDomain, openGitHubCloneDatabase } = await import('../../src-
|
|
1115
|
+
const { GitHubDomain, openGitHubCloneDatabase } = await import('../../src-46YGR2WY.js');
|
|
1191
1116
|
const db = openGitHubCloneDatabase(":memory:");
|
|
1192
1117
|
try {
|
|
1193
1118
|
new GitHubDomain(db).seed(seed);
|
|
@@ -3395,7 +3320,7 @@ function localDigest(twin) {
|
|
|
3395
3320
|
}
|
|
3396
3321
|
function bakedVersions() {
|
|
3397
3322
|
try {
|
|
3398
|
-
return JSON.parse('{"@pome-sh/sdk":"0.11.6","@pome-sh/wire":"0.4.
|
|
3323
|
+
return JSON.parse('{"@pome-sh/sdk":"0.11.6","@pome-sh/wire":"0.4.3","@pome-sh/twin-github":"0.12.0","@pome-sh/twin-gmail":"0.4.0","@pome-sh/twin-linear":"0.4.1","@pome-sh/twin-slack":"0.4.1","@pome-sh/twin-stripe":"0.4.7"}');
|
|
3399
3324
|
} catch {
|
|
3400
3325
|
return {};
|
|
3401
3326
|
}
|
|
@@ -4093,13 +4018,13 @@ function validateJsonl(name, raw) {
|
|
|
4093
4018
|
`pome eval: ${name} is corrupt \u2014 line ${i + 1} is not valid JSON.`
|
|
4094
4019
|
);
|
|
4095
4020
|
}
|
|
4096
|
-
if (
|
|
4021
|
+
if (isLegacyEventRow(parsed)) {
|
|
4097
4022
|
throw new HostedUsageError(
|
|
4098
4023
|
`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
4024
|
);
|
|
4100
4025
|
}
|
|
4101
4026
|
}
|
|
4102
|
-
if (
|
|
4027
|
+
if (nonEmpty === 0) {
|
|
4103
4028
|
throw new HostedUsageError(
|
|
4104
4029
|
"pome eval: events.jsonl is empty \u2014 the run captured no trace to evaluate."
|
|
4105
4030
|
);
|
|
@@ -4120,24 +4045,12 @@ async function readRunDirArtifacts(runDir) {
|
|
|
4120
4045
|
parseJsonFile("state_initial.json", stateInitialJson);
|
|
4121
4046
|
const stateFinalJson = await readRequiredFile(runDir, "state_final.json");
|
|
4122
4047
|
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
4048
|
return {
|
|
4135
4049
|
runDir,
|
|
4136
4050
|
meta,
|
|
4137
4051
|
eventsJsonl,
|
|
4138
4052
|
stateInitialJson,
|
|
4139
4053
|
stateFinalJson,
|
|
4140
|
-
signalsJsonl,
|
|
4141
4054
|
metaJson: metaRaw
|
|
4142
4055
|
};
|
|
4143
4056
|
}
|
|
@@ -4239,7 +4152,6 @@ async function runEval(options) {
|
|
|
4239
4152
|
stateFinalJson: JSON.stringify(
|
|
4240
4153
|
redactSecrets(JSON.parse(artifacts.stateFinalJson))
|
|
4241
4154
|
),
|
|
4242
|
-
signalsJsonl: redactJsonl(artifacts.signalsJsonl ?? ""),
|
|
4243
4155
|
// D18.1 — already validated as parseable JSON in readRunDirArtifacts.
|
|
4244
4156
|
// Re-serialize with the SAME formatting writeRunArtifactsCore's writeJson
|
|
4245
4157
|
// uses (2-space indent + trailing newline) so the bytes `pome eval`
|
|
@@ -4284,8 +4196,7 @@ async function runEval(options) {
|
|
|
4284
4196
|
expectedBehavior: "",
|
|
4285
4197
|
traceStorageKey: keys.eventsKey ?? void 0,
|
|
4286
4198
|
stateInitialStorageKey: keys.stateInitialKey ?? void 0,
|
|
4287
|
-
stateFinalStorageKey: keys.stateFinalKey ?? void 0
|
|
4288
|
-
signalsStorageKey: keys.signalsKey ?? void 0
|
|
4199
|
+
stateFinalStorageKey: keys.stateFinalKey ?? void 0
|
|
4289
4200
|
});
|
|
4290
4201
|
}
|
|
4291
4202
|
let finalized;
|
|
@@ -4961,7 +4872,7 @@ function firstSentence(description) {
|
|
|
4961
4872
|
function resolveExampleRef(env = process.env) {
|
|
4962
4873
|
const override = env.POME_EXAMPLE_REF?.trim();
|
|
4963
4874
|
if (override) return override;
|
|
4964
|
-
const baked = "
|
|
4875
|
+
const baked = "16bd8bf4255ab4a22c0d466529abcab652301773".trim() ;
|
|
4965
4876
|
return FULL_SHA.test(baked) ? baked : "main";
|
|
4966
4877
|
}
|
|
4967
4878
|
function rawUrlFor(example, file, ref) {
|
|
@@ -5316,6 +5227,143 @@ async function loadTrialEvents(runDir) {
|
|
|
5316
5227
|
}
|
|
5317
5228
|
return events;
|
|
5318
5229
|
}
|
|
5230
|
+
var USAGE_EVENT = "cli_usage";
|
|
5231
|
+
var USAGE_DOCS_URL = "https://github.com/pome-sh/digital-twins#telemetry";
|
|
5232
|
+
var DEFAULT_HOST = "https://us.i.posthog.com";
|
|
5233
|
+
var REQUEST_TIMEOUT_MS = 1500;
|
|
5234
|
+
function bakedIn(name) {
|
|
5235
|
+
const value = name === "key" ? "" : "" ;
|
|
5236
|
+
return value !== void 0 && value.length > 0 ? value : void 0;
|
|
5237
|
+
}
|
|
5238
|
+
function telemetryDestination(env = process.env) {
|
|
5239
|
+
const key = env.POME_TELEMETRY_KEY || bakedIn("key");
|
|
5240
|
+
if (!key) return void 0;
|
|
5241
|
+
const host = (env.POME_TELEMETRY_HOST || bakedIn("host") || DEFAULT_HOST).replace(/\/+$/, "");
|
|
5242
|
+
return { key, host };
|
|
5243
|
+
}
|
|
5244
|
+
function telemetryOptOut(env = process.env) {
|
|
5245
|
+
const off = (value) => value !== void 0 && /^(0|false|off|no)$/i.test(value.trim());
|
|
5246
|
+
const set = (value) => value !== void 0 && value.trim() !== "" && value.trim() !== "0";
|
|
5247
|
+
if (off(env.POME_TELEMETRY)) return "POME_TELEMETRY";
|
|
5248
|
+
if (set(env.DO_NOT_TRACK)) return "DO_NOT_TRACK";
|
|
5249
|
+
if (set(env.CI)) return "CI";
|
|
5250
|
+
return void 0;
|
|
5251
|
+
}
|
|
5252
|
+
function usageStatePath() {
|
|
5253
|
+
return join(homedir(), ".pome", "telemetry.json");
|
|
5254
|
+
}
|
|
5255
|
+
function usageProperties(input) {
|
|
5256
|
+
const nodeVersion = input.nodeVersion ?? process.version;
|
|
5257
|
+
return {
|
|
5258
|
+
command: input.command,
|
|
5259
|
+
cli_version: input.version,
|
|
5260
|
+
os: input.platform ?? process.platform,
|
|
5261
|
+
node_major: Number(nodeVersion.replace(/^v/, "").split(".")[0]),
|
|
5262
|
+
// Anonymous events: no person profile is created or updated in PostHog.
|
|
5263
|
+
$process_person_profile: false
|
|
5264
|
+
};
|
|
5265
|
+
}
|
|
5266
|
+
function commandName(command) {
|
|
5267
|
+
const names = [];
|
|
5268
|
+
let current = command;
|
|
5269
|
+
while (current && current.parent) {
|
|
5270
|
+
names.unshift(current.name());
|
|
5271
|
+
current = current.parent;
|
|
5272
|
+
}
|
|
5273
|
+
return names.join(" ");
|
|
5274
|
+
}
|
|
5275
|
+
var FIRST_RUN_NOTICE = `pome sends one anonymous usage event per day (CLI version, OS, Node major, command name; no arguments, paths or repo names). Turn it off with POME_TELEMETRY=0. ${USAGE_DOCS_URL}`;
|
|
5276
|
+
async function readState(path) {
|
|
5277
|
+
try {
|
|
5278
|
+
const parsed = JSON.parse(await readFile(path, "utf8"));
|
|
5279
|
+
if (typeof parsed.id === "string" && parsed.id.length > 0) {
|
|
5280
|
+
return {
|
|
5281
|
+
id: parsed.id,
|
|
5282
|
+
...typeof parsed.last_sent === "string" ? { last_sent: parsed.last_sent } : {},
|
|
5283
|
+
...parsed.notice_shown === true ? { notice_shown: true } : {}
|
|
5284
|
+
};
|
|
5285
|
+
}
|
|
5286
|
+
} catch {
|
|
5287
|
+
}
|
|
5288
|
+
return { id: randomUUID() };
|
|
5289
|
+
}
|
|
5290
|
+
async function writeState(path, state) {
|
|
5291
|
+
await mkdir(dirname(path), { recursive: true, mode: 448 });
|
|
5292
|
+
await writeFile(path, `${JSON.stringify(state, null, 2)}
|
|
5293
|
+
`, { mode: 384 });
|
|
5294
|
+
await chmod(path, 384);
|
|
5295
|
+
}
|
|
5296
|
+
var STALE_LOCK_MS = 3e4;
|
|
5297
|
+
async function withStateLock(path, fn) {
|
|
5298
|
+
const lockPath = `${path}.lock`;
|
|
5299
|
+
await mkdir(dirname(path), { recursive: true, mode: 448 });
|
|
5300
|
+
try {
|
|
5301
|
+
const handle = await open(lockPath, "wx", 384);
|
|
5302
|
+
await handle.close();
|
|
5303
|
+
} catch (err) {
|
|
5304
|
+
if (err.code !== "EEXIST") throw err;
|
|
5305
|
+
const age = await stat(lockPath).then((s) => Date.now() - s.mtimeMs, () => 0);
|
|
5306
|
+
if (age <= STALE_LOCK_MS) return "locked";
|
|
5307
|
+
await unlink(lockPath).catch(() => void 0);
|
|
5308
|
+
try {
|
|
5309
|
+
const handle = await open(lockPath, "wx", 384);
|
|
5310
|
+
await handle.close();
|
|
5311
|
+
} catch {
|
|
5312
|
+
return "locked";
|
|
5313
|
+
}
|
|
5314
|
+
}
|
|
5315
|
+
try {
|
|
5316
|
+
return await fn();
|
|
5317
|
+
} finally {
|
|
5318
|
+
await unlink(lockPath).catch(() => void 0);
|
|
5319
|
+
}
|
|
5320
|
+
}
|
|
5321
|
+
async function maybeSendUsageTick(input) {
|
|
5322
|
+
const env = input.env ?? process.env;
|
|
5323
|
+
const optOut = telemetryOptOut(env);
|
|
5324
|
+
if (optOut) return { sent: false, reason: "opt-out", detail: optOut };
|
|
5325
|
+
const destination = telemetryDestination(env);
|
|
5326
|
+
if (!destination) return { sent: false, reason: "no-key" };
|
|
5327
|
+
const statePath2 = input.statePath ?? usageStatePath();
|
|
5328
|
+
const today = (input.now ?? /* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
5329
|
+
let state;
|
|
5330
|
+
try {
|
|
5331
|
+
const claimed = await withStateLock(statePath2, async () => {
|
|
5332
|
+
const current = await readState(statePath2);
|
|
5333
|
+
if (current.last_sent === today) return void 0;
|
|
5334
|
+
if (!current.notice_shown) {
|
|
5335
|
+
(input.notify ?? ((line) => console.error(line)))(FIRST_RUN_NOTICE);
|
|
5336
|
+
current.notice_shown = true;
|
|
5337
|
+
}
|
|
5338
|
+
current.last_sent = today;
|
|
5339
|
+
await writeState(statePath2, current);
|
|
5340
|
+
return current;
|
|
5341
|
+
});
|
|
5342
|
+
if (claimed === "locked" || claimed === void 0) return { sent: false, reason: "already-today" };
|
|
5343
|
+
state = claimed;
|
|
5344
|
+
} catch (err) {
|
|
5345
|
+
return { sent: false, reason: "request-failed", detail: `state: ${err.message}` };
|
|
5346
|
+
}
|
|
5347
|
+
const body = {
|
|
5348
|
+
api_key: destination.key,
|
|
5349
|
+
event: USAGE_EVENT,
|
|
5350
|
+
distinct_id: state.id,
|
|
5351
|
+
properties: usageProperties({ command: input.command, version: input.version }),
|
|
5352
|
+
timestamp: (input.now ?? /* @__PURE__ */ new Date()).toISOString()
|
|
5353
|
+
};
|
|
5354
|
+
try {
|
|
5355
|
+
const res = await (input.fetchImpl ?? fetch)(`${destination.host}/capture/`, {
|
|
5356
|
+
method: "POST",
|
|
5357
|
+
headers: { "content-type": "application/json" },
|
|
5358
|
+
body: JSON.stringify(body),
|
|
5359
|
+
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS)
|
|
5360
|
+
});
|
|
5361
|
+
if (!res.ok) return { sent: false, reason: "request-failed", detail: `HTTP ${res.status}` };
|
|
5362
|
+
return { sent: true };
|
|
5363
|
+
} catch (err) {
|
|
5364
|
+
return { sent: false, reason: "request-failed", detail: err.message };
|
|
5365
|
+
}
|
|
5366
|
+
}
|
|
5319
5367
|
|
|
5320
5368
|
// src/cli/main.ts
|
|
5321
5369
|
var PACKAGE_VERSION = readPackageVersion();
|
|
@@ -5324,7 +5372,7 @@ var DEFAULT_AGENT_COMMAND = `node ${DEFAULT_AGENT_FILE}`;
|
|
|
5324
5372
|
var MANIFEST_SCHEMA_URL = "https://pome.sh/schemas/v1/pome.json";
|
|
5325
5373
|
var MAX_UNREADABLE_PATHS_SHOWN = 5;
|
|
5326
5374
|
function readPackageVersion() {
|
|
5327
|
-
if ("0.
|
|
5375
|
+
if ("0.45.0".length > 0) return "0.45.0";
|
|
5328
5376
|
try {
|
|
5329
5377
|
const here = dirname(fileURLToPath(import.meta.url));
|
|
5330
5378
|
const candidates = [
|
|
@@ -5353,8 +5401,91 @@ function createProgram() {
|
|
|
5353
5401
|
process.env.POME_API_URL ?? DEFAULT_CONTROL_PLANE_URL
|
|
5354
5402
|
).option("--artifacts-dir <dir>", "Directory for run artifacts", "runs");
|
|
5355
5403
|
program.name("pome").description(
|
|
5356
|
-
"
|
|
5357
|
-
).version(PACKAGE_VERSION).showHelpAfterError("(add --help for usage)")
|
|
5404
|
+
"Stateful local twins of GitHub, Slack, Stripe, Gmail and Linear that your agent calls as if they were the real API. Start with `pome twin start <twin>`."
|
|
5405
|
+
).version(PACKAGE_VERSION).showHelpAfterError("(add --help for usage)").hook("preAction", (_root, actionCommand) => {
|
|
5406
|
+
void maybeSendUsageTick({ command: commandName(actionCommand), version: PACKAGE_VERSION });
|
|
5407
|
+
});
|
|
5408
|
+
const twin = program.command("twin").summary("Run a twin on this machine").description(
|
|
5409
|
+
"Start a twin on this machine, print its status, show its tape, or write a starter seed file"
|
|
5410
|
+
);
|
|
5411
|
+
twin.command("start").argument(
|
|
5412
|
+
"[names...]",
|
|
5413
|
+
`Twin names (${TWIN_NAME_LIST.join(" | ")}). One, or several to boot together (each on its own port). Optional when --seed names exactly one twin.`
|
|
5414
|
+
).option(
|
|
5415
|
+
"--port <port>",
|
|
5416
|
+
// Built from the registry rather than restated: the per-twin overrides
|
|
5417
|
+
// are the registry's to add, and this text went stale when linear's did.
|
|
5418
|
+
`Port to bind (default: $PORT, else ${TWIN_NAME_LIST.filter(
|
|
5419
|
+
(twin2) => TWIN_REGISTRY[twin2].portEnvName
|
|
5420
|
+
).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.`
|
|
5421
|
+
).option(
|
|
5422
|
+
"--seed <path>",
|
|
5423
|
+
"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."
|
|
5424
|
+
).description(
|
|
5425
|
+
"Start one or more standalone twins as a long-lived foreground server (Ctrl-C to stop)"
|
|
5426
|
+
).action(async (names, options) => {
|
|
5427
|
+
const { runTwinStartCommand } = await import('../../twinStart-XN3BYOUF.js');
|
|
5428
|
+
await runTwinStartCommand(names, options);
|
|
5429
|
+
});
|
|
5430
|
+
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(
|
|
5431
|
+
"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"
|
|
5432
|
+
).action(async (names, options) => {
|
|
5433
|
+
const { runTwinSeedCommand } = await import('../../twinSeed-ZFZO7BL7.js');
|
|
5434
|
+
await runTwinSeedCommand(names, options);
|
|
5435
|
+
});
|
|
5436
|
+
twin.command("status").summary("Say whether the local twins are running").description(
|
|
5437
|
+
"Say whether each twin `pome twin start` booted here is still running, and print its paste-able env lines"
|
|
5438
|
+
).action(async () => {
|
|
5439
|
+
const statusPath = ".pome/twin-status.json";
|
|
5440
|
+
if (!existsSync(statusPath)) {
|
|
5441
|
+
console.log("No standalone twin status found.");
|
|
5442
|
+
return;
|
|
5443
|
+
}
|
|
5444
|
+
const { standaloneStatusEntries } = await import('../../twinStart-XN3BYOUF.js');
|
|
5445
|
+
let entries;
|
|
5446
|
+
try {
|
|
5447
|
+
entries = standaloneStatusEntries(JSON.parse(await readFile(statusPath, "utf8"))).map(
|
|
5448
|
+
(status) => ({ ...status, origin: new URL(status.rest_url).origin })
|
|
5449
|
+
);
|
|
5450
|
+
if (entries.length === 0 || entries.some((status) => status.name === "")) {
|
|
5451
|
+
throw new Error("no twins");
|
|
5452
|
+
}
|
|
5453
|
+
} catch {
|
|
5454
|
+
throw new Error(
|
|
5455
|
+
`pome twin status: ${statusPath} is unreadable \u2014 start a twin with \`pome twin start <${TWIN_NAME_LIST.join("|")}>\`.`
|
|
5456
|
+
);
|
|
5457
|
+
}
|
|
5458
|
+
for (const [index, status] of entries.entries()) {
|
|
5459
|
+
const running = await fetch(`${status.origin}/healthz`, {
|
|
5460
|
+
signal: AbortSignal.timeout(1e3)
|
|
5461
|
+
}).then(
|
|
5462
|
+
async (res) => res.ok && (await res.json().catch(() => ({}))).twin === status.name,
|
|
5463
|
+
() => false
|
|
5464
|
+
);
|
|
5465
|
+
if (index > 0) console.log("");
|
|
5466
|
+
console.log(
|
|
5467
|
+
running ? `${status.name} twin \u2014 running` : `${status.name} twin \u2014 not running (stale ${statusPath})`
|
|
5468
|
+
);
|
|
5469
|
+
const envName = TWIN_REGISTRY[status.name]?.envName ?? status.name.toUpperCase();
|
|
5470
|
+
console.log(`POME_${envName}_REST_URL=${status.rest_url}`);
|
|
5471
|
+
console.log(`POME_${envName}_MCP_URL=${status.mcp_url}`);
|
|
5472
|
+
console.log(`POME_AUTH_TOKEN=${status.auth_token}`);
|
|
5473
|
+
}
|
|
5474
|
+
});
|
|
5475
|
+
twin.command("tape").argument(
|
|
5476
|
+
"[name]",
|
|
5477
|
+
`Twin name (${TWIN_NAME_LIST.join(" | ")}). Optional when one twin is recorded in .pome/twin-status.json.`
|
|
5478
|
+
).option(
|
|
5479
|
+
"--diff",
|
|
5480
|
+
"Also print the state diff since the twin booted \u2014 its seed, default or --seed \u2014 per collection: added, changed, removed.",
|
|
5481
|
+
false
|
|
5482
|
+
).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(
|
|
5483
|
+
"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."
|
|
5484
|
+
).action(async (name, options) => {
|
|
5485
|
+
const { runTwinTapeCommand } = await import('../../twinTape-5P3HQ27N.js');
|
|
5486
|
+
await runTwinTapeCommand(name, options);
|
|
5487
|
+
});
|
|
5488
|
+
program.commandsGroup("Going further:");
|
|
5358
5489
|
program.command("init").summary("Set up Pome in this project").description(
|
|
5359
5490
|
"Create pome.json, plus starter files in a new project \u2014 or, with --example <id>, fetch a complete runnable example into ./<id>"
|
|
5360
5491
|
).option(
|
|
@@ -5728,7 +5859,7 @@ function createProgram() {
|
|
|
5728
5859
|
return;
|
|
5729
5860
|
}
|
|
5730
5861
|
{
|
|
5731
|
-
const { runDoctorChecks } = await import('../../checks-
|
|
5862
|
+
const { runDoctorChecks } = await import('../../checks-RDU56OGI.js');
|
|
5732
5863
|
const { renderDoctorReport } = await import('../../render-ZQQ4UMNO.js');
|
|
5733
5864
|
const doctorReport = await runDoctorChecks({ mode: useLocal ? "full" : "hosted" });
|
|
5734
5865
|
if (!doctorReport.ok) {
|
|
@@ -5766,7 +5897,7 @@ function createProgram() {
|
|
|
5766
5897
|
taskForRuns.config.runs
|
|
5767
5898
|
);
|
|
5768
5899
|
if (k > 1) {
|
|
5769
|
-
const { runTrialGroup } = await import('../../runTrialGroup-
|
|
5900
|
+
const { runTrialGroup } = await import('../../runTrialGroup-MMTTTDWY.js');
|
|
5770
5901
|
const fileForRerun = relative(process.cwd(), file);
|
|
5771
5902
|
const rerunCommand = defaultTask ? options.trials !== void 0 ? `pome run -n ${k}` : "pome run" : `pome run ${fileForRerun && !fileForRerun.startsWith("..") ? fileForRerun : file} -n ${k}`;
|
|
5772
5903
|
const groupResult = await runTrialGroup({
|
|
@@ -5848,7 +5979,7 @@ function createProgram() {
|
|
|
5848
5979
|
program.command("doctor").summary("Check the agent and twin wiring").description(
|
|
5849
5980
|
"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
5981
|
).action(async () => {
|
|
5851
|
-
const { runDoctorChecks } = await import('../../checks-
|
|
5982
|
+
const { runDoctorChecks } = await import('../../checks-RDU56OGI.js');
|
|
5852
5983
|
const { renderDoctorReport } = await import('../../render-ZQQ4UMNO.js');
|
|
5853
5984
|
const report = await runDoctorChecks();
|
|
5854
5985
|
for (const line of renderDoctorReport(report, { passNote: true })) console.error(line);
|
|
@@ -5999,65 +6130,6 @@ function createProgram() {
|
|
|
5999
6130
|
})
|
|
6000
6131
|
);
|
|
6001
6132
|
});
|
|
6002
|
-
const twin = program.command("twin").summary("Run a twin on this machine").description("Start a twin on this machine, print its status or a starter seed file");
|
|
6003
|
-
twin.command("start").argument(
|
|
6004
|
-
"[name]",
|
|
6005
|
-
`Twin name (${TWIN_NAME_LIST.join(" | ")}). Optional when --seed names exactly one twin.`
|
|
6006
|
-
).option(
|
|
6007
|
-
"--port <port>",
|
|
6008
|
-
// Built from the registry rather than restated: the per-twin overrides
|
|
6009
|
-
// are the registry's to add, and this text went stale when linear's did.
|
|
6010
|
-
`Port to bind (default: $PORT, else ${TWIN_NAME_LIST.filter(
|
|
6011
|
-
(twin2) => TWIN_REGISTRY[twin2].portEnvName
|
|
6012
|
-
).map((twin2) => `${TWIN_REGISTRY[twin2].portEnvName}/${TWIN_REGISTRY[twin2].defaultPort} for ${twin2}`).join(", ")}, otherwise 3333)`
|
|
6013
|
-
).option(
|
|
6014
|
-
"--seed <path>",
|
|
6015
|
-
"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."
|
|
6016
|
-
).description(
|
|
6017
|
-
"Start a standalone twin as a long-lived foreground server (Ctrl-C to stop)"
|
|
6018
|
-
).action(async (name, options) => {
|
|
6019
|
-
const { runTwinStartCommand } = await import('../../twinStart-3Q74IURZ.js');
|
|
6020
|
-
await runTwinStartCommand(name, options);
|
|
6021
|
-
});
|
|
6022
|
-
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
|
-
"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
|
-
).action(async (names, options) => {
|
|
6025
|
-
const { runTwinSeedCommand } = await import('../../twinSeed-J7UAY3GM.js');
|
|
6026
|
-
await runTwinSeedCommand(names, options);
|
|
6027
|
-
});
|
|
6028
|
-
twin.command("status").summary("Say whether the local twin is running").description(
|
|
6029
|
-
"Say whether the twin `pome twin start` last booted here is still running, and print its paste-able env lines"
|
|
6030
|
-
).action(async () => {
|
|
6031
|
-
const statusPath = ".pome/twin-status.json";
|
|
6032
|
-
if (!existsSync(statusPath)) {
|
|
6033
|
-
console.log("No standalone twin status found.");
|
|
6034
|
-
return;
|
|
6035
|
-
}
|
|
6036
|
-
let status;
|
|
6037
|
-
let origin;
|
|
6038
|
-
try {
|
|
6039
|
-
status = JSON.parse(await readFile(statusPath, "utf8"));
|
|
6040
|
-
if (typeof status.name !== "string" || status.name === "") throw new Error("no name");
|
|
6041
|
-
origin = new URL(status.rest_url).origin;
|
|
6042
|
-
} catch {
|
|
6043
|
-
throw new Error(
|
|
6044
|
-
`pome twin status: ${statusPath} is unreadable \u2014 start a twin with \`pome twin start <${TWIN_NAME_LIST.join("|")}>\`.`
|
|
6045
|
-
);
|
|
6046
|
-
}
|
|
6047
|
-
const running = await fetch(`${origin}/healthz`, {
|
|
6048
|
-
signal: AbortSignal.timeout(1e3)
|
|
6049
|
-
}).then(
|
|
6050
|
-
async (res) => res.ok && (await res.json().catch(() => ({}))).twin === status.name,
|
|
6051
|
-
() => false
|
|
6052
|
-
);
|
|
6053
|
-
console.log(
|
|
6054
|
-
running ? `${status.name} twin \u2014 running` : `${status.name} twin \u2014 not running (stale ${statusPath})`
|
|
6055
|
-
);
|
|
6056
|
-
const envName = TWIN_REGISTRY[status.name]?.envName ?? status.name.toUpperCase();
|
|
6057
|
-
console.log(`POME_${envName}_REST_URL=${status.rest_url}`);
|
|
6058
|
-
console.log(`POME_${envName}_MCP_URL=${status.mcp_url}`);
|
|
6059
|
-
console.log(`POME_AUTH_TOKEN=${status.auth_token}`);
|
|
6060
|
-
});
|
|
6061
6133
|
program.command("capture-server").summary("Record the agent's model calls").description(
|
|
6062
6134
|
"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."
|
|
6063
6135
|
).option("--port <port>", "TCP port to listen on (0 = ephemeral).", "8910").option(
|
|
@@ -6102,8 +6174,8 @@ async function taskFiles(target) {
|
|
|
6102
6174
|
if (!existsSync(resolved)) {
|
|
6103
6175
|
throw new HostedUsageError(`Task path not found: ${target}`);
|
|
6104
6176
|
}
|
|
6105
|
-
const
|
|
6106
|
-
if (
|
|
6177
|
+
const stat4 = await import('node:fs/promises').then((fs) => fs.stat(resolved));
|
|
6178
|
+
if (stat4.isFile()) return [resolved];
|
|
6107
6179
|
const entries = await readdir(resolved);
|
|
6108
6180
|
return entries.filter((entry) => entry.endsWith(".md")).sort().map((entry) => join(resolved, entry));
|
|
6109
6181
|
}
|
|
@@ -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';
|
|
@@ -3081,12 +3081,6 @@ function checkRunJson(run, repo) {
|
|
|
3081
3081
|
html_url: `https://github.com/${repo.full_name}/runs/${run.id}`,
|
|
3082
3082
|
details_url: run.details_url,
|
|
3083
3083
|
status: run.status,
|
|
3084
|
-
// The twin's `conclusion` column carries the full GitHub check-run
|
|
3085
|
-
// conclusion vocabulary including `"stale"`, but the pinned
|
|
3086
|
-
// @octokit/openapi-types version's `check-run.conclusion` enum predates
|
|
3087
|
-
// `"stale"`. The twin faithfully emits a real upstream value; narrow it to
|
|
3088
|
-
// the schema's declared union for the type anchor only (twin
|
|
3089
|
-
// tracks live GitHub, not a lagging spec snapshot), runtime value unchanged.
|
|
3090
3084
|
conclusion: run.conclusion,
|
|
3091
3085
|
started_at: run.started_at,
|
|
3092
3086
|
completed_at: run.completed_at,
|
|
@@ -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';
|