hungry-ghost-hive 0.43.0 → 0.43.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.
Files changed (133) hide show
  1. package/dist/cli/commands/agents.d.ts.map +1 -1
  2. package/dist/cli/commands/agents.js +4 -11
  3. package/dist/cli/commands/agents.js.map +1 -1
  4. package/dist/cli/commands/approach.d.ts.map +1 -1
  5. package/dist/cli/commands/approach.js +2 -6
  6. package/dist/cli/commands/approach.js.map +1 -1
  7. package/dist/cli/commands/init.d.ts.map +1 -1
  8. package/dist/cli/commands/init.js +9 -0
  9. package/dist/cli/commands/init.js.map +1 -1
  10. package/dist/cli/commands/init.test.js +3 -0
  11. package/dist/cli/commands/init.test.js.map +1 -1
  12. package/dist/cli/commands/manager/index.d.ts +2 -27
  13. package/dist/cli/commands/manager/index.d.ts.map +1 -1
  14. package/dist/cli/commands/manager/index.js +23 -1519
  15. package/dist/cli/commands/manager/index.js.map +1 -1
  16. package/dist/cli/commands/manager/manager-utils.d.ts +9 -0
  17. package/dist/cli/commands/manager/manager-utils.d.ts.map +1 -0
  18. package/dist/cli/commands/manager/manager-utils.js +49 -0
  19. package/dist/cli/commands/manager/manager-utils.js.map +1 -0
  20. package/dist/cli/commands/manager/pr-sync-orchestrator.d.ts +7 -0
  21. package/dist/cli/commands/manager/pr-sync-orchestrator.d.ts.map +1 -0
  22. package/dist/cli/commands/manager/pr-sync-orchestrator.js +537 -0
  23. package/dist/cli/commands/manager/pr-sync-orchestrator.js.map +1 -0
  24. package/dist/cli/commands/manager/qa-review-handler.d.ts +15 -0
  25. package/dist/cli/commands/manager/qa-review-handler.d.ts.map +1 -0
  26. package/dist/cli/commands/manager/qa-review-handler.js +290 -0
  27. package/dist/cli/commands/manager/qa-review-handler.js.map +1 -0
  28. package/dist/cli/commands/manager/stuck-story-helpers.d.ts +32 -0
  29. package/dist/cli/commands/manager/stuck-story-helpers.d.ts.map +1 -0
  30. package/dist/cli/commands/manager/stuck-story-helpers.js +163 -0
  31. package/dist/cli/commands/manager/stuck-story-helpers.js.map +1 -0
  32. package/dist/cli/commands/manager/stuck-story-processor.d.ts +8 -0
  33. package/dist/cli/commands/manager/stuck-story-processor.d.ts.map +1 -0
  34. package/dist/cli/commands/manager/stuck-story-processor.js +392 -0
  35. package/dist/cli/commands/manager/stuck-story-processor.js.map +1 -0
  36. package/dist/cli/commands/manager/tech-lead-lifecycle.d.ts +3 -0
  37. package/dist/cli/commands/manager/tech-lead-lifecycle.d.ts.map +1 -0
  38. package/dist/cli/commands/manager/tech-lead-lifecycle.js +141 -0
  39. package/dist/cli/commands/manager/tech-lead-lifecycle.js.map +1 -0
  40. package/dist/cli/commands/my-stories.d.ts.map +1 -1
  41. package/dist/cli/commands/my-stories.js +5 -20
  42. package/dist/cli/commands/my-stories.js.map +1 -1
  43. package/dist/cli/commands/pr.js +7 -22
  44. package/dist/cli/commands/pr.js.map +1 -1
  45. package/dist/cli/commands/progress.d.ts.map +1 -1
  46. package/dist/cli/commands/progress.js +2 -5
  47. package/dist/cli/commands/progress.js.map +1 -1
  48. package/dist/cli/commands/resume.d.ts.map +1 -1
  49. package/dist/cli/commands/resume.js +3 -6
  50. package/dist/cli/commands/resume.js.map +1 -1
  51. package/dist/cli/commands/status.d.ts.map +1 -1
  52. package/dist/cli/commands/status.js +2 -5
  53. package/dist/cli/commands/status.js.map +1 -1
  54. package/dist/cli/commands/stories.d.ts.map +1 -1
  55. package/dist/cli/commands/stories.js +2 -5
  56. package/dist/cli/commands/stories.js.map +1 -1
  57. package/dist/cluster/adapters.d.ts +3 -2
  58. package/dist/cluster/adapters.d.ts.map +1 -1
  59. package/dist/cluster/adapters.js +2 -11
  60. package/dist/cluster/adapters.js.map +1 -1
  61. package/dist/cluster/cluster-http-server.d.ts +20 -0
  62. package/dist/cluster/cluster-http-server.d.ts.map +1 -0
  63. package/dist/cluster/cluster-http-server.js +140 -0
  64. package/dist/cluster/cluster-http-server.js.map +1 -0
  65. package/dist/cluster/heartbeat-manager.d.ts +24 -0
  66. package/dist/cluster/heartbeat-manager.d.ts.map +1 -0
  67. package/dist/cluster/heartbeat-manager.js +74 -0
  68. package/dist/cluster/heartbeat-manager.js.map +1 -0
  69. package/dist/cluster/raft-state-machine.d.ts +48 -0
  70. package/dist/cluster/raft-state-machine.d.ts.map +1 -0
  71. package/dist/cluster/raft-state-machine.js +207 -0
  72. package/dist/cluster/raft-state-machine.js.map +1 -0
  73. package/dist/cluster/runtime.d.ts +5 -29
  74. package/dist/cluster/runtime.d.ts.map +1 -1
  75. package/dist/cluster/runtime.js +58 -406
  76. package/dist/cluster/runtime.js.map +1 -1
  77. package/dist/integrations/jira/sync.d.ts +2 -5
  78. package/dist/integrations/jira/sync.d.ts.map +1 -1
  79. package/dist/integrations/jira/sync.js +116 -178
  80. package/dist/integrations/jira/sync.js.map +1 -1
  81. package/dist/utils/cli-helpers.d.ts +19 -0
  82. package/dist/utils/cli-helpers.d.ts.map +1 -0
  83. package/dist/utils/cli-helpers.js +51 -0
  84. package/dist/utils/cli-helpers.js.map +1 -0
  85. package/dist/utils/cli-helpers.test.d.ts +2 -0
  86. package/dist/utils/cli-helpers.test.d.ts.map +1 -0
  87. package/dist/utils/cli-helpers.test.js +100 -0
  88. package/dist/utils/cli-helpers.test.js.map +1 -0
  89. package/dist/utils/github-cli.d.ts +3 -0
  90. package/dist/utils/github-cli.d.ts.map +1 -0
  91. package/dist/utils/github-cli.js +4 -0
  92. package/dist/utils/github-cli.js.map +1 -0
  93. package/dist/utils/pr-sync.d.ts.map +1 -1
  94. package/dist/utils/pr-sync.js +1 -2
  95. package/dist/utils/pr-sync.js.map +1 -1
  96. package/dist/utils/story-status.d.ts +19 -0
  97. package/dist/utils/story-status.d.ts.map +1 -0
  98. package/dist/utils/story-status.js +58 -0
  99. package/dist/utils/story-status.js.map +1 -0
  100. package/dist/utils/story-status.test.d.ts +2 -0
  101. package/dist/utils/story-status.test.d.ts.map +1 -0
  102. package/dist/utils/story-status.test.js +65 -0
  103. package/dist/utils/story-status.test.js.map +1 -0
  104. package/package.json +1 -1
  105. package/src/cli/commands/agents.ts +3 -11
  106. package/src/cli/commands/approach.ts +2 -7
  107. package/src/cli/commands/init.test.ts +4 -0
  108. package/src/cli/commands/init.ts +9 -0
  109. package/src/cli/commands/manager/index.ts +166 -2236
  110. package/src/cli/commands/manager/manager-utils.ts +85 -0
  111. package/src/cli/commands/manager/pr-sync-orchestrator.ts +659 -0
  112. package/src/cli/commands/manager/qa-review-handler.ts +399 -0
  113. package/src/cli/commands/manager/stuck-story-helpers.ts +255 -0
  114. package/src/cli/commands/manager/stuck-story-processor.ts +604 -0
  115. package/src/cli/commands/manager/tech-lead-lifecycle.ts +210 -0
  116. package/src/cli/commands/my-stories.ts +5 -30
  117. package/src/cli/commands/pr.ts +6 -22
  118. package/src/cli/commands/progress.ts +2 -7
  119. package/src/cli/commands/resume.ts +3 -6
  120. package/src/cli/commands/status.ts +2 -5
  121. package/src/cli/commands/stories.ts +2 -5
  122. package/src/cluster/adapters.ts +3 -12
  123. package/src/cluster/cluster-http-server.ts +187 -0
  124. package/src/cluster/heartbeat-manager.ts +112 -0
  125. package/src/cluster/raft-state-machine.ts +267 -0
  126. package/src/cluster/runtime.ts +71 -515
  127. package/src/integrations/jira/sync.ts +157 -215
  128. package/src/utils/cli-helpers.test.ts +138 -0
  129. package/src/utils/cli-helpers.ts +61 -0
  130. package/src/utils/github-cli.ts +4 -0
  131. package/src/utils/pr-sync.ts +1 -3
  132. package/src/utils/story-status.test.ts +74 -0
  133. package/src/utils/story-status.ts +62 -0
