@link-assistant/hive-mind 1.25.3 → 1.25.5
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 +24 -0
- package/package.json +1 -1
- package/src/agent.lib.mjs +0 -1
- package/src/agent.prompts.lib.mjs +2 -2
- package/src/claude.prompts.lib.mjs +2 -2
- package/src/github-merge.lib.mjs +44 -0
- package/src/solve.auto-merge.lib.mjs +32 -8
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# @link-assistant/hive-mind
|
|
2
2
|
|
|
3
|
+
## 1.25.5
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- e0d68a4: fix: prevent false positive 'Ready to merge' for repos with CI but no required branch protection (Issue #1363)
|
|
8
|
+
|
|
9
|
+
Previously, the auto-merge logic would incorrectly declare a PR "Ready to merge — no CI/CD configured" when a repository had GitHub Actions workflows but no required status checks in branch protection rules. This happened because:
|
|
10
|
+
- `mergeStateStatus=CLEAN` (no required checks to block merging)
|
|
11
|
+
- `check_runs=[]` (CI hadn't started yet — race condition, GitHub takes ~10-30s to register checks)
|
|
12
|
+
|
|
13
|
+
The fix adds a workflow detection step (`getActiveRepoWorkflows`) that queries the GitHub Actions API to check if the repository has any active workflows. When workflows exist but no checks have started, the system now correctly identifies this as a race condition (CI hasn't started yet) rather than "no CI configured", and waits for the checks to appear before proceeding.
|
|
14
|
+
|
|
15
|
+
Full case study analysis in `docs/case-studies/issue-1363/`.
|
|
16
|
+
|
|
17
|
+
## 1.25.4
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- 2a670b0: fix: use universal GitHub blob URL format for screenshots to fix broken images in private repositories (Issue #1349)
|
|
22
|
+
|
|
23
|
+
Previously, the system prompt instructed AI agents to embed screenshots using `raw.githubusercontent.com` URLs. These URLs always return HTTP 404 for private repositories because GitHub does not authenticate raw content requests when rendering PR description markdown.
|
|
24
|
+
|
|
25
|
+
Now agents are instructed to use the `https://github.com/{owner}/{repo}/blob/{branch}/path?raw=true` URL format instead, which works for both public and private repositories. This simplifies the implementation by removing the need to check repository visibility at all.
|
|
26
|
+
|
|
3
27
|
## 1.25.3
|
|
4
28
|
|
|
5
29
|
### Patch Changes
|
package/package.json
CHANGED
package/src/agent.lib.mjs
CHANGED
|
@@ -408,7 +408,6 @@ export const executeAgent = async params => {
|
|
|
408
408
|
if (argv.verbose) {
|
|
409
409
|
await log(`👁️ Model vision capability: ${modelSupportsVision ? 'supported' : 'not supported'}`, { verbose: true });
|
|
410
410
|
}
|
|
411
|
-
|
|
412
411
|
// Build the user prompt
|
|
413
412
|
const prompt = buildUserPrompt({
|
|
414
413
|
issueUrl,
|
|
@@ -230,8 +230,8 @@ GitHub CLI command patterns.
|
|
|
230
230
|
Visual UI work and screenshots.
|
|
231
231
|
- When you work on visual UI changes (frontend, CSS, HTML, design), include a render or screenshot of the final result in the pull request description.
|
|
232
232
|
- When you need to show visual results, take a screenshot and save it to the repository (e.g., in a docs/screenshots/ or assets/ folder).
|
|
233
|
-
- When you save screenshots to the repository, use permanent
|
|
234
|
-
- When uploading images, commit them to the branch first, then reference them using the
|
|
233
|
+
- When you save screenshots to the repository, use permanent links in the pull request description markdown (e.g., https://github.com/${owner}/${repo}/blob/${branchName}/docs/screenshots/result.png?raw=true).
|
|
234
|
+
- When uploading images, commit them to the branch first, then reference them using the GitHub blob URL format with ?raw=true suffix (works for both public and private repositories).
|
|
235
235
|
- When the visual result is important for review, mention it explicitly in the pull request description with the embedded image.`
|
|
236
236
|
: ''
|
|
237
237
|
}${ciExamples}${getArchitectureCareSubPrompt(argv)}`;
|
|
@@ -319,8 +319,8 @@ Agent Commander usage (unified subagent delegation).
|
|
|
319
319
|
Visual UI work and screenshots.
|
|
320
320
|
- When you work on visual UI changes (frontend, CSS, HTML, design), include a render or screenshot of the final result in the pull request description.
|
|
321
321
|
- When you need to show visual results, take a screenshot and save it to the repository (e.g., in a docs/screenshots/ or assets/ folder).
|
|
322
|
-
- When you save screenshots to the repository, use permanent
|
|
323
|
-
- When uploading images, commit them to the branch first, then reference them using the
|
|
322
|
+
- When you save screenshots to the repository, use permanent links in the pull request description markdown (e.g., https://github.com/${owner}/${repo}/blob/${branchName}/docs/screenshots/result.png?raw=true).
|
|
323
|
+
- When uploading images, commit them to the branch first, then reference them using the GitHub blob URL format with ?raw=true suffix (works for both public and private repositories).
|
|
324
324
|
- When the visual result is important for review, mention it explicitly in the pull request description with the embedded image.`
|
|
325
325
|
: ''
|
|
326
326
|
}${ciExamples}${getArchitectureCareSubPrompt(argv)}`;
|
package/src/github-merge.lib.mjs
CHANGED
|
@@ -1227,6 +1227,48 @@ export async function getWorkflowRunsForSha(owner, repo, sha, verbose = false) {
|
|
|
1227
1227
|
}
|
|
1228
1228
|
}
|
|
1229
1229
|
|
|
1230
|
+
/**
|
|
1231
|
+
* Get the count of active (enabled) GitHub Actions workflows in a repository
|
|
1232
|
+
* Issue #1363: Used to distinguish between "no CI configured" and "CI hasn't started yet"
|
|
1233
|
+
*
|
|
1234
|
+
* When a repo has NO workflows, no_checks means no CI configured.
|
|
1235
|
+
* When a repo HAS workflows, no_checks means CI checks haven't started yet (race condition).
|
|
1236
|
+
*
|
|
1237
|
+
* @param {string} owner - Repository owner
|
|
1238
|
+
* @param {string} repo - Repository name
|
|
1239
|
+
* @param {boolean} verbose - Whether to log verbose output
|
|
1240
|
+
* @returns {Promise<{count: number, hasWorkflows: boolean, workflows: Array<{id: number, name: string, state: string}>}>}
|
|
1241
|
+
*/
|
|
1242
|
+
export async function getActiveRepoWorkflows(owner, repo, verbose = false) {
|
|
1243
|
+
try {
|
|
1244
|
+
const { stdout } = await exec(`gh api "repos/${owner}/${repo}/actions/workflows" --jq '[.workflows[] | select(.state == "active")] | map({id: .id, name: .name, state: .state})'`);
|
|
1245
|
+
const workflows = JSON.parse(stdout.trim() || '[]');
|
|
1246
|
+
|
|
1247
|
+
if (verbose) {
|
|
1248
|
+
console.log(`[VERBOSE] /merge: Found ${workflows.length} active workflows in ${owner}/${repo}`);
|
|
1249
|
+
for (const wf of workflows) {
|
|
1250
|
+
console.log(`[VERBOSE] /merge: - ${wf.name} (${wf.id}): ${wf.state}`);
|
|
1251
|
+
}
|
|
1252
|
+
}
|
|
1253
|
+
|
|
1254
|
+
return {
|
|
1255
|
+
count: workflows.length,
|
|
1256
|
+
hasWorkflows: workflows.length > 0,
|
|
1257
|
+
workflows,
|
|
1258
|
+
};
|
|
1259
|
+
} catch (error) {
|
|
1260
|
+
if (verbose) {
|
|
1261
|
+
console.log(`[VERBOSE] /merge: Error fetching workflows for ${owner}/${repo}: ${error.message}`);
|
|
1262
|
+
}
|
|
1263
|
+
// On error, assume no workflows (safer: avoids false positives in the no-CI case)
|
|
1264
|
+
return {
|
|
1265
|
+
count: 0,
|
|
1266
|
+
hasWorkflows: false,
|
|
1267
|
+
workflows: [],
|
|
1268
|
+
};
|
|
1269
|
+
}
|
|
1270
|
+
}
|
|
1271
|
+
|
|
1230
1272
|
// Issue #1341: Import and re-export post-merge CI functions from separate module
|
|
1231
1273
|
// to keep this file under the 1500 line limit
|
|
1232
1274
|
import { waitForCommitCI, checkBranchCIHealth, getMergeCommitSha } from './github-merge-ci.lib.mjs';
|
|
@@ -1265,4 +1307,6 @@ export default {
|
|
|
1265
1307
|
waitForCommitCI,
|
|
1266
1308
|
checkBranchCIHealth,
|
|
1267
1309
|
getMergeCommitSha,
|
|
1310
|
+
// Issue #1363: Detect active workflows to distinguish "no CI" from race condition
|
|
1311
|
+
getActiveRepoWorkflows,
|
|
1268
1312
|
};
|
|
@@ -33,7 +33,7 @@ const { reportError } = sentryLib;
|
|
|
33
33
|
|
|
34
34
|
// Import GitHub merge functions
|
|
35
35
|
const githubMergeLib = await import('./github-merge.lib.mjs');
|
|
36
|
-
const { checkPRMergeable, checkMergePermissions, mergePullRequest, waitForCI, checkForBillingLimitError, getRepoVisibility, BILLING_LIMIT_ERROR_PATTERN, getDetailedCIStatus, rerunWorkflowRun, getWorkflowRunsForSha } = githubMergeLib;
|
|
36
|
+
const { checkPRMergeable, checkMergePermissions, mergePullRequest, waitForCI, checkForBillingLimitError, getRepoVisibility, BILLING_LIMIT_ERROR_PATTERN, getDetailedCIStatus, rerunWorkflowRun, getWorkflowRunsForSha, getActiveRepoWorkflows } = githubMergeLib;
|
|
37
37
|
|
|
38
38
|
// Import GitHub functions for log attachment
|
|
39
39
|
const githubLib = await import('./github.lib.mjs');
|
|
@@ -197,14 +197,38 @@ const getMergeBlockers = async (owner, repo, prNumber, verbose = false) => {
|
|
|
197
197
|
// Otherwise (e.g. mergeStateStatus === 'BLOCKED'), treat as pending race condition.
|
|
198
198
|
const earlyMergeStatus = await checkPRMergeable(owner, repo, prNumber, verbose);
|
|
199
199
|
if (earlyMergeStatus.mergeable) {
|
|
200
|
-
//
|
|
201
|
-
//
|
|
202
|
-
//
|
|
203
|
-
|
|
204
|
-
|
|
200
|
+
// Issue #1363: Before concluding "no CI configured", verify the repo actually
|
|
201
|
+
// has no active GitHub Actions workflows. If workflows exist but no checks have
|
|
202
|
+
// started yet, this is a race condition (GitHub takes ~10-30s to register checks
|
|
203
|
+
// after a push), NOT a "no CI configured" situation.
|
|
204
|
+
//
|
|
205
|
+
// This fixes a false positive where a repo with CI workflows but WITHOUT branch
|
|
206
|
+
// protection (required status checks) would be declared "no CI configured" because:
|
|
207
|
+
// - mergeStateStatus=CLEAN (no required checks to block it)
|
|
208
|
+
// - check_runs=[] (CI hasn't started yet — race condition)
|
|
209
|
+
const repoWorkflows = await getActiveRepoWorkflows(owner, repo, verbose);
|
|
210
|
+
if (repoWorkflows.hasWorkflows) {
|
|
211
|
+
// Repo HAS workflows — this is a race condition, not "no CI configured"
|
|
212
|
+
// Wait for CI checks to appear
|
|
213
|
+
if (verbose) {
|
|
214
|
+
console.log(`[VERBOSE] /merge: PR #${prNumber} has no CI checks yet, but repo has ${repoWorkflows.count} active workflow(s) - treating as race condition (CI hasn't started)`);
|
|
215
|
+
}
|
|
216
|
+
blockers.push({
|
|
217
|
+
type: 'ci_pending',
|
|
218
|
+
message: `CI/CD checks have not started yet (${repoWorkflows.count} workflow(s) configured, waiting for checks to appear)`,
|
|
219
|
+
details: repoWorkflows.workflows.map(wf => wf.name),
|
|
220
|
+
});
|
|
221
|
+
} else {
|
|
222
|
+
// Repo has NO workflows — this is truly "no CI configured"
|
|
223
|
+
// PR is already mergeable with no CI checks configured.
|
|
224
|
+
// Do NOT add a ci_pending blocker. The mergeability check below will also
|
|
225
|
+
// confirm this is mergeable, so blockers will be empty → PR IS MERGEABLE path.
|
|
226
|
+
if (verbose) {
|
|
227
|
+
console.log(`[VERBOSE] /merge: PR #${prNumber} has no CI checks and repo has no active workflows - no CI/CD configured`);
|
|
228
|
+
}
|
|
229
|
+
// Return early with no CI blocker, mergeability already confirmed
|
|
230
|
+
return { blockers, ciStatus, noCiConfigured: true };
|
|
205
231
|
}
|
|
206
|
-
// Return early with no CI blocker, mergeability already confirmed
|
|
207
|
-
return { blockers, ciStatus, noCiConfigured: true };
|
|
208
232
|
} else {
|
|
209
233
|
// PR is not yet mergeable despite no checks - treat as pending race condition
|
|
210
234
|
blockers.push({
|