@posthog/agent 2.3.510 → 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 +131 -104
- 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 +360 -139
- package/dist/server/agent-server.js.map +1 -1
- package/dist/server/bin.cjs +342 -121
- package/dist/server/bin.cjs.map +1 -1
- package/package.json +2 -2
- 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
|
@@ -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() {
|
|
@@ -15825,6 +15825,31 @@ function getAvailableSlashCommands(commands) {
|
|
|
15825
15825
|
}
|
|
15826
15826
|
|
|
15827
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
|
+
}
|
|
15828
15853
|
function parseMcpServers(params) {
|
|
15829
15854
|
const mcpServers = {};
|
|
15830
15855
|
if (!Array.isArray(params.mcpServers)) {
|
|
@@ -15958,9 +15983,9 @@ function resolveModelPreference(preference, options) {
|
|
|
15958
15983
|
|
|
15959
15984
|
// src/adapters/claude/session/options.ts
|
|
15960
15985
|
import { spawn as spawn2 } from "child_process";
|
|
15961
|
-
import * as
|
|
15962
|
-
import * as
|
|
15963
|
-
import * as
|
|
15986
|
+
import * as fs7 from "fs";
|
|
15987
|
+
import * as os3 from "os";
|
|
15988
|
+
import * as path9 from "path";
|
|
15964
15989
|
|
|
15965
15990
|
// src/adapters/claude/session/instructions.ts
|
|
15966
15991
|
var BRANCH_NAMING = `
|
|
@@ -16011,8 +16036,9 @@ function buildSystemPrompt(customPrompt) {
|
|
|
16011
16036
|
}
|
|
16012
16037
|
return defaultPrompt;
|
|
16013
16038
|
}
|
|
16014
|
-
function buildMcpServers(userServers, acpServers) {
|
|
16039
|
+
function buildMcpServers(userServers, acpServers, projectScopedServers) {
|
|
16015
16040
|
return {
|
|
16041
|
+
...projectScopedServers,
|
|
16016
16042
|
...userServers || {},
|
|
16017
16043
|
...acpServers
|
|
16018
16044
|
};
|
|
@@ -16161,12 +16187,12 @@ function buildSpawnWrapper(sessionId, onProcessSpawned, onProcessExited, logger)
|
|
|
16161
16187
|
};
|
|
16162
16188
|
}
|
|
16163
16189
|
function ensureLocalSettings(cwd) {
|
|
16164
|
-
const claudeDir =
|
|
16165
|
-
const localSettingsPath =
|
|
16190
|
+
const claudeDir = path9.join(cwd, ".claude");
|
|
16191
|
+
const localSettingsPath = path9.join(claudeDir, "settings.local.json");
|
|
16166
16192
|
try {
|
|
16167
|
-
if (!
|
|
16168
|
-
|
|
16169
|
-
|
|
16193
|
+
if (!fs7.existsSync(localSettingsPath)) {
|
|
16194
|
+
fs7.mkdirSync(claudeDir, { recursive: true });
|
|
16195
|
+
fs7.writeFileSync(localSettingsPath, "{}\n", { flag: "wx" });
|
|
16170
16196
|
}
|
|
16171
16197
|
} catch {
|
|
16172
16198
|
}
|
|
@@ -16196,7 +16222,8 @@ function buildSessionOptions(params) {
|
|
|
16196
16222
|
},
|
|
16197
16223
|
mcpServers: buildMcpServers(
|
|
16198
16224
|
params.userProvidedOptions?.mcpServers,
|
|
16199
|
-
params.mcpServers
|
|
16225
|
+
params.mcpServers,
|
|
16226
|
+
loadUserClaudeJsonMcpServers(params.cwd, params.logger)
|
|
16200
16227
|
),
|
|
16201
16228
|
env: buildEnvironment(),
|
|
16202
16229
|
hooks: buildHooks(
|
|
@@ -16241,18 +16268,18 @@ function buildSessionOptions(params) {
|
|
|
16241
16268
|
return options;
|
|
16242
16269
|
}
|
|
16243
16270
|
function clearStatsigCache() {
|
|
16244
|
-
const statsigPath =
|
|
16245
|
-
process.env.CLAUDE_CONFIG_DIR ||
|
|
16271
|
+
const statsigPath = path9.join(
|
|
16272
|
+
process.env.CLAUDE_CONFIG_DIR || path9.join(os3.homedir(), ".claude"),
|
|
16246
16273
|
"statsig"
|
|
16247
16274
|
);
|
|
16248
|
-
|
|
16275
|
+
fs7.rm(statsigPath, { recursive: true, force: true }, () => {
|
|
16249
16276
|
});
|
|
16250
16277
|
}
|
|
16251
16278
|
|
|
16252
16279
|
// src/adapters/claude/session/settings.ts
|
|
16253
|
-
import * as
|
|
16254
|
-
import * as
|
|
16255
|
-
import * as
|
|
16280
|
+
import * as fs8 from "fs";
|
|
16281
|
+
import * as os4 from "os";
|
|
16282
|
+
import * as path10 from "path";
|
|
16256
16283
|
import { minimatch } from "minimatch";
|
|
16257
16284
|
|
|
16258
16285
|
// src/utils/async-mutex.ts
|
|
@@ -16333,13 +16360,13 @@ function parseRule(rule) {
|
|
|
16333
16360
|
function normalizePath(filePath, cwd) {
|
|
16334
16361
|
let resolved = filePath;
|
|
16335
16362
|
if (resolved.startsWith("~/")) {
|
|
16336
|
-
resolved =
|
|
16363
|
+
resolved = path10.join(os4.homedir(), resolved.slice(2));
|
|
16337
16364
|
} else if (resolved.startsWith("./")) {
|
|
16338
|
-
resolved =
|
|
16339
|
-
} else if (!
|
|
16340
|
-
resolved =
|
|
16365
|
+
resolved = path10.join(cwd, resolved.slice(2));
|
|
16366
|
+
} else if (!path10.isAbsolute(resolved)) {
|
|
16367
|
+
resolved = path10.join(cwd, resolved);
|
|
16341
16368
|
}
|
|
16342
|
-
return
|
|
16369
|
+
return path10.normalize(resolved).replace(/\\/g, "/");
|
|
16343
16370
|
}
|
|
16344
16371
|
function matchesGlob(pattern, filePath, cwd) {
|
|
16345
16372
|
const normalizedPattern = normalizePath(pattern, cwd);
|
|
@@ -16386,11 +16413,11 @@ function formatRule(rule) {
|
|
|
16386
16413
|
}
|
|
16387
16414
|
async function writeFileAtomic(filePath, data) {
|
|
16388
16415
|
const tmpPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
|
|
16389
|
-
await
|
|
16416
|
+
await fs8.promises.writeFile(tmpPath, data);
|
|
16390
16417
|
try {
|
|
16391
|
-
await
|
|
16418
|
+
await fs8.promises.rename(tmpPath, filePath);
|
|
16392
16419
|
} catch (error) {
|
|
16393
|
-
await
|
|
16420
|
+
await fs8.promises.rm(tmpPath, { force: true });
|
|
16394
16421
|
throw error;
|
|
16395
16422
|
}
|
|
16396
16423
|
}
|
|
@@ -16399,7 +16426,7 @@ async function loadSettingsFile(filePath) {
|
|
|
16399
16426
|
return {};
|
|
16400
16427
|
}
|
|
16401
16428
|
try {
|
|
16402
|
-
const content = await
|
|
16429
|
+
const content = await fs8.promises.readFile(filePath, "utf-8");
|
|
16403
16430
|
return JSON.parse(content);
|
|
16404
16431
|
} catch (error) {
|
|
16405
16432
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
@@ -16414,7 +16441,7 @@ async function loadSettingsFile(filePath) {
|
|
|
16414
16441
|
}
|
|
16415
16442
|
async function readSettingsFileForUpdate(filePath) {
|
|
16416
16443
|
try {
|
|
16417
|
-
const content = await
|
|
16444
|
+
const content = await fs8.promises.readFile(filePath, "utf-8");
|
|
16418
16445
|
return JSON.parse(content);
|
|
16419
16446
|
} catch (error) {
|
|
16420
16447
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
@@ -16460,11 +16487,11 @@ var SettingsManager = class {
|
|
|
16460
16487
|
return this.initPromise;
|
|
16461
16488
|
}
|
|
16462
16489
|
getUserSettingsPath() {
|
|
16463
|
-
const configDir = process.env.CLAUDE_CONFIG_DIR ||
|
|
16464
|
-
return
|
|
16490
|
+
const configDir = process.env.CLAUDE_CONFIG_DIR || path10.join(os4.homedir(), ".claude");
|
|
16491
|
+
return path10.join(configDir, "settings.json");
|
|
16465
16492
|
}
|
|
16466
16493
|
getProjectSettingsPath() {
|
|
16467
|
-
return
|
|
16494
|
+
return path10.join(this.cwd, ".claude", "settings.json");
|
|
16468
16495
|
}
|
|
16469
16496
|
/**
|
|
16470
16497
|
* Local settings are anchored to the primary worktree so every worktree of
|
|
@@ -16472,7 +16499,7 @@ var SettingsManager = class {
|
|
|
16472
16499
|
* avoids re-prompting for the same permission in every worktree.
|
|
16473
16500
|
*/
|
|
16474
16501
|
getLocalSettingsPath() {
|
|
16475
|
-
return
|
|
16502
|
+
return path10.join(this.repoRoot, ".claude", "settings.local.json");
|
|
16476
16503
|
}
|
|
16477
16504
|
async loadAllSettings() {
|
|
16478
16505
|
this.repoRoot = await resolveMainRepoPath(this.cwd);
|
|
@@ -16599,7 +16626,7 @@ var SettingsManager = class {
|
|
|
16599
16626
|
}
|
|
16600
16627
|
permissions.allow = Array.from(current2);
|
|
16601
16628
|
const next = { ...existing, permissions };
|
|
16602
|
-
await
|
|
16629
|
+
await fs8.promises.mkdir(path10.dirname(filePath), { recursive: true });
|
|
16603
16630
|
await writeFileAtomic(filePath, `${JSON.stringify(next, null, 2)}
|
|
16604
16631
|
`);
|
|
16605
16632
|
this.localSettings = next;
|
|
@@ -16632,7 +16659,7 @@ var SettingsManager = class {
|
|
|
16632
16659
|
...existing,
|
|
16633
16660
|
posthogApprovedExecTools: Array.from(current2)
|
|
16634
16661
|
};
|
|
16635
|
-
await
|
|
16662
|
+
await fs8.promises.mkdir(path10.dirname(filePath), { recursive: true });
|
|
16636
16663
|
await writeFileAtomic(filePath, `${JSON.stringify(next, null, 2)}
|
|
16637
16664
|
`);
|
|
16638
16665
|
this.localSettings = next;
|
|
@@ -16738,7 +16765,7 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
16738
16765
|
};
|
|
16739
16766
|
}
|
|
16740
16767
|
async newSession(params) {
|
|
16741
|
-
if (
|
|
16768
|
+
if (fs9.existsSync(path11.resolve(os5.homedir(), ".claude.json.backup")) && !fs9.existsSync(path11.resolve(os5.homedir(), ".claude.json"))) {
|
|
16742
16769
|
throw RequestError2.authRequired();
|
|
16743
16770
|
}
|
|
16744
16771
|
const response = await this.createSession(params, {
|
|
@@ -17981,9 +18008,9 @@ function resetUsage(state) {
|
|
|
17981
18008
|
}
|
|
17982
18009
|
|
|
17983
18010
|
// src/adapters/codex/settings.ts
|
|
17984
|
-
import * as
|
|
17985
|
-
import * as
|
|
17986
|
-
import * as
|
|
18011
|
+
import * as fs10 from "fs";
|
|
18012
|
+
import * as os6 from "os";
|
|
18013
|
+
import * as path12 from "path";
|
|
17987
18014
|
var CodexSettingsManager = class {
|
|
17988
18015
|
cwd;
|
|
17989
18016
|
settings = { mcpServerNames: [] };
|
|
@@ -17994,12 +18021,12 @@ var CodexSettingsManager = class {
|
|
|
17994
18021
|
async initialize() {
|
|
17995
18022
|
}
|
|
17996
18023
|
getConfigPath() {
|
|
17997
|
-
return
|
|
18024
|
+
return path12.join(os6.homedir(), ".codex", "config.toml");
|
|
17998
18025
|
}
|
|
17999
18026
|
loadSettings() {
|
|
18000
18027
|
const configPath = this.getConfigPath();
|
|
18001
18028
|
try {
|
|
18002
|
-
const content =
|
|
18029
|
+
const content = fs10.readFileSync(configPath, "utf-8");
|
|
18003
18030
|
this.settings = parseCodexToml(content, this.cwd);
|
|
18004
18031
|
} catch {
|
|
18005
18032
|
this.settings = { mcpServerNames: [] };
|
|
@@ -18770,18 +18797,18 @@ function createCodexConnection(config) {
|
|
|
18770
18797
|
// src/handoff-checkpoint.ts
|
|
18771
18798
|
import { mkdtemp as mkdtemp2, readFile as readFile4, rm as rm4, writeFile as writeFile2 } from "fs/promises";
|
|
18772
18799
|
import { tmpdir as tmpdir2 } from "os";
|
|
18773
|
-
import { dirname as dirname6, join as
|
|
18800
|
+
import { dirname as dirname6, join as join10 } from "path";
|
|
18774
18801
|
|
|
18775
18802
|
// ../git/dist/handoff.js
|
|
18776
18803
|
import { spawn as spawn4 } from "child_process";
|
|
18777
18804
|
import { copyFile, mkdtemp, readFile as readFile3, rm as rm3, stat as stat3 } from "fs/promises";
|
|
18778
18805
|
import { tmpdir } from "os";
|
|
18779
|
-
import
|
|
18806
|
+
import path14 from "path";
|
|
18780
18807
|
|
|
18781
18808
|
// ../git/dist/sagas/checkpoint.js
|
|
18782
18809
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
18783
|
-
import * as
|
|
18784
|
-
import * as
|
|
18810
|
+
import * as fs11 from "fs/promises";
|
|
18811
|
+
import * as path13 from "path";
|
|
18785
18812
|
|
|
18786
18813
|
// ../shared/dist/index.js
|
|
18787
18814
|
var CLOUD_PROMPT_PREFIX = "__twig_cloud_prompt_v1__:";
|
|
@@ -19054,12 +19081,12 @@ async function getGitBusyState(git) {
|
|
|
19054
19081
|
const toplevel = (await git.raw(["rev-parse", "--show-toplevel"])).trim();
|
|
19055
19082
|
const resolveGitPath = async (gitPath) => {
|
|
19056
19083
|
const relative = (await git.raw(["rev-parse", "--git-path", gitPath])).trim();
|
|
19057
|
-
return
|
|
19084
|
+
return path13.isAbsolute(relative) ? relative : path13.resolve(toplevel, relative);
|
|
19058
19085
|
};
|
|
19059
19086
|
const pathExists = async (gitPath) => {
|
|
19060
19087
|
const resolved = await resolveGitPath(gitPath);
|
|
19061
19088
|
try {
|
|
19062
|
-
await
|
|
19089
|
+
await fs11.access(resolved);
|
|
19063
19090
|
return true;
|
|
19064
19091
|
} catch {
|
|
19065
19092
|
return false;
|
|
@@ -19068,7 +19095,7 @@ async function getGitBusyState(git) {
|
|
|
19068
19095
|
const dirExists = async (gitPath) => {
|
|
19069
19096
|
const resolved = await resolveGitPath(gitPath);
|
|
19070
19097
|
try {
|
|
19071
|
-
const stat4 = await
|
|
19098
|
+
const stat4 = await fs11.stat(resolved);
|
|
19072
19099
|
return stat4.isDirectory();
|
|
19073
19100
|
} catch {
|
|
19074
19101
|
return false;
|
|
@@ -19088,6 +19115,7 @@ async function getGitBusyState(git) {
|
|
|
19088
19115
|
}
|
|
19089
19116
|
return { busy: false };
|
|
19090
19117
|
}
|
|
19118
|
+
var MAX_WORKTREE_FILE_BYTES = 1024 * 1024;
|
|
19091
19119
|
async function createWorktreeTree(git, baseDir, head) {
|
|
19092
19120
|
const { tempGit, tempIndexPath } = await createTempIndexGit(git, baseDir, "checkpoint-worktree");
|
|
19093
19121
|
try {
|
|
@@ -19097,13 +19125,85 @@ async function createWorktreeTree(git, baseDir, head) {
|
|
|
19097
19125
|
await tempGit.raw(["read-tree", "--empty"]);
|
|
19098
19126
|
}
|
|
19099
19127
|
await tempGit.raw(["add", "-A", "--", "."]);
|
|
19128
|
+
await reconcileLargeBlobs(tempGit, head, MAX_WORKTREE_FILE_BYTES);
|
|
19100
19129
|
const treeHash = await tempGit.raw(["write-tree"]);
|
|
19101
19130
|
return treeHash.trim();
|
|
19102
19131
|
} finally {
|
|
19103
|
-
await
|
|
19132
|
+
await fs11.rm(tempIndexPath, { force: true }).catch(() => {
|
|
19104
19133
|
});
|
|
19105
19134
|
}
|
|
19106
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
|
+
}
|
|
19107
19207
|
async function createMetaTree(git, baseDir, indexTree, worktreeTree) {
|
|
19108
19208
|
const { tempGit, tempIndexPath } = await createTempIndexGit(git, baseDir, "checkpoint-meta");
|
|
19109
19209
|
try {
|
|
@@ -19127,7 +19227,7 @@ async function createMetaTree(git, baseDir, indexTree, worktreeTree) {
|
|
|
19127
19227
|
const metaTree = await tempGit.raw(["write-tree"]);
|
|
19128
19228
|
return metaTree.trim();
|
|
19129
19229
|
} finally {
|
|
19130
|
-
await
|
|
19230
|
+
await fs11.rm(tempIndexPath, { force: true }).catch(() => {
|
|
19131
19231
|
});
|
|
19132
19232
|
}
|
|
19133
19233
|
}
|
|
@@ -19144,12 +19244,12 @@ function formatCheckpointMessage(meta) {
|
|
|
19144
19244
|
async function getGitCommonDir(git, baseDir) {
|
|
19145
19245
|
const raw = await git.raw(["rev-parse", "--git-common-dir"]);
|
|
19146
19246
|
const dir = raw.trim() || ".git";
|
|
19147
|
-
return
|
|
19247
|
+
return path13.isAbsolute(dir) ? dir : path13.resolve(baseDir, dir);
|
|
19148
19248
|
}
|
|
19149
19249
|
async function createTempIndexGit(git, baseDir, label) {
|
|
19150
|
-
const tmpDir =
|
|
19151
|
-
await
|
|
19152
|
-
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()}`);
|
|
19153
19253
|
const tempGit = createGitClient(baseDir).env({
|
|
19154
19254
|
...process.env,
|
|
19155
19255
|
GIT_INDEX_FILE: tempIndexPath
|
|
@@ -19176,6 +19276,7 @@ async function deleteCheckpoint(git, checkpointId) {
|
|
|
19176
19276
|
// ../git/dist/handoff.js
|
|
19177
19277
|
var HANDOFF_HEAD_REF_PREFIX = "refs/posthog-code-handoff/head/";
|
|
19178
19278
|
var CHECKPOINT_REF_PREFIX2 = "refs/posthog-code-checkpoint/";
|
|
19279
|
+
var MAX_HANDOFF_FILE_BYTES = 1024 * 1024;
|
|
19179
19280
|
var GitHandoffTracker = class {
|
|
19180
19281
|
repositoryPath;
|
|
19181
19282
|
logger;
|
|
@@ -19183,7 +19284,7 @@ var GitHandoffTracker = class {
|
|
|
19183
19284
|
this.repositoryPath = config.repositoryPath;
|
|
19184
19285
|
this.logger = config.logger;
|
|
19185
19286
|
}
|
|
19186
|
-
async captureForHandoff(
|
|
19287
|
+
async captureForHandoff(localGitState) {
|
|
19187
19288
|
const captureSaga = new CaptureCheckpointSaga(this.logger);
|
|
19188
19289
|
const result = await captureSaga.run({ baseDir: this.repositoryPath });
|
|
19189
19290
|
if (!result.success) {
|
|
@@ -19193,17 +19294,20 @@ var GitHandoffTracker = class {
|
|
|
19193
19294
|
const git = createGitClient(this.repositoryPath);
|
|
19194
19295
|
const tempDir = await this.createTempDir(checkpoint.checkpointId);
|
|
19195
19296
|
const checkpointRef = `${CHECKPOINT_REF_PREFIX2}${checkpoint.checkpointId}`;
|
|
19196
|
-
const packRefs = [
|
|
19197
|
-
checkpoint.head,
|
|
19198
|
-
checkpoint.indexTree,
|
|
19199
|
-
checkpoint.worktreeTree
|
|
19200
|
-
].filter((ref) => !!ref);
|
|
19201
|
-
const headRef = checkpoint.head ? `${HANDOFF_HEAD_REF_PREFIX}${checkpoint.checkpointId}` : void 0;
|
|
19202
|
-
const packPrefix = path13.join(tempDir, checkpoint.checkpointId);
|
|
19203
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);
|
|
19204
19308
|
const [headPack, indexFile, tracking] = await Promise.all([
|
|
19205
19309
|
this.captureObjectPack(packPrefix, packRefs),
|
|
19206
|
-
this.
|
|
19310
|
+
this.statFileArtifact(reconciledIndex.indexFilePath),
|
|
19207
19311
|
getTrackingMetadata(git, checkpoint.branch)
|
|
19208
19312
|
]);
|
|
19209
19313
|
return {
|
|
@@ -19214,7 +19318,7 @@ var GitHandoffTracker = class {
|
|
|
19214
19318
|
headRef,
|
|
19215
19319
|
head: checkpoint.head,
|
|
19216
19320
|
branch: checkpoint.branch,
|
|
19217
|
-
indexTree:
|
|
19321
|
+
indexTree: reconciledIndex.indexTree,
|
|
19218
19322
|
worktreeTree: checkpoint.worktreeTree,
|
|
19219
19323
|
timestamp: checkpoint.timestamp,
|
|
19220
19324
|
upstreamRemote: tracking.upstreamRemote,
|
|
@@ -19234,6 +19338,7 @@ var GitHandoffTracker = class {
|
|
|
19234
19338
|
const { checkpoint, headPackPath, indexPath, localGitState, onDivergedBranch } = input;
|
|
19235
19339
|
const git = createGitClient(this.repositoryPath);
|
|
19236
19340
|
if (headPackPath) {
|
|
19341
|
+
await this.ensureBaselineForApply(git, checkpoint, localGitState);
|
|
19237
19342
|
await this.unpackPackFile(headPackPath);
|
|
19238
19343
|
}
|
|
19239
19344
|
if (checkpoint.branch && checkpoint.head) {
|
|
@@ -19272,14 +19377,89 @@ var GitHandoffTracker = class {
|
|
|
19272
19377
|
});
|
|
19273
19378
|
return { path: packPath, rawBytes };
|
|
19274
19379
|
}
|
|
19275
|
-
async
|
|
19276
|
-
const
|
|
19277
|
-
const
|
|
19278
|
-
await copyFile(
|
|
19279
|
-
|
|
19280
|
-
|
|
19281
|
-
|
|
19282
|
-
}
|
|
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) };
|
|
19283
19463
|
}
|
|
19284
19464
|
async restoreIndexFile(git, indexPath) {
|
|
19285
19465
|
const gitIndexPath = await this.getGitPath(git, "index");
|
|
@@ -19307,6 +19487,20 @@ var GitHandoffTracker = class {
|
|
|
19307
19487
|
shouldRestoreTracking(branchStatus2, localGitState, tracking) {
|
|
19308
19488
|
return branchStatus2.kind === "missing" || !hasTrackingConfig(localGitState) && (tracking.upstreamRemote !== null || tracking.upstreamMergeRef !== null);
|
|
19309
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
|
+
}
|
|
19310
19504
|
async ensureRemoteForTracking(git, tracking) {
|
|
19311
19505
|
if (!tracking.upstreamRemote || !tracking.remoteUrl)
|
|
19312
19506
|
return;
|
|
@@ -19407,7 +19601,7 @@ var GitHandoffTracker = class {
|
|
|
19407
19601
|
async getGitPath(git, gitPath) {
|
|
19408
19602
|
const raw = await git.raw(["rev-parse", "--git-path", gitPath]);
|
|
19409
19603
|
const resolved = raw.trim();
|
|
19410
|
-
return
|
|
19604
|
+
return path14.isAbsolute(resolved) ? resolved : path14.resolve(this.repositoryPath, resolved);
|
|
19411
19605
|
}
|
|
19412
19606
|
async getFileSize(filePath) {
|
|
19413
19607
|
return (await stat3(filePath)).size;
|
|
@@ -19443,6 +19637,31 @@ var GitHandoffTracker = class {
|
|
|
19443
19637
|
});
|
|
19444
19638
|
});
|
|
19445
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
|
+
}
|
|
19446
19665
|
runGitProcess(args2, input) {
|
|
19447
19666
|
return new Promise((resolve7, reject) => {
|
|
19448
19667
|
const child = spawn4("git", args2, {
|
|
@@ -19465,12 +19684,14 @@ var GitHandoffTracker = class {
|
|
|
19465
19684
|
}
|
|
19466
19685
|
reject(new Error(stderr || `git ${args2.join(" ")} failed with code ${code}`));
|
|
19467
19686
|
});
|
|
19687
|
+
child.stdin.on("error", () => {
|
|
19688
|
+
});
|
|
19468
19689
|
child.stdin.end(input);
|
|
19469
19690
|
});
|
|
19470
19691
|
}
|
|
19471
19692
|
};
|
|
19472
19693
|
function joinTempPrefix(checkpointId) {
|
|
19473
|
-
return
|
|
19694
|
+
return path14.join(tmpdir(), `posthog-code-handoff-${checkpointId}-`);
|
|
19474
19695
|
}
|
|
19475
19696
|
async function getCurrentBranchName(git) {
|
|
19476
19697
|
try {
|
|
@@ -19573,10 +19794,10 @@ var HandoffCheckpointTracker = class {
|
|
|
19573
19794
|
}
|
|
19574
19795
|
const gitTracker = this.createGitTracker();
|
|
19575
19796
|
const tmpDir = await mkdtemp2(
|
|
19576
|
-
|
|
19797
|
+
join10(tmpdir2(), `posthog-code-handoff-${checkpoint.checkpointId}-`)
|
|
19577
19798
|
);
|
|
19578
|
-
const packPath =
|
|
19579
|
-
const indexPath =
|
|
19799
|
+
const packPath = join10(tmpDir, `${checkpoint.checkpointId}.pack`);
|
|
19800
|
+
const indexPath = join10(tmpDir, `${checkpoint.checkpointId}.index`);
|
|
19580
19801
|
try {
|
|
19581
19802
|
const downloads = await this.downloadArtifacts([
|
|
19582
19803
|
{
|
|
@@ -19955,9 +20176,9 @@ var PostHogAPIClient = class {
|
|
|
19955
20176
|
|
|
19956
20177
|
// src/adapters/claude/session/jsonl-hydration.ts
|
|
19957
20178
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
19958
|
-
import * as
|
|
19959
|
-
import * as
|
|
19960
|
-
import * as
|
|
20179
|
+
import * as fs12 from "fs/promises";
|
|
20180
|
+
import * as os7 from "os";
|
|
20181
|
+
import * as path15 from "path";
|
|
19961
20182
|
var CHARS_PER_TOKEN = 4;
|
|
19962
20183
|
var DEFAULT_MAX_TOKENS = 15e4;
|
|
19963
20184
|
function estimateTurnTokens(turn) {
|
|
@@ -20264,9 +20485,9 @@ ${toolSummary}`);
|
|
|
20264
20485
|
}
|
|
20265
20486
|
|
|
20266
20487
|
// src/session-log-writer.ts
|
|
20267
|
-
import
|
|
20488
|
+
import fs13 from "fs";
|
|
20268
20489
|
import fsp from "fs/promises";
|
|
20269
|
-
import
|
|
20490
|
+
import path16 from "path";
|
|
20270
20491
|
var SessionLogWriter = class _SessionLogWriter {
|
|
20271
20492
|
static FLUSH_DEBOUNCE_MS = 500;
|
|
20272
20493
|
static FLUSH_MAX_INTERVAL_MS = 5e3;
|
|
@@ -20302,13 +20523,13 @@ var SessionLogWriter = class _SessionLogWriter {
|
|
|
20302
20523
|
this.sessions.set(sessionId, { context, currentTurnMessages: [] });
|
|
20303
20524
|
this.lastFlushAttemptTime.set(sessionId, Date.now());
|
|
20304
20525
|
if (this.localCachePath) {
|
|
20305
|
-
const sessionDir =
|
|
20526
|
+
const sessionDir = path16.join(
|
|
20306
20527
|
this.localCachePath,
|
|
20307
20528
|
"sessions",
|
|
20308
20529
|
context.runId
|
|
20309
20530
|
);
|
|
20310
20531
|
try {
|
|
20311
|
-
|
|
20532
|
+
fs13.mkdirSync(sessionDir, { recursive: true });
|
|
20312
20533
|
} catch (error) {
|
|
20313
20534
|
this.logger.warn("Failed to create local cache directory", {
|
|
20314
20535
|
sessionDir,
|
|
@@ -20560,14 +20781,14 @@ var SessionLogWriter = class _SessionLogWriter {
|
|
|
20560
20781
|
if (!this.localCachePath) return;
|
|
20561
20782
|
const session = this.sessions.get(sessionId);
|
|
20562
20783
|
if (!session) return;
|
|
20563
|
-
const logPath =
|
|
20784
|
+
const logPath = path16.join(
|
|
20564
20785
|
this.localCachePath,
|
|
20565
20786
|
"sessions",
|
|
20566
20787
|
session.context.runId,
|
|
20567
20788
|
"logs.ndjson"
|
|
20568
20789
|
);
|
|
20569
20790
|
try {
|
|
20570
|
-
|
|
20791
|
+
fs13.appendFileSync(logPath, `${JSON.stringify(entry)}
|
|
20571
20792
|
`);
|
|
20572
20793
|
} catch (error) {
|
|
20573
20794
|
this.logger.warn("Failed to write to local cache", {
|
|
@@ -20579,13 +20800,13 @@ var SessionLogWriter = class _SessionLogWriter {
|
|
|
20579
20800
|
}
|
|
20580
20801
|
}
|
|
20581
20802
|
static async cleanupOldSessions(localCachePath) {
|
|
20582
|
-
const sessionsDir =
|
|
20803
|
+
const sessionsDir = path16.join(localCachePath, "sessions");
|
|
20583
20804
|
let deleted = 0;
|
|
20584
20805
|
try {
|
|
20585
20806
|
const entries = await fsp.readdir(sessionsDir);
|
|
20586
20807
|
const now = Date.now();
|
|
20587
20808
|
for (const entry of entries) {
|
|
20588
|
-
const entryPath =
|
|
20809
|
+
const entryPath = path16.join(sessionsDir, entry);
|
|
20589
20810
|
try {
|
|
20590
20811
|
const stats = await fsp.stat(entryPath);
|
|
20591
20812
|
if (stats.isDirectory() && now - stats.birthtimeMs > _SessionLogWriter.SESSIONS_MAX_AGE_MS) {
|
|
@@ -20623,7 +20844,7 @@ async function getAgentshVersion() {
|
|
|
20623
20844
|
}
|
|
20624
20845
|
async function resolveAgentshRuntimeInfo({
|
|
20625
20846
|
sessionIdPath = AGENTSH_SESSION_ID_FILE,
|
|
20626
|
-
readSessionId = async (
|
|
20847
|
+
readSessionId = async (path17) => readFile5(path17, "utf8"),
|
|
20627
20848
|
getVersion = getAgentshVersion
|
|
20628
20849
|
} = {}) {
|
|
20629
20850
|
let sessionId;
|
|
@@ -21849,7 +22070,7 @@ Continue from where you left off. The user is waiting for your response.`
|
|
|
21849
22070
|
throw new Error(`Failed to download artifact ${artifact.name}`);
|
|
21850
22071
|
}
|
|
21851
22072
|
const safeName = this.getSafeArtifactName(artifact.name);
|
|
21852
|
-
const artifactDir =
|
|
22073
|
+
const artifactDir = join12(
|
|
21853
22074
|
this.config.repositoryPath ?? "/tmp/workspace",
|
|
21854
22075
|
".posthog",
|
|
21855
22076
|
"attachments",
|
|
@@ -21857,7 +22078,7 @@ Continue from where you left off. The user is waiting for your response.`
|
|
|
21857
22078
|
artifact.id ?? safeName
|
|
21858
22079
|
);
|
|
21859
22080
|
await mkdir4(artifactDir, { recursive: true });
|
|
21860
|
-
const artifactPath =
|
|
22081
|
+
const artifactPath = join12(artifactDir, safeName);
|
|
21861
22082
|
await writeFile4(artifactPath, Buffer.from(data));
|
|
21862
22083
|
return resourceLink(pathToFileURL(artifactPath).toString(), artifact.name, {
|
|
21863
22084
|
...artifact.content_type ? { mimeType: artifact.content_type } : {},
|