@dotobokuri/fleet-console 1.18.0 → 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 (67) hide show
  1. package/AGENTS.md +6 -5
  2. package/dist/cli.d.ts +13 -12
  3. package/dist/cli.mjs +143 -175
  4. package/dist/client/assets/SymbolsNerdFontMono-Regular-CoUzE12l.woff2 +0 -0
  5. package/dist/client/assets/{_baseUniq-DFEDX4NY.js → _baseUniq-C4_iQlZS.js} +1 -1
  6. package/dist/client/assets/{arc-CGwMrR6o.js → arc-BBAWxYi5.js} +1 -1
  7. package/dist/client/assets/{architectureDiagram-Q4EWVU46-BqLyvIOK.js → architectureDiagram-Q4EWVU46-_oQqhexV.js} +1 -1
  8. package/dist/client/assets/{blockDiagram-DXYQGD6D-DoiPMLdv.js → blockDiagram-DXYQGD6D-3xT9VFiD.js} +1 -1
  9. package/dist/client/assets/{c4Diagram-AHTNJAMY-DfGxDkah.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-3zXv74oY.js → chunk-4BX2VUAB-tS9Ys0P9.js} +1 -1
  12. package/dist/client/assets/{chunk-4TB4RGXK-MkXUmjUE.js → chunk-4TB4RGXK-YZgAG7SW.js} +1 -1
  13. package/dist/client/assets/{chunk-55IACEB6-mhkgqlI_.js → chunk-55IACEB6-m-CtqHoO.js} +1 -1
  14. package/dist/client/assets/{chunk-EDXVE4YY-B0_ZDihs.js → chunk-EDXVE4YY-yoymxaEV.js} +1 -1
  15. package/dist/client/assets/{chunk-FMBD7UC4-BQAuE4pL.js → chunk-FMBD7UC4-REUkrQAG.js} +1 -1
  16. package/dist/client/assets/{chunk-OYMX7WX6-CY8Eyj9X.js → chunk-OYMX7WX6-DzMuL105.js} +1 -1
  17. package/dist/client/assets/{chunk-QZHKN3VN-CaZoMwKH.js → chunk-QZHKN3VN-DXFFll8-.js} +1 -1
  18. package/dist/client/assets/{chunk-YZCP3GAM-DV1YOEUH.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-Cy3v0C_N.js → cose-bilkent-S5V4N54A-BupE-a40.js} +1 -1
  23. package/dist/client/assets/{dagre-KV5264BT-CGJ6x_VR.js → dagre-KV5264BT-Jn67LxMS.js} +1 -1
  24. package/dist/client/assets/{diagram-5BDNPKRD-MyyXeHKQ.js → diagram-5BDNPKRD-BAeFEORH.js} +1 -1
  25. package/dist/client/assets/{diagram-G4DWMVQ6-D52Q2132.js → diagram-G4DWMVQ6-CnZrDABY.js} +1 -1
  26. package/dist/client/assets/{diagram-MMDJMWI5-DCypusCr.js → diagram-MMDJMWI5-DefG-kXU.js} +1 -1
  27. package/dist/client/assets/{diagram-TYMM5635-c5UBqE9-.js → diagram-TYMM5635-BPkXKB-Q.js} +1 -1
  28. package/dist/client/assets/{erDiagram-SMLLAGMA-BlF0Lxy7.js → erDiagram-SMLLAGMA-Bi4jlild.js} +1 -1
  29. package/dist/client/assets/{flowDiagram-DWJPFMVM-lo8xyzfx.js → flowDiagram-DWJPFMVM-BoZyLO7h.js} +1 -1
  30. package/dist/client/assets/{ganttDiagram-T4ZO3ILL-BXVZMpon.js → ganttDiagram-T4ZO3ILL-LgzSNjrh.js} +1 -1
  31. package/dist/client/assets/{gitGraphDiagram-UUTBAWPF-DB1A6uYk.js → gitGraphDiagram-UUTBAWPF-B4fH-hPT.js} +1 -1
  32. package/dist/client/assets/{graph-Ck2AX1p2.js → graph-D3ZAYMLG.js} +1 -1
  33. package/dist/client/assets/{index-Cf9MmpwN.css → index-DctP_CJP.css} +1 -1
  34. package/dist/client/assets/index-vgEn_EkG.js +404 -0
  35. package/dist/client/assets/{infoDiagram-42DDH7IO-NEVE42fw.js → infoDiagram-42DDH7IO-pENdunXd.js} +1 -1
  36. package/dist/client/assets/{ishikawaDiagram-UXIWVN3A-MbFr_8pL.js → ishikawaDiagram-UXIWVN3A-WakLHKte.js} +1 -1
  37. package/dist/client/assets/{journeyDiagram-VCZTEJTY-Sq2ja3q8.js → journeyDiagram-VCZTEJTY-CrqXKtzk.js} +1 -1
  38. package/dist/client/assets/{kanban-definition-6JOO6SKY-C63qPhtK.js → kanban-definition-6JOO6SKY-DdSC9eJ-.js} +1 -1
  39. package/dist/client/assets/{layout-CFEuVj4N.js → layout-BI1Oko_a.js} +1 -1
  40. package/dist/client/assets/{linear-B626G8Op.js → linear-KUjZtfMe.js} +1 -1
  41. package/dist/client/assets/{mermaid.core-BT7SVKBR.js → mermaid.core-DNlIf4_3.js} +4 -4
  42. package/dist/client/assets/{min-MbEOApMw.js → min-DCAecveI.js} +1 -1
  43. package/dist/client/assets/{mindmap-definition-QFDTVHPH-DMpht5Mg.js → mindmap-definition-QFDTVHPH-BSCyQA-4.js} +1 -1
  44. package/dist/client/assets/{pieDiagram-DEJITSTG-B4XS0haZ.js → pieDiagram-DEJITSTG-C_1I63z5.js} +1 -1
  45. package/dist/client/assets/{quadrantDiagram-34T5L4WZ-CReo5Ajb.js → quadrantDiagram-34T5L4WZ-CtqeYPcA.js} +1 -1
  46. package/dist/client/assets/{requirementDiagram-MS252O5E-A50aqG-K.js → requirementDiagram-MS252O5E-Cpakdg-s.js} +1 -1
  47. package/dist/client/assets/{sankeyDiagram-XADWPNL6-471VOdlW.js → sankeyDiagram-XADWPNL6-CK_eMH3e.js} +1 -1
  48. package/dist/client/assets/{sequenceDiagram-FGHM5R23-BAvOyUC-.js → sequenceDiagram-FGHM5R23-D2YygHqF.js} +1 -1
  49. package/dist/client/assets/{stateDiagram-FHFEXIEX-gCtZrvR-.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-CTHf-uxq.js → timeline-definition-GMOUNBTQ-Brgny70W.js} +1 -1
  52. package/dist/client/assets/{vennDiagram-DHZGUBPP-5gvXi0dO.js → vennDiagram-DHZGUBPP-B1I5E8Hy.js} +1 -1
  53. package/dist/client/assets/{wardley-RL74JXVD-XR-qQTWZ.js → wardley-RL74JXVD-P0VCYfKI.js} +1 -1
  54. package/dist/client/assets/{wardleyDiagram-NUSXRM2D-EwPsMHdt.js → wardleyDiagram-NUSXRM2D-DhYC5Sus.js} +1 -1
  55. package/dist/client/assets/{xychartDiagram-5P7HB3ND-CePwuUb7.js → xychartDiagram-5P7HB3ND-ByJX99rJ.js} +1 -1
  56. package/dist/client/index.html +2 -2
  57. package/dist/fleet-plugins/diff/routes.mjs +207 -34
  58. package/dist/fleet-plugins/file-explorer/routes.mjs +1 -1
  59. package/dist/fleet-plugins/skills/routes.mjs +101 -83
  60. package/dist/fleet-plugins/terminal/routes.mjs +556 -325
  61. package/package.json +1 -1
  62. package/dist/client/assets/channel-DlT8zCVq.js +0 -1
  63. package/dist/client/assets/classDiagram-6PBFFD2Q-B-UN9f9r.js +0 -1
  64. package/dist/client/assets/classDiagram-v2-HSJHXN6E-B-UN9f9r.js +0 -1
  65. package/dist/client/assets/clone-CDPRFCO0.js +0 -1
  66. package/dist/client/assets/index-DWgndVkX.js +0 -404
  67. package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-Bdb0YU66.js +0 -1
@@ -1,15 +1,15 @@
1
1
  #!/usr/bin/env node
