@posthog/agent 2.3.508 → 2.3.513
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 +234 -110
- package/dist/agent.js.map +1 -1
- package/dist/handoff-checkpoint.js +212 -18
- package/dist/handoff-checkpoint.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 +463 -145
- package/dist/server/agent-server.js.map +1 -1
- package/dist/server/bin.cjs +445 -127
- package/dist/server/bin.cjs.map +1 -1
- package/package.json +2 -2
- package/src/adapters/claude/claude-agent.ts +10 -0
- package/src/adapters/claude/conversion/sdk-to-acp.ts +67 -6
- package/src/adapters/claude/session/mcp-config.test.ts +112 -0
- package/src/adapters/claude/session/mcp-config.ts +45 -0
- package/src/adapters/claude/session/options.ts +4 -0
- package/src/adapters/claude/types.ts +10 -0
- package/src/utils/partial-json.test.ts +72 -0
- package/src/utils/partial-json.ts +68 -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"(exports2, module2) {
|
|
515
515
|
"use strict";
|
|
516
|
-
var
|
|
516
|
+
var os8 = __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 = os8.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(path17, isFile2, isDirectory) {
|
|
813
|
+
log(`checking %s`, path17);
|
|
814
814
|
try {
|
|
815
|
-
const stat4 = fs_1.statSync(
|
|
815
|
+
const stat4 = fs_1.statSync(path17);
|
|
816
816
|
if (stat4.isFile() && isFile2) {
|
|
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(path17, type = exports2.READABLE) {
|
|
836
|
+
return check(path17, (type & exports2.FILE) > 0, (type & exports2.FOLDER) > 0);
|
|
837
837
|
}
|
|
838
838
|
exports2.exists = exists2;
|
|
839
839
|
exports2.FILE = 1;
|
|
@@ -929,11 +929,11 @@ var require_tree_sitter = __commonJS({
|
|
|
929
929
|
throw toThrow;
|
|
930
930
|
};
|
|
931
931
|
var scriptDirectory = "";
|
|
932
|
-
function locateFile(
|
|
932
|
+
function locateFile(path17) {
|
|
933
933
|
if (Module["locateFile"]) {
|
|
934
|
-
return Module["locateFile"](
|
|
934
|
+
return Module["locateFile"](path17, scriptDirectory);
|
|
935
935
|
}
|
|
936
|
-
return scriptDirectory +
|
|
936
|
+
return scriptDirectory + path17;
|
|
937
937
|
}
|
|
938
938
|
var readAsync, readBinary;
|
|
939
939
|
if (ENVIRONMENT_IS_NODE) {
|
|
@@ -3454,8 +3454,8 @@ var require_tree_sitter = __commonJS({
|
|
|
3454
3454
|
} else {
|
|
3455
3455
|
const url = input;
|
|
3456
3456
|
if (typeof process !== "undefined" && process.versions && process.versions.node) {
|
|
3457
|
-
const
|
|
3458
|
-
bytes = Promise.resolve(
|
|
3457
|
+
const fs14 = __require("fs");
|
|
3458
|
+
bytes = Promise.resolve(fs14.readFileSync(url));
|
|
3459
3459
|
} else {
|
|
3460
3460
|
bytes = fetch(url).then((response) => response.arrayBuffer().then((buffer) => {
|
|
3461
3461
|
if (response.ok) {
|
|
@@ -3785,7 +3785,7 @@ ${JSON.stringify(symbolNames, null, 2)}`);
|
|
|
3785
3785
|
|
|
3786
3786
|
// src/server/agent-server.ts
|
|
3787
3787
|
import { mkdir as mkdir4, writeFile as writeFile4 } from "fs/promises";
|
|
3788
|
-
import { basename as basename2, join as
|
|
3788
|
+
import { basename as basename2, join as join12 } from "path";
|
|
3789
3789
|
import { pathToFileURL } from "url";
|
|
3790
3790
|
import {
|
|
3791
3791
|
ClientSideConnection as ClientSideConnection2,
|
|
@@ -3835,8 +3835,8 @@ function pathspec(...paths) {
|
|
|
3835
3835
|
cache.set(key, paths);
|
|
3836
3836
|
return key;
|
|
3837
3837
|
}
|
|
3838
|
-
function isPathSpec(
|
|
3839
|
-
return
|
|
3838
|
+
function isPathSpec(path17) {
|
|
3839
|
+
return path17 instanceof String && cache.has(path17);
|
|
3840
3840
|
}
|
|
3841
3841
|
function toPaths(pathSpec) {
|
|
3842
3842
|
return cache.get(pathSpec) || [];
|
|
@@ -3925,8 +3925,8 @@ function toLinesWithContent(input = "", trimmed2 = true, separator = "\n") {
|
|
|
3925
3925
|
function forEachLineWithContent(input, callback) {
|
|
3926
3926
|
return toLinesWithContent(input, true).map((line) => callback(line));
|
|
3927
3927
|
}
|
|
3928
|
-
function folderExists(
|
|
3929
|
-
return (0, import_file_exists.exists)(
|
|
3928
|
+
function folderExists(path17) {
|
|
3929
|
+
return (0, import_file_exists.exists)(path17, import_file_exists.FOLDER);
|
|
3930
3930
|
}
|
|
3931
3931
|
function append(target, item) {
|
|
3932
3932
|
if (Array.isArray(target)) {
|
|
@@ -4330,8 +4330,8 @@ function checkIsRepoRootTask() {
|
|
|
4330
4330
|
commands,
|
|
4331
4331
|
format: "utf-8",
|
|
4332
4332
|
onError,
|
|
4333
|
-
parser(
|
|
4334
|
-
return /^\.(git)?$/.test(
|
|
4333
|
+
parser(path17) {
|
|
4334
|
+
return /^\.(git)?$/.test(path17.trim());
|
|
4335
4335
|
}
|
|
4336
4336
|
};
|
|
4337
4337
|
}
|
|
@@ -4765,11 +4765,11 @@ function parseGrep(grep) {
|
|
|
4765
4765
|
const paths = /* @__PURE__ */ new Set();
|
|
4766
4766
|
const results = {};
|
|
4767
4767
|
forEachLineWithContent(grep, (input) => {
|
|
4768
|
-
const [
|
|
4769
|
-
paths.add(
|
|
4770
|
-
(results[
|
|
4768
|
+
const [path17, line, preview] = input.split(NULL);
|
|
4769
|
+
paths.add(path17);
|
|
4770
|
+
(results[path17] = results[path17] || []).push({
|
|
4771
4771
|
line: asNumber(line),
|
|
4772
|
-
path:
|
|
4772
|
+
path: path17,
|
|
4773
4773
|
preview
|
|
4774
4774
|
});
|
|
4775
4775
|
});
|
|
@@ -5534,14 +5534,14 @@ var init_hash_object = __esm({
|
|
|
5534
5534
|
init_task();
|
|
5535
5535
|
}
|
|
5536
5536
|
});
|
|
5537
|
-
function parseInit(bare,
|
|
5537
|
+
function parseInit(bare, path17, text2) {
|
|
5538
5538
|
const response = String(text2).trim();
|
|
5539
5539
|
let result;
|
|
5540
5540
|
if (result = initResponseRegex.exec(response)) {
|
|
5541
|
-
return new InitSummary(bare,
|
|
5541
|
+
return new InitSummary(bare, path17, false, result[1]);
|
|
5542
5542
|
}
|
|
5543
5543
|
if (result = reInitResponseRegex.exec(response)) {
|
|
5544
|
-
return new InitSummary(bare,
|
|
5544
|
+
return new InitSummary(bare, path17, true, result[1]);
|
|
5545
5545
|
}
|
|
5546
5546
|
let gitDir = "";
|
|
5547
5547
|
const tokens = response.split(" ");
|
|
@@ -5552,7 +5552,7 @@ function parseInit(bare, path16, text2) {
|
|
|
5552
5552
|
break;
|
|
5553
5553
|
}
|
|
5554
5554
|
}
|
|
5555
|
-
return new InitSummary(bare,
|
|
5555
|
+
return new InitSummary(bare, path17, /^re/i.test(response), gitDir);
|
|
5556
5556
|
}
|
|
5557
5557
|
var InitSummary;
|
|
5558
5558
|
var initResponseRegex;
|
|
@@ -5561,9 +5561,9 @@ var init_InitSummary = __esm({
|
|
|
5561
5561
|
"src/lib/responses/InitSummary.ts"() {
|
|
5562
5562
|
"use strict";
|
|
5563
5563
|
InitSummary = class {
|
|
5564
|
-
constructor(bare,
|
|
5564
|
+
constructor(bare, path17, existing, gitDir) {
|
|
5565
5565
|
this.bare = bare;
|
|
5566
|
-
this.path =
|
|
5566
|
+
this.path = path17;
|
|
5567
5567
|
this.existing = existing;
|
|
5568
5568
|
this.gitDir = gitDir;
|
|
5569
5569
|
}
|
|
@@ -5575,7 +5575,7 @@ var init_InitSummary = __esm({
|
|
|
5575
5575
|
function hasBareCommand(command) {
|
|
5576
5576
|
return command.includes(bareCommand);
|
|
5577
5577
|
}
|
|
5578
|
-
function initTask(bare = false,
|
|
5578
|
+
function initTask(bare = false, path17, customArgs) {
|
|
5579
5579
|
const commands = ["init", ...customArgs];
|
|
5580
5580
|
if (bare && !hasBareCommand(commands)) {
|
|
5581
5581
|
commands.splice(1, 0, bareCommand);
|
|
@@ -5584,7 +5584,7 @@ function initTask(bare = false, path16, customArgs) {
|
|
|
5584
5584
|
commands,
|
|
5585
5585
|
format: "utf-8",
|
|
5586
5586
|
parser(text2) {
|
|
5587
|
-
return parseInit(commands.includes("--bare"),
|
|
5587
|
+
return parseInit(commands.includes("--bare"), path17, text2);
|
|
5588
5588
|
}
|
|
5589
5589
|
};
|
|
5590
5590
|
}
|
|
@@ -6400,12 +6400,12 @@ var init_FileStatusSummary = __esm({
|
|
|
6400
6400
|
"use strict";
|
|
6401
6401
|
fromPathRegex = /^(.+)\0(.+)$/;
|
|
6402
6402
|
FileStatusSummary = class {
|
|
6403
|
-
constructor(
|
|
6404
|
-
this.path =
|
|
6403
|
+
constructor(path17, index, working_dir) {
|
|
6404
|
+
this.path = path17;
|
|
6405
6405
|
this.index = index;
|
|
6406
6406
|
this.working_dir = working_dir;
|
|
6407
6407
|
if (index === "R" || working_dir === "R") {
|
|
6408
|
-
const detail = fromPathRegex.exec(
|
|
6408
|
+
const detail = fromPathRegex.exec(path17) || [null, path17, path17];
|
|
6409
6409
|
this.from = detail[2] || "";
|
|
6410
6410
|
this.path = detail[1] || "";
|
|
6411
6411
|
}
|
|
@@ -6436,14 +6436,14 @@ function splitLine(result, lineStr) {
|
|
|
6436
6436
|
default:
|
|
6437
6437
|
return;
|
|
6438
6438
|
}
|
|
6439
|
-
function data(index, workingDir,
|
|
6439
|
+
function data(index, workingDir, path17) {
|
|
6440
6440
|
const raw = `${index}${workingDir}`;
|
|
6441
6441
|
const handler = parsers6.get(raw);
|
|
6442
6442
|
if (handler) {
|
|
6443
|
-
handler(result,
|
|
6443
|
+
handler(result, path17);
|
|
6444
6444
|
}
|
|
6445
6445
|
if (raw !== "##" && raw !== "!!") {
|
|
6446
|
-
result.files.push(new FileStatusSummary(
|
|
6446
|
+
result.files.push(new FileStatusSummary(path17, index, workingDir));
|
|
6447
6447
|
}
|
|
6448
6448
|
}
|
|
6449
6449
|
}
|
|
@@ -6756,9 +6756,9 @@ var init_simple_git_api = __esm({
|
|
|
6756
6756
|
next
|
|
6757
6757
|
);
|
|
6758
6758
|
}
|
|
6759
|
-
hashObject(
|
|
6759
|
+
hashObject(path17, write) {
|
|
6760
6760
|
return this._runTask(
|
|
6761
|
-
hashObjectTask(
|
|
6761
|
+
hashObjectTask(path17, write === true),
|
|
6762
6762
|
trailingFunctionArgument(arguments)
|
|
6763
6763
|
);
|
|
6764
6764
|
}
|
|
@@ -7111,8 +7111,8 @@ var init_branch = __esm({
|
|
|
7111
7111
|
}
|
|
7112
7112
|
});
|
|
7113
7113
|
function toPath(input) {
|
|
7114
|
-
const
|
|
7115
|
-
return
|
|
7114
|
+
const path17 = input.trim().replace(/^["']|["']$/g, "");
|
|
7115
|
+
return path17 && normalize(path17);
|
|
7116
7116
|
}
|
|
7117
7117
|
var parseCheckIgnore;
|
|
7118
7118
|
var init_CheckIgnore = __esm({
|
|
@@ -7426,8 +7426,8 @@ __export(sub_module_exports, {
|
|
|
7426
7426
|
subModuleTask: () => subModuleTask,
|
|
7427
7427
|
updateSubModuleTask: () => updateSubModuleTask
|
|
7428
7428
|
});
|
|
7429
|
-
function addSubModuleTask(repo,
|
|
7430
|
-
return subModuleTask(["add", repo,
|
|
7429
|
+
function addSubModuleTask(repo, path17) {
|
|
7430
|
+
return subModuleTask(["add", repo, path17]);
|
|
7431
7431
|
}
|
|
7432
7432
|
function initSubModuleTask(customArgs) {
|
|
7433
7433
|
return subModuleTask(["init", ...customArgs]);
|
|
@@ -7757,8 +7757,8 @@ var require_git = __commonJS2({
|
|
|
7757
7757
|
}
|
|
7758
7758
|
return this._runTask(straightThroughStringTask2(command, this._trimmed), next);
|
|
7759
7759
|
};
|
|
7760
|
-
Git2.prototype.submoduleAdd = function(repo,
|
|
7761
|
-
return this._runTask(addSubModuleTask2(repo,
|
|
7760
|
+
Git2.prototype.submoduleAdd = function(repo, path17, then) {
|
|
7761
|
+
return this._runTask(addSubModuleTask2(repo, path17), trailingFunctionArgument2(arguments));
|
|
7762
7762
|
};
|
|
7763
7763
|
Git2.prototype.submoduleUpdate = function(args2, then) {
|
|
7764
7764
|
return this._runTask(
|
|
@@ -8599,7 +8599,7 @@ import { z as z4 } from "zod";
|
|
|
8599
8599
|
// package.json
|
|
8600
8600
|
var package_default = {
|
|
8601
8601
|
name: "@posthog/agent",
|
|
8602
|
-
version: "2.3.
|
|
8602
|
+
version: "2.3.513",
|
|
8603
8603
|
repository: "https://github.com/PostHog/code",
|
|
8604
8604
|
description: "TypeScript agent framework wrapping Claude Agent SDK with Git-based task execution for PostHog",
|
|
8605
8605
|
exports: {
|
|
@@ -9035,9 +9035,9 @@ function nodeWritableToWebWritable(nodeStream) {
|
|
|
9035
9035
|
|
|
9036
9036
|
// src/adapters/claude/claude-agent.ts
|
|
9037
9037
|
import { randomUUID } from "crypto";
|
|
9038
|
-
import * as
|
|
9039
|
-
import * as
|
|
9040
|
-
import * as
|
|
9038
|
+
import * as fs9 from "fs";
|
|
9039
|
+
import * as os5 from "os";
|
|
9040
|
+
import * as path11 from "path";
|
|
9041
9041
|
import {
|
|
9042
9042
|
RequestError as RequestError2
|
|
9043
9043
|
} from "@agentclientprotocol/sdk";
|
|
@@ -13449,8 +13449,8 @@ var ToolContentBuilder = class {
|
|
|
13449
13449
|
this.items.push({ type: "content", content: image(data, mimeType, uri) });
|
|
13450
13450
|
return this;
|
|
13451
13451
|
}
|
|
13452
|
-
diff(
|
|
13453
|
-
this.items.push({ type: "diff", path:
|
|
13452
|
+
diff(path17, oldText, newText) {
|
|
13453
|
+
this.items.push({ type: "diff", path: path17, oldText, newText });
|
|
13454
13454
|
return this;
|
|
13455
13455
|
}
|
|
13456
13456
|
build() {
|
|
@@ -13461,6 +13461,54 @@ function toolContent() {
|
|
|
13461
13461
|
return new ToolContentBuilder();
|
|
13462
13462
|
}
|
|
13463
13463
|
|
|
13464
|
+
// src/utils/partial-json.ts
|
|
13465
|
+
function tryParsePartialJson(s) {
|
|
13466
|
+
const trimmed2 = s.trim();
|
|
13467
|
+
if (!trimmed2) return null;
|
|
13468
|
+
try {
|
|
13469
|
+
return JSON.parse(trimmed2);
|
|
13470
|
+
} catch {
|
|
13471
|
+
}
|
|
13472
|
+
const closers = [];
|
|
13473
|
+
let inString = false;
|
|
13474
|
+
let escaped = false;
|
|
13475
|
+
for (let i2 = 0; i2 < trimmed2.length; i2++) {
|
|
13476
|
+
const ch = trimmed2[i2];
|
|
13477
|
+
if (inString) {
|
|
13478
|
+
if (escaped) {
|
|
13479
|
+
escaped = false;
|
|
13480
|
+
} else if (ch === "\\") {
|
|
13481
|
+
escaped = true;
|
|
13482
|
+
} else if (ch === '"') {
|
|
13483
|
+
inString = false;
|
|
13484
|
+
}
|
|
13485
|
+
continue;
|
|
13486
|
+
}
|
|
13487
|
+
if (ch === '"') inString = true;
|
|
13488
|
+
else if (ch === "{") closers.push("}");
|
|
13489
|
+
else if (ch === "[") closers.push("]");
|
|
13490
|
+
else if (ch === "}" || ch === "]") closers.pop();
|
|
13491
|
+
}
|
|
13492
|
+
const closeBrackets = (str) => {
|
|
13493
|
+
let out2 = str;
|
|
13494
|
+
for (let i2 = closers.length - 1; i2 >= 0; i2--) out2 += closers[i2];
|
|
13495
|
+
return out2;
|
|
13496
|
+
};
|
|
13497
|
+
const candidates = [];
|
|
13498
|
+
const closedString = inString ? `${trimmed2}"` : trimmed2;
|
|
13499
|
+
candidates.push(closeBrackets(closedString));
|
|
13500
|
+
let stripped = closedString.replace(/[,:]\s*$/, "");
|
|
13501
|
+
stripped = stripped.replace(/,?\s*"[^"]*"\s*:?\s*$/, "");
|
|
13502
|
+
candidates.push(closeBrackets(stripped));
|
|
13503
|
+
for (const candidate of candidates) {
|
|
13504
|
+
try {
|
|
13505
|
+
return JSON.parse(candidate);
|
|
13506
|
+
} catch {
|
|
13507
|
+
}
|
|
13508
|
+
}
|
|
13509
|
+
return null;
|
|
13510
|
+
}
|
|
13511
|
+
|
|
13464
13512
|
// src/adapters/claude/permissions/posthog-exec-gate.ts
|
|
13465
13513
|
var POSTHOG_EXEC_TOOL_RE = /^mcp__posthog(?:_[^_]+)*__exec$/;
|
|
13466
13514
|
var POSTHOG_CALL_COMMAND_RE = /^\s*call\s+(?:--json\s+)?([a-zA-Z0-9_-]+)/;
|
|
@@ -14627,12 +14675,19 @@ function toAcpNotifications(content, role, sessionId, toolUseCache, fileContentC
|
|
|
14627
14675
|
}
|
|
14628
14676
|
return output;
|
|
14629
14677
|
}
|
|
14630
|
-
function streamEventToAcpNotifications(message, sessionId, toolUseCache, fileContentCache, client, logger, parentToolCallId, registerHooks, supportsTerminalOutput, cwd, enrichedReadCache) {
|
|
14678
|
+
function streamEventToAcpNotifications(message, sessionId, toolUseCache, toolUseStreamCache, fileContentCache, client, logger, parentToolCallId, registerHooks, supportsTerminalOutput, cwd, enrichedReadCache) {
|
|
14631
14679
|
const event = message.event;
|
|
14632
14680
|
switch (event.type) {
|
|
14633
|
-
case "content_block_start":
|
|
14681
|
+
case "content_block_start": {
|
|
14682
|
+
const block = event.content_block;
|
|
14683
|
+
if (block.type === "tool_use" || block.type === "mcp_tool_use") {
|
|
14684
|
+
toolUseStreamCache.set(event.index, {
|
|
14685
|
+
toolUseId: block.id,
|
|
14686
|
+
partialJson: ""
|
|
14687
|
+
});
|
|
14688
|
+
}
|
|
14634
14689
|
return toAcpNotifications(
|
|
14635
|
-
[
|
|
14690
|
+
[block],
|
|
14636
14691
|
"assistant",
|
|
14637
14692
|
sessionId,
|
|
14638
14693
|
toolUseCache,
|
|
@@ -14646,7 +14701,16 @@ function streamEventToAcpNotifications(message, sessionId, toolUseCache, fileCon
|
|
|
14646
14701
|
void 0,
|
|
14647
14702
|
enrichedReadCache
|
|
14648
14703
|
);
|
|
14649
|
-
|
|
14704
|
+
}
|
|
14705
|
+
case "content_block_delta": {
|
|
14706
|
+
if (event.delta.type === "input_json_delta") {
|
|
14707
|
+
return inputJsonDeltaToAcpNotifications(
|
|
14708
|
+
event.index,
|
|
14709
|
+
event.delta.partial_json,
|
|
14710
|
+
sessionId,
|
|
14711
|
+
toolUseStreamCache
|
|
14712
|
+
);
|
|
14713
|
+
}
|
|
14650
14714
|
return toAcpNotifications(
|
|
14651
14715
|
[event.delta],
|
|
14652
14716
|
"assistant",
|
|
@@ -14662,16 +14726,36 @@ function streamEventToAcpNotifications(message, sessionId, toolUseCache, fileCon
|
|
|
14662
14726
|
void 0,
|
|
14663
14727
|
enrichedReadCache
|
|
14664
14728
|
);
|
|
14729
|
+
}
|
|
14730
|
+
case "content_block_stop":
|
|
14731
|
+
toolUseStreamCache.delete(event.index);
|
|
14732
|
+
return [];
|
|
14665
14733
|
case "message_start":
|
|
14666
14734
|
case "message_delta":
|
|
14667
14735
|
case "message_stop":
|
|
14668
|
-
case "content_block_stop":
|
|
14669
14736
|
return [];
|
|
14670
14737
|
default:
|
|
14671
14738
|
unreachable(event, logger);
|
|
14672
14739
|
return [];
|
|
14673
14740
|
}
|
|
14674
14741
|
}
|
|
14742
|
+
function inputJsonDeltaToAcpNotifications(index, partialJson, sessionId, toolUseStreamCache) {
|
|
14743
|
+
const entry = toolUseStreamCache.get(index);
|
|
14744
|
+
if (!entry) return [];
|
|
14745
|
+
entry.partialJson += partialJson;
|
|
14746
|
+
const parsed = tryParsePartialJson(entry.partialJson);
|
|
14747
|
+
if (!parsed || typeof parsed !== "object") return [];
|
|
14748
|
+
return [
|
|
14749
|
+
{
|
|
14750
|
+
sessionId,
|
|
14751
|
+
update: {
|
|
14752
|
+
sessionUpdate: "tool_call_update",
|
|
14753
|
+
toolCallId: entry.toolUseId,
|
|
14754
|
+
rawInput: parsed
|
|
14755
|
+
}
|
|
14756
|
+
}
|
|
14757
|
+
];
|
|
14758
|
+
}
|
|
14675
14759
|
async function handleSystemMessage(message, context) {
|
|
14676
14760
|
const { session, sessionId, client, logger } = context;
|
|
14677
14761
|
switch (message.subtype) {
|
|
@@ -14815,12 +14899,20 @@ function extractUsageFromResult(message) {
|
|
|
14815
14899
|
};
|
|
14816
14900
|
}
|
|
14817
14901
|
async function handleStreamEvent(message, context) {
|
|
14818
|
-
const {
|
|
14902
|
+
const {
|
|
14903
|
+
sessionId,
|
|
14904
|
+
client,
|
|
14905
|
+
toolUseCache,
|
|
14906
|
+
toolUseStreamCache,
|
|
14907
|
+
fileContentCache,
|
|
14908
|
+
logger
|
|
14909
|
+
} = context;
|
|
14819
14910
|
const parentToolCallId = message.parent_tool_use_id ?? void 0;
|
|
14820
14911
|
for (const notification of streamEventToAcpNotifications(
|
|
14821
14912
|
message,
|
|
14822
14913
|
sessionId,
|
|
14823
14914
|
toolUseCache,
|
|
14915
|
+
toolUseStreamCache,
|
|
14824
14916
|
fileContentCache,
|
|
14825
14917
|
client,
|
|
14826
14918
|
logger,
|
|
@@ -15733,6 +15825,31 @@ function getAvailableSlashCommands(commands) {
|
|
|
15733
15825
|
}
|
|
15734
15826
|
|
|
15735
15827
|
// src/adapters/claude/session/mcp-config.ts
|
|
15828
|
+
import * as fs6 from "fs";
|
|
15829
|
+
import * as os2 from "os";
|
|
15830
|
+
import * as path8 from "path";
|
|
15831
|
+
function loadUserClaudeJsonMcpServers(cwd, logger, homeDir = os2.homedir()) {
|
|
15832
|
+
const claudeJsonPath = path8.join(homeDir, ".claude.json");
|
|
15833
|
+
let raw;
|
|
15834
|
+
try {
|
|
15835
|
+
raw = fs6.readFileSync(claudeJsonPath, "utf8");
|
|
15836
|
+
} catch {
|
|
15837
|
+
return {};
|
|
15838
|
+
}
|
|
15839
|
+
let cfg;
|
|
15840
|
+
try {
|
|
15841
|
+
cfg = JSON.parse(raw);
|
|
15842
|
+
} catch (err2) {
|
|
15843
|
+
logger?.warn("Failed to parse ~/.claude.json", {
|
|
15844
|
+
error: err2 instanceof Error ? err2.message : String(err2)
|
|
15845
|
+
});
|
|
15846
|
+
return {};
|
|
15847
|
+
}
|
|
15848
|
+
const topLevel = cfg.mcpServers && typeof cfg.mcpServers === "object" ? cfg.mcpServers : {};
|
|
15849
|
+
const project = cfg.projects?.[cwd];
|
|
15850
|
+
const projectScoped = project?.mcpServers && typeof project.mcpServers === "object" ? project.mcpServers : {};
|
|
15851
|
+
return { ...topLevel, ...projectScoped };
|
|
15852
|
+
}
|
|
15736
15853
|
function parseMcpServers(params) {
|
|
15737
15854
|
const mcpServers = {};
|
|
15738
15855
|
if (!Array.isArray(params.mcpServers)) {
|
|
@@ -15866,9 +15983,9 @@ function resolveModelPreference(preference, options) {
|
|
|
15866
15983
|
|
|
15867
15984
|
// src/adapters/claude/session/options.ts
|
|
15868
15985
|
import { spawn as spawn2 } from "child_process";
|
|
15869
|
-
import * as
|
|
15870
|
-
import * as
|
|
15871
|
-
import * as
|
|
15986
|
+
import * as fs7 from "fs";
|
|
15987
|
+
import * as os3 from "os";
|
|
15988
|
+
import * as path9 from "path";
|
|
15872
15989
|
|
|
15873
15990
|
// src/adapters/claude/session/instructions.ts
|
|
15874
15991
|
var BRANCH_NAMING = `
|
|
@@ -15919,8 +16036,9 @@ function buildSystemPrompt(customPrompt) {
|
|
|
15919
16036
|
}
|
|
15920
16037
|
return defaultPrompt;
|
|
15921
16038
|
}
|
|
15922
|
-
function buildMcpServers(userServers, acpServers) {
|
|
16039
|
+
function buildMcpServers(userServers, acpServers, projectScopedServers) {
|
|
15923
16040
|
return {
|
|
16041
|
+
...projectScopedServers,
|
|
15924
16042
|
...userServers || {},
|
|
15925
16043
|
...acpServers
|
|
15926
16044
|
};
|
|
@@ -16069,12 +16187,12 @@ function buildSpawnWrapper(sessionId, onProcessSpawned, onProcessExited, logger)
|
|
|
16069
16187
|
};
|
|
16070
16188
|
}
|
|
16071
16189
|
function ensureLocalSettings(cwd) {
|
|
16072
|
-
const claudeDir =
|
|
16073
|
-
const localSettingsPath =
|
|
16190
|
+
const claudeDir = path9.join(cwd, ".claude");
|
|
16191
|
+
const localSettingsPath = path9.join(claudeDir, "settings.local.json");
|
|
16074
16192
|
try {
|
|
16075
|
-
if (!
|
|
16076
|
-
|
|
16077
|
-
|
|
16193
|
+
if (!fs7.existsSync(localSettingsPath)) {
|
|
16194
|
+
fs7.mkdirSync(claudeDir, { recursive: true });
|
|
16195
|
+
fs7.writeFileSync(localSettingsPath, "{}\n", { flag: "wx" });
|
|
16078
16196
|
}
|
|
16079
16197
|
} catch {
|
|
16080
16198
|
}
|
|
@@ -16104,7 +16222,8 @@ function buildSessionOptions(params) {
|
|
|
16104
16222
|
},
|
|
16105
16223
|
mcpServers: buildMcpServers(
|
|
16106
16224
|
params.userProvidedOptions?.mcpServers,
|
|
16107
|
-
params.mcpServers
|
|
16225
|
+
params.mcpServers,
|
|
16226
|
+
loadUserClaudeJsonMcpServers(params.cwd, params.logger)
|
|
16108
16227
|
),
|
|
16109
16228
|
env: buildEnvironment(),
|
|
16110
16229
|
hooks: buildHooks(
|
|
@@ -16149,18 +16268,18 @@ function buildSessionOptions(params) {
|
|
|
16149
16268
|
return options;
|
|
16150
16269
|
}
|
|
16151
16270
|
function clearStatsigCache() {
|
|
16152
|
-
const statsigPath =
|
|
16153
|
-
process.env.CLAUDE_CONFIG_DIR ||
|
|
16271
|
+
const statsigPath = path9.join(
|
|
16272
|
+
process.env.CLAUDE_CONFIG_DIR || path9.join(os3.homedir(), ".claude"),
|
|
16154
16273
|
"statsig"
|
|
16155
16274
|
);
|
|
16156
|
-
|
|
16275
|
+
fs7.rm(statsigPath, { recursive: true, force: true }, () => {
|
|
16157
16276
|
});
|
|
16158
16277
|
}
|
|
16159
16278
|
|
|
16160
16279
|
// src/adapters/claude/session/settings.ts
|
|
16161
|
-
import * as
|
|
16162
|
-
import * as
|
|
16163
|
-
import * as
|
|
16280
|
+
import * as fs8 from "fs";
|
|
16281
|
+
import * as os4 from "os";
|
|
16282
|
+
import * as path10 from "path";
|
|
16164
16283
|
import { minimatch } from "minimatch";
|
|
16165
16284
|
|
|
16166
16285
|
// src/utils/async-mutex.ts
|
|
@@ -16241,13 +16360,13 @@ function parseRule(rule) {
|
|
|
16241
16360
|
function normalizePath(filePath, cwd) {
|
|
16242
16361
|
let resolved = filePath;
|
|
16243
16362
|
if (resolved.startsWith("~/")) {
|
|
16244
|
-
resolved =
|
|
16363
|
+
resolved = path10.join(os4.homedir(), resolved.slice(2));
|
|
16245
16364
|
} else if (resolved.startsWith("./")) {
|
|
16246
|
-
resolved =
|
|
16247
|
-
} else if (!
|
|
16248
|
-
resolved =
|
|
16365
|
+
resolved = path10.join(cwd, resolved.slice(2));
|
|
16366
|
+
} else if (!path10.isAbsolute(resolved)) {
|
|
16367
|
+
resolved = path10.join(cwd, resolved);
|
|
16249
16368
|
}
|
|
16250
|
-
return
|
|
16369
|
+
return path10.normalize(resolved).replace(/\\/g, "/");
|
|
16251
16370
|
}
|
|
16252
16371
|
function matchesGlob(pattern, filePath, cwd) {
|
|
16253
16372
|
const normalizedPattern = normalizePath(pattern, cwd);
|
|
@@ -16294,11 +16413,11 @@ function formatRule(rule) {
|
|
|
16294
16413
|
}
|
|
16295
16414
|
async function writeFileAtomic(filePath, data) {
|
|
16296
16415
|
const tmpPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
|
|
16297
|
-
await
|
|
16416
|
+
await fs8.promises.writeFile(tmpPath, data);
|
|
16298
16417
|
try {
|
|
16299
|
-
await
|
|
16418
|
+
await fs8.promises.rename(tmpPath, filePath);
|
|
16300
16419
|
} catch (error) {
|
|
16301
|
-
await
|
|
16420
|
+
await fs8.promises.rm(tmpPath, { force: true });
|
|
16302
16421
|
throw error;
|
|
16303
16422
|
}
|
|
16304
16423
|
}
|
|
@@ -16307,7 +16426,7 @@ async function loadSettingsFile(filePath) {
|
|
|
16307
16426
|
return {};
|
|
16308
16427
|
}
|
|
16309
16428
|
try {
|
|
16310
|
-
const content = await
|
|
16429
|
+
const content = await fs8.promises.readFile(filePath, "utf-8");
|
|
16311
16430
|
return JSON.parse(content);
|
|
16312
16431
|
} catch (error) {
|
|
16313
16432
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
@@ -16322,7 +16441,7 @@ async function loadSettingsFile(filePath) {
|
|
|
16322
16441
|
}
|
|
16323
16442
|
async function readSettingsFileForUpdate(filePath) {
|
|
16324
16443
|
try {
|
|
16325
|
-
const content = await
|
|
16444
|
+
const content = await fs8.promises.readFile(filePath, "utf-8");
|
|
16326
16445
|
return JSON.parse(content);
|
|
16327
16446
|
} catch (error) {
|
|
16328
16447
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
@@ -16368,11 +16487,11 @@ var SettingsManager = class {
|
|
|
16368
16487
|
return this.initPromise;
|
|
16369
16488
|
}
|
|
16370
16489
|
getUserSettingsPath() {
|
|
16371
|
-
const configDir = process.env.CLAUDE_CONFIG_DIR ||
|
|
16372
|
-
return
|
|
16490
|
+
const configDir = process.env.CLAUDE_CONFIG_DIR || path10.join(os4.homedir(), ".claude");
|
|
16491
|
+
return path10.join(configDir, "settings.json");
|
|
16373
16492
|
}
|
|
16374
16493
|
getProjectSettingsPath() {
|
|
16375
|
-
return
|
|
16494
|
+
return path10.join(this.cwd, ".claude", "settings.json");
|
|
16376
16495
|
}
|
|
16377
16496
|
/**
|
|
16378
16497
|
* Local settings are anchored to the primary worktree so every worktree of
|
|
@@ -16380,7 +16499,7 @@ var SettingsManager = class {
|
|
|
16380
16499
|
* avoids re-prompting for the same permission in every worktree.
|
|
16381
16500
|
*/
|
|
16382
16501
|
getLocalSettingsPath() {
|
|
16383
|
-
return
|
|
16502
|
+
return path10.join(this.repoRoot, ".claude", "settings.local.json");
|
|
16384
16503
|
}
|
|
16385
16504
|
async loadAllSettings() {
|
|
16386
16505
|
this.repoRoot = await resolveMainRepoPath(this.cwd);
|
|
@@ -16507,7 +16626,7 @@ var SettingsManager = class {
|
|
|
16507
16626
|
}
|
|
16508
16627
|
permissions.allow = Array.from(current2);
|
|
16509
16628
|
const next = { ...existing, permissions };
|
|
16510
|
-
await
|
|
16629
|
+
await fs8.promises.mkdir(path10.dirname(filePath), { recursive: true });
|
|
16511
16630
|
await writeFileAtomic(filePath, `${JSON.stringify(next, null, 2)}
|
|
16512
16631
|
`);
|
|
16513
16632
|
this.localSettings = next;
|
|
@@ -16540,7 +16659,7 @@ var SettingsManager = class {
|
|
|
16540
16659
|
...existing,
|
|
16541
16660
|
posthogApprovedExecTools: Array.from(current2)
|
|
16542
16661
|
};
|
|
16543
|
-
await
|
|
16662
|
+
await fs8.promises.mkdir(path10.dirname(filePath), { recursive: true });
|
|
16544
16663
|
await writeFileAtomic(filePath, `${JSON.stringify(next, null, 2)}
|
|
16545
16664
|
`);
|
|
16546
16665
|
this.localSettings = next;
|
|
@@ -16583,6 +16702,7 @@ function shouldEmitRawMessage(config, message) {
|
|
|
16583
16702
|
var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
16584
16703
|
adapterName = "claude";
|
|
16585
16704
|
toolUseCache;
|
|
16705
|
+
toolUseStreamCache;
|
|
16586
16706
|
backgroundTerminals = {};
|
|
16587
16707
|
clientCapabilities;
|
|
16588
16708
|
options;
|
|
@@ -16592,6 +16712,7 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
16592
16712
|
super(client);
|
|
16593
16713
|
this.options = options;
|
|
16594
16714
|
this.toolUseCache = {};
|
|
16715
|
+
this.toolUseStreamCache = /* @__PURE__ */ new Map();
|
|
16595
16716
|
this.logger = new Logger({ debug: true, prefix: "[ClaudeAcpAgent]" });
|
|
16596
16717
|
this.enrichment = createEnrichment(options?.posthogApiConfig, this.logger);
|
|
16597
16718
|
}
|
|
@@ -16644,7 +16765,7 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
16644
16765
|
};
|
|
16645
16766
|
}
|
|
16646
16767
|
async newSession(params) {
|
|
16647
|
-
if (
|
|
16768
|
+
if (fs9.existsSync(path11.resolve(os5.homedir(), ".claude.json.backup")) && !fs9.existsSync(path11.resolve(os5.homedir(), ".claude.json"))) {
|
|
16648
16769
|
throw RequestError2.authRequired();
|
|
16649
16770
|
}
|
|
16650
16771
|
const response = await this.createSession(params, {
|
|
@@ -16786,6 +16907,7 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
16786
16907
|
sessionId: params.sessionId,
|
|
16787
16908
|
client: this.client,
|
|
16788
16909
|
toolUseCache: this.toolUseCache,
|
|
16910
|
+
toolUseStreamCache: this.toolUseStreamCache,
|
|
16789
16911
|
fileContentCache: this.fileContentCache,
|
|
16790
16912
|
enrichedReadCache: this.enrichedReadCache,
|
|
16791
16913
|
logger: this.logger,
|
|
@@ -17038,6 +17160,7 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
17038
17160
|
}
|
|
17039
17161
|
throw error;
|
|
17040
17162
|
} finally {
|
|
17163
|
+
this.toolUseStreamCache.clear();
|
|
17041
17164
|
if (!handedOff) {
|
|
17042
17165
|
this.session.promptRunning = false;
|
|
17043
17166
|
for (const [key, pending] of this.session.pendingMessages) {
|
|
@@ -17612,6 +17735,7 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
17612
17735
|
sessionId,
|
|
17613
17736
|
client: this.client,
|
|
17614
17737
|
toolUseCache: this.toolUseCache,
|
|
17738
|
+
toolUseStreamCache: this.toolUseStreamCache,
|
|
17615
17739
|
fileContentCache: this.fileContentCache,
|
|
17616
17740
|
enrichedReadCache: this.enrichedReadCache,
|
|
17617
17741
|
logger: this.logger,
|
|
@@ -17884,9 +18008,9 @@ function resetUsage(state) {
|
|
|
17884
18008
|
}
|
|
17885
18009
|
|
|
17886
18010
|
// src/adapters/codex/settings.ts
|
|
17887
|
-
import * as
|
|
17888
|
-
import * as
|
|
17889
|
-
import * as
|
|
18011
|
+
import * as fs10 from "fs";
|
|
18012
|
+
import * as os6 from "os";
|
|
18013
|
+
import * as path12 from "path";
|
|
17890
18014
|
var CodexSettingsManager = class {
|
|
17891
18015
|
cwd;
|
|
17892
18016
|
settings = { mcpServerNames: [] };
|
|
@@ -17897,12 +18021,12 @@ var CodexSettingsManager = class {
|
|
|
17897
18021
|
async initialize() {
|
|
17898
18022
|
}
|
|
17899
18023
|
getConfigPath() {
|
|
17900
|
-
return
|
|
18024
|
+
return path12.join(os6.homedir(), ".codex", "config.toml");
|
|
17901
18025
|
}
|
|
17902
18026
|
loadSettings() {
|
|
17903
18027
|
const configPath = this.getConfigPath();
|
|
17904
18028
|
try {
|
|
17905
|
-
const content =
|
|
18029
|
+
const content = fs10.readFileSync(configPath, "utf-8");
|
|
17906
18030
|
this.settings = parseCodexToml(content, this.cwd);
|
|
17907
18031
|
} catch {
|
|
17908
18032
|
this.settings = { mcpServerNames: [] };
|
|
@@ -18673,18 +18797,18 @@ function createCodexConnection(config) {
|
|
|
18673
18797
|
// src/handoff-checkpoint.ts
|
|
18674
18798
|
import { mkdtemp as mkdtemp2, readFile as readFile4, rm as rm4, writeFile as writeFile2 } from "fs/promises";
|
|
18675
18799
|
import { tmpdir as tmpdir2 } from "os";
|
|
18676
|
-
import { dirname as dirname6, join as
|
|
18800
|
+
import { dirname as dirname6, join as join10 } from "path";
|
|
18677
18801
|
|
|
18678
18802
|
// ../git/dist/handoff.js
|
|
18679
18803
|
import { spawn as spawn4 } from "child_process";
|
|
18680
18804
|
import { copyFile, mkdtemp, readFile as readFile3, rm as rm3, stat as stat3 } from "fs/promises";
|
|
18681
18805
|
import { tmpdir } from "os";
|
|
18682
|
-
import
|
|
18806
|
+
import path14 from "path";
|
|
18683
18807
|
|
|
18684
18808
|
// ../git/dist/sagas/checkpoint.js
|
|
18685
18809
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
18686
|
-
import * as
|
|
18687
|
-
import * as
|
|
18810
|
+
import * as fs11 from "fs/promises";
|
|
18811
|
+
import * as path13 from "path";
|
|
18688
18812
|
|
|
18689
18813
|
// ../shared/dist/index.js
|
|
18690
18814
|
var CLOUD_PROMPT_PREFIX = "__twig_cloud_prompt_v1__:";
|
|
@@ -18957,12 +19081,12 @@ async function getGitBusyState(git) {
|
|
|
18957
19081
|
const toplevel = (await git.raw(["rev-parse", "--show-toplevel"])).trim();
|
|
18958
19082
|
const resolveGitPath = async (gitPath) => {
|
|
18959
19083
|
const relative = (await git.raw(["rev-parse", "--git-path", gitPath])).trim();
|
|
18960
|
-
return
|
|
19084
|
+
return path13.isAbsolute(relative) ? relative : path13.resolve(toplevel, relative);
|
|
18961
19085
|
};
|
|
18962
19086
|
const pathExists = async (gitPath) => {
|
|
18963
19087
|
const resolved = await resolveGitPath(gitPath);
|
|
18964
19088
|
try {
|
|
18965
|
-
await
|
|
19089
|
+
await fs11.access(resolved);
|
|
18966
19090
|
return true;
|
|
18967
19091
|
} catch {
|
|
18968
19092
|
return false;
|
|
@@ -18971,7 +19095,7 @@ async function getGitBusyState(git) {
|
|
|
18971
19095
|
const dirExists = async (gitPath) => {
|
|
18972
19096
|
const resolved = await resolveGitPath(gitPath);
|
|
18973
19097
|
try {
|
|
18974
|
-
const stat4 = await
|
|
19098
|
+
const stat4 = await fs11.stat(resolved);
|
|
18975
19099
|
return stat4.isDirectory();
|
|
18976
19100
|
} catch {
|
|
18977
19101
|
return false;
|
|
@@ -18991,6 +19115,7 @@ async function getGitBusyState(git) {
|
|
|
18991
19115
|
}
|
|
18992
19116
|
return { busy: false };
|
|
18993
19117
|
}
|
|
19118
|
+
var MAX_WORKTREE_FILE_BYTES = 1024 * 1024;
|
|
18994
19119
|
async function createWorktreeTree(git, baseDir, head) {
|
|
18995
19120
|
const { tempGit, tempIndexPath } = await createTempIndexGit(git, baseDir, "checkpoint-worktree");
|
|
18996
19121
|
try {
|
|
@@ -19000,13 +19125,85 @@ async function createWorktreeTree(git, baseDir, head) {
|
|
|
19000
19125
|
await tempGit.raw(["read-tree", "--empty"]);
|
|
19001
19126
|
}
|
|
19002
19127
|
await tempGit.raw(["add", "-A", "--", "."]);
|
|
19128
|
+
await reconcileLargeBlobs(tempGit, head, MAX_WORKTREE_FILE_BYTES);
|
|
19003
19129
|
const treeHash = await tempGit.raw(["write-tree"]);
|
|
19004
19130
|
return treeHash.trim();
|
|
19005
19131
|
} finally {
|
|
19006
|
-
await
|
|
19132
|
+
await fs11.rm(tempIndexPath, { force: true }).catch(() => {
|
|
19007
19133
|
});
|
|
19008
19134
|
}
|
|
19009
19135
|
}
|
|
19136
|
+
async function reconcileLargeBlobs(tempGit, head, maxBytes) {
|
|
19137
|
+
const intermediateTree = (await tempGit.raw(["write-tree"])).trim();
|
|
19138
|
+
const largePaths = await listLargeBlobPaths(tempGit, intermediateTree, maxBytes);
|
|
19139
|
+
if (largePaths.length === 0)
|
|
19140
|
+
return;
|
|
19141
|
+
const headEntries = head ? await readHeadBlobEntries(tempGit, head, largePaths) : /* @__PURE__ */ new Map();
|
|
19142
|
+
for (const filePath of largePaths) {
|
|
19143
|
+
const headEntry = headEntries.get(filePath);
|
|
19144
|
+
if (headEntry) {
|
|
19145
|
+
await tempGit.raw([
|
|
19146
|
+
"update-index",
|
|
19147
|
+
"--cacheinfo",
|
|
19148
|
+
`${headEntry.mode},${headEntry.hash},${filePath}`
|
|
19149
|
+
]);
|
|
19150
|
+
} else {
|
|
19151
|
+
await tempGit.raw(["update-index", "--force-remove", filePath]).catch(() => {
|
|
19152
|
+
});
|
|
19153
|
+
}
|
|
19154
|
+
}
|
|
19155
|
+
}
|
|
19156
|
+
async function listLargeBlobPaths(tempGit, tree, maxBytes) {
|
|
19157
|
+
const output = await tempGit.raw(["ls-tree", "-r", "-l", tree]);
|
|
19158
|
+
const result = [];
|
|
19159
|
+
for (const line of output.split("\n")) {
|
|
19160
|
+
if (!line)
|
|
19161
|
+
continue;
|
|
19162
|
+
const tabIndex = line.indexOf(" ");
|
|
19163
|
+
if (tabIndex < 0)
|
|
19164
|
+
continue;
|
|
19165
|
+
const meta = line.slice(0, tabIndex);
|
|
19166
|
+
const filePath = line.slice(tabIndex + 1);
|
|
19167
|
+
const parts2 = meta.split(/\s+/);
|
|
19168
|
+
if (parts2.length < 4)
|
|
19169
|
+
continue;
|
|
19170
|
+
const [, type, , sizeStr] = parts2;
|
|
19171
|
+
if (type !== "blob")
|
|
19172
|
+
continue;
|
|
19173
|
+
if (sizeStr === "-")
|
|
19174
|
+
continue;
|
|
19175
|
+
const size = Number.parseInt(sizeStr, 10);
|
|
19176
|
+
if (Number.isFinite(size) && size > maxBytes) {
|
|
19177
|
+
result.push(filePath);
|
|
19178
|
+
}
|
|
19179
|
+
}
|
|
19180
|
+
return result;
|
|
19181
|
+
}
|
|
19182
|
+
async function readHeadBlobEntries(tempGit, head, paths) {
|
|
19183
|
+
const result = /* @__PURE__ */ new Map();
|
|
19184
|
+
const CHUNK_SIZE = 100;
|
|
19185
|
+
for (let i2 = 0; i2 < paths.length; i2 += CHUNK_SIZE) {
|
|
19186
|
+
const chunk = paths.slice(i2, i2 + CHUNK_SIZE);
|
|
19187
|
+
const output = await tempGit.raw(["ls-tree", "-r", head, "--", ...chunk]).catch(() => "");
|
|
19188
|
+
for (const line of output.split("\n")) {
|
|
19189
|
+
if (!line)
|
|
19190
|
+
continue;
|
|
19191
|
+
const tabIndex = line.indexOf(" ");
|
|
19192
|
+
if (tabIndex < 0)
|
|
19193
|
+
continue;
|
|
19194
|
+
const meta = line.slice(0, tabIndex);
|
|
19195
|
+
const filePath = line.slice(tabIndex + 1);
|
|
19196
|
+
const parts2 = meta.split(/\s+/);
|
|
19197
|
+
if (parts2.length < 3)
|
|
19198
|
+
continue;
|
|
19199
|
+
const [mode, type, hash] = parts2;
|
|
19200
|
+
if (type !== "blob")
|
|
19201
|
+
continue;
|
|
19202
|
+
result.set(filePath, { mode, hash });
|
|
19203
|
+
}
|
|
19204
|
+
}
|
|
19205
|
+
return result;
|
|
19206
|
+
}
|
|
19010
19207
|
async function createMetaTree(git, baseDir, indexTree, worktreeTree) {
|
|
19011
19208
|
const { tempGit, tempIndexPath } = await createTempIndexGit(git, baseDir, "checkpoint-meta");
|
|
19012
19209
|
try {
|
|
@@ -19030,7 +19227,7 @@ async function createMetaTree(git, baseDir, indexTree, worktreeTree) {
|
|
|
19030
19227
|
const metaTree = await tempGit.raw(["write-tree"]);
|
|
19031
19228
|
return metaTree.trim();
|
|
19032
19229
|
} finally {
|
|
19033
|
-
await
|
|
19230
|
+
await fs11.rm(tempIndexPath, { force: true }).catch(() => {
|
|
19034
19231
|
});
|
|
19035
19232
|
}
|
|
19036
19233
|
}
|
|
@@ -19047,12 +19244,12 @@ function formatCheckpointMessage(meta) {
|
|
|
19047
19244
|
async function getGitCommonDir(git, baseDir) {
|
|
19048
19245
|
const raw = await git.raw(["rev-parse", "--git-common-dir"]);
|
|
19049
19246
|
const dir = raw.trim() || ".git";
|
|
19050
|
-
return
|
|
19247
|
+
return path13.isAbsolute(dir) ? dir : path13.resolve(baseDir, dir);
|
|
19051
19248
|
}
|
|
19052
19249
|
async function createTempIndexGit(git, baseDir, label) {
|
|
19053
|
-
const tmpDir =
|
|
19054
|
-
await
|
|
19055
|
-
const tempIndexPath =
|
|
19250
|
+
const tmpDir = path13.join(await getGitCommonDir(git, baseDir), "posthog-code-tmp");
|
|
19251
|
+
await fs11.mkdir(tmpDir, { recursive: true });
|
|
19252
|
+
const tempIndexPath = path13.join(tmpDir, `${label}-${Date.now()}-${randomUUID2()}`);
|
|
19056
19253
|
const tempGit = createGitClient(baseDir).env({
|
|
19057
19254
|
...process.env,
|
|
19058
19255
|
GIT_INDEX_FILE: tempIndexPath
|
|
@@ -19079,6 +19276,7 @@ async function deleteCheckpoint(git, checkpointId) {
|
|
|
19079
19276
|
// ../git/dist/handoff.js
|
|
19080
19277
|
var HANDOFF_HEAD_REF_PREFIX = "refs/posthog-code-handoff/head/";
|
|
19081
19278
|
var CHECKPOINT_REF_PREFIX2 = "refs/posthog-code-checkpoint/";
|
|
19279
|
+
var MAX_HANDOFF_FILE_BYTES = 1024 * 1024;
|
|
19082
19280
|
var GitHandoffTracker = class {
|
|
19083
19281
|
repositoryPath;
|
|
19084
19282
|
logger;
|
|
@@ -19086,7 +19284,7 @@ var GitHandoffTracker = class {
|
|
|
19086
19284
|
this.repositoryPath = config.repositoryPath;
|
|
19087
19285
|
this.logger = config.logger;
|
|
19088
19286
|
}
|
|
19089
|
-
async captureForHandoff(
|
|
19287
|
+
async captureForHandoff(localGitState) {
|
|
19090
19288
|
const captureSaga = new CaptureCheckpointSaga(this.logger);
|
|
19091
19289
|
const result = await captureSaga.run({ baseDir: this.repositoryPath });
|
|
19092
19290
|
if (!result.success) {
|
|
@@ -19096,17 +19294,20 @@ var GitHandoffTracker = class {
|
|
|
19096
19294
|
const git = createGitClient(this.repositoryPath);
|
|
19097
19295
|
const tempDir = await this.createTempDir(checkpoint.checkpointId);
|
|
19098
19296
|
const checkpointRef = `${CHECKPOINT_REF_PREFIX2}${checkpoint.checkpointId}`;
|
|
19099
|
-
const packRefs = [
|
|
19100
|
-
checkpoint.head,
|
|
19101
|
-
checkpoint.indexTree,
|
|
19102
|
-
checkpoint.worktreeTree
|
|
19103
|
-
].filter((ref) => !!ref);
|
|
19104
|
-
const headRef = checkpoint.head ? `${HANDOFF_HEAD_REF_PREFIX}${checkpoint.checkpointId}` : void 0;
|
|
19105
|
-
const packPrefix = path13.join(tempDir, checkpoint.checkpointId);
|
|
19106
19297
|
try {
|
|
19298
|
+
const reconciledIndex = await this.reconcileHandoffIndex(git, checkpoint.head, checkpoint.indexTree, tempDir, checkpoint.checkpointId);
|
|
19299
|
+
const packBaseline = localGitState?.upstreamHead ?? null;
|
|
19300
|
+
const packRefs = [
|
|
19301
|
+
checkpoint.head,
|
|
19302
|
+
reconciledIndex.indexTree,
|
|
19303
|
+
checkpoint.worktreeTree,
|
|
19304
|
+
packBaseline ? `^${packBaseline}` : null
|
|
19305
|
+
].filter((ref) => !!ref);
|
|
19306
|
+
const headRef = checkpoint.head ? `${HANDOFF_HEAD_REF_PREFIX}${checkpoint.checkpointId}` : void 0;
|
|
19307
|
+
const packPrefix = path14.join(tempDir, checkpoint.checkpointId);
|
|
19107
19308
|
const [headPack, indexFile, tracking] = await Promise.all([
|
|
19108
19309
|
this.captureObjectPack(packPrefix, packRefs),
|
|
19109
|
-
this.
|
|
19310
|
+
this.statFileArtifact(reconciledIndex.indexFilePath),
|
|
19110
19311
|
getTrackingMetadata(git, checkpoint.branch)
|
|
19111
19312
|
]);
|
|
19112
19313
|
return {
|
|
@@ -19117,7 +19318,7 @@ var GitHandoffTracker = class {
|
|
|
19117
19318
|
headRef,
|
|
19118
19319
|
head: checkpoint.head,
|
|
19119
19320
|
branch: checkpoint.branch,
|
|
19120
|
-
indexTree:
|
|
19321
|
+
indexTree: reconciledIndex.indexTree,
|
|
19121
19322
|
worktreeTree: checkpoint.worktreeTree,
|
|
19122
19323
|
timestamp: checkpoint.timestamp,
|
|
19123
19324
|
upstreamRemote: tracking.upstreamRemote,
|
|
@@ -19137,6 +19338,7 @@ var GitHandoffTracker = class {
|
|
|
19137
19338
|
const { checkpoint, headPackPath, indexPath, localGitState, onDivergedBranch } = input;
|
|
19138
19339
|
const git = createGitClient(this.repositoryPath);
|
|
19139
19340
|
if (headPackPath) {
|
|
19341
|
+
await this.ensureBaselineForApply(git, checkpoint, localGitState);
|
|
19140
19342
|
await this.unpackPackFile(headPackPath);
|
|
19141
19343
|
}
|
|
19142
19344
|
if (checkpoint.branch && checkpoint.head) {
|
|
@@ -19175,14 +19377,89 @@ var GitHandoffTracker = class {
|
|
|
19175
19377
|
});
|
|
19176
19378
|
return { path: packPath, rawBytes };
|
|
19177
19379
|
}
|
|
19178
|
-
async
|
|
19179
|
-
const
|
|
19180
|
-
const
|
|
19181
|
-
await copyFile(
|
|
19182
|
-
|
|
19183
|
-
|
|
19184
|
-
|
|
19185
|
-
}
|
|
19380
|
+
async reconcileHandoffIndex(git, head, indexTree, tempDir, checkpointId) {
|
|
19381
|
+
const realIndexPath = await this.getGitPath(git, "index");
|
|
19382
|
+
const tempIndexPath = path14.join(tempDir, `${checkpointId}.index`);
|
|
19383
|
+
await copyFile(realIndexPath, tempIndexPath);
|
|
19384
|
+
const largePaths = await this.listLargeBlobsInTree(indexTree, MAX_HANDOFF_FILE_BYTES);
|
|
19385
|
+
if (largePaths.length === 0) {
|
|
19386
|
+
return { indexTree, indexFilePath: tempIndexPath };
|
|
19387
|
+
}
|
|
19388
|
+
const headBlobs = head ? await this.readHeadBlobsForPaths(head, largePaths) : /* @__PURE__ */ new Map();
|
|
19389
|
+
const env = { ...process.env, GIT_INDEX_FILE: tempIndexPath };
|
|
19390
|
+
for (const filePath of largePaths) {
|
|
19391
|
+
const headBlob = headBlobs.get(filePath);
|
|
19392
|
+
if (headBlob) {
|
|
19393
|
+
await this.runGitWithEnv(env, [
|
|
19394
|
+
"update-index",
|
|
19395
|
+
"--cacheinfo",
|
|
19396
|
+
`${headBlob.mode},${headBlob.hash},${filePath}`
|
|
19397
|
+
]);
|
|
19398
|
+
} else {
|
|
19399
|
+
await this.runGitWithEnv(env, [
|
|
19400
|
+
"update-index",
|
|
19401
|
+
"--force-remove",
|
|
19402
|
+
filePath
|
|
19403
|
+
]).catch(() => {
|
|
19404
|
+
});
|
|
19405
|
+
}
|
|
19406
|
+
}
|
|
19407
|
+
const reconciledTree = (await this.runGitWithEnv(env, ["write-tree"])).trim();
|
|
19408
|
+
return { indexTree: reconciledTree, indexFilePath: tempIndexPath };
|
|
19409
|
+
}
|
|
19410
|
+
async listLargeBlobsInTree(tree, maxBytes) {
|
|
19411
|
+
const { stdout } = await this.runGitProcess(["ls-tree", "-r", "-l", tree], "");
|
|
19412
|
+
const result = [];
|
|
19413
|
+
for (const line of stdout.split("\n")) {
|
|
19414
|
+
if (!line)
|
|
19415
|
+
continue;
|
|
19416
|
+
const tabIndex = line.indexOf(" ");
|
|
19417
|
+
if (tabIndex < 0)
|
|
19418
|
+
continue;
|
|
19419
|
+
const meta = line.slice(0, tabIndex);
|
|
19420
|
+
const filePath = line.slice(tabIndex + 1);
|
|
19421
|
+
const parts2 = meta.split(/\s+/);
|
|
19422
|
+
if (parts2.length < 4)
|
|
19423
|
+
continue;
|
|
19424
|
+
const [, type, , sizeStr] = parts2;
|
|
19425
|
+
if (type !== "blob")
|
|
19426
|
+
continue;
|
|
19427
|
+
if (sizeStr === "-")
|
|
19428
|
+
continue;
|
|
19429
|
+
const size = Number.parseInt(sizeStr, 10);
|
|
19430
|
+
if (Number.isFinite(size) && size > maxBytes) {
|
|
19431
|
+
result.push(filePath);
|
|
19432
|
+
}
|
|
19433
|
+
}
|
|
19434
|
+
return result;
|
|
19435
|
+
}
|
|
19436
|
+
async readHeadBlobsForPaths(head, paths) {
|
|
19437
|
+
const result = /* @__PURE__ */ new Map();
|
|
19438
|
+
const CHUNK_SIZE = 100;
|
|
19439
|
+
for (let i2 = 0; i2 < paths.length; i2 += CHUNK_SIZE) {
|
|
19440
|
+
const chunk = paths.slice(i2, i2 + CHUNK_SIZE);
|
|
19441
|
+
const { stdout } = await this.runGitProcess(["ls-tree", "-r", head, "--", ...chunk], "").catch(() => ({ stdout: "", stderr: "" }));
|
|
19442
|
+
for (const line of stdout.split("\n")) {
|
|
19443
|
+
if (!line)
|
|
19444
|
+
continue;
|
|
19445
|
+
const tabIndex = line.indexOf(" ");
|
|
19446
|
+
if (tabIndex < 0)
|
|
19447
|
+
continue;
|
|
19448
|
+
const meta = line.slice(0, tabIndex);
|
|
19449
|
+
const filePath = line.slice(tabIndex + 1);
|
|
19450
|
+
const parts2 = meta.split(/\s+/);
|
|
19451
|
+
if (parts2.length < 3)
|
|
19452
|
+
continue;
|
|
19453
|
+
const [mode, type, hash] = parts2;
|
|
19454
|
+
if (type !== "blob")
|
|
19455
|
+
continue;
|
|
19456
|
+
result.set(filePath, { mode, hash });
|
|
19457
|
+
}
|
|
19458
|
+
}
|
|
19459
|
+
return result;
|
|
19460
|
+
}
|
|
19461
|
+
async statFileArtifact(filePath) {
|
|
19462
|
+
return { path: filePath, rawBytes: await this.getFileSize(filePath) };
|
|
19186
19463
|
}
|
|
19187
19464
|
async restoreIndexFile(git, indexPath) {
|
|
19188
19465
|
const gitIndexPath = await this.getGitPath(git, "index");
|
|
@@ -19210,6 +19487,20 @@ var GitHandoffTracker = class {
|
|
|
19210
19487
|
shouldRestoreTracking(branchStatus2, localGitState, tracking) {
|
|
19211
19488
|
return branchStatus2.kind === "missing" || !hasTrackingConfig(localGitState) && (tracking.upstreamRemote !== null || tracking.upstreamMergeRef !== null);
|
|
19212
19489
|
}
|
|
19490
|
+
async ensureBaselineForApply(git, checkpoint, localGitState) {
|
|
19491
|
+
const tracking = this.getPreferredTracking(localGitState, checkpoint);
|
|
19492
|
+
if (!tracking.upstreamRemote || !tracking.upstreamMergeRef)
|
|
19493
|
+
return;
|
|
19494
|
+
await this.ensureRemoteForTracking(git, tracking).catch(() => {
|
|
19495
|
+
});
|
|
19496
|
+
await git.raw(["fetch", tracking.upstreamRemote, tracking.upstreamMergeRef]).catch((err2) => {
|
|
19497
|
+
this.logger?.error("Handoff baseline fetch failed; if the pack excludes commits the receiver does not already have, the subsequent unpack/read-tree will fail with an object-missing error", {
|
|
19498
|
+
err: String(err2),
|
|
19499
|
+
remote: tracking.upstreamRemote,
|
|
19500
|
+
ref: tracking.upstreamMergeRef
|
|
19501
|
+
});
|
|
19502
|
+
});
|
|
19503
|
+
}
|
|
19213
19504
|
async ensureRemoteForTracking(git, tracking) {
|
|
19214
19505
|
if (!tracking.upstreamRemote || !tracking.remoteUrl)
|
|
19215
19506
|
return;
|
|
@@ -19310,7 +19601,7 @@ var GitHandoffTracker = class {
|
|
|
19310
19601
|
async getGitPath(git, gitPath) {
|
|
19311
19602
|
const raw = await git.raw(["rev-parse", "--git-path", gitPath]);
|
|
19312
19603
|
const resolved = raw.trim();
|
|
19313
|
-
return
|
|
19604
|
+
return path14.isAbsolute(resolved) ? resolved : path14.resolve(this.repositoryPath, resolved);
|
|
19314
19605
|
}
|
|
19315
19606
|
async getFileSize(filePath) {
|
|
19316
19607
|
return (await stat3(filePath)).size;
|
|
@@ -19346,6 +19637,31 @@ var GitHandoffTracker = class {
|
|
|
19346
19637
|
});
|
|
19347
19638
|
});
|
|
19348
19639
|
}
|
|
19640
|
+
async runGitWithEnv(env, args2) {
|
|
19641
|
+
return new Promise((resolve7, reject) => {
|
|
19642
|
+
const child = spawn4("git", args2, {
|
|
19643
|
+
cwd: this.repositoryPath,
|
|
19644
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
19645
|
+
env
|
|
19646
|
+
});
|
|
19647
|
+
let stdout = "";
|
|
19648
|
+
let stderr = "";
|
|
19649
|
+
child.stdout.on("data", (chunk) => {
|
|
19650
|
+
stdout += chunk.toString();
|
|
19651
|
+
});
|
|
19652
|
+
child.stderr.on("data", (chunk) => {
|
|
19653
|
+
stderr += chunk.toString();
|
|
19654
|
+
});
|
|
19655
|
+
child.on("error", reject);
|
|
19656
|
+
child.on("close", (code) => {
|
|
19657
|
+
if (code === 0) {
|
|
19658
|
+
resolve7(stdout);
|
|
19659
|
+
return;
|
|
19660
|
+
}
|
|
19661
|
+
reject(new Error(stderr || `git ${args2.join(" ")} failed with code ${code}`));
|
|
19662
|
+
});
|
|
19663
|
+
});
|
|
19664
|
+
}
|
|
19349
19665
|
runGitProcess(args2, input) {
|
|
19350
19666
|
return new Promise((resolve7, reject) => {
|
|
19351
19667
|
const child = spawn4("git", args2, {
|
|
@@ -19368,12 +19684,14 @@ var GitHandoffTracker = class {
|
|
|
19368
19684
|
}
|
|
19369
19685
|
reject(new Error(stderr || `git ${args2.join(" ")} failed with code ${code}`));
|
|
19370
19686
|
});
|
|
19687
|
+
child.stdin.on("error", () => {
|
|
19688
|
+
});
|
|
19371
19689
|
child.stdin.end(input);
|
|
19372
19690
|
});
|
|
19373
19691
|
}
|
|
19374
19692
|
};
|
|
19375
19693
|
function joinTempPrefix(checkpointId) {
|
|
19376
|
-
return
|
|
19694
|
+
return path14.join(tmpdir(), `posthog-code-handoff-${checkpointId}-`);
|
|
19377
19695
|
}
|
|
19378
19696
|
async function getCurrentBranchName(git) {
|
|
19379
19697
|
try {
|
|
@@ -19476,10 +19794,10 @@ var HandoffCheckpointTracker = class {
|
|
|
19476
19794
|
}
|
|
19477
19795
|
const gitTracker = this.createGitTracker();
|
|
19478
19796
|
const tmpDir = await mkdtemp2(
|
|
19479
|
-
|
|
19797
|
+
join10(tmpdir2(), `posthog-code-handoff-${checkpoint.checkpointId}-`)
|
|
19480
19798
|
);
|
|
19481
|
-
const packPath =
|
|
19482
|
-
const indexPath =
|
|
19799
|
+
const packPath = join10(tmpDir, `${checkpoint.checkpointId}.pack`);
|
|
19800
|
+
const indexPath = join10(tmpDir, `${checkpoint.checkpointId}.index`);
|
|
19483
19801
|
try {
|
|
19484
19802
|
const downloads = await this.downloadArtifacts([
|
|
19485
19803
|
{
|
|
@@ -19858,9 +20176,9 @@ var PostHogAPIClient = class {
|
|
|
19858
20176
|
|
|
19859
20177
|
// src/adapters/claude/session/jsonl-hydration.ts
|
|
19860
20178
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
19861
|
-
import * as
|
|
19862
|
-
import * as
|
|
19863
|
-
import * as
|
|
20179
|
+
import * as fs12 from "fs/promises";
|
|
20180
|
+
import * as os7 from "os";
|
|
20181
|
+
import * as path15 from "path";
|
|
19864
20182
|
var CHARS_PER_TOKEN = 4;
|
|
19865
20183
|
var DEFAULT_MAX_TOKENS = 15e4;
|
|
19866
20184
|
function estimateTurnTokens(turn) {
|
|
@@ -20167,9 +20485,9 @@ ${toolSummary}`);
|
|
|
20167
20485
|
}
|
|
20168
20486
|
|
|
20169
20487
|
// src/session-log-writer.ts
|
|
20170
|
-
import
|
|
20488
|
+
import fs13 from "fs";
|
|
20171
20489
|
import fsp from "fs/promises";
|
|
20172
|
-
import
|
|
20490
|
+
import path16 from "path";
|
|
20173
20491
|
var SessionLogWriter = class _SessionLogWriter {
|
|
20174
20492
|
static FLUSH_DEBOUNCE_MS = 500;
|
|
20175
20493
|
static FLUSH_MAX_INTERVAL_MS = 5e3;
|
|
@@ -20205,13 +20523,13 @@ var SessionLogWriter = class _SessionLogWriter {
|
|
|
20205
20523
|
this.sessions.set(sessionId, { context, currentTurnMessages: [] });
|
|
20206
20524
|
this.lastFlushAttemptTime.set(sessionId, Date.now());
|
|
20207
20525
|
if (this.localCachePath) {
|
|
20208
|
-
const sessionDir =
|
|
20526
|
+
const sessionDir = path16.join(
|
|
20209
20527
|
this.localCachePath,
|
|
20210
20528
|
"sessions",
|
|
20211
20529
|
context.runId
|
|
20212
20530
|
);
|
|
20213
20531
|
try {
|
|
20214
|
-
|
|
20532
|
+
fs13.mkdirSync(sessionDir, { recursive: true });
|
|
20215
20533
|
} catch (error) {
|
|
20216
20534
|
this.logger.warn("Failed to create local cache directory", {
|
|
20217
20535
|
sessionDir,
|
|
@@ -20463,14 +20781,14 @@ var SessionLogWriter = class _SessionLogWriter {
|
|
|
20463
20781
|
if (!this.localCachePath) return;
|
|
20464
20782
|
const session = this.sessions.get(sessionId);
|
|
20465
20783
|
if (!session) return;
|
|
20466
|
-
const logPath =
|
|
20784
|
+
const logPath = path16.join(
|
|
20467
20785
|
this.localCachePath,
|
|
20468
20786
|
"sessions",
|
|
20469
20787
|
session.context.runId,
|
|
20470
20788
|
"logs.ndjson"
|
|
20471
20789
|
);
|
|
20472
20790
|
try {
|
|
20473
|
-
|
|
20791
|
+
fs13.appendFileSync(logPath, `${JSON.stringify(entry)}
|
|
20474
20792
|
`);
|
|
20475
20793
|
} catch (error) {
|
|
20476
20794
|
this.logger.warn("Failed to write to local cache", {
|
|
@@ -20482,13 +20800,13 @@ var SessionLogWriter = class _SessionLogWriter {
|
|
|
20482
20800
|
}
|
|
20483
20801
|
}
|
|
20484
20802
|
static async cleanupOldSessions(localCachePath) {
|
|
20485
|
-
const sessionsDir =
|
|
20803
|
+
const sessionsDir = path16.join(localCachePath, "sessions");
|
|
20486
20804
|
let deleted = 0;
|
|
20487
20805
|
try {
|
|
20488
20806
|
const entries = await fsp.readdir(sessionsDir);
|
|
20489
20807
|
const now = Date.now();
|
|
20490
20808
|
for (const entry of entries) {
|
|
20491
|
-
const entryPath =
|
|
20809
|
+
const entryPath = path16.join(sessionsDir, entry);
|
|
20492
20810
|
try {
|
|
20493
20811
|
const stats = await fsp.stat(entryPath);
|
|
20494
20812
|
if (stats.isDirectory() && now - stats.birthtimeMs > _SessionLogWriter.SESSIONS_MAX_AGE_MS) {
|
|
@@ -20526,7 +20844,7 @@ async function getAgentshVersion() {
|
|
|
20526
20844
|
}
|
|
20527
20845
|
async function resolveAgentshRuntimeInfo({
|
|
20528
20846
|
sessionIdPath = AGENTSH_SESSION_ID_FILE,
|
|
20529
|
-
readSessionId = async (
|
|
20847
|
+
readSessionId = async (path17) => readFile5(path17, "utf8"),
|
|
20530
20848
|
getVersion = getAgentshVersion
|
|
20531
20849
|
} = {}) {
|
|
20532
20850
|
let sessionId;
|
|
@@ -21752,7 +22070,7 @@ Continue from where you left off. The user is waiting for your response.`
|
|
|
21752
22070
|
throw new Error(`Failed to download artifact ${artifact.name}`);
|
|
21753
22071
|
}
|
|
21754
22072
|
const safeName = this.getSafeArtifactName(artifact.name);
|
|
21755
|
-
const artifactDir =
|
|
22073
|
+
const artifactDir = join12(
|
|
21756
22074
|
this.config.repositoryPath ?? "/tmp/workspace",
|
|
21757
22075
|
".posthog",
|
|
21758
22076
|
"attachments",
|
|
@@ -21760,7 +22078,7 @@ Continue from where you left off. The user is waiting for your response.`
|
|
|
21760
22078
|
artifact.id ?? safeName
|
|
21761
22079
|
);
|
|
21762
22080
|
await mkdir4(artifactDir, { recursive: true });
|
|
21763
|
-
const artifactPath =
|
|
22081
|
+
const artifactPath = join12(artifactDir, safeName);
|
|
21764
22082
|
await writeFile4(artifactPath, Buffer.from(data));
|
|
21765
22083
|
return resourceLink(pathToFileURL(artifactPath).toString(), artifact.name, {
|
|
21766
22084
|
...artifact.content_type ? { mimeType: artifact.content_type } : {},
|