@intrect/openswarm 0.2.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 +21 -0
- package/README.md +544 -0
- package/config.example.yaml +107 -0
- package/dist/adapters/base.d.ts +8 -0
- package/dist/adapters/base.d.ts.map +1 -0
- package/dist/adapters/base.js +104 -0
- package/dist/adapters/base.js.map +1 -0
- package/dist/adapters/claude.d.ts +13 -0
- package/dist/adapters/claude.d.ts.map +1 -0
- package/dist/adapters/claude.js +318 -0
- package/dist/adapters/claude.js.map +1 -0
- package/dist/adapters/codex.d.ts +14 -0
- package/dist/adapters/codex.d.ts.map +1 -0
- package/dist/adapters/codex.js +366 -0
- package/dist/adapters/codex.js.map +1 -0
- package/dist/adapters/cryptoQuantAdapter.d.ts +85 -0
- package/dist/adapters/cryptoQuantAdapter.d.ts.map +1 -0
- package/dist/adapters/cryptoQuantAdapter.js +238 -0
- package/dist/adapters/cryptoQuantAdapter.js.map +1 -0
- package/dist/adapters/index.d.ts +17 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +47 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/processRegistry.d.ts +38 -0
- package/dist/adapters/processRegistry.d.ts.map +1 -0
- package/dist/adapters/processRegistry.js +147 -0
- package/dist/adapters/processRegistry.js.map +1 -0
- package/dist/adapters/streamBuffer.d.ts +59 -0
- package/dist/adapters/streamBuffer.d.ts.map +1 -0
- package/dist/adapters/streamBuffer.js +123 -0
- package/dist/adapters/streamBuffer.js.map +1 -0
- package/dist/adapters/types.d.ts +65 -0
- package/dist/adapters/types.d.ts.map +1 -0
- package/dist/adapters/types.js +6 -0
- package/dist/adapters/types.js.map +1 -0
- package/dist/agents/agentBus.d.ts +160 -0
- package/dist/agents/agentBus.d.ts.map +1 -0
- package/dist/agents/agentBus.js +350 -0
- package/dist/agents/agentBus.js.map +1 -0
- package/dist/agents/agentPair.d.ts +210 -0
- package/dist/agents/agentPair.d.ts.map +1 -0
- package/dist/agents/agentPair.js +420 -0
- package/dist/agents/agentPair.js.map +1 -0
- package/dist/agents/auditor.d.ts +27 -0
- package/dist/agents/auditor.d.ts.map +1 -0
- package/dist/agents/auditor.js +237 -0
- package/dist/agents/auditor.js.map +1 -0
- package/dist/agents/cliStreamParser.d.ts +18 -0
- package/dist/agents/cliStreamParser.d.ts.map +1 -0
- package/dist/agents/cliStreamParser.js +156 -0
- package/dist/agents/cliStreamParser.js.map +1 -0
- package/dist/agents/documenter.d.ts +31 -0
- package/dist/agents/documenter.d.ts.map +1 -0
- package/dist/agents/documenter.js +285 -0
- package/dist/agents/documenter.js.map +1 -0
- package/dist/agents/index.d.ts +10 -0
- package/dist/agents/index.d.ts.map +1 -0
- package/dist/agents/index.js +10 -0
- package/dist/agents/index.js.map +1 -0
- package/dist/agents/pairMetrics.d.ts +63 -0
- package/dist/agents/pairMetrics.d.ts.map +1 -0
- package/dist/agents/pairMetrics.js +231 -0
- package/dist/agents/pairMetrics.js.map +1 -0
- package/dist/agents/pairPipeline.d.ts +155 -0
- package/dist/agents/pairPipeline.d.ts.map +1 -0
- package/dist/agents/pairPipeline.js +793 -0
- package/dist/agents/pairPipeline.js.map +1 -0
- package/dist/agents/pairWebhook.d.ts +59 -0
- package/dist/agents/pairWebhook.d.ts.map +1 -0
- package/dist/agents/pairWebhook.js +242 -0
- package/dist/agents/pairWebhook.js.map +1 -0
- package/dist/agents/pipelineFormat.d.ts +11 -0
- package/dist/agents/pipelineFormat.d.ts.map +1 -0
- package/dist/agents/pipelineFormat.js +164 -0
- package/dist/agents/pipelineFormat.js.map +1 -0
- package/dist/agents/pipelineGuards.d.ts +23 -0
- package/dist/agents/pipelineGuards.d.ts.map +1 -0
- package/dist/agents/pipelineGuards.js +175 -0
- package/dist/agents/pipelineGuards.js.map +1 -0
- package/dist/agents/reviewer.d.ts +37 -0
- package/dist/agents/reviewer.d.ts.map +1 -0
- package/dist/agents/reviewer.js +213 -0
- package/dist/agents/reviewer.js.map +1 -0
- package/dist/agents/skillDocumenter.d.ts +23 -0
- package/dist/agents/skillDocumenter.d.ts.map +1 -0
- package/dist/agents/skillDocumenter.js +218 -0
- package/dist/agents/skillDocumenter.js.map +1 -0
- package/dist/agents/tester.d.ts +37 -0
- package/dist/agents/tester.d.ts.map +1 -0
- package/dist/agents/tester.js +308 -0
- package/dist/agents/tester.js.map +1 -0
- package/dist/agents/worker.d.ts +30 -0
- package/dist/agents/worker.d.ts.map +1 -0
- package/dist/agents/worker.js +128 -0
- package/dist/agents/worker.js.map +1 -0
- package/dist/automation/autonomousRunner.d.ts +123 -0
- package/dist/automation/autonomousRunner.d.ts.map +1 -0
- package/dist/automation/autonomousRunner.js +1082 -0
- package/dist/automation/autonomousRunner.js.map +1 -0
- package/dist/automation/ciWorker.d.ts +51 -0
- package/dist/automation/ciWorker.d.ts.map +1 -0
- package/dist/automation/ciWorker.js +282 -0
- package/dist/automation/ciWorker.js.map +1 -0
- package/dist/automation/conflictResolver.d.ts +29 -0
- package/dist/automation/conflictResolver.d.ts.map +1 -0
- package/dist/automation/conflictResolver.js +261 -0
- package/dist/automation/conflictResolver.js.map +1 -0
- package/dist/automation/dailyReporter.d.ts +26 -0
- package/dist/automation/dailyReporter.d.ts.map +1 -0
- package/dist/automation/dailyReporter.js +132 -0
- package/dist/automation/dailyReporter.js.map +1 -0
- package/dist/automation/index.d.ts +7 -0
- package/dist/automation/index.d.ts.map +1 -0
- package/dist/automation/index.js +7 -0
- package/dist/automation/index.js.map +1 -0
- package/dist/automation/longRunningMonitor.d.ts +26 -0
- package/dist/automation/longRunningMonitor.d.ts.map +1 -0
- package/dist/automation/longRunningMonitor.js +231 -0
- package/dist/automation/longRunningMonitor.js.map +1 -0
- package/dist/automation/prOwnership.d.ts +18 -0
- package/dist/automation/prOwnership.d.ts.map +1 -0
- package/dist/automation/prOwnership.js +61 -0
- package/dist/automation/prOwnership.js.map +1 -0
- package/dist/automation/prProcessor.d.ts +62 -0
- package/dist/automation/prProcessor.d.ts.map +1 -0
- package/dist/automation/prProcessor.js +700 -0
- package/dist/automation/prProcessor.js.map +1 -0
- package/dist/automation/runnerExecution.d.ts +49 -0
- package/dist/automation/runnerExecution.d.ts.map +1 -0
- package/dist/automation/runnerExecution.js +663 -0
- package/dist/automation/runnerExecution.js.map +1 -0
- package/dist/automation/runnerState.d.ts +170 -0
- package/dist/automation/runnerState.d.ts.map +1 -0
- package/dist/automation/runnerState.js +495 -0
- package/dist/automation/runnerState.js.map +1 -0
- package/dist/automation/runnerTypes.d.ts +46 -0
- package/dist/automation/runnerTypes.d.ts.map +1 -0
- package/dist/automation/runnerTypes.js +5 -0
- package/dist/automation/runnerTypes.js.map +1 -0
- package/dist/automation/scheduler.d.ts +75 -0
- package/dist/automation/scheduler.d.ts.map +1 -0
- package/dist/automation/scheduler.js +394 -0
- package/dist/automation/scheduler.js.map +1 -0
- package/dist/cli/promptHandler.d.ts +13 -0
- package/dist/cli/promptHandler.d.ts.map +1 -0
- package/dist/cli/promptHandler.js +189 -0
- package/dist/cli/promptHandler.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +138 -0
- package/dist/cli.js.map +1 -0
- package/dist/core/config.d.ts +308 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +529 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/eventHub.d.ts +194 -0
- package/dist/core/eventHub.d.ts.map +1 -0
- package/dist/core/eventHub.js +136 -0
- package/dist/core/eventHub.js.map +1 -0
- package/dist/core/index.d.ts +6 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +6 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/service.d.ts +27 -0
- package/dist/core/service.d.ts.map +1 -0
- package/dist/core/service.js +438 -0
- package/dist/core/service.js.map +1 -0
- package/dist/core/traceCollector.d.ts +105 -0
- package/dist/core/traceCollector.d.ts.map +1 -0
- package/dist/core/traceCollector.js +141 -0
- package/dist/core/traceCollector.js.map +1 -0
- package/dist/core/types.d.ts +413 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +5 -0
- package/dist/core/types.js.map +1 -0
- package/dist/discord/discordCore.d.ts +104 -0
- package/dist/discord/discordCore.d.ts.map +1 -0
- package/dist/discord/discordCore.js +698 -0
- package/dist/discord/discordCore.js.map +1 -0
- package/dist/discord/discordHandlers.d.ts +86 -0
- package/dist/discord/discordHandlers.d.ts.map +1 -0
- package/dist/discord/discordHandlers.js +849 -0
- package/dist/discord/discordHandlers.js.map +1 -0
- package/dist/discord/discordPair.d.ts +6 -0
- package/dist/discord/discordPair.d.ts.map +1 -0
- package/dist/discord/discordPair.js +567 -0
- package/dist/discord/discordPair.js.map +1 -0
- package/dist/discord/index.d.ts +4 -0
- package/dist/discord/index.d.ts.map +1 -0
- package/dist/discord/index.js +11 -0
- package/dist/discord/index.js.map +1 -0
- package/dist/github/github.d.ts +236 -0
- package/dist/github/github.d.ts.map +1 -0
- package/dist/github/github.js +535 -0
- package/dist/github/github.js.map +1 -0
- package/dist/github/index.d.ts +2 -0
- package/dist/github/index.d.ts.map +1 -0
- package/dist/github/index.js +2 -0
- package/dist/github/index.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +60 -0
- package/dist/index.js.map +1 -0
- package/dist/knowledge/analyzer.d.ts +36 -0
- package/dist/knowledge/analyzer.d.ts.map +1 -0
- package/dist/knowledge/analyzer.js +170 -0
- package/dist/knowledge/analyzer.js.map +1 -0
- package/dist/knowledge/gitInfo.d.ts +10 -0
- package/dist/knowledge/gitInfo.d.ts.map +1 -0
- package/dist/knowledge/gitInfo.js +134 -0
- package/dist/knowledge/gitInfo.js.map +1 -0
- package/dist/knowledge/graph.d.ts +45 -0
- package/dist/knowledge/graph.d.ts.map +1 -0
- package/dist/knowledge/graph.js +262 -0
- package/dist/knowledge/graph.js.map +1 -0
- package/dist/knowledge/graphqlExporter.d.ts +64 -0
- package/dist/knowledge/graphqlExporter.d.ts.map +1 -0
- package/dist/knowledge/graphqlExporter.js +333 -0
- package/dist/knowledge/graphqlExporter.js.map +1 -0
- package/dist/knowledge/index.d.ts +58 -0
- package/dist/knowledge/index.d.ts.map +1 -0
- package/dist/knowledge/index.js +212 -0
- package/dist/knowledge/index.js.map +1 -0
- package/dist/knowledge/repository.d.ts +64 -0
- package/dist/knowledge/repository.d.ts.map +1 -0
- package/dist/knowledge/repository.js +250 -0
- package/dist/knowledge/repository.js.map +1 -0
- package/dist/knowledge/riskOnAnalyzer.d.ts +79 -0
- package/dist/knowledge/riskOnAnalyzer.d.ts.map +1 -0
- package/dist/knowledge/riskOnAnalyzer.js +243 -0
- package/dist/knowledge/riskOnAnalyzer.js.map +1 -0
- package/dist/knowledge/scanner.d.ts +14 -0
- package/dist/knowledge/scanner.d.ts.map +1 -0
- package/dist/knowledge/scanner.js +350 -0
- package/dist/knowledge/scanner.js.map +1 -0
- package/dist/knowledge/store.d.ts +23 -0
- package/dist/knowledge/store.d.ts.map +1 -0
- package/dist/knowledge/store.js +86 -0
- package/dist/knowledge/store.js.map +1 -0
- package/dist/knowledge/types.d.ts +288 -0
- package/dist/knowledge/types.d.ts.map +1 -0
- package/dist/knowledge/types.js +111 -0
- package/dist/knowledge/types.js.map +1 -0
- package/dist/linear/index.d.ts +3 -0
- package/dist/linear/index.d.ts.map +1 -0
- package/dist/linear/index.js +3 -0
- package/dist/linear/index.js.map +1 -0
- package/dist/linear/linear.d.ts +160 -0
- package/dist/linear/linear.d.ts.map +1 -0
- package/dist/linear/linear.js +983 -0
- package/dist/linear/linear.js.map +1 -0
- package/dist/linear/projectUpdater.d.ts +23 -0
- package/dist/linear/projectUpdater.d.ts.map +1 -0
- package/dist/linear/projectUpdater.js +347 -0
- package/dist/linear/projectUpdater.js.map +1 -0
- package/dist/locale/en.d.ts +3 -0
- package/dist/locale/en.d.ts.map +1 -0
- package/dist/locale/en.js +436 -0
- package/dist/locale/en.js.map +1 -0
- package/dist/locale/index.d.ts +28 -0
- package/dist/locale/index.d.ts.map +1 -0
- package/dist/locale/index.js +89 -0
- package/dist/locale/index.js.map +1 -0
- package/dist/locale/ko.d.ts +3 -0
- package/dist/locale/ko.d.ts.map +1 -0
- package/dist/locale/ko.js +436 -0
- package/dist/locale/ko.js.map +1 -0
- package/dist/locale/prompts/en.d.ts +3 -0
- package/dist/locale/prompts/en.d.ts.map +1 -0
- package/dist/locale/prompts/en.js +278 -0
- package/dist/locale/prompts/en.js.map +1 -0
- package/dist/locale/prompts/ko.d.ts +3 -0
- package/dist/locale/prompts/ko.d.ts.map +1 -0
- package/dist/locale/prompts/ko.js +279 -0
- package/dist/locale/prompts/ko.js.map +1 -0
- package/dist/locale/types.d.ts +407 -0
- package/dist/locale/types.d.ts.map +1 -0
- package/dist/locale/types.js +5 -0
- package/dist/locale/types.js.map +1 -0
- package/dist/memory/codex.d.ts +93 -0
- package/dist/memory/codex.d.ts.map +1 -0
- package/dist/memory/codex.js +366 -0
- package/dist/memory/codex.js.map +1 -0
- package/dist/memory/compaction.d.ts +21 -0
- package/dist/memory/compaction.d.ts.map +1 -0
- package/dist/memory/compaction.js +205 -0
- package/dist/memory/compaction.js.map +1 -0
- package/dist/memory/index.d.ts +13 -0
- package/dist/memory/index.d.ts.map +1 -0
- package/dist/memory/index.js +13 -0
- package/dist/memory/index.js.map +1 -0
- package/dist/memory/memoryCore.d.ts +178 -0
- package/dist/memory/memoryCore.d.ts.map +1 -0
- package/dist/memory/memoryCore.js +623 -0
- package/dist/memory/memoryCore.js.map +1 -0
- package/dist/memory/memoryOps.d.ts +90 -0
- package/dist/memory/memoryOps.d.ts.map +1 -0
- package/dist/memory/memoryOps.js +606 -0
- package/dist/memory/memoryOps.js.map +1 -0
- package/dist/orchestration/conflictDetector.d.ts +15 -0
- package/dist/orchestration/conflictDetector.d.ts.map +1 -0
- package/dist/orchestration/conflictDetector.js +130 -0
- package/dist/orchestration/conflictDetector.js.map +1 -0
- package/dist/orchestration/decisionEngine.d.ts +177 -0
- package/dist/orchestration/decisionEngine.d.ts.map +1 -0
- package/dist/orchestration/decisionEngine.js +496 -0
- package/dist/orchestration/decisionEngine.js.map +1 -0
- package/dist/orchestration/index.d.ts +5 -0
- package/dist/orchestration/index.d.ts.map +1 -0
- package/dist/orchestration/index.js +5 -0
- package/dist/orchestration/index.js.map +1 -0
- package/dist/orchestration/taskParser.d.ts +67 -0
- package/dist/orchestration/taskParser.d.ts.map +1 -0
- package/dist/orchestration/taskParser.js +542 -0
- package/dist/orchestration/taskParser.js.map +1 -0
- package/dist/orchestration/taskScheduler.d.ts +141 -0
- package/dist/orchestration/taskScheduler.d.ts.map +1 -0
- package/dist/orchestration/taskScheduler.js +317 -0
- package/dist/orchestration/taskScheduler.js.map +1 -0
- package/dist/orchestration/workflow.d.ts +145 -0
- package/dist/orchestration/workflow.d.ts.map +1 -0
- package/dist/orchestration/workflow.js +301 -0
- package/dist/orchestration/workflow.js.map +1 -0
- package/dist/runners/cliRunner.d.ts +11 -0
- package/dist/runners/cliRunner.d.ts.map +1 -0
- package/dist/runners/cliRunner.js +194 -0
- package/dist/runners/cliRunner.js.map +1 -0
- package/dist/support/apiCache.d.ts +85 -0
- package/dist/support/apiCache.d.ts.map +1 -0
- package/dist/support/apiCache.js +163 -0
- package/dist/support/apiCache.js.map +1 -0
- package/dist/support/chat.d.ts +3 -0
- package/dist/support/chat.d.ts.map +1 -0
- package/dist/support/chat.js +304 -0
- package/dist/support/chat.js.map +1 -0
- package/dist/support/chatBackend.d.ts +25 -0
- package/dist/support/chatBackend.d.ts.map +1 -0
- package/dist/support/chatBackend.js +235 -0
- package/dist/support/chatBackend.js.map +1 -0
- package/dist/support/chatMemory.d.ts +71 -0
- package/dist/support/chatMemory.d.ts.map +1 -0
- package/dist/support/chatMemory.js +119 -0
- package/dist/support/chatMemory.js.map +1 -0
- package/dist/support/chatTui.d.ts +3 -0
- package/dist/support/chatTui.d.ts.map +1 -0
- package/dist/support/chatTui.js +998 -0
- package/dist/support/chatTui.js.map +1 -0
- package/dist/support/costTracker.d.ts +29 -0
- package/dist/support/costTracker.d.ts.map +1 -0
- package/dist/support/costTracker.js +113 -0
- package/dist/support/costTracker.js.map +1 -0
- package/dist/support/dashboardHtml.d.ts +3 -0
- package/dist/support/dashboardHtml.d.ts.map +1 -0
- package/dist/support/dashboardHtml.js +2070 -0
- package/dist/support/dashboardHtml.js.map +1 -0
- package/dist/support/delete-beliefs.d.ts +2 -0
- package/dist/support/delete-beliefs.d.ts.map +1 -0
- package/dist/support/delete-beliefs.js +34 -0
- package/dist/support/delete-beliefs.js.map +1 -0
- package/dist/support/dev.d.ts +55 -0
- package/dist/support/dev.d.ts.map +1 -0
- package/dist/support/dev.js +298 -0
- package/dist/support/dev.js.map +1 -0
- package/dist/support/editParser.d.ts +37 -0
- package/dist/support/editParser.d.ts.map +1 -0
- package/dist/support/editParser.js +365 -0
- package/dist/support/editParser.js.map +1 -0
- package/dist/support/gitStatus.d.ts +21 -0
- package/dist/support/gitStatus.d.ts.map +1 -0
- package/dist/support/gitStatus.js +108 -0
- package/dist/support/gitStatus.js.map +1 -0
- package/dist/support/gitTracker.d.ts +30 -0
- package/dist/support/gitTracker.d.ts.map +1 -0
- package/dist/support/gitTracker.js +143 -0
- package/dist/support/gitTracker.js.map +1 -0
- package/dist/support/index.d.ts +13 -0
- package/dist/support/index.d.ts.map +1 -0
- package/dist/support/index.js +13 -0
- package/dist/support/index.js.map +1 -0
- package/dist/support/planner.d.ts +58 -0
- package/dist/support/planner.d.ts.map +1 -0
- package/dist/support/planner.js +395 -0
- package/dist/support/planner.js.map +1 -0
- package/dist/support/projectMapper.d.ts +46 -0
- package/dist/support/projectMapper.d.ts.map +1 -0
- package/dist/support/projectMapper.js +259 -0
- package/dist/support/projectMapper.js.map +1 -0
- package/dist/support/quotaTracker.d.ts +29 -0
- package/dist/support/quotaTracker.d.ts.map +1 -0
- package/dist/support/quotaTracker.js +89 -0
- package/dist/support/quotaTracker.js.map +1 -0
- package/dist/support/rateLimiter.d.ts +101 -0
- package/dist/support/rateLimiter.d.ts.map +1 -0
- package/dist/support/rateLimiter.js +219 -0
- package/dist/support/rateLimiter.js.map +1 -0
- package/dist/support/rollback.d.ts +61 -0
- package/dist/support/rollback.d.ts.map +1 -0
- package/dist/support/rollback.js +328 -0
- package/dist/support/rollback.js.map +1 -0
- package/dist/support/stuckDetector.d.ts +68 -0
- package/dist/support/stuckDetector.d.ts.map +1 -0
- package/dist/support/stuckDetector.js +174 -0
- package/dist/support/stuckDetector.js.map +1 -0
- package/dist/support/timeWindow.d.ts +60 -0
- package/dist/support/timeWindow.d.ts.map +1 -0
- package/dist/support/timeWindow.js +236 -0
- package/dist/support/timeWindow.js.map +1 -0
- package/dist/support/web.d.ts +11 -0
- package/dist/support/web.d.ts.map +1 -0
- package/dist/support/web.js +938 -0
- package/dist/support/web.js.map +1 -0
- package/dist/support/workflowLinear.d.ts +99 -0
- package/dist/support/workflowLinear.d.ts.map +1 -0
- package/dist/support/workflowLinear.js +257 -0
- package/dist/support/workflowLinear.js.map +1 -0
- package/dist/support/worktreeManager.d.ts +20 -0
- package/dist/support/worktreeManager.d.ts.map +1 -0
- package/dist/support/worktreeManager.js +144 -0
- package/dist/support/worktreeManager.js.map +1 -0
- package/dist/taskState/store.d.ts +101 -0
- package/dist/taskState/store.d.ts.map +1 -0
- package/dist/taskState/store.js +346 -0
- package/dist/taskState/store.js.map +1 -0
- package/package.json +70 -0
- package/templates/AGENTS.md +432 -0
- package/templates/BOOT.md +25 -0
- package/templates/BOOTSTRAP.md +50 -0
- package/templates/CHANGELOG_AUDIT.md +74 -0
- package/templates/HEARTBEAT.md +86 -0
- package/templates/IDENTITY.md +27 -0
- package/templates/ISSUE_ANALYSIS.md +31 -0
- package/templates/PR_LAND.md +75 -0
- package/templates/PR_REVIEW.md +97 -0
- package/templates/SOUL.dev.md +52 -0
- package/templates/SOUL.md +81 -0
- package/templates/TOOLS.md +52 -0
- package/templates/USER.md +22 -0
|
@@ -0,0 +1,663 @@
|
|
|
1
|
+
// ============================================
|
|
2
|
+
// OpenSwarm - Runner Execution Helpers
|
|
3
|
+
// Execution/reporting/integration logic extracted from AutonomousRunner
|
|
4
|
+
// ============================================
|
|
5
|
+
import { EmbedBuilder } from 'discord.js';
|
|
6
|
+
import { createPipelineFromConfig, buildTaskPrefix } from '../agents/pairPipeline.js';
|
|
7
|
+
import { formatParsedTaskSummary, loadParsedTask } from '../orchestration/taskParser.js';
|
|
8
|
+
import { saveCognitiveMemory } from '../memory/index.js';
|
|
9
|
+
import * as workerAgent from '../agents/worker.js';
|
|
10
|
+
import * as reviewerAgent from '../agents/reviewer.js';
|
|
11
|
+
import * as projectMapper from '../support/projectMapper.js';
|
|
12
|
+
import * as linear from '../linear/index.js';
|
|
13
|
+
import * as planner from '../support/planner.js';
|
|
14
|
+
import { analyzeIssue } from '../knowledge/index.js';
|
|
15
|
+
import { t } from '../locale/index.js';
|
|
16
|
+
import { broadcastEvent } from '../core/eventHub.js';
|
|
17
|
+
import { buildBranchName, createWorktree, commitAndCreatePR, removeWorktree, } from '../support/worktreeManager.js';
|
|
18
|
+
import { getDecompositionDepth, getChildrenCount, getDailyCreationCount, canCreateMoreIssues, registerDecomposition, } from './runnerState.js';
|
|
19
|
+
import { buildTaskStateSyncComment, completeParentIfChildrenDone, markTaskBlocked, markTaskDecomposed, markTaskDone, markTaskInProgress, releaseDependentTasks, upsertTaskState, } from '../taskState/store.js';
|
|
20
|
+
let discordSend = null;
|
|
21
|
+
export function setDiscordReporter(sendFn) {
|
|
22
|
+
discordSend = sendFn;
|
|
23
|
+
console.log('[AutonomousRunner] Discord reporter registered');
|
|
24
|
+
}
|
|
25
|
+
export async function reportToDiscord(message) {
|
|
26
|
+
if (!discordSend) {
|
|
27
|
+
console.log('[AutonomousRunner] No Discord reporter, logging instead:', typeof message === 'string' ? message : message.data.title);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
if (typeof message === 'string') {
|
|
32
|
+
// Convert plain text to Embed for consistent Discord UI
|
|
33
|
+
const embed = new EmbedBuilder()
|
|
34
|
+
.setDescription(message)
|
|
35
|
+
.setColor(0x00ff41) // OpenSwarm green
|
|
36
|
+
.setTimestamp();
|
|
37
|
+
await discordSend({ embeds: [embed] });
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
await discordSend({ embeds: [message] });
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
console.error('[AutonomousRunner] Discord report failed:', error);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
let linearFetch = null;
|
|
48
|
+
export function setLinearFetcher(fetchFn) {
|
|
49
|
+
linearFetch = fetchFn;
|
|
50
|
+
console.log('[AutonomousRunner] Linear fetcher registered');
|
|
51
|
+
}
|
|
52
|
+
// Track consecutive fetch failures for visibility
|
|
53
|
+
let fetchFailureCount = 0;
|
|
54
|
+
export async function fetchLinearTasks() {
|
|
55
|
+
if (!linearFetch) {
|
|
56
|
+
console.log('[AutonomousRunner] No Linear fetcher registered');
|
|
57
|
+
return { tasks: [], error: 'No Linear fetcher registered' };
|
|
58
|
+
}
|
|
59
|
+
try {
|
|
60
|
+
const tasks = await linearFetch();
|
|
61
|
+
if (fetchFailureCount > 0) {
|
|
62
|
+
console.log(`[AutonomousRunner] Linear fetch recovered after ${fetchFailureCount} failures`);
|
|
63
|
+
}
|
|
64
|
+
fetchFailureCount = 0;
|
|
65
|
+
return { tasks };
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
fetchFailureCount++;
|
|
69
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
70
|
+
console.error(`[AutonomousRunner] Linear fetch failed (${fetchFailureCount}x consecutive): ${msg}`);
|
|
71
|
+
return { tasks: [], error: msg };
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// Project Path Resolution
|
|
75
|
+
export async function resolveProjectPath(ctx, task) {
|
|
76
|
+
const projectName = task.linearProject?.name;
|
|
77
|
+
const projectId = task.linearProject?.id;
|
|
78
|
+
if (!projectId || !projectName) {
|
|
79
|
+
console.error(`[AutonomousRunner] Task "${task.title}" has no Linear project info - SKIP`);
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
// 1순위: allowedProjects에서 정확한 basename 매칭 (fuzzy보다 신뢰도 높음)
|
|
83
|
+
for (const allowed of ctx.allowedProjects) {
|
|
84
|
+
const expanded = allowed.replace('~', process.env.HOME || '');
|
|
85
|
+
const dirName = expanded.split('/').pop();
|
|
86
|
+
if (dirName === projectName || dirName?.toLowerCase() === projectName.toLowerCase()) {
|
|
87
|
+
if (await isValidProjectPath(expanded)) {
|
|
88
|
+
console.log(`[AutonomousRunner] AllowedProjects match: ${projectName} → ${expanded}`);
|
|
89
|
+
return expanded;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// 2순위: ~/dev/{name} 직접 경로
|
|
94
|
+
const directPath = `${process.env.HOME}/dev/${projectName}`;
|
|
95
|
+
if (await isValidProjectPath(directPath)) {
|
|
96
|
+
console.log(`[AutonomousRunner] Direct path found: ${projectName} → ${directPath}`);
|
|
97
|
+
return directPath;
|
|
98
|
+
}
|
|
99
|
+
const lowerPath = `${process.env.HOME}/dev/${projectName.toLowerCase()}`;
|
|
100
|
+
if (await isValidProjectPath(lowerPath)) {
|
|
101
|
+
console.log(`[AutonomousRunner] Lowercase path found: ${projectName} → ${lowerPath}`);
|
|
102
|
+
return lowerPath;
|
|
103
|
+
}
|
|
104
|
+
// 3순위: ~/dev/tools/ 서브디렉토리
|
|
105
|
+
const toolsPath = `${process.env.HOME}/dev/tools/${projectName}`;
|
|
106
|
+
if (await isValidProjectPath(toolsPath)) {
|
|
107
|
+
console.log(`[AutonomousRunner] Tools path found: ${projectName} → ${toolsPath}`);
|
|
108
|
+
return toolsPath;
|
|
109
|
+
}
|
|
110
|
+
// 4순위: fuzzy match (스캔 기반, 오탐 가능성 있음)
|
|
111
|
+
const mappedPath = await projectMapper.mapLinearProject(projectId, projectName, ctx.allowedProjects);
|
|
112
|
+
if (mappedPath) {
|
|
113
|
+
console.log(`[AutonomousRunner] Fuzzy mapped: ${projectName} → ${mappedPath}`);
|
|
114
|
+
return mappedPath;
|
|
115
|
+
}
|
|
116
|
+
console.error(`[AutonomousRunner] Failed to resolve project path for "${projectName}" - SKIP`);
|
|
117
|
+
console.error(`[AutonomousRunner] Tried: allowedProjects, ${directPath}, ${lowerPath}, ${toolsPath}, fuzzy mapper`);
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
export async function isValidProjectPath(path) {
|
|
121
|
+
try {
|
|
122
|
+
const fs = await import('fs/promises');
|
|
123
|
+
const stats = await fs.stat(path);
|
|
124
|
+
if (!stats.isDirectory())
|
|
125
|
+
return false;
|
|
126
|
+
const checks = ['.git', 'package.json', 'pyproject.toml'];
|
|
127
|
+
for (const check of checks) {
|
|
128
|
+
try {
|
|
129
|
+
await fs.stat(`${path}/${check}`);
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
// continue
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return false;
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
return false;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
// Task Decomposition
|
|
143
|
+
export async function decomposeTask(ctx, task, projectPath, targetMinutes) {
|
|
144
|
+
console.log(`[AutonomousRunner] Decomposing task: ${task.title}`);
|
|
145
|
+
const taskId = task.issueId || task.id;
|
|
146
|
+
const maxDepth = ctx.decompositionMaxDepth ?? 2;
|
|
147
|
+
const maxChildren = ctx.decompositionMaxChildren ?? 5;
|
|
148
|
+
const dailyLimit = ctx.decompositionDailyLimit ?? 20;
|
|
149
|
+
const autoBacklog = ctx.decompositionAutoBacklog ?? true;
|
|
150
|
+
// ============================================
|
|
151
|
+
// Pre-checks: Depth, Children, Daily Limit
|
|
152
|
+
// ============================================
|
|
153
|
+
// Check decomposition depth limit
|
|
154
|
+
if (task.issueId) {
|
|
155
|
+
const currentDepth = getDecompositionDepth(task.issueId);
|
|
156
|
+
if (currentDepth >= maxDepth) {
|
|
157
|
+
console.log(`[AutonomousRunner] Decomposition depth limit reached: ${currentDepth}/${maxDepth}`);
|
|
158
|
+
if (autoBacklog && task.issueId) {
|
|
159
|
+
try {
|
|
160
|
+
await linear.updateIssueState(task.issueId, 'Backlog');
|
|
161
|
+
await linear.addComment(task.issueId, `⚠️ **Auto-moved to Backlog**\n\n` +
|
|
162
|
+
`Reason: Decomposition depth limit reached (${currentDepth}/${maxDepth})\n\n` +
|
|
163
|
+
`This task has been nested too deeply. Please review and simplify the task structure, ` +
|
|
164
|
+
`or handle it manually.`);
|
|
165
|
+
console.log(`[AutonomousRunner] Task moved to backlog (depth limit)`);
|
|
166
|
+
}
|
|
167
|
+
catch (err) {
|
|
168
|
+
console.error(`[AutonomousRunner] Failed to move to backlog:`, err);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
return false;
|
|
172
|
+
}
|
|
173
|
+
// Check children count limit
|
|
174
|
+
const childrenCount = getChildrenCount(task.issueId);
|
|
175
|
+
if (childrenCount >= maxChildren) {
|
|
176
|
+
console.log(`[AutonomousRunner] Children count limit reached: ${childrenCount}/${maxChildren}`);
|
|
177
|
+
if (autoBacklog) {
|
|
178
|
+
try {
|
|
179
|
+
await linear.updateIssueState(task.issueId, 'Backlog');
|
|
180
|
+
await linear.addComment(task.issueId, `⚠️ **Auto-moved to Backlog**\n\n` +
|
|
181
|
+
`Reason: Too many sub-issues already created (${childrenCount}/${maxChildren})\n\n` +
|
|
182
|
+
`This task has generated too many sub-issues. Please review the decomposition strategy, ` +
|
|
183
|
+
`or handle it manually.`);
|
|
184
|
+
console.log(`[AutonomousRunner] Task moved to backlog (children limit)`);
|
|
185
|
+
}
|
|
186
|
+
catch (err) {
|
|
187
|
+
console.error(`[AutonomousRunner] Failed to move to backlog:`, err);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
// Check daily creation limit
|
|
194
|
+
// NOTE: Don't move to Backlog on daily limit — it resets tomorrow.
|
|
195
|
+
// Moving to Backlog would permanently exclude the task from future heartbeats.
|
|
196
|
+
// Instead, skip decomposition and fall through to direct execution.
|
|
197
|
+
if (!canCreateMoreIssues(dailyLimit)) {
|
|
198
|
+
const currentCount = getDailyCreationCount();
|
|
199
|
+
console.log(`[AutonomousRunner] Daily issue creation limit reached: ${currentCount}/${dailyLimit} — skipping decomposition (will retry tomorrow)`);
|
|
200
|
+
return false;
|
|
201
|
+
}
|
|
202
|
+
broadcastEvent({ type: 'pipeline:stage', data: { taskId, stage: 'decompose', status: 'start' } });
|
|
203
|
+
await ctx.reportToDiscord(t('runner.decomposition.starting', {
|
|
204
|
+
title: task.title,
|
|
205
|
+
estimated: String(planner.estimateTaskDuration(task)),
|
|
206
|
+
threshold: String(targetMinutes),
|
|
207
|
+
}));
|
|
208
|
+
// Periodic progress log while planner runs (fallback if stdout isn't streaming)
|
|
209
|
+
let elapsed = 0;
|
|
210
|
+
const progressTimer = setInterval(() => {
|
|
211
|
+
elapsed += 30;
|
|
212
|
+
broadcastEvent({ type: 'log', data: { taskId, stage: 'decompose', line: `⏱ Planner running... ${elapsed}s` } });
|
|
213
|
+
}, 30000);
|
|
214
|
+
// KG 영향 분석 — 플래너에 파일 분리 힌트 제공
|
|
215
|
+
const impactAnalysis = await analyzeIssue(projectPath, task.title, task.description).catch(() => null);
|
|
216
|
+
let result;
|
|
217
|
+
try {
|
|
218
|
+
result = await planner.runPlanner({
|
|
219
|
+
taskTitle: task.title,
|
|
220
|
+
taskDescription: task.description || '',
|
|
221
|
+
projectPath,
|
|
222
|
+
projectName: task.linearProject?.name,
|
|
223
|
+
targetMinutes,
|
|
224
|
+
model: ctx.plannerModel ?? 'claude-sonnet-4-5-20250929',
|
|
225
|
+
timeoutMs: ctx.plannerTimeoutMs ?? 600000,
|
|
226
|
+
onLog: (line) => broadcastEvent({ type: 'log', data: { taskId, stage: 'decompose', line } }),
|
|
227
|
+
impactAnalysis: impactAnalysis ?? undefined,
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
finally {
|
|
231
|
+
clearInterval(progressTimer);
|
|
232
|
+
}
|
|
233
|
+
await ctx.reportToDiscord(planner.formatPlannerResult(result));
|
|
234
|
+
if (!result.success) {
|
|
235
|
+
console.error(`[AutonomousRunner] Planner failed: ${result.error}`);
|
|
236
|
+
broadcastEvent({ type: 'pipeline:stage', data: { taskId, stage: 'decompose', status: 'fail' } });
|
|
237
|
+
return false;
|
|
238
|
+
}
|
|
239
|
+
if (!result.needsDecomposition || result.subTasks.length === 0) {
|
|
240
|
+
console.log('[AutonomousRunner] Planner determined no decomposition needed');
|
|
241
|
+
return 'no-decomp';
|
|
242
|
+
}
|
|
243
|
+
if (!task.issueId) {
|
|
244
|
+
console.error('[AutonomousRunner] Cannot create sub-issues: no parent issueId');
|
|
245
|
+
return false;
|
|
246
|
+
}
|
|
247
|
+
const createdSubIssues = [];
|
|
248
|
+
for (const [index, subTask] of result.subTasks.entries()) {
|
|
249
|
+
const depsStr = subTask.dependencies?.length
|
|
250
|
+
? `\n\n${t('runner.decomposition.prerequisite', { deps: subTask.dependencies.join(', ') })}`
|
|
251
|
+
: '';
|
|
252
|
+
const subDescription = `${subTask.description}\n\n` +
|
|
253
|
+
`${t('runner.decomposition.estimatedTime', { n: String(subTask.estimatedMinutes) })}${depsStr}\n\n` +
|
|
254
|
+
t('runner.decomposition.autoDecomposed', { parentTitle: task.title });
|
|
255
|
+
const subResult = await linear.createSubIssue(task.issueId, subTask.title, subDescription, {
|
|
256
|
+
priority: subTask.priority,
|
|
257
|
+
projectId: task.linearProject?.id,
|
|
258
|
+
estimatedMinutes: subTask.estimatedMinutes,
|
|
259
|
+
});
|
|
260
|
+
if ('error' in subResult) {
|
|
261
|
+
console.error(`[AutonomousRunner] Failed to create sub-issue: ${subResult.error}`);
|
|
262
|
+
continue;
|
|
263
|
+
}
|
|
264
|
+
createdSubIssues.push({
|
|
265
|
+
id: subResult.id,
|
|
266
|
+
identifier: subResult.identifier,
|
|
267
|
+
title: subResult.title,
|
|
268
|
+
dependencies: subTask.dependencies || [],
|
|
269
|
+
topoRank: index,
|
|
270
|
+
estimatedMinutes: subTask.estimatedMinutes,
|
|
271
|
+
});
|
|
272
|
+
console.log(`[AutonomousRunner] Created sub-issue: ${subResult.identifier}`);
|
|
273
|
+
}
|
|
274
|
+
if (createdSubIssues.length === 0) {
|
|
275
|
+
console.error('[AutonomousRunner] No sub-issues created');
|
|
276
|
+
broadcastEvent({ type: 'pipeline:stage', data: { taskId, stage: 'decompose', status: 'fail' } });
|
|
277
|
+
return false;
|
|
278
|
+
}
|
|
279
|
+
// Register decomposition in tracking (for limits)
|
|
280
|
+
registerDecomposition(task.issueId, task.parentId, // Parent ID if this task is also a sub-issue
|
|
281
|
+
createdSubIssues.map(s => s.id));
|
|
282
|
+
console.log(`[AutonomousRunner] Registered decomposition: parent=${task.issueId}, children=${createdSubIssues.length}, daily=${getDailyCreationCount()}/${dailyLimit}`);
|
|
283
|
+
await linear.markAsDecomposed(task.issueId, createdSubIssues.length, result.totalEstimatedMinutes);
|
|
284
|
+
const childIdByTitle = new Map(createdSubIssues.map((subIssue) => [subIssue.title, subIssue.id]));
|
|
285
|
+
const parentState = markTaskDecomposed(task.issueId, {
|
|
286
|
+
issueIdentifier: task.issueIdentifier,
|
|
287
|
+
title: task.title,
|
|
288
|
+
projectId: task.linearProject?.id,
|
|
289
|
+
projectName: task.linearProject?.name,
|
|
290
|
+
parentIssueId: task.parentId,
|
|
291
|
+
childIssueIds: createdSubIssues.map((subIssue) => subIssue.id),
|
|
292
|
+
});
|
|
293
|
+
await linear.addComment(task.issueId, buildTaskStateSyncComment(parentState, 'Parent task decomposed'));
|
|
294
|
+
const subIssueList = createdSubIssues
|
|
295
|
+
.map((s, i) => `${i + 1}. ${s.identifier}: ${s.title}`)
|
|
296
|
+
.join('\n');
|
|
297
|
+
await ctx.reportToDiscord(t('runner.decomposition.completed', {
|
|
298
|
+
original: task.issueIdentifier || task.issueId || '',
|
|
299
|
+
count: String(createdSubIssues.length),
|
|
300
|
+
list: subIssueList,
|
|
301
|
+
totalMinutes: String(result.totalEstimatedMinutes),
|
|
302
|
+
}));
|
|
303
|
+
broadcastEvent({ type: 'pipeline:stage', data: { taskId, stage: 'decompose', status: 'complete' } });
|
|
304
|
+
// Log each sub-issue as a log line for the dashboard
|
|
305
|
+
for (const s of createdSubIssues) {
|
|
306
|
+
broadcastEvent({ type: 'log', data: { taskId, stage: 'decompose', line: `↳ ${s.identifier}: ${s.title}` } });
|
|
307
|
+
}
|
|
308
|
+
console.log(`[AutonomousRunner] Decomposition complete: ${createdSubIssues.length} sub-issues created`);
|
|
309
|
+
for (const subIssue of createdSubIssues) {
|
|
310
|
+
const dependencyIssueIds = subIssue.dependencies
|
|
311
|
+
.map((title) => childIdByTitle.get(title))
|
|
312
|
+
.filter((value) => Boolean(value));
|
|
313
|
+
const isReady = dependencyIssueIds.length === 0;
|
|
314
|
+
const childState = upsertTaskState(subIssue.id, {
|
|
315
|
+
issueIdentifier: subIssue.identifier,
|
|
316
|
+
title: subIssue.title,
|
|
317
|
+
projectId: task.linearProject?.id,
|
|
318
|
+
projectName: task.linearProject?.name,
|
|
319
|
+
parentIssueId: task.issueId,
|
|
320
|
+
dependencyIssueIds,
|
|
321
|
+
dependencyTitles: subIssue.dependencies,
|
|
322
|
+
topoRank: subIssue.topoRank,
|
|
323
|
+
execution: {
|
|
324
|
+
status: isReady ? 'todo' : 'blocked',
|
|
325
|
+
blockedReason: isReady ? undefined : `Waiting on dependencies: ${dependencyIssueIds.join(', ')}`,
|
|
326
|
+
retryCount: 0,
|
|
327
|
+
},
|
|
328
|
+
linearState: isReady ? 'Todo' : 'Backlog',
|
|
329
|
+
});
|
|
330
|
+
try {
|
|
331
|
+
if (isReady) {
|
|
332
|
+
await linear.updateIssueState(subIssue.id, 'Todo');
|
|
333
|
+
console.log(`[AutonomousRunner] Moved ${subIssue.identifier} to Todo`);
|
|
334
|
+
}
|
|
335
|
+
else {
|
|
336
|
+
console.log(`[AutonomousRunner] Keeping ${subIssue.identifier} in Backlog until dependencies resolve`);
|
|
337
|
+
}
|
|
338
|
+
await linear.addComment(subIssue.id, buildTaskStateSyncComment(childState, isReady ? 'Task ready after decomposition' : 'Task blocked by decomposition dependency'));
|
|
339
|
+
}
|
|
340
|
+
catch (err) {
|
|
341
|
+
console.warn(`[AutonomousRunner] Failed to initialize ${subIssue.identifier} state:`, err);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
// Trigger immediate heartbeat to pick up newly created sub-issues
|
|
345
|
+
if (ctx.scheduleNextHeartbeat) {
|
|
346
|
+
console.log('[AutonomousRunner] Scheduling immediate heartbeat to process sub-issues...');
|
|
347
|
+
ctx.scheduleNextHeartbeat();
|
|
348
|
+
}
|
|
349
|
+
return true;
|
|
350
|
+
}
|
|
351
|
+
// Pipeline Execution
|
|
352
|
+
export async function executePipeline(ctx, task, projectPath) {
|
|
353
|
+
console.log(`[AutonomousRunner] executePipeline: ${task.title}`);
|
|
354
|
+
if (ctx.enableDecomposition) {
|
|
355
|
+
const threshold = ctx.decompositionThresholdMinutes ?? 30;
|
|
356
|
+
const needsDecomp = planner.needsDecomposition(task, threshold, true); // heuristic pre-filter
|
|
357
|
+
if (needsDecomp) {
|
|
358
|
+
const estimated = planner.estimateTaskDuration(task);
|
|
359
|
+
console.log(`[AutonomousRunner] Task "${task.title}" may need decomposition (estimated ${estimated}min > ${threshold}min)`);
|
|
360
|
+
const decomposed = await decomposeTask(ctx, task, projectPath, threshold);
|
|
361
|
+
if (decomposed === true) {
|
|
362
|
+
// Successfully decomposed into sub-issues
|
|
363
|
+
return {
|
|
364
|
+
success: true,
|
|
365
|
+
sessionId: `decomposed-${Date.now()}`,
|
|
366
|
+
iterations: 0,
|
|
367
|
+
totalDuration: 0,
|
|
368
|
+
finalStatus: 'decomposed',
|
|
369
|
+
stages: [],
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
if (decomposed === 'no-decomp') {
|
|
373
|
+
// Planner says task is smaller than threshold — proceed with direct execution
|
|
374
|
+
console.log('[AutonomousRunner] Planner says task fits in threshold, executing directly');
|
|
375
|
+
}
|
|
376
|
+
else {
|
|
377
|
+
// Decomposition failed (limit reached, planner error, API error, etc.)
|
|
378
|
+
// Fall through to direct execution instead of aborting entirely
|
|
379
|
+
console.log('[AutonomousRunner] Decomposition failed, falling back to direct execution');
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
// ============================================
|
|
384
|
+
// Git Worktree: work in an isolated branch per issue
|
|
385
|
+
// ============================================
|
|
386
|
+
let worktreeInfo = null;
|
|
387
|
+
let actualPath = projectPath;
|
|
388
|
+
if (ctx.worktreeMode && task.issueId && task.issueIdentifier) {
|
|
389
|
+
const branchName = buildBranchName(task.issueIdentifier, task.title);
|
|
390
|
+
try {
|
|
391
|
+
worktreeInfo = await createWorktree(projectPath, task.issueId, branchName);
|
|
392
|
+
actualPath = worktreeInfo.worktreePath;
|
|
393
|
+
broadcastEvent({
|
|
394
|
+
type: 'log',
|
|
395
|
+
data: {
|
|
396
|
+
taskId: task.issueId,
|
|
397
|
+
stage: 'worktree',
|
|
398
|
+
line: `Worktree: ${actualPath} (branch: ${branchName})`,
|
|
399
|
+
},
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
catch (err) {
|
|
403
|
+
console.warn('[Worktree] Failed to create worktree, falling back to main repo:', err);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
try {
|
|
407
|
+
const roles = ctx.getRolesForProject(projectPath); // look up config using original path
|
|
408
|
+
const pipeline = createPipelineFromConfig(roles, ctx.pairMaxAttempts ?? 3, ctx.guards, ctx.jobProfiles);
|
|
409
|
+
const taskPrefix = buildTaskPrefix(task, actualPath);
|
|
410
|
+
pipeline.on('stage:start', ({ stage }) => {
|
|
411
|
+
console.log(`[${taskPrefix}] Stage started: ${stage}`);
|
|
412
|
+
});
|
|
413
|
+
const taskReportCtx = {
|
|
414
|
+
issueIdentifier: task.issueIdentifier || task.issueId,
|
|
415
|
+
projectName: task.linearProject?.name,
|
|
416
|
+
projectPath: actualPath,
|
|
417
|
+
};
|
|
418
|
+
pipeline.on('stage:complete', async ({ stage, result }) => {
|
|
419
|
+
console.log(`[${taskPrefix}] Stage completed: ${stage}, success=${result.success}`);
|
|
420
|
+
await reportStageResult(stage, result, ctx.reportToDiscord, taskReportCtx);
|
|
421
|
+
});
|
|
422
|
+
pipeline.on('revision:start', ({ stage }) => {
|
|
423
|
+
void ctx.reportToDiscord(t('runner.pipeline.revisionNeeded', { stage }));
|
|
424
|
+
});
|
|
425
|
+
// HALT event: low confidence → report to Linear + Discord
|
|
426
|
+
pipeline.on('halt', async ({ confidence, haltReason, sessionId, iteration }) => {
|
|
427
|
+
console.warn(`[${taskPrefix}] HALT event: confidence=${confidence}%, reason=${haltReason}`);
|
|
428
|
+
// Report to Linear
|
|
429
|
+
if (task.issueId && ctx.guards?.haltToLinear) {
|
|
430
|
+
try {
|
|
431
|
+
await linear.logHalt(task.issueId, sessionId, confidence, iteration, haltReason);
|
|
432
|
+
}
|
|
433
|
+
catch (err) {
|
|
434
|
+
console.error(`[${taskPrefix}] Linear logHalt failed:`, err);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
// Report to Discord
|
|
438
|
+
const haltEmbed = new EmbedBuilder()
|
|
439
|
+
.setTitle('⚠️ HALT - Low Confidence')
|
|
440
|
+
.setColor(0xFFA500)
|
|
441
|
+
.addFields({ name: 'Task', value: task.title, inline: false }, { name: 'Confidence', value: `${confidence}%`, inline: true }, { name: 'Iteration', value: `#${iteration}`, inline: true }, { name: 'Reason', value: haltReason || 'Low confidence score', inline: false })
|
|
442
|
+
.setTimestamp();
|
|
443
|
+
await ctx.reportToDiscord(haltEmbed);
|
|
444
|
+
});
|
|
445
|
+
const stages = getEnabledStages(roles);
|
|
446
|
+
const issueRef = task.issueIdentifier || task.issueId || '';
|
|
447
|
+
const projectDisplay = task.linearProject?.name
|
|
448
|
+
? `📁 ${task.linearProject.name} (${actualPath.split('/').slice(-2).join('/')})`
|
|
449
|
+
: actualPath.split('/').slice(-2).join('/');
|
|
450
|
+
const startEmbed = new EmbedBuilder()
|
|
451
|
+
.setTitle(t('runner.pipeline.starting'))
|
|
452
|
+
.setColor(0x00AE86)
|
|
453
|
+
.addFields({ name: t('runner.result.taskLabel'), value: task.title, inline: false }, { name: 'Project', value: projectDisplay, inline: true }, ...(issueRef ? [{ name: 'Issue', value: issueRef, inline: true }] : []), { name: 'Stages', value: stages.join(' → '), inline: true }, ...(worktreeInfo ? [{ name: 'Branch', value: worktreeInfo.branchName, inline: true }] : []))
|
|
454
|
+
.setTimestamp();
|
|
455
|
+
await ctx.reportToDiscord(startEmbed);
|
|
456
|
+
if (task.issueId) {
|
|
457
|
+
try {
|
|
458
|
+
const sessionId = `pipeline-${Date.now()}`;
|
|
459
|
+
const inProgressState = markTaskInProgress(task.issueId, {
|
|
460
|
+
issueIdentifier: task.issueIdentifier,
|
|
461
|
+
title: task.title,
|
|
462
|
+
projectId: task.linearProject?.id,
|
|
463
|
+
projectName: task.linearProject?.name,
|
|
464
|
+
linearState: 'In Progress',
|
|
465
|
+
sessionId,
|
|
466
|
+
branchName: worktreeInfo?.branchName,
|
|
467
|
+
worktreePath: actualPath,
|
|
468
|
+
});
|
|
469
|
+
await linear.logPairStart(task.issueId, sessionId, projectPath);
|
|
470
|
+
await linear.addComment(task.issueId, buildTaskStateSyncComment(inProgressState, 'Task execution started'));
|
|
471
|
+
}
|
|
472
|
+
catch (err) {
|
|
473
|
+
console.error(`[${taskPrefix}] Linear logPairStart failed:`, err);
|
|
474
|
+
// Continue pipeline even if this fails
|
|
475
|
+
await linear.updateIssueState(task.issueId, 'In Progress');
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
// Run pipeline in worktree path
|
|
479
|
+
const result = await pipeline.run(task, actualPath);
|
|
480
|
+
// Create PR (worktree mode + pipeline success = finalStatus 'approved')
|
|
481
|
+
if (worktreeInfo && result.success && result.finalStatus === 'approved') {
|
|
482
|
+
try {
|
|
483
|
+
const prUrl = await commitAndCreatePR(worktreeInfo, task.title, task.issueIdentifier || '', task.description || '');
|
|
484
|
+
result.prUrl = prUrl;
|
|
485
|
+
broadcastEvent({
|
|
486
|
+
type: 'log',
|
|
487
|
+
data: {
|
|
488
|
+
taskId: task.issueId || task.id,
|
|
489
|
+
stage: 'pr',
|
|
490
|
+
line: `PR created: ${prUrl}`,
|
|
491
|
+
},
|
|
492
|
+
});
|
|
493
|
+
console.log(`[Runner] PR created for ${task.issueIdentifier}: ${prUrl}`);
|
|
494
|
+
}
|
|
495
|
+
catch (err) {
|
|
496
|
+
console.error('[Worktree] PR creation failed:', err);
|
|
497
|
+
broadcastEvent({
|
|
498
|
+
type: 'log',
|
|
499
|
+
data: {
|
|
500
|
+
taskId: task.issueId || task.id,
|
|
501
|
+
stage: 'pr',
|
|
502
|
+
line: `PR creation failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
503
|
+
},
|
|
504
|
+
});
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
else if (worktreeInfo) {
|
|
508
|
+
// Log why PR was not created
|
|
509
|
+
const reason = !result.success
|
|
510
|
+
? `Pipeline failed (${result.finalStatus})`
|
|
511
|
+
: `Unexpected state (success=${result.success}, finalStatus=${result.finalStatus})`;
|
|
512
|
+
console.log(`[Runner] PR not created for ${task.issueIdentifier}: ${reason}`);
|
|
513
|
+
}
|
|
514
|
+
return result;
|
|
515
|
+
}
|
|
516
|
+
finally {
|
|
517
|
+
// Clean up worktree regardless of success/failure
|
|
518
|
+
if (worktreeInfo) {
|
|
519
|
+
await removeWorktree(worktreeInfo).catch((err) => console.warn('[Worktree] Cleanup failed:', err));
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
function getEnabledStages(roles) {
|
|
524
|
+
const stages = [];
|
|
525
|
+
if (roles?.worker?.enabled !== false)
|
|
526
|
+
stages.push('worker');
|
|
527
|
+
if (roles?.reviewer?.enabled !== false)
|
|
528
|
+
stages.push('reviewer');
|
|
529
|
+
if (roles?.tester?.enabled)
|
|
530
|
+
stages.push('tester');
|
|
531
|
+
if (roles?.documenter?.enabled)
|
|
532
|
+
stages.push('documenter');
|
|
533
|
+
return stages;
|
|
534
|
+
}
|
|
535
|
+
// Reporting
|
|
536
|
+
async function reportStageResult(stage, result, reportFn, taskCtx) {
|
|
537
|
+
switch (stage) {
|
|
538
|
+
case 'worker':
|
|
539
|
+
await reportFn(workerAgent.formatWorkReport(result.result, taskCtx));
|
|
540
|
+
break;
|
|
541
|
+
case 'reviewer':
|
|
542
|
+
await reportFn(reviewerAgent.formatReviewFeedback(result.result));
|
|
543
|
+
break;
|
|
544
|
+
case 'tester': {
|
|
545
|
+
const { formatTestReport } = await import('../agents/tester.js');
|
|
546
|
+
await reportFn(formatTestReport(result.result));
|
|
547
|
+
break;
|
|
548
|
+
}
|
|
549
|
+
case 'documenter': {
|
|
550
|
+
const { formatDocReport } = await import('../agents/documenter.js');
|
|
551
|
+
await reportFn(formatDocReport(result.result));
|
|
552
|
+
break;
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
export async function requestApproval(decision, reportFn) {
|
|
557
|
+
if (!decision.task)
|
|
558
|
+
return;
|
|
559
|
+
const projectInfo = decision.task.linearProject?.name
|
|
560
|
+
? `📁 **${decision.task.linearProject.name}**\n`
|
|
561
|
+
: '';
|
|
562
|
+
const issueRef = decision.task.issueIdentifier || decision.task.issueId || 'N/A';
|
|
563
|
+
const embed = new EmbedBuilder()
|
|
564
|
+
.setTitle(t('runner.approval.title'))
|
|
565
|
+
.setColor(0xFFA500)
|
|
566
|
+
.setDescription(t('runner.approval.question', { project: projectInfo, title: decision.task.title }))
|
|
567
|
+
.addFields({ name: 'Issue', value: issueRef, inline: true }, { name: 'Priority', value: `P${decision.task.priority}`, inline: true }, { name: t('runner.approval.reason'), value: decision.reason, inline: false })
|
|
568
|
+
.setFooter({ text: t('runner.approval.footer') })
|
|
569
|
+
.setTimestamp();
|
|
570
|
+
await reportFn(embed);
|
|
571
|
+
if (decision.task.issueId) {
|
|
572
|
+
const parsed = await loadParsedTask(decision.task.issueId);
|
|
573
|
+
if (parsed) {
|
|
574
|
+
const summary = formatParsedTaskSummary(parsed);
|
|
575
|
+
await reportFn(`\`\`\`\n${summary.slice(0, 1800)}\n\`\`\``);
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
export async function reportExecutionResult(task, result, reportFn) {
|
|
580
|
+
const duration = (result.duration / 1000).toFixed(1);
|
|
581
|
+
const stepCount = Object.keys(result.execution.stepResults).length;
|
|
582
|
+
const completedCount = Object.values(result.execution.stepResults)
|
|
583
|
+
.filter(r => r.status === 'completed').length;
|
|
584
|
+
const projectPrefix = task.linearProject?.name ? `[${task.linearProject.name}] ` : '';
|
|
585
|
+
const taskDisplay = `${projectPrefix}${task.title}`;
|
|
586
|
+
if (result.success) {
|
|
587
|
+
const embed = new EmbedBuilder()
|
|
588
|
+
.setTitle(t('runner.result.taskCompleted'))
|
|
589
|
+
.setColor(0x00FF00)
|
|
590
|
+
.addFields({ name: t('runner.result.taskLabel'), value: taskDisplay, inline: false }, { name: t('runner.result.duration'), value: `${duration}s`, inline: true }, { name: t('runner.result.completedSteps'), value: `${completedCount}/${stepCount}`, inline: true })
|
|
591
|
+
.setTimestamp();
|
|
592
|
+
await reportFn(embed);
|
|
593
|
+
try {
|
|
594
|
+
await saveCognitiveMemory('strategy', `Autonomous execution succeeded: "${task.title}"`, { confidence: 0.8, derivedFrom: task.issueId });
|
|
595
|
+
}
|
|
596
|
+
catch (memErr) {
|
|
597
|
+
console.warn(`[AutonomousRunner] Memory save failed (non-critical):`, memErr);
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
else {
|
|
601
|
+
const embed = new EmbedBuilder()
|
|
602
|
+
.setTitle(t('runner.result.taskFailed'))
|
|
603
|
+
.setColor(0xFF0000)
|
|
604
|
+
.addFields({ name: t('runner.result.taskLabel'), value: taskDisplay, inline: false }, { name: t('runner.result.failedStep'), value: result.failedStep || 'Unknown', inline: true }, { name: t('runner.result.rollback'), value: result.rollbackPerformed ? '✅' : '❌', inline: true })
|
|
605
|
+
.setTimestamp();
|
|
606
|
+
await reportFn(embed);
|
|
607
|
+
const failedStepResult = result.execution.stepResults[result.failedStep || ''];
|
|
608
|
+
if (failedStepResult?.error) {
|
|
609
|
+
await reportFn(`\`\`\`\n${failedStepResult.error.slice(0, 1500)}\n\`\`\``);
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
export async function reconcileCompletionState(task) {
|
|
614
|
+
if (!task.issueId)
|
|
615
|
+
return;
|
|
616
|
+
const released = releaseDependentTasks(task.issueId);
|
|
617
|
+
for (const child of released) {
|
|
618
|
+
try {
|
|
619
|
+
await linear.updateIssueState(child.issueId, 'Todo');
|
|
620
|
+
await linear.addComment(child.issueId, buildTaskStateSyncComment(child, 'Task unblocked and ready'));
|
|
621
|
+
}
|
|
622
|
+
catch (err) {
|
|
623
|
+
console.warn(`[AutonomousRunner] Failed to release dependent task ${child.issueId}:`, err);
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
const parent = completeParentIfChildrenDone(task.issueId);
|
|
627
|
+
if (!parent)
|
|
628
|
+
return;
|
|
629
|
+
try {
|
|
630
|
+
await linear.updateIssueState(parent.issueId, 'Done');
|
|
631
|
+
await linear.addComment(parent.issueId, buildTaskStateSyncComment(parent, 'All child tasks completed'));
|
|
632
|
+
}
|
|
633
|
+
catch (err) {
|
|
634
|
+
console.warn(`[AutonomousRunner] Failed to complete parent task ${parent.issueId}:`, err);
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
export async function syncFailureState(task, reason) {
|
|
638
|
+
if (!task.issueId)
|
|
639
|
+
return;
|
|
640
|
+
const state = markTaskBlocked(task.issueId, reason, task.blockedBy || [], task.linearState);
|
|
641
|
+
try {
|
|
642
|
+
await linear.addComment(task.issueId, buildTaskStateSyncComment(state, 'Task blocked'));
|
|
643
|
+
}
|
|
644
|
+
catch (err) {
|
|
645
|
+
console.warn(`[AutonomousRunner] Failed to sync blocked state for ${task.issueId}:`, err);
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
export async function syncSuccessState(task, confidence) {
|
|
649
|
+
if (!task.issueId)
|
|
650
|
+
return;
|
|
651
|
+
const state = markTaskDone(task.issueId, {
|
|
652
|
+
issueIdentifier: task.issueIdentifier,
|
|
653
|
+
title: task.title,
|
|
654
|
+
confidence,
|
|
655
|
+
});
|
|
656
|
+
try {
|
|
657
|
+
await linear.addComment(task.issueId, buildTaskStateSyncComment(state, 'Task completed'));
|
|
658
|
+
}
|
|
659
|
+
catch (err) {
|
|
660
|
+
console.warn(`[AutonomousRunner] Failed to sync success state for ${task.issueId}:`, err);
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
//# sourceMappingURL=runnerExecution.js.map
|