hungry-ghost-hive 0.43.2 → 0.44.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.
Files changed (73) hide show
  1. package/dist/agents/tech-lead.d.ts.map +1 -1
  2. package/dist/agents/tech-lead.js +4 -1
  3. package/dist/agents/tech-lead.js.map +1 -1
  4. package/dist/cli/commands/manager/tech-lead-lifecycle.d.ts.map +1 -1
  5. package/dist/cli/commands/manager/tech-lead-lifecycle.js +4 -1
  6. package/dist/cli/commands/manager/tech-lead-lifecycle.js.map +1 -1
  7. package/dist/cli/commands/pr.js +5 -0
  8. package/dist/cli/commands/pr.js.map +1 -1
  9. package/dist/cli/commands/pr.test.js +43 -1
  10. package/dist/cli/commands/pr.test.js.map +1 -1
  11. package/dist/cli/commands/req.d.ts.map +1 -1
  12. package/dist/cli/commands/req.js +2 -1
  13. package/dist/cli/commands/req.js.map +1 -1
  14. package/dist/cli/commands/resume.d.ts.map +1 -1
  15. package/dist/cli/commands/resume.js +4 -1
  16. package/dist/cli/commands/resume.js.map +1 -1
  17. package/dist/cli-runtimes/chrome.d.ts +17 -0
  18. package/dist/cli-runtimes/chrome.d.ts.map +1 -0
  19. package/dist/cli-runtimes/chrome.js +36 -0
  20. package/dist/cli-runtimes/chrome.js.map +1 -0
  21. package/dist/cli-runtimes/claude.d.ts +3 -3
  22. package/dist/cli-runtimes/claude.d.ts.map +1 -1
  23. package/dist/cli-runtimes/claude.js +14 -8
  24. package/dist/cli-runtimes/claude.js.map +1 -1
  25. package/dist/cli-runtimes/codex.d.ts +3 -3
  26. package/dist/cli-runtimes/codex.d.ts.map +1 -1
  27. package/dist/cli-runtimes/codex.js +2 -2
  28. package/dist/cli-runtimes/codex.js.map +1 -1
  29. package/dist/cli-runtimes/gemini.d.ts +3 -3
  30. package/dist/cli-runtimes/gemini.d.ts.map +1 -1
  31. package/dist/cli-runtimes/gemini.js +2 -2
  32. package/dist/cli-runtimes/gemini.js.map +1 -1
  33. package/dist/cli-runtimes/index.d.ts +3 -2
  34. package/dist/cli-runtimes/index.d.ts.map +1 -1
  35. package/dist/cli-runtimes/index.js +1 -0
  36. package/dist/cli-runtimes/index.js.map +1 -1
  37. package/dist/cli-runtimes/index.test.js +133 -1
  38. package/dist/cli-runtimes/index.test.js.map +1 -1
  39. package/dist/cli-runtimes/types.d.ts +9 -2
  40. package/dist/cli-runtimes/types.d.ts.map +1 -1
  41. package/dist/config/schema.d.ts +8 -0
  42. package/dist/config/schema.d.ts.map +1 -1
  43. package/dist/config/schema.js +6 -0
  44. package/dist/config/schema.js.map +1 -1
  45. package/dist/context-files/index.test.js +1 -0
  46. package/dist/context-files/index.test.js.map +1 -1
  47. package/dist/orchestrator/scheduler.d.ts.map +1 -1
  48. package/dist/orchestrator/scheduler.js +4 -1
  49. package/dist/orchestrator/scheduler.js.map +1 -1
  50. package/dist/utils/auto-merge.d.ts.map +1 -1
  51. package/dist/utils/auto-merge.js +66 -5
  52. package/dist/utils/auto-merge.js.map +1 -1
  53. package/dist/utils/auto-merge.test.js +62 -0
  54. package/dist/utils/auto-merge.test.js.map +1 -1
  55. package/package.json +1 -1
  56. package/src/agents/tech-lead.ts +4 -1
  57. package/src/cli/commands/manager/tech-lead-lifecycle.ts +4 -1
  58. package/src/cli/commands/pr.test.ts +77 -1
  59. package/src/cli/commands/pr.ts +5 -0
  60. package/src/cli/commands/req.ts +4 -1
  61. package/src/cli/commands/resume.ts +4 -1
  62. package/src/cli-runtimes/chrome.ts +43 -0
  63. package/src/cli-runtimes/claude.ts +26 -9
  64. package/src/cli-runtimes/codex.ts +12 -3
  65. package/src/cli-runtimes/gemini.ts +12 -3
  66. package/src/cli-runtimes/index.test.ts +158 -0
  67. package/src/cli-runtimes/index.ts +3 -2
  68. package/src/cli-runtimes/types.ts +19 -2
  69. package/src/config/schema.ts +6 -0
  70. package/src/context-files/index.test.ts +1 -0
  71. package/src/orchestrator/scheduler.ts +9 -1
  72. package/src/utils/auto-merge.test.ts +81 -0
  73. package/src/utils/auto-merge.ts +78 -5
@@ -29,6 +29,7 @@ const PR_MERGE_TIMEOUT_MS = 60000;
29
29
  interface GitHubPRState {
30
30
  state: string;
31
31
  mergeable: string;
32
+ mergeStateStatus: string;
32
33
  }
33
34
 
