@dotobokuri/fleet-console 1.33.0 → 1.35.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/dist/cli.mjs +576 -433
- package/dist/client/assets/{_baseUniq-DGGrBWAb.js → _baseUniq--isZn0gt.js} +1 -1
- package/dist/client/assets/{arc-BNCMUJG_.js → arc-CbzUc80R.js} +1 -1
- package/dist/client/assets/{architectureDiagram-Q4EWVU46-C7qQq1FU.js → architectureDiagram-Q4EWVU46-KMk7A7ht.js} +1 -1
- package/dist/client/assets/{blockDiagram-DXYQGD6D-Cd8j3SNd.js → blockDiagram-DXYQGD6D-BDIXylVL.js} +1 -1
- package/dist/client/assets/{c4Diagram-AHTNJAMY-fFAORcJP.js → c4Diagram-AHTNJAMY-4BtEjWxc.js} +1 -1
- package/dist/client/assets/channel-DNy689Yu.js +1 -0
- package/dist/client/assets/{chunk-4BX2VUAB-peomhKWw.js → chunk-4BX2VUAB-B6P7vZc2.js} +1 -1
- package/dist/client/assets/{chunk-4TB4RGXK-TEb8s6Dl.js → chunk-4TB4RGXK-w5tBo1dz.js} +1 -1
- package/dist/client/assets/{chunk-55IACEB6-11aKxGwZ.js → chunk-55IACEB6-C_Bcd4uB.js} +1 -1
- package/dist/client/assets/{chunk-EDXVE4YY-CPeOY-w0.js → chunk-EDXVE4YY-BikIv-lO.js} +1 -1
- package/dist/client/assets/{chunk-FMBD7UC4-DpbKBDUG.js → chunk-FMBD7UC4-C785J70Z.js} +1 -1
- package/dist/client/assets/{chunk-OYMX7WX6-DQiIenR8.js → chunk-OYMX7WX6-qhvy0Mwx.js} +1 -1
- package/dist/client/assets/{chunk-QZHKN3VN-ByEBhAst.js → chunk-QZHKN3VN-28VsIAWd.js} +1 -1
- package/dist/client/assets/{chunk-YZCP3GAM-Ca8uNdzu.js → chunk-YZCP3GAM-Dj_CFH0t.js} +1 -1
- package/dist/client/assets/classDiagram-6PBFFD2Q-BN9_O5GO.js +1 -0
- package/dist/client/assets/classDiagram-v2-HSJHXN6E-BN9_O5GO.js +1 -0
- package/dist/client/assets/clone-CYXyhbsy.js +1 -0
- package/dist/client/assets/{cose-bilkent-S5V4N54A-B9r4jGi9.js → cose-bilkent-S5V4N54A-CbwRTcWp.js} +1 -1
- package/dist/client/assets/{dagre-KV5264BT-Csnn3Aws.js → dagre-KV5264BT-DmTFlNmc.js} +1 -1
- package/dist/client/assets/{diagram-5BDNPKRD-xgvBmNve.js → diagram-5BDNPKRD-D5filFx0.js} +1 -1
- package/dist/client/assets/{diagram-G4DWMVQ6-eDo2cgdI.js → diagram-G4DWMVQ6-BstKtz5F.js} +1 -1
- package/dist/client/assets/{diagram-MMDJMWI5-C3GDlrcv.js → diagram-MMDJMWI5-BubZFKBf.js} +1 -1
- package/dist/client/assets/{diagram-TYMM5635-BDyVzMHP.js → diagram-TYMM5635-Dkt0qt66.js} +1 -1
- package/dist/client/assets/{erDiagram-SMLLAGMA-YegVvYsw.js → erDiagram-SMLLAGMA-D32vcceA.js} +1 -1
- package/dist/client/assets/{flowDiagram-DWJPFMVM-zcVenDmh.js → flowDiagram-DWJPFMVM-8iX8d0Mm.js} +1 -1
- package/dist/client/assets/{ganttDiagram-T4ZO3ILL-CkMabQtg.js → ganttDiagram-T4ZO3ILL-DVdts0bT.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-UUTBAWPF-CuD1D5LQ.js → gitGraphDiagram-UUTBAWPF-C36cV6di.js} +1 -1
- package/dist/client/assets/{graph-DvVj819O.js → graph-BfCG4izN.js} +1 -1
- package/dist/client/assets/index-0s24Vlsc.css +1 -0
- package/dist/client/assets/index-o0x3lJ2C.js +452 -0
- package/dist/client/assets/{infoDiagram-42DDH7IO-DPoWXM0E.js → infoDiagram-42DDH7IO-7hCUS4JK.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-UXIWVN3A-BBoXoRxo.js → ishikawaDiagram-UXIWVN3A-DYOGN_tm.js} +1 -1
- package/dist/client/assets/{journeyDiagram-VCZTEJTY-B-IoiUw0.js → journeyDiagram-VCZTEJTY-C-RaUFGz.js} +1 -1
- package/dist/client/assets/{kanban-definition-6JOO6SKY-BcjjEa8G.js → kanban-definition-6JOO6SKY-7GR2tX78.js} +1 -1
- package/dist/client/assets/{layout-BjaFRuOv.js → layout-C9u6a9pL.js} +1 -1
- package/dist/client/assets/{linear-DLVG-hZ_.js → linear-CoxISMQN.js} +1 -1
- package/dist/client/assets/{mermaid.core-6fYEjApv.js → mermaid.core-Clx-Pww4.js} +4 -4
- package/dist/client/assets/{min-BfgBrJLR.js → min-B7iH_omx.js} +1 -1
- package/dist/client/assets/{mindmap-definition-QFDTVHPH-BjelYLWH.js → mindmap-definition-QFDTVHPH-BEg4jpMk.js} +1 -1
- package/dist/client/assets/{pieDiagram-DEJITSTG-BznY8oUt.js → pieDiagram-DEJITSTG-Cu-NdmIs.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-34T5L4WZ-jEnKUROj.js → quadrantDiagram-34T5L4WZ-BW_7SRcp.js} +1 -1
- package/dist/client/assets/{requirementDiagram-MS252O5E-BuQqQSjX.js → requirementDiagram-MS252O5E-C_F2SkO4.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-XADWPNL6-B9g8trZW.js → sankeyDiagram-XADWPNL6-B7f43JV1.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-FGHM5R23-V6Zwufo5.js → sequenceDiagram-FGHM5R23-oARdfmhl.js} +1 -1
- package/dist/client/assets/{stateDiagram-FHFEXIEX-8E2cIHyh.js → stateDiagram-FHFEXIEX-VKGucJY7.js} +1 -1
- package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-DfRePizj.js +1 -0
- package/dist/client/assets/{timeline-definition-GMOUNBTQ-DpiM_Ig9.js → timeline-definition-GMOUNBTQ-DsImBBQe.js} +1 -1
- package/dist/client/assets/{vennDiagram-DHZGUBPP-D975VPJg.js → vennDiagram-DHZGUBPP-DdJLtnOA.js} +1 -1
- package/dist/client/assets/{wardley-RL74JXVD-BiM6uI8Z.js → wardley-RL74JXVD-Cn3hq_Uh.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-NUSXRM2D-IoXxaljw.js → wardleyDiagram-NUSXRM2D-VZCV5eGr.js} +1 -1
- package/dist/client/assets/{xychartDiagram-5P7HB3ND-BqNE-iqW.js → xychartDiagram-5P7HB3ND-BglQI2vQ.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/fleet-plugins/file-explorer/routes.mjs +102 -5
- package/dist/fleet-plugins/repository/routes.mjs +110 -6
- package/dist/fleet-plugins/skills/routes.mjs +93 -42
- package/dist/fleet-plugins/terminal/routes.mjs +901 -799
- package/package.json +1 -1
- package/dist/client/assets/channel-BDofRchL.js +0 -1
- package/dist/client/assets/classDiagram-6PBFFD2Q-BrRbVOSf.js +0 -1
- package/dist/client/assets/classDiagram-v2-HSJHXN6E-BrRbVOSf.js +0 -1
- package/dist/client/assets/clone-CEWs7Jhj.js +0 -1
- package/dist/client/assets/index-DeA0aGZd.css +0 -1
- package/dist/client/assets/index-Dk_jqw8o.js +0 -451
- package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-0HROefWC.js +0 -1
package/dist/cli.mjs
CHANGED
|
@@ -903,16 +903,22 @@ function sanitizeGlobalOptionsData(value) {
|
|
|
903
903
|
return { data: createEmptyGlobalOptionsData(), changed: true };
|
|
904
904
|
}
|
|
905
905
|
const kimiModel = sanitizeKimiModel(value.kimiModel);
|
|
906
|
+
const agentIdleDormantMinutes = sanitizeAgentIdleDormantMinutes(value.agentIdleDormantMinutes);
|
|
906
907
|
const data = {
|
|
907
908
|
version: GLOBAL_OPTIONS_VERSION,
|
|
908
909
|
...typeof value.enableMetaphor === "boolean" ? { enableMetaphor: value.enableMetaphor } : {},
|
|
909
|
-
...
|
|
910
|
-
...
|
|
910
|
+
...kimiModel ? { kimiModel } : {},
|
|
911
|
+
...agentIdleDormantMinutes !== void 0 ? { agentIdleDormantMinutes } : {}
|
|
911
912
|
};
|
|
912
|
-
const allowedKeys = /* @__PURE__ */ new Set(["version", "enableMetaphor", "
|
|
913
|
-
const changed = Object.keys(value).some((key) => !allowedKeys.has(key)) || "enableMetaphor" in value && typeof value.enableMetaphor !== "boolean" || "
|
|
913
|
+
const allowedKeys = /* @__PURE__ */ new Set(["version", "enableMetaphor", "kimiModel", "agentIdleDormantMinutes"]);
|
|
914
|
+
const changed = Object.keys(value).some((key) => !allowedKeys.has(key)) || "enableMetaphor" in value && typeof value.enableMetaphor !== "boolean" || "kimiModel" in value && kimiModel === void 0 || "agentIdleDormantMinutes" in value && agentIdleDormantMinutes === void 0;
|
|
914
915
|
return { data, changed };
|
|
915
916
|
}
|
|
917
|
+
function sanitizeAgentIdleDormantMinutes(value) {
|
|
918
|
+
if (value === null) return null;
|
|
919
|
+
if (typeof value === "number" && Number.isFinite(value) && Number.isInteger(value) && value > 0) return value;
|
|
920
|
+
return void 0;
|
|
921
|
+
}
|
|
916
922
|
function sanitizeKimiModel(value) {
|
|
917
923
|
if (!isRecord(value)) {
|
|
918
924
|
return void 0;
|
|
@@ -12209,6 +12215,8 @@ var SETTINGS_LOCK_OWNER_FILE_NAME = "owner.json";
|
|
|
12209
12215
|
var SETTINGS_TEMP_PREFIX = ".settings.";
|
|
12210
12216
|
var MIN_CONSOLE_STATIC_PORT = 1024;
|
|
12211
12217
|
var MAX_CONSOLE_STATIC_PORT = 65535;
|
|
12218
|
+
var MAX_SEEN_FEATURE_TOURS = 64;
|
|
12219
|
+
var MAX_FEATURE_TOUR_KEY_LENGTH = 64;
|
|
12212
12220
|
function createConsoleSettingsStore(deps = {}) {
|
|
12213
12221
|
const paths = deps.paths ?? createConsoleDataPaths();
|
|
12214
12222
|
const createStore = deps.createStore ?? createDurableJsonStore;
|
|
@@ -12248,6 +12256,16 @@ function sanitizeUiFontSettings(value) {
|
|
|
12248
12256
|
}
|
|
12249
12257
|
return void 0;
|
|
12250
12258
|
}
|
|
12259
|
+
function sanitizeSeenFeatureTours(value) {
|
|
12260
|
+
if (!Array.isArray(value)) return void 0;
|
|
12261
|
+
const seen = /* @__PURE__ */ new Set();
|
|
12262
|
+
for (const item of value) {
|
|
12263
|
+
if (typeof item !== "string" || item.length > MAX_FEATURE_TOUR_KEY_LENGTH) continue;
|
|
12264
|
+
seen.add(item);
|
|
12265
|
+
if (seen.size === MAX_SEEN_FEATURE_TOURS) break;
|
|
12266
|
+
}
|
|
12267
|
+
return [...seen];
|
|
12268
|
+
}
|
|
12251
12269
|
function isUiFontSettings(value) {
|
|
12252
12270
|
if (!isRecord2(value) || !isValidUiFontSize(value.size)) return false;
|
|
12253
12271
|
if (value.source === "builtin") return isConsoleUiFontId(value.id);
|
|
@@ -12259,6 +12277,7 @@ function readConsoleGeneralSettings(value) {
|
|
|
12259
12277
|
const consoleStaticPort = isValidConsoleStaticPort(value.consoleStaticPort) ? value.consoleStaticPort : void 0;
|
|
12260
12278
|
const language = value.language === "auto" || value.language === "en" || value.language === "ko" ? value.language : void 0;
|
|
12261
12279
|
const reducePanelMotion = typeof value.reducePanelMotion === "boolean" ? value.reducePanelMotion : void 0;
|
|
12280
|
+
const seenFeatureTours = sanitizeSeenFeatureTours(value.seenFeatureTours);
|
|
12262
12281
|
const theme = value.theme === "instrument" || value.theme === "maritime" || value.theme === "carbon" ? value.theme : void 0;
|
|
12263
12282
|
const uiFont = sanitizeUiFontSettings(value.uiFont);
|
|
12264
12283
|
return {
|
|
@@ -12266,6 +12285,7 @@ function readConsoleGeneralSettings(value) {
|
|
|
12266
12285
|
...consoleStaticPort !== void 0 ? { consoleStaticPort } : {},
|
|
12267
12286
|
...language !== void 0 ? { language } : {},
|
|
12268
12287
|
...reducePanelMotion !== void 0 ? { reducePanelMotion } : {},
|
|
12288
|
+
...seenFeatureTours !== void 0 ? { seenFeatureTours } : {},
|
|
12269
12289
|
...theme !== void 0 ? { theme } : {},
|
|
12270
12290
|
...uiFont !== void 0 ? { uiFont } : {}
|
|
12271
12291
|
};
|
|
@@ -12366,6 +12386,10 @@ async function mutateGlobalSettings(req, res, deps) {
|
|
|
12366
12386
|
deps.writeJson(res, 400, { error: "invalid_reduce_panel_motion" });
|
|
12367
12387
|
return;
|
|
12368
12388
|
}
|
|
12389
|
+
if (body2.seenFeatureTours !== void 0 && !isSeenFeatureToursInput(body2.seenFeatureTours)) {
|
|
12390
|
+
deps.writeJson(res, 400, { error: "invalid_seen_feature_tours" });
|
|
12391
|
+
return;
|
|
12392
|
+
}
|
|
12369
12393
|
if (body2.theme !== void 0 && body2.theme !== "instrument" && body2.theme !== "maritime" && body2.theme !== "carbon") {
|
|
12370
12394
|
deps.writeJson(res, 400, { error: "invalid_theme" });
|
|
12371
12395
|
return;
|
|
@@ -12384,6 +12408,7 @@ async function mutateGlobalSettings(req, res, deps) {
|
|
|
12384
12408
|
...isValidConsoleStaticPort2(body2.consoleStaticPort) ? { consoleStaticPort: body2.consoleStaticPort } : {},
|
|
12385
12409
|
...body2.language === "auto" || body2.language === "en" || body2.language === "ko" ? { language: body2.language } : {},
|
|
12386
12410
|
...typeof body2.reducePanelMotion === "boolean" ? { reducePanelMotion: body2.reducePanelMotion } : {},
|
|
12411
|
+
...body2.seenFeatureTours !== void 0 ? { seenFeatureTours: sanitizeSeenFeatureTours(body2.seenFeatureTours) ?? [] } : {},
|
|
12387
12412
|
...theme !== void 0 ? { theme } : {},
|
|
12388
12413
|
...isUiFontSettings(body2.uiFont) ? { uiFont: body2.uiFont } : {}
|
|
12389
12414
|
},
|
|
@@ -12400,6 +12425,7 @@ function toGlobalSettingsState(data) {
|
|
|
12400
12425
|
consoleStaticPort: general.consoleStaticPort ?? null,
|
|
12401
12426
|
language: general.language ?? "auto",
|
|
12402
12427
|
reducePanelMotion: general.reducePanelMotion ?? false,
|
|
12428
|
+
seenFeatureTours: general.seenFeatureTours ?? [],
|
|
12403
12429
|
theme: general.theme ?? "instrument",
|
|
12404
12430
|
uiFont: general.uiFont ?? DEFAULT_UI_FONT_SETTINGS
|
|
12405
12431
|
};
|
|
@@ -12414,6 +12440,9 @@ function isValidConsoleStaticPort2(value) {
|
|
|
12414
12440
|
function isUiFontSettingsOrUndefined(value) {
|
|
12415
12441
|
return value === void 0 || isUiFontSettings(value);
|
|
12416
12442
|
}
|
|
12443
|
+
function isSeenFeatureToursInput(value) {
|
|
12444
|
+
return Array.isArray(value) && value.length <= 64 && value.every((item) => typeof item === "string" && item.length <= 64);
|
|
12445
|
+
}
|
|
12417
12446
|
|
|
12418
12447
|
// core/host/plugin-settings-routes.ts
|
|
12419
12448
|
var PLUGIN_SETTINGS_PREFIX = "/api/v1/settings/plugins/";
|
|
@@ -31774,35 +31803,23 @@ var AcpConnection = class extends BaseConnection {
|
|
|
31774
31803
|
}
|
|
31775
31804
|
case "tool_call": {
|
|
31776
31805
|
const { sessionUpdate: _tc, ...toolCallData } = update;
|
|
31777
|
-
const rawTcTitle = toolCallData.title ?? "";
|
|
31778
|
-
const cleanTcTitle = rawTcTitle.replace(/\s*\(\s*[\d.,\s-]*\b(?:NaN|undefined)\b[\d.,\s-]*\)/g, "");
|
|
31779
|
-
if (cleanTcTitle !== rawTcTitle) {
|
|
31780
|
-
console.debug("[AcpConnection] sanitized tool_call payload", { rawTitle: rawTcTitle, cleanTitle: cleanTcTitle });
|
|
31781
|
-
}
|
|
31782
|
-
const titleTcOverride = "title" in toolCallData ? { title: cleanTcTitle } : {};
|
|
31783
31806
|
this.emit(
|
|
31784
31807
|
"toolCall",
|
|
31785
|
-
|
|
31808
|
+
toolCallData.title ?? "",
|
|
31786
31809
|
toolCallData.status ?? "",
|
|
31787
31810
|
sessionId,
|
|
31788
|
-
|
|
31811
|
+
toolCallData
|
|
31789
31812
|
);
|
|
31790
31813
|
break;
|
|
31791
31814
|
}
|
|
31792
31815
|
case "tool_call_update": {
|
|
31793
31816
|
const { sessionUpdate: _tcu, ...toolCallUpdateData } = update;
|
|
31794
|
-
const rawTitle = toolCallUpdateData.title ?? "";
|
|
31795
|
-
const cleanTitle = rawTitle.replace(/\s*\(\s*[\d.,\s-]*\b(?:NaN|undefined)\b[\d.,\s-]*\)/g, "");
|
|
31796
|
-
if (cleanTitle !== rawTitle) {
|
|
31797
|
-
console.debug("[AcpConnection] sanitized tool_call_update payload", { rawTitle, cleanTitle });
|
|
31798
|
-
}
|
|
31799
|
-
const titleOverride = "title" in toolCallUpdateData ? { title: cleanTitle } : {};
|
|
31800
31817
|
this.emit(
|
|
31801
31818
|
"toolCallUpdate",
|
|
31802
|
-
|
|
31819
|
+
toolCallUpdateData.title ?? "",
|
|
31803
31820
|
toolCallUpdateData.status ?? "",
|
|
31804
31821
|
sessionId,
|
|
31805
|
-
|
|
31822
|
+
toolCallUpdateData
|
|
31806
31823
|
);
|
|
31807
31824
|
break;
|
|
31808
31825
|
}
|
|
@@ -31967,7 +31984,7 @@ function inferBinName(packageName) {
|
|
|
31967
31984
|
// ../../packages/core-unified-agent/models.json
|
|
31968
31985
|
var models_default = {
|
|
31969
31986
|
version: 1,
|
|
31970
|
-
updatedAt: "2026-07-
|
|
31987
|
+
updatedAt: "2026-07-25T00:00:00Z",
|
|
31971
31988
|
providers: {
|
|
31972
31989
|
claude: {
|
|
31973
31990
|
name: "Claude Code",
|
|
@@ -32003,11 +32020,13 @@ var models_default = {
|
|
|
32003
32020
|
defaultModel: "gpt-5.6-sol",
|
|
32004
32021
|
models: [
|
|
32005
32022
|
{ modelId: "gpt-5.6-sol", name: "GPT-5.6-Sol", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max", "ultra"], default: "low" } },
|
|
32023
|
+
{ modelId: "gpt-5.6-sol-fast", name: "GPT-5.6-Sol Fast", providerModelId: "gpt-5.6-sol", serviceTier: "priority", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max", "ultra"], default: "low" } },
|
|
32006
32024
|
{ modelId: "gpt-5.6-terra", name: "GPT-5.6-Terra", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max", "ultra"], default: "medium" } },
|
|
32025
|
+
{ modelId: "gpt-5.6-terra-fast", name: "GPT-5.6-Terra Fast", providerModelId: "gpt-5.6-terra", serviceTier: "priority", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max", "ultra"], default: "medium" } },
|
|
32007
32026
|
{ modelId: "gpt-5.6-luna", name: "GPT-5.6-Luna", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max"], default: "medium" } },
|
|
32027
|
+
{ modelId: "gpt-5.6-luna-fast", name: "GPT-5.6-Luna Fast", providerModelId: "gpt-5.6-luna", serviceTier: "priority", effort: { supported: true, levels: ["low", "medium", "high", "xhigh", "max"], default: "medium" } },
|
|
32008
32028
|
{ modelId: "gpt-5.5", name: "GPT-5.5", effort: { supported: true, levels: ["low", "medium", "high", "xhigh"], default: "high" } },
|
|
32009
|
-
{ modelId: "gpt-5.
|
|
32010
|
-
{ modelId: "gpt-5.4-mini", name: "GPT-5.4 Mini", effort: { supported: true, levels: ["low", "medium", "high", "xhigh"], default: "high" } }
|
|
32029
|
+
{ modelId: "gpt-5.5-fast", name: "GPT-5.5 Fast", providerModelId: "gpt-5.5", serviceTier: "priority", effort: { supported: true, levels: ["low", "medium", "high", "xhigh"], default: "high" } }
|
|
32011
32030
|
]
|
|
32012
32031
|
},
|
|
32013
32032
|
"opencode-go": {
|
|
@@ -32093,6 +32112,10 @@ var ModelEntrySchema = external_exports.object({
|
|
|
32093
32112
|
description: external_exports.string().optional(),
|
|
32094
32113
|
/** spawn 시 실제 CLI 모델 ID를 조립해야 하는 경우의 템플릿 */
|
|
32095
32114
|
spawnModelTemplate: external_exports.string().optional(),
|
|
32115
|
+
/** 카탈로그 ID와 실제 provider 모델 ID가 다른 경우의 원본 모델 ID */
|
|
32116
|
+
providerModelId: external_exports.string().optional(),
|
|
32117
|
+
/** provider가 모델과 별도로 받는 서비스 티어 */
|
|
32118
|
+
serviceTier: external_exports.string().optional(),
|
|
32096
32119
|
/** 모델의 컨텍스트 윈도우 크기 (토큰) */
|
|
32097
32120
|
contextWindow: external_exports.number().int().positive().optional(),
|
|
32098
32121
|
/** 모델별 effort 설정 */
|
|
@@ -32115,6 +32138,14 @@ var ModelEntrySchema = external_exports.object({
|
|
|
32115
32138
|
path: ["spawnModelTemplate"]
|
|
32116
32139
|
});
|
|
32117
32140
|
}
|
|
32141
|
+
if (ctx.value.serviceTier && !ctx.value.providerModelId) {
|
|
32142
|
+
ctx.issues.push({
|
|
32143
|
+
code: "custom",
|
|
32144
|
+
input: ctx.value.serviceTier,
|
|
32145
|
+
message: "serviceTier\uB97C \uC9C0\uC815\uD55C \uBAA8\uB378\uC740 providerModelId\uB3C4 \uC9C0\uC815\uD574\uC57C \uD569\uB2C8\uB2E4",
|
|
32146
|
+
path: ["serviceTier"]
|
|
32147
|
+
});
|
|
32148
|
+
}
|
|
32118
32149
|
});
|
|
32119
32150
|
var ModelsMappingSchema = external_exports.record(external_exports.string(), external_exports.string());
|
|
32120
32151
|
var ProviderSchema = external_exports.object({
|
|
@@ -32264,8 +32295,6 @@ var CLI_BACKENDS = {
|
|
|
32264
32295
|
cliCommand: "codex",
|
|
32265
32296
|
protocol: "codex-app-server",
|
|
32266
32297
|
authRequired: true,
|
|
32267
|
-
npxPackage: "@agentclientprotocol/codex-acp@1.1.2",
|
|
32268
|
-
acpArgs: [],
|
|
32269
32298
|
appServerArgs: ["app-server", "--listen", "stdio://"],
|
|
32270
32299
|
modes: [
|
|
32271
32300
|
{ id: "default", label: "Plan" },
|
|
@@ -32275,7 +32304,7 @@ var CLI_BACKENDS = {
|
|
|
32275
32304
|
supportsSessionClose: true,
|
|
32276
32305
|
supportsSessionLoad: true,
|
|
32277
32306
|
requiresModelAtSpawn: false,
|
|
32278
|
-
usesNpxBridge:
|
|
32307
|
+
usesNpxBridge: false,
|
|
32279
32308
|
defaultMaxTokens: 1e5
|
|
32280
32309
|
},
|
|
32281
32310
|
"opencode-go": {
|
|
@@ -32366,22 +32395,6 @@ function getYoloModeId(cli) {
|
|
|
32366
32395
|
function getAllBackendConfigs() {
|
|
32367
32396
|
return Object.values(CLI_BACKENDS);
|
|
32368
32397
|
}
|
|
32369
|
-
function buildCodexConfigEnv(configOverrides, baseConfigJson) {
|
|
32370
|
-
const map2 = parseBaseConfigMap(baseConfigJson);
|
|
32371
|
-
for (const override of configOverrides ?? []) {
|
|
32372
|
-
const eqIndex = override.indexOf("=");
|
|
32373
|
-
if (eqIndex < 0) {
|
|
32374
|
-
continue;
|
|
32375
|
-
}
|
|
32376
|
-
const key = override.slice(0, eqIndex);
|
|
32377
|
-
const rawValue = override.slice(eqIndex + 1);
|
|
32378
|
-
assignNestedKey(map2, key, parseOverrideValue(rawValue));
|
|
32379
|
-
}
|
|
32380
|
-
if (Object.keys(map2).length === 0) {
|
|
32381
|
-
return void 0;
|
|
32382
|
-
}
|
|
32383
|
-
return JSON.stringify(map2);
|
|
32384
|
-
}
|
|
32385
32398
|
function buildConfigOverrideArgs(overrides) {
|
|
32386
32399
|
return overrides.flatMap((override) => ["-c", override]);
|
|
32387
32400
|
}
|
|
@@ -32408,45 +32421,6 @@ function mcpServerConfigsToAcp(servers) {
|
|
|
32408
32421
|
headers: server.headers ?? []
|
|
32409
32422
|
}));
|
|
32410
32423
|
}
|
|
32411
|
-
function parseBaseConfigMap(baseConfigJson) {
|
|
32412
|
-
if (!baseConfigJson) {
|
|
32413
|
-
return {};
|
|
32414
|
-
}
|
|
32415
|
-
try {
|
|
32416
|
-
const parsed = JSON.parse(baseConfigJson);
|
|
32417
|
-
if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
|
|
32418
|
-
return parsed;
|
|
32419
|
-
}
|
|
32420
|
-
} catch {
|
|
32421
|
-
}
|
|
32422
|
-
return {};
|
|
32423
|
-
}
|
|
32424
|
-
function parseOverrideValue(raw) {
|
|
32425
|
-
try {
|
|
32426
|
-
return JSON.parse(raw);
|
|
32427
|
-
} catch {
|
|
32428
|
-
if (raw.length >= 2 && raw.startsWith('"') && raw.endsWith('"')) {
|
|
32429
|
-
return raw.slice(1, -1);
|
|
32430
|
-
}
|
|
32431
|
-
return raw;
|
|
32432
|
-
}
|
|
32433
|
-
}
|
|
32434
|
-
function assignNestedKey(target, dottedKey, value) {
|
|
32435
|
-
const segments = dottedKey.split(".");
|
|
32436
|
-
let cursor = target;
|
|
32437
|
-
for (let i = 0; i < segments.length - 1; i += 1) {
|
|
32438
|
-
const segment = segments[i];
|
|
32439
|
-
const existing = cursor[segment];
|
|
32440
|
-
if (typeof existing === "object" && existing !== null && !Array.isArray(existing)) {
|
|
32441
|
-
cursor = existing;
|
|
32442
|
-
} else {
|
|
32443
|
-
const nested = {};
|
|
32444
|
-
cursor[segment] = nested;
|
|
32445
|
-
cursor = nested;
|
|
32446
|
-
}
|
|
32447
|
-
}
|
|
32448
|
-
cursor[segments[segments.length - 1]] = value;
|
|
32449
|
-
}
|
|
32450
32424
|
|
|
32451
32425
|
// ../../packages/core-unified-agent/src/detector/CliDetector.ts
|
|
32452
32426
|
var CLI_DETECT_LIST = Object.entries(CLI_BACKENDS).map(([id, backend]) => ({
|
|
@@ -33002,6 +32976,7 @@ var CODEX_METHODS = {
|
|
|
33002
32976
|
THREAD_RESUME: "thread/resume",
|
|
33003
32977
|
THREAD_READ: "thread/read",
|
|
33004
32978
|
THREAD_ARCHIVE: "thread/archive",
|
|
32979
|
+
THREAD_UNARCHIVE: "thread/unarchive",
|
|
33005
32980
|
TURN_START: "turn/start",
|
|
33006
32981
|
TURN_INTERRUPT: "turn/interrupt",
|
|
33007
32982
|
TURN_STEER: "turn/steer"
|
|
@@ -33030,6 +33005,7 @@ var CODEX_MCP_READY_STATUS = "ready";
|
|
|
33030
33005
|
var CODEX_MCP_FAILED_STATUSES = /* @__PURE__ */ new Set(["failed", "error"]);
|
|
33031
33006
|
var DEFAULT_MCP_STARTUP_TIMEOUT = 6e4;
|
|
33032
33007
|
var STDERR_TAIL_LIMIT = 20;
|
|
33008
|
+
var SESSION_TEARDOWN_TIMEOUT_MS = 5e3;
|
|
33033
33009
|
var CodexAppServerConnection = class extends BaseConnection {
|
|
33034
33010
|
clientInfo;
|
|
33035
33011
|
autoApprove;
|
|
@@ -33042,6 +33018,7 @@ var CodexAppServerConnection = class extends BaseConnection {
|
|
|
33042
33018
|
pendingMcpReadyWaiters = /* @__PURE__ */ new Set();
|
|
33043
33019
|
stdoutBuffer = "";
|
|
33044
33020
|
pendingModel = null;
|
|
33021
|
+
pendingServiceTier = void 0;
|
|
33045
33022
|
pendingEffort = null;
|
|
33046
33023
|
codexHome = null;
|
|
33047
33024
|
isDisconnecting = false;
|
|
@@ -33066,6 +33043,9 @@ var CodexAppServerConnection = class extends BaseConnection {
|
|
|
33066
33043
|
setPendingModel(model) {
|
|
33067
33044
|
this.pendingModel = model;
|
|
33068
33045
|
}
|
|
33046
|
+
setPendingServiceTier(serviceTier) {
|
|
33047
|
+
this.pendingServiceTier = serviceTier;
|
|
33048
|
+
}
|
|
33069
33049
|
setPendingEffort(effort) {
|
|
33070
33050
|
this.pendingEffort = effort;
|
|
33071
33051
|
}
|
|
@@ -33108,6 +33088,7 @@ var CodexAppServerConnection = class extends BaseConnection {
|
|
|
33108
33088
|
cwd: options?.cwd ?? this.cwd,
|
|
33109
33089
|
developerInstructions: options?.developerInstructions ?? null,
|
|
33110
33090
|
model: options?.model ?? null,
|
|
33091
|
+
serviceTier: options?.serviceTier ?? null,
|
|
33111
33092
|
approvalPolicy: options?.approvalPolicy ?? null,
|
|
33112
33093
|
sandbox: options?.sandbox ?? null,
|
|
33113
33094
|
config: options?.config ?? null
|
|
@@ -33118,10 +33099,11 @@ var CodexAppServerConnection = class extends BaseConnection {
|
|
|
33118
33099
|
this.setState("ready");
|
|
33119
33100
|
return response;
|
|
33120
33101
|
} catch (error51) {
|
|
33102
|
+
const diagnosticError = this.withStderrDiagnostics(error51, "Codex initialize");
|
|
33121
33103
|
this.setState("error");
|
|
33122
33104
|
this.isDisconnecting = true;
|
|
33123
33105
|
await this.disconnect();
|
|
33124
|
-
throw
|
|
33106
|
+
throw diagnosticError;
|
|
33125
33107
|
}
|
|
33126
33108
|
}
|
|
33127
33109
|
async loadSession(threadId, options) {
|
|
@@ -33129,11 +33111,37 @@ var CodexAppServerConnection = class extends BaseConnection {
|
|
|
33129
33111
|
try {
|
|
33130
33112
|
response = await this.sendThreadResumeRequest(threadId, options);
|
|
33131
33113
|
} catch (error51) {
|
|
33132
|
-
|
|
33133
|
-
|
|
33134
|
-
|
|
33114
|
+
if (isArchivedThreadError(error51, threadId)) {
|
|
33115
|
+
try {
|
|
33116
|
+
await this.sendRequest(
|
|
33117
|
+
CODEX_METHODS.THREAD_UNARCHIVE,
|
|
33118
|
+
{ threadId }
|
|
33119
|
+
);
|
|
33120
|
+
} catch (unarchiveError) {
|
|
33121
|
+
const message = unarchiveError instanceof Error ? unarchiveError.message : String(unarchiveError);
|
|
33122
|
+
throw new Error(
|
|
33123
|
+
`thread/unarchive\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4(\uC6D0\uC778: archived \uC0C1\uD0DC\uB85C resume \uAC70\uBD80\uB428): ${message}`,
|
|
33124
|
+
{ cause: unarchiveError }
|
|
33125
|
+
);
|
|
33126
|
+
}
|
|
33127
|
+
try {
|
|
33128
|
+
response = await this.sendThreadResumeRequest(threadId, options);
|
|
33129
|
+
} catch (resumeError) {
|
|
33130
|
+
await this.sendRequest(
|
|
33131
|
+
CODEX_METHODS.THREAD_ARCHIVE,
|
|
33132
|
+
{ threadId },
|
|
33133
|
+
SESSION_TEARDOWN_TIMEOUT_MS
|
|
33134
|
+
).catch(() => {
|
|
33135
|
+
});
|
|
33136
|
+
throw resumeError;
|
|
33137
|
+
}
|
|
33138
|
+
} else {
|
|
33139
|
+
const rolloutPath = this.findRolloutPathForThreadId(threadId);
|
|
33140
|
+
if (!rolloutPath || !isMissingRolloutError(error51, threadId)) {
|
|
33141
|
+
throw error51;
|
|
33142
|
+
}
|
|
33143
|
+
response = await this.sendThreadResumeRequest(threadId, options, rolloutPath);
|
|
33135
33144
|
}
|
|
33136
|
-
response = await this.sendThreadResumeRequest(threadId, options, rolloutPath);
|
|
33137
33145
|
}
|
|
33138
33146
|
this.threadId = response.thread.id;
|
|
33139
33147
|
this.turnId = null;
|
|
@@ -33195,16 +33203,19 @@ var CodexAppServerConnection = class extends BaseConnection {
|
|
|
33195
33203
|
this.on("exit", onExit);
|
|
33196
33204
|
});
|
|
33197
33205
|
try {
|
|
33206
|
+
const serviceTier = options?.serviceTier !== void 0 ? options.serviceTier : this.pendingServiceTier;
|
|
33198
33207
|
const response = await this.sendRequest(
|
|
33199
33208
|
CODEX_METHODS.TURN_START,
|
|
33200
33209
|
{
|
|
33201
33210
|
threadId: sessionId,
|
|
33202
33211
|
input,
|
|
33203
33212
|
model: options?.model ?? this.pendingModel ?? null,
|
|
33213
|
+
...serviceTier !== void 0 ? { serviceTier } : {},
|
|
33204
33214
|
effort: options?.effort ?? this.pendingEffort ?? null
|
|
33205
33215
|
}
|
|
33206
33216
|
);
|
|
33207
33217
|
this.pendingModel = null;
|
|
33218
|
+
this.pendingServiceTier = void 0;
|
|
33208
33219
|
this.pendingEffort = null;
|
|
33209
33220
|
this.turnId = response.turn.id;
|
|
33210
33221
|
await turnCompleted;
|
|
@@ -33231,14 +33242,16 @@ var CodexAppServerConnection = class extends BaseConnection {
|
|
|
33231
33242
|
if (threadId && activeTurnId) {
|
|
33232
33243
|
await this.sendRequest(
|
|
33233
33244
|
CODEX_METHODS.TURN_INTERRUPT,
|
|
33234
|
-
{ threadId, turnId: activeTurnId }
|
|
33245
|
+
{ threadId, turnId: activeTurnId },
|
|
33246
|
+
SESSION_TEARDOWN_TIMEOUT_MS
|
|
33235
33247
|
).catch(() => {
|
|
33236
33248
|
});
|
|
33237
33249
|
}
|
|
33238
33250
|
if (threadId) {
|
|
33239
33251
|
await this.sendRequest(
|
|
33240
33252
|
CODEX_METHODS.THREAD_ARCHIVE,
|
|
33241
|
-
{ threadId }
|
|
33253
|
+
{ threadId },
|
|
33254
|
+
SESSION_TEARDOWN_TIMEOUT_MS
|
|
33242
33255
|
).catch(() => {
|
|
33243
33256
|
});
|
|
33244
33257
|
}
|
|
@@ -33256,6 +33269,7 @@ var CodexAppServerConnection = class extends BaseConnection {
|
|
|
33256
33269
|
cwd: options?.cwd ?? this.cwd,
|
|
33257
33270
|
developerInstructions: options?.developerInstructions ?? null,
|
|
33258
33271
|
model: options?.model ?? null,
|
|
33272
|
+
serviceTier: options?.serviceTier ?? null,
|
|
33259
33273
|
approvalPolicy: options?.approvalPolicy ?? null,
|
|
33260
33274
|
sandbox: options?.sandbox ?? null,
|
|
33261
33275
|
config: options?.config ?? null
|
|
@@ -33273,6 +33287,9 @@ var CodexAppServerConnection = class extends BaseConnection {
|
|
|
33273
33287
|
this.rejectPendingRequests(new Error("Codex \uC5F0\uACB0\uC774 \uC885\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4."));
|
|
33274
33288
|
this.rejectPendingMcpReadyWaiters(new Error("Codex \uC5F0\uACB0\uC774 \uC885\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4."));
|
|
33275
33289
|
this.stdoutBuffer = "";
|
|
33290
|
+
this.pendingModel = null;
|
|
33291
|
+
this.pendingServiceTier = void 0;
|
|
33292
|
+
this.pendingEffort = null;
|
|
33276
33293
|
this.codexHome = null;
|
|
33277
33294
|
try {
|
|
33278
33295
|
await super.disconnect();
|
|
@@ -33721,6 +33738,7 @@ var CodexAppServerConnection = class extends BaseConnection {
|
|
|
33721
33738
|
path: rolloutPath ?? null,
|
|
33722
33739
|
cwd: options?.cwd ?? this.cwd,
|
|
33723
33740
|
model: options?.model ?? null,
|
|
33741
|
+
serviceTier: options?.serviceTier ?? null,
|
|
33724
33742
|
approvalPolicy: options?.approvalPolicy ?? null,
|
|
33725
33743
|
sandbox: options?.sandbox ?? null,
|
|
33726
33744
|
developerInstructions: options?.developerInstructions ?? null,
|
|
@@ -33840,6 +33858,9 @@ var CodexAppServerConnection = class extends BaseConnection {
|
|
|
33840
33858
|
function isMissingRolloutError(error51, threadId) {
|
|
33841
33859
|
return error51 instanceof Error && error51.message.includes(`no rollout found for thread id ${threadId}`);
|
|
33842
33860
|
}
|
|
33861
|
+
function isArchivedThreadError(error51, threadId) {
|
|
33862
|
+
return error51 instanceof Error && error51.message.includes(`session ${threadId} is archived`);
|
|
33863
|
+
}
|
|
33843
33864
|
function findRolloutPath(root, threadId) {
|
|
33844
33865
|
if (!fs10.existsSync(root)) {
|
|
33845
33866
|
return null;
|
|
@@ -33861,7 +33882,7 @@ function findRolloutPath(root, threadId) {
|
|
|
33861
33882
|
}
|
|
33862
33883
|
|
|
33863
33884
|
// ../../packages/core-unified-agent/src/client/UnifiedCodexAgentClient.ts
|
|
33864
|
-
var CODEX_TURN_LEVEL_CONFIG_KEYS = /* @__PURE__ */ new Set(["effort"
|
|
33885
|
+
var CODEX_TURN_LEVEL_CONFIG_KEYS = /* @__PURE__ */ new Set(["effort"]);
|
|
33865
33886
|
var CODEX_THREAD_POLICY_CONFIG_KEYS = /* @__PURE__ */ new Set(["approvalPolicy", "sandbox"]);
|
|
33866
33887
|
var UnifiedCodexAgentClient = class extends EventEmitter {
|
|
33867
33888
|
connection = null;
|
|
@@ -33870,6 +33891,8 @@ var UnifiedCodexAgentClient = class extends EventEmitter {
|
|
|
33870
33891
|
currentSystemPrompt = null;
|
|
33871
33892
|
firstPromptPending = null;
|
|
33872
33893
|
pendingOverrides = null;
|
|
33894
|
+
currentModelSelection = {};
|
|
33895
|
+
archiveSessionOnDisconnect = false;
|
|
33873
33896
|
detector = new CliDetector();
|
|
33874
33897
|
on(event, listener) {
|
|
33875
33898
|
return super.on(event, listener);
|
|
@@ -33889,9 +33912,6 @@ var UnifiedCodexAgentClient = class extends EventEmitter {
|
|
|
33889
33912
|
throw new Error("UnifiedCodexAgentClient\uB294 codex CLI\uB9CC \uC9C0\uC6D0\uD569\uB2C8\uB2E4.");
|
|
33890
33913
|
}
|
|
33891
33914
|
this.validateModelEffort(options.model, options.effort);
|
|
33892
|
-
if (shouldUseCodexAcp(options)) {
|
|
33893
|
-
return this.connectAcp(options);
|
|
33894
|
-
}
|
|
33895
33915
|
return this.connectAppServer(options);
|
|
33896
33916
|
}
|
|
33897
33917
|
async connectAppServer(options) {
|
|
@@ -33900,6 +33920,7 @@ var UnifiedCodexAgentClient = class extends EventEmitter {
|
|
|
33900
33920
|
const command2 = options.cliPath ?? backend.cliCommand;
|
|
33901
33921
|
const baseArgs = backend.appServerArgs ?? ["app-server", "--listen", "stdio://"];
|
|
33902
33922
|
const modeMapping = this.resolveMode(options.yoloMode === false ? "default" : "yolo");
|
|
33923
|
+
const modelSelection = this.resolveModelSelection(options.model);
|
|
33903
33924
|
const args = [
|
|
33904
33925
|
...baseArgs,
|
|
33905
33926
|
...this.buildStartupConfigArgs(options.configOverrides, options.mcpServers, modeMapping)
|
|
@@ -33923,13 +33944,14 @@ var UnifiedCodexAgentClient = class extends EventEmitter {
|
|
|
33923
33944
|
if (options.sessionId) {
|
|
33924
33945
|
await connection.connect({
|
|
33925
33946
|
skipThreadStart: true,
|
|
33926
|
-
model:
|
|
33947
|
+
model: modelSelection.providerModelId,
|
|
33948
|
+
serviceTier: modelSelection.serviceTier
|
|
33927
33949
|
});
|
|
33928
33950
|
await connection.loadSession(
|
|
33929
33951
|
options.sessionId,
|
|
33930
33952
|
this.buildCodexThreadDefaultsForResume(
|
|
33931
33953
|
options.cwd,
|
|
33932
|
-
|
|
33954
|
+
modelSelection,
|
|
33933
33955
|
null,
|
|
33934
33956
|
modeMapping
|
|
33935
33957
|
)
|
|
@@ -33937,7 +33959,8 @@ var UnifiedCodexAgentClient = class extends EventEmitter {
|
|
|
33937
33959
|
} else {
|
|
33938
33960
|
await connection.connect({
|
|
33939
33961
|
developerInstructions: void 0,
|
|
33940
|
-
model:
|
|
33962
|
+
model: modelSelection.providerModelId,
|
|
33963
|
+
serviceTier: modelSelection.serviceTier,
|
|
33941
33964
|
approvalPolicy: modeMapping.approvalPolicy,
|
|
33942
33965
|
sandbox: modeMapping.sandbox
|
|
33943
33966
|
});
|
|
@@ -33951,6 +33974,8 @@ var UnifiedCodexAgentClient = class extends EventEmitter {
|
|
|
33951
33974
|
this.sessionCwd = options.cwd;
|
|
33952
33975
|
this.currentSystemPrompt = options.systemPrompt ?? null;
|
|
33953
33976
|
this.firstPromptPending = options.sessionId ? null : this.currentSystemPrompt;
|
|
33977
|
+
this.currentModelSelection = modelSelection;
|
|
33978
|
+
this.archiveSessionOnDisconnect = options.archiveSessionOnDisconnect === true;
|
|
33954
33979
|
this.pendingOverrides = {
|
|
33955
33980
|
turnConfig: options.effort ? { effort: options.effort } : {},
|
|
33956
33981
|
threadConfig: {
|
|
@@ -33964,71 +33989,17 @@ var UnifiedCodexAgentClient = class extends EventEmitter {
|
|
|
33964
33989
|
session: { sessionId }
|
|
33965
33990
|
};
|
|
33966
33991
|
}
|
|
33967
|
-
async connectAcp(options) {
|
|
33968
|
-
const cleanEnv = cleanEnvironment(process.env, options.env);
|
|
33969
|
-
const spawnConfig = createSpawnConfig("codex", options);
|
|
33970
|
-
const codexConfigEnv = buildCodexConfigEnv(
|
|
33971
|
-
options.configOverrides,
|
|
33972
|
-
cleanEnv.CODEX_CONFIG
|
|
33973
|
-
);
|
|
33974
|
-
const connection = new AcpConnection({
|
|
33975
|
-
command: spawnConfig.command,
|
|
33976
|
-
args: spawnConfig.args,
|
|
33977
|
-
cliType: "codex",
|
|
33978
|
-
cwd: options.cwd,
|
|
33979
|
-
env: { ...cleanEnv, ...codexConfigEnv ? { CODEX_CONFIG: codexConfigEnv } : {} },
|
|
33980
|
-
requestTimeout: options.timeout ?? 6e5,
|
|
33981
|
-
initTimeout: options.timeout ?? 6e4,
|
|
33982
|
-
promptIdleTimeout: options.promptIdleTimeout ?? 6e5,
|
|
33983
|
-
clientInfo: options.clientInfo,
|
|
33984
|
-
autoApprove: options.autoApprove,
|
|
33985
|
-
fsAccess: options.fsAccess
|
|
33986
|
-
});
|
|
33987
|
-
this.connection = connection;
|
|
33988
|
-
this.setupEventForwarding();
|
|
33989
|
-
const recentLogs = [];
|
|
33990
|
-
const collectLog = (message) => {
|
|
33991
|
-
recentLogs.push(message);
|
|
33992
|
-
if (recentLogs.length > 30) {
|
|
33993
|
-
recentLogs.shift();
|
|
33994
|
-
}
|
|
33995
|
-
};
|
|
33996
|
-
connection.on("log", collectLog);
|
|
33997
|
-
let session;
|
|
33998
|
-
try {
|
|
33999
|
-
session = await connection.connect(
|
|
34000
|
-
options.cwd,
|
|
34001
|
-
options.sessionId,
|
|
34002
|
-
this.resolveAcpMcpServers(options.mcpServers)
|
|
34003
|
-
);
|
|
34004
|
-
} catch (error51) {
|
|
34005
|
-
const connectionError = this.buildConnectionError(error51, recentLogs);
|
|
34006
|
-
await this.cleanupFailedConnection();
|
|
34007
|
-
throw connectionError;
|
|
34008
|
-
} finally {
|
|
34009
|
-
connection.off("log", collectLog);
|
|
34010
|
-
}
|
|
34011
|
-
await this.finalizeAcpConnect(options, session);
|
|
34012
|
-
return {
|
|
34013
|
-
cli: "codex",
|
|
34014
|
-
protocol: "acp",
|
|
34015
|
-
session
|
|
34016
|
-
};
|
|
34017
|
-
}
|
|
34018
33992
|
async disconnect() {
|
|
34019
33993
|
if (!this.connection) {
|
|
34020
33994
|
this.clearSessionState();
|
|
34021
33995
|
return;
|
|
34022
33996
|
}
|
|
34023
|
-
|
|
34024
|
-
|
|
34025
|
-
|
|
34026
|
-
await conn.endSession(this.sessionId);
|
|
34027
|
-
} catch {
|
|
34028
|
-
}
|
|
33997
|
+
if (this.archiveSessionOnDisconnect && this.sessionId) {
|
|
33998
|
+
await this.connection.endSession().catch(() => {
|
|
33999
|
+
});
|
|
34029
34000
|
}
|
|
34030
|
-
await
|
|
34031
|
-
|
|
34001
|
+
await this.connection.disconnect();
|
|
34002
|
+
this.connection.removeAllListeners();
|
|
34032
34003
|
this.connection = null;
|
|
34033
34004
|
this.clearSessionState();
|
|
34034
34005
|
}
|
|
@@ -34036,14 +34007,7 @@ var UnifiedCodexAgentClient = class extends EventEmitter {
|
|
|
34036
34007
|
if (!this.connection) {
|
|
34037
34008
|
throw new Error("\uC5F0\uACB0\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
|
|
34038
34009
|
}
|
|
34039
|
-
|
|
34040
|
-
if (!this.sessionId) {
|
|
34041
|
-
throw new Error("\uC5F0\uACB0\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
|
|
34042
|
-
}
|
|
34043
|
-
await this.connection.endSession(this.sessionId);
|
|
34044
|
-
} else {
|
|
34045
|
-
await this.connection.endSession();
|
|
34046
|
-
}
|
|
34010
|
+
await this.connection.endSession();
|
|
34047
34011
|
this.sessionId = null;
|
|
34048
34012
|
this.sessionCwd = null;
|
|
34049
34013
|
}
|
|
@@ -34058,7 +34022,7 @@ var UnifiedCodexAgentClient = class extends EventEmitter {
|
|
|
34058
34022
|
}
|
|
34059
34023
|
return {
|
|
34060
34024
|
cli: "codex",
|
|
34061
|
-
protocol:
|
|
34025
|
+
protocol: "codex-app-server",
|
|
34062
34026
|
sessionId: this.sessionId,
|
|
34063
34027
|
state: this.connection.connectionState
|
|
34064
34028
|
};
|
|
@@ -34070,12 +34034,6 @@ var UnifiedCodexAgentClient = class extends EventEmitter {
|
|
|
34070
34034
|
if (!this.connection) {
|
|
34071
34035
|
throw new Error("\uC5F0\uACB0\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
|
|
34072
34036
|
}
|
|
34073
|
-
if (this.connection instanceof AcpConnection) {
|
|
34074
|
-
if (!this.sessionId) {
|
|
34075
|
-
throw new Error("\uC5F0\uACB0\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
|
|
34076
|
-
}
|
|
34077
|
-
return this.sendPromptWithPendingSystemPrompt(content);
|
|
34078
|
-
}
|
|
34079
34037
|
this.applyPendingOverrides();
|
|
34080
34038
|
const input = typeof content === "string" ? [{ type: "text", text: content, text_elements: [] }] : content.map((block) => "text" in block ? { type: "text", text: block.text, text_elements: [] } : { type: "text", text: JSON.stringify(block), text_elements: [] });
|
|
34081
34039
|
const systemPrompt = this.firstPromptPending;
|
|
@@ -34086,53 +34044,20 @@ var UnifiedCodexAgentClient = class extends EventEmitter {
|
|
|
34086
34044
|
}
|
|
34087
34045
|
return { stopReason: "end_turn" };
|
|
34088
34046
|
}
|
|
34089
|
-
async sendPromptWithPendingSystemPrompt(content) {
|
|
34090
|
-
if (!(this.connection instanceof AcpConnection) || !this.sessionId) {
|
|
34091
|
-
throw new Error("\uC5F0\uACB0\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
|
|
34092
|
-
}
|
|
34093
|
-
const systemPrompt = this.firstPromptPending;
|
|
34094
|
-
if (!systemPrompt) {
|
|
34095
|
-
return this.connection.sendPrompt(this.sessionId, content);
|
|
34096
|
-
}
|
|
34097
|
-
const userBlocks = typeof content === "string" ? [{ type: "text", text: content }] : content;
|
|
34098
|
-
const response = await this.connection.sendPrompt(this.sessionId, [
|
|
34099
|
-
{ type: "text", text: systemPrompt },
|
|
34100
|
-
...userBlocks
|
|
34101
|
-
]);
|
|
34102
|
-
this.firstPromptPending = null;
|
|
34103
|
-
return response;
|
|
34104
|
-
}
|
|
34105
34047
|
async cancelPrompt() {
|
|
34106
34048
|
if (!this.connection) {
|
|
34107
34049
|
throw new Error("\uC5F0\uACB0\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
|
|
34108
34050
|
}
|
|
34109
|
-
if (this.connection instanceof AcpConnection) {
|
|
34110
|
-
if (!this.sessionId) {
|
|
34111
|
-
throw new Error("\uC5F0\uACB0\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
|
|
34112
|
-
}
|
|
34113
|
-
await this.connection.cancelSession(this.sessionId);
|
|
34114
|
-
return;
|
|
34115
|
-
}
|
|
34116
34051
|
await this.connection.cancelPrompt();
|
|
34117
34052
|
}
|
|
34118
34053
|
async setModel(model) {
|
|
34119
|
-
|
|
34120
|
-
|
|
34121
|
-
|
|
34122
|
-
}
|
|
34123
|
-
this.ensurePendingOverrides().model = model;
|
|
34054
|
+
const selection = this.resolveModelSelection(model);
|
|
34055
|
+
this.currentModelSelection = selection;
|
|
34056
|
+
this.ensurePendingOverrides().model = selection;
|
|
34124
34057
|
}
|
|
34125
34058
|
async setConfigOption(configId, value) {
|
|
34126
|
-
if (
|
|
34127
|
-
|
|
34128
|
-
await this.connection.setModel(this.sessionId, value);
|
|
34129
|
-
return;
|
|
34130
|
-
}
|
|
34131
|
-
await this.connection.setConfigOption(
|
|
34132
|
-
this.sessionId,
|
|
34133
|
-
configId === "effort" ? "reasoning_effort" : configId,
|
|
34134
|
-
value
|
|
34135
|
-
);
|
|
34059
|
+
if (configId === "model") {
|
|
34060
|
+
await this.setModel(value);
|
|
34136
34061
|
return;
|
|
34137
34062
|
}
|
|
34138
34063
|
const pending = this.ensurePendingOverrides();
|
|
@@ -34144,10 +34069,6 @@ var UnifiedCodexAgentClient = class extends EventEmitter {
|
|
|
34144
34069
|
this.emitTyped("log", `[codex] config '${configId}' will apply on next thread/start or thread/resume`);
|
|
34145
34070
|
}
|
|
34146
34071
|
async setMode(mode) {
|
|
34147
|
-
if (this.connection instanceof AcpConnection && this.sessionId) {
|
|
34148
|
-
await this.connection.setMode(this.sessionId, this.resolveAcpMode(mode));
|
|
34149
|
-
return;
|
|
34150
|
-
}
|
|
34151
34072
|
const resolved = this.resolveMode(mode);
|
|
34152
34073
|
const pending = this.ensurePendingOverrides();
|
|
34153
34074
|
pending.threadConfig.approvalPolicy = resolved.approvalPolicy;
|
|
@@ -34170,17 +34091,6 @@ var UnifiedCodexAgentClient = class extends EventEmitter {
|
|
|
34170
34091
|
if (!this.connection) {
|
|
34171
34092
|
throw new Error("\uC5F0\uACB0\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
|
|
34172
34093
|
}
|
|
34173
|
-
if (this.connection instanceof AcpConnection) {
|
|
34174
|
-
await this.connection.loadSession({
|
|
34175
|
-
sessionId,
|
|
34176
|
-
cwd: this.sessionCwd ?? process.cwd(),
|
|
34177
|
-
mcpServers: this.resolveAcpMcpServers(mcpServers)
|
|
34178
|
-
});
|
|
34179
|
-
this.sessionId = sessionId;
|
|
34180
|
-
this.currentSystemPrompt = null;
|
|
34181
|
-
this.firstPromptPending = null;
|
|
34182
|
-
return;
|
|
34183
|
-
}
|
|
34184
34094
|
if (mcpServers?.length) {
|
|
34185
34095
|
this.emitTyped(
|
|
34186
34096
|
"log",
|
|
@@ -34192,7 +34102,7 @@ var UnifiedCodexAgentClient = class extends EventEmitter {
|
|
|
34192
34102
|
sessionId,
|
|
34193
34103
|
this.buildCodexThreadDefaultsForResume(
|
|
34194
34104
|
targetCwd,
|
|
34195
|
-
|
|
34105
|
+
this.currentModelSelection,
|
|
34196
34106
|
null,
|
|
34197
34107
|
this.pendingOverrides?.threadConfig ?? {}
|
|
34198
34108
|
)
|
|
@@ -34206,24 +34116,6 @@ var UnifiedCodexAgentClient = class extends EventEmitter {
|
|
|
34206
34116
|
throw new Error("\uC5F0\uACB0\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
|
|
34207
34117
|
}
|
|
34208
34118
|
const targetCwd = cwd ?? this.sessionCwd ?? process.cwd();
|
|
34209
|
-
if (this.connection instanceof AcpConnection) {
|
|
34210
|
-
if (!this.sessionId) {
|
|
34211
|
-
throw new Error("\uC5F0\uACB0\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
|
|
34212
|
-
}
|
|
34213
|
-
if (!this.connection.canResetSession) {
|
|
34214
|
-
throw new Error("[codex] \uC138\uC158 \uB9AC\uC14B\uC744 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. disconnect() \uD6C4 \uC7AC\uC5F0\uACB0\uD558\uC138\uC694.");
|
|
34215
|
-
}
|
|
34216
|
-
await this.connection.endSession(this.sessionId);
|
|
34217
|
-
const session = await this.connection.reconnectSession(targetCwd);
|
|
34218
|
-
this.sessionId = session.sessionId;
|
|
34219
|
-
this.sessionCwd = targetCwd;
|
|
34220
|
-
this.firstPromptPending = this.currentSystemPrompt;
|
|
34221
|
-
return {
|
|
34222
|
-
cli: "codex",
|
|
34223
|
-
protocol: "acp",
|
|
34224
|
-
session
|
|
34225
|
-
};
|
|
34226
|
-
}
|
|
34227
34119
|
const result = await this.connection.resetSession(
|
|
34228
34120
|
this.buildCodexThreadDefaultsForReset(targetCwd)
|
|
34229
34121
|
);
|
|
@@ -34239,33 +34131,14 @@ var UnifiedCodexAgentClient = class extends EventEmitter {
|
|
|
34239
34131
|
protocol: "codex-app-server"
|
|
34240
34132
|
};
|
|
34241
34133
|
}
|
|
34242
|
-
resolveAcpMcpServers(servers) {
|
|
34243
|
-
return servers?.length ? mcpServerConfigsToAcp(servers) : [];
|
|
34244
|
-
}
|
|
34245
|
-
async finalizeAcpConnect(options, session) {
|
|
34246
|
-
this.sessionId = session.sessionId;
|
|
34247
|
-
this.sessionCwd = options.cwd;
|
|
34248
|
-
this.currentSystemPrompt = options.systemPrompt ?? null;
|
|
34249
|
-
this.firstPromptPending = options.sessionId ? null : this.currentSystemPrompt;
|
|
34250
|
-
this.pendingOverrides = {
|
|
34251
|
-
turnConfig: {},
|
|
34252
|
-
threadConfig: {}
|
|
34253
|
-
};
|
|
34254
|
-
const mode = options.yoloMode === false ? "default" : "yolo";
|
|
34255
|
-
await this.setMode(mode);
|
|
34256
|
-
if (options.model) {
|
|
34257
|
-
await this.setModel(options.model);
|
|
34258
|
-
}
|
|
34259
|
-
if (options.effort) {
|
|
34260
|
-
await this.setConfigOption("effort", options.effort);
|
|
34261
|
-
}
|
|
34262
|
-
}
|
|
34263
34134
|
clearSessionState() {
|
|
34264
34135
|
this.sessionId = null;
|
|
34265
34136
|
this.sessionCwd = null;
|
|
34266
34137
|
this.currentSystemPrompt = null;
|
|
34267
34138
|
this.firstPromptPending = null;
|
|
34268
34139
|
this.pendingOverrides = null;
|
|
34140
|
+
this.currentModelSelection = {};
|
|
34141
|
+
this.archiveSessionOnDisconnect = false;
|
|
34269
34142
|
}
|
|
34270
34143
|
validateModelEffort(modelId, effort) {
|
|
34271
34144
|
if (!effort) {
|
|
@@ -34288,69 +34161,7 @@ var UnifiedCodexAgentClient = class extends EventEmitter {
|
|
|
34288
34161
|
}
|
|
34289
34162
|
setupEventForwarding() {
|
|
34290
34163
|
if (!this.connection) return;
|
|
34291
|
-
|
|
34292
|
-
if (connection instanceof AcpConnection) {
|
|
34293
|
-
this.setupAcpEventForwarding(connection);
|
|
34294
|
-
return;
|
|
34295
|
-
}
|
|
34296
|
-
this.setupAppServerEventForwarding(connection);
|
|
34297
|
-
}
|
|
34298
|
-
setupAcpEventForwarding(connection) {
|
|
34299
|
-
connection.on("stateChange", (state) => {
|
|
34300
|
-
this.emitTyped("stateChange", state);
|
|
34301
|
-
});
|
|
34302
|
-
connection.on("userMessageChunk", (text, sessionId) => {
|
|
34303
|
-
this.emitTyped("userMessageChunk", text, sessionId);
|
|
34304
|
-
});
|
|
34305
|
-
connection.on("messageChunk", (text, sessionId) => {
|
|
34306
|
-
this.emitTyped("messageChunk", text, sessionId);
|
|
34307
|
-
});
|
|
34308
|
-
connection.on("thoughtChunk", (text, sessionId) => {
|
|
34309
|
-
this.emitTyped("thoughtChunk", text, sessionId);
|
|
34310
|
-
});
|
|
34311
|
-
connection.on("toolCall", (title, status, sessionId, data) => {
|
|
34312
|
-
this.emitTyped("toolCall", title, status, sessionId, data);
|
|
34313
|
-
});
|
|
34314
|
-
connection.on("toolCallUpdate", (title, status, sessionId, data) => {
|
|
34315
|
-
this.emitTyped("toolCallUpdate", title, status, sessionId, data);
|
|
34316
|
-
});
|
|
34317
|
-
connection.on("plan", (plan, sessionId) => {
|
|
34318
|
-
this.emitTyped("plan", plan, sessionId);
|
|
34319
|
-
});
|
|
34320
|
-
connection.on("availableCommandsUpdate", (commands, sessionId) => {
|
|
34321
|
-
this.emitTyped("availableCommandsUpdate", commands, sessionId);
|
|
34322
|
-
});
|
|
34323
|
-
connection.on("promptComplete", (sessionId) => {
|
|
34324
|
-
this.emitTyped("promptComplete", sessionId);
|
|
34325
|
-
});
|
|
34326
|
-
connection.on("permissionRequest", (params, resolve3) => {
|
|
34327
|
-
this.emitTyped(
|
|
34328
|
-
"permissionRequest",
|
|
34329
|
-
params,
|
|
34330
|
-
resolve3
|
|
34331
|
-
);
|
|
34332
|
-
});
|
|
34333
|
-
connection.on("sessionUpdate", (update) => {
|
|
34334
|
-
this.emitTyped("sessionUpdate", update);
|
|
34335
|
-
});
|
|
34336
|
-
connection.on("fileRead", (params, resolve3) => {
|
|
34337
|
-
this.emitTyped("fileRead", params, resolve3);
|
|
34338
|
-
});
|
|
34339
|
-
connection.on("fileWrite", (params, resolve3) => {
|
|
34340
|
-
this.emitTyped("fileWrite", params, resolve3);
|
|
34341
|
-
});
|
|
34342
|
-
connection.on("error", (err) => {
|
|
34343
|
-
this.emitTyped("error", err);
|
|
34344
|
-
});
|
|
34345
|
-
connection.on("exit", (code, signal) => {
|
|
34346
|
-
this.emitTyped("exit", code, signal);
|
|
34347
|
-
});
|
|
34348
|
-
connection.on("log", (msg) => {
|
|
34349
|
-
this.emitTyped("log", msg);
|
|
34350
|
-
});
|
|
34351
|
-
connection.on("logEntry", (entry) => {
|
|
34352
|
-
this.emitTyped("logEntry", entry);
|
|
34353
|
-
});
|
|
34164
|
+
this.setupAppServerEventForwarding(this.connection);
|
|
34354
34165
|
}
|
|
34355
34166
|
setupAppServerEventForwarding(connection) {
|
|
34356
34167
|
connection.on("stateChange", (state) => {
|
|
@@ -34413,15 +34224,15 @@ var UnifiedCodexAgentClient = class extends EventEmitter {
|
|
|
34413
34224
|
if (!this.pendingOverrides || !this.connection) {
|
|
34414
34225
|
return;
|
|
34415
34226
|
}
|
|
34416
|
-
if (this.connection instanceof AcpConnection) {
|
|
34417
|
-
return;
|
|
34418
|
-
}
|
|
34419
34227
|
if (this.pendingOverrides.model) {
|
|
34420
|
-
this.connection.setPendingModel(this.pendingOverrides.model);
|
|
34228
|
+
this.connection.setPendingModel(this.pendingOverrides.model.providerModelId ?? null);
|
|
34229
|
+
this.connection.setPendingServiceTier(this.pendingOverrides.model.serviceTier ?? null);
|
|
34421
34230
|
this.pendingOverrides.model = void 0;
|
|
34422
34231
|
}
|
|
34423
34232
|
if (this.pendingOverrides.turnConfig.model) {
|
|
34424
|
-
this.
|
|
34233
|
+
const selection = this.resolveModelSelection(this.pendingOverrides.turnConfig.model);
|
|
34234
|
+
this.connection.setPendingModel(selection.providerModelId ?? null);
|
|
34235
|
+
this.connection.setPendingServiceTier(selection.serviceTier ?? null);
|
|
34425
34236
|
delete this.pendingOverrides.turnConfig.model;
|
|
34426
34237
|
}
|
|
34427
34238
|
if (this.pendingOverrides.turnConfig.effort) {
|
|
@@ -34436,19 +34247,22 @@ var UnifiedCodexAgentClient = class extends EventEmitter {
|
|
|
34436
34247
|
const config2 = configEntries.length > 0 ? Object.fromEntries(configEntries) : void 0;
|
|
34437
34248
|
return {
|
|
34438
34249
|
cwd,
|
|
34250
|
+
model: this.currentModelSelection.providerModelId,
|
|
34251
|
+
serviceTier: this.currentModelSelection.serviceTier,
|
|
34439
34252
|
approvalPolicy,
|
|
34440
34253
|
sandbox,
|
|
34441
34254
|
developerInstructions: void 0,
|
|
34442
34255
|
config: config2
|
|
34443
34256
|
};
|
|
34444
34257
|
}
|
|
34445
|
-
buildCodexThreadDefaultsForResume(cwd,
|
|
34258
|
+
buildCodexThreadDefaultsForResume(cwd, modelSelection, systemPrompt, threadConfig) {
|
|
34446
34259
|
const { approvalPolicy, sandbox } = threadConfig;
|
|
34447
34260
|
const configEntries = Object.entries(threadConfig).filter(([key]) => !CODEX_THREAD_POLICY_CONFIG_KEYS.has(key));
|
|
34448
34261
|
const config2 = configEntries.length > 0 ? Object.fromEntries(configEntries) : void 0;
|
|
34449
34262
|
return {
|
|
34450
34263
|
cwd,
|
|
34451
|
-
...
|
|
34264
|
+
...modelSelection.providerModelId ? { model: modelSelection.providerModelId } : {},
|
|
34265
|
+
...modelSelection.serviceTier ? { serviceTier: modelSelection.serviceTier } : {},
|
|
34452
34266
|
approvalPolicy,
|
|
34453
34267
|
sandbox,
|
|
34454
34268
|
developerInstructions: systemPrompt ?? void 0,
|
|
@@ -34465,16 +34279,6 @@ var UnifiedCodexAgentClient = class extends EventEmitter {
|
|
|
34465
34279
|
return { approvalPolicy: "on-request", sandbox: "read-only" };
|
|
34466
34280
|
}
|
|
34467
34281
|
}
|
|
34468
|
-
resolveAcpMode(modeId) {
|
|
34469
|
-
switch (modeId) {
|
|
34470
|
-
case "autoEdit":
|
|
34471
|
-
return "agent";
|
|
34472
|
-
case "yolo":
|
|
34473
|
-
return "agent-full-access";
|
|
34474
|
-
default:
|
|
34475
|
-
return "read-only";
|
|
34476
|
-
}
|
|
34477
|
-
}
|
|
34478
34282
|
buildStartupConfigArgs(overrides, servers, modeMapping) {
|
|
34479
34283
|
const configArgs = [
|
|
34480
34284
|
...modeMapping ? [
|
|
@@ -34504,6 +34308,10 @@ var UnifiedCodexAgentClient = class extends EventEmitter {
|
|
|
34504
34308
|
return;
|
|
34505
34309
|
}
|
|
34506
34310
|
try {
|
|
34311
|
+
if (this.archiveSessionOnDisconnect && this.sessionId) {
|
|
34312
|
+
await this.connection.endSession().catch(() => {
|
|
34313
|
+
});
|
|
34314
|
+
}
|
|
34507
34315
|
await this.connection.disconnect();
|
|
34508
34316
|
} catch {
|
|
34509
34317
|
}
|
|
@@ -34511,65 +34319,17 @@ var UnifiedCodexAgentClient = class extends EventEmitter {
|
|
|
34511
34319
|
this.connection = null;
|
|
34512
34320
|
this.clearSessionState();
|
|
34513
34321
|
}
|
|
34514
|
-
|
|
34515
|
-
if (
|
|
34516
|
-
return
|
|
34517
|
-
"[codex] \uC778\uC99D\uC774 \uD544\uC694\uD558\uAC70\uB098 \uC778\uC99D\uC774 \uB9CC\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4. \uBA3C\uC800 \uD574\uB2F9 CLI\uC5D0\uC11C \uB85C\uADF8\uC778/\uC778\uC99D\uC744 \uC644\uB8CC\uD55C \uB4A4 \uB2E4\uC2DC \uC2DC\uB3C4\uD574\uC8FC\uC138\uC694."
|
|
34518
|
-
);
|
|
34519
|
-
}
|
|
34520
|
-
if (error51 instanceof Error) {
|
|
34521
|
-
return error51;
|
|
34522
|
-
}
|
|
34523
|
-
if (typeof error51 === "object" && error51 !== null) {
|
|
34524
|
-
const obj = error51;
|
|
34525
|
-
if (typeof obj.message === "string") {
|
|
34526
|
-
const code = typeof obj.code === "number" ? ` (code: ${obj.code})` : "";
|
|
34527
|
-
const data = obj.data ? ` \u2014 ${JSON.stringify(obj.data)}` : "";
|
|
34528
|
-
return new Error(`${obj.message}${code}${data}`);
|
|
34529
|
-
}
|
|
34530
|
-
return new Error(JSON.stringify(error51));
|
|
34531
|
-
}
|
|
34532
|
-
return new Error(String(error51));
|
|
34533
|
-
}
|
|
34534
|
-
isAuthenticationError(error51, recentLogs) {
|
|
34535
|
-
const authPatterns = [
|
|
34536
|
-
/auth_required/i,
|
|
34537
|
-
/authentication required/i,
|
|
34538
|
-
/not authenticated/i,
|
|
34539
|
-
/please login/i,
|
|
34540
|
-
/please log in/i,
|
|
34541
|
-
/sign in/i,
|
|
34542
|
-
/reauth/i,
|
|
34543
|
-
/unauthorized/i,
|
|
34544
|
-
/invalid api key/i
|
|
34545
|
-
];
|
|
34546
|
-
if (this.matchAnyPattern(this.extractErrorText(error51), authPatterns)) {
|
|
34547
|
-
return true;
|
|
34548
|
-
}
|
|
34549
|
-
return recentLogs.some((log) => this.matchAnyPattern(log, authPatterns));
|
|
34550
|
-
}
|
|
34551
|
-
extractErrorText(error51) {
|
|
34552
|
-
if (error51 instanceof Error) {
|
|
34553
|
-
const code = error51.code;
|
|
34554
|
-
if (code === -32e3) {
|
|
34555
|
-
return `auth_required ${error51.message}`;
|
|
34556
|
-
}
|
|
34557
|
-
return error51.message;
|
|
34558
|
-
}
|
|
34559
|
-
if (typeof error51 === "string") {
|
|
34560
|
-
return error51;
|
|
34322
|
+
resolveModelSelection(modelId) {
|
|
34323
|
+
if (!modelId) {
|
|
34324
|
+
return {};
|
|
34561
34325
|
}
|
|
34562
|
-
|
|
34563
|
-
|
|
34564
|
-
|
|
34565
|
-
|
|
34326
|
+
const model = getProviderModels("codex").models.find((entry) => entry.modelId === modelId);
|
|
34327
|
+
return {
|
|
34328
|
+
providerModelId: model?.providerModelId ?? modelId,
|
|
34329
|
+
serviceTier: model?.serviceTier
|
|
34330
|
+
};
|
|
34566
34331
|
}
|
|
34567
34332
|
};
|
|
34568
|
-
function shouldUseCodexAcp(options) {
|
|
34569
|
-
const value = options.env?.CODEX_USE_ACP ?? process.env.CODEX_USE_ACP;
|
|
34570
|
-
const normalized = value?.trim().toLowerCase();
|
|
34571
|
-
return normalized !== void 0 && normalized !== "false" && normalized !== "0";
|
|
34572
|
-
}
|
|
34573
34333
|
var UnifiedCursorAgentClient = class extends EventEmitter {
|
|
34574
34334
|
connection = null;
|
|
34575
34335
|
sessionId = null;
|
|
@@ -38086,9 +37846,243 @@ function stripIpv6Brackets2(host) {
|
|
|
38086
37846
|
|
|
38087
37847
|
// core/host/operations/types.ts
|
|
38088
37848
|
var MAX_GROUP_NAME_LENGTH = 64;
|
|
37849
|
+
var DELETION_GRACE_MS = 8e3;
|
|
38089
37850
|
|
|
38090
|
-
// core/host/
|
|
38091
|
-
var
|
|
37851
|
+
// core/host/deferred-deletion.ts
|
|
37852
|
+
var DeferredDeletionError = class extends Error {
|
|
37853
|
+
status;
|
|
37854
|
+
constructor(status, message) {
|
|
37855
|
+
super(message);
|
|
37856
|
+
this.name = "DeferredDeletionError";
|
|
37857
|
+
this.status = status;
|
|
37858
|
+
}
|
|
37859
|
+
};
|
|
37860
|
+
var OPERATION_DELETED_EVENT_CHANNEL = "operation:deleted";
|
|
37861
|
+
var OPERATION_RESTORED_EVENT_CHANNEL = "operation:restored";
|
|
37862
|
+
var OPERATION_PURGED_EVENT_CHANNEL = "operation:purged";
|
|
37863
|
+
var PURGE_RETRY_MS = 1e3;
|
|
37864
|
+
function createDeferredDeletionCoordinator(deps) {
|
|
37865
|
+
const now = deps.now ?? Date.now;
|
|
37866
|
+
const randomId = deps.randomId ?? crypto2.randomUUID;
|
|
37867
|
+
const setTimer = deps.setTimer ?? setTimeout;
|
|
37868
|
+
const clearTimer = deps.clearTimer ?? clearTimeout;
|
|
37869
|
+
let tombstones = [];
|
|
37870
|
+
let timer = null;
|
|
37871
|
+
function list() {
|
|
37872
|
+
return tombstones;
|
|
37873
|
+
}
|
|
37874
|
+
function load(nextTombstones) {
|
|
37875
|
+
tombstones = [...nextTombstones];
|
|
37876
|
+
schedule();
|
|
37877
|
+
}
|
|
37878
|
+
function deleteOperation(operationId) {
|
|
37879
|
+
sweepExpired();
|
|
37880
|
+
const existing = tombstones.find((item) => item.kind === "operation" && item.targetId === operationId);
|
|
37881
|
+
if (existing) return toReceipt(existing);
|
|
37882
|
+
const operation = deps.operations.get(operationId);
|
|
37883
|
+
if (!operation) return null;
|
|
37884
|
+
const previousOperations = deps.operations.list();
|
|
37885
|
+
const deletedAt = now();
|
|
37886
|
+
const tombstone = {
|
|
37887
|
+
deletionId: randomId(),
|
|
37888
|
+
targetId: operation.id,
|
|
37889
|
+
deletedAt,
|
|
37890
|
+
expiresAt: deletedAt + DELETION_GRACE_MS,
|
|
37891
|
+
kind: "operation",
|
|
37892
|
+
operation
|
|
37893
|
+
};
|
|
37894
|
+
const nextTombstones = [...tombstones, tombstone];
|
|
37895
|
+
deps.operations.delete(operationId);
|
|
37896
|
+
try {
|
|
37897
|
+
deps.save(nextTombstones);
|
|
37898
|
+
} catch (error51) {
|
|
37899
|
+
deps.operations.replace(previousOperations);
|
|
37900
|
+
throw error51;
|
|
37901
|
+
}
|
|
37902
|
+
tombstones = nextTombstones;
|
|
37903
|
+
publishOperation(OPERATION_DELETED_EVENT_CHANNEL, operation);
|
|
37904
|
+
schedule();
|
|
37905
|
+
return toReceipt(tombstone);
|
|
37906
|
+
}
|
|
37907
|
+
function deleteTheater(theaterId) {
|
|
37908
|
+
sweepExpired();
|
|
37909
|
+
const existing = tombstones.find((item) => item.kind === "theater" && item.targetId === theaterId);
|
|
37910
|
+
if (existing) return toReceipt(existing);
|
|
37911
|
+
const theater = deps.theaters.get(theaterId);
|
|
37912
|
+
if (!theater) return null;
|
|
37913
|
+
const previousTheaters = deps.theaters.list();
|
|
37914
|
+
const previousOperations = deps.operations.list();
|
|
37915
|
+
const previousGroups = deps.operations.listAllGroups();
|
|
37916
|
+
const deletedOperations = deps.operations.listByTheater(theaterId);
|
|
37917
|
+
const deletedGroups = deps.operations.listGroups(theaterId);
|
|
37918
|
+
const deletedAt = now();
|
|
37919
|
+
const tombstone = {
|
|
37920
|
+
deletionId: randomId(),
|
|
37921
|
+
targetId: theater.id,
|
|
37922
|
+
deletedAt,
|
|
37923
|
+
expiresAt: deletedAt + DELETION_GRACE_MS,
|
|
37924
|
+
kind: "theater",
|
|
37925
|
+
theater,
|
|
37926
|
+
operations: deletedOperations,
|
|
37927
|
+
groups: deletedGroups
|
|
37928
|
+
};
|
|
37929
|
+
const nextTombstones = [...tombstones, tombstone];
|
|
37930
|
+
deps.theaters.remove(theaterId);
|
|
37931
|
+
deps.operations.deleteByTheater(theaterId);
|
|
37932
|
+
try {
|
|
37933
|
+
deps.save(nextTombstones);
|
|
37934
|
+
} catch (error51) {
|
|
37935
|
+
deps.theaters.restore(previousTheaters);
|
|
37936
|
+
deps.operations.replace(previousOperations);
|
|
37937
|
+
deps.operations.replaceGroups(previousGroups);
|
|
37938
|
+
throw error51;
|
|
37939
|
+
}
|
|
37940
|
+
tombstones = nextTombstones;
|
|
37941
|
+
deps.unregisterTheaterWorkspaces(theaterId);
|
|
37942
|
+
for (const operation of deletedOperations) publishOperation(OPERATION_DELETED_EVENT_CHANNEL, operation);
|
|
37943
|
+
schedule();
|
|
37944
|
+
return toReceipt(tombstone);
|
|
37945
|
+
}
|
|
37946
|
+
async function restore(deletionId) {
|
|
37947
|
+
const restoredAt = now();
|
|
37948
|
+
const tombstone = tombstones.find((item) => item.deletionId === deletionId);
|
|
37949
|
+
if (!tombstone || tombstone.expiresAt <= restoredAt) {
|
|
37950
|
+
if (tombstone) sweepExpired();
|
|
37951
|
+
throw new DeferredDeletionError(404, "deletion_not_found");
|
|
37952
|
+
}
|
|
37953
|
+
if (tombstone.kind === "operation") {
|
|
37954
|
+
if (deps.operations.get(tombstone.targetId) || !deps.theaters.get(tombstone.operation.theaterId)) {
|
|
37955
|
+
throw new DeferredDeletionError(409, "restore_conflict");
|
|
37956
|
+
}
|
|
37957
|
+
const previousOperations2 = deps.operations.list();
|
|
37958
|
+
const nextTombstones2 = tombstones.filter((item) => item.deletionId !== deletionId);
|
|
37959
|
+
deps.operations.replace([...previousOperations2, tombstone.operation]);
|
|
37960
|
+
try {
|
|
37961
|
+
deps.save(nextTombstones2);
|
|
37962
|
+
} catch (error51) {
|
|
37963
|
+
deps.operations.replace(previousOperations2);
|
|
37964
|
+
throw error51;
|
|
37965
|
+
}
|
|
37966
|
+
tombstones = nextTombstones2;
|
|
37967
|
+
publishOperation(OPERATION_RESTORED_EVENT_CHANNEL, tombstone.operation);
|
|
37968
|
+
schedule();
|
|
37969
|
+
return { ok: true, kind: tombstone.kind, targetId: tombstone.targetId };
|
|
37970
|
+
}
|
|
37971
|
+
await deps.validateTheaterRestore(tombstone.theater);
|
|
37972
|
+
if (deps.theaters.get(tombstone.targetId) || tombstone.operations.some((operation) => deps.operations.get(operation.id)) || hasGroupConflict(tombstone.groups, deps.operations.listAllGroups())) {
|
|
37973
|
+
throw new DeferredDeletionError(409, "restore_conflict");
|
|
37974
|
+
}
|
|
37975
|
+
const previousTheaters = deps.theaters.list();
|
|
37976
|
+
const previousOperations = deps.operations.list();
|
|
37977
|
+
const previousGroups = deps.operations.listAllGroups();
|
|
37978
|
+
const nextTombstones = tombstones.filter((item) => item.deletionId !== deletionId);
|
|
37979
|
+
deps.theaters.restore([...previousTheaters, tombstone.theater]);
|
|
37980
|
+
deps.operations.replace([...previousOperations, ...tombstone.operations]);
|
|
37981
|
+
deps.operations.replaceGroups([...previousGroups, ...tombstone.groups]);
|
|
37982
|
+
try {
|
|
37983
|
+
deps.save(nextTombstones);
|
|
37984
|
+
} catch (error51) {
|
|
37985
|
+
deps.theaters.restore(previousTheaters);
|
|
37986
|
+
deps.operations.replace(previousOperations);
|
|
37987
|
+
deps.operations.replaceGroups(previousGroups);
|
|
37988
|
+
throw error51;
|
|
37989
|
+
}
|
|
37990
|
+
tombstones = nextTombstones;
|
|
37991
|
+
await deps.registerTheaterWorkspace(tombstone.theater);
|
|
37992
|
+
for (const operation of tombstone.operations) publishOperation(OPERATION_RESTORED_EVENT_CHANNEL, operation);
|
|
37993
|
+
schedule();
|
|
37994
|
+
return { ok: true, kind: tombstone.kind, targetId: tombstone.targetId };
|
|
37995
|
+
}
|
|
37996
|
+
function sweepExpired() {
|
|
37997
|
+
const cutoff = now();
|
|
37998
|
+
const expired = tombstones.filter((item) => item.expiresAt <= cutoff);
|
|
37999
|
+
if (expired.length === 0) {
|
|
38000
|
+
schedule();
|
|
38001
|
+
return;
|
|
38002
|
+
}
|
|
38003
|
+
const expiredIds = new Set(expired.map((item) => item.deletionId));
|
|
38004
|
+
const nextTombstones = tombstones.filter((item) => !expiredIds.has(item.deletionId));
|
|
38005
|
+
try {
|
|
38006
|
+
deps.save(nextTombstones);
|
|
38007
|
+
} catch (error51) {
|
|
38008
|
+
schedule(PURGE_RETRY_MS);
|
|
38009
|
+
throw error51;
|
|
38010
|
+
}
|
|
38011
|
+
tombstones = nextTombstones;
|
|
38012
|
+
for (const tombstone of expired) {
|
|
38013
|
+
if (tombstone.kind === "operation") {
|
|
38014
|
+
publishOperation(OPERATION_PURGED_EVENT_CHANNEL, tombstone.operation);
|
|
38015
|
+
} else {
|
|
38016
|
+
for (const operation of tombstone.operations) publishOperation(OPERATION_PURGED_EVENT_CHANNEL, operation);
|
|
38017
|
+
}
|
|
38018
|
+
}
|
|
38019
|
+
schedule();
|
|
38020
|
+
}
|
|
38021
|
+
function hasPendingOperation(operationId) {
|
|
38022
|
+
sweepExpired();
|
|
38023
|
+
return tombstones.some((item) => item.kind === "operation" ? item.targetId === operationId : item.operations.some((operation) => operation.id === operationId));
|
|
38024
|
+
}
|
|
38025
|
+
function hasPendingTheater(theaterId) {
|
|
38026
|
+
sweepExpired();
|
|
38027
|
+
return tombstones.some((item) => item.kind === "theater" && item.targetId === theaterId);
|
|
38028
|
+
}
|
|
38029
|
+
function schedule(forcedDelay) {
|
|
38030
|
+
if (timer) clearTimer(timer);
|
|
38031
|
+
timer = null;
|
|
38032
|
+
if (forcedDelay !== void 0) {
|
|
38033
|
+
timer = setTimer(runScheduledSweep, forcedDelay);
|
|
38034
|
+
timer.unref?.();
|
|
38035
|
+
return;
|
|
38036
|
+
}
|
|
38037
|
+
const nearest = tombstones.reduce((minimum, item) => minimum === null ? item.expiresAt : Math.min(minimum, item.expiresAt), null);
|
|
38038
|
+
if (nearest === null) return;
|
|
38039
|
+
timer = setTimer(runScheduledSweep, Math.max(0, nearest - now()));
|
|
38040
|
+
timer.unref?.();
|
|
38041
|
+
}
|
|
38042
|
+
function runScheduledSweep() {
|
|
38043
|
+
timer = null;
|
|
38044
|
+
try {
|
|
38045
|
+
sweepExpired();
|
|
38046
|
+
} catch {
|
|
38047
|
+
}
|
|
38048
|
+
}
|
|
38049
|
+
function dispose() {
|
|
38050
|
+
if (timer) clearTimer(timer);
|
|
38051
|
+
timer = null;
|
|
38052
|
+
}
|
|
38053
|
+
function publishOperation(channel, operation) {
|
|
38054
|
+
deps.publish(channel, {
|
|
38055
|
+
operationId: operation.id,
|
|
38056
|
+
pluginId: operation.pluginId,
|
|
38057
|
+
type: operation.type,
|
|
38058
|
+
...channel === OPERATION_RESTORED_EVENT_CHANNEL ? { operation } : {}
|
|
38059
|
+
});
|
|
38060
|
+
}
|
|
38061
|
+
return {
|
|
38062
|
+
list,
|
|
38063
|
+
load,
|
|
38064
|
+
deleteOperation,
|
|
38065
|
+
deleteTheater,
|
|
38066
|
+
restore,
|
|
38067
|
+
sweepExpired,
|
|
38068
|
+
hasPendingOperation,
|
|
38069
|
+
hasPendingTheater,
|
|
38070
|
+
dispose
|
|
38071
|
+
};
|
|
38072
|
+
}
|
|
38073
|
+
function toReceipt(tombstone) {
|
|
38074
|
+
return {
|
|
38075
|
+
deletionId: tombstone.deletionId,
|
|
38076
|
+
kind: tombstone.kind,
|
|
38077
|
+
targetId: tombstone.targetId,
|
|
38078
|
+
expiresAt: tombstone.expiresAt
|
|
38079
|
+
};
|
|
38080
|
+
}
|
|
38081
|
+
function hasGroupConflict(groups, existing) {
|
|
38082
|
+
const existingIds = new Set(existing.map((group) => group.id));
|
|
38083
|
+
return groups.some((group) => existingIds.has(group.id));
|
|
38084
|
+
}
|
|
38085
|
+
var STATE_VERSION = 3;
|
|
38092
38086
|
var STATE_LOCK_DIR_NAME = "state.lock";
|
|
38093
38087
|
var STATE_LOCK_OWNER_FILE_NAME = "owner.json";
|
|
38094
38088
|
var STATE_TEMP_PREFIX = ".state.";
|
|
@@ -38135,25 +38129,37 @@ function sanitizeDurableConsoleState(value) {
|
|
|
38135
38129
|
version: STATE_VERSION,
|
|
38136
38130
|
theaters: readTheaterRegistrations(upgraded.theaters),
|
|
38137
38131
|
operations: readOperations(upgraded.operations),
|
|
38138
|
-
groups: readOperationGroups(upgraded.groups)
|
|
38132
|
+
groups: readOperationGroups(upgraded.groups),
|
|
38133
|
+
deletionTombstones: readDeletionTombstones(upgraded.deletionTombstones)
|
|
38139
38134
|
};
|
|
38140
38135
|
}
|
|
38141
38136
|
function emptyDurableConsoleState() {
|
|
38142
|
-
return { version: STATE_VERSION, theaters: [], operations: [], groups: [] };
|
|
38137
|
+
return { version: STATE_VERSION, theaters: [], operations: [], groups: [], deletionTombstones: [] };
|
|
38143
38138
|
}
|
|
38144
38139
|
function migrateToCurrentVersion(value) {
|
|
38145
|
-
|
|
38146
|
-
|
|
38140
|
+
let current = value;
|
|
38141
|
+
if (current.version === 1) current = migrateV1ToV2(current);
|
|
38142
|
+
if (current.version === 2) current = migrateV2ToV3(current);
|
|
38143
|
+
return current;
|
|
38147
38144
|
}
|
|
38148
38145
|
function migrateV1ToV2(v1) {
|
|
38149
38146
|
const operations = Array.isArray(v1.operations) ? v1.operations.map(migrateV1Operation) : [];
|
|
38150
38147
|
return {
|
|
38151
|
-
version:
|
|
38148
|
+
version: 2,
|
|
38152
38149
|
theaters: v1.theaters ?? [],
|
|
38153
38150
|
operations,
|
|
38154
38151
|
groups: []
|
|
38155
38152
|
};
|
|
38156
38153
|
}
|
|
38154
|
+
function migrateV2ToV3(v2) {
|
|
38155
|
+
return {
|
|
38156
|
+
version: STATE_VERSION,
|
|
38157
|
+
theaters: v2.theaters ?? [],
|
|
38158
|
+
operations: v2.operations ?? [],
|
|
38159
|
+
groups: v2.groups ?? [],
|
|
38160
|
+
deletionTombstones: []
|
|
38161
|
+
};
|
|
38162
|
+
}
|
|
38157
38163
|
function migrateV1Operation(value) {
|
|
38158
38164
|
if (!isRecord5(value)) return null;
|
|
38159
38165
|
const sessionId = readNonEmptyString(value.sessionId);
|
|
@@ -38317,6 +38323,37 @@ function sanitizeOperationGroup(value) {
|
|
|
38317
38323
|
if (!VALID_GROUP_COLOR_KEYS.has(color)) return null;
|
|
38318
38324
|
return { id, theaterId, name: rawName, color, order, createdAt };
|
|
38319
38325
|
}
|
|
38326
|
+
function readDeletionTombstones(value) {
|
|
38327
|
+
if (!Array.isArray(value)) return [];
|
|
38328
|
+
const tombstones = [];
|
|
38329
|
+
for (const item of value) {
|
|
38330
|
+
const tombstone = sanitizeDeletionTombstone(item);
|
|
38331
|
+
if (tombstone) tombstones.push(tombstone);
|
|
38332
|
+
}
|
|
38333
|
+
return tombstones;
|
|
38334
|
+
}
|
|
38335
|
+
function sanitizeDeletionTombstone(value) {
|
|
38336
|
+
if (!isRecord5(value)) return null;
|
|
38337
|
+
const deletionId = readNonEmptyString(value.deletionId);
|
|
38338
|
+
const targetId = readNonEmptyString(value.targetId);
|
|
38339
|
+
const deletedAt = readFiniteNumber(value.deletedAt);
|
|
38340
|
+
const expiresAt = readFiniteNumber(value.expiresAt);
|
|
38341
|
+
if (!deletionId || !targetId || deletedAt === null || expiresAt === null) return null;
|
|
38342
|
+
if (value.kind === "operation") {
|
|
38343
|
+
const operation = sanitizeOperationNode(value.operation);
|
|
38344
|
+
if (!operation || operation.id !== targetId) return null;
|
|
38345
|
+
return { deletionId, targetId, deletedAt, expiresAt, kind: "operation", operation };
|
|
38346
|
+
}
|
|
38347
|
+
if (value.kind === "theater") {
|
|
38348
|
+
const theater = sanitizeTheaterRegistration(value.theater);
|
|
38349
|
+
if (!theater || theater.id !== targetId || !Array.isArray(value.operations) || !Array.isArray(value.groups)) return null;
|
|
38350
|
+
const operations = value.operations.map(sanitizeOperationNode).filter((operation) => operation !== null);
|
|
38351
|
+
const groups = value.groups.map(sanitizeOperationGroup).filter((group) => group !== null);
|
|
38352
|
+
if (operations.length !== value.operations.length || groups.length !== value.groups.length || operations.some((operation) => operation.theaterId !== targetId) || groups.some((group) => group.theaterId !== targetId)) return null;
|
|
38353
|
+
return { deletionId, targetId, deletedAt, expiresAt, kind: "theater", theater, operations, groups };
|
|
38354
|
+
}
|
|
38355
|
+
return null;
|
|
38356
|
+
}
|
|
38320
38357
|
|
|
38321
38358
|
// core/host/operations/sanitize.ts
|
|
38322
38359
|
var FIXED_SENSITIVE_OPERATION_FIELDS = /* @__PURE__ */ new Set([
|
|
@@ -38332,11 +38369,20 @@ var FIXED_SENSITIVE_OPERATION_FIELDS = /* @__PURE__ */ new Set([
|
|
|
38332
38369
|
]);
|
|
38333
38370
|
function createSanitizedOpDto(node, options = {}) {
|
|
38334
38371
|
const sensitiveFields = /* @__PURE__ */ new Set([...FIXED_SENSITIVE_OPERATION_FIELDS, ...options.sensitiveFields ?? []]);
|
|
38372
|
+
const payload = sanitizeRecord(node.payload, sensitiveFields);
|
|
38373
|
+
delete payload.resumeAvailable;
|
|
38374
|
+
if (isResumableProviderSession(node.payload?.providerSession)) payload.resumeAvailable = true;
|
|
38335
38375
|
return {
|
|
38336
38376
|
...node,
|
|
38337
|
-
payload
|
|
38377
|
+
payload
|
|
38338
38378
|
};
|
|
38339
38379
|
}
|
|
38380
|
+
function isResumableProviderSession(value) {
|
|
38381
|
+
if (!isRecord6(value)) return false;
|
|
38382
|
+
const provider = value.provider;
|
|
38383
|
+
const sessionId = value.sessionId;
|
|
38384
|
+
return typeof provider === "string" && provider.length > 0 && typeof sessionId === "string" && sessionId.length > 0;
|
|
38385
|
+
}
|
|
38340
38386
|
function sanitizeRecord(value, sensitiveFields) {
|
|
38341
38387
|
const output = {};
|
|
38342
38388
|
for (const [key, item] of Object.entries(value)) {
|
|
@@ -38418,6 +38464,10 @@ async function handleCollection(req, res, deps) {
|
|
|
38418
38464
|
deps.writeJson(res, 400, { error: "invalid_operation_accent" });
|
|
38419
38465
|
return;
|
|
38420
38466
|
}
|
|
38467
|
+
if (typeof body2.id === "string" && deps.isPendingDeletion?.(body2.id)) {
|
|
38468
|
+
deps.writeJson(res, 409, { error: "pending_deletion" });
|
|
38469
|
+
return;
|
|
38470
|
+
}
|
|
38421
38471
|
try {
|
|
38422
38472
|
const node = deps.store.create({
|
|
38423
38473
|
id: typeof body2.id === "string" ? body2.id : void 0,
|
|
@@ -38450,8 +38500,8 @@ async function handleItem(req, res, id, deps) {
|
|
|
38450
38500
|
return;
|
|
38451
38501
|
}
|
|
38452
38502
|
if (req.method === "DELETE") {
|
|
38453
|
-
const
|
|
38454
|
-
deps.writeJson(res,
|
|
38503
|
+
const deletion = deps.deleteOperation(id);
|
|
38504
|
+
deps.writeJson(res, 200, { ok: true, deletion });
|
|
38455
38505
|
return;
|
|
38456
38506
|
}
|
|
38457
38507
|
const body2 = await deps.readJsonBody(req);
|
|
@@ -39042,6 +39092,10 @@ function createPlansRouter(deps) {
|
|
|
39042
39092
|
await handlePlansRead(req, res, deps);
|
|
39043
39093
|
return true;
|
|
39044
39094
|
}
|
|
39095
|
+
if (pathname === "/api/v1/plans/search") {
|
|
39096
|
+
await handlePlansSearch(req, res, deps);
|
|
39097
|
+
return true;
|
|
39098
|
+
}
|
|
39045
39099
|
if (pathname === "/api/v1/plans/events") {
|
|
39046
39100
|
await handlePlansEvents(req, res, deps);
|
|
39047
39101
|
return true;
|
|
@@ -39049,6 +39103,38 @@ function createPlansRouter(deps) {
|
|
|
39049
39103
|
return false;
|
|
39050
39104
|
};
|
|
39051
39105
|
}
|
|
39106
|
+
async function handlePlansSearch(req, res, deps) {
|
|
39107
|
+
if (req.method !== "POST") {
|
|
39108
|
+
deps.writeJson(res, 405, { error: "Method not allowed" });
|
|
39109
|
+
return;
|
|
39110
|
+
}
|
|
39111
|
+
if (!deps.isAuthorized(req)) {
|
|
39112
|
+
deps.writeJson(res, 401, { error: "unauthorized" });
|
|
39113
|
+
return;
|
|
39114
|
+
}
|
|
39115
|
+
const body2 = await deps.readJsonBody(req);
|
|
39116
|
+
if (!isPlainObject2(body2) || typeof body2.theaterId !== "string" || typeof body2.query !== "string" || body2.query.trim() === "" || !Number.isInteger(body2.limit) || body2.limit < 1 || body2.limit > 8 || "relPath" in body2) {
|
|
39117
|
+
deps.writeJson(res, 400, { error: "invalid_request" });
|
|
39118
|
+
return;
|
|
39119
|
+
}
|
|
39120
|
+
const theaterPath = deps.resolveTheaterPath(body2.theaterId);
|
|
39121
|
+
if (!theaterPath) {
|
|
39122
|
+
deps.writeJson(res, 404, { error: "theater_not_found" });
|
|
39123
|
+
return;
|
|
39124
|
+
}
|
|
39125
|
+
try {
|
|
39126
|
+
const context = await resolveTheaterRoot(theaterPath);
|
|
39127
|
+
const tokens = body2.query.trim().toLocaleLowerCase().split(/\s+/).filter(Boolean);
|
|
39128
|
+
const plans = (await listPlansForWorkspace(deps.dataDir, context.realRoot)).filter((plan) => {
|
|
39129
|
+
const text = `${plan.name}
|
|
39130
|
+
${plan.title}`.toLocaleLowerCase();
|
|
39131
|
+
return tokens.every((token) => text.includes(token));
|
|
39132
|
+
}).slice(0, body2.limit).map((plan) => ({ name: plan.name, title: plan.title }));
|
|
39133
|
+
deps.writeJson(res, 200, { plans });
|
|
39134
|
+
} catch (error51) {
|
|
39135
|
+
writePlanStoreError(res, deps, error51);
|
|
39136
|
+
}
|
|
39137
|
+
}
|
|
39052
39138
|
async function handlePlansEvents(req, res, deps) {
|
|
39053
39139
|
if (req.method !== "GET") {
|
|
39054
39140
|
deps.writeJson(res, 405, { error: "Method not allowed" });
|
|
@@ -40864,7 +40950,6 @@ var SERVER_TIMEOUT_MS = 30 * 60 * 1e3;
|
|
|
40864
40950
|
var MAX_BODY_BYTES = 1024 * 1024;
|
|
40865
40951
|
var UPDATE_APPLY_FORBIDDEN_BODY_KEYS = /* @__PURE__ */ new Set(["channel", "package", "packageName", "packageVersion", "packages", "targetVersion", "version"]);
|
|
40866
40952
|
var OPERATION_RENAMED_EVENT_CHANNEL = "operation:renamed";
|
|
40867
|
-
var OPERATION_DELETED_EVENT_CHANNEL = "operation:deleted";
|
|
40868
40953
|
var PAIRING_IDENTITY_PATH = "/api/v1/pairing-identity";
|
|
40869
40954
|
var PAIRING_IDENTITY = { product: "fleet-console", schemaVersion: 1, pairingProtocolVersion: 1 };
|
|
40870
40955
|
var SERVER_API_CATALOG = [
|
|
@@ -40924,6 +41009,13 @@ var SERVER_API_CATALOG = [
|
|
|
40924
41009
|
category: "Observer",
|
|
40925
41010
|
gate: "origin-write"
|
|
40926
41011
|
},
|
|
41012
|
+
{
|
|
41013
|
+
method: "POST",
|
|
41014
|
+
path: "/api/v1/deletions/:deletionId/restore",
|
|
41015
|
+
summary: "\uC720\uC608 \uC911\uC778 Operation \uB610\uB294 Theater \uC0AD\uC81C\uB97C \uBCF5\uAD6C\uD569\uB2C8\uB2E4.",
|
|
41016
|
+
category: "Observer",
|
|
41017
|
+
gate: "origin-write"
|
|
41018
|
+
},
|
|
40927
41019
|
{
|
|
40928
41020
|
method: "POST",
|
|
40929
41021
|
path: "/api/v1/theaters/:theaterId/codex-workspace",
|
|
@@ -41051,16 +41143,29 @@ function createConsoleServer(deps = {}) {
|
|
|
41051
41143
|
function publishPluginEvent(channel2, payload) {
|
|
41052
41144
|
for (const listener of pluginEventListeners.get(channel2) ?? []) listener(payload);
|
|
41053
41145
|
}
|
|
41054
|
-
|
|
41055
|
-
|
|
41056
|
-
|
|
41057
|
-
|
|
41058
|
-
publishPluginEvent
|
|
41059
|
-
|
|
41060
|
-
|
|
41061
|
-
|
|
41062
|
-
|
|
41063
|
-
|
|
41146
|
+
const deletionCoordinator = createDeferredDeletionCoordinator({
|
|
41147
|
+
operations,
|
|
41148
|
+
theaters,
|
|
41149
|
+
save: saveDurableState,
|
|
41150
|
+
publish: publishPluginEvent,
|
|
41151
|
+
unregisterTheaterWorkspaces: (theaterId) => codex.unregisterTheaterWorkspaces(theaterId),
|
|
41152
|
+
validateTheaterRestore: async (theater) => {
|
|
41153
|
+
try {
|
|
41154
|
+
const restoredRealpath = await fs10__default.promises.realpath(theater.path);
|
|
41155
|
+
const stat4 = await fs10__default.promises.stat(restoredRealpath);
|
|
41156
|
+
if (!stat4.isDirectory() || restoredRealpath !== theater.realpath || workspaceHash(restoredRealpath) !== theater.id) {
|
|
41157
|
+
throw new Error("restore_conflict");
|
|
41158
|
+
}
|
|
41159
|
+
} catch {
|
|
41160
|
+
throw new DeferredDeletionError(409, "restore_parent_missing");
|
|
41161
|
+
}
|
|
41162
|
+
},
|
|
41163
|
+
registerTheaterWorkspace: async (theater) => {
|
|
41164
|
+
await codex.registerWorkspace(theater.realpath, theater.lastOpenedAt, theater.id);
|
|
41165
|
+
}
|
|
41166
|
+
});
|
|
41167
|
+
function deleteOperationForPlugin(operationId) {
|
|
41168
|
+
return deletionCoordinator.deleteOperation(operationId) !== null;
|
|
41064
41169
|
}
|
|
41065
41170
|
let desktopFullscreen = false;
|
|
41066
41171
|
let unsubscribeUpdateCheckChanges = updateCheck.onChange?.(() => {
|
|
@@ -41071,6 +41176,7 @@ function createConsoleServer(deps = {}) {
|
|
|
41071
41176
|
list: () => operations.list(),
|
|
41072
41177
|
get: (id) => operations.get(id),
|
|
41073
41178
|
create: (input) => {
|
|
41179
|
+
if (input.id && deletionCoordinator.hasPendingOperation(input.id)) throw new Error("pending_deletion");
|
|
41074
41180
|
const operation = operations.create(input);
|
|
41075
41181
|
persistDurableState();
|
|
41076
41182
|
return operation;
|
|
@@ -41086,7 +41192,7 @@ function createConsoleServer(deps = {}) {
|
|
|
41086
41192
|
}
|
|
41087
41193
|
return operation;
|
|
41088
41194
|
},
|
|
41089
|
-
delete:
|
|
41195
|
+
delete: deleteOperationForPlugin,
|
|
41090
41196
|
registerOperationType: (type) => {
|
|
41091
41197
|
pluginOperationTypes.add(type);
|
|
41092
41198
|
return () => {
|
|
@@ -41300,7 +41406,8 @@ function createConsoleServer(deps = {}) {
|
|
|
41300
41406
|
readJsonBody,
|
|
41301
41407
|
writeJson,
|
|
41302
41408
|
persist: persistDurableState,
|
|
41303
|
-
deleteOperation,
|
|
41409
|
+
deleteOperation: (operationId) => deletionCoordinator.deleteOperation(operationId),
|
|
41410
|
+
isPendingDeletion: (operationId) => deletionCoordinator.hasPendingOperation(operationId),
|
|
41304
41411
|
getPluginSensitiveFields: (pluginId) => [
|
|
41305
41412
|
...pluginHost.sensitiveFieldsByPluginId.get(pluginId) ?? [],
|
|
41306
41413
|
...pluginPayloadSanitizers.get(pluginId) ?? []
|
|
@@ -41390,6 +41497,11 @@ function createConsoleServer(deps = {}) {
|
|
|
41390
41497
|
runAsyncBooleanHandler(plansRouter({ req, res, pathname }), res, () => false);
|
|
41391
41498
|
return;
|
|
41392
41499
|
}
|
|
41500
|
+
const restoreMatch = pathname.match(/^\/api\/v1\/deletions\/([^/]+)\/restore$/);
|
|
41501
|
+
if (restoreMatch) {
|
|
41502
|
+
runAsyncHandler(handleDeferredDeletionRestore(req, res, decodeURIComponent(restoreMatch[1] ?? "")), res);
|
|
41503
|
+
return;
|
|
41504
|
+
}
|
|
41393
41505
|
const theaterItemMatch = pathname.match(/^\/api\/v1\/theaters\/([^/]+)$/);
|
|
41394
41506
|
if (theaterItemMatch) {
|
|
41395
41507
|
runAsyncHandler(handleObserverTheaterItem(req, res, decodeURIComponent(theaterItemMatch[1] ?? "")), res);
|
|
@@ -41537,6 +41649,11 @@ function createConsoleServer(deps = {}) {
|
|
|
41537
41649
|
writeJson(res, 400, { error: "invalid_folder_grant" });
|
|
41538
41650
|
return;
|
|
41539
41651
|
}
|
|
41652
|
+
const canonicalCwd = canonicalizeTheaterPathSync(cwd);
|
|
41653
|
+
if (deletionCoordinator.hasPendingTheater(workspaceHash(canonicalCwd))) {
|
|
41654
|
+
writeJson(res, 409, { error: "pending_deletion" });
|
|
41655
|
+
return;
|
|
41656
|
+
}
|
|
41540
41657
|
const theater = await theaters.register(cwd);
|
|
41541
41658
|
await codex.registerWorkspace(theater.realpath, void 0, theater.id);
|
|
41542
41659
|
persistDurableState();
|
|
@@ -41566,12 +41683,27 @@ function createConsoleServer(deps = {}) {
|
|
|
41566
41683
|
writeJson(res, 200, toTheaterInfo(theater, true));
|
|
41567
41684
|
return;
|
|
41568
41685
|
}
|
|
41569
|
-
|
|
41570
|
-
|
|
41571
|
-
|
|
41572
|
-
|
|
41573
|
-
|
|
41574
|
-
|
|
41686
|
+
const deletion = deletionCoordinator.deleteTheater(theaterId);
|
|
41687
|
+
writeJson(res, 200, { ok: true, deletion });
|
|
41688
|
+
}
|
|
41689
|
+
async function handleDeferredDeletionRestore(req, res, deletionId) {
|
|
41690
|
+
if (req.method !== "POST") {
|
|
41691
|
+
writeJson(res, 405, { error: "Method not allowed" });
|
|
41692
|
+
return;
|
|
41693
|
+
}
|
|
41694
|
+
if (!isTerminalAuthorized(req)) {
|
|
41695
|
+
writeJson(res, 401, { error: "unauthorized" });
|
|
41696
|
+
return;
|
|
41697
|
+
}
|
|
41698
|
+
try {
|
|
41699
|
+
writeJson(res, 200, await deletionCoordinator.restore(deletionId));
|
|
41700
|
+
} catch (error51) {
|
|
41701
|
+
if (error51 instanceof DeferredDeletionError) {
|
|
41702
|
+
writeJson(res, error51.status, { error: error51.message });
|
|
41703
|
+
return;
|
|
41704
|
+
}
|
|
41705
|
+
throw error51;
|
|
41706
|
+
}
|
|
41575
41707
|
}
|
|
41576
41708
|
function handleStatus(req, res) {
|
|
41577
41709
|
const theaterId = readUrl(req).searchParams.get("theaterId");
|
|
@@ -41788,6 +41920,12 @@ function createConsoleServer(deps = {}) {
|
|
|
41788
41920
|
operations.replace([]);
|
|
41789
41921
|
operations.replaceGroups([]);
|
|
41790
41922
|
}
|
|
41923
|
+
deletionCoordinator.load(state.deletionTombstones ?? []);
|
|
41924
|
+
try {
|
|
41925
|
+
deletionCoordinator.sweepExpired();
|
|
41926
|
+
} catch (error51) {
|
|
41927
|
+
console.warn(`[fleet-console] Expired deletion sweep deferred: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
41928
|
+
}
|
|
41791
41929
|
await restoreCodexWorkspaces();
|
|
41792
41930
|
}
|
|
41793
41931
|
async function restoreCodexWorkspaces() {
|
|
@@ -41829,16 +41967,20 @@ function createConsoleServer(deps = {}) {
|
|
|
41829
41967
|
}
|
|
41830
41968
|
function persistDurableState() {
|
|
41831
41969
|
try {
|
|
41832
|
-
|
|
41833
|
-
version: 2,
|
|
41834
|
-
theaters: theaters.list(),
|
|
41835
|
-
operations: operations.list(),
|
|
41836
|
-
groups: operations.listAllGroups()
|
|
41837
|
-
});
|
|
41970
|
+
saveDurableState(deletionCoordinator.list());
|
|
41838
41971
|
} catch (error51) {
|
|
41839
41972
|
console.warn(`[fleet-console] Durable state save failed: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
41840
41973
|
}
|
|
41841
41974
|
}
|
|
41975
|
+
function saveDurableState(deletionTombstones) {
|
|
41976
|
+
durableStateStore.save({
|
|
41977
|
+
version: STATE_VERSION,
|
|
41978
|
+
theaters: theaters.list(),
|
|
41979
|
+
operations: operations.list(),
|
|
41980
|
+
groups: operations.listAllGroups(),
|
|
41981
|
+
deletionTombstones
|
|
41982
|
+
});
|
|
41983
|
+
}
|
|
41842
41984
|
async function stopServer() {
|
|
41843
41985
|
const current = server;
|
|
41844
41986
|
const currentLoopback = loopbackServer;
|
|
@@ -41848,6 +41990,7 @@ function createConsoleServer(deps = {}) {
|
|
|
41848
41990
|
lockHandle = null;
|
|
41849
41991
|
activeLockFile = null;
|
|
41850
41992
|
activeEndpoint = null;
|
|
41993
|
+
deletionCoordinator.dispose();
|
|
41851
41994
|
try {
|
|
41852
41995
|
await Promise.all([
|
|
41853
41996
|
closeHttpServer(current),
|