@agentclientprotocol/codex-acp 1.11.1-preview.4 → 1.11.1-preview.6
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 +582 -633
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -22772,6 +22772,111 @@ function reversePatch(structuredPatch) {
|
|
|
22772
22772
|
return reversed;
|
|
22773
22773
|
}
|
|
22774
22774
|
|
|
22775
|
+
// src/DiffStats.ts
|
|
22776
|
+
var DiffStatsCalculator = class {
|
|
22777
|
+
addedFile(text) {
|
|
22778
|
+
return { version: 1, added: this.lineCount(text), removed: 0 };
|
|
22779
|
+
}
|
|
22780
|
+
deletedFile(text) {
|
|
22781
|
+
return { version: 1, added: 0, removed: this.lineCount(text) };
|
|
22782
|
+
}
|
|
22783
|
+
update(patch) {
|
|
22784
|
+
if (patch.isBinary || patch.hunks.length === 0) return null;
|
|
22785
|
+
let added = 0;
|
|
22786
|
+
let removed = 0;
|
|
22787
|
+
let previousOldEnd = 1;
|
|
22788
|
+
let previousNewEnd = 1;
|
|
22789
|
+
for (const hunk of patch.hunks) {
|
|
22790
|
+
const { oldStart, oldLines, newStart, newLines } = hunk;
|
|
22791
|
+
if (![oldStart, oldLines, newStart, newLines].every(Number.isSafeInteger) || oldStart < previousOldEnd || newStart < previousNewEnd || oldLines < 0 || newLines < 0 || newStart - oldStart !== added - removed) return null;
|
|
22792
|
+
let oldConsumed = 0;
|
|
22793
|
+
let newConsumed = 0;
|
|
22794
|
+
let previousWasContent = false;
|
|
22795
|
+
for (const line of hunk.lines) {
|
|
22796
|
+
switch (line[0]) {
|
|
22797
|
+
case "+":
|
|
22798
|
+
added++;
|
|
22799
|
+
newConsumed++;
|
|
22800
|
+
previousWasContent = true;
|
|
22801
|
+
break;
|
|
22802
|
+
case "-":
|
|
22803
|
+
removed++;
|
|
22804
|
+
oldConsumed++;
|
|
22805
|
+
previousWasContent = true;
|
|
22806
|
+
break;
|
|
22807
|
+
case " ":
|
|
22808
|
+
case void 0:
|
|
22809
|
+
oldConsumed++;
|
|
22810
|
+
newConsumed++;
|
|
22811
|
+
previousWasContent = true;
|
|
22812
|
+
break;
|
|
22813
|
+
case "\\":
|
|
22814
|
+
if (!previousWasContent || line.replace(/\r$/, "") !== "\") return null;
|
|
22815
|
+
previousWasContent = false;
|
|
22816
|
+
break;
|
|
22817
|
+
default:
|
|
22818
|
+
return null;
|
|
22819
|
+
}
|
|
22820
|
+
}
|
|
22821
|
+
if (oldConsumed !== oldLines || newConsumed !== newLines) return null;
|
|
22822
|
+
previousOldEnd = oldStart + oldLines;
|
|
22823
|
+
previousNewEnd = newStart + newLines;
|
|
22824
|
+
}
|
|
22825
|
+
return { version: 1, added, removed };
|
|
22826
|
+
}
|
|
22827
|
+
lineCount(text) {
|
|
22828
|
+
let count = 0;
|
|
22829
|
+
for (let offset = text.indexOf("\n"); offset >= 0; offset = text.indexOf("\n", offset + 1)) count++;
|
|
22830
|
+
for (let offset = text.indexOf("\r"); offset >= 0; offset = text.indexOf("\r", offset + 1)) {
|
|
22831
|
+
if (text[offset + 1] !== "\n") count++;
|
|
22832
|
+
}
|
|
22833
|
+
if (text.length > 0 && !text.endsWith("\n") && !text.endsWith("\r")) count++;
|
|
22834
|
+
return count;
|
|
22835
|
+
}
|
|
22836
|
+
};
|
|
22837
|
+
|
|
22838
|
+
// src/AirExtension.ts
|
|
22839
|
+
var JETBRAINS_META_KEY = "jetbrains";
|
|
22840
|
+
var AIR_META_KEY = "air";
|
|
22841
|
+
var AIR_EXTENSION_VERSION_KEY = "version";
|
|
22842
|
+
var AIR_EXTENSION_CAPABILITIES_KEY = "capabilities";
|
|
22843
|
+
var AIR_DIFF_STATS_KEY = "diffStats";
|
|
22844
|
+
var AIR_SESSION_FAILURE_KEY = "sessionFailure";
|
|
22845
|
+
var AIR_AGENT_FILE_CHANGE_REPORT_KEY = "agentFileChangeReport";
|
|
22846
|
+
var AIR_NATIVE_SUBAGENT_SESSIONS_KEY = "nativeSubagentSessions";
|
|
22847
|
+
var AIR_ASYNC_TASKS_KEY = "asyncTasks";
|
|
22848
|
+
var AIR_RECOMMENDED_CONFIG_VALUE_KEY = "recommendedValue";
|
|
22849
|
+
var AIR_ASYNC_TASKS_BACKGROUNDED_KEY = "backgrounded";
|
|
22850
|
+
var AIR_AGENT_FILE_CHANGE_REPORT_REQUEST_KEY = "agentFileChangeReportRequest";
|
|
22851
|
+
var AIR_EXTENSION_VERSION = 1;
|
|
22852
|
+
function withAirMeta(meta3, key, value) {
|
|
22853
|
+
const root = asRecord(meta3);
|
|
22854
|
+
const jetbrains = asRecord(root[JETBRAINS_META_KEY]);
|
|
22855
|
+
const air = asRecord(jetbrains[AIR_META_KEY]);
|
|
22856
|
+
return {
|
|
22857
|
+
...root,
|
|
22858
|
+
[JETBRAINS_META_KEY]: {
|
|
22859
|
+
...jetbrains,
|
|
22860
|
+
[AIR_META_KEY]: {
|
|
22861
|
+
...air,
|
|
22862
|
+
[AIR_EXTENSION_VERSION_KEY]: AIR_EXTENSION_VERSION,
|
|
22863
|
+
[key]: value
|
|
22864
|
+
}
|
|
22865
|
+
}
|
|
22866
|
+
};
|
|
22867
|
+
}
|
|
22868
|
+
function clientSupportsAirCapability(capabilities, capability) {
|
|
22869
|
+
const meta3 = asRecord(capabilities?._meta);
|
|
22870
|
+
const jetbrains = asRecord(meta3[JETBRAINS_META_KEY]);
|
|
22871
|
+
const air = asRecord(jetbrains[AIR_META_KEY]);
|
|
22872
|
+
const version2 = air[AIR_EXTENSION_VERSION_KEY];
|
|
22873
|
+
const supported = air[AIR_EXTENSION_CAPABILITIES_KEY];
|
|
22874
|
+
return typeof version2 === "number" && Number.isInteger(version2) && version2 >= AIR_EXTENSION_VERSION && Array.isArray(supported) && supported.includes(capability);
|
|
22875
|
+
}
|
|
22876
|
+
function asRecord(value) {
|
|
22877
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
22878
|
+
}
|
|
22879
|
+
|
|
22775
22880
|
// src/CodexToolCallMapper.ts
|
|
22776
22881
|
import { readFile } from "node:fs/promises";
|
|
22777
22882
|
import path2 from "node:path";
|
|
@@ -22843,6 +22948,7 @@ function commandToolName(source) {
|
|
|
22843
22948
|
|
|
22844
22949
|
// src/CodexToolCallMapper.ts
|
|
22845
22950
|
var CONTEXT_COMPACTION_META = createContextCompactionMeta();
|
|
22951
|
+
var DIFF_STATS = new DiffStatsCalculator();
|
|
22846
22952
|
function toAcpStatus(status) {
|
|
22847
22953
|
switch (status) {
|
|
22848
22954
|
case "inProgress":
|
|
@@ -23507,53 +23613,43 @@ async function createAddFileContent(change) {
|
|
|
23507
23613
|
newText: change.diff,
|
|
23508
23614
|
// app-server always returns file content instead of diff
|
|
23509
23615
|
path: change.path,
|
|
23510
|
-
_meta: {
|
|
23511
|
-
kind: "add"
|
|
23512
|
-
}
|
|
23616
|
+
_meta: withAirMeta({ kind: "add" }, AIR_DIFF_STATS_KEY, DIFF_STATS.addedFile(change.diff))
|
|
23513
23617
|
};
|
|
23514
23618
|
}
|
|
23515
23619
|
async function createUpdateFileContent(change) {
|
|
23516
23620
|
if (change.kind.type !== "update") return null;
|
|
23517
23621
|
const unifiedDiff = recoverCorruptedDiff(change.diff);
|
|
23622
|
+
const patches = parsePatch(unifiedDiff);
|
|
23623
|
+
if (patches.length !== 1) return null;
|
|
23624
|
+
const patch = patches[0];
|
|
23518
23625
|
const movePath = change.kind.move_path;
|
|
23519
23626
|
const oldContent = await readFileContent(change.path);
|
|
23520
23627
|
if (oldContent !== null) {
|
|
23521
|
-
const patchedContent = applyPatch(oldContent,
|
|
23628
|
+
const patchedContent = applyPatch(oldContent, patch);
|
|
23522
23629
|
if (patchedContent === false) {
|
|
23523
|
-
const
|
|
23524
|
-
if (
|
|
23525
|
-
|
|
23526
|
-
if (revertedContent2 !== false) {
|
|
23527
|
-
return createUpdateDiffContent(change.path, revertedContent2, oldContent);
|
|
23528
|
-
}
|
|
23630
|
+
const revertedContent2 = applyPatch(oldContent, reversePatch(patch));
|
|
23631
|
+
if (revertedContent2 !== false) {
|
|
23632
|
+
return createUpdateDiffContent(change.path, revertedContent2, oldContent, patch);
|
|
23529
23633
|
}
|
|
23530
23634
|
return null;
|
|
23531
23635
|
}
|
|
23532
|
-
return createUpdateDiffContent(movePath ?? change.path, oldContent, patchedContent);
|
|
23636
|
+
return createUpdateDiffContent(movePath ?? change.path, oldContent, patchedContent, patch);
|
|
23533
23637
|
}
|
|
23534
23638
|
if (!movePath) return null;
|
|
23535
23639
|
const newContent = await readFileContent(movePath);
|
|
23536
23640
|
if (newContent === null) return null;
|
|
23537
|
-
const
|
|
23538
|
-
if (!revertedPatch) return null;
|
|
23539
|
-
const revertedContent = applyPatch(newContent, revertedPatch);
|
|
23641
|
+
const revertedContent = applyPatch(newContent, reversePatch(patch));
|
|
23540
23642
|
if (revertedContent === false) return null;
|
|
23541
|
-
return createUpdateDiffContent(movePath, revertedContent, newContent);
|
|
23643
|
+
return createUpdateDiffContent(movePath, revertedContent, newContent, patch);
|
|
23542
23644
|
}
|
|
23543
|
-
function
|
|
23544
|
-
const
|
|
23545
|
-
if (!patch) return null;
|
|
23546
|
-
return reversePatch(patch);
|
|
23547
|
-
}
|
|
23548
|
-
function createUpdateDiffContent(path9, oldText, newText) {
|
|
23645
|
+
function createUpdateDiffContent(path9, oldText, newText, patch) {
|
|
23646
|
+
const stats = DIFF_STATS.update(patch);
|
|
23549
23647
|
return {
|
|
23550
23648
|
type: "diff",
|
|
23551
23649
|
oldText,
|
|
23552
23650
|
newText,
|
|
23553
23651
|
path: path9,
|
|
23554
|
-
_meta: {
|
|
23555
|
-
kind: "update"
|
|
23556
|
-
}
|
|
23652
|
+
_meta: stats ? withAirMeta({ kind: "update" }, AIR_DIFF_STATS_KEY, stats) : { kind: "update" }
|
|
23557
23653
|
};
|
|
23558
23654
|
}
|
|
23559
23655
|
async function createDeleteFileContent(change) {
|
|
@@ -23563,9 +23659,7 @@ async function createDeleteFileContent(change) {
|
|
|
23563
23659
|
// app-server always returns file content instead of diff
|
|
23564
23660
|
newText: "",
|
|
23565
23661
|
path: change.path,
|
|
23566
|
-
_meta: {
|
|
23567
|
-
kind: "delete"
|
|
23568
|
-
}
|
|
23662
|
+
_meta: withAirMeta({ kind: "delete" }, AIR_DIFF_STATS_KEY, DIFF_STATS.deletedFile(change.diff))
|
|
23569
23663
|
};
|
|
23570
23664
|
}
|
|
23571
23665
|
async function readFileContent(filePath) {
|
|
@@ -23677,47 +23771,6 @@ function sameThreadGoalSnapshot(left, right) {
|
|
|
23677
23771
|
// src/CodexEventHandler.ts
|
|
23678
23772
|
import { randomUUID } from "node:crypto";
|
|
23679
23773
|
|
|
23680
|
-
// src/AirExtension.ts
|
|
23681
|
-
var JETBRAINS_META_KEY = "jetbrains";
|
|
23682
|
-
var AIR_META_KEY = "air";
|
|
23683
|
-
var AIR_EXTENSION_VERSION_KEY = "version";
|
|
23684
|
-
var AIR_EXTENSION_CAPABILITIES_KEY = "capabilities";
|
|
23685
|
-
var AIR_SESSION_FAILURE_KEY = "sessionFailure";
|
|
23686
|
-
var AIR_AGENT_FILE_CHANGE_REPORT_KEY = "agentFileChangeReport";
|
|
23687
|
-
var AIR_NATIVE_SUBAGENT_SESSIONS_KEY = "nativeSubagentSessions";
|
|
23688
|
-
var AIR_ASYNC_TASKS_KEY = "asyncTasks";
|
|
23689
|
-
var AIR_RECOMMENDED_CONFIG_VALUE_KEY = "recommendedValue";
|
|
23690
|
-
var AIR_ASYNC_TASKS_BACKGROUNDED_KEY = "backgrounded";
|
|
23691
|
-
var AIR_AGENT_FILE_CHANGE_REPORT_REQUEST_KEY = "agentFileChangeReportRequest";
|
|
23692
|
-
var AIR_EXTENSION_VERSION = 1;
|
|
23693
|
-
function withAirMeta(meta3, key, value) {
|
|
23694
|
-
const root = asRecord(meta3);
|
|
23695
|
-
const jetbrains = asRecord(root[JETBRAINS_META_KEY]);
|
|
23696
|
-
const air = asRecord(jetbrains[AIR_META_KEY]);
|
|
23697
|
-
return {
|
|
23698
|
-
...root,
|
|
23699
|
-
[JETBRAINS_META_KEY]: {
|
|
23700
|
-
...jetbrains,
|
|
23701
|
-
[AIR_META_KEY]: {
|
|
23702
|
-
...air,
|
|
23703
|
-
[AIR_EXTENSION_VERSION_KEY]: AIR_EXTENSION_VERSION,
|
|
23704
|
-
[key]: value
|
|
23705
|
-
}
|
|
23706
|
-
}
|
|
23707
|
-
};
|
|
23708
|
-
}
|
|
23709
|
-
function clientSupportsAirCapability(capabilities, capability) {
|
|
23710
|
-
const meta3 = asRecord(capabilities?._meta);
|
|
23711
|
-
const jetbrains = asRecord(meta3[JETBRAINS_META_KEY]);
|
|
23712
|
-
const air = asRecord(jetbrains[AIR_META_KEY]);
|
|
23713
|
-
const version2 = air[AIR_EXTENSION_VERSION_KEY];
|
|
23714
|
-
const supported = air[AIR_EXTENSION_CAPABILITIES_KEY];
|
|
23715
|
-
return typeof version2 === "number" && Number.isInteger(version2) && version2 >= AIR_EXTENSION_VERSION && Array.isArray(supported) && supported.includes(capability);
|
|
23716
|
-
}
|
|
23717
|
-
function asRecord(value) {
|
|
23718
|
-
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
23719
|
-
}
|
|
23720
|
-
|
|
23721
23774
|
// src/subagents/CodexAgentPath.ts
|
|
23722
23775
|
function normalizeAgentPath(path9) {
|
|
23723
23776
|
const normalized = path9.trim().replace(/\/+$/, "");
|
|
@@ -24147,6 +24200,305 @@ function mergeRateLimitSnapshot(previous, update) {
|
|
|
24147
24200
|
};
|
|
24148
24201
|
}
|
|
24149
24202
|
|
|
24203
|
+
// src/AgentFileChangeReport.ts
|
|
24204
|
+
import fs2 from "node:fs";
|
|
24205
|
+
import path3 from "node:path";
|
|
24206
|
+
var AGENT_FILE_CHANGE_REPORT_VERSION = 1;
|
|
24207
|
+
var AGENT_FILE_CHANGE_REPORT_MAX_PATHS = 1024;
|
|
24208
|
+
var AGENT_FILE_CHANGE_REPORT_MAX_PATH_LENGTH = 4096;
|
|
24209
|
+
var AGENT_FILE_CHANGE_REPORT_MAX_TOTAL_BYTES = 256 * 1024;
|
|
24210
|
+
var AGENT_FILE_CHANGE_REPORT_MAX_DIFF_BYTES = 8 * 1024 * 1024;
|
|
24211
|
+
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.";
|
|
24212
|
+
function captureAgentFileChangeWorkspace(cwd, additionalDirectories) {
|
|
24213
|
+
const lexicalCwd = parseWorkspaceRoot(cwd);
|
|
24214
|
+
return {
|
|
24215
|
+
cwd,
|
|
24216
|
+
additionalDirectories: [...additionalDirectories],
|
|
24217
|
+
diffRoot: lexicalCwd === null ? cwd : findDiffDisplayRoot(lexicalCwd).value
|
|
24218
|
+
};
|
|
24219
|
+
}
|
|
24220
|
+
function parseAgentFileChangeReportRequest(meta3) {
|
|
24221
|
+
const jetbrains = asRecord2(meta3?.[JETBRAINS_META_KEY]);
|
|
24222
|
+
const air = asRecord2(jetbrains?.[AIR_META_KEY]);
|
|
24223
|
+
const request = asRecord2(air?.[AIR_AGENT_FILE_CHANGE_REPORT_REQUEST_KEY]);
|
|
24224
|
+
if (request === null || !hasOnlyKeys(request, ["version", "requestId"]) || request["version"] !== AGENT_FILE_CHANGE_REPORT_VERSION) {
|
|
24225
|
+
return null;
|
|
24226
|
+
}
|
|
24227
|
+
const requestId = request["requestId"];
|
|
24228
|
+
if (typeof requestId !== "string" || !/^[A-Za-z0-9._:-]{1,128}$/.test(requestId)) {
|
|
24229
|
+
return null;
|
|
24230
|
+
}
|
|
24231
|
+
return { version: AGENT_FILE_CHANGE_REPORT_VERSION, requestId };
|
|
24232
|
+
}
|
|
24233
|
+
function createReportedAgentFileChangeReport(requestId, diff, workspace) {
|
|
24234
|
+
if (Buffer.byteLength(diff, "utf8") > AGENT_FILE_CHANGE_REPORT_MAX_DIFF_BYTES) {
|
|
24235
|
+
throw new AgentFileChangeReportError("invalidOutput", "The turn diff exceeds the parser input limit");
|
|
24236
|
+
}
|
|
24237
|
+
const parsedReport = parseTurnDiff(diff);
|
|
24238
|
+
const normalized = normalizeFileChangeReport(parsedReport, workspace);
|
|
24239
|
+
return fitReportedAgentFileChangeReport({
|
|
24240
|
+
version: AGENT_FILE_CHANGE_REPORT_VERSION,
|
|
24241
|
+
requestId,
|
|
24242
|
+
status: "reported",
|
|
24243
|
+
...normalized
|
|
24244
|
+
});
|
|
24245
|
+
}
|
|
24246
|
+
function createUnavailableAgentFileChangeReport(requestId, reason) {
|
|
24247
|
+
return {
|
|
24248
|
+
version: AGENT_FILE_CHANGE_REPORT_VERSION,
|
|
24249
|
+
requestId,
|
|
24250
|
+
status: "unavailable",
|
|
24251
|
+
reason
|
|
24252
|
+
};
|
|
24253
|
+
}
|
|
24254
|
+
var AgentFileChangeReportError = class extends Error {
|
|
24255
|
+
reason;
|
|
24256
|
+
constructor(reason, message) {
|
|
24257
|
+
super(message);
|
|
24258
|
+
this.name = "AgentFileChangeReportError";
|
|
24259
|
+
this.reason = reason;
|
|
24260
|
+
}
|
|
24261
|
+
};
|
|
24262
|
+
function parseTurnDiff(diff) {
|
|
24263
|
+
if (diff.trim() === "") {
|
|
24264
|
+
return { paths: [], complete: false, uncertainty: TURN_DIFF_UNCERTAINTY };
|
|
24265
|
+
}
|
|
24266
|
+
let patches;
|
|
24267
|
+
try {
|
|
24268
|
+
patches = parsePatch(diff);
|
|
24269
|
+
} catch (error51) {
|
|
24270
|
+
throw new AgentFileChangeReportError(
|
|
24271
|
+
"invalidOutput",
|
|
24272
|
+
`The turn diff is not valid unified diff: ${error51 instanceof Error ? error51.message : String(error51)}`
|
|
24273
|
+
);
|
|
24274
|
+
}
|
|
24275
|
+
if (patches.length === 0) {
|
|
24276
|
+
throw new AgentFileChangeReportError("invalidOutput", "The turn diff contains no parseable file patches");
|
|
24277
|
+
}
|
|
24278
|
+
const rawFileHeaders = extractRawFileHeaders(diff);
|
|
24279
|
+
const paths = [];
|
|
24280
|
+
for (const [index, patch] of patches.entries()) {
|
|
24281
|
+
const rawHeaders = rawFileHeaders[index];
|
|
24282
|
+
const oldPath = normalizeDiffPath(selectLosslessFileName(rawHeaders?.oldFileName, patch.oldFileName));
|
|
24283
|
+
const newPath = normalizeDiffPath(selectLosslessFileName(rawHeaders?.newFileName, patch.newFileName));
|
|
24284
|
+
if (oldPath === null && newPath === null) {
|
|
24285
|
+
throw new AgentFileChangeReportError("invalidOutput", "The turn diff contains a patch without a file path");
|
|
24286
|
+
}
|
|
24287
|
+
if (oldPath !== null) paths.push(oldPath);
|
|
24288
|
+
if (newPath !== null) paths.push(newPath);
|
|
24289
|
+
}
|
|
24290
|
+
return { paths, complete: false, uncertainty: TURN_DIFF_UNCERTAINTY };
|
|
24291
|
+
}
|
|
24292
|
+
function extractRawFileHeaders(diff) {
|
|
24293
|
+
return diff.split(/(?=^diff --git )/m).filter((section) => section.trim() !== "").map((section) => {
|
|
24294
|
+
const lines = section.split(/\r?\n/);
|
|
24295
|
+
for (let index = 0; index < lines.length; index += 1) {
|
|
24296
|
+
const line = lines[index];
|
|
24297
|
+
if (line?.startsWith("@@ ")) return null;
|
|
24298
|
+
const nextLine = lines[index + 1];
|
|
24299
|
+
if (line?.startsWith("--- ") && nextLine?.startsWith("+++ ")) {
|
|
24300
|
+
return {
|
|
24301
|
+
oldFileName: line.slice(4),
|
|
24302
|
+
newFileName: nextLine.slice(4)
|
|
24303
|
+
};
|
|
24304
|
+
}
|
|
24305
|
+
}
|
|
24306
|
+
return null;
|
|
24307
|
+
});
|
|
24308
|
+
}
|
|
24309
|
+
function selectLosslessFileName(rawFileName, parsedFileName) {
|
|
24310
|
+
return rawFileName === void 0 || rawFileName.startsWith('"') ? parsedFileName : rawFileName;
|
|
24311
|
+
}
|
|
24312
|
+
function normalizeDiffPath(value) {
|
|
24313
|
+
if (value === void 0 || value === "/dev/null") return null;
|
|
24314
|
+
return value.startsWith("a/") || value.startsWith("b/") ? value.slice(2) : value;
|
|
24315
|
+
}
|
|
24316
|
+
function fitReportedAgentFileChangeReport(report) {
|
|
24317
|
+
const paths = [...report.paths];
|
|
24318
|
+
let truncated = report.truncated;
|
|
24319
|
+
let fitted = report;
|
|
24320
|
+
while (Buffer.byteLength(JSON.stringify(fitted), "utf8") > AGENT_FILE_CHANGE_REPORT_MAX_TOTAL_BYTES) {
|
|
24321
|
+
if (paths.length === 0) {
|
|
24322
|
+
throw new AgentFileChangeReportError("invalidOutput", "The audit report exceeds the wire limit");
|
|
24323
|
+
}
|
|
24324
|
+
paths.pop();
|
|
24325
|
+
truncated = true;
|
|
24326
|
+
fitted = {
|
|
24327
|
+
...report,
|
|
24328
|
+
paths: [...paths],
|
|
24329
|
+
declaredComplete: false,
|
|
24330
|
+
truncated
|
|
24331
|
+
};
|
|
24332
|
+
}
|
|
24333
|
+
return fitted;
|
|
24334
|
+
}
|
|
24335
|
+
function normalizeFileChangeReport(report, workspace) {
|
|
24336
|
+
const lexicalCwd = parseWorkspaceRoot(workspace.cwd);
|
|
24337
|
+
if (lexicalCwd === null) {
|
|
24338
|
+
throw new AgentFileChangeReportError("providerError", "The session working directory is not absolute");
|
|
24339
|
+
}
|
|
24340
|
+
const cwd = canonicalizeWorkspaceRoot(lexicalCwd);
|
|
24341
|
+
const diffRoot = parseWorkspaceRoot(workspace.diffRoot);
|
|
24342
|
+
if (diffRoot === null || diffRoot.flavor !== cwd.flavor) {
|
|
24343
|
+
throw new AgentFileChangeReportError("providerError", "The captured turn-diff root is invalid");
|
|
24344
|
+
}
|
|
24345
|
+
const roots = [cwd, ...workspace.additionalDirectories.flatMap((directory) => {
|
|
24346
|
+
const root = normalizeWorkspaceRoot(directory);
|
|
24347
|
+
return root === null || root.flavor !== cwd.flavor ? [] : [root];
|
|
24348
|
+
})];
|
|
24349
|
+
const paths = [];
|
|
24350
|
+
const seen = /* @__PURE__ */ new Set();
|
|
24351
|
+
let totalBytes = 0;
|
|
24352
|
+
let truncated = false;
|
|
24353
|
+
for (const reportedPath of report.paths) {
|
|
24354
|
+
if (reportedPath.length > AGENT_FILE_CHANGE_REPORT_MAX_PATH_LENGTH) {
|
|
24355
|
+
truncated = true;
|
|
24356
|
+
continue;
|
|
24357
|
+
}
|
|
24358
|
+
const normalized = normalizeReportedPath(reportedPath, diffRoot, roots);
|
|
24359
|
+
if (normalized === null || normalized.value.length > AGENT_FILE_CHANGE_REPORT_MAX_PATH_LENGTH) {
|
|
24360
|
+
truncated = true;
|
|
24361
|
+
continue;
|
|
24362
|
+
}
|
|
24363
|
+
const key = normalized.flavor === "windows" ? normalized.value.toLowerCase() : normalized.value;
|
|
24364
|
+
if (seen.has(key)) {
|
|
24365
|
+
continue;
|
|
24366
|
+
}
|
|
24367
|
+
const bytes = Buffer.byteLength(normalized.value, "utf8");
|
|
24368
|
+
if (paths.length >= AGENT_FILE_CHANGE_REPORT_MAX_PATHS || totalBytes + bytes > AGENT_FILE_CHANGE_REPORT_MAX_TOTAL_BYTES) {
|
|
24369
|
+
truncated = true;
|
|
24370
|
+
continue;
|
|
24371
|
+
}
|
|
24372
|
+
seen.add(key);
|
|
24373
|
+
paths.push(normalized.value);
|
|
24374
|
+
totalBytes += bytes;
|
|
24375
|
+
}
|
|
24376
|
+
return {
|
|
24377
|
+
paths,
|
|
24378
|
+
declaredComplete: report.complete && !truncated,
|
|
24379
|
+
truncated,
|
|
24380
|
+
...report.uncertainty ? { uncertainty: report.uncertainty } : {}
|
|
24381
|
+
};
|
|
24382
|
+
}
|
|
24383
|
+
function normalizeWorkspaceRoot(value) {
|
|
24384
|
+
const root = parseWorkspaceRoot(value);
|
|
24385
|
+
return root === null ? null : canonicalizeWorkspaceRoot(root);
|
|
24386
|
+
}
|
|
24387
|
+
function parseWorkspaceRoot(value) {
|
|
24388
|
+
const trimmed = value.trim();
|
|
24389
|
+
if (!isValidPathText(trimmed)) {
|
|
24390
|
+
return null;
|
|
24391
|
+
}
|
|
24392
|
+
if (isWindowsAbsolutePath(trimmed)) {
|
|
24393
|
+
return {
|
|
24394
|
+
value: path3.win32.normalize(trimmed.replace(/\//g, "\\")),
|
|
24395
|
+
flavor: "windows"
|
|
24396
|
+
};
|
|
24397
|
+
}
|
|
24398
|
+
if (path3.posix.isAbsolute(trimmed)) {
|
|
24399
|
+
return {
|
|
24400
|
+
value: path3.posix.normalize(trimmed.replace(/\\/g, "/")),
|
|
24401
|
+
flavor: "posix"
|
|
24402
|
+
};
|
|
24403
|
+
}
|
|
24404
|
+
return null;
|
|
24405
|
+
}
|
|
24406
|
+
function normalizeReportedPath(value, relativeRoot, roots) {
|
|
24407
|
+
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)) {
|
|
24408
|
+
return null;
|
|
24409
|
+
}
|
|
24410
|
+
let candidate;
|
|
24411
|
+
if (isWindowsAbsolutePath(value)) {
|
|
24412
|
+
candidate = { value: path3.win32.normalize(value.replace(/\//g, "\\")), flavor: "windows" };
|
|
24413
|
+
} else if (path3.posix.isAbsolute(value)) {
|
|
24414
|
+
candidate = { value: path3.posix.normalize(value.replace(/\\/g, "/")), flavor: "posix" };
|
|
24415
|
+
} else if (relativeRoot.flavor === "windows") {
|
|
24416
|
+
candidate = {
|
|
24417
|
+
value: path3.win32.resolve(relativeRoot.value, value.replace(/\//g, "\\")),
|
|
24418
|
+
flavor: "windows"
|
|
24419
|
+
};
|
|
24420
|
+
} else {
|
|
24421
|
+
candidate = {
|
|
24422
|
+
value: path3.posix.resolve(relativeRoot.value, value.replace(/\\/g, "/")),
|
|
24423
|
+
flavor: "posix"
|
|
24424
|
+
};
|
|
24425
|
+
}
|
|
24426
|
+
candidate = canonicalizeReportedPath(candidate);
|
|
24427
|
+
return roots.some((root) => pathIsStrictlyInside(root, candidate)) ? candidate : null;
|
|
24428
|
+
}
|
|
24429
|
+
function findDiffDisplayRoot(cwd) {
|
|
24430
|
+
if (!isNativePathFlavor(cwd.flavor)) return cwd;
|
|
24431
|
+
const pathImplementation = cwd.flavor === "windows" ? path3.win32 : path3.posix;
|
|
24432
|
+
let current = cwd.value;
|
|
24433
|
+
while (true) {
|
|
24434
|
+
if (fs2.existsSync(pathImplementation.join(current, ".git"))) {
|
|
24435
|
+
return canonicalizeWorkspaceRoot({ value: current, flavor: cwd.flavor });
|
|
24436
|
+
}
|
|
24437
|
+
const parent = pathImplementation.dirname(current);
|
|
24438
|
+
if (parent === current) return cwd;
|
|
24439
|
+
current = parent;
|
|
24440
|
+
}
|
|
24441
|
+
}
|
|
24442
|
+
function canonicalizeWorkspaceRoot(root) {
|
|
24443
|
+
if (!isNativePathFlavor(root.flavor)) {
|
|
24444
|
+
return root;
|
|
24445
|
+
}
|
|
24446
|
+
return { ...root, value: canonicalizeFromExistingAncestor(root.value) };
|
|
24447
|
+
}
|
|
24448
|
+
function canonicalizeReportedPath(candidate) {
|
|
24449
|
+
if (!isNativePathFlavor(candidate.flavor)) {
|
|
24450
|
+
return candidate;
|
|
24451
|
+
}
|
|
24452
|
+
const parent = canonicalizeFromExistingAncestor(path3.dirname(candidate.value));
|
|
24453
|
+
return { ...candidate, value: path3.resolve(parent, path3.basename(candidate.value)) };
|
|
24454
|
+
}
|
|
24455
|
+
function canonicalizeFromExistingAncestor(value) {
|
|
24456
|
+
const original = path3.resolve(value);
|
|
24457
|
+
let current = original;
|
|
24458
|
+
const missingSegments = [];
|
|
24459
|
+
while (true) {
|
|
24460
|
+
try {
|
|
24461
|
+
const canonical = fs2.realpathSync.native(current);
|
|
24462
|
+
return path3.resolve(canonical, ...missingSegments.reverse());
|
|
24463
|
+
} catch (error51) {
|
|
24464
|
+
if (!isMissingPathError(error51)) return original;
|
|
24465
|
+
}
|
|
24466
|
+
const parent = path3.dirname(current);
|
|
24467
|
+
if (parent === current) return original;
|
|
24468
|
+
missingSegments.push(path3.basename(current));
|
|
24469
|
+
current = parent;
|
|
24470
|
+
}
|
|
24471
|
+
}
|
|
24472
|
+
function isMissingPathError(error51) {
|
|
24473
|
+
if (typeof error51 !== "object" || error51 === null || !("code" in error51)) return false;
|
|
24474
|
+
return error51.code === "ENOENT" || error51.code === "ENOTDIR";
|
|
24475
|
+
}
|
|
24476
|
+
function isNativePathFlavor(flavor) {
|
|
24477
|
+
return process.platform === "win32" ? flavor === "windows" : flavor === "posix";
|
|
24478
|
+
}
|
|
24479
|
+
function pathIsStrictlyInside(root, candidate) {
|
|
24480
|
+
if (root.flavor !== candidate.flavor) {
|
|
24481
|
+
return false;
|
|
24482
|
+
}
|
|
24483
|
+
const pathImplementation = root.flavor === "windows" ? path3.win32 : path3.posix;
|
|
24484
|
+
const relative = pathImplementation.relative(root.value, candidate.value);
|
|
24485
|
+
return relative.length > 0 && !pathImplementation.isAbsolute(relative) && relative !== ".." && !relative.startsWith(`..${pathImplementation.sep}`);
|
|
24486
|
+
}
|
|
24487
|
+
function isWindowsAbsolutePath(value) {
|
|
24488
|
+
const portable = value.replace(/\\/g, "/");
|
|
24489
|
+
return /^[A-Za-z]:\//.test(portable) || /^\/\/[^/]+\/[^/]+(?:\/|$)/.test(portable);
|
|
24490
|
+
}
|
|
24491
|
+
function isValidPathText(value) {
|
|
24492
|
+
return value.length > 0 && !/[\u0000-\u001F\u007F-\u009F]/.test(value);
|
|
24493
|
+
}
|
|
24494
|
+
function asRecord2(value) {
|
|
24495
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
|
|
24496
|
+
}
|
|
24497
|
+
function hasOnlyKeys(value, allowed) {
|
|
24498
|
+
const allowedKeys = new Set(allowed);
|
|
24499
|
+
return Object.keys(value).every((key) => allowedKeys.has(key));
|
|
24500
|
+
}
|
|
24501
|
+
|
|
24150
24502
|
// src/CodexEventHandler.ts
|
|
24151
24503
|
var MAX_SESSION_FAILURE_TITLE_LENGTH = 240;
|
|
24152
24504
|
var SESSION_FAILURE_POLICY = {
|
|
@@ -24254,6 +24606,9 @@ var CodexEventHandler = class _CodexEventHandler {
|
|
|
24254
24606
|
terminalCommandIds = /* @__PURE__ */ new Set();
|
|
24255
24607
|
terminalCommandOutputIds = /* @__PURE__ */ new Set();
|
|
24256
24608
|
agentMessagePhases = /* @__PURE__ */ new Map();
|
|
24609
|
+
turnDiffs = /* @__PURE__ */ new Map();
|
|
24610
|
+
oversizedTurnDiffs = /* @__PURE__ */ new Set();
|
|
24611
|
+
collectTurnDiffs;
|
|
24257
24612
|
subagents;
|
|
24258
24613
|
/** Connection-level `authStatus` sink; the app-server account push feeds it. */
|
|
24259
24614
|
onAccountUpdated;
|
|
@@ -24261,7 +24616,7 @@ var CodexEventHandler = class _CodexEventHandler {
|
|
|
24261
24616
|
sessionState.sessionId,
|
|
24262
24617
|
false,
|
|
24263
24618
|
new ACPSessionConnection(connection, sessionState.sessionId)
|
|
24264
|
-
), onAccountUpdated) {
|
|
24619
|
+
), onAccountUpdated, collectTurnDiffs = false) {
|
|
24265
24620
|
this.onAccountUpdated = onAccountUpdated;
|
|
24266
24621
|
this.sessionState = sessionState;
|
|
24267
24622
|
this.supportsPlanUpdates = supportsPlanUpdates;
|
|
@@ -24269,6 +24624,7 @@ var CodexEventHandler = class _CodexEventHandler {
|
|
|
24269
24624
|
this.sessionFailureEpoch = sessionFailureEpoch;
|
|
24270
24625
|
this.session = new ACPSessionConnection(connection, sessionState.sessionId);
|
|
24271
24626
|
this.subagents = subagents;
|
|
24627
|
+
this.collectTurnDiffs = collectTurnDiffs;
|
|
24272
24628
|
if (sessionState.sessionFailure !== void 0) {
|
|
24273
24629
|
this.failuresById.set(sessionState.sessionFailure.id, sessionState.sessionFailure);
|
|
24274
24630
|
}
|
|
@@ -24276,6 +24632,12 @@ var CodexEventHandler = class _CodexEventHandler {
|
|
|
24276
24632
|
getFailure() {
|
|
24277
24633
|
return this.failure;
|
|
24278
24634
|
}
|
|
24635
|
+
getTurnDiff(turnId) {
|
|
24636
|
+
return this.turnDiffs.get(turnId) ?? "";
|
|
24637
|
+
}
|
|
24638
|
+
isTurnDiffOversized(turnId) {
|
|
24639
|
+
return this.oversizedTurnDiffs.has(turnId);
|
|
24640
|
+
}
|
|
24279
24641
|
getTerminalSessionFailureMeta(turnId, allowUnattributed = false) {
|
|
24280
24642
|
const failure = this.sessionState.sessionFailure;
|
|
24281
24643
|
if (!this.supportsTypedSessionFailures || failure === void 0 || (this.failureTurnIdById.get(failure.id) === void 0 ? !allowUnattributed : turnId === null || this.failureTurnIdById.get(failure.id) !== turnId)) {
|
|
@@ -24435,6 +24797,8 @@ var CodexEventHandler = class _CodexEventHandler {
|
|
|
24435
24797
|
this.pendingPlanItemIds.clear();
|
|
24436
24798
|
this.planDeltaTextByItemId.clear();
|
|
24437
24799
|
this.lastEmittedPlanTextByItemId.clear();
|
|
24800
|
+
this.turnDiffs.clear();
|
|
24801
|
+
this.oversizedTurnDiffs.clear();
|
|
24438
24802
|
}
|
|
24439
24803
|
async createUpdateEvent(notification) {
|
|
24440
24804
|
switch (notification.method) {
|
|
@@ -24453,6 +24817,20 @@ var CodexEventHandler = class _CodexEventHandler {
|
|
|
24453
24817
|
case "turn/plan/updated":
|
|
24454
24818
|
this.completeRetryIncidentOnTurnProgress();
|
|
24455
24819
|
return await this.updatePlan(notification.params);
|
|
24820
|
+
case "turn/diff/updated":
|
|
24821
|
+
if (notification.params.threadId === this.sessionState.sessionId) {
|
|
24822
|
+
this.completeRetryIncidentOnTurnProgress();
|
|
24823
|
+
if (!this.disposed && this.collectTurnDiffs) {
|
|
24824
|
+
if (Buffer.byteLength(notification.params.diff, "utf8") > AGENT_FILE_CHANGE_REPORT_MAX_DIFF_BYTES) {
|
|
24825
|
+
this.turnDiffs.delete(notification.params.turnId);
|
|
24826
|
+
this.oversizedTurnDiffs.add(notification.params.turnId);
|
|
24827
|
+
} else {
|
|
24828
|
+
this.oversizedTurnDiffs.delete(notification.params.turnId);
|
|
24829
|
+
this.turnDiffs.set(notification.params.turnId, notification.params.diff);
|
|
24830
|
+
}
|
|
24831
|
+
}
|
|
24832
|
+
}
|
|
24833
|
+
return null;
|
|
24456
24834
|
case "error":
|
|
24457
24835
|
return await this.createErrorEvent(notification.params);
|
|
24458
24836
|
case "turn/started":
|
|
@@ -24547,7 +24925,6 @@ var CodexEventHandler = class _CodexEventHandler {
|
|
|
24547
24925
|
case "command/exec/outputDelta":
|
|
24548
24926
|
case "hook/started":
|
|
24549
24927
|
case "hook/completed":
|
|
24550
|
-
case "turn/diff/updated":
|
|
24551
24928
|
case "turn/moderationMetadata":
|
|
24552
24929
|
case "item/fileChange/outputDelta":
|
|
24553
24930
|
case "item/fileChange/patchUpdated":
|
|
@@ -26599,31 +26976,31 @@ function isCodexAuthRequest(request) {
|
|
|
26599
26976
|
|
|
26600
26977
|
// node_modules/open/index.js
|
|
26601
26978
|
import process11 from "node:process";
|
|
26602
|
-
import
|
|
26979
|
+
import path5 from "node:path";
|
|
26603
26980
|
import { fileURLToPath } from "node:url";
|
|
26604
26981
|
import childProcess4 from "node:child_process";
|
|
26605
|
-
import
|
|
26982
|
+
import fs7, { constants as fsConstants2 } from "node:fs/promises";
|
|
26606
26983
|
|
|
26607
26984
|
// node_modules/wsl-utils/index.js
|
|
26608
|
-
import
|
|
26985
|
+
import path4 from "node:path";
|
|
26609
26986
|
import { promisify as promisify2 } from "node:util";
|
|
26610
26987
|
import childProcess2 from "node:child_process";
|
|
26611
|
-
import
|
|
26988
|
+
import fs6, { constants as fsConstants } from "node:fs/promises";
|
|
26612
26989
|
|
|
26613
26990
|
// node_modules/is-wsl/index.js
|
|
26614
26991
|
import process3 from "node:process";
|
|
26615
26992
|
import os from "node:os";
|
|
26616
|
-
import
|
|
26993
|
+
import fs5 from "node:fs";
|
|
26617
26994
|
|
|
26618
26995
|
// node_modules/is-inside-container/index.js
|
|
26619
|
-
import
|
|
26996
|
+
import fs4 from "node:fs";
|
|
26620
26997
|
|
|
26621
26998
|
// node_modules/is-docker/index.js
|
|
26622
|
-
import
|
|
26999
|
+
import fs3 from "node:fs";
|
|
26623
27000
|
var isDockerCached;
|
|
26624
27001
|
function hasDockerEnv() {
|
|
26625
27002
|
try {
|
|
26626
|
-
|
|
27003
|
+
fs3.statSync("/.dockerenv");
|
|
26627
27004
|
return true;
|
|
26628
27005
|
} catch {
|
|
26629
27006
|
return false;
|
|
@@ -26631,7 +27008,7 @@ function hasDockerEnv() {
|
|
|
26631
27008
|
}
|
|
26632
27009
|
function hasDockerCGroup() {
|
|
26633
27010
|
try {
|
|
26634
|
-
return
|
|
27011
|
+
return fs3.readFileSync("/proc/self/cgroup", "utf8").includes("docker");
|
|
26635
27012
|
} catch {
|
|
26636
27013
|
return false;
|
|
26637
27014
|
}
|
|
@@ -26647,7 +27024,7 @@ function isDocker() {
|
|
|
26647
27024
|
var cachedResult;
|
|
26648
27025
|
var hasContainerEnv = () => {
|
|
26649
27026
|
try {
|
|
26650
|
-
|
|
27027
|
+
fs4.statSync("/run/.containerenv");
|
|
26651
27028
|
return true;
|
|
26652
27029
|
} catch {
|
|
26653
27030
|
return false;
|
|
@@ -26672,12 +27049,12 @@ var isWsl = () => {
|
|
|
26672
27049
|
return true;
|
|
26673
27050
|
}
|
|
26674
27051
|
try {
|
|
26675
|
-
if (
|
|
27052
|
+
if (fs5.readFileSync("/proc/version", "utf8").toLowerCase().includes("microsoft")) {
|
|
26676
27053
|
return !isInsideContainer();
|
|
26677
27054
|
}
|
|
26678
27055
|
} catch {
|
|
26679
27056
|
}
|
|
26680
|
-
if (
|
|
27057
|
+
if (fs5.existsSync("/proc/sys/fs/binfmt_misc/WSLInterop") || fs5.existsSync("/run/WSL")) {
|
|
26681
27058
|
return !isInsideContainer();
|
|
26682
27059
|
}
|
|
26683
27060
|
return false;
|
|
@@ -26745,14 +27122,14 @@ var wslDrivesMountPoint = /* @__PURE__ */ (() => {
|
|
|
26745
27122
|
const configFilePath = "/etc/wsl.conf";
|
|
26746
27123
|
let isConfigFileExists = false;
|
|
26747
27124
|
try {
|
|
26748
|
-
await
|
|
27125
|
+
await fs6.access(configFilePath, fsConstants.F_OK);
|
|
26749
27126
|
isConfigFileExists = true;
|
|
26750
27127
|
} catch {
|
|
26751
27128
|
}
|
|
26752
27129
|
if (!isConfigFileExists) {
|
|
26753
27130
|
return defaultMountPoint;
|
|
26754
27131
|
}
|
|
26755
|
-
const configContent = await
|
|
27132
|
+
const configContent = await fs6.readFile(configFilePath, { encoding: "utf8" });
|
|
26756
27133
|
const parsedMountPoint = parseMountPointFromConfig(configContent);
|
|
26757
27134
|
if (parsedMountPoint === void 0) {
|
|
26758
27135
|
return defaultMountPoint;
|
|
@@ -26772,7 +27149,7 @@ var canAccessPowerShell = async () => {
|
|
|
26772
27149
|
canAccessPowerShellPromise ??= (async () => {
|
|
26773
27150
|
try {
|
|
26774
27151
|
const psPath = await powerShellPath2();
|
|
26775
|
-
await
|
|
27152
|
+
await fs6.access(psPath, fsConstants.X_OK);
|
|
26776
27153
|
return true;
|
|
26777
27154
|
} catch {
|
|
26778
27155
|
return false;
|
|
@@ -26785,7 +27162,7 @@ var wslDefaultBrowser = async () => {
|
|
|
26785
27162
|
const command = String.raw`(Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice").ProgId`;
|
|
26786
27163
|
const { stdout } = await executePowerShell(command, {
|
|
26787
27164
|
powerShellPath: psPath,
|
|
26788
|
-
cwd:
|
|
27165
|
+
cwd: path4.dirname(psPath)
|
|
26789
27166
|
});
|
|
26790
27167
|
return stdout.trim();
|
|
26791
27168
|
};
|
|
@@ -26991,8 +27368,8 @@ var is_in_ssh_default = isInSsh;
|
|
|
26991
27368
|
|
|
26992
27369
|
// node_modules/open/index.js
|
|
26993
27370
|
var fallbackAttemptSymbol = /* @__PURE__ */ Symbol("fallbackAttempt");
|
|
26994
|
-
var __dirname = import.meta.url ?
|
|
26995
|
-
var localXdgOpenPath =
|
|
27371
|
+
var __dirname = import.meta.url ? path5.dirname(fileURLToPath(import.meta.url)) : "";
|
|
27372
|
+
var localXdgOpenPath = path5.join(__dirname, "xdg-open");
|
|
26996
27373
|
var { platform, arch } = process11;
|
|
26997
27374
|
var tryEachApp = async (apps2, opener) => {
|
|
26998
27375
|
if (apps2.length === 0) {
|
|
@@ -27134,7 +27511,7 @@ var baseOpen = async (options) => {
|
|
|
27134
27511
|
childProcessOptions.stdio = "ignore";
|
|
27135
27512
|
}
|
|
27136
27513
|
if (is_wsl_default) {
|
|
27137
|
-
childProcessOptions.cwd =
|
|
27514
|
+
childProcessOptions.cwd = path5.dirname(command);
|
|
27138
27515
|
}
|
|
27139
27516
|
} else {
|
|
27140
27517
|
if (app) {
|
|
@@ -27143,7 +27520,7 @@ var baseOpen = async (options) => {
|
|
|
27143
27520
|
const isBundled = !__dirname || __dirname === "/";
|
|
27144
27521
|
let exeLocalXdgOpen = false;
|
|
27145
27522
|
try {
|
|
27146
|
-
await
|
|
27523
|
+
await fs7.access(localXdgOpenPath, fsConstants2.X_OK);
|
|
27147
27524
|
exeLocalXdgOpen = true;
|
|
27148
27525
|
} catch {
|
|
27149
27526
|
}
|
|
@@ -27431,7 +27808,7 @@ var package_default = {
|
|
|
27431
27808
|
publishConfig: {
|
|
27432
27809
|
access: "public"
|
|
27433
27810
|
},
|
|
27434
|
-
version: "1.11.1-preview.
|
|
27811
|
+
version: "1.11.1-preview.6",
|
|
27435
27812
|
description: "",
|
|
27436
27813
|
main: "dist/index.js",
|
|
27437
27814
|
bin: {
|
|
@@ -27483,402 +27860,106 @@ var package_default = {
|
|
|
27483
27860
|
keywords: [],
|
|
27484
27861
|
author: "Agent Client Protocol",
|
|
27485
27862
|
license: "Apache-2.0",
|
|
27486
|
-
type: "module",
|
|
27487
|
-
devDependencies: {
|
|
27488
|
-
"@types/node": "^26.1.0",
|
|
27489
|
-
esbuild: "^0.28.2",
|
|
27490
|
-
"mcp-hello-world": "^1.1.2",
|
|
27491
|
-
tsx: "^4.23.12",
|
|
27492
|
-
typescript: "^7.0.2",
|
|
27493
|
-
vitest: "^4.1.11"
|
|
27494
|
-
},
|
|
27495
|
-
dependencies: {
|
|
27496
|
-
"@agentclientprotocol/sdk": "^1.4.0",
|
|
27497
|
-
"@openai/codex": "^0.154.0",
|
|
27498
|
-
diff: "^9.0.0",
|
|
27499
|
-
open: "^11.0.1",
|
|
27500
|
-
"vscode-jsonrpc": "^9.0.1",
|
|
27501
|
-
zod: "^4.0.0"
|
|
27502
|
-
}
|
|
27503
|
-
};
|
|
27504
|
-
|
|
27505
|
-
// src/CollaborationModeConfig.ts
|
|
27506
|
-
var COLLABORATION_MODE_CONFIG_ID = "collaboration_mode";
|
|
27507
|
-
var DEFAULT_COLLABORATION_MODE = "default";
|
|
27508
|
-
var PLAN_COLLABORATION_MODE = "plan";
|
|
27509
|
-
function createCollaborationModeConfigOption(currentValue) {
|
|
27510
|
-
return {
|
|
27511
|
-
id: COLLABORATION_MODE_CONFIG_ID,
|
|
27512
|
-
name: "Collaboration mode",
|
|
27513
|
-
description: "How Codex collaborates for subsequent turns",
|
|
27514
|
-
category: "collaboration_mode",
|
|
27515
|
-
type: "select",
|
|
27516
|
-
currentValue,
|
|
27517
|
-
options: [
|
|
27518
|
-
{ value: DEFAULT_COLLABORATION_MODE, name: "Default" },
|
|
27519
|
-
{ value: PLAN_COLLABORATION_MODE, name: "Plan", description: "Plan before making changes" }
|
|
27520
|
-
]
|
|
27521
|
-
};
|
|
27522
|
-
}
|
|
27523
|
-
function parseCollaborationMode(value) {
|
|
27524
|
-
if (value === DEFAULT_COLLABORATION_MODE) return DEFAULT_COLLABORATION_MODE;
|
|
27525
|
-
if (value === PLAN_COLLABORATION_MODE) return PLAN_COLLABORATION_MODE;
|
|
27526
|
-
return null;
|
|
27527
|
-
}
|
|
27528
|
-
function createCodexCollaborationMode(mode, currentModelId) {
|
|
27529
|
-
const modelId = ModelId.fromString(currentModelId);
|
|
27530
|
-
return {
|
|
27531
|
-
mode,
|
|
27532
|
-
settings: {
|
|
27533
|
-
model: modelId.model,
|
|
27534
|
-
reasoning_effort: modelId.effort,
|
|
27535
|
-
developer_instructions: null
|
|
27536
|
-
}
|
|
27537
|
-
};
|
|
27538
|
-
}
|
|
27539
|
-
|
|
27540
|
-
// src/PathUtils.ts
|
|
27541
|
-
import path5 from "node:path";
|
|
27542
|
-
function isAbsolutePathLike(value) {
|
|
27543
|
-
const trimmed = value.trim();
|
|
27544
|
-
return path5.isAbsolute(trimmed) || isWindowsAbsolutePath(trimmed);
|
|
27545
|
-
}
|
|
27546
|
-
function arePathsEqual(left, right) {
|
|
27547
|
-
return normalizePathForComparison(left) === normalizePathForComparison(right);
|
|
27548
|
-
}
|
|
27549
|
-
function arePathBasenamesEqual(left, right) {
|
|
27550
|
-
const leftBase = path5.posix.basename(normalizePathForComparison(left));
|
|
27551
|
-
const rightBase = path5.posix.basename(normalizePathForComparison(right));
|
|
27552
|
-
if (shouldComparePathCaseInsensitive(left) || shouldComparePathCaseInsensitive(right)) {
|
|
27553
|
-
return leftBase.toLowerCase() === rightBase.toLowerCase();
|
|
27554
|
-
}
|
|
27555
|
-
return leftBase === rightBase;
|
|
27556
|
-
}
|
|
27557
|
-
function normalizePathForComparison(value) {
|
|
27558
|
-
const trimmed = value.trim();
|
|
27559
|
-
if (trimmed.length === 0) {
|
|
27560
|
-
return "";
|
|
27561
|
-
}
|
|
27562
|
-
if (isWindowsAbsolutePath(trimmed)) {
|
|
27563
|
-
const normalized2 = path5.win32.normalize(trimmed).replace(/\\/g, "/");
|
|
27564
|
-
return trimTrailingPathSeparators(normalized2).toLowerCase();
|
|
27565
|
-
}
|
|
27566
|
-
const pathForComparison = path5.isAbsolute(trimmed) ? trimmed : trimmed.replace(/\\/g, "/");
|
|
27567
|
-
const normalized = path5.posix.normalize(pathForComparison);
|
|
27568
|
-
return trimTrailingPathSeparators(normalized);
|
|
27569
|
-
}
|
|
27570
|
-
function isWindowsAbsolutePath(value) {
|
|
27571
|
-
const portableValue = value.replace(/\\/g, "/");
|
|
27572
|
-
return /^[A-Za-z]:\//.test(portableValue) || /^\/\/[^/]+\/[^/]+/.test(portableValue);
|
|
27573
|
-
}
|
|
27574
|
-
function shouldComparePathCaseInsensitive(value) {
|
|
27575
|
-
return isWindowsAbsolutePath(value) || /^[A-Za-z]:/.test(value) || value.includes("\\");
|
|
27576
|
-
}
|
|
27577
|
-
function trimTrailingPathSeparators(value) {
|
|
27578
|
-
let trimmed = value;
|
|
27579
|
-
while (trimmed.endsWith("/") && !isRootPath(trimmed)) {
|
|
27580
|
-
trimmed = trimmed.slice(0, -1);
|
|
27581
|
-
}
|
|
27582
|
-
return trimmed;
|
|
27583
|
-
}
|
|
27584
|
-
function isRootPath(value) {
|
|
27585
|
-
return value === "/" || /^[A-Za-z]:\/$/.test(value) || /^\/\/[^/]+\/[^/]+\/$/.test(value);
|
|
27586
|
-
}
|
|
27587
|
-
|
|
27588
|
-
// src/AgentFileChangeReport.ts
|
|
27589
|
-
import fs7 from "node:fs";
|
|
27590
|
-
import path6 from "node:path";
|
|
27591
|
-
var AGENT_FILE_CHANGE_REPORT_VERSION = 1;
|
|
27592
|
-
var AGENT_FILE_CHANGE_REPORT_TIMEOUT_MS = 3e4;
|
|
27593
|
-
var AGENT_FILE_CHANGE_REPORT_MAX_PATHS = 1024;
|
|
27594
|
-
var AGENT_FILE_CHANGE_REPORT_MAX_PATH_LENGTH = 4096;
|
|
27595
|
-
var AGENT_FILE_CHANGE_REPORT_MAX_TOTAL_BYTES = 256 * 1024;
|
|
27596
|
-
var AGENT_FILE_CHANGE_REPORT_MAX_UNCERTAINTY_LENGTH = 2e3;
|
|
27597
|
-
var AGENT_FILE_CHANGE_REPORT_OUTPUT_SCHEMA = {
|
|
27598
|
-
type: "object",
|
|
27599
|
-
additionalProperties: false,
|
|
27600
|
-
required: ["paths", "complete", "uncertainty"],
|
|
27601
|
-
properties: {
|
|
27602
|
-
paths: {
|
|
27603
|
-
type: "array",
|
|
27604
|
-
items: { type: "string" }
|
|
27605
|
-
},
|
|
27606
|
-
complete: { type: "boolean" },
|
|
27607
|
-
uncertainty: {
|
|
27608
|
-
anyOf: [{
|
|
27609
|
-
type: "string",
|
|
27610
|
-
maxLength: AGENT_FILE_CHANGE_REPORT_MAX_UNCERTAINTY_LENGTH
|
|
27611
|
-
}, {
|
|
27612
|
-
type: "null"
|
|
27613
|
-
}]
|
|
27614
|
-
}
|
|
27615
|
-
}
|
|
27616
|
-
};
|
|
27617
|
-
var AGENT_FILE_CHANGE_REPORT_DEVELOPER_INSTRUCTIONS = `You are running an internal, read-only file-change audit for the immediately preceding turn.
|
|
27618
|
-
Do not modify files, run commands that can modify files, or ask the user questions.
|
|
27619
|
-
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.
|
|
27620
|
-
Do not report files that were only read or inspected.
|
|
27621
|
-
You may use read-only inspection when needed. If the list may be incomplete, set complete to false and briefly explain why in uncertainty.`;
|
|
27622
|
-
function createAgentFileChangeReportPrompt(workspace) {
|
|
27623
|
-
return `List the paths changed by the immediately preceding turn.
|
|
27624
|
-
Return only the structured result required by the output schema.
|
|
27625
|
-
Relative paths are resolved against the working directory.
|
|
27626
|
-
Working directory: ${JSON.stringify(workspace.cwd)}
|
|
27627
|
-
Additional allowed directories: ${JSON.stringify(workspace.additionalDirectories)}`;
|
|
27628
|
-
}
|
|
27629
|
-
function parseAgentFileChangeReportRequest(meta3) {
|
|
27630
|
-
const jetbrains = asRecord2(meta3?.[JETBRAINS_META_KEY]);
|
|
27631
|
-
const air = asRecord2(jetbrains?.[AIR_META_KEY]);
|
|
27632
|
-
const request = asRecord2(air?.[AIR_AGENT_FILE_CHANGE_REPORT_REQUEST_KEY]);
|
|
27633
|
-
if (request === null || !hasOnlyKeys(request, ["version", "requestId"]) || request["version"] !== AGENT_FILE_CHANGE_REPORT_VERSION) {
|
|
27634
|
-
return null;
|
|
27635
|
-
}
|
|
27636
|
-
const requestId = request["requestId"];
|
|
27637
|
-
if (typeof requestId !== "string" || !/^[A-Za-z0-9._:-]{1,128}$/.test(requestId)) {
|
|
27638
|
-
return null;
|
|
27639
|
-
}
|
|
27640
|
-
return { version: AGENT_FILE_CHANGE_REPORT_VERSION, requestId };
|
|
27641
|
-
}
|
|
27642
|
-
function createReportedAgentFileChangeReport(requestId, turn, workspace) {
|
|
27643
|
-
const modelReport = parseModelFileChangeReport(turn);
|
|
27644
|
-
const normalized = normalizeModelFileChangeReport(modelReport, workspace);
|
|
27645
|
-
return fitReportedAgentFileChangeReport({
|
|
27646
|
-
version: AGENT_FILE_CHANGE_REPORT_VERSION,
|
|
27647
|
-
requestId,
|
|
27648
|
-
status: "reported",
|
|
27649
|
-
...normalized
|
|
27650
|
-
});
|
|
27651
|
-
}
|
|
27652
|
-
function createUnavailableAgentFileChangeReport(requestId, reason) {
|
|
27653
|
-
return {
|
|
27654
|
-
version: AGENT_FILE_CHANGE_REPORT_VERSION,
|
|
27655
|
-
requestId,
|
|
27656
|
-
status: "unavailable",
|
|
27657
|
-
reason
|
|
27658
|
-
};
|
|
27659
|
-
}
|
|
27660
|
-
var AgentFileChangeReportError = class extends Error {
|
|
27661
|
-
reason;
|
|
27662
|
-
constructor(reason, message) {
|
|
27663
|
-
super(message);
|
|
27664
|
-
this.name = "AgentFileChangeReportError";
|
|
27665
|
-
this.reason = reason;
|
|
27666
|
-
}
|
|
27667
|
-
};
|
|
27668
|
-
function parseModelFileChangeReport(turn) {
|
|
27669
|
-
switch (turn.status) {
|
|
27670
|
-
case "interrupted":
|
|
27671
|
-
throw new AgentFileChangeReportError("cancelled", "The audit turn was interrupted");
|
|
27672
|
-
case "failed":
|
|
27673
|
-
throw new AgentFileChangeReportError(
|
|
27674
|
-
"providerError",
|
|
27675
|
-
`The audit turn failed${turn.error?.message ? `: ${turn.error.message}` : ""}`
|
|
27676
|
-
);
|
|
27677
|
-
case "inProgress":
|
|
27678
|
-
throw new AgentFileChangeReportError("notReported", "The audit turn did not complete");
|
|
27679
|
-
case "completed":
|
|
27680
|
-
break;
|
|
27681
|
-
}
|
|
27682
|
-
let text = null;
|
|
27683
|
-
for (let index = turn.items.length - 1; index >= 0; index -= 1) {
|
|
27684
|
-
const item = turn.items[index];
|
|
27685
|
-
if (item?.type === "agentMessage") {
|
|
27686
|
-
text = item.text;
|
|
27687
|
-
break;
|
|
27688
|
-
}
|
|
27689
|
-
}
|
|
27690
|
-
if (text === null) {
|
|
27691
|
-
throw new AgentFileChangeReportError("notReported", "The audit turn returned no agent message");
|
|
27692
|
-
}
|
|
27693
|
-
let value;
|
|
27694
|
-
try {
|
|
27695
|
-
value = JSON.parse(text);
|
|
27696
|
-
} catch {
|
|
27697
|
-
throw new AgentFileChangeReportError("invalidOutput", "The audit turn returned invalid JSON");
|
|
27698
|
-
}
|
|
27699
|
-
const report = asRecord2(value);
|
|
27700
|
-
if (report === null || !hasOnlyKeys(report, ["paths", "complete", "uncertainty"])) {
|
|
27701
|
-
throw new AgentFileChangeReportError("invalidOutput", "The audit turn returned an invalid object");
|
|
27702
|
-
}
|
|
27703
|
-
const paths = report["paths"];
|
|
27704
|
-
const complete = report["complete"];
|
|
27705
|
-
const uncertainty = report["uncertainty"];
|
|
27706
|
-
if (!Array.isArray(paths) || !paths.every((item) => typeof item === "string") || typeof complete !== "boolean" || uncertainty !== void 0 && uncertainty !== null && typeof uncertainty !== "string") {
|
|
27707
|
-
throw new AgentFileChangeReportError("invalidOutput", "The audit turn returned invalid fields");
|
|
27708
|
-
}
|
|
27709
|
-
const normalizedUncertainty = typeof uncertainty === "string" ? uncertainty.trim() : void 0;
|
|
27710
|
-
if (normalizedUncertainty !== void 0 && normalizedUncertainty.length > AGENT_FILE_CHANGE_REPORT_MAX_UNCERTAINTY_LENGTH) {
|
|
27711
|
-
throw new AgentFileChangeReportError("invalidOutput", "The audit turn returned oversized uncertainty");
|
|
27863
|
+
type: "module",
|
|
27864
|
+
devDependencies: {
|
|
27865
|
+
"@types/node": "^26.1.0",
|
|
27866
|
+
esbuild: "^0.28.2",
|
|
27867
|
+
"mcp-hello-world": "^1.1.2",
|
|
27868
|
+
tsx: "^4.23.12",
|
|
27869
|
+
typescript: "^7.0.2",
|
|
27870
|
+
vitest: "^4.1.11"
|
|
27871
|
+
},
|
|
27872
|
+
dependencies: {
|
|
27873
|
+
"@agentclientprotocol/sdk": "^1.4.0",
|
|
27874
|
+
"@openai/codex": "^0.154.0",
|
|
27875
|
+
diff: "^9.0.0",
|
|
27876
|
+
open: "^11.0.1",
|
|
27877
|
+
"vscode-jsonrpc": "^9.0.1",
|
|
27878
|
+
zod: "^4.0.0"
|
|
27712
27879
|
}
|
|
27880
|
+
};
|
|
27881
|
+
|
|
27882
|
+
// src/CollaborationModeConfig.ts
|
|
27883
|
+
var COLLABORATION_MODE_CONFIG_ID = "collaboration_mode";
|
|
27884
|
+
var DEFAULT_COLLABORATION_MODE = "default";
|
|
27885
|
+
var PLAN_COLLABORATION_MODE = "plan";
|
|
27886
|
+
function createCollaborationModeConfigOption(currentValue) {
|
|
27713
27887
|
return {
|
|
27714
|
-
|
|
27715
|
-
|
|
27716
|
-
|
|
27888
|
+
id: COLLABORATION_MODE_CONFIG_ID,
|
|
27889
|
+
name: "Collaboration mode",
|
|
27890
|
+
description: "How Codex collaborates for subsequent turns",
|
|
27891
|
+
category: "collaboration_mode",
|
|
27892
|
+
type: "select",
|
|
27893
|
+
currentValue,
|
|
27894
|
+
options: [
|
|
27895
|
+
{ value: DEFAULT_COLLABORATION_MODE, name: "Default" },
|
|
27896
|
+
{ value: PLAN_COLLABORATION_MODE, name: "Plan", description: "Plan before making changes" }
|
|
27897
|
+
]
|
|
27717
27898
|
};
|
|
27718
27899
|
}
|
|
27719
|
-
function
|
|
27720
|
-
|
|
27721
|
-
|
|
27722
|
-
|
|
27723
|
-
while (Buffer.byteLength(JSON.stringify(fitted), "utf8") > AGENT_FILE_CHANGE_REPORT_MAX_TOTAL_BYTES) {
|
|
27724
|
-
if (paths.length === 0) {
|
|
27725
|
-
throw new AgentFileChangeReportError("invalidOutput", "The audit report exceeds the wire limit");
|
|
27726
|
-
}
|
|
27727
|
-
paths.pop();
|
|
27728
|
-
truncated = true;
|
|
27729
|
-
fitted = {
|
|
27730
|
-
...report,
|
|
27731
|
-
paths: [...paths],
|
|
27732
|
-
declaredComplete: false,
|
|
27733
|
-
truncated
|
|
27734
|
-
};
|
|
27735
|
-
}
|
|
27736
|
-
return fitted;
|
|
27900
|
+
function parseCollaborationMode(value) {
|
|
27901
|
+
if (value === DEFAULT_COLLABORATION_MODE) return DEFAULT_COLLABORATION_MODE;
|
|
27902
|
+
if (value === PLAN_COLLABORATION_MODE) return PLAN_COLLABORATION_MODE;
|
|
27903
|
+
return null;
|
|
27737
27904
|
}
|
|
27738
|
-
function
|
|
27739
|
-
const
|
|
27740
|
-
if (cwd === null) {
|
|
27741
|
-
throw new AgentFileChangeReportError("providerError", "The session working directory is not absolute");
|
|
27742
|
-
}
|
|
27743
|
-
const roots = [cwd, ...workspace.additionalDirectories.flatMap((directory) => {
|
|
27744
|
-
const root = normalizeWorkspaceRoot(directory);
|
|
27745
|
-
return root === null || root.flavor !== cwd.flavor ? [] : [root];
|
|
27746
|
-
})];
|
|
27747
|
-
const paths = [];
|
|
27748
|
-
const seen = /* @__PURE__ */ new Set();
|
|
27749
|
-
let totalBytes = 0;
|
|
27750
|
-
let truncated = false;
|
|
27751
|
-
for (const reportedPath of report.paths) {
|
|
27752
|
-
if (reportedPath.length > AGENT_FILE_CHANGE_REPORT_MAX_PATH_LENGTH) {
|
|
27753
|
-
truncated = true;
|
|
27754
|
-
continue;
|
|
27755
|
-
}
|
|
27756
|
-
const normalized = normalizeReportedPath(reportedPath, cwd, roots);
|
|
27757
|
-
if (normalized === null || normalized.value.length > AGENT_FILE_CHANGE_REPORT_MAX_PATH_LENGTH) {
|
|
27758
|
-
truncated = true;
|
|
27759
|
-
continue;
|
|
27760
|
-
}
|
|
27761
|
-
const key = normalized.flavor === "windows" ? normalized.value.toLowerCase() : normalized.value;
|
|
27762
|
-
if (seen.has(key)) {
|
|
27763
|
-
continue;
|
|
27764
|
-
}
|
|
27765
|
-
const bytes = Buffer.byteLength(normalized.value, "utf8");
|
|
27766
|
-
if (paths.length >= AGENT_FILE_CHANGE_REPORT_MAX_PATHS || totalBytes + bytes > AGENT_FILE_CHANGE_REPORT_MAX_TOTAL_BYTES) {
|
|
27767
|
-
truncated = true;
|
|
27768
|
-
continue;
|
|
27769
|
-
}
|
|
27770
|
-
seen.add(key);
|
|
27771
|
-
paths.push(normalized.value);
|
|
27772
|
-
totalBytes += bytes;
|
|
27773
|
-
}
|
|
27905
|
+
function createCodexCollaborationMode(mode, currentModelId) {
|
|
27906
|
+
const modelId = ModelId.fromString(currentModelId);
|
|
27774
27907
|
return {
|
|
27775
|
-
|
|
27776
|
-
|
|
27777
|
-
|
|
27778
|
-
|
|
27908
|
+
mode,
|
|
27909
|
+
settings: {
|
|
27910
|
+
model: modelId.model,
|
|
27911
|
+
reasoning_effort: modelId.effort,
|
|
27912
|
+
developer_instructions: null
|
|
27913
|
+
}
|
|
27779
27914
|
};
|
|
27780
27915
|
}
|
|
27781
|
-
|
|
27782
|
-
|
|
27783
|
-
|
|
27784
|
-
|
|
27785
|
-
}
|
|
27786
|
-
if (isWindowsAbsolutePath2(trimmed)) {
|
|
27787
|
-
return canonicalizeWorkspaceRoot({
|
|
27788
|
-
value: path6.win32.normalize(trimmed.replace(/\//g, "\\")),
|
|
27789
|
-
flavor: "windows"
|
|
27790
|
-
});
|
|
27791
|
-
}
|
|
27792
|
-
if (path6.posix.isAbsolute(trimmed)) {
|
|
27793
|
-
return canonicalizeWorkspaceRoot({
|
|
27794
|
-
value: path6.posix.normalize(trimmed.replace(/\\/g, "/")),
|
|
27795
|
-
flavor: "posix"
|
|
27796
|
-
});
|
|
27797
|
-
}
|
|
27798
|
-
return null;
|
|
27799
|
-
}
|
|
27800
|
-
function normalizeReportedPath(value, cwd, roots) {
|
|
27916
|
+
|
|
27917
|
+
// src/PathUtils.ts
|
|
27918
|
+
import path6 from "node:path";
|
|
27919
|
+
function isAbsolutePathLike(value) {
|
|
27801
27920
|
const trimmed = value.trim();
|
|
27802
|
-
|
|
27803
|
-
return null;
|
|
27804
|
-
}
|
|
27805
|
-
let candidate;
|
|
27806
|
-
if (isWindowsAbsolutePath2(trimmed)) {
|
|
27807
|
-
candidate = { value: path6.win32.normalize(trimmed.replace(/\//g, "\\")), flavor: "windows" };
|
|
27808
|
-
} else if (path6.posix.isAbsolute(trimmed)) {
|
|
27809
|
-
candidate = { value: path6.posix.normalize(trimmed.replace(/\\/g, "/")), flavor: "posix" };
|
|
27810
|
-
} else if (cwd.flavor === "windows") {
|
|
27811
|
-
candidate = {
|
|
27812
|
-
value: path6.win32.resolve(cwd.value, trimmed.replace(/\//g, "\\")),
|
|
27813
|
-
flavor: "windows"
|
|
27814
|
-
};
|
|
27815
|
-
} else {
|
|
27816
|
-
candidate = {
|
|
27817
|
-
value: path6.posix.resolve(cwd.value, trimmed.replace(/\\/g, "/")),
|
|
27818
|
-
flavor: "posix"
|
|
27819
|
-
};
|
|
27820
|
-
}
|
|
27821
|
-
candidate = canonicalizeReportedPath(candidate);
|
|
27822
|
-
return roots.some((root) => pathIsStrictlyInside(root, candidate)) ? candidate : null;
|
|
27921
|
+
return path6.isAbsolute(trimmed) || isWindowsAbsolutePath2(trimmed);
|
|
27823
27922
|
}
|
|
27824
|
-
function
|
|
27825
|
-
|
|
27826
|
-
return root;
|
|
27827
|
-
}
|
|
27828
|
-
return { ...root, value: canonicalizeFromExistingAncestor(root.value) };
|
|
27923
|
+
function arePathsEqual(left, right) {
|
|
27924
|
+
return normalizePathForComparison(left) === normalizePathForComparison(right);
|
|
27829
27925
|
}
|
|
27830
|
-
function
|
|
27831
|
-
|
|
27832
|
-
|
|
27926
|
+
function arePathBasenamesEqual(left, right) {
|
|
27927
|
+
const leftBase = path6.posix.basename(normalizePathForComparison(left));
|
|
27928
|
+
const rightBase = path6.posix.basename(normalizePathForComparison(right));
|
|
27929
|
+
if (shouldComparePathCaseInsensitive(left) || shouldComparePathCaseInsensitive(right)) {
|
|
27930
|
+
return leftBase.toLowerCase() === rightBase.toLowerCase();
|
|
27833
27931
|
}
|
|
27834
|
-
|
|
27835
|
-
return { ...candidate, value: path6.resolve(parent, path6.basename(candidate.value)) };
|
|
27932
|
+
return leftBase === rightBase;
|
|
27836
27933
|
}
|
|
27837
|
-
function
|
|
27838
|
-
const
|
|
27839
|
-
|
|
27840
|
-
|
|
27841
|
-
while (true) {
|
|
27842
|
-
try {
|
|
27843
|
-
const canonical = fs7.realpathSync.native(current);
|
|
27844
|
-
return path6.resolve(canonical, ...missingSegments.reverse());
|
|
27845
|
-
} catch (error51) {
|
|
27846
|
-
if (!isMissingPathError(error51)) return original;
|
|
27847
|
-
}
|
|
27848
|
-
const parent = path6.dirname(current);
|
|
27849
|
-
if (parent === current) return original;
|
|
27850
|
-
missingSegments.push(path6.basename(current));
|
|
27851
|
-
current = parent;
|
|
27934
|
+
function normalizePathForComparison(value) {
|
|
27935
|
+
const trimmed = value.trim();
|
|
27936
|
+
if (trimmed.length === 0) {
|
|
27937
|
+
return "";
|
|
27852
27938
|
}
|
|
27853
|
-
|
|
27854
|
-
|
|
27855
|
-
|
|
27856
|
-
return error51.code === "ENOENT" || error51.code === "ENOTDIR";
|
|
27857
|
-
}
|
|
27858
|
-
function isNativePathFlavor(flavor) {
|
|
27859
|
-
return process.platform === "win32" ? flavor === "windows" : flavor === "posix";
|
|
27860
|
-
}
|
|
27861
|
-
function pathIsStrictlyInside(root, candidate) {
|
|
27862
|
-
if (root.flavor !== candidate.flavor) {
|
|
27863
|
-
return false;
|
|
27939
|
+
if (isWindowsAbsolutePath2(trimmed)) {
|
|
27940
|
+
const normalized2 = path6.win32.normalize(trimmed).replace(/\\/g, "/");
|
|
27941
|
+
return trimTrailingPathSeparators(normalized2).toLowerCase();
|
|
27864
27942
|
}
|
|
27865
|
-
const
|
|
27866
|
-
const
|
|
27867
|
-
return
|
|
27943
|
+
const pathForComparison = path6.isAbsolute(trimmed) ? trimmed : trimmed.replace(/\\/g, "/");
|
|
27944
|
+
const normalized = path6.posix.normalize(pathForComparison);
|
|
27945
|
+
return trimTrailingPathSeparators(normalized);
|
|
27868
27946
|
}
|
|
27869
27947
|
function isWindowsAbsolutePath2(value) {
|
|
27870
|
-
const
|
|
27871
|
-
return /^[A-Za-z]:\//.test(
|
|
27948
|
+
const portableValue = value.replace(/\\/g, "/");
|
|
27949
|
+
return /^[A-Za-z]:\//.test(portableValue) || /^\/\/[^/]+\/[^/]+/.test(portableValue);
|
|
27872
27950
|
}
|
|
27873
|
-
function
|
|
27874
|
-
return value
|
|
27951
|
+
function shouldComparePathCaseInsensitive(value) {
|
|
27952
|
+
return isWindowsAbsolutePath2(value) || /^[A-Za-z]:/.test(value) || value.includes("\\");
|
|
27875
27953
|
}
|
|
27876
|
-
function
|
|
27877
|
-
|
|
27954
|
+
function trimTrailingPathSeparators(value) {
|
|
27955
|
+
let trimmed = value;
|
|
27956
|
+
while (trimmed.endsWith("/") && !isRootPath(trimmed)) {
|
|
27957
|
+
trimmed = trimmed.slice(0, -1);
|
|
27958
|
+
}
|
|
27959
|
+
return trimmed;
|
|
27878
27960
|
}
|
|
27879
|
-
function
|
|
27880
|
-
|
|
27881
|
-
return Object.keys(value).every((key) => allowedKeys.has(key));
|
|
27961
|
+
function isRootPath(value) {
|
|
27962
|
+
return value === "/" || /^[A-Za-z]:\/$/.test(value) || /^\/\/[^/]+\/[^/]+\/$/.test(value);
|
|
27882
27963
|
}
|
|
27883
27964
|
|
|
27884
27965
|
// src/subagents/CodexSubagentSubscriptions.ts
|
|
@@ -28620,7 +28701,7 @@ var CodexAcpClient = class {
|
|
|
28620
28701
|
baseUrl: activeProvider.baseUrl
|
|
28621
28702
|
});
|
|
28622
28703
|
const mergedConfig = {
|
|
28623
|
-
...mergeGatewayConfig(this.config, this.gatewayConfig),
|
|
28704
|
+
...forceGitRootTurnDiffPaths(mergeGatewayConfig(this.config, this.gatewayConfig)),
|
|
28624
28705
|
projects: Object.fromEntries(sessionRoots.map((root) => [root, {
|
|
28625
28706
|
trust_level: "trusted"
|
|
28626
28707
|
}]))
|
|
@@ -28780,101 +28861,6 @@ var CodexAcpClient = class {
|
|
|
28780
28861
|
serviceTier
|
|
28781
28862
|
}, onTurnStarted);
|
|
28782
28863
|
}
|
|
28783
|
-
async runAgentFileChangeReport(params) {
|
|
28784
|
-
if (params.signal?.aborted) {
|
|
28785
|
-
return createUnavailableAgentFileChangeReport(params.requestId, "cancelled");
|
|
28786
|
-
}
|
|
28787
|
-
const budget = new AgentFileChangeReportBudget(params.signal);
|
|
28788
|
-
let forkThreadId = null;
|
|
28789
|
-
let auditTurnId = null;
|
|
28790
|
-
let auditTurnCompleted = false;
|
|
28791
|
-
let lateStopReason = null;
|
|
28792
|
-
try {
|
|
28793
|
-
const forkPromise = this.codexClient.threadFork({
|
|
28794
|
-
excludeTurns: true,
|
|
28795
|
-
threadId: params.sessionId,
|
|
28796
|
-
lastTurnId: params.turnId,
|
|
28797
|
-
cwd: params.workspace.cwd,
|
|
28798
|
-
approvalPolicy: "never",
|
|
28799
|
-
sandbox: "read-only",
|
|
28800
|
-
developerInstructions: AGENT_FILE_CHANGE_REPORT_DEVELOPER_INSTRUCTIONS,
|
|
28801
|
-
ephemeral: true
|
|
28802
|
-
});
|
|
28803
|
-
void forkPromise.then((fork2) => {
|
|
28804
|
-
if (lateStopReason !== null && forkThreadId === null) {
|
|
28805
|
-
void this.unsubscribeAgentFileChangeReportThread(fork2.thread.id, budget);
|
|
28806
|
-
}
|
|
28807
|
-
}, () => {
|
|
28808
|
-
});
|
|
28809
|
-
const fork = await budget.wait(forkPromise);
|
|
28810
|
-
forkThreadId = fork.thread.id;
|
|
28811
|
-
const turnPromise = this.codexClient.runTurn({
|
|
28812
|
-
threadId: forkThreadId,
|
|
28813
|
-
input: [{
|
|
28814
|
-
type: "text",
|
|
28815
|
-
text: createAgentFileChangeReportPrompt(params.workspace),
|
|
28816
|
-
text_elements: []
|
|
28817
|
-
}],
|
|
28818
|
-
cwd: params.workspace.cwd,
|
|
28819
|
-
approvalPolicy: "never",
|
|
28820
|
-
sandboxPolicy: { type: "readOnly", networkAccess: false },
|
|
28821
|
-
summary: "none",
|
|
28822
|
-
outputSchema: AGENT_FILE_CHANGE_REPORT_OUTPUT_SCHEMA
|
|
28823
|
-
}, (turnId) => {
|
|
28824
|
-
auditTurnId = turnId;
|
|
28825
|
-
if (lateStopReason !== null && forkThreadId !== null) {
|
|
28826
|
-
void this.interruptAgentFileChangeReport(forkThreadId, turnId, lateStopReason, budget);
|
|
28827
|
-
}
|
|
28828
|
-
});
|
|
28829
|
-
const outcome = await budget.wait(turnPromise);
|
|
28830
|
-
auditTurnCompleted = true;
|
|
28831
|
-
return createReportedAgentFileChangeReport(
|
|
28832
|
-
params.requestId,
|
|
28833
|
-
outcome.turn,
|
|
28834
|
-
params.workspace
|
|
28835
|
-
);
|
|
28836
|
-
} catch (error51) {
|
|
28837
|
-
if (error51 instanceof AgentFileChangeReportBudgetError) {
|
|
28838
|
-
lateStopReason = error51.reason;
|
|
28839
|
-
if (!auditTurnCompleted && forkThreadId !== null && auditTurnId !== null) {
|
|
28840
|
-
await this.interruptAgentFileChangeReport(
|
|
28841
|
-
forkThreadId,
|
|
28842
|
-
auditTurnId,
|
|
28843
|
-
error51.reason,
|
|
28844
|
-
budget
|
|
28845
|
-
);
|
|
28846
|
-
}
|
|
28847
|
-
return createUnavailableAgentFileChangeReport(params.requestId, error51.reason);
|
|
28848
|
-
}
|
|
28849
|
-
if (error51 instanceof AgentFileChangeReportError) {
|
|
28850
|
-
logger.error("Agent file-change report unavailable", error51);
|
|
28851
|
-
return createUnavailableAgentFileChangeReport(params.requestId, error51.reason);
|
|
28852
|
-
}
|
|
28853
|
-
logger.error("Agent file-change report failed", error51);
|
|
28854
|
-
return createUnavailableAgentFileChangeReport(params.requestId, "providerError");
|
|
28855
|
-
} finally {
|
|
28856
|
-
if (forkThreadId !== null) {
|
|
28857
|
-
await this.unsubscribeAgentFileChangeReportThread(forkThreadId, budget);
|
|
28858
|
-
}
|
|
28859
|
-
}
|
|
28860
|
-
}
|
|
28861
|
-
async interruptAgentFileChangeReport(threadId, turnId, reason, budget) {
|
|
28862
|
-
this.codexClient.markTurnStale(threadId, turnId);
|
|
28863
|
-
try {
|
|
28864
|
-
await budget.wait(this.codexClient.turnInterrupt({ threadId, turnId }));
|
|
28865
|
-
} catch (error51) {
|
|
28866
|
-
logger.error(`Failed to interrupt ${reason} agent file-change report`, error51);
|
|
28867
|
-
} finally {
|
|
28868
|
-
this.codexClient.resolveTurnInterrupted(threadId, turnId);
|
|
28869
|
-
}
|
|
28870
|
-
}
|
|
28871
|
-
async unsubscribeAgentFileChangeReportThread(threadId, budget) {
|
|
28872
|
-
try {
|
|
28873
|
-
await budget.wait(this.codexClient.threadUnsubscribe({ threadId }));
|
|
28874
|
-
} catch (error51) {
|
|
28875
|
-
logger.error("Failed to unsubscribe the agent file-change report thread", error51);
|
|
28876
|
-
}
|
|
28877
|
-
}
|
|
28878
28864
|
async setCollaborationMode(sessionId, mode, currentModelId) {
|
|
28879
28865
|
await this.codexClient.threadSettingsUpdate({
|
|
28880
28866
|
threadId: sessionId,
|
|
@@ -29031,58 +29017,6 @@ var CodexAcpClient = class {
|
|
|
29031
29017
|
};
|
|
29032
29018
|
}
|
|
29033
29019
|
};
|
|
29034
|
-
var AgentFileChangeReportBudgetError = class extends Error {
|
|
29035
|
-
constructor(reason) {
|
|
29036
|
-
super(`Agent file-change report ${reason}`);
|
|
29037
|
-
this.reason = reason;
|
|
29038
|
-
this.name = "AgentFileChangeReportBudgetError";
|
|
29039
|
-
}
|
|
29040
|
-
reason;
|
|
29041
|
-
};
|
|
29042
|
-
var AgentFileChangeReportBudget = class {
|
|
29043
|
-
constructor(signal) {
|
|
29044
|
-
this.signal = signal;
|
|
29045
|
-
}
|
|
29046
|
-
signal;
|
|
29047
|
-
deadline = Date.now() + AGENT_FILE_CHANGE_REPORT_TIMEOUT_MS;
|
|
29048
|
-
async wait(operation) {
|
|
29049
|
-
void operation.catch(() => {
|
|
29050
|
-
});
|
|
29051
|
-
const immediateReason = this.stopReason();
|
|
29052
|
-
if (immediateReason !== null) {
|
|
29053
|
-
throw new AgentFileChangeReportBudgetError(immediateReason);
|
|
29054
|
-
}
|
|
29055
|
-
return await new Promise((resolve, reject) => {
|
|
29056
|
-
let settled = false;
|
|
29057
|
-
const finish = (action) => {
|
|
29058
|
-
if (settled) return;
|
|
29059
|
-
settled = true;
|
|
29060
|
-
clearTimeout(timeout);
|
|
29061
|
-
this.signal?.removeEventListener("abort", onAbort);
|
|
29062
|
-
action();
|
|
29063
|
-
};
|
|
29064
|
-
const onAbort = () => finish(() => reject(new AgentFileChangeReportBudgetError("cancelled")));
|
|
29065
|
-
const timeout = setTimeout(
|
|
29066
|
-
() => finish(() => reject(new AgentFileChangeReportBudgetError("timeout"))),
|
|
29067
|
-
Math.max(1, this.deadline - Date.now())
|
|
29068
|
-
);
|
|
29069
|
-
timeout.unref();
|
|
29070
|
-
this.signal?.addEventListener("abort", onAbort, { once: true });
|
|
29071
|
-
if (this.signal?.aborted) {
|
|
29072
|
-
onAbort();
|
|
29073
|
-
}
|
|
29074
|
-
void operation.then(
|
|
29075
|
-
(value) => finish(() => resolve(value)),
|
|
29076
|
-
(error51) => finish(() => reject(error51))
|
|
29077
|
-
);
|
|
29078
|
-
});
|
|
29079
|
-
}
|
|
29080
|
-
stopReason() {
|
|
29081
|
-
if (this.signal?.aborted) return "cancelled";
|
|
29082
|
-
if (Date.now() >= this.deadline) return "timeout";
|
|
29083
|
-
return null;
|
|
29084
|
-
}
|
|
29085
|
-
};
|
|
29086
29020
|
function buildPromptItems(prompt) {
|
|
29087
29021
|
return prompt.map((block) => {
|
|
29088
29022
|
switch (block.type) {
|
|
@@ -29197,6 +29131,16 @@ function mergeSandboxWorkspaceWriteRoots(config2, roots) {
|
|
|
29197
29131
|
}
|
|
29198
29132
|
};
|
|
29199
29133
|
}
|
|
29134
|
+
function forceGitRootTurnDiffPaths(config2) {
|
|
29135
|
+
const features = isJsonObject(config2["features"]) ? config2["features"] : {};
|
|
29136
|
+
return {
|
|
29137
|
+
...config2,
|
|
29138
|
+
features: {
|
|
29139
|
+
...features,
|
|
29140
|
+
cwd_relative_turn_diffs: false
|
|
29141
|
+
}
|
|
29142
|
+
};
|
|
29143
|
+
}
|
|
29200
29144
|
function addAdditionalDirectoriesToSandboxPolicy(sandboxPolicy, additionalDirectories) {
|
|
29201
29145
|
if (additionalDirectories.length === 0 || sandboxPolicy.type !== "workspaceWrite") {
|
|
29202
29146
|
return sandboxPolicy;
|
|
@@ -33951,24 +33895,19 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
33951
33895
|
title
|
|
33952
33896
|
});
|
|
33953
33897
|
}
|
|
33954
|
-
async publishAgentFileChangeReport(sessionState, turnId, request, unavailableReason,
|
|
33898
|
+
async publishAgentFileChangeReport(sessionState, turnId, request, unavailableReason, turnDiff, workspace) {
|
|
33955
33899
|
let report;
|
|
33956
33900
|
try {
|
|
33957
|
-
report = turnId === null ? createUnavailableAgentFileChangeReport(request.requestId, unavailableReason) :
|
|
33958
|
-
sessionId: sessionState.sessionId,
|
|
33959
|
-
turnId,
|
|
33960
|
-
// The client owns request-id correlation and duplicate suppression. The wrapper
|
|
33961
|
-
// stays stateless so a retried ACP prompt still receives a terminal report.
|
|
33962
|
-
requestId: request.requestId,
|
|
33963
|
-
workspace: {
|
|
33964
|
-
cwd: sessionState.cwd,
|
|
33965
|
-
additionalDirectories: sessionState.additionalDirectories
|
|
33966
|
-
},
|
|
33967
|
-
signal
|
|
33968
|
-
});
|
|
33901
|
+
report = turnId === null ? createUnavailableAgentFileChangeReport(request.requestId, unavailableReason) : createReportedAgentFileChangeReport(request.requestId, turnDiff, workspace);
|
|
33969
33902
|
} catch (error51) {
|
|
33970
|
-
logger.error(
|
|
33971
|
-
|
|
33903
|
+
logger.error(
|
|
33904
|
+
error51 instanceof AgentFileChangeReportError ? "Agent file-change report unavailable" : "Agent file-change report failed unexpectedly",
|
|
33905
|
+
error51
|
|
33906
|
+
);
|
|
33907
|
+
report = createUnavailableAgentFileChangeReport(
|
|
33908
|
+
request.requestId,
|
|
33909
|
+
error51 instanceof AgentFileChangeReportError ? error51.reason : "providerError"
|
|
33910
|
+
);
|
|
33972
33911
|
}
|
|
33973
33912
|
try {
|
|
33974
33913
|
const session = new ACPSessionConnection(this.connection, sessionState.sessionId);
|
|
@@ -34438,6 +34377,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
34438
34377
|
});
|
|
34439
34378
|
const sessionState = this.getSessionState(params.sessionId);
|
|
34440
34379
|
const agentFileChangeReportRequest = clientSupportsAgentFileChangeReports(this.clientCapabilities) ? parseAgentFileChangeReportRequest(params._meta) : null;
|
|
34380
|
+
const agentFileChangeWorkspace = agentFileChangeReportRequest === null ? null : captureAgentFileChangeWorkspace(sessionState.cwd, sessionState.additionalDirectories);
|
|
34441
34381
|
let agentFileChangeReportTurnId = null;
|
|
34442
34382
|
let agentFileChangeReportUnavailableReason = "providerError";
|
|
34443
34383
|
let promptWasCancelled = false;
|
|
@@ -34476,7 +34416,8 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
34476
34416
|
clientSupportsTypedSessionFailures(this.clientCapabilities),
|
|
34477
34417
|
this.sessionFailureEpoch,
|
|
34478
34418
|
sessionState.subagents,
|
|
34479
|
-
(accountUpdated) => this.handleAccountUpdated(accountUpdated)
|
|
34419
|
+
(accountUpdated) => this.handleAccountUpdated(accountUpdated),
|
|
34420
|
+
agentFileChangeReportRequest !== null
|
|
34480
34421
|
);
|
|
34481
34422
|
eventHandler = promptEventHandler;
|
|
34482
34423
|
const permissionLifecycle = this.permissionLifecycleContext(sessionState);
|
|
@@ -34828,13 +34769,21 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
34828
34769
|
} catch (error51) {
|
|
34829
34770
|
logger.error("Failed to publish terminal subagent state during prompt cleanup", error51);
|
|
34830
34771
|
}
|
|
34831
|
-
if (agentFileChangeReportRequest !== null) {
|
|
34772
|
+
if (agentFileChangeReportRequest !== null && agentFileChangeWorkspace !== null) {
|
|
34773
|
+
if (promptWasCancelled || activePrompt.signal.aborted || this.sessionIsClosing(params.sessionId)) {
|
|
34774
|
+
agentFileChangeReportTurnId = null;
|
|
34775
|
+
agentFileChangeReportUnavailableReason = "cancelled";
|
|
34776
|
+
} else if (agentFileChangeReportTurnId !== null && eventHandler?.isTurnDiffOversized(agentFileChangeReportTurnId)) {
|
|
34777
|
+
agentFileChangeReportTurnId = null;
|
|
34778
|
+
agentFileChangeReportUnavailableReason = "invalidOutput";
|
|
34779
|
+
}
|
|
34832
34780
|
await this.publishAgentFileChangeReport(
|
|
34833
34781
|
sessionState,
|
|
34834
34782
|
agentFileChangeReportTurnId,
|
|
34835
34783
|
agentFileChangeReportRequest,
|
|
34836
34784
|
agentFileChangeReportUnavailableReason,
|
|
34837
|
-
|
|
34785
|
+
agentFileChangeReportTurnId === null || eventHandler === null ? "" : eventHandler.getTurnDiff(agentFileChangeReportTurnId),
|
|
34786
|
+
agentFileChangeWorkspace
|
|
34838
34787
|
);
|
|
34839
34788
|
}
|
|
34840
34789
|
logger.log("Prompt completed", { sessionId: params.sessionId });
|