@posthog/agent 2.3.168 → 2.3.169

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.169",
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,188 @@ 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
+ callbacks?.onUsageUpdate?.(update);
5038
+ }
5039
+ await upstreamClient.sessionUpdate(params);
5040
+ },
5041
+ async readTextFile(params) {
5042
+ return upstreamClient.readTextFile(params);
5043
+ },
5044
+ async writeTextFile(params) {
5045
+ return upstreamClient.writeTextFile(params);
5046
+ },
5047
+ async createTerminal(params) {
5048
+ const handle = await upstreamClient.createTerminal(params);
5049
+ terminalHandles.set(handle.id, handle);
5050
+ return { terminalId: handle.id };
5051
+ },
5052
+ async terminalOutput(params) {
5053
+ const handle = terminalHandles.get(params.terminalId);
5054
+ if (!handle) {
5055
+ return { output: "", truncated: false };
5056
+ }
5057
+ return handle.currentOutput();
5058
+ },
5059
+ async releaseTerminal(params) {
5060
+ const handle = terminalHandles.get(params.terminalId);
5061
+ if (handle) {
5062
+ terminalHandles.delete(params.terminalId);
5063
+ const result = await handle.release();
5064
+ return result ?? void 0;
5065
+ }
5066
+ },
5067
+ async waitForTerminalExit(params) {
5068
+ const handle = terminalHandles.get(params.terminalId);
5069
+ if (!handle) {
5070
+ return { exitCode: 1 };
5071
+ }
5072
+ return handle.waitForExit();
5073
+ },
5074
+ async killTerminal(params) {
5075
+ const handle = terminalHandles.get(params.terminalId);
5076
+ if (handle) {
5077
+ return handle.kill();
5078
+ }
5079
+ },
5080
+ async extMethod(method, params) {
5081
+ return upstreamClient.extMethod(method, params);
5082
+ },
5083
+ async extNotification(method, params) {
5084
+ return upstreamClient.extNotification(method, params);
5085
+ }
5086
+ };
5087
+ }
5088
+
5089
+ // src/adapters/codex/session-state.ts
5090
+ function createSessionState(sessionId, cwd, opts) {
5091
+ return {
5092
+ sessionId,
5093
+ cwd,
5094
+ modeId: opts?.modeId ?? "default",
5095
+ modelId: opts?.modelId,
5096
+ configOptions: [],
5097
+ accumulatedUsage: {
5098
+ inputTokens: 0,
5099
+ outputTokens: 0,
5100
+ cachedReadTokens: 0,
5101
+ cachedWriteTokens: 0
5102
+ },
5103
+ cancelled: false,
5104
+ taskRunId: opts?.taskRunId,
5105
+ taskId: opts?.taskId
5106
+ };
5107
+ }
5108
+ function resetUsage(state) {
5109
+ state.accumulatedUsage = {
5110
+ inputTokens: 0,
5111
+ outputTokens: 0,
5112
+ cachedReadTokens: 0,
5113
+ cachedWriteTokens: 0
5114
+ };
5115
+ }
5116
+
5117
+ // src/adapters/codex/settings.ts
5118
+ import * as fs5 from "fs";
5119
+ import * as os5 from "os";
5120
+ import * as path7 from "path";
5121
+ var CodexSettingsManager = class {
5122
+ cwd;
5123
+ settings = {};
5124
+ initialized = false;
5125
+ constructor(cwd) {
5126
+ this.cwd = cwd;
5127
+ }
5128
+ async initialize() {
5129
+ if (this.initialized) {
5130
+ return;
5131
+ }
5132
+ await this.loadSettings();
5133
+ this.initialized = true;
5134
+ }
5135
+ getConfigPath() {
5136
+ return path7.join(os5.homedir(), ".codex", "config.toml");
5137
+ }
5138
+ async loadSettings() {
5139
+ const configPath = this.getConfigPath();
5140
+ try {
5141
+ const content = await fs5.promises.readFile(configPath, "utf-8");
5142
+ this.settings = parseCodexToml(content, this.cwd);
5143
+ } catch {
5144
+ this.settings = {};
5145
+ }
5146
+ }
5147
+ getSettings() {
5148
+ return this.settings;
5149
+ }
5150
+ getCwd() {
5151
+ return this.cwd;
5152
+ }
5153
+ async setCwd(cwd) {
5154
+ if (this.cwd === cwd) {
5155
+ return;
5156
+ }
5157
+ this.dispose();
5158
+ this.cwd = cwd;
5159
+ this.initialized = false;
5160
+ await this.initialize();
5161
+ }
5162
+ dispose() {
5163
+ this.initialized = false;
5164
+ }
5165
+ };
5166
+ function parseCodexToml(content, cwd) {
5167
+ const settings = {};
5168
+ let currentSection = "";
5169
+ for (const line of content.split("\n")) {
5170
+ const trimmed2 = line.trim();
5171
+ if (!trimmed2 || trimmed2.startsWith("#")) continue;
5172
+ const sectionMatch = trimmed2.match(/^\[(.+)\]$/);
5173
+ if (sectionMatch) {
5174
+ currentSection = sectionMatch[1] ?? "";
5175
+ continue;
5176
+ }
5177
+ const kvMatch = trimmed2.match(/^(\w+)\s*=\s*(.+)$/);
5178
+ if (!kvMatch) continue;
5179
+ const key = kvMatch[1];
5180
+ let value = kvMatch[2]?.trim() ?? "";
5181
+ if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
5182
+ value = value.slice(1, -1);
5183
+ }
5184
+ if (!currentSection) {
5185
+ if (key === "model") settings.model = value;
5186
+ if (key === "personality") settings.personality = value;
5187
+ if (key === "model_reasoning_effort")
5188
+ settings.modelReasoningEffort = value;
5189
+ } else if (currentSection === `projects."${cwd}"`) {
5190
+ if (key === "trust_level") settings.trustLevel = value;
5191
+ }
5192
+ }
5193
+ return settings;
5194
+ }
5195
+
5014
5196
  // src/adapters/codex/spawn.ts
