@pome-sh/cli 0.42.4 → 0.43.1
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 +238 -117
- package/dist/build-info.json +3 -3
- package/dist/{checks-BKMTBJSO.js → checks-V442KL5O.js} +9 -14
- package/dist/{chunk-RPPF2KDQ.js → chunk-4DXTT3RV.js} +7 -7
- package/dist/{chunk-6KJC4BTO.js → chunk-5KFDRR53.js} +2 -2
- package/dist/{chunk-5NPGY73F.js → chunk-64AWQJ7R.js} +2 -2
- package/dist/{chunk-STMGQ7GU.js → chunk-A6AM6KS4.js} +1405 -172
- package/dist/{chunk-NNXVR46L.js → chunk-CS7O2ZXB.js} +114 -2
- package/dist/{chunk-VPXIGCZW.js → chunk-GQSNU3YP.js} +1 -1
- package/dist/{chunk-HRAD7MRX.js → chunk-TWURH7YM.js} +34 -10
- package/dist/{runTrialGroup-BP446HIE.js → runTrialGroup-HYGGBLMM.js} +20 -10
- package/dist/{server-GDK4TBTL.js → server-2WHSHTUD.js} +2 -2
- package/dist/src/cli/main.js +488 -226
- package/dist/{src-Z4C4SSDR.js → src-DBOHIQNB.js} +2 -2
- package/dist/{src-FUPOFZI4.js → src-FRPUTB2H.js} +2 -2
- package/dist/{src-UY4Y75BD.js → src-G6CMFUR6.js} +2 -2
- package/dist/{src-SNSK5ENY.js → src-SJDGRXC5.js} +2 -2
- package/dist/{src-V3RUKDMQ.js → src-VBXONWR3.js} +2 -2
- package/dist/twinHarness-33MAVAXV.js +6 -0
- package/dist/{twinSeed-X6VHBOLM.js → twinSeed-J7UAY3GM.js} +1 -1
- package/dist/{twinStart-QQU6OIO4.js → twinStart-3Q74IURZ.js} +21 -17
- package/package.json +1 -2
- package/dist/agent-Q2UTRJYL.js +0 -408
- package/dist/chunk-46POYRLY.js +0 -1240
- package/dist/chunk-DFOQGAKS.js +0 -116
- package/dist/chunk-JNXZBK3O.js +0 -17
- package/dist/chunk-WERG4AUH.js +0 -462
- package/dist/chunk-ZX4WNSZ5.js +0 -71
- package/dist/runDemo-DRDMCG25.js +0 -408
- package/dist/twinHarness-ATYQTDA5.js +0 -6
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { seedSchema as seedSchema$2 } from './chunk-NBOQN5VX.js';
|
|
2
2
|
import { seedSchema } from './chunk-YBWG5JK2.js';
|
|
3
|
-
import { twinIdSchema } from './chunk-
|
|
3
|
+
import { twinIdSchema } from './chunk-5KFDRR53.js';
|
|
4
4
|
import { seedSchema as seedSchema$1 } from './chunk-2K6BJ3PI.js';
|
|
5
5
|
import { z } from 'zod';
|
|
6
|
+
import { readFile, writeFile } from 'node:fs/promises';
|
|
7
|
+
import { resolve, join, dirname } from 'node:path';
|
|
8
|
+
import { stringify, parse } from 'yaml';
|
|
6
9
|
|
|
7
10
|
var SLUG_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
8
11
|
var SLUG_MAX_LENGTH = 64;
|
|
@@ -1146,5 +1149,114 @@ function exitCodeFor(err) {
|
|
|
1146
1149
|
if (err instanceof HostedDiscardRefusedError) return 5;
|
|
1147
1150
|
return 2;
|
|
1148
1151
|
}
|
|
1152
|
+
var MANIFEST_JSON = "pome.json";
|
|
1153
|
+
var MANIFEST_YAML = "pome.yaml";
|
|
1154
|
+
var MANIFEST_YML = "pome.yml";
|
|
1155
|
+
var MANIFEST_FILES = [MANIFEST_JSON, MANIFEST_YAML, MANIFEST_YML];
|
|
1156
|
+
var SCHEMA_URL = "https://pome.sh/schemas/v1/pome.json";
|
|
1157
|
+
var YAML_SCHEMA_COMMENT = `# yaml-language-server: $schema=${SCHEMA_URL}`;
|
|
1158
|
+
function formatFor(fileName) {
|
|
1159
|
+
return fileName === MANIFEST_JSON ? "json" : "yaml";
|
|
1160
|
+
}
|
|
1161
|
+
async function findManifestPath(startDir = process.cwd()) {
|
|
1162
|
+
let dir = resolve(startDir);
|
|
1163
|
+
for (; ; ) {
|
|
1164
|
+
const present = [];
|
|
1165
|
+
for (const fileName of MANIFEST_FILES) {
|
|
1166
|
+
if (await fileExists(join(dir, fileName))) present.push(fileName);
|
|
1167
|
+
}
|
|
1168
|
+
if (present.length > 1) {
|
|
1169
|
+
throw new HostedOrchError(
|
|
1170
|
+
`Multiple pome manifests in ${dir}: ${present.join(", ")}. Keep exactly one (pome.json is canonical).`
|
|
1171
|
+
);
|
|
1172
|
+
}
|
|
1173
|
+
if (present.length === 1) {
|
|
1174
|
+
const fileName = present[0];
|
|
1175
|
+
return { path: join(dir, fileName), format: formatFor(fileName) };
|
|
1176
|
+
}
|
|
1177
|
+
const parent = dirname(dir);
|
|
1178
|
+
if (parent === dir) return null;
|
|
1179
|
+
dir = parent;
|
|
1180
|
+
}
|
|
1181
|
+
}
|
|
1182
|
+
async function readManifest(startDir = process.cwd()) {
|
|
1183
|
+
const found = await findManifestPath(startDir);
|
|
1184
|
+
if (!found) return null;
|
|
1185
|
+
const text = await readFile(found.path, "utf8");
|
|
1186
|
+
const raw = parseManifestText(text, found);
|
|
1187
|
+
const manifest = validateManifest(raw, found.path);
|
|
1188
|
+
return { ...found, manifest, raw };
|
|
1189
|
+
}
|
|
1190
|
+
async function readRequiredManifest(startDir = process.cwd()) {
|
|
1191
|
+
const read = await readManifest(startDir);
|
|
1192
|
+
if (!read) {
|
|
1193
|
+
throw new HostedOrchError(
|
|
1194
|
+
`No pome manifest found (${MANIFEST_JSON} or ${MANIFEST_YAML}). Run \`pome init\` first.`
|
|
1195
|
+
);
|
|
1196
|
+
}
|
|
1197
|
+
return read;
|
|
1198
|
+
}
|
|
1199
|
+
async function writeManifest(path, format, data) {
|
|
1200
|
+
if (format === "json") {
|
|
1201
|
+
await writeFile(path, `${JSON.stringify(data, null, 2)}
|
|
1202
|
+
`);
|
|
1203
|
+
return;
|
|
1204
|
+
}
|
|
1205
|
+
const { $schema: _dropped, ...body } = data;
|
|
1206
|
+
await writeFile(path, `${YAML_SCHEMA_COMMENT}
|
|
1207
|
+
${stringify(body)}`);
|
|
1208
|
+
}
|
|
1209
|
+
function parseManifestText(text, found) {
|
|
1210
|
+
let parsed;
|
|
1211
|
+
try {
|
|
1212
|
+
parsed = found.format === "json" ? JSON.parse(text) : parse(text);
|
|
1213
|
+
} catch (err) {
|
|
1214
|
+
throw new HostedOrchError(
|
|
1215
|
+
`${found.path} is not valid ${found.format.toUpperCase()}: ${err instanceof Error ? err.message : String(err)}`
|
|
1216
|
+
);
|
|
1217
|
+
}
|
|
1218
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
1219
|
+
throw new HostedOrchError(`${found.path} is not a ${found.format} object`);
|
|
1220
|
+
}
|
|
1221
|
+
return parsed;
|
|
1222
|
+
}
|
|
1223
|
+
function validateManifest(raw, path) {
|
|
1224
|
+
const result = manifestSchema.safeParse(raw);
|
|
1225
|
+
if (result.success) return result.data;
|
|
1226
|
+
const slugIssue = result.error.issues.find(
|
|
1227
|
+
(issue) => issue.path[0] === "agent" && issue.path[1] === "slug"
|
|
1228
|
+
);
|
|
1229
|
+
if (slugIssue) {
|
|
1230
|
+
throw new HostedOrchError(slugErrorMessage(raw, path));
|
|
1231
|
+
}
|
|
1232
|
+
const summary = result.error.issues.map((issue) => `${issue.path.join(".") || "(root)"}: ${issue.message}`).join("; ");
|
|
1233
|
+
throw new HostedOrchError(`Invalid pome manifest ${path}: ${summary}`);
|
|
1234
|
+
}
|
|
1235
|
+
function slugErrorMessage(raw, path) {
|
|
1236
|
+
const agent = typeof raw.agent === "object" && raw.agent !== null ? raw.agent : {};
|
|
1237
|
+
const name = typeof agent.name === "string" ? agent.name : "";
|
|
1238
|
+
const badSlug = typeof agent.slug === "string" ? agent.slug : "";
|
|
1239
|
+
const suggestion = deriveAgentSlug(name || badSlug);
|
|
1240
|
+
const base = `Invalid agent.slug in ${path}: must match ${SLUG_RE} (lowercase kebab-case, max 64 chars).`;
|
|
1241
|
+
return suggestion.length > 0 ? `${base} Did you mean "${suggestion}"?` : base;
|
|
1242
|
+
}
|
|
1243
|
+
function normalizeManifestTwins(manifestTwins) {
|
|
1244
|
+
if (manifestTwins === void 0) return void 0;
|
|
1245
|
+
const out = /* @__PURE__ */ new Set();
|
|
1246
|
+
for (const twin of manifestTwins) {
|
|
1247
|
+
const norm = twin.trim().toLowerCase();
|
|
1248
|
+
if (norm.length > 0) out.add(norm);
|
|
1249
|
+
}
|
|
1250
|
+
return out.size > 0 ? [...out] : void 0;
|
|
1251
|
+
}
|
|
1252
|
+
async function fileExists(path) {
|
|
1253
|
+
try {
|
|
1254
|
+
await readFile(path, "utf8");
|
|
1255
|
+
return true;
|
|
1256
|
+
} catch (err) {
|
|
1257
|
+
if (err.code === "ENOENT") return false;
|
|
1258
|
+
throw err;
|
|
1259
|
+
}
|
|
1260
|
+
}
|
|
1149
1261
|
|
|
1150
|
-
export { HostedAuthError, HostedDiscardRefusedError, HostedOrchError, HostedQuotaError, HostedTrialError, HostedUsageError,
|
|
1262
|
+
export { HostedAuthError, HostedDiscardRefusedError, HostedOrchError, HostedQuotaError, HostedTrialError, HostedUsageError, MANIFEST_JSON, MOUNTED_TWINS, agentResponseSchema, createEvalSessionResponseSchema, createSessionResponseSchema, criterionSchema, deriveAgentSlug, exitCodeFor, finalizeResponseSchema, findManifestPath, isMultiTwinSeedEnvelope, normalizeManifestTwins, normalizeTaskConfigKeys, readManifest, readRequiredManifest, sessionPublicSchema, submitResultResponseSchema, writeManifest };
|
|
@@ -445,6 +445,7 @@ function defineTwin(spec) {
|
|
|
445
445
|
}
|
|
446
446
|
var RESERVED_SESSION_PREFIXES = ["/_pome", "/mcp"];
|
|
447
447
|
var CLIENT_IP_VAR = "pomeClientIp";
|
|
448
|
+
var ADMIN_NO_PEER_OPT_IN = "TWIN_ADMIN_ALLOW_NO_PEER";
|
|
448
449
|
var nodeGetConnInfo;
|
|
449
450
|
function loadNodeGetConnInfo() {
|
|
450
451
|
nodeGetConnInfo ??= import('@hono/node-server/conninfo').then((mod) => mod.getConnInfo, () => void 0);
|
|
@@ -490,10 +491,11 @@ function createAdminGate(options = {}) {
|
|
|
490
491
|
}
|
|
491
492
|
const remote = await getClientIp(c);
|
|
492
493
|
if (!remote) {
|
|
493
|
-
if (process.env
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
494
|
+
if (process.env[ADMIN_NO_PEER_OPT_IN] === "1") {
|
|
495
|
+
await next();
|
|
496
|
+
return;
|
|
497
|
+
}
|
|
498
|
+
return forbidden();
|
|
497
499
|
}
|
|
498
500
|
if (!isLoopbackAddress(remote))
|
|
499
501
|
return forbidden();
|
|
@@ -503,13 +505,22 @@ function createAdminGate(options = {}) {
|
|
|
503
505
|
|
|
504
506
|
// ../packages/sdk/dist/auth.js
|
|
505
507
|
var PROVIDER_SHAPED_TEAM_ID = "provider-shaped";
|
|
508
|
+
var DEV_ONLY_INSECURE_SECRET = "dev-only-insecure-secret";
|
|
509
|
+
var DEV_SECRETS_OPT_IN = "POME_ALLOW_DEV_SECRETS";
|
|
506
510
|
function resolveAuthSecret() {
|
|
507
511
|
const secret = process.env.TWIN_AUTH_SECRET;
|
|
508
|
-
if (
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
+
if (secret)
|
|
513
|
+
return secret;
|
|
514
|
+
if (process.env[DEV_SECRETS_OPT_IN] === "1")
|
|
515
|
+
return DEV_ONLY_INSECURE_SECRET;
|
|
516
|
+
throw new MissingAuthSecretError();
|
|
512
517
|
}
|
|
518
|
+
var MissingAuthSecretError = class extends Error {
|
|
519
|
+
constructor() {
|
|
520
|
+
super(`TWIN_AUTH_SECRET is not set. Set it, or set ${DEV_SECRETS_OPT_IN}=1 to serve the public dev secret on a twin nothing but this machine can reach.`);
|
|
521
|
+
this.name = "MissingAuthSecretError";
|
|
522
|
+
}
|
|
523
|
+
};
|
|
513
524
|
var SIG_LENGTH = 22;
|
|
514
525
|
function mintProviderToken(spec, options) {
|
|
515
526
|
const prefix = options.prefix ?? spec.prefixes[0];
|
|
@@ -674,7 +685,14 @@ function bearerAuth(options = {}) {
|
|
|
674
685
|
}
|
|
675
686
|
}
|
|
676
687
|
if (options.providerToken) {
|
|
677
|
-
|
|
688
|
+
let providerSid;
|
|
689
|
+
try {
|
|
690
|
+
providerSid = verifyProviderToken(options.providerToken, token);
|
|
691
|
+
} catch (err) {
|
|
692
|
+
if (err instanceof MissingAuthSecretError)
|
|
693
|
+
return respond(unauthorized("invalid", { token }));
|
|
694
|
+
throw err;
|
|
695
|
+
}
|
|
678
696
|
if (providerSid) {
|
|
679
697
|
const mismatch2 = checkSid(providerSid);
|
|
680
698
|
if (mismatch2)
|
|
@@ -1281,8 +1299,14 @@ function isLoopbackHost(value) {
|
|
|
1281
1299
|
function ensureTwinAuthSecret(twin, host) {
|
|
1282
1300
|
if (process.env.TWIN_AUTH_SECRET)
|
|
1283
1301
|
return;
|
|
1284
|
-
if (isLoopbackHost(host))
|
|
1302
|
+
if (isLoopbackHost(host)) {
|
|
1303
|
+
if (process.env[DEV_SECRETS_OPT_IN] === "1")
|
|
1304
|
+
return;
|
|
1305
|
+
const secret = randomBytes(32).toString("hex");
|
|
1306
|
+
process.env.TWIN_AUTH_SECRET = secret;
|
|
1307
|
+
console.log(`[twin-${twin}] TWIN_AUTH_SECRET not set \u2014 generated ${secret} for this loopback boot (not persisted; set TWIN_AUTH_SECRET to choose one, or ${DEV_SECRETS_OPT_IN}=1 for the public dev secret)`);
|
|
1285
1308
|
return;
|
|
1309
|
+
}
|
|
1286
1310
|
const dataDir = process.env.POME_TWIN_DATA_DIR || join(".pome-data", twin);
|
|
1287
1311
|
const secretPath = join(dataDir, "secret");
|
|
1288
1312
|
try {
|
|
@@ -1,24 +1,34 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import { createHostedClient, parseTaskFile, outcomeOf, isNarrated, criterionPhrase, narratorReadingLines } from './chunk-STMGQ7GU.js';
|
|
4
|
-
import './chunk-VPXIGCZW.js';
|
|
1
|
+
import { runTaskHosted, createHostedClient, parseTaskFile, resolveRunAgentIdentity, outcomeOf, isNarrated, criterionPhrase, narratorReadingLines } from './chunk-A6AM6KS4.js';
|
|
2
|
+
import './chunk-GQSNU3YP.js';
|
|
5
3
|
import './chunk-NW7HGA2K.js';
|
|
6
4
|
import './chunk-PASFBRK4.js';
|
|
7
5
|
import './chunk-3FZY376K.js';
|
|
8
|
-
import './chunk-
|
|
9
|
-
import './chunk-
|
|
10
|
-
import { HostedQuotaError, HostedTrialError } from './chunk-NNXVR46L.js';
|
|
6
|
+
import './chunk-4DXTT3RV.js';
|
|
7
|
+
import { HostedQuotaError, HostedTrialError } from './chunk-CS7O2ZXB.js';
|
|
11
8
|
import './chunk-NBOQN5VX.js';
|
|
12
9
|
import './chunk-YBWG5JK2.js';
|
|
13
|
-
import './chunk-
|
|
14
|
-
import './chunk-
|
|
10
|
+
import './chunk-TWURH7YM.js';
|
|
11
|
+
import './chunk-5KFDRR53.js';
|
|
15
12
|
import './chunk-SG6ZTIMT.js';
|
|
16
13
|
import './chunk-2K6BJ3PI.js';
|
|
17
14
|
import './chunk-FBSA5L36.js';
|
|
18
|
-
import { randomUUID } from 'node:crypto';
|
|
15
|
+
import { randomUUID, randomBytes } from 'node:crypto';
|
|
19
16
|
import { readFile } from 'node:fs/promises';
|
|
20
17
|
import { dirname } from 'node:path';
|
|
21
18
|
|
|
19
|
+
var NANOID_ALPHABET = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
|
|
20
|
+
function nanoid(size = 21) {
|
|
21
|
+
const bytes = randomBytes(size);
|
|
22
|
+
let id = "";
|
|
23
|
+
for (let i = 0; i < size; i += 1) {
|
|
24
|
+
id += NANOID_ALPHABET[bytes[i] & 63];
|
|
25
|
+
}
|
|
26
|
+
return id;
|
|
27
|
+
}
|
|
28
|
+
function newGroupId() {
|
|
29
|
+
return `grp_${nanoid(21)}`;
|
|
30
|
+
}
|
|
31
|
+
|
|
22
32
|
// src/runner/groupRender.ts
|
|
23
33
|
function flagHintLine(agentCommandSource) {
|
|
24
34
|
return `-n sets how many isolated trials to run \xB7 the agent command comes from ${agentCommandSource}`;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { POME_RECORDER_EVENTS_PATH, PROVIDER_SHAPED_TEAM_ID, TwinBootError, TwinError, UnknownToolError, bearerAuth, createAdminGate, createApp, createFileBackedRecorderStore, createRecorderHandle, createRecorderStore, created, ensureTwinAuthSecret, failureInjectionMiddleware, formTokenResolver, isLoopbackHost, mintProviderToken, ok, queryTokenResolver, recordedRequestHeaders, requireAdminAuth, resolveAuthSecret, resolveRecorderStore, serve, setClientIp, setRecordedTool, toTwinHttpEventRow, twinBuildInfo, verifyProviderToken } from './chunk-
|
|
2
|
-
import './chunk-
|
|
1
|
+
export { POME_RECORDER_EVENTS_PATH, PROVIDER_SHAPED_TEAM_ID, TwinBootError, TwinError, UnknownToolError, bearerAuth, createAdminGate, createApp, createFileBackedRecorderStore, createRecorderHandle, createRecorderStore, created, ensureTwinAuthSecret, failureInjectionMiddleware, formTokenResolver, isLoopbackHost, mintProviderToken, ok, queryTokenResolver, recordedRequestHeaders, requireAdminAuth, resolveAuthSecret, resolveRecorderStore, serve, setClientIp, setRecordedTool, toTwinHttpEventRow, twinBuildInfo, verifyProviderToken } from './chunk-TWURH7YM.js';
|
|
2
|
+
import './chunk-5KFDRR53.js';
|
|
3
3
|
export { redactEvent, redactSecrets } from './chunk-SG6ZTIMT.js';
|
|
4
4
|
export { FAILURE_INJECTION_OVERRIDE_KEY, createFailureInjectionStore, failureInjectionRuleSchema } from './chunk-FBSA5L36.js';
|