@link-assistant/hive-mind 1.67.0 → 1.67.2

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,17 @@
1
1
  # @link-assistant/hive-mind
2
2
 
3
+ ## 1.67.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 240231e: Verify the pull request still links to the issue after every work session inside `--watch`, `--auto-restart-until-mergeable`, and `--finalize`, so that an iteration that turns out to be the last one cannot leave the PR un-linked when the AI rewrote the description without a closing keyword.
8
+
9
+ ## 1.67.1
10
+
11
+ ### Patch Changes
12
+
13
+ - d37f752: Working session summary now always appears before the working session log on every PR comment thread. The per-iteration code in auto-restart-until-mergeable mode and watch / temporary auto-restart mode now posts the summary comment before uploading the log, matching the existing top-level flow.
14
+
3
15
  ## 1.67.0
4
16
 
5
17
  ### Minor Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@link-assistant/hive-mind",
3
- "version": "1.67.0",
3
+ "version": "1.67.2",
4
4
  "description": "AI-powered issue solver and hive mind for collaborative problem solving",
5
5
  "main": "src/hive.mjs",
6
6
  "type": "module",
@@ -23,12 +23,21 @@ const { wrapDollarWithGhRetry } = await import('./github-rate-limit.lib.mjs');
23
23
  const $ = wrapDollarWithGhRetry(__rawDollar$);
24
24
  // Import shared library functions
25
25
  const lib = await import('./lib.mjs');
26
- const { log } = lib;
26
+ const { log, cleanErrorMessage } = lib;
27
27
 
28
28
  // Import shared restart utilities
29
29
  const restartShared = await import('./solve.restart-shared.lib.mjs');
30
30
  const { executeToolIteration } = restartShared;
31
31
 
