@dotobokuri/fleet-console 1.6.0 → 1.7.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 +1 -0
- package/README.md +9 -4
- package/dist/cli-bin.mjs +439 -284
- package/dist/cli.d.ts +4 -0
- package/dist/cli.mjs +439 -284
- package/dist/client/assets/{_baseUniq-CYDnUUwD.js → _baseUniq-DaRHKvkJ.js} +1 -1
- package/dist/client/assets/{arc-C2kUi1S_.js → arc-ByrjrNFZ.js} +1 -1
- package/dist/client/assets/{architectureDiagram-Q4EWVU46-CsfgL2zC.js → architectureDiagram-Q4EWVU46-yRDXYtYq.js} +1 -1
- package/dist/client/assets/{blockDiagram-DXYQGD6D-uqim2Pmo.js → blockDiagram-DXYQGD6D-B3Ud4HmY.js} +1 -1
- package/dist/client/assets/{c4Diagram-AHTNJAMY-CRz88GqP.js → c4Diagram-AHTNJAMY-BWtT7uJ6.js} +1 -1
- package/dist/client/assets/channel-D1hUfR86.js +1 -0
- package/dist/client/assets/{chunk-4BX2VUAB-DNgf85a7.js → chunk-4BX2VUAB-Cdk_k5EX.js} +1 -1
- package/dist/client/assets/{chunk-4TB4RGXK-Ds39jFtV.js → chunk-4TB4RGXK-CfeLiRAa.js} +1 -1
- package/dist/client/assets/{chunk-55IACEB6-Bv7hCHgD.js → chunk-55IACEB6-B26kabv5.js} +1 -1
- package/dist/client/assets/{chunk-EDXVE4YY-BUjgWLOR.js → chunk-EDXVE4YY-CZ5hqsgg.js} +1 -1
- package/dist/client/assets/{chunk-FMBD7UC4-WVMeE3Je.js → chunk-FMBD7UC4-CuCp-r0v.js} +1 -1
- package/dist/client/assets/{chunk-OYMX7WX6-Bd5Z4NNL.js → chunk-OYMX7WX6-Dy5T8Uzb.js} +1 -1
- package/dist/client/assets/{chunk-QZHKN3VN-BfIbGoT4.js → chunk-QZHKN3VN-PNRzwWoU.js} +1 -1
- package/dist/client/assets/{chunk-YZCP3GAM-T_CDhFqg.js → chunk-YZCP3GAM-BjJxIVvV.js} +1 -1
- package/dist/client/assets/classDiagram-6PBFFD2Q-B7ZtwAd2.js +1 -0
- package/dist/client/assets/classDiagram-v2-HSJHXN6E-B7ZtwAd2.js +1 -0
- package/dist/client/assets/clone-BggxG0Ng.js +1 -0
- package/dist/client/assets/{cose-bilkent-S5V4N54A-M6EvTH7M.js → cose-bilkent-S5V4N54A-CIL2KUnC.js} +1 -1
- package/dist/client/assets/{dagre-KV5264BT-UUCScvPY.js → dagre-KV5264BT-BoekxdN3.js} +1 -1
- package/dist/client/assets/{diagram-5BDNPKRD-BnmEvwtB.js → diagram-5BDNPKRD-8Uqn3Uve.js} +1 -1
- package/dist/client/assets/{diagram-G4DWMVQ6-QHdTQz1G.js → diagram-G4DWMVQ6-CWZp4Fw1.js} +1 -1
- package/dist/client/assets/{diagram-MMDJMWI5-B-4tZ6wC.js → diagram-MMDJMWI5-Cxxmq5lR.js} +1 -1
- package/dist/client/assets/{diagram-TYMM5635-D5KVosUo.js → diagram-TYMM5635-BDL3SVhp.js} +1 -1
- package/dist/client/assets/{erDiagram-SMLLAGMA-B-FwpOjI.js → erDiagram-SMLLAGMA-Bm_XDDZi.js} +1 -1
- package/dist/client/assets/{flowDiagram-DWJPFMVM-CO00mjhm.js → flowDiagram-DWJPFMVM-z3JhyUpl.js} +1 -1
- package/dist/client/assets/{ganttDiagram-T4ZO3ILL-ChcRAmXN.js → ganttDiagram-T4ZO3ILL-DVfDRTRP.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-UUTBAWPF-BWSq2uT3.js → gitGraphDiagram-UUTBAWPF-_gni8LDF.js} +1 -1
- package/dist/client/assets/{graph-mErvxWG_.js → graph-Beq1lcyq.js} +1 -1
- package/dist/client/assets/index-3nhZQ9tb.css +1 -0
- package/dist/client/assets/index-DFffaVk9.js +734 -0
- package/dist/client/assets/{infoDiagram-42DDH7IO-CchQFIPi.js → infoDiagram-42DDH7IO-B-TP33al.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-UXIWVN3A-BAsF6BnZ.js → ishikawaDiagram-UXIWVN3A-1YDVINPA.js} +1 -1
- package/dist/client/assets/{journeyDiagram-VCZTEJTY-DE0wiQxC.js → journeyDiagram-VCZTEJTY-CZJuR6NC.js} +1 -1
- package/dist/client/assets/{kanban-definition-6JOO6SKY-BzPJLpKw.js → kanban-definition-6JOO6SKY-_sSHU_-t.js} +1 -1
- package/dist/client/assets/{layout-CO0unZG0.js → layout-UzmHJbGX.js} +1 -1
- package/dist/client/assets/{linear-CkDoVGz5.js → linear-BHitegAT.js} +1 -1
- package/dist/client/assets/{mermaid.core-BWqsf-WS.js → mermaid.core-ptwBQDH8.js} +4 -4
- package/dist/client/assets/{min-BMb-G34C.js → min-CBjwmJst.js} +1 -1
- package/dist/client/assets/{mindmap-definition-QFDTVHPH-XVxnUTPw.js → mindmap-definition-QFDTVHPH-C8NIvAO1.js} +1 -1
- package/dist/client/assets/{pieDiagram-DEJITSTG-CKM6Cfhz.js → pieDiagram-DEJITSTG-paebhRXC.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-34T5L4WZ-Dn_2AZqA.js → quadrantDiagram-34T5L4WZ-Bk0pN-T7.js} +1 -1
- package/dist/client/assets/{requirementDiagram-MS252O5E-uNgGGE60.js → requirementDiagram-MS252O5E-CkPyeOJB.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-XADWPNL6-B75Ahck1.js → sankeyDiagram-XADWPNL6-tJsRZl9C.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-FGHM5R23-Cw5UNG2_.js → sequenceDiagram-FGHM5R23-D1V2Qnb3.js} +1 -1
- package/dist/client/assets/{stateDiagram-FHFEXIEX-C6u6py_B.js → stateDiagram-FHFEXIEX-DdEFxPzQ.js} +1 -1
- package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-CpqK8Q3C.js +1 -0
- package/dist/client/assets/{timeline-definition-GMOUNBTQ-Bi50wA17.js → timeline-definition-GMOUNBTQ-D8sNtFqY.js} +1 -1
- package/dist/client/assets/{vennDiagram-DHZGUBPP-CufQGlDN.js → vennDiagram-DHZGUBPP-DoTEQk3E.js} +1 -1
- package/dist/client/assets/{wardley-RL74JXVD-BQLghHpH.js → wardley-RL74JXVD-BuEgLJ7M.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-NUSXRM2D-C-_4o-CK.js → wardleyDiagram-NUSXRM2D-B0Gl34Zh.js} +1 -1
- package/dist/client/assets/{xychartDiagram-5P7HB3ND-e4ekvSc7.js → xychartDiagram-5P7HB3ND-Bf4nAMbM.js} +1 -1
- package/dist/client/index.html +2 -2
- package/package.json +1 -1
- package/dist/client/assets/channel-BDggAVtM.js +0 -1
- package/dist/client/assets/classDiagram-6PBFFD2Q-AVod154E.js +0 -1
- package/dist/client/assets/classDiagram-v2-HSJHXN6E-AVod154E.js +0 -1
- package/dist/client/assets/clone-DMJcvMWj.js +0 -1
- package/dist/client/assets/index-B4QPttGw.css +0 -1
- package/dist/client/assets/index-GN6Lp6Jj.js +0 -734
- package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-BMBsbsoy.js +0 -1
package/dist/cli-bin.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import * as fs5 from 'fs';
|
|
|
4
4
|
import fs5__default, { readFileSync, existsSync, mkdtempSync, writeFileSync, mkdirSync, rmSync, chmodSync, renameSync, readdirSync, constants, openSync, closeSync, lstatSync, unlinkSync, realpathSync, statSync, symlinkSync, fstatSync } from 'fs';
|
|
5
5
|
import * as path93 from 'path';
|
|
6
6
|
import path93__default, { join, resolve, relative, dirname } from 'path';
|
|
7
|
-
import
|
|
7
|
+
import process6 from 'process';
|
|
8
8
|
import { fileURLToPath, pathToFileURL } from 'url';
|
|
9
9
|
import * as os22 from 'os';
|
|
10
10
|
import os22__default from 'os';
|
|
@@ -969,10 +969,10 @@ function mergeDefs(...defs) {
|
|
|
969
969
|
function cloneDef(schema) {
|
|
970
970
|
return mergeDefs(schema._zod.def);
|
|
971
971
|
}
|
|
972
|
-
function getElementAtPath(obj,
|
|
973
|
-
if (!
|
|
972
|
+
function getElementAtPath(obj, path35) {
|
|
973
|
+
if (!path35)
|
|
974
974
|
return obj;
|
|
975
|
-
return
|
|
975
|
+
return path35.reduce((acc, key) => acc?.[key], obj);
|
|
976
976
|
}
|
|
977
977
|
function promiseAllObject(promisesObj) {
|
|
978
978
|
const keys = Object.keys(promisesObj);
|
|
@@ -1381,11 +1381,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
1381
1381
|
}
|
|
1382
1382
|
return false;
|
|
1383
1383
|
}
|
|
1384
|
-
function prefixIssues(
|
|
1384
|
+
function prefixIssues(path35, issues) {
|
|
1385
1385
|
return issues.map((iss) => {
|
|
1386
1386
|
var _a3;
|
|
1387
1387
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
1388
|
-
iss.path.unshift(
|
|
1388
|
+
iss.path.unshift(path35);
|
|
1389
1389
|
return iss;
|
|
1390
1390
|
});
|
|
1391
1391
|
}
|
|
@@ -1532,16 +1532,16 @@ function flattenError(error51, mapper = (issue3) => issue3.message) {
|
|
|
1532
1532
|
}
|
|
1533
1533
|
function formatError(error51, mapper = (issue3) => issue3.message) {
|
|
1534
1534
|
const fieldErrors = { _errors: [] };
|
|
1535
|
-
const processError = (error52,
|
|
1535
|
+
const processError = (error52, path35 = []) => {
|
|
1536
1536
|
for (const issue3 of error52.issues) {
|
|
1537
1537
|
if (issue3.code === "invalid_union" && issue3.errors.length) {
|
|
1538
|
-
issue3.errors.map((issues) => processError({ issues }, [...
|
|
1538
|
+
issue3.errors.map((issues) => processError({ issues }, [...path35, ...issue3.path]));
|
|
1539
1539
|
} else if (issue3.code === "invalid_key") {
|
|
1540
|
-
processError({ issues: issue3.issues }, [...
|
|
1540
|
+
processError({ issues: issue3.issues }, [...path35, ...issue3.path]);
|
|
1541
1541
|
} else if (issue3.code === "invalid_element") {
|
|
1542
|
-
processError({ issues: issue3.issues }, [...
|
|
1542
|
+
processError({ issues: issue3.issues }, [...path35, ...issue3.path]);
|
|
1543
1543
|
} else {
|
|
1544
|
-
const fullpath = [...
|
|
1544
|
+
const fullpath = [...path35, ...issue3.path];
|
|
1545
1545
|
if (fullpath.length === 0) {
|
|
1546
1546
|
fieldErrors._errors.push(mapper(issue3));
|
|
1547
1547
|
} else {
|
|
@@ -1568,17 +1568,17 @@ function formatError(error51, mapper = (issue3) => issue3.message) {
|
|
|
1568
1568
|
}
|
|
1569
1569
|
function treeifyError(error51, mapper = (issue3) => issue3.message) {
|
|
1570
1570
|
const result = { errors: [] };
|
|
1571
|
-
const processError = (error52,
|
|
1571
|
+
const processError = (error52, path35 = []) => {
|
|
1572
1572
|
var _a3, _b;
|
|
1573
1573
|
for (const issue3 of error52.issues) {
|
|
1574
1574
|
if (issue3.code === "invalid_union" && issue3.errors.length) {
|
|
1575
|
-
issue3.errors.map((issues) => processError({ issues }, [...
|
|
1575
|
+
issue3.errors.map((issues) => processError({ issues }, [...path35, ...issue3.path]));
|
|
1576
1576
|
} else if (issue3.code === "invalid_key") {
|
|
1577
|
-
processError({ issues: issue3.issues }, [...
|
|
1577
|
+
processError({ issues: issue3.issues }, [...path35, ...issue3.path]);
|
|
1578
1578
|
} else if (issue3.code === "invalid_element") {
|
|
1579
|
-
processError({ issues: issue3.issues }, [...
|
|
1579
|
+
processError({ issues: issue3.issues }, [...path35, ...issue3.path]);
|
|
1580
1580
|
} else {
|
|
1581
|
-
const fullpath = [...
|
|
1581
|
+
const fullpath = [...path35, ...issue3.path];
|
|
1582
1582
|
if (fullpath.length === 0) {
|
|
1583
1583
|
result.errors.push(mapper(issue3));
|
|
1584
1584
|
continue;
|
|
@@ -1610,8 +1610,8 @@ function treeifyError(error51, mapper = (issue3) => issue3.message) {
|
|
|
1610
1610
|
}
|
|
1611
1611
|
function toDotPath(_path) {
|
|
1612
1612
|
const segs = [];
|
|
1613
|
-
const
|
|
1614
|
-
for (const seg of
|
|
1613
|
+
const path35 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
1614
|
+
for (const seg of path35) {
|
|
1615
1615
|
if (typeof seg === "number")
|
|
1616
1616
|
segs.push(`[${seg}]`);
|
|
1617
1617
|
else if (typeof seg === "symbol")
|
|
@@ -14275,13 +14275,13 @@ function resolveRef(ref, ctx) {
|
|
|
14275
14275
|
if (!ref.startsWith("#")) {
|
|
14276
14276
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
14277
14277
|
}
|
|
14278
|
-
const
|
|
14279
|
-
if (
|
|
14278
|
+
const path35 = ref.slice(1).split("/").filter(Boolean);
|
|
14279
|
+
if (path35.length === 0) {
|
|
14280
14280
|
return ctx.rootSchema;
|
|
14281
14281
|
}
|
|
14282
14282
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
14283
|
-
if (
|
|
14284
|
-
const key =
|
|
14283
|
+
if (path35[0] === defsKey) {
|
|
14284
|
+
const key = path35[1];
|
|
14285
14285
|
if (!key || !ctx.defs[key]) {
|
|
14286
14286
|
throw new Error(`Reference not found: ${ref}`);
|
|
14287
14287
|
}
|
|
@@ -17046,7 +17046,9 @@ function killProcess(child, forceTimeoutMs = 3e3) {
|
|
|
17046
17046
|
try {
|
|
17047
17047
|
execSync(`taskkill /PID ${child.pid} /T /F`, {
|
|
17048
17048
|
stdio: "pipe",
|
|
17049
|
-
timeout: 5e3
|
|
17049
|
+
timeout: 5e3,
|
|
17050
|
+
// 콘솔 없는 호스트에서 taskkill 호출 시 새 콘솔 창이 깜빡이는 것을 방지한다.
|
|
17051
|
+
windowsHide: true
|
|
17050
17052
|
});
|
|
17051
17053
|
} catch {
|
|
17052
17054
|
child.kill("SIGKILL");
|
|
@@ -17120,7 +17122,12 @@ var BaseConnection = class extends EventEmitter {
|
|
|
17120
17122
|
cwd: this.cwd,
|
|
17121
17123
|
stdio: ["pipe", "pipe", "pipe"],
|
|
17122
17124
|
env: this.env,
|
|
17123
|
-
windowsVerbatimArguments: true
|
|
17125
|
+
windowsVerbatimArguments: true,
|
|
17126
|
+
// 콘솔이 없는 호스트(예: fleet-console 백엔드)에서 cmd.exe를 spawn하면
|
|
17127
|
+
// Windows가 새 콘솔 창을 할당해 깜빡인다. stdio는 모두 pipe라 가시 콘솔이
|
|
17128
|
+
// 불필요하므로 CREATE_NO_WINDOW로 창 생성을 억제한다. (fleet-cli처럼 콘솔이
|
|
17129
|
+
// 이미 있는 경우에도 무해하다.)
|
|
17130
|
+
windowsHide: true
|
|
17124
17131
|
}) : spawn(this.command, this.args, {
|
|
17125
17132
|
cwd: this.cwd,
|
|
17126
17133
|
stdio: ["pipe", "pipe", "pipe"],
|
|
@@ -17876,7 +17883,9 @@ function resolveNpxPath(env) {
|
|
|
17876
17883
|
encoding: "utf-8",
|
|
17877
17884
|
stdio: "pipe",
|
|
17878
17885
|
timeout: 5e3,
|
|
17879
|
-
env
|
|
17886
|
+
env,
|
|
17887
|
+
// 콘솔 없는 호스트에서 `where npx` 실행 시 콘솔 창이 깜빡이는 것을 방지한다.
|
|
17888
|
+
windowsHide: true
|
|
17880
17889
|
}).trim();
|
|
17881
17890
|
const candidates = result.split("\n").map((line) => line.trim()).filter((line) => line.length > 0);
|
|
17882
17891
|
if (windows) {
|
|
@@ -32447,7 +32456,7 @@ function createSessionCaptureHookExec(deps) {
|
|
|
32447
32456
|
deps.provider
|
|
32448
32457
|
] : [deps.entryPath, "hook", "capture-session", deps.provider];
|
|
32449
32458
|
return {
|
|
32450
|
-
command: deps.execPath ??
|
|
32459
|
+
command: deps.execPath ?? process6.execPath,
|
|
32451
32460
|
args
|
|
32452
32461
|
};
|
|
32453
32462
|
}
|
|
@@ -32805,15 +32814,21 @@ function claudeHooks(options) {
|
|
|
32805
32814
|
if (!hookExec) {
|
|
32806
32815
|
throw new Error("Fleet Claude session hook command is required");
|
|
32807
32816
|
}
|
|
32808
|
-
const
|
|
32817
|
+
const userPromptSubmitExecs = [options.captureSessionHookExec, options.turnStartHookExec].filter((exec) => exec !== void 0);
|
|
32818
|
+
const stopExecs = [options.turnEndHookExec].filter((exec) => exec !== void 0);
|
|
32809
32819
|
return {
|
|
32810
32820
|
hooks: {
|
|
32811
32821
|
SessionStart: [{
|
|
32812
32822
|
hooks: [claudeCommandHook(hookExec)]
|
|
32813
32823
|
}],
|
|
32814
|
-
...
|
|
32824
|
+
...userPromptSubmitExecs.length > 0 ? {
|
|
32815
32825
|
UserPromptSubmit: [{
|
|
32816
|
-
hooks:
|
|
32826
|
+
hooks: userPromptSubmitExecs.map(claudeCommandHook)
|
|
32827
|
+
}]
|
|
32828
|
+
} : {},
|
|
32829
|
+
...stopExecs.length > 0 ? {
|
|
32830
|
+
Stop: [{
|
|
32831
|
+
hooks: stopExecs.map(claudeCommandHook)
|
|
32817
32832
|
}]
|
|
32818
32833
|
} : {}
|
|
32819
32834
|
}
|
|
@@ -33576,11 +33591,17 @@ async function injectAgentCliProfile(profile, options) {
|
|
|
33576
33591
|
dataDir: options.dataDir,
|
|
33577
33592
|
rootDir: options.pluginRootDir,
|
|
33578
33593
|
captureSessionHookExec: options.captureSessionHookExec,
|
|
33594
|
+
turnStartHookExec: options.turnStartHookExec,
|
|
33595
|
+
turnEndHookExec: options.turnEndHookExec,
|
|
33579
33596
|
hookExec: startupDefinitions.host === "claude" ? requireHookExec(options.hookExec) : void 0,
|
|
33580
33597
|
withMarketplaceLock: options.withMarketplaceLock
|
|
33581
33598
|
});
|
|
33582
33599
|
const codexPluginKeys = plugin.codexRegistrations.map((registration) => `${registration.pluginName}@${registration.marketplaceName}`);
|
|
33583
|
-
const codexProfile = profile.id === "codex" ? writeCodexFleetProfile(profile.env, doctrine, codexPluginKeys,
|
|
33600
|
+
const codexProfile = profile.id === "codex" ? writeCodexFleetProfile(profile.env, doctrine, codexPluginKeys, {
|
|
33601
|
+
captureSessionHookExec: options.captureSessionHookExec,
|
|
33602
|
+
turnStartHookExec: options.turnStartHookExec,
|
|
33603
|
+
turnEndHookExec: options.turnEndHookExec
|
|
33604
|
+
}, (cleanup2) => tempCleanups.push(cleanup2)) : void 0;
|
|
33584
33605
|
const launchWarnings = [];
|
|
33585
33606
|
for (const registration of plugin.codexRegistrations) {
|
|
33586
33607
|
const registrationWarning = await ensureCodexPluginRegistered(registration, {
|
|
@@ -33656,7 +33677,7 @@ function writeSystemPromptFile(cliId, systemPrompt, onCleanup) {
|
|
|
33656
33677
|
chmodBestEffort2(filePath, SYSTEM_PROMPT_FILE_MODE);
|
|
33657
33678
|
return filePath;
|
|
33658
33679
|
}
|
|
33659
|
-
function writeCodexFleetProfile(env, doctrine, pluginKeys,
|
|
33680
|
+
function writeCodexFleetProfile(env, doctrine, pluginKeys, hookExecs, onCleanup) {
|
|
33660
33681
|
const codexHome = env.CODEX_HOME ?? path93__default.join(env.HOME ?? os22__default.homedir(), ".codex");
|
|
33661
33682
|
mkdirSync(codexHome, { recursive: true });
|
|
33662
33683
|
pruneStaleCodexFleetProfiles(codexHome);
|
|
@@ -33676,19 +33697,31 @@ function writeCodexFleetProfile(env, doctrine, pluginKeys, captureSessionHookExe
|
|
|
33676
33697
|
"enabled = true",
|
|
33677
33698
|
""
|
|
33678
33699
|
]),
|
|
33679
|
-
...
|
|
33700
|
+
...codexHooksConfig(hookExecs)
|
|
33680
33701
|
].join("\n"));
|
|
33681
33702
|
chmodBestEffort2(profilePath, SYSTEM_PROMPT_FILE_MODE);
|
|
33682
33703
|
return { profileName, profilePath };
|
|
33683
33704
|
}
|
|
33684
|
-
function
|
|
33685
|
-
|
|
33686
|
-
const
|
|
33687
|
-
return [
|
|
33688
|
-
|
|
33689
|
-
|
|
33690
|
-
|
|
33691
|
-
|
|
33705
|
+
function codexHooksConfig(hookExecs) {
|
|
33706
|
+
const userPromptSubmitExecs = [hookExecs.captureSessionHookExec, hookExecs.turnStartHookExec].filter((exec) => exec !== void 0);
|
|
33707
|
+
const stopExecs = [hookExecs.turnEndHookExec].filter((exec) => exec !== void 0);
|
|
33708
|
+
if (userPromptSubmitExecs.length === 0 && stopExecs.length === 0) return [];
|
|
33709
|
+
const lines = ["[hooks]"];
|
|
33710
|
+
if (userPromptSubmitExecs.length > 0) {
|
|
33711
|
+
lines.push(`UserPromptSubmit = ${codexHookHandlersInline(userPromptSubmitExecs)}`);
|
|
33712
|
+
}
|
|
33713
|
+
if (stopExecs.length > 0) {
|
|
33714
|
+
lines.push(`Stop = ${codexHookHandlersInline(stopExecs)}`);
|
|
33715
|
+
}
|
|
33716
|
+
lines.push("");
|
|
33717
|
+
return lines;
|
|
33718
|
+
}
|
|
33719
|
+
function codexHookHandlersInline(execs) {
|
|
33720
|
+
const handlers = execs.map((exec) => {
|
|
33721
|
+
const command2 = buildPosixShellCommand([exec.command, ...exec.args]);
|
|
33722
|
+
return `{ type = "command", command = "${escapeTomlBasicString2(command2)}" }`;
|
|
33723
|
+
}).join(", ");
|
|
33724
|
+
return `[{ hooks = [${handlers}] }]`;
|
|
33692
33725
|
}
|
|
33693
33726
|
function writeFileNoFollow2(filePath, content) {
|
|
33694
33727
|
const flags = constants.O_WRONLY | constants.O_CREAT | constants.O_TRUNC | constants.O_NOFOLLOW;
|
|
@@ -41842,6 +41875,12 @@ function createConsoleObservabilityStore(deps = {}) {
|
|
|
41842
41875
|
session.status = status;
|
|
41843
41876
|
return toTerminalSessionInfo(session);
|
|
41844
41877
|
}
|
|
41878
|
+
function setTerminalSessionTurnState(sessionId, turnState) {
|
|
41879
|
+
const session = terminalSessionsById.get(sessionId);
|
|
41880
|
+
if (!session) return null;
|
|
41881
|
+
session.turnState = turnState;
|
|
41882
|
+
return toTerminalSessionInfo(session);
|
|
41883
|
+
}
|
|
41845
41884
|
function transitionTerminalSessionToDormant(sessionId, providerSession) {
|
|
41846
41885
|
const session = terminalSessionsById.get(sessionId);
|
|
41847
41886
|
if (!session) return null;
|
|
@@ -41909,6 +41948,7 @@ function createConsoleObservabilityStore(deps = {}) {
|
|
|
41909
41948
|
subscribeAll,
|
|
41910
41949
|
updateTerminalSessionProviderSession,
|
|
41911
41950
|
updateTerminalSessionStatus,
|
|
41951
|
+
setTerminalSessionTurnState,
|
|
41912
41952
|
transitionTerminalSessionToDormant,
|
|
41913
41953
|
removeTerminalSession,
|
|
41914
41954
|
registerTerminalRuntimeSession,
|
|
@@ -41977,6 +42017,7 @@ function toTerminalSessionInfo(state) {
|
|
|
41977
42017
|
cliId: state.cliId,
|
|
41978
42018
|
cliLabel: state.cliLabel,
|
|
41979
42019
|
status: state.status,
|
|
42020
|
+
turnState: state.turnState ?? "none",
|
|
41980
42021
|
createdAt: state.createdAt,
|
|
41981
42022
|
theaterId: state.theaterId,
|
|
41982
42023
|
registrationId: state.registrationId,
|
|
@@ -42193,6 +42234,126 @@ function resolveConsolePath(pathname) {
|
|
|
42193
42234
|
if (!path93__default.extname(withoutPrefix)) return "index.html";
|
|
42194
42235
|
return withoutPrefix;
|
|
42195
42236
|
}
|
|
42237
|
+
var TerminalFolderListError = class extends Error {
|
|
42238
|
+
code;
|
|
42239
|
+
constructor(code) {
|
|
42240
|
+
super(code);
|
|
42241
|
+
this.name = "TerminalFolderListError";
|
|
42242
|
+
this.code = code;
|
|
42243
|
+
}
|
|
42244
|
+
};
|
|
42245
|
+
var DIRECTORY_ENTRY_CAP = 500;
|
|
42246
|
+
var WINDOWS_DRIVE_LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");
|
|
42247
|
+
async function listTerminalFolders(requestedPath, deps = {}) {
|
|
42248
|
+
const platform = deps.platform ?? process.platform;
|
|
42249
|
+
const stat5 = deps.stat ?? fs5__default.promises.stat;
|
|
42250
|
+
const opendir = deps.opendir ?? fs5__default.promises.opendir;
|
|
42251
|
+
const targetPath = normalizeListPath(requestedPath, platform, deps);
|
|
42252
|
+
const roots = await listRoots(platform, stat5);
|
|
42253
|
+
const targetStat = await statDirectory(targetPath, stat5);
|
|
42254
|
+
if (!targetStat.isDirectory()) throw new TerminalFolderListError("invalid_path");
|
|
42255
|
+
const entries = [];
|
|
42256
|
+
const truncated = await collectDirectoryEntries(targetPath, opendir, stat5, entries);
|
|
42257
|
+
entries.sort((a, b) => a.name.localeCompare(b.name));
|
|
42258
|
+
return {
|
|
42259
|
+
path: targetPath,
|
|
42260
|
+
parentPath: parentPath(targetPath, platform),
|
|
42261
|
+
roots,
|
|
42262
|
+
entries,
|
|
42263
|
+
...truncated ? { truncated: true } : {}
|
|
42264
|
+
};
|
|
42265
|
+
}
|
|
42266
|
+
function normalizeFolderBrowserPath(value, platform = process.platform) {
|
|
42267
|
+
if (typeof value !== "string" || value.length === 0 || value.includes("\0")) throw new TerminalFolderListError("invalid_path");
|
|
42268
|
+
if (isWindowsAmbiguousPath(value, platform) || !path93__default.isAbsolute(value)) throw new TerminalFolderListError("invalid_path");
|
|
42269
|
+
return path93__default.resolve(value);
|
|
42270
|
+
}
|
|
42271
|
+
function normalizeListPath(requestedPath, platform, deps) {
|
|
42272
|
+
if (requestedPath === null || requestedPath === void 0) {
|
|
42273
|
+
const home = deps.homedir?.() ?? os22__default.homedir();
|
|
42274
|
+
const start = home || deps.cwd?.() || process.cwd();
|
|
42275
|
+
return path93__default.resolve(start);
|
|
42276
|
+
}
|
|
42277
|
+
return normalizeFolderBrowserPath(requestedPath, platform);
|
|
42278
|
+
}
|
|
42279
|
+
async function listRoots(platform, stat5) {
|
|
42280
|
+
if (platform !== "win32") return ["/"];
|
|
42281
|
+
const roots = [];
|
|
42282
|
+
await Promise.all(WINDOWS_DRIVE_LETTERS.map(async (letter) => {
|
|
42283
|
+
const root = `${letter}:\\`;
|
|
42284
|
+
try {
|
|
42285
|
+
if ((await stat5(root)).isDirectory()) roots.push(root);
|
|
42286
|
+
} catch {
|
|
42287
|
+
}
|
|
42288
|
+
}));
|
|
42289
|
+
return roots.sort();
|
|
42290
|
+
}
|
|
42291
|
+
async function statDirectory(targetPath, stat5) {
|
|
42292
|
+
try {
|
|
42293
|
+
return await stat5(targetPath);
|
|
42294
|
+
} catch (error51) {
|
|
42295
|
+
throw mapFsError(error51);
|
|
42296
|
+
}
|
|
42297
|
+
}
|
|
42298
|
+
async function collectDirectoryEntries(targetPath, opendir, stat5, entries) {
|
|
42299
|
+
const directory = await openDirectory(targetPath, opendir);
|
|
42300
|
+
try {
|
|
42301
|
+
let dirent = await directory.read();
|
|
42302
|
+
while (dirent !== null) {
|
|
42303
|
+
const entry = await toTerminalFolderEntry(targetPath, dirent, stat5);
|
|
42304
|
+
if (entry !== null) {
|
|
42305
|
+
if (entries.length >= DIRECTORY_ENTRY_CAP) return true;
|
|
42306
|
+
entries.push(entry);
|
|
42307
|
+
}
|
|
42308
|
+
dirent = await directory.read();
|
|
42309
|
+
}
|
|
42310
|
+
return false;
|
|
42311
|
+
} catch (error51) {
|
|
42312
|
+
throw mapFsError(error51);
|
|
42313
|
+
} finally {
|
|
42314
|
+
await directory.close();
|
|
42315
|
+
}
|
|
42316
|
+
}
|
|
42317
|
+
async function openDirectory(targetPath, opendir) {
|
|
42318
|
+
try {
|
|
42319
|
+
return await opendir(targetPath);
|
|
42320
|
+
} catch (error51) {
|
|
42321
|
+
throw mapFsError(error51);
|
|
42322
|
+
}
|
|
42323
|
+
}
|
|
42324
|
+
async function toTerminalFolderEntry(targetPath, dirent, stat5) {
|
|
42325
|
+
if (!dirent.isDirectory() && !dirent.isSymbolicLink()) return null;
|
|
42326
|
+
const entryPath = path93__default.join(targetPath, dirent.name);
|
|
42327
|
+
if (dirent.isDirectory()) return { name: dirent.name, path: entryPath, kind: "dir", accessible: true };
|
|
42328
|
+
const accessible = await statSymlinkDirectory(entryPath, stat5);
|
|
42329
|
+
if (accessible === null) return null;
|
|
42330
|
+
return { name: dirent.name, path: entryPath, kind: "dir", accessible };
|
|
42331
|
+
}
|
|
42332
|
+
async function statSymlinkDirectory(entryPath, stat5) {
|
|
42333
|
+
try {
|
|
42334
|
+
return (await stat5(entryPath)).isDirectory() ? true : null;
|
|
42335
|
+
} catch {
|
|
42336
|
+
return false;
|
|
42337
|
+
}
|
|
42338
|
+
}
|
|
42339
|
+
function mapFsError(error51) {
|
|
42340
|
+
const code = error51.code;
|
|
42341
|
+
if (code === "EACCES" || code === "EPERM") return new TerminalFolderListError("forbidden");
|
|
42342
|
+
if (code === "ENOENT" || code === "ENOTDIR") return new TerminalFolderListError("not_found");
|
|
42343
|
+
return new TerminalFolderListError("invalid_path");
|
|
42344
|
+
}
|
|
42345
|
+
function parentPath(targetPath, platform) {
|
|
42346
|
+
const parsed = path93__default.parse(targetPath);
|
|
42347
|
+
const resolved = path93__default.resolve(targetPath);
|
|
42348
|
+
if (resolved === path93__default.resolve(parsed.root)) return null;
|
|
42349
|
+
const parent = path93__default.dirname(resolved);
|
|
42350
|
+
if (platform === "win32" && parent === resolved) return null;
|
|
42351
|
+
return parent;
|
|
42352
|
+
}
|
|
42353
|
+
function isWindowsAmbiguousPath(value, platform) {
|
|
42354
|
+
if (platform !== "win32") return false;
|
|
42355
|
+
return /^[a-zA-Z]:(?![\\/])/.test(value) || /^[\\/](?![\\/])/.test(value);
|
|
42356
|
+
}
|
|
42196
42357
|
var GRANT_ID_BYTES = 24;
|
|
42197
42358
|
var DEFAULT_GRANT_TTL_MS = 6e4;
|
|
42198
42359
|
function createFolderGrantStore(deps = {}) {
|
|
@@ -42224,167 +42385,15 @@ function createFolderGrantStore(deps = {}) {
|
|
|
42224
42385
|
return { issue: issue3, consume };
|
|
42225
42386
|
}
|
|
42226
42387
|
function validateAbsoluteDirectory(cwd, statSync5 = fs5__default.statSync) {
|
|
42227
|
-
if (
|
|
42388
|
+
if (typeof cwd !== "string" || cwd.length === 0 || cwd.includes("\0")) throw new Error("invalid_folder");
|
|
42389
|
+
if (isWindowsAmbiguousPath2(cwd) || !path93__default.isAbsolute(cwd)) throw new Error("invalid_folder");
|
|
42228
42390
|
const normalized = path93__default.resolve(cwd);
|
|
42229
42391
|
if (!statSync5(normalized).isDirectory()) throw new Error("invalid_folder");
|
|
42230
42392
|
return normalized;
|
|
42231
42393
|
}
|
|
42232
|
-
|
|
42233
|
-
|
|
42234
|
-
|
|
42235
|
-
var DIALOG_TIMEOUT_MS = 3e4;
|
|
42236
|
-
var POWERSHELL_FOLDER_PICKER_CSHARP = `
|
|
42237
|
-
using System;
|
|
42238
|
-
using System.Runtime.InteropServices;
|
|
42239
|
-
namespace FleetPicker {
|
|
42240
|
-
[ComImport, Guid("43826d1e-e718-42ee-bc55-a1e261c37bfe"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
|
42241
|
-
public interface IShellItem {
|
|
42242
|
-
void BindToHandler();
|
|
42243
|
-
void GetParent();
|
|
42244
|
-
[PreserveSig] int GetDisplayName(int sigdn, out IntPtr ppszName);
|
|
42245
|
-
void GetAttributes();
|
|
42246
|
-
void Compare();
|
|
42247
|
-
}
|
|
42248
|
-
[ComImport, Guid("d57c7288-d4ad-4768-be02-9d969532d960"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
|
42249
|
-
public interface IFileOpenDialog {
|
|
42250
|
-
[PreserveSig] int Show(IntPtr parent);
|
|
42251
|
-
void SetFileTypes(); void SetFileTypeIndex(); void GetFileTypeIndex();
|
|
42252
|
-
void Advise(); void Unadvise();
|
|
42253
|
-
[PreserveSig] int SetOptions(uint fos);
|
|
42254
|
-
[PreserveSig] int GetOptions(out uint pfos);
|
|
42255
|
-
void SetDefaultFolder();
|
|
42256
|
-
void SetFolder(IShellItem psi);
|
|
42257
|
-
void GetFolder(); void GetCurrentSelection();
|
|
42258
|
-
void SetFileName(); void GetFileName(); void SetTitle(); void SetOkButtonLabel(); void SetFileNameLabel();
|
|
42259
|
-
[PreserveSig] int GetResult(out IShellItem ppsi);
|
|
42260
|
-
void AddPlace(IShellItem psi, int fdap);
|
|
42261
|
-
void SetDefaultExtension(); void Close(); void SetClientGuid(); void ClearClientData(); void SetFilter();
|
|
42262
|
-
void GetResults(); void GetSelectedItems();
|
|
42263
|
-
}
|
|
42264
|
-
[ComImport, Guid("DC1C5A9C-E88A-4DDE-A5A1-60F82A20AEF7")] public class FileOpenDialog { }
|
|
42265
|
-
public static class Picker {
|
|
42266
|
-
[DllImport("shell32.dll", CharSet=CharSet.Unicode, PreserveSig=false)]
|
|
42267
|
-
static extern void SHCreateItemFromParsingName(string pszPath, IntPtr pbc, ref Guid riid, [MarshalAs(UnmanagedType.Interface)] out IShellItem ppv);
|
|
42268
|
-
static IShellItem ItemFromPath(string path) {
|
|
42269
|
-
Guid iid = new Guid("43826d1e-e718-42ee-bc55-a1e261c37bfe");
|
|
42270
|
-
IShellItem it; SHCreateItemFromParsingName(path, IntPtr.Zero, ref iid, out it); return it;
|
|
42271
|
-
}
|
|
42272
|
-
public static string Pick(string initialPath) {
|
|
42273
|
-
var dlg = (IFileOpenDialog)(new FileOpenDialog());
|
|
42274
|
-
uint opts; dlg.GetOptions(out opts);
|
|
42275
|
-
dlg.SetOptions(opts | 0x20); // FOS_PICKFOLDERS
|
|
42276
|
-
if (!string.IsNullOrEmpty(initialPath)) {
|
|
42277
|
-
// \uC2DC\uC791 \uD3F4\uB354\uB97C WSL \uC704\uCE58\uB85C \uC9C0\uC815\uD558\uACE0 \uC88C\uCE21\uC5D0 \uACE0\uC815(FDAP_TOP). \uC2E4\uD328\uD574\uB3C4 \uAE30\uBCF8 \uC704\uCE58\uB85C \uC9C4\uD589\uD55C\uB2E4.
|
|
42278
|
-
try { IShellItem s = ItemFromPath(initialPath); dlg.AddPlace(s, 1); dlg.SetFolder(s); } catch { }
|
|
42279
|
-
}
|
|
42280
|
-
if (dlg.Show(IntPtr.Zero) != 0) return null; // \uCDE8\uC18C/\uC2E4\uD328 \uC2DC null
|
|
42281
|
-
IShellItem item; dlg.GetResult(out item);
|
|
42282
|
-
IntPtr ptr; if (item.GetDisplayName(unchecked((int)0x80058000), out ptr) != 0) return null; // SIGDN_FILESYSPATH; \uBE44 \uD30C\uC77C\uC2DC\uC2A4\uD15C \uC120\uD0DD \uAC00\uB4DC
|
|
42283
|
-
string path = Marshal.PtrToStringAuto(ptr);
|
|
42284
|
-
Marshal.FreeCoTaskMem(ptr);
|
|
42285
|
-
return path;
|
|
42286
|
-
}
|
|
42287
|
-
}
|
|
42288
|
-
}`;
|
|
42289
|
-
function createNativeFolderPicker(deps = {}) {
|
|
42290
|
-
const platform = deps.platform ?? process.platform;
|
|
42291
|
-
const runCommand = deps.runCommand ?? runNativeCommand;
|
|
42292
|
-
const statSync5 = deps.statSync ?? fs5__default.statSync;
|
|
42293
|
-
const readProcVersion = deps.readProcVersion ?? defaultReadProcVersion;
|
|
42294
|
-
const env = deps.env ?? process.env;
|
|
42295
|
-
return async () => {
|
|
42296
|
-
const isWsl = platform === "linux" && detectWsl(readProcVersion, env);
|
|
42297
|
-
const wslStartPath = isWsl ? wslStartFolderUnc(env) : "";
|
|
42298
|
-
const commands = buildPickerCommands(platform, isWsl, wslStartPath);
|
|
42299
|
-
if (commands.length === 0) return { kind: "error", error: "unsupported_platform" };
|
|
42300
|
-
for (const command2 of commands) {
|
|
42301
|
-
const result = await runPickerCommand(runCommand, command2);
|
|
42302
|
-
if ("kind" in result && result.kind === "unavailable") continue;
|
|
42303
|
-
if ("kind" in result && result.kind === "cancelled") return { kind: "cancelled" };
|
|
42304
|
-
if ("kind" in result && result.kind === "timeout") return { kind: "error", error: "dialog_timeout" };
|
|
42305
|
-
if ("kind" in result) continue;
|
|
42306
|
-
let resolvedPath = result.stdout.trim();
|
|
42307
|
-
if (command2.postProcess === "wslpath") {
|
|
42308
|
-
try {
|
|
42309
|
-
const wslResult = await runCommand("wslpath", ["-u", resolvedPath]);
|
|
42310
|
-
resolvedPath = wslResult.stdout.trim();
|
|
42311
|
-
} catch {
|
|
42312
|
-
return { kind: "error", error: "invalid_folder" };
|
|
42313
|
-
}
|
|
42314
|
-
}
|
|
42315
|
-
try {
|
|
42316
|
-
return { kind: "selected", cwd: validateAbsoluteDirectory(resolvedPath, statSync5) };
|
|
42317
|
-
} catch {
|
|
42318
|
-
return { kind: "error", error: "invalid_folder" };
|
|
42319
|
-
}
|
|
42320
|
-
}
|
|
42321
|
-
return { kind: "error", error: "dialog_unavailable" };
|
|
42322
|
-
};
|
|
42323
|
-
}
|
|
42324
|
-
function defaultReadProcVersion() {
|
|
42325
|
-
try {
|
|
42326
|
-
return fs5__default.readFileSync("/proc/version", "utf8");
|
|
42327
|
-
} catch {
|
|
42328
|
-
return "";
|
|
42329
|
-
}
|
|
42330
|
-
}
|
|
42331
|
-
function detectWsl(readProcVersion, env) {
|
|
42332
|
-
if (env.WSL_INTEROP !== void 0 || env.WSL_DISTRO_NAME !== void 0) return true;
|
|
42333
|
-
return /microsoft|wsl/i.test(readProcVersion());
|
|
42334
|
-
}
|
|
42335
|
-
function buildPickerCommands(platform, isWsl = false, wslStartPath = "") {
|
|
42336
|
-
if (platform === "darwin") {
|
|
42337
|
-
return [{ bin: "osascript", args: ["-e", 'POSIX path of (choose folder with prompt "Choose a Fleet workspace")'] }];
|
|
42338
|
-
}
|
|
42339
|
-
if (platform === "linux") {
|
|
42340
|
-
const commands = [];
|
|
42341
|
-
if (isWsl) {
|
|
42342
|
-
commands.push({ bin: "powershell.exe", args: buildPowerShellPickerArgs(wslStartPath), postProcess: "wslpath" });
|
|
42343
|
-
}
|
|
42344
|
-
commands.push(
|
|
42345
|
-
{ bin: "zenity", args: ["--file-selection", "--directory", "--title=Choose a Fleet workspace"] },
|
|
42346
|
-
{ bin: "kdialog", args: ["--getexistingdirectory", ".", "Choose a Fleet workspace"] }
|
|
42347
|
-
);
|
|
42348
|
-
return commands;
|
|
42349
|
-
}
|
|
42350
|
-
if (platform === "win32") {
|
|
42351
|
-
return [{ bin: "powershell.exe", args: buildPowerShellPickerArgs("") }];
|
|
42352
|
-
}
|
|
42353
|
-
return [];
|
|
42354
|
-
}
|
|
42355
|
-
function buildPowerShellPickerArgs(initialWindowsPath) {
|
|
42356
|
-
const escaped = initialWindowsPath.replace(/'/g, "''");
|
|
42357
|
-
const script = [
|
|
42358
|
-
"[Console]::OutputEncoding=[Text.Encoding]::UTF8",
|
|
42359
|
-
`Add-Type -TypeDefinition '${POWERSHELL_FOLDER_PICKER_CSHARP}'`,
|
|
42360
|
-
`$selection = [FleetPicker.Picker]::Pick('${escaped}')`,
|
|
42361
|
-
"if ([string]::IsNullOrEmpty($selection)) { exit 1 }",
|
|
42362
|
-
"[Console]::Out.Write($selection)"
|
|
42363
|
-
].join("\n");
|
|
42364
|
-
return ["-NoProfile", "-Sta", "-Command", script];
|
|
42365
|
-
}
|
|
42366
|
-
function wslStartFolderUnc(env) {
|
|
42367
|
-
const distro = env.WSL_DISTRO_NAME;
|
|
42368
|
-
if (!distro) return "";
|
|
42369
|
-
const home = env.HOME;
|
|
42370
|
-
if (home && home.startsWith("/") && !home.startsWith("/mnt/")) {
|
|
42371
|
-
return `\\\\wsl.localhost\\${distro}${home.replace(/\//g, "\\")}`;
|
|
42372
|
-
}
|
|
42373
|
-
return `\\\\wsl.localhost\\${distro}`;
|
|
42374
|
-
}
|
|
42375
|
-
async function runPickerCommand(runCommand, command2) {
|
|
42376
|
-
try {
|
|
42377
|
-
return await runCommand(command2.bin, command2.args);
|
|
42378
|
-
} catch (error51) {
|
|
42379
|
-
const err = error51;
|
|
42380
|
-
if (err.code === "ENOENT") return { kind: "unavailable" };
|
|
42381
|
-
if (err.code === "ETIMEDOUT") return { kind: "timeout" };
|
|
42382
|
-
return { kind: "cancelled" };
|
|
42383
|
-
}
|
|
42384
|
-
}
|
|
42385
|
-
async function runNativeCommand(bin, args) {
|
|
42386
|
-
const result = await execFileAsync(bin, [...args], { timeout: DIALOG_TIMEOUT_MS, windowsHide: true });
|
|
42387
|
-
return { stdout: result.stdout, stderr: result.stderr };
|
|
42394
|
+
function isWindowsAmbiguousPath2(value) {
|
|
42395
|
+
if (process.platform !== "win32") return false;
|
|
42396
|
+
return /^[a-zA-Z]:(?![\\/])/.test(value) || /^[\\/](?![\\/])/.test(value);
|
|
42388
42397
|
}
|
|
42389
42398
|
var JAVASCRIPT_ENTRY_EXTENSIONS = /* @__PURE__ */ new Set([".cjs", ".js", ".mjs"]);
|
|
42390
42399
|
var TYPESCRIPT_ENTRY_EXTENSIONS = /* @__PURE__ */ new Set([".cts", ".mts", ".ts", ".tsx"]);
|
|
@@ -42393,23 +42402,10 @@ function buildConsoleHookCommand(entry) {
|
|
|
42393
42402
|
if (entry === void 0) {
|
|
42394
42403
|
throw new Error("Fleet Console session hook command requires the current console entry path");
|
|
42395
42404
|
}
|
|
42396
|
-
|
|
42397
|
-
|
|
42398
|
-
|
|
42399
|
-
|
|
42400
|
-
args: [entry.entryPath, "hook", "subagents-context"]
|
|
42401
|
-
};
|
|
42402
|
-
}
|
|
42403
|
-
if (TYPESCRIPT_ENTRY_EXTENSIONS.has(extension)) {
|
|
42404
|
-
if (!entry.tsxLoaderPath) {
|
|
42405
|
-
throw new Error("Fleet Console session hook command for TypeScript entries requires a tsx loader path");
|
|
42406
|
-
}
|
|
42407
|
-
return {
|
|
42408
|
-
command: entry.execPath,
|
|
42409
|
-
args: ["--import", pathToFileURL(entry.tsxLoaderPath).href, entry.entryPath, "hook", "subagents-context"]
|
|
42410
|
-
};
|
|
42411
|
-
}
|
|
42412
|
-
throw new Error(`Unsupported Fleet Console session hook entry extension: ${extension}`);
|
|
42405
|
+
return buildConsoleCliHookExec(entry, ["hook", "subagents-context"]);
|
|
42406
|
+
}
|
|
42407
|
+
function buildConsoleTurnHookCommand(entry, phase) {
|
|
42408
|
+
return buildConsoleCliHookExec(entry, ["hook", phase === "start" ? "turn-start" : "turn-end"]);
|
|
42413
42409
|
}
|
|
42414
42410
|
function buildConsoleCaptureHookCommand(entry, cliId) {
|
|
42415
42411
|
const extension = path93__default.extname(entry.entryPath);
|
|
@@ -42440,7 +42436,9 @@ function runCodexCommand(command2) {
|
|
|
42440
42436
|
const result = spawnSync(command2.bin, command2.args, {
|
|
42441
42437
|
cwd: command2.cwd,
|
|
42442
42438
|
encoding: "utf8",
|
|
42443
|
-
env: command2.env
|
|
42439
|
+
env: command2.env,
|
|
42440
|
+
// 콘솔 없는 fleet-console 백엔드에서 codex 등록 명령 실행 시 콘솔 창이 깜빡이는 것을 방지한다.
|
|
42441
|
+
windowsHide: true
|
|
42444
42442
|
});
|
|
42445
42443
|
return {
|
|
42446
42444
|
status: result.status,
|
|
@@ -42453,6 +42451,25 @@ function withConsoleMarketplaceLock(target, fn) {
|
|
|
42453
42451
|
mkdirSync(path93__default.dirname(lockDir), { recursive: true });
|
|
42454
42452
|
return withDirectoryLock({ lockDir }, fn);
|
|
42455
42453
|
}
|
|
42454
|
+
function buildConsoleCliHookExec(entry, trailingArgs) {
|
|
42455
|
+
const extension = path93__default.extname(entry.entryPath);
|
|
42456
|
+
if (JAVASCRIPT_ENTRY_EXTENSIONS.has(extension)) {
|
|
42457
|
+
return {
|
|
42458
|
+
command: entry.execPath,
|
|
42459
|
+
args: [entry.entryPath, ...trailingArgs]
|
|
42460
|
+
};
|
|
42461
|
+
}
|
|
42462
|
+
if (TYPESCRIPT_ENTRY_EXTENSIONS.has(extension)) {
|
|
42463
|
+
if (!entry.tsxLoaderPath) {
|
|
42464
|
+
throw new Error("Fleet Console session hook command for TypeScript entries requires a tsx loader path");
|
|
42465
|
+
}
|
|
42466
|
+
return {
|
|
42467
|
+
command: entry.execPath,
|
|
42468
|
+
args: ["--import", pathToFileURL(entry.tsxLoaderPath).href, entry.entryPath, ...trailingArgs]
|
|
42469
|
+
};
|
|
42470
|
+
}
|
|
42471
|
+
throw new Error(`Unsupported Fleet Console session hook entry extension: ${extension}`);
|
|
42472
|
+
}
|
|
42456
42473
|
|
|
42457
42474
|
// src/terminal/launch.ts
|
|
42458
42475
|
var DEFAULT_TERMINAL_CWD_FALLBACK = os22__default.homedir;
|
|
@@ -42461,12 +42478,12 @@ var CONSOLE_ENTRY_PATH = fileURLToPath(import.meta.url);
|
|
|
42461
42478
|
var HOOK_ENTRY_EXTENSIONS = /* @__PURE__ */ new Set([".cjs", ".cts", ".js", ".mjs", ".mts", ".ts", ".tsx"]);
|
|
42462
42479
|
var require2 = createRequire(import.meta.url);
|
|
42463
42480
|
function createDefaultTerminalLaunchResolver(deps = {}) {
|
|
42464
|
-
const baseCwd = deps.cwd ??
|
|
42465
|
-
const env = deps.env ??
|
|
42466
|
-
const execPath = deps.execPath ??
|
|
42481
|
+
const baseCwd = deps.cwd ?? process6.cwd();
|
|
42482
|
+
const env = deps.env ?? process6.env;
|
|
42483
|
+
const execPath = deps.execPath ?? process6.execPath;
|
|
42467
42484
|
const homedir3 = deps.homedir ?? DEFAULT_TERMINAL_CWD_FALLBACK;
|
|
42468
|
-
const platform = deps.platform ??
|
|
42469
|
-
const entryPath = resolveHookEntryPath(deps.entryPath ??
|
|
42485
|
+
const platform = deps.platform ?? process6.platform;
|
|
42486
|
+
const entryPath = resolveHookEntryPath(deps.entryPath ?? process6.argv[1]);
|
|
42470
42487
|
const tsxLoaderPath = deps.tsxLoaderPath ?? resolveOptionalPackage("tsx");
|
|
42471
42488
|
const dataDir = deps.dataDir ?? getFleetDataDir();
|
|
42472
42489
|
const infraServices = deps.infraServices ?? createInfraServices();
|
|
@@ -42527,7 +42544,7 @@ function hasHookEntryExtension(entryPath) {
|
|
|
42527
42544
|
}
|
|
42528
42545
|
function startTerminalShell(launch, size) {
|
|
42529
42546
|
const { spawn: spawnPty } = require2("node-pty");
|
|
42530
|
-
const useConptyDll = resolveUseConptyDll(
|
|
42547
|
+
const useConptyDll = resolveUseConptyDll(process6.platform, process6.env);
|
|
42531
42548
|
return spawnPty(launch.bin, [...launch.args], {
|
|
42532
42549
|
cols: size.cols,
|
|
42533
42550
|
rows: size.rows,
|
|
@@ -42563,6 +42580,8 @@ async function createAgentCliLaunchSpec(options) {
|
|
|
42563
42580
|
dedicatedMcpSession: agentRuntime.dedicatedMcpSession,
|
|
42564
42581
|
enableMetaphor: false,
|
|
42565
42582
|
captureSessionHookExec: buildConsoleCaptureHookCommand(options.hookEntry, profile.id),
|
|
42583
|
+
turnStartHookExec: buildConsoleTurnHookCommand(options.hookEntry, "start"),
|
|
42584
|
+
turnEndHookExec: buildConsoleTurnHookCommand(options.hookEntry, "end"),
|
|
42566
42585
|
hookExec: buildConsoleHookCommand(options.hookEntry),
|
|
42567
42586
|
onCleanup: (cleanup) => cleanupStack.push(cleanup),
|
|
42568
42587
|
replaceSystemPrompt: false,
|
|
@@ -42663,6 +42682,8 @@ var DEFAULT_COLS = 80;
|
|
|
42663
42682
|
var DEFAULT_ROWS = 24;
|
|
42664
42683
|
var DEFAULT_SCROLLBACK_LIMIT = 512;
|
|
42665
42684
|
var WS_OPEN_STATE = 1;
|
|
42685
|
+
var THEATER_SHELL_SESSION_PREFIX = "shell:";
|
|
42686
|
+
var THEATER_SHELL_DETACH_GRACE_MS = 4e3;
|
|
42666
42687
|
function createTerminalSessionManager(deps) {
|
|
42667
42688
|
const startShell = deps.startShell ?? startTerminalShell;
|
|
42668
42689
|
const scrollbackLimit = deps.scrollbackLimit ?? DEFAULT_SCROLLBACK_LIMIT;
|
|
@@ -42673,6 +42694,7 @@ function createTerminalSessionManager(deps) {
|
|
|
42673
42694
|
}
|
|
42674
42695
|
async function attach(socket, context) {
|
|
42675
42696
|
const session = await getOrCreateSession(context);
|
|
42697
|
+
clearGraceTimer(session);
|
|
42676
42698
|
if (session.activeSocket && session.activeSocket !== socket) {
|
|
42677
42699
|
session.activeSocket.close(4e3, "terminal_replaced");
|
|
42678
42700
|
}
|
|
@@ -42752,7 +42774,8 @@ function createTerminalSessionManager(deps) {
|
|
|
42752
42774
|
renameCommand: launch.renameCommand,
|
|
42753
42775
|
activeSocket: null,
|
|
42754
42776
|
cols: DEFAULT_COLS,
|
|
42755
|
-
rows: DEFAULT_ROWS
|
|
42777
|
+
rows: DEFAULT_ROWS,
|
|
42778
|
+
graceTimer: null
|
|
42756
42779
|
};
|
|
42757
42780
|
const dataDisposable = pty.onData((data) => handlePtyData(session, data));
|
|
42758
42781
|
const exitDisposable = pty.onExit(() => removeSession(session));
|
|
@@ -42790,6 +42813,13 @@ function createTerminalSessionManager(deps) {
|
|
|
42790
42813
|
function detachSocket(session, socket) {
|
|
42791
42814
|
if (session.activeSocket !== socket) return;
|
|
42792
42815
|
session.activeSocket = null;
|
|
42816
|
+
if (isTheaterShell(session.id)) {
|
|
42817
|
+
clearGraceTimer(session);
|
|
42818
|
+
session.graceTimer = setTimeout(() => {
|
|
42819
|
+
session.graceTimer = null;
|
|
42820
|
+
if (session.activeSocket === null) removeSession(session);
|
|
42821
|
+
}, THEATER_SHELL_DETACH_GRACE_MS);
|
|
42822
|
+
}
|
|
42793
42823
|
}
|
|
42794
42824
|
function replayScrollback(session, socket) {
|
|
42795
42825
|
for (const chunk of session.scrollback) {
|
|
@@ -42805,6 +42835,7 @@ function createTerminalSessionManager(deps) {
|
|
|
42805
42835
|
}
|
|
42806
42836
|
async function killSession(session, options = {}) {
|
|
42807
42837
|
const killPty = options.killPty ?? true;
|
|
42838
|
+
clearGraceTimer(session);
|
|
42808
42839
|
session.activeSocket?.close(4001, "terminal_closed");
|
|
42809
42840
|
session.activeSocket = null;
|
|
42810
42841
|
for (const disposable of session.disposables) disposable.dispose();
|
|
@@ -42828,6 +42859,14 @@ function killPtyBestEffort(pty) {
|
|
|
42828
42859
|
} catch {
|
|
42829
42860
|
}
|
|
42830
42861
|
}
|
|
42862
|
+
function isTheaterShell(sessionId) {
|
|
42863
|
+
return sessionId.startsWith(THEATER_SHELL_SESSION_PREFIX);
|
|
42864
|
+
}
|
|
42865
|
+
function clearGraceTimer(session) {
|
|
42866
|
+
if (session.graceTimer === null) return;
|
|
42867
|
+
clearTimeout(session.graceTimer);
|
|
42868
|
+
session.graceTimer = null;
|
|
42869
|
+
}
|
|
42831
42870
|
function toBuffer(data) {
|
|
42832
42871
|
if (Buffer.isBuffer(data)) return data;
|
|
42833
42872
|
if (Array.isArray(data)) return Buffer.concat(data);
|
|
@@ -42871,7 +42910,7 @@ function createTerminalTicketRegistry(deps = {}) {
|
|
|
42871
42910
|
}
|
|
42872
42911
|
return { ttlMs, issue: issue3, consume, prune };
|
|
42873
42912
|
}
|
|
42874
|
-
var
|
|
42913
|
+
var execFileAsync = promisify(execFile);
|
|
42875
42914
|
var GIT_STATUS_TIMEOUT_MS = 4e3;
|
|
42876
42915
|
var GIT_STATUS_MAX_BUFFER = 1024 * 1024;
|
|
42877
42916
|
var GIT_HASH_TIMEOUT_MS = 4e3;
|
|
@@ -42880,11 +42919,13 @@ function createWorkspaceChangeScanner() {
|
|
|
42880
42919
|
return {
|
|
42881
42920
|
async snapshot(cwd) {
|
|
42882
42921
|
try {
|
|
42883
|
-
const { stdout } = await
|
|
42922
|
+
const { stdout } = await execFileAsync("git", ["status", "--porcelain=v1", "-z", "--untracked-files=all"], {
|
|
42884
42923
|
cwd,
|
|
42885
42924
|
encoding: "utf8",
|
|
42886
42925
|
maxBuffer: GIT_STATUS_MAX_BUFFER,
|
|
42887
|
-
timeout: GIT_STATUS_TIMEOUT_MS
|
|
42926
|
+
timeout: GIT_STATUS_TIMEOUT_MS,
|
|
42927
|
+
// 콘솔 없는 fleet-console 백엔드에서 git.exe 실행 시 콘솔 창이 깜빡이는 것을 방지한다.
|
|
42928
|
+
windowsHide: true
|
|
42888
42929
|
});
|
|
42889
42930
|
const entries = parseGitStatusPorcelainZ(stdout);
|
|
42890
42931
|
if (!entries) return null;
|
|
@@ -42944,7 +42985,9 @@ function execGitHashObject(cwd, paths) {
|
|
|
42944
42985
|
cwd,
|
|
42945
42986
|
encoding: "utf8",
|
|
42946
42987
|
maxBuffer: GIT_HASH_MAX_BUFFER,
|
|
42947
|
-
timeout: GIT_HASH_TIMEOUT_MS
|
|
42988
|
+
timeout: GIT_HASH_TIMEOUT_MS,
|
|
42989
|
+
// 콘솔 없는 fleet-console 백엔드에서 git.exe 실행 시 콘솔 창이 깜빡이는 것을 방지한다.
|
|
42990
|
+
windowsHide: true
|
|
42948
42991
|
},
|
|
42949
42992
|
(error51, stdout) => {
|
|
42950
42993
|
if (error51) {
|
|
@@ -43125,6 +43168,7 @@ function createConsoleUpdateCheckService(deps = {}) {
|
|
|
43125
43168
|
var DEFAULT_HOST2 = "127.0.0.1";
|
|
43126
43169
|
var DEFAULT_PORT2 = 0;
|
|
43127
43170
|
var SHELL_TERMINAL_SESSION_ID = "shell";
|
|
43171
|
+
var THEATER_SHELL_SESSION_PREFIX2 = "shell:";
|
|
43128
43172
|
var SERVER_TIMEOUT_MS = 30 * 60 * 1e3;
|
|
43129
43173
|
var MAX_BODY_BYTES = 1024 * 1024;
|
|
43130
43174
|
function createConsoleServer(deps = {}) {
|
|
@@ -43169,7 +43213,6 @@ function createConsoleServer(deps = {}) {
|
|
|
43169
43213
|
getPort: () => lockHandle?.payload.port ?? port,
|
|
43170
43214
|
getAdminToken: () => lockHandle?.payload.token ?? null
|
|
43171
43215
|
});
|
|
43172
|
-
const pickTerminalFolder = deps.terminalPickFolder ?? createNativeFolderPicker();
|
|
43173
43216
|
const pendingRuntimeSessions = /* @__PURE__ */ new Map();
|
|
43174
43217
|
const terminalSessions = createTerminalSessionManager({
|
|
43175
43218
|
launch: deps.terminalLaunch ?? createDefaultTerminalLaunchResolver({
|
|
@@ -43251,8 +43294,12 @@ function createConsoleServer(deps = {}) {
|
|
|
43251
43294
|
runAsyncHandler(handleTerminalTicket(req, res), res);
|
|
43252
43295
|
return;
|
|
43253
43296
|
}
|
|
43254
|
-
if (pathname === "/terminal/folders/
|
|
43255
|
-
runAsyncHandler(
|
|
43297
|
+
if (pathname === "/terminal/folders/list") {
|
|
43298
|
+
runAsyncHandler(handleTerminalFoldersList(req, res), res);
|
|
43299
|
+
return;
|
|
43300
|
+
}
|
|
43301
|
+
if (pathname === "/terminal/folders/grants") {
|
|
43302
|
+
runAsyncHandler(handleTerminalFolderGrants(req, res), res);
|
|
43256
43303
|
return;
|
|
43257
43304
|
}
|
|
43258
43305
|
if (pathname === "/terminal/sessions") {
|
|
@@ -43264,6 +43311,11 @@ function createConsoleServer(deps = {}) {
|
|
|
43264
43311
|
runAsyncHandler(handleTerminalSessionResume(req, res, decodeURIComponent(terminalSessionResumeMatch[1] ?? "")), res);
|
|
43265
43312
|
return;
|
|
43266
43313
|
}
|
|
43314
|
+
const terminalSessionTurnMatch = pathname.match(/^\/terminal\/sessions\/([^/]+)\/turn$/);
|
|
43315
|
+
if (terminalSessionTurnMatch) {
|
|
43316
|
+
runAsyncHandler(handleTerminalSessionTurn(req, res, decodeURIComponent(terminalSessionTurnMatch[1] ?? "")), res);
|
|
43317
|
+
return;
|
|
43318
|
+
}
|
|
43267
43319
|
const terminalSessionItemMatch = pathname.match(/^\/terminal\/sessions\/([^/]+)$/);
|
|
43268
43320
|
if (terminalSessionItemMatch) {
|
|
43269
43321
|
runAsyncHandler(handleTerminalSessionItem(req, res, decodeURIComponent(terminalSessionItemMatch[1] ?? "")), res);
|
|
@@ -43330,6 +43382,30 @@ function createConsoleServer(deps = {}) {
|
|
|
43330
43382
|
};
|
|
43331
43383
|
writeJson(res, 200, body);
|
|
43332
43384
|
}
|
|
43385
|
+
async function handleTerminalSessionTurn(req, res, sessionId) {
|
|
43386
|
+
if (req.method !== "POST") {
|
|
43387
|
+
writeJson(res, 405, { error: "Method not allowed" });
|
|
43388
|
+
return;
|
|
43389
|
+
}
|
|
43390
|
+
const token = lockHandle?.payload.token;
|
|
43391
|
+
if (!token || req.headers.authorization !== `Bearer ${token}`) {
|
|
43392
|
+
writeJson(res, 401, { error: "Unauthorized" });
|
|
43393
|
+
return;
|
|
43394
|
+
}
|
|
43395
|
+
const body = await readJsonBody(req);
|
|
43396
|
+
const turnState = body?.phase === "start" ? "running" : body?.phase === "end" ? "ended" : null;
|
|
43397
|
+
if (turnState === null) {
|
|
43398
|
+
writeJson(res, 400, { error: "invalid_phase" });
|
|
43399
|
+
return;
|
|
43400
|
+
}
|
|
43401
|
+
const updated = observability.setTerminalSessionTurnState(sessionId, turnState);
|
|
43402
|
+
if (!updated) {
|
|
43403
|
+
writeJson(res, 404, { error: "terminal_session_not_found" });
|
|
43404
|
+
return;
|
|
43405
|
+
}
|
|
43406
|
+
observability.notifySessionUpdated(updated);
|
|
43407
|
+
writeJson(res, 200, { ok: true });
|
|
43408
|
+
}
|
|
43333
43409
|
async function handleTerminalTicket(req, res) {
|
|
43334
43410
|
if (req.method !== "POST") {
|
|
43335
43411
|
writeJson(res, 405, { error: "Method not allowed" });
|
|
@@ -43342,16 +43418,29 @@ function createConsoleServer(deps = {}) {
|
|
|
43342
43418
|
const body = await readJsonBody(req);
|
|
43343
43419
|
const kind = body?.kind === "shell" ? "shell" : "fleet";
|
|
43344
43420
|
const requestedSessionId = body?.sessionId;
|
|
43421
|
+
const requestedTheaterId = typeof body?.theaterId === "string" ? body.theaterId : void 0;
|
|
43345
43422
|
let sessionId;
|
|
43423
|
+
let cwd;
|
|
43346
43424
|
if (kind === "shell") {
|
|
43347
|
-
|
|
43425
|
+
if (typeof requestedSessionId === "string" && requestedSessionId.startsWith(THEATER_SHELL_SESSION_PREFIX2) && requestedTheaterId) {
|
|
43426
|
+
const theater = theaters.get(requestedTheaterId);
|
|
43427
|
+
if (!theater) {
|
|
43428
|
+
writeJson(res, 404, { error: "theater_not_found" });
|
|
43429
|
+
return;
|
|
43430
|
+
}
|
|
43431
|
+
sessionId = requestedSessionId;
|
|
43432
|
+
cwd = theater.path;
|
|
43433
|
+
} else {
|
|
43434
|
+
sessionId = SHELL_TERMINAL_SESSION_ID;
|
|
43435
|
+
cwd = "";
|
|
43436
|
+
}
|
|
43348
43437
|
} else if (typeof requestedSessionId === "string" && requestedSessionId.length > 0) {
|
|
43349
43438
|
sessionId = requestedSessionId;
|
|
43439
|
+
cwd = observability.getLaunchCwd(sessionId);
|
|
43350
43440
|
} else {
|
|
43351
43441
|
writeJson(res, 400, { error: "terminal_session_not_found" });
|
|
43352
43442
|
return;
|
|
43353
43443
|
}
|
|
43354
|
-
const cwd = kind === "shell" ? "" : observability.getLaunchCwd(sessionId);
|
|
43355
43444
|
if (cwd === null) {
|
|
43356
43445
|
writeJson(res, 404, { error: "terminal_session_not_found" });
|
|
43357
43446
|
return;
|
|
@@ -43366,7 +43455,7 @@ function createConsoleServer(deps = {}) {
|
|
|
43366
43455
|
kind
|
|
43367
43456
|
}));
|
|
43368
43457
|
}
|
|
43369
|
-
async function
|
|
43458
|
+
async function handleTerminalFoldersList(req, res) {
|
|
43370
43459
|
if (req.method !== "POST") {
|
|
43371
43460
|
writeJson(res, 405, { error: "Method not allowed" });
|
|
43372
43461
|
return;
|
|
@@ -43375,16 +43464,41 @@ function createConsoleServer(deps = {}) {
|
|
|
43375
43464
|
writeJson(res, 401, { error: "unauthorized" });
|
|
43376
43465
|
return;
|
|
43377
43466
|
}
|
|
43378
|
-
const
|
|
43379
|
-
if (
|
|
43380
|
-
writeJson(res,
|
|
43467
|
+
const body = await readJsonBody(req);
|
|
43468
|
+
if (!isPlainObject2(body) || body.path !== void 0 && body.path !== null && typeof body.path !== "string") {
|
|
43469
|
+
writeJson(res, 400, { error: "invalid_path" });
|
|
43470
|
+
return;
|
|
43471
|
+
}
|
|
43472
|
+
try {
|
|
43473
|
+
const payload = await listTerminalFolders(body.path === void 0 ? null : body.path);
|
|
43474
|
+
writeJson(res, 200, payload);
|
|
43475
|
+
} catch (error51) {
|
|
43476
|
+
if (error51 instanceof TerminalFolderListError) {
|
|
43477
|
+
writeJson(res, terminalFolderListStatus(error51), { error: error51.code });
|
|
43478
|
+
return;
|
|
43479
|
+
}
|
|
43480
|
+
throw error51;
|
|
43481
|
+
}
|
|
43482
|
+
}
|
|
43483
|
+
async function handleTerminalFolderGrants(req, res) {
|
|
43484
|
+
if (req.method !== "POST") {
|
|
43485
|
+
writeJson(res, 405, { error: "Method not allowed" });
|
|
43486
|
+
return;
|
|
43487
|
+
}
|
|
43488
|
+
if (!isTerminalAuthorized(req)) {
|
|
43489
|
+
writeJson(res, 401, { error: "unauthorized" });
|
|
43381
43490
|
return;
|
|
43382
43491
|
}
|
|
43383
|
-
|
|
43384
|
-
|
|
43492
|
+
const body = await readJsonBody(req);
|
|
43493
|
+
if (!isPlainObject2(body) || typeof body.path !== "string") {
|
|
43494
|
+
writeJson(res, 400, { error: "invalid_folder" });
|
|
43385
43495
|
return;
|
|
43386
43496
|
}
|
|
43387
|
-
|
|
43497
|
+
try {
|
|
43498
|
+
writeJson(res, 200, { folderGrantId: folderGrants.issue(body.path) });
|
|
43499
|
+
} catch {
|
|
43500
|
+
writeJson(res, 400, { error: "invalid_folder" });
|
|
43501
|
+
}
|
|
43388
43502
|
}
|
|
43389
43503
|
async function handleTerminalSessions(req, res) {
|
|
43390
43504
|
if (!isTerminalAuthorized(req)) {
|
|
@@ -43514,19 +43628,20 @@ function createConsoleServer(deps = {}) {
|
|
|
43514
43628
|
writeJson(res, 401, { error: "unauthorized" });
|
|
43515
43629
|
return;
|
|
43516
43630
|
}
|
|
43517
|
-
const
|
|
43518
|
-
if (
|
|
43519
|
-
writeJson(res,
|
|
43631
|
+
const body = await readJsonBody(req);
|
|
43632
|
+
if (!isPlainObject2(body) || typeof body.folderGrantId !== "string") {
|
|
43633
|
+
writeJson(res, 400, { error: "invalid_folder_grant" });
|
|
43520
43634
|
return;
|
|
43521
43635
|
}
|
|
43522
|
-
|
|
43523
|
-
|
|
43636
|
+
const cwd = folderGrants.consume(body.folderGrantId);
|
|
43637
|
+
if (!cwd) {
|
|
43638
|
+
writeJson(res, 400, { error: "invalid_folder_grant" });
|
|
43524
43639
|
return;
|
|
43525
43640
|
}
|
|
43526
|
-
const theater = await theaters.register(
|
|
43641
|
+
const theater = await theaters.register(cwd);
|
|
43527
43642
|
let hasWiki = false;
|
|
43528
43643
|
try {
|
|
43529
|
-
await codex.registerWorkspace(
|
|
43644
|
+
await codex.registerWorkspace(cwd);
|
|
43530
43645
|
hasWiki = true;
|
|
43531
43646
|
} catch (error51) {
|
|
43532
43647
|
if (!(error51 instanceof Error && error51.message === "knowledge_root_missing")) {
|
|
@@ -43546,11 +43661,7 @@ function createConsoleServer(deps = {}) {
|
|
|
43546
43661
|
return;
|
|
43547
43662
|
}
|
|
43548
43663
|
const operations = observability.listDurableOperations().filter((operation) => operation.theaterId === theaterId);
|
|
43549
|
-
|
|
43550
|
-
if (!removed) {
|
|
43551
|
-
writeJson(res, 404, { error: "theater_not_found" });
|
|
43552
|
-
return;
|
|
43553
|
-
}
|
|
43664
|
+
theaters.remove(theaterId);
|
|
43554
43665
|
for (const operation of operations) forgetTerminalSession(operation.sessionId, { persist: false });
|
|
43555
43666
|
persistDurableState();
|
|
43556
43667
|
writeJson(res, 200, { ok: true });
|
|
@@ -43938,6 +44049,14 @@ function readOptionalAgentCliId(value, res) {
|
|
|
43938
44049
|
return false;
|
|
43939
44050
|
}
|
|
43940
44051
|
}
|
|
44052
|
+
function terminalFolderListStatus(error51) {
|
|
44053
|
+
if (error51.code === "forbidden") return 403;
|
|
44054
|
+
if (error51.code === "not_found") return 404;
|
|
44055
|
+
return 400;
|
|
44056
|
+
}
|
|
44057
|
+
function isPlainObject2(value) {
|
|
44058
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
44059
|
+
}
|
|
43941
44060
|
async function readJsonBody(req) {
|
|
43942
44061
|
const chunks = [];
|
|
43943
44062
|
let total = 0;
|
|
@@ -43997,9 +44116,9 @@ function isAllowedTerminalOrigin(req, expectedPort) {
|
|
|
43997
44116
|
return origin === `http://127.0.0.1:${expectedPort}`;
|
|
43998
44117
|
}
|
|
43999
44118
|
var CAPTURE_TEMP_PREFIX = ".capture.";
|
|
44000
|
-
async function runCaptureSessionHook(provider, env =
|
|
44119
|
+
async function runCaptureSessionHook(provider, env = process6.env) {
|
|
44001
44120
|
return captureSession({
|
|
44002
|
-
diagnostics:
|
|
44121
|
+
diagnostics: process6.stderr,
|
|
44003
44122
|
env,
|
|
44004
44123
|
input: await readStdin(),
|
|
44005
44124
|
provider
|
|
@@ -44016,12 +44135,12 @@ function captureSession(options) {
|
|
|
44016
44135
|
}
|
|
44017
44136
|
function captureSessionStrict(options) {
|
|
44018
44137
|
const provider = parseProvider(options.provider);
|
|
44019
|
-
const fleetSessionId = readFleetSessionId(options.env ??
|
|
44138
|
+
const fleetSessionId = readFleetSessionId(options.env ?? process6.env);
|
|
44020
44139
|
const input = parseHookInput(options.input ?? "");
|
|
44021
44140
|
const providerSession = toProviderSession(provider, input, options.now ?? (() => /* @__PURE__ */ new Date()));
|
|
44022
44141
|
const capturesDir = (options.paths ?? createConsoleDataPaths()).capturesDir;
|
|
44023
44142
|
const finalPath = path93__default.join(capturesDir, `${fleetSessionId}.json`);
|
|
44024
|
-
const tempPath = path93__default.join(capturesDir, `${CAPTURE_TEMP_PREFIX}${fleetSessionId}.${
|
|
44143
|
+
const tempPath = path93__default.join(capturesDir, `${CAPTURE_TEMP_PREFIX}${fleetSessionId}.${process6.pid}.${Date.now()}.tmp`);
|
|
44025
44144
|
fs5__default.mkdirSync(capturesDir, { recursive: true, mode: 448 });
|
|
44026
44145
|
fs5__default.writeFileSync(tempPath, `${JSON.stringify(providerSession, null, 2)}
|
|
44027
44146
|
`, { mode: 384 });
|
|
@@ -44061,11 +44180,11 @@ function toProviderSession(provider, input, now) {
|
|
|
44061
44180
|
function readStdin() {
|
|
44062
44181
|
return new Promise((resolve, reject) => {
|
|
44063
44182
|
const chunks = [];
|
|
44064
|
-
|
|
44183
|
+
process6.stdin.on("data", (chunk) => {
|
|
44065
44184
|
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
44066
44185
|
});
|
|
44067
|
-
|
|
44068
|
-
|
|
44186
|
+
process6.stdin.on("error", reject);
|
|
44187
|
+
process6.stdin.on("end", () => resolve(Buffer.concat(chunks).toString("utf8")));
|
|
44069
44188
|
});
|
|
44070
44189
|
}
|
|
44071
44190
|
function createConsoleStalePolicy(deps = {}) {
|
|
@@ -44080,12 +44199,42 @@ function createConsoleStalePolicy(deps = {}) {
|
|
|
44080
44199
|
}
|
|
44081
44200
|
return { isBuildStale };
|
|
44082
44201
|
}
|
|
44202
|
+
var TURN_POST_TIMEOUT_MS = 1500;
|
|
44203
|
+
async function runTurnStateHook(phase, env = process6.env, options = {}) {
|
|
44204
|
+
try {
|
|
44205
|
+
await postTurnState(phase, env, options);
|
|
44206
|
+
} catch {
|
|
44207
|
+
}
|
|
44208
|
+
}
|
|
44209
|
+
async function postTurnState(phase, env, options) {
|
|
44210
|
+
const sessionId = env.FLEET_CONSOLE_SESSION_ID;
|
|
44211
|
+
if (!sessionId) return;
|
|
44212
|
+
const paths = createConsolePaths({ env });
|
|
44213
|
+
const lock = createConsoleLock().readLock(paths.lockFile);
|
|
44214
|
+
if (!lock) return;
|
|
44215
|
+
const fetchImpl = options.fetchImpl ?? fetch;
|
|
44216
|
+
const controller = new AbortController();
|
|
44217
|
+
const timer = setTimeout(() => controller.abort(), options.timeoutMs ?? TURN_POST_TIMEOUT_MS);
|
|
44218
|
+
try {
|
|
44219
|
+
await fetchImpl(`${lock.endpoint}terminal/sessions/${encodeURIComponent(sessionId)}/turn`, {
|
|
44220
|
+
method: "POST",
|
|
44221
|
+
headers: {
|
|
44222
|
+
authorization: `Bearer ${lock.token}`,
|
|
44223
|
+
"content-type": "application/json"
|
|
44224
|
+
},
|
|
44225
|
+
body: JSON.stringify({ phase }),
|
|
44226
|
+
signal: controller.signal
|
|
44227
|
+
});
|
|
44228
|
+
} finally {
|
|
44229
|
+
clearTimeout(timer);
|
|
44230
|
+
}
|
|
44231
|
+
}
|
|
44083
44232
|
|
|
44084
44233
|
// src/cli.ts
|
|
44085
44234
|
var FIXED_HOST = "127.0.0.1";
|
|
44086
44235
|
var HELP_BANNER_INDENT = " ";
|
|
44087
44236
|
var DEFAULT_HELP_RELEASE = "local";
|
|
44088
|
-
var CONSOLE_HOOK_COMMANDS = /* @__PURE__ */ new Set(["capture-session", "subagents-context"]);
|
|
44237
|
+
var CONSOLE_HOOK_COMMANDS = /* @__PURE__ */ new Set(["capture-session", "subagents-context", "turn-start", "turn-end"]);
|
|
44089
44238
|
function parseConsoleCliMode(argv) {
|
|
44090
44239
|
if (argv.length === 0) return "start";
|
|
44091
44240
|
const [first, ...rest] = argv;
|
|
@@ -44116,6 +44265,8 @@ function parseConsoleHookCommand(argv) {
|
|
|
44116
44265
|
throw new Error("Unknown fleet-console hook command");
|
|
44117
44266
|
}
|
|
44118
44267
|
if (commandName === "subagents-context" && rest.length === 0) return { command: "subagents-context" };
|
|
44268
|
+
if (commandName === "turn-start" && rest.length === 0) return { command: "turn-start" };
|
|
44269
|
+
if (commandName === "turn-end" && rest.length === 0) return { command: "turn-end" };
|
|
44119
44270
|
if (commandName === "capture-session" && rest.length === 1 && rest[0]) return { command: "capture-session", provider: rest[0] };
|
|
44120
44271
|
throw new Error("Unknown fleet-console hook command");
|
|
44121
44272
|
}
|
|
@@ -44179,8 +44330,8 @@ function buildWikiHelpText(options = {}) {
|
|
|
44179
44330
|
return colorEnabled ? text : stripAnsi(text);
|
|
44180
44331
|
}
|
|
44181
44332
|
function createConsoleDaemonLifecycle(deps = {}) {
|
|
44182
|
-
const env = deps.env ??
|
|
44183
|
-
const execPath = deps.execPath ??
|
|
44333
|
+
const env = deps.env ?? process6.env;
|
|
44334
|
+
const execPath = deps.execPath ?? process6.execPath;
|
|
44184
44335
|
const serverModulePath = deps.serverModulePath ?? resolveDefaultServerModulePath();
|
|
44185
44336
|
const spawnDetached = deps.spawnDetached ?? ((bin, args, options) => {
|
|
44186
44337
|
spawn(bin, [...args], options).unref();
|
|
@@ -44194,10 +44345,10 @@ function createConsoleDaemonLifecycle(deps = {}) {
|
|
|
44194
44345
|
const server = createConsoleServer();
|
|
44195
44346
|
await server.start(paths);
|
|
44196
44347
|
await new Promise((resolve) => {
|
|
44197
|
-
|
|
44348
|
+
process6.once("SIGTERM", () => {
|
|
44198
44349
|
void server.stop().finally(resolve);
|
|
44199
44350
|
});
|
|
44200
|
-
|
|
44351
|
+
process6.once("SIGINT", () => {
|
|
44201
44352
|
void server.stop().finally(resolve);
|
|
44202
44353
|
});
|
|
44203
44354
|
});
|
|
@@ -44211,14 +44362,14 @@ function createConsoleDaemonLifecycle(deps = {}) {
|
|
|
44211
44362
|
const payload = readTrustedLock();
|
|
44212
44363
|
if (!payload) return;
|
|
44213
44364
|
try {
|
|
44214
|
-
|
|
44365
|
+
process6.kill(payload.pid, "SIGTERM");
|
|
44215
44366
|
} catch (err) {
|
|
44216
44367
|
if (err.code !== "ESRCH") throw err;
|
|
44217
44368
|
}
|
|
44218
44369
|
await sleep(200);
|
|
44219
44370
|
try {
|
|
44220
|
-
|
|
44221
|
-
|
|
44371
|
+
process6.kill(payload.pid, 0);
|
|
44372
|
+
process6.kill(payload.pid, "SIGKILL");
|
|
44222
44373
|
} catch (err) {
|
|
44223
44374
|
if (err.code !== "ESRCH") throw err;
|
|
44224
44375
|
}
|
|
@@ -44325,51 +44476,55 @@ async function runConsoleRestart(deps = {}) {
|
|
|
44325
44476
|
return openFleetConsole({ lifecycle, openBrowser: deps.openBrowser });
|
|
44326
44477
|
}
|
|
44327
44478
|
async function main() {
|
|
44328
|
-
if (
|
|
44479
|
+
if (process6.argv[2] === "serve") {
|
|
44329
44480
|
await createConsoleDaemonLifecycle().runServer();
|
|
44330
44481
|
return;
|
|
44331
44482
|
}
|
|
44332
|
-
if (
|
|
44333
|
-
const hookCommand = parseConsoleHookCommand(
|
|
44483
|
+
if (process6.argv[2] === "hook") {
|
|
44484
|
+
const hookCommand = parseConsoleHookCommand(process6.argv.slice(3));
|
|
44334
44485
|
if (hookCommand.command === "subagents-context") {
|
|
44335
|
-
|
|
44486
|
+
process6.stdout.write(`${runSubagentsContextHook(process6.env)}
|
|
44336
44487
|
`);
|
|
44337
44488
|
return;
|
|
44338
44489
|
}
|
|
44339
|
-
|
|
44490
|
+
if (hookCommand.command === "turn-start" || hookCommand.command === "turn-end") {
|
|
44491
|
+
await runTurnStateHook(hookCommand.command === "turn-start" ? "start" : "end", process6.env);
|
|
44492
|
+
return;
|
|
44493
|
+
}
|
|
44494
|
+
await runCaptureSessionHook(hookCommand.provider, process6.env);
|
|
44340
44495
|
return;
|
|
44341
44496
|
}
|
|
44342
|
-
if (
|
|
44343
|
-
await mainWiki(
|
|
44497
|
+
if (process6.argv[2] === "codex") {
|
|
44498
|
+
await mainWiki(process6.argv.slice(3));
|
|
44344
44499
|
return;
|
|
44345
44500
|
}
|
|
44346
|
-
const mode = parseConsoleCliMode(
|
|
44501
|
+
const mode = parseConsoleCliMode(process6.argv.slice(2));
|
|
44347
44502
|
if (mode === "help") {
|
|
44348
|
-
|
|
44503
|
+
process6.stdout.write(`${buildConsoleHelpText({ env: process6.env, isTTY: process6.stdout.isTTY })}
|
|
44349
44504
|
`);
|
|
44350
44505
|
return;
|
|
44351
44506
|
}
|
|
44352
44507
|
if (mode === "status") {
|
|
44353
|
-
|
|
44508
|
+
process6.stdout.write(`${await runConsoleStatus()}
|
|
44354
44509
|
`);
|
|
44355
44510
|
return;
|
|
44356
44511
|
}
|
|
44357
44512
|
if (mode === "stop") {
|
|
44358
|
-
|
|
44513
|
+
process6.stdout.write(`${await runConsoleStop()}
|
|
44359
44514
|
`);
|
|
44360
44515
|
return;
|
|
44361
44516
|
}
|
|
44362
44517
|
if (mode === "restart") {
|
|
44363
44518
|
await runConsoleRestart();
|
|
44364
|
-
|
|
44519
|
+
process6.stdout.write("Fleet Console restarted.\n");
|
|
44365
44520
|
return;
|
|
44366
44521
|
}
|
|
44367
44522
|
await openFleetConsole();
|
|
44368
|
-
|
|
44523
|
+
process6.stdout.write("Fleet Console opened.\n");
|
|
44369
44524
|
}
|
|
44370
|
-
async function mainWiki(argv =
|
|
44525
|
+
async function mainWiki(argv = process6.argv.slice(2)) {
|
|
44371
44526
|
if (argv.includes("--help") || argv.includes("-h")) {
|
|
44372
|
-
|
|
44527
|
+
process6.stdout.write(`${buildWikiHelpText({ env: process6.env, isTTY: process6.stdout.isTTY })}
|
|
44373
44528
|
`);
|
|
44374
44529
|
return;
|
|
44375
44530
|
}
|
|
@@ -44381,19 +44536,19 @@ async function mainWiki(argv = process5.argv.slice(2)) {
|
|
|
44381
44536
|
if (unsupported.length > 0) {
|
|
44382
44537
|
throw new Error(`Unknown fleet wiki option: ${unsupported[0]}`);
|
|
44383
44538
|
}
|
|
44384
|
-
await openFleetWikiWorkspace({ cwd:
|
|
44539
|
+
await openFleetWikiWorkspace({ cwd: process6.cwd() });
|
|
44385
44540
|
}
|
|
44386
44541
|
function resolveDefaultServerModulePath() {
|
|
44387
44542
|
const builtPath = new URL("../dist/cli.mjs", import.meta.url).pathname;
|
|
44388
44543
|
if (fs5__default.existsSync(builtPath)) return builtPath;
|
|
44389
44544
|
return fileURLToPath(import.meta.url);
|
|
44390
44545
|
}
|
|
44391
|
-
var isDirectRun =
|
|
44546
|
+
var isDirectRun = process6.argv[1] && path93__default.resolve(process6.argv[1]) === fileURLToPath(import.meta.url);
|
|
44392
44547
|
if (isDirectRun) {
|
|
44393
44548
|
await main().catch((error51) => {
|
|
44394
|
-
|
|
44549
|
+
process6.stderr.write(`${error51 instanceof Error ? error51.message : String(error51)}
|
|
44395
44550
|
`);
|
|
44396
|
-
|
|
44551
|
+
process6.exitCode = 1;
|
|
44397
44552
|
});
|
|
44398
44553
|
}
|
|
44399
44554
|
|