2
- import * as fs8 from 'fs';
3
- import fs8__default, { mkdtempSync, writeFileSync, mkdirSync, existsSync, 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';
8
- import crypto3, { createHash, randomUUID } from 'crypto';
9
- import process4 from 'process';
7
+ import os3__default, { homedir } from 'os';
8
+ import crypto4, { createHash, randomUUID } from 'crypto';
9
+ import process5 from 'process';
10
10
  import { EventEmitter } from 'events';
11
11
  import { mkdir, writeFile, access, readFile, stat, readdir, appendFile, rename, rm } from 'fs/promises';
12
- import { execFile, execSync, spawn, spawnSync } from 'child_process';
12
+ import { execFile, spawn, execSync, spawnSync } from 'child_process';
13
13
  import { Writable, Readable } from 'stream';
14
14
  import http from 'http';
15
15
  import { fileURLToPath, pathToFileURL } from 'url';
@@ -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,7 +555,7 @@ function updateGlobalOptions(store2, mutate) {
556
555
  return store2.update(mutate);
557
556
  }
558
557
 
559
- // ../../packages/fleet-infra/src/index.ts
558
+ // ../../packages/core-infra/src/index.ts
560
559
  function createInfraServices(deps = {}) {
561
560
  const globalOptionsService = createGlobalOptionsService();
562
561
  const authService = createAuthService({ authPath: deps.authPath ?? DEFAULT_AUTH_PATH });
@@ -17393,6 +17392,122 @@ var RequestError = class _RequestError extends Error {
17393
17392
  };
17394
17393
  }
17395
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
+ }
17396
17511
 
17397
17512
  // ../../packages/core-unified-agent/src/utils/env.ts
