bazilion 0.20.0 → 0.21.0-beta.2
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.js +430 -369
- package/dist/cli.js.map +1 -1
- package/dist/daemon.js +811 -488
- package/dist/daemon.js.map +1 -1
- package/dist/migrations/0001_init.sql +2 -1
- package/dist/migrations/0002_device_token_scopes.sql +8 -0
- package/dist/migrations/0003_web_pairing_tokens.sql +18 -0
- package/dist/web/client/assets/{ChatPane-CGCtAuD3.js → ChatPane--0BWZYHD.js} +1 -1
- package/dist/web/client/assets/{ConfirmDialog-Br19uXWH.js → ConfirmDialog-D9AiLH_Z.js} +1 -1
- package/dist/web/client/assets/{FieldRow-Csy3_cH5.js → FieldRow-Cd0EUpYd.js} +1 -1
- package/dist/web/client/assets/{ProductionTeamPolicyEditor-DG1x4Cqz.js → ProductionTeamPolicyEditor-BR5_1Wyv.js} +1 -1
- package/dist/web/client/assets/{ProfileCommunicationEditor-C3odNVkK.js → ProfileCommunicationEditor-K2wGbGky.js} +1 -1
- package/dist/web/client/assets/{ResultSourceConversation-5PFWqXTY.js → ResultSourceConversation-Y9VTd-nz.js} +1 -1
- package/dist/web/client/assets/{TeamTabs-BHB_COm0.js → TeamTabs-Yuc_lSZ9.js} +1 -1
- package/dist/web/client/assets/{TemplatesTabs-YyytjW7k.js → TemplatesTabs-Pj00chC7.js} +1 -1
- package/dist/web/client/assets/{UnsavedChangesGuard-CredyC3E.js → UnsavedChangesGuard-BSfJZH7E.js} +1 -1
- package/dist/web/client/assets/{_id-CIkPtQY0.js → _id-B4yPnTNN.js} +1 -1
- package/dist/web/client/assets/{_id-KXX6nuKc.js → _id-CUbb0F4l.js} +1 -1
- package/dist/web/client/assets/{_id-BZ_-4M4s.js → _id-D2l33vb6.js} +1 -1
- package/dist/web/client/assets/{_id-BLm9LVlZ.js → _id-DCFRZAJN.js} +1 -1
- package/dist/web/client/assets/{_id-nDbQY7f_.js → _id-UniNI3bQ.js} +1 -1
- package/dist/web/client/assets/{activity-BE7jG1Mz.js → activity-C5QG0Wgv.js} +1 -1
- package/dist/web/client/assets/{agents-S9lzXrrs.js → agents-CQo9V1lc.js} +1 -1
- package/dist/web/client/assets/{agents-vOPd-upn.js → agents-DVVPYxPM.js} +1 -1
- package/dist/web/client/assets/{approvals-BUfhlUAX.js → approvals-DQz6TJE8.js} +1 -1
- package/dist/web/client/assets/{attention-C3r-2GSp.js → attention-BtCLaWhZ.js} +1 -1
- package/dist/web/client/assets/chevron-right-BGFokHDA.js +1 -0
- package/dist/web/client/assets/{config-AL_EM57n.js → config-DuhKvD0X.js} +1 -1
- package/dist/web/client/assets/{inbox-LlCpJrMH.js → inbox-Cr7iGkrF.js} +1 -1
- package/dist/web/client/assets/{index-CwMw0pnV.js → index-ChXVa4eb.js} +2 -2
- package/dist/web/client/assets/{learning-zvTJ_9vM.js → learning-5eO_SZUP.js} +1 -1
- package/dist/web/client/assets/{login-BpQ54z8Y.js → login-Cn9mf44C.js} +1 -1
- package/dist/web/client/assets/{mcp-BD6VzXg_.js → mcp-0COajQD4.js} +1 -1
- package/dist/web/client/assets/{members-SEDi8SFo.js → members-9eTmy1QM.js} +1 -1
- package/dist/web/client/assets/{memory-zi_dPlMA.js → memory-CExQd_vP.js} +1 -1
- package/dist/web/client/assets/{policy-URjQAAdN.js → policy-B-zDlt_G.js} +1 -1
- package/dist/web/client/assets/{results-Bcuy4Flp.js → results-BUmKkuHo.js} +1 -1
- package/dist/web/client/assets/{review-CVH7X9-d.js → review-BUTz_zRX.js} +1 -1
- package/dist/web/client/assets/{routes-BJEX6yAE.js → routes-b1FscQsH.js} +1 -1
- package/dist/web/client/assets/{services-BTG4F5FL.js → services-D-RdMc8g.js} +1 -1
- package/dist/web/client/assets/{skills-DwiHS7eD.js → skills-CNbkY2ji.js} +1 -1
- package/dist/web/client/assets/{teams-DfpwQu1i.js → teams-Dn9o_-P-.js} +1 -1
- package/dist/web/client/assets/{teams-DcROmSGB.js → teams-H4OTWt8E.js} +1 -1
- package/dist/web/client/assets/{telegram-BLyaaUXE.js → telegram-BnM54CPN.js} +1 -1
- package/dist/web/client/assets/tokens-C-I23fVZ.js +1 -0
- package/dist/web/client/assets/{triggers-CtVhrAGA.js → triggers-DG9YoC7B.js} +1 -1
- package/dist/web/client/assets/{verifications-TC0ccGLY.js → verifications-CzToBSUN.js} +1 -1
- package/dist/web/client/assets/{welcome-DML3X1ha.js → welcome-REp-dEfY.js} +1 -1
- package/dist/web/client/assets/{x-D8yuCam7.js → x-C-BpLdcp.js} +1 -1
- package/dist/web/server/assets/{_tanstack-start-manifest_v-BGSoO6CK.js → _tanstack-start-manifest_v-BfURdqEL.js} +82 -82
- package/dist/web/server/assets/{router-BVhdWkwP.js → router-CyZ-GH8M.js} +1 -1
- package/dist/web/server/assets/{tokens-_2hptHP6.js → tokens-BFhrz5qd.js} +1 -1
- package/dist/web/server/assets/{tokens-DDwtO15P.js → tokens-DO_eDpv_.js} +96 -3
- package/dist/web/server/server.js +2 -2
- package/dist/worker.js +127 -90
- package/dist/worker.js.map +1 -1
- package/package.json +3 -3
- package/dist/web/client/assets/chevron-right-C7P3Z105.js +0 -1
- package/dist/web/client/assets/tokens-Dp9Vwvfx.js +0 -1
package/dist/daemon.js
CHANGED
|
@@ -135,12 +135,12 @@ var require_isexe = __commonJS({
|
|
|
135
135
|
if (typeof Promise !== "function") {
|
|
136
136
|
throw new TypeError("callback not provided");
|
|
137
137
|
}
|
|
138
|
-
return new Promise(function(
|
|
138
|
+
return new Promise(function(resolve9, reject2) {
|
|
139
139
|
isexe(path, options || {}, function(er, is) {
|
|
140
140
|
if (er) {
|
|
141
141
|
reject2(er);
|
|
142
142
|
} else {
|
|
143
|
-
|
|
143
|
+
resolve9(is);
|
|
144
144
|
}
|
|
145
145
|
});
|
|
146
146
|
});
|
|
@@ -207,27 +207,27 @@ var require_which = __commonJS({
|
|
|
207
207
|
opt = {};
|
|
208
208
|
const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
|
|
209
209
|
const found = [];
|
|
210
|
-
const step = (i) => new Promise((
|
|
210
|
+
const step = (i) => new Promise((resolve9, reject2) => {
|
|
211
211
|
if (i === pathEnv.length)
|
|
212
|
-
return opt.all && found.length ?
|
|
212
|
+
return opt.all && found.length ? resolve9(found) : reject2(getNotFoundError(cmd));
|
|
213
213
|
const ppRaw = pathEnv[i];
|
|
214
214
|
const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
|
|
215
215
|
const pCmd = path.join(pathPart, cmd);
|
|
216
216
|
const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
|
|
217
|
-
|
|
217
|
+
resolve9(subStep(p, i, 0));
|
|
218
218
|
});
|
|
219
|
-
const subStep = (p, i, ii) => new Promise((
|
|
219
|
+
const subStep = (p, i, ii) => new Promise((resolve9, reject2) => {
|
|
220
220
|
if (ii === pathExt.length)
|
|
221
|
-
return
|
|
221
|
+
return resolve9(step(i + 1));
|
|
222
222
|
const ext = pathExt[ii];
|
|
223
223
|
isexe(p + ext, { pathExt: pathExtExe }, (er, is) => {
|
|
224
224
|
if (!er && is) {
|
|
225
225
|
if (opt.all)
|
|
226
226
|
found.push(p + ext);
|
|
227
227
|
else
|
|
228
|
-
return
|
|
228
|
+
return resolve9(p + ext);
|
|
229
229
|
}
|
|
230
|
-
return
|
|
230
|
+
return resolve9(subStep(p, i, ii + 1));
|
|
231
231
|
});
|
|
232
232
|
});
|
|
233
233
|
return cb ? step(0).then((res) => cb(null, res), cb) : step(0);
|
|
@@ -7796,7 +7796,7 @@ var init_stdio2 = __esm({
|
|
|
7796
7796
|
if (this._process) {
|
|
7797
7797
|
throw new Error("StdioClientTransport already started! If using Client class, note that connect() calls start() automatically.");
|
|
7798
7798
|
}
|
|
7799
|
-
return new Promise((
|
|
7799
|
+
return new Promise((resolve9, reject2) => {
|
|
7800
7800
|
this._process = (0, import_cross_spawn.default)(this._serverParams.command, this._serverParams.args ?? [], {
|
|
7801
7801
|
// merge default env with server env because mcp server needs some env vars
|
|
7802
7802
|
env: {
|
|
@@ -7813,7 +7813,7 @@ var init_stdio2 = __esm({
|
|
|
7813
7813
|
this.onerror?.(error2);
|
|
7814
7814
|
});
|
|
7815
7815
|
this._process.on("spawn", () => {
|
|
7816
|
-
|
|
7816
|
+
resolve9();
|
|
7817
7817
|
});
|
|
7818
7818
|
this._process.on("close", (_code) => {
|
|
7819
7819
|
this._process = void 0;
|
|
@@ -7872,22 +7872,22 @@ var init_stdio2 = __esm({
|
|
|
7872
7872
|
if (this._process) {
|
|
7873
7873
|
const processToClose = this._process;
|
|
7874
7874
|
this._process = void 0;
|
|
7875
|
-
const closePromise = new Promise((
|
|
7875
|
+
const closePromise = new Promise((resolve9) => {
|
|
7876
7876
|
processToClose.once("close", () => {
|
|
7877
|
-
|
|
7877
|
+
resolve9();
|
|
7878
7878
|
});
|
|
7879
7879
|
});
|
|
7880
7880
|
try {
|
|
7881
7881
|
processToClose.stdin?.end();
|
|
7882
7882
|
} catch {
|
|
7883
7883
|
}
|
|
7884
|
-
await Promise.race([closePromise, new Promise((
|
|
7884
|
+
await Promise.race([closePromise, new Promise((resolve9) => setTimeout(resolve9, 2e3).unref())]);
|
|
7885
7885
|
if (processToClose.exitCode === null) {
|
|
7886
7886
|
try {
|
|
7887
7887
|
processToClose.kill("SIGTERM");
|
|
7888
7888
|
} catch {
|
|
7889
7889
|
}
|
|
7890
|
-
await Promise.race([closePromise, new Promise((
|
|
7890
|
+
await Promise.race([closePromise, new Promise((resolve9) => setTimeout(resolve9, 2e3).unref())]);
|
|
7891
7891
|
}
|
|
7892
7892
|
if (processToClose.exitCode === null) {
|
|
7893
7893
|
try {
|
|
@@ -7899,15 +7899,15 @@ var init_stdio2 = __esm({
|
|
|
7899
7899
|
this._readBuffer.clear();
|
|
7900
7900
|
}
|
|
7901
7901
|
send(message) {
|
|
7902
|
-
return new Promise((
|
|
7902
|
+
return new Promise((resolve9) => {
|
|
7903
7903
|
if (!this._process?.stdin) {
|
|
7904
7904
|
throw new Error("Not connected");
|
|
7905
7905
|
}
|
|
7906
7906
|
const json = serializeMessage(message);
|
|
7907
7907
|
if (this._process.stdin.write(json)) {
|
|
7908
|
-
|
|
7908
|
+
resolve9();
|
|
7909
7909
|
} else {
|
|
7910
|
-
this._process.stdin.once("drain",
|
|
7910
|
+
this._process.stdin.once("drain", resolve9);
|
|
7911
7911
|
}
|
|
7912
7912
|
});
|
|
7913
7913
|
}
|
|
@@ -7956,8 +7956,8 @@ async function random(size) {
|
|
|
7956
7956
|
const evenDistCutoff = Math.pow(2, 8) - Math.pow(2, 8) % mask2.length;
|
|
7957
7957
|
let result = "";
|
|
7958
7958
|
while (result.length < size) {
|
|
7959
|
-
const
|
|
7960
|
-
for (const randomByte of
|
|
7959
|
+
const randomBytes7 = await getRandomValues(size - result.length);
|
|
7960
|
+
for (const randomByte of randomBytes7) {
|
|
7961
7961
|
if (randomByte < evenDistCutoff) {
|
|
7962
7962
|
result += mask2[randomByte % mask2.length];
|
|
7963
7963
|
}
|
|
@@ -9803,7 +9803,7 @@ var init_sse = __esm({
|
|
|
9803
9803
|
}
|
|
9804
9804
|
_startOrAuth() {
|
|
9805
9805
|
const fetchImpl = this?._eventSourceInit?.fetch ?? this._fetch ?? fetch;
|
|
9806
|
-
return new Promise((
|
|
9806
|
+
return new Promise((resolve9, reject2) => {
|
|
9807
9807
|
this._eventSource = new EventSource(this._url.href, {
|
|
9808
9808
|
...this._eventSourceInit,
|
|
9809
9809
|
fetch: async (url2, init) => {
|
|
@@ -9824,7 +9824,7 @@ var init_sse = __esm({
|
|
|
9824
9824
|
this._abortController = new AbortController();
|
|
9825
9825
|
this._eventSource.onerror = (event2) => {
|
|
9826
9826
|
if (event2.code === 401 && this._authProvider) {
|
|
9827
|
-
this._authThenStart().then(
|
|
9827
|
+
this._authThenStart().then(resolve9, reject2);
|
|
9828
9828
|
return;
|
|
9829
9829
|
}
|
|
9830
9830
|
const error2 = new SseError(event2.code, event2.message, event2);
|
|
@@ -9846,7 +9846,7 @@ var init_sse = __esm({
|
|
|
9846
9846
|
void this.close();
|
|
9847
9847
|
return;
|
|
9848
9848
|
}
|
|
9849
|
-
|
|
9849
|
+
resolve9();
|
|
9850
9850
|
});
|
|
9851
9851
|
this._eventSource.onmessage = (event2) => {
|
|
9852
9852
|
const messageEvent = event2;
|
|
@@ -11016,7 +11016,7 @@ var init_protocol = __esm({
|
|
|
11016
11016
|
return;
|
|
11017
11017
|
}
|
|
11018
11018
|
const pollInterval = task2.pollInterval ?? this._options?.defaultTaskPollInterval ?? 1e3;
|
|
11019
|
-
await new Promise((
|
|
11019
|
+
await new Promise((resolve9) => setTimeout(resolve9, pollInterval));
|
|
11020
11020
|
options?.signal?.throwIfAborted();
|
|
11021
11021
|
}
|
|
11022
11022
|
} catch (error2) {
|
|
@@ -11033,7 +11033,7 @@ var init_protocol = __esm({
|
|
|
11033
11033
|
*/
|
|
11034
11034
|
request(request2, resultSchema, options) {
|
|
11035
11035
|
const { relatedRequestId, resumptionToken, onresumptiontoken, task, relatedTask } = options ?? {};
|
|
11036
|
-
return new Promise((
|
|
11036
|
+
return new Promise((resolve9, reject2) => {
|
|
11037
11037
|
const earlyReject = (error2) => {
|
|
11038
11038
|
reject2(error2);
|
|
11039
11039
|
};
|
|
@@ -11111,7 +11111,7 @@ var init_protocol = __esm({
|
|
|
11111
11111
|
if (!parseResult.success) {
|
|
11112
11112
|
reject2(parseResult.error);
|
|
11113
11113
|
} else {
|
|
11114
|
-
|
|
11114
|
+
resolve9(parseResult.data);
|
|
11115
11115
|
}
|
|
11116
11116
|
} catch (error2) {
|
|
11117
11117
|
reject2(error2);
|
|
@@ -11372,12 +11372,12 @@ var init_protocol = __esm({
|
|
|
11372
11372
|
}
|
|
11373
11373
|
} catch {
|
|
11374
11374
|
}
|
|
11375
|
-
return new Promise((
|
|
11375
|
+
return new Promise((resolve9, reject2) => {
|
|
11376
11376
|
if (signal.aborted) {
|
|
11377
11377
|
reject2(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
|
|
11378
11378
|
return;
|
|
11379
11379
|
}
|
|
11380
|
-
const timeoutId = setTimeout(
|
|
11380
|
+
const timeoutId = setTimeout(resolve9, interval);
|
|
11381
11381
|
signal.addEventListener("abort", () => {
|
|
11382
11382
|
clearTimeout(timeoutId);
|
|
11383
11383
|
reject2(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
|
|
@@ -14404,7 +14404,7 @@ var require_compile = __commonJS({
|
|
|
14404
14404
|
const schOrFunc = root.refs[ref];
|
|
14405
14405
|
if (schOrFunc)
|
|
14406
14406
|
return schOrFunc;
|
|
14407
|
-
let _sch =
|
|
14407
|
+
let _sch = resolve9.call(this, root, ref);
|
|
14408
14408
|
if (_sch === void 0) {
|
|
14409
14409
|
const schema = (_a3 = root.localRefs) === null || _a3 === void 0 ? void 0 : _a3[ref];
|
|
14410
14410
|
const { schemaId } = this.opts;
|
|
@@ -14431,7 +14431,7 @@ var require_compile = __commonJS({
|
|
|
14431
14431
|
function sameSchemaEnv(s1, s2) {
|
|
14432
14432
|
return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
|
|
14433
14433
|
}
|
|
14434
|
-
function
|
|
14434
|
+
function resolve9(root, ref) {
|
|
14435
14435
|
let sch;
|
|
14436
14436
|
while (typeof (sch = this.refs[ref]) == "string")
|
|
14437
14437
|
ref = sch;
|
|
@@ -15062,7 +15062,7 @@ var require_fast_uri = __commonJS({
|
|
|
15062
15062
|
}
|
|
15063
15063
|
return uri;
|
|
15064
15064
|
}
|
|
15065
|
-
function
|
|
15065
|
+
function resolve9(baseURI, relativeURI, options) {
|
|
15066
15066
|
const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
|
|
15067
15067
|
const resolved = resolveComponent(parse3(baseURI, schemelessOptions), parse3(relativeURI, schemelessOptions), schemelessOptions, true);
|
|
15068
15068
|
schemelessOptions.skipEscape = true;
|
|
@@ -15320,7 +15320,7 @@ var require_fast_uri = __commonJS({
|
|
|
15320
15320
|
var fastUri = {
|
|
15321
15321
|
SCHEMES,
|
|
15322
15322
|
normalize: normalize4,
|
|
15323
|
-
resolve:
|
|
15323
|
+
resolve: resolve9,
|
|
15324
15324
|
resolveComponent,
|
|
15325
15325
|
equal,
|
|
15326
15326
|
serialize,
|
|
@@ -18283,8 +18283,8 @@ var require_dist = __commonJS({
|
|
|
18283
18283
|
return ajv;
|
|
18284
18284
|
}
|
|
18285
18285
|
const [formats, exportName] = opts.mode === "fast" ? [formats_1.fastFormats, fastName] : [formats_1.fullFormats, fullName];
|
|
18286
|
-
const
|
|
18287
|
-
addFormats(ajv,
|
|
18286
|
+
const list17 = opts.formats || formats_1.formatNames;
|
|
18287
|
+
addFormats(ajv, list17, formats, exportName);
|
|
18288
18288
|
if (opts.keywords)
|
|
18289
18289
|
(0, limit_1.default)(ajv);
|
|
18290
18290
|
return ajv;
|
|
@@ -18296,11 +18296,11 @@ var require_dist = __commonJS({
|
|
|
18296
18296
|
throw new Error(`Unknown format "${name}"`);
|
|
18297
18297
|
return f;
|
|
18298
18298
|
};
|
|
18299
|
-
function addFormats(ajv,
|
|
18299
|
+
function addFormats(ajv, list17, fs, exportName) {
|
|
18300
18300
|
var _a3;
|
|
18301
18301
|
var _b;
|
|
18302
18302
|
(_a3 = (_b = ajv.opts.code).formats) !== null && _a3 !== void 0 ? _a3 : _b.formats = (0, codegen_1._)`require("ajv-formats/dist/formats").${exportName}`;
|
|
18303
|
-
for (const f of
|
|
18303
|
+
for (const f of list17)
|
|
18304
18304
|
ajv.addFormat(f, fs[f]);
|
|
18305
18305
|
}
|
|
18306
18306
|
module.exports = exports = formatsPlugin;
|
|
@@ -20988,6 +20988,7 @@ function inTx(db, fn) {
|
|
|
20988
20988
|
// ../daemon/src/core/db/migrate.ts
|
|
20989
20989
|
import { readdirSync as readdirSync2, readFileSync as readFileSync5 } from "fs";
|
|
20990
20990
|
import { dirname, join as join8 } from "path";
|
|
20991
|
+
import { DatabaseSync as DatabaseSync2 } from "node:sqlite";
|
|
20991
20992
|
import { fileURLToPath } from "url";
|
|
20992
20993
|
var migrationsDir = join8(dirname(fileURLToPath(import.meta.url)), "migrations");
|
|
20993
20994
|
var schemaMigrationsSql = `
|
|
@@ -20996,23 +20997,28 @@ var schemaMigrationsSql = `
|
|
|
20996
20997
|
applied_at INTEGER NOT NULL
|
|
20997
20998
|
)
|
|
20998
20999
|
`;
|
|
20999
|
-
var INCOMPATIBLE_DATABASE_MESSAGE = "Bazilion cannot start because this home uses an incompatible
|
|
21000
|
+
var INCOMPATIBLE_DATABASE_MESSAGE = "Bazilion cannot start because this home uses an incompatible database schema. Preserve the entire Bazilion home directory as a filesystem backup first, keeping bazilion.db and auth.json together. Then perform the reset with `bazilion uninstall --yes` (from the repository root of a source checkout: `pnpm tsx apps/cli/src/index.ts uninstall --yes`) and start Bazilion again. Use `--all` only if you also want to remove logs and installed skills.";
|
|
21000
21001
|
var IncompatibleDatabaseError = class extends Error {
|
|
21001
21002
|
constructor() {
|
|
21002
21003
|
super(INCOMPATIBLE_DATABASE_MESSAGE);
|
|
21003
21004
|
this.name = "IncompatibleDatabaseError";
|
|
21004
21005
|
}
|
|
21005
21006
|
};
|
|
21006
|
-
var
|
|
21007
|
-
|
|
21007
|
+
var DatabaseNewerThanBinaryError = class extends Error {
|
|
21008
|
+
constructor(dbVersion, supportedVersion) {
|
|
21009
|
+
super(
|
|
21010
|
+
`Bazilion cannot start because this home was written by a newer version: its database schema version (${dbVersion}) is newer than this binary supports (${supportedVersion}). Upgrade Bazilion to a release that supports this schema. Downgrades are unsupported; if you must run an older release, restore a pre-upgrade snapshot instead.`
|
|
21011
|
+
);
|
|
21012
|
+
this.name = "DatabaseNewerThanBinaryError";
|
|
21013
|
+
}
|
|
21014
|
+
};
|
|
21015
|
+
function listMigrations() {
|
|
21008
21016
|
return readdirSync2(migrationsDir).filter((file) => file.endsWith(".sql")).sort().map((file) => ({
|
|
21009
21017
|
version: file.replace(/\.sql$/, ""),
|
|
21010
21018
|
sql: readFileSync5(join8(migrationsDir, file), "utf8")
|
|
21011
21019
|
}));
|
|
21012
21020
|
}
|
|
21013
|
-
|
|
21014
|
-
return sql.replace(/\s+/g, " ").trim();
|
|
21015
|
-
}
|
|
21021
|
+
var canonicalSchemaObjectsByPrefix = /* @__PURE__ */ new Map();
|
|
21016
21022
|
function schemaObjects(db) {
|
|
21017
21023
|
return db.raw.query(
|
|
21018
21024
|
`SELECT type, name, tbl_name, sql
|
|
@@ -21024,46 +21030,61 @@ function schemaObjects(db) {
|
|
|
21024
21030
|
function schemaPayload(rows) {
|
|
21025
21031
|
return rows.map((row2) => [row2.type, row2.name, row2.tbl_name, normalizeSql(row2.sql)].join("\0")).join("\n");
|
|
21026
21032
|
}
|
|
21027
|
-
function
|
|
21028
|
-
|
|
21033
|
+
function normalizeSql(sql) {
|
|
21034
|
+
return sql.replace(/\s+/g, " ").trim();
|
|
21035
|
+
}
|
|
21036
|
+
function expectedSchema(files, prefixLength) {
|
|
21037
|
+
const cached2 = canonicalSchemaObjectsByPrefix.get(prefixLength);
|
|
21038
|
+
if (cached2) return cached2;
|
|
21029
21039
|
const canonical = openInMemoryDb();
|
|
21030
21040
|
try {
|
|
21031
21041
|
canonical.raw.exec(schemaMigrationsSql);
|
|
21032
|
-
for (const file of files) canonical.raw.exec(file.sql);
|
|
21033
|
-
|
|
21034
|
-
|
|
21042
|
+
for (const file of files.slice(0, prefixLength)) canonical.raw.exec(file.sql);
|
|
21043
|
+
const objects = schemaObjects(canonical);
|
|
21044
|
+
canonicalSchemaObjectsByPrefix.set(prefixLength, objects);
|
|
21045
|
+
return objects;
|
|
21035
21046
|
} finally {
|
|
21036
21047
|
canonical.close();
|
|
21037
21048
|
}
|
|
21038
21049
|
}
|
|
21039
21050
|
function assertMigrationCompatibility(db) {
|
|
21040
|
-
const files =
|
|
21051
|
+
const files = listMigrations();
|
|
21041
21052
|
const expectedVersions = files.map((file) => file.version);
|
|
21053
|
+
const dbUserVersion = userVersion(db);
|
|
21054
|
+
if (dbUserVersion > files.length) {
|
|
21055
|
+
throw new DatabaseNewerThanBinaryError(dbUserVersion, files.length);
|
|
21056
|
+
}
|
|
21042
21057
|
let appliedVersions;
|
|
21043
21058
|
try {
|
|
21044
21059
|
appliedVersions = db.raw.query("SELECT version FROM schema_migrations ORDER BY version").all().map((row2) => row2.version);
|
|
21045
21060
|
} catch {
|
|
21046
21061
|
throw new IncompatibleDatabaseError();
|
|
21047
21062
|
}
|
|
21048
|
-
const actualObjects = schemaObjects(db);
|
|
21049
|
-
const expectedObjects = expectedSchema(files);
|
|
21050
21063
|
if (appliedVersions.length === 0) {
|
|
21051
|
-
const
|
|
21064
|
+
const actualObjects2 = schemaObjects(db);
|
|
21065
|
+
const migrationTable = actualObjects2.filter(
|
|
21052
21066
|
(row2) => row2.type === "table" && row2.name === "schema_migrations"
|
|
21053
21067
|
);
|
|
21054
|
-
const expectedMigrationTable =
|
|
21068
|
+
const expectedMigrationTable = expectedSchema(files, 0).filter(
|
|
21055
21069
|
(row2) => row2.type === "table" && row2.name === "schema_migrations"
|
|
21056
21070
|
);
|
|
21057
|
-
if (
|
|
21071
|
+
if (actualObjects2.length !== 1 || migrationTable.length !== 1 || schemaPayload(migrationTable) !== schemaPayload(expectedMigrationTable)) {
|
|
21058
21072
|
throw new IncompatibleDatabaseError();
|
|
21059
21073
|
}
|
|
21060
21074
|
return;
|
|
21061
21075
|
}
|
|
21062
|
-
|
|
21076
|
+
const expectedSet = new Set(expectedVersions);
|
|
21077
|
+
const isPrefix = appliedVersions.every((version2) => expectedSet.has(version2)) && appliedVersions.length <= expectedVersions.length && appliedVersions.every((version2, index) => version2 === expectedVersions[index]);
|
|
21078
|
+
if (!isPrefix) {
|
|
21079
|
+
throw new IncompatibleDatabaseError();
|
|
21080
|
+
}
|
|
21081
|
+
const actualObjects = schemaObjects(db);
|
|
21082
|
+
const expectedObjects = expectedSchema(files, appliedVersions.length);
|
|
21083
|
+
if (schemaPayload(actualObjects) !== schemaPayload(expectedObjects)) {
|
|
21063
21084
|
throw new IncompatibleDatabaseError();
|
|
21064
21085
|
}
|
|
21065
21086
|
}
|
|
21066
|
-
function runMigrations(db) {
|
|
21087
|
+
function runMigrations(db, options = {}) {
|
|
21067
21088
|
const existingObjects = schemaObjects(db);
|
|
21068
21089
|
if (existingObjects.length > 0 && !existingObjects.some((row2) => row2.type === "table" && row2.name === "schema_migrations")) {
|
|
21069
21090
|
throw new IncompatibleDatabaseError();
|
|
@@ -21073,8 +21094,13 @@ function runMigrations(db) {
|
|
|
21073
21094
|
const applied = new Set(
|
|
21074
21095
|
db.raw.query("SELECT version FROM schema_migrations").all().map((r) => r.version)
|
|
21075
21096
|
);
|
|
21076
|
-
|
|
21077
|
-
|
|
21097
|
+
const files = listMigrations();
|
|
21098
|
+
const pending = files.filter((file) => !applied.has(file.version));
|
|
21099
|
+
if (pending.length > 0 && applied.size > 0 && options.preMigrationSnapshotPath !== void 0) {
|
|
21100
|
+
db.raw.exec(`VACUUM INTO '${options.preMigrationSnapshotPath.replaceAll("'", "''")}'`);
|
|
21101
|
+
verifySnapshot(options.preMigrationSnapshotPath);
|
|
21102
|
+
}
|
|
21103
|
+
for (const file of pending) {
|
|
21078
21104
|
const tx = db.raw.transaction(() => {
|
|
21079
21105
|
db.raw.exec(file.sql);
|
|
21080
21106
|
db.raw.run("INSERT INTO schema_migrations (version, applied_at) VALUES (?, ?)", [
|
|
@@ -21084,14 +21110,38 @@ function runMigrations(db) {
|
|
|
21084
21110
|
});
|
|
21085
21111
|
tx();
|
|
21086
21112
|
}
|
|
21113
|
+
if (userVersion(db) < files.length) {
|
|
21114
|
+
db.raw.exec(`PRAGMA user_version = ${files.length}`);
|
|
21115
|
+
}
|
|
21087
21116
|
assertMigrationCompatibility(db);
|
|
21088
21117
|
}
|
|
21118
|
+
function userVersion(db) {
|
|
21119
|
+
const row2 = db.raw.query("PRAGMA user_version").all()[0];
|
|
21120
|
+
const value = row2?.user_version;
|
|
21121
|
+
return typeof value === "number" ? value : Number(value ?? 0);
|
|
21122
|
+
}
|
|
21123
|
+
function verifySnapshot(path) {
|
|
21124
|
+
const snapshot = new DatabaseSync2(path);
|
|
21125
|
+
try {
|
|
21126
|
+
const row2 = snapshot.prepare("PRAGMA integrity_check").get();
|
|
21127
|
+
if (row2.integrity_check !== "ok") {
|
|
21128
|
+
throw new Error(
|
|
21129
|
+
`Pre-migration snapshot failed integrity check: ${String(row2.integrity_check)}`
|
|
21130
|
+
);
|
|
21131
|
+
}
|
|
21132
|
+
} finally {
|
|
21133
|
+
snapshot.close();
|
|
21134
|
+
}
|
|
21135
|
+
}
|
|
21089
21136
|
|
|
21090
21137
|
// ../daemon/src/core/paths.ts
|
|
21138
|
+
import { realpathSync } from "fs";
|
|
21091
21139
|
import { homedir } from "os";
|
|
21092
|
-
import { join as join9 } from "path";
|
|
21140
|
+
import { basename, dirname as dirname2, join as join9, resolve as resolve2 } from "path";
|
|
21093
21141
|
function resolvePaths(home) {
|
|
21094
|
-
const root =
|
|
21142
|
+
const root = canonicalHome(
|
|
21143
|
+
resolve2(home ?? process.env.BAZILION_HOME ?? join9(homedir(), ".bazilion"))
|
|
21144
|
+
);
|
|
21095
21145
|
return {
|
|
21096
21146
|
home: root,
|
|
21097
21147
|
db: join9(root, "bazilion.db"),
|
|
@@ -21115,6 +21165,22 @@ function resolvePaths(home) {
|
|
|
21115
21165
|
}
|
|
21116
21166
|
};
|
|
21117
21167
|
}
|
|
21168
|
+
function canonicalHome(root) {
|
|
21169
|
+
let resolved = root;
|
|
21170
|
+
const unresolvedTail = [];
|
|
21171
|
+
while (true) {
|
|
21172
|
+
try {
|
|
21173
|
+
resolved = realpathSync(resolved);
|
|
21174
|
+
break;
|
|
21175
|
+
} catch {
|
|
21176
|
+
const parent = dirname2(resolved);
|
|
21177
|
+
if (parent === resolved) break;
|
|
21178
|
+
unresolvedTail.unshift(basename(resolved));
|
|
21179
|
+
resolved = parent;
|
|
21180
|
+
}
|
|
21181
|
+
}
|
|
21182
|
+
return join9(resolved, ...unresolvedTail);
|
|
21183
|
+
}
|
|
21118
21184
|
|
|
21119
21185
|
// ../daemon/src/core/profile/delete.ts
|
|
21120
21186
|
import { existsSync as existsSync6, rmSync as rmSync4 } from "fs";
|
|
@@ -23606,60 +23672,197 @@ function remove8(db, id) {
|
|
|
23606
23672
|
db.raw.run("DELETE FROM agent_triggers WHERE id = ?", [id]);
|
|
23607
23673
|
}
|
|
23608
23674
|
|
|
23675
|
+
// ../daemon/src/core/repos/webPairingTokens.ts
|
|
23676
|
+
var webPairingTokens_exports = {};
|
|
23677
|
+
__export(webPairingTokens_exports, {
|
|
23678
|
+
PAIRING_TOKEN_TTL_MS: () => PAIRING_TOKEN_TTL_MS,
|
|
23679
|
+
completeExchange: () => completeExchange,
|
|
23680
|
+
create: () => create2,
|
|
23681
|
+
exchange: () => exchange,
|
|
23682
|
+
list: () => list9
|
|
23683
|
+
});
|
|
23684
|
+
import { createHash as createHash3, randomBytes as randomBytes3, randomUUID as randomUUID11 } from "crypto";
|
|
23685
|
+
|
|
23686
|
+
// ../../packages/api-types/src/entities.ts
|
|
23687
|
+
var REASONING_LEVELS = [
|
|
23688
|
+
"off",
|
|
23689
|
+
"minimal",
|
|
23690
|
+
"low",
|
|
23691
|
+
"medium",
|
|
23692
|
+
"high",
|
|
23693
|
+
"xhigh"
|
|
23694
|
+
];
|
|
23695
|
+
var DEVICE_TOKEN_SCOPES = ["read", "write", "approvals", "admin"];
|
|
23696
|
+
var ALL_DEVICE_TOKEN_SCOPES = DEVICE_TOKEN_SCOPES;
|
|
23697
|
+
|
|
23698
|
+
// ../../packages/api-types/src/git-review.ts
|
|
23699
|
+
var REVIEW_LIMITS = {
|
|
23700
|
+
files: 1e3,
|
|
23701
|
+
fileBytes: 1024 * 1024,
|
|
23702
|
+
totalBytes: 16 * 1024 * 1024,
|
|
23703
|
+
patchBytes: 256 * 1024
|
|
23704
|
+
};
|
|
23705
|
+
|
|
23706
|
+
// ../../packages/api-types/src/publication.ts
|
|
23707
|
+
var PUBLICATION_LIMITS = {
|
|
23708
|
+
repository: 200,
|
|
23709
|
+
branch: 200,
|
|
23710
|
+
commitMessage: 2e3,
|
|
23711
|
+
refusalDetail: 400,
|
|
23712
|
+
error: 400,
|
|
23713
|
+
/** Branches that are never published to, whatever the host says. */
|
|
23714
|
+
protectedBranches: ["main", "master", "trunk", "develop", "release"]
|
|
23715
|
+
};
|
|
23716
|
+
|
|
23717
|
+
// ../../packages/api-types/src/verification.ts
|
|
23718
|
+
var VERIFICATION_OUTCOME_LIMITS = [
|
|
23719
|
+
"Facts above are executor-owned. A non-zero exit is a result about the commands that ran, never proof about later code, and this is not an approval to publish, merge or deploy.",
|
|
23720
|
+
"Declared output paths are not enforced, so a change they do not cover appears above rather than being prevented."
|
|
23721
|
+
];
|
|
23722
|
+
|
|
23723
|
+
// ../../packages/api-types/src/index.ts
|
|
23724
|
+
var PROFILE_FILES = [
|
|
23725
|
+
"profile.json",
|
|
23726
|
+
"SOUL.md",
|
|
23727
|
+
"IDENTITY.md",
|
|
23728
|
+
"BOOTSTRAP.md",
|
|
23729
|
+
"AGENTS.md",
|
|
23730
|
+
"TOOLS.md"
|
|
23731
|
+
];
|
|
23732
|
+
|
|
23733
|
+
// ../daemon/src/core/repos/webPairingTokens.ts
|
|
23734
|
+
var PAIRING_TOKEN_TTL_MS = 10 * 6e4;
|
|
23735
|
+
function hashToken(token) {
|
|
23736
|
+
return createHash3("sha256").update(token).digest("hex");
|
|
23737
|
+
}
|
|
23738
|
+
function create2(db, opts = {}) {
|
|
23739
|
+
const id = randomUUID11();
|
|
23740
|
+
const code = randomBytes3(24).toString("hex");
|
|
23741
|
+
const now = Date.now();
|
|
23742
|
+
const scopes = (opts.scopes ?? ALL_DEVICE_TOKEN_SCOPES).join(" ");
|
|
23743
|
+
db.raw.run(
|
|
23744
|
+
`INSERT INTO web_pairing_tokens (id, token_hash, scopes, created_at, expires_at)
|
|
23745
|
+
VALUES (?, ?, ?, ?, ?)`,
|
|
23746
|
+
[id, hashToken(code), scopes, now, now + PAIRING_TOKEN_TTL_MS]
|
|
23747
|
+
);
|
|
23748
|
+
return {
|
|
23749
|
+
code,
|
|
23750
|
+
meta: {
|
|
23751
|
+
id,
|
|
23752
|
+
scopes: scopes.split(" "),
|
|
23753
|
+
createdAt: now,
|
|
23754
|
+
expiresAt: now + PAIRING_TOKEN_TTL_MS,
|
|
23755
|
+
usedAt: null,
|
|
23756
|
+
usedByTokenId: null
|
|
23757
|
+
}
|
|
23758
|
+
};
|
|
23759
|
+
}
|
|
23760
|
+
function exchange(db, code, now = Date.now()) {
|
|
23761
|
+
const tokenHash = hashToken(code);
|
|
23762
|
+
const claimed = db.raw.run(
|
|
23763
|
+
`UPDATE web_pairing_tokens
|
|
23764
|
+
SET used_at = ?, used_by_token_id = 'pending'
|
|
23765
|
+
WHERE token_hash = ? AND used_at IS NULL AND expires_at > ?`,
|
|
23766
|
+
[now, tokenHash, now]
|
|
23767
|
+
);
|
|
23768
|
+
if (claimed.changes === 0) {
|
|
23769
|
+
const row3 = db.raw.query(
|
|
23770
|
+
"SELECT expires_at, used_at FROM web_pairing_tokens WHERE token_hash = ?"
|
|
23771
|
+
).get(tokenHash);
|
|
23772
|
+
if (!row3) return { ok: false, reason: "invalid" };
|
|
23773
|
+
if (row3.used_at !== null) return { ok: false, reason: "used" };
|
|
23774
|
+
return { ok: false, reason: "expired" };
|
|
23775
|
+
}
|
|
23776
|
+
const row2 = db.raw.query(
|
|
23777
|
+
"SELECT scopes, used_by_token_id FROM web_pairing_tokens WHERE token_hash = ?"
|
|
23778
|
+
).get(tokenHash);
|
|
23779
|
+
if (!row2) return { ok: false, reason: "invalid" };
|
|
23780
|
+
return { ok: true, scopes: row2.scopes.split(" ") };
|
|
23781
|
+
}
|
|
23782
|
+
function completeExchange(db, code, deviceTokenId) {
|
|
23783
|
+
db.raw.run(
|
|
23784
|
+
`UPDATE web_pairing_tokens SET used_by_token_id = ?
|
|
23785
|
+
WHERE token_hash = ? AND used_by_token_id = 'pending'`,
|
|
23786
|
+
[deviceTokenId, hashToken(code)]
|
|
23787
|
+
);
|
|
23788
|
+
}
|
|
23789
|
+
function list9(db, opts) {
|
|
23790
|
+
const sql = opts?.includeUsed ? "SELECT * FROM web_pairing_tokens ORDER BY created_at DESC" : "SELECT * FROM web_pairing_tokens WHERE used_at IS NULL AND expires_at > ? ORDER BY created_at DESC";
|
|
23791
|
+
const rows = opts?.includeUsed ? db.raw.query(sql).all() : db.raw.query(sql).all(Date.now());
|
|
23792
|
+
return rows.map((r) => ({
|
|
23793
|
+
id: r.id,
|
|
23794
|
+
scopes: r.scopes.split(" "),
|
|
23795
|
+
createdAt: r.created_at,
|
|
23796
|
+
expiresAt: r.expires_at,
|
|
23797
|
+
usedAt: r.used_at,
|
|
23798
|
+
usedByTokenId: r.used_by_token_id
|
|
23799
|
+
}));
|
|
23800
|
+
}
|
|
23801
|
+
|
|
23609
23802
|
// ../daemon/src/core/repos/webSessions.ts
|
|
23610
23803
|
var webSessions_exports = {};
|
|
23611
23804
|
__export(webSessions_exports, {
|
|
23612
23805
|
SESSION_ABSOLUTE_MS: () => SESSION_ABSOLUTE_MS,
|
|
23613
23806
|
SESSION_IDLE_MS: () => SESSION_IDLE_MS,
|
|
23614
23807
|
authenticate: () => authenticate,
|
|
23615
|
-
create: () =>
|
|
23808
|
+
create: () => create4,
|
|
23616
23809
|
csrfMatches: () => csrfMatches,
|
|
23617
|
-
list: () =>
|
|
23810
|
+
list: () => list11,
|
|
23618
23811
|
revoke: () => revoke3,
|
|
23619
23812
|
revokeAll: () => revokeAll,
|
|
23620
23813
|
revokeForDevice: () => revokeForDevice
|
|
23621
23814
|
});
|
|
23622
|
-
import { createHash as
|
|
23815
|
+
import { createHash as createHash5, randomBytes as randomBytes5, randomUUID as randomUUID13 } from "crypto";
|
|
23623
23816
|
|
|
23624
23817
|
// ../daemon/src/core/repos/webTokens.ts
|
|
23625
23818
|
var webTokens_exports = {};
|
|
23626
23819
|
__export(webTokens_exports, {
|
|
23627
|
-
create: () =>
|
|
23820
|
+
create: () => create3,
|
|
23628
23821
|
findActiveByToken: () => findActiveByToken,
|
|
23629
23822
|
get: () => get16,
|
|
23630
|
-
hashToken: () =>
|
|
23631
|
-
list: () =>
|
|
23823
|
+
hashToken: () => hashToken2,
|
|
23824
|
+
list: () => list10,
|
|
23632
23825
|
markUsed: () => markUsed,
|
|
23826
|
+
parseScopes: () => parseScopes,
|
|
23633
23827
|
rejectionReason: () => rejectionReason,
|
|
23634
23828
|
revoke: () => revoke2
|
|
23635
23829
|
});
|
|
23636
|
-
import { createHash as
|
|
23830
|
+
import { createHash as createHash4, randomBytes as randomBytes4, randomUUID as randomUUID12 } from "crypto";
|
|
23831
|
+
function parseScopes(raw2) {
|
|
23832
|
+
if (!raw2) return [...ALL_DEVICE_TOKEN_SCOPES];
|
|
23833
|
+
const parsed = raw2.split(/\s+/).filter(Boolean).filter(
|
|
23834
|
+
(s) => ALL_DEVICE_TOKEN_SCOPES.includes(s)
|
|
23835
|
+
);
|
|
23836
|
+
return parsed.length > 0 ? parsed : [...ALL_DEVICE_TOKEN_SCOPES];
|
|
23837
|
+
}
|
|
23637
23838
|
function toToken(r) {
|
|
23638
23839
|
return {
|
|
23639
23840
|
id: r.id,
|
|
23640
23841
|
label: r.label,
|
|
23641
23842
|
kind: r.kind,
|
|
23843
|
+
scopes: parseScopes(r.scopes),
|
|
23642
23844
|
createdAt: r.created_at,
|
|
23643
23845
|
lastUsedAt: r.last_used_at,
|
|
23644
23846
|
expiresAt: r.expires_at,
|
|
23645
23847
|
revokedAt: r.revoked_at
|
|
23646
23848
|
};
|
|
23647
23849
|
}
|
|
23648
|
-
function
|
|
23649
|
-
return
|
|
23850
|
+
function hashToken2(token) {
|
|
23851
|
+
return createHash4("sha256").update(token).digest("hex");
|
|
23650
23852
|
}
|
|
23651
|
-
function
|
|
23652
|
-
const id =
|
|
23653
|
-
const token =
|
|
23654
|
-
const tokenHash =
|
|
23853
|
+
function create3(db, label, opts = {}) {
|
|
23854
|
+
const id = randomUUID12();
|
|
23855
|
+
const token = randomBytes4(24).toString("hex");
|
|
23856
|
+
const tokenHash = hashToken2(token);
|
|
23655
23857
|
const now = Date.now();
|
|
23656
23858
|
const kind = opts.kind ?? "device";
|
|
23657
23859
|
const expiresAt = kind === "bootstrap" ? null : opts.expiresAt ?? now + 90 * 864e5;
|
|
23860
|
+
const scopes = (kind === "bootstrap" ? ALL_DEVICE_TOKEN_SCOPES : opts.scopes ?? ALL_DEVICE_TOKEN_SCOPES).join(" ");
|
|
23658
23861
|
db.raw.run(
|
|
23659
23862
|
`INSERT INTO web_tokens
|
|
23660
|
-
(id, label, kind, token_hash, created_at, last_used_at, expires_at, revoked_at)
|
|
23661
|
-
VALUES (?, ?, ?, ?, ?, NULL, ?, NULL)`,
|
|
23662
|
-
[id, label, kind, tokenHash, now, expiresAt]
|
|
23863
|
+
(id, label, kind, token_hash, scopes, created_at, last_used_at, expires_at, revoked_at)
|
|
23864
|
+
VALUES (?, ?, ?, ?, ?, ?, NULL, ?, NULL)`,
|
|
23865
|
+
[id, label, kind, tokenHash, scopes, now, expiresAt]
|
|
23663
23866
|
);
|
|
23664
23867
|
return {
|
|
23665
23868
|
token,
|
|
@@ -23667,6 +23870,7 @@ function create2(db, label, opts = {}) {
|
|
|
23667
23870
|
id,
|
|
23668
23871
|
label,
|
|
23669
23872
|
kind,
|
|
23873
|
+
scopes: parseScopes(scopes),
|
|
23670
23874
|
createdAt: now,
|
|
23671
23875
|
lastUsedAt: null,
|
|
23672
23876
|
expiresAt,
|
|
@@ -23674,7 +23878,7 @@ function create2(db, label, opts = {}) {
|
|
|
23674
23878
|
}
|
|
23675
23879
|
};
|
|
23676
23880
|
}
|
|
23677
|
-
function
|
|
23881
|
+
function list10(db, opts) {
|
|
23678
23882
|
const sql = opts?.includeRevoked ? "SELECT * FROM web_tokens ORDER BY created_at ASC" : "SELECT * FROM web_tokens WHERE revoked_at IS NULL ORDER BY created_at ASC";
|
|
23679
23883
|
return db.raw.query(sql).all().map(toToken);
|
|
23680
23884
|
}
|
|
@@ -23683,7 +23887,7 @@ function get16(db, id) {
|
|
|
23683
23887
|
return row2 ? toToken(row2) : null;
|
|
23684
23888
|
}
|
|
23685
23889
|
function findActiveByToken(db, token) {
|
|
23686
|
-
const tokenHash =
|
|
23890
|
+
const tokenHash = hashToken2(token);
|
|
23687
23891
|
const row2 = db.raw.query(
|
|
23688
23892
|
`SELECT * FROM web_tokens
|
|
23689
23893
|
WHERE token_hash = ? AND revoked_at IS NULL
|
|
@@ -23694,7 +23898,7 @@ function findActiveByToken(db, token) {
|
|
|
23694
23898
|
function rejectionReason(db, token, now = Date.now()) {
|
|
23695
23899
|
const row2 = db.raw.query(
|
|
23696
23900
|
"SELECT expires_at, revoked_at FROM web_tokens WHERE token_hash = ?"
|
|
23697
|
-
).get(
|
|
23901
|
+
).get(hashToken2(token));
|
|
23698
23902
|
if (!row2) return "invalid";
|
|
23699
23903
|
if (row2.revoked_at !== null) return "revoked";
|
|
23700
23904
|
if (row2.expires_at !== null && row2.expires_at <= now) return "expired";
|
|
@@ -23715,7 +23919,7 @@ function revoke2(db, id, when = Date.now()) {
|
|
|
23715
23919
|
var SESSION_IDLE_MS = 12 * 60 * 60 * 1e3;
|
|
23716
23920
|
var SESSION_ABSOLUTE_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
23717
23921
|
function hash(value) {
|
|
23718
|
-
return
|
|
23922
|
+
return createHash5("sha256").update(value).digest("hex");
|
|
23719
23923
|
}
|
|
23720
23924
|
function toSession(row2, currentId) {
|
|
23721
23925
|
return {
|
|
@@ -23730,15 +23934,15 @@ function toSession(row2, currentId) {
|
|
|
23730
23934
|
current: row2.id === currentId
|
|
23731
23935
|
};
|
|
23732
23936
|
}
|
|
23733
|
-
function
|
|
23937
|
+
function create4(db, deviceTokenId, now = Date.now()) {
|
|
23734
23938
|
const token = db.raw.query(
|
|
23735
23939
|
`SELECT id, label FROM web_tokens
|
|
23736
23940
|
WHERE id = ? AND kind = 'device' AND revoked_at IS NULL AND expires_at > ?`
|
|
23737
23941
|
).get(deviceTokenId, now);
|
|
23738
23942
|
if (!token) throw new Error("active device credential required");
|
|
23739
|
-
const id =
|
|
23740
|
-
const secret =
|
|
23741
|
-
const csrfToken =
|
|
23943
|
+
const id = randomUUID13();
|
|
23944
|
+
const secret = randomBytes5(32).toString("base64url");
|
|
23945
|
+
const csrfToken = randomBytes5(32).toString("base64url");
|
|
23742
23946
|
const idleExpiresAt = now + SESSION_IDLE_MS;
|
|
23743
23947
|
const absoluteExpiresAt = now + SESSION_ABSOLUTE_MS;
|
|
23744
23948
|
db.raw.run(
|
|
@@ -23771,7 +23975,7 @@ function authenticate(db, cookieValue, now = Date.now()) {
|
|
|
23771
23975
|
const secret = cookieValue.slice(separator + 1);
|
|
23772
23976
|
if (!secret) return null;
|
|
23773
23977
|
const row2 = db.raw.query(
|
|
23774
|
-
`SELECT s.*, t.label AS device_label
|
|
23978
|
+
`SELECT s.*, t.label AS device_label, t.scopes AS device_scopes
|
|
23775
23979
|
FROM web_sessions s JOIN web_tokens t ON t.id = s.device_token_id
|
|
23776
23980
|
WHERE s.id = ? AND s.secret_hash = ? AND s.revoked_at IS NULL
|
|
23777
23981
|
AND s.idle_expires_at > ? AND s.absolute_expires_at > ?
|
|
@@ -23788,13 +23992,14 @@ function authenticate(db, cookieValue, now = Date.now()) {
|
|
|
23788
23992
|
id,
|
|
23789
23993
|
deviceTokenId: row2.device_token_id,
|
|
23790
23994
|
deviceLabel: row2.device_label,
|
|
23995
|
+
deviceScopes: row2.device_scopes,
|
|
23791
23996
|
csrfHash: row2.csrf_hash
|
|
23792
23997
|
};
|
|
23793
23998
|
}
|
|
23794
23999
|
function csrfMatches(session, csrf) {
|
|
23795
|
-
return
|
|
24000
|
+
return hashToken2(csrf) === session.csrfHash;
|
|
23796
24001
|
}
|
|
23797
|
-
function
|
|
24002
|
+
function list11(db, opts = {}) {
|
|
23798
24003
|
const where = opts.includeRevoked ? "" : "WHERE s.revoked_at IS NULL";
|
|
23799
24004
|
return db.raw.query(
|
|
23800
24005
|
`SELECT s.*, t.label AS device_label FROM web_sessions s
|
|
@@ -23853,7 +24058,7 @@ function mergeSecretsIntoEnv(db, password, env = process.env) {
|
|
|
23853
24058
|
// ../daemon/src/core/skills/import.ts
|
|
23854
24059
|
import { cpSync, existsSync as existsSync8, mkdtempSync, readdirSync as readdirSync3, rmSync as rmSync5, statSync as statSync2 } from "fs";
|
|
23855
24060
|
import { tmpdir } from "os";
|
|
23856
|
-
import { basename, join as join11, resolve as
|
|
24061
|
+
import { basename as basename2, join as join11, resolve as resolve3, sep } from "path";
|
|
23857
24062
|
import AdmZip from "adm-zip";
|
|
23858
24063
|
|
|
23859
24064
|
// ../daemon/src/core/skills/parse.ts
|
|
@@ -23967,7 +24172,7 @@ function extractZipSafely(zipPath) {
|
|
|
23967
24172
|
if (rawName.startsWith("/") || rawName.startsWith("\\")) {
|
|
23968
24173
|
throw new Error(`zip entry has absolute path: ${rawName}`);
|
|
23969
24174
|
}
|
|
23970
|
-
const resolved =
|
|
24175
|
+
const resolved = resolve3(root, rawName);
|
|
23971
24176
|
if (resolved !== root && !resolved.startsWith(root + sep)) {
|
|
23972
24177
|
throw new Error(`zip entry escapes extraction root: ${rawName}`);
|
|
23973
24178
|
}
|
|
@@ -23985,7 +24190,7 @@ function extractZipSafely(zipPath) {
|
|
|
23985
24190
|
return { root, effectiveSource };
|
|
23986
24191
|
}
|
|
23987
24192
|
function importSkills(paths2, input) {
|
|
23988
|
-
const rawSource =
|
|
24193
|
+
const rawSource = resolve3(input.source);
|
|
23989
24194
|
if (!existsSync8(rawSource)) {
|
|
23990
24195
|
throw new Error(`source does not exist: ${rawSource}`);
|
|
23991
24196
|
}
|
|
@@ -24011,7 +24216,7 @@ function importSkills(paths2, input) {
|
|
|
24011
24216
|
function importSkillsFromDir(paths2, source, input) {
|
|
24012
24217
|
const candidates = [];
|
|
24013
24218
|
if (existsSync8(join11(source, "SKILL.md"))) {
|
|
24014
|
-
candidates.push({ name:
|
|
24219
|
+
candidates.push({ name: basename2(source), dir: source });
|
|
24015
24220
|
} else {
|
|
24016
24221
|
const entries = readdirSync3(source, { withFileTypes: true });
|
|
24017
24222
|
for (const e of entries) {
|
|
@@ -24078,7 +24283,7 @@ function resolveAgentSkills(db, paths2, agentId) {
|
|
|
24078
24283
|
}
|
|
24079
24284
|
|
|
24080
24285
|
// ../daemon/src/core/team/delete.ts
|
|
24081
|
-
import { randomUUID as
|
|
24286
|
+
import { randomUUID as randomUUID14 } from "crypto";
|
|
24082
24287
|
import { existsSync as existsSync9, renameSync as renameSync2, rmSync as rmSync6 } from "fs";
|
|
24083
24288
|
function deleteTeam(db, paths2, id, expectedTeamPolicyRevision) {
|
|
24084
24289
|
const g2 = get3(db, id, paths2);
|
|
@@ -24097,7 +24302,7 @@ function deleteTeam(db, paths2, id, expectedTeamPolicyRevision) {
|
|
|
24097
24302
|
`cannot delete team "${id}": ${members2.length} agent(s) still belong to it: ${names}. Move or delete them first.`
|
|
24098
24303
|
);
|
|
24099
24304
|
}
|
|
24100
|
-
const stagedPath = `${g2.path}.deleting-${
|
|
24305
|
+
const stagedPath = `${g2.path}.deleting-${randomUUID14()}`;
|
|
24101
24306
|
const hadSlot = existsSync9(g2.path);
|
|
24102
24307
|
if (hadSlot) renameSync2(g2.path, stagedPath);
|
|
24103
24308
|
try {
|
|
@@ -24121,7 +24326,7 @@ function deleteTeam(db, paths2, id, expectedTeamPolicyRevision) {
|
|
|
24121
24326
|
}
|
|
24122
24327
|
|
|
24123
24328
|
// ../daemon/src/core/team-policy/adopt.ts
|
|
24124
|
-
import { randomUUID as
|
|
24329
|
+
import { randomUUID as randomUUID15 } from "crypto";
|
|
24125
24330
|
function previewTeamPolicyAdoption(db, teamId, input) {
|
|
24126
24331
|
return resolveAdoptionPlan(db, teamId, { ...input, previewEdges: [] }).resolved;
|
|
24127
24332
|
}
|
|
@@ -24194,7 +24399,7 @@ function adoptTeamTemplate(db, teamId, input) {
|
|
|
24194
24399
|
);
|
|
24195
24400
|
db.raw.run("DELETE FROM template_instantiations WHERE team_id = ?", [teamId]);
|
|
24196
24401
|
db.raw.run("DELETE FROM team_policy_edges WHERE team_id = ?", [teamId]);
|
|
24197
|
-
const instantiationId =
|
|
24402
|
+
const instantiationId = randomUUID15();
|
|
24198
24403
|
db.raw.run(
|
|
24199
24404
|
`INSERT INTO template_instantiations
|
|
24200
24405
|
(id, team_id, template_id, template_revision, created_at)
|
|
@@ -24292,7 +24497,7 @@ function edgeKey(edge) {
|
|
|
24292
24497
|
}
|
|
24293
24498
|
|
|
24294
24499
|
// ../daemon/src/core/team-policy/authorization.ts
|
|
24295
|
-
import { createHash as
|
|
24500
|
+
import { createHash as createHash6, randomUUID as randomUUID16 } from "crypto";
|
|
24296
24501
|
function denied(channel, code, reason) {
|
|
24297
24502
|
return {
|
|
24298
24503
|
decision: "deny",
|
|
@@ -24442,7 +24647,7 @@ function authorizeInSnapshot(db, input) {
|
|
|
24442
24647
|
};
|
|
24443
24648
|
}
|
|
24444
24649
|
function authorizationFingerprint(input, operation) {
|
|
24445
|
-
return
|
|
24650
|
+
return createHash6("sha256").update(JSON.stringify({ operation, source: input.source, target: input.target })).digest("hex");
|
|
24446
24651
|
}
|
|
24447
24652
|
function recordDenial(db, input, operation, result) {
|
|
24448
24653
|
const fingerprint2 = authorizationFingerprint(input, operation);
|
|
@@ -24472,7 +24677,7 @@ function recordDenial(db, input, operation, result) {
|
|
|
24472
24677
|
const sourceGroup = agentGroup(input.source) ?? agentGroup(input.target) ?? ("teamId" in input.source ? input.source.teamId : null);
|
|
24473
24678
|
const targetGroup = agentGroup(input.target) ?? agentGroup(input.source) ?? ("teamId" in input.target ? input.target.teamId : null);
|
|
24474
24679
|
const values = [
|
|
24475
|
-
|
|
24680
|
+
randomUUID16(),
|
|
24476
24681
|
input.attemptKind,
|
|
24477
24682
|
input.attemptId,
|
|
24478
24683
|
operation,
|
|
@@ -24522,7 +24727,7 @@ function recordDenial(db, input, operation, result) {
|
|
|
24522
24727
|
}
|
|
24523
24728
|
|
|
24524
24729
|
// ../daemon/src/core/team-policy/source.ts
|
|
24525
|
-
import { randomUUID as
|
|
24730
|
+
import { randomUUID as randomUUID17 } from "crypto";
|
|
24526
24731
|
function diffTeamPolicy(db, teamId) {
|
|
24527
24732
|
const detail3 = detail(db, teamId);
|
|
24528
24733
|
if (!detail3) throw new Error(`team_policy_missing: ${teamId}`);
|
|
@@ -24590,7 +24795,7 @@ function saveTeamPolicyAsTemplate(db, paths2, teamId, input) {
|
|
|
24590
24795
|
const team = get3(db, teamId, paths2);
|
|
24591
24796
|
if (!team) throw new Error(`team not found: ${teamId}`);
|
|
24592
24797
|
const members2 = list(db, { includeArchived: true }).filter((agent) => agent.teamId === teamId);
|
|
24593
|
-
const slotByAgent = new Map(members2.map((agent) => [agent.id,
|
|
24798
|
+
const slotByAgent = new Map(members2.map((agent) => [agent.id, randomUUID17()]));
|
|
24594
24799
|
const stateByAgent = new Map(
|
|
24595
24800
|
agentState(db, teamId).map((state3) => [state3.agentId, state3])
|
|
24596
24801
|
);
|
|
@@ -24666,7 +24871,7 @@ function updateTeamPolicySource(db, teamId, input) {
|
|
|
24666
24871
|
baselineBindings.map((binding) => [binding.agentId, binding.sourceSlotId])
|
|
24667
24872
|
);
|
|
24668
24873
|
for (const id of selectedIds) {
|
|
24669
|
-
if (!slotByAgent.has(id)) slotByAgent.set(id,
|
|
24874
|
+
if (!slotByAgent.has(id)) slotByAgent.set(id, randomUUID17());
|
|
24670
24875
|
}
|
|
24671
24876
|
const previousSlotById = new Map(previous.slots.map((slot) => [slot.slotId, slot]));
|
|
24672
24877
|
const selectedMembers = [...selectedIds].map((id) => {
|
|
@@ -24734,7 +24939,7 @@ function pruneEmptyNonbaselineInstantiation(db, instantiationId, baselineId) {
|
|
|
24734
24939
|
}
|
|
24735
24940
|
|
|
24736
24941
|
// ../daemon/src/core/team-policy/spawn.ts
|
|
24737
|
-
import { randomUUID as
|
|
24942
|
+
import { randomUUID as randomUUID18 } from "crypto";
|
|
24738
24943
|
import { readdirSync as readdirSync4, rmSync as rmSync8 } from "fs";
|
|
24739
24944
|
|
|
24740
24945
|
// ../daemon/src/core/team-policy/rm-with-retry.ts
|
|
@@ -24901,7 +25106,7 @@ async function spawnTeamTemplate(db, paths2, input) {
|
|
|
24901
25106
|
})
|
|
24902
25107
|
);
|
|
24903
25108
|
}
|
|
24904
|
-
const instantiationId =
|
|
25109
|
+
const instantiationId = randomUUID18();
|
|
24905
25110
|
db.raw.run(
|
|
24906
25111
|
`INSERT INTO template_instantiations
|
|
24907
25112
|
(id, team_id, template_id, template_revision, created_at)
|
|
@@ -24989,6 +25194,7 @@ function safeReaddir(path) {
|
|
|
24989
25194
|
|
|
24990
25195
|
// ../daemon/src/lib/ctx.ts
|
|
24991
25196
|
import { chmodSync, existsSync as existsSync18, mkdirSync as mkdirSync10, writeFileSync as writeFileSync14 } from "fs";
|
|
25197
|
+
import { dirname as dirname7, join as join30 } from "path";
|
|
24992
25198
|
|
|
24993
25199
|
// ../daemon/src/core/repos/coding-commands.ts
|
|
24994
25200
|
var CODING_COMMAND_TTL_MS = 7 * 864e5;
|
|
@@ -25048,7 +25254,7 @@ function interruptCodingCommands(db, turnId) {
|
|
|
25048
25254
|
}
|
|
25049
25255
|
|
|
25050
25256
|
// ../daemon/src/core/repos/notifications.ts
|
|
25051
|
-
import { randomUUID as
|
|
25257
|
+
import { randomUUID as randomUUID19 } from "crypto";
|
|
25052
25258
|
var NOTIFICATION_RECEIPT_LIMIT = 1e5;
|
|
25053
25259
|
var settingsFields = `revision, enabled, restore_paused restorePaused, kinds_json kindsJson,
|
|
25054
25260
|
timezone, quiet_json quietJson, destination_json destinationJson, eligible_after eligibleAfter,
|
|
@@ -25177,7 +25383,7 @@ function admit(db, item, binding, now = Date.now()) {
|
|
|
25177
25383
|
if (existing) return decode(existing);
|
|
25178
25384
|
const count3 = db.raw.query("SELECT COUNT(*) n FROM notification_receipts").get()?.n ?? 0;
|
|
25179
25385
|
if (count3 >= NOTIFICATION_RECEIPT_LIMIT) throw new Error("notification_capacity_reached");
|
|
25180
|
-
const id =
|
|
25386
|
+
const id = randomUUID19();
|
|
25181
25387
|
db.raw.run(
|
|
25182
25388
|
`INSERT INTO notification_receipts (id, source_kind, source_id, agent_id, team_id,
|
|
25183
25389
|
destination_id, destination_json, state, created_at, updated_at)
|
|
@@ -25197,7 +25403,7 @@ function admit(db, item, binding, now = Date.now()) {
|
|
|
25197
25403
|
return get17(db, id);
|
|
25198
25404
|
})();
|
|
25199
25405
|
}
|
|
25200
|
-
function
|
|
25406
|
+
function list12(db, options = {}) {
|
|
25201
25407
|
if (options.limit !== void 0 && !Number.isFinite(options.limit))
|
|
25202
25408
|
throw new Error("notification_limit_invalid");
|
|
25203
25409
|
const limit = Math.max(1, Math.min(100, Math.trunc(options.limit ?? 50)));
|
|
@@ -25271,7 +25477,7 @@ function recoverInterrupted(db, now = Date.now()) {
|
|
|
25271
25477
|
}
|
|
25272
25478
|
|
|
25273
25479
|
// ../daemon/src/core/repos/publications.ts
|
|
25274
|
-
import { randomUUID as
|
|
25480
|
+
import { randomUUID as randomUUID20 } from "crypto";
|
|
25275
25481
|
var PUBLICATION_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
25276
25482
|
var PublicationError = class extends Error {
|
|
25277
25483
|
constructor(code, message) {
|
|
@@ -25312,7 +25518,7 @@ function toRecord(row2) {
|
|
|
25312
25518
|
}
|
|
25313
25519
|
function createPublication(db, input) {
|
|
25314
25520
|
const now = input.now ?? Date.now();
|
|
25315
|
-
const id =
|
|
25521
|
+
const id = randomUUID20();
|
|
25316
25522
|
return inTx(db, () => {
|
|
25317
25523
|
const published = db.raw.query(
|
|
25318
25524
|
"SELECT id FROM publications WHERE packet_id = ? AND state = 'published'"
|
|
@@ -25465,7 +25671,7 @@ function notePublicationError(db, id, error2, now = Date.now()) {
|
|
|
25465
25671
|
}
|
|
25466
25672
|
|
|
25467
25673
|
// ../daemon/src/core/repos/questions.ts
|
|
25468
|
-
import { createHash as
|
|
25674
|
+
import { createHash as createHash7, randomUUID as randomUUID21 } from "crypto";
|
|
25469
25675
|
|
|
25470
25676
|
// ../daemon/src/lib/question-input.ts
|
|
25471
25677
|
var QUESTION_LIMITS = Object.freeze({
|
|
@@ -25580,7 +25786,7 @@ function get18(db, agentId, id) {
|
|
|
25580
25786
|
).get(agentId, id);
|
|
25581
25787
|
return row2 ? decode2(row2) : null;
|
|
25582
25788
|
}
|
|
25583
|
-
function
|
|
25789
|
+
function list13(db, agentId, limit = 20, conversationId) {
|
|
25584
25790
|
if (!Number.isInteger(limit) || limit < 1 || limit > 100)
|
|
25585
25791
|
throw new Error("Invalid question limit");
|
|
25586
25792
|
return db.raw.query(
|
|
@@ -25592,7 +25798,7 @@ function required(db, agentId, id) {
|
|
|
25592
25798
|
if (!item) throw new Error("Question unavailable");
|
|
25593
25799
|
return item;
|
|
25594
25800
|
}
|
|
25595
|
-
function
|
|
25801
|
+
function create5(db, input, now = Date.now()) {
|
|
25596
25802
|
const question = parseQuestionInput(input.question);
|
|
25597
25803
|
if (!input.turnId || !input.toolCallId || input.turnId.length > 256 || input.toolCallId.length > 256)
|
|
25598
25804
|
throw new Error("Invalid question identity");
|
|
@@ -25611,7 +25817,7 @@ function create4(db, input, now = Date.now()) {
|
|
|
25611
25817
|
COALESCE(SUM(status = 'pending'), 0) AS pending, COALESCE(SUM(turn_id = ?), 0) AS turn FROM agent_questions`).get(input.turnId);
|
|
25612
25818
|
if (!count3 || count3.total >= QUESTION_LIMITS.recordsPerHome || count3.pending >= QUESTION_LIMITS.pendingPerHome || count3.turn >= QUESTION_LIMITS.perTurn)
|
|
25613
25819
|
throw new Error("Question capacity reached");
|
|
25614
|
-
const id =
|
|
25820
|
+
const id = randomUUID21();
|
|
25615
25821
|
db.raw.run(
|
|
25616
25822
|
`INSERT INTO agent_questions (id, agent_id, team_id, conversation_id, turn_id, tool_call_id,
|
|
25617
25823
|
question_json, binding_json, status, created_at, expires_at, continuation) VALUES (?, ?, ?, ?, ?, ?, ?, ?, 'pending', ?, ?, 'waiting')`,
|
|
@@ -25733,7 +25939,7 @@ function retireClosedApprovals(db, now) {
|
|
|
25733
25939
|
now
|
|
25734
25940
|
);
|
|
25735
25941
|
}
|
|
25736
|
-
var digest2 = (value) =>
|
|
25942
|
+
var digest2 = (value) => createHash7("sha256").update(JSON.stringify(value)).digest("hex");
|
|
25737
25943
|
function approvalSnapshot(db, agentId, id) {
|
|
25738
25944
|
const question = get18(db, agentId, id);
|
|
25739
25945
|
if (!question) return null;
|
|
@@ -25812,9 +26018,9 @@ function ownsApproval(db, capturedId, providedId) {
|
|
|
25812
26018
|
}
|
|
25813
26019
|
|
|
25814
26020
|
// ../daemon/src/core/repos/review-packets.ts
|
|
25815
|
-
import { randomUUID as
|
|
26021
|
+
import { randomUUID as randomUUID22 } from "crypto";
|
|
25816
26022
|
var REVIEW_PACKET_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
25817
|
-
var
|
|
26023
|
+
var REVIEW_LIMITS2 = {
|
|
25818
26024
|
summary: 2e3,
|
|
25819
26025
|
note: 4e3,
|
|
25820
26026
|
path: 1e3,
|
|
@@ -25842,8 +26048,8 @@ function assertLength(value, max, field) {
|
|
|
25842
26048
|
}
|
|
25843
26049
|
function createReviewPacket(db, input) {
|
|
25844
26050
|
const now = input.now ?? Date.now();
|
|
25845
|
-
const id =
|
|
25846
|
-
if (input.summary) assertLength(input.summary,
|
|
26051
|
+
const id = randomUUID22();
|
|
26052
|
+
if (input.summary) assertLength(input.summary, REVIEW_LIMITS2.summary, "summary");
|
|
25847
26053
|
db.raw.run(
|
|
25848
26054
|
`INSERT INTO review_packets (
|
|
25849
26055
|
id, team_id, requester_kind, requester_agent_id, reviewer_agent_id, snapshot_id,
|
|
@@ -25906,8 +26112,8 @@ function recordReviewExport(db, packetId, revision4, now = Date.now()) {
|
|
|
25906
26112
|
return Number(result.changes) > 0;
|
|
25907
26113
|
}
|
|
25908
26114
|
function addReviewFinding(db, input) {
|
|
25909
|
-
assertLength(input.path,
|
|
25910
|
-
assertLength(input.note,
|
|
26115
|
+
assertLength(input.path, REVIEW_LIMITS2.path, "path");
|
|
26116
|
+
assertLength(input.note, REVIEW_LIMITS2.note, "note");
|
|
25911
26117
|
if (input.note.trim() === "") {
|
|
25912
26118
|
throw new ReviewPacketError("invalid_resolution", "a finding needs a note");
|
|
25913
26119
|
}
|
|
@@ -25915,13 +26121,13 @@ function addReviewFinding(db, input) {
|
|
|
25915
26121
|
const count3 = db.raw.query(
|
|
25916
26122
|
"SELECT count(*) AS n FROM review_findings WHERE packet_id = ?"
|
|
25917
26123
|
).get(input.packetId)?.n;
|
|
25918
|
-
if ((count3 ?? 0) >=
|
|
26124
|
+
if ((count3 ?? 0) >= REVIEW_LIMITS2.findings) {
|
|
25919
26125
|
throw new ReviewPacketError(
|
|
25920
26126
|
"finding_limit",
|
|
25921
|
-
`a packet holds at most ${
|
|
26127
|
+
`a packet holds at most ${REVIEW_LIMITS2.findings} findings`
|
|
25922
26128
|
);
|
|
25923
26129
|
}
|
|
25924
|
-
const id =
|
|
26130
|
+
const id = randomUUID22();
|
|
25925
26131
|
db.raw.run(
|
|
25926
26132
|
`INSERT INTO review_findings (
|
|
25927
26133
|
id, packet_id, author_kind, author_agent_id, path, line_start, line_end, severity, note,
|
|
@@ -25968,7 +26174,7 @@ function resolveReviewFinding(db, input) {
|
|
|
25968
26174
|
if (input.resolutionNote.trim() === "") {
|
|
25969
26175
|
throw new ReviewPacketError("invalid_resolution", "resolving a finding needs a note saying how");
|
|
25970
26176
|
}
|
|
25971
|
-
assertLength(input.resolutionNote,
|
|
26177
|
+
assertLength(input.resolutionNote, REVIEW_LIMITS2.summary, "resolution note");
|
|
25972
26178
|
const now = input.now ?? Date.now();
|
|
25973
26179
|
db.raw.run(
|
|
25974
26180
|
`UPDATE review_findings
|
|
@@ -25989,8 +26195,8 @@ function resolveReviewFinding(db, input) {
|
|
|
25989
26195
|
return updated;
|
|
25990
26196
|
}
|
|
25991
26197
|
function recordReviewConclusion(db, input) {
|
|
25992
|
-
if (input.note) assertLength(input.note,
|
|
25993
|
-
const id =
|
|
26198
|
+
if (input.note) assertLength(input.note, REVIEW_LIMITS2.note, "conclusion note");
|
|
26199
|
+
const id = randomUUID22();
|
|
25994
26200
|
db.raw.run(
|
|
25995
26201
|
`INSERT INTO review_conclusions (
|
|
25996
26202
|
id, packet_id, reviewer_kind, reviewer_agent_id, conclusion, note, snapshot_id, created_at
|
|
@@ -26033,7 +26239,7 @@ function claimReviewAttempt(db, input) {
|
|
|
26033
26239
|
const next = (db.raw.query(
|
|
26034
26240
|
"SELECT COALESCE(MAX(attempt_number), 0) AS n FROM review_attempts WHERE packet_id = ?"
|
|
26035
26241
|
).get(input.packetId)?.n ?? 0) + 1;
|
|
26036
|
-
const id =
|
|
26242
|
+
const id = randomUUID22();
|
|
26037
26243
|
db.raw.run(
|
|
26038
26244
|
`INSERT INTO review_attempts (
|
|
26039
26245
|
id, packet_id, attempt_number, supersedes_attempt_id, state, lease_owner, lease_expires_at, created_at
|
|
@@ -26065,7 +26271,7 @@ function listReviewAttempts(db, packetId) {
|
|
|
26065
26271
|
).all(packetId).map(toAttempt);
|
|
26066
26272
|
}
|
|
26067
26273
|
function finishReviewAttempt(db, input) {
|
|
26068
|
-
if (input.error != null) assertLength(input.error,
|
|
26274
|
+
if (input.error != null) assertLength(input.error, REVIEW_LIMITS2.summary, "error");
|
|
26069
26275
|
const now = input.now ?? Date.now();
|
|
26070
26276
|
return inTx(db, () => {
|
|
26071
26277
|
const row2 = db.raw.query(
|
|
@@ -26156,7 +26362,7 @@ function recordReportedState(db, input) {
|
|
|
26156
26362
|
if (!REVIEW_REPORTED_STATES.includes(input.state)) {
|
|
26157
26363
|
throw new ReviewPacketError("invalid_resolution", `unknown reported state: ${input.state}`);
|
|
26158
26364
|
}
|
|
26159
|
-
if (input.reference && input.reference.length >
|
|
26365
|
+
if (input.reference && input.reference.length > REVIEW_LIMITS2.path) {
|
|
26160
26366
|
throw new ReviewPacketError("invalid_resolution", "the reported reference is too long");
|
|
26161
26367
|
}
|
|
26162
26368
|
const next = { ...packet.reported, [input.state]: input.reference?.trim() || null };
|
|
@@ -26216,7 +26422,7 @@ function toAttempt(row2) {
|
|
|
26216
26422
|
}
|
|
26217
26423
|
|
|
26218
26424
|
// ../daemon/src/core/repos/user-queue.ts
|
|
26219
|
-
import { createHash as
|
|
26425
|
+
import { createHash as createHash8, randomUUID as randomUUID23 } from "crypto";
|
|
26220
26426
|
var QUEUE_LIMITS = Object.freeze({
|
|
26221
26427
|
perAgent: 20,
|
|
26222
26428
|
perHome: 100,
|
|
@@ -26233,7 +26439,7 @@ var fields2 = `id, agent_id AS agentId, team_id AS teamId, conversation_id AS co
|
|
|
26233
26439
|
supersedes_id AS supersedesId, approval_id AS approvalId, diagnostic, created_at AS createdAt,
|
|
26234
26440
|
updated_at AS updatedAt, started_at AS startedAt, finished_at AS finishedAt`;
|
|
26235
26441
|
var uuid2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
26236
|
-
var hash2 = (value) =>
|
|
26442
|
+
var hash2 = (value) => createHash8("sha256").update(value).digest("hex");
|
|
26237
26443
|
var QueueConflictError = class extends Error {
|
|
26238
26444
|
code = "queue_conflict";
|
|
26239
26445
|
};
|
|
@@ -26299,7 +26505,7 @@ function get19(db, agentId, id) {
|
|
|
26299
26505
|
).get(agentId, id);
|
|
26300
26506
|
return row2 ? hydrate(db, row2) : null;
|
|
26301
26507
|
}
|
|
26302
|
-
function
|
|
26508
|
+
function list14(db, agentId, options = {}) {
|
|
26303
26509
|
const { all = false, limit = 20, offset = 0 } = options;
|
|
26304
26510
|
if (!Number.isSafeInteger(limit) || limit < 1 || limit > 100 || !Number.isSafeInteger(offset) || offset < 0)
|
|
26305
26511
|
throw new Error("Invalid queue pagination");
|
|
@@ -26404,7 +26610,7 @@ function accept(db, input, replacement) {
|
|
|
26404
26610
|
db.raw.run(
|
|
26405
26611
|
`INSERT INTO user_queue_attachments (id,item_id,ordinal,name,mime_type,byte_length,sha256,bytes) VALUES (?,?,?,?,?,?,?,?)`,
|
|
26406
26612
|
[
|
|
26407
|
-
|
|
26613
|
+
randomUUID23(),
|
|
26408
26614
|
input.id,
|
|
26409
26615
|
ordinal,
|
|
26410
26616
|
file.name,
|
|
@@ -26632,7 +26838,7 @@ function approvalReference(db, agentId, id) {
|
|
|
26632
26838
|
}
|
|
26633
26839
|
|
|
26634
26840
|
// ../daemon/src/core/repos/verification-requests.ts
|
|
26635
|
-
import { randomUUID as
|
|
26841
|
+
import { randomUUID as randomUUID24 } from "crypto";
|
|
26636
26842
|
var VERIFICATION_REQUEST_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
26637
26843
|
var VERIFICATION_MAX_CHECKS = 8;
|
|
26638
26844
|
var VERIFICATION_LIMITS = {
|
|
@@ -26724,7 +26930,7 @@ var VerificationRequestError = class extends Error {
|
|
|
26724
26930
|
};
|
|
26725
26931
|
function createVerificationRequest(db, input) {
|
|
26726
26932
|
const now = input.now ?? Date.now();
|
|
26727
|
-
const id = input.id ??
|
|
26933
|
+
const id = input.id ?? randomUUID24();
|
|
26728
26934
|
if (input.checks.length < 1)
|
|
26729
26935
|
throw new VerificationRequestError("a request needs at least one check");
|
|
26730
26936
|
if (input.checks.length > VERIFICATION_MAX_CHECKS) {
|
|
@@ -26842,7 +27048,7 @@ function claimVerificationAttempt(db, input) {
|
|
|
26842
27048
|
`SELECT id, attempt_number FROM verification_attempts WHERE request_id = ?
|
|
26843
27049
|
ORDER BY attempt_number DESC LIMIT 1`
|
|
26844
27050
|
).get(input.requestId);
|
|
26845
|
-
const attemptId =
|
|
27051
|
+
const attemptId = randomUUID24();
|
|
26846
27052
|
db.raw.run(
|
|
26847
27053
|
`INSERT INTO verification_attempts
|
|
26848
27054
|
(id, request_id, attempt_number, supersedes_attempt_id, state, lease_owner,
|
|
@@ -27030,7 +27236,7 @@ function unregisterAgent(agentId) {
|
|
|
27030
27236
|
if (!state3.active.delete(agentId)) return;
|
|
27031
27237
|
const waiters = state3.idleWaiters.get(agentId);
|
|
27032
27238
|
state3.idleWaiters.delete(agentId);
|
|
27033
|
-
for (const
|
|
27239
|
+
for (const resolve9 of waiters ?? []) resolve9();
|
|
27034
27240
|
}
|
|
27035
27241
|
function cancelAgent(agentId) {
|
|
27036
27242
|
const { active } = registry();
|
|
@@ -27048,9 +27254,9 @@ function ownsActiveAgent(agentId, controller) {
|
|
|
27048
27254
|
function waitForAgentIdle(agentId) {
|
|
27049
27255
|
const state3 = registry();
|
|
27050
27256
|
if (!state3.active.has(agentId)) return Promise.resolve();
|
|
27051
|
-
return new Promise((
|
|
27257
|
+
return new Promise((resolve9) => {
|
|
27052
27258
|
const waiters = state3.idleWaiters.get(agentId) ?? /* @__PURE__ */ new Set();
|
|
27053
|
-
waiters.add(
|
|
27259
|
+
waiters.add(resolve9);
|
|
27054
27260
|
state3.idleWaiters.set(agentId, waiters);
|
|
27055
27261
|
});
|
|
27056
27262
|
}
|
|
@@ -27094,25 +27300,25 @@ function reconcilePrivateResults(db, options = {}) {
|
|
|
27094
27300
|
}
|
|
27095
27301
|
|
|
27096
27302
|
// ../daemon/src/lib/coding-environment/lifecycle.ts
|
|
27097
|
-
import { randomUUID as
|
|
27303
|
+
import { randomUUID as randomUUID28 } from "crypto";
|
|
27098
27304
|
|
|
27099
27305
|
// ../daemon/src/lib/coding-environment/resources.ts
|
|
27100
|
-
import { randomUUID as
|
|
27306
|
+
import { randomUUID as randomUUID26 } from "crypto";
|
|
27101
27307
|
|
|
27102
27308
|
// ../daemon/src/runtime/shell/docker.ts
|
|
27103
27309
|
import { spawn } from "child_process";
|
|
27104
|
-
import { randomUUID as
|
|
27310
|
+
import { randomUUID as randomUUID25 } from "crypto";
|
|
27105
27311
|
import { closeSync as closeSync2, constants as constants2, mkdtempSync as mkdtempSync2, openSync as openSync2, rmSync as rmSync9, writeFileSync as writeFileSync6 } from "fs";
|
|
27106
27312
|
import { access, lstat, realpath, stat } from "fs/promises";
|
|
27107
27313
|
import { tmpdir as tmpdir2 } from "os";
|
|
27108
27314
|
import { delimiter, isAbsolute as isAbsolute2, join as join14, relative, sep as sep2 } from "path";
|
|
27109
27315
|
|
|
27110
27316
|
// ../daemon/src/runtime/coding-directory.ts
|
|
27111
|
-
import { realpathSync as
|
|
27317
|
+
import { realpathSync as realpathSync3 } from "fs";
|
|
27112
27318
|
import { join as join13 } from "path";
|
|
27113
27319
|
|
|
27114
27320
|
// ../daemon/src/lib/repository-context/files.ts
|
|
27115
|
-
import { createHash as
|
|
27321
|
+
import { createHash as createHash9 } from "crypto";
|
|
27116
27322
|
import {
|
|
27117
27323
|
closeSync,
|
|
27118
27324
|
constants,
|
|
@@ -27121,10 +27327,10 @@ import {
|
|
|
27121
27327
|
opendirSync,
|
|
27122
27328
|
openSync,
|
|
27123
27329
|
readSync,
|
|
27124
|
-
realpathSync
|
|
27330
|
+
realpathSync as realpathSync2
|
|
27125
27331
|
} from "fs";
|
|
27126
27332
|
import { isAbsolute, join as join12 } from "path";
|
|
27127
|
-
var hash3 = (value) =>
|
|
27333
|
+
var hash3 = (value) => createHash9("sha256").update(value).digest("hex");
|
|
27128
27334
|
var ContextReadError = class extends Error {
|
|
27129
27335
|
code;
|
|
27130
27336
|
constructor(code) {
|
|
@@ -27162,7 +27368,7 @@ var ContextDirectory = class _ContextDirectory {
|
|
|
27162
27368
|
this.label = label;
|
|
27163
27369
|
this.parent = parent;
|
|
27164
27370
|
if (process.platform !== "linux") throw new ContextReadError("safe_reads_unavailable");
|
|
27165
|
-
const path = parent ? join12(parent.path, registeredPath) :
|
|
27371
|
+
const path = parent ? join12(parent.path, registeredPath) : realpathSync2(registeredPath);
|
|
27166
27372
|
this.fd = openSync(path, constants.O_RDONLY | constants.O_DIRECTORY | constants.O_NOFOLLOW);
|
|
27167
27373
|
const stat2 = fstatSync(this.fd);
|
|
27168
27374
|
this.identity = hash3(identity(stat2));
|
|
@@ -27245,7 +27451,7 @@ var ContextDirectory = class _ContextDirectory {
|
|
|
27245
27451
|
}
|
|
27246
27452
|
}
|
|
27247
27453
|
validate(skipGit = false, names) {
|
|
27248
|
-
const currentPath = this.parent ? join12(this.parent.path, this.registeredPath) :
|
|
27454
|
+
const currentPath = this.parent ? join12(this.parent.path, this.registeredPath) : realpathSync2(this.registeredPath);
|
|
27249
27455
|
const stat2 = lstatSync(currentPath);
|
|
27250
27456
|
if (!stat2.isDirectory() || identity(stat2) !== this.originalStamp)
|
|
27251
27457
|
throw new ContextReadError("root_changed");
|
|
@@ -27274,7 +27480,7 @@ function resolveCodingDirectory(root, cwd) {
|
|
|
27274
27480
|
try {
|
|
27275
27481
|
let current = directory;
|
|
27276
27482
|
for (const part of relativeParts(cwd)) current = current.directory(part);
|
|
27277
|
-
const path =
|
|
27483
|
+
const path = realpathSync3(join13(root, cwd));
|
|
27278
27484
|
directory.validate();
|
|
27279
27485
|
return { path, identity: current.identity };
|
|
27280
27486
|
} finally {
|
|
@@ -27591,7 +27797,7 @@ function createPreparedDockerBashOperations(runtime, lifecycle) {
|
|
|
27591
27797
|
}
|
|
27592
27798
|
await assertDockerExecutableIdentity(runtime.dockerPath, runtime.executableIdentity);
|
|
27593
27799
|
if (signal?.aborted) throw new Error("aborted");
|
|
27594
|
-
const containerName = lifecycle?.name("bash") ?? `bazilion-bash-${process.pid}-${
|
|
27800
|
+
const containerName = lifecycle?.name("bash") ?? `bazilion-bash-${process.pid}-${randomUUID25().replaceAll("-", "")}`;
|
|
27595
27801
|
const spec = buildDockerRunSpec({
|
|
27596
27802
|
image: runtime.image,
|
|
27597
27803
|
resolvedImage: runtime.imageId,
|
|
@@ -27640,7 +27846,7 @@ async function preflightProtectedDockerEngine(input) {
|
|
|
27640
27846
|
}
|
|
27641
27847
|
async function proveProtectedContainerCreation(engine, workspace, readOnlyMounts, lifecycle, signal) {
|
|
27642
27848
|
if (signal?.aborted) throw new Error("aborted");
|
|
27643
|
-
const containerName = lifecycle?.name("preflight") ?? `bazilion-preflight-${process.pid}-${
|
|
27849
|
+
const containerName = lifecycle?.name("preflight") ?? `bazilion-preflight-${process.pid}-${randomUUID25().replaceAll("-", "")}`;
|
|
27644
27850
|
const dockerClientEnv = { DOCKER_HOST: engine.endpoint };
|
|
27645
27851
|
const spec = buildDockerRunSpec({
|
|
27646
27852
|
image: engine.image,
|
|
@@ -27701,7 +27907,7 @@ function runProtectedContainerCreate(spec, options) {
|
|
|
27701
27907
|
)
|
|
27702
27908
|
);
|
|
27703
27909
|
}
|
|
27704
|
-
return new Promise((
|
|
27910
|
+
return new Promise((resolve9, reject2) => {
|
|
27705
27911
|
let child;
|
|
27706
27912
|
try {
|
|
27707
27913
|
child = spawn(spec.executable, ["container", "create", ...spec.args.slice(1)], {
|
|
@@ -27727,7 +27933,7 @@ function runProtectedContainerCreate(spec, options) {
|
|
|
27727
27933
|
if (killSettleHandle) clearTimeout(killSettleHandle);
|
|
27728
27934
|
options?.signal?.removeEventListener("abort", onAbort);
|
|
27729
27935
|
if (error2) reject2(error2);
|
|
27730
|
-
else
|
|
27936
|
+
else resolve9();
|
|
27731
27937
|
};
|
|
27732
27938
|
const commandTimeout = options?.timeoutMs !== void 0 && options.timeoutMs <= DOCKER_CREATE_TIMEOUT_MS;
|
|
27733
27939
|
const timeoutError = () => commandTimeout ? new Error(`timeout:${options?.timeout}`) : new Error(
|
|
@@ -27759,7 +27965,7 @@ function runProtectedContainerCreate(spec, options) {
|
|
|
27759
27965
|
}
|
|
27760
27966
|
function runProtectedContainerProbe(spec, signal) {
|
|
27761
27967
|
if (signal?.aborted) return Promise.reject(new Error("aborted"));
|
|
27762
|
-
return new Promise((
|
|
27968
|
+
return new Promise((resolve9, reject2) => {
|
|
27763
27969
|
let child;
|
|
27764
27970
|
try {
|
|
27765
27971
|
child = spawn(spec.executable, ["container", "start", "--attach", spec.containerName], {
|
|
@@ -27783,7 +27989,7 @@ function runProtectedContainerProbe(spec, signal) {
|
|
|
27783
27989
|
if (killSettleHandle) clearTimeout(killSettleHandle);
|
|
27784
27990
|
signal?.removeEventListener("abort", onAbort);
|
|
27785
27991
|
if (error2) reject2(error2);
|
|
27786
|
-
else
|
|
27992
|
+
else resolve9();
|
|
27787
27993
|
};
|
|
27788
27994
|
const timeoutError = () => new Error(
|
|
27789
27995
|
`Docker sandbox could not start its protected preflight container within ${DOCKER_PROBE_START_TIMEOUT_MS}ms`
|
|
@@ -27816,7 +28022,7 @@ async function removePreflightContainer(dockerPath, containerName, processEnv, c
|
|
|
27816
28022
|
last = await runCleanupCommand(dockerPath, args, processEnv);
|
|
27817
28023
|
if (last.ok && !last.missing) return;
|
|
27818
28024
|
if (attempt < CLEANUP_ATTEMPTS - 1) {
|
|
27819
|
-
await new Promise((
|
|
28025
|
+
await new Promise((resolve9) => setTimeout(resolve9, CLEANUP_RETRY_DELAY_MS));
|
|
27820
28026
|
}
|
|
27821
28027
|
}
|
|
27822
28028
|
if (last?.missing && creationAcknowledged) return;
|
|
@@ -27972,7 +28178,7 @@ function createDockerBashOperations(options) {
|
|
|
27972
28178
|
const dockerClientEnv = await resolveLocalDockerClientEnv(dockerPath, hostEnv);
|
|
27973
28179
|
const resolvedImage = await inspectSandboxImage(dockerPath, image, dockerClientEnv);
|
|
27974
28180
|
if (signal?.aborted) throw new Error("aborted");
|
|
27975
|
-
const containerName = options.lifecycle?.name("bash") ?? `bazilion-bash-${process.pid}-${
|
|
28181
|
+
const containerName = options.lifecycle?.name("bash") ?? `bazilion-bash-${process.pid}-${randomUUID25().replaceAll("-", "")}`;
|
|
27976
28182
|
const spec = buildDockerRunSpec({
|
|
27977
28183
|
image,
|
|
27978
28184
|
env,
|
|
@@ -28037,7 +28243,7 @@ function executeDockerRun(spec, options) {
|
|
|
28037
28243
|
)
|
|
28038
28244
|
);
|
|
28039
28245
|
}
|
|
28040
|
-
return new Promise((
|
|
28246
|
+
return new Promise((resolve9, reject2) => {
|
|
28041
28247
|
const child = spawn(spec.executable, spec.args, {
|
|
28042
28248
|
stdio: ["ignore", "pipe", "pipe", envFileFd ?? "ignore"],
|
|
28043
28249
|
windowsHide: true,
|
|
@@ -28080,7 +28286,7 @@ function executeDockerRun(spec, options) {
|
|
|
28080
28286
|
reject2(new Error(`Docker sandbox CLI for container "${spec.containerName}" was killed`));
|
|
28081
28287
|
return;
|
|
28082
28288
|
}
|
|
28083
|
-
|
|
28289
|
+
resolve9({ exitCode });
|
|
28084
28290
|
};
|
|
28085
28291
|
child.stdout?.on("data", options.onData);
|
|
28086
28292
|
child.stderr?.on("data", (data) => {
|
|
@@ -28249,7 +28455,7 @@ async function inspectSandboxImage(dockerPath, image, processEnv) {
|
|
|
28249
28455
|
return id;
|
|
28250
28456
|
}
|
|
28251
28457
|
function runDockerInspection(dockerPath, args, processEnv, subject) {
|
|
28252
|
-
return new Promise((
|
|
28458
|
+
return new Promise((resolve9, reject2) => {
|
|
28253
28459
|
const child = spawn(dockerPath, args, {
|
|
28254
28460
|
stdio: ["ignore", "pipe", "pipe"],
|
|
28255
28461
|
windowsHide: true,
|
|
@@ -28266,7 +28472,7 @@ function runDockerInspection(dockerPath, args, processEnv, subject) {
|
|
|
28266
28472
|
reject2(error2);
|
|
28267
28473
|
return;
|
|
28268
28474
|
}
|
|
28269
|
-
|
|
28475
|
+
resolve9(stdout.trim());
|
|
28270
28476
|
};
|
|
28271
28477
|
const timeoutHandle = setTimeout(() => {
|
|
28272
28478
|
child.kill("SIGKILL");
|
|
@@ -28405,7 +28611,7 @@ async function removeContainer(dockerPath, containerName, processEnv) {
|
|
|
28405
28611
|
last = await runCleanupCommand(dockerPath, args, processEnv);
|
|
28406
28612
|
if (last.ok) return;
|
|
28407
28613
|
if (attempt < CLEANUP_ATTEMPTS - 1) {
|
|
28408
|
-
await new Promise((
|
|
28614
|
+
await new Promise((resolve9) => setTimeout(resolve9, CLEANUP_RETRY_DELAY_MS));
|
|
28409
28615
|
}
|
|
28410
28616
|
}
|
|
28411
28617
|
if (last && !last.missing) {
|
|
@@ -28415,7 +28621,7 @@ async function removeContainer(dockerPath, containerName, processEnv) {
|
|
|
28415
28621
|
}
|
|
28416
28622
|
}
|
|
28417
28623
|
function runCleanupCommand(dockerPath, args, processEnv) {
|
|
28418
|
-
return new Promise((
|
|
28624
|
+
return new Promise((resolve9) => {
|
|
28419
28625
|
let done = false;
|
|
28420
28626
|
let stderr = "";
|
|
28421
28627
|
const child = spawn(dockerPath, args, {
|
|
@@ -28428,7 +28634,7 @@ function runCleanupCommand(dockerPath, args, processEnv) {
|
|
|
28428
28634
|
done = true;
|
|
28429
28635
|
clearTimeout(timeoutHandle);
|
|
28430
28636
|
const detail3 = error2 || stderr.trim();
|
|
28431
|
-
|
|
28637
|
+
resolve9({
|
|
28432
28638
|
ok,
|
|
28433
28639
|
missing: /no such container/i.test(detail3),
|
|
28434
28640
|
error: detail3
|
|
@@ -28596,7 +28802,7 @@ async function terminateWorkerProcess(identity2, observedNormalExit = false) {
|
|
|
28596
28802
|
}
|
|
28597
28803
|
killed = true;
|
|
28598
28804
|
}
|
|
28599
|
-
await new Promise((
|
|
28805
|
+
await new Promise((resolve9) => setTimeout(resolve9, 25));
|
|
28600
28806
|
}
|
|
28601
28807
|
return false;
|
|
28602
28808
|
} catch {
|
|
@@ -28628,7 +28834,7 @@ var WorkspaceResources = class {
|
|
|
28628
28834
|
}
|
|
28629
28835
|
register(lease, resource) {
|
|
28630
28836
|
return inTx(this.db, () => {
|
|
28631
|
-
const id =
|
|
28837
|
+
const id = randomUUID26();
|
|
28632
28838
|
lease.attach({ id, kind: resource.kind });
|
|
28633
28839
|
this.db.raw.run(
|
|
28634
28840
|
"INSERT INTO workspace_resources (id, writer_id, kind, identity_json) VALUES (?, ?, ?, ?)",
|
|
@@ -28666,8 +28872,8 @@ var WorkspaceResources = class {
|
|
|
28666
28872
|
};
|
|
28667
28873
|
|
|
28668
28874
|
// ../daemon/src/lib/coding-environment/workspace.ts
|
|
28669
|
-
import { randomUUID as
|
|
28670
|
-
import { realpathSync as
|
|
28875
|
+
import { randomUUID as randomUUID27 } from "crypto";
|
|
28876
|
+
import { realpathSync as realpathSync4, statSync as statSync4 } from "fs";
|
|
28671
28877
|
import { isAbsolute as isAbsolute3, relative as relative2 } from "path";
|
|
28672
28878
|
var WorkspaceBusyError = class extends Error {
|
|
28673
28879
|
constructor(recoveryRequired = false) {
|
|
@@ -28685,14 +28891,18 @@ function overlappingWorkspaceRoots(a, b2) {
|
|
|
28685
28891
|
return contains(a, b2) || contains(b2, a);
|
|
28686
28892
|
}
|
|
28687
28893
|
function workspaceIdentity(registeredRoot) {
|
|
28688
|
-
|
|
28689
|
-
|
|
28690
|
-
|
|
28691
|
-
|
|
28692
|
-
|
|
28693
|
-
|
|
28694
|
-
|
|
28894
|
+
if (process.platform === "linux") {
|
|
28895
|
+
const directory = new ContextDirectory(registeredRoot);
|
|
28896
|
+
try {
|
|
28897
|
+
const root2 = realpathSync4(registeredRoot);
|
|
28898
|
+
directory.validate();
|
|
28899
|
+
return { root: root2, rootIdentity: directory.identity };
|
|
28900
|
+
} finally {
|
|
28901
|
+
directory.close();
|
|
28902
|
+
}
|
|
28695
28903
|
}
|
|
28904
|
+
const root = realpathSync4(registeredRoot);
|
|
28905
|
+
return { root, rootIdentity: hash3(identity(statSync4(root))) };
|
|
28696
28906
|
}
|
|
28697
28907
|
function view(row2) {
|
|
28698
28908
|
return {
|
|
@@ -28710,7 +28920,7 @@ var WorkspaceCoordinator = class {
|
|
|
28710
28920
|
this.db = db;
|
|
28711
28921
|
}
|
|
28712
28922
|
db;
|
|
28713
|
-
identity =
|
|
28923
|
+
identity = randomUUID27();
|
|
28714
28924
|
leases = /* @__PURE__ */ new Set();
|
|
28715
28925
|
issued = /* @__PURE__ */ new WeakSet();
|
|
28716
28926
|
claim(teamId, registeredRoot, kind) {
|
|
@@ -28724,7 +28934,7 @@ var WorkspaceCoordinator = class {
|
|
|
28724
28934
|
const recovery = row2.daemon_identity !== this.identity || row2.state === "recovery";
|
|
28725
28935
|
if (recovery || exclusive || row2.exclusive === 1) throw new WorkspaceBusyError(recovery);
|
|
28726
28936
|
}
|
|
28727
|
-
const id =
|
|
28937
|
+
const id = randomUUID27();
|
|
28728
28938
|
this.db.raw.run(
|
|
28729
28939
|
`INSERT INTO workspace_writers
|
|
28730
28940
|
(id, team_id, root_path, root_identity, daemon_identity, kind, exclusive, state, created_at)
|
|
@@ -28843,7 +29053,7 @@ var WorkspaceLifecycle = class {
|
|
|
28843
29053
|
const prefix = `bazilion-${lease.writer.id}-`;
|
|
28844
29054
|
const records2 = /* @__PURE__ */ new Map();
|
|
28845
29055
|
return {
|
|
28846
|
-
name: (kind) => `${prefix}${kind}-${
|
|
29056
|
+
name: (kind) => `${prefix}${kind}-${randomUUID28()}`,
|
|
28847
29057
|
beforeCreate: async (identity2) => {
|
|
28848
29058
|
if (!identity2.containerName.startsWith(prefix) || !/^bazilion-[a-z0-9-]{1,160}$/.test(identity2.containerName) || records2.has(identity2.containerName))
|
|
28849
29059
|
throw new Error("Invalid turn container identity");
|
|
@@ -28878,7 +29088,7 @@ var WorkspaceLifecycle = class {
|
|
|
28878
29088
|
};
|
|
28879
29089
|
|
|
28880
29090
|
// ../daemon/src/lib/conversation-target.ts
|
|
28881
|
-
import { randomUUID as
|
|
29091
|
+
import { randomUUID as randomUUID30 } from "crypto";
|
|
28882
29092
|
|
|
28883
29093
|
// ../daemon/src/core/repos/conversations.ts
|
|
28884
29094
|
var columns = "id, agent_id AS agentId, title, title_revision AS titleRevision, created_at AS createdAt, updated_at AS updatedAt";
|
|
@@ -28919,7 +29129,7 @@ function filename(db, agentId, id) {
|
|
|
28919
29129
|
if (!row2) throw new Error("Conversation not found");
|
|
28920
29130
|
return row2.filename;
|
|
28921
29131
|
}
|
|
28922
|
-
function
|
|
29132
|
+
function list15(db, agentId, limit = 20, offset = 0) {
|
|
28923
29133
|
if (!Number.isSafeInteger(limit) || limit < 1 || limit > 100 || !Number.isSafeInteger(offset) || offset < 0)
|
|
28924
29134
|
throw new Error("Invalid conversation pagination");
|
|
28925
29135
|
const conversations = db.raw.query(
|
|
@@ -28935,7 +29145,7 @@ function title(value) {
|
|
|
28935
29145
|
throw new Error("Conversation title must be 1\u2013200 characters without control characters");
|
|
28936
29146
|
return value.trim();
|
|
28937
29147
|
}
|
|
28938
|
-
function
|
|
29148
|
+
function create6(db, agentId, input, persistFile) {
|
|
28939
29149
|
if (!uuid3.test(input.requestId)) throw new Error("Conversation requestId must be a UUID");
|
|
28940
29150
|
if (!input.expectedSelection || !Number.isSafeInteger(input.expectedSelection.revision) || input.expectedSelection.revision < 0 || input.expectedSelection.conversationId !== null && (typeof input.expectedSelection.conversationId !== "string" || !uuid3.test(input.expectedSelection.conversationId)))
|
|
28941
29151
|
throw new Error("Invalid expected conversation selection");
|
|
@@ -28955,7 +29165,7 @@ function create5(db, agentId, input, persistFile) {
|
|
|
28955
29165
|
if (!db.raw.query("SELECT id FROM agents WHERE id = ?").get(agentId))
|
|
28956
29166
|
throw new Error("Agent not found");
|
|
28957
29167
|
const now = Date.now();
|
|
28958
|
-
const displayTitle = initialTitle ?? `Conversation ${
|
|
29168
|
+
const displayTitle = initialTitle ?? `Conversation ${list15(db, agentId, 1).total + 1}`;
|
|
28959
29169
|
const file = persistFile(input.requestId);
|
|
28960
29170
|
if (file !== `${input.requestId}.jsonl`)
|
|
28961
29171
|
throw new Error("Invalid canonical conversation filename");
|
|
@@ -29000,14 +29210,14 @@ function rename(db, agentId, id, value, expectedRevision) {
|
|
|
29000
29210
|
}
|
|
29001
29211
|
|
|
29002
29212
|
// ../daemon/src/lib/conversation-file.ts
|
|
29003
|
-
import { randomUUID as
|
|
29213
|
+
import { randomUUID as randomUUID29 } from "crypto";
|
|
29004
29214
|
import {
|
|
29005
29215
|
closeSync as closeSync4,
|
|
29006
29216
|
constants as constants4,
|
|
29007
29217
|
fsyncSync,
|
|
29008
29218
|
linkSync,
|
|
29009
29219
|
openSync as openSync4,
|
|
29010
|
-
realpathSync as
|
|
29220
|
+
realpathSync as realpathSync6,
|
|
29011
29221
|
unlinkSync,
|
|
29012
29222
|
writeFileSync as writeFileSync7
|
|
29013
29223
|
} from "fs";
|
|
@@ -29015,18 +29225,21 @@ import { join as join16 } from "path";
|
|
|
29015
29225
|
import { SessionManager } from "@earendil-works/pi-coding-agent";
|
|
29016
29226
|
|
|
29017
29227
|
// ../daemon/src/lib/result-source.ts
|
|
29018
|
-
import { closeSync as closeSync3, constants as constants3, fstatSync as fstatSync2, openSync as openSync3, readSync as readSync2, realpathSync as
|
|
29019
|
-
import { basename as
|
|
29228
|
+
import { closeSync as closeSync3, constants as constants3, fstatSync as fstatSync2, lstatSync as lstatSync2, openSync as openSync3, readSync as readSync2, realpathSync as realpathSync5 } from "fs";
|
|
29229
|
+
import { basename as basename3, join as join15 } from "path";
|
|
29020
29230
|
function readResultSession(paths2, agentId, filename2, sessionId, minimumEntryOffset = 0) {
|
|
29021
|
-
if (
|
|
29022
|
-
const directory = join15(
|
|
29231
|
+
if (basename3(filename2) !== filename2) throw new Error("Invalid result session filename");
|
|
29232
|
+
const directory = join15(realpathSync5(paths2.agentsDir), agentId, "sessions");
|
|
29023
29233
|
return readCanonicalSessionFile(directory, filename2, sessionId, minimumEntryOffset);
|
|
29024
29234
|
}
|
|
29025
29235
|
function readCanonicalSessionFile(directory, filename2, sessionId, minimumEntryOffset = 0) {
|
|
29026
|
-
if (
|
|
29027
|
-
if (
|
|
29236
|
+
if (basename3(filename2) !== filename2) throw new Error("Invalid session filename");
|
|
29237
|
+
if (realpathSync5(directory) !== directory) throw new Error("Result session escaped its owner");
|
|
29238
|
+
const target = join15(directory, filename2);
|
|
29239
|
+
if (lstatSync2(target).isSymbolicLink())
|
|
29240
|
+
throw new Error("Result session file must not be a symlink");
|
|
29028
29241
|
const fd = openSync3(
|
|
29029
|
-
|
|
29242
|
+
target,
|
|
29030
29243
|
constants3.O_RDONLY | constants3.O_NOFOLLOW | constants3.O_NONBLOCK
|
|
29031
29244
|
);
|
|
29032
29245
|
try {
|
|
@@ -29061,11 +29274,11 @@ var uuid4 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
|
29061
29274
|
function createConversationFile(paths2, agentId, conversationId, cwd) {
|
|
29062
29275
|
if (!uuid4.test(agentId) || !uuid4.test(conversationId))
|
|
29063
29276
|
throw new Error("Invalid conversation identity");
|
|
29064
|
-
const directory = join16(
|
|
29065
|
-
if (
|
|
29277
|
+
const directory = join16(realpathSync6(paths2.agentsDir), agentId, "sessions");
|
|
29278
|
+
if (realpathSync6(directory) !== directory) throw new Error("Conversation escaped its Agent");
|
|
29066
29279
|
const filename2 = `${conversationId}.jsonl`;
|
|
29067
29280
|
const destination = join16(directory, filename2);
|
|
29068
|
-
const staging = join16(directory, `.conversation-${
|
|
29281
|
+
const staging = join16(directory, `.conversation-${randomUUID29()}.tmp`);
|
|
29069
29282
|
const header = SessionManager.inMemory(cwd, { id: conversationId }).getHeader();
|
|
29070
29283
|
const fd = openSync4(staging, constants4.O_WRONLY | constants4.O_CREAT | constants4.O_EXCL, 384);
|
|
29071
29284
|
try {
|
|
@@ -29085,6 +29298,8 @@ function createConversationFile(paths2, agentId, conversationId, cwd) {
|
|
|
29085
29298
|
const directoryFd = openSync4(directory, constants4.O_RDONLY | constants4.O_DIRECTORY);
|
|
29086
29299
|
try {
|
|
29087
29300
|
fsyncSync(directoryFd);
|
|
29301
|
+
} catch (error2) {
|
|
29302
|
+
if (process.platform !== "win32") throw error2;
|
|
29088
29303
|
} finally {
|
|
29089
29304
|
closeSync4(directoryFd);
|
|
29090
29305
|
}
|
|
@@ -29099,11 +29314,11 @@ function resolveConversationTarget(db, paths2, agentId, pinnedId) {
|
|
|
29099
29314
|
let id = pinnedId ?? selection(db, agentId).conversationId;
|
|
29100
29315
|
if (!id) {
|
|
29101
29316
|
const agent = resolveAgent(db, paths2, agentId);
|
|
29102
|
-
id =
|
|
29317
|
+
id = create6(
|
|
29103
29318
|
db,
|
|
29104
29319
|
agentId,
|
|
29105
29320
|
{
|
|
29106
|
-
requestId:
|
|
29321
|
+
requestId: randomUUID30(),
|
|
29107
29322
|
expectedSelection: { conversationId: null, revision: 0 }
|
|
29108
29323
|
},
|
|
29109
29324
|
(newId) => createConversationFile(paths2, agentId, newId, agent.team.path)
|
|
@@ -29135,9 +29350,9 @@ function acquireAgentLifecycleLease(agentId) {
|
|
|
29135
29350
|
leases.held.add(agentId);
|
|
29136
29351
|
return Promise.resolve(makeRelease(agentId));
|
|
29137
29352
|
}
|
|
29138
|
-
return new Promise((
|
|
29353
|
+
return new Promise((resolve9) => {
|
|
29139
29354
|
const queue = leases.waiters.get(agentId) ?? [];
|
|
29140
|
-
queue.push({ resolve:
|
|
29355
|
+
queue.push({ resolve: resolve9 });
|
|
29141
29356
|
leases.waiters.set(agentId, queue);
|
|
29142
29357
|
});
|
|
29143
29358
|
}
|
|
@@ -29170,7 +29385,7 @@ async function runAgentLifecycleMutation(agentId, mutation) {
|
|
|
29170
29385
|
}
|
|
29171
29386
|
|
|
29172
29387
|
// ../daemon/src/lib/agent-loop-guard.ts
|
|
29173
|
-
import { randomUUID as
|
|
29388
|
+
import { randomUUID as randomUUID31 } from "crypto";
|
|
29174
29389
|
var DEFAULT_MAX_HOPS = 8;
|
|
29175
29390
|
function toEvent(row2) {
|
|
29176
29391
|
return {
|
|
@@ -29222,8 +29437,8 @@ function enforceMessageCausality(db, input) {
|
|
|
29222
29437
|
const target = agents_exports.get(db, input.to);
|
|
29223
29438
|
if (!source || !target) return null;
|
|
29224
29439
|
const event2 = {
|
|
29225
|
-
id:
|
|
29226
|
-
causalChainId: input.causality.causalChainId ?? input.causality.parentMessageId ??
|
|
29440
|
+
id: randomUUID31(),
|
|
29441
|
+
causalChainId: input.causality.causalChainId ?? input.causality.parentMessageId ?? randomUUID31(),
|
|
29227
29442
|
parentMessageId: input.causality.parentMessageId,
|
|
29228
29443
|
fromAgentId: input.from,
|
|
29229
29444
|
toAgentId: input.to,
|
|
@@ -29387,26 +29602,26 @@ import {
|
|
|
29387
29602
|
readdirSync as readdirSync6,
|
|
29388
29603
|
readFileSync as readFileSync9,
|
|
29389
29604
|
rmSync as rmSync10,
|
|
29390
|
-
statSync as
|
|
29605
|
+
statSync as statSync5,
|
|
29391
29606
|
writeFileSync as writeFileSync8
|
|
29392
29607
|
} from "fs";
|
|
29393
|
-
import { dirname as
|
|
29608
|
+
import { dirname as dirname3, join as join17 } from "path";
|
|
29394
29609
|
|
|
29395
29610
|
// ../daemon/src/runtime/memory/qmd.ts
|
|
29396
29611
|
import {
|
|
29397
29612
|
closeSync as closeSync5,
|
|
29398
29613
|
constants as constants5,
|
|
29399
29614
|
fstatSync as fstatSync3,
|
|
29400
|
-
lstatSync as
|
|
29615
|
+
lstatSync as lstatSync3,
|
|
29401
29616
|
mkdirSync as mkdirSync5,
|
|
29402
29617
|
openSync as openSync5,
|
|
29403
29618
|
readdirSync as readdirSync7,
|
|
29404
29619
|
readFileSync as readFileSync10,
|
|
29405
|
-
realpathSync as
|
|
29620
|
+
realpathSync as realpathSync7,
|
|
29406
29621
|
rmSync as rmSync11,
|
|
29407
29622
|
writeFileSync as writeFileSync9
|
|
29408
29623
|
} from "fs";
|
|
29409
|
-
import { dirname as
|
|
29624
|
+
import { dirname as dirname4, isAbsolute as isAbsolute4, join as join18, relative as relative3, resolve as resolve4, sep as sep3 } from "path";
|
|
29410
29625
|
import { createStore, extractSnippet } from "@tobilu/qmd";
|
|
29411
29626
|
|
|
29412
29627
|
// ../daemon/src/lib/native-module-error.ts
|
|
@@ -29473,7 +29688,7 @@ function unsafeMemoryPath(path, reason) {
|
|
|
29473
29688
|
}
|
|
29474
29689
|
function lstatIfPresent(path) {
|
|
29475
29690
|
try {
|
|
29476
|
-
return
|
|
29691
|
+
return lstatSync3(path);
|
|
29477
29692
|
} catch (error2) {
|
|
29478
29693
|
if (error2.code === "ENOENT") return void 0;
|
|
29479
29694
|
throw error2;
|
|
@@ -29490,14 +29705,14 @@ function assertContained(root, candidate) {
|
|
|
29490
29705
|
}
|
|
29491
29706
|
function initializeSafeRoot(root) {
|
|
29492
29707
|
mkdirSync5(root, { recursive: true });
|
|
29493
|
-
const info =
|
|
29708
|
+
const info = lstatSync3(root);
|
|
29494
29709
|
if (info.isSymbolicLink()) {
|
|
29495
29710
|
throw unsafeMemoryPath(root, "memory root must not be a symbolic link");
|
|
29496
29711
|
}
|
|
29497
29712
|
if (!info.isDirectory()) {
|
|
29498
29713
|
throw unsafeMemoryPath(root, "memory root is not a directory");
|
|
29499
29714
|
}
|
|
29500
|
-
return
|
|
29715
|
+
return realpathSync7(root);
|
|
29501
29716
|
}
|
|
29502
29717
|
function assertRootUnchanged(root, canonicalRoot) {
|
|
29503
29718
|
const info = lstatIfPresent(root);
|
|
@@ -29508,7 +29723,7 @@ function assertRootUnchanged(root, canonicalRoot) {
|
|
|
29508
29723
|
if (!info.isDirectory()) {
|
|
29509
29724
|
throw unsafeMemoryPath(root, "memory root is not a directory");
|
|
29510
29725
|
}
|
|
29511
|
-
const current =
|
|
29726
|
+
const current = realpathSync7(root);
|
|
29512
29727
|
if (relative3(canonicalRoot, current) !== "" || relative3(current, canonicalRoot) !== "") {
|
|
29513
29728
|
throw unsafeMemoryPath(root, "memory root changed after initialization");
|
|
29514
29729
|
}
|
|
@@ -29518,7 +29733,7 @@ function safeKey(root, key3) {
|
|
|
29518
29733
|
if (key3.length === 0 || key3.includes("\0") || isAbsolute4(key3) || /^[A-Za-z]:[\\/]/.test(key3) || key3.startsWith("\\\\") || segments.includes("..")) {
|
|
29519
29734
|
throw new Error(`unsafe memory key: ${key3}`);
|
|
29520
29735
|
}
|
|
29521
|
-
const candidate =
|
|
29736
|
+
const candidate = resolve4(root, key3);
|
|
29522
29737
|
if (candidate === root) throw new Error(`unsafe memory key: ${key3}`);
|
|
29523
29738
|
assertContained(root, candidate);
|
|
29524
29739
|
return candidate;
|
|
@@ -29538,12 +29753,12 @@ function inspectSafePath(root, path) {
|
|
|
29538
29753
|
if (index < components.length - 1 && !info.isDirectory()) {
|
|
29539
29754
|
throw unsafeMemoryPath(current, "path ancestor is not a directory");
|
|
29540
29755
|
}
|
|
29541
|
-
assertContained(root,
|
|
29756
|
+
assertContained(root, realpathSync7(current));
|
|
29542
29757
|
}
|
|
29543
29758
|
return lstatIfPresent(path);
|
|
29544
29759
|
}
|
|
29545
29760
|
function ensureSafeParentDirectories(root, path) {
|
|
29546
|
-
const parent =
|
|
29761
|
+
const parent = dirname4(path);
|
|
29547
29762
|
assertContained(root, parent);
|
|
29548
29763
|
const rel = relative3(root, parent);
|
|
29549
29764
|
let current = root;
|
|
@@ -29552,7 +29767,7 @@ function ensureSafeParentDirectories(root, path) {
|
|
|
29552
29767
|
let info = lstatIfPresent(current);
|
|
29553
29768
|
if (!info) {
|
|
29554
29769
|
mkdirSync5(current);
|
|
29555
|
-
info =
|
|
29770
|
+
info = lstatSync3(current);
|
|
29556
29771
|
}
|
|
29557
29772
|
if (info.isSymbolicLink()) {
|
|
29558
29773
|
throw unsafeMemoryPath(current, "symbolic-link ancestors are not allowed");
|
|
@@ -29560,7 +29775,7 @@ function ensureSafeParentDirectories(root, path) {
|
|
|
29560
29775
|
if (!info.isDirectory()) {
|
|
29561
29776
|
throw unsafeMemoryPath(current, "path ancestor is not a directory");
|
|
29562
29777
|
}
|
|
29563
|
-
assertContained(root,
|
|
29778
|
+
assertContained(root, realpathSync7(current));
|
|
29564
29779
|
}
|
|
29565
29780
|
}
|
|
29566
29781
|
function readSafeFile(root, path) {
|
|
@@ -29612,10 +29827,10 @@ function writeSafeFile(root, path, content) {
|
|
|
29612
29827
|
}
|
|
29613
29828
|
}
|
|
29614
29829
|
function assertSafeTree(root, dir = root) {
|
|
29615
|
-
assertContained(root,
|
|
29830
|
+
assertContained(root, realpathSync7(dir));
|
|
29616
29831
|
for (const entry of readdirSync7(dir, { withFileTypes: true })) {
|
|
29617
29832
|
const full = join18(dir, entry.name);
|
|
29618
|
-
const info =
|
|
29833
|
+
const info = lstatSync3(full);
|
|
29619
29834
|
if (info.isSymbolicLink()) {
|
|
29620
29835
|
throw unsafeMemoryPath(full, "symbolic links are not allowed in memory storage");
|
|
29621
29836
|
}
|
|
@@ -29629,7 +29844,7 @@ function assertSafeTree(root, dir = root) {
|
|
|
29629
29844
|
function walkMd(root, dir, prefix, out) {
|
|
29630
29845
|
for (const entry of readdirSync7(dir, { withFileTypes: true })) {
|
|
29631
29846
|
const full = join18(dir, entry.name);
|
|
29632
|
-
const info =
|
|
29847
|
+
const info = lstatSync3(full);
|
|
29633
29848
|
if (info.isSymbolicLink()) {
|
|
29634
29849
|
throw unsafeMemoryPath(full, "symbolic links are not allowed in memory storage");
|
|
29635
29850
|
}
|
|
@@ -30599,7 +30814,7 @@ var keys = (value, required3, optional2 = []) => required3.every((key3) => Objec
|
|
|
30599
30814
|
var string = (value, limit = 4096) => typeof value === "string" && value.length <= limit;
|
|
30600
30815
|
var digest3 = (value) => typeof value === "string" && /^[a-f0-9]{64}$/.test(value);
|
|
30601
30816
|
var count2 = (value) => Number.isSafeInteger(value) && value >= 0;
|
|
30602
|
-
var
|
|
30817
|
+
var list16 = (value, limit, check) => Array.isArray(value) && value.length <= limit && value.every(check);
|
|
30603
30818
|
var issue = (value) => object2(value) && keys(value, ["code", "message"], ["path"]) && string(value.code, 100) && string(value.message, 1024) && (value.path === void 0 || string(value.path));
|
|
30604
30819
|
function assertRepositoryContext(value, teamId) {
|
|
30605
30820
|
if (!object2(value) || !keys(value, [
|
|
@@ -30628,15 +30843,15 @@ function assertRepositoryContext(value, teamId) {
|
|
|
30628
30843
|
"untracked",
|
|
30629
30844
|
"conflicted",
|
|
30630
30845
|
"issues"
|
|
30631
|
-
]) || !["complete", "incomplete"].includes(String(instructions.state)) || !
|
|
30846
|
+
]) || !["complete", "incomplete"].includes(String(instructions.state)) || !list16(instructions.issues, 128, issue) || !list16(
|
|
30632
30847
|
instructions.files,
|
|
30633
30848
|
17,
|
|
30634
30849
|
(file) => object2(file) && keys(file, ["path", "scope", "precedence", "sha256", "content"]) && string(file.path) && string(file.scope) && count2(file.precedence) && digest3(file.sha256) && string(file.content, 64 * 1024) && Buffer.byteLength(file.content) <= 64 * 1024
|
|
30635
|
-
) || !["complete", "incomplete"].includes(String(commands.state)) || !
|
|
30850
|
+
) || !["complete", "incomplete"].includes(String(commands.state)) || !list16(commands.issues, 128, issue) || !list16(
|
|
30636
30851
|
commands.sources,
|
|
30637
30852
|
32,
|
|
30638
30853
|
(source) => object2(source) && keys(source, ["path", "sha256"]) && string(source.path) && digest3(source.sha256)
|
|
30639
|
-
) || !
|
|
30854
|
+
) || !list16(
|
|
30640
30855
|
commands.candidates,
|
|
30641
30856
|
32,
|
|
30642
30857
|
(candidate) => object2(candidate) && keys(candidate, [
|
|
@@ -30648,7 +30863,7 @@ function assertRepositoryContext(value, teamId) {
|
|
|
30648
30863
|
"kind",
|
|
30649
30864
|
"packageManager"
|
|
30650
30865
|
]) && string(candidate.source) && digest3(candidate.sha256) && string(candidate.location) && string(candidate.cwd) && string(candidate.command) && ["script", "excerpt"].includes(String(candidate.kind)) && [null, "npm", "pnpm", "yarn"].includes(candidate.packageManager)
|
|
30651
|
-
) || !["available", "unavailable", "not_repository"].includes(String(git2.state)) || ![null, "branch", "detached", "unborn"].includes(git2.headState) || ![git2.root, git2.branch, git2.head].every((value2) => value2 === null || string(value2)) || ![git2.staged, git2.unstaged, git2.untracked, git2.conflicted].every(count2) || !
|
|
30866
|
+
) || !["available", "unavailable", "not_repository"].includes(String(git2.state)) || ![null, "branch", "detached", "unborn"].includes(git2.headState) || ![git2.root, git2.branch, git2.head].every((value2) => value2 === null || string(value2)) || ![git2.staged, git2.unstaged, git2.untracked, git2.conflicted].every(count2) || !list16(git2.issues, 128, issue))
|
|
30652
30867
|
throw new Error("Invalid repository context report");
|
|
30653
30868
|
const report2 = value;
|
|
30654
30869
|
if (report2.instructions.files.reduce((bytes, file) => bytes + Buffer.byteLength(file.content), 0) > 128 * 1024 || report2.instructions.state === "complete" && (report2.rootIdentity === null || report2.instructions.issues.length > 0))
|
|
@@ -30741,8 +30956,8 @@ ${JSON.stringify(current.commands)}`
|
|
|
30741
30956
|
}
|
|
30742
30957
|
|
|
30743
30958
|
// ../daemon/src/runtime/pi/session.ts
|
|
30744
|
-
import { existsSync as existsSync15, mkdirSync as mkdirSync8, statSync as
|
|
30745
|
-
import { basename as
|
|
30959
|
+
import { existsSync as existsSync15, mkdirSync as mkdirSync8, statSync as statSync8, writeFileSync as writeFileSync11 } from "fs";
|
|
30960
|
+
import { basename as basename5, join as join24 } from "path";
|
|
30746
30961
|
import {
|
|
30747
30962
|
createAssistantMessageEventStream
|
|
30748
30963
|
} from "@earendil-works/pi-ai";
|
|
@@ -31260,14 +31475,14 @@ function isRetryableError(err) {
|
|
|
31260
31475
|
return false;
|
|
31261
31476
|
}
|
|
31262
31477
|
function sleepWithAbort(ms, signal) {
|
|
31263
|
-
return new Promise((
|
|
31478
|
+
return new Promise((resolve9, reject2) => {
|
|
31264
31479
|
if (signal?.aborted) {
|
|
31265
31480
|
reject2(new Error("aborted"));
|
|
31266
31481
|
return;
|
|
31267
31482
|
}
|
|
31268
31483
|
const t = setTimeout(() => {
|
|
31269
31484
|
if (signal) signal.removeEventListener("abort", onAbort);
|
|
31270
|
-
|
|
31485
|
+
resolve9();
|
|
31271
31486
|
}, ms);
|
|
31272
31487
|
const onAbort = () => {
|
|
31273
31488
|
clearTimeout(t);
|
|
@@ -31859,47 +32074,47 @@ import {
|
|
|
31859
32074
|
closeSync as closeSync6,
|
|
31860
32075
|
constants as constants6,
|
|
31861
32076
|
fstatSync as fstatSync4,
|
|
31862
|
-
lstatSync as
|
|
32077
|
+
lstatSync as lstatSync4,
|
|
31863
32078
|
mkdirSync as mkdirSync6,
|
|
31864
32079
|
openSync as openSync6,
|
|
31865
32080
|
readFileSync as readFileSync11,
|
|
31866
|
-
realpathSync as
|
|
32081
|
+
realpathSync as realpathSync8
|
|
31867
32082
|
} from "fs";
|
|
31868
|
-
import { dirname as
|
|
32083
|
+
import { dirname as dirname5, isAbsolute as isAbsolute5, relative as relative4, resolve as resolve5 } from "path";
|
|
31869
32084
|
function resolveRealDirectory(path) {
|
|
31870
|
-
const requested =
|
|
31871
|
-
const entry =
|
|
32085
|
+
const requested = resolve5(path);
|
|
32086
|
+
const entry = lstatSync4(requested);
|
|
31872
32087
|
if (entry.isSymbolicLink() || !entry.isDirectory()) {
|
|
31873
32088
|
throw new Error("expected a real directory");
|
|
31874
32089
|
}
|
|
31875
|
-
return
|
|
32090
|
+
return realpathSync8(requested);
|
|
31876
32091
|
}
|
|
31877
32092
|
function ensureContainedRealDirectory(path, root, options = {}) {
|
|
31878
|
-
const requestedRoot =
|
|
31879
|
-
const requested =
|
|
32093
|
+
const requestedRoot = resolve5(root);
|
|
32094
|
+
const requested = resolve5(path);
|
|
31880
32095
|
if (!isContained2(requestedRoot, requested)) throw new Error("directory escapes its root");
|
|
31881
|
-
const canonicalRoot =
|
|
32096
|
+
const canonicalRoot = realpathSync8(requestedRoot);
|
|
31882
32097
|
try {
|
|
31883
|
-
const entry =
|
|
32098
|
+
const entry = lstatSync4(requested);
|
|
31884
32099
|
if (entry.isSymbolicLink() || !entry.isDirectory()) {
|
|
31885
32100
|
throw new Error("expected a real directory");
|
|
31886
32101
|
}
|
|
31887
32102
|
} catch (error2) {
|
|
31888
32103
|
if (error2.code !== "ENOENT" || !options.create) throw error2;
|
|
31889
|
-
const canonicalParent =
|
|
32104
|
+
const canonicalParent = realpathSync8(dirname5(requested));
|
|
31890
32105
|
if (!isContained2(canonicalRoot, canonicalParent)) throw new Error("directory escapes its root");
|
|
31891
32106
|
mkdirSync6(requested, { recursive: true, mode: 448 });
|
|
31892
|
-
const entry =
|
|
32107
|
+
const entry = lstatSync4(requested);
|
|
31893
32108
|
if (entry.isSymbolicLink() || !entry.isDirectory()) {
|
|
31894
32109
|
throw new Error("expected a real directory");
|
|
31895
32110
|
}
|
|
31896
32111
|
}
|
|
31897
|
-
const canonical =
|
|
32112
|
+
const canonical = realpathSync8(requested);
|
|
31898
32113
|
if (!isContained2(canonicalRoot, canonical)) throw new Error("directory escapes its root");
|
|
31899
32114
|
return canonical;
|
|
31900
32115
|
}
|
|
31901
32116
|
function readRegularFileNoFollow(path) {
|
|
31902
|
-
const entry =
|
|
32117
|
+
const entry = lstatSync4(path);
|
|
31903
32118
|
if (entry.isSymbolicLink()) throw new Error("symbolic links are not allowed");
|
|
31904
32119
|
if (!entry.isFile()) throw new Error("target is not a regular file");
|
|
31905
32120
|
let fd;
|
|
@@ -32090,8 +32305,8 @@ function boundReviewedLessons(lessons, maxCharacters = 8e3) {
|
|
|
32090
32305
|
}
|
|
32091
32306
|
|
|
32092
32307
|
// ../daemon/src/runtime/shell/tooling.ts
|
|
32093
|
-
import { existsSync as existsSync12, lstatSync as
|
|
32094
|
-
import { dirname as
|
|
32308
|
+
import { existsSync as existsSync12, lstatSync as lstatSync5, realpathSync as realpathSync9 } from "fs";
|
|
32309
|
+
import { dirname as dirname6, isAbsolute as isAbsolute6, join as join20, relative as relative5, sep as sep4 } from "path";
|
|
32095
32310
|
import {
|
|
32096
32311
|
createBashToolDefinition,
|
|
32097
32312
|
createLocalBashOperations as createLocalBashOperations2,
|
|
@@ -32149,9 +32364,9 @@ function createSessionShellTools(cwd, env, options = {}) {
|
|
|
32149
32364
|
env: buildSandboxContainerEnv(env, config2.envAllowlist),
|
|
32150
32365
|
readOnlyMounts: [
|
|
32151
32366
|
...existsSync12(join20(cwd, "memory")) ? [safeReadOnlyMount(join20(cwd, "memory"), SANDBOX_MEMORY_DIR, cwd)] : [],
|
|
32152
|
-
...options.inputsDir ? [safeReadOnlyMount(options.inputsDir, SANDBOX_INPUTS_DIR,
|
|
32367
|
+
...options.inputsDir ? [safeReadOnlyMount(options.inputsDir, SANDBOX_INPUTS_DIR, dirname6(options.inputsDir))] : [],
|
|
32153
32368
|
...(options.skillMounts ?? []).map(
|
|
32154
|
-
(mount) => safeReadOnlyMount(mount.source, mount.target,
|
|
32369
|
+
(mount) => safeReadOnlyMount(mount.source, mount.target, dirname6(mount.source))
|
|
32155
32370
|
)
|
|
32156
32371
|
]
|
|
32157
32372
|
});
|
|
@@ -32165,12 +32380,12 @@ function createSessionShellTools(cwd, env, options = {}) {
|
|
|
32165
32380
|
return { config: config2, hostToolNames: [], customBash };
|
|
32166
32381
|
}
|
|
32167
32382
|
function safeReadOnlyMount(source, target, expectedRoot) {
|
|
32168
|
-
const info =
|
|
32383
|
+
const info = lstatSync5(source);
|
|
32169
32384
|
if (info.isSymbolicLink() || !info.isDirectory()) {
|
|
32170
32385
|
throw new Error(`Docker sandbox read-only mount must be a real directory: ${source}`);
|
|
32171
32386
|
}
|
|
32172
|
-
const sourceRoot =
|
|
32173
|
-
const canonicalSource =
|
|
32387
|
+
const sourceRoot = realpathSync9(expectedRoot);
|
|
32388
|
+
const canonicalSource = realpathSync9(source);
|
|
32174
32389
|
const rel = relative5(sourceRoot, canonicalSource);
|
|
32175
32390
|
const contained = rel === "" || rel !== ".." && !rel.startsWith(`..${sep4}`) && !isAbsolute6(rel);
|
|
32176
32391
|
if (!contained) {
|
|
@@ -32183,18 +32398,18 @@ function safeReadOnlyMount(source, target, expectedRoot) {
|
|
|
32183
32398
|
import {
|
|
32184
32399
|
constants as constants7,
|
|
32185
32400
|
existsSync as existsSync13,
|
|
32186
|
-
lstatSync as
|
|
32401
|
+
lstatSync as lstatSync6,
|
|
32187
32402
|
mkdirSync as mkdirSync7,
|
|
32188
32403
|
mkdtempSync as mkdtempSync3,
|
|
32189
|
-
realpathSync as
|
|
32404
|
+
realpathSync as realpathSync10,
|
|
32190
32405
|
rmSync as rmSync12,
|
|
32191
|
-
statSync as
|
|
32406
|
+
statSync as statSync6
|
|
32192
32407
|
} from "fs";
|
|
32193
32408
|
import { access as access2 } from "fs/promises";
|
|
32194
32409
|
import { tmpdir as tmpdir3 } from "os";
|
|
32195
32410
|
import { isAbsolute as isAbsolute7, join as join21, relative as relative6, sep as sep5 } from "path";
|
|
32196
32411
|
var REDACTED_VALUE = "[REDACTED]";
|
|
32197
|
-
var
|
|
32412
|
+
var REASONING_LEVELS2 = /* @__PURE__ */ new Set([
|
|
32198
32413
|
"off",
|
|
32199
32414
|
"minimal",
|
|
32200
32415
|
"low",
|
|
@@ -32507,7 +32722,7 @@ function assertProtectedProviderRuntime(value) {
|
|
|
32507
32722
|
}
|
|
32508
32723
|
if (!nonEmptyString(runtime.modelId))
|
|
32509
32724
|
throw new Error("protected provider runtime requires a model id");
|
|
32510
|
-
if (!
|
|
32725
|
+
if (!REASONING_LEVELS2.has(runtime.reasoningLevel)) {
|
|
32511
32726
|
throw new Error("protected provider runtime requires a valid reasoning level");
|
|
32512
32727
|
}
|
|
32513
32728
|
if (runtime.apiKey !== void 0 && !nonEmptyString(runtime.apiKey)) {
|
|
@@ -32874,11 +33089,11 @@ function containsUnsafeDockerArgument(value) {
|
|
|
32874
33089
|
function requireCanonicalRealDirectory(value, name) {
|
|
32875
33090
|
if (typeof value !== "string") throw new Error(`worker: ${name} must be a path`);
|
|
32876
33091
|
try {
|
|
32877
|
-
const entry =
|
|
33092
|
+
const entry = lstatSync6(value);
|
|
32878
33093
|
if (entry.isSymbolicLink() || !entry.isDirectory()) {
|
|
32879
33094
|
throw new Error("unsafe entry");
|
|
32880
33095
|
}
|
|
32881
|
-
const canonical =
|
|
33096
|
+
const canonical = realpathSync10(value);
|
|
32882
33097
|
if (canonical !== value) throw new Error("non-canonical entry");
|
|
32883
33098
|
return canonical;
|
|
32884
33099
|
} catch {
|
|
@@ -32887,9 +33102,9 @@ function requireCanonicalRealDirectory(value, name) {
|
|
|
32887
33102
|
}
|
|
32888
33103
|
function resolveCanonicalDirectory(value, name) {
|
|
32889
33104
|
try {
|
|
32890
|
-
const entry =
|
|
33105
|
+
const entry = statSync6(value);
|
|
32891
33106
|
if (!entry.isDirectory()) throw new Error("not a directory");
|
|
32892
|
-
return
|
|
33107
|
+
return realpathSync10(value);
|
|
32893
33108
|
} catch {
|
|
32894
33109
|
throw new Error(`worker: ${name} is unavailable or unsafe`);
|
|
32895
33110
|
}
|
|
@@ -32922,16 +33137,16 @@ function assertMinimalWorkerScratch(value) {
|
|
|
32922
33137
|
}
|
|
32923
33138
|
}
|
|
32924
33139
|
function requireCanonicalWindowsDirectory(value, name) {
|
|
32925
|
-
if (!value || !isAbsolute7(value) || !existsSync13(value) || !
|
|
33140
|
+
if (!value || !isAbsolute7(value) || !existsSync13(value) || !statSync6(value).isDirectory()) {
|
|
32926
33141
|
throw new Error(`minimal worker bootstrap requires a valid ${name} directory`);
|
|
32927
33142
|
}
|
|
32928
|
-
return
|
|
33143
|
+
return realpathSync10(value);
|
|
32929
33144
|
}
|
|
32930
33145
|
function requireCanonicalWindowsFile(value, name) {
|
|
32931
|
-
if (!value || !isAbsolute7(value) || !existsSync13(value) || !
|
|
33146
|
+
if (!value || !isAbsolute7(value) || !existsSync13(value) || !statSync6(value).isFile()) {
|
|
32932
33147
|
throw new Error(`minimal worker bootstrap requires a valid ${name} executable`);
|
|
32933
33148
|
}
|
|
32934
|
-
return
|
|
33149
|
+
return realpathSync10(value);
|
|
32935
33150
|
}
|
|
32936
33151
|
function objectRecord(value, label) {
|
|
32937
33152
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
@@ -33183,10 +33398,10 @@ import {
|
|
|
33183
33398
|
fstatSync as fstatSync5,
|
|
33184
33399
|
openSync as openSync7,
|
|
33185
33400
|
readSync as readSync3,
|
|
33186
|
-
realpathSync as
|
|
33187
|
-
statSync as
|
|
33401
|
+
realpathSync as realpathSync11,
|
|
33402
|
+
statSync as statSync7
|
|
33188
33403
|
} from "fs";
|
|
33189
|
-
import { basename as
|
|
33404
|
+
import { basename as basename4, extname, isAbsolute as isAbsolute8, relative as relative7, resolve as resolve6, sep as sep6 } from "path";
|
|
33190
33405
|
var MAX_DELIVER_BYTES = 25 * 1024 * 1024;
|
|
33191
33406
|
var MIME = {
|
|
33192
33407
|
".pdf": "application/pdf",
|
|
@@ -33207,10 +33422,10 @@ function isWithin2(root, candidate) {
|
|
|
33207
33422
|
return rel === "" || rel !== ".." && !rel.startsWith(`..${sep6}`) && !isAbsolute8(rel);
|
|
33208
33423
|
}
|
|
33209
33424
|
function deliverFileTool(cwd, sink, sessionId = "") {
|
|
33210
|
-
const workspacePath =
|
|
33425
|
+
const workspacePath = resolve6(cwd);
|
|
33211
33426
|
let workspaceRealPath = null;
|
|
33212
33427
|
try {
|
|
33213
|
-
workspaceRealPath =
|
|
33428
|
+
workspaceRealPath = realpathSync11(workspacePath);
|
|
33214
33429
|
} catch {
|
|
33215
33430
|
}
|
|
33216
33431
|
return {
|
|
@@ -33235,7 +33450,7 @@ function deliverFileTool(cwd, sink, sessionId = "") {
|
|
|
33235
33450
|
if (isAbsolute8(p)) {
|
|
33236
33451
|
throw new Error(`deliver_file: path must stay within the workspace: ${p}`);
|
|
33237
33452
|
}
|
|
33238
|
-
const abs =
|
|
33453
|
+
const abs = resolve6(workspacePath, p);
|
|
33239
33454
|
if (!isWithin2(workspacePath, abs)) {
|
|
33240
33455
|
throw new Error(`deliver_file: path must stay within the workspace: ${p}`);
|
|
33241
33456
|
}
|
|
@@ -33245,8 +33460,8 @@ function deliverFileTool(cwd, sink, sessionId = "") {
|
|
|
33245
33460
|
let real;
|
|
33246
33461
|
let expected;
|
|
33247
33462
|
try {
|
|
33248
|
-
real =
|
|
33249
|
-
expected =
|
|
33463
|
+
real = realpathSync11(abs);
|
|
33464
|
+
expected = statSync7(real);
|
|
33250
33465
|
} catch {
|
|
33251
33466
|
throw new Error(`deliver_file: no such file: ${p}`);
|
|
33252
33467
|
}
|
|
@@ -33270,7 +33485,7 @@ function deliverFileTool(cwd, sink, sessionId = "") {
|
|
|
33270
33485
|
}
|
|
33271
33486
|
let confirmedReal;
|
|
33272
33487
|
try {
|
|
33273
|
-
confirmedReal =
|
|
33488
|
+
confirmedReal = realpathSync11(abs);
|
|
33274
33489
|
} catch {
|
|
33275
33490
|
throw new Error(`deliver_file: path changed during validation: ${p}`);
|
|
33276
33491
|
}
|
|
@@ -33279,7 +33494,7 @@ function deliverFileTool(cwd, sink, sessionId = "") {
|
|
|
33279
33494
|
}
|
|
33280
33495
|
if (stat2.size > MAX_DELIVER_BYTES) {
|
|
33281
33496
|
throw new Error(
|
|
33282
|
-
`deliver_file: "${
|
|
33497
|
+
`deliver_file: "${basename4(abs)}" is too large (${(stat2.size / 1024 / 1024).toFixed(1)} MB > 25 MB)`
|
|
33283
33498
|
);
|
|
33284
33499
|
}
|
|
33285
33500
|
const buffer = Buffer.alloc(MAX_DELIVER_BYTES + 1);
|
|
@@ -33294,7 +33509,7 @@ function deliverFileTool(cwd, sink, sessionId = "") {
|
|
|
33294
33509
|
} finally {
|
|
33295
33510
|
closeSync7(fd);
|
|
33296
33511
|
}
|
|
33297
|
-
const name =
|
|
33512
|
+
const name = basename4(abs);
|
|
33298
33513
|
const mimeType = MIME[extname(abs).toLowerCase()] ?? "application/octet-stream";
|
|
33299
33514
|
if (!context?.toolCallId || !sessionId)
|
|
33300
33515
|
throw new Error("deliver_file: missing source operation");
|
|
@@ -33320,7 +33535,7 @@ import {
|
|
|
33320
33535
|
closeSync as closeSync8,
|
|
33321
33536
|
constants as constants9,
|
|
33322
33537
|
fstatSync as fstatSync6,
|
|
33323
|
-
lstatSync as
|
|
33538
|
+
lstatSync as lstatSync7,
|
|
33324
33539
|
openSync as openSync8,
|
|
33325
33540
|
readdirSync as readdirSync9,
|
|
33326
33541
|
writeFileSync as writeFileSync10
|
|
@@ -33417,7 +33632,7 @@ function homeTools(agentDir) {
|
|
|
33417
33632
|
for (const file of HOME_FILES_READABLE) {
|
|
33418
33633
|
const path = privateHomeFile(homeRoot, file);
|
|
33419
33634
|
try {
|
|
33420
|
-
const s =
|
|
33635
|
+
const s = lstatSync7(path);
|
|
33421
33636
|
if (s.isSymbolicLink() || !s.isFile()) continue;
|
|
33422
33637
|
entries.push(`${file} (${s.size}b)`);
|
|
33423
33638
|
} catch {
|
|
@@ -33449,7 +33664,7 @@ function privateHomeFile(homeRoot, file) {
|
|
|
33449
33664
|
return join23(homeRoot, file);
|
|
33450
33665
|
}
|
|
33451
33666
|
function rejectSymlinkOrNonFile(path) {
|
|
33452
|
-
const entry =
|
|
33667
|
+
const entry = lstatSync7(path);
|
|
33453
33668
|
if (entry.isSymbolicLink()) throw new Error("symbolic links are not allowed");
|
|
33454
33669
|
if (!entry.isFile()) throw new Error("target is not a regular file");
|
|
33455
33670
|
}
|
|
@@ -34793,8 +35008,8 @@ function loadSessionHead(agent, paths2, target) {
|
|
|
34793
35008
|
const recent = target ? explicitConversationFile(sessionDir, target) : null;
|
|
34794
35009
|
if (!recent) return { file: null, size: 0 };
|
|
34795
35010
|
try {
|
|
34796
|
-
const s =
|
|
34797
|
-
return { file:
|
|
35011
|
+
const s = statSync8(recent);
|
|
35012
|
+
return { file: basename5(recent), size: s.size };
|
|
34798
35013
|
} catch {
|
|
34799
35014
|
return { file: null, size: 0 };
|
|
34800
35015
|
}
|
|
@@ -34962,7 +35177,7 @@ function assertSelectedProvider(requested, expected) {
|
|
|
34962
35177
|
}
|
|
34963
35178
|
function waitForRefresh(pending, signal) {
|
|
34964
35179
|
if (!signal) return pending;
|
|
34965
|
-
return new Promise((
|
|
35180
|
+
return new Promise((resolve9, reject2) => {
|
|
34966
35181
|
let settled = false;
|
|
34967
35182
|
const finish = (callback) => {
|
|
34968
35183
|
if (settled) return;
|
|
@@ -34977,7 +35192,7 @@ function waitForRefresh(pending, signal) {
|
|
|
34977
35192
|
return;
|
|
34978
35193
|
}
|
|
34979
35194
|
pending.then(
|
|
34980
|
-
(value) => finish(() =>
|
|
35195
|
+
(value) => finish(() => resolve9(value)),
|
|
34981
35196
|
(error2) => finish(() => reject2(error2))
|
|
34982
35197
|
);
|
|
34983
35198
|
});
|
|
@@ -35213,12 +35428,12 @@ async function* spawnWorker(spec, opts) {
|
|
|
35213
35428
|
if (opts.signal?.aborted) onAbort();
|
|
35214
35429
|
else opts.signal?.addEventListener("abort", onAbort);
|
|
35215
35430
|
const waitForExit = new Promise(
|
|
35216
|
-
(
|
|
35431
|
+
(resolve9) => {
|
|
35217
35432
|
if (child.exitCode !== null || child.signalCode !== null) {
|
|
35218
|
-
|
|
35433
|
+
resolve9({ code: child.exitCode, signal: child.signalCode });
|
|
35219
35434
|
return;
|
|
35220
35435
|
}
|
|
35221
|
-
child.once("close", (code, signal) =>
|
|
35436
|
+
child.once("close", (code, signal) => resolve9({ code, signal }));
|
|
35222
35437
|
}
|
|
35223
35438
|
);
|
|
35224
35439
|
let emittedFatal = false;
|
|
@@ -35662,7 +35877,7 @@ var AsyncFrameQueue = class {
|
|
|
35662
35877
|
const frame = this.#frames.shift();
|
|
35663
35878
|
if (frame) return Promise.resolve({ done: false, value: frame });
|
|
35664
35879
|
if (this.#ended) return Promise.resolve({ done: true, value: void 0 });
|
|
35665
|
-
return new Promise((
|
|
35880
|
+
return new Promise((resolve9) => this.#waiters.push(resolve9));
|
|
35666
35881
|
}
|
|
35667
35882
|
};
|
|
35668
35883
|
}
|
|
@@ -35832,8 +36047,8 @@ var CommandApprovalRegistry = class {
|
|
|
35832
36047
|
return { approval, decision: Promise.resolve(decision2) };
|
|
35833
36048
|
}
|
|
35834
36049
|
let resolveDecision;
|
|
35835
|
-
const decision = new Promise((
|
|
35836
|
-
resolveDecision =
|
|
36050
|
+
const decision = new Promise((resolve9) => {
|
|
36051
|
+
resolveDecision = resolve9;
|
|
35837
36052
|
});
|
|
35838
36053
|
const timer = setTimeout(() => {
|
|
35839
36054
|
this.#settle(input.id, "deny", "timeout");
|
|
@@ -36047,11 +36262,11 @@ async function getSsrfProxy() {
|
|
|
36047
36262
|
if (serverUrl) return serverUrl;
|
|
36048
36263
|
const s = createServer(onRequest);
|
|
36049
36264
|
s.on("connect", onConnect);
|
|
36050
|
-
await new Promise((
|
|
36265
|
+
await new Promise((resolve9, reject2) => {
|
|
36051
36266
|
s.once("error", reject2);
|
|
36052
36267
|
s.listen(0, "127.0.0.1", () => {
|
|
36053
36268
|
s.off("error", reject2);
|
|
36054
|
-
|
|
36269
|
+
resolve9();
|
|
36055
36270
|
});
|
|
36056
36271
|
});
|
|
36057
36272
|
const addr = s.address();
|
|
@@ -36066,7 +36281,7 @@ async function closeSsrfProxy() {
|
|
|
36066
36281
|
server = null;
|
|
36067
36282
|
serverUrl = null;
|
|
36068
36283
|
if (!s) return;
|
|
36069
|
-
await new Promise((
|
|
36284
|
+
await new Promise((resolve9) => s.close(() => resolve9()));
|
|
36070
36285
|
}
|
|
36071
36286
|
|
|
36072
36287
|
// ../daemon/src/lib/resources.ts
|
|
@@ -36446,7 +36661,7 @@ function createBrowserHost(config2) {
|
|
|
36446
36661
|
}
|
|
36447
36662
|
|
|
36448
36663
|
// ../daemon/src/lib/coding-environment/agent-host.ts
|
|
36449
|
-
import { createHash as
|
|
36664
|
+
import { createHash as createHash11, randomUUID as randomUUID34 } from "crypto";
|
|
36450
36665
|
|
|
36451
36666
|
// ../daemon/src/core/repos/coding-command-logs.ts
|
|
36452
36667
|
var CODING_LOG_BYTES = 2 * 1024 * 1024;
|
|
@@ -36666,7 +36881,7 @@ function pruneCodingCommandLogs(db, now = Date.now(), budgetBytes = CODING_LOG_H
|
|
|
36666
36881
|
}
|
|
36667
36882
|
|
|
36668
36883
|
// ../daemon/src/lib/communication.ts
|
|
36669
|
-
import { randomUUID as
|
|
36884
|
+
import { randomUUID as randomUUID33 } from "crypto";
|
|
36670
36885
|
|
|
36671
36886
|
// ../daemon/src/lib/question-approval.ts
|
|
36672
36887
|
function questionApprovalReference(snapshot, kind) {
|
|
@@ -36761,7 +36976,7 @@ function questionVisible(db, item) {
|
|
|
36761
36976
|
}
|
|
36762
36977
|
|
|
36763
36978
|
// ../daemon/src/core/repos/results.ts
|
|
36764
|
-
import { createHash as
|
|
36979
|
+
import { createHash as createHash10, randomUUID as randomUUID32 } from "crypto";
|
|
36765
36980
|
var MAX_RESULT_BYTES = 25 * 1024 * 1024;
|
|
36766
36981
|
var MAX_RETAINED_RESULT_BYTES = 1024 * 1024 * 1024;
|
|
36767
36982
|
var columns2 = `id, team_id AS teamId, agent_id AS agentId, source_kind AS sourceKind,
|
|
@@ -36796,7 +37011,7 @@ function publish(db, input) {
|
|
|
36796
37011
|
throw new Error("Result exceeds the 25 MiB per-file limit");
|
|
36797
37012
|
}
|
|
36798
37013
|
const bytes = Buffer.from(input.bytes);
|
|
36799
|
-
const sha256 =
|
|
37014
|
+
const sha256 = createHash10("sha256").update(bytes).digest("hex");
|
|
36800
37015
|
return db.raw.transaction(() => {
|
|
36801
37016
|
const existing = source === "session_tool" ? db.raw.query(
|
|
36802
37017
|
`SELECT ${columns2} FROM agent_results
|
|
@@ -36824,7 +37039,7 @@ function publish(db, input) {
|
|
|
36824
37039
|
"Result storage is full (1 GiB). Delete saved results before delivering more files."
|
|
36825
37040
|
);
|
|
36826
37041
|
}
|
|
36827
|
-
const id =
|
|
37042
|
+
const id = randomUUID32();
|
|
36828
37043
|
db.raw.run(
|
|
36829
37044
|
`INSERT INTO agent_results
|
|
36830
37045
|
(id, team_id, agent_id, source_kind, session_id, tool_call_id, review_packet_id, review_revision,
|
|
@@ -36897,7 +37112,7 @@ function readCaptured(db, id) {
|
|
|
36897
37112
|
).get(id);
|
|
36898
37113
|
if (!row2) throw new Error("Captured result is unavailable");
|
|
36899
37114
|
const bytes = Buffer.from(row2.bytes);
|
|
36900
|
-
if (bytes.byteLength !== row2.byte_length ||
|
|
37115
|
+
if (bytes.byteLength !== row2.byte_length || createHash10("sha256").update(bytes).digest("hex") !== row2.sha256) {
|
|
36901
37116
|
throw new Error("Captured result failed integrity verification");
|
|
36902
37117
|
}
|
|
36903
37118
|
return bytes;
|
|
@@ -37144,7 +37359,7 @@ function isUserFacingFrame(frame) {
|
|
|
37144
37359
|
}
|
|
37145
37360
|
function sendAgentMessage(db, input) {
|
|
37146
37361
|
const attemptKind = input.attemptKind ?? "agent_tool";
|
|
37147
|
-
const attemptId = input.attemptId ??
|
|
37362
|
+
const attemptId = input.attemptId ?? randomUUID33();
|
|
37148
37363
|
const outcome = db.raw.transaction(
|
|
37149
37364
|
() => {
|
|
37150
37365
|
const causality = resolveMessageCausality(db, input);
|
|
@@ -37576,7 +37791,7 @@ async function captureRepositoryGit(root, budgetMs = INSPECTION_BUDGET_MS) {
|
|
|
37576
37791
|
rmSync14(scratch, { recursive: true, force: true });
|
|
37577
37792
|
};
|
|
37578
37793
|
try {
|
|
37579
|
-
const rawGit = (args) => new Promise((
|
|
37794
|
+
const rawGit = (args) => new Promise((resolve9, reject2) => {
|
|
37580
37795
|
execFile(
|
|
37581
37796
|
"git",
|
|
37582
37797
|
args,
|
|
@@ -37597,7 +37812,7 @@ async function captureRepositoryGit(root, budgetMs = INSPECTION_BUDGET_MS) {
|
|
|
37597
37812
|
maxBuffer: RUN_MAX_BUFFER,
|
|
37598
37813
|
encoding: "utf8"
|
|
37599
37814
|
},
|
|
37600
|
-
(error2, stdout) => error2 ? reject2(error2) :
|
|
37815
|
+
(error2, stdout) => error2 ? reject2(error2) : resolve9(stdout)
|
|
37601
37816
|
);
|
|
37602
37817
|
});
|
|
37603
37818
|
const inspectionArgs = (args) => [
|
|
@@ -37726,51 +37941,6 @@ objectformat = ${value}`
|
|
|
37726
37941
|
}
|
|
37727
37942
|
}
|
|
37728
37943
|
|
|
37729
|
-
// ../../packages/api-types/src/entities.ts
|
|
37730
|
-
var REASONING_LEVELS2 = [
|
|
37731
|
-
"off",
|
|
37732
|
-
"minimal",
|
|
37733
|
-
"low",
|
|
37734
|
-
"medium",
|
|
37735
|
-
"high",
|
|
37736
|
-
"xhigh"
|
|
37737
|
-
];
|
|
37738
|
-
|
|
37739
|
-
// ../../packages/api-types/src/git-review.ts
|
|
37740
|
-
var REVIEW_LIMITS2 = {
|
|
37741
|
-
files: 1e3,
|
|
37742
|
-
fileBytes: 1024 * 1024,
|
|
37743
|
-
totalBytes: 16 * 1024 * 1024,
|
|
37744
|
-
patchBytes: 256 * 1024
|
|
37745
|
-
};
|
|
37746
|
-
|
|
37747
|
-
// ../../packages/api-types/src/publication.ts
|
|
37748
|
-
var PUBLICATION_LIMITS = {
|
|
37749
|
-
repository: 200,
|
|
37750
|
-
branch: 200,
|
|
37751
|
-
commitMessage: 2e3,
|
|
37752
|
-
refusalDetail: 400,
|
|
37753
|
-
error: 400,
|
|
37754
|
-
/** Branches that are never published to, whatever the host says. */
|
|
37755
|
-
protectedBranches: ["main", "master", "trunk", "develop", "release"]
|
|
37756
|
-
};
|
|
37757
|
-
|
|
37758
|
-
// ../../packages/api-types/src/verification.ts
|
|
37759
|
-
var VERIFICATION_OUTCOME_LIMITS = [
|
|
37760
|
-
"Facts above are executor-owned. A non-zero exit is a result about the commands that ran, never proof about later code, and this is not an approval to publish, merge or deploy.",
|
|
37761
|
-
"Declared output paths are not enforced, so a change they do not cover appears above rather than being prevented."
|
|
37762
|
-
];
|
|
37763
|
-
|
|
37764
|
-
// ../../packages/api-types/src/index.ts
|
|
37765
|
-
var PROFILE_FILES = [
|
|
37766
|
-
"profile.json",
|
|
37767
|
-
"SOUL.md",
|
|
37768
|
-
"IDENTITY.md",
|
|
37769
|
-
"BOOTSTRAP.md",
|
|
37770
|
-
"AGENTS.md",
|
|
37771
|
-
"TOOLS.md"
|
|
37772
|
-
];
|
|
37773
|
-
|
|
37774
37944
|
// ../daemon/src/lib/git-review/refs.ts
|
|
37775
37945
|
var REF_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._/-]{0,254}$/;
|
|
37776
37946
|
function isCommitOid(value) {
|
|
@@ -37888,7 +38058,7 @@ var CREDENTIAL_EXTENSIONS = [
|
|
|
37888
38058
|
];
|
|
37889
38059
|
function reviewScope(path) {
|
|
37890
38060
|
const segments = path.split("/");
|
|
37891
|
-
const
|
|
38061
|
+
const basename7 = segments[segments.length - 1] ?? "";
|
|
37892
38062
|
for (const prefix of BAZILION_STATE_PREFIXES) {
|
|
37893
38063
|
if (path === prefix.slice(0, -1) || path.startsWith(prefix)) {
|
|
37894
38064
|
return { included: false, reason: "bazilion_state" };
|
|
@@ -37897,7 +38067,7 @@ function reviewScope(path) {
|
|
|
37897
38067
|
if (segments.some((segment) => CREDENTIAL_SEGMENTS.has(segment.toLowerCase()))) {
|
|
37898
38068
|
return { included: false, reason: "credential_shaped" };
|
|
37899
38069
|
}
|
|
37900
|
-
const lower =
|
|
38070
|
+
const lower = basename7.toLowerCase();
|
|
37901
38071
|
if (CREDENTIAL_BASENAME_PATTERNS.some((pattern) => pattern.test(lower))) {
|
|
37902
38072
|
return { included: false, reason: "credential_shaped" };
|
|
37903
38073
|
}
|
|
@@ -37908,7 +38078,7 @@ function reviewScope(path) {
|
|
|
37908
38078
|
}
|
|
37909
38079
|
|
|
37910
38080
|
// ../daemon/src/lib/git-review/changes.ts
|
|
37911
|
-
async function listChanges(captured, base, identity2, limits =
|
|
38081
|
+
async function listChanges(captured, base, identity2, limits = REVIEW_LIMITS) {
|
|
37912
38082
|
const issues = [];
|
|
37913
38083
|
const raw2 = await readDiff(captured, base, [
|
|
37914
38084
|
"--raw",
|
|
@@ -37997,7 +38167,7 @@ async function listChanges(captured, base, identity2, limits = REVIEW_LIMITS2) {
|
|
|
37997
38167
|
issues
|
|
37998
38168
|
};
|
|
37999
38169
|
}
|
|
38000
|
-
async function readChangePatch(captured, base, change, patchBytes =
|
|
38170
|
+
async function readChangePatch(captured, base, change, patchBytes = REVIEW_LIMITS.patchBytes) {
|
|
38001
38171
|
if (change.excludedReason) return { patch: null, truncated: false, omitted: "excluded" };
|
|
38002
38172
|
if (change.binary) return { patch: null, truncated: false, omitted: "binary" };
|
|
38003
38173
|
if (change.status === "untracked") {
|
|
@@ -38029,7 +38199,7 @@ async function readChangePatch(captured, base, change, patchBytes = REVIEW_LIMIT
|
|
|
38029
38199
|
omitted: null
|
|
38030
38200
|
};
|
|
38031
38201
|
}
|
|
38032
|
-
async function attachPatches(captured, report2, limits =
|
|
38202
|
+
async function attachPatches(captured, report2, limits = REVIEW_LIMITS, onlyPath) {
|
|
38033
38203
|
let total = 0;
|
|
38034
38204
|
let tooLarge = 0;
|
|
38035
38205
|
const changes = [];
|
|
@@ -38162,7 +38332,7 @@ function compareSnapshots(before, after) {
|
|
|
38162
38332
|
return before.id === after.id ? "identical" : "changed";
|
|
38163
38333
|
}
|
|
38164
38334
|
async function captureSourceSnapshot(captured, base, identity2, input = {}) {
|
|
38165
|
-
const limits = input.limits ??
|
|
38335
|
+
const limits = input.limits ?? REVIEW_LIMITS;
|
|
38166
38336
|
const issues = [];
|
|
38167
38337
|
const withheld = { excluded: 0, tooLarge: 0, notRegular: 0, unstable: 0 };
|
|
38168
38338
|
let incomplete = false;
|
|
@@ -38825,10 +38995,18 @@ async function resolveRepositoryContext(input) {
|
|
|
38825
38995
|
report2.fingerprint = hash3(JSON.stringify({ ...report2, capturedAt: 0, fingerprint: "" }));
|
|
38826
38996
|
return report2;
|
|
38827
38997
|
}
|
|
38998
|
+
var RepositoryContextIncompleteError = class extends Error {
|
|
38999
|
+
codes;
|
|
39000
|
+
constructor(codes) {
|
|
39001
|
+
super(`Repository instructions incomplete (${codes.join(", ")}). Inspect Team repository context before coding.`);
|
|
39002
|
+
this.name = "RepositoryContextIncompleteError";
|
|
39003
|
+
this.codes = codes;
|
|
39004
|
+
}
|
|
39005
|
+
};
|
|
38828
39006
|
function requireCompleteRepositoryContext(report2) {
|
|
38829
39007
|
if (report2.instructions.state !== "complete") {
|
|
38830
|
-
throw new
|
|
38831
|
-
|
|
39008
|
+
throw new RepositoryContextIncompleteError(
|
|
39009
|
+
report2.instructions.issues.map((i) => i.code)
|
|
38832
39010
|
);
|
|
38833
39011
|
}
|
|
38834
39012
|
}
|
|
@@ -38875,12 +39053,12 @@ function createCodingHost(input) {
|
|
|
38875
39053
|
sources2.push([
|
|
38876
39054
|
current.label,
|
|
38877
39055
|
name,
|
|
38878
|
-
value ?
|
|
39056
|
+
value ? createHash11("sha256").update(value).digest("hex") : null
|
|
38879
39057
|
]);
|
|
38880
39058
|
}
|
|
38881
39059
|
}
|
|
38882
39060
|
dir.validate();
|
|
38883
|
-
fingerprint2 =
|
|
39061
|
+
fingerprint2 = createHash11("sha256").update(JSON.stringify(sources2)).digest("hex");
|
|
38884
39062
|
} catch {
|
|
38885
39063
|
} finally {
|
|
38886
39064
|
dir.close();
|
|
@@ -38947,7 +39125,7 @@ function createCodingHost(input) {
|
|
|
38947
39125
|
try {
|
|
38948
39126
|
const environment2 = await snapshot(command.cwd);
|
|
38949
39127
|
const receipt = {
|
|
38950
|
-
id:
|
|
39128
|
+
id: randomUUID34(),
|
|
38951
39129
|
agentId: input.agentId,
|
|
38952
39130
|
teamId: input.teamId,
|
|
38953
39131
|
turnId: input.turnId,
|
|
@@ -39282,7 +39460,7 @@ function createDbMessagingHost(db, opts = {}) {
|
|
|
39282
39460
|
}
|
|
39283
39461
|
|
|
39284
39462
|
// ../daemon/src/lib/question-service.ts
|
|
39285
|
-
import { randomUUID as
|
|
39463
|
+
import { randomUUID as randomUUID36 } from "crypto";
|
|
39286
39464
|
|
|
39287
39465
|
// ../daemon/src/lib/question-consumption.ts
|
|
39288
39466
|
import { isDeepStrictEqual } from "util";
|
|
@@ -39330,13 +39508,13 @@ function verifyQuestionConsumption(paths2, question, target, turnStartEntry = 1)
|
|
|
39330
39508
|
}
|
|
39331
39509
|
|
|
39332
39510
|
// ../daemon/src/lib/question-receipt.ts
|
|
39333
|
-
import { createHash as
|
|
39511
|
+
import { createHash as createHash12, createHmac, randomBytes as randomBytes6, timingSafeEqual as timingSafeEqual2 } from "crypto";
|
|
39334
39512
|
import { isDeepStrictEqual as isDeepStrictEqual2 } from "util";
|
|
39335
|
-
var hash4 = (text3) =>
|
|
39336
|
-
function key(db,
|
|
39337
|
-
if (
|
|
39513
|
+
var hash4 = (text3) => createHash12("sha256").update(text3).digest("hex");
|
|
39514
|
+
function key(db, create8) {
|
|
39515
|
+
if (create8)
|
|
39338
39516
|
db.raw.run("INSERT OR IGNORE INTO question_receipt_key (singleton, key) VALUES (1, ?)", [
|
|
39339
|
-
|
|
39517
|
+
randomBytes6(32)
|
|
39340
39518
|
]);
|
|
39341
39519
|
const row2 = db.raw.query("SELECT key FROM question_receipt_key WHERE singleton = 1").get();
|
|
39342
39520
|
return row2 ? Buffer.from(row2.key) : null;
|
|
@@ -39412,7 +39590,7 @@ var QuestionWaiters = class {
|
|
|
39412
39590
|
if ([...this.#waiting.values()].some((entry) => entry.question.turnId === current.turnId)) {
|
|
39413
39591
|
throw new Error("This turn already has a waiting question");
|
|
39414
39592
|
}
|
|
39415
|
-
return new Promise((
|
|
39593
|
+
return new Promise((resolve9) => {
|
|
39416
39594
|
const abort = () => this.closeTurn(current.turnId, "cancelled");
|
|
39417
39595
|
const timer = setTimeout(
|
|
39418
39596
|
() => {
|
|
@@ -39422,7 +39600,7 @@ var QuestionWaiters = class {
|
|
|
39422
39600
|
Math.max(0, current.expiresAt - this.now())
|
|
39423
39601
|
);
|
|
39424
39602
|
timer.unref();
|
|
39425
|
-
this.#waiting.set(current.id, { question: current, resolve:
|
|
39603
|
+
this.#waiting.set(current.id, { question: current, resolve: resolve9, signal, abort, timer });
|
|
39426
39604
|
signal.addEventListener("abort", abort, { once: true });
|
|
39427
39605
|
if (signal.aborted) abort();
|
|
39428
39606
|
});
|
|
@@ -39455,7 +39633,7 @@ var QuestionWaiters = class {
|
|
|
39455
39633
|
};
|
|
39456
39634
|
|
|
39457
39635
|
// ../daemon/src/lib/telegram/question-transport.ts
|
|
39458
|
-
import { createHash as
|
|
39636
|
+
import { createHash as createHash14 } from "crypto";
|
|
39459
39637
|
|
|
39460
39638
|
// ../daemon/src/lib/telegram/outbound-queue.ts
|
|
39461
39639
|
var DEFAULT_MIN_INTERVAL_MS = Number(process.env.BAZILION_TELEGRAM_SEND_INTERVAL_MS ?? 200);
|
|
@@ -39512,7 +39690,7 @@ function sleep(ms) {
|
|
|
39512
39690
|
}
|
|
39513
39691
|
|
|
39514
39692
|
// ../daemon/src/lib/telegram/queue-binding.ts
|
|
39515
|
-
import { createHash as
|
|
39693
|
+
import { createHash as createHash13 } from "crypto";
|
|
39516
39694
|
|
|
39517
39695
|
// ../daemon/src/lib/telegram/ingress-attempt.ts
|
|
39518
39696
|
function isTelegramIngressPayload(value) {
|
|
@@ -39598,7 +39776,7 @@ function captureTelegramQueueBinding(db, authToken, authorization, transportBotT
|
|
|
39598
39776
|
teamId: agent.team_id,
|
|
39599
39777
|
ownerGrantId: owner.grant_id,
|
|
39600
39778
|
topicBindingId: agent.telegram_binding_id,
|
|
39601
|
-
botDigest:
|
|
39779
|
+
botDigest: createHash13("sha256").update(JSON.stringify([botToken, credential?.envelope ?? null])).digest("hex")
|
|
39602
39780
|
};
|
|
39603
39781
|
}
|
|
39604
39782
|
function requireTelegramQueueBinding(db, authToken, value) {
|
|
@@ -39762,7 +39940,7 @@ Reply to THIS message with Other text, or /answer ${question.id} your answer. Cl
|
|
|
39762
39940
|
};
|
|
39763
39941
|
}
|
|
39764
39942
|
function requestId(identity2) {
|
|
39765
|
-
const hex =
|
|
39943
|
+
const hex = createHash14("sha256").update(identity2).digest("hex");
|
|
39766
39944
|
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-4${hex.slice(13, 16)}-8${hex.slice(17, 20)}-${hex.slice(20, 32)}`;
|
|
39767
39945
|
}
|
|
39768
39946
|
function parseTelegramQuestionReply(db, authToken, update3) {
|
|
@@ -39810,7 +39988,7 @@ function parseTelegramQuestionReply(db, authToken, update3) {
|
|
|
39810
39988
|
}
|
|
39811
39989
|
|
|
39812
39990
|
// ../daemon/src/lib/attachments.ts
|
|
39813
|
-
import { randomUUID as
|
|
39991
|
+
import { randomUUID as randomUUID35 } from "crypto";
|
|
39814
39992
|
import { closeSync as closeSync9, constants as constants10, fstatSync as fstatSync7, openSync as openSync9, writeFileSync as writeFileSync13 } from "fs";
|
|
39815
39993
|
import { join as join26, posix } from "path";
|
|
39816
39994
|
var MAX_FILE_BYTES = 25 * 1024 * 1024;
|
|
@@ -39837,7 +40015,7 @@ function saveInputFiles(agentDir, files, options = {}) {
|
|
|
39837
40015
|
lines.push(`[attachment "${label}" skipped: too large (${fmtBytes(buf.byteLength)} > 25 MB)]`);
|
|
39838
40016
|
continue;
|
|
39839
40017
|
}
|
|
39840
|
-
const filename2 = `${
|
|
40018
|
+
const filename2 = `${randomUUID35().slice(0, 8)}-${safeName(label)}`;
|
|
39841
40019
|
const path = join26(dir, filename2);
|
|
39842
40020
|
let fd;
|
|
39843
40021
|
try {
|
|
@@ -40710,7 +40888,7 @@ var QuestionService = class {
|
|
|
40710
40888
|
turn.conversation.id
|
|
40711
40889
|
).length;
|
|
40712
40890
|
this.#attached.add(turn);
|
|
40713
|
-
const turnId =
|
|
40891
|
+
const turnId = randomUUID36();
|
|
40714
40892
|
const listeners = /* @__PURE__ */ new Set();
|
|
40715
40893
|
if (onQuestion) listeners.add(onQuestion);
|
|
40716
40894
|
this.#turns.set(turnId, {
|
|
@@ -40755,7 +40933,7 @@ var QuestionService = class {
|
|
|
40755
40933
|
ask: async (toolCallId, input) => {
|
|
40756
40934
|
if (closed) throw new Error("Question turn is closed");
|
|
40757
40935
|
this.#validateTurn(turn);
|
|
40758
|
-
const item =
|
|
40936
|
+
const item = create5(this.db, {
|
|
40759
40937
|
agentId: turn.agent.agent.id,
|
|
40760
40938
|
teamId: turn.agent.team.id,
|
|
40761
40939
|
conversationId: turn.conversation.id,
|
|
@@ -42881,18 +43059,18 @@ var _pendingByAgent = /* @__PURE__ */ new Map();
|
|
|
42881
43059
|
function reactSeen(agentId, chatId2, messageId) {
|
|
42882
43060
|
const deps = _liveDepsResolver?.();
|
|
42883
43061
|
if (!deps) return;
|
|
42884
|
-
const
|
|
42885
|
-
|
|
42886
|
-
_pendingByAgent.set(agentId,
|
|
43062
|
+
const list17 = _pendingByAgent.get(agentId) ?? [];
|
|
43063
|
+
list17.push({ chatId: chatId2, messageId });
|
|
43064
|
+
_pendingByAgent.set(agentId, list17);
|
|
42887
43065
|
void deps.api.setMessageReaction(chatId2, messageId, [{ type: "emoji", emoji: SEEN_EMOJI }]).catch(() => void 0);
|
|
42888
43066
|
}
|
|
42889
43067
|
function clearReactionsFor(agentId) {
|
|
42890
|
-
const
|
|
42891
|
-
if (!
|
|
43068
|
+
const list17 = _pendingByAgent.get(agentId);
|
|
43069
|
+
if (!list17 || list17.length === 0) return;
|
|
42892
43070
|
_pendingByAgent.delete(agentId);
|
|
42893
43071
|
const deps = _liveDepsResolver?.();
|
|
42894
43072
|
if (!deps) return;
|
|
42895
|
-
for (const { chatId: chatId2, messageId } of
|
|
43073
|
+
for (const { chatId: chatId2, messageId } of list17) {
|
|
42896
43074
|
void deps.api.setMessageReaction(chatId2, messageId, []).catch(() => void 0);
|
|
42897
43075
|
}
|
|
42898
43076
|
}
|
|
@@ -43209,10 +43387,10 @@ function mirrorTypingStop(agentId) {
|
|
|
43209
43387
|
}
|
|
43210
43388
|
|
|
43211
43389
|
// ../daemon/src/lib/user-md-host.ts
|
|
43212
|
-
import { createHash as
|
|
43390
|
+
import { createHash as createHash15 } from "crypto";
|
|
43213
43391
|
var USER_MD_MAX_BYTES = 12e3;
|
|
43214
43392
|
function computeEtag(content) {
|
|
43215
|
-
return
|
|
43393
|
+
return createHash15("sha256").update(content, "utf8").digest("hex").slice(0, 16);
|
|
43216
43394
|
}
|
|
43217
43395
|
function createDbUserMdHost(db, paths2) {
|
|
43218
43396
|
return {
|
|
@@ -43825,7 +44003,7 @@ function bound(value) {
|
|
|
43825
44003
|
}
|
|
43826
44004
|
|
|
43827
44005
|
// ../daemon/src/lib/review/dispatch.ts
|
|
43828
|
-
import { randomUUID as
|
|
44006
|
+
import { randomUUID as randomUUID37 } from "crypto";
|
|
43829
44007
|
|
|
43830
44008
|
// ../daemon/src/lib/review/preparation.ts
|
|
43831
44009
|
async function prepareChangeReviewTurn(input) {
|
|
@@ -44188,7 +44366,7 @@ function refused(message) {
|
|
|
44188
44366
|
}
|
|
44189
44367
|
|
|
44190
44368
|
// ../daemon/src/lib/review/dispatch.ts
|
|
44191
|
-
var REVIEW_DISPATCH_OWNER =
|
|
44369
|
+
var REVIEW_DISPATCH_OWNER = randomUUID37();
|
|
44192
44370
|
var REVIEW_LEASE_MS = 10 * 60 * 1e3;
|
|
44193
44371
|
var dispatchRegistry = () => {
|
|
44194
44372
|
const global2 = globalThis;
|
|
@@ -44629,9 +44807,9 @@ async function dispatchClaimableReviews(now = Date.now()) {
|
|
|
44629
44807
|
}
|
|
44630
44808
|
|
|
44631
44809
|
// ../daemon/src/lib/verification/admission.ts
|
|
44632
|
-
import { randomUUID as
|
|
44810
|
+
import { randomUUID as randomUUID38 } from "crypto";
|
|
44633
44811
|
var VERIFICATION_LEASE_MS = 10 * 60 * 1e3;
|
|
44634
|
-
var VERIFICATION_DISPATCH_OWNER =
|
|
44812
|
+
var VERIFICATION_DISPATCH_OWNER = randomUUID38();
|
|
44635
44813
|
async function admitVerificationRequest(db, paths2, requestId2, now = Date.now()) {
|
|
44636
44814
|
const request2 = getVerificationRequestById(db, requestId2, now);
|
|
44637
44815
|
if (!request2) return { kind: "deferred", requestId: requestId2, reason: "unknown_or_expired" };
|
|
@@ -44769,7 +44947,7 @@ function safeTeam3(db, paths2, teamId) {
|
|
|
44769
44947
|
}
|
|
44770
44948
|
|
|
44771
44949
|
// ../daemon/src/lib/verification/executor.ts
|
|
44772
|
-
import { randomUUID as
|
|
44950
|
+
import { randomUUID as randomUUID39 } from "crypto";
|
|
44773
44951
|
import { existsSync as existsSync17 } from "fs";
|
|
44774
44952
|
import { join as join28, posix as posix2, relative as relative8, sep as sep7 } from "path";
|
|
44775
44953
|
import { createLocalBashOperations as createLocalBashOperations3 } from "@earendil-works/pi-coding-agent";
|
|
@@ -44800,14 +44978,14 @@ function createProtectedCheckExecutor(input) {
|
|
|
44800
44978
|
}
|
|
44801
44979
|
const container = buildContainerOperations(input, env, config2.envAllowlist, absoluteCwd);
|
|
44802
44980
|
if ("blocked" in container) return blocked3("environment_unavailable", container.blocked);
|
|
44803
|
-
const commandId =
|
|
44981
|
+
const commandId = randomUUID39();
|
|
44804
44982
|
const startedAt = Date.now();
|
|
44805
44983
|
const receipt = {
|
|
44806
44984
|
id: commandId,
|
|
44807
44985
|
agentId: input.request.recipientAgentId,
|
|
44808
44986
|
teamId: input.request.teamId,
|
|
44809
44987
|
turnId: input.attemptId,
|
|
44810
|
-
toolCallId: `verification:${input.attemptId}:${
|
|
44988
|
+
toolCallId: `verification:${input.attemptId}:${randomUUID39()}`,
|
|
44811
44989
|
input: {
|
|
44812
44990
|
command,
|
|
44813
44991
|
cwd: relative9,
|
|
@@ -45269,7 +45447,7 @@ function abandonVerificationAttempt(db, input) {
|
|
|
45269
45447
|
}
|
|
45270
45448
|
|
|
45271
45449
|
// ../daemon/src/lib/verification/writes.ts
|
|
45272
|
-
import { createHash as
|
|
45450
|
+
import { createHash as createHash16 } from "crypto";
|
|
45273
45451
|
import { lstat as lstat2, readdir, readFile, readlink } from "fs/promises";
|
|
45274
45452
|
import { join as join29 } from "path";
|
|
45275
45453
|
var FINGERPRINT_LIMITS = {
|
|
@@ -45284,10 +45462,11 @@ var FINGERPRINT_LIMITS = {
|
|
|
45284
45462
|
async function fingerprintPath(root, path, digest4) {
|
|
45285
45463
|
const absolute = join29(root, path);
|
|
45286
45464
|
const info = await lstat2(absolute);
|
|
45287
|
-
if (info.isSymbolicLink())
|
|
45465
|
+
if (info.isSymbolicLink())
|
|
45466
|
+
return `link:${(await readlink(absolute)).replaceAll("\\", "/")}`;
|
|
45288
45467
|
if (!info.isFile()) return `other:${info.mode}`;
|
|
45289
45468
|
if (!digest4 || info.size > FINGERPRINT_LIMITS.fileBytes) return `size:${info.size}`;
|
|
45290
|
-
return `sha256:${
|
|
45469
|
+
return `sha256:${createHash16("sha256").update(await readFile(absolute)).digest("hex")}`;
|
|
45291
45470
|
}
|
|
45292
45471
|
async function fingerprintWorkspace(root) {
|
|
45293
45472
|
const entries = /* @__PURE__ */ new Map();
|
|
@@ -45996,7 +46175,15 @@ function bootstrap(paths2) {
|
|
|
45996
46175
|
}
|
|
45997
46176
|
const db = openDb(paths2.db);
|
|
45998
46177
|
try {
|
|
45999
|
-
runMigrations(db
|
|
46178
|
+
runMigrations(db, {
|
|
46179
|
+
// Before the first forward migration of an existing home, preserve the
|
|
46180
|
+
// pre-upgrade state beside the database. A failed migration then leaves
|
|
46181
|
+
// a restorable copy instead of a half-migrated home.
|
|
46182
|
+
preMigrationSnapshotPath: join30(
|
|
46183
|
+
dirname7(paths2.db),
|
|
46184
|
+
`bazilion.pre-migration-${(/* @__PURE__ */ new Date()).toISOString().replace(/[-:T]/g, "").replace(/\..*/, "")}.db`
|
|
46185
|
+
)
|
|
46186
|
+
});
|
|
46000
46187
|
let existingAuthToken = null;
|
|
46001
46188
|
if (authFileExists) {
|
|
46002
46189
|
try {
|
|
@@ -46078,6 +46265,7 @@ function authenticateToken(token) {
|
|
|
46078
46265
|
kind: match.kind,
|
|
46079
46266
|
tokenId: match.id,
|
|
46080
46267
|
label: match.label,
|
|
46268
|
+
scopes: match.scopes,
|
|
46081
46269
|
sessionId: null
|
|
46082
46270
|
};
|
|
46083
46271
|
}
|
|
@@ -46122,8 +46310,49 @@ function isLoopbackHost(hostname2) {
|
|
|
46122
46310
|
return hostname2 === "127.0.0.1" || hostname2 === "localhost" || hostname2 === "[::1]" || hostname2 === "::1";
|
|
46123
46311
|
}
|
|
46124
46312
|
|
|
46313
|
+
// ../daemon/src/lib/scopes.ts
|
|
46314
|
+
var ADMIN_PREFIXES = [
|
|
46315
|
+
"/api/config",
|
|
46316
|
+
"/api/mcp-servers",
|
|
46317
|
+
"/api/backup",
|
|
46318
|
+
"/api/tokens",
|
|
46319
|
+
"/api/pair/codes",
|
|
46320
|
+
"/api/auth/openai",
|
|
46321
|
+
"/api/providers/test",
|
|
46322
|
+
"/api/communication"
|
|
46323
|
+
];
|
|
46324
|
+
var APPROVALS_MUTATION_PREFIXES = ["/api/approvals", "/api/shell-approvals", "/api/notifications"];
|
|
46325
|
+
var APPROVALS_MUTATION_PATTERNS = [
|
|
46326
|
+
/\/queue(\/|$)/,
|
|
46327
|
+
// follow-up queue resolve/control/stop/reconcile
|
|
46328
|
+
/\/questions\/[^/]+\/answer$/,
|
|
46329
|
+
// structured question answers (BAZ-037)
|
|
46330
|
+
/\/acknowledge/
|
|
46331
|
+
// attention acknowledge / acknowledge-all (BAZ-026)
|
|
46332
|
+
];
|
|
46333
|
+
var READ_METHODS = /* @__PURE__ */ new Set(["GET", "HEAD", "OPTIONS"]);
|
|
46334
|
+
function requiredScope(method, path) {
|
|
46335
|
+
const isRead = READ_METHODS.has(method.toUpperCase());
|
|
46336
|
+
if (ADMIN_PREFIXES.some((p) => path === p || path.startsWith(`${p}/`))) {
|
|
46337
|
+
return "admin";
|
|
46338
|
+
}
|
|
46339
|
+
if (!isRead) {
|
|
46340
|
+
if (APPROVALS_MUTATION_PREFIXES.some((p) => path === p || path.startsWith(`${p}/`))) {
|
|
46341
|
+
return "approvals";
|
|
46342
|
+
}
|
|
46343
|
+
if (path.startsWith("/api/agents") || path.startsWith("/api/attention")) {
|
|
46344
|
+
if (APPROVALS_MUTATION_PATTERNS.some((re) => re.test(path))) return "approvals";
|
|
46345
|
+
}
|
|
46346
|
+
}
|
|
46347
|
+
return isRead ? "read" : "write";
|
|
46348
|
+
}
|
|
46349
|
+
function scopeAllows(scopes, method, path) {
|
|
46350
|
+
const required3 = requiredScope(method, path);
|
|
46351
|
+
return { allowed: scopes.includes(required3), required: required3 };
|
|
46352
|
+
}
|
|
46353
|
+
|
|
46125
46354
|
// ../daemon/src/lib/middleware-auth.ts
|
|
46126
|
-
var PUBLIC_PATHS = /* @__PURE__ */ new Set(["/api/login", "/api/health"]);
|
|
46355
|
+
var PUBLIC_PATHS = /* @__PURE__ */ new Set(["/api/login", "/api/health", "/api/pair/exchange"]);
|
|
46127
46356
|
var SETUP_OPEN_PREFIXES = [
|
|
46128
46357
|
"/api/config",
|
|
46129
46358
|
"/api/auth",
|
|
@@ -46158,6 +46387,7 @@ async function authMiddleware(c, next) {
|
|
|
46158
46387
|
kind: "session",
|
|
46159
46388
|
tokenId: session.deviceTokenId,
|
|
46160
46389
|
label: session.deviceLabel,
|
|
46390
|
+
scopes: parseScopes(session.deviceScopes),
|
|
46161
46391
|
sessionId: session.id
|
|
46162
46392
|
} : null);
|
|
46163
46393
|
if (!principal) {
|
|
@@ -46176,6 +46406,19 @@ async function authMiddleware(c, next) {
|
|
|
46176
46406
|
}
|
|
46177
46407
|
c.set("authPrincipal", principal);
|
|
46178
46408
|
if (session) c.set("authSession", session);
|
|
46409
|
+
if (principal.kind !== "bootstrap") {
|
|
46410
|
+
const check = scopeAllows(principal.scopes, c.req.method, path);
|
|
46411
|
+
if (!check.allowed) {
|
|
46412
|
+
return c.json(
|
|
46413
|
+
{
|
|
46414
|
+
error: `credential is missing the '${check.required}' scope`,
|
|
46415
|
+
code: "insufficient_scope",
|
|
46416
|
+
requiredScope: check.required
|
|
46417
|
+
},
|
|
46418
|
+
403
|
|
46419
|
+
);
|
|
46420
|
+
}
|
|
46421
|
+
}
|
|
46179
46422
|
if (!isSetupOpen(path) && !isSetupComplete(getCtx().db)) {
|
|
46180
46423
|
return c.json({ error: "setup incomplete" }, 409);
|
|
46181
46424
|
}
|
|
@@ -46183,9 +46426,9 @@ async function authMiddleware(c, next) {
|
|
|
46183
46426
|
}
|
|
46184
46427
|
|
|
46185
46428
|
// ../daemon/src/routes/agents.ts
|
|
46186
|
-
import { randomUUID as
|
|
46429
|
+
import { randomUUID as randomUUID41 } from "crypto";
|
|
46187
46430
|
import { existsSync as existsSync19, readFileSync as readFileSync12 } from "fs";
|
|
46188
|
-
import { join as
|
|
46431
|
+
import { join as join31 } from "path";
|
|
46189
46432
|
import { Hono } from "hono";
|
|
46190
46433
|
|
|
46191
46434
|
// ../daemon/src/lib/agent-id.ts
|
|
@@ -46513,7 +46756,7 @@ var handle5 = async (ctx) => {
|
|
|
46513
46756
|
try {
|
|
46514
46757
|
reconcileApprovalHolds(ctx.db);
|
|
46515
46758
|
if (command === "list" || command === "history") {
|
|
46516
|
-
const state3 =
|
|
46759
|
+
const state3 = list14(ctx.db, agent.id, {
|
|
46517
46760
|
all: command === "history",
|
|
46518
46761
|
offset: command === "history" && arg ? revision2(arg) : 0
|
|
46519
46762
|
});
|
|
@@ -47411,7 +47654,7 @@ function errMsg(e) {
|
|
|
47411
47654
|
}
|
|
47412
47655
|
|
|
47413
47656
|
// ../daemon/src/lib/telegram/notification-transport.ts
|
|
47414
|
-
import { createHash as
|
|
47657
|
+
import { createHash as createHash17 } from "crypto";
|
|
47415
47658
|
var resolver = null;
|
|
47416
47659
|
function notificationDestinationAllowed(chat, owner, bot) {
|
|
47417
47660
|
return chat.type === "supergroup" && chat.is_forum === true && !chat.username && !chat.active_usernames?.length && owner.status !== "left" && owner.status !== "kicked" && (owner.status !== "restricted" || owner.is_member === true) && (bot.status === "creator" || bot.status === "administrator" && bot.can_manage_topics === true);
|
|
@@ -47434,8 +47677,8 @@ function capture(db, authToken) {
|
|
|
47434
47677
|
const topicId = Number(topic?.value);
|
|
47435
47678
|
if (!owner || !Number.isSafeInteger(chatId2) || chatId2 >= 0 || !Number.isSafeInteger(topicId) || topicId <= 0 || !env.TELEGRAM_BOT_TOKEN || env.TELEGRAM_BOT_TOKEN !== live2.botToken)
|
|
47436
47679
|
return null;
|
|
47437
|
-
const botDigest =
|
|
47438
|
-
const id =
|
|
47680
|
+
const botDigest = createHash17("sha256").update(JSON.stringify([live2.botToken, envelope])).digest("hex");
|
|
47681
|
+
const id = createHash17("sha256").update(JSON.stringify([chatId2, topicId, owner.grant_id, botDigest])).digest("hex");
|
|
47439
47682
|
return {
|
|
47440
47683
|
binding: { id, chatId: chatId2, topicId, ownerGrantId: owner.grant_id, botDigest },
|
|
47441
47684
|
ownerId: owner.user_id,
|
|
@@ -47508,7 +47751,7 @@ async function notifyTelegramQueueStatus(db, agentId, itemId) {
|
|
|
47508
47751
|
}
|
|
47509
47752
|
|
|
47510
47753
|
// ../daemon/src/lib/user-queue-admission.ts
|
|
47511
|
-
import { randomUUID as
|
|
47754
|
+
import { randomUUID as randomUUID40 } from "crypto";
|
|
47512
47755
|
async function enqueueTelegramInput(binding, message, attachments2, context = getCtx()) {
|
|
47513
47756
|
validateInput(message, attachments2);
|
|
47514
47757
|
const { db, paths: paths2, authToken } = context;
|
|
@@ -47527,7 +47770,7 @@ async function enqueueTelegramInput(binding, message, attachments2, context = ge
|
|
|
47527
47770
|
const existing = findAttempt(db, "telegram", binding.authorization.attemptId);
|
|
47528
47771
|
return db.raw.transaction(() => {
|
|
47529
47772
|
const item = accept(db, {
|
|
47530
|
-
id: existing?.id ??
|
|
47773
|
+
id: existing?.id ?? randomUUID40(),
|
|
47531
47774
|
agentId,
|
|
47532
47775
|
teamId: existing?.teamId ?? agent.team.id,
|
|
47533
47776
|
conversationId,
|
|
@@ -48589,7 +48832,7 @@ agentsRouter.get("/", (c) => {
|
|
|
48589
48832
|
const { db, paths: paths2, authToken } = getCtx();
|
|
48590
48833
|
const agents = agents_exports.list(db, { includeArchived }).map((agent) => ({
|
|
48591
48834
|
...agent,
|
|
48592
|
-
identity: loadIdentityFromFile(
|
|
48835
|
+
identity: loadIdentityFromFile(join31(agent.dir, "IDENTITY.md"))
|
|
48593
48836
|
}));
|
|
48594
48837
|
return c.json(agents);
|
|
48595
48838
|
});
|
|
@@ -48611,7 +48854,7 @@ agentsRouter.post("/", async (c) => {
|
|
|
48611
48854
|
}
|
|
48612
48855
|
let reasoningLevel;
|
|
48613
48856
|
if (typeof raw2.reasoningLevel === "string") {
|
|
48614
|
-
if (!
|
|
48857
|
+
if (!REASONING_LEVELS.includes(raw2.reasoningLevel)) {
|
|
48615
48858
|
return c.json({ error: `invalid reasoningLevel: ${raw2.reasoningLevel}` }, 400);
|
|
48616
48859
|
}
|
|
48617
48860
|
reasoningLevel = raw2.reasoningLevel;
|
|
@@ -48683,7 +48926,7 @@ agentsRouter.patch("/:id", async (c) => {
|
|
|
48683
48926
|
void syncAgentTopicIcon(db, resolvedId).catch(() => void 0);
|
|
48684
48927
|
}
|
|
48685
48928
|
if (body.reasoningLevel !== void 0) {
|
|
48686
|
-
if (typeof body.reasoningLevel !== "string" || !
|
|
48929
|
+
if (typeof body.reasoningLevel !== "string" || !REASONING_LEVELS.includes(body.reasoningLevel)) {
|
|
48687
48930
|
return c.json({ error: `invalid reasoningLevel: ${body.reasoningLevel}` }, 400);
|
|
48688
48931
|
}
|
|
48689
48932
|
agents_exports.setReasoningLevel(db, resolvedId, body.reasoningLevel);
|
|
@@ -49014,7 +49257,7 @@ agentsRouter.patch("/:id/review-config", async (c) => {
|
|
|
49014
49257
|
if (!Number.isInteger(everyNTurns) || everyNTurns < 1 || everyNTurns > 100) {
|
|
49015
49258
|
return c.json({ error: "everyNTurns must be an integer from 1 to 100" }, 400);
|
|
49016
49259
|
}
|
|
49017
|
-
if (!
|
|
49260
|
+
if (!REASONING_LEVELS.includes(reasoningLevel)) {
|
|
49018
49261
|
return c.json({ error: `invalid reasoningLevel: ${reasoningLevel}` }, 400);
|
|
49019
49262
|
}
|
|
49020
49263
|
if (body.model !== void 0 && body.model !== null && !body.model.includes(":")) {
|
|
@@ -49121,7 +49364,7 @@ for (const decision of ["approve", "reject", "revoke"]) {
|
|
|
49121
49364
|
if (!team) return c.json({ error: `team not found: ${agent.teamId}` }, 404);
|
|
49122
49365
|
try {
|
|
49123
49366
|
const proposal = await runAgentLifecycleMutation(agent.id, async () => {
|
|
49124
|
-
const memory = qmdBackend(
|
|
49367
|
+
const memory = qmdBackend(join31(team.path, "memory"));
|
|
49125
49368
|
if (decision === "approve")
|
|
49126
49369
|
return approveLessonProposal(db, memory, current.id, body.version);
|
|
49127
49370
|
if (decision === "reject") return rejectLessonProposal(db, current.id, body.version);
|
|
@@ -49347,7 +49590,7 @@ agentsRouter.post("/:id/chat", async (c) => {
|
|
|
49347
49590
|
if (!message && attachments2.length === 0) {
|
|
49348
49591
|
return c.json({ error: "message or an attachment is required" }, 400);
|
|
49349
49592
|
}
|
|
49350
|
-
const requestAttemptId = c.req.header("x-request-id") ??
|
|
49593
|
+
const requestAttemptId = c.req.header("x-request-id") ?? randomUUID41();
|
|
49351
49594
|
let preparedTurn;
|
|
49352
49595
|
try {
|
|
49353
49596
|
preparedTurn = await prepareAgentTurn({
|
|
@@ -49369,6 +49612,14 @@ agentsRouter.post("/:id/chat", async (c) => {
|
|
|
49369
49612
|
} catch (error2) {
|
|
49370
49613
|
if (error2 instanceof WorkspaceBusyError)
|
|
49371
49614
|
return c.json({ error: error2.message, code: error2.message }, 409);
|
|
49615
|
+
if (error2 instanceof ContextReadError || error2 instanceof RepositoryContextIncompleteError)
|
|
49616
|
+
return c.json(
|
|
49617
|
+
{
|
|
49618
|
+
error: `this turn needs repository context, which this platform cannot prepare (${error2 instanceof RepositoryContextIncompleteError ? error2.codes.join(", ") : error2.code}); agent turns currently require Linux`,
|
|
49619
|
+
code: error2 instanceof RepositoryContextIncompleteError ? error2.codes[0] : error2.code
|
|
49620
|
+
},
|
|
49621
|
+
422
|
|
49622
|
+
);
|
|
49372
49623
|
if (error2 instanceof ConversationConflictError)
|
|
49373
49624
|
return c.json({ error: error2.message, code: error2.code, selection: error2.selection }, 409);
|
|
49374
49625
|
if (error2 instanceof CommunicationPendingError) {
|
|
@@ -49477,7 +49728,7 @@ agentsRouter.post("/:id/chat/compact", async (c) => {
|
|
|
49477
49728
|
);
|
|
49478
49729
|
const resolved = resolveAgent(db, paths2, id);
|
|
49479
49730
|
const env = mergeSecretsIntoEnv(db, authToken);
|
|
49480
|
-
const memory = qmdBackend(
|
|
49731
|
+
const memory = qmdBackend(join31(resolved.team.path, "memory"));
|
|
49481
49732
|
await memory.init();
|
|
49482
49733
|
const apiKeyResolution = await resolveAgentApiKey(db, authToken, resolved, {
|
|
49483
49734
|
withRefresher: true
|
|
@@ -49552,7 +49803,7 @@ agentsRouter.get("/:id/chat/context", async (c) => {
|
|
|
49552
49803
|
const promptSkills = loadPromptSkills(paths2.skillsDir, resolved.skills);
|
|
49553
49804
|
const files = [];
|
|
49554
49805
|
for (const file of CONTEXT_FILE_ORDER2) {
|
|
49555
|
-
const path =
|
|
49806
|
+
const path = join31(resolved.agent.dir, file);
|
|
49556
49807
|
if (!existsSync19(path)) continue;
|
|
49557
49808
|
const content = readFileSync12(path, "utf8").trimEnd();
|
|
49558
49809
|
if (!content) continue;
|
|
@@ -49582,7 +49833,7 @@ Read-only context about the human you're working with in this team. You cannot e
|
|
|
49582
49833
|
|
|
49583
49834
|
${resolved.team.userMd.trim()}`.length : 0;
|
|
49584
49835
|
const memoryHintChars = "# Memory\n\nYou have a persistent memory backend. Use `memory_write` to remember things across sessions, and `memory_search` / `memory_read` / `memory_list` to recall them. Always check memory at the start of a session if the user might have told you something important before.".length;
|
|
49585
|
-
const memory = qmdBackend(
|
|
49836
|
+
const memory = qmdBackend(join31(resolved.team.path, "memory"));
|
|
49586
49837
|
await memory.init();
|
|
49587
49838
|
const apiKeyResolution = await resolveAgentApiKey(db, authToken, resolved, {
|
|
49588
49839
|
withRefresher: true
|
|
@@ -49724,7 +49975,7 @@ agentsRouter.post("/:id/chat/truncate", async (c) => {
|
|
|
49724
49975
|
409
|
|
49725
49976
|
);
|
|
49726
49977
|
const resolved = resolveAgent(db, paths2, id);
|
|
49727
|
-
const memory = qmdBackend(
|
|
49978
|
+
const memory = qmdBackend(join31(resolved.team.path, "memory"));
|
|
49728
49979
|
await memory.init();
|
|
49729
49980
|
const env = mergeSecretsIntoEnv(db, authToken);
|
|
49730
49981
|
const apiKeyResolution = await resolveAgentApiKey(db, authToken, resolved, {
|
|
@@ -50167,7 +50418,7 @@ function queuedApprovalInput(agentId, itemId) {
|
|
|
50167
50418
|
function assertQueuedApprovalReady(approval) {
|
|
50168
50419
|
const { db } = getCtx();
|
|
50169
50420
|
const ref = validateQueuedUserApproval(approval, queuedApprovalInput);
|
|
50170
|
-
const head =
|
|
50421
|
+
const head = list14(db, ref.agentId, { limit: 1 }).items[0];
|
|
50171
50422
|
if (control(db, ref.agentId).paused || head?.id !== ref.itemId || head.status !== "held")
|
|
50172
50423
|
throw new QueueConflictError("Queued approval is paused or waiting for earlier input");
|
|
50173
50424
|
}
|
|
@@ -50228,7 +50479,7 @@ async function deliverQueuedApproval(approval) {
|
|
|
50228
50479
|
});
|
|
50229
50480
|
} catch (error2) {
|
|
50230
50481
|
if (error2 instanceof WorkspaceBusyError && !error2.recoveryRequired) {
|
|
50231
|
-
await new Promise((
|
|
50482
|
+
await new Promise((resolve9) => setTimeout(resolve9, 1e3));
|
|
50232
50483
|
continue;
|
|
50233
50484
|
}
|
|
50234
50485
|
if (isAgentTurnActiveError(error2, ref.agentId)) continue;
|
|
@@ -50880,14 +51131,14 @@ function callbackUnavailable(error2, host2, port2) {
|
|
|
50880
51131
|
}
|
|
50881
51132
|
function closeServer(server3) {
|
|
50882
51133
|
if (!server3.listening) return Promise.resolve();
|
|
50883
|
-
return new Promise((
|
|
51134
|
+
return new Promise((resolve9) => server3.close(() => resolve9()));
|
|
50884
51135
|
}
|
|
50885
51136
|
async function preflightOpenAICodexCallback(options) {
|
|
50886
51137
|
const host2 = options?.host ?? openAICodexCallbackHost();
|
|
50887
51138
|
const port2 = options?.port ?? OPENAI_CODEX_CALLBACK_PORT;
|
|
50888
51139
|
const server3 = createServer2();
|
|
50889
51140
|
try {
|
|
50890
|
-
await new Promise((
|
|
51141
|
+
await new Promise((resolve9, reject2) => {
|
|
50891
51142
|
const cleanup = () => {
|
|
50892
51143
|
server3.removeListener("error", onError);
|
|
50893
51144
|
server3.removeListener("listening", onListening);
|
|
@@ -50898,7 +51149,7 @@ async function preflightOpenAICodexCallback(options) {
|
|
|
50898
51149
|
};
|
|
50899
51150
|
const onListening = () => {
|
|
50900
51151
|
cleanup();
|
|
50901
|
-
|
|
51152
|
+
resolve9();
|
|
50902
51153
|
};
|
|
50903
51154
|
server3.once("error", onError);
|
|
50904
51155
|
server3.once("listening", onListening);
|
|
@@ -50984,7 +51235,7 @@ var webOpenAILoginTail = Promise.resolve();
|
|
|
50984
51235
|
function waitForLoginTurn(turn, signal) {
|
|
50985
51236
|
if (!signal) return turn;
|
|
50986
51237
|
if (signal.aborted) return Promise.reject(abortReason(signal));
|
|
50987
|
-
return new Promise((
|
|
51238
|
+
return new Promise((resolve9, reject2) => {
|
|
50988
51239
|
const onAbort = () => {
|
|
50989
51240
|
signal.removeEventListener("abort", onAbort);
|
|
50990
51241
|
reject2(abortReason(signal));
|
|
@@ -50992,7 +51243,7 @@ function waitForLoginTurn(turn, signal) {
|
|
|
50992
51243
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
50993
51244
|
void turn.then(() => {
|
|
50994
51245
|
signal.removeEventListener("abort", onAbort);
|
|
50995
|
-
|
|
51246
|
+
resolve9();
|
|
50996
51247
|
});
|
|
50997
51248
|
});
|
|
50998
51249
|
}
|
|
@@ -51000,8 +51251,8 @@ async function acquireWebOpenAILogin(signal) {
|
|
|
51000
51251
|
const previous = webOpenAILoginTail;
|
|
51001
51252
|
let releaseGate = () => {
|
|
51002
51253
|
};
|
|
51003
|
-
const gate = new Promise((
|
|
51004
|
-
releaseGate =
|
|
51254
|
+
const gate = new Promise((resolve9) => {
|
|
51255
|
+
releaseGate = resolve9;
|
|
51005
51256
|
});
|
|
51006
51257
|
webOpenAILoginTail = previous.then(() => gate);
|
|
51007
51258
|
try {
|
|
@@ -51229,6 +51480,47 @@ authRouter.delete("/sessions/:id", (c) => {
|
|
|
51229
51480
|
}
|
|
51230
51481
|
return c.body(null, 204);
|
|
51231
51482
|
});
|
|
51483
|
+
authRouter.post("/pair/codes", async (c) => {
|
|
51484
|
+
const body = await c.req.json().catch(() => null);
|
|
51485
|
+
let scopes = [...ALL_DEVICE_TOKEN_SCOPES];
|
|
51486
|
+
if (body?.scopes !== void 0) {
|
|
51487
|
+
if (!Array.isArray(body.scopes) || body.scopes.length === 0 || body.scopes.some((s) => !DEVICE_TOKEN_SCOPES.includes(s))) {
|
|
51488
|
+
return c.json(
|
|
51489
|
+
{ error: `scopes must be a non-empty subset of: ${DEVICE_TOKEN_SCOPES.join(", ")}` },
|
|
51490
|
+
400
|
|
51491
|
+
);
|
|
51492
|
+
}
|
|
51493
|
+
scopes = [...new Set(body.scopes)];
|
|
51494
|
+
}
|
|
51495
|
+
const created = webPairingTokens_exports.create(getCtx().db, { scopes });
|
|
51496
|
+
const serverOrigin = process.env.BAZILION_PUBLIC_ORIGIN?.replace(/\/$/, "");
|
|
51497
|
+
const setupUrl = `bazilion-pair://pair?server=${encodeURIComponent(serverOrigin ?? new URL(c.req.url).origin)}&code=${encodeURIComponent(created.code)}`;
|
|
51498
|
+
return c.json(
|
|
51499
|
+
{ code: created.code, meta: created.meta, setupUrl },
|
|
51500
|
+
201
|
|
51501
|
+
);
|
|
51502
|
+
});
|
|
51503
|
+
authRouter.post("/pair/exchange", async (c) => {
|
|
51504
|
+
const body = await c.req.json().catch(() => null);
|
|
51505
|
+
if (!body || typeof body.code !== "string" || !body.code.trim()) {
|
|
51506
|
+
return c.json({ error: "code is required" }, 400);
|
|
51507
|
+
}
|
|
51508
|
+
const { db } = getCtx();
|
|
51509
|
+
const outcome = db.raw.transaction(() => {
|
|
51510
|
+
const result = webPairingTokens_exports.exchange(db, body.code.trim());
|
|
51511
|
+
if (!result.ok) return result;
|
|
51512
|
+
const minted = webTokens_exports.create(db, "paired device", { scopes: result.scopes });
|
|
51513
|
+
webPairingTokens_exports.completeExchange(db, body.code.trim(), minted.meta.id);
|
|
51514
|
+
return { ok: true, minted };
|
|
51515
|
+
})();
|
|
51516
|
+
if (!outcome.ok) {
|
|
51517
|
+
return c.json({ error: `pairing code ${outcome.reason}` }, 400);
|
|
51518
|
+
}
|
|
51519
|
+
return c.json(
|
|
51520
|
+
{ token: outcome.minted.token, meta: outcome.minted.meta },
|
|
51521
|
+
201
|
|
51522
|
+
);
|
|
51523
|
+
});
|
|
51232
51524
|
|
|
51233
51525
|
// ../daemon/src/routes/communication.ts
|
|
51234
51526
|
import { Hono as Hono5 } from "hono";
|
|
@@ -51446,7 +51738,7 @@ conversationsRouter.onError((error2, c) => {
|
|
|
51446
51738
|
});
|
|
51447
51739
|
conversationsRouter.get("/:agentId/conversations", (c) => {
|
|
51448
51740
|
return c.json(
|
|
51449
|
-
|
|
51741
|
+
list15(
|
|
51450
51742
|
getCtx().db,
|
|
51451
51743
|
c.req.param("agentId"),
|
|
51452
51744
|
Number(c.req.query("limit") ?? 20),
|
|
@@ -51462,7 +51754,7 @@ conversationsRouter.post("/:agentId/conversations", async (c) => {
|
|
|
51462
51754
|
return c.json({ error: "Invalid conversation request" }, 400);
|
|
51463
51755
|
if (get20(db, agentId, input.requestId)) {
|
|
51464
51756
|
return c.json(
|
|
51465
|
-
|
|
51757
|
+
create6(db, agentId, input, () => {
|
|
51466
51758
|
throw new Error("Existing conversation disappeared");
|
|
51467
51759
|
})
|
|
51468
51760
|
);
|
|
@@ -51472,7 +51764,7 @@ conversationsRouter.post("/:agentId/conversations", async (c) => {
|
|
|
51472
51764
|
if (pendingCount(db, agentId) > 0)
|
|
51473
51765
|
throw new Error("Pending follow-ups must be resolved first");
|
|
51474
51766
|
const agent = resolveAgent(db, paths2, agentId);
|
|
51475
|
-
return
|
|
51767
|
+
return create6(
|
|
51476
51768
|
db,
|
|
51477
51769
|
agentId,
|
|
51478
51770
|
input,
|
|
@@ -51675,23 +51967,23 @@ messagesRouter.patch("/:id", async (c) => {
|
|
|
51675
51967
|
// ../daemon/src/routes/misc.ts
|
|
51676
51968
|
import { existsSync as existsSync20 } from "fs";
|
|
51677
51969
|
import { homedir as homedir2 } from "os";
|
|
51678
|
-
import { join as
|
|
51970
|
+
import { join as join34 } from "path";
|
|
51679
51971
|
import { Hono as Hono10 } from "hono";
|
|
51680
51972
|
|
|
51681
51973
|
// ../daemon/src/lib/backup.ts
|
|
51682
|
-
import { createHash as
|
|
51974
|
+
import { createHash as createHash18 } from "crypto";
|
|
51683
51975
|
import { mkdtempSync as mkdtempSync5, rmSync as rmSync15 } from "fs";
|
|
51684
51976
|
import { tmpdir as tmpdir5 } from "os";
|
|
51685
|
-
import { join as
|
|
51686
|
-
import { DatabaseSync as
|
|
51687
|
-
import { create as
|
|
51977
|
+
import { join as join32, resolve as resolve7 } from "path";
|
|
51978
|
+
import { DatabaseSync as DatabaseSync3 } from "node:sqlite";
|
|
51979
|
+
import { create as create7 } from "tar";
|
|
51688
51980
|
var snapshotTail = Promise.resolve();
|
|
51689
51981
|
async function serializeSnapshot(work) {
|
|
51690
51982
|
let release2 = () => {
|
|
51691
51983
|
};
|
|
51692
51984
|
const previous = snapshotTail;
|
|
51693
|
-
snapshotTail = new Promise((
|
|
51694
|
-
release2 =
|
|
51985
|
+
snapshotTail = new Promise((resolve9) => {
|
|
51986
|
+
release2 = resolve9;
|
|
51695
51987
|
});
|
|
51696
51988
|
await previous;
|
|
51697
51989
|
try {
|
|
@@ -51701,7 +51993,7 @@ async function serializeSnapshot(work) {
|
|
|
51701
51993
|
}
|
|
51702
51994
|
}
|
|
51703
51995
|
function assertSnapshotIntegrity(path) {
|
|
51704
|
-
const snapshot = new
|
|
51996
|
+
const snapshot = new DatabaseSync3(path, { readOnly: true });
|
|
51705
51997
|
try {
|
|
51706
51998
|
const rows = snapshot.prepare("PRAGMA integrity_check").all();
|
|
51707
51999
|
if (rows.length !== 1 || rows[0]?.integrity_check !== "ok") {
|
|
@@ -51710,7 +52002,7 @@ function assertSnapshotIntegrity(path) {
|
|
|
51710
52002
|
}
|
|
51711
52003
|
for (const row2 of snapshot.prepare("SELECT id, bytes, byte_length, sha256 FROM agent_results WHERE deleted_at IS NULL").iterate()) {
|
|
51712
52004
|
const bytes = row2.bytes;
|
|
51713
|
-
if (!(bytes instanceof Uint8Array) || bytes.byteLength !== row2.byte_length ||
|
|
52005
|
+
if (!(bytes instanceof Uint8Array) || bytes.byteLength !== row2.byte_length || createHash18("sha256").update(bytes).digest("hex") !== row2.sha256) {
|
|
51714
52006
|
throw new Error(`Result snapshot integrity verification failed: ${row2.id}`);
|
|
51715
52007
|
}
|
|
51716
52008
|
}
|
|
@@ -51726,8 +52018,8 @@ function assertSnapshotIntegrity(path) {
|
|
|
51726
52018
|
}
|
|
51727
52019
|
async function createBackupSnapshot(db) {
|
|
51728
52020
|
return serializeSnapshot(async () => {
|
|
51729
|
-
const directory = mkdtempSync5(
|
|
51730
|
-
const database =
|
|
52021
|
+
const directory = mkdtempSync5(join32(tmpdir5(), "bazilion-backup-"));
|
|
52022
|
+
const database = join32(directory, "bazilion.snapshot");
|
|
51731
52023
|
let cleaned = false;
|
|
51732
52024
|
const cleanup = () => {
|
|
51733
52025
|
if (cleaned) return;
|
|
@@ -51748,8 +52040,8 @@ async function createBackupSnapshot(db) {
|
|
|
51748
52040
|
});
|
|
51749
52041
|
}
|
|
51750
52042
|
function createBackupArchive(paths2, snapshot) {
|
|
51751
|
-
const snapshotPath =
|
|
51752
|
-
return
|
|
52043
|
+
const snapshotPath = resolve7(snapshot.database);
|
|
52044
|
+
return create7(
|
|
51753
52045
|
{
|
|
51754
52046
|
cwd: paths2.home,
|
|
51755
52047
|
gzip: true,
|
|
@@ -51760,7 +52052,7 @@ function createBackupArchive(paths2, snapshot) {
|
|
|
51760
52052
|
preservePaths: true,
|
|
51761
52053
|
strict: true,
|
|
51762
52054
|
filter(path) {
|
|
51763
|
-
if (
|
|
52055
|
+
if (resolve7(path) === snapshotPath) return true;
|
|
51764
52056
|
const normalized = path.replaceAll("\\", "/").replace(/^\.\//, "");
|
|
51765
52057
|
if (normalized === "bazilion.db" || normalized.startsWith("bazilion.db-")) return false;
|
|
51766
52058
|
if (normalized === "daemon-runtime.json" || normalized.startsWith("daemon-runtime.json.reclaim-")) {
|
|
@@ -51770,7 +52062,7 @@ function createBackupArchive(paths2, snapshot) {
|
|
|
51770
52062
|
return true;
|
|
51771
52063
|
},
|
|
51772
52064
|
onWriteEntry(entry) {
|
|
51773
|
-
if (
|
|
52065
|
+
if (resolve7(entry.absolute) === snapshotPath) entry.path = "./bazilion.db";
|
|
51774
52066
|
}
|
|
51775
52067
|
},
|
|
51776
52068
|
[".", snapshotPath]
|
|
@@ -51778,7 +52070,7 @@ function createBackupArchive(paths2, snapshot) {
|
|
|
51778
52070
|
}
|
|
51779
52071
|
|
|
51780
52072
|
// ../daemon/src/lib/daemon-liveness.ts
|
|
51781
|
-
import { createHash as
|
|
52073
|
+
import { createHash as createHash19, randomUUID as randomUUID42 } from "crypto";
|
|
51782
52074
|
import {
|
|
51783
52075
|
chmodSync as chmodSync2,
|
|
51784
52076
|
closeSync as closeSync10,
|
|
@@ -51786,32 +52078,32 @@ import {
|
|
|
51786
52078
|
fsyncSync as fsyncSync2,
|
|
51787
52079
|
ftruncateSync,
|
|
51788
52080
|
futimesSync,
|
|
51789
|
-
lstatSync as
|
|
52081
|
+
lstatSync as lstatSync8,
|
|
51790
52082
|
mkdirSync as mkdirSync11,
|
|
51791
52083
|
openSync as openSync10,
|
|
51792
52084
|
readFileSync as readFileSync13,
|
|
51793
|
-
realpathSync as
|
|
52085
|
+
realpathSync as realpathSync12,
|
|
51794
52086
|
renameSync as renameSync3,
|
|
51795
52087
|
rmSync as rmSync16,
|
|
51796
52088
|
writeSync
|
|
51797
52089
|
} from "fs";
|
|
51798
|
-
import { basename as
|
|
52090
|
+
import { basename as basename6, dirname as dirname8, join as join33, resolve as resolve8 } from "path";
|
|
51799
52091
|
var HEARTBEAT_MS = 2e3;
|
|
51800
52092
|
function canonicalHomeIdentity(home) {
|
|
51801
|
-
const absolute =
|
|
52093
|
+
const absolute = resolve8(home);
|
|
51802
52094
|
try {
|
|
51803
|
-
return
|
|
52095
|
+
return realpathSync12.native(absolute);
|
|
51804
52096
|
} catch (error2) {
|
|
51805
52097
|
if (errorCode(error2) !== "ENOENT") throw error2;
|
|
51806
|
-
const parent =
|
|
52098
|
+
const parent = dirname8(absolute);
|
|
51807
52099
|
if (parent === absolute) throw error2;
|
|
51808
|
-
return
|
|
52100
|
+
return join33(canonicalHomeIdentity(parent), basename6(absolute));
|
|
51809
52101
|
}
|
|
51810
52102
|
}
|
|
51811
52103
|
function daemonLivenessPath(home) {
|
|
51812
|
-
const
|
|
51813
|
-
const identity2 =
|
|
51814
|
-
return
|
|
52104
|
+
const canonicalHome2 = canonicalHomeIdentity(home);
|
|
52105
|
+
const identity2 = createHash19("sha256").update(canonicalHome2).digest("hex").slice(0, 24);
|
|
52106
|
+
return join33(dirname8(canonicalHome2), `.bazilion-runtime-${identity2}.json`);
|
|
51815
52107
|
}
|
|
51816
52108
|
var activeInstanceId = null;
|
|
51817
52109
|
function getDaemonInstanceId() {
|
|
@@ -51825,7 +52117,7 @@ function errorCode(error2) {
|
|
|
51825
52117
|
}
|
|
51826
52118
|
function readExisting(path) {
|
|
51827
52119
|
try {
|
|
51828
|
-
const stat2 =
|
|
52120
|
+
const stat2 = lstatSync8(path);
|
|
51829
52121
|
const raw2 = stat2.isFile() ? readFileSync13(path, "utf8") : "";
|
|
51830
52122
|
let instanceId;
|
|
51831
52123
|
let version2;
|
|
@@ -51906,7 +52198,7 @@ function pidIsAlive(pid) {
|
|
|
51906
52198
|
}
|
|
51907
52199
|
}
|
|
51908
52200
|
function reclaimStaleRecord(path, existing) {
|
|
51909
|
-
const identity2 =
|
|
52201
|
+
const identity2 = createHash19("sha256").update(existing.instanceId ?? existing.raw).update(`\0${existing.stat.dev}\0${existing.stat.ino}`).digest("hex").slice(0, 24);
|
|
51910
52202
|
const claim5 = `${path}.reclaim-${identity2}`;
|
|
51911
52203
|
try {
|
|
51912
52204
|
mkdirSync11(claim5, { mode: 448 });
|
|
@@ -51919,7 +52211,7 @@ function reclaimStaleRecord(path, existing) {
|
|
|
51919
52211
|
if (!current || !sameFile(current.stat, existing.stat) || current.raw !== existing.raw) {
|
|
51920
52212
|
return null;
|
|
51921
52213
|
}
|
|
51922
|
-
renameSync3(path,
|
|
52214
|
+
renameSync3(path, join33(claim5, "stale-record.json"));
|
|
51923
52215
|
return claim5;
|
|
51924
52216
|
} catch (error2) {
|
|
51925
52217
|
if (!["ENOENT", "EEXIST"].includes(errorCode(error2) ?? "")) throw error2;
|
|
@@ -51936,7 +52228,7 @@ function writeRecord(fd, record3) {
|
|
|
51936
52228
|
function fsyncParentDirectory(path) {
|
|
51937
52229
|
let directoryFd = null;
|
|
51938
52230
|
try {
|
|
51939
|
-
directoryFd = openSync10(
|
|
52231
|
+
directoryFd = openSync10(dirname8(path), "r");
|
|
51940
52232
|
fsyncSync2(directoryFd);
|
|
51941
52233
|
} catch (error2) {
|
|
51942
52234
|
if (process.platform !== "win32") throw error2;
|
|
@@ -51945,10 +52237,10 @@ function fsyncParentDirectory(path) {
|
|
|
51945
52237
|
}
|
|
51946
52238
|
}
|
|
51947
52239
|
function acquireDaemonLiveness(paths2) {
|
|
51948
|
-
mkdirSync11(
|
|
52240
|
+
mkdirSync11(dirname8(resolve8(paths2.home)), { recursive: true });
|
|
51949
52241
|
const path = daemonLivenessPath(paths2.home);
|
|
51950
|
-
mkdirSync11(
|
|
51951
|
-
const instanceId =
|
|
52242
|
+
mkdirSync11(dirname8(path), { recursive: true });
|
|
52243
|
+
const instanceId = randomUUID42();
|
|
51952
52244
|
const startedAt = Date.now();
|
|
51953
52245
|
let fd = null;
|
|
51954
52246
|
let reclaimClaim = null;
|
|
@@ -52020,7 +52312,7 @@ function acquireDaemonLiveness(paths2) {
|
|
|
52020
52312
|
closeSync10(fd);
|
|
52021
52313
|
fd = null;
|
|
52022
52314
|
try {
|
|
52023
|
-
if (sameFile(
|
|
52315
|
+
if (sameFile(lstatSync8(path), ownedStat)) rmSync16(path, { force: true });
|
|
52024
52316
|
} catch {
|
|
52025
52317
|
}
|
|
52026
52318
|
throw error2;
|
|
@@ -52029,7 +52321,7 @@ function acquireDaemonLiveness(paths2) {
|
|
|
52029
52321
|
let stopped = false;
|
|
52030
52322
|
const stillOwnsPath = () => {
|
|
52031
52323
|
try {
|
|
52032
|
-
return sameFile(
|
|
52324
|
+
return sameFile(lstatSync8(path), ownedStat);
|
|
52033
52325
|
} catch {
|
|
52034
52326
|
return false;
|
|
52035
52327
|
}
|
|
@@ -52072,7 +52364,18 @@ function acquireDaemonLiveness(paths2) {
|
|
|
52072
52364
|
const ownsPath = stillOwnsPath();
|
|
52073
52365
|
closeSync10(fd);
|
|
52074
52366
|
fd = null;
|
|
52075
|
-
if (ownsPath)
|
|
52367
|
+
if (!ownsPath) return;
|
|
52368
|
+
for (let attempt = 1; attempt <= 8; attempt++) {
|
|
52369
|
+
try {
|
|
52370
|
+
rmSync16(path, { force: true });
|
|
52371
|
+
return;
|
|
52372
|
+
} catch (error2) {
|
|
52373
|
+
const code = error2.code;
|
|
52374
|
+
if (attempt === 8 || !["EPERM", "EBUSY", "ENOTEMPTY"].includes(code ?? "")) throw error2;
|
|
52375
|
+
const wait = attempt * 250;
|
|
52376
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, wait);
|
|
52377
|
+
}
|
|
52378
|
+
}
|
|
52076
52379
|
}
|
|
52077
52380
|
};
|
|
52078
52381
|
}
|
|
@@ -52173,7 +52476,14 @@ var protectedDockerReadiness = createProtectedDockerReadinessCache();
|
|
|
52173
52476
|
miscRouter.get("/health", (c) => {
|
|
52174
52477
|
const instanceId = getDaemonInstanceId();
|
|
52175
52478
|
if (instanceId) c.header("x-bazilion-daemon-instance", instanceId);
|
|
52176
|
-
return c.json({
|
|
52479
|
+
return c.json({
|
|
52480
|
+
ok: true,
|
|
52481
|
+
auth: {
|
|
52482
|
+
required: true,
|
|
52483
|
+
credentialKinds: ["bootstrap", "device", "pairing-code"],
|
|
52484
|
+
setupComplete: isSetupComplete(getCtx().db)
|
|
52485
|
+
}
|
|
52486
|
+
});
|
|
52177
52487
|
});
|
|
52178
52488
|
miscRouter.get("/health/details", async (c) => {
|
|
52179
52489
|
const paths2 = resolvePaths();
|
|
@@ -52239,7 +52549,7 @@ miscRouter.get("/health/details", async (c) => {
|
|
|
52239
52549
|
}
|
|
52240
52550
|
}
|
|
52241
52551
|
const providerConfig = loadProviderConfigFromEnv(effectiveEnv, oauth);
|
|
52242
|
-
const openclawSkillsDir =
|
|
52552
|
+
const openclawSkillsDir = join34(homedir2(), ".openclaw", "skills");
|
|
52243
52553
|
const CLOUD_KEYS = [
|
|
52244
52554
|
["anthropic", "anthropic"],
|
|
52245
52555
|
["openai", "openai"],
|
|
@@ -52431,10 +52741,23 @@ miscRouter.post("/tokens", async (c) => {
|
|
|
52431
52741
|
if (!Number.isInteger(expiresInDays) || expiresInDays < 1 || expiresInDays > 365) {
|
|
52432
52742
|
return c.json({ error: "expiresInDays must be an integer from 1 to 365" }, 400);
|
|
52433
52743
|
}
|
|
52744
|
+
let scopes = [...ALL_DEVICE_TOKEN_SCOPES];
|
|
52745
|
+
if (body.scopes !== void 0) {
|
|
52746
|
+
if (!Array.isArray(body.scopes) || body.scopes.length === 0 || body.scopes.some((s) => !DEVICE_TOKEN_SCOPES.includes(s))) {
|
|
52747
|
+
return c.json(
|
|
52748
|
+
{
|
|
52749
|
+
error: `scopes must be a non-empty subset of: ${DEVICE_TOKEN_SCOPES.join(", ")}`
|
|
52750
|
+
},
|
|
52751
|
+
400
|
|
52752
|
+
);
|
|
52753
|
+
}
|
|
52754
|
+
scopes = [...new Set(body.scopes)];
|
|
52755
|
+
}
|
|
52434
52756
|
const { db } = getCtx();
|
|
52435
52757
|
const created = webTokens_exports.create(db, body.label.trim(), {
|
|
52436
52758
|
kind: "device",
|
|
52437
|
-
expiresAt: Date.now() + expiresInDays * 864e5
|
|
52759
|
+
expiresAt: Date.now() + expiresInDays * 864e5,
|
|
52760
|
+
scopes
|
|
52438
52761
|
});
|
|
52439
52762
|
return c.json({ token: created.token, meta: created.meta }, 201);
|
|
52440
52763
|
});
|
|
@@ -52463,7 +52786,7 @@ import { bodyLimit } from "hono/body-limit";
|
|
|
52463
52786
|
import { HTTPException } from "hono/http-exception";
|
|
52464
52787
|
|
|
52465
52788
|
// ../daemon/src/lib/notification-control.ts
|
|
52466
|
-
import { randomUUID as
|
|
52789
|
+
import { randomUUID as randomUUID43 } from "crypto";
|
|
52467
52790
|
|
|
52468
52791
|
// ../daemon/src/lib/notification-authorization.ts
|
|
52469
52792
|
function authorizeAttentionNotification(db, item, captured) {
|
|
@@ -52628,7 +52951,7 @@ var NotificationControl = class {
|
|
|
52628
52951
|
);
|
|
52629
52952
|
for (const item of items) byKind[item.kind]++;
|
|
52630
52953
|
const value = {
|
|
52631
|
-
id:
|
|
52954
|
+
id: randomUUID43(),
|
|
52632
52955
|
settingsRevision: revision4,
|
|
52633
52956
|
destinationId: binding.id,
|
|
52634
52957
|
kinds,
|
|
@@ -52838,7 +53161,7 @@ var NotificationDispatcher = class {
|
|
|
52838
53161
|
if (!settings2.enabled || settings2.restorePaused) return;
|
|
52839
53162
|
const binding = destinationBinding(this.db);
|
|
52840
53163
|
if (!binding || this.transport.capture()?.id !== binding.id) {
|
|
52841
|
-
for (const item of
|
|
53164
|
+
for (const item of list12(this.db, { deferredOnly: true, limit: 100 }).receipts)
|
|
52842
53165
|
suppress(this.db, item.id, "destination_changed", this.now());
|
|
52843
53166
|
this.diagnostic = "notification_destination_unavailable";
|
|
52844
53167
|
return;
|
|
@@ -52868,7 +53191,7 @@ var NotificationDispatcher = class {
|
|
|
52868
53191
|
suppress(this.db, receipt.id, authorization.reason, this.now());
|
|
52869
53192
|
if (++admitted >= 100) break;
|
|
52870
53193
|
}
|
|
52871
|
-
for (const receipt of
|
|
53194
|
+
for (const receipt of list12(this.db, { deferredOnly: true, limit: 10 }).receipts) {
|
|
52872
53195
|
if (!this.#current(receipt.id)) continue;
|
|
52873
53196
|
let claimed = null;
|
|
52874
53197
|
const owner = { attempt: null };
|
|
@@ -53027,7 +53350,7 @@ notificationsRouter.get("/receipts", (c) => {
|
|
|
53027
53350
|
const cursor = c.req.query("cursor");
|
|
53028
53351
|
if (!Number.isSafeInteger(limit) || limit < 1 || limit > 100 || cursor && !/^[a-f0-9-]{36}$/.test(cursor))
|
|
53029
53352
|
return c.json({ error: "Invalid notification receipt page" }, 400);
|
|
53030
|
-
return c.json(
|
|
53353
|
+
return c.json(list12(getCtx().db, { limit, cursor }));
|
|
53031
53354
|
});
|
|
53032
53355
|
notificationsRouter.get("/receipts/:id", (c) => {
|
|
53033
53356
|
const receipt = get17(getCtx().db, c.req.param("id"));
|
|
@@ -53053,7 +53376,7 @@ notificationsRouter.post("/receipts/:id/retry", async (c) => {
|
|
|
53053
53376
|
|
|
53054
53377
|
// ../daemon/src/routes/profiles.ts
|
|
53055
53378
|
import { existsSync as existsSync21, readFileSync as readFileSync14, writeFileSync as writeFileSync15 } from "fs";
|
|
53056
|
-
import { join as
|
|
53379
|
+
import { join as join35 } from "path";
|
|
53057
53380
|
import { Hono as Hono12 } from "hono";
|
|
53058
53381
|
var profilesRouter = new Hono12();
|
|
53059
53382
|
profilesRouter.get("/", (c) => {
|
|
@@ -53205,7 +53528,7 @@ profilesRouter.put("/:id/files/:file", async (c) => {
|
|
|
53205
53528
|
});
|
|
53206
53529
|
function resolveFilePath(profilesDir, id, file) {
|
|
53207
53530
|
if (!PROFILE_FILES.includes(file)) return null;
|
|
53208
|
-
return
|
|
53531
|
+
return join35(profilesDir, id, file);
|
|
53209
53532
|
}
|
|
53210
53533
|
function csvToArray(v2) {
|
|
53211
53534
|
if (Array.isArray(v2)) return v2.filter((s) => typeof s === "string");
|
|
@@ -53257,7 +53580,7 @@ questionsRouter.get("/:agentId/questions", (c) => {
|
|
|
53257
53580
|
const { db } = getCtx();
|
|
53258
53581
|
const conversationId = c.req.query("conversationId");
|
|
53259
53582
|
return c.json({
|
|
53260
|
-
questions:
|
|
53583
|
+
questions: list13(db, c.req.param("agentId"), 100, conversationId).filter((item) => questionVisible(db, item))
|
|
53261
53584
|
});
|
|
53262
53585
|
});
|
|
53263
53586
|
questionsRouter.get("/:agentId/questions/:id", (c) => {
|
|
@@ -53418,7 +53741,7 @@ shellApprovalsRouter.post("/:id", async (c) => {
|
|
|
53418
53741
|
// ../daemon/src/routes/skills.ts
|
|
53419
53742
|
import { existsSync as existsSync22, mkdtempSync as mkdtempSync6, rmSync as rmSync17, writeFileSync as writeFileSync16 } from "fs";
|
|
53420
53743
|
import { homedir as homedir3, tmpdir as tmpdir6 } from "os";
|
|
53421
|
-
import { join as
|
|
53744
|
+
import { join as join36 } from "path";
|
|
53422
53745
|
import { Hono as Hono16 } from "hono";
|
|
53423
53746
|
var MAX_ZIP_BYTES = 50 * 1024 * 1024;
|
|
53424
53747
|
var skillsRouter = new Hono16();
|
|
@@ -53512,8 +53835,8 @@ async function parseImportInput(request2) {
|
|
|
53512
53835
|
if (!filename2.toLowerCase().endsWith(".zip")) {
|
|
53513
53836
|
throw new Error("uploaded file must be a .zip archive");
|
|
53514
53837
|
}
|
|
53515
|
-
const tmpDir = mkdtempSync6(
|
|
53516
|
-
const zipPath =
|
|
53838
|
+
const tmpDir = mkdtempSync6(join36(tmpdir6(), "bazilion-skill-upload-"));
|
|
53839
|
+
const zipPath = join36(tmpDir, filename2.replace(/[^\w.-]+/g, "_"));
|
|
53517
53840
|
const buf = Buffer.from(await file.arrayBuffer());
|
|
53518
53841
|
writeFileSync16(zipPath, buf);
|
|
53519
53842
|
const forceField = form.get("force");
|
|
@@ -53528,7 +53851,7 @@ async function parseImportInput(request2) {
|
|
|
53528
53851
|
if (!body) throw new Error("invalid JSON body");
|
|
53529
53852
|
const from = body.source ?? body.from;
|
|
53530
53853
|
if (typeof from !== "string" || !from) throw new Error("source is required");
|
|
53531
|
-
const source = from === "openclaw" ?
|
|
53854
|
+
const source = from === "openclaw" ? join36(homedir3(), ".openclaw", "skills") : from;
|
|
53532
53855
|
return {
|
|
53533
53856
|
source,
|
|
53534
53857
|
force: Boolean(body.force),
|
|
@@ -53538,7 +53861,7 @@ async function parseImportInput(request2) {
|
|
|
53538
53861
|
}
|
|
53539
53862
|
|
|
53540
53863
|
// ../daemon/src/routes/team-templates.ts
|
|
53541
|
-
import { randomUUID as
|
|
53864
|
+
import { randomUUID as randomUUID44 } from "crypto";
|
|
53542
53865
|
import { Hono as Hono17 } from "hono";
|
|
53543
53866
|
var teamTemplatesRouter = new Hono17();
|
|
53544
53867
|
teamTemplatesRouter.get("/", (c) => {
|
|
@@ -53578,7 +53901,7 @@ teamTemplatesRouter.post("/import", async (c) => {
|
|
|
53578
53901
|
if (!profiles_exports.get(db, parsed.profileId)) {
|
|
53579
53902
|
throw new Error(`profile not found: ${parsed.profileId}`);
|
|
53580
53903
|
}
|
|
53581
|
-
const slotId =
|
|
53904
|
+
const slotId = randomUUID44();
|
|
53582
53905
|
keyToSlot.set(clientKey, slotId);
|
|
53583
53906
|
return { ...parsed, slotId };
|
|
53584
53907
|
});
|
|
@@ -53799,7 +54122,7 @@ function parseSlot(value, index) {
|
|
|
53799
54122
|
throw new Error(`invalid_template_definition: slot ${index} requires profileId and agentName`);
|
|
53800
54123
|
}
|
|
53801
54124
|
const reasoning = slot.reasoningLevel;
|
|
53802
|
-
if (reasoning !== void 0 && reasoning !== null && (typeof reasoning !== "string" || !
|
|
54125
|
+
if (reasoning !== void 0 && reasoning !== null && (typeof reasoning !== "string" || !REASONING_LEVELS.includes(reasoning))) {
|
|
53803
54126
|
throw new Error(`invalid_template_definition: slot ${index} reasoningLevel is invalid`);
|
|
53804
54127
|
}
|
|
53805
54128
|
const result = {
|
|
@@ -53870,7 +54193,7 @@ function canonicalError(c, error2) {
|
|
|
53870
54193
|
}
|
|
53871
54194
|
|
|
53872
54195
|
// ../daemon/src/routes/teams.ts
|
|
53873
|
-
import { join as
|
|
54196
|
+
import { join as join40 } from "path";
|
|
53874
54197
|
import { Hono as Hono18 } from "hono";
|
|
53875
54198
|
|
|
53876
54199
|
// ../daemon/src/lib/coding-environment/management.ts
|
|
@@ -54075,9 +54398,9 @@ function resolvePublicationTarget(db, authToken) {
|
|
|
54075
54398
|
}
|
|
54076
54399
|
|
|
54077
54400
|
// ../daemon/src/lib/publication/revision-content.ts
|
|
54078
|
-
import { createHash as
|
|
54401
|
+
import { createHash as createHash20 } from "crypto";
|
|
54079
54402
|
import { readFileSync as readFileSync15 } from "fs";
|
|
54080
|
-
import { join as
|
|
54403
|
+
import { join as join37 } from "path";
|
|
54081
54404
|
function readReviewedRevisionFiles(db, paths2, packet) {
|
|
54082
54405
|
const record3 = getSourceSnapshot(db, packet.teamId, packet.snapshotId);
|
|
54083
54406
|
if (!record3) {
|
|
@@ -54127,7 +54450,7 @@ function readReviewedRevisionFiles(db, paths2, packet) {
|
|
|
54127
54450
|
}
|
|
54128
54451
|
let content;
|
|
54129
54452
|
try {
|
|
54130
|
-
content = readFileSync15(
|
|
54453
|
+
content = readFileSync15(join37(paths2.teamDir(packet.teamId), entry.path));
|
|
54131
54454
|
} catch {
|
|
54132
54455
|
return {
|
|
54133
54456
|
ok: false,
|
|
@@ -54135,7 +54458,7 @@ function readReviewedRevisionFiles(db, paths2, packet) {
|
|
|
54135
54458
|
detail: `the reviewed content for ${entry.path} can no longer be read`
|
|
54136
54459
|
};
|
|
54137
54460
|
}
|
|
54138
|
-
const digest4 =
|
|
54461
|
+
const digest4 = createHash20("sha256").update(content).digest("hex");
|
|
54139
54462
|
if (digest4 !== entry.digest) {
|
|
54140
54463
|
return {
|
|
54141
54464
|
ok: false,
|
|
@@ -54251,7 +54574,7 @@ function refused2(reason, detail3) {
|
|
|
54251
54574
|
// ../daemon/src/lib/publication/git-publish.ts
|
|
54252
54575
|
import { execFile as execFile2 } from "child_process";
|
|
54253
54576
|
import { mkdirSync as mkdirSync12, mkdtempSync as mkdtempSync7, rmSync as rmSync18, writeFileSync as writeFileSync17 } from "fs";
|
|
54254
|
-
import { dirname as
|
|
54577
|
+
import { dirname as dirname9, join as join38 } from "path";
|
|
54255
54578
|
import { promisify } from "util";
|
|
54256
54579
|
var execFileAsync = promisify(execFile2);
|
|
54257
54580
|
var COMMAND_BUDGET_MS = 6e4;
|
|
@@ -54259,8 +54582,8 @@ var MAX_OUTPUT = 64 * 1024;
|
|
|
54259
54582
|
var AUTHOR_NAME = "Bazilion";
|
|
54260
54583
|
var AUTHOR_EMAIL = "bazilion@localhost";
|
|
54261
54584
|
async function publishRevisionCommit(input) {
|
|
54262
|
-
const scratch = mkdtempSync7(
|
|
54263
|
-
const gitDir =
|
|
54585
|
+
const scratch = mkdtempSync7(join38(input.scratchParentDir ?? "/tmp", "bazilion-publish-"));
|
|
54586
|
+
const gitDir = join38(scratch, "repo");
|
|
54264
54587
|
const gitEnv = environment(scratch, input.remoteUrl, input.credential);
|
|
54265
54588
|
const run = (args, cwd = scratch) => git(["-C", gitDir, ...args], cwd, gitEnv);
|
|
54266
54589
|
try {
|
|
@@ -54297,8 +54620,8 @@ async function publishRevisionCommit(input) {
|
|
|
54297
54620
|
}
|
|
54298
54621
|
await run(["checkout", "--quiet", "--detach", input.baseOid]);
|
|
54299
54622
|
for (const file of input.files) {
|
|
54300
|
-
const target =
|
|
54301
|
-
mkdirSync12(
|
|
54623
|
+
const target = join38(gitDir, file.path);
|
|
54624
|
+
mkdirSync12(dirname9(target), { recursive: true });
|
|
54302
54625
|
writeFileSync17(target, file.content);
|
|
54303
54626
|
}
|
|
54304
54627
|
for (const path of input.removed) {
|
|
@@ -54883,7 +55206,7 @@ function renderExportDocument(exported) {
|
|
|
54883
55206
|
// ../daemon/src/lib/review/file-link.ts
|
|
54884
55207
|
import { execFile as execFile3 } from "child_process";
|
|
54885
55208
|
import { hostname } from "os";
|
|
54886
|
-
import { isAbsolute as isAbsolute10, join as
|
|
55209
|
+
import { isAbsolute as isAbsolute10, join as join39 } from "path";
|
|
54887
55210
|
import { promisify as promisify2 } from "util";
|
|
54888
55211
|
var execFileAsync2 = promisify2(execFile3);
|
|
54889
55212
|
var EDITOR_TEMPLATE_ENV = "BAZILION_REVIEW_EDITOR";
|
|
@@ -54896,7 +55219,7 @@ function buildFileLink(input) {
|
|
|
54896
55219
|
const known = revision4.ok && revision4.changes.some((change) => change.path === input.path);
|
|
54897
55220
|
const line = input.line !== null && input.line >= 1 ? input.line : null;
|
|
54898
55221
|
const copyTarget = line === null ? input.path : `${input.path}:${line}`;
|
|
54899
|
-
const hostPath = known ?
|
|
55222
|
+
const hostPath = known ? join39(team.path, input.path) : null;
|
|
54900
55223
|
const template = env[EDITOR_TEMPLATE_ENV]?.trim();
|
|
54901
55224
|
const mapped = hostPath ? mapHostPath(hostPath, env[EDITOR_MAP_ENV]) : null;
|
|
54902
55225
|
if (!known) {
|
|
@@ -55445,7 +55768,7 @@ teamsRouter.post("/:id/review/snapshots", async (c) => {
|
|
|
55445
55768
|
}
|
|
55446
55769
|
let includeUntracked;
|
|
55447
55770
|
if (input.includeUntracked !== void 0) {
|
|
55448
|
-
if (!Array.isArray(input.includeUntracked) || input.includeUntracked.length >
|
|
55771
|
+
if (!Array.isArray(input.includeUntracked) || input.includeUntracked.length > REVIEW_LIMITS.files) {
|
|
55449
55772
|
return c.json({ error: "Invalid untracked selection" }, 400);
|
|
55450
55773
|
}
|
|
55451
55774
|
includeUntracked = [];
|
|
@@ -55779,7 +56102,7 @@ async function openMemory(rawId) {
|
|
|
55779
56102
|
const { db, paths: paths2 } = getCtx();
|
|
55780
56103
|
const team = teams_exports.get(db, rawId, paths2);
|
|
55781
56104
|
if (!team) throw new TeamMemoryNotFoundError(`team not found: ${rawId}`);
|
|
55782
|
-
const mem = qmdBackend(
|
|
56105
|
+
const mem = qmdBackend(join40(team.path, "memory"));
|
|
55783
56106
|
await mem.init();
|
|
55784
56107
|
return { mem, team };
|
|
55785
56108
|
}
|
|
@@ -56392,7 +56715,7 @@ userQueueRouter.onError((error2, c) => {
|
|
|
56392
56715
|
userQueueRouter.get(
|
|
56393
56716
|
"/:agentId/queue",
|
|
56394
56717
|
(c) => c.json(
|
|
56395
|
-
|
|
56718
|
+
list14(getCtx().db, c.req.param("agentId"), {
|
|
56396
56719
|
all: c.req.query("all") === "1",
|
|
56397
56720
|
limit: Number(c.req.query("limit") ?? 20),
|
|
56398
56721
|
offset: Number(c.req.query("offset") ?? 0)
|
|
@@ -56633,7 +56956,7 @@ function startUserQueuePump() {
|
|
|
56633
56956
|
stopping = true;
|
|
56634
56957
|
clearInterval(timer);
|
|
56635
56958
|
for (const agentId of active.keys()) {
|
|
56636
|
-
const head =
|
|
56959
|
+
const head = list14(db, agentId, { limit: 1 }).items[0];
|
|
56637
56960
|
if (head?.status === "running") cancelAgent(agentId);
|
|
56638
56961
|
}
|
|
56639
56962
|
await Promise.allSettled(active.values());
|
|
@@ -56662,7 +56985,7 @@ try {
|
|
|
56662
56985
|
try {
|
|
56663
56986
|
getCtx();
|
|
56664
56987
|
} catch (error2) {
|
|
56665
|
-
const detail3 = error2 instanceof IncompatibleDatabaseError || error2 instanceof IncompatibleBootstrapIdentityError ? error2.message : error2 instanceof Error ? error2.stack ?? error2.message : String(error2);
|
|
56988
|
+
const detail3 = error2 instanceof IncompatibleDatabaseError || error2 instanceof DatabaseNewerThanBinaryError || error2 instanceof IncompatibleBootstrapIdentityError ? error2.message : error2 instanceof Error ? error2.stack ?? error2.message : String(error2);
|
|
56666
56989
|
writeSync2(process.stderr.fd, `bazilion daemon failed to start: ${detail3}
|
|
56667
56990
|
`);
|
|
56668
56991
|
try {
|