34
35
  /**
@@ -149,6 +150,8 @@ export async function autoMergeApprovedPRs(
149
150
  claimed: ClaimedPR;
150
151
  outcome:
151
152
  | { type: 'merged' }
153
+ | { type: 'auto_merge_pending' }
154
+ | { type: 'branch_updated' }
152
155
  | { type: 'already_closed'; prState: GitHubPRState }
153
156
  | { type: 'conflicts' }
154
157
  | { type: 'unknown_state' }
@@ -163,10 +166,9 @@ export async function autoMergeApprovedPRs(
163
166
  try {
164
167
  // Check PR state
165
168
  let prState: GitHubPRState;
166
- let mergeableStatus: boolean;
167
169
  try {
168
170
  const prViewOutput = execSync(
169
- `gh pr view ${pr.github_pr_number} --json state,mergeable${repoFlag}`,
171
+ `gh pr view ${pr.github_pr_number} --json state,mergeable,mergeStateStatus${repoFlag}`,
170
172
  {
171
173
  stdio: 'pipe',
172
174
  cwd: repoCwd,
@@ -175,7 +177,6 @@ export async function autoMergeApprovedPRs(
175
177
  }
176
178
  );
177
179
  prState = JSON.parse(prViewOutput);
178
- mergeableStatus = prState.mergeable === 'MERGEABLE';
179
180
  } catch {
180
181
  results.push({ claimed, outcome: { type: 'unknown_state' } });
181
182
  continue;
@@ -186,7 +187,22 @@ export async function autoMergeApprovedPRs(
186
187
  continue;
187
188
  }
188
189
 
189
- if (!mergeableStatus) {
190
+ // Update stale branches that are behind the base branch
191
+ if (prState.mergeStateStatus === 'BEHIND') {
192
+ try {
193
+ execSync(`gh pr update-branch ${pr.github_pr_number}${repoFlag}`, {
194
+ stdio: 'pipe',
195
+ cwd: repoCwd,
196
+ timeout: PR_MERGE_TIMEOUT_MS,
197
+ });
198
+ results.push({ claimed, outcome: { type: 'branch_updated' } });
199
+ } catch {
200
+ results.push({ claimed, outcome: { type: 'unknown_state' } });
201
+ }
202
+ continue;
203
+ }
204
+
205
+ if (prState.mergeable !== 'MERGEABLE') {
190
206
  results.push({ claimed, outcome: { type: 'conflicts' } });
191
207
  continue;
192
208
  }
@@ -198,7 +214,32 @@ export async function autoMergeApprovedPRs(
198
214
  cwd: repoCwd,
199
215
  timeout: PR_MERGE_TIMEOUT_MS,
200
216
  });
201
- results.push({ claimed, outcome: { type: 'merged' } });
217
+
218
+ // Verify actual merge state: --auto may queue the merge rather than merge immediately
219
+ let postMergeState: GitHubPRState;
220
+ try {
221
+ const postMergeOutput = execSync(
222
+ `gh pr view ${pr.github_pr_number} --json state,mergeable,mergeStateStatus${repoFlag}`,
223
+ {
224
+ stdio: 'pipe',
225
+ cwd: repoCwd,
226
+ encoding: 'utf-8',
227
+ timeout: PR_STATE_CHECK_TIMEOUT_MS,
228
+ }
229
+ );
230
+ postMergeState = JSON.parse(postMergeOutput);
231
+ } catch {
232
+ // If we can't re-check, assume it merged (command succeeded)
233
+ results.push({ claimed, outcome: { type: 'merged' } });
234
+ continue;
235
+ }
236
+
237
+ if (postMergeState.state === 'MERGED') {
238
+ results.push({ claimed, outcome: { type: 'merged' } });
239
+ } else {
240
+ // PR is OPEN with auto-merge enabled — GitHub will merge when CI passes
241
+ results.push({ claimed, outcome: { type: 'auto_merge_pending' } });
242
+ }
202
243
  } catch (mergeErr) {
203
244
  results.push({
204
245
  claimed,
@@ -340,6 +381,38 @@ export async function autoMergeApprovedPRs(
340
381
  break;
341
382
  }
342
383
 
384
+ case 'auto_merge_pending': {
385
+ createLog(phaseDb.db, {
386
+ agentId: 'manager',
387
+ storyId: pr.story_id || undefined,
388
+ eventType: 'PR_MERGE_SKIPPED',
389
+ status: 'info',
390
+ message: `PR #${pr.github_pr_number} is queued for auto-merge, waiting for CI checks to complete`,
391
+ metadata: { pr_id: pr.id },
392
+ });
393
+ break;
394
+ }
395
+
396
+ case 'branch_updated': {
397
+ // Reset to 'approved' so the PR is retried on the next cycle once CI passes
398
+ await withTransaction(
399
+ phaseDb.db,
400
+ () => {
401
+ updatePullRequest(phaseDb.db, pr.id, { status: 'approved' });
402
+ createLog(phaseDb.db, {
403
+ agentId: 'manager',
404
+ storyId: pr.story_id || undefined,
405
+ eventType: 'PR_MERGE_SKIPPED',
406
+ status: 'info',
407
+ message: `Updated stale branch for PR #${pr.github_pr_number} (was behind base branch), will retry merge`,
408
+ metadata: { pr_id: pr.id },
409
+ });
410
+ },
411
+ () => phaseDb.save()
412
+ );
413
+ break;
414
+ }
415
+
343
416
  case 'merge_failed': {
344
417
  await withTransaction(
345
418
  phaseDb.db,