@link-assistant/hive-mind 1.35.7 → 1.35.9

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,23 @@
1
1
  # @link-assistant/hive-mind
2
2
 
3
+ ## 1.35.9
4
+
5
+ ### Patch Changes
6
+
7
+ - 2e4e00e: fix: update tool display names to full official names (Issue #1470)
8
+ - Update `getToolDisplayName()` in `src/model-info.lib.mjs` to return full official names: "Anthropic Claude Code", "OpenAI Codex", "OpenCode", "Agent CLI"
9
+ - Update usage limit messages in `src/claude.lib.mjs`, `src/codex.lib.mjs`, and `src/agent.lib.mjs` to use full tool names
10
+ - Update test assertions in `tests/model-info.test.mjs` and `tests/test-usage-limit.mjs` to match new display names
11
+
12
+ ## 1.35.8
13
+
14
+ ### Patch Changes
15
+
16
+ - ca57154: fix: add retry with exponential backoff for PR verification after creation (Issue #1468)
17
+ - Add retry logic with exponential backoff (up to 5 attempts: 2s, 4s, 6s, 8s, 10s) to PR verification step in solve.auto-pr.lib.mjs to handle GitHub API eventual consistency
18
+ - Add case study with timeline reconstruction and root cause analysis
19
+ - Add 11 unit tests covering retry behavior, backoff timing, and edge cases
20
+
3
21
  ## 1.35.7
4
22
 
5
23
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@link-assistant/hive-mind",
3
- "version": "1.35.7",
3
+ "version": "1.35.9",
4
4
  "description": "AI-powered issue solver and hive mind for collaborative problem solving",
5
5
  "main": "src/hive.mjs",
6
6
  "type": "module",
package/src/agent.lib.mjs CHANGED
@@ -899,7 +899,7 @@ export const executeAgentCommand = async params => {
899
899
 
900
900
  // Format and display user-friendly message
901
901
  const messageLines = formatUsageLimitMessage({
902
- tool: 'Agent',
902
+ tool: 'Agent CLI',
903
903
  resetTime: limitInfo.resetTime,
904
904
  sessionId,
905
905
  resumeCommand: sessionId ? `${process.argv[0]} ${process.argv[1]} ${argv.url} --resume ${sessionId}` : null,
@@ -1257,7 +1257,7 @@ export const executeClaudeCommand = async params => {
1257
1257
 
1258
1258
  // Format and display user-friendly message
1259
1259
  const messageLines = formatUsageLimitMessage({
1260
- tool: 'Claude',
1260
+ tool: 'Anthropic Claude Code',
1261
1261
  resetTime: limitInfo.resetTime,
1262
1262
  sessionId,
1263
1263
  resumeCommand: argv.url ? `${process.argv[0]} ${process.argv[1]} --auto-continue ${argv.url}` : null,
package/src/codex.lib.mjs CHANGED
@@ -390,7 +390,7 @@ export const executeCodexCommand = async params => {
390
390
 
391
391
  // Format and display user-friendly message
392
392
  const messageLines = formatUsageLimitMessage({
393
- tool: 'Codex',
393
+ tool: 'OpenAI Codex',
394
394
  resetTime: limitInfo.resetTime,
395
395
  sessionId,
396
396
  resumeCommand: sessionId ? `${process.argv[0]} ${process.argv[1]} ${argv.url} --resume ${sessionId}` : null,
@@ -26,13 +26,13 @@ export const getToolDisplayName = tool => {
26
26
  const name = (tool || '').toString().toLowerCase();
27
27
  switch (name) {
28
28
  case 'claude':
29
- return 'Claude';
29
+ return 'Anthropic Claude Code';
30
30
  case 'codex':
31
- return 'Codex';
31
+ return 'OpenAI Codex';
32
32
  case 'opencode':
33
33
  return 'OpenCode';
34
34
  case 'agent':
35
- return 'Agent';
35
+ return 'Agent CLI';
36
36
  default:
37
37
  return 'AI tool';
38
38
  }
@@ -1203,33 +1203,59 @@ ${prBody}`,
1203
1203
 
1204
1204
  // CRITICAL: Verify the PR was actually created by querying GitHub API
1205
1205
  // This is essential because gh pr create can return a URL but PR creation might have failed
1206
+ // Issue #1468: Use retry with exponential backoff because GitHub's API is eventually
1207
+ // consistent — a newly created PR may not be visible via gh pr view for several seconds.
1208
+ // This matches the existing retry pattern used for the compare API (lines 571-624).
1206
1209
  await log(formatAligned('🔍', 'Verifying:', 'PR creation...'), { verbose: true });
1207
- const verifyResult = await $({
1208
- silent: true,
1209
- })`gh pr view ${localPrNumber} --repo ${owner}/${repo} --json number,url,state 2>&1`;
1210
-
1211
- if (verifyResult.code === 0) {
1212
- try {
1213
- const prData = JSON.parse(verifyResult.stdout.toString().trim());
1214
- if (prData.number && prData.url) {
1215
- await log(formatAligned('✅', 'Verification:', 'PR exists on GitHub'), { verbose: true });
1216
- // Update prUrl and localPrNumber from verified data
1217
- prUrl = prData.url;
1218
- localPrNumber = String(prData.number);
1219
- } else {
1220
- throw new Error('PR data incomplete');
1210
+
1211
+ let prVerified = false;
1212
+ let verifyAttempts = 0;
1213
+ const maxVerifyAttempts = 5;
1214
+ let lastVerifyResult = null;
1215
+
1216
+ while (!prVerified && verifyAttempts < maxVerifyAttempts) {
1217
+ verifyAttempts++;
1218
+ const waitTime = Math.min(2000 * verifyAttempts, 10000); // 2s, 4s, 6s, 8s, 10s
1219
+
1220
+ if (verifyAttempts > 1) {
1221
+ await log(` Retry ${verifyAttempts}/${maxVerifyAttempts}: Waiting ${waitTime}ms for GitHub to propagate PR...`);
1222
+ }
1223
+
1224
+ await new Promise(resolve => setTimeout(resolve, waitTime));
1225
+
1226
+ lastVerifyResult = await $({
1227
+ silent: true,
1228
+ })`gh pr view ${localPrNumber} --repo ${owner}/${repo} --json number,url,state 2>&1`;
1229
+
1230
+ if (lastVerifyResult.code === 0) {
1231
+ try {
1232
+ const prData = JSON.parse(lastVerifyResult.stdout.toString().trim());
1233
+ if (prData.number && prData.url) {
1234
+ await log(formatAligned('✅', 'Verification:', `PR exists on GitHub (attempt ${verifyAttempts}/${maxVerifyAttempts})`), { verbose: true });
1235
+ // Update prUrl and localPrNumber from verified data
1236
+ prUrl = prData.url;
1237
+ localPrNumber = String(prData.number);
1238
+ prVerified = true;
1239
+ }
1240
+ } catch {
1241
+ // Parse failed, will retry
1242
+ if (argv.verbose) {
1243
+ await log(` Verify attempt ${verifyAttempts}: Could not parse PR data, retrying...`, { verbose: true });
1244
+ }
1221
1245
  }
1222
- } catch {
1223
- await log('❌ PR verification failed: Could not parse PR data', { level: 'error' });
1224
- throw new Error('PR creation verification failed - invalid response');
1246
+ } else if (argv.verbose) {
1247
+ const attemptStderr = lastVerifyResult.stderr ? lastVerifyResult.stderr.toString().trim() : '';
1248
+ await log(` Verify attempt ${verifyAttempts}: PR not found yet${attemptStderr ? ` (${attemptStderr})` : ''}`, { verbose: true });
1225
1249
  }
1226
- } else {
1227
- // PR does not exist - gh pr create must have failed silently
1250
+ }
1251
+
1252
+ if (!prVerified) {
1253
+ // PR does not exist after all retries - gh pr create must have failed silently
1228
1254
  // Issue #1462: Include gh pr create stderr for root cause diagnosis
1229
- const verifyStderr = verifyResult.stderr ? verifyResult.stderr.toString().trim() : '';
1255
+ const verifyStderr = lastVerifyResult && lastVerifyResult.stderr ? lastVerifyResult.stderr.toString().trim() : '';
1230
1256
  const stderrInfo = prCreateStderr ? ` (gh pr create stderr: ${prCreateStderr.trim()})` : '';
1231
1257
  const verifyInfo = verifyStderr ? ` (gh pr view stderr: ${verifyStderr})` : '';
1232
- throw new Error(`PR verification failed - gh pr create returned URL "${prUrl}" but PR #${localPrNumber} does not exist on GitHub${stderrInfo}${verifyInfo}`);
1258
+ throw new Error(`PR verification failed - gh pr create returned URL "${prUrl}" but PR #${localPrNumber} does not exist on GitHub after ${maxVerifyAttempts} verification attempts${stderrInfo}${verifyInfo}`);
1233
1259
  }
1234
1260
  // Store PR info globally for error handlers
1235
1261
  global.createdPR = { number: localPrNumber, url: prUrl };