@link-assistant/hive-mind 1.56.16 → 1.56.17

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,11 @@
1
1
  # @link-assistant/hive-mind
2
2
 
3
+ ## 1.56.17
4
+
5
+ ### Patch Changes
6
+
7
+ - b693172: Improve the repository-not-accessible error message in `/solve` (issue #1692). The headline drops the redundant "not found or" wording and the technical "(GitHub returns 404 for private repos without permissions)" parenthetical, leads with the most-actionable hypothesis ("Repository may be private — ensure the bot has been granted access"), and only suggests `--auto-accept-invite` when that flag is _not_ already active. The Telegram bot surface picks up the same suppression so users do not see the hint echoed back when they already passed the flag.
8
+
3
9
  ## 1.56.16
4
10
 
5
11
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@link-assistant/hive-mind",
3
- "version": "1.56.16",
3
+ "version": "1.56.17",
4
4
  "description": "AI-powered issue solver and hive mind for collaborative problem solving",
5
5
  "main": "src/hive.mjs",
6
6
  "type": "module",
@@ -21,13 +21,16 @@ import { ghPrView, ghIssueView } from './github.lib.mjs';
21
21
  * @param {number|string} [options.number] - Issue or PR number (if applicable)
22
22
  * @param {string} [options.type] - URL type: 'issue' or 'pull'
23
23
  * @param {boolean} [options.verbose=false] - Whether verbose logging is enabled
24
+ * @param {boolean} [options.autoAcceptInvite=false] - Whether the caller already passed
25
+ * `--auto-accept-invite`. When true, the repo-404 message omits the suggestion to
26
+ * use that flag, since it would not be actionable (issue #1692).
24
27
  * @returns {Promise<{valid: boolean, error?: string, level?: string, details?: string}>}
25
28
  * - valid: true if all entities exist and are accessible
26
29
  * - error: user-facing error message (when valid=false)
27
30
  * - level: which entity level failed ('user', 'repo', 'issue', 'pull')
28
31
  * - details: additional context for verbose logging
29
32
  */
30
- export async function validateGitHubEntityExistence({ owner, repo, number, type, verbose = false }) {
33
+ export async function validateGitHubEntityExistence({ owner, repo, number, type, verbose = false, autoAcceptInvite = false }) {
31
34
  // Step 1: Check user/organization existence
32
35
  try {
33
36
  const userResult = await ghCmdRetry(() => $`gh api users/${owner} --jq .login`, { label: `check user ${owner}` });
@@ -53,9 +56,13 @@ export async function validateGitHubEntityExistence({ owner, repo, number, type,
53
56
  if (repoResult.code !== 0) {
54
57
  const errorOutput = (repoResult.stderr ? repoResult.stderr.toString() : '') + (repoResult.stdout ? repoResult.stdout.toString() : '');
55
58
  if (errorOutput.includes('404') || errorOutput.includes('Not Found')) {
59
+ const bullets = ['• Repository may be private — ensure the bot has been granted access', '• The repository name is spelled correctly', '• The repository has not been deleted, transferred, or never existed'];
60
+ if (!autoAcceptInvite) {
61
+ bullets.push('• If Hive Mind bot was recently invited, try using --auto-accept-invite to accept pending invitations');
62
+ }
56
63
  return {
57
64
  valid: false,
58
- error: `Repository '${owner}/${repo}' not found or not accessible.\n\n💡 Please check:\n• The repository name is spelled correctly\n• If it's a private repository, ensure the bot has been granted access (GitHub returns 404 for private repos without permissions)\n• The repository has not been deleted or transferred\n• If you were recently invited, try using --auto-accept-invite to accept pending invitations`,
65
+ error: `Repository '${owner}/${repo}' is not accessible.\n\n💡 Please check:\n${bullets.join('\n')}`,
59
66
  level: 'repo',
60
67
  };
61
68
  }
package/src/solve.mjs CHANGED
@@ -290,7 +290,7 @@ if (!hasWriteAccess) {
290
290
  }
291
291
 
292
292
  // Issue #1552: Validate entity existence AFTER permissions (cascade: user/org → repo → issue/PR)
293
- const entityCheck = await (await import('./github-entity-validation.lib.mjs')).validateGitHubEntityExistence({ owner, repo, number: urlNumber, type: isIssueUrl ? 'issue' : isPrUrl ? 'pull' : undefined, verbose: argv.verbose });
293
+ const entityCheck = await (await import('./github-entity-validation.lib.mjs')).validateGitHubEntityExistence({ owner, repo, number: urlNumber, type: isIssueUrl ? 'issue' : isPrUrl ? 'pull' : undefined, verbose: argv.verbose, autoAcceptInvite: !!argv.autoAcceptInvite });
294
294
  if (!entityCheck.valid) {
295
295
  await log(`\n❌ ${entityCheck.error}\n`, { level: 'error' });
296
296
  await safeExit(1, `GitHub entity not found (${entityCheck.level})`);
@@ -974,7 +974,7 @@ async function handleSolveCommand(ctx) {
974
974
  VERBOSE && console.log(`[VERBOSE] Auto-accept invite pre-check failed: ${e.message}`);
975
975
  }
976
976
  }
977
- const entityCheck = await validateGitHubEntityExistence({ owner: validation.parsed.owner, repo: validation.parsed.repo, number: validation.parsed.number, type: validation.parsed.type, verbose: VERBOSE });
977
+ const entityCheck = await validateGitHubEntityExistence({ owner: validation.parsed.owner, repo: validation.parsed.repo, number: validation.parsed.number, type: validation.parsed.type, verbose: VERBOSE, autoAcceptInvite: args.some(a => a === '--auto-accept-invite') });
978
978
  if (!entityCheck.valid) {
979
979
  await safeReply(ctx, `❌ ${escapeMarkdown(entityCheck.error)}`, { reply_to_message_id: ctx.message.message_id });
980
980
  return;