5015
5197
  import { spawn as spawn2 } from "child_process";
5016
5198
  import { existsSync as existsSync3 } from "fs";
@@ -5107,64 +5289,216 @@ function spawnCodexProcess(options) {
5107
5289
  };
5108
5290
  }
5109
5291
 
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;
5292
+ // src/adapters/codex/codex-agent.ts
5293
+ var CodexAcpAgent = class extends BaseAcpAgent {
5294
+ adapterName = "codex";
5295
+ codexProcess;
5296
+ codexConnection;
5297
+ sessionState;
5298
+ constructor(client, options) {
5299
+ super(client);
5300
+ this.logger = new Logger({ debug: true, prefix: "[CodexAcpAgent]" });
5301
+ this.codexProcess = spawnCodexProcess({
5302
+ ...options.codexProcessOptions,
5303
+ logger: this.logger,
5304
+ processCallbacks: options.processCallbacks
5305
+ });
5306
+ const codexReadable = nodeReadableToWebReadable(this.codexProcess.stdout);
5307
+ const codexWritable = nodeWritableToWebWritable(this.codexProcess.stdin);
5308
+ const codexStream = ndJsonStream(codexWritable, codexReadable);
5309
+ const cwd = options.codexProcessOptions.cwd ?? process.cwd();
5310
+ const settingsManager = new CodexSettingsManager(cwd);
5311
+ const abortController = new AbortController();
5312
+ this.session = {
5313
+ abortController,
5314
+ settingsManager,
5315
+ notificationHistory: [],
5316
+ cancelled: false
5317
+ };
5318
+ this.codexConnection = new ClientSideConnection(
5319
+ (_agent) => createCodexClient(
5320
+ this.client,
5321
+ this.logger,
5322
+ this.sessionState ?? {
5323
+ sessionId: "",
5324
+ cwd: "",
5325
+ modeId: "default",
5326
+ configOptions: [],
5327
+ accumulatedUsage: {
5328
+ inputTokens: 0,
5329
+ outputTokens: 0,
5330
+ cachedReadTokens: 0,
5331
+ cachedWriteTokens: 0
5332
+ },
5333
+ cancelled: false
5334
+ }
5335
+ ),
5336
+ codexStream
5337
+ );
5338
+ }
5339
+ async initialize(request) {
5340
+ await this.session.settingsManager.initialize();
5341
+ const response = await this.codexConnection.initialize(request);
5143
5342
  return {
5144
- ...opt,
5145
- currentValue: nextCurrent,
5146
- options: filteredOptions
5343
+ ...response,
5344
+ agentCapabilities: {
5345
+ ...response.agentCapabilities,
5346
+ sessionCapabilities: {
5347
+ ...response.agentCapabilities?.sessionCapabilities,
5348
+ resume: {},
5349
+ fork: {}
5350
+ },
5351
+ _meta: {
5352
+ posthog: {
5353
+ resumeSession: true
5354
+ }
5355
+ }
5356
+ },
5357
+ agentInfo: {
5358
+ name: package_default.name,
5359
+ title: "Codex Agent",
5360
+ version: package_default.version
5361
+ }
5147
5362
  };
5148
- });
5149
- if (payload.result?.configOptions) {
5150
- return { ...msg, result: { ...payload.result, configOptions: filtered } };
5151
5363
  }
