hungry-ghost-hive 0.48.0 → 0.49.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.
- package/dist/agents/base-agent.d.ts +11 -11
- package/dist/agents/base-agent.d.ts.map +1 -1
- package/dist/agents/base-agent.js +25 -25
- package/dist/agents/base-agent.js.map +1 -1
- package/dist/agents/base-agent.test.js +2 -1
- package/dist/agents/base-agent.test.js.map +1 -1
- package/dist/agents/intermediate.d.ts +2 -0
- package/dist/agents/intermediate.d.ts.map +1 -1
- package/dist/agents/intermediate.js +25 -18
- package/dist/agents/intermediate.js.map +1 -1
- package/dist/agents/junior.d.ts +2 -0
- package/dist/agents/junior.d.ts.map +1 -1
- package/dist/agents/junior.js +25 -18
- package/dist/agents/junior.js.map +1 -1
- package/dist/agents/qa.d.ts +2 -0
- package/dist/agents/qa.d.ts.map +1 -1
- package/dist/agents/qa.js +47 -38
- package/dist/agents/qa.js.map +1 -1
- package/dist/agents/senior.d.ts +2 -0
- package/dist/agents/senior.d.ts.map +1 -1
- package/dist/agents/senior.js +40 -27
- package/dist/agents/senior.js.map +1 -1
- package/dist/agents/tech-lead.d.ts +2 -0
- package/dist/agents/tech-lead.d.ts.map +1 -1
- package/dist/agents/tech-lead.js +37 -31
- package/dist/agents/tech-lead.js.map +1 -1
- package/dist/cli/commands/add-repo.js +2 -2
- package/dist/cli/commands/add-repo.js.map +1 -1
- package/dist/cli/commands/add-repo.test.js +1 -1
- package/dist/cli/commands/add-repo.test.js.map +1 -1
- package/dist/cli/commands/agents.d.ts.map +1 -1
- package/dist/cli/commands/agents.js +12 -10
- package/dist/cli/commands/agents.js.map +1 -1
- package/dist/cli/commands/agents.test.js +7 -7
- package/dist/cli/commands/agents.test.js.map +1 -1
- package/dist/cli/commands/approach.js +2 -2
- package/dist/cli/commands/approach.js.map +1 -1
- package/dist/cli/commands/approvals.js +7 -7
- package/dist/cli/commands/approvals.js.map +1 -1
- package/dist/cli/commands/approvals.test.js +8 -8
- package/dist/cli/commands/approvals.test.js.map +1 -1
- package/dist/cli/commands/assign.js +4 -4
- package/dist/cli/commands/assign.js.map +1 -1
- package/dist/cli/commands/assign.test.js +18 -16
- package/dist/cli/commands/assign.test.js.map +1 -1
- package/dist/cli/commands/cleanup.d.ts.map +1 -1
- package/dist/cli/commands/cleanup.js +8 -8
- package/dist/cli/commands/cleanup.js.map +1 -1
- package/dist/cli/commands/cleanup.test.js +5 -1
- package/dist/cli/commands/cleanup.test.js.map +1 -1
- package/dist/cli/commands/escalations.js +9 -7
- package/dist/cli/commands/escalations.js.map +1 -1
- package/dist/cli/commands/escalations.test.js +2 -2
- package/dist/cli/commands/escalations.test.js.map +1 -1
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +48 -5
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/init.test.js +4 -0
- package/dist/cli/commands/init.test.js.map +1 -1
- package/dist/cli/commands/manager/agent-monitoring.d.ts +2 -2
- package/dist/cli/commands/manager/agent-monitoring.d.ts.map +1 -1
- package/dist/cli/commands/manager/agent-monitoring.js +1 -1
- package/dist/cli/commands/manager/agent-monitoring.js.map +1 -1
- package/dist/cli/commands/manager/auditor-lifecycle.js +3 -3
- package/dist/cli/commands/manager/auditor-lifecycle.js.map +1 -1
- package/dist/cli/commands/manager/auditor-lifecycle.test.js +21 -14
- package/dist/cli/commands/manager/auditor-lifecycle.test.js.map +1 -1
- package/dist/cli/commands/manager/auto-reject-comment-only-reviews.test.js +28 -23
- package/dist/cli/commands/manager/auto-reject-comment-only-reviews.test.js.map +1 -1
- package/dist/cli/commands/manager/escalation-handler.d.ts +2 -2
- package/dist/cli/commands/manager/escalation-handler.d.ts.map +1 -1
- package/dist/cli/commands/manager/escalation-handler.js +11 -10
- package/dist/cli/commands/manager/escalation-handler.js.map +1 -1
- package/dist/cli/commands/manager/escalation-handler.test.js +8 -8
- package/dist/cli/commands/manager/escalation-handler.test.js.map +1 -1
- package/dist/cli/commands/manager/feature-sign-off.js +7 -7
- package/dist/cli/commands/manager/feature-sign-off.js.map +1 -1
- package/dist/cli/commands/manager/feature-sign-off.test.js +40 -31
- package/dist/cli/commands/manager/feature-sign-off.test.js.map +1 -1
- package/dist/cli/commands/manager/feature-test-result.d.ts.map +1 -1
- package/dist/cli/commands/manager/feature-test-result.js +12 -13
- package/dist/cli/commands/manager/feature-test-result.js.map +1 -1
- package/dist/cli/commands/manager/handoff-recovery.d.ts.map +1 -1
- package/dist/cli/commands/manager/handoff-recovery.js +14 -15
- package/dist/cli/commands/manager/handoff-recovery.js.map +1 -1
- package/dist/cli/commands/manager/index.d.ts.map +1 -1
- package/dist/cli/commands/manager/index.js +26 -26
- package/dist/cli/commands/manager/index.js.map +1 -1
- package/dist/cli/commands/manager/index.test.js +3 -3
- package/dist/cli/commands/manager/index.test.js.map +1 -1
- package/dist/cli/commands/manager/merged-story-cleanup.d.ts +2 -2
- package/dist/cli/commands/manager/merged-story-cleanup.d.ts.map +1 -1
- package/dist/cli/commands/manager/merged-story-cleanup.js +6 -7
- package/dist/cli/commands/manager/merged-story-cleanup.js.map +1 -1
- package/dist/cli/commands/manager/merged-story-cleanup.test.js +27 -18
- package/dist/cli/commands/manager/merged-story-cleanup.test.js.map +1 -1
- package/dist/cli/commands/manager/pr-sync-orchestrator.d.ts.map +1 -1
- package/dist/cli/commands/manager/pr-sync-orchestrator.js +46 -38
- package/dist/cli/commands/manager/pr-sync-orchestrator.js.map +1 -1
- package/dist/cli/commands/manager/qa-review-handler.d.ts.map +1 -1
- package/dist/cli/commands/manager/qa-review-handler.js +25 -22
- package/dist/cli/commands/manager/qa-review-handler.js.map +1 -1
- package/dist/cli/commands/manager/spin-down.d.ts.map +1 -1
- package/dist/cli/commands/manager/spin-down.js +23 -19
- package/dist/cli/commands/manager/spin-down.js.map +1 -1
- package/dist/cli/commands/manager/stale-escalations.d.ts +2 -3
- package/dist/cli/commands/manager/stale-escalations.d.ts.map +1 -1
- package/dist/cli/commands/manager/stale-escalations.js.map +1 -1
- package/dist/cli/commands/manager/stuck-story-helpers.js +8 -8
- package/dist/cli/commands/manager/stuck-story-helpers.js.map +1 -1
- package/dist/cli/commands/manager/stuck-story-processor.d.ts +2 -2
- package/dist/cli/commands/manager/stuck-story-processor.d.ts.map +1 -1
- package/dist/cli/commands/manager/stuck-story-processor.js +23 -22
- package/dist/cli/commands/manager/stuck-story-processor.js.map +1 -1
- package/dist/cli/commands/manager/tech-lead-lifecycle.js +6 -6
- package/dist/cli/commands/manager/tech-lead-lifecycle.js.map +1 -1
- package/dist/cli/commands/manager/types.d.ts +2 -3
- package/dist/cli/commands/manager/types.d.ts.map +1 -1
- package/dist/cli/commands/manager/types.js.map +1 -1
- package/dist/cli/commands/msg.test.js +2 -2
- package/dist/cli/commands/msg.test.js.map +1 -1
- package/dist/cli/commands/my-stories.d.ts.map +1 -1
- package/dist/cli/commands/my-stories.js +17 -18
- package/dist/cli/commands/my-stories.js.map +1 -1
- package/dist/cli/commands/my-stories.test.js +2 -2
- package/dist/cli/commands/my-stories.test.js.map +1 -1
- package/dist/cli/commands/nuke.test.js +1 -1
- package/dist/cli/commands/nuke.test.js.map +1 -1
- package/dist/cli/commands/pr.js +32 -32
- package/dist/cli/commands/pr.js.map +1 -1
- package/dist/cli/commands/pr.test.js +10 -6
- package/dist/cli/commands/pr.test.js.map +1 -1
- package/dist/cli/commands/progress.d.ts.map +1 -1
- package/dist/cli/commands/progress.js +4 -5
- package/dist/cli/commands/progress.js.map +1 -1
- package/dist/cli/commands/progress.test.js +1 -1
- package/dist/cli/commands/progress.test.js.map +1 -1
- package/dist/cli/commands/req-headless.test.d.ts +2 -0
- package/dist/cli/commands/req-headless.test.d.ts.map +1 -0
- package/dist/cli/commands/req-headless.test.js +128 -0
- package/dist/cli/commands/req-headless.test.js.map +1 -0
- package/dist/cli/commands/req-spawn.test.js +5 -1
- package/dist/cli/commands/req-spawn.test.js.map +1 -1
- package/dist/cli/commands/req.d.ts.map +1 -1
- package/dist/cli/commands/req.js +13 -14
- package/dist/cli/commands/req.js.map +1 -1
- package/dist/cli/commands/resume.d.ts.map +1 -1
- package/dist/cli/commands/resume.js +7 -8
- package/dist/cli/commands/resume.js.map +1 -1
- package/dist/cli/commands/resume.test.js +1 -1
- package/dist/cli/commands/resume.test.js.map +1 -1
- package/dist/cli/commands/status.d.ts.map +1 -1
- package/dist/cli/commands/status.js +42 -40
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/cli/commands/status.test.js +1 -1
- package/dist/cli/commands/status.test.js.map +1 -1
- package/dist/cli/commands/stories.js +9 -9
- package/dist/cli/commands/stories.js.map +1 -1
- package/dist/cli/commands/stories.test.js +2 -2
- package/dist/cli/commands/stories.test.js.map +1 -1
- package/dist/cli/commands/teams.js +11 -11
- package/dist/cli/commands/teams.js.map +1 -1
- package/dist/cli/commands/teams.test.js +2 -2
- package/dist/cli/commands/teams.test.js.map +1 -1
- package/dist/cli/dashboard/index.d.ts +2 -2
- package/dist/cli/dashboard/index.d.ts.map +1 -1
- package/dist/cli/dashboard/index.js +29 -20
- package/dist/cli/dashboard/index.js.map +1 -1
- package/dist/cli/dashboard/index.test.js +34 -32
- package/dist/cli/dashboard/index.test.js.map +1 -1
- package/dist/cli/dashboard/panels/activity.d.ts +3 -3
- package/dist/cli/dashboard/panels/activity.d.ts.map +1 -1
- package/dist/cli/dashboard/panels/activity.js +1 -1
- package/dist/cli/dashboard/panels/activity.js.map +1 -1
- package/dist/cli/dashboard/panels/agents.d.ts +3 -3
- package/dist/cli/dashboard/panels/agents.d.ts.map +1 -1
- package/dist/cli/dashboard/panels/agents.js +2 -2
- package/dist/cli/dashboard/panels/agents.js.map +1 -1
- package/dist/cli/dashboard/panels/escalations.d.ts +3 -3
- package/dist/cli/dashboard/panels/escalations.d.ts.map +1 -1
- package/dist/cli/dashboard/panels/escalations.js +1 -1
- package/dist/cli/dashboard/panels/escalations.js.map +1 -1
- package/dist/cli/dashboard/panels/merge-queue.d.ts +3 -3
- package/dist/cli/dashboard/panels/merge-queue.d.ts.map +1 -1
- package/dist/cli/dashboard/panels/merge-queue.js +1 -1
- package/dist/cli/dashboard/panels/merge-queue.js.map +1 -1
- package/dist/cli/dashboard/panels/pipeline.d.ts +3 -3
- package/dist/cli/dashboard/panels/pipeline.d.ts.map +1 -1
- package/dist/cli/dashboard/panels/pipeline.js +1 -1
- package/dist/cli/dashboard/panels/pipeline.js.map +1 -1
- package/dist/config/schema.d.ts +85 -82
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +1 -0
- package/dist/config/schema.js.map +1 -1
- package/dist/connectors/project-management/operations.d.ts +7 -7
- package/dist/connectors/project-management/operations.d.ts.map +1 -1
- package/dist/connectors/project-management/operations.js +2 -3
- package/dist/connectors/project-management/operations.js.map +1 -1
- package/dist/context-files/index.test.js +1 -0
- package/dist/context-files/index.test.js.map +1 -1
- package/dist/db/client.d.ts +6 -0
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +7 -0
- package/dist/db/client.js.map +1 -1
- package/dist/db/postgres-provider.d.ts +43 -0
- package/dist/db/postgres-provider.d.ts.map +1 -0
- package/dist/db/postgres-provider.integration.test.d.ts +2 -0
- package/dist/db/postgres-provider.integration.test.d.ts.map +1 -0
- package/dist/db/postgres-provider.integration.test.js +399 -0
- package/dist/db/postgres-provider.integration.test.js.map +1 -0
- package/dist/db/postgres-provider.js +315 -0
- package/dist/db/postgres-provider.js.map +1 -0
- package/dist/db/postgres-provider.test.d.ts +2 -0
- package/dist/db/postgres-provider.test.d.ts.map +1 -0
- package/dist/db/postgres-provider.test.js +72 -0
- package/dist/db/postgres-provider.test.js.map +1 -0
- package/dist/db/provider.d.ts +59 -0
- package/dist/db/provider.d.ts.map +1 -0
- package/dist/db/provider.js +121 -0
- package/dist/db/provider.js.map +1 -0
- package/dist/db/provider.test.d.ts +2 -0
- package/dist/db/provider.test.d.ts.map +1 -0
- package/dist/db/provider.test.js +226 -0
- package/dist/db/provider.test.js.map +1 -0
- package/dist/db/queries/agents.d.ts +13 -13
- package/dist/db/queries/agents.d.ts.map +1 -1
- package/dist/db/queries/agents.js +27 -28
- package/dist/db/queries/agents.js.map +1 -1
- package/dist/db/queries/agents.test.js +113 -111
- package/dist/db/queries/agents.test.js.map +1 -1
- package/dist/db/queries/escalations.d.ts +16 -16
- package/dist/db/queries/escalations.d.ts.map +1 -1
- package/dist/db/queries/escalations.js +34 -35
- package/dist/db/queries/escalations.js.map +1 -1
- package/dist/db/queries/escalations.test.js +133 -131
- package/dist/db/queries/escalations.test.js.map +1 -1
- package/dist/db/queries/heartbeat.d.ts +5 -5
- package/dist/db/queries/heartbeat.d.ts.map +1 -1
- package/dist/db/queries/heartbeat.js +7 -23
- package/dist/db/queries/heartbeat.js.map +1 -1
- package/dist/db/queries/heartbeat.test.js +76 -76
- package/dist/db/queries/heartbeat.test.js.map +1 -1
- package/dist/db/queries/integration-sync.d.ts +7 -7
- package/dist/db/queries/integration-sync.d.ts.map +1 -1
- package/dist/db/queries/integration-sync.js +13 -14
- package/dist/db/queries/integration-sync.js.map +1 -1
- package/dist/db/queries/logs.d.ts +10 -10
- package/dist/db/queries/logs.d.ts.map +1 -1
- package/dist/db/queries/logs.js +44 -42
- package/dist/db/queries/logs.js.map +1 -1
- package/dist/db/queries/logs.test.js +149 -146
- package/dist/db/queries/logs.test.js.map +1 -1
- package/dist/db/queries/messages.d.ts +6 -6
- package/dist/db/queries/messages.d.ts.map +1 -1
- package/dist/db/queries/messages.js +12 -11
- package/dist/db/queries/messages.js.map +1 -1
- package/dist/db/queries/messages.test.js +47 -46
- package/dist/db/queries/messages.test.js.map +1 -1
- package/dist/db/queries/pull-requests.d.ts +18 -18
- package/dist/db/queries/pull-requests.d.ts.map +1 -1
- package/dist/db/queries/pull-requests.js +50 -48
- package/dist/db/queries/pull-requests.js.map +1 -1
- package/dist/db/queries/pull-requests.test.js +195 -198
- package/dist/db/queries/pull-requests.test.js.map +1 -1
- package/dist/db/queries/requirements.d.ts +8 -8
- package/dist/db/queries/requirements.d.ts.map +1 -1
- package/dist/db/queries/requirements.js +17 -18
- package/dist/db/queries/requirements.js.map +1 -1
- package/dist/db/queries/requirements.test.js +83 -81
- package/dist/db/queries/requirements.test.js.map +1 -1
- package/dist/db/queries/stories.d.ts +29 -29
- package/dist/db/queries/stories.d.ts.map +1 -1
- package/dist/db/queries/stories.js +58 -64
- package/dist/db/queries/stories.js.map +1 -1
- package/dist/db/queries/stories.test.js +172 -170
- package/dist/db/queries/stories.test.js.map +1 -1
- package/dist/db/queries/teams.d.ts +6 -6
- package/dist/db/queries/teams.d.ts.map +1 -1
- package/dist/db/queries/teams.js +11 -12
- package/dist/db/queries/teams.js.map +1 -1
- package/dist/db/queries/teams.test.js +36 -34
- package/dist/db/queries/teams.test.js.map +1 -1
- package/dist/integrations/jira/repair.test.js +26 -24
- package/dist/integrations/jira/repair.test.js.map +1 -1
- package/dist/integrations/jira/stories.d.ts +3 -3
- package/dist/integrations/jira/stories.d.ts.map +1 -1
- package/dist/integrations/jira/stories.js +12 -12
- package/dist/integrations/jira/stories.js.map +1 -1
- package/dist/integrations/jira/stories.test.js +10 -8
- package/dist/integrations/jira/stories.test.js.map +1 -1
- package/dist/integrations/jira/sync.d.ts +7 -7
- package/dist/integrations/jira/sync.d.ts.map +1 -1
- package/dist/integrations/jira/sync.js +17 -20
- package/dist/integrations/jira/sync.js.map +1 -1
- package/dist/integrations/jira/sync.test.js +63 -62
- package/dist/integrations/jira/sync.test.js.map +1 -1
- package/dist/integrations/jira/transitions.d.ts +3 -3
- package/dist/integrations/jira/transitions.d.ts.map +1 -1
- package/dist/integrations/jira/transitions.js +3 -3
- package/dist/integrations/jira/transitions.js.map +1 -1
- package/dist/orchestrator/agent-selector.d.ts +3 -3
- package/dist/orchestrator/agent-selector.d.ts.map +1 -1
- package/dist/orchestrator/agent-selector.js +5 -6
- package/dist/orchestrator/agent-selector.js.map +1 -1
- package/dist/orchestrator/dependency-resolver.d.ts +4 -4
- package/dist/orchestrator/dependency-resolver.d.ts.map +1 -1
- package/dist/orchestrator/dependency-resolver.js +6 -6
- package/dist/orchestrator/dependency-resolver.js.map +1 -1
- package/dist/orchestrator/feature-branch.d.ts +3 -3
- package/dist/orchestrator/feature-branch.d.ts.map +1 -1
- package/dist/orchestrator/feature-branch.js +9 -10
- package/dist/orchestrator/feature-branch.js.map +1 -1
- package/dist/orchestrator/feature-branch.test.js +80 -78
- package/dist/orchestrator/feature-branch.test.js.map +1 -1
- package/dist/orchestrator/orphan-recovery.d.ts +2 -2
- package/dist/orchestrator/orphan-recovery.d.ts.map +1 -1
- package/dist/orchestrator/orphan-recovery.js +10 -10
- package/dist/orchestrator/orphan-recovery.js.map +1 -1
- package/dist/orchestrator/scheduler.d.ts +4 -4
- package/dist/orchestrator/scheduler.d.ts.map +1 -1
- package/dist/orchestrator/scheduler.js +90 -76
- package/dist/orchestrator/scheduler.js.map +1 -1
- package/dist/orchestrator/scheduler.test.js +496 -374
- package/dist/orchestrator/scheduler.test.js.map +1 -1
- package/dist/utils/auto-merge.d.ts.map +1 -1
- package/dist/utils/auto-merge.js +74 -56
- package/dist/utils/auto-merge.js.map +1 -1
- package/dist/utils/auto-merge.test.js +101 -66
- package/dist/utils/auto-merge.test.js.map +1 -1
- package/dist/utils/cli-helpers.d.ts +5 -5
- package/dist/utils/cli-helpers.d.ts.map +1 -1
- package/dist/utils/cli-helpers.js +8 -9
- package/dist/utils/cli-helpers.js.map +1 -1
- package/dist/utils/cli-helpers.test.js +28 -30
- package/dist/utils/cli-helpers.test.js.map +1 -1
- package/dist/utils/paths.d.ts +6 -0
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +12 -1
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/paths.test.js +1 -0
- package/dist/utils/paths.test.js.map +1 -1
- package/dist/utils/pr-sync.d.ts +10 -10
- package/dist/utils/pr-sync.d.ts.map +1 -1
- package/dist/utils/pr-sync.js +20 -21
- package/dist/utils/pr-sync.js.map +1 -1
- package/dist/utils/pr-sync.test.js +52 -50
- package/dist/utils/pr-sync.test.js.map +1 -1
- package/dist/utils/with-hive-context.d.ts.map +1 -1
- package/dist/utils/with-hive-context.js +70 -1
- package/dist/utils/with-hive-context.js.map +1 -1
- package/package.json +3 -1
- package/src/agents/base-agent.test.ts +2 -1
- package/src/agents/base-agent.ts +32 -28
- package/src/agents/intermediate.ts +27 -18
- package/src/agents/junior.ts +27 -18
- package/src/agents/qa.ts +54 -40
- package/src/agents/senior.ts +42 -27
- package/src/agents/tech-lead.ts +42 -32
- package/src/cli/commands/add-repo.test.ts +1 -1
- package/src/cli/commands/add-repo.ts +2 -2
- package/src/cli/commands/agents.test.ts +7 -7
- package/src/cli/commands/agents.ts +12 -10
- package/src/cli/commands/approach.ts +2 -2
- package/src/cli/commands/approvals.test.ts +8 -8
- package/src/cli/commands/approvals.ts +9 -7
- package/src/cli/commands/assign.test.ts +19 -18
- package/src/cli/commands/assign.ts +4 -4
- package/src/cli/commands/cleanup.test.ts +5 -1
- package/src/cli/commands/cleanup.ts +11 -9
- package/src/cli/commands/escalations.test.ts +2 -2
- package/src/cli/commands/escalations.ts +9 -7
- package/src/cli/commands/init.test.ts +5 -0
- package/src/cli/commands/init.ts +53 -5
- package/src/cli/commands/manager/agent-monitoring.ts +3 -3
- package/src/cli/commands/manager/auditor-lifecycle.test.ts +21 -14
- package/src/cli/commands/manager/auditor-lifecycle.ts +3 -3
- package/src/cli/commands/manager/auto-reject-comment-only-reviews.test.ts +28 -23
- package/src/cli/commands/manager/escalation-handler.test.ts +13 -13
- package/src/cli/commands/manager/escalation-handler.ts +19 -12
- package/src/cli/commands/manager/feature-sign-off.test.ts +40 -31
- package/src/cli/commands/manager/feature-sign-off.ts +7 -7
- package/src/cli/commands/manager/feature-test-result.ts +13 -16
- package/src/cli/commands/manager/handoff-recovery.ts +20 -20
- package/src/cli/commands/manager/index.test.ts +4 -4
- package/src/cli/commands/manager/index.ts +58 -59
- package/src/cli/commands/manager/merged-story-cleanup.test.ts +28 -19
- package/src/cli/commands/manager/merged-story-cleanup.ts +11 -14
- package/src/cli/commands/manager/pr-sync-orchestrator.ts +115 -110
- package/src/cli/commands/manager/qa-review-handler.ts +50 -63
- package/src/cli/commands/manager/spin-down.ts +27 -25
- package/src/cli/commands/manager/stale-escalations.ts +2 -3
- package/src/cli/commands/manager/stuck-story-helpers.ts +10 -10
- package/src/cli/commands/manager/stuck-story-processor.ts +56 -62
- package/src/cli/commands/manager/tech-lead-lifecycle.ts +6 -6
- package/src/cli/commands/manager/types.ts +2 -3
- package/src/cli/commands/msg.test.ts +2 -2
- package/src/cli/commands/my-stories.test.ts +4 -2
- package/src/cli/commands/my-stories.ts +22 -27
- package/src/cli/commands/nuke.test.ts +1 -1
- package/src/cli/commands/pr.test.ts +10 -6
- package/src/cli/commands/pr.ts +41 -32
- package/src/cli/commands/progress.test.ts +1 -1
- package/src/cli/commands/progress.ts +11 -6
- package/src/cli/commands/req-headless.test.ts +170 -0
- package/src/cli/commands/req-spawn.test.ts +12 -2
- package/src/cli/commands/req.ts +13 -14
- package/src/cli/commands/resume.test.ts +1 -1
- package/src/cli/commands/resume.ts +7 -8
- package/src/cli/commands/status.test.ts +1 -1
- package/src/cli/commands/status.ts +52 -40
- package/src/cli/commands/stories.test.ts +4 -2
- package/src/cli/commands/stories.ts +11 -11
- package/src/cli/commands/teams.test.ts +2 -2
- package/src/cli/commands/teams.ts +11 -11
- package/src/cli/dashboard/index.test.ts +35 -34
- package/src/cli/dashboard/index.ts +34 -23
- package/src/cli/dashboard/panels/activity.ts +10 -4
- package/src/cli/dashboard/panels/agents.ts +8 -5
- package/src/cli/dashboard/panels/escalations.ts +4 -4
- package/src/cli/dashboard/panels/merge-queue.ts +4 -4
- package/src/cli/dashboard/panels/pipeline.ts +10 -4
- package/src/config/schema.ts +1 -0
- package/src/connectors/project-management/operations.ts +9 -10
- package/src/context-files/index.test.ts +1 -0
- package/src/db/client.ts +17 -0
- package/src/db/pg-migrations/001-full-schema.sql +209 -0
- package/src/db/postgres-provider.integration.test.ts +574 -0
- package/src/db/postgres-provider.test.ts +97 -0
- package/src/db/postgres-provider.ts +364 -0
- package/src/db/provider.test.ts +283 -0
- package/src/db/provider.ts +161 -0
- package/src/db/queries/agents.test.ts +114 -113
- package/src/db/queries/agents.ts +50 -36
- package/src/db/queries/escalations.test.ts +134 -133
- package/src/db/queries/escalations.ts +72 -57
- package/src/db/queries/heartbeat.test.ts +77 -78
- package/src/db/queries/heartbeat.ts +24 -46
- package/src/db/queries/integration-sync.ts +26 -26
- package/src/db/queries/logs.test.ts +151 -148
- package/src/db/queries/logs.ts +78 -53
- package/src/db/queries/messages.test.ts +48 -50
- package/src/db/queries/messages.ts +26 -18
- package/src/db/queries/pull-requests.test.ts +194 -199
- package/src/db/queries/pull-requests.ts +117 -88
- package/src/db/queries/requirements.test.ts +84 -83
- package/src/db/queries/requirements.ts +33 -28
- package/src/db/queries/stories.test.ts +173 -172
- package/src/db/queries/stories.ts +141 -110
- package/src/db/queries/teams.test.ts +37 -36
- package/src/db/queries/teams.ts +22 -14
- package/src/integrations/jira/repair.test.ts +27 -26
- package/src/integrations/jira/stories.test.ts +15 -16
- package/src/integrations/jira/stories.ts +15 -15
- package/src/integrations/jira/sync.test.ts +68 -68
- package/src/integrations/jira/sync.ts +29 -39
- package/src/integrations/jira/transitions.ts +6 -6
- package/src/orchestrator/agent-selector.ts +9 -8
- package/src/orchestrator/dependency-resolver.ts +16 -7
- package/src/orchestrator/feature-branch.test.ts +85 -80
- package/src/orchestrator/feature-branch.ts +13 -14
- package/src/orchestrator/orphan-recovery.ts +14 -13
- package/src/orchestrator/scheduler.test.ts +536 -394
- package/src/orchestrator/scheduler.ts +129 -115
- package/src/utils/auto-merge.test.ts +102 -68
- package/src/utils/auto-merge.ts +161 -168
- package/src/utils/cli-helpers.test.ts +30 -32
- package/src/utils/cli-helpers.ts +15 -11
- package/src/utils/paths.test.ts +1 -0
- package/src/utils/paths.ts +14 -1
- package/src/utils/pr-sync.test.ts +55 -52
- package/src/utils/pr-sync.ts +27 -32
- package/src/utils/with-hive-context.ts +89 -1
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import chalk from 'chalk';
|
|
4
4
|
import { syncStatusForStory } from '../../../connectors/project-management/operations.js';
|
|
5
|
-
import type {
|
|
6
|
-
import { queryAll, withTransaction } from '../../../db/client.js';
|
|
5
|
+
import type { StoryRow } from '../../../db/client.js';
|
|
7
6
|
import { getTechLead } from '../../../db/queries/agents.js';
|
|
8
7
|
import { createEscalation } from '../../../db/queries/escalations.js';
|
|
9
8
|
import { createLog } from '../../../db/queries/logs.js';
|
|
@@ -49,15 +48,14 @@ function getLatestStoryUpdateMs(stories: StoryRow[]): number {
|
|
|
49
48
|
return latestMs;
|
|
50
49
|
}
|
|
51
50
|
|
|
52
|
-
function getActivePipelineCountForRequirement(
|
|
53
|
-
db:
|
|
51
|
+
async function getActivePipelineCountForRequirement(
|
|
52
|
+
db: import('../../../db/provider.js').DatabaseProvider,
|
|
54
53
|
requirementId: string | null
|
|
55
|
-
): number {
|
|
54
|
+
): Promise<number> {
|
|
56
55
|
const statuses = `'planned', 'in_progress', 'review', 'qa', 'qa_failed', 'pr_submitted'`;
|
|
57
56
|
|
|
58
57
|
if (requirementId) {
|
|
59
|
-
const result = queryAll<{ count: number }>(
|
|
60
|
-
db,
|
|
58
|
+
const result = await db.queryAll<{ count: number }>(
|
|
61
59
|
`
|
|
62
60
|
SELECT COUNT(*) as count
|
|
63
61
|
FROM stories
|
|
@@ -69,8 +67,7 @@ function getActivePipelineCountForRequirement(
|
|
|
69
67
|
return result[0]?.count || 0;
|
|
70
68
|
}
|
|
71
69
|
|
|
72
|
-
const result = queryAll<{ count: number }>(
|
|
73
|
-
db,
|
|
70
|
+
const result = await db.queryAll<{ count: number }>(
|
|
74
71
|
`
|
|
75
72
|
SELECT COUNT(*) as count
|
|
76
73
|
FROM stories
|
|
@@ -89,7 +86,7 @@ async function nudgeTechLeadForStalledHandoff(
|
|
|
89
86
|
// Brief lock for DB read
|
|
90
87
|
const fallbackSession = getTechLeadSessionName(ctx.paths.hiveDir);
|
|
91
88
|
const techLeadInfo = await ctx.withDb(async db => {
|
|
92
|
-
const techLead = getTechLead(db.
|
|
89
|
+
const techLead = await getTechLead(db.provider);
|
|
93
90
|
return techLead
|
|
94
91
|
? {
|
|
95
92
|
sessionName: techLead.tmux_session || fallbackSession,
|
|
@@ -144,7 +141,7 @@ async function nudgeTechLeadForStalledHandoff(
|
|
|
144
141
|
|
|
145
142
|
// Brief lock for log write
|
|
146
143
|
await ctx.withDb(async db => {
|
|
147
|
-
createLog(db.
|
|
144
|
+
await createLog(db.provider, {
|
|
148
145
|
agentId: 'manager',
|
|
149
146
|
eventType: 'STORY_PROGRESS_UPDATE',
|
|
150
147
|
message: `Nudged Tech Lead to unblock stalled planning handoff for ${requirementLabel}`,
|
|
@@ -164,17 +161,17 @@ async function promoteEstimatedStoriesToPlanned(
|
|
|
164
161
|
const promoted = await ctx.withDb(async db => {
|
|
165
162
|
let count = 0;
|
|
166
163
|
|
|
167
|
-
await withTransaction(
|
|
164
|
+
await db.provider.withTransaction(async () => {
|
|
168
165
|
for (const story of stories) {
|
|
169
|
-
updateStory(db.
|
|
166
|
+
await updateStory(db.provider, story.id, { status: 'planned' });
|
|
170
167
|
count++;
|
|
171
168
|
}
|
|
172
169
|
|
|
173
170
|
if (requirementId) {
|
|
174
|
-
updateRequirement(db.
|
|
171
|
+
await updateRequirement(db.provider, requirementId, { status: 'planned' });
|
|
175
172
|
}
|
|
176
173
|
|
|
177
|
-
createLog(db.
|
|
174
|
+
await createLog(db.provider, {
|
|
178
175
|
agentId: 'manager',
|
|
179
176
|
eventType: 'PLANNING_COMPLETED',
|
|
180
177
|
message: `Auto-promoted ${count} estimated story/ies to planned (${reason})`,
|
|
@@ -186,7 +183,7 @@ async function promoteEstimatedStoriesToPlanned(
|
|
|
186
183
|
|
|
187
184
|
// Sync status changes to Jira
|
|
188
185
|
for (const story of stories) {
|
|
189
|
-
await syncStatusForStory(ctx.root, db.
|
|
186
|
+
await syncStatusForStory(ctx.root, db.provider, story.id, 'planned');
|
|
190
187
|
}
|
|
191
188
|
|
|
192
189
|
return count;
|
|
@@ -216,8 +213,8 @@ async function runAutoAssignmentAfterHandoff(ctx: ManagerCheckContext): Promise<
|
|
|
216
213
|
|
|
217
214
|
if (result.errors.length > 0) {
|
|
218
215
|
const reason = `Manager auto-handoff recovered planning but assignment still has errors: ${result.errors.join('; ')}`;
|
|
219
|
-
createEscalation(db.
|
|
220
|
-
createLog(db.
|
|
216
|
+
await createEscalation(db.provider, { reason });
|
|
217
|
+
await createLog(db.provider, {
|
|
221
218
|
agentId: 'manager',
|
|
222
219
|
eventType: 'ESCALATION_CREATED',
|
|
223
220
|
status: 'error',
|
|
@@ -234,7 +231,7 @@ async function runAutoAssignmentAfterHandoff(ctx: ManagerCheckContext): Promise<
|
|
|
234
231
|
export async function handleStalledPlanningHandoff(ctx: ManagerCheckContext): Promise<void> {
|
|
235
232
|
// Phase 1: Read estimated stories and evaluate handoff state (brief lock)
|
|
236
233
|
const { groupedStories, estimatedCount } = await ctx.withDb(async db => {
|
|
237
|
-
const estimatedStories = getStoriesByStatus(db.
|
|
234
|
+
const estimatedStories = await getStoriesByStatus(db.provider, 'estimated');
|
|
238
235
|
verboseLog(ctx, `handoff: estimatedStories=${estimatedStories.length}`);
|
|
239
236
|
|
|
240
237
|
const grouped = new Map<string, { requirementId: string | null; stories: StoryRow[] }>();
|
|
@@ -258,7 +255,10 @@ export async function handleStalledPlanningHandoff(ctx: ManagerCheckContext): Pr
|
|
|
258
255
|
}> = [];
|
|
259
256
|
|
|
260
257
|
for (const [key, group] of grouped) {
|
|
261
|
-
const activePipelineCount = getActivePipelineCountForRequirement(
|
|
258
|
+
const activePipelineCount = await getActivePipelineCountForRequirement(
|
|
259
|
+
db.provider,
|
|
260
|
+
group.requirementId
|
|
261
|
+
);
|
|
262
262
|
const latestUpdateMs = getLatestStoryUpdateMs(group.stories);
|
|
263
263
|
groupsWithPipeline.push({
|
|
264
264
|
key,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Licensed under the Hungry Ghost Hive License. See LICENSE.
|
|
2
2
|
|
|
3
|
-
import type { Database } from 'sql.js';
|
|
4
3
|
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
4
|
+
import type { DatabaseProvider } from '../../../db/provider.js';
|
|
5
5
|
import { getApprovedPullRequests, updatePullRequest } from '../../../db/queries/pull-requests.js';
|
|
6
6
|
|
|
7
7
|
// Mock the functions we're testing with
|
|
@@ -30,12 +30,12 @@ describe('Auto-merge PRs', () => {
|
|
|
30
30
|
vi.clearAllMocks();
|
|
31
31
|
});
|
|
32
32
|
|
|
33
|
-
it('should return 0 when no approved PRs exist', () => {
|
|
33
|
+
it('should return 0 when no approved PRs exist', async () => {
|
|
34
34
|
// Mock empty approved PRs
|
|
35
|
-
vi.mocked(getApprovedPullRequests).
|
|
35
|
+
vi.mocked(getApprovedPullRequests).mockResolvedValue([]);
|
|
36
36
|
|
|
37
37
|
// This is a basic test to ensure the function handles empty PR lists
|
|
38
|
-
const approvedPRs = getApprovedPullRequests({} as
|
|
38
|
+
const approvedPRs = await getApprovedPullRequests({} as DatabaseProvider);
|
|
39
39
|
expect(approvedPRs).toEqual([]);
|
|
40
40
|
});
|
|
41
41
|
|
|
@@ -8,9 +8,8 @@ import { loadConfig } from '../../../config/loader.js';
|
|
|
8
8
|
import type { HiveConfig } from '../../../config/schema.js';
|
|
9
9
|
import { syncFromProvider } from '../../../connectors/project-management/operations.js';
|
|
10
10
|
import type { StoryRow } from '../../../db/client.js';
|
|
11
|
-
import { queryAll, queryOne, withTransaction } from '../../../db/client.js';
|
|
12
11
|
import { acquireLock } from '../../../db/lock.js';
|
|
13
|
-
import { getAgentById, getAllAgents } from '../../../db/queries/agents.js';
|
|
12
|
+
import { getAgentById, getAllAgents, type AgentRow } from '../../../db/queries/agents.js';
|
|
14
13
|
import { getPendingEscalations, updateEscalation } from '../../../db/queries/escalations.js';
|
|
15
14
|
import { createLog } from '../../../db/queries/logs.js';
|
|
16
15
|
import {
|
|
@@ -442,7 +441,7 @@ managerCommand
|
|
|
442
441
|
return;
|
|
443
442
|
}
|
|
444
443
|
}
|
|
445
|
-
const scheduler = new Scheduler(db.
|
|
444
|
+
const scheduler = new Scheduler(db.provider, {
|
|
446
445
|
scaling: config.scaling,
|
|
447
446
|
models: config.models,
|
|
448
447
|
qa: config.qa,
|
|
@@ -511,7 +510,7 @@ managerCommand
|
|
|
511
510
|
.option('-m, --message <msg>', 'Custom message to send')
|
|
512
511
|
.action(async (session: string, options: { message?: string }) => {
|
|
513
512
|
await withHiveContext(async ({ root, db }) => {
|
|
514
|
-
const agent = getAgentById(db.
|
|
513
|
+
const agent = await getAgentById(db.provider, session.replace('hive-', ''));
|
|
515
514
|
const cliTool = (agent?.cli_tool || 'claude') as CLITool;
|
|
516
515
|
await nudgeAgent(root, session, options.message, undefined, undefined, cliTool);
|
|
517
516
|
console.log(chalk.green(`Nudged ${session}`));
|
|
@@ -584,7 +583,7 @@ async function managerCheck(
|
|
|
584
583
|
fn: (db: import('../../../db/client.js').DatabaseClient, scheduler: Scheduler) => Promise<T> | T
|
|
585
584
|
): Promise<T> => {
|
|
586
585
|
return withHiveContext(async ({ db }) => {
|
|
587
|
-
const scheduler = new Scheduler(db.
|
|
586
|
+
const scheduler = new Scheduler(db.provider, {
|
|
588
587
|
scaling: resolvedConfig.scaling,
|
|
589
588
|
models: resolvedConfig.models,
|
|
590
589
|
qa: resolvedConfig.qa,
|
|
@@ -706,7 +705,7 @@ async function managerCheck(
|
|
|
706
705
|
|
|
707
706
|
async function backfillPRNumbers(ctx: ManagerCheckContext): Promise<void> {
|
|
708
707
|
await ctx.withDb(async db => {
|
|
709
|
-
const backfilled = backfillGithubPrNumbers(db.
|
|
708
|
+
const backfilled = await backfillGithubPrNumbers(db.provider);
|
|
710
709
|
verboseLogCtx(ctx, `backfillPRNumbers: backfilled=${backfilled}`);
|
|
711
710
|
if (backfilled > 0) {
|
|
712
711
|
console.log(chalk.yellow(` Backfilled ${backfilled} PR(s) with github_pr_number from URL`));
|
|
@@ -798,7 +797,7 @@ async function runAutoMerge(ctx: ManagerCheckContext): Promise<void> {
|
|
|
798
797
|
|
|
799
798
|
async function syncJiraStatuses(ctx: ManagerCheckContext): Promise<void> {
|
|
800
799
|
await ctx.withDb(async db => {
|
|
801
|
-
const syncedStories = await syncFromProvider(ctx.root, db.
|
|
800
|
+
const syncedStories = await syncFromProvider(ctx.root, db.provider);
|
|
802
801
|
verboseLogCtx(ctx, `syncJiraStatuses: synced=${syncedStories}`);
|
|
803
802
|
if (syncedStories > 0) {
|
|
804
803
|
ctx.counters.jiraSynced = syncedStories;
|
|
@@ -812,13 +811,13 @@ async function syncJiraStatuses(ctx: ManagerCheckContext): Promise<void> {
|
|
|
812
811
|
async function prepareSessionData(ctx: ManagerCheckContext): Promise<void> {
|
|
813
812
|
await ctx.withDb(async db => {
|
|
814
813
|
// Pre-populate escalation dedup set
|
|
815
|
-
const existingEscalations = getPendingEscalations(db.
|
|
814
|
+
const existingEscalations = await getPendingEscalations(db.provider);
|
|
816
815
|
ctx.escalatedSessions = new Set(
|
|
817
816
|
existingEscalations.filter(e => e.from_agent_id).map(e => e.from_agent_id)
|
|
818
817
|
);
|
|
819
818
|
|
|
820
819
|
// Batch fetch all agents and index by session name
|
|
821
|
-
const allAgents = getAllAgents(db.
|
|
820
|
+
const allAgents = await getAllAgents(db.provider);
|
|
822
821
|
const bySessionName = new Map<string, (typeof allAgents)[number]>();
|
|
823
822
|
for (const agent of allAgents) {
|
|
824
823
|
bySessionName.set(`hive-${agent.id}`, agent);
|
|
@@ -841,14 +840,14 @@ async function resolveStaleEscalations(ctx: ManagerCheckContext): Promise<void>
|
|
|
841
840
|
ctx.config.manager.nudge_cooldown_ms,
|
|
842
841
|
ctx.config.manager.stuck_threshold_ms
|
|
843
842
|
);
|
|
844
|
-
const pendingEscalations = getPendingEscalations(db.
|
|
843
|
+
const pendingEscalations = await getPendingEscalations(db.provider);
|
|
845
844
|
verboseLogCtx(
|
|
846
845
|
ctx,
|
|
847
846
|
`resolveStaleEscalations: pending=${pendingEscalations.length}, staleAfterMs=${staleAfterMs}`
|
|
848
847
|
);
|
|
849
848
|
if (pendingEscalations.length === 0) return;
|
|
850
849
|
|
|
851
|
-
const uniqueAgents = new Map<string,
|
|
850
|
+
const uniqueAgents = new Map<string, AgentRow>();
|
|
852
851
|
for (const agent of ctx.agentsBySessionName.values()) {
|
|
853
852
|
uniqueAgents.set(agent.id, agent);
|
|
854
853
|
}
|
|
@@ -864,40 +863,37 @@ async function resolveStaleEscalations(ctx: ManagerCheckContext): Promise<void>
|
|
|
864
863
|
if (staleEscalations.length === 0) return;
|
|
865
864
|
verboseLogCtx(ctx, `resolveStaleEscalations: stale=${staleEscalations.length}`);
|
|
866
865
|
|
|
867
|
-
withTransaction(
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
if (stale.escalation.from_agent_id) {
|
|
876
|
-
ctx.escalatedSessions.delete(stale.escalation.from_agent_id);
|
|
877
|
-
}
|
|
878
|
-
ctx.counters.escalationsResolved++;
|
|
879
|
-
createLog(db.db, {
|
|
880
|
-
agentId: 'manager',
|
|
881
|
-
storyId: stale.escalation.story_id || undefined,
|
|
882
|
-
eventType: 'ESCALATION_RESOLVED',
|
|
883
|
-
message: `Auto-resolved stale escalation ${stale.escalation.id}`,
|
|
884
|
-
metadata: {
|
|
885
|
-
escalation_id: stale.escalation.id,
|
|
886
|
-
from_agent_id: stale.escalation.from_agent_id,
|
|
887
|
-
reason: stale.reason,
|
|
888
|
-
},
|
|
889
|
-
});
|
|
866
|
+
await db.provider.withTransaction(async () => {
|
|
867
|
+
for (const stale of staleEscalations) {
|
|
868
|
+
await updateEscalation(db.provider, stale.escalation.id, {
|
|
869
|
+
status: 'resolved',
|
|
870
|
+
resolution: `Manager auto-resolved stale escalation: ${stale.reason}`,
|
|
871
|
+
});
|
|
872
|
+
if (stale.escalation.from_agent_id) {
|
|
873
|
+
ctx.escalatedSessions.delete(stale.escalation.from_agent_id);
|
|
890
874
|
}
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
875
|
+
ctx.counters.escalationsResolved++;
|
|
876
|
+
await createLog(db.provider, {
|
|
877
|
+
agentId: 'manager',
|
|
878
|
+
storyId: stale.escalation.story_id || undefined,
|
|
879
|
+
eventType: 'ESCALATION_RESOLVED',
|
|
880
|
+
message: `Auto-resolved stale escalation ${stale.escalation.id}`,
|
|
881
|
+
metadata: {
|
|
882
|
+
escalation_id: stale.escalation.id,
|
|
883
|
+
from_agent_id: stale.escalation.from_agent_id,
|
|
884
|
+
reason: stale.reason,
|
|
885
|
+
},
|
|
886
|
+
});
|
|
887
|
+
}
|
|
888
|
+
});
|
|
889
|
+
db.save();
|
|
894
890
|
console.log(chalk.yellow(` Auto-cleared ${staleEscalations.length} stale escalation(s)`));
|
|
895
891
|
});
|
|
896
892
|
}
|
|
897
893
|
|
|
898
894
|
async function resolveOrphanedSessionEscalations(ctx: ManagerCheckContext): Promise<void> {
|
|
899
895
|
const resolvedCount = await ctx.withDb(async db => {
|
|
900
|
-
const pendingEscalations = getPendingEscalations(db.
|
|
896
|
+
const pendingEscalations = await getPendingEscalations(db.provider);
|
|
901
897
|
verboseLogCtx(ctx, `resolveOrphanedSessionEscalations: pending=${pendingEscalations.length}`);
|
|
902
898
|
if (pendingEscalations.length === 0) {
|
|
903
899
|
return 0;
|
|
@@ -905,7 +901,7 @@ async function resolveOrphanedSessionEscalations(ctx: ManagerCheckContext): Prom
|
|
|
905
901
|
|
|
906
902
|
const activeSessionNames = new Set(ctx.hiveSessions.map(session => session.name));
|
|
907
903
|
const agentStatusBySessionName = new Map<string, string>();
|
|
908
|
-
for (const agent of getAllAgents(db.
|
|
904
|
+
for (const agent of await getAllAgents(db.provider)) {
|
|
909
905
|
if (agent.tmux_session) {
|
|
910
906
|
agentStatusBySessionName.set(agent.tmux_session, agent.status);
|
|
911
907
|
}
|
|
@@ -924,11 +920,11 @@ async function resolveOrphanedSessionEscalations(ctx: ManagerCheckContext): Prom
|
|
|
924
920
|
continue;
|
|
925
921
|
}
|
|
926
922
|
|
|
927
|
-
updateEscalation(db.
|
|
923
|
+
await updateEscalation(db.provider, escalation.id, {
|
|
928
924
|
status: 'resolved',
|
|
929
925
|
resolution: `Manager auto-resolved stale escalation from inactive session ${fromSession}`,
|
|
930
926
|
});
|
|
931
|
-
createLog(db.
|
|
927
|
+
await createLog(db.provider, {
|
|
932
928
|
agentId: 'manager',
|
|
933
929
|
storyId: escalation.story_id || undefined,
|
|
934
930
|
eventType: 'ESCALATION_RESOLVED',
|
|
@@ -959,7 +955,7 @@ async function resolveOrphanedSessionEscalations(ctx: ManagerCheckContext): Prom
|
|
|
959
955
|
|
|
960
956
|
async function scanAgentSessions(ctx: ManagerCheckContext): Promise<void> {
|
|
961
957
|
// Phase 1: Batch fetch pending messages (brief lock)
|
|
962
|
-
const allPendingMessages = await ctx.withDb(async db => getAllPendingMessages(db.
|
|
958
|
+
const allPendingMessages = await ctx.withDb(async db => getAllPendingMessages(db.provider));
|
|
963
959
|
const messagesBySessionName = new Map<string, MessageRow[]>();
|
|
964
960
|
const activeSessionNames = new Set<string>();
|
|
965
961
|
const maxStuckNudgesPerStory = getMaxStuckNudgesPerStory(ctx.config);
|
|
@@ -1080,7 +1076,7 @@ async function scanAgentSessions(ctx: ManagerCheckContext): Promise<void> {
|
|
|
1080
1076
|
verboseLogCtx(ctx, `Agent ${session.name}: full-ai skipped (no current story)`);
|
|
1081
1077
|
} else {
|
|
1082
1078
|
// Brief lock for story lookup
|
|
1083
|
-
const story = await ctx.withDb(async db => getStoryById(db.
|
|
1079
|
+
const story = await ctx.withDb(async db => getStoryById(db.provider, storyId));
|
|
1084
1080
|
if (!story || ['merged', 'completed'].includes(story.status)) {
|
|
1085
1081
|
verboseLogCtx(
|
|
1086
1082
|
ctx,
|
|
@@ -1181,7 +1177,7 @@ async function scanAgentSessions(ctx: ManagerCheckContext): Promise<void> {
|
|
|
1181
1177
|
}
|
|
1182
1178
|
// Brief lock for log write
|
|
1183
1179
|
await ctx.withDb(async db => {
|
|
1184
|
-
createLog(db.
|
|
1180
|
+
createLog(db.provider, {
|
|
1185
1181
|
agentId: 'manager',
|
|
1186
1182
|
storyId,
|
|
1187
1183
|
eventType: 'STORY_PROGRESS_UPDATE',
|
|
@@ -1222,7 +1218,7 @@ async function batchMarkMessagesRead(ctx: ManagerCheckContext): Promise<void> {
|
|
|
1222
1218
|
verboseLogCtx(ctx, `batchMarkMessagesRead: count=${ctx.messagesToMarkRead.length}`);
|
|
1223
1219
|
if (ctx.messagesToMarkRead.length > 0) {
|
|
1224
1220
|
await ctx.withDb(async db => {
|
|
1225
|
-
markMessagesRead(db.
|
|
1221
|
+
markMessagesRead(db.provider, ctx.messagesToMarkRead);
|
|
1226
1222
|
db.save();
|
|
1227
1223
|
});
|
|
1228
1224
|
}
|
|
@@ -1237,8 +1233,7 @@ async function batchMarkMessagesRead(ctx: ManagerCheckContext): Promise<void> {
|
|
|
1237
1233
|
async function notifyUnassignedStories(ctx: ManagerCheckContext): Promise<void> {
|
|
1238
1234
|
// Phase 1: Read planned unassigned stories (brief lock)
|
|
1239
1235
|
const plannedCount = await ctx.withDb(async db => {
|
|
1240
|
-
const plannedStories = queryAll<StoryRow>(
|
|
1241
|
-
db.db,
|
|
1236
|
+
const plannedStories = await db.provider.queryAll<StoryRow>(
|
|
1242
1237
|
"SELECT * FROM stories WHERE status = 'planned' AND assigned_agent_id IS NULL"
|
|
1243
1238
|
);
|
|
1244
1239
|
return plannedStories.length;
|
|
@@ -1334,24 +1329,28 @@ async function printSummary(ctx: ManagerCheckContext): Promise<void> {
|
|
|
1334
1329
|
|
|
1335
1330
|
const noActionSnapshot = await ctx.withDb(async db => {
|
|
1336
1331
|
const pendingEscalations =
|
|
1337
|
-
|
|
1338
|
-
db.
|
|
1339
|
-
|
|
1332
|
+
(
|
|
1333
|
+
await db.provider.queryOne<{ count: number }>(
|
|
1334
|
+
"SELECT COUNT(*) AS count FROM escalations WHERE status = 'pending'"
|
|
1335
|
+
)
|
|
1340
1336
|
)?.count ?? 0;
|
|
1341
1337
|
const pendingActionableStories =
|
|
1342
|
-
|
|
1343
|
-
db.
|
|
1344
|
-
|
|
1338
|
+
(
|
|
1339
|
+
await db.provider.queryOne<{ count: number }>(
|
|
1340
|
+
"SELECT COUNT(*) AS count FROM stories WHERE status IN ('planned', 'in_progress', 'review', 'qa', 'qa_failed', 'pr_submitted')"
|
|
1341
|
+
)
|
|
1345
1342
|
)?.count ?? 0;
|
|
1346
1343
|
const activeWorkerAgents =
|
|
1347
|
-
|
|
1348
|
-
db.
|
|
1349
|
-
|
|
1344
|
+
(
|
|
1345
|
+
await db.provider.queryOne<{ count: number }>(
|
|
1346
|
+
"SELECT COUNT(*) AS count FROM agents WHERE type != 'tech_lead' AND status != 'terminated'"
|
|
1347
|
+
)
|
|
1350
1348
|
)?.count ?? 0;
|
|
1351
1349
|
const workingWorkerAgents =
|
|
1352
|
-
|
|
1353
|
-
db.
|
|
1354
|
-
|
|
1350
|
+
(
|
|
1351
|
+
await db.provider.queryOne<{ count: number }>(
|
|
1352
|
+
"SELECT COUNT(*) AS count FROM agents WHERE type != 'tech_lead' AND status = 'working'"
|
|
1353
|
+
)
|
|
1355
1354
|
)?.count ?? 0;
|
|
1356
1355
|
|
|
1357
1356
|
return {
|
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
import { describe, expect, it } from 'vitest';
|
|
4
4
|
import { run } from '../../../db/client.js';
|
|
5
|
+
import { SqliteProvider } from '../../../db/provider.js';
|
|
5
6
|
import { createAgent, getAgentById, updateAgent } from '../../../db/queries/agents.js';
|
|
6
7
|
import { createTestDatabase } from '../../../db/queries/test-helpers.js';
|
|
7
8
|
import { cleanupAgentsReferencingMergedStory } from './merged-story-cleanup.js';
|
|
8
9
|
|
|
9
10
|
function insertStoryRow(
|
|
10
|
-
db:
|
|
11
|
+
db: SqliteProvider,
|
|
11
12
|
input: {
|
|
12
13
|
id: string;
|
|
13
14
|
status: string;
|
|
@@ -16,7 +17,7 @@ function insertStoryRow(
|
|
|
16
17
|
): void {
|
|
17
18
|
const now = new Date().toISOString();
|
|
18
19
|
run(
|
|
19
|
-
db,
|
|
20
|
+
db.db,
|
|
20
21
|
`
|
|
21
22
|
INSERT INTO stories (id, title, description, status, assigned_agent_id, created_at, updated_at)
|
|
22
23
|
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
@@ -35,15 +36,22 @@ function insertStoryRow(
|
|
|
35
36
|
|
|
36
37
|
describe('cleanupAgentsReferencingMergedStory', () => {
|
|
37
38
|
it('clears stale merged-story pointers and reassigns to another active assigned story', async () => {
|
|
38
|
-
const
|
|
39
|
+
const rawDb = await createTestDatabase();
|
|
40
|
+
const db = new SqliteProvider(rawDb);
|
|
39
41
|
|
|
40
|
-
const seniorA = createAgent(db, { type: 'senior', tmuxSession: 'hive-senior-a' });
|
|
41
|
-
const seniorB = createAgent(db, { type: 'senior', tmuxSession: 'hive-senior-b' });
|
|
42
|
-
const seniorTerminated = createAgent(db, {
|
|
42
|
+
const seniorA = await createAgent(db, { type: 'senior', tmuxSession: 'hive-senior-a' });
|
|
43
|
+
const seniorB = await createAgent(db, { type: 'senior', tmuxSession: 'hive-senior-b' });
|
|
44
|
+
const seniorTerminated = await createAgent(db, {
|
|
45
|
+
type: 'senior',
|
|
46
|
+
tmuxSession: 'hive-senior-c',
|
|
47
|
+
});
|
|
43
48
|
|
|
44
|
-
updateAgent(db, seniorA.id, { status: 'working', currentStoryId: 'STORY-MERGED' });
|
|
45
|
-
updateAgent(db, seniorB.id, { status: 'working', currentStoryId: 'STORY-MERGED' });
|
|
46
|
-
updateAgent(db, seniorTerminated.id, {
|
|
49
|
+
await updateAgent(db, seniorA.id, { status: 'working', currentStoryId: 'STORY-MERGED' });
|
|
50
|
+
await updateAgent(db, seniorB.id, { status: 'working', currentStoryId: 'STORY-MERGED' });
|
|
51
|
+
await updateAgent(db, seniorTerminated.id, {
|
|
52
|
+
status: 'terminated',
|
|
53
|
+
currentStoryId: 'STORY-MERGED',
|
|
54
|
+
});
|
|
47
55
|
|
|
48
56
|
insertStoryRow(db, { id: 'STORY-MERGED', status: 'merged' });
|
|
49
57
|
insertStoryRow(db, {
|
|
@@ -57,25 +65,26 @@ describe('cleanupAgentsReferencingMergedStory', () => {
|
|
|
57
65
|
assignedAgentId: seniorA.id,
|
|
58
66
|
});
|
|
59
67
|
|
|
60
|
-
const result = cleanupAgentsReferencingMergedStory(db, 'STORY-MERGED');
|
|
68
|
+
const result = await cleanupAgentsReferencingMergedStory(db, 'STORY-MERGED');
|
|
61
69
|
|
|
62
70
|
expect(result).toEqual({ cleared: 2, reassigned: 1 });
|
|
63
|
-
expect(getAgentById(db, seniorA.id)?.current_story_id).toBe('STORY-REVIEW');
|
|
64
|
-
expect(getAgentById(db, seniorA.id)?.status).toBe('working');
|
|
65
|
-
expect(getAgentById(db, seniorB.id)?.current_story_id).toBeNull();
|
|
66
|
-
expect(getAgentById(db, seniorB.id)?.status).toBe('idle');
|
|
67
|
-
expect(getAgentById(db, seniorTerminated.id)?.current_story_id).toBe('STORY-MERGED');
|
|
71
|
+
expect((await getAgentById(db, seniorA.id))?.current_story_id).toBe('STORY-REVIEW');
|
|
72
|
+
expect((await getAgentById(db, seniorA.id))?.status).toBe('working');
|
|
73
|
+
expect((await getAgentById(db, seniorB.id))?.current_story_id).toBeNull();
|
|
74
|
+
expect((await getAgentById(db, seniorB.id))?.status).toBe('idle');
|
|
75
|
+
expect((await getAgentById(db, seniorTerminated.id))?.current_story_id).toBe('STORY-MERGED');
|
|
68
76
|
|
|
69
|
-
db.close();
|
|
77
|
+
await db.close();
|
|
70
78
|
});
|
|
71
79
|
|
|
72
80
|
it('is a no-op when no non-terminated agent references the merged story', async () => {
|
|
73
|
-
const
|
|
81
|
+
const rawDb = await createTestDatabase();
|
|
82
|
+
const db = new SqliteProvider(rawDb);
|
|
74
83
|
insertStoryRow(db, { id: 'STORY-MERGED', status: 'merged' });
|
|
75
84
|
|
|
76
|
-
const result = cleanupAgentsReferencingMergedStory(db, 'STORY-MERGED');
|
|
85
|
+
const result = await cleanupAgentsReferencingMergedStory(db, 'STORY-MERGED');
|
|
77
86
|
|
|
78
87
|
expect(result).toEqual({ cleared: 0, reassigned: 0 });
|
|
79
|
-
db.close();
|
|
88
|
+
await db.close();
|
|
80
89
|
});
|
|
81
90
|
});
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// Licensed under the Hungry Ghost Hive License. See LICENSE.
|
|
2
2
|
|
|
3
|
-
import type {
|
|
4
|
-
import { queryAll, queryOne } from '../../../db/client.js';
|
|
3
|
+
import type { DatabaseProvider } from '../../../db/provider.js';
|
|
5
4
|
import { updateAgent } from '../../../db/queries/agents.js';
|
|
6
5
|
|
|
7
6
|
const ACTIVE_STORY_STATUS_ORDER: ReadonlyArray<{
|
|
@@ -24,14 +23,13 @@ function buildActiveStatusPriorityCase(): string {
|
|
|
24
23
|
return `CASE status ${clauses} ELSE 99 END`;
|
|
25
24
|
}
|
|
26
25
|
|
|
27
|
-
function getNextAssignedActiveStoryId(
|
|
28
|
-
db:
|
|
26
|
+
async function getNextAssignedActiveStoryId(
|
|
27
|
+
db: DatabaseProvider,
|
|
29
28
|
agentId: string,
|
|
30
29
|
mergedStoryId: string
|
|
31
|
-
): string | null {
|
|
30
|
+
): Promise<string | null> {
|
|
32
31
|
const statusPriorityCase = buildActiveStatusPriorityCase();
|
|
33
|
-
const row = queryOne<{ id: string }>(
|
|
34
|
-
db,
|
|
32
|
+
const row = await db.queryOne<{ id: string }>(
|
|
35
33
|
`
|
|
36
34
|
SELECT id
|
|
37
35
|
FROM stories
|
|
@@ -51,12 +49,11 @@ export interface MergedStoryCleanupResult {
|
|
|
51
49
|
reassigned: number;
|
|
52
50
|
}
|
|
53
51
|
|
|
54
|
-
export function cleanupAgentsReferencingMergedStory(
|
|
55
|
-
db:
|
|
52
|
+
export async function cleanupAgentsReferencingMergedStory(
|
|
53
|
+
db: DatabaseProvider,
|
|
56
54
|
mergedStoryId: string
|
|
57
|
-
): MergedStoryCleanupResult {
|
|
58
|
-
const staleAgents = queryAll<{ id: string }>(
|
|
59
|
-
db,
|
|
55
|
+
): Promise<MergedStoryCleanupResult> {
|
|
56
|
+
const staleAgents = await db.queryAll<{ id: string }>(
|
|
60
57
|
`
|
|
61
58
|
SELECT id
|
|
62
59
|
FROM agents
|
|
@@ -70,8 +67,8 @@ export function cleanupAgentsReferencingMergedStory(
|
|
|
70
67
|
let reassigned = 0;
|
|
71
68
|
|
|
72
69
|
for (const agent of staleAgents) {
|
|
73
|
-
const nextStoryId = getNextAssignedActiveStoryId(db, agent.id, mergedStoryId);
|
|
74
|
-
updateAgent(db, agent.id, {
|
|
70
|
+
const nextStoryId = await getNextAssignedActiveStoryId(db, agent.id, mergedStoryId);
|
|
71
|
+
await updateAgent(db, agent.id, {
|
|
75
72
|
currentStoryId: nextStoryId,
|
|
76
73
|
status: nextStoryId ? 'working' : 'idle',
|
|
77
74
|
});
|