32
+ // Issue #1763: Re-verify PR ↔ issue link after every finalize iteration so a
33
+ // PR body that the AI rewrote without a closing keyword does not survive past
34
+ // the last requirements-check.
35
+ const resultsLib = await import('./solve.results.lib.mjs');
36
+ const { ensurePullRequestIssueLink } = resultsLib;
37
+
38
+ const sentryLib = await import('./sentry.lib.mjs');
39
+ const { reportError } = sentryLib;
40
+
32
41
  /**
33
42
  * Runs finalize requirements-check iterations after the main solve.
34
43
  *
@@ -116,6 +125,34 @@ export const runAutoEnsureRequirements = async ({ issueUrl, owner, repo, issueNu
116
125
  if (ensureResult.pricingInfo) pricingInfo = ensureResult.pricingInfo;
117
126
  }
118
127
 
128
+ // Issue #1763: Re-verify the PR body contains a closing keyword for the
129
+ // issue after every finalize iteration. The AI agent can rewrite the PR
130
+ // description mid-session and any iteration may end up being the last
131
+ // one, so this check cannot be deferred to the top-level verifyResults
132
+ // path.
133
+ if (prNumber && issueNumber && owner && repo) {
134
+ try {
135
+ await log('🔗 Verifying PR issue link after finalize iteration...');
136
+ await ensurePullRequestIssueLink({
137
+ prNumber,
138
+ issueNumber,
139
+ owner,
140
+ repo,
141
+ argv,
142
+ });
143
+ } catch (issueLinkError) {
144
+ reportError(issueLinkError, {
145
+ context: 'ensure_pr_issue_link_finalize_iteration',
146
+ prNumber,
147
+ owner,
148
+ repo,
149
+ ensureIteration,
150
+ operation: 'ensure_pr_issue_link',
151
+ });
152
+ await log(`⚠️ PR issue link check error: ${cleanErrorMessage(issueLinkError)}`, { level: 'warning' });
153
+ }
154
+ }
155
+
119
156
  await log(`✅ FINALIZE iteration ${ensureIteration}/${finalizeCount} complete`);
120
157
  await log('');
121
158
  }
@@ -60,8 +60,10 @@ const toolComments = await import('./tool-comments.lib.mjs');
60
60
  const { READY_TO_MERGE_MARKER, AUTO_RESTART_MARKER, AUTO_MERGED_MARKER, postTrackedComment } = toolComments;
61
61
 
62
62
  // Issue #1728: Per-iteration working session summary attachment helper
63
+ // Issue #1763: Per-iteration PR ↔ issue link verification (so a clobbered
64
+ // PR body is restored before the next stop condition fires).
63
65
  const resultsLib = await import('./solve.results.lib.mjs');
64
- const { maybeAttachWorkingSessionSummary } = resultsLib;
66
+ const { maybeAttachWorkingSessionSummary, ensurePullRequestIssueLink } = resultsLib;
65
67
 
66
68
  // Issue #1574: Interruptible sleep so CTRL+C is never blocked by a lingering timer
67
69
  const { interruptibleSleep } = await import('./interruptible-sleep.lib.mjs');
@@ -857,6 +859,43 @@ No further AI sessions will be started automatically for this run. Please review
857
859
  }
858
860
  }
859
861
 
862
+ // Issue #1761: Post the working session **summary** BEFORE uploading
863
+ // the working session **log** so the summary always appears above
864
+ // the log in PR comment chronological order. The summary acts as a
865
+ // human-readable header for the (potentially very long) log that
866
+ // follows, and reordering matches the top-level flow in
867
+ // src/solve.mjs (which calls maybeAttachWorkingSessionSummary
868
+ // before verifyResults / attachLogToGitHub).
869
+ //
870
+ // Issue #1728: Attach a "Working session summary" comment for this
871
+ // iteration if the AI didn't post any comments of its own (and
872
+ // --auto-attach-solution-summary is enabled, which it is by default).
873
+ // Before this fix, only the top-level solve.mjs flow honoured this
874
+ // flag, so iterations inside auto-restart-until-mergeable silently
875
+ // dropped the AI's last message — see #1728.
876
+ try {
877
+ await maybeAttachWorkingSessionSummary({
878
+ argv,
879
+ resultSummary: toolResult.resultSummary,
880
+ workStartTime: iterationStartTime,
881
+ owner,
882
+ repo,
883
+ prNumber,
884
+ issueNumber,
885
+ success: true,
886
+ });
887
+ } catch (summaryError) {
888
+ reportError(summaryError, {
889
+ context: 'attach_auto_restart_working_session_summary',
890
+ prNumber,
891
+ owner,
892
+ repo,
893
+ iteration,
894
+ operation: 'attach_working_session_summary',
895
+ });
896
+ await log(formatAligned('', `⚠️ Working session summary error: ${cleanErrorMessage(summaryError)}`, '', 2));
897
+ }
898
+
860
899
  // Attach log if enabled
861
900
  const shouldAttachLogs = argv.attachLogs || argv['attach-logs'];
862
901
  if (prNumber && shouldAttachLogs) {
@@ -905,33 +944,33 @@ No further AI sessions will be started automatically for this run. Please review
905
944
  }
906
945
  }
907
946
 
908
- // Issue #1728: Attach a "Working session summary" comment for this
909
- // iteration if the AI didn't post any comments of its own (and
910
- // --auto-attach-solution-summary is enabled, which it is by default).
911
- // Before this fix, only the top-level solve.mjs flow honoured this
912
- // flag, so iterations inside auto-restart-until-mergeable silently
913
- // dropped the AI's last message — see #1728.
914
- try {
915
- await maybeAttachWorkingSessionSummary({
916
- argv,
917
- resultSummary: toolResult.resultSummary,
918
- workStartTime: iterationStartTime,
919
- owner,
920
- repo,
921
- prNumber,
922
- issueNumber,
923
- success: true,
924
- });
925
- } catch (summaryError) {
926
- reportError(summaryError, {
927
- context: 'attach_auto_restart_working_session_summary',
928
- prNumber,
929
- owner,
930
- repo,
931
- iteration,
932
- operation: 'attach_working_session_summary',
933
- });
934
- await log(formatAligned('', `⚠️ Working session summary error: ${cleanErrorMessage(summaryError)}`, '', 2));
947
+ // Issue #1763: Re-verify the PR body contains a closing keyword for
948
+ // the issue after every auto-restart-until-mergeable iteration. The
949
+ // AI agent can rewrite the PR description mid-session and any
950
+ // iteration may end up being the last one (mergeable, max-iters,
951
+ // billing limit, etc.), so this check cannot be deferred to the
952
+ // top-level verifyResults path.
953
+ if (prNumber && issueNumber && owner && repo) {
954
+ try {
955
+ await log(formatAligned('🔗', 'Verifying PR issue link after iteration...', '', 2));
956
+ await ensurePullRequestIssueLink({
957
+ prNumber,
958
+ issueNumber,
959
+ owner,
960
+ repo,
961
+ argv,
962
+ });
963
+ } catch (issueLinkError) {
964
+ reportError(issueLinkError, {
965
+ context: 'ensure_pr_issue_link_auto_restart_iteration',
966
+ prNumber,
967
+ owner,
968
+ repo,
969
+ iteration,
970
+ operation: 'ensure_pr_issue_link',
971
+ });
972
+ await log(formatAligned('', `⚠️ PR issue link check error: ${cleanErrorMessage(issueLinkError)}`, '', 2));
973
+ }
935
974
  }
936
975
 
937
976
  await log('');
@@ -47,8 +47,11 @@ const toolComments = await import('./tool-comments.lib.mjs');
47
47
  const { AUTO_RESTART_MARKER, postTrackedComment } = toolComments;
48
48
 
49
49
  // Issue #1728: Per-iteration working session summary attachment helper
50
+ // Issue #1763: Per-iteration PR ↔ issue link verification (in case the AI
51
+ // agent overwrites the PR body without a closing keyword and the iteration
52
+ // ends up being the last one).
50
53
  const resultsLib = await import('./solve.results.lib.mjs');
51
- const { maybeAttachWorkingSessionSummary } = resultsLib;
54
+ const { maybeAttachWorkingSessionSummary, ensurePullRequestIssueLink } = resultsLib;
52
55
 
53
56
  /**
54
57
  * Monitor for feedback in a loop and trigger restart when detected
@@ -421,6 +424,42 @@ export const watchForFeedback = async params => {
421
424
  }
422
425
  }
423
426
 
427
+ // Issue #1761: Post the working session **summary** BEFORE uploading
428
+ // the working session **log** so the summary always appears above
429
+ // the log in PR comment chronological order. The summary acts as a
430
+ // human-readable header for the (potentially very long) log that
431
+ // follows, and reordering matches the top-level flow in
432
+ // src/solve.mjs (which calls maybeAttachWorkingSessionSummary
433
+ // before verifyResults / attachLogToGitHub).
434
+ //
435
+ // Issue #1728: Attach a "Working session summary" comment for this
436
+ // iteration if the AI didn't post any comments of its own (and
437
+ // --auto-attach-solution-summary is enabled, which it is by default).
438
+ // Same fix as in solve.auto-merge.lib.mjs — every working session,
439
+ // not just the top-level run, should honour the auto-attach flag.
440
+ try {
441
+ await maybeAttachWorkingSessionSummary({
442
+ argv,
443
+ resultSummary: toolResult.resultSummary,
444
+ workStartTime: iterationStartTime,
445
+ owner,
446
+ repo,
447
+ prNumber,
448
+ issueNumber,
449
+ success: true,
450
+ });
451
+ } catch (summaryError) {
452
+ reportError(summaryError, {
453
+ context: 'attach_watch_working_session_summary',
454
+ prNumber,
455
+ owner,
456
+ repo,
457
+ autoRestartCount,
458
+ operation: 'attach_working_session_summary',
459
+ });
460
+ await log(formatAligned('', `⚠️ Working session summary error: ${cleanErrorMessage(summaryError)}`, '', 2));
461
+ }
462
+
424
463
  // Issue #1107: Attach log after each auto-restart session with its own cost estimation
425
464
  // This ensures each restart has its own log comment instead of one combined log at the end
426
465
  const shouldAttachLogs = argv.attachLogs || argv['attach-logs'];
@@ -478,32 +517,32 @@ export const watchForFeedback = async params => {
478
517
  }
479
518
  }
480
519
 
481
- // Issue #1728: Attach a "Working session summary" comment for this
482
- // iteration if the AI didn't post any comments of its own (and
483
- // --auto-attach-solution-summary is enabled, which it is by default).
484
- // Same fix as in solve.auto-merge.lib.mjs every working session,
485
- // not just the top-level run, should honour the auto-attach flag.
486
- try {
487
- await maybeAttachWorkingSessionSummary({
488
- argv,
489
- resultSummary: toolResult.resultSummary,
490
- workStartTime: iterationStartTime,
491
- owner,
492
- repo,
493
- prNumber,
494
- issueNumber,
495
- success: true,
496
- });
497
- } catch (summaryError) {
498
- reportError(summaryError, {
499
- context: 'attach_watch_working_session_summary',
500
- prNumber,
501
- owner,
502
- repo,
503
- autoRestartCount,
504
- operation: 'attach_working_session_summary',
505
- });
506
- await log(formatAligned('', `⚠️ Working session summary error: ${cleanErrorMessage(summaryError)}`, '', 2));
520
+ // Issue #1763: Re-verify the PR body contains a closing keyword for
521
+ // the issue after every iteration. The AI agent can rewrite the PR
522
+ // description mid-session and any iteration may turn out to be the
523
+ // last one (interrupt, hit iteration cap, billing limit, etc.), so
524
+ // we cannot rely on a single end-of-run check.
525
+ if (prNumber && issueNumber && owner && repo) {
526
+ try {
527
+ await log(formatAligned('🔗', 'Verifying PR issue link after iteration...', '', 2));
528
+ await ensurePullRequestIssueLink({
529
+ prNumber,
530
+ issueNumber,
531
+ owner,
532
+ repo,
533
+ argv,
534
+ });
535
+ } catch (issueLinkError) {
536
+ reportError(issueLinkError, {
537
+ context: 'ensure_pr_issue_link_watch_iteration',
538
+ prNumber,
539
+ owner,
540
+ repo,
541
+ autoRestartCount,
542
+ operation: 'ensure_pr_issue_link',
543
+ });
544
+ await log(formatAligned('', `⚠️ PR issue link check error: ${cleanErrorMessage(issueLinkError)}`, '', 2));
545
+ }
507
546
  }
508
547
 
509
548
  await log('');