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/db/queries/logs.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Licensed under the Hungry Ghost Hive License. See LICENSE.
|
|
2
2
|
|
|
3
|
-
import type
|
|
4
|
-
import {
|
|
3
|
+
import { type AgentLogRow } from '../client.js';
|
|
4
|
+
import type { DatabaseProvider } from '../provider.js';
|
|
5
5
|
|
|
6
6
|
export type { AgentLogRow };
|
|
7
7
|
|
|
@@ -91,23 +91,22 @@ function inferAgentType(
|
|
|
91
91
|
return 'tech_lead';
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
-
function getAgentColumnNames(
|
|
95
|
-
const
|
|
96
|
-
if (result.length === 0) return new Set<string>();
|
|
97
|
-
|
|
94
|
+
async function getAgentColumnNames(provider: DatabaseProvider): Promise<Set<string>> {
|
|
95
|
+
const rows = await provider.queryAll<{ name: string }>('PRAGMA table_info(agents)');
|
|
98
96
|
const columnNames = new Set<string>();
|
|
99
|
-
for (const row of
|
|
100
|
-
|
|
101
|
-
columnNames.add(String(row[1]));
|
|
97
|
+
for (const row of rows) {
|
|
98
|
+
columnNames.add(row.name);
|
|
102
99
|
}
|
|
103
100
|
return columnNames;
|
|
104
101
|
}
|
|
105
102
|
|
|
106
|
-
function ensureLogAgentExists(
|
|
107
|
-
const existing = queryOne<{ id: string }>(
|
|
103
|
+
async function ensureLogAgentExists(provider: DatabaseProvider, agentId: string): Promise<void> {
|
|
104
|
+
const existing = await provider.queryOne<{ id: string }>('SELECT id FROM agents WHERE id = ?', [
|
|
105
|
+
agentId,
|
|
106
|
+
]);
|
|
108
107
|
if (existing?.id) return;
|
|
109
108
|
|
|
110
|
-
const columns = getAgentColumnNames(
|
|
109
|
+
const columns = await getAgentColumnNames(provider);
|
|
111
110
|
const now = new Date().toISOString();
|
|
112
111
|
const insertColumns: string[] = ['id'];
|
|
113
112
|
const insertValues: (string | null)[] = [agentId];
|
|
@@ -134,8 +133,7 @@ function ensureLogAgentExists(db: Database, agentId: string): void {
|
|
|
134
133
|
}
|
|
135
134
|
|
|
136
135
|
const placeholders = insertColumns.map(() => '?').join(', ');
|
|
137
|
-
run(
|
|
138
|
-
db,
|
|
136
|
+
await provider.run(
|
|
139
137
|
`
|
|
140
138
|
INSERT OR IGNORE INTO agents (${insertColumns.join(', ')})
|
|
141
139
|
VALUES (${placeholders})
|
|
@@ -144,17 +142,18 @@ function ensureLogAgentExists(db: Database, agentId: string): void {
|
|
|
144
142
|
);
|
|
145
143
|
}
|
|
146
144
|
|
|
147
|
-
function resolveLogAgentId(
|
|
148
|
-
const direct = queryOne<{ id: string }>(
|
|
145
|
+
async function resolveLogAgentId(provider: DatabaseProvider, rawAgentId: string): Promise<string> {
|
|
146
|
+
const direct = await provider.queryOne<{ id: string }>('SELECT id FROM agents WHERE id = ?', [
|
|
147
|
+
rawAgentId,
|
|
148
|
+
]);
|
|
149
149
|
if (direct?.id) return direct.id;
|
|
150
150
|
|
|
151
|
-
const columns = getAgentColumnNames(
|
|
151
|
+
const columns = await getAgentColumnNames(provider);
|
|
152
152
|
|
|
153
153
|
// Many call-sites provide tmux session names (for example: "hive-qa-team-1").
|
|
154
154
|
// Prefer resolving those back to canonical agent IDs so logs remain linked.
|
|
155
155
|
if (columns.has('tmux_session')) {
|
|
156
|
-
const bySession = queryOne<{ id: string }>(
|
|
157
|
-
db,
|
|
156
|
+
const bySession = await provider.queryOne<{ id: string }>(
|
|
158
157
|
`SELECT id FROM agents WHERE tmux_session = ?${
|
|
159
158
|
columns.has('updated_at') ? ' ORDER BY updated_at DESC' : ''
|
|
160
159
|
} LIMIT 1`,
|
|
@@ -165,24 +164,31 @@ function resolveLogAgentId(db: Database, rawAgentId: string): string {
|
|
|
165
164
|
|
|
166
165
|
// Last resort: create a lightweight synthetic agent row for system/session actors
|
|
167
166
|
// like "manager" or "scheduler" so FK constraints cannot fail logging.
|
|
168
|
-
ensureLogAgentExists(
|
|
167
|
+
await ensureLogAgentExists(provider, rawAgentId);
|
|
169
168
|
return rawAgentId;
|
|
170
169
|
}
|
|
171
170
|
|
|
172
|
-
function resolveLogStoryId(
|
|
171
|
+
async function resolveLogStoryId(
|
|
172
|
+
provider: DatabaseProvider,
|
|
173
|
+
storyId?: string | null
|
|
174
|
+
): Promise<string | null> {
|
|
173
175
|
if (!storyId) return null;
|
|
174
|
-
const story = queryOne<{ id: string }>(
|
|
176
|
+
const story = await provider.queryOne<{ id: string }>('SELECT id FROM stories WHERE id = ?', [
|
|
177
|
+
storyId,
|
|
178
|
+
]);
|
|
175
179
|
return story?.id || null;
|
|
176
180
|
}
|
|
177
181
|
|
|
178
|
-
export function createLog(
|
|
182
|
+
export async function createLog(
|
|
183
|
+
provider: DatabaseProvider,
|
|
184
|
+
input: CreateLogInput
|
|
185
|
+
): Promise<AgentLogRow> {
|
|
179
186
|
const metadata = input.metadata ? JSON.stringify(input.metadata) : null;
|
|
180
187
|
const now = new Date().toISOString();
|
|
181
|
-
const resolvedAgentId = resolveLogAgentId(
|
|
182
|
-
const resolvedStoryId = resolveLogStoryId(
|
|
188
|
+
const resolvedAgentId = await resolveLogAgentId(provider, input.agentId);
|
|
189
|
+
const resolvedStoryId = await resolveLogStoryId(provider, input.storyId);
|
|
183
190
|
|
|
184
|
-
run(
|
|
185
|
-
db,
|
|
191
|
+
await provider.run(
|
|
186
192
|
`
|
|
187
193
|
INSERT INTO agent_logs (agent_id, story_id, event_type, status, message, metadata, timestamp)
|
|
188
194
|
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
@@ -199,17 +205,23 @@ export function createLog(db: Database, input: CreateLogInput): AgentLogRow {
|
|
|
199
205
|
);
|
|
200
206
|
|
|
201
207
|
// Get the last inserted row
|
|
202
|
-
const result = queryOne<{ id: number }>(
|
|
203
|
-
return getLogById(
|
|
208
|
+
const result = await provider.queryOne<{ id: number }>('SELECT last_insert_rowid() as id');
|
|
209
|
+
return (await getLogById(provider, result?.id || 0))!;
|
|
204
210
|
}
|
|
205
211
|
|
|
206
|
-
export function getLogById(
|
|
207
|
-
|
|
212
|
+
export async function getLogById(
|
|
213
|
+
provider: DatabaseProvider,
|
|
214
|
+
id: number
|
|
215
|
+
): Promise<AgentLogRow | undefined> {
|
|
216
|
+
return await provider.queryOne<AgentLogRow>('SELECT * FROM agent_logs WHERE id = ?', [id]);
|
|
208
217
|
}
|
|
209
218
|
|
|
210
|
-
export function getLogsByAgent(
|
|
211
|
-
|
|
212
|
-
|
|
219
|
+
export async function getLogsByAgent(
|
|
220
|
+
provider: DatabaseProvider,
|
|
221
|
+
agentId: string,
|
|
222
|
+
limit = 100
|
|
223
|
+
): Promise<AgentLogRow[]> {
|
|
224
|
+
return await provider.queryAll<AgentLogRow>(
|
|
213
225
|
`
|
|
214
226
|
SELECT * FROM agent_logs
|
|
215
227
|
WHERE agent_id = ?
|
|
@@ -220,9 +232,11 @@ export function getLogsByAgent(db: Database, agentId: string, limit = 100): Agen
|
|
|
220
232
|
);
|
|
221
233
|
}
|
|
222
234
|
|
|
223
|
-
export function getLogsByStory(
|
|
224
|
-
|
|
225
|
-
|
|
235
|
+
export async function getLogsByStory(
|
|
236
|
+
provider: DatabaseProvider,
|
|
237
|
+
storyId: string
|
|
238
|
+
): Promise<AgentLogRow[]> {
|
|
239
|
+
return await provider.queryAll<AgentLogRow>(
|
|
226
240
|
`
|
|
227
241
|
SELECT * FROM agent_logs
|
|
228
242
|
WHERE story_id = ?
|
|
@@ -232,9 +246,12 @@ export function getLogsByStory(db: Database, storyId: string): AgentLogRow[] {
|
|
|
232
246
|
);
|
|
233
247
|
}
|
|
234
248
|
|
|
235
|
-
export function getLogsByEventType(
|
|
236
|
-
|
|
237
|
-
|
|
249
|
+
export async function getLogsByEventType(
|
|
250
|
+
provider: DatabaseProvider,
|
|
251
|
+
eventType: EventType,
|
|
252
|
+
limit = 100
|
|
253
|
+
): Promise<AgentLogRow[]> {
|
|
254
|
+
return await provider.queryAll<AgentLogRow>(
|
|
238
255
|
`
|
|
239
256
|
SELECT * FROM agent_logs
|
|
240
257
|
WHERE event_type = ?
|
|
@@ -245,9 +262,11 @@ export function getLogsByEventType(db: Database, eventType: EventType, limit = 1
|
|
|
245
262
|
);
|
|
246
263
|
}
|
|
247
264
|
|
|
248
|
-
export function getRecentLogs(
|
|
249
|
-
|
|
250
|
-
|
|
265
|
+
export async function getRecentLogs(
|
|
266
|
+
provider: DatabaseProvider,
|
|
267
|
+
limit = 50
|
|
268
|
+
): Promise<AgentLogRow[]> {
|
|
269
|
+
return await provider.queryAll<AgentLogRow>(
|
|
251
270
|
`
|
|
252
271
|
SELECT * FROM agent_logs
|
|
253
272
|
ORDER BY timestamp DESC
|
|
@@ -257,9 +276,11 @@ export function getRecentLogs(db: Database, limit = 50): AgentLogRow[] {
|
|
|
257
276
|
);
|
|
258
277
|
}
|
|
259
278
|
|
|
260
|
-
export function getLogsSince(
|
|
261
|
-
|
|
262
|
-
|
|
279
|
+
export async function getLogsSince(
|
|
280
|
+
provider: DatabaseProvider,
|
|
281
|
+
since: string
|
|
282
|
+
): Promise<AgentLogRow[]> {
|
|
283
|
+
return await provider.queryAll<AgentLogRow>(
|
|
263
284
|
`
|
|
264
285
|
SELECT * FROM agent_logs
|
|
265
286
|
WHERE timestamp > ?
|
|
@@ -269,9 +290,11 @@ export function getLogsSince(db: Database, since: string): AgentLogRow[] {
|
|
|
269
290
|
);
|
|
270
291
|
}
|
|
271
292
|
|
|
272
|
-
export function countQaFailuresByStory(
|
|
273
|
-
|
|
274
|
-
|
|
293
|
+
export async function countQaFailuresByStory(
|
|
294
|
+
provider: DatabaseProvider,
|
|
295
|
+
storyId: string
|
|
296
|
+
): Promise<number> {
|
|
297
|
+
const result = await provider.queryOne<{ count: number }>(
|
|
275
298
|
`
|
|
276
299
|
SELECT COUNT(*) as count
|
|
277
300
|
FROM agent_logs
|
|
@@ -282,21 +305,23 @@ export function countQaFailuresByStory(db: Database, storyId: string): number {
|
|
|
282
305
|
return result?.count || 0;
|
|
283
306
|
}
|
|
284
307
|
|
|
285
|
-
export function pruneOldLogs(
|
|
308
|
+
export async function pruneOldLogs(
|
|
309
|
+
provider: DatabaseProvider,
|
|
310
|
+
retentionDays: number
|
|
311
|
+
): Promise<number> {
|
|
286
312
|
const cutoffDate = new Date();
|
|
287
313
|
cutoffDate.setDate(cutoffDate.getDate() - retentionDays);
|
|
288
314
|
const cutoff = cutoffDate.toISOString();
|
|
289
315
|
|
|
290
316
|
// Get count before delete
|
|
291
|
-
const before = queryOne<{ count: number }>(
|
|
292
|
-
db,
|
|
317
|
+
const before = await provider.queryOne<{ count: number }>(
|
|
293
318
|
`
|
|
294
319
|
SELECT COUNT(*) as count FROM agent_logs WHERE timestamp < ?
|
|
295
320
|
`,
|
|
296
321
|
[cutoff]
|
|
297
322
|
);
|
|
298
323
|
|
|
299
|
-
run(
|
|
324
|
+
await provider.run(`DELETE FROM agent_logs WHERE timestamp < ?`, [cutoff]);
|
|
300
325
|
|
|
301
326
|
return before?.count || 0;
|
|
302
327
|
}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
// Licensed under the Hungry Ghost Hive License. See LICENSE.
|
|
2
2
|
|
|
3
|
-
import type { Database } from 'sql.js';
|
|
4
3
|
import { beforeEach, describe, expect, it } from 'vitest';
|
|
5
|
-
import {
|
|
4
|
+
import { SqliteProvider } from '../provider.js';
|
|
6
5
|
import {
|
|
7
6
|
getAllPendingMessages,
|
|
8
7
|
getMessageById,
|
|
@@ -12,10 +11,11 @@ import {
|
|
|
12
11
|
import { createTestDatabase } from './test-helpers.js';
|
|
13
12
|
|
|
14
13
|
describe('messages queries', () => {
|
|
15
|
-
let db:
|
|
14
|
+
let db: SqliteProvider;
|
|
16
15
|
|
|
17
16
|
beforeEach(async () => {
|
|
18
|
-
|
|
17
|
+
const rawDb = await createTestDatabase();
|
|
18
|
+
db = new SqliteProvider(rawDb);
|
|
19
19
|
});
|
|
20
20
|
|
|
21
21
|
// Helper function to create a test message
|
|
@@ -28,8 +28,7 @@ describe('messages queries', () => {
|
|
|
28
28
|
subject?: string | null
|
|
29
29
|
): void {
|
|
30
30
|
const now = new Date().toISOString();
|
|
31
|
-
run(
|
|
32
|
-
db,
|
|
31
|
+
db.db.run(
|
|
33
32
|
`
|
|
34
33
|
INSERT INTO messages (id, from_session, to_session, subject, body, status, created_at)
|
|
35
34
|
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
@@ -39,12 +38,12 @@ describe('messages queries', () => {
|
|
|
39
38
|
}
|
|
40
39
|
|
|
41
40
|
describe('getUnreadMessages', () => {
|
|
42
|
-
it('should return unread messages for a session', () => {
|
|
41
|
+
it('should return unread messages for a session', async () => {
|
|
43
42
|
createMessage('msg1', 'session-a', 'session-b', 'Message 1', 'pending');
|
|
44
43
|
createMessage('msg2', 'session-a', 'session-b', 'Message 2', 'pending');
|
|
45
44
|
createMessage('msg3', 'session-a', 'session-b', 'Message 3', 'read');
|
|
46
45
|
|
|
47
|
-
const unread = getUnreadMessages(db, 'session-b');
|
|
46
|
+
const unread = await getUnreadMessages(db, 'session-b');
|
|
48
47
|
|
|
49
48
|
expect(unread).toHaveLength(2);
|
|
50
49
|
expect(unread.map(m => m.id)).toContain('msg1');
|
|
@@ -52,21 +51,21 @@ describe('messages queries', () => {
|
|
|
52
51
|
expect(unread.map(m => m.id)).not.toContain('msg3');
|
|
53
52
|
});
|
|
54
53
|
|
|
55
|
-
it('should return empty array when no unread messages', () => {
|
|
54
|
+
it('should return empty array when no unread messages', async () => {
|
|
56
55
|
createMessage('msg1', 'session-a', 'session-b', 'Message 1', 'read');
|
|
57
56
|
|
|
58
|
-
const unread = getUnreadMessages(db, 'session-b');
|
|
57
|
+
const unread = await getUnreadMessages(db, 'session-b');
|
|
59
58
|
|
|
60
59
|
expect(unread).toEqual([]);
|
|
61
60
|
});
|
|
62
61
|
|
|
63
|
-
it('should order messages by created_at ASC', () => {
|
|
62
|
+
it('should order messages by created_at ASC', async () => {
|
|
64
63
|
// Create messages with slight delays to ensure ordering
|
|
65
64
|
createMessage('msg1', 'session-a', 'session-b', 'First', 'pending');
|
|
66
65
|
createMessage('msg2', 'session-a', 'session-b', 'Second', 'pending');
|
|
67
66
|
createMessage('msg3', 'session-a', 'session-b', 'Third', 'pending');
|
|
68
67
|
|
|
69
|
-
const unread = getUnreadMessages(db, 'session-b');
|
|
68
|
+
const unread = await getUnreadMessages(db, 'session-b');
|
|
70
69
|
|
|
71
70
|
expect(unread).toHaveLength(3);
|
|
72
71
|
expect(unread[0].id).toBe('msg1');
|
|
@@ -74,12 +73,12 @@ describe('messages queries', () => {
|
|
|
74
73
|
expect(unread[2].id).toBe('msg3');
|
|
75
74
|
});
|
|
76
75
|
|
|
77
|
-
it('should filter by recipient session', () => {
|
|
76
|
+
it('should filter by recipient session', async () => {
|
|
78
77
|
createMessage('msg1', 'session-a', 'session-b', 'For B', 'pending');
|
|
79
78
|
createMessage('msg2', 'session-a', 'session-c', 'For C', 'pending');
|
|
80
79
|
|
|
81
|
-
const unreadB = getUnreadMessages(db, 'session-b');
|
|
82
|
-
const unreadC = getUnreadMessages(db, 'session-c');
|
|
80
|
+
const unreadB = await getUnreadMessages(db, 'session-b');
|
|
81
|
+
const unreadC = await getUnreadMessages(db, 'session-c');
|
|
83
82
|
|
|
84
83
|
expect(unreadB).toHaveLength(1);
|
|
85
84
|
expect(unreadB[0].id).toBe('msg1');
|
|
@@ -89,43 +88,43 @@ describe('messages queries', () => {
|
|
|
89
88
|
});
|
|
90
89
|
|
|
91
90
|
describe('markMessageRead', () => {
|
|
92
|
-
it('should mark a pending message as read', () => {
|
|
91
|
+
it('should mark a pending message as read', async () => {
|
|
93
92
|
createMessage('msg1', 'session-a', 'session-b', 'Message', 'pending');
|
|
94
93
|
|
|
95
|
-
markMessageRead(db, 'msg1');
|
|
94
|
+
await markMessageRead(db, 'msg1');
|
|
96
95
|
|
|
97
|
-
const message = getMessageById(db, 'msg1');
|
|
96
|
+
const message = await getMessageById(db, 'msg1');
|
|
98
97
|
expect(message?.status).toBe('read');
|
|
99
98
|
});
|
|
100
99
|
|
|
101
|
-
it('should not affect already read messages', () => {
|
|
100
|
+
it('should not affect already read messages', async () => {
|
|
102
101
|
createMessage('msg1', 'session-a', 'session-b', 'Message', 'read');
|
|
103
102
|
|
|
104
|
-
markMessageRead(db, 'msg1');
|
|
103
|
+
await markMessageRead(db, 'msg1');
|
|
105
104
|
|
|
106
|
-
const message = getMessageById(db, 'msg1');
|
|
105
|
+
const message = await getMessageById(db, 'msg1');
|
|
107
106
|
expect(message?.status).toBe('read');
|
|
108
107
|
});
|
|
109
108
|
|
|
110
|
-
it('should not affect replied messages', () => {
|
|
109
|
+
it('should not affect replied messages', async () => {
|
|
111
110
|
createMessage('msg1', 'session-a', 'session-b', 'Message', 'replied');
|
|
112
111
|
|
|
113
|
-
markMessageRead(db, 'msg1');
|
|
112
|
+
await markMessageRead(db, 'msg1');
|
|
114
113
|
|
|
115
|
-
const message = getMessageById(db, 'msg1');
|
|
114
|
+
const message = await getMessageById(db, 'msg1');
|
|
116
115
|
expect(message?.status).toBe('replied');
|
|
117
116
|
});
|
|
118
117
|
|
|
119
|
-
it('should not throw for non-existent message', () => {
|
|
120
|
-
expect(
|
|
118
|
+
it('should not throw for non-existent message', async () => {
|
|
119
|
+
await expect(markMessageRead(db, 'non-existent-id')).resolves.not.toThrow();
|
|
121
120
|
});
|
|
122
121
|
});
|
|
123
122
|
|
|
124
123
|
describe('getMessageById', () => {
|
|
125
|
-
it('should retrieve a message by ID', () => {
|
|
124
|
+
it('should retrieve a message by ID', async () => {
|
|
126
125
|
createMessage('msg1', 'session-a', 'session-b', 'Test message', 'pending', 'Test subject');
|
|
127
126
|
|
|
128
|
-
const message = getMessageById(db, 'msg1');
|
|
127
|
+
const message = await getMessageById(db, 'msg1');
|
|
129
128
|
|
|
130
129
|
expect(message).toBeDefined();
|
|
131
130
|
expect(message?.id).toBe('msg1');
|
|
@@ -136,15 +135,15 @@ describe('messages queries', () => {
|
|
|
136
135
|
expect(message?.status).toBe('pending');
|
|
137
136
|
});
|
|
138
137
|
|
|
139
|
-
it('should return undefined for non-existent message', () => {
|
|
140
|
-
const message = getMessageById(db, 'non-existent-id');
|
|
138
|
+
it('should return undefined for non-existent message', async () => {
|
|
139
|
+
const message = await getMessageById(db, 'non-existent-id');
|
|
141
140
|
expect(message).toBeUndefined();
|
|
142
141
|
});
|
|
143
142
|
|
|
144
|
-
it('should handle messages without subject', () => {
|
|
143
|
+
it('should handle messages without subject', async () => {
|
|
145
144
|
createMessage('msg1', 'session-a', 'session-b', 'Message without subject', 'pending');
|
|
146
145
|
|
|
147
|
-
const message = getMessageById(db, 'msg1');
|
|
146
|
+
const message = await getMessageById(db, 'msg1');
|
|
148
147
|
|
|
149
148
|
expect(message?.subject).toBeNull();
|
|
150
149
|
expect(message?.body).toBe('Message without subject');
|
|
@@ -152,32 +151,32 @@ describe('messages queries', () => {
|
|
|
152
151
|
});
|
|
153
152
|
|
|
154
153
|
describe('getAllPendingMessages', () => {
|
|
155
|
-
it('should return all pending messages across all sessions', () => {
|
|
154
|
+
it('should return all pending messages across all sessions', async () => {
|
|
156
155
|
createMessage('msg1', 'session-a', 'session-b', 'Message 1', 'pending');
|
|
157
156
|
createMessage('msg2', 'session-b', 'session-c', 'Message 2', 'pending');
|
|
158
157
|
createMessage('msg3', 'session-c', 'session-a', 'Message 3', 'read');
|
|
159
158
|
createMessage('msg4', 'session-a', 'session-d', 'Message 4', 'replied');
|
|
160
159
|
|
|
161
|
-
const pending = getAllPendingMessages(db);
|
|
160
|
+
const pending = await getAllPendingMessages(db);
|
|
162
161
|
|
|
163
162
|
expect(pending).toHaveLength(2);
|
|
164
163
|
expect(pending.map(m => m.id)).toContain('msg1');
|
|
165
164
|
expect(pending.map(m => m.id)).toContain('msg2');
|
|
166
165
|
});
|
|
167
166
|
|
|
168
|
-
it('should return empty array when no pending messages', () => {
|
|
167
|
+
it('should return empty array when no pending messages', async () => {
|
|
169
168
|
createMessage('msg1', 'session-a', 'session-b', 'Message', 'read');
|
|
170
169
|
|
|
171
|
-
const pending = getAllPendingMessages(db);
|
|
170
|
+
const pending = await getAllPendingMessages(db);
|
|
172
171
|
|
|
173
172
|
expect(pending).toEqual([]);
|
|
174
173
|
});
|
|
175
174
|
|
|
176
|
-
it('should order by created_at ASC', () => {
|
|
175
|
+
it('should order by created_at ASC', async () => {
|
|
177
176
|
createMessage('msg1', 'session-a', 'session-b', 'First', 'pending');
|
|
178
177
|
createMessage('msg2', 'session-a', 'session-b', 'Second', 'pending');
|
|
179
178
|
|
|
180
|
-
const pending = getAllPendingMessages(db);
|
|
179
|
+
const pending = await getAllPendingMessages(db);
|
|
181
180
|
|
|
182
181
|
expect(pending[0].id).toBe('msg1');
|
|
183
182
|
expect(pending[1].id).toBe('msg2');
|
|
@@ -185,31 +184,31 @@ describe('messages queries', () => {
|
|
|
185
184
|
});
|
|
186
185
|
|
|
187
186
|
describe('edge cases', () => {
|
|
188
|
-
it('should handle messages with null subject', () => {
|
|
187
|
+
it('should handle messages with null subject', async () => {
|
|
189
188
|
createMessage('msg1', 'session-a', 'session-b', 'Body text', 'pending', null);
|
|
190
189
|
|
|
191
|
-
const message = getMessageById(db, 'msg1');
|
|
190
|
+
const message = await getMessageById(db, 'msg1');
|
|
192
191
|
expect(message?.subject).toBeNull();
|
|
193
192
|
expect(message?.body).toBe('Body text');
|
|
194
193
|
});
|
|
195
194
|
|
|
196
|
-
it('should handle messages with very long body text', () => {
|
|
195
|
+
it('should handle messages with very long body text', async () => {
|
|
197
196
|
const longBody = 'A'.repeat(50000);
|
|
198
197
|
createMessage('msg1', 'session-a', 'session-b', longBody, 'pending');
|
|
199
198
|
|
|
200
|
-
const message = getMessageById(db, 'msg1');
|
|
199
|
+
const message = await getMessageById(db, 'msg1');
|
|
201
200
|
expect(message?.body).toBe(longBody);
|
|
202
201
|
});
|
|
203
202
|
|
|
204
|
-
it('should handle special characters in message content', () => {
|
|
203
|
+
it('should handle special characters in message content', async () => {
|
|
205
204
|
const specialBody = 'Message with \'quotes\' "double" and\nnewlines\ttabs';
|
|
206
205
|
createMessage('msg1', 'session-a', 'session-b', specialBody, 'pending', 'Special chars');
|
|
207
206
|
|
|
208
|
-
const message = getMessageById(db, 'msg1');
|
|
207
|
+
const message = await getMessageById(db, 'msg1');
|
|
209
208
|
expect(message?.body).toBe(specialBody);
|
|
210
209
|
});
|
|
211
210
|
|
|
212
|
-
it('should handle session names with special characters', () => {
|
|
211
|
+
it('should handle session names with special characters', async () => {
|
|
213
212
|
createMessage(
|
|
214
213
|
'msg1',
|
|
215
214
|
'session-with-dashes',
|
|
@@ -218,15 +217,14 @@ describe('messages queries', () => {
|
|
|
218
217
|
'pending'
|
|
219
218
|
);
|
|
220
219
|
|
|
221
|
-
const unread = getUnreadMessages(db, 'session_with_underscores');
|
|
220
|
+
const unread = await getUnreadMessages(db, 'session_with_underscores');
|
|
222
221
|
expect(unread).toHaveLength(1);
|
|
223
222
|
expect(unread[0].from_session).toBe('session-with-dashes');
|
|
224
223
|
});
|
|
225
224
|
|
|
226
|
-
it('should handle reply and replied_at fields', () => {
|
|
225
|
+
it('should handle reply and replied_at fields', async () => {
|
|
227
226
|
const now = new Date().toISOString();
|
|
228
|
-
run(
|
|
229
|
-
db,
|
|
227
|
+
db.db.run(
|
|
230
228
|
`
|
|
231
229
|
INSERT INTO messages (id, from_session, to_session, body, status, reply, replied_at, created_at)
|
|
232
230
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
@@ -234,7 +232,7 @@ describe('messages queries', () => {
|
|
|
234
232
|
['msg1', 'session-a', 'session-b', 'Original message', 'replied', 'Reply text', now, now]
|
|
235
233
|
);
|
|
236
234
|
|
|
237
|
-
const message = getMessageById(db, 'msg1');
|
|
235
|
+
const message = await getMessageById(db, 'msg1');
|
|
238
236
|
expect(message?.status).toBe('replied');
|
|
239
237
|
expect(message?.reply).toBe('Reply text');
|
|
240
238
|
expect(message?.replied_at).toBeDefined();
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// Licensed under the Hungry Ghost Hive License. See LICENSE.
|
|
2
2
|
|
|
3
|
-
import type {
|
|
4
|
-
import { queryAll, queryOne, run } from '../client.js';
|
|
3
|
+
import type { DatabaseProvider } from '../provider.js';
|
|
5
4
|
|
|
6
5
|
export interface MessageRow {
|
|
7
6
|
id: string;
|
|
@@ -15,9 +14,11 @@ export interface MessageRow {
|
|
|
15
14
|
replied_at: string | null;
|
|
16
15
|
}
|
|
17
16
|
|
|
18
|
-
export function getUnreadMessages(
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
export async function getUnreadMessages(
|
|
18
|
+
provider: DatabaseProvider,
|
|
19
|
+
toSession: string
|
|
20
|
+
): Promise<MessageRow[]> {
|
|
21
|
+
return await provider.queryAll<MessageRow>(
|
|
21
22
|
`
|
|
22
23
|
SELECT * FROM messages
|
|
23
24
|
WHERE to_session = ? AND status = 'pending'
|
|
@@ -27,31 +28,38 @@ export function getUnreadMessages(db: Database, toSession: string): MessageRow[]
|
|
|
27
28
|
);
|
|
28
29
|
}
|
|
29
30
|
|
|
30
|
-
export function markMessageRead(
|
|
31
|
-
|
|
31
|
+
export async function markMessageRead(
|
|
32
|
+
provider: DatabaseProvider,
|
|
33
|
+
messageId: string
|
|
34
|
+
): Promise<void> {
|
|
35
|
+
await provider.run(`UPDATE messages SET status = 'read' WHERE id = ? AND status = 'pending'`, [
|
|
36
|
+
messageId,
|
|
37
|
+
]);
|
|
32
38
|
}
|
|
33
39
|
|
|
34
|
-
export function markMessagesRead(
|
|
40
|
+
export async function markMessagesRead(
|
|
41
|
+
provider: DatabaseProvider,
|
|
42
|
+
messageIds: string[]
|
|
43
|
+
): Promise<void> {
|
|
35
44
|
if (messageIds.length === 0) return;
|
|
36
45
|
const placeholders = messageIds.map(() => '?').join(',');
|
|
37
|
-
run(
|
|
38
|
-
db,
|
|
46
|
+
await provider.run(
|
|
39
47
|
`UPDATE messages SET status = 'read' WHERE id IN (${placeholders}) AND status = 'pending'`,
|
|
40
48
|
messageIds
|
|
41
49
|
);
|
|
42
50
|
}
|
|
43
51
|
|
|
44
|
-
export function getMessageById(
|
|
45
|
-
|
|
52
|
+
export async function getMessageById(
|
|
53
|
+
provider: DatabaseProvider,
|
|
54
|
+
id: string
|
|
55
|
+
): Promise<MessageRow | undefined> {
|
|
56
|
+
return await provider.queryOne<MessageRow>('SELECT * FROM messages WHERE id = ?', [id]);
|
|
46
57
|
}
|
|
47
58
|
|
|
48
|
-
export function getAllPendingMessages(
|
|
49
|
-
return queryAll<MessageRow>(
|
|
50
|
-
db,
|
|
51
|
-
`
|
|
59
|
+
export async function getAllPendingMessages(provider: DatabaseProvider): Promise<MessageRow[]> {
|
|
60
|
+
return await provider.queryAll<MessageRow>(`
|
|
52
61
|
SELECT * FROM messages
|
|
53
62
|
WHERE status = 'pending'
|
|
54
63
|
ORDER BY created_at ASC
|
|
55
|
-
`
|
|
56
|
-
);
|
|
64
|
+
`);
|
|
57
65
|
}
|