pullfrog 0.1.28 → 0.1.29

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.
Files changed (3) hide show
  1. package/dist/cli.mjs +51 -36
  2. package/dist/index.js +50 -35
  3. package/package.json +1 -1
package/dist/cli.mjs CHANGED
@@ -93765,14 +93765,14 @@ var require_turndown_cjs = __commonJS({
93765
93765
  } else if (node2.nodeType === 1) {
93766
93766
  replacement = replacementForNode.call(self2, node2);
93767
93767
  }
93768
- return join23(output, replacement);
93768
+ return join24(output, replacement);
93769
93769
  }, "");
93770
93770
  }
93771
93771
  function postProcess(output) {
93772
93772
  var self2 = this;
93773
93773
  this.rules.forEach(function(rule) {
93774
93774
  if (typeof rule.append === "function") {
93775
- output = join23(output, rule.append(self2.options));
93775
+ output = join24(output, rule.append(self2.options));
93776
93776
  }
93777
93777
  });
93778
93778
  return output.replace(/^[\t\r\n]+/, "").replace(/[\t\r\n\s]+$/, "");
@@ -93784,7 +93784,7 @@ var require_turndown_cjs = __commonJS({
93784
93784
  if (whitespace.leading || whitespace.trailing) content = content.trim();
93785
93785
  return whitespace.leading + rule.replacement(content, node2, this.options) + whitespace.trailing;
93786
93786
  }
93787
- function join23(output, replacement) {
93787
+ function join24(output, replacement) {
93788
93788
  var s1 = trimTrailingNewlines(output);
93789
93789
  var s2 = trimLeadingNewlines(replacement);
93790
93790
  var nls = Math.max(output.length - s1.length, replacement.length - s2.length);
@@ -100726,7 +100726,7 @@ import { dirname as dirname6 } from "node:path";
100726
100726
  // main.ts
100727
100727
  import { existsSync as existsSync8, readdirSync as readdirSync2 } from "node:fs";
100728
100728
  import { readFile as readFile5 } from "node:fs/promises";
100729
- import { join as join22 } from "node:path";
100729
+ import { join as join23 } from "node:path";
100730
100730
 
100731
100731
  // agents/claude.ts
100732
100732
  import { execFileSync as execFileSync3 } from "node:child_process";
@@ -101867,7 +101867,7 @@ var import_semver = __toESM(require_semver2(), 1);
101867
101867
  // package.json
101868
101868
  var package_default = {
101869
101869
  name: "pullfrog",
101870
- version: "0.1.28",
101870
+ version: "0.1.29",
101871
101871
  type: "module",
101872
101872
  bin: {
101873
101873
  pullfrog: "dist/cli.mjs",
@@ -151257,7 +151257,7 @@ function closeBrowserDaemon(toolState) {
151257
151257
  // mcp/checkout.ts
151258
151258
  import { createHash as createHash2 } from "node:crypto";
151259
151259
  import { statSync, unlinkSync as unlinkSync3, writeFileSync as writeFileSync8 } from "node:fs";
151260
- import { join as join13 } from "node:path";
151260
+ import { join as join14 } from "node:path";
151261
151261
 
151262
151262
  // utils/diffCoverage.ts
151263
151263
  import { isAbsolute, normalize as normalize2, resolve } from "node:path";
@@ -151527,6 +151527,7 @@ function readNumber(params) {
151527
151527
  import { execSync } from "node:child_process";
151528
151528
  import { createHash } from "node:crypto";
151529
151529
  import { readFileSync as readFileSync3, realpathSync, unlinkSync } from "node:fs";
151530
+ import { join as join11 } from "node:path";
151530
151531
 
151531
151532
  // utils/shell.ts
151532
151533
  import { spawnSync as spawnSync4 } from "node:child_process";
@@ -151596,6 +151597,18 @@ function verifyGitBinary() {
151596
151597
  }
151597
151598
  return gitBinary.path;
151598
151599
  }
151600
+ var hooksDirCache = /* @__PURE__ */ new Map();
151601
+ function resolveHooksDir(cwd, gitPath) {
151602
+ const cached4 = hooksDirCache.get(cwd);
151603
+ if (cached4) return cached4;
151604
+ const commonDir = $2(gitPath, ["rev-parse", "--path-format=absolute", "--git-common-dir"], {
151605
+ cwd,
151606
+ log: false
151607
+ }).trim();
151608
+ const hooksDir = join11(commonDir, "hooks");
151609
+ hooksDirCache.set(cwd, hooksDir);
151610
+ return hooksDir;
151611
+ }
151599
151612
  var authServer;
151600
151613
  function setGitAuthServer(server) {
151601
151614
  authServer = server;
@@ -151617,6 +151630,8 @@ async function $git(subcommand, args2, options) {
151617
151630
  "protocol.file.allow=never",
151618
151631
  "-c",
151619
151632
  "core.sshCommand=ssh",
151633
+ "-c",
151634
+ `core.hooksPath=${resolveHooksDir(cwd, gitPath)}`,
151620
151635
  subcommand,
151621
151636
  ...args2
151622
151637
  ];
@@ -151886,7 +151901,7 @@ function postProcessRangeDiff(raw2, contextLines = 3) {
151886
151901
  // mcp/git.ts
151887
151902
  import { randomUUID as randomUUID3 } from "node:crypto";
151888
151903
  import { writeFileSync as writeFileSync7 } from "node:fs";
151889
- import { join as join11 } from "node:path";
151904
+ import { join as join12 } from "node:path";
151890
151905
  function getPushDestination(branch, storedDest) {
151891
151906
  if (storedDest && storedDest.localBranch === branch) {
151892
151907
  log.debug(`using stored push destination: ${storedDest.remoteName}/${storedDest.remoteBranch}`);
@@ -152204,7 +152219,7 @@ function countAhead(head, base) {
152204
152219
  function spillGitOutput(params) {
152205
152220
  const tempDir = process.env.PULLFROG_TEMP_DIR;
152206
152221
  if (!tempDir) throw new Error("PULLFROG_TEMP_DIR not set");
152207
- const outputPath = join11(tempDir, `git-${params.command}-${randomUUID3().slice(0, 8)}.txt`);
152222
+ const outputPath = join12(tempDir, `git-${params.command}-${randomUUID3().slice(0, 8)}.txt`);
152208
152223
  writeFileSync7(outputPath, params.output);
152209
152224
  const previewByLines = params.output.split("\n").slice(0, OVERFLOW_PREVIEW_LINES).join("\n");
152210
152225
  const preview = previewByLines.length <= OVERFLOW_PREVIEW_MAX_CHARS ? previewByLines : `${previewByLines.slice(0, OVERFLOW_PREVIEW_MAX_CHARS)}\u2026`;
@@ -152908,9 +152923,9 @@ async function reportReviewNodeId(ctx, params) {
152908
152923
  import { execFileSync as execFileSync7, execSync as execSync2 } from "node:child_process";
152909
152924
  import { mkdtempSync as mkdtempSync2, readdirSync, realpathSync as realpathSync2, unlinkSync as unlinkSync2 } from "node:fs";
152910
152925
  import { tmpdir as tmpdir3 } from "node:os";
152911
- import { join as join12 } from "node:path";
152926
+ import { join as join13 } from "node:path";
152912
152927
  function createTempDirectory() {
152913
- const sharedTempDir = mkdtempSync2(join12(tmpdir3(), "pullfrog-"));
152928
+ const sharedTempDir = mkdtempSync2(join13(tmpdir3(), "pullfrog-"));
152914
152929
  process.env.PULLFROG_TEMP_DIR = sharedTempDir;
152915
152930
  log.info(`\xBB created temp dir at ${sharedTempDir}`);
152916
152931
  return sharedTempDir;
@@ -152955,13 +152970,13 @@ function wipeRunnerLeakSurface() {
152955
152970
  return [];
152956
152971
  }
152957
152972
  };
152958
- const fileCommandsDir = join12(runnerTemp, "_runner_file_commands");
152973
+ const fileCommandsDir = join13(runnerTemp, "_runner_file_commands");
152959
152974
  for (const entry of listDir(fileCommandsDir)) {
152960
- tryUnlink(join12(fileCommandsDir, entry));
152975
+ tryUnlink(join13(fileCommandsDir, entry));
152961
152976
  }
152962
152977
  for (const entry of listDir(runnerTemp)) {
152963
152978
  if (entry.endsWith(".sh") || /^git-credentials-.*\.config$/.test(entry)) {
152964
- tryUnlink(join12(runnerTemp, entry));
152979
+ tryUnlink(join13(runnerTemp, entry));
152965
152980
  }
152966
152981
  }
152967
152982
  if (wiped.length > 0) {
@@ -153470,7 +153485,7 @@ function CheckoutPrTool(ctx) {
153470
153485
  headSha: ctx.toolState.checkoutSha
153471
153486
  });
153472
153487
  if (incremental) {
153473
- incrementalDiffPath = join13(
153488
+ incrementalDiffPath = join14(
153474
153489
  tempDir,
153475
153490
  `pr-${pull_number}-${beforeShort}-${headShort}-incremental.diff`
153476
153491
  );
@@ -153484,7 +153499,7 @@ function CheckoutPrTool(ctx) {
153484
153499
  const diffPreview = formatResult.content.split("\n").slice(0, 100).join("\n");
153485
153500
  log.debug(`formatted diff preview (first 100 lines):
153486
153501
  ${diffPreview}`);
153487
- const diffPath = join13(tempDir, `pr-${pull_number}-${headShort}.diff`);
153502
+ const diffPath = join14(tempDir, `pr-${pull_number}-${headShort}.diff`);
153488
153503
  writeFileSync8(diffPath, formatResult.content);
153489
153504
  log.debug(`wrote diff to ${diffPath} (${formatResult.content.length} bytes)`);
153490
153505
  ctx.toolState.diffCoverage = createDiffCoverageState({
@@ -153593,7 +153608,7 @@ ${dirty}`
153593
153608
 
153594
153609
  // mcp/checkSuite.ts
153595
153610
  import { mkdirSync as mkdirSync7, writeFileSync as writeFileSync9 } from "node:fs";
153596
- import { join as join14 } from "node:path";
153611
+ import { join as join15 } from "node:path";
153597
153612
  var GetCheckSuiteLogs = type({
153598
153613
  check_suite_id: type.number.describe("the id from check_suite.id")
153599
153614
  });
@@ -153689,7 +153704,7 @@ function GetCheckSuiteLogsTool(ctx) {
153689
153704
  if (!tempDir) {
153690
153705
  throw new Error("PULLFROG_TEMP_DIR not set");
153691
153706
  }
153692
- const logsDir = join14(tempDir, "ci-logs");
153707
+ const logsDir = join15(tempDir, "ci-logs");
153693
153708
  mkdirSync7(logsDir, { recursive: true });
153694
153709
  const jobResults = [];
153695
153710
  for (const run4 of failedRuns) {
@@ -153716,7 +153731,7 @@ function GetCheckSuiteLogsTool(ctx) {
153716
153731
  );
153717
153732
  }
153718
153733
  const logsText = await logsResult.text();
153719
- const logPath = join14(logsDir, `job-${job.id}.log`);
153734
+ const logPath = join15(logsDir, `job-${job.id}.log`);
153720
153735
  writeFileSync9(logPath, logsText);
153721
153736
  const analysis = analyzeLog(logsText, 80);
153722
153737
  const failedSteps = job.steps?.filter((s) => s.conclusion === "failure").map((s) => `Step ${s.number}: ${s.name}`) ?? [];
@@ -153766,7 +153781,7 @@ function GetCheckSuiteLogsTool(ctx) {
153766
153781
 
153767
153782
  // mcp/commitInfo.ts
153768
153783
  import { writeFileSync as writeFileSync10 } from "node:fs";
153769
- import { join as join15 } from "node:path";
153784
+ import { join as join16 } from "node:path";
153770
153785
  var CommitInfo = type({
153771
153786
  sha: type.string.describe("the commit SHA (full or abbreviated) to fetch")
153772
153787
  });
@@ -153790,7 +153805,7 @@ function CommitInfoTool(ctx) {
153790
153805
  "PULLFROG_TEMP_DIR not set - get_commit_info must run in pullfrog action context"
153791
153806
  );
153792
153807
  }
153793
- const diffFile = join15(tempDir, `commit-${sha.slice(0, 7)}.diff`);
153808
+ const diffFile = join16(tempDir, `commit-${sha.slice(0, 7)}.diff`);
153794
153809
  writeFileSync10(diffFile, formatResult.content);
153795
153810
  log.debug(`wrote commit diff to ${diffFile} (${formatResult.content.length} bytes)`);
153796
153811
  return {
@@ -154452,7 +154467,7 @@ function PullRequestInfoTool(ctx) {
154452
154467
 
154453
154468
  // mcp/reviewComments.ts
154454
154469
  import { writeFileSync as writeFileSync11 } from "node:fs";
154455
- import { join as join16 } from "node:path";
154470
+ import { join as join17 } from "node:path";
154456
154471
  var REVIEW_THREADS_QUERY = `
154457
154472
  query ($owner: String!, $name: String!, $prNumber: Int!) {
154458
154473
  repository(owner: $owner, name: $name) {
@@ -154868,7 +154883,7 @@ function GetReviewCommentsTool(ctx) {
154868
154883
  throw new Error("PULLFROG_TEMP_DIR not set");
154869
154884
  }
154870
154885
  const filename = `review-${params.review_id}-threads.md`;
154871
- const commentsPath = join16(tempDir, filename);
154886
+ const commentsPath = join17(tempDir, filename);
154872
154887
  writeFileSync11(commentsPath, formatted.content);
154873
154888
  log.debug(`wrote ${threadBlocks.length} threads to ${commentsPath}`);
154874
154889
  return {
@@ -155106,7 +155121,7 @@ import { spawn as spawn4, spawnSync as spawnSync5 } from "node:child_process";
155106
155121
  import { randomUUID as randomUUID4 } from "node:crypto";
155107
155122
  import { closeSync, openSync, writeFileSync as writeFileSync12 } from "node:fs";
155108
155123
  import { userInfo as userInfo2 } from "node:os";
155109
- import { join as join17 } from "node:path";
155124
+ import { join as join18 } from "node:path";
155110
155125
  import { setTimeout as sleep2 } from "node:timers/promises";
155111
155126
  var ShellParams = type({
155112
155127
  command: "string",
@@ -155269,7 +155284,7 @@ function getTempDir() {
155269
155284
  var MAX_OUTPUT_CHARS = 5e3;
155270
155285
  function capOutput(output) {
155271
155286
  if (output.length <= MAX_OUTPUT_CHARS) return output;
155272
- const fullPath = join17(getTempDir(), `shell-${randomUUID4().slice(0, 8)}.log`);
155287
+ const fullPath = join18(getTempDir(), `shell-${randomUUID4().slice(0, 8)}.log`);
155273
155288
  writeFileSync12(fullPath, output);
155274
155289
  const elided = output.length - MAX_OUTPUT_CHARS;
155275
155290
  return `... [${elided} chars truncated; full output saved to ${fullPath}] ...
@@ -155324,8 +155339,8 @@ Do NOT use this tool for git commands \u2014 use the dedicated git tools instead
155324
155339
  if (params.background) {
155325
155340
  const tempDir = getTempDir();
155326
155341
  const handle = `bg-${randomUUID4().slice(0, 8)}`;
155327
- const outputPath = join17(tempDir, `${handle}.log`);
155328
- const pidPath = join17(tempDir, `${handle}.pid`);
155342
+ const outputPath = join18(tempDir, `${handle}.log`);
155343
+ const pidPath = join18(tempDir, `${handle}.pid`);
155329
155344
  const logFd = openSync(outputPath, "a");
155330
155345
  let proc2;
155331
155346
  try {
@@ -155886,7 +155901,7 @@ function selectFallbackModelIfNeeded(input) {
155886
155901
  import { randomUUID as randomUUID5 } from "node:crypto";
155887
155902
  import { writeFileSync as writeFileSync13 } from "node:fs";
155888
155903
  import { createServer as createServer3 } from "node:http";
155889
- import { join as join18 } from "node:path";
155904
+ import { join as join19 } from "node:path";
155890
155905
  var REVOKED_TRAP_MS = 6e4;
155891
155906
  function revokeGitHubToken(token) {
155892
155907
  fetch("https://api.github.com/installation/token", {
@@ -155955,7 +155970,7 @@ async function startGitAuthServer(tmpdir4) {
155955
155970
  function writeAskpassScript(code) {
155956
155971
  const scriptId = randomUUID5();
155957
155972
  const scriptName = `askpass-${scriptId}.js`;
155958
- const scriptPath = join18(tmpdir4, scriptName);
155973
+ const scriptPath = join19(tmpdir4, scriptName);
155959
155974
  const content = [
155960
155975
  `#!/usr/bin/env node`,
155961
155976
  `var a=process.argv[2]||"";`,
@@ -155993,7 +156008,7 @@ async function startGitAuthServer(tmpdir4) {
155993
156008
  var core3 = __toESM(require_core(), 1);
155994
156009
  import { createSign } from "node:crypto";
155995
156010
  import { rename, writeFile } from "node:fs/promises";
155996
- import { dirname as dirname3, join as join19 } from "node:path";
156011
+ import { dirname as dirname3, join as join20 } from "node:path";
155997
156012
 
155998
156013
  // node_modules/.pnpm/@octokit+plugin-throttling@11.0.3_@octokit+core@7.0.5/node_modules/@octokit/plugin-throttling/dist-bundle/index.js
155999
156014
  var import_light = __toESM(require_light(), 1);
@@ -159851,7 +159866,7 @@ function getGitHubUsageSummary() {
159851
159866
  }
159852
159867
  async function writeGitHubUsageSummaryToFile(path4) {
159853
159868
  const summary2 = getGitHubUsageSummary();
159854
- const tmpPath = join19(dirname3(path4), `.usage-summary-${process.pid}.tmp`);
159869
+ const tmpPath = join20(dirname3(path4), `.usage-summary-${process.pid}.tmp`);
159855
159870
  await writeFile(tmpPath, JSON.stringify(summary2));
159856
159871
  await rename(tmpPath, path4);
159857
159872
  }
@@ -160269,7 +160284,7 @@ function resolveInstructions(ctx) {
160269
160284
 
160270
160285
  // utils/learnings.ts
160271
160286
  import { mkdir as mkdir2, readFile as readFile3, writeFile as writeFile2 } from "node:fs/promises";
160272
- import { dirname as dirname4, join as join20 } from "node:path";
160287
+ import { dirname as dirname4, join as join21 } from "node:path";
160273
160288
 
160274
160289
  // utils/learningsTruncate.ts
160275
160290
  var MAX_LEARNINGS_LENGTH = 1e5;
@@ -160286,7 +160301,7 @@ function truncateAtLineBoundary(body, cap) {
160286
160301
  // utils/learnings.ts
160287
160302
  var LEARNINGS_FILE_NAME = "pullfrog-learnings.md";
160288
160303
  function learningsFilePath(tmpdir4) {
160289
- return join20(tmpdir4, LEARNINGS_FILE_NAME);
160304
+ return join21(tmpdir4, LEARNINGS_FILE_NAME);
160290
160305
  }
160291
160306
  async function seedLearningsFile(params) {
160292
160307
  const path4 = learningsFilePath(params.tmpdir);
@@ -160967,7 +160982,7 @@ async function runProxyResolution(ctx) {
160967
160982
 
160968
160983
  // utils/prSummary.ts
160969
160984
  import { mkdir as mkdir3, readFile as readFile4, writeFile as writeFile3 } from "node:fs/promises";
160970
- import { dirname as dirname5, join as join21 } from "node:path";
160985
+ import { dirname as dirname5, join as join22 } from "node:path";
160971
160986
  var SUMMARY_FILE_NAME = "pullfrog-summary.md";
160972
160987
  var SUMMARY_SCAFFOLD = `# PR summary
160973
160988
 
@@ -160977,7 +160992,7 @@ var SUMMARY_SCAFFOLD = `# PR summary
160977
160992
  var MIN_SNAPSHOT_LENGTH = 60;
160978
160993
  var MAX_SNAPSHOT_LENGTH = 32768;
160979
160994
  function summaryFilePath(tmpdir4) {
160980
- return join21(tmpdir4, SUMMARY_FILE_NAME);
160995
+ return join22(tmpdir4, SUMMARY_FILE_NAME);
160981
160996
  }
160982
160997
  async function seedSummaryFile(params) {
160983
160998
  const path4 = summaryFilePath(params.tmpdir);
@@ -161988,7 +162003,7 @@ ${instructions.user}` : null,
161988
162003
  log.info(instructions.full);
161989
162004
  });
161990
162005
  if (agentId === "opencode") {
161991
- const pluginDir = join22(process.cwd(), ".opencode", "plugin");
162006
+ const pluginDir = join23(process.cwd(), ".opencode", "plugin");
161992
162007
  const hasPlugins = existsSync8(pluginDir) && readdirSync2(pluginDir).some((f) => /\.[jt]sx?$/.test(f));
161993
162008
  if (hasPlugins && toolState.dependencyInstallation?.promise) {
161994
162009
  log.info(
@@ -163046,7 +163061,7 @@ async function run2() {
163046
163061
  }
163047
163062
 
163048
163063
  // cli.ts
163049
- var VERSION10 = "0.1.28";
163064
+ var VERSION10 = "0.1.29";
163050
163065
  var bin = basename2(process.argv[1] || "");
163051
163066
  var PROG = bin === "pf" || bin === "pullfrog" ? bin : "pullfrog";
163052
163067
  var rawArgs = process.argv.slice(2);
package/dist/index.js CHANGED
@@ -93492,14 +93492,14 @@ var require_turndown_cjs = __commonJS({
93492
93492
  } else if (node2.nodeType === 1) {
93493
93493
  replacement = replacementForNode.call(self2, node2);
93494
93494
  }
93495
- return join22(output, replacement);
93495
+ return join23(output, replacement);
93496
93496
  }, "");
93497
93497
  }
93498
93498
  function postProcess(output) {
93499
93499
  var self2 = this;
93500
93500
  this.rules.forEach(function(rule) {
93501
93501
  if (typeof rule.append === "function") {
93502
- output = join22(output, rule.append(self2.options));
93502
+ output = join23(output, rule.append(self2.options));
93503
93503
  }
93504
93504
  });
93505
93505
  return output.replace(/^[\t\r\n]+/, "").replace(/[\t\r\n\s]+$/, "");
@@ -93511,7 +93511,7 @@ var require_turndown_cjs = __commonJS({
93511
93511
  if (whitespace.leading || whitespace.trailing) content = content.trim();
93512
93512
  return whitespace.leading + rule.replacement(content, node2, this.options) + whitespace.trailing;
93513
93513
  }
93514
- function join22(output, replacement) {
93514
+ function join23(output, replacement) {
93515
93515
  var s1 = trimTrailingNewlines(output);
93516
93516
  var s2 = trimLeadingNewlines(replacement);
93517
93517
  var nls = Math.max(output.length - s1.length, replacement.length - s2.length);
@@ -98926,7 +98926,7 @@ var require_fast_content_type_parse = __commonJS({
98926
98926
  // main.ts
98927
98927
  import { existsSync as existsSync8, readdirSync as readdirSync2 } from "node:fs";
98928
98928
  import { readFile as readFile5 } from "node:fs/promises";
98929
- import { join as join21 } from "node:path";
98929
+ import { join as join22 } from "node:path";
98930
98930
 
98931
98931
  // agents/claude.ts
98932
98932
  import { execFileSync as execFileSync2 } from "node:child_process";
@@ -100067,7 +100067,7 @@ var import_semver = __toESM(require_semver2(), 1);
100067
100067
  // package.json
100068
100068
  var package_default = {
100069
100069
  name: "pullfrog",
100070
- version: "0.1.28",
100070
+ version: "0.1.29",
100071
100071
  type: "module",
100072
100072
  bin: {
100073
100073
  pullfrog: "dist/cli.mjs",
@@ -149499,7 +149499,7 @@ function closeBrowserDaemon(toolState) {
149499
149499
  // mcp/checkout.ts
149500
149500
  import { createHash as createHash2 } from "node:crypto";
149501
149501
  import { statSync, unlinkSync as unlinkSync3, writeFileSync as writeFileSync7 } from "node:fs";
149502
- import { join as join12 } from "node:path";
149502
+ import { join as join13 } from "node:path";
149503
149503
 
149504
149504
  // utils/diffCoverage.ts
149505
149505
  import { isAbsolute, normalize as normalize2, resolve } from "node:path";
@@ -149769,6 +149769,7 @@ function readNumber(params) {
149769
149769
  import { execSync } from "node:child_process";
149770
149770
  import { createHash } from "node:crypto";
149771
149771
  import { readFileSync as readFileSync2, realpathSync, unlinkSync } from "node:fs";
149772
+ import { join as join10 } from "node:path";
149772
149773
 
149773
149774
  // utils/shell.ts
149774
149775
  import { spawnSync as spawnSync4 } from "node:child_process";
@@ -149838,6 +149839,18 @@ function verifyGitBinary() {
149838
149839
  }
149839
149840
  return gitBinary.path;
149840
149841
  }
149842
+ var hooksDirCache = /* @__PURE__ */ new Map();
149843
+ function resolveHooksDir(cwd, gitPath) {
149844
+ const cached4 = hooksDirCache.get(cwd);
149845
+ if (cached4) return cached4;
149846
+ const commonDir = $(gitPath, ["rev-parse", "--path-format=absolute", "--git-common-dir"], {
149847
+ cwd,
149848
+ log: false
149849
+ }).trim();
149850
+ const hooksDir = join10(commonDir, "hooks");
149851
+ hooksDirCache.set(cwd, hooksDir);
149852
+ return hooksDir;
149853
+ }
149841
149854
  var authServer;
149842
149855
  function setGitAuthServer(server) {
149843
149856
  authServer = server;
@@ -149859,6 +149872,8 @@ async function $git(subcommand, args2, options) {
149859
149872
  "protocol.file.allow=never",
149860
149873
  "-c",
149861
149874
  "core.sshCommand=ssh",
149875
+ "-c",
149876
+ `core.hooksPath=${resolveHooksDir(cwd, gitPath)}`,
149862
149877
  subcommand,
149863
149878
  ...args2
149864
149879
  ];
@@ -150128,7 +150143,7 @@ function postProcessRangeDiff(raw2, contextLines = 3) {
150128
150143
  // mcp/git.ts
150129
150144
  import { randomUUID as randomUUID3 } from "node:crypto";
150130
150145
  import { writeFileSync as writeFileSync6 } from "node:fs";
150131
- import { join as join10 } from "node:path";
150146
+ import { join as join11 } from "node:path";
150132
150147
  function getPushDestination(branch, storedDest) {
150133
150148
  if (storedDest && storedDest.localBranch === branch) {
150134
150149
  log.debug(`using stored push destination: ${storedDest.remoteName}/${storedDest.remoteBranch}`);
@@ -150446,7 +150461,7 @@ function countAhead(head, base) {
150446
150461
  function spillGitOutput(params) {
150447
150462
  const tempDir = process.env.PULLFROG_TEMP_DIR;
150448
150463
  if (!tempDir) throw new Error("PULLFROG_TEMP_DIR not set");
150449
- const outputPath = join10(tempDir, `git-${params.command}-${randomUUID3().slice(0, 8)}.txt`);
150464
+ const outputPath = join11(tempDir, `git-${params.command}-${randomUUID3().slice(0, 8)}.txt`);
150450
150465
  writeFileSync6(outputPath, params.output);
150451
150466
  const previewByLines = params.output.split("\n").slice(0, OVERFLOW_PREVIEW_LINES).join("\n");
150452
150467
  const preview = previewByLines.length <= OVERFLOW_PREVIEW_MAX_CHARS ? previewByLines : `${previewByLines.slice(0, OVERFLOW_PREVIEW_MAX_CHARS)}\u2026`;
@@ -151150,9 +151165,9 @@ async function reportReviewNodeId(ctx, params) {
151150
151165
  import { execFileSync as execFileSync6, execSync as execSync2 } from "node:child_process";
151151
151166
  import { mkdtempSync, readdirSync, realpathSync as realpathSync2, unlinkSync as unlinkSync2 } from "node:fs";
151152
151167
  import { tmpdir as tmpdir2 } from "node:os";
151153
- import { join as join11 } from "node:path";
151168
+ import { join as join12 } from "node:path";
151154
151169
  function createTempDirectory() {
151155
- const sharedTempDir = mkdtempSync(join11(tmpdir2(), "pullfrog-"));
151170
+ const sharedTempDir = mkdtempSync(join12(tmpdir2(), "pullfrog-"));
151156
151171
  process.env.PULLFROG_TEMP_DIR = sharedTempDir;
151157
151172
  log.info(`\xBB created temp dir at ${sharedTempDir}`);
151158
151173
  return sharedTempDir;
@@ -151197,13 +151212,13 @@ function wipeRunnerLeakSurface() {
151197
151212
  return [];
151198
151213
  }
151199
151214
  };
151200
- const fileCommandsDir = join11(runnerTemp, "_runner_file_commands");
151215
+ const fileCommandsDir = join12(runnerTemp, "_runner_file_commands");
151201
151216
  for (const entry of listDir(fileCommandsDir)) {
151202
- tryUnlink(join11(fileCommandsDir, entry));
151217
+ tryUnlink(join12(fileCommandsDir, entry));
151203
151218
  }
151204
151219
  for (const entry of listDir(runnerTemp)) {
151205
151220
  if (entry.endsWith(".sh") || /^git-credentials-.*\.config$/.test(entry)) {
151206
- tryUnlink(join11(runnerTemp, entry));
151221
+ tryUnlink(join12(runnerTemp, entry));
151207
151222
  }
151208
151223
  }
151209
151224
  if (wiped.length > 0) {
@@ -151712,7 +151727,7 @@ function CheckoutPrTool(ctx) {
151712
151727
  headSha: ctx.toolState.checkoutSha
151713
151728
  });
151714
151729
  if (incremental) {
151715
- incrementalDiffPath = join12(
151730
+ incrementalDiffPath = join13(
151716
151731
  tempDir,
151717
151732
  `pr-${pull_number}-${beforeShort}-${headShort}-incremental.diff`
151718
151733
  );
@@ -151726,7 +151741,7 @@ function CheckoutPrTool(ctx) {
151726
151741
  const diffPreview = formatResult.content.split("\n").slice(0, 100).join("\n");
151727
151742
  log.debug(`formatted diff preview (first 100 lines):
151728
151743
  ${diffPreview}`);
151729
- const diffPath = join12(tempDir, `pr-${pull_number}-${headShort}.diff`);
151744
+ const diffPath = join13(tempDir, `pr-${pull_number}-${headShort}.diff`);
151730
151745
  writeFileSync7(diffPath, formatResult.content);
151731
151746
  log.debug(`wrote diff to ${diffPath} (${formatResult.content.length} bytes)`);
151732
151747
  ctx.toolState.diffCoverage = createDiffCoverageState({
@@ -151835,7 +151850,7 @@ ${dirty}`
151835
151850
 
151836
151851
  // mcp/checkSuite.ts
151837
151852
  import { mkdirSync as mkdirSync7, writeFileSync as writeFileSync8 } from "node:fs";
151838
- import { join as join13 } from "node:path";
151853
+ import { join as join14 } from "node:path";
151839
151854
  var GetCheckSuiteLogs = type({
151840
151855
  check_suite_id: type.number.describe("the id from check_suite.id")
151841
151856
  });
@@ -151931,7 +151946,7 @@ function GetCheckSuiteLogsTool(ctx) {
151931
151946
  if (!tempDir) {
151932
151947
  throw new Error("PULLFROG_TEMP_DIR not set");
151933
151948
  }
151934
- const logsDir = join13(tempDir, "ci-logs");
151949
+ const logsDir = join14(tempDir, "ci-logs");
151935
151950
  mkdirSync7(logsDir, { recursive: true });
151936
151951
  const jobResults = [];
151937
151952
  for (const run of failedRuns) {
@@ -151958,7 +151973,7 @@ function GetCheckSuiteLogsTool(ctx) {
151958
151973
  );
151959
151974
  }
151960
151975
  const logsText = await logsResult.text();
151961
- const logPath = join13(logsDir, `job-${job.id}.log`);
151976
+ const logPath = join14(logsDir, `job-${job.id}.log`);
151962
151977
  writeFileSync8(logPath, logsText);
151963
151978
  const analysis = analyzeLog(logsText, 80);
151964
151979
  const failedSteps = job.steps?.filter((s) => s.conclusion === "failure").map((s) => `Step ${s.number}: ${s.name}`) ?? [];
@@ -152008,7 +152023,7 @@ function GetCheckSuiteLogsTool(ctx) {
152008
152023
 
152009
152024
  // mcp/commitInfo.ts
152010
152025
  import { writeFileSync as writeFileSync9 } from "node:fs";
152011
- import { join as join14 } from "node:path";
152026
+ import { join as join15 } from "node:path";
152012
152027
  var CommitInfo = type({
152013
152028
  sha: type.string.describe("the commit SHA (full or abbreviated) to fetch")
152014
152029
  });
@@ -152032,7 +152047,7 @@ function CommitInfoTool(ctx) {
152032
152047
  "PULLFROG_TEMP_DIR not set - get_commit_info must run in pullfrog action context"
152033
152048
  );
152034
152049
  }
152035
- const diffFile = join14(tempDir, `commit-${sha.slice(0, 7)}.diff`);
152050
+ const diffFile = join15(tempDir, `commit-${sha.slice(0, 7)}.diff`);
152036
152051
  writeFileSync9(diffFile, formatResult.content);
152037
152052
  log.debug(`wrote commit diff to ${diffFile} (${formatResult.content.length} bytes)`);
152038
152053
  return {
@@ -152694,7 +152709,7 @@ function PullRequestInfoTool(ctx) {
152694
152709
 
152695
152710
  // mcp/reviewComments.ts
152696
152711
  import { writeFileSync as writeFileSync10 } from "node:fs";
152697
- import { join as join15 } from "node:path";
152712
+ import { join as join16 } from "node:path";
152698
152713
  var REVIEW_THREADS_QUERY = `
152699
152714
  query ($owner: String!, $name: String!, $prNumber: Int!) {
152700
152715
  repository(owner: $owner, name: $name) {
@@ -153110,7 +153125,7 @@ function GetReviewCommentsTool(ctx) {
153110
153125
  throw new Error("PULLFROG_TEMP_DIR not set");
153111
153126
  }
153112
153127
  const filename = `review-${params.review_id}-threads.md`;
153113
- const commentsPath = join15(tempDir, filename);
153128
+ const commentsPath = join16(tempDir, filename);
153114
153129
  writeFileSync10(commentsPath, formatted.content);
153115
153130
  log.debug(`wrote ${threadBlocks.length} threads to ${commentsPath}`);
153116
153131
  return {
@@ -153348,7 +153363,7 @@ import { spawn as spawn2, spawnSync as spawnSync5 } from "node:child_process";
153348
153363
  import { randomUUID as randomUUID4 } from "node:crypto";
153349
153364
  import { closeSync, openSync, writeFileSync as writeFileSync11 } from "node:fs";
153350
153365
  import { userInfo as userInfo2 } from "node:os";
153351
- import { join as join16 } from "node:path";
153366
+ import { join as join17 } from "node:path";
153352
153367
  import { setTimeout as sleep2 } from "node:timers/promises";
153353
153368
  var ShellParams = type({
153354
153369
  command: "string",
@@ -153511,7 +153526,7 @@ function getTempDir() {
153511
153526
  var MAX_OUTPUT_CHARS = 5e3;
153512
153527
  function capOutput(output) {
153513
153528
  if (output.length <= MAX_OUTPUT_CHARS) return output;
153514
- const fullPath = join16(getTempDir(), `shell-${randomUUID4().slice(0, 8)}.log`);
153529
+ const fullPath = join17(getTempDir(), `shell-${randomUUID4().slice(0, 8)}.log`);
153515
153530
  writeFileSync11(fullPath, output);
153516
153531
  const elided = output.length - MAX_OUTPUT_CHARS;
153517
153532
  return `... [${elided} chars truncated; full output saved to ${fullPath}] ...
@@ -153566,8 +153581,8 @@ Do NOT use this tool for git commands \u2014 use the dedicated git tools instead
153566
153581
  if (params.background) {
153567
153582
  const tempDir = getTempDir();
153568
153583
  const handle = `bg-${randomUUID4().slice(0, 8)}`;
153569
- const outputPath = join16(tempDir, `${handle}.log`);
153570
- const pidPath = join16(tempDir, `${handle}.pid`);
153584
+ const outputPath = join17(tempDir, `${handle}.log`);
153585
+ const pidPath = join17(tempDir, `${handle}.pid`);
153571
153586
  const logFd = openSync(outputPath, "a");
153572
153587
  let proc2;
153573
153588
  try {
@@ -154128,7 +154143,7 @@ function selectFallbackModelIfNeeded(input) {
154128
154143
  import { randomUUID as randomUUID5 } from "node:crypto";
154129
154144
  import { writeFileSync as writeFileSync12 } from "node:fs";
154130
154145
  import { createServer as createServer3 } from "node:http";
154131
- import { join as join17 } from "node:path";
154146
+ import { join as join18 } from "node:path";
154132
154147
  var REVOKED_TRAP_MS = 6e4;
154133
154148
  function revokeGitHubToken(token) {
154134
154149
  fetch("https://api.github.com/installation/token", {
@@ -154197,7 +154212,7 @@ async function startGitAuthServer(tmpdir3) {
154197
154212
  function writeAskpassScript(code) {
154198
154213
  const scriptId = randomUUID5();
154199
154214
  const scriptName = `askpass-${scriptId}.js`;
154200
- const scriptPath = join17(tmpdir3, scriptName);
154215
+ const scriptPath = join18(tmpdir3, scriptName);
154201
154216
  const content = [
154202
154217
  `#!/usr/bin/env node`,
154203
154218
  `var a=process.argv[2]||"";`,
@@ -154235,7 +154250,7 @@ async function startGitAuthServer(tmpdir3) {
154235
154250
  var core3 = __toESM(require_core(), 1);
154236
154251
  import { createSign } from "node:crypto";
154237
154252
  import { rename, writeFile } from "node:fs/promises";
154238
- import { dirname as dirname3, join as join18 } from "node:path";
154253
+ import { dirname as dirname3, join as join19 } from "node:path";
154239
154254
 
154240
154255
  // node_modules/.pnpm/@octokit+plugin-throttling@11.0.3_@octokit+core@7.0.5/node_modules/@octokit/plugin-throttling/dist-bundle/index.js
154241
154256
  var import_light = __toESM(require_light(), 1);
@@ -158093,7 +158108,7 @@ function getGitHubUsageSummary() {
158093
158108
  }
158094
158109
  async function writeGitHubUsageSummaryToFile(path4) {
158095
158110
  const summary2 = getGitHubUsageSummary();
158096
- const tmpPath = join18(dirname3(path4), `.usage-summary-${process.pid}.tmp`);
158111
+ const tmpPath = join19(dirname3(path4), `.usage-summary-${process.pid}.tmp`);
158097
158112
  await writeFile(tmpPath, JSON.stringify(summary2));
158098
158113
  await rename(tmpPath, path4);
158099
158114
  }
@@ -158511,7 +158526,7 @@ function resolveInstructions(ctx) {
158511
158526
 
158512
158527
  // utils/learnings.ts
158513
158528
  import { mkdir as mkdir2, readFile as readFile3, writeFile as writeFile2 } from "node:fs/promises";
158514
- import { dirname as dirname4, join as join19 } from "node:path";
158529
+ import { dirname as dirname4, join as join20 } from "node:path";
158515
158530
 
158516
158531
  // utils/learningsTruncate.ts
158517
158532
  var MAX_LEARNINGS_LENGTH = 1e5;
@@ -158528,7 +158543,7 @@ function truncateAtLineBoundary(body, cap) {
158528
158543
  // utils/learnings.ts
158529
158544
  var LEARNINGS_FILE_NAME = "pullfrog-learnings.md";
158530
158545
  function learningsFilePath(tmpdir3) {
158531
- return join19(tmpdir3, LEARNINGS_FILE_NAME);
158546
+ return join20(tmpdir3, LEARNINGS_FILE_NAME);
158532
158547
  }
158533
158548
  async function seedLearningsFile(params) {
158534
158549
  const path4 = learningsFilePath(params.tmpdir);
@@ -159209,7 +159224,7 @@ async function runProxyResolution(ctx) {
159209
159224
 
159210
159225
  // utils/prSummary.ts
159211
159226
  import { mkdir as mkdir3, readFile as readFile4, writeFile as writeFile3 } from "node:fs/promises";
159212
- import { dirname as dirname5, join as join20 } from "node:path";
159227
+ import { dirname as dirname5, join as join21 } from "node:path";
159213
159228
  var SUMMARY_FILE_NAME = "pullfrog-summary.md";
159214
159229
  var SUMMARY_SCAFFOLD = `# PR summary
159215
159230
 
@@ -159219,7 +159234,7 @@ var SUMMARY_SCAFFOLD = `# PR summary
159219
159234
  var MIN_SNAPSHOT_LENGTH = 60;
159220
159235
  var MAX_SNAPSHOT_LENGTH = 32768;
159221
159236
  function summaryFilePath(tmpdir3) {
159222
- return join20(tmpdir3, SUMMARY_FILE_NAME);
159237
+ return join21(tmpdir3, SUMMARY_FILE_NAME);
159223
159238
  }
159224
159239
  async function seedSummaryFile(params) {
159225
159240
  const path4 = summaryFilePath(params.tmpdir);
@@ -160230,7 +160245,7 @@ ${instructions.user}` : null,
160230
160245
  log.info(instructions.full);
160231
160246
  });
160232
160247
  if (agentId === "opencode") {
160233
- const pluginDir = join21(process.cwd(), ".opencode", "plugin");
160248
+ const pluginDir = join22(process.cwd(), ".opencode", "plugin");
160234
160249
  const hasPlugins = existsSync8(pluginDir) && readdirSync2(pluginDir).some((f) => /\.[jt]sx?$/.test(f));
160235
160250
  if (hasPlugins && toolState.dependencyInstallation?.promise) {
160236
160251
  log.info(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pullfrog",
3
- "version": "0.1.28",
3
+ "version": "0.1.29",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "pullfrog": "dist/cli.mjs",