@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.
- package/CHANGELOG.md +19 -0
- package/package.json +1 -1
- package/src/hive.config.lib.mjs +90 -203
- package/src/hive.mjs +33 -28
- package/src/option-suggestions.lib.mjs +12 -0
- package/src/solve.branch.lib.mjs +2 -1
- package/src/solve.config.lib.mjs +389 -372
- package/src/solve.repository.lib.mjs +77 -8
|
@@ -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
|
-
//
|
|
1182
|
-
//
|
|
1183
|
-
|
|
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
|
-
|
|
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;
|