@usecontextlayer/ctxe 0.4.11 → 0.4.13
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/cli.mjs +252 -163
- package/dist/cli.mjs.map +1 -1
- package/package.json +3 -3
package/dist/cli.mjs
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
3
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="ef06741d-8451-516d-a05b-dd7da1f526a8")}catch(e){}}();
|
|
4
4
|
import { createRequire } from "node:module";
|
|
5
5
|
import * as Sentry from "@sentry/node";
|
|
6
6
|
import * as xi from "node:fs";
|
|
7
7
|
import { appendFileSync, createReadStream, createWriteStream, existsSync, readFileSync, realpathSync, statSync, writeFileSync } from "node:fs";
|
|
8
8
|
import { constants, homedir, tmpdir } from "node:os";
|
|
9
|
-
import path, { posix, sep, win32 } from "node:path";
|
|
9
|
+
import path, { posix, resolve, sep, win32 } from "node:path";
|
|
10
10
|
import { fileURLToPath } from "node:url";
|
|
11
11
|
import fs, { lstatSync, readdir, readdirSync, readlinkSync, realpathSync as realpathSync$1 } from "fs";
|
|
12
12
|
import { access, copyFile, cp, lstat, mkdir, mkdtemp, readFile, readdir as readdir$1, readlink, realpath, rename, rm, stat, writeFile } from "node:fs/promises";
|
|
@@ -59,7 +59,7 @@ var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
|
59
59
|
|
|
60
60
|
//#endregion
|
|
61
61
|
//#region package.json
|
|
62
|
-
var version$1 = "0.4.
|
|
62
|
+
var version$1 = "0.4.13";
|
|
63
63
|
|
|
64
64
|
//#endregion
|
|
65
65
|
//#region sentry.ts
|
|
@@ -7283,6 +7283,74 @@ function _getDefaultLogLevel() {
|
|
|
7283
7283
|
}
|
|
7284
7284
|
const consola = createConsola();
|
|
7285
7285
|
|
|
7286
|
+
//#endregion
|
|
7287
|
+
//#region ../../node_modules/.pnpm/uuid@14.0.0/node_modules/uuid/dist-node/rng.js
|
|
7288
|
+
const rnds8 = new Uint8Array(16);
|
|
7289
|
+
function rng() {
|
|
7290
|
+
return crypto.getRandomValues(rnds8);
|
|
7291
|
+
}
|
|
7292
|
+
|
|
7293
|
+
//#endregion
|
|
7294
|
+
//#region ../../node_modules/.pnpm/uuid@14.0.0/node_modules/uuid/dist-node/stringify.js
|
|
7295
|
+
const byteToHex = [];
|
|
7296
|
+
for (let i = 0; i < 256; ++i) byteToHex.push((i + 256).toString(16).slice(1));
|
|
7297
|
+
function unsafeStringify(arr, offset = 0) {
|
|
7298
|
+
return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase();
|
|
7299
|
+
}
|
|
7300
|
+
|
|
7301
|
+
//#endregion
|
|
7302
|
+
//#region ../../node_modules/.pnpm/uuid@14.0.0/node_modules/uuid/dist-node/v7.js
|
|
7303
|
+
const _state = {};
|
|
7304
|
+
function v7(options, buf, offset) {
|
|
7305
|
+
let bytes;
|
|
7306
|
+
if (options) bytes = v7Bytes(options.random ?? options.rng?.() ?? rng(), options.msecs, options.seq, buf, offset);
|
|
7307
|
+
else {
|
|
7308
|
+
const now = Date.now();
|
|
7309
|
+
const rnds = rng();
|
|
7310
|
+
updateV7State(_state, now, rnds);
|
|
7311
|
+
bytes = v7Bytes(rnds, _state.msecs, _state.seq, buf, offset);
|
|
7312
|
+
}
|
|
7313
|
+
return buf ?? unsafeStringify(bytes);
|
|
7314
|
+
}
|
|
7315
|
+
function updateV7State(state, now, rnds) {
|
|
7316
|
+
state.msecs ??= -Infinity;
|
|
7317
|
+
state.seq ??= 0;
|
|
7318
|
+
if (now > state.msecs) {
|
|
7319
|
+
state.seq = rnds[6] << 23 | rnds[7] << 16 | rnds[8] << 8 | rnds[9];
|
|
7320
|
+
state.msecs = now;
|
|
7321
|
+
} else {
|
|
7322
|
+
state.seq = state.seq + 1 | 0;
|
|
7323
|
+
if (state.seq === 0) state.msecs++;
|
|
7324
|
+
}
|
|
7325
|
+
return state;
|
|
7326
|
+
}
|
|
7327
|
+
function v7Bytes(rnds, msecs, seq, buf, offset = 0) {
|
|
7328
|
+
if (rnds.length < 16) throw new Error("Random bytes length must be >= 16");
|
|
7329
|
+
if (!buf) {
|
|
7330
|
+
buf = new Uint8Array(16);
|
|
7331
|
+
offset = 0;
|
|
7332
|
+
} else if (offset < 0 || offset + 16 > buf.length) throw new RangeError(`UUID byte range ${offset}:${offset + 15} is out of buffer bounds`);
|
|
7333
|
+
msecs ??= Date.now();
|
|
7334
|
+
seq ??= rnds[6] * 127 << 24 | rnds[7] << 16 | rnds[8] << 8 | rnds[9];
|
|
7335
|
+
buf[offset++] = msecs / 1099511627776 & 255;
|
|
7336
|
+
buf[offset++] = msecs / 4294967296 & 255;
|
|
7337
|
+
buf[offset++] = msecs / 16777216 & 255;
|
|
7338
|
+
buf[offset++] = msecs / 65536 & 255;
|
|
7339
|
+
buf[offset++] = msecs / 256 & 255;
|
|
7340
|
+
buf[offset++] = msecs & 255;
|
|
7341
|
+
buf[offset++] = 112 | seq >>> 28 & 15;
|
|
7342
|
+
buf[offset++] = seq >>> 20 & 255;
|
|
7343
|
+
buf[offset++] = 128 | seq >>> 14 & 63;
|
|
7344
|
+
buf[offset++] = seq >>> 6 & 255;
|
|
7345
|
+
buf[offset++] = seq << 2 & 255 | rnds[10] & 3;
|
|
7346
|
+
buf[offset++] = rnds[11];
|
|
7347
|
+
buf[offset++] = rnds[12];
|
|
7348
|
+
buf[offset++] = rnds[13];
|
|
7349
|
+
buf[offset++] = rnds[14];
|
|
7350
|
+
buf[offset++] = rnds[15];
|
|
7351
|
+
return buf;
|
|
7352
|
+
}
|
|
7353
|
+
|
|
7286
7354
|
//#endregion
|
|
7287
7355
|
//#region ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/core.js
|
|
7288
7356
|
var _a$1;
|
|
@@ -17926,74 +17994,6 @@ const execaNode = createExeca(mapNode);
|
|
|
17926
17994
|
const $ = createExeca(mapScriptAsync, {}, deepScriptOptions, setScriptSync);
|
|
17927
17995
|
const { sendMessage, getOneMessage, getEachMessage, getCancelSignal } = getIpcExport();
|
|
17928
17996
|
|
|
17929
|
-
//#endregion
|
|
17930
|
-
//#region ../../node_modules/.pnpm/uuid@14.0.0/node_modules/uuid/dist-node/rng.js
|
|
17931
|
-
const rnds8 = new Uint8Array(16);
|
|
17932
|
-
function rng() {
|
|
17933
|
-
return crypto.getRandomValues(rnds8);
|
|
17934
|
-
}
|
|
17935
|
-
|
|
17936
|
-
//#endregion
|
|
17937
|
-
//#region ../../node_modules/.pnpm/uuid@14.0.0/node_modules/uuid/dist-node/stringify.js
|
|
17938
|
-
const byteToHex = [];
|
|
17939
|
-
for (let i = 0; i < 256; ++i) byteToHex.push((i + 256).toString(16).slice(1));
|
|
17940
|
-
function unsafeStringify(arr, offset = 0) {
|
|
17941
|
-
return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase();
|
|
17942
|
-
}
|
|
17943
|
-
|
|
17944
|
-
//#endregion
|
|
17945
|
-
//#region ../../node_modules/.pnpm/uuid@14.0.0/node_modules/uuid/dist-node/v7.js
|
|
17946
|
-
const _state = {};
|
|
17947
|
-
function v7(options, buf, offset) {
|
|
17948
|
-
let bytes;
|
|
17949
|
-
if (options) bytes = v7Bytes(options.random ?? options.rng?.() ?? rng(), options.msecs, options.seq, buf, offset);
|
|
17950
|
-
else {
|
|
17951
|
-
const now = Date.now();
|
|
17952
|
-
const rnds = rng();
|
|
17953
|
-
updateV7State(_state, now, rnds);
|
|
17954
|
-
bytes = v7Bytes(rnds, _state.msecs, _state.seq, buf, offset);
|
|
17955
|
-
}
|
|
17956
|
-
return buf ?? unsafeStringify(bytes);
|
|
17957
|
-
}
|
|
17958
|
-
function updateV7State(state, now, rnds) {
|
|
17959
|
-
state.msecs ??= -Infinity;
|
|
17960
|
-
state.seq ??= 0;
|
|
17961
|
-
if (now > state.msecs) {
|
|
17962
|
-
state.seq = rnds[6] << 23 | rnds[7] << 16 | rnds[8] << 8 | rnds[9];
|
|
17963
|
-
state.msecs = now;
|
|
17964
|
-
} else {
|
|
17965
|
-
state.seq = state.seq + 1 | 0;
|
|
17966
|
-
if (state.seq === 0) state.msecs++;
|
|
17967
|
-
}
|
|
17968
|
-
return state;
|
|
17969
|
-
}
|
|
17970
|
-
function v7Bytes(rnds, msecs, seq, buf, offset = 0) {
|
|
17971
|
-
if (rnds.length < 16) throw new Error("Random bytes length must be >= 16");
|
|
17972
|
-
if (!buf) {
|
|
17973
|
-
buf = new Uint8Array(16);
|
|
17974
|
-
offset = 0;
|
|
17975
|
-
} else if (offset < 0 || offset + 16 > buf.length) throw new RangeError(`UUID byte range ${offset}:${offset + 15} is out of buffer bounds`);
|
|
17976
|
-
msecs ??= Date.now();
|
|
17977
|
-
seq ??= rnds[6] * 127 << 24 | rnds[7] << 16 | rnds[8] << 8 | rnds[9];
|
|
17978
|
-
buf[offset++] = msecs / 1099511627776 & 255;
|
|
17979
|
-
buf[offset++] = msecs / 4294967296 & 255;
|
|
17980
|
-
buf[offset++] = msecs / 16777216 & 255;
|
|
17981
|
-
buf[offset++] = msecs / 65536 & 255;
|
|
17982
|
-
buf[offset++] = msecs / 256 & 255;
|
|
17983
|
-
buf[offset++] = msecs & 255;
|
|
17984
|
-
buf[offset++] = 112 | seq >>> 28 & 15;
|
|
17985
|
-
buf[offset++] = seq >>> 20 & 255;
|
|
17986
|
-
buf[offset++] = 128 | seq >>> 14 & 63;
|
|
17987
|
-
buf[offset++] = seq >>> 6 & 255;
|
|
17988
|
-
buf[offset++] = seq << 2 & 255 | rnds[10] & 3;
|
|
17989
|
-
buf[offset++] = rnds[11];
|
|
17990
|
-
buf[offset++] = rnds[12];
|
|
17991
|
-
buf[offset++] = rnds[13];
|
|
17992
|
-
buf[offset++] = rnds[14];
|
|
17993
|
-
buf[offset++] = rnds[15];
|
|
17994
|
-
return buf;
|
|
17995
|
-
}
|
|
17996
|
-
|
|
17997
17997
|
//#endregion
|
|
17998
17998
|
//#region ../../node_modules/.pnpm/kind-of@6.0.3/node_modules/kind-of/index.js
|
|
17999
17999
|
var require_kind_of = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
@@ -29629,6 +29629,44 @@ function osUsername() {
|
|
|
29629
29629
|
|
|
29630
29630
|
//#endregion
|
|
29631
29631
|
//#region ../engine/dist/index.mjs
|
|
29632
|
+
function msToIso(ms) {
|
|
29633
|
+
return new Date(ms).toISOString();
|
|
29634
|
+
}
|
|
29635
|
+
const isoMsSchema = string().transform((value, ctx) => {
|
|
29636
|
+
const ms = Date.parse(value);
|
|
29637
|
+
if (Number.isNaN(ms)) {
|
|
29638
|
+
ctx.addIssue({
|
|
29639
|
+
code: "custom",
|
|
29640
|
+
message: "must be an ISO-8601 timestamp"
|
|
29641
|
+
});
|
|
29642
|
+
return NEVER;
|
|
29643
|
+
}
|
|
29644
|
+
return ms;
|
|
29645
|
+
});
|
|
29646
|
+
function isoToMs(iso, label) {
|
|
29647
|
+
const result = isoMsSchema.safeParse(iso);
|
|
29648
|
+
if (!result.success) throw new Error(`${label} is not a valid ISO-8601 timestamp: ${iso}`);
|
|
29649
|
+
return result.data;
|
|
29650
|
+
}
|
|
29651
|
+
function resolveAdHocWindow(input) {
|
|
29652
|
+
const window = input.lastMs !== void 0 ? {
|
|
29653
|
+
from: input.nowMs - input.lastMs,
|
|
29654
|
+
to: input.nowMs
|
|
29655
|
+
} : {
|
|
29656
|
+
from: input.fromMs ?? input.oldestMs,
|
|
29657
|
+
to: input.toMs ?? input.nowMs
|
|
29658
|
+
};
|
|
29659
|
+
if (window.from >= window.to) throw new Error(`adhoc window is empty: from (${msToIso(window.from)}) must be strictly before to (${msToIso(window.to)}).`);
|
|
29660
|
+
return window;
|
|
29661
|
+
}
|
|
29662
|
+
function buildAdHocSlice(tables, window) {
|
|
29663
|
+
const slice = {};
|
|
29664
|
+
for (const table of tables) slice[table] = {
|
|
29665
|
+
from: window.from,
|
|
29666
|
+
to: window.to
|
|
29667
|
+
};
|
|
29668
|
+
return slice;
|
|
29669
|
+
}
|
|
29632
29670
|
const SYNTHESIZERS_DIR_RELATIVE = ".agents/synthesizers";
|
|
29633
29671
|
const SAFE_ENGINE_NAME_PATTERN = /^[A-Za-z0-9._-]+$/u;
|
|
29634
29672
|
function assertSafeEngineName(name) {
|
|
@@ -29674,25 +29712,6 @@ function formatError(error) {
|
|
|
29674
29712
|
if (error instanceof Error) return error.message;
|
|
29675
29713
|
return String(error);
|
|
29676
29714
|
}
|
|
29677
|
-
function msToIso(ms) {
|
|
29678
|
-
return new Date(ms).toISOString();
|
|
29679
|
-
}
|
|
29680
|
-
const isoMsSchema = string().transform((value, ctx) => {
|
|
29681
|
-
const ms = Date.parse(value);
|
|
29682
|
-
if (Number.isNaN(ms)) {
|
|
29683
|
-
ctx.addIssue({
|
|
29684
|
-
code: "custom",
|
|
29685
|
-
message: "must be an ISO-8601 timestamp"
|
|
29686
|
-
});
|
|
29687
|
-
return NEVER;
|
|
29688
|
-
}
|
|
29689
|
-
return ms;
|
|
29690
|
-
});
|
|
29691
|
-
function isoToMs(iso, label) {
|
|
29692
|
-
const result = isoMsSchema.safeParse(iso);
|
|
29693
|
-
if (!result.success) throw new Error(`${label} is not a valid ISO-8601 timestamp: ${iso}`);
|
|
29694
|
-
return result.data;
|
|
29695
|
-
}
|
|
29696
29715
|
const cursorFileSchema = strictObject({
|
|
29697
29716
|
floors: record(string(), isoMsSchema),
|
|
29698
29717
|
frontier: isoMsSchema
|
|
@@ -29718,12 +29737,12 @@ async function writeCursor(rootDir, synthesizerName, cursor) {
|
|
|
29718
29737
|
}
|
|
29719
29738
|
const ENGINE_CONFIG_FILE_NAME = "engine.json";
|
|
29720
29739
|
const nonEmptyStringSchema$1 = string().trim().min(1);
|
|
29721
|
-
const DURATION_UNIT_MS = {
|
|
29740
|
+
const DURATION_UNIT_MS$1 = {
|
|
29722
29741
|
h: 36e5,
|
|
29723
29742
|
m: 6e4,
|
|
29724
29743
|
s: 1e3
|
|
29725
29744
|
};
|
|
29726
|
-
const durationMsSchema = string().transform((value, ctx) => {
|
|
29745
|
+
const durationMsSchema$1 = string().transform((value, ctx) => {
|
|
29727
29746
|
const match = /^(\d+)([hms])$/.exec(value);
|
|
29728
29747
|
if (match === null) {
|
|
29729
29748
|
ctx.addIssue({
|
|
@@ -29733,7 +29752,7 @@ const durationMsSchema = string().transform((value, ctx) => {
|
|
|
29733
29752
|
return NEVER;
|
|
29734
29753
|
}
|
|
29735
29754
|
const [, amount, unit] = match;
|
|
29736
|
-
return Number(amount) * DURATION_UNIT_MS[unit];
|
|
29755
|
+
return Number(amount) * DURATION_UNIT_MS$1[unit];
|
|
29737
29756
|
});
|
|
29738
29757
|
const microsandboxConfigSchema = record(string(), unknown()).superRefine((config, ctx) => {
|
|
29739
29758
|
if ("bindMounts" in config) ctx.addIssue({
|
|
@@ -29743,11 +29762,11 @@ const microsandboxConfigSchema = record(string(), unknown()).superRefine((config
|
|
|
29743
29762
|
});
|
|
29744
29763
|
}).optional();
|
|
29745
29764
|
const engineConfigSchema = strictObject({
|
|
29746
|
-
maxSliceSize: durationMsSchema.optional(),
|
|
29765
|
+
maxSliceSize: durationMsSchema$1.optional(),
|
|
29747
29766
|
microsandbox: microsandboxConfigSchema,
|
|
29748
29767
|
oldestConsideredPoint: isoMsSchema.optional(),
|
|
29749
29768
|
synthesizerImage: nonEmptyStringSchema$1.optional(),
|
|
29750
|
-
tick: durationMsSchema.optional()
|
|
29769
|
+
tick: durationMsSchema$1.optional()
|
|
29751
29770
|
});
|
|
29752
29771
|
function mergeEngineConfig(...inputs) {
|
|
29753
29772
|
return applyDefaults(Object.assign({}, ...inputs.map((input) => stripUndefined(input))));
|
|
@@ -29778,7 +29797,7 @@ function validate(raw, sourcePath) {
|
|
|
29778
29797
|
}
|
|
29779
29798
|
function applyDefaults(input) {
|
|
29780
29799
|
return {
|
|
29781
|
-
synthesizerImage: input.synthesizerImage ?? "ghcr.io/usecontextlayer/ctx-sandbox:0.4.
|
|
29800
|
+
synthesizerImage: input.synthesizerImage ?? "ghcr.io/usecontextlayer/ctx-sandbox:0.4.13",
|
|
29782
29801
|
...input.microsandbox !== void 0 ? { microsandbox: input.microsandbox } : {},
|
|
29783
29802
|
...input.oldestConsideredPoint !== void 0 ? { oldestConsideredPoint: input.oldestConsideredPoint } : {},
|
|
29784
29803
|
maxSliceSize: input.maxSliceSize ?? 864e5,
|
|
@@ -29796,14 +29815,12 @@ function formatZodError$1(error) {
|
|
|
29796
29815
|
}
|
|
29797
29816
|
function gatePasses(input) {
|
|
29798
29817
|
if (input.syncHorizon === null) return false;
|
|
29799
|
-
if (input.mode === "manual") return input.frontier < input.syncHorizon;
|
|
29800
29818
|
return input.syncHorizon - input.frontier >= input.tick;
|
|
29801
29819
|
}
|
|
29802
29820
|
function planLoopPass(input) {
|
|
29803
29821
|
const horizon = input.syncHorizon;
|
|
29804
29822
|
const horizonDue = horizon === null ? [] : input.synthesizers.filter((synthesizer) => gatePasses({
|
|
29805
29823
|
frontier: synthesizer.frontier,
|
|
29806
|
-
mode: "loop",
|
|
29807
29824
|
syncHorizon: horizon,
|
|
29808
29825
|
tick: input.tick
|
|
29809
29826
|
}));
|
|
@@ -30232,9 +30249,9 @@ function dirtyWorkingTreeIssue(paths) {
|
|
|
30232
30249
|
};
|
|
30233
30250
|
}
|
|
30234
30251
|
const runTriggerSchema = _enum([
|
|
30252
|
+
"adhoc",
|
|
30235
30253
|
"backfill",
|
|
30236
|
-
"daemon"
|
|
30237
|
-
"manual"
|
|
30254
|
+
"daemon"
|
|
30238
30255
|
]);
|
|
30239
30256
|
_enum([
|
|
30240
30257
|
"success",
|
|
@@ -30484,6 +30501,14 @@ function formatCombinedRepairError(repo, branch, tree) {
|
|
|
30484
30501
|
"Operator must inspect and choose the order manually."
|
|
30485
30502
|
].join("\n");
|
|
30486
30503
|
}
|
|
30504
|
+
function renderSliceJson(slice) {
|
|
30505
|
+
const windows = {};
|
|
30506
|
+
for (const [table, window] of Object.entries(slice)) windows[table] = {
|
|
30507
|
+
from: msToIso(window.from),
|
|
30508
|
+
to: msToIso(window.to)
|
|
30509
|
+
};
|
|
30510
|
+
return `${JSON.stringify(windows, null, " ")}\n`;
|
|
30511
|
+
}
|
|
30487
30512
|
const synthesizerSpecFrontmatterSchema = strictObject({
|
|
30488
30513
|
description: string().optional(),
|
|
30489
30514
|
name: string().trim().min(1)
|
|
@@ -30800,15 +30825,16 @@ function buildSandboxFilesystemPlan(input) {
|
|
|
30800
30825
|
const guestWorkdir = workspaceGuestPath(rootDir);
|
|
30801
30826
|
const bindMounts = [{
|
|
30802
30827
|
guestPath: outputGuestPath(rootDir),
|
|
30803
|
-
hostPath: path.join(rootDir, "output"),
|
|
30828
|
+
hostPath: input.outputHostDir ?? path.join(rootDir, "output"),
|
|
30804
30829
|
hostPathBehavior: "createDir",
|
|
30805
30830
|
mode: "rw"
|
|
30806
|
-
}
|
|
30831
|
+
}];
|
|
30832
|
+
if (input.mountTranscript ?? true) bindMounts.push({
|
|
30807
30833
|
guestPath: CLAUDE_PROJECTS_GUEST_PATH,
|
|
30808
30834
|
hostPath: claudeProjectsDirPath(rootDir),
|
|
30809
30835
|
hostPathBehavior: "createDir",
|
|
30810
30836
|
mode: "rw"
|
|
30811
|
-
}
|
|
30837
|
+
});
|
|
30812
30838
|
const textPatches = [
|
|
30813
30839
|
{
|
|
30814
30840
|
content: input.claudeMaterial.claudeJson,
|
|
@@ -31036,9 +31062,11 @@ async function executeSynthesizerRun(input) {
|
|
|
31036
31062
|
runId: input.runId,
|
|
31037
31063
|
sliceJson: input.sliceJson,
|
|
31038
31064
|
synthesizer: input.synthesizer,
|
|
31039
|
-
synthesizerImage: input.synthesizerImage
|
|
31065
|
+
synthesizerImage: input.synthesizerImage,
|
|
31066
|
+
...input.outputHostDir !== void 0 && { outputHostDir: input.outputHostDir },
|
|
31067
|
+
...input.mountTranscript !== void 0 && { mountTranscript: input.mountTranscript }
|
|
31040
31068
|
});
|
|
31041
|
-
const result = await input.executor.run(executorInput);
|
|
31069
|
+
const result = await input.executor.run(executorInput, input.hooks);
|
|
31042
31070
|
const completedAtMs = now().getTime();
|
|
31043
31071
|
const durationMs = Math.max(0, completedAtMs - startedAtMs);
|
|
31044
31072
|
const status = classifyOutcome(result.exitCode, result.observation);
|
|
@@ -31087,7 +31115,9 @@ function buildExecutorInput(input) {
|
|
|
31087
31115
|
sandboxName: buildSandboxName(input.synthesizer.name, input.runId),
|
|
31088
31116
|
sliceJson: input.sliceJson,
|
|
31089
31117
|
synthesizerBody: input.synthesizer.body,
|
|
31090
|
-
synthesizerName: input.synthesizer.name
|
|
31118
|
+
synthesizerName: input.synthesizer.name,
|
|
31119
|
+
...input.outputHostDir !== void 0 && { outputHostDir: input.outputHostDir },
|
|
31120
|
+
...input.mountTranscript !== void 0 && { mountTranscript: input.mountTranscript }
|
|
31091
31121
|
};
|
|
31092
31122
|
}
|
|
31093
31123
|
function buildContextEngineEnv(input) {
|
|
@@ -31167,14 +31197,6 @@ function reconcileCursor(input) {
|
|
|
31167
31197
|
frontier: input.prevCursor.frontier
|
|
31168
31198
|
};
|
|
31169
31199
|
}
|
|
31170
|
-
function renderSliceJson(slice) {
|
|
31171
|
-
const windows = {};
|
|
31172
|
-
for (const [table, window] of Object.entries(slice)) windows[table] = {
|
|
31173
|
-
from: msToIso(window.from),
|
|
31174
|
-
to: msToIso(window.to)
|
|
31175
|
-
};
|
|
31176
|
-
return `${JSON.stringify(windows, null, " ")}\n`;
|
|
31177
|
-
}
|
|
31178
31200
|
const DEFAULT_OLDEST_LOOKBACK_MS = 720 * 60 * 60 * 1e3;
|
|
31179
31201
|
function resolveOldest(config, beginMs) {
|
|
31180
31202
|
return config.oldestConsideredPoint ?? beginMs - DEFAULT_OLDEST_LOOKBACK_MS;
|
|
@@ -31195,14 +31217,7 @@ async function openSynthesizerTransaction(input) {
|
|
|
31195
31217
|
trigger: input.trigger
|
|
31196
31218
|
});
|
|
31197
31219
|
await writeRunRecord(runDir, startingRecord);
|
|
31198
|
-
const watermark = await input.watermarkCapture(
|
|
31199
|
-
rootDir: input.repo.rootDir,
|
|
31200
|
-
runDir,
|
|
31201
|
-
runId,
|
|
31202
|
-
startedAt,
|
|
31203
|
-
synthesizer: input.synthesizer,
|
|
31204
|
-
trigger: input.trigger
|
|
31205
|
-
});
|
|
31220
|
+
const watermark = await input.watermarkCapture();
|
|
31206
31221
|
const persistedCursor = await readCursor(input.repo.rootDir, input.synthesizer.name);
|
|
31207
31222
|
const planConfig = {
|
|
31208
31223
|
maxSliceSize: input.config.maxSliceSize,
|
|
@@ -31372,26 +31387,38 @@ var Engine = class {
|
|
|
31372
31387
|
this.daemonRunning = false;
|
|
31373
31388
|
}
|
|
31374
31389
|
}
|
|
31375
|
-
async
|
|
31376
|
-
await this.
|
|
31390
|
+
async runAdHoc(input) {
|
|
31391
|
+
const synthesizer = await this.ensureSynthesizerLoaded(input.synthesizerName);
|
|
31377
31392
|
const config = this.requireConfig();
|
|
31378
|
-
const
|
|
31379
|
-
const
|
|
31380
|
-
|
|
31381
|
-
|
|
31382
|
-
|
|
31383
|
-
|
|
31384
|
-
|
|
31385
|
-
|
|
31386
|
-
const { record } = await this.runSynthesizerTransaction({
|
|
31387
|
-
syncHorizon,
|
|
31388
|
-
synthesizerName,
|
|
31389
|
-
trigger: "manual"
|
|
31393
|
+
const begin = this.nowDate();
|
|
31394
|
+
const nowMs = begin.getTime();
|
|
31395
|
+
const window = resolveAdHocWindow({
|
|
31396
|
+
nowMs,
|
|
31397
|
+
oldestMs: resolveOldest(config, nowMs),
|
|
31398
|
+
...input.fromMs !== void 0 && { fromMs: input.fromMs },
|
|
31399
|
+
...input.toMs !== void 0 && { toMs: input.toMs },
|
|
31400
|
+
...input.lastMs !== void 0 && { lastMs: input.lastMs }
|
|
31390
31401
|
});
|
|
31391
|
-
|
|
31392
|
-
|
|
31393
|
-
|
|
31394
|
-
|
|
31402
|
+
const watermark = await this.watermarkCapture();
|
|
31403
|
+
const sliceJson = renderSliceJson(buildAdHocSlice(Object.keys(watermark), window));
|
|
31404
|
+
const runId = assertSafeEngineName((this.runIdFactory ?? v7)());
|
|
31405
|
+
return (await executeSynthesizerRun({
|
|
31406
|
+
databaseUrl: this.databaseUrl,
|
|
31407
|
+
executor: this.executor,
|
|
31408
|
+
logger: this.logger,
|
|
31409
|
+
mountTranscript: false,
|
|
31410
|
+
outputHostDir: input.outputDir,
|
|
31411
|
+
rootDir: this.repo.rootDir,
|
|
31412
|
+
runId,
|
|
31413
|
+
sliceJson,
|
|
31414
|
+
startedAt: begin.toISOString(),
|
|
31415
|
+
synthesizer,
|
|
31416
|
+
synthesizerImage: config.synthesizerImage,
|
|
31417
|
+
trigger: "adhoc",
|
|
31418
|
+
...config.microsandbox !== void 0 && { microsandboxConfig: config.microsandbox },
|
|
31419
|
+
...this.now !== void 0 && { now: this.now },
|
|
31420
|
+
...input.hooks !== void 0 && { hooks: input.hooks }
|
|
31421
|
+
})).outcome;
|
|
31395
31422
|
}
|
|
31396
31423
|
async backfill(synthesizerName, options = {}) {
|
|
31397
31424
|
await this.prepareSynthesizerRun(synthesizerName);
|
|
@@ -31494,9 +31521,14 @@ var Engine = class {
|
|
|
31494
31521
|
async prepareSynthesizerRun(synthesizerName) {
|
|
31495
31522
|
const report = await runRootPreflight(this.repo);
|
|
31496
31523
|
if (!report.ready) throw new Error(formatPreflightFailure(this.repo.rootDir, report.issues));
|
|
31524
|
+
await this.ensureSynthesizerLoaded(synthesizerName);
|
|
31525
|
+
}
|
|
31526
|
+
async ensureSynthesizerLoaded(synthesizerName) {
|
|
31497
31527
|
await this.ensureLoaded();
|
|
31498
31528
|
await this.refreshSynthesizers();
|
|
31499
|
-
|
|
31529
|
+
const synthesizer = this.synthesizers.get(synthesizerName);
|
|
31530
|
+
if (!synthesizer) throw new Error(`Unknown synthesizer '${synthesizerName}'.`);
|
|
31531
|
+
return synthesizer;
|
|
31500
31532
|
}
|
|
31501
31533
|
async runSynthesizerTransaction(request) {
|
|
31502
31534
|
const releaseLock = await acquireTransactionLock(this.repo.rootDir);
|
|
@@ -31761,6 +31793,7 @@ async function drainExecStream(handle, options) {
|
|
|
31761
31793
|
if (settled.kind === "stderr") options.onStderr(settled.data);
|
|
31762
31794
|
else if (settled.kind === "stdout") {
|
|
31763
31795
|
observer.feed(settled.data);
|
|
31796
|
+
options.onStdout(settled.data);
|
|
31764
31797
|
if (resultSeenAt === void 0 && observer.resultSeen) resultSeenAt = lastEventAt;
|
|
31765
31798
|
} else if (settled.kind === "exited") return {
|
|
31766
31799
|
exitCode: settled.code,
|
|
@@ -31770,7 +31803,7 @@ async function drainExecStream(handle, options) {
|
|
|
31770
31803
|
}
|
|
31771
31804
|
}
|
|
31772
31805
|
var MicrosandboxClaudeExecutor = class {
|
|
31773
|
-
async run(input) {
|
|
31806
|
+
async run(input, hooks) {
|
|
31774
31807
|
const microsandbox = await import("microsandbox");
|
|
31775
31808
|
const runPlan = buildMicrosandboxClaudeRunPlan(input);
|
|
31776
31809
|
const stderrParts = [];
|
|
@@ -31789,7 +31822,9 @@ var MicrosandboxClaudeExecutor = class {
|
|
|
31789
31822
|
guestEnv: runPlan.microsandboxConfig.env,
|
|
31790
31823
|
rootDir: input.rootDir,
|
|
31791
31824
|
sliceJson: input.sliceJson,
|
|
31792
|
-
synthesizerBody: input.synthesizerBody
|
|
31825
|
+
synthesizerBody: input.synthesizerBody,
|
|
31826
|
+
...input.outputHostDir !== void 0 && { outputHostDir: input.outputHostDir },
|
|
31827
|
+
...input.mountTranscript !== void 0 && { mountTranscript: input.mountTranscript }
|
|
31793
31828
|
});
|
|
31794
31829
|
await ensureHostFilesystemReady(fsPlan);
|
|
31795
31830
|
let builder = microsandbox.Sandbox.builder(runPlan.sandboxName).image(runPlan.image).memory(GUEST_MEMORY_MIB).replace();
|
|
@@ -31798,14 +31833,23 @@ var MicrosandboxClaudeExecutor = class {
|
|
|
31798
31833
|
sandbox = await builder.create();
|
|
31799
31834
|
const [cmd, ...args] = runPlan.command;
|
|
31800
31835
|
const stderrDecoder = new TextDecoder("utf-8", { fatal: false });
|
|
31836
|
+
const stdoutDecoder = new TextDecoder("utf-8", { fatal: false });
|
|
31801
31837
|
try {
|
|
31802
31838
|
const drained = await drainExecStream(await sandbox.execStreamWith(cmd, (e) => e.args(args)), {
|
|
31803
31839
|
inactivityMs: EXEC_INACTIVITY_TIMEOUT_MS,
|
|
31804
31840
|
maxDurationMs: EXEC_MAX_DURATION_MS,
|
|
31805
|
-
onStderr: (data) =>
|
|
31841
|
+
onStderr: (data) => {
|
|
31842
|
+
const text = stderrDecoder.decode(data, { stream: true });
|
|
31843
|
+
stderrParts.push(text);
|
|
31844
|
+
hooks?.onStderr?.(text);
|
|
31845
|
+
},
|
|
31846
|
+
onStdout: (data) => {
|
|
31847
|
+
if (hooks?.onStdout) hooks.onStdout(stdoutDecoder.decode(data, { stream: true }));
|
|
31848
|
+
},
|
|
31806
31849
|
resultGraceMs: EXEC_RESULT_GRACE_MS
|
|
31807
31850
|
});
|
|
31808
31851
|
stderrParts.push(stderrDecoder.decode());
|
|
31852
|
+
hooks?.onStdout?.(stdoutDecoder.decode());
|
|
31809
31853
|
observation = drained.observation;
|
|
31810
31854
|
if (drained.kind === "exited") exitCode = drained.exitCode;
|
|
31811
31855
|
else if (drained.kind === "result_no_exit") {
|
|
@@ -32151,6 +32195,62 @@ async function runEngineLogsCommand(synthesizerName, options, paths) {
|
|
|
32151
32195
|
}));
|
|
32152
32196
|
}
|
|
32153
32197
|
|
|
32198
|
+
//#endregion
|
|
32199
|
+
//#region commands/adhoc.ts
|
|
32200
|
+
const DURATION_UNIT_MS = {
|
|
32201
|
+
d: 864e5,
|
|
32202
|
+
h: 36e5,
|
|
32203
|
+
m: 6e4,
|
|
32204
|
+
s: 1e3
|
|
32205
|
+
};
|
|
32206
|
+
const durationMsSchema = string().transform((value, ctx) => {
|
|
32207
|
+
const match = /^(\d+)(d|h|m|s)$/.exec(value);
|
|
32208
|
+
if (match === null) {
|
|
32209
|
+
ctx.addIssue({
|
|
32210
|
+
code: "custom",
|
|
32211
|
+
message: "must be a duration like \"7d\", \"12h\", \"30m\", or \"45s\""
|
|
32212
|
+
});
|
|
32213
|
+
return NEVER;
|
|
32214
|
+
}
|
|
32215
|
+
const [, amount, unit] = match;
|
|
32216
|
+
return Number(amount) * DURATION_UNIT_MS[unit];
|
|
32217
|
+
});
|
|
32218
|
+
const adHocWindowSchema = object({
|
|
32219
|
+
from: isoMsSchema.optional(),
|
|
32220
|
+
last: durationMsSchema.optional(),
|
|
32221
|
+
to: isoMsSchema.optional()
|
|
32222
|
+
}).refine((window) => window.last !== void 0 !== (window.from !== void 0 || window.to !== void 0), { message: "provide --last, or at least one of --from/--to (not both)" });
|
|
32223
|
+
async function runAdHocCommand(input) {
|
|
32224
|
+
const window = adHocWindowSchema.parse({
|
|
32225
|
+
...input.from !== void 0 && { from: input.from },
|
|
32226
|
+
...input.to !== void 0 && { to: input.to },
|
|
32227
|
+
...input.last !== void 0 && { last: input.last }
|
|
32228
|
+
});
|
|
32229
|
+
const engine = buildEngine({
|
|
32230
|
+
databaseUrl: resolveDatabaseUrl({ cliValue: input.databaseUrl }),
|
|
32231
|
+
paths: input.paths
|
|
32232
|
+
});
|
|
32233
|
+
const outputDir = resolve(input.out);
|
|
32234
|
+
const outcome = await engine.runAdHoc({
|
|
32235
|
+
hooks: {
|
|
32236
|
+
onStderr: (chunk) => process.stderr.write(chunk),
|
|
32237
|
+
onStdout: (chunk) => process.stdout.write(chunk)
|
|
32238
|
+
},
|
|
32239
|
+
outputDir,
|
|
32240
|
+
synthesizerName: input.synthesizerName,
|
|
32241
|
+
...window.from !== void 0 && { fromMs: window.from },
|
|
32242
|
+
...window.to !== void 0 && { toMs: window.to },
|
|
32243
|
+
...window.last !== void 0 && { lastMs: window.last }
|
|
32244
|
+
});
|
|
32245
|
+
process.stderr.write(`${formatJsonOutput({
|
|
32246
|
+
durationMs: outcome.durationMs,
|
|
32247
|
+
exitCode: outcome.exitCode,
|
|
32248
|
+
out: outputDir,
|
|
32249
|
+
status: outcome.status
|
|
32250
|
+
})}\n`);
|
|
32251
|
+
if (outcome.status !== "success") process.exitCode = 1;
|
|
32252
|
+
}
|
|
32253
|
+
|
|
32154
32254
|
//#endregion
|
|
32155
32255
|
//#region commands/backfill.ts
|
|
32156
32256
|
async function runBackfillCommand(input) {
|
|
@@ -32205,21 +32305,6 @@ async function runResetCommand(input) {
|
|
|
32205
32305
|
process.stdout.write(`${formatJsonOutput(result)}\n`);
|
|
32206
32306
|
}
|
|
32207
32307
|
|
|
32208
|
-
//#endregion
|
|
32209
|
-
//#region commands/run.ts
|
|
32210
|
-
async function runRunCommand(input) {
|
|
32211
|
-
const outcome = await buildEngine({
|
|
32212
|
-
databaseUrl: resolveDatabaseUrl({ cliValue: input.databaseUrl }),
|
|
32213
|
-
paths: input.paths
|
|
32214
|
-
}).runOnce(input.synthesizerName);
|
|
32215
|
-
if (outcome.kind === "caught_up") {
|
|
32216
|
-
process.stdout.write(`${formatJsonOutput({ status: "caught_up" })}\n`);
|
|
32217
|
-
return;
|
|
32218
|
-
}
|
|
32219
|
-
process.stdout.write(`${formatJsonOutput(outcome.record)}\n`);
|
|
32220
|
-
if (outcome.record.status !== "success") process.exitCode = 1;
|
|
32221
|
-
}
|
|
32222
|
-
|
|
32223
32308
|
//#endregion
|
|
32224
32309
|
//#region commands/start.ts
|
|
32225
32310
|
async function runStartCommand(input) {
|
|
@@ -32319,11 +32404,15 @@ function createProgram() {
|
|
|
32319
32404
|
yes: options.yes ?? false
|
|
32320
32405
|
});
|
|
32321
32406
|
});
|
|
32322
|
-
program.command("
|
|
32323
|
-
await
|
|
32407
|
+
program.command("adhoc").argument("<synthesizer>", "Synthesizer name").option("--from <iso>", "Window start (ISO-8601, exclusive). Defaults to the engine's oldestConsideredPoint when omitted.").option("--to <iso>", "Window end (ISO-8601, inclusive). Defaults to now when omitted.").option("--last <duration>", "Relative window ending now, e.g. \"7d\", \"12h\", \"30m\". Mutually exclusive with --from/--to.").requiredOption("--out <dir>", "Directory the synthesized output is written to. Used exactly as-is (created if missing); the synthesizer reads its current contents as prior output.").option("--database-url <url>", "Postgres URL of the ContextBase database the synthesizer reads from. Falls back to CTXB_DATABASE_URL.").description("Ephemeral authoring run: run a synthesizer once over an explicit window into --out, reading your live (uncommitted) synthesizer.md and output/types. Touches nothing durable — no preflight, no sync horizon, no cursor, no commit, no push. Streams the run to stdout; saves no transcript. Exits non-zero on a non-success run.").action(async function(synthesizerName, options) {
|
|
32408
|
+
await runAdHocCommand({
|
|
32324
32409
|
databaseUrl: options.databaseUrl,
|
|
32410
|
+
from: options.from,
|
|
32411
|
+
last: options.last,
|
|
32412
|
+
out: options.out,
|
|
32325
32413
|
paths: resolveRuntimePaths(this),
|
|
32326
|
-
synthesizerName
|
|
32414
|
+
synthesizerName,
|
|
32415
|
+
to: options.to
|
|
32327
32416
|
});
|
|
32328
32417
|
});
|
|
32329
32418
|
program.command("backfill").argument("<synthesizer>", "Synthesizer name").option("--database-url <url>", "Postgres URL of the ContextBase database the synthesizer reads from. Falls back to CTXB_DATABASE_URL.").description("Walk a synthesizer's cursor forward slice-by-slice until it catches up to the sync horizon. The same loop the daemon runs, without the sleep. Streams each slice's run record; prints a summary; exits non-zero if a slice fails or the usage window is rate-limited.").action(async function(synthesizerName, options) {
|
|
@@ -32362,4 +32451,4 @@ runCli().catch((error) => {
|
|
|
32362
32451
|
//#endregion
|
|
32363
32452
|
export { createProgram, resolveRepoContext, resolveRuntimePaths, runCli };
|
|
32364
32453
|
//# sourceMappingURL=cli.mjs.map
|
|
32365
|
-
//# debugId=
|
|
32454
|
+
//# debugId=ef06741d-8451-516d-a05b-dd7da1f526a8
|