5152
- if (payload.params?.update?.configOptions) {
5364
+ async newSession(params) {
5365
+ const meta = params._meta;
5366
+ const response = await this.codexConnection.newSession(params);
5367
+ this.sessionState = createSessionState(response.sessionId, params.cwd, {
5368
+ taskRunId: meta?.taskRunId,
5369
+ taskId: meta?.taskId ?? meta?.persistence?.taskId,
5370
+ modeId: response.modes?.currentModeId ?? "default",
5371
+ modelId: response.models?.currentModelId
5372
+ });
5373
+ this.sessionId = response.sessionId;
5374
+ this.sessionState.configOptions = response.configOptions ?? [];
5375
+ if (meta?.taskRunId) {
5376
+ await this.client.extNotification(POSTHOG_NOTIFICATIONS.SDK_SESSION, {
5377
+ taskRunId: meta.taskRunId,
5378
+ sessionId: response.sessionId,
5379
+ adapter: "codex"
5380
+ });
5381
+ }
5382
+ this.logger.info("Codex session created", {
5383
+ sessionId: response.sessionId,
5384
+ taskRunId: meta?.taskRunId
5385
+ });
5386
+ return response;
5387
+ }
5388
+ async loadSession(params) {
5389
+ const response = await this.codexConnection.loadSession(params);
5390
+ this.sessionState = createSessionState(params.sessionId, params.cwd);
5391
+ this.sessionId = params.sessionId;
5392
+ this.sessionState.configOptions = response.configOptions ?? [];
5393
+ return response;
5394
+ }
5395
+ async unstable_resumeSession(params) {
5396
+ const loadResponse = await this.codexConnection.loadSession({
5397
+ sessionId: params.sessionId,
5398
+ cwd: params.cwd,
5399
+ mcpServers: params.mcpServers ?? []
5400
+ });
5401
+ this.sessionState = createSessionState(params.sessionId, params.cwd);
5402
+ this.sessionId = params.sessionId;
5403
+ this.sessionState.configOptions = loadResponse.configOptions ?? [];
5404
+ const meta = params._meta;
5405
+ if (meta?.taskRunId) {
5406
+ await this.client.extNotification(POSTHOG_NOTIFICATIONS.SDK_SESSION, {
5407
+ taskRunId: meta.taskRunId,
5408
+ sessionId: params.sessionId,
5409
+ adapter: "codex"
5410
+ });
5411
+ }
5153
5412
  return {
5154
- ...msg,
5155
- params: {
5156
- ...payload.params,
5157
- update: { ...payload.params.update, configOptions: filtered }
5158
- }
5413
+ modes: loadResponse.modes,
5414
+ models: loadResponse.models,
5415
+ configOptions: loadResponse.configOptions
5159
5416
  };
5160
5417
  }
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
- }
5418
+ async unstable_forkSession(params) {
5419
+ const newResponse = await this.codexConnection.newSession({
5420
+ cwd: params.cwd,
5421
+ mcpServers: params.mcpServers ?? [],
5422
+ _meta: params._meta
5423
+ });
5424
+ this.sessionState = createSessionState(newResponse.sessionId, params.cwd);
5425
+ this.sessionId = newResponse.sessionId;
5426
+ this.sessionState.configOptions = newResponse.configOptions ?? [];
5427
+ return newResponse;
5428
+ }
5429
+ async listSessions(params) {
5430
+ return this.codexConnection.listSessions(params);
5431
+ }
5432
+ async unstable_listSessions(params) {
5433
+ return this.codexConnection.listSessions(params);
5434
+ }
5435
+ async prompt(params) {
5436
+ if (this.sessionState) {
5437
+ this.sessionState.cancelled = false;
5438
+ this.sessionState.interruptReason = void 0;
5439
+ resetUsage(this.sessionState);
5440
+ }
5441
+ const response = await this.codexConnection.prompt(params);
5442
+ if (this.sessionState?.taskRunId && response.usage) {
5443
+ await this.client.extNotification("_posthog/usage_update", {
5444
+ sessionId: params.sessionId,
5445
+ used: {
5446
+ inputTokens: response.usage.inputTokens ?? 0,
5447
+ outputTokens: response.usage.outputTokens ?? 0,
5448
+ cachedReadTokens: response.usage.cachedReadTokens ?? 0,
5449
+ cachedWriteTokens: response.usage.cachedWriteTokens ?? 0
5450
+ },
5451
+ cost: null
5452
+ });
5453
+ }
5454
+ return response;
5455
+ }
5456
+ async interrupt() {
5457
+ if (this.sessionState) {
5458
+ this.sessionState.cancelled = true;
5459
+ }
5460
+ await this.codexConnection.cancel({
5461
+ sessionId: this.sessionId
5462
+ });
5463
+ }
5464
+ async cancel(params) {
5465
+ if (this.sessionState) {
5466
+ this.sessionState.cancelled = true;
5467
+ const meta = params._meta;
5468
+ if (meta?.interruptReason) {
5469
+ this.sessionState.interruptReason = meta.interruptReason;
5470
+ }
5471
+ }
5472
+ await this.codexConnection.cancel(params);
5473
+ }
5474
+ async setSessionMode(params) {
5475
+ const response = await this.codexConnection.setSessionMode(params);
5476
+ if (this.sessionState) {
5477
+ this.sessionState.modeId = params.modeId;
5478
+ }
5479
+ return response ?? {};
5480
+ }
5481
+ async setSessionConfigOption(params) {
5482
+ const response = await this.codexConnection.setSessionConfigOption(params);
5483
+ if (this.sessionState && response.configOptions) {
5484
+ this.sessionState.configOptions = response.configOptions;
5485
+ }
5486
+ return response;
5487
+ }
5488
+ async authenticate(_params) {
5489
+ }
5490
+ async closeSession() {
5491
+ this.logger.info("Closing Codex session", { sessionId: this.sessionId });
5492
+ this.session.settingsManager.dispose();
5493
+ try {
5494
+ this.codexProcess.kill();
5495
+ } catch (err) {
5496
+ this.logger.warn("Failed to kill codex-acp process", { error: err });
5497
+ }
5498
+ }
5499
+ };
5500
+
5501
+ // src/adapters/acp-connection.ts
5168
5502
  function createAcpConnection(config = {}) {
5169
5503
  const adapterType = config.adapter ?? "claude";
5170
5504
  if (adapterType === "codex") {
@@ -5205,7 +5539,7 @@ function createClaudeConnection(config) {
5205
5539
  hasLogWriter: !!logWriter
5206
5540
  });
5207
5541
  }
5208
- const agentStream = ndJsonStream(agentWritable, streams.agent.readable);
5542
+ const agentStream = ndJsonStream2(agentWritable, streams.agent.readable);
5209
5543
  let agent = null;
