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
package/src/agents/base-agent.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Licensed under the Hungry Ghost Hive License. See LICENSE.
|
|
2
2
|
|
|
3
|
-
import type {
|
|
3
|
+
import type { DatabaseProvider } from '../db/provider.js';
|
|
4
4
|
import {
|
|
5
5
|
updateAgent,
|
|
6
6
|
type AgentRow,
|
|
@@ -32,7 +32,7 @@ export interface MemoryState {
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
export interface AgentContext {
|
|
35
|
-
db:
|
|
35
|
+
db: DatabaseProvider;
|
|
36
36
|
provider: LLMProvider;
|
|
37
37
|
agentRow: AgentRow;
|
|
38
38
|
workDir: string;
|
|
@@ -46,7 +46,7 @@ export interface AgentContext {
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
export abstract class BaseAgent {
|
|
49
|
-
protected db:
|
|
49
|
+
protected db: DatabaseProvider;
|
|
50
50
|
protected provider: LLMProvider;
|
|
51
51
|
protected agentId: string;
|
|
52
52
|
protected agentType: AgentType;
|
|
@@ -112,9 +112,9 @@ export abstract class BaseAgent {
|
|
|
112
112
|
}, HEARTBEAT_INTERVAL_MS);
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
private sendHeartbeat(): void {
|
|
115
|
+
private async sendHeartbeat(): Promise<void> {
|
|
116
116
|
try {
|
|
117
|
-
updateAgentHeartbeat(this.db, this.agentId);
|
|
117
|
+
await updateAgentHeartbeat(this.db, this.agentId);
|
|
118
118
|
} catch (err) {
|
|
119
119
|
// Heartbeat failure shouldn't crash the agent
|
|
120
120
|
console.error(`Heartbeat failed for ${this.agentId}:`, err);
|
|
@@ -128,8 +128,12 @@ export abstract class BaseAgent {
|
|
|
128
128
|
}
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
-
protected log(
|
|
132
|
-
|
|
131
|
+
protected async log(
|
|
132
|
+
eventType: EventType,
|
|
133
|
+
message?: string,
|
|
134
|
+
metadata?: Record<string, unknown>
|
|
135
|
+
): Promise<void> {
|
|
136
|
+
await createLog(this.db, {
|
|
133
137
|
agentId: this.agentId,
|
|
134
138
|
storyId: this.memoryState.currentTask?.storyId,
|
|
135
139
|
eventType,
|
|
@@ -138,13 +142,13 @@ export abstract class BaseAgent {
|
|
|
138
142
|
});
|
|
139
143
|
}
|
|
140
144
|
|
|
141
|
-
protected updateStatus(status: AgentStatus): void {
|
|
142
|
-
updateAgent(this.db, this.agentId, { status });
|
|
145
|
+
protected async updateStatus(status: AgentStatus): Promise<void> {
|
|
146
|
+
await updateAgent(this.db, this.agentId, { status });
|
|
143
147
|
}
|
|
144
148
|
|
|
145
|
-
protected saveMemoryState(): void {
|
|
149
|
+
protected async saveMemoryState(): Promise<void> {
|
|
146
150
|
this.memoryState.checkpointTokens = this.totalTokens;
|
|
147
|
-
updateAgent(this.db, this.agentId, {
|
|
151
|
+
await updateAgent(this.db, this.agentId, {
|
|
148
152
|
memoryState: JSON.stringify(this.memoryState),
|
|
149
153
|
});
|
|
150
154
|
}
|
|
@@ -169,7 +173,7 @@ export abstract class BaseAgent {
|
|
|
169
173
|
return result.content;
|
|
170
174
|
} catch (err) {
|
|
171
175
|
// Log timeout/error event
|
|
172
|
-
this.log(
|
|
176
|
+
await this.log(
|
|
173
177
|
'AGENT_TERMINATED',
|
|
174
178
|
`LLM call failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
175
179
|
{
|
|
@@ -195,9 +199,9 @@ Keep it under 500 words.`;
|
|
|
195
199
|
const summaryResult = await this.provider.complete(this.messages);
|
|
196
200
|
|
|
197
201
|
this.memoryState.conversationSummary = summaryResult.content;
|
|
198
|
-
this.saveMemoryState();
|
|
202
|
+
await this.saveMemoryState();
|
|
199
203
|
|
|
200
|
-
this.log('AGENT_CHECKPOINT', 'Checkpoint saved', {
|
|
204
|
+
await this.log('AGENT_CHECKPOINT', 'Checkpoint saved', {
|
|
201
205
|
totalTokens: this.totalTokens,
|
|
202
206
|
});
|
|
203
207
|
|
|
@@ -212,52 +216,52 @@ Keep it under 500 words.`;
|
|
|
212
216
|
this.totalTokens = 0;
|
|
213
217
|
}
|
|
214
218
|
|
|
215
|
-
protected addDecision(decision: string): void {
|
|
219
|
+
protected async addDecision(decision: string): Promise<void> {
|
|
216
220
|
this.memoryState.context.decisionsMade.push(decision);
|
|
217
|
-
this.saveMemoryState();
|
|
221
|
+
await this.saveMemoryState();
|
|
218
222
|
}
|
|
219
223
|
|
|
220
|
-
protected addBlocker(blocker: string): void {
|
|
224
|
+
protected async addBlocker(blocker: string): Promise<void> {
|
|
221
225
|
this.memoryState.context.blockers.push(blocker);
|
|
222
|
-
this.saveMemoryState();
|
|
226
|
+
await this.saveMemoryState();
|
|
223
227
|
}
|
|
224
228
|
|
|
225
|
-
protected removeBlocker(blocker: string): void {
|
|
229
|
+
protected async removeBlocker(blocker: string): Promise<void> {
|
|
226
230
|
this.memoryState.context.blockers = this.memoryState.context.blockers.filter(
|
|
227
231
|
b => b !== blocker
|
|
228
232
|
);
|
|
229
|
-
this.saveMemoryState();
|
|
233
|
+
await this.saveMemoryState();
|
|
230
234
|
}
|
|
231
235
|
|
|
232
|
-
protected setCurrentTask(storyId: string, phase: string): void {
|
|
236
|
+
protected async setCurrentTask(storyId: string, phase: string): Promise<void> {
|
|
233
237
|
this.memoryState.currentTask = {
|
|
234
238
|
storyId,
|
|
235
239
|
phase,
|
|
236
240
|
filesModified: [],
|
|
237
241
|
lastAction: '',
|
|
238
242
|
};
|
|
239
|
-
this.saveMemoryState();
|
|
243
|
+
await this.saveMemoryState();
|
|
240
244
|
}
|
|
241
245
|
|
|
242
|
-
protected updateTaskProgress(lastAction: string, filesModified?: string[]): void {
|
|
246
|
+
protected async updateTaskProgress(lastAction: string, filesModified?: string[]): Promise<void> {
|
|
243
247
|
if (this.memoryState.currentTask) {
|
|
244
248
|
this.memoryState.currentTask.lastAction = lastAction;
|
|
245
249
|
if (filesModified) {
|
|
246
250
|
this.memoryState.currentTask.filesModified.push(...filesModified);
|
|
247
251
|
}
|
|
248
|
-
this.saveMemoryState();
|
|
252
|
+
await this.saveMemoryState();
|
|
249
253
|
}
|
|
250
254
|
}
|
|
251
255
|
|
|
252
256
|
async run(): Promise<void> {
|
|
253
|
-
this.updateStatus('working');
|
|
254
|
-
this.log('AGENT_SPAWNED', `${this.agentType} agent started`);
|
|
257
|
+
await this.updateStatus('working');
|
|
258
|
+
await this.log('AGENT_SPAWNED', `${this.agentType} agent started`);
|
|
255
259
|
|
|
256
260
|
try {
|
|
257
261
|
await this.execute();
|
|
258
262
|
} catch (err) {
|
|
259
|
-
this.updateStatus('blocked');
|
|
260
|
-
this.log(
|
|
263
|
+
await this.updateStatus('blocked');
|
|
264
|
+
await this.log(
|
|
261
265
|
'AGENT_TERMINATED',
|
|
262
266
|
`Error: ${err instanceof Error ? err.message : 'Unknown error'}`,
|
|
263
267
|
{
|
|
@@ -17,16 +17,25 @@ export class IntermediateAgent extends BaseAgent {
|
|
|
17
17
|
|
|
18
18
|
constructor(context: IntermediateContext) {
|
|
19
19
|
super(context);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
private async init(context: IntermediateContext): Promise<void> {
|
|
20
23
|
if (context.agentRow.team_id) {
|
|
21
|
-
this.team = getTeamById(this.db, context.agentRow.team_id) || null;
|
|
24
|
+
this.team = (await getTeamById(this.db, context.agentRow.team_id)) || null;
|
|
22
25
|
}
|
|
23
26
|
if (context.storyId) {
|
|
24
|
-
this.story = getStoryById(this.db, context.storyId) || null;
|
|
27
|
+
this.story = (await getStoryById(this.db, context.storyId)) || null;
|
|
25
28
|
} else if (context.agentRow.current_story_id) {
|
|
26
|
-
this.story = getStoryById(this.db, context.agentRow.current_story_id) || null;
|
|
29
|
+
this.story = (await getStoryById(this.db, context.agentRow.current_story_id)) || null;
|
|
27
30
|
}
|
|
28
31
|
}
|
|
29
32
|
|
|
33
|
+
static async create(context: IntermediateContext): Promise<IntermediateAgent> {
|
|
34
|
+
const agent = new IntermediateAgent(context);
|
|
35
|
+
await agent.init(context);
|
|
36
|
+
return agent;
|
|
37
|
+
}
|
|
38
|
+
|
|
30
39
|
getSystemPrompt(): string {
|
|
31
40
|
const teamInfo = this.team
|
|
32
41
|
? `Team: ${this.team.name}\nRepository: ${this.team.repo_path}`
|
|
@@ -65,12 +74,12 @@ ${this.memoryState.conversationSummary || 'Starting fresh.'}`;
|
|
|
65
74
|
|
|
66
75
|
async execute(): Promise<void> {
|
|
67
76
|
if (!this.story) {
|
|
68
|
-
this.log('STORY_PROGRESS_UPDATE', 'No story assigned, waiting');
|
|
77
|
+
await this.log('STORY_PROGRESS_UPDATE', 'No story assigned, waiting');
|
|
69
78
|
return;
|
|
70
79
|
}
|
|
71
80
|
|
|
72
|
-
this.setCurrentTask(this.story.id, 'implementation');
|
|
73
|
-
this.log('STORY_STARTED', `Working on: ${this.story.title}`, { storyId: this.story.id });
|
|
81
|
+
await this.setCurrentTask(this.story.id, 'implementation');
|
|
82
|
+
await this.log('STORY_STARTED', `Working on: ${this.story.title}`, { storyId: this.story.id });
|
|
74
83
|
|
|
75
84
|
try {
|
|
76
85
|
await this.implementStory();
|
|
@@ -81,7 +90,7 @@ ${this.memoryState.conversationSummary || 'Starting fresh.'}`;
|
|
|
81
90
|
`Failed after ${this.retryCount} attempts: ${err instanceof Error ? err.message : 'Unknown error'}`
|
|
82
91
|
);
|
|
83
92
|
} else {
|
|
84
|
-
this.log(
|
|
93
|
+
await this.log(
|
|
85
94
|
'STORY_PROGRESS_UPDATE',
|
|
86
95
|
`Retry ${this.retryCount}: ${err instanceof Error ? err.message : 'Unknown error'}`,
|
|
87
96
|
{
|
|
@@ -106,7 +115,7 @@ ${this.memoryState.conversationSummary || 'Starting fresh.'}`;
|
|
|
106
115
|
|
|
107
116
|
// Update story with branch name if not set
|
|
108
117
|
if (!this.story.branch_name) {
|
|
109
|
-
updateStory(this.db, this.story.id, { branchName }, this.storiesDir);
|
|
118
|
+
await updateStory(this.db, this.story.id, { branchName }, this.storiesDir);
|
|
110
119
|
}
|
|
111
120
|
|
|
112
121
|
const prompt = `Implement this story:
|
|
@@ -134,18 +143,18 @@ ${this.story.acceptance_criteria ? JSON.parse(this.story.acceptance_criteria).jo
|
|
|
134
143
|
Begin implementation.`;
|
|
135
144
|
|
|
136
145
|
const response = await this.chat(prompt);
|
|
137
|
-
this.updateTaskProgress('Implementation in progress', []);
|
|
138
|
-
this.log('STORY_PROGRESS_UPDATE', response.substring(0, 200), { storyId: this.story.id });
|
|
146
|
+
await this.updateTaskProgress('Implementation in progress', []);
|
|
147
|
+
await this.log('STORY_PROGRESS_UPDATE', response.substring(0, 200), { storyId: this.story.id });
|
|
139
148
|
|
|
140
149
|
// Continue implementation (simplified - in reality this would be iterative)
|
|
141
150
|
const continuePrompt =
|
|
142
151
|
'Continue with the implementation. Show me the code changes you would make.';
|
|
143
152
|
await this.chat(continuePrompt);
|
|
144
|
-
this.log('STORY_PROGRESS_UPDATE', 'Code changes proposed', { storyId: this.story.id });
|
|
153
|
+
await this.log('STORY_PROGRESS_UPDATE', 'Code changes proposed', { storyId: this.story.id });
|
|
145
154
|
|
|
146
155
|
// Mark as complete
|
|
147
|
-
updateStory(this.db, this.story.id, { status: 'review' }, this.storiesDir);
|
|
148
|
-
this.log('STORY_COMPLETED', 'Implementation complete, ready for review', {
|
|
156
|
+
await updateStory(this.db, this.story.id, { status: 'review' }, this.storiesDir);
|
|
157
|
+
await this.log('STORY_COMPLETED', 'Implementation complete, ready for review', {
|
|
149
158
|
storyId: this.story.id,
|
|
150
159
|
branchName,
|
|
151
160
|
});
|
|
@@ -153,25 +162,25 @@ Begin implementation.`;
|
|
|
153
162
|
|
|
154
163
|
private async escalateToSenior(reason: string): Promise<void> {
|
|
155
164
|
// Find Senior for this team
|
|
156
|
-
const seniors = getAgentsByTeam(this.db, this.teamId!).filter(
|
|
165
|
+
const seniors = (await getAgentsByTeam(this.db, this.teamId!)).filter(
|
|
157
166
|
a => a.type === 'senior' && a.status !== 'terminated'
|
|
158
167
|
);
|
|
159
168
|
|
|
160
169
|
const seniorId = seniors[0]?.id;
|
|
161
170
|
|
|
162
|
-
const escalation = createEscalation(this.db, {
|
|
171
|
+
const escalation = await createEscalation(this.db, {
|
|
163
172
|
storyId: this.story?.id,
|
|
164
173
|
fromAgentId: this.agentId,
|
|
165
174
|
toAgentId: seniorId,
|
|
166
175
|
reason,
|
|
167
176
|
});
|
|
168
177
|
|
|
169
|
-
this.log('ESCALATION_CREATED', reason, {
|
|
178
|
+
await this.log('ESCALATION_CREATED', reason, {
|
|
170
179
|
escalationId: escalation.id,
|
|
171
180
|
toAgent: seniorId,
|
|
172
181
|
});
|
|
173
182
|
|
|
174
|
-
this.updateStatus('blocked');
|
|
175
|
-
this.addBlocker(`Escalated to Senior: ${reason}`);
|
|
183
|
+
await this.updateStatus('blocked');
|
|
184
|
+
await this.addBlocker(`Escalated to Senior: ${reason}`);
|
|
176
185
|
}
|
|
177
186
|
}
|
package/src/agents/junior.ts
CHANGED
|
@@ -17,16 +17,25 @@ export class JuniorAgent extends BaseAgent {
|
|
|
17
17
|
|
|
18
18
|
constructor(context: JuniorContext) {
|
|
19
19
|
super(context);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
private async init(context: JuniorContext): Promise<void> {
|
|
20
23
|
if (context.agentRow.team_id) {
|
|
21
|
-
this.team = getTeamById(this.db, context.agentRow.team_id) || null;
|
|
24
|
+
this.team = (await getTeamById(this.db, context.agentRow.team_id)) || null;
|
|
22
25
|
}
|
|
23
26
|
if (context.storyId) {
|
|
24
|
-
this.story = getStoryById(this.db, context.storyId) || null;
|
|
27
|
+
this.story = (await getStoryById(this.db, context.storyId)) || null;
|
|
25
28
|
} else if (context.agentRow.current_story_id) {
|
|
26
|
-
this.story = getStoryById(this.db, context.agentRow.current_story_id) || null;
|
|
29
|
+
this.story = (await getStoryById(this.db, context.agentRow.current_story_id)) || null;
|
|
27
30
|
}
|
|
28
31
|
}
|
|
29
32
|
|
|
33
|
+
static async create(context: JuniorContext): Promise<JuniorAgent> {
|
|
34
|
+
const agent = new JuniorAgent(context);
|
|
35
|
+
await agent.init(context);
|
|
36
|
+
return agent;
|
|
37
|
+
}
|
|
38
|
+
|
|
30
39
|
getSystemPrompt(): string {
|
|
31
40
|
const teamInfo = this.team
|
|
32
41
|
? `Team: ${this.team.name}\nRepository: ${this.team.repo_path}`
|
|
@@ -71,12 +80,12 @@ ${this.memoryState.conversationSummary || 'Starting fresh.'}`;
|
|
|
71
80
|
|
|
72
81
|
async execute(): Promise<void> {
|
|
73
82
|
if (!this.story) {
|
|
74
|
-
this.log('STORY_PROGRESS_UPDATE', 'No story assigned, waiting');
|
|
83
|
+
await this.log('STORY_PROGRESS_UPDATE', 'No story assigned, waiting');
|
|
75
84
|
return;
|
|
76
85
|
}
|
|
77
86
|
|
|
78
|
-
this.setCurrentTask(this.story.id, 'implementation');
|
|
79
|
-
this.log('STORY_STARTED', `Working on: ${this.story.title}`, { storyId: this.story.id });
|
|
87
|
+
await this.setCurrentTask(this.story.id, 'implementation');
|
|
88
|
+
await this.log('STORY_STARTED', `Working on: ${this.story.title}`, { storyId: this.story.id });
|
|
80
89
|
|
|
81
90
|
try {
|
|
82
91
|
await this.implementStory();
|
|
@@ -88,7 +97,7 @@ ${this.memoryState.conversationSummary || 'Starting fresh.'}`;
|
|
|
88
97
|
`Encountered error: ${err instanceof Error ? err.message : 'Unknown error'}`
|
|
89
98
|
);
|
|
90
99
|
} else {
|
|
91
|
-
this.log(
|
|
100
|
+
await this.log(
|
|
92
101
|
'STORY_PROGRESS_UPDATE',
|
|
93
102
|
`Error: ${err instanceof Error ? err.message : 'Unknown error'}`,
|
|
94
103
|
{
|
|
@@ -111,7 +120,7 @@ ${this.memoryState.conversationSummary || 'Starting fresh.'}`;
|
|
|
111
120
|
.substring(0, 30)}`;
|
|
112
121
|
|
|
113
122
|
if (!this.story.branch_name) {
|
|
114
|
-
updateStory(this.db, this.story.id, { branchName }, this.storiesDir);
|
|
123
|
+
await updateStory(this.db, this.story.id, { branchName }, this.storiesDir);
|
|
115
124
|
}
|
|
116
125
|
|
|
117
126
|
const prompt = `I need to implement this simple story:
|
|
@@ -140,42 +149,42 @@ This is a simple task (complexity ${this.story.complexity_score || 1}-3).
|
|
|
140
149
|
Please help me identify which files I need to read and modify.`;
|
|
141
150
|
|
|
142
151
|
await this.chat(prompt);
|
|
143
|
-
this.updateTaskProgress('Analyzing task', []);
|
|
144
|
-
this.log('STORY_PROGRESS_UPDATE', 'Analyzing requirements', { storyId: this.story.id });
|
|
152
|
+
await this.updateTaskProgress('Analyzing task', []);
|
|
153
|
+
await this.log('STORY_PROGRESS_UPDATE', 'Analyzing requirements', { storyId: this.story.id });
|
|
145
154
|
|
|
146
155
|
// Get guidance and implement
|
|
147
156
|
const implementPrompt = `Based on the analysis, show me the exact code changes to make. Keep it simple and minimal.`;
|
|
148
157
|
await this.chat(implementPrompt);
|
|
149
|
-
this.log('STORY_PROGRESS_UPDATE', 'Making code changes', { storyId: this.story.id });
|
|
158
|
+
await this.log('STORY_PROGRESS_UPDATE', 'Making code changes', { storyId: this.story.id });
|
|
150
159
|
|
|
151
160
|
// Complete
|
|
152
|
-
updateStory(this.db, this.story.id, { status: 'review' }, this.storiesDir);
|
|
153
|
-
this.log('STORY_COMPLETED', 'Implementation complete, ready for review', {
|
|
161
|
+
await updateStory(this.db, this.story.id, { status: 'review' }, this.storiesDir);
|
|
162
|
+
await this.log('STORY_COMPLETED', 'Implementation complete, ready for review', {
|
|
154
163
|
storyId: this.story.id,
|
|
155
164
|
branchName,
|
|
156
165
|
});
|
|
157
166
|
}
|
|
158
167
|
|
|
159
168
|
private async escalateToSenior(reason: string): Promise<void> {
|
|
160
|
-
const seniors = getAgentsByTeam(this.db, this.teamId!).filter(
|
|
169
|
+
const seniors = (await getAgentsByTeam(this.db, this.teamId!)).filter(
|
|
161
170
|
a => a.type === 'senior' && a.status !== 'terminated'
|
|
162
171
|
);
|
|
163
172
|
|
|
164
173
|
const seniorId = seniors[0]?.id;
|
|
165
174
|
|
|
166
|
-
const escalation = createEscalation(this.db, {
|
|
175
|
+
const escalation = await createEscalation(this.db, {
|
|
167
176
|
storyId: this.story?.id,
|
|
168
177
|
fromAgentId: this.agentId,
|
|
169
178
|
toAgentId: seniorId,
|
|
170
179
|
reason,
|
|
171
180
|
});
|
|
172
181
|
|
|
173
|
-
this.log('ESCALATION_CREATED', reason, {
|
|
182
|
+
await this.log('ESCALATION_CREATED', reason, {
|
|
174
183
|
escalationId: escalation.id,
|
|
175
184
|
toAgent: seniorId,
|
|
176
185
|
});
|
|
177
186
|
|
|
178
|
-
this.updateStatus('blocked');
|
|
179
|
-
this.addBlocker(`Escalated to Senior: ${reason}`);
|
|
187
|
+
await this.updateStatus('blocked');
|
|
188
|
+
await this.addBlocker(`Escalated to Senior: ${reason}`);
|
|
180
189
|
}
|
|
181
190
|
}
|
package/src/agents/qa.ts
CHANGED
|
@@ -25,15 +25,23 @@ export class QAAgent extends BaseAgent {
|
|
|
25
25
|
constructor(context: QAContext) {
|
|
26
26
|
super(context);
|
|
27
27
|
this.qaConfig = context.qaConfig;
|
|
28
|
+
}
|
|
28
29
|
|
|
30
|
+
private async init(context: QAContext): Promise<void> {
|
|
29
31
|
if (context.agentRow.team_id) {
|
|
30
|
-
this.team = getTeamById(this.db, context.agentRow.team_id) || null;
|
|
31
|
-
this.pendingStories = getStoriesByStatus(this.db, 'qa').filter(
|
|
32
|
+
this.team = (await getTeamById(this.db, context.agentRow.team_id)) || null;
|
|
33
|
+
this.pendingStories = (await getStoriesByStatus(this.db, 'qa')).filter(
|
|
32
34
|
s => s.team_id === context.agentRow.team_id
|
|
33
35
|
);
|
|
34
36
|
}
|
|
35
37
|
}
|
|
36
38
|
|
|
39
|
+
static async create(context: QAContext): Promise<QAAgent> {
|
|
40
|
+
const agent = new QAAgent(context);
|
|
41
|
+
await agent.init(context);
|
|
42
|
+
return agent;
|
|
43
|
+
}
|
|
44
|
+
|
|
37
45
|
getSystemPrompt(): string {
|
|
38
46
|
const teamInfo = this.team
|
|
39
47
|
? `Team: ${this.team.name}\nRepository: ${this.team.repo_path}`
|
|
@@ -73,7 +81,7 @@ ${this.memoryState.conversationSummary || 'Starting fresh.'}`;
|
|
|
73
81
|
|
|
74
82
|
async execute(): Promise<void> {
|
|
75
83
|
if (this.pendingStories.length === 0) {
|
|
76
|
-
this.log('STORY_QA_STARTED', 'No stories pending QA');
|
|
84
|
+
await this.log('STORY_QA_STARTED', 'No stories pending QA');
|
|
77
85
|
return;
|
|
78
86
|
}
|
|
79
87
|
|
|
@@ -83,23 +91,23 @@ ${this.memoryState.conversationSummary || 'Starting fresh.'}`;
|
|
|
83
91
|
}
|
|
84
92
|
|
|
85
93
|
private async processStory(story: StoryRow): Promise<void> {
|
|
86
|
-
this.setCurrentTask(story.id, 'qa');
|
|
87
|
-
this.log('STORY_QA_STARTED', `QA for story: ${story.title}`, { storyId: story.id });
|
|
94
|
+
await this.setCurrentTask(story.id, 'qa');
|
|
95
|
+
await this.log('STORY_QA_STARTED', `QA for story: ${story.title}`, { storyId: story.id });
|
|
88
96
|
|
|
89
97
|
// Checkout the branch
|
|
90
98
|
if (story.branch_name) {
|
|
91
99
|
try {
|
|
92
100
|
await execa('git', ['checkout', story.branch_name], { cwd: this.workDir });
|
|
93
101
|
} catch (err) {
|
|
94
|
-
this.log(
|
|
102
|
+
await this.log(
|
|
95
103
|
'STORY_QA_FAILED',
|
|
96
104
|
`Failed to checkout branch: ${err instanceof Error ? err.message : 'Unknown error'}`,
|
|
97
105
|
{
|
|
98
106
|
storyId: story.id,
|
|
99
107
|
}
|
|
100
108
|
);
|
|
101
|
-
updateStory(this.db, story.id, { status: 'qa_failed' }, this.storiesDir);
|
|
102
|
-
this.checkAndEscalate(story);
|
|
109
|
+
await updateStory(this.db, story.id, { status: 'qa_failed' }, this.storiesDir);
|
|
110
|
+
await this.checkAndEscalate(story);
|
|
103
111
|
return;
|
|
104
112
|
}
|
|
105
113
|
}
|
|
@@ -107,16 +115,16 @@ ${this.memoryState.conversationSummary || 'Starting fresh.'}`;
|
|
|
107
115
|
// Run quality checks
|
|
108
116
|
const qualityPassed = await this.runQualityChecks(story.id);
|
|
109
117
|
if (!qualityPassed) {
|
|
110
|
-
updateStory(this.db, story.id, { status: 'qa_failed' });
|
|
111
|
-
this.checkAndEscalate(story);
|
|
118
|
+
await updateStory(this.db, story.id, { status: 'qa_failed' });
|
|
119
|
+
await this.checkAndEscalate(story);
|
|
112
120
|
return;
|
|
113
121
|
}
|
|
114
122
|
|
|
115
123
|
// Run build
|
|
116
124
|
const buildPassed = await this.runBuild(story.id);
|
|
117
125
|
if (!buildPassed) {
|
|
118
|
-
updateStory(this.db, story.id, { status: 'qa_failed' });
|
|
119
|
-
this.checkAndEscalate(story);
|
|
126
|
+
await updateStory(this.db, story.id, { status: 'qa_failed' });
|
|
127
|
+
await this.checkAndEscalate(story);
|
|
120
128
|
return;
|
|
121
129
|
}
|
|
122
130
|
|
|
@@ -124,21 +132,21 @@ ${this.memoryState.conversationSummary || 'Starting fresh.'}`;
|
|
|
124
132
|
if (this.qaConfig.testCommand) {
|
|
125
133
|
const testsPassed = await this.runTests(story.id);
|
|
126
134
|
if (!testsPassed) {
|
|
127
|
-
updateStory(this.db, story.id, { status: 'qa_failed' }, this.storiesDir);
|
|
128
|
-
this.checkAndEscalate(story);
|
|
135
|
+
await updateStory(this.db, story.id, { status: 'qa_failed' }, this.storiesDir);
|
|
136
|
+
await this.checkAndEscalate(story);
|
|
129
137
|
return;
|
|
130
138
|
}
|
|
131
139
|
}
|
|
132
140
|
|
|
133
141
|
// All checks passed
|
|
134
|
-
this.log('STORY_QA_PASSED', 'All QA checks passed', { storyId: story.id });
|
|
142
|
+
await this.log('STORY_QA_PASSED', 'All QA checks passed', { storyId: story.id });
|
|
135
143
|
|
|
136
144
|
// Create PR
|
|
137
145
|
await this.createPR(story);
|
|
138
146
|
}
|
|
139
147
|
|
|
140
148
|
private async runQualityChecks(storyId: string): Promise<boolean> {
|
|
141
|
-
this.log('CODE_QUALITY_CHECK_STARTED', 'Running quality checks', { storyId });
|
|
149
|
+
await this.log('CODE_QUALITY_CHECK_STARTED', 'Running quality checks', { storyId });
|
|
142
150
|
|
|
143
151
|
for (const check of this.qaConfig.qualityChecks) {
|
|
144
152
|
try {
|
|
@@ -146,7 +154,7 @@ ${this.memoryState.conversationSummary || 'Starting fresh.'}`;
|
|
|
146
154
|
await execa(cmd, args, { cwd: this.workDir });
|
|
147
155
|
} catch (err) {
|
|
148
156
|
const error = err as { stderr?: string; stdout?: string };
|
|
149
|
-
this.log('CODE_QUALITY_CHECK_FAILED', `Check failed: ${check}`, {
|
|
157
|
+
await this.log('CODE_QUALITY_CHECK_FAILED', `Check failed: ${check}`, {
|
|
150
158
|
storyId,
|
|
151
159
|
error: error.stderr || error.stdout,
|
|
152
160
|
});
|
|
@@ -154,21 +162,21 @@ ${this.memoryState.conversationSummary || 'Starting fresh.'}`;
|
|
|
154
162
|
}
|
|
155
163
|
}
|
|
156
164
|
|
|
157
|
-
this.log('CODE_QUALITY_CHECK_PASSED', 'All quality checks passed', { storyId });
|
|
165
|
+
await this.log('CODE_QUALITY_CHECK_PASSED', 'All quality checks passed', { storyId });
|
|
158
166
|
return true;
|
|
159
167
|
}
|
|
160
168
|
|
|
161
169
|
private async runBuild(storyId: string): Promise<boolean> {
|
|
162
|
-
this.log('BUILD_STARTED', 'Running build', { storyId });
|
|
170
|
+
await this.log('BUILD_STARTED', 'Running build', { storyId });
|
|
163
171
|
|
|
164
172
|
try {
|
|
165
173
|
const [cmd, ...args] = this.qaConfig.buildCommand.split(' ');
|
|
166
174
|
await execa(cmd, args, { cwd: this.workDir });
|
|
167
|
-
this.log('BUILD_PASSED', 'Build succeeded', { storyId });
|
|
175
|
+
await this.log('BUILD_PASSED', 'Build succeeded', { storyId });
|
|
168
176
|
return true;
|
|
169
177
|
} catch (err) {
|
|
170
178
|
const error = err as { stderr?: string; stdout?: string };
|
|
171
|
-
this.log('BUILD_FAILED', 'Build failed', {
|
|
179
|
+
await this.log('BUILD_FAILED', 'Build failed', {
|
|
172
180
|
storyId,
|
|
173
181
|
error: error.stderr || error.stdout,
|
|
174
182
|
});
|
|
@@ -179,16 +187,16 @@ ${this.memoryState.conversationSummary || 'Starting fresh.'}`;
|
|
|
179
187
|
private async runTests(storyId: string): Promise<boolean> {
|
|
180
188
|
if (!this.qaConfig.testCommand) return true;
|
|
181
189
|
|
|
182
|
-
this.log('BUILD_STARTED', 'Running tests', { storyId });
|
|
190
|
+
await this.log('BUILD_STARTED', 'Running tests', { storyId });
|
|
183
191
|
|
|
184
192
|
try {
|
|
185
193
|
const [cmd, ...args] = this.qaConfig.testCommand.split(' ');
|
|
186
194
|
await execa(cmd, args, { cwd: this.workDir });
|
|
187
|
-
this.log('BUILD_PASSED', 'Tests passed', { storyId });
|
|
195
|
+
await this.log('BUILD_PASSED', 'Tests passed', { storyId });
|
|
188
196
|
return true;
|
|
189
197
|
} catch (err) {
|
|
190
198
|
const error = err as { stderr?: string; stdout?: string };
|
|
191
|
-
this.log('BUILD_FAILED', 'Tests failed', {
|
|
199
|
+
await this.log('BUILD_FAILED', 'Tests failed', {
|
|
192
200
|
storyId,
|
|
193
201
|
error: error.stderr || error.stdout,
|
|
194
202
|
});
|
|
@@ -198,15 +206,17 @@ ${this.memoryState.conversationSummary || 'Starting fresh.'}`;
|
|
|
198
206
|
|
|
199
207
|
private async createPR(story: StoryRow): Promise<void> {
|
|
200
208
|
if (!story.branch_name) {
|
|
201
|
-
this.log('STORY_PR_CREATED', 'No branch name, skipping PR creation', {
|
|
202
|
-
|
|
209
|
+
await this.log('STORY_PR_CREATED', 'No branch name, skipping PR creation', {
|
|
210
|
+
storyId: story.id,
|
|
211
|
+
});
|
|
212
|
+
await updateStory(this.db, story.id, { status: 'pr_submitted' }, this.storiesDir);
|
|
203
213
|
return;
|
|
204
214
|
}
|
|
205
215
|
|
|
206
216
|
// Check if PR already exists
|
|
207
|
-
const existingPR = getPullRequestByStory(this.db, story.id);
|
|
217
|
+
const existingPR = await getPullRequestByStory(this.db, story.id);
|
|
208
218
|
if (existingPR) {
|
|
209
|
-
this.log('STORY_PR_CREATED', 'PR already exists', {
|
|
219
|
+
await this.log('STORY_PR_CREATED', 'PR already exists', {
|
|
210
220
|
storyId: story.id,
|
|
211
221
|
prUrl: existingPR.github_pr_url,
|
|
212
222
|
});
|
|
@@ -241,7 +251,7 @@ ${this.memoryState.conversationSummary || 'Starting fresh.'}`;
|
|
|
241
251
|
const prNumber = prNumberMatch ? parseInt(prNumberMatch[1], 10) : undefined;
|
|
242
252
|
|
|
243
253
|
// Create PR record
|
|
244
|
-
const pr = createPullRequest(this.db, {
|
|
254
|
+
const pr = await createPullRequest(this.db, {
|
|
245
255
|
storyId: story.id,
|
|
246
256
|
teamId: story.team_id,
|
|
247
257
|
branchName: story.branch_name || `feature/${story.id}`,
|
|
@@ -250,7 +260,7 @@ ${this.memoryState.conversationSummary || 'Starting fresh.'}`;
|
|
|
250
260
|
});
|
|
251
261
|
|
|
252
262
|
// Update story
|
|
253
|
-
updateStory(
|
|
263
|
+
await updateStory(
|
|
254
264
|
this.db,
|
|
255
265
|
story.id,
|
|
256
266
|
{
|
|
@@ -260,40 +270,44 @@ ${this.memoryState.conversationSummary || 'Starting fresh.'}`;
|
|
|
260
270
|
this.storiesDir
|
|
261
271
|
);
|
|
262
272
|
|
|
263
|
-
this.log('STORY_PR_CREATED', `PR created: ${prUrl}`, {
|
|
273
|
+
await this.log('STORY_PR_CREATED', `PR created: ${prUrl}`, {
|
|
264
274
|
storyId: story.id,
|
|
265
275
|
prId: pr.id,
|
|
266
276
|
prNumber,
|
|
267
277
|
});
|
|
268
278
|
} catch (err) {
|
|
269
279
|
const error = err as { stderr?: string };
|
|
270
|
-
this.log(
|
|
271
|
-
|
|
272
|
-
|
|
280
|
+
await this.log(
|
|
281
|
+
'STORY_PR_CREATED',
|
|
282
|
+
`Failed to create PR: ${error.stderr || 'Unknown error'}`,
|
|
283
|
+
{
|
|
284
|
+
storyId: story.id,
|
|
285
|
+
}
|
|
286
|
+
);
|
|
273
287
|
|
|
274
288
|
// Still mark as pr_submitted since QA passed
|
|
275
|
-
updateStory(this.db, story.id, { status: 'pr_submitted' }, this.storiesDir);
|
|
289
|
+
await updateStory(this.db, story.id, { status: 'pr_submitted' }, this.storiesDir);
|
|
276
290
|
}
|
|
277
291
|
}
|
|
278
292
|
|
|
279
|
-
private checkAndEscalate(story: StoryRow): void {
|
|
280
|
-
const failureCount = countQaFailuresByStory(this.db, story.id);
|
|
293
|
+
private async checkAndEscalate(story: StoryRow): Promise<void> {
|
|
294
|
+
const failureCount = await countQaFailuresByStory(this.db, story.id);
|
|
281
295
|
|
|
282
296
|
if (failureCount >= 3) {
|
|
283
297
|
// Find the senior agent for the team
|
|
284
|
-
const seniorAgents = getAgentsByType(this.db, 'senior').filter(
|
|
298
|
+
const seniorAgents = (await getAgentsByType(this.db, 'senior')).filter(
|
|
285
299
|
a => a.team_id === story.team_id
|
|
286
300
|
);
|
|
287
301
|
|
|
288
302
|
if (seniorAgents.length > 0) {
|
|
289
|
-
const escalation = createEscalation(this.db, {
|
|
303
|
+
const escalation = await createEscalation(this.db, {
|
|
290
304
|
storyId: story.id,
|
|
291
305
|
fromAgentId: this.agentId,
|
|
292
306
|
toAgentId: seniorAgents[0].id,
|
|
293
307
|
reason: `Story failed QA ${failureCount} times. Needs senior review and assistance.`,
|
|
294
308
|
});
|
|
295
309
|
|
|
296
|
-
this.log('ESCALATION_CREATED', `Story escalated after ${failureCount} QA failures`, {
|
|
310
|
+
await this.log('ESCALATION_CREATED', `Story escalated after ${failureCount} QA failures`, {
|
|
297
311
|
storyId: story.id,
|
|
298
312
|
escalationId: escalation.id,
|
|
299
313
|
failureCount,
|