@diffohq/diffo 0.17.0 → 0.17.1

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/cli.mjs CHANGED
@@ -3536,6 +3536,20 @@ async function fetchPrHeadAsync(root, number, remote = "origin") {
3536
3536
  function fetchBranch(root, branch, remote = "origin") {
3537
3537
  fetchSync(root, [remote, branch]);
3538
3538
  }
3539
+ async function fetchBranchAsync(root, branch, remote = "origin") {
3540
+ await execFileAsync("git", [
3541
+ "fetch",
3542
+ "--quiet",
3543
+ remote,
3544
+ branch
3545
+ ], {
3546
+ cwd: root,
3547
+ encoding: "utf-8",
3548
+ maxBuffer: MAX_BUFFER,
3549
+ timeout: FETCH_TIMEOUT_MS,
3550
+ env: FETCH_ENV
3551
+ });
3552
+ }
3539
3553
  function revParse(root, ref) {
3540
3554
  try {
3541
3555
  return git(root, [
@@ -5157,11 +5171,19 @@ function prepareWorktree(repoPath, ref, baseBranch, db, home = homedir()) {
5157
5171
  * Move an existing worktree to the pull request's head, if it is clean.
5158
5172
  * `headSha` is what the forge just reported: the fetch runs only when the
5159
5173
  * local ref is not there yet, so a quiet PR costs no network on any tick.
5174
+ *
5175
+ * The base branch is fetched with the head. The diff is cut at the merge-base
5176
+ * with `<remote>/<baseBranch>`, and a head that moved has usually caught up
5177
+ * with the base: against the base as it was at the open, every commit the
5178
+ * base gained in between reads as the pull request's own change.
5160
5179
  */
5161
- async function advanceWorktree(repoPath, worktreePath, ref, headSha) {
5180
+ async function advanceWorktree(repoPath, worktreePath, ref, headSha, baseBranch) {
5162
5181
  const root = resolve(repoPath);
5163
5182
  const head = prHeadRef(ref.number);
5164
- if (revParse(root, head) !== headSha) await fetchPrHeadAsync(root, ref.number, remoteForPr(root, ref));
5183
+ if (revParse(root, head) !== headSha) {
5184
+ const remote = remoteForPr(root, ref);
5185
+ await Promise.all([fetchPrHeadAsync(root, ref.number, remote), fetchBranchAsync(root, baseBranch, remote)]);
5186
+ }
5165
5187
  const sha = revParse(root, head);
5166
5188
  if (sha === null) return null;
5167
5189
  if (revParse(worktreePath, "HEAD") === sha) return {
@@ -5337,14 +5359,14 @@ var PrPuller = class {
5337
5359
  }
5338
5360
  if (before && before.head.sha !== pr.head.sha) log?.(`pull request head moved ${before.head.sha.slice(0, 7)} → ${pr.head.sha.slice(0, 7)}`);
5339
5361
  try {
5340
- const moved = await advanceWorktree(this.deps.mainRepo, this.deps.worktree, ref, pr.head.sha);
5362
+ const moved = await advanceWorktree(this.deps.mainRepo, this.deps.worktree, ref, pr.head.sha, this.deps.baseBranch);
5341
5363
  this.lastFetchError = null;
5342
5364
  if (moved?.moved) {
5343
5365
  log?.(`worktree advanced to ${moved.sha.slice(0, 7)}`);
5344
5366
  await store.refresh();
5345
5367
  }
5346
5368
  } catch (err) {
5347
- const message = `could not fetch the pull request head: ${err.message.split("\n")[0]}`;
5369
+ const message = `could not fetch the pull request: ${err.message.split("\n")[0]}`;
5348
5370
  if (message !== this.lastFetchError) {
5349
5371
  this.lastFetchError = message;
5350
5372
  log?.(message);
@@ -8046,6 +8068,7 @@ function startServer(options) {
8046
8068
  ref: options.pr.ref,
8047
8069
  mainRepo: options.pr.mainRepo,
8048
8070
  worktree: options.root,
8071
+ baseBranch: options.pr.baseBranch,
8049
8072
  store,
8050
8073
  review,
8051
8074
  db,
@@ -9233,12 +9256,13 @@ async function openPullRequest(target, ref, baseOverride, explicitPr) {
9233
9256
  }
9234
9257
  if (pr.state !== "open") process.stderr.write(`diffo: pull request #${pr.number} is ${pr.state}, opening it read-mostly\n`);
9235
9258
  const mainRepo = mainRepoOf(repoPath);
9259
+ const baseBranch = baseOverride ?? pr.base.ref;
9236
9260
  const db = new DiffoDb();
9237
9261
  let prepared;
9238
9262
  try {
9239
9263
  const own = worktreePathFor(mainRepo, ref.number);
9240
9264
  for (const entry of sweepWorktrees(db, mainRepo, { except: own })) if (entry.outcome === "removed") process.stderr.write(`diffo: removed the worktree for ${entry.record.prKey} (${entry.reason})\n`);
9241
- prepared = prepareWorktree(mainRepo, ref, baseOverride ?? pr.base.ref, db);
9265
+ prepared = prepareWorktree(mainRepo, ref, baseBranch, db);
9242
9266
  } catch (err) {
9243
9267
  fail(`could not check the pull request out: ${err.message}`);
9244
9268
  } finally {
@@ -9252,7 +9276,8 @@ async function openPullRequest(target, ref, baseOverride, explicitPr) {
9252
9276
  context: {
9253
9277
  ref,
9254
9278
  forge,
9255
- mainRepo
9279
+ mainRepo,
9280
+ baseBranch
9256
9281
  }
9257
9282
  };
9258
9283
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@diffohq/diffo",
3
- "version": "0.17.0",
3
+ "version": "0.17.1",
4
4
  "description": "Local, live code review for the AI age — read what the agent wrote and send feedback straight back, or review a GitHub pull request with your agent beside you",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
package/plugin.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
3
3
  "name": "diffo",
4
- "version": "0.17.0",
4
+ "version": "0.17.1",
5
5
  "description": "Local, live code review for the AI age — read what the agent wrote and send feedback straight back, or review a GitHub pull request with your agent beside you",
6
6
  "author": {
7
7
  "name": "DiffoHQ",