@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.
@@ -509,7 +509,7 @@ var require_has_flag = __commonJS({
509
509
  var require_supports_color = __commonJS({
510
510
  "../../node_modules/supports-color/index.js"(exports2, module2) {
511
511
  "use strict";
512
- var os7 = require("os");
512
+ var os8 = require("os");
513
513
  var tty = require("tty");
514
514
  var hasFlag = require_has_flag();
515
515
  var { env } = process;
@@ -557,7 +557,7 @@ var require_supports_color = __commonJS({
557
557
  return min;
558
558
  }
559
559
  if (process.platform === "win32") {
560
- const osRelease = os7.release().split(".");
560
+ const osRelease = os8.release().split(".");
561
561
  if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
562
562
  return Number(osRelease[2]) >= 14931 ? 3 : 2;
563
563
  }
@@ -805,10 +805,10 @@ var require_src2 = __commonJS({
805
805
  var fs_1 = require("fs");
806
806
  var debug_1 = __importDefault(require_src());
807
807
  var log = debug_1.default("@kwsites/file-exists");
808
- function check(path16, isFile2, isDirectory) {
809
- log(`checking %s`, path16);
808
+ function check(path17, isFile2, isDirectory) {
809
+ log(`checking %s`, path17);
810
810
  try {
811
- const stat4 = fs_1.statSync(path16);
811
+ const stat4 = fs_1.statSync(path17);
812
812
  if (stat4.isFile() && isFile2) {
813
813
  log(`[OK] path represents a file`);
814
814
  return true;
@@ -828,8 +828,8 @@ var require_src2 = __commonJS({
828
828
  throw e;
829
829
  }
830
830
  }
831
- function exists2(path16, type = exports2.READABLE) {
832
- return check(path16, (type & exports2.FILE) > 0, (type & exports2.FOLDER) > 0);
831
+ function exists2(path17, type = exports2.READABLE) {
832
+ return check(path17, (type & exports2.FILE) > 0, (type & exports2.FOLDER) > 0);
833
833
  }
834
834
  exports2.exists = exists2;
835
835
  exports2.FILE = 1;
@@ -925,11 +925,11 @@ var require_tree_sitter = __commonJS({
925
925
  throw toThrow;
926
926
  };
927
927
  var scriptDirectory = "";
928
- function locateFile(path16) {
928
+ function locateFile(path17) {
929
929
  if (Module["locateFile"]) {
930
- return Module["locateFile"](path16, scriptDirectory);
930
+ return Module["locateFile"](path17, scriptDirectory);
931
931
  }
932
- return scriptDirectory + path16;
932
+ return scriptDirectory + path17;
933
933
  }
934
934
  var readAsync, readBinary;
935
935
  if (ENVIRONMENT_IS_NODE) {
@@ -3450,8 +3450,8 @@ var require_tree_sitter = __commonJS({
3450
3450
  } else {
3451
3451
  const url = input;
3452
3452
  if (typeof process !== "undefined" && process.versions && process.versions.node) {
3453
- const fs13 = require("fs");
3454
- bytes = Promise.resolve(fs13.readFileSync(url));
3453
+ const fs14 = require("fs");
3454
+ bytes = Promise.resolve(fs14.readFileSync(url));
3455
3455
  } else {
3456
3456
  bytes = fetch(url).then((response) => response.arrayBuffer().then((buffer) => {
3457
3457
  if (response.ok) {
@@ -3991,8 +3991,8 @@ function pathspec(...paths) {
3991
3991
  cache.set(key, paths);
3992
3992
  return key;
3993
3993
  }
3994
- function isPathSpec(path16) {
3995
- return path16 instanceof String && cache.has(path16);
3994
+ function isPathSpec(path17) {
3995
+ return path17 instanceof String && cache.has(path17);
3996
3996
  }
3997
3997
  function toPaths(pathSpec) {
3998
3998
  return cache.get(pathSpec) || [];
@@ -4081,8 +4081,8 @@ function toLinesWithContent(input = "", trimmed2 = true, separator = "\n") {
4081
4081
  function forEachLineWithContent(input, callback) {
4082
4082
  return toLinesWithContent(input, true).map((line) => callback(line));
4083
4083
  }
4084
- function folderExists(path16) {
4085
- return (0, import_file_exists.exists)(path16, import_file_exists.FOLDER);
4084
+ function folderExists(path17) {
4085
+ return (0, import_file_exists.exists)(path17, import_file_exists.FOLDER);
4086
4086
  }
4087
4087
  function append(target, item) {
4088
4088
  if (Array.isArray(target)) {
@@ -4486,8 +4486,8 @@ function checkIsRepoRootTask() {
4486
4486
  commands,
4487
4487
  format: "utf-8",
4488
4488
  onError,
4489
- parser(path16) {
4490
- return /^\.(git)?$/.test(path16.trim());
4489
+ parser(path17) {
4490
+ return /^\.(git)?$/.test(path17.trim());
4491
4491
  }
4492
4492
  };
4493
4493
  }
@@ -4921,11 +4921,11 @@ function parseGrep(grep) {
4921
4921
  const paths = /* @__PURE__ */ new Set();
4922
4922
  const results = {};
4923
4923
  forEachLineWithContent(grep, (input) => {
4924
- const [path16, line, preview] = input.split(NULL);
4925
- paths.add(path16);
4926
- (results[path16] = results[path16] || []).push({
4924
+ const [path17, line, preview] = input.split(NULL);
4925
+ paths.add(path17);
4926
+ (results[path17] = results[path17] || []).push({
4927
4927
  line: asNumber(line),
4928
- path: path16,
4928
+ path: path17,
4929
4929
  preview
4930
4930
  });
4931
4931
  });
@@ -5690,14 +5690,14 @@ var init_hash_object = __esm({
5690
5690
  init_task();
5691
5691
  }
5692
5692
  });
5693
- function parseInit(bare, path16, text2) {
5693
+ function parseInit(bare, path17, text2) {
5694
5694
  const response = String(text2).trim();
5695
5695
  let result;
5696
5696
  if (result = initResponseRegex.exec(response)) {
5697
- return new InitSummary(bare, path16, false, result[1]);
5697
+ return new InitSummary(bare, path17, false, result[1]);
5698
5698
  }
5699
5699
  if (result = reInitResponseRegex.exec(response)) {
5700
- return new InitSummary(bare, path16, true, result[1]);
5700
+ return new InitSummary(bare, path17, true, result[1]);
5701
5701
  }
5702
5702
  let gitDir = "";
5703
5703
  const tokens = response.split(" ");
@@ -5708,7 +5708,7 @@ function parseInit(bare, path16, text2) {
5708
5708
  break;
5709
5709
  }
5710
5710
  }
5711
- return new InitSummary(bare, path16, /^re/i.test(response), gitDir);
5711
+ return new InitSummary(bare, path17, /^re/i.test(response), gitDir);
5712
5712
  }
5713
5713
  var InitSummary;
5714
5714
  var initResponseRegex;
@@ -5717,9 +5717,9 @@ var init_InitSummary = __esm({
5717
5717
  "src/lib/responses/InitSummary.ts"() {
5718
5718
  "use strict";
5719
5719
  InitSummary = class {
5720
- constructor(bare, path16, existing, gitDir) {
5720
+ constructor(bare, path17, existing, gitDir) {
5721
5721
  this.bare = bare;
5722
- this.path = path16;
5722
+ this.path = path17;
5723
5723
  this.existing = existing;
5724
5724
  this.gitDir = gitDir;
5725
5725
  }
@@ -5731,7 +5731,7 @@ var init_InitSummary = __esm({
5731
5731
  function hasBareCommand(command) {
5732
5732
  return command.includes(bareCommand);
5733
5733
  }
5734
- function initTask(bare = false, path16, customArgs) {
5734
+ function initTask(bare = false, path17, customArgs) {
5735
5735
  const commands = ["init", ...customArgs];
5736
5736
  if (bare && !hasBareCommand(commands)) {
5737
5737
  commands.splice(1, 0, bareCommand);
@@ -5740,7 +5740,7 @@ function initTask(bare = false, path16, customArgs) {
5740
5740
  commands,
5741
5741
  format: "utf-8",
5742
5742
  parser(text2) {
5743
- return parseInit(commands.includes("--bare"), path16, text2);
5743
+ return parseInit(commands.includes("--bare"), path17, text2);
5744
5744
  }
5745
5745
  };
5746
5746
  }
@@ -6556,12 +6556,12 @@ var init_FileStatusSummary = __esm({
6556
6556
  "use strict";
6557
6557
  fromPathRegex = /^(.+)\0(.+)$/;
6558
6558
  FileStatusSummary = class {
6559
- constructor(path16, index, working_dir) {
6560
- this.path = path16;
6559
+ constructor(path17, index, working_dir) {
6560
+ this.path = path17;
6561
6561
  this.index = index;
6562
6562
  this.working_dir = working_dir;
6563
6563
  if (index === "R" || working_dir === "R") {
6564
- const detail = fromPathRegex.exec(path16) || [null, path16, path16];
6564
+ const detail = fromPathRegex.exec(path17) || [null, path17, path17];
6565
6565
  this.from = detail[2] || "";
6566
6566
  this.path = detail[1] || "";
6567
6567
  }
@@ -6592,14 +6592,14 @@ function splitLine(result, lineStr) {
6592
6592
  default:
6593
6593
  return;
6594
6594
  }
6595
- function data(index, workingDir, path16) {
6595
+ function data(index, workingDir, path17) {
6596
6596
  const raw = `${index}${workingDir}`;
6597
6597
  const handler = parsers6.get(raw);
6598
6598
  if (handler) {
6599
- handler(result, path16);
6599
+ handler(result, path17);
6600
6600
  }
6601
6601
  if (raw !== "##" && raw !== "!!") {
6602
- result.files.push(new FileStatusSummary(path16, index, workingDir));
6602
+ result.files.push(new FileStatusSummary(path17, index, workingDir));
6603
6603
  }
6604
6604
  }
6605
6605
  }
@@ -6912,9 +6912,9 @@ var init_simple_git_api = __esm({
6912
6912
  next
6913
6913
  );
6914
6914
  }
6915
- hashObject(path16, write) {
6915
+ hashObject(path17, write) {
6916
6916
  return this._runTask(
6917
- hashObjectTask(path16, write === true),
6917
+ hashObjectTask(path17, write === true),
6918
6918
  trailingFunctionArgument(arguments)
6919
6919
  );
6920
6920
  }
@@ -7267,8 +7267,8 @@ var init_branch = __esm({
7267
7267
  }
7268
7268
  });
7269
7269
  function toPath(input) {
7270
- const path16 = input.trim().replace(/^["']|["']$/g, "");
7271
- return path16 && (0, import_node_path.normalize)(path16);
7270
+ const path17 = input.trim().replace(/^["']|["']$/g, "");
7271
+ return path17 && (0, import_node_path.normalize)(path17);
7272
7272
  }
7273
7273
  var parseCheckIgnore;
7274
7274
  var init_CheckIgnore = __esm({
@@ -7582,8 +7582,8 @@ __export(sub_module_exports, {
7582
7582
  subModuleTask: () => subModuleTask,
7583
7583
  updateSubModuleTask: () => updateSubModuleTask
7584
7584
  });
7585
- function addSubModuleTask(repo, path16) {
7586
- return subModuleTask(["add", repo, path16]);
7585
+ function addSubModuleTask(repo, path17) {
7586
+ return subModuleTask(["add", repo, path17]);
7587
7587
  }
7588
7588
  function initSubModuleTask(customArgs) {
7589
7589
  return subModuleTask(["init", ...customArgs]);
@@ -7913,8 +7913,8 @@ var require_git = __commonJS2({
7913
7913
  }
7914
7914
  return this._runTask(straightThroughStringTask2(command, this._trimmed), next);
7915
7915
  };
7916
- Git2.prototype.submoduleAdd = function(repo, path16, then) {
7917
- return this._runTask(addSubModuleTask2(repo, path16), trailingFunctionArgument2(arguments));
7916
+ Git2.prototype.submoduleAdd = function(repo, path17, then) {
7917
+ return this._runTask(addSubModuleTask2(repo, path17), trailingFunctionArgument2(arguments));
7918
7918
  };
7919
7919
  Git2.prototype.submoduleUpdate = function(args2, then) {
7920
7920
  return this._runTask(
@@ -8755,7 +8755,7 @@ var import_zod3 = require("zod");
8755
8755
  // package.json
8756
8756
  var package_default = {
8757
8757
  name: "@posthog/agent",
8758
- version: "2.3.508",
8758
+ version: "2.3.513",
8759
8759
  repository: "https://github.com/PostHog/code",
8760
8760
  description: "TypeScript agent framework wrapping Claude Agent SDK with Git-based task execution for PostHog",
8761
8761
  exports: {
@@ -9191,9 +9191,9 @@ function nodeWritableToWebWritable(nodeStream) {
9191
9191
 
9192
9192
  // src/adapters/claude/claude-agent.ts
9193
9193
  var import_node_crypto = require("crypto");
9194
- var fs8 = __toESM(require("fs"), 1);
9195
- var os4 = __toESM(require("os"), 1);
9196
- var path10 = __toESM(require("path"), 1);
9194
+ var fs9 = __toESM(require("fs"), 1);
9195
+ var os5 = __toESM(require("os"), 1);
9196
+ var path11 = __toESM(require("path"), 1);
9197
9197
  var import_sdk2 = require("@agentclientprotocol/sdk");
9198
9198
  var import_claude_agent_sdk = require("@anthropic-ai/claude-agent-sdk");
9199
9199
  var import_uuid = require("uuid");
@@ -13600,8 +13600,8 @@ var ToolContentBuilder = class {
13600
13600
  this.items.push({ type: "content", content: image(data, mimeType, uri) });
13601
13601
  return this;
13602
13602
  }
13603
- diff(path16, oldText, newText) {
13604
- this.items.push({ type: "diff", path: path16, oldText, newText });
13603
+ diff(path17, oldText, newText) {
13604
+ this.items.push({ type: "diff", path: path17, oldText, newText });
13605
13605
  return this;
13606
13606
  }
13607
13607
  build() {
@@ -13612,6 +13612,54 @@ function toolContent() {
13612
13612
  return new ToolContentBuilder();
13613
13613
  }
13614
13614
 
13615
+ // src/utils/partial-json.ts
13616
+ function tryParsePartialJson(s) {
13617
+ const trimmed2 = s.trim();
13618
+ if (!trimmed2) return null;
13619
+ try {
13620
+ return JSON.parse(trimmed2);
13621
+ } catch {
13622
+ }
13623
+ const closers = [];
13624
+ let inString = false;
13625
+ let escaped = false;
13626
+ for (let i2 = 0; i2 < trimmed2.length; i2++) {
13627
+ const ch = trimmed2[i2];
13628
+ if (inString) {
13629
+ if (escaped) {
13630
+ escaped = false;
13631
+ } else if (ch === "\\") {
13632
+ escaped = true;
13633
+ } else if (ch === '"') {
13634
+ inString = false;
13635
+ }
13636
+ continue;
13637
+ }
13638
+ if (ch === '"') inString = true;
13639
+ else if (ch === "{") closers.push("}");
13640
+ else if (ch === "[") closers.push("]");
13641
+ else if (ch === "}" || ch === "]") closers.pop();
13642
+ }
13643
+ const closeBrackets = (str) => {
13644
+ let out2 = str;
13645
+ for (let i2 = closers.length - 1; i2 >= 0; i2--) out2 += closers[i2];
13646
+ return out2;
13647
+ };
13648
+ const candidates = [];
13649
+ const closedString = inString ? `${trimmed2}"` : trimmed2;
13650
+ candidates.push(closeBrackets(closedString));
13651
+ let stripped = closedString.replace(/[,:]\s*$/, "");
13652
+ stripped = stripped.replace(/,?\s*"[^"]*"\s*:?\s*$/, "");
13653
+ candidates.push(closeBrackets(stripped));
13654
+ for (const candidate of candidates) {
13655
+ try {
13656
+ return JSON.parse(candidate);
13657
+ } catch {
13658
+ }
13659
+ }
13660
+ return null;
13661
+ }
13662
+
13615
13663
  // src/adapters/claude/permissions/posthog-exec-gate.ts
13616
13664
  var POSTHOG_EXEC_TOOL_RE = /^mcp__posthog(?:_[^_]+)*__exec$/;
13617
13665
  var POSTHOG_CALL_COMMAND_RE = /^\s*call\s+(?:--json\s+)?([a-zA-Z0-9_-]+)/;
@@ -14778,12 +14826,19 @@ function toAcpNotifications(content, role, sessionId, toolUseCache, fileContentC
14778
14826
  }
14779
14827
  return output;
14780
14828
  }
14781
- function streamEventToAcpNotifications(message, sessionId, toolUseCache, fileContentCache, client, logger, parentToolCallId, registerHooks, supportsTerminalOutput, cwd, enrichedReadCache) {
14829
+ function streamEventToAcpNotifications(message, sessionId, toolUseCache, toolUseStreamCache, fileContentCache, client, logger, parentToolCallId, registerHooks, supportsTerminalOutput, cwd, enrichedReadCache) {
14782
14830
  const event = message.event;
14783
14831
  switch (event.type) {
14784
- case "content_block_start":
14832
+ case "content_block_start": {
14833
+ const block = event.content_block;
14834
+ if (block.type === "tool_use" || block.type === "mcp_tool_use") {
14835
+ toolUseStreamCache.set(event.index, {
14836
+ toolUseId: block.id,
14837
+ partialJson: ""
14838
+ });
14839
+ }
14785
14840
  return toAcpNotifications(
14786
- [event.content_block],
14841
+ [block],
14787
14842
  "assistant",
14788
14843
  sessionId,
14789
14844
  toolUseCache,
@@ -14797,7 +14852,16 @@ function streamEventToAcpNotifications(message, sessionId, toolUseCache, fileCon
14797
14852
  void 0,
14798
14853
  enrichedReadCache
14799
14854
  );
14800
- case "content_block_delta":
14855
+ }
14856
+ case "content_block_delta": {
14857
+ if (event.delta.type === "input_json_delta") {
14858
+ return inputJsonDeltaToAcpNotifications(
14859
+ event.index,
14860
+ event.delta.partial_json,
14861
+ sessionId,
14862
+ toolUseStreamCache
14863
+ );
14864
+ }
14801
14865
  return toAcpNotifications(
14802
14866
  [event.delta],
14803
14867
  "assistant",
@@ -14813,16 +14877,36 @@ function streamEventToAcpNotifications(message, sessionId, toolUseCache, fileCon
14813
14877
  void 0,
14814
14878
  enrichedReadCache
14815
14879
  );
14880
+ }
14881
+ case "content_block_stop":
14882
+ toolUseStreamCache.delete(event.index);
14883
+ return [];
14816
14884
  case "message_start":
14817
14885
  case "message_delta":
14818
14886
  case "message_stop":
14819
- case "content_block_stop":
14820
14887
  return [];
14821
14888
  default:
14822
14889
  unreachable(event, logger);
14823
14890
  return [];
14824
14891
  }
14825
14892
  }
14893
+ function inputJsonDeltaToAcpNotifications(index, partialJson, sessionId, toolUseStreamCache) {
14894
+ const entry = toolUseStreamCache.get(index);
14895
+ if (!entry) return [];
14896
+ entry.partialJson += partialJson;
14897
+ const parsed = tryParsePartialJson(entry.partialJson);
14898
+ if (!parsed || typeof parsed !== "object") return [];
14899
+ return [
14900
+ {
14901
+ sessionId,
14902
+ update: {
14903
+ sessionUpdate: "tool_call_update",
14904
+ toolCallId: entry.toolUseId,
14905
+ rawInput: parsed
14906
+ }
14907
+ }
14908
+ ];
14909
+ }
14826
14910
  async function handleSystemMessage(message, context) {
14827
14911
  const { session, sessionId, client, logger } = context;
14828
14912
  switch (message.subtype) {
@@ -14966,12 +15050,20 @@ function extractUsageFromResult(message) {
14966
15050
  };
14967
15051
  }
14968
15052
  async function handleStreamEvent(message, context) {
14969
- const { sessionId, client, toolUseCache, fileContentCache, logger } = context;
15053
+ const {
15054
+ sessionId,
15055
+ client,
15056
+ toolUseCache,
15057
+ toolUseStreamCache,
15058
+ fileContentCache,
15059
+ logger
15060
+ } = context;
14970
15061
  const parentToolCallId = message.parent_tool_use_id ?? void 0;
14971
15062
  for (const notification of streamEventToAcpNotifications(
14972
15063
  message,
14973
15064
  sessionId,
14974
15065
  toolUseCache,
15066
+ toolUseStreamCache,
14975
15067
  fileContentCache,
14976
15068
  client,
14977
15069
  logger,
@@ -15884,6 +15976,31 @@ function getAvailableSlashCommands(commands) {
15884
15976
  }
15885
15977
 
15886
15978
  // src/adapters/claude/session/mcp-config.ts
15979
+ var fs6 = __toESM(require("fs"), 1);
15980
+ var os2 = __toESM(require("os"), 1);
15981
+ var path8 = __toESM(require("path"), 1);
15982
+ function loadUserClaudeJsonMcpServers(cwd, logger, homeDir = os2.homedir()) {
15983
+ const claudeJsonPath = path8.join(homeDir, ".claude.json");
15984
+ let raw;
15985
+ try {
15986
+ raw = fs6.readFileSync(claudeJsonPath, "utf8");
15987
+ } catch {
15988
+ return {};
15989
+ }
15990
+ let cfg;
15991
+ try {
15992
+ cfg = JSON.parse(raw);
15993
+ } catch (err2) {
15994
+ logger?.warn("Failed to parse ~/.claude.json", {
15995
+ error: err2 instanceof Error ? err2.message : String(err2)
15996
+ });
15997
+ return {};
15998
+ }
15999
+ const topLevel = cfg.mcpServers && typeof cfg.mcpServers === "object" ? cfg.mcpServers : {};
16000
+ const project = cfg.projects?.[cwd];
16001
+ const projectScoped = project?.mcpServers && typeof project.mcpServers === "object" ? project.mcpServers : {};
16002
+ return { ...topLevel, ...projectScoped };
16003
+ }
15887
16004
  function parseMcpServers(params) {
15888
16005
  const mcpServers = {};
15889
16006
  if (!Array.isArray(params.mcpServers)) {
@@ -15910,9 +16027,9 @@ function parseMcpServers(params) {
15910
16027
 
15911
16028
  // src/adapters/claude/session/options.ts
15912
16029
  var import_node_child_process2 = require("child_process");
15913
- var fs6 = __toESM(require("fs"), 1);
15914
- var os2 = __toESM(require("os"), 1);
15915
- var path8 = __toESM(require("path"), 1);
16030
+ var fs7 = __toESM(require("fs"), 1);
16031
+ var os3 = __toESM(require("os"), 1);
16032
+ var path9 = __toESM(require("path"), 1);
15916
16033
 
15917
16034
  // src/adapters/claude/session/instructions.ts
15918
16035
  var BRANCH_NAMING = `
@@ -15963,8 +16080,9 @@ function buildSystemPrompt(customPrompt) {
15963
16080
  }
15964
16081
  return defaultPrompt;
15965
16082
  }
15966
- function buildMcpServers(userServers, acpServers) {
16083
+ function buildMcpServers(userServers, acpServers, projectScopedServers) {
15967
16084
  return {
16085
+ ...projectScopedServers,
15968
16086
  ...userServers || {},
15969
16087
  ...acpServers
15970
16088
  };
@@ -16113,12 +16231,12 @@ function buildSpawnWrapper(sessionId, onProcessSpawned, onProcessExited, logger)
16113
16231
  };
16114
16232
  }
16115
16233
  function ensureLocalSettings(cwd) {
16116
- const claudeDir = path8.join(cwd, ".claude");
16117
- const localSettingsPath = path8.join(claudeDir, "settings.local.json");
16234
+ const claudeDir = path9.join(cwd, ".claude");
16235
+ const localSettingsPath = path9.join(claudeDir, "settings.local.json");
16118
16236
  try {
16119
- if (!fs6.existsSync(localSettingsPath)) {
16120
- fs6.mkdirSync(claudeDir, { recursive: true });
16121
- fs6.writeFileSync(localSettingsPath, "{}\n", { flag: "wx" });
16237
+ if (!fs7.existsSync(localSettingsPath)) {
16238
+ fs7.mkdirSync(claudeDir, { recursive: true });
16239
+ fs7.writeFileSync(localSettingsPath, "{}\n", { flag: "wx" });
16122
16240
  }
16123
16241
  } catch {
16124
16242
  }
@@ -16148,7 +16266,8 @@ function buildSessionOptions(params) {
16148
16266
  },
16149
16267
  mcpServers: buildMcpServers(
16150
16268
  params.userProvidedOptions?.mcpServers,
16151
- params.mcpServers
16269
+ params.mcpServers,
16270
+ loadUserClaudeJsonMcpServers(params.cwd, params.logger)
16152
16271
  ),
16153
16272
  env: buildEnvironment(),
16154
16273
  hooks: buildHooks(
@@ -16193,18 +16312,18 @@ function buildSessionOptions(params) {
16193
16312
  return options;
16194
16313
  }
16195
16314
  function clearStatsigCache() {
16196
- const statsigPath = path8.join(
16197
- process.env.CLAUDE_CONFIG_DIR || path8.join(os2.homedir(), ".claude"),
16315
+ const statsigPath = path9.join(
16316
+ process.env.CLAUDE_CONFIG_DIR || path9.join(os3.homedir(), ".claude"),
16198
16317
  "statsig"
16199
16318
  );
16200
- fs6.rm(statsigPath, { recursive: true, force: true }, () => {
16319
+ fs7.rm(statsigPath, { recursive: true, force: true }, () => {
16201
16320
  });
16202
16321
  }
16203
16322
 
16204
16323
  // src/adapters/claude/session/settings.ts
16205
- var fs7 = __toESM(require("fs"), 1);
16206
- var os3 = __toESM(require("os"), 1);
16207
- var path9 = __toESM(require("path"), 1);
16324
+ var fs8 = __toESM(require("fs"), 1);
16325
+ var os4 = __toESM(require("os"), 1);
16326
+ var path10 = __toESM(require("path"), 1);
16208
16327
  var import_minimatch = require("minimatch");
16209
16328
 
16210
16329
  // src/utils/async-mutex.ts
@@ -16285,13 +16404,13 @@ function parseRule(rule) {
16285
16404
  function normalizePath(filePath, cwd) {
16286
16405
  let resolved = filePath;
16287
16406
  if (resolved.startsWith("~/")) {
16288
- resolved = path9.join(os3.homedir(), resolved.slice(2));
16407
+ resolved = path10.join(os4.homedir(), resolved.slice(2));
16289
16408
  } else if (resolved.startsWith("./")) {
16290
- resolved = path9.join(cwd, resolved.slice(2));
16291
- } else if (!path9.isAbsolute(resolved)) {
16292
- resolved = path9.join(cwd, resolved);
16409
+ resolved = path10.join(cwd, resolved.slice(2));
16410
+ } else if (!path10.isAbsolute(resolved)) {
16411
+ resolved = path10.join(cwd, resolved);
16293
16412
  }
16294
- return path9.normalize(resolved).replace(/\\/g, "/");
16413
+ return path10.normalize(resolved).replace(/\\/g, "/");
16295
16414
  }
16296
16415
  function matchesGlob(pattern, filePath, cwd) {
16297
16416
  const normalizedPattern = normalizePath(pattern, cwd);
@@ -16338,11 +16457,11 @@ function formatRule(rule) {
16338
16457
  }
16339
16458
  async function writeFileAtomic(filePath, data) {
16340
16459
  const tmpPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
16341
- await fs7.promises.writeFile(tmpPath, data);
16460
+ await fs8.promises.writeFile(tmpPath, data);
16342
16461
  try {
16343
- await fs7.promises.rename(tmpPath, filePath);
16462
+ await fs8.promises.rename(tmpPath, filePath);
16344
16463
  } catch (error) {
16345
- await fs7.promises.rm(tmpPath, { force: true });
16464
+ await fs8.promises.rm(tmpPath, { force: true });
16346
16465
  throw error;
16347
16466
  }
16348
16467
  }
@@ -16351,7 +16470,7 @@ async function loadSettingsFile(filePath) {
16351
16470
  return {};
16352
16471
  }
16353
16472
  try {
16354
- const content = await fs7.promises.readFile(filePath, "utf-8");
16473
+ const content = await fs8.promises.readFile(filePath, "utf-8");
16355
16474
  return JSON.parse(content);
16356
16475
  } catch (error) {
16357
16476
  if (error instanceof Error && "code" in error && error.code === "ENOENT") {
@@ -16366,7 +16485,7 @@ async function loadSettingsFile(filePath) {
16366
16485
  }
16367
16486
  async function readSettingsFileForUpdate(filePath) {
16368
16487
  try {
16369
- const content = await fs7.promises.readFile(filePath, "utf-8");
16488
+ const content = await fs8.promises.readFile(filePath, "utf-8");
16370
16489
  return JSON.parse(content);
16371
16490
  } catch (error) {
16372
16491
  if (error instanceof Error && "code" in error && error.code === "ENOENT") {
@@ -16412,11 +16531,11 @@ var SettingsManager = class {
16412
16531
  return this.initPromise;
16413
16532
  }
16414
16533
  getUserSettingsPath() {
16415
- const configDir = process.env.CLAUDE_CONFIG_DIR || path9.join(os3.homedir(), ".claude");
16416
- return path9.join(configDir, "settings.json");
16534
+ const configDir = process.env.CLAUDE_CONFIG_DIR || path10.join(os4.homedir(), ".claude");
16535
+ return path10.join(configDir, "settings.json");
16417
16536
  }
16418
16537
  getProjectSettingsPath() {
16419
- return path9.join(this.cwd, ".claude", "settings.json");
16538
+ return path10.join(this.cwd, ".claude", "settings.json");
16420
16539
  }
16421
16540
  /**
16422
16541
  * Local settings are anchored to the primary worktree so every worktree of
@@ -16424,7 +16543,7 @@ var SettingsManager = class {
16424
16543
  * avoids re-prompting for the same permission in every worktree.
16425
16544
  */
16426
16545
  getLocalSettingsPath() {
16427
- return path9.join(this.repoRoot, ".claude", "settings.local.json");
16546
+ return path10.join(this.repoRoot, ".claude", "settings.local.json");
16428
16547
  }
16429
16548
  async loadAllSettings() {
16430
16549
  this.repoRoot = await resolveMainRepoPath(this.cwd);
@@ -16551,7 +16670,7 @@ var SettingsManager = class {
16551
16670
  }
16552
16671
  permissions.allow = Array.from(current2);
16553
16672
  const next = { ...existing, permissions };
16554
- await fs7.promises.mkdir(path9.dirname(filePath), { recursive: true });
16673
+ await fs8.promises.mkdir(path10.dirname(filePath), { recursive: true });
16555
16674
  await writeFileAtomic(filePath, `${JSON.stringify(next, null, 2)}
16556
16675
  `);
16557
16676
  this.localSettings = next;
@@ -16584,7 +16703,7 @@ var SettingsManager = class {
16584
16703
  ...existing,
16585
16704
  posthogApprovedExecTools: Array.from(current2)
16586
16705
  };
16587
- await fs7.promises.mkdir(path9.dirname(filePath), { recursive: true });
16706
+ await fs8.promises.mkdir(path10.dirname(filePath), { recursive: true });
16588
16707
  await writeFileAtomic(filePath, `${JSON.stringify(next, null, 2)}
16589
16708
  `);
16590
16709
  this.localSettings = next;
@@ -16627,6 +16746,7 @@ function shouldEmitRawMessage(config, message) {
16627
16746
  var ClaudeAcpAgent = class extends BaseAcpAgent {
16628
16747
  adapterName = "claude";
16629
16748
  toolUseCache;
16749
+ toolUseStreamCache;
16630
16750
  backgroundTerminals = {};
16631
16751
  clientCapabilities;
16632
16752
  options;
@@ -16636,6 +16756,7 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
16636
16756
  super(client);
16637
16757
  this.options = options;
16638
16758
  this.toolUseCache = {};
16759
+ this.toolUseStreamCache = /* @__PURE__ */ new Map();
16639
16760
  this.logger = new Logger({ debug: true, prefix: "[ClaudeAcpAgent]" });
16640
16761
  this.enrichment = createEnrichment(options?.posthogApiConfig, this.logger);
16641
16762
  }
@@ -16688,7 +16809,7 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
16688
16809
  };
16689
16810
  }
16690
16811
  async newSession(params) {
16691
- if (fs8.existsSync(path10.resolve(os4.homedir(), ".claude.json.backup")) && !fs8.existsSync(path10.resolve(os4.homedir(), ".claude.json"))) {
16812
+ if (fs9.existsSync(path11.resolve(os5.homedir(), ".claude.json.backup")) && !fs9.existsSync(path11.resolve(os5.homedir(), ".claude.json"))) {
16692
16813
  throw import_sdk2.RequestError.authRequired();
16693
16814
  }
16694
16815
  const response = await this.createSession(params, {
@@ -16830,6 +16951,7 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
16830
16951
  sessionId: params.sessionId,
16831
16952
  client: this.client,
16832
16953
  toolUseCache: this.toolUseCache,
16954
+ toolUseStreamCache: this.toolUseStreamCache,
16833
16955
  fileContentCache: this.fileContentCache,
16834
16956
  enrichedReadCache: this.enrichedReadCache,
16835
16957
  logger: this.logger,
@@ -17082,6 +17204,7 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
17082
17204
  }
17083
17205
  throw error;
17084
17206
  } finally {
17207
+ this.toolUseStreamCache.clear();
17085
17208
  if (!handedOff) {
17086
17209
  this.session.promptRunning = false;
17087
17210
  for (const [key, pending] of this.session.pendingMessages) {
@@ -17656,6 +17779,7 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
17656
17779
  sessionId,
17657
17780
  client: this.client,
17658
17781
  toolUseCache: this.toolUseCache,
17782
+ toolUseStreamCache: this.toolUseStreamCache,
17659
17783
  fileContentCache: this.fileContentCache,
17660
17784
  enrichedReadCache: this.enrichedReadCache,
17661
17785
  logger: this.logger,
@@ -17890,9 +18014,9 @@ function resetUsage(state) {
17890
18014
  }
17891
18015
 
17892
18016
  // src/adapters/codex/settings.ts
17893
- var fs9 = __toESM(require("fs"), 1);
17894
- var os5 = __toESM(require("os"), 1);
17895
- var path11 = __toESM(require("path"), 1);
18017
+ var fs10 = __toESM(require("fs"), 1);
18018
+ var os6 = __toESM(require("os"), 1);
18019
+ var path12 = __toESM(require("path"), 1);
17896
18020
  var CodexSettingsManager = class {
17897
18021
  cwd;
17898
18022
  settings = { mcpServerNames: [] };
@@ -17903,12 +18027,12 @@ var CodexSettingsManager = class {
17903
18027
  async initialize() {
17904
18028
  }
17905
18029
  getConfigPath() {
17906
- return path11.join(os5.homedir(), ".codex", "config.toml");
18030
+ return path12.join(os6.homedir(), ".codex", "config.toml");
17907
18031
  }
17908
18032
  loadSettings() {
17909
18033
  const configPath = this.getConfigPath();
17910
18034
  try {
17911
- const content = fs9.readFileSync(configPath, "utf-8");
18035
+ const content = fs10.readFileSync(configPath, "utf-8");
17912
18036
  this.settings = parseCodexToml(content, this.cwd);
17913
18037
  } catch {
17914
18038
  this.settings = { mcpServerNames: [] };
@@ -18689,8 +18813,8 @@ var import_node_path5 = __toESM(require("path"), 1);
18689
18813
 
18690
18814
  // ../git/dist/sagas/checkpoint.js
18691
18815
  var import_node_crypto2 = require("crypto");
18692
- var fs10 = __toESM(require("fs/promises"), 1);
18693
- var path12 = __toESM(require("path"), 1);
18816
+ var fs11 = __toESM(require("fs/promises"), 1);
18817
+ var path13 = __toESM(require("path"), 1);
18694
18818
 
18695
18819
  // ../shared/dist/index.js
18696
18820
  var CLOUD_PROMPT_PREFIX = "__twig_cloud_prompt_v1__:";
@@ -18963,12 +19087,12 @@ async function getGitBusyState(git) {
18963
19087
  const toplevel = (await git.raw(["rev-parse", "--show-toplevel"])).trim();
18964
19088
  const resolveGitPath = async (gitPath) => {
18965
19089
  const relative = (await git.raw(["rev-parse", "--git-path", gitPath])).trim();
18966
- return path12.isAbsolute(relative) ? relative : path12.resolve(toplevel, relative);
19090
+ return path13.isAbsolute(relative) ? relative : path13.resolve(toplevel, relative);
18967
19091
  };
18968
19092
  const pathExists = async (gitPath) => {
18969
19093
  const resolved = await resolveGitPath(gitPath);
18970
19094
  try {
18971
- await fs10.access(resolved);
19095
+ await fs11.access(resolved);
18972
19096
  return true;
18973
19097
  } catch {
18974
19098
  return false;
@@ -18977,7 +19101,7 @@ async function getGitBusyState(git) {
18977
19101
  const dirExists = async (gitPath) => {
18978
19102
  const resolved = await resolveGitPath(gitPath);
18979
19103
  try {
18980
- const stat4 = await fs10.stat(resolved);
19104
+ const stat4 = await fs11.stat(resolved);
18981
19105
  return stat4.isDirectory();
18982
19106
  } catch {
18983
19107
  return false;
@@ -18997,6 +19121,7 @@ async function getGitBusyState(git) {
18997
19121
  }
18998
19122
  return { busy: false };
18999
19123
  }
19124
+ var MAX_WORKTREE_FILE_BYTES = 1024 * 1024;
19000
19125
  async function createWorktreeTree(git, baseDir, head) {
19001
19126
  const { tempGit, tempIndexPath } = await createTempIndexGit(git, baseDir, "checkpoint-worktree");
19002
19127
  try {
@@ -19006,13 +19131,85 @@ async function createWorktreeTree(git, baseDir, head) {
19006
19131
  await tempGit.raw(["read-tree", "--empty"]);
19007
19132
  }
19008
19133
  await tempGit.raw(["add", "-A", "--", "."]);
19134
+ await reconcileLargeBlobs(tempGit, head, MAX_WORKTREE_FILE_BYTES);
19009
19135
  const treeHash = await tempGit.raw(["write-tree"]);
19010
19136
  return treeHash.trim();
19011
19137
  } finally {
19012
- await fs10.rm(tempIndexPath, { force: true }).catch(() => {
19138
+ await fs11.rm(tempIndexPath, { force: true }).catch(() => {
19013
19139
  });
19014
19140
  }
19015
19141
  }
19142
+ async function reconcileLargeBlobs(tempGit, head, maxBytes) {
19143
+ const intermediateTree = (await tempGit.raw(["write-tree"])).trim();
19144
+ const largePaths = await listLargeBlobPaths(tempGit, intermediateTree, maxBytes);
19145
+ if (largePaths.length === 0)
19146
+ return;
19147
+ const headEntries = head ? await readHeadBlobEntries(tempGit, head, largePaths) : /* @__PURE__ */ new Map();
19148
+ for (const filePath of largePaths) {
19149
+ const headEntry = headEntries.get(filePath);
19150
+ if (headEntry) {
19151
+ await tempGit.raw([
19152
+ "update-index",
19153
+ "--cacheinfo",
19154
+ `${headEntry.mode},${headEntry.hash},${filePath}`
19155
+ ]);
19156
+ } else {
19157
+ await tempGit.raw(["update-index", "--force-remove", filePath]).catch(() => {
19158
+ });
19159
+ }
19160
+ }
19161
+ }
19162
+ async function listLargeBlobPaths(tempGit, tree, maxBytes) {
19163
+ const output = await tempGit.raw(["ls-tree", "-r", "-l", tree]);
19164
+ const result = [];
19165
+ for (const line of output.split("\n")) {
19166
+ if (!line)
19167
+ continue;
19168
+ const tabIndex = line.indexOf(" ");
19169
+ if (tabIndex < 0)
19170
+ continue;
19171
+ const meta = line.slice(0, tabIndex);
19172
+ const filePath = line.slice(tabIndex + 1);
19173
+ const parts2 = meta.split(/\s+/);
19174
+ if (parts2.length < 4)
19175
+ continue;
19176
+ const [, type, , sizeStr] = parts2;
19177
+ if (type !== "blob")
19178
+ continue;
19179
+ if (sizeStr === "-")
19180
+ continue;
19181
+ const size = Number.parseInt(sizeStr, 10);
19182
+ if (Number.isFinite(size) && size > maxBytes) {
19183
+ result.push(filePath);
19184
+ }
19185
+ }
19186
+ return result;
19187
+ }
19188
+ async function readHeadBlobEntries(tempGit, head, paths) {
19189
+ const result = /* @__PURE__ */ new Map();
19190
+ const CHUNK_SIZE = 100;
19191
+ for (let i2 = 0; i2 < paths.length; i2 += CHUNK_SIZE) {
19192
+ const chunk = paths.slice(i2, i2 + CHUNK_SIZE);
19193
+ const output = await tempGit.raw(["ls-tree", "-r", head, "--", ...chunk]).catch(() => "");
19194
+ for (const line of output.split("\n")) {
19195
+ if (!line)
19196
+ continue;
19197
+ const tabIndex = line.indexOf(" ");
19198
+ if (tabIndex < 0)
19199
+ continue;
19200
+ const meta = line.slice(0, tabIndex);
19201
+ const filePath = line.slice(tabIndex + 1);
19202
+ const parts2 = meta.split(/\s+/);
19203
+ if (parts2.length < 3)
19204
+ continue;
19205
+ const [mode, type, hash] = parts2;
19206
+ if (type !== "blob")
19207
+ continue;
19208
+ result.set(filePath, { mode, hash });
19209
+ }
19210
+ }
19211
+ return result;
19212
+ }
19016
19213
  async function createMetaTree(git, baseDir, indexTree, worktreeTree) {
19017
19214
  const { tempGit, tempIndexPath } = await createTempIndexGit(git, baseDir, "checkpoint-meta");
19018
19215
  try {
@@ -19036,7 +19233,7 @@ async function createMetaTree(git, baseDir, indexTree, worktreeTree) {
19036
19233
  const metaTree = await tempGit.raw(["write-tree"]);
19037
19234
  return metaTree.trim();
19038
19235
  } finally {
19039
- await fs10.rm(tempIndexPath, { force: true }).catch(() => {
19236
+ await fs11.rm(tempIndexPath, { force: true }).catch(() => {
19040
19237
  });
19041
19238
  }
19042
19239
  }
@@ -19053,12 +19250,12 @@ function formatCheckpointMessage(meta) {
19053
19250
  async function getGitCommonDir(git, baseDir) {
19054
19251
  const raw = await git.raw(["rev-parse", "--git-common-dir"]);
19055
19252
  const dir = raw.trim() || ".git";
19056
- return path12.isAbsolute(dir) ? dir : path12.resolve(baseDir, dir);
19253
+ return path13.isAbsolute(dir) ? dir : path13.resolve(baseDir, dir);
19057
19254
  }
19058
19255
  async function createTempIndexGit(git, baseDir, label) {
19059
- const tmpDir = path12.join(await getGitCommonDir(git, baseDir), "posthog-code-tmp");
19060
- await fs10.mkdir(tmpDir, { recursive: true });
19061
- const tempIndexPath = path12.join(tmpDir, `${label}-${Date.now()}-${(0, import_node_crypto2.randomUUID)()}`);
19256
+ const tmpDir = path13.join(await getGitCommonDir(git, baseDir), "posthog-code-tmp");
19257
+ await fs11.mkdir(tmpDir, { recursive: true });
19258
+ const tempIndexPath = path13.join(tmpDir, `${label}-${Date.now()}-${(0, import_node_crypto2.randomUUID)()}`);
19062
19259
  const tempGit = createGitClient(baseDir).env({
19063
19260
  ...process.env,
19064
19261
  GIT_INDEX_FILE: tempIndexPath
@@ -19085,6 +19282,7 @@ async function deleteCheckpoint(git, checkpointId) {
19085
19282
  // ../git/dist/handoff.js
19086
19283
  var HANDOFF_HEAD_REF_PREFIX = "refs/posthog-code-handoff/head/";
19087
19284
  var CHECKPOINT_REF_PREFIX2 = "refs/posthog-code-checkpoint/";
19285
+ var MAX_HANDOFF_FILE_BYTES = 1024 * 1024;
19088
19286
  var GitHandoffTracker = class {
19089
19287
  repositoryPath;
19090
19288
  logger;
@@ -19092,7 +19290,7 @@ var GitHandoffTracker = class {
19092
19290
  this.repositoryPath = config.repositoryPath;
19093
19291
  this.logger = config.logger;
19094
19292
  }
19095
- async captureForHandoff(_localGitState) {
19293
+ async captureForHandoff(localGitState) {
19096
19294
  const captureSaga = new CaptureCheckpointSaga(this.logger);
19097
19295
  const result = await captureSaga.run({ baseDir: this.repositoryPath });
19098
19296
  if (!result.success) {
@@ -19102,17 +19300,20 @@ var GitHandoffTracker = class {
19102
19300
  const git = createGitClient(this.repositoryPath);
19103
19301
  const tempDir = await this.createTempDir(checkpoint.checkpointId);
19104
19302
  const checkpointRef = `${CHECKPOINT_REF_PREFIX2}${checkpoint.checkpointId}`;
19105
- const packRefs = [
19106
- checkpoint.head,
19107
- checkpoint.indexTree,
19108
- checkpoint.worktreeTree
19109
- ].filter((ref) => !!ref);
19110
- const headRef = checkpoint.head ? `${HANDOFF_HEAD_REF_PREFIX}${checkpoint.checkpointId}` : void 0;
19111
- const packPrefix = import_node_path5.default.join(tempDir, checkpoint.checkpointId);
19112
19303
  try {
19304
+ const reconciledIndex = await this.reconcileHandoffIndex(git, checkpoint.head, checkpoint.indexTree, tempDir, checkpoint.checkpointId);
19305
+ const packBaseline = localGitState?.upstreamHead ?? null;
19306
+ const packRefs = [
19307
+ checkpoint.head,
19308
+ reconciledIndex.indexTree,
19309
+ checkpoint.worktreeTree,
19310
+ packBaseline ? `^${packBaseline}` : null
19311
+ ].filter((ref) => !!ref);
19312
+ const headRef = checkpoint.head ? `${HANDOFF_HEAD_REF_PREFIX}${checkpoint.checkpointId}` : void 0;
19313
+ const packPrefix = import_node_path5.default.join(tempDir, checkpoint.checkpointId);
19113
19314
  const [headPack, indexFile, tracking] = await Promise.all([
19114
19315
  this.captureObjectPack(packPrefix, packRefs),
19115
- this.copyIndexFile(git, checkpoint.checkpointId, tempDir),
19316
+ this.statFileArtifact(reconciledIndex.indexFilePath),
19116
19317
  getTrackingMetadata(git, checkpoint.branch)
19117
19318
  ]);
19118
19319
  return {
@@ -19123,7 +19324,7 @@ var GitHandoffTracker = class {
19123
19324
  headRef,
19124
19325
  head: checkpoint.head,
19125
19326
  branch: checkpoint.branch,
19126
- indexTree: checkpoint.indexTree,
19327
+ indexTree: reconciledIndex.indexTree,
19127
19328
  worktreeTree: checkpoint.worktreeTree,
19128
19329
  timestamp: checkpoint.timestamp,
19129
19330
  upstreamRemote: tracking.upstreamRemote,
@@ -19143,6 +19344,7 @@ var GitHandoffTracker = class {
19143
19344
  const { checkpoint, headPackPath, indexPath, localGitState, onDivergedBranch } = input;
19144
19345
  const git = createGitClient(this.repositoryPath);
19145
19346
  if (headPackPath) {
19347
+ await this.ensureBaselineForApply(git, checkpoint, localGitState);
19146
19348
  await this.unpackPackFile(headPackPath);
19147
19349
  }
19148
19350
  if (checkpoint.branch && checkpoint.head) {
@@ -19181,14 +19383,89 @@ var GitHandoffTracker = class {
19181
19383
  });
19182
19384
  return { path: packPath, rawBytes };
19183
19385
  }
19184
- async copyIndexFile(git, checkpointId, tempDir) {
19185
- const indexPath = await this.getGitPath(git, "index");
19186
- const copiedIndexPath = import_node_path5.default.join(tempDir, `${checkpointId}.index`);
19187
- await (0, import_promises2.copyFile)(indexPath, copiedIndexPath);
19188
- return {
19189
- path: copiedIndexPath,
19190
- rawBytes: await this.getFileSize(copiedIndexPath)
19191
- };
19386
+ async reconcileHandoffIndex(git, head, indexTree, tempDir, checkpointId) {
19387
+ const realIndexPath = await this.getGitPath(git, "index");
19388
+ const tempIndexPath = import_node_path5.default.join(tempDir, `${checkpointId}.index`);
19389
+ await (0, import_promises2.copyFile)(realIndexPath, tempIndexPath);
19390
+ const largePaths = await this.listLargeBlobsInTree(indexTree, MAX_HANDOFF_FILE_BYTES);
19391
+ if (largePaths.length === 0) {
19392
+ return { indexTree, indexFilePath: tempIndexPath };
19393
+ }
19394
+ const headBlobs = head ? await this.readHeadBlobsForPaths(head, largePaths) : /* @__PURE__ */ new Map();
19395
+ const env = { ...process.env, GIT_INDEX_FILE: tempIndexPath };
19396
+ for (const filePath of largePaths) {
19397
+ const headBlob = headBlobs.get(filePath);
19398
+ if (headBlob) {
19399
+ await this.runGitWithEnv(env, [
19400
+ "update-index",
19401
+ "--cacheinfo",
19402
+ `${headBlob.mode},${headBlob.hash},${filePath}`
19403
+ ]);
19404
+ } else {
19405
+ await this.runGitWithEnv(env, [
19406
+ "update-index",
19407
+ "--force-remove",
19408
+ filePath
19409
+ ]).catch(() => {
19410
+ });
19411
+ }
19412
+ }
19413
+ const reconciledTree = (await this.runGitWithEnv(env, ["write-tree"])).trim();
19414
+ return { indexTree: reconciledTree, indexFilePath: tempIndexPath };
19415
+ }
19416
+ async listLargeBlobsInTree(tree, maxBytes) {
19417
+ const { stdout } = await this.runGitProcess(["ls-tree", "-r", "-l", tree], "");
19418
+ const result = [];
19419
+ for (const line of stdout.split("\n")) {
19420
+ if (!line)
19421
+ continue;
19422
+ const tabIndex = line.indexOf(" ");
19423
+ if (tabIndex < 0)
19424
+ continue;
19425
+ const meta = line.slice(0, tabIndex);
19426
+ const filePath = line.slice(tabIndex + 1);
19427
+ const parts2 = meta.split(/\s+/);
19428
+ if (parts2.length < 4)
19429
+ continue;
19430
+ const [, type, , sizeStr] = parts2;
19431
+ if (type !== "blob")
19432
+ continue;
19433
+ if (sizeStr === "-")
19434
+ continue;
19435
+ const size = Number.parseInt(sizeStr, 10);
19436
+ if (Number.isFinite(size) && size > maxBytes) {
19437
+ result.push(filePath);
19438
+ }
19439
+ }
19440
+ return result;
19441
+ }
19442
+ async readHeadBlobsForPaths(head, paths) {
19443
+ const result = /* @__PURE__ */ new Map();
19444
+ const CHUNK_SIZE = 100;
19445
+ for (let i2 = 0; i2 < paths.length; i2 += CHUNK_SIZE) {
19446
+ const chunk = paths.slice(i2, i2 + CHUNK_SIZE);
19447
+ const { stdout } = await this.runGitProcess(["ls-tree", "-r", head, "--", ...chunk], "").catch(() => ({ stdout: "", stderr: "" }));
19448
+ for (const line of stdout.split("\n")) {
19449
+ if (!line)
19450
+ continue;
19451
+ const tabIndex = line.indexOf(" ");
19452
+ if (tabIndex < 0)
19453
+ continue;
19454
+ const meta = line.slice(0, tabIndex);
19455
+ const filePath = line.slice(tabIndex + 1);
19456
+ const parts2 = meta.split(/\s+/);
19457
+ if (parts2.length < 3)
19458
+ continue;
19459
+ const [mode, type, hash] = parts2;
19460
+ if (type !== "blob")
19461
+ continue;
19462
+ result.set(filePath, { mode, hash });
19463
+ }
19464
+ }
19465
+ return result;
19466
+ }
19467
+ async statFileArtifact(filePath) {
19468
+ return { path: filePath, rawBytes: await this.getFileSize(filePath) };
19192
19469
  }
19193
19470
  async restoreIndexFile(git, indexPath) {
19194
19471
  const gitIndexPath = await this.getGitPath(git, "index");
@@ -19216,6 +19493,20 @@ var GitHandoffTracker = class {
19216
19493
  shouldRestoreTracking(branchStatus2, localGitState, tracking) {
19217
19494
  return branchStatus2.kind === "missing" || !hasTrackingConfig(localGitState) && (tracking.upstreamRemote !== null || tracking.upstreamMergeRef !== null);
19218
19495
  }
19496
+ async ensureBaselineForApply(git, checkpoint, localGitState) {
19497
+ const tracking = this.getPreferredTracking(localGitState, checkpoint);
19498
+ if (!tracking.upstreamRemote || !tracking.upstreamMergeRef)
19499
+ return;
19500
+ await this.ensureRemoteForTracking(git, tracking).catch(() => {
19501
+ });
19502
+ await git.raw(["fetch", tracking.upstreamRemote, tracking.upstreamMergeRef]).catch((err2) => {
19503
+ 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", {
19504
+ err: String(err2),
19505
+ remote: tracking.upstreamRemote,
19506
+ ref: tracking.upstreamMergeRef
19507
+ });
19508
+ });
19509
+ }
19219
19510
  async ensureRemoteForTracking(git, tracking) {
19220
19511
  if (!tracking.upstreamRemote || !tracking.remoteUrl)
19221
19512
  return;
@@ -19352,6 +19643,31 @@ var GitHandoffTracker = class {
19352
19643
  });
19353
19644
  });
19354
19645
  }
19646
+ async runGitWithEnv(env, args2) {
19647
+ return new Promise((resolve7, reject) => {
19648
+ const child = (0, import_node_child_process4.spawn)("git", args2, {
19649
+ cwd: this.repositoryPath,
19650
+ stdio: ["ignore", "pipe", "pipe"],
19651
+ env
19652
+ });
19653
+ let stdout = "";
19654
+ let stderr = "";
19655
+ child.stdout.on("data", (chunk) => {
19656
+ stdout += chunk.toString();
19657
+ });
19658
+ child.stderr.on("data", (chunk) => {
19659
+ stderr += chunk.toString();
19660
+ });
19661
+ child.on("error", reject);
19662
+ child.on("close", (code) => {
19663
+ if (code === 0) {
19664
+ resolve7(stdout);
19665
+ return;
19666
+ }
19667
+ reject(new Error(stderr || `git ${args2.join(" ")} failed with code ${code}`));
19668
+ });
19669
+ });
19670
+ }
19355
19671
  runGitProcess(args2, input) {
19356
19672
  return new Promise((resolve7, reject) => {
19357
19673
  const child = (0, import_node_child_process4.spawn)("git", args2, {
@@ -19374,6 +19690,8 @@ var GitHandoffTracker = class {
19374
19690
  }
19375
19691
  reject(new Error(stderr || `git ${args2.join(" ")} failed with code ${code}`));
19376
19692
  });
19693
+ child.stdin.on("error", () => {
19694
+ });
19377
19695
  child.stdin.end(input);
19378
19696
  });
19379
19697
  }
@@ -19864,9 +20182,9 @@ var PostHogAPIClient = class {
19864
20182
 
19865
20183
  // src/adapters/claude/session/jsonl-hydration.ts
19866
20184
  var import_node_crypto3 = require("crypto");
19867
- var fs11 = __toESM(require("fs/promises"), 1);
19868
- var os6 = __toESM(require("os"), 1);
19869
- var path14 = __toESM(require("path"), 1);
20185
+ var fs12 = __toESM(require("fs/promises"), 1);
20186
+ var os7 = __toESM(require("os"), 1);
20187
+ var path15 = __toESM(require("path"), 1);
19870
20188
  var CHARS_PER_TOKEN = 4;
19871
20189
  var DEFAULT_MAX_TOKENS = 15e4;
19872
20190
  function estimateTurnTokens(turn) {
@@ -20532,7 +20850,7 @@ async function getAgentshVersion() {
20532
20850
  }
20533
20851
  async function resolveAgentshRuntimeInfo({
20534
20852
  sessionIdPath = AGENTSH_SESSION_ID_FILE,
20535
- readSessionId = async (path16) => (0, import_promises5.readFile)(path16, "utf8"),
20853
+ readSessionId = async (path17) => (0, import_promises5.readFile)(path17, "utf8"),
20536
20854
  getVersion = getAgentshVersion
20537
20855
  } = {}) {
20538
20856
  let sessionId;