@link-assistant/hive-mind 1.27.0 → 1.29.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 CHANGED
@@ -1,5 +1,47 @@
1
1
  # @link-assistant/hive-mind
2
2
 
3
+ ## 1.29.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 161b595: feat: add --auto-accept-invite option to solve command
8
+
9
+ Adds a new `--auto-accept-invite` boolean option to the `solve` command that automatically accepts the pending GitHub repository or organization invitation for the specific repository/organization being solved, before checking write access.
10
+
11
+ Unlike the `/accept_invites` Telegram command (which accepts ALL pending invitations), this option is scoped to the target repo/org only, making it safer and more targeted. Useful when you've just been invited to a repository and want to run `solve` without manually accepting the invitation first.
12
+
13
+ ## 1.28.0
14
+
15
+ ### Minor Changes
16
+
17
+ - docs: expand best practices with CI/CD guide, universal prompts, and architecture improvement (Issue #1403)
18
+
19
+ Splits the existing `docs/BEST-PRACTICES.md` into two focused documents:
20
+ - **`docs/CI-CD-BEST-PRACTICES.md`** (renamed from the original) — Updated and expanded CI/CD guide covering all key points from existing workflow templates, including: running checks only on relevant file changes, fast-fail job ordering, fresh merge simulation, concurrency control, changeset exemptions for docs-only PRs, secrets detection, documentation validation, and OIDC trusted publishing.
21
+ - **`docs/BEST-PRACTICES.md`** (new general guide) — Universal best practices for AI-driven development including: deep analysis bug/feature prompts, universal validation prompt, plan mode prompt, issue writing guidelines with acceptance criteria patterns, an architecture improvement prompt linking to the Code Architecture Principles repository, CI/CD summary with link to the CI/CD guide, and subagent coordination patterns.
22
+
23
+ Also updates `README.md` to link to both new documents in the Best Practices section.
24
+
25
+ feat: enable --auto-restart-until-mergeable by default (Issue #1360)
26
+
27
+ The `--auto-restart-until-mergeable` feature has become stable enough to be enabled by default. Previously, users had to explicitly pass this flag to enable automatic restart until the PR becomes mergeable.
28
+
29
+ Now the feature is enabled by default, meaning the solver will automatically restart on new comments from non-bot users, CI failures, merge conflicts, or other issues — without requiring any extra flags. Users who want to disable this behavior can pass `--no-auto-restart-until-mergeable`.
30
+
31
+ fix: filter GitHub Pages deployment workflows from PR CI check (Issue #1399)
32
+
33
+ `getActiveRepoWorkflows()` included the `pages-build-deployment` workflow (path: `dynamic/pages/pages-build-deployment`) as if it were a PR CI workflow. This workflow is auto-created by GitHub for GitHub Pages and only runs on the default branch after merge — it never creates check-runs on PR branches. As a result, `--auto-restart-until-mergeable` got stuck in an infinite loop waiting for CI checks that would never appear.
34
+
35
+ The fix filters out workflows with the `dynamic/pages/` prefix from `getActiveRepoWorkflows()`. These are GitHub Pages internal workflows, not user-defined CI pipelines.
36
+
37
+ Affected scenario: repositories with GitHub Pages enabled but no `.github/workflows/` files (e.g., `konard/links-visuals`).
38
+
39
+ fix: resolve Prettier formatting issue in README.md (Issue #1401)
40
+
41
+ The CI/CD `lint` job was failing on the `main` branch because README.md had Prettier formatting violations after commit `da376061` ("Clarify Time Freedom and Any Device Programming features"). That commit added longer text to two table cells, which made the table column widths inconsistent with Prettier's expected format.
42
+
43
+ The fix runs `prettier --write` on README.md to re-align the table column widths, bringing the file back into conformance with the `format:check` CI step.
44
+
3
45
  ## 1.27.0
4
46
 
5
47
  ### Minor Changes
package/README.md CHANGED
@@ -21,18 +21,18 @@ Inspired by [konard/problem-solving](https://github.com/konard/problem-solving)
21
21
 
22
22
  Hive Mind is a **generalist AI** (mini-AGI) capable of working on a wide range of tasks - not just programming. Almost anything that can be done with files in a repository can be automated.
23
23
 
24
- | Feature | What It Means For You |
25
- | ---------------------------- | -------------------------------------------------------------------------------------------------- |
26
- | **No Babysitting** | Full autonomous mode with sudo access. AI has creative freedom like a real programmer. |
27
- | **Cloud Isolation** | Runs on dedicated VMs or Docker. Easy to restore if broken. |
28
- | **Full Internet + Sudo** | AI can install packages, fetch docs, and configure the system as needed. |
29
- | **Pre-installed Toolchain** | 25GB+ ready: 10 language runtimes, 2 theorem provers, build tools. Can install more. |
30
- | **Token Efficiency** | Routine tasks automated in code, so AI tokens focus on creative problem-solving. |
31
- | **Time Freedom** | What takes humans 2-8 hours, AI completes in 10-25 minutes. "The code is written while you sleep." |
32
- | **Scale with Orchestration** | Parallel workers feel like a team of developers, all for ~$200/month. |
33
- | **Human Control** | AI creates draft PRs - you decide what merges. Quality gates where they matter. |
34
- | **Any Device Programming** | Manage AI from any device with `/solve` and `/hive`. No PC, IDE, or laptop required. |
35
- | **100% Open Source** | Unlicense (public domain). Full transparency, no vendor lock-in. |
24
+ | Feature | What It Means For You |
25
+ | ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
26
+ | **No Babysitting** | Full autonomous mode with sudo access. AI has creative freedom like a real programmer. |
27
+ | **Cloud Isolation** | Runs on dedicated VMs or Docker. Easy to restore if broken. |
28
+ | **Full Internet + Sudo** | AI can install packages, fetch docs, and configure the system as needed. |
29
+ | **Pre-installed Toolchain** | 25GB+ ready: 10 language runtimes, 2 theorem provers, build tools. Can install more. |
30
+ | **Token Efficiency** | Routine tasks automated in code, so AI tokens focus on creative problem-solving. |
31
+ | **Time Freedom** | What takes humans 2-8 hours, AI completes each working session in 10-25 minutes. Mass execution of tasks in repository is possible. "The code is written while you sleep." |
32
+ | **Scale with Orchestration** | Parallel workers feel like a team of developers, all for ~$200/month. |
33
+ | **Human Control** | AI creates draft PRs - you decide what merges. Quality gates where they matter. |
34
+ | **Any Device Programming** | Manage AI from any device with `/solve` and `/hive` via Telegram bot. No PC, IDE, or laptop required. |
35
+ | **100% Open Source** | Unlicense (public domain). Full transparency, no vendor lock-in. |
36
36
 
37
37
  > _"Compared to Codex for $200, this solution is fire."_ - User feedback
38
38
 
@@ -404,9 +404,9 @@ The Hive Mind includes a Telegram bot interface (SwarmMindBot) for remote comman
404
404
 
405
405
  ### 🚀 Test Drive
406
406
 
407
- Want to see the Hive Mind in action? Join our Telegram channel where you can execute the Hive Mind on your own issues and watch AI solve them:
407
+ Want to see the Hive Mind in action? Request a free demo or get faster support by messaging the developer directly on Telegram:
408
408
 
409
- **[Join https://t.me/hive_mind_pull_requests](https://t.me/hive_mind_pull_requests)**
409
+ **[Message @drakonard on Telegram](https://t.me/drakonard)**
410
410
 
411
411
  ### Setup
412
412
 
@@ -839,6 +839,30 @@ screen -wipe
839
839
  screen -ls
840
840
  ```
841
841
 
842
+ ### Top with full arguments of each command
843
+
844
+ ```bash
845
+ top -c
846
+ ```
847
+
848
+ ### See the full tree of processes
849
+
850
+ ```bash
851
+ ps -eo pid,ppid,user,args --forest
852
+ ```
853
+
854
+ or
855
+
856
+ ```bash
857
+ ps axjf
858
+ ```
859
+
860
+ ### Kill all commands spawned by specific task
861
+
862
+ ```bash
863
+ pkill -f gh-issue-solver-1773073065743
864
+ ```
865
+
842
866
  That can be done, but not recommended as reboot have better effect.
843
867
 
844
868
  ## 📄 License
@@ -847,7 +871,10 @@ Unlicense License - see [LICENSE](./LICENSE)
847
871
 
848
872
  ## 🏆 Best Practices
849
873
 
850
- Hive Mind works even better when repositories have strong CI/CD pipelines. See [BEST-PRACTICES.md](./docs/BEST-PRACTICES.md) for recommended configurations that maximize AI solver quality.
874
+ Hive Mind works even better when repositories have strong CI/CD pipelines and clear issue requirements. See:
875
+
876
+ - [BEST-PRACTICES.md](./docs/BEST-PRACTICES.md) — Universal prompts, issue writing guidelines, architecture improvement, and subagent patterns
877
+ - [CI-CD-BEST-PRACTICES.md](./docs/CI-CD-BEST-PRACTICES.md) — CI/CD pipeline setup, recommended templates, and enforcement strategies
851
878
 
852
879
  Key benefits of proper CI/CD:
853
880
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@link-assistant/hive-mind",
3
- "version": "1.27.0",
3
+ "version": "1.29.0",
4
4
  "description": "AI-powered issue solver and hive mind for collaborative problem solving",
5
5
  "main": "src/hive.mjs",
6
6
  "type": "module",
@@ -1403,20 +1403,31 @@ export async function getWorkflowRunsForSha(owner, repo, sha, verbose = false) {
1403
1403
  * When a repo has NO workflows, no_checks means no CI configured.
1404
1404
  * When a repo HAS workflows, no_checks means CI checks haven't started yet (race condition).
1405
1405
  *
1406
+ * Issue #1399: GitHub Pages deployment workflows (path: "dynamic/pages/...") are excluded
1407
+ * because they only run on the default branch after merge, never on PR branches. Counting
1408
+ * them as "CI workflows" causes an infinite loop waiting for check-runs that never appear.
1409
+ *
1406
1410
  * @param {string} owner - Repository owner
1407
1411
  * @param {string} repo - Repository name
1408
1412
  * @param {boolean} verbose - Whether to log verbose output
1409
- * @returns {Promise<{count: number, hasWorkflows: boolean, workflows: Array<{id: number, name: string, state: string}>}>}
1413
+ * @returns {Promise<{count: number, hasWorkflows: boolean, workflows: Array<{id: number, name: string, state: string, path: string}>}>}
1410
1414
  */
1411
1415
  export async function getActiveRepoWorkflows(owner, repo, verbose = false) {
1412
1416
  try {
1413
- const { stdout } = await exec(`gh api "repos/${owner}/${repo}/actions/workflows" --jq '[.workflows[] | select(.state == "active")] | map({id: .id, name: .name, state: .state})'`);
1414
- const workflows = JSON.parse(stdout.trim() || '[]');
1417
+ const { stdout } = await exec(`gh api "repos/${owner}/${repo}/actions/workflows" --jq '[.workflows[] | select(.state == "active")] | map({id: .id, name: .name, state: .state, path: .path})'`);
1418
+ const allWorkflows = JSON.parse(stdout.trim() || '[]');
1419
+
1420
+ // Issue #1399: Filter out GitHub Pages deployment workflows.
1421
+ // These have path "dynamic/pages/pages-build-deployment" and only run on the
1422
+ // default branch after merge — they never produce check-runs on PR branches.
1423
+ // Including them causes an infinite loop when waiting for PR CI checks.
1424
+ const workflows = allWorkflows.filter(wf => !wf.path.startsWith('dynamic/pages/'));
1415
1425
 
1416
1426
  if (verbose) {
1417
- console.log(`[VERBOSE] /merge: Found ${workflows.length} active workflows in ${owner}/${repo}`);
1418
- for (const wf of workflows) {
1419
- console.log(`[VERBOSE] /merge: - ${wf.name} (${wf.id}): ${wf.state}`);
1427
+ console.log(`[VERBOSE] /merge: Found ${allWorkflows.length} active workflows in ${owner}/${repo} (${workflows.length} PR-relevant after filtering out GitHub Pages deployment workflows)`);
1428
+ for (const wf of allWorkflows) {
1429
+ const filtered = wf.path.startsWith('dynamic/pages/');
1430
+ console.log(`[VERBOSE] /merge: - ${wf.name} (${wf.id}): ${wf.state}, path=${wf.path}${filtered ? ' [excluded: GitHub Pages deployment]' : ''}`);
1420
1431
  }
1421
1432
  }
1422
1433
 
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Auto-accept GitHub invitation for a specific repository/organization.
3
+ *
4
+ * Unlike the /accept_invites Telegram command (which accepts ALL pending invitations),
5
+ * this module only accepts the invitation for the specific repository or organization
6
+ * that is being solved. This is safer and more targeted.
7
+ *
8
+ * @see https://docs.github.com/en/rest/collaborators/invitations
9
+ * @see https://docs.github.com/en/rest/orgs/members
10
+ * @see https://github.com/link-assistant/hive-mind/issues/1373
11
+ */
12
+
13
+ import { promisify } from 'util';
14
+ import { exec as execCallback } from 'child_process';
15
+
16
+ const exec = promisify(execCallback);
17
+
18
+ /**
19
+ * Accepts pending GitHub repository or organization invitation for a specific target.
20
+ *
21
+ * Checks for a pending repository invitation matching `owner/repo` and/or a pending
22
+ * organization membership for `owner`. Accepts only the matching invitation(s).
23
+ *
24
+ * @param {string} owner - Repository owner (user or organization login)
25
+ * @param {string} repo - Repository name
26
+ * @param {Function} log - Logging function
27
+ * @param {boolean} verbose - Whether verbose logging is enabled
28
+ * @returns {Promise<{acceptedRepo: boolean, acceptedOrg: boolean}>} Result of acceptance attempts
29
+ */
30
+ export async function autoAcceptInviteForRepo(owner, repo, log, verbose) {
31
+ const result = { acceptedRepo: false, acceptedOrg: false };
32
+ const fullName = `${owner}/${repo}`;
33
+
34
+ await log(`🔍 --auto-accept-invite: Checking for pending invitation to ${fullName}...`);
35
+
36
+ // Check for pending repository invitation
37
+ try {
38
+ const { stdout: repoInvJson } = await exec('gh api /user/repository_invitations 2>/dev/null || echo "[]"');
39
+ const repoInvitations = JSON.parse(repoInvJson.trim() || '[]');
40
+ verbose && (await log(` Found ${repoInvitations.length} total pending repo invitation(s)`, { verbose: true }));
41
+
42
+ const matchingInv = repoInvitations.find(inv => inv.repository?.full_name?.toLowerCase() === fullName.toLowerCase());
43
+
44
+ if (matchingInv) {
45
+ try {
46
+ await exec(`gh api -X PATCH /user/repository_invitations/${matchingInv.id}`);
47
+ await log(`✅ --auto-accept-invite: Accepted repository invitation for ${fullName}`);
48
+ result.acceptedRepo = true;
49
+ } catch (e) {
50
+ await log(`⚠️ --auto-accept-invite: Failed to accept repository invitation for ${fullName}: ${e.message}`, { level: 'warning' });
51
+ }
52
+ } else {
53
+ verbose && (await log(` No pending repository invitation found for ${fullName}`, { verbose: true }));
54
+ }
55
+ } catch (e) {
56
+ verbose && (await log(` Could not fetch repository invitations: ${e.message}`, { verbose: true }));
57
+ }
58
+
59
+ // Check for pending organization membership
60
+ try {
61
+ const { stdout: orgMemJson } = await exec('gh api /user/memberships/orgs 2>/dev/null || echo "[]"');
62
+ const orgMemberships = JSON.parse(orgMemJson.trim() || '[]');
63
+ const pendingOrgs = orgMemberships.filter(m => m.state === 'pending');
64
+ verbose && (await log(` Found ${pendingOrgs.length} total pending org invitation(s)`, { verbose: true }));
65
+
66
+ const matchingOrg = pendingOrgs.find(m => m.organization?.login?.toLowerCase() === owner.toLowerCase());
67
+
68
+ if (matchingOrg) {
69
+ const orgName = matchingOrg.organization.login;
70
+ try {
71
+ await exec(`gh api -X PATCH /user/memberships/orgs/${orgName} -f state=active`);
72
+ await log(`✅ --auto-accept-invite: Accepted organization invitation for ${orgName}`);
73
+ result.acceptedOrg = true;
74
+ } catch (e) {
75
+ await log(`⚠️ --auto-accept-invite: Failed to accept organization invitation for ${orgName}: ${e.message}`, { level: 'warning' });
76
+ }
77
+ } else {
78
+ verbose && (await log(` No pending organization invitation found for ${owner}`, { verbose: true }));
79
+ }
80
+ } catch (e) {
81
+ verbose && (await log(` Could not fetch organization memberships: ${e.message}`, { verbose: true }));
82
+ }
83
+
84
+ if (!result.acceptedRepo && !result.acceptedOrg) {
85
+ await log(`ℹ️ --auto-accept-invite: No pending invitation found for ${fullName} or organization ${owner}`);
86
+ }
87
+
88
+ return result;
89
+ }
@@ -179,7 +179,7 @@ export const SOLVE_OPTION_DEFINITIONS = {
179
179
  'auto-restart-until-mergeable': {
180
180
  type: 'boolean',
181
181
  description: 'Auto-restart until PR becomes mergeable (no iteration limit). Restarts on new comments from non-bot users, CI failures, merge conflicts, or other issues. Does NOT auto-merge.',
182
- default: false,
182
+ default: true,
183
183
  },
184
184
  'auto-restart-on-non-updated-pull-request-description': {
185
185
  type: 'boolean',
@@ -369,6 +369,11 @@ export const SOLVE_OPTION_DEFINITIONS = {
369
369
  description: 'Automatically attach solution summary only if the AI did not create any comments during the session. This provides visible feedback when the AI completes silently.',
370
370
  default: false,
371
371
  },
372
+ 'auto-accept-invite': {
373
+ type: 'boolean',
374
+ description: 'Automatically accept the pending GitHub repository or organization invitation for the specific repository/organization being solved, before checking write access. Unlike /accept_invites which accepts all pending invitations, this only accepts the invite for the target repo/org.',
375
+ default: false,
376
+ },
372
377
  };
373
378
 
374
379
  // Function to create yargs configuration - avoids duplication
package/src/solve.mjs CHANGED
@@ -94,6 +94,8 @@ const { prepareFeedbackAndTimestamps, checkUncommittedChanges, checkForkActions
94
94
  // Import model validation library
95
95
  const modelValidation = await import('./model-validation.lib.mjs');
96
96
  const { validateAndExitOnInvalidModel } = modelValidation;
97
+ const acceptInviteLib = await import('./solve.accept-invite.lib.mjs');
98
+ const { autoAcceptInviteForRepo } = acceptInviteLib;
97
99
 
98
100
  // Initialize log file EARLY to capture all output including version and command
99
101
  // Use default directory (cwd) initially, will be set from argv.logDir after parsing
@@ -313,6 +315,11 @@ if (argv.autoFork && !argv.fork) {
313
315
  }
314
316
  }
315
317
 
318
+ // Accept pending GitHub invitation for the specific repo/org before checking write access
319
+ if (argv.autoAcceptInvite) {
320
+ await autoAcceptInviteForRepo(owner, repo, log, argv.verbose);
321
+ }
322
+
316
323
  // Early check: Verify repository write permissions BEFORE doing any work
317
324
  // This prevents wasting AI tokens when user doesn't have access and --fork is not used
318
325
  const { checkRepositoryWritePermission } = githubLib;