hungry-ghost-hive 0.3.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/LICENSE +111 -0
- package/README.md +352 -0
- package/dist/agents/base-agent.d.ts +63 -0
- package/dist/agents/base-agent.d.ts.map +1 -0
- package/dist/agents/base-agent.js +189 -0
- package/dist/agents/base-agent.js.map +1 -0
- package/dist/agents/index.d.ts +7 -0
- package/dist/agents/index.d.ts.map +1 -0
- package/dist/agents/index.js +7 -0
- package/dist/agents/index.js.map +1 -0
- package/dist/agents/intermediate.d.ts +15 -0
- package/dist/agents/intermediate.d.ts.map +1 -0
- package/dist/agents/intermediate.js +142 -0
- package/dist/agents/intermediate.js.map +1 -0
- package/dist/agents/junior.d.ts +15 -0
- package/dist/agents/junior.d.ts.map +1 -0
- package/dist/agents/junior.js +147 -0
- package/dist/agents/junior.js.map +1 -0
- package/dist/agents/qa.d.ts +23 -0
- package/dist/agents/qa.d.ts.map +1 -0
- package/dist/agents/qa.js +238 -0
- package/dist/agents/qa.js.map +1 -0
- package/dist/agents/senior.d.ts +18 -0
- package/dist/agents/senior.d.ts.map +1 -0
- package/dist/agents/senior.js +267 -0
- package/dist/agents/senior.js.map +1 -0
- package/dist/agents/tech-lead.d.ts +17 -0
- package/dist/agents/tech-lead.d.ts.map +1 -0
- package/dist/agents/tech-lead.js +274 -0
- package/dist/agents/tech-lead.js.map +1 -0
- package/dist/cli/commands/add-repo.d.ts +3 -0
- package/dist/cli/commands/add-repo.d.ts.map +1 -0
- package/dist/cli/commands/add-repo.js +84 -0
- package/dist/cli/commands/add-repo.js.map +1 -0
- package/dist/cli/commands/agents.d.ts +3 -0
- package/dist/cli/commands/agents.d.ts.map +1 -0
- package/dist/cli/commands/agents.js +214 -0
- package/dist/cli/commands/agents.js.map +1 -0
- package/dist/cli/commands/assign.d.ts +3 -0
- package/dist/cli/commands/assign.d.ts.map +1 -0
- package/dist/cli/commands/assign.js +81 -0
- package/dist/cli/commands/assign.js.map +1 -0
- package/dist/cli/commands/config.d.ts +3 -0
- package/dist/cli/commands/config.d.ts.map +1 -0
- package/dist/cli/commands/config.js +118 -0
- package/dist/cli/commands/config.js.map +1 -0
- package/dist/cli/commands/escalations.d.ts +3 -0
- package/dist/cli/commands/escalations.d.ts.map +1 -0
- package/dist/cli/commands/escalations.js +157 -0
- package/dist/cli/commands/escalations.js.map +1 -0
- package/dist/cli/commands/index.d.ts +17 -0
- package/dist/cli/commands/index.d.ts.map +1 -0
- package/dist/cli/commands/index.js +17 -0
- package/dist/cli/commands/index.js.map +1 -0
- package/dist/cli/commands/init.d.ts +3 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +59 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/manager.d.ts +3 -0
- package/dist/cli/commands/manager.d.ts.map +1 -0
- package/dist/cli/commands/manager.js +775 -0
- package/dist/cli/commands/manager.js.map +1 -0
- package/dist/cli/commands/manager.test.d.ts +2 -0
- package/dist/cli/commands/manager.test.d.ts.map +1 -0
- package/dist/cli/commands/manager.test.js +45 -0
- package/dist/cli/commands/manager.test.js.map +1 -0
- package/dist/cli/commands/msg.d.ts +3 -0
- package/dist/cli/commands/msg.d.ts.map +1 -0
- package/dist/cli/commands/msg.js +190 -0
- package/dist/cli/commands/msg.js.map +1 -0
- package/dist/cli/commands/my-stories.d.ts +3 -0
- package/dist/cli/commands/my-stories.d.ts.map +1 -0
- package/dist/cli/commands/my-stories.js +174 -0
- package/dist/cli/commands/my-stories.js.map +1 -0
- package/dist/cli/commands/nuke.d.ts +3 -0
- package/dist/cli/commands/nuke.d.ts.map +1 -0
- package/dist/cli/commands/nuke.js +189 -0
- package/dist/cli/commands/nuke.js.map +1 -0
- package/dist/cli/commands/pr.d.ts +3 -0
- package/dist/cli/commands/pr.d.ts.map +1 -0
- package/dist/cli/commands/pr.js +488 -0
- package/dist/cli/commands/pr.js.map +1 -0
- package/dist/cli/commands/req.d.ts +3 -0
- package/dist/cli/commands/req.d.ts.map +1 -0
- package/dist/cli/commands/req.js +212 -0
- package/dist/cli/commands/req.js.map +1 -0
- package/dist/cli/commands/resume.d.ts +3 -0
- package/dist/cli/commands/resume.d.ts.map +1 -0
- package/dist/cli/commands/resume.js +114 -0
- package/dist/cli/commands/resume.js.map +1 -0
- package/dist/cli/commands/status.d.ts +3 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +259 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/commands/stories.d.ts +3 -0
- package/dist/cli/commands/stories.d.ts.map +1 -0
- package/dist/cli/commands/stories.js +111 -0
- package/dist/cli/commands/stories.js.map +1 -0
- package/dist/cli/commands/teams.d.ts +3 -0
- package/dist/cli/commands/teams.d.ts.map +1 -0
- package/dist/cli/commands/teams.js +137 -0
- package/dist/cli/commands/teams.js.map +1 -0
- package/dist/cli/dashboard/index.d.ts +5 -0
- package/dist/cli/dashboard/index.d.ts.map +1 -0
- package/dist/cli/dashboard/index.js +128 -0
- package/dist/cli/dashboard/index.js.map +1 -0
- package/dist/cli/dashboard/panels/activity.d.ts +5 -0
- package/dist/cli/dashboard/panels/activity.d.ts.map +1 -0
- package/dist/cli/dashboard/panels/activity.js +64 -0
- package/dist/cli/dashboard/panels/activity.js.map +1 -0
- package/dist/cli/dashboard/panels/agents.d.ts +5 -0
- package/dist/cli/dashboard/panels/agents.d.ts.map +1 -0
- package/dist/cli/dashboard/panels/agents.js +196 -0
- package/dist/cli/dashboard/panels/agents.js.map +1 -0
- package/dist/cli/dashboard/panels/escalations.d.ts +5 -0
- package/dist/cli/dashboard/panels/escalations.d.ts.map +1 -0
- package/dist/cli/dashboard/panels/escalations.js +93 -0
- package/dist/cli/dashboard/panels/escalations.js.map +1 -0
- package/dist/cli/dashboard/panels/merge-queue.d.ts +5 -0
- package/dist/cli/dashboard/panels/merge-queue.d.ts.map +1 -0
- package/dist/cli/dashboard/panels/merge-queue.js +57 -0
- package/dist/cli/dashboard/panels/merge-queue.js.map +1 -0
- package/dist/cli/dashboard/panels/pipeline.d.ts +5 -0
- package/dist/cli/dashboard/panels/pipeline.d.ts.map +1 -0
- package/dist/cli/dashboard/panels/pipeline.js +54 -0
- package/dist/cli/dashboard/panels/pipeline.js.map +1 -0
- package/dist/cli/dashboard/panels/stories.d.ts +5 -0
- package/dist/cli/dashboard/panels/stories.d.ts.map +1 -0
- package/dist/cli/dashboard/panels/stories.js +79 -0
- package/dist/cli/dashboard/panels/stories.js.map +1 -0
- package/dist/cli-runtimes/claude.d.ts +8 -0
- package/dist/cli-runtimes/claude.d.ts.map +1 -0
- package/dist/cli-runtimes/claude.js +27 -0
- package/dist/cli-runtimes/claude.js.map +1 -0
- package/dist/cli-runtimes/codex.d.ts +8 -0
- package/dist/cli-runtimes/codex.d.ts.map +1 -0
- package/dist/cli-runtimes/codex.js +27 -0
- package/dist/cli-runtimes/codex.js.map +1 -0
- package/dist/cli-runtimes/gemini.d.ts +8 -0
- package/dist/cli-runtimes/gemini.d.ts.map +1 -0
- package/dist/cli-runtimes/gemini.js +29 -0
- package/dist/cli-runtimes/gemini.js.map +1 -0
- package/dist/cli-runtimes/index.d.ts +25 -0
- package/dist/cli-runtimes/index.d.ts.map +1 -0
- package/dist/cli-runtimes/index.js +48 -0
- package/dist/cli-runtimes/index.js.map +1 -0
- package/dist/cli-runtimes/index.test.d.ts +2 -0
- package/dist/cli-runtimes/index.test.d.ts.map +1 -0
- package/dist/cli-runtimes/index.test.js +216 -0
- package/dist/cli-runtimes/index.test.js.map +1 -0
- package/dist/cli-runtimes/types.d.ts +27 -0
- package/dist/cli-runtimes/types.d.ts.map +1 -0
- package/dist/cli-runtimes/types.js +2 -0
- package/dist/cli-runtimes/types.js.map +1 -0
- package/dist/config/index.d.ts +3 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +3 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/loader.d.ts +11 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +72 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/schema.d.ts +660 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +217 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/config/schema.test.d.ts +2 -0
- package/dist/config/schema.test.d.ts.map +1 -0
- package/dist/config/schema.test.js +123 -0
- package/dist/config/schema.test.js.map +1 -0
- package/dist/context-files/generator.d.ts +32 -0
- package/dist/context-files/generator.d.ts.map +1 -0
- package/dist/context-files/generator.js +120 -0
- package/dist/context-files/generator.js.map +1 -0
- package/dist/context-files/index.d.ts +38 -0
- package/dist/context-files/index.d.ts.map +1 -0
- package/dist/context-files/index.js +76 -0
- package/dist/context-files/index.js.map +1 -0
- package/dist/context-files/index.test.d.ts +2 -0
- package/dist/context-files/index.test.d.ts.map +1 -0
- package/dist/context-files/index.test.js +265 -0
- package/dist/context-files/index.test.js.map +1 -0
- package/dist/context-files/templates.d.ts +19 -0
- package/dist/context-files/templates.d.ts.map +1 -0
- package/dist/context-files/templates.js +266 -0
- package/dist/context-files/templates.js.map +1 -0
- package/dist/db/client.d.ts +95 -0
- package/dist/db/client.d.ts.map +1 -0
- package/dist/db/client.js +343 -0
- package/dist/db/client.js.map +1 -0
- package/dist/db/lock.d.ts +25 -0
- package/dist/db/lock.d.ts.map +1 -0
- package/dist/db/lock.js +56 -0
- package/dist/db/lock.js.map +1 -0
- package/dist/db/lock.test.d.ts +2 -0
- package/dist/db/lock.test.d.ts.map +1 -0
- package/dist/db/lock.test.js +73 -0
- package/dist/db/lock.test.js.map +1 -0
- package/dist/db/queries/agents.d.ts +31 -0
- package/dist/db/queries/agents.d.ts.map +1 -0
- package/dist/db/queries/agents.js +76 -0
- package/dist/db/queries/agents.js.map +1 -0
- package/dist/db/queries/escalations.d.ts +29 -0
- package/dist/db/queries/escalations.d.ts.map +1 -0
- package/dist/db/queries/escalations.js +105 -0
- package/dist/db/queries/escalations.js.map +1 -0
- package/dist/db/queries/heartbeat.d.ts +20 -0
- package/dist/db/queries/heartbeat.d.ts.map +1 -0
- package/dist/db/queries/heartbeat.js +61 -0
- package/dist/db/queries/heartbeat.js.map +1 -0
- package/dist/db/queries/index.d.ts +8 -0
- package/dist/db/queries/index.d.ts.map +1 -0
- package/dist/db/queries/index.js +8 -0
- package/dist/db/queries/index.js.map +1 -0
- package/dist/db/queries/logs.d.ts +21 -0
- package/dist/db/queries/logs.d.ts.map +1 -0
- package/dist/db/queries/logs.js +72 -0
- package/dist/db/queries/logs.js.map +1 -0
- package/dist/db/queries/messages.d.ts +17 -0
- package/dist/db/queries/messages.d.ts.map +1 -0
- package/dist/db/queries/messages.js +22 -0
- package/dist/db/queries/messages.js.map +1 -0
- package/dist/db/queries/pull-requests.d.ts +33 -0
- package/dist/db/queries/pull-requests.d.ts.map +1 -0
- package/dist/db/queries/pull-requests.js +130 -0
- package/dist/db/queries/pull-requests.js.map +1 -0
- package/dist/db/queries/requirements.d.ts +22 -0
- package/dist/db/queries/requirements.d.ts.map +1 -0
- package/dist/db/queries/requirements.js +53 -0
- package/dist/db/queries/requirements.js.map +1 -0
- package/dist/db/queries/stories.d.ts +42 -0
- package/dist/db/queries/stories.d.ts.map +1 -0
- package/dist/db/queries/stories.js +163 -0
- package/dist/db/queries/stories.js.map +1 -0
- package/dist/db/queries/teams.d.ts +14 -0
- package/dist/db/queries/teams.d.ts.map +1 -0
- package/dist/db/queries/teams.js +24 -0
- package/dist/db/queries/teams.js.map +1 -0
- package/dist/git/branches.d.ts +52 -0
- package/dist/git/branches.d.ts.map +1 -0
- package/dist/git/branches.js +133 -0
- package/dist/git/branches.js.map +1 -0
- package/dist/git/github.d.ts +75 -0
- package/dist/git/github.d.ts.map +1 -0
- package/dist/git/github.js +162 -0
- package/dist/git/github.js.map +1 -0
- package/dist/git/index.d.ts +4 -0
- package/dist/git/index.d.ts.map +1 -0
- package/dist/git/index.js +4 -0
- package/dist/git/index.js.map +1 -0
- package/dist/git/submodules.d.ts +47 -0
- package/dist/git/submodules.d.ts.map +1 -0
- package/dist/git/submodules.js +115 -0
- package/dist/git/submodules.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +62 -0
- package/dist/index.js.map +1 -0
- package/dist/llm/anthropic.d.ts +18 -0
- package/dist/llm/anthropic.d.ts.map +1 -0
- package/dist/llm/anthropic.js +111 -0
- package/dist/llm/anthropic.js.map +1 -0
- package/dist/llm/index.d.ts +6 -0
- package/dist/llm/index.d.ts.map +1 -0
- package/dist/llm/index.js +24 -0
- package/dist/llm/index.js.map +1 -0
- package/dist/llm/openai.d.ts +18 -0
- package/dist/llm/openai.d.ts.map +1 -0
- package/dist/llm/openai.js +103 -0
- package/dist/llm/openai.js.map +1 -0
- package/dist/llm/provider.d.ts +38 -0
- package/dist/llm/provider.d.ts.map +1 -0
- package/dist/llm/provider.js +17 -0
- package/dist/llm/provider.js.map +1 -0
- package/dist/orchestrator/index.d.ts +4 -0
- package/dist/orchestrator/index.d.ts.map +1 -0
- package/dist/orchestrator/index.js +4 -0
- package/dist/orchestrator/index.js.map +1 -0
- package/dist/orchestrator/scaler.d.ts +42 -0
- package/dist/orchestrator/scaler.d.ts.map +1 -0
- package/dist/orchestrator/scaler.js +154 -0
- package/dist/orchestrator/scaler.js.map +1 -0
- package/dist/orchestrator/scheduler.d.ts +90 -0
- package/dist/orchestrator/scheduler.d.ts.map +1 -0
- package/dist/orchestrator/scheduler.js +1003 -0
- package/dist/orchestrator/scheduler.js.map +1 -0
- package/dist/orchestrator/scheduler.test.d.ts +2 -0
- package/dist/orchestrator/scheduler.test.d.ts.map +1 -0
- package/dist/orchestrator/scheduler.test.js +242 -0
- package/dist/orchestrator/scheduler.test.js.map +1 -0
- package/dist/orchestrator/workflow.d.ts +18 -0
- package/dist/orchestrator/workflow.d.ts.map +1 -0
- package/dist/orchestrator/workflow.js +106 -0
- package/dist/orchestrator/workflow.js.map +1 -0
- package/dist/state-detectors/claude.d.ts +33 -0
- package/dist/state-detectors/claude.d.ts.map +1 -0
- package/dist/state-detectors/claude.js +237 -0
- package/dist/state-detectors/claude.js.map +1 -0
- package/dist/state-detectors/claude.test.d.ts +2 -0
- package/dist/state-detectors/claude.test.d.ts.map +1 -0
- package/dist/state-detectors/claude.test.js +127 -0
- package/dist/state-detectors/claude.test.js.map +1 -0
- package/dist/state-detectors/codex.d.ts +34 -0
- package/dist/state-detectors/codex.d.ts.map +1 -0
- package/dist/state-detectors/codex.js +233 -0
- package/dist/state-detectors/codex.js.map +1 -0
- package/dist/state-detectors/codex.test.d.ts +2 -0
- package/dist/state-detectors/codex.test.d.ts.map +1 -0
- package/dist/state-detectors/codex.test.js +85 -0
- package/dist/state-detectors/codex.test.js.map +1 -0
- package/dist/state-detectors/factory.d.ts +22 -0
- package/dist/state-detectors/factory.d.ts.map +1 -0
- package/dist/state-detectors/factory.js +37 -0
- package/dist/state-detectors/factory.js.map +1 -0
- package/dist/state-detectors/factory.test.d.ts +2 -0
- package/dist/state-detectors/factory.test.d.ts.map +1 -0
- package/dist/state-detectors/factory.test.js +44 -0
- package/dist/state-detectors/factory.test.js.map +1 -0
- package/dist/state-detectors/gemini.d.ts +34 -0
- package/dist/state-detectors/gemini.d.ts.map +1 -0
- package/dist/state-detectors/gemini.js +236 -0
- package/dist/state-detectors/gemini.js.map +1 -0
- package/dist/state-detectors/gemini.test.d.ts +2 -0
- package/dist/state-detectors/gemini.test.d.ts.map +1 -0
- package/dist/state-detectors/gemini.test.js +93 -0
- package/dist/state-detectors/gemini.test.js.map +1 -0
- package/dist/state-detectors/index.d.ts +20 -0
- package/dist/state-detectors/index.d.ts.map +1 -0
- package/dist/state-detectors/index.js +21 -0
- package/dist/state-detectors/index.js.map +1 -0
- package/dist/state-detectors/types.d.ts +67 -0
- package/dist/state-detectors/types.d.ts.map +1 -0
- package/dist/state-detectors/types.js +28 -0
- package/dist/state-detectors/types.js.map +1 -0
- package/dist/tmux/index.d.ts +2 -0
- package/dist/tmux/index.d.ts.map +1 -0
- package/dist/tmux/index.js +2 -0
- package/dist/tmux/index.js.map +1 -0
- package/dist/tmux/manager.d.ts +45 -0
- package/dist/tmux/manager.d.ts.map +1 -0
- package/dist/tmux/manager.js +252 -0
- package/dist/tmux/manager.js.map +1 -0
- package/dist/utils/claude-code-state.d.ts +46 -0
- package/dist/utils/claude-code-state.d.ts.map +1 -0
- package/dist/utils/claude-code-state.js +252 -0
- package/dist/utils/claude-code-state.js.map +1 -0
- package/dist/utils/cli-builder.d.ts +19 -0
- package/dist/utils/cli-builder.d.ts.map +1 -0
- package/dist/utils/cli-builder.js +58 -0
- package/dist/utils/cli-builder.js.map +1 -0
- package/dist/utils/cli-commands.d.ts +27 -0
- package/dist/utils/cli-commands.d.ts.map +1 -0
- package/dist/utils/cli-commands.js +69 -0
- package/dist/utils/cli-commands.js.map +1 -0
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +3 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/logger.d.ts +13 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +77 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/paths.d.ts +17 -0
- package/dist/utils/paths.d.ts.map +1 -0
- package/dist/utils/paths.js +33 -0
- package/dist/utils/paths.js.map +1 -0
- package/dist/utils/timeout.d.ts +25 -0
- package/dist/utils/timeout.d.ts.map +1 -0
- package/dist/utils/timeout.js +57 -0
- package/dist/utils/timeout.js.map +1 -0
- package/package.json +78 -0
- package/src/agents/base-agent.ts +255 -0
- package/src/agents/index.ts +6 -0
- package/src/agents/intermediate.ts +161 -0
- package/src/agents/junior.ts +166 -0
- package/src/agents/qa.ts +272 -0
- package/src/agents/senior.ts +307 -0
- package/src/agents/tech-lead.ts +324 -0
- package/src/cli/commands/add-repo.ts +89 -0
- package/src/cli/commands/agents.ts +247 -0
- package/src/cli/commands/assign.ts +86 -0
- package/src/cli/commands/config.ts +121 -0
- package/src/cli/commands/escalations.ts +179 -0
- package/src/cli/commands/index.ts +16 -0
- package/src/cli/commands/init.ts +66 -0
- package/src/cli/commands/manager.test.ts +52 -0
- package/src/cli/commands/manager.ts +916 -0
- package/src/cli/commands/msg.ts +232 -0
- package/src/cli/commands/my-stories.ts +198 -0
- package/src/cli/commands/nuke.ts +223 -0
- package/src/cli/commands/pr.ts +559 -0
- package/src/cli/commands/req.ts +231 -0
- package/src/cli/commands/resume.ts +129 -0
- package/src/cli/commands/status.ts +284 -0
- package/src/cli/commands/stories.ts +131 -0
- package/src/cli/commands/teams.ts +158 -0
- package/src/cli/dashboard/index.ts +141 -0
- package/src/cli/dashboard/panels/activity.ts +77 -0
- package/src/cli/dashboard/panels/agents.ts +244 -0
- package/src/cli/dashboard/panels/escalations.ts +109 -0
- package/src/cli/dashboard/panels/merge-queue.ts +65 -0
- package/src/cli/dashboard/panels/pipeline.ts +65 -0
- package/src/cli/dashboard/panels/stories.ts +87 -0
- package/src/cli-runtimes/claude.ts +31 -0
- package/src/cli-runtimes/codex.ts +31 -0
- package/src/cli-runtimes/gemini.ts +33 -0
- package/src/cli-runtimes/index.test.ts +261 -0
- package/src/cli-runtimes/index.ts +52 -0
- package/src/cli-runtimes/types.ts +30 -0
- package/src/config/index.ts +2 -0
- package/src/config/loader.ts +89 -0
- package/src/config/schema.test.ts +135 -0
- package/src/config/schema.ts +238 -0
- package/src/context-files/generator.ts +132 -0
- package/src/context-files/index.test.ts +323 -0
- package/src/context-files/index.ts +102 -0
- package/src/context-files/templates.ts +279 -0
- package/src/db/client.ts +475 -0
- package/src/db/lock.test.ts +93 -0
- package/src/db/lock.ts +74 -0
- package/src/db/migrations/001-initial.sql +121 -0
- package/src/db/migrations/005-add-agent-heartbeat.sql +4 -0
- package/src/db/queries/agents.ts +113 -0
- package/src/db/queries/escalations.ts +140 -0
- package/src/db/queries/heartbeat.ts +92 -0
- package/src/db/queries/index.ts +7 -0
- package/src/db/queries/logs.ts +136 -0
- package/src/db/queries/messages.ts +38 -0
- package/src/db/queries/pull-requests.ts +170 -0
- package/src/db/queries/requirements.ts +81 -0
- package/src/db/queries/stories.ts +223 -0
- package/src/db/queries/teams.ts +39 -0
- package/src/git/branches.ts +186 -0
- package/src/git/github.ts +247 -0
- package/src/git/index.ts +3 -0
- package/src/git/submodules.ts +141 -0
- package/src/index.ts +93 -0
- package/src/llm/anthropic.ts +134 -0
- package/src/llm/index.ts +26 -0
- package/src/llm/openai.ts +125 -0
- package/src/llm/provider.ts +60 -0
- package/src/orchestrator/index.ts +3 -0
- package/src/orchestrator/scaler.ts +201 -0
- package/src/orchestrator/scheduler.test.ts +288 -0
- package/src/orchestrator/scheduler.ts +1130 -0
- package/src/orchestrator/workflow.ts +137 -0
- package/src/state-detectors/claude.test.ts +149 -0
- package/src/state-detectors/claude.ts +256 -0
- package/src/state-detectors/codex.test.ts +100 -0
- package/src/state-detectors/codex.ts +252 -0
- package/src/state-detectors/factory.test.ts +51 -0
- package/src/state-detectors/factory.ts +40 -0
- package/src/state-detectors/gemini.test.ts +110 -0
- package/src/state-detectors/gemini.ts +255 -0
- package/src/state-detectors/index.ts +25 -0
- package/src/state-detectors/types.ts +80 -0
- package/src/tmux/index.ts +1 -0
- package/src/tmux/manager.ts +310 -0
- package/src/types/sql.js.d.ts +34 -0
- package/src/utils/claude-code-state.ts +281 -0
- package/src/utils/cli-builder.ts +78 -0
- package/src/utils/cli-commands.ts +84 -0
- package/src/utils/index.ts +2 -0
- package/src/utils/logger.ts +93 -0
- package/src/utils/paths.ts +49 -0
- package/src/utils/timeout.ts +84 -0
- package/tsconfig.json +25 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Timeout and retry utilities for LLM calls
|
|
3
|
+
*/
|
|
4
|
+
export declare class TimeoutError extends Error {
|
|
5
|
+
readonly timeoutMs: number;
|
|
6
|
+
constructor(message: string, timeoutMs: number);
|
|
7
|
+
}
|
|
8
|
+
export interface RetryOptions {
|
|
9
|
+
maxRetries: number;
|
|
10
|
+
baseDelayMs?: number;
|
|
11
|
+
maxDelayMs?: number;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Wraps a promise with a timeout
|
|
15
|
+
*/
|
|
16
|
+
export declare function withTimeout<T>(promise: Promise<T>, timeoutMs: number, errorMessage?: string): Promise<T>;
|
|
17
|
+
/**
|
|
18
|
+
* Retries a function with exponential backoff
|
|
19
|
+
*/
|
|
20
|
+
export declare function withRetry<T>(fn: () => Promise<T>, options: RetryOptions): Promise<T>;
|
|
21
|
+
/**
|
|
22
|
+
* Combines timeout and retry logic
|
|
23
|
+
*/
|
|
24
|
+
export declare function withTimeoutAndRetry<T>(fn: () => Promise<T>, timeoutMs: number, retryOptions: RetryOptions, errorMessage?: string): Promise<T>;
|
|
25
|
+
//# sourceMappingURL=timeout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timeout.d.ts","sourceRoot":"","sources":["../../src/utils/timeout.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,qBAAa,YAAa,SAAQ,KAAK;aACQ,SAAS,EAAE,MAAM;gBAAlD,OAAO,EAAE,MAAM,EAAkB,SAAS,EAAE,MAAM;CAI/D;AAED,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAC3B,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EACnB,SAAS,EAAE,MAAM,EACjB,YAAY,SAAwB,GACnC,OAAO,CAAC,CAAC,CAAC,CAgBZ;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,CAAC,EAC/B,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC,CAAC,CAAC,CAoBZ;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,CAAC,EACzC,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,YAAY,EAC1B,YAAY,SAAwB,GACnC,OAAO,CAAC,CAAC,CAAC,CAKZ"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Timeout and retry utilities for LLM calls
|
|
3
|
+
*/
|
|
4
|
+
export class TimeoutError extends Error {
|
|
5
|
+
timeoutMs;
|
|
6
|
+
constructor(message, timeoutMs) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.timeoutMs = timeoutMs;
|
|
9
|
+
this.name = 'TimeoutError';
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Wraps a promise with a timeout
|
|
14
|
+
*/
|
|
15
|
+
export function withTimeout(promise, timeoutMs, errorMessage = 'Operation timed out') {
|
|
16
|
+
return new Promise((resolve, reject) => {
|
|
17
|
+
const timer = setTimeout(() => {
|
|
18
|
+
reject(new TimeoutError(`${errorMessage} after ${timeoutMs}ms`, timeoutMs));
|
|
19
|
+
}, timeoutMs);
|
|
20
|
+
promise
|
|
21
|
+
.then((result) => {
|
|
22
|
+
clearTimeout(timer);
|
|
23
|
+
resolve(result);
|
|
24
|
+
})
|
|
25
|
+
.catch((err) => {
|
|
26
|
+
clearTimeout(timer);
|
|
27
|
+
reject(err);
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Retries a function with exponential backoff
|
|
33
|
+
*/
|
|
34
|
+
export async function withRetry(fn, options) {
|
|
35
|
+
const { maxRetries, baseDelayMs = 1000, maxDelayMs = 30000 } = options;
|
|
36
|
+
let lastError;
|
|
37
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
38
|
+
try {
|
|
39
|
+
return await fn();
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
lastError = err instanceof Error ? err : new Error(String(err));
|
|
43
|
+
if (attempt === maxRetries)
|
|
44
|
+
break;
|
|
45
|
+
const delay = Math.min(baseDelayMs * Math.pow(2, attempt) * (0.5 + Math.random() * 0.5), maxDelayMs);
|
|
46
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
throw lastError || new Error('Max retries exceeded');
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Combines timeout and retry logic
|
|
53
|
+
*/
|
|
54
|
+
export async function withTimeoutAndRetry(fn, timeoutMs, retryOptions, errorMessage = 'Operation timed out') {
|
|
55
|
+
return withRetry(() => withTimeout(fn(), timeoutMs, errorMessage), retryOptions);
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=timeout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timeout.js","sourceRoot":"","sources":["../../src/utils/timeout.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,OAAO,YAAa,SAAQ,KAAK;IACQ;IAA7C,YAAY,OAAe,EAAkB,SAAiB;QAC5D,KAAK,CAAC,OAAO,CAAC,CAAC;QAD4B,cAAS,GAAT,SAAS,CAAQ;QAE5D,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;IAC7B,CAAC;CACF;AAQD;;GAEG;AACH,MAAM,UAAU,WAAW,CACzB,OAAmB,EACnB,SAAiB,EACjB,YAAY,GAAG,qBAAqB;IAEpC,OAAO,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACxC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,MAAM,CAAC,IAAI,YAAY,CAAC,GAAG,YAAY,UAAU,SAAS,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC;QAC9E,CAAC,EAAE,SAAS,CAAC,CAAC;QAEd,OAAO;aACJ,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;YACf,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,OAAO,CAAC,MAAM,CAAC,CAAC;QAClB,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;YACb,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,MAAM,CAAC,GAAG,CAAC,CAAC;QACd,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,EAAoB,EACpB,OAAqB;IAErB,MAAM,EAAE,UAAU,EAAE,WAAW,GAAG,IAAI,EAAE,UAAU,GAAG,KAAK,EAAE,GAAG,OAAO,CAAC;IACvE,IAAI,SAA4B,CAAC;IAEjC,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,UAAU,EAAE,OAAO,EAAE,EAAE,CAAC;QACvD,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,EAAE,CAAC;QACpB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,SAAS,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YAChE,IAAI,OAAO,KAAK,UAAU;gBAAE,MAAM;YAElC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CACpB,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC,EAChE,UAAU,CACX,CAAC;YACF,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;IAED,MAAM,SAAS,IAAI,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;AACvD,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,EAAoB,EACpB,SAAiB,EACjB,YAA0B,EAC1B,YAAY,GAAG,qBAAqB;IAEpC,OAAO,SAAS,CACd,GAAG,EAAE,CAAC,WAAW,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,YAAY,CAAC,EAChD,YAAY,CACb,CAAC;AACJ,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "hungry-ghost-hive",
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "AI Agent Orchestrator - Manages agile software development teams of AI agents",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"hive": "./dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"main": "./dist/index.js",
|
|
10
|
+
"scripts": {
|
|
11
|
+
"prepare": "husky install",
|
|
12
|
+
"build": "tsc",
|
|
13
|
+
"prepack": "npm run build",
|
|
14
|
+
"dev": "tsx src/index.ts",
|
|
15
|
+
"start": "node dist/index.js",
|
|
16
|
+
"lint": "eslint src/",
|
|
17
|
+
"type-check": "tsc --noEmit",
|
|
18
|
+
"test": "vitest run",
|
|
19
|
+
"test:watch": "vitest"
|
|
20
|
+
},
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "git+https://github.com/nikrich/hungry-ghost-hive.git"
|
|
24
|
+
},
|
|
25
|
+
"homepage": "https://github.com/nikrich/hungry-ghost-hive#readme",
|
|
26
|
+
"bugs": {
|
|
27
|
+
"url": "https://github.com/nikrich/hungry-ghost-hive/issues"
|
|
28
|
+
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"@anthropic-ai/sdk": "^0.24.0",
|
|
31
|
+
"@types/proper-lockfile": "^4.1.4",
|
|
32
|
+
"blessed": "^0.1.81",
|
|
33
|
+
"blessed-contrib": "^4.10.0",
|
|
34
|
+
"chalk": "^5.3.0",
|
|
35
|
+
"commander": "^12.0.0",
|
|
36
|
+
"execa": "^9.0.0",
|
|
37
|
+
"nanoid": "^5.0.0",
|
|
38
|
+
"openai": "^4.0.0",
|
|
39
|
+
"ora": "^8.0.0",
|
|
40
|
+
"proper-lockfile": "^4.1.2",
|
|
41
|
+
"sql.js": "^1.13.0",
|
|
42
|
+
"yaml": "^2.0.0",
|
|
43
|
+
"zod": "^3.22.0"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@commitlint/cli": "^18.0.0",
|
|
47
|
+
"@commitlint/config-conventional": "^18.0.0",
|
|
48
|
+
"@eslint/js": "^9.39.2",
|
|
49
|
+
"@types/blessed": "^0.1.0",
|
|
50
|
+
"@types/node": "^20.0.0",
|
|
51
|
+
"eslint": "^9.39.2",
|
|
52
|
+
"husky": "^9.1.7",
|
|
53
|
+
"tsx": "^4.0.0",
|
|
54
|
+
"typescript": "^5.0.0",
|
|
55
|
+
"typescript-eslint": "^8.54.0",
|
|
56
|
+
"vitest": "^1.0.0"
|
|
57
|
+
},
|
|
58
|
+
"engines": {
|
|
59
|
+
"node": ">=18.0.0"
|
|
60
|
+
},
|
|
61
|
+
"files": [
|
|
62
|
+
"dist",
|
|
63
|
+
"src",
|
|
64
|
+
"tsconfig.json"
|
|
65
|
+
],
|
|
66
|
+
"keywords": [
|
|
67
|
+
"ai",
|
|
68
|
+
"agents",
|
|
69
|
+
"orchestrator",
|
|
70
|
+
"cli",
|
|
71
|
+
"agile",
|
|
72
|
+
"development"
|
|
73
|
+
],
|
|
74
|
+
"license": "MIT",
|
|
75
|
+
"publishConfig": {
|
|
76
|
+
"access": "public"
|
|
77
|
+
}
|
|
78
|
+
}
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import type { Database } from 'sql.js';
|
|
2
|
+
import type { LLMProvider, Message } from '../llm/provider.js';
|
|
3
|
+
import { createLog, type EventType } from '../db/queries/logs.js';
|
|
4
|
+
import { updateAgent, type AgentRow, type AgentType, type AgentStatus } from '../db/queries/agents.js';
|
|
5
|
+
import { updateAgentHeartbeat } from '../db/queries/heartbeat.js';
|
|
6
|
+
|
|
7
|
+
export interface MemoryState {
|
|
8
|
+
conversationSummary: string;
|
|
9
|
+
currentTask?: {
|
|
10
|
+
storyId?: string;
|
|
11
|
+
phase: string;
|
|
12
|
+
filesModified: string[];
|
|
13
|
+
lastAction: string;
|
|
14
|
+
};
|
|
15
|
+
context: {
|
|
16
|
+
codebaseNotes?: string;
|
|
17
|
+
blockers: string[];
|
|
18
|
+
decisionsMade: string[];
|
|
19
|
+
};
|
|
20
|
+
checkpointTokens: number;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface AgentContext {
|
|
24
|
+
db: Database;
|
|
25
|
+
provider: LLMProvider;
|
|
26
|
+
agentRow: AgentRow;
|
|
27
|
+
workDir: string;
|
|
28
|
+
config: {
|
|
29
|
+
maxRetries: number;
|
|
30
|
+
checkpointThreshold: number;
|
|
31
|
+
pollInterval: number;
|
|
32
|
+
llmTimeoutMs: number;
|
|
33
|
+
llmMaxRetries: number;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export abstract class BaseAgent {
|
|
38
|
+
protected db: Database;
|
|
39
|
+
protected provider: LLMProvider;
|
|
40
|
+
protected agentId: string;
|
|
41
|
+
protected agentType: AgentType;
|
|
42
|
+
protected teamId: string | null;
|
|
43
|
+
protected workDir: string;
|
|
44
|
+
protected config: AgentContext['config'];
|
|
45
|
+
protected messages: Message[] = [];
|
|
46
|
+
protected memoryState: MemoryState;
|
|
47
|
+
protected totalTokens = 0;
|
|
48
|
+
private heartbeatInterval: NodeJS.Timeout | null = null;
|
|
49
|
+
|
|
50
|
+
constructor(context: AgentContext) {
|
|
51
|
+
this.db = context.db;
|
|
52
|
+
this.provider = context.provider;
|
|
53
|
+
this.agentId = context.agentRow.id;
|
|
54
|
+
this.agentType = context.agentRow.type;
|
|
55
|
+
this.teamId = context.agentRow.team_id;
|
|
56
|
+
this.workDir = context.workDir;
|
|
57
|
+
this.config = context.config;
|
|
58
|
+
|
|
59
|
+
// Load or initialize memory state
|
|
60
|
+
if (context.agentRow.memory_state) {
|
|
61
|
+
this.memoryState = JSON.parse(context.agentRow.memory_state);
|
|
62
|
+
} else {
|
|
63
|
+
this.memoryState = {
|
|
64
|
+
conversationSummary: '',
|
|
65
|
+
context: {
|
|
66
|
+
blockers: [],
|
|
67
|
+
decisionsMade: [],
|
|
68
|
+
},
|
|
69
|
+
checkpointTokens: 0,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Initialize messages with system prompt
|
|
74
|
+
this.messages = [
|
|
75
|
+
{ role: 'system', content: this.getSystemPrompt() },
|
|
76
|
+
];
|
|
77
|
+
|
|
78
|
+
// Add memory context if resuming
|
|
79
|
+
if (this.memoryState.conversationSummary) {
|
|
80
|
+
this.messages.push({
|
|
81
|
+
role: 'user',
|
|
82
|
+
content: `Previous context:\n${this.memoryState.conversationSummary}\n\nContinue from where you left off.`,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Start heartbeat mechanism for faster failure detection
|
|
87
|
+
this.startHeartbeat();
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
abstract getSystemPrompt(): string;
|
|
91
|
+
|
|
92
|
+
private startHeartbeat(): void {
|
|
93
|
+
// Send initial heartbeat
|
|
94
|
+
this.sendHeartbeat();
|
|
95
|
+
|
|
96
|
+
// Send heartbeat every 10 seconds
|
|
97
|
+
this.heartbeatInterval = setInterval(() => {
|
|
98
|
+
this.sendHeartbeat();
|
|
99
|
+
}, 10000);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
private sendHeartbeat(): void {
|
|
103
|
+
try {
|
|
104
|
+
updateAgentHeartbeat(this.db, this.agentId);
|
|
105
|
+
} catch (err) {
|
|
106
|
+
// Heartbeat failure shouldn't crash the agent
|
|
107
|
+
console.error(`Heartbeat failed for ${this.agentId}:`, err);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
private stopHeartbeat(): void {
|
|
112
|
+
if (this.heartbeatInterval) {
|
|
113
|
+
clearInterval(this.heartbeatInterval);
|
|
114
|
+
this.heartbeatInterval = null;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
protected log(
|
|
119
|
+
eventType: EventType,
|
|
120
|
+
message?: string,
|
|
121
|
+
metadata?: Record<string, unknown>
|
|
122
|
+
): void {
|
|
123
|
+
createLog(this.db, {
|
|
124
|
+
agentId: this.agentId,
|
|
125
|
+
storyId: this.memoryState.currentTask?.storyId,
|
|
126
|
+
eventType,
|
|
127
|
+
message,
|
|
128
|
+
metadata,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
protected updateStatus(status: AgentStatus): void {
|
|
133
|
+
updateAgent(this.db, this.agentId, { status });
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
protected saveMemoryState(): void {
|
|
137
|
+
this.memoryState.checkpointTokens = this.totalTokens;
|
|
138
|
+
updateAgent(this.db, this.agentId, {
|
|
139
|
+
memoryState: JSON.stringify(this.memoryState),
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
protected async chat(userMessage: string): Promise<string> {
|
|
144
|
+
this.messages.push({ role: 'user', content: userMessage });
|
|
145
|
+
|
|
146
|
+
try {
|
|
147
|
+
// Apply configured timeout to LLM call
|
|
148
|
+
const result = await this.provider.complete(this.messages, {
|
|
149
|
+
timeoutMs: this.config.llmTimeoutMs,
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
this.totalTokens += result.usage.inputTokens + result.usage.outputTokens;
|
|
153
|
+
this.messages.push({ role: 'assistant', content: result.content });
|
|
154
|
+
|
|
155
|
+
// Check if we need to checkpoint
|
|
156
|
+
if (this.totalTokens > this.config.checkpointThreshold) {
|
|
157
|
+
await this.checkpoint();
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return result.content;
|
|
161
|
+
} catch (err) {
|
|
162
|
+
// Log timeout/error event
|
|
163
|
+
this.log('AGENT_TERMINATED', `LLM call failed: ${err instanceof Error ? err.message : String(err)}`, {
|
|
164
|
+
error: err instanceof Error ? err.stack : String(err),
|
|
165
|
+
});
|
|
166
|
+
throw err;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
protected async checkpoint(): Promise<void> {
|
|
171
|
+
// Summarize the conversation
|
|
172
|
+
const summaryPrompt = `Summarize the key points of our conversation so far in a concise paragraph. Focus on:
|
|
173
|
+
1. What task we're working on
|
|
174
|
+
2. What progress has been made
|
|
175
|
+
3. What decisions were made
|
|
176
|
+
4. What blockers or issues exist
|
|
177
|
+
5. What's the next step
|
|
178
|
+
|
|
179
|
+
Keep it under 500 words.`;
|
|
180
|
+
|
|
181
|
+
this.messages.push({ role: 'user', content: summaryPrompt });
|
|
182
|
+
const summaryResult = await this.provider.complete(this.messages);
|
|
183
|
+
|
|
184
|
+
this.memoryState.conversationSummary = summaryResult.content;
|
|
185
|
+
this.saveMemoryState();
|
|
186
|
+
|
|
187
|
+
this.log('AGENT_CHECKPOINT', 'Checkpoint saved', {
|
|
188
|
+
totalTokens: this.totalTokens,
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
// Reset messages but keep context
|
|
192
|
+
this.messages = [
|
|
193
|
+
{ role: 'system', content: this.getSystemPrompt() },
|
|
194
|
+
{ role: 'user', content: `Previous context:\n${this.memoryState.conversationSummary}\n\nContinue from where you left off.` },
|
|
195
|
+
];
|
|
196
|
+
this.totalTokens = 0;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
protected addDecision(decision: string): void {
|
|
200
|
+
this.memoryState.context.decisionsMade.push(decision);
|
|
201
|
+
this.saveMemoryState();
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
protected addBlocker(blocker: string): void {
|
|
205
|
+
this.memoryState.context.blockers.push(blocker);
|
|
206
|
+
this.saveMemoryState();
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
protected removeBlocker(blocker: string): void {
|
|
210
|
+
this.memoryState.context.blockers = this.memoryState.context.blockers.filter(
|
|
211
|
+
b => b !== blocker
|
|
212
|
+
);
|
|
213
|
+
this.saveMemoryState();
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
protected setCurrentTask(storyId: string, phase: string): void {
|
|
217
|
+
this.memoryState.currentTask = {
|
|
218
|
+
storyId,
|
|
219
|
+
phase,
|
|
220
|
+
filesModified: [],
|
|
221
|
+
lastAction: '',
|
|
222
|
+
};
|
|
223
|
+
this.saveMemoryState();
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
protected updateTaskProgress(lastAction: string, filesModified?: string[]): void {
|
|
227
|
+
if (this.memoryState.currentTask) {
|
|
228
|
+
this.memoryState.currentTask.lastAction = lastAction;
|
|
229
|
+
if (filesModified) {
|
|
230
|
+
this.memoryState.currentTask.filesModified.push(...filesModified);
|
|
231
|
+
}
|
|
232
|
+
this.saveMemoryState();
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
async run(): Promise<void> {
|
|
237
|
+
this.updateStatus('working');
|
|
238
|
+
this.log('AGENT_SPAWNED', `${this.agentType} agent started`);
|
|
239
|
+
|
|
240
|
+
try {
|
|
241
|
+
await this.execute();
|
|
242
|
+
} catch (err) {
|
|
243
|
+
this.updateStatus('blocked');
|
|
244
|
+
this.log('AGENT_TERMINATED', `Error: ${err instanceof Error ? err.message : 'Unknown error'}`, {
|
|
245
|
+
error: err instanceof Error ? err.stack : String(err),
|
|
246
|
+
});
|
|
247
|
+
throw err;
|
|
248
|
+
} finally {
|
|
249
|
+
// Stop heartbeat when agent completes or fails
|
|
250
|
+
this.stopHeartbeat();
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
abstract execute(): Promise<void>;
|
|
255
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { BaseAgent, type MemoryState, type AgentContext } from './base-agent.js';
|
|
2
|
+
export { TechLeadAgent, type TechLeadContext } from './tech-lead.js';
|
|
3
|
+
export { SeniorAgent, type SeniorContext } from './senior.js';
|
|
4
|
+
export { IntermediateAgent, type IntermediateContext } from './intermediate.js';
|
|
5
|
+
export { JuniorAgent, type JuniorContext } from './junior.js';
|
|
6
|
+
export { QAAgent, type QAContext } from './qa.js';
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { BaseAgent, type AgentContext } from './base-agent.js';
|
|
2
|
+
import { getTeamById, type TeamRow } from '../db/queries/teams.js';
|
|
3
|
+
import { updateStory, getStoryById, type StoryRow } from '../db/queries/stories.js';
|
|
4
|
+
import { getAgentsByTeam } from '../db/queries/agents.js';
|
|
5
|
+
import { createEscalation } from '../db/queries/escalations.js';
|
|
6
|
+
|
|
7
|
+
export interface IntermediateContext extends AgentContext {
|
|
8
|
+
storyId?: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export class IntermediateAgent extends BaseAgent {
|
|
12
|
+
private team: TeamRow | null = null;
|
|
13
|
+
private story: StoryRow | null = null;
|
|
14
|
+
private retryCount = 0;
|
|
15
|
+
|
|
16
|
+
constructor(context: IntermediateContext) {
|
|
17
|
+
super(context);
|
|
18
|
+
if (context.agentRow.team_id) {
|
|
19
|
+
this.team = getTeamById(this.db, context.agentRow.team_id) || null;
|
|
20
|
+
}
|
|
21
|
+
if (context.storyId) {
|
|
22
|
+
this.story = getStoryById(this.db, context.storyId) || null;
|
|
23
|
+
} else if (context.agentRow.current_story_id) {
|
|
24
|
+
this.story = getStoryById(this.db, context.agentRow.current_story_id) || null;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
getSystemPrompt(): string {
|
|
29
|
+
const teamInfo = this.team
|
|
30
|
+
? `Team: ${this.team.name}\nRepository: ${this.team.repo_path}`
|
|
31
|
+
: 'No team assigned';
|
|
32
|
+
|
|
33
|
+
const storyInfo = this.story
|
|
34
|
+
? `Current Story: ${this.story.id}\nTitle: ${this.story.title}\nStatus: ${this.story.status}`
|
|
35
|
+
: 'No story assigned';
|
|
36
|
+
|
|
37
|
+
return `You are an Intermediate Developer working on assigned stories.
|
|
38
|
+
|
|
39
|
+
## Your Team
|
|
40
|
+
${teamInfo}
|
|
41
|
+
|
|
42
|
+
## Assignment
|
|
43
|
+
${storyInfo}
|
|
44
|
+
|
|
45
|
+
## Your Responsibilities
|
|
46
|
+
1. Implement assigned stories with moderate complexity (4-5 points)
|
|
47
|
+
2. Follow existing code patterns and conventions
|
|
48
|
+
3. Write tests for your code
|
|
49
|
+
4. Create clear commit messages
|
|
50
|
+
5. Request help from Senior when stuck
|
|
51
|
+
|
|
52
|
+
## Development Guidelines
|
|
53
|
+
- Work on the feature branch assigned to the story
|
|
54
|
+
- Follow TDD when possible
|
|
55
|
+
- Commit frequently with descriptive messages
|
|
56
|
+
- Update progress regularly
|
|
57
|
+
- Escalate after 2 failed attempts
|
|
58
|
+
|
|
59
|
+
## Current Context
|
|
60
|
+
${this.memoryState.conversationSummary || 'Starting fresh.'}`;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async execute(): Promise<void> {
|
|
64
|
+
if (!this.story) {
|
|
65
|
+
this.log('STORY_PROGRESS_UPDATE', 'No story assigned, waiting');
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
this.setCurrentTask(this.story.id, 'implementation');
|
|
70
|
+
this.log('STORY_STARTED', `Working on: ${this.story.title}`, { storyId: this.story.id });
|
|
71
|
+
|
|
72
|
+
try {
|
|
73
|
+
await this.implementStory();
|
|
74
|
+
} catch (err) {
|
|
75
|
+
this.retryCount++;
|
|
76
|
+
if (this.retryCount >= this.config.maxRetries) {
|
|
77
|
+
await this.escalateToSenior(`Failed after ${this.retryCount} attempts: ${err instanceof Error ? err.message : 'Unknown error'}`);
|
|
78
|
+
} else {
|
|
79
|
+
this.log('STORY_PROGRESS_UPDATE', `Retry ${this.retryCount}: ${err instanceof Error ? err.message : 'Unknown error'}`, {
|
|
80
|
+
storyId: this.story.id,
|
|
81
|
+
});
|
|
82
|
+
// Retry
|
|
83
|
+
await this.execute();
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
private async implementStory(): Promise<void> {
|
|
89
|
+
if (!this.story) return;
|
|
90
|
+
|
|
91
|
+
const branchName = this.story.branch_name ||
|
|
92
|
+
`feature/${this.story.id.toLowerCase()}-${this.story.title.toLowerCase().replace(/[^a-z0-9]+/g, '-').substring(0, 30)}`;
|
|
93
|
+
|
|
94
|
+
// Update story with branch name if not set
|
|
95
|
+
if (!this.story.branch_name) {
|
|
96
|
+
updateStory(this.db, this.story.id, { branchName });
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const prompt = `Implement this story:
|
|
100
|
+
|
|
101
|
+
## Story: ${this.story.id}
|
|
102
|
+
**Title:** ${this.story.title}
|
|
103
|
+
|
|
104
|
+
**Description:**
|
|
105
|
+
${this.story.description}
|
|
106
|
+
|
|
107
|
+
**Acceptance Criteria:**
|
|
108
|
+
${this.story.acceptance_criteria ? JSON.parse(this.story.acceptance_criteria).join('\n- ') : 'None specified'}
|
|
109
|
+
|
|
110
|
+
**Branch:** ${branchName}
|
|
111
|
+
|
|
112
|
+
## Instructions
|
|
113
|
+
1. Checkout or create the feature branch
|
|
114
|
+
2. Read the relevant files to understand the context
|
|
115
|
+
3. Implement the required changes
|
|
116
|
+
4. Write tests
|
|
117
|
+
5. Commit with clear messages
|
|
118
|
+
6. Update me on progress
|
|
119
|
+
|
|
120
|
+
Begin implementation.`;
|
|
121
|
+
|
|
122
|
+
const response = await this.chat(prompt);
|
|
123
|
+
this.updateTaskProgress('Implementation in progress', []);
|
|
124
|
+
this.log('STORY_PROGRESS_UPDATE', response.substring(0, 200), { storyId: this.story.id });
|
|
125
|
+
|
|
126
|
+
// Continue implementation (simplified - in reality this would be iterative)
|
|
127
|
+
const continuePrompt = 'Continue with the implementation. Show me the code changes you would make.';
|
|
128
|
+
await this.chat(continuePrompt);
|
|
129
|
+
this.log('STORY_PROGRESS_UPDATE', 'Code changes proposed', { storyId: this.story.id });
|
|
130
|
+
|
|
131
|
+
// Mark as complete
|
|
132
|
+
updateStory(this.db, this.story.id, { status: 'review' });
|
|
133
|
+
this.log('STORY_COMPLETED', 'Implementation complete, ready for review', {
|
|
134
|
+
storyId: this.story.id,
|
|
135
|
+
branchName,
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
private async escalateToSenior(reason: string): Promise<void> {
|
|
140
|
+
// Find Senior for this team
|
|
141
|
+
const seniors = getAgentsByTeam(this.db, this.teamId!)
|
|
142
|
+
.filter(a => a.type === 'senior' && a.status !== 'terminated');
|
|
143
|
+
|
|
144
|
+
const seniorId = seniors[0]?.id;
|
|
145
|
+
|
|
146
|
+
const escalation = createEscalation(this.db, {
|
|
147
|
+
storyId: this.story?.id,
|
|
148
|
+
fromAgentId: this.agentId,
|
|
149
|
+
toAgentId: seniorId,
|
|
150
|
+
reason,
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
this.log('ESCALATION_CREATED', reason, {
|
|
154
|
+
escalationId: escalation.id,
|
|
155
|
+
toAgent: seniorId,
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
this.updateStatus('blocked');
|
|
159
|
+
this.addBlocker(`Escalated to Senior: ${reason}`);
|
|
160
|
+
}
|
|
161
|
+
}
|