@dotobokuri/fleet-console 1.17.0 → 1.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +5 -5
- package/dist/cli.d.ts +0 -2
- package/dist/cli.mjs +1055 -2270
- package/dist/client/assets/{_baseUniq-24vRkv8i.js → _baseUniq-DFEDX4NY.js} +1 -1
- package/dist/client/assets/{arc-BTiCiQ57.js → arc-CGwMrR6o.js} +1 -1
- package/dist/client/assets/{architectureDiagram-Q4EWVU46-B24oDJvB.js → architectureDiagram-Q4EWVU46-BqLyvIOK.js} +1 -1
- package/dist/client/assets/{blockDiagram-DXYQGD6D-BOAE3FdW.js → blockDiagram-DXYQGD6D-DoiPMLdv.js} +1 -1
- package/dist/client/assets/{c4Diagram-AHTNJAMY-C0W9raQx.js → c4Diagram-AHTNJAMY-DfGxDkah.js} +1 -1
- package/dist/client/assets/channel-DlT8zCVq.js +1 -0
- package/dist/client/assets/{chunk-4BX2VUAB-DvyhIkzo.js → chunk-4BX2VUAB-3zXv74oY.js} +1 -1
- package/dist/client/assets/{chunk-4TB4RGXK-CMV1UZLH.js → chunk-4TB4RGXK-MkXUmjUE.js} +1 -1
- package/dist/client/assets/{chunk-55IACEB6-CG75wbs4.js → chunk-55IACEB6-mhkgqlI_.js} +1 -1
- package/dist/client/assets/{chunk-EDXVE4YY-9CjdVkNM.js → chunk-EDXVE4YY-B0_ZDihs.js} +1 -1
- package/dist/client/assets/{chunk-FMBD7UC4-i496V3zS.js → chunk-FMBD7UC4-BQAuE4pL.js} +1 -1
- package/dist/client/assets/{chunk-OYMX7WX6-CeRfBoEk.js → chunk-OYMX7WX6-CY8Eyj9X.js} +1 -1
- package/dist/client/assets/{chunk-QZHKN3VN-D1mXQVL_.js → chunk-QZHKN3VN-CaZoMwKH.js} +1 -1
- package/dist/client/assets/{chunk-YZCP3GAM-DUXK6jpB.js → chunk-YZCP3GAM-DV1YOEUH.js} +1 -1
- package/dist/client/assets/classDiagram-6PBFFD2Q-B-UN9f9r.js +1 -0
- package/dist/client/assets/classDiagram-v2-HSJHXN6E-B-UN9f9r.js +1 -0
- package/dist/client/assets/clone-CDPRFCO0.js +1 -0
- package/dist/client/assets/{cose-bilkent-S5V4N54A-Cw97IMZH.js → cose-bilkent-S5V4N54A-Cy3v0C_N.js} +1 -1
- package/dist/client/assets/{dagre-KV5264BT-CyY9URRi.js → dagre-KV5264BT-CGJ6x_VR.js} +1 -1
- package/dist/client/assets/{diagram-5BDNPKRD-BEVj5KaK.js → diagram-5BDNPKRD-MyyXeHKQ.js} +1 -1
- package/dist/client/assets/{diagram-G4DWMVQ6-IXOT_4VL.js → diagram-G4DWMVQ6-D52Q2132.js} +1 -1
- package/dist/client/assets/{diagram-MMDJMWI5-CO2p0poL.js → diagram-MMDJMWI5-DCypusCr.js} +1 -1
- package/dist/client/assets/{diagram-TYMM5635-DvRDFMNM.js → diagram-TYMM5635-c5UBqE9-.js} +1 -1
- package/dist/client/assets/{erDiagram-SMLLAGMA-C5uteguB.js → erDiagram-SMLLAGMA-BlF0Lxy7.js} +1 -1
- package/dist/client/assets/{flowDiagram-DWJPFMVM-JekEx60D.js → flowDiagram-DWJPFMVM-lo8xyzfx.js} +1 -1
- package/dist/client/assets/{ganttDiagram-T4ZO3ILL-DRKjnKDn.js → ganttDiagram-T4ZO3ILL-BXVZMpon.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-UUTBAWPF-Dhnk3n7N.js → gitGraphDiagram-UUTBAWPF-DB1A6uYk.js} +1 -1
- package/dist/client/assets/{graph-DE-kEMug.js → graph-Ck2AX1p2.js} +1 -1
- package/dist/client/assets/index-Cf9MmpwN.css +1 -0
- package/dist/client/assets/index-DWgndVkX.js +404 -0
- package/dist/client/assets/{infoDiagram-42DDH7IO-DG9M_7T9.js → infoDiagram-42DDH7IO-NEVE42fw.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-UXIWVN3A-CiP4wnqc.js → ishikawaDiagram-UXIWVN3A-MbFr_8pL.js} +1 -1
- package/dist/client/assets/{journeyDiagram-VCZTEJTY-DklSog3d.js → journeyDiagram-VCZTEJTY-Sq2ja3q8.js} +1 -1
- package/dist/client/assets/{kanban-definition-6JOO6SKY-BVB77h52.js → kanban-definition-6JOO6SKY-C63qPhtK.js} +1 -1
- package/dist/client/assets/{layout-CAevigwv.js → layout-CFEuVj4N.js} +1 -1
- package/dist/client/assets/{linear-CB_shmWV.js → linear-B626G8Op.js} +1 -1
- package/dist/client/assets/{mermaid.core-DPLCTlKT.js → mermaid.core-BT7SVKBR.js} +4 -4
- package/dist/client/assets/{min-Cimc7NFp.js → min-MbEOApMw.js} +1 -1
- package/dist/client/assets/{mindmap-definition-QFDTVHPH-DnyowBeF.js → mindmap-definition-QFDTVHPH-DMpht5Mg.js} +1 -1
- package/dist/client/assets/{pieDiagram-DEJITSTG-B1mr5ZWu.js → pieDiagram-DEJITSTG-B4XS0haZ.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-34T5L4WZ-CJla4J4E.js → quadrantDiagram-34T5L4WZ-CReo5Ajb.js} +1 -1
- package/dist/client/assets/{requirementDiagram-MS252O5E-Bduy03Er.js → requirementDiagram-MS252O5E-A50aqG-K.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-XADWPNL6-G7I_cbR7.js → sankeyDiagram-XADWPNL6-471VOdlW.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-FGHM5R23-D4Uf0SLt.js → sequenceDiagram-FGHM5R23-BAvOyUC-.js} +1 -1
- package/dist/client/assets/{stateDiagram-FHFEXIEX-Fr0IevW-.js → stateDiagram-FHFEXIEX-gCtZrvR-.js} +1 -1
- package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-Bdb0YU66.js +1 -0
- package/dist/client/assets/{timeline-definition-GMOUNBTQ-CzR6FMOJ.js → timeline-definition-GMOUNBTQ-CTHf-uxq.js} +1 -1
- package/dist/client/assets/{vennDiagram-DHZGUBPP-CCzsRm3-.js → vennDiagram-DHZGUBPP-5gvXi0dO.js} +1 -1
- package/dist/client/assets/{wardley-RL74JXVD-C9U_HC7W.js → wardley-RL74JXVD-XR-qQTWZ.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-NUSXRM2D-BkwkDUKo.js → wardleyDiagram-NUSXRM2D-EwPsMHdt.js} +1 -1
- package/dist/client/assets/{xychartDiagram-5P7HB3ND-CZ45hysw.js → xychartDiagram-5P7HB3ND-CePwuUb7.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/fleet-plugins/diff/routes.mjs +76 -21
- package/dist/fleet-plugins/skills/routes.mjs +7 -118
- package/dist/fleet-plugins/terminal/routes.mjs +281 -974
- package/package.json +1 -1
- package/dist/client/assets/channel-yb1CkB_S.js +0 -1
- package/dist/client/assets/classDiagram-6PBFFD2Q-DgNTT8Lb.js +0 -1
- package/dist/client/assets/classDiagram-v2-HSJHXN6E-DgNTT8Lb.js +0 -1
- package/dist/client/assets/clone-BLvG1gy6.js +0 -1
- package/dist/client/assets/index-BY_CeGCl.js +0 -402
- package/dist/client/assets/index-CfNSyAUJ.css +0 -1
- package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-DXt_OYu8.js +0 -1
package/dist/cli.mjs
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { spawn, execFileSync, execFile, execSync } from 'child_process';
|
|
3
3
|
import * as fs11 from 'fs';
|
|
4
|
-
import fs11__default, {
|
|
5
|
-
import * as
|
|
6
|
-
import
|
|
4
|
+
import fs11__default, { realpathSync, accessSync, constants, existsSync, lstatSync } from 'fs';
|
|
5
|
+
import * as path25 from 'path';
|
|
6
|
+
import path25__default, { join, resolve, relative, sep, dirname } from 'path';
|
|
7
7
|
import process4 from 'process';
|
|
8
8
|
import { fileURLToPath, pathToFileURL } from 'url';
|
|
9
|
-
import * as
|
|
10
|
-
import
|
|
11
|
-
import { EventEmitter } from 'events';
|
|
12
|
-
import { stat, readFile, realpath, readdir, mkdir, mkdtemp, writeFile, access, appendFile, rm, rename } from 'fs/promises';
|
|
13
|
-
import { Writable, Readable } from 'stream';
|
|
9
|
+
import * as os4 from 'os';
|
|
10
|
+
import os4__default from 'os';
|
|
14
11
|
import crypto5, { createHash, randomUUID } from 'crypto';
|
|
15
|
-
import http2 from 'http';
|
|
16
12
|
import { builtinModules, createRequire } from 'module';
|
|
13
|
+
import http2 from 'http';
|
|
14
|
+
import { EventEmitter } from 'events';
|
|
15
|
+
import { stat, readFile, realpath, readdir, mkdir, mkdtemp, writeFile, appendFile, rm, rename, access } from 'fs/promises';
|
|
16
|
+
import { Writable, Readable } from 'stream';
|
|
17
17
|
import net2 from 'net';
|
|
18
18
|
|
|
19
19
|
var __defProp = Object.defineProperty;
|
|
@@ -22,7 +22,7 @@ var __export = (target, all) => {
|
|
|
22
22
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
23
23
|
};
|
|
24
24
|
function openBrowser(url2, deps = {}) {
|
|
25
|
-
const platform = deps.platform ??
|
|
25
|
+
const platform = deps.platform ?? os4__default.platform();
|
|
26
26
|
const spawnBrowser = deps.spawnBrowser ?? ((command2, args, options) => {
|
|
27
27
|
const child = spawn(command2, [...args], options);
|
|
28
28
|
child.once("error", () => {
|
|
@@ -214,6 +214,709 @@ function readStringControlSequence(text, start, scanStart, allowBelTerminator) {
|
|
|
214
214
|
function isC1Control(code) {
|
|
215
215
|
return code >= 128 && code <= 159;
|
|
216
216
|
}
|
|
217
|
+
var LOCK_DIR_MODE = 448;
|
|
218
|
+
var LOCK_FILE_MODE = 384;
|
|
219
|
+
function createConsoleLock(deps = {}) {
|
|
220
|
+
const fsImpl = deps.fs ?? fs11__default;
|
|
221
|
+
const now = deps.now ?? Date.now;
|
|
222
|
+
const randomToken = deps.randomToken ?? (() => crypto5.randomBytes(32).toString("base64url"));
|
|
223
|
+
const hostname5 = deps.hostname ?? (() => "127.0.0.1");
|
|
224
|
+
function ensureLockDir(dir) {
|
|
225
|
+
fsImpl.mkdirSync(dir, { recursive: true, mode: LOCK_DIR_MODE });
|
|
226
|
+
fsImpl.chmodSync(dir, LOCK_DIR_MODE);
|
|
227
|
+
}
|
|
228
|
+
function readLock(lockFile) {
|
|
229
|
+
try {
|
|
230
|
+
const stat5 = fsImpl.lstatSync(lockFile);
|
|
231
|
+
if (stat5.isSymbolicLink()) {
|
|
232
|
+
throw new Error(`Refusing symbolic console lock: ${lockFile}`);
|
|
233
|
+
}
|
|
234
|
+
return JSON.parse(fsImpl.readFileSync(lockFile, "utf8"));
|
|
235
|
+
} catch (err) {
|
|
236
|
+
if (err.code === "ENOENT") return null;
|
|
237
|
+
throw err;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
function writeLock(input) {
|
|
241
|
+
ensureLockDir(input.dir);
|
|
242
|
+
const payload = {
|
|
243
|
+
pid: input.pid,
|
|
244
|
+
host: hostname5(),
|
|
245
|
+
port: input.port,
|
|
246
|
+
endpoint: input.endpoint,
|
|
247
|
+
startedAt: now(),
|
|
248
|
+
token: randomToken(),
|
|
249
|
+
version: input.version
|
|
250
|
+
};
|
|
251
|
+
const fd = fsImpl.openSync(input.lockFile, fs11__default.constants.O_CREAT | fs11__default.constants.O_EXCL | fs11__default.constants.O_WRONLY, LOCK_FILE_MODE);
|
|
252
|
+
try {
|
|
253
|
+
fsImpl.writeFileSync(fd, `${JSON.stringify(payload, null, 2)}
|
|
254
|
+
`, "utf8");
|
|
255
|
+
fsImpl.fchmodSync(fd, LOCK_FILE_MODE);
|
|
256
|
+
} finally {
|
|
257
|
+
fsImpl.closeSync(fd);
|
|
258
|
+
}
|
|
259
|
+
return { payload, release: () => removeLock(input.lockFile, payload.pid) };
|
|
260
|
+
}
|
|
261
|
+
function removeLock(lockFile, pid) {
|
|
262
|
+
let current = null;
|
|
263
|
+
try {
|
|
264
|
+
current = readLock(lockFile);
|
|
265
|
+
} catch (err) {
|
|
266
|
+
if (pid != null) throw err;
|
|
267
|
+
}
|
|
268
|
+
if (pid != null && current && current.pid !== pid) return;
|
|
269
|
+
try {
|
|
270
|
+
fsImpl.rmSync(lockFile, { force: true });
|
|
271
|
+
} catch (err) {
|
|
272
|
+
if (err.code !== "ENOENT") throw err;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
function assertLockModes(lockFile) {
|
|
276
|
+
if (typeof process.getuid !== "function") return;
|
|
277
|
+
const dir = path25__default.dirname(lockFile);
|
|
278
|
+
const dirMode = fsImpl.statSync(dir).mode & 511;
|
|
279
|
+
const fileMode = fsImpl.statSync(lockFile).mode & 511;
|
|
280
|
+
if (dirMode !== LOCK_DIR_MODE) {
|
|
281
|
+
throw new Error(`Console lock directory mode must be 0700, got ${dirMode.toString(8)}`);
|
|
282
|
+
}
|
|
283
|
+
if (fileMode !== LOCK_FILE_MODE) {
|
|
284
|
+
throw new Error(`Console lock file mode must be 0600, got ${fileMode.toString(8)}`);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
function assertTrustedLock(input) {
|
|
288
|
+
const dirStat = fsImpl.statSync(input.dir);
|
|
289
|
+
const fileStat = fsImpl.lstatSync(input.lockFile);
|
|
290
|
+
if (fileStat.isSymbolicLink()) {
|
|
291
|
+
throw new Error(`Refusing symbolic console lock: ${input.lockFile}`);
|
|
292
|
+
}
|
|
293
|
+
assertLockModes(input.lockFile);
|
|
294
|
+
const currentUid = typeof process.getuid === "function" ? process.getuid() : null;
|
|
295
|
+
if (currentUid != null && (dirStat.uid !== currentUid || fileStat.uid !== currentUid)) {
|
|
296
|
+
throw new Error("Console lock owner does not match current user");
|
|
297
|
+
}
|
|
298
|
+
if (input.payload.host !== input.host) {
|
|
299
|
+
throw new Error(`Console lock host must match ${input.host}: ${input.payload.host}`);
|
|
300
|
+
}
|
|
301
|
+
if (!Number.isInteger(input.payload.port) || input.payload.port < 1 || input.payload.port > 65535) {
|
|
302
|
+
throw new Error(`Console lock port must be a valid TCP port, got ${input.payload.port}`);
|
|
303
|
+
}
|
|
304
|
+
const endpoint = new URL(input.payload.endpoint);
|
|
305
|
+
if (endpoint.protocol !== "http:" || endpoint.pathname !== "/") {
|
|
306
|
+
throw new Error("Console lock endpoint must be the loopback server root");
|
|
307
|
+
}
|
|
308
|
+
if (endpoint.hostname !== input.host || Number(endpoint.port) !== input.payload.port) {
|
|
309
|
+
throw new Error("Console lock endpoint must use the loopback host and the lock port");
|
|
310
|
+
}
|
|
311
|
+
if (input.payload.endpoint !== `http://${input.host}:${input.payload.port}/`) {
|
|
312
|
+
throw new Error("Console lock endpoint must match the lock host and port");
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
return { ensureLockDir, readLock, writeLock, removeLock, assertLockModes, assertTrustedLock };
|
|
316
|
+
}
|
|
317
|
+
var FLEET_DATA_DIR_NAME = ".fleet";
|
|
318
|
+
function getFleetDataDir() {
|
|
319
|
+
return path25.join(os4.homedir(), FLEET_DATA_DIR_NAME);
|
|
320
|
+
}
|
|
321
|
+
var SECURE_DIR_MODE = 448;
|
|
322
|
+
var SECURE_FILE_MODE = 384;
|
|
323
|
+
var NOFOLLOW_FLAG = fs11.constants.O_NOFOLLOW ?? 0;
|
|
324
|
+
function safeLstat(targetPath) {
|
|
325
|
+
try {
|
|
326
|
+
return fs11.lstatSync(targetPath);
|
|
327
|
+
} catch (error51) {
|
|
328
|
+
if (error51.code === "ENOENT") {
|
|
329
|
+
return null;
|
|
330
|
+
}
|
|
331
|
+
throw error51;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
function ensureSafeDirectory(dirPath) {
|
|
335
|
+
const stat5 = safeLstat(dirPath);
|
|
336
|
+
if (stat5) {
|
|
337
|
+
if (!stat5.isDirectory() || stat5.isSymbolicLink()) {
|
|
338
|
+
throw new Error(`Unsafe Fleet directory: ${dirPath}`);
|
|
339
|
+
}
|
|
340
|
+
fs11.chmodSync(dirPath, SECURE_DIR_MODE);
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
fs11.mkdirSync(dirPath, { recursive: true, mode: SECURE_DIR_MODE });
|
|
344
|
+
const created = safeLstat(dirPath);
|
|
345
|
+
if (!created?.isDirectory() || created.isSymbolicLink()) {
|
|
346
|
+
throw new Error(`Unsafe Fleet directory: ${dirPath}`);
|
|
347
|
+
}
|
|
348
|
+
fs11.chmodSync(dirPath, SECURE_DIR_MODE);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
// ../../packages/fleet-infra/src/fs-store/atomic-write.ts
|
|
352
|
+
var DEFAULT_MAX_ATTEMPTS = 10;
|
|
353
|
+
var IGNORED_FSYNC_ERROR_CODES = /* @__PURE__ */ new Set(["EPERM", "EINVAL", "ENOSYS"]);
|
|
354
|
+
function buildTempPath(filePath) {
|
|
355
|
+
const suffix = `${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}.${os4.hostname()}`;
|
|
356
|
+
return `${filePath}.${suffix}.tmp`;
|
|
357
|
+
}
|
|
358
|
+
function writeAtomicSync(filePath, content, options = {}) {
|
|
359
|
+
const mode = options.mode ?? SECURE_FILE_MODE;
|
|
360
|
+
const doFsync = options.fsync !== false;
|
|
361
|
+
const maxAttempts = options.maxAttempts ?? DEFAULT_MAX_ATTEMPTS;
|
|
362
|
+
let lastExistsError;
|
|
363
|
+
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
364
|
+
const tempPath = buildTempPath(filePath);
|
|
365
|
+
let tempCreated = false;
|
|
366
|
+
try {
|
|
367
|
+
fs11.writeFileSync(tempPath, content, { encoding: "utf-8", flag: "wx", mode });
|
|
368
|
+
tempCreated = true;
|
|
369
|
+
if (doFsync) {
|
|
370
|
+
const fd = fs11.openSync(tempPath, "r");
|
|
371
|
+
try {
|
|
372
|
+
fsyncSyncBestEffort(fd);
|
|
373
|
+
} finally {
|
|
374
|
+
fs11.closeSync(fd);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
fs11.renameSync(tempPath, filePath);
|
|
378
|
+
return;
|
|
379
|
+
} catch (error51) {
|
|
380
|
+
const code = error51.code;
|
|
381
|
+
if (!tempCreated && code === "EEXIST") {
|
|
382
|
+
lastExistsError = error51;
|
|
383
|
+
continue;
|
|
384
|
+
}
|
|
385
|
+
if (tempCreated) {
|
|
386
|
+
try {
|
|
387
|
+
fs11.unlinkSync(tempPath);
|
|
388
|
+
} catch {
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
throw error51;
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
throw lastExistsError ?? new Error(`Failed to create temp file after ${maxAttempts} attempts: ${filePath}`);
|
|
395
|
+
}
|
|
396
|
+
function cleanupTempFiles(dir, prefix, minAgeMs, now) {
|
|
397
|
+
let entries;
|
|
398
|
+
try {
|
|
399
|
+
entries = fs11.readdirSync(dir);
|
|
400
|
+
} catch {
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
for (const entry of entries) {
|
|
404
|
+
if (!entry.startsWith(prefix)) {
|
|
405
|
+
continue;
|
|
406
|
+
}
|
|
407
|
+
const tempPath = path25.join(dir, entry);
|
|
408
|
+
try {
|
|
409
|
+
const stat5 = fs11.lstatSync(tempPath);
|
|
410
|
+
if (stat5?.isFile() && !stat5.isSymbolicLink() && now - stat5.mtimeMs >= minAgeMs) {
|
|
411
|
+
fs11.unlinkSync(tempPath);
|
|
412
|
+
}
|
|
413
|
+
} catch {
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
function isIgnoredFsyncError(error51) {
|
|
418
|
+
const code = error51.code;
|
|
419
|
+
return typeof code === "string" && IGNORED_FSYNC_ERROR_CODES.has(code);
|
|
420
|
+
}
|
|
421
|
+
function fsyncSyncBestEffort(fd) {
|
|
422
|
+
try {
|
|
423
|
+
fs11.fsyncSync(fd);
|
|
424
|
+
} catch (error51) {
|
|
425
|
+
if (!isIgnoredFsyncError(error51)) {
|
|
426
|
+
throw error51;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
var DEFAULT_LOCK_TIMEOUT_MS = 5e3;
|
|
431
|
+
var DEFAULT_STALE_LOCK_MS = 3e4;
|
|
432
|
+
var DEFAULT_RETRY_MS = 25;
|
|
433
|
+
var DEFAULT_OWNER_FILE_NAME = "owner.json";
|
|
434
|
+
function withDirectoryLock(deps, operation) {
|
|
435
|
+
const ownerFileName = deps.ownerFileName ?? DEFAULT_OWNER_FILE_NAME;
|
|
436
|
+
const timeoutMs = deps.timeoutMs ?? DEFAULT_LOCK_TIMEOUT_MS;
|
|
437
|
+
const staleLockMs = deps.staleLockMs ?? DEFAULT_STALE_LOCK_MS;
|
|
438
|
+
const retryMs = deps.retryMs ?? DEFAULT_RETRY_MS;
|
|
439
|
+
const now = deps.now ?? (() => Date.now());
|
|
440
|
+
const startedAt = now();
|
|
441
|
+
while (true) {
|
|
442
|
+
try {
|
|
443
|
+
fs11.mkdirSync(deps.lockDir, { mode: 448 });
|
|
444
|
+
writeLockOwner(deps.lockDir, ownerFileName, now());
|
|
445
|
+
try {
|
|
446
|
+
return operation();
|
|
447
|
+
} finally {
|
|
448
|
+
releaseLock(deps.lockDir);
|
|
449
|
+
}
|
|
450
|
+
} catch (error51) {
|
|
451
|
+
const code = error51.code;
|
|
452
|
+
if (code !== "EEXIST") throw error51;
|
|
453
|
+
recoverStaleLock(deps.lockDir, ownerFileName, now, staleLockMs);
|
|
454
|
+
if (now() - startedAt >= timeoutMs) {
|
|
455
|
+
throw new Error(`Timed out waiting for Fleet directory lock: ${deps.lockDir}`);
|
|
456
|
+
}
|
|
457
|
+
sleepSync(retryMs);
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
function releaseLock(lockDir) {
|
|
462
|
+
try {
|
|
463
|
+
fs11.rmSync(lockDir, { recursive: true, force: true });
|
|
464
|
+
} catch {
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
function recoverStaleLock(lockDir, ownerFileName, now, staleLockMs) {
|
|
468
|
+
try {
|
|
469
|
+
const initialSnapshot = readLockSnapshot(lockDir, ownerFileName);
|
|
470
|
+
if (!isRecoverableSnapshot(initialSnapshot, now, staleLockMs)) return;
|
|
471
|
+
const quarantineDir = buildQuarantinePath(lockDir);
|
|
472
|
+
try {
|
|
473
|
+
fs11.renameSync(lockDir, quarantineDir);
|
|
474
|
+
} catch {
|
|
475
|
+
return;
|
|
476
|
+
}
|
|
477
|
+
try {
|
|
478
|
+
const quarantinedSnapshot = readLockSnapshot(quarantineDir, ownerFileName);
|
|
479
|
+
if (sameLockSnapshot(initialSnapshot, quarantinedSnapshot) && isRecoverableSnapshot(quarantinedSnapshot, now, staleLockMs)) {
|
|
480
|
+
fs11.rmSync(quarantineDir, { recursive: true, force: true });
|
|
481
|
+
} else {
|
|
482
|
+
restoreQuarantinedLock(quarantineDir, lockDir);
|
|
483
|
+
}
|
|
484
|
+
} catch (error51) {
|
|
485
|
+
const code = error51.code;
|
|
486
|
+
if (code !== "ENOENT") throw error51;
|
|
487
|
+
}
|
|
488
|
+
} catch (error51) {
|
|
489
|
+
const code = error51.code;
|
|
490
|
+
if (code !== "ENOENT") throw error51;
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
function readLockSnapshot(lockDir, ownerFileName) {
|
|
494
|
+
const stat5 = fs11.lstatSync(lockDir);
|
|
495
|
+
if (stat5.isSymbolicLink()) {
|
|
496
|
+
return { owner: null, mtimeMs: 0 };
|
|
497
|
+
}
|
|
498
|
+
return {
|
|
499
|
+
owner: readLockOwner(lockDir, ownerFileName),
|
|
500
|
+
mtimeMs: stat5.mtimeMs
|
|
501
|
+
};
|
|
502
|
+
}
|
|
503
|
+
function buildQuarantinePath(lockDir) {
|
|
504
|
+
const suffix = `${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}`;
|
|
505
|
+
return `${lockDir}.stale.${suffix}`;
|
|
506
|
+
}
|
|
507
|
+
function writeLockOwner(lockDir, ownerFileName, startedAt) {
|
|
508
|
+
const owner = {
|
|
509
|
+
pid: process.pid,
|
|
510
|
+
hostname: os4.hostname(),
|
|
511
|
+
startedAt
|
|
512
|
+
};
|
|
513
|
+
const ownerPath = path25.join(lockDir, ownerFileName);
|
|
514
|
+
try {
|
|
515
|
+
fs11.writeFileSync(ownerPath, JSON.stringify(owner), { encoding: "utf-8", mode: 384 });
|
|
516
|
+
} catch (error51) {
|
|
517
|
+
releaseLock(lockDir);
|
|
518
|
+
throw error51;
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
function readLockOwner(lockDir, ownerFileName) {
|
|
522
|
+
const ownerPath = path25.join(lockDir, ownerFileName);
|
|
523
|
+
try {
|
|
524
|
+
return sanitizeLockOwner(JSON.parse(fs11.readFileSync(ownerPath, "utf-8")));
|
|
525
|
+
} catch (error51) {
|
|
526
|
+
const code = error51.code;
|
|
527
|
+
if (code === "ENOENT") return null;
|
|
528
|
+
throw error51;
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
function isRecoverableOwner(owner, now, staleLockMs) {
|
|
532
|
+
if (owner.hostname !== os4.hostname()) return false;
|
|
533
|
+
if (now() - owner.startedAt < staleLockMs) return false;
|
|
534
|
+
return !isProcessAlive(owner.pid);
|
|
535
|
+
}
|
|
536
|
+
function isRecoverableSnapshot(snapshot, now, staleLockMs) {
|
|
537
|
+
if (snapshot.owner) return isRecoverableOwner(snapshot.owner, now, staleLockMs);
|
|
538
|
+
return now() - snapshot.mtimeMs >= staleLockMs;
|
|
539
|
+
}
|
|
540
|
+
function sameLockSnapshot(a, b) {
|
|
541
|
+
if (!a.owner || !b.owner) return !a.owner && !b.owner && a.mtimeMs === b.mtimeMs;
|
|
542
|
+
return a.owner.pid === b.owner.pid && a.owner.hostname === b.owner.hostname && a.owner.startedAt === b.owner.startedAt;
|
|
543
|
+
}
|
|
544
|
+
function restoreQuarantinedLock(quarantineDir, lockDir) {
|
|
545
|
+
try {
|
|
546
|
+
fs11.renameSync(quarantineDir, lockDir);
|
|
547
|
+
} catch {
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
function isProcessAlive(pid) {
|
|
551
|
+
try {
|
|
552
|
+
process.kill(pid, 0);
|
|
553
|
+
return true;
|
|
554
|
+
} catch (error51) {
|
|
555
|
+
const code = error51.code;
|
|
556
|
+
if (code === "ESRCH") return false;
|
|
557
|
+
return true;
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
function sanitizeLockOwner(value) {
|
|
561
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return null;
|
|
562
|
+
const record2 = value;
|
|
563
|
+
const pid = record2.pid;
|
|
564
|
+
const hostname5 = record2.hostname;
|
|
565
|
+
const startedAt = record2.startedAt;
|
|
566
|
+
if (!Number.isInteger(pid) || pid <= 0) return null;
|
|
567
|
+
if (typeof hostname5 !== "string" || !hostname5) return null;
|
|
568
|
+
if (!Number.isFinite(startedAt) || startedAt <= 0) return null;
|
|
569
|
+
return {
|
|
570
|
+
pid,
|
|
571
|
+
hostname: hostname5,
|
|
572
|
+
startedAt
|
|
573
|
+
};
|
|
574
|
+
}
|
|
575
|
+
function sleepSync(ms) {
|
|
576
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
|
|
577
|
+
}
|
|
578
|
+
function readAuthStoreFile(filePath) {
|
|
579
|
+
let fd;
|
|
580
|
+
try {
|
|
581
|
+
fd = fs11.openSync(filePath, fs11.constants.O_RDONLY | NOFOLLOW_FLAG);
|
|
582
|
+
if (!fs11.fstatSync(fd).isFile()) {
|
|
583
|
+
return {};
|
|
584
|
+
}
|
|
585
|
+
return JSON.parse(fs11.readFileSync(fd, "utf-8"));
|
|
586
|
+
} catch {
|
|
587
|
+
return {};
|
|
588
|
+
} finally {
|
|
589
|
+
if (fd !== void 0) {
|
|
590
|
+
try {
|
|
591
|
+
fs11.closeSync(fd);
|
|
592
|
+
} catch {
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
// ../../packages/fleet-infra/src/auth/auth-storage.ts
|
|
599
|
+
var DEFAULT_AUTH_PATH = path25.join(getFleetDataDir(), "auth.json");
|
|
600
|
+
var AUTH_LOCK_OWNER_FILE_NAME = "owner.json";
|
|
601
|
+
var AUTH_LOCK_TIMEOUT_MS = 5e3;
|
|
602
|
+
function createAuthService(deps = {}) {
|
|
603
|
+
const authPath = deps.authPath ?? DEFAULT_AUTH_PATH;
|
|
604
|
+
const lockDir = `${authPath}.lock`;
|
|
605
|
+
return {
|
|
606
|
+
// [HIGH #1] TOCTOU 수정: existsSync/read/check/delete/write 전체를 락 블록 안으로 이동
|
|
607
|
+
async deleteApiKey(providerId) {
|
|
608
|
+
let deleted = false;
|
|
609
|
+
withAuthLock(authPath, lockDir, () => {
|
|
610
|
+
if (!fs11.existsSync(authPath)) return;
|
|
611
|
+
const data = readAuthStoreFile(authPath);
|
|
612
|
+
if (!Object.prototype.hasOwnProperty.call(data, providerId)) return;
|
|
613
|
+
delete data[providerId];
|
|
614
|
+
writeAuthData(authPath, data);
|
|
615
|
+
deleted = true;
|
|
616
|
+
});
|
|
617
|
+
return deleted;
|
|
618
|
+
},
|
|
619
|
+
// [HIGH #2] 읽기 경로: fd 기반 O_RDONLY|O_NOFOLLOW+fstatSync isFile
|
|
620
|
+
async getApiKey(providerId) {
|
|
621
|
+
let fd;
|
|
622
|
+
try {
|
|
623
|
+
if (!fs11.existsSync(authPath)) {
|
|
624
|
+
return void 0;
|
|
625
|
+
}
|
|
626
|
+
fd = fs11.openSync(authPath, fs11.constants.O_RDONLY | NOFOLLOW_FLAG);
|
|
627
|
+
if (!fs11.fstatSync(fd).isFile()) {
|
|
628
|
+
return void 0;
|
|
629
|
+
}
|
|
630
|
+
const data = JSON.parse(fs11.readFileSync(fd, "utf-8"));
|
|
631
|
+
return typeof data[providerId]?.key === "string" ? data[providerId].key : void 0;
|
|
632
|
+
} catch {
|
|
633
|
+
return void 0;
|
|
634
|
+
} finally {
|
|
635
|
+
if (fd !== void 0) {
|
|
636
|
+
try {
|
|
637
|
+
fs11.closeSync(fd);
|
|
638
|
+
} catch {
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
},
|
|
643
|
+
// [HIGH #2] 읽기 경로: fd 기반 O_RDONLY|O_NOFOLLOW 통일
|
|
644
|
+
async listProviderIds() {
|
|
645
|
+
if (!fs11.existsSync(authPath)) {
|
|
646
|
+
return [];
|
|
647
|
+
}
|
|
648
|
+
try {
|
|
649
|
+
return Object.keys(readAuthStoreFile(authPath)).sort();
|
|
650
|
+
} catch {
|
|
651
|
+
return [];
|
|
652
|
+
}
|
|
653
|
+
},
|
|
654
|
+
async setApiKey(providerId, key) {
|
|
655
|
+
const dir = path25.dirname(authPath);
|
|
656
|
+
ensureSafeDirectory(dir);
|
|
657
|
+
withAuthLock(authPath, lockDir, () => {
|
|
658
|
+
const data = fs11.existsSync(authPath) ? readAuthStoreFile(authPath) : {};
|
|
659
|
+
data[providerId] = {
|
|
660
|
+
...data[providerId] ?? {},
|
|
661
|
+
key
|
|
662
|
+
};
|
|
663
|
+
writeAuthData(authPath, data);
|
|
664
|
+
});
|
|
665
|
+
}
|
|
666
|
+
};
|
|
667
|
+
}
|
|
668
|
+
function withAuthLock(authPath, lockDir, operation) {
|
|
669
|
+
return withDirectoryLock(
|
|
670
|
+
{
|
|
671
|
+
lockDir,
|
|
672
|
+
ownerFileName: AUTH_LOCK_OWNER_FILE_NAME,
|
|
673
|
+
timeoutMs: AUTH_LOCK_TIMEOUT_MS
|
|
674
|
+
},
|
|
675
|
+
operation
|
|
676
|
+
);
|
|
677
|
+
}
|
|
678
|
+
function writeAuthData(authPath, data) {
|
|
679
|
+
writeAtomicSync(authPath, `${JSON.stringify(data, null, 2)}
|
|
680
|
+
`, {
|
|
681
|
+
mode: SECURE_FILE_MODE,
|
|
682
|
+
fsync: true
|
|
683
|
+
});
|
|
684
|
+
}
|
|
685
|
+
var DEFAULT_TEMP_FILE_MIN_AGE_MS = 6e4;
|
|
686
|
+
function createDurableJsonStore(deps) {
|
|
687
|
+
const now = deps.now ?? (() => Date.now());
|
|
688
|
+
const sensitivity = deps.sensitivity;
|
|
689
|
+
const mode = sensitivity === "sensitive" ? SECURE_FILE_MODE : 420;
|
|
690
|
+
const minAgeMs = deps.tempCleanupMinAgeMs ?? DEFAULT_TEMP_FILE_MIN_AGE_MS;
|
|
691
|
+
const dir = path25.dirname(deps.filePath);
|
|
692
|
+
return {
|
|
693
|
+
path: deps.filePath,
|
|
694
|
+
load() {
|
|
695
|
+
return readJsonFile(deps.filePath, deps.sanitize);
|
|
696
|
+
},
|
|
697
|
+
save(data) {
|
|
698
|
+
withLock(() => {
|
|
699
|
+
writeAtomicSync(deps.filePath, `${JSON.stringify(data, null, 2)}
|
|
700
|
+
`, { mode });
|
|
701
|
+
});
|
|
702
|
+
},
|
|
703
|
+
update(mutate) {
|
|
704
|
+
let result;
|
|
705
|
+
withLock(() => {
|
|
706
|
+
const current = readJsonFile(deps.filePath, deps.sanitize);
|
|
707
|
+
const next = mutate(current);
|
|
708
|
+
writeAtomicSync(deps.filePath, `${JSON.stringify(next, null, 2)}
|
|
709
|
+
`, { mode });
|
|
710
|
+
result = next;
|
|
711
|
+
});
|
|
712
|
+
return result;
|
|
713
|
+
}
|
|
714
|
+
};
|
|
715
|
+
function withLock(operation) {
|
|
716
|
+
if (!deps.lockDir) {
|
|
717
|
+
ensureSafeDirectoryIfSensitive(dir, sensitivity);
|
|
718
|
+
return operation();
|
|
719
|
+
}
|
|
720
|
+
ensureSafeDirectoryIfSensitive(dir, sensitivity);
|
|
721
|
+
return withDirectoryLock(
|
|
722
|
+
{
|
|
723
|
+
lockDir: deps.lockDir,
|
|
724
|
+
ownerFileName: deps.lockOwnerFileName,
|
|
725
|
+
timeoutMs: deps.timeoutMs,
|
|
726
|
+
staleLockMs: deps.staleLockMs,
|
|
727
|
+
now
|
|
728
|
+
},
|
|
729
|
+
() => {
|
|
730
|
+
if (deps.tempCleanupPrefix) {
|
|
731
|
+
cleanupTempFiles(dir, deps.tempCleanupPrefix, minAgeMs, now());
|
|
732
|
+
}
|
|
733
|
+
return operation();
|
|
734
|
+
}
|
|
735
|
+
);
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
function readJsonFile(filePath, sanitize) {
|
|
739
|
+
let fd;
|
|
740
|
+
try {
|
|
741
|
+
const stat5 = fs11.lstatSync(filePath);
|
|
742
|
+
if (!stat5 || !stat5.isFile() || stat5.isSymbolicLink()) {
|
|
743
|
+
return sanitize(void 0);
|
|
744
|
+
}
|
|
745
|
+
fd = fs11.openSync(filePath, fs11.constants.O_RDONLY | NOFOLLOW_FLAG);
|
|
746
|
+
if (!fs11.fstatSync(fd).isFile()) {
|
|
747
|
+
return sanitize(void 0);
|
|
748
|
+
}
|
|
749
|
+
return sanitize(JSON.parse(fs11.readFileSync(fd, "utf-8")));
|
|
750
|
+
} catch {
|
|
751
|
+
return sanitize(void 0);
|
|
752
|
+
} finally {
|
|
753
|
+
if (fd !== void 0) {
|
|
754
|
+
try {
|
|
755
|
+
fs11.closeSync(fd);
|
|
756
|
+
} catch {
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
function ensureSafeDirectoryIfSensitive(dir, sensitivity) {
|
|
762
|
+
if (sensitivity === "sensitive") {
|
|
763
|
+
ensureSafeDirectory(dir);
|
|
764
|
+
} else {
|
|
765
|
+
fs11.mkdirSync(dir, { recursive: true });
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
// ../../packages/fleet-infra/src/global-options/store.ts
|
|
770
|
+
var GLOBAL_OPTIONS_VERSION = 1;
|
|
771
|
+
var GLOBAL_OPTIONS_FILE_NAME = "settings.json";
|
|
772
|
+
var LOCK_DIR_NAME = "settings.json.lock";
|
|
773
|
+
var LOCK_OWNER_FILE_NAME = "owner";
|
|
774
|
+
var TEMP_FILE_PREFIX = `.tmp-${GLOBAL_OPTIONS_FILE_NAME}-`;
|
|
775
|
+
function createGlobalOptionsStore(deps = {}) {
|
|
776
|
+
const dataDir = deps.dataDir ?? getFleetDataDir();
|
|
777
|
+
const optionsPath = path25.join(dataDir, GLOBAL_OPTIONS_FILE_NAME);
|
|
778
|
+
const lockDir = path25.join(dataDir, LOCK_DIR_NAME);
|
|
779
|
+
const store2 = createDurableJsonStore({
|
|
780
|
+
filePath: optionsPath,
|
|
781
|
+
lockDir,
|
|
782
|
+
lockOwnerFileName: LOCK_OWNER_FILE_NAME,
|
|
783
|
+
sanitize: (value) => sanitizeGlobalOptionsData(value).data,
|
|
784
|
+
sensitivity: "sensitive",
|
|
785
|
+
timeoutMs: deps.timeoutMs,
|
|
786
|
+
staleLockMs: deps.staleLockMs,
|
|
787
|
+
tempCleanupPrefix: TEMP_FILE_PREFIX,
|
|
788
|
+
now: deps.now
|
|
789
|
+
});
|
|
790
|
+
return {
|
|
791
|
+
path: optionsPath,
|
|
792
|
+
load: () => store2.load(),
|
|
793
|
+
save: (data) => store2.save(sanitizeGlobalOptionsData(data).data),
|
|
794
|
+
update: (mutate) => store2.update((current) => sanitizeGlobalOptionsData(mutate(current)).data)
|
|
795
|
+
};
|
|
796
|
+
}
|
|
797
|
+
function createEmptyGlobalOptionsData() {
|
|
798
|
+
return {
|
|
799
|
+
version: GLOBAL_OPTIONS_VERSION
|
|
800
|
+
};
|
|
801
|
+
}
|
|
802
|
+
function sanitizeGlobalOptionsData(value) {
|
|
803
|
+
if (!isRecord(value)) {
|
|
804
|
+
return { data: createEmptyGlobalOptionsData(), changed: true };
|
|
805
|
+
}
|
|
806
|
+
if (value.version !== GLOBAL_OPTIONS_VERSION) {
|
|
807
|
+
return { data: createEmptyGlobalOptionsData(), changed: true };
|
|
808
|
+
}
|
|
809
|
+
const data = {
|
|
810
|
+
version: GLOBAL_OPTIONS_VERSION,
|
|
811
|
+
...typeof value.replaceSystemPrompt === "boolean" ? { replaceSystemPrompt: value.replaceSystemPrompt } : {},
|
|
812
|
+
...typeof value.enableMetaphor === "boolean" ? { enableMetaphor: value.enableMetaphor } : {}
|
|
813
|
+
};
|
|
814
|
+
const allowedKeys = /* @__PURE__ */ new Set(["version", "replaceSystemPrompt", "enableMetaphor"]);
|
|
815
|
+
const changed = Object.keys(value).some((key) => !allowedKeys.has(key)) || "replaceSystemPrompt" in value && typeof value.replaceSystemPrompt !== "boolean" || "enableMetaphor" in value && typeof value.enableMetaphor !== "boolean";
|
|
816
|
+
return { data, changed };
|
|
817
|
+
}
|
|
818
|
+
function isRecord(value) {
|
|
819
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
// ../../packages/fleet-infra/src/global-options/service.ts
|
|
823
|
+
function createGlobalOptionsService(deps = {}) {
|
|
824
|
+
const store2 = deps.store ?? createGlobalOptionsStore({ dataDir: deps.dataDir });
|
|
825
|
+
return {
|
|
826
|
+
load: () => store2.load(),
|
|
827
|
+
save: (data) => {
|
|
828
|
+
store2.save(data);
|
|
829
|
+
return store2.load();
|
|
830
|
+
},
|
|
831
|
+
update: (mutate) => updateGlobalOptions(store2, mutate)
|
|
832
|
+
};
|
|
833
|
+
}
|
|
834
|
+
function updateGlobalOptions(store2, mutate) {
|
|
835
|
+
return store2.update(mutate);
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
// ../../packages/fleet-infra/src/index.ts
|
|
839
|
+
function createInfraServices(deps = {}) {
|
|
840
|
+
const globalOptionsService = createGlobalOptionsService();
|
|
841
|
+
const authService = createAuthService({ authPath: deps.authPath ?? DEFAULT_AUTH_PATH });
|
|
842
|
+
return {
|
|
843
|
+
authService,
|
|
844
|
+
globalOptionsService
|
|
845
|
+
};
|
|
846
|
+
}
|
|
847
|
+
function readFleetConsoleRelease() {
|
|
848
|
+
const requireFromHere = createRequire(import.meta.url);
|
|
849
|
+
const packageJsonPath = resolvePackageJsonPath(requireFromHere);
|
|
850
|
+
const pkg = requireFromHere(packageJsonPath);
|
|
851
|
+
const packageRoot = path25__default.dirname(packageJsonPath);
|
|
852
|
+
const version2 = pkg.version ?? "";
|
|
853
|
+
if (pkg.private === true) {
|
|
854
|
+
return { channel: "local", version: version2, packageRoot };
|
|
855
|
+
}
|
|
856
|
+
return { channel: "stable", version: version2, packageRoot };
|
|
857
|
+
}
|
|
858
|
+
function resolvePackageJsonPath(requireFromHere) {
|
|
859
|
+
for (const candidate of ["../package.json", "../../package.json"]) {
|
|
860
|
+
try {
|
|
861
|
+
return requireFromHere.resolve(candidate);
|
|
862
|
+
} catch (error51) {
|
|
863
|
+
if (error51.code !== "MODULE_NOT_FOUND") throw error51;
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
throw new Error("fleet_console_package_json_not_found");
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
// core/host/paths.ts
|
|
870
|
+
var LOCK_DIR_NAME2 = "fleet-console";
|
|
871
|
+
var CONSOLE_RUNTIME_DIR_NAME = "console";
|
|
872
|
+
var LOCK_FILE_NAME = "console.lock";
|
|
873
|
+
var CONSOLE_DATA_DIR_NAME = "console";
|
|
874
|
+
var CONSOLE_STATE_FILE_NAME = "state.json";
|
|
875
|
+
var CONSOLE_SETTINGS_FILE_NAME = "settings.json";
|
|
876
|
+
var CONSOLE_CAPTURES_DIR_NAME = "captures";
|
|
877
|
+
function createConsolePaths(deps = {}) {
|
|
878
|
+
const env = deps.env ?? process.env;
|
|
879
|
+
const base = env.FLEET_CONSOLE_DIR ?? defaultConsoleBaseDir(deps);
|
|
880
|
+
return { dir: base, lockFile: path25__default.join(base, LOCK_FILE_NAME) };
|
|
881
|
+
}
|
|
882
|
+
function createConsoleDataPaths(deps = {}) {
|
|
883
|
+
const dir = defaultConsoleDataBaseDir(deps);
|
|
884
|
+
return {
|
|
885
|
+
dir,
|
|
886
|
+
stateFile: path25__default.join(dir, CONSOLE_STATE_FILE_NAME),
|
|
887
|
+
settingsFile: path25__default.join(dir, CONSOLE_SETTINGS_FILE_NAME),
|
|
888
|
+
capturesDir: path25__default.join(dir, CONSOLE_CAPTURES_DIR_NAME)
|
|
889
|
+
};
|
|
890
|
+
}
|
|
891
|
+
function defaultConsoleBaseDir(deps) {
|
|
892
|
+
let release;
|
|
893
|
+
const channel = deps.channel ?? (release = readFleetConsoleRelease()).channel;
|
|
894
|
+
if (channel === "local") {
|
|
895
|
+
const packageRoot = deps.packageRoot ?? (release ??= readFleetConsoleRelease()).packageRoot;
|
|
896
|
+
return localConsoleDir(packageRoot);
|
|
897
|
+
}
|
|
898
|
+
const uid = deps.uid ?? (typeof process.getuid === "function" ? process.getuid() : 0);
|
|
899
|
+
return path25__default.join(os4__default.tmpdir(), `${LOCK_DIR_NAME2}-${uid}-${channel}`);
|
|
900
|
+
}
|
|
901
|
+
function defaultConsoleDataBaseDir(deps) {
|
|
902
|
+
if (deps.fleetDataDir !== void 0) {
|
|
903
|
+
return path25__default.join(deps.fleetDataDir, CONSOLE_DATA_DIR_NAME);
|
|
904
|
+
}
|
|
905
|
+
const env = deps.env ?? process.env;
|
|
906
|
+
if (env.FLEET_CONSOLE_DIR) {
|
|
907
|
+
return env.FLEET_CONSOLE_DIR;
|
|
908
|
+
}
|
|
909
|
+
let release;
|
|
910
|
+
const channel = deps.channel ?? (release = readFleetConsoleRelease()).channel;
|
|
911
|
+
if (channel === "local") {
|
|
912
|
+
const packageRoot = deps.packageRoot ?? (release ??= readFleetConsoleRelease()).packageRoot;
|
|
913
|
+
return localConsoleDir(packageRoot);
|
|
914
|
+
}
|
|
915
|
+
return path25__default.join(getFleetDataDir(), CONSOLE_DATA_DIR_NAME);
|
|
916
|
+
}
|
|
917
|
+
function localConsoleDir(packageRoot) {
|
|
918
|
+
return path25__default.join(path25__default.resolve(packageRoot, "..", ".."), ".fleet", CONSOLE_RUNTIME_DIR_NAME);
|
|
919
|
+
}
|
|
217
920
|
|
|
218
921
|
// ../../packages/fleet-carriers/src/dispatch/framework.ts
|
|
219
922
|
var framework_exports = {};
|
|
@@ -374,7 +1077,7 @@ __export(external_exports, {
|
|
|
374
1077
|
guid: () => guid2,
|
|
375
1078
|
hash: () => hash,
|
|
376
1079
|
hex: () => hex2,
|
|
377
|
-
hostname: () =>
|
|
1080
|
+
hostname: () => hostname4,
|
|
378
1081
|
httpUrl: () => httpUrl,
|
|
379
1082
|
includes: () => _includes,
|
|
380
1083
|
instanceof: () => _instanceof,
|
|
@@ -1004,10 +1707,10 @@ function mergeDefs(...defs) {
|
|
|
1004
1707
|
function cloneDef(schema) {
|
|
1005
1708
|
return mergeDefs(schema._zod.def);
|
|
1006
1709
|
}
|
|
1007
|
-
function getElementAtPath(obj,
|
|
1008
|
-
if (!
|
|
1710
|
+
function getElementAtPath(obj, path46) {
|
|
1711
|
+
if (!path46)
|
|
1009
1712
|
return obj;
|
|
1010
|
-
return
|
|
1713
|
+
return path46.reduce((acc, key) => acc?.[key], obj);
|
|
1011
1714
|
}
|
|
1012
1715
|
function promiseAllObject(promisesObj) {
|
|
1013
1716
|
const keys = Object.keys(promisesObj);
|
|
@@ -1416,11 +2119,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
1416
2119
|
}
|
|
1417
2120
|
return false;
|
|
1418
2121
|
}
|
|
1419
|
-
function prefixIssues(
|
|
2122
|
+
function prefixIssues(path46, issues) {
|
|
1420
2123
|
return issues.map((iss) => {
|
|
1421
2124
|
var _a3;
|
|
1422
2125
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
1423
|
-
iss.path.unshift(
|
|
2126
|
+
iss.path.unshift(path46);
|
|
1424
2127
|
return iss;
|
|
1425
2128
|
});
|
|
1426
2129
|
}
|
|
@@ -1567,16 +2270,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
|
|
|
1567
2270
|
}
|
|
1568
2271
|
function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
1569
2272
|
const fieldErrors = { _errors: [] };
|
|
1570
|
-
const processError = (error52,
|
|
2273
|
+
const processError = (error52, path46 = []) => {
|
|
1571
2274
|
for (const issue2 of error52.issues) {
|
|
1572
2275
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
1573
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
2276
|
+
issue2.errors.map((issues) => processError({ issues }, [...path46, ...issue2.path]));
|
|
1574
2277
|
} else if (issue2.code === "invalid_key") {
|
|
1575
|
-
processError({ issues: issue2.issues }, [...
|
|
2278
|
+
processError({ issues: issue2.issues }, [...path46, ...issue2.path]);
|
|
1576
2279
|
} else if (issue2.code === "invalid_element") {
|
|
1577
|
-
processError({ issues: issue2.issues }, [...
|
|
2280
|
+
processError({ issues: issue2.issues }, [...path46, ...issue2.path]);
|
|
1578
2281
|
} else {
|
|
1579
|
-
const fullpath = [...
|
|
2282
|
+
const fullpath = [...path46, ...issue2.path];
|
|
1580
2283
|
if (fullpath.length === 0) {
|
|
1581
2284
|
fieldErrors._errors.push(mapper(issue2));
|
|
1582
2285
|
} else {
|
|
@@ -1603,17 +2306,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
|
1603
2306
|
}
|
|
1604
2307
|
function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
1605
2308
|
const result = { errors: [] };
|
|
1606
|
-
const processError = (error52,
|
|
2309
|
+
const processError = (error52, path46 = []) => {
|
|
1607
2310
|
var _a3, _b;
|
|
1608
2311
|
for (const issue2 of error52.issues) {
|
|
1609
2312
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
1610
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
2313
|
+
issue2.errors.map((issues) => processError({ issues }, [...path46, ...issue2.path]));
|
|
1611
2314
|
} else if (issue2.code === "invalid_key") {
|
|
1612
|
-
processError({ issues: issue2.issues }, [...
|
|
2315
|
+
processError({ issues: issue2.issues }, [...path46, ...issue2.path]);
|
|
1613
2316
|
} else if (issue2.code === "invalid_element") {
|
|
1614
|
-
processError({ issues: issue2.issues }, [...
|
|
2317
|
+
processError({ issues: issue2.issues }, [...path46, ...issue2.path]);
|
|
1615
2318
|
} else {
|
|
1616
|
-
const fullpath = [...
|
|
2319
|
+
const fullpath = [...path46, ...issue2.path];
|
|
1617
2320
|
if (fullpath.length === 0) {
|
|
1618
2321
|
result.errors.push(mapper(issue2));
|
|
1619
2322
|
continue;
|
|
@@ -1645,8 +2348,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
|
1645
2348
|
}
|
|
1646
2349
|
function toDotPath(_path) {
|
|
1647
2350
|
const segs = [];
|
|
1648
|
-
const
|
|
1649
|
-
for (const seg of
|
|
2351
|
+
const path46 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
2352
|
+
for (const seg of path46) {
|
|
1650
2353
|
if (typeof seg === "number")
|
|
1651
2354
|
segs.push(`[${seg}]`);
|
|
1652
2355
|
else if (typeof seg === "symbol")
|
|
@@ -1782,7 +2485,7 @@ __export(regexes_exports, {
|
|
|
1782
2485
|
extendedDuration: () => extendedDuration,
|
|
1783
2486
|
guid: () => guid,
|
|
1784
2487
|
hex: () => hex,
|
|
1785
|
-
hostname: () =>
|
|
2488
|
+
hostname: () => hostname3,
|
|
1786
2489
|
html5Email: () => html5Email,
|
|
1787
2490
|
httpProtocol: () => httpProtocol,
|
|
1788
2491
|
idnEmail: () => idnEmail,
|
|
@@ -1860,7 +2563,7 @@ var cidrv4 = /^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-5]
|
|
|
1860
2563
|
var cidrv6 = /^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|::|([0-9a-fA-F]{1,4})?::([0-9a-fA-F]{1,4}:?){0,6})\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/;
|
|
1861
2564
|
var base64 = /^$|^(?:[0-9a-zA-Z+/]{4})*(?:(?:[0-9a-zA-Z+/]{2}==)|(?:[0-9a-zA-Z+/]{3}=))?$/;
|
|
1862
2565
|
var base64url = /^[A-Za-z0-9_-]*$/;
|
|
1863
|
-
var
|
|
2566
|
+
var hostname3 = /^(?=.{1,253}\.?$)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[-0-9a-zA-Z]{0,61}[0-9a-zA-Z])?)*\.?$/;
|
|
1864
2567
|
var domain = /^([a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$/;
|
|
1865
2568
|
var httpProtocol = /^https?$/;
|
|
1866
2569
|
var e164 = /^\+[1-9]\d{6,14}$/;
|
|
@@ -12714,7 +13417,7 @@ __export(schemas_exports2, {
|
|
|
12714
13417
|
guid: () => guid2,
|
|
12715
13418
|
hash: () => hash,
|
|
12716
13419
|
hex: () => hex2,
|
|
12717
|
-
hostname: () =>
|
|
13420
|
+
hostname: () => hostname4,
|
|
12718
13421
|
httpUrl: () => httpUrl,
|
|
12719
13422
|
instanceof: () => _instanceof,
|
|
12720
13423
|
int: () => int,
|
|
@@ -13334,7 +14037,7 @@ var ZodCustomStringFormat = /* @__PURE__ */ $constructor("ZodCustomStringFormat"
|
|
|
13334
14037
|
function stringFormat(format, fnOrRegex, _params = {}) {
|
|
13335
14038
|
return _stringFormat(ZodCustomStringFormat, format, fnOrRegex, _params);
|
|
13336
14039
|
}
|
|
13337
|
-
function
|
|
14040
|
+
function hostname4(_params) {
|
|
13338
14041
|
return _stringFormat(ZodCustomStringFormat, "hostname", regexes_exports.hostname, _params);
|
|
13339
14042
|
}
|
|
13340
14043
|
function hex2(_params) {
|
|
@@ -14310,13 +15013,13 @@ function resolveRef(ref, ctx) {
|
|
|
14310
15013
|
if (!ref.startsWith("#")) {
|
|
14311
15014
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
14312
15015
|
}
|
|
14313
|
-
const
|
|
14314
|
-
if (
|
|
15016
|
+
const path46 = ref.slice(1).split("/").filter(Boolean);
|
|
15017
|
+
if (path46.length === 0) {
|
|
14315
15018
|
return ctx.rootSchema;
|
|
14316
15019
|
}
|
|
14317
15020
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
14318
|
-
if (
|
|
14319
|
-
const key =
|
|
15021
|
+
if (path46[0] === defsKey) {
|
|
15022
|
+
const key = path46[1];
|
|
14320
15023
|
if (!key || !ctx.defs[key]) {
|
|
14321
15024
|
throw new Error(`Reference not found: ${ref}`);
|
|
14322
15025
|
}
|
|
@@ -17627,7 +18330,7 @@ var AcpConnection = class extends BaseConnection {
|
|
|
17627
18330
|
}
|
|
17628
18331
|
/** Claude 계열 브릿지인지 여부를 단일 판별 지점으로 유지합니다. */
|
|
17629
18332
|
isClaudeBackend() {
|
|
17630
|
-
return this.cliType === "claude"
|
|
18333
|
+
return this.cliType === "claude";
|
|
17631
18334
|
}
|
|
17632
18335
|
/** Claude bridge만 native system prompt append를 지원하므로 이 경로만 사용합니다. */
|
|
17633
18336
|
getClaudeSystemPrompt(systemPrompt) {
|
|
@@ -18125,7 +18828,7 @@ function inferBinName(packageName) {
|
|
|
18125
18828
|
// ../../packages/core-unified-agent/models.json
|
|
18126
18829
|
var models_default = {
|
|
18127
18830
|
version: 1,
|
|
18128
|
-
updatedAt: "2026-
|
|
18831
|
+
updatedAt: "2026-07-04T00:00:00Z",
|
|
18129
18832
|
providers: {
|
|
18130
18833
|
claude: {
|
|
18131
18834
|
name: "Claude Code with Anthropic",
|
|
@@ -18140,48 +18843,6 @@ var models_default = {
|
|
|
18140
18843
|
{ modelId: "claude-opus-4-8[1m]", name: "Claude Opus 4.8 [1M]", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max"], default: "high" } }
|
|
18141
18844
|
]
|
|
18142
18845
|
},
|
|
18143
|
-
"claude-zai": {
|
|
18144
|
-
name: "Claude Code with Z.AI GLM",
|
|
18145
|
-
defaultModel: "opus",
|
|
18146
|
-
models: [
|
|
18147
|
-
{ modelId: "haiku", name: "GLM-4.5 Air (Haiku slot)", effort: { supported: false } },
|
|
18148
|
-
{ modelId: "sonnet", name: "GLM-5 Turbo (Sonnet slot)", effort: { supported: false } },
|
|
18149
|
-
{ modelId: "opus", name: "GLM-5.1 (Opus slot)", effort: { supported: false } }
|
|
18150
|
-
],
|
|
18151
|
-
modelsMapping: {
|
|
18152
|
-
haiku: "glm-4.5-air",
|
|
18153
|
-
sonnet: "glm-5-turbo",
|
|
18154
|
-
opus: "glm-5.1"
|
|
18155
|
-
}
|
|
18156
|
-
},
|
|
18157
|
-
"claude-kimi": {
|
|
18158
|
-
name: "Claude Code with Moonshot Kimi",
|
|
18159
|
-
defaultModel: "opus",
|
|
18160
|
-
models: [
|
|
18161
|
-
{ modelId: "haiku", name: "Kimi K2.7 Code (Haiku slot)", effort: { supported: false } },
|
|
18162
|
-
{ modelId: "sonnet", name: "Kimi K2.7 Code (Sonnet slot)", effort: { supported: false } },
|
|
18163
|
-
{ modelId: "opus", name: "Kimi K2.7 Code (Opus slot)", effort: { supported: false } }
|
|
18164
|
-
],
|
|
18165
|
-
modelsMapping: {
|
|
18166
|
-
haiku: "kimi-k2.7-code",
|
|
18167
|
-
sonnet: "kimi-k2.7-code",
|
|
18168
|
-
opus: "kimi-k2.7-code"
|
|
18169
|
-
}
|
|
18170
|
-
},
|
|
18171
|
-
"claude-glm": {
|
|
18172
|
-
name: "Claude Code with ZhipuAI GLM",
|
|
18173
|
-
defaultModel: "opus",
|
|
18174
|
-
models: [
|
|
18175
|
-
{ modelId: "haiku", name: "GLM-4.5-Air (Haiku slot)", effort: { supported: false } },
|
|
18176
|
-
{ modelId: "sonnet", name: "GLM-4.7 (Sonnet slot)", effort: { supported: false } },
|
|
18177
|
-
{ modelId: "opus", name: "GLM-5.1 (Opus slot)", effort: { supported: false } }
|
|
18178
|
-
],
|
|
18179
|
-
modelsMapping: {
|
|
18180
|
-
haiku: "glm-4.5-air",
|
|
18181
|
-
sonnet: "glm-4.7",
|
|
18182
|
-
opus: "glm-5.1"
|
|
18183
|
-
}
|
|
18184
|
-
},
|
|
18185
18846
|
codex: {
|
|
18186
18847
|
name: "OpenAI Codex CLI",
|
|
18187
18848
|
defaultModel: "gpt-5.4",
|
|
@@ -18199,7 +18860,9 @@ var models_default = {
|
|
|
18199
18860
|
{ modelId: "opencode-go/deepseek-v4-pro", name: "DeepSeek V4 Pro", effort: { supported: false } },
|
|
18200
18861
|
{ modelId: "opencode-go/glm-5", name: "GLM-5", effort: { supported: false } },
|
|
18201
18862
|
{ modelId: "opencode-go/glm-5.1", name: "GLM-5.1", effort: { supported: false } },
|
|
18202
|
-
{ modelId: "opencode-go/
|
|
18863
|
+
{ modelId: "opencode-go/glm-5.2", name: "GLM-5.2", effort: { supported: false } },
|
|
18864
|
+
{ modelId: "opencode-go/kimi-k2.6", name: "Kimi K2.6 (3x limits)", effort: { supported: false } },
|
|
18865
|
+
{ modelId: "opencode-go/kimi-k2.7-code", name: "Kimi K2.7 Code", effort: { supported: false } }
|
|
18203
18866
|
]
|
|
18204
18867
|
},
|
|
18205
18868
|
cursor: {
|
|
@@ -18212,9 +18875,9 @@ var models_default = {
|
|
|
18212
18875
|
{ modelId: "gemini-3.1-pro", name: "Gemini 3.1 Pro", effort: { supported: false } },
|
|
18213
18876
|
{ modelId: "gemini-3-flash", name: "Gemini 3 Flash", effort: { supported: false } },
|
|
18214
18877
|
{ modelId: "gemini-3.5-flash", name: "Gemini 3.5 Flash", effort: { supported: false } },
|
|
18215
|
-
{ modelId: "
|
|
18216
|
-
{ modelId: "
|
|
18217
|
-
{ modelId: "claude-4
|
|
18878
|
+
{ modelId: "kimi-k2.7-code", name: "Kimi K2.7 Code", effort: { supported: false } },
|
|
18879
|
+
{ modelId: "glm-5.2", name: "GLM 5.2", spawnModelTemplate: "glm-5.2-{effort}", effort: { supported: true, levels: ["high", "max"], default: "max" } },
|
|
18880
|
+
{ modelId: "claude-opus-4-8-thinking", name: "Claude Opus 4.8 Thinking", spawnModelTemplate: "claude-opus-4-8-thinking-{effort}", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max"], default: "xhigh" } }
|
|
18218
18881
|
]
|
|
18219
18882
|
}
|
|
18220
18883
|
}
|
|
@@ -18385,77 +19048,6 @@ var CLI_BACKENDS = {
|
|
|
18385
19048
|
usesNpxBridge: true,
|
|
18386
19049
|
defaultMaxTokens: 16384
|
|
18387
19050
|
},
|
|
18388
|
-
"claude-zai": {
|
|
18389
|
-
id: "claude-zai",
|
|
18390
|
-
cliCommand: "claude",
|
|
18391
|
-
protocol: "acp",
|
|
18392
|
-
authRequired: true,
|
|
18393
|
-
npxPackage: "@agentclientprotocol/claude-agent-acp@0.33.1",
|
|
18394
|
-
modes: [
|
|
18395
|
-
{ id: "default", label: "Default" },
|
|
18396
|
-
{ id: "plan", label: "Plan" },
|
|
18397
|
-
{ id: "bypassPermissions", label: "YOLO" }
|
|
18398
|
-
],
|
|
18399
|
-
supportsSessionClose: true,
|
|
18400
|
-
supportsSessionLoad: true,
|
|
18401
|
-
requiresModelAtSpawn: false,
|
|
18402
|
-
usesNpxBridge: true,
|
|
18403
|
-
defaultMaxTokens: 16384,
|
|
18404
|
-
defaultEnv: {
|
|
18405
|
-
ANTHROPIC_BASE_URL: "https://api.z.ai/api/anthropic",
|
|
18406
|
-
API_TIMEOUT_MS: "3000000"
|
|
18407
|
-
}
|
|
18408
|
-
},
|
|
18409
|
-
"claude-kimi": {
|
|
18410
|
-
id: "claude-kimi",
|
|
18411
|
-
cliCommand: "claude",
|
|
18412
|
-
protocol: "acp",
|
|
18413
|
-
authRequired: true,
|
|
18414
|
-
npxPackage: "@agentclientprotocol/claude-agent-acp@0.33.1",
|
|
18415
|
-
modes: [
|
|
18416
|
-
{ id: "default", label: "Default" },
|
|
18417
|
-
{ id: "plan", label: "Plan" },
|
|
18418
|
-
{ id: "bypassPermissions", label: "YOLO" }
|
|
18419
|
-
],
|
|
18420
|
-
supportsSessionClose: true,
|
|
18421
|
-
supportsSessionLoad: true,
|
|
18422
|
-
requiresModelAtSpawn: false,
|
|
18423
|
-
usesNpxBridge: true,
|
|
18424
|
-
defaultMaxTokens: 16384,
|
|
18425
|
-
defaultEnv: {
|
|
18426
|
-
ANTHROPIC_BASE_URL: "https://api.kimi.com/coding/",
|
|
18427
|
-
ENABLE_TOOL_SEARCH: "false",
|
|
18428
|
-
ANTHROPIC_MODEL: "kimi-k2.7-code",
|
|
18429
|
-
CLAUDE_CODE_SUBAGENT_MODEL: "kimi-k2.7-code",
|
|
18430
|
-
API_TIMEOUT_MS: "3000000"
|
|
18431
|
-
}
|
|
18432
|
-
},
|
|
18433
|
-
"claude-glm": {
|
|
18434
|
-
id: "claude-glm",
|
|
18435
|
-
cliCommand: "claude",
|
|
18436
|
-
protocol: "acp",
|
|
18437
|
-
authRequired: true,
|
|
18438
|
-
npxPackage: "@agentclientprotocol/claude-agent-acp@0.33.1",
|
|
18439
|
-
modes: [
|
|
18440
|
-
{ id: "default", label: "Default" },
|
|
18441
|
-
{ id: "plan", label: "Plan" },
|
|
18442
|
-
{ id: "bypassPermissions", label: "YOLO" }
|
|
18443
|
-
],
|
|
18444
|
-
supportsSessionClose: true,
|
|
18445
|
-
supportsSessionLoad: true,
|
|
18446
|
-
requiresModelAtSpawn: false,
|
|
18447
|
-
usesNpxBridge: true,
|
|
18448
|
-
defaultMaxTokens: 16384,
|
|
18449
|
-
defaultEnv: {
|
|
18450
|
-
ANTHROPIC_BASE_URL: "https://open.bigmodel.cn/api/anthropic",
|
|
18451
|
-
// ZhipuAI Claude Code 권장 슬롯 매핑 — 직접 launch(Native PTY) 경로에서도
|
|
18452
|
-
// haiku/sonnet/opus 별칭이 GLM 모델로 해석되도록 env로 고정한다.
|
|
18453
|
-
ANTHROPIC_DEFAULT_HAIKU_MODEL: "glm-4.5-air",
|
|
18454
|
-
ANTHROPIC_DEFAULT_SONNET_MODEL: "glm-4.7",
|
|
18455
|
-
ANTHROPIC_DEFAULT_OPUS_MODEL: "glm-5.1",
|
|
18456
|
-
API_TIMEOUT_MS: "3000000"
|
|
18457
|
-
}
|
|
18458
|
-
},
|
|
18459
19051
|
codex: {
|
|
18460
19052
|
id: "codex",
|
|
18461
19053
|
cliCommand: "codex",
|
|
@@ -18550,9 +19142,6 @@ function getBackendConfig(cli) {
|
|
|
18550
19142
|
function getYoloModeId(cli) {
|
|
18551
19143
|
switch (cli) {
|
|
18552
19144
|
case "claude":
|
|
18553
|
-
case "claude-zai":
|
|
18554
|
-
case "claude-kimi":
|
|
18555
|
-
case "claude-glm":
|
|
18556
19145
|
return "bypassPermissions";
|
|
18557
19146
|
case "opencode-go":
|
|
18558
19147
|
return "build";
|
|
@@ -19886,12 +20475,12 @@ var CodexAppServerConnection = class extends BaseConnection {
|
|
|
19886
20475
|
);
|
|
19887
20476
|
}
|
|
19888
20477
|
findRolloutPathForThreadId(threadId) {
|
|
19889
|
-
const codexHome = this.codexHome ?? this.env.CODEX_HOME ??
|
|
20478
|
+
const codexHome = this.codexHome ?? this.env.CODEX_HOME ?? path25.join(this.env.HOME ?? "", ".codex");
|
|
19890
20479
|
if (!codexHome) {
|
|
19891
20480
|
return null;
|
|
19892
20481
|
}
|
|
19893
20482
|
for (const rootName of ["sessions", "archived_sessions"]) {
|
|
19894
|
-
const found = findRolloutPath(
|
|
20483
|
+
const found = findRolloutPath(path25.join(codexHome, rootName), threadId);
|
|
19895
20484
|
if (found) {
|
|
19896
20485
|
return found;
|
|
19897
20486
|
}
|
|
@@ -20002,7 +20591,7 @@ function findRolloutPath(root, threadId) {
|
|
|
20002
20591
|
return null;
|
|
20003
20592
|
}
|
|
20004
20593
|
for (const entry of fs11.readdirSync(root, { withFileTypes: true })) {
|
|
20005
|
-
const entryPath =
|
|
20594
|
+
const entryPath = path25.join(root, entry.name);
|
|
20006
20595
|
if (entry.isDirectory()) {
|
|
20007
20596
|
const found = findRolloutPath(entryPath, threadId);
|
|
20008
20597
|
if (found) {
|
|
@@ -21454,9 +22043,6 @@ var UnifiedAgent = {
|
|
|
21454
22043
|
createClient(cli) {
|
|
21455
22044
|
switch (cli) {
|
|
21456
22045
|
case "claude":
|
|
21457
|
-
case "claude-zai":
|
|
21458
|
-
case "claude-kimi":
|
|
21459
|
-
case "claude-glm":
|
|
21460
22046
|
return new UnifiedClaudeAgentClient(cli);
|
|
21461
22047
|
case "codex":
|
|
21462
22048
|
return new UnifiedCodexAgentClient();
|
|
@@ -21476,7 +22062,7 @@ var UnifiedAgent = {
|
|
|
21476
22062
|
const preferred = await new CliDetector().getPreferred();
|
|
21477
22063
|
if (!preferred) {
|
|
21478
22064
|
throw new Error(
|
|
21479
|
-
"\uC0AC\uC6A9 \uAC00\uB2A5\uD55C CLI\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4. claude,
|
|
22065
|
+
"\uC0AC\uC6A9 \uAC00\uB2A5\uD55C CLI\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4. claude, codex, opencode-go, cursor \uC911 \uD558\uB098\uB97C \uC124\uCE58\uD574\uC8FC\uC138\uC694."
|
|
21480
22066
|
);
|
|
21481
22067
|
}
|
|
21482
22068
|
return this.createClient(preferred.cli);
|
|
@@ -21509,47 +22095,6 @@ var CLI_DISPLAY_NAMES = {
|
|
|
21509
22095
|
};
|
|
21510
22096
|
var CARRIER_JOBS_SELF_CALL_HINT = `When the Admiral passes prior \`job_id\` references in <prior_jobs>, use the \`carrier_jobs\` tool (available via your MCP server) to self-fetch results. Full lookup: \`carrier_jobs(action:"result", format:"full", job_id:"<id>")\`. If archive content has expired (\`full_invalidated\` is true), fall back to \`carrier_jobs(action:"result", format:"summary", job_id:"<id>")\`.`;
|
|
21511
22097
|
|
|
21512
|
-
// ../../packages/fleet-carriers/src/store/index.ts
|
|
21513
|
-
var store_exports = {};
|
|
21514
|
-
__export(store_exports, {
|
|
21515
|
-
applyAgentCliTypeSelectionUpdate: () => applyAgentCliTypeSelectionUpdate,
|
|
21516
|
-
buildHealedCarriers: () => buildHealedCarriers,
|
|
21517
|
-
filterCarrierAgentModesToRegisteredIds: () => filterCarrierAgentModesToRegisteredIds,
|
|
21518
|
-
getAgentCliSelection: () => getAgentCliSelection,
|
|
21519
|
-
getCarriersFilePath: () => getCarriersFilePath,
|
|
21520
|
-
getConfiguredTaskForceBackends: () => getConfiguredTaskForceBackends,
|
|
21521
|
-
getConfiguredTaskForceBackendsFromSnapshot: () => getConfiguredTaskForceBackendsFromSnapshot,
|
|
21522
|
-
getConfiguredTaskForceCarrierIds: () => getConfiguredTaskForceCarrierIds,
|
|
21523
|
-
getConfiguredTaskForceCarrierIdsFromSnapshot: () => getConfiguredTaskForceCarrierIdsFromSnapshot,
|
|
21524
|
-
getEnabledCarrierSubagentIds: () => getEnabledCarrierSubagentIds,
|
|
21525
|
-
getTaskForceModelConfig: () => getTaskForceModelConfig,
|
|
21526
|
-
initStore: () => initStore,
|
|
21527
|
-
isCarrierAgentModeSubagent: () => isCarrierAgentModeSubagent,
|
|
21528
|
-
loadCarrierDisplayNameOverrides: () => loadCarrierDisplayNameOverrides,
|
|
21529
|
-
loadCarrierStates: () => loadCarrierStates,
|
|
21530
|
-
normalizeCarrierDisplayNameInput: () => normalizeCarrierDisplayNameInput,
|
|
21531
|
-
readCarrierAgentModeSnapshot: () => readCarrierAgentModeSnapshot,
|
|
21532
|
-
readCarriersSnapshot: () => readCarriersSnapshot,
|
|
21533
|
-
readFileBackedCarriersSnapshot: () => readFileBackedCarriersSnapshot,
|
|
21534
|
-
readRawCarriers: () => readRawCarriers,
|
|
21535
|
-
readRawCarriersOrDefaultStore: () => readRawCarriersOrDefaultStore,
|
|
21536
|
-
resetCarrierTaskForceConfig: () => resetCarrierTaskForceConfig,
|
|
21537
|
-
resetStoreForTests: () => resetStoreForTests,
|
|
21538
|
-
resetTaskForceModelSelection: () => resetTaskForceModelSelection,
|
|
21539
|
-
resolveAgentCliType: () => resolveAgentCliType,
|
|
21540
|
-
resolveCarrierState: () => resolveCarrierState,
|
|
21541
|
-
sanitizeCarrierDisplayName: () => sanitizeCarrierDisplayName,
|
|
21542
|
-
saveAgentCliSelection: () => saveAgentCliSelection,
|
|
21543
|
-
setCarrierAgentMode: () => setCarrierAgentMode,
|
|
21544
|
-
store: () => store,
|
|
21545
|
-
updateAgentCliSelection: () => updateAgentCliSelection,
|
|
21546
|
-
updateAgentCliTypeOverride: () => updateAgentCliTypeOverride,
|
|
21547
|
-
updateCarrierDisplayName: () => updateCarrierDisplayName,
|
|
21548
|
-
updateCarriers: () => updateCarriers,
|
|
21549
|
-
updateTaskForceModelSelection: () => updateTaskForceModelSelection,
|
|
21550
|
-
withStoreLock: () => withStoreLock
|
|
21551
|
-
});
|
|
21552
|
-
|
|
21553
22098
|
// ../../packages/fleet-carriers/src/store/cli-types.ts
|
|
21554
22099
|
var cli_types_exports = {};
|
|
21555
22100
|
__export(cli_types_exports, {
|
|
@@ -21578,17 +22123,14 @@ function sanitizeFreeformText(value) {
|
|
|
21578
22123
|
if (!trimmed || CONTROL_AND_C1_CHAR_PATTERN.test(trimmed)) return null;
|
|
21579
22124
|
return trimmed;
|
|
21580
22125
|
}
|
|
21581
|
-
function
|
|
22126
|
+
function isRecord2(value) {
|
|
21582
22127
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
21583
22128
|
}
|
|
21584
|
-
function sanitizeAgentMode(value) {
|
|
21585
|
-
return value === "cli" || value === "subagent" ? value : void 0;
|
|
21586
|
-
}
|
|
21587
22129
|
function sanitizeAgentCliType(value) {
|
|
21588
22130
|
return typeof value === "string" && value in CLI_BACKENDS ? value : void 0;
|
|
21589
22131
|
}
|
|
21590
22132
|
function sanitizeAgentCliSelection(value) {
|
|
21591
|
-
if (!
|
|
22133
|
+
if (!isRecord2(value)) return void 0;
|
|
21592
22134
|
const model = sanitizeFreeformText(value.model);
|
|
21593
22135
|
if (!model) return void 0;
|
|
21594
22136
|
const effort = sanitizeFreeformText(value.effort);
|
|
@@ -21610,7 +22152,7 @@ function sanitizeAgentCliSelectionForCliType(cliType, value) {
|
|
|
21610
22152
|
};
|
|
21611
22153
|
}
|
|
21612
22154
|
function sanitizeAgentCli(value) {
|
|
21613
|
-
if (!
|
|
22155
|
+
if (!isRecord2(value)) return {};
|
|
21614
22156
|
const result = /* @__PURE__ */ Object.create(null);
|
|
21615
22157
|
for (const [cliType, selection] of Object.entries(value)) {
|
|
21616
22158
|
const sanitizedCliType = sanitizeAgentCliType(cliType);
|
|
@@ -21620,7 +22162,7 @@ function sanitizeAgentCli(value) {
|
|
|
21620
22162
|
return result;
|
|
21621
22163
|
}
|
|
21622
22164
|
function sanitizeTaskforce(value) {
|
|
21623
|
-
if (!
|
|
22165
|
+
if (!isRecord2(value)) return {};
|
|
21624
22166
|
const result = /* @__PURE__ */ Object.create(null);
|
|
21625
22167
|
for (const [cliType, selection] of Object.entries(value)) {
|
|
21626
22168
|
const sanitizedCliType = sanitizeAgentCliType(cliType);
|
|
@@ -21632,14 +22174,12 @@ function sanitizeTaskforce(value) {
|
|
|
21632
22174
|
return result;
|
|
21633
22175
|
}
|
|
21634
22176
|
function sanitizeCarrierState(value) {
|
|
21635
|
-
if (!
|
|
21636
|
-
const agentMode = sanitizeAgentMode(value.agentMode);
|
|
22177
|
+
if (!isRecord2(value)) return void 0;
|
|
21637
22178
|
const agentCliType = sanitizeAgentCliType(value.agentCliType);
|
|
21638
22179
|
const agentCli = sanitizeAgentCli(value.agentCli);
|
|
21639
22180
|
const taskforce = sanitizeTaskforce(value.taskforce);
|
|
21640
22181
|
const displayName = sanitizeFreeformText(value.displayName);
|
|
21641
22182
|
const result = {};
|
|
21642
|
-
if (agentMode) result.agentMode = agentMode;
|
|
21643
22183
|
if (agentCliType) result.agentCliType = agentCliType;
|
|
21644
22184
|
if (Object.keys(agentCli).length > 0) result.agentCli = agentCli;
|
|
21645
22185
|
if (Object.keys(taskforce).length > 0) result.taskforce = taskforce;
|
|
@@ -21647,7 +22187,7 @@ function sanitizeCarrierState(value) {
|
|
|
21647
22187
|
return Object.keys(result).length > 0 ? result : {};
|
|
21648
22188
|
}
|
|
21649
22189
|
function sanitizeCarriersMap(value) {
|
|
21650
|
-
if (!
|
|
22190
|
+
if (!isRecord2(value)) return {};
|
|
21651
22191
|
const result = /* @__PURE__ */ Object.create(null);
|
|
21652
22192
|
for (const [carrierId, state] of Object.entries(value)) {
|
|
21653
22193
|
const sanitizedCarrierId = sanitizeConfigKey(carrierId);
|
|
@@ -21836,7 +22376,7 @@ function resolvePathBinary(command2, env, options = {}) {
|
|
|
21836
22376
|
return resolved ? wrapWindowsShim(resolved, env, platform) : void 0;
|
|
21837
22377
|
}
|
|
21838
22378
|
function wrapWindowsShim(resolved, env, platform) {
|
|
21839
|
-
if (platform !== "win32" || !WINDOWS_SHIM_EXTENSIONS.has(
|
|
22379
|
+
if (platform !== "win32" || !WINDOWS_SHIM_EXTENSIONS.has(path25__default.extname(resolved).toLowerCase())) {
|
|
21840
22380
|
return { bin: resolved, prefixArgs: [] };
|
|
21841
22381
|
}
|
|
21842
22382
|
rejectCmdExpansionSensitiveShim(resolved);
|
|
@@ -21854,13 +22394,13 @@ function forceWindowsArgQuoting(value) {
|
|
|
21854
22394
|
return `${value} `;
|
|
21855
22395
|
}
|
|
21856
22396
|
function findOnPath(bin, pathValue, pathExts, platform) {
|
|
21857
|
-
const pathSeparator = platform === "win32" ? WINDOWS_PATH_SEPARATOR :
|
|
21858
|
-
if (hasPathSeparator(bin, platform) ||
|
|
22397
|
+
const pathSeparator = platform === "win32" ? WINDOWS_PATH_SEPARATOR : path25__default.delimiter;
|
|
22398
|
+
if (hasPathSeparator(bin, platform) || path25__default.isAbsolute(bin)) {
|
|
21859
22399
|
return resolveWithExtensions(bin, pathExts, platform);
|
|
21860
22400
|
}
|
|
21861
22401
|
for (const entry of pathValue.split(pathSeparator)) {
|
|
21862
22402
|
const searchDir = entry.length === 0 ? "." : entry;
|
|
21863
|
-
const candidate = resolveWithExtensions(
|
|
22403
|
+
const candidate = resolveWithExtensions(path25__default.join(searchDir, bin), pathExts, platform);
|
|
21864
22404
|
if (candidate) {
|
|
21865
22405
|
return candidate;
|
|
21866
22406
|
}
|
|
@@ -21868,7 +22408,7 @@ function findOnPath(bin, pathValue, pathExts, platform) {
|
|
|
21868
22408
|
return void 0;
|
|
21869
22409
|
}
|
|
21870
22410
|
function resolveWithExtensions(candidate, pathExts, platform) {
|
|
21871
|
-
if (platform !== "win32" ||
|
|
22411
|
+
if (platform !== "win32" || path25__default.extname(candidate).length > 0) {
|
|
21872
22412
|
return existsSync(candidate) ? candidate : void 0;
|
|
21873
22413
|
}
|
|
21874
22414
|
for (const ext of pathExts) {
|
|
@@ -22933,7 +23473,7 @@ function formatInstallCommand(packageNames, command2, versionOrChannel) {
|
|
|
22933
23473
|
return `${command2} i -g ${packageNames.map((name) => `${name}@${versionOrChannel}`).join(" ")}`;
|
|
22934
23474
|
}
|
|
22935
23475
|
function isPathInside(deps, child, parent) {
|
|
22936
|
-
const separator = deps.platform === "win32" ? "\\" :
|
|
23476
|
+
const separator = deps.platform === "win32" ? "\\" : path25__default.sep;
|
|
22937
23477
|
return child === parent || child.startsWith(`${parent}${separator}`);
|
|
22938
23478
|
}
|
|
22939
23479
|
function normalizeExistingPath(deps, value) {
|
|
@@ -22948,10 +23488,10 @@ function normalizePath(deps, value) {
|
|
|
22948
23488
|
return deps.platform === "win32" ? resolved.toLowerCase() : resolved;
|
|
22949
23489
|
}
|
|
22950
23490
|
function resolvePathForPlatform(platform, value) {
|
|
22951
|
-
return platform === "win32" ?
|
|
23491
|
+
return platform === "win32" ? path25__default.win32.resolve(value) : path25__default.resolve(value);
|
|
22952
23492
|
}
|
|
22953
23493
|
function joinPathForPlatform(platform, ...parts) {
|
|
22954
|
-
return platform === "win32" ?
|
|
23494
|
+
return platform === "win32" ? path25__default.win32.join(...parts) : path25__default.join(...parts);
|
|
22955
23495
|
}
|
|
22956
23496
|
function defaultExecFile(file2, args) {
|
|
22957
23497
|
return execFileSync(file2, args, { encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] });
|
|
@@ -23031,350 +23571,6 @@ __export(state_io_exports, {
|
|
|
23031
23571
|
updateCarriers: () => updateCarriers,
|
|
23032
23572
|
withStoreLock: () => withStoreLock
|
|
23033
23573
|
});
|
|
23034
|
-
var SECURE_DIR_MODE = 448;
|
|
23035
|
-
var SECURE_FILE_MODE = 384;
|
|
23036
|
-
var NOFOLLOW_FLAG = fs11.constants.O_NOFOLLOW ?? 0;
|
|
23037
|
-
function safeLstat(targetPath) {
|
|
23038
|
-
try {
|
|
23039
|
-
return fs11.lstatSync(targetPath);
|
|
23040
|
-
} catch (error51) {
|
|
23041
|
-
if (error51.code === "ENOENT") {
|
|
23042
|
-
return null;
|
|
23043
|
-
}
|
|
23044
|
-
throw error51;
|
|
23045
|
-
}
|
|
23046
|
-
}
|
|
23047
|
-
function ensureSafeDirectory(dirPath) {
|
|
23048
|
-
const stat5 = safeLstat(dirPath);
|
|
23049
|
-
if (stat5) {
|
|
23050
|
-
if (!stat5.isDirectory() || stat5.isSymbolicLink()) {
|
|
23051
|
-
throw new Error(`Unsafe Fleet directory: ${dirPath}`);
|
|
23052
|
-
}
|
|
23053
|
-
fs11.chmodSync(dirPath, SECURE_DIR_MODE);
|
|
23054
|
-
return;
|
|
23055
|
-
}
|
|
23056
|
-
fs11.mkdirSync(dirPath, { recursive: true, mode: SECURE_DIR_MODE });
|
|
23057
|
-
const created = safeLstat(dirPath);
|
|
23058
|
-
if (!created?.isDirectory() || created.isSymbolicLink()) {
|
|
23059
|
-
throw new Error(`Unsafe Fleet directory: ${dirPath}`);
|
|
23060
|
-
}
|
|
23061
|
-
fs11.chmodSync(dirPath, SECURE_DIR_MODE);
|
|
23062
|
-
}
|
|
23063
|
-
|
|
23064
|
-
// ../../packages/fleet-infra/src/fs-store/atomic-write.ts
|
|
23065
|
-
var DEFAULT_MAX_ATTEMPTS = 10;
|
|
23066
|
-
var IGNORED_FSYNC_ERROR_CODES = /* @__PURE__ */ new Set(["EPERM", "EINVAL", "ENOSYS"]);
|
|
23067
|
-
function buildTempPath(filePath) {
|
|
23068
|
-
const suffix = `${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}.${os3.hostname()}`;
|
|
23069
|
-
return `${filePath}.${suffix}.tmp`;
|
|
23070
|
-
}
|
|
23071
|
-
function writeAtomicSync(filePath, content, options = {}) {
|
|
23072
|
-
const mode = options.mode ?? SECURE_FILE_MODE;
|
|
23073
|
-
const doFsync = options.fsync !== false;
|
|
23074
|
-
const maxAttempts = options.maxAttempts ?? DEFAULT_MAX_ATTEMPTS;
|
|
23075
|
-
let lastExistsError;
|
|
23076
|
-
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
23077
|
-
const tempPath = buildTempPath(filePath);
|
|
23078
|
-
let tempCreated = false;
|
|
23079
|
-
try {
|
|
23080
|
-
fs11.writeFileSync(tempPath, content, { encoding: "utf-8", flag: "wx", mode });
|
|
23081
|
-
tempCreated = true;
|
|
23082
|
-
if (doFsync) {
|
|
23083
|
-
const fd = fs11.openSync(tempPath, "r");
|
|
23084
|
-
try {
|
|
23085
|
-
fsyncSyncBestEffort(fd);
|
|
23086
|
-
} finally {
|
|
23087
|
-
fs11.closeSync(fd);
|
|
23088
|
-
}
|
|
23089
|
-
}
|
|
23090
|
-
fs11.renameSync(tempPath, filePath);
|
|
23091
|
-
return;
|
|
23092
|
-
} catch (error51) {
|
|
23093
|
-
const code = error51.code;
|
|
23094
|
-
if (!tempCreated && code === "EEXIST") {
|
|
23095
|
-
lastExistsError = error51;
|
|
23096
|
-
continue;
|
|
23097
|
-
}
|
|
23098
|
-
if (tempCreated) {
|
|
23099
|
-
try {
|
|
23100
|
-
fs11.unlinkSync(tempPath);
|
|
23101
|
-
} catch {
|
|
23102
|
-
}
|
|
23103
|
-
}
|
|
23104
|
-
throw error51;
|
|
23105
|
-
}
|
|
23106
|
-
}
|
|
23107
|
-
throw lastExistsError ?? new Error(`Failed to create temp file after ${maxAttempts} attempts: ${filePath}`);
|
|
23108
|
-
}
|
|
23109
|
-
function cleanupTempFiles(dir, prefix, minAgeMs, now) {
|
|
23110
|
-
let entries;
|
|
23111
|
-
try {
|
|
23112
|
-
entries = fs11.readdirSync(dir);
|
|
23113
|
-
} catch {
|
|
23114
|
-
return;
|
|
23115
|
-
}
|
|
23116
|
-
for (const entry of entries) {
|
|
23117
|
-
if (!entry.startsWith(prefix)) {
|
|
23118
|
-
continue;
|
|
23119
|
-
}
|
|
23120
|
-
const tempPath = path26.join(dir, entry);
|
|
23121
|
-
try {
|
|
23122
|
-
const stat5 = fs11.lstatSync(tempPath);
|
|
23123
|
-
if (stat5?.isFile() && !stat5.isSymbolicLink() && now - stat5.mtimeMs >= minAgeMs) {
|
|
23124
|
-
fs11.unlinkSync(tempPath);
|
|
23125
|
-
}
|
|
23126
|
-
} catch {
|
|
23127
|
-
}
|
|
23128
|
-
}
|
|
23129
|
-
}
|
|
23130
|
-
function isIgnoredFsyncError(error51) {
|
|
23131
|
-
const code = error51.code;
|
|
23132
|
-
return typeof code === "string" && IGNORED_FSYNC_ERROR_CODES.has(code);
|
|
23133
|
-
}
|
|
23134
|
-
function fsyncSyncBestEffort(fd) {
|
|
23135
|
-
try {
|
|
23136
|
-
fs11.fsyncSync(fd);
|
|
23137
|
-
} catch (error51) {
|
|
23138
|
-
if (!isIgnoredFsyncError(error51)) {
|
|
23139
|
-
throw error51;
|
|
23140
|
-
}
|
|
23141
|
-
}
|
|
23142
|
-
}
|
|
23143
|
-
var DEFAULT_LOCK_TIMEOUT_MS = 5e3;
|
|
23144
|
-
var DEFAULT_STALE_LOCK_MS = 3e4;
|
|
23145
|
-
var DEFAULT_RETRY_MS = 25;
|
|
23146
|
-
var DEFAULT_OWNER_FILE_NAME = "owner.json";
|
|
23147
|
-
function withDirectoryLock(deps, operation) {
|
|
23148
|
-
const ownerFileName = deps.ownerFileName ?? DEFAULT_OWNER_FILE_NAME;
|
|
23149
|
-
const timeoutMs = deps.timeoutMs ?? DEFAULT_LOCK_TIMEOUT_MS;
|
|
23150
|
-
const staleLockMs = deps.staleLockMs ?? DEFAULT_STALE_LOCK_MS;
|
|
23151
|
-
const retryMs = deps.retryMs ?? DEFAULT_RETRY_MS;
|
|
23152
|
-
const now = deps.now ?? (() => Date.now());
|
|
23153
|
-
const startedAt = now();
|
|
23154
|
-
while (true) {
|
|
23155
|
-
try {
|
|
23156
|
-
fs11.mkdirSync(deps.lockDir, { mode: 448 });
|
|
23157
|
-
writeLockOwner(deps.lockDir, ownerFileName, now());
|
|
23158
|
-
try {
|
|
23159
|
-
return operation();
|
|
23160
|
-
} finally {
|
|
23161
|
-
releaseLock(deps.lockDir);
|
|
23162
|
-
}
|
|
23163
|
-
} catch (error51) {
|
|
23164
|
-
const code = error51.code;
|
|
23165
|
-
if (code !== "EEXIST") throw error51;
|
|
23166
|
-
recoverStaleLock(deps.lockDir, ownerFileName, now, staleLockMs);
|
|
23167
|
-
if (now() - startedAt >= timeoutMs) {
|
|
23168
|
-
throw new Error(`Timed out waiting for Fleet directory lock: ${deps.lockDir}`);
|
|
23169
|
-
}
|
|
23170
|
-
sleepSync(retryMs);
|
|
23171
|
-
}
|
|
23172
|
-
}
|
|
23173
|
-
}
|
|
23174
|
-
function releaseLock(lockDir) {
|
|
23175
|
-
try {
|
|
23176
|
-
fs11.rmSync(lockDir, { recursive: true, force: true });
|
|
23177
|
-
} catch {
|
|
23178
|
-
}
|
|
23179
|
-
}
|
|
23180
|
-
function recoverStaleLock(lockDir, ownerFileName, now, staleLockMs) {
|
|
23181
|
-
try {
|
|
23182
|
-
const initialSnapshot = readLockSnapshot(lockDir, ownerFileName);
|
|
23183
|
-
if (!isRecoverableSnapshot(initialSnapshot, now, staleLockMs)) return;
|
|
23184
|
-
const quarantineDir = buildQuarantinePath(lockDir);
|
|
23185
|
-
try {
|
|
23186
|
-
fs11.renameSync(lockDir, quarantineDir);
|
|
23187
|
-
} catch {
|
|
23188
|
-
return;
|
|
23189
|
-
}
|
|
23190
|
-
try {
|
|
23191
|
-
const quarantinedSnapshot = readLockSnapshot(quarantineDir, ownerFileName);
|
|
23192
|
-
if (sameLockSnapshot(initialSnapshot, quarantinedSnapshot) && isRecoverableSnapshot(quarantinedSnapshot, now, staleLockMs)) {
|
|
23193
|
-
fs11.rmSync(quarantineDir, { recursive: true, force: true });
|
|
23194
|
-
} else {
|
|
23195
|
-
restoreQuarantinedLock(quarantineDir, lockDir);
|
|
23196
|
-
}
|
|
23197
|
-
} catch (error51) {
|
|
23198
|
-
const code = error51.code;
|
|
23199
|
-
if (code !== "ENOENT") throw error51;
|
|
23200
|
-
}
|
|
23201
|
-
} catch (error51) {
|
|
23202
|
-
const code = error51.code;
|
|
23203
|
-
if (code !== "ENOENT") throw error51;
|
|
23204
|
-
}
|
|
23205
|
-
}
|
|
23206
|
-
function readLockSnapshot(lockDir, ownerFileName) {
|
|
23207
|
-
const stat5 = fs11.lstatSync(lockDir);
|
|
23208
|
-
if (stat5.isSymbolicLink()) {
|
|
23209
|
-
return { owner: null, mtimeMs: 0 };
|
|
23210
|
-
}
|
|
23211
|
-
return {
|
|
23212
|
-
owner: readLockOwner(lockDir, ownerFileName),
|
|
23213
|
-
mtimeMs: stat5.mtimeMs
|
|
23214
|
-
};
|
|
23215
|
-
}
|
|
23216
|
-
function buildQuarantinePath(lockDir) {
|
|
23217
|
-
const suffix = `${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}`;
|
|
23218
|
-
return `${lockDir}.stale.${suffix}`;
|
|
23219
|
-
}
|
|
23220
|
-
function writeLockOwner(lockDir, ownerFileName, startedAt) {
|
|
23221
|
-
const owner = {
|
|
23222
|
-
pid: process.pid,
|
|
23223
|
-
hostname: os3.hostname(),
|
|
23224
|
-
startedAt
|
|
23225
|
-
};
|
|
23226
|
-
const ownerPath = path26.join(lockDir, ownerFileName);
|
|
23227
|
-
try {
|
|
23228
|
-
fs11.writeFileSync(ownerPath, JSON.stringify(owner), { encoding: "utf-8", mode: 384 });
|
|
23229
|
-
} catch (error51) {
|
|
23230
|
-
releaseLock(lockDir);
|
|
23231
|
-
throw error51;
|
|
23232
|
-
}
|
|
23233
|
-
}
|
|
23234
|
-
function readLockOwner(lockDir, ownerFileName) {
|
|
23235
|
-
const ownerPath = path26.join(lockDir, ownerFileName);
|
|
23236
|
-
try {
|
|
23237
|
-
return sanitizeLockOwner(JSON.parse(fs11.readFileSync(ownerPath, "utf-8")));
|
|
23238
|
-
} catch (error51) {
|
|
23239
|
-
const code = error51.code;
|
|
23240
|
-
if (code === "ENOENT") return null;
|
|
23241
|
-
throw error51;
|
|
23242
|
-
}
|
|
23243
|
-
}
|
|
23244
|
-
function isRecoverableOwner(owner, now, staleLockMs) {
|
|
23245
|
-
if (owner.hostname !== os3.hostname()) return false;
|
|
23246
|
-
if (now() - owner.startedAt < staleLockMs) return false;
|
|
23247
|
-
return !isProcessAlive(owner.pid);
|
|
23248
|
-
}
|
|
23249
|
-
function isRecoverableSnapshot(snapshot, now, staleLockMs) {
|
|
23250
|
-
if (snapshot.owner) return isRecoverableOwner(snapshot.owner, now, staleLockMs);
|
|
23251
|
-
return now() - snapshot.mtimeMs >= staleLockMs;
|
|
23252
|
-
}
|
|
23253
|
-
function sameLockSnapshot(a, b) {
|
|
23254
|
-
if (!a.owner || !b.owner) return !a.owner && !b.owner && a.mtimeMs === b.mtimeMs;
|
|
23255
|
-
return a.owner.pid === b.owner.pid && a.owner.hostname === b.owner.hostname && a.owner.startedAt === b.owner.startedAt;
|
|
23256
|
-
}
|
|
23257
|
-
function restoreQuarantinedLock(quarantineDir, lockDir) {
|
|
23258
|
-
try {
|
|
23259
|
-
fs11.renameSync(quarantineDir, lockDir);
|
|
23260
|
-
} catch {
|
|
23261
|
-
}
|
|
23262
|
-
}
|
|
23263
|
-
function isProcessAlive(pid) {
|
|
23264
|
-
try {
|
|
23265
|
-
process.kill(pid, 0);
|
|
23266
|
-
return true;
|
|
23267
|
-
} catch (error51) {
|
|
23268
|
-
const code = error51.code;
|
|
23269
|
-
if (code === "ESRCH") return false;
|
|
23270
|
-
return true;
|
|
23271
|
-
}
|
|
23272
|
-
}
|
|
23273
|
-
function sanitizeLockOwner(value) {
|
|
23274
|
-
if (typeof value !== "object" || value === null || Array.isArray(value)) return null;
|
|
23275
|
-
const record2 = value;
|
|
23276
|
-
const pid = record2.pid;
|
|
23277
|
-
const hostname5 = record2.hostname;
|
|
23278
|
-
const startedAt = record2.startedAt;
|
|
23279
|
-
if (!Number.isInteger(pid) || pid <= 0) return null;
|
|
23280
|
-
if (typeof hostname5 !== "string" || !hostname5) return null;
|
|
23281
|
-
if (!Number.isFinite(startedAt) || startedAt <= 0) return null;
|
|
23282
|
-
return {
|
|
23283
|
-
pid,
|
|
23284
|
-
hostname: hostname5,
|
|
23285
|
-
startedAt
|
|
23286
|
-
};
|
|
23287
|
-
}
|
|
23288
|
-
function sleepSync(ms) {
|
|
23289
|
-
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
|
|
23290
|
-
}
|
|
23291
|
-
|
|
23292
|
-
// ../../packages/fleet-infra/src/fs-store/json-store.ts
|
|
23293
|
-
var DEFAULT_TEMP_FILE_MIN_AGE_MS = 6e4;
|
|
23294
|
-
function createDurableJsonStore(deps) {
|
|
23295
|
-
const now = deps.now ?? (() => Date.now());
|
|
23296
|
-
const sensitivity = deps.sensitivity;
|
|
23297
|
-
const mode = sensitivity === "sensitive" ? SECURE_FILE_MODE : 420;
|
|
23298
|
-
const minAgeMs = deps.tempCleanupMinAgeMs ?? DEFAULT_TEMP_FILE_MIN_AGE_MS;
|
|
23299
|
-
const dir = path26.dirname(deps.filePath);
|
|
23300
|
-
return {
|
|
23301
|
-
path: deps.filePath,
|
|
23302
|
-
load() {
|
|
23303
|
-
return readJsonFile(deps.filePath, deps.sanitize);
|
|
23304
|
-
},
|
|
23305
|
-
save(data) {
|
|
23306
|
-
withLock(() => {
|
|
23307
|
-
writeAtomicSync(deps.filePath, `${JSON.stringify(data, null, 2)}
|
|
23308
|
-
`, { mode });
|
|
23309
|
-
});
|
|
23310
|
-
},
|
|
23311
|
-
update(mutate) {
|
|
23312
|
-
let result;
|
|
23313
|
-
withLock(() => {
|
|
23314
|
-
const current = readJsonFile(deps.filePath, deps.sanitize);
|
|
23315
|
-
const next = mutate(current);
|
|
23316
|
-
writeAtomicSync(deps.filePath, `${JSON.stringify(next, null, 2)}
|
|
23317
|
-
`, { mode });
|
|
23318
|
-
result = next;
|
|
23319
|
-
});
|
|
23320
|
-
return result;
|
|
23321
|
-
}
|
|
23322
|
-
};
|
|
23323
|
-
function withLock(operation) {
|
|
23324
|
-
if (!deps.lockDir) {
|
|
23325
|
-
ensureSafeDirectoryIfSensitive(dir, sensitivity);
|
|
23326
|
-
return operation();
|
|
23327
|
-
}
|
|
23328
|
-
ensureSafeDirectoryIfSensitive(dir, sensitivity);
|
|
23329
|
-
return withDirectoryLock(
|
|
23330
|
-
{
|
|
23331
|
-
lockDir: deps.lockDir,
|
|
23332
|
-
ownerFileName: deps.lockOwnerFileName,
|
|
23333
|
-
timeoutMs: deps.timeoutMs,
|
|
23334
|
-
staleLockMs: deps.staleLockMs,
|
|
23335
|
-
now
|
|
23336
|
-
},
|
|
23337
|
-
() => {
|
|
23338
|
-
if (deps.tempCleanupPrefix) {
|
|
23339
|
-
cleanupTempFiles(dir, deps.tempCleanupPrefix, minAgeMs, now());
|
|
23340
|
-
}
|
|
23341
|
-
return operation();
|
|
23342
|
-
}
|
|
23343
|
-
);
|
|
23344
|
-
}
|
|
23345
|
-
}
|
|
23346
|
-
function readJsonFile(filePath, sanitize) {
|
|
23347
|
-
let fd;
|
|
23348
|
-
try {
|
|
23349
|
-
const stat5 = fs11.lstatSync(filePath);
|
|
23350
|
-
if (!stat5 || !stat5.isFile() || stat5.isSymbolicLink()) {
|
|
23351
|
-
return sanitize(void 0);
|
|
23352
|
-
}
|
|
23353
|
-
fd = fs11.openSync(filePath, fs11.constants.O_RDONLY | NOFOLLOW_FLAG);
|
|
23354
|
-
if (!fs11.fstatSync(fd).isFile()) {
|
|
23355
|
-
return sanitize(void 0);
|
|
23356
|
-
}
|
|
23357
|
-
return sanitize(JSON.parse(fs11.readFileSync(fd, "utf-8")));
|
|
23358
|
-
} catch {
|
|
23359
|
-
return sanitize(void 0);
|
|
23360
|
-
} finally {
|
|
23361
|
-
if (fd !== void 0) {
|
|
23362
|
-
try {
|
|
23363
|
-
fs11.closeSync(fd);
|
|
23364
|
-
} catch {
|
|
23365
|
-
}
|
|
23366
|
-
}
|
|
23367
|
-
}
|
|
23368
|
-
}
|
|
23369
|
-
function ensureSafeDirectoryIfSensitive(dir, sensitivity) {
|
|
23370
|
-
if (sensitivity === "sensitive") {
|
|
23371
|
-
ensureSafeDirectory(dir);
|
|
23372
|
-
} else {
|
|
23373
|
-
fs11.mkdirSync(dir, { recursive: true });
|
|
23374
|
-
}
|
|
23375
|
-
}
|
|
23376
|
-
|
|
23377
|
-
// ../../packages/fleet-carriers/src/store/state-io.ts
|
|
23378
23574
|
var FILENAME = "carriers.json";
|
|
23379
23575
|
var DEFAULT_STORE_DIRNAME = ".fleet";
|
|
23380
23576
|
var STALE_SUBAGENT_MODE_FILENAME = "carrier-subagent.json";
|
|
@@ -23405,7 +23601,7 @@ function readRawCarriersOrDefaultStore() {
|
|
|
23405
23601
|
}
|
|
23406
23602
|
function getCarriersFilePath() {
|
|
23407
23603
|
if (!runtimeState.storeDir) return null;
|
|
23408
|
-
return
|
|
23604
|
+
return path25.join(runtimeState.storeDir, FILENAME);
|
|
23409
23605
|
}
|
|
23410
23606
|
function updateCarriers(mutator) {
|
|
23411
23607
|
if (!runtimeState.storeDir) return;
|
|
@@ -23420,7 +23616,7 @@ function updateCarriers(mutator) {
|
|
|
23420
23616
|
function withStoreLock(operation) {
|
|
23421
23617
|
if (!runtimeState.storeDir) return operation();
|
|
23422
23618
|
fs11.mkdirSync(runtimeState.storeDir, { recursive: true });
|
|
23423
|
-
const lockDir =
|
|
23619
|
+
const lockDir = path25.join(runtimeState.storeDir, LOCK_DIRNAME);
|
|
23424
23620
|
return withDirectoryLock(
|
|
23425
23621
|
{ lockDir, ownerFileName: LOCK_OWNER_FILENAME },
|
|
23426
23622
|
operation
|
|
@@ -23431,10 +23627,10 @@ function readCarriers() {
|
|
|
23431
23627
|
return readCarriersFromDir(runtimeState.storeDir);
|
|
23432
23628
|
}
|
|
23433
23629
|
function resolveDefaultStoreDir() {
|
|
23434
|
-
return
|
|
23630
|
+
return path25.join(os4.homedir(), DEFAULT_STORE_DIRNAME);
|
|
23435
23631
|
}
|
|
23436
23632
|
function readCarriersFromDir(dir) {
|
|
23437
|
-
const filePath =
|
|
23633
|
+
const filePath = path25.join(dir, FILENAME);
|
|
23438
23634
|
let fd;
|
|
23439
23635
|
try {
|
|
23440
23636
|
const stat5 = fs11.lstatSync(filePath);
|
|
@@ -23464,7 +23660,7 @@ function recordLastLocalWriteFingerprint(filePath, generation) {
|
|
|
23464
23660
|
function writeCarriers(s) {
|
|
23465
23661
|
if (!runtimeState.storeDir) throw new Error("Fleet store is not initialized.");
|
|
23466
23662
|
fs11.mkdirSync(runtimeState.storeDir, { recursive: true });
|
|
23467
|
-
const filePath =
|
|
23663
|
+
const filePath = path25.join(runtimeState.storeDir, FILENAME);
|
|
23468
23664
|
const next = serializeFleetCarriers(s);
|
|
23469
23665
|
writeAtomicSync(filePath, `${JSON.stringify(next, null, 2)}
|
|
23470
23666
|
`, { fsync: false, mode: 420 });
|
|
@@ -23489,7 +23685,7 @@ function sanitizeFleetCarriers(value) {
|
|
|
23489
23685
|
}
|
|
23490
23686
|
function unlinkStaleSubagentModeFile(dir) {
|
|
23491
23687
|
try {
|
|
23492
|
-
fs11.unlinkSync(
|
|
23688
|
+
fs11.unlinkSync(path25.join(dir, STALE_SUBAGENT_MODE_FILENAME));
|
|
23493
23689
|
} catch {
|
|
23494
23690
|
}
|
|
23495
23691
|
}
|
|
@@ -23691,7 +23887,6 @@ function resolveCarriersRecord(raw, defaultsByCarrier, resolve2) {
|
|
|
23691
23887
|
function buildResolvedCarrierState(state, defaults, agentCliType, taskforce) {
|
|
23692
23888
|
const agentCli = sanitizeAgentCli(state.agentCli);
|
|
23693
23889
|
return {
|
|
23694
|
-
agentMode: state.agentMode ?? defaults?.defaultAgentMode ?? "cli",
|
|
23695
23890
|
agentCliType,
|
|
23696
23891
|
agentCli: {
|
|
23697
23892
|
...agentCli,
|
|
@@ -23717,57 +23912,6 @@ function resolveSelectionForCliType(stored, cliType, defaults) {
|
|
|
23717
23912
|
return { model, effort };
|
|
23718
23913
|
}
|
|
23719
23914
|
|
|
23720
|
-
// ../../packages/fleet-carriers/src/store/subagent-mode.ts
|
|
23721
|
-
var subagent_mode_exports = {};
|
|
23722
|
-
__export(subagent_mode_exports, {
|
|
23723
|
-
filterCarrierAgentModesToRegisteredIds: () => filterCarrierAgentModesToRegisteredIds,
|
|
23724
|
-
getEnabledCarrierSubagentIds: () => getEnabledCarrierSubagentIds,
|
|
23725
|
-
isCarrierAgentModeSubagent: () => isCarrierAgentModeSubagent,
|
|
23726
|
-
readCarrierAgentModeSnapshot: () => readCarrierAgentModeSnapshot,
|
|
23727
|
-
setCarrierAgentMode: () => setCarrierAgentMode
|
|
23728
|
-
});
|
|
23729
|
-
function readCarrierAgentModeSnapshot(defaultsByCarrier = {}) {
|
|
23730
|
-
const raw = readRawCarriers();
|
|
23731
|
-
const carriers = buildHealedCarriers(defaultsByCarrier);
|
|
23732
|
-
return {
|
|
23733
|
-
agentModes: Object.fromEntries(
|
|
23734
|
-
Object.entries(carriers).filter(([, state]) => state.agentMode === "subagent").map(([id]) => [id, "subagent"])
|
|
23735
|
-
),
|
|
23736
|
-
generation: raw._meta?.generation ?? 0
|
|
23737
|
-
};
|
|
23738
|
-
}
|
|
23739
|
-
function isCarrierAgentModeSubagent(carrierId, defaultAgentMode = "cli") {
|
|
23740
|
-
const rawMode = readRawCarriers().carriers?.[carrierId]?.agentMode;
|
|
23741
|
-
return (rawMode ?? defaultAgentMode) === "subagent";
|
|
23742
|
-
}
|
|
23743
|
-
function setCarrierAgentMode(carrierId, enabled, defaultAgentMode = "cli") {
|
|
23744
|
-
const sanitizedCarrierId = sanitizeConfigKey(carrierId);
|
|
23745
|
-
if (!sanitizedCarrierId) return;
|
|
23746
|
-
const nextAgentMode = enabled ? "subagent" : "cli";
|
|
23747
|
-
updateCarriers((states) => {
|
|
23748
|
-
const carriers = { ...states.carriers ?? {} };
|
|
23749
|
-
const current = carriers[sanitizedCarrierId] ?? {};
|
|
23750
|
-
const next = { ...current };
|
|
23751
|
-
if (nextAgentMode === defaultAgentMode) delete next.agentMode;
|
|
23752
|
-
else next.agentMode = nextAgentMode;
|
|
23753
|
-
carriers[sanitizedCarrierId] = next;
|
|
23754
|
-
states.carriers = carriers;
|
|
23755
|
-
});
|
|
23756
|
-
}
|
|
23757
|
-
function filterCarrierAgentModesToRegisteredIds(snapshot, registeredCarrierIds) {
|
|
23758
|
-
const allowed = new Set(registeredCarrierIds);
|
|
23759
|
-
return {
|
|
23760
|
-
agentModes: Object.fromEntries(
|
|
23761
|
-
Object.entries(snapshot.agentModes).filter(([carrierId]) => allowed.has(carrierId))
|
|
23762
|
-
),
|
|
23763
|
-
generation: snapshot.generation
|
|
23764
|
-
};
|
|
23765
|
-
}
|
|
23766
|
-
function getEnabledCarrierSubagentIds(snapshot, registeredCarrierIds) {
|
|
23767
|
-
const filtered = registeredCarrierIds ? filterCarrierAgentModesToRegisteredIds(snapshot, registeredCarrierIds) : snapshot;
|
|
23768
|
-
return Object.keys(filtered.agentModes).sort();
|
|
23769
|
-
}
|
|
23770
|
-
|
|
23771
23915
|
// ../../packages/fleet-carriers/src/store/taskforce-config.ts
|
|
23772
23916
|
var taskforce_config_exports = {};
|
|
23773
23917
|
__export(taskforce_config_exports, {
|
|
@@ -23890,20 +24034,12 @@ function isTaskForceCliType(value) {
|
|
|
23890
24034
|
}
|
|
23891
24035
|
|
|
23892
24036
|
// ../../packages/fleet-carriers/src/store/index.ts
|
|
23893
|
-
|
|
24037
|
+
({
|
|
23894
24038
|
...state_io_exports,
|
|
23895
|
-
...subagent_mode_exports,
|
|
23896
24039
|
...models_exports,
|
|
23897
24040
|
...taskforce_config_exports,
|
|
23898
24041
|
...cli_types_exports,
|
|
23899
|
-
...display_names_exports
|
|
23900
|
-
stateIo: state_io_exports,
|
|
23901
|
-
subagentMode: subagent_mode_exports,
|
|
23902
|
-
models: models_exports,
|
|
23903
|
-
taskforceConfig: taskforce_config_exports,
|
|
23904
|
-
cliTypes: cli_types_exports,
|
|
23905
|
-
displayNames: display_names_exports
|
|
23906
|
-
};
|
|
24042
|
+
...display_names_exports});
|
|
23907
24043
|
|
|
23908
24044
|
// ../../packages/fleet-carriers/src/dispatch/framework.ts
|
|
23909
24045
|
var CarrierRegistry = class {
|
|
@@ -23949,7 +24085,6 @@ function registerCarrier(registry3, config2) {
|
|
|
23949
24085
|
existing.defaultModel = config2.defaultModel;
|
|
23950
24086
|
existing.defaultEffort = config2.defaultEffort;
|
|
23951
24087
|
existing.carrierMetadata = config2.carrierMetadata;
|
|
23952
|
-
existing.subagent = config2.subagent;
|
|
23953
24088
|
} else {
|
|
23954
24089
|
gs.modes.set(config2.id, { config: config2 });
|
|
23955
24090
|
}
|
|
@@ -24064,27 +24199,6 @@ function getModelEffort(cliType, modelId) {
|
|
|
24064
24199
|
return normalizeEffort(getEffort(cliType, modelId));
|
|
24065
24200
|
}
|
|
24066
24201
|
|
|
24067
|
-
// ../../packages/fleet-carriers/src/personas/index.ts
|
|
24068
|
-
var personas_exports = {};
|
|
24069
|
-
__export(personas_exports, {
|
|
24070
|
-
CHRONICLE_DEFAULTS: () => CHRONICLE_DEFAULTS,
|
|
24071
|
-
CHRONICLE_METADATA: () => CARRIER_METADATA,
|
|
24072
|
-
GENESIS_DEFAULTS: () => GENESIS_DEFAULTS,
|
|
24073
|
-
GENESIS_METADATA: () => CARRIER_METADATA2,
|
|
24074
|
-
KIROV_DEFAULTS: () => KIROV_DEFAULTS,
|
|
24075
|
-
KIROV_METADATA: () => CARRIER_METADATA3,
|
|
24076
|
-
NIMITZ_DEFAULTS: () => NIMITZ_DEFAULTS,
|
|
24077
|
-
NIMITZ_METADATA: () => CARRIER_METADATA4,
|
|
24078
|
-
OHIO_DEFAULTS: () => OHIO_DEFAULTS,
|
|
24079
|
-
OHIO_METADATA: () => CARRIER_METADATA5,
|
|
24080
|
-
SENTINEL_DEFAULTS: () => SENTINEL_DEFAULTS,
|
|
24081
|
-
SENTINEL_METADATA: () => CARRIER_METADATA6,
|
|
24082
|
-
TEMPEST_DEFAULTS: () => TEMPEST_DEFAULTS,
|
|
24083
|
-
TEMPEST_METADATA: () => CARRIER_METADATA7,
|
|
24084
|
-
VANGUARD_DEFAULTS: () => VANGUARD_DEFAULTS,
|
|
24085
|
-
VANGUARD_METADATA: () => CARRIER_METADATA8
|
|
24086
|
-
});
|
|
24087
|
-
|
|
24088
24202
|
// ../../packages/fleet-carriers/src/personas/chronicle.ts
|
|
24089
24203
|
var CHRONICLE_DEFAULTS = {
|
|
24090
24204
|
id: "chronicle",
|
|
@@ -24093,14 +24207,8 @@ var CHRONICLE_DEFAULTS = {
|
|
|
24093
24207
|
agent: {
|
|
24094
24208
|
dispatch: {
|
|
24095
24209
|
defaultCliType: "claude",
|
|
24096
|
-
defaultAgentMode: "subagent",
|
|
24097
24210
|
defaultModel: "sonnet",
|
|
24098
24211
|
defaultEffort: "low"
|
|
24099
|
-
},
|
|
24100
|
-
nativeSubagents: {
|
|
24101
|
-
byHost: {
|
|
24102
|
-
claude: { defaultModel: "sonnet", defaultEffort: "low" }
|
|
24103
|
-
}
|
|
24104
24212
|
}
|
|
24105
24213
|
}
|
|
24106
24214
|
};
|
|
@@ -24193,14 +24301,8 @@ var GENESIS_DEFAULTS = {
|
|
|
24193
24301
|
agent: {
|
|
24194
24302
|
dispatch: {
|
|
24195
24303
|
defaultCliType: "claude",
|
|
24196
|
-
defaultAgentMode: "subagent",
|
|
24197
24304
|
defaultModel: "sonnet",
|
|
24198
24305
|
defaultEffort: "medium"
|
|
24199
|
-
},
|
|
24200
|
-
nativeSubagents: {
|
|
24201
|
-
byHost: {
|
|
24202
|
-
claude: { defaultModel: "sonnet", defaultEffort: "medium" }
|
|
24203
|
-
}
|
|
24204
24306
|
}
|
|
24205
24307
|
}
|
|
24206
24308
|
};
|
|
@@ -24268,14 +24370,8 @@ var KIROV_DEFAULTS = {
|
|
|
24268
24370
|
agent: {
|
|
24269
24371
|
dispatch: {
|
|
24270
24372
|
defaultCliType: "claude",
|
|
24271
|
-
defaultAgentMode: "subagent",
|
|
24272
24373
|
defaultModel: "opus[1m]",
|
|
24273
24374
|
defaultEffort: "xhigh"
|
|
24274
|
-
},
|
|
24275
|
-
nativeSubagents: {
|
|
24276
|
-
byHost: {
|
|
24277
|
-
claude: { defaultModel: "opus[1m]", defaultEffort: "xhigh" }
|
|
24278
|
-
}
|
|
24279
24375
|
}
|
|
24280
24376
|
}
|
|
24281
24377
|
};
|
|
@@ -24338,14 +24434,8 @@ var NIMITZ_DEFAULTS = {
|
|
|
24338
24434
|
agent: {
|
|
24339
24435
|
dispatch: {
|
|
24340
24436
|
defaultCliType: "claude",
|
|
24341
|
-
defaultAgentMode: "subagent",
|
|
24342
24437
|
defaultModel: "opus[1m]",
|
|
24343
24438
|
defaultEffort: "max"
|
|
24344
|
-
},
|
|
24345
|
-
nativeSubagents: {
|
|
24346
|
-
byHost: {
|
|
24347
|
-
claude: { defaultModel: "opus[1m]", defaultEffort: "xhigh" }
|
|
24348
|
-
}
|
|
24349
24439
|
}
|
|
24350
24440
|
}
|
|
24351
24441
|
};
|
|
@@ -24409,14 +24499,8 @@ var OHIO_DEFAULTS = {
|
|
|
24409
24499
|
agent: {
|
|
24410
24500
|
dispatch: {
|
|
24411
24501
|
defaultCliType: "claude",
|
|
24412
|
-
defaultAgentMode: "subagent",
|
|
24413
24502
|
defaultModel: "sonnet",
|
|
24414
24503
|
defaultEffort: "low"
|
|
24415
|
-
},
|
|
24416
|
-
nativeSubagents: {
|
|
24417
|
-
byHost: {
|
|
24418
|
-
claude: { defaultModel: "sonnet", defaultEffort: "low" }
|
|
24419
|
-
}
|
|
24420
24504
|
}
|
|
24421
24505
|
}
|
|
24422
24506
|
};
|
|
@@ -24481,14 +24565,8 @@ var SENTINEL_DEFAULTS = {
|
|
|
24481
24565
|
agent: {
|
|
24482
24566
|
dispatch: {
|
|
24483
24567
|
defaultCliType: "claude",
|
|
24484
|
-
defaultAgentMode: "subagent",
|
|
24485
24568
|
defaultModel: "sonnet",
|
|
24486
24569
|
defaultEffort: "max"
|
|
24487
|
-
},
|
|
24488
|
-
nativeSubagents: {
|
|
24489
|
-
byHost: {
|
|
24490
|
-
claude: { defaultModel: "sonnet", defaultEffort: "xhigh" }
|
|
24491
|
-
}
|
|
24492
24570
|
}
|
|
24493
24571
|
}
|
|
24494
24572
|
};
|
|
@@ -24544,14 +24622,8 @@ var TEMPEST_DEFAULTS = {
|
|
|
24544
24622
|
agent: {
|
|
24545
24623
|
dispatch: {
|
|
24546
24624
|
defaultCliType: "claude",
|
|
24547
|
-
defaultAgentMode: "subagent",
|
|
24548
24625
|
defaultModel: "sonnet",
|
|
24549
24626
|
defaultEffort: "medium"
|
|
24550
|
-
},
|
|
24551
|
-
nativeSubagents: {
|
|
24552
|
-
byHost: {
|
|
24553
|
-
claude: { defaultModel: "sonnet", defaultEffort: "medium" }
|
|
24554
|
-
}
|
|
24555
24627
|
}
|
|
24556
24628
|
}
|
|
24557
24629
|
};
|
|
@@ -24606,14 +24678,8 @@ var VANGUARD_DEFAULTS = {
|
|
|
24606
24678
|
agent: {
|
|
24607
24679
|
dispatch: {
|
|
24608
24680
|
defaultCliType: "claude",
|
|
24609
|
-
defaultAgentMode: "subagent",
|
|
24610
24681
|
defaultModel: "haiku",
|
|
24611
24682
|
defaultEffort: "low"
|
|
24612
|
-
},
|
|
24613
|
-
nativeSubagents: {
|
|
24614
|
-
byHost: {
|
|
24615
|
-
claude: { defaultModel: "haiku", defaultEffort: "low" }
|
|
24616
|
-
}
|
|
24617
24683
|
}
|
|
24618
24684
|
}
|
|
24619
24685
|
};
|
|
@@ -24678,24 +24744,14 @@ function registerDefaultCarriers(registry3) {
|
|
|
24678
24744
|
}
|
|
24679
24745
|
function buildDefaultCarrierConfig(registration) {
|
|
24680
24746
|
const { defaults, metadata } = registration;
|
|
24681
|
-
const claudeSubagentDefaults = defaults.agent.nativeSubagents?.byHost?.claude;
|
|
24682
24747
|
return {
|
|
24683
24748
|
id: defaults.id,
|
|
24684
24749
|
defaultCliType: defaults.agent.dispatch.defaultCliType,
|
|
24685
|
-
defaultAgentMode: defaults.agent.dispatch.defaultAgentMode,
|
|
24686
24750
|
defaultEffort: defaults.agent.dispatch.defaultEffort,
|
|
24687
24751
|
defaultModel: defaults.agent.dispatch.defaultModel,
|
|
24688
24752
|
slot: defaults.slot,
|
|
24689
24753
|
displayName: defaults.displayName,
|
|
24690
|
-
carrierMetadata: metadata
|
|
24691
|
-
subagent: {
|
|
24692
|
-
provider: "claude",
|
|
24693
|
-
defaultModel: claudeSubagentDefaults?.defaultModel,
|
|
24694
|
-
defaultEffort: claudeSubagentDefaults?.defaultEffort,
|
|
24695
|
-
byHost: {
|
|
24696
|
-
claude: claudeSubagentDefaults
|
|
24697
|
-
}
|
|
24698
|
-
}
|
|
24754
|
+
carrierMetadata: metadata
|
|
24699
24755
|
};
|
|
24700
24756
|
}
|
|
24701
24757
|
|
|
@@ -24828,7 +24884,7 @@ var StatusOverlayController = class {
|
|
|
24828
24884
|
function buildCarrierModelDefaults(config2, cliType) {
|
|
24829
24885
|
if (!config2) return {};
|
|
24830
24886
|
if (cliType === "claude") {
|
|
24831
|
-
return
|
|
24887
|
+
return {
|
|
24832
24888
|
...config2.defaultModel ? { defaultModel: config2.defaultModel } : {},
|
|
24833
24889
|
...config2.defaultEffort ? { defaultEffort: config2.defaultEffort } : {}
|
|
24834
24890
|
};
|
|
@@ -24845,46 +24901,8 @@ __export(taskforce_exports, {
|
|
|
24845
24901
|
launchTaskForceJob: () => launchTaskForceJob
|
|
24846
24902
|
});
|
|
24847
24903
|
|
|
24848
|
-
// ../../packages/fleet-carriers/src/jobs/archive.ts
|
|
24849
|
-
var archive_exports = {};
|
|
24850
|
-
__export(archive_exports, {
|
|
24851
|
-
appendBlock: () => appendBlock,
|
|
24852
|
-
createJobArchive: () => createJobArchive,
|
|
24853
|
-
createJobStreamArchiveStore: () => createJobStreamArchiveStore,
|
|
24854
|
-
detachJobArchive: () => detachJobArchive,
|
|
24855
|
-
finalizeJobArchive: () => finalizeJobArchive,
|
|
24856
|
-
getFinalized: () => getFinalized,
|
|
24857
|
-
hasFinalizedJobArchive: () => hasFinalizedJobArchive,
|
|
24858
|
-
hasJobArchive: () => hasJobArchive,
|
|
24859
|
-
redactSecrets: () => redactSecrets,
|
|
24860
|
-
resetJobArchivesForTest: () => resetJobArchivesForTest,
|
|
24861
|
-
sanitizeArchiveText: () => sanitizeArchiveText,
|
|
24862
|
-
serializeJobArchive: () => serializeJobArchive,
|
|
24863
|
-
toArchiveBlock: () => toArchiveBlock,
|
|
24864
|
-
toMessageArchiveBlock: () => toMessageArchiveBlock,
|
|
24865
|
-
toThoughtArchiveBlock: () => toThoughtArchiveBlock,
|
|
24866
|
-
toToolCallArchiveBlock: () => toToolCallArchiveBlock
|
|
24867
|
-
});
|
|
24868
|
-
|
|
24869
24904
|
// ../../packages/fleet-carriers/src/jobs/types.ts
|
|
24870
|
-
var types_exports2 = {};
|
|
24871
|
-
__export(types_exports2, {
|
|
24872
|
-
CARRIER_JOBS_FULL_RESULT_BYTE_CAP: () => CARRIER_JOBS_FULL_RESULT_BYTE_CAP,
|
|
24873
|
-
CARRIER_JOBS_GLOBAL_BYTE_CAP: () => CARRIER_JOBS_GLOBAL_BYTE_CAP,
|
|
24874
|
-
CARRIER_JOBS_PER_SUBOP_BYTE_CAP: () => CARRIER_JOBS_PER_SUBOP_BYTE_CAP,
|
|
24875
|
-
CARRIER_JOB_TTL_MS: () => CARRIER_JOB_TTL_MS,
|
|
24876
|
-
JOB_LAUNCH_NOTICE: () => JOB_LAUNCH_NOTICE,
|
|
24877
|
-
buildCarrierJobId: () => buildCarrierJobId,
|
|
24878
|
-
buildJobSummary: () => buildJobSummary,
|
|
24879
|
-
computeFinalStatus: () => computeFinalStatus,
|
|
24880
|
-
formatLaunchResponseText: () => formatLaunchResponseText,
|
|
24881
|
-
isCarrierJobId: () => isCarrierJobId,
|
|
24882
|
-
parseCarrierJobId: () => parseCarrierJobId
|
|
24883
|
-
});
|
|
24884
24905
|
var CARRIER_JOB_TTL_MS = 3 * 60 * 60 * 1e3;
|
|
24885
|
-
var CARRIER_JOBS_FULL_RESULT_BYTE_CAP = 2e4;
|
|
24886
|
-
var CARRIER_JOBS_PER_SUBOP_BYTE_CAP = 2e4;
|
|
24887
|
-
var CARRIER_JOBS_GLOBAL_BYTE_CAP = 6e4;
|
|
24888
24906
|
var JOB_LAUNCH_NOTICE = [
|
|
24889
24907
|
"Job accepted from carrier_dispatch; result arrives later via carrier-completion follow-up push tagged [carrier:result].",
|
|
24890
24908
|
"Task Force is an execution mode of carrier_dispatch when the selected carrier is configured for it.",
|
|
@@ -24925,19 +24943,6 @@ function buildCarrierJobId(kind, toolCallId) {
|
|
|
24925
24943
|
}
|
|
24926
24944
|
return `${kind}:${toolCallId}`;
|
|
24927
24945
|
}
|
|
24928
|
-
function parseCarrierJobId(jobId) {
|
|
24929
|
-
const separatorIndex = jobId.indexOf(":");
|
|
24930
|
-
if (separatorIndex <= 0 || separatorIndex === jobId.length - 1) return null;
|
|
24931
|
-
const prefix = jobId.slice(0, separatorIndex);
|
|
24932
|
-
if (!JOB_PREFIXES.has(prefix)) return null;
|
|
24933
|
-
return {
|
|
24934
|
-
kind: prefix,
|
|
24935
|
-
toolCallId: jobId.slice(separatorIndex + 1)
|
|
24936
|
-
};
|
|
24937
|
-
}
|
|
24938
|
-
function isCarrierJobId(jobId) {
|
|
24939
|
-
return parseCarrierJobId(jobId) !== null;
|
|
24940
|
-
}
|
|
24941
24946
|
function buildJobSummaryText(prefix, status, successCount, failureCount, error51) {
|
|
24942
24947
|
if (status === "aborted") return `${prefix} aborted: ${successCount} done, ${failureCount} failed`;
|
|
24943
24948
|
if (error51) return `${prefix} failed: ${error51}`;
|
|
@@ -24945,9 +24950,7 @@ function buildJobSummaryText(prefix, status, successCount, failureCount, error51
|
|
|
24945
24950
|
}
|
|
24946
24951
|
|
|
24947
24952
|
// ../../packages/fleet-carriers/src/jobs/archive.ts
|
|
24948
|
-
var HEAD_BYTE_RATIO = 0.25;
|
|
24949
24953
|
var MAX_TEXT_CHARS = 24e3;
|
|
24950
|
-
var MAX_RAW_OUTPUT_CHARS = 12e3;
|
|
24951
24954
|
var ANSI_PATTERN2 = /\x1b\[[0-?]*[ -/]*[@-~]/g;
|
|
24952
24955
|
var CONTROL_PATTERN2 = /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g;
|
|
24953
24956
|
var SECRET_PATTERNS2 = [
|
|
@@ -24962,270 +24965,6 @@ var MAX_TOTAL_BYTES = 8 * 1024 * 1024;
|
|
|
24962
24965
|
var PRESERVE_HEAD_BLOCKS = 20;
|
|
24963
24966
|
var PRESERVE_TAIL_BLOCKS = 50;
|
|
24964
24967
|
var defaultJobStreamArchiveStore = createJobStreamArchiveStore();
|
|
24965
|
-
function serializeJobArchive(archive, opts) {
|
|
24966
|
-
const blocks = archive.truncated ? [...archive.blocks] : [...archive.blocks].sort((a, b) => a.timestamp - b.timestamp);
|
|
24967
|
-
if (blocks.length === 0) {
|
|
24968
|
-
return `(no archived output)`;
|
|
24969
|
-
}
|
|
24970
|
-
const perSubOpMaxBytes = opts?.perSubOpMaxBytes;
|
|
24971
|
-
if (perSubOpMaxBytes !== void 0 && perSubOpMaxBytes > 0) {
|
|
24972
|
-
let merged = applyPerSubOpByteCap(blocks, perSubOpMaxBytes);
|
|
24973
|
-
const globalMax = opts?.maxBytes;
|
|
24974
|
-
if (globalMax !== void 0 && globalMax > 0) {
|
|
24975
|
-
merged = applyByteCap(merged, globalMax, void 0, false);
|
|
24976
|
-
}
|
|
24977
|
-
return merged.map((block) => renderBlock(block)).join("\n\n").trimEnd();
|
|
24978
|
-
}
|
|
24979
|
-
return applyByteCap(blocks, opts?.maxBytes, void 0, false).map((block) => renderBlock(block)).join("\n\n").trimEnd();
|
|
24980
|
-
}
|
|
24981
|
-
function applyPerSubOpByteCap(blocks, perSubOpMaxBytes) {
|
|
24982
|
-
const groupMap = /* @__PURE__ */ new Map();
|
|
24983
|
-
const orderedKeys = [];
|
|
24984
|
-
for (const block of blocks) {
|
|
24985
|
-
const key = subOpGroupKey(block);
|
|
24986
|
-
if (!groupMap.has(key)) {
|
|
24987
|
-
groupMap.set(key, []);
|
|
24988
|
-
orderedKeys.push(key);
|
|
24989
|
-
}
|
|
24990
|
-
groupMap.get(key).push(block);
|
|
24991
|
-
}
|
|
24992
|
-
const merged = [];
|
|
24993
|
-
for (const key of orderedKeys) {
|
|
24994
|
-
const groupBlocks = groupMap.get(key);
|
|
24995
|
-
const headerLabel = groupBlocks[0]?.label;
|
|
24996
|
-
if (headerLabel !== void 0 && headerLabel !== "") {
|
|
24997
|
-
const minTs = Math.min(...groupBlocks.map((b) => b.timestamp));
|
|
24998
|
-
if (groupBlocks.every((block) => !block.text?.trim())) {
|
|
24999
|
-
merged.push(groupHeaderBlock(headerLabel, minTs - 1));
|
|
25000
|
-
merged.push(emptyGroupPlaceholderBlock(headerLabel, minTs));
|
|
25001
|
-
continue;
|
|
25002
|
-
}
|
|
25003
|
-
const header = groupHeaderBlock(headerLabel, minTs - 1);
|
|
25004
|
-
merged.push(...applyByteCap([header, ...groupBlocks], perSubOpMaxBytes, headerLabel, true));
|
|
25005
|
-
} else {
|
|
25006
|
-
merged.push(...applyByteCap(groupBlocks, perSubOpMaxBytes, void 0, true));
|
|
25007
|
-
}
|
|
25008
|
-
}
|
|
25009
|
-
return merged;
|
|
25010
|
-
}
|
|
25011
|
-
function subOpGroupKey(block) {
|
|
25012
|
-
return `${block.source}\0${block.label ?? ""}`;
|
|
25013
|
-
}
|
|
25014
|
-
function groupHeaderBlock(label, timestamp) {
|
|
25015
|
-
return {
|
|
25016
|
-
kind: "text",
|
|
25017
|
-
timestamp,
|
|
25018
|
-
source: "archive",
|
|
25019
|
-
label: void 0,
|
|
25020
|
-
text: `\u2500\u2500 ${label} \u2500\u2500`
|
|
25021
|
-
};
|
|
25022
|
-
}
|
|
25023
|
-
function emptyGroupPlaceholderBlock(label, timestamp) {
|
|
25024
|
-
return {
|
|
25025
|
-
kind: "text",
|
|
25026
|
-
timestamp,
|
|
25027
|
-
source: "archive",
|
|
25028
|
-
label: void 0,
|
|
25029
|
-
text: `(no archived output for ${label})`
|
|
25030
|
-
};
|
|
25031
|
-
}
|
|
25032
|
-
function applyByteCap(blocks, maxBytes, truncatedInLabel, enableSingleBlockCharSlice = false) {
|
|
25033
|
-
if (!maxBytes || maxBytes <= 0) return blocks;
|
|
25034
|
-
const full = blocks.map((block) => renderBlock(block)).join("\n\n").trimEnd();
|
|
25035
|
-
if (byteLength2(full) <= maxBytes) return blocks;
|
|
25036
|
-
if (enableSingleBlockCharSlice) {
|
|
25037
|
-
const sliced = trySliceOversizedSingleOrHeaderPayload(blocks, maxBytes, truncatedInLabel);
|
|
25038
|
-
if (sliced) return sliced;
|
|
25039
|
-
}
|
|
25040
|
-
const headBudget = Math.floor(maxBytes * HEAD_BYTE_RATIO);
|
|
25041
|
-
const head = [];
|
|
25042
|
-
let headBytes = 0;
|
|
25043
|
-
for (const block of blocks) {
|
|
25044
|
-
const blockBytes2 = serializedBlockBytes(block, head.length > 0);
|
|
25045
|
-
if (headBytes + blockBytes2 > headBudget) break;
|
|
25046
|
-
head.push(block);
|
|
25047
|
-
headBytes += blockBytes2;
|
|
25048
|
-
}
|
|
25049
|
-
const tail = [];
|
|
25050
|
-
for (let index = blocks.length - 1; index >= head.length; index--) {
|
|
25051
|
-
const nextTail = [blocks[index], ...tail];
|
|
25052
|
-
const omittedCount = blocks.length - head.length - nextTail.length;
|
|
25053
|
-
const marker = buildTruncatedMarker(blocks, head.length, omittedCount, truncatedInLabel);
|
|
25054
|
-
const candidateBytes = serializedBlocksBytes([...head, marker, ...nextTail]);
|
|
25055
|
-
if (candidateBytes > maxBytes) continue;
|
|
25056
|
-
tail.unshift(blocks[index]);
|
|
25057
|
-
}
|
|
25058
|
-
let selected = buildCappedSelection(blocks, head, tail, truncatedInLabel);
|
|
25059
|
-
if (selected === blocks) return blocks;
|
|
25060
|
-
while (serializedBlocksBytes(selected) > maxBytes && tail.length > 0) {
|
|
25061
|
-
tail.shift();
|
|
25062
|
-
selected = buildCappedSelection(blocks, head, tail, truncatedInLabel);
|
|
25063
|
-
}
|
|
25064
|
-
while (serializedBlocksBytes(selected) > maxBytes && head.length > 0) {
|
|
25065
|
-
head.pop();
|
|
25066
|
-
selected = buildCappedSelection(blocks, head, tail, truncatedInLabel);
|
|
25067
|
-
}
|
|
25068
|
-
return selected;
|
|
25069
|
-
}
|
|
25070
|
-
function trySliceOversizedSingleOrHeaderPayload(blocks, maxBytes, truncatedInLabel) {
|
|
25071
|
-
if (blocks.length === 1) {
|
|
25072
|
-
const block = blocks[0];
|
|
25073
|
-
const rendered = renderBlock(block);
|
|
25074
|
-
if (byteLength2(rendered) <= maxBytes) return null;
|
|
25075
|
-
return sliceSingleOversizedTextBlock(block, rendered, maxBytes, truncatedInLabel);
|
|
25076
|
-
}
|
|
25077
|
-
if (blocks.length === 2 && isSerializerGroupHeaderBlock(blocks[0]) && blocks[1]?.kind === "text") {
|
|
25078
|
-
const headerBlock = blocks[0];
|
|
25079
|
-
const payloadBlock = blocks[1];
|
|
25080
|
-
const headerRendered = renderBlock(headerBlock);
|
|
25081
|
-
const bodyRendered = renderBlock(payloadBlock);
|
|
25082
|
-
const sep3 = "\n\n";
|
|
25083
|
-
const prefixBytes = byteLength2(headerRendered) + byteLength2(sep3);
|
|
25084
|
-
const innerBudget = maxBytes - prefixBytes;
|
|
25085
|
-
if (innerBudget <= 0) {
|
|
25086
|
-
return [headerBlock, buildCharTruncatedMarkerBlock(payloadBlock.timestamp, countCodepointsInUtf8Buffer(Buffer.from(bodyRendered, "utf8")), truncatedInLabel)];
|
|
25087
|
-
}
|
|
25088
|
-
if (byteLength2(bodyRendered) <= innerBudget) return null;
|
|
25089
|
-
const { head, marker, tail } = splitRenderedUtf8AtByteCap(bodyRendered, innerBudget, truncatedInLabel);
|
|
25090
|
-
return [
|
|
25091
|
-
headerBlock,
|
|
25092
|
-
{ ...payloadBlock, text: head },
|
|
25093
|
-
{
|
|
25094
|
-
kind: "text",
|
|
25095
|
-
timestamp: payloadBlock.timestamp,
|
|
25096
|
-
source: "archive",
|
|
25097
|
-
label: "truncated",
|
|
25098
|
-
text: marker
|
|
25099
|
-
},
|
|
25100
|
-
{ ...payloadBlock, text: tail, timestamp: payloadBlock.timestamp + 1 }
|
|
25101
|
-
];
|
|
25102
|
-
}
|
|
25103
|
-
return null;
|
|
25104
|
-
}
|
|
25105
|
-
function sliceSingleOversizedTextBlock(block, rendered, maxBytes, truncatedInLabel) {
|
|
25106
|
-
const { head, marker, tail } = splitRenderedUtf8AtByteCap(rendered, maxBytes, truncatedInLabel);
|
|
25107
|
-
const ts = block.timestamp;
|
|
25108
|
-
return [
|
|
25109
|
-
{ ...block, text: head },
|
|
25110
|
-
{ kind: "text", timestamp: ts, source: "archive", label: "truncated", text: marker },
|
|
25111
|
-
{ ...block, text: tail, timestamp: ts + 1 }
|
|
25112
|
-
];
|
|
25113
|
-
}
|
|
25114
|
-
function isSerializerGroupHeaderBlock(block) {
|
|
25115
|
-
if (block.kind !== "text" || block.source !== "archive" || block.label !== void 0) return false;
|
|
25116
|
-
const line = block.text?.trim() ?? "";
|
|
25117
|
-
return /^── .+ ──$/.test(line);
|
|
25118
|
-
}
|
|
25119
|
-
function splitRenderedUtf8AtByteCap(rendered, maxBytes, charLabel) {
|
|
25120
|
-
const buf = Buffer.from(rendered, "utf8");
|
|
25121
|
-
if (buf.length <= maxBytes) {
|
|
25122
|
-
return { head: rendered, marker: "", tail: "" };
|
|
25123
|
-
}
|
|
25124
|
-
const sepLen = byteLength2("\n\n");
|
|
25125
|
-
let headBudget = Math.min(buf.length, Math.floor(maxBytes * HEAD_BYTE_RATIO));
|
|
25126
|
-
const tailBudget = Math.min(buf.length, Math.floor(maxBytes * (1 - HEAD_BYTE_RATIO)));
|
|
25127
|
-
for (let iter = 0; iter < 200; iter++) {
|
|
25128
|
-
let headLen2 = utf8PrefixByteLength(buf, headBudget);
|
|
25129
|
-
let tailStart2 = utf8SuffixStartIndex(buf, tailBudget);
|
|
25130
|
-
if (tailStart2 < headLen2) {
|
|
25131
|
-
tailStart2 = utf8SuffixStartIndex(buf, Math.max(0, Math.min(tailBudget, buf.length - headLen2)));
|
|
25132
|
-
}
|
|
25133
|
-
if (tailStart2 < headLen2) {
|
|
25134
|
-
tailStart2 = headLen2;
|
|
25135
|
-
}
|
|
25136
|
-
const midBuf = buf.subarray(headLen2, tailStart2);
|
|
25137
|
-
const omittedChars = countCodepointsInUtf8Buffer(midBuf);
|
|
25138
|
-
const marker2 = buildCharTruncatedMarker(omittedChars, charLabel);
|
|
25139
|
-
const headStr = buf.subarray(0, headLen2).toString("utf8");
|
|
25140
|
-
const tailStr = buf.subarray(tailStart2).toString("utf8");
|
|
25141
|
-
const total = byteLength2(headStr) + sepLen + byteLength2(marker2) + sepLen + byteLength2(tailStr);
|
|
25142
|
-
if (total <= maxBytes) {
|
|
25143
|
-
return { head: headStr, marker: marker2, tail: tailStr };
|
|
25144
|
-
}
|
|
25145
|
-
headBudget = Math.max(0, headBudget - Math.max(16, Math.floor(headBudget * 0.08)));
|
|
25146
|
-
if (headBudget === 0) break;
|
|
25147
|
-
}
|
|
25148
|
-
const marker = buildCharTruncatedMarker(Math.max(1, countCodepointsInUtf8Buffer(buf) - 1), charLabel);
|
|
25149
|
-
const markerTotal = byteLength2(marker) + 2 * sepLen;
|
|
25150
|
-
const room = Math.max(1, maxBytes - markerTotal);
|
|
25151
|
-
const tailBudgetFallback = Math.min(buf.length, Math.max(1, Math.floor(room * (1 - HEAD_BYTE_RATIO))));
|
|
25152
|
-
let tailStart = utf8SuffixStartIndex(buf, tailBudgetFallback);
|
|
25153
|
-
let headLen = utf8PrefixByteLength(buf, Math.min(buf.length, Math.floor(room * HEAD_BYTE_RATIO)));
|
|
25154
|
-
if (tailStart < headLen) {
|
|
25155
|
-
tailStart = utf8SuffixStartIndex(buf, Math.max(0, Math.min(tailBudgetFallback, buf.length - headLen)));
|
|
25156
|
-
}
|
|
25157
|
-
if (tailStart < headLen) {
|
|
25158
|
-
tailStart = headLen;
|
|
25159
|
-
}
|
|
25160
|
-
return {
|
|
25161
|
-
head: buf.subarray(0, headLen).toString("utf8"),
|
|
25162
|
-
marker,
|
|
25163
|
-
tail: buf.subarray(tailStart).toString("utf8")
|
|
25164
|
-
};
|
|
25165
|
-
}
|
|
25166
|
-
function buildCharTruncatedMarkerBlock(timestamp, omittedChars, label) {
|
|
25167
|
-
return {
|
|
25168
|
-
kind: "text",
|
|
25169
|
-
timestamp,
|
|
25170
|
-
source: "archive",
|
|
25171
|
-
label: "truncated",
|
|
25172
|
-
text: buildCharTruncatedMarker(omittedChars, label)
|
|
25173
|
-
};
|
|
25174
|
-
}
|
|
25175
|
-
function buildCharTruncatedMarker(omittedChars, label) {
|
|
25176
|
-
if (label !== void 0 && label.length > 0) {
|
|
25177
|
-
return `[truncated ${omittedChars} chars in ${label}]`;
|
|
25178
|
-
}
|
|
25179
|
-
return `[truncated ${omittedChars} chars]`;
|
|
25180
|
-
}
|
|
25181
|
-
function utf8PrefixByteLength(buf, maxBytes) {
|
|
25182
|
-
let len = Math.min(maxBytes, buf.length);
|
|
25183
|
-
while (len > 0 && len < buf.length && (buf[len] & 192) === 128) {
|
|
25184
|
-
len--;
|
|
25185
|
-
}
|
|
25186
|
-
return len;
|
|
25187
|
-
}
|
|
25188
|
-
function utf8SuffixStartIndex(buf, tailMaxBytes) {
|
|
25189
|
-
if (tailMaxBytes <= 0) return buf.length;
|
|
25190
|
-
const capped = Math.min(tailMaxBytes, buf.length);
|
|
25191
|
-
let start = buf.length - capped;
|
|
25192
|
-
while (start < buf.length && (buf[start] & 192) === 128) {
|
|
25193
|
-
start++;
|
|
25194
|
-
}
|
|
25195
|
-
return start;
|
|
25196
|
-
}
|
|
25197
|
-
function countCodepointsInUtf8Buffer(slice) {
|
|
25198
|
-
if (slice.length === 0) return 0;
|
|
25199
|
-
return [...slice.toString("utf8")].length;
|
|
25200
|
-
}
|
|
25201
|
-
function renderBlock(block) {
|
|
25202
|
-
return block.text?.trim() || "(empty)";
|
|
25203
|
-
}
|
|
25204
|
-
function buildCappedSelection(blocks, head, tail, truncatedInLabel) {
|
|
25205
|
-
const omittedCount = blocks.length - head.length - tail.length;
|
|
25206
|
-
if (omittedCount <= 0) return blocks;
|
|
25207
|
-
return [...head, buildTruncatedMarker(blocks, head.length, omittedCount, truncatedInLabel), ...tail];
|
|
25208
|
-
}
|
|
25209
|
-
function buildTruncatedMarker(blocks, omittedStart, omittedCount, truncatedInLabel) {
|
|
25210
|
-
const timestamp = blocks[omittedStart]?.timestamp ?? blocks.at(-1)?.timestamp ?? 0;
|
|
25211
|
-
const text = truncatedInLabel !== void 0 && truncatedInLabel.length > 0 ? `[truncated ${omittedCount} blocks in ${truncatedInLabel}]` : `[truncated ${omittedCount} blocks]`;
|
|
25212
|
-
return {
|
|
25213
|
-
kind: "text",
|
|
25214
|
-
timestamp,
|
|
25215
|
-
source: "archive",
|
|
25216
|
-
label: "truncated",
|
|
25217
|
-
text
|
|
25218
|
-
};
|
|
25219
|
-
}
|
|
25220
|
-
function serializedBlocksBytes(blocks) {
|
|
25221
|
-
return byteLength2(blocks.map((block) => renderBlock(block)).join("\n\n").trimEnd());
|
|
25222
|
-
}
|
|
25223
|
-
function serializedBlockBytes(block, includeSeparator) {
|
|
25224
|
-
return byteLength2(`${includeSeparator ? "\n\n" : ""}${renderBlock(block)}`);
|
|
25225
|
-
}
|
|
25226
|
-
function byteLength2(value) {
|
|
25227
|
-
return Buffer.byteLength(value, "utf8");
|
|
25228
|
-
}
|
|
25229
24968
|
function toArchiveBlock(kind, source, text, label, timestamp = Date.now()) {
|
|
25230
24969
|
return {
|
|
25231
24970
|
kind,
|
|
@@ -25235,24 +24974,6 @@ function toArchiveBlock(kind, source, text, label, timestamp = Date.now()) {
|
|
|
25235
24974
|
text: sanitizeArchiveText(text, MAX_TEXT_CHARS)
|
|
25236
24975
|
};
|
|
25237
24976
|
}
|
|
25238
|
-
function toMessageArchiveBlock(source, text, label, timestamp = Date.now()) {
|
|
25239
|
-
return toArchiveBlock("text", source, text, label, timestamp);
|
|
25240
|
-
}
|
|
25241
|
-
function toThoughtArchiveBlock(source, text, label, timestamp = Date.now()) {
|
|
25242
|
-
return toArchiveBlock("thought", source, text, label, timestamp);
|
|
25243
|
-
}
|
|
25244
|
-
function toToolCallArchiveBlock(source, title, status, rawOutput, toolCallId, label, timestamp = Date.now()) {
|
|
25245
|
-
return {
|
|
25246
|
-
kind: "tool_call",
|
|
25247
|
-
timestamp,
|
|
25248
|
-
source: sanitizeArchiveText(source, 400),
|
|
25249
|
-
label: label ? sanitizeArchiveText(label, 400) : void 0,
|
|
25250
|
-
title: sanitizeArchiveText(title, 800),
|
|
25251
|
-
status: sanitizeArchiveText(status, 200),
|
|
25252
|
-
rawOutput: rawOutput === void 0 ? void 0 : safeSerialize(rawOutput, MAX_RAW_OUTPUT_CHARS),
|
|
25253
|
-
toolCallId: toolCallId ? sanitizeArchiveText(toolCallId, 400) : void 0
|
|
25254
|
-
};
|
|
25255
|
-
}
|
|
25256
24977
|
function sanitizeArchiveText(value, maxChars = MAX_TEXT_CHARS) {
|
|
25257
24978
|
const cleaned = value.replace(ANSI_PATTERN2, "").replace(CONTROL_PATTERN2, "");
|
|
25258
24979
|
if (cleaned.length <= maxChars) return cleaned;
|
|
@@ -25265,14 +24986,6 @@ function redactSecrets(value) {
|
|
|
25265
24986
|
value
|
|
25266
24987
|
);
|
|
25267
24988
|
}
|
|
25268
|
-
function safeSerialize(value, maxChars) {
|
|
25269
|
-
if (typeof value === "string") return sanitizeArchiveText(value, maxChars);
|
|
25270
|
-
try {
|
|
25271
|
-
return sanitizeArchiveText(JSON.stringify(value, null, 2), maxChars);
|
|
25272
|
-
} catch {
|
|
25273
|
-
return sanitizeArchiveText(String(value), maxChars);
|
|
25274
|
-
}
|
|
25275
|
-
}
|
|
25276
24989
|
function createJobStreamArchiveStore() {
|
|
25277
24990
|
const state = { archives: /* @__PURE__ */ new Map() };
|
|
25278
24991
|
function getLiveArchive(jobId, now) {
|
|
@@ -25351,21 +25064,6 @@ function appendBlock(jobId, block, now = Date.now()) {
|
|
|
25351
25064
|
function finalizeJobArchive(jobId, status, now = Date.now()) {
|
|
25352
25065
|
return defaultJobStreamArchiveStore.finalizeJobArchive(jobId, status, now);
|
|
25353
25066
|
}
|
|
25354
|
-
function getFinalized(jobId, now = Date.now()) {
|
|
25355
|
-
return defaultJobStreamArchiveStore.getFinalized(jobId, now);
|
|
25356
|
-
}
|
|
25357
|
-
function hasJobArchive(jobId, now = Date.now()) {
|
|
25358
|
-
return defaultJobStreamArchiveStore.hasJobArchive(jobId, now);
|
|
25359
|
-
}
|
|
25360
|
-
function hasFinalizedJobArchive(jobId, now = Date.now()) {
|
|
25361
|
-
return defaultJobStreamArchiveStore.hasFinalizedJobArchive(jobId, now);
|
|
25362
|
-
}
|
|
25363
|
-
function detachJobArchive(jobId) {
|
|
25364
|
-
defaultJobStreamArchiveStore.detachJobArchive(jobId);
|
|
25365
|
-
}
|
|
25366
|
-
function resetJobArchivesForTest() {
|
|
25367
|
-
defaultJobStreamArchiveStore.resetJobArchivesForTest();
|
|
25368
|
-
}
|
|
25369
25067
|
function buildTruncatedBlock(timestamp) {
|
|
25370
25068
|
return {
|
|
25371
25069
|
kind: "text",
|
|
@@ -25457,26 +25155,6 @@ function blockBytes(block) {
|
|
|
25457
25155
|
return Buffer.byteLength(JSON.stringify(block), "utf8");
|
|
25458
25156
|
}
|
|
25459
25157
|
|
|
25460
|
-
// ../../packages/fleet-carriers/src/jobs/dispatch.ts
|
|
25461
|
-
var dispatch_exports = {};
|
|
25462
|
-
__export(dispatch_exports, {
|
|
25463
|
-
CARRIER_JOBS_DOCTRINE: () => CARRIER_JOBS_DOCTRINE,
|
|
25464
|
-
CARRIER_RESULT_PUSH_PREFIX: () => CARRIER_RESULT_PUSH_PREFIX,
|
|
25465
|
-
JOB_LAUNCH_NOTICE: () => JOB_LAUNCH_NOTICE,
|
|
25466
|
-
buildCarrierJobsSchema: () => buildCarrierJobsSchema,
|
|
25467
|
-
buildCarrierJobsToolSpec: () => buildCarrierJobsToolSpec,
|
|
25468
|
-
buildCarrierResultSystemReminder: () => buildCarrierResultSystemReminder,
|
|
25469
|
-
configureJobSummaryCache: () => configureJobSummaryCache,
|
|
25470
|
-
createJobSummaryCache: () => createJobSummaryCache,
|
|
25471
|
-
dispatchCarrierJobsAction: () => dispatchCarrierJobsAction,
|
|
25472
|
-
formatLaunchResponseText: () => formatLaunchResponseText,
|
|
25473
|
-
getJobSummary: () => getJobSummary,
|
|
25474
|
-
listJobSummaries: () => listJobSummaries,
|
|
25475
|
-
putJobSummary: () => putJobSummary,
|
|
25476
|
-
resetJobSummaryCacheForTest: () => resetJobSummaryCacheForTest,
|
|
25477
|
-
wrapSystemReminder: () => wrapSystemReminder
|
|
25478
|
-
});
|
|
25479
|
-
|
|
25480
25158
|
// ../../node_modules/.pnpm/typebox@1.1.34/node_modules/typebox/build/system/memory/memory.mjs
|
|
25481
25159
|
var memory_exports = {};
|
|
25482
25160
|
__export(memory_exports, {
|
|
@@ -29684,29 +29362,6 @@ __export(typebox_exports, {
|
|
|
29684
29362
|
Void: () => Void
|
|
29685
29363
|
});
|
|
29686
29364
|
|
|
29687
|
-
// ../../packages/fleet-carriers/src/jobs/lifecycle.ts
|
|
29688
|
-
var lifecycle_exports = {};
|
|
29689
|
-
__export(lifecycle_exports, {
|
|
29690
|
-
acquireJobPermit: () => acquireJobPermit,
|
|
29691
|
-
cancelJob: () => cancelJob,
|
|
29692
|
-
combineAbortSignals: () => combineAbortSignals,
|
|
29693
|
-
configureDetachedJobCap: () => configureDetachedJobCap,
|
|
29694
|
-
createJobCancelRegistry: () => createJobCancelRegistry,
|
|
29695
|
-
finalizeDetachedJob: () => finalizeDetachedJob,
|
|
29696
|
-
getActiveBackgroundJobCount: () => getActiveBackgroundJobCount,
|
|
29697
|
-
getActiveJob: () => getActiveJob,
|
|
29698
|
-
hasJobCancelControllers: () => hasJobCancelControllers,
|
|
29699
|
-
launchResponseResult: () => launchResponseResult,
|
|
29700
|
-
listActiveJobs: () => listActiveJobs,
|
|
29701
|
-
onActiveJobCountChange: () => onActiveJobCountChange,
|
|
29702
|
-
registerJobAbortController: () => registerJobAbortController,
|
|
29703
|
-
releaseJobPermit: () => releaseJobPermit,
|
|
29704
|
-
resetJobCancelRegistryForTest: () => resetJobCancelRegistryForTest,
|
|
29705
|
-
resetJobConcurrencyForTest: () => resetJobConcurrencyForTest,
|
|
29706
|
-
startDetachedJob: () => startDetachedJob,
|
|
29707
|
-
unregisterJobAbortControllers: () => unregisterJobAbortControllers
|
|
29708
|
-
});
|
|
29709
|
-
|
|
29710
29365
|
// ../../packages/fleet-carriers/src/jobs/summary-cache.ts
|
|
29711
29366
|
var DEFAULT_MAX_ENTRIES = 50;
|
|
29712
29367
|
var defaultJobSummaryCache = createJobSummaryCache();
|
|
@@ -29762,18 +29417,6 @@ function createJobSummaryCache() {
|
|
|
29762
29417
|
function putJobSummary(summary, now = Date.now()) {
|
|
29763
29418
|
defaultJobSummaryCache.putJobSummary(summary, now);
|
|
29764
29419
|
}
|
|
29765
|
-
function getJobSummary(jobId, now = Date.now()) {
|
|
29766
|
-
return defaultJobSummaryCache.getJobSummary(jobId, now);
|
|
29767
|
-
}
|
|
29768
|
-
function listJobSummaries(now = Date.now()) {
|
|
29769
|
-
return defaultJobSummaryCache.listJobSummaries(now);
|
|
29770
|
-
}
|
|
29771
|
-
function configureJobSummaryCache(maxEntries, onEvict) {
|
|
29772
|
-
defaultJobSummaryCache.configureJobSummaryCache(maxEntries, onEvict);
|
|
29773
|
-
}
|
|
29774
|
-
function resetJobSummaryCacheForTest() {
|
|
29775
|
-
defaultJobSummaryCache.resetJobSummaryCacheForTest();
|
|
29776
|
-
}
|
|
29777
29420
|
|
|
29778
29421
|
// ../../packages/fleet-carriers/src/jobs/lifecycle.ts
|
|
29779
29422
|
var DEFAULT_MAX_DETACHED_JOBS = 5;
|
|
@@ -29819,33 +29462,6 @@ function releaseJobPermit(jobId, finished = {}) {
|
|
|
29819
29462
|
state.activeJobs.delete(jobId);
|
|
29820
29463
|
notifyActiveJobCountChange(state);
|
|
29821
29464
|
}
|
|
29822
|
-
function getActiveJob(jobId) {
|
|
29823
|
-
return getGuardState().activeJobs.get(jobId) ?? null;
|
|
29824
|
-
}
|
|
29825
|
-
function listActiveJobs() {
|
|
29826
|
-
return [...getGuardState().activeJobs.values()].sort((a, b) => b.startedAt - a.startedAt);
|
|
29827
|
-
}
|
|
29828
|
-
function getActiveBackgroundJobCount() {
|
|
29829
|
-
return getGuardState().activeJobs.size;
|
|
29830
|
-
}
|
|
29831
|
-
function onActiveJobCountChange(callback) {
|
|
29832
|
-
const state = getGuardState();
|
|
29833
|
-
state.activeJobCountCallbacks.push(callback);
|
|
29834
|
-
return () => {
|
|
29835
|
-
const index = state.activeJobCountCallbacks.indexOf(callback);
|
|
29836
|
-
if (index >= 0) state.activeJobCountCallbacks.splice(index, 1);
|
|
29837
|
-
};
|
|
29838
|
-
}
|
|
29839
|
-
function configureDetachedJobCap(maxDetachedJobs) {
|
|
29840
|
-
getGuardState().maxDetachedJobs = maxDetachedJobs;
|
|
29841
|
-
}
|
|
29842
|
-
function resetJobConcurrencyForTest() {
|
|
29843
|
-
const state = getGuardState();
|
|
29844
|
-
state.activeJobs.clear();
|
|
29845
|
-
state.activeCarrierJobs.clear();
|
|
29846
|
-
state.maxDetachedJobs = DEFAULT_MAX_DETACHED_JOBS;
|
|
29847
|
-
state.activeJobCountCallbacks = [];
|
|
29848
|
-
}
|
|
29849
29465
|
function createJobCancelRegistry() {
|
|
29850
29466
|
const state = { controllers: /* @__PURE__ */ new Map() };
|
|
29851
29467
|
return {
|
|
@@ -29880,15 +29496,6 @@ function registerJobAbortController(jobId, controller) {
|
|
|
29880
29496
|
function unregisterJobAbortControllers(jobId) {
|
|
29881
29497
|
defaultJobCancelRegistry.unregisterJobAbortControllers(jobId);
|
|
29882
29498
|
}
|
|
29883
|
-
function cancelJob(jobId) {
|
|
29884
|
-
return defaultJobCancelRegistry.cancelJob(jobId);
|
|
29885
|
-
}
|
|
29886
|
-
function hasJobCancelControllers(jobId) {
|
|
29887
|
-
return defaultJobCancelRegistry.hasJobCancelControllers(jobId);
|
|
29888
|
-
}
|
|
29889
|
-
function resetJobCancelRegistryForTest() {
|
|
29890
|
-
defaultJobCancelRegistry.resetJobCancelRegistryForTest();
|
|
29891
|
-
}
|
|
29892
29499
|
function combineAbortSignals(signals) {
|
|
29893
29500
|
if (signals.length === 0) {
|
|
29894
29501
|
return new AbortController().signal;
|
|
@@ -29963,43 +29570,74 @@ function getGuardState() {
|
|
|
29963
29570
|
return guardState;
|
|
29964
29571
|
}
|
|
29965
29572
|
|
|
29573
|
+
// ../../packages/fleet-carriers/src/jobs/workspace-manifest.ts
|
|
29574
|
+
var WORKSPACE_CHANGE_LIMIT = 200;
|
|
29575
|
+
var WORKSPACE_CHANGE_CLEARED_STATUS = "cleared";
|
|
29576
|
+
async function captureWorkspaceSnapshot(scanner, cwd) {
|
|
29577
|
+
if (!scanner) return null;
|
|
29578
|
+
try {
|
|
29579
|
+
return await scanner.snapshot(cwd);
|
|
29580
|
+
} catch {
|
|
29581
|
+
return null;
|
|
29582
|
+
}
|
|
29583
|
+
}
|
|
29584
|
+
async function captureJobWindowManifest(scanner, cwd, baseline) {
|
|
29585
|
+
if (!scanner) return void 0;
|
|
29586
|
+
const end = await captureWorkspaceSnapshot(scanner, cwd);
|
|
29587
|
+
return buildWorkspaceManifest(baseline, end);
|
|
29588
|
+
}
|
|
29589
|
+
function buildWorkspaceManifest(baseline, end) {
|
|
29590
|
+
if (!baseline || !end) return void 0;
|
|
29591
|
+
const baselineByPath = new Map(baseline.map((entry) => [entry.path, normalizeSnapshotEntry(entry)]));
|
|
29592
|
+
const endChanges = end.map(normalizeSnapshotEntry).filter((entry) => hasWindowChange(baselineByPath.get(entry.path), entry)).map(toManifestEntry);
|
|
29593
|
+
const endPaths = new Set(end.map((entry) => entry.path));
|
|
29594
|
+
const clearedChanges = [...baselineByPath.values()].filter((entry) => !endPaths.has(entry.path)).map((entry) => ({ status: WORKSPACE_CHANGE_CLEARED_STATUS, path: entry.path }));
|
|
29595
|
+
const changes = [...endChanges, ...clearedChanges];
|
|
29596
|
+
const truncated = changes.length > WORKSPACE_CHANGE_LIMIT;
|
|
29597
|
+
const capped = changes.slice(0, WORKSPACE_CHANGE_LIMIT);
|
|
29598
|
+
return {
|
|
29599
|
+
changes: capped,
|
|
29600
|
+
truncated
|
|
29601
|
+
};
|
|
29602
|
+
}
|
|
29603
|
+
function buildStatLine(changeCount, truncated) {
|
|
29604
|
+
const suffix = changeCount === 1 ? "file" : "files";
|
|
29605
|
+
return `${truncated ? `${WORKSPACE_CHANGE_LIMIT}+` : String(changeCount)} ${suffix} (window-approx)`;
|
|
29606
|
+
}
|
|
29607
|
+
function normalizeSnapshotEntry(entry) {
|
|
29608
|
+
return {
|
|
29609
|
+
status: entry.status.trim(),
|
|
29610
|
+
path: entry.path,
|
|
29611
|
+
contentHash: entry.contentHash?.trim()
|
|
29612
|
+
};
|
|
29613
|
+
}
|
|
29614
|
+
function toManifestEntry(entry) {
|
|
29615
|
+
return {
|
|
29616
|
+
status: entry.status,
|
|
29617
|
+
path: entry.path
|
|
29618
|
+
};
|
|
29619
|
+
}
|
|
29620
|
+
function hasWindowChange(baseline, end) {
|
|
29621
|
+
if (!baseline) return true;
|
|
29622
|
+
if (baseline.status !== end.status) return true;
|
|
29623
|
+
if (baseline.contentHash && end.contentHash) {
|
|
29624
|
+
return baseline.contentHash !== end.contentHash;
|
|
29625
|
+
}
|
|
29626
|
+
return false;
|
|
29627
|
+
}
|
|
29628
|
+
|
|
29966
29629
|
// ../../packages/fleet-carriers/src/jobs/dispatch.ts
|
|
29967
29630
|
var CARRIER_RESULT_PUSH_PREFIX = "[carrier:result]";
|
|
29968
|
-
var CARRIER_JOBS_DOCTRINE = {
|
|
29969
|
-
id: "carrier_jobs",
|
|
29970
|
-
tag: "carrier_jobs",
|
|
29971
|
-
title: "carrier_jobs Tool Guidelines",
|
|
29972
|
-
description: `Lookup and control detached carrier jobs registered by carrier_dispatch. This is not a delegation tool and not a polling tool; use it only to inspect archived output, cancel by job_id, or list jobs.`,
|
|
29973
|
-
promptSnippet: `carrier_jobs \u2014 Lookup/control detached carrier jobs: status, result, cancel, list.`,
|
|
29974
|
-
whenToUse: [
|
|
29975
|
-
`Use carrier_jobs when a follow-up push is missing, explicit job inspection is required, or the Admiral needs completion metadata, full archived output, cancellation, or a job list.`,
|
|
29976
|
-
`Use action:"result" only after the job is finalized; full results remain repeatable for 3 hours.`
|
|
29977
|
-
],
|
|
29978
|
-
whenNotToUse: [
|
|
29979
|
-
`Do not use carrier_jobs to delegate new work; use carrier_dispatch.`,
|
|
29980
|
-
`Do not request results for active jobs. Results are finalized-only, read-many for 3 hours, and expire by TTL.`,
|
|
29981
|
-
`Do not poll, wait-check, or call carrier_jobs merely to see whether a launched job is done; terminal results arrive through the [carrier:result] follow-up push.`
|
|
29982
|
-
],
|
|
29983
|
-
usageGuidelines: [
|
|
29984
|
-
`carrier_jobs has exactly four actions: status, result, cancel, list.`,
|
|
29985
|
-
`After launch, continue independent work if available; otherwise stop tool use and wait passively for the follow-up push instead of issuing status probes.`,
|
|
29986
|
-
`Treat carrier_jobs as the fallback channel for missing pushes or explicit lookups, not as a polling loop.`,
|
|
29987
|
-
`Results are finalized-only, read-many for 3h in process memory.`,
|
|
29988
|
-
`Task Force dispatch full responses return results: { [cliType]: "..." }; non-Task-Force full responses still return full_result.`,
|
|
29989
|
-
`carrier_jobs reads the process-memory summary cache and JobStreamArchive only. It never reads the Agent Panel stream-store.`
|
|
29990
|
-
]
|
|
29991
|
-
};
|
|
29992
29631
|
var REMINDER_TEXT_LIMIT = 500;
|
|
29993
29632
|
var REMINDER_CONTROL_CHARS = /[\u0000-\u001F\u007F-\u009F]/g;
|
|
29994
29633
|
var REMINDER_WHITESPACE = /\s+/g;
|
|
29995
|
-
var ACTIVE_STATUS_NOTICE = "Job is still running. The [carrier:result] push will be delivered automatically when it finishes \u2014 do not call carrier_jobs again until that push arrives. Stop calling tools now and return control to the user; the push wakes the agent even after this response ends.";
|
|
29996
|
-
var ACTIVE_CANCEL_NOTICE = "Cancel did not apply: the job is still running normally, not hung. Long-running carrier jobs are expected \u2014 do not retry cancel without an explicit user request to abort. The [carrier:result] push will arrive automatically; stop calling tools and return control to the user.";
|
|
29997
29634
|
function buildCarrierResultSystemReminder(input) {
|
|
29635
|
+
const changes = input.summary.workspaceChanges ? buildStatLine(input.summary.workspaceChanges.changes.length, input.summary.workspaceChanges.truncated) : "unavailable";
|
|
29998
29636
|
const lines = [`- ${input.jobId}: ${sanitizeReminderText(input.summary.summary)}`];
|
|
29999
29637
|
const metadata = [
|
|
30000
29638
|
`kind=${input.kind}`,
|
|
30001
29639
|
`status=${input.status}`,
|
|
30002
|
-
`changes=${sanitizeReminderText(
|
|
29640
|
+
`changes=${sanitizeReminderText(changes)}`,
|
|
30003
29641
|
input.label ? `label=${sanitizeReminderText(input.label)}` : void 0,
|
|
30004
29642
|
input.taskforceBackend ? `backend=${sanitizeReminderText(input.taskforceBackend)}` : void 0,
|
|
30005
29643
|
input.error ? `error=${sanitizeReminderText(input.error)}` : void 0
|
|
@@ -30014,66 +29652,6 @@ function wrapSystemReminder(text, attrs) {
|
|
|
30014
29652
|
${text}
|
|
30015
29653
|
</system-reminder>`;
|
|
30016
29654
|
}
|
|
30017
|
-
function buildCarrierJobsSchema() {
|
|
30018
|
-
return typebox_exports.Object({
|
|
30019
|
-
action: typebox_exports.Unsafe({
|
|
30020
|
-
type: "string",
|
|
30021
|
-
enum: ["status", "result", "cancel", "list"],
|
|
30022
|
-
description: "Job action to perform."
|
|
30023
|
-
}),
|
|
30024
|
-
job_id: typebox_exports.Optional(typebox_exports.String({
|
|
30025
|
-
description: "Required for status, result, and cancel. Must be a prefixed job ID such as sortie:<toolCallId>."
|
|
30026
|
-
})),
|
|
30027
|
-
format: typebox_exports.Optional(typebox_exports.Unsafe({
|
|
30028
|
-
type: "string",
|
|
30029
|
-
enum: ["summary", "full"],
|
|
30030
|
-
description: "Optional result detail level for renderers and result lookups."
|
|
30031
|
-
}))
|
|
30032
|
-
});
|
|
30033
|
-
}
|
|
30034
|
-
function buildCarrierJobsToolSpec() {
|
|
30035
|
-
return {
|
|
30036
|
-
...CARRIER_JOBS_DOCTRINE,
|
|
30037
|
-
parameters: buildCarrierJobsSchema(),
|
|
30038
|
-
async execute(args) {
|
|
30039
|
-
const result = dispatchCarrierJobsAction(args);
|
|
30040
|
-
return {
|
|
30041
|
-
content: [{ type: "text", text: JSON.stringify(result) }],
|
|
30042
|
-
isError: false,
|
|
30043
|
-
details: result
|
|
30044
|
-
};
|
|
30045
|
-
}
|
|
30046
|
-
};
|
|
30047
|
-
}
|
|
30048
|
-
function dispatchCarrierJobsAction(params, now = Date.now()) {
|
|
30049
|
-
if (params.action === "list") {
|
|
30050
|
-
return {
|
|
30051
|
-
action: "list",
|
|
30052
|
-
ok: true,
|
|
30053
|
-
active: listActiveJobs(),
|
|
30054
|
-
recent: listJobSummaries(now)
|
|
30055
|
-
};
|
|
30056
|
-
}
|
|
30057
|
-
const jobIdError = validateJobId(params.job_id);
|
|
30058
|
-
if (jobIdError) {
|
|
30059
|
-
return {
|
|
30060
|
-
action: params.action,
|
|
30061
|
-
job_id: params.job_id,
|
|
30062
|
-
ok: false,
|
|
30063
|
-
error: jobIdError
|
|
30064
|
-
};
|
|
30065
|
-
}
|
|
30066
|
-
const jobId = params.job_id;
|
|
30067
|
-
if (params.action === "status") return statusResponse(jobId, now);
|
|
30068
|
-
if (params.action === "result") return resultResponse(jobId, normalizeFormat(params.format), now);
|
|
30069
|
-
if (params.action === "cancel") return cancelResponse(jobId, now);
|
|
30070
|
-
return {
|
|
30071
|
-
action: String(params.action),
|
|
30072
|
-
job_id: jobId,
|
|
30073
|
-
ok: false,
|
|
30074
|
-
error: "unsupported action"
|
|
30075
|
-
};
|
|
30076
|
-
}
|
|
30077
29655
|
function sanitizeReminderText(text) {
|
|
30078
29656
|
return escapeXmlText(
|
|
30079
29657
|
text.replace(REMINDER_CONTROL_CHARS, " ").replace(REMINDER_WHITESPACE, " ").trim().slice(0, REMINDER_TEXT_LIMIT)
|
|
@@ -30091,131 +29669,8 @@ function escapeXmlAttribute(value) {
|
|
|
30091
29669
|
function escapeXmlText(value) {
|
|
30092
29670
|
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
30093
29671
|
}
|
|
30094
|
-
function statusResponse(jobId, now) {
|
|
30095
|
-
const active = getActiveJob(jobId);
|
|
30096
|
-
const summary = getJobSummary(jobId, now);
|
|
30097
|
-
const availability = getAvailability(jobId, summary, now);
|
|
30098
|
-
return {
|
|
30099
|
-
action: "status",
|
|
30100
|
-
job_id: jobId,
|
|
30101
|
-
ok: Boolean(active || summary || availability.full_available),
|
|
30102
|
-
status: active?.status ?? summary?.status ?? "not_found",
|
|
30103
|
-
summary: summary ?? void 0,
|
|
30104
|
-
notice: active ? ACTIVE_STATUS_NOTICE : void 0,
|
|
30105
|
-
...availability
|
|
30106
|
-
};
|
|
30107
|
-
}
|
|
30108
|
-
function resultResponse(jobId, format, now) {
|
|
30109
|
-
const active = getActiveJob(jobId);
|
|
30110
|
-
const summary = getJobSummary(jobId, now);
|
|
30111
|
-
const availability = getAvailability(jobId, summary, now);
|
|
30112
|
-
if (active) {
|
|
30113
|
-
return {
|
|
30114
|
-
action: "result",
|
|
30115
|
-
format,
|
|
30116
|
-
job_id: jobId,
|
|
30117
|
-
ok: false,
|
|
30118
|
-
status: active.status,
|
|
30119
|
-
summary: summary ?? void 0,
|
|
30120
|
-
...availability,
|
|
30121
|
-
error: "job not finalized",
|
|
30122
|
-
retry_after: "do not retry; wait for the [carrier:result] push that will arrive automatically when the job reaches done, error, or aborted.",
|
|
30123
|
-
notice: ACTIVE_STATUS_NOTICE
|
|
30124
|
-
};
|
|
30125
|
-
}
|
|
30126
|
-
if (format === "summary") {
|
|
30127
|
-
return {
|
|
30128
|
-
action: "result",
|
|
30129
|
-
format,
|
|
30130
|
-
job_id: jobId,
|
|
30131
|
-
ok: Boolean(summary),
|
|
30132
|
-
status: summary?.status ?? "not_found",
|
|
30133
|
-
summary: summary ?? void 0,
|
|
30134
|
-
...availability,
|
|
30135
|
-
error: summary ? void 0 : "summary unavailable or expired"
|
|
30136
|
-
};
|
|
30137
|
-
}
|
|
30138
|
-
const archive = getFinalized(jobId, now);
|
|
30139
|
-
const isTaskForceJob = jobId.startsWith("taskforce:");
|
|
30140
|
-
const isSubOpJob = isTaskForceJob;
|
|
30141
|
-
const serializeOpts = isSubOpJob ? { perSubOpMaxBytes: CARRIER_JOBS_PER_SUBOP_BYTE_CAP, maxBytes: CARRIER_JOBS_GLOBAL_BYTE_CAP } : { maxBytes: CARRIER_JOBS_FULL_RESULT_BYTE_CAP };
|
|
30142
|
-
const fullResult = archive ? serializeJobArchive(archive, serializeOpts) : void 0;
|
|
30143
|
-
return {
|
|
30144
|
-
action: "result",
|
|
30145
|
-
format,
|
|
30146
|
-
job_id: jobId,
|
|
30147
|
-
ok: Boolean(archive),
|
|
30148
|
-
status: archive?.status ?? summary?.status ?? "not_found",
|
|
30149
|
-
summary: summary ?? void 0,
|
|
30150
|
-
...availability,
|
|
30151
|
-
full_result: isTaskForceJob ? void 0 : fullResult,
|
|
30152
|
-
results: archive && isTaskForceJob ? serializeTaskForceResultsByBackend(archive) : void 0,
|
|
30153
|
-
error: archive ? void 0 : "full result unavailable or expired"
|
|
30154
|
-
};
|
|
30155
|
-
}
|
|
30156
|
-
function cancelResponse(jobId, now) {
|
|
30157
|
-
const result = cancelJob(jobId);
|
|
30158
|
-
const active = getActiveJob(jobId);
|
|
30159
|
-
const summary = getJobSummary(jobId, now);
|
|
30160
|
-
return {
|
|
30161
|
-
action: "cancel",
|
|
30162
|
-
job_id: jobId,
|
|
30163
|
-
ok: result.cancelled,
|
|
30164
|
-
cancelled: result.cancelled,
|
|
30165
|
-
status: result.cancelled ? "cancelled" : active?.status ?? summary?.status ?? "not_found",
|
|
30166
|
-
summary: summary ?? void 0,
|
|
30167
|
-
notice: !result.cancelled && active ? ACTIVE_CANCEL_NOTICE : void 0,
|
|
30168
|
-
...getAvailability(jobId, summary, now),
|
|
30169
|
-
error: result.cancelled ? void 0 : "job not found or already finished"
|
|
30170
|
-
};
|
|
30171
|
-
}
|
|
30172
|
-
function getAvailability(jobId, summary, now) {
|
|
30173
|
-
const fullAvailable = hasFinalizedJobArchive(jobId, now);
|
|
30174
|
-
return {
|
|
30175
|
-
summary_available: Boolean(summary),
|
|
30176
|
-
full_available: fullAvailable,
|
|
30177
|
-
full_invalidated: !hasJobArchive(jobId, now) && Boolean(summary)
|
|
30178
|
-
};
|
|
30179
|
-
}
|
|
30180
|
-
function validateJobId(jobId) {
|
|
30181
|
-
if (!jobId) return "job_id is required";
|
|
30182
|
-
if (!isCarrierJobId(jobId)) return "job_id must start with carrier:, sortie:, or taskforce:";
|
|
30183
|
-
return null;
|
|
30184
|
-
}
|
|
30185
|
-
function normalizeFormat(format) {
|
|
30186
|
-
return format === "summary" ? "summary" : "full";
|
|
30187
|
-
}
|
|
30188
|
-
function serializeTaskForceResultsByBackend(archive) {
|
|
30189
|
-
const grouped = /* @__PURE__ */ new Map();
|
|
30190
|
-
const orderedKeys = [];
|
|
30191
|
-
for (const block of archive.blocks) {
|
|
30192
|
-
if (!block.label) continue;
|
|
30193
|
-
if (!grouped.has(block.label)) {
|
|
30194
|
-
grouped.set(block.label, []);
|
|
30195
|
-
orderedKeys.push(block.label);
|
|
30196
|
-
}
|
|
30197
|
-
grouped.get(block.label).push(block);
|
|
30198
|
-
}
|
|
30199
|
-
const results = {};
|
|
30200
|
-
for (const cliType of orderedKeys) {
|
|
30201
|
-
const blocks = grouped.get(cliType);
|
|
30202
|
-
results[cliType] = serializeJobArchive(
|
|
30203
|
-
{ ...archive, blocks },
|
|
30204
|
-
{ maxBytes: CARRIER_JOBS_PER_SUBOP_BYTE_CAP }
|
|
30205
|
-
);
|
|
30206
|
-
}
|
|
30207
|
-
return results;
|
|
30208
|
-
}
|
|
30209
29672
|
|
|
30210
29673
|
// ../../packages/fleet-carriers/src/jobs/sanitize.ts
|
|
30211
|
-
var sanitize_exports = {};
|
|
30212
|
-
__export(sanitize_exports, {
|
|
30213
|
-
sanitizeChunk: () => sanitizeChunk,
|
|
30214
|
-
sanitizeOneLineText: () => sanitizeOneLineText,
|
|
30215
|
-
sanitizeToolBlockLabel: () => sanitizeToolBlockLabel,
|
|
30216
|
-
sanitizeToolLabel: () => sanitizeToolLabel,
|
|
30217
|
-
stripTerminalControlSequences: () => stripTerminalControlSequences
|
|
30218
|
-
});
|
|
30219
29674
|
var CONTROL_CHARS = /[\u0000-\u001f\u007f]/g;
|
|
30220
29675
|
var MULTILINE_CONTROL_CHARS = /[\u0000-\u0009\u000b-\u001f\u007f]/g;
|
|
30221
29676
|
var LINE_BREAKS = /[\r\n]+/g;
|
|
@@ -30301,84 +29756,17 @@ function isEscIntermediate(code) {
|
|
|
30301
29756
|
return code >= 32 && code <= 47;
|
|
30302
29757
|
}
|
|
30303
29758
|
|
|
30304
|
-
// ../../packages/fleet-carriers/src/jobs/workspace-manifest.ts
|
|
30305
|
-
var WORKSPACE_CHANGE_ATTRIBUTION = "window-approximate";
|
|
30306
|
-
var WORKSPACE_CHANGE_LIMIT = 200;
|
|
30307
|
-
var WORKSPACE_CHANGE_CLEARED_STATUS = "cleared";
|
|
30308
|
-
async function captureWorkspaceSnapshot(scanner, cwd) {
|
|
30309
|
-
if (!scanner) return null;
|
|
30310
|
-
try {
|
|
30311
|
-
return await scanner.snapshot(cwd);
|
|
30312
|
-
} catch {
|
|
30313
|
-
return null;
|
|
30314
|
-
}
|
|
30315
|
-
}
|
|
30316
|
-
async function captureJobWindowManifest(scanner, cwd, baseline) {
|
|
30317
|
-
if (!scanner) {
|
|
30318
|
-
return unavailableWorkspaceManifest("scanner-not-configured");
|
|
30319
|
-
}
|
|
30320
|
-
const end = await captureWorkspaceSnapshot(scanner, cwd);
|
|
30321
|
-
return buildWorkspaceManifest(baseline, end);
|
|
30322
|
-
}
|
|
30323
|
-
function buildWorkspaceManifest(baseline, end, reason) {
|
|
30324
|
-
if (!baseline || !end) {
|
|
30325
|
-
return unavailableWorkspaceManifest("snapshot-unavailable");
|
|
30326
|
-
}
|
|
30327
|
-
const baselineByPath = new Map(baseline.map((entry) => [entry.path, normalizeSnapshotEntry(entry)]));
|
|
30328
|
-
const endChanges = end.map(normalizeSnapshotEntry).filter((entry) => hasWindowChange(baselineByPath.get(entry.path), entry)).map(toManifestEntry);
|
|
30329
|
-
const endPaths = new Set(end.map((entry) => entry.path));
|
|
30330
|
-
const clearedChanges = [...baselineByPath.values()].filter((entry) => !endPaths.has(entry.path)).map((entry) => ({ status: WORKSPACE_CHANGE_CLEARED_STATUS, path: entry.path }));
|
|
30331
|
-
const changes = [...endChanges, ...clearedChanges];
|
|
30332
|
-
const truncated = changes.length > WORKSPACE_CHANGE_LIMIT;
|
|
30333
|
-
const capped = changes.slice(0, WORKSPACE_CHANGE_LIMIT);
|
|
30334
|
-
return {
|
|
30335
|
-
attribution: WORKSPACE_CHANGE_ATTRIBUTION,
|
|
30336
|
-
available: true,
|
|
30337
|
-
changes: capped,
|
|
30338
|
-
statLine: buildStatLine(changes.length, truncated),
|
|
30339
|
-
truncated
|
|
30340
|
-
};
|
|
30341
|
-
}
|
|
30342
|
-
function unavailableWorkspaceManifest(reason) {
|
|
30343
|
-
return {
|
|
30344
|
-
attribution: WORKSPACE_CHANGE_ATTRIBUTION,
|
|
30345
|
-
available: false,
|
|
30346
|
-
reason,
|
|
30347
|
-
changes: [],
|
|
30348
|
-
statLine: "unavailable",
|
|
30349
|
-
truncated: false
|
|
30350
|
-
};
|
|
30351
|
-
}
|
|
30352
|
-
function normalizeSnapshotEntry(entry) {
|
|
30353
|
-
return {
|
|
30354
|
-
status: entry.status.trim(),
|
|
30355
|
-
path: entry.path,
|
|
30356
|
-
contentHash: entry.contentHash?.trim()
|
|
30357
|
-
};
|
|
30358
|
-
}
|
|
30359
|
-
function toManifestEntry(entry) {
|
|
30360
|
-
return {
|
|
30361
|
-
status: entry.status,
|
|
30362
|
-
path: entry.path
|
|
30363
|
-
};
|
|
30364
|
-
}
|
|
30365
|
-
function hasWindowChange(baseline, end) {
|
|
30366
|
-
if (!baseline) return true;
|
|
30367
|
-
if (baseline.status !== end.status) return true;
|
|
30368
|
-
if (baseline.contentHash && end.contentHash) {
|
|
30369
|
-
return baseline.contentHash !== end.contentHash;
|
|
30370
|
-
}
|
|
30371
|
-
return false;
|
|
30372
|
-
}
|
|
30373
|
-
function buildStatLine(changeCount, truncated) {
|
|
30374
|
-
const suffix = changeCount === 1 ? "file" : "files";
|
|
30375
|
-
return `${truncated ? `${WORKSPACE_CHANGE_LIMIT}+` : String(changeCount)} ${suffix} (window-approx)`;
|
|
30376
|
-
}
|
|
30377
|
-
|
|
30378
29759
|
// ../../packages/fleet-carriers/src/dispatch/prompt.ts
|
|
30379
29760
|
var CARRIER_FLEET_BACKGROUND = String.raw`You are an autonomous agent (Carrier) operating within a coordinated multi-agent Fleet system. The Admiral, your superior, dispatches specialized tasks to you and synthesizes your output for the user. Below is your identity, operational permissions, behavioral principles, and required output format. Your assigned task arrives in the user message channel below.`;
|
|
29761
|
+
var COMMON_RESPONSE_PROTOCOL = `<response_protocol>
|
|
29762
|
+
Keep progress narration concise \u2014 at most one line per meaningful step. No verbose play-by-play or step-by-step essays (short streaming lines are acceptable for the live observation channel).
|
|
29763
|
+
|
|
29764
|
+
When the mission is complete, wrap the entire final output in a <report>...</report> tag and emit it exactly once, at the very end. The Admiral retrieves only the report block, so everything you need to convey \u2014 results, evidence, file paths, caveats \u2014 must be inside it. Your persona's output_format structure applies inside the report block as usual.
|
|
29765
|
+
|
|
29766
|
+
Do not mention or demonstrate the literal opening and closing report tag anywhere in the body outside that final block.
|
|
29767
|
+
</response_protocol>`;
|
|
30380
29768
|
function buildCarrierSystemPrompt(metadata) {
|
|
30381
|
-
const parts = [CARRIER_FLEET_BACKGROUND];
|
|
29769
|
+
const parts = [CARRIER_FLEET_BACKGROUND, COMMON_RESPONSE_PROTOCOL];
|
|
30382
29770
|
if (metadata) {
|
|
30383
29771
|
parts.push(`<your_identity>
|
|
30384
29772
|
${metadata.title}
|
|
@@ -30838,7 +30226,6 @@ function buildCarrierDispatchToolSpec(registry3, deps) {
|
|
|
30838
30226
|
});
|
|
30839
30227
|
}
|
|
30840
30228
|
const metadata = config2.carrierMetadata;
|
|
30841
|
-
const isNativeSubagentMode = isCarrierAgentModeSubagent(carrierId, config2.defaultAgentMode);
|
|
30842
30229
|
if (metadata) {
|
|
30843
30230
|
const blockValidation = validateRequiredRequestBlocks(metadata, request, carrierId);
|
|
30844
30231
|
if (!blockValidation.ok) {
|
|
@@ -30849,7 +30236,7 @@ function buildCarrierDispatchToolSpec(registry3, deps) {
|
|
|
30849
30236
|
});
|
|
30850
30237
|
}
|
|
30851
30238
|
}
|
|
30852
|
-
if (
|
|
30239
|
+
if (getConfiguredTaskForceBackends(carrierId).length >= 2) {
|
|
30853
30240
|
return launchTaskForceJob({
|
|
30854
30241
|
registry: registry3,
|
|
30855
30242
|
carrierId,
|
|
@@ -31084,7 +30471,6 @@ function resolveCarrierTrackModelInfo(registry3, carrierId) {
|
|
|
31084
30471
|
const modelConfig = loadCarrierStates({
|
|
31085
30472
|
[carrierId]: carrierConfig ? {
|
|
31086
30473
|
cliType,
|
|
31087
|
-
...carrierConfig.defaultAgentMode ? { defaultAgentMode: carrierConfig.defaultAgentMode } : {},
|
|
31088
30474
|
...carrierConfig.defaultEffort ? { defaultEffort: carrierConfig.defaultEffort } : {},
|
|
31089
30475
|
...carrierConfig.defaultModel ? { defaultModel: carrierConfig.defaultModel } : {}
|
|
31090
30476
|
} : cliType
|
|
@@ -31110,7 +30496,7 @@ function resolveDispatchCwd(rawCwd, fallbackCwd) {
|
|
|
31110
30496
|
if (rawCwd === void 0) return { ok: true, cwd: fallbackCwd };
|
|
31111
30497
|
const trimmed = rawCwd.trim();
|
|
31112
30498
|
if (trimmed.length === 0) return { ok: true, cwd: fallbackCwd };
|
|
31113
|
-
if (!
|
|
30499
|
+
if (!path25__default.isAbsolute(trimmed)) {
|
|
31114
30500
|
return {
|
|
31115
30501
|
ok: false,
|
|
31116
30502
|
error: `Invalid cwd "${rawCwd}": must be an absolute path. Provide an absolute directory or omit cwd to use the host session cwd.`
|
|
@@ -31172,593 +30558,11 @@ function formatRequestBlocksGuide(meta3) {
|
|
|
31172
30558
|
});
|
|
31173
30559
|
}
|
|
31174
30560
|
|
|
31175
|
-
// ../../packages/fleet-carriers/src/subagents/index.ts
|
|
31176
|
-
var subagents_exports = {};
|
|
31177
|
-
__export(subagents_exports, {
|
|
31178
|
-
CLAUDE_SUBAGENT_COLORS: () => CLAUDE_SUBAGENT_COLORS,
|
|
31179
|
-
buildClaudeSubagentDefinition: () => buildClaudeSubagentDefinition,
|
|
31180
|
-
buildClaudeSubagentDefinitions: () => buildClaudeSubagentDefinitions,
|
|
31181
|
-
buildClaudeSubagentName: () => buildClaudeSubagentName
|
|
31182
|
-
});
|
|
31183
|
-
|
|
31184
|
-
// ../../packages/fleet-carriers/src/subagents/claude.ts
|
|
31185
|
-
var NAME_SEGMENT_SPLIT_PATTERN = /[^a-zA-Z0-9]+/;
|
|
31186
|
-
var CLAUDE_MAX_EFFORT = "xhigh";
|
|
31187
|
-
var CLAUDE_SUBAGENT_COLORS = {
|
|
31188
|
-
nimitz: "blue",
|
|
31189
|
-
vanguard: "cyan",
|
|
31190
|
-
chronicle: "green",
|
|
31191
|
-
genesis: "orange",
|
|
31192
|
-
kirov: "purple",
|
|
31193
|
-
ohio: "yellow",
|
|
31194
|
-
sentinel: "red",
|
|
31195
|
-
tempest: "pink"
|
|
31196
|
-
};
|
|
31197
|
-
function buildClaudeSubagentDefinitions(options) {
|
|
31198
|
-
const enabled = new Set(options.enabledCarrierIds);
|
|
31199
|
-
return options.carrierConfigs.filter((config2) => enabled.has(config2.id)).map((config2) => buildClaudeSubagentDefinition(config2));
|
|
31200
|
-
}
|
|
31201
|
-
function buildClaudeSubagentDefinition(config2) {
|
|
31202
|
-
const color = CLAUDE_SUBAGENT_COLORS[config2.id];
|
|
31203
|
-
const effort = getClaudeEffort(config2);
|
|
31204
|
-
const model = getClaudeModel(config2);
|
|
31205
|
-
const definition = {
|
|
31206
|
-
carrierId: config2.id,
|
|
31207
|
-
...color ? { color } : {},
|
|
31208
|
-
description: buildDescription(config2),
|
|
31209
|
-
...effort ? { effort } : {},
|
|
31210
|
-
...model ? { model } : {},
|
|
31211
|
-
name: buildClaudeSubagentName(config2.id),
|
|
31212
|
-
prompt: buildCarrierSystemPrompt(config2.carrierMetadata)
|
|
31213
|
-
};
|
|
31214
|
-
return definition;
|
|
31215
|
-
}
|
|
31216
|
-
function buildClaudeSubagentName(carrierId) {
|
|
31217
|
-
const lowerCaseName = carrierId.split(NAME_SEGMENT_SPLIT_PATTERN).filter((segment) => segment.length > 0).map((segment) => segment.toLowerCase()).join("");
|
|
31218
|
-
return lowerCaseName || "carrier";
|
|
31219
|
-
}
|
|
31220
|
-
function buildDescription(config2) {
|
|
31221
|
-
const metadata = config2.carrierMetadata;
|
|
31222
|
-
const parts = [
|
|
31223
|
-
config2.displayName,
|
|
31224
|
-
metadata?.title,
|
|
31225
|
-
metadata?.summary,
|
|
31226
|
-
metadata?.whenToUse?.length ? `Use for: ${metadata.whenToUse.join(", ")}.` : void 0
|
|
31227
|
-
];
|
|
31228
|
-
return parts.filter((part) => typeof part === "string" && part.trim().length > 0).join(" - ").replace(/\s+/g, " ").trim();
|
|
31229
|
-
}
|
|
31230
|
-
function getClaudeEffort(config2) {
|
|
31231
|
-
const effort = config2.subagent?.byHost?.claude?.defaultEffort ?? config2.subagent?.defaultEffort;
|
|
31232
|
-
return clampClaudeEffort(effort);
|
|
31233
|
-
}
|
|
31234
|
-
function getClaudeModel(config2) {
|
|
31235
|
-
return config2.subagent?.byHost?.claude?.defaultModel ?? config2.subagent?.defaultModel;
|
|
31236
|
-
}
|
|
31237
|
-
function clampClaudeEffort(effort) {
|
|
31238
|
-
return effort === "max" ? CLAUDE_MAX_EFFORT : effort;
|
|
31239
|
-
}
|
|
31240
|
-
|
|
31241
30561
|
// ../../packages/fleet-carriers/src/index.ts
|
|
31242
|
-
var dispatch = {
|
|
31243
|
-
...framework_exports,
|
|
31244
|
-
framework: framework_exports,
|
|
31245
|
-
statusOverlayController: status_overlay_exports,
|
|
31246
|
-
taskforce: taskforce_exports,
|
|
31247
|
-
toolSpec: tool_spec_exports,
|
|
31248
|
-
types: types_exports,
|
|
31249
|
-
buildToolSpecs: buildCarrierDispatchToolSpec
|
|
31250
|
-
};
|
|
31251
|
-
var jobs = {
|
|
31252
|
-
archive: archive_exports,
|
|
31253
|
-
dispatch: dispatch_exports,
|
|
31254
|
-
lifecycle: lifecycle_exports,
|
|
31255
|
-
sanitize: sanitize_exports,
|
|
31256
|
-
types: types_exports2,
|
|
31257
|
-
buildToolSpec: buildCarrierJobsToolSpec,
|
|
31258
|
-
configureJobSummaryCache,
|
|
31259
|
-
detachJobArchive,
|
|
31260
|
-
acquireJobPermit,
|
|
31261
|
-
getActiveBackgroundJobCount,
|
|
31262
|
-
onActiveJobCountChange,
|
|
31263
|
-
resetJobConcurrencyForTest,
|
|
31264
|
-
streaming: {
|
|
31265
|
-
register: registerStreamHandler,
|
|
31266
|
-
unregister: unregisterStreamHandler,
|
|
31267
|
-
emit: emitStreamEvent
|
|
31268
|
-
}
|
|
31269
|
-
};
|
|
31270
|
-
function createCarrierRuntime() {
|
|
31271
|
-
const registry3 = createCarrierRegistry();
|
|
31272
|
-
const boundStream = createBoundCarrierStream(registry3);
|
|
31273
|
-
const boundCarrierJobs = createBoundCarrierJobs(registry3, boundStream);
|
|
31274
|
-
return {
|
|
31275
|
-
registry: registry3,
|
|
31276
|
-
dispatch,
|
|
31277
|
-
jobs: boundCarrierJobs,
|
|
31278
|
-
personas: personas_exports,
|
|
31279
|
-
subagents: subagents_exports,
|
|
31280
|
-
store: store_exports,
|
|
31281
|
-
stream: boundStream,
|
|
31282
|
-
registerCarrierDefaults() {
|
|
31283
|
-
registerDefaultCarriers(registry3);
|
|
31284
|
-
}
|
|
31285
|
-
};
|
|
31286
|
-
}
|
|
31287
|
-
function createBoundCarrierStream(registry3) {
|
|
31288
|
-
return {
|
|
31289
|
-
register(handler) {
|
|
31290
|
-
return registerStreamHandler(registry3, handler);
|
|
31291
|
-
},
|
|
31292
|
-
unregister(handler) {
|
|
31293
|
-
unregisterStreamHandler(registry3, handler);
|
|
31294
|
-
},
|
|
31295
|
-
emit(event) {
|
|
31296
|
-
emitStreamEvent(registry3, event);
|
|
31297
|
-
}
|
|
31298
|
-
};
|
|
31299
|
-
}
|
|
31300
|
-
function createBoundCarrierJobs(registry3, boundStream = createBoundCarrierStream(registry3)) {
|
|
31301
|
-
return {
|
|
31302
|
-
...jobs,
|
|
31303
|
-
streaming: boundStream
|
|
31304
|
-
};
|
|
31305
|
-
}
|
|
31306
|
-
|
|
31307
|
-
// core/host/hooks/subagents-context.ts
|
|
31308
|
-
var FLEET_PLUGIN_NAME = "fleet";
|
|
31309
|
-
function runSubagentsContextHook(env) {
|
|
31310
|
-
const fleetRoot = env.FLEET_ROOT ?? path26__default.join(env.HOME ?? os3__default.homedir(), ".fleet");
|
|
31311
|
-
if (!canReadCarrierState(path26__default.join(fleetRoot, "carriers.json"))) {
|
|
31312
|
-
return JSON.stringify({ hookSpecificOutput: { hookEventName: "SessionStart", additionalContext: "" } });
|
|
31313
|
-
}
|
|
31314
|
-
const carrierRuntime = createCarrierRuntime();
|
|
31315
|
-
carrierRuntime.store.initStore(fleetRoot);
|
|
31316
|
-
carrierRuntime.registerCarrierDefaults();
|
|
31317
|
-
const { carrierConfigs, definitions } = buildClaudeNativeSubagentPlan(carrierRuntime.registry);
|
|
31318
|
-
const configsById = new Map(carrierConfigs.map((config2) => [config2.id, config2]));
|
|
31319
|
-
const additionalContext = buildSubagentsSection(definitions.map((definition) => ({
|
|
31320
|
-
carrierId: definition.carrierId,
|
|
31321
|
-
displayName: configsById.get(definition.carrierId)?.displayName,
|
|
31322
|
-
nativeName: `${FLEET_PLUGIN_NAME}:${definition.name}`
|
|
31323
|
-
}))) ?? "";
|
|
31324
|
-
return JSON.stringify({ hookSpecificOutput: { hookEventName: "SessionStart", additionalContext } });
|
|
31325
|
-
}
|
|
31326
|
-
function buildClaudeNativeSubagentPlan(registry3) {
|
|
31327
|
-
const carrierIds = getRegisteredOrder(registry3);
|
|
31328
|
-
const carrierConfigs = carrierIds.map((carrierId) => getCarrierConfig(registry3, carrierId)).filter((config2) => config2 !== void 0);
|
|
31329
|
-
const defaultsByCarrier = Object.fromEntries(
|
|
31330
|
-
carrierConfigs.map((config2) => [config2.id, buildHostCarrierModelDefaults(config2)])
|
|
31331
|
-
);
|
|
31332
|
-
const enabledCarrierIds = getEnabledCarrierSubagentIds(
|
|
31333
|
-
readCarrierAgentModeSnapshot(defaultsByCarrier),
|
|
31334
|
-
carrierIds
|
|
31335
|
-
);
|
|
31336
|
-
return {
|
|
31337
|
-
carrierConfigs,
|
|
31338
|
-
definitions: buildClaudeSubagentDefinitions({ carrierConfigs, enabledCarrierIds })
|
|
31339
|
-
};
|
|
31340
|
-
}
|
|
31341
|
-
function buildHostCarrierModelDefaults(config2) {
|
|
31342
|
-
const cliType = resolveAgentCliType2(config2.id, config2.defaultCliType);
|
|
31343
|
-
const cliDefaults = buildCarrierModelDefaults(config2, cliType);
|
|
31344
|
-
return {
|
|
31345
|
-
cliType,
|
|
31346
|
-
...config2.defaultAgentMode ? { defaultAgentMode: config2.defaultAgentMode } : {},
|
|
31347
|
-
...cliDefaults.defaultEffort ? { defaultEffort: cliDefaults.defaultEffort } : {},
|
|
31348
|
-
...cliDefaults.defaultModel ? { defaultModel: cliDefaults.defaultModel } : {}
|
|
31349
|
-
};
|
|
31350
|
-
}
|
|
31351
|
-
function buildSubagentsSection(entries) {
|
|
31352
|
-
if (entries.length === 0) return void 0;
|
|
31353
|
-
const lines = entries.map((entry) => {
|
|
31354
|
-
const label = entry.displayName ? `${entry.displayName} (${entry.carrierId})` : entry.carrierId;
|
|
31355
|
-
return `- ${label}: invoke as Claude native subagent \`${entry.nativeName}\`.`;
|
|
31356
|
-
}).join("\n");
|
|
31357
|
-
return `<fleet section="subagents">
|
|
31358
|
-
# Claude Native Subagents
|
|
31359
|
-
|
|
31360
|
-
The following Fleet carriers are exposed as Claude native subagents for this session:
|
|
31361
|
-
|
|
31362
|
-
${lines}
|
|
31363
|
-
|
|
31364
|
-
Native subagent calls return inline and do not emit \`[carrier:result]\`. Do not wait for a carrier job completion push after native invocation.
|
|
31365
|
-
|
|
31366
|
-
\`carrier_dispatch\` remains available as a separate Fleet delegation path for carriers that are not invoked through the native subagent interface.
|
|
31367
|
-
</fleet>`;
|
|
31368
|
-
}
|
|
31369
|
-
function canReadCarrierState(filePath) {
|
|
31370
|
-
try {
|
|
31371
|
-
return isReadableCarrierStateRoot(JSON.parse(readFileSync(filePath, "utf8")));
|
|
31372
|
-
} catch {
|
|
31373
|
-
return false;
|
|
31374
|
-
}
|
|
31375
|
-
}
|
|
31376
|
-
function isReadableCarrierStateRoot(value) {
|
|
31377
|
-
if (!isRecord2(value)) return false;
|
|
31378
|
-
const carriers = value.carriers;
|
|
31379
|
-
return carriers === void 0 || isRecord2(carriers);
|
|
31380
|
-
}
|
|
31381
|
-
function isRecord2(value) {
|
|
31382
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
31383
|
-
}
|
|
31384
|
-
var LOCK_DIR_MODE = 448;
|
|
31385
|
-
var LOCK_FILE_MODE = 384;
|
|
31386
|
-
function createConsoleLock(deps = {}) {
|
|
31387
|
-
const fsImpl = deps.fs ?? fs11__default;
|
|
31388
|
-
const now = deps.now ?? Date.now;
|
|
31389
|
-
const randomToken = deps.randomToken ?? (() => crypto5.randomBytes(32).toString("base64url"));
|
|
31390
|
-
const hostname5 = deps.hostname ?? (() => "127.0.0.1");
|
|
31391
|
-
function ensureLockDir(dir) {
|
|
31392
|
-
fsImpl.mkdirSync(dir, { recursive: true, mode: LOCK_DIR_MODE });
|
|
31393
|
-
fsImpl.chmodSync(dir, LOCK_DIR_MODE);
|
|
31394
|
-
}
|
|
31395
|
-
function readLock(lockFile) {
|
|
31396
|
-
try {
|
|
31397
|
-
const stat5 = fsImpl.lstatSync(lockFile);
|
|
31398
|
-
if (stat5.isSymbolicLink()) {
|
|
31399
|
-
throw new Error(`Refusing symbolic console lock: ${lockFile}`);
|
|
31400
|
-
}
|
|
31401
|
-
return JSON.parse(fsImpl.readFileSync(lockFile, "utf8"));
|
|
31402
|
-
} catch (err) {
|
|
31403
|
-
if (err.code === "ENOENT") return null;
|
|
31404
|
-
throw err;
|
|
31405
|
-
}
|
|
31406
|
-
}
|
|
31407
|
-
function writeLock(input) {
|
|
31408
|
-
ensureLockDir(input.dir);
|
|
31409
|
-
const payload = {
|
|
31410
|
-
pid: input.pid,
|
|
31411
|
-
host: hostname5(),
|
|
31412
|
-
port: input.port,
|
|
31413
|
-
endpoint: input.endpoint,
|
|
31414
|
-
startedAt: now(),
|
|
31415
|
-
token: randomToken(),
|
|
31416
|
-
version: input.version
|
|
31417
|
-
};
|
|
31418
|
-
const fd = fsImpl.openSync(input.lockFile, fs11__default.constants.O_CREAT | fs11__default.constants.O_EXCL | fs11__default.constants.O_WRONLY, LOCK_FILE_MODE);
|
|
31419
|
-
try {
|
|
31420
|
-
fsImpl.writeFileSync(fd, `${JSON.stringify(payload, null, 2)}
|
|
31421
|
-
`, "utf8");
|
|
31422
|
-
fsImpl.fchmodSync(fd, LOCK_FILE_MODE);
|
|
31423
|
-
} finally {
|
|
31424
|
-
fsImpl.closeSync(fd);
|
|
31425
|
-
}
|
|
31426
|
-
return { payload, release: () => removeLock(input.lockFile, payload.pid) };
|
|
31427
|
-
}
|
|
31428
|
-
function removeLock(lockFile, pid) {
|
|
31429
|
-
let current = null;
|
|
31430
|
-
try {
|
|
31431
|
-
current = readLock(lockFile);
|
|
31432
|
-
} catch (err) {
|
|
31433
|
-
if (pid != null) throw err;
|
|
31434
|
-
}
|
|
31435
|
-
if (pid != null && current && current.pid !== pid) return;
|
|
31436
|
-
try {
|
|
31437
|
-
fsImpl.rmSync(lockFile, { force: true });
|
|
31438
|
-
} catch (err) {
|
|
31439
|
-
if (err.code !== "ENOENT") throw err;
|
|
31440
|
-
}
|
|
31441
|
-
}
|
|
31442
|
-
function assertLockModes(lockFile) {
|
|
31443
|
-
if (typeof process.getuid !== "function") return;
|
|
31444
|
-
const dir = path26__default.dirname(lockFile);
|
|
31445
|
-
const dirMode = fsImpl.statSync(dir).mode & 511;
|
|
31446
|
-
const fileMode = fsImpl.statSync(lockFile).mode & 511;
|
|
31447
|
-
if (dirMode !== LOCK_DIR_MODE) {
|
|
31448
|
-
throw new Error(`Console lock directory mode must be 0700, got ${dirMode.toString(8)}`);
|
|
31449
|
-
}
|
|
31450
|
-
if (fileMode !== LOCK_FILE_MODE) {
|
|
31451
|
-
throw new Error(`Console lock file mode must be 0600, got ${fileMode.toString(8)}`);
|
|
31452
|
-
}
|
|
31453
|
-
}
|
|
31454
|
-
function assertTrustedLock(input) {
|
|
31455
|
-
const dirStat = fsImpl.statSync(input.dir);
|
|
31456
|
-
const fileStat = fsImpl.lstatSync(input.lockFile);
|
|
31457
|
-
if (fileStat.isSymbolicLink()) {
|
|
31458
|
-
throw new Error(`Refusing symbolic console lock: ${input.lockFile}`);
|
|
31459
|
-
}
|
|
31460
|
-
assertLockModes(input.lockFile);
|
|
31461
|
-
const currentUid = typeof process.getuid === "function" ? process.getuid() : null;
|
|
31462
|
-
if (currentUid != null && (dirStat.uid !== currentUid || fileStat.uid !== currentUid)) {
|
|
31463
|
-
throw new Error("Console lock owner does not match current user");
|
|
31464
|
-
}
|
|
31465
|
-
if (input.payload.host !== input.host) {
|
|
31466
|
-
throw new Error(`Console lock host must match ${input.host}: ${input.payload.host}`);
|
|
31467
|
-
}
|
|
31468
|
-
if (!Number.isInteger(input.payload.port) || input.payload.port < 1 || input.payload.port > 65535) {
|
|
31469
|
-
throw new Error(`Console lock port must be a valid TCP port, got ${input.payload.port}`);
|
|
31470
|
-
}
|
|
31471
|
-
const endpoint = new URL(input.payload.endpoint);
|
|
31472
|
-
if (endpoint.protocol !== "http:" || endpoint.pathname !== "/") {
|
|
31473
|
-
throw new Error("Console lock endpoint must be the loopback server root");
|
|
31474
|
-
}
|
|
31475
|
-
if (endpoint.hostname !== input.host || Number(endpoint.port) !== input.payload.port) {
|
|
31476
|
-
throw new Error("Console lock endpoint must use the loopback host and the lock port");
|
|
31477
|
-
}
|
|
31478
|
-
if (input.payload.endpoint !== `http://${input.host}:${input.payload.port}/`) {
|
|
31479
|
-
throw new Error("Console lock endpoint must match the lock host and port");
|
|
31480
|
-
}
|
|
31481
|
-
}
|
|
31482
|
-
return { ensureLockDir, readLock, writeLock, removeLock, assertLockModes, assertTrustedLock };
|
|
31483
|
-
}
|
|
31484
|
-
var FLEET_DATA_DIR_NAME = ".fleet";
|
|
31485
|
-
function getFleetDataDir() {
|
|
31486
|
-
return path26.join(os3.homedir(), FLEET_DATA_DIR_NAME);
|
|
31487
|
-
}
|
|
31488
|
-
function readAuthStoreFile(filePath) {
|
|
31489
|
-
let fd;
|
|
31490
|
-
try {
|
|
31491
|
-
fd = fs11.openSync(filePath, fs11.constants.O_RDONLY | NOFOLLOW_FLAG);
|
|
31492
|
-
if (!fs11.fstatSync(fd).isFile()) {
|
|
31493
|
-
return {};
|
|
31494
|
-
}
|
|
31495
|
-
return JSON.parse(fs11.readFileSync(fd, "utf-8"));
|
|
31496
|
-
} catch {
|
|
31497
|
-
return {};
|
|
31498
|
-
} finally {
|
|
31499
|
-
if (fd !== void 0) {
|
|
31500
|
-
try {
|
|
31501
|
-
fs11.closeSync(fd);
|
|
31502
|
-
} catch {
|
|
31503
|
-
}
|
|
31504
|
-
}
|
|
31505
|
-
}
|
|
31506
|
-
}
|
|
31507
|
-
|
|
31508
|
-
// ../../packages/fleet-infra/src/auth/auth-storage.ts
|
|
31509
|
-
var DEFAULT_AUTH_PATH = path26.join(getFleetDataDir(), "auth.json");
|
|
31510
|
-
var AUTH_LOCK_OWNER_FILE_NAME = "owner.json";
|
|
31511
|
-
var AUTH_LOCK_TIMEOUT_MS = 5e3;
|
|
31512
|
-
function createAuthService(deps = {}) {
|
|
31513
|
-
const authPath = deps.authPath ?? DEFAULT_AUTH_PATH;
|
|
31514
|
-
const lockDir = `${authPath}.lock`;
|
|
31515
|
-
return {
|
|
31516
|
-
// [HIGH #1] TOCTOU 수정: existsSync/read/check/delete/write 전체를 락 블록 안으로 이동
|
|
31517
|
-
async deleteApiKey(providerId) {
|
|
31518
|
-
let deleted = false;
|
|
31519
|
-
withAuthLock(authPath, lockDir, () => {
|
|
31520
|
-
if (!fs11.existsSync(authPath)) return;
|
|
31521
|
-
const data = readAuthStoreFile(authPath);
|
|
31522
|
-
if (!Object.prototype.hasOwnProperty.call(data, providerId)) return;
|
|
31523
|
-
delete data[providerId];
|
|
31524
|
-
writeAuthData(authPath, data);
|
|
31525
|
-
deleted = true;
|
|
31526
|
-
});
|
|
31527
|
-
return deleted;
|
|
31528
|
-
},
|
|
31529
|
-
// [HIGH #2] 읽기 경로: fd 기반 O_RDONLY|O_NOFOLLOW+fstatSync isFile
|
|
31530
|
-
async getApiKey(providerId) {
|
|
31531
|
-
let fd;
|
|
31532
|
-
try {
|
|
31533
|
-
if (!fs11.existsSync(authPath)) {
|
|
31534
|
-
return void 0;
|
|
31535
|
-
}
|
|
31536
|
-
fd = fs11.openSync(authPath, fs11.constants.O_RDONLY | NOFOLLOW_FLAG);
|
|
31537
|
-
if (!fs11.fstatSync(fd).isFile()) {
|
|
31538
|
-
return void 0;
|
|
31539
|
-
}
|
|
31540
|
-
const data = JSON.parse(fs11.readFileSync(fd, "utf-8"));
|
|
31541
|
-
return typeof data[providerId]?.key === "string" ? data[providerId].key : void 0;
|
|
31542
|
-
} catch {
|
|
31543
|
-
return void 0;
|
|
31544
|
-
} finally {
|
|
31545
|
-
if (fd !== void 0) {
|
|
31546
|
-
try {
|
|
31547
|
-
fs11.closeSync(fd);
|
|
31548
|
-
} catch {
|
|
31549
|
-
}
|
|
31550
|
-
}
|
|
31551
|
-
}
|
|
31552
|
-
},
|
|
31553
|
-
// [HIGH #2] 읽기 경로: fd 기반 O_RDONLY|O_NOFOLLOW 통일
|
|
31554
|
-
async listProviderIds() {
|
|
31555
|
-
if (!fs11.existsSync(authPath)) {
|
|
31556
|
-
return [];
|
|
31557
|
-
}
|
|
31558
|
-
try {
|
|
31559
|
-
return Object.keys(readAuthStoreFile(authPath)).sort();
|
|
31560
|
-
} catch {
|
|
31561
|
-
return [];
|
|
31562
|
-
}
|
|
31563
|
-
},
|
|
31564
|
-
async setApiKey(providerId, key) {
|
|
31565
|
-
const dir = path26.dirname(authPath);
|
|
31566
|
-
ensureSafeDirectory(dir);
|
|
31567
|
-
withAuthLock(authPath, lockDir, () => {
|
|
31568
|
-
const data = fs11.existsSync(authPath) ? readAuthStoreFile(authPath) : {};
|
|
31569
|
-
data[providerId] = {
|
|
31570
|
-
...data[providerId] ?? {},
|
|
31571
|
-
key
|
|
31572
|
-
};
|
|
31573
|
-
writeAuthData(authPath, data);
|
|
31574
|
-
});
|
|
31575
|
-
}
|
|
31576
|
-
};
|
|
31577
|
-
}
|
|
31578
|
-
function withAuthLock(authPath, lockDir, operation) {
|
|
31579
|
-
return withDirectoryLock(
|
|
31580
|
-
{
|
|
31581
|
-
lockDir,
|
|
31582
|
-
ownerFileName: AUTH_LOCK_OWNER_FILE_NAME,
|
|
31583
|
-
timeoutMs: AUTH_LOCK_TIMEOUT_MS
|
|
31584
|
-
},
|
|
31585
|
-
operation
|
|
31586
|
-
);
|
|
31587
|
-
}
|
|
31588
|
-
function writeAuthData(authPath, data) {
|
|
31589
|
-
writeAtomicSync(authPath, `${JSON.stringify(data, null, 2)}
|
|
31590
|
-
`, {
|
|
31591
|
-
mode: SECURE_FILE_MODE,
|
|
31592
|
-
fsync: true
|
|
31593
|
-
});
|
|
31594
|
-
}
|
|
31595
|
-
var GLOBAL_OPTIONS_VERSION = 1;
|
|
31596
|
-
var GLOBAL_OPTIONS_FILE_NAME = "settings.json";
|
|
31597
|
-
var LOCK_DIR_NAME = "settings.json.lock";
|
|
31598
|
-
var LOCK_OWNER_FILE_NAME = "owner";
|
|
31599
|
-
var TEMP_FILE_PREFIX = `.tmp-${GLOBAL_OPTIONS_FILE_NAME}-`;
|
|
31600
|
-
function createGlobalOptionsStore(deps = {}) {
|
|
31601
|
-
const dataDir = deps.dataDir ?? getFleetDataDir();
|
|
31602
|
-
const optionsPath = path26.join(dataDir, GLOBAL_OPTIONS_FILE_NAME);
|
|
31603
|
-
const lockDir = path26.join(dataDir, LOCK_DIR_NAME);
|
|
31604
|
-
const store2 = createDurableJsonStore({
|
|
31605
|
-
filePath: optionsPath,
|
|
31606
|
-
lockDir,
|
|
31607
|
-
lockOwnerFileName: LOCK_OWNER_FILE_NAME,
|
|
31608
|
-
sanitize: (value) => sanitizeGlobalOptionsData(value).data,
|
|
31609
|
-
sensitivity: "sensitive",
|
|
31610
|
-
timeoutMs: deps.timeoutMs,
|
|
31611
|
-
staleLockMs: deps.staleLockMs,
|
|
31612
|
-
tempCleanupPrefix: TEMP_FILE_PREFIX,
|
|
31613
|
-
now: deps.now
|
|
31614
|
-
});
|
|
31615
|
-
return {
|
|
31616
|
-
path: optionsPath,
|
|
31617
|
-
load: () => store2.load(),
|
|
31618
|
-
save: (data) => store2.save(sanitizeGlobalOptionsData(data).data),
|
|
31619
|
-
update: (mutate) => store2.update((current) => sanitizeGlobalOptionsData(mutate(current)).data)
|
|
31620
|
-
};
|
|
31621
|
-
}
|
|
31622
|
-
function createEmptyGlobalOptionsData() {
|
|
31623
|
-
return {
|
|
31624
|
-
version: GLOBAL_OPTIONS_VERSION
|
|
31625
|
-
};
|
|
31626
|
-
}
|
|
31627
|
-
function sanitizeGlobalOptionsData(value) {
|
|
31628
|
-
if (!isRecord3(value)) {
|
|
31629
|
-
return { data: createEmptyGlobalOptionsData(), changed: true };
|
|
31630
|
-
}
|
|
31631
|
-
if (value.version !== GLOBAL_OPTIONS_VERSION) {
|
|
31632
|
-
return { data: createEmptyGlobalOptionsData(), changed: true };
|
|
31633
|
-
}
|
|
31634
|
-
const data = {
|
|
31635
|
-
version: GLOBAL_OPTIONS_VERSION,
|
|
31636
|
-
...typeof value.replaceSystemPrompt === "boolean" ? { replaceSystemPrompt: value.replaceSystemPrompt } : {},
|
|
31637
|
-
...typeof value.enableMetaphor === "boolean" ? { enableMetaphor: value.enableMetaphor } : {}
|
|
31638
|
-
};
|
|
31639
|
-
const allowedKeys = /* @__PURE__ */ new Set(["version", "replaceSystemPrompt", "enableMetaphor"]);
|
|
31640
|
-
const changed = Object.keys(value).some((key) => !allowedKeys.has(key)) || "replaceSystemPrompt" in value && typeof value.replaceSystemPrompt !== "boolean" || "enableMetaphor" in value && typeof value.enableMetaphor !== "boolean";
|
|
31641
|
-
return { data, changed };
|
|
31642
|
-
}
|
|
31643
|
-
function isRecord3(value) {
|
|
31644
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
31645
|
-
}
|
|
31646
|
-
|
|
31647
|
-
// ../../packages/fleet-infra/src/global-options/service.ts
|
|
31648
|
-
function createGlobalOptionsService(deps = {}) {
|
|
31649
|
-
const store2 = deps.store ?? createGlobalOptionsStore({ dataDir: deps.dataDir });
|
|
31650
|
-
return {
|
|
31651
|
-
load: () => store2.load(),
|
|
31652
|
-
save: (data) => {
|
|
31653
|
-
store2.save(data);
|
|
31654
|
-
return store2.load();
|
|
31655
|
-
},
|
|
31656
|
-
update: (mutate) => updateGlobalOptions(store2, mutate)
|
|
31657
|
-
};
|
|
31658
|
-
}
|
|
31659
|
-
function updateGlobalOptions(store2, mutate) {
|
|
31660
|
-
return store2.update(mutate);
|
|
31661
|
-
}
|
|
31662
30562
|
({
|
|
31663
|
-
|
|
31664
|
-
baseUrl: CLI_BACKENDS["claude-zai"].defaultEnv.ANTHROPIC_BASE_URL,
|
|
31665
|
-
env: CLI_BACKENDS["claude-zai"].defaultEnv
|
|
31666
|
-
},
|
|
31667
|
-
"claude-kimi": {
|
|
31668
|
-
baseUrl: CLI_BACKENDS["claude-kimi"].defaultEnv.ANTHROPIC_BASE_URL,
|
|
31669
|
-
env: CLI_BACKENDS["claude-kimi"].defaultEnv
|
|
31670
|
-
},
|
|
31671
|
-
"claude-glm": {
|
|
31672
|
-
baseUrl: CLI_BACKENDS["claude-glm"].defaultEnv.ANTHROPIC_BASE_URL,
|
|
31673
|
-
env: CLI_BACKENDS["claude-glm"].defaultEnv
|
|
31674
|
-
}
|
|
31675
|
-
});
|
|
31676
|
-
|
|
31677
|
-
// ../../packages/fleet-infra/src/index.ts
|
|
31678
|
-
function createInfraServices(deps = {}) {
|
|
31679
|
-
const globalOptionsService = createGlobalOptionsService();
|
|
31680
|
-
const authService = createAuthService({ authPath: deps.authPath ?? DEFAULT_AUTH_PATH });
|
|
31681
|
-
return {
|
|
31682
|
-
authService,
|
|
31683
|
-
globalOptionsService
|
|
31684
|
-
};
|
|
31685
|
-
}
|
|
31686
|
-
function readFleetConsoleRelease() {
|
|
31687
|
-
const requireFromHere = createRequire(import.meta.url);
|
|
31688
|
-
const packageJsonPath = resolvePackageJsonPath(requireFromHere);
|
|
31689
|
-
const pkg = requireFromHere(packageJsonPath);
|
|
31690
|
-
const packageRoot = path26__default.dirname(packageJsonPath);
|
|
31691
|
-
const version2 = pkg.version ?? "";
|
|
31692
|
-
if (pkg.private === true) {
|
|
31693
|
-
return { channel: "local", version: version2, packageRoot };
|
|
31694
|
-
}
|
|
31695
|
-
return { channel: "stable", version: version2, packageRoot };
|
|
31696
|
-
}
|
|
31697
|
-
function resolvePackageJsonPath(requireFromHere) {
|
|
31698
|
-
for (const candidate of ["../package.json", "../../package.json"]) {
|
|
31699
|
-
try {
|
|
31700
|
-
return requireFromHere.resolve(candidate);
|
|
31701
|
-
} catch (error51) {
|
|
31702
|
-
if (error51.code !== "MODULE_NOT_FOUND") throw error51;
|
|
31703
|
-
}
|
|
31704
|
-
}
|
|
31705
|
-
throw new Error("fleet_console_package_json_not_found");
|
|
31706
|
-
}
|
|
31707
|
-
|
|
31708
|
-
// core/host/paths.ts
|
|
31709
|
-
var LOCK_DIR_NAME2 = "fleet-console";
|
|
31710
|
-
var CONSOLE_RUNTIME_DIR_NAME = "console";
|
|
31711
|
-
var LOCK_FILE_NAME = "console.lock";
|
|
31712
|
-
var CONSOLE_DATA_DIR_NAME = "console";
|
|
31713
|
-
var CONSOLE_STATE_FILE_NAME = "state.json";
|
|
31714
|
-
var CONSOLE_SETTINGS_FILE_NAME = "settings.json";
|
|
31715
|
-
var CONSOLE_CAPTURES_DIR_NAME = "captures";
|
|
31716
|
-
function createConsolePaths(deps = {}) {
|
|
31717
|
-
const env = deps.env ?? process.env;
|
|
31718
|
-
const base = env.FLEET_CONSOLE_DIR ?? defaultConsoleBaseDir(deps);
|
|
31719
|
-
return { dir: base, lockFile: path26__default.join(base, LOCK_FILE_NAME) };
|
|
31720
|
-
}
|
|
31721
|
-
function createConsoleDataPaths(deps = {}) {
|
|
31722
|
-
const dir = defaultConsoleDataBaseDir(deps);
|
|
31723
|
-
return {
|
|
31724
|
-
dir,
|
|
31725
|
-
stateFile: path26__default.join(dir, CONSOLE_STATE_FILE_NAME),
|
|
31726
|
-
settingsFile: path26__default.join(dir, CONSOLE_SETTINGS_FILE_NAME),
|
|
31727
|
-
capturesDir: path26__default.join(dir, CONSOLE_CAPTURES_DIR_NAME)
|
|
31728
|
-
};
|
|
31729
|
-
}
|
|
31730
|
-
function defaultConsoleBaseDir(deps) {
|
|
31731
|
-
let release;
|
|
31732
|
-
const channel = deps.channel ?? (release = readFleetConsoleRelease()).channel;
|
|
31733
|
-
if (channel === "local") {
|
|
31734
|
-
const packageRoot = deps.packageRoot ?? (release ??= readFleetConsoleRelease()).packageRoot;
|
|
31735
|
-
return localConsoleDir(packageRoot);
|
|
31736
|
-
}
|
|
31737
|
-
const uid = deps.uid ?? (typeof process.getuid === "function" ? process.getuid() : 0);
|
|
31738
|
-
return path26__default.join(os3__default.tmpdir(), `${LOCK_DIR_NAME2}-${uid}-${channel}`);
|
|
31739
|
-
}
|
|
31740
|
-
function defaultConsoleDataBaseDir(deps) {
|
|
31741
|
-
if (deps.fleetDataDir !== void 0) {
|
|
31742
|
-
return path26__default.join(deps.fleetDataDir, CONSOLE_DATA_DIR_NAME);
|
|
31743
|
-
}
|
|
31744
|
-
const env = deps.env ?? process.env;
|
|
31745
|
-
if (env.FLEET_CONSOLE_DIR) {
|
|
31746
|
-
return env.FLEET_CONSOLE_DIR;
|
|
31747
|
-
}
|
|
31748
|
-
let release;
|
|
31749
|
-
const channel = deps.channel ?? (release = readFleetConsoleRelease()).channel;
|
|
31750
|
-
if (channel === "local") {
|
|
31751
|
-
const packageRoot = deps.packageRoot ?? (release ??= readFleetConsoleRelease()).packageRoot;
|
|
31752
|
-
return localConsoleDir(packageRoot);
|
|
31753
|
-
}
|
|
31754
|
-
return path26__default.join(getFleetDataDir(), CONSOLE_DATA_DIR_NAME);
|
|
31755
|
-
}
|
|
31756
|
-
function localConsoleDir(packageRoot) {
|
|
31757
|
-
return path26__default.join(path26__default.resolve(packageRoot, "..", ".."), ".fleet", CONSOLE_RUNTIME_DIR_NAME);
|
|
31758
|
-
}
|
|
30563
|
+
...framework_exports});
|
|
31759
30564
|
|
|
31760
30565
|
// core/host/carrier-settings-routes.ts
|
|
31761
|
-
var SUBAGENT_CLI_TYPES = /* @__PURE__ */ new Set(["claude", "claude-zai", "claude-kimi", "claude-glm"]);
|
|
31762
30566
|
var TASKFORCE_MIN_BACKENDS = 2;
|
|
31763
30567
|
var CARRIER_SETTINGS_API_CATALOG = [
|
|
31764
30568
|
{
|
|
@@ -31778,7 +30582,7 @@ var CARRIER_SETTINGS_API_CATALOG = [
|
|
|
31778
30582
|
{
|
|
31779
30583
|
method: "PATCH",
|
|
31780
30584
|
path: "/api/v1/settings/carriers/:id",
|
|
31781
|
-
summary: "Update carrier settings fields (cli, model, displayName
|
|
30585
|
+
summary: "Update carrier settings fields (cli, model, displayName).",
|
|
31782
30586
|
category: "Settings",
|
|
31783
30587
|
gate: "origin-write"
|
|
31784
30588
|
},
|
|
@@ -31932,22 +30736,8 @@ async function mutateCarrierPatch(req, res, deps, controller, carrierId) {
|
|
|
31932
30736
|
}
|
|
31933
30737
|
normalizedDisplayName = parsed;
|
|
31934
30738
|
}
|
|
31935
|
-
if (body.agentMode !== void 0) {
|
|
31936
|
-
if (body.agentMode !== "cli" && body.agentMode !== "subagent") {
|
|
31937
|
-
deps.writeJson(res, 400, { error: "invalid_agent_mode" });
|
|
31938
|
-
return;
|
|
31939
|
-
}
|
|
31940
|
-
if (body.agentMode === "subagent" && !SUBAGENT_CLI_TYPES.has(effectiveCliType)) {
|
|
31941
|
-
deps.writeJson(res, 400, { error: "subagent_unsupported" });
|
|
31942
|
-
return;
|
|
31943
|
-
}
|
|
31944
|
-
}
|
|
31945
30739
|
if (newCliType) {
|
|
31946
30740
|
await controller.changeCliType(carrierId, newCliType);
|
|
31947
|
-
if (!SUBAGENT_CLI_TYPES.has(newCliType)) {
|
|
31948
|
-
const resolved = readCarriersSnapshot(buildDefaultsByCarrier(deps.registry)).carriers[carrierId];
|
|
31949
|
-
if (resolved?.agentMode === "subagent") updateCarrierAgentModeAtomically(carrierId, "cli", config2.defaultAgentMode ?? "cli");
|
|
31950
|
-
}
|
|
31951
30741
|
}
|
|
31952
30742
|
if (modelSelection) {
|
|
31953
30743
|
await updateAgentCliSelection(carrierId, effectiveCliType, modelSelection);
|
|
@@ -31957,11 +30747,6 @@ async function mutateCarrierPatch(req, res, deps, controller, carrierId) {
|
|
|
31957
30747
|
updateCarrierDisplayName(carrierId, normalizedDisplayName, getCarrierSourceDisplayName(deps.registry, carrierId));
|
|
31958
30748
|
notifyStatusUpdate(deps.registry);
|
|
31959
30749
|
}
|
|
31960
|
-
if (body.agentMode === "cli" || body.agentMode === "subagent") {
|
|
31961
|
-
updateCarrierAgentModeAtomically(carrierId, body.agentMode, config2.defaultAgentMode ?? "cli");
|
|
31962
|
-
if (body.agentMode === "subagent") refreshTaskForceConfiguredCarriers(deps.registry);
|
|
31963
|
-
notifyStatusUpdate(deps.registry);
|
|
31964
|
-
}
|
|
31965
30750
|
writeMutationState(res, deps);
|
|
31966
30751
|
}
|
|
31967
30752
|
function mutateTaskForceBackend(res, deps, carrierId, cliType, body) {
|
|
@@ -31993,7 +30778,6 @@ function buildDefaultsByCarrier(registry3) {
|
|
|
31993
30778
|
const config2 = requireCarrierConfig(registry3, carrierId);
|
|
31994
30779
|
return [carrierId, {
|
|
31995
30780
|
cliType: config2.defaultCliType,
|
|
31996
|
-
...config2.defaultAgentMode ? { defaultAgentMode: config2.defaultAgentMode } : {},
|
|
31997
30781
|
...buildCarrierModelDefaults(config2, config2.defaultCliType)
|
|
31998
30782
|
}];
|
|
31999
30783
|
})
|
|
@@ -32015,8 +30799,6 @@ function toCarrierSettingsCarrier(registry3, config2, resolved) {
|
|
|
32015
30799
|
defaultCliType: config2.defaultCliType,
|
|
32016
30800
|
model: selection.model,
|
|
32017
30801
|
...selection.effort ? { effort: selection.effort } : {},
|
|
32018
|
-
agentMode: resolved.agentMode,
|
|
32019
|
-
subagentMode: resolved.agentMode === "subagent",
|
|
32020
30802
|
taskForceBackendCount: taskForceBackends.length,
|
|
32021
30803
|
taskforce: { backends: taskForceBackends }
|
|
32022
30804
|
};
|
|
@@ -32037,7 +30819,6 @@ function toCliOption(cliType) {
|
|
|
32037
30819
|
return {
|
|
32038
30820
|
id: cliType,
|
|
32039
30821
|
displayName: CLI_DISPLAY_NAMES[cliType] ?? provider.name,
|
|
32040
|
-
supportsSubagent: SUBAGENT_CLI_TYPES.has(cliType),
|
|
32041
30822
|
models: provider.models.map((model) => {
|
|
32042
30823
|
const effort = getEffort(cliType, model.modelId);
|
|
32043
30824
|
return {
|
|
@@ -32082,28 +30863,12 @@ function createStatusOverlayController(registry3) {
|
|
|
32082
30863
|
notifyStatusUpdate: () => notifyStatusUpdate(registry3)
|
|
32083
30864
|
});
|
|
32084
30865
|
}
|
|
32085
|
-
function updateCarrierAgentModeAtomically(carrierId, agentMode, defaultAgentMode) {
|
|
32086
|
-
if (agentMode === "cli") {
|
|
32087
|
-
setCarrierAgentMode(carrierId, false, defaultAgentMode);
|
|
32088
|
-
return;
|
|
32089
|
-
}
|
|
32090
|
-
updateCarriers((states) => {
|
|
32091
|
-
const carriers = { ...states.carriers ?? {} };
|
|
32092
|
-
const current = carriers[carrierId] ?? {};
|
|
32093
|
-
const next = { ...current };
|
|
32094
|
-
next.agentMode = "subagent";
|
|
32095
|
-
delete next.taskforce;
|
|
32096
|
-
carriers[carrierId] = next;
|
|
32097
|
-
states.carriers = carriers;
|
|
32098
|
-
});
|
|
32099
|
-
}
|
|
32100
30866
|
function updateTaskForceBackendAtomically(carrierId, cliType, selection) {
|
|
32101
30867
|
updateCarriers((states) => {
|
|
32102
30868
|
const carriers = { ...states.carriers ?? {} };
|
|
32103
30869
|
const current = carriers[carrierId] ?? {};
|
|
32104
30870
|
carriers[carrierId] = {
|
|
32105
30871
|
...current,
|
|
32106
|
-
agentMode: "cli",
|
|
32107
30872
|
taskforce: {
|
|
32108
30873
|
...current.taskforce ?? {},
|
|
32109
30874
|
[cliType]: selection
|
|
@@ -32142,7 +30907,6 @@ function readCurrentModelSelection(registry3, carrierId) {
|
|
|
32142
30907
|
const defaults = {
|
|
32143
30908
|
[carrierId]: {
|
|
32144
30909
|
cliType: config2.defaultCliType,
|
|
32145
|
-
...config2.defaultAgentMode ? { defaultAgentMode: config2.defaultAgentMode } : {},
|
|
32146
30910
|
...buildCarrierModelDefaults(config2, config2.defaultCliType)
|
|
32147
30911
|
}
|
|
32148
30912
|
};
|
|
@@ -32152,7 +30916,6 @@ function readCurrentModelSelection(registry3, carrierId) {
|
|
|
32152
30916
|
}
|
|
32153
30917
|
function fallbackResolvedState(config2) {
|
|
32154
30918
|
return {
|
|
32155
|
-
agentMode: config2.defaultAgentMode ?? "cli",
|
|
32156
30919
|
agentCliType: config2.defaultCliType,
|
|
32157
30920
|
agentCli: { [config2.defaultCliType]: readDefaultSelection(config2.defaultCliType) },
|
|
32158
30921
|
taskforce: {}
|
|
@@ -32307,7 +31070,7 @@ function createConsoleSettingsStore(deps = {}) {
|
|
|
32307
31070
|
const createStore = deps.createStore ?? createDurableJsonStore;
|
|
32308
31071
|
return createStore({
|
|
32309
31072
|
filePath: paths.settingsFile,
|
|
32310
|
-
lockDir:
|
|
31073
|
+
lockDir: path25__default.join(paths.dir, SETTINGS_LOCK_DIR_NAME),
|
|
32311
31074
|
lockOwnerFileName: SETTINGS_LOCK_OWNER_FILE_NAME,
|
|
32312
31075
|
now: deps.now,
|
|
32313
31076
|
sanitize: sanitizeConsoleSettingsData,
|
|
@@ -32316,7 +31079,7 @@ function createConsoleSettingsStore(deps = {}) {
|
|
|
32316
31079
|
});
|
|
32317
31080
|
}
|
|
32318
31081
|
function sanitizeConsoleSettingsData(value) {
|
|
32319
|
-
if (!
|
|
31082
|
+
if (!isRecord3(value)) return emptyConsoleSettingsData();
|
|
32320
31083
|
if (value.version !== SETTINGS_VERSION) return emptyConsoleSettingsData();
|
|
32321
31084
|
const general = readConsoleGeneralSettings(value.general);
|
|
32322
31085
|
const plugins = readConsolePluginSettings(value.plugins);
|
|
@@ -32330,7 +31093,7 @@ function emptyConsoleSettingsData() {
|
|
|
32330
31093
|
return { version: 1, general: {}, plugins: {} };
|
|
32331
31094
|
}
|
|
32332
31095
|
function readConsoleGeneralSettings(value) {
|
|
32333
|
-
if (!
|
|
31096
|
+
if (!isRecord3(value)) return null;
|
|
32334
31097
|
const consolePortMode = value.consolePortMode === "dynamic" || value.consolePortMode === "static" ? value.consolePortMode : void 0;
|
|
32335
31098
|
const consoleStaticPort = isValidConsoleStaticPort2(value.consoleStaticPort) ? value.consoleStaticPort : void 0;
|
|
32336
31099
|
const theme = value.theme === "maritime" || value.theme === "carbon" ? value.theme : void 0;
|
|
@@ -32341,16 +31104,16 @@ function readConsoleGeneralSettings(value) {
|
|
|
32341
31104
|
};
|
|
32342
31105
|
}
|
|
32343
31106
|
function readConsolePluginSettings(value) {
|
|
32344
|
-
if (!
|
|
31107
|
+
if (!isRecord3(value)) return null;
|
|
32345
31108
|
const result = {};
|
|
32346
31109
|
for (const [key, entry] of Object.entries(value)) {
|
|
32347
31110
|
if (!PLUGIN_ID_PATTERN.test(key)) continue;
|
|
32348
|
-
if (!
|
|
31111
|
+
if (!isRecord3(entry)) continue;
|
|
32349
31112
|
result[key] = entry;
|
|
32350
31113
|
}
|
|
32351
31114
|
return result;
|
|
32352
31115
|
}
|
|
32353
|
-
function
|
|
31116
|
+
function isRecord3(value) {
|
|
32354
31117
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
32355
31118
|
}
|
|
32356
31119
|
function isValidConsoleStaticPort2(value) {
|
|
@@ -32409,7 +31172,7 @@ function createPluginSettingsRouter(deps) {
|
|
|
32409
31172
|
return true;
|
|
32410
31173
|
}
|
|
32411
31174
|
const body = await deps.readJsonBody(req);
|
|
32412
|
-
if (!
|
|
31175
|
+
if (!isRecord4(body)) {
|
|
32413
31176
|
deps.writeJson(res, 400, { error: "invalid_json" });
|
|
32414
31177
|
return true;
|
|
32415
31178
|
}
|
|
@@ -32429,7 +31192,7 @@ function createPluginSettingsRouter(deps) {
|
|
|
32429
31192
|
return true;
|
|
32430
31193
|
};
|
|
32431
31194
|
}
|
|
32432
|
-
function
|
|
31195
|
+
function isRecord4(value) {
|
|
32433
31196
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
32434
31197
|
}
|
|
32435
31198
|
function isJsonRequest3(req) {
|
|
@@ -32854,18 +31617,18 @@ Always read \`schema/wiki-schema.md\` directly before composing or revising entr
|
|
|
32854
31617
|
`;
|
|
32855
31618
|
async function ensureWorkspaceSchema(paths) {
|
|
32856
31619
|
await mkdir(paths.schemaDir, { recursive: true });
|
|
32857
|
-
await writeDefaultFileIfMissing(
|
|
32858
|
-
await writeDefaultFileIfMissing(
|
|
31620
|
+
await writeDefaultFileIfMissing(path25__default.join(paths.schemaDir, WORKSPACE_SCHEMA_AGENTS_FILENAME), DEFAULT_WORKSPACE_SCHEMA_AGENTS);
|
|
31621
|
+
await writeDefaultFileIfMissing(path25__default.join(paths.schemaDir, WORKSPACE_SCHEMA_FILENAME), DEFAULT_WORKSPACE_WIKI_SCHEMA);
|
|
32859
31622
|
await writeDefaultFileIfMissing(buildTemplatePath(paths, "prd"), DEFAULT_TEMPLATE_PRD);
|
|
32860
31623
|
return readWorkspaceSchemaSummary(paths);
|
|
32861
31624
|
}
|
|
32862
31625
|
async function ensureWorkspaceDoctrine(paths) {
|
|
32863
31626
|
await mkdir(paths.root, { recursive: true });
|
|
32864
|
-
await writeDefaultFileIfMissing(
|
|
31627
|
+
await writeDefaultFileIfMissing(path25__default.join(paths.root, WORKSPACE_KNOWLEDGE_AGENTS_FILENAME), DEFAULT_WORKSPACE_KNOWLEDGE_AGENTS);
|
|
32865
31628
|
}
|
|
32866
31629
|
async function readWorkspaceSchemaSummary(paths) {
|
|
32867
|
-
const agentsPath =
|
|
32868
|
-
const wikiSchemaPath =
|
|
31630
|
+
const agentsPath = path25__default.join(paths.schemaDir, WORKSPACE_SCHEMA_AGENTS_FILENAME);
|
|
31631
|
+
const wikiSchemaPath = path25__default.join(paths.schemaDir, WORKSPACE_SCHEMA_FILENAME);
|
|
32869
31632
|
const wikiSchemaContent = await tryReadFile(wikiSchemaPath);
|
|
32870
31633
|
const templates = await scanTemplates(paths);
|
|
32871
31634
|
if (wikiSchemaContent === null) {
|
|
@@ -32904,7 +31667,7 @@ async function scanTemplates(paths) {
|
|
|
32904
31667
|
if (!entry.name.startsWith(WORKSPACE_TEMPLATE_PREFIX) || !entry.name.endsWith(WORKSPACE_TEMPLATE_SUFFIX)) continue;
|
|
32905
31668
|
const id = entry.name.slice(WORKSPACE_TEMPLATE_PREFIX.length, -WORKSPACE_TEMPLATE_SUFFIX.length);
|
|
32906
31669
|
if (!id) continue;
|
|
32907
|
-
const filePath =
|
|
31670
|
+
const filePath = path25__default.join(paths.schemaDir, entry.name);
|
|
32908
31671
|
try {
|
|
32909
31672
|
const parsed = parseTemplateMarkdown(await readFile(filePath, "utf8"));
|
|
32910
31673
|
templates.push({
|
|
@@ -32938,7 +31701,7 @@ async function validateTemplateCompliance(paths, templateId, body) {
|
|
|
32938
31701
|
}
|
|
32939
31702
|
}
|
|
32940
31703
|
function inferTemplateIdFromTarget(target, knownTemplateIds) {
|
|
32941
|
-
const basename =
|
|
31704
|
+
const basename = path25__default.basename(target, ".md");
|
|
32942
31705
|
const ids = knownTemplateIds ?? DEFAULT_TEMPLATE_IDS;
|
|
32943
31706
|
const sorted = [...ids].sort((a, b) => b.length - a.length);
|
|
32944
31707
|
for (const id of sorted) {
|
|
@@ -32967,7 +31730,7 @@ function extractSchemaSummary(content) {
|
|
|
32967
31730
|
return lines.find((line) => line.length > 0 && !line.startsWith("#")) ?? "Workspace schema is present.";
|
|
32968
31731
|
}
|
|
32969
31732
|
function buildTemplatePath(paths, id) {
|
|
32970
|
-
return
|
|
31733
|
+
return path25__default.join(paths.schemaDir, `${WORKSPACE_TEMPLATE_PREFIX}${id}${WORKSPACE_TEMPLATE_SUFFIX}`);
|
|
32971
31734
|
}
|
|
32972
31735
|
function parseTemplateMarkdown(content) {
|
|
32973
31736
|
const normalized = content.replace(/\r\n/g, "\n");
|
|
@@ -32994,16 +31757,16 @@ function isAlreadyExistsError(error51) {
|
|
|
32994
31757
|
|
|
32995
31758
|
// ../../packages/fleet-wiki/src/paths.ts
|
|
32996
31759
|
function resolveMemoryPaths(cwd) {
|
|
32997
|
-
const root =
|
|
31760
|
+
const root = path25__default.join(cwd, KNOWLEDGE_ROOT_DIRNAME);
|
|
32998
31761
|
return {
|
|
32999
31762
|
root,
|
|
33000
|
-
rawDir:
|
|
33001
|
-
wikiDir:
|
|
33002
|
-
schemaDir:
|
|
33003
|
-
queueDir:
|
|
33004
|
-
archiveDir:
|
|
33005
|
-
conflictsDir:
|
|
33006
|
-
indexFile:
|
|
31763
|
+
rawDir: path25__default.join(root, RAW_DIRNAME),
|
|
31764
|
+
wikiDir: path25__default.join(root, WIKI_DIRNAME),
|
|
31765
|
+
schemaDir: path25__default.join(root, SCHEMA_DIRNAME),
|
|
31766
|
+
queueDir: path25__default.join(root, QUEUE_DIRNAME),
|
|
31767
|
+
archiveDir: path25__default.join(root, ARCHIVE_DIRNAME),
|
|
31768
|
+
conflictsDir: path25__default.join(root, CONFLICTS_DIRNAME),
|
|
31769
|
+
indexFile: path25__default.join(root, INDEX_FILENAME)
|
|
33007
31770
|
};
|
|
33008
31771
|
}
|
|
33009
31772
|
async function ensureMemoryRoot(paths) {
|
|
@@ -33018,10 +31781,10 @@ async function ensureMemoryRoot(paths) {
|
|
|
33018
31781
|
await ensureWorkspaceDoctrine(paths);
|
|
33019
31782
|
}
|
|
33020
31783
|
function getIndexMarkdownFile(paths) {
|
|
33021
|
-
return
|
|
31784
|
+
return path25__default.join(paths.wikiDir, INDEX_MD_FILENAME);
|
|
33022
31785
|
}
|
|
33023
31786
|
function getLogFile(paths) {
|
|
33024
|
-
return
|
|
31787
|
+
return path25__default.join(paths.root, LOG_MD_FILENAME);
|
|
33025
31788
|
}
|
|
33026
31789
|
|
|
33027
31790
|
// ../../packages/fleet-wiki/src/log.ts
|
|
@@ -33087,12 +31850,12 @@ async function readWikiEntry(id, paths) {
|
|
|
33087
31850
|
const index = await loadIndex(paths);
|
|
33088
31851
|
const indexed = index[id];
|
|
33089
31852
|
if (indexed) {
|
|
33090
|
-
const resolved =
|
|
33091
|
-
const rel =
|
|
33092
|
-
if (!rel || rel.startsWith("..") ||
|
|
31853
|
+
const resolved = path25__default.resolve(paths.root, indexed.path);
|
|
31854
|
+
const rel = path25__default.relative(paths.wikiDir, resolved);
|
|
31855
|
+
if (!rel || rel.startsWith("..") || path25__default.isAbsolute(rel)) return null;
|
|
33093
31856
|
return readMarkdownFile(resolved);
|
|
33094
31857
|
}
|
|
33095
|
-
const fallbackPath =
|
|
31858
|
+
const fallbackPath = path25__default.join(paths.wikiDir, `${id}.md`);
|
|
33096
31859
|
if (await pathExists(fallbackPath)) {
|
|
33097
31860
|
return readMarkdownFile(fallbackPath);
|
|
33098
31861
|
}
|
|
@@ -33103,20 +31866,20 @@ async function readWikiEntry(id, paths) {
|
|
|
33103
31866
|
async function writeWikiEntryAtTarget(entry, target, paths) {
|
|
33104
31867
|
await ensureMemoryRoot(paths);
|
|
33105
31868
|
assertSafeEntryId(entry.id);
|
|
33106
|
-
const absoluteTarget =
|
|
33107
|
-
const relativeTarget =
|
|
33108
|
-
if (!relativeTarget || relativeTarget.startsWith("..") ||
|
|
31869
|
+
const absoluteTarget = path25__default.resolve(paths.root, target);
|
|
31870
|
+
const relativeTarget = path25__default.relative(paths.wikiDir, absoluteTarget);
|
|
31871
|
+
if (!relativeTarget || relativeTarget.startsWith("..") || path25__default.isAbsolute(relativeTarget)) {
|
|
33109
31872
|
throw new Error(`[fleet-wiki] wiki target escapes wiki/: ${target}`);
|
|
33110
31873
|
}
|
|
33111
31874
|
if (!absoluteTarget.endsWith(".md")) {
|
|
33112
31875
|
throw new Error(`[fleet-wiki] wiki target must end with .md: ${target}`);
|
|
33113
31876
|
}
|
|
33114
|
-
if (
|
|
31877
|
+
if (path25__default.basename(absoluteTarget, ".md") !== entry.id) {
|
|
33115
31878
|
throw new Error("wiki patch body id must match target filename");
|
|
33116
31879
|
}
|
|
33117
|
-
await mkdir(
|
|
31880
|
+
await mkdir(path25__default.dirname(absoluteTarget), { recursive: true });
|
|
33118
31881
|
await writeMarkdownAtomic(absoluteTarget, serializeWikiEntry(entry), paths);
|
|
33119
|
-
return
|
|
31882
|
+
return path25__default.join("wiki", relativeTarget).replaceAll(path25__default.sep, "/");
|
|
33120
31883
|
}
|
|
33121
31884
|
async function listWiki(paths) {
|
|
33122
31885
|
const entries = await listWikiRecords(paths);
|
|
@@ -33339,7 +32102,7 @@ function parseWikiEntry(content) {
|
|
|
33339
32102
|
async function listWikiRecords(paths) {
|
|
33340
32103
|
return listMarkdownEntriesRecursive(paths.wikiDir, paths, (content, filePath) => ({
|
|
33341
32104
|
entry: parseWikiEntry(content),
|
|
33342
|
-
path:
|
|
32105
|
+
path: path25__default.relative(paths.root, filePath).replaceAll(path25__default.sep, "/")
|
|
33343
32106
|
}));
|
|
33344
32107
|
}
|
|
33345
32108
|
async function listMarkdownEntriesRecursive(dirPath, paths, parser) {
|
|
@@ -33352,7 +32115,7 @@ async function listMarkdownEntriesRecursive(dirPath, paths, parser) {
|
|
|
33352
32115
|
}
|
|
33353
32116
|
const sortedEntries = entries.sort((left, right) => left.name.localeCompare(right.name));
|
|
33354
32117
|
for (const entry of sortedEntries) {
|
|
33355
|
-
const filePath =
|
|
32118
|
+
const filePath = path25__default.join(dirPath, entry.name);
|
|
33356
32119
|
if (entry.isDirectory()) {
|
|
33357
32120
|
items.push(...await listMarkdownEntriesRecursive(filePath, paths, parser));
|
|
33358
32121
|
continue;
|
|
@@ -33490,9 +32253,9 @@ async function writeJsonAtomic(filePath, value, paths) {
|
|
|
33490
32253
|
}
|
|
33491
32254
|
async function writeAtomic(filePath, content, paths) {
|
|
33492
32255
|
await ensureMemoryRoot(paths);
|
|
33493
|
-
const tempPath =
|
|
33494
|
-
|
|
33495
|
-
`.tmp-${process.pid}-${Date.now()}-${crypto5.randomUUID()}-${
|
|
32256
|
+
const tempPath = path25__default.join(
|
|
32257
|
+
path25__default.dirname(filePath),
|
|
32258
|
+
`.tmp-${process.pid}-${Date.now()}-${crypto5.randomUUID()}-${os4__default.hostname()}`
|
|
33496
32259
|
);
|
|
33497
32260
|
await writeFile(tempPath, content, "utf8");
|
|
33498
32261
|
await rename(tempPath, filePath);
|
|
@@ -33585,7 +32348,7 @@ function toRankedHit(entry, reason, detail, graphBoost, backlinksById) {
|
|
|
33585
32348
|
score: basePriority * 100 + statusPriority * 10 + graphScore + (detail.tagBoost ?? 0),
|
|
33586
32349
|
reason,
|
|
33587
32350
|
excerpt,
|
|
33588
|
-
path:
|
|
32351
|
+
path: path25__default.join("wiki", `${entry.id}.md`),
|
|
33589
32352
|
tags: entry.tags,
|
|
33590
32353
|
updated: entry.updated,
|
|
33591
32354
|
version: entry.version,
|
|
@@ -33695,15 +32458,15 @@ var PATCH_SET_DIRNAME = "_sets";
|
|
|
33695
32458
|
var PATCH_SET_META_FILENAME = PATCH_META_FILENAME;
|
|
33696
32459
|
function getPatchSetDir(paths, patchSetId) {
|
|
33697
32460
|
assertSafePatchSetId(patchSetId);
|
|
33698
|
-
const patchSetDir =
|
|
33699
|
-
const relative =
|
|
33700
|
-
if (!relative || relative.startsWith("..") ||
|
|
32461
|
+
const patchSetDir = path25__default.join(paths.queueDir, PATCH_SET_DIRNAME, patchSetId);
|
|
32462
|
+
const relative = path25__default.relative(path25__default.join(paths.queueDir, PATCH_SET_DIRNAME), patchSetDir);
|
|
32463
|
+
if (!relative || relative.startsWith("..") || path25__default.isAbsolute(relative)) {
|
|
33701
32464
|
throw new Error(`[fleet-wiki] patch set id escapes queue/_sets: ${patchSetId}`);
|
|
33702
32465
|
}
|
|
33703
32466
|
return patchSetDir;
|
|
33704
32467
|
}
|
|
33705
32468
|
function getPatchSetMetaFile(paths, patchSetId) {
|
|
33706
|
-
return
|
|
32469
|
+
return path25__default.join(getPatchSetDir(paths, patchSetId), PATCH_SET_META_FILENAME);
|
|
33707
32470
|
}
|
|
33708
32471
|
async function readPatchSet(paths, patchSetId) {
|
|
33709
32472
|
const patchSet = await readJsonFile2(getPatchSetMetaFile(paths, patchSetId));
|
|
@@ -33726,7 +32489,7 @@ async function createConflict(input, paths) {
|
|
|
33726
32489
|
await ensureMemoryRoot(paths);
|
|
33727
32490
|
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
33728
32491
|
const conflictId = buildConflictId(now, input.wikiId, input.reason, input.proposed);
|
|
33729
|
-
const conflictDir =
|
|
32492
|
+
const conflictDir = path25__default.join(paths.conflictsDir, conflictId);
|
|
33730
32493
|
await mkdir(conflictDir, { recursive: true });
|
|
33731
32494
|
const meta3 = {
|
|
33732
32495
|
id: conflictId,
|
|
@@ -33746,13 +32509,13 @@ async function createConflict(input, paths) {
|
|
|
33746
32509
|
currentHash: input.currentHash,
|
|
33747
32510
|
warnings: input.warnings
|
|
33748
32511
|
};
|
|
33749
|
-
await writeJsonFile(
|
|
33750
|
-
await writePatchFile(
|
|
32512
|
+
await writeJsonFile(path25__default.join(conflictDir, CONFLICT_META_FILENAME), meta3, paths);
|
|
32513
|
+
await writePatchFile(path25__default.join(conflictDir, CONFLICT_PROPOSED_FILENAME), input.proposed, paths);
|
|
33751
32514
|
if (input.current !== void 0) {
|
|
33752
|
-
await writePatchFile(
|
|
32515
|
+
await writePatchFile(path25__default.join(conflictDir, CONFLICT_CURRENT_FILENAME), input.current, paths);
|
|
33753
32516
|
}
|
|
33754
32517
|
if (input.rawSource !== void 0) {
|
|
33755
|
-
await writePatchFile(
|
|
32518
|
+
await writePatchFile(path25__default.join(conflictDir, CONFLICT_RAW_SOURCE_FILENAME), input.rawSource, paths);
|
|
33756
32519
|
}
|
|
33757
32520
|
return {
|
|
33758
32521
|
meta: meta3,
|
|
@@ -33802,11 +32565,11 @@ async function validatePatch(patch, paths) {
|
|
|
33802
32565
|
if (!target || !summary || !proposer || !created) throw new Error("patch frontmatter is incomplete");
|
|
33803
32566
|
if (summary.length > 120) throw new Error("patch summary exceeds 120 chars");
|
|
33804
32567
|
assertCanonicalPatchTarget(target);
|
|
33805
|
-
const absoluteTarget =
|
|
33806
|
-
if (!absoluteTarget.startsWith(`${paths.root}${
|
|
32568
|
+
const absoluteTarget = path25__default.resolve(paths.root, target);
|
|
32569
|
+
if (!absoluteTarget.startsWith(`${paths.root}${path25__default.sep}`) && absoluteTarget !== paths.root) {
|
|
33807
32570
|
throw new Error("patch target escapes wiki root");
|
|
33808
32571
|
}
|
|
33809
|
-
if (!absoluteTarget.startsWith(`${paths.wikiDir}${
|
|
32572
|
+
if (!absoluteTarget.startsWith(`${paths.wikiDir}${path25__default.sep}`)) throw new Error("wiki patch must target wiki/");
|
|
33810
32573
|
assertNoSymlinkPathComponents(target, paths);
|
|
33811
32574
|
if (op === "create_wiki" && await pathExists(absoluteTarget)) {
|
|
33812
32575
|
throw new Error(
|
|
@@ -33830,7 +32593,7 @@ async function listQueue(paths) {
|
|
|
33830
32593
|
for (const id of ids) {
|
|
33831
32594
|
if (id === "_sets") continue;
|
|
33832
32595
|
try {
|
|
33833
|
-
const meta3 = await readJsonFile2(
|
|
32596
|
+
const meta3 = await readJsonFile2(path25__default.join(paths.queueDir, id, PATCH_META_FILENAME));
|
|
33834
32597
|
results.push({ id, meta: meta3 });
|
|
33835
32598
|
} catch {
|
|
33836
32599
|
continue;
|
|
@@ -33855,9 +32618,9 @@ async function resolveQueueSelection(id, paths) {
|
|
|
33855
32618
|
}
|
|
33856
32619
|
async function showQueue(id, paths) {
|
|
33857
32620
|
const selection = await resolveQueueSelection(id, paths);
|
|
33858
|
-
const queueDir =
|
|
33859
|
-
const patch = await parsePatch(await readPatchFile(
|
|
33860
|
-
const meta3 = await readJsonFile2(
|
|
32621
|
+
const queueDir = path25__default.join(paths.queueDir, selection.id);
|
|
32622
|
+
const patch = await parsePatch(await readPatchFile(path25__default.join(queueDir, PATCH_FILENAME)));
|
|
32623
|
+
const meta3 = await readJsonFile2(path25__default.join(queueDir, PATCH_META_FILENAME));
|
|
33861
32624
|
return { patch, meta: meta3 };
|
|
33862
32625
|
}
|
|
33863
32626
|
async function approvePatch(id, paths) {
|
|
@@ -33880,8 +32643,8 @@ async function approvePatch(id, paths) {
|
|
|
33880
32643
|
rawSourceRef: meta3.rawSourceRef,
|
|
33881
32644
|
warnings: meta3.warnings
|
|
33882
32645
|
});
|
|
33883
|
-
const queueDir =
|
|
33884
|
-
await writeJsonFile(
|
|
32646
|
+
const queueDir = path25__default.join(paths.queueDir, id);
|
|
32647
|
+
await writeJsonFile(path25__default.join(queueDir, PATCH_META_FILENAME), {
|
|
33885
32648
|
...meta3,
|
|
33886
32649
|
conflictId
|
|
33887
32650
|
}, paths);
|
|
@@ -33934,7 +32697,7 @@ async function rejectPatch(id, reason, paths) {
|
|
|
33934
32697
|
}
|
|
33935
32698
|
async function normalizeWikiEntryPatch(entry, target, paths) {
|
|
33936
32699
|
assertSafeEntryId(entry.id);
|
|
33937
|
-
if (entry.id !==
|
|
32700
|
+
if (entry.id !== path25__default.basename(target, ".md")) {
|
|
33938
32701
|
throw new Error("wiki patch body id must match target filename");
|
|
33939
32702
|
}
|
|
33940
32703
|
const inlineRawSourceRef = extractInlineRawSourceRef(entry.body);
|
|
@@ -33972,9 +32735,9 @@ function extractInlineRawSourceRef(body) {
|
|
|
33972
32735
|
}
|
|
33973
32736
|
async function validatePatchBase(patch, meta3, paths) {
|
|
33974
32737
|
if (patch.frontmatter.op !== "update_wiki" || !meta3?.baseVersion && !meta3?.baseHash) return;
|
|
33975
|
-
const wikiId =
|
|
32738
|
+
const wikiId = path25__default.basename(patch.frontmatter.target, ".md");
|
|
33976
32739
|
const currentEntry = await readWikiEntry(wikiId, paths);
|
|
33977
|
-
const currentPath =
|
|
32740
|
+
const currentPath = path25__default.join(paths.root, patch.frontmatter.target);
|
|
33978
32741
|
const currentMarkdown = await pathExists(currentPath) ? await readPatchFile(currentPath) : void 0;
|
|
33979
32742
|
if (meta3.baseVersion !== void 0 && currentEntry?.version !== meta3.baseVersion) {
|
|
33980
32743
|
throw new Error(
|
|
@@ -34033,17 +32796,17 @@ function assertCanonicalPatchTarget(target) {
|
|
|
34033
32796
|
if (target.endsWith("/")) {
|
|
34034
32797
|
throw new Error("patch target must not end with a slash");
|
|
34035
32798
|
}
|
|
34036
|
-
if (target.startsWith("/") ||
|
|
32799
|
+
if (target.startsWith("/") || path25__default.posix.isAbsolute(target) || path25__default.win32.isAbsolute(target)) {
|
|
34037
32800
|
throw new Error("patch target must be relative");
|
|
34038
32801
|
}
|
|
34039
|
-
if (
|
|
32802
|
+
if (path25__default.posix.normalize(target) !== target) {
|
|
34040
32803
|
throw new Error("patch target must not contain dot segments or redundant separators");
|
|
34041
32804
|
}
|
|
34042
32805
|
}
|
|
34043
32806
|
function canonicalApprovalLockKey(paths, target) {
|
|
34044
32807
|
const wikiRoot = realpathSync(paths.wikiDir);
|
|
34045
|
-
const relativeTarget =
|
|
34046
|
-
const targetPath =
|
|
32808
|
+
const relativeTarget = path25__default.posix.relative("wiki", target);
|
|
32809
|
+
const targetPath = path25__default.join(wikiRoot, ...relativeTarget.split("/"));
|
|
34047
32810
|
return `${wikiRoot}\0${targetPath}`.toLowerCase();
|
|
34048
32811
|
}
|
|
34049
32812
|
function canonicalPatchEditLockKey(paths, patchId) {
|
|
@@ -34059,7 +32822,7 @@ function assertNoSymlinkPathComponents(target, paths) {
|
|
|
34059
32822
|
throw error51;
|
|
34060
32823
|
}
|
|
34061
32824
|
for (const part of parts) {
|
|
34062
|
-
current =
|
|
32825
|
+
current = path25__default.join(current, part);
|
|
34063
32826
|
try {
|
|
34064
32827
|
if (lstatSync(current).isSymbolicLink()) {
|
|
34065
32828
|
throw new Error("patch target must not include symlink path components");
|
|
@@ -34074,8 +32837,8 @@ function assertSafeRawSourceRef(rawSourceRef, paths) {
|
|
|
34074
32837
|
if (!rawSourceRef.startsWith("raw/")) {
|
|
34075
32838
|
throw new Error("raw source provenance must point into raw/");
|
|
34076
32839
|
}
|
|
34077
|
-
const absoluteRef =
|
|
34078
|
-
if (!absoluteRef.startsWith(`${paths.rawDir}${
|
|
32840
|
+
const absoluteRef = path25__default.resolve(paths.root, rawSourceRef);
|
|
32841
|
+
if (!absoluteRef.startsWith(`${paths.rawDir}${path25__default.sep}`)) {
|
|
34079
32842
|
throw new Error("raw source provenance must point into raw/");
|
|
34080
32843
|
}
|
|
34081
32844
|
}
|
|
@@ -34091,14 +32854,14 @@ function classifyPatchConflict(error51) {
|
|
|
34091
32854
|
}
|
|
34092
32855
|
async function recordPatchConflict(patch, paths, reason, options) {
|
|
34093
32856
|
const now = /* @__PURE__ */ new Date();
|
|
34094
|
-
const targetPath =
|
|
32857
|
+
const targetPath = path25__default.join(paths.root, patch.frontmatter.target);
|
|
34095
32858
|
const current = await pathExists(targetPath) ? await readPatchFile(targetPath) : void 0;
|
|
34096
32859
|
const currentEntry = current ? parseStoredWikiEntry(current) : void 0;
|
|
34097
32860
|
const proposedEntry = parsePatchBodyEntry(patch.body);
|
|
34098
32861
|
const record2 = await createConflict({
|
|
34099
32862
|
reason,
|
|
34100
32863
|
target: patch.frontmatter.target,
|
|
34101
|
-
wikiId: proposedEntry?.id ??
|
|
32864
|
+
wikiId: proposedEntry?.id ?? path25__default.basename(patch.frontmatter.target, ".md"),
|
|
34102
32865
|
title: proposedEntry?.title,
|
|
34103
32866
|
proposer: patch.frontmatter.proposer,
|
|
34104
32867
|
rawSourceRef: options?.rawSourceRef,
|
|
@@ -34194,11 +32957,11 @@ function parseInlineArray(value) {
|
|
|
34194
32957
|
return inner.split(",").map((item) => item.trim().replace(/^"(.*)"$/, "$1"));
|
|
34195
32958
|
}
|
|
34196
32959
|
async function archiveQueueEntry(id, paths, meta3) {
|
|
34197
|
-
const fromDir =
|
|
34198
|
-
const toDir =
|
|
32960
|
+
const fromDir = path25__default.join(paths.queueDir, id);
|
|
32961
|
+
const toDir = path25__default.join(paths.archiveDir, id);
|
|
34199
32962
|
await removePath(toDir);
|
|
34200
32963
|
await movePath(fromDir, toDir);
|
|
34201
|
-
await writeJsonFile(
|
|
32964
|
+
await writeJsonFile(path25__default.join(toDir, PATCH_META_FILENAME), meta3, paths);
|
|
34202
32965
|
}
|
|
34203
32966
|
function buildQueueIdHelp(prefix, availableIds) {
|
|
34204
32967
|
if (availableIds.length === 0) {
|
|
@@ -34920,7 +33683,7 @@ async function canonicalizeTheaterPath(cwd) {
|
|
|
34920
33683
|
return canonicalizeTheaterPathSync(cwd);
|
|
34921
33684
|
}
|
|
34922
33685
|
function canonicalizeTheaterPathSync(cwd) {
|
|
34923
|
-
const resolved =
|
|
33686
|
+
const resolved = path25__default.resolve(cwd);
|
|
34924
33687
|
try {
|
|
34925
33688
|
return fs11__default.realpathSync.native(resolved);
|
|
34926
33689
|
} catch {
|
|
@@ -34928,7 +33691,7 @@ function canonicalizeTheaterPathSync(cwd) {
|
|
|
34928
33691
|
}
|
|
34929
33692
|
}
|
|
34930
33693
|
function theaterLabel(cwd) {
|
|
34931
|
-
return
|
|
33694
|
+
return path25__default.basename(cwd) || cwd;
|
|
34932
33695
|
}
|
|
34933
33696
|
|
|
34934
33697
|
// core/host/codex/workspaces.ts
|
|
@@ -34936,7 +33699,7 @@ var WorkspaceRegistry = class {
|
|
|
34936
33699
|
#items = /* @__PURE__ */ new Map();
|
|
34937
33700
|
#mruId = null;
|
|
34938
33701
|
async register(cwdInput, lastOpenedAt) {
|
|
34939
|
-
const cwd =
|
|
33702
|
+
const cwd = path25__default.resolve(cwdInput);
|
|
34940
33703
|
const real = await canonicalizeTheaterPath(cwd);
|
|
34941
33704
|
const paths = resolveMemoryPaths(real);
|
|
34942
33705
|
if (!await directoryExists(paths.root)) {
|
|
@@ -34952,7 +33715,7 @@ var WorkspaceRegistry = class {
|
|
|
34952
33715
|
id,
|
|
34953
33716
|
cwd,
|
|
34954
33717
|
realpath: real,
|
|
34955
|
-
label:
|
|
33718
|
+
label: path25__default.basename(cwd),
|
|
34956
33719
|
paths,
|
|
34957
33720
|
registeredAt: existing?.registeredAt ?? now,
|
|
34958
33721
|
// 복원 경로는 durable lastOpenedAt을 그대로 보존해 재시작 후에도 워크스페이스 최근성
|
|
@@ -35091,7 +33854,7 @@ function createCodexGateway(deps) {
|
|
|
35091
33854
|
}
|
|
35092
33855
|
};
|
|
35093
33856
|
}
|
|
35094
|
-
function buildAllowedAccessSets(host, port, interfaces =
|
|
33857
|
+
function buildAllowedAccessSets(host, port, interfaces = os4__default.networkInterfaces()) {
|
|
35095
33858
|
const hosts = isWildcardBindHost(host) ? enumerateWildcardAccessHosts(interfaces) : isDualBindHost(host) ? [host, LOOPBACK_HOST] : [host];
|
|
35096
33859
|
const allowedHosts = /* @__PURE__ */ new Set();
|
|
35097
33860
|
const allowedOrigins = /* @__PURE__ */ new Set();
|
|
@@ -35270,7 +34033,7 @@ function createConsoleDurableStateStore(deps = {}) {
|
|
|
35270
34033
|
const createStore = deps.createStore ?? createDurableJsonStore;
|
|
35271
34034
|
return createStore({
|
|
35272
34035
|
filePath: paths.stateFile,
|
|
35273
|
-
lockDir:
|
|
34036
|
+
lockDir: path25__default.join(paths.dir, STATE_LOCK_DIR_NAME),
|
|
35274
34037
|
lockOwnerFileName: STATE_LOCK_OWNER_FILE_NAME,
|
|
35275
34038
|
now: deps.now,
|
|
35276
34039
|
sanitize: sanitizeDurableConsoleState,
|
|
@@ -35279,7 +34042,7 @@ function createConsoleDurableStateStore(deps = {}) {
|
|
|
35279
34042
|
});
|
|
35280
34043
|
}
|
|
35281
34044
|
function sanitizeDurableConsoleState(value) {
|
|
35282
|
-
if (!
|
|
34045
|
+
if (!isRecord5(value)) return emptyDurableConsoleState();
|
|
35283
34046
|
const upgraded = migrateToCurrentVersion(value);
|
|
35284
34047
|
if (upgraded.version !== STATE_VERSION) return emptyDurableConsoleState();
|
|
35285
34048
|
return {
|
|
@@ -35306,13 +34069,13 @@ function migrateV1ToV2(v1) {
|
|
|
35306
34069
|
};
|
|
35307
34070
|
}
|
|
35308
34071
|
function migrateV1Operation(value) {
|
|
35309
|
-
if (!
|
|
34072
|
+
if (!isRecord5(value)) return null;
|
|
35310
34073
|
const sessionId = readNonEmptyString(value.sessionId);
|
|
35311
34074
|
const theaterId = readNonEmptyString(value.theaterId);
|
|
35312
34075
|
const cwd = readNonEmptyString(value.cwd);
|
|
35313
34076
|
const createdAt = readFiniteNumber(value.createdAt);
|
|
35314
34077
|
if (!sessionId || !theaterId || !cwd || createdAt === null) return null;
|
|
35315
|
-
const title = readOptionalString(value.label) ?? (
|
|
34078
|
+
const title = readOptionalString(value.label) ?? (path25__default.basename(cwd) || cwd);
|
|
35316
34079
|
const payload = { cwd };
|
|
35317
34080
|
const cliId = readOptionalString(value.cliId);
|
|
35318
34081
|
const cliLabel = readOptionalString(value.cliLabel);
|
|
@@ -35320,7 +34083,7 @@ function migrateV1Operation(value) {
|
|
|
35320
34083
|
if (cliId) payload.cliId = cliId;
|
|
35321
34084
|
if (cliLabel) payload.cliLabel = cliLabel;
|
|
35322
34085
|
if (labelSource) payload.labelSource = labelSource;
|
|
35323
|
-
if (
|
|
34086
|
+
if (isRecord5(value.providerSession)) payload.providerSession = value.providerSession;
|
|
35324
34087
|
return {
|
|
35325
34088
|
id: sessionId,
|
|
35326
34089
|
theaterId,
|
|
@@ -35351,7 +34114,7 @@ function readOperations(value) {
|
|
|
35351
34114
|
return nodes;
|
|
35352
34115
|
}
|
|
35353
34116
|
function sanitizeTheaterRegistration(value) {
|
|
35354
|
-
if (!
|
|
34117
|
+
if (!isRecord5(value)) return null;
|
|
35355
34118
|
const id = readNonEmptyString(value.id);
|
|
35356
34119
|
const theaterPath = readNonEmptyString(value.path);
|
|
35357
34120
|
const realpath2 = readNonEmptyString(value.realpath);
|
|
@@ -35362,7 +34125,7 @@ function sanitizeTheaterRegistration(value) {
|
|
|
35362
34125
|
return { id, path: theaterPath, realpath: realpath2, label, registeredAt, lastOpenedAt };
|
|
35363
34126
|
}
|
|
35364
34127
|
function sanitizeOperationNode(value) {
|
|
35365
|
-
if (!
|
|
34128
|
+
if (!isRecord5(value)) return null;
|
|
35366
34129
|
const id = readNonEmptyString(value.id);
|
|
35367
34130
|
const theaterId = readNonEmptyString(value.theaterId);
|
|
35368
34131
|
const type = readNonEmptyString(value.type);
|
|
@@ -35386,7 +34149,7 @@ function sanitizeOperationNode(value) {
|
|
|
35386
34149
|
};
|
|
35387
34150
|
}
|
|
35388
34151
|
function sanitizeOperationTimestamps(value) {
|
|
35389
|
-
if (!
|
|
34152
|
+
if (!isRecord5(value)) return null;
|
|
35390
34153
|
const createdAt = readFiniteNumber(value.createdAt);
|
|
35391
34154
|
const updatedAt = readFiniteNumber(value.updatedAt);
|
|
35392
34155
|
if (createdAt === null || updatedAt === null) return null;
|
|
@@ -35394,7 +34157,7 @@ function sanitizeOperationTimestamps(value) {
|
|
|
35394
34157
|
}
|
|
35395
34158
|
function sanitizeOperationGeometry(value) {
|
|
35396
34159
|
if (value === null || value === void 0) return null;
|
|
35397
|
-
if (!
|
|
34160
|
+
if (!isRecord5(value)) return null;
|
|
35398
34161
|
const x = readFiniteNumber(value.x);
|
|
35399
34162
|
const y = readFiniteNumber(value.y);
|
|
35400
34163
|
const width = readFiniteNumber(value.width);
|
|
@@ -35403,7 +34166,7 @@ function sanitizeOperationGeometry(value) {
|
|
|
35403
34166
|
if (x === null || y === null || width === null || height === null || zIndex === null) return null;
|
|
35404
34167
|
return { x, y, width, height, zIndex };
|
|
35405
34168
|
}
|
|
35406
|
-
function
|
|
34169
|
+
function isRecord5(value) {
|
|
35407
34170
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
35408
34171
|
}
|
|
35409
34172
|
function readNonEmptyString(value) {
|
|
@@ -35413,7 +34176,7 @@ function readOptionalString(value) {
|
|
|
35413
34176
|
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
35414
34177
|
}
|
|
35415
34178
|
function readRecord(value) {
|
|
35416
|
-
return
|
|
34179
|
+
return isRecord5(value) ? value : {};
|
|
35417
34180
|
}
|
|
35418
34181
|
function remapTerminalPluginId(pluginId) {
|
|
35419
34182
|
return pluginId === "agent" || pluginId === "shell" ? "terminal" : pluginId;
|
|
@@ -35447,7 +34210,7 @@ function readOperationGroups(value) {
|
|
|
35447
34210
|
return groups;
|
|
35448
34211
|
}
|
|
35449
34212
|
function sanitizeOperationGroup(value) {
|
|
35450
|
-
if (!
|
|
34213
|
+
if (!isRecord5(value)) return null;
|
|
35451
34214
|
const id = readNonEmptyString(value.id);
|
|
35452
34215
|
const theaterId = readNonEmptyString(value.theaterId);
|
|
35453
34216
|
const rawName = readNonEmptyString(value.name);
|
|
@@ -35489,10 +34252,10 @@ function sanitizeRecord(value, sensitiveFields) {
|
|
|
35489
34252
|
}
|
|
35490
34253
|
function sanitizeValue(value, sensitiveFields) {
|
|
35491
34254
|
if (Array.isArray(value)) return value.map((item) => sanitizeValue(item, sensitiveFields));
|
|
35492
|
-
if (!
|
|
34255
|
+
if (!isRecord6(value)) return value;
|
|
35493
34256
|
return sanitizeRecord(value, sensitiveFields);
|
|
35494
34257
|
}
|
|
35495
|
-
function
|
|
34258
|
+
function isRecord6(value) {
|
|
35496
34259
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
35497
34260
|
}
|
|
35498
34261
|
|
|
@@ -35511,6 +34274,14 @@ function createOperationsRouter(deps) {
|
|
|
35511
34274
|
deps.writeJson(res, 200, deps.resolveLaunchCatalog ? await deps.resolveLaunchCatalog() : { plugins: [] });
|
|
35512
34275
|
return true;
|
|
35513
34276
|
}
|
|
34277
|
+
if (pathname === "/api/v1/operations/events") {
|
|
34278
|
+
if (req.method !== "GET") {
|
|
34279
|
+
deps.writeJson(res, 405, { error: "Method not allowed" });
|
|
34280
|
+
return true;
|
|
34281
|
+
}
|
|
34282
|
+
deps.subscribeOperationSse?.(res);
|
|
34283
|
+
return true;
|
|
34284
|
+
}
|
|
35514
34285
|
if (pathname === "/api/v1/operations/groups") {
|
|
35515
34286
|
await handleGroupCollection(req, res, deps);
|
|
35516
34287
|
return true;
|
|
@@ -35560,8 +34331,8 @@ async function handleCollection(req, res, deps) {
|
|
|
35560
34331
|
pluginId: body.pluginId,
|
|
35561
34332
|
title: body.title,
|
|
35562
34333
|
...typeof body.accent === "string" ? { accent: body.accent } : {},
|
|
35563
|
-
payload:
|
|
35564
|
-
geometry:
|
|
34334
|
+
payload: isRecord7(body.payload) ? body.payload : {},
|
|
34335
|
+
geometry: isRecord7(body.geometry) ? readGeometry(body.geometry) : null
|
|
35565
34336
|
});
|
|
35566
34337
|
deps.persist();
|
|
35567
34338
|
deps.writeJson(res, 201, { operation: sanitizeOperationNode2(node, deps) });
|
|
@@ -35618,23 +34389,24 @@ async function handleItem(req, res, id, deps) {
|
|
|
35618
34389
|
...typeof body.title === "string" ? { title: body.title } : {},
|
|
35619
34390
|
...typeof body.accent === "string" || body.accent === null ? { accent: body.accent } : {},
|
|
35620
34391
|
...typeof body.groupId === "string" || body.groupId === null ? { groupId: body.groupId } : {},
|
|
35621
|
-
...
|
|
35622
|
-
...
|
|
34392
|
+
...isRecord7(body.payload) ? { payload: body.payload } : {},
|
|
34393
|
+
...isRecord7(body.geometry) || body.geometry === null ? { geometry: body.geometry === null ? null : readGeometry(body.geometry) } : {}
|
|
35623
34394
|
});
|
|
35624
34395
|
if (!node) {
|
|
35625
34396
|
deps.writeJson(res, 404, { error: "operation_not_found" });
|
|
35626
34397
|
return;
|
|
35627
34398
|
}
|
|
35628
34399
|
deps.persist();
|
|
35629
|
-
if (previousNode &&
|
|
34400
|
+
if (previousNode && typeof body.title === "string") {
|
|
35630
34401
|
deps.publishRenameEvent?.({
|
|
35631
34402
|
operationId: node.id,
|
|
35632
34403
|
pluginId: node.pluginId,
|
|
35633
34404
|
type: node.type,
|
|
35634
|
-
title: node.title,
|
|
34405
|
+
title: body.title.trim() === "" ? "" : node.title,
|
|
35635
34406
|
previousTitle: previousNode.title
|
|
35636
34407
|
});
|
|
35637
34408
|
}
|
|
34409
|
+
deps.broadcastOperationChanged?.(deps.store.get(id) ?? node);
|
|
35638
34410
|
deps.writeJson(res, 200, { operation: sanitizeOperationNode2(node, deps) });
|
|
35639
34411
|
} catch (error51) {
|
|
35640
34412
|
deps.writeJson(res, 400, { error: error51 instanceof Error ? error51.message : "invalid_operation_patch" });
|
|
@@ -35723,7 +34495,7 @@ function readFiniteNumber2(value) {
|
|
|
35723
34495
|
function readRequestUrl(req) {
|
|
35724
34496
|
return new URL(req.url ?? "/", "http://127.0.0.1");
|
|
35725
34497
|
}
|
|
35726
|
-
function
|
|
34498
|
+
function isRecord7(value) {
|
|
35727
34499
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
35728
34500
|
}
|
|
35729
34501
|
function createOperationStore(deps = {}) {
|
|
@@ -36008,14 +34780,14 @@ function renderShim(definition) {
|
|
|
36008
34780
|
].join("\n");
|
|
36009
34781
|
}
|
|
36010
34782
|
function isSubpath(root, target) {
|
|
36011
|
-
const relative =
|
|
36012
|
-
return relative === "" || !relative.startsWith("..") && !
|
|
34783
|
+
const relative = path25__default.relative(root, target);
|
|
34784
|
+
return relative === "" || !relative.startsWith("..") && !path25__default.isAbsolute(relative);
|
|
36013
34785
|
}
|
|
36014
34786
|
function discoverFleetPlugins(options = {}) {
|
|
36015
|
-
const builtInSourceRoot = options.builtInSourceRoot ?? (options.cwd ?
|
|
34787
|
+
const builtInSourceRoot = options.builtInSourceRoot ?? (options.cwd ? path25__default.resolve(options.cwd, "runtime/fleet-plugins") : null);
|
|
36016
34788
|
const roots = [
|
|
36017
34789
|
...builtInSourceRoot ? [{ root: builtInSourceRoot, builtInDistRoot: options.builtInDistRoot ?? null, external: false }] : [],
|
|
36018
|
-
{ root:
|
|
34790
|
+
{ root: path25__default.join(options.homeDir ?? os4__default.homedir(), ".fleet", "plugins"), builtInDistRoot: null, external: true }
|
|
36019
34791
|
];
|
|
36020
34792
|
const sourcePlugins = roots.flatMap((root) => discoverPluginRoot(root.root, root.builtInDistRoot, root.external));
|
|
36021
34793
|
const sourcePluginIds = new Set(sourcePlugins.map((plugin) => plugin.manifest.id));
|
|
@@ -36023,7 +34795,7 @@ function discoverFleetPlugins(options = {}) {
|
|
|
36023
34795
|
return [...sourcePlugins, ...distPlugins];
|
|
36024
34796
|
}
|
|
36025
34797
|
function parseFleetPluginManifest(value) {
|
|
36026
|
-
if (!
|
|
34798
|
+
if (!isRecord8(value)) return null;
|
|
36027
34799
|
const id = readPluginId(value.id);
|
|
36028
34800
|
if (!id) return null;
|
|
36029
34801
|
return {
|
|
@@ -36041,8 +34813,8 @@ function discoverPluginRoot(root, builtInDistRoot, external) {
|
|
|
36041
34813
|
const plugins = [];
|
|
36042
34814
|
for (const entry of entries) {
|
|
36043
34815
|
if (!entry.isDirectory() || entry.name === "shared") continue;
|
|
36044
|
-
const pluginRoot =
|
|
36045
|
-
const manifestPath =
|
|
34816
|
+
const pluginRoot = path25__default.join(root, entry.name);
|
|
34817
|
+
const manifestPath = path25__default.join(pluginRoot, "plugin.json");
|
|
36046
34818
|
if (!fs11__default.existsSync(manifestPath)) continue;
|
|
36047
34819
|
const manifest = readManifest(manifestPath);
|
|
36048
34820
|
if (!manifest) continue;
|
|
@@ -36060,8 +34832,8 @@ function discoverDistPluginRoot(root) {
|
|
|
36060
34832
|
const plugins = [];
|
|
36061
34833
|
for (const entry of entries) {
|
|
36062
34834
|
if (!entry.isDirectory() || entry.name === "shared") continue;
|
|
36063
|
-
const pluginRoot =
|
|
36064
|
-
const manifestPath =
|
|
34835
|
+
const pluginRoot = path25__default.join(root, entry.name);
|
|
34836
|
+
const manifestPath = path25__default.join(pluginRoot, "plugin.json");
|
|
36065
34837
|
const manifest = fs11__default.existsSync(manifestPath) ? readManifest(manifestPath) : readDistPluginManifest(entry.name);
|
|
36066
34838
|
if (!manifest) continue;
|
|
36067
34839
|
const clientEntry = resolveOptionalManifestEntry(pluginRoot, manifest.client, "client");
|
|
@@ -36088,10 +34860,10 @@ function resolveRoutesEntry(pluginRoot, manifest, builtInDistRoot) {
|
|
|
36088
34860
|
if (manifestRoute2 === false) return false;
|
|
36089
34861
|
if (manifestRoute2) return manifestRoute2;
|
|
36090
34862
|
}
|
|
36091
|
-
const manifestRoute =
|
|
34863
|
+
const manifestRoute = path25__default.join(pluginRoot, "routes.ts");
|
|
36092
34864
|
if (fs11__default.existsSync(manifestRoute)) return manifestRoute;
|
|
36093
34865
|
if (!builtInDistRoot) return null;
|
|
36094
|
-
const builtRoute =
|
|
34866
|
+
const builtRoute = path25__default.join(builtInDistRoot, manifest.id, "routes.mjs");
|
|
36095
34867
|
return fs11__default.existsSync(builtRoute) ? builtRoute : null;
|
|
36096
34868
|
}
|
|
36097
34869
|
function resolveDistRoutesEntry(pluginRoot, manifest) {
|
|
@@ -36105,7 +34877,7 @@ function resolveOptionalManifestEntry(pluginRoot, entryPath, label) {
|
|
|
36105
34877
|
console.warn(`[fleet-console] Plugin ${label} entry skipped: unsafe relative path ${entryPath}`);
|
|
36106
34878
|
return false;
|
|
36107
34879
|
}
|
|
36108
|
-
const candidate =
|
|
34880
|
+
const candidate = path25__default.resolve(pluginRoot, entryPath);
|
|
36109
34881
|
if (!fs11__default.existsSync(candidate)) return null;
|
|
36110
34882
|
const rootRealpath = fs11__default.realpathSync.native(pluginRoot);
|
|
36111
34883
|
const entryRealpath = fs11__default.realpathSync.native(candidate);
|
|
@@ -36123,14 +34895,14 @@ function readDistPluginManifest(id) {
|
|
|
36123
34895
|
return pluginId ? { id: pluginId, routes: "routes.mjs" } : null;
|
|
36124
34896
|
}
|
|
36125
34897
|
function isSafeRelativeEntry(entryPath) {
|
|
36126
|
-
if (
|
|
34898
|
+
if (path25__default.isAbsolute(entryPath)) return false;
|
|
36127
34899
|
return entryPath.split(/[\\/]+/u).every((segment) => segment !== "..");
|
|
36128
34900
|
}
|
|
36129
34901
|
function isSubpath2(root, candidate) {
|
|
36130
|
-
const relative =
|
|
36131
|
-
return relative === "" || !relative.startsWith("..") && !
|
|
34902
|
+
const relative = path25__default.relative(root, candidate);
|
|
34903
|
+
return relative === "" || !relative.startsWith("..") && !path25__default.isAbsolute(relative);
|
|
36132
34904
|
}
|
|
36133
|
-
function
|
|
34905
|
+
function isRecord8(value) {
|
|
36134
34906
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
36135
34907
|
}
|
|
36136
34908
|
|
|
@@ -36151,7 +34923,7 @@ var PLUGIN_DEV_EXTERNALS = [
|
|
|
36151
34923
|
"@dotobokuri/*",
|
|
36152
34924
|
"@fleet-plugins/*"
|
|
36153
34925
|
];
|
|
36154
|
-
var __dirname$1 =
|
|
34926
|
+
var __dirname$1 = path25__default.dirname(fileURLToPath(import.meta.url));
|
|
36155
34927
|
function createFleetPluginHost(deps) {
|
|
36156
34928
|
const plugins = filterDiscoveredPlugins(discoverFleetPlugins(deps));
|
|
36157
34929
|
const sensitiveFieldsByPluginId = new Map(plugins.map((plugin) => [plugin.manifest.id, plugin.manifest.sensitiveFields ?? []]));
|
|
@@ -36225,39 +34997,39 @@ async function importPluginModule(entry) {
|
|
|
36225
34997
|
return await import(pathToFileURL(entry).href);
|
|
36226
34998
|
}
|
|
36227
34999
|
async function writeTemporaryPluginBundle(entry, source) {
|
|
36228
|
-
const cacheRoot =
|
|
35000
|
+
const cacheRoot = path25__default.join(resolvePluginBundleNodeModules(entry), ".cache");
|
|
36229
35001
|
await mkdir(cacheRoot, { recursive: true });
|
|
36230
|
-
const dir = await mkdtemp(
|
|
36231
|
-
const file2 =
|
|
35002
|
+
const dir = await mkdtemp(path25__default.join(cacheRoot, "fleet-console-plugin-"));
|
|
35003
|
+
const file2 = path25__default.join(dir, "routes.mjs");
|
|
36232
35004
|
await writeFile(file2, source, "utf8");
|
|
36233
35005
|
return file2;
|
|
36234
35006
|
}
|
|
36235
35007
|
function resolvePluginBundleNodeModules(entry) {
|
|
36236
35008
|
const packageNodeModules = resolveConsolePackageNodeModules();
|
|
36237
|
-
let dir =
|
|
35009
|
+
let dir = path25__default.dirname(entry);
|
|
36238
35010
|
let fallback = packageNodeModules;
|
|
36239
35011
|
while (true) {
|
|
36240
|
-
const workspaceConsoleNodeModules =
|
|
35012
|
+
const workspaceConsoleNodeModules = path25__default.join(dir, "runtime", "fleet-console", "node_modules");
|
|
36241
35013
|
if (hasFleetConsoleSdk(workspaceConsoleNodeModules)) return workspaceConsoleNodeModules;
|
|
36242
|
-
const candidate =
|
|
35014
|
+
const candidate = path25__default.join(dir, "node_modules");
|
|
36243
35015
|
if (hasFleetConsoleSdk(candidate)) return candidate;
|
|
36244
35016
|
if (fallback === null && existsSync(candidate)) fallback = candidate;
|
|
36245
|
-
const parent =
|
|
36246
|
-
if (parent === dir) return fallback ??
|
|
35017
|
+
const parent = path25__default.dirname(dir);
|
|
35018
|
+
if (parent === dir) return fallback ?? path25__default.join(path25__default.dirname(entry), "node_modules");
|
|
36247
35019
|
dir = parent;
|
|
36248
35020
|
}
|
|
36249
35021
|
}
|
|
36250
35022
|
function resolveConsolePackageNodeModules() {
|
|
36251
35023
|
for (const candidate of [
|
|
36252
|
-
|
|
36253
|
-
|
|
35024
|
+
path25__default.resolve(__dirname$1, "..", "node_modules"),
|
|
35025
|
+
path25__default.resolve(__dirname$1, "..", "..", "..", "node_modules")
|
|
36254
35026
|
]) {
|
|
36255
35027
|
if (hasFleetConsoleSdk(candidate)) return candidate;
|
|
36256
35028
|
}
|
|
36257
35029
|
return null;
|
|
36258
35030
|
}
|
|
36259
35031
|
function hasFleetConsoleSdk(nodeModules) {
|
|
36260
|
-
return existsSync(
|
|
35032
|
+
return existsSync(path25__default.join(nodeModules, "@fleet-console", "sdk"));
|
|
36261
35033
|
}
|
|
36262
35034
|
function resolveRegister(mod) {
|
|
36263
35035
|
if (mod.register) return mod.register;
|
|
@@ -36516,6 +35288,14 @@ function normalizePrefix3(prefix) {
|
|
|
36516
35288
|
function matchesPrefix2(pathname, prefix) {
|
|
36517
35289
|
return pathname === prefix || pathname.startsWith(`${prefix}/`);
|
|
36518
35290
|
}
|
|
35291
|
+
|
|
35292
|
+
// core/host/sse.ts
|
|
35293
|
+
function encodeSseData(event, data) {
|
|
35294
|
+
return `event: ${event}
|
|
35295
|
+
data: ${JSON.stringify(data)}
|
|
35296
|
+
|
|
35297
|
+
`;
|
|
35298
|
+
}
|
|
36519
35299
|
var MIME_TYPES = {
|
|
36520
35300
|
".css": "text/css; charset=utf-8",
|
|
36521
35301
|
".html": "text/html; charset=utf-8",
|
|
@@ -36525,7 +35305,7 @@ var MIME_TYPES = {
|
|
|
36525
35305
|
".woff2": "font/woff2"
|
|
36526
35306
|
};
|
|
36527
35307
|
function createStaticConsoleHandler(packageRoot) {
|
|
36528
|
-
const consoleRoot =
|
|
35308
|
+
const consoleRoot = path25__default.join(packageRoot, "dist", "client");
|
|
36529
35309
|
return (req, res, pathname) => tryServeStaticConsole(req, res, pathname, consoleRoot);
|
|
36530
35310
|
}
|
|
36531
35311
|
function tryServeStaticConsole(req, res, pathname, consoleRoot) {
|
|
@@ -36541,7 +35321,7 @@ function tryServeStaticConsole(req, res, pathname, consoleRoot) {
|
|
|
36541
35321
|
res.end(JSON.stringify({ error: "Not found" }));
|
|
36542
35322
|
return true;
|
|
36543
35323
|
}
|
|
36544
|
-
const absolutePath =
|
|
35324
|
+
const absolutePath = path25__default.resolve(consoleRoot, relativePath2);
|
|
36545
35325
|
if (!absolutePath.startsWith(consoleRoot)) {
|
|
36546
35326
|
res.writeHead(404, withSecurityHeaders2({ "Content-Type": "application/json" }));
|
|
36547
35327
|
res.end(JSON.stringify({ error: "Not found" }));
|
|
@@ -36549,7 +35329,7 @@ function tryServeStaticConsole(req, res, pathname, consoleRoot) {
|
|
|
36549
35329
|
}
|
|
36550
35330
|
try {
|
|
36551
35331
|
const data = fs11__default.readFileSync(absolutePath);
|
|
36552
|
-
const contentType = MIME_TYPES[
|
|
35332
|
+
const contentType = MIME_TYPES[path25__default.extname(absolutePath)] ?? "application/octet-stream";
|
|
36553
35333
|
res.writeHead(200, withSecurityHeaders2({ "Content-Type": contentType }));
|
|
36554
35334
|
if (req.method === "HEAD") {
|
|
36555
35335
|
res.end();
|
|
@@ -36569,7 +35349,7 @@ function tryServeStaticConsole(req, res, pathname, consoleRoot) {
|
|
|
36569
35349
|
}
|
|
36570
35350
|
function serveFallbackIndex(req, res, consoleRoot) {
|
|
36571
35351
|
try {
|
|
36572
|
-
const data = fs11__default.readFileSync(
|
|
35352
|
+
const data = fs11__default.readFileSync(path25__default.join(consoleRoot, "index.html"));
|
|
36573
35353
|
res.writeHead(200, withSecurityHeaders2({ "Content-Type": MIME_TYPES[".html"] }));
|
|
36574
35354
|
if (req.method === "HEAD") {
|
|
36575
35355
|
res.end();
|
|
@@ -36595,7 +35375,7 @@ function resolveConsolePath(pathname) {
|
|
|
36595
35375
|
}
|
|
36596
35376
|
if (withoutPrefix === "") return "index.html";
|
|
36597
35377
|
if (withoutPrefix.includes("\0")) return null;
|
|
36598
|
-
if (!
|
|
35378
|
+
if (!path25__default.extname(withoutPrefix)) return "index.html";
|
|
36599
35379
|
return withoutPrefix;
|
|
36600
35380
|
}
|
|
36601
35381
|
var TheaterFolderListError = class extends Error {
|
|
@@ -36629,14 +35409,14 @@ async function listTheaterFolders(requestedPath, deps = {}) {
|
|
|
36629
35409
|
}
|
|
36630
35410
|
function normalizeFolderBrowserPath(value, platform = process.platform) {
|
|
36631
35411
|
if (typeof value !== "string" || value.length === 0 || value.includes("\0")) throw new TheaterFolderListError("invalid_path");
|
|
36632
|
-
if (isWindowsAmbiguousPath(value, platform) || !
|
|
36633
|
-
return
|
|
35412
|
+
if (isWindowsAmbiguousPath(value, platform) || !path25__default.isAbsolute(value)) throw new TheaterFolderListError("invalid_path");
|
|
35413
|
+
return path25__default.resolve(value);
|
|
36634
35414
|
}
|
|
36635
35415
|
function normalizeListPath(requestedPath, platform, deps) {
|
|
36636
35416
|
if (requestedPath === null || requestedPath === void 0) {
|
|
36637
|
-
const home = deps.homedir?.() ??
|
|
35417
|
+
const home = deps.homedir?.() ?? os4__default.homedir();
|
|
36638
35418
|
const start = home || deps.cwd?.() || process.cwd();
|
|
36639
|
-
return
|
|
35419
|
+
return path25__default.resolve(start);
|
|
36640
35420
|
}
|
|
36641
35421
|
return normalizeFolderBrowserPath(requestedPath, platform);
|
|
36642
35422
|
}
|
|
@@ -36687,7 +35467,7 @@ async function openDirectory(targetPath, opendir) {
|
|
|
36687
35467
|
}
|
|
36688
35468
|
async function toTheaterFolderEntry(targetPath, dirent, stat5) {
|
|
36689
35469
|
if (!dirent.isDirectory() && !dirent.isSymbolicLink()) return null;
|
|
36690
|
-
const entryPath =
|
|
35470
|
+
const entryPath = path25__default.join(targetPath, dirent.name);
|
|
36691
35471
|
if (dirent.isDirectory()) return { name: dirent.name, path: entryPath, kind: "dir", accessible: true };
|
|
36692
35472
|
const accessible = await statSymlinkDirectory(entryPath, stat5);
|
|
36693
35473
|
if (accessible === null) return null;
|
|
@@ -36707,10 +35487,10 @@ function mapFsError(error51) {
|
|
|
36707
35487
|
return new TheaterFolderListError("invalid_path");
|
|
36708
35488
|
}
|
|
36709
35489
|
function parentPath(targetPath, platform) {
|
|
36710
|
-
const parsed =
|
|
36711
|
-
const resolved =
|
|
36712
|
-
if (resolved ===
|
|
36713
|
-
const parent =
|
|
35490
|
+
const parsed = path25__default.parse(targetPath);
|
|
35491
|
+
const resolved = path25__default.resolve(targetPath);
|
|
35492
|
+
if (resolved === path25__default.resolve(parsed.root)) return null;
|
|
35493
|
+
const parent = path25__default.dirname(resolved);
|
|
36714
35494
|
if (platform === "win32" && parent === resolved) return null;
|
|
36715
35495
|
return parent;
|
|
36716
35496
|
}
|
|
@@ -36750,8 +35530,8 @@ function createFolderGrantStore(deps = {}) {
|
|
|
36750
35530
|
}
|
|
36751
35531
|
function validateAbsoluteDirectory(cwd, statSync2 = fs11__default.statSync) {
|
|
36752
35532
|
if (typeof cwd !== "string" || cwd.length === 0 || cwd.includes("\0")) throw new Error("invalid_folder");
|
|
36753
|
-
if (isWindowsAmbiguousPath2(cwd) || !
|
|
36754
|
-
const normalized =
|
|
35533
|
+
if (isWindowsAmbiguousPath2(cwd) || !path25__default.isAbsolute(cwd)) throw new Error("invalid_folder");
|
|
35534
|
+
const normalized = path25__default.resolve(cwd);
|
|
36755
35535
|
if (!statSync2(normalized).isDirectory()) throw new Error("invalid_folder");
|
|
36756
35536
|
return normalized;
|
|
36757
35537
|
}
|
|
@@ -36763,7 +35543,7 @@ var TheaterRegistry = class {
|
|
|
36763
35543
|
#items = /* @__PURE__ */ new Map();
|
|
36764
35544
|
#mruId = null;
|
|
36765
35545
|
async register(cwd) {
|
|
36766
|
-
const resolved =
|
|
35546
|
+
const resolved = path25__default.resolve(cwd);
|
|
36767
35547
|
const real = await canonicalizeTheaterPath(resolved);
|
|
36768
35548
|
const id = workspaceHash(real);
|
|
36769
35549
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -36835,17 +35615,17 @@ function createConsoleUpdateApplyService(deps = {}) {
|
|
|
36835
35615
|
const preflightInstall = deps.preflightInstall ?? ((currentPackageRoot) => preflightPackageManager(currentPackageRoot, env));
|
|
36836
35616
|
const serverModulePath = deps.serverModulePath ?? resolveDefaultServerModulePath();
|
|
36837
35617
|
const spawnWorker = deps.spawnWorker ?? defaultSpawnWorker;
|
|
36838
|
-
const tmpDir = deps.tmpDir ??
|
|
35618
|
+
const tmpDir = deps.tmpDir ?? os4__default.tmpdir();
|
|
36839
35619
|
const writeFile5 = deps.writeFile ?? ((filePath, content, options) => {
|
|
36840
35620
|
fs11__default.writeFileSync(filePath, content, { mode: options.mode });
|
|
36841
35621
|
});
|
|
36842
35622
|
async function start(request) {
|
|
36843
35623
|
const packageManager = await preflightInstall(request.currentPackageRoot);
|
|
36844
35624
|
const stamp = `${now()}-${processPid}`;
|
|
36845
|
-
const workerPath =
|
|
35625
|
+
const workerPath = path25__default.join(tmpDir, `${WORKER_FILE_PREFIX}${stamp}${WORKER_FILE_SUFFIX}`);
|
|
36846
35626
|
makeDir(request.dataDir, { recursive: true, mode: 448 });
|
|
36847
|
-
const statusFile =
|
|
36848
|
-
const logFile =
|
|
35627
|
+
const statusFile = path25__default.join(request.dataDir, `${WORKER_FILE_PREFIX}${stamp}${STATUS_FILE_SUFFIX}`);
|
|
35628
|
+
const logFile = path25__default.join(request.dataDir, `${WORKER_FILE_PREFIX}${stamp}${LOG_FILE_SUFFIX}`);
|
|
36849
35629
|
const script = emitConsoleUpdateWorkerScript({
|
|
36850
35630
|
currentEndpoint: request.currentEndpoint,
|
|
36851
35631
|
currentPackageRoot: request.currentPackageRoot,
|
|
@@ -37193,7 +35973,7 @@ function resolveDefaultServerModulePath() {
|
|
|
37193
35973
|
if (sourcePath.endsWith(".ts")) {
|
|
37194
35974
|
return sourcePath.replace(/update-apply\.ts$/, "cli.ts");
|
|
37195
35975
|
}
|
|
37196
|
-
return
|
|
35976
|
+
return path25__default.join(path25__default.dirname(sourcePath), "cli.mjs");
|
|
37197
35977
|
}
|
|
37198
35978
|
|
|
37199
35979
|
// core/host/update-check.ts
|
|
@@ -37323,27 +36103,6 @@ var SERVER_API_CATALOG = [
|
|
|
37323
36103
|
category: "Terminal Plugin",
|
|
37324
36104
|
gate: "origin-write"
|
|
37325
36105
|
},
|
|
37326
|
-
{
|
|
37327
|
-
method: "GET",
|
|
37328
|
-
path: "/plugins/terminal/model-auth/state",
|
|
37329
|
-
summary: "Get Terminal plugin model sign-in status.",
|
|
37330
|
-
category: "Terminal Plugin",
|
|
37331
|
-
gate: "loopback"
|
|
37332
|
-
},
|
|
37333
|
-
{
|
|
37334
|
-
method: "PUT",
|
|
37335
|
-
path: "/plugins/terminal/model-auth/providers/:cli",
|
|
37336
|
-
summary: "Register a Terminal plugin model provider API key.",
|
|
37337
|
-
category: "Terminal Plugin",
|
|
37338
|
-
gate: "origin-write"
|
|
37339
|
-
},
|
|
37340
|
-
{
|
|
37341
|
-
method: "DELETE",
|
|
37342
|
-
path: "/plugins/terminal/model-auth/providers/:cli",
|
|
37343
|
-
summary: "Remove a Terminal plugin model provider API key.",
|
|
37344
|
-
category: "Terminal Plugin",
|
|
37345
|
-
gate: "origin-write"
|
|
37346
|
-
},
|
|
37347
36106
|
{
|
|
37348
36107
|
method: "POST",
|
|
37349
36108
|
path: "/api/v1/theaters/folder-listings",
|
|
@@ -37408,6 +36167,7 @@ function createConsoleServer(deps = {}) {
|
|
|
37408
36167
|
const pluginLaunchCatalogProviders = /* @__PURE__ */ new Map();
|
|
37409
36168
|
const pluginCleanupCallbacks = /* @__PURE__ */ new Set();
|
|
37410
36169
|
const pluginEventListeners = /* @__PURE__ */ new Map();
|
|
36170
|
+
const operationSseSubscribers = /* @__PURE__ */ new Set();
|
|
37411
36171
|
const pluginHostCapabilities = {
|
|
37412
36172
|
operations: {
|
|
37413
36173
|
list: () => operations.list(),
|
|
@@ -37418,8 +36178,14 @@ function createConsoleServer(deps = {}) {
|
|
|
37418
36178
|
return operation;
|
|
37419
36179
|
},
|
|
37420
36180
|
patch: (id, input) => {
|
|
36181
|
+
const previousTitle = "title" in input ? operations.get(id)?.title : void 0;
|
|
37421
36182
|
const operation = operations.patch(id, input);
|
|
37422
|
-
if (operation)
|
|
36183
|
+
if (operation) {
|
|
36184
|
+
persistDurableState();
|
|
36185
|
+
if (previousTitle !== void 0 && previousTitle !== operation.title) {
|
|
36186
|
+
broadcastOperationChanged(operation);
|
|
36187
|
+
}
|
|
36188
|
+
}
|
|
37423
36189
|
return operation;
|
|
37424
36190
|
},
|
|
37425
36191
|
delete: (id) => {
|
|
@@ -37473,7 +36239,7 @@ function createConsoleServer(deps = {}) {
|
|
|
37473
36239
|
paths: {
|
|
37474
36240
|
dataDir: durablePaths.dir,
|
|
37475
36241
|
capturesDir: durablePaths.capturesDir,
|
|
37476
|
-
pluginDataDir: (pluginId) =>
|
|
36242
|
+
pluginDataDir: (pluginId) => path25__default.join(durablePaths.dir, "plugins", pluginId),
|
|
37477
36243
|
resolveTheaterPath: (theaterId) => theaters.get(theaterId)?.path ?? null,
|
|
37478
36244
|
canonicalizeTheaterPath: canonicalizeTheaterPathSync,
|
|
37479
36245
|
workspaceHash
|
|
@@ -37577,7 +36343,20 @@ function createConsoleServer(deps = {}) {
|
|
|
37577
36343
|
],
|
|
37578
36344
|
resolveLaunchCatalog: resolveOperationCatalog,
|
|
37579
36345
|
publishRenameEvent: (event) => pluginHostCapabilities.events.publish(OPERATION_RENAMED_EVENT_CHANNEL, event),
|
|
37580
|
-
publishDeleteEvent: (event) => pluginHostCapabilities.events.publish(OPERATION_DELETED_EVENT_CHANNEL, event)
|
|
36346
|
+
publishDeleteEvent: (event) => pluginHostCapabilities.events.publish(OPERATION_DELETED_EVENT_CHANNEL, event),
|
|
36347
|
+
broadcastOperationChanged,
|
|
36348
|
+
subscribeOperationSse: (res) => {
|
|
36349
|
+
res.writeHead(200, withSecurityHeaders2({
|
|
36350
|
+
"Content-Type": "text/event-stream",
|
|
36351
|
+
"Cache-Control": "no-cache",
|
|
36352
|
+
"Connection": "keep-alive"
|
|
36353
|
+
}));
|
|
36354
|
+
res.write(":connected\n\n");
|
|
36355
|
+
operationSseSubscribers.add(res);
|
|
36356
|
+
res.on("close", () => {
|
|
36357
|
+
operationSseSubscribers.delete(res);
|
|
36358
|
+
});
|
|
36359
|
+
}
|
|
37581
36360
|
});
|
|
37582
36361
|
routeRegistry.register("/api/v1/operations", operationsRouter);
|
|
37583
36362
|
routeRegistry.register("/api/v1/settings", async (ctx) => {
|
|
@@ -37996,6 +36775,18 @@ function createConsoleServer(deps = {}) {
|
|
|
37996
36775
|
}
|
|
37997
36776
|
}
|
|
37998
36777
|
}
|
|
36778
|
+
function broadcastOperationChanged(node) {
|
|
36779
|
+
if (operationSseSubscribers.size === 0) return;
|
|
36780
|
+
const sensitiveFields = [
|
|
36781
|
+
...pluginHost.sensitiveFieldsByPluginId.get(node.pluginId) ?? [],
|
|
36782
|
+
...pluginPayloadSanitizers.get(node.pluginId) ?? []
|
|
36783
|
+
];
|
|
36784
|
+
const sanitized = createSanitizedOpDto(node, { sensitiveFields });
|
|
36785
|
+
const data = encodeSseData("operation:changed", { operation: sanitized });
|
|
36786
|
+
for (const res of operationSseSubscribers) {
|
|
36787
|
+
res.write(data);
|
|
36788
|
+
}
|
|
36789
|
+
}
|
|
37999
36790
|
function persistDurableState() {
|
|
38000
36791
|
try {
|
|
38001
36792
|
durableStateStore.save({
|
|
@@ -38134,11 +36925,11 @@ function createConsoleServer(deps = {}) {
|
|
|
38134
36925
|
return returnedServer;
|
|
38135
36926
|
}
|
|
38136
36927
|
function resolveBuiltInPluginDiscoveryRoots(packageRoot) {
|
|
38137
|
-
const packageRootRepo =
|
|
38138
|
-
const sourceRoot =
|
|
36928
|
+
const packageRootRepo = path25__default.resolve(packageRoot, "..", "..");
|
|
36929
|
+
const sourceRoot = path25__default.join(packageRootRepo, "runtime", "fleet-plugins");
|
|
38139
36930
|
return {
|
|
38140
36931
|
...fs11__default.existsSync(sourceRoot) ? { builtInSourceRoot: sourceRoot } : {},
|
|
38141
|
-
builtInDistRoot:
|
|
36932
|
+
builtInDistRoot: path25__default.join(packageRoot, "dist", "fleet-plugins")
|
|
38142
36933
|
};
|
|
38143
36934
|
}
|
|
38144
36935
|
function createHttpServer(handler, upgradeRegistry) {
|
|
@@ -38291,14 +37082,14 @@ async function readPluginStorageJson(dataDir, pluginId, key) {
|
|
|
38291
37082
|
}
|
|
38292
37083
|
async function writePluginStorageJson(dataDir, pluginId, key, value) {
|
|
38293
37084
|
const file2 = resolvePluginStorageFile(dataDir, pluginId, key);
|
|
38294
|
-
await fs11__default.promises.mkdir(
|
|
37085
|
+
await fs11__default.promises.mkdir(path25__default.dirname(file2), { recursive: true });
|
|
38295
37086
|
await fs11__default.promises.writeFile(file2, JSON.stringify(value), "utf8");
|
|
38296
37087
|
}
|
|
38297
37088
|
function resolvePluginStorageFile(dataDir, pluginId, key) {
|
|
38298
37089
|
if (!/^[a-z0-9][a-z0-9._-]*$/i.test(pluginId) || !/^[a-z0-9][a-z0-9._-]*$/i.test(key)) {
|
|
38299
37090
|
throw new Error("invalid_plugin_storage_key");
|
|
38300
37091
|
}
|
|
38301
|
-
return
|
|
37092
|
+
return path25__default.join(dataDir, "plugins", pluginId, `${key}.json`);
|
|
38302
37093
|
}
|
|
38303
37094
|
function isNodeError(error51) {
|
|
38304
37095
|
return error51 instanceof Error && "code" in error51;
|
|
@@ -38320,7 +37111,7 @@ function createConsoleStalePolicy(deps = {}) {
|
|
|
38320
37111
|
var FIXED_HOST = "127.0.0.1";
|
|
38321
37112
|
var HELP_BANNER_INDENT = " ";
|
|
38322
37113
|
var DEFAULT_HELP_RELEASE = "local";
|
|
38323
|
-
var CONSOLE_HOOK_COMMANDS = /* @__PURE__ */ new Set(["capture-session", "
|
|
37114
|
+
var CONSOLE_HOOK_COMMANDS = /* @__PURE__ */ new Set(["capture-session", "turn-start", "turn-end", "attention", "auto-name"]);
|
|
38324
37115
|
function parseConsoleCliMode(argv) {
|
|
38325
37116
|
if (argv.length === 0) return "start";
|
|
38326
37117
|
const [first, ...rest] = argv;
|
|
@@ -38350,7 +37141,6 @@ function parseConsoleHookCommand(argv) {
|
|
|
38350
37141
|
if (!commandName || !CONSOLE_HOOK_COMMANDS.has(commandName)) {
|
|
38351
37142
|
throw new Error("Unknown fleet-console hook command");
|
|
38352
37143
|
}
|
|
38353
|
-
if (commandName === "subagents-context" && rest.length === 0) return { command: "subagents-context" };
|
|
38354
37144
|
if (commandName === "turn-start" && rest.length === 0) return { command: "turn-start" };
|
|
38355
37145
|
if (commandName === "turn-end" && rest.length === 0) return { command: "turn-end" };
|
|
38356
37146
|
if (commandName === "attention" && rest.length === 0) return { command: "attention" };
|
|
@@ -38522,11 +37312,6 @@ async function main() {
|
|
|
38522
37312
|
}
|
|
38523
37313
|
if (process4.argv[2] === "hook") {
|
|
38524
37314
|
const hookCommand = parseConsoleHookCommand(process4.argv.slice(3));
|
|
38525
|
-
if (hookCommand.command === "subagents-context") {
|
|
38526
|
-
process4.stdout.write(`${runSubagentsContextHook(process4.env)}
|
|
38527
|
-
`);
|
|
38528
|
-
return;
|
|
38529
|
-
}
|
|
38530
37315
|
if (hookCommand.command === "turn-start" || hookCommand.command === "turn-end") {
|
|
38531
37316
|
await postAgentHook(`/sessions/${readHookSessionId(process4.env)}/turn`, { phase: hookCommand.command === "turn-start" ? "start" : "end" }, process4.env);
|
|
38532
37317
|
return;
|
|
@@ -38622,7 +37407,7 @@ function readStdinBestEffort() {
|
|
|
38622
37407
|
});
|
|
38623
37408
|
});
|
|
38624
37409
|
}
|
|
38625
|
-
var isDirectRun = process4.argv[1] &&
|
|
37410
|
+
var isDirectRun = process4.argv[1] && path25__default.resolve(process4.argv[1]) === fileURLToPath(import.meta.url);
|
|
38626
37411
|
if (isDirectRun) {
|
|
38627
37412
|
await main().catch((error51) => {
|
|
38628
37413
|
process4.stderr.write(`${error51 instanceof Error ? error51.message : String(error51)}
|