@dotobokuri/fleet-console 1.8.0 → 1.9.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 (65) hide show
  1. package/AGENTS.md +6 -4
  2. package/dist/cli-bin.mjs +1824 -599
  3. package/dist/cli.d.ts +4 -0
  4. package/dist/cli.mjs +1824 -599
  5. package/dist/client/assets/{_baseUniq-BvJBBAyx.js → _baseUniq-_nKBty4x.js} +1 -1
  6. package/dist/client/assets/{arc-_In9IKSA.js → arc-DEjqUlkY.js} +1 -1
  7. package/dist/client/assets/{architectureDiagram-Q4EWVU46-Ch4p9PP9.js → architectureDiagram-Q4EWVU46-CPF3RLab.js} +1 -1
  8. package/dist/client/assets/{blockDiagram-DXYQGD6D-dV3nM6N6.js → blockDiagram-DXYQGD6D-DguupB0e.js} +1 -1
  9. package/dist/client/assets/{c4Diagram-AHTNJAMY-Cd4rkDvb.js → c4Diagram-AHTNJAMY-Dd7AVc09.js} +1 -1
  10. package/dist/client/assets/channel-DA6xE92d.js +1 -0
  11. package/dist/client/assets/{chunk-4BX2VUAB-BdFP7-t8.js → chunk-4BX2VUAB-CSIihHG7.js} +1 -1
  12. package/dist/client/assets/{chunk-4TB4RGXK-CwZmzqqH.js → chunk-4TB4RGXK-DR_cPI3H.js} +1 -1
  13. package/dist/client/assets/{chunk-55IACEB6-jonfKM4s.js → chunk-55IACEB6-97czQ3iV.js} +1 -1
  14. package/dist/client/assets/{chunk-EDXVE4YY-Di2ByMxa.js → chunk-EDXVE4YY-piQCPtjQ.js} +1 -1
  15. package/dist/client/assets/{chunk-FMBD7UC4-DXLnCQWV.js → chunk-FMBD7UC4-BIeV9l0L.js} +1 -1
  16. package/dist/client/assets/{chunk-OYMX7WX6-DpgtrxyA.js → chunk-OYMX7WX6-DWUJBKm_.js} +1 -1
  17. package/dist/client/assets/{chunk-QZHKN3VN-BdkOO2d4.js → chunk-QZHKN3VN-DHL5fPU4.js} +1 -1
  18. package/dist/client/assets/{chunk-YZCP3GAM-Hfgm6DyM.js → chunk-YZCP3GAM-Dk19Wldz.js} +1 -1
  19. package/dist/client/assets/classDiagram-6PBFFD2Q-D46R_D_e.js +1 -0
  20. package/dist/client/assets/classDiagram-v2-HSJHXN6E-D46R_D_e.js +1 -0
  21. package/dist/client/assets/clone-DV233GSJ.js +1 -0
  22. package/dist/client/assets/{cose-bilkent-S5V4N54A-DqClnVsA.js → cose-bilkent-S5V4N54A-CcROwyfn.js} +1 -1
  23. package/dist/client/assets/{dagre-KV5264BT-DlVHx9hg.js → dagre-KV5264BT-kdHN8OcZ.js} +1 -1
  24. package/dist/client/assets/{diagram-5BDNPKRD-DJVcbz8w.js → diagram-5BDNPKRD-yqi72mWd.js} +1 -1
  25. package/dist/client/assets/{diagram-G4DWMVQ6-ZCER6PqU.js → diagram-G4DWMVQ6-CTjHbP--.js} +1 -1
  26. package/dist/client/assets/{diagram-MMDJMWI5-DFt5a-B8.js → diagram-MMDJMWI5-BCGN9v8i.js} +1 -1
  27. package/dist/client/assets/{diagram-TYMM5635-DXPsYs4b.js → diagram-TYMM5635-p6gtwFXr.js} +1 -1
  28. package/dist/client/assets/{erDiagram-SMLLAGMA-BEiMZzzV.js → erDiagram-SMLLAGMA-BHNCT04F.js} +1 -1
  29. package/dist/client/assets/{flowDiagram-DWJPFMVM-DTBFF-X2.js → flowDiagram-DWJPFMVM-DP-E6Gb1.js} +1 -1
  30. package/dist/client/assets/{ganttDiagram-T4ZO3ILL-nE9kklkz.js → ganttDiagram-T4ZO3ILL-COKcadl7.js} +1 -1
  31. package/dist/client/assets/{gitGraphDiagram-UUTBAWPF-VD6J4jc_.js → gitGraphDiagram-UUTBAWPF-CVkte06j.js} +1 -1
  32. package/dist/client/assets/{graph-CuZGH1eI.js → graph-BljmCiGu.js} +1 -1
  33. package/dist/client/assets/index-B7IECSX7.css +1 -0
  34. package/dist/client/assets/index-CSTdaEyG.js +777 -0
  35. package/dist/client/assets/{infoDiagram-42DDH7IO-BdxLeDgE.js → infoDiagram-42DDH7IO-Dh_U82lE.js} +1 -1
  36. package/dist/client/assets/{ishikawaDiagram-UXIWVN3A-OG_S8qjo.js → ishikawaDiagram-UXIWVN3A-BtZhb0mv.js} +1 -1
  37. package/dist/client/assets/{journeyDiagram-VCZTEJTY-CvZPwJCs.js → journeyDiagram-VCZTEJTY-_Zd4No67.js} +1 -1
  38. package/dist/client/assets/{kanban-definition-6JOO6SKY-4hgVjEGs.js → kanban-definition-6JOO6SKY-CpIIMkPJ.js} +1 -1
  39. package/dist/client/assets/{layout-BHDLAxp5.js → layout-ButG21vs.js} +1 -1
  40. package/dist/client/assets/{linear-WT8NWS1o.js → linear-C-frnGuN.js} +1 -1
  41. package/dist/client/assets/{mermaid.core-UWKHwZrH.js → mermaid.core-ISlBhdkY.js} +4 -4
  42. package/dist/client/assets/{min-CkGW0p-k.js → min-CalB2Q9y.js} +1 -1
  43. package/dist/client/assets/{mindmap-definition-QFDTVHPH-BxjJxQqR.js → mindmap-definition-QFDTVHPH-BfilPIUD.js} +1 -1
  44. package/dist/client/assets/{pieDiagram-DEJITSTG-BTjPSbyX.js → pieDiagram-DEJITSTG-Dm_1WIPT.js} +1 -1
  45. package/dist/client/assets/{quadrantDiagram-34T5L4WZ-D2fCxzGw.js → quadrantDiagram-34T5L4WZ-DMzRgLeF.js} +1 -1
  46. package/dist/client/assets/{requirementDiagram-MS252O5E-CtElLmk8.js → requirementDiagram-MS252O5E-Bl1lUR6U.js} +1 -1
  47. package/dist/client/assets/{sankeyDiagram-XADWPNL6-DGqMKAC2.js → sankeyDiagram-XADWPNL6-VxDrFumf.js} +1 -1
  48. package/dist/client/assets/{sequenceDiagram-FGHM5R23-B8Yva4cR.js → sequenceDiagram-FGHM5R23-BoB_k7L2.js} +1 -1
  49. package/dist/client/assets/{stateDiagram-FHFEXIEX-BxBGow-_.js → stateDiagram-FHFEXIEX-C8DFihD3.js} +1 -1
  50. package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-DlDadEC7.js +1 -0
  51. package/dist/client/assets/{timeline-definition-GMOUNBTQ-CUcV7Qpm.js → timeline-definition-GMOUNBTQ-G5hn4rEl.js} +1 -1
  52. package/dist/client/assets/{vennDiagram-DHZGUBPP-DS0hFmpX.js → vennDiagram-DHZGUBPP-D_jMNDmm.js} +1 -1
  53. package/dist/client/assets/{wardley-RL74JXVD-Dhd3kp0H.js → wardley-RL74JXVD-Clc5Li47.js} +1 -1
  54. package/dist/client/assets/{wardleyDiagram-NUSXRM2D-B6QDK0rE.js → wardleyDiagram-NUSXRM2D-Bygn2On7.js} +1 -1
  55. package/dist/client/assets/{xychartDiagram-5P7HB3ND-tiuCrAL_.js → xychartDiagram-5P7HB3ND-arK3uijt.js} +1 -1
  56. package/dist/client/index.html +2 -2
  57. package/package.json +1 -1
  58. package/postinstall.mjs +29 -0
  59. package/dist/client/assets/channel-F-hXrSqZ.js +0 -1
  60. package/dist/client/assets/classDiagram-6PBFFD2Q-DqXQgyK4.js +0 -1
  61. package/dist/client/assets/classDiagram-v2-HSJHXN6E-DqXQgyK4.js +0 -1
  62. package/dist/client/assets/clone-kL599Cyi.js +0 -1
  63. package/dist/client/assets/index-ClU0e8Rv.js +0 -734
  64. package/dist/client/assets/index-VeebE_4d.css +0 -1
  65. package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-COhEt-rs.js +0 -1
package/dist/cli-bin.mjs CHANGED
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
- import { execFile, spawn, spawnSync, execSync } from 'child_process';
2
+ import { execFile, spawn, spawnSync, execFileSync, execSync } from 'child_process';
3
3
  import * as fs7 from 'fs';
4
- import fs7__default, { readFileSync, existsSync, mkdtempSync, writeFileSync, mkdirSync, rmSync, chmodSync, renameSync, readdirSync, constants, openSync, closeSync, lstatSync, unlinkSync, realpathSync, statSync, symlinkSync, fstatSync } from 'fs';
5
- import * as path93 from 'path';
6
- import path93__default, { join, resolve, relative, dirname } from 'path';
7
- import process7 from 'process';
4
+ import fs7__default, { readFileSync, existsSync, mkdtempSync, writeFileSync, mkdirSync, realpathSync, rmSync, chmodSync, renameSync, readdirSync, constants, openSync, closeSync, accessSync, lstatSync, unlinkSync, statSync, fstatSync } from 'fs';
5
+ import * as path92 from 'path';
6
+ import path92__default, { join, resolve, relative, dirname } from 'path';
7
+ import process9 from 'process';
8
8
  import { fileURLToPath, pathToFileURL } from 'url';
9
- import crypto4, { createHash, randomUUID, timingSafeEqual } from 'crypto';
9
+ import crypto3, { createHash, randomUUID, timingSafeEqual } from 'crypto';
10
10
  import * as os22 from 'os';
11
11
  import os22__default from 'os';
12
12
  import { EventEmitter } from 'events';