5210
5544
  const agentConnection = new AgentSideConnection((client) => {
5211
5545
  agent = new ClaudeAcpAgent(client, config.processCallbacks);
@@ -5237,214 +5571,63 @@ function createClaudeConnection(config) {
5237
5571
  function createCodexConnection(config) {
5238
5572
  const logger = config.logger?.child("CodexConnection") ?? new Logger({ debug: true, prefix: "[CodexConnection]" });
5239
5573
  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
5574
+ const streams = createBidirectionalStreams();
5575
+ let agentWritable = streams.agent.writable;
5576
+ let clientWritable = streams.client.writable;
5577
+ if (config.taskRunId && logWriter) {
5578
+ if (!logWriter.isRegistered(config.taskRunId)) {
5579
+ logWriter.register(config.taskRunId, {
5580
+ taskId: config.taskId ?? config.taskRunId,
5581
+ runId: config.taskRunId,
5582
+ deviceType: config.deviceType
5400
5583
  });
5401
5584
  }
5402
- clientWritable = createTappedWritableStream(clientWritable, {
5585
+ const taskRunId = config.taskRunId;
5586
+ agentWritable = createTappedWritableStream(streams.agent.writable, {
5403
5587
  onMessage: (line) => {
5404
- logWriter.appendRawLine(taskRunId2, line);
5588
+ logWriter.appendRawLine(taskRunId, line);
5589
+ },
5590
+ logger
5591
+ });
5592
+ clientWritable = createTappedWritableStream(streams.client.writable, {
5593
+ onMessage: (line) => {
5594
+ logWriter.appendRawLine(taskRunId, line);
5405
5595
  },
5406
5596
  logger
5407
5597
  });
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
5598
  } else {
5432
5599
  logger.info("Tapped streams NOT enabled for Codex", {
5433
5600
  hasTaskRunId: !!config.taskRunId,
5434
5601
  hasLogWriter: !!logWriter
5435
5602
  });
5436
5603
  }
5604
+ const agentStream = ndJsonStream2(agentWritable, streams.agent.readable);
5605
+ let agent = null;
5606
+ const agentConnection = new AgentSideConnection((client) => {
5607
+ agent = new CodexAcpAgent(client, {
5608
+ codexProcessOptions: config.codexOptions ?? {},
5609
+ processCallbacks: config.processCallbacks
5610
+ });
5611
+ logger.info(`Created ${agent.adapterName} agent`);
5612
+ return agent;
5613
+ }, agentStream);
5437
5614
  return {
5438
- agentConnection: void 0,
5615
+ agentConnection,
5439
5616
  clientStreams: {
5440
- readable: clientReadable,
5617
+ readable: streams.client.readable,
5441
5618
  writable: clientWritable
5442
5619
  },
5443
5620
  cleanup: async () => {
5444
5621
  logger.info("Cleaning up Codex connection");
5445
- codexProcess.kill();
5622
+ if (agent) {
5623
+ await agent.closeSession();
5624
+ }
5625
+ try {
5626
+ await streams.client.writable.close();
5627
+ } catch {
5628
+ }
5446
5629
  try {
5447
- await clientWritable.close();
5630
+ await streams.agent.writable.close();
5448
5631
  } catch {
5449
5632
  }
5450
5633
  }
@@ -5453,9 +5636,9 @@ function createCodexConnection(config) {
5453
5636
 
5454
5637
  // src/adapters/claude/session/jsonl-hydration.ts
5455
5638
  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";
5639
+ import * as fs6 from "fs/promises";
5640
+ import * as os6 from "os";
5641
+ import * as path8 from "path";
5459
5642
  var CHARS_PER_TOKEN = 4;
5460
5643
  var DEFAULT_MAX_TOKENS = 15e4;
5461
5644
  function estimateTurnTokens(turn) {
@@ -5818,8 +6001,8 @@ var Saga = class {
5818
6001
  };
5819
6002
 
5820
6003
  // ../git/dist/queries.js
5821
- import * as fs7 from "fs/promises";
5822
- import * as path9 from "path";
6004
+ import * as fs8 from "fs/promises";
6005
+ import * as path10 from "path";
5823
6006
 
5824
6007
  // ../../node_modules/simple-git/dist/esm/index.js
5825
6008
  var import_file_exists = __toESM(require_dist(), 1);
@@ -5858,8 +6041,8 @@ function pathspec(...paths) {
5858
6041
  cache.set(key, paths);
5859
6042
  return key;
5860
6043
  }
5861
- function isPathSpec(path12) {
5862
- return path12 instanceof String && cache.has(path12);
6044
+ function isPathSpec(path13) {
6045
+ return path13 instanceof String && cache.has(path13);
5863
6046
  }
5864
6047
  function toPaths(pathSpec) {
5865
6048
  return cache.get(pathSpec) || [];
@@ -5948,8 +6131,8 @@ function toLinesWithContent(input = "", trimmed2 = true, separator = "\n") {
5948
6131
  function forEachLineWithContent(input, callback) {
5949
6132
  return toLinesWithContent(input, true).map((line) => callback(line));
5950
6133
  }
5951
- function folderExists(path12) {
5952
- return (0, import_file_exists.exists)(path12, import_file_exists.FOLDER);
6134
+ function folderExists(path13) {
6135
+ return (0, import_file_exists.exists)(path13, import_file_exists.FOLDER);
5953
6136
  }
5954
6137
  function append(target, item) {
5955
6138
  if (Array.isArray(target)) {
@@ -6353,8 +6536,8 @@ function checkIsRepoRootTask() {
6353
6536
  commands,
6354
6537
  format: "utf-8",
6355
6538
  onError,
6356
- parser(path12) {
6357
- return /^\.(git)?$/.test(path12.trim());
6539
+ parser(path13) {
6540
+ return /^\.(git)?$/.test(path13.trim());
6358
6541
  }
6359
6542
  };
6360
6543
  }
@@ -6788,11 +6971,11 @@ function parseGrep(grep) {
6788
6971
  const paths = /* @__PURE__ */ new Set();
6789
6972
  const results = {};
6790
6973
  forEachLineWithContent(grep, (input) => {
6791
- const [path12, line, preview] = input.split(NULL);
6792
- paths.add(path12);
6793
- (results[path12] = results[path12] || []).push({
6974
+ const [path13, line, preview] = input.split(NULL);
6975
+ paths.add(path13);
6976
+ (results[path13] = results[path13] || []).push({
6794
6977
  line: asNumber(line),
6795
- path: path12,
6978
+ path: path13,
6796
6979
  preview
6797
6980
  });
6798
6981
  });
@@ -7557,14 +7740,14 @@ var init_hash_object = __esm({
7557
7740
  init_task();
7558
7741
  }
7559
7742
  });
7560
- function parseInit(bare, path12, text2) {
7743
+ function parseInit(bare, path13, text2) {
7561
7744
  const response = String(text2).trim();
7562
7745
  let result;
7563
7746
  if (result = initResponseRegex.exec(response)) {
7564
- return new InitSummary(bare, path12, false, result[1]);
7747
+ return new InitSummary(bare, path13, false, result[1]);
7565
7748
  }
7566
7749
  if (result = reInitResponseRegex.exec(response)) {
7567
- return new InitSummary(bare, path12, true, result[1]);
7750
+ return new InitSummary(bare, path13, true, result[1]);
7568
7751
  }
7569
7752
  let gitDir = "";
7570
7753
  const tokens = response.split(" ");
@@ -7575,7 +7758,7 @@ function parseInit(bare, path12, text2) {
7575
7758
  break;
7576
7759
  }
7577
7760
  }
7578
- return new InitSummary(bare, path12, /^re/i.test(response), gitDir);
7761
+ return new InitSummary(bare, path13, /^re/i.test(response), gitDir);
7579
7762
  }
7580
7763
  var InitSummary;
7581
7764
  var initResponseRegex;
@@ -7584,9 +7767,9 @@ var init_InitSummary = __esm({
7584
7767
  "src/lib/responses/InitSummary.ts"() {
7585
7768
  "use strict";
7586
7769
  InitSummary = class {
7587
- constructor(bare, path12, existing, gitDir) {
7770
+ constructor(bare, path13, existing, gitDir) {
7588
7771
  this.bare = bare;
7589
- this.path = path12;
7772
+ this.path = path13;
7590
7773
  this.existing = existing;
7591
7774
  this.gitDir = gitDir;
7592
7775
  }
@@ -7598,7 +7781,7 @@ var init_InitSummary = __esm({
7598
7781
  function hasBareCommand(command) {
7599
7782
  return command.includes(bareCommand);
7600
7783
  }
7601
- function initTask(bare = false, path12, customArgs) {
7784
+ function initTask(bare = false, path13, customArgs) {
7602
7785
  const commands = ["init", ...customArgs];
7603
7786
  if (bare && !hasBareCommand(commands)) {
7604
7787
  commands.splice(1, 0, bareCommand);
@@ -7607,7 +7790,7 @@ function initTask(bare = false, path12, customArgs) {
7607
7790
  commands,
7608
7791
  format: "utf-8",
7609
7792
  parser(text2) {
7610
- return parseInit(commands.includes("--bare"), path12, text2);
7793
+ return parseInit(commands.includes("--bare"), path13, text2);
7611
7794
  }
7612
7795
  };
7613
7796
  }
@@ -8423,12 +8606,12 @@ var init_FileStatusSummary = __esm({
8423
8606
  "use strict";
8424
8607
  fromPathRegex = /^(.+)\0(.+)$/;
8425
8608
  FileStatusSummary = class {
8426
- constructor(path12, index, working_dir) {
8427
- this.path = path12;
8609
+ constructor(path13, index, working_dir) {
8610
+ this.path = path13;
8428
8611
  this.index = index;
8429
8612
  this.working_dir = working_dir;
8430
8613
  if (index === "R" || working_dir === "R") {
8431
- const detail = fromPathRegex.exec(path12) || [null, path12, path12];
8614
+ const detail = fromPathRegex.exec(path13) || [null, path13, path13];
8432
8615
  this.from = detail[2] || "";
8433
8616
  this.path = detail[1] || "";
8434
8617
  }
@@ -8459,14 +8642,14 @@ function splitLine(result, lineStr) {
8459
8642
  default:
8460
8643
  return;
8461
8644
  }
8462
- function data(index, workingDir, path12) {
8645
+ function data(index, workingDir, path13) {
8463
8646
  const raw = `${index}${workingDir}`;
8464
8647
  const handler = parsers6.get(raw);
8465
8648
  if (handler) {
8466
- handler(result, path12);
8649
+ handler(result, path13);
8467
8650
  }
8468
8651
  if (raw !== "##" && raw !== "!!") {
8469
- result.files.push(new FileStatusSummary(path12, index, workingDir));
8652
+ result.files.push(new FileStatusSummary(path13, index, workingDir));
8470
8653
  }
8471
8654
  }
8472
8655
  }
@@ -8779,9 +8962,9 @@ var init_simple_git_api = __esm({
8779
8962
  next
8780
8963
  );
8781
8964
  }
8782
- hashObject(path12, write) {
8965
+ hashObject(path13, write) {
8783
8966
  return this._runTask(
8784
- hashObjectTask(path12, write === true),
8967
+ hashObjectTask(path13, write === true),
8785
8968
  trailingFunctionArgument(arguments)
8786
8969
  );
8787
8970
  }
@@ -9134,8 +9317,8 @@ var init_branch = __esm({
9134
9317
  }
9135
9318
  });
9136
9319
  function toPath(input) {
9137
- const path12 = input.trim().replace(/^["']|["']$/g, "");
9138
- return path12 && normalize2(path12);
9320
+ const path13 = input.trim().replace(/^["']|["']$/g, "");
9321
+ return path13 && normalize2(path13);
9139
9322
  }
9140
9323
  var parseCheckIgnore;
9141
9324
  var init_CheckIgnore = __esm({
@@ -9449,8 +9632,8 @@ __export(sub_module_exports, {
9449
9632
  subModuleTask: () => subModuleTask,
9450
9633
  updateSubModuleTask: () => updateSubModuleTask
9451
9634
  });
9452
- function addSubModuleTask(repo, path12) {
9453
- return subModuleTask(["add", repo, path12]);
9635
+ function addSubModuleTask(repo, path13) {
9636
+ return subModuleTask(["add", repo, path13]);
9454
9637
  }
9455
9638
  function initSubModuleTask(customArgs) {
9456
9639
  return subModuleTask(["init", ...customArgs]);
@@ -9780,8 +9963,8 @@ var require_git = __commonJS2({
9780
9963
  }
9781
9964
  return this._runTask(straightThroughStringTask2(command, this._trimmed), next);
9782
9965
  };
9783
- Git2.prototype.submoduleAdd = function(repo, path12, then) {
9784
- return this._runTask(addSubModuleTask2(repo, path12), trailingFunctionArgument2(arguments));
9966
+ Git2.prototype.submoduleAdd = function(repo, path13, then) {
9967
+ return this._runTask(addSubModuleTask2(repo, path13), trailingFunctionArgument2(arguments));
9785
9968
  };
9786
9969
  Git2.prototype.submoduleUpdate = function(args, then) {
9787
9970
  return this._runTask(
@@ -10382,22 +10565,22 @@ function createGitClient(baseDir, options) {
10382
10565
 
10383
10566
  // ../git/dist/lock-detector.js
10384
10567
  import { execFile } from "child_process";
10385
- import fs6 from "fs/promises";
10386
- import path8 from "path";
10568
+ import fs7 from "fs/promises";
10569
+ import path9 from "path";
10387
10570
  import { promisify } from "util";
10388
10571
  var execFileAsync = promisify(execFile);
10389
10572
  async function getIndexLockPath(repoPath) {
10390
10573
  try {
10391
10574
  const { stdout } = await execFileAsync("git", ["rev-parse", "--git-path", "index.lock"], { cwd: repoPath });
10392
- return path8.resolve(repoPath, stdout.trim());
10575
+ return path9.resolve(repoPath, stdout.trim());
10393
10576
  } catch {
10394
- return path8.join(repoPath, ".git", "index.lock");
10577
+ return path9.join(repoPath, ".git", "index.lock");
10395
10578
  }
10396
10579
  }
10397
10580
  async function getLockInfo(repoPath) {
10398
10581
  const lockPath = await getIndexLockPath(repoPath);
10399
10582
  try {
10400
- const stat = await fs6.stat(lockPath);
10583
+ const stat = await fs7.stat(lockPath);
10401
10584
  return {
10402
10585
  path: lockPath,
10403
10586
  ageMs: Date.now() - stat.mtimeMs
@@ -10408,7 +10591,7 @@ async function getLockInfo(repoPath) {
10408
10591
  }
10409
10592
  async function removeLock(repoPath) {
10410
10593
  const lockPath = await getIndexLockPath(repoPath);
10411
- await fs6.rm(lockPath, { force: true });
10594
+ await fs7.rm(lockPath, { force: true });
10412
10595
  }
10413
10596
  async function isLocked(repoPath) {
10414
10597
  return await getLockInfo(repoPath) !== null;
@@ -10589,12 +10772,12 @@ async function getHeadSha(baseDir, options) {
10589
10772
 
10590
10773
  // src/sagas/apply-snapshot-saga.ts
10591
10774
  import { mkdir as mkdir4, rm as rm3, writeFile as writeFile4 } from "fs/promises";
10592
- import { join as join7 } from "path";
10775
+ import { join as join8 } from "path";
10593
10776
 
10594
10777
  // ../git/dist/sagas/tree.js
10595
10778
  import { existsSync as existsSync4 } from "fs";
10596
- import * as fs8 from "fs/promises";
10597
- import * as path10 from "path";
10779
+ import * as fs9 from "fs/promises";
10780
+ import * as path11 from "path";
10598
10781
  import * as tar from "tar";
10599
10782
 
10600
10783
  // ../git/dist/git-saga.js
@@ -10621,14 +10804,14 @@ var CaptureTreeSaga = class extends GitSaga {
10621
10804
  tempIndexPath = null;
10622
10805
  async executeGitOperations(input) {
10623
10806
  const { baseDir, lastTreeHash, archivePath, signal } = input;
10624
- const tmpDir = path10.join(baseDir, ".git", "posthog-code-tmp");
10807
+ const tmpDir = path11.join(baseDir, ".git", "posthog-code-tmp");
10625
10808
  await this.step({
10626
10809
  name: "create_tmp_dir",
10627
- execute: () => fs8.mkdir(tmpDir, { recursive: true }),
10810
+ execute: () => fs9.mkdir(tmpDir, { recursive: true }),
10628
10811
  rollback: async () => {
10629
10812
  }
10630
10813
  });
10631
- this.tempIndexPath = path10.join(tmpDir, `index-${Date.now()}`);
10814
+ this.tempIndexPath = path11.join(tmpDir, `index-${Date.now()}`);
10632
10815
  const tempIndexGit = this.git.env({
10633
10816
  ...process.env,
10634
10817
  GIT_INDEX_FILE: this.tempIndexPath
@@ -10638,7 +10821,7 @@ var CaptureTreeSaga = class extends GitSaga {
10638
10821
  execute: () => tempIndexGit.raw(["read-tree", "HEAD"]),
10639
10822
  rollback: async () => {
10640
10823
  if (this.tempIndexPath) {
10641
- await fs8.rm(this.tempIndexPath, { force: true }).catch(() => {
10824
+ await fs9.rm(this.tempIndexPath, { force: true }).catch(() => {
10642
10825
  });
10643
10826
  }
10644
10827
  }
@@ -10647,7 +10830,7 @@ var CaptureTreeSaga = class extends GitSaga {
10647
10830
  const treeHash = await this.readOnlyStep("write_tree", () => tempIndexGit.raw(["write-tree"]));
10648
10831
  if (lastTreeHash && treeHash === lastTreeHash) {
10649
10832
  this.log.debug("No changes since last capture", { treeHash });
10650
- await fs8.rm(this.tempIndexPath, { force: true }).catch(() => {
10833
+ await fs9.rm(this.tempIndexPath, { force: true }).catch(() => {
10651
10834
  });
10652
10835
  return { snapshot: null, changed: false };
10653
10836
  }
@@ -10659,7 +10842,7 @@ var CaptureTreeSaga = class extends GitSaga {
10659
10842
  }
10660
10843
  });
10661
10844
  const changes = await this.readOnlyStep("get_changes", () => this.getChanges(this.git, baseCommit, treeHash));
10662
- await fs8.rm(this.tempIndexPath, { force: true }).catch(() => {
10845
+ await fs9.rm(this.tempIndexPath, { force: true }).catch(() => {
10663
10846
  });
10664
10847
  const snapshot = {
10665
10848
  treeHash,
@@ -10683,15 +10866,15 @@ var CaptureTreeSaga = class extends GitSaga {
10683
10866
  if (filesToArchive.length === 0) {
10684
10867
  return void 0;
10685
10868
  }
10686
- const existingFiles = filesToArchive.filter((f) => existsSync4(path10.join(baseDir, f)));
10869
+ const existingFiles = filesToArchive.filter((f) => existsSync4(path11.join(baseDir, f)));
10687
10870
  if (existingFiles.length === 0) {
10688
10871
  return void 0;
10689
10872
  }
10690
10873
  await this.step({
10691
10874
  name: "create_archive",
10692
10875
  execute: async () => {
10693
- const archiveDir = path10.dirname(archivePath);
10694
- await fs8.mkdir(archiveDir, { recursive: true });
10876
+ const archiveDir = path11.dirname(archivePath);
10877
+ await fs9.mkdir(archiveDir, { recursive: true });
10695
10878
  await tar.create({
10696
10879
  gzip: true,
10697
10880
  file: archivePath,
@@ -10699,7 +10882,7 @@ var CaptureTreeSaga = class extends GitSaga {
10699
10882
  }, existingFiles);
10700
10883
  },
10701
10884
  rollback: async () => {
10702
- await fs8.rm(archivePath, { force: true }).catch(() => {
10885
+ await fs9.rm(archivePath, { force: true }).catch(() => {
10703
10886
  });
10704
10887
  }
10705
10888
  });
@@ -10799,9 +10982,9 @@ var ApplyTreeSaga = class extends GitSaga {
10799
10982
  const filesToExtract = changes.filter((c) => c.status !== "D").map((c) => c.path);
10800
10983
  await this.readOnlyStep("backup_existing_files", async () => {
10801
10984
  for (const filePath of filesToExtract) {
10802
- const fullPath = path10.join(baseDir, filePath);
10985
+ const fullPath = path11.join(baseDir, filePath);
10803
10986
  try {
10804
- const content = await fs8.readFile(fullPath);
10987
+ const content = await fs9.readFile(fullPath);
10805
10988
  this.fileBackups.set(filePath, content);
10806
10989
  } catch {
10807
10990
  }
@@ -10818,16 +11001,16 @@ var ApplyTreeSaga = class extends GitSaga {
10818
11001
  },
10819
11002
  rollback: async () => {
10820
11003
  for (const filePath of this.extractedFiles) {
10821
- const fullPath = path10.join(baseDir, filePath);
11004
+ const fullPath = path11.join(baseDir, filePath);
10822
11005
  const backup = this.fileBackups.get(filePath);
10823
11006
  if (backup) {
10824
- const dir = path10.dirname(fullPath);
10825
- await fs8.mkdir(dir, { recursive: true }).catch(() => {
11007
+ const dir = path11.dirname(fullPath);
11008
+ await fs9.mkdir(dir, { recursive: true }).catch(() => {
10826
11009
  });
10827
- await fs8.writeFile(fullPath, backup).catch(() => {
11010
+ await fs9.writeFile(fullPath, backup).catch(() => {
10828
11011
  });
10829
11012
  } else {
10830
- await fs8.rm(fullPath, { force: true }).catch(() => {
11013
+ await fs9.rm(fullPath, { force: true }).catch(() => {
10831
11014
  });
10832
11015
  }
10833
11016
  }
@@ -10835,10 +11018,10 @@ var ApplyTreeSaga = class extends GitSaga {
10835
11018
  });
10836
11019
  }
10837
11020
  for (const change of changes.filter((c) => c.status === "D")) {
10838
- const fullPath = path10.join(baseDir, change.path);
11021
+ const fullPath = path11.join(baseDir, change.path);
10839
11022
  const backupContent = await this.readOnlyStep(`backup_${change.path}`, async () => {
10840
11023
  try {
10841
- return await fs8.readFile(fullPath);
11024
+ return await fs9.readFile(fullPath);
10842
11025
  } catch {
10843
11026
  return null;
10844
11027
  }
@@ -10846,15 +11029,15 @@ var ApplyTreeSaga = class extends GitSaga {
10846
11029
  await this.step({
10847
11030
  name: `delete_${change.path}`,
10848
11031
  execute: async () => {
10849
- await fs8.rm(fullPath, { force: true });
11032
+ await fs9.rm(fullPath, { force: true });
10850
11033
  this.log.debug(`Deleted file: ${change.path}`);
10851
11034
  },
10852
11035
  rollback: async () => {
10853
11036
  if (backupContent) {
10854
- const dir = path10.dirname(fullPath);
10855
- await fs8.mkdir(dir, { recursive: true }).catch(() => {
11037
+ const dir = path11.dirname(fullPath);
11038
+ await fs9.mkdir(dir, { recursive: true }).catch(() => {
10856
11039
  });
10857
- await fs8.writeFile(fullPath, backupContent).catch(() => {
11040
+ await fs9.writeFile(fullPath, backupContent).catch(() => {
10858
11041
  });
10859
11042
  }
10860
11043
  }
@@ -10877,7 +11060,7 @@ var ApplySnapshotSaga = class extends Saga {
10877
11060
  archivePath = null;
10878
11061
  async execute(input) {
10879
11062
  const { snapshot, repositoryPath, apiClient, taskId, runId } = input;
10880
- const tmpDir = join7(repositoryPath, ".posthog", "tmp");
11063
+ const tmpDir = join8(repositoryPath, ".posthog", "tmp");
10881
11064
  if (!snapshot.archiveUrl) {
10882
11065
  throw new Error("Cannot apply snapshot: no archive URL");
10883
11066
  }
@@ -10888,7 +11071,7 @@ var ApplySnapshotSaga = class extends Saga {
10888
11071
  rollback: async () => {
10889
11072
  }
10890
11073
  });
10891
- const archivePath = join7(tmpDir, `${snapshot.treeHash}.tar.gz`);
11074
+ const archivePath = join8(tmpDir, `${snapshot.treeHash}.tar.gz`);
10892
11075
  this.archivePath = archivePath;
10893
11076
  await this.step({
10894
11077
  name: "download_archive",
@@ -10937,7 +11120,7 @@ var ApplySnapshotSaga = class extends Saga {
10937
11120
  // src/sagas/capture-tree-saga.ts
10938
11121
  import { existsSync as existsSync5 } from "fs";
10939
11122
  import { readFile as readFile3, rm as rm4 } from "fs/promises";
10940
- import { join as join8 } from "path";
11123
+ import { join as join9 } from "path";
10941
11124
  var CaptureTreeSaga2 = class extends Saga {
10942
11125
  sagaName = "CaptureTreeSaga";
10943
11126
  async execute(input) {
@@ -10949,14 +11132,14 @@ var CaptureTreeSaga2 = class extends Saga {
10949
11132
  taskId,
10950
11133
  runId
10951
11134
  } = input;
10952
- const tmpDir = join8(repositoryPath, ".posthog", "tmp");
10953
- if (existsSync5(join8(repositoryPath, ".gitmodules"))) {
11135
+ const tmpDir = join9(repositoryPath, ".posthog", "tmp");
11136
+ if (existsSync5(join9(repositoryPath, ".gitmodules"))) {
10954
11137
  this.log.warn(
10955
11138
  "Repository has submodules - snapshot may not capture submodule state"
10956
11139
  );
10957
11140
  }
10958
11141
  const shouldArchive = !!apiClient;
10959
- const archivePath = shouldArchive ? join8(tmpDir, `tree-${Date.now()}.tar.gz`) : void 0;
11142
+ const archivePath = shouldArchive ? join9(tmpDir, `tree-${Date.now()}.tar.gz`) : void 0;
10960
11143
  const gitCaptureSaga = new CaptureTreeSaga(this.log);
10961
11144
  const captureResult = await gitCaptureSaga.run({
10962
11145
  baseDir: repositoryPath,
@@ -11415,9 +11598,9 @@ async function resumeFromLog(config) {
11415
11598
  }
11416
11599
 
11417
11600
  // src/session-log-writer.ts
11418
- import fs9 from "fs";
11601
+ import fs10 from "fs";
11419
11602
  import fsp from "fs/promises";
11420
- import path11 from "path";
11603
+ import path12 from "path";
11421
11604
  var SessionLogWriter = class _SessionLogWriter {
11422
11605
  static FLUSH_DEBOUNCE_MS = 500;
11423
11606
  static FLUSH_MAX_INTERVAL_MS = 5e3;
@@ -11457,13 +11640,13 @@ var SessionLogWriter = class _SessionLogWriter {
11457
11640
  this.sessions.set(sessionId, { context, currentTurnMessages: [] });
11458
11641
  this.lastFlushAttemptTime.set(sessionId, Date.now());
11459
11642
  if (this.localCachePath) {
11460
- const sessionDir = path11.join(
11643
+ const sessionDir = path12.join(
11461
11644
  this.localCachePath,
11462
11645
  "sessions",
11463
11646
  context.runId
11464
11647
  );
11465
11648
  try {
11466
- fs9.mkdirSync(sessionDir, { recursive: true });
11649
+ fs10.mkdirSync(sessionDir, { recursive: true });
11467
11650
  } catch (error) {
11468
11651
  this.logger.warn("Failed to create local cache directory", {
11469
11652
  sessionDir,
@@ -11715,14 +11898,14 @@ var SessionLogWriter = class _SessionLogWriter {
11715
11898
  if (!this.localCachePath) return;
11716
11899
  const session = this.sessions.get(sessionId);
11717
11900
  if (!session) return;
11718
- const logPath = path11.join(
11901
+ const logPath = path12.join(
11719
11902
  this.localCachePath,
11720
11903
  "sessions",
11721
11904
  session.context.runId,
11722
11905
  "logs.ndjson"
11723
11906
  );
11724
11907
  try {
11725
- fs9.appendFileSync(logPath, `${JSON.stringify(entry)}
11908
+ fs10.appendFileSync(logPath, `${JSON.stringify(entry)}
11726
11909
  `);
11727
11910
  } catch (error) {
11728
11911
  this.logger.warn("Failed to write to local cache", {
@@ -11734,13 +11917,13 @@ var SessionLogWriter = class _SessionLogWriter {
11734
11917
  }
11735
11918
  }
11736
11919
  static async cleanupOldSessions(localCachePath) {
11737
- const sessionsDir = path11.join(localCachePath, "sessions");
11920
+ const sessionsDir = path12.join(localCachePath, "sessions");
11738
11921
  let deleted = 0;
11739
11922
  try {
11740
11923
  const entries = await fsp.readdir(sessionsDir);
11741
11924
  const now = Date.now();
11742
11925
  for (const entry of entries) {
11743
- const entryPath = path11.join(sessionsDir, entry);
11926
+ const entryPath = path12.join(sessionsDir, entry);
11744
11927
  try {
11745
11928
  const stats = await fsp.stat(entryPath);
11746
11929
  if (stats.isDirectory() && now - stats.birthtimeMs > _SessionLogWriter.SESSIONS_MAX_AGE_MS) {
@@ -12388,8 +12571,8 @@ You MUST NOT create a new branch, close the existing PR, or create a new PR.`
12388
12571
  onAcpMessage,
12389
12572
  this.logger
12390
12573
  );
12391
- const clientStream = ndJsonStream2(tappedWritable, tappedReadable);
12392
- const clientConnection = new ClientSideConnection(
12574
+ const clientStream = ndJsonStream3(tappedWritable, tappedReadable);
12575
+ const clientConnection = new ClientSideConnection2(
12393
12576
  () => this.createCloudClient(payload),
12394
12577
  clientStream
12395
12578
  );