@dotobokuri/fleet-console 1.17.1 → 1.19.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 (68) hide show
  1. package/AGENTS.md +10 -9
  2. package/dist/cli.d.ts +13 -14
  3. package/dist/cli.mjs +1181 -2428
  4. package/dist/client/assets/SymbolsNerdFontMono-Regular-CoUzE12l.woff2 +0 -0
  5. package/dist/client/assets/{_baseUniq-B7sqIsqm.js → _baseUniq-C4_iQlZS.js} +1 -1
  6. package/dist/client/assets/{arc-CvtYLN8U.js → arc-BBAWxYi5.js} +1 -1
  7. package/dist/client/assets/{architectureDiagram-Q4EWVU46-rlI7pNrR.js → architectureDiagram-Q4EWVU46-_oQqhexV.js} +1 -1
  8. package/dist/client/assets/{blockDiagram-DXYQGD6D-nwx9BNRz.js → blockDiagram-DXYQGD6D-3xT9VFiD.js} +1 -1
  9. package/dist/client/assets/{c4Diagram-AHTNJAMY-CRL_0Ism.js → c4Diagram-AHTNJAMY-S-IMcMW2.js} +1 -1
  10. package/dist/client/assets/channel-5tV1napa.js +1 -0
  11. package/dist/client/assets/{chunk-4BX2VUAB-DEkncDR3.js → chunk-4BX2VUAB-tS9Ys0P9.js} +1 -1
  12. package/dist/client/assets/{chunk-4TB4RGXK-Bnot0Ti1.js → chunk-4TB4RGXK-YZgAG7SW.js} +1 -1
  13. package/dist/client/assets/{chunk-55IACEB6-EgKmMTlI.js → chunk-55IACEB6-m-CtqHoO.js} +1 -1
  14. package/dist/client/assets/{chunk-EDXVE4YY-BKiKnVQE.js → chunk-EDXVE4YY-yoymxaEV.js} +1 -1
  15. package/dist/client/assets/{chunk-FMBD7UC4-BRC398vL.js → chunk-FMBD7UC4-REUkrQAG.js} +1 -1
  16. package/dist/client/assets/{chunk-OYMX7WX6-D82gQaXN.js → chunk-OYMX7WX6-DzMuL105.js} +1 -1
  17. package/dist/client/assets/{chunk-QZHKN3VN-BYdI5fky.js → chunk-QZHKN3VN-DXFFll8-.js} +1 -1
  18. package/dist/client/assets/{chunk-YZCP3GAM-BhBgOoc0.js → chunk-YZCP3GAM-CmY7W-gg.js} +1 -1
  19. package/dist/client/assets/classDiagram-6PBFFD2Q-WDM904ap.js +1 -0
  20. package/dist/client/assets/classDiagram-v2-HSJHXN6E-WDM904ap.js +1 -0
  21. package/dist/client/assets/clone-BJg9p0cC.js +1 -0
  22. package/dist/client/assets/{cose-bilkent-S5V4N54A-J8dfEdWD.js → cose-bilkent-S5V4N54A-BupE-a40.js} +1 -1
  23. package/dist/client/assets/{dagre-KV5264BT-zGd_6_Kv.js → dagre-KV5264BT-Jn67LxMS.js} +1 -1
  24. package/dist/client/assets/{diagram-5BDNPKRD-BQpQGgZ3.js → diagram-5BDNPKRD-BAeFEORH.js} +1 -1
  25. package/dist/client/assets/{diagram-G4DWMVQ6-BbgPVITm.js → diagram-G4DWMVQ6-CnZrDABY.js} +1 -1
  26. package/dist/client/assets/{diagram-MMDJMWI5-lJsMf0Ic.js → diagram-MMDJMWI5-DefG-kXU.js} +1 -1
  27. package/dist/client/assets/{diagram-TYMM5635-BpEKTzOh.js → diagram-TYMM5635-BPkXKB-Q.js} +1 -1
  28. package/dist/client/assets/{erDiagram-SMLLAGMA-CHHVwJ_a.js → erDiagram-SMLLAGMA-Bi4jlild.js} +1 -1
  29. package/dist/client/assets/{flowDiagram-DWJPFMVM-Cun8a4NF.js → flowDiagram-DWJPFMVM-BoZyLO7h.js} +1 -1
  30. package/dist/client/assets/{ganttDiagram-T4ZO3ILL-CGCwH_yf.js → ganttDiagram-T4ZO3ILL-LgzSNjrh.js} +1 -1
  31. package/dist/client/assets/{gitGraphDiagram-UUTBAWPF-BkY4qdoV.js → gitGraphDiagram-UUTBAWPF-B4fH-hPT.js} +1 -1
  32. package/dist/client/assets/{graph-HbRzXQtt.js → graph-D3ZAYMLG.js} +1 -1
  33. package/dist/client/assets/index-DctP_CJP.css +1 -0
  34. package/dist/client/assets/index-vgEn_EkG.js +404 -0
  35. package/dist/client/assets/{infoDiagram-42DDH7IO-B21Xtz8v.js → infoDiagram-42DDH7IO-pENdunXd.js} +1 -1
  36. package/dist/client/assets/{ishikawaDiagram-UXIWVN3A-DiABngEH.js → ishikawaDiagram-UXIWVN3A-WakLHKte.js} +1 -1
  37. package/dist/client/assets/{journeyDiagram-VCZTEJTY-BKZ-Uivu.js → journeyDiagram-VCZTEJTY-CrqXKtzk.js} +1 -1
  38. package/dist/client/assets/{kanban-definition-6JOO6SKY-CoJzTtsH.js → kanban-definition-6JOO6SKY-DdSC9eJ-.js} +1 -1
  39. package/dist/client/assets/{layout-D5tmQpxt.js → layout-BI1Oko_a.js} +1 -1
  40. package/dist/client/assets/{linear-B_riNOXk.js → linear-KUjZtfMe.js} +1 -1
  41. package/dist/client/assets/{mermaid.core-CyRCP3U3.js → mermaid.core-DNlIf4_3.js} +4 -4
  42. package/dist/client/assets/{min-Cn8LZZXB.js → min-DCAecveI.js} +1 -1
  43. package/dist/client/assets/{mindmap-definition-QFDTVHPH-BN_7mZUt.js → mindmap-definition-QFDTVHPH-BSCyQA-4.js} +1 -1
  44. package/dist/client/assets/{pieDiagram-DEJITSTG-DPP2-sYA.js → pieDiagram-DEJITSTG-C_1I63z5.js} +1 -1
  45. package/dist/client/assets/{quadrantDiagram-34T5L4WZ-CQ_oo-f9.js → quadrantDiagram-34T5L4WZ-CtqeYPcA.js} +1 -1
  46. package/dist/client/assets/{requirementDiagram-MS252O5E-BkGq7nxD.js → requirementDiagram-MS252O5E-Cpakdg-s.js} +1 -1
  47. package/dist/client/assets/{sankeyDiagram-XADWPNL6-BVcoktBR.js → sankeyDiagram-XADWPNL6-CK_eMH3e.js} +1 -1
  48. package/dist/client/assets/{sequenceDiagram-FGHM5R23-B5rr_VYJ.js → sequenceDiagram-FGHM5R23-D2YygHqF.js} +1 -1
  49. package/dist/client/assets/{stateDiagram-FHFEXIEX-BV8RqzB9.js → stateDiagram-FHFEXIEX-DEDhnbhU.js} +1 -1
  50. package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-ji50PgJQ.js +1 -0
  51. package/dist/client/assets/{timeline-definition-GMOUNBTQ-CJ8TM-3t.js → timeline-definition-GMOUNBTQ-Brgny70W.js} +1 -1
  52. package/dist/client/assets/{vennDiagram-DHZGUBPP-BETSq-Pu.js → vennDiagram-DHZGUBPP-B1I5E8Hy.js} +1 -1
  53. package/dist/client/assets/{wardley-RL74JXVD-CyT2qapq.js → wardley-RL74JXVD-P0VCYfKI.js} +1 -1
  54. package/dist/client/assets/{wardleyDiagram-NUSXRM2D-CWHaiUEG.js → wardleyDiagram-NUSXRM2D-DhYC5Sus.js} +1 -1
  55. package/dist/client/assets/{xychartDiagram-5P7HB3ND-oVPlZ_Yn.js → xychartDiagram-5P7HB3ND-ByJX99rJ.js} +1 -1
  56. package/dist/client/index.html +2 -2
  57. package/dist/fleet-plugins/diff/routes.mjs +260 -32
  58. package/dist/fleet-plugins/file-explorer/routes.mjs +1 -1
  59. package/dist/fleet-plugins/skills/routes.mjs +108 -201
  60. package/dist/fleet-plugins/terminal/routes.mjs +821 -1283
  61. package/package.json +1 -1
  62. package/dist/client/assets/channel-Ct9EqqyG.js +0 -1
  63. package/dist/client/assets/classDiagram-6PBFFD2Q-CPMS8Qpo.js +0 -1
  64. package/dist/client/assets/classDiagram-v2-HSJHXN6E-CPMS8Qpo.js +0 -1
  65. package/dist/client/assets/clone-C5XNYXHD.js +0 -1
  66. package/dist/client/assets/index-CfNSyAUJ.css +0 -1
  67. package/dist/client/assets/index-CzCMC0e-.js +0 -402
  68. package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-Bx_fpQWQ.js +0 -1
@@ -1,16 +1,16 @@
1
1
  #!/usr/bin/env node
2
- import * as fs8 from 'fs';
3
- import fs8__default, { existsSync, mkdtempSync, writeFileSync, mkdirSync, rmSync, chmodSync, renameSync, readdirSync, readFileSync, constants, openSync, closeSync, realpathSync, fstatSync, lstatSync, unlinkSync, statSync } from 'fs';
2
+ import * as fs2 from 'fs';
3
+ import fs2__default, { existsSync, accessSync, constants, mkdtempSync, writeFileSync, mkdirSync, rmSync, chmodSync, renameSync, readdirSync, readFileSync, openSync, closeSync, realpathSync, fstatSync, lstatSync, unlinkSync, statSync } from 'fs';
4
4
  import * as path27 from 'path';
5
5
  import path27__default, { dirname } from 'path';
6
6
  import * as os3 from 'os';
7
- import os3__default from 'os';
7
+ import os3__default, { homedir } from 'os';
8
+ import crypto4, { createHash, randomUUID } from 'crypto';
9
+ import process5 from 'process';
8
10
  import { EventEmitter } from 'events';
9
11
  import { mkdir, writeFile, access, readFile, stat, readdir, appendFile, rename, rm } from 'fs/promises';
10
- import { execFile, execSync, spawn, spawnSync } from 'child_process';
12
+ import { execFile, spawn, execSync, spawnSync } from 'child_process';
11
13
  import { Writable, Readable } from 'stream';
12
- import crypto3, { createHash, randomUUID } from 'crypto';
13
- import process4 from 'process';
14
14
  import http from 'http';
15
15
  import { fileURLToPath, pathToFileURL } from 'url';
16
16
  import { createRequire } from 'module';
@@ -44,10 +44,10 @@ function getFleetDataDir() {
44
44
  }
45
45
  var SECURE_DIR_MODE = 448;
46
46
  var SECURE_FILE_MODE = 384;