17398
17513
  var REMOVE_KEYS = [
@@ -17430,12 +17545,7 @@ function killProcess(child, forceTimeoutMs = 3e3) {
17430
17545
  markIntentionalKill(child);
17431
17546
  if (isWindows()) {
17432
17547
  try {
17433
- execSync(`taskkill /PID ${child.pid} /T /F`, {
17434
- stdio: "pipe",
17435
- timeout: 5e3,
17436
- // 콘솔 없는 호스트에서 taskkill 호출 시 새 콘솔 창이 깜빡이는 것을 방지한다.
17437
- windowsHide: true
17438
- });
17548
+ execSync(`taskkill /PID ${child.pid} /T /F`, withHidden({ stdio: "pipe", timeout: 5e3 }));
17439
17549
  } catch {
17440
17550
  child.kill("SIGKILL");
17441
17551
  }
@@ -17538,17 +17648,12 @@ var BaseConnection = class extends EventEmitter {
17538
17648
  const child = isWindows() ? spawn(
17539
17649
  this.env.ComSpec ?? "cmd.exe",
17540
17650
  buildWindowsCmdArgs(this.command, this.args),
17541
- {
17651
+ withHidden({
17542
17652
  cwd: this.cwd,
17543
17653
  stdio: ["pipe", "pipe", "pipe"],
17544
17654
  env: this.env,
17545
- windowsVerbatimArguments: true,
17546
- // 콘솔이 없는 호스트(예: fleet-console 백엔드)에서 cmd.exe를 spawn하면
17547
- // Windows가 새 콘솔 창을 할당해 깜빡인다. stdio는 모두 pipe라 가시 콘솔이
17548
- // 불필요하므로 CREATE_NO_WINDOW로 창 생성을 억제한다. (fleet-cli처럼 콘솔이
17549
- // 이미 있는 경우에도 무해하다.)
17550
- windowsHide: true
17551
- }
17655
+ windowsVerbatimArguments: true
17656
+ })
17552
17657
  ) : spawn(this.command, this.args, {
17553
17658
  cwd: this.cwd,
17554
17659
  stdio: ["pipe", "pipe", "pipe"],
@@ -18429,35 +18534,14 @@ function createIdleTimeoutRace(promise2, idleMs, label) {
18429
18534
  });
18430
18535
  return [wrapped, resetTimer];
18431
18536
  }
18537
+
18538
+ // ../../packages/core-unified-agent/src/utils/npx.ts
18432
18539
  function resolveNpxPath(env) {
18433
- const windows = isWindows();
18434
- const whichCmd = windows ? "where npx" : "which npx";
18435
- try {
18436
- const result = execSync(whichCmd, {
18437
- encoding: "utf-8",
18438
- stdio: "pipe",
18439
- timeout: 5e3,
18440
- env,
18441
- // 콘솔 없는 호스트에서 `where npx` 실행 시 콘솔 창이 깜빡이는 것을 방지한다.
18442
- windowsHide: true
18443
- }).trim();
18444
- const candidates = result.split("\n").map((line) => line.trim()).filter((line) => line.length > 0);
18445
- if (windows) {
18446
- const executable = candidates.find((p) => /\.(cmd|bat|exe)$/i.test(p));
18447
- if (executable) {
18448
- return executable;
18449
- }
18450
- }
18451
- if (candidates.length > 0) {
18452
- return candidates[0];
18453
- }
18454
- return windows ? "npx.cmd" : "npx";
18455
- } catch {
18456
- if (windows) {
18457
- return "npx.cmd";
18458
- }
18459
- return "npx";
18540
+ const resolved = findBinaryPath("npx", env ?? process.env);
18541
+ if (resolved) {
18542
+ return resolved;
18460
18543
  }
18544
+ return isWindows() ? "npx.cmd" : "npx";
18461
18545
  }
18462
18546
  function buildNpxArgs(packageName, preferOffline = false) {
18463
18547
  const args = ["--yes"];
@@ -18479,7 +18563,7 @@ var models_default = {
18479
18563
  updatedAt: "2026-07-04T00:00:00Z",
18480
18564
  providers: {
18481
18565
  claude: {
18482
- name: "Claude Code with Anthropic",
18566
+ name: "Claude Code",
18483
18567
  defaultModel: "opus[1m]",
18484
18568
  models: [
18485
18569
  { modelId: "haiku", name: "Claude Haiku", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max"], default: "low" } },
@@ -18492,7 +18576,7 @@ var models_default = {
18492
18576
  ]
18493
18577
  },
18494
18578
  codex: {
18495
- name: "OpenAI Codex CLI",
18579
+ name: "Codex",
18496
18580
  defaultModel: "gpt-5.4",
18497
18581
  models: [
18498
18582
  { modelId: "gpt-5.4", name: "GPT-5.4", effort: { supported: true, levels: ["low", "medium", "high", "xhigh"], default: "high" } },
@@ -18957,25 +19041,23 @@ var CliDetector = class {
18957
19041
  * @returns 사용 가능 여부
18958
19042
  */
18959
19043
  async isCliAvailable(command) {
18960
- const whichCommand = isWindows() ? "where" : "which";
18961
- try {
18962
- await this.execCommand(whichCommand, [command], 3e3);
19044
+ const resolved = findBinaryPath(command, process.env);
19045
+ if (resolved !== void 0) {
18963
19046
  return true;
18964
- } catch {
18965
- if (isWindows()) {
18966
- try {
18967
- await this.execCommand(
18968
- "powershell",
18969
- ["-NoProfile", "-Command", `Get-Command -All ${command}`],
18970
- 5e3
18971
- );
18972
- return true;
18973
- } catch {
18974
- return false;
18975
- }
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;
18976
19058
  }
18977
- return false;
18978
19059
  }
19060
+ return false;
18979
19061
  }
18980
19062
  /**
18981
19063
  * CLI의 버전을 감지합니다.
@@ -18999,13 +19081,8 @@ var CliDetector = class {
18999
19081
  * @returns 전체 경로 또는 커맨드 이름
19000
19082
  */
19001
19083
  async getCliPath(command) {
19002
- const whichCommand = isWindows() ? "where" : "which";
19003
- try {
19004
- const result = await this.execCommand(whichCommand, [command], 3e3);
19005
- return result.split(/\r?\n/)[0].trim();
19006
- } catch {
19007
- return command;
19008
- }
19084
+ const resolved = findBinaryPath(command, process.env);
19085
+ return resolved ?? command;
19009
19086
  }
19010
19087
  /**
19011
19088
  * 외부 명령 실행 결과(stdout)를 문자열로 반환합니다.
@@ -19015,11 +19092,7 @@ var CliDetector = class {
19015
19092
  execFile(
19016
19093
  command,
19017
19094
  args,
19018
- {
19019
- encoding: "utf-8",
19020
- timeout,
19021
- windowsHide: true
19022
- },
19095
+ withHidden({ encoding: "utf-8", timeout }),
19023
19096
  (error51, stdout) => {
19024
19097
  if (error51) {
19025
19098
  reject(error51);
@@ -20235,10 +20308,10 @@ function isMissingRolloutError(error51, threadId) {
20235
20308
  return error51 instanceof Error && error51.message.includes(`no rollout found for thread id ${threadId}`);
20236
20309
  }
20237
20310
  function findRolloutPath(root, threadId) {
20238
- if (!fs8.existsSync(root)) {
20311
+ if (!fs2.existsSync(root)) {
20239
20312
  return null;
20240
20313
  }
20241
- for (const entry of fs8.readdirSync(root, { withFileTypes: true })) {
20314
+ for (const entry of fs2.readdirSync(root, { withFileTypes: true })) {
20242
20315
  const entryPath = path27.join(root, entry.name);
20243
20316
  if (entry.isDirectory()) {
20244
20317
  const found = findRolloutPath(entryPath, threadId);
@@ -21892,7 +21965,7 @@ function specToMcpTool(spec) {
21892
21965
  }
21893
21966
  function installExecutorToolCallRouter(runtime, sessionToken, ctx) {
21894
21967
  runtime.server.setOnToolCallArrived(sessionToken, (toolName, args) => {
21895
- const toolCallId = crypto3.randomUUID();
21968
+ const toolCallId = crypto4.randomUUID();
21896
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) => {
21897
21970
  runtime.server.resolveNextToolCall(sessionToken, toolCallId, {
21898
21971
  content: [{ type: "text", text: err instanceof Error ? err.message : String(err) }],
@@ -22287,7 +22360,7 @@ function createInProcessMcpServer(deps = {}) {
22287
22360
  if (activeStopPromise) await activeStopPromise;
22288
22361
  if (activeServer && activeServerUrl) return activeServerUrl;
22289
22362
  if (activeStartPromise) return activeStartPromise;
22290
- activeOpaquePath = `/${crypto3.randomUUID()}`;
22363
+ activeOpaquePath = `/${crypto4.randomUUID()}`;
22291
22364
  activeStartPromise = new Promise((resolve2, reject) => {
22292
22365
  const srv = http.createServer(handleRequest);
22293
22366
  srv.timeout = MCP_SERVER_TIMEOUT_MS;
@@ -22544,7 +22617,7 @@ function createExecutorMcpSession(deps, toolTimeoutSeconds, request) {
22544
22617
  throw new Error("Executor session cwd is required");
22545
22618
  }
22546
22619
  assertNonEmptyExecutorTools(request.serverName, request.specs);
22547
- const token = crypto3.randomUUID();
22620
+ const token = crypto4.randomUUID();
22548
22621
  registerExecutorSessionTools(runtime.runtime, token, [...request.specs]);
22549
22622
  installExecutorToolCallRouter(runtime.runtime, token, {
22550
22623
  cwd,
@@ -22590,7 +22663,7 @@ function issueSessionToken(deps, sessionTokensByLabel, request) {
22590
22663
  for (const { name, runtime } of deps.runtimes) {
22591
22664
  const tools = runtime.registry.getAllAgentTools();
22592
22665
  assertNonEmptyExecutorTools(name, tools);
22593
- const token = crypto3.randomUUID();
22666
+ const token = crypto4.randomUUID();
22594
22667
  registerExecutorSessionTools(runtime, token, tools);
22595
22668
  installExecutorToolCallRouter(runtime, token, { cwd, sessionLabel: label, signal: request.signal });
22596
22669
  tokens.push({ name, token });
@@ -22728,104 +22801,6 @@ function assertNoAuthorizationHeader(config2) {
22728
22801
  throw new Error(`Builtin external MCP server "${config2.name}" must not define headers.`);
22729
22802
  }
22730
22803
  }
22731
- var DEFAULT_WINDOWS_PATHEXT = ".COM;.EXE;.BAT;.CMD";
22732
- var WINDOWS_PATH_SEPARATOR = ";";
22733
- var WINDOWS_SHIM_EXTENSIONS = /* @__PURE__ */ new Set([".cmd", ".bat"]);
22734
- var CMD_EXPANSION_SENSITIVE_PATTERN = /[%^]/;
22735
- function resolveBinary(defaultBin, overrideName, env, options = {}) {
22736
- const override = env[overrideName];
22737
- if (override && override.trim().length > 0) {
22738
- const resolvedOverride = resolvePathBinary(override, env, options);
22739
- if (!resolvedOverride) {
22740
- throw new Error(`${overrideName}="${override}" did not resolve to an executable; provide an absolute path or a name discoverable on PATH`);
22741
- }
22742
- return resolvedOverride;
22743
- }
22744
- const resolved = resolvePathBinary(defaultBin, env, options);
22745
- if (!resolved) {
22746
- throw new Error(`${defaultBin} binary not found; set ${overrideName} or install ${defaultBin} on PATH`);
22747
- }
22748
- return resolved;
22749
- }
22750
- function resolvePathBinary(command, env, options = {}) {
22751
- const platform = options.platform ?? process.platform;
22752
- const isWindows2 = platform === "win32";
22753
- const pathValue = isWindows2 ? env.Path ?? env.PATH ?? "" : env.PATH ?? "";
22754
- const pathExts = isWindows2 ? parsePathExt(env.PATHEXT) : [""];
22755
- const resolved = findOnPath(command, pathValue, pathExts, platform);
22756
- return resolved ? wrapWindowsShim(resolved, env, platform) : void 0;
22757
- }
22758
- function createChildEnv(env, overlay) {
22759
- const child = {};
22760
- for (const [key, value] of Object.entries(env)) {
22761
- if (value !== void 0) {
22762
- child[key] = value;
22763
- }
22764
- }
22765
- for (const [key, value] of Object.entries(overlay)) {
22766
- if (value !== void 0) {
22767
- child[key] = value;
22768
- }
22769
- }
22770
- return child;
22771
- }
22772
- function wrapWindowsShim(resolved, env, platform) {
22773
- if (platform !== "win32" || !WINDOWS_SHIM_EXTENSIONS.has(path27__default.extname(resolved).toLowerCase())) {
22774
- return { bin: resolved, prefixArgs: [] };
22775
- }
22776
- rejectCmdExpansionSensitiveShim(resolved);
22777
- return {
22778
- bin: env.ComSpec ?? "cmd.exe",
22779
- prefixArgs: ["/d", "/s", "/c", "call", forceWindowsArgQuoting(resolved)]
22780
- };
22781
- }
22782
- function rejectCmdExpansionSensitiveShim(resolved) {
22783
- if (CMD_EXPANSION_SENSITIVE_PATTERN.test(resolved)) {
22784
- throw new Error(`Refusing to run Windows shim path with cmd.exe expansion-sensitive characters (% or ^): ${resolved}`);
22785
- }
22786
- }
22787
- function forceWindowsArgQuoting(value) {
22788
- return `${value} `;
22789
- }
22790
- function findOnPath(bin, pathValue, pathExts, platform) {
22791
- const pathSeparator = platform === "win32" ? WINDOWS_PATH_SEPARATOR : path27__default.delimiter;
22792
- if (hasPathSeparator(bin, platform) || path27__default.isAbsolute(bin)) {
22793
- return resolveWithExtensions(bin, pathExts, platform);
22794
- }
22795
- for (const entry of pathValue.split(pathSeparator)) {
22796
- const searchDir = entry.length === 0 ? "." : entry;
22797
- const candidate = resolveWithExtensions(path27__default.join(searchDir, bin), pathExts, platform);
22798
- if (candidate) {
22799
- return candidate;
22800
- }
22801
- }
22802
- return void 0;
22803
- }
22804
- function resolveWithExtensions(candidate, pathExts, platform) {
22805
- if (platform !== "win32" || path27__default.extname(candidate).length > 0) {
22806
- return existsSync(candidate) ? candidate : void 0;
22807
- }
22808
- for (const ext of pathExts) {
22809
- if (ext.length === 0) {
22810
- continue;
22811
- }
22812
- const withExt = `${candidate}${ext}`;
22813
- if (existsSync(withExt)) {
22814
- return withExt;
22815
- }
22816
- }
22817
- return existsSync(candidate) ? candidate : void 0;
22818
- }
22819
- function hasPathSeparator(value, platform) {
22820
- if (value.includes("/")) {
22821
- return true;
22822
- }
22823
- return platform === "win32" && value.includes("\\");
22824
- }
22825
- function parsePathExt(pathExt) {
22826
- const raw = pathExt && pathExt.trim().length > 0 ? pathExt : DEFAULT_WINDOWS_PATHEXT;
22827
- return raw.split(WINDOWS_PATH_SEPARATOR).map((entry) => entry.trim()).filter((entry) => entry.length > 0);
22828
- }
22829
22804
 
22830
22805
  // ../../packages/core-agent/src/internal/session-errors.ts
22831
22806
  var DEAD_SESSION_PATTERNS = [
@@ -23619,7 +23594,6 @@ __export(state_io_exports, {
23619
23594
  withStoreLock: () => withStoreLock
23620
23595
  });
23621
23596
  var FILENAME = "carriers.json";
23622
- var DEFAULT_STORE_DIRNAME = ".fleet";
23623
23597
  var STALE_SUBAGENT_MODE_FILENAME = "carrier-subagent.json";
23624
23598
  var LOCK_DIRNAME = "carriers.json.lock";
23625
23599
  var LOCK_OWNER_FILENAME = "owner.json";
@@ -23629,10 +23603,11 @@ var runtimeState = {
23629
23603
  lastLocalWriteFingerprint: null
23630
23604
  };
23631
23605
  function initStore(dir) {
23632
- runtimeState.storeDir = dir;
23633
- ensureSafeDirectory(dir);
23606
+ const resolvedDir = dir ?? getFleetDataDir();
23607
+ runtimeState.storeDir = resolvedDir;
23608
+ ensureSafeDirectory(resolvedDir);
23634
23609
  withStoreLock(() => {
23635
- unlinkStaleSubagentModeFile(dir);
23610
+ unlinkStaleSubagentModeFile(resolvedDir);
23636
23611
  });
23637
23612
  }
23638
23613
  function resetStoreForTests() {
@@ -23644,14 +23619,12 @@ function readRawCarriers() {
23644
23619
  return readCarriers();
23645
23620
  }
23646
23621
  function readRawCarriersOrDefaultStore() {
23647
- return runtimeState.storeDir ? readCarriers() : readCarriersFromDir(resolveDefaultStoreDir());
23622
+ return readCarriers();
23648
23623
  }
23649
23624
  function getCarriersFilePath() {
23650
- if (!runtimeState.storeDir) return null;
23651
- return path27.join(runtimeState.storeDir, FILENAME);
23625
+ return path27.join(resolveStoreDir(), FILENAME);
23652
23626
  }
23653
23627
  function updateCarriers(mutator) {
23654
- if (!runtimeState.storeDir) return;
23655
23628
  withStoreLock(() => {
23656
23629
  const carriers = readCarriers();
23657
23630
  const snapshot = structuredClone(carriers);
@@ -23661,36 +23634,35 @@ function updateCarriers(mutator) {
23661
23634
  });
23662
23635
  }
23663
23636
  function withStoreLock(operation) {
23664
- if (!runtimeState.storeDir) return operation();
23665
- fs8.mkdirSync(runtimeState.storeDir, { recursive: true });
23666
- const lockDir = path27.join(runtimeState.storeDir, LOCK_DIRNAME);
23637
+ const dir = resolveStoreDir();
23638
+ ensureSafeDirectory(dir);
23639
+ const lockDir = path27.join(dir, LOCK_DIRNAME);
23667
23640
  return withDirectoryLock(
23668
23641
  { lockDir, ownerFileName: LOCK_OWNER_FILENAME },
23669
23642
  operation
23670
23643
  );
23671
23644
  }
23672
- function readCarriers() {
23673
- if (!runtimeState.storeDir) return {};
23674
- return readCarriersFromDir(runtimeState.storeDir);
23645
+ function resolveStoreDir() {
23646
+ return runtimeState.storeDir ?? getFleetDataDir();
23675
23647
  }
23676
- function resolveDefaultStoreDir() {
23677
- return path27.join(os3.homedir(), DEFAULT_STORE_DIRNAME);
23648
+ function readCarriers() {
23649
+ return readCarriersFromDir(resolveStoreDir());
23678
23650
  }
23679
23651
  function readCarriersFromDir(dir) {
23680
23652
  const filePath = path27.join(dir, FILENAME);
23681
23653
  let fd;
23682
23654
  try {
23683
- const stat3 = fs8.lstatSync(filePath);
23655
+ const stat3 = fs2.lstatSync(filePath);
23684
23656
  if (!stat3.isFile() || stat3.isSymbolicLink()) return {};
23685
- fd = fs8.openSync(filePath, fs8.constants.O_RDONLY | NOFOLLOW_FLAG);
23686
- if (!fs8.fstatSync(fd).isFile()) return {};
23687
- 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")));
23688
23660
  } catch {
23689
23661
  return {};
23690
23662
  } finally {
23691
23663
  if (fd !== void 0) {
23692
23664
  try {
23693
- fs8.closeSync(fd);
23665
+ fs2.closeSync(fd);
23694
23666
  } catch {
23695
23667
  }
23696
23668
  }
@@ -23698,16 +23670,15 @@ function readCarriersFromDir(dir) {
23698
23670
  }
23699
23671
  function recordLastLocalWriteFingerprint(filePath, generation) {
23700
23672
  try {
23701
- const st = fs8.statSync(filePath);
23673
+ const st = fs2.statSync(filePath);
23702
23674
  runtimeState.lastLocalWriteFingerprint = { generation, mtimeMs: st.mtimeMs, size: st.size };
23703
23675
  } catch {
23704
23676
  runtimeState.lastLocalWriteFingerprint = { generation, mtimeMs: 0, size: 0 };
23705
23677
  }
23706
23678
  }
23707
23679
  function writeCarriers(s) {
23708
- if (!runtimeState.storeDir) throw new Error("Fleet store is not initialized.");
23709
- fs8.mkdirSync(runtimeState.storeDir, { recursive: true });
23710
- const filePath = path27.join(runtimeState.storeDir, FILENAME);
23680
+ const dir = resolveStoreDir();
23681
+ const filePath = path27.join(dir, FILENAME);
23711
23682
  const next = serializeFleetCarriers(s);
23712
23683
  writeAtomicSync(filePath, `${JSON.stringify(next, null, 2)}
23713
23684
  `, { fsync: false, mode: 420 });
@@ -23732,7 +23703,7 @@ function sanitizeFleetCarriers(value) {
23732
23703
  }
23733
23704
  function unlinkStaleSubagentModeFile(dir) {
23734
23705
  try {
23735
- fs8.unlinkSync(path27.join(dir, STALE_SUBAGENT_MODE_FILENAME));
23706
+ fs2.unlinkSync(path27.join(dir, STALE_SUBAGENT_MODE_FILENAME));
23736
23707
  } catch {
23737
23708
  }
23738
23709
  }
@@ -26019,8 +25990,8 @@ function Create(hidden, enumerable, options = {}) {
26019
25990
  Metrics.create += 1;
26020
25991
  const settings2 = settings_exports.Get();
26021
25992
  const withOptions = Merge(enumerable, options);
26022
- const withHidden = settings2.enumerableKind ? Merge(withOptions, hidden) : MergeHidden(withOptions, hidden);
26023
- 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;
26024
25995
  }
26025
25996
 
26026
25997
  // ../../node_modules/.pnpm/typebox@1.1.34/node_modules/typebox/build/system/memory/discard.mjs
@@ -31856,11 +31827,39 @@ function buildModelArgs2(model) {
31856
31827
  return model === void 0 ? [] : ["--model", model];
31857
31828
  }
31858
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
+
31859
31857
  // ../../packages/fleet-admiral/src/agent-cli/registry.ts
31860
31858
  var DEFAULT_CLI_ID = "claude";
31861
31859
  var DEFINITIONS = {
31862
31860
  claude: claudeCli,
31863
- codex: codexCli
31861
+ codex: codexCli,
31862
+ cursor: cursorCli
31864
31863
  };
31865
31864
  async function resolveAgentCliProfile(env, cwd, options = {}) {
31866
31865
  const id = resolveAgentCliId(env, options);
@@ -31905,6 +31904,10 @@ var AGENT_CLI_INJECTION_CAPABILITIES = {
31905
31904
  codex: {
31906
31905
  builderId: "codex-native",
31907
31906
  enabled: true
31907
+ },
31908
+ cursor: {
31909
+ builderId: "cursor-native",
31910
+ enabled: true
31908
31911
  }
31909
31912
  };
31910
31913
  function getAgentCliInjectionCapability(cliId) {
@@ -31920,17 +31923,16 @@ function createSessionCaptureHookExec(deps) {
31920
31923
  deps.provider
31921
31924
  ] : [deps.entryPath, "hook", "capture-session", deps.provider];
31922
31925
  return {
31923
- command: deps.execPath ?? process4.execPath,
31926
+ command: deps.execPath ?? process5.execPath,
31924
31927
  args
31925
31928
  };
31926
31929
  }
31927
31930
 
31928
31931
  // ../../packages/fleet-admiral/src/agent-cli/builders/claude.ts
31929
31932
  function buildClaudeNativeArgs(context) {
31930
- const systemPromptArg = context.replaceSystemPrompt ? "--system-prompt-file" : "--append-system-prompt-file";
31931
31933
  return [
31932
31934
  ...buildResumeArgs2(context.resumeSessionId),
31933
- systemPromptArg,
31935
+ "--append-system-prompt-file",
31934
31936
  requireSystemPromptFile(context),
31935
31937
  ...context.pluginRoots.flatMap((pluginRoot) => [
31936
31938
  "--plugin-dir",
@@ -31960,8 +31962,6 @@ function requireSystemPromptFile(context) {
31960
31962
  if (context.systemPromptFile) return context.systemPromptFile;
31961
31963
  throw new Error("Claude system prompt file is required for native injection");
31962
31964
  }
31963
-
31964
- // ../../packages/fleet-admiral/src/agent-cli/builders/toml.ts
31965
31965
  var TOML_BASIC_STRING_ESCAPE_PATTERN = /[\u0000-\u001f"\\\u007f]/g;
31966
31966
  var TOML_MULTILINE_CONTROL_PATTERN = new RegExp("[\\u0000-\\u0008\\u000b-\\u001f\\u007f]", "g");
31967
31967
  var TOML_MULTILINE_QUOTE_RUN_PATTERN = /"+/g;
@@ -32005,9 +32005,16 @@ function escapeTomlMultilineString(value) {
32005
32005
  function buildPosixShellCommand(values) {
32006
32006
  return values.map(posixShellQuote).join(" ");
32007
32007
  }
32008
+ function buildHostShellCommand(values, platform = process5.platform) {
32009
+ if (platform === "win32") return values.map(windowsShellQuote).join(" ");
32010
+ return buildPosixShellCommand(values);
32011
+ }
32008
32012
  function posixShellQuote(value) {
32009
32013
  return `'${value.replaceAll("'", "'\\''")}'`;
32010
32014
  }
32015
+ function windowsShellQuote(value) {
32016
+ return `"${value.replaceAll('"', '""')}"`;
32017
+ }
32011
32018
 
32012
32019
  // ../../packages/fleet-admiral/src/agent-cli/builders/codex.ts
32013
32020
  var CODEX_TOOL_TIMEOUT_SEC = 1800;
@@ -32048,6 +32055,24 @@ function requireCodexProfileName(context) {
32048
32055
  throw new Error("Codex profile name is required for native injection");
32049
32056
  }
32050
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
+
32051
32076
  // ../../packages/fleet-admiral/src/agent-cli/assets.generated.ts
32052
32077
  var EMBEDDED_AGENT_CLI_SKILL_ASSETS = [
32053
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" },
@@ -32215,6 +32240,36 @@ function assertSegmentRealpathWithinRoot(resolvedBase, segmentPath) {
32215
32240
  }
32216
32241
 
32217
32242
  // ../../packages/fleet-admiral/src/agent-cli/plugin/fleet.ts
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
+ `;
32218
32273
  var assetBundle = {
32219
32274
  description: "Fleet carrier delegation and wiki evidence plugin",
32220
32275
  directoryName: "fleet",
@@ -32228,6 +32283,9 @@ function renderAssetPluginRoot(pluginRoot, bundle, options) {
32228
32283
  if (options.cliId === "claude") {
32229
32284
  writePrivateJson(path27__default.join(pluginRoot, "hooks", "hooks.json"), claudeHooks(options), pluginRoot);
32230
32285
  }
32286
+ if (options.cliId === "cursor") {
32287
+ renderCursorPluginRoot(pluginRoot, options);
32288
+ }
32231
32289
  }
32232
32290
  function claudeHooks(options) {
32233
32291
  const userPromptSubmitExecs = [options.captureSessionHookExec, options.turnStartHookExec, options.autoNameHookExec].filter((exec) => exec !== void 0);
@@ -32267,6 +32325,60 @@ function claudeCommandHook(hookExec) {
32267
32325
  type: "command"
32268
32326
  };
32269
32327
  }
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
+ }
32339
+ }
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
+ };
32381
+ }
32270
32382
  function renderEmbeddedSkillAssets(pluginRoot) {
32271
32383
  for (const asset of EMBEDDED_AGENT_CLI_SKILL_ASSETS) {
32272
32384
  writePrivateFile(path27__default.join(pluginRoot, "skills", asset.relativePath), asset.content, pluginRoot);
@@ -32653,9 +32765,11 @@ var MARKETPLACE_MANAGED_ENTRIES = [
32653
32765
  ".agents",
32654
32766
  ".claude-plugin",
32655
32767
  ".codex-plugin",
32768
+ ".cursor-plugin",
32656
32769
  "hooks",
32657
32770
  "skills",
32658
32771
  "agents",
32772
+ "mcp.json",
32659
32773
  "claude",
32660
32774
  "codex-marketplace",
32661
32775
  "plugins"
@@ -32664,15 +32778,17 @@ var MARKETPLACE_PRUNE_ENTRIES = [
32664
32778
  ".agents",
32665
32779
  ".claude-plugin",
32666
32780
  ".codex-plugin",
32781
+ ".cursor-plugin",
32667
32782
  "hooks",
32668
32783
  "skills",
32669
32784
  "agents",
32785
+ "mcp.json",
32670
32786
  "claude",
32671
32787
  "codex-marketplace"
32672
32788
  ];
32673
32789
  var HASH_IGNORED_RELATIVE_PATHS = new Set(PLUGIN_BUNDLES.map((bundle) => bundle.hashFileName));
32674
32790
  async function createAgentCliPlugin(options) {
32675
- const fleetRoot = options.rootDir ?? options.dataDir;
32791
+ const fleetRoot = options.rootDir ?? options.dataDir ?? getFleetDataDir();
32676
32792
  const renderableBundles = resolveRenderablePluginBundles(fleetRoot);
32677
32793
  const marketplaceBundles = groupRenderableBundlesByMarketplace(renderableBundles);
32678
32794
  const pluginRoots = /* @__PURE__ */ new Map();
@@ -32738,12 +32854,15 @@ function renderPluginRoot(pluginRoot, bundle, options) {
32738
32854
  writePrivateJson(path27__default.join(stagedPluginRoot, ".claude-plugin", "plugin.json"), claudeManifest(bundle), stagedPluginRoot);
32739
32855
  switch (bundle.source) {
32740
32856
  case "asset":
32741
- ensurePrivateDir(path27__default.join(stagedPluginRoot, "agents"), stagedPluginRoot);
32857
+ if (options.cliId === "claude") {
32858
+ ensurePrivateDir(path27__default.join(stagedPluginRoot, "agents"), stagedPluginRoot);
32859
+ }
32742
32860
  ensurePrivateDir(path27__default.join(stagedPluginRoot, "skills"), stagedPluginRoot);
32743
32861
  renderAssetPluginRoot(stagedPluginRoot, bundle, options);
32744
32862
  break;
32745
32863
  }
32746
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);
32747
32866
  removePrivatePath(pluginRoot, parentRoot);
32748
32867
  renameSync(stagedPluginRoot, pluginRoot);
32749
32868
  } finally {
@@ -32757,6 +32876,7 @@ function renderMarketplaceRoot(target, bundles) {
32757
32876
  try {
32758
32877
  writePrivateJson(path27__default.join(stagedRoot, ".agents", "plugins", "marketplace.json"), codexMarketplace(target, bundles), stagedRoot);
32759
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);
32760
32880
  pruneMarketplaceRoot(target);
32761
32881
  pruneStalePluginDirs(target, bundles);
32762
32882
  for (const entry of readdirSync(stagedRoot)) {
@@ -32781,7 +32901,7 @@ function pruneStalePluginDirs(target, bundles) {
32781
32901
  }
32782
32902
  }
32783
32903
  function buildContentHash(target) {
32784
- const hash2 = crypto3.createHash("sha256");
32904
+ const hash2 = crypto4.createHash("sha256");
32785
32905
  for (const filePath of listRenderableFiles(target)) {
32786
32906
  const relativePath = path27__default.relative(target.root, filePath);
32787
32907
  hash2.update(relativePath);
@@ -32876,6 +32996,17 @@ function claudeMarketplace(target, bundles) {
32876
32996
  }))
32877
32997
  };
32878
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
+ }
32879
33010
  function pluginRootForTarget(target, bundle) {
32880
33011
  return path27__default.join(target.root, PLUGIN_BUNDLES_DIR_NAME, bundle.directoryName);
32881
33012
  }
@@ -32890,8 +33021,30 @@ function codexManifest(bundle, pluginRoot) {
32890
33021
  skills: "./skills/"
32891
33022
  };
32892
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
+ }
32893
33046
  function codexManifestVersion(bundle, pluginRoot) {
32894
- const hash2 = crypto3.createHash("sha256");
33047
+ const hash2 = crypto4.createHash("sha256");
32895
33048
  hash2.update(bundle.name);
32896
33049
  hash2.update("\0");
32897
33050
  hash2.update(bundle.description);
@@ -32912,6 +33065,22 @@ function listCodexEffectivePluginFiles(pluginRoot) {
32912
33065
  collectRenderableFiles(pluginRoot, skillsPath, files, /* @__PURE__ */ new Set());
32913
33066
  return files.sort();
32914
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
+ }
32915
33084
  function claudeManifest(bundle) {
32916
33085
  return {
32917
33086
  name: bundle.name,
@@ -32934,7 +33103,7 @@ async function injectAgentCliProfile(profile, options) {
32934
33103
  }
32935
33104
  const injectTone = options.enableMetaphor ?? false;
32936
33105
  const endpoint = await options.dedicatedMcpSession.getEndpoint();
32937
- const tokenLabel = options.mcpSessionLabel ?? `agent:${profile.id}:${crypto3.randomUUID()}`;
33106
+ const tokenLabel = options.mcpSessionLabel ?? `agent:${profile.id}:${crypto4.randomUUID()}`;
32938
33107
  const tokens = await options.dedicatedMcpSession.issueSessionToken({ cwd: profile.cwd, label: tokenLabel });
32939
33108
  const mcpServers = buildAgentCliMcpServerConfigs(endpoint.servers, tokens);
32940
33109
  const doctrine = options.buildSystemPrompt(injectTone);
@@ -32946,7 +33115,9 @@ async function injectAgentCliProfile(profile, options) {
32946
33115
  codexCommandRunner: options.codexCommandRunner,
32947
33116
  cwd: profile.cwd,
32948
33117
  dataDir: options.dataDir,
33118
+ doctrine,
32949
33119
  rootDir: options.pluginRootDir,
33120
+ mcpServers,
32950
33121
  captureSessionHookExec: options.captureSessionHookExec,
32951
33122
  turnStartHookExec: options.turnStartHookExec,
32952
33123
  turnEndHookExec: options.turnEndHookExec,
@@ -32970,7 +33141,7 @@ async function injectAgentCliProfile(profile, options) {
32970
33141
  env: { ...profile.env }
32971
33142
  }, requireCodexCommandRunner(options.codexCommandRunner), options.withMarketplaceLock, {
32972
33143
  homeMarketplaceName: FLEET_MARKETPLACE_NAME,
32973
- homeMarketplaceRoot: path27__default.join(options.pluginRootDir ?? options.dataDir, "marketplace"),
33144
+ homeMarketplaceRoot: path27__default.join(options.pluginRootDir ?? options.dataDir ?? getFleetDataDir(), "marketplace"),
32974
33145
  projectMarketplaceRoot: path27__default.join(profile.cwd, ".fleet")
32975
33146
  });
32976
33147
  if (cleanupWarning !== void 0) {
@@ -33002,7 +33173,6 @@ async function injectAgentCliProfile(profile, options) {
33002
33173
  pluginRoot: plugin.pluginRoot,
33003
33174
  pluginRoots: plugin.pluginRoots,
33004
33175
  codexProfileName: codexProfile?.profileName,
33005
- replaceSystemPrompt: options.replaceSystemPrompt ?? false,
33006
33176
  resumeSessionId: options.resumeSessionId,
33007
33177
  systemPromptFile
33008
33178
  };
@@ -33198,6 +33368,8 @@ function buildAgentCliArgs(builderId, context) {
33198
33368
  return buildClaudeNativeArgs(context);
33199
33369
  case "codex-native":
33200
33370
  return buildCodexNativeArgs(context);
33371
+ case "cursor-native":
33372
+ return buildCursorNativeArgs(context);
33201
33373
  }
33202
33374
  }
33203
33375
  function mergeAgentCliArgs(profile, builderId, context, injectedArgs) {
@@ -33245,6 +33417,7 @@ var CHRONICLE_WIKI_TOOL_IDS = /* @__PURE__ */ new Set([
33245
33417
  ]);
33246
33418
  function createFleetAgentRuntimeLifecycle(deps) {
33247
33419
  let active = true;
33420
+ const resolvedDataDir = deps.dataDir ?? getFleetDataDir();
33248
33421
  const mcpRuntime = createFleetAgentRuntimeMcpServices();
33249
33422
  const carrierRuntime = createCarrierRuntime();
33250
33423
  const dedicatedMcpSession = createExecutorSessionManager({
@@ -33260,7 +33433,7 @@ function createFleetAgentRuntimeLifecycle(deps) {
33260
33433
  ]
33261
33434
  });
33262
33435
  registerExecutorPort(mcpRuntime.mcpRegistry, carrierRuntime, () => active);
33263
- carrierRuntime.store.initStore(deps.dataDir);
33436
+ carrierRuntime.store.initStore(resolvedDataDir);
33264
33437
  carrierRuntime.registerCarrierDefaults();
33265
33438
  registerFleetAgentRuntimeTools(mcpRuntime.mcpRegistry, carrierRuntime, deps);
33266
33439
  registerExecutorMcpRuntimeProvider(mcpRuntime, dedicatedMcpSession, () => active);
@@ -34447,7 +34620,7 @@ function stripLeadingFrontmatter(body) {
34447
34620
  return stripped ? next : body;
34448
34621
  }
34449
34622
  function computeContentHash(content) {
34450
- 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);
34451
34624
  }
34452
34625
  function assertWithinRawDir(absolutePath, paths) {
34453
34626
  const relative = path27__default.relative(paths.rawDir, absolutePath);
@@ -34660,7 +34833,7 @@ async function writeAtomic(filePath, content, paths) {
34660
34833
  await ensureMemoryRoot(paths);
34661
34834
  const tempPath = path27__default.join(
34662
34835
  path27__default.dirname(filePath),
34663
- `.tmp-${process.pid}-${Date.now()}-${crypto3.randomUUID()}-${os3__default.hostname()}`
34836
+ `.tmp-${process.pid}-${Date.now()}-${crypto4.randomUUID()}-${os3__default.hostname()}`
34664
34837
  );
34665
34838
  await writeFile(tempPath, content, "utf8");
34666
34839
  await rename(tempPath, filePath);
@@ -37213,7 +37386,7 @@ function parseOptionalIsoDate(value) {
37213
37386
  return Number.isFinite(timestamp) ? timestamp : null;
37214
37387
  }
37215
37388
  function hashBodyForComparison(body) {
37216
- 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);
37217
37390
  }
37218
37391
  function hasConflictingStatuses(entries) {
37219
37392
  const statuses = new Set(entries.map((entry) => entry.status).filter((status) => status !== "unknown"));
@@ -39409,7 +39582,7 @@ var DEFAULT_TICKET_TTL_MS = 1e4;
39409
39582
  function createPluginTerminalTicketRegistry(deps = {}) {
39410
39583
  const ttlMs = deps.ttlMs ?? DEFAULT_TICKET_TTL_MS;
39411
39584
  const now = deps.now ?? Date.now;
39412
- const randomTicket = deps.randomTicket ?? (() => crypto3.randomBytes(32).toString("base64url"));
39585
+ const randomTicket = deps.randomTicket ?? (() => crypto4.randomBytes(32).toString("base64url"));
39413
39586
  const tickets = /* @__PURE__ */ new Map();
39414
39587
  function issue3(context) {
39415
39588
  prune();
@@ -39441,10 +39614,10 @@ var TERMINAL_TERM = "xterm-256color";
39441
39614
  var FLEET_CONSOLE_PACKAGE_NAME = "@dotobokuri/fleet-console";
39442
39615
  var require2 = createRequire(import.meta.url);
39443
39616
  function createShellTerminalLaunchResolver(deps = {}) {
39444
- const baseCwd = deps.cwd ?? process4.cwd();
39445
- const env = deps.env ?? process4.env;
39617
+ const baseCwd = deps.cwd ?? process5.cwd();
39618
+ const env = deps.env ?? process5.env;
39446
39619
  const homedir3 = deps.homedir ?? DEFAULT_TERMINAL_CWD_FALLBACK;
39447
- const platform = deps.platform ?? process4.platform;
39620
+ const platform = deps.platform ?? process5.platform;
39448
39621
  return async (selectedCwd) => {
39449
39622
  const cwd = selectedCwd || baseCwd || homedir3();
39450
39623
  const shell = resolveWindowsLaunchBinary(resolveUserShell(env, platform), [], env, platform, "user shell");
@@ -39455,7 +39628,7 @@ function startTerminalShell(launch, size) {
39455
39628
  const testStartShell = globalThis.__fleetTerminalStartShell;
39456
39629
  if (testStartShell) return testStartShell(launch, size);
39457
39630
  const { spawn: spawnPty } = loadNodePty();
39458
- const useConptyDll = resolveUseConptyDll(process4.platform, process4.env);
39631
+ const useConptyDll = resolveUseConptyDll(process5.platform, process5.env);
39459
39632
  return spawnPty(launch.bin, [...launch.args], {
39460
39633
  cols: size.cols,
39461
39634
  rows: size.rows,
@@ -40074,7 +40247,8 @@ var BINARY_DISPLAY_NAMES = {
40074
40247
  };
40075
40248
  var OVERRIDE_ENV_BY_COMMAND = {
40076
40249
  claude: "CLAUDE_BIN",
40077
- codex: "CODEX_BIN"
40250
+ codex: "CODEX_BIN",
40251
+ "cursor-agent": "CURSOR_AGENT_BIN"
40078
40252
  };
40079
40253
  var VERSION_PROBE_TIMEOUT_MS = 5e3;
40080
40254
  var SEMVER_PATTERN = /(\d+\.\d+\.\d+)/;
@@ -40138,7 +40312,7 @@ function execFileVersion(bin, args) {
40138
40312
  execFile(
40139
40313
  bin,
40140
40314
  [...args],
40141
- { encoding: "utf-8", timeout: VERSION_PROBE_TIMEOUT_MS, windowsHide: true },
40315
+ withHidden({ encoding: "utf-8", timeout: VERSION_PROBE_TIMEOUT_MS }),
40142
40316
  (error51, stdout, stderr) => {
40143
40317
  if (error51) {
40144
40318
  reject(error51);
@@ -40272,7 +40446,7 @@ function readProviderSessionCapture(fleetSessionId, deps = {}) {
40272
40446
  const capturesDir = deps.capturesDir ?? defaultCapturePaths().capturesDir;
40273
40447
  const filePath = path27__default.join(capturesDir, `${fleetSessionId}.json`);
40274
40448
  try {
40275
- const parsed = JSON.parse(fs8__default.readFileSync(filePath, "utf8"));
40449
+ const parsed = JSON.parse(fs2__default.readFileSync(filePath, "utf8"));
40276
40450
  return sanitizeProviderSession(parsed);
40277
40451
  } catch {
40278
40452
  return null;
@@ -40282,7 +40456,7 @@ function unlinkProviderSessionCapture(fleetSessionId, deps = {}) {
40282
40456
  if (!isSafeCaptureId(fleetSessionId)) return false;
40283
40457
  const capturesDir = deps.capturesDir ?? defaultCapturePaths().capturesDir;
40284
40458
  try {
40285
- fs8__default.unlinkSync(path27__default.join(capturesDir, `${fleetSessionId}.json`));
40459
+ fs2__default.unlinkSync(path27__default.join(capturesDir, `${fleetSessionId}.json`));
40286
40460
  return true;
40287
40461
  } catch {
40288
40462
  return false;
@@ -40290,20 +40464,20 @@ function unlinkProviderSessionCapture(fleetSessionId, deps = {}) {
40290
40464
  }
40291
40465
  function captureSessionStrict(options) {
40292
40466
  const provider = parseProvider(options.provider);
40293
- const fleetSessionId = readFleetSessionId(options.env ?? process4.env);
40467
+ const fleetSessionId = readFleetSessionId(options.env ?? process5.env);
40294
40468
  const input = parseHookInput(options.input ?? "");
40295
40469
  const providerSession = toProviderSession(provider, input, options.now ?? (() => /* @__PURE__ */ new Date()));
40296
40470
  const capturesDir = (options.paths ?? defaultCapturePaths()).capturesDir;
40297
40471
  const finalPath = path27__default.join(capturesDir, `${fleetSessionId}.json`);
40298
- const tempPath = path27__default.join(capturesDir, `${CAPTURE_TEMP_PREFIX}${fleetSessionId}.${process4.pid}.${Date.now()}.tmp`);
40299
- fs8__default.mkdirSync(capturesDir, { recursive: true, mode: 448 });
40300
- 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)}
40301
40475
  `, { mode: 384 });
40302
- fs8__default.renameSync(tempPath, finalPath);
40476
+ fs2__default.renameSync(tempPath, finalPath);
40303
40477
  return { path: finalPath, providerSession };
40304
40478
  }
40305
40479
  function parseProvider(value) {
40306
- if (value === "claude" || value === "codex") return value;
40480
+ if (isProvider(value)) return value;
40307
40481
  throw new Error("invalid_provider");
40308
40482
  }
40309
40483
  function readFleetSessionId(env) {
@@ -40323,10 +40497,10 @@ function parseHookInput(input) {
40323
40497
  throw new Error("invalid_hook_input");
40324
40498
  }
40325
40499
  function toProviderSession(provider, input, now) {
40326
- if (typeof input.session_id !== "string" || input.session_id.length === 0) throw new Error("missing_provider_session_id");
40500
+ const sessionId = readProviderSessionId(input);
40327
40501
  return {
40328
40502
  provider,
40329
- sessionId: input.session_id,
40503
+ sessionId,
40330
40504
  ...typeof input.transcript_path === "string" && input.transcript_path.length > 0 ? { transcriptPath: input.transcript_path } : {},
40331
40505
  ...typeof input.source === "string" && input.source.length > 0 ? { source: input.source } : {},
40332
40506
  capturedAt: now().toISOString()
@@ -40335,7 +40509,7 @@ function toProviderSession(provider, input, now) {
40335
40509
  function sanitizeProviderSession(value) {
40336
40510
  if (!value || typeof value !== "object" || Array.isArray(value)) return null;
40337
40511
  const candidate = value;
40338
- 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;
40339
40513
  return {
40340
40514
  provider: candidate.provider,
40341
40515
  sessionId: candidate.sessionId,
@@ -40344,6 +40518,15 @@ function sanitizeProviderSession(value) {
40344
40518
  capturedAt: candidate.capturedAt
40345
40519
  };
40346
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
+ }
40347
40530
  function isSafeCaptureId(value) {
40348
40531
  return value.length > 0 && path27__default.basename(value) === value && !value.includes(path27__default.sep) && !value.includes(path27__default.posix.sep);
40349
40532
  }
@@ -40385,16 +40568,12 @@ function buildConsoleCaptureHookCommand(entry, cliId) {
40385
40568
  throw new Error(`Unsupported Fleet Console session hook entry extension: ${extension}`);
40386
40569
  }
40387
40570
  function toCaptureProvider(cliId) {
40388
- return cliId === "codex" ? "codex" : "claude";
40571
+ if (cliId === "codex") return "codex";
40572
+ if (cliId === "cursor") return "cursor";
40573
+ return "claude";
40389
40574
  }
40390
40575
  function runCodexCommand(command) {
40391
- const result = spawnSync(command.bin, command.args, {
40392
- cwd: command.cwd,
40393
- encoding: "utf8",
40394
- env: command.env,
40395
- // 콘솔 없는 fleet-console 백엔드에서 codex 등록 명령 실행 시 콘솔 창이 깜빡이는 것을 방지한다.
40396
- windowsHide: true
40397
- });
40576
+ const result = spawnSync(command.bin, command.args, withHidden({ cwd: command.cwd, encoding: "utf8", env: command.env }));
40398
40577
  return {
40399
40578
  status: result.status,
40400
40579
  stderr: result.stderr ?? "",
@@ -40433,12 +40612,12 @@ var CONSOLE_ENTRY_PATH = fileURLToPath(import.meta.url);
40433
40612
  var HOOK_ENTRY_EXTENSIONS = /* @__PURE__ */ new Set([".cjs", ".cts", ".js", ".mjs", ".mts", ".ts", ".tsx"]);
40434
40613
  var require4 = createRequire(import.meta.url);
40435
40614
  function createAgentTerminalLaunchResolver(deps = {}) {
40436
- const baseCwd = deps.cwd ?? process4.cwd();
40437
- const env = deps.env ?? process4.env;
40438
- 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;
40439
40618
  const homedir3 = deps.homedir ?? DEFAULT_TERMINAL_CWD_FALLBACK2;
40440
- const platform = deps.platform ?? process4.platform;
40441
- const entryPath = resolveHookEntryPath(deps.entryPath ?? process4.argv[1]);
40619
+ const platform = deps.platform ?? process5.platform;
40620
+ const entryPath = resolveHookEntryPath(deps.entryPath ?? process5.argv[1]);
40442
40621
  const tsxLoaderPath = deps.tsxLoaderPath ?? resolveOptionalPackage("tsx");
40443
40622
  const dataDir = deps.dataDir ?? getFleetDataDir();
40444
40623
  const infraServices = deps.infraServices ?? createInfraServices();
@@ -40483,7 +40662,7 @@ function resolveHookEntryPath(candidate) {
40483
40662
  if (candidate && hasHookEntryExtension(candidate)) return candidate;
40484
40663
  if (candidate) {
40485
40664
  try {
40486
- const realPath = fs8__default.realpathSync(candidate);
40665
+ const realPath = fs2__default.realpathSync(candidate);
40487
40666
  if (hasHookEntryExtension(realPath)) return realPath;
40488
40667
  } catch {
40489
40668
  }
@@ -40517,7 +40696,6 @@ async function createAgentCliLaunchSpec(options) {
40517
40696
  inputWaitingHookExec: buildConsoleAttentionHookCommand(options.hookEntry),
40518
40697
  autoNameHookExec: buildConsoleAutoNameHookCommand(options.hookEntry),
40519
40698
  onCleanup: (cleanup) => cleanupStack.push(cleanup),
40520
- replaceSystemPrompt: globalSettings.replaceSystemPrompt,
40521
40699
  resumeSessionId: options.resumeSessionId,
40522
40700
  withMarketplaceLock: withConsoleMarketplaceLock,
40523
40701
  mcpSessionLabel: options.sessionId
@@ -40601,12 +40779,9 @@ function resolveOptionalPackage(id) {
40601
40779
  function readGlobalSettingsSnapshot(infraServices) {
40602
40780
  try {
40603
40781
  const data = infraServices.globalOptionsService.load();
40604
- return {
40605
- enableMetaphor: data.enableMetaphor ?? false,
40606
- replaceSystemPrompt: data.replaceSystemPrompt ?? false
40607
- };
40782
+ return { enableMetaphor: data.enableMetaphor ?? false };
40608
40783
  } catch {
40609
- return { enableMetaphor: false, replaceSystemPrompt: false };
40784
+ return { enableMetaphor: false };
40610
40785
  }
40611
40786
  }
40612
40787
  var TENANT_EVENT_LIMIT = 1e3;
@@ -40964,12 +41139,12 @@ function toTerminalSessionInfo(state) {
40964
41139
  };
40965
41140
  }
40966
41141
  function defaultWorkspaceHash(canonicalCwd) {
40967
- return crypto3.createHash("sha256").update(canonicalCwd).digest("hex").slice(0, 12);
41142
+ return crypto4.createHash("sha256").update(canonicalCwd).digest("hex").slice(0, 12);
40968
41143
  }
40969
41144
  function defaultCanonicalizeTheaterPath(cwd) {
40970
41145
  const resolved = path27__default.resolve(cwd);
40971
41146
  try {
40972
- return fs8__default.realpathSync.native(resolved);
41147
+ return fs2__default.realpathSync.native(resolved);
40973
41148
  } catch {
40974
41149
  return resolved;
40975
41150
  }
@@ -41198,10 +41373,15 @@ function registerAgentRoutes(ctx, terminalRuntime, deps) {
41198
41373
  registerRouter(ctx, "agent", api.handle);
41199
41374
  return api.launchKinds;
41200
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
+ }
41201
41383
  function createAgentApi(ctx, terminalRuntime, deps) {
41202
- const dataDir = ctx.host.paths.dataDir;
41203
41384
  const runtime = createFleetAgentRuntimeLifecycle({
41204
- dataDir,
41205
41385
  onMcpServerStartError: (error51) => {
41206
41386
  console.error("[fleet-console] Failed to start MCP server", error51);
41207
41387
  },
@@ -41217,7 +41397,6 @@ function createAgentApi(ctx, terminalRuntime, deps) {
41217
41397
  const jobOriginById = /* @__PURE__ */ new Map();
41218
41398
  const launchResolver = createAgentTerminalLaunchResolver({
41219
41399
  agentRuntime: runtime,
41220
- dataDir,
41221
41400
  infraServices: deps,
41222
41401
  onRuntimeSessionStart: (session) => {
41223
41402
  pendingRuntimeSessions.set(session.sessionId, session);
@@ -41254,6 +41433,7 @@ function createAgentApi(ctx, terminalRuntime, deps) {
41254
41433
  }
41255
41434
  injectRenameCommand(payload.operationId, payload.title);
41256
41435
  });
41436
+ backfillAgentOperationLaunchKinds();
41257
41437
  rehydrateDormantAgentOperations();
41258
41438
  async function handle({ req, res, pathname }) {
41259
41439
  const path42 = pathname.slice(`${ctx.basePath}/agent`.length) || "/";
@@ -41385,7 +41565,7 @@ function createAgentApi(ctx, terminalRuntime, deps) {
41385
41565
  ctx.host.http.writeJson(res, 409, { error: "agent_cli_unavailable" });
41386
41566
  return;
41387
41567
  }
41388
- const sessionId = crypto3.randomUUID();
41568
+ const sessionId = crypto4.randomUUID();
41389
41569
  const session = observability.createPendingTerminalSession({ sessionId, cwd, cliId });
41390
41570
  ctx.host.operations.create({
41391
41571
  id: session.sessionId,
@@ -41517,8 +41697,8 @@ function createAgentApi(ctx, terminalRuntime, deps) {
41517
41697
  return true;
41518
41698
  }
41519
41699
  const result = captureSession({
41520
- diagnostics: process4.stderr,
41521
- env: { ...process4.env, FLEET_CONSOLE_SESSION_ID: sessionId },
41700
+ diagnostics: process5.stderr,
41701
+ env: { ...process5.env, FLEET_CONSOLE_SESSION_ID: sessionId },
41522
41702
  input: body.input,
41523
41703
  paths: ctx.host.paths,
41524
41704
  provider: body.provider
@@ -41537,7 +41717,7 @@ function createAgentApi(ctx, terminalRuntime, deps) {
41537
41717
  }
41538
41718
  async function buildAgentCliLaunchMetadata() {
41539
41719
  const metadata = getAgentCliMetadata();
41540
- if ((process4.env.FLEET_TERMINAL_CMD ?? "").trim().length > 0) {
41720
+ if ((process5.env.FLEET_TERMINAL_CMD ?? "").trim().length > 0) {
41541
41721
  return metadata.map((meta3) => ({ id: meta3.id, label: meta3.label, available: true, signedIn: true }));
41542
41722
  }
41543
41723
  const detected = await detector.detect();
@@ -41617,6 +41797,13 @@ function createAgentApi(ctx, terminalRuntime, deps) {
41617
41797
  ctx.host.operations.patch(operation.id, { payload: { ...operation.payload, ...toOperationPayload(cwd, dormant, providerSession) } });
41618
41798
  }
41619
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
+ }
41620
41807
  return { cleanup, handle, handleExit, launch, launchKinds: buildLaunchKinds };
41621
41808
  function methodNotAllowed(res) {
41622
41809
  ctx.host.http.writeJson(res, 405, { error: "Method not allowed" });
@@ -41631,6 +41818,7 @@ function toOperationPayload(cwd, session, providerSession) {
41631
41818
  return {
41632
41819
  cwd,
41633
41820
  ...session.cliId ? { cliId: session.cliId } : {},
41821
+ ...session.cliId ? { launchKindId: session.cliId } : {},
41634
41822
  ...session.cliLabel ? { cliLabel: session.cliLabel } : {},
41635
41823
  ...providerSession ? { providerSession } : {},
41636
41824
  ...session.labelSource ? { labelSource: session.labelSource } : {}
@@ -41660,7 +41848,7 @@ function readProviderSession(value) {
41660
41848
  const providerSession = value?.providerSession;
41661
41849
  if (!providerSession || typeof providerSession !== "object") return void 0;
41662
41850
  const candidate = providerSession;
41663
- 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;
41664
41852
  return {
41665
41853
  provider: candidate.provider,
41666
41854
  sessionId: candidate.sessionId,
@@ -41669,6 +41857,9 @@ function readProviderSession(value) {
41669
41857
  ...typeof candidate.source === "string" ? { source: candidate.source } : {}
41670
41858
  };
41671
41859
  }
41860
+ function isProvider2(value) {
41861
+ return value === "claude" || value === "codex" || value === "cursor";
41862
+ }
41672
41863
  function resolveCarrierEventOrigin(event, jobOriginById) {
41673
41864
  if (event.originSessionId) {
41674
41865
  jobOriginById.set(event.jobId, event.originSessionId);
@@ -41710,6 +41901,47 @@ function withSignatureCli(event, registry3) {
41710
41901
  const signatureCli = resolveAgentCliType2(obj.ownerCarrierId, config2.defaultCliType);
41711
41902
  return { ...obj, signatureCli };
41712
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" });
41910
+ return true;
41911
+ }
41912
+ if (!ctx.host.security.isTerminalAuthorized(req)) {
41913
+ ctx.host.http.writeJson(res, 401, { error: "Unauthorized" });
41914
+ return true;
41915
+ }
41916
+ if (req.headers.origin === void 0) {
41917
+ ctx.host.http.writeJson(res, 401, { error: "Unauthorized" });
41918
+ return true;
41919
+ }
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" });
41924
+ return true;
41925
+ }
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
+ }));
41942
+ return true;
41943
+ });
41944
+ }
41713
41945
 
41714
41946
  // ../fleet-plugins/terminal/server/settings-routes.ts
41715
41947
  function registerTerminalSettingsRoutes(ctx, deps) {
@@ -41734,7 +41966,6 @@ function registerTerminalSettingsRoutes(ctx, deps) {
41734
41966
  }
41735
41967
  const updated = deps.globalOptionsService.update((current) => ({
41736
41968
  ...current,
41737
- replaceSystemPrompt: body.replaceSystemPrompt,
41738
41969
  enableMetaphor: body.enableMetaphor
41739
41970
  }));
41740
41971
  ctx.host.http.writeJson(res, 200, toTerminalSettingsState(updated));
@@ -41746,15 +41977,14 @@ function registerTerminalSettingsRoutes(ctx, deps) {
41746
41977
  }
41747
41978
  function toTerminalSettingsState(data) {
41748
41979
  return {
41749
- replaceSystemPrompt: data.replaceSystemPrompt ?? false,
41750
41980
  enableMetaphor: data.enableMetaphor ?? false
41751
41981
  };
41752
41982
  }
41753
41983
  function isTerminalSettingsBody(value) {
41754
41984
  if (!value || typeof value !== "object" || Array.isArray(value)) return false;
41755
- if (Object.keys(value).length !== 2) return false;
41985
+ if (Object.keys(value).length !== 1) return false;
41756
41986
  const body = value;
41757
- return typeof body.replaceSystemPrompt === "boolean" && typeof body.enableMetaphor === "boolean";
41987
+ return typeof body.enableMetaphor === "boolean";
41758
41988
  }
41759
41989
  function isJsonRequest(req) {
41760
41990
  const contentType = req.headers["content-type"];
@@ -41846,6 +42076,7 @@ var routes_default = definePlugin({
41846
42076
  });
41847
42077
  ctx.host.lifecycle.registerCleanup(unsubscribeDelete);
41848
42078
  registerShellRoutes(ctx, runtime);
42079
+ registerGlobalShellRoutes(ctx, runtime);
41849
42080
  registerTerminalSettingsRoutes(ctx, { globalOptionsService: infraServices.globalOptionsService });
41850
42081
  const agentLaunchKinds = registerAgentRoutes(ctx, runtime, {
41851
42082
  globalOptionsService: infraServices.globalOptionsService