@agentconnect.md/codex-acp 1.11.0-agentconnect.1 → 1.12.0-agentconnect.2
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/index.js +747 -721
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -22782,6 +22782,111 @@ function reversePatch(structuredPatch) {
|
|
|
22782
22782
|
return reversed;
|
|
22783
22783
|
}
|
|
22784
22784
|
|
|
22785
|
+
// src/DiffStats.ts
|
|
22786
|
+
var DiffStatsCalculator = class {
|
|
22787
|
+
addedFile(text) {
|
|
22788
|
+
return { version: 1, added: this.lineCount(text), removed: 0 };
|
|
22789
|
+
}
|
|
22790
|
+
deletedFile(text) {
|
|
22791
|
+
return { version: 1, added: 0, removed: this.lineCount(text) };
|
|
22792
|
+
}
|
|
22793
|
+
update(patch) {
|
|
22794
|
+
if (patch.isBinary || patch.hunks.length === 0) return null;
|
|
22795
|
+
let added = 0;
|
|
22796
|
+
let removed = 0;
|
|
22797
|
+
let previousOldEnd = 1;
|
|
22798
|
+
let previousNewEnd = 1;
|
|
22799
|
+
for (const hunk of patch.hunks) {
|
|
22800
|
+
const { oldStart, oldLines, newStart, newLines } = hunk;
|
|
22801
|
+
if (![oldStart, oldLines, newStart, newLines].every(Number.isSafeInteger) || oldStart < previousOldEnd || newStart < previousNewEnd || oldLines < 0 || newLines < 0 || newStart - oldStart !== added - removed) return null;
|
|
22802
|
+
let oldConsumed = 0;
|
|
22803
|
+
let newConsumed = 0;
|
|
22804
|
+
let previousWasContent = false;
|
|
22805
|
+
for (const line of hunk.lines) {
|
|
22806
|
+
switch (line[0]) {
|
|
22807
|
+
case "+":
|
|
22808
|
+
added++;
|
|
22809
|
+
newConsumed++;
|
|
22810
|
+
previousWasContent = true;
|
|
22811
|
+
break;
|
|
22812
|
+
case "-":
|
|
22813
|
+
removed++;
|
|
22814
|
+
oldConsumed++;
|
|
22815
|
+
previousWasContent = true;
|
|
22816
|
+
break;
|
|
22817
|
+
case " ":
|
|
22818
|
+
case void 0:
|
|
22819
|
+
oldConsumed++;
|
|
22820
|
+
newConsumed++;
|
|
22821
|
+
previousWasContent = true;
|
|
22822
|
+
break;
|
|
22823
|
+
case "\\":
|
|
22824
|
+
if (!previousWasContent || line.replace(/\r$/, "") !== "\") return null;
|
|
22825
|
+
previousWasContent = false;
|
|
22826
|
+
break;
|
|
22827
|
+
default:
|
|
22828
|
+
return null;
|
|
22829
|
+
}
|
|
22830
|
+
}
|
|
22831
|
+
if (oldConsumed !== oldLines || newConsumed !== newLines) return null;
|
|
22832
|
+
previousOldEnd = oldStart + oldLines;
|
|
22833
|
+
previousNewEnd = newStart + newLines;
|
|
22834
|
+
}
|
|
22835
|
+
return { version: 1, added, removed };
|
|
22836
|
+
}
|
|
22837
|
+
lineCount(text) {
|
|
22838
|
+
let count = 0;
|
|
22839
|
+
for (let offset = text.indexOf("\n"); offset >= 0; offset = text.indexOf("\n", offset + 1)) count++;
|
|
22840
|
+
for (let offset = text.indexOf("\r"); offset >= 0; offset = text.indexOf("\r", offset + 1)) {
|
|
22841
|
+
if (text[offset + 1] !== "\n") count++;
|
|
22842
|
+
}
|
|
22843
|
+
if (text.length > 0 && !text.endsWith("\n") && !text.endsWith("\r")) count++;
|
|
22844
|
+
return count;
|
|
22845
|
+
}
|
|
22846
|
+
};
|
|
22847
|
+
|
|
22848
|
+
// src/AirExtension.ts
|
|
22849
|
+
var JETBRAINS_META_KEY = "jetbrains";
|
|
22850
|
+
var AIR_META_KEY = "air";
|
|
22851
|
+
var AIR_EXTENSION_VERSION_KEY = "version";
|
|
22852
|
+
var AIR_EXTENSION_CAPABILITIES_KEY = "capabilities";
|
|
22853
|
+
var AIR_DIFF_STATS_KEY = "diffStats";
|
|
22854
|
+
var AIR_SESSION_FAILURE_KEY = "sessionFailure";
|
|
22855
|
+
var AIR_AGENT_FILE_CHANGE_REPORT_KEY = "agentFileChangeReport";
|
|
22856
|
+
var AIR_NATIVE_SUBAGENT_SESSIONS_KEY = "nativeSubagentSessions";
|
|
22857
|
+
var AIR_ASYNC_TASKS_KEY = "asyncTasks";
|
|
22858
|
+
var AIR_RECOMMENDED_CONFIG_VALUE_KEY = "recommendedValue";
|
|
22859
|
+
var AIR_ASYNC_TASKS_BACKGROUNDED_KEY = "backgrounded";
|
|
22860
|
+
var AIR_AGENT_FILE_CHANGE_REPORT_REQUEST_KEY = "agentFileChangeReportRequest";
|
|
22861
|
+
var AIR_EXTENSION_VERSION = 1;
|
|
22862
|
+
function withAirMeta(meta3, key, value) {
|
|
22863
|
+
const root = asRecord(meta3);
|
|
22864
|
+
const jetbrains = asRecord(root[JETBRAINS_META_KEY]);
|
|
22865
|
+
const air = asRecord(jetbrains[AIR_META_KEY]);
|
|
22866
|
+
return {
|
|
22867
|
+
...root,
|
|
22868
|
+
[JETBRAINS_META_KEY]: {
|
|
22869
|
+
...jetbrains,
|
|
22870
|
+
[AIR_META_KEY]: {
|
|
22871
|
+
...air,
|
|
22872
|
+
[AIR_EXTENSION_VERSION_KEY]: AIR_EXTENSION_VERSION,
|
|
22873
|
+
[key]: value
|
|
22874
|
+
}
|
|
22875
|
+
}
|
|
22876
|
+
};
|
|
22877
|
+
}
|
|
22878
|
+
function clientSupportsAirCapability(capabilities, capability) {
|
|
22879
|
+
const meta3 = asRecord(capabilities?._meta);
|
|
22880
|
+
const jetbrains = asRecord(meta3[JETBRAINS_META_KEY]);
|
|
22881
|
+
const air = asRecord(jetbrains[AIR_META_KEY]);
|
|
22882
|
+
const version2 = air[AIR_EXTENSION_VERSION_KEY];
|
|
22883
|
+
const supported = air[AIR_EXTENSION_CAPABILITIES_KEY];
|
|
22884
|
+
return typeof version2 === "number" && Number.isInteger(version2) && version2 >= AIR_EXTENSION_VERSION && Array.isArray(supported) && supported.includes(capability);
|
|
22885
|
+
}
|
|
22886
|
+
function asRecord(value) {
|
|
22887
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
22888
|
+
}
|
|
22889
|
+
|
|
22785
22890
|
// src/CodexToolCallMapper.ts
|
|
22786
22891
|
import { readFile } from "node:fs/promises";
|
|
22787
22892
|
import path2 from "node:path";
|
|
@@ -22834,8 +22939,26 @@ function createContextCompactionMeta(metadata = {}) {
|
|
|
22834
22939
|
};
|
|
22835
22940
|
}
|
|
22836
22941
|
|
|
22942
|
+
// src/ToolCallName.ts
|
|
22943
|
+
function functionToolName(name, namespace) {
|
|
22944
|
+
return `${namespace ?? ""}${name}`;
|
|
22945
|
+
}
|
|
22946
|
+
function commandToolName(source) {
|
|
22947
|
+
switch (source) {
|
|
22948
|
+
case "unifiedExecStartup":
|
|
22949
|
+
return "exec_command";
|
|
22950
|
+
case "unifiedExecInteraction":
|
|
22951
|
+
return "write_stdin";
|
|
22952
|
+
// These sources do not identify a unique model tool.
|
|
22953
|
+
case "agent":
|
|
22954
|
+
case "userShell":
|
|
22955
|
+
return void 0;
|
|
22956
|
+
}
|
|
22957
|
+
}
|
|
22958
|
+
|
|
22837
22959
|
// src/CodexToolCallMapper.ts
|
|
22838
22960
|
var CONTEXT_COMPACTION_META = createContextCompactionMeta();
|
|
22961
|
+
var DIFF_STATS = new DiffStatsCalculator();
|
|
22839
22962
|
function toAcpStatus(status) {
|
|
22840
22963
|
switch (status) {
|
|
22841
22964
|
case "inProgress":
|
|
@@ -22864,14 +22987,19 @@ async function createFileChangeUpdate(item) {
|
|
|
22864
22987
|
};
|
|
22865
22988
|
}
|
|
22866
22989
|
async function createCommandExecutionUpdate(item) {
|
|
22990
|
+
const name = commandToolName(item.source);
|
|
22867
22991
|
const commandAction = item.commandActions.length === 1 ? item.commandActions[0] : void 0;
|
|
22868
22992
|
if (commandAction) {
|
|
22869
|
-
return
|
|
22993
|
+
return {
|
|
22994
|
+
...createCommandActionEvent(item.id, item.status, item.cwd, commandAction),
|
|
22995
|
+
...name === void 0 ? {} : { name }
|
|
22996
|
+
};
|
|
22870
22997
|
}
|
|
22871
22998
|
const command = stripShellPrefix(item.command);
|
|
22872
22999
|
return createTerminalCommandEvent({
|
|
22873
23000
|
sessionUpdate: "tool_call",
|
|
22874
23001
|
toolCallId: item.id,
|
|
23002
|
+
...name === void 0 ? {} : { name },
|
|
22875
23003
|
kind: "execute",
|
|
22876
23004
|
title: command,
|
|
22877
23005
|
status: toAcpStatus(item.status),
|
|
@@ -22926,7 +23054,10 @@ async function createMcpToolCallUpdate(item) {
|
|
|
22926
23054
|
};
|
|
22927
23055
|
}
|
|
22928
23056
|
async function createDynamicToolCallUpdate(item) {
|
|
22929
|
-
return
|
|
23057
|
+
return {
|
|
23058
|
+
...await createExecuteToolCallUpdate(item, item.tool, { arguments: item.arguments }),
|
|
23059
|
+
name: functionToolName(item.tool, item.namespace)
|
|
23060
|
+
};
|
|
22930
23061
|
}
|
|
22931
23062
|
function createImageViewUpdate(item) {
|
|
22932
23063
|
const displayPath = item.path;
|
|
@@ -22934,6 +23065,7 @@ function createImageViewUpdate(item) {
|
|
|
22934
23065
|
sessionUpdate: "tool_call",
|
|
22935
23066
|
toolCallId: item.id,
|
|
22936
23067
|
kind: "read",
|
|
23068
|
+
name: "view_image",
|
|
22937
23069
|
title: `View Image ${displayPath}`,
|
|
22938
23070
|
status: "completed",
|
|
22939
23071
|
content: [createContent({
|
|
@@ -23491,53 +23623,43 @@ async function createAddFileContent(change) {
|
|
|
23491
23623
|
newText: change.diff,
|
|
23492
23624
|
// app-server always returns file content instead of diff
|
|
23493
23625
|
path: change.path,
|
|
23494
|
-
_meta: {
|
|
23495
|
-
kind: "add"
|
|
23496
|
-
}
|
|
23626
|
+
_meta: withAirMeta({ kind: "add" }, AIR_DIFF_STATS_KEY, DIFF_STATS.addedFile(change.diff))
|
|
23497
23627
|
};
|
|
23498
23628
|
}
|
|
23499
23629
|
async function createUpdateFileContent(change) {
|
|
23500
23630
|
if (change.kind.type !== "update") return null;
|
|
23501
23631
|
const unifiedDiff = recoverCorruptedDiff(change.diff);
|
|
23632
|
+
const patches = parsePatch(unifiedDiff);
|
|
23633
|
+
if (patches.length !== 1) return null;
|
|
23634
|
+
const patch = patches[0];
|
|
23502
23635
|
const movePath = change.kind.move_path;
|
|
23503
23636
|
const oldContent = await readFileContent(change.path);
|
|
23504
23637
|
if (oldContent !== null) {
|
|
23505
|
-
const patchedContent = applyPatch(oldContent,
|
|
23638
|
+
const patchedContent = applyPatch(oldContent, patch);
|
|
23506
23639
|
if (patchedContent === false) {
|
|
23507
|
-
const
|
|
23508
|
-
if (
|
|
23509
|
-
|
|
23510
|
-
if (revertedContent2 !== false) {
|
|
23511
|
-
return createUpdateDiffContent(change.path, revertedContent2, oldContent);
|
|
23512
|
-
}
|
|
23640
|
+
const revertedContent2 = applyPatch(oldContent, reversePatch(patch));
|
|
23641
|
+
if (revertedContent2 !== false) {
|
|
23642
|
+
return createUpdateDiffContent(change.path, revertedContent2, oldContent, patch);
|
|
23513
23643
|
}
|
|
23514
23644
|
return null;
|
|
23515
23645
|
}
|
|
23516
|
-
return createUpdateDiffContent(movePath ?? change.path, oldContent, patchedContent);
|
|
23646
|
+
return createUpdateDiffContent(movePath ?? change.path, oldContent, patchedContent, patch);
|
|
23517
23647
|
}
|
|
23518
23648
|
if (!movePath) return null;
|
|
23519
23649
|
const newContent = await readFileContent(movePath);
|
|
23520
23650
|
if (newContent === null) return null;
|
|
23521
|
-
const
|
|
23522
|
-
if (!revertedPatch) return null;
|
|
23523
|
-
const revertedContent = applyPatch(newContent, revertedPatch);
|
|
23651
|
+
const revertedContent = applyPatch(newContent, reversePatch(patch));
|
|
23524
23652
|
if (revertedContent === false) return null;
|
|
23525
|
-
return createUpdateDiffContent(movePath, revertedContent, newContent);
|
|
23526
|
-
}
|
|
23527
|
-
function revertPatch(unifiedDiff) {
|
|
23528
|
-
const [patch] = parsePatch(unifiedDiff);
|
|
23529
|
-
if (!patch) return null;
|
|
23530
|
-
return reversePatch(patch);
|
|
23653
|
+
return createUpdateDiffContent(movePath, revertedContent, newContent, patch);
|
|
23531
23654
|
}
|
|
23532
|
-
function createUpdateDiffContent(path9, oldText, newText) {
|
|
23655
|
+
function createUpdateDiffContent(path9, oldText, newText, patch) {
|
|
23656
|
+
const stats = DIFF_STATS.update(patch);
|
|
23533
23657
|
return {
|
|
23534
23658
|
type: "diff",
|
|
23535
23659
|
oldText,
|
|
23536
23660
|
newText,
|
|
23537
23661
|
path: path9,
|
|
23538
|
-
_meta: {
|
|
23539
|
-
kind: "update"
|
|
23540
|
-
}
|
|
23662
|
+
_meta: stats ? withAirMeta({ kind: "update" }, AIR_DIFF_STATS_KEY, stats) : { kind: "update" }
|
|
23541
23663
|
};
|
|
23542
23664
|
}
|
|
23543
23665
|
async function createDeleteFileContent(change) {
|
|
@@ -23547,9 +23669,7 @@ async function createDeleteFileContent(change) {
|
|
|
23547
23669
|
// app-server always returns file content instead of diff
|
|
23548
23670
|
newText: "",
|
|
23549
23671
|
path: change.path,
|
|
23550
|
-
_meta: {
|
|
23551
|
-
kind: "delete"
|
|
23552
|
-
}
|
|
23672
|
+
_meta: withAirMeta({ kind: "delete" }, AIR_DIFF_STATS_KEY, DIFF_STATS.deletedFile(change.diff))
|
|
23553
23673
|
};
|
|
23554
23674
|
}
|
|
23555
23675
|
async function readFileContent(filePath) {
|
|
@@ -23661,47 +23781,6 @@ function sameThreadGoalSnapshot(left, right) {
|
|
|
23661
23781
|
// src/CodexEventHandler.ts
|
|
23662
23782
|
import { randomUUID } from "node:crypto";
|
|
23663
23783
|
|
|
23664
|
-
// src/AirExtension.ts
|
|
23665
|
-
var JETBRAINS_META_KEY = "jetbrains";
|
|
23666
|
-
var AIR_META_KEY = "air";
|
|
23667
|
-
var AIR_EXTENSION_VERSION_KEY = "version";
|
|
23668
|
-
var AIR_EXTENSION_CAPABILITIES_KEY = "capabilities";
|
|
23669
|
-
var AIR_SESSION_FAILURE_KEY = "sessionFailure";
|
|
23670
|
-
var AIR_AGENT_FILE_CHANGE_REPORT_KEY = "agentFileChangeReport";
|
|
23671
|
-
var AIR_NATIVE_SUBAGENT_SESSIONS_KEY = "nativeSubagentSessions";
|
|
23672
|
-
var AIR_ASYNC_TASKS_KEY = "asyncTasks";
|
|
23673
|
-
var AIR_RECOMMENDED_CONFIG_VALUE_KEY = "recommendedValue";
|
|
23674
|
-
var AIR_ASYNC_TASKS_BACKGROUNDED_KEY = "backgrounded";
|
|
23675
|
-
var AIR_AGENT_FILE_CHANGE_REPORT_REQUEST_KEY = "agentFileChangeReportRequest";
|
|
23676
|
-
var AIR_EXTENSION_VERSION = 1;
|
|
23677
|
-
function withAirMeta(meta3, key, value) {
|
|
23678
|
-
const root = asRecord(meta3);
|
|
23679
|
-
const jetbrains = asRecord(root[JETBRAINS_META_KEY]);
|
|
23680
|
-
const air = asRecord(jetbrains[AIR_META_KEY]);
|
|
23681
|
-
return {
|
|
23682
|
-
...root,
|
|
23683
|
-
[JETBRAINS_META_KEY]: {
|
|
23684
|
-
...jetbrains,
|
|
23685
|
-
[AIR_META_KEY]: {
|
|
23686
|
-
...air,
|
|
23687
|
-
[AIR_EXTENSION_VERSION_KEY]: AIR_EXTENSION_VERSION,
|
|
23688
|
-
[key]: value
|
|
23689
|
-
}
|
|
23690
|
-
}
|
|
23691
|
-
};
|
|
23692
|
-
}
|
|
23693
|
-
function clientSupportsAirCapability(capabilities, capability) {
|
|
23694
|
-
const meta3 = asRecord(capabilities?._meta);
|
|
23695
|
-
const jetbrains = asRecord(meta3[JETBRAINS_META_KEY]);
|
|
23696
|
-
const air = asRecord(jetbrains[AIR_META_KEY]);
|
|
23697
|
-
const version2 = air[AIR_EXTENSION_VERSION_KEY];
|
|
23698
|
-
const supported = air[AIR_EXTENSION_CAPABILITIES_KEY];
|
|
23699
|
-
return typeof version2 === "number" && Number.isInteger(version2) && version2 >= AIR_EXTENSION_VERSION && Array.isArray(supported) && supported.includes(capability);
|
|
23700
|
-
}
|
|
23701
|
-
function asRecord(value) {
|
|
23702
|
-
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
23703
|
-
}
|
|
23704
|
-
|
|
23705
23784
|
// src/subagents/CodexAgentPath.ts
|
|
23706
23785
|
function normalizeAgentPath(path9) {
|
|
23707
23786
|
const normalized = path9.trim().replace(/\/+$/, "");
|
|
@@ -24095,40 +24174,339 @@ function terminalStateFromTurn(status) {
|
|
|
24095
24174
|
return void 0;
|
|
24096
24175
|
}
|
|
24097
24176
|
}
|
|
24098
|
-
function fallbackName(sessionId) {
|
|
24099
|
-
const suffix = sessionId.length > 8 ? sessionId.slice(-8) : sessionId;
|
|
24100
|
-
return `Agent ${suffix}`;
|
|
24177
|
+
function fallbackName(sessionId) {
|
|
24178
|
+
const suffix = sessionId.length > 8 ? sessionId.slice(-8) : sessionId;
|
|
24179
|
+
return `Agent ${suffix}`;
|
|
24180
|
+
}
|
|
24181
|
+
|
|
24182
|
+
// src/RateLimitsMap.ts
|
|
24183
|
+
function rateLimitId(snapshot, fallback = "codex") {
|
|
24184
|
+
return snapshot.limitId ?? fallback;
|
|
24185
|
+
}
|
|
24186
|
+
function createRateLimitsMap(response) {
|
|
24187
|
+
const result = /* @__PURE__ */ new Map();
|
|
24188
|
+
const snapshots = Object.entries(response.rateLimitsByLimitId ?? {}).filter((entry) => entry[1] !== void 0);
|
|
24189
|
+
if (snapshots.length === 0) {
|
|
24190
|
+
snapshots.push([rateLimitId(response.rateLimits), response.rateLimits]);
|
|
24191
|
+
}
|
|
24192
|
+
for (const [fallbackId, snapshot] of snapshots) {
|
|
24193
|
+
const limitId = rateLimitId(snapshot, fallbackId);
|
|
24194
|
+
result.set(limitId, {
|
|
24195
|
+
limitId,
|
|
24196
|
+
limitName: snapshot.limitName ?? limitId,
|
|
24197
|
+
snapshot
|
|
24198
|
+
});
|
|
24199
|
+
}
|
|
24200
|
+
return result;
|
|
24201
|
+
}
|
|
24202
|
+
function mergeRateLimitSnapshot(previous, update) {
|
|
24203
|
+
return {
|
|
24204
|
+
...update,
|
|
24205
|
+
limitId: update.limitId ?? "codex",
|
|
24206
|
+
credits: update.credits ?? previous.credits,
|
|
24207
|
+
individualLimit: update.individualLimit ?? previous.individualLimit,
|
|
24208
|
+
spendControlReached: update.spendControlReached ?? previous.spendControlReached,
|
|
24209
|
+
planType: update.planType ?? previous.planType
|
|
24210
|
+
};
|
|
24211
|
+
}
|
|
24212
|
+
|
|
24213
|
+
// src/AgentFileChangeReport.ts
|
|
24214
|
+
import fs2 from "node:fs";
|
|
24215
|
+
import path3 from "node:path";
|
|
24216
|
+
var AGENT_FILE_CHANGE_REPORT_VERSION = 1;
|
|
24217
|
+
var AGENT_FILE_CHANGE_REPORT_MAX_PATHS = 1024;
|
|
24218
|
+
var AGENT_FILE_CHANGE_REPORT_MAX_PATH_LENGTH = 4096;
|
|
24219
|
+
var AGENT_FILE_CHANGE_REPORT_MAX_TOTAL_BYTES = 256 * 1024;
|
|
24220
|
+
var AGENT_FILE_CHANGE_REPORT_MAX_DIFF_BYTES = 8 * 1024 * 1024;
|
|
24221
|
+
var TURN_DIFF_UNCERTAINTY = "Codex turn diffs may omit same-content renames and changes made outside apply_patch, including shell commands, version-control commands, generators, and child processes.";
|
|
24222
|
+
function captureAgentFileChangeWorkspace(cwd, additionalDirectories) {
|
|
24223
|
+
const lexicalCwd = parseWorkspaceRoot(cwd);
|
|
24224
|
+
return {
|
|
24225
|
+
cwd,
|
|
24226
|
+
additionalDirectories: [...additionalDirectories],
|
|
24227
|
+
diffRoot: lexicalCwd === null ? cwd : findDiffDisplayRoot(lexicalCwd).value
|
|
24228
|
+
};
|
|
24229
|
+
}
|
|
24230
|
+
function parseAgentFileChangeReportRequest(meta3) {
|
|
24231
|
+
const jetbrains = asRecord2(meta3?.[JETBRAINS_META_KEY]);
|
|
24232
|
+
const air = asRecord2(jetbrains?.[AIR_META_KEY]);
|
|
24233
|
+
const request = asRecord2(air?.[AIR_AGENT_FILE_CHANGE_REPORT_REQUEST_KEY]);
|
|
24234
|
+
if (request === null || !hasOnlyKeys(request, ["version", "requestId"]) || request["version"] !== AGENT_FILE_CHANGE_REPORT_VERSION) {
|
|
24235
|
+
return null;
|
|
24236
|
+
}
|
|
24237
|
+
const requestId = request["requestId"];
|
|
24238
|
+
if (typeof requestId !== "string" || !/^[A-Za-z0-9._:-]{1,128}$/.test(requestId)) {
|
|
24239
|
+
return null;
|
|
24240
|
+
}
|
|
24241
|
+
return { version: AGENT_FILE_CHANGE_REPORT_VERSION, requestId };
|
|
24242
|
+
}
|
|
24243
|
+
function createReportedAgentFileChangeReport(requestId, diff, workspace) {
|
|
24244
|
+
if (Buffer.byteLength(diff, "utf8") > AGENT_FILE_CHANGE_REPORT_MAX_DIFF_BYTES) {
|
|
24245
|
+
throw new AgentFileChangeReportError("invalidOutput", "The turn diff exceeds the parser input limit");
|
|
24246
|
+
}
|
|
24247
|
+
const parsedReport = parseTurnDiff(diff);
|
|
24248
|
+
const normalized = normalizeFileChangeReport(parsedReport, workspace);
|
|
24249
|
+
return fitReportedAgentFileChangeReport({
|
|
24250
|
+
version: AGENT_FILE_CHANGE_REPORT_VERSION,
|
|
24251
|
+
requestId,
|
|
24252
|
+
status: "reported",
|
|
24253
|
+
...normalized
|
|
24254
|
+
});
|
|
24255
|
+
}
|
|
24256
|
+
function createUnavailableAgentFileChangeReport(requestId, reason) {
|
|
24257
|
+
return {
|
|
24258
|
+
version: AGENT_FILE_CHANGE_REPORT_VERSION,
|
|
24259
|
+
requestId,
|
|
24260
|
+
status: "unavailable",
|
|
24261
|
+
reason
|
|
24262
|
+
};
|
|
24263
|
+
}
|
|
24264
|
+
var AgentFileChangeReportError = class extends Error {
|
|
24265
|
+
reason;
|
|
24266
|
+
constructor(reason, message) {
|
|
24267
|
+
super(message);
|
|
24268
|
+
this.name = "AgentFileChangeReportError";
|
|
24269
|
+
this.reason = reason;
|
|
24270
|
+
}
|
|
24271
|
+
};
|
|
24272
|
+
function parseTurnDiff(diff) {
|
|
24273
|
+
if (diff.trim() === "") {
|
|
24274
|
+
return { paths: [], complete: false, uncertainty: TURN_DIFF_UNCERTAINTY };
|
|
24275
|
+
}
|
|
24276
|
+
let patches;
|
|
24277
|
+
try {
|
|
24278
|
+
patches = parsePatch(diff);
|
|
24279
|
+
} catch (error51) {
|
|
24280
|
+
throw new AgentFileChangeReportError(
|
|
24281
|
+
"invalidOutput",
|
|
24282
|
+
`The turn diff is not valid unified diff: ${error51 instanceof Error ? error51.message : String(error51)}`
|
|
24283
|
+
);
|
|
24284
|
+
}
|
|
24285
|
+
if (patches.length === 0) {
|
|
24286
|
+
throw new AgentFileChangeReportError("invalidOutput", "The turn diff contains no parseable file patches");
|
|
24287
|
+
}
|
|
24288
|
+
const rawFileHeaders = extractRawFileHeaders(diff);
|
|
24289
|
+
const paths = [];
|
|
24290
|
+
for (const [index, patch] of patches.entries()) {
|
|
24291
|
+
const rawHeaders = rawFileHeaders[index];
|
|
24292
|
+
const oldPath = normalizeDiffPath(selectLosslessFileName(rawHeaders?.oldFileName, patch.oldFileName));
|
|
24293
|
+
const newPath = normalizeDiffPath(selectLosslessFileName(rawHeaders?.newFileName, patch.newFileName));
|
|
24294
|
+
if (oldPath === null && newPath === null) {
|
|
24295
|
+
throw new AgentFileChangeReportError("invalidOutput", "The turn diff contains a patch without a file path");
|
|
24296
|
+
}
|
|
24297
|
+
if (oldPath !== null) paths.push(oldPath);
|
|
24298
|
+
if (newPath !== null) paths.push(newPath);
|
|
24299
|
+
}
|
|
24300
|
+
return { paths, complete: false, uncertainty: TURN_DIFF_UNCERTAINTY };
|
|
24301
|
+
}
|
|
24302
|
+
function extractRawFileHeaders(diff) {
|
|
24303
|
+
return diff.split(/(?=^diff --git )/m).filter((section) => section.trim() !== "").map((section) => {
|
|
24304
|
+
const lines = section.split(/\r?\n/);
|
|
24305
|
+
for (let index = 0; index < lines.length; index += 1) {
|
|
24306
|
+
const line = lines[index];
|
|
24307
|
+
if (line?.startsWith("@@ ")) return null;
|
|
24308
|
+
const nextLine = lines[index + 1];
|
|
24309
|
+
if (line?.startsWith("--- ") && nextLine?.startsWith("+++ ")) {
|
|
24310
|
+
return {
|
|
24311
|
+
oldFileName: line.slice(4),
|
|
24312
|
+
newFileName: nextLine.slice(4)
|
|
24313
|
+
};
|
|
24314
|
+
}
|
|
24315
|
+
}
|
|
24316
|
+
return null;
|
|
24317
|
+
});
|
|
24318
|
+
}
|
|
24319
|
+
function selectLosslessFileName(rawFileName, parsedFileName) {
|
|
24320
|
+
return rawFileName === void 0 || rawFileName.startsWith('"') ? parsedFileName : rawFileName;
|
|
24321
|
+
}
|
|
24322
|
+
function normalizeDiffPath(value) {
|
|
24323
|
+
if (value === void 0 || value === "/dev/null") return null;
|
|
24324
|
+
return value.startsWith("a/") || value.startsWith("b/") ? value.slice(2) : value;
|
|
24325
|
+
}
|
|
24326
|
+
function fitReportedAgentFileChangeReport(report) {
|
|
24327
|
+
const paths = [...report.paths];
|
|
24328
|
+
let truncated = report.truncated;
|
|
24329
|
+
let fitted = report;
|
|
24330
|
+
while (Buffer.byteLength(JSON.stringify(fitted), "utf8") > AGENT_FILE_CHANGE_REPORT_MAX_TOTAL_BYTES) {
|
|
24331
|
+
if (paths.length === 0) {
|
|
24332
|
+
throw new AgentFileChangeReportError("invalidOutput", "The audit report exceeds the wire limit");
|
|
24333
|
+
}
|
|
24334
|
+
paths.pop();
|
|
24335
|
+
truncated = true;
|
|
24336
|
+
fitted = {
|
|
24337
|
+
...report,
|
|
24338
|
+
paths: [...paths],
|
|
24339
|
+
declaredComplete: false,
|
|
24340
|
+
truncated
|
|
24341
|
+
};
|
|
24342
|
+
}
|
|
24343
|
+
return fitted;
|
|
24344
|
+
}
|
|
24345
|
+
function normalizeFileChangeReport(report, workspace) {
|
|
24346
|
+
const lexicalCwd = parseWorkspaceRoot(workspace.cwd);
|
|
24347
|
+
if (lexicalCwd === null) {
|
|
24348
|
+
throw new AgentFileChangeReportError("providerError", "The session working directory is not absolute");
|
|
24349
|
+
}
|
|
24350
|
+
const cwd = canonicalizeWorkspaceRoot(lexicalCwd);
|
|
24351
|
+
const diffRoot = parseWorkspaceRoot(workspace.diffRoot);
|
|
24352
|
+
if (diffRoot === null || diffRoot.flavor !== cwd.flavor) {
|
|
24353
|
+
throw new AgentFileChangeReportError("providerError", "The captured turn-diff root is invalid");
|
|
24354
|
+
}
|
|
24355
|
+
const roots = [cwd, ...workspace.additionalDirectories.flatMap((directory) => {
|
|
24356
|
+
const root = normalizeWorkspaceRoot(directory);
|
|
24357
|
+
return root === null || root.flavor !== cwd.flavor ? [] : [root];
|
|
24358
|
+
})];
|
|
24359
|
+
const paths = [];
|
|
24360
|
+
const seen = /* @__PURE__ */ new Set();
|
|
24361
|
+
let totalBytes = 0;
|
|
24362
|
+
let truncated = false;
|
|
24363
|
+
for (const reportedPath of report.paths) {
|
|
24364
|
+
if (reportedPath.length > AGENT_FILE_CHANGE_REPORT_MAX_PATH_LENGTH) {
|
|
24365
|
+
truncated = true;
|
|
24366
|
+
continue;
|
|
24367
|
+
}
|
|
24368
|
+
const normalized = normalizeReportedPath(reportedPath, diffRoot, roots);
|
|
24369
|
+
if (normalized === null || normalized.value.length > AGENT_FILE_CHANGE_REPORT_MAX_PATH_LENGTH) {
|
|
24370
|
+
truncated = true;
|
|
24371
|
+
continue;
|
|
24372
|
+
}
|
|
24373
|
+
const key = normalized.flavor === "windows" ? normalized.value.toLowerCase() : normalized.value;
|
|
24374
|
+
if (seen.has(key)) {
|
|
24375
|
+
continue;
|
|
24376
|
+
}
|
|
24377
|
+
const bytes = Buffer.byteLength(normalized.value, "utf8");
|
|
24378
|
+
if (paths.length >= AGENT_FILE_CHANGE_REPORT_MAX_PATHS || totalBytes + bytes > AGENT_FILE_CHANGE_REPORT_MAX_TOTAL_BYTES) {
|
|
24379
|
+
truncated = true;
|
|
24380
|
+
continue;
|
|
24381
|
+
}
|
|
24382
|
+
seen.add(key);
|
|
24383
|
+
paths.push(normalized.value);
|
|
24384
|
+
totalBytes += bytes;
|
|
24385
|
+
}
|
|
24386
|
+
return {
|
|
24387
|
+
paths,
|
|
24388
|
+
declaredComplete: report.complete && !truncated,
|
|
24389
|
+
truncated,
|
|
24390
|
+
...report.uncertainty ? { uncertainty: report.uncertainty } : {}
|
|
24391
|
+
};
|
|
24392
|
+
}
|
|
24393
|
+
function normalizeWorkspaceRoot(value) {
|
|
24394
|
+
const root = parseWorkspaceRoot(value);
|
|
24395
|
+
return root === null ? null : canonicalizeWorkspaceRoot(root);
|
|
24396
|
+
}
|
|
24397
|
+
function parseWorkspaceRoot(value) {
|
|
24398
|
+
const trimmed = value.trim();
|
|
24399
|
+
if (!isValidPathText(trimmed)) {
|
|
24400
|
+
return null;
|
|
24401
|
+
}
|
|
24402
|
+
if (isWindowsAbsolutePath(trimmed)) {
|
|
24403
|
+
return {
|
|
24404
|
+
value: path3.win32.normalize(trimmed.replace(/\//g, "\\")),
|
|
24405
|
+
flavor: "windows"
|
|
24406
|
+
};
|
|
24407
|
+
}
|
|
24408
|
+
if (path3.posix.isAbsolute(trimmed)) {
|
|
24409
|
+
return {
|
|
24410
|
+
value: path3.posix.normalize(trimmed.replace(/\\/g, "/")),
|
|
24411
|
+
flavor: "posix"
|
|
24412
|
+
};
|
|
24413
|
+
}
|
|
24414
|
+
return null;
|
|
24415
|
+
}
|
|
24416
|
+
function normalizeReportedPath(value, relativeRoot, roots) {
|
|
24417
|
+
if (!isValidPathText(value) || /^[A-Za-z]:[^\\/]/.test(value) || /^\\\\[?.]\\/.test(value) || /^(?:\\\\|\/\/)/.test(value) && !isWindowsAbsolutePath(value) || relativeRoot.flavor === "windows" && /^\\(?!\\)/.test(value) || /^[A-Za-z][A-Za-z0-9+.-]*:\/\//.test(value)) {
|
|
24418
|
+
return null;
|
|
24419
|
+
}
|
|
24420
|
+
let candidate;
|
|
24421
|
+
if (isWindowsAbsolutePath(value)) {
|
|
24422
|
+
candidate = { value: path3.win32.normalize(value.replace(/\//g, "\\")), flavor: "windows" };
|
|
24423
|
+
} else if (path3.posix.isAbsolute(value)) {
|
|
24424
|
+
candidate = { value: path3.posix.normalize(value.replace(/\\/g, "/")), flavor: "posix" };
|
|
24425
|
+
} else if (relativeRoot.flavor === "windows") {
|
|
24426
|
+
candidate = {
|
|
24427
|
+
value: path3.win32.resolve(relativeRoot.value, value.replace(/\//g, "\\")),
|
|
24428
|
+
flavor: "windows"
|
|
24429
|
+
};
|
|
24430
|
+
} else {
|
|
24431
|
+
candidate = {
|
|
24432
|
+
value: path3.posix.resolve(relativeRoot.value, value.replace(/\\/g, "/")),
|
|
24433
|
+
flavor: "posix"
|
|
24434
|
+
};
|
|
24435
|
+
}
|
|
24436
|
+
candidate = canonicalizeReportedPath(candidate);
|
|
24437
|
+
return roots.some((root) => pathIsStrictlyInside(root, candidate)) ? candidate : null;
|
|
24438
|
+
}
|
|
24439
|
+
function findDiffDisplayRoot(cwd) {
|
|
24440
|
+
if (!isNativePathFlavor(cwd.flavor)) return cwd;
|
|
24441
|
+
const pathImplementation = cwd.flavor === "windows" ? path3.win32 : path3.posix;
|
|
24442
|
+
let current = cwd.value;
|
|
24443
|
+
while (true) {
|
|
24444
|
+
if (fs2.existsSync(pathImplementation.join(current, ".git"))) {
|
|
24445
|
+
return canonicalizeWorkspaceRoot({ value: current, flavor: cwd.flavor });
|
|
24446
|
+
}
|
|
24447
|
+
const parent = pathImplementation.dirname(current);
|
|
24448
|
+
if (parent === current) return cwd;
|
|
24449
|
+
current = parent;
|
|
24450
|
+
}
|
|
24451
|
+
}
|
|
24452
|
+
function canonicalizeWorkspaceRoot(root) {
|
|
24453
|
+
if (!isNativePathFlavor(root.flavor)) {
|
|
24454
|
+
return root;
|
|
24455
|
+
}
|
|
24456
|
+
return { ...root, value: canonicalizeFromExistingAncestor(root.value) };
|
|
24457
|
+
}
|
|
24458
|
+
function canonicalizeReportedPath(candidate) {
|
|
24459
|
+
if (!isNativePathFlavor(candidate.flavor)) {
|
|
24460
|
+
return candidate;
|
|
24461
|
+
}
|
|
24462
|
+
const parent = canonicalizeFromExistingAncestor(path3.dirname(candidate.value));
|
|
24463
|
+
return { ...candidate, value: path3.resolve(parent, path3.basename(candidate.value)) };
|
|
24464
|
+
}
|
|
24465
|
+
function canonicalizeFromExistingAncestor(value) {
|
|
24466
|
+
const original = path3.resolve(value);
|
|
24467
|
+
let current = original;
|
|
24468
|
+
const missingSegments = [];
|
|
24469
|
+
while (true) {
|
|
24470
|
+
try {
|
|
24471
|
+
const canonical = fs2.realpathSync.native(current);
|
|
24472
|
+
return path3.resolve(canonical, ...missingSegments.reverse());
|
|
24473
|
+
} catch (error51) {
|
|
24474
|
+
if (!isMissingPathError(error51)) return original;
|
|
24475
|
+
}
|
|
24476
|
+
const parent = path3.dirname(current);
|
|
24477
|
+
if (parent === current) return original;
|
|
24478
|
+
missingSegments.push(path3.basename(current));
|
|
24479
|
+
current = parent;
|
|
24480
|
+
}
|
|
24481
|
+
}
|
|
24482
|
+
function isMissingPathError(error51) {
|
|
24483
|
+
if (typeof error51 !== "object" || error51 === null || !("code" in error51)) return false;
|
|
24484
|
+
return error51.code === "ENOENT" || error51.code === "ENOTDIR";
|
|
24101
24485
|
}
|
|
24102
|
-
|
|
24103
|
-
|
|
24104
|
-
function rateLimitId(snapshot, fallback = "codex") {
|
|
24105
|
-
return snapshot.limitId ?? fallback;
|
|
24486
|
+
function isNativePathFlavor(flavor) {
|
|
24487
|
+
return process.platform === "win32" ? flavor === "windows" : flavor === "posix";
|
|
24106
24488
|
}
|
|
24107
|
-
function
|
|
24108
|
-
|
|
24109
|
-
|
|
24110
|
-
if (snapshots.length === 0) {
|
|
24111
|
-
snapshots.push([rateLimitId(response.rateLimits), response.rateLimits]);
|
|
24112
|
-
}
|
|
24113
|
-
for (const [fallbackId, snapshot] of snapshots) {
|
|
24114
|
-
const limitId = rateLimitId(snapshot, fallbackId);
|
|
24115
|
-
result.set(limitId, {
|
|
24116
|
-
limitId,
|
|
24117
|
-
limitName: snapshot.limitName ?? limitId,
|
|
24118
|
-
snapshot
|
|
24119
|
-
});
|
|
24489
|
+
function pathIsStrictlyInside(root, candidate) {
|
|
24490
|
+
if (root.flavor !== candidate.flavor) {
|
|
24491
|
+
return false;
|
|
24120
24492
|
}
|
|
24121
|
-
|
|
24493
|
+
const pathImplementation = root.flavor === "windows" ? path3.win32 : path3.posix;
|
|
24494
|
+
const relative = pathImplementation.relative(root.value, candidate.value);
|
|
24495
|
+
return relative.length > 0 && !pathImplementation.isAbsolute(relative) && relative !== ".." && !relative.startsWith(`..${pathImplementation.sep}`);
|
|
24122
24496
|
}
|
|
24123
|
-
function
|
|
24124
|
-
|
|
24125
|
-
|
|
24126
|
-
|
|
24127
|
-
|
|
24128
|
-
|
|
24129
|
-
|
|
24130
|
-
|
|
24131
|
-
|
|
24497
|
+
function isWindowsAbsolutePath(value) {
|
|
24498
|
+
const portable = value.replace(/\\/g, "/");
|
|
24499
|
+
return /^[A-Za-z]:\//.test(portable) || /^\/\/[^/]+\/[^/]+(?:\/|$)/.test(portable);
|
|
24500
|
+
}
|
|
24501
|
+
function isValidPathText(value) {
|
|
24502
|
+
return value.length > 0 && !/[\u0000-\u001F\u007F-\u009F]/.test(value);
|
|
24503
|
+
}
|
|
24504
|
+
function asRecord2(value) {
|
|
24505
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
|
|
24506
|
+
}
|
|
24507
|
+
function hasOnlyKeys(value, allowed) {
|
|
24508
|
+
const allowedKeys = new Set(allowed);
|
|
24509
|
+
return Object.keys(value).every((key) => allowedKeys.has(key));
|
|
24132
24510
|
}
|
|
24133
24511
|
|
|
24134
24512
|
// src/CodexEventHandler.ts
|
|
@@ -24238,6 +24616,9 @@ var CodexEventHandler = class _CodexEventHandler {
|
|
|
24238
24616
|
terminalCommandIds = /* @__PURE__ */ new Set();
|
|
24239
24617
|
terminalCommandOutputIds = /* @__PURE__ */ new Set();
|
|
24240
24618
|
agentMessagePhases = /* @__PURE__ */ new Map();
|
|
24619
|
+
turnDiffs = /* @__PURE__ */ new Map();
|
|
24620
|
+
oversizedTurnDiffs = /* @__PURE__ */ new Set();
|
|
24621
|
+
collectTurnDiffs;
|
|
24241
24622
|
subagents;
|
|
24242
24623
|
/** Connection-level `authStatus` sink; the app-server account push feeds it. */
|
|
24243
24624
|
onAccountUpdated;
|
|
@@ -24245,7 +24626,7 @@ var CodexEventHandler = class _CodexEventHandler {
|
|
|
24245
24626
|
sessionState.sessionId,
|
|
24246
24627
|
false,
|
|
24247
24628
|
new ACPSessionConnection(connection, sessionState.sessionId)
|
|
24248
|
-
), onAccountUpdated) {
|
|
24629
|
+
), onAccountUpdated, collectTurnDiffs = false) {
|
|
24249
24630
|
this.onAccountUpdated = onAccountUpdated;
|
|
24250
24631
|
this.sessionState = sessionState;
|
|
24251
24632
|
this.supportsPlanUpdates = supportsPlanUpdates;
|
|
@@ -24253,6 +24634,7 @@ var CodexEventHandler = class _CodexEventHandler {
|
|
|
24253
24634
|
this.sessionFailureEpoch = sessionFailureEpoch;
|
|
24254
24635
|
this.session = new ACPSessionConnection(connection, sessionState.sessionId);
|
|
24255
24636
|
this.subagents = subagents;
|
|
24637
|
+
this.collectTurnDiffs = collectTurnDiffs;
|
|
24256
24638
|
if (sessionState.sessionFailure !== void 0) {
|
|
24257
24639
|
this.failuresById.set(sessionState.sessionFailure.id, sessionState.sessionFailure);
|
|
24258
24640
|
}
|
|
@@ -24260,6 +24642,12 @@ var CodexEventHandler = class _CodexEventHandler {
|
|
|
24260
24642
|
getFailure() {
|
|
24261
24643
|
return this.failure;
|
|
24262
24644
|
}
|
|
24645
|
+
getTurnDiff(turnId) {
|
|
24646
|
+
return this.turnDiffs.get(turnId) ?? "";
|
|
24647
|
+
}
|
|
24648
|
+
isTurnDiffOversized(turnId) {
|
|
24649
|
+
return this.oversizedTurnDiffs.has(turnId);
|
|
24650
|
+
}
|
|
24263
24651
|
getTerminalSessionFailureMeta(turnId, allowUnattributed = false) {
|
|
24264
24652
|
const failure = this.sessionState.sessionFailure;
|
|
24265
24653
|
if (!this.supportsTypedSessionFailures || failure === void 0 || (this.failureTurnIdById.get(failure.id) === void 0 ? !allowUnattributed : turnId === null || this.failureTurnIdById.get(failure.id) !== turnId)) {
|
|
@@ -24419,6 +24807,8 @@ var CodexEventHandler = class _CodexEventHandler {
|
|
|
24419
24807
|
this.pendingPlanItemIds.clear();
|
|
24420
24808
|
this.planDeltaTextByItemId.clear();
|
|
24421
24809
|
this.lastEmittedPlanTextByItemId.clear();
|
|
24810
|
+
this.turnDiffs.clear();
|
|
24811
|
+
this.oversizedTurnDiffs.clear();
|
|
24422
24812
|
}
|
|
24423
24813
|
async createUpdateEvent(notification) {
|
|
24424
24814
|
switch (notification.method) {
|
|
@@ -24437,6 +24827,20 @@ var CodexEventHandler = class _CodexEventHandler {
|
|
|
24437
24827
|
case "turn/plan/updated":
|
|
24438
24828
|
this.completeRetryIncidentOnTurnProgress();
|
|
24439
24829
|
return await this.updatePlan(notification.params);
|
|
24830
|
+
case "turn/diff/updated":
|
|
24831
|
+
if (notification.params.threadId === this.sessionState.sessionId) {
|
|
24832
|
+
this.completeRetryIncidentOnTurnProgress();
|
|
24833
|
+
if (!this.disposed && this.collectTurnDiffs) {
|
|
24834
|
+
if (Buffer.byteLength(notification.params.diff, "utf8") > AGENT_FILE_CHANGE_REPORT_MAX_DIFF_BYTES) {
|
|
24835
|
+
this.turnDiffs.delete(notification.params.turnId);
|
|
24836
|
+
this.oversizedTurnDiffs.add(notification.params.turnId);
|
|
24837
|
+
} else {
|
|
24838
|
+
this.oversizedTurnDiffs.delete(notification.params.turnId);
|
|
24839
|
+
this.turnDiffs.set(notification.params.turnId, notification.params.diff);
|
|
24840
|
+
}
|
|
24841
|
+
}
|
|
24842
|
+
}
|
|
24843
|
+
return null;
|
|
24440
24844
|
case "error":
|
|
24441
24845
|
return await this.createErrorEvent(notification.params);
|
|
24442
24846
|
case "turn/started":
|
|
@@ -24531,7 +24935,6 @@ var CodexEventHandler = class _CodexEventHandler {
|
|
|
24531
24935
|
case "command/exec/outputDelta":
|
|
24532
24936
|
case "hook/started":
|
|
24533
24937
|
case "hook/completed":
|
|
24534
|
-
case "turn/diff/updated":
|
|
24535
24938
|
case "turn/moderationMetadata":
|
|
24536
24939
|
case "item/fileChange/outputDelta":
|
|
24537
24940
|
case "item/fileChange/patchUpdated":
|
|
@@ -24715,10 +25118,16 @@ ${event.details}` : event.summary;
|
|
|
24715
25118
|
async completeItemEvent(event) {
|
|
24716
25119
|
switch (event.item.type) {
|
|
24717
25120
|
case "fileChange":
|
|
25121
|
+
return {
|
|
25122
|
+
sessionUpdate: "tool_call_update",
|
|
25123
|
+
toolCallId: event.item.id,
|
|
25124
|
+
status: event.item.status === "completed" ? "completed" : "failed"
|
|
25125
|
+
};
|
|
24718
25126
|
case "dynamicToolCall":
|
|
24719
25127
|
return {
|
|
24720
25128
|
sessionUpdate: "tool_call_update",
|
|
24721
25129
|
toolCallId: event.item.id,
|
|
25130
|
+
name: functionToolName(event.item.tool, event.item.namespace),
|
|
24722
25131
|
status: event.item.status === "completed" ? "completed" : "failed"
|
|
24723
25132
|
};
|
|
24724
25133
|
case "mcpToolCall":
|
|
@@ -24930,9 +25339,11 @@ ${event.stdin}
|
|
|
24930
25339
|
return `mcp_startup.${encodeURIComponent(serverName)}`;
|
|
24931
25340
|
}
|
|
24932
25341
|
completeCommandExecutionEvent(item) {
|
|
25342
|
+
const name = commandToolName(item.source);
|
|
24933
25343
|
const update = {
|
|
24934
25344
|
sessionUpdate: "tool_call_update",
|
|
24935
25345
|
toolCallId: item.id,
|
|
25346
|
+
...name === void 0 ? {} : { name },
|
|
24936
25347
|
status: item.status === "completed" ? "completed" : "failed",
|
|
24937
25348
|
rawOutput: {
|
|
24938
25349
|
formatted_output: item.aggregatedOutput ?? "",
|
|
@@ -25548,7 +25959,8 @@ function nonBlank(value) {
|
|
|
25548
25959
|
}
|
|
25549
25960
|
|
|
25550
25961
|
// src/permissions/presentation.ts
|
|
25551
|
-
function commandToolCall(params) {
|
|
25962
|
+
function commandToolCall(params, permissionContext) {
|
|
25963
|
+
const name = permissionContext.commandName(params.threadId, params.itemId);
|
|
25552
25964
|
const network = params.networkApprovalContext;
|
|
25553
25965
|
const rawInput = {
|
|
25554
25966
|
...params.command ? { command: stripShellPrefix(params.command) } : {},
|
|
@@ -25559,6 +25971,7 @@ function commandToolCall(params) {
|
|
|
25559
25971
|
const additionalPermissionContent = params.additionalPermissions ? permissionProfileContent(params.additionalPermissions) : [];
|
|
25560
25972
|
return {
|
|
25561
25973
|
toolCallId: params.itemId,
|
|
25974
|
+
...name !== void 0 ? { name } : {},
|
|
25562
25975
|
kind: "execute",
|
|
25563
25976
|
status: "pending",
|
|
25564
25977
|
title: network ? `${network.protocol} network access to ${network.host}` : commandTitle(params.commandActions),
|
|
@@ -25584,6 +25997,7 @@ function additionalPermissionsToolCall(itemId, cwd, environmentId, permissions)
|
|
|
25584
25997
|
const content = permissionProfileContent(permissions);
|
|
25585
25998
|
return {
|
|
25586
25999
|
toolCallId: itemId,
|
|
26000
|
+
name: "request_permissions",
|
|
25587
26001
|
kind: "other",
|
|
25588
26002
|
status: "pending",
|
|
25589
26003
|
title: "Additional sandbox permissions",
|
|
@@ -25682,7 +26096,7 @@ var CodexApprovalHandler = class {
|
|
|
25682
26096
|
try {
|
|
25683
26097
|
const response = await this.requestPermission({
|
|
25684
26098
|
sessionId: params.threadId,
|
|
25685
|
-
toolCall: commandToolCall(authoritativeParams),
|
|
26099
|
+
toolCall: commandToolCall(authoritativeParams, this.permissionContext),
|
|
25686
26100
|
options: decisions.map(({ option }) => option),
|
|
25687
26101
|
_meta: requestPermissionMeta(
|
|
25688
26102
|
params.networkApprovalContext ? CODEX_NETWORK_PERMISSION_TITLE : CODEX_COMMAND_PERMISSION_TITLE,
|
|
@@ -25790,6 +26204,7 @@ var PermissionPromptContext = class {
|
|
|
25790
26204
|
this.nextStandaloneId = nextStandaloneId;
|
|
25791
26205
|
}
|
|
25792
26206
|
nextStandaloneId;
|
|
26207
|
+
commandNames = /* @__PURE__ */ new Map();
|
|
25793
26208
|
fileChanges = /* @__PURE__ */ new Map();
|
|
25794
26209
|
pendingMcpApprovals = /* @__PURE__ */ new Map();
|
|
25795
26210
|
handleNotification(notification) {
|
|
@@ -25813,6 +26228,9 @@ var PermissionPromptContext = class {
|
|
|
25813
26228
|
fileChange(threadId, itemId) {
|
|
25814
26229
|
return this.fileChanges.get(threadId)?.get(itemId);
|
|
25815
26230
|
}
|
|
26231
|
+
commandName(threadId, itemId) {
|
|
26232
|
+
return this.commandNames.get(threadId)?.get(itemId);
|
|
26233
|
+
}
|
|
25816
26234
|
popPendingMcpApproval(threadId, serverName) {
|
|
25817
26235
|
const byServer = this.pendingMcpApprovals.get(threadId);
|
|
25818
26236
|
if (!byServer) return void 0;
|
|
@@ -25827,6 +26245,15 @@ var PermissionPromptContext = class {
|
|
|
25827
26245
|
return this.nextStandaloneId(serverName);
|
|
25828
26246
|
}
|
|
25829
26247
|
handleItemStarted(threadId, item) {
|
|
26248
|
+
if (item.type === "commandExecution") {
|
|
26249
|
+
const name = commandToolName(item.source);
|
|
26250
|
+
if (name !== void 0) {
|
|
26251
|
+
const byItem = this.commandNames.get(threadId) ?? /* @__PURE__ */ new Map();
|
|
26252
|
+
byItem.set(item.id, name);
|
|
26253
|
+
this.commandNames.set(threadId, byItem);
|
|
26254
|
+
}
|
|
26255
|
+
return;
|
|
26256
|
+
}
|
|
25830
26257
|
if (item.type === "fileChange") {
|
|
25831
26258
|
const byItem = this.fileChanges.get(threadId) ?? /* @__PURE__ */ new Map();
|
|
25832
26259
|
byItem.set(item.id, item);
|
|
@@ -25841,6 +26268,12 @@ var PermissionPromptContext = class {
|
|
|
25841
26268
|
this.pendingMcpApprovals.set(threadId, byServer);
|
|
25842
26269
|
}
|
|
25843
26270
|
handleItemCompleted(threadId, item) {
|
|
26271
|
+
if (item.type === "commandExecution") {
|
|
26272
|
+
const byItem = this.commandNames.get(threadId);
|
|
26273
|
+
byItem?.delete(item.id);
|
|
26274
|
+
if (byItem?.size === 0) this.commandNames.delete(threadId);
|
|
26275
|
+
return;
|
|
26276
|
+
}
|
|
25844
26277
|
if (item.type === "fileChange") {
|
|
25845
26278
|
const byItem = this.fileChanges.get(threadId);
|
|
25846
26279
|
byItem?.delete(item.id);
|
|
@@ -25858,6 +26291,7 @@ var PermissionPromptContext = class {
|
|
|
25858
26291
|
if (byServer.size === 0) this.pendingMcpApprovals.delete(threadId);
|
|
25859
26292
|
}
|
|
25860
26293
|
clearTransientState(threadId) {
|
|
26294
|
+
this.commandNames.delete(threadId);
|
|
25861
26295
|
this.fileChanges.delete(threadId);
|
|
25862
26296
|
this.pendingMcpApprovals.delete(threadId);
|
|
25863
26297
|
}
|
|
@@ -26046,7 +26480,9 @@ function cancelledResponse() {
|
|
|
26046
26480
|
}
|
|
26047
26481
|
|
|
26048
26482
|
// src/CodexElicitationHandler.ts
|
|
26049
|
-
var
|
|
26483
|
+
var USER_INPUT_NOTE_FIELD_SUFFIX = "_note";
|
|
26484
|
+
var USER_INPUT_OTHER_OPTION = "None of the above";
|
|
26485
|
+
var USER_INPUT_NOTE_PREFIX = "user_note: ";
|
|
26050
26486
|
function normalizeElicitationSchema(value) {
|
|
26051
26487
|
const normalized = normalizeElicitationSchemaValue(value);
|
|
26052
26488
|
if (!isRecord2(normalized)) {
|
|
@@ -26103,16 +26539,14 @@ function elicitationResponseMeta(response, context, persist = void 0) {
|
|
|
26103
26539
|
}
|
|
26104
26540
|
return Object.keys(meta3).length === 0 ? null : meta3;
|
|
26105
26541
|
}
|
|
26106
|
-
function
|
|
26107
|
-
const base = `${questionId}${
|
|
26108
|
-
|
|
26109
|
-
return base;
|
|
26110
|
-
}
|
|
26542
|
+
function userInputNoteFieldId(questionId, questionIds) {
|
|
26543
|
+
const base = `${questionId}${USER_INPUT_NOTE_FIELD_SUFFIX}`;
|
|
26544
|
+
let fieldId = base;
|
|
26111
26545
|
let index = 1;
|
|
26112
|
-
while (questionIds.has(
|
|
26113
|
-
|
|
26546
|
+
while (questionIds.has(fieldId)) {
|
|
26547
|
+
fieldId = `${base}${index++}`;
|
|
26114
26548
|
}
|
|
26115
|
-
return
|
|
26549
|
+
return fieldId;
|
|
26116
26550
|
}
|
|
26117
26551
|
function userInputResponseValue(content, fieldId) {
|
|
26118
26552
|
const value = content[fieldId];
|
|
@@ -26125,14 +26559,14 @@ function userInputResponseValue(content, fieldId) {
|
|
|
26125
26559
|
return value;
|
|
26126
26560
|
}
|
|
26127
26561
|
var CodexElicitationHandler = class {
|
|
26128
|
-
constructor(connection, permissionContext, clientCapabilities = null, cancellationSignal,
|
|
26129
|
-
this.
|
|
26562
|
+
constructor(connection, permissionContext, clientCapabilities = null, cancellationSignal, fullAccessApprovedServers) {
|
|
26563
|
+
this.fullAccessApprovedServers = fullAccessApprovedServers;
|
|
26130
26564
|
this.connection = connection;
|
|
26131
26565
|
this.permissionContext = permissionContext;
|
|
26132
26566
|
this.clientCapabilities = clientCapabilities;
|
|
26133
26567
|
this.cancellationSignal = cancellationSignal;
|
|
26134
26568
|
}
|
|
26135
|
-
|
|
26569
|
+
fullAccessApprovedServers;
|
|
26136
26570
|
connection;
|
|
26137
26571
|
permissionContext;
|
|
26138
26572
|
clientCapabilities;
|
|
@@ -26151,9 +26585,9 @@ var CodexElicitationHandler = class {
|
|
|
26151
26585
|
async handleElicitation(params) {
|
|
26152
26586
|
try {
|
|
26153
26587
|
const context = this.createMcpElicitationContext(params);
|
|
26154
|
-
const
|
|
26155
|
-
if (
|
|
26156
|
-
const accepted = !this.cancellationSignal?.aborted && params.mode === "form" && context.isToolApproval && context.persistOptions.has("session") &&
|
|
26588
|
+
const approvedServers = this.fullAccessApprovedServers?.(params);
|
|
26589
|
+
if (approvedServers !== void 0) {
|
|
26590
|
+
const accepted = !this.cancellationSignal?.aborted && params.mode === "form" && context.isToolApproval && context.persistOptions.has("session") && approvedServers.has(params.serverName);
|
|
26157
26591
|
await this.publishAcceptedMcpToolApproval(params.threadId, context, accepted);
|
|
26158
26592
|
return { action: accepted ? "accept" : "cancel", content: accepted ? {} : null, _meta: null };
|
|
26159
26593
|
}
|
|
@@ -26220,7 +26654,7 @@ var CodexElicitationHandler = class {
|
|
|
26220
26654
|
}
|
|
26221
26655
|
}
|
|
26222
26656
|
async handleUserInput(params) {
|
|
26223
|
-
if (this.
|
|
26657
|
+
if (this.fullAccessApprovedServers?.(params) !== void 0 && params.itemId === `mcp-deps-${params.turnId}` && params.questions.some((question) => question.id === "skill_mcp_dependency_install")) {
|
|
26224
26658
|
return { answers: {} };
|
|
26225
26659
|
}
|
|
26226
26660
|
if (!clientSupportsFormElicitation(this.clientCapabilities)) {
|
|
@@ -26349,8 +26783,8 @@ var CodexElicitationHandler = class {
|
|
|
26349
26783
|
const hasOptions = options.length > 0;
|
|
26350
26784
|
const hasOtherAnswer = question.isOther && hasOptions;
|
|
26351
26785
|
const base = {
|
|
26352
|
-
title: question.header || question.id,
|
|
26353
|
-
description: question.
|
|
26786
|
+
title: question.question || question.header || question.id,
|
|
26787
|
+
...question.header ? { description: question.header } : {},
|
|
26354
26788
|
_meta: {
|
|
26355
26789
|
codex: {
|
|
26356
26790
|
isOther: question.isOther,
|
|
@@ -26358,42 +26792,45 @@ var CodexElicitationHandler = class {
|
|
|
26358
26792
|
}
|
|
26359
26793
|
}
|
|
26360
26794
|
};
|
|
26361
|
-
|
|
26362
|
-
required2.push(question.id);
|
|
26363
|
-
}
|
|
26795
|
+
required2.push(question.id);
|
|
26364
26796
|
properties[question.id] = hasOptions ? {
|
|
26365
26797
|
...base,
|
|
26366
26798
|
type: "string",
|
|
26367
|
-
oneOf:
|
|
26368
|
-
|
|
26369
|
-
|
|
26370
|
-
|
|
26371
|
-
|
|
26799
|
+
oneOf: [
|
|
26800
|
+
...options.map((option) => ({
|
|
26801
|
+
const: option.label,
|
|
26802
|
+
title: option.label,
|
|
26803
|
+
...option.description ? { description: option.description } : {}
|
|
26804
|
+
})),
|
|
26805
|
+
...hasOtherAnswer && !options.some((option) => option.label === USER_INPUT_OTHER_OPTION) ? [{
|
|
26806
|
+
const: USER_INPUT_OTHER_OPTION,
|
|
26807
|
+
title: USER_INPUT_OTHER_OPTION,
|
|
26808
|
+
description: "Provide a different answer in the note field."
|
|
26809
|
+
}] : []
|
|
26810
|
+
]
|
|
26372
26811
|
} : {
|
|
26373
26812
|
...base,
|
|
26374
26813
|
type: "string"
|
|
26375
26814
|
};
|
|
26376
26815
|
if (hasOtherAnswer) {
|
|
26377
|
-
properties[
|
|
26816
|
+
properties[userInputNoteFieldId(question.id, questionIds)] = {
|
|
26378
26817
|
type: "string",
|
|
26379
|
-
title: "
|
|
26380
|
-
description: "Type your own answer instead of choosing an option above.",
|
|
26818
|
+
title: "Additional answer or note",
|
|
26381
26819
|
_meta: {
|
|
26382
26820
|
codex: {
|
|
26383
26821
|
questionId: question.id,
|
|
26384
|
-
|
|
26822
|
+
role: "user_note",
|
|
26385
26823
|
isSecret: question.isSecret
|
|
26386
26824
|
}
|
|
26387
26825
|
}
|
|
26388
26826
|
};
|
|
26389
26827
|
}
|
|
26390
26828
|
}
|
|
26391
|
-
const firstQuestion = params.questions[0];
|
|
26392
26829
|
return {
|
|
26393
26830
|
sessionId: params.threadId,
|
|
26394
26831
|
toolCallId: params.itemId,
|
|
26395
26832
|
mode: "form",
|
|
26396
|
-
message:
|
|
26833
|
+
message: "Codex needs your input to continue.",
|
|
26397
26834
|
requestedSchema: {
|
|
26398
26835
|
type: "object",
|
|
26399
26836
|
properties,
|
|
@@ -26444,12 +26881,23 @@ var CodexElicitationHandler = class {
|
|
|
26444
26881
|
const content = contentRecord(response.content);
|
|
26445
26882
|
const questionIds = new Set(params.questions.map((question) => question.id));
|
|
26446
26883
|
for (const question of params.questions) {
|
|
26447
|
-
const
|
|
26448
|
-
|
|
26884
|
+
const answerValues = [];
|
|
26885
|
+
const value = userInputResponseValue(content, question.id);
|
|
26886
|
+
if (value !== void 0) {
|
|
26887
|
+
answerValues.push(...Array.isArray(value) ? value.map(String) : [String(value)]);
|
|
26888
|
+
}
|
|
26889
|
+
if (question.isOther && question.options != null && question.options.length > 0) {
|
|
26890
|
+
const note = userInputResponseValue(content, userInputNoteFieldId(question.id, questionIds));
|
|
26891
|
+
if (note !== void 0) {
|
|
26892
|
+
const notes = Array.isArray(note) ? note : [note];
|
|
26893
|
+
answerValues.push(...notes.map((item) => `${USER_INPUT_NOTE_PREFIX}${String(item).trim()}`));
|
|
26894
|
+
}
|
|
26895
|
+
}
|
|
26896
|
+
if (answerValues.length === 0) {
|
|
26449
26897
|
continue;
|
|
26450
26898
|
}
|
|
26451
26899
|
answers[question.id] = {
|
|
26452
|
-
answers:
|
|
26900
|
+
answers: answerValues
|
|
26453
26901
|
};
|
|
26454
26902
|
}
|
|
26455
26903
|
return { answers };
|
|
@@ -26539,31 +26987,31 @@ function isCodexAuthRequest(request) {
|
|
|
26539
26987
|
|
|
26540
26988
|
// node_modules/open/index.js
|
|
26541
26989
|
import process11 from "node:process";
|
|
26542
|
-
import
|
|
26990
|
+
import path5 from "node:path";
|
|
26543
26991
|
import { fileURLToPath } from "node:url";
|
|
26544
26992
|
import childProcess4 from "node:child_process";
|
|
26545
|
-
import
|
|
26993
|
+
import fs7, { constants as fsConstants2 } from "node:fs/promises";
|
|
26546
26994
|
|
|
26547
26995
|
// node_modules/wsl-utils/index.js
|
|
26548
|
-
import
|
|
26996
|
+
import path4 from "node:path";
|
|
26549
26997
|
import { promisify as promisify2 } from "node:util";
|
|
26550
26998
|
import childProcess2 from "node:child_process";
|
|
26551
|
-
import
|
|
26999
|
+
import fs6, { constants as fsConstants } from "node:fs/promises";
|
|
26552
27000
|
|
|
26553
27001
|
// node_modules/is-wsl/index.js
|
|
26554
27002
|
import process3 from "node:process";
|
|
26555
27003
|
import os from "node:os";
|
|
26556
|
-
import
|
|
27004
|
+
import fs5 from "node:fs";
|
|
26557
27005
|
|
|
26558
27006
|
// node_modules/is-inside-container/index.js
|
|
26559
|
-
import
|
|
27007
|
+
import fs4 from "node:fs";
|
|
26560
27008
|
|
|
26561
27009
|
// node_modules/is-docker/index.js
|
|
26562
|
-
import
|
|
27010
|
+
import fs3 from "node:fs";
|
|
26563
27011
|
var isDockerCached;
|
|
26564
27012
|
function hasDockerEnv() {
|
|
26565
27013
|
try {
|
|
26566
|
-
|
|
27014
|
+
fs3.statSync("/.dockerenv");
|
|
26567
27015
|
return true;
|
|
26568
27016
|
} catch {
|
|
26569
27017
|
return false;
|
|
@@ -26571,7 +27019,7 @@ function hasDockerEnv() {
|
|
|
26571
27019
|
}
|
|
26572
27020
|
function hasDockerCGroup() {
|
|
26573
27021
|
try {
|
|
26574
|
-
return
|
|
27022
|
+
return fs3.readFileSync("/proc/self/cgroup", "utf8").includes("docker");
|
|
26575
27023
|
} catch {
|
|
26576
27024
|
return false;
|
|
26577
27025
|
}
|
|
@@ -26587,7 +27035,7 @@ function isDocker() {
|
|
|
26587
27035
|
var cachedResult;
|
|
26588
27036
|
var hasContainerEnv = () => {
|
|
26589
27037
|
try {
|
|
26590
|
-
|
|
27038
|
+
fs4.statSync("/run/.containerenv");
|
|
26591
27039
|
return true;
|
|
26592
27040
|
} catch {
|
|
26593
27041
|
return false;
|
|
@@ -26612,12 +27060,12 @@ var isWsl = () => {
|
|
|
26612
27060
|
return true;
|
|
26613
27061
|
}
|
|
26614
27062
|
try {
|
|
26615
|
-
if (
|
|
27063
|
+
if (fs5.readFileSync("/proc/version", "utf8").toLowerCase().includes("microsoft")) {
|
|
26616
27064
|
return !isInsideContainer();
|
|
26617
27065
|
}
|
|
26618
27066
|
} catch {
|
|
26619
27067
|
}
|
|
26620
|
-
if (
|
|
27068
|
+
if (fs5.existsSync("/proc/sys/fs/binfmt_misc/WSLInterop") || fs5.existsSync("/run/WSL")) {
|
|
26621
27069
|
return !isInsideContainer();
|
|
26622
27070
|
}
|
|
26623
27071
|
return false;
|
|
@@ -26685,14 +27133,14 @@ var wslDrivesMountPoint = /* @__PURE__ */ (() => {
|
|
|
26685
27133
|
const configFilePath = "/etc/wsl.conf";
|
|
26686
27134
|
let isConfigFileExists = false;
|
|
26687
27135
|
try {
|
|
26688
|
-
await
|
|
27136
|
+
await fs6.access(configFilePath, fsConstants.F_OK);
|
|
26689
27137
|
isConfigFileExists = true;
|
|
26690
27138
|
} catch {
|
|
26691
27139
|
}
|
|
26692
27140
|
if (!isConfigFileExists) {
|
|
26693
27141
|
return defaultMountPoint;
|
|
26694
27142
|
}
|
|
26695
|
-
const configContent = await
|
|
27143
|
+
const configContent = await fs6.readFile(configFilePath, { encoding: "utf8" });
|
|
26696
27144
|
const parsedMountPoint = parseMountPointFromConfig(configContent);
|
|
26697
27145
|
if (parsedMountPoint === void 0) {
|
|
26698
27146
|
return defaultMountPoint;
|
|
@@ -26712,7 +27160,7 @@ var canAccessPowerShell = async () => {
|
|
|
26712
27160
|
canAccessPowerShellPromise ??= (async () => {
|
|
26713
27161
|
try {
|
|
26714
27162
|
const psPath = await powerShellPath2();
|
|
26715
|
-
await
|
|
27163
|
+
await fs6.access(psPath, fsConstants.X_OK);
|
|
26716
27164
|
return true;
|
|
26717
27165
|
} catch {
|
|
26718
27166
|
return false;
|
|
@@ -26725,7 +27173,7 @@ var wslDefaultBrowser = async () => {
|
|
|
26725
27173
|
const command = String.raw`(Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice").ProgId`;
|
|
26726
27174
|
const { stdout } = await executePowerShell(command, {
|
|
26727
27175
|
powerShellPath: psPath,
|
|
26728
|
-
cwd:
|
|
27176
|
+
cwd: path4.dirname(psPath)
|
|
26729
27177
|
});
|
|
26730
27178
|
return stdout.trim();
|
|
26731
27179
|
};
|
|
@@ -26931,8 +27379,8 @@ var is_in_ssh_default = isInSsh;
|
|
|
26931
27379
|
|
|
26932
27380
|
// node_modules/open/index.js
|
|
26933
27381
|
var fallbackAttemptSymbol = /* @__PURE__ */ Symbol("fallbackAttempt");
|
|
26934
|
-
var __dirname = import.meta.url ?
|
|
26935
|
-
var localXdgOpenPath =
|
|
27382
|
+
var __dirname = import.meta.url ? path5.dirname(fileURLToPath(import.meta.url)) : "";
|
|
27383
|
+
var localXdgOpenPath = path5.join(__dirname, "xdg-open");
|
|
26936
27384
|
var { platform, arch } = process11;
|
|
26937
27385
|
var tryEachApp = async (apps2, opener) => {
|
|
26938
27386
|
if (apps2.length === 0) {
|
|
@@ -27074,7 +27522,7 @@ var baseOpen = async (options) => {
|
|
|
27074
27522
|
childProcessOptions.stdio = "ignore";
|
|
27075
27523
|
}
|
|
27076
27524
|
if (is_wsl_default) {
|
|
27077
|
-
childProcessOptions.cwd =
|
|
27525
|
+
childProcessOptions.cwd = path5.dirname(command);
|
|
27078
27526
|
}
|
|
27079
27527
|
} else {
|
|
27080
27528
|
if (app) {
|
|
@@ -27083,7 +27531,7 @@ var baseOpen = async (options) => {
|
|
|
27083
27531
|
const isBundled = !__dirname || __dirname === "/";
|
|
27084
27532
|
let exeLocalXdgOpen = false;
|
|
27085
27533
|
try {
|
|
27086
|
-
await
|
|
27534
|
+
await fs7.access(localXdgOpenPath, fsConstants2.X_OK);
|
|
27087
27535
|
exeLocalXdgOpen = true;
|
|
27088
27536
|
} catch {
|
|
27089
27537
|
}
|
|
@@ -27371,7 +27819,7 @@ var package_default = {
|
|
|
27371
27819
|
publishConfig: {
|
|
27372
27820
|
access: "public"
|
|
27373
27821
|
},
|
|
27374
|
-
version: "1.
|
|
27822
|
+
version: "1.12.0-agentconnect.2",
|
|
27375
27823
|
description: "",
|
|
27376
27824
|
main: "dist/index.js",
|
|
27377
27825
|
bin: {
|
|
@@ -27422,402 +27870,106 @@ var package_default = {
|
|
|
27422
27870
|
keywords: [],
|
|
27423
27871
|
author: "Agent Client Protocol",
|
|
27424
27872
|
license: "Apache-2.0",
|
|
27425
|
-
type: "module",
|
|
27426
|
-
devDependencies: {
|
|
27427
|
-
"@types/node": "^26.1.0",
|
|
27428
|
-
esbuild: "^0.28.2",
|
|
27429
|
-
"mcp-hello-world": "^1.1.2",
|
|
27430
|
-
tsx: "^4.23.12",
|
|
27431
|
-
typescript: "^7.0.2",
|
|
27432
|
-
vitest: "^4.1.11"
|
|
27433
|
-
},
|
|
27434
|
-
dependencies: {
|
|
27435
|
-
"@agentclientprotocol/sdk": "^1.4.0",
|
|
27436
|
-
"@openai/codex": "^0.
|
|
27437
|
-
diff: "^9.0.0",
|
|
27438
|
-
open: "^11.0.1",
|
|
27439
|
-
"vscode-jsonrpc": "^9.0.1",
|
|
27440
|
-
zod: "^4.0.0"
|
|
27441
|
-
}
|
|
27442
|
-
};
|
|
27443
|
-
|
|
27444
|
-
// src/CollaborationModeConfig.ts
|
|
27445
|
-
var COLLABORATION_MODE_CONFIG_ID = "collaboration_mode";
|
|
27446
|
-
var DEFAULT_COLLABORATION_MODE = "default";
|
|
27447
|
-
var PLAN_COLLABORATION_MODE = "plan";
|
|
27448
|
-
function createCollaborationModeConfigOption(currentValue) {
|
|
27449
|
-
return {
|
|
27450
|
-
id: COLLABORATION_MODE_CONFIG_ID,
|
|
27451
|
-
name: "Collaboration mode",
|
|
27452
|
-
description: "How Codex collaborates for subsequent turns",
|
|
27453
|
-
category: "collaboration_mode",
|
|
27454
|
-
type: "select",
|
|
27455
|
-
currentValue,
|
|
27456
|
-
options: [
|
|
27457
|
-
{ value: DEFAULT_COLLABORATION_MODE, name: "Default" },
|
|
27458
|
-
{ value: PLAN_COLLABORATION_MODE, name: "Plan", description: "Plan before making changes" }
|
|
27459
|
-
]
|
|
27460
|
-
};
|
|
27461
|
-
}
|
|
27462
|
-
function parseCollaborationMode(value) {
|
|
27463
|
-
if (value === DEFAULT_COLLABORATION_MODE) return DEFAULT_COLLABORATION_MODE;
|
|
27464
|
-
if (value === PLAN_COLLABORATION_MODE) return PLAN_COLLABORATION_MODE;
|
|
27465
|
-
return null;
|
|
27466
|
-
}
|
|
27467
|
-
function createCodexCollaborationMode(mode, currentModelId) {
|
|
27468
|
-
const modelId = ModelId.fromString(currentModelId);
|
|
27469
|
-
return {
|
|
27470
|
-
mode,
|
|
27471
|
-
settings: {
|
|
27472
|
-
model: modelId.model,
|
|
27473
|
-
reasoning_effort: modelId.effort,
|
|
27474
|
-
developer_instructions: null
|
|
27475
|
-
}
|
|
27476
|
-
};
|
|
27477
|
-
}
|
|
27478
|
-
|
|
27479
|
-
// src/PathUtils.ts
|
|
27480
|
-
import path5 from "node:path";
|
|
27481
|
-
function isAbsolutePathLike(value) {
|
|
27482
|
-
const trimmed = value.trim();
|
|
27483
|
-
return path5.isAbsolute(trimmed) || isWindowsAbsolutePath(trimmed);
|
|
27484
|
-
}
|
|
27485
|
-
function arePathsEqual(left, right) {
|
|
27486
|
-
return normalizePathForComparison(left) === normalizePathForComparison(right);
|
|
27487
|
-
}
|
|
27488
|
-
function arePathBasenamesEqual(left, right) {
|
|
27489
|
-
const leftBase = path5.posix.basename(normalizePathForComparison(left));
|
|
27490
|
-
const rightBase = path5.posix.basename(normalizePathForComparison(right));
|
|
27491
|
-
if (shouldComparePathCaseInsensitive(left) || shouldComparePathCaseInsensitive(right)) {
|
|
27492
|
-
return leftBase.toLowerCase() === rightBase.toLowerCase();
|
|
27493
|
-
}
|
|
27494
|
-
return leftBase === rightBase;
|
|
27495
|
-
}
|
|
27496
|
-
function normalizePathForComparison(value) {
|
|
27497
|
-
const trimmed = value.trim();
|
|
27498
|
-
if (trimmed.length === 0) {
|
|
27499
|
-
return "";
|
|
27500
|
-
}
|
|
27501
|
-
if (isWindowsAbsolutePath(trimmed)) {
|
|
27502
|
-
const normalized2 = path5.win32.normalize(trimmed).replace(/\\/g, "/");
|
|
27503
|
-
return trimTrailingPathSeparators(normalized2).toLowerCase();
|
|
27504
|
-
}
|
|
27505
|
-
const pathForComparison = path5.isAbsolute(trimmed) ? trimmed : trimmed.replace(/\\/g, "/");
|
|
27506
|
-
const normalized = path5.posix.normalize(pathForComparison);
|
|
27507
|
-
return trimTrailingPathSeparators(normalized);
|
|
27508
|
-
}
|
|
27509
|
-
function isWindowsAbsolutePath(value) {
|
|
27510
|
-
const portableValue = value.replace(/\\/g, "/");
|
|
27511
|
-
return /^[A-Za-z]:\//.test(portableValue) || /^\/\/[^/]+\/[^/]+/.test(portableValue);
|
|
27512
|
-
}
|
|
27513
|
-
function shouldComparePathCaseInsensitive(value) {
|
|
27514
|
-
return isWindowsAbsolutePath(value) || /^[A-Za-z]:/.test(value) || value.includes("\\");
|
|
27515
|
-
}
|
|
27516
|
-
function trimTrailingPathSeparators(value) {
|
|
27517
|
-
let trimmed = value;
|
|
27518
|
-
while (trimmed.endsWith("/") && !isRootPath(trimmed)) {
|
|
27519
|
-
trimmed = trimmed.slice(0, -1);
|
|
27520
|
-
}
|
|
27521
|
-
return trimmed;
|
|
27522
|
-
}
|
|
27523
|
-
function isRootPath(value) {
|
|
27524
|
-
return value === "/" || /^[A-Za-z]:\/$/.test(value) || /^\/\/[^/]+\/[^/]+\/$/.test(value);
|
|
27525
|
-
}
|
|
27526
|
-
|
|
27527
|
-
// src/AgentFileChangeReport.ts
|
|
27528
|
-
import fs7 from "node:fs";
|
|
27529
|
-
import path6 from "node:path";
|
|
27530
|
-
var AGENT_FILE_CHANGE_REPORT_VERSION = 1;
|
|
27531
|
-
var AGENT_FILE_CHANGE_REPORT_TIMEOUT_MS = 3e4;
|
|
27532
|
-
var AGENT_FILE_CHANGE_REPORT_MAX_PATHS = 1024;
|
|
27533
|
-
var AGENT_FILE_CHANGE_REPORT_MAX_PATH_LENGTH = 4096;
|
|
27534
|
-
var AGENT_FILE_CHANGE_REPORT_MAX_TOTAL_BYTES = 256 * 1024;
|
|
27535
|
-
var AGENT_FILE_CHANGE_REPORT_MAX_UNCERTAINTY_LENGTH = 2e3;
|
|
27536
|
-
var AGENT_FILE_CHANGE_REPORT_OUTPUT_SCHEMA = {
|
|
27537
|
-
type: "object",
|
|
27538
|
-
additionalProperties: false,
|
|
27539
|
-
required: ["paths", "complete", "uncertainty"],
|
|
27540
|
-
properties: {
|
|
27541
|
-
paths: {
|
|
27542
|
-
type: "array",
|
|
27543
|
-
items: { type: "string" }
|
|
27544
|
-
},
|
|
27545
|
-
complete: { type: "boolean" },
|
|
27546
|
-
uncertainty: {
|
|
27547
|
-
anyOf: [{
|
|
27548
|
-
type: "string",
|
|
27549
|
-
maxLength: AGENT_FILE_CHANGE_REPORT_MAX_UNCERTAINTY_LENGTH
|
|
27550
|
-
}, {
|
|
27551
|
-
type: "null"
|
|
27552
|
-
}]
|
|
27553
|
-
}
|
|
27554
|
-
}
|
|
27555
|
-
};
|
|
27556
|
-
var AGENT_FILE_CHANGE_REPORT_DEVELOPER_INSTRUCTIONS = `You are running an internal, read-only file-change audit for the immediately preceding turn.
|
|
27557
|
-
Do not modify files, run commands that can modify files, or ask the user questions.
|
|
27558
|
-
Report files that the preceding turn causally created, modified, deleted, or moved, including changes made by shell commands, version-control commands, generators, and child processes.
|
|
27559
|
-
Do not report files that were only read or inspected.
|
|
27560
|
-
You may use read-only inspection when needed. If the list may be incomplete, set complete to false and briefly explain why in uncertainty.`;
|
|
27561
|
-
function createAgentFileChangeReportPrompt(workspace) {
|
|
27562
|
-
return `List the paths changed by the immediately preceding turn.
|
|
27563
|
-
Return only the structured result required by the output schema.
|
|
27564
|
-
Relative paths are resolved against the working directory.
|
|
27565
|
-
Working directory: ${JSON.stringify(workspace.cwd)}
|
|
27566
|
-
Additional allowed directories: ${JSON.stringify(workspace.additionalDirectories)}`;
|
|
27567
|
-
}
|
|
27568
|
-
function parseAgentFileChangeReportRequest(meta3) {
|
|
27569
|
-
const jetbrains = asRecord2(meta3?.[JETBRAINS_META_KEY]);
|
|
27570
|
-
const air = asRecord2(jetbrains?.[AIR_META_KEY]);
|
|
27571
|
-
const request = asRecord2(air?.[AIR_AGENT_FILE_CHANGE_REPORT_REQUEST_KEY]);
|
|
27572
|
-
if (request === null || !hasOnlyKeys(request, ["version", "requestId"]) || request["version"] !== AGENT_FILE_CHANGE_REPORT_VERSION) {
|
|
27573
|
-
return null;
|
|
27574
|
-
}
|
|
27575
|
-
const requestId = request["requestId"];
|
|
27576
|
-
if (typeof requestId !== "string" || !/^[A-Za-z0-9._:-]{1,128}$/.test(requestId)) {
|
|
27577
|
-
return null;
|
|
27578
|
-
}
|
|
27579
|
-
return { version: AGENT_FILE_CHANGE_REPORT_VERSION, requestId };
|
|
27580
|
-
}
|
|
27581
|
-
function createReportedAgentFileChangeReport(requestId, turn, workspace) {
|
|
27582
|
-
const modelReport = parseModelFileChangeReport(turn);
|
|
27583
|
-
const normalized = normalizeModelFileChangeReport(modelReport, workspace);
|
|
27584
|
-
return fitReportedAgentFileChangeReport({
|
|
27585
|
-
version: AGENT_FILE_CHANGE_REPORT_VERSION,
|
|
27586
|
-
requestId,
|
|
27587
|
-
status: "reported",
|
|
27588
|
-
...normalized
|
|
27589
|
-
});
|
|
27590
|
-
}
|
|
27591
|
-
function createUnavailableAgentFileChangeReport(requestId, reason) {
|
|
27592
|
-
return {
|
|
27593
|
-
version: AGENT_FILE_CHANGE_REPORT_VERSION,
|
|
27594
|
-
requestId,
|
|
27595
|
-
status: "unavailable",
|
|
27596
|
-
reason
|
|
27597
|
-
};
|
|
27598
|
-
}
|
|
27599
|
-
var AgentFileChangeReportError = class extends Error {
|
|
27600
|
-
reason;
|
|
27601
|
-
constructor(reason, message) {
|
|
27602
|
-
super(message);
|
|
27603
|
-
this.name = "AgentFileChangeReportError";
|
|
27604
|
-
this.reason = reason;
|
|
27605
|
-
}
|
|
27606
|
-
};
|
|
27607
|
-
function parseModelFileChangeReport(turn) {
|
|
27608
|
-
switch (turn.status) {
|
|
27609
|
-
case "interrupted":
|
|
27610
|
-
throw new AgentFileChangeReportError("cancelled", "The audit turn was interrupted");
|
|
27611
|
-
case "failed":
|
|
27612
|
-
throw new AgentFileChangeReportError(
|
|
27613
|
-
"providerError",
|
|
27614
|
-
`The audit turn failed${turn.error?.message ? `: ${turn.error.message}` : ""}`
|
|
27615
|
-
);
|
|
27616
|
-
case "inProgress":
|
|
27617
|
-
throw new AgentFileChangeReportError("notReported", "The audit turn did not complete");
|
|
27618
|
-
case "completed":
|
|
27619
|
-
break;
|
|
27620
|
-
}
|
|
27621
|
-
let text = null;
|
|
27622
|
-
for (let index = turn.items.length - 1; index >= 0; index -= 1) {
|
|
27623
|
-
const item = turn.items[index];
|
|
27624
|
-
if (item?.type === "agentMessage") {
|
|
27625
|
-
text = item.text;
|
|
27626
|
-
break;
|
|
27627
|
-
}
|
|
27628
|
-
}
|
|
27629
|
-
if (text === null) {
|
|
27630
|
-
throw new AgentFileChangeReportError("notReported", "The audit turn returned no agent message");
|
|
27631
|
-
}
|
|
27632
|
-
let value;
|
|
27633
|
-
try {
|
|
27634
|
-
value = JSON.parse(text);
|
|
27635
|
-
} catch {
|
|
27636
|
-
throw new AgentFileChangeReportError("invalidOutput", "The audit turn returned invalid JSON");
|
|
27637
|
-
}
|
|
27638
|
-
const report = asRecord2(value);
|
|
27639
|
-
if (report === null || !hasOnlyKeys(report, ["paths", "complete", "uncertainty"])) {
|
|
27640
|
-
throw new AgentFileChangeReportError("invalidOutput", "The audit turn returned an invalid object");
|
|
27641
|
-
}
|
|
27642
|
-
const paths = report["paths"];
|
|
27643
|
-
const complete = report["complete"];
|
|
27644
|
-
const uncertainty = report["uncertainty"];
|
|
27645
|
-
if (!Array.isArray(paths) || !paths.every((item) => typeof item === "string") || typeof complete !== "boolean" || uncertainty !== void 0 && uncertainty !== null && typeof uncertainty !== "string") {
|
|
27646
|
-
throw new AgentFileChangeReportError("invalidOutput", "The audit turn returned invalid fields");
|
|
27647
|
-
}
|
|
27648
|
-
const normalizedUncertainty = typeof uncertainty === "string" ? uncertainty.trim() : void 0;
|
|
27649
|
-
if (normalizedUncertainty !== void 0 && normalizedUncertainty.length > AGENT_FILE_CHANGE_REPORT_MAX_UNCERTAINTY_LENGTH) {
|
|
27650
|
-
throw new AgentFileChangeReportError("invalidOutput", "The audit turn returned oversized uncertainty");
|
|
27873
|
+
type: "module",
|
|
27874
|
+
devDependencies: {
|
|
27875
|
+
"@types/node": "^26.1.0",
|
|
27876
|
+
esbuild: "^0.28.2",
|
|
27877
|
+
"mcp-hello-world": "^1.1.2",
|
|
27878
|
+
tsx: "^4.23.12",
|
|
27879
|
+
typescript: "^7.0.2",
|
|
27880
|
+
vitest: "^4.1.11"
|
|
27881
|
+
},
|
|
27882
|
+
dependencies: {
|
|
27883
|
+
"@agentclientprotocol/sdk": "^1.4.0",
|
|
27884
|
+
"@openai/codex": "^0.154.0",
|
|
27885
|
+
diff: "^9.0.0",
|
|
27886
|
+
open: "^11.0.1",
|
|
27887
|
+
"vscode-jsonrpc": "^9.0.1",
|
|
27888
|
+
zod: "^4.0.0"
|
|
27651
27889
|
}
|
|
27890
|
+
};
|
|
27891
|
+
|
|
27892
|
+
// src/CollaborationModeConfig.ts
|
|
27893
|
+
var COLLABORATION_MODE_CONFIG_ID = "collaboration_mode";
|
|
27894
|
+
var DEFAULT_COLLABORATION_MODE = "default";
|
|
27895
|
+
var PLAN_COLLABORATION_MODE = "plan";
|
|
27896
|
+
function createCollaborationModeConfigOption(currentValue) {
|
|
27652
27897
|
return {
|
|
27653
|
-
|
|
27654
|
-
|
|
27655
|
-
|
|
27898
|
+
id: COLLABORATION_MODE_CONFIG_ID,
|
|
27899
|
+
name: "Collaboration mode",
|
|
27900
|
+
description: "How Codex collaborates for subsequent turns",
|
|
27901
|
+
category: "collaboration_mode",
|
|
27902
|
+
type: "select",
|
|
27903
|
+
currentValue,
|
|
27904
|
+
options: [
|
|
27905
|
+
{ value: DEFAULT_COLLABORATION_MODE, name: "Default" },
|
|
27906
|
+
{ value: PLAN_COLLABORATION_MODE, name: "Plan", description: "Plan before making changes" }
|
|
27907
|
+
]
|
|
27656
27908
|
};
|
|
27657
27909
|
}
|
|
27658
|
-
function
|
|
27659
|
-
|
|
27660
|
-
|
|
27661
|
-
|
|
27662
|
-
while (Buffer.byteLength(JSON.stringify(fitted), "utf8") > AGENT_FILE_CHANGE_REPORT_MAX_TOTAL_BYTES) {
|
|
27663
|
-
if (paths.length === 0) {
|
|
27664
|
-
throw new AgentFileChangeReportError("invalidOutput", "The audit report exceeds the wire limit");
|
|
27665
|
-
}
|
|
27666
|
-
paths.pop();
|
|
27667
|
-
truncated = true;
|
|
27668
|
-
fitted = {
|
|
27669
|
-
...report,
|
|
27670
|
-
paths: [...paths],
|
|
27671
|
-
declaredComplete: false,
|
|
27672
|
-
truncated
|
|
27673
|
-
};
|
|
27674
|
-
}
|
|
27675
|
-
return fitted;
|
|
27910
|
+
function parseCollaborationMode(value) {
|
|
27911
|
+
if (value === DEFAULT_COLLABORATION_MODE) return DEFAULT_COLLABORATION_MODE;
|
|
27912
|
+
if (value === PLAN_COLLABORATION_MODE) return PLAN_COLLABORATION_MODE;
|
|
27913
|
+
return null;
|
|
27676
27914
|
}
|
|
27677
|
-
function
|
|
27678
|
-
const
|
|
27679
|
-
if (cwd === null) {
|
|
27680
|
-
throw new AgentFileChangeReportError("providerError", "The session working directory is not absolute");
|
|
27681
|
-
}
|
|
27682
|
-
const roots = [cwd, ...workspace.additionalDirectories.flatMap((directory) => {
|
|
27683
|
-
const root = normalizeWorkspaceRoot(directory);
|
|
27684
|
-
return root === null || root.flavor !== cwd.flavor ? [] : [root];
|
|
27685
|
-
})];
|
|
27686
|
-
const paths = [];
|
|
27687
|
-
const seen = /* @__PURE__ */ new Set();
|
|
27688
|
-
let totalBytes = 0;
|
|
27689
|
-
let truncated = false;
|
|
27690
|
-
for (const reportedPath of report.paths) {
|
|
27691
|
-
if (reportedPath.length > AGENT_FILE_CHANGE_REPORT_MAX_PATH_LENGTH) {
|
|
27692
|
-
truncated = true;
|
|
27693
|
-
continue;
|
|
27694
|
-
}
|
|
27695
|
-
const normalized = normalizeReportedPath(reportedPath, cwd, roots);
|
|
27696
|
-
if (normalized === null || normalized.value.length > AGENT_FILE_CHANGE_REPORT_MAX_PATH_LENGTH) {
|
|
27697
|
-
truncated = true;
|
|
27698
|
-
continue;
|
|
27699
|
-
}
|
|
27700
|
-
const key = normalized.flavor === "windows" ? normalized.value.toLowerCase() : normalized.value;
|
|
27701
|
-
if (seen.has(key)) {
|
|
27702
|
-
continue;
|
|
27703
|
-
}
|
|
27704
|
-
const bytes = Buffer.byteLength(normalized.value, "utf8");
|
|
27705
|
-
if (paths.length >= AGENT_FILE_CHANGE_REPORT_MAX_PATHS || totalBytes + bytes > AGENT_FILE_CHANGE_REPORT_MAX_TOTAL_BYTES) {
|
|
27706
|
-
truncated = true;
|
|
27707
|
-
continue;
|
|
27708
|
-
}
|
|
27709
|
-
seen.add(key);
|
|
27710
|
-
paths.push(normalized.value);
|
|
27711
|
-
totalBytes += bytes;
|
|
27712
|
-
}
|
|
27915
|
+
function createCodexCollaborationMode(mode, currentModelId) {
|
|
27916
|
+
const modelId = ModelId.fromString(currentModelId);
|
|
27713
27917
|
return {
|
|
27714
|
-
|
|
27715
|
-
|
|
27716
|
-
|
|
27717
|
-
|
|
27918
|
+
mode,
|
|
27919
|
+
settings: {
|
|
27920
|
+
model: modelId.model,
|
|
27921
|
+
reasoning_effort: modelId.effort,
|
|
27922
|
+
developer_instructions: null
|
|
27923
|
+
}
|
|
27718
27924
|
};
|
|
27719
27925
|
}
|
|
27720
|
-
|
|
27721
|
-
|
|
27722
|
-
|
|
27723
|
-
|
|
27724
|
-
}
|
|
27725
|
-
if (isWindowsAbsolutePath2(trimmed)) {
|
|
27726
|
-
return canonicalizeWorkspaceRoot({
|
|
27727
|
-
value: path6.win32.normalize(trimmed.replace(/\//g, "\\")),
|
|
27728
|
-
flavor: "windows"
|
|
27729
|
-
});
|
|
27730
|
-
}
|
|
27731
|
-
if (path6.posix.isAbsolute(trimmed)) {
|
|
27732
|
-
return canonicalizeWorkspaceRoot({
|
|
27733
|
-
value: path6.posix.normalize(trimmed.replace(/\\/g, "/")),
|
|
27734
|
-
flavor: "posix"
|
|
27735
|
-
});
|
|
27736
|
-
}
|
|
27737
|
-
return null;
|
|
27738
|
-
}
|
|
27739
|
-
function normalizeReportedPath(value, cwd, roots) {
|
|
27926
|
+
|
|
27927
|
+
// src/PathUtils.ts
|
|
27928
|
+
import path6 from "node:path";
|
|
27929
|
+
function isAbsolutePathLike(value) {
|
|
27740
27930
|
const trimmed = value.trim();
|
|
27741
|
-
|
|
27742
|
-
return null;
|
|
27743
|
-
}
|
|
27744
|
-
let candidate;
|
|
27745
|
-
if (isWindowsAbsolutePath2(trimmed)) {
|
|
27746
|
-
candidate = { value: path6.win32.normalize(trimmed.replace(/\//g, "\\")), flavor: "windows" };
|
|
27747
|
-
} else if (path6.posix.isAbsolute(trimmed)) {
|
|
27748
|
-
candidate = { value: path6.posix.normalize(trimmed.replace(/\\/g, "/")), flavor: "posix" };
|
|
27749
|
-
} else if (cwd.flavor === "windows") {
|
|
27750
|
-
candidate = {
|
|
27751
|
-
value: path6.win32.resolve(cwd.value, trimmed.replace(/\//g, "\\")),
|
|
27752
|
-
flavor: "windows"
|
|
27753
|
-
};
|
|
27754
|
-
} else {
|
|
27755
|
-
candidate = {
|
|
27756
|
-
value: path6.posix.resolve(cwd.value, trimmed.replace(/\\/g, "/")),
|
|
27757
|
-
flavor: "posix"
|
|
27758
|
-
};
|
|
27759
|
-
}
|
|
27760
|
-
candidate = canonicalizeReportedPath(candidate);
|
|
27761
|
-
return roots.some((root) => pathIsStrictlyInside(root, candidate)) ? candidate : null;
|
|
27931
|
+
return path6.isAbsolute(trimmed) || isWindowsAbsolutePath2(trimmed);
|
|
27762
27932
|
}
|
|
27763
|
-
function
|
|
27764
|
-
|
|
27765
|
-
return root;
|
|
27766
|
-
}
|
|
27767
|
-
return { ...root, value: canonicalizeFromExistingAncestor(root.value) };
|
|
27933
|
+
function arePathsEqual(left, right) {
|
|
27934
|
+
return normalizePathForComparison(left) === normalizePathForComparison(right);
|
|
27768
27935
|
}
|
|
27769
|
-
function
|
|
27770
|
-
|
|
27771
|
-
|
|
27936
|
+
function arePathBasenamesEqual(left, right) {
|
|
27937
|
+
const leftBase = path6.posix.basename(normalizePathForComparison(left));
|
|
27938
|
+
const rightBase = path6.posix.basename(normalizePathForComparison(right));
|
|
27939
|
+
if (shouldComparePathCaseInsensitive(left) || shouldComparePathCaseInsensitive(right)) {
|
|
27940
|
+
return leftBase.toLowerCase() === rightBase.toLowerCase();
|
|
27772
27941
|
}
|
|
27773
|
-
|
|
27774
|
-
return { ...candidate, value: path6.resolve(parent, path6.basename(candidate.value)) };
|
|
27942
|
+
return leftBase === rightBase;
|
|
27775
27943
|
}
|
|
27776
|
-
function
|
|
27777
|
-
const
|
|
27778
|
-
|
|
27779
|
-
|
|
27780
|
-
while (true) {
|
|
27781
|
-
try {
|
|
27782
|
-
const canonical = fs7.realpathSync.native(current);
|
|
27783
|
-
return path6.resolve(canonical, ...missingSegments.reverse());
|
|
27784
|
-
} catch (error51) {
|
|
27785
|
-
if (!isMissingPathError(error51)) return original;
|
|
27786
|
-
}
|
|
27787
|
-
const parent = path6.dirname(current);
|
|
27788
|
-
if (parent === current) return original;
|
|
27789
|
-
missingSegments.push(path6.basename(current));
|
|
27790
|
-
current = parent;
|
|
27944
|
+
function normalizePathForComparison(value) {
|
|
27945
|
+
const trimmed = value.trim();
|
|
27946
|
+
if (trimmed.length === 0) {
|
|
27947
|
+
return "";
|
|
27791
27948
|
}
|
|
27792
|
-
|
|
27793
|
-
|
|
27794
|
-
|
|
27795
|
-
return error51.code === "ENOENT" || error51.code === "ENOTDIR";
|
|
27796
|
-
}
|
|
27797
|
-
function isNativePathFlavor(flavor) {
|
|
27798
|
-
return process.platform === "win32" ? flavor === "windows" : flavor === "posix";
|
|
27799
|
-
}
|
|
27800
|
-
function pathIsStrictlyInside(root, candidate) {
|
|
27801
|
-
if (root.flavor !== candidate.flavor) {
|
|
27802
|
-
return false;
|
|
27949
|
+
if (isWindowsAbsolutePath2(trimmed)) {
|
|
27950
|
+
const normalized2 = path6.win32.normalize(trimmed).replace(/\\/g, "/");
|
|
27951
|
+
return trimTrailingPathSeparators(normalized2).toLowerCase();
|
|
27803
27952
|
}
|
|
27804
|
-
const
|
|
27805
|
-
const
|
|
27806
|
-
return
|
|
27953
|
+
const pathForComparison = path6.isAbsolute(trimmed) ? trimmed : trimmed.replace(/\\/g, "/");
|
|
27954
|
+
const normalized = path6.posix.normalize(pathForComparison);
|
|
27955
|
+
return trimTrailingPathSeparators(normalized);
|
|
27807
27956
|
}
|
|
27808
27957
|
function isWindowsAbsolutePath2(value) {
|
|
27809
|
-
const
|
|
27810
|
-
return /^[A-Za-z]:\//.test(
|
|
27958
|
+
const portableValue = value.replace(/\\/g, "/");
|
|
27959
|
+
return /^[A-Za-z]:\//.test(portableValue) || /^\/\/[^/]+\/[^/]+/.test(portableValue);
|
|
27811
27960
|
}
|
|
27812
|
-
function
|
|
27813
|
-
return value
|
|
27961
|
+
function shouldComparePathCaseInsensitive(value) {
|
|
27962
|
+
return isWindowsAbsolutePath2(value) || /^[A-Za-z]:/.test(value) || value.includes("\\");
|
|
27814
27963
|
}
|
|
27815
|
-
function
|
|
27816
|
-
|
|
27964
|
+
function trimTrailingPathSeparators(value) {
|
|
27965
|
+
let trimmed = value;
|
|
27966
|
+
while (trimmed.endsWith("/") && !isRootPath(trimmed)) {
|
|
27967
|
+
trimmed = trimmed.slice(0, -1);
|
|
27968
|
+
}
|
|
27969
|
+
return trimmed;
|
|
27817
27970
|
}
|
|
27818
|
-
function
|
|
27819
|
-
|
|
27820
|
-
return Object.keys(value).every((key) => allowedKeys.has(key));
|
|
27971
|
+
function isRootPath(value) {
|
|
27972
|
+
return value === "/" || /^[A-Za-z]:\/$/.test(value) || /^\/\/[^/]+\/[^/]+\/$/.test(value);
|
|
27821
27973
|
}
|
|
27822
27974
|
|
|
27823
27975
|
// src/subagents/CodexSubagentSubscriptions.ts
|
|
@@ -27958,7 +28110,7 @@ async function forkSession(request, additionalDirectories, dependencies) {
|
|
|
27958
28110
|
modelProvider: response.modelProvider,
|
|
27959
28111
|
currentServiceTier: response.serviceTier ?? null,
|
|
27960
28112
|
additionalDirectories,
|
|
27961
|
-
|
|
28113
|
+
fullAccessApprovedMcpServers: prepared.fullAccessApprovedMcpServers
|
|
27962
28114
|
};
|
|
27963
28115
|
}
|
|
27964
28116
|
async function resolveForkTurnId(request, codexClient) {
|
|
@@ -28417,7 +28569,7 @@ var CodexAcpClient = class {
|
|
|
28417
28569
|
const initialAgentMode = AgentMode.getInitialAgentMode();
|
|
28418
28570
|
await this.refreshSkills(request.cwd, additionalDirectories);
|
|
28419
28571
|
const prepared = await this.createSessionConfig(request.cwd, additionalDirectories, request.mcpServers ?? []);
|
|
28420
|
-
await this.
|
|
28572
|
+
await this.restrictResumedMcpServers(request.sessionId, prepared);
|
|
28421
28573
|
const response = await this.codexClient.threadResume({
|
|
28422
28574
|
excludeTurns: true,
|
|
28423
28575
|
config: prepared.config,
|
|
@@ -28437,7 +28589,7 @@ var CodexAcpClient = class {
|
|
|
28437
28589
|
modelProvider: response.modelProvider,
|
|
28438
28590
|
currentServiceTier: response.serviceTier ?? null,
|
|
28439
28591
|
additionalDirectories,
|
|
28440
|
-
|
|
28592
|
+
fullAccessApprovedMcpServers: prepared.fullAccessApprovedMcpServers
|
|
28441
28593
|
};
|
|
28442
28594
|
}
|
|
28443
28595
|
async forkSession(request) {
|
|
@@ -28457,7 +28609,7 @@ var CodexAcpClient = class {
|
|
|
28457
28609
|
const initialAgentMode = AgentMode.getInitialAgentMode();
|
|
28458
28610
|
await this.refreshSkills(request.cwd, additionalDirectories);
|
|
28459
28611
|
const prepared = await this.createSessionConfig(request.cwd, additionalDirectories, request.mcpServers ?? []);
|
|
28460
|
-
await this.
|
|
28612
|
+
await this.restrictResumedMcpServers(request.sessionId, prepared);
|
|
28461
28613
|
const response = await this.codexClient.threadResume({
|
|
28462
28614
|
excludeTurns: true,
|
|
28463
28615
|
config: prepared.config,
|
|
@@ -28482,7 +28634,7 @@ var CodexAcpClient = class {
|
|
|
28482
28634
|
currentServiceTier: response.serviceTier ?? null,
|
|
28483
28635
|
thread,
|
|
28484
28636
|
additionalDirectories,
|
|
28485
|
-
|
|
28637
|
+
fullAccessApprovedMcpServers: prepared.fullAccessApprovedMcpServers
|
|
28486
28638
|
};
|
|
28487
28639
|
}
|
|
28488
28640
|
async readSessionThread(sessionId) {
|
|
@@ -28512,7 +28664,7 @@ var CodexAcpClient = class {
|
|
|
28512
28664
|
modelProvider: response.modelProvider,
|
|
28513
28665
|
currentServiceTier: response.serviceTier ?? null,
|
|
28514
28666
|
additionalDirectories,
|
|
28515
|
-
|
|
28667
|
+
fullAccessApprovedMcpServers: prepared.fullAccessApprovedMcpServers
|
|
28516
28668
|
};
|
|
28517
28669
|
}
|
|
28518
28670
|
async closeSession(sessionId) {
|
|
@@ -28539,10 +28691,10 @@ var CodexAcpClient = class {
|
|
|
28539
28691
|
if (!this.isProtectedFullAccess(agentMode)) return agentMode.approvalPolicy;
|
|
28540
28692
|
return { granular: { sandbox_approval: false, rules: false, skill_approval: false, request_permissions: false, mcp_elicitations: false } };
|
|
28541
28693
|
}
|
|
28542
|
-
async
|
|
28543
|
-
if (prepared.
|
|
28694
|
+
async restrictResumedMcpServers(sessionId, prepared) {
|
|
28695
|
+
if (prepared.fullAccessApprovedMcpServers.length === 0) return;
|
|
28544
28696
|
const loaded = await this.codexClient.threadLoadedList({});
|
|
28545
|
-
if (loaded.data.includes(sessionId) || loaded.nextCursor !== null) prepared.
|
|
28697
|
+
if (loaded.data.includes(sessionId) || loaded.nextCursor !== null) prepared.fullAccessApprovedMcpServers = [];
|
|
28546
28698
|
}
|
|
28547
28699
|
async deleteSession(sessionId) {
|
|
28548
28700
|
await this.codexClient.threadArchive({ threadId: sessionId });
|
|
@@ -28621,14 +28773,14 @@ var CodexAcpClient = class {
|
|
|
28621
28773
|
baseUrl: activeProvider.baseUrl
|
|
28622
28774
|
});
|
|
28623
28775
|
const mergedConfig = {
|
|
28624
|
-
...mergeGatewayConfig(this.config, this.gatewayConfig),
|
|
28776
|
+
...forceGitRootTurnDiffPaths(mergeGatewayConfig(this.config, this.gatewayConfig)),
|
|
28625
28777
|
projects: Object.fromEntries(sessionRoots2.map((root) => [root, {
|
|
28626
28778
|
trust_level: "trusted"
|
|
28627
28779
|
}]))
|
|
28628
28780
|
};
|
|
28629
28781
|
const configWithWorkspaceRoots = mergeSandboxWorkspaceWriteRoots(mergedConfig, additionalDirectories);
|
|
28630
28782
|
if (mcpServers.length === 0) {
|
|
28631
|
-
return { config: configWithWorkspaceRoots,
|
|
28783
|
+
return { config: configWithWorkspaceRoots, fullAccessApprovedMcpServers: [] };
|
|
28632
28784
|
}
|
|
28633
28785
|
const requestedServers = mcpServers.map((mcp) => ({
|
|
28634
28786
|
name: sanitizeMcpServerName(mcp.name),
|
|
@@ -28640,13 +28792,14 @@ var CodexAcpClient = class {
|
|
|
28640
28792
|
serversToConfigure = requestedServers.filter((mcp) => !existingNames.has(mcp.name));
|
|
28641
28793
|
}
|
|
28642
28794
|
if (serversToConfigure.length === 0) {
|
|
28643
|
-
return { config: configWithWorkspaceRoots,
|
|
28795
|
+
return { config: configWithWorkspaceRoots, fullAccessApprovedMcpServers: [] };
|
|
28644
28796
|
}
|
|
28645
28797
|
const configuredServers = Object.fromEntries(serversToConfigure.map((mcp) => [mcp.name, this.createMcpSeverConfig(mcp.server)]));
|
|
28646
28798
|
const inheritedServers = isJsonObject(this.config["mcp_servers"]) ? this.config["mcp_servers"] : {};
|
|
28647
28799
|
return {
|
|
28648
28800
|
config: { ...configWithWorkspaceRoots, mcp_servers: configuredServers },
|
|
28649
|
-
|
|
28801
|
+
// Every server the launcher injected, on any transport; a name any config layer also declares is never approved, so session config cannot borrow a launcher's name.
|
|
28802
|
+
fullAccessApprovedMcpServers: this.permissionProfileConfig ? Object.keys(configuredServers).filter((name) => !existingNames.has(name) && !Object.hasOwn(inheritedServers, name)) : []
|
|
28650
28803
|
};
|
|
28651
28804
|
}
|
|
28652
28805
|
async getConfigMcpServerNames(projectPath) {
|
|
@@ -28788,101 +28941,6 @@ var CodexAcpClient = class {
|
|
|
28788
28941
|
serviceTier
|
|
28789
28942
|
}, onTurnStarted);
|
|
28790
28943
|
}
|
|
28791
|
-
async runAgentFileChangeReport(params) {
|
|
28792
|
-
if (params.signal?.aborted) {
|
|
28793
|
-
return createUnavailableAgentFileChangeReport(params.requestId, "cancelled");
|
|
28794
|
-
}
|
|
28795
|
-
const budget = new AgentFileChangeReportBudget(params.signal);
|
|
28796
|
-
let forkThreadId = null;
|
|
28797
|
-
let auditTurnId = null;
|
|
28798
|
-
let auditTurnCompleted = false;
|
|
28799
|
-
let lateStopReason = null;
|
|
28800
|
-
try {
|
|
28801
|
-
const forkPromise = this.codexClient.threadFork({
|
|
28802
|
-
excludeTurns: true,
|
|
28803
|
-
threadId: params.sessionId,
|
|
28804
|
-
lastTurnId: params.turnId,
|
|
28805
|
-
cwd: params.workspace.cwd,
|
|
28806
|
-
approvalPolicy: "never",
|
|
28807
|
-
sandbox: "read-only",
|
|
28808
|
-
developerInstructions: AGENT_FILE_CHANGE_REPORT_DEVELOPER_INSTRUCTIONS,
|
|
28809
|
-
ephemeral: true
|
|
28810
|
-
});
|
|
28811
|
-
void forkPromise.then((fork2) => {
|
|
28812
|
-
if (lateStopReason !== null && forkThreadId === null) {
|
|
28813
|
-
void this.unsubscribeAgentFileChangeReportThread(fork2.thread.id, budget);
|
|
28814
|
-
}
|
|
28815
|
-
}, () => {
|
|
28816
|
-
});
|
|
28817
|
-
const fork = await budget.wait(forkPromise);
|
|
28818
|
-
forkThreadId = fork.thread.id;
|
|
28819
|
-
const turnPromise = this.codexClient.runTurn({
|
|
28820
|
-
threadId: forkThreadId,
|
|
28821
|
-
input: [{
|
|
28822
|
-
type: "text",
|
|
28823
|
-
text: createAgentFileChangeReportPrompt(params.workspace),
|
|
28824
|
-
text_elements: []
|
|
28825
|
-
}],
|
|
28826
|
-
cwd: params.workspace.cwd,
|
|
28827
|
-
approvalPolicy: "never",
|
|
28828
|
-
sandboxPolicy: { type: "readOnly", networkAccess: false },
|
|
28829
|
-
summary: "none",
|
|
28830
|
-
outputSchema: AGENT_FILE_CHANGE_REPORT_OUTPUT_SCHEMA
|
|
28831
|
-
}, (turnId) => {
|
|
28832
|
-
auditTurnId = turnId;
|
|
28833
|
-
if (lateStopReason !== null && forkThreadId !== null) {
|
|
28834
|
-
void this.interruptAgentFileChangeReport(forkThreadId, turnId, lateStopReason, budget);
|
|
28835
|
-
}
|
|
28836
|
-
});
|
|
28837
|
-
const outcome = await budget.wait(turnPromise);
|
|
28838
|
-
auditTurnCompleted = true;
|
|
28839
|
-
return createReportedAgentFileChangeReport(
|
|
28840
|
-
params.requestId,
|
|
28841
|
-
outcome.turn,
|
|
28842
|
-
params.workspace
|
|
28843
|
-
);
|
|
28844
|
-
} catch (error51) {
|
|
28845
|
-
if (error51 instanceof AgentFileChangeReportBudgetError) {
|
|
28846
|
-
lateStopReason = error51.reason;
|
|
28847
|
-
if (!auditTurnCompleted && forkThreadId !== null && auditTurnId !== null) {
|
|
28848
|
-
await this.interruptAgentFileChangeReport(
|
|
28849
|
-
forkThreadId,
|
|
28850
|
-
auditTurnId,
|
|
28851
|
-
error51.reason,
|
|
28852
|
-
budget
|
|
28853
|
-
);
|
|
28854
|
-
}
|
|
28855
|
-
return createUnavailableAgentFileChangeReport(params.requestId, error51.reason);
|
|
28856
|
-
}
|
|
28857
|
-
if (error51 instanceof AgentFileChangeReportError) {
|
|
28858
|
-
logger.error("Agent file-change report unavailable", error51);
|
|
28859
|
-
return createUnavailableAgentFileChangeReport(params.requestId, error51.reason);
|
|
28860
|
-
}
|
|
28861
|
-
logger.error("Agent file-change report failed", error51);
|
|
28862
|
-
return createUnavailableAgentFileChangeReport(params.requestId, "providerError");
|
|
28863
|
-
} finally {
|
|
28864
|
-
if (forkThreadId !== null) {
|
|
28865
|
-
await this.unsubscribeAgentFileChangeReportThread(forkThreadId, budget);
|
|
28866
|
-
}
|
|
28867
|
-
}
|
|
28868
|
-
}
|
|
28869
|
-
async interruptAgentFileChangeReport(threadId, turnId, reason, budget) {
|
|
28870
|
-
this.codexClient.markTurnStale(threadId, turnId);
|
|
28871
|
-
try {
|
|
28872
|
-
await budget.wait(this.codexClient.turnInterrupt({ threadId, turnId }));
|
|
28873
|
-
} catch (error51) {
|
|
28874
|
-
logger.error(`Failed to interrupt ${reason} agent file-change report`, error51);
|
|
28875
|
-
} finally {
|
|
28876
|
-
this.codexClient.resolveTurnInterrupted(threadId, turnId);
|
|
28877
|
-
}
|
|
28878
|
-
}
|
|
28879
|
-
async unsubscribeAgentFileChangeReportThread(threadId, budget) {
|
|
28880
|
-
try {
|
|
28881
|
-
await budget.wait(this.codexClient.threadUnsubscribe({ threadId }));
|
|
28882
|
-
} catch (error51) {
|
|
28883
|
-
logger.error("Failed to unsubscribe the agent file-change report thread", error51);
|
|
28884
|
-
}
|
|
28885
|
-
}
|
|
28886
28944
|
async setAgentMode(sessionId, agentMode) {
|
|
28887
28945
|
const config2 = this.permissionProfileConfig;
|
|
28888
28946
|
if (!config2) return;
|
|
@@ -29048,58 +29106,6 @@ var CodexAcpClient = class {
|
|
|
29048
29106
|
};
|
|
29049
29107
|
}
|
|
29050
29108
|
};
|
|
29051
|
-
var AgentFileChangeReportBudgetError = class extends Error {
|
|
29052
|
-
constructor(reason) {
|
|
29053
|
-
super(`Agent file-change report ${reason}`);
|
|
29054
|
-
this.reason = reason;
|
|
29055
|
-
this.name = "AgentFileChangeReportBudgetError";
|
|
29056
|
-
}
|
|
29057
|
-
reason;
|
|
29058
|
-
};
|
|
29059
|
-
var AgentFileChangeReportBudget = class {
|
|
29060
|
-
constructor(signal) {
|
|
29061
|
-
this.signal = signal;
|
|
29062
|
-
}
|
|
29063
|
-
signal;
|
|
29064
|
-
deadline = Date.now() + AGENT_FILE_CHANGE_REPORT_TIMEOUT_MS;
|
|
29065
|
-
async wait(operation) {
|
|
29066
|
-
void operation.catch(() => {
|
|
29067
|
-
});
|
|
29068
|
-
const immediateReason = this.stopReason();
|
|
29069
|
-
if (immediateReason !== null) {
|
|
29070
|
-
throw new AgentFileChangeReportBudgetError(immediateReason);
|
|
29071
|
-
}
|
|
29072
|
-
return await new Promise((resolve, reject) => {
|
|
29073
|
-
let settled = false;
|
|
29074
|
-
const finish = (action) => {
|
|
29075
|
-
if (settled) return;
|
|
29076
|
-
settled = true;
|
|
29077
|
-
clearTimeout(timeout);
|
|
29078
|
-
this.signal?.removeEventListener("abort", onAbort);
|
|
29079
|
-
action();
|
|
29080
|
-
};
|
|
29081
|
-
const onAbort = () => finish(() => reject(new AgentFileChangeReportBudgetError("cancelled")));
|
|
29082
|
-
const timeout = setTimeout(
|
|
29083
|
-
() => finish(() => reject(new AgentFileChangeReportBudgetError("timeout"))),
|
|
29084
|
-
Math.max(1, this.deadline - Date.now())
|
|
29085
|
-
);
|
|
29086
|
-
timeout.unref();
|
|
29087
|
-
this.signal?.addEventListener("abort", onAbort, { once: true });
|
|
29088
|
-
if (this.signal?.aborted) {
|
|
29089
|
-
onAbort();
|
|
29090
|
-
}
|
|
29091
|
-
void operation.then(
|
|
29092
|
-
(value) => finish(() => resolve(value)),
|
|
29093
|
-
(error51) => finish(() => reject(error51))
|
|
29094
|
-
);
|
|
29095
|
-
});
|
|
29096
|
-
}
|
|
29097
|
-
stopReason() {
|
|
29098
|
-
if (this.signal?.aborted) return "cancelled";
|
|
29099
|
-
if (Date.now() >= this.deadline) return "timeout";
|
|
29100
|
-
return null;
|
|
29101
|
-
}
|
|
29102
|
-
};
|
|
29103
29109
|
function buildPromptItems(prompt) {
|
|
29104
29110
|
return prompt.map((block) => {
|
|
29105
29111
|
switch (block.type) {
|
|
@@ -29214,6 +29220,16 @@ function mergeSandboxWorkspaceWriteRoots(config2, roots) {
|
|
|
29214
29220
|
}
|
|
29215
29221
|
};
|
|
29216
29222
|
}
|
|
29223
|
+
function forceGitRootTurnDiffPaths(config2) {
|
|
29224
|
+
const features = isJsonObject(config2["features"]) ? config2["features"] : {};
|
|
29225
|
+
return {
|
|
29226
|
+
...config2,
|
|
29227
|
+
features: {
|
|
29228
|
+
...features,
|
|
29229
|
+
cwd_relative_turn_diffs: false
|
|
29230
|
+
}
|
|
29231
|
+
};
|
|
29232
|
+
}
|
|
29217
29233
|
function addAdditionalDirectoriesToSandboxPolicy(sandboxPolicy, additionalDirectories) {
|
|
29218
29234
|
if (additionalDirectories.length === 0 || sandboxPolicy.type !== "workspaceWrite") {
|
|
29219
29235
|
return sandboxPolicy;
|
|
@@ -31011,6 +31027,7 @@ function createFunctionCallUpdate(item) {
|
|
|
31011
31027
|
if (!toolCallId || !name) {
|
|
31012
31028
|
return null;
|
|
31013
31029
|
}
|
|
31030
|
+
const toolName = functionToolName(name, stringValue(item["namespace"]));
|
|
31014
31031
|
const isExecCommand = name === "exec_command";
|
|
31015
31032
|
const args = parseFunctionArguments(item["arguments"]);
|
|
31016
31033
|
const command = isExecCommand ? commandFromFunctionArguments(args) : null;
|
|
@@ -31018,7 +31035,10 @@ function createFunctionCallUpdate(item) {
|
|
|
31018
31035
|
const commandAction = command ? inferCommandAction(command, cwd) : null;
|
|
31019
31036
|
if (commandAction) {
|
|
31020
31037
|
return {
|
|
31021
|
-
update:
|
|
31038
|
+
update: {
|
|
31039
|
+
...createCommandActionEvent(toolCallId, "inProgress", cwd, commandAction),
|
|
31040
|
+
name: toolName
|
|
31041
|
+
},
|
|
31022
31042
|
usesTerminal: false,
|
|
31023
31043
|
isExecCommand
|
|
31024
31044
|
};
|
|
@@ -31026,6 +31046,7 @@ function createFunctionCallUpdate(item) {
|
|
|
31026
31046
|
const update = {
|
|
31027
31047
|
sessionUpdate: "tool_call",
|
|
31028
31048
|
toolCallId,
|
|
31049
|
+
name: toolName,
|
|
31029
31050
|
kind: toolKindForFunctionCall(name),
|
|
31030
31051
|
title: titleForFunctionCall(name, args),
|
|
31031
31052
|
status: "in_progress",
|
|
@@ -32693,7 +32714,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
32693
32714
|
supportedReasoningEfforts: currentModel?.supportedReasoningEfforts ?? [],
|
|
32694
32715
|
supportedInputModalities: currentModel?.inputModalities ?? ["text", "image"],
|
|
32695
32716
|
agentMode: AgentMode.getInitialAgentMode(),
|
|
32696
|
-
|
|
32717
|
+
fullAccessApprovedMcpServers: sessionMetadata.fullAccessApprovedMcpServers ?? [],
|
|
32697
32718
|
collaborationMode: sessionMetadata.collaborationMode,
|
|
32698
32719
|
currentTurnId: null,
|
|
32699
32720
|
lastTokenUsage: null,
|
|
@@ -33033,7 +33054,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
33033
33054
|
additionalDirectories: session.additionalDirectories,
|
|
33034
33055
|
mcpServers: session.mcpServers ?? []
|
|
33035
33056
|
});
|
|
33036
|
-
session.
|
|
33057
|
+
session.fullAccessApprovedMcpServers = metadata.fullAccessApprovedMcpServers ?? [];
|
|
33037
33058
|
session.authProvider = replacement.getModelProvider();
|
|
33038
33059
|
session.asyncTasks.refresh();
|
|
33039
33060
|
logger.log("Resumed session after provider restart", { sessionId: session.sessionId });
|
|
@@ -33765,7 +33786,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
33765
33786
|
supportedReasoningEfforts: currentModel?.supportedReasoningEfforts ?? [],
|
|
33766
33787
|
supportedInputModalities: currentModel?.inputModalities ?? ["text", "image"],
|
|
33767
33788
|
agentMode: AgentMode.getInitialAgentMode(),
|
|
33768
|
-
|
|
33789
|
+
fullAccessApprovedMcpServers: sessionMetadata.fullAccessApprovedMcpServers ?? [],
|
|
33769
33790
|
collaborationMode: sessionMetadata.collaborationMode,
|
|
33770
33791
|
currentTurnId: null,
|
|
33771
33792
|
lastTokenUsage: null,
|
|
@@ -33979,24 +34000,19 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
33979
34000
|
title
|
|
33980
34001
|
});
|
|
33981
34002
|
}
|
|
33982
|
-
async publishAgentFileChangeReport(sessionState, turnId, request, unavailableReason,
|
|
34003
|
+
async publishAgentFileChangeReport(sessionState, turnId, request, unavailableReason, turnDiff, workspace) {
|
|
33983
34004
|
let report;
|
|
33984
34005
|
try {
|
|
33985
|
-
report = turnId === null ? createUnavailableAgentFileChangeReport(request.requestId, unavailableReason) :
|
|
33986
|
-
sessionId: sessionState.sessionId,
|
|
33987
|
-
turnId,
|
|
33988
|
-
// The client owns request-id correlation and duplicate suppression. The wrapper
|
|
33989
|
-
// stays stateless so a retried ACP prompt still receives a terminal report.
|
|
33990
|
-
requestId: request.requestId,
|
|
33991
|
-
workspace: {
|
|
33992
|
-
cwd: sessionState.cwd,
|
|
33993
|
-
additionalDirectories: sessionState.additionalDirectories
|
|
33994
|
-
},
|
|
33995
|
-
signal
|
|
33996
|
-
});
|
|
34006
|
+
report = turnId === null ? createUnavailableAgentFileChangeReport(request.requestId, unavailableReason) : createReportedAgentFileChangeReport(request.requestId, turnDiff, workspace);
|
|
33997
34007
|
} catch (error51) {
|
|
33998
|
-
logger.error(
|
|
33999
|
-
|
|
34008
|
+
logger.error(
|
|
34009
|
+
error51 instanceof AgentFileChangeReportError ? "Agent file-change report unavailable" : "Agent file-change report failed unexpectedly",
|
|
34010
|
+
error51
|
|
34011
|
+
);
|
|
34012
|
+
report = createUnavailableAgentFileChangeReport(
|
|
34013
|
+
request.requestId,
|
|
34014
|
+
error51 instanceof AgentFileChangeReportError ? error51.reason : "providerError"
|
|
34015
|
+
);
|
|
34000
34016
|
}
|
|
34001
34017
|
try {
|
|
34002
34018
|
const session = new ACPSessionConnection(this.connection, sessionState.sessionId);
|
|
@@ -34466,6 +34482,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
34466
34482
|
});
|
|
34467
34483
|
const sessionState = this.getSessionState(params.sessionId);
|
|
34468
34484
|
const agentFileChangeReportRequest = clientSupportsAgentFileChangeReports(this.clientCapabilities) ? parseAgentFileChangeReportRequest(params._meta) : null;
|
|
34485
|
+
const agentFileChangeWorkspace = agentFileChangeReportRequest === null ? null : captureAgentFileChangeWorkspace(sessionState.cwd, sessionState.additionalDirectories);
|
|
34469
34486
|
let agentFileChangeReportTurnId = null;
|
|
34470
34487
|
let agentFileChangeReportUnavailableReason = "providerError";
|
|
34471
34488
|
let promptWasCancelled = false;
|
|
@@ -34505,15 +34522,16 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
34505
34522
|
clientSupportsTypedSessionFailures(this.clientCapabilities),
|
|
34506
34523
|
this.sessionFailureEpoch,
|
|
34507
34524
|
sessionState.subagents,
|
|
34508
|
-
(accountUpdated) => this.handleAccountUpdated(accountUpdated)
|
|
34525
|
+
(accountUpdated) => this.handleAccountUpdated(accountUpdated),
|
|
34526
|
+
agentFileChangeReportRequest !== null
|
|
34509
34527
|
);
|
|
34510
34528
|
eventHandler = promptEventHandler;
|
|
34511
34529
|
const permissionLifecycle = this.permissionLifecycleContext(sessionState);
|
|
34512
34530
|
const permissionContext = permissionLifecycle.beginPrompt();
|
|
34513
34531
|
let promptAgentMode;
|
|
34514
34532
|
let permissionModeRevision;
|
|
34515
|
-
const
|
|
34516
|
-
const
|
|
34533
|
+
const approvedServers = new Set(sessionState.fullAccessApprovedMcpServers);
|
|
34534
|
+
const noApprovedServers = /* @__PURE__ */ new Set();
|
|
34517
34535
|
let mcpApprovalTurnId = null;
|
|
34518
34536
|
const isProtectedFullAccess = () => this.codexAcpClient.isProtectedFullAccess(promptAgentMode ?? sessionState.agentMode);
|
|
34519
34537
|
const approvalHandler = new CodexApprovalHandler(
|
|
@@ -34529,7 +34547,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
34529
34547
|
activePrompt.signal,
|
|
34530
34548
|
(request) => {
|
|
34531
34549
|
if (!isProtectedFullAccess()) return void 0;
|
|
34532
|
-
return mcpApprovalTurnId !== null && request.turnId === mcpApprovalTurnId && sessionState.agentMode.kind === "full_access" && sessionState.permissionModeRevision === permissionModeRevision ?
|
|
34550
|
+
return mcpApprovalTurnId !== null && request.turnId === mcpApprovalTurnId && sessionState.agentMode.kind === "full_access" && sessionState.permissionModeRevision === permissionModeRevision ? approvedServers : noApprovedServers;
|
|
34533
34551
|
}
|
|
34534
34552
|
);
|
|
34535
34553
|
const observeInteraction = async (event) => {
|
|
@@ -34876,13 +34894,21 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
34876
34894
|
} catch (error51) {
|
|
34877
34895
|
logger.error("Failed to publish terminal subagent state during prompt cleanup", error51);
|
|
34878
34896
|
}
|
|
34879
|
-
if (agentFileChangeReportRequest !== null) {
|
|
34897
|
+
if (agentFileChangeReportRequest !== null && agentFileChangeWorkspace !== null) {
|
|
34898
|
+
if (promptWasCancelled || activePrompt.signal.aborted || this.sessionIsClosing(params.sessionId)) {
|
|
34899
|
+
agentFileChangeReportTurnId = null;
|
|
34900
|
+
agentFileChangeReportUnavailableReason = "cancelled";
|
|
34901
|
+
} else if (agentFileChangeReportTurnId !== null && eventHandler?.isTurnDiffOversized(agentFileChangeReportTurnId)) {
|
|
34902
|
+
agentFileChangeReportTurnId = null;
|
|
34903
|
+
agentFileChangeReportUnavailableReason = "invalidOutput";
|
|
34904
|
+
}
|
|
34880
34905
|
await this.publishAgentFileChangeReport(
|
|
34881
34906
|
sessionState,
|
|
34882
34907
|
agentFileChangeReportTurnId,
|
|
34883
34908
|
agentFileChangeReportRequest,
|
|
34884
34909
|
agentFileChangeReportUnavailableReason,
|
|
34885
|
-
|
|
34910
|
+
agentFileChangeReportTurnId === null || eventHandler === null ? "" : eventHandler.getTurnDiff(agentFileChangeReportTurnId),
|
|
34911
|
+
agentFileChangeWorkspace
|
|
34886
34912
|
);
|
|
34887
34913
|
}
|
|
34888
34914
|
logger.log("Prompt completed", { sessionId: params.sessionId });
|