@@ -0,0 +1,537 @@
1
+ // Licensed under the Hungry Ghost Hive License. See LICENSE.
2
+ import chalk from 'chalk';
3
+ import { execa } from 'execa';
4
+ import { syncStatusForStory } from '../../../connectors/project-management/operations.js';
5
+ import { queryAll, queryOne, withTransaction } from '../../../db/client.js';
6
+ import { createLog } from '../../../db/queries/logs.js';
7
+ import { createPullRequest, getPullRequestsByStatus, updatePullRequest, } from '../../../db/queries/pull-requests.js';
8
+ import { updateStory } from '../../../db/queries/stories.js';
9
+ import { GH_CLI_TIMEOUT_MS } from '../../../utils/github-cli.js';
10
+ import { fetchOpenGitHubPRs, getExistingPRIdentifiers, ghRepoSlug, } from '../../../utils/pr-sync.js';
11
+ import { extractStoryIdFromBranch } from '../../../utils/story-id.js';
12
+ import { sendManagerNudge, verboseLogCtx } from './manager-utils.js';
13
+ import { cleanupAgentsReferencingMergedStory } from './merged-story-cleanup.js';
14
+ const GH_PR_VIEW_TIMEOUT_MS = 30_000;
15
+ const REVIEWING_PR_VALIDATION_MIN_AGE_MS = 5 * 60 * 1000;
16
+ export async function syncMergedPRs(ctx) {
17
+ // Phase 1: Read teams (brief lock)
18
+ const teamInfos = await ctx.withDb(async (db) => {
19
+ const { getAllTeams } = await import('../../../db/queries/teams.js');
20
+ return getAllTeams(db.db)
21
+ .filter(t => t.repo_path)
22
+ .map(t => ({
23
+ repoDir: `${ctx.root}/${t.repo_path}`,
24
+ slug: ghRepoSlug(t.repo_url),
25
+ }));
26
+ });
27
+ if (teamInfos.length === 0)
28
+ return;
29
+ // Phase 2: GitHub CLI calls (no lock)
30
+ const GITHUB_PR_LIST_LIMIT = 20;
31
+ const ghResults = [];
32
+ for (const team of teamInfos) {
33
+ try {
34
+ const args = [
35
+ 'pr',
36
+ 'list',
37
+ '--json',
38
+ 'number,headRefName,mergedAt',
39
+ '--state',
40
+ 'merged',
41
+ '--limit',
42
+ String(GITHUB_PR_LIST_LIMIT),
43
+ ];
44
+ if (team.slug)
45
+ args.push('-R', team.slug);
46
+ const result = await execa('gh', args, { cwd: team.repoDir, timeout: GH_CLI_TIMEOUT_MS });
47
+ ghResults.push({ mergedPRs: JSON.parse(result.stdout) });
48
+ }
49
+ catch {
50
+ ghResults.push({ mergedPRs: [] });
51
+ }
52
+ }
53
+ // Phase 3: DB reads + writes (brief lock)
54
+ const mergedSynced = await ctx.withDb(async (db) => {
55
+ let storiesUpdated = 0;
56
+ for (const ghResult of ghResults) {
57
+ const candidateStoryIds = Array.from(new Set(ghResult.mergedPRs
58
+ .map(pr => extractStoryIdFromBranch(pr.headRefName))
59
+ .filter((id) => Boolean(id))));
60
+ if (candidateStoryIds.length === 0)
61
+ continue;
62
+ const placeholders = candidateStoryIds.map(() => '?').join(',');
63
+ const updatableStories = queryAll(db.db, `SELECT id FROM stories WHERE status != 'merged' AND id IN (${placeholders})`, candidateStoryIds);
64
+ const updatableStoryIds = new Set(updatableStories.map(s => s.id));
65
+ const toUpdate = [];
66
+ for (const pr of ghResult.mergedPRs) {
67
+ const storyId = extractStoryIdFromBranch(pr.headRefName);
68
+ if (!storyId || !updatableStoryIds.has(storyId))
69
+ continue;
70
+ updatableStoryIds.delete(storyId);
71
+ toUpdate.push({ storyId, prNumber: pr.number });
72
+ }
73
+ if (toUpdate.length > 0) {
74
+ await withTransaction(db.db, () => {
75
+ for (const update of toUpdate) {
76
+ updateStory(db.db, update.storyId, { status: 'merged', assignedAgentId: null });
77
+ const cleanup = cleanupAgentsReferencingMergedStory(db.db, update.storyId);
78
+ createLog(db.db, {
79
+ agentId: 'manager',
80
+ storyId: update.storyId,
81
+ eventType: 'STORY_MERGED',
82
+ message: `Story synced to merged from GitHub PR #${update.prNumber}`,
83
+ metadata: {
84
+ merged_agent_cleanup_cleared: cleanup.cleared,
85
+ merged_agent_cleanup_reassigned: cleanup.reassigned,
86
+ },
87
+ });
88
+ }
89
+ });
90
+ for (const update of toUpdate) {
91
+ syncStatusForStory(ctx.root, db.db, update.storyId, 'merged');
92
+ }
93
+ storiesUpdated += toUpdate.length;
94
+ }
95
+ }
96
+ if (storiesUpdated > 0)
97
+ db.save();
98
+ return storiesUpdated;
99
+ });
100
+ verboseLogCtx(ctx, `syncMergedPRs: synced=${mergedSynced}`);
101
+ if (mergedSynced > 0) {
102
+ console.log(chalk.green(` Synced ${mergedSynced} merged story(ies) from GitHub`));
103
+ }
104
+ }
105
+ export async function reconcileAgentsOnMergedStories(ctx) {
106
+ const result = await ctx.withDb(async (db) => {
107
+ const mergedStoryIds = queryAll(db.db, `
108
+ SELECT DISTINCT s.id
109
+ FROM stories s
110
+ JOIN agents a ON a.current_story_id = s.id
111
+ WHERE s.status = 'merged'
112
+ AND a.status != 'terminated'
113
+ `).map(row => row.id);
114
+ if (mergedStoryIds.length === 0) {
115
+ return { storyCount: 0, cleared: 0, reassigned: 0 };
116
+ }
117
+ let cleared = 0;
118
+ let reassigned = 0;
119
+ for (const storyId of mergedStoryIds) {
120
+ const cleanup = cleanupAgentsReferencingMergedStory(db.db, storyId);
121
+ if (cleanup.cleared > 0) {
122
+ createLog(db.db, {
123
+ agentId: 'manager',
124
+ storyId,
125
+ eventType: 'STORY_PROGRESS_UPDATE',
126
+ message: `Reconciled stale merged-story agent assignments`,
127
+ metadata: {
128
+ story_id: storyId,
129
+ cleared_agents: cleanup.cleared,
130
+ reassigned_agents: cleanup.reassigned,
131
+ recovery: 'merged_story_agent_reconcile',
132
+ },
133
+ });
134
+ }
135
+ cleared += cleanup.cleared;
136
+ reassigned += cleanup.reassigned;
137
+ }
138
+ if (cleared > 0) {
139
+ db.save();
140
+ }
141
+ return { storyCount: mergedStoryIds.length, cleared, reassigned };
142
+ });
143
+ verboseLogCtx(ctx, `reconcileAgentsOnMergedStories: stories=${result.storyCount}, cleared=${result.cleared}, reassigned=${result.reassigned}`);
144
+ if (result.cleared > 0) {
145
+ console.log(chalk.yellow(` Reconciled ${result.cleared} stale merged-story agent assignment(s) (${result.reassigned} reassigned, ${result.cleared - result.reassigned} idled)`));
146
+ }
147
+ }
148
+ export async function syncOpenPRs(ctx) {
149
+ const maxAgeHours = ctx.config.merge_queue?.max_age_hours;
150
+ // Phase 1: Read teams + existing identifiers (brief lock)
151
+ const setupData = await ctx.withDb(async (db) => {
152
+ const { getAllTeams } = await import('../../../db/queries/teams.js');
153
+ const teams = getAllTeams(db.db);
154
+ const { existingBranches, existingPrNumbers } = getExistingPRIdentifiers(db.db, true);
155
+ return {
156
+ teams: teams
157
+ .filter(t => t.repo_path)
158
+ .map(t => ({
159
+ id: t.id,
160
+ repoDir: `${ctx.root}/${t.repo_path}`,
161
+ slug: ghRepoSlug(t.repo_url),
162
+ })),
163
+ existingBranches,
164
+ existingPrNumbers,
165
+ };
166
+ });
167
+ if (setupData.teams.length === 0)
168
+ return;
169
+ // Phase 2: GitHub CLI calls (no lock)
170
+ const teamPRs = new Map();
171
+ for (const team of setupData.teams) {
172
+ try {
173
+ const prs = await fetchOpenGitHubPRs(team.repoDir, team.slug);
174
+ teamPRs.set(team.id, prs);
175
+ }
176
+ catch {
177
+ // gh CLI might not be authenticated
178
+ }
179
+ }
180
+ // Phase 3: Import into DB (brief lock)
181
+ const syncedPRs = await ctx.withDb(async (db, scheduler) => {
182
+ // Re-read identifiers in case another process synced in the meantime
183
+ const { existingBranches, existingPrNumbers } = getExistingPRIdentifiers(db.db, true);
184
+ let totalSynced = 0;
185
+ for (const team of setupData.teams) {
186
+ const prs = teamPRs.get(team.id);
187
+ if (!prs)
188
+ continue;
189
+ for (const ghPR of prs) {
190
+ if (existingBranches.has(ghPR.headRefName) || existingPrNumbers.has(ghPR.number))
191
+ continue;
192
+ // Age filtering
193
+ if (maxAgeHours !== undefined) {
194
+ const ageHours = (Date.now() - new Date(ghPR.createdAt).getTime()) / (1000 * 60 * 60);
195
+ if (ageHours > maxAgeHours) {
196
+ createLog(db.db, {
197
+ agentId: 'manager',
198
+ eventType: 'PR_SYNC_SKIPPED',
199
+ status: 'info',
200
+ message: `Skipped syncing old PR #${ghPR.number} (${ghPR.headRefName}): created ${ageHours.toFixed(1)}h ago (max: ${maxAgeHours}h)`,
201
+ metadata: {
202
+ pr_number: ghPR.number,
203
+ branch: ghPR.headRefName,
204
+ age_hours: ageHours,
205
+ max_age_hours: maxAgeHours,
206
+ reason: 'too_old',
207
+ },
208
+ });
209
+ continue;
210
+ }
211
+ }
212
+ const storyId = extractStoryIdFromBranch(ghPR.headRefName);
213
+ if (storyId) {
214
+ const storyRows = queryAll(db.db, `SELECT id, status FROM stories WHERE id = ? AND status != 'merged'`, [storyId]);
215
+ if (storyRows.length === 0) {
216
+ createLog(db.db, {
217
+ agentId: 'manager',
218
+ eventType: 'PR_SYNC_SKIPPED',
219
+ status: 'info',
220
+ message: `Skipped syncing PR #${ghPR.number} (${ghPR.headRefName}): story ${storyId} not found or already merged`,
221
+ metadata: {
222
+ pr_number: ghPR.number,
223
+ branch: ghPR.headRefName,
224
+ story_id: storyId,
225
+ reason: 'inactive_story',
226
+ },
227
+ });
228
+ continue;
229
+ }
230
+ }
231
+ createPullRequest(db.db, {
232
+ storyId,
233
+ teamId: team.id,
234
+ branchName: ghPR.headRefName,
235
+ githubPrNumber: ghPR.number,
236
+ githubPrUrl: ghPR.url,
237
+ submittedBy: null,
238
+ });
239
+ existingBranches.add(ghPR.headRefName);
240
+ existingPrNumbers.add(ghPR.number);
241
+ totalSynced++;
242
+ }
243
+ }
244
+ if (totalSynced > 0) {
245
+ db.save();
246
+ await scheduler.checkMergeQueue();
247
+ db.save();
248
+ }
249
+ return totalSynced;
250
+ });
251
+ verboseLogCtx(ctx, `syncOpenPRs: synced=${syncedPRs}`);
252
+ if (syncedPRs > 0) {
253
+ console.log(chalk.yellow(` Synced ${syncedPRs} GitHub PR(s) into merge queue`));
254
+ }
255
+ }
256
+ export async function closeStalePRs(ctx) {
257
+ // Phase 1: Read teams + PR data (brief lock)
258
+ const { teamInfos, prsByStory } = await ctx.withDb(async (db) => {
259
+ const { getAllTeams } = await import('../../../db/queries/teams.js');
260
+ const teams = getAllTeams(db.db).filter(t => t.repo_path);
261
+ // Pre-fetch all non-closed PR data grouped by story
262
+ const allPRs = queryAll(db.db, `SELECT story_id, id, github_pr_number FROM pull_requests WHERE status NOT IN ('closed') ORDER BY created_at DESC`);
263
+ const prsByStory = new Map();
264
+ for (const pr of allPRs) {
265
+ if (!pr.story_id)
266
+ continue;
267
+ const existing = prsByStory.get(pr.story_id) || [];
268
+ existing.push({ id: pr.id, github_pr_number: pr.github_pr_number });
269
+ prsByStory.set(pr.story_id, existing);
270
+ }
271
+ return {
272
+ teamInfos: teams.map(t => ({
273
+ repoDir: `${ctx.root}/${t.repo_path}`,
274
+ })),
275
+ prsByStory,
276
+ };
277
+ });
278
+ if (teamInfos.length === 0)
279
+ return;
280
+ // Phase 2: GitHub CLI calls (no lock)
281
+ const baseBranch = ctx.config.github?.base_branch ?? 'main';
282
+ const closed = [];
283
+ for (const team of teamInfos) {
284
+ try {
285
+ const openGHPRs = await fetchOpenGitHubPRs(team.repoDir);
286
+ for (const ghPR of openGHPRs) {
287
+ // Skip PRs that don't target the configured base branch
288
+ if (ghPR.baseRefName !== baseBranch)
289
+ continue;
290
+ const storyId = extractStoryIdFromBranch(ghPR.headRefName);
291
+ if (!storyId)
292
+ continue;
293
+ const prsForStory = prsByStory.get(storyId);
294
+ if (!prsForStory || prsForStory.length === 0)
295
+ continue;
296
+ const hasUnsyncedEntry = prsForStory.some(pr => pr.github_pr_number == null);
297
+ if (hasUnsyncedEntry)
298
+ continue;
299
+ const isInQueue = prsForStory.some(pr => pr.github_pr_number === ghPR.number);
300
+ if (!isInQueue) {
301
+ const supersededByPrNumber = prsForStory.find(pr => pr.github_pr_number !== null)?.github_pr_number ?? null;
302
+ try {
303
+ await execa('gh', ['pr', 'close', String(ghPR.number)], {
304
+ cwd: team.repoDir,
305
+ timeout: GH_CLI_TIMEOUT_MS,
306
+ });
307
+ closed.push({
308
+ storyId,
309
+ closedPrNumber: ghPR.number,
310
+ branch: ghPR.headRefName,
311
+ supersededByPrNumber,
312
+ });
313
+ }
314
+ catch {
315
+ // Non-fatal
316
+ }
317
+ }
318
+ }
319
+ }
320
+ catch {
321
+ continue;
322
+ }
323
+ }
324
+ // Phase 3: Write logs (brief lock)
325
+ if (closed.length > 0) {
326
+ await ctx.withDb(async (db) => {
327
+ for (const info of closed) {
328
+ const supersededDesc = info.supersededByPrNumber !== null ? ` by PR #${info.supersededByPrNumber}` : '';
329
+ createLog(db.db, {
330
+ agentId: 'manager',
331
+ storyId: info.storyId,
332
+ eventType: 'PR_CLOSED',
333
+ message: `Auto-closed stale GitHub PR #${info.closedPrNumber} (${info.branch}) - superseded${supersededDesc}`,
334
+ metadata: {
335
+ github_pr_number: info.closedPrNumber,
336
+ branch: info.branch,
337
+ reason: 'stale',
338
+ superseded_by_pr_number: info.supersededByPrNumber,
339
+ },
340
+ });
341
+ }
342
+ db.save();
343
+ });
344
+ console.log(chalk.yellow(` Closed ${closed.length} stale GitHub PR(s):`));
345
+ for (const info of closed) {
346
+ const supersededDesc = info.supersededByPrNumber !== null
347
+ ? ` (superseded by PR #${info.supersededByPrNumber})`
348
+ : '';
349
+ console.log(chalk.gray(` PR #${info.closedPrNumber} [${info.storyId}] ${info.branch}${supersededDesc}`));
350
+ }
351
+ }
352
+ verboseLogCtx(ctx, `closeStalePRs: closed=${closed.length}`);
353
+ }
354
+ export async function recoverStaleReviewingPRs(ctx) {
355
+ const now = Date.now();
356
+ // Phase 1: Read stale reviewing PRs and resolve repo metadata (brief lock)
357
+ const candidates = await ctx.withDb(async (db) => {
358
+ const reviewingPRs = getPullRequestsByStatus(db.db, 'reviewing').filter(pr => {
359
+ if (!pr.github_pr_number || !pr.team_id)
360
+ return false;
361
+ const updatedAtMs = Date.parse(pr.updated_at);
362
+ if (Number.isNaN(updatedAtMs))
363
+ return true;
364
+ return now - updatedAtMs >= REVIEWING_PR_VALIDATION_MIN_AGE_MS;
365
+ });
366
+ verboseLogCtx(ctx, `recoverStaleReviewingPRs: staleCandidates=${reviewingPRs.length}`);
367
+ if (reviewingPRs.length === 0) {
368
+ return [];
369
+ }
370
+ const { getAllTeams } = await import('../../../db/queries/teams.js');
371
+ const teams = getAllTeams(db.db);
372
+ const teamsById = new Map(teams.map(team => [team.id, team]));
373
+ const result = [];
374
+ for (const pr of reviewingPRs) {
375
+ const team = teamsById.get(pr.team_id);
376
+ if (!team?.repo_path)
377
+ continue;
378
+ result.push({
379
+ id: pr.id,
380
+ storyId: pr.story_id,
381
+ teamId: pr.team_id,
382
+ branchName: pr.branch_name,
383
+ githubPrNumber: pr.github_pr_number,
384
+ reviewedBy: pr.reviewed_by,
385
+ repoDir: `${ctx.root}/${team.repo_path}`,
386
+ repoSlug: ghRepoSlug(team.repo_url),
387
+ });
388
+ }
389
+ return result;
390
+ });
391
+ if (candidates.length === 0)
392
+ return;
393
+ // Phase 2: Check GitHub state for each stale reviewing PR (no lock)
394
+ const mergedResults = [];
395
+ const rejectedResults = [];
396
+ for (const candidate of candidates) {
397
+ try {
398
+ const args = ['pr', 'view', String(candidate.githubPrNumber), '--json', 'state,url'];
399
+ if (candidate.repoSlug)
400
+ args.push('-R', candidate.repoSlug);
401
+ const result = await execa('gh', args, {
402
+ cwd: candidate.repoDir,
403
+ timeout: GH_PR_VIEW_TIMEOUT_MS,
404
+ });
405
+ const parsed = JSON.parse(result.stdout);
406
+ const state = parsed.state?.toUpperCase();
407
+ const url = parsed.url || null;
408
+ if (state === 'OPEN') {
409
+ // PR is still open on GitHub but stale in 'reviewing' — the QA agent
410
+ // may have missed the original nudge. Re-nudge if QA agent is idle.
411
+ if (candidate.reviewedBy) {
412
+ const qaAgent = ctx.agentsBySessionName.get(candidate.reviewedBy);
413
+ if (qaAgent && qaAgent.status === 'idle') {
414
+ const githubLine = candidate.repoSlug
415
+ ? `\n# GitHub: https://github.com/${candidate.repoSlug}/pull/${candidate.githubPrNumber}`
416
+ : '';
417
+ await sendManagerNudge(ctx, candidate.reviewedBy, `# [REMINDER] You are assigned PR review ${candidate.id} (${candidate.storyId || 'no-story'}).${githubLine}
418
+ # This PR has been waiting for review. Execute now:
419
+ # hive pr show ${candidate.id}
420
+ # hive pr approve ${candidate.id}
421
+ # or reject:
422
+ # hive pr reject ${candidate.id} -r "reason"`);
423
+ verboseLogCtx(ctx, `recoverStaleReviewingPRs: re-nudged idle QA ${candidate.reviewedBy} for stale pr=${candidate.id}`);
424
+ }
425
+ }
426
+ continue;
427
+ }
428
+ if (state === 'MERGED') {
429
+ mergedResults.push({
430
+ candidate,
431
+ githubState: 'MERGED',
432
+ githubUrl: url,
433
+ });
434
+ continue;
435
+ }
436
+ if (state) {
437
+ rejectedResults.push({
438
+ candidate,
439
+ githubState: state,
440
+ githubUrl: url,
441
+ });
442
+ }
443
+ }
444
+ catch (err) {
445
+ verboseLogCtx(ctx, `recoverStaleReviewingPRs: skip pr=${candidate.id} github_check_failed=${err instanceof Error ? err.message : String(err)}`);
446
+ }
447
+ }
448
+ if (mergedResults.length === 0 && rejectedResults.length === 0)
449
+ return;
450
+ const mergedStoryIds = [];
451
+ // Phase 3: Apply DB updates (brief lock)
452
+ await ctx.withDb(async (db) => {
453
+ for (const result of mergedResults) {
454
+ await withTransaction(db.db, () => {
455
+ const currentPR = queryOne(db.db, `SELECT status FROM pull_requests WHERE id = ?`, [result.candidate.id]);
456
+ if (!currentPR || currentPR.status !== 'reviewing')
457
+ return;
458
+ updatePullRequest(db.db, result.candidate.id, {
459
+ status: 'merged',
460
+ reviewedBy: result.candidate.reviewedBy || 'manager',
461
+ });
462
+ createLog(db.db, {
463
+ agentId: 'manager',
464
+ storyId: result.candidate.storyId || undefined,
465
+ eventType: 'PR_MERGED',
466
+ message: `Auto-closed reviewing PR ${result.candidate.id}: GitHub PR #${result.candidate.githubPrNumber} is already merged`,
467
+ metadata: {
468
+ pr_id: result.candidate.id,
469
+ github_pr_number: result.candidate.githubPrNumber,
470
+ github_state: result.githubState,
471
+ github_url: result.githubUrl,
472
+ },
473
+ });
474
+ if (!result.candidate.storyId)
475
+ return;
476
+ updateStory(db.db, result.candidate.storyId, { status: 'merged', assignedAgentId: null });
477
+ const cleanup = cleanupAgentsReferencingMergedStory(db.db, result.candidate.storyId);
478
+ createLog(db.db, {
479
+ agentId: 'manager',
480
+ storyId: result.candidate.storyId,
481
+ eventType: 'STORY_MERGED',
482
+ message: `Story auto-synced to merged (GitHub PR #${result.candidate.githubPrNumber} already merged)`,
483
+ metadata: {
484
+ pr_id: result.candidate.id,
485
+ github_pr_number: result.candidate.githubPrNumber,
486
+ github_url: result.githubUrl,
487
+ merged_agent_cleanup_cleared: cleanup.cleared,
488
+ merged_agent_cleanup_reassigned: cleanup.reassigned,
489
+ },
490
+ });
491
+ mergedStoryIds.push(result.candidate.storyId);
492
+ }, () => db.save());
493
+ }
494
+ for (const result of rejectedResults) {
495
+ await withTransaction(db.db, () => {
496
+ const currentPR = queryOne(db.db, `SELECT status FROM pull_requests WHERE id = ?`, [result.candidate.id]);
497
+ if (!currentPR || currentPR.status !== 'reviewing')
498
+ return;
499
+ const reason = `GitHub PR #${result.candidate.githubPrNumber} is ${result.githubState.toLowerCase()} on GitHub${result.githubUrl ? ` (${result.githubUrl})` : ''}. Reopen/create a new PR and resubmit.`;
500
+ updatePullRequest(db.db, result.candidate.id, {
501
+ status: 'rejected',
502
+ reviewedBy: result.candidate.reviewedBy || 'manager',
503
+ reviewNotes: reason,
504
+ });
505
+ createLog(db.db, {
506
+ agentId: 'manager',
507
+ storyId: result.candidate.storyId || undefined,
508
+ eventType: 'PR_REJECTED',
509
+ status: 'warn',
510
+ message: `Auto-rejected stale review ${result.candidate.id}: ${reason}`,
511
+ metadata: {
512
+ pr_id: result.candidate.id,
513
+ github_pr_number: result.candidate.githubPrNumber,
514
+ github_state: result.githubState,
515
+ github_url: result.githubUrl,
516
+ branch: result.candidate.branchName,
517
+ team_id: result.candidate.teamId,
518
+ },
519
+ });
520
+ }, () => db.save());
521
+ }
522
+ });
523
+ // Sync merged stories to PM provider outside lock
524
+ const uniqueMergedStoryIds = Array.from(new Set(mergedStoryIds));
525
+ for (const storyId of uniqueMergedStoryIds) {
526
+ await ctx.withDb(async (db) => {
527
+ await syncStatusForStory(ctx.root, db.db, storyId, 'merged');
528
+ });
529
+ }
530
+ if (mergedResults.length > 0) {
531
+ console.log(chalk.green(` Auto-synced ${mergedResults.length} reviewing PR(s) that were already merged on GitHub`));
532
+ }
533
+ if (rejectedResults.length > 0) {
534
+ console.log(chalk.yellow(` Auto-rejected ${rejectedResults.length} stale reviewing PR(s) with non-open GitHub PR state`));
535
+ }
536
+ }
537
+ //# sourceMappingURL=pr-sync-orchestrator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pr-sync-orchestrator.js","sourceRoot":"","sources":["../../../../src/cli/commands/manager/pr-sync-orchestrator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { ManagerCheckContext } from './types.js';
2
+ export declare function notifyQAOfQueuedPRs(ctx: ManagerCheckContext): Promise<void>;
3
+ /**
4
+ * Auto-reject PRs where the QA agent posted review comments/feedback on GitHub
5
+ * but never formally approved or rejected via `hive pr approve/reject`.
6
+ *
7
+ * Detection: PR is in 'reviewing' status, the assigned QA agent is idle,
8
+ * and there are GitHub comments or CHANGES_REQUESTED reviews on the PR.
9
+ *
10
+ * Action: Auto-reject the PR with the QA's feedback as the rejection reason,
11
+ * which triggers the standard qa_failed flow back to the developer agent.
12
+ */
13
+ export declare function autoRejectCommentOnlyReviews(ctx: ManagerCheckContext): Promise<void>;
14
+ export declare function handleRejectedPRs(ctx: ManagerCheckContext): Promise<void>;
15
+ //# sourceMappingURL=qa-review-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qa-review-handler.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/manager/qa-review-handler.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEtD,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CA2GjF;AAED;;;;;;;;;GASG;AACH,wBAAsB,4BAA4B,CAAC,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CA+K1F;AAED,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAoF/E"}