lody 0.76.0 → 0.77.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,7 +5,7 @@ import { Writable, Readable } from "node:stream";
5
5
  import { StringDecoder } from "node:string_decoder";
6
6
  import fs__default from "node:fs";
7
7
  import path__default from "node:path";
8
- import fs__default$1, { readFile, constants } from "node:fs/promises";
8
+ import fs__default$1, { constants, readFile } from "node:fs/promises";
9
9
  import process$1 from "node:process";
10
10
  import { fileURLToPath } from "node:url";
11
11
  import { promisify } from "node:util";
@@ -52,7 +52,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
52
52
  mod
53
53
  ));
54
54
  var require_is = __commonJS({
55
- "../../node_modules/.pnpm/vscode-jsonrpc@9.0.1/node_modules/vscode-jsonrpc/lib/common/is.js"(exports$1) {
55
+ "../../../node_modules/.pnpm/vscode-jsonrpc@9.0.1/node_modules/vscode-jsonrpc/lib/common/is.js"(exports$1) {
56
56
  Object.defineProperty(exports$1, "__esModule", { value: true });
57
57
  exports$1.boolean = boolean4;
58
58
  exports$1.string = string4;
@@ -85,7 +85,7 @@ var require_is = __commonJS({
85
85
  }
86
86
  });
87
87
  var require_messages = __commonJS({
88
- "../../node_modules/.pnpm/vscode-jsonrpc@9.0.1/node_modules/vscode-jsonrpc/lib/common/messages.js"(exports$1) {
88
+ "../../../node_modules/.pnpm/vscode-jsonrpc@9.0.1/node_modules/vscode-jsonrpc/lib/common/messages.js"(exports$1) {
89
89
  var __createBinding = exports$1 && exports$1.__createBinding || (Object.create ? (function(o, m, k, k2) {
90
90
  if (k2 === void 0) k2 = k;
91
91
  var desc = Object.getOwnPropertyDescriptor(m, k);
@@ -467,7 +467,7 @@ var require_messages = __commonJS({
467
467
  }
468
468
  });
469
469
  var require_linkedMap = __commonJS({
470
- "../../node_modules/.pnpm/vscode-jsonrpc@9.0.1/node_modules/vscode-jsonrpc/lib/common/linkedMap.js"(exports$1) {
470
+ "../../../node_modules/.pnpm/vscode-jsonrpc@9.0.1/node_modules/vscode-jsonrpc/lib/common/linkedMap.js"(exports$1) {
471
471
  Object.defineProperty(exports$1, "__esModule", { value: true });
472
472
  exports$1.LRUCache = exports$1.LinkedMap = exports$1.Touch = void 0;
473
473
  var Touch;
@@ -848,7 +848,7 @@ var require_linkedMap = __commonJS({
848
848
  }
849
849
  });
850
850
  var require_disposable = __commonJS({
851
- "../../node_modules/.pnpm/vscode-jsonrpc@9.0.1/node_modules/vscode-jsonrpc/lib/common/disposable.js"(exports$1) {
851
+ "../../../node_modules/.pnpm/vscode-jsonrpc@9.0.1/node_modules/vscode-jsonrpc/lib/common/disposable.js"(exports$1) {
852
852
  Object.defineProperty(exports$1, "__esModule", { value: true });
853
853
  exports$1.Disposable = void 0;
854
854
  var Disposable;
@@ -863,7 +863,7 @@ var require_disposable = __commonJS({
863
863
  }
864
864
  });
865
865
  var require_ral = __commonJS({
866
- "../../node_modules/.pnpm/vscode-jsonrpc@9.0.1/node_modules/vscode-jsonrpc/lib/common/ral.js"(exports$1) {
866
+ "../../../node_modules/.pnpm/vscode-jsonrpc@9.0.1/node_modules/vscode-jsonrpc/lib/common/ral.js"(exports$1) {
867
867
  Object.defineProperty(exports$1, "__esModule", { value: true });
868
868
  var _ral;
869
869
  function RAL() {
@@ -885,7 +885,7 @@ var require_ral = __commonJS({
885
885
  }
886
886
  });
887
887
  var require_events = __commonJS({
888
- "../../node_modules/.pnpm/vscode-jsonrpc@9.0.1/node_modules/vscode-jsonrpc/lib/common/events.js"(exports$1) {
888
+ "../../../node_modules/.pnpm/vscode-jsonrpc@9.0.1/node_modules/vscode-jsonrpc/lib/common/events.js"(exports$1) {
889
889
  var __importDefault = exports$1 && exports$1.__importDefault || function(mod) {
890
890
  return mod && mod.__esModule ? mod : { "default": mod };
891
891
  };
@@ -1019,7 +1019,7 @@ var require_events = __commonJS({
1019
1019
  }
1020
1020
  });
1021
1021
  var require_cancellation = __commonJS({
1022
- "../../node_modules/.pnpm/vscode-jsonrpc@9.0.1/node_modules/vscode-jsonrpc/lib/common/cancellation.js"(exports$1) {
1022
+ "../../../node_modules/.pnpm/vscode-jsonrpc@9.0.1/node_modules/vscode-jsonrpc/lib/common/cancellation.js"(exports$1) {
1023
1023
  var __createBinding = exports$1 && exports$1.__createBinding || (Object.create ? (function(o, m, k, k2) {
1024
1024
  if (k2 === void 0) k2 = k;
1025
1025
  var desc = Object.getOwnPropertyDescriptor(m, k);
@@ -1145,7 +1145,7 @@ var require_cancellation = __commonJS({
1145
1145
  }
1146
1146
  });
1147
1147
  var require_sharedArrayCancellation = __commonJS({
1148
- "../../node_modules/.pnpm/vscode-jsonrpc@9.0.1/node_modules/vscode-jsonrpc/lib/common/sharedArrayCancellation.js"(exports$1) {
1148
+ "../../../node_modules/.pnpm/vscode-jsonrpc@9.0.1/node_modules/vscode-jsonrpc/lib/common/sharedArrayCancellation.js"(exports$1) {
1149
1149
  Object.defineProperty(exports$1, "__esModule", { value: true });
1150
1150
  exports$1.SharedArrayReceiverStrategy = exports$1.SharedArraySenderStrategy = void 0;
1151
1151
  var cancellation_1 = require_cancellation();
@@ -1221,7 +1221,7 @@ var require_sharedArrayCancellation = __commonJS({
1221
1221
  }
1222
1222
  });
1223
1223
  var require_semaphore = __commonJS({
1224
- "../../node_modules/.pnpm/vscode-jsonrpc@9.0.1/node_modules/vscode-jsonrpc/lib/common/semaphore.js"(exports$1) {
1224
+ "../../../node_modules/.pnpm/vscode-jsonrpc@9.0.1/node_modules/vscode-jsonrpc/lib/common/semaphore.js"(exports$1) {
1225
1225
  var __importDefault = exports$1 && exports$1.__importDefault || function(mod) {
1226
1226
  return mod && mod.__esModule ? mod : { "default": mod };
1227
1227
  };
@@ -1292,7 +1292,7 @@ var require_semaphore = __commonJS({
1292
1292
  }
1293
1293
  });
1294
1294
  var require_messageReader = __commonJS({
1295
- "../../node_modules/.pnpm/vscode-jsonrpc@9.0.1/node_modules/vscode-jsonrpc/lib/common/messageReader.js"(exports$1) {
1295
+ "../../../node_modules/.pnpm/vscode-jsonrpc@9.0.1/node_modules/vscode-jsonrpc/lib/common/messageReader.js"(exports$1) {
1296
1296
  var __createBinding = exports$1 && exports$1.__createBinding || (Object.create ? (function(o, m, k, k2) {
1297
1297
  if (k2 === void 0) k2 = k;
1298
1298
  var desc = Object.getOwnPropertyDescriptor(m, k);
@@ -1530,7 +1530,7 @@ ${JSON.stringify(Object.fromEntries(headers))}`));
1530
1530
  }
1531
1531
  });
1532
1532
  var require_messageWriter = __commonJS({
1533
- "../../node_modules/.pnpm/vscode-jsonrpc@9.0.1/node_modules/vscode-jsonrpc/lib/common/messageWriter.js"(exports$1) {
1533
+ "../../../node_modules/.pnpm/vscode-jsonrpc@9.0.1/node_modules/vscode-jsonrpc/lib/common/messageWriter.js"(exports$1) {
1534
1534
  var __createBinding = exports$1 && exports$1.__createBinding || (Object.create ? (function(o, m, k, k2) {
1535
1535
  if (k2 === void 0) k2 = k;
1536
1536
  var desc = Object.getOwnPropertyDescriptor(m, k);
@@ -1685,7 +1685,7 @@ var require_messageWriter = __commonJS({
1685
1685
  }
1686
1686
  });
1687
1687
  var require_messageBuffer = __commonJS({
1688
- "../../node_modules/.pnpm/vscode-jsonrpc@9.0.1/node_modules/vscode-jsonrpc/lib/common/messageBuffer.js"(exports$1) {
1688
+ "../../../node_modules/.pnpm/vscode-jsonrpc@9.0.1/node_modules/vscode-jsonrpc/lib/common/messageBuffer.js"(exports$1) {
1689
1689
  Object.defineProperty(exports$1, "__esModule", { value: true });
1690
1690
  exports$1.AbstractMessageBuffer = void 0;
1691
1691
  var CR = 13;
@@ -1833,7 +1833,7 @@ ${header}`);
1833
1833
  }
1834
1834
  });
1835
1835
  var require_connection = __commonJS({
1836
- "../../node_modules/.pnpm/vscode-jsonrpc@9.0.1/node_modules/vscode-jsonrpc/lib/common/connection.js"(exports$1) {
1836
+ "../../../node_modules/.pnpm/vscode-jsonrpc@9.0.1/node_modules/vscode-jsonrpc/lib/common/connection.js"(exports$1) {
1837
1837
  var __createBinding = exports$1 && exports$1.__createBinding || (Object.create ? (function(o, m, k, k2) {
1838
1838
  if (k2 === void 0) k2 = k;
1839
1839
  var desc = Object.getOwnPropertyDescriptor(m, k);
@@ -2996,7 +2996,7 @@ ${JSON.stringify(message, null, 4)}`);
2996
2996
  }
2997
2997
  });
2998
2998
  var require_api = __commonJS({
2999
- "../../node_modules/.pnpm/vscode-jsonrpc@9.0.1/node_modules/vscode-jsonrpc/lib/common/api.js"(exports$1) {
2999
+ "../../../node_modules/.pnpm/vscode-jsonrpc@9.0.1/node_modules/vscode-jsonrpc/lib/common/api.js"(exports$1) {
3000
3000
  var __importDefault = exports$1 && exports$1.__importDefault || function(mod) {
3001
3001
  return mod && mod.__esModule ? mod : { "default": mod };
3002
3002
  };
@@ -3207,7 +3207,7 @@ var require_api = __commonJS({
3207
3207
  }
3208
3208
  });
3209
3209
  var require_ril = __commonJS({
3210
- "../../node_modules/.pnpm/vscode-jsonrpc@9.0.1/node_modules/vscode-jsonrpc/lib/node/ril.js"(exports$1) {
3210
+ "../../../node_modules/.pnpm/vscode-jsonrpc@9.0.1/node_modules/vscode-jsonrpc/lib/node/ril.js"(exports$1) {
3211
3211
  Object.defineProperty(exports$1, "__esModule", { value: true });
3212
3212
  var util_1 = __require("util");
3213
3213
  var api_1 = require_api();
@@ -3362,7 +3362,7 @@ var require_ril = __commonJS({
3362
3362
  }
3363
3363
  });
3364
3364
  var require_main = __commonJS({
3365
- "../../node_modules/.pnpm/vscode-jsonrpc@9.0.1/node_modules/vscode-jsonrpc/lib/node/main.js"(exports$1) {
3365
+ "../../../node_modules/.pnpm/vscode-jsonrpc@9.0.1/node_modules/vscode-jsonrpc/lib/node/main.js"(exports$1) {
3366
3366
  var __createBinding = exports$1 && exports$1.__createBinding || (Object.create ? (function(o, m, k, k2) {
3367
3367
  if (k2 === void 0) k2 = k;
3368
3368
  var desc = Object.getOwnPropertyDescriptor(m, k);
@@ -3416,7 +3416,7 @@ var require_main = __commonJS({
3416
3416
  exports$1.createMessageConnection = createMessageConnection2;
3417
3417
  var ril_1 = __importDefault(require_ril());
3418
3418
  ril_1.default.install();
3419
- var path6 = __importStar(__require("path"));
3419
+ var path7 = __importStar(__require("path"));
3420
3420
  var os2 = __importStar(__require("os"));
3421
3421
  var fs7 = __importStar(__require("fs"));
3422
3422
  var crypto_1 = __require("crypto");
@@ -3568,7 +3568,7 @@ var require_main = __commonJS({
3568
3568
  throw new Error(`Unable to generate a random pipe name with ${randomLength} characters.`);
3569
3569
  }
3570
3570
  const randomSuffix = (0, crypto_1.randomBytes)(Math.floor(randomLength / 2)).toString("hex");
3571
- return path6.join(tmpDir, `lsp-${randomSuffix}.sock`);
3571
+ return path7.join(tmpDir, `lsp-${randomSuffix}.sock`);
3572
3572
  }
3573
3573
  function createClientPipeTransport(pipeName, encoding = "utf-8") {
3574
3574
  let connectResolve;
@@ -3653,6 +3653,8 @@ var require_main = __commonJS({
3653
3653
  }
3654
3654
  }
3655
3655
  });
3656
+ var rpc = __toESM(require_main());
3657
+ var import_node = __toESM(require_main());
3656
3658
  var AGENT_METHODS = {
3657
3659
  initialize: "initialize",
3658
3660
  authenticate: "authenticate",
@@ -4457,10 +4459,10 @@ function mergeDefs(...defs) {
4457
4459
  function cloneDef(schema) {
4458
4460
  return mergeDefs(schema._zod.def);
4459
4461
  }
4460
- function getElementAtPath(obj, path6) {
4461
- if (!path6)
4462
+ function getElementAtPath(obj, path7) {
4463
+ if (!path7)
4462
4464
  return obj;
4463
- return path6.reduce((acc, key) => acc?.[key], obj);
4465
+ return path7.reduce((acc, key) => acc?.[key], obj);
4464
4466
  }
4465
4467
  function promiseAllObject(promisesObj) {
4466
4468
  const keys = Object.keys(promisesObj);
@@ -4843,11 +4845,11 @@ function aborted(x, startIndex = 0) {
4843
4845
  }
4844
4846
  return false;
4845
4847
  }
4846
- function prefixIssues(path6, issues) {
4848
+ function prefixIssues(path7, issues) {
4847
4849
  return issues.map((iss) => {
4848
4850
  var _a2;
4849
4851
  (_a2 = iss).path ?? (_a2.path = []);
4850
- iss.path.unshift(path6);
4852
+ iss.path.unshift(path7);
4851
4853
  return iss;
4852
4854
  });
4853
4855
  }
@@ -5028,7 +5030,7 @@ function formatError(error48, mapper = (issue2) => issue2.message) {
5028
5030
  }
5029
5031
  function treeifyError(error48, mapper = (issue2) => issue2.message) {
5030
5032
  const result = { errors: [] };
5031
- const processError = (error49, path6 = []) => {
5033
+ const processError = (error49, path7 = []) => {
5032
5034
  var _a2, _b;
5033
5035
  for (const issue2 of error49.issues) {
5034
5036
  if (issue2.code === "invalid_union" && issue2.errors.length) {
@@ -5038,7 +5040,7 @@ function treeifyError(error48, mapper = (issue2) => issue2.message) {
5038
5040
  } else if (issue2.code === "invalid_element") {
5039
5041
  processError({ issues: issue2.issues }, issue2.path);
5040
5042
  } else {
5041
- const fullpath = [...path6, ...issue2.path];
5043
+ const fullpath = [...path7, ...issue2.path];
5042
5044
  if (fullpath.length === 0) {
5043
5045
  result.errors.push(mapper(issue2));
5044
5046
  continue;
@@ -5070,8 +5072,8 @@ function treeifyError(error48, mapper = (issue2) => issue2.message) {
5070
5072
  }
5071
5073
  function toDotPath(_path) {
5072
5074
  const segs = [];
5073
- const path6 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
5074
- for (const seg of path6) {
5075
+ const path7 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
5076
+ for (const seg of path7) {
5075
5077
  if (typeof seg === "number")
5076
5078
  segs.push(`[${seg}]`);
5077
5079
  else if (typeof seg === "symbol")
@@ -16906,13 +16908,13 @@ function resolveRef(ref, ctx) {
16906
16908
  if (!ref.startsWith("#")) {
16907
16909
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
16908
16910
  }
16909
- const path6 = ref.slice(1).split("/").filter(Boolean);
16910
- if (path6.length === 0) {
16911
+ const path7 = ref.slice(1).split("/").filter(Boolean);
16912
+ if (path7.length === 0) {
16911
16913
  return ctx.rootSchema;
16912
16914
  }
16913
16915
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
16914
- if (path6[0] === defsKey) {
16915
- const key = path6[1];
16916
+ if (path7[0] === defsKey) {
16917
+ const key = path7[1];
16916
16918
  if (!key || !ctx.defs[key]) {
16917
16919
  throw new Error(`Reference not found: ${ref}`);
16918
16920
  }
@@ -20811,8 +20813,6 @@ var AgentApp = class {
20811
20813
  };
20812
20814
  }
20813
20815
  };
20814
- var rpc = __toESM(require_main());
20815
- var import_node = __toESM(require_main());
20816
20816
  function createJSONRPCWriter(writable) {
20817
20817
  return {
20818
20818
  async write(msg) {
@@ -20985,13 +20985,16 @@ var ACPSessionConnection = class {
20985
20985
  });
20986
20986
  }
20987
20987
  };
20988
+ var GOAL_EXTENSION_VERSION = 1;
20989
+ var GOAL_CONTROL_METHOD = "_session/goal";
20990
+ var LEGACY_GOAL_CONTROL_METHOD = "_codex/session/goal_control";
20991
+ var GOAL_CONTROL_ACTIONS = ["set", "pause", "resume", "clear"];
20988
20992
  var LEGACY_SET_SESSION_MODEL_METHOD = "session/set_model";
20989
20993
  var ACP_EXT_SESSION_USAGE_UPDATE_METHOD = "_acp_ext:session_usage_update";
20990
20994
  var ACP_EXT_SESSION_RATE_LIMITS_METHOD = "_acp_ext:session_rate_limits";
20991
20995
  var ACP_EXT_CODEX_PROPOSED_PLAN_METHOD = "_acp_ext:codex_proposed_plan";
20992
20996
  var CODEX_STEER_APPLIED_METHOD = "_codex/steerApplied";
20993
20997
  var SESSION_STEERING_METHOD = "_session/steering";
20994
- var GOAL_CONTROL_METHOD = "_codex/session/goal_control";
20995
20998
  function getLodyForkTurnId(meta3) {
20996
20999
  if (typeof meta3 !== "object" || meta3 === null) return null;
20997
21000
  const lody = meta3["lody"];
@@ -21010,7 +21013,7 @@ var CODEX_STEER_CAPABILITY = {
21010
21013
  configPolicy: "active"
21011
21014
  };
21012
21015
  function isExtMethodRequest(request) {
21013
- return request.method === "authentication/status" || request.method === "authentication/logout" || request.method === LEGACY_SET_SESSION_MODEL_METHOD || request.method === GOAL_CONTROL_METHOD || request.method === SESSION_STEERING_METHOD;
21016
+ return request.method === "authentication/status" || request.method === "authentication/logout" || request.method === LEGACY_SET_SESSION_MODEL_METHOD || request.method === GOAL_CONTROL_METHOD || request.method === LEGACY_GOAL_CONTROL_METHOD || request.method === SESSION_STEERING_METHOD;
21014
21017
  }
21015
21018
  function toTokenCount(usage) {
21016
21019
  return {
@@ -22109,13 +22112,13 @@ function createTerminalCommandEvent(event, terminalId, cwd) {
22109
22112
  }
22110
22113
  };
22111
22114
  }
22112
- function createSearchTitle(query, path6) {
22113
- if (query && path6) {
22114
- return `Search for '${query}' in ${path6}`;
22115
+ function createSearchTitle(query, path7) {
22116
+ if (query && path7) {
22117
+ return `Search for '${query}' in ${path7}`;
22115
22118
  } else if (query) {
22116
22119
  return `Search for '${query}'`;
22117
- } else if (path6) {
22118
- return `Search in '${path6}'`;
22120
+ } else if (path7) {
22121
+ return `Search in '${path7}'`;
22119
22122
  }
22120
22123
  return "Search";
22121
22124
  }
@@ -22341,12 +22344,12 @@ function revertPatch(unifiedDiff) {
22341
22344
  if (!patch) return null;
22342
22345
  return reversePatch(patch);
22343
22346
  }
22344
- function createUpdateDiffContent(path6, oldText, newText) {
22347
+ function createUpdateDiffContent(path7, oldText, newText) {
22345
22348
  return {
22346
22349
  type: "diff",
22347
22350
  oldText,
22348
22351
  newText,
22349
- path: path6,
22352
+ path: path7,
22350
22353
  _meta: {
22351
22354
  kind: "update"
22352
22355
  }
@@ -22496,13 +22499,30 @@ function createAgentTextMessageChunk(text, messageId, meta3) {
22496
22499
  function createAgentTextThoughtChunk(text, messageId, meta3) {
22497
22500
  return createAgentThoughtChunk({ type: "text", text }, messageId);
22498
22501
  }
22502
+ function toGoalStatus(status) {
22503
+ switch (status) {
22504
+ case "active":
22505
+ case "paused":
22506
+ case "blocked":
22507
+ case "complete":
22508
+ return status;
22509
+ case "usageLimited":
22510
+ case "budgetLimited":
22511
+ return "limited";
22512
+ }
22513
+ }
22514
+ function toUnixMilliseconds(timestampSeconds) {
22515
+ return timestampSeconds * 1e3;
22516
+ }
22499
22517
  function toThreadGoalSnapshot(goal) {
22500
22518
  return {
22501
22519
  objective: goal.objective.trim(),
22502
- status: goal.status,
22520
+ status: toGoalStatus(goal.status),
22503
22521
  tokenBudget: goal.tokenBudget,
22522
+ tokensUsed: goal.tokensUsed,
22504
22523
  timeUsedSeconds: goal.timeUsedSeconds,
22505
- createdAt: goal.createdAt,
22524
+ createdAt: toUnixMilliseconds(goal.createdAt),
22525
+ updatedAt: toUnixMilliseconds(goal.updatedAt),
22506
22526
  controlMethod: GOAL_CONTROL_METHOD
22507
22527
  };
22508
22528
  }
@@ -22852,9 +22872,7 @@ ${event.details}` : "";
22852
22872
  return null;
22853
22873
  }
22854
22874
  this.sessionState.currentGoal = goalSnapshot;
22855
- return this.createCodexSessionInfoUpdate({
22856
- goal: goalSnapshot
22857
- });
22875
+ return this.createGoalSessionInfoUpdate(goalSnapshot);
22858
22876
  }
22859
22877
  createThreadGoalClearedEvent(_event) {
22860
22878
  this.sessionState.goalRevision += 1;
@@ -22862,9 +22880,13 @@ ${event.details}` : "";
22862
22880
  return null;
22863
22881
  }
22864
22882
  this.sessionState.currentGoal = null;
22865
- return this.createCodexSessionInfoUpdate({
22866
- goal: null
22867
- });
22883
+ return this.createGoalSessionInfoUpdate(null);
22884
+ }
22885
+ createGoalSessionInfoUpdate(goal) {
22886
+ return {
22887
+ sessionUpdate: "session_info_update",
22888
+ _meta: { goal }
22889
+ };
22868
22890
  }
22869
22891
  createReasoningSummaryDeltaEvent(event) {
22870
22892
  this.seenReasoningDeltaItemIds.add(event.itemId);
@@ -23701,11 +23723,11 @@ var CodexApprovalHandler = class {
23701
23723
  });
23702
23724
  }
23703
23725
  const fileSystem = permissions.fileSystem;
23704
- for (const path6 of fileSystem?.read ?? []) {
23705
- changes.push(this.fileSystemGrantChange(path6, "read", lifetime, suffix));
23726
+ for (const path7 of fileSystem?.read ?? []) {
23727
+ changes.push(this.fileSystemGrantChange(path7, "read", lifetime, suffix));
23706
23728
  }
23707
- for (const path6 of fileSystem?.write ?? []) {
23708
- changes.push(this.fileSystemGrantChange(path6, "write", lifetime, suffix));
23729
+ for (const path7 of fileSystem?.write ?? []) {
23730
+ changes.push(this.fileSystemGrantChange(path7, "write", lifetime, suffix));
23709
23731
  }
23710
23732
  for (const entry of fileSystem?.entries ?? []) {
23711
23733
  const matcher = (() => {
@@ -23734,16 +23756,16 @@ var CodexApprovalHandler = class {
23734
23756
  }
23735
23757
  return changes.length > 0 ? { version: 1, changes } : void 0;
23736
23758
  }
23737
- fileSystemGrantChange(path6, access, lifetime, suffix) {
23759
+ fileSystemGrantChange(path7, access, lifetime, suffix) {
23738
23760
  return {
23739
23761
  type: "grant",
23740
23762
  operation: "grant",
23741
- description: `Allow ${access} access to ${path6}${suffix}`,
23763
+ description: `Allow ${access} access to ${path7}${suffix}`,
23742
23764
  lifetime,
23743
23765
  targets: [{
23744
23766
  type: "filesystem",
23745
23767
  access: [access],
23746
- matcher: { type: "exact_path", path: path6 }
23768
+ matcher: { type: "exact_path", path: path7 }
23747
23769
  }]
23748
23770
  };
23749
23771
  }
@@ -24423,6 +24445,11 @@ var ChatGptAuthMethod = {
24423
24445
  name: "ChatGPT",
24424
24446
  description: "Use ChatGPT to authenticate"
24425
24447
  };
24448
+ var ChatGptDeviceCodeAuthMethod = {
24449
+ id: "chat-gpt-device-code",
24450
+ name: "ChatGPT (device code)",
24451
+ description: "Sign in to ChatGPT by opening a verification page and entering a one-time code"
24452
+ };
24426
24453
  var GatewayAuthMethod = {
24427
24454
  id: "gateway",
24428
24455
  name: "Custom model gateway",
@@ -24439,6 +24466,9 @@ function getCodexAuthMethods(clientCapabilities, env = process.env) {
24439
24466
  if (!env["NO_BROWSER"]) {
24440
24467
  authMethods.push(ChatGptAuthMethod);
24441
24468
  }
24469
+ if (clientSupportsUrlElicitation(clientCapabilities)) {
24470
+ authMethods.push(ChatGptDeviceCodeAuthMethod);
24471
+ }
24442
24472
  const supportsGatewayAuth = clientCapabilities?.auth?._meta?.["gateway"] === true;
24443
24473
  if (supportsGatewayAuth) {
24444
24474
  authMethods.push(GatewayAuthMethod);
@@ -24446,7 +24476,7 @@ function getCodexAuthMethods(clientCapabilities, env = process.env) {
24446
24476
  return authMethods;
24447
24477
  }
24448
24478
  function isCodexAuthRequest(request) {
24449
- return request.methodId === "api-key" || request.methodId === "chat-gpt" || request.methodId === "gateway";
24479
+ return request.methodId === "api-key" || request.methodId === "chat-gpt" || request.methodId === "chat-gpt-device-code" || request.methodId === "gateway";
24450
24480
  }
24451
24481
  var isDockerCached;
24452
24482
  function hasDockerEnv() {
@@ -24600,15 +24630,15 @@ var wslDefaultBrowser = async () => {
24600
24630
  const { stdout } = await executePowerShell(command, { powerShellPath: psPath });
24601
24631
  return stdout.trim();
24602
24632
  };
24603
- var convertWslPathToWindows = async (path6) => {
24604
- if (/^[a-z]+:\/\//i.test(path6)) {
24605
- return path6;
24633
+ var convertWslPathToWindows = async (path7) => {
24634
+ if (/^[a-z]+:\/\//i.test(path7)) {
24635
+ return path7;
24606
24636
  }
24607
24637
  try {
24608
- const { stdout } = await execFile2("wslpath", ["-aw", path6], { encoding: "utf8" });
24638
+ const { stdout } = await execFile2("wslpath", ["-aw", path7], { encoding: "utf8" });
24609
24639
  return stdout.trim();
24610
24640
  } catch {
24611
- return path6;
24641
+ return path7;
24612
24642
  }
24613
24643
  };
24614
24644
  function defineLazyProperty(object2, propertyName, valueGetter) {
@@ -25148,7 +25178,7 @@ var package_default = {
25148
25178
  publishConfig: {
25149
25179
  access: "public"
25150
25180
  },
25151
- version: "1.3.0",
25181
+ version: "1.4.0",
25152
25182
  description: "An ACP-compatible coding agent powered by Codex",
25153
25183
  main: "dist/index.js",
25154
25184
  bin: {
@@ -25216,7 +25246,7 @@ var package_default = {
25216
25246
  },
25217
25247
  dependencies: {
25218
25248
  "@agentclientprotocol/sdk": "^1.3.0",
25219
- "@openai/codex": "^0.145.0",
25249
+ "@openai/codex": "^0.147.0",
25220
25250
  diff: "^9.0.0",
25221
25251
  open: "^11.0.0",
25222
25252
  "vscode-jsonrpc": "^9.0.1",
@@ -25256,6 +25286,51 @@ function createCodexCollaborationMode(mode, currentModelId) {
25256
25286
  }
25257
25287
  };
25258
25288
  }
25289
+ function isAbsolutePathLike(value) {
25290
+ const trimmed = value.trim();
25291
+ return path__default.isAbsolute(trimmed) || isWindowsAbsolutePath(trimmed);
25292
+ }
25293
+ function arePathsEqual(left, right) {
25294
+ return normalizePathForComparison(left) === normalizePathForComparison(right);
25295
+ }
25296
+ function arePathBasenamesEqual(left, right) {
25297
+ const leftBase = path__default.posix.basename(normalizePathForComparison(left));
25298
+ const rightBase = path__default.posix.basename(normalizePathForComparison(right));
25299
+ if (shouldComparePathCaseInsensitive(left) || shouldComparePathCaseInsensitive(right)) {
25300
+ return leftBase.toLowerCase() === rightBase.toLowerCase();
25301
+ }
25302
+ return leftBase === rightBase;
25303
+ }
25304
+ function normalizePathForComparison(value) {
25305
+ const trimmed = value.trim();
25306
+ if (trimmed.length === 0) {
25307
+ return "";
25308
+ }
25309
+ if (isWindowsAbsolutePath(trimmed)) {
25310
+ const normalized2 = path__default.win32.normalize(trimmed).replace(/\\/g, "/");
25311
+ return trimTrailingPathSeparators(normalized2).toLowerCase();
25312
+ }
25313
+ const pathForComparison = path__default.isAbsolute(trimmed) ? trimmed : trimmed.replace(/\\/g, "/");
25314
+ const normalized = path__default.posix.normalize(pathForComparison);
25315
+ return trimTrailingPathSeparators(normalized);
25316
+ }
25317
+ function isWindowsAbsolutePath(value) {
25318
+ const portableValue = value.replace(/\\/g, "/");
25319
+ return /^[A-Za-z]:\//.test(portableValue) || /^\/\/[^/]+\/[^/]+/.test(portableValue);
25320
+ }
25321
+ function shouldComparePathCaseInsensitive(value) {
25322
+ return isWindowsAbsolutePath(value) || /^[A-Za-z]:/.test(value) || value.includes("\\");
25323
+ }
25324
+ function trimTrailingPathSeparators(value) {
25325
+ let trimmed = value;
25326
+ while (trimmed.endsWith("/") && !isRootPath(trimmed)) {
25327
+ trimmed = trimmed.slice(0, -1);
25328
+ }
25329
+ return trimmed;
25330
+ }
25331
+ function isRootPath(value) {
25332
+ return value === "/" || /^[A-Za-z]:\/$/.test(value) || /^\/\/[^/]+\/[^/]+\/$/.test(value);
25333
+ }
25259
25334
  var CUSTOM_GATEWAY_PROVIDER_ID = "custom-gateway";
25260
25335
  var SESSION_LIST_PAGE_SIZE = 100;
25261
25336
  var SUPPORTED_GATEWAY_PROTOCOLS = {
@@ -25299,43 +25374,24 @@ var CodexAcpClient = class {
25299
25374
  getHomePath() {
25300
25375
  return this.configPath;
25301
25376
  }
25302
- async authenticate(authRequest) {
25377
+ async authenticate(authRequest, urlElicitationRequester) {
25303
25378
  if (!isCodexAuthRequest(authRequest)) {
25304
25379
  throw RequestError.invalidRequest();
25305
25380
  }
25306
25381
  this.gatewayConfig = null;
25307
25382
  switch (authRequest.methodId) {
25308
- case "api-key": {
25309
- const apiKey = authRequest._meta?.["api-key"]?.apiKey ?? this.readApiKeyFromEnv();
25310
- return await this.authenticateWithApiKey(apiKey);
25311
- }
25312
- case "chat-gpt": {
25313
- const accountResponse = await this.codexClient.accountRead({ refreshToken: true });
25314
- if (accountResponse.account?.type === "chatgpt") {
25315
- return true;
25316
- }
25317
- const loginCompletedPromise = this.awaitNextLoginCompleted();
25318
- const loginResponse = await this.codexClient.accountLogin({ type: "chatgpt" });
25319
- if (loginResponse.type == "chatgpt") {
25320
- await open_default(loginResponse.authUrl);
25321
- }
25322
- const result = await loginCompletedPromise;
25323
- return result.success;
25324
- }
25383
+ case "api-key":
25384
+ return await this.authenticateWithApiKey(authRequest);
25385
+ case "chat-gpt":
25386
+ return await this.authenticateWithChatGpt();
25387
+ case "chat-gpt-device-code":
25388
+ return await this.authenticateWithChatGptDeviceCode(urlElicitationRequester);
25325
25389
  case "gateway":
25326
- if (!authRequest._meta) throw RequestError.invalidRequest();
25327
- const gatewaySettings = authRequest._meta["gateway"];
25328
- if (!gatewaySettings) throw RequestError.invalidRequest();
25329
- this.applyGatewayConfig({
25330
- baseUrl: gatewaySettings.baseUrl,
25331
- apiType: GatewayAuthMethod._meta.gateway.protocol,
25332
- headers: gatewaySettings.headers,
25333
- providerName: gatewaySettings.providerName
25334
- });
25335
- return true;
25390
+ return this.authenticateWithGateway(authRequest);
25336
25391
  }
25337
25392
  }
25338
- async authenticateWithApiKey(apiKey) {
25393
+ async authenticateWithApiKey(authRequest) {
25394
+ const apiKey = authRequest._meta?.["api-key"]?.apiKey ?? this.readApiKeyFromEnv();
25339
25395
  const loginCompletedPromise = this.awaitNextLoginCompleted();
25340
25396
  await this.codexClient.accountLogin({
25341
25397
  type: "apiKey",
@@ -25344,6 +25400,56 @@ var CodexAcpClient = class {
25344
25400
  const result = await loginCompletedPromise;
25345
25401
  return result.success;
25346
25402
  }
25403
+ async authenticateWithChatGpt() {
25404
+ const accountResponse = await this.codexClient.accountRead({ refreshToken: true });
25405
+ if (accountResponse.account?.type === "chatgpt") {
25406
+ return true;
25407
+ }
25408
+ const loginCompletedPromise = this.awaitNextLoginCompleted();
25409
+ const loginResponse = await this.codexClient.accountLogin({ type: "chatgpt" });
25410
+ if (loginResponse.type == "chatgpt") {
25411
+ await open_default(loginResponse.authUrl);
25412
+ }
25413
+ const result = await loginCompletedPromise;
25414
+ return result.success;
25415
+ }
25416
+ async authenticateWithChatGptDeviceCode(urlElicitationRequester) {
25417
+ const accountResponse = await this.codexClient.accountRead({ refreshToken: true });
25418
+ if (accountResponse.account?.type === "chatgpt") {
25419
+ return true;
25420
+ }
25421
+ if (!urlElicitationRequester) {
25422
+ throw RequestError.invalidRequest(void 0, "Device code authentication requires URL elicitation support");
25423
+ }
25424
+ const loginCompletedPromise = this.awaitNextLoginCompleted();
25425
+ const loginResponse = await this.codexClient.accountLogin({ type: "chatgptDeviceCode" });
25426
+ if (loginResponse.type !== "chatgptDeviceCode") {
25427
+ return false;
25428
+ }
25429
+ const elicitationResponse = await urlElicitationRequester.elicitUrl({
25430
+ url: loginResponse.verificationUrl,
25431
+ message: `Sign in to ChatGPT and enter this code: ${loginResponse.userCode}`,
25432
+ elicitationId: loginResponse.loginId
25433
+ });
25434
+ if (!CreateElicitationResponse.isAccept(elicitationResponse)) {
25435
+ await this.codexClient.accountLoginCancel({ loginId: loginResponse.loginId });
25436
+ return false;
25437
+ }
25438
+ const result = await loginCompletedPromise;
25439
+ return result.success;
25440
+ }
25441
+ authenticateWithGateway(authRequest) {
25442
+ if (!authRequest._meta) throw RequestError.invalidRequest();
25443
+ const gatewaySettings = authRequest._meta["gateway"];
25444
+ if (!gatewaySettings) throw RequestError.invalidRequest();
25445
+ this.applyGatewayConfig({
25446
+ baseUrl: gatewaySettings.baseUrl,
25447
+ apiType: GatewayAuthMethod._meta.gateway.protocol,
25448
+ headers: gatewaySettings.headers,
25449
+ providerName: gatewaySettings.providerName
25450
+ });
25451
+ return true;
25452
+ }
25347
25453
  readApiKeyFromEnv() {
25348
25454
  for (const envVar of [CODEX_API_KEY_ENV_VAR, OPENAI_API_KEY_ENV_VAR]) {
25349
25455
  const value = process.env[envVar]?.trim();
@@ -25613,12 +25719,16 @@ var CodexAcpClient = class {
25613
25719
  const response = await this.codexClient.threadGoalGet({ threadId: sessionId });
25614
25720
  return response?.goal ?? null;
25615
25721
  }
25616
- async setGoal(sessionId, objective, onTurnStarted) {
25617
- return await this.codexClient.runGoalSet({
25722
+ async setGoal(sessionId, objective, onTurnStarted, onGoalSet) {
25723
+ const params = {
25618
25724
  threadId: sessionId,
25619
25725
  objective,
25620
25726
  status: "active"
25621
- }, onTurnStarted);
25727
+ };
25728
+ if (onGoalSet === void 0) {
25729
+ return await this.codexClient.runGoalSet(params, onTurnStarted);
25730
+ }
25731
+ return await this.codexClient.runGoalSet(params, onTurnStarted, void 0, onGoalSet);
25622
25732
  }
25623
25733
  async setGoalStatus(sessionId, status) {
25624
25734
  let updatedGoal = null;
@@ -25633,11 +25743,15 @@ var CodexAcpClient = class {
25633
25743
  }
25634
25744
  return updatedGoal;
25635
25745
  }
25636
- async resumeGoal(sessionId, onTurnStarted) {
25637
- return await this.codexClient.runGoalSet({
25746
+ async resumeGoal(sessionId, onTurnStarted, onGoalSet) {
25747
+ const params = {
25638
25748
  threadId: sessionId,
25639
25749
  status: "active"
25640
- }, onTurnStarted);
25750
+ };
25751
+ if (onGoalSet === void 0) {
25752
+ return await this.codexClient.runGoalSet(params, onTurnStarted);
25753
+ }
25754
+ return await this.codexClient.runGoalSet(params, onTurnStarted, void 0, onGoalSet);
25641
25755
  }
25642
25756
  async clearGoal(sessionId) {
25643
25757
  await this.codexClient.runGoalClear({ threadId: sessionId });
@@ -25893,11 +26007,10 @@ var CodexAcpClient = class {
25893
26007
  const requestedCwd = request.cwd?.trim() ?? null;
25894
26008
  const filterByCwd = (thread) => {
25895
26009
  if (!requestedCwd) return true;
25896
- if (path__default.isAbsolute(requestedCwd)) {
25897
- return thread.cwd === requestedCwd;
26010
+ if (isAbsolutePathLike(requestedCwd)) {
26011
+ return arePathsEqual(thread.cwd, requestedCwd);
25898
26012
  }
25899
- const requestedBase = path__default.basename(requestedCwd);
25900
- return path__default.basename(thread.cwd) === requestedBase;
26013
+ return arePathBasenamesEqual(thread.cwd, requestedCwd);
25901
26014
  };
25902
26015
  const preferredProvider = this.getModelProvider();
25903
26016
  const modelProviders = preferredProvider ? [preferredProvider] : [];
@@ -25923,7 +26036,7 @@ var CodexAcpClient = class {
25923
26036
  let sessions = listResponse.data.map(mapThreadToSession);
25924
26037
  if (requestedCwd) {
25925
26038
  const filtered = listResponse.data.filter(filterByCwd).map(mapThreadToSession);
25926
- if (filtered.length > 0 || path__default.isAbsolute(requestedCwd)) {
26039
+ if (filtered.length > 0 || isAbsolutePathLike(requestedCwd)) {
25927
26040
  sessions = filtered;
25928
26041
  } else {
25929
26042
  logger.log("Ignoring non-absolute cwd filter for session/list", { cwd: requestedCwd });
@@ -26039,8 +26152,8 @@ function formatUriAsLink(name, uri) {
26039
26152
  return `[@${name}](${uri})`;
26040
26153
  }
26041
26154
  if (uri.startsWith("file://")) {
26042
- const path6 = uri.replace("file://", "");
26043
- const fileName = path6.split("/").pop() ?? path6;
26155
+ const path7 = uri.replace("file://", "");
26156
+ const fileName = path7.split("/").pop() ?? path7;
26044
26157
  return `[@${fileName}](${uri})`;
26045
26158
  }
26046
26159
  return uri;
@@ -26192,6 +26305,10 @@ function createReasoningEffortConfigOption(supportedReasoningEfforts, currentEff
26192
26305
  }))
26193
26306
  };
26194
26307
  }
26308
+ var GOAL_CONTINUATION_PROMPT = [{
26309
+ type: "text",
26310
+ text: "Continue working toward the active goal."
26311
+ }];
26195
26312
  var CodexCommands = class {
26196
26313
  connection;
26197
26314
  codexAcpClient;
@@ -26485,7 +26602,7 @@ var CodexCommands = class {
26485
26602
  }
26486
26603
  createGoalCommandResult(turnCompleted) {
26487
26604
  if (turnCompleted === null) {
26488
- return { handled: true };
26605
+ return { handled: false, prompt: GOAL_CONTINUATION_PROMPT };
26489
26606
  }
26490
26607
  return {
26491
26608
  handled: true,
@@ -26920,8 +27037,8 @@ function imageBlocks(images) {
26920
27037
  return [{ type: "text", text: `[@image](${image})` }];
26921
27038
  }
26922
27039
  const record2 = asRecord(image);
26923
- const path6 = record2 ? stringValue(record2["path"]) ?? stringValue(record2["url"]) : null;
26924
- return path6 ? [{ type: "text", text: `[@image](${path6})` }] : [];
27040
+ const path7 = record2 ? stringValue(record2["path"]) ?? stringValue(record2["url"]) : null;
27041
+ return path7 ? [{ type: "text", text: `[@image](${path7})` }] : [];
26925
27042
  });
26926
27043
  }
26927
27044
  function contentBlocksFromResponseContent(content) {
@@ -27720,6 +27837,7 @@ var CodexAcpServer = class _CodexAcpServer {
27720
27837
  closingSessions;
27721
27838
  sessionGenerations;
27722
27839
  sessionOpenGenerations;
27840
+ goalControlGenerations;
27723
27841
  constructor(connection, codexAcpClient, defaultAuthRequest, getExitCode, getRecentStderr) {
27724
27842
  this.sessions = /* @__PURE__ */ new Map();
27725
27843
  this.pendingMcpStartupSessions = /* @__PURE__ */ new Map();
@@ -27730,6 +27848,7 @@ var CodexAcpServer = class _CodexAcpServer {
27730
27848
  this.closingSessions = /* @__PURE__ */ new Map();
27731
27849
  this.sessionGenerations = /* @__PURE__ */ new Map();
27732
27850
  this.sessionOpenGenerations = /* @__PURE__ */ new Map();
27851
+ this.goalControlGenerations = /* @__PURE__ */ new Map();
27733
27852
  this.connection = connection;
27734
27853
  this.codexAcpClient = codexAcpClient;
27735
27854
  this.defaultAuthRequest = defaultAuthRequest ?? null;
@@ -27796,6 +27915,11 @@ var CodexAcpServer = class _CodexAcpServer {
27796
27915
  _meta: {
27797
27916
  steering: {
27798
27917
  supported: true
27918
+ },
27919
+ goal: {
27920
+ version: GOAL_EXTENSION_VERSION,
27921
+ controlMethod: GOAL_CONTROL_METHOD,
27922
+ actions: [...GOAL_CONTROL_ACTIONS]
27799
27923
  }
27800
27924
  }
27801
27925
  };
@@ -27816,17 +27940,58 @@ var CodexAcpServer = class _CodexAcpServer {
27816
27940
  return await this.unstable_setSessionModel(this.parseLegacySetSessionModelParams(methodRequest.params));
27817
27941
  case SESSION_STEERING_METHOD:
27818
27942
  return await this.executeOrQueueSteeringRequest(this.parseSessionSteerParams(methodRequest.params));
27819
- case GOAL_CONTROL_METHOD: {
27943
+ case GOAL_CONTROL_METHOD:
27944
+ case LEGACY_GOAL_CONTROL_METHOD: {
27820
27945
  const sessionState = this.sessions.get(methodRequest.params.sessionId);
27821
27946
  if (!sessionState) {
27822
27947
  throw RequestError.invalidParams(void 0, `Unknown session: ${methodRequest.params.sessionId}`);
27823
27948
  }
27824
27949
  const sessionGeneration = this.getSessionGeneration(sessionState.sessionId);
27825
- if (methodRequest.params.action === "pause") {
27950
+ const goalControlGeneration = this.bumpGoalControlGeneration(sessionState.sessionId);
27951
+ if (methodRequest.params.action === "set") {
27952
+ const objective = methodRequest.params.objective;
27953
+ let updatedGoal = null;
27954
+ const turnCompleted = await this.runWithProcessCheck(() => this.codexAcpClient.setGoal(
27955
+ sessionState.sessionId,
27956
+ objective,
27957
+ void 0,
27958
+ (goal) => {
27959
+ updatedGoal = goal;
27960
+ }
27961
+ ));
27962
+ if (turnCompleted === null && updatedGoal !== null) {
27963
+ await this.startGoalContinuationIfCurrent(
27964
+ sessionState,
27965
+ sessionGeneration,
27966
+ goalControlGeneration,
27967
+ updatedGoal
27968
+ );
27969
+ }
27970
+ } else if (methodRequest.params.action === "pause") {
27826
27971
  const goal = await this.runWithProcessCheck(() => this.codexAcpClient.setGoalStatus(sessionState.sessionId, "paused"));
27827
27972
  if (this.goalPublishIsCurrent(sessionState, sessionGeneration)) {
27828
27973
  await this.publishGoalSnapshot(sessionState, toThreadGoalSnapshot(goal), false);
27829
27974
  }
27975
+ } else if (methodRequest.params.action === "resume") {
27976
+ let updatedGoal = null;
27977
+ const turnCompleted = await this.runWithProcessCheck(() => this.codexAcpClient.resumeGoal(
27978
+ sessionState.sessionId,
27979
+ void 0,
27980
+ (goal) => {
27981
+ updatedGoal = goal;
27982
+ }
27983
+ ));
27984
+ if (updatedGoal !== null && this.goalPublishIsCurrent(sessionState, sessionGeneration)) {
27985
+ await this.publishGoalSnapshot(sessionState, toThreadGoalSnapshot(updatedGoal), false);
27986
+ }
27987
+ if (turnCompleted === null && updatedGoal !== null) {
27988
+ await this.startGoalContinuationIfCurrent(
27989
+ sessionState,
27990
+ sessionGeneration,
27991
+ goalControlGeneration,
27992
+ updatedGoal
27993
+ );
27994
+ }
27830
27995
  } else if (methodRequest.params.action === "clear") {
27831
27996
  await this.runWithProcessCheck(() => this.codexAcpClient.clearGoal(sessionState.sessionId));
27832
27997
  if (this.goalPublishIsCurrent(sessionState, sessionGeneration)) {
@@ -27935,6 +28100,11 @@ Check ${configPath} and project .codex directories, especially their config.toml
27935
28100
  getSessionGeneration(sessionId) {
27936
28101
  return this.sessionGenerations.get(sessionId) ?? 0;
27937
28102
  }
28103
+ bumpGoalControlGeneration(sessionId) {
28104
+ const generation = (this.goalControlGenerations.get(sessionId) ?? 0) + 1;
28105
+ this.goalControlGenerations.set(sessionId, generation);
28106
+ return generation;
28107
+ }
27938
28108
  bumpSessionGeneration(sessionId) {
27939
28109
  const generation = this.getSessionGeneration(sessionId) + 1;
27940
28110
  this.sessionGenerations.set(sessionId, generation);
@@ -28220,6 +28390,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
28220
28390
  this.activePrompts.delete(params.sessionId);
28221
28391
  this.pendingSteers.delete(params.sessionId);
28222
28392
  this.steeringQueues.delete(params.sessionId);
28393
+ this.goalControlGenerations.delete(params.sessionId);
28223
28394
  }
28224
28395
  this.endSessionCloseFence(params.sessionId);
28225
28396
  }
@@ -28275,9 +28446,10 @@ Check ${configPath} and project .codex directories, especially their config.toml
28275
28446
  });
28276
28447
  }, 0);
28277
28448
  }
28278
- async authenticate(_params) {
28449
+ async authenticate(_params, requestId) {
28279
28450
  logger.log("Authenticate request received");
28280
- const isAuthenticated = await this.runWithProcessCheck(() => this.codexAcpClient.authenticate(_params));
28451
+ const elicitationRequester = this.createUrlElicitationRequester(requestId);
28452
+ const isAuthenticated = await this.runWithProcessCheck(() => this.codexAcpClient.authenticate(_params, elicitationRequester));
28281
28453
  if (!isAuthenticated) {
28282
28454
  logger.log("Authenticate request failed");
28283
28455
  throw RequestError.invalidParams();
@@ -28286,6 +28458,18 @@ Check ${configPath} and project .codex directories, especially their config.toml
28286
28458
  logger.log("Authenticate request completed");
28287
28459
  return {};
28288
28460
  }
28461
+ createUrlElicitationRequester(requestId) {
28462
+ if (requestId == null || !clientSupportsUrlElicitation(this.clientCapabilities)) {
28463
+ return void 0;
28464
+ }
28465
+ return {
28466
+ elicitUrl: (request) => this.connection.request(methods.client.elicitation.create, {
28467
+ mode: "url",
28468
+ requestId,
28469
+ ...request
28470
+ })
28471
+ };
28472
+ }
28289
28473
  async logout(_params) {
28290
28474
  logger.log("Logout request received");
28291
28475
  await this.runWithProcessCheck(() => this.codexAcpClient.logout());
@@ -28609,29 +28793,48 @@ Check ${configPath} and project .codex directories, especially their config.toml
28609
28793
  * fails or is cancelled before the turn starts.
28610
28794
  */
28611
28795
  async startNewTurnFromSteering(params) {
28796
+ await this.startNewTurnFromExternalPrompt(params, "Steering");
28797
+ return { outcome: "startedNewTurn" };
28798
+ }
28799
+ async startGoalContinuationIfCurrent(sessionState, sessionGeneration, goalControlGeneration, expectedGoal) {
28800
+ await this.startNewTurnFromExternalPrompt({
28801
+ sessionId: sessionState.sessionId,
28802
+ prompt: GOAL_CONTINUATION_PROMPT
28803
+ }, "Goal continuation", async () => {
28804
+ if (!this.goalPublishIsCurrent(sessionState, sessionGeneration) || this.goalControlGenerations.get(sessionState.sessionId) !== goalControlGeneration) {
28805
+ return false;
28806
+ }
28807
+ const currentGoal = await this.runWithProcessCheck(() => this.codexAcpClient.getGoal(sessionState.sessionId));
28808
+ return currentGoal?.status === "active" && currentGoal.objective === expectedGoal.objective && currentGoal.createdAt === expectedGoal.createdAt && this.goalControlGenerations.get(sessionState.sessionId) === goalControlGeneration;
28809
+ });
28810
+ }
28811
+ async startNewTurnFromExternalPrompt(params, source, canStart = async () => true) {
28612
28812
  const previousPrompt = this.activePrompts.get(params.sessionId);
28613
28813
  await previousPrompt?.completion;
28614
28814
  if (this.sessionIsClosing(params.sessionId)) {
28615
28815
  throw RequestError.invalidRequest(`Session ${params.sessionId} is closing`);
28616
28816
  }
28817
+ if (!await canStart()) {
28818
+ return false;
28819
+ }
28617
28820
  return await new Promise((resolve, reject) => {
28618
28821
  let turnStarted = false;
28619
28822
  const promptDone = this.prompt(params, void 0, () => {
28620
28823
  turnStarted = true;
28621
- logger.log("Steering session started a new turn", { sessionId: params.sessionId });
28622
- resolve({ outcome: "startedNewTurn" });
28824
+ logger.log(`${source} started a new turn`, { sessionId: params.sessionId });
28825
+ resolve(true);
28623
28826
  });
28624
28827
  promptDone.then(
28625
28828
  (response) => {
28626
28829
  if (!turnStarted && response.stopReason === "cancelled") {
28627
28830
  reject(RequestError.invalidRequest(`Session ${params.sessionId} was cancelled before the steering turn started`));
28628
28831
  } else {
28629
- resolve({ outcome: "startedNewTurn" });
28832
+ resolve(turnStarted);
28630
28833
  }
28631
28834
  },
28632
28835
  (error48) => {
28633
28836
  if (turnStarted) {
28634
- logger.error(`Steering-started prompt for session ${params.sessionId} failed`, error48);
28837
+ logger.error(`${source} prompt for session ${params.sessionId} failed`, error48);
28635
28838
  } else {
28636
28839
  reject(error48);
28637
28840
  }
@@ -28745,9 +28948,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
28745
28948
  await session.update({
28746
28949
  sessionUpdate: "session_info_update",
28747
28950
  _meta: {
28748
- codex: {
28749
- goal: snapshot
28750
- }
28951
+ goal: snapshot
28751
28952
  }
28752
28953
  });
28753
28954
  }
@@ -29043,8 +29244,8 @@ Check ${configPath} and project .codex directories, especially their config.toml
29043
29244
  return `[@${name}](${uri})`;
29044
29245
  }
29045
29246
  if (uri.startsWith("file://")) {
29046
- const path6 = uri.replace("file://", "");
29047
- const fileName = path6.split("/").pop() ?? path6;
29247
+ const path7 = uri.replace("file://", "");
29248
+ const fileName = path7.split("/").pop() ?? path7;
29048
29249
  return `[@${fileName}](${uri})`;
29049
29250
  }
29050
29251
  return uri;
@@ -29419,6 +29620,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
29419
29620
  _meta: this.buildQuotaMeta(sessionState)
29420
29621
  };
29421
29622
  }
29623
+ const effectiveParams = commandResult.prompt === void 0 ? params : { ...params, prompt: commandResult.prompt };
29422
29624
  if (this.sessionIsClosing(params.sessionId)) {
29423
29625
  return this.cancelledPromptResponse(sessionState);
29424
29626
  }
@@ -29431,7 +29633,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
29431
29633
  reason: sessionState.account?.type === "apiKey" ? "API key" : "model lacks reasoning"
29432
29634
  });
29433
29635
  }
29434
- if (!sessionState.supportedInputModalities.includes("image") && params.prompt.some((b) => b.type === "image")) {
29636
+ if (!sessionState.supportedInputModalities.includes("image") && effectiveParams.prompt.some((b) => b.type === "image")) {
29435
29637
  throw RequestError.invalidRequest("The current model does not support image input");
29436
29638
  }
29437
29639
  const agentMode = sessionState.agentMode;
@@ -29442,7 +29644,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
29442
29644
  ensurePendingTurnStart();
29443
29645
  const sendPromptPromise = this.runWithProcessCheck(
29444
29646
  () => this.codexAcpClient.sendPrompt(
29445
- params,
29647
+ effectiveParams,
29446
29648
  agentMode,
29447
29649
  modelId,
29448
29650
  serviceTier,
@@ -30162,6 +30364,9 @@ var CodexAppServerClient = class {
30162
30364
  async accountLogin(params) {
30163
30365
  return await this.sendRequest({ method: "account/login/start", params });
30164
30366
  }
30367
+ async accountLoginCancel(params) {
30368
+ return await this.sendRequest({ method: "account/login/cancel", params });
30369
+ }
30165
30370
  async accountLogout() {
30166
30371
  return await this.sendRequest({ method: "account/logout", params: void 0 });
30167
30372
  }
@@ -30688,6 +30893,20 @@ function spawnCodexCli(codexPath, args) {
30688
30893
  const bundledCodexPath = createRequire$1(import.meta.url).resolve("@openai/codex/bin/codex.js");
30689
30894
  return spawn(process.execPath, [bundledCodexPath, ...args], options);
30690
30895
  }
30896
+ var goalControlParamsParser = external_exports.discriminatedUnion("action", [
30897
+ external_exports.object({
30898
+ sessionId: external_exports.string(),
30899
+ action: external_exports.literal("set"),
30900
+ objective: external_exports.string().trim().min(1)
30901
+ }).passthrough(),
30902
+ external_exports.object({
30903
+ sessionId: external_exports.string(),
30904
+ action: external_exports.enum(["pause", "resume", "clear"])
30905
+ }).passthrough()
30906
+ ]);
30907
+ function registerGoalControlRequests(app, getAgent) {
30908
+ return app.onRequest(GOAL_CONTROL_METHOD, goalControlParamsParser, (ctx) => getAgent().extMethod(GOAL_CONTROL_METHOD, ctx.params)).onRequest(LEGACY_GOAL_CONTROL_METHOD, goalControlParamsParser, (ctx) => getAgent().extMethod(LEGACY_GOAL_CONTROL_METHOD, ctx.params));
30909
+ }
30691
30910
  var emptyExtensionParamsParser = external_exports.preprocess(
30692
30911
  (params) => params ?? {},
30693
30912
  external_exports.object({}).passthrough()
@@ -30701,10 +30920,25 @@ var sessionSteerParamsParser = external_exports.object({
30701
30920
  prompt: external_exports.array(external_exports.any()),
30702
30921
  steerId: external_exports.string().min(1).optional()
30703
30922
  }).passthrough();
30704
- var goalControlParamsParser = external_exports.object({
30705
- sessionId: external_exports.string(),
30706
- action: external_exports.enum(["pause", "clear"])
30707
- }).passthrough();
30923
+ function createCodexAcpApp(options) {
30924
+ let codexAcpServer = null;
30925
+ const getAgent = () => {
30926
+ if (!codexAcpServer) {
30927
+ throw RequestError.internalError("ACP agent is not connected");
30928
+ }
30929
+ return codexAcpServer;
30930
+ };
30931
+ const agentApp = agent({ name: options.name }).onConnect((connection) => {
30932
+ const agent2 = options.createAgent(connection.client);
30933
+ codexAcpServer = agent2;
30934
+ connection.signal.addEventListener("abort", () => {
30935
+ if (codexAcpServer === agent2) {
30936
+ codexAcpServer = null;
30937
+ }
30938
+ });
30939
+ }).onRequest(methods.agent.initialize, (ctx) => getAgent().initialize(ctx.params)).onRequest(methods.agent.session.new, (ctx) => getAgent().newSession(ctx.params)).onRequest(methods.agent.session.load, (ctx) => getAgent().loadSession(ctx.params)).onRequest(methods.agent.session.fork, (ctx) => getAgent().unstable_forkSession(ctx.params)).onRequest(methods.agent.session.list, (ctx) => getAgent().listSessions(ctx.params)).onRequest(methods.agent.session.delete, (ctx) => getAgent().deleteSession(ctx.params)).onRequest(methods.agent.session.resume, (ctx) => getAgent().resumeSession(ctx.params)).onRequest(methods.agent.session.close, (ctx) => getAgent().closeSession(ctx.params)).onRequest(methods.agent.session.setMode, (ctx) => getAgent().setSessionMode(ctx.params)).onRequest(methods.agent.session.setConfigOption, (ctx) => getAgent().setSessionConfigOption(ctx.params)).onRequest(methods.agent.authenticate, (ctx) => getAgent().authenticate(ctx.params, ctx.requestId)).onRequest(methods.agent.logout, (ctx) => getAgent().logout(ctx.params)).onRequest(methods.agent.providers.list, (ctx) => getAgent().listProviders(ctx.params)).onRequest(methods.agent.providers.set, (ctx) => getAgent().setProvider(ctx.params)).onRequest(methods.agent.providers.disable, (ctx) => getAgent().disableProvider(ctx.params)).onRequest(methods.agent.session.prompt, (ctx) => getAgent().prompt(ctx.params, ctx.signal)).onNotification(methods.agent.session.cancel, (ctx) => getAgent().cancel(ctx.params)).onRequest("authentication/status", emptyExtensionParamsParser, (ctx) => getAgent().extMethod("authentication/status", ctx.params)).onRequest("authentication/logout", emptyExtensionParamsParser, (ctx) => getAgent().extMethod("authentication/logout", ctx.params)).onRequest(LEGACY_SET_SESSION_MODEL_METHOD, legacySetSessionModelParamsParser, (ctx) => getAgent().extMethod(LEGACY_SET_SESSION_MODEL_METHOD, ctx.params)).onRequest(SESSION_STEERING_METHOD, sessionSteerParamsParser, (ctx) => getAgent().extMethod(SESSION_STEERING_METHOD, ctx.params));
30940
+ return registerGoalControlRequests(agentApp, getAgent);
30941
+ }
30708
30942
  if (process.argv.includes("--version")) {
30709
30943
  console.log(`${package_default.name} ${package_default.version}`);
30710
30944
  process.exit(0);
@@ -30761,20 +30995,5 @@ function startAcpServer() {
30761
30995
  const codexClient = new CodexAcpClient(appServerClient, config2, modelProvider);
30762
30996
  return new CodexAcpServer(connection, codexClient, defaultAuthRequest, () => codexConnection.process.exitCode, () => stderr);
30763
30997
  }
30764
- let codexAcpServer = null;
30765
- const getAgent = () => {
30766
- if (!codexAcpServer) {
30767
- throw RequestError.internalError("ACP agent is not connected");
30768
- }
30769
- return codexAcpServer;
30770
- };
30771
- agent({ name: package_default.name }).onConnect((connection) => {
30772
- const agent2 = createAgent(connection.client);
30773
- codexAcpServer = agent2;
30774
- connection.signal.addEventListener("abort", () => {
30775
- if (codexAcpServer === agent2) {
30776
- codexAcpServer = null;
30777
- }
30778
- });
30779
- }).onRequest(methods.agent.initialize, (ctx) => getAgent().initialize(ctx.params)).onRequest(methods.agent.session.new, (ctx) => getAgent().newSession(ctx.params)).onRequest(methods.agent.session.load, (ctx) => getAgent().loadSession(ctx.params)).onRequest(methods.agent.session.fork, (ctx) => getAgent().unstable_forkSession(ctx.params)).onRequest(methods.agent.session.list, (ctx) => getAgent().listSessions(ctx.params)).onRequest(methods.agent.session.delete, (ctx) => getAgent().deleteSession(ctx.params)).onRequest(methods.agent.session.resume, (ctx) => getAgent().resumeSession(ctx.params)).onRequest(methods.agent.session.close, (ctx) => getAgent().closeSession(ctx.params)).onRequest(methods.agent.session.setMode, (ctx) => getAgent().setSessionMode(ctx.params)).onRequest(methods.agent.session.setConfigOption, (ctx) => getAgent().setSessionConfigOption(ctx.params)).onRequest(methods.agent.authenticate, (ctx) => getAgent().authenticate(ctx.params)).onRequest(methods.agent.logout, (ctx) => getAgent().logout(ctx.params)).onRequest(methods.agent.providers.list, (ctx) => getAgent().listProviders(ctx.params)).onRequest(methods.agent.providers.set, (ctx) => getAgent().setProvider(ctx.params)).onRequest(methods.agent.providers.disable, (ctx) => getAgent().disableProvider(ctx.params)).onRequest(methods.agent.session.prompt, (ctx) => getAgent().prompt(ctx.params, ctx.signal)).onNotification(methods.agent.session.cancel, (ctx) => getAgent().cancel(ctx.params)).onRequest("authentication/status", emptyExtensionParamsParser, (ctx) => getAgent().extMethod("authentication/status", ctx.params)).onRequest("authentication/logout", emptyExtensionParamsParser, (ctx) => getAgent().extMethod("authentication/logout", ctx.params)).onRequest(LEGACY_SET_SESSION_MODEL_METHOD, legacySetSessionModelParamsParser, (ctx) => getAgent().extMethod(LEGACY_SET_SESSION_MODEL_METHOD, ctx.params)).onRequest(SESSION_STEERING_METHOD, sessionSteerParamsParser, (ctx) => getAgent().extMethod(SESSION_STEERING_METHOD, ctx.params)).onRequest(GOAL_CONTROL_METHOD, goalControlParamsParser, (ctx) => getAgent().extMethod(GOAL_CONTROL_METHOD, ctx.params)).connect(acpJsonStream);
30998
+ createCodexAcpApp({ name: package_default.name, createAgent }).connect(acpJsonStream);
30780
30999
  }