@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.
- package/dist/agent.js +649 -425
- package/dist/agent.js.map +1 -1
- package/dist/posthog-api.js +1 -1
- package/dist/posthog-api.js.map +1 -1
- package/dist/server/agent-server.js +620 -397
- package/dist/server/agent-server.js.map +1 -1
- package/dist/server/bin.cjs +597 -377
- package/dist/server/bin.cjs.map +1 -1
- package/dist/types.d.ts +1 -0
- package/package.json +1 -1
- package/src/adapters/acp-connection.ts +53 -334
- package/src/adapters/base-acp-agent.ts +13 -2
- package/src/adapters/codex/codex-agent.ts +386 -0
- package/src/adapters/codex/codex-client.ts +168 -0
- package/src/adapters/codex/session-state.ts +65 -0
- package/src/adapters/codex/settings.ts +127 -0
- package/src/adapters/codex/spawn.ts +8 -0
- package/src/agent.ts +1 -0
- package/src/types.ts +1 -0
|
@@ -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
|
|
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 =
|
|
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(
|
|
813
|
-
log(`checking %s`,
|
|
812
|
+
function check(path13, isFile, isDirectory) {
|
|
813
|
+
log(`checking %s`, path13);
|
|
814
814
|
try {
|
|
815
|
-
const stat = fs_1.statSync(
|
|
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(
|
|
836
|
-
return check(
|
|
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
|
|
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.
|
|
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(
|
|
1603
|
-
this.items.push({ type: "diff", path:
|
|
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/
|
|
5111
|
-
|
|
5112
|
-
|
|
5113
|
-
|
|
5114
|
-
|
|
5115
|
-
|
|
5116
|
-
|
|
5117
|
-
|
|
5118
|
-
|
|
5119
|
-
|
|
5120
|
-
|
|
5121
|
-
|
|
5122
|
-
|
|
5123
|
-
|
|
5124
|
-
const
|
|
5125
|
-
|
|
5126
|
-
|
|
5127
|
-
|
|
5128
|
-
|
|
5129
|
-
|
|
5130
|
-
|
|
5131
|
-
|
|
5132
|
-
|
|
5133
|
-
|
|
5134
|
-
|
|
5135
|
-
|
|
5136
|
-
|
|
5137
|
-
|
|
5138
|
-
|
|
5139
|
-
|
|
5140
|
-
|
|
5141
|
-
|
|
5142
|
-
|
|
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
|
-
...
|
|
5145
|
-
|
|
5146
|
-
|
|
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
|
-
|
|
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
|
-
|
|
5155
|
-
|
|
5156
|
-
|
|
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
|
-
|
|
5162
|
-
|
|
5163
|
-
|
|
5164
|
-
|
|
5165
|
-
|
|
5166
|
-
|
|
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 =
|
|
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
|
|
5241
|
-
|
|
5242
|
-
|
|
5243
|
-
|
|
5244
|
-
|
|
5245
|
-
|
|
5246
|
-
|
|
5247
|
-
|
|
5248
|
-
|
|
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
|
-
|
|
5625
|
+
const taskRunId = config.taskRunId;
|
|
5626
|
+
agentWritable = createTappedWritableStream(streams.agent.writable, {
|
|
5403
5627
|
onMessage: (line) => {
|
|
5404
|
-
logWriter.appendRawLine(
|
|
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
|
|
5655
|
+
agentConnection,
|
|
5439
5656
|
clientStreams: {
|
|
5440
|
-
readable:
|
|
5657
|
+
readable: streams.client.readable,
|
|
5441
5658
|
writable: clientWritable
|
|
5442
5659
|
},
|
|
5443
5660
|
cleanup: async () => {
|
|
5444
5661
|
logger.info("Cleaning up Codex connection");
|
|
5445
|
-
|
|
5662
|
+
if (agent) {
|
|
5663
|
+
await agent.closeSession();
|
|
5664
|
+
}
|
|
5665
|
+
try {
|
|
5666
|
+
await streams.client.writable.close();
|
|
5667
|
+
} catch {
|
|
5668
|
+
}
|
|
5446
5669
|
try {
|
|
5447
|
-
await
|
|
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
|
|
5457
|
-
import * as
|
|
5458
|
-
import * as
|
|
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
|
|
5822
|
-
import * as
|
|
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(
|
|
5862
|
-
return
|
|
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(
|
|
5952
|
-
return (0, import_file_exists.exists)(
|
|
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(
|
|
6357
|
-
return /^\.(git)?$/.test(
|
|
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 [
|
|
6792
|
-
paths.add(
|
|
6793
|
-
(results[
|
|
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:
|
|
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,
|
|
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,
|
|
7787
|
+
return new InitSummary(bare, path13, false, result[1]);
|
|
7565
7788
|
}
|
|
7566
7789
|
if (result = reInitResponseRegex.exec(response)) {
|
|
7567
|
-
return new InitSummary(bare,
|
|
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,
|
|
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,
|
|
7810
|
+
constructor(bare, path13, existing, gitDir) {
|
|
7588
7811
|
this.bare = bare;
|
|
7589
|
-
this.path =
|
|
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,
|
|
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"),
|
|
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(
|
|
8427
|
-
this.path =
|
|
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(
|
|
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,
|
|
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,
|
|
8689
|
+
handler(result, path13);
|
|
8467
8690
|
}
|
|
8468
8691
|
if (raw !== "##" && raw !== "!!") {
|
|
8469
|
-
result.files.push(new FileStatusSummary(
|
|
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(
|
|
9005
|
+
hashObject(path13, write) {
|
|
8783
9006
|
return this._runTask(
|
|
8784
|
-
hashObjectTask(
|
|
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
|
|
9138
|
-
return
|
|
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,
|
|
9453
|
-
return subModuleTask(["add", repo,
|
|
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,
|
|
9784
|
-
return this._runTask(addSubModuleTask2(repo,
|
|
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
|
|
10386
|
-
import
|
|
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
|
|
10615
|
+
return path9.resolve(repoPath, stdout.trim());
|
|
10393
10616
|
} catch {
|
|
10394
|
-
return
|
|
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
|
|
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
|
|
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
|
|
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
|
|
10597
|
-
import * as
|
|
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 =
|
|
10847
|
+
const tmpDir = path11.join(baseDir, ".git", "posthog-code-tmp");
|
|
10625
10848
|
await this.step({
|
|
10626
10849
|
name: "create_tmp_dir",
|
|
10627
|
-
execute: () =>
|
|
10850
|
+
execute: () => fs9.mkdir(tmpDir, { recursive: true }),
|
|
10628
10851
|
rollback: async () => {
|
|
10629
10852
|
}
|
|
10630
10853
|
});
|
|
10631
|
-
this.tempIndexPath =
|
|
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
|
|
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
|
|
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
|
|
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(
|
|
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 =
|
|
10694
|
-
await
|
|
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
|
|
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 =
|
|
11025
|
+
const fullPath = path11.join(baseDir, filePath);
|
|
10803
11026
|
try {
|
|
10804
|
-
const content = await
|
|
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 =
|
|
11044
|
+
const fullPath = path11.join(baseDir, filePath);
|
|
10822
11045
|
const backup = this.fileBackups.get(filePath);
|
|
10823
11046
|
if (backup) {
|
|
10824
|
-
const dir =
|
|
10825
|
-
await
|
|
11047
|
+
const dir = path11.dirname(fullPath);
|
|
11048
|
+
await fs9.mkdir(dir, { recursive: true }).catch(() => {
|
|
10826
11049
|
});
|
|
10827
|
-
await
|
|
11050
|
+
await fs9.writeFile(fullPath, backup).catch(() => {
|
|
10828
11051
|
});
|
|
10829
11052
|
} else {
|
|
10830
|
-
await
|
|
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 =
|
|
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
|
|
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
|
|
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 =
|
|
10855
|
-
await
|
|
11077
|
+
const dir = path11.dirname(fullPath);
|
|
11078
|
+
await fs9.mkdir(dir, { recursive: true }).catch(() => {
|
|
10856
11079
|
});
|
|
10857
|
-
await
|
|
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 =
|
|
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 =
|
|
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
|
|
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 =
|
|
10953
|
-
if (existsSync5(
|
|
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 ?
|
|
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
|
|
11641
|
+
import fs10 from "fs";
|
|
11419
11642
|
import fsp from "fs/promises";
|
|
11420
|
-
import
|
|
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 =
|
|
11683
|
+
const sessionDir = path12.join(
|
|
11461
11684
|
this.localCachePath,
|
|
11462
11685
|
"sessions",
|
|
11463
11686
|
context.runId
|
|
11464
11687
|
);
|
|
11465
11688
|
try {
|
|
11466
|
-
|
|
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 =
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
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 =
|
|
12392
|
-
const clientConnection = new
|
|
12614
|
+
const clientStream = ndJsonStream3(tappedWritable, tappedReadable);
|
|
12615
|
+
const clientConnection = new ClientSideConnection2(
|
|
12393
12616
|
() => this.createCloudClient(payload),
|
|
12394
12617
|
clientStream
|
|
12395
12618
|
);
|