@link-assistant/hive-mind 1.23.14 → 1.24.1

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,40 @@
1
1
  # @link-assistant/hive-mind
2
2
 
3
+ ## 1.24.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 4b032ca: fix: use headRepository.name from PR data to construct fork name correctly
8
+
9
+ Previously, when solving a PR from a fork where the fork's repository name
10
+ differs from the base repository name, the tool incorrectly built the fork
11
+ name using the base repo's name instead of the actual head repo name.
12
+
13
+ Example failure scenario (Issue #1332):
14
+ - Base repo: `konard/MILANA808-Milana-backend` (a fork itself)
15
+ - PR head repo: `MILANA808/Milana-backend`
16
+ - Tool tried: `MILANA808/MILANA808-Milana-backend` (wrong, 404)
17
+ - Should try: `MILANA808/Milana-backend` (correct)
18
+
19
+ The fix propagates `forkRepoName` (from `headRepository.name` in PR data)
20
+ through the call chain: `solve.mjs` → `setupRepositoryAndClone` →
21
+ `setupRepository`, where it's used as the correct source of truth for
22
+ building fork repo names. Falls back to base repo name if unavailable.
23
+
24
+ Also improves the error message when a fork cannot be found, clarifying
25
+ that the fork name may differ from the base repo name.
26
+
27
+ ## 1.24.0
28
+
29
+ ### Minor Changes
30
+
31
+ - c93b8cd: Add support for Claude Sonnet 4.6 and set it as the default model for `--tool claude`
32
+ - Added `claude-sonnet-4-6` as the new default model when using `sonnet` alias
33
+ - Added `sonnet-4-6` short alias for explicit Sonnet 4.6 selection
34
+ - Added backward compatibility aliases: `sonnet-4-5` and `claude-sonnet-4-5` for Sonnet 4.5
35
+ - Added 1M token context window support for Sonnet 4.6 (`sonnet[1m]`, `sonnet-4-6[1m]`)
36
+ - Maintained full backward compatibility with previous model versions
37
+
3
38
  ## 1.23.14
4
39
 
5
40
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@link-assistant/hive-mind",
3
- "version": "1.23.14",
3
+ "version": "1.24.1",
4
4
  "description": "AI-powered issue solver and hive mind for collaborative problem solving",
5
5
  "main": "src/hive.mjs",
6
6
  "type": "module",
@@ -6,22 +6,24 @@
6
6
  */
7
7
 
8
8
  // Claude models (Anthropic API)
9
- // Updated for Opus 4.5/4.6 support (Issue #1221, Issue #1238)
9
+ // Updated for Opus 4.5/4.6 and Sonnet 4.6 support (Issue #1221, Issue #1238, Issue #1329)
10
10
  export const claudeModels = {
11
- sonnet: 'claude-sonnet-4-5-20250929', // Sonnet 4.5
12
- opus: 'claude-opus-4-5-20251101', // Opus 4.5 (default, Issue #1238)
11
+ sonnet: 'claude-sonnet-4-6', // Sonnet 4.6 (default, Issue #1329)
12
+ opus: 'claude-opus-4-5-20251101', // Opus 4.5 (Issue #1238)
13
13
  haiku: 'claude-haiku-4-5-20251001', // Haiku 4.5
14
14
  'haiku-3-5': 'claude-3-5-haiku-20241022', // Haiku 3.5
15
15
  'haiku-3': 'claude-3-haiku-20240307', // Haiku 3
16
- // Shorter version aliases (Issue #1221 - PR comment feedback)
16
+ // Shorter version aliases (Issue #1221, Issue #1329 - PR comment feedback)
17
+ 'sonnet-4-6': 'claude-sonnet-4-6', // Sonnet 4.6 short alias (Issue #1329)
17
18
  'opus-4-6': 'claude-opus-4-6', // Opus 4.6 short alias
18
19
  'opus-4-5': 'claude-opus-4-5-20251101', // Opus 4.5 short alias
19
- 'sonnet-4-5': 'claude-sonnet-4-5-20250929', // Sonnet 4.5 short alias
20
+ 'sonnet-4-5': 'claude-sonnet-4-5-20250929', // Sonnet 4.5 short alias (backward compatibility)
20
21
  'haiku-4-5': 'claude-haiku-4-5-20251001', // Haiku 4.5 short alias
21
- // Version aliases for backward compatibility (Issue #1221)
22
+ // Version aliases for backward compatibility (Issue #1221, Issue #1329)
23
+ 'claude-sonnet-4-6': 'claude-sonnet-4-6', // Sonnet 4.6 (Issue #1329)
22
24
  'claude-opus-4-6': 'claude-opus-4-6', // Opus 4.6
23
25
  'claude-opus-4-5': 'claude-opus-4-5-20251101', // Opus 4.5
24
- 'claude-sonnet-4-5': 'claude-sonnet-4-5-20250929', // Sonnet 4.5
26
+ 'claude-sonnet-4-5': 'claude-sonnet-4-5-20250929', // Sonnet 4.5 (backward compatibility)
25
27
  'claude-haiku-4-5': 'claude-haiku-4-5-20251001', // Haiku 4.5
26
28
  };
27
29
 
@@ -14,21 +14,23 @@ import { log } from './lib.mjs';
14
14
  // These are the "known good" model names that we accept
15
15
  export const CLAUDE_MODELS = {
16
16
  // Short aliases (single word)
17
- sonnet: 'claude-sonnet-4-5-20250929',
18
- opus: 'claude-opus-4-5-20251101', // Changed to Opus 4.5 (Issue #1238)
17
+ sonnet: 'claude-sonnet-4-6', // Sonnet 4.6 (default, Issue #1329)
18
+ opus: 'claude-opus-4-5-20251101', // Opus 4.5 (Issue #1238)
19
19
  haiku: 'claude-haiku-4-5-20251001',
20
20
  'haiku-3-5': 'claude-3-5-haiku-20241022',
21
21
  'haiku-3': 'claude-3-haiku-20240307',
22
- // Shorter version aliases (Issue #1221 - PR comment feedback)
22
+ // Shorter version aliases (Issue #1221, Issue #1329 - PR comment feedback)
23
+ 'sonnet-4-6': 'claude-sonnet-4-6', // Sonnet 4.6 short alias (Issue #1329)
23
24
  'opus-4-6': 'claude-opus-4-6', // Opus 4.6 short alias
24
25
  'opus-4-5': 'claude-opus-4-5-20251101', // Opus 4.5 short alias
25
- 'sonnet-4-5': 'claude-sonnet-4-5-20250929', // Sonnet 4.5 short alias
26
+ 'sonnet-4-5': 'claude-sonnet-4-5-20250929', // Sonnet 4.5 short alias (backward compatibility)
26
27
  'haiku-4-5': 'claude-haiku-4-5-20251001', // Haiku 4.5 short alias
28
+ // Sonnet version aliases (Issue #1329)
29
+ 'claude-sonnet-4-6': 'claude-sonnet-4-6', // Sonnet 4.6
30
+ 'claude-sonnet-4-5': 'claude-sonnet-4-5-20250929', // Sonnet 4.5 (backward compatibility)
27
31
  // Opus version aliases (Issue #1221)
28
32
  'claude-opus-4-6': 'claude-opus-4-6', // Opus 4.6
29
33
  'claude-opus-4-5': 'claude-opus-4-5-20251101', // Opus 4.5
30
- // Sonnet version aliases
31
- 'claude-sonnet-4-5': 'claude-sonnet-4-5-20250929',
32
34
  // Haiku version aliases
33
35
  'claude-haiku-4-5': 'claude-haiku-4-5-20251001',
34
36
  // Full model IDs (also valid inputs)
@@ -39,14 +41,16 @@ export const CLAUDE_MODELS = {
39
41
  'claude-3-haiku-20240307': 'claude-3-haiku-20240307',
40
42
  };
41
43
 
42
- // Models that support 1M token context window via [1m] suffix (Issue #1221, Issue #1238)
44
+ // Models that support 1M token context window via [1m] suffix (Issue #1221, Issue #1238, Issue #1329)
43
45
  // See: https://code.claude.com/docs/en/model-config
44
46
  export const MODELS_SUPPORTING_1M_CONTEXT = [
45
47
  'claude-opus-4-6',
46
48
  'claude-opus-4-5-20251101',
49
+ 'claude-sonnet-4-6', // Sonnet 4.6 (Issue #1329)
47
50
  'claude-sonnet-4-5-20250929',
48
51
  'claude-sonnet-4-5',
49
- 'sonnet',
52
+ 'sonnet', // Now maps to Sonnet 4.6 (Issue #1329)
53
+ 'sonnet-4-6', // Short alias (Issue #1329)
50
54
  'opus',
51
55
  'opus-4-6', // Short alias (Issue #1221 - PR comment feedback)
52
56
  'opus-4-5', // Short alias (Issue #1238)
package/src/solve.mjs CHANGED
@@ -347,6 +347,7 @@ let prBranch;
347
347
  let mergeStateStatus;
348
348
  let prState;
349
349
  let forkOwner = null;
350
+ let forkRepoName = null;
350
351
  let isContinueMode = false;
351
352
  // Auto-continue logic: check for existing PRs if --auto-continue is enabled
352
353
  const autoContinueResult = await processAutoContinueForIssue(argv, isIssueUrl, urlNumber, owner, repo);
@@ -376,9 +377,9 @@ if (autoContinueResult.isContinueMode) {
376
377
  }
377
378
  if (prCheckData.headRepositoryOwner && prCheckData.headRepositoryOwner.login !== owner) {
378
379
  forkOwner = prCheckData.headRepositoryOwner.login;
379
- // Get actual fork repository name (may be prefixed)
380
- const forkRepoName = prCheckData.headRepository && prCheckData.headRepository.name ? prCheckData.headRepository.name : repo;
381
- await log(`🍴 Detected fork PR from ${forkOwner}/${forkRepoName}`);
380
+ // Get actual fork repository name (may be prefixed) and store for use in setupRepository
381
+ forkRepoName = prCheckData.headRepository && prCheckData.headRepository.name ? prCheckData.headRepository.name : null;
382
+ await log(`🍴 Detected fork PR from ${forkOwner}/${forkRepoName || repo}`);
382
383
  if (argv.verbose) {
383
384
  await log(` Fork owner: ${forkOwner}`, { verbose: true });
384
385
  await log(' Will clone fork repository for continue mode', { verbose: true });
@@ -456,9 +457,9 @@ if (isPrUrl) {
456
457
  // Check if this is a fork PR
457
458
  if (prData.headRepositoryOwner && prData.headRepositoryOwner.login !== owner) {
458
459
  forkOwner = prData.headRepositoryOwner.login;
459
- // Get actual fork repository name (may be prefixed)
460
- const forkRepoName = prData.headRepository && prData.headRepository.name ? prData.headRepository.name : repo;
461
- await log(`🍴 Detected fork PR from ${forkOwner}/${forkRepoName}`);
460
+ // Get actual fork repository name and store for use in setupRepository
461
+ forkRepoName = prData.headRepository && prData.headRepository.name ? prData.headRepository.name : null;
462
+ await log(`🍴 Detected fork PR from ${forkOwner}/${forkRepoName || repo}`);
462
463
  if (argv.verbose) {
463
464
  await log(` Fork owner: ${forkOwner}`, { verbose: true });
464
465
  await log(' Will clone fork repository for continue mode', { verbose: true });
@@ -529,6 +530,7 @@ try {
529
530
  owner,
530
531
  repo,
531
532
  forkOwner,
533
+ forkRepoName,
532
534
  tempDir,
533
535
  isContinueMode,
534
536
  issueUrl,
@@ -3,9 +3,9 @@
3
3
  * Handles repository cloning, forking, and remote setup
4
4
  */
5
5
 
6
- export async function setupRepositoryAndClone({ argv, owner, repo, forkOwner, tempDir, isContinueMode, issueUrl, log, $, needsClone = true }) {
6
+ export async function setupRepositoryAndClone({ argv, owner, repo, forkOwner, forkRepoName, tempDir, isContinueMode, issueUrl, log, $, needsClone = true }) {
7
7
  // Set up repository and handle forking
8
- const { repoToClone, forkedRepo, upstreamRemote, prForkOwner } = await setupRepository(argv, owner, repo, forkOwner, issueUrl);
8
+ const { repoToClone, forkedRepo, upstreamRemote, prForkOwner } = await setupRepository(argv, owner, repo, forkOwner, issueUrl, forkRepoName);
9
9
 
10
10
  // Clone repository and set up remotes (skip if needsClone is false - directory already has repo)
11
11
  if (needsClone) {
@@ -32,10 +32,10 @@ export async function setupRepositoryAndClone({ argv, owner, repo, forkOwner, te
32
32
  return { repoToClone, forkedRepo, upstreamRemote, prForkRemote, prForkOwner };
33
33
  }
34
34
 
35
- async function setupRepository(argv, owner, repo, forkOwner, issueUrl) {
35
+ async function setupRepository(argv, owner, repo, forkOwner, issueUrl, forkRepoName) {
36
36
  const repository = await import('./solve.repository.lib.mjs');
37
37
  const { setupRepository: setupRepoFn } = repository;
38
- return await setupRepoFn(argv, owner, repo, forkOwner, issueUrl);
38
+ return await setupRepoFn(argv, owner, repo, forkOwner, issueUrl, forkRepoName);
39
39
  }
40
40
 
41
41
  async function cloneRepository(repoToClone, tempDir, argv, owner, repo) {
@@ -387,7 +387,7 @@ const tryInitializeEmptyRepository = async (owner, repo) => {
387
387
  };
388
388
 
389
389
  // Handle fork creation and repository setup
390
- export const setupRepository = async (argv, owner, repo, forkOwner = null, issueUrl = null) => {
390
+ export const setupRepository = async (argv, owner, repo, forkOwner = null, issueUrl = null, forkRepoName = null) => {
391
391
  let repoToClone = `${owner}/${repo}`;
392
392
  let forkedRepo = null;
393
393
  let upstreamRemote = null;
@@ -820,9 +820,10 @@ Thank you!`;
820
820
  await log(`\n${formatAligned('🍴', 'Fork mode:', 'DETECTED from PR')}`);
821
821
  await log(`${formatAligned('', 'Fork owner:', forkOwner)}`);
822
822
 
823
- // Determine fork name - try prefixed name first if option is enabled, otherwise try standard name
824
- const standardForkName = `${forkOwner}/${repo}`;
825
- const prefixedForkName = `${forkOwner}/${owner}-${repo}`;
823
+ // Use actual head repo name from PR data (headRepository.name) if available, otherwise guess from base repo name
824
+ const headRepoName = forkRepoName || repo;
825
+ const standardForkName = `${forkOwner}/${headRepoName}`;
826
+ const prefixedForkName = `${forkOwner}/${owner}-${headRepoName}`;
826
827
  const expectedForkName = argv.prefixForkNameWithOwnerName ? prefixedForkName : standardForkName;
827
828
  const alternateForkName = argv.prefixForkNameWithOwnerName ? standardForkName : prefixedForkName;
828
829
 
@@ -897,9 +898,9 @@ Thank you!`;
897
898
  upstreamRemote = `${owner}/${repo}`;
898
899
  } else {
899
900
  await log(`${formatAligned('❌', 'Error:', 'Fork not accessible')}`);
900
- await log(`${formatAligned('', 'Fork:', expectedForkName)}`);
901
- await log(`${formatAligned('', 'Suggestion:', 'The PR may be from a fork you no longer have access to')}`);
902
- await log(`${formatAligned('', 'Hint:', 'Try running with --fork flag to use your own fork instead')}`);
901
+ await log(`${formatAligned('', 'Fork tried:', expectedForkName)}`);
902
+ await log(`${formatAligned('', 'Suggestion:', forkRepoName ? "The fork's repo name may differ from the base repo name" : `Fork name was guessed from base repo name '${repo}' (headRepository.name unavailable)`)}`);
903
+ await log(`${formatAligned('', 'Hint:', 'Try running with --fork flag to create your own fork instead')}`);
903
904
  await safeExit(1, 'Repository setup failed');
904
905
  }
905
906
  }