47
- var NOFOLLOW_FLAG = fs8.constants.O_NOFOLLOW ?? 0;
47
+ var NOFOLLOW_FLAG = fs2.constants.O_NOFOLLOW ?? 0;
48
48
  function safeLstat(targetPath) {
49
49
  try {
50
- return fs8.lstatSync(targetPath);
50
+ return fs2.lstatSync(targetPath);
51
51
  } catch (error51) {
52
52
  if (error51.code === "ENOENT") {
53
53
  return null;
@@ -61,18 +61,18 @@ function ensureSafeDirectory(dirPath) {
61
61
  if (!stat3.isDirectory() || stat3.isSymbolicLink()) {
62
62
  throw new Error(`Unsafe Fleet directory: ${dirPath}`);
63
63
  }
64
- fs8.chmodSync(dirPath, SECURE_DIR_MODE);
64
+ fs2.chmodSync(dirPath, SECURE_DIR_MODE);
65
65
  return;
66
66
  }
67
- fs8.mkdirSync(dirPath, { recursive: true, mode: SECURE_DIR_MODE });
67
+ fs2.mkdirSync(dirPath, { recursive: true, mode: SECURE_DIR_MODE });
68
68
  const created = safeLstat(dirPath);
69
69
  if (!created?.isDirectory() || created.isSymbolicLink()) {
70
70
  throw new Error(`Unsafe Fleet directory: ${dirPath}`);
71
71
  }
72
- fs8.chmodSync(dirPath, SECURE_DIR_MODE);
72
+ fs2.chmodSync(dirPath, SECURE_DIR_MODE);
73
73
  }
74
74
 
75
- // ../../packages/fleet-infra/src/fs-store/atomic-write.ts
75
+ // ../../packages/core-infra/src/fs-store/atomic-write.ts
76
76
  var DEFAULT_MAX_ATTEMPTS = 10;
77
77
  var IGNORED_FSYNC_ERROR_CODES = /* @__PURE__ */ new Set(["EPERM", "EINVAL", "ENOSYS"]);
78
78
  function buildTempPath(filePath) {
@@ -88,17 +88,17 @@ function writeAtomicSync(filePath, content, options = {}) {
88
88
  const tempPath = buildTempPath(filePath);
89
89
  let tempCreated = false;
90
90
  try {
91
- fs8.writeFileSync(tempPath, content, { encoding: "utf-8", flag: "wx", mode });
91
+ fs2.writeFileSync(tempPath, content, { encoding: "utf-8", flag: "wx", mode });
92
92
  tempCreated = true;
93
93
  if (doFsync) {
94
- const fd = fs8.openSync(tempPath, "r");
94
+ const fd = fs2.openSync(tempPath, "r");
95
95
  try {
96
96
  fsyncSyncBestEffort(fd);
97
97
  } finally {
98
- fs8.closeSync(fd);
98
+ fs2.closeSync(fd);
99
99
  }
100
100
  }
101
- fs8.renameSync(tempPath, filePath);
101
+ fs2.renameSync(tempPath, filePath);
102
102
  return;
103
103
  } catch (error51) {
104
104
  const code = error51.code;
@@ -108,7 +108,7 @@ function writeAtomicSync(filePath, content, options = {}) {
108
108
  }
109
109
  if (tempCreated) {
110
110
  try {
111
- fs8.unlinkSync(tempPath);
111
+ fs2.unlinkSync(tempPath);
112
112
  } catch {
113
113
  }
114
114
  }
@@ -120,7 +120,7 @@ function writeAtomicSync(filePath, content, options = {}) {
120
120
  function cleanupTempFiles(dir, prefix, minAgeMs, now) {
121
121
  let entries;
122
122
  try {
123
- entries = fs8.readdirSync(dir);
123
+ entries = fs2.readdirSync(dir);
124
124
  } catch {
125
125
  return;
126
126
  }
@@ -130,9 +130,9 @@ function cleanupTempFiles(dir, prefix, minAgeMs, now) {
130
130
  }
131
131
  const tempPath = path27.join(dir, entry);
132
132
  try {
133
- const stat3 = fs8.lstatSync(tempPath);
133
+ const stat3 = fs2.lstatSync(tempPath);
134
134
  if (stat3?.isFile() && !stat3.isSymbolicLink() && now - stat3.mtimeMs >= minAgeMs) {
135
- fs8.unlinkSync(tempPath);
135
+ fs2.unlinkSync(tempPath);
136
136
  }
137
137
  } catch {
138
138
  }
@@ -144,7 +144,7 @@ function isIgnoredFsyncError(error51) {
144
144
  }
145
145
  function fsyncSyncBestEffort(fd) {
146
146
  try {
147
- fs8.fsyncSync(fd);
147
+ fs2.fsyncSync(fd);
148
148
  } catch (error51) {
149
149
  if (!isIgnoredFsyncError(error51)) {
150
150
  throw error51;
@@ -164,7 +164,7 @@ function withDirectoryLock(deps, operation) {
164
164
  const startedAt = now();
165
165
  while (true) {
166
166
  try {
167
- fs8.mkdirSync(deps.lockDir, { mode: 448 });
167
+ fs2.mkdirSync(deps.lockDir, { mode: 448 });
168
168
  writeLockOwner(deps.lockDir, ownerFileName, now());
169
169
  try {
170
170
  return operation();
@@ -184,7 +184,7 @@ function withDirectoryLock(deps, operation) {
184
184
  }
185
185
  function releaseLock(lockDir) {
186
186
  try {
187
- fs8.rmSync(lockDir, { recursive: true, force: true });
187
+ fs2.rmSync(lockDir, { recursive: true, force: true });
188
188
  } catch {
189
189
  }
190
190
  }
@@ -194,14 +194,14 @@ function recoverStaleLock(lockDir, ownerFileName, now, staleLockMs) {
194
194
  if (!isRecoverableSnapshot(initialSnapshot, now, staleLockMs)) return;
195
195
  const quarantineDir = buildQuarantinePath(lockDir);
196
196
  try {
197
- fs8.renameSync(lockDir, quarantineDir);
197
+ fs2.renameSync(lockDir, quarantineDir);
198
198
  } catch {
199
199
  return;
200
200
  }
201
201
  try {
202
202
  const quarantinedSnapshot = readLockSnapshot(quarantineDir, ownerFileName);
203
203
  if (sameLockSnapshot(initialSnapshot, quarantinedSnapshot) && isRecoverableSnapshot(quarantinedSnapshot, now, staleLockMs)) {
204
- fs8.rmSync(quarantineDir, { recursive: true, force: true });
204
+ fs2.rmSync(quarantineDir, { recursive: true, force: true });
205
205
  } else {
206
206
  restoreQuarantinedLock(quarantineDir, lockDir);
207
207
  }
@@ -215,7 +215,7 @@ function recoverStaleLock(lockDir, ownerFileName, now, staleLockMs) {
215
215
  }
216
216
  }
217
217
  function readLockSnapshot(lockDir, ownerFileName) {
218
- const stat3 = fs8.lstatSync(lockDir);
218
+ const stat3 = fs2.lstatSync(lockDir);
219
219
  if (stat3.isSymbolicLink()) {
220
220
  return { owner: null, mtimeMs: 0 };
221
221
  }
@@ -236,7 +236,7 @@ function writeLockOwner(lockDir, ownerFileName, startedAt) {
236
236
  };
237
237
  const ownerPath = path27.join(lockDir, ownerFileName);
238
238
  try {
239
- fs8.writeFileSync(ownerPath, JSON.stringify(owner), { encoding: "utf-8", mode: 384 });
239
+ fs2.writeFileSync(ownerPath, JSON.stringify(owner), { encoding: "utf-8", mode: 384 });
240
240
  } catch (error51) {
241
241
  releaseLock(lockDir);
242
242
  throw error51;
@@ -245,7 +245,7 @@ function writeLockOwner(lockDir, ownerFileName, startedAt) {
245
245
  function readLockOwner(lockDir, ownerFileName) {
246
246
  const ownerPath = path27.join(lockDir, ownerFileName);
247
247
  try {
248
- return sanitizeLockOwner(JSON.parse(fs8.readFileSync(ownerPath, "utf-8")));
248
+ return sanitizeLockOwner(JSON.parse(fs2.readFileSync(ownerPath, "utf-8")));
249
249
  } catch (error51) {
250
250
  const code = error51.code;
251
251
  if (code === "ENOENT") return null;
@@ -267,7 +267,7 @@ function sameLockSnapshot(a, b) {
267
267
  }
268
268
  function restoreQuarantinedLock(quarantineDir, lockDir) {
269
269
  try {
270
- fs8.renameSync(quarantineDir, lockDir);
270
+ fs2.renameSync(quarantineDir, lockDir);
271
271
  } catch {
272
272
  }
273
273
  }
@@ -302,24 +302,24 @@ function sleepSync(ms) {
302
302
  function readAuthStoreFile(filePath) {
303
303
  let fd;
304
304
  try {
305
- fd = fs8.openSync(filePath, fs8.constants.O_RDONLY | NOFOLLOW_FLAG);
306
- if (!fs8.fstatSync(fd).isFile()) {
305
+ fd = fs2.openSync(filePath, fs2.constants.O_RDONLY | NOFOLLOW_FLAG);
306
+ if (!fs2.fstatSync(fd).isFile()) {
307
307
  return {};
308
308
  }
309
- return JSON.parse(fs8.readFileSync(fd, "utf-8"));
309
+ return JSON.parse(fs2.readFileSync(fd, "utf-8"));
310
310
  } catch {
311
311
  return {};
312
312
  } finally {
313
313
  if (fd !== void 0) {
314
314
  try {
315
- fs8.closeSync(fd);
315
+ fs2.closeSync(fd);
316
316
  } catch {
317
317
  }
318
318
  }
319
319
  }
320
320
  }
321
321
 
322
- // ../../packages/fleet-infra/src/auth/auth-storage.ts
322
+ // ../../packages/core-infra/src/auth/auth-storage.ts
323
323
  var DEFAULT_AUTH_PATH = path27.join(getFleetDataDir(), "auth.json");
324
324
  var AUTH_LOCK_OWNER_FILE_NAME = "owner.json";
325
325
  var AUTH_LOCK_TIMEOUT_MS = 5e3;
@@ -331,7 +331,7 @@ function createAuthService(deps = {}) {
331
331
  async deleteApiKey(providerId) {
332
332
  let deleted = false;
333
333
  withAuthLock(authPath, lockDir, () => {
334
- if (!fs8.existsSync(authPath)) return;
334
+ if (!fs2.existsSync(authPath)) return;
335
335
  const data = readAuthStoreFile(authPath);
336
336
  if (!Object.prototype.hasOwnProperty.call(data, providerId)) return;
337
337
  delete data[providerId];
@@ -344,21 +344,21 @@ function createAuthService(deps = {}) {
344
344
  async getApiKey(providerId) {
345
345
  let fd;
346
346
  try {
347
- if (!fs8.existsSync(authPath)) {
347
+ if (!fs2.existsSync(authPath)) {
348
348
  return void 0;
349
349
  }
350
- fd = fs8.openSync(authPath, fs8.constants.O_RDONLY | NOFOLLOW_FLAG);
351
- if (!fs8.fstatSync(fd).isFile()) {
350
+ fd = fs2.openSync(authPath, fs2.constants.O_RDONLY | NOFOLLOW_FLAG);
351
+ if (!fs2.fstatSync(fd).isFile()) {
352
352
  return void 0;
353
353
  }
354
- const data = JSON.parse(fs8.readFileSync(fd, "utf-8"));
354
+ const data = JSON.parse(fs2.readFileSync(fd, "utf-8"));
355
355
  return typeof data[providerId]?.key === "string" ? data[providerId].key : void 0;
356
356
  } catch {
357
357
  return void 0;
358
358
  } finally {
359
359
  if (fd !== void 0) {
360
360
  try {
361
- fs8.closeSync(fd);
361
+ fs2.closeSync(fd);
362
362
  } catch {
363
363
  }
364
364
  }
@@ -366,7 +366,7 @@ function createAuthService(deps = {}) {
366
366
  },
367
367
  // [HIGH #2] 읽기 경로: fd 기반 O_RDONLY|O_NOFOLLOW 통일
368
368
  async listProviderIds() {
369
- if (!fs8.existsSync(authPath)) {
369
+ if (!fs2.existsSync(authPath)) {
370
370
  return [];
371
371
  }
372
372
  try {
@@ -379,7 +379,7 @@ function createAuthService(deps = {}) {
379
379
  const dir = path27.dirname(authPath);
380
380
  ensureSafeDirectory(dir);
381
381
  withAuthLock(authPath, lockDir, () => {
382
- const data = fs8.existsSync(authPath) ? readAuthStoreFile(authPath) : {};
382
+ const data = fs2.existsSync(authPath) ? readAuthStoreFile(authPath) : {};
383
383
  data[providerId] = {
384
384
  ...data[providerId] ?? {},
385
385
  key
@@ -461,21 +461,21 @@ function createDurableJsonStore(deps) {
461
461
  function readJsonFile(filePath, sanitize) {
462
462
  let fd;
463
463
  try {
464
- const stat3 = fs8.lstatSync(filePath);
464
+ const stat3 = fs2.lstatSync(filePath);
465
465
  if (!stat3 || !stat3.isFile() || stat3.isSymbolicLink()) {
466
466
  return sanitize(void 0);
467
467
  }
468
- fd = fs8.openSync(filePath, fs8.constants.O_RDONLY | NOFOLLOW_FLAG);
469
- if (!fs8.fstatSync(fd).isFile()) {
468
+ fd = fs2.openSync(filePath, fs2.constants.O_RDONLY | NOFOLLOW_FLAG);
469
+ if (!fs2.fstatSync(fd).isFile()) {
470
470
  return sanitize(void 0);
471
471
  }
472
- return sanitize(JSON.parse(fs8.readFileSync(fd, "utf-8")));
472
+ return sanitize(JSON.parse(fs2.readFileSync(fd, "utf-8")));
473
473
  } catch {
474
474
  return sanitize(void 0);
475
475
  } finally {
476
476
  if (fd !== void 0) {
477
477
  try {
478
- fs8.closeSync(fd);
478
+ fs2.closeSync(fd);
479
479
  } catch {
480
480
  }
481
481
  }
@@ -487,7 +487,7 @@ function ensureSafeDirectoryIfSensitive(dir, sensitivity) {
487
487
  }
488
488
  }
489
489
 
490
- // ../../packages/fleet-infra/src/global-options/store.ts
490
+ // ../../packages/core-infra/src/data-dir/settings/store.ts
491
491
  var GLOBAL_OPTIONS_VERSION = 1;
492
492
  var GLOBAL_OPTIONS_FILE_NAME = "settings.json";
493
493
  var LOCK_DIR_NAME = "settings.json.lock";
@@ -529,18 +529,17 @@ function sanitizeGlobalOptionsData(value) {
529
529
  }
530
530
  const data = {
531
531
  version: GLOBAL_OPTIONS_VERSION,
532
- ...typeof value.replaceSystemPrompt === "boolean" ? { replaceSystemPrompt: value.replaceSystemPrompt } : {},
533
532
  ...typeof value.enableMetaphor === "boolean" ? { enableMetaphor: value.enableMetaphor } : {}
534
533
  };
535
- const allowedKeys = /* @__PURE__ */ new Set(["version", "replaceSystemPrompt", "enableMetaphor"]);
536
- const changed = Object.keys(value).some((key) => !allowedKeys.has(key)) || "replaceSystemPrompt" in value && typeof value.replaceSystemPrompt !== "boolean" || "enableMetaphor" in value && typeof value.enableMetaphor !== "boolean";
534
+ const allowedKeys = /* @__PURE__ */ new Set(["version", "enableMetaphor"]);
535
+ const changed = Object.keys(value).some((key) => !allowedKeys.has(key)) || "enableMetaphor" in value && typeof value.enableMetaphor !== "boolean";
537
536
  return { data, changed };
538
537
  }
539
538
  function isRecord(value) {
540
539
  return typeof value === "object" && value !== null && !Array.isArray(value);
541
540
  }
542
541
 
543
- // ../../packages/fleet-infra/src/global-options/service.ts
542
+ // ../../packages/core-infra/src/data-dir/settings/service.ts
544
543
  function createGlobalOptionsService(deps = {}) {
545
544
  const store2 = deps.store ?? createGlobalOptionsStore({ dataDir: deps.dataDir });
546
545
  return {
@@ -556,6 +555,43 @@ function updateGlobalOptions(store2, mutate) {
556
555
  return store2.update(mutate);
557
556
  }
558
557
 
558
+ // ../../packages/core-infra/src/index.ts
559
+ function createInfraServices(deps = {}) {
560
+ const globalOptionsService = createGlobalOptionsService();
561
+ const authService = createAuthService({ authPath: deps.authPath ?? DEFAULT_AUTH_PATH });
562
+ return {
563
+ authService,
564
+ globalOptionsService
565
+ };
566
+ }
567
+
568
+ // ../../packages/fleet-carriers/src/dispatch/framework.ts
569
+ var framework_exports = {};
570
+ __export(framework_exports, {
571
+ CarrierRegistry: () => CarrierRegistry,
572
+ clearRegisteredCarriers: () => clearRegisteredCarriers,
573
+ createCarrierRegistry: () => createCarrierRegistry,
574
+ emitStreamEvent: () => emitStreamEvent,
575
+ getAllCliTypes: () => getAllCliTypes,
576
+ getCarrierConfig: () => getCarrierConfig,
577
+ getCarrierSourceDisplayName: () => getCarrierSourceDisplayName,
578
+ getRegisteredCarrierConfig: () => getRegisteredCarrierConfig,
579
+ getRegisteredOrder: () => getRegisteredOrder,
580
+ normalizeEffort: () => normalizeEffort,
581
+ notifyStatusUpdate: () => notifyStatusUpdate,
582
+ registerCarrier: () => registerCarrier,
583
+ registerStreamHandler: () => registerStreamHandler,
584
+ resetCarrierRegistryForTests: () => resetCarrierRegistryForTests,
585
+ resolveAgentCliType: () => resolveAgentCliType2,
586
+ resolveCarrierDisplayName: () => resolveCarrierDisplayName,
587
+ resolveValidatedEffort: () => resolveValidatedEffort,
588
+ setTaskForceConfiguredCarriers: () => setTaskForceConfiguredCarriers,
589
+ toCarrierJobStatus: () => toCarrierJobStatus,
590
+ toTrackFinalStatus: () => toTrackFinalStatus,
591
+ unregisterStreamHandler: () => unregisterStreamHandler,
592
+ updateCarrierCliType: () => updateCarrierCliType
593
+ });
594
+
559
595
  // ../../node_modules/.pnpm/zod@4.4.1/node_modules/zod/v4/classic/external.js
560
596
  var external_exports = {};
561
597
  __export(external_exports, {
@@ -17356,6 +17392,122 @@ var RequestError = class _RequestError extends Error {
17356
17392
  };
17357
17393
  }
17358
17394
  };
17395
+ var DEFAULT_WINDOWS_PATHEXT = ".COM;.EXE;.BAT;.CMD";
17396
+ var WINDOWS_PATH_SEPARATOR = ";";
17397
+ var WINDOWS_SHIM_EXTENSIONS = /* @__PURE__ */ new Set([".cmd", ".bat"]);
17398
+ var CMD_EXPANSION_SENSITIVE_PATTERN = /[%^]/;
17399
+ function resolveBinary(defaultBin, overrideName, env, options = {}) {
17400
+ const override = env[overrideName];
17401
+ if (override && override.trim().length > 0) {
17402
+ const resolvedOverride = resolvePathBinary(override, env, options);
17403
+ if (!resolvedOverride) {
17404
+ throw new Error(`${overrideName}="${override}" did not resolve to an executable; provide an absolute path or a name discoverable on PATH`);
17405
+ }
17406
+ return resolvedOverride;
17407
+ }
17408
+ const resolved = resolvePathBinary(defaultBin, env, options);
17409
+ if (!resolved) {
17410
+ throw new Error(`${defaultBin} binary not found; set ${overrideName} or install ${defaultBin} on PATH`);
17411
+ }
17412
+ return resolved;
17413
+ }
17414
+ function resolvePathBinary(command, env, options = {}) {
17415
+ const resolved = findBinaryPath(command, env, options);
17416
+ return resolved ? wrapWindowsShim(resolved, env, options.platform ?? process.platform) : void 0;
17417
+ }
17418
+ function findBinaryPath(command, env, options = {}) {
17419
+ const platform = options.platform ?? process.platform;
17420
+ const isWindows2 = platform === "win32";
17421
+ const pathValue = isWindows2 ? env.Path ?? env.PATH ?? "" : env.PATH ?? "";
17422
+ const pathExts = isWindows2 ? parsePathExt(env.PATHEXT) : [""];
17423
+ return findOnPath(command, pathValue, pathExts, platform);
17424
+ }
17425
+ function createChildEnv(env, overlay) {
17426
+ const child = {};
17427
+ for (const [key, value] of Object.entries(env)) {
17428
+ if (value !== void 0) {
17429
+ child[key] = value;
17430
+ }
17431
+ }
17432
+ for (const [key, value] of Object.entries(overlay)) {
17433
+ if (value !== void 0) {
17434
+ child[key] = value;
17435
+ }
17436
+ }
17437
+ return child;
17438
+ }
17439
+ function wrapWindowsShim(resolved, env, platform) {
17440
+ if (platform !== "win32" || !WINDOWS_SHIM_EXTENSIONS.has(path27__default.extname(resolved).toLowerCase())) {
17441
+ return { bin: resolved, prefixArgs: [] };
17442
+ }
17443
+ rejectCmdExpansionSensitiveShim(resolved);
17444
+ return {
17445
+ bin: env.ComSpec ?? "cmd.exe",
17446
+ prefixArgs: ["/d", "/s", "/c", "call", forceWindowsArgQuoting(resolved)]
17447
+ };
17448
+ }
17449
+ function rejectCmdExpansionSensitiveShim(resolved) {
17450
+ if (CMD_EXPANSION_SENSITIVE_PATTERN.test(resolved)) {
17451
+ throw new Error(`Refusing to run Windows shim path with cmd.exe expansion-sensitive characters (% or ^): ${resolved}`);
17452
+ }
17453
+ }
17454
+ function forceWindowsArgQuoting(value) {
17455
+ return `${value} `;
17456
+ }
17457
+ function findOnPath(bin, pathValue, pathExts, platform) {
17458
+ const pathSeparator = platform === "win32" ? WINDOWS_PATH_SEPARATOR : path27__default.delimiter;
17459
+ if (hasPathSeparator(bin, platform) || path27__default.isAbsolute(bin)) {
17460
+ return resolveWithExtensions(bin, pathExts, platform);
17461
+ }
17462
+ for (const entry of pathValue.split(pathSeparator)) {
17463
+ const searchDir = entry.length === 0 ? "." : entry;
17464
+ const candidate = resolveWithExtensions(path27__default.join(searchDir, bin), pathExts, platform);
17465
+ if (candidate) {
17466
+ return candidate;
17467
+ }
17468
+ }
17469
+ return void 0;
17470
+ }
17471
+ function resolveWithExtensions(candidate, pathExts, platform) {
17472
+ if (platform !== "win32" || path27__default.extname(candidate).length > 0) {
17473
+ return isAccessibleExecutable(candidate, platform) ? candidate : void 0;
17474
+ }
17475
+ for (const ext of pathExts) {
17476
+ if (ext.length === 0) {
17477
+ continue;
17478
+ }
17479
+ const withExt = `${candidate}${ext}`;
17480
+ if (existsSync(withExt)) {
17481
+ return withExt;
17482
+ }
17483
+ }
17484
+ return isAccessibleExecutable(candidate, platform) ? candidate : void 0;
17485
+ }
17486
+ function isAccessibleExecutable(candidate, platform) {
17487
+ if (!existsSync(candidate)) return false;
17488
+ if (platform === "win32") return true;
17489
+ try {
17490
+ accessSync(candidate, constants.X_OK);
17491
+ return true;
17492
+ } catch {
17493
+ return false;
17494
+ }
17495
+ }
17496
+ function hasPathSeparator(value, platform) {
17497
+ if (value.includes("/")) {
17498
+ return true;
17499
+ }
17500
+ return platform === "win32" && value.includes("\\");
17501
+ }
17502
+ function parsePathExt(pathExt) {
17503
+ const raw = pathExt && pathExt.trim().length > 0 ? pathExt : DEFAULT_WINDOWS_PATHEXT;
17504
+ return raw.split(WINDOWS_PATH_SEPARATOR).map((entry) => entry.trim()).filter((entry) => entry.length > 0);
17505
+ }
17506
+
17507
+ // ../../packages/core-process/src/hidden.ts
17508
+ function withHidden(options) {
17509
+ return { ...options ?? {}, windowsHide: true };
17510
+ }
17359
17511
 
17360
17512
  // ../../packages/core-unified-agent/src/utils/env.ts
17361
17513
  var REMOVE_KEYS = [
@@ -17393,12 +17545,7 @@ function killProcess(child, forceTimeoutMs = 3e3) {
17393
17545
  markIntentionalKill(child);
17394
17546
  if (isWindows()) {
17395
17547
  try {
17396
- execSync(`taskkill /PID ${child.pid} /T /F`, {
17397
- stdio: "pipe",
17398
- timeout: 5e3,
17399
- // 콘솔 없는 호스트에서 taskkill 호출 시 새 콘솔 창이 깜빡이는 것을 방지한다.
17400
- windowsHide: true
17401
- });
17548
+ execSync(`taskkill /PID ${child.pid} /T /F`, withHidden({ stdio: "pipe", timeout: 5e3 }));
17402
17549
  } catch {
17403
17550
  child.kill("SIGKILL");
17404
17551
  }
@@ -17501,17 +17648,12 @@ var BaseConnection = class extends EventEmitter {
17501
17648
  const child = isWindows() ? spawn(
17502
17649
  this.env.ComSpec ?? "cmd.exe",
17503
17650
  buildWindowsCmdArgs(this.command, this.args),
17504
- {
17651
+ withHidden({
17505
17652
  cwd: this.cwd,
17506
17653
  stdio: ["pipe", "pipe", "pipe"],
17507
17654
  env: this.env,
17508
- windowsVerbatimArguments: true,
17509
- // 콘솔이 없는 호스트(예: fleet-console 백엔드)에서 cmd.exe를 spawn하면
17510
- // Windows가 새 콘솔 창을 할당해 깜빡인다. stdio는 모두 pipe라 가시 콘솔이
17511
- // 불필요하므로 CREATE_NO_WINDOW로 창 생성을 억제한다. (fleet-cli처럼 콘솔이
17512
- // 이미 있는 경우에도 무해하다.)
17513
- windowsHide: true
17514
- }
17655
+ windowsVerbatimArguments: true
17656
+ })
17515
17657
  ) : spawn(this.command, this.args, {
17516
17658
  cwd: this.cwd,
17517
17659
  stdio: ["pipe", "pipe", "pipe"],
@@ -17941,7 +18083,7 @@ var AcpConnection = class extends BaseConnection {
17941
18083
  }
17942
18084
  /** Claude 계열 브릿지인지 여부를 단일 판별 지점으로 유지합니다. */
17943
18085
  isClaudeBackend() {
17944
- return this.cliType === "claude" || this.cliType === "claude-zai" || this.cliType === "claude-kimi" || this.cliType === "claude-glm";
18086
+ return this.cliType === "claude";
17945
18087
  }
17946
18088
  /** Claude bridge만 native system prompt append를 지원하므로 이 경로만 사용합니다. */
17947
18089
  getClaudeSystemPrompt(systemPrompt) {
@@ -18392,35 +18534,14 @@ function createIdleTimeoutRace(promise2, idleMs, label) {
18392
18534
  });
18393
18535
  return [wrapped, resetTimer];
18394
18536
  }
18537
+
18538
+ // ../../packages/core-unified-agent/src/utils/npx.ts
18395
18539
  function resolveNpxPath(env) {
18396
- const windows = isWindows();
18397
- const whichCmd = windows ? "where npx" : "which npx";
18398
- try {
18399
- const result = execSync(whichCmd, {
18400
- encoding: "utf-8",
18401
- stdio: "pipe",
18402
- timeout: 5e3,
18403
- env,
18404
- // 콘솔 없는 호스트에서 `where npx` 실행 시 콘솔 창이 깜빡이는 것을 방지한다.
18405
- windowsHide: true
18406
- }).trim();
18407
- const candidates = result.split("\n").map((line) => line.trim()).filter((line) => line.length > 0);
18408
- if (windows) {
18409
- const executable = candidates.find((p) => /\.(cmd|bat|exe)$/i.test(p));
18410
- if (executable) {
18411
- return executable;
18412
- }
18413
- }
18414
- if (candidates.length > 0) {
18415
- return candidates[0];
18416
- }
18417
- return windows ? "npx.cmd" : "npx";
18418
- } catch {
18419
- if (windows) {
18420
- return "npx.cmd";
18421
- }
18422
- return "npx";
18540
+ const resolved = findBinaryPath("npx", env ?? process.env);
18541
+ if (resolved) {
18542
+ return resolved;
18423
18543
  }
18544
+ return isWindows() ? "npx.cmd" : "npx";
18424
18545
  }
18425
18546
  function buildNpxArgs(packageName, preferOffline = false) {
18426
18547
  const args = ["--yes"];
@@ -18439,10 +18560,10 @@ function inferBinName(packageName) {
18439
18560
  // ../../packages/core-unified-agent/models.json
18440
18561
  var models_default = {
18441
18562
  version: 1,
18442
- updatedAt: "2026-06-16T00:00:00Z",
18563
+ updatedAt: "2026-07-04T00:00:00Z",
18443
18564
  providers: {
18444
18565
  claude: {
18445
- name: "Claude Code with Anthropic",
18566
+ name: "Claude Code",
18446
18567
  defaultModel: "opus[1m]",
18447
18568
  models: [
18448
18569
  { modelId: "haiku", name: "Claude Haiku", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max"], default: "low" } },
@@ -18454,50 +18575,8 @@ var models_default = {
18454
18575
  { modelId: "claude-opus-4-8[1m]", name: "Claude Opus 4.8 [1M]", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max"], default: "high" } }
18455
18576
  ]
18456
18577
  },
18457
- "claude-zai": {
18458
- name: "Claude Code with Z.AI GLM",
18459
- defaultModel: "opus",
18460
- models: [
18461
- { modelId: "haiku", name: "GLM-4.5 Air (Haiku slot)", effort: { supported: false } },
18462
- { modelId: "sonnet", name: "GLM-5 Turbo (Sonnet slot)", effort: { supported: false } },
18463
- { modelId: "opus", name: "GLM-5.1 (Opus slot)", effort: { supported: false } }
18464
- ],
18465
- modelsMapping: {
18466
- haiku: "glm-4.5-air",
18467
- sonnet: "glm-5-turbo",
18468
- opus: "glm-5.1"
18469
- }
18470
- },
18471
- "claude-kimi": {
18472
- name: "Claude Code with Moonshot Kimi",
18473
- defaultModel: "opus",
18474
- models: [
18475
- { modelId: "haiku", name: "Kimi K2.7 Code (Haiku slot)", effort: { supported: false } },
18476
- { modelId: "sonnet", name: "Kimi K2.7 Code (Sonnet slot)", effort: { supported: false } },
18477
- { modelId: "opus", name: "Kimi K2.7 Code (Opus slot)", effort: { supported: false } }
18478
- ],
18479
- modelsMapping: {
18480
- haiku: "kimi-k2.7-code",
18481
- sonnet: "kimi-k2.7-code",
18482
- opus: "kimi-k2.7-code"
18483
- }
18484
- },
18485
- "claude-glm": {
18486
- name: "Claude Code with ZhipuAI GLM",
18487
- defaultModel: "opus",
18488
- models: [
18489
- { modelId: "haiku", name: "GLM-4.5-Air (Haiku slot)", effort: { supported: false } },
18490
- { modelId: "sonnet", name: "GLM-4.7 (Sonnet slot)", effort: { supported: false } },
18491
- { modelId: "opus", name: "GLM-5.1 (Opus slot)", effort: { supported: false } }
18492
- ],
18493
- modelsMapping: {
18494
- haiku: "glm-4.5-air",
18495
- sonnet: "glm-4.7",
18496
- opus: "glm-5.1"
18497
- }
18498
- },
18499
18578
  codex: {
18500
- name: "OpenAI Codex CLI",
18579
+ name: "Codex",
18501
18580
  defaultModel: "gpt-5.4",
18502
18581
  models: [
18503
18582
  { modelId: "gpt-5.4", name: "GPT-5.4", effort: { supported: true, levels: ["low", "medium", "high", "xhigh"], default: "high" } },
@@ -18513,7 +18592,9 @@ var models_default = {
18513
18592
  { modelId: "opencode-go/deepseek-v4-pro", name: "DeepSeek V4 Pro", effort: { supported: false } },
18514
18593
  { modelId: "opencode-go/glm-5", name: "GLM-5", effort: { supported: false } },
18515
18594
  { modelId: "opencode-go/glm-5.1", name: "GLM-5.1", effort: { supported: false } },
18516
- { modelId: "opencode-go/kimi-k2.6", name: "Kimi K2.6 (3x limits)", effort: { supported: false } }
18595
+ { modelId: "opencode-go/glm-5.2", name: "GLM-5.2", effort: { supported: false } },
18596
+ { modelId: "opencode-go/kimi-k2.6", name: "Kimi K2.6 (3x limits)", effort: { supported: false } },
18597
+ { modelId: "opencode-go/kimi-k2.7-code", name: "Kimi K2.7 Code", effort: { supported: false } }
18517
18598
  ]
18518
18599
  },
18519
18600
  cursor: {
@@ -18526,9 +18607,9 @@ var models_default = {
18526
18607
  { modelId: "gemini-3.1-pro", name: "Gemini 3.1 Pro", effort: { supported: false } },
18527
18608
  { modelId: "gemini-3-flash", name: "Gemini 3 Flash", effort: { supported: false } },
18528
18609
  { modelId: "gemini-3.5-flash", name: "Gemini 3.5 Flash", effort: { supported: false } },
18529
- { modelId: "claude-opus-4-7-thinking", name: "Claude Opus 4.7 Thinking", spawnModelTemplate: "claude-opus-4-7-thinking-{effort}", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max"], default: "xhigh" } },
18530
- { modelId: "claude-opus-4-8-thinking", name: "Claude Opus 4.8 Thinking", spawnModelTemplate: "claude-opus-4-8-thinking-{effort}", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max"], default: "xhigh" } },
18531
- { modelId: "claude-4.6-sonnet-medium-thinking", name: "Claude Sonnet 4.6 Medium Thinking", effort: { supported: false } }
18610
+ { modelId: "kimi-k2.7-code", name: "Kimi K2.7 Code", effort: { supported: false } },
18611
+ { modelId: "glm-5.2", name: "GLM 5.2", spawnModelTemplate: "glm-5.2-{effort}", effort: { supported: true, levels: ["high", "max"], default: "max" } },
18612
+ { modelId: "claude-opus-4-8-thinking", name: "Claude Opus 4.8 Thinking", spawnModelTemplate: "claude-opus-4-8-thinking-{effort}", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max"], default: "xhigh" } }
18532
18613
  ]
18533
18614
  }
18534
18615
  }
@@ -18699,77 +18780,6 @@ var CLI_BACKENDS = {
18699
18780
  usesNpxBridge: true,
18700
18781
  defaultMaxTokens: 16384
18701
18782
  },
18702
- "claude-zai": {
18703
- id: "claude-zai",
18704
- cliCommand: "claude",
18705
- protocol: "acp",
18706
- authRequired: true,
18707
- npxPackage: "@agentclientprotocol/claude-agent-acp@0.33.1",
18708
- modes: [
18709
- { id: "default", label: "Default" },
18710
- { id: "plan", label: "Plan" },
18711
- { id: "bypassPermissions", label: "YOLO" }
18712
- ],
18713
- supportsSessionClose: true,
18714
- supportsSessionLoad: true,
18715
- requiresModelAtSpawn: false,
18716
- usesNpxBridge: true,
18717
- defaultMaxTokens: 16384,
18718
- defaultEnv: {
18719
- ANTHROPIC_BASE_URL: "https://api.z.ai/api/anthropic",
18720
- API_TIMEOUT_MS: "3000000"
18721
- }
18722
- },
18723
- "claude-kimi": {
18724
- id: "claude-kimi",
18725
- cliCommand: "claude",
18726
- protocol: "acp",
18727
- authRequired: true,
18728
- npxPackage: "@agentclientprotocol/claude-agent-acp@0.33.1",
18729
- modes: [
18730
- { id: "default", label: "Default" },
18731
- { id: "plan", label: "Plan" },
18732
- { id: "bypassPermissions", label: "YOLO" }
18733
- ],
18734
- supportsSessionClose: true,
18735
- supportsSessionLoad: true,
18736
- requiresModelAtSpawn: false,
18737
- usesNpxBridge: true,
18738
- defaultMaxTokens: 16384,
18739
- defaultEnv: {
18740
- ANTHROPIC_BASE_URL: "https://api.kimi.com/coding/",
18741
- ENABLE_TOOL_SEARCH: "false",
18742
- ANTHROPIC_MODEL: "kimi-k2.7-code",
18743
- CLAUDE_CODE_SUBAGENT_MODEL: "kimi-k2.7-code",
18744
- API_TIMEOUT_MS: "3000000"
18745
- }
18746
- },
18747
- "claude-glm": {
18748
- id: "claude-glm",
18749
- cliCommand: "claude",
18750
- protocol: "acp",
18751
- authRequired: true,
18752
- npxPackage: "@agentclientprotocol/claude-agent-acp@0.33.1",
18753
- modes: [
18754
- { id: "default", label: "Default" },
18755
- { id: "plan", label: "Plan" },
18756
- { id: "bypassPermissions", label: "YOLO" }
18757
- ],
18758
- supportsSessionClose: true,
18759
- supportsSessionLoad: true,
18760
- requiresModelAtSpawn: false,
18761
- usesNpxBridge: true,
18762
- defaultMaxTokens: 16384,
18763
- defaultEnv: {
18764
- ANTHROPIC_BASE_URL: "https://open.bigmodel.cn/api/anthropic",
18765
- // ZhipuAI Claude Code 권장 슬롯 매핑 — 직접 launch(Native PTY) 경로에서도
18766
- // haiku/sonnet/opus 별칭이 GLM 모델로 해석되도록 env로 고정한다.
18767
- ANTHROPIC_DEFAULT_HAIKU_MODEL: "glm-4.5-air",
18768
- ANTHROPIC_DEFAULT_SONNET_MODEL: "glm-4.7",
18769
- ANTHROPIC_DEFAULT_OPUS_MODEL: "glm-5.1",
18770
- API_TIMEOUT_MS: "3000000"
18771
- }
18772
- },
18773
18783
  codex: {
18774
18784
  id: "codex",
18775
18785
  cliCommand: "codex",
@@ -18864,9 +18874,6 @@ function getBackendConfig(cli) {
18864
18874
  function getYoloModeId(cli) {
18865
18875
  switch (cli) {
18866
18876
  case "claude":
18867
- case "claude-zai":
18868
- case "claude-kimi":
18869
- case "claude-glm":
18870
18877
  return "bypassPermissions";
18871
18878
  case "opencode-go":
18872
18879
  return "build";
@@ -19034,25 +19041,23 @@ var CliDetector = class {
19034
19041
  * @returns 사용 가능 여부
19035
19042
  */
19036
19043
  async isCliAvailable(command) {
19037
- const whichCommand = isWindows() ? "where" : "which";
19038
- try {
19039
- await this.execCommand(whichCommand, [command], 3e3);
19044
+ const resolved = findBinaryPath(command, process.env);
19045
+ if (resolved !== void 0) {
19040
19046
  return true;
19041
- } catch {
19042
- if (isWindows()) {
19043
- try {
19044
- await this.execCommand(
19045
- "powershell",
19046
- ["-NoProfile", "-Command", `Get-Command -All ${command}`],
19047
- 5e3
19048
- );
19049
- return true;
19050
- } catch {
19051
- return false;
19052
- }
19047
+ }
19048
+ if (process.platform === "win32") {
19049
+ try {
19050
+ await this.execCommand(
19051
+ "powershell",
19052
+ ["-NoProfile", "-Command", `Get-Command -All ${command}`],
19053
+ 5e3
19054
+ );
19055
+ return true;
19056
+ } catch {
19057
+ return false;
19053
19058
  }
19054
- return false;
19055
19059
  }
19060
+ return false;
19056
19061
  }
19057
19062
  /**
19058
19063
  * CLI의 버전을 감지합니다.
@@ -19076,13 +19081,8 @@ var CliDetector = class {
19076
19081
  * @returns 전체 경로 또는 커맨드 이름
19077
19082
  */
19078
19083
  async getCliPath(command) {
19079
- const whichCommand = isWindows() ? "where" : "which";
19080
- try {
19081
- const result = await this.execCommand(whichCommand, [command], 3e3);
19082
- return result.split(/\r?\n/)[0].trim();
19083
- } catch {
19084
- return command;
19085
- }
19084
+ const resolved = findBinaryPath(command, process.env);
19085
+ return resolved ?? command;
19086
19086
  }
19087
19087
  /**
19088
19088
  * 외부 명령 실행 결과(stdout)를 문자열로 반환합니다.
@@ -19092,11 +19092,7 @@ var CliDetector = class {
19092
19092
  execFile(
19093
19093
  command,
19094
19094
  args,
19095
- {
19096
- encoding: "utf-8",
19097
- timeout,
19098
- windowsHide: true
19099
- },
19095
+ withHidden({ encoding: "utf-8", timeout }),
19100
19096
  (error51, stdout) => {
19101
19097
  if (error51) {
19102
19098
  reject(error51);
@@ -20312,10 +20308,10 @@ function isMissingRolloutError(error51, threadId) {
20312
20308
  return error51 instanceof Error && error51.message.includes(`no rollout found for thread id ${threadId}`);
20313
20309
  }
20314
20310
  function findRolloutPath(root, threadId) {
20315
- if (!fs8.existsSync(root)) {
20311
+ if (!fs2.existsSync(root)) {
20316
20312
  return null;
20317
20313
  }
20318
- for (const entry of fs8.readdirSync(root, { withFileTypes: true })) {
20314
+ for (const entry of fs2.readdirSync(root, { withFileTypes: true })) {
20319
20315
  const entryPath = path27.join(root, entry.name);
20320
20316
  if (entry.isDirectory()) {
20321
20317
  const found = findRolloutPath(entryPath, threadId);
@@ -21768,9 +21764,6 @@ var UnifiedAgent = {
21768
21764
  createClient(cli) {
21769
21765
  switch (cli) {
21770
21766
  case "claude":
21771
- case "claude-zai":
21772
- case "claude-kimi":
21773
- case "claude-glm":
21774
21767
  return new UnifiedClaudeAgentClient(cli);
21775
21768
  case "codex":
21776
21769
  return new UnifiedCodexAgentClient();
@@ -21790,7 +21783,7 @@ var UnifiedAgent = {
21790
21783
  const preferred = await new CliDetector().getPreferred();
21791
21784
  if (!preferred) {
21792
21785
  throw new Error(
21793
- "\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."
21786
+ "\uC0AC\uC6A9 \uAC00\uB2A5\uD55C CLI\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4. claude, codex, opencode-go, cursor \uC911 \uD558\uB098\uB97C \uC124\uCE58\uD574\uC8FC\uC138\uC694."
21794
21787
  );
21795
21788
  }
21796
21789
  return this.createClient(preferred.cli);
@@ -21805,211 +21798,6 @@ var UnifiedAgent = {
21805
21798
  }
21806
21799
  };
21807
21800
 
21808
- // ../../packages/fleet-infra/src/auth/messages.ts
21809
- function formatMissingAuthKeyMessage(input) {
21810
- const cliHint = input.cli ? `cli '${input.cli}'` : "selected CLI";
21811
- return `Auth token not found for ${cliHint} (providerId: '${input.providerId}'). Run \`fleet auth login\` to register one.`;
21812
- }
21813
- function formatAuthValidationFailureMessage(input) {
21814
- const detail = input.detail ? ` Detail: ${input.detail}` : "";
21815
- if (input.status === "unauthorized") {
21816
- return `Auth token was rejected (providerId: '${input.providerId}'). Check the token and try again.${detail}`;
21817
- }
21818
- if (input.status === "forbidden") {
21819
- return `Auth token is not allowed for this provider (providerId: '${input.providerId}'). Check the token permissions.${detail}`;
21820
- }
21821
- if (input.status === "timeout") {
21822
- return `Auth token validation timed out (providerId: '${input.providerId}'). Check the connection and try again.${detail}`;
21823
- }
21824
- if (input.status === "network") {
21825
- return `Auth token validation failed due to a network error (providerId: '${input.providerId}'). Check the connection and try again.${detail}`;
21826
- }
21827
- if (input.status === "server") {
21828
- return `Auth token validation failed because the provider returned an error (providerId: '${input.providerId}'). Try again later.${detail}`;
21829
- }
21830
- return `Auth token validation failed (providerId: '${input.providerId}'). Check the token and try again.${detail}`;
21831
- }
21832
-
21833
- // ../../packages/fleet-infra/src/auth/validation.ts
21834
- var DEFAULT_AUTH_VALIDATION_TIMEOUT_MS = 5e3;
21835
- async function validateAnthropicCompatibleApiKey(request) {
21836
- const controller = new AbortController();
21837
- const timeout = setTimeout(() => {
21838
- controller.abort();
21839
- }, request.timeoutMs ?? DEFAULT_AUTH_VALIDATION_TIMEOUT_MS);
21840
- try {
21841
- const response = await fetch(buildMessagesUrl(request.baseUrl), {
21842
- method: "POST",
21843
- headers: {
21844
- "anthropic-version": "2023-06-01",
21845
- "content-type": "application/json",
21846
- "x-api-key": request.apiKey
21847
- },
21848
- body: JSON.stringify({
21849
- model: "claude-3-5-haiku-20241022",
21850
- max_tokens: 1,
21851
- messages: [
21852
- {
21853
- role: "user",
21854
- content: "ping"
21855
- }
21856
- ]
21857
- }),
21858
- signal: controller.signal
21859
- });
21860
- if (response.ok) {
21861
- return { providerId: request.providerId, status: "success" };
21862
- }
21863
- if (response.status === 401) {
21864
- return { providerId: request.providerId, status: "unauthorized" };
21865
- }
21866
- if (response.status === 403) {
21867
- return { providerId: request.providerId, status: "forbidden" };
21868
- }
21869
- if (response.status >= 500) {
21870
- return {
21871
- providerId: request.providerId,
21872
- status: "server",
21873
- detail: `HTTP ${response.status}`
21874
- };
21875
- }
21876
- return {
21877
- providerId: request.providerId,
21878
- status: "unknown",
21879
- detail: `HTTP ${response.status}`
21880
- };
21881
- } catch (error51) {
21882
- if (isAbortError(error51)) {
21883
- return { providerId: request.providerId, status: "timeout" };
21884
- }
21885
- return {
21886
- providerId: request.providerId,
21887
- status: "network",
21888
- detail: error51 instanceof Error ? error51.message : String(error51)
21889
- };
21890
- } finally {
21891
- clearTimeout(timeout);
21892
- }
21893
- }
21894
- function isAuthValidationSuccess(result) {
21895
- return result.status === "success";
21896
- }
21897
- function createAuthValidationError(result) {
21898
- return new Error(formatAuthValidationFailureMessage(result));
21899
- }
21900
- function buildMessagesUrl(baseUrl) {
21901
- return `${baseUrl.replace(/\/+$/, "")}/v1/messages`;
21902
- }
21903
- function isAbortError(error51) {
21904
- return error51 instanceof DOMException && error51.name === "AbortError";
21905
- }
21906
-
21907
- // ../../packages/fleet-infra/src/auth/auth-providers.ts
21908
- var CLI_TO_AUTH_PROVIDER_ID = {
21909
- "claude-zai": "Claude Code with Z.AI GLM",
21910
- "claude-kimi": "Claude Code with Moonshot Kimi",
21911
- "claude-glm": "Claude Code with ZhipuAI GLM"
21912
- };
21913
- var CLAUDE_ZAI_PROVIDER_ID = "Claude Code with Z.AI GLM";
21914
- var CLAUDE_KIMI_PROVIDER_ID = "Claude Code with Moonshot Kimi";
21915
- var CLAUDE_GLM_PROVIDER_ID = "Claude Code with ZhipuAI GLM";
21916
- var AUTH_PROVIDER_DEFINITIONS = {
21917
- "claude-zai": {
21918
- providerId: CLAUDE_ZAI_PROVIDER_ID,
21919
- baseUrl: CLI_BACKENDS["claude-zai"].defaultEnv.ANTHROPIC_BASE_URL,
21920
- env: CLI_BACKENDS["claude-zai"].defaultEnv
21921
- },
21922
- "claude-kimi": {
21923
- providerId: CLAUDE_KIMI_PROVIDER_ID,
21924
- baseUrl: CLI_BACKENDS["claude-kimi"].defaultEnv.ANTHROPIC_BASE_URL,
21925
- env: CLI_BACKENDS["claude-kimi"].defaultEnv
21926
- },
21927
- "claude-glm": {
21928
- providerId: CLAUDE_GLM_PROVIDER_ID,
21929
- baseUrl: CLI_BACKENDS["claude-glm"].defaultEnv.ANTHROPIC_BASE_URL,
21930
- env: CLI_BACKENDS["claude-glm"].defaultEnv
21931
- }
21932
- };
21933
- async function resolveAuthEnv(cli, deps) {
21934
- const provider = AUTH_PROVIDER_DEFINITIONS[cli];
21935
- if (!provider) return {};
21936
- const auth = deps?.authService ?? createAuthService({ authPath: DEFAULT_AUTH_PATH });
21937
- const token = await auth.getApiKey(provider.providerId);
21938
- if (!token) {
21939
- throw new Error(formatMissingAuthKeyMessage({ cli, providerId: provider.providerId }));
21940
- }
21941
- const validation = await validateAnthropicCompatibleApiKey({
21942
- providerId: provider.providerId,
21943
- apiKey: token,
21944
- baseUrl: provider.baseUrl
21945
- });
21946
- if (!isAuthValidationSuccess(validation)) {
21947
- const failure = {
21948
- providerId: validation.providerId,
21949
- status: validation.status,
21950
- detail: validation.detail
21951
- };
21952
- throw createAuthValidationError(failure);
21953
- }
21954
- return { ...provider.env, ANTHROPIC_AUTH_TOKEN: token };
21955
- }
21956
- async function validateAuthKeyForCli(cli, apiKey) {
21957
- const provider = AUTH_PROVIDER_DEFINITIONS[cli];
21958
- if (!provider) {
21959
- return { providerId: cli, status: "success" };
21960
- }
21961
- const validation = await validateAnthropicCompatibleApiKey({
21962
- providerId: provider.providerId,
21963
- apiKey,
21964
- baseUrl: provider.baseUrl
21965
- });
21966
- if (isAuthValidationSuccess(validation)) {
21967
- return { providerId: validation.providerId, status: "success" };
21968
- }
21969
- return {
21970
- providerId: validation.providerId,
21971
- status: validation.status,
21972
- detail: validation.detail
21973
- };
21974
- }
21975
-
21976
- // ../../packages/fleet-infra/src/index.ts
21977
- function createInfraServices(deps = {}) {
21978
- const globalOptionsService = createGlobalOptionsService();
21979
- const authService = createAuthService({ authPath: deps.authPath ?? DEFAULT_AUTH_PATH });
21980
- return {
21981
- authService,
21982
- globalOptionsService
21983
- };
21984
- }
21985
-
21986
- // ../../packages/fleet-carriers/src/dispatch/framework.ts
21987
- var framework_exports = {};
21988
- __export(framework_exports, {
21989
- CarrierRegistry: () => CarrierRegistry,
21990
- clearRegisteredCarriers: () => clearRegisteredCarriers,
21991
- createCarrierRegistry: () => createCarrierRegistry,
21992
- emitStreamEvent: () => emitStreamEvent,
21993
- getAllCliTypes: () => getAllCliTypes,
21994
- getCarrierConfig: () => getCarrierConfig,
21995
- getCarrierSourceDisplayName: () => getCarrierSourceDisplayName,
21996
- getRegisteredCarrierConfig: () => getRegisteredCarrierConfig,
21997
- getRegisteredOrder: () => getRegisteredOrder,
21998
- normalizeEffort: () => normalizeEffort,
21999
- notifyStatusUpdate: () => notifyStatusUpdate,
22000
- registerCarrier: () => registerCarrier,
22001
- registerStreamHandler: () => registerStreamHandler,
22002
- resetCarrierRegistryForTests: () => resetCarrierRegistryForTests,
22003
- resolveAgentCliType: () => resolveAgentCliType2,
22004
- resolveCarrierDisplayName: () => resolveCarrierDisplayName,
22005
- resolveValidatedEffort: () => resolveValidatedEffort,
22006
- setTaskForceConfiguredCarriers: () => setTaskForceConfiguredCarriers,
22007
- toCarrierJobStatus: () => toCarrierJobStatus,
22008
- toTrackFinalStatus: () => toTrackFinalStatus,
22009
- unregisterStreamHandler: () => unregisterStreamHandler,
22010
- updateCarrierCliType: () => updateCarrierCliType
22011
- });
22012
-
22013
21801
  // ../../packages/fleet-carriers/src/constants.ts
22014
21802
  var CLI_PROVIDER_DISPLAY_NAMES = Object.fromEntries(
22015
21803
  Object.keys(CLI_BACKENDS).map((cliType) => [
@@ -22034,21 +21822,17 @@ var store_exports = {};
22034
21822
  __export(store_exports, {
22035
21823
  applyAgentCliTypeSelectionUpdate: () => applyAgentCliTypeSelectionUpdate,
22036
21824
  buildHealedCarriers: () => buildHealedCarriers,
22037
- filterCarrierAgentModesToRegisteredIds: () => filterCarrierAgentModesToRegisteredIds,
22038
21825
  getAgentCliSelection: () => getAgentCliSelection,
22039
21826
  getCarriersFilePath: () => getCarriersFilePath,
22040
21827
  getConfiguredTaskForceBackends: () => getConfiguredTaskForceBackends,
22041
21828
  getConfiguredTaskForceBackendsFromSnapshot: () => getConfiguredTaskForceBackendsFromSnapshot,
22042
21829
  getConfiguredTaskForceCarrierIds: () => getConfiguredTaskForceCarrierIds,
22043
21830
  getConfiguredTaskForceCarrierIdsFromSnapshot: () => getConfiguredTaskForceCarrierIdsFromSnapshot,
22044
- getEnabledCarrierSubagentIds: () => getEnabledCarrierSubagentIds,
22045
21831
  getTaskForceModelConfig: () => getTaskForceModelConfig,
22046
21832
  initStore: () => initStore,
22047
- isCarrierAgentModeSubagent: () => isCarrierAgentModeSubagent,
22048
21833
  loadCarrierDisplayNameOverrides: () => loadCarrierDisplayNameOverrides,
22049
21834
  loadCarrierStates: () => loadCarrierStates,
22050
21835
  normalizeCarrierDisplayNameInput: () => normalizeCarrierDisplayNameInput,
22051
- readCarrierAgentModeSnapshot: () => readCarrierAgentModeSnapshot,
22052
21836
  readCarriersSnapshot: () => readCarriersSnapshot,
22053
21837
  readFileBackedCarriersSnapshot: () => readFileBackedCarriersSnapshot,
22054
21838
  readRawCarriers: () => readRawCarriers,
@@ -22060,7 +21844,6 @@ __export(store_exports, {
22060
21844
  resolveCarrierState: () => resolveCarrierState,
22061
21845
  sanitizeCarrierDisplayName: () => sanitizeCarrierDisplayName,
22062
21846
  saveAgentCliSelection: () => saveAgentCliSelection,
22063
- setCarrierAgentMode: () => setCarrierAgentMode,
22064
21847
  store: () => store,
22065
21848
  updateAgentCliSelection: () => updateAgentCliSelection,
22066
21849
  updateAgentCliTypeOverride: () => updateAgentCliTypeOverride,
@@ -22101,9 +21884,6 @@ function sanitizeFreeformText(value) {
22101
21884
  function isRecord2(value) {
22102
21885
  return typeof value === "object" && value !== null && !Array.isArray(value);
22103
21886
  }
22104
- function sanitizeAgentMode(value) {
22105
- return value === "cli" || value === "subagent" ? value : void 0;
22106
- }
22107
21887
  function sanitizeAgentCliType(value) {
22108
21888
  return typeof value === "string" && value in CLI_BACKENDS ? value : void 0;
22109
21889
  }
@@ -22153,13 +21933,11 @@ function sanitizeTaskforce(value) {
22153
21933
  }
22154
21934
  function sanitizeCarrierState(value) {
22155
21935
  if (!isRecord2(value)) return void 0;
22156
- const agentMode = sanitizeAgentMode(value.agentMode);
22157
21936
  const agentCliType = sanitizeAgentCliType(value.agentCliType);
22158
21937
  const agentCli = sanitizeAgentCli(value.agentCli);
22159
21938
  const taskforce = sanitizeTaskforce(value.taskforce);
22160
21939
  const displayName = sanitizeFreeformText(value.displayName);
22161
21940
  const result = {};
22162
- if (agentMode) result.agentMode = agentMode;
22163
21941
  if (agentCliType) result.agentCliType = agentCliType;
22164
21942
  if (Object.keys(agentCli).length > 0) result.agentCli = agentCli;
22165
21943
  if (Object.keys(taskforce).length > 0) result.taskforce = taskforce;
@@ -22187,7 +21965,7 @@ function specToMcpTool(spec) {
22187
21965
  }
22188
21966
  function installExecutorToolCallRouter(runtime, sessionToken, ctx) {
22189
21967
  runtime.server.setOnToolCallArrived(sessionToken, (toolName, args) => {
22190
- const toolCallId = crypto3.randomUUID();
21968
+ const toolCallId = crypto4.randomUUID();
22191
21969
  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) => {
22192
21970
  runtime.server.resolveNextToolCall(sessionToken, toolCallId, {
22193
21971
  content: [{ type: "text", text: err instanceof Error ? err.message : String(err) }],
@@ -22582,7 +22360,7 @@ function createInProcessMcpServer(deps = {}) {
22582
22360
  if (activeStopPromise) await activeStopPromise;
22583
22361
  if (activeServer && activeServerUrl) return activeServerUrl;
22584
22362
  if (activeStartPromise) return activeStartPromise;
22585
- activeOpaquePath = `/${crypto3.randomUUID()}`;
22363
+ activeOpaquePath = `/${crypto4.randomUUID()}`;
22586
22364
  activeStartPromise = new Promise((resolve2, reject) => {
22587
22365
  const srv = http.createServer(handleRequest);
22588
22366
  srv.timeout = MCP_SERVER_TIMEOUT_MS;
@@ -22839,7 +22617,7 @@ function createExecutorMcpSession(deps, toolTimeoutSeconds, request) {
22839
22617
  throw new Error("Executor session cwd is required");
22840
22618
  }
22841
22619
  assertNonEmptyExecutorTools(request.serverName, request.specs);
22842
- const token = crypto3.randomUUID();
22620
+ const token = crypto4.randomUUID();
22843
22621
  registerExecutorSessionTools(runtime.runtime, token, [...request.specs]);
22844
22622
  installExecutorToolCallRouter(runtime.runtime, token, {
22845
22623
  cwd,
@@ -22885,7 +22663,7 @@ function issueSessionToken(deps, sessionTokensByLabel, request) {
22885
22663
  for (const { name, runtime } of deps.runtimes) {
22886
22664
  const tools = runtime.registry.getAllAgentTools();
22887
22665
  assertNonEmptyExecutorTools(name, tools);
22888
- const token = crypto3.randomUUID();
22666
+ const token = crypto4.randomUUID();
22889
22667
  registerExecutorSessionTools(runtime, token, tools);
22890
22668
  installExecutorToolCallRouter(runtime, token, { cwd, sessionLabel: label, signal: request.signal });
22891
22669
  tokens.push({ name, token });
@@ -23023,104 +22801,6 @@ function assertNoAuthorizationHeader(config2) {
23023
22801
  throw new Error(`Builtin external MCP server "${config2.name}" must not define headers.`);
23024
22802
  }
23025
22803
  }
23026
- var DEFAULT_WINDOWS_PATHEXT = ".COM;.EXE;.BAT;.CMD";
23027
- var WINDOWS_PATH_SEPARATOR = ";";
23028
- var WINDOWS_SHIM_EXTENSIONS = /* @__PURE__ */ new Set([".cmd", ".bat"]);
23029
- var CMD_EXPANSION_SENSITIVE_PATTERN = /[%^]/;
23030
- function resolveBinary(defaultBin, overrideName, env, options = {}) {
23031
- const override = env[overrideName];
23032
- if (override && override.trim().length > 0) {
23033
- const resolvedOverride = resolvePathBinary(override, env, options);
23034
- if (!resolvedOverride) {
23035
- throw new Error(`${overrideName}="${override}" did not resolve to an executable; provide an absolute path or a name discoverable on PATH`);
23036
- }
23037
- return resolvedOverride;
23038
- }
23039
- const resolved = resolvePathBinary(defaultBin, env, options);
23040
- if (!resolved) {
23041
- throw new Error(`${defaultBin} binary not found; set ${overrideName} or install ${defaultBin} on PATH`);
23042
- }
23043
- return resolved;
23044
- }
23045
- function resolvePathBinary(command, env, options = {}) {
23046
- const platform = options.platform ?? process.platform;
23047
- const isWindows2 = platform === "win32";
23048
- const pathValue = isWindows2 ? env.Path ?? env.PATH ?? "" : env.PATH ?? "";
23049
- const pathExts = isWindows2 ? parsePathExt(env.PATHEXT) : [""];
23050
- const resolved = findOnPath(command, pathValue, pathExts, platform);
23051
- return resolved ? wrapWindowsShim(resolved, env, platform) : void 0;
23052
- }
23053
- function createChildEnv(env, overlay) {
23054
- const child = {};
23055
- for (const [key, value] of Object.entries(env)) {
23056
- if (value !== void 0) {
23057
- child[key] = value;
23058
- }
23059
- }
23060
- for (const [key, value] of Object.entries(overlay)) {
23061
- if (value !== void 0) {
23062
- child[key] = value;
23063
- }
23064
- }
23065
- return child;
23066
- }
23067
- function wrapWindowsShim(resolved, env, platform) {
23068
- if (platform !== "win32" || !WINDOWS_SHIM_EXTENSIONS.has(path27__default.extname(resolved).toLowerCase())) {
23069
- return { bin: resolved, prefixArgs: [] };
23070
- }
23071
- rejectCmdExpansionSensitiveShim(resolved);
23072
- return {
23073
- bin: env.ComSpec ?? "cmd.exe",
23074
- prefixArgs: ["/d", "/s", "/c", "call", forceWindowsArgQuoting(resolved)]
23075
- };
23076
- }
23077
- function rejectCmdExpansionSensitiveShim(resolved) {
23078
- if (CMD_EXPANSION_SENSITIVE_PATTERN.test(resolved)) {
23079
- throw new Error(`Refusing to run Windows shim path with cmd.exe expansion-sensitive characters (% or ^): ${resolved}`);
23080
- }
23081
- }
23082
- function forceWindowsArgQuoting(value) {
23083
- return `${value} `;
23084
- }
23085
- function findOnPath(bin, pathValue, pathExts, platform) {
23086
- const pathSeparator = platform === "win32" ? WINDOWS_PATH_SEPARATOR : path27__default.delimiter;
23087
- if (hasPathSeparator(bin, platform) || path27__default.isAbsolute(bin)) {
23088
- return resolveWithExtensions(bin, pathExts, platform);
23089
- }
23090
- for (const entry of pathValue.split(pathSeparator)) {
23091
- const searchDir = entry.length === 0 ? "." : entry;
23092
- const candidate = resolveWithExtensions(path27__default.join(searchDir, bin), pathExts, platform);
23093
- if (candidate) {
23094
- return candidate;
23095
- }
23096
- }
23097
- return void 0;
23098
- }
23099
- function resolveWithExtensions(candidate, pathExts, platform) {
23100
- if (platform !== "win32" || path27__default.extname(candidate).length > 0) {
23101
- return existsSync(candidate) ? candidate : void 0;
23102
- }
23103
- for (const ext of pathExts) {
23104
- if (ext.length === 0) {
23105
- continue;
23106
- }
23107
- const withExt = `${candidate}${ext}`;
23108
- if (existsSync(withExt)) {
23109
- return withExt;
23110
- }
23111
- }
23112
- return existsSync(candidate) ? candidate : void 0;
23113
- }
23114
- function hasPathSeparator(value, platform) {
23115
- if (value.includes("/")) {
23116
- return true;
23117
- }
23118
- return platform === "win32" && value.includes("\\");
23119
- }
23120
- function parsePathExt(pathExt) {
23121
- const raw = pathExt && pathExt.trim().length > 0 ? pathExt : DEFAULT_WINDOWS_PATHEXT;
23122
- return raw.split(WINDOWS_PATH_SEPARATOR).map((entry) => entry.trim()).filter((entry) => entry.length > 0);
23123
- }
23124
22804
 
23125
22805
  // ../../packages/core-agent/src/internal/session-errors.ts
23126
22806
  var DEAD_SESSION_PATTERNS = [
@@ -23914,7 +23594,6 @@ __export(state_io_exports, {
23914
23594
  withStoreLock: () => withStoreLock
23915
23595
  });
23916
23596
  var FILENAME = "carriers.json";
23917
- var DEFAULT_STORE_DIRNAME = ".fleet";
23918
23597
  var STALE_SUBAGENT_MODE_FILENAME = "carrier-subagent.json";
23919
23598
  var LOCK_DIRNAME = "carriers.json.lock";
23920
23599
  var LOCK_OWNER_FILENAME = "owner.json";
@@ -23924,10 +23603,11 @@ var runtimeState = {
23924
23603
  lastLocalWriteFingerprint: null
23925
23604
  };
23926
23605
  function initStore(dir) {
23927
- runtimeState.storeDir = dir;
23928
- ensureSafeDirectory(dir);
23606
+ const resolvedDir = dir ?? getFleetDataDir();
23607
+ runtimeState.storeDir = resolvedDir;
23608
+ ensureSafeDirectory(resolvedDir);
23929
23609
  withStoreLock(() => {
23930
- unlinkStaleSubagentModeFile(dir);
23610
+ unlinkStaleSubagentModeFile(resolvedDir);
23931
23611
  });
23932
23612
  }
23933
23613
  function resetStoreForTests() {
@@ -23939,14 +23619,12 @@ function readRawCarriers() {
23939
23619
  return readCarriers();
23940
23620
  }
23941
23621
  function readRawCarriersOrDefaultStore() {
23942
- return runtimeState.storeDir ? readCarriers() : readCarriersFromDir(resolveDefaultStoreDir());
23622
+ return readCarriers();
23943
23623
  }
23944
23624
  function getCarriersFilePath() {
23945
- if (!runtimeState.storeDir) return null;
23946
- return path27.join(runtimeState.storeDir, FILENAME);
23625
+ return path27.join(resolveStoreDir(), FILENAME);
23947
23626
  }
23948
23627
  function updateCarriers(mutator) {
23949
- if (!runtimeState.storeDir) return;
23950
23628
  withStoreLock(() => {
23951
23629
  const carriers = readCarriers();
23952
23630
  const snapshot = structuredClone(carriers);
@@ -23956,36 +23634,35 @@ function updateCarriers(mutator) {
23956
23634
  });
23957
23635
  }
23958
23636
  function withStoreLock(operation) {
23959
- if (!runtimeState.storeDir) return operation();
23960
- fs8.mkdirSync(runtimeState.storeDir, { recursive: true });
23961
- const lockDir = path27.join(runtimeState.storeDir, LOCK_DIRNAME);
23637
+ const dir = resolveStoreDir();
23638
+ ensureSafeDirectory(dir);
23639
+ const lockDir = path27.join(dir, LOCK_DIRNAME);
23962
23640
  return withDirectoryLock(
23963
23641
  { lockDir, ownerFileName: LOCK_OWNER_FILENAME },
23964
23642
  operation
23965
23643
  );
23966
23644
  }
23967
- function readCarriers() {
23968
- if (!runtimeState.storeDir) return {};
23969
- return readCarriersFromDir(runtimeState.storeDir);
23645
+ function resolveStoreDir() {
23646
+ return runtimeState.storeDir ?? getFleetDataDir();
23970
23647
  }
23971
- function resolveDefaultStoreDir() {
23972
- return path27.join(os3.homedir(), DEFAULT_STORE_DIRNAME);
23648
+ function readCarriers() {
23649
+ return readCarriersFromDir(resolveStoreDir());
23973
23650
  }
23974
23651
  function readCarriersFromDir(dir) {
23975
23652
  const filePath = path27.join(dir, FILENAME);
23976
23653
  let fd;
23977
23654
  try {
23978
- const stat3 = fs8.lstatSync(filePath);
23655
+ const stat3 = fs2.lstatSync(filePath);
23979
23656
  if (!stat3.isFile() || stat3.isSymbolicLink()) return {};
23980
- fd = fs8.openSync(filePath, fs8.constants.O_RDONLY | NOFOLLOW_FLAG);
23981
- if (!fs8.fstatSync(fd).isFile()) return {};
23982
- return sanitizeFleetCarriers(JSON.parse(fs8.readFileSync(fd, "utf-8")));
23657
+ fd = fs2.openSync(filePath, fs2.constants.O_RDONLY | NOFOLLOW_FLAG);
23658
+ if (!fs2.fstatSync(fd).isFile()) return {};
23659
+ return sanitizeFleetCarriers(JSON.parse(fs2.readFileSync(fd, "utf-8")));
23983
23660
  } catch {
23984
23661
  return {};
23985
23662
  } finally {
23986
23663
  if (fd !== void 0) {
23987
23664
  try {
23988
- fs8.closeSync(fd);
23665
+ fs2.closeSync(fd);
23989
23666
  } catch {
23990
23667
  }
23991
23668
  }
@@ -23993,16 +23670,15 @@ function readCarriersFromDir(dir) {
23993
23670
  }
23994
23671
  function recordLastLocalWriteFingerprint(filePath, generation) {
23995
23672
  try {
23996
- const st = fs8.statSync(filePath);
23673
+ const st = fs2.statSync(filePath);
23997
23674
  runtimeState.lastLocalWriteFingerprint = { generation, mtimeMs: st.mtimeMs, size: st.size };
23998
23675
  } catch {
23999
23676
  runtimeState.lastLocalWriteFingerprint = { generation, mtimeMs: 0, size: 0 };
24000
23677
  }
24001
23678
  }
24002
23679
  function writeCarriers(s) {
24003
- if (!runtimeState.storeDir) throw new Error("Fleet store is not initialized.");
24004
- fs8.mkdirSync(runtimeState.storeDir, { recursive: true });
24005
- const filePath = path27.join(runtimeState.storeDir, FILENAME);
23680
+ const dir = resolveStoreDir();
23681
+ const filePath = path27.join(dir, FILENAME);
24006
23682
  const next = serializeFleetCarriers(s);
24007
23683
  writeAtomicSync(filePath, `${JSON.stringify(next, null, 2)}
24008
23684
  `, { fsync: false, mode: 420 });
@@ -24027,7 +23703,7 @@ function sanitizeFleetCarriers(value) {
24027
23703
  }
24028
23704
  function unlinkStaleSubagentModeFile(dir) {
24029
23705
  try {
24030
- fs8.unlinkSync(path27.join(dir, STALE_SUBAGENT_MODE_FILENAME));
23706
+ fs2.unlinkSync(path27.join(dir, STALE_SUBAGENT_MODE_FILENAME));
24031
23707
  } catch {
24032
23708
  }
24033
23709
  }
@@ -24229,7 +23905,6 @@ function resolveCarriersRecord(raw, defaultsByCarrier, resolve2) {
24229
23905
  function buildResolvedCarrierState(state, defaults, agentCliType, taskforce) {
24230
23906
  const agentCli = sanitizeAgentCli(state.agentCli);
24231
23907
  return {
24232
- agentMode: state.agentMode ?? defaults?.defaultAgentMode ?? "cli",
24233
23908
  agentCliType,
24234
23909
  agentCli: {
24235
23910
  ...agentCli,
@@ -24255,57 +23930,6 @@ function resolveSelectionForCliType(stored, cliType, defaults) {
24255
23930
  return { model, effort };
24256
23931
  }
24257
23932
 
24258
- // ../../packages/fleet-carriers/src/store/subagent-mode.ts
24259
- var subagent_mode_exports = {};
24260
- __export(subagent_mode_exports, {
24261
- filterCarrierAgentModesToRegisteredIds: () => filterCarrierAgentModesToRegisteredIds,
24262
- getEnabledCarrierSubagentIds: () => getEnabledCarrierSubagentIds,
24263
- isCarrierAgentModeSubagent: () => isCarrierAgentModeSubagent,
24264
- readCarrierAgentModeSnapshot: () => readCarrierAgentModeSnapshot,
24265
- setCarrierAgentMode: () => setCarrierAgentMode
24266
- });
24267
- function readCarrierAgentModeSnapshot(defaultsByCarrier = {}) {
24268
- const raw = readRawCarriers();
24269
- const carriers = buildHealedCarriers(defaultsByCarrier);
24270
- return {
24271
- agentModes: Object.fromEntries(
24272
- Object.entries(carriers).filter(([, state]) => state.agentMode === "subagent").map(([id]) => [id, "subagent"])
24273
- ),
24274
- generation: raw._meta?.generation ?? 0
24275
- };
24276
- }
24277
- function isCarrierAgentModeSubagent(carrierId, defaultAgentMode = "cli") {
24278
- const rawMode = readRawCarriers().carriers?.[carrierId]?.agentMode;
24279
- return (rawMode ?? defaultAgentMode) === "subagent";
24280
- }
24281
- function setCarrierAgentMode(carrierId, enabled, defaultAgentMode = "cli") {
24282
- const sanitizedCarrierId = sanitizeConfigKey(carrierId);
24283
- if (!sanitizedCarrierId) return;
24284
- const nextAgentMode = enabled ? "subagent" : "cli";
24285
- updateCarriers((states) => {
24286
- const carriers = { ...states.carriers ?? {} };
24287
- const current = carriers[sanitizedCarrierId] ?? {};
24288
- const next = { ...current };
24289
- if (nextAgentMode === defaultAgentMode) delete next.agentMode;
24290
- else next.agentMode = nextAgentMode;
24291
- carriers[sanitizedCarrierId] = next;
24292
- states.carriers = carriers;
24293
- });
24294
- }
24295
- function filterCarrierAgentModesToRegisteredIds(snapshot, registeredCarrierIds) {
24296
- const allowed = new Set(registeredCarrierIds);
24297
- return {
24298
- agentModes: Object.fromEntries(
24299
- Object.entries(snapshot.agentModes).filter(([carrierId]) => allowed.has(carrierId))
24300
- ),
24301
- generation: snapshot.generation
24302
- };
24303
- }
24304
- function getEnabledCarrierSubagentIds(snapshot, registeredCarrierIds) {
24305
- const filtered = registeredCarrierIds ? filterCarrierAgentModesToRegisteredIds(snapshot, registeredCarrierIds) : snapshot;
24306
- return Object.keys(filtered.agentModes).sort();
24307
- }
24308
-
24309
23933
  // ../../packages/fleet-carriers/src/store/taskforce-config.ts
24310
23934
  var taskforce_config_exports = {};
24311
23935
  __export(taskforce_config_exports, {
@@ -24430,13 +24054,11 @@ function isTaskForceCliType(value) {
24430
24054
  // ../../packages/fleet-carriers/src/store/index.ts
24431
24055
  var store = {
24432
24056
  ...state_io_exports,
24433
- ...subagent_mode_exports,
24434
24057
  ...models_exports,
24435
24058
  ...taskforce_config_exports,
24436
24059
  ...cli_types_exports,
24437
24060
  ...display_names_exports,
24438
24061
  stateIo: state_io_exports,
24439
- subagentMode: subagent_mode_exports,
24440
24062
  models: models_exports,
24441
24063
  taskforceConfig: taskforce_config_exports,
24442
24064
  cliTypes: cli_types_exports,
@@ -24487,7 +24109,6 @@ function registerCarrier(registry3, config2) {
24487
24109
  existing.defaultModel = config2.defaultModel;
24488
24110
  existing.defaultEffort = config2.defaultEffort;
24489
24111
  existing.carrierMetadata = config2.carrierMetadata;
24490
- existing.subagent = config2.subagent;
24491
24112
  } else {
24492
24113
  gs.modes.set(config2.id, { config: config2 });
24493
24114
  }
@@ -24631,14 +24252,8 @@ var CHRONICLE_DEFAULTS = {
24631
24252
  agent: {
24632
24253
  dispatch: {
24633
24254
  defaultCliType: "claude",
24634
- defaultAgentMode: "subagent",
24635
24255
  defaultModel: "sonnet",
24636
24256
  defaultEffort: "low"
24637
- },
24638
- nativeSubagents: {
24639
- byHost: {
24640
- claude: { defaultModel: "sonnet", defaultEffort: "low" }
24641
- }
24642
24257
  }
24643
24258
  }
24644
24259
  };
@@ -24731,14 +24346,8 @@ var GENESIS_DEFAULTS = {
24731
24346
  agent: {
24732
24347
  dispatch: {
24733
24348
  defaultCliType: "claude",
24734
- defaultAgentMode: "subagent",
24735
24349
  defaultModel: "sonnet",
24736
24350
  defaultEffort: "medium"
24737
- },
24738
- nativeSubagents: {
24739
- byHost: {
24740
- claude: { defaultModel: "sonnet", defaultEffort: "medium" }
24741
- }
24742
24351
  }
24743
24352
  }
24744
24353
  };
@@ -24806,14 +24415,8 @@ var KIROV_DEFAULTS = {
24806
24415
  agent: {
24807
24416
  dispatch: {
24808
24417
  defaultCliType: "claude",
24809
- defaultAgentMode: "subagent",
24810
24418
  defaultModel: "opus[1m]",
24811
24419
  defaultEffort: "xhigh"
24812
- },
24813
- nativeSubagents: {
24814
- byHost: {
24815
- claude: { defaultModel: "opus[1m]", defaultEffort: "xhigh" }
24816
- }
24817
24420
  }
24818
24421
  }
24819
24422
  };
@@ -24876,14 +24479,8 @@ var NIMITZ_DEFAULTS = {
24876
24479
  agent: {
24877
24480
  dispatch: {
24878
24481
  defaultCliType: "claude",
24879
- defaultAgentMode: "subagent",
24880
24482
  defaultModel: "opus[1m]",
24881
24483
  defaultEffort: "max"
24882
- },
24883
- nativeSubagents: {
24884
- byHost: {
24885
- claude: { defaultModel: "opus[1m]", defaultEffort: "xhigh" }
24886
- }
24887
24484
  }
24888
24485
  }
24889
24486
  };
@@ -24947,14 +24544,8 @@ var OHIO_DEFAULTS = {
24947
24544
  agent: {
24948
24545
  dispatch: {
24949
24546
  defaultCliType: "claude",
24950
- defaultAgentMode: "subagent",
24951
24547
  defaultModel: "sonnet",
24952
24548
  defaultEffort: "low"
24953
- },
24954
- nativeSubagents: {
24955
- byHost: {
24956
- claude: { defaultModel: "sonnet", defaultEffort: "low" }
24957
- }
24958
24549
  }
24959
24550
  }
24960
24551
  };
@@ -25019,14 +24610,8 @@ var SENTINEL_DEFAULTS = {
25019
24610
  agent: {
25020
24611
  dispatch: {
25021
24612
  defaultCliType: "claude",
25022
- defaultAgentMode: "subagent",
25023
24613
  defaultModel: "sonnet",
25024
24614
  defaultEffort: "max"
25025
- },
25026
- nativeSubagents: {
25027
- byHost: {
25028
- claude: { defaultModel: "sonnet", defaultEffort: "xhigh" }
25029
- }
25030
24615
  }
25031
24616
  }
25032
24617
  };
@@ -25082,14 +24667,8 @@ var TEMPEST_DEFAULTS = {
25082
24667
  agent: {
25083
24668
  dispatch: {
25084
24669
  defaultCliType: "claude",
25085
- defaultAgentMode: "subagent",
25086
24670
  defaultModel: "sonnet",
25087
24671
  defaultEffort: "medium"
25088
- },
25089
- nativeSubagents: {
25090
- byHost: {
25091
- claude: { defaultModel: "sonnet", defaultEffort: "medium" }
25092
- }
25093
24672
  }
25094
24673
  }
25095
24674
  };
@@ -25144,14 +24723,8 @@ var VANGUARD_DEFAULTS = {
25144
24723
  agent: {
25145
24724
  dispatch: {
25146
24725
  defaultCliType: "claude",
25147
- defaultAgentMode: "subagent",
25148
24726
  defaultModel: "haiku",
25149
24727
  defaultEffort: "low"
25150
- },
25151
- nativeSubagents: {
25152
- byHost: {
25153
- claude: { defaultModel: "haiku", defaultEffort: "low" }
25154
- }
25155
24728
  }
25156
24729
  }
25157
24730
  };
@@ -25216,24 +24789,14 @@ function registerDefaultCarriers(registry3) {
25216
24789
  }
25217
24790
  function buildDefaultCarrierConfig(registration) {
25218
24791
  const { defaults, metadata } = registration;
25219
- const claudeSubagentDefaults = defaults.agent.nativeSubagents?.byHost?.claude;
25220
24792
  return {
25221
24793
  id: defaults.id,
25222
24794
  defaultCliType: defaults.agent.dispatch.defaultCliType,
25223
- defaultAgentMode: defaults.agent.dispatch.defaultAgentMode,
25224
24795
  defaultEffort: defaults.agent.dispatch.defaultEffort,
25225
24796
  defaultModel: defaults.agent.dispatch.defaultModel,
25226
24797
  slot: defaults.slot,
25227
24798
  displayName: defaults.displayName,
25228
- carrierMetadata: metadata,
25229
- subagent: {
25230
- provider: "claude",
25231
- defaultModel: claudeSubagentDefaults?.defaultModel,
25232
- defaultEffort: claudeSubagentDefaults?.defaultEffort,
25233
- byHost: {
25234
- claude: claudeSubagentDefaults
25235
- }
25236
- }
24799
+ carrierMetadata: metadata
25237
24800
  };
25238
24801
  }
25239
24802
 
@@ -25366,7 +24929,7 @@ var StatusOverlayController = class {
25366
24929
  function buildCarrierModelDefaults(config2, cliType) {
25367
24930
  if (!config2) return {};
25368
24931
  if (cliType === "claude") {
25369
- return config2.subagent?.byHost?.claude ?? {
24932
+ return {
25370
24933
  ...config2.defaultModel ? { defaultModel: config2.defaultModel } : {},
25371
24934
  ...config2.defaultEffort ? { defaultEffort: config2.defaultEffort } : {}
25372
24935
  };
@@ -26427,8 +25990,8 @@ function Create(hidden, enumerable, options = {}) {
26427
25990
  Metrics.create += 1;
26428
25991
  const settings2 = settings_exports.Get();
26429
25992
  const withOptions = Merge(enumerable, options);
26430
- const withHidden = settings2.enumerableKind ? Merge(withOptions, hidden) : MergeHidden(withOptions, hidden);
26431
- return settings2.immutableTypes ? Object.freeze(withHidden) : withHidden;
25993
+ const withHidden2 = settings2.enumerableKind ? Merge(withOptions, hidden) : MergeHidden(withOptions, hidden);
25994
+ return settings2.immutableTypes ? Object.freeze(withHidden2) : withHidden2;
26432
25995
  }
26433
25996
 
26434
25997
  // ../../node_modules/.pnpm/typebox@1.1.34/node_modules/typebox/build/system/memory/discard.mjs
@@ -30501,6 +30064,79 @@ function getGuardState() {
30501
30064
  return guardState;
30502
30065
  }
30503
30066
 
30067
+ // ../../packages/fleet-carriers/src/jobs/report-extract.ts
30068
+ var REPORT_OPEN = "<report>";
30069
+ var REPORT_CLOSE = "</report>";
30070
+ function extractFinalReport(text) {
30071
+ let openIdx = text.lastIndexOf(REPORT_OPEN);
30072
+ while (openIdx !== -1) {
30073
+ const bodyStart = openIdx + REPORT_OPEN.length;
30074
+ const closeIdx = text.indexOf(REPORT_CLOSE, bodyStart);
30075
+ if (closeIdx !== -1) {
30076
+ const body = text.slice(bodyStart, closeIdx).trim();
30077
+ if (body) return body;
30078
+ }
30079
+ openIdx = openIdx === 0 ? -1 : text.lastIndexOf(REPORT_OPEN, openIdx - 1);
30080
+ }
30081
+ return null;
30082
+ }
30083
+
30084
+ // ../../packages/fleet-carriers/src/jobs/workspace-manifest.ts
30085
+ var WORKSPACE_CHANGE_LIMIT = 200;
30086
+ var WORKSPACE_CHANGE_CLEARED_STATUS = "cleared";
30087
+ async function captureWorkspaceSnapshot(scanner, cwd) {
30088
+ if (!scanner) return null;
30089
+ try {
30090
+ return await scanner.snapshot(cwd);
30091
+ } catch {
30092
+ return null;
30093
+ }
30094
+ }
30095
+ async function captureJobWindowManifest(scanner, cwd, baseline) {
30096
+ if (!scanner) return void 0;
30097
+ const end = await captureWorkspaceSnapshot(scanner, cwd);
30098
+ return buildWorkspaceManifest(baseline, end);
30099
+ }
30100
+ function buildWorkspaceManifest(baseline, end) {
30101
+ if (!baseline || !end) return void 0;
30102
+ const baselineByPath = new Map(baseline.map((entry) => [entry.path, normalizeSnapshotEntry(entry)]));
30103
+ const endChanges = end.map(normalizeSnapshotEntry).filter((entry) => hasWindowChange(baselineByPath.get(entry.path), entry)).map(toManifestEntry);
30104
+ const endPaths = new Set(end.map((entry) => entry.path));
30105
+ const clearedChanges = [...baselineByPath.values()].filter((entry) => !endPaths.has(entry.path)).map((entry) => ({ status: WORKSPACE_CHANGE_CLEARED_STATUS, path: entry.path }));
30106
+ const changes = [...endChanges, ...clearedChanges];
30107
+ const truncated = changes.length > WORKSPACE_CHANGE_LIMIT;
30108
+ const capped = changes.slice(0, WORKSPACE_CHANGE_LIMIT);
30109
+ return {
30110
+ changes: capped,
30111
+ truncated
30112
+ };
30113
+ }
30114
+ function buildStatLine(changeCount, truncated) {
30115
+ const suffix = changeCount === 1 ? "file" : "files";
30116
+ return `${truncated ? `${WORKSPACE_CHANGE_LIMIT}+` : String(changeCount)} ${suffix} (window-approx)`;
30117
+ }
30118
+ function normalizeSnapshotEntry(entry) {
30119
+ return {
30120
+ status: entry.status.trim(),
30121
+ path: entry.path,
30122
+ contentHash: entry.contentHash?.trim()
30123
+ };
30124
+ }
30125
+ function toManifestEntry(entry) {
30126
+ return {
30127
+ status: entry.status,
30128
+ path: entry.path
30129
+ };
30130
+ }
30131
+ function hasWindowChange(baseline, end) {
30132
+ if (!baseline) return true;
30133
+ if (baseline.status !== end.status) return true;
30134
+ if (baseline.contentHash && end.contentHash) {
30135
+ return baseline.contentHash !== end.contentHash;
30136
+ }
30137
+ return false;
30138
+ }
30139
+
30504
30140
  // ../../packages/fleet-carriers/src/jobs/dispatch.ts
30505
30141
  var CARRIER_RESULT_PUSH_PREFIX = "[carrier:result]";
30506
30142
  var CARRIER_JOBS_DOCTRINE = {
@@ -30533,11 +30169,12 @@ var REMINDER_WHITESPACE = /\s+/g;
30533
30169
  var ACTIVE_STATUS_NOTICE = "Job is still running. The [carrier:result] push will be delivered automatically when it finishes \u2014 do not call carrier_jobs again until that push arrives. Stop calling tools now and return control to the user; the push wakes the agent even after this response ends.";
30534
30170
  var ACTIVE_CANCEL_NOTICE = "Cancel did not apply: the job is still running normally, not hung. Long-running carrier jobs are expected \u2014 do not retry cancel without an explicit user request to abort. The [carrier:result] push will arrive automatically; stop calling tools and return control to the user.";
30535
30171
  function buildCarrierResultSystemReminder(input) {
30172
+ const changes = input.summary.workspaceChanges ? buildStatLine(input.summary.workspaceChanges.changes.length, input.summary.workspaceChanges.truncated) : "unavailable";
30536
30173
  const lines = [`- ${input.jobId}: ${sanitizeReminderText(input.summary.summary)}`];
30537
30174
  const metadata = [
30538
30175
  `kind=${input.kind}`,
30539
30176
  `status=${input.status}`,
30540
- `changes=${sanitizeReminderText(input.summary.workspaceChanges?.statLine ?? "unavailable")}`,
30177
+ `changes=${sanitizeReminderText(changes)}`,
30541
30178
  input.label ? `label=${sanitizeReminderText(input.label)}` : void 0,
30542
30179
  input.taskforceBackend ? `backend=${sanitizeReminderText(input.taskforceBackend)}` : void 0,
30543
30180
  input.error ? `error=${sanitizeReminderText(input.error)}` : void 0
@@ -30564,8 +30201,8 @@ function buildCarrierJobsSchema() {
30564
30201
  })),
30565
30202
  format: typebox_exports.Optional(typebox_exports.Unsafe({
30566
30203
  type: "string",
30567
- enum: ["summary", "full"],
30568
- description: "Optional result detail level for renderers and result lookups."
30204
+ enum: ["summary", "full", "raw"],
30205
+ description: `Optional result detail level. "full" returns the final report (extracted deterministically from the carrier's <report> block; falls back to the raw archive when absent). "summary" returns metadata only. "raw" returns the unprocessed full archive (debugging/audit). Defaults to "full" when omitted.`
30569
30206
  }))
30570
30207
  });
30571
30208
  }
@@ -30586,7 +30223,6 @@ function buildCarrierJobsToolSpec() {
30586
30223
  function dispatchCarrierJobsAction(params, now = Date.now()) {
30587
30224
  if (params.action === "list") {
30588
30225
  return {
30589
- action: "list",
30590
30226
  ok: true,
30591
30227
  active: listActiveJobs(),
30592
30228
  recent: listJobSummaries(now)
@@ -30595,7 +30231,6 @@ function dispatchCarrierJobsAction(params, now = Date.now()) {
30595
30231
  const jobIdError = validateJobId(params.job_id);
30596
30232
  if (jobIdError) {
30597
30233
  return {
30598
- action: params.action,
30599
30234
  job_id: params.job_id,
30600
30235
  ok: false,
30601
30236
  error: jobIdError
@@ -30606,7 +30241,6 @@ function dispatchCarrierJobsAction(params, now = Date.now()) {
30606
30241
  if (params.action === "result") return resultResponse(jobId, normalizeFormat(params.format), now);
30607
30242
  if (params.action === "cancel") return cancelResponse(jobId, now);
30608
30243
  return {
30609
- action: String(params.action),
30610
30244
  job_id: jobId,
30611
30245
  ok: false,
30612
30246
  error: "unsupported action"
@@ -30634,7 +30268,6 @@ function statusResponse(jobId, now) {
30634
30268
  const summary = getJobSummary(jobId, now);
30635
30269
  const availability = getAvailability(jobId, summary, now);
30636
30270
  return {
30637
- action: "status",
30638
30271
  job_id: jobId,
30639
30272
  ok: Boolean(active || summary || availability.full_available),
30640
30273
  status: active?.status ?? summary?.status ?? "not_found",
@@ -30649,8 +30282,6 @@ function resultResponse(jobId, format, now) {
30649
30282
  const availability = getAvailability(jobId, summary, now);
30650
30283
  if (active) {
30651
30284
  return {
30652
- action: "result",
30653
- format,
30654
30285
  job_id: jobId,
30655
30286
  ok: false,
30656
30287
  status: active.status,
@@ -30663,8 +30294,6 @@ function resultResponse(jobId, format, now) {
30663
30294
  }
30664
30295
  if (format === "summary") {
30665
30296
  return {
30666
- action: "result",
30667
- format,
30668
30297
  job_id: jobId,
30669
30298
  ok: Boolean(summary),
30670
30299
  status: summary?.status ?? "not_found",
@@ -30677,17 +30306,31 @@ function resultResponse(jobId, format, now) {
30677
30306
  const isTaskForceJob = jobId.startsWith("taskforce:");
30678
30307
  const isSubOpJob = isTaskForceJob;
30679
30308
  const serializeOpts = isSubOpJob ? { perSubOpMaxBytes: CARRIER_JOBS_PER_SUBOP_BYTE_CAP, maxBytes: CARRIER_JOBS_GLOBAL_BYTE_CAP } : { maxBytes: CARRIER_JOBS_FULL_RESULT_BYTE_CAP };
30680
- const fullResult = archive ? serializeJobArchive(archive, serializeOpts) : void 0;
30309
+ let fullResult;
30310
+ let results;
30311
+ if (archive) {
30312
+ if (isTaskForceJob) {
30313
+ results = serializeTaskForceResultsByBackend(archive, format);
30314
+ } else if (format === "raw") {
30315
+ fullResult = serializeJobArchive(archive, serializeOpts);
30316
+ } else {
30317
+ const rawSerialized = serializeJobArchive(archive);
30318
+ const reportBody = extractFinalReport(rawSerialized);
30319
+ if (reportBody !== null) {
30320
+ fullResult = capTextBytes(reportBody, CARRIER_JOBS_FULL_RESULT_BYTE_CAP);
30321
+ } else {
30322
+ fullResult = serializeJobArchive(archive, serializeOpts);
30323
+ }
30324
+ }
30325
+ }
30681
30326
  return {
30682
- action: "result",
30683
- format,
30684
30327
  job_id: jobId,
30685
30328
  ok: Boolean(archive),
30686
30329
  status: archive?.status ?? summary?.status ?? "not_found",
30687
30330
  summary: summary ?? void 0,
30688
30331
  ...availability,
30689
30332
  full_result: isTaskForceJob ? void 0 : fullResult,
30690
- results: archive && isTaskForceJob ? serializeTaskForceResultsByBackend(archive) : void 0,
30333
+ results: archive && isTaskForceJob ? results : void 0,
30691
30334
  error: archive ? void 0 : "full result unavailable or expired"
30692
30335
  };
30693
30336
  }
@@ -30696,7 +30339,6 @@ function cancelResponse(jobId, now) {
30696
30339
  const active = getActiveJob(jobId);
30697
30340
  const summary = getJobSummary(jobId, now);
30698
30341
  return {
30699
- action: "cancel",
30700
30342
  job_id: jobId,
30701
30343
  ok: result.cancelled,
30702
30344
  cancelled: result.cancelled,
@@ -30710,7 +30352,6 @@ function cancelResponse(jobId, now) {
30710
30352
  function getAvailability(jobId, summary, now) {
30711
30353
  const fullAvailable = hasFinalizedJobArchive(jobId, now);
30712
30354
  return {
30713
- summary_available: Boolean(summary),
30714
30355
  full_available: fullAvailable,
30715
30356
  full_invalidated: !hasJobArchive(jobId, now) && Boolean(summary)
30716
30357
  };
@@ -30721,9 +30362,10 @@ function validateJobId(jobId) {
30721
30362
  return null;
30722
30363
  }
30723
30364
  function normalizeFormat(format) {
30724
- return format === "summary" ? "summary" : "full";
30365
+ if (format === "summary" || format === "raw") return format;
30366
+ return "full";
30725
30367
  }
30726
- function serializeTaskForceResultsByBackend(archive) {
30368
+ function serializeTaskForceResultsByBackend(archive, format) {
30727
30369
  const grouped = /* @__PURE__ */ new Map();
30728
30370
  const orderedKeys = [];
30729
30371
  for (const block of archive.blocks) {
@@ -30737,13 +30379,30 @@ function serializeTaskForceResultsByBackend(archive) {
30737
30379
  const results = {};
30738
30380
  for (const cliType of orderedKeys) {
30739
30381
  const blocks = grouped.get(cliType);
30740
- results[cliType] = serializeJobArchive(
30741
- { ...archive, blocks },
30742
- { maxBytes: CARRIER_JOBS_PER_SUBOP_BYTE_CAP }
30743
- );
30382
+ const subArchive = { ...archive, blocks };
30383
+ if (format === "raw") {
30384
+ results[cliType] = serializeJobArchive(subArchive, { maxBytes: CARRIER_JOBS_PER_SUBOP_BYTE_CAP });
30385
+ } else {
30386
+ const rawSerialized = serializeJobArchive(subArchive);
30387
+ const reportBody = extractFinalReport(rawSerialized);
30388
+ if (reportBody !== null) {
30389
+ results[cliType] = capTextBytes(reportBody, CARRIER_JOBS_PER_SUBOP_BYTE_CAP);
30390
+ } else {
30391
+ results[cliType] = serializeJobArchive(subArchive, { maxBytes: CARRIER_JOBS_PER_SUBOP_BYTE_CAP });
30392
+ }
30393
+ }
30744
30394
  }
30745
30395
  return results;
30746
30396
  }
30397
+ function capTextBytes(text, maxBytes) {
30398
+ if (Buffer.byteLength(text, "utf8") <= maxBytes) return text;
30399
+ const buf = Buffer.from(text, "utf8");
30400
+ const marker = "\n\n[truncated]";
30401
+ const markerBytes = Buffer.byteLength(marker, "utf8");
30402
+ let end = Math.max(0, maxBytes - markerBytes);
30403
+ while (end > 0 && (buf[end] & 192) === 128) end--;
30404
+ return buf.subarray(0, end).toString("utf8") + marker;
30405
+ }
30747
30406
 
30748
30407
  // ../../packages/fleet-carriers/src/jobs/sanitize.ts
30749
30408
  var sanitize_exports = {};
@@ -30839,84 +30498,17 @@ function isEscIntermediate(code) {
30839
30498
  return code >= 32 && code <= 47;
30840
30499
  }
30841
30500
 
30842
- // ../../packages/fleet-carriers/src/jobs/workspace-manifest.ts
30843
- var WORKSPACE_CHANGE_ATTRIBUTION = "window-approximate";
30844
- var WORKSPACE_CHANGE_LIMIT = 200;
30845
- var WORKSPACE_CHANGE_CLEARED_STATUS = "cleared";
30846
- async function captureWorkspaceSnapshot(scanner, cwd) {
30847
- if (!scanner) return null;
30848
- try {
30849
- return await scanner.snapshot(cwd);
30850
- } catch {
30851
- return null;
30852
- }
30853
- }
30854
- async function captureJobWindowManifest(scanner, cwd, baseline) {
30855
- if (!scanner) {
30856
- return unavailableWorkspaceManifest("scanner-not-configured");
30857
- }
30858
- const end = await captureWorkspaceSnapshot(scanner, cwd);
30859
- return buildWorkspaceManifest(baseline, end);
30860
- }
30861
- function buildWorkspaceManifest(baseline, end, reason) {
30862
- if (!baseline || !end) {
30863
- return unavailableWorkspaceManifest("snapshot-unavailable");
30864
- }
30865
- const baselineByPath = new Map(baseline.map((entry) => [entry.path, normalizeSnapshotEntry(entry)]));
30866
- const endChanges = end.map(normalizeSnapshotEntry).filter((entry) => hasWindowChange(baselineByPath.get(entry.path), entry)).map(toManifestEntry);
30867
- const endPaths = new Set(end.map((entry) => entry.path));
30868
- const clearedChanges = [...baselineByPath.values()].filter((entry) => !endPaths.has(entry.path)).map((entry) => ({ status: WORKSPACE_CHANGE_CLEARED_STATUS, path: entry.path }));
30869
- const changes = [...endChanges, ...clearedChanges];
30870
- const truncated = changes.length > WORKSPACE_CHANGE_LIMIT;
30871
- const capped = changes.slice(0, WORKSPACE_CHANGE_LIMIT);
30872
- return {
30873
- attribution: WORKSPACE_CHANGE_ATTRIBUTION,
30874
- available: true,
30875
- changes: capped,
30876
- statLine: buildStatLine(changes.length, truncated),
30877
- truncated
30878
- };
30879
- }
30880
- function unavailableWorkspaceManifest(reason) {
30881
- return {
30882
- attribution: WORKSPACE_CHANGE_ATTRIBUTION,
30883
- available: false,
30884
- reason,
30885
- changes: [],
30886
- statLine: "unavailable",
30887
- truncated: false
30888
- };
30889
- }
30890
- function normalizeSnapshotEntry(entry) {
30891
- return {
30892
- status: entry.status.trim(),
30893
- path: entry.path,
30894
- contentHash: entry.contentHash?.trim()
30895
- };
30896
- }
30897
- function toManifestEntry(entry) {
30898
- return {
30899
- status: entry.status,
30900
- path: entry.path
30901
- };
30902
- }
30903
- function hasWindowChange(baseline, end) {
30904
- if (!baseline) return true;
30905
- if (baseline.status !== end.status) return true;
30906
- if (baseline.contentHash && end.contentHash) {
30907
- return baseline.contentHash !== end.contentHash;
30908
- }
30909
- return false;
30910
- }
30911
- function buildStatLine(changeCount, truncated) {
30912
- const suffix = changeCount === 1 ? "file" : "files";
30913
- return `${truncated ? `${WORKSPACE_CHANGE_LIMIT}+` : String(changeCount)} ${suffix} (window-approx)`;
30914
- }
30915
-
30916
30501
  // ../../packages/fleet-carriers/src/dispatch/prompt.ts
30917
30502
  var CARRIER_FLEET_BACKGROUND = String.raw`You are an autonomous agent (Carrier) operating within a coordinated multi-agent Fleet system. The Admiral, your superior, dispatches specialized tasks to you and synthesizes your output for the user. Below is your identity, operational permissions, behavioral principles, and required output format. Your assigned task arrives in the user message channel below.`;
30503
+ var COMMON_RESPONSE_PROTOCOL = `<response_protocol>
30504
+ Keep progress narration concise \u2014 at most one line per meaningful step. No verbose play-by-play or step-by-step essays (short streaming lines are acceptable for the live observation channel).
30505
+
30506
+ When the mission is complete, wrap the entire final output in a <report>...</report> tag and emit it exactly once, at the very end. The Admiral retrieves only the report block, so everything you need to convey \u2014 results, evidence, file paths, caveats \u2014 must be inside it. Your persona's output_format structure applies inside the report block as usual.
30507
+
30508
+ Do not mention or demonstrate the literal opening and closing report tag anywhere in the body outside that final block.
30509
+ </response_protocol>`;
30918
30510
  function buildCarrierSystemPrompt(metadata) {
30919
- const parts = [CARRIER_FLEET_BACKGROUND];
30511
+ const parts = [CARRIER_FLEET_BACKGROUND, COMMON_RESPONSE_PROTOCOL];
30920
30512
  if (metadata) {
30921
30513
  parts.push(`<your_identity>
30922
30514
  ${metadata.title}
@@ -31376,7 +30968,6 @@ function buildCarrierDispatchToolSpec(registry3, deps) {
31376
30968
  });
31377
30969
  }
31378
30970
  const metadata = config2.carrierMetadata;
31379
- const isNativeSubagentMode = isCarrierAgentModeSubagent(carrierId, config2.defaultAgentMode);
31380
30971
  if (metadata) {
31381
30972
  const blockValidation = validateRequiredRequestBlocks(metadata, request, carrierId);
31382
30973
  if (!blockValidation.ok) {
@@ -31387,7 +30978,7 @@ function buildCarrierDispatchToolSpec(registry3, deps) {
31387
30978
  });
31388
30979
  }
31389
30980
  }
31390
- if (!isNativeSubagentMode && getConfiguredTaskForceBackends(carrierId).length >= 2) {
30981
+ if (getConfiguredTaskForceBackends(carrierId).length >= 2) {
31391
30982
  return launchTaskForceJob({
31392
30983
  registry: registry3,
31393
30984
  carrierId,
@@ -31622,7 +31213,6 @@ function resolveCarrierTrackModelInfo(registry3, carrierId) {
31622
31213
  const modelConfig = loadCarrierStates({
31623
31214
  [carrierId]: carrierConfig ? {
31624
31215
  cliType,
31625
- ...carrierConfig.defaultAgentMode ? { defaultAgentMode: carrierConfig.defaultAgentMode } : {},
31626
31216
  ...carrierConfig.defaultEffort ? { defaultEffort: carrierConfig.defaultEffort } : {},
31627
31217
  ...carrierConfig.defaultModel ? { defaultModel: carrierConfig.defaultModel } : {}
31628
31218
  } : cliType
@@ -31710,72 +31300,6 @@ function formatRequestBlocksGuide(meta3) {
31710
31300
  });
31711
31301
  }
31712
31302
 
31713
- // ../../packages/fleet-carriers/src/subagents/index.ts
31714
- var subagents_exports = {};
31715
- __export(subagents_exports, {
31716
- CLAUDE_SUBAGENT_COLORS: () => CLAUDE_SUBAGENT_COLORS,
31717
- buildClaudeSubagentDefinition: () => buildClaudeSubagentDefinition,
31718
- buildClaudeSubagentDefinitions: () => buildClaudeSubagentDefinitions,
31719
- buildClaudeSubagentName: () => buildClaudeSubagentName
31720
- });
31721
-
31722
- // ../../packages/fleet-carriers/src/subagents/claude.ts
31723
- var NAME_SEGMENT_SPLIT_PATTERN = /[^a-zA-Z0-9]+/;
31724
- var CLAUDE_MAX_EFFORT = "xhigh";
31725
- var CLAUDE_SUBAGENT_COLORS = {
31726
- nimitz: "blue",
31727
- vanguard: "cyan",
31728
- chronicle: "green",
31729
- genesis: "orange",
31730
- kirov: "purple",
31731
- ohio: "yellow",
31732
- sentinel: "red",
31733
- tempest: "pink"
31734
- };
31735
- function buildClaudeSubagentDefinitions(options) {
31736
- const enabled = new Set(options.enabledCarrierIds);
31737
- return options.carrierConfigs.filter((config2) => enabled.has(config2.id)).map((config2) => buildClaudeSubagentDefinition(config2));
31738
- }
31739
- function buildClaudeSubagentDefinition(config2) {
31740
- const color = CLAUDE_SUBAGENT_COLORS[config2.id];
31741
- const effort = getClaudeEffort(config2);
31742
- const model = getClaudeModel(config2);
31743
- const definition = {
31744
- carrierId: config2.id,
31745
- ...color ? { color } : {},
31746
- description: buildDescription(config2),
31747
- ...effort ? { effort } : {},
31748
- ...model ? { model } : {},
31749
- name: buildClaudeSubagentName(config2.id),
31750
- prompt: buildCarrierSystemPrompt(config2.carrierMetadata)
31751
- };
31752
- return definition;
31753
- }
31754
- function buildClaudeSubagentName(carrierId) {
31755
- const lowerCaseName = carrierId.split(NAME_SEGMENT_SPLIT_PATTERN).filter((segment) => segment.length > 0).map((segment) => segment.toLowerCase()).join("");
31756
- return lowerCaseName || "carrier";
31757
- }
31758
- function buildDescription(config2) {
31759
- const metadata = config2.carrierMetadata;
31760
- const parts = [
31761
- config2.displayName,
31762
- metadata?.title,
31763
- metadata?.summary,
31764
- metadata?.whenToUse?.length ? `Use for: ${metadata.whenToUse.join(", ")}.` : void 0
31765
- ];
31766
- return parts.filter((part) => typeof part === "string" && part.trim().length > 0).join(" - ").replace(/\s+/g, " ").trim();
31767
- }
31768
- function getClaudeEffort(config2) {
31769
- const effort = config2.subagent?.byHost?.claude?.defaultEffort ?? config2.subagent?.defaultEffort;
31770
- return clampClaudeEffort(effort);
31771
- }
31772
- function getClaudeModel(config2) {
31773
- return config2.subagent?.byHost?.claude?.defaultModel ?? config2.subagent?.defaultModel;
31774
- }
31775
- function clampClaudeEffort(effort) {
31776
- return effort === "max" ? CLAUDE_MAX_EFFORT : effort;
31777
- }
31778
-
31779
31303
  // ../../packages/fleet-carriers/src/index.ts
31780
31304
  var dispatch = {
31781
31305
  ...framework_exports,
@@ -31814,7 +31338,6 @@ function createCarrierRuntime() {
31814
31338
  dispatch,
31815
31339
  jobs: boundCarrierJobs,
31816
31340
  personas: personas_exports,
31817
- subagents: subagents_exports,
31818
31341
  store: store_exports,
31819
31342
  stream: boundStream,
31820
31343
  registerCarrierDefaults() {
@@ -32090,6 +31613,10 @@ Disposition (report one line): ${"`"}inspection: pass${"`"} | ${"`"}inspection:
32090
31613
  deviations corrected by the Admiral${"`"} | ${"`"}inspection: rejected — re-dispatched
32091
31614
  with findings${"`"}. Small deviations the Admiral corrects directly during
32092
31615
  integration; systematic deviations route back to the owning carrier.
31616
+ "Small/harmless" is a claim that needs evidence, not an eyeball impression:
31617
+ before so classifying a deviation, confirm it changes no observable behavior,
31618
+ contract, or output and is unreachable by any real execution path; if
31619
+ unconfirmed, treat it as a defect, not a small deviation.
32093
31620
  Proportionality: full-diff reading for doctrine/prompt/structural changes;
32094
31621
  stat + targeted sampling for large mechanical changes. Read-only jobs skip
32095
31622
  this gate — their claims route through Deep Dive instead.
@@ -32239,12 +31766,11 @@ function createClaudeFamilyCliDefinition(options) {
32239
31766
  label: options.label,
32240
31767
  async createProfile(profileOptions) {
32241
31768
  const { bin, prefixArgs } = resolveBinary("claude", "CLAUDE_BIN", profileOptions.env);
32242
- const authEnv = options.authCli && profileOptions.authEnvResolver ? await profileOptions.authEnvResolver(options.authCli, { authService: profileOptions.authService }) : {};
32243
31769
  return {
32244
31770
  args: [...prefixArgs, ...buildModelArgs(profileOptions.model)],
32245
31771
  bin,
32246
31772
  cwd: profileOptions.cwd,
32247
- env: createChildEnv(profileOptions.env, authEnv),
31773
+ env: createChildEnv(profileOptions.env, {}),
32248
31774
  id: options.id,
32249
31775
  label: options.label,
32250
31776
  messagePolicy: {
@@ -32269,20 +31795,6 @@ var claudeCli = createClaudeFamilyCliDefinition({
32269
31795
  label: "Claude"
32270
31796
  });
32271
31797
 
32272
- // ../../packages/fleet-admiral/src/agent-cli/claude-glm/claude-glm.ts
32273
- var claudeGlmCli = createClaudeFamilyCliDefinition({
32274
- authCli: "claude-glm",
32275
- id: "claude-glm",
32276
- label: "Claude GLM"
32277
- });
32278
-
32279
- // ../../packages/fleet-admiral/src/agent-cli/claude-kimi/claude-kimi.ts
32280
- var claudeKimiCli = createClaudeFamilyCliDefinition({
32281
- authCli: "claude-kimi",
32282
- id: "claude-kimi",
32283
- label: "Claude Kimi"
32284
- });
32285
-
32286
31798
  // ../../packages/fleet-admiral/src/agent-cli/codex/codex.ts
32287
31799
  var codexCli = {
32288
31800
  id: "codex",
@@ -32315,19 +31827,43 @@ function buildModelArgs2(model) {
32315
31827
  return model === void 0 ? [] : ["--model", model];
32316
31828
  }
32317
31829
 
31830
+ // ../../packages/fleet-admiral/src/agent-cli/cursor/cursor.ts
31831
+ var cursorCli = {
31832
+ id: "cursor",
31833
+ label: "Cursor",
31834
+ async createProfile(options) {
31835
+ const { bin, prefixArgs } = resolveBinary("cursor-agent", "CURSOR_AGENT_BIN", options.env);
31836
+ return {
31837
+ args: [...prefixArgs, ...buildModelArgs3(options.model)],
31838
+ bin,
31839
+ binPrefixArgs: prefixArgs,
31840
+ cwd: options.cwd,
31841
+ env: createChildEnv(options.env, {}),
31842
+ id: "cursor",
31843
+ label: "Cursor",
31844
+ messagePolicy: {
31845
+ bracketedPaste: true,
31846
+ lineTerminator: "\r",
31847
+ multilineStrategy: "paste-mode"
31848
+ },
31849
+ terminalName: "xterm-256color"
31850
+ };
31851
+ }
31852
+ };
31853
+ function buildModelArgs3(model) {
31854
+ return model === void 0 ? [] : ["--model", model];
31855
+ }
31856
+
32318
31857
  // ../../packages/fleet-admiral/src/agent-cli/registry.ts
32319
31858
  var DEFAULT_CLI_ID = "claude";
32320
31859
  var DEFINITIONS = {
32321
31860
  claude: claudeCli,
32322
- "claude-kimi": claudeKimiCli,
32323
- "claude-glm": claudeGlmCli,
32324
- codex: codexCli
31861
+ codex: codexCli,
31862
+ cursor: cursorCli
32325
31863
  };
32326
31864
  async function resolveAgentCliProfile(env, cwd, options = {}) {
32327
31865
  const id = resolveAgentCliId(env, options);
32328
31866
  return DEFINITIONS[id].createProfile({
32329
- authEnvResolver: options.authEnvResolver,
32330
- authService: options.authService,
32331
31867
  cwd,
32332
31868
  env,
32333
31869
  model: options.model,
@@ -32365,17 +31901,13 @@ var AGENT_CLI_INJECTION_CAPABILITIES = {
32365
31901
  builderId: "claude-native",
32366
31902
  enabled: true
32367
31903
  },
32368
- "claude-kimi": {
32369
- builderId: "claude-native",
32370
- enabled: true
32371
- },
32372
- "claude-glm": {
32373
- builderId: "claude-native",
32374
- enabled: true
32375
- },
32376
31904
  codex: {
32377
31905
  builderId: "codex-native",
32378
31906
  enabled: true
31907
+ },
31908
+ cursor: {
31909
+ builderId: "cursor-native",
31910
+ enabled: true
32379
31911
  }
32380
31912
  };
32381
31913
  function getAgentCliInjectionCapability(cliId) {
@@ -32391,45 +31923,16 @@ function createSessionCaptureHookExec(deps) {
32391
31923
  deps.provider
32392
31924
  ] : [deps.entryPath, "hook", "capture-session", deps.provider];
32393
31925
  return {
32394
- command: deps.execPath ?? process4.execPath,
31926
+ command: deps.execPath ?? process5.execPath,
32395
31927
  args
32396
31928
  };
32397
31929
  }
32398
31930
 
32399
- // ../../packages/fleet-admiral/src/agent-cli/carrier-defaults.ts
32400
- function buildHostCarrierModelDefaults(config2) {
32401
- const cliType = resolveAgentCliType2(config2.id, config2.defaultCliType);
32402
- const cliDefaults = buildCarrierModelDefaults(config2, cliType);
32403
- return {
32404
- cliType,
32405
- ...config2.defaultAgentMode ? { defaultAgentMode: config2.defaultAgentMode } : {},
32406
- ...cliDefaults.defaultEffort ? { defaultEffort: cliDefaults.defaultEffort } : {},
32407
- ...cliDefaults.defaultModel ? { defaultModel: cliDefaults.defaultModel } : {}
32408
- };
32409
- }
32410
- function buildClaudeNativeSubagentPlan(registry3) {
32411
- const carrierIds = getRegisteredOrder(registry3);
32412
- const carrierConfigs = carrierIds.map((carrierId) => getCarrierConfig(registry3, carrierId)).filter((config2) => config2 !== void 0);
32413
- const defaultsByCarrier = Object.fromEntries(
32414
- carrierConfigs.map((config2) => [config2.id, buildHostCarrierModelDefaults(config2)])
32415
- );
32416
- const enabledCarrierIds = getEnabledCarrierSubagentIds(
32417
- readCarrierAgentModeSnapshot(defaultsByCarrier),
32418
- carrierIds
32419
- );
32420
- return {
32421
- carrierConfigs,
32422
- definitions: buildClaudeSubagentDefinitions({ carrierConfigs, enabledCarrierIds }),
32423
- enabledCarrierIds
32424
- };
32425
- }
32426
-
32427
31931
  // ../../packages/fleet-admiral/src/agent-cli/builders/claude.ts
32428
31932
  function buildClaudeNativeArgs(context) {
32429
- const systemPromptArg = context.replaceSystemPrompt ? "--system-prompt-file" : "--append-system-prompt-file";
32430
31933
  return [
32431
31934
  ...buildResumeArgs2(context.resumeSessionId),
32432
- systemPromptArg,
31935
+ "--append-system-prompt-file",
32433
31936
  requireSystemPromptFile(context),
32434
31937
  ...context.pluginRoots.flatMap((pluginRoot) => [
32435
31938
  "--plugin-dir",
@@ -32459,8 +31962,6 @@ function requireSystemPromptFile(context) {
32459
31962
  if (context.systemPromptFile) return context.systemPromptFile;
32460
31963
  throw new Error("Claude system prompt file is required for native injection");
32461
31964
  }
32462
-
32463
- // ../../packages/fleet-admiral/src/agent-cli/builders/toml.ts
32464
31965
  var TOML_BASIC_STRING_ESCAPE_PATTERN = /[\u0000-\u001f"\\\u007f]/g;
32465
31966
  var TOML_MULTILINE_CONTROL_PATTERN = new RegExp("[\\u0000-\\u0008\\u000b-\\u001f\\u007f]", "g");
32466
31967
  var TOML_MULTILINE_QUOTE_RUN_PATTERN = /"+/g;
@@ -32504,9 +32005,16 @@ function escapeTomlMultilineString(value) {
32504
32005
  function buildPosixShellCommand(values) {
32505
32006
  return values.map(posixShellQuote).join(" ");
32506
32007
  }
32008
+ function buildHostShellCommand(values, platform = process5.platform) {
32009
+ if (platform === "win32") return values.map(windowsShellQuote).join(" ");
32010
+ return buildPosixShellCommand(values);
32011
+ }
32507
32012
  function posixShellQuote(value) {
32508
32013
  return `'${value.replaceAll("'", "'\\''")}'`;
32509
32014
  }
32015
+ function windowsShellQuote(value) {
32016
+ return `"${value.replaceAll('"', '""')}"`;
32017
+ }
32510
32018
 
32511
32019
  // ../../packages/fleet-admiral/src/agent-cli/builders/codex.ts
32512
32020
  var CODEX_TOOL_TIMEOUT_SEC = 1800;
@@ -32523,10 +32031,7 @@ function buildCodexNativeArgs(context) {
32523
32031
  "-c",
32524
32032
  'approval_policy="never"',
32525
32033
  "-c",
32526
- 'sandbox_mode="danger-full-access"',
32527
- // hook 신뢰 프롬프트("Hooks need review")를 fleet 관리 세션에서 건너뛴다. bypass_hook_trust는
32528
- // config 키가 아니라 전용 CLI 플래그이므로 -c override가 아닌 플래그로 전달해야 한다.
32529
- "--dangerously-bypass-hook-trust"
32034
+ 'sandbox_mode="danger-full-access"'
32530
32035
  ];
32531
32036
  for (const server of context.mcpServers) {
32532
32037
  const prefix = `mcp_servers.${server.name}`;
@@ -32550,6 +32055,24 @@ function requireCodexProfileName(context) {
32550
32055
  throw new Error("Codex profile name is required for native injection");
32551
32056
  }
32552
32057
 
32058
+ // ../../packages/fleet-admiral/src/agent-cli/builders/cursor.ts
32059
+ function buildCursorNativeArgs(context) {
32060
+ return [
32061
+ ...buildResumeArgs4(context.resumeSessionId),
32062
+ ...context.pluginRoots.flatMap((pluginRoot) => [
32063
+ "--plugin-dir",
32064
+ pluginRoot
32065
+ ]),
32066
+ "--sandbox",
32067
+ "disabled",
32068
+ "--force",
32069
+ ...context.mcpServers.length > 0 ? ["--approve-mcps"] : []
32070
+ ];
32071
+ }
32072
+ function buildResumeArgs4(resumeSessionId) {
32073
+ return resumeSessionId === void 0 ? [] : ["--resume", resumeSessionId];
32074
+ }
32075
+
32553
32076
  // ../../packages/fleet-admiral/src/agent-cli/assets.generated.ts
32554
32077
  var EMBEDDED_AGENT_CLI_SKILL_ASSETS = [
32555
32078
  { relativePath: "assumption-audit/SKILL.md", content: "---\nname: assumption-audit\ndescription: Resolve decision-shaped Context Confidence gate failures one blocking gap at a time before the active protocol re-applies its planning boundary.\n---\n\nUse this auxiliary skill only when the active protocol or Context Confidence re-entry path has already found an unresolved blocking gap and the gap is decision-shaped. This skill is not a protocol mode, does not replace the active protocol, and cannot declare the planning boundary passed by itself.\n\nFor each unresolved blocking gap, triage the gap before questioning:\n\n- **Scout-shaped**: the answer should come from direct file reads, focused reconnaissance, carrier scouting, or another verifiable evidence source. Send the workflow back to that evidence-gathering path instead of asking the user to decide.\n- **Decision-shaped**: the answer depends on preference, scope, risk appetite, product intent, or authority that evidence alone cannot settle. Ask exactly one question for this gap.\n- **Escalation-shaped**: the answer requires authority beyond the current operator, changes the mission boundary, repeatedly fails to resolve, or would weaken the active protocol's required gate. Escalate to the Admiral of the Navy (\uB300\uC6D0\uC218).\n\nWhen a gap is decision-shaped, ask one question at a time. Present your recommended answer first, then give one or two concrete alternatives when useful. Walk decision dependencies one branch at a time until the current gap is resolved; do not bundle unrelated gaps into the same question.\n\nAfter the gap is answered, report the resolved decision in one short line and return control to the active protocol or Context Confidence Standing Order. The active workflow must re-evaluate confidence and re-apply the required planning boundary gate before planning proceeds.\n" },
@@ -32717,50 +32240,59 @@ function assertSegmentRealpathWithinRoot(resolvedBase, segmentPath) {
32717
32240
  }
32718
32241
 
32719
32242
  // ../../packages/fleet-admiral/src/agent-cli/plugin/fleet.ts
32720
- var CLAUDE_AGENT_FILE_STEM_ALLOWLIST = /^[A-Za-z0-9][A-Za-z0-9_-]{0,79}$/;
32243
+ var CURSOR_DOCTRINE_RULE_FILE = "fleet-doctrine.mdc";
32244
+ var CURSOR_DOCTRINE_RULE_FRONTMATTER = `---
32245
+ description: Fleet Admiral operating doctrine. Always apply in Fleet-launched Cursor Agent sessions.
32246
+ globs:
32247
+ alwaysApply: true
32248
+ ---
32249
+ `;
32250
+ var CURSOR_DOCTRINE_RULE_PREAMBLE = `# Fleet Runtime Doctrine for Cursor Agent
32251
+
32252
+ You are running as Cursor Agent inside Fleet. Cursor provides this file as a persistent rule, not as a native system prompt. For this Fleet-launched session, treat the embedded Fleet system prompt below as your active Fleet runtime doctrine.
32253
+
32254
+ Priority and interpretation:
32255
+
32256
+ - Follow higher-priority platform, system, developer, and direct user instructions first.
32257
+ - Within Cursor rules, project instructions, and other same-layer guidance, this Fleet doctrine is the governing instruction set for Fleet identity, roles, workflow, carrier operations, and reporting.
32258
+ - Treat Fleet identity and role names from the embedded prompt as the identity anchor for this session. Do not replace them with generic Cursor Agent identity when answering, planning, or delegating.
32259
+ - Do not treat this document as optional background or reference material. Apply it continuously when deciding who you are, how Fleet roles are named, which protocol applies, and how to report work.
32260
+ - Do not merely summarize or acknowledge the embedded prompt. Execute the operational requirements it defines, including protocol selection, evidence thresholds, carrier routing, and result reporting.
32261
+ - If other same-layer Cursor rules conflict with this doctrine, preserve the Fleet doctrine unless the user's latest explicit instruction requires a narrower task-specific exception.
32262
+ - When unsure whether a Fleet instruction applies, prefer following the Fleet doctrine and briefly surface the uncertainty instead of silently ignoring it.
32263
+
32264
+ ## Embedded Fleet System Prompt
32265
+
32266
+ The following block is the Fleet system prompt content adapted for Cursor's rules mechanism. It is intentionally embedded verbatim after this wrapper.
32267
+
32268
+ <fleet-system-prompt>
32269
+ `;
32270
+ var CURSOR_DOCTRINE_RULE_FOOTER = `
32271
+ </fleet-system-prompt>
32272
+ `;
32721
32273
  var assetBundle = {
32722
32274
  description: "Fleet carrier delegation and wiki evidence plugin",
32723
32275
  directoryName: "fleet",
32724
32276
  displayName: "Fleet",
32725
32277
  hashFileName: ".fleet-codex-plugin.hash",
32726
- includeClaudeAgents: true,
32727
32278
  name: "fleet",
32728
32279
  source: "asset"
32729
32280
  };
32730
32281
  function renderAssetPluginRoot(pluginRoot, bundle, options) {
32731
32282
  renderEmbeddedSkillAssets(pluginRoot);
32732
- if (bundle.includeClaudeAgents) {
32733
- for (const subagent of options.claudeDefinitions) {
32734
- const fileStem = parseClaudeAgentFileStem(subagent.name);
32735
- writePrivateFile(path27__default.join(pluginRoot, "agents", `${fileStem}.md`), claudeAgentFile(subagent), pluginRoot);
32736
- }
32737
- }
32738
- if (options.cliId === "claude" || options.cliId === "claude-kimi" || options.cliId === "claude-glm") {
32283
+ if (options.cliId === "claude") {
32739
32284
  writePrivateJson(path27__default.join(pluginRoot, "hooks", "hooks.json"), claudeHooks(options), pluginRoot);
32740
32285
  }
32741
- }
32742
- function validateClaudeAgentFileStems(subagents) {
32743
- for (const subagent of subagents) {
32744
- parseClaudeAgentFileStem(subagent.name);
32286
+ if (options.cliId === "cursor") {
32287
+ renderCursorPluginRoot(pluginRoot, options);
32745
32288
  }
32746
32289
  }
32747
- function parseClaudeAgentFileStem(name) {
32748
- if (CLAUDE_AGENT_FILE_STEM_ALLOWLIST.test(name) && path27__default.basename(name) === name) return name;
32749
- throw new Error(`Invalid Claude agent file name: ${name}`);
32750
- }
32751
32290
  function claudeHooks(options) {
32752
- const hookExec = options.hookExec;
32753
- if (!hookExec) {
32754
- throw new Error("Fleet Claude session hook command is required");
32755
- }
32756
32291
  const userPromptSubmitExecs = [options.captureSessionHookExec, options.turnStartHookExec, options.autoNameHookExec].filter((exec) => exec !== void 0);
32757
32292
  const stopExecs = [options.turnEndHookExec].filter((exec) => exec !== void 0);
32758
32293
  const inputWaitingExec = options.inputWaitingHookExec;
32759
32294
  return {
32760
32295
  hooks: {
32761
- SessionStart: [{
32762
- hooks: [claudeCommandHook(hookExec)]
32763
- }],
32764
32296
  ...userPromptSubmitExecs.length > 0 ? {
32765
32297
  UserPromptSubmit: [{
32766
32298
  hooks: userPromptSubmitExecs.map(claudeCommandHook)
@@ -32785,9 +32317,6 @@ function claudeHooks(options) {
32785
32317
  };
32786
32318
  }
32787
32319
  function claudeCommandHook(hookExec) {
32788
- if (!hookExec) {
32789
- throw new Error("Fleet Claude session hook command is required");
32790
- }
32791
32320
  return {
32792
32321
  // exec 형식: command는 직접 spawn되는 실행 파일, args는 셸 토크나이징 없이 그대로 전달된다.
32793
32322
  // Windows cmd/powershell의 따옴표 규칙과 무관하게 동작하며 공백 포함 경로도 안전하다.
@@ -32796,22 +32325,59 @@ function claudeCommandHook(hookExec) {
32796
32325
  type: "command"
32797
32326
  };
32798
32327
  }
32799
- function claudeAgentFile(subagent) {
32800
- const frontmatter = [
32801
- "---",
32802
- `name: ${yamlScalar(subagent.name)}`,
32803
- `description: ${yamlScalar(subagent.description)}`,
32804
- ...subagent.model ? [`model: ${yamlScalar(subagent.model)}`] : [],
32805
- ...subagent.effort ? [`effort: ${yamlScalar(subagent.effort)}`] : [],
32806
- ...subagent.color ? [`color: ${yamlScalar(subagent.color)}`] : [],
32807
- "background: true",
32808
- "---",
32809
- ""
32810
- ];
32811
- return [...frontmatter, subagent.prompt, ""].join("\n");
32328
+ function renderCursorPluginRoot(pluginRoot, options) {
32329
+ if (options.doctrine !== void 0) {
32330
+ renderCursorDoctrineRule(pluginRoot, options.doctrine);
32331
+ }
32332
+ if ((options.mcpServers ?? []).length > 0) {
32333
+ writePrivateJson(path27__default.join(pluginRoot, "mcp.json"), cursorMcpConfig(options.mcpServers ?? []), pluginRoot);
32334
+ }
32335
+ const hooks = cursorHooks(options);
32336
+ if (hooks !== void 0) {
32337
+ writePrivateJson(path27__default.join(pluginRoot, "hooks", "hooks.json"), hooks, pluginRoot);
32338
+ }
32812
32339
  }
32813
- function yamlScalar(value) {
32814
- return JSON.stringify(value);
32340
+ function renderCursorDoctrineRule(pluginRoot, doctrine) {
32341
+ writePrivateFile(
32342
+ path27__default.join(pluginRoot, "rules", CURSOR_DOCTRINE_RULE_FILE),
32343
+ `${CURSOR_DOCTRINE_RULE_FRONTMATTER}${CURSOR_DOCTRINE_RULE_PREAMBLE}${doctrine}${CURSOR_DOCTRINE_RULE_FOOTER}`,
32344
+ pluginRoot
32345
+ );
32346
+ }
32347
+ function cursorMcpConfig(servers) {
32348
+ return {
32349
+ mcpServers: Object.fromEntries(
32350
+ servers.map((server) => [server.name, {
32351
+ type: "http",
32352
+ url: server.endpointUrl,
32353
+ headers: {
32354
+ Authorization: `Bearer ${server.bearerToken}`
32355
+ }
32356
+ }])
32357
+ )
32358
+ };
32359
+ }
32360
+ function cursorHooks(options) {
32361
+ const sessionStartExecs = [options.captureSessionHookExec].filter((exec) => exec !== void 0);
32362
+ const beforeSubmitPromptExecs = [options.turnStartHookExec, options.autoNameHookExec].filter((exec) => exec !== void 0);
32363
+ const stopExecs = [options.turnEndHookExec].filter((exec) => exec !== void 0);
32364
+ if (sessionStartExecs.length === 0 && beforeSubmitPromptExecs.length === 0 && stopExecs.length === 0) return void 0;
32365
+ return {
32366
+ version: 1,
32367
+ hooks: {
32368
+ ...sessionStartExecs.length > 0 ? {
32369
+ sessionStart: sessionStartExecs.map((exec) => cursorCommandHook(exec))
32370
+ } : {},
32371
+ ...beforeSubmitPromptExecs.length > 0 ? { beforeSubmitPrompt: beforeSubmitPromptExecs.map((exec) => cursorCommandHook(exec)) } : {},
32372
+ ...stopExecs.length > 0 ? { stop: stopExecs.map((exec) => cursorCommandHook(exec)) } : {}
32373
+ }
32374
+ };
32375
+ }
32376
+ function cursorCommandHook(hookExec, extraArgs = []) {
32377
+ return {
32378
+ type: "command",
32379
+ command: buildHostShellCommand([hookExec.command, ...hookExec.args, ...extraArgs])
32380
+ };
32815
32381
  }
32816
32382
  function renderEmbeddedSkillAssets(pluginRoot) {
32817
32383
  for (const asset of EMBEDDED_AGENT_CLI_SKILL_ASSETS) {
@@ -33199,9 +32765,11 @@ var MARKETPLACE_MANAGED_ENTRIES = [
33199
32765
  ".agents",
33200
32766
  ".claude-plugin",
33201
32767
  ".codex-plugin",
32768
+ ".cursor-plugin",
33202
32769
  "hooks",
33203
32770
  "skills",
33204
32771
  "agents",
32772
+ "mcp.json",
33205
32773
  "claude",
33206
32774
  "codex-marketplace",
33207
32775
  "plugins"
@@ -33210,20 +32778,21 @@ var MARKETPLACE_PRUNE_ENTRIES = [
33210
32778
  ".agents",
33211
32779
  ".claude-plugin",
33212
32780
  ".codex-plugin",
32781
+ ".cursor-plugin",
33213
32782
  "hooks",
33214
32783
  "skills",
33215
32784
  "agents",
32785
+ "mcp.json",
33216
32786
  "claude",
33217
32787
  "codex-marketplace"
33218
32788
  ];
33219
32789
  var HASH_IGNORED_RELATIVE_PATHS = new Set(PLUGIN_BUNDLES.map((bundle) => bundle.hashFileName));
33220
32790
  async function createAgentCliPlugin(options) {
33221
- const fleetRoot = options.rootDir ?? options.dataDir;
32791
+ const fleetRoot = options.rootDir ?? options.dataDir ?? getFleetDataDir();
33222
32792
  const renderableBundles = resolveRenderablePluginBundles(fleetRoot);
33223
32793
  const marketplaceBundles = groupRenderableBundlesByMarketplace(renderableBundles);
33224
32794
  const pluginRoots = /* @__PURE__ */ new Map();
33225
32795
  const contentHashes = /* @__PURE__ */ new Map();
33226
- validateClaudeAgentFileStems(options.claudeDefinitions);
33227
32796
  for (const marketplace of marketplaceBundles) {
33228
32797
  await options.withMarketplaceLock(marketplace.target.root, () => {
33229
32798
  for (const { bundle, target } of marketplace.bundles) {
@@ -33285,12 +32854,15 @@ function renderPluginRoot(pluginRoot, bundle, options) {
33285
32854
  writePrivateJson(path27__default.join(stagedPluginRoot, ".claude-plugin", "plugin.json"), claudeManifest(bundle), stagedPluginRoot);
33286
32855
  switch (bundle.source) {
33287
32856
  case "asset":
33288
- ensurePrivateDir(path27__default.join(stagedPluginRoot, "agents"), stagedPluginRoot);
32857
+ if (options.cliId === "claude") {
32858
+ ensurePrivateDir(path27__default.join(stagedPluginRoot, "agents"), stagedPluginRoot);
32859
+ }
33289
32860
  ensurePrivateDir(path27__default.join(stagedPluginRoot, "skills"), stagedPluginRoot);
33290
32861
  renderAssetPluginRoot(stagedPluginRoot, bundle, options);
33291
32862
  break;
33292
32863
  }
33293
32864
  writePrivateJson(path27__default.join(stagedPluginRoot, ".codex-plugin", "plugin.json"), codexManifest(bundle, stagedPluginRoot), stagedPluginRoot);
32865
+ writePrivateJson(path27__default.join(stagedPluginRoot, ".cursor-plugin", "plugin.json"), cursorManifest(bundle, stagedPluginRoot), stagedPluginRoot);
33294
32866
  removePrivatePath(pluginRoot, parentRoot);
33295
32867
  renameSync(stagedPluginRoot, pluginRoot);
33296
32868
  } finally {
@@ -33304,6 +32876,7 @@ function renderMarketplaceRoot(target, bundles) {
33304
32876
  try {
33305
32877
  writePrivateJson(path27__default.join(stagedRoot, ".agents", "plugins", "marketplace.json"), codexMarketplace(target, bundles), stagedRoot);
33306
32878
  writePrivateJson(path27__default.join(stagedRoot, ".claude-plugin", "marketplace.json"), claudeMarketplace(target, bundles), stagedRoot);
32879
+ writePrivateJson(path27__default.join(stagedRoot, ".cursor-plugin", "marketplace.json"), cursorMarketplace(target, bundles), stagedRoot);
33307
32880
  pruneMarketplaceRoot(target);
33308
32881
  pruneStalePluginDirs(target, bundles);
33309
32882
  for (const entry of readdirSync(stagedRoot)) {
@@ -33328,7 +32901,7 @@ function pruneStalePluginDirs(target, bundles) {
33328
32901
  }
33329
32902
  }
33330
32903
  function buildContentHash(target) {
33331
- const hash2 = crypto3.createHash("sha256");
32904
+ const hash2 = crypto4.createHash("sha256");
33332
32905
  for (const filePath of listRenderableFiles(target)) {
33333
32906
  const relativePath = path27__default.relative(target.root, filePath);
33334
32907
  hash2.update(relativePath);
@@ -33423,6 +32996,17 @@ function claudeMarketplace(target, bundles) {
33423
32996
  }))
33424
32997
  };
33425
32998
  }
32999
+ function cursorMarketplace(target, bundles) {
33000
+ return {
33001
+ name: target.name,
33002
+ owner: "fleet",
33003
+ plugins: bundles.map((bundle) => ({
33004
+ name: bundle.name,
33005
+ description: bundle.description,
33006
+ source: marketplacePluginPath(target, bundle)
33007
+ }))
33008
+ };
33009
+ }
33426
33010
  function pluginRootForTarget(target, bundle) {
33427
33011
  return path27__default.join(target.root, PLUGIN_BUNDLES_DIR_NAME, bundle.directoryName);
33428
33012
  }
@@ -33437,8 +33021,30 @@ function codexManifest(bundle, pluginRoot) {
33437
33021
  skills: "./skills/"
33438
33022
  };
33439
33023
  }
33024
+ function cursorManifest(bundle, pluginRoot) {
33025
+ return {
33026
+ name: bundle.name,
33027
+ version: cursorManifestVersion(bundle, pluginRoot),
33028
+ description: bundle.description
33029
+ };
33030
+ }
33031
+ function cursorManifestVersion(bundle, pluginRoot) {
33032
+ const hash2 = crypto4.createHash("sha256");
33033
+ hash2.update(bundle.name);
33034
+ hash2.update("\0");
33035
+ hash2.update(bundle.description);
33036
+ hash2.update("\0");
33037
+ for (const filePath of listCursorEffectivePluginFiles(pluginRoot)) {
33038
+ const relativePath = path27__default.relative(pluginRoot, filePath);
33039
+ hash2.update(relativePath);
33040
+ hash2.update("\0");
33041
+ hash2.update(readFileSync(filePath));
33042
+ hash2.update("\0");
33043
+ }
33044
+ return `0.0.0+${hash2.digest("hex").slice(0, 12)}`;
33045
+ }
33440
33046
  function codexManifestVersion(bundle, pluginRoot) {
33441
- const hash2 = crypto3.createHash("sha256");
33047
+ const hash2 = crypto4.createHash("sha256");
33442
33048
  hash2.update(bundle.name);
33443
33049
  hash2.update("\0");
33444
33050
  hash2.update(bundle.description);
@@ -33459,6 +33065,22 @@ function listCodexEffectivePluginFiles(pluginRoot) {
33459
33065
  collectRenderableFiles(pluginRoot, skillsPath, files, /* @__PURE__ */ new Set());
33460
33066
  return files.sort();
33461
33067
  }
33068
+ function listCursorEffectivePluginFiles(pluginRoot) {
33069
+ const files = [];
33070
+ for (const entry of ["skills", "rules", "hooks", "mcp.json"]) {
33071
+ const entryPath = path27__default.join(pluginRoot, entry);
33072
+ if (!existsSync(entryPath)) continue;
33073
+ const stat3 = lstatSync(entryPath);
33074
+ if (stat3.isFile()) {
33075
+ files.push(entryPath);
33076
+ continue;
33077
+ }
33078
+ if (stat3.isDirectory()) {
33079
+ collectRenderableFiles(pluginRoot, entryPath, files, /* @__PURE__ */ new Set());
33080
+ }
33081
+ }
33082
+ return files.sort();
33083
+ }
33462
33084
  function claudeManifest(bundle) {
33463
33085
  return {
33464
33086
  name: bundle.name,
@@ -33468,9 +33090,11 @@ function claudeManifest(bundle) {
33468
33090
  }
33469
33091
 
33470
33092
  // ../../packages/fleet-admiral/src/agent-cli/injection.ts
33471
- var CODEX_FLEET_PROFILE_FILE_NAME_PATTERN = /^fleet-[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}\.config\.toml$/;
33472
- var CODEX_FLEET_PROFILE_MARKER = "# Fleet-managed Codex session profile";
33473
- var CODEX_STALE_PROFILE_MAX_AGE_MS = 24 * 60 * 60 * 1e3;
33093
+ var CODEX_FLEET_PROFILE_NAME = "fleet";
33094
+ var CODEX_FLEET_PROFILE_FILE_NAME = `${CODEX_FLEET_PROFILE_NAME}.config.toml`;
33095
+ var CODEX_LEGACY_FLEET_PROFILE_FILE_NAME_PATTERN = /^fleet-[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}\.config\.toml$/;
33096
+ var CODEX_FLEET_PROFILE_MARKER = "# Fleet-managed Codex profile";
33097
+ var CODEX_LEGACY_FLEET_PROFILE_MARKER = "# Fleet-managed Codex session profile";
33474
33098
  var SYSTEM_PROMPT_FILE_MODE = 384;
33475
33099
  async function injectAgentCliProfile(profile, options) {
33476
33100
  const capability = getAgentCliInjectionCapability(profile.id);
@@ -33479,27 +33103,26 @@ async function injectAgentCliProfile(profile, options) {
33479
33103
  }
33480
33104
  const injectTone = options.enableMetaphor ?? false;
33481
33105
  const endpoint = await options.dedicatedMcpSession.getEndpoint();
33482
- const startupDefinitions = buildStartupNativeDefinitions(profile.id, options.carrierRuntime);
33483
- const tokenLabel = options.mcpSessionLabel ?? `agent:${profile.id}:${crypto3.randomUUID()}`;
33106
+ const tokenLabel = options.mcpSessionLabel ?? `agent:${profile.id}:${crypto4.randomUUID()}`;
33484
33107
  const tokens = await options.dedicatedMcpSession.issueSessionToken({ cwd: profile.cwd, label: tokenLabel });
33485
33108
  const mcpServers = buildAgentCliMcpServerConfigs(endpoint.servers, tokens);
33486
33109
  const doctrine = options.buildSystemPrompt(injectTone);
33487
33110
  const tempCleanups = [];
33488
33111
  try {
33489
- const systemPromptFile = profile.id === "claude" || profile.id === "claude-kimi" || profile.id === "claude-glm" ? writeSystemPromptFile(profile.id, doctrine, (cleanup2) => tempCleanups.push(cleanup2)) : void 0;
33112
+ const systemPromptFile = profile.id === "claude" ? writeSystemPromptFile(profile.id, doctrine, (cleanup2) => tempCleanups.push(cleanup2)) : void 0;
33490
33113
  const plugin = await createAgentCliPlugin({
33491
- claudeDefinitions: startupDefinitions.host === "claude" ? startupDefinitions.definitions : [],
33492
33114
  cliId: profile.id,
33493
33115
  codexCommandRunner: options.codexCommandRunner,
33494
33116
  cwd: profile.cwd,
33495
33117
  dataDir: options.dataDir,
33118
+ doctrine,
33496
33119
  rootDir: options.pluginRootDir,
33120
+ mcpServers,
33497
33121
  captureSessionHookExec: options.captureSessionHookExec,
33498
33122
  turnStartHookExec: options.turnStartHookExec,
33499
33123
  turnEndHookExec: options.turnEndHookExec,
33500
33124
  inputWaitingHookExec: options.inputWaitingHookExec,
33501
33125
  autoNameHookExec: options.autoNameHookExec,
33502
- hookExec: startupDefinitions.host === "claude" ? requireHookExec(options.hookExec) : void 0,
33503
33126
  withMarketplaceLock: options.withMarketplaceLock
33504
33127
  });
33505
33128
  const codexPluginKeys = plugin.codexRegistrations.map((registration) => `${registration.pluginName}@${registration.marketplaceName}`);
@@ -33508,7 +33131,7 @@ async function injectAgentCliProfile(profile, options) {
33508
33131
  turnStartHookExec: options.turnStartHookExec,
33509
33132
  turnEndHookExec: options.turnEndHookExec,
33510
33133
  autoNameHookExec: options.autoNameHookExec
33511
- }, (cleanup2) => tempCleanups.push(cleanup2)) : void 0;
33134
+ }) : void 0;
33512
33135
  const launchWarnings = [];
33513
33136
  if (profile.id === "codex") {
33514
33137
  const cleanupWarning = await cleanupDeprecatedCodexPluginState({
@@ -33518,7 +33141,7 @@ async function injectAgentCliProfile(profile, options) {
33518
33141
  env: { ...profile.env }
33519
33142
  }, requireCodexCommandRunner(options.codexCommandRunner), options.withMarketplaceLock, {
33520
33143
  homeMarketplaceName: FLEET_MARKETPLACE_NAME,
33521
- homeMarketplaceRoot: path27__default.join(options.pluginRootDir ?? options.dataDir, "marketplace"),
33144
+ homeMarketplaceRoot: path27__default.join(options.pluginRootDir ?? options.dataDir ?? getFleetDataDir(), "marketplace"),
33522
33145
  projectMarketplaceRoot: path27__default.join(profile.cwd, ".fleet")
33523
33146
  });
33524
33147
  if (cleanupWarning !== void 0) {
@@ -33550,7 +33173,6 @@ async function injectAgentCliProfile(profile, options) {
33550
33173
  pluginRoot: plugin.pluginRoot,
33551
33174
  pluginRoots: plugin.pluginRoots,
33552
33175
  codexProfileName: codexProfile?.profileName,
33553
- replaceSystemPrompt: options.replaceSystemPrompt ?? false,
33554
33176
  resumeSessionId: options.resumeSessionId,
33555
33177
  systemPromptFile
33556
33178
  };
@@ -33569,15 +33191,6 @@ async function injectAgentCliProfile(profile, options) {
33569
33191
  throw error51;
33570
33192
  }
33571
33193
  }
33572
- function buildStartupNativeDefinitions(cliId, carrierRuntime) {
33573
- const host = getNativeSubagentHost(cliId);
33574
- if (host === "none") return { host, definitions: [] };
33575
- return { host, definitions: buildClaudeNativeSubagentPlan(carrierRuntime.registry).definitions };
33576
- }
33577
- function getNativeSubagentHost(cliId) {
33578
- if (cliId === "claude" || cliId === "claude-kimi" || cliId === "claude-glm") return "claude";
33579
- return "none";
33580
- }
33581
33194
  function buildAgentCliMcpServerConfigs(endpoints, tokens) {
33582
33195
  return endpoints.map((endpoint) => {
33583
33196
  const token = tokens.find((entry) => entry.name === endpoint.name)?.token;
@@ -33599,13 +33212,13 @@ function writeSystemPromptFile(cliId, systemPrompt, onCleanup) {
33599
33212
  chmodBestEffort2(filePath, SYSTEM_PROMPT_FILE_MODE);
33600
33213
  return filePath;
33601
33214
  }
33602
- function writeCodexFleetProfile(env, doctrine, pluginKeys, hookExecs, onCleanup) {
33215
+ function writeCodexFleetProfile(env, doctrine, pluginKeys, hookExecs) {
33603
33216
  const codexHome = env.CODEX_HOME ?? path27__default.join(env.HOME ?? os3__default.homedir(), ".codex");
33604
33217
  mkdirSync(codexHome, { recursive: true });
33605
- pruneStaleCodexFleetProfiles(codexHome);
33606
- const profileName = `fleet-${crypto3.randomUUID()}`;
33607
- const profilePath = path27__default.join(codexHome, `${profileName}.config.toml`);
33608
- onCleanup(() => rmBestEffort(profilePath));
33218
+ pruneLegacyCodexFleetProfiles(codexHome);
33219
+ const profileName = CODEX_FLEET_PROFILE_NAME;
33220
+ const profilePath = path27__default.join(codexHome, CODEX_FLEET_PROFILE_FILE_NAME);
33221
+ const hookTrustState = readCodexFleetHookTrustState(profilePath);
33609
33222
  writeFileNoFollow2(profilePath, [
33610
33223
  CODEX_FLEET_PROFILE_MARKER,
33611
33224
  // doctrine를 멀티라인 TOML 문자열로 직렬화해 실제 줄바꿈을 보존(pretty)한다.
@@ -33614,12 +33227,16 @@ function writeCodexFleetProfile(env, doctrine, pluginKeys, hookExecs, onCleanup)
33614
33227
  escapeTomlMultilineString(doctrine),
33615
33228
  `"""`,
33616
33229
  "",
33230
+ "[features]",
33231
+ "hooks = true",
33232
+ "",
33617
33233
  ...pluginKeys.flatMap((pluginKey) => [
33618
33234
  `[plugins."${escapeTomlBasicString2(pluginKey)}"]`,
33619
33235
  "enabled = true",
33620
33236
  ""
33621
33237
  ]),
33622
- ...codexHooksConfig(hookExecs)
33238
+ ...codexHooksConfig(hookExecs),
33239
+ ...hookTrustState
33623
33240
  ].join("\n"));
33624
33241
  chmodBestEffort2(profilePath, SYSTEM_PROMPT_FILE_MODE);
33625
33242
  return { profileName, profilePath };
@@ -33654,27 +33271,67 @@ function writeFileNoFollow2(filePath, content) {
33654
33271
  closeSync(fd);
33655
33272
  }
33656
33273
  }
33657
- function pruneStaleCodexFleetProfiles(codexHome) {
33274
+ function readCodexFleetHookTrustState(profilePath) {
33275
+ try {
33276
+ const content = readFileNoFollow(profilePath);
33277
+ if ((content.split(/\r?\n/, 1)[0] ?? "") !== CODEX_FLEET_PROFILE_MARKER) return [];
33278
+ return extractCodexHookTrustStateSections(content);
33279
+ } catch {
33280
+ return [];
33281
+ }
33282
+ }
33283
+ function readFileNoFollow(filePath) {
33284
+ const fd = openSync(filePath, constants.O_RDONLY | constants.O_NOFOLLOW);
33285
+ try {
33286
+ return readFileSync(fd, "utf8");
33287
+ } finally {
33288
+ closeSync(fd);
33289
+ }
33290
+ }
33291
+ function extractCodexHookTrustStateSections(content) {
33292
+ const sections = [];
33293
+ let current;
33294
+ for (const line of content.split(/\r?\n/)) {
33295
+ if (/^\[hooks\.state\./.test(line)) {
33296
+ if (current !== void 0) pushCodexHookTrustStateSection(sections, current);
33297
+ current = [line];
33298
+ continue;
33299
+ }
33300
+ if (current === void 0) continue;
33301
+ if (/^\s*\[/.test(line)) {
33302
+ pushCodexHookTrustStateSection(sections, current);
33303
+ current = void 0;
33304
+ continue;
33305
+ }
33306
+ current.push(line);
33307
+ }
33308
+ if (current !== void 0) pushCodexHookTrustStateSection(sections, current);
33309
+ return sections;
33310
+ }
33311
+ function pushCodexHookTrustStateSection(sections, section) {
33312
+ sections.push(...section);
33313
+ if (section[section.length - 1] !== "") sections.push("");
33314
+ }
33315
+ function pruneLegacyCodexFleetProfiles(codexHome) {
33658
33316
  let entries;
33659
33317
  try {
33660
33318
  entries = readdirSync(codexHome);
33661
33319
  } catch {
33662
33320
  return;
33663
33321
  }
33664
- const now = Date.now();
33665
33322
  for (const entry of entries) {
33666
- if (!CODEX_FLEET_PROFILE_FILE_NAME_PATTERN.test(entry)) continue;
33323
+ if (!CODEX_LEGACY_FLEET_PROFILE_FILE_NAME_PATTERN.test(entry)) continue;
33667
33324
  const filePath = path27__default.join(codexHome, entry);
33668
- if (!isStaleFleetCodexProfile(filePath, now)) continue;
33325
+ if (!isLegacyFleetCodexProfile(filePath)) continue;
33669
33326
  unlinkBestEffort2(filePath);
33670
33327
  }
33671
33328
  }
33672
- function isStaleFleetCodexProfile(filePath, now) {
33329
+ function isLegacyFleetCodexProfile(filePath) {
33673
33330
  try {
33674
33331
  const stat3 = lstatSync(filePath);
33675
33332
  if (!stat3.isFile() || stat3.isSymbolicLink()) return false;
33676
- if (now - stat3.mtimeMs <= CODEX_STALE_PROFILE_MAX_AGE_MS) return false;
33677
- return readFirstLine(filePath) === CODEX_FLEET_PROFILE_MARKER;
33333
+ const firstLine = readFirstLine(filePath);
33334
+ return firstLine === CODEX_LEGACY_FLEET_PROFILE_MARKER;
33678
33335
  } catch {
33679
33336
  return false;
33680
33337
  }
@@ -33701,10 +33358,6 @@ function unlinkBestEffort2(targetPath) {
33701
33358
  } catch {
33702
33359
  }
33703
33360
  }
33704
- function requireHookExec(hookExec) {
33705
- if (hookExec) return hookExec;
33706
- throw new Error("Fleet session hook executable is required for Claude native injection");
33707
- }
33708
33361
  function requireCodexCommandRunner(codexCommandRunner) {
33709
33362
  if (codexCommandRunner) return codexCommandRunner;
33710
33363
  throw new Error("Codex plugin registration requires an injected command runner");
@@ -33715,6 +33368,8 @@ function buildAgentCliArgs(builderId, context) {
33715
33368
  return buildClaudeNativeArgs(context);
33716
33369
  case "codex-native":
33717
33370
  return buildCodexNativeArgs(context);
33371
+ case "cursor-native":
33372
+ return buildCursorNativeArgs(context);
33718
33373
  }
33719
33374
  }
33720
33375
  function mergeAgentCliArgs(profile, builderId, context, injectedArgs) {
@@ -33762,6 +33417,7 @@ var CHRONICLE_WIKI_TOOL_IDS = /* @__PURE__ */ new Set([
33762
33417
  ]);
33763
33418
  function createFleetAgentRuntimeLifecycle(deps) {
33764
33419
  let active = true;
33420
+ const resolvedDataDir = deps.dataDir ?? getFleetDataDir();
33765
33421
  const mcpRuntime = createFleetAgentRuntimeMcpServices();
33766
33422
  const carrierRuntime = createCarrierRuntime();
33767
33423
  const dedicatedMcpSession = createExecutorSessionManager({
@@ -33777,7 +33433,7 @@ function createFleetAgentRuntimeLifecycle(deps) {
33777
33433
  ]
33778
33434
  });
33779
33435
  registerExecutorPort(mcpRuntime.mcpRegistry, carrierRuntime, () => active);
33780
- carrierRuntime.store.initStore(deps.dataDir);
33436
+ carrierRuntime.store.initStore(resolvedDataDir);
33781
33437
  carrierRuntime.registerCarrierDefaults();
33782
33438
  registerFleetAgentRuntimeTools(mcpRuntime.mcpRegistry, carrierRuntime, deps);
33783
33439
  registerExecutorMcpRuntimeProvider(mcpRuntime, dedicatedMcpSession, () => active);
@@ -33825,7 +33481,7 @@ function registerExecutorPort(mcpRegistry, carrierRuntime, isActive) {
33825
33481
  }
33826
33482
  function registerFleetAgentRuntimeTools(mcpRegistry, carrierRuntime, deps) {
33827
33483
  registerAgentToolDefaults(mcpRegistry, carrierRuntime, {
33828
- authEnvResolver: deps.authEnvResolver,
33484
+ authEnvResolver: async () => ({}),
33829
33485
  reservedExternalMcpServerIds: buildReservedExternalMcpServerIds(deps.reservedExternalMcpServerIds),
33830
33486
  workspaceChangeScanner: deps.workspaceChangeScanner
33831
33487
  });
@@ -34964,7 +34620,7 @@ function stripLeadingFrontmatter(body) {
34964
34620
  return stripped ? next : body;
34965
34621
  }
34966
34622
  function computeContentHash(content) {
34967
- return crypto3.createHash("sha256").update(content, "utf8").digest("hex").slice(0, 8);
34623
+ return crypto4.createHash("sha256").update(content, "utf8").digest("hex").slice(0, 8);
34968
34624
  }
34969
34625
  function assertWithinRawDir(absolutePath, paths) {
34970
34626
  const relative = path27__default.relative(paths.rawDir, absolutePath);
@@ -35177,7 +34833,7 @@ async function writeAtomic(filePath, content, paths) {
35177
34833
  await ensureMemoryRoot(paths);
35178
34834
  const tempPath = path27__default.join(
35179
34835
  path27__default.dirname(filePath),
35180
- `.tmp-${process.pid}-${Date.now()}-${crypto3.randomUUID()}-${os3__default.hostname()}`
34836
+ `.tmp-${process.pid}-${Date.now()}-${crypto4.randomUUID()}-${os3__default.hostname()}`
35181
34837
  );
35182
34838
  await writeFile(tempPath, content, "utf8");
35183
34839
  await rename(tempPath, filePath);
@@ -37730,7 +37386,7 @@ function parseOptionalIsoDate(value) {
37730
37386
  return Number.isFinite(timestamp) ? timestamp : null;
37731
37387
  }
37732
37388
  function hashBodyForComparison(body) {
37733
- return crypto3.createHash("sha256").update(body.replace(/\s+/g, " ").trim(), "utf8").digest("hex").slice(0, 8);
37389
+ return crypto4.createHash("sha256").update(body.replace(/\s+/g, " ").trim(), "utf8").digest("hex").slice(0, 8);
37734
37390
  }
37735
37391
  function hasConflictingStatuses(entries) {
37736
37392
  const statuses = new Set(entries.map((entry) => entry.status).filter((status) => status !== "unknown"));
@@ -39926,7 +39582,7 @@ var DEFAULT_TICKET_TTL_MS = 1e4;
39926
39582
  function createPluginTerminalTicketRegistry(deps = {}) {
39927
39583
  const ttlMs = deps.ttlMs ?? DEFAULT_TICKET_TTL_MS;
39928
39584
  const now = deps.now ?? Date.now;
39929
- const randomTicket = deps.randomTicket ?? (() => crypto3.randomBytes(32).toString("base64url"));
39585
+ const randomTicket = deps.randomTicket ?? (() => crypto4.randomBytes(32).toString("base64url"));
39930
39586
  const tickets = /* @__PURE__ */ new Map();
39931
39587
  function issue3(context) {
39932
39588
  prune();
@@ -39958,10 +39614,10 @@ var TERMINAL_TERM = "xterm-256color";
39958
39614
  var FLEET_CONSOLE_PACKAGE_NAME = "@dotobokuri/fleet-console";
39959
39615
  var require2 = createRequire(import.meta.url);
39960
39616
  function createShellTerminalLaunchResolver(deps = {}) {
39961
- const baseCwd = deps.cwd ?? process4.cwd();
39962
- const env = deps.env ?? process4.env;
39617
+ const baseCwd = deps.cwd ?? process5.cwd();
39618
+ const env = deps.env ?? process5.env;
39963
39619
  const homedir3 = deps.homedir ?? DEFAULT_TERMINAL_CWD_FALLBACK;
39964
- const platform = deps.platform ?? process4.platform;
39620
+ const platform = deps.platform ?? process5.platform;
39965
39621
  return async (selectedCwd) => {
39966
39622
  const cwd = selectedCwd || baseCwd || homedir3();
39967
39623
  const shell = resolveWindowsLaunchBinary(resolveUserShell(env, platform), [], env, platform, "user shell");
@@ -39972,7 +39628,7 @@ function startTerminalShell(launch, size) {
39972
39628
  const testStartShell = globalThis.__fleetTerminalStartShell;
39973
39629
  if (testStartShell) return testStartShell(launch, size);
39974
39630
  const { spawn: spawnPty } = loadNodePty();
39975
- const useConptyDll = resolveUseConptyDll(process4.platform, process4.env);
39631
+ const useConptyDll = resolveUseConptyDll(process5.platform, process5.env);
39976
39632
  return spawnPty(launch.bin, [...launch.args], {
39977
39633
  cols: size.cols,
39978
39634
  rows: size.rows,
@@ -40591,7 +40247,8 @@ var BINARY_DISPLAY_NAMES = {
40591
40247
  };
40592
40248
  var OVERRIDE_ENV_BY_COMMAND = {
40593
40249
  claude: "CLAUDE_BIN",
40594
- codex: "CODEX_BIN"
40250
+ codex: "CODEX_BIN",
40251
+ "cursor-agent": "CURSOR_AGENT_BIN"
40595
40252
  };
40596
40253
  var VERSION_PROBE_TIMEOUT_MS = 5e3;
40597
40254
  var SEMVER_PATTERN = /(\d+\.\d+\.\d+)/;
@@ -40655,7 +40312,7 @@ function execFileVersion(bin, args) {
40655
40312
  execFile(
40656
40313
  bin,
40657
40314
  [...args],
40658
- { encoding: "utf-8", timeout: VERSION_PROBE_TIMEOUT_MS, windowsHide: true },
40315
+ withHidden({ encoding: "utf-8", timeout: VERSION_PROBE_TIMEOUT_MS }),
40659
40316
  (error51, stdout, stderr) => {
40660
40317
  if (error51) {
40661
40318
  reject(error51);
@@ -40668,9 +40325,8 @@ function execFileVersion(bin, args) {
40668
40325
  }
40669
40326
 
40670
40327
  // ../fleet-plugins/terminal/server/agent-api/agent-cli-launch-kinds.ts
40671
- var UNSUPPORTED_AGENT_CLI_IDS = /* @__PURE__ */ new Set(["claude-kimi", "claude-glm"]);
40672
40328
  function buildAgentCliLaunchKinds(metadata, operationType) {
40673
- return metadata.filter((cli) => !UNSUPPORTED_AGENT_CLI_IDS.has(cli.id)).map((cli) => {
40329
+ return metadata.map((cli) => {
40674
40330
  const disabledReason = resolveDisabledReason(cli);
40675
40331
  return {
40676
40332
  id: cli.id,
@@ -40693,10 +40349,7 @@ function combineAgentCliLaunchMetadata(metadata, installStatuses, authStatuses)
40693
40349
  return metadata.map((meta3) => ({
40694
40350
  id: meta3.id,
40695
40351
  label: meta3.label,
40696
- // claude 계열 3종은 같은 `claude` 바이너리를 공유하므로 cliCommand로 설치 여부를 판정한다.
40697
40352
  available: availableByCommand.get(CLI_BACKENDS[meta3.id].cliCommand) ?? false,
40698
- // model-auth 게이트 대상(claude-kimi/glm)만 실제 로그인 상태를 반영하고,
40699
- // 자체 인증 CLI(claude/codex)는 Fleet이 로그인 여부를 알 수 없으므로 게이트하지 않는다(true).
40700
40353
  signedIn: signedInByCli.has(meta3.id) ? signedInByCli.get(meta3.id) ?? false : true
40701
40354
  }));
40702
40355
  }
@@ -40793,7 +40446,7 @@ function readProviderSessionCapture(fleetSessionId, deps = {}) {
40793
40446
  const capturesDir = deps.capturesDir ?? defaultCapturePaths().capturesDir;
40794
40447
  const filePath = path27__default.join(capturesDir, `${fleetSessionId}.json`);
40795
40448
  try {
40796
- const parsed = JSON.parse(fs8__default.readFileSync(filePath, "utf8"));
40449
+ const parsed = JSON.parse(fs2__default.readFileSync(filePath, "utf8"));
40797
40450
  return sanitizeProviderSession(parsed);
40798
40451
  } catch {
40799
40452
  return null;
@@ -40803,7 +40456,7 @@ function unlinkProviderSessionCapture(fleetSessionId, deps = {}) {
40803
40456
  if (!isSafeCaptureId(fleetSessionId)) return false;
40804
40457
  const capturesDir = deps.capturesDir ?? defaultCapturePaths().capturesDir;
40805
40458
  try {
40806
- fs8__default.unlinkSync(path27__default.join(capturesDir, `${fleetSessionId}.json`));
40459
+ fs2__default.unlinkSync(path27__default.join(capturesDir, `${fleetSessionId}.json`));
40807
40460
  return true;
40808
40461
  } catch {
40809
40462
  return false;
@@ -40811,20 +40464,20 @@ function unlinkProviderSessionCapture(fleetSessionId, deps = {}) {
40811
40464
  }
40812
40465
  function captureSessionStrict(options) {
40813
40466
  const provider = parseProvider(options.provider);
40814
- const fleetSessionId = readFleetSessionId(options.env ?? process4.env);
40467
+ const fleetSessionId = readFleetSessionId(options.env ?? process5.env);
40815
40468
  const input = parseHookInput(options.input ?? "");
40816
40469
  const providerSession = toProviderSession(provider, input, options.now ?? (() => /* @__PURE__ */ new Date()));
40817
40470
  const capturesDir = (options.paths ?? defaultCapturePaths()).capturesDir;
40818
40471
  const finalPath = path27__default.join(capturesDir, `${fleetSessionId}.json`);
40819
- const tempPath = path27__default.join(capturesDir, `${CAPTURE_TEMP_PREFIX}${fleetSessionId}.${process4.pid}.${Date.now()}.tmp`);
40820
- fs8__default.mkdirSync(capturesDir, { recursive: true, mode: 448 });
40821
- fs8__default.writeFileSync(tempPath, `${JSON.stringify(providerSession, null, 2)}
40472
+ const tempPath = path27__default.join(capturesDir, `${CAPTURE_TEMP_PREFIX}${fleetSessionId}.${process5.pid}.${Date.now()}.tmp`);
40473
+ fs2__default.mkdirSync(capturesDir, { recursive: true, mode: 448 });
40474
+ fs2__default.writeFileSync(tempPath, `${JSON.stringify(providerSession, null, 2)}
40822
40475
  `, { mode: 384 });
40823
- fs8__default.renameSync(tempPath, finalPath);
40476
+ fs2__default.renameSync(tempPath, finalPath);
40824
40477
  return { path: finalPath, providerSession };
40825
40478
  }
40826
40479
  function parseProvider(value) {
40827
- if (value === "claude" || value === "codex") return value;
40480
+ if (isProvider(value)) return value;
40828
40481
  throw new Error("invalid_provider");
40829
40482
  }
40830
40483
  function readFleetSessionId(env) {
@@ -40844,10 +40497,10 @@ function parseHookInput(input) {
40844
40497
  throw new Error("invalid_hook_input");
40845
40498
  }
40846
40499
  function toProviderSession(provider, input, now) {
40847
- if (typeof input.session_id !== "string" || input.session_id.length === 0) throw new Error("missing_provider_session_id");
40500
+ const sessionId = readProviderSessionId(input);
40848
40501
  return {
40849
40502
  provider,
40850
- sessionId: input.session_id,
40503
+ sessionId,
40851
40504
  ...typeof input.transcript_path === "string" && input.transcript_path.length > 0 ? { transcriptPath: input.transcript_path } : {},
40852
40505
  ...typeof input.source === "string" && input.source.length > 0 ? { source: input.source } : {},
40853
40506
  capturedAt: now().toISOString()
@@ -40856,7 +40509,7 @@ function toProviderSession(provider, input, now) {
40856
40509
  function sanitizeProviderSession(value) {
40857
40510
  if (!value || typeof value !== "object" || Array.isArray(value)) return null;
40858
40511
  const candidate = value;
40859
- if (candidate.provider !== "claude" && candidate.provider !== "codex" || typeof candidate.sessionId !== "string" || typeof candidate.capturedAt !== "string") return null;
40512
+ if (!isProvider(candidate.provider) || typeof candidate.sessionId !== "string" || typeof candidate.capturedAt !== "string") return null;
40860
40513
  return {
40861
40514
  provider: candidate.provider,
40862
40515
  sessionId: candidate.sessionId,
@@ -40865,6 +40518,15 @@ function sanitizeProviderSession(value) {
40865
40518
  capturedAt: candidate.capturedAt
40866
40519
  };
40867
40520
  }
40521
+ function readProviderSessionId(input) {
40522
+ for (const value of [input.session_id, input.conversation_id, input.chat_id]) {
40523
+ if (typeof value === "string" && value.length > 0) return value;
40524
+ }
40525
+ throw new Error("missing_provider_session_id");
40526
+ }
40527
+ function isProvider(value) {
40528
+ return value === "claude" || value === "codex" || value === "cursor";
40529
+ }
40868
40530
  function isSafeCaptureId(value) {
40869
40531
  return value.length > 0 && path27__default.basename(value) === value && !value.includes(path27__default.sep) && !value.includes(path27__default.posix.sep);
40870
40532
  }
@@ -40874,12 +40536,6 @@ function defaultCapturePaths() {
40874
40536
  var JAVASCRIPT_ENTRY_EXTENSIONS = /* @__PURE__ */ new Set([".cjs", ".js", ".mjs"]);
40875
40537
  var TYPESCRIPT_ENTRY_EXTENSIONS = /* @__PURE__ */ new Set([".cts", ".mts", ".ts", ".tsx"]);
40876
40538
  var MARKETPLACE_LOCK_DIR_SUFFIX = ".lock";
40877
- function buildConsoleHookCommand(entry) {
40878
- if (entry === void 0) {
40879
- throw new Error("Fleet Console session hook command requires the current console entry path");
40880
- }
40881
- return buildConsoleCliHookExec(entry, ["hook", "subagents-context"]);
40882
- }
40883
40539
  function buildConsoleTurnHookCommand(entry, phase) {
40884
40540
  return buildConsoleCliHookExec(entry, ["hook", phase === "start" ? "turn-start" : "turn-end"]);
40885
40541
  }
@@ -40912,16 +40568,12 @@ function buildConsoleCaptureHookCommand(entry, cliId) {
40912
40568
  throw new Error(`Unsupported Fleet Console session hook entry extension: ${extension}`);
40913
40569
  }
40914
40570
  function toCaptureProvider(cliId) {
40915
- return cliId === "codex" ? "codex" : "claude";
40571
+ if (cliId === "codex") return "codex";
40572
+ if (cliId === "cursor") return "cursor";
40573
+ return "claude";
40916
40574
  }
40917
40575
  function runCodexCommand(command) {
40918
- const result = spawnSync(command.bin, command.args, {
40919
- cwd: command.cwd,
40920
- encoding: "utf8",
40921
- env: command.env,
40922
- // 콘솔 없는 fleet-console 백엔드에서 codex 등록 명령 실행 시 콘솔 창이 깜빡이는 것을 방지한다.
40923
- windowsHide: true
40924
- });
40576
+ const result = spawnSync(command.bin, command.args, withHidden({ cwd: command.cwd, encoding: "utf8", env: command.env }));
40925
40577
  return {
40926
40578
  status: result.status,
40927
40579
  stderr: result.stderr ?? "",
@@ -40960,19 +40612,18 @@ var CONSOLE_ENTRY_PATH = fileURLToPath(import.meta.url);
40960
40612
  var HOOK_ENTRY_EXTENSIONS = /* @__PURE__ */ new Set([".cjs", ".cts", ".js", ".mjs", ".mts", ".ts", ".tsx"]);
40961
40613
  var require4 = createRequire(import.meta.url);
40962
40614
  function createAgentTerminalLaunchResolver(deps = {}) {
40963
- const baseCwd = deps.cwd ?? process4.cwd();
40964
- const env = deps.env ?? process4.env;
40965
- const execPath = deps.execPath ?? process4.execPath;
40615
+ const baseCwd = deps.cwd ?? process5.cwd();
40616
+ const env = deps.env ?? process5.env;
40617
+ const execPath = deps.execPath ?? process5.execPath;
40966
40618
  const homedir3 = deps.homedir ?? DEFAULT_TERMINAL_CWD_FALLBACK2;
40967
- const platform = deps.platform ?? process4.platform;
40968
- const entryPath = resolveHookEntryPath(deps.entryPath ?? process4.argv[1]);
40619
+ const platform = deps.platform ?? process5.platform;
40620
+ const entryPath = resolveHookEntryPath(deps.entryPath ?? process5.argv[1]);
40969
40621
  const tsxLoaderPath = deps.tsxLoaderPath ?? resolveOptionalPackage("tsx");
40970
40622
  const dataDir = deps.dataDir ?? getFleetDataDir();
40971
40623
  const infraServices = deps.infraServices ?? createInfraServices();
40972
40624
  const agentRuntime = deps.agentRuntime;
40973
40625
  const injectProfile = deps.injectProfile ?? injectAgentCliProfile;
40974
40626
  const resolveProfile = deps.resolveProfile ?? resolveAgentCliProfile;
40975
- const authEnvResolver = (cli) => resolveAuthEnv(cli, { authService: infraServices.authService });
40976
40627
  const hookEntry = { entryPath, execPath, ...tsxLoaderPath ? { tsxLoaderPath } : {} };
40977
40628
  return async (selectedCwd, context) => {
40978
40629
  const cwd = selectedCwd || baseCwd || homedir3();
@@ -40992,7 +40643,6 @@ function createAgentTerminalLaunchResolver(deps = {}) {
40992
40643
  }
40993
40644
  const sessionId = context?.sessionId ?? "default";
40994
40645
  return createAgentCliLaunchSpec({
40995
- authEnvResolver,
40996
40646
  agentRuntime,
40997
40647
  cwd,
40998
40648
  dataDir,
@@ -41012,7 +40662,7 @@ function resolveHookEntryPath(candidate) {
41012
40662
  if (candidate && hasHookEntryExtension(candidate)) return candidate;
41013
40663
  if (candidate) {
41014
40664
  try {
41015
- const realPath = fs8__default.realpathSync(candidate);
40665
+ const realPath = fs2__default.realpathSync(candidate);
41016
40666
  if (hasHookEntryExtension(realPath)) return realPath;
41017
40667
  } catch {
41018
40668
  }
@@ -41030,15 +40680,12 @@ async function createAgentCliLaunchSpec(options) {
41030
40680
  throw new Error("Fleet Console agent runtime is unavailable.");
41031
40681
  }
41032
40682
  const profile = await options.resolveProfile(options.env, options.cwd, {
41033
- authEnvResolver: options.authEnvResolver,
41034
- authService: options.infraServices.authService,
41035
40683
  cliId: options.cliId,
41036
40684
  resumeSessionId: options.resumeSessionId
41037
40685
  });
41038
40686
  const globalSettings = readGlobalSettingsSnapshot(options.infraServices);
41039
40687
  const injectedProfile = await options.injectProfile(profile, {
41040
40688
  buildSystemPrompt: (injectTone) => createSystemPromptBuilder({ carrierRuntime: agentRuntime.carrierRuntime }).build(injectTone),
41041
- carrierRuntime: agentRuntime.carrierRuntime,
41042
40689
  codexCommandRunner: runCodexCommand,
41043
40690
  dataDir: options.dataDir,
41044
40691
  dedicatedMcpSession: agentRuntime.dedicatedMcpSession,
@@ -41048,9 +40695,7 @@ async function createAgentCliLaunchSpec(options) {
41048
40695
  turnEndHookExec: buildConsoleTurnHookCommand(options.hookEntry, "end"),
41049
40696
  inputWaitingHookExec: buildConsoleAttentionHookCommand(options.hookEntry),
41050
40697
  autoNameHookExec: buildConsoleAutoNameHookCommand(options.hookEntry),
41051
- hookExec: buildConsoleHookCommand(options.hookEntry),
41052
40698
  onCleanup: (cleanup) => cleanupStack.push(cleanup),
41053
- replaceSystemPrompt: globalSettings.replaceSystemPrompt,
41054
40699
  resumeSessionId: options.resumeSessionId,
41055
40700
  withMarketplaceLock: withConsoleMarketplaceLock,
41056
40701
  mcpSessionLabel: options.sessionId
@@ -41134,12 +40779,9 @@ function resolveOptionalPackage(id) {
41134
40779
  function readGlobalSettingsSnapshot(infraServices) {
41135
40780
  try {
41136
40781
  const data = infraServices.globalOptionsService.load();
41137
- return {
41138
- enableMetaphor: data.enableMetaphor ?? false,
41139
- replaceSystemPrompt: data.replaceSystemPrompt ?? false
41140
- };
40782
+ return { enableMetaphor: data.enableMetaphor ?? false };
41141
40783
  } catch {
41142
- return { enableMetaphor: false, replaceSystemPrompt: false };
40784
+ return { enableMetaphor: false };
41143
40785
  }
41144
40786
  }
41145
40787
  var TENANT_EVENT_LIMIT = 1e3;
@@ -41276,7 +40918,6 @@ function createConsoleObservabilityStore(deps = {}) {
41276
40918
  cwdLabel: path27__default.basename(operation.cwd) || operation.cwd,
41277
40919
  label: operation.label,
41278
40920
  labelSource: operation.labelSource,
41279
- autoNamePromptSeen: operation.autoNamePromptSeen,
41280
40921
  cliId: operation.cliId,
41281
40922
  cliLabel: operation.cliLabel,
41282
40923
  createdAt: operation.createdAt,
@@ -41298,7 +40939,6 @@ function createConsoleObservabilityStore(deps = {}) {
41298
40939
  cwd: session.cwd,
41299
40940
  ...session.label ? { label: session.label } : {},
41300
40941
  ...session.labelSource ? { labelSource: session.labelSource } : {},
41301
- ...session.autoNamePromptSeen ? { autoNamePromptSeen: true } : {},
41302
40942
  ...session.cliId ? { cliId: session.cliId } : {},
41303
40943
  ...session.cliLabel ? { cliLabel: session.cliLabel } : {},
41304
40944
  createdAt: session.createdAt,
@@ -41345,11 +40985,9 @@ function createConsoleObservabilityStore(deps = {}) {
41345
40985
  if (label.length === 0) {
41346
40986
  delete session.label;
41347
40987
  delete session.labelSource;
41348
- delete session.autoNamePromptSeen;
41349
40988
  } else {
41350
40989
  session.label = label;
41351
40990
  session.labelSource = "user";
41352
- session.autoNamePromptSeen = true;
41353
40991
  }
41354
40992
  return toTerminalSessionInfo(session);
41355
40993
  }
@@ -41357,17 +40995,16 @@ function createConsoleObservabilityStore(deps = {}) {
41357
40995
  const session = terminalSessionsById.get(sessionId);
41358
40996
  if (!session) return null;
41359
40997
  const effectiveSource = session.labelSource ?? (session.label ? "user" : void 0);
41360
- if (effectiveSource === "user" || session.autoNamePromptSeen) {
41361
- return { session: toTerminalSessionInfo(session), changed: false, renamed: false };
40998
+ if (effectiveSource === "user") {
40999
+ return { session: toTerminalSessionInfo(session), renamed: false };
41362
41000
  }
41363
- session.autoNamePromptSeen = true;
41364
41001
  const next = label?.trim().slice(0, 200) ?? "";
41365
41002
  if (next.length === 0 || next === session.label) {
41366
- return { session: toTerminalSessionInfo(session), changed: true, renamed: false };
41003
+ return { session: toTerminalSessionInfo(session), renamed: false };
41367
41004
  }
41368
41005
  session.label = next;
41369
41006
  session.labelSource = "auto";
41370
- return { session: toTerminalSessionInfo(session), changed: true, renamed: true };
41007
+ return { session: toTerminalSessionInfo(session), renamed: true };
41371
41008
  }
41372
41009
  function notifySessionUpdated(session) {
41373
41010
  const event = { type: "session:updated", session };
@@ -41502,12 +41139,12 @@ function toTerminalSessionInfo(state) {
41502
41139
  };
41503
41140
  }
41504
41141
  function defaultWorkspaceHash(canonicalCwd) {
41505
- return crypto3.createHash("sha256").update(canonicalCwd).digest("hex").slice(0, 12);
41142
+ return crypto4.createHash("sha256").update(canonicalCwd).digest("hex").slice(0, 12);
41506
41143
  }
41507
41144
  function defaultCanonicalizeTheaterPath(cwd) {
41508
41145
  const resolved = path27__default.resolve(cwd);
41509
41146
  try {
41510
- return fs8__default.realpathSync.native(resolved);
41147
+ return fs2__default.realpathSync.native(resolved);
41511
41148
  } catch {
41512
41149
  return resolved;
41513
41150
  }
@@ -41539,7 +41176,8 @@ function normalizeEventPayload(event) {
41539
41176
  label: safeString(obj.label),
41540
41177
  startedAt: safeNumber(obj.startedAt),
41541
41178
  activeJobToolCallId: safeOptionalString(obj.activeJobToolCallId),
41542
- tracks: Array.isArray(obj.tracks) ? obj.tracks.map(normalizeTrackMeta) : []
41179
+ tracks: Array.isArray(obj.tracks) ? obj.tracks.map(normalizeTrackMeta) : [],
41180
+ signatureCli: safeOptionalString(obj.signatureCli)
41543
41181
  };
41544
41182
  case "job:finalized":
41545
41183
  return {
@@ -41721,26 +41359,6 @@ function withAgentSecurityHeaders(headers) {
41721
41359
  };
41722
41360
  }
41723
41361
 
41724
- // ../fleet-plugins/terminal/server/model-auth-state.ts
41725
- var TERMINAL_MODEL_AUTH_PROVIDERS = [
41726
- { cli: "claude-kimi", displayName: "Moonshot Kimi" },
41727
- { cli: "claude-glm", displayName: "ZhipuAI GLM" }
41728
- ];
41729
- async function buildModelAuthState(authService) {
41730
- const signedInIds = new Set(await authService.listProviderIds());
41731
- return {
41732
- providers: TERMINAL_MODEL_AUTH_PROVIDERS.map((provider) => toProviderState(provider, signedInIds))
41733
- };
41734
- }
41735
- function toProviderState(provider, signedInIds) {
41736
- const providerId = CLI_TO_AUTH_PROVIDER_ID[provider.cli] ?? provider.cli;
41737
- return {
41738
- cli: provider.cli,
41739
- displayName: provider.displayName,
41740
- signedIn: signedInIds.has(providerId)
41741
- };
41742
- }
41743
-
41744
41362
  // ../fleet-plugins/terminal/server/agent.ts
41745
41363
  var AGENT_OPERATION_TYPE = "agent";
41746
41364
  var OPERATION_RENAMED_EVENT_CHANNEL = "operation:renamed";
@@ -41755,12 +41373,15 @@ function registerAgentRoutes(ctx, terminalRuntime, deps) {
41755
41373
  registerRouter(ctx, "agent", api.handle);
41756
41374
  return api.launchKinds;
41757
41375
  }
41376
+ function buildAgentLaunchKindBackfillPatch(operation) {
41377
+ if (operation.pluginId !== TERMINAL_PLUGIN_ID || operation.type !== AGENT_OPERATION_TYPE) return null;
41378
+ const cliId = operation.payload.cliId;
41379
+ if (typeof cliId !== "string" || cliId.length === 0) return null;
41380
+ if (operation.payload.launchKindId !== void 0) return null;
41381
+ return { payload: { ...operation.payload, launchKindId: cliId } };
41382
+ }
41758
41383
  function createAgentApi(ctx, terminalRuntime, deps) {
41759
- const dataDir = ctx.host.paths.dataDir;
41760
- const authEnvResolver = (cli) => resolveAuthEnv(cli, { authService: deps.authService });
41761
41384
  const runtime = createFleetAgentRuntimeLifecycle({
41762
- authEnvResolver,
41763
- dataDir,
41764
41385
  onMcpServerStartError: (error51) => {
41765
41386
  console.error("[fleet-console] Failed to start MCP server", error51);
41766
41387
  },
@@ -41776,7 +41397,6 @@ function createAgentApi(ctx, terminalRuntime, deps) {
41776
41397
  const jobOriginById = /* @__PURE__ */ new Map();
41777
41398
  const launchResolver = createAgentTerminalLaunchResolver({
41778
41399
  agentRuntime: runtime,
41779
- dataDir,
41780
41400
  infraServices: deps,
41781
41401
  onRuntimeSessionStart: (session) => {
41782
41402
  pendingRuntimeSessions.set(session.sessionId, session);
@@ -41785,7 +41405,7 @@ function createAgentApi(ctx, terminalRuntime, deps) {
41785
41405
  const unsubscribeStream = runtime.carrierRuntime.jobs.streaming.register((event) => {
41786
41406
  const sessionId = resolveCarrierEventOrigin(event, jobOriginById);
41787
41407
  if (!sessionId) return;
41788
- observability.appendTerminalRuntimeEvent(sessionId, event);
41408
+ observability.appendTerminalRuntimeEvent(sessionId, withSignatureCli(event, runtime.carrierRuntime.registry));
41789
41409
  });
41790
41410
  const unsubscribeReminder = createCarrierResultReminderRouter({
41791
41411
  streamRegister: runtime.carrierRuntime.jobs.streaming.register,
@@ -41801,8 +41421,19 @@ function createAgentApi(ctx, terminalRuntime, deps) {
41801
41421
  const unsubscribeRename = ctx.host.events.subscribe(OPERATION_RENAMED_EVENT_CHANNEL, (payload) => {
41802
41422
  if (!isOperationRenamedEvent(payload)) return;
41803
41423
  if (payload.pluginId !== TERMINAL_PLUGIN_ID || payload.type !== AGENT_OPERATION_TYPE) return;
41424
+ const updated = observability.renameTerminalSession(payload.operationId, payload.title);
41425
+ if (updated) {
41426
+ observability.notifySessionUpdated(updated);
41427
+ const operation = ctx.host.operations.get(payload.operationId);
41428
+ if (operation) {
41429
+ const cwd = readPayloadString(operation.payload, "cwd") || ctx.host.paths.resolveTheaterPath(operation.theaterId) || "";
41430
+ const providerSession = readProviderSession(operation.payload);
41431
+ ctx.host.operations.patch(payload.operationId, { title: updated.label ?? updated.cwdLabel, payload: toOperationPayload(cwd, updated, providerSession) });
41432
+ }
41433
+ }
41804
41434
  injectRenameCommand(payload.operationId, payload.title);
41805
41435
  });
41436
+ backfillAgentOperationLaunchKinds();
41806
41437
  rehydrateDormantAgentOperations();
41807
41438
  async function handle({ req, res, pathname }) {
41808
41439
  const path42 = pathname.slice(`${ctx.basePath}/agent`.length) || "/";
@@ -41926,24 +41557,6 @@ function createAgentApi(ctx, terminalRuntime, deps) {
41926
41557
  ctx.host.http.writeJson(res, 200, { ok: true });
41927
41558
  return true;
41928
41559
  }
41929
- if (req.method === "PATCH") {
41930
- const body = await ctx.host.http.readJsonBody(req);
41931
- if (!body || body.label !== void 0 && typeof body.label !== "string") {
41932
- ctx.host.http.writeJson(res, 400, { error: "invalid_session_label" });
41933
- return true;
41934
- }
41935
- const updated = observability.renameTerminalSession(sessionId, body.label ?? "");
41936
- if (!updated) {
41937
- ctx.host.http.writeJson(res, 404, { error: "session_not_found" });
41938
- return true;
41939
- }
41940
- observability.notifySessionUpdated(updated);
41941
- const renamedCwd = readPayloadString(ctx.host.operations.get(sessionId)?.payload ?? {}, "cwd") ?? updated.cwdLabel;
41942
- ctx.host.operations.patch(sessionId, { title: updated.label ?? path27__default.basename(renamedCwd) });
41943
- injectRenameCommand(sessionId, updated.label);
41944
- ctx.host.http.writeJson(res, 200, updated);
41945
- return true;
41946
- }
41947
41560
  return methodNotAllowed(res);
41948
41561
  }
41949
41562
  async function createSession(cwd, theaterId, cliId, res) {
@@ -41952,7 +41565,7 @@ function createAgentApi(ctx, terminalRuntime, deps) {
41952
41565
  ctx.host.http.writeJson(res, 409, { error: "agent_cli_unavailable" });
41953
41566
  return;
41954
41567
  }
41955
- const sessionId = crypto3.randomUUID();
41568
+ const sessionId = crypto4.randomUUID();
41956
41569
  const session = observability.createPendingTerminalSession({ sessionId, cwd, cliId });
41957
41570
  ctx.host.operations.create({
41958
41571
  id: session.sessionId,
@@ -42084,8 +41697,8 @@ function createAgentApi(ctx, terminalRuntime, deps) {
42084
41697
  return true;
42085
41698
  }
42086
41699
  const result = captureSession({
42087
- diagnostics: process4.stderr,
42088
- env: { ...process4.env, FLEET_CONSOLE_SESSION_ID: sessionId },
41700
+ diagnostics: process5.stderr,
41701
+ env: { ...process5.env, FLEET_CONSOLE_SESSION_ID: sessionId },
42089
41702
  input: body.input,
42090
41703
  paths: ctx.host.paths,
42091
41704
  provider: body.provider
@@ -42104,14 +41717,11 @@ function createAgentApi(ctx, terminalRuntime, deps) {
42104
41717
  }
42105
41718
  async function buildAgentCliLaunchMetadata() {
42106
41719
  const metadata = getAgentCliMetadata();
42107
- if ((process4.env.FLEET_TERMINAL_CMD ?? "").trim().length > 0) {
41720
+ if ((process5.env.FLEET_TERMINAL_CMD ?? "").trim().length > 0) {
42108
41721
  return metadata.map((meta3) => ({ id: meta3.id, label: meta3.label, available: true, signedIn: true }));
42109
41722
  }
42110
- const [detected, modelAuth] = await Promise.all([
42111
- detector.detect(),
42112
- buildModelAuthState(deps.authService)
42113
- ]);
42114
- return combineAgentCliLaunchMetadata(metadata, detected, modelAuth.providers);
41723
+ const detected = await detector.detect();
41724
+ return combineAgentCliLaunchMetadata(metadata, detected, []);
42115
41725
  }
42116
41726
  async function buildLaunchKinds() {
42117
41727
  const metadata = await buildAgentCliLaunchMetadata();
@@ -42187,6 +41797,13 @@ function createAgentApi(ctx, terminalRuntime, deps) {
42187
41797
  ctx.host.operations.patch(operation.id, { payload: { ...operation.payload, ...toOperationPayload(cwd, dormant, providerSession) } });
42188
41798
  }
42189
41799
  }
41800
+ function backfillAgentOperationLaunchKinds() {
41801
+ for (const operation of ctx.host.operations.list()) {
41802
+ const patch = buildAgentLaunchKindBackfillPatch(operation);
41803
+ if (!patch) continue;
41804
+ ctx.host.operations.patch(operation.id, patch);
41805
+ }
41806
+ }
42190
41807
  return { cleanup, handle, handleExit, launch, launchKinds: buildLaunchKinds };
42191
41808
  function methodNotAllowed(res) {
42192
41809
  ctx.host.http.writeJson(res, 405, { error: "Method not allowed" });
@@ -42201,6 +41818,7 @@ function toOperationPayload(cwd, session, providerSession) {
42201
41818
  return {
42202
41819
  cwd,
42203
41820
  ...session.cliId ? { cliId: session.cliId } : {},
41821
+ ...session.cliId ? { launchKindId: session.cliId } : {},
42204
41822
  ...session.cliLabel ? { cliLabel: session.cliLabel } : {},
42205
41823
  ...providerSession ? { providerSession } : {},
42206
41824
  ...session.labelSource ? { labelSource: session.labelSource } : {}
@@ -42230,7 +41848,7 @@ function readProviderSession(value) {
42230
41848
  const providerSession = value?.providerSession;
42231
41849
  if (!providerSession || typeof providerSession !== "object") return void 0;
42232
41850
  const candidate = providerSession;
42233
- if (candidate.provider !== "claude" && candidate.provider !== "codex" || typeof candidate.sessionId !== "string" || typeof candidate.capturedAt !== "string") return void 0;
41851
+ if (!isProvider2(candidate.provider) || typeof candidate.sessionId !== "string" || typeof candidate.capturedAt !== "string") return void 0;
42234
41852
  return {
42235
41853
  provider: candidate.provider,
42236
41854
  sessionId: candidate.sessionId,
@@ -42239,6 +41857,9 @@ function readProviderSession(value) {
42239
41857
  ...typeof candidate.source === "string" ? { source: candidate.source } : {}
42240
41858
  };
42241
41859
  }
41860
+ function isProvider2(value) {
41861
+ return value === "claude" || value === "codex" || value === "cursor";
41862
+ }
42242
41863
  function resolveCarrierEventOrigin(event, jobOriginById) {
42243
41864
  if (event.originSessionId) {
42244
41865
  jobOriginById.set(event.jobId, event.originSessionId);
@@ -42271,135 +41892,55 @@ function readHookPrompt(value) {
42271
41892
  return void 0;
42272
41893
  }
42273
41894
  }
42274
-
42275
- // ../fleet-plugins/terminal/server/model-auth-routes.ts
42276
- var UPSTREAM_FAILURE_STATUSES = /* @__PURE__ */ new Set(["timeout", "network", "server"]);
42277
- function registerTerminalModelAuthRoutes(ctx, deps) {
42278
- registerRouter(ctx, "model-auth", createTerminalModelAuthRouter(ctx, {
42279
- ...deps,
42280
- validateApiKey: (cli, apiKey) => validateAuthKeyForCli(cli, apiKey)
42281
- }));
42282
- }
42283
- function createTerminalModelAuthRouter(ctx, deps) {
42284
- return async function handleTerminalModelAuthRoute({ req, res, pathname }) {
42285
- const path42 = pathname.slice(`${ctx.basePath}/model-auth`.length) || "/";
42286
- if (path42 === "/state") {
42287
- if (req.method !== "GET") {
42288
- ctx.host.http.writeJson(res, 405, { error: "Method not allowed" });
42289
- return true;
42290
- }
42291
- ctx.host.http.writeJson(res, 200, await buildModelAuthState(deps.authService));
41895
+ function withSignatureCli(event, registry3) {
41896
+ if (typeof event !== "object" || event === null) return event;
41897
+ const obj = event;
41898
+ if (obj.type !== "job:registered" || typeof obj.ownerCarrierId !== "string") return event;
41899
+ const config2 = getCarrierConfig(registry3, obj.ownerCarrierId);
41900
+ if (!config2) return event;
41901
+ const signatureCli = resolveAgentCliType2(obj.ownerCarrierId, config2.defaultCliType);
41902
+ return { ...obj, signatureCli };
41903
+ }
41904
+ var GLOBAL_SHELL_SESSION_ID = "global-shell";
41905
+ var GLOBAL_SHELL_OPERATION_TYPE = "shell";
41906
+ function registerGlobalShellRoutes(ctx, runtime) {
41907
+ registerRouter(ctx, "global/ticket", async ({ req, res }) => {
41908
+ if (req.method !== "POST") {
41909
+ ctx.host.http.writeJson(res, 405, { error: "Method not allowed" });
42292
41910
  return true;
42293
41911
  }
42294
- const cli = parseProviderPath(path42);
42295
- if (!cli) return false;
42296
- const provider = await findProvider(deps, cli);
42297
- if (!provider) {
42298
- ctx.host.http.writeJson(res, 404, { error: "provider_not_found" });
41912
+ if (!ctx.host.security.isTerminalAuthorized(req)) {
41913
+ ctx.host.http.writeJson(res, 401, { error: "Unauthorized" });
42299
41914
  return true;
42300
41915
  }
42301
- if (req.method === "PUT") {
42302
- await signInProvider(ctx, req, res, deps, provider);
41916
+ if (req.headers.origin === void 0) {
41917
+ ctx.host.http.writeJson(res, 401, { error: "Unauthorized" });
42303
41918
  return true;
42304
41919
  }
42305
- if (req.method === "DELETE") {
42306
- await signOutProvider(ctx, req, res, deps, provider);
41920
+ const body = await ctx.host.http.readJsonBody(req);
41921
+ const operationId = typeof body?.operationId === "string" ? body.operationId : typeof body?.sessionId === "string" ? body.sessionId : null;
41922
+ if (!operationId) {
41923
+ ctx.host.http.writeJson(res, 400, { error: "operation_id_required" });
42307
41924
  return true;
42308
41925
  }
42309
- ctx.host.http.writeJson(res, 405, { error: "Method not allowed" });
41926
+ if (operationId !== GLOBAL_SHELL_SESSION_ID) {
41927
+ ctx.host.http.writeJson(res, 409, { error: "invalid_global_shell_operation" });
41928
+ return true;
41929
+ }
41930
+ if (!runtime.canAttach(GLOBAL_SHELL_SESSION_ID)) {
41931
+ ctx.host.http.writeJson(res, 503, { error: "Terminal session capacity exhausted" });
41932
+ return true;
41933
+ }
41934
+ ctx.host.http.writeJson(res, 200, runtime.issueTicket({
41935
+ cwd: homedir(),
41936
+ sessionId: GLOBAL_SHELL_SESSION_ID,
41937
+ operationId,
41938
+ operationType: GLOBAL_SHELL_OPERATION_TYPE,
41939
+ pluginId: ctx.pluginId,
41940
+ kind: "shell"
41941
+ }));
42310
41942
  return true;
42311
- };
42312
- }
42313
- async function signInProvider(ctx, req, res, deps, provider) {
42314
- if (!ctx.host.security.isTerminalAuthorized(req)) {
42315
- ctx.host.http.writeJson(res, 401, { error: "unauthorized" });
42316
- return;
42317
- }
42318
- if (!isJsonRequest(req)) {
42319
- ctx.host.http.writeJson(res, 415, { error: "unsupported_media_type" });
42320
- return;
42321
- }
42322
- const body = await ctx.host.http.readJsonBody(req);
42323
- if (!body || typeof body !== "object" || Array.isArray(body)) {
42324
- ctx.host.http.writeJson(res, 400, { error: "invalid_json" });
42325
- return;
42326
- }
42327
- if (Object.keys(body).length !== 1 || typeof body.apiKey !== "string") {
42328
- ctx.host.http.writeJson(res, 400, { error: "invalid_api_key" });
42329
- return;
42330
- }
42331
- const apiKey = body.apiKey.trim();
42332
- if (apiKey.length === 0) {
42333
- ctx.host.http.writeJson(res, 400, { error: "invalid_api_key" });
42334
- return;
42335
- }
42336
- const providerId = CLI_TO_AUTH_PROVIDER_ID[provider.cli];
42337
- if (!providerId) {
42338
- ctx.host.http.writeJson(res, 500, { error: "provider_unavailable" });
42339
- return;
42340
- }
42341
- const validation = await deps.validateApiKey(provider.cli, apiKey);
42342
- if (validation.status !== "success") {
42343
- const status = UPSTREAM_FAILURE_STATUSES.has(validation.status) ? 502 : 400;
42344
- ctx.host.http.writeJson(res, status, {
42345
- error: formatSignInFailureMessage(provider.displayName, validation.status),
42346
- status: validation.status
42347
- });
42348
- return;
42349
- }
42350
- await deps.authService.setApiKey(providerId, apiKey);
42351
- await writeMutationState(ctx, res, deps);
42352
- }
42353
- async function signOutProvider(ctx, req, res, deps, provider) {
42354
- if (!ctx.host.security.isTerminalAuthorized(req)) {
42355
- ctx.host.http.writeJson(res, 401, { error: "unauthorized" });
42356
- return;
42357
- }
42358
- const providerId = CLI_TO_AUTH_PROVIDER_ID[provider.cli];
42359
- if (!providerId) {
42360
- ctx.host.http.writeJson(res, 500, { error: "provider_unavailable" });
42361
- return;
42362
- }
42363
- await deps.authService.deleteApiKey(providerId);
42364
- await writeMutationState(ctx, res, deps);
42365
- }
42366
- async function writeMutationState(ctx, res, deps) {
42367
- ctx.host.http.writeJson(res, 200, { state: await buildModelAuthState(deps.authService) });
42368
- }
42369
- async function findProvider(deps, cli) {
42370
- return (await buildModelAuthState(deps.authService)).providers.find((provider) => provider.cli === cli) ?? null;
42371
- }
42372
- function parseProviderPath(path42) {
42373
- const parts = path42.split("/").filter(Boolean);
42374
- if (parts.length !== 2 || parts[0] !== "providers") return null;
42375
- return safeDecodeURIComponent(parts[1] ?? "");
42376
- }
42377
- function safeDecodeURIComponent(value) {
42378
- try {
42379
- return decodeURIComponent(value);
42380
- } catch {
42381
- return null;
42382
- }
42383
- }
42384
- function isJsonRequest(req) {
42385
- const contentType = req.headers["content-type"];
42386
- return typeof contentType === "string" && contentType.toLowerCase().split(";")[0]?.trim() === "application/json";
42387
- }
42388
- function formatSignInFailureMessage(displayName, status) {
42389
- switch (status) {
42390
- case "unauthorized":
42391
- return `${displayName} rejected the API key. Check the key and try again.`;
42392
- case "forbidden":
42393
- return `The API key is not allowed for ${displayName}. Check its permissions.`;
42394
- case "timeout":
42395
- return `Validating the ${displayName} API key timed out. Check your connection and try again.`;
42396
- case "network":
42397
- return `Could not reach ${displayName} to validate the API key. Check your connection and try again.`;
42398
- case "server":
42399
- return `${displayName} returned an error while validating the API key. Try again later.`;
42400
- default:
42401
- return `Could not validate the ${displayName} API key. Check the key and try again.`;
42402
- }
41943
+ });
42403
41944
  }
42404
41945
 
42405
41946
  // ../fleet-plugins/terminal/server/settings-routes.ts
@@ -42414,7 +41955,7 @@ function registerTerminalSettingsRoutes(ctx, deps) {
42414
41955
  ctx.host.http.writeJson(res, 401, { error: "unauthorized" });
42415
41956
  return true;
42416
41957
  }
42417
- if (!isJsonRequest2(req)) {
41958
+ if (!isJsonRequest(req)) {
42418
41959
  ctx.host.http.writeJson(res, 415, { error: "unsupported_media_type" });
42419
41960
  return true;
42420
41961
  }
@@ -42425,7 +41966,6 @@ function registerTerminalSettingsRoutes(ctx, deps) {
42425
41966
  }
42426
41967
  const updated = deps.globalOptionsService.update((current) => ({
42427
41968
  ...current,
42428
- replaceSystemPrompt: body.replaceSystemPrompt,
42429
41969
  enableMetaphor: body.enableMetaphor
42430
41970
  }));
42431
41971
  ctx.host.http.writeJson(res, 200, toTerminalSettingsState(updated));
@@ -42437,17 +41977,16 @@ function registerTerminalSettingsRoutes(ctx, deps) {
42437
41977
  }
42438
41978
  function toTerminalSettingsState(data) {
42439
41979
  return {
42440
- replaceSystemPrompt: data.replaceSystemPrompt ?? false,
42441
41980
  enableMetaphor: data.enableMetaphor ?? false
42442
41981
  };
42443
41982
  }
42444
41983
  function isTerminalSettingsBody(value) {
42445
41984
  if (!value || typeof value !== "object" || Array.isArray(value)) return false;
42446
- if (Object.keys(value).length !== 2) return false;
41985
+ if (Object.keys(value).length !== 1) return false;
42447
41986
  const body = value;
42448
- return typeof body.replaceSystemPrompt === "boolean" && typeof body.enableMetaphor === "boolean";
41987
+ return typeof body.enableMetaphor === "boolean";
42449
41988
  }
42450
- function isJsonRequest2(req) {
41989
+ function isJsonRequest(req) {
42451
41990
  const contentType = req.headers["content-type"];
42452
41991
  return typeof contentType === "string" && contentType.toLowerCase().split(";")[0]?.trim() === "application/json";
42453
41992
  }
@@ -42537,10 +42076,9 @@ var routes_default = definePlugin({
42537
42076
  });
42538
42077
  ctx.host.lifecycle.registerCleanup(unsubscribeDelete);
42539
42078
  registerShellRoutes(ctx, runtime);
42079
+ registerGlobalShellRoutes(ctx, runtime);
42540
42080
  registerTerminalSettingsRoutes(ctx, { globalOptionsService: infraServices.globalOptionsService });
42541
- registerTerminalModelAuthRoutes(ctx, { authService: infraServices.authService });
42542
42081
  const agentLaunchKinds = registerAgentRoutes(ctx, runtime, {
42543
- authService: infraServices.authService,
42544
42082
  globalOptionsService: infraServices.globalOptionsService
42545
42083
  });
42546
42084
  registerLaunchCatalog(ctx, async () => [...await agentLaunchKinds(), SHELL_LAUNCH_KIND]);