@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.
- package/AGENTS.md +6 -5
- package/dist/cli.d.ts +13 -12
- package/dist/cli.mjs +143 -175
- package/dist/client/assets/SymbolsNerdFontMono-Regular-CoUzE12l.woff2 +0 -0
- package/dist/client/assets/{_baseUniq-DFEDX4NY.js → _baseUniq-C4_iQlZS.js} +1 -1
- package/dist/client/assets/{arc-CGwMrR6o.js → arc-BBAWxYi5.js} +1 -1
- package/dist/client/assets/{architectureDiagram-Q4EWVU46-BqLyvIOK.js → architectureDiagram-Q4EWVU46-_oQqhexV.js} +1 -1
- package/dist/client/assets/{blockDiagram-DXYQGD6D-DoiPMLdv.js → blockDiagram-DXYQGD6D-3xT9VFiD.js} +1 -1
- package/dist/client/assets/{c4Diagram-AHTNJAMY-DfGxDkah.js → c4Diagram-AHTNJAMY-S-IMcMW2.js} +1 -1
- package/dist/client/assets/channel-5tV1napa.js +1 -0
- package/dist/client/assets/{chunk-4BX2VUAB-3zXv74oY.js → chunk-4BX2VUAB-tS9Ys0P9.js} +1 -1
- package/dist/client/assets/{chunk-4TB4RGXK-MkXUmjUE.js → chunk-4TB4RGXK-YZgAG7SW.js} +1 -1
- package/dist/client/assets/{chunk-55IACEB6-mhkgqlI_.js → chunk-55IACEB6-m-CtqHoO.js} +1 -1
- package/dist/client/assets/{chunk-EDXVE4YY-B0_ZDihs.js → chunk-EDXVE4YY-yoymxaEV.js} +1 -1
- package/dist/client/assets/{chunk-FMBD7UC4-BQAuE4pL.js → chunk-FMBD7UC4-REUkrQAG.js} +1 -1
- package/dist/client/assets/{chunk-OYMX7WX6-CY8Eyj9X.js → chunk-OYMX7WX6-DzMuL105.js} +1 -1
- package/dist/client/assets/{chunk-QZHKN3VN-CaZoMwKH.js → chunk-QZHKN3VN-DXFFll8-.js} +1 -1
- package/dist/client/assets/{chunk-YZCP3GAM-DV1YOEUH.js → chunk-YZCP3GAM-CmY7W-gg.js} +1 -1
- package/dist/client/assets/classDiagram-6PBFFD2Q-WDM904ap.js +1 -0
- package/dist/client/assets/classDiagram-v2-HSJHXN6E-WDM904ap.js +1 -0
- package/dist/client/assets/clone-BJg9p0cC.js +1 -0
- package/dist/client/assets/{cose-bilkent-S5V4N54A-Cy3v0C_N.js → cose-bilkent-S5V4N54A-BupE-a40.js} +1 -1
- package/dist/client/assets/{dagre-KV5264BT-CGJ6x_VR.js → dagre-KV5264BT-Jn67LxMS.js} +1 -1
- package/dist/client/assets/{diagram-5BDNPKRD-MyyXeHKQ.js → diagram-5BDNPKRD-BAeFEORH.js} +1 -1
- package/dist/client/assets/{diagram-G4DWMVQ6-D52Q2132.js → diagram-G4DWMVQ6-CnZrDABY.js} +1 -1
- package/dist/client/assets/{diagram-MMDJMWI5-DCypusCr.js → diagram-MMDJMWI5-DefG-kXU.js} +1 -1
- package/dist/client/assets/{diagram-TYMM5635-c5UBqE9-.js → diagram-TYMM5635-BPkXKB-Q.js} +1 -1
- package/dist/client/assets/{erDiagram-SMLLAGMA-BlF0Lxy7.js → erDiagram-SMLLAGMA-Bi4jlild.js} +1 -1
- package/dist/client/assets/{flowDiagram-DWJPFMVM-lo8xyzfx.js → flowDiagram-DWJPFMVM-BoZyLO7h.js} +1 -1
- package/dist/client/assets/{ganttDiagram-T4ZO3ILL-BXVZMpon.js → ganttDiagram-T4ZO3ILL-LgzSNjrh.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-UUTBAWPF-DB1A6uYk.js → gitGraphDiagram-UUTBAWPF-B4fH-hPT.js} +1 -1
- package/dist/client/assets/{graph-Ck2AX1p2.js → graph-D3ZAYMLG.js} +1 -1
- package/dist/client/assets/{index-Cf9MmpwN.css → index-DctP_CJP.css} +1 -1
- package/dist/client/assets/index-vgEn_EkG.js +404 -0
- package/dist/client/assets/{infoDiagram-42DDH7IO-NEVE42fw.js → infoDiagram-42DDH7IO-pENdunXd.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-UXIWVN3A-MbFr_8pL.js → ishikawaDiagram-UXIWVN3A-WakLHKte.js} +1 -1
- package/dist/client/assets/{journeyDiagram-VCZTEJTY-Sq2ja3q8.js → journeyDiagram-VCZTEJTY-CrqXKtzk.js} +1 -1
- package/dist/client/assets/{kanban-definition-6JOO6SKY-C63qPhtK.js → kanban-definition-6JOO6SKY-DdSC9eJ-.js} +1 -1
- package/dist/client/assets/{layout-CFEuVj4N.js → layout-BI1Oko_a.js} +1 -1
- package/dist/client/assets/{linear-B626G8Op.js → linear-KUjZtfMe.js} +1 -1
- package/dist/client/assets/{mermaid.core-BT7SVKBR.js → mermaid.core-DNlIf4_3.js} +4 -4
- package/dist/client/assets/{min-MbEOApMw.js → min-DCAecveI.js} +1 -1
- package/dist/client/assets/{mindmap-definition-QFDTVHPH-DMpht5Mg.js → mindmap-definition-QFDTVHPH-BSCyQA-4.js} +1 -1
- package/dist/client/assets/{pieDiagram-DEJITSTG-B4XS0haZ.js → pieDiagram-DEJITSTG-C_1I63z5.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-34T5L4WZ-CReo5Ajb.js → quadrantDiagram-34T5L4WZ-CtqeYPcA.js} +1 -1
- package/dist/client/assets/{requirementDiagram-MS252O5E-A50aqG-K.js → requirementDiagram-MS252O5E-Cpakdg-s.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-XADWPNL6-471VOdlW.js → sankeyDiagram-XADWPNL6-CK_eMH3e.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-FGHM5R23-BAvOyUC-.js → sequenceDiagram-FGHM5R23-D2YygHqF.js} +1 -1
- package/dist/client/assets/{stateDiagram-FHFEXIEX-gCtZrvR-.js → stateDiagram-FHFEXIEX-DEDhnbhU.js} +1 -1
- package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-ji50PgJQ.js +1 -0
- package/dist/client/assets/{timeline-definition-GMOUNBTQ-CTHf-uxq.js → timeline-definition-GMOUNBTQ-Brgny70W.js} +1 -1
- package/dist/client/assets/{vennDiagram-DHZGUBPP-5gvXi0dO.js → vennDiagram-DHZGUBPP-B1I5E8Hy.js} +1 -1
- package/dist/client/assets/{wardley-RL74JXVD-XR-qQTWZ.js → wardley-RL74JXVD-P0VCYfKI.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-NUSXRM2D-EwPsMHdt.js → wardleyDiagram-NUSXRM2D-DhYC5Sus.js} +1 -1
- package/dist/client/assets/{xychartDiagram-5P7HB3ND-CePwuUb7.js → xychartDiagram-5P7HB3ND-ByJX99rJ.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/fleet-plugins/diff/routes.mjs +207 -34
- package/dist/fleet-plugins/file-explorer/routes.mjs +1 -1
- package/dist/fleet-plugins/skills/routes.mjs +101 -83
- package/dist/fleet-plugins/terminal/routes.mjs +556 -325
- package/package.json +1 -1
- package/dist/client/assets/channel-DlT8zCVq.js +0 -1
- package/dist/client/assets/classDiagram-6PBFFD2Q-B-UN9f9r.js +0 -1
- package/dist/client/assets/classDiagram-v2-HSJHXN6E-B-UN9f9r.js +0 -1
- package/dist/client/assets/clone-CDPRFCO0.js +0 -1
- package/dist/client/assets/index-DWgndVkX.js +0 -404
- package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-Bdb0YU66.js +0 -1
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import * as
|
|
3
|
-
import
|
|
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
|
|
9
|
-
import
|
|
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,
|
|
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 =
|
|
47
|
+
var NOFOLLOW_FLAG = fs2.constants.O_NOFOLLOW ?? 0;
|
|
48
48
|
function safeLstat(targetPath) {
|
|
49
49
|
try {
|
|
50
|
-
return
|
|
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
|
-
|
|
64
|
+
fs2.chmodSync(dirPath, SECURE_DIR_MODE);
|
|
65
65
|
return;
|
|
66
66
|
}
|
|
67
|
-
|
|
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
|
-
|
|
72
|
+
fs2.chmodSync(dirPath, SECURE_DIR_MODE);
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
// ../../packages/
|
|
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
|
-
|
|
91
|
+
fs2.writeFileSync(tempPath, content, { encoding: "utf-8", flag: "wx", mode });
|
|
92
92
|
tempCreated = true;
|
|
93
93
|
if (doFsync) {
|
|
94
|
-
const fd =
|
|
94
|
+
const fd = fs2.openSync(tempPath, "r");
|
|
95
95
|
try {
|
|
96
96
|
fsyncSyncBestEffort(fd);
|
|
97
97
|
} finally {
|
|
98
|
-
|
|
98
|
+
fs2.closeSync(fd);
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
|
-
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
133
|
+
const stat3 = fs2.lstatSync(tempPath);
|
|
134
134
|
if (stat3?.isFile() && !stat3.isSymbolicLink() && now - stat3.mtimeMs >= minAgeMs) {
|
|
135
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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 =
|
|
306
|
-
if (!
|
|
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(
|
|
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
|
-
|
|
315
|
+
fs2.closeSync(fd);
|
|
316
316
|
} catch {
|
|
317
317
|
}
|
|
318
318
|
}
|
|
319
319
|
}
|
|
320
320
|
}
|
|
321
321
|
|
|
322
|
-
// ../../packages/
|
|
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 (!
|
|
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 (!
|
|
347
|
+
if (!fs2.existsSync(authPath)) {
|
|
348
348
|
return void 0;
|
|
349
349
|
}
|
|
350
|
-
fd =
|
|
351
|
-
if (!
|
|
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(
|
|
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
|
-
|
|
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 (!
|
|
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 =
|
|
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 =
|
|
464
|
+
const stat3 = fs2.lstatSync(filePath);
|
|
465
465
|
if (!stat3 || !stat3.isFile() || stat3.isSymbolicLink()) {
|
|
466
466
|
return sanitize(void 0);
|
|
467
467
|
}
|
|
468
|
-
fd =
|
|
469
|
-
if (!
|
|
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(
|
|
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
|
-
|
|
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/
|
|
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", "
|
|
536
|
-
const changed = Object.keys(value).some((key) => !allowedKeys.has(key)) || "
|
|
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/
|
|
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/
|
|
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
|
-
|
|
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
|
|
18434
|
-
|
|
18435
|
-
|
|
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
|
|
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: "
|
|
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
|
|
18961
|
-
|
|
18962
|
-
await this.execCommand(whichCommand, [command], 3e3);
|
|
19044
|
+
const resolved = findBinaryPath(command, process.env);
|
|
19045
|
+
if (resolved !== void 0) {
|
|
18963
19046
|
return true;
|
|
18964
|
-
}
|
|
18965
|
-
|
|
18966
|
-
|
|
18967
|
-
|
|
18968
|
-
|
|
18969
|
-
|
|
18970
|
-
|
|
18971
|
-
|
|
18972
|
-
|
|
18973
|
-
|
|
18974
|
-
|
|
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
|
|
19003
|
-
|
|
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 (!
|
|
20311
|
+
if (!fs2.existsSync(root)) {
|
|
20239
20312
|
return null;
|
|
20240
20313
|
}
|
|
20241
|
-
for (const entry of
|
|
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 =
|
|
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 = `/${
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
23633
|
-
|
|
23606
|
+
const resolvedDir = dir ?? getFleetDataDir();
|
|
23607
|
+
runtimeState.storeDir = resolvedDir;
|
|
23608
|
+
ensureSafeDirectory(resolvedDir);
|
|
23634
23609
|
withStoreLock(() => {
|
|
23635
|
-
unlinkStaleSubagentModeFile(
|
|
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
|
|
23622
|
+
return readCarriers();
|
|
23648
23623
|
}
|
|
23649
23624
|
function getCarriersFilePath() {
|
|
23650
|
-
|
|
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
|
-
|
|
23665
|
-
|
|
23666
|
-
const lockDir = path27.join(
|
|
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
|
|
23673
|
-
|
|
23674
|
-
return readCarriersFromDir(runtimeState.storeDir);
|
|
23645
|
+
function resolveStoreDir() {
|
|
23646
|
+
return runtimeState.storeDir ?? getFleetDataDir();
|
|
23675
23647
|
}
|
|
23676
|
-
function
|
|
23677
|
-
return
|
|
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 =
|
|
23655
|
+
const stat3 = fs2.lstatSync(filePath);
|
|
23684
23656
|
if (!stat3.isFile() || stat3.isSymbolicLink()) return {};
|
|
23685
|
-
fd =
|
|
23686
|
-
if (!
|
|
23687
|
-
return sanitizeFleetCarriers(JSON.parse(
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
23709
|
-
|
|
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
|
-
|
|
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
|
|
26023
|
-
return settings2.immutableTypes ? Object.freeze(
|
|
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 ??
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
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}:${
|
|
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(
|
|
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
|
|
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()}-${
|
|
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
|
|
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 ?? (() =>
|
|
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 ??
|
|
39445
|
-
const env = deps.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 ??
|
|
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(
|
|
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
|
|
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(
|
|
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
|
-
|
|
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 ??
|
|
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}.${
|
|
40299
|
-
|
|
40300
|
-
|
|
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
|
-
|
|
40476
|
+
fs2__default.renameSync(tempPath, finalPath);
|
|
40303
40477
|
return { path: finalPath, providerSession };
|
|
40304
40478
|
}
|
|
40305
40479
|
function parseProvider(value) {
|
|
40306
|
-
if (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
|
-
|
|
40500
|
+
const sessionId = readProviderSessionId(input);
|
|
40327
40501
|
return {
|
|
40328
40502
|
provider,
|
|
40329
|
-
sessionId
|
|
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
|
|
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
|
-
|
|
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 ??
|
|
40437
|
-
const env = deps.env ??
|
|
40438
|
-
const execPath = deps.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 ??
|
|
40441
|
-
const entryPath = resolveHookEntryPath(deps.entryPath ??
|
|
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 =
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
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:
|
|
41521
|
-
env: { ...
|
|
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 ((
|
|
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
|
|
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 !==
|
|
41985
|
+
if (Object.keys(value).length !== 1) return false;
|
|
41756
41986
|
const body = value;
|
|
41757
|
-
return typeof body.
|
|
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
|