@dotobokuri/fleet-console 1.17.1 → 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.
Files changed (66) hide show
  1. package/AGENTS.md +5 -5
  2. package/dist/cli.d.ts +0 -2
  3. package/dist/cli.mjs +1055 -2270
  4. package/dist/client/assets/{_baseUniq-B7sqIsqm.js → _baseUniq-DFEDX4NY.js} +1 -1
  5. package/dist/client/assets/{arc-CvtYLN8U.js → arc-CGwMrR6o.js} +1 -1
  6. package/dist/client/assets/{architectureDiagram-Q4EWVU46-rlI7pNrR.js → architectureDiagram-Q4EWVU46-BqLyvIOK.js} +1 -1
  7. package/dist/client/assets/{blockDiagram-DXYQGD6D-nwx9BNRz.js → blockDiagram-DXYQGD6D-DoiPMLdv.js} +1 -1
  8. package/dist/client/assets/{c4Diagram-AHTNJAMY-CRL_0Ism.js → c4Diagram-AHTNJAMY-DfGxDkah.js} +1 -1
  9. package/dist/client/assets/channel-DlT8zCVq.js +1 -0
  10. package/dist/client/assets/{chunk-4BX2VUAB-DEkncDR3.js → chunk-4BX2VUAB-3zXv74oY.js} +1 -1
  11. package/dist/client/assets/{chunk-4TB4RGXK-Bnot0Ti1.js → chunk-4TB4RGXK-MkXUmjUE.js} +1 -1
  12. package/dist/client/assets/{chunk-55IACEB6-EgKmMTlI.js → chunk-55IACEB6-mhkgqlI_.js} +1 -1
  13. package/dist/client/assets/{chunk-EDXVE4YY-BKiKnVQE.js → chunk-EDXVE4YY-B0_ZDihs.js} +1 -1
  14. package/dist/client/assets/{chunk-FMBD7UC4-BRC398vL.js → chunk-FMBD7UC4-BQAuE4pL.js} +1 -1
  15. package/dist/client/assets/{chunk-OYMX7WX6-D82gQaXN.js → chunk-OYMX7WX6-CY8Eyj9X.js} +1 -1
  16. package/dist/client/assets/{chunk-QZHKN3VN-BYdI5fky.js → chunk-QZHKN3VN-CaZoMwKH.js} +1 -1
  17. package/dist/client/assets/{chunk-YZCP3GAM-BhBgOoc0.js → chunk-YZCP3GAM-DV1YOEUH.js} +1 -1
  18. package/dist/client/assets/classDiagram-6PBFFD2Q-B-UN9f9r.js +1 -0
  19. package/dist/client/assets/classDiagram-v2-HSJHXN6E-B-UN9f9r.js +1 -0
  20. package/dist/client/assets/clone-CDPRFCO0.js +1 -0
  21. package/dist/client/assets/{cose-bilkent-S5V4N54A-J8dfEdWD.js → cose-bilkent-S5V4N54A-Cy3v0C_N.js} +1 -1
  22. package/dist/client/assets/{dagre-KV5264BT-zGd_6_Kv.js → dagre-KV5264BT-CGJ6x_VR.js} +1 -1
  23. package/dist/client/assets/{diagram-5BDNPKRD-BQpQGgZ3.js → diagram-5BDNPKRD-MyyXeHKQ.js} +1 -1
  24. package/dist/client/assets/{diagram-G4DWMVQ6-BbgPVITm.js → diagram-G4DWMVQ6-D52Q2132.js} +1 -1
  25. package/dist/client/assets/{diagram-MMDJMWI5-lJsMf0Ic.js → diagram-MMDJMWI5-DCypusCr.js} +1 -1
  26. package/dist/client/assets/{diagram-TYMM5635-BpEKTzOh.js → diagram-TYMM5635-c5UBqE9-.js} +1 -1
  27. package/dist/client/assets/{erDiagram-SMLLAGMA-CHHVwJ_a.js → erDiagram-SMLLAGMA-BlF0Lxy7.js} +1 -1
  28. package/dist/client/assets/{flowDiagram-DWJPFMVM-Cun8a4NF.js → flowDiagram-DWJPFMVM-lo8xyzfx.js} +1 -1
  29. package/dist/client/assets/{ganttDiagram-T4ZO3ILL-CGCwH_yf.js → ganttDiagram-T4ZO3ILL-BXVZMpon.js} +1 -1
  30. package/dist/client/assets/{gitGraphDiagram-UUTBAWPF-BkY4qdoV.js → gitGraphDiagram-UUTBAWPF-DB1A6uYk.js} +1 -1
  31. package/dist/client/assets/{graph-HbRzXQtt.js → graph-Ck2AX1p2.js} +1 -1
  32. package/dist/client/assets/index-Cf9MmpwN.css +1 -0
  33. package/dist/client/assets/index-DWgndVkX.js +404 -0
  34. package/dist/client/assets/{infoDiagram-42DDH7IO-B21Xtz8v.js → infoDiagram-42DDH7IO-NEVE42fw.js} +1 -1
  35. package/dist/client/assets/{ishikawaDiagram-UXIWVN3A-DiABngEH.js → ishikawaDiagram-UXIWVN3A-MbFr_8pL.js} +1 -1
  36. package/dist/client/assets/{journeyDiagram-VCZTEJTY-BKZ-Uivu.js → journeyDiagram-VCZTEJTY-Sq2ja3q8.js} +1 -1
  37. package/dist/client/assets/{kanban-definition-6JOO6SKY-CoJzTtsH.js → kanban-definition-6JOO6SKY-C63qPhtK.js} +1 -1
  38. package/dist/client/assets/{layout-D5tmQpxt.js → layout-CFEuVj4N.js} +1 -1
  39. package/dist/client/assets/{linear-B_riNOXk.js → linear-B626G8Op.js} +1 -1
  40. package/dist/client/assets/{mermaid.core-CyRCP3U3.js → mermaid.core-BT7SVKBR.js} +4 -4
  41. package/dist/client/assets/{min-Cn8LZZXB.js → min-MbEOApMw.js} +1 -1
  42. package/dist/client/assets/{mindmap-definition-QFDTVHPH-BN_7mZUt.js → mindmap-definition-QFDTVHPH-DMpht5Mg.js} +1 -1
  43. package/dist/client/assets/{pieDiagram-DEJITSTG-DPP2-sYA.js → pieDiagram-DEJITSTG-B4XS0haZ.js} +1 -1
  44. package/dist/client/assets/{quadrantDiagram-34T5L4WZ-CQ_oo-f9.js → quadrantDiagram-34T5L4WZ-CReo5Ajb.js} +1 -1
  45. package/dist/client/assets/{requirementDiagram-MS252O5E-BkGq7nxD.js → requirementDiagram-MS252O5E-A50aqG-K.js} +1 -1
  46. package/dist/client/assets/{sankeyDiagram-XADWPNL6-BVcoktBR.js → sankeyDiagram-XADWPNL6-471VOdlW.js} +1 -1
  47. package/dist/client/assets/{sequenceDiagram-FGHM5R23-B5rr_VYJ.js → sequenceDiagram-FGHM5R23-BAvOyUC-.js} +1 -1
  48. package/dist/client/assets/{stateDiagram-FHFEXIEX-BV8RqzB9.js → stateDiagram-FHFEXIEX-gCtZrvR-.js} +1 -1
  49. package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-Bdb0YU66.js +1 -0
  50. package/dist/client/assets/{timeline-definition-GMOUNBTQ-CJ8TM-3t.js → timeline-definition-GMOUNBTQ-CTHf-uxq.js} +1 -1
  51. package/dist/client/assets/{vennDiagram-DHZGUBPP-BETSq-Pu.js → vennDiagram-DHZGUBPP-5gvXi0dO.js} +1 -1
  52. package/dist/client/assets/{wardley-RL74JXVD-CyT2qapq.js → wardley-RL74JXVD-XR-qQTWZ.js} +1 -1
  53. package/dist/client/assets/{wardleyDiagram-NUSXRM2D-CWHaiUEG.js → wardleyDiagram-NUSXRM2D-EwPsMHdt.js} +1 -1
  54. package/dist/client/assets/{xychartDiagram-5P7HB3ND-oVPlZ_Yn.js → xychartDiagram-5P7HB3ND-CePwuUb7.js} +1 -1
  55. package/dist/client/index.html +2 -2
  56. package/dist/fleet-plugins/diff/routes.mjs +76 -21
  57. package/dist/fleet-plugins/skills/routes.mjs +7 -118
  58. package/dist/fleet-plugins/terminal/routes.mjs +281 -974
  59. package/package.json +1 -1
  60. package/dist/client/assets/channel-Ct9EqqyG.js +0 -1
  61. package/dist/client/assets/classDiagram-6PBFFD2Q-CPMS8Qpo.js +0 -1
  62. package/dist/client/assets/classDiagram-v2-HSJHXN6E-CPMS8Qpo.js +0 -1
  63. package/dist/client/assets/clone-C5XNYXHD.js +0 -1
  64. package/dist/client/assets/index-CfNSyAUJ.css +0 -1
  65. package/dist/client/assets/index-CzCMC0e-.js +0 -402
  66. package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-Bx_fpQWQ.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, { readFileSync, realpathSync, accessSync, constants, existsSync, lstatSync } from 'fs';
