@link-assistant/hive-mind 1.16.0 → 1.17.0

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.
@@ -1178,17 +1178,59 @@ export const setupPrForkRemote = async (tempDir, argv, prForkOwner, repo, isCont
1178
1178
  }
1179
1179
 
1180
1180
  // This is someone else's fork - add it as pr-fork remote
1181
- // Determine the fork repository name (might be prefixed if --prefix-fork-name-with-owner-name was used)
1182
- // Try both standard and prefixed names
1183
- let prForkRepoName = repo;
1184
- if (owner && argv.prefixForkNameWithOwnerName) {
1185
- // When prefix option is enabled, try prefixed name first
1186
- prForkRepoName = `${owner}-${repo}`;
1187
- }
1181
+ // IMPORTANT: The fork owner's repository name is independent of our naming preferences
1182
+ // We need to discover the actual fork name, not assume it matches our convention
1183
+ // This fixes issue #1217 where incorrect fork name was used
1188
1184
 
1189
1185
  await log(`${formatAligned('🔗', 'Setting up pr-fork:', "Branch exists in another user's fork")}`);
1190
1186
  await log(`${formatAligned('', 'PR fork owner:', prForkOwner)}`);
1191
1187
  await log(`${formatAligned('', 'Current user:', currentUser)}`);
1188
+
1189
+ // Discover the actual fork repository name by querying GitHub API
1190
+ // The fork could have any name (standard, prefixed, or custom renamed)
1191
+ let prForkRepoName = null;
1192
+
1193
+ // Strategy 1: Query the upstream repo's forks to find this user's fork
1194
+ if (owner) {
1195
+ await log(`${formatAligned('🔍', 'Discovering fork name:', `Searching ${owner}/${repo}/forks for ${prForkOwner}'s fork...`)}`);
1196
+ const forksResult = await $`gh api repos/${owner}/${repo}/forks --paginate --jq '.[] | select(.owner.login == "${prForkOwner}") | .name'`;
1197
+ if (forksResult.code === 0 && forksResult.stdout) {
1198
+ const forkName = forksResult.stdout.toString().trim().split('\n')[0]; // Take first match
1199
+ if (forkName) {
1200
+ prForkRepoName = forkName;
1201
+ await log(`${formatAligned('✅', 'Found fork:', `${prForkOwner}/${prForkRepoName}`)}`);
1202
+ }
1203
+ }
1204
+ }
1205
+
1206
+ // Strategy 2: If not found in forks list, try common naming patterns
1207
+ if (!prForkRepoName) {
1208
+ const possibleNames = [
1209
+ repo, // Standard name: "eo2js"
1210
+ owner ? `${owner}-${repo}` : null, // Prefixed name: "objectionary-eo2js"
1211
+ ].filter(Boolean);
1212
+
1213
+ await log(`${formatAligned('🔍', 'Trying common names:', possibleNames.join(', '))}`);
1214
+
1215
+ for (const candidateName of possibleNames) {
1216
+ const checkResult = await $`gh repo view ${prForkOwner}/${candidateName} --json name 2>/dev/null`;
1217
+ if (checkResult.code === 0) {
1218
+ prForkRepoName = candidateName;
1219
+ await log(`${formatAligned('✅', 'Found fork:', `${prForkOwner}/${prForkRepoName}`)}`);
1220
+ break;
1221
+ }
1222
+ }
1223
+ }
1224
+
1225
+ // If still not found, we cannot proceed
1226
+ if (!prForkRepoName) {
1227
+ await log(`${formatAligned('❌', 'Error:', `Could not find ${prForkOwner}'s fork of ${owner}/${repo}`)}`);
1228
+ await log(`${formatAligned('', 'Checked:', `${prForkOwner}/${repo} and ${prForkOwner}/${owner}-${repo}`)}`);
1229
+ await log(`${formatAligned('', 'Suggestion:', 'The fork may have been deleted or renamed')}`);
1230
+ await log(`${formatAligned('', 'Workaround:', 'Remove --fork flag to continue work in the original fork')}`);
1231
+ return null;
1232
+ }
1233
+
1192
1234
  await log(`${formatAligned('', 'Action:', `Adding ${prForkOwner}/${prForkRepoName} as pr-fork remote`)}`);
1193
1235
 
1194
1236
  const addRemoteResult = await $({
@@ -1224,7 +1266,8 @@ export const setupPrForkRemote = async (tempDir, argv, prForkOwner, repo, isCont
1224
1266
  };
1225
1267
 
1226
1268
  // Checkout branch for continue mode (PR branch from remote)
1227
- export const checkoutPrBranch = async (tempDir, branchName, prForkRemote, prForkOwner) => {
1269
+ // prNumber is optional - when provided, enables PR refs fallback (refs/pull/{number}/head)
1270
+ export const checkoutPrBranch = async (tempDir, branchName, prForkRemote, prForkOwner, prNumber = null) => {
1228
1271
  await log(`\n${formatAligned('🔄', 'Checking out PR branch:', branchName)}`);
1229
1272
 
1230
1273
  // Determine which remote to use for branch checkout
@@ -1287,6 +1330,32 @@ export const checkoutPrBranch = async (tempDir, branchName, prForkRemote, prFork
1287
1330
  }
1288
1331
  }
1289
1332
  }
1333
+
1334
+ // FALLBACK: If all remote checks failed and we have a PR number,
1335
+ // use GitHub's special PR refs (refs/pull/{number}/head)
1336
+ // This works regardless of fork naming conventions and doesn't require fork access
1337
+ // See: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/checking-out-pull-requests-locally
1338
+ if (checkoutResult.code !== 0 && prNumber) {
1339
+ await log(`${formatAligned('🔄', 'Trying PR refs fallback:', `Fetching refs/pull/${prNumber}/head...`)}`);
1340
+
1341
+ // Fetch the PR head using GitHub's special refs
1342
+ const prRefFetchResult = await $({ cwd: tempDir })`git fetch origin pull/${prNumber}/head:${branchName}`;
1343
+
1344
+ if (prRefFetchResult.code === 0) {
1345
+ await log(`${formatAligned('✅', 'Fetched PR ref:', `refs/pull/${prNumber}/head`)}`);
1346
+ checkoutResult = await $({ cwd: tempDir })`git checkout ${branchName}`;
1347
+
1348
+ if (checkoutResult.code === 0) {
1349
+ await log(`${formatAligned('â„šī¸', 'Note:', 'Checked out using GitHub PR refs (fork access not required)')}`);
1350
+ await log(`${formatAligned('', '', 'This is a read-only checkout - you may need to push to a different branch')}`);
1351
+ }
1352
+ } else {
1353
+ await log(`${formatAligned('âš ī¸', 'PR refs fallback failed:', 'Could not fetch PR head')}`);
1354
+ if (prRefFetchResult.stderr) {
1355
+ await log(`${formatAligned('', 'Details:', prRefFetchResult.stderr.toString().trim())}`);
1356
+ }
1357
+ }
1358
+ }
1290
1359
  }
1291
1360
 
1292
1361
  return checkoutResult;