@posthog/agent 2.3.168 → 2.3.171

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.
@@ -513,7 +513,7 @@ var require_has_flag = __commonJS({
513
513
  var require_supports_color = __commonJS({
514
514
  "../../node_modules/supports-color/index.js"(exports, module) {
515
515
  "use strict";
516
- var os6 = __require("os");
516
+ var os7 = __require("os");
517
517
  var tty = __require("tty");
518
518
  var hasFlag = require_has_flag();
519
519
  var { env } = process;
@@ -561,7 +561,7 @@ var require_supports_color = __commonJS({
561
561
  return min;
562
562
  }
563
563
  if (process.platform === "win32") {
564
- const osRelease = os6.release().split(".");
564
+ const osRelease = os7.release().split(".");
565
565
  if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
566
566
  return Number(osRelease[2]) >= 14931 ? 3 : 2;
567
567
  }
@@ -809,10 +809,10 @@ var require_src2 = __commonJS({
809
809
  var fs_1 = __require("fs");
810
810
  var debug_1 = __importDefault(require_src());
811
811
  var log = debug_1.default("@kwsites/file-exists");
812
- function check(path12, isFile, isDirectory) {
813
- log(`checking %s`, path12);
812
+ function check(path13, isFile, isDirectory) {
813
+ log(`checking %s`, path13);
814
814
  try {
815
- const stat = fs_1.statSync(path12);
815
+ const stat = fs_1.statSync(path13);
816
816
  if (stat.isFile() && isFile) {
817
817
  log(`[OK] path represents a file`);
818
818
  return true;
@@ -832,8 +832,8 @@ var require_src2 = __commonJS({
832
832
  throw e;
833
833
  }
834
834
  }
835
- function exists2(path12, type = exports.READABLE) {
836
- return check(path12, (type & exports.FILE) > 0, (type & exports.FOLDER) > 0);
835
+ function exists2(path13, type = exports.READABLE) {
836
+ return check(path13, (type & exports.FILE) > 0, (type & exports.FOLDER) > 0);
837
837
  }
838
838
  exports.exists = exists2;
839
839
  exports.FILE = 1;
@@ -898,8 +898,8 @@ var require_dist2 = __commonJS({
898
898
 
899
899
  // src/server/agent-server.ts
900
900
  import {
901
- ClientSideConnection,
902
- ndJsonStream as ndJsonStream2,
901
+ ClientSideConnection as ClientSideConnection2,
902
+ ndJsonStream as ndJsonStream3,
903
903
  PROTOCOL_VERSION
904
904
  } from "@agentclientprotocol/sdk";
905
905
  import { serve } from "@hono/node-server";
@@ -908,7 +908,7 @@ import { Hono } from "hono";
908
908
  // package.json
909
909
  var package_default = {
910
910
  name: "@posthog/agent",
911
- version: "2.3.168",
911
+ version: "2.3.171",
912
912
  repository: "https://github.com/PostHog/code",
913
913
  description: "TypeScript agent framework wrapping Claude Agent SDK with Git-based task execution for PostHog",
914
914
  exports: {
@@ -1070,64 +1070,7 @@ var POSTHOG_NOTIFICATIONS = {
1070
1070
  };
1071
1071
 
1072
1072
  // src/adapters/acp-connection.ts
1073
- import { AgentSideConnection, ndJsonStream } from "@agentclientprotocol/sdk";
1074
-
1075
- // src/gateway-models.ts
1076
- var DEFAULT_GATEWAY_MODEL = "claude-opus-4-6";
1077
- var BLOCKED_MODELS = /* @__PURE__ */ new Set(["gpt-5-mini", "openai/gpt-5-mini"]);
1078
- var CACHE_TTL = 10 * 60 * 1e3;
1079
- var gatewayModelsCache = null;
1080
- async function fetchGatewayModels(options) {
1081
- const gatewayUrl = options?.gatewayUrl ?? process.env.ANTHROPIC_BASE_URL;
1082
- if (!gatewayUrl) {
1083
- return [];
1084
- }
1085
- if (gatewayModelsCache && gatewayModelsCache.url === gatewayUrl && Date.now() < gatewayModelsCache.expiry) {
1086
- return gatewayModelsCache.models;
1087
- }
1088
- const modelsUrl = `${gatewayUrl}/v1/models`;
1089
- try {
1090
- const response = await fetch(modelsUrl);
1091
- if (!response.ok) {
1092
- return [];
1093
- }
1094
- const data = await response.json();
1095
- const models = (data.data ?? []).filter((m) => !BLOCKED_MODELS.has(m.id));
1096
- gatewayModelsCache = {
1097
- models,
1098
- expiry: Date.now() + CACHE_TTL,
1099
- url: gatewayUrl
1100
- };
1101
- return models;
1102
- } catch {
1103
- return [];
1104
- }
1105
- }
1106
- function isAnthropicModel(model) {
1107
- if (model.owned_by) {
1108
- return model.owned_by === "anthropic";
1109
- }
1110
- return model.id.startsWith("claude-") || model.id.startsWith("anthropic/");
1111
- }
1112
- var PROVIDER_PREFIXES = ["anthropic/", "openai/", "google-vertex/"];
1113
- function formatGatewayModelName(model) {
1114
- return formatModelId(model.id);
1115
- }
1116
- function formatModelId(modelId) {
1117
- let cleanId = modelId;
1118
- for (const prefix of PROVIDER_PREFIXES) {
1119
- if (cleanId.startsWith(prefix)) {
1120
- cleanId = cleanId.slice(prefix.length);
1121
- break;
1122
- }
1123
- }
1124
- cleanId = cleanId.replace(/(\d)-(\d)/g, "$1.$2");
1125
- const words = cleanId.split(/[-_]/).map((word) => {
1126
- if (word.match(/^[0-9.]+$/)) return word;
1127
- return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
1128
- });
1129
- return words.join(" ");
1130
- }
1073
+ import { AgentSideConnection, ndJsonStream as ndJsonStream2 } from "@agentclientprotocol/sdk";
1131
1074
 
1132
1075
  // src/utils/logger.ts
1133
1076
  var Logger = class _Logger {
@@ -1392,6 +1335,63 @@ function unreachable(value, logger) {
1392
1335
  logger.error(`Unexpected case: ${valueAsString}`);
1393
1336
  }
1394
1337
 
1338
+ // src/gateway-models.ts
1339
+ var DEFAULT_GATEWAY_MODEL = "claude-opus-4-6";
1340
+ var BLOCKED_MODELS = /* @__PURE__ */ new Set(["gpt-5-mini", "openai/gpt-5-mini"]);
1341
+ var CACHE_TTL = 10 * 60 * 1e3;
1342
+ var gatewayModelsCache = null;
1343
+ async function fetchGatewayModels(options) {
1344
+ const gatewayUrl = options?.gatewayUrl ?? process.env.ANTHROPIC_BASE_URL;
1345
+ if (!gatewayUrl) {
1346
+ return [];
1347
+ }
1348
+ if (gatewayModelsCache && gatewayModelsCache.url === gatewayUrl && Date.now() < gatewayModelsCache.expiry) {
1349
+ return gatewayModelsCache.models;
1350
+ }
1351
+ const modelsUrl = `${gatewayUrl}/v1/models`;
1352
+ try {
1353
+ const response = await fetch(modelsUrl);
1354
+ if (!response.ok) {
1355
+ return [];
1356
+ }
1357
+ const data = await response.json();
1358
+ const models = (data.data ?? []).filter((m) => !BLOCKED_MODELS.has(m.id));
1359
+ gatewayModelsCache = {
1360
+ models,
1361
+ expiry: Date.now() + CACHE_TTL,
1362
+ url: gatewayUrl
1363
+ };
1364
+ return models;
1365
+ } catch {
1366
+ return [];
1367
+ }
1368
+ }
1369
+ function isAnthropicModel(model) {
1370
+ if (model.owned_by) {
1371
+ return model.owned_by === "anthropic";
1372
+ }
1373
+ return model.id.startsWith("claude-") || model.id.startsWith("anthropic/");
1374
+ }
1375
+ var PROVIDER_PREFIXES = ["anthropic/", "openai/", "google-vertex/"];
1376
+ function formatGatewayModelName(model) {
1377
+ return formatModelId(model.id);
1378
+ }
1379
+ function formatModelId(modelId) {
1380
+ let cleanId = modelId;
1381
+ for (const prefix of PROVIDER_PREFIXES) {
1382
+ if (cleanId.startsWith(prefix)) {
1383
+ cleanId = cleanId.slice(prefix.length);
1384
+ break;
1385
+ }
1386
+ }
1387
+ cleanId = cleanId.replace(/(\d)-(\d)/g, "$1.$2");
1388
+ const words = cleanId.split(/[-_]/).map((word) => {
1389
+ if (word.match(/^[0-9.]+$/)) return word;
1390
+ return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
1391
+ });
1392
+ return words.join(" ");
1393
+ }
1394
+
1395
1395
  // src/adapters/base-acp-agent.ts
1396
1396
  var DEFAULT_CONTEXT_WINDOW = 2e5;
1397
1397
  var BaseAcpAgent = class {
@@ -1599,8 +1599,8 @@ var ToolContentBuilder = class {
1599
1599
  this.items.push({ type: "content", content: image(data, mimeType, uri) });
1600
1600
  return this;
1601
1601
  }
1602
- diff(path12, oldText, newText) {
1603
- this.items.push({ type: "diff", path: path12, oldText, newText });
1602
+ diff(path13, oldText, newText) {
1603
+ this.items.push({ type: "diff", path: path13, oldText, newText });
1604
1604
  return this;
1605
1605
  }
1606
1606
  build() {
@@ -5011,6 +5011,204 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
5011
5011
  }
5012
5012
  };
5013
5013
 
5014
+ // src/adapters/codex/codex-agent.ts
5015
+ import {
5016
+ ClientSideConnection,
5017
+ ndJsonStream
5018
+ } from "@agentclientprotocol/sdk";
5019
+
5020
+ // src/adapters/codex/codex-client.ts
5021
+ function createCodexClient(upstreamClient, logger, sessionState, callbacks) {
5022
+ const terminalHandles = /* @__PURE__ */ new Map();
5023
+ return {
5024
+ async requestPermission(params) {
5025
+ logger.debug("Relaying permission request to upstream", {
5026
+ sessionId: params.sessionId
5027
+ });
5028
+ return upstreamClient.requestPermission(params);
5029
+ },
5030
+ async sessionUpdate(params) {
5031
+ const update = params.update;
5032
+ if (update?.sessionUpdate === "usage_update") {
5033
+ const used = update.used;
5034
+ const size = update.size;
5035
+ if (used !== void 0) sessionState.contextUsed = used;
5036
+ if (size !== void 0) sessionState.contextSize = size;
5037
+ const inputTokens = update.inputTokens;
5038
+ const outputTokens = update.outputTokens;
5039
+ if (inputTokens !== void 0) {
5040
+ sessionState.accumulatedUsage.inputTokens += inputTokens;
5041
+ }
5042
+ if (outputTokens !== void 0) {
5043
+ sessionState.accumulatedUsage.outputTokens += outputTokens;
5044
+ }
5045
+ const cachedRead = update.cachedReadTokens;
5046
+ const cachedWrite = update.cachedWriteTokens;
5047
+ if (cachedRead !== void 0) {
5048
+ sessionState.accumulatedUsage.cachedReadTokens += cachedRead;
5049
+ }
5050
+ if (cachedWrite !== void 0) {
5051
+ sessionState.accumulatedUsage.cachedWriteTokens += cachedWrite;
5052
+ }
5053
+ callbacks?.onUsageUpdate?.(update);
5054
+ }
5055
+ await upstreamClient.sessionUpdate(params);
5056
+ },
5057
+ async readTextFile(params) {
5058
+ return upstreamClient.readTextFile(params);
5059
+ },
5060
+ async writeTextFile(params) {
5061
+ return upstreamClient.writeTextFile(params);
5062
+ },
5063
+ async createTerminal(params) {
5064
+ const handle = await upstreamClient.createTerminal(params);
5065
+ terminalHandles.set(handle.id, handle);
5066
+ return { terminalId: handle.id };
5067
+ },
5068
+ async terminalOutput(params) {
5069
+ const handle = terminalHandles.get(params.terminalId);
5070
+ if (!handle) {
5071
+ return { output: "", truncated: false };
5072
+ }
5073
+ return handle.currentOutput();
5074
+ },
5075
+ async releaseTerminal(params) {
5076
+ const handle = terminalHandles.get(params.terminalId);
5077
+ if (handle) {
5078
+ terminalHandles.delete(params.terminalId);
5079
+ const result = await handle.release();
5080
+ return result ?? void 0;
5081
+ }
5082
+ },
5083
+ async waitForTerminalExit(params) {
5084
+ const handle = terminalHandles.get(params.terminalId);
5085
+ if (!handle) {
5086
+ return { exitCode: 1 };
5087
+ }
5088
+ return handle.waitForExit();
5089
+ },
5090
+ async killTerminal(params) {
5091
+ const handle = terminalHandles.get(params.terminalId);
5092
+ if (handle) {
5093
+ return handle.kill();
5094
+ }
5095
+ },
5096
+ async extMethod(method, params) {
5097
+ return upstreamClient.extMethod(method, params);
5098
+ },
5099
+ async extNotification(method, params) {
5100
+ return upstreamClient.extNotification(method, params);
5101
+ }
5102
+ };
5103
+ }
5104
+
5105
+ // src/adapters/codex/session-state.ts
5106
+ function createSessionState(sessionId, cwd, opts) {
5107
+ return {
5108
+ sessionId,
5109
+ cwd,
5110
+ modeId: opts?.modeId ?? "default",
5111
+ modelId: opts?.modelId,
5112
+ configOptions: [],
5113
+ accumulatedUsage: {
5114
+ inputTokens: 0,
5115
+ outputTokens: 0,
5116
+ cachedReadTokens: 0,
5117
+ cachedWriteTokens: 0
5118
+ },
5119
+ cancelled: false,
5120
+ taskRunId: opts?.taskRunId,
5121
+ taskId: opts?.taskId
5122
+ };
5123
+ }
5124
+ function resetUsage(state) {
5125
+ state.accumulatedUsage = {
5126
+ inputTokens: 0,
5127
+ outputTokens: 0,
5128
+ cachedReadTokens: 0,
5129
+ cachedWriteTokens: 0
5130
+ };
5131
+ }
5132
+
5133
+ // src/adapters/codex/settings.ts
5134
+ import * as fs5 from "fs";
5135
+ import * as os5 from "os";
5136
+ import * as path7 from "path";
5137
+ var CodexSettingsManager = class {
5138
+ cwd;
5139
+ settings = {};
5140
+ initialized = false;
5141
+ constructor(cwd) {
5142
+ this.cwd = cwd;
5143
+ }
5144
+ async initialize() {
5145
+ if (this.initialized) {
5146
+ return;
5147
+ }
5148
+ await this.loadSettings();
5149
+ this.initialized = true;
5150
+ }
5151
+ getConfigPath() {
5152
+ return path7.join(os5.homedir(), ".codex", "config.toml");
5153
+ }
5154
+ async loadSettings() {
5155
+ const configPath = this.getConfigPath();
5156
+ try {
5157
+ const content = await fs5.promises.readFile(configPath, "utf-8");
5158
+ this.settings = parseCodexToml(content, this.cwd);
5159
+ } catch {
5160
+ this.settings = {};
5161
+ }
5162
+ }
5163
+ getSettings() {
5164
+ return this.settings;
5165
+ }
5166
+ getCwd() {
5167
+ return this.cwd;
5168
+ }
5169
+ async setCwd(cwd) {
5170
+ if (this.cwd === cwd) {
5171
+ return;
5172
+ }
5173
+ this.dispose();
5174
+ this.cwd = cwd;
5175
+ this.initialized = false;
5176
+ await this.initialize();
5177
+ }
5178
+ dispose() {
5179
+ this.initialized = false;
5180
+ }
5181
+ };
5182
+ function parseCodexToml(content, cwd) {
5183
+ const settings = {};
5184
+ let currentSection = "";
5185
+ for (const line of content.split("\n")) {
5186
+ const trimmed2 = line.trim();
5187
+ if (!trimmed2 || trimmed2.startsWith("#")) continue;
5188
+ const sectionMatch = trimmed2.match(/^\[(.+)\]$/);
5189
+ if (sectionMatch) {
5190
+ currentSection = sectionMatch[1] ?? "";
5191
+ continue;
5192
+ }
5193
+ const kvMatch = trimmed2.match(/^(\w+)\s*=\s*(.+)$/);
5194
+ if (!kvMatch) continue;
5195
+ const key = kvMatch[1];
5196
+ let value = kvMatch[2]?.trim() ?? "";
5197
+ if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
5198
+ value = value.slice(1, -1);
5199
+ }
5200
+ if (!currentSection) {
5201
+ if (key === "model") settings.model = value;
5202
+ if (key === "personality") settings.personality = value;
5203
+ if (key === "model_reasoning_effort")
5204
+ settings.modelReasoningEffort = value;
5205
+ } else if (currentSection === `projects."${cwd}"`) {
5206
+ if (key === "trust_level") settings.trustLevel = value;
5207
+ }
5208
+ }
5209
+ return settings;
5210
+ }
5211
+
5014
5212
  // src/adapters/codex/spawn.ts
5015
5213
  import { spawn as spawn2 } from "child_process";
5016
5214
  import { existsSync as existsSync3 } from "fs";
@@ -5031,6 +5229,10 @@ function buildConfigArgs(options) {
5031
5229
  if (options.model) {
5032
5230
  args.push("-c", `model="${options.model}"`);
5033
5231
  }
5232
+ if (options.instructions) {
5233
+ const escaped = options.instructions.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
5234
+ args.push("-c", `instructions="${escaped}"`);
5235
+ }
5034
5236
  return args;
5035
5237
  }
5036
5238
  function findCodexBinary(options) {
@@ -5107,64 +5309,236 @@ function spawnCodexProcess(options) {
5107
5309
  };
5108
5310
  }
5109
5311
 
5110
- // src/adapters/acp-connection.ts
5111
- function isGroupedOptions(options) {
5112
- return options.length > 0 && "group" in options[0];
5113
- }
5114
- function formatOption(o) {
5115
- if (!o.value) return o;
5116
- return { ...o, name: formatModelId(o.value) };
5117
- }
5118
- function filterModelConfigOptions(msg, allowedModelIds) {
5119
- const payload = msg;
5120
- const configOptions = payload.result?.configOptions ?? payload.params?.update?.configOptions;
5121
- if (!configOptions) return null;
5122
- const filtered = configOptions.map((opt) => {
5123
- if (opt.category !== "model" || !opt.options) return opt;
5124
- const options = opt.options;
5125
- if (isGroupedOptions(options)) {
5126
- const filteredOptions2 = options.map((group) => ({
5127
- ...group,
5128
- options: (group.options ?? []).filter((o) => o?.value && allowedModelIds.has(o.value)).map(formatOption)
5129
- }));
5130
- const flat = filteredOptions2.flatMap((g) => g.options ?? []);
5131
- const currentAllowed2 = opt.currentValue && allowedModelIds.has(opt.currentValue);
5132
- const nextCurrent2 = currentAllowed2 || flat.length === 0 ? opt.currentValue : flat[0]?.value;
5133
- return {
5134
- ...opt,
5135
- currentValue: nextCurrent2,
5136
- options: filteredOptions2
5137
- };
5138
- }
5139
- const valueOptions = options;
5140
- const filteredOptions = valueOptions.filter((o) => o?.value && allowedModelIds.has(o.value)).map(formatOption);
5141
- const currentAllowed = opt.currentValue && allowedModelIds.has(opt.currentValue);
5142
- const nextCurrent = currentAllowed || filteredOptions.length === 0 ? opt.currentValue : filteredOptions[0]?.value;
5312
+ // src/adapters/codex/codex-agent.ts
5313
+ var CodexAcpAgent = class extends BaseAcpAgent {
5314
+ adapterName = "codex";
5315
+ codexProcess;
5316
+ codexConnection;
5317
+ sessionState;
5318
+ constructor(client, options) {
5319
+ super(client);
5320
+ this.logger = new Logger({ debug: true, prefix: "[CodexAcpAgent]" });
5321
+ this.codexProcess = spawnCodexProcess({
5322
+ ...options.codexProcessOptions,
5323
+ logger: this.logger,
5324
+ processCallbacks: options.processCallbacks
5325
+ });
5326
+ const codexReadable = nodeReadableToWebReadable(this.codexProcess.stdout);
5327
+ const codexWritable = nodeWritableToWebWritable(this.codexProcess.stdin);
5328
+ const codexStream = ndJsonStream(codexWritable, codexReadable);
5329
+ const cwd = options.codexProcessOptions.cwd ?? process.cwd();
5330
+ const settingsManager = new CodexSettingsManager(cwd);
5331
+ const abortController = new AbortController();
5332
+ this.session = {
5333
+ abortController,
5334
+ settingsManager,
5335
+ notificationHistory: [],
5336
+ cancelled: false
5337
+ };
5338
+ this.codexConnection = new ClientSideConnection(
5339
+ (_agent) => createCodexClient(
5340
+ this.client,
5341
+ this.logger,
5342
+ this.sessionState ?? {
5343
+ sessionId: "",
5344
+ cwd: "",
5345
+ modeId: "default",
5346
+ configOptions: [],
5347
+ accumulatedUsage: {
5348
+ inputTokens: 0,
5349
+ outputTokens: 0,
5350
+ cachedReadTokens: 0,
5351
+ cachedWriteTokens: 0
5352
+ },
5353
+ cancelled: false
5354
+ }
5355
+ ),
5356
+ codexStream
5357
+ );
5358
+ }
5359
+ async initialize(request) {
5360
+ await this.session.settingsManager.initialize();
5361
+ const response = await this.codexConnection.initialize(request);
5143
5362
  return {
5144
- ...opt,
5145
- currentValue: nextCurrent,
5146
- options: filteredOptions
5363
+ ...response,
5364
+ agentCapabilities: {
5365
+ ...response.agentCapabilities,
5366
+ sessionCapabilities: {
5367
+ ...response.agentCapabilities?.sessionCapabilities,
5368
+ resume: {},
5369
+ fork: {}
5370
+ },
5371
+ _meta: {
5372
+ posthog: {
5373
+ resumeSession: true
5374
+ }
5375
+ }
5376
+ },
5377
+ agentInfo: {
5378
+ name: package_default.name,
5379
+ title: "Codex Agent",
5380
+ version: package_default.version
5381
+ }
5147
5382
  };
5148
- });
5149
- if (payload.result?.configOptions) {
5150
- return { ...msg, result: { ...payload.result, configOptions: filtered } };
5151
5383
  }
5152
- if (payload.params?.update?.configOptions) {
5384
+ async newSession(params) {
5385
+ const meta = params._meta;
5386
+ const response = await this.codexConnection.newSession(params);
5387
+ this.sessionState = createSessionState(response.sessionId, params.cwd, {
5388
+ taskRunId: meta?.taskRunId,
5389
+ taskId: meta?.taskId ?? meta?.persistence?.taskId,
5390
+ modeId: response.modes?.currentModeId ?? "default",
5391
+ modelId: response.models?.currentModelId
5392
+ });
5393
+ this.sessionId = response.sessionId;
5394
+ this.sessionState.configOptions = response.configOptions ?? [];
5395
+ if (meta?.taskRunId) {
5396
+ await this.client.extNotification(POSTHOG_NOTIFICATIONS.SDK_SESSION, {
5397
+ taskRunId: meta.taskRunId,
5398
+ sessionId: response.sessionId,
5399
+ adapter: "codex"
5400
+ });
5401
+ }
5402
+ this.logger.info("Codex session created", {
5403
+ sessionId: response.sessionId,
5404
+ taskRunId: meta?.taskRunId
5405
+ });
5406
+ return response;
5407
+ }
5408
+ async loadSession(params) {
5409
+ const response = await this.codexConnection.loadSession(params);
5410
+ this.sessionState = createSessionState(params.sessionId, params.cwd);
5411
+ this.sessionId = params.sessionId;
5412
+ this.sessionState.configOptions = response.configOptions ?? [];
5413
+ return response;
5414
+ }
5415
+ async unstable_resumeSession(params) {
5416
+ const loadResponse = await this.codexConnection.loadSession({
5417
+ sessionId: params.sessionId,
5418
+ cwd: params.cwd,
5419
+ mcpServers: params.mcpServers ?? []
5420
+ });
5421
+ this.sessionState = createSessionState(params.sessionId, params.cwd);
5422
+ this.sessionId = params.sessionId;
5423
+ this.sessionState.configOptions = loadResponse.configOptions ?? [];
5424
+ const meta = params._meta;
5425
+ if (meta?.taskRunId) {
5426
+ await this.client.extNotification(POSTHOG_NOTIFICATIONS.SDK_SESSION, {
5427
+ taskRunId: meta.taskRunId,
5428
+ sessionId: params.sessionId,
5429
+ adapter: "codex"
5430
+ });
5431
+ }
5153
5432
  return {
5154
- ...msg,
5155
- params: {
5156
- ...payload.params,
5157
- update: { ...payload.params.update, configOptions: filtered }
5158
- }
5433
+ modes: loadResponse.modes,
5434
+ models: loadResponse.models,
5435
+ configOptions: loadResponse.configOptions
5159
5436
  };
5160
5437
  }
5161
- return null;
5162
- }
5163
- function extractReasoningEffort(configOptions) {
5164
- if (!configOptions) return void 0;
5165
- const option = configOptions.find((opt) => opt.id === "reasoning_effort");
5166
- return option?.currentValue ?? void 0;
5167
- }
5438
+ async unstable_forkSession(params) {
5439
+ const newResponse = await this.codexConnection.newSession({
5440
+ cwd: params.cwd,
5441
+ mcpServers: params.mcpServers ?? [],
5442
+ _meta: params._meta
5443
+ });
5444
+ this.sessionState = createSessionState(newResponse.sessionId, params.cwd);
5445
+ this.sessionId = newResponse.sessionId;
5446
+ this.sessionState.configOptions = newResponse.configOptions ?? [];
5447
+ return newResponse;
5448
+ }
5449
+ async listSessions(params) {
5450
+ return this.codexConnection.listSessions(params);
5451
+ }
5452
+ async unstable_listSessions(params) {
5453
+ return this.codexConnection.listSessions(params);
5454
+ }
5455
+ async prompt(params) {
5456
+ if (this.sessionState) {
5457
+ this.sessionState.cancelled = false;
5458
+ this.sessionState.interruptReason = void 0;
5459
+ resetUsage(this.sessionState);
5460
+ }
5461
+ const response = await this.codexConnection.prompt(params);
5462
+ if (this.sessionState && response.usage) {
5463
+ this.sessionState.accumulatedUsage.inputTokens += response.usage.inputTokens ?? 0;
5464
+ this.sessionState.accumulatedUsage.outputTokens += response.usage.outputTokens ?? 0;
5465
+ this.sessionState.accumulatedUsage.cachedReadTokens += response.usage.cachedReadTokens ?? 0;
5466
+ this.sessionState.accumulatedUsage.cachedWriteTokens += response.usage.cachedWriteTokens ?? 0;
5467
+ }
5468
+ if (this.sessionState?.taskRunId) {
5469
+ const { accumulatedUsage } = this.sessionState;
5470
+ await this.client.extNotification(POSTHOG_NOTIFICATIONS.TURN_COMPLETE, {
5471
+ sessionId: params.sessionId,
5472
+ stopReason: response.stopReason ?? "end_turn",
5473
+ usage: {
5474
+ inputTokens: accumulatedUsage.inputTokens,
5475
+ outputTokens: accumulatedUsage.outputTokens,
5476
+ cachedReadTokens: accumulatedUsage.cachedReadTokens,
5477
+ cachedWriteTokens: accumulatedUsage.cachedWriteTokens,
5478
+ totalTokens: accumulatedUsage.inputTokens + accumulatedUsage.outputTokens + accumulatedUsage.cachedReadTokens + accumulatedUsage.cachedWriteTokens
5479
+ }
5480
+ });
5481
+ if (response.usage) {
5482
+ await this.client.extNotification("_posthog/usage_update", {
5483
+ sessionId: params.sessionId,
5484
+ used: {
5485
+ inputTokens: response.usage.inputTokens ?? 0,
5486
+ outputTokens: response.usage.outputTokens ?? 0,
5487
+ cachedReadTokens: response.usage.cachedReadTokens ?? 0,
5488
+ cachedWriteTokens: response.usage.cachedWriteTokens ?? 0
5489
+ },
5490
+ cost: null
5491
+ });
5492
+ }
5493
+ }
5494
+ return response;
5495
+ }
5496
+ async interrupt() {
5497
+ if (this.sessionState) {
5498
+ this.sessionState.cancelled = true;
5499
+ }
5500
+ await this.codexConnection.cancel({
5501
+ sessionId: this.sessionId
5502
+ });
5503
+ }
5504
+ async cancel(params) {
5505
+ if (this.sessionState) {
5506
+ this.sessionState.cancelled = true;
5507
+ const meta = params._meta;
5508
+ if (meta?.interruptReason) {
5509
+ this.sessionState.interruptReason = meta.interruptReason;
5510
+ }
5511
+ }
5512
+ await this.codexConnection.cancel(params);
5513
+ }
5514
+ async setSessionMode(params) {
5515
+ const response = await this.codexConnection.setSessionMode(params);
5516
+ if (this.sessionState) {
5517
+ this.sessionState.modeId = params.modeId;
5518
+ }
5519
+ return response ?? {};
5520
+ }
5521
+ async setSessionConfigOption(params) {
5522
+ const response = await this.codexConnection.setSessionConfigOption(params);
5523
+ if (this.sessionState && response.configOptions) {
5524
+ this.sessionState.configOptions = response.configOptions;
5525
+ }
5526
+ return response;
5527
+ }
5528
+ async authenticate(_params) {
5529
+ }
5530
+ async closeSession() {
5531
+ this.logger.info("Closing Codex session", { sessionId: this.sessionId });
5532
+ this.session.settingsManager.dispose();
5533
+ try {
5534
+ this.codexProcess.kill();
5535
+ } catch (err) {
5536
+ this.logger.warn("Failed to kill codex-acp process", { error: err });
5537
+ }
5538
+ }
5539
+ };
5540
+
5541
+ // src/adapters/acp-connection.ts
5168
5542
  function createAcpConnection(config = {}) {
5169
5543
  const adapterType = config.adapter ?? "claude";
5170
5544
  if (adapterType === "codex") {
@@ -5205,7 +5579,7 @@ function createClaudeConnection(config) {
5205
5579
  hasLogWriter: !!logWriter
5206
5580
  });
5207
5581
  }
5208
- const agentStream = ndJsonStream(agentWritable, streams.agent.readable);
5582
+ const agentStream = ndJsonStream2(agentWritable, streams.agent.readable);
5209
5583
  let agent = null;
5210
5584
  const agentConnection = new AgentSideConnection((client) => {
5211
5585
  agent = new ClaudeAcpAgent(client, config.processCallbacks);
@@ -5237,214 +5611,63 @@ function createClaudeConnection(config) {
5237
5611
  function createCodexConnection(config) {
5238
5612
  const logger = config.logger?.child("CodexConnection") ?? new Logger({ debug: true, prefix: "[CodexConnection]" });
5239
5613
  const { logWriter } = config;
5240
- const allowedModelIds = config.allowedModelIds;
5241
- const codexProcess = spawnCodexProcess({
5242
- ...config.codexOptions,
5243
- logger,
5244
- processCallbacks: config.processCallbacks
5245
- });
5246
- let clientReadable = nodeReadableToWebReadable(codexProcess.stdout);
5247
- let clientWritable = nodeWritableToWebWritable(codexProcess.stdin);
5248
- let isLoadingSession = false;
5249
- let loadRequestId = null;
5250
- let newSessionRequestId = null;
5251
- let sdkSessionEmitted = false;
5252
- const reasoningEffortBySessionId = /* @__PURE__ */ new Map();
5253
- let injectedConfigId = 0;
5254
- const decoder = new TextDecoder();
5255
- const encoder = new TextEncoder();
5256
- let readBuffer = "";
5257
- const taskRunId = config.taskRunId;
5258
- const filteringReadable = clientReadable.pipeThrough(
5259
- new TransformStream({
5260
- transform(chunk, controller) {
5261
- readBuffer += decoder.decode(chunk, { stream: true });
5262
- const lines = readBuffer.split("\n");
5263
- readBuffer = lines.pop() ?? "";
5264
- const outputLines = [];
5265
- for (const line of lines) {
5266
- const trimmed2 = line.trim();
5267
- if (!trimmed2) {
5268
- outputLines.push(line);
5269
- continue;
5270
- }
5271
- let shouldFilter = false;
5272
- try {
5273
- const msg = JSON.parse(trimmed2);
5274
- const sessionId = msg?.params?.sessionId ?? msg?.result?.sessionId ?? null;
5275
- const configOptions = msg?.result?.configOptions ?? msg?.params?.update?.configOptions;
5276
- if (sessionId && configOptions) {
5277
- const effort = extractReasoningEffort(configOptions);
5278
- if (effort) {
5279
- reasoningEffortBySessionId.set(sessionId, effort);
5280
- }
5281
- }
5282
- if (!sdkSessionEmitted && newSessionRequestId !== null && msg.id === newSessionRequestId && "result" in msg) {
5283
- const sessionId2 = msg.result?.sessionId;
5284
- if (sessionId2 && taskRunId) {
5285
- const sdkSessionNotification = {
5286
- jsonrpc: "2.0",
5287
- method: POSTHOG_NOTIFICATIONS.SDK_SESSION,
5288
- params: {
5289
- taskRunId,
5290
- sessionId: sessionId2,
5291
- adapter: "codex"
5292
- }
5293
- };
5294
- outputLines.push(JSON.stringify(sdkSessionNotification));
5295
- sdkSessionEmitted = true;
5296
- }
5297
- newSessionRequestId = null;
5298
- }
5299
- if (isLoadingSession) {
5300
- if (msg.id === loadRequestId && "result" in msg) {
5301
- logger.debug("session/load complete, resuming stream");
5302
- isLoadingSession = false;
5303
- loadRequestId = null;
5304
- } else if (msg.method === "session/update") {
5305
- shouldFilter = true;
5306
- }
5307
- }
5308
- if (!shouldFilter && allowedModelIds && allowedModelIds.size > 0) {
5309
- const updated = filterModelConfigOptions(msg, allowedModelIds);
5310
- if (updated) {
5311
- outputLines.push(JSON.stringify(updated));
5312
- continue;
5313
- }
5314
- }
5315
- } catch {
5316
- }
5317
- if (!shouldFilter) {
5318
- outputLines.push(line);
5319
- const isChunkNoise = trimmed2.includes('"sessionUpdate":"agent_message_chunk"') || trimmed2.includes('"sessionUpdate":"agent_thought_chunk"');
5320
- if (!isChunkNoise) {
5321
- logger.debug("codex-acp stdout:", trimmed2);
5322
- }
5323
- }
5324
- }
5325
- if (outputLines.length > 0) {
5326
- const output = `${outputLines.join("\n")}
5327
- `;
5328
- controller.enqueue(encoder.encode(output));
5329
- }
5330
- },
5331
- flush(controller) {
5332
- if (readBuffer.trim()) {
5333
- controller.enqueue(encoder.encode(readBuffer));
5334
- }
5335
- }
5336
- })
5337
- );
5338
- clientReadable = filteringReadable;
5339
- const originalWritable = clientWritable;
5340
- clientWritable = new WritableStream({
5341
- write(chunk) {
5342
- const text2 = decoder.decode(chunk, { stream: true });
5343
- const trimmed2 = text2.trim();
5344
- logger.debug("codex-acp stdin:", trimmed2);
5345
- try {
5346
- const msg = JSON.parse(trimmed2);
5347
- if (msg.method === "session/set_config_option" && msg.params?.configId === "reasoning_effort" && msg.params?.sessionId && msg.params?.value) {
5348
- reasoningEffortBySessionId.set(
5349
- msg.params.sessionId,
5350
- msg.params.value
5351
- );
5352
- }
5353
- if (msg.method === "session/prompt" && msg.params?.sessionId) {
5354
- const effort = reasoningEffortBySessionId.get(msg.params.sessionId);
5355
- if (effort) {
5356
- const injection = {
5357
- jsonrpc: "2.0",
5358
- id: `reasoning_effort_${Date.now()}_${injectedConfigId++}`,
5359
- method: "session/set_config_option",
5360
- params: {
5361
- sessionId: msg.params.sessionId,
5362
- configId: "reasoning_effort",
5363
- value: effort
5364
- }
5365
- };
5366
- const injectionLine = `${JSON.stringify(injection)}
5367
- `;
5368
- const writer2 = originalWritable.getWriter();
5369
- return writer2.write(encoder.encode(injectionLine)).then(() => writer2.releaseLock()).then(() => {
5370
- const nextWriter = originalWritable.getWriter();
5371
- return nextWriter.write(chunk).finally(() => nextWriter.releaseLock());
5372
- });
5373
- }
5374
- }
5375
- if (msg.method === "session/new" && msg.id) {
5376
- logger.debug("session/new detected, tracking request ID");
5377
- newSessionRequestId = msg.id;
5378
- } else if (msg.method === "session/load" && msg.id) {
5379
- logger.debug("session/load detected, pausing stream updates");
5380
- isLoadingSession = true;
5381
- loadRequestId = msg.id;
5382
- }
5383
- } catch {
5384
- }
5385
- const writer = originalWritable.getWriter();
5386
- return writer.write(chunk).finally(() => writer.releaseLock());
5387
- },
5388
- close() {
5389
- const writer = originalWritable.getWriter();
5390
- return writer.close().finally(() => writer.releaseLock());
5391
- }
5392
- });
5393
- const shouldTapLogs = config.taskRunId && logWriter;
5394
- if (shouldTapLogs && config.taskRunId) {
5395
- const taskRunId2 = config.taskRunId;
5396
- if (!logWriter.isRegistered(taskRunId2)) {
5397
- logWriter.register(taskRunId2, {
5398
- taskId: config.taskId ?? taskRunId2,
5399
- runId: taskRunId2
5614
+ const streams = createBidirectionalStreams();
5615
+ let agentWritable = streams.agent.writable;
5616
+ let clientWritable = streams.client.writable;
5617
+ if (config.taskRunId && logWriter) {
5618
+ if (!logWriter.isRegistered(config.taskRunId)) {
5619
+ logWriter.register(config.taskRunId, {
5620
+ taskId: config.taskId ?? config.taskRunId,
5621
+ runId: config.taskRunId,
5622
+ deviceType: config.deviceType
5400
5623
  });
5401
5624
  }
5402
- clientWritable = createTappedWritableStream(clientWritable, {
5625
+ const taskRunId = config.taskRunId;
5626
+ agentWritable = createTappedWritableStream(streams.agent.writable, {
5403
5627
  onMessage: (line) => {
5404
- logWriter.appendRawLine(taskRunId2, line);
5628
+ logWriter.appendRawLine(taskRunId, line);
5629
+ },
5630
+ logger
5631
+ });
5632
+ clientWritable = createTappedWritableStream(streams.client.writable, {
5633
+ onMessage: (line) => {
5634
+ logWriter.appendRawLine(taskRunId, line);
5405
5635
  },
5406
5636
  logger
5407
5637
  });
5408
- const originalReadable = clientReadable;
5409
- const logDecoder = new TextDecoder();
5410
- let logBuffer = "";
5411
- clientReadable = originalReadable.pipeThrough(
5412
- new TransformStream({
5413
- transform(chunk, controller) {
5414
- logBuffer += logDecoder.decode(chunk, { stream: true });
5415
- const lines = logBuffer.split("\n");
5416
- logBuffer = lines.pop() ?? "";
5417
- for (const line of lines) {
5418
- if (line.trim()) {
5419
- logWriter.appendRawLine(taskRunId2, line);
5420
- }
5421
- }
5422
- controller.enqueue(chunk);
5423
- },
5424
- flush() {
5425
- if (logBuffer.trim()) {
5426
- logWriter.appendRawLine(taskRunId2, logBuffer);
5427
- }
5428
- }
5429
- })
5430
- );
5431
5638
  } else {
5432
5639
  logger.info("Tapped streams NOT enabled for Codex", {
5433
5640
  hasTaskRunId: !!config.taskRunId,
5434
5641
  hasLogWriter: !!logWriter
5435
5642
  });
5436
5643
  }
5644
+ const agentStream = ndJsonStream2(agentWritable, streams.agent.readable);
5645
+ let agent = null;
5646
+ const agentConnection = new AgentSideConnection((client) => {
5647
+ agent = new CodexAcpAgent(client, {
5648
+ codexProcessOptions: config.codexOptions ?? {},
5649
+ processCallbacks: config.processCallbacks
5650
+ });
5651
+ logger.info(`Created ${agent.adapterName} agent`);
5652
+ return agent;
5653
+ }, agentStream);
5437
5654
  return {
5438
- agentConnection: void 0,
5655
+ agentConnection,
5439
5656
  clientStreams: {
5440
- readable: clientReadable,
5657
+ readable: streams.client.readable,
5441
5658
  writable: clientWritable
5442
5659
  },
5443
5660
  cleanup: async () => {
5444
5661
  logger.info("Cleaning up Codex connection");
5445
- codexProcess.kill();
5662
+ if (agent) {
5663
+ await agent.closeSession();
5664
+ }
5665
+ try {
5666
+ await streams.client.writable.close();
5667
+ } catch {
5668
+ }
5446
5669
  try {
5447
- await clientWritable.close();
5670
+ await streams.agent.writable.close();
5448
5671
  } catch {
5449
5672
  }
5450
5673
  }
@@ -5453,9 +5676,9 @@ function createCodexConnection(config) {
5453
5676
 
5454
5677
  // src/adapters/claude/session/jsonl-hydration.ts
5455
5678
  import { randomUUID as randomUUID2 } from "crypto";
5456
- import * as fs5 from "fs/promises";
5457
- import * as os5 from "os";
5458
- import * as path7 from "path";
5679
+ import * as fs6 from "fs/promises";
5680
+ import * as os6 from "os";
5681
+ import * as path8 from "path";
5459
5682
  var CHARS_PER_TOKEN = 4;
5460
5683
  var DEFAULT_MAX_TOKENS = 15e4;
5461
5684
  function estimateTurnTokens(turn) {
@@ -5818,8 +6041,8 @@ var Saga = class {
5818
6041
  };
5819
6042
 
5820
6043
  // ../git/dist/queries.js
5821
- import * as fs7 from "fs/promises";
5822
- import * as path9 from "path";
6044
+ import * as fs8 from "fs/promises";
6045
+ import * as path10 from "path";
5823
6046
 
5824
6047
  // ../../node_modules/simple-git/dist/esm/index.js
5825
6048
  var import_file_exists = __toESM(require_dist(), 1);
@@ -5858,8 +6081,8 @@ function pathspec(...paths) {
5858
6081
  cache.set(key, paths);
5859
6082
  return key;
5860
6083
  }
5861
- function isPathSpec(path12) {
5862
- return path12 instanceof String && cache.has(path12);
6084
+ function isPathSpec(path13) {
6085
+ return path13 instanceof String && cache.has(path13);
5863
6086
  }
5864
6087
  function toPaths(pathSpec) {
5865
6088
  return cache.get(pathSpec) || [];
@@ -5948,8 +6171,8 @@ function toLinesWithContent(input = "", trimmed2 = true, separator = "\n") {
5948
6171
  function forEachLineWithContent(input, callback) {
5949
6172
  return toLinesWithContent(input, true).map((line) => callback(line));
5950
6173
  }
5951
- function folderExists(path12) {
5952
- return (0, import_file_exists.exists)(path12, import_file_exists.FOLDER);
6174
+ function folderExists(path13) {
6175
+ return (0, import_file_exists.exists)(path13, import_file_exists.FOLDER);
5953
6176
  }
5954
6177
  function append(target, item) {
5955
6178
  if (Array.isArray(target)) {
@@ -6353,8 +6576,8 @@ function checkIsRepoRootTask() {
6353
6576
  commands,
6354
6577
  format: "utf-8",
6355
6578
  onError,
6356
- parser(path12) {
6357
- return /^\.(git)?$/.test(path12.trim());
6579
+ parser(path13) {
6580
+ return /^\.(git)?$/.test(path13.trim());
6358
6581
  }
6359
6582
  };
6360
6583
  }
@@ -6788,11 +7011,11 @@ function parseGrep(grep) {
6788
7011
  const paths = /* @__PURE__ */ new Set();
6789
7012
  const results = {};
6790
7013
  forEachLineWithContent(grep, (input) => {
6791
- const [path12, line, preview] = input.split(NULL);
6792
- paths.add(path12);
6793
- (results[path12] = results[path12] || []).push({
7014
+ const [path13, line, preview] = input.split(NULL);
7015
+ paths.add(path13);
7016
+ (results[path13] = results[path13] || []).push({
6794
7017
  line: asNumber(line),
6795
- path: path12,
7018
+ path: path13,
6796
7019
  preview
6797
7020
  });
6798
7021
  });
@@ -7557,14 +7780,14 @@ var init_hash_object = __esm({
7557
7780
  init_task();
7558
7781
  }
7559
7782
  });
7560
- function parseInit(bare, path12, text2) {
7783
+ function parseInit(bare, path13, text2) {
7561
7784
  const response = String(text2).trim();
7562
7785
  let result;
7563
7786
  if (result = initResponseRegex.exec(response)) {
7564
- return new InitSummary(bare, path12, false, result[1]);
7787
+ return new InitSummary(bare, path13, false, result[1]);
7565
7788
  }
7566
7789
  if (result = reInitResponseRegex.exec(response)) {
7567
- return new InitSummary(bare, path12, true, result[1]);
7790
+ return new InitSummary(bare, path13, true, result[1]);
7568
7791
  }
7569
7792
  let gitDir = "";
7570
7793
  const tokens = response.split(" ");
@@ -7575,7 +7798,7 @@ function parseInit(bare, path12, text2) {
7575
7798
  break;
7576
7799
  }
7577
7800
  }
7578
- return new InitSummary(bare, path12, /^re/i.test(response), gitDir);
7801
+ return new InitSummary(bare, path13, /^re/i.test(response), gitDir);
7579
7802
  }
7580
7803
  var InitSummary;
7581
7804
  var initResponseRegex;
@@ -7584,9 +7807,9 @@ var init_InitSummary = __esm({
7584
7807
  "src/lib/responses/InitSummary.ts"() {
7585
7808
  "use strict";
7586
7809
  InitSummary = class {
7587
- constructor(bare, path12, existing, gitDir) {
7810
+ constructor(bare, path13, existing, gitDir) {
7588
7811
  this.bare = bare;
7589
- this.path = path12;
7812
+ this.path = path13;
7590
7813
  this.existing = existing;
7591
7814
  this.gitDir = gitDir;
7592
7815
  }
@@ -7598,7 +7821,7 @@ var init_InitSummary = __esm({
7598
7821
  function hasBareCommand(command) {
7599
7822
  return command.includes(bareCommand);
7600
7823
  }
7601
- function initTask(bare = false, path12, customArgs) {
7824
+ function initTask(bare = false, path13, customArgs) {
7602
7825
  const commands = ["init", ...customArgs];
7603
7826
  if (bare && !hasBareCommand(commands)) {
7604
7827
  commands.splice(1, 0, bareCommand);
@@ -7607,7 +7830,7 @@ function initTask(bare = false, path12, customArgs) {
7607
7830
  commands,
7608
7831
  format: "utf-8",
7609
7832
  parser(text2) {
7610
- return parseInit(commands.includes("--bare"), path12, text2);
7833
+ return parseInit(commands.includes("--bare"), path13, text2);
7611
7834
  }
7612
7835
  };
7613
7836
  }
@@ -8423,12 +8646,12 @@ var init_FileStatusSummary = __esm({
8423
8646
  "use strict";
8424
8647
  fromPathRegex = /^(.+)\0(.+)$/;
8425
8648
  FileStatusSummary = class {
8426
- constructor(path12, index, working_dir) {
8427
- this.path = path12;
8649
+ constructor(path13, index, working_dir) {
8650
+ this.path = path13;
8428
8651
  this.index = index;
8429
8652
  this.working_dir = working_dir;
8430
8653
  if (index === "R" || working_dir === "R") {
8431
- const detail = fromPathRegex.exec(path12) || [null, path12, path12];
8654
+ const detail = fromPathRegex.exec(path13) || [null, path13, path13];
8432
8655
  this.from = detail[2] || "";
8433
8656
  this.path = detail[1] || "";
8434
8657
  }
@@ -8459,14 +8682,14 @@ function splitLine(result, lineStr) {
8459
8682
  default:
8460
8683
  return;
8461
8684
  }
8462
- function data(index, workingDir, path12) {
8685
+ function data(index, workingDir, path13) {
8463
8686
  const raw = `${index}${workingDir}`;
8464
8687
  const handler = parsers6.get(raw);
8465
8688
  if (handler) {
8466
- handler(result, path12);
8689
+ handler(result, path13);
8467
8690
  }
8468
8691
  if (raw !== "##" && raw !== "!!") {
8469
- result.files.push(new FileStatusSummary(path12, index, workingDir));
8692
+ result.files.push(new FileStatusSummary(path13, index, workingDir));
8470
8693
  }
8471
8694
  }
8472
8695
  }
@@ -8779,9 +9002,9 @@ var init_simple_git_api = __esm({
8779
9002
  next
8780
9003
  );
8781
9004
  }
8782
- hashObject(path12, write) {
9005
+ hashObject(path13, write) {
8783
9006
  return this._runTask(
8784
- hashObjectTask(path12, write === true),
9007
+ hashObjectTask(path13, write === true),
8785
9008
  trailingFunctionArgument(arguments)
8786
9009
  );
8787
9010
  }
@@ -9134,8 +9357,8 @@ var init_branch = __esm({
9134
9357
  }
9135
9358
  });
9136
9359
  function toPath(input) {
9137
- const path12 = input.trim().replace(/^["']|["']$/g, "");
9138
- return path12 && normalize2(path12);
9360
+ const path13 = input.trim().replace(/^["']|["']$/g, "");
9361
+ return path13 && normalize2(path13);
9139
9362
  }
9140
9363
  var parseCheckIgnore;
9141
9364
  var init_CheckIgnore = __esm({
@@ -9449,8 +9672,8 @@ __export(sub_module_exports, {
9449
9672
  subModuleTask: () => subModuleTask,
9450
9673
  updateSubModuleTask: () => updateSubModuleTask
9451
9674
  });
9452
- function addSubModuleTask(repo, path12) {
9453
- return subModuleTask(["add", repo, path12]);
9675
+ function addSubModuleTask(repo, path13) {
9676
+ return subModuleTask(["add", repo, path13]);
9454
9677
  }
9455
9678
  function initSubModuleTask(customArgs) {
9456
9679
  return subModuleTask(["init", ...customArgs]);
@@ -9780,8 +10003,8 @@ var require_git = __commonJS2({
9780
10003
  }
9781
10004
  return this._runTask(straightThroughStringTask2(command, this._trimmed), next);
9782
10005
  };
9783
- Git2.prototype.submoduleAdd = function(repo, path12, then) {
9784
- return this._runTask(addSubModuleTask2(repo, path12), trailingFunctionArgument2(arguments));
10006
+ Git2.prototype.submoduleAdd = function(repo, path13, then) {
10007
+ return this._runTask(addSubModuleTask2(repo, path13), trailingFunctionArgument2(arguments));
9785
10008
  };
9786
10009
  Git2.prototype.submoduleUpdate = function(args, then) {
9787
10010
  return this._runTask(
@@ -10382,22 +10605,22 @@ function createGitClient(baseDir, options) {
10382
10605
 
10383
10606
  // ../git/dist/lock-detector.js
10384
10607
  import { execFile } from "child_process";
10385
- import fs6 from "fs/promises";
10386
- import path8 from "path";
10608
+ import fs7 from "fs/promises";
10609
+ import path9 from "path";
10387
10610
  import { promisify } from "util";
10388
10611
  var execFileAsync = promisify(execFile);
10389
10612
  async function getIndexLockPath(repoPath) {
10390
10613
  try {
10391
10614
  const { stdout } = await execFileAsync("git", ["rev-parse", "--git-path", "index.lock"], { cwd: repoPath });
10392
- return path8.resolve(repoPath, stdout.trim());
10615
+ return path9.resolve(repoPath, stdout.trim());
10393
10616
  } catch {
10394
- return path8.join(repoPath, ".git", "index.lock");
10617
+ return path9.join(repoPath, ".git", "index.lock");
10395
10618
  }
10396
10619
  }
10397
10620
  async function getLockInfo(repoPath) {
10398
10621
  const lockPath = await getIndexLockPath(repoPath);
10399
10622
  try {
10400
- const stat = await fs6.stat(lockPath);
10623
+ const stat = await fs7.stat(lockPath);
10401
10624
  return {
10402
10625
  path: lockPath,
10403
10626
  ageMs: Date.now() - stat.mtimeMs
@@ -10408,7 +10631,7 @@ async function getLockInfo(repoPath) {
10408
10631
  }
10409
10632
  async function removeLock(repoPath) {
10410
10633
  const lockPath = await getIndexLockPath(repoPath);
10411
- await fs6.rm(lockPath, { force: true });
10634
+ await fs7.rm(lockPath, { force: true });
10412
10635
  }
10413
10636
  async function isLocked(repoPath) {
10414
10637
  return await getLockInfo(repoPath) !== null;
@@ -10589,12 +10812,12 @@ async function getHeadSha(baseDir, options) {
10589
10812
 
10590
10813
  // src/sagas/apply-snapshot-saga.ts
10591
10814
  import { mkdir as mkdir4, rm as rm3, writeFile as writeFile4 } from "fs/promises";
10592
- import { join as join7 } from "path";
10815
+ import { join as join8 } from "path";
10593
10816
 
10594
10817
  // ../git/dist/sagas/tree.js
10595
10818
  import { existsSync as existsSync4 } from "fs";
10596
- import * as fs8 from "fs/promises";
10597
- import * as path10 from "path";
10819
+ import * as fs9 from "fs/promises";
10820
+ import * as path11 from "path";
10598
10821
  import * as tar from "tar";
10599
10822
 
10600
10823
  // ../git/dist/git-saga.js
@@ -10621,14 +10844,14 @@ var CaptureTreeSaga = class extends GitSaga {
10621
10844
  tempIndexPath = null;
10622
10845
  async executeGitOperations(input) {
10623
10846
  const { baseDir, lastTreeHash, archivePath, signal } = input;
10624
- const tmpDir = path10.join(baseDir, ".git", "posthog-code-tmp");
10847
+ const tmpDir = path11.join(baseDir, ".git", "posthog-code-tmp");
10625
10848
  await this.step({
10626
10849
  name: "create_tmp_dir",
10627
- execute: () => fs8.mkdir(tmpDir, { recursive: true }),
10850
+ execute: () => fs9.mkdir(tmpDir, { recursive: true }),
10628
10851
  rollback: async () => {
10629
10852
  }
10630
10853
  });
10631
- this.tempIndexPath = path10.join(tmpDir, `index-${Date.now()}`);
10854
+ this.tempIndexPath = path11.join(tmpDir, `index-${Date.now()}`);
10632
10855
  const tempIndexGit = this.git.env({
10633
10856
  ...process.env,
10634
10857
  GIT_INDEX_FILE: this.tempIndexPath
@@ -10638,7 +10861,7 @@ var CaptureTreeSaga = class extends GitSaga {
10638
10861
  execute: () => tempIndexGit.raw(["read-tree", "HEAD"]),
10639
10862
  rollback: async () => {
10640
10863
  if (this.tempIndexPath) {
10641
- await fs8.rm(this.tempIndexPath, { force: true }).catch(() => {
10864
+ await fs9.rm(this.tempIndexPath, { force: true }).catch(() => {
10642
10865
  });
10643
10866
  }
10644
10867
  }
@@ -10647,7 +10870,7 @@ var CaptureTreeSaga = class extends GitSaga {
10647
10870
  const treeHash = await this.readOnlyStep("write_tree", () => tempIndexGit.raw(["write-tree"]));
10648
10871
  if (lastTreeHash && treeHash === lastTreeHash) {
10649
10872
  this.log.debug("No changes since last capture", { treeHash });
10650
- await fs8.rm(this.tempIndexPath, { force: true }).catch(() => {
10873
+ await fs9.rm(this.tempIndexPath, { force: true }).catch(() => {
10651
10874
  });
10652
10875
  return { snapshot: null, changed: false };
10653
10876
  }
@@ -10659,7 +10882,7 @@ var CaptureTreeSaga = class extends GitSaga {
10659
10882
  }
10660
10883
  });
10661
10884
  const changes = await this.readOnlyStep("get_changes", () => this.getChanges(this.git, baseCommit, treeHash));
10662
- await fs8.rm(this.tempIndexPath, { force: true }).catch(() => {
10885
+ await fs9.rm(this.tempIndexPath, { force: true }).catch(() => {
10663
10886
  });
10664
10887
  const snapshot = {
10665
10888
  treeHash,
@@ -10683,15 +10906,15 @@ var CaptureTreeSaga = class extends GitSaga {
10683
10906
  if (filesToArchive.length === 0) {
10684
10907
  return void 0;
10685
10908
  }
10686
- const existingFiles = filesToArchive.filter((f) => existsSync4(path10.join(baseDir, f)));
10909
+ const existingFiles = filesToArchive.filter((f) => existsSync4(path11.join(baseDir, f)));
10687
10910
  if (existingFiles.length === 0) {
10688
10911
  return void 0;
10689
10912
  }
10690
10913
  await this.step({
10691
10914
  name: "create_archive",
10692
10915
  execute: async () => {
10693
- const archiveDir = path10.dirname(archivePath);
10694
- await fs8.mkdir(archiveDir, { recursive: true });
10916
+ const archiveDir = path11.dirname(archivePath);
10917
+ await fs9.mkdir(archiveDir, { recursive: true });
10695
10918
  await tar.create({
10696
10919
  gzip: true,
10697
10920
  file: archivePath,
@@ -10699,7 +10922,7 @@ var CaptureTreeSaga = class extends GitSaga {
10699
10922
  }, existingFiles);
10700
10923
  },
10701
10924
  rollback: async () => {
10702
- await fs8.rm(archivePath, { force: true }).catch(() => {
10925
+ await fs9.rm(archivePath, { force: true }).catch(() => {
10703
10926
  });
10704
10927
  }
10705
10928
  });
@@ -10799,9 +11022,9 @@ var ApplyTreeSaga = class extends GitSaga {
10799
11022
  const filesToExtract = changes.filter((c) => c.status !== "D").map((c) => c.path);
10800
11023
  await this.readOnlyStep("backup_existing_files", async () => {
10801
11024
  for (const filePath of filesToExtract) {
10802
- const fullPath = path10.join(baseDir, filePath);
11025
+ const fullPath = path11.join(baseDir, filePath);
10803
11026
  try {
10804
- const content = await fs8.readFile(fullPath);
11027
+ const content = await fs9.readFile(fullPath);
10805
11028
  this.fileBackups.set(filePath, content);
10806
11029
  } catch {
10807
11030
  }
@@ -10818,16 +11041,16 @@ var ApplyTreeSaga = class extends GitSaga {
10818
11041
  },
10819
11042
  rollback: async () => {
10820
11043
  for (const filePath of this.extractedFiles) {
10821
- const fullPath = path10.join(baseDir, filePath);
11044
+ const fullPath = path11.join(baseDir, filePath);
10822
11045
  const backup = this.fileBackups.get(filePath);
10823
11046
  if (backup) {
10824
- const dir = path10.dirname(fullPath);
10825
- await fs8.mkdir(dir, { recursive: true }).catch(() => {
11047
+ const dir = path11.dirname(fullPath);
11048
+ await fs9.mkdir(dir, { recursive: true }).catch(() => {
10826
11049
  });
10827
- await fs8.writeFile(fullPath, backup).catch(() => {
11050
+ await fs9.writeFile(fullPath, backup).catch(() => {
10828
11051
  });
10829
11052
  } else {
10830
- await fs8.rm(fullPath, { force: true }).catch(() => {
11053
+ await fs9.rm(fullPath, { force: true }).catch(() => {
10831
11054
  });
10832
11055
  }
10833
11056
  }
@@ -10835,10 +11058,10 @@ var ApplyTreeSaga = class extends GitSaga {
10835
11058
  });
10836
11059
  }
10837
11060
  for (const change of changes.filter((c) => c.status === "D")) {
10838
- const fullPath = path10.join(baseDir, change.path);
11061
+ const fullPath = path11.join(baseDir, change.path);
10839
11062
  const backupContent = await this.readOnlyStep(`backup_${change.path}`, async () => {
10840
11063
  try {
10841
- return await fs8.readFile(fullPath);
11064
+ return await fs9.readFile(fullPath);
10842
11065
  } catch {
10843
11066
  return null;
10844
11067
  }
@@ -10846,15 +11069,15 @@ var ApplyTreeSaga = class extends GitSaga {
10846
11069
  await this.step({
10847
11070
  name: `delete_${change.path}`,
10848
11071
  execute: async () => {
10849
- await fs8.rm(fullPath, { force: true });
11072
+ await fs9.rm(fullPath, { force: true });
10850
11073
  this.log.debug(`Deleted file: ${change.path}`);
10851
11074
  },
10852
11075
  rollback: async () => {
10853
11076
  if (backupContent) {
10854
- const dir = path10.dirname(fullPath);
10855
- await fs8.mkdir(dir, { recursive: true }).catch(() => {
11077
+ const dir = path11.dirname(fullPath);
11078
+ await fs9.mkdir(dir, { recursive: true }).catch(() => {
10856
11079
  });
10857
- await fs8.writeFile(fullPath, backupContent).catch(() => {
11080
+ await fs9.writeFile(fullPath, backupContent).catch(() => {
10858
11081
  });
10859
11082
  }
10860
11083
  }
@@ -10877,7 +11100,7 @@ var ApplySnapshotSaga = class extends Saga {
10877
11100
  archivePath = null;
10878
11101
  async execute(input) {
10879
11102
  const { snapshot, repositoryPath, apiClient, taskId, runId } = input;
10880
- const tmpDir = join7(repositoryPath, ".posthog", "tmp");
11103
+ const tmpDir = join8(repositoryPath, ".posthog", "tmp");
10881
11104
  if (!snapshot.archiveUrl) {
10882
11105
  throw new Error("Cannot apply snapshot: no archive URL");
10883
11106
  }
@@ -10888,7 +11111,7 @@ var ApplySnapshotSaga = class extends Saga {
10888
11111
  rollback: async () => {
10889
11112
  }
10890
11113
  });
10891
- const archivePath = join7(tmpDir, `${snapshot.treeHash}.tar.gz`);
11114
+ const archivePath = join8(tmpDir, `${snapshot.treeHash}.tar.gz`);
10892
11115
  this.archivePath = archivePath;
10893
11116
  await this.step({
10894
11117
  name: "download_archive",
@@ -10937,7 +11160,7 @@ var ApplySnapshotSaga = class extends Saga {
10937
11160
  // src/sagas/capture-tree-saga.ts
10938
11161
  import { existsSync as existsSync5 } from "fs";
10939
11162
  import { readFile as readFile3, rm as rm4 } from "fs/promises";
10940
- import { join as join8 } from "path";
11163
+ import { join as join9 } from "path";
10941
11164
  var CaptureTreeSaga2 = class extends Saga {
10942
11165
  sagaName = "CaptureTreeSaga";
10943
11166
  async execute(input) {
@@ -10949,14 +11172,14 @@ var CaptureTreeSaga2 = class extends Saga {
10949
11172
  taskId,
10950
11173
  runId
10951
11174
  } = input;
10952
- const tmpDir = join8(repositoryPath, ".posthog", "tmp");
10953
- if (existsSync5(join8(repositoryPath, ".gitmodules"))) {
11175
+ const tmpDir = join9(repositoryPath, ".posthog", "tmp");
11176
+ if (existsSync5(join9(repositoryPath, ".gitmodules"))) {
10954
11177
  this.log.warn(
10955
11178
  "Repository has submodules - snapshot may not capture submodule state"
10956
11179
  );
10957
11180
  }
10958
11181
  const shouldArchive = !!apiClient;
10959
- const archivePath = shouldArchive ? join8(tmpDir, `tree-${Date.now()}.tar.gz`) : void 0;
11182
+ const archivePath = shouldArchive ? join9(tmpDir, `tree-${Date.now()}.tar.gz`) : void 0;
10960
11183
  const gitCaptureSaga = new CaptureTreeSaga(this.log);
10961
11184
  const captureResult = await gitCaptureSaga.run({
10962
11185
  baseDir: repositoryPath,
@@ -11415,9 +11638,9 @@ async function resumeFromLog(config) {
11415
11638
  }
11416
11639
 
11417
11640
  // src/session-log-writer.ts
11418
- import fs9 from "fs";
11641
+ import fs10 from "fs";
11419
11642
  import fsp from "fs/promises";
11420
- import path11 from "path";
11643
+ import path12 from "path";
11421
11644
  var SessionLogWriter = class _SessionLogWriter {
11422
11645
  static FLUSH_DEBOUNCE_MS = 500;
11423
11646
  static FLUSH_MAX_INTERVAL_MS = 5e3;
@@ -11457,13 +11680,13 @@ var SessionLogWriter = class _SessionLogWriter {
11457
11680
  this.sessions.set(sessionId, { context, currentTurnMessages: [] });
11458
11681
  this.lastFlushAttemptTime.set(sessionId, Date.now());
11459
11682
  if (this.localCachePath) {
11460
- const sessionDir = path11.join(
11683
+ const sessionDir = path12.join(
11461
11684
  this.localCachePath,
11462
11685
  "sessions",
11463
11686
  context.runId
11464
11687
  );
11465
11688
  try {
11466
- fs9.mkdirSync(sessionDir, { recursive: true });
11689
+ fs10.mkdirSync(sessionDir, { recursive: true });
11467
11690
  } catch (error) {
11468
11691
  this.logger.warn("Failed to create local cache directory", {
11469
11692
  sessionDir,
@@ -11715,14 +11938,14 @@ var SessionLogWriter = class _SessionLogWriter {
11715
11938
  if (!this.localCachePath) return;
11716
11939
  const session = this.sessions.get(sessionId);
11717
11940
  if (!session) return;
11718
- const logPath = path11.join(
11941
+ const logPath = path12.join(
11719
11942
  this.localCachePath,
11720
11943
  "sessions",
11721
11944
  session.context.runId,
11722
11945
  "logs.ndjson"
11723
11946
  );
11724
11947
  try {
11725
- fs9.appendFileSync(logPath, `${JSON.stringify(entry)}
11948
+ fs10.appendFileSync(logPath, `${JSON.stringify(entry)}
11726
11949
  `);
11727
11950
  } catch (error) {
11728
11951
  this.logger.warn("Failed to write to local cache", {
@@ -11734,13 +11957,13 @@ var SessionLogWriter = class _SessionLogWriter {
11734
11957
  }
11735
11958
  }
11736
11959
  static async cleanupOldSessions(localCachePath) {
11737
- const sessionsDir = path11.join(localCachePath, "sessions");
11960
+ const sessionsDir = path12.join(localCachePath, "sessions");
11738
11961
  let deleted = 0;
11739
11962
  try {
11740
11963
  const entries = await fsp.readdir(sessionsDir);
11741
11964
  const now = Date.now();
11742
11965
  for (const entry of entries) {
11743
- const entryPath = path11.join(sessionsDir, entry);
11966
+ const entryPath = path12.join(sessionsDir, entry);
11744
11967
  try {
11745
11968
  const stats = await fsp.stat(entryPath);
11746
11969
  if (stats.isDirectory() && now - stats.birthtimeMs > _SessionLogWriter.SESSIONS_MAX_AGE_MS) {
@@ -12388,8 +12611,8 @@ You MUST NOT create a new branch, close the existing PR, or create a new PR.`
12388
12611
  onAcpMessage,
12389
12612
  this.logger
12390
12613
  );
12391
- const clientStream = ndJsonStream2(tappedWritable, tappedReadable);
12392
- const clientConnection = new ClientSideConnection(
12614
+ const clientStream = ndJsonStream3(tappedWritable, tappedReadable);
12615
+ const clientConnection = new ClientSideConnection2(
12393
12616
  () => this.createCloudClient(payload),
12394
12617
  clientStream
12395
12618
  );