@@ -27,7 +27,7 @@ var LOCK_FILE_MODE = 384;
27
27
  function createConsoleLock(deps = {}) {
28
28
  const fsImpl = deps.fs ?? fs7__default;
29
29
  const now = deps.now ?? Date.now;
30
- const randomToken = deps.randomToken ?? (() => crypto4.randomBytes(32).toString("base64url"));
30
+ const randomToken = deps.randomToken ?? (() => crypto3.randomBytes(32).toString("base64url"));
31
31
  const hostname5 = deps.hostname ?? (() => "127.0.0.1");
32
32
  function ensureLockDir(dir) {
33
33
  fsImpl.mkdirSync(dir, { recursive: true, mode: LOCK_DIR_MODE });
@@ -82,7 +82,7 @@ function createConsoleLock(deps = {}) {
82
82
  }
83
83
  function assertLockModes(lockFile) {
84
84
  if (typeof process.getuid !== "function") return;
85
- const dir = path93__default.dirname(lockFile);
85
+ const dir = path92__default.dirname(lockFile);
86
86
  const dirMode = fsImpl.statSync(dir).mode & 511;
87
87
  const fileMode = fsImpl.statSync(lockFile).mode & 511;
88
88
  if (dirMode !== LOCK_DIR_MODE) {
@@ -124,7 +124,7 @@ function createConsoleLock(deps = {}) {
124
124
  }
125
125
  var FLEET_DATA_DIR_NAME = ".fleet";
126
126
  function getFleetDataDir() {
127
- return path93.join(os22.homedir(), FLEET_DATA_DIR_NAME);
127
+ return path92.join(os22.homedir(), FLEET_DATA_DIR_NAME);
128
128
  }
129
129
  var SECURE_DIR_MODE = 448;
130
130
  var SECURE_FILE_MODE = 384;
@@ -210,7 +210,7 @@ function cleanupTempFiles(dir, prefix, minAgeMs, now) {
210
210
  if (!entry.startsWith(prefix)) {
211
211
  continue;
212
212
  }
213
- const tempPath = path93.join(dir, entry);
213
+ const tempPath = path92.join(dir, entry);
214
214
  try {
215
215
  const stat5 = fs7.lstatSync(tempPath);
216
216
  if (stat5?.isFile() && !stat5.isSymbolicLink() && now - stat5.mtimeMs >= minAgeMs) {
@@ -316,7 +316,7 @@ function writeLockOwner(lockDir, ownerFileName, startedAt) {
316
316
  hostname: os22.hostname(),
317
317
  startedAt
318
318
  };
319
- const ownerPath = path93.join(lockDir, ownerFileName);
319
+ const ownerPath = path92.join(lockDir, ownerFileName);
320
320
  try {
321
321
  fs7.writeFileSync(ownerPath, JSON.stringify(owner), { encoding: "utf-8", mode: 384 });
322
322
  } catch (error51) {
@@ -325,7 +325,7 @@ function writeLockOwner(lockDir, ownerFileName, startedAt) {
325
325
  }
326
326
  }
327
327
  function readLockOwner(lockDir, ownerFileName) {
328
- const ownerPath = path93.join(lockDir, ownerFileName);
328
+ const ownerPath = path92.join(lockDir, ownerFileName);
329
329
  try {
330
330
  return sanitizeLockOwner(JSON.parse(fs7.readFileSync(ownerPath, "utf-8")));
331
331
  } catch (error51) {
@@ -1144,10 +1144,10 @@ function mergeDefs(...defs) {
1144
1144
  function cloneDef(schema) {
1145
1145
  return mergeDefs(schema._zod.def);
1146
1146
  }
1147
- function getElementAtPath(obj, path35) {
1148
- if (!path35)
1147
+ function getElementAtPath(obj, path36) {
1148
+ if (!path36)
1149
1149
  return obj;
1150
- return path35.reduce((acc, key) => acc?.[key], obj);
1150
+ return path36.reduce((acc, key) => acc?.[key], obj);
1151
1151
  }
1152
1152
  function promiseAllObject(promisesObj) {
1153
1153
  const keys = Object.keys(promisesObj);
@@ -1556,11 +1556,11 @@ function explicitlyAborted(x, startIndex = 0) {
1556
1556
  }
1557
1557
  return false;
1558
1558
  }
1559
- function prefixIssues(path35, issues) {
1559
+ function prefixIssues(path36, issues) {
1560
1560
  return issues.map((iss) => {
1561
1561
  var _a3;
1562
1562
  (_a3 = iss).path ?? (_a3.path = []);
1563
- iss.path.unshift(path35);
1563
+ iss.path.unshift(path36);
1564
1564
  return iss;
1565
1565
  });
1566
1566
  }
@@ -1707,16 +1707,16 @@ function flattenError(error51, mapper = (issue3) => issue3.message) {
1707
1707
  }
1708
1708
  function formatError(error51, mapper = (issue3) => issue3.message) {
1709
1709
  const fieldErrors = { _errors: [] };
1710
- const processError = (error52, path35 = []) => {
1710
+ const processError = (error52, path36 = []) => {
1711
1711
  for (const issue3 of error52.issues) {
1712
1712
  if (issue3.code === "invalid_union" && issue3.errors.length) {
1713
- issue3.errors.map((issues) => processError({ issues }, [...path35, ...issue3.path]));
1713
+ issue3.errors.map((issues) => processError({ issues }, [...path36, ...issue3.path]));
1714
1714
  } else if (issue3.code === "invalid_key") {
1715
- processError({ issues: issue3.issues }, [...path35, ...issue3.path]);
1715
+ processError({ issues: issue3.issues }, [...path36, ...issue3.path]);
1716
1716
  } else if (issue3.code === "invalid_element") {
1717
- processError({ issues: issue3.issues }, [...path35, ...issue3.path]);
1717
+ processError({ issues: issue3.issues }, [...path36, ...issue3.path]);
1718
1718
  } else {
1719
- const fullpath = [...path35, ...issue3.path];
1719
+ const fullpath = [...path36, ...issue3.path];
1720
1720
  if (fullpath.length === 0) {
1721
1721
  fieldErrors._errors.push(mapper(issue3));
1722
1722
  } else {
@@ -1743,17 +1743,17 @@ function formatError(error51, mapper = (issue3) => issue3.message) {
1743
1743
  }
1744
1744
  function treeifyError(error51, mapper = (issue3) => issue3.message) {
1745
1745
  const result = { errors: [] };
1746
- const processError = (error52, path35 = []) => {
1746
+ const processError = (error52, path36 = []) => {
1747
1747
  var _a3, _b;
1748
1748
  for (const issue3 of error52.issues) {
1749
1749
  if (issue3.code === "invalid_union" && issue3.errors.length) {
1750
- issue3.errors.map((issues) => processError({ issues }, [...path35, ...issue3.path]));
1750
+ issue3.errors.map((issues) => processError({ issues }, [...path36, ...issue3.path]));
1751
1751
  } else if (issue3.code === "invalid_key") {
1752
- processError({ issues: issue3.issues }, [...path35, ...issue3.path]);
1752
+ processError({ issues: issue3.issues }, [...path36, ...issue3.path]);
1753
1753
  } else if (issue3.code === "invalid_element") {
1754
- processError({ issues: issue3.issues }, [...path35, ...issue3.path]);
1754
+ processError({ issues: issue3.issues }, [...path36, ...issue3.path]);
1755
1755
  } else {
1756
- const fullpath = [...path35, ...issue3.path];
1756
+ const fullpath = [...path36, ...issue3.path];
1757
1757
  if (fullpath.length === 0) {
1758
1758
  result.errors.push(mapper(issue3));
1759
1759
  continue;
@@ -1785,8 +1785,8 @@ function treeifyError(error51, mapper = (issue3) => issue3.message) {
1785
1785
  }
1786
1786
  function toDotPath(_path) {
1787
1787
  const segs = [];
1788
- const path35 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
1789
- for (const seg of path35) {
1788
+ const path36 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
1789
+ for (const seg of path36) {
1790
1790
  if (typeof seg === "number")
1791
1791
  segs.push(`[${seg}]`);
1792
1792
  else if (typeof seg === "symbol")
@@ -14450,13 +14450,13 @@ function resolveRef(ref, ctx) {
14450
14450
  if (!ref.startsWith("#")) {
14451
14451
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
14452
14452
  }
14453
- const path35 = ref.slice(1).split("/").filter(Boolean);
14454
- if (path35.length === 0) {
14453
+ const path36 = ref.slice(1).split("/").filter(Boolean);
14454
+ if (path36.length === 0) {
14455
14455
  return ctx.rootSchema;
14456
14456
  }
14457
14457
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
14458
- if (path35[0] === defsKey) {
14459
- const key = path35[1];
14458
+ if (path36[0] === defsKey) {
14459
+ const key = path36[1];
14460
14460
  if (!key || !ctx.defs[key]) {
14461
14461
  throw new Error(`Reference not found: ${ref}`);
14462
14462
  }
@@ -17641,7 +17641,7 @@ var AcpConnection = class extends BaseConnection {
17641
17641
  }
17642
17642
  /** Claude 계열 브릿지인지 여부를 단일 판별 지점으로 유지합니다. */
17643
17643
  isClaudeBackend() {
17644
- return this.cliType === "claude" || this.cliType === "claude-zai" || this.cliType === "claude-kimi";
17644
+ return this.cliType === "claude" || this.cliType === "claude-zai" || this.cliType === "claude-kimi" || this.cliType === "claude-glm";
17645
17645
  }
17646
17646
  /** Claude bridge만 native system prompt append를 지원하므로 이 경로만 사용합니다. */
17647
17647
  getClaudeSystemPrompt(systemPrompt) {
@@ -18140,6 +18140,20 @@ var models_default = {
18140
18140
  opus: "kimi-k2.7-code"
18141
18141
  }
18142
18142
  },
18143
+ "claude-glm": {
18144
+ name: "Claude Code with ZhipuAI GLM",
18145
+ defaultModel: "opus",
18146
+ models: [
18147
+ { modelId: "haiku", name: "GLM-4.5-Air (Haiku slot)", effort: { supported: false } },
18148
+ { modelId: "sonnet", name: "GLM-4.7 (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-4.7",
18154
+ opus: "glm-5.1"
18155
+ }
18156
+ },
18143
18157
  codex: {
18144
18158
  name: "OpenAI Codex CLI",
18145
18159
  defaultModel: "gpt-5.4",
@@ -18386,6 +18400,32 @@ var CLI_BACKENDS = {
18386
18400
  API_TIMEOUT_MS: "3000000"
18387
18401
  }
18388
18402
  },
18403
+ "claude-glm": {
18404
+ id: "claude-glm",
18405
+ cliCommand: "claude",
18406
+ protocol: "acp",
18407
+ authRequired: true,
18408
+ npxPackage: "@agentclientprotocol/claude-agent-acp@0.33.1",
18409
+ modes: [
18410
+ { id: "default", label: "Default" },
18411
+ { id: "plan", label: "Plan" },
18412
+ { id: "bypassPermissions", label: "YOLO" }
18413
+ ],
18414
+ supportsSessionClose: true,
18415
+ supportsSessionLoad: true,
18416
+ requiresModelAtSpawn: false,
18417
+ usesNpxBridge: true,
18418
+ defaultMaxTokens: 16384,
18419
+ defaultEnv: {
18420
+ ANTHROPIC_BASE_URL: "https://open.bigmodel.cn/api/anthropic",
18421
+ // ZhipuAI Claude Code 권장 슬롯 매핑 — 직접 launch(Native PTY) 경로에서도
18422
+ // haiku/sonnet/opus 별칭이 GLM 모델로 해석되도록 env로 고정한다.
18423
+ ANTHROPIC_DEFAULT_HAIKU_MODEL: "glm-4.5-air",
18424
+ ANTHROPIC_DEFAULT_SONNET_MODEL: "glm-4.7",
18425
+ ANTHROPIC_DEFAULT_OPUS_MODEL: "glm-5.1",
18426
+ API_TIMEOUT_MS: "3000000"
18427
+ }
18428
+ },
18389
18429
  codex: {
18390
18430
  id: "codex",
18391
18431
  cliCommand: "codex",
@@ -18482,6 +18522,7 @@ function getYoloModeId(cli) {
18482
18522
  case "claude":
18483
18523
  case "claude-zai":
18484
18524
  case "claude-kimi":
18525
+ case "claude-glm":
18485
18526
  return "bypassPermissions";
18486
18527
  case "opencode-go":
18487
18528
  return "build";
@@ -19717,12 +19758,12 @@ var CodexAppServerConnection = class extends BaseConnection {
19717
19758
  });
19718
19759
  }
19719
19760
  findRolloutPathForThreadId(threadId) {
19720
- const codexHome = this.codexHome ?? this.env.CODEX_HOME ?? path93.join(this.env.HOME ?? "", ".codex");
19761
+ const codexHome = this.codexHome ?? this.env.CODEX_HOME ?? path92.join(this.env.HOME ?? "", ".codex");
19721
19762
  if (!codexHome) {
19722
19763
  return null;
19723
19764
  }
19724
19765
  for (const rootName of ["sessions", "archived_sessions"]) {
19725
- const found = findRolloutPath(path93.join(codexHome, rootName), threadId);
19766
+ const found = findRolloutPath(path92.join(codexHome, rootName), threadId);
19726
19767
  if (found) {
19727
19768
  return found;
19728
19769
  }
@@ -19826,7 +19867,7 @@ function findRolloutPath(root, threadId) {
19826
19867
  return null;
19827
19868
  }
19828
19869
  for (const entry of fs7.readdirSync(root, { withFileTypes: true })) {
19829
- const entryPath = path93.join(root, entry.name);
19870
+ const entryPath = path92.join(root, entry.name);
19830
19871
  if (entry.isDirectory()) {
19831
19872
  const found = findRolloutPath(entryPath, threadId);
19832
19873
  if (found) {
@@ -21220,6 +21261,7 @@ var UnifiedAgent = {
21220
21261
  case "claude":
21221
21262
  case "claude-zai":
21222
21263
  case "claude-kimi":
21264
+ case "claude-glm":
21223
21265
  return new UnifiedClaudeAgentClient(cli);
21224
21266
  case "codex":
21225
21267
  return new UnifiedCodexAgentClient();
@@ -21238,7 +21280,7 @@ var UnifiedAgent = {
21238
21280
  }
21239
21281
  const preferred = await new CliDetector().getPreferred();
21240
21282
  if (!preferred) {
21241
- throw new Error("\uC0AC\uC6A9 \uAC00\uB2A5\uD55C CLI\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4. claude, claude-zai, claude-kimi, codex, opencode-go, cursor \uC911 \uD558\uB098\uB97C \uC124\uCE58\uD574\uC8FC\uC138\uC694.");
21283
+ throw new Error("\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.");
21242
21284
  }
21243
21285
  return this.createClient(preferred.cli);
21244
21286
  },
@@ -21251,6 +21293,8 @@ var UnifiedAgent = {
21251
21293
  return client;
21252
21294
  }
21253
21295
  };
21296
+
21297
+ // ../../packages/fleet-infra/dist/chunk-35EEE5KI.js
21254
21298
  function readAuthStoreFile(filePath) {
21255
21299
  let fd;
21256
21300
  try {
@@ -21270,7 +21314,7 @@ function readAuthStoreFile(filePath) {
21270
21314
  }
21271
21315
  }
21272
21316
  }
21273
- var DEFAULT_AUTH_PATH = path93.join(getFleetDataDir(), "auth.json");
21317
+ var DEFAULT_AUTH_PATH = path92.join(getFleetDataDir(), "auth.json");
21274
21318
  var AUTH_LOCK_OWNER_FILE_NAME = "owner.json";
21275
21319
  var AUTH_LOCK_TIMEOUT_MS = 5e3;
21276
21320
  function createAuthService(deps = {}) {
@@ -21326,7 +21370,7 @@ function createAuthService(deps = {}) {
21326
21370
  }
21327
21371
  },
21328
21372
  async setApiKey(providerId, key) {
21329
- const dir = path93.dirname(authPath);
21373
+ const dir = path92.dirname(authPath);
21330
21374
  ensureSafeDirectory(dir);
21331
21375
  withAuthLock(authPath, lockDir, () => {
21332
21376
  const data = fs7.existsSync(authPath) ? readAuthStoreFile(authPath) : {};
@@ -21379,72 +21423,6 @@ function formatAuthValidationFailureMessage(input) {
21379
21423
  }
21380
21424
  return `Auth token validation failed (providerId: '${input.providerId}'). Check the token and try again.${detail}`;
21381
21425
  }
21382
- var LEGACY_AUTH_PATH = path93.join(getFleetDataDir(), "agent", "auth.json");
21383
- var CURRENT_AUTH_PATH = path93.join(getFleetDataDir(), "auth.json");
21384
- function mergeAuthStoresNoOverwrite(legacy, current) {
21385
- const data = { ...current };
21386
- const migratedProviderIds = [];
21387
- const skippedProviderIds = [];
21388
- for (const [providerId, entry] of Object.entries(legacy)) {
21389
- if (Object.prototype.hasOwnProperty.call(data, providerId)) {
21390
- skippedProviderIds.push(providerId);
21391
- continue;
21392
- }
21393
- data[providerId] = entry;
21394
- migratedProviderIds.push(providerId);
21395
- }
21396
- return {
21397
- data,
21398
- migratedProviderIds,
21399
- skippedProviderIds
21400
- };
21401
- }
21402
- async function migrateLegacyAuthStore(options = {}) {
21403
- const legacyPath = options.legacyPath ?? LEGACY_AUTH_PATH;
21404
- const currentPath = options.currentPath ?? CURRENT_AUTH_PATH;
21405
- if (!fs7.existsSync(legacyPath)) {
21406
- return createMigrationResult({
21407
- legacyPath,
21408
- currentPath,
21409
- status: "legacy-missing",
21410
- migratedProviderIds: [],
21411
- skippedProviderIds: [],
21412
- shouldPrintNotice: false
21413
- });
21414
- }
21415
- const legacy = readAuthStoreFile(legacyPath);
21416
- const current = fs7.existsSync(currentPath) ? readAuthStoreFile(currentPath) : {};
21417
- const merged = mergeAuthStoresNoOverwrite(legacy, current);
21418
- if (merged.migratedProviderIds.length > 0) {
21419
- const dir = path93.dirname(currentPath);
21420
- ensureSafeDirectory(dir);
21421
- writeAtomicSync(currentPath, `${JSON.stringify(merged.data, null, 2)}
21422
- `, {
21423
- mode: SECURE_FILE_MODE,
21424
- fsync: true
21425
- });
21426
- }
21427
- return createMigrationResult({
21428
- legacyPath,
21429
- currentPath,
21430
- status: merged.migratedProviderIds.length > 0 ? "migrated" : "unchanged",
21431
- migratedProviderIds: merged.migratedProviderIds,
21432
- skippedProviderIds: merged.skippedProviderIds,
21433
- shouldPrintNotice: options.notify !== false && merged.migratedProviderIds.length > 0
21434
- });
21435
- }
21436
- function createMigrationResult(input) {
21437
- return {
21438
- legacyPath: input.legacyPath,
21439
- currentPath: input.currentPath,
21440
- migratedCount: input.migratedProviderIds.length,
21441
- skippedCount: input.skippedProviderIds.length,
21442
- migratedProviderIds: input.migratedProviderIds,
21443
- skippedProviderIds: input.skippedProviderIds,
21444
- shouldPrintNotice: input.shouldPrintNotice,
21445
- status: input.status
21446
- };
21447
- }
21448
21426
  var DEFAULT_AUTH_VALIDATION_TIMEOUT_MS = 5e3;
21449
21427
  async function validateAnthropicCompatibleApiKey(request) {
21450
21428
  const controller = new AbortController();
@@ -21517,8 +21495,14 @@ function buildMessagesUrl(baseUrl) {
21517
21495
  function isAbortError(error51) {
21518
21496
  return error51 instanceof DOMException && error51.name === "AbortError";
21519
21497
  }
21498
+ var CLI_TO_AUTH_PROVIDER_ID = {
21499
+ "claude-zai": "Claude Code with Z.AI GLM",
21500
+ "claude-kimi": "Claude Code with Moonshot Kimi",
21501
+ "claude-glm": "Claude Code with ZhipuAI GLM"
21502
+ };
21520
21503
  var CLAUDE_ZAI_PROVIDER_ID = "Claude Code with Z.AI GLM";
21521
21504
  var CLAUDE_KIMI_PROVIDER_ID = "Claude Code with Moonshot Kimi";
21505
+ var CLAUDE_GLM_PROVIDER_ID = "Claude Code with ZhipuAI GLM";
21522
21506
  var AUTH_PROVIDER_DEFINITIONS = {
21523
21507
  "claude-zai": {
21524
21508
  providerId: CLAUDE_ZAI_PROVIDER_ID,
@@ -21529,12 +21513,16 @@ var AUTH_PROVIDER_DEFINITIONS = {
21529
21513
  providerId: CLAUDE_KIMI_PROVIDER_ID,
21530
21514
  baseUrl: CLI_BACKENDS["claude-kimi"].defaultEnv.ANTHROPIC_BASE_URL,
21531
21515
  env: CLI_BACKENDS["claude-kimi"].defaultEnv
21516
+ },
21517
+ "claude-glm": {
21518
+ providerId: CLAUDE_GLM_PROVIDER_ID,
21519
+ baseUrl: CLI_BACKENDS["claude-glm"].defaultEnv.ANTHROPIC_BASE_URL,
21520
+ env: CLI_BACKENDS["claude-glm"].defaultEnv
21532
21521
  }
21533
21522
  };
21534
21523
  async function resolveAuthEnv(cli, deps) {
21535
21524
  const provider = AUTH_PROVIDER_DEFINITIONS[cli];
21536
21525
  if (!provider) return {};
21537
- await migrateLegacyAuthStore();
21538
21526
  const auth = deps?.authService ?? createAuthService({ authPath: DEFAULT_AUTH_PATH });
21539
21527
  const token = await auth.getApiKey(provider.providerId);
21540
21528
  if (!token) {
@@ -21555,13 +21543,32 @@ async function resolveAuthEnv(cli, deps) {
21555
21543
  }
21556
21544
  return { ...provider.env, ANTHROPIC_AUTH_TOKEN: token };
21557
21545
  }
21546
+ async function validateAuthKeyForCli(cli, apiKey) {
21547
+ const provider = AUTH_PROVIDER_DEFINITIONS[cli];
21548
+ if (!provider) {
21549
+ return { providerId: cli, status: "success" };
21550
+ }
21551
+ const validation = await validateAnthropicCompatibleApiKey({
21552
+ providerId: provider.providerId,
21553
+ apiKey,
21554
+ baseUrl: provider.baseUrl
21555
+ });
21556
+ if (isAuthValidationSuccess(validation)) {
21557
+ return { providerId: validation.providerId, status: "success" };
21558
+ }
21559
+ return {
21560
+ providerId: validation.providerId,
21561
+ status: validation.status,
21562
+ detail: validation.detail
21563
+ };
21564
+ }
21558
21565
  var DEFAULT_TEMP_FILE_MIN_AGE_MS = 6e4;
21559
21566
  function createDurableJsonStore(deps) {
21560
21567
  const now = deps.now ?? (() => Date.now());
21561
21568
  const sensitivity = deps.sensitivity;
21562
21569
  const mode = sensitivity === "sensitive" ? SECURE_FILE_MODE : 420;
21563
21570
  const minAgeMs = deps.tempCleanupMinAgeMs ?? DEFAULT_TEMP_FILE_MIN_AGE_MS;
21564
- const dir = path93.dirname(deps.filePath);
21571
+ const dir = path92.dirname(deps.filePath);
21565
21572
  return {
21566
21573
  path: deps.filePath,
21567
21574
  load() {
@@ -21645,8 +21652,8 @@ var LOCK_OWNER_FILE_NAME = "owner";
21645
21652
  var TEMP_FILE_PREFIX = `.tmp-${GLOBAL_OPTIONS_FILE_NAME}-`;
21646
21653
  function createGlobalOptionsStore(deps = {}) {
21647
21654
  const dataDir = deps.dataDir ?? getFleetDataDir();
21648
- const optionsPath = path93.join(dataDir, GLOBAL_OPTIONS_FILE_NAME);
21649
- const lockDir = path93.join(dataDir, LOCK_DIR_NAME);
21655
+ const optionsPath = path92.join(dataDir, GLOBAL_OPTIONS_FILE_NAME);
21656
+ const lockDir = path92.join(dataDir, LOCK_DIR_NAME);
21650
21657
  const store2 = createDurableJsonStore({
21651
21658
  filePath: optionsPath,
21652
21659
  lockDir,
@@ -21717,7 +21724,7 @@ function readFleetConsoleRelease() {
21717
21724
  const requireFromHere = createRequire(import.meta.url);
21718
21725
  const packageJsonPath = requireFromHere.resolve("../package.json");
21719
21726
  const pkg = requireFromHere(packageJsonPath);
21720
- const packageRoot = path93__default.dirname(packageJsonPath);
21727
+ const packageRoot = path92__default.dirname(packageJsonPath);
21721
21728
  const version2 = pkg.version ?? "";
21722
21729
  if (pkg.private === true) {
21723
21730
  return { channel: "local", version: version2, packageRoot };
@@ -21735,14 +21742,14 @@ var CONSOLE_CAPTURES_DIR_NAME = "captures";
21735
21742
  function createConsolePaths(deps = {}) {
21736
21743
  const env = deps.env ?? process.env;
21737
21744
  const base = env.FLEET_CONSOLE_DIR ?? defaultConsoleBaseDir(deps);
21738
- return { dir: base, lockFile: path93__default.join(base, LOCK_FILE_NAME) };
21745
+ return { dir: base, lockFile: path92__default.join(base, LOCK_FILE_NAME) };
21739
21746
  }
21740
21747
  function createConsoleDataPaths(deps = {}) {
21741
- const dir = path93__default.join(deps.fleetDataDir ?? getFleetDataDir(), CONSOLE_DATA_DIR_NAME);
21748
+ const dir = defaultConsoleDataBaseDir(deps);
21742
21749
  return {
21743
21750
  dir,
21744
- stateFile: path93__default.join(dir, CONSOLE_STATE_FILE_NAME),
21745
- capturesDir: path93__default.join(dir, CONSOLE_CAPTURES_DIR_NAME)
21751
+ stateFile: path92__default.join(dir, CONSOLE_STATE_FILE_NAME),
21752
+ capturesDir: path92__default.join(dir, CONSOLE_CAPTURES_DIR_NAME)
21746
21753
  };
21747
21754
  }
21748
21755
  function defaultConsoleBaseDir(deps) {
@@ -21750,26 +21757,93 @@ function defaultConsoleBaseDir(deps) {
21750
21757
  const channel = deps.channel ?? (release = readFleetConsoleRelease()).channel;
21751
21758
  if (channel === "local") {
21752
21759
  const packageRoot = deps.packageRoot ?? (release ??= readFleetConsoleRelease()).packageRoot;
21753
- return path93__default.join(path93__default.resolve(packageRoot, "..", ".."), ".fleet", CONSOLE_RUNTIME_DIR_NAME);
21760
+ return localConsoleDir(packageRoot);
21754
21761
  }
21755
21762
  const uid = deps.uid ?? (typeof process.getuid === "function" ? process.getuid() : 0);
21756
- return path93__default.join(os22__default.tmpdir(), `${LOCK_DIR_NAME2}-${uid}-${channel}`);
21763
+ return path92__default.join(os22__default.tmpdir(), `${LOCK_DIR_NAME2}-${uid}-${channel}`);
21764
+ }
21765
+ function defaultConsoleDataBaseDir(deps) {
21766
+ if (deps.fleetDataDir !== void 0) {
21767
+ return path92__default.join(deps.fleetDataDir, CONSOLE_DATA_DIR_NAME);
21768
+ }
21769
+ const env = deps.env ?? process.env;
21770
+ if (env.FLEET_CONSOLE_DIR) {
21771
+ return env.FLEET_CONSOLE_DIR;
21772
+ }
21773
+ let release;
21774
+ const channel = deps.channel ?? (release = readFleetConsoleRelease()).channel;
21775
+ if (channel === "local") {
21776
+ const packageRoot = deps.packageRoot ?? (release ??= readFleetConsoleRelease()).packageRoot;
21777
+ return localConsoleDir(packageRoot);
21778
+ }
21779
+ return path92__default.join(getFleetDataDir(), CONSOLE_DATA_DIR_NAME);
21780
+ }
21781
+ function localConsoleDir(packageRoot) {
21782
+ return path92__default.join(path92__default.resolve(packageRoot, "..", ".."), ".fleet", CONSOLE_RUNTIME_DIR_NAME);
21757
21783
  }
21758
21784
 
21759
21785
  // src/attention-hook.ts
21760
21786
  var ATTENTION_POST_TIMEOUT_MS = 1500;
21761
- async function runAttentionHook(env = process7.env, options = {}) {
21787
+ var ATTENTION_STDIN_TIMEOUT_MS = 500;
21788
+ var ATTENTION_REASONS = /* @__PURE__ */ new Set([
21789
+ "idle_prompt",
21790
+ "permission_prompt",
21791
+ "auth_success",
21792
+ "elicitation_dialog",
21793
+ "elicitation_complete",
21794
+ "elicitation_response"
21795
+ ]);
21796
+ async function runAttentionHook(env = process9.env, options = {}) {
21762
21797
  try {
21763
21798
  await postAttention(env, options);
21764
21799
  } catch {
21765
21800
  }
21766
21801
  }
21802
+ function normalizeAttentionReason(value) {
21803
+ return typeof value === "string" && ATTENTION_REASONS.has(value) ? value : void 0;
21804
+ }
21805
+ async function readHookReason(options) {
21806
+ const stream = options.stdin ?? process9.stdin;
21807
+ const raw = await readHookStdin(stream, options.stdinTimeoutMs ?? ATTENTION_STDIN_TIMEOUT_MS);
21808
+ if (!raw) return void 0;
21809
+ try {
21810
+ const parsed = JSON.parse(raw);
21811
+ return normalizeAttentionReason(parsed?.notification_type);
21812
+ } catch {
21813
+ return void 0;
21814
+ }
21815
+ }
21816
+ async function readHookStdin(stream, timeoutMs) {
21817
+ return await new Promise((resolve) => {
21818
+ const chunks = [];
21819
+ let settled = false;
21820
+ const finish = (value) => {
21821
+ if (settled) return;
21822
+ settled = true;
21823
+ resolve(value);
21824
+ };
21825
+ const timer = setTimeout(() => finish(""), timeoutMs);
21826
+ if (typeof timer.unref === "function") timer.unref();
21827
+ stream.on("data", (chunk) => {
21828
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
21829
+ });
21830
+ stream.on("end", () => {
21831
+ clearTimeout(timer);
21832
+ finish(Buffer.concat(chunks).toString("utf8"));
21833
+ });
21834
+ stream.on("error", () => {
21835
+ clearTimeout(timer);
21836
+ finish("");
21837
+ });
21838
+ });
21839
+ }
21767
21840
  async function postAttention(env, options) {
21768
21841
  const sessionId = env.FLEET_CONSOLE_SESSION_ID;
21769
21842
  if (!sessionId) return;
21770
21843
  const paths = createConsolePaths({ env });
21771
21844
  const lock = createConsoleLock().readLock(paths.lockFile);
21772
21845
  if (!lock) return;
21846
+ const reason = await readHookReason(options);
21773
21847
  const fetchImpl = options.fetchImpl ?? fetch;
21774
21848
  const controller = new AbortController();
21775
21849
  const timer = setTimeout(() => controller.abort(), options.timeoutMs ?? ATTENTION_POST_TIMEOUT_MS);
@@ -21780,7 +21854,7 @@ async function postAttention(env, options) {
21780
21854
  authorization: `Bearer ${lock.token}`,
21781
21855
  "content-type": "application/json"
21782
21856
  },
21783
- body: JSON.stringify({}),
21857
+ body: JSON.stringify(reason ? { reason } : {}),
21784
21858
  signal: controller.signal
21785
21859
  });
21786
21860
  } finally {
@@ -21790,17 +21864,20 @@ async function postAttention(env, options) {
21790
21864
  function openBrowser(url2, deps = {}) {
21791
21865
  const platform = deps.platform ?? os22__default.platform();
21792
21866
  const spawnBrowser = deps.spawnBrowser ?? ((command2, args, options) => {
21793
- spawn(command2, [...args], options).unref();
21867
+ const child = spawn(command2, [...args], options);
21868
+ child.once("error", () => {
21869
+ });
21870
+ child.unref();
21794
21871
  });
21795
21872
  if (platform === "darwin") {
21796
- spawnBrowser("open", [url2], { detached: true, stdio: "ignore" });
21873
+ spawnBrowser("open", [url2], { detached: true, stdio: "ignore", windowsHide: true });
21797
21874
  return;
21798
21875
  }
21799
21876
  if (platform === "win32") {
21800
- spawnBrowser("cmd", ["/c", "start", "", url2], { detached: true, stdio: "ignore" });
21877
+ spawnBrowser("cmd", ["/c", "start", "", url2], { detached: true, stdio: "ignore", windowsHide: true });
21801
21878
  return;
21802
21879
  }
21803
- spawnBrowser("xdg-open", [url2], { detached: true, stdio: "ignore" });
21880
+ spawnBrowser("xdg-open", [url2], { detached: true, stdio: "ignore", windowsHide: true });
21804
21881
  }
21805
21882
 
21806
21883
  // src/health.ts
@@ -21980,7 +22057,7 @@ function specToMcpTool(spec) {
21980
22057
  }
21981
22058
  function installExecutorToolCallRouter(runtime, sessionToken, ctx) {
21982
22059
  runtime.server.setOnToolCallArrived(sessionToken, (toolName, args) => {
21983
- const toolCallId = crypto4.randomUUID();
22060
+ const toolCallId = crypto3.randomUUID();
21984
22061
  void runtime.registry.invoke(toolName, args, { cwd: ctx.cwd, sessionLabel: ctx.sessionLabel, toolCallId, signal: ctx.signal }).then((result) => runtime.server.resolveNextToolCall(sessionToken, toolCallId, result)).catch((err) => {
21985
22062
  runtime.server.resolveNextToolCall(sessionToken, toolCallId, {
21986
22063
  content: [{ type: "text", text: err instanceof Error ? err.message : String(err) }],
@@ -22371,7 +22448,7 @@ function createInProcessMcpServer(deps = {}) {
22371
22448
  if (activeStopPromise) await activeStopPromise;
22372
22449
  if (activeServer && activeServerUrl) return activeServerUrl;
22373
22450
  if (activeStartPromise) return activeStartPromise;
22374
- activeOpaquePath = `/${crypto4.randomUUID()}`;
22451
+ activeOpaquePath = `/${crypto3.randomUUID()}`;
22375
22452
  activeStartPromise = new Promise((resolve, reject) => {
22376
22453
  const srv = http.createServer(handleRequest);
22377
22454
  srv.timeout = MCP_SERVER_TIMEOUT_MS;
@@ -22628,7 +22705,7 @@ function createExecutorMcpSession(deps, toolTimeoutSeconds, request) {
22628
22705
  throw new Error("Executor session cwd is required");
22629
22706
  }
22630
22707
  assertNonEmptyExecutorTools(request.serverName, request.specs);
22631
- const token = crypto4.randomUUID();
22708
+ const token = crypto3.randomUUID();
22632
22709
  registerExecutorSessionTools(runtime.runtime, token, [...request.specs]);
22633
22710
  installExecutorToolCallRouter(runtime.runtime, token, {
22634
22711
  cwd,
@@ -22674,7 +22751,7 @@ function issueSessionToken(deps, sessionTokensByLabel, request) {
22674
22751
  for (const { name, runtime } of deps.runtimes) {
22675
22752
  const tools = runtime.registry.getAllAgentTools();
22676
22753
  assertNonEmptyExecutorTools(name, tools);
22677
- const token = crypto4.randomUUID();
22754
+ const token = crypto3.randomUUID();
22678
22755
  registerExecutorSessionTools(runtime, token, tools);
22679
22756
  installExecutorToolCallRouter(runtime, token, { cwd, sessionLabel: label, signal: request.signal });
22680
22757
  tokens.push({ name, token });
@@ -22850,7 +22927,7 @@ function createChildEnv(env, overlay) {
22850
22927
  return child;
22851
22928
  }
22852
22929
  function wrapWindowsShim(resolved, env, platform) {
22853
- if (platform !== "win32" || !WINDOWS_SHIM_EXTENSIONS.has(path93__default.extname(resolved).toLowerCase())) {
22930
+ if (platform !== "win32" || !WINDOWS_SHIM_EXTENSIONS.has(path92__default.extname(resolved).toLowerCase())) {
22854
22931
  return { bin: resolved, prefixArgs: [] };
22855
22932
  }
22856
22933
  rejectCmdExpansionSensitiveShim(resolved);
@@ -22868,13 +22945,13 @@ function forceWindowsArgQuoting(value) {
22868
22945
  return `${value} `;
22869
22946
  }
22870
22947
  function findOnPath(bin, pathValue, pathExts, platform) {
22871
- const pathSeparator = platform === "win32" ? WINDOWS_PATH_SEPARATOR : path93__default.delimiter;
22872
- if (hasPathSeparator(bin, platform) || path93__default.isAbsolute(bin)) {
22948
+ const pathSeparator = platform === "win32" ? WINDOWS_PATH_SEPARATOR : path92__default.delimiter;
22949
+ if (hasPathSeparator(bin, platform) || path92__default.isAbsolute(bin)) {
22873
22950
  return resolveWithExtensions(bin, pathExts, platform);
22874
22951
  }
22875
22952
  for (const entry of pathValue.split(pathSeparator)) {
22876
22953
  const searchDir = entry.length === 0 ? "." : entry;
22877
- const candidate = resolveWithExtensions(path93__default.join(searchDir, bin), pathExts, platform);
22954
+ const candidate = resolveWithExtensions(path92__default.join(searchDir, bin), pathExts, platform);
22878
22955
  if (candidate) {
22879
22956
  return candidate;
22880
22957
  }
@@ -22882,7 +22959,7 @@ function findOnPath(bin, pathValue, pathExts, platform) {
22882
22959
  return void 0;
22883
22960
  }
22884
22961
  function resolveWithExtensions(candidate, pathExts, platform) {
22885
- if (platform !== "win32" || path93__default.extname(candidate).length > 0) {
22962
+ if (platform !== "win32" || path92__default.extname(candidate).length > 0) {
22886
22963
  return existsSync(candidate) ? candidate : void 0;
22887
22964
  }
22888
22965
  for (const ext of pathExts) {
@@ -23782,6 +23859,230 @@ function parseNumericPart(value) {
23782
23859
  function compareNumbers(left, right) {
23783
23860
  return left === right ? 0 : left > right ? 1 : -1;
23784
23861
  }
23862
+ var DEFAULT_CHANNEL = "latest";
23863
+ var PACKAGE_MANAGER_COMMANDS = ["npm", "pnpm"];
23864
+ function createGlobalPackageUpdater(deps) {
23865
+ const resolvedDeps = resolveDeps(deps);
23866
+ return {
23867
+ detectPackageManager: () => detectPackageManager(resolvedDeps),
23868
+ update: (options = {}) => updatePackages(resolvedDeps, options),
23869
+ install: (manager, versionOrChannel) => installPackages(resolvedDeps, manager, versionOrChannel),
23870
+ createManualInstallMessage: (channel, reason) => createManualInstallMessage(resolvedDeps, channel, reason),
23871
+ formatInstallCommand: (command2, versionOrChannel) => formatInstallCommand(resolvedDeps.packageNames, command2, versionOrChannel)
23872
+ };
23873
+ }
23874
+ function resolveDeps(deps) {
23875
+ if (deps.packageNames.length === 0) {
23876
+ throw new Error("packageNames must contain at least one package");
23877
+ }
23878
+ return {
23879
+ packageNames: deps.packageNames,
23880
+ resolveCurrentPackageRoot: deps.resolveCurrentPackageRoot,
23881
+ resolveCurrentVersion: deps.resolveCurrentVersion,
23882
+ resolveLatestVersion: deps.resolveLatestVersion ?? fetchLatestVersion,
23883
+ isVersionGreater: deps.isVersionGreater ?? isVersionGreater,
23884
+ prepareInstall: deps.prepareInstall,
23885
+ finalizeSuccess: deps.finalizeSuccess,
23886
+ report: deps.report,
23887
+ env: deps.env ?? process.env,
23888
+ platform: deps.platform ?? process.platform,
23889
+ resolveBinary: deps.resolveBinary ?? resolvePathBinary,
23890
+ execFile: deps.execFile ?? defaultExecFile,
23891
+ spawnInstall: deps.spawnInstall ?? defaultSpawnInstall,
23892
+ realpath: deps.realpath ?? realpathSync,
23893
+ canWrite: deps.canWrite ?? defaultCanWrite
23894
+ };
23895
+ }
23896
+ async function updatePackages(deps, options) {
23897
+ const channel = options.channel ?? DEFAULT_CHANNEL;
23898
+ const detection = await detectPackageManager(deps);
23899
+ if (detection.manager === void 0) {
23900
+ return {
23901
+ status: "manual",
23902
+ code: 0,
23903
+ reason: detection.reason,
23904
+ manualMessage: createManualInstallMessage(deps, channel, detection.reason)
23905
+ };
23906
+ }
23907
+ const currentVersion = await deps.resolveCurrentVersion();
23908
+ const latestVersion = await deps.resolveLatestVersion(deps.packageNames[0], channel);
23909
+ if (currentVersion !== void 0 && latestVersion !== void 0 && !deps.isVersionGreater(latestVersion, currentVersion)) {
23910
+ deps.report?.(`Global package is already on the latest version (v${currentVersion}).`);
23911
+ return {
23912
+ status: "current",
23913
+ code: 0,
23914
+ manager: detection.manager,
23915
+ currentVersion,
23916
+ latestVersion
23917
+ };
23918
+ }
23919
+ const versionOrChannel = latestVersion ?? channel;
23920
+ if (latestVersion === void 0) {
23921
+ deps.report?.(`Could not resolve the latest package version; reinstalling ${channel}.`);
23922
+ } else {
23923
+ deps.report?.(`Installing global packages at ${versionOrChannel}.`);
23924
+ }
23925
+ const context = createInstallContext(deps, detection.manager, versionOrChannel);
23926
+ await deps.prepareInstall?.(context);
23927
+ const code = await installPackages(deps, detection.manager, versionOrChannel);
23928
+ if (code === 0) {
23929
+ await deps.finalizeSuccess?.(context);
23930
+ return {
23931
+ status: "installed",
23932
+ code,
23933
+ manager: detection.manager,
23934
+ currentVersion,
23935
+ latestVersion,
23936
+ versionOrChannel
23937
+ };
23938
+ }
23939
+ return {
23940
+ status: "failed",
23941
+ code,
23942
+ manager: detection.manager,
23943
+ currentVersion,
23944
+ latestVersion,
23945
+ versionOrChannel,
23946
+ manualMessage: createManualInstallMessage(deps, channel, void 0)
23947
+ };
23948
+ }
23949
+ async function detectPackageManager(deps) {
23950
+ const packageRoot = await deps.resolveCurrentPackageRoot();
23951
+ if (packageRoot === void 0) {
23952
+ return { manager: void 0, reason: "local" };
23953
+ }
23954
+ for (const command2 of PACKAGE_MANAGER_COMMANDS) {
23955
+ const detected = detectGlobalRoot(deps, command2, packageRoot);
23956
+ if (detected?.manager !== void 0 || detected?.reason === "permission") {
23957
+ return detected;
23958
+ }
23959
+ }
23960
+ return { manager: void 0, reason: "local" };
23961
+ }
23962
+ function detectGlobalRoot(deps, command2, packageRoot) {
23963
+ try {
23964
+ const resolved = deps.resolveBinary(command2, deps.env, { platform: deps.platform });
23965
+ if (resolved === void 0) {
23966
+ return void 0;
23967
+ }
23968
+ const globalRoot = deps.execFile(resolved.bin, [...resolved.prefixArgs, "root", "-g"]).trim();
23969
+ const resolvedRoot = normalizePath(deps, deps.realpath(resolvePathForPlatform(deps.platform, globalRoot)));
23970
+ const normalizedPackageRoot = normalizeExistingPath(deps, packageRoot);
23971
+ if (isPathInside(deps, normalizedPackageRoot, resolvedRoot)) {
23972
+ return createManagerDetection(deps, command2, resolvedRoot, resolved);
23973
+ }
23974
+ const expectedPackageDir = joinPathForPlatform(deps.platform, globalRoot, deps.packageNames[0]);
23975
+ try {
23976
+ const resolvedPackageDir = normalizePath(deps, deps.realpath(expectedPackageDir));
23977
+ if (resolvedPackageDir === normalizedPackageRoot) {
23978
+ return createManagerDetection(deps, command2, resolvedRoot, resolved);
23979
+ }
23980
+ } catch {
23981
+ }
23982
+ } catch (error51) {
23983
+ deps.report?.(`Failed to detect global ${command2} install: ${formatError2(error51)}`);
23984
+ return void 0;
23985
+ }
23986
+ return void 0;
23987
+ }
23988
+ function createManagerDetection(deps, command2, globalRoot, resolved) {
23989
+ if (!deps.canWrite(globalRoot)) {
23990
+ return { manager: void 0, reason: "permission" };
23991
+ }
23992
+ return {
23993
+ manager: {
23994
+ command: command2,
23995
+ globalRoot,
23996
+ resolved
23997
+ },
23998
+ reason: void 0
23999
+ };
24000
+ }
24001
+ function installPackages(deps, manager, versionOrChannel) {
24002
+ const context = createInstallContext(deps, manager, versionOrChannel);
24003
+ const commandArgs = [...manager.resolved.prefixArgs, "i", "-g", "--force", ...deps.packageNames.map((name) => `${name}@${versionOrChannel}`)];
24004
+ const child = deps.spawnInstall(manager.resolved.bin, commandArgs, { ...context, commandArgs });
24005
+ return new Promise((resolve) => {
24006
+ child.once("error", () => {
24007
+ resolve(1);
24008
+ });
24009
+ child.once("exit", (code, signal) => {
24010
+ if (typeof code === "number") {
24011
+ resolve(code);
24012
+ return;
24013
+ }
24014
+ resolve(signal === null ? 0 : 1);
24015
+ });
24016
+ });
24017
+ }
24018
+ function createInstallContext(deps, manager, versionOrChannel) {
24019
+ return {
24020
+ manager,
24021
+ versionOrChannel,
24022
+ packageNames: deps.packageNames
24023
+ };
24024
+ }
24025
+ function createManualInstallMessage(deps, channel, reason) {
24026
+ const reasonLine = reason === "permission" ? "Global package install location is not writable, so no installer was run." : "Global npm or pnpm installation could not be detected, so no installer was run.";
24027
+ const commands = PACKAGE_MANAGER_COMMANDS.map((command2) => formatInstallCommand(deps.packageNames, command2, channel));
24028
+ return [reasonLine, "Run one of these commands manually:", ...commands].join("\n");
24029
+ }
24030
+ function formatInstallCommand(packageNames, command2, versionOrChannel) {
24031
+ return `${command2} i -g ${packageNames.map((name) => `${name}@${versionOrChannel}`).join(" ")}`;
24032
+ }
24033
+ function isPathInside(deps, child, parent) {
24034
+ const separator = deps.platform === "win32" ? "\\" : path92__default.sep;
24035
+ return child === parent || child.startsWith(`${parent}${separator}`);
24036
+ }
24037
+ function normalizeExistingPath(deps, value) {
24038
+ try {
24039
+ return normalizePath(deps, deps.realpath(value));
24040
+ } catch {
24041
+ return normalizePath(deps, value);
24042
+ }
24043
+ }
24044
+ function normalizePath(deps, value) {
24045
+ const resolved = resolvePathForPlatform(deps.platform, value);
24046
+ return deps.platform === "win32" ? resolved.toLowerCase() : resolved;
24047
+ }
24048
+ function resolvePathForPlatform(platform, value) {
24049
+ return platform === "win32" ? path92__default.win32.resolve(value) : path92__default.resolve(value);
24050
+ }
24051
+ function joinPathForPlatform(platform, ...parts) {
24052
+ return platform === "win32" ? path92__default.win32.join(...parts) : path92__default.join(...parts);
24053
+ }
24054
+ function defaultExecFile(file2, args) {
24055
+ return execFileSync(file2, args, { encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] });
24056
+ }
24057
+ function defaultSpawnInstall(file2, args) {
24058
+ return spawn(file2, args, { stdio: "inherit" });
24059
+ }
24060
+ function defaultCanWrite(targetPath) {
24061
+ try {
24062
+ accessSync(targetPath, constants.W_OK);
24063
+ return true;
24064
+ } catch {
24065
+ return false;
24066
+ }
24067
+ }
24068
+ function formatError2(error51) {
24069
+ if (typeof error51 === "object" && error51 !== null) {
24070
+ const stderr = "stderr" in error51 ? error51.stderr : void 0;
24071
+ if (Buffer.isBuffer(stderr)) {
24072
+ const text = stderr.toString("utf8").trim();
24073
+ if (text.length > 0) {
24074
+ return text;
24075
+ }
24076
+ }
24077
+ if (typeof stderr === "string" && stderr.trim().length > 0) {
24078
+ return stderr.trim();
24079
+ }
24080
+ }
24081
+ if (error51 instanceof Error) {
24082
+ return error51.message;
24083
+ }
24084
+ return String(error51);
24085
+ }
23785
24086
 
23786
24087
  // ../../node_modules/.pnpm/typebox@1.1.34/node_modules/typebox/build/system/memory/memory.mjs
23787
24088
  var memory_exports = {};
@@ -28247,7 +28548,7 @@ function readRawCarriersOrDefaultStore() {
28247
28548
  }
28248
28549
  function getCarriersFilePath() {
28249
28550
  if (!runtimeState.storeDir) return null;
28250
- return path93.join(runtimeState.storeDir, FILENAME);
28551
+ return path92.join(runtimeState.storeDir, FILENAME);
28251
28552
  }
28252
28553
  function updateCarriers(mutator) {
28253
28554
  if (!runtimeState.storeDir) return;
@@ -28262,7 +28563,7 @@ function updateCarriers(mutator) {
28262
28563
  function withStoreLock(operation) {
28263
28564
  if (!runtimeState.storeDir) return operation();
28264
28565
  fs7.mkdirSync(runtimeState.storeDir, { recursive: true });
28265
- const lockDir = path93.join(runtimeState.storeDir, LOCK_DIRNAME);
28566
+ const lockDir = path92.join(runtimeState.storeDir, LOCK_DIRNAME);
28266
28567
  return withDirectoryLock(
28267
28568
  { lockDir, ownerFileName: LOCK_OWNER_FILENAME },
28268
28569
  operation
@@ -28273,10 +28574,10 @@ function readCarriers() {
28273
28574
  return readCarriersFromDir(runtimeState.storeDir);
28274
28575
  }
28275
28576
  function resolveDefaultStoreDir() {
28276
- return path93.join(os22.homedir(), DEFAULT_STORE_DIRNAME);
28577
+ return path92.join(os22.homedir(), DEFAULT_STORE_DIRNAME);
28277
28578
  }
28278
28579
  function readCarriersFromDir(dir) {
28279
- const filePath = path93.join(dir, FILENAME);
28580
+ const filePath = path92.join(dir, FILENAME);
28280
28581
  let fd;
28281
28582
  try {
28282
28583
  const stat5 = fs7.lstatSync(filePath);
@@ -28306,7 +28607,7 @@ function recordLastLocalWriteFingerprint(filePath, generation) {
28306
28607
  function writeCarriers(s) {
28307
28608
  if (!runtimeState.storeDir) throw new Error("Fleet store is not initialized.");
28308
28609
  fs7.mkdirSync(runtimeState.storeDir, { recursive: true });
28309
- const filePath = path93.join(runtimeState.storeDir, FILENAME);
28610
+ const filePath = path92.join(runtimeState.storeDir, FILENAME);
28310
28611
  const next = serializeFleetCarriers(s);
28311
28612
  writeAtomicSync(filePath, `${JSON.stringify(next, null, 2)}
28312
28613
  `, { fsync: false, mode: 420 });
@@ -28331,7 +28632,7 @@ function sanitizeFleetCarriers(value) {
28331
28632
  }
28332
28633
  function unlinkStaleSubagentModeFile(dir) {
28333
28634
  try {
28334
- fs7.unlinkSync(path93.join(dir, STALE_SUBAGENT_MODE_FILENAME));
28635
+ fs7.unlinkSync(path92.join(dir, STALE_SUBAGENT_MODE_FILENAME));
28335
28636
  } catch {
28336
28637
  }
28337
28638
  }
@@ -31906,8 +32207,8 @@ function createBoundCarrierJobs(registry3, boundStream = createBoundCarrierStrea
31906
32207
  // src/hooks/subagents-context.ts
31907
32208
  var FLEET_PLUGIN_NAME = "fleet";
31908
32209
  function runSubagentsContextHook(env) {
31909
- const fleetRoot = env.FLEET_ROOT ?? path93__default.join(env.HOME ?? os22__default.homedir(), ".fleet");
31910
- if (!canReadCarrierState(path93__default.join(fleetRoot, "carriers.json"))) {
32210
+ const fleetRoot = env.FLEET_ROOT ?? path92__default.join(env.HOME ?? os22__default.homedir(), ".fleet");
32211
+ if (!canReadCarrierState(path92__default.join(fleetRoot, "carriers.json"))) {
31911
32212
  return JSON.stringify({ hookSpecificOutput: { hookEventName: "SessionStart", additionalContext: "" } });
31912
32213
  }
31913
32214
  const carrierRuntime = createCarrierRuntime();
@@ -32385,6 +32686,11 @@ var claudeCli = createClaudeFamilyCliDefinition({
32385
32686
  id: "claude",
32386
32687
  label: "Claude"
32387
32688
  });
32689
+ var claudeGlmCli = createClaudeFamilyCliDefinition({
32690
+ authCli: "claude-glm",
32691
+ id: "claude-glm",
32692
+ label: "Claude GLM"
32693
+ });
32388
32694
  var claudeKimiCli = createClaudeFamilyCliDefinition({
32389
32695
  authCli: "claude-kimi",
32390
32696
  id: "claude-kimi",
@@ -32424,6 +32730,7 @@ var DEFAULT_CLI_ID = "claude";
32424
32730
  var DEFINITIONS = {
32425
32731
  claude: claudeCli,
32426
32732
  "claude-kimi": claudeKimiCli,
32733
+ "claude-glm": claudeGlmCli,
32427
32734
  codex: codexCli
32428
32735
  };
32429
32736
  async function resolveAgentCliProfile(env, cwd, options = {}) {
@@ -32470,6 +32777,10 @@ var AGENT_CLI_INJECTION_CAPABILITIES = {
32470
32777
  builderId: "claude-native",
32471
32778
  enabled: true
32472
32779
  },
32780
+ "claude-glm": {
32781
+ builderId: "claude-native",
32782
+ enabled: true
32783
+ },
32473
32784
  codex: {
32474
32785
  builderId: "codex-native",
32475
32786
  enabled: true
@@ -32488,7 +32799,7 @@ function createSessionCaptureHookExec(deps) {
32488
32799
  deps.provider
32489
32800
  ] : [deps.entryPath, "hook", "capture-session", deps.provider];
32490
32801
  return {
32491
- command: deps.execPath ?? process7.execPath,
32802
+ command: deps.execPath ?? process9.execPath,
32492
32803
  args
32493
32804
  };
32494
32805
  }
@@ -32661,16 +32972,10 @@ function writePrivateJson(filePath, value, rootBase) {
32661
32972
  function writePrivateFile(filePath, content, rootBase) {
32662
32973
  const resolvedBase = ensureRootBase(rootBase);
32663
32974
  ensurePathWithinRoot(resolvedBase, filePath);
32664
- ensureDirectorySegments(resolvedBase, path93__default.dirname(filePath));
32975
+ ensureDirectorySegments(resolvedBase, path92__default.dirname(filePath));
32665
32976
  writeFileNoFollow(filePath, content);
32666
32977
  chmodBestEffort(filePath, FILE_MODE);
32667
32978
  }
32668
- function linkPrivateSymlink(linkPath, target, rootBase) {
32669
- const resolvedBase = ensureRootBase(rootBase);
32670
- ensurePathWithinRoot(resolvedBase, linkPath);
32671
- ensureDirectorySegments(resolvedBase, path93__default.dirname(linkPath));
32672
- symlinkSync(target, linkPath);
32673
- }
32674
32979
  function removePrivatePath(targetPath, rootBase) {
32675
32980
  const resolvedBase = assertRootBaseSafe(rootBase);
32676
32981
  ensurePathWithinRoot(resolvedBase, targetPath);
@@ -32714,20 +33019,20 @@ function writeFileNoFollow(filePath, content) {
32714
33019
  }
32715
33020
  }
32716
33021
  function ensureRootBase(rootBase) {
32717
- const resolvedBase = path93__default.resolve(rootBase);
32718
- const anchor = findExistingDirectoryAnchor(path93__default.dirname(resolvedBase));
33022
+ const resolvedBase = path92__default.resolve(rootBase);
33023
+ const anchor = findExistingDirectoryAnchor(path92__default.dirname(resolvedBase));
32719
33024
  ensureDirectorySegments(anchor, resolvedBase);
32720
33025
  assertDirectorySafe(resolvedBase, "Plugin root base");
32721
33026
  return resolvedBase;
32722
33027
  }
32723
33028
  function assertRootBaseSafe(rootBase) {
32724
- const resolvedBase = path93__default.resolve(rootBase);
32725
- assertExistingSegmentsSafe(findExistingDirectoryAnchor(path93__default.dirname(resolvedBase)), resolvedBase);
33029
+ const resolvedBase = path92__default.resolve(rootBase);
33030
+ assertExistingSegmentsSafe(findExistingDirectoryAnchor(path92__default.dirname(resolvedBase)), resolvedBase);
32726
33031
  assertDirectorySafe(resolvedBase, "Plugin root base");
32727
33032
  return resolvedBase;
32728
33033
  }
32729
33034
  function findExistingDirectoryAnchor(targetPath) {
32730
- const resolvedTarget = path93__default.resolve(targetPath);
33035
+ const resolvedTarget = path92__default.resolve(targetPath);
32731
33036
  let current = resolvedTarget;
32732
33037
  while (true) {
32733
33038
  try {
@@ -32735,7 +33040,7 @@ function findExistingDirectoryAnchor(targetPath) {
32735
33040
  return current;
32736
33041
  } catch (error51) {
32737
33042
  if (error51 instanceof Error && "code" in error51 && error51.code === "ENOENT") {
32738
- const parent = path93__default.dirname(current);
33043
+ const parent = path92__default.dirname(current);
32739
33044
  if (parent === current) throw error51;
32740
33045
  current = parent;
32741
33046
  continue;
@@ -32754,17 +33059,17 @@ function assertDirectorySafe(dirPath, label) {
32754
33059
  }
32755
33060
  }
32756
33061
  function ensurePathWithinRoot(resolvedBase, candidatePath) {
32757
- const resolvedCandidate = path93__default.resolve(candidatePath);
32758
- const relative = path93__default.relative(resolvedBase, resolvedCandidate);
32759
- if (relative === "" || !relative.startsWith("..") && !path93__default.isAbsolute(relative)) return;
33062
+ const resolvedCandidate = path92__default.resolve(candidatePath);
33063
+ const relative = path92__default.relative(resolvedBase, resolvedCandidate);
33064
+ if (relative === "" || !relative.startsWith("..") && !path92__default.isAbsolute(relative)) return;
32760
33065
  throw new Error(`Plugin path escapes root base: ${candidatePath}`);
32761
33066
  }
32762
33067
  function ensureDirectorySegments(resolvedBase, dirPath) {
32763
- const target = path93__default.resolve(dirPath);
32764
- const relative = path93__default.relative(resolvedBase, target);
33068
+ const target = path92__default.resolve(dirPath);
33069
+ const relative = path92__default.relative(resolvedBase, target);
32765
33070
  let current = resolvedBase;
32766
- for (const segment of relative.split(path93__default.sep).filter(Boolean)) {
32767
- current = path93__default.join(current, segment);
33071
+ for (const segment of relative.split(path92__default.sep).filter(Boolean)) {
33072
+ current = path92__default.join(current, segment);
32768
33073
  try {
32769
33074
  const stat5 = lstatSync(current);
32770
33075
  if (stat5.isSymbolicLink()) {
@@ -32785,11 +33090,11 @@ function ensureDirectorySegments(resolvedBase, dirPath) {
32785
33090
  }
32786
33091
  }
32787
33092
  function assertExistingSegmentsSafe(resolvedBase, targetPath) {
32788
- const target = path93__default.resolve(targetPath);
32789
- const relative = path93__default.relative(resolvedBase, target);
33093
+ const target = path92__default.resolve(targetPath);
33094
+ const relative = path92__default.relative(resolvedBase, target);
32790
33095
  let current = resolvedBase;
32791
- for (const segment of relative.split(path93__default.sep).filter(Boolean)) {
32792
- current = path93__default.join(current, segment);
33096
+ for (const segment of relative.split(path92__default.sep).filter(Boolean)) {
33097
+ current = path92__default.join(current, segment);
32793
33098
  const stat5 = lstatSync(current);
32794
33099
  if (stat5.isSymbolicLink()) {
32795
33100
  throw new Error(`Plugin path segment is a symlink: ${current}`);
@@ -32801,13 +33106,13 @@ function assertExistingSegmentsSafe(resolvedBase, targetPath) {
32801
33106
  }
32802
33107
  }
32803
33108
  function assertExistingParentSegmentsSafe(resolvedBase, targetPath) {
32804
- assertExistingSegmentsSafe(resolvedBase, path93__default.dirname(targetPath));
33109
+ assertExistingSegmentsSafe(resolvedBase, path92__default.dirname(targetPath));
32805
33110
  }
32806
33111
  function assertSegmentRealpathWithinRoot(resolvedBase, segmentPath) {
32807
33112
  const baseRealpath = realpathSync(resolvedBase);
32808
33113
  const segmentRealpath = realpathSync(segmentPath);
32809
- const relative = path93__default.relative(baseRealpath, segmentRealpath);
32810
- if (relative === "" || !relative.startsWith("..") && !path93__default.isAbsolute(relative)) return;
33114
+ const relative = path92__default.relative(baseRealpath, segmentRealpath);
33115
+ if (relative === "" || !relative.startsWith("..") && !path92__default.isAbsolute(relative)) return;
32811
33116
  throw new Error(`Plugin path segment escapes root base: ${segmentPath}`);
32812
33117
  }
32813
33118
  var CLAUDE_AGENT_FILE_STEM_ALLOWLIST = /^[A-Za-z0-9][A-Za-z0-9_-]{0,79}$/;
@@ -32825,11 +33130,11 @@ function renderAssetPluginRoot(pluginRoot, bundle, options) {
32825
33130
  if (bundle.includeClaudeAgents) {
32826
33131
  for (const subagent of options.claudeDefinitions) {
32827
33132
  const fileStem = parseClaudeAgentFileStem(subagent.name);
32828
- writePrivateFile(path93__default.join(pluginRoot, "agents", `${fileStem}.md`), claudeAgentFile(subagent), pluginRoot);
33133
+ writePrivateFile(path92__default.join(pluginRoot, "agents", `${fileStem}.md`), claudeAgentFile(subagent), pluginRoot);
32829
33134
  }
32830
33135
  }
32831
- if (options.cliId === "claude" || options.cliId === "claude-kimi") {
32832
- writePrivateJson(path93__default.join(pluginRoot, "hooks", "hooks.json"), claudeHooks(options), pluginRoot);
33136
+ if (options.cliId === "claude" || options.cliId === "claude-kimi" || options.cliId === "claude-glm") {
33137
+ writePrivateJson(path92__default.join(pluginRoot, "hooks", "hooks.json"), claudeHooks(options), pluginRoot);
32833
33138
  }
32834
33139
  }
32835
33140
  function validateClaudeAgentFileStems(subagents) {
@@ -32838,7 +33143,7 @@ function validateClaudeAgentFileStems(subagents) {
32838
33143
  }
32839
33144
  }
32840
33145
  function parseClaudeAgentFileStem(name) {
32841
- if (CLAUDE_AGENT_FILE_STEM_ALLOWLIST.test(name) && path93__default.basename(name) === name) return name;
33146
+ if (CLAUDE_AGENT_FILE_STEM_ALLOWLIST.test(name) && path92__default.basename(name) === name) return name;
32842
33147
  throw new Error(`Invalid Claude agent file name: ${name}`);
32843
33148
  }
32844
33149
  function claudeHooks(options) {
@@ -32846,7 +33151,7 @@ function claudeHooks(options) {
32846
33151
  if (!hookExec) {
32847
33152
  throw new Error("Fleet Claude session hook command is required");
32848
33153
  }
32849
- const userPromptSubmitExecs = [options.captureSessionHookExec, options.turnStartHookExec].filter((exec) => exec !== void 0);
33154
+ const userPromptSubmitExecs = [options.captureSessionHookExec, options.turnStartHookExec, options.autoNameHookExec].filter((exec) => exec !== void 0);
32850
33155
  const stopExecs = [options.turnEndHookExec].filter((exec) => exec !== void 0);
32851
33156
  const inputWaitingExec = options.inputWaitingHookExec;
32852
33157
  return {
@@ -32908,74 +33213,8 @@ function yamlScalar(value) {
32908
33213
  }
32909
33214
  function renderEmbeddedSkillAssets(pluginRoot) {
32910
33215
  for (const asset of EMBEDDED_AGENT_CLI_SKILL_ASSETS) {
32911
- writePrivateFile(path93__default.join(pluginRoot, "skills", asset.relativePath), asset.content, pluginRoot);
32912
- }
32913
- }
32914
- function linkUserFleetSourcesIntoPlugin(sourceRoot, pluginRoot) {
32915
- const entries = listUserFleetSourceEntries(sourceRoot);
32916
- for (const entry of entries) {
32917
- linkPrivateSymlink(path93__default.join(pluginRoot, entry.pluginRelative), entry.sourcePath, pluginRoot);
32918
- }
32919
- }
32920
- function listUserFleetSourceEntries(sourceRoot) {
32921
- const entries = [];
32922
- for (const pluginRelative of ["skills", "agents", "hooks"]) {
32923
- const sourcePath = path93__default.join(sourceRoot, pluginRelative);
32924
- if (!existsSync(sourcePath)) continue;
32925
- const resolvedStat = statSync(sourcePath);
32926
- if (!resolvedStat.isDirectory()) {
32927
- throw new Error(`Fleet plugin source path is not a directory: ${sourcePath}`);
32928
- }
32929
- entries.push({ kind: "directory", pluginRelative, sourcePath });
32930
- }
32931
- const mcpPath = path93__default.join(sourceRoot, ".mcp.json");
32932
- if (existsSync(mcpPath)) {
32933
- const resolvedStat = statSync(mcpPath);
32934
- if (!resolvedStat.isFile()) {
32935
- throw new Error(`Fleet plugin source path is not a file: ${mcpPath}`);
32936
- }
32937
- entries.push({ kind: "file", pluginRelative: ".mcp.json", sourcePath: mcpPath });
32938
- }
32939
- return entries;
32940
- }
32941
- var GLOBAL_FLEET_SOURCE_ENTRIES = ["skills", "agents", "hooks", ".mcp.json"];
32942
- var globalBundle = {
32943
- description: "Fleet global user-level agents, skills, hooks, and MCP plugin",
32944
- directoryName: "fleet-global",
32945
- displayName: "Fleet Global",
32946
- hashFileName: ".fleet-global-codex-plugin.hash",
32947
- name: "fleet-global",
32948
- source: "global"
32949
- };
32950
- function renderGlobalPluginRoot(pluginRoot, fleetRoot) {
32951
- linkUserFleetSourcesIntoPlugin(fleetRoot, pluginRoot);
32952
- }
32953
- function globalFleetContentExists(fleetRoot) {
32954
- return GLOBAL_FLEET_SOURCE_ENTRIES.some((entry) => existsSync(path93__default.join(fleetRoot, entry)));
32955
- }
32956
- var projectBundle = {
32957
- description: "Fleet project-local agents, skills, hooks, and MCP plugin",
32958
- directoryName: "fleet-project",
32959
- displayName: "Fleet Project",
32960
- hashFileName: ".fleet-project-codex-plugin.hash",
32961
- name: "fleet-project",
32962
- source: "project"
32963
- };
32964
- function renderProjectPluginRoot(pluginRoot, options) {
32965
- const fleetProjectRoot = resolveProjectFleetRoot(options.cwd);
32966
- linkUserFleetSourcesIntoPlugin(fleetProjectRoot, pluginRoot);
32967
- }
32968
- function resolveProjectFleetRoot(cwd) {
32969
- const fleetProjectRoot = path93__default.join(cwd, ".fleet");
32970
- const sourceStat = lstatSync(fleetProjectRoot);
32971
- if (sourceStat.isSymbolicLink()) {
32972
- throw new Error(`Fleet project plugin source root is a symlink: ${fleetProjectRoot}`);
32973
- }
32974
- const verifiedStat = statSync(fleetProjectRoot);
32975
- if (!verifiedStat.isDirectory()) {
32976
- throw new Error(`Fleet project plugin source root is not a directory: ${fleetProjectRoot}`);
33216
+ writePrivateFile(path92__default.join(pluginRoot, "skills", asset.relativePath), asset.content, pluginRoot);
32977
33217
  }
32978
- return fleetProjectRoot;
32979
33218
  }
32980
33219
  var CONFIG_FILE_NAME = "config.toml";
32981
33220
  var CONFIG_FILE_MODE = 384;
@@ -32989,7 +33228,7 @@ function neutralizeCodexFleetPluginConfig(options) {
32989
33228
  mutateCodexConfigWithRetry(options, 0);
32990
33229
  }
32991
33230
  function mutateCodexConfigWithRetry(options, attempt) {
32992
- const configPath = path93__default.join(options.codexHome, CONFIG_FILE_NAME);
33231
+ const configPath = path92__default.join(options.codexHome, CONFIG_FILE_NAME);
32993
33232
  const targetPath = resolveRealConfigPath(configPath);
32994
33233
  const snapshot = readConfigSnapshot(targetPath);
32995
33234
  const nextContent = patchCodexConfig(snapshot.content, options);
@@ -33010,7 +33249,7 @@ function resolveRealConfigPath(configPath) {
33010
33249
  } catch (error51) {
33011
33250
  if (!isNodeError(error51, "ENOENT")) throw error51;
33012
33251
  try {
33013
- return path93__default.join(realpathSync(path93__default.dirname(configPath)), path93__default.basename(configPath));
33252
+ return path92__default.join(realpathSync(path92__default.dirname(configPath)), path92__default.basename(configPath));
33014
33253
  } catch (dirError) {
33015
33254
  if (isNodeError(dirError, "ENOENT")) return configPath;
33016
33255
  throw dirError;
@@ -33047,9 +33286,9 @@ function readConfigSnapshot(configPath) {
33047
33286
  }
33048
33287
  }
33049
33288
  function writeConfigIfUnchanged(configPath, snapshot, content) {
33050
- mkdirSync(path93__default.dirname(configPath), { recursive: true, mode: 448 });
33289
+ mkdirSync(path92__default.dirname(configPath), { recursive: true, mode: 448 });
33051
33290
  assertConfigUnchanged(configPath, snapshot);
33052
- const tempPath = path93__default.join(path93__default.dirname(configPath), `.${path93__default.basename(configPath)}.${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}.tmp`);
33291
+ const tempPath = path92__default.join(path92__default.dirname(configPath), `.${path92__default.basename(configPath)}.${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}.tmp`);
33053
33292
  let fd;
33054
33293
  try {
33055
33294
  fd = openSync(tempPath, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW, CONFIG_FILE_MODE);
@@ -33198,6 +33437,10 @@ function unlinkBestEffort(targetPath) {
33198
33437
  } catch {
33199
33438
  }
33200
33439
  }
33440
+ var DEPRECATED_HOME_PLUGIN_NAME = "fleet-global";
33441
+ var DEPRECATED_PROJECT_PLUGIN_NAME = "fleet-project";
33442
+ var DEPRECATED_PROJECT_MARKETPLACE_NAME_PREFIX = "fleet-project-";
33443
+ var FLAT_MARKETPLACE_FS_RESIDUE_ENTRIES = [".agents", ".claude-plugin", "plugin"];
33201
33444
  async function ensureCodexPluginRegistered(registration, command2, runCommand, withMarketplaceLock) {
33202
33445
  try {
33203
33446
  await withMarketplaceLock(registration.marketplaceDir, () => {
@@ -33208,6 +33451,47 @@ async function ensureCodexPluginRegistered(registration, command2, runCommand, w
33208
33451
  return error51 instanceof Error ? error51.message : String(error51);
33209
33452
  }
33210
33453
  }
33454
+ async function cleanupDeprecatedCodexPluginState(command2, runCommand, withMarketplaceLock, targets) {
33455
+ try {
33456
+ const marketplaceList = runCommand({ ...command2, args: [...command2.args, "plugin", "marketplace", "list"] });
33457
+ assertCommandSucceeded("codex plugin marketplace list", marketplaceList);
33458
+ const pluginList = runCommand({ ...command2, args: [...command2.args, "plugin", "list"] });
33459
+ assertCommandSucceeded("codex plugin list", pluginList);
33460
+ if (isCodexPluginInstalled(pluginList, DEPRECATED_HOME_PLUGIN_NAME, targets.homeMarketplaceName)) {
33461
+ await withMarketplaceLock(targets.homeMarketplaceRoot, () => {
33462
+ const removed = runCommand({
33463
+ ...command2,
33464
+ args: [...command2.args, "plugin", "remove", DEPRECATED_HOME_PLUGIN_NAME, "-m", targets.homeMarketplaceName]
33465
+ });
33466
+ assertCommandSucceeded("codex plugin remove fleet-global", removed);
33467
+ });
33468
+ }
33469
+ const projectTargetRoot = normalizeMarketplaceRoot(targets.projectMarketplaceRoot, command2.cwd);
33470
+ const projectMarketplaces = parseMarketplaceEntries(marketplaceList).filter(
33471
+ (entry) => entry.name.startsWith(DEPRECATED_PROJECT_MARKETPLACE_NAME_PREFIX) && normalizeMarketplaceRoot(entry.root, command2.cwd) === projectTargetRoot
33472
+ );
33473
+ for (const marketplace of projectMarketplaces) {
33474
+ await withMarketplaceLock(targets.projectMarketplaceRoot, () => {
33475
+ if (isCodexPluginInstalled(pluginList, DEPRECATED_PROJECT_PLUGIN_NAME, marketplace.name)) {
33476
+ const removedPlugin = runCommand({
33477
+ ...command2,
33478
+ args: [...command2.args, "plugin", "remove", DEPRECATED_PROJECT_PLUGIN_NAME, "-m", marketplace.name]
33479
+ });
33480
+ assertCommandSucceeded("codex plugin remove fleet-project", removedPlugin);
33481
+ }
33482
+ const removedMarketplace = runCommand({
33483
+ ...command2,
33484
+ args: [...command2.args, "plugin", "marketplace", "remove", marketplace.name]
33485
+ });
33486
+ assertCommandSucceeded("codex plugin marketplace remove fleet-project", removedMarketplace);
33487
+ removeFlatMarketplaceResidue(targets.projectMarketplaceRoot);
33488
+ });
33489
+ }
33490
+ return void 0;
33491
+ } catch (error51) {
33492
+ return error51 instanceof Error ? error51.message : String(error51);
33493
+ }
33494
+ }
33211
33495
  function ensureCodexPluginRegisteredOrThrow(registration, command2, runCommand) {
33212
33496
  const marketplaceList = runCommand({ ...command2, args: [...command2.args, "plugin", "marketplace", "list"] });
33213
33497
  assertCommandSucceeded("codex plugin marketplace list", marketplaceList);
@@ -33250,7 +33534,7 @@ function ensureCodexPluginRegisteredOrThrow(registration, command2, runCommand)
33250
33534
  pluginKey
33251
33535
  });
33252
33536
  writePrivateFile(registration.hashPath, `${registration.contentHash}
33253
- `, path93__default.dirname(registration.hashPath));
33537
+ `, path92__default.dirname(registration.hashPath));
33254
33538
  }
33255
33539
  function assertCommandSucceeded(label, result) {
33256
33540
  if (result.status === 0) return;
@@ -33258,20 +33542,23 @@ function assertCommandSucceeded(label, result) {
33258
33542
  throw new Error(`${label} failed${detail.length > 0 ? `: ${detail}` : ""}`);
33259
33543
  }
33260
33544
  function resolveCodexHome(env) {
33261
- return env.CODEX_HOME ?? path93__default.join(env.HOME ?? os22__default.homedir(), ".codex");
33545
+ return env.CODEX_HOME ?? path92__default.join(env.HOME ?? os22__default.homedir(), ".codex");
33262
33546
  }
33263
33547
  function findMarketplaceEntries(result, marketplaceName) {
33548
+ return parseMarketplaceEntries(result).filter((entry) => entry.name === marketplaceName);
33549
+ }
33550
+ function parseMarketplaceEntries(result) {
33264
33551
  const entries = [];
33265
33552
  for (const line of commandOutput(result).split(/\r?\n/)) {
33266
33553
  const match = line.trim().match(/^(\S+)\s+(.+)$/);
33267
- if (match?.[1] === marketplaceName) {
33554
+ if (match) {
33268
33555
  entries.push({ name: match[1], root: match[2].trim() });
33269
33556
  }
33270
33557
  }
33271
33558
  return entries;
33272
33559
  }
33273
33560
  function normalizeMarketplaceRoot(rootPath, cwd) {
33274
- const resolved = path93__default.resolve(cwd, rootPath);
33561
+ const resolved = path92__default.resolve(cwd, rootPath);
33275
33562
  try {
33276
33563
  return realpathSync(resolved);
33277
33564
  } catch (error51) {
@@ -33293,12 +33580,15 @@ function readHash(hashPath) {
33293
33580
  if (!existsSync(hashPath)) return void 0;
33294
33581
  return readFileSync(hashPath, "utf8").trim();
33295
33582
  }
33583
+ function removeFlatMarketplaceResidue(projectMarketplaceRoot) {
33584
+ for (const entry of FLAT_MARKETPLACE_FS_RESIDUE_ENTRIES) {
33585
+ removePrivatePath(path92__default.join(projectMarketplaceRoot, entry), projectMarketplaceRoot);
33586
+ }
33587
+ }
33296
33588
  var FLEET_MARKETPLACE_NAME = "fleet-harness";
33297
- var FLEET_PROJECT_MARKETPLACE_NAME_PREFIX = "fleet-project";
33298
33589
  var MARKETPLACE_DIR_NAME = "marketplace";
33299
- var FLAT_PLUGIN_DIR_NAME = "plugin";
33300
33590
  var PLUGIN_BUNDLES_DIR_NAME = "plugins";
33301
- var PLUGIN_BUNDLES = [assetBundle, projectBundle, globalBundle];
33591
+ var PLUGIN_BUNDLES = [assetBundle];
33302
33592
  var MARKETPLACE_MANAGED_ENTRIES = [
33303
33593
  ".agents",
33304
33594
  ".claude-plugin",
@@ -33310,11 +33600,6 @@ var MARKETPLACE_MANAGED_ENTRIES = [
33310
33600
  "codex-marketplace",
33311
33601
  "plugins"
33312
33602
  ];
33313
- var FLAT_MARKETPLACE_MANAGED_ENTRIES = [
33314
- ".agents",
33315
- ".claude-plugin",
33316
- "plugin"
33317
- ];
33318
33603
  var MARKETPLACE_PRUNE_ENTRIES = [
33319
33604
  ".agents",
33320
33605
  ".claude-plugin",
@@ -33325,14 +33610,10 @@ var MARKETPLACE_PRUNE_ENTRIES = [
33325
33610
  "claude",
33326
33611
  "codex-marketplace"
33327
33612
  ];
33328
- var FLAT_MARKETPLACE_PRUNE_ENTRIES = [
33329
- ".agents",
33330
- ".claude-plugin"
33331
- ];
33332
33613
  var HASH_IGNORED_RELATIVE_PATHS = new Set(PLUGIN_BUNDLES.map((bundle) => bundle.hashFileName));
33333
33614
  async function createAgentCliPlugin(options) {
33334
33615
  const fleetRoot = options.rootDir ?? options.dataDir;
33335
- const renderableBundles = resolveRenderablePluginBundles(options, fleetRoot);
33616
+ const renderableBundles = resolveRenderablePluginBundles(fleetRoot);
33336
33617
  const marketplaceBundles = groupRenderableBundlesByMarketplace(renderableBundles);
33337
33618
  const pluginRoots = /* @__PURE__ */ new Map();
33338
33619
  const contentHashes = /* @__PURE__ */ new Map();
@@ -33341,7 +33622,7 @@ async function createAgentCliPlugin(options) {
33341
33622
  await options.withMarketplaceLock(marketplace.target.root, () => {
33342
33623
  for (const { bundle, target } of marketplace.bundles) {
33343
33624
  const pluginRoot = pluginRootForTarget(target, bundle);
33344
- renderPluginRoot(pluginRoot, bundle, options, fleetRoot);
33625
+ renderPluginRoot(pluginRoot, bundle, options);
33345
33626
  pluginRoots.set(bundle, pluginRoot);
33346
33627
  }
33347
33628
  renderMarketplaceRoot(marketplace.target, marketplace.bundles.map(({ bundle }) => bundle));
@@ -33356,7 +33637,7 @@ async function createAgentCliPlugin(options) {
33356
33637
  cleanup,
33357
33638
  codexRegistrations: options.cliId === "codex" ? renderableBundles.map(({ bundle, target }, index) => ({
33358
33639
  contentHash: contentHashes.get(target.root),
33359
- hashPath: path93__default.join(target.root, bundle.hashFileName),
33640
+ hashPath: path92__default.join(target.root, bundle.hashFileName),
33360
33641
  marketplaceDir: target.root,
33361
33642
  marketplaceName: target.name,
33362
33643
  pluginName: bundle.name,
@@ -33366,43 +33647,14 @@ async function createAgentCliPlugin(options) {
33366
33647
  pluginRoots: resolvedPluginRoots
33367
33648
  };
33368
33649
  }
33369
- function resolveRenderablePluginBundles(options, fleetRoot) {
33650
+ function resolveRenderablePluginBundles(fleetRoot) {
33370
33651
  const homeMarketplace = homeMarketplaceTarget(fleetRoot);
33371
- let projectMarketplace;
33372
- const renderableBundles = [];
33373
- for (const bundle of PLUGIN_BUNDLES) {
33374
- switch (bundle.source) {
33375
- case "project": {
33376
- if (!existsSync(path93__default.join(options.cwd, ".fleet"))) break;
33377
- projectMarketplace ??= projectMarketplaceTarget(options.cwd);
33378
- renderableBundles.push({ bundle, target: projectMarketplace });
33379
- break;
33380
- }
33381
- case "global":
33382
- if (globalFleetContentExists(fleetRoot)) {
33383
- renderableBundles.push({ bundle, target: homeMarketplace });
33384
- }
33385
- break;
33386
- default:
33387
- renderableBundles.push({ bundle, target: homeMarketplace });
33388
- }
33389
- }
33390
- return renderableBundles;
33652
+ return PLUGIN_BUNDLES.map((bundle) => ({ bundle, target: homeMarketplace }));
33391
33653
  }
33392
33654
  function homeMarketplaceTarget(fleetRoot) {
33393
33655
  return {
33394
- flat: false,
33395
33656
  name: FLEET_MARKETPLACE_NAME,
33396
- root: path93__default.join(fleetRoot, MARKETPLACE_DIR_NAME)
33397
- };
33398
- }
33399
- function projectMarketplaceTarget(cwd) {
33400
- const projectFleetRoot = resolveProjectFleetRoot(cwd);
33401
- const hash2 = crypto4.createHash("sha256").update(path93__default.resolve(cwd, ".fleet")).digest("hex").slice(0, 12);
33402
- return {
33403
- flat: true,
33404
- name: `${FLEET_PROJECT_MARKETPLACE_NAME_PREFIX}-${hash2}`,
33405
- root: projectFleetRoot
33657
+ root: path92__default.join(fleetRoot, MARKETPLACE_DIR_NAME)
33406
33658
  };
33407
33659
  }
33408
33660
  function groupRenderableBundlesByMarketplace(bundles) {
@@ -33417,28 +33669,22 @@ function groupRenderableBundlesByMarketplace(bundles) {
33417
33669
  }
33418
33670
  return groups;
33419
33671
  }
33420
- function renderPluginRoot(pluginRoot, bundle, options, fleetRoot) {
33421
- const parentRoot = path93__default.dirname(pluginRoot);
33672
+ function renderPluginRoot(pluginRoot, bundle, options) {
33673
+ const parentRoot = path92__default.dirname(pluginRoot);
33422
33674
  ensurePrivateDir(parentRoot, parentRoot);
33423
33675
  const stageParent = createStagingDir(parentRoot);
33424
- const stagedPluginRoot = path93__default.join(stageParent, path93__default.basename(pluginRoot));
33676
+ const stagedPluginRoot = path92__default.join(stageParent, path92__default.basename(pluginRoot));
33425
33677
  try {
33426
33678
  ensurePrivateDir(stagedPluginRoot, stagedPluginRoot);
33427
- writePrivateJson(path93__default.join(stagedPluginRoot, ".claude-plugin", "plugin.json"), claudeManifest(bundle), stagedPluginRoot);
33679
+ writePrivateJson(path92__default.join(stagedPluginRoot, ".claude-plugin", "plugin.json"), claudeManifest(bundle), stagedPluginRoot);
33428
33680
  switch (bundle.source) {
33429
33681
  case "asset":
33430
- ensurePrivateDir(path93__default.join(stagedPluginRoot, "agents"), stagedPluginRoot);
33431
- ensurePrivateDir(path93__default.join(stagedPluginRoot, "skills"), stagedPluginRoot);
33682
+ ensurePrivateDir(path92__default.join(stagedPluginRoot, "agents"), stagedPluginRoot);
33683
+ ensurePrivateDir(path92__default.join(stagedPluginRoot, "skills"), stagedPluginRoot);
33432
33684
  renderAssetPluginRoot(stagedPluginRoot, bundle, options);
33433
33685
  break;
33434
- case "project":
33435
- renderProjectPluginRoot(stagedPluginRoot, options);
33436
- break;
33437
- case "global":
33438
- renderGlobalPluginRoot(stagedPluginRoot, fleetRoot);
33439
- break;
33440
33686
  }
33441
- writePrivateJson(path93__default.join(stagedPluginRoot, ".codex-plugin", "plugin.json"), codexManifest(bundle, stagedPluginRoot), stagedPluginRoot);
33687
+ writePrivateJson(path92__default.join(stagedPluginRoot, ".codex-plugin", "plugin.json"), codexManifest(bundle, stagedPluginRoot), stagedPluginRoot);
33442
33688
  removePrivatePath(pluginRoot, parentRoot);
33443
33689
  renameSync(stagedPluginRoot, pluginRoot);
33444
33690
  } finally {
@@ -33450,26 +33696,35 @@ function renderMarketplaceRoot(target, bundles) {
33450
33696
  ensurePrivateDir(marketplaceRoot, marketplaceRoot);
33451
33697
  const stagedRoot = createStagingDir(marketplaceRoot);
33452
33698
  try {
33453
- writePrivateJson(path93__default.join(stagedRoot, ".agents", "plugins", "marketplace.json"), codexMarketplace(target, bundles), stagedRoot);
33454
- writePrivateJson(path93__default.join(stagedRoot, ".claude-plugin", "marketplace.json"), claudeMarketplace(target, bundles), stagedRoot);
33699
+ writePrivateJson(path92__default.join(stagedRoot, ".agents", "plugins", "marketplace.json"), codexMarketplace(target, bundles), stagedRoot);
33700
+ writePrivateJson(path92__default.join(stagedRoot, ".claude-plugin", "marketplace.json"), claudeMarketplace(target, bundles), stagedRoot);
33455
33701
  pruneMarketplaceRoot(target);
33702
+ pruneStalePluginDirs(target, bundles);
33456
33703
  for (const entry of readdirSync(stagedRoot)) {
33457
- renameSync(path93__default.join(stagedRoot, entry), path93__default.join(marketplaceRoot, entry));
33704
+ renameSync(path92__default.join(stagedRoot, entry), path92__default.join(marketplaceRoot, entry));
33458
33705
  }
33459
33706
  } finally {
33460
33707
  cleanupPrivateRoot(stagedRoot, marketplaceRoot);
33461
33708
  }
33462
33709
  }
33463
33710
  function pruneMarketplaceRoot(target) {
33464
- const entries = target.flat ? FLAT_MARKETPLACE_PRUNE_ENTRIES : MARKETPLACE_PRUNE_ENTRIES;
33465
- for (const entry of entries) {
33466
- removePrivatePath(path93__default.join(target.root, entry), target.root);
33711
+ for (const entry of MARKETPLACE_PRUNE_ENTRIES) {
33712
+ removePrivatePath(path92__default.join(target.root, entry), target.root);
33713
+ }
33714
+ }
33715
+ function pruneStalePluginDirs(target, bundles) {
33716
+ const pluginsDir = path92__default.join(target.root, PLUGIN_BUNDLES_DIR_NAME);
33717
+ if (!existsSync(pluginsDir)) return;
33718
+ const activeDirectoryNames = new Set(bundles.map((bundle) => bundle.directoryName));
33719
+ for (const entry of readdirSync(pluginsDir)) {
33720
+ if (activeDirectoryNames.has(entry)) continue;
33721
+ removePrivatePath(path92__default.join(pluginsDir, entry), target.root);
33467
33722
  }
33468
33723
  }
33469
33724
  function buildContentHash(target) {
33470
- const hash2 = crypto4.createHash("sha256");
33725
+ const hash2 = crypto3.createHash("sha256");
33471
33726
  for (const filePath of listRenderableFiles(target)) {
33472
- const relativePath2 = path93__default.relative(target.root, filePath);
33727
+ const relativePath2 = path92__default.relative(target.root, filePath);
33473
33728
  hash2.update(relativePath2);
33474
33729
  hash2.update("\0");
33475
33730
  hash2.update(readFileSync(filePath));
@@ -33478,15 +33733,14 @@ function buildContentHash(target) {
33478
33733
  return hash2.digest("hex");
33479
33734
  }
33480
33735
  function createStagingDir(rootPath) {
33481
- const stageRoot = mkdtempSync(path93__default.join(rootPath, `.fleet-stage-${process.pid}-${Date.now()}-`));
33736
+ const stageRoot = mkdtempSync(path92__default.join(rootPath, `.fleet-stage-${process.pid}-${Date.now()}-`));
33482
33737
  return stageRoot;
33483
33738
  }
33484
33739
  function listRenderableFiles(target) {
33485
33740
  const files = [];
33486
33741
  const ancestorRealDirs = /* @__PURE__ */ new Set();
33487
- const entries = target.flat ? FLAT_MARKETPLACE_MANAGED_ENTRIES : MARKETPLACE_MANAGED_ENTRIES;
33488
- for (const entry of entries) {
33489
- const entryPath = path93__default.join(target.root, entry);
33742
+ for (const entry of MARKETPLACE_MANAGED_ENTRIES) {
33743
+ const entryPath = path92__default.join(target.root, entry);
33490
33744
  if (!existsSync(entryPath)) continue;
33491
33745
  collectRenderableFiles(target.root, entryPath, files, ancestorRealDirs);
33492
33746
  }
@@ -33497,8 +33751,8 @@ function collectRenderableFiles(rootPath, currentPath, files, ancestorRealDirs)
33497
33751
  if (ancestorRealDirs.has(realDir)) return;
33498
33752
  ancestorRealDirs.add(realDir);
33499
33753
  for (const entry of readdirSync(currentPath)) {
33500
- const entryPath = path93__default.join(currentPath, entry);
33501
- const relativePath2 = path93__default.relative(rootPath, entryPath);
33754
+ const entryPath = path92__default.join(currentPath, entry);
33755
+ const relativePath2 = path92__default.relative(rootPath, entryPath);
33502
33756
  if (HASH_IGNORED_RELATIVE_PATHS.has(relativePath2)) continue;
33503
33757
  const stat5 = lstatSync(entryPath);
33504
33758
  if (stat5.isSymbolicLink()) {
@@ -33564,10 +33818,9 @@ function claudeMarketplace(target, bundles) {
33564
33818
  };
33565
33819
  }
33566
33820
  function pluginRootForTarget(target, bundle) {
33567
- return target.flat ? path93__default.join(target.root, FLAT_PLUGIN_DIR_NAME) : path93__default.join(target.root, PLUGIN_BUNDLES_DIR_NAME, bundle.directoryName);
33821
+ return path92__default.join(target.root, PLUGIN_BUNDLES_DIR_NAME, bundle.directoryName);
33568
33822
  }
33569
33823
  function marketplacePluginPath(target, bundle) {
33570
- if (target.flat) return `./${FLAT_PLUGIN_DIR_NAME}`;
33571
33824
  return `./${PLUGIN_BUNDLES_DIR_NAME}/${bundle.directoryName}`;
33572
33825
  }
33573
33826
  function codexManifest(bundle, pluginRoot) {
@@ -33579,13 +33832,13 @@ function codexManifest(bundle, pluginRoot) {
33579
33832
  };
33580
33833
  }
33581
33834
  function codexManifestVersion(bundle, pluginRoot) {
33582
- const hash2 = crypto4.createHash("sha256");
33835
+ const hash2 = crypto3.createHash("sha256");
33583
33836
  hash2.update(bundle.name);
33584
33837
  hash2.update("\0");
33585
33838
  hash2.update(bundle.description);
33586
33839
  hash2.update("\0");
33587
33840
  for (const filePath of listCodexEffectivePluginFiles(pluginRoot)) {
33588
- const relativePath2 = path93__default.relative(pluginRoot, filePath);
33841
+ const relativePath2 = path92__default.relative(pluginRoot, filePath);
33589
33842
  hash2.update(relativePath2);
33590
33843
  hash2.update("\0");
33591
33844
  hash2.update(readFileSync(filePath));
@@ -33594,7 +33847,7 @@ function codexManifestVersion(bundle, pluginRoot) {
33594
33847
  return `0.0.0+${hash2.digest("hex").slice(0, 12)}`;
33595
33848
  }
33596
33849
  function listCodexEffectivePluginFiles(pluginRoot) {
33597
- const skillsPath = path93__default.join(pluginRoot, "skills");
33850
+ const skillsPath = path92__default.join(pluginRoot, "skills");
33598
33851
  if (!existsSync(skillsPath)) return [];
33599
33852
  const files = [];
33600
33853
  collectRenderableFiles(pluginRoot, skillsPath, files, /* @__PURE__ */ new Set());
@@ -33619,13 +33872,13 @@ async function injectAgentCliProfile(profile, options) {
33619
33872
  const injectTone = options.enableMetaphor ?? false;
33620
33873
  const endpoint = await options.dedicatedMcpSession.getEndpoint();
33621
33874
  const startupDefinitions = buildStartupNativeDefinitions(profile.id, options.carrierRuntime);
33622
- const tokenLabel = options.mcpSessionLabel ?? `agent:${profile.id}:${crypto4.randomUUID()}`;
33875
+ const tokenLabel = options.mcpSessionLabel ?? `agent:${profile.id}:${crypto3.randomUUID()}`;
33623
33876
  const tokens = await options.dedicatedMcpSession.issueSessionToken({ cwd: profile.cwd, label: tokenLabel });
33624
33877
  const mcpServers = buildAgentCliMcpServerConfigs(endpoint.servers, tokens);
33625
33878
  const doctrine = options.buildSystemPrompt(injectTone);
33626
33879
  const tempCleanups = [];
33627
33880
  try {
33628
- const systemPromptFile = profile.id === "claude" || profile.id === "claude-kimi" ? writeSystemPromptFile(profile.id, doctrine, (cleanup2) => tempCleanups.push(cleanup2)) : void 0;
33881
+ const systemPromptFile = profile.id === "claude" || profile.id === "claude-kimi" || profile.id === "claude-glm" ? writeSystemPromptFile(profile.id, doctrine, (cleanup2) => tempCleanups.push(cleanup2)) : void 0;
33629
33882
  const plugin = await createAgentCliPlugin({
33630
33883
  claudeDefinitions: startupDefinitions.host === "claude" ? startupDefinitions.definitions : [],
33631
33884
  cliId: profile.id,
@@ -33637,6 +33890,7 @@ async function injectAgentCliProfile(profile, options) {
33637
33890
  turnStartHookExec: options.turnStartHookExec,
33638
33891
  turnEndHookExec: options.turnEndHookExec,
33639
33892
  inputWaitingHookExec: options.inputWaitingHookExec,
33893
+ autoNameHookExec: options.autoNameHookExec,
33640
33894
  hookExec: startupDefinitions.host === "claude" ? requireHookExec(options.hookExec) : void 0,
33641
33895
  withMarketplaceLock: options.withMarketplaceLock
33642
33896
  });
@@ -33644,9 +33898,25 @@ async function injectAgentCliProfile(profile, options) {
33644
33898
  const codexProfile = profile.id === "codex" ? writeCodexFleetProfile(profile.env, doctrine, codexPluginKeys, {
33645
33899
  captureSessionHookExec: options.captureSessionHookExec,
33646
33900
  turnStartHookExec: options.turnStartHookExec,
33647
- turnEndHookExec: options.turnEndHookExec
33901
+ turnEndHookExec: options.turnEndHookExec,
33902
+ autoNameHookExec: options.autoNameHookExec
33648
33903
  }, (cleanup2) => tempCleanups.push(cleanup2)) : void 0;
33649
33904
  const launchWarnings = [];
33905
+ if (profile.id === "codex") {
33906
+ const cleanupWarning = await cleanupDeprecatedCodexPluginState({
33907
+ args: [...profile.binPrefixArgs ?? []],
33908
+ bin: profile.bin,
33909
+ cwd: profile.cwd,
33910
+ env: { ...profile.env }
33911
+ }, requireCodexCommandRunner(options.codexCommandRunner), options.withMarketplaceLock, {
33912
+ homeMarketplaceName: FLEET_MARKETPLACE_NAME,
33913
+ homeMarketplaceRoot: path92__default.join(options.pluginRootDir ?? options.dataDir, "marketplace"),
33914
+ projectMarketplaceRoot: path92__default.join(profile.cwd, ".fleet")
33915
+ });
33916
+ if (cleanupWarning !== void 0) {
33917
+ launchWarnings.push(`Deprecated Codex plugin cleanup failed: ${cleanupWarning}`);
33918
+ }
33919
+ }
33650
33920
  for (const registration of plugin.codexRegistrations) {
33651
33921
  const registrationWarning = await ensureCodexPluginRegistered(registration, {
33652
33922
  args: [...profile.binPrefixArgs ?? []],
@@ -33697,7 +33967,7 @@ function buildStartupNativeDefinitions(cliId, carrierRuntime) {
33697
33967
  return { host, definitions: buildClaudeNativeSubagentPlan2(carrierRuntime.registry).definitions };
33698
33968
  }
33699
33969
  function getNativeSubagentHost(cliId) {
33700
- if (cliId === "claude" || cliId === "claude-kimi") return "claude";
33970
+ if (cliId === "claude" || cliId === "claude-kimi" || cliId === "claude-glm") return "claude";
33701
33971
  return "none";
33702
33972
  }
33703
33973
  function buildAgentCliMcpServerConfigs(endpoints, tokens) {
@@ -33714,19 +33984,19 @@ function buildAgentCliMcpServerConfigs(endpoints, tokens) {
33714
33984
  });
33715
33985
  }
33716
33986
  function writeSystemPromptFile(cliId, systemPrompt, onCleanup) {
33717
- const tempDir = mkdtempSync(path93__default.join(os22__default.tmpdir(), `fleet-${cliId}-`));
33987
+ const tempDir = mkdtempSync(path92__default.join(os22__default.tmpdir(), `fleet-${cliId}-`));
33718
33988
  onCleanup(() => rmBestEffort(tempDir));
33719
- const filePath = path93__default.join(tempDir, "system-prompt.md");
33989
+ const filePath = path92__default.join(tempDir, "system-prompt.md");
33720
33990
  writeFileSync(filePath, systemPrompt, { encoding: "utf8", flag: "wx", mode: SYSTEM_PROMPT_FILE_MODE });
33721
33991
  chmodBestEffort2(filePath, SYSTEM_PROMPT_FILE_MODE);
33722
33992
  return filePath;
33723
33993
  }
33724
33994
  function writeCodexFleetProfile(env, doctrine, pluginKeys, hookExecs, onCleanup) {
33725
- const codexHome = env.CODEX_HOME ?? path93__default.join(env.HOME ?? os22__default.homedir(), ".codex");
33995
+ const codexHome = env.CODEX_HOME ?? path92__default.join(env.HOME ?? os22__default.homedir(), ".codex");
33726
33996
  mkdirSync(codexHome, { recursive: true });
33727
33997
  pruneStaleCodexFleetProfiles(codexHome);
33728
- const profileName = `fleet-${crypto4.randomUUID()}`;
33729
- const profilePath = path93__default.join(codexHome, `${profileName}.config.toml`);
33998
+ const profileName = `fleet-${crypto3.randomUUID()}`;
33999
+ const profilePath = path92__default.join(codexHome, `${profileName}.config.toml`);
33730
34000
  onCleanup(() => rmBestEffort(profilePath));
33731
34001
  writeFileNoFollow2(profilePath, [
33732
34002
  CODEX_FLEET_PROFILE_MARKER,
@@ -33747,7 +34017,7 @@ function writeCodexFleetProfile(env, doctrine, pluginKeys, hookExecs, onCleanup)
33747
34017
  return { profileName, profilePath };
33748
34018
  }
33749
34019
  function codexHooksConfig(hookExecs) {
33750
- const userPromptSubmitExecs = [hookExecs.captureSessionHookExec, hookExecs.turnStartHookExec].filter((exec) => exec !== void 0);
34020
+ const userPromptSubmitExecs = [hookExecs.captureSessionHookExec, hookExecs.turnStartHookExec, hookExecs.autoNameHookExec].filter((exec) => exec !== void 0);
33751
34021
  const stopExecs = [hookExecs.turnEndHookExec].filter((exec) => exec !== void 0);
33752
34022
  if (userPromptSubmitExecs.length === 0 && stopExecs.length === 0) return [];
33753
34023
  const lines = ["[hooks]"];
@@ -33786,7 +34056,7 @@ function pruneStaleCodexFleetProfiles(codexHome) {
33786
34056
  const now = Date.now();
33787
34057
  for (const entry of entries) {
33788
34058
  if (!CODEX_FLEET_PROFILE_FILE_NAME_PATTERN.test(entry)) continue;
33789
- const filePath = path93__default.join(codexHome, entry);
34059
+ const filePath = path92__default.join(codexHome, entry);
33790
34060
  if (!isStaleFleetCodexProfile(filePath, now)) continue;
33791
34061
  unlinkBestEffort2(filePath);
33792
34062
  }
@@ -34230,7 +34500,7 @@ function extractLegacyMarkdownWikiLinks(body, wikiDir, basePath) {
34230
34500
  }
34231
34501
  function resolveLegacyWikiTarget(target, wikiDir, basePath) {
34232
34502
  if (!target || target.startsWith("#")) return null;
34233
- if (path93__default.isAbsolute(target)) return null;
34503
+ if (path92__default.isAbsolute(target)) return null;
34234
34504
  if (/^[a-z][a-z0-9+.-]*:/i.test(target)) return null;
34235
34505
  const withoutFragment = target.split("#", 1)[0]?.split("?", 1)[0] ?? "";
34236
34506
  if (!withoutFragment.endsWith(".md")) return null;
@@ -34240,12 +34510,12 @@ function resolveLegacyWikiTarget(target, wikiDir, basePath) {
34240
34510
  } catch {
34241
34511
  return null;
34242
34512
  }
34243
- const resolved = path93__default.resolve(path93__default.dirname(basePath), decodedTarget);
34244
- const relative = path93__default.relative(wikiDir, resolved);
34245
- if (!relative || relative.startsWith("..") || path93__default.isAbsolute(relative)) return null;
34513
+ const resolved = path92__default.resolve(path92__default.dirname(basePath), decodedTarget);
34514
+ const relative = path92__default.relative(wikiDir, resolved);
34515
+ if (!relative || relative.startsWith("..") || path92__default.isAbsolute(relative)) return null;
34246
34516
  return {
34247
34517
  target,
34248
- entryId: path93__default.basename(relative, ".md")
34518
+ entryId: path92__default.basename(relative, ".md")
34249
34519
  };
34250
34520
  }
34251
34521
  var KNOWLEDGE_ROOT_DIRNAME = ".fleet/knowledge";
@@ -34503,18 +34773,18 @@ Always read \`schema/wiki-schema.md\` directly before composing or revising entr
34503
34773
  `;
34504
34774
  async function ensureWorkspaceSchema(paths) {
34505
34775
  await mkdir(paths.schemaDir, { recursive: true });
34506
- await writeDefaultFileIfMissing(path93__default.join(paths.schemaDir, WORKSPACE_SCHEMA_AGENTS_FILENAME), DEFAULT_WORKSPACE_SCHEMA_AGENTS);
34507
- await writeDefaultFileIfMissing(path93__default.join(paths.schemaDir, WORKSPACE_SCHEMA_FILENAME), DEFAULT_WORKSPACE_WIKI_SCHEMA);
34776
+ await writeDefaultFileIfMissing(path92__default.join(paths.schemaDir, WORKSPACE_SCHEMA_AGENTS_FILENAME), DEFAULT_WORKSPACE_SCHEMA_AGENTS);
34777
+ await writeDefaultFileIfMissing(path92__default.join(paths.schemaDir, WORKSPACE_SCHEMA_FILENAME), DEFAULT_WORKSPACE_WIKI_SCHEMA);
34508
34778
  await writeDefaultFileIfMissing(buildTemplatePath(paths, "prd"), DEFAULT_TEMPLATE_PRD);
34509
34779
  return readWorkspaceSchemaSummary(paths);
34510
34780
  }
34511
34781
  async function ensureWorkspaceDoctrine(paths) {
34512
34782
  await mkdir(paths.root, { recursive: true });
34513
- await writeDefaultFileIfMissing(path93__default.join(paths.root, WORKSPACE_KNOWLEDGE_AGENTS_FILENAME), DEFAULT_WORKSPACE_KNOWLEDGE_AGENTS);
34783
+ await writeDefaultFileIfMissing(path92__default.join(paths.root, WORKSPACE_KNOWLEDGE_AGENTS_FILENAME), DEFAULT_WORKSPACE_KNOWLEDGE_AGENTS);
34514
34784
  }
34515
34785
  async function readWorkspaceSchemaSummary(paths) {
34516
- const agentsPath = path93__default.join(paths.schemaDir, WORKSPACE_SCHEMA_AGENTS_FILENAME);
34517
- const wikiSchemaPath = path93__default.join(paths.schemaDir, WORKSPACE_SCHEMA_FILENAME);
34786
+ const agentsPath = path92__default.join(paths.schemaDir, WORKSPACE_SCHEMA_AGENTS_FILENAME);
34787
+ const wikiSchemaPath = path92__default.join(paths.schemaDir, WORKSPACE_SCHEMA_FILENAME);
34518
34788
  const wikiSchemaContent = await tryReadFile(wikiSchemaPath);
34519
34789
  const templates = await scanTemplates(paths);
34520
34790
  if (wikiSchemaContent === null) {
@@ -34553,7 +34823,7 @@ async function scanTemplates(paths) {
34553
34823
  if (!entry.name.startsWith(WORKSPACE_TEMPLATE_PREFIX) || !entry.name.endsWith(WORKSPACE_TEMPLATE_SUFFIX)) continue;
34554
34824
  const id = entry.name.slice(WORKSPACE_TEMPLATE_PREFIX.length, -WORKSPACE_TEMPLATE_SUFFIX.length);
34555
34825
  if (!id) continue;
34556
- const filePath = path93__default.join(paths.schemaDir, entry.name);
34826
+ const filePath = path92__default.join(paths.schemaDir, entry.name);
34557
34827
  try {
34558
34828
  const parsed = parseTemplateMarkdown(await readFile(filePath, "utf8"));
34559
34829
  templates.push({
@@ -34587,7 +34857,7 @@ async function validateTemplateCompliance(paths, templateId, body) {
34587
34857
  }
34588
34858
  }
34589
34859
  function inferTemplateIdFromTarget(target, knownTemplateIds) {
34590
- const basename = path93__default.basename(target, ".md");
34860
+ const basename = path92__default.basename(target, ".md");
34591
34861
  const ids = knownTemplateIds ?? DEFAULT_TEMPLATE_IDS;
34592
34862
  const sorted = [...ids].sort((a, b) => b.length - a.length);
34593
34863
  for (const id of sorted) {
@@ -34616,7 +34886,7 @@ function extractSchemaSummary(content) {
34616
34886
  return lines.find((line) => line.length > 0 && !line.startsWith("#")) ?? "Workspace schema is present.";
34617
34887
  }
34618
34888
  function buildTemplatePath(paths, id) {
34619
- return path93__default.join(paths.schemaDir, `${WORKSPACE_TEMPLATE_PREFIX}${id}${WORKSPACE_TEMPLATE_SUFFIX}`);
34889
+ return path92__default.join(paths.schemaDir, `${WORKSPACE_TEMPLATE_PREFIX}${id}${WORKSPACE_TEMPLATE_SUFFIX}`);
34620
34890
  }
34621
34891
  function parseTemplateMarkdown(content) {
34622
34892
  const normalized = content.replace(/\r\n/g, "\n");
@@ -34641,16 +34911,16 @@ function isAlreadyExistsError(error51) {
34641
34911
  return typeof error51 === "object" && error51 !== null && "code" in error51 && error51.code === "EEXIST";
34642
34912
  }
34643
34913
  function resolveMemoryPaths(cwd) {
34644
- const root = path93__default.join(cwd, KNOWLEDGE_ROOT_DIRNAME);
34914
+ const root = path92__default.join(cwd, KNOWLEDGE_ROOT_DIRNAME);
34645
34915
  return {
34646
34916
  root,
34647
- rawDir: path93__default.join(root, RAW_DIRNAME),
34648
- wikiDir: path93__default.join(root, WIKI_DIRNAME),
34649
- schemaDir: path93__default.join(root, SCHEMA_DIRNAME),
34650
- queueDir: path93__default.join(root, QUEUE_DIRNAME),
34651
- archiveDir: path93__default.join(root, ARCHIVE_DIRNAME),
34652
- conflictsDir: path93__default.join(root, CONFLICTS_DIRNAME),
34653
- indexFile: path93__default.join(root, INDEX_FILENAME)
34917
+ rawDir: path92__default.join(root, RAW_DIRNAME),
34918
+ wikiDir: path92__default.join(root, WIKI_DIRNAME),
34919
+ schemaDir: path92__default.join(root, SCHEMA_DIRNAME),
34920
+ queueDir: path92__default.join(root, QUEUE_DIRNAME),
34921
+ archiveDir: path92__default.join(root, ARCHIVE_DIRNAME),
34922
+ conflictsDir: path92__default.join(root, CONFLICTS_DIRNAME),
34923
+ indexFile: path92__default.join(root, INDEX_FILENAME)
34654
34924
  };
34655
34925
  }
34656
34926
  async function ensureMemoryRoot(paths) {
@@ -34665,10 +34935,10 @@ async function ensureMemoryRoot(paths) {
34665
34935
  await ensureWorkspaceDoctrine(paths);
34666
34936
  }
34667
34937
  function getIndexMarkdownFile(paths) {
34668
- return path93__default.join(paths.wikiDir, INDEX_MD_FILENAME);
34938
+ return path92__default.join(paths.wikiDir, INDEX_MD_FILENAME);
34669
34939
  }
34670
34940
  function getLogFile(paths) {
34671
- return path93__default.join(paths.root, LOG_MD_FILENAME);
34941
+ return path92__default.join(paths.root, LOG_MD_FILENAME);
34672
34942
  }
34673
34943
  var LOG_HEADER_PATTERN = /^## (.+) — (.+)$/;
34674
34944
  var LOG_BULLET_PATTERN = /^- ([a-z0-9_]+): `([\s\S]*)`$/;
@@ -34826,12 +35096,12 @@ async function readWikiEntry(id, paths) {
34826
35096
  const index = await loadIndex(paths);
34827
35097
  const indexed = index[id];
34828
35098
  if (indexed) {
34829
- const resolved = path93__default.resolve(paths.root, indexed.path);
34830
- const rel = path93__default.relative(paths.wikiDir, resolved);
34831
- if (!rel || rel.startsWith("..") || path93__default.isAbsolute(rel)) return null;
35099
+ const resolved = path92__default.resolve(paths.root, indexed.path);
35100
+ const rel = path92__default.relative(paths.wikiDir, resolved);
35101
+ if (!rel || rel.startsWith("..") || path92__default.isAbsolute(rel)) return null;
34832
35102
  return readMarkdownFile(resolved);
34833
35103
  }
34834
- const fallbackPath = path93__default.join(paths.wikiDir, `${id}.md`);
35104
+ const fallbackPath = path92__default.join(paths.wikiDir, `${id}.md`);
34835
35105
  if (await pathExists(fallbackPath)) {
34836
35106
  return readMarkdownFile(fallbackPath);
34837
35107
  }
@@ -34842,20 +35112,20 @@ async function readWikiEntry(id, paths) {
34842
35112
  async function writeWikiEntryAtTarget(entry, target, paths) {
34843
35113
  await ensureMemoryRoot(paths);
34844
35114
  assertSafeEntryId(entry.id);
34845
- const absoluteTarget = path93__default.resolve(paths.root, target);
34846
- const relativeTarget = path93__default.relative(paths.wikiDir, absoluteTarget);
34847
- if (!relativeTarget || relativeTarget.startsWith("..") || path93__default.isAbsolute(relativeTarget)) {
35115
+ const absoluteTarget = path92__default.resolve(paths.root, target);
35116
+ const relativeTarget = path92__default.relative(paths.wikiDir, absoluteTarget);
35117
+ if (!relativeTarget || relativeTarget.startsWith("..") || path92__default.isAbsolute(relativeTarget)) {
34848
35118
  throw new Error(`[fleet-wiki] wiki target escapes wiki/: ${target}`);
34849
35119
  }
34850
35120
  if (!absoluteTarget.endsWith(".md")) {
34851
35121
  throw new Error(`[fleet-wiki] wiki target must end with .md: ${target}`);
34852
35122
  }
34853
- if (path93__default.basename(absoluteTarget, ".md") !== entry.id) {
35123
+ if (path92__default.basename(absoluteTarget, ".md") !== entry.id) {
34854
35124
  throw new Error("wiki patch body id must match target filename");
34855
35125
  }
34856
- await mkdir(path93__default.dirname(absoluteTarget), { recursive: true });
35126
+ await mkdir(path92__default.dirname(absoluteTarget), { recursive: true });
34857
35127
  await writeMarkdownAtomic(absoluteTarget, serializeWikiEntry(entry), paths);
34858
- return path93__default.join("wiki", relativeTarget).replaceAll(path93__default.sep, "/");
35128
+ return path92__default.join("wiki", relativeTarget).replaceAll(path92__default.sep, "/");
34859
35129
  }
34860
35130
  async function writeRawSourceEntry(entry, paths) {
34861
35131
  await ensureMemoryRoot(paths);
@@ -34874,11 +35144,11 @@ async function writeRawSourceEntry(entry, paths) {
34874
35144
  },
34875
35145
  entry.content
34876
35146
  );
34877
- await writeMarkdownAtomic(path93__default.join(paths.root, relativePath2), content, paths);
35147
+ await writeMarkdownAtomic(path92__default.join(paths.root, relativePath2), content, paths);
34878
35148
  return relativePath2;
34879
35149
  }
34880
35150
  async function readRawSourceEntry(rawSourceRef, paths) {
34881
- const absolutePath = path93__default.resolve(paths.root, rawSourceRef);
35151
+ const absolutePath = path92__default.resolve(paths.root, rawSourceRef);
34882
35152
  assertWithinRawDir(absolutePath, paths);
34883
35153
  const parsed = parseMarkdown(await readFile(absolutePath, "utf8"));
34884
35154
  return {
@@ -35066,11 +35336,11 @@ function stripLeadingFrontmatter(body) {
35066
35336
  return stripped ? next : body;
35067
35337
  }
35068
35338
  function computeContentHash(content) {
35069
- return crypto4.createHash("sha256").update(content, "utf8").digest("hex").slice(0, 8);
35339
+ return crypto3.createHash("sha256").update(content, "utf8").digest("hex").slice(0, 8);
35070
35340
  }
35071
35341
  function assertWithinRawDir(absolutePath, paths) {
35072
- const relative = path93__default.relative(paths.rawDir, absolutePath);
35073
- if (!relative || relative.startsWith("..") || path93__default.isAbsolute(relative)) {
35342
+ const relative = path92__default.relative(paths.rawDir, absolutePath);
35343
+ if (!relative || relative.startsWith("..") || path92__default.isAbsolute(relative)) {
35074
35344
  throw new Error(`[fleet-wiki] raw source ref escapes raw/: ${absolutePath}`);
35075
35345
  }
35076
35346
  }
@@ -35126,7 +35396,7 @@ function parseWikiEntry(content) {
35126
35396
  async function listWikiRecords(paths) {
35127
35397
  return listMarkdownEntriesRecursive(paths.wikiDir, paths, (content, filePath) => ({
35128
35398
  entry: parseWikiEntry(content),
35129
- path: path93__default.relative(paths.root, filePath).replaceAll(path93__default.sep, "/")
35399
+ path: path92__default.relative(paths.root, filePath).replaceAll(path92__default.sep, "/")
35130
35400
  }));
35131
35401
  }
35132
35402
  async function listMarkdownEntriesRecursive(dirPath, paths, parser) {
@@ -35139,7 +35409,7 @@ async function listMarkdownEntriesRecursive(dirPath, paths, parser) {
35139
35409
  }
35140
35410
  const sortedEntries = entries.sort((left, right) => left.name.localeCompare(right.name));
35141
35411
  for (const entry of sortedEntries) {
35142
- const filePath = path93__default.join(dirPath, entry.name);
35412
+ const filePath = path92__default.join(dirPath, entry.name);
35143
35413
  if (entry.isDirectory()) {
35144
35414
  items.push(...await listMarkdownEntriesRecursive(filePath, paths, parser));
35145
35415
  continue;
@@ -35277,9 +35547,9 @@ async function writeJsonAtomic(filePath, value, paths) {
35277
35547
  }
35278
35548
  async function writeAtomic(filePath, content, paths) {
35279
35549
  await ensureMemoryRoot(paths);
35280
- const tempPath = path93__default.join(
35281
- path93__default.dirname(filePath),
35282
- `.tmp-${process.pid}-${Date.now()}-${crypto4.randomUUID()}-${os22__default.hostname()}`
35550
+ const tempPath = path92__default.join(
35551
+ path92__default.dirname(filePath),
35552
+ `.tmp-${process.pid}-${Date.now()}-${crypto3.randomUUID()}-${os22__default.hostname()}`
35283
35553
  );
35284
35554
  await writeFile(tempPath, content, "utf8");
35285
35555
  await rename(tempPath, filePath);
@@ -35323,7 +35593,7 @@ async function enhancedSearch(paths, options) {
35323
35593
  for (const entry of entries) {
35324
35594
  if (!index[entry.id]) {
35325
35595
  index[entry.id] = {
35326
- path: path93__default.join("wiki", `${entry.id}.md`),
35596
+ path: path92__default.join("wiki", `${entry.id}.md`),
35327
35597
  title: entry.title,
35328
35598
  tags: entry.tags,
35329
35599
  updated: entry.updated
@@ -35459,7 +35729,7 @@ function toEnhancedHit(entry, signals) {
35459
35729
  score: enhancedScore,
35460
35730
  reason: signals.legacyReason ?? "body",
35461
35731
  excerpt,
35462
- path: path93__default.join("wiki", `${entry.id}.md`),
35732
+ path: path92__default.join("wiki", `${entry.id}.md`),
35463
35733
  tags: entry.tags,
35464
35734
  updated: entry.updated,
35465
35735
  version: entry.version,
@@ -35653,7 +35923,7 @@ function toRankedHit(entry, reason, detail, graphBoost, backlinksById) {
35653
35923
  score: basePriority * 100 + statusPriority * 10 + graphScore + (detail.tagBoost ?? 0),
35654
35924
  reason,
35655
35925
  excerpt,
35656
- path: path93__default.join("wiki", `${entry.id}.md`),
35926
+ path: path92__default.join("wiki", `${entry.id}.md`),
35657
35927
  tags: entry.tags,
35658
35928
  updated: entry.updated,
35659
35929
  version: entry.version,
@@ -36077,15 +36347,15 @@ var PATCH_SET_DIRNAME = "_sets";
36077
36347
  var PATCH_SET_META_FILENAME = PATCH_META_FILENAME;
36078
36348
  function getPatchSetDir(paths, patchSetId) {
36079
36349
  assertSafePatchSetId(patchSetId);
36080
- const patchSetDir = path93__default.join(paths.queueDir, PATCH_SET_DIRNAME, patchSetId);
36081
- const relative = path93__default.relative(path93__default.join(paths.queueDir, PATCH_SET_DIRNAME), patchSetDir);
36082
- if (!relative || relative.startsWith("..") || path93__default.isAbsolute(relative)) {
36350
+ const patchSetDir = path92__default.join(paths.queueDir, PATCH_SET_DIRNAME, patchSetId);
36351
+ const relative = path92__default.relative(path92__default.join(paths.queueDir, PATCH_SET_DIRNAME), patchSetDir);
36352
+ if (!relative || relative.startsWith("..") || path92__default.isAbsolute(relative)) {
36083
36353
  throw new Error(`[fleet-wiki] patch set id escapes queue/_sets: ${patchSetId}`);
36084
36354
  }
36085
36355
  return patchSetDir;
36086
36356
  }
36087
36357
  function getPatchSetMetaFile(paths, patchSetId) {
36088
- return path93__default.join(getPatchSetDir(paths, patchSetId), PATCH_SET_META_FILENAME);
36358
+ return path92__default.join(getPatchSetDir(paths, patchSetId), PATCH_SET_META_FILENAME);
36089
36359
  }
36090
36360
  function buildPatchSetId(createdAt, sourceRef) {
36091
36361
  const compact = createdAt.replace(/[:.]/g, "-");
@@ -36118,7 +36388,7 @@ async function createConflict(input, paths) {
36118
36388
  await ensureMemoryRoot(paths);
36119
36389
  const now = input.now ?? /* @__PURE__ */ new Date();
36120
36390
  const conflictId = buildConflictId(now, input.wikiId, input.reason, input.proposed);
36121
- const conflictDir = path93__default.join(paths.conflictsDir, conflictId);
36391
+ const conflictDir = path92__default.join(paths.conflictsDir, conflictId);
36122
36392
  await mkdir(conflictDir, { recursive: true });
36123
36393
  const meta3 = {
36124
36394
  id: conflictId,
@@ -36138,13 +36408,13 @@ async function createConflict(input, paths) {
36138
36408
  currentHash: input.currentHash,
36139
36409
  warnings: input.warnings
36140
36410
  };
36141
- await writeJsonFile(path93__default.join(conflictDir, CONFLICT_META_FILENAME), meta3, paths);
36142
- await writePatchFile(path93__default.join(conflictDir, CONFLICT_PROPOSED_FILENAME), input.proposed, paths);
36411
+ await writeJsonFile(path92__default.join(conflictDir, CONFLICT_META_FILENAME), meta3, paths);
36412
+ await writePatchFile(path92__default.join(conflictDir, CONFLICT_PROPOSED_FILENAME), input.proposed, paths);
36143
36413
  if (input.current !== void 0) {
36144
- await writePatchFile(path93__default.join(conflictDir, CONFLICT_CURRENT_FILENAME), input.current, paths);
36414
+ await writePatchFile(path92__default.join(conflictDir, CONFLICT_CURRENT_FILENAME), input.current, paths);
36145
36415
  }
36146
36416
  if (input.rawSource !== void 0) {
36147
- await writePatchFile(path93__default.join(conflictDir, CONFLICT_RAW_SOURCE_FILENAME), input.rawSource, paths);
36417
+ await writePatchFile(path92__default.join(conflictDir, CONFLICT_RAW_SOURCE_FILENAME), input.rawSource, paths);
36148
36418
  }
36149
36419
  return {
36150
36420
  meta: meta3,
@@ -36158,7 +36428,7 @@ async function listConflicts(paths) {
36158
36428
  const metas = [];
36159
36429
  for (const id of ids) {
36160
36430
  try {
36161
- metas.push(await readJsonFile2(path93__default.join(paths.conflictsDir, id, CONFLICT_META_FILENAME)));
36431
+ metas.push(await readJsonFile2(path92__default.join(paths.conflictsDir, id, CONFLICT_META_FILENAME)));
36162
36432
  } catch {
36163
36433
  continue;
36164
36434
  }
@@ -36167,13 +36437,13 @@ async function listConflicts(paths) {
36167
36437
  }
36168
36438
  async function readConflict(conflictId, paths) {
36169
36439
  const conflictDir = resolveConflictDir(conflictId, paths);
36170
- const meta3 = await readJsonFile2(path93__default.join(conflictDir, CONFLICT_META_FILENAME));
36171
- const currentPath = path93__default.join(conflictDir, CONFLICT_CURRENT_FILENAME);
36172
- const rawSourcePath = path93__default.join(conflictDir, CONFLICT_RAW_SOURCE_FILENAME);
36440
+ const meta3 = await readJsonFile2(path92__default.join(conflictDir, CONFLICT_META_FILENAME));
36441
+ const currentPath = path92__default.join(conflictDir, CONFLICT_CURRENT_FILENAME);
36442
+ const rawSourcePath = path92__default.join(conflictDir, CONFLICT_RAW_SOURCE_FILENAME);
36173
36443
  return {
36174
36444
  meta: meta3,
36175
36445
  current: await pathExists(currentPath) ? await readPatchFile(currentPath) : void 0,
36176
- proposed: await readPatchFile(path93__default.join(conflictDir, CONFLICT_PROPOSED_FILENAME)),
36446
+ proposed: await readPatchFile(path92__default.join(conflictDir, CONFLICT_PROPOSED_FILENAME)),
36177
36447
  rawSource: await pathExists(rawSourcePath) ? await readPatchFile(rawSourcePath) : void 0
36178
36448
  };
36179
36449
  }
@@ -36192,9 +36462,9 @@ function sanitizeConflictToken(value) {
36192
36462
  return value.toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 64) || "unknown";
36193
36463
  }
36194
36464
  function resolveConflictDir(conflictId, paths) {
36195
- const conflictDir = path93__default.resolve(paths.conflictsDir, conflictId);
36196
- const relative = path93__default.relative(paths.conflictsDir, conflictDir);
36197
- if (!relative || relative.startsWith("..") || path93__default.isAbsolute(relative)) {
36465
+ const conflictDir = path92__default.resolve(paths.conflictsDir, conflictId);
36466
+ const relative = path92__default.relative(paths.conflictsDir, conflictDir);
36467
+ if (!relative || relative.startsWith("..") || path92__default.isAbsolute(relative)) {
36198
36468
  throw new Error(`[fleet-wiki] conflict id escapes conflicts/: ${conflictId}`);
36199
36469
  }
36200
36470
  return conflictDir;
@@ -36230,11 +36500,11 @@ async function validatePatch(patch, paths) {
36230
36500
  if (!target || !summary || !proposer || !created) throw new Error("patch frontmatter is incomplete");
36231
36501
  if (summary.length > 120) throw new Error("patch summary exceeds 120 chars");
36232
36502
  assertCanonicalPatchTarget(target);
36233
- const absoluteTarget = path93__default.resolve(paths.root, target);
36234
- if (!absoluteTarget.startsWith(`${paths.root}${path93__default.sep}`) && absoluteTarget !== paths.root) {
36503
+ const absoluteTarget = path92__default.resolve(paths.root, target);
36504
+ if (!absoluteTarget.startsWith(`${paths.root}${path92__default.sep}`) && absoluteTarget !== paths.root) {
36235
36505
  throw new Error("patch target escapes wiki root");
36236
36506
  }
36237
- if (!absoluteTarget.startsWith(`${paths.wikiDir}${path93__default.sep}`)) throw new Error("wiki patch must target wiki/");
36507
+ if (!absoluteTarget.startsWith(`${paths.wikiDir}${path92__default.sep}`)) throw new Error("wiki patch must target wiki/");
36238
36508
  assertNoSymlinkPathComponents(target, paths);
36239
36509
  if (op === "create_wiki" && await pathExists(absoluteTarget)) {
36240
36510
  throw new Error(
@@ -36255,19 +36525,19 @@ async function applyPatch(patch, paths) {
36255
36525
  async function enqueuePatch(patch, paths, metaOverrides) {
36256
36526
  await ensureMemoryRoot(paths);
36257
36527
  const patchId = buildPatchId(patch.frontmatter.created, patch.frontmatter.summary, patch.frontmatter.target, patch.body);
36258
- const queueDir = path93__default.join(paths.queueDir, patchId);
36528
+ const queueDir = path92__default.join(paths.queueDir, patchId);
36259
36529
  if (await pathExists(queueDir)) {
36260
36530
  throw new Error(`[fleet-wiki] patch id collision: ${patchId} - this should never happen with target+body hashing`);
36261
36531
  }
36262
36532
  await mkdir(queueDir, { recursive: true });
36263
- await writePatchFile(path93__default.join(queueDir, PATCH_FILENAME), serializePatch(patch), paths);
36533
+ await writePatchFile(path92__default.join(queueDir, PATCH_FILENAME), serializePatch(patch), paths);
36264
36534
  const meta3 = {
36265
36535
  id: patchId,
36266
36536
  status: "pending",
36267
36537
  createdAt: patch.frontmatter.created,
36268
36538
  ...metaOverrides
36269
36539
  };
36270
- await writeJsonFile(path93__default.join(queueDir, PATCH_META_FILENAME), meta3, paths);
36540
+ await writeJsonFile(path92__default.join(queueDir, PATCH_META_FILENAME), meta3, paths);
36271
36541
  await appendLog(paths, "patch enqueued", {
36272
36542
  patch_id: patchId,
36273
36543
  patch_set_id: meta3.patch_set_id ?? null,
@@ -36285,7 +36555,7 @@ async function listQueue(paths) {
36285
36555
  for (const id of ids) {
36286
36556
  if (id === "_sets") continue;
36287
36557
  try {
36288
- const meta3 = await readJsonFile2(path93__default.join(paths.queueDir, id, PATCH_META_FILENAME));
36558
+ const meta3 = await readJsonFile2(path92__default.join(paths.queueDir, id, PATCH_META_FILENAME));
36289
36559
  results.push({ id, meta: meta3 });
36290
36560
  } catch {
36291
36561
  continue;
@@ -36310,17 +36580,17 @@ async function resolveQueueSelection(id, paths) {
36310
36580
  }
36311
36581
  async function showQueue(id, paths) {
36312
36582
  const selection = await resolveQueueSelection(id, paths);
36313
- const queueDir = path93__default.join(paths.queueDir, selection.id);
36314
- const patch = await parsePatch(await readPatchFile(path93__default.join(queueDir, PATCH_FILENAME)));
36315
- const meta3 = await readJsonFile2(path93__default.join(queueDir, PATCH_META_FILENAME));
36583
+ const queueDir = path92__default.join(paths.queueDir, selection.id);
36584
+ const patch = await parsePatch(await readPatchFile(path92__default.join(queueDir, PATCH_FILENAME)));
36585
+ const meta3 = await readJsonFile2(path92__default.join(queueDir, PATCH_META_FILENAME));
36316
36586
  return { patch, meta: meta3 };
36317
36587
  }
36318
36588
  async function rewriteQueuedPatch(id, paths, patch, meta3, expectedPatchHash) {
36319
36589
  assertSafeQueueId(id);
36320
36590
  return withPatchEditLock(paths, id, async () => {
36321
- const queueDir = path93__default.join(paths.queueDir, id);
36591
+ const queueDir = path92__default.join(paths.queueDir, id);
36322
36592
  if (expectedPatchHash !== void 0) {
36323
- const currentMarkdown = await readPatchFile(path93__default.join(queueDir, PATCH_FILENAME));
36593
+ const currentMarkdown = await readPatchFile(path92__default.join(queueDir, PATCH_FILENAME));
36324
36594
  const currentHash = computeContentHash(currentMarkdown);
36325
36595
  if (currentHash !== expectedPatchHash) {
36326
36596
  throw new Error(`[fleet-wiki] wiki_patch_edit stale base_patch_hash: expected ${currentHash}, got ${expectedPatchHash}`);
@@ -36329,8 +36599,8 @@ async function rewriteQueuedPatch(id, paths, patch, meta3, expectedPatchHash) {
36329
36599
  const patchMarkdown = serializePatch(patch);
36330
36600
  const patchHash = computeContentHash(patchMarkdown);
36331
36601
  const nextMeta = { ...meta3, lastEditHash: patchHash };
36332
- await writePatchFile(path93__default.join(queueDir, PATCH_FILENAME), patchMarkdown, paths);
36333
- await writeJsonFile(path93__default.join(queueDir, PATCH_META_FILENAME), nextMeta, paths);
36602
+ await writePatchFile(path92__default.join(queueDir, PATCH_FILENAME), patchMarkdown, paths);
36603
+ await writeJsonFile(path92__default.join(queueDir, PATCH_META_FILENAME), nextMeta, paths);
36334
36604
  return patchHash;
36335
36605
  });
36336
36606
  }
@@ -36354,8 +36624,8 @@ async function approvePatch(id, paths) {
36354
36624
  rawSourceRef: meta3.rawSourceRef,
36355
36625
  warnings: meta3.warnings
36356
36626
  });
36357
- const queueDir = path93__default.join(paths.queueDir, id);
36358
- await writeJsonFile(path93__default.join(queueDir, PATCH_META_FILENAME), {
36627
+ const queueDir = path92__default.join(paths.queueDir, id);
36628
+ await writeJsonFile(path92__default.join(queueDir, PATCH_META_FILENAME), {
36359
36629
  ...meta3,
36360
36630
  conflictId
36361
36631
  }, paths);
@@ -36391,7 +36661,7 @@ async function approvePatchSet(patchSetId, paths) {
36391
36661
  const failed = [];
36392
36662
  const missing = [];
36393
36663
  for (const patchId of patchSet.patchIds) {
36394
- const queueDir = path93__default.join(paths.queueDir, patchId);
36664
+ const queueDir = path92__default.join(paths.queueDir, patchId);
36395
36665
  if (!await pathExists(queueDir)) {
36396
36666
  missing.push(patchId);
36397
36667
  continue;
@@ -36457,7 +36727,7 @@ ${patch.body}`;
36457
36727
  }
36458
36728
  async function normalizeWikiEntryPatch(entry, target, paths) {
36459
36729
  assertSafeEntryId(entry.id);
36460
- if (entry.id !== path93__default.basename(target, ".md")) {
36730
+ if (entry.id !== path92__default.basename(target, ".md")) {
36461
36731
  throw new Error("wiki patch body id must match target filename");
36462
36732
  }
36463
36733
  const inlineRawSourceRef = extractInlineRawSourceRef(entry.body);
@@ -36500,9 +36770,9 @@ function buildPatchId(createdAt, summary, target, body) {
36500
36770
  }
36501
36771
  async function validatePatchBase(patch, meta3, paths) {
36502
36772
  if (patch.frontmatter.op !== "update_wiki" || !meta3?.baseVersion && !meta3?.baseHash) return;
36503
- const wikiId = path93__default.basename(patch.frontmatter.target, ".md");
36773
+ const wikiId = path92__default.basename(patch.frontmatter.target, ".md");
36504
36774
  const currentEntry = await readWikiEntry(wikiId, paths);
36505
- const currentPath = path93__default.join(paths.root, patch.frontmatter.target);
36775
+ const currentPath = path92__default.join(paths.root, patch.frontmatter.target);
36506
36776
  const currentMarkdown = await pathExists(currentPath) ? await readPatchFile(currentPath) : void 0;
36507
36777
  if (meta3.baseVersion !== void 0 && currentEntry?.version !== meta3.baseVersion) {
36508
36778
  throw new Error(
@@ -36561,17 +36831,17 @@ function assertCanonicalPatchTarget(target) {
36561
36831
  if (target.endsWith("/")) {
36562
36832
  throw new Error("patch target must not end with a slash");
36563
36833
  }
36564
- if (target.startsWith("/") || path93__default.posix.isAbsolute(target) || path93__default.win32.isAbsolute(target)) {
36834
+ if (target.startsWith("/") || path92__default.posix.isAbsolute(target) || path92__default.win32.isAbsolute(target)) {
36565
36835
  throw new Error("patch target must be relative");
36566
36836
  }
36567
- if (path93__default.posix.normalize(target) !== target) {
36837
+ if (path92__default.posix.normalize(target) !== target) {
36568
36838
  throw new Error("patch target must not contain dot segments or redundant separators");
36569
36839
  }
36570
36840
  }
36571
36841
  function canonicalApprovalLockKey(paths, target) {
36572
36842
  const wikiRoot = realpathSync(paths.wikiDir);
36573
- const relativeTarget = path93__default.posix.relative("wiki", target);
36574
- const targetPath = path93__default.join(wikiRoot, ...relativeTarget.split("/"));
36843
+ const relativeTarget = path92__default.posix.relative("wiki", target);
36844
+ const targetPath = path92__default.join(wikiRoot, ...relativeTarget.split("/"));
36575
36845
  return `${wikiRoot}\0${targetPath}`.toLowerCase();
36576
36846
  }
36577
36847
  function canonicalPatchEditLockKey(paths, patchId) {
@@ -36587,7 +36857,7 @@ function assertNoSymlinkPathComponents(target, paths) {
36587
36857
  throw error51;
36588
36858
  }
36589
36859
  for (const part of parts) {
36590
- current = path93__default.join(current, part);
36860
+ current = path92__default.join(current, part);
36591
36861
  try {
36592
36862
  if (lstatSync(current).isSymbolicLink()) {
36593
36863
  throw new Error("patch target must not include symlink path components");
@@ -36602,8 +36872,8 @@ function assertSafeRawSourceRef(rawSourceRef, paths) {
36602
36872
  if (!rawSourceRef.startsWith("raw/")) {
36603
36873
  throw new Error("raw source provenance must point into raw/");
36604
36874
  }
36605
- const absoluteRef = path93__default.resolve(paths.root, rawSourceRef);
36606
- if (!absoluteRef.startsWith(`${paths.rawDir}${path93__default.sep}`)) {
36875
+ const absoluteRef = path92__default.resolve(paths.root, rawSourceRef);
36876
+ if (!absoluteRef.startsWith(`${paths.rawDir}${path92__default.sep}`)) {
36607
36877
  throw new Error("raw source provenance must point into raw/");
36608
36878
  }
36609
36879
  }
@@ -36619,14 +36889,14 @@ function classifyPatchConflict(error51) {
36619
36889
  }
36620
36890
  async function recordPatchConflict(patch, paths, reason, options) {
36621
36891
  const now = /* @__PURE__ */ new Date();
36622
- const targetPath = path93__default.join(paths.root, patch.frontmatter.target);
36892
+ const targetPath = path92__default.join(paths.root, patch.frontmatter.target);
36623
36893
  const current = await pathExists(targetPath) ? await readPatchFile(targetPath) : void 0;
36624
36894
  const currentEntry = current ? parseStoredWikiEntry(current) : void 0;
36625
36895
  const proposedEntry = parsePatchBodyEntry(patch.body);
36626
36896
  const record2 = await createConflict({
36627
36897
  reason,
36628
36898
  target: patch.frontmatter.target,
36629
- wikiId: proposedEntry?.id ?? path93__default.basename(patch.frontmatter.target, ".md"),
36899
+ wikiId: proposedEntry?.id ?? path92__default.basename(patch.frontmatter.target, ".md"),
36630
36900
  title: proposedEntry?.title,
36631
36901
  proposer: patch.frontmatter.proposer,
36632
36902
  rawSourceRef: options?.rawSourceRef,
@@ -36722,11 +36992,11 @@ function parseInlineArray(value) {
36722
36992
  return inner.split(",").map((item) => item.trim().replace(/^"(.*)"$/, "$1"));
36723
36993
  }
36724
36994
  async function archiveQueueEntry(id, paths, meta3) {
36725
- const fromDir = path93__default.join(paths.queueDir, id);
36726
- const toDir = path93__default.join(paths.archiveDir, id);
36995
+ const fromDir = path92__default.join(paths.queueDir, id);
36996
+ const toDir = path92__default.join(paths.archiveDir, id);
36727
36997
  await removePath(toDir);
36728
36998
  await movePath(fromDir, toDir);
36729
- await writeJsonFile(path93__default.join(toDir, PATCH_META_FILENAME), meta3, paths);
36999
+ await writeJsonFile(path92__default.join(toDir, PATCH_META_FILENAME), meta3, paths);
36730
37000
  }
36731
37001
  function buildQueueIdHelp(prefix, availableIds) {
36732
37002
  if (availableIds.length === 0) {
@@ -36934,7 +37204,7 @@ async function resolveCompileSource(input, paths, now) {
36934
37204
  }
36935
37205
  async function buildCompileProposals(input, paths, now, resolvedSource) {
36936
37206
  const sourceTarget = `wiki/sources/${resolvedSource.sourcePageId}.md`;
36937
- const sourceExists = await pathExists(path93__default.join(paths.root, sourceTarget));
37207
+ const sourceExists = await pathExists(path92__default.join(paths.root, sourceTarget));
36938
37208
  const existingEntries = await listWiki(paths);
36939
37209
  const sourcePageTitle = resolvedSource.sourceTitle?.trim() || `Source ${resolvedSource.sourcePageId}`;
36940
37210
  const existingSourceEntry = existingEntries.find((entry) => entry.id === resolvedSource.sourcePageId);
@@ -36956,7 +37226,7 @@ async function buildCompileProposals(input, paths, now, resolvedSource) {
36956
37226
  target: sourceTarget,
36957
37227
  summary: truncateSummary(`Compile source page ${sourcePageTitle}`),
36958
37228
  entry: sourceEntry,
36959
- baseHash: sourceExists ? computeContentHash(await readPatchFile(path93__default.join(paths.root, sourceTarget))) : void 0,
37229
+ baseHash: sourceExists ? computeContentHash(await readPatchFile(path92__default.join(paths.root, sourceTarget))) : void 0,
36960
37230
  baseVersion: existingSourceEntry?.version
36961
37231
  }];
36962
37232
  const relatedCandidates = await discoverRelatedEntryCandidates(paths, resolvedSource.sourceContent, resolvedSource.sourceTitle);
@@ -36976,7 +37246,7 @@ async function buildCompileProposals(input, paths, now, resolvedSource) {
36976
37246
  rawSourceRefs: mergeRawSourceRefs(existing.rawSourceRefs, existing.rawSourceRef, { ref: resolvedSource.rawSourceRef }),
36977
37247
  body: appendSourceCompileNote(existing.body, resolvedSource.sourcePageId, resolvedSource.rawSourceRef)
36978
37248
  },
36979
- baseHash: computeContentHash(await readPatchFile(path93__default.join(paths.wikiDir, `${existing.id}.md`))),
37249
+ baseHash: computeContentHash(await readPatchFile(path92__default.join(paths.wikiDir, `${existing.id}.md`))),
36980
37250
  baseVersion: existing.version
36981
37251
  });
36982
37252
  }
@@ -37111,13 +37381,13 @@ async function readClaims(entryId, paths) {
37111
37381
  }
37112
37382
  }
37113
37383
  function getClaimsDir(paths) {
37114
- return path93__default.join(paths.wikiDir, CLAIMS_DIRNAME);
37384
+ return path92__default.join(paths.wikiDir, CLAIMS_DIRNAME);
37115
37385
  }
37116
37386
  function getClaimsFile(paths, entryId) {
37117
37387
  assertSafeEntryId(entryId);
37118
- const claimsFile = path93__default.join(getClaimsDir(paths), `${entryId}.json`);
37119
- const relative = path93__default.relative(getClaimsDir(paths), claimsFile);
37120
- if (!relative || relative.startsWith("..") || path93__default.isAbsolute(relative)) {
37388
+ const claimsFile = path92__default.join(getClaimsDir(paths), `${entryId}.json`);
37389
+ const relative = path92__default.relative(getClaimsDir(paths), claimsFile);
37390
+ if (!relative || relative.startsWith("..") || path92__default.isAbsolute(relative)) {
37121
37391
  throw new Error(`[fleet-wiki] claims sidecar escapes wiki/.claims: ${entryId}`);
37122
37392
  }
37123
37393
  return claimsFile;
@@ -37208,7 +37478,7 @@ function assertSafeClaimRawRef(ref) {
37208
37478
  if (!ref.startsWith("raw/")) {
37209
37479
  throw new Error(`claim sourceRef must point into raw/: ${ref}`);
37210
37480
  }
37211
- if (ref.includes("..") || path93__default.isAbsolute(ref)) {
37481
+ if (ref.includes("..") || path92__default.isAbsolute(ref)) {
37212
37482
  throw new Error(`claim sourceRef escapes raw/: ${ref}`);
37213
37483
  }
37214
37484
  }
@@ -37284,22 +37554,22 @@ async function runDryDock(paths, options = {}) {
37284
37554
  }
37285
37555
  for (const fileName of await listFileNames(paths.rawDir)) {
37286
37556
  if (!fileName.endsWith(".md")) continue;
37287
- const filePath = path93__default.join(paths.rawDir, fileName);
37557
+ const filePath = path92__default.join(paths.rawDir, fileName);
37288
37558
  issues.push(...safetyIssues(await readPatchFile(filePath), filePath));
37289
37559
  }
37290
37560
  for (const queueId of await listDirectoryNames(paths.queueDir)) {
37291
37561
  if (queueId === PATCH_SET_DIRNAME) continue;
37292
- const queueDir = path93__default.join(paths.queueDir, queueId);
37562
+ const queueDir = path92__default.join(paths.queueDir, queueId);
37293
37563
  try {
37294
- const patchContent = await readPatchFile(path93__default.join(queueDir, PATCH_FILENAME));
37295
- issues.push(...safetyIssues(patchContent, path93__default.join(queueDir, PATCH_FILENAME)));
37296
- await readJsonFile2(path93__default.join(queueDir, PATCH_META_FILENAME));
37564
+ const patchContent = await readPatchFile(path92__default.join(queueDir, PATCH_FILENAME));
37565
+ issues.push(...safetyIssues(patchContent, path92__default.join(queueDir, PATCH_FILENAME)));
37566
+ await readJsonFile2(path92__default.join(queueDir, PATCH_META_FILENAME));
37297
37567
  } catch {
37298
37568
  issues.push(issue2("malformed_queue", "error", "\uC190\uC0C1\uB41C queue \uC5D4\uD2B8\uB9AC", queueDir));
37299
37569
  }
37300
37570
  }
37301
- for (const patchSetId of await listDirectoryNames(path93__default.join(paths.queueDir, PATCH_SET_DIRNAME))) {
37302
- const patchSetMetaFile = path93__default.join(paths.queueDir, PATCH_SET_DIRNAME, patchSetId, PATCH_META_FILENAME);
37571
+ for (const patchSetId of await listDirectoryNames(path92__default.join(paths.queueDir, PATCH_SET_DIRNAME))) {
37572
+ const patchSetMetaFile = path92__default.join(paths.queueDir, PATCH_SET_DIRNAME, patchSetId, PATCH_META_FILENAME);
37303
37573
  let patchSet;
37304
37574
  try {
37305
37575
  patchSet = await readPatchSet(paths, patchSetId);
@@ -37308,8 +37578,8 @@ async function runDryDock(paths, options = {}) {
37308
37578
  continue;
37309
37579
  }
37310
37580
  for (const patchId of patchSet.patchIds) {
37311
- const queueMetaFile = path93__default.join(paths.queueDir, patchId, PATCH_META_FILENAME);
37312
- const archiveMetaFile = path93__default.join(paths.archiveDir, patchId, PATCH_META_FILENAME);
37581
+ const queueMetaFile = path92__default.join(paths.queueDir, patchId, PATCH_META_FILENAME);
37582
+ const archiveMetaFile = path92__default.join(paths.archiveDir, patchId, PATCH_META_FILENAME);
37313
37583
  if (!await pathExists(queueMetaFile) && !await pathExists(archiveMetaFile)) {
37314
37584
  issues.push(
37315
37585
  issue2(
@@ -37346,7 +37616,7 @@ async function runDryDock(paths, options = {}) {
37346
37616
  "conflict_unresolved",
37347
37617
  "warning",
37348
37618
  `\uBBF8\uD574\uACB0 conflict: ${conflict.reason} (${conflict.target})`,
37349
- path93__default.join(paths.conflictsDir, conflict.id, "meta.json")
37619
+ path92__default.join(paths.conflictsDir, conflict.id, "meta.json")
37350
37620
  )
37351
37621
  );
37352
37622
  }
@@ -37359,7 +37629,7 @@ async function runDryDock(paths, options = {}) {
37359
37629
  "unresolved_conflict",
37360
37630
  "warning",
37361
37631
  "\uC190\uC0C1\uB41C conflict \uC5D4\uD2B8\uB9AC",
37362
- path93__default.join(paths.conflictsDir, conflictId, "meta.json")
37632
+ path92__default.join(paths.conflictsDir, conflictId, "meta.json")
37363
37633
  )
37364
37634
  );
37365
37635
  }
@@ -37416,8 +37686,8 @@ async function claimIssues(paths, wikiIds) {
37416
37686
  const claimsDir = getClaimsDir(paths);
37417
37687
  for (const fileName of await listFileNames(claimsDir)) {
37418
37688
  if (!fileName.endsWith(".json")) continue;
37419
- const filePath = path93__default.join(claimsDir, fileName);
37420
- const entryIdFromFile = path93__default.basename(fileName, ".json");
37689
+ const filePath = path92__default.join(claimsDir, fileName);
37690
+ const entryIdFromFile = path92__default.basename(fileName, ".json");
37421
37691
  let raw;
37422
37692
  try {
37423
37693
  raw = await readJsonFile2(filePath);
@@ -37496,7 +37766,7 @@ function toSemanticEntry(filePath, frontmatter, body) {
37496
37766
  async function schemaIssues(paths) {
37497
37767
  const issues = [];
37498
37768
  const schema = await readWorkspaceSchemaSummary(paths);
37499
- const agentsPath = path93__default.join(paths.schemaDir, WORKSPACE_SCHEMA_AGENTS_FILENAME);
37769
+ const agentsPath = path92__default.join(paths.schemaDir, WORKSPACE_SCHEMA_AGENTS_FILENAME);
37500
37770
  if (!await pathExists(schema.wikiSchemaPath)) {
37501
37771
  issues.push(issue2("schema_missing", "warning", `Workspace schema file is missing: schema/${WORKSPACE_SCHEMA_FILENAME}`, schema.wikiSchemaPath));
37502
37772
  } else {
@@ -37816,7 +38086,7 @@ function parseOptionalIsoDate(value) {
37816
38086
  return Number.isFinite(timestamp) ? timestamp : null;
37817
38087
  }
37818
38088
  function hashBodyForComparison(body) {
37819
- return crypto4.createHash("sha256").update(body.replace(/\s+/g, " ").trim(), "utf8").digest("hex").slice(0, 8);
38089
+ return crypto3.createHash("sha256").update(body.replace(/\s+/g, " ").trim(), "utf8").digest("hex").slice(0, 8);
37820
38090
  }
37821
38091
  function hasConflictingStatuses(entries) {
37822
38092
  const statuses = new Set(entries.map((entry) => entry.status).filter((status) => status !== "unknown"));
@@ -37883,7 +38153,7 @@ async function listWikiMarkdownFiles(dirPath) {
37883
38153
  const files = [];
37884
38154
  const sortedEntries = entries.sort((left, right) => left.name.localeCompare(right.name));
37885
38155
  for (const entry of sortedEntries) {
37886
- const filePath = path93__default.join(dirPath, entry.name);
38156
+ const filePath = path92__default.join(dirPath, entry.name);
37887
38157
  if (entry.isDirectory()) {
37888
38158
  files.push(...await listWikiMarkdownFiles(filePath));
37889
38159
  continue;
@@ -37965,7 +38235,7 @@ async function planIngest(input, paths, now) {
37965
38235
  const target = `wiki/${input.id}.md`;
37966
38236
  const proposer = input.proposer ?? "tool:wiki_ingest";
37967
38237
  const currentEntry = await readWikiEntry(input.id, paths);
37968
- const currentMarkdown = currentEntry ? await readPatchFile(path93__default.join(paths.wikiDir, `${input.id}.md`)) : void 0;
38238
+ const currentMarkdown = currentEntry ? await readPatchFile(path92__default.join(paths.wikiDir, `${input.id}.md`)) : void 0;
37969
38239
  const currentHash = currentMarkdown ? computeContentHash(currentMarkdown) : void 0;
37970
38240
  const rawSource = buildRawSourceEntry(input, now);
37971
38241
  await ensureWorkspaceSchema(paths);
@@ -38644,11 +38914,11 @@ async function editQueuedPatch(input, paths) {
38644
38914
  };
38645
38915
  }
38646
38916
  async function readQueuedPatchSnapshot(paths, patchId) {
38647
- const queueDir = path93__default.join(paths.queueDir, patchId);
38648
- const markdown = await readPatchFile(path93__default.join(queueDir, PATCH_FILENAME));
38917
+ const queueDir = path92__default.join(paths.queueDir, patchId);
38918
+ const markdown = await readPatchFile(path92__default.join(queueDir, PATCH_FILENAME));
38649
38919
  return {
38650
38920
  patch: await parsePatch(markdown),
38651
- meta: await readJsonFile2(path93__default.join(queueDir, PATCH_META_FILENAME)),
38921
+ meta: await readJsonFile2(path92__default.join(queueDir, PATCH_META_FILENAME)),
38652
38922
  patchHash: computeContentHash(markdown)
38653
38923
  };
38654
38924
  }
@@ -39404,7 +39674,7 @@ ${input.answer ?? ""}`)}`;
39404
39674
  assertSafeEntryId(targetId);
39405
39675
  const subdir = input.targetType === "synthesis" ? "synthesis" : "queries";
39406
39676
  const target = `wiki/${subdir}/${targetId}.md`;
39407
- const absoluteTarget = path93__default.join(paths.root, target);
39677
+ const absoluteTarget = path92__default.join(paths.root, target);
39408
39678
  const exists = await pathExists(absoluteTarget);
39409
39679
  const existingEntry = exists ? await readWikiEntry(targetId, paths) : null;
39410
39680
  if (exists && !existingEntry) {
@@ -39486,7 +39756,7 @@ function assertSafeRawRef(rawRef) {
39486
39756
  if (!rawRef.startsWith("raw/")) {
39487
39757
  throw new Error(`[fleet-wiki] wiki_query raw source ref must point into raw/: ${rawRef}`);
39488
39758
  }
39489
- if (rawRef.includes("..") || path93__default.isAbsolute(rawRef)) {
39759
+ if (rawRef.includes("..") || path92__default.isAbsolute(rawRef)) {
39490
39760
  throw new Error(`[fleet-wiki] wiki_query raw source ref escapes raw/: ${rawRef}`);
39491
39761
  }
39492
39762
  }
@@ -39605,7 +39875,7 @@ async function buildReadEntryResult(entry, paths, graph, input) {
39605
39875
  rawSourceRef: entry.rawSourceRef,
39606
39876
  rawSourceRefs,
39607
39877
  source: {
39608
- path: path93__default.join("wiki", `${entry.id}.md`),
39878
+ path: path92__default.join("wiki", `${entry.id}.md`),
39609
39879
  rawSourceRef: entry.rawSourceRef,
39610
39880
  rawSourceRefs
39611
39881
  },
@@ -39731,7 +40001,7 @@ function buildRelatedEntries(entry, graph) {
39731
40001
  deduped.set(candidate.id, {
39732
40002
  id: relatedEntry.id,
39733
40003
  title: relatedEntry.title,
39734
- path: path93__default.join("wiki", `${relatedEntry.id}.md`),
40004
+ path: path92__default.join("wiki", `${relatedEntry.id}.md`),
39735
40005
  reason: candidate.reason
39736
40006
  });
39737
40007
  }
@@ -40000,7 +40270,7 @@ function buildWikiToolSpec(config2, usage) {
40000
40270
  }
40001
40271
 
40002
40272
  // src/carrier-settings-routes.ts
40003
- var SUBAGENT_CLI_TYPES = /* @__PURE__ */ new Set(["claude", "claude-zai", "claude-kimi"]);
40273
+ var SUBAGENT_CLI_TYPES = /* @__PURE__ */ new Set(["claude", "claude-zai", "claude-kimi", "claude-glm"]);
40004
40274
  var TASKFORCE_MIN_BACKENDS = 2;
40005
40275
  function createCarrierSettingsRouter(deps) {
40006
40276
  const controller = createStatusOverlayController(deps.registry);
@@ -40440,13 +40710,13 @@ function safeEqual(left, right) {
40440
40710
  return timingSafeEqual(leftBytes, rightBytes);
40441
40711
  }
40442
40712
  function workspaceHash(canonicalCwd) {
40443
- return crypto4.createHash("sha256").update(canonicalCwd).digest("hex").slice(0, 12);
40713
+ return crypto3.createHash("sha256").update(canonicalCwd).digest("hex").slice(0, 12);
40444
40714
  }
40445
40715
  async function canonicalizeTheaterPath(cwd) {
40446
40716
  return canonicalizeTheaterPathSync(cwd);
40447
40717
  }
40448
40718
  function canonicalizeTheaterPathSync(cwd) {
40449
- const resolved = path93__default.resolve(cwd);
40719
+ const resolved = path92__default.resolve(cwd);
40450
40720
  try {
40451
40721
  return fs7__default.realpathSync.native(resolved);
40452
40722
  } catch {
@@ -40454,7 +40724,7 @@ function canonicalizeTheaterPathSync(cwd) {
40454
40724
  }
40455
40725
  }
40456
40726
  function theaterLabel(cwd) {
40457
- return path93__default.basename(cwd) || cwd;
40727
+ return path92__default.basename(cwd) || cwd;
40458
40728
  }
40459
40729
 
40460
40730
  // src/codex/workspaces.ts
@@ -40462,7 +40732,7 @@ var WorkspaceRegistry = class {
40462
40732
  #items = /* @__PURE__ */ new Map();
40463
40733
  #mruId = null;
40464
40734
  async register(cwdInput, lastOpenedAt) {
40465
- const cwd = path93__default.resolve(cwdInput);
40735
+ const cwd = path92__default.resolve(cwdInput);
40466
40736
  const real = await canonicalizeTheaterPath(cwd);
40467
40737
  const paths = resolveMemoryPaths(real);
40468
40738
  if (!await directoryExists(paths.root)) {
@@ -40478,7 +40748,7 @@ var WorkspaceRegistry = class {
40478
40748
  id,
40479
40749
  cwd,
40480
40750
  realpath: real,
40481
- label: path93__default.basename(cwd),
40751
+ label: path92__default.basename(cwd),
40482
40752
  paths,
40483
40753
  registeredAt: existing?.registeredAt ?? now,
40484
40754
  // 복원 경로는 durable lastOpenedAt을 그대로 보존해 재시작 후에도 워크스페이스 최근성
@@ -41281,7 +41551,7 @@ function statusRank(status) {
41281
41551
 
41282
41552
  // src/security-headers.ts
41283
41553
  var CONSOLE_SECURITY_HEADERS = {
41284
- "Content-Security-Policy": "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:; connect-src 'self' ws: wss:; object-src 'none'; base-uri 'none'",
41554
+ "Content-Security-Policy": "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:; connect-src 'self' ws: wss: https://api.github.com; object-src 'none'; base-uri 'none'",
41285
41555
  "X-Content-Type-Options": "nosniff",
41286
41556
  "Referrer-Policy": "no-referrer",
41287
41557
  "Cache-Control": "no-store"
@@ -41533,7 +41803,7 @@ function createConsoleDurableStateStore(deps = {}) {
41533
41803
  const createStore = deps.createStore ?? createDurableJsonStore;
41534
41804
  return createStore({
41535
41805
  filePath: paths.stateFile,
41536
- lockDir: path93__default.join(paths.dir, STATE_LOCK_DIR_NAME),
41806
+ lockDir: path92__default.join(paths.dir, STATE_LOCK_DIR_NAME),
41537
41807
  lockOwnerFileName: STATE_LOCK_OWNER_FILE_NAME,
41538
41808
  now: deps.now,
41539
41809
  sanitize: sanitizeDurableConsoleState,
@@ -41555,7 +41825,7 @@ function emptyDurableConsoleState() {
41555
41825
  function readProviderSessionCapture(fleetSessionId, deps = {}) {
41556
41826
  if (!isSafeCaptureId(fleetSessionId)) return null;
41557
41827
  const capturesDir = deps.capturesDir ?? createConsoleDataPaths().capturesDir;
41558
- const filePath = path93__default.join(capturesDir, `${fleetSessionId}.json`);
41828
+ const filePath = path92__default.join(capturesDir, `${fleetSessionId}.json`);
41559
41829
  try {
41560
41830
  const parsed = JSON.parse(fs7__default.readFileSync(filePath, "utf8"));
41561
41831
  return sanitizeProviderSession(parsed);
@@ -41578,7 +41848,7 @@ function unlinkProviderSessionCapture(fleetSessionId, deps = {}) {
41578
41848
  if (!isSafeCaptureId(fleetSessionId)) return false;
41579
41849
  const capturesDir = deps.capturesDir ?? createConsoleDataPaths().capturesDir;
41580
41850
  try {
41581
- fs7__default.unlinkSync(path93__default.join(capturesDir, `${fleetSessionId}.json`));
41851
+ fs7__default.unlinkSync(path92__default.join(capturesDir, `${fleetSessionId}.json`));
41582
41852
  return true;
41583
41853
  } catch {
41584
41854
  return false;
@@ -41627,6 +41897,9 @@ function sanitizeDurableOperation(value) {
41627
41897
  const sequence = readPositiveInteger(value.sequence);
41628
41898
  const createdAt = readFiniteNumber(value.createdAt);
41629
41899
  if (!sessionId || !theaterId || !cwd || !cwdLabel || sequence === null || createdAt === null) return null;
41900
+ const label = readOptionalString(value.label);
41901
+ const labelSource = readLabelSource(value.labelSource);
41902
+ const autoNamePromptSeen = value.autoNamePromptSeen === true || labelSource === "auto" && label !== void 0;
41630
41903
  const providerSession = sanitizeProviderSession(value.providerSession);
41631
41904
  return {
41632
41905
  sessionId,
@@ -41634,7 +41907,9 @@ function sanitizeDurableOperation(value) {
41634
41907
  cwd,
41635
41908
  cwdLabel,
41636
41909
  sequence,
41637
- ...readOptionalString(value.label) ? { label: readOptionalString(value.label) } : {},
41910
+ ...label ? { label } : {},
41911
+ ...labelSource ? { labelSource } : {},
41912
+ ...autoNamePromptSeen ? { autoNamePromptSeen: true } : {},
41638
41913
  ...readOptionalString(value.cliId) ? { cliId: readOptionalString(value.cliId) } : {},
41639
41914
  ...readOptionalString(value.cliLabel) ? { cliLabel: readOptionalString(value.cliLabel) } : {},
41640
41915
  createdAt,
@@ -41659,7 +41934,7 @@ function isRecord4(value) {
41659
41934
  return typeof value === "object" && value !== null && !Array.isArray(value);
41660
41935
  }
41661
41936
  function isSafeCaptureId(value) {
41662
- return value.length > 0 && path93__default.basename(value) === value && !value.includes(path93__default.sep) && !value.includes(path93__default.posix.sep);
41937
+ return value.length > 0 && path92__default.basename(value) === value && !value.includes(path92__default.sep) && !value.includes(path92__default.posix.sep);
41663
41938
  }
41664
41939
  function readNonEmptyString(value) {
41665
41940
  return typeof value === "string" && value.length > 0 ? value : null;
@@ -41667,6 +41942,9 @@ function readNonEmptyString(value) {
41667
41942
  function readOptionalString(value) {
41668
41943
  return typeof value === "string" && value.length > 0 ? value : void 0;
41669
41944
  }
41945
+ function readLabelSource(value) {
41946
+ return value === "user" || value === "auto" ? value : void 0;
41947
+ }
41670
41948
  function readPositiveInteger(value) {
41671
41949
  return typeof value === "number" && Number.isInteger(value) && value > 0 ? value : null;
41672
41950
  }
@@ -41674,6 +41952,69 @@ function readFiniteNumber(value) {
41674
41952
  return typeof value === "number" && Number.isFinite(value) ? value : null;
41675
41953
  }
41676
41954
 
41955
+ // src/auto-name.ts
41956
+ var MAX_LABEL_LENGTH = 60;
41957
+ var MIN_LABEL_LENGTH = 4;
41958
+ var MAX_SCAN_LINES = 6;
41959
+ var SECRET_MIN_TOKEN_LENGTH = 24;
41960
+ var CODE_FENCE_PATTERN = /^(```|~~~)/;
41961
+ var MARKER_PREFIX_PATTERN = /^([>#]+|[-*+]|\d+[.)])\s+/;
41962
+ var WRAPPER_TRIM_PATTERN = /^[*_`~]+|[*_`~]+$/g;
41963
+ var CONTROL_CHAR_PATTERN2 = new RegExp("[\\u0000-\\u001F\\u007F]", "g");
41964
+ var WHITESPACE_RUN_PATTERN = /\s+/g;
41965
+ var TRAILING_PUNCT_PATTERN = /[.,;:!?)\]}'"]+$/;
41966
+ var URL_PATTERN = /(https?:\/\/|ftp:\/\/|www\.)/i;
41967
+ var PATH_PATTERN = /(^|\s)(\/[^\s/]|~\/|\.{1,2}\/|[a-zA-Z]:[\\/])/;
41968
+ var LOW_SIGNAL_PATTERN = /^(continue|계속|진행|다음|next|ok|okay|go|run|yes|yep|sure|y|n|no|네|응|예|그래|stop|wait|hold on|fix it|do it|please|thanks?|thank you)$/i;
41969
+ var SECRET_PREFIX_PATTERN = /^(ghp_|gho_|ghs_|ghu_|ghr_|github_pat_|sk-|sk_live_|sk_test_|pk-|rk-|xox[baprs]-|AKIA|ASIA|AIza|ya29\.|glpat-|eyJ)/;
41970
+ var SECRET_CHARSET_PATTERN = /^[A-Za-z0-9_\-+/=.]+$/;
41971
+ function deriveOperationLabel(prompt) {
41972
+ if (typeof prompt !== "string" || prompt.length === 0) return null;
41973
+ const lines = prompt.split(/\r?\n/);
41974
+ let examined = 0;
41975
+ let inFence = false;
41976
+ for (const rawLine of lines) {
41977
+ const trimmed = rawLine.trim();
41978
+ if (trimmed.length === 0) continue;
41979
+ if (CODE_FENCE_PATTERN.test(trimmed)) {
41980
+ inFence = !inFence;
41981
+ continue;
41982
+ }
41983
+ if (inFence) continue;
41984
+ examined += 1;
41985
+ if (examined > MAX_SCAN_LINES) break;
41986
+ const candidate = normalizeLine(trimmed);
41987
+ if (candidate !== null) return candidate;
41988
+ }
41989
+ return null;
41990
+ }
41991
+ function normalizeLine(line) {
41992
+ let value = line.replace(CONTROL_CHAR_PATTERN2, " ").replace(WHITESPACE_RUN_PATTERN, " ").trim();
41993
+ for (let depth = 0; depth < 4; depth += 1) {
41994
+ const before = value;
41995
+ value = value.replace(MARKER_PREFIX_PATTERN, "").trim();
41996
+ value = value.replace(WRAPPER_TRIM_PATTERN, "").trim();
41997
+ if (value === before) break;
41998
+ }
41999
+ if (value.length === 0) return null;
42000
+ if (value.startsWith("/")) return null;
42001
+ if (URL_PATTERN.test(value)) return null;
42002
+ if (PATH_PATTERN.test(value)) return null;
42003
+ if (hasSecretToken(value)) return null;
42004
+ if (LOW_SIGNAL_PATTERN.test(value)) return null;
42005
+ if (value.length < MIN_LABEL_LENGTH) return null;
42006
+ return value.length > MAX_LABEL_LENGTH ? value.slice(0, MAX_LABEL_LENGTH).trimEnd() : value;
42007
+ }
42008
+ function hasSecretToken(value) {
42009
+ return value.split(/\s+/).some(looksSecretToken);
42010
+ }
42011
+ function looksSecretToken(rawToken) {
42012
+ const token = rawToken.replace(TRAILING_PUNCT_PATTERN, "");
42013
+ if (token.length === 0) return false;
42014
+ if (SECRET_PREFIX_PATTERN.test(token)) return true;
42015
+ return token.length >= SECRET_MIN_TOKEN_LENGTH && SECRET_CHARSET_PATTERN.test(token) && /[0-9]/.test(token) && /[A-Za-z]/.test(token);
42016
+ }
42017
+
41677
42018
  // src/global-settings-routes.ts
41678
42019
  function createGlobalSettingsRouter(deps) {
41679
42020
  return async function handleGlobalSettingsRoute(context) {
@@ -41740,6 +42081,259 @@ function isJsonRequest3(req) {
41740
42081
  const contentType = req.headers["content-type"];
41741
42082
  return typeof contentType === "string" && contentType.toLowerCase().split(";")[0]?.trim() === "application/json";
41742
42083
  }
42084
+ var BINARY_DISPLAY_NAMES = {
42085
+ claude: "Claude Code",
42086
+ codex: "Codex CLI",
42087
+ opencode: "OpenCode",
42088
+ "cursor-agent": "Cursor Agent"
42089
+ };
42090
+ var OVERRIDE_ENV_BY_COMMAND = {
42091
+ claude: "CLAUDE_BIN",
42092
+ codex: "CODEX_BIN"
42093
+ };
42094
+ var VERSION_PROBE_TIMEOUT_MS = 5e3;
42095
+ var SEMVER_PATTERN = /(\d+\.\d+\.\d+)/;
42096
+ function createAgentCliDetector(deps) {
42097
+ return {
42098
+ detect: async () => {
42099
+ const commands = distinctBinaryCommands();
42100
+ return Promise.all(commands.map((command2) => detectOne(command2, deps)));
42101
+ }
42102
+ };
42103
+ }
42104
+ function createDefaultAgentCliDetector() {
42105
+ return createAgentCliDetector({
42106
+ resolve: (command2) => resolveCommandWithOverride(command2, process.env),
42107
+ runVersion: (bin, args) => execFileVersion(bin, args)
42108
+ });
42109
+ }
42110
+ function resolveCommandWithOverride(command2, env) {
42111
+ const overrideName = OVERRIDE_ENV_BY_COMMAND[command2];
42112
+ const override = overrideName ? env[overrideName] : void 0;
42113
+ if (override && override.trim().length > 0) {
42114
+ return resolvePathBinary(override, env);
42115
+ }
42116
+ return resolvePathBinary(command2, env);
42117
+ }
42118
+ function distinctBinaryCommands() {
42119
+ const seen = /* @__PURE__ */ new Set();
42120
+ const commands = [];
42121
+ for (const backend of Object.values(CLI_BACKENDS)) {
42122
+ if (!seen.has(backend.cliCommand)) {
42123
+ seen.add(backend.cliCommand);
42124
+ commands.push(backend.cliCommand);
42125
+ }
42126
+ }
42127
+ return commands;
42128
+ }
42129
+ async function detectOne(command2, deps) {
42130
+ const resolved = deps.resolve(command2);
42131
+ const available = resolved !== void 0;
42132
+ let version2 = null;
42133
+ if (resolved) {
42134
+ version2 = await probeVersionSafe(resolved, deps);
42135
+ }
42136
+ return {
42137
+ id: command2,
42138
+ displayName: BINARY_DISPLAY_NAMES[command2] ?? command2,
42139
+ available,
42140
+ version: version2
42141
+ };
42142
+ }
42143
+ async function probeVersionSafe(resolved, deps) {
42144
+ try {
42145
+ const output = await deps.runVersion(resolved.bin, [...resolved.prefixArgs, "--version"]);
42146
+ return output.match(SEMVER_PATTERN)?.[1] ?? null;
42147
+ } catch {
42148
+ return null;
42149
+ }
42150
+ }
42151
+ function execFileVersion(bin, args) {
42152
+ return new Promise((resolve, reject) => {
42153
+ execFile(
42154
+ bin,
42155
+ [...args],
42156
+ { encoding: "utf-8", timeout: VERSION_PROBE_TIMEOUT_MS, windowsHide: true },
42157
+ (error51, stdout, stderr) => {
42158
+ if (error51) {
42159
+ reject(error51);
42160
+ return;
42161
+ }
42162
+ resolve((stdout || stderr || "").trim());
42163
+ }
42164
+ );
42165
+ });
42166
+ }
42167
+
42168
+ // src/agent-cli-launch-metadata.ts
42169
+ function combineAgentCliLaunchMetadata(metadata, installStatuses, authStatuses) {
42170
+ const availableByCommand = new Map(installStatuses.map((entry) => [entry.id, entry.available]));
42171
+ const signedInByCli = new Map(authStatuses.map((entry) => [entry.cli, entry.signedIn]));
42172
+ return metadata.map((meta3) => ({
42173
+ id: meta3.id,
42174
+ label: meta3.label,
42175
+ // claude 계열 3종은 같은 `claude` 바이너리를 공유하므로 cliCommand로 설치 여부를 판정한다.
42176
+ available: availableByCommand.get(CLI_BACKENDS[meta3.id].cliCommand) ?? false,
42177
+ // model-auth 게이트 대상(claude-kimi/glm)만 실제 로그인 상태를 반영하고,
42178
+ // 자체 인증 CLI(claude/codex)는 Fleet이 로그인 여부를 알 수 없으므로 게이트하지 않는다(true).
42179
+ signedIn: signedInByCli.has(meta3.id) ? signedInByCli.get(meta3.id) ?? false : true
42180
+ }));
42181
+ }
42182
+
42183
+ // src/agent-cli-routes.ts
42184
+ function createAgentCliRouter(deps) {
42185
+ return async function handleAgentCliRoute(context) {
42186
+ const { req, res, pathname } = context;
42187
+ if (pathname === "/agent-cli/state") {
42188
+ if (req.method !== "GET") {
42189
+ deps.writeJson(res, 405, { error: "Method not allowed" });
42190
+ return true;
42191
+ }
42192
+ const clis = await deps.detect();
42193
+ const body = { clis };
42194
+ deps.writeJson(res, 200, body);
42195
+ return true;
42196
+ }
42197
+ return false;
42198
+ };
42199
+ }
42200
+
42201
+ // src/model-auth-routes.ts
42202
+ var MODEL_AUTH_PROVIDERS = [
42203
+ { cli: "claude-kimi", displayName: "Moonshot Kimi" },
42204
+ { cli: "claude-glm", displayName: "ZhipuAI GLM" }
42205
+ ];
42206
+ var UPSTREAM_FAILURE_STATUSES = /* @__PURE__ */ new Set(["timeout", "network", "server"]);
42207
+ function createModelAuthRouter(deps) {
42208
+ return async function handleModelAuthRoute(context) {
42209
+ const { req, res, pathname } = context;
42210
+ if (pathname === "/model-auth/state") {
42211
+ if (req.method !== "GET") {
42212
+ deps.writeJson(res, 405, { error: "Method not allowed" });
42213
+ return true;
42214
+ }
42215
+ deps.writeJson(res, 200, await buildModelAuthState(deps.authService));
42216
+ return true;
42217
+ }
42218
+ const cli = parseProviderPath(pathname);
42219
+ if (!cli) return false;
42220
+ const provider = MODEL_AUTH_PROVIDERS.find((entry) => entry.cli === cli);
42221
+ if (!provider) {
42222
+ deps.writeJson(res, 404, { error: "provider_not_found" });
42223
+ return true;
42224
+ }
42225
+ if (req.method === "PUT") {
42226
+ await signInProvider(req, res, deps, provider);
42227
+ return true;
42228
+ }
42229
+ if (req.method === "DELETE") {
42230
+ await signOutProvider(req, res, deps, provider);
42231
+ return true;
42232
+ }
42233
+ deps.writeJson(res, 405, { error: "Method not allowed" });
42234
+ return true;
42235
+ };
42236
+ }
42237
+ async function buildModelAuthState(authService) {
42238
+ const signedInIds = new Set(await authService.listProviderIds());
42239
+ return {
42240
+ providers: MODEL_AUTH_PROVIDERS.map((provider) => toProviderState(provider, signedInIds))
42241
+ };
42242
+ }
42243
+ async function signInProvider(req, res, deps, provider) {
42244
+ if (!deps.isAuthorized(req)) {
42245
+ deps.writeJson(res, 401, { error: "unauthorized" });
42246
+ return;
42247
+ }
42248
+ if (!isJsonRequest4(req)) {
42249
+ deps.writeJson(res, 415, { error: "unsupported_media_type" });
42250
+ return;
42251
+ }
42252
+ const body = await deps.readJsonBody(req);
42253
+ if (!body || typeof body !== "object" || Array.isArray(body)) {
42254
+ deps.writeJson(res, 400, { error: "invalid_json" });
42255
+ return;
42256
+ }
42257
+ const apiKey = typeof body.apiKey === "string" ? body.apiKey.trim() : "";
42258
+ if (apiKey.length === 0) {
42259
+ deps.writeJson(res, 400, { error: "invalid_api_key" });
42260
+ return;
42261
+ }
42262
+ const providerId = CLI_TO_AUTH_PROVIDER_ID[provider.cli];
42263
+ if (!providerId) {
42264
+ deps.writeJson(res, 500, { error: "provider_unavailable" });
42265
+ return;
42266
+ }
42267
+ const validation = await deps.validateApiKey(provider.cli, apiKey);
42268
+ if (validation.status !== "success") {
42269
+ const status = UPSTREAM_FAILURE_STATUSES.has(validation.status) ? 502 : 400;
42270
+ deps.writeJson(res, status, {
42271
+ error: formatSignInFailureMessage(provider.displayName, validation.status),
42272
+ status: validation.status
42273
+ });
42274
+ return;
42275
+ }
42276
+ await deps.authService.setApiKey(providerId, apiKey);
42277
+ await writeMutationState2(res, deps);
42278
+ }
42279
+ async function signOutProvider(req, res, deps, provider) {
42280
+ if (!deps.isAuthorized(req)) {
42281
+ deps.writeJson(res, 401, { error: "unauthorized" });
42282
+ return;
42283
+ }
42284
+ const providerId = CLI_TO_AUTH_PROVIDER_ID[provider.cli];
42285
+ if (!providerId) {
42286
+ deps.writeJson(res, 500, { error: "provider_unavailable" });
42287
+ return;
42288
+ }
42289
+ await deps.authService.deleteApiKey(providerId);
42290
+ await writeMutationState2(res, deps);
42291
+ }
42292
+ async function writeMutationState2(res, deps) {
42293
+ const response = { state: await buildModelAuthState(deps.authService) };
42294
+ deps.writeJson(res, 200, response);
42295
+ }
42296
+ function toProviderState(provider, signedInIds) {
42297
+ const providerId = CLI_TO_AUTH_PROVIDER_ID[provider.cli] ?? provider.cli;
42298
+ return {
42299
+ cli: provider.cli,
42300
+ displayName: provider.displayName,
42301
+ signedIn: signedInIds.has(providerId)
42302
+ };
42303
+ }
42304
+ function parseProviderPath(pathname) {
42305
+ const parts = pathname.split("/").filter(Boolean);
42306
+ if (parts.length !== 3 || parts[0] !== "model-auth" || parts[1] !== "providers") return null;
42307
+ const cli = safeDecodeURIComponent2(parts[2] ?? "");
42308
+ return cli ? cli : null;
42309
+ }
42310
+ function safeDecodeURIComponent2(value) {
42311
+ try {
42312
+ return decodeURIComponent(value);
42313
+ } catch {
42314
+ return null;
42315
+ }
42316
+ }
42317
+ function isJsonRequest4(req) {
42318
+ const contentType = req.headers["content-type"];
42319
+ return typeof contentType === "string" && contentType.toLowerCase().split(";")[0]?.trim() === "application/json";
42320
+ }
42321
+ function formatSignInFailureMessage(displayName, status) {
42322
+ switch (status) {
42323
+ case "unauthorized":
42324
+ return `${displayName} rejected the API key. Check the key and try again.`;
42325
+ case "forbidden":
42326
+ return `The API key is not allowed for ${displayName}. Check its permissions.`;
42327
+ case "timeout":
42328
+ return `Validating the ${displayName} API key timed out. Check your connection and try again.`;
42329
+ case "network":
42330
+ return `Could not reach ${displayName} to validate the API key. Check your connection and try again.`;
42331
+ case "server":
42332
+ return `${displayName} returned an error while validating the API key. Try again later.`;
42333
+ default:
42334
+ return `Could not validate the ${displayName} API key. Check the key and try again.`;
42335
+ }
42336
+ }
41743
42337
 
41744
42338
  // src/observability-routes.ts
41745
42339
  function writeObserverEvents(req, res, workspace, store2) {
@@ -41779,10 +42373,14 @@ function writeAggregateObserverEvents(req, res, workspaces, store2, resolveWorks
41779
42373
  }
41780
42374
  const unsubscribers = options.subscribeAll ? [
41781
42375
  store2.subscribeAll((event) => {
41782
- if (isSessionUpdatedEvent(event) || isSessionAttentionEvent(event)) {
42376
+ if (isSessionUpdatedEvent(event)) {
41783
42377
  writeEvent(res, 0, event.type, { session: event.session });
41784
42378
  return;
41785
42379
  }
42380
+ if (isSessionAttentionEvent(event)) {
42381
+ writeEvent(res, 0, event.type, { session: event.session, reason: event.reason });
42382
+ return;
42383
+ }
41786
42384
  writeEvent(res, event.id, event.type, { tenant: resolvedWorkspaceSnapshot(resolveWorkspace, event.tenantId), event });
41787
42385
  })
41788
42386
  ] : workspaces.map(
@@ -41932,7 +42530,7 @@ function createConsoleObservabilityStore(deps = {}) {
41932
42530
  return terminalSessionsById.get(sessionId)?.cwd ?? workspacesByCliRunId.get(sessionId)?.session.cwd ?? null;
41933
42531
  }
41934
42532
  function createPendingTerminalSession(input) {
41935
- if (!path93__default.isAbsolute(input.cwd)) throw new Error("Terminal session cwd must be absolute");
42533
+ if (!path92__default.isAbsolute(input.cwd)) throw new Error("Terminal session cwd must be absolute");
41936
42534
  const createdAt = input.createdAt ?? now();
41937
42535
  const canonicalCwd = canonicalizeTheaterPathSync(input.cwd);
41938
42536
  const theaterId = workspaceHash(canonicalCwd);
@@ -41942,7 +42540,7 @@ function createConsoleObservabilityStore(deps = {}) {
41942
42540
  sessionId: input.sessionId,
41943
42541
  cwd: input.cwd,
41944
42542
  canonicalCwd,
41945
- cwdLabel: path93__default.basename(input.cwd) || input.cwd,
42543
+ cwdLabel: path92__default.basename(input.cwd) || input.cwd,
41946
42544
  sequence,
41947
42545
  cliId: input.cliId,
41948
42546
  createdAt,
@@ -41963,6 +42561,8 @@ function createConsoleObservabilityStore(deps = {}) {
41963
42561
  cwdLabel: operation.cwdLabel,
41964
42562
  sequence: operation.sequence,
41965
42563
  label: operation.label,
42564
+ labelSource: operation.labelSource,
42565
+ autoNamePromptSeen: operation.autoNamePromptSeen,
41966
42566
  cliId: operation.cliId,
41967
42567
  cliLabel: operation.cliLabel,
41968
42568
  createdAt: operation.createdAt,
@@ -41985,6 +42585,8 @@ function createConsoleObservabilityStore(deps = {}) {
41985
42585
  cwdLabel: session.cwdLabel,
41986
42586
  sequence: session.sequence,
41987
42587
  ...session.label ? { label: session.label } : {},
42588
+ ...session.labelSource ? { labelSource: session.labelSource } : {},
42589
+ ...session.autoNamePromptSeen ? { autoNamePromptSeen: true } : {},
41988
42590
  ...session.cliId ? { cliId: session.cliId } : {},
41989
42591
  ...session.cliLabel ? { cliLabel: session.cliLabel } : {},
41990
42592
  createdAt: session.createdAt,
@@ -42030,11 +42632,31 @@ function createConsoleObservabilityStore(deps = {}) {
42030
42632
  const label = rawLabel.trim().slice(0, 200);
42031
42633
  if (label.length === 0) {
42032
42634
  delete session.label;
42635
+ delete session.labelSource;
42636
+ delete session.autoNamePromptSeen;
42033
42637
  } else {
42034
42638
  session.label = label;
42639
+ session.labelSource = "user";
42640
+ session.autoNamePromptSeen = true;
42035
42641
  }
42036
42642
  return toTerminalSessionInfo(session);
42037
42643
  }
42644
+ function autoNameTerminalSession(sessionId, label) {
42645
+ const session = terminalSessionsById.get(sessionId);
42646
+ if (!session) return null;
42647
+ const effectiveSource = session.labelSource ?? (session.label ? "user" : void 0);
42648
+ if (effectiveSource === "user" || session.autoNamePromptSeen) {
42649
+ return { session: toTerminalSessionInfo(session), changed: false, renamed: false };
42650
+ }
42651
+ session.autoNamePromptSeen = true;
42652
+ const next = label?.trim().slice(0, 200) ?? "";
42653
+ if (next.length === 0 || next === session.label) {
42654
+ return { session: toTerminalSessionInfo(session), changed: true, renamed: false };
42655
+ }
42656
+ session.label = next;
42657
+ session.labelSource = "auto";
42658
+ return { session: toTerminalSessionInfo(session), changed: true, renamed: true };
42659
+ }
42038
42660
  function notifySessionUpdated(session) {
42039
42661
  const event = { type: "session:updated", session };
42040
42662
  for (const listener of allListeners) listener(event);
@@ -42043,8 +42665,8 @@ function createConsoleObservabilityStore(deps = {}) {
42043
42665
  const session = terminalSessionsById.get(sessionId);
42044
42666
  return session ? toTerminalSessionInfo(session) : null;
42045
42667
  }
42046
- function notifySessionAttention(session) {
42047
- const event = { type: "session:attention", session };
42668
+ function notifySessionAttention(session, reason) {
42669
+ const event = { type: "session:attention", session, reason };
42048
42670
  for (const listener of allListeners) listener(event);
42049
42671
  }
42050
42672
  function removeTerminalSession(sessionId) {
@@ -42085,6 +42707,7 @@ function createConsoleObservabilityStore(deps = {}) {
42085
42707
  notifySessionAttention,
42086
42708
  notifySessionUpdated,
42087
42709
  renameTerminalSession,
42710
+ autoNameTerminalSession,
42088
42711
  subscribe,
42089
42712
  subscribeAll,
42090
42713
  updateTerminalSessionProviderSession,
@@ -42318,7 +42941,7 @@ function tryServeStaticConsole(req, res, pathname) {
42318
42941
  res.end(JSON.stringify({ error: "Not found" }));
42319
42942
  return true;
42320
42943
  }
42321
- const absolutePath = path93__default.resolve(CONSOLE_ROOT, relativePath2);
42944
+ const absolutePath = path92__default.resolve(CONSOLE_ROOT, relativePath2);
42322
42945
  if (!absolutePath.startsWith(CONSOLE_ROOT)) {
42323
42946
  res.writeHead(404, withSecurityHeaders2({ "Content-Type": "application/json" }));
42324
42947
  res.end(JSON.stringify({ error: "Not found" }));
@@ -42326,7 +42949,7 @@ function tryServeStaticConsole(req, res, pathname) {
42326
42949
  }
42327
42950
  try {
42328
42951
  const data = fs7__default.readFileSync(absolutePath);
42329
- const contentType = MIME_TYPES[path93__default.extname(absolutePath)] ?? "application/octet-stream";
42952
+ const contentType = MIME_TYPES[path92__default.extname(absolutePath)] ?? "application/octet-stream";
42330
42953
  res.writeHead(200, withSecurityHeaders2({ "Content-Type": contentType }));
42331
42954
  if (req.method === "HEAD") {
42332
42955
  res.end();
@@ -42346,7 +42969,7 @@ function tryServeStaticConsole(req, res, pathname) {
42346
42969
  }
42347
42970
  function serveFallbackIndex(req, res) {
42348
42971
  try {
42349
- const data = fs7__default.readFileSync(path93__default.join(CONSOLE_ROOT, "index.html"));
42972
+ const data = fs7__default.readFileSync(path92__default.join(CONSOLE_ROOT, "index.html"));
42350
42973
  res.writeHead(200, withSecurityHeaders2({ "Content-Type": MIME_TYPES[".html"] }));
42351
42974
  if (req.method === "HEAD") {
42352
42975
  res.end();
@@ -42372,7 +42995,7 @@ function resolveConsolePath(pathname) {
42372
42995
  }
42373
42996
  if (withoutPrefix === "") return "index.html";
42374
42997
  if (withoutPrefix.includes("\0")) return null;
42375
- if (!path93__default.extname(withoutPrefix)) return "index.html";
42998
+ if (!path92__default.extname(withoutPrefix)) return "index.html";
42376
42999
  return withoutPrefix;
42377
43000
  }
42378
43001
  var TerminalFolderListError = class extends Error {
@@ -42406,14 +43029,14 @@ async function listTerminalFolders(requestedPath, deps = {}) {
42406
43029
  }
42407
43030
  function normalizeFolderBrowserPath(value, platform = process.platform) {
42408
43031
  if (typeof value !== "string" || value.length === 0 || value.includes("\0")) throw new TerminalFolderListError("invalid_path");
42409
- if (isWindowsAmbiguousPath(value, platform) || !path93__default.isAbsolute(value)) throw new TerminalFolderListError("invalid_path");
42410
- return path93__default.resolve(value);
43032
+ if (isWindowsAmbiguousPath(value, platform) || !path92__default.isAbsolute(value)) throw new TerminalFolderListError("invalid_path");
43033
+ return path92__default.resolve(value);
42411
43034
  }
42412
43035
  function normalizeListPath(requestedPath, platform, deps) {
42413
43036
  if (requestedPath === null || requestedPath === void 0) {
42414
43037
  const home = deps.homedir?.() ?? os22__default.homedir();
42415
43038
  const start = home || deps.cwd?.() || process.cwd();
42416
- return path93__default.resolve(start);
43039
+ return path92__default.resolve(start);
42417
43040
  }
42418
43041
  return normalizeFolderBrowserPath(requestedPath, platform);
42419
43042
  }
@@ -42464,7 +43087,7 @@ async function openDirectory(targetPath, opendir) {
42464
43087
  }
42465
43088
  async function toTerminalFolderEntry(targetPath, dirent, stat5) {
42466
43089
  if (!dirent.isDirectory() && !dirent.isSymbolicLink()) return null;
42467
- const entryPath = path93__default.join(targetPath, dirent.name);
43090
+ const entryPath = path92__default.join(targetPath, dirent.name);
42468
43091
  if (dirent.isDirectory()) return { name: dirent.name, path: entryPath, kind: "dir", accessible: true };
42469
43092
  const accessible = await statSymlinkDirectory(entryPath, stat5);
42470
43093
  if (accessible === null) return null;
@@ -42484,10 +43107,10 @@ function mapFsError(error51) {
42484
43107
  return new TerminalFolderListError("invalid_path");
42485
43108
  }
42486
43109
  function parentPath(targetPath, platform) {
42487
- const parsed = path93__default.parse(targetPath);
42488
- const resolved = path93__default.resolve(targetPath);
42489
- if (resolved === path93__default.resolve(parsed.root)) return null;
42490
- const parent = path93__default.dirname(resolved);
43110
+ const parsed = path92__default.parse(targetPath);
43111
+ const resolved = path92__default.resolve(targetPath);
43112
+ if (resolved === path92__default.resolve(parsed.root)) return null;
43113
+ const parent = path92__default.dirname(resolved);
42491
43114
  if (platform === "win32" && parent === resolved) return null;
42492
43115
  return parent;
42493
43116
  }
@@ -42498,14 +43121,14 @@ function isWindowsAmbiguousPath(value, platform) {
42498
43121
  var GRANT_ID_BYTES = 24;
42499
43122
  var DEFAULT_GRANT_TTL_MS = 6e4;
42500
43123
  function createFolderGrantStore(deps = {}) {
42501
- const randomId = deps.randomId ?? (() => crypto4.randomBytes(GRANT_ID_BYTES).toString("base64url"));
42502
- const statSync5 = deps.statSync ?? fs7__default.statSync;
43124
+ const randomId = deps.randomId ?? (() => crypto3.randomBytes(GRANT_ID_BYTES).toString("base64url"));
43125
+ const statSync4 = deps.statSync ?? fs7__default.statSync;
42503
43126
  const ttlMs = deps.ttlMs ?? DEFAULT_GRANT_TTL_MS;
42504
43127
  const now = deps.now ?? Date.now;
42505
43128
  const grants = /* @__PURE__ */ new Map();
42506
43129
  function issue3(cwd) {
42507
43130
  prune();
42508
- const normalized = validateAbsoluteDirectory(cwd, statSync5);
43131
+ const normalized = validateAbsoluteDirectory(cwd, statSync4);
42509
43132
  const folderGrantId = randomId();
42510
43133
  grants.set(folderGrantId, { cwd: normalized, expiresAt: now() + ttlMs });
42511
43134
  return folderGrantId;
@@ -42525,11 +43148,11 @@ function createFolderGrantStore(deps = {}) {
42525
43148
  }
42526
43149
  return { issue: issue3, consume };
42527
43150
  }
42528
- function validateAbsoluteDirectory(cwd, statSync5 = fs7__default.statSync) {
43151
+ function validateAbsoluteDirectory(cwd, statSync4 = fs7__default.statSync) {
42529
43152
  if (typeof cwd !== "string" || cwd.length === 0 || cwd.includes("\0")) throw new Error("invalid_folder");
42530
- if (isWindowsAmbiguousPath2(cwd) || !path93__default.isAbsolute(cwd)) throw new Error("invalid_folder");
42531
- const normalized = path93__default.resolve(cwd);
42532
- if (!statSync5(normalized).isDirectory()) throw new Error("invalid_folder");
43153
+ if (isWindowsAmbiguousPath2(cwd) || !path92__default.isAbsolute(cwd)) throw new Error("invalid_folder");
43154
+ const normalized = path92__default.resolve(cwd);
43155
+ if (!statSync4(normalized).isDirectory()) throw new Error("invalid_folder");
42533
43156
  return normalized;
42534
43157
  }
42535
43158
  function isWindowsAmbiguousPath2(value) {
@@ -42551,8 +43174,11 @@ function buildConsoleTurnHookCommand(entry, phase) {
42551
43174
  function buildConsoleAttentionHookCommand(entry) {
42552
43175
  return buildConsoleCliHookExec(entry, ["hook", "attention"]);
42553
43176
  }
43177
+ function buildConsoleAutoNameHookCommand(entry) {
43178
+ return buildConsoleCliHookExec(entry, ["hook", "auto-name"]);
43179
+ }
42554
43180
  function buildConsoleCaptureHookCommand(entry, cliId) {
42555
- const extension = path93__default.extname(entry.entryPath);
43181
+ const extension = path92__default.extname(entry.entryPath);
42556
43182
  if (JAVASCRIPT_ENTRY_EXTENSIONS.has(extension)) {
42557
43183
  return createSessionCaptureHookExec({
42558
43184
  entryPath: entry.entryPath,
@@ -42592,11 +43218,11 @@ function runCodexCommand(command2) {
42592
43218
  }
42593
43219
  function withConsoleMarketplaceLock(target, fn) {
42594
43220
  const lockDir = `${target}${MARKETPLACE_LOCK_DIR_SUFFIX}`;
42595
- mkdirSync(path93__default.dirname(lockDir), { recursive: true });
43221
+ mkdirSync(path92__default.dirname(lockDir), { recursive: true });
42596
43222
  return withDirectoryLock({ lockDir }, fn);
42597
43223
  }
42598
43224
  function buildConsoleCliHookExec(entry, trailingArgs) {
42599
- const extension = path93__default.extname(entry.entryPath);
43225
+ const extension = path92__default.extname(entry.entryPath);
42600
43226
  if (JAVASCRIPT_ENTRY_EXTENSIONS.has(extension)) {
42601
43227
  return {
42602
43228
  command: entry.execPath,
@@ -42622,12 +43248,12 @@ var CONSOLE_ENTRY_PATH = fileURLToPath(import.meta.url);
42622
43248
  var HOOK_ENTRY_EXTENSIONS = /* @__PURE__ */ new Set([".cjs", ".cts", ".js", ".mjs", ".mts", ".ts", ".tsx"]);
42623
43249
  var require2 = createRequire(import.meta.url);
42624
43250
  function createDefaultTerminalLaunchResolver(deps = {}) {
42625
- const baseCwd = deps.cwd ?? process7.cwd();
42626
- const env = deps.env ?? process7.env;
42627
- const execPath = deps.execPath ?? process7.execPath;
43251
+ const baseCwd = deps.cwd ?? process9.cwd();
43252
+ const env = deps.env ?? process9.env;
43253
+ const execPath = deps.execPath ?? process9.execPath;
42628
43254
  const homedir3 = deps.homedir ?? DEFAULT_TERMINAL_CWD_FALLBACK;
42629
- const platform = deps.platform ?? process7.platform;
42630
- const entryPath = resolveHookEntryPath(deps.entryPath ?? process7.argv[1]);
43255
+ const platform = deps.platform ?? process9.platform;
43256
+ const entryPath = resolveHookEntryPath(deps.entryPath ?? process9.argv[1]);
42631
43257
  const tsxLoaderPath = deps.tsxLoaderPath ?? resolveOptionalPackage("tsx");
42632
43258
  const dataDir = deps.dataDir ?? getFleetDataDir();
42633
43259
  const infraServices = deps.infraServices ?? createInfraServices();
@@ -42684,11 +43310,11 @@ function resolveHookEntryPath(candidate) {
42684
43310
  return CONSOLE_ENTRY_PATH;
42685
43311
  }
42686
43312
  function hasHookEntryExtension(entryPath) {
42687
- return HOOK_ENTRY_EXTENSIONS.has(path93__default.extname(entryPath));
43313
+ return HOOK_ENTRY_EXTENSIONS.has(path92__default.extname(entryPath));
42688
43314
  }
42689
43315
  function startTerminalShell(launch, size) {
42690
43316
  const { spawn: spawnPty } = require2("node-pty");
42691
- const useConptyDll = resolveUseConptyDll(process7.platform, process7.env);
43317
+ const useConptyDll = resolveUseConptyDll(process9.platform, process9.env);
42692
43318
  return spawnPty(launch.bin, [...launch.args], {
42693
43319
  cols: size.cols,
42694
43320
  rows: size.rows,
@@ -42728,6 +43354,7 @@ async function createAgentCliLaunchSpec(options) {
42728
43354
  turnStartHookExec: buildConsoleTurnHookCommand(options.hookEntry, "start"),
42729
43355
  turnEndHookExec: buildConsoleTurnHookCommand(options.hookEntry, "end"),
42730
43356
  inputWaitingHookExec: buildConsoleAttentionHookCommand(options.hookEntry),
43357
+ autoNameHookExec: buildConsoleAutoNameHookCommand(options.hookEntry),
42731
43358
  hookExec: buildConsoleHookCommand(options.hookEntry),
42732
43359
  onCleanup: (cleanup) => cleanupStack.push(cleanup),
42733
43360
  replaceSystemPrompt: globalSettings.replaceSystemPrompt,
@@ -42861,6 +43488,9 @@ function createTerminalSessionManager(deps) {
42861
43488
  socket.on("message", (data, isBinary) => handleSocketMessage(session, data, isBinary));
42862
43489
  socket.once("close", () => detachSocket(session, socket));
42863
43490
  }
43491
+ function hasLiveSessions() {
43492
+ return sessions.size > 0 || pendingSessions.size > 0;
43493
+ }
42864
43494
  async function createSession(context) {
42865
43495
  await getOrCreateSession(context);
42866
43496
  }
@@ -43002,7 +43632,7 @@ function createTerminalSessionManager(deps) {
43002
43632
  await runLaunchCleanup(session.cleanup);
43003
43633
  }
43004
43634
  }
43005
- return { canAttach, createSession, attach, getSessionMessagePolicy, getSessionRenameCommand, terminate, stop, writeToSession };
43635
+ return { canAttach, createSession, attach, hasLiveSessions, getSessionMessagePolicy, getSessionRenameCommand, terminate, stop, writeToSession };
43006
43636
  }
43007
43637
  async function runLaunchCleanup(cleanup) {
43008
43638
  try {
@@ -43040,7 +43670,7 @@ var DEFAULT_TICKET_TTL_MS = 1e4;
43040
43670
  function createTerminalTicketRegistry(deps = {}) {
43041
43671
  const ttlMs = deps.ttlMs ?? DEFAULT_TICKET_TTL_MS;
43042
43672
  const now = deps.now ?? Date.now;
43043
- const randomTicket = deps.randomTicket ?? (() => crypto4.randomBytes(32).toString("base64url"));
43673
+ const randomTicket = deps.randomTicket ?? (() => crypto3.randomBytes(32).toString("base64url"));
43044
43674
  const tickets = /* @__PURE__ */ new Map();
43045
43675
  function issue3(context) {
43046
43676
  prune();
@@ -43212,7 +43842,7 @@ var TheaterRegistry = class {
43212
43842
  #items = /* @__PURE__ */ new Map();
43213
43843
  #mruId = null;
43214
43844
  async register(cwd) {
43215
- const resolved = path93__default.resolve(cwd);
43845
+ const resolved = path92__default.resolve(cwd);
43216
43846
  const real = await canonicalizeTheaterPath(resolved);
43217
43847
  const id = workspaceHash(real);
43218
43848
  const now = (/* @__PURE__ */ new Date()).toISOString();
@@ -43267,6 +43897,383 @@ var TheaterRegistry = class {
43267
43897
  return removed;
43268
43898
  }
43269
43899
  };
43900
+ var PACKAGE_NAMES = ["@dotobokuri/fleet-cli", "@dotobokuri/fleet-console"];
43901
+ var WORKER_FILE_PREFIX = "fleet-console-update-";
43902
+ var WORKER_FILE_SUFFIX = ".mjs";
43903
+ var STATUS_FILE_SUFFIX = ".status.json";
43904
+ var LOG_FILE_SUFFIX = ".log";
43905
+ var TEMP_FILE_MODE = 384;
43906
+ function createConsoleUpdateApplyService(deps = {}) {
43907
+ const env = deps.env ?? process9.env;
43908
+ const execPath = deps.execPath ?? process9.execPath;
43909
+ const makeDir = deps.makeDir ?? ((dirPath, options) => {
43910
+ fs7__default.mkdirSync(dirPath, options);
43911
+ });
43912
+ const now = deps.now ?? Date.now;
43913
+ const processPid = deps.processPid ?? process9.pid;
43914
+ const preflightInstall = deps.preflightInstall ?? ((currentPackageRoot) => preflightPackageManager(currentPackageRoot, env));
43915
+ const serverModulePath = deps.serverModulePath ?? resolveDefaultServerModulePath();
43916
+ const spawnWorker = deps.spawnWorker ?? defaultSpawnWorker;
43917
+ const tmpDir = deps.tmpDir ?? os22__default.tmpdir();
43918
+ const writeFile4 = deps.writeFile ?? ((filePath, content, options) => {
43919
+ fs7__default.writeFileSync(filePath, content, { mode: options.mode });
43920
+ });
43921
+ async function start(request) {
43922
+ const packageManager = await preflightInstall(request.currentPackageRoot);
43923
+ const stamp = `${now()}-${processPid}`;
43924
+ const workerPath = path92__default.join(tmpDir, `${WORKER_FILE_PREFIX}${stamp}${WORKER_FILE_SUFFIX}`);
43925
+ makeDir(request.dataDir, { recursive: true, mode: 448 });
43926
+ const statusFile = path92__default.join(request.dataDir, `${WORKER_FILE_PREFIX}${stamp}${STATUS_FILE_SUFFIX}`);
43927
+ const logFile = path92__default.join(request.dataDir, `${WORKER_FILE_PREFIX}${stamp}${LOG_FILE_SUFFIX}`);
43928
+ const script = emitConsoleUpdateWorkerScript({
43929
+ currentEndpoint: request.currentEndpoint,
43930
+ currentPackageRoot: request.currentPackageRoot,
43931
+ currentPid: request.currentPid,
43932
+ lockFile: request.lockFile,
43933
+ logFile,
43934
+ packageManager,
43935
+ packageNames: PACKAGE_NAMES,
43936
+ serverModulePath,
43937
+ statusFile,
43938
+ targetVersion: request.targetVersion,
43939
+ workerPath
43940
+ });
43941
+ writeFile4(workerPath, script, { mode: TEMP_FILE_MODE });
43942
+ await spawnDetachedWorker(spawnWorker, execPath, [workerPath], env);
43943
+ return { accepted: true };
43944
+ }
43945
+ return { start };
43946
+ }
43947
+ function emitConsoleUpdateWorkerScript(config2) {
43948
+ return `import { execFileSync, spawn } from "node:child_process";
43949
+ import fs from "node:fs";
43950
+ import os from "node:os";
43951
+ import path from "node:path";
43952
+
43953
+ const config = ${JSON.stringify(config2)};
43954
+ const stalePrefix = ${JSON.stringify(WORKER_FILE_PREFIX)};
43955
+ const workerSuffix = ${JSON.stringify(WORKER_FILE_SUFFIX)};
43956
+ const stopTimeoutMs = 60000;
43957
+ const startTimeoutMs = 60000;
43958
+ const sleepMs = 250;
43959
+
43960
+ async function main() {
43961
+ writeStatus("starting");
43962
+ cleanupStaleWorkers();
43963
+ const manager = detectPackageManager();
43964
+ ensureGlobalRootWritable(manager);
43965
+ writeStatus("preflight-ok", { manager: manager.command });
43966
+ await stopCurrentConsole();
43967
+ await waitForOldConsoleExit();
43968
+ writeStatus("installing", { manager: manager.command });
43969
+ await installPackages(manager);
43970
+ writeStatus("starting-daemon");
43971
+ const lock = await startNewDaemon();
43972
+ openBrowser(new URL("console/", lock.endpoint).toString());
43973
+ writeStatus("completed");
43974
+ }
43975
+
43976
+ main()
43977
+ .catch((error) => {
43978
+ writeStatus("failed", { error: sanitizeError(error) });
43979
+ log("failed: " + sanitizeError(error));
43980
+ process.exitCode = 1;
43981
+ })
43982
+ .finally(() => {
43983
+ try {
43984
+ fs.rmSync(config.workerPath, { force: true });
43985
+ } catch {
43986
+ // \uC790\uAC00 \uC815\uB9AC\uB294 \uC2E4\uD328\uD574\uB3C4 \uC5C5\uB370\uC774\uD2B8 \uACB0\uACFC\uB97C \uB9C9\uC9C0 \uC54A\uB294\uB2E4.
43987
+ }
43988
+ });
43989
+
43990
+ function writeStatus(phase, extra = {}) {
43991
+ const payload = {
43992
+ phase,
43993
+ updatedAt: new Date().toISOString(),
43994
+ ...extra,
43995
+ };
43996
+ fs.writeFileSync(config.statusFile, JSON.stringify(payload, null, 2), { mode: 0o600 });
43997
+ log("phase: " + phase);
43998
+ }
43999
+
44000
+ function log(message) {
44001
+ fs.appendFileSync(config.logFile, new Date().toISOString() + " " + message + "\\n", { mode: 0o600 });
44002
+ }
44003
+
44004
+ function cleanupStaleWorkers() {
44005
+ const now = Date.now();
44006
+ for (const entry of fs.readdirSync(os.tmpdir())) {
44007
+ if (!entry.startsWith(stalePrefix) || !entry.endsWith(workerSuffix)) continue;
44008
+ const filePath = path.join(os.tmpdir(), entry);
44009
+ if (filePath === config.workerPath) continue;
44010
+ try {
44011
+ const stat = fs.statSync(filePath);
44012
+ if (now - stat.mtimeMs > 24 * 60 * 60 * 1000) fs.rmSync(filePath, { force: true });
44013
+ } catch {
44014
+ // \uC624\uB798\uB41C \uC784\uC2DC worker \uC815\uB9AC\uB294 \uCD5C\uC120 \uB178\uB825\uC73C\uB85C\uB9CC \uC218\uD589\uD55C\uB2E4.
44015
+ }
44016
+ }
44017
+ }
44018
+
44019
+ async function stopCurrentConsole() {
44020
+ writeStatus("stopping-console");
44021
+ try {
44022
+ process.kill(config.currentPid, "SIGTERM");
44023
+ } catch (error) {
44024
+ if (!isNoSuchProcess(error)) throw error;
44025
+ }
44026
+ }
44027
+
44028
+ async function waitForOldConsoleExit() {
44029
+ const deadline = Date.now() + stopTimeoutMs;
44030
+ let escalated = false;
44031
+ while (Date.now() < deadline) {
44032
+ const pidGone = !isProcessAlive(config.currentPid);
44033
+ const lockGone = !fs.existsSync(config.lockFile);
44034
+ const healthGone = await isHealthGone(config.currentEndpoint);
44035
+ if (pidGone && lockGone && healthGone) return;
44036
+ if (!escalated && Date.now() > deadline - 10000 && isProcessAlive(config.currentPid)) {
44037
+ escalated = true;
44038
+ try {
44039
+ process.kill(config.currentPid, "SIGKILL");
44040
+ } catch (error) {
44041
+ if (!isNoSuchProcess(error)) throw error;
44042
+ }
44043
+ }
44044
+ await sleep(sleepMs);
44045
+ }
44046
+ throw new Error("old console did not stop before timeout");
44047
+ }
44048
+
44049
+ function detectPackageManager() {
44050
+ const configured = config.packageManager;
44051
+ try {
44052
+ const root = execFileSync(configured.bin, [...configured.prefixArgs, "root", "-g"], { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
44053
+ if (!root) throw new Error("global package manager root is empty");
44054
+ const rootReal = safeRealpath(root);
44055
+ const packageReal = normalizeExistingPath(config.currentPackageRoot);
44056
+ if (!rootReal || !packageReal) throw new Error("global package manager root could not be resolved");
44057
+ if (isPathInside(packageReal, rootReal)) {
44058
+ return { ...configured, root: rootReal };
44059
+ }
44060
+ for (const packageName of config.packageNames) {
44061
+ if (packageReal === safeRealpath(path.join(root, packageName))) {
44062
+ return { ...configured, root: rootReal };
44063
+ }
44064
+ }
44065
+ } catch (error) {
44066
+ throw new Error("no supported global package manager found: " + sanitizeError(error));
44067
+ }
44068
+ throw new Error("no supported global package manager found");
44069
+ }
44070
+
44071
+ function ensureGlobalRootWritable(manager) {
44072
+ try {
44073
+ fs.accessSync(manager.root, fs.constants.W_OK);
44074
+ } catch {
44075
+ throw new Error("global package manager root is not writable");
44076
+ }
44077
+ }
44078
+
44079
+ async function installPackages(manager) {
44080
+ const packages = config.packageNames.map((name) => name + "@" + config.targetVersion);
44081
+ const code = await spawnExit(manager.bin, [...manager.prefixArgs, "i", "-g", "--force", ...packages]);
44082
+ if (code !== 0) throw new Error("global package install failed with exit code " + code);
44083
+ }
44084
+
44085
+ async function startNewDaemon() {
44086
+ const child = spawn(process.execPath, [config.serverModulePath, "serve"], {
44087
+ detached: true,
44088
+ env: process.env,
44089
+ stdio: "ignore",
44090
+ windowsHide: true,
44091
+ });
44092
+ child.once("error", () => {});
44093
+ child.unref();
44094
+ const deadline = Date.now() + startTimeoutMs;
44095
+ while (Date.now() < deadline) {
44096
+ const lock = readLock();
44097
+ if (lock && lock.pid !== config.currentPid && await isNewHealthOk(lock)) return lock;
44098
+ await sleep(sleepMs);
44099
+ }
44100
+ throw new Error("new console daemon did not become healthy");
44101
+ }
44102
+
44103
+ function openBrowser(url) {
44104
+ const platform = os.platform();
44105
+ if (platform === "darwin") {
44106
+ spawnBrowser("open", [url]);
44107
+ return;
44108
+ }
44109
+ if (platform === "win32") {
44110
+ spawnBrowser("cmd", ["/c", "start", "", url]);
44111
+ return;
44112
+ }
44113
+ spawnBrowser("xdg-open", [url]);
44114
+ }
44115
+
44116
+ function spawnBrowser(command, args) {
44117
+ const child = spawn(command, args, { detached: true, stdio: "ignore", windowsHide: true });
44118
+ child.once("error", () => {});
44119
+ child.unref();
44120
+ }
44121
+
44122
+ function spawnExit(command, args) {
44123
+ return new Promise((resolve) => {
44124
+ const child = spawn(command, args, { stdio: "ignore", windowsHide: true });
44125
+ child.once("error", () => resolve(1));
44126
+ child.once("exit", (code) => resolve(code ?? 1));
44127
+ });
44128
+ }
44129
+
44130
+ function readLock() {
44131
+ try {
44132
+ return JSON.parse(fs.readFileSync(config.lockFile, "utf8"));
44133
+ } catch {
44134
+ return null;
44135
+ }
44136
+ }
44137
+
44138
+ async function isNewHealthOk(lock) {
44139
+ if (!lock || typeof lock.endpoint !== "string" || typeof lock.token !== "string") return false;
44140
+ try {
44141
+ const response = await fetch(new URL("health", lock.endpoint), {
44142
+ headers: { authorization: "Bearer " + lock.token },
44143
+ });
44144
+ if (!response.ok) return false;
44145
+ const version = await readHealthVersion(response);
44146
+ if (version === null) {
44147
+ log("new health response did not expose a version; waiting for verified target");
44148
+ return false;
44149
+ }
44150
+ return version === config.targetVersion;
44151
+ } catch {
44152
+ return false;
44153
+ }
44154
+ }
44155
+
44156
+ async function readHealthVersion(response) {
44157
+ try {
44158
+ const payload = await response.json();
44159
+ return typeof payload.version === "string" ? payload.version : null;
44160
+ } catch {
44161
+ return null;
44162
+ }
44163
+ }
44164
+
44165
+ async function isHealthGone(endpoint) {
44166
+ try {
44167
+ await fetch(new URL("health", endpoint));
44168
+ return false;
44169
+ } catch {
44170
+ return true;
44171
+ }
44172
+ }
44173
+
44174
+ function isProcessAlive(pid) {
44175
+ try {
44176
+ process.kill(pid, 0);
44177
+ return true;
44178
+ } catch (error) {
44179
+ return !isNoSuchProcess(error);
44180
+ }
44181
+ }
44182
+
44183
+ function isNoSuchProcess(error) {
44184
+ return error && typeof error === "object" && error.code === "ESRCH";
44185
+ }
44186
+
44187
+ function safeRealpath(targetPath) {
44188
+ try {
44189
+ return normalizePath(fs.realpathSync(targetPath));
44190
+ } catch {
44191
+ return "";
44192
+ }
44193
+ }
44194
+
44195
+ function normalizeExistingPath(targetPath) {
44196
+ return safeRealpath(targetPath) || normalizePath(targetPath);
44197
+ }
44198
+
44199
+ function normalizePath(targetPath) {
44200
+ const resolved = path.resolve(targetPath);
44201
+ return os.platform() === "win32" ? resolved.toLowerCase() : resolved;
44202
+ }
44203
+
44204
+ function isPathInside(targetPath, rootPath) {
44205
+ const relative = path.relative(rootPath, targetPath);
44206
+ return relative === "" || (!!relative && !relative.startsWith("..") && !path.isAbsolute(relative));
44207
+ }
44208
+
44209
+ function sleep(ms) {
44210
+ return new Promise((resolve) => setTimeout(resolve, ms));
44211
+ }
44212
+
44213
+ function sanitizeError(error) {
44214
+ const message = error instanceof Error ? error.message : String(error);
44215
+ return message
44216
+ .replaceAll(config.currentPackageRoot, "[path]")
44217
+ .replaceAll(config.lockFile, "[path]")
44218
+ .replaceAll(config.logFile, "[path]")
44219
+ .replaceAll(config.statusFile, "[path]")
44220
+ .replaceAll(config.workerPath, "[path]");
44221
+ }
44222
+ `;
44223
+ }
44224
+ async function preflightPackageManager(packageRoot, env) {
44225
+ const updater = createGlobalPackageUpdater({
44226
+ env,
44227
+ packageNames: PACKAGE_NAMES,
44228
+ resolveCurrentPackageRoot: () => packageRoot,
44229
+ resolveCurrentVersion: () => void 0
44230
+ });
44231
+ const detection = await updater.detectPackageManager();
44232
+ if (detection.manager === void 0) {
44233
+ if (detection.reason === "permission") {
44234
+ throw new Error("global package manager root is not writable");
44235
+ }
44236
+ throw new Error("no supported global package manager found");
44237
+ }
44238
+ return {
44239
+ bin: detection.manager.resolved.bin,
44240
+ command: detection.manager.command,
44241
+ globalRoot: detection.manager.globalRoot,
44242
+ prefixArgs: detection.manager.resolved.prefixArgs
44243
+ };
44244
+ }
44245
+ function spawnDetachedWorker(spawnWorker, execPath, args, env) {
44246
+ return new Promise((resolve, reject) => {
44247
+ const child = spawnWorker(execPath, args, { detached: true, env, stdio: "ignore", windowsHide: true });
44248
+ let settled = false;
44249
+ child.once("error", (error51) => {
44250
+ if (settled) return;
44251
+ settled = true;
44252
+ reject(error51);
44253
+ });
44254
+ child.unref();
44255
+ queueMicrotask(() => {
44256
+ if (settled) return;
44257
+ settled = true;
44258
+ resolve();
44259
+ });
44260
+ });
44261
+ }
44262
+ function defaultSpawnWorker(execPath, args, options) {
44263
+ const child = spawn(execPath, [...args], options);
44264
+ child.once("error", () => {
44265
+ });
44266
+ return child;
44267
+ }
44268
+ function resolveDefaultServerModulePath() {
44269
+ const builtPath = fileURLToPath(new URL("../dist/cli.mjs", import.meta.url));
44270
+ if (fs7__default.existsSync(builtPath)) return builtPath;
44271
+ const sourcePath = fileURLToPath(import.meta.url);
44272
+ if (sourcePath.endsWith(".ts")) {
44273
+ return sourcePath.replace(/update-apply\.ts$/, "cli.ts");
44274
+ }
44275
+ return path92__default.join(path92__default.dirname(sourcePath), "cli.mjs");
44276
+ }
43270
44277
 
43271
44278
  // src/update-check.ts
43272
44279
  var FLEET_CONSOLE_PACKAGE_NAME = "@dotobokuri/fleet-console";
@@ -43288,9 +44295,9 @@ function createConsoleUpdateCheckService(deps = {}) {
43288
44295
  void refresh();
43289
44296
  return current?.status ?? NO_UPDATE_STATUS;
43290
44297
  };
43291
- const refresh = async () => {
44298
+ const refresh = async (options = {}) => {
43292
44299
  const current = cached2;
43293
- if (current && now() - current.checkedAt < ttlMs) {
44300
+ if (options.force !== true && current && now() - current.checkedAt < ttlMs) {
43294
44301
  return current.status;
43295
44302
  }
43296
44303
  if (inFlight) {
@@ -43328,23 +44335,26 @@ var SHELL_TERMINAL_SESSION_ID = "shell";
43328
44335
  var THEATER_SHELL_SESSION_PREFIX2 = "shell:";
43329
44336
  var SERVER_TIMEOUT_MS = 30 * 60 * 1e3;
43330
44337
  var MAX_BODY_BYTES = 1024 * 1024;
44338
+ var UPDATE_APPLY_FORBIDDEN_BODY_KEYS = /* @__PURE__ */ new Set(["channel", "package", "packageName", "packageVersion", "packages", "targetVersion", "version"]);
43331
44339
  function createConsoleServer(deps = {}) {
43332
44340
  const host = deps.host ?? DEFAULT_HOST2;
43333
44341
  const port = deps.port ?? DEFAULT_PORT2;
43334
- const version2 = deps.version ?? readFleetConsoleRelease().version;
43335
- const channel = readConsoleChannel();
44342
+ const release = deps.release ?? readFleetConsoleRelease();
44343
+ const version2 = deps.version ?? release.version;
44344
+ const channel = release.channel;
43336
44345
  const carrierRegistry = createCarrierRegistry();
43337
44346
  registerDefaultCarriers(carrierRegistry);
43338
44347
  const lock = createConsoleLock({ hostname: () => host });
43339
44348
  const observability = createConsoleObservabilityStore();
43340
44349
  const updateCheck = deps.updateCheck ?? createConsoleUpdateCheckService();
44350
+ const updateApply = deps.updateApply ?? createConsoleUpdateApplyService();
43341
44351
  const theaters = new TheaterRegistry();
43342
44352
  const terminalTickets = createTerminalTicketRegistry();
43343
44353
  const folderGrants = createFolderGrantStore();
43344
44354
  const infraServices = createInfraServices();
43345
44355
  const dataDir = deps.dataDir ?? getFleetDataDir();
43346
44356
  initStore(dataDir);
43347
- const durablePaths = createConsoleDataPaths({ fleetDataDir: dataDir });
44357
+ const durablePaths = createConsoleDataPaths({ fleetDataDir: deps.dataDir });
43348
44358
  const durableStateStore = createConsoleDurableStateStore({ paths: durablePaths });
43349
44359
  const authEnvResolver = (cli) => resolveAuthEnv(cli, { authService: infraServices.authService });
43350
44360
  const ownsAgentRuntime = deps.agentRuntime === void 0;
@@ -43423,9 +44433,11 @@ function createConsoleServer(deps = {}) {
43423
44433
  let server = null;
43424
44434
  let loopbackServer = null;
43425
44435
  let lockHandle = null;
44436
+ let activeLockFile = null;
43426
44437
  let activeEndpoint = null;
43427
44438
  let agentRuntimeStopped = false;
43428
44439
  let consoleResourcesDisposed = false;
44440
+ let updateApplyInFlight = false;
43429
44441
  const carrierSettingsRouter = createCarrierSettingsRouter({
43430
44442
  registry: carrierRegistry,
43431
44443
  isAuthorized: isTerminalAuthorized,
@@ -43438,6 +44450,18 @@ function createConsoleServer(deps = {}) {
43438
44450
  readJsonBody,
43439
44451
  writeJson
43440
44452
  });
44453
+ const agentCliDetector = deps.agentCliDetector ?? createDefaultAgentCliDetector();
44454
+ const agentCliRouter = createAgentCliRouter({
44455
+ detect: agentCliDetector.detect,
44456
+ writeJson
44457
+ });
44458
+ const modelAuthRouter = createModelAuthRouter({
44459
+ authService: infraServices.authService,
44460
+ validateApiKey: (cli, apiKey) => validateAuthKeyForCli(cli, apiKey),
44461
+ isAuthorized: isTerminalAuthorized,
44462
+ readJsonBody,
44463
+ writeJson
44464
+ });
43441
44465
  function handleRequest(req, res) {
43442
44466
  const pathname = getPathname(req);
43443
44467
  if (pathname === "/console/codex" || pathname.startsWith("/console/codex/")) {
@@ -43484,6 +44508,11 @@ function createConsoleServer(deps = {}) {
43484
44508
  runAsyncHandler(handleTerminalSessionAttention(req, res, decodeURIComponent(terminalSessionAttentionMatch[1] ?? "")), res);
43485
44509
  return;
43486
44510
  }
44511
+ const terminalSessionAutoNameMatch = pathname.match(/^\/terminal\/sessions\/([^/]+)\/auto-name$/);
44512
+ if (terminalSessionAutoNameMatch) {
44513
+ runAsyncHandler(handleTerminalSessionAutoName(req, res, decodeURIComponent(terminalSessionAutoNameMatch[1] ?? "")), res);
44514
+ return;
44515
+ }
43487
44516
  const terminalSessionItemMatch = pathname.match(/^\/terminal\/sessions\/([^/]+)$/);
43488
44517
  if (terminalSessionItemMatch) {
43489
44518
  runAsyncHandler(handleTerminalSessionItem(req, res, decodeURIComponent(terminalSessionItemMatch[1] ?? "")), res);
@@ -43507,6 +44536,10 @@ function createConsoleServer(deps = {}) {
43507
44536
  handleObserverStatus(req, res);
43508
44537
  return;
43509
44538
  }
44539
+ if (pathname === "/update/apply") {
44540
+ runAsyncHandler(handleUpdateApply(req, res), res);
44541
+ return;
44542
+ }
43510
44543
  if (pathname === "/observer/carriers") {
43511
44544
  handleObserverCarriers(req, res);
43512
44545
  return;
@@ -43519,6 +44552,14 @@ function createConsoleServer(deps = {}) {
43519
44552
  runAsyncBooleanHandler(globalSettingsRouter({ req, res, pathname }), res);
43520
44553
  return;
43521
44554
  }
44555
+ if (pathname === "/agent-cli" || pathname.startsWith("/agent-cli/")) {
44556
+ runAsyncBooleanHandler(agentCliRouter({ req, res, pathname }), res);
44557
+ return;
44558
+ }
44559
+ if (pathname === "/model-auth" || pathname.startsWith("/model-auth/")) {
44560
+ runAsyncBooleanHandler(modelAuthRouter({ req, res, pathname }), res);
44561
+ return;
44562
+ }
43522
44563
  if (pathname === "/observer/tenants") {
43523
44564
  handleObserverWorkspaces(req, res);
43524
44565
  return;
@@ -43593,9 +44634,31 @@ function createConsoleServer(deps = {}) {
43593
44634
  writeJson(res, 404, { error: "terminal_session_not_found" });
43594
44635
  return;
43595
44636
  }
43596
- observability.notifySessionAttention(session);
44637
+ const body = await readJsonBody(req);
44638
+ observability.notifySessionAttention(session, normalizeAttentionReason(body?.reason));
43597
44639
  writeJson(res, 200, { ok: true });
43598
44640
  }
44641
+ async function handleTerminalSessionAutoName(req, res, sessionId) {
44642
+ if (req.method !== "POST") {
44643
+ writeJson(res, 405, { error: "Method not allowed" });
44644
+ return;
44645
+ }
44646
+ const token = lockHandle?.payload.token;
44647
+ if (!token || req.headers.authorization !== `Bearer ${token}`) {
44648
+ writeJson(res, 401, { error: "Unauthorized" });
44649
+ return;
44650
+ }
44651
+ const body = await readJsonBody(req);
44652
+ const label = deriveOperationLabel(body?.prompt);
44653
+ const result = observability.autoNameTerminalSession(sessionId, label);
44654
+ if (result?.renamed) {
44655
+ observability.notifySessionUpdated(result.session);
44656
+ }
44657
+ if (result?.changed) {
44658
+ persistDurableState();
44659
+ }
44660
+ writeJson(res, 200, { ok: true, renamed: result?.renamed === true });
44661
+ }
43599
44662
  async function handleTerminalTicket(req, res) {
43600
44663
  if (req.method !== "POST") {
43601
44664
  writeJson(res, 405, { error: "Method not allowed" });
@@ -43805,9 +44868,20 @@ function createConsoleServer(deps = {}) {
43805
44868
  writeJson(res, 503, { error: "terminal_unavailable" });
43806
44869
  }
43807
44870
  }
44871
+ async function buildAgentCliLaunchMetadata() {
44872
+ const metadata = getAgentCliMetadata();
44873
+ if ((process.env.FLEET_TERMINAL_CMD ?? "").trim().length > 0) {
44874
+ return metadata.map((meta3) => ({ id: meta3.id, label: meta3.label, available: true, signedIn: true }));
44875
+ }
44876
+ const [detected, modelAuth] = await Promise.all([
44877
+ agentCliDetector.detect(),
44878
+ buildModelAuthState(infraServices.authService)
44879
+ ]);
44880
+ return combineAgentCliLaunchMetadata(metadata, detected, modelAuth.providers);
44881
+ }
43808
44882
  async function handleObserverTheaters(req, res) {
43809
44883
  if (req.method === "GET") {
43810
- writeJson(res, 200, { theaters: listTheaterInfos(), agentClis: getAgentCliMetadata() });
44884
+ writeJson(res, 200, { theaters: listTheaterInfos(), agentClis: await buildAgentCliLaunchMetadata() });
43811
44885
  return;
43812
44886
  }
43813
44887
  if (req.method !== "POST") {
@@ -43877,7 +44951,14 @@ function createConsoleServer(deps = {}) {
43877
44951
  await createTerminalSessionForCwd(theater.path, res, cliId);
43878
44952
  }
43879
44953
  async function createTerminalSessionForCwd(cwd, res, cliId) {
43880
- const sessionId = crypto4.randomUUID();
44954
+ if (cliId) {
44955
+ const meta3 = (await buildAgentCliLaunchMetadata()).find((entry) => entry.id === cliId);
44956
+ if (!meta3 || !meta3.available || !meta3.signedIn) {
44957
+ writeJson(res, 409, { error: "agent_cli_unavailable" });
44958
+ return;
44959
+ }
44960
+ }
44961
+ const sessionId = crypto3.randomUUID();
43881
44962
  const session = observability.createPendingTerminalSession({ sessionId, cwd, cliId });
43882
44963
  try {
43883
44964
  await terminalSessions.createSession({ sessionId, cwd, cliId });
@@ -43906,6 +44987,69 @@ function createConsoleServer(deps = {}) {
43906
44987
  };
43907
44988
  writeJson(res, 200, payload);
43908
44989
  }
44990
+ async function handleUpdateApply(req, res) {
44991
+ if (req.method !== "POST") {
44992
+ writeJson(res, 405, { error: "Method not allowed" });
44993
+ return;
44994
+ }
44995
+ if (!isExactConsoleOrigin(req)) {
44996
+ writeJson(res, 401, { error: "unauthorized" });
44997
+ return;
44998
+ }
44999
+ const body = await readJsonBody(req);
45000
+ if (body === null && requestHasBody(req)) {
45001
+ writeJson(res, 400, { error: "invalid_update_apply_body" });
45002
+ return;
45003
+ }
45004
+ if (body !== null && (!isPlainObject2(body) || hasForbiddenUpdateApplyBodyKeys(body))) {
45005
+ writeJson(res, 400, { error: "invalid_update_apply_body" });
45006
+ return;
45007
+ }
45008
+ if (channel === "local") {
45009
+ writeJson(res, 403, { error: "local_channel" });
45010
+ return;
45011
+ }
45012
+ if (updateApplyInFlight) {
45013
+ writeJson(res, 409, { error: "update_already_in_progress" });
45014
+ return;
45015
+ }
45016
+ if (terminalSessions.hasLiveSessions()) {
45017
+ writeJson(res, 409, { error: "active_terminal_sessions" });
45018
+ return;
45019
+ }
45020
+ const freshStatus = await updateCheck.refresh({ force: true });
45021
+ if (!freshStatus.updateAvailable || !freshStatus.latestVersion) {
45022
+ writeJson(res, 409, { error: "update_not_available" });
45023
+ return;
45024
+ }
45025
+ const handle = lockHandle;
45026
+ if (!handle || !activeEndpoint || !activeLockFile) {
45027
+ writeJson(res, 503, { error: "console_not_ready" });
45028
+ return;
45029
+ }
45030
+ updateApplyInFlight = true;
45031
+ try {
45032
+ await updateApply.start({
45033
+ currentEndpoint: activeEndpoint,
45034
+ currentPackageRoot: release.packageRoot,
45035
+ currentPid: process.pid,
45036
+ dataDir: durablePaths.dir,
45037
+ lockFile: activeLockFile,
45038
+ targetVersion: freshStatus.latestVersion
45039
+ });
45040
+ } catch {
45041
+ updateApplyInFlight = false;
45042
+ writeJson(res, 503, { error: "update_worker_unavailable" });
45043
+ return;
45044
+ }
45045
+ res.once("finish", () => {
45046
+ setImmediate(() => {
45047
+ void stopAfterAcceptedUpdateApply();
45048
+ });
45049
+ });
45050
+ const payload = { status: "accepted" };
45051
+ writeJson(res, 202, payload);
45052
+ }
43909
45053
  function handleObserverCarriers(_req, res) {
43910
45054
  writeJson(res, 200, {
43911
45055
  carriers: readCarrierStatusEntries(carrierRegistry).map(toCarrierReadinessEntry)
@@ -43949,6 +45093,10 @@ function createConsoleServer(deps = {}) {
43949
45093
  if (!lockHandle) return false;
43950
45094
  return isAllowedTerminalOrigin(req, lockHandle.payload.port ?? port);
43951
45095
  }
45096
+ function isExactConsoleOrigin(req) {
45097
+ if (!lockHandle) return false;
45098
+ return req.headers.origin === `http://127.0.0.1:${lockHandle.payload.port ?? port}`;
45099
+ }
43952
45100
  function listVisibleWorkspaces(requestedTenantId) {
43953
45101
  if (requestedTenantId) {
43954
45102
  const workspace = observability.getWorkspace(requestedTenantId);
@@ -44000,6 +45148,13 @@ function createConsoleServer(deps = {}) {
44000
45148
  await agentRuntime.cleanup();
44001
45149
  agentRuntimeStopped = true;
44002
45150
  }
45151
+ async function stopAfterAcceptedUpdateApply() {
45152
+ try {
45153
+ await stopServer();
45154
+ } catch (error51) {
45155
+ console.warn(`[fleet-console] Update apply shutdown failed: ${error51 instanceof Error ? error51.message : String(error51)}`);
45156
+ }
45157
+ }
44003
45158
  async function cleanupAfterFailedStart() {
44004
45159
  const current = server;
44005
45160
  const currentLoopback = loopbackServer;
@@ -44007,6 +45162,7 @@ function createConsoleServer(deps = {}) {
44007
45162
  server = null;
44008
45163
  loopbackServer = null;
44009
45164
  lockHandle = null;
45165
+ activeLockFile = null;
44010
45166
  activeEndpoint = null;
44011
45167
  await Promise.all([
44012
45168
  closeHttpServer(current),
@@ -44097,7 +45253,35 @@ function createConsoleServer(deps = {}) {
44097
45253
  if (operation.providerSession) observability.updateTerminalSessionProviderSession(operation.sessionId, operation.providerSession);
44098
45254
  }
44099
45255
  }
44100
- return {
45256
+ async function stopServer() {
45257
+ const current = server;
45258
+ const currentLoopback = loopbackServer;
45259
+ const currentLock = lockHandle;
45260
+ let cleanupError;
45261
+ server = null;
45262
+ loopbackServer = null;
45263
+ lockHandle = null;
45264
+ activeLockFile = null;
45265
+ activeEndpoint = null;
45266
+ try {
45267
+ await Promise.all([
45268
+ closeHttpServer(current),
45269
+ closeHttpServer(currentLoopback)
45270
+ ]);
45271
+ await terminalSessions.stop();
45272
+ if (!agentRuntimeStopped) {
45273
+ try {
45274
+ if (ownsAgentRuntime) await cleanupOwnedAgentRuntime();
45275
+ } catch (error51) {
45276
+ cleanupError = error51;
45277
+ }
45278
+ }
45279
+ } finally {
45280
+ disposeConsoleResources(currentLock);
45281
+ }
45282
+ if (cleanupError) throw cleanupError;
45283
+ }
45284
+ const returnedServer = {
44101
45285
  host,
44102
45286
  port,
44103
45287
  async start(lockPaths) {
@@ -44117,6 +45301,7 @@ function createConsoleServer(deps = {}) {
44117
45301
  server = srv;
44118
45302
  loopbackServer = localLoopbackServer;
44119
45303
  lockHandle = lock.writeLock({ dir: lockPaths.dir, lockFile: lockPaths.lockFile, pid: process.pid, port: actualPort, endpoint, version: version2 });
45304
+ activeLockFile = lockPaths.lockFile;
44120
45305
  activeEndpoint = endpoint;
44121
45306
  resolve();
44122
45307
  } catch (err) {
@@ -44137,40 +45322,10 @@ function createConsoleServer(deps = {}) {
44137
45322
  return activeEndpoint;
44138
45323
  },
44139
45324
  async stop() {
44140
- const current = server;
44141
- const currentLoopback = loopbackServer;
44142
- const currentLock = lockHandle;
44143
- let cleanupError;
44144
- server = null;
44145
- loopbackServer = null;
44146
- lockHandle = null;
44147
- activeEndpoint = null;
44148
- try {
44149
- await Promise.all([
44150
- closeHttpServer(current),
44151
- closeHttpServer(currentLoopback)
44152
- ]);
44153
- await terminalSessions.stop();
44154
- if (!agentRuntimeStopped) {
44155
- try {
44156
- if (ownsAgentRuntime) await cleanupOwnedAgentRuntime();
44157
- } catch (error51) {
44158
- cleanupError = error51;
44159
- }
44160
- }
44161
- } finally {
44162
- disposeConsoleResources(currentLock);
44163
- }
44164
- if (cleanupError) throw cleanupError;
45325
+ await stopServer();
44165
45326
  }
44166
45327
  };
44167
- }
44168
- function readConsoleChannel() {
44169
- try {
44170
- return readFleetConsoleRelease().channel;
44171
- } catch {
44172
- return "unknown";
44173
- }
45328
+ return returnedServer;
44174
45329
  }
44175
45330
  function resolveCarrierEventOrigin(event, jobOriginById) {
44176
45331
  const originSessionId = event.originSessionId;
@@ -44261,6 +45416,14 @@ function terminalFolderListStatus(error51) {
44261
45416
  function isPlainObject2(value) {
44262
45417
  return typeof value === "object" && value !== null && !Array.isArray(value);
44263
45418
  }
45419
+ function hasForbiddenUpdateApplyBodyKeys(body) {
45420
+ return Object.keys(body).some((key) => UPDATE_APPLY_FORBIDDEN_BODY_KEYS.has(key));
45421
+ }
45422
+ function requestHasBody(req) {
45423
+ const contentLength = req.headers["content-length"];
45424
+ if (typeof contentLength === "string" && contentLength !== "0") return true;
45425
+ return req.headers["transfer-encoding"] !== void 0;
45426
+ }
44264
45427
  async function readJsonBody(req) {
44265
45428
  const chunks = [];
44266
45429
  let total = 0;
@@ -44320,9 +45483,9 @@ function isAllowedTerminalOrigin(req, expectedPort) {
44320
45483
  return origin === `http://127.0.0.1:${expectedPort}`;
44321
45484
  }
44322
45485
  var CAPTURE_TEMP_PREFIX = ".capture.";
44323
- async function runCaptureSessionHook(provider, env = process7.env) {
45486
+ async function runCaptureSessionHook(provider, env = process9.env) {
44324
45487
  return captureSession({
44325
- diagnostics: process7.stderr,
45488
+ diagnostics: process9.stderr,
44326
45489
  env,
44327
45490
  input: await readStdin(),
44328
45491
  provider
@@ -44339,12 +45502,12 @@ function captureSession(options) {
44339
45502
  }
44340
45503
  function captureSessionStrict(options) {
44341
45504
  const provider = parseProvider(options.provider);
44342
- const fleetSessionId = readFleetSessionId(options.env ?? process7.env);
45505
+ const fleetSessionId = readFleetSessionId(options.env ?? process9.env);
44343
45506
  const input = parseHookInput(options.input ?? "");
44344
45507
  const providerSession = toProviderSession(provider, input, options.now ?? (() => /* @__PURE__ */ new Date()));
44345
45508
  const capturesDir = (options.paths ?? createConsoleDataPaths()).capturesDir;
44346
- const finalPath = path93__default.join(capturesDir, `${fleetSessionId}.json`);
44347
- const tempPath = path93__default.join(capturesDir, `${CAPTURE_TEMP_PREFIX}${fleetSessionId}.${process7.pid}.${Date.now()}.tmp`);
45509
+ const finalPath = path92__default.join(capturesDir, `${fleetSessionId}.json`);
45510
+ const tempPath = path92__default.join(capturesDir, `${CAPTURE_TEMP_PREFIX}${fleetSessionId}.${process9.pid}.${Date.now()}.tmp`);
44348
45511
  fs7__default.mkdirSync(capturesDir, { recursive: true, mode: 448 });
44349
45512
  fs7__default.writeFileSync(tempPath, `${JSON.stringify(providerSession, null, 2)}
44350
45513
  `, { mode: 384 });
@@ -44358,7 +45521,7 @@ function parseProvider(value) {
44358
45521
  function readFleetSessionId(env) {
44359
45522
  const value = env.FLEET_CONSOLE_SESSION_ID;
44360
45523
  if (!value) throw new Error("missing_fleet_session_id");
44361
- if (path93__default.basename(value) !== value || value.includes(path93__default.sep) || value.includes(path93__default.posix.sep)) {
45524
+ if (path92__default.basename(value) !== value || value.includes(path92__default.sep) || value.includes(path92__default.posix.sep)) {
44362
45525
  throw new Error("invalid_fleet_session_id");
44363
45526
  }
44364
45527
  return value;
@@ -44384,11 +45547,11 @@ function toProviderSession(provider, input, now) {
44384
45547
  function readStdin() {
44385
45548
  return new Promise((resolve, reject) => {
44386
45549
  const chunks = [];
44387
- process7.stdin.on("data", (chunk) => {
45550
+ process9.stdin.on("data", (chunk) => {
44388
45551
  chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
44389
45552
  });
44390
- process7.stdin.on("error", reject);
44391
- process7.stdin.on("end", () => resolve(Buffer.concat(chunks).toString("utf8")));
45553
+ process9.stdin.on("error", reject);
45554
+ process9.stdin.on("end", () => resolve(Buffer.concat(chunks).toString("utf8")));
44392
45555
  });
44393
45556
  }
44394
45557
  function createConsoleStalePolicy(deps = {}) {
@@ -44404,7 +45567,7 @@ function createConsoleStalePolicy(deps = {}) {
44404
45567
  return { isBuildStale };
44405
45568
  }
44406
45569
  var TURN_POST_TIMEOUT_MS = 1500;
44407
- async function runTurnStateHook(phase, env = process7.env, options = {}) {
45570
+ async function runTurnStateHook(phase, env = process9.env, options = {}) {
44408
45571
  try {
44409
45572
  await postTurnState(phase, env, options);
44410
45573
  } catch {
@@ -44433,12 +45596,66 @@ async function postTurnState(phase, env, options) {
44433
45596
  clearTimeout(timer);
44434
45597
  }
44435
45598
  }
45599
+ var AUTO_NAME_POST_TIMEOUT_MS = 1500;
45600
+ var MAX_PROMPT_PAYLOAD = 2e3;
45601
+ async function runAutoNameHook(env = process9.env, options = {}) {
45602
+ try {
45603
+ await postAutoName(env, options);
45604
+ } catch {
45605
+ }
45606
+ }
45607
+ async function postAutoName(env, options) {
45608
+ const sessionId = env.FLEET_CONSOLE_SESSION_ID;
45609
+ if (!sessionId) return;
45610
+ const prompt = extractPrompt(options.input ?? await readStdin2());
45611
+ if (prompt === null) return;
45612
+ const paths = createConsolePaths({ env });
45613
+ const lock = createConsoleLock().readLock(paths.lockFile);
45614
+ if (!lock) return;
45615
+ const fetchImpl = options.fetchImpl ?? fetch;
45616
+ const controller = new AbortController();
45617
+ const timer = setTimeout(() => controller.abort(), options.timeoutMs ?? AUTO_NAME_POST_TIMEOUT_MS);
45618
+ try {
45619
+ await fetchImpl(`${lock.endpoint}terminal/sessions/${encodeURIComponent(sessionId)}/auto-name`, {
45620
+ method: "POST",
45621
+ headers: {
45622
+ authorization: `Bearer ${lock.token}`,
45623
+ "content-type": "application/json"
45624
+ },
45625
+ body: JSON.stringify({ prompt }),
45626
+ signal: controller.signal
45627
+ });
45628
+ } finally {
45629
+ clearTimeout(timer);
45630
+ }
45631
+ }
45632
+ function extractPrompt(input) {
45633
+ try {
45634
+ const parsed = JSON.parse(input);
45635
+ if (typeof parsed !== "object" || parsed === null) return null;
45636
+ const value = parsed.prompt;
45637
+ if (typeof value !== "string" || value.trim().length === 0) return null;
45638
+ return value.slice(0, MAX_PROMPT_PAYLOAD);
45639
+ } catch {
45640
+ return null;
45641
+ }
45642
+ }
45643
+ function readStdin2() {
45644
+ return new Promise((resolve, reject) => {
45645
+ const chunks = [];
45646
+ process9.stdin.on("data", (chunk) => {
45647
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
45648
+ });
45649
+ process9.stdin.on("error", reject);
45650
+ process9.stdin.on("end", () => resolve(Buffer.concat(chunks).toString("utf8")));
45651
+ });
45652
+ }
44436
45653
 
44437
45654
  // src/cli.ts
44438
45655
  var FIXED_HOST = "127.0.0.1";
44439
45656
  var HELP_BANNER_INDENT = " ";
44440
45657
  var DEFAULT_HELP_RELEASE = "local";
44441
- var CONSOLE_HOOK_COMMANDS = /* @__PURE__ */ new Set(["capture-session", "subagents-context", "turn-start", "turn-end", "attention"]);
45658
+ var CONSOLE_HOOK_COMMANDS = /* @__PURE__ */ new Set(["capture-session", "subagents-context", "turn-start", "turn-end", "attention", "auto-name"]);
44442
45659
  function parseConsoleCliMode(argv) {
44443
45660
  if (argv.length === 0) return "start";
44444
45661
  const [first, ...rest] = argv;
@@ -44472,6 +45689,7 @@ function parseConsoleHookCommand(argv) {
44472
45689
  if (commandName === "turn-start" && rest.length === 0) return { command: "turn-start" };
44473
45690
  if (commandName === "turn-end" && rest.length === 0) return { command: "turn-end" };
44474
45691
  if (commandName === "attention" && rest.length === 0) return { command: "attention" };
45692
+ if (commandName === "auto-name" && rest.length === 0) return { command: "auto-name" };
44475
45693
  if (commandName === "capture-session" && rest.length === 1 && rest[0]) return { command: "capture-session", provider: rest[0] };
44476
45694
  throw new Error("Unknown fleet-console hook command");
44477
45695
  }
@@ -44535,11 +45753,14 @@ function buildWikiHelpText(options = {}) {
44535
45753
  return colorEnabled ? text : stripAnsi(text);
44536
45754
  }
44537
45755
  function createConsoleDaemonLifecycle(deps = {}) {
44538
- const env = deps.env ?? process7.env;
44539
- const execPath = deps.execPath ?? process7.execPath;
44540
- const serverModulePath = deps.serverModulePath ?? resolveDefaultServerModulePath();
45756
+ const env = deps.env ?? process9.env;
45757
+ const execPath = deps.execPath ?? process9.execPath;
45758
+ const serverModulePath = deps.serverModulePath ?? resolveDefaultServerModulePath2();
44541
45759
  const spawnDetached = deps.spawnDetached ?? ((bin, args, options) => {
44542
- spawn(bin, [...args], options).unref();
45760
+ const child = spawn(bin, [...args], options);
45761
+ child.once("error", () => {
45762
+ });
45763
+ child.unref();
44543
45764
  });
44544
45765
  const sleep = deps.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
44545
45766
  const paths = createConsolePaths({ env });
@@ -44550,10 +45771,10 @@ function createConsoleDaemonLifecycle(deps = {}) {
44550
45771
  const server = createConsoleServer();
44551
45772
  await server.start(paths);
44552
45773
  await new Promise((resolve) => {
44553
- process7.once("SIGTERM", () => {
45774
+ process9.once("SIGTERM", () => {
44554
45775
  void server.stop().finally(resolve);
44555
45776
  });
44556
- process7.once("SIGINT", () => {
45777
+ process9.once("SIGINT", () => {
44557
45778
  void server.stop().finally(resolve);
44558
45779
  });
44559
45780
  });
@@ -44567,14 +45788,14 @@ function createConsoleDaemonLifecycle(deps = {}) {
44567
45788
  const payload = readTrustedLock();
44568
45789
  if (!payload) return;
44569
45790
  try {
44570
- process7.kill(payload.pid, "SIGTERM");
45791
+ process9.kill(payload.pid, "SIGTERM");
44571
45792
  } catch (err) {
44572
45793
  if (err.code !== "ESRCH") throw err;
44573
45794
  }
44574
45795
  await sleep(200);
44575
45796
  try {
44576
- process7.kill(payload.pid, 0);
44577
- process7.kill(payload.pid, "SIGKILL");
45797
+ process9.kill(payload.pid, 0);
45798
+ process9.kill(payload.pid, "SIGKILL");
44578
45799
  } catch (err) {
44579
45800
  if (err.code !== "ESRCH") throw err;
44580
45801
  }
@@ -44589,7 +45810,7 @@ function createConsoleDaemonLifecycle(deps = {}) {
44589
45810
  if (typeof probeResult.health?.workspaceCount === "number" && probeResult.health.workspaceCount > 0) return current.endpoint;
44590
45811
  }
44591
45812
  if (current) await stop();
44592
- spawnDetached(execPath, [serverModulePath, "serve"], { detached: true, env, stdio: "ignore" });
45813
+ spawnDetached(execPath, [serverModulePath, "serve"], { detached: true, env, stdio: "ignore", windowsHide: true });
44593
45814
  for (let i = 0; i < 30; i += 1) {
44594
45815
  await sleep(100);
44595
45816
  const next = await probe();
@@ -44640,7 +45861,7 @@ async function openFleetWikiWorkspace(options) {
44640
45861
  authorization: `Bearer ${status.lock.token}`,
44641
45862
  "content-type": "application/json"
44642
45863
  },
44643
- body: JSON.stringify({ cwd: path93__default.resolve(options.cwd) })
45864
+ body: JSON.stringify({ cwd: path92__default.resolve(options.cwd) })
44644
45865
  });
44645
45866
  if (!response.ok) {
44646
45867
  throw new Error(`Fleet Console Codex workspace registration failed: ${response.status} ${await response.text()}`);
@@ -44681,59 +45902,63 @@ async function runConsoleRestart(deps = {}) {
44681
45902
  return openFleetConsole({ lifecycle, openBrowser: deps.openBrowser });
44682
45903
  }
44683
45904
  async function main() {
44684
- if (process7.argv[2] === "serve") {
45905
+ if (process9.argv[2] === "serve") {
44685
45906
  await createConsoleDaemonLifecycle().runServer();
44686
45907
  return;
44687
45908
  }
44688
- if (process7.argv[2] === "hook") {
44689
- const hookCommand = parseConsoleHookCommand(process7.argv.slice(3));
45909
+ if (process9.argv[2] === "hook") {
45910
+ const hookCommand = parseConsoleHookCommand(process9.argv.slice(3));
44690
45911
  if (hookCommand.command === "subagents-context") {
44691
- process7.stdout.write(`${runSubagentsContextHook(process7.env)}
45912
+ process9.stdout.write(`${runSubagentsContextHook(process9.env)}
44692
45913
  `);
44693
45914
  return;
44694
45915
  }
44695
45916
  if (hookCommand.command === "turn-start" || hookCommand.command === "turn-end") {
44696
- await runTurnStateHook(hookCommand.command === "turn-start" ? "start" : "end", process7.env);
45917
+ await runTurnStateHook(hookCommand.command === "turn-start" ? "start" : "end", process9.env);
44697
45918
  return;
44698
45919
  }
44699
45920
  if (hookCommand.command === "attention") {
44700
- await runAttentionHook(process7.env);
45921
+ await runAttentionHook(process9.env);
45922
+ return;
45923
+ }
45924
+ if (hookCommand.command === "auto-name") {
45925
+ await runAutoNameHook(process9.env);
44701
45926
  return;
44702
45927
  }
44703
- await runCaptureSessionHook(hookCommand.provider, process7.env);
45928
+ await runCaptureSessionHook(hookCommand.provider, process9.env);
44704
45929
  return;
44705
45930
  }
44706
- if (process7.argv[2] === "codex") {
44707
- await mainWiki(process7.argv.slice(3));
45931
+ if (process9.argv[2] === "codex") {
45932
+ await mainWiki(process9.argv.slice(3));
44708
45933
  return;
44709
45934
  }
44710
- const mode = parseConsoleCliMode(process7.argv.slice(2));
45935
+ const mode = parseConsoleCliMode(process9.argv.slice(2));
44711
45936
  if (mode === "help") {
44712
- process7.stdout.write(`${buildConsoleHelpText({ env: process7.env, isTTY: process7.stdout.isTTY })}
45937
+ process9.stdout.write(`${buildConsoleHelpText({ env: process9.env, isTTY: process9.stdout.isTTY })}
44713
45938
  `);
44714
45939
  return;
44715
45940
  }
44716
45941
  if (mode === "status") {
44717
- process7.stdout.write(`${await runConsoleStatus()}
45942
+ process9.stdout.write(`${await runConsoleStatus()}
44718
45943
  `);
44719
45944
  return;
44720
45945
  }
44721
45946
  if (mode === "stop") {
44722
- process7.stdout.write(`${await runConsoleStop()}
45947
+ process9.stdout.write(`${await runConsoleStop()}
44723
45948
  `);
44724
45949
  return;
44725
45950
  }
44726
45951
  if (mode === "restart") {
44727
45952
  await runConsoleRestart();
44728
- process7.stdout.write("Fleet Console restarted.\n");
45953
+ process9.stdout.write("Fleet Console restarted.\n");
44729
45954
  return;
44730
45955
  }
44731
45956
  await openFleetConsole();
44732
- process7.stdout.write("Fleet Console opened.\n");
45957
+ process9.stdout.write("Fleet Console opened.\n");
44733
45958
  }
44734
- async function mainWiki(argv = process7.argv.slice(2)) {
45959
+ async function mainWiki(argv = process9.argv.slice(2)) {
44735
45960
  if (argv.includes("--help") || argv.includes("-h")) {
44736
- process7.stdout.write(`${buildWikiHelpText({ env: process7.env, isTTY: process7.stdout.isTTY })}
45961
+ process9.stdout.write(`${buildWikiHelpText({ env: process9.env, isTTY: process9.stdout.isTTY })}
44737
45962
  `);
44738
45963
  return;
44739
45964
  }
@@ -44745,19 +45970,19 @@ async function mainWiki(argv = process7.argv.slice(2)) {
44745
45970
  if (unsupported.length > 0) {
44746
45971
  throw new Error(`Unknown fleet wiki option: ${unsupported[0]}`);
44747
45972
  }
44748
- await openFleetWikiWorkspace({ cwd: process7.cwd() });
45973
+ await openFleetWikiWorkspace({ cwd: process9.cwd() });
44749
45974
  }
44750
- function resolveDefaultServerModulePath() {
45975
+ function resolveDefaultServerModulePath2() {
44751
45976
  const builtPath = new URL("../dist/cli.mjs", import.meta.url).pathname;
44752
45977
  if (fs7__default.existsSync(builtPath)) return builtPath;
44753
45978
  return fileURLToPath(import.meta.url);
44754
45979
  }
44755
- var isDirectRun = process7.argv[1] && path93__default.resolve(process7.argv[1]) === fileURLToPath(import.meta.url);
45980
+ var isDirectRun = process9.argv[1] && path92__default.resolve(process9.argv[1]) === fileURLToPath(import.meta.url);
44756
45981
  if (isDirectRun) {
44757
45982
  await main().catch((error51) => {
44758
- process7.stderr.write(`${error51 instanceof Error ? error51.message : String(error51)}
45983
+ process9.stderr.write(`${error51 instanceof Error ? error51.message : String(error51)}
44759
45984
  `);
44760
- process7.exitCode = 1;
45985
+ process9.exitCode = 1;
44761
45986
  });
44762
45987
  }
44763
45988