hungry-ghost-hive 0.47.4 → 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 +24 -21
- package/dist/cli/commands/req.js.map +1 -1
- package/dist/cli/commands/req.test.js +31 -0
- package/dist/cli/commands/req.test.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/index.js +8 -1
- package/dist/index.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.test.ts +36 -0
- package/src/cli/commands/req.ts +24 -20
- 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/index.ts +8 -1
- 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
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// Licensed under the Hungry Ghost Hive License. See LICENSE.
|
|
2
2
|
|
|
3
3
|
import { nanoid } from 'nanoid';
|
|
4
|
-
import type
|
|
5
|
-
import {
|
|
4
|
+
import { type EscalationRow } from '../client.js';
|
|
5
|
+
import type { DatabaseProvider } from '../provider.js';
|
|
6
6
|
|
|
7
7
|
export type { EscalationRow };
|
|
8
8
|
|
|
@@ -21,12 +21,14 @@ export interface UpdateEscalationInput {
|
|
|
21
21
|
resolution?: string | null;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
export function createEscalation(
|
|
24
|
+
export async function createEscalation(
|
|
25
|
+
provider: DatabaseProvider,
|
|
26
|
+
input: CreateEscalationInput
|
|
27
|
+
): Promise<EscalationRow> {
|
|
25
28
|
const id = `ESC-${nanoid(6).toUpperCase()}`;
|
|
26
29
|
const now = new Date().toISOString();
|
|
27
30
|
|
|
28
|
-
run(
|
|
29
|
-
db,
|
|
31
|
+
await provider.run(
|
|
30
32
|
`
|
|
31
33
|
INSERT INTO escalations (id, story_id, from_agent_id, to_agent_id, reason, created_at)
|
|
32
34
|
VALUES (?, ?, ?, ?, ?, ?)
|
|
@@ -41,16 +43,21 @@ export function createEscalation(db: Database, input: CreateEscalationInput): Es
|
|
|
41
43
|
]
|
|
42
44
|
);
|
|
43
45
|
|
|
44
|
-
return getEscalationById(
|
|
46
|
+
return (await getEscalationById(provider, id))!;
|
|
45
47
|
}
|
|
46
48
|
|
|
47
|
-
export function getEscalationById(
|
|
48
|
-
|
|
49
|
+
export async function getEscalationById(
|
|
50
|
+
provider: DatabaseProvider,
|
|
51
|
+
id: string
|
|
52
|
+
): Promise<EscalationRow | undefined> {
|
|
53
|
+
return await provider.queryOne<EscalationRow>('SELECT * FROM escalations WHERE id = ?', [id]);
|
|
49
54
|
}
|
|
50
55
|
|
|
51
|
-
export function getEscalationsByStory(
|
|
52
|
-
|
|
53
|
-
|
|
56
|
+
export async function getEscalationsByStory(
|
|
57
|
+
provider: DatabaseProvider,
|
|
58
|
+
storyId: string
|
|
59
|
+
): Promise<EscalationRow[]> {
|
|
60
|
+
return await provider.queryAll<EscalationRow>(
|
|
54
61
|
`
|
|
55
62
|
SELECT * FROM escalations
|
|
56
63
|
WHERE story_id = ?
|
|
@@ -60,9 +67,11 @@ export function getEscalationsByStory(db: Database, storyId: string): Escalation
|
|
|
60
67
|
);
|
|
61
68
|
}
|
|
62
69
|
|
|
63
|
-
export function getEscalationsByFromAgent(
|
|
64
|
-
|
|
65
|
-
|
|
70
|
+
export async function getEscalationsByFromAgent(
|
|
71
|
+
provider: DatabaseProvider,
|
|
72
|
+
agentId: string
|
|
73
|
+
): Promise<EscalationRow[]> {
|
|
74
|
+
return await provider.queryAll<EscalationRow>(
|
|
66
75
|
`
|
|
67
76
|
SELECT * FROM escalations
|
|
68
77
|
WHERE from_agent_id = ?
|
|
@@ -72,19 +81,18 @@ export function getEscalationsByFromAgent(db: Database, agentId: string): Escala
|
|
|
72
81
|
);
|
|
73
82
|
}
|
|
74
83
|
|
|
75
|
-
export function getEscalationsByToAgent(
|
|
84
|
+
export async function getEscalationsByToAgent(
|
|
85
|
+
provider: DatabaseProvider,
|
|
86
|
+
agentId: string | null
|
|
87
|
+
): Promise<EscalationRow[]> {
|
|
76
88
|
if (agentId === null) {
|
|
77
|
-
return queryAll<EscalationRow>(
|
|
78
|
-
db,
|
|
79
|
-
`
|
|
89
|
+
return await provider.queryAll<EscalationRow>(`
|
|
80
90
|
SELECT * FROM escalations
|
|
81
91
|
WHERE to_agent_id IS NULL
|
|
82
92
|
ORDER BY created_at DESC
|
|
83
|
-
`
|
|
84
|
-
);
|
|
93
|
+
`);
|
|
85
94
|
}
|
|
86
|
-
return queryAll<EscalationRow>(
|
|
87
|
-
db,
|
|
95
|
+
return await provider.queryAll<EscalationRow>(
|
|
88
96
|
`
|
|
89
97
|
SELECT * FROM escalations
|
|
90
98
|
WHERE to_agent_id = ?
|
|
@@ -94,9 +102,11 @@ export function getEscalationsByToAgent(db: Database, agentId: string | null): E
|
|
|
94
102
|
);
|
|
95
103
|
}
|
|
96
104
|
|
|
97
|
-
export function getEscalationsByStatus(
|
|
98
|
-
|
|
99
|
-
|
|
105
|
+
export async function getEscalationsByStatus(
|
|
106
|
+
provider: DatabaseProvider,
|
|
107
|
+
status: EscalationStatus
|
|
108
|
+
): Promise<EscalationRow[]> {
|
|
109
|
+
return await provider.queryAll<EscalationRow>(
|
|
100
110
|
`
|
|
101
111
|
SELECT * FROM escalations
|
|
102
112
|
WHERE status = ?
|
|
@@ -106,28 +116,26 @@ export function getEscalationsByStatus(db: Database, status: EscalationStatus):
|
|
|
106
116
|
);
|
|
107
117
|
}
|
|
108
118
|
|
|
109
|
-
export function getPendingEscalations(
|
|
110
|
-
return getEscalationsByStatus(
|
|
119
|
+
export async function getPendingEscalations(provider: DatabaseProvider): Promise<EscalationRow[]> {
|
|
120
|
+
return await getEscalationsByStatus(provider, 'pending');
|
|
111
121
|
}
|
|
112
122
|
|
|
113
|
-
export function getPendingHumanEscalations(
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
123
|
+
export async function getPendingHumanEscalations(
|
|
124
|
+
provider: DatabaseProvider
|
|
125
|
+
): Promise<EscalationRow[]> {
|
|
126
|
+
return await provider.queryAll<EscalationRow>(`
|
|
117
127
|
SELECT * FROM escalations
|
|
118
128
|
WHERE status = 'pending' AND to_agent_id IS NULL
|
|
119
129
|
ORDER BY created_at
|
|
120
|
-
`
|
|
121
|
-
);
|
|
130
|
+
`);
|
|
122
131
|
}
|
|
123
132
|
|
|
124
|
-
export function getRecentEscalationsForAgent(
|
|
125
|
-
|
|
133
|
+
export async function getRecentEscalationsForAgent(
|
|
134
|
+
provider: DatabaseProvider,
|
|
126
135
|
agentId: string,
|
|
127
136
|
minutesBack: number = 30
|
|
128
|
-
): EscalationRow[] {
|
|
129
|
-
return queryAll<EscalationRow>(
|
|
130
|
-
db,
|
|
137
|
+
): Promise<EscalationRow[]> {
|
|
138
|
+
return await provider.queryAll<EscalationRow>(
|
|
131
139
|
`
|
|
132
140
|
SELECT * FROM escalations
|
|
133
141
|
WHERE from_agent_id = ?
|
|
@@ -138,9 +146,11 @@ export function getRecentEscalationsForAgent(
|
|
|
138
146
|
);
|
|
139
147
|
}
|
|
140
148
|
|
|
141
|
-
export function getActiveEscalationsForAgent(
|
|
142
|
-
|
|
143
|
-
|
|
149
|
+
export async function getActiveEscalationsForAgent(
|
|
150
|
+
provider: DatabaseProvider,
|
|
151
|
+
agentId: string
|
|
152
|
+
): Promise<EscalationRow[]> {
|
|
153
|
+
return await provider.queryAll<EscalationRow>(
|
|
144
154
|
`
|
|
145
155
|
SELECT * FROM escalations
|
|
146
156
|
WHERE from_agent_id = ?
|
|
@@ -151,15 +161,17 @@ export function getActiveEscalationsForAgent(db: Database, agentId: string): Esc
|
|
|
151
161
|
);
|
|
152
162
|
}
|
|
153
163
|
|
|
154
|
-
export function getAllEscalations(
|
|
155
|
-
return queryAll<EscalationRow>(
|
|
164
|
+
export async function getAllEscalations(provider: DatabaseProvider): Promise<EscalationRow[]> {
|
|
165
|
+
return await provider.queryAll<EscalationRow>(
|
|
166
|
+
'SELECT * FROM escalations ORDER BY created_at DESC'
|
|
167
|
+
);
|
|
156
168
|
}
|
|
157
169
|
|
|
158
|
-
export function updateEscalation(
|
|
159
|
-
|
|
170
|
+
export async function updateEscalation(
|
|
171
|
+
provider: DatabaseProvider,
|
|
160
172
|
id: string,
|
|
161
173
|
input: UpdateEscalationInput
|
|
162
|
-
): EscalationRow | undefined {
|
|
174
|
+
): Promise<EscalationRow | undefined> {
|
|
163
175
|
const updates: string[] = [];
|
|
164
176
|
const values: (string | null)[] = [];
|
|
165
177
|
|
|
@@ -181,26 +193,29 @@ export function updateEscalation(
|
|
|
181
193
|
}
|
|
182
194
|
|
|
183
195
|
if (updates.length === 0) {
|
|
184
|
-
return getEscalationById(
|
|
196
|
+
return await getEscalationById(provider, id);
|
|
185
197
|
}
|
|
186
198
|
|
|
187
199
|
values.push(id);
|
|
188
|
-
run(
|
|
189
|
-
return getEscalationById(
|
|
200
|
+
await provider.run(`UPDATE escalations SET ${updates.join(', ')} WHERE id = ?`, values);
|
|
201
|
+
return await getEscalationById(provider, id);
|
|
190
202
|
}
|
|
191
203
|
|
|
192
|
-
export function resolveEscalation(
|
|
193
|
-
|
|
204
|
+
export async function resolveEscalation(
|
|
205
|
+
provider: DatabaseProvider,
|
|
194
206
|
id: string,
|
|
195
207
|
resolution: string
|
|
196
|
-
): EscalationRow | undefined {
|
|
197
|
-
return updateEscalation(
|
|
208
|
+
): Promise<EscalationRow | undefined> {
|
|
209
|
+
return await updateEscalation(provider, id, { status: 'resolved', resolution });
|
|
198
210
|
}
|
|
199
211
|
|
|
200
|
-
export function acknowledgeEscalation(
|
|
201
|
-
|
|
212
|
+
export async function acknowledgeEscalation(
|
|
213
|
+
provider: DatabaseProvider,
|
|
214
|
+
id: string
|
|
215
|
+
): Promise<EscalationRow | undefined> {
|
|
216
|
+
return await updateEscalation(provider, id, { status: 'acknowledged' });
|
|
202
217
|
}
|
|
203
218
|
|
|
204
|
-
export function deleteEscalation(
|
|
205
|
-
run(
|
|
219
|
+
export async function deleteEscalation(provider: DatabaseProvider, id: string): Promise<void> {
|
|
220
|
+
await provider.run('DELETE FROM escalations WHERE id = ?', [id]);
|
|
206
221
|
}
|
|
@@ -1,19 +1,20 @@
|
|
|
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 } from 'vitest';
|
|
4
|
+
import { SqliteProvider } from '../provider.js';
|
|
5
5
|
import { createAgent } from './agents.js';
|
|
6
6
|
import { getStaleAgents, isAgentHeartbeatCurrent, updateAgentHeartbeat } from './heartbeat.js';
|
|
7
7
|
import { createTeam } from './teams.js';
|
|
8
8
|
import { createTestDatabase } from './test-helpers.js';
|
|
9
9
|
|
|
10
10
|
describe('heartbeat queries', () => {
|
|
11
|
-
let db:
|
|
11
|
+
let db: SqliteProvider;
|
|
12
12
|
let teamId: string;
|
|
13
13
|
|
|
14
14
|
beforeEach(async () => {
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
const rawDb = await createTestDatabase();
|
|
16
|
+
db = new SqliteProvider(rawDb);
|
|
17
|
+
const team = await createTeam(db, {
|
|
17
18
|
repoUrl: 'https://github.com/test/repo.git',
|
|
18
19
|
repoPath: '/path/to/repo',
|
|
19
20
|
name: 'Test Team',
|
|
@@ -22,15 +23,15 @@ describe('heartbeat queries', () => {
|
|
|
22
23
|
});
|
|
23
24
|
|
|
24
25
|
describe('updateAgentHeartbeat', () => {
|
|
25
|
-
it('should update agent last_seen timestamp', () => {
|
|
26
|
-
const agent = createAgent(db, {
|
|
26
|
+
it('should update agent last_seen timestamp', async () => {
|
|
27
|
+
const agent = await createAgent(db, {
|
|
27
28
|
type: 'senior',
|
|
28
29
|
teamId,
|
|
29
30
|
});
|
|
30
31
|
|
|
31
|
-
updateAgentHeartbeat(db, agent.id);
|
|
32
|
+
await updateAgentHeartbeat(db, agent.id);
|
|
32
33
|
|
|
33
|
-
const stmt = db.prepare(`SELECT last_seen FROM agents WHERE id = ?`);
|
|
34
|
+
const stmt = db.db.prepare(`SELECT last_seen FROM agents WHERE id = ?`);
|
|
34
35
|
stmt.bind([agent.id]);
|
|
35
36
|
const afterUpdate = [];
|
|
36
37
|
while (stmt.step()) afterUpdate.push(stmt.getAsObject());
|
|
@@ -41,17 +42,17 @@ describe('heartbeat queries', () => {
|
|
|
41
42
|
expect(typeof updatedLastSeen).toBe('string');
|
|
42
43
|
});
|
|
43
44
|
|
|
44
|
-
it('should handle multiple heartbeat updates', () => {
|
|
45
|
-
const agent = createAgent(db, {
|
|
45
|
+
it('should handle multiple heartbeat updates', async () => {
|
|
46
|
+
const agent = await createAgent(db, {
|
|
46
47
|
type: 'senior',
|
|
47
48
|
teamId,
|
|
48
49
|
});
|
|
49
50
|
|
|
50
|
-
updateAgentHeartbeat(db, agent.id);
|
|
51
|
-
updateAgentHeartbeat(db, agent.id);
|
|
52
|
-
updateAgentHeartbeat(db, agent.id);
|
|
51
|
+
await updateAgentHeartbeat(db, agent.id);
|
|
52
|
+
await updateAgentHeartbeat(db, agent.id);
|
|
53
|
+
await updateAgentHeartbeat(db, agent.id);
|
|
53
54
|
|
|
54
|
-
const stmtResult = db.prepare(`SELECT last_seen FROM agents WHERE id = ?`);
|
|
55
|
+
const stmtResult = db.db.prepare(`SELECT last_seen FROM agents WHERE id = ?`);
|
|
55
56
|
stmtResult.bind([agent.id]);
|
|
56
57
|
const result = [];
|
|
57
58
|
while (stmtResult.step()) result.push(stmtResult.getAsObject());
|
|
@@ -61,135 +62,133 @@ describe('heartbeat queries', () => {
|
|
|
61
62
|
expect(lastSeen).toBeDefined();
|
|
62
63
|
});
|
|
63
64
|
|
|
64
|
-
it('should not throw error for non-existent agent', () => {
|
|
65
|
-
expect(()
|
|
66
|
-
updateAgentHeartbeat(db, 'non-existent-agent');
|
|
67
|
-
}).not.toThrow();
|
|
65
|
+
it('should not throw error for non-existent agent', async () => {
|
|
66
|
+
await expect(updateAgentHeartbeat(db, 'non-existent-agent')).resolves.not.toThrow();
|
|
68
67
|
});
|
|
69
68
|
});
|
|
70
69
|
|
|
71
70
|
describe('getStaleAgents', () => {
|
|
72
|
-
it('should return agents with stale heartbeats', () => {
|
|
71
|
+
it('should return agents with stale heartbeats', async () => {
|
|
73
72
|
// Create agent and manually set old last_seen
|
|
74
|
-
const agent = createAgent(db, {
|
|
73
|
+
const agent = await createAgent(db, {
|
|
75
74
|
type: 'senior',
|
|
76
75
|
teamId,
|
|
77
76
|
});
|
|
78
77
|
|
|
79
78
|
// Set last_seen to 30 seconds ago
|
|
80
79
|
const oldTimestamp = new Date(Date.now() - 30000).toISOString();
|
|
81
|
-
db.run(`UPDATE agents SET last_seen = ? WHERE id = ?`, [oldTimestamp, agent.id]);
|
|
80
|
+
db.db.run(`UPDATE agents SET last_seen = ? WHERE id = ?`, [oldTimestamp, agent.id]);
|
|
82
81
|
|
|
83
|
-
const staleAgents = getStaleAgents(db, 15);
|
|
82
|
+
const staleAgents = await getStaleAgents(db, 15);
|
|
84
83
|
|
|
85
84
|
expect(staleAgents.length).toBeGreaterThan(0);
|
|
86
85
|
expect(staleAgents[0].id).toBe(agent.id);
|
|
87
86
|
expect(staleAgents[0].seconds_since_heartbeat).toBeGreaterThan(15);
|
|
88
87
|
});
|
|
89
88
|
|
|
90
|
-
it('should not return agents with current heartbeats', () => {
|
|
91
|
-
const agent = createAgent(db, {
|
|
89
|
+
it('should not return agents with current heartbeats', async () => {
|
|
90
|
+
const agent = await createAgent(db, {
|
|
92
91
|
type: 'senior',
|
|
93
92
|
teamId,
|
|
94
93
|
});
|
|
95
94
|
|
|
96
|
-
updateAgentHeartbeat(db, agent.id);
|
|
95
|
+
await updateAgentHeartbeat(db, agent.id);
|
|
97
96
|
|
|
98
|
-
const staleAgents = getStaleAgents(db, 15);
|
|
97
|
+
const staleAgents = await getStaleAgents(db, 15);
|
|
99
98
|
|
|
100
99
|
expect(staleAgents).toEqual([]);
|
|
101
100
|
});
|
|
102
101
|
|
|
103
|
-
it('should respect timeout parameter', () => {
|
|
104
|
-
const agent = createAgent(db, {
|
|
102
|
+
it('should respect timeout parameter', async () => {
|
|
103
|
+
const agent = await createAgent(db, {
|
|
105
104
|
type: 'senior',
|
|
106
105
|
teamId,
|
|
107
106
|
});
|
|
108
107
|
|
|
109
108
|
// Set last_seen to 10 seconds ago
|
|
110
109
|
const timestamp = new Date(Date.now() - 10000).toISOString();
|
|
111
|
-
db.run(`UPDATE agents SET last_seen = ? WHERE id = ?`, [timestamp, agent.id]);
|
|
110
|
+
db.db.run(`UPDATE agents SET last_seen = ? WHERE id = ?`, [timestamp, agent.id]);
|
|
112
111
|
|
|
113
112
|
// With 5 second timeout, should be stale
|
|
114
|
-
const staleWith5 = getStaleAgents(db, 5);
|
|
113
|
+
const staleWith5 = await getStaleAgents(db, 5);
|
|
115
114
|
expect(staleWith5.length).toBeGreaterThan(0);
|
|
116
115
|
|
|
117
116
|
// With 20 second timeout, should not be stale
|
|
118
|
-
const staleWith20 = getStaleAgents(db, 20);
|
|
117
|
+
const staleWith20 = await getStaleAgents(db, 20);
|
|
119
118
|
expect(staleWith20).toEqual([]);
|
|
120
119
|
});
|
|
121
120
|
|
|
122
|
-
it('should only return active agents (working/idle)', () => {
|
|
123
|
-
const workingAgent = createAgent(db, {
|
|
121
|
+
it('should only return active agents (working/idle)', async () => {
|
|
122
|
+
const workingAgent = await createAgent(db, {
|
|
124
123
|
type: 'senior',
|
|
125
124
|
teamId,
|
|
126
125
|
});
|
|
127
126
|
|
|
128
|
-
const terminatedAgent = createAgent(db, {
|
|
127
|
+
const terminatedAgent = await createAgent(db, {
|
|
129
128
|
type: 'junior',
|
|
130
129
|
teamId,
|
|
131
130
|
});
|
|
132
131
|
|
|
133
132
|
// Set both to old heartbeat
|
|
134
133
|
const oldTimestamp = new Date(Date.now() - 30000).toISOString();
|
|
135
|
-
db.run(`UPDATE agents SET last_seen = ? WHERE id = ?`, [oldTimestamp, workingAgent.id]);
|
|
136
|
-
db.run(`UPDATE agents SET last_seen = ?, status = 'terminated' WHERE id = ?`, [
|
|
134
|
+
db.db.run(`UPDATE agents SET last_seen = ? WHERE id = ?`, [oldTimestamp, workingAgent.id]);
|
|
135
|
+
db.db.run(`UPDATE agents SET last_seen = ?, status = 'terminated' WHERE id = ?`, [
|
|
137
136
|
oldTimestamp,
|
|
138
137
|
terminatedAgent.id,
|
|
139
138
|
]);
|
|
140
139
|
|
|
141
|
-
const staleAgents = getStaleAgents(db, 15);
|
|
140
|
+
const staleAgents = await getStaleAgents(db, 15);
|
|
142
141
|
|
|
143
142
|
// Should only include working/idle agents
|
|
144
143
|
expect(staleAgents.some(a => a.id === workingAgent.id)).toBe(true);
|
|
145
144
|
expect(staleAgents.some(a => a.id === terminatedAgent.id)).toBe(false);
|
|
146
145
|
});
|
|
147
146
|
|
|
148
|
-
it('should handle agents with null last_seen after grace period', () => {
|
|
149
|
-
const agent = createAgent(db, {
|
|
147
|
+
it('should handle agents with null last_seen after grace period', async () => {
|
|
148
|
+
const agent = await createAgent(db, {
|
|
150
149
|
type: 'senior',
|
|
151
150
|
teamId,
|
|
152
151
|
});
|
|
153
152
|
|
|
154
153
|
// Set last_seen to null and created_at to old timestamp (> 60 + timeout seconds ago)
|
|
155
154
|
const oldCreatedAt = new Date(Date.now() - 90000).toISOString(); // 90 seconds ago
|
|
156
|
-
db.run(`UPDATE agents SET last_seen = NULL, created_at = ? WHERE id = ?`, [
|
|
155
|
+
db.db.run(`UPDATE agents SET last_seen = NULL, created_at = ? WHERE id = ?`, [
|
|
157
156
|
oldCreatedAt,
|
|
158
157
|
agent.id,
|
|
159
158
|
]);
|
|
160
159
|
|
|
161
|
-
const staleAgents = getStaleAgents(db, 15);
|
|
160
|
+
const staleAgents = await getStaleAgents(db, 15);
|
|
162
161
|
|
|
163
162
|
// Should be detected as stale (older than 60 + 15 = 75 seconds)
|
|
164
163
|
expect(staleAgents.some(a => a.id === agent.id)).toBe(true);
|
|
165
164
|
});
|
|
166
165
|
|
|
167
|
-
it('should not return recently created agents with null last_seen', () => {
|
|
168
|
-
const agent = createAgent(db, {
|
|
166
|
+
it('should not return recently created agents with null last_seen', async () => {
|
|
167
|
+
const agent = await createAgent(db, {
|
|
169
168
|
type: 'senior',
|
|
170
169
|
teamId,
|
|
171
170
|
});
|
|
172
171
|
|
|
173
172
|
// Set last_seen to null but keep recent created_at
|
|
174
|
-
db.run(`UPDATE agents SET last_seen = NULL WHERE id = ?`, [agent.id]);
|
|
173
|
+
db.db.run(`UPDATE agents SET last_seen = NULL WHERE id = ?`, [agent.id]);
|
|
175
174
|
|
|
176
|
-
const staleAgents = getStaleAgents(db, 15);
|
|
175
|
+
const staleAgents = await getStaleAgents(db, 15);
|
|
177
176
|
|
|
178
177
|
// Should not be stale (within grace period)
|
|
179
178
|
expect(staleAgents.some(a => a.id === agent.id)).toBe(false);
|
|
180
179
|
});
|
|
181
180
|
|
|
182
|
-
it('should calculate seconds_since_heartbeat correctly', () => {
|
|
183
|
-
const agent = createAgent(db, {
|
|
181
|
+
it('should calculate seconds_since_heartbeat correctly', async () => {
|
|
182
|
+
const agent = await createAgent(db, {
|
|
184
183
|
type: 'senior',
|
|
185
184
|
teamId,
|
|
186
185
|
});
|
|
187
186
|
|
|
188
187
|
// Set last_seen to exactly 30 seconds ago
|
|
189
188
|
const timestamp = new Date(Date.now() - 30000).toISOString();
|
|
190
|
-
db.run(`UPDATE agents SET last_seen = ? WHERE id = ?`, [timestamp, agent.id]);
|
|
189
|
+
db.db.run(`UPDATE agents SET last_seen = ? WHERE id = ?`, [timestamp, agent.id]);
|
|
191
190
|
|
|
192
|
-
const staleAgents = getStaleAgents(db, 15);
|
|
191
|
+
const staleAgents = await getStaleAgents(db, 15);
|
|
193
192
|
|
|
194
193
|
const staleAgent = staleAgents.find(a => a.id === agent.id);
|
|
195
194
|
expect(staleAgent).toBeDefined();
|
|
@@ -198,100 +197,100 @@ describe('heartbeat queries', () => {
|
|
|
198
197
|
expect(staleAgent!.seconds_since_heartbeat).toBeLessThanOrEqual(35);
|
|
199
198
|
});
|
|
200
199
|
|
|
201
|
-
it('should return multiple stale agents', () => {
|
|
202
|
-
const agent1 = createAgent(db, { type: 'senior', teamId });
|
|
203
|
-
const agent2 = createAgent(db, { type: 'intermediate', teamId });
|
|
204
|
-
const agent3 = createAgent(db, { type: 'junior', teamId });
|
|
200
|
+
it('should return multiple stale agents', async () => {
|
|
201
|
+
const agent1 = await createAgent(db, { type: 'senior', teamId });
|
|
202
|
+
const agent2 = await createAgent(db, { type: 'intermediate', teamId });
|
|
203
|
+
const agent3 = await createAgent(db, { type: 'junior', teamId });
|
|
205
204
|
|
|
206
205
|
const oldTimestamp = new Date(Date.now() - 30000).toISOString();
|
|
207
|
-
db.run(`UPDATE agents SET last_seen = ? WHERE id IN (?, ?, ?)`, [
|
|
206
|
+
db.db.run(`UPDATE agents SET last_seen = ? WHERE id IN (?, ?, ?)`, [
|
|
208
207
|
oldTimestamp,
|
|
209
208
|
agent1.id,
|
|
210
209
|
agent2.id,
|
|
211
210
|
agent3.id,
|
|
212
211
|
]);
|
|
213
212
|
|
|
214
|
-
const staleAgents = getStaleAgents(db, 15);
|
|
213
|
+
const staleAgents = await getStaleAgents(db, 15);
|
|
215
214
|
|
|
216
215
|
expect(staleAgents.length).toBe(3);
|
|
217
216
|
});
|
|
218
217
|
});
|
|
219
218
|
|
|
220
219
|
describe('isAgentHeartbeatCurrent', () => {
|
|
221
|
-
it('should return true for agent with current heartbeat', () => {
|
|
222
|
-
const agent = createAgent(db, {
|
|
220
|
+
it('should return true for agent with current heartbeat', async () => {
|
|
221
|
+
const agent = await createAgent(db, {
|
|
223
222
|
type: 'senior',
|
|
224
223
|
teamId,
|
|
225
224
|
});
|
|
226
225
|
|
|
227
|
-
updateAgentHeartbeat(db, agent.id);
|
|
226
|
+
await updateAgentHeartbeat(db, agent.id);
|
|
228
227
|
|
|
229
|
-
const isCurrent = isAgentHeartbeatCurrent(db, agent.id, 15);
|
|
228
|
+
const isCurrent = await isAgentHeartbeatCurrent(db, agent.id, 15);
|
|
230
229
|
|
|
231
230
|
expect(isCurrent).toBe(true);
|
|
232
231
|
});
|
|
233
232
|
|
|
234
|
-
it('should return false for agent with stale heartbeat', () => {
|
|
235
|
-
const agent = createAgent(db, {
|
|
233
|
+
it('should return false for agent with stale heartbeat', async () => {
|
|
234
|
+
const agent = await createAgent(db, {
|
|
236
235
|
type: 'senior',
|
|
237
236
|
teamId,
|
|
238
237
|
});
|
|
239
238
|
|
|
240
239
|
// Set last_seen to 30 seconds ago
|
|
241
240
|
const oldTimestamp = new Date(Date.now() - 30000).toISOString();
|
|
242
|
-
db.run(`UPDATE agents SET last_seen = ? WHERE id = ?`, [oldTimestamp, agent.id]);
|
|
241
|
+
db.db.run(`UPDATE agents SET last_seen = ? WHERE id = ?`, [oldTimestamp, agent.id]);
|
|
243
242
|
|
|
244
|
-
const isCurrent = isAgentHeartbeatCurrent(db, agent.id, 15);
|
|
243
|
+
const isCurrent = await isAgentHeartbeatCurrent(db, agent.id, 15);
|
|
245
244
|
|
|
246
245
|
expect(isCurrent).toBe(false);
|
|
247
246
|
});
|
|
248
247
|
|
|
249
|
-
it('should return false for agent with null last_seen', () => {
|
|
250
|
-
const agent = createAgent(db, {
|
|
248
|
+
it('should return false for agent with null last_seen', async () => {
|
|
249
|
+
const agent = await createAgent(db, {
|
|
251
250
|
type: 'senior',
|
|
252
251
|
teamId,
|
|
253
252
|
});
|
|
254
253
|
|
|
255
254
|
// Set last_seen to null
|
|
256
|
-
db.run(`UPDATE agents SET last_seen = NULL WHERE id = ?`, [agent.id]);
|
|
255
|
+
db.db.run(`UPDATE agents SET last_seen = NULL WHERE id = ?`, [agent.id]);
|
|
257
256
|
|
|
258
|
-
const isCurrent = isAgentHeartbeatCurrent(db, agent.id, 15);
|
|
257
|
+
const isCurrent = await isAgentHeartbeatCurrent(db, agent.id, 15);
|
|
259
258
|
|
|
260
259
|
expect(isCurrent).toBe(false);
|
|
261
260
|
});
|
|
262
261
|
|
|
263
|
-
it('should respect custom timeout', () => {
|
|
264
|
-
const agent = createAgent(db, {
|
|
262
|
+
it('should respect custom timeout', async () => {
|
|
263
|
+
const agent = await createAgent(db, {
|
|
265
264
|
type: 'senior',
|
|
266
265
|
teamId,
|
|
267
266
|
});
|
|
268
267
|
|
|
269
268
|
// Set last_seen to 10 seconds ago
|
|
270
269
|
const timestamp = new Date(Date.now() - 10000).toISOString();
|
|
271
|
-
db.run(`UPDATE agents SET last_seen = ? WHERE id = ?`, [timestamp, agent.id]);
|
|
270
|
+
db.db.run(`UPDATE agents SET last_seen = ? WHERE id = ?`, [timestamp, agent.id]);
|
|
272
271
|
|
|
273
272
|
// With 5 second timeout, should be false
|
|
274
|
-
expect(isAgentHeartbeatCurrent(db, agent.id, 5)).toBe(false);
|
|
273
|
+
expect(await isAgentHeartbeatCurrent(db, agent.id, 5)).toBe(false);
|
|
275
274
|
|
|
276
275
|
// With 20 second timeout, should be true
|
|
277
|
-
expect(isAgentHeartbeatCurrent(db, agent.id, 20)).toBe(true);
|
|
276
|
+
expect(await isAgentHeartbeatCurrent(db, agent.id, 20)).toBe(true);
|
|
278
277
|
});
|
|
279
278
|
|
|
280
|
-
it('should return false for non-existent agent', () => {
|
|
281
|
-
const isCurrent = isAgentHeartbeatCurrent(db, 'non-existent-agent', 15);
|
|
279
|
+
it('should return false for non-existent agent', async () => {
|
|
280
|
+
const isCurrent = await isAgentHeartbeatCurrent(db, 'non-existent-agent', 15);
|
|
282
281
|
expect(isCurrent).toBe(false);
|
|
283
282
|
});
|
|
284
283
|
|
|
285
|
-
it('should use default timeout of 15 seconds', () => {
|
|
286
|
-
const agent = createAgent(db, {
|
|
284
|
+
it('should use default timeout of 15 seconds', async () => {
|
|
285
|
+
const agent = await createAgent(db, {
|
|
287
286
|
type: 'senior',
|
|
288
287
|
teamId,
|
|
289
288
|
});
|
|
290
289
|
|
|
291
|
-
updateAgentHeartbeat(db, agent.id);
|
|
290
|
+
await updateAgentHeartbeat(db, agent.id);
|
|
292
291
|
|
|
293
292
|
// Should use default 15 second timeout
|
|
294
|
-
const isCurrent = isAgentHeartbeatCurrent(db, agent.id);
|
|
293
|
+
const isCurrent = await isAgentHeartbeatCurrent(db, agent.id);
|
|
295
294
|
|
|
296
295
|
expect(isCurrent).toBe(true);
|
|
297
296
|
});
|