5
- import * as path26 from 'path';
6
- import path26__default, { join, resolve, relative, sep, dirname } from 'path';
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 os3 from 'os';
10
- import os3__default from 'os';
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 ?? os3__default.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: () => hostname2,
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, path47) {
1008
- if (!path47)
1710
+ function getElementAtPath(obj, path46) {
1711
+ if (!path46)
1009
1712
  return obj;
1010
- return path47.reduce((acc, key) => acc?.[key], obj);
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(path47, issues) {
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(path47);
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, path47 = []) => {
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 }, [...path47, ...issue2.path]));
2276
+ issue2.errors.map((issues) => processError({ issues }, [...path46, ...issue2.path]));
1574
2277
  } else if (issue2.code === "invalid_key") {
1575
- processError({ issues: issue2.issues }, [...path47, ...issue2.path]);
2278
+ processError({ issues: issue2.issues }, [...path46, ...issue2.path]);
1576
2279
  } else if (issue2.code === "invalid_element") {
1577
- processError({ issues: issue2.issues }, [...path47, ...issue2.path]);
2280
+ processError({ issues: issue2.issues }, [...path46, ...issue2.path]);
1578
2281
  } else {
1579
- const fullpath = [...path47, ...issue2.path];
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, path47 = []) => {
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 }, [...path47, ...issue2.path]));
2313
+ issue2.errors.map((issues) => processError({ issues }, [...path46, ...issue2.path]));
1611
2314
  } else if (issue2.code === "invalid_key") {
1612
- processError({ issues: issue2.issues }, [...path47, ...issue2.path]);
2315
+ processError({ issues: issue2.issues }, [...path46, ...issue2.path]);
1613
2316
  } else if (issue2.code === "invalid_element") {
1614
- processError({ issues: issue2.issues }, [...path47, ...issue2.path]);
2317
+ processError({ issues: issue2.issues }, [...path46, ...issue2.path]);
1615
2318
  } else {
1616
- const fullpath = [...path47, ...issue2.path];
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 path47 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
1649
- for (const seg of path47) {
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: () => 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 hostname = /^(?=.{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])?)*\.?$/;
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: () => hostname2,
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 hostname2(_params) {
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 path47 = ref.slice(1).split("/").filter(Boolean);
14314
- if (path47.length === 0) {
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 (path47[0] === defsKey) {
14319
- const key = path47[1];
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" || this.cliType === "claude-zai" || this.cliType === "claude-kimi" || this.cliType === "claude-glm";
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-06-16T00:00:00Z",
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/kimi-k2.6", name: "Kimi K2.6 (3x limits)", effort: { supported: false } }
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: "claude-opus-4-7-thinking", name: "Claude Opus 4.7 Thinking", spawnModelTemplate: "claude-opus-4-7-thinking-{effort}", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max"], default: "xhigh" } },
18216
- { 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" } },
18217
- { modelId: "claude-4.6-sonnet-medium-thinking", name: "Claude Sonnet 4.6 Medium Thinking", effort: { supported: false } }
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 ?? path26.join(this.env.HOME ?? "", ".codex");
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(path26.join(codexHome, rootName), threadId);
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 = path26.join(root, entry.name);
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, claude-zai, claude-kimi, claude-glm, codex, opencode-go, cursor \uC911 \uD558\uB098\uB97C \uC124\uCE58\uD574\uC8FC\uC138\uC694."
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 isRecord(value) {
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 (!isRecord(value)) return void 0;
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 (!isRecord(value)) return {};
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 (!isRecord(value)) return {};
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 (!isRecord(value)) return void 0;
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 (!isRecord(value)) return {};
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(path26__default.extname(resolved).toLowerCase())) {
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 : path26__default.delimiter;
21858
- if (hasPathSeparator(bin, platform) || path26__default.isAbsolute(bin)) {
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(path26__default.join(searchDir, bin), pathExts, platform);
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" || path26__default.extname(candidate).length > 0) {
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" ? "\\" : path26__default.sep;
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" ? path26__default.win32.resolve(value) : path26__default.resolve(value);
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" ? path26__default.win32.join(...parts) : path26__default.join(...parts);
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 path26.join(runtimeState.storeDir, FILENAME);
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 = path26.join(runtimeState.storeDir, LOCK_DIRNAME);
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 path26.join(os3.homedir(), DEFAULT_STORE_DIRNAME);
23630
+ return path25.join(os4.homedir(), DEFAULT_STORE_DIRNAME);
23435
23631
  }
23436
23632
  function readCarriersFromDir(dir) {
23437
- const filePath = path26.join(dir, FILENAME);
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 = path26.join(runtimeState.storeDir, FILENAME);
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(path26.join(dir, STALE_SUBAGENT_MODE_FILENAME));
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
- var store = {
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 config2.subagent?.byHost?.claude ?? {
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(input.summary.workspaceChanges?.statLine ?? "unavailable")}`,
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, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
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 (!isNativeSubagentMode && getConfiguredTaskForceBackends(carrierId).length >= 2) {
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 (!path26__default.isAbsolute(trimmed)) {
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
- "claude-zai": {
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, agentMode).",
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: path26__default.join(paths.dir, SETTINGS_LOCK_DIR_NAME),
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 (!isRecord4(value)) return emptyConsoleSettingsData();
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 (!isRecord4(value)) return null;
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 (!isRecord4(value)) return null;
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 (!isRecord4(entry)) continue;
31111
+ if (!isRecord3(entry)) continue;
32349
31112
  result[key] = entry;
32350
31113
  }
32351
31114
  return result;
32352
31115
  }
32353
- function isRecord4(value) {
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 (!isRecord5(body)) {
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 isRecord5(value) {
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(path26__default.join(paths.schemaDir, WORKSPACE_SCHEMA_AGENTS_FILENAME), DEFAULT_WORKSPACE_SCHEMA_AGENTS);
32858
- await writeDefaultFileIfMissing(path26__default.join(paths.schemaDir, WORKSPACE_SCHEMA_FILENAME), DEFAULT_WORKSPACE_WIKI_SCHEMA);
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(path26__default.join(paths.root, WORKSPACE_KNOWLEDGE_AGENTS_FILENAME), DEFAULT_WORKSPACE_KNOWLEDGE_AGENTS);
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 = path26__default.join(paths.schemaDir, WORKSPACE_SCHEMA_AGENTS_FILENAME);
32868
- const wikiSchemaPath = path26__default.join(paths.schemaDir, WORKSPACE_SCHEMA_FILENAME);
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 = path26__default.join(paths.schemaDir, entry.name);
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 = path26__default.basename(target, ".md");
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 path26__default.join(paths.schemaDir, `${WORKSPACE_TEMPLATE_PREFIX}${id}${WORKSPACE_TEMPLATE_SUFFIX}`);
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 = path26__default.join(cwd, KNOWLEDGE_ROOT_DIRNAME);
31760
+ const root = path25__default.join(cwd, KNOWLEDGE_ROOT_DIRNAME);
32998
31761
  return {
32999
31762
  root,
33000
- rawDir: path26__default.join(root, RAW_DIRNAME),
33001
- wikiDir: path26__default.join(root, WIKI_DIRNAME),
33002
- schemaDir: path26__default.join(root, SCHEMA_DIRNAME),
33003
- queueDir: path26__default.join(root, QUEUE_DIRNAME),
33004
- archiveDir: path26__default.join(root, ARCHIVE_DIRNAME),
33005
- conflictsDir: path26__default.join(root, CONFLICTS_DIRNAME),
33006
- indexFile: path26__default.join(root, INDEX_FILENAME)
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 path26__default.join(paths.wikiDir, INDEX_MD_FILENAME);
31784
+ return path25__default.join(paths.wikiDir, INDEX_MD_FILENAME);
33022
31785
  }
33023
31786
  function getLogFile(paths) {
33024
- return path26__default.join(paths.root, LOG_MD_FILENAME);
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 = path26__default.resolve(paths.root, indexed.path);
33091
- const rel = path26__default.relative(paths.wikiDir, resolved);
33092
- if (!rel || rel.startsWith("..") || path26__default.isAbsolute(rel)) return null;
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 = path26__default.join(paths.wikiDir, `${id}.md`);
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 = path26__default.resolve(paths.root, target);
33107
- const relativeTarget = path26__default.relative(paths.wikiDir, absoluteTarget);
33108
- if (!relativeTarget || relativeTarget.startsWith("..") || path26__default.isAbsolute(relativeTarget)) {
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 (path26__default.basename(absoluteTarget, ".md") !== entry.id) {
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(path26__default.dirname(absoluteTarget), { recursive: true });
31880
+ await mkdir(path25__default.dirname(absoluteTarget), { recursive: true });
33118
31881
  await writeMarkdownAtomic(absoluteTarget, serializeWikiEntry(entry), paths);
33119
- return path26__default.join("wiki", relativeTarget).replaceAll(path26__default.sep, "/");
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: path26__default.relative(paths.root, filePath).replaceAll(path26__default.sep, "/")
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 = path26__default.join(dirPath, entry.name);
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 = path26__default.join(
33494
- path26__default.dirname(filePath),
33495
- `.tmp-${process.pid}-${Date.now()}-${crypto5.randomUUID()}-${os3__default.hostname()}`
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: path26__default.join("wiki", `${entry.id}.md`),
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 = path26__default.join(paths.queueDir, PATCH_SET_DIRNAME, patchSetId);
33699
- const relative = path26__default.relative(path26__default.join(paths.queueDir, PATCH_SET_DIRNAME), patchSetDir);
33700
- if (!relative || relative.startsWith("..") || path26__default.isAbsolute(relative)) {
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 path26__default.join(getPatchSetDir(paths, patchSetId), PATCH_SET_META_FILENAME);
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 = path26__default.join(paths.conflictsDir, conflictId);
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(path26__default.join(conflictDir, CONFLICT_META_FILENAME), meta3, paths);
33750
- await writePatchFile(path26__default.join(conflictDir, CONFLICT_PROPOSED_FILENAME), input.proposed, paths);
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(path26__default.join(conflictDir, CONFLICT_CURRENT_FILENAME), input.current, paths);
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(path26__default.join(conflictDir, CONFLICT_RAW_SOURCE_FILENAME), input.rawSource, paths);
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 = path26__default.resolve(paths.root, target);
33806
- if (!absoluteTarget.startsWith(`${paths.root}${path26__default.sep}`) && absoluteTarget !== 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}${path26__default.sep}`)) throw new Error("wiki patch must target wiki/");
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(path26__default.join(paths.queueDir, id, PATCH_META_FILENAME));
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 = path26__default.join(paths.queueDir, selection.id);
33859
- const patch = await parsePatch(await readPatchFile(path26__default.join(queueDir, PATCH_FILENAME)));
33860
- const meta3 = await readJsonFile2(path26__default.join(queueDir, PATCH_META_FILENAME));
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 = path26__default.join(paths.queueDir, id);
33884
- await writeJsonFile(path26__default.join(queueDir, PATCH_META_FILENAME), {
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 !== path26__default.basename(target, ".md")) {
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 = path26__default.basename(patch.frontmatter.target, ".md");
32738
+ const wikiId = path25__default.basename(patch.frontmatter.target, ".md");
33976
32739
  const currentEntry = await readWikiEntry(wikiId, paths);
33977
- const currentPath = path26__default.join(paths.root, patch.frontmatter.target);
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("/") || path26__default.posix.isAbsolute(target) || path26__default.win32.isAbsolute(target)) {
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 (path26__default.posix.normalize(target) !== target) {
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 = path26__default.posix.relative("wiki", target);
34046
- const targetPath = path26__default.join(wikiRoot, ...relativeTarget.split("/"));
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 = path26__default.join(current, part);
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 = path26__default.resolve(paths.root, rawSourceRef);
34078
- if (!absoluteRef.startsWith(`${paths.rawDir}${path26__default.sep}`)) {
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 = path26__default.join(paths.root, patch.frontmatter.target);
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 ?? path26__default.basename(patch.frontmatter.target, ".md"),
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 = path26__default.join(paths.queueDir, id);
34198
- const toDir = path26__default.join(paths.archiveDir, id);
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(path26__default.join(toDir, PATCH_META_FILENAME), meta3, paths);
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 = path26__default.resolve(cwd);
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 path26__default.basename(cwd) || cwd;
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 = path26__default.resolve(cwdInput);
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: path26__default.basename(cwd),
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 = os3__default.networkInterfaces()) {
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: path26__default.join(paths.dir, STATE_LOCK_DIR_NAME),
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 (!isRecord6(value)) return emptyDurableConsoleState();
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 (!isRecord6(value)) return null;
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) ?? (path26__default.basename(cwd) || cwd);
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 (isRecord6(value.providerSession)) payload.providerSession = value.providerSession;
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 (!isRecord6(value)) return null;
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 (!isRecord6(value)) return null;
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 (!isRecord6(value)) return null;
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 (!isRecord6(value)) return null;
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 isRecord6(value) {
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 isRecord6(value) ? value : {};
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 (!isRecord6(value)) return null;
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 (!isRecord7(value)) return value;
34255
+ if (!isRecord6(value)) return value;
35493
34256
  return sanitizeRecord(value, sensitiveFields);
35494
34257
  }
35495
- function isRecord7(value) {
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: isRecord8(body.payload) ? body.payload : {},
35564
- geometry: isRecord8(body.geometry) ? readGeometry(body.geometry) : null
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
- ...isRecord8(body.payload) ? { payload: body.payload } : {},
35622
- ...isRecord8(body.geometry) || body.geometry === null ? { geometry: body.geometry === null ? null : readGeometry(body.geometry) } : {}
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 && previousNode.title !== node.title) {
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 isRecord8(value) {
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 = path26__default.relative(root, target);
36012
- return relative === "" || !relative.startsWith("..") && !path26__default.isAbsolute(relative);
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 ? path26__default.resolve(options.cwd, "runtime/fleet-plugins") : null);
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: path26__default.join(options.homeDir ?? os3__default.homedir(), ".fleet", "plugins"), builtInDistRoot: null, external: true }
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 (!isRecord9(value)) return null;
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 = path26__default.join(root, entry.name);
36045
- const manifestPath = path26__default.join(pluginRoot, "plugin.json");
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 = path26__default.join(root, entry.name);
36064
- const manifestPath = path26__default.join(pluginRoot, "plugin.json");
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 = path26__default.join(pluginRoot, "routes.ts");
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 = path26__default.join(builtInDistRoot, manifest.id, "routes.mjs");
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 = path26__default.resolve(pluginRoot, entryPath);
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 (path26__default.isAbsolute(entryPath)) return false;
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 = path26__default.relative(root, candidate);
36131
- return relative === "" || !relative.startsWith("..") && !path26__default.isAbsolute(relative);
34902
+ const relative = path25__default.relative(root, candidate);
34903
+ return relative === "" || !relative.startsWith("..") && !path25__default.isAbsolute(relative);
36132
34904
  }
36133
- function isRecord9(value) {
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 = path26__default.dirname(fileURLToPath(import.meta.url));
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 = path26__default.join(resolvePluginBundleNodeModules(entry), ".cache");
35000
+ const cacheRoot = path25__default.join(resolvePluginBundleNodeModules(entry), ".cache");
36229
35001
  await mkdir(cacheRoot, { recursive: true });
36230
- const dir = await mkdtemp(path26__default.join(cacheRoot, "fleet-console-plugin-"));
36231
- const file2 = path26__default.join(dir, "routes.mjs");
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 = path26__default.dirname(entry);
35009
+ let dir = path25__default.dirname(entry);
36238
35010
  let fallback = packageNodeModules;
36239
35011
  while (true) {
36240
- const workspaceConsoleNodeModules = path26__default.join(dir, "runtime", "fleet-console", "node_modules");
35012
+ const workspaceConsoleNodeModules = path25__default.join(dir, "runtime", "fleet-console", "node_modules");
36241
35013
  if (hasFleetConsoleSdk(workspaceConsoleNodeModules)) return workspaceConsoleNodeModules;
36242
- const candidate = path26__default.join(dir, "node_modules");
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 = path26__default.dirname(dir);
36246
- if (parent === dir) return fallback ?? path26__default.join(path26__default.dirname(entry), "node_modules");
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
- path26__default.resolve(__dirname$1, "..", "node_modules"),
36253
- path26__default.resolve(__dirname$1, "..", "..", "..", "node_modules")
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(path26__default.join(nodeModules, "@fleet-console", "sdk"));
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 = path26__default.join(packageRoot, "dist", "client");
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 = path26__default.resolve(consoleRoot, relativePath2);
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[path26__default.extname(absolutePath)] ?? "application/octet-stream";
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(path26__default.join(consoleRoot, "index.html"));
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 (!path26__default.extname(withoutPrefix)) return "index.html";
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) || !path26__default.isAbsolute(value)) throw new TheaterFolderListError("invalid_path");
36633
- return path26__default.resolve(value);
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?.() ?? os3__default.homedir();
35417
+ const home = deps.homedir?.() ?? os4__default.homedir();
36638
35418
  const start = home || deps.cwd?.() || process.cwd();
36639
- return path26__default.resolve(start);
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 = path26__default.join(targetPath, dirent.name);
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 = path26__default.parse(targetPath);
36711
- const resolved = path26__default.resolve(targetPath);
36712
- if (resolved === path26__default.resolve(parsed.root)) return null;
36713
- const parent = path26__default.dirname(resolved);
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) || !path26__default.isAbsolute(cwd)) throw new Error("invalid_folder");
36754
- const normalized = path26__default.resolve(cwd);
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 = path26__default.resolve(cwd);
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 ?? os3__default.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 = path26__default.join(tmpDir, `${WORKER_FILE_PREFIX}${stamp}${WORKER_FILE_SUFFIX}`);
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 = path26__default.join(request.dataDir, `${WORKER_FILE_PREFIX}${stamp}${STATUS_FILE_SUFFIX}`);
36848
- const logFile = path26__default.join(request.dataDir, `${WORKER_FILE_PREFIX}${stamp}${LOG_FILE_SUFFIX}`);
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 path26__default.join(path26__default.dirname(sourcePath), "cli.mjs");
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) persistDurableState();
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) => path26__default.join(durablePaths.dir, "plugins", 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 = path26__default.resolve(packageRoot, "..", "..");
38138
- const sourceRoot = path26__default.join(packageRootRepo, "runtime", "fleet-plugins");
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: path26__default.join(packageRoot, "dist", "fleet-plugins")
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(path26__default.dirname(file2), { recursive: true });
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 path26__default.join(dataDir, "plugins", pluginId, `${key}.json`);
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", "subagents-context", "turn-start", "turn-end", "attention", "auto-name"]);
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] && path26__default.resolve(process4.argv[1]) === fileURLToPath(import.meta.url);
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)}