@agentclientprotocol/codex-acp 1.11.1-preview.3 → 1.11.1-preview.5

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.
Files changed (2) hide show
  1. package/dist/index.js +165 -98
  2. package/package.json +2 -2
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, unifiedDiff);
23628
+ const patchedContent = applyPatch(oldContent, patch);
23522
23629
  if (patchedContent === false) {
23523
- const revertedPatch2 = revertPatch(unifiedDiff);
23524
- if (revertedPatch2) {
23525
- const revertedContent2 = applyPatch(oldContent, revertedPatch2);
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 revertedPatch = revertPatch(unifiedDiff);
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 revertPatch(unifiedDiff) {
23544
- const [patch] = parsePatch(unifiedDiff);
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(/\/+$/, "");
@@ -26090,7 +26143,9 @@ function cancelledResponse() {
26090
26143
  }
26091
26144
 
26092
26145
  // src/CodexElicitationHandler.ts
26093
- var USER_INPUT_OTHER_FIELD_SUFFIX = "__other";
26146
+ var USER_INPUT_NOTE_FIELD_SUFFIX = "_note";
26147
+ var USER_INPUT_OTHER_OPTION = "None of the above";
26148
+ var USER_INPUT_NOTE_PREFIX = "user_note: ";
26094
26149
  function normalizeElicitationSchema(value) {
26095
26150
  const normalized = normalizeElicitationSchemaValue(value);
26096
26151
  if (!isRecord2(normalized)) {
@@ -26147,16 +26202,14 @@ function elicitationResponseMeta(response, context, persist = void 0) {
26147
26202
  }
26148
26203
  return Object.keys(meta3).length === 0 ? null : meta3;
26149
26204
  }
26150
- function userInputOtherFieldId(questionId, questionIds) {
26151
- const base = `${questionId}${USER_INPUT_OTHER_FIELD_SUFFIX}`;
26152
- if (!questionIds.has(base)) {
26153
- return base;
26154
- }
26205
+ function userInputNoteFieldId(questionId, questionIds) {
26206
+ const base = `${questionId}${USER_INPUT_NOTE_FIELD_SUFFIX}`;
26207
+ let fieldId = base;
26155
26208
  let index = 1;
26156
- while (questionIds.has(`${base}${index}`)) {
26157
- index += 1;
26209
+ while (questionIds.has(fieldId)) {
26210
+ fieldId = `${base}${index++}`;
26158
26211
  }
26159
- return `${base}${index}`;
26212
+ return fieldId;
26160
26213
  }
26161
26214
  function userInputResponseValue(content, fieldId) {
26162
26215
  const value = content[fieldId];
@@ -26395,8 +26448,8 @@ var CodexElicitationHandler = class {
26395
26448
  const hasOptions = options.length > 0;
26396
26449
  const hasOtherAnswer = question.isOther && hasOptions;
26397
26450
  const base = {
26398
- title: question.header || question.id,
26399
- description: question.question,
26451
+ title: question.question || question.header || question.id,
26452
+ ...question.header ? { description: question.header } : {},
26400
26453
  _meta: {
26401
26454
  codex: {
26402
26455
  isOther: question.isOther,
@@ -26404,42 +26457,45 @@ var CodexElicitationHandler = class {
26404
26457
  }
26405
26458
  }
26406
26459
  };
26407
- if (!hasOtherAnswer) {
26408
- required2.push(question.id);
26409
- }
26460
+ required2.push(question.id);
26410
26461
  properties[question.id] = hasOptions ? {
26411
26462
  ...base,
26412
26463
  type: "string",
26413
- oneOf: options.map((option) => ({
26414
- const: option.label,
26415
- title: option.label,
26416
- description: option.description
26417
- }))
26464
+ oneOf: [
26465
+ ...options.map((option) => ({
26466
+ const: option.label,
26467
+ title: option.label,
26468
+ ...option.description ? { description: option.description } : {}
26469
+ })),
26470
+ ...hasOtherAnswer && !options.some((option) => option.label === USER_INPUT_OTHER_OPTION) ? [{
26471
+ const: USER_INPUT_OTHER_OPTION,
26472
+ title: USER_INPUT_OTHER_OPTION,
26473
+ description: "Provide a different answer in the note field."
26474
+ }] : []
26475
+ ]
26418
26476
  } : {
26419
26477
  ...base,
26420
26478
  type: "string"
26421
26479
  };
26422
26480
  if (hasOtherAnswer) {
26423
- properties[userInputOtherFieldId(question.id, questionIds)] = {
26481
+ properties[userInputNoteFieldId(question.id, questionIds)] = {
26424
26482
  type: "string",
26425
- title: "Other",
26426
- description: "Type your own answer instead of choosing an option above.",
26483
+ title: "Additional answer or note",
26427
26484
  _meta: {
26428
26485
  codex: {
26429
26486
  questionId: question.id,
26430
- isOtherAnswer: true,
26487
+ role: "user_note",
26431
26488
  isSecret: question.isSecret
26432
26489
  }
26433
26490
  }
26434
26491
  };
26435
26492
  }
26436
26493
  }
26437
- const firstQuestion = params.questions[0];
26438
26494
  return {
26439
26495
  sessionId: params.threadId,
26440
26496
  toolCallId: params.itemId,
26441
26497
  mode: "form",
26442
- message: params.questions.length === 1 && firstQuestion ? firstQuestion.question : "Input requested",
26498
+ message: "Codex needs your input to continue.",
26443
26499
  requestedSchema: {
26444
26500
  type: "object",
26445
26501
  properties,
@@ -26490,12 +26546,23 @@ var CodexElicitationHandler = class {
26490
26546
  const content = contentRecord(response.content);
26491
26547
  const questionIds = new Set(params.questions.map((question) => question.id));
26492
26548
  for (const question of params.questions) {
26493
- const value = question.isOther && question.options != null && question.options.length > 0 ? userInputResponseValue(content, userInputOtherFieldId(question.id, questionIds)) ?? userInputResponseValue(content, question.id) : userInputResponseValue(content, question.id);
26494
- if (value === void 0) {
26549
+ const answerValues = [];
26550
+ const value = userInputResponseValue(content, question.id);
26551
+ if (value !== void 0) {
26552
+ answerValues.push(...Array.isArray(value) ? value.map(String) : [String(value)]);
26553
+ }
26554
+ if (question.isOther && question.options != null && question.options.length > 0) {
26555
+ const note = userInputResponseValue(content, userInputNoteFieldId(question.id, questionIds));
26556
+ if (note !== void 0) {
26557
+ const notes = Array.isArray(note) ? note : [note];
26558
+ answerValues.push(...notes.map((item) => `${USER_INPUT_NOTE_PREFIX}${String(item).trim()}`));
26559
+ }
26560
+ }
26561
+ if (answerValues.length === 0) {
26495
26562
  continue;
26496
26563
  }
26497
26564
  answers[question.id] = {
26498
- answers: Array.isArray(value) ? value.map(String) : [String(value)]
26565
+ answers: answerValues
26499
26566
  };
26500
26567
  }
26501
26568
  return { answers };
@@ -27417,7 +27484,7 @@ var package_default = {
27417
27484
  publishConfig: {
27418
27485
  access: "public"
27419
27486
  },
27420
- version: "1.11.1-preview.3",
27487
+ version: "1.11.1-preview.5",
27421
27488
  description: "",
27422
27489
  main: "dist/index.js",
27423
27490
  bin: {
@@ -27480,7 +27547,7 @@ var package_default = {
27480
27547
  },
27481
27548
  dependencies: {
27482
27549
  "@agentclientprotocol/sdk": "^1.4.0",
27483
- "@openai/codex": "^0.153.4",
27550
+ "@openai/codex": "^0.154.0",
27484
27551
  diff: "^9.0.0",
27485
27552
  open: "^11.0.1",
27486
27553
  "vscode-jsonrpc": "^9.0.1",
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.11.1-preview.3",
6
+ "version": "1.11.1-preview.5",
7
7
  "description": "",
8
8
  "main": "dist/index.js",
9
9
  "bin": {
@@ -66,7 +66,7 @@
66
66
  },
67
67
  "dependencies": {
68
68
  "@agentclientprotocol/sdk": "^1.4.0",
69
- "@openai/codex": "^0.153.4",
69
+ "@openai/codex": "^0.154.0",
70
70
  "diff": "^9.0.0",
71
71
  "open": "^11.0.1",
72
72
  "vscode-jsonrpc": "^9.0.1",