@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 @@
|
|
|
1
|
+
{"version":3,"file":"discordCore.d.ts","sourceRoot":"","sources":["../../src/discord/discordCore.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,698 @@
|
|
|
1
|
+
// ============================================
|
|
2
|
+
// OpenSwarm - Discord Bot Core
|
|
3
|
+
//
|
|
4
|
+
// Entry point, shared state, history, config,
|
|
5
|
+
// events, and message routing.
|
|
6
|
+
import { Client, Events, GatewayIntentBits, TextChannel, EmbedBuilder, } from 'discord.js';
|
|
7
|
+
import { spawn } from 'node:child_process';
|
|
8
|
+
import fs from 'node:fs/promises';
|
|
9
|
+
import { extractCostFromJson, formatCost } from '../support/costTracker.js';
|
|
10
|
+
import * as memory from '../memory/index.js';
|
|
11
|
+
import { t, getPrompts, getDateLocale } from '../locale/index.js';
|
|
12
|
+
// Handler module (for routing)
|
|
13
|
+
import { handlePair } from './discordPair.js';
|
|
14
|
+
export let client = null;
|
|
15
|
+
export let reportChannelId = '';
|
|
16
|
+
// Allowed user IDs (loaded from environment variables)
|
|
17
|
+
const ALLOWED_USER_IDS = process.env.DISCORD_ALLOWED_USERS?.split(',').map(id => id.trim()) || [];
|
|
18
|
+
// OpenClaw-style History Management
|
|
19
|
+
// Per-channel history map (in-memory cache)
|
|
20
|
+
export const channelHistoryMap = new Map();
|
|
21
|
+
// History settings (based on OpenClaw defaults)
|
|
22
|
+
const HISTORY_LIMIT = 30; // Last 30 messages (OpenClaw default: 50)
|
|
23
|
+
const MAX_HISTORY_CHANNELS = 100; // Max channel count (LRU eviction)
|
|
24
|
+
// Context markers (OpenClaw style)
|
|
25
|
+
const HISTORY_CONTEXT_MARKER = '[Chat messages since your last reply - for context]';
|
|
26
|
+
const CURRENT_MESSAGE_MARKER = '[Current message]';
|
|
27
|
+
/**
|
|
28
|
+
* Evict old channel history entries using LRU
|
|
29
|
+
*/
|
|
30
|
+
function evictOldHistoryChannels() {
|
|
31
|
+
if (channelHistoryMap.size <= MAX_HISTORY_CHANNELS)
|
|
32
|
+
return;
|
|
33
|
+
const keysToDelete = channelHistoryMap.size - MAX_HISTORY_CHANNELS;
|
|
34
|
+
const iterator = channelHistoryMap.keys();
|
|
35
|
+
for (let i = 0; i < keysToDelete; i++) {
|
|
36
|
+
const key = iterator.next().value;
|
|
37
|
+
if (key)
|
|
38
|
+
channelHistoryMap.delete(key);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Append history entry
|
|
43
|
+
*/
|
|
44
|
+
export function appendHistoryEntry(channelId, entry) {
|
|
45
|
+
const history = channelHistoryMap.get(channelId) ?? [];
|
|
46
|
+
history.push(entry);
|
|
47
|
+
// Maintain max count
|
|
48
|
+
while (history.length > HISTORY_LIMIT) {
|
|
49
|
+
history.shift();
|
|
50
|
+
}
|
|
51
|
+
// LRU: delete existing key and re-insert (refresh order)
|
|
52
|
+
if (channelHistoryMap.has(channelId)) {
|
|
53
|
+
channelHistoryMap.delete(channelId);
|
|
54
|
+
}
|
|
55
|
+
channelHistoryMap.set(channelId, history);
|
|
56
|
+
evictOldHistoryChannels();
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Add response to the last history entry
|
|
60
|
+
*/
|
|
61
|
+
export function updateLastHistoryResponse(channelId, response) {
|
|
62
|
+
const history = channelHistoryMap.get(channelId);
|
|
63
|
+
if (history && history.length > 0) {
|
|
64
|
+
history[history.length - 1].response = response;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Format history entry (OpenClaw envelope style)
|
|
69
|
+
*/
|
|
70
|
+
function formatHistoryEntry(entry) {
|
|
71
|
+
const time = new Date(entry.timestamp).toLocaleTimeString(getDateLocale(), {
|
|
72
|
+
hour: '2-digit',
|
|
73
|
+
minute: '2-digit'
|
|
74
|
+
});
|
|
75
|
+
let formatted = `[${time}] ${entry.sender}: ${entry.body}`;
|
|
76
|
+
if (entry.response) {
|
|
77
|
+
// Include full response (no truncation)
|
|
78
|
+
formatted += `\n[${time}] OpenSwarm: ${entry.response}`;
|
|
79
|
+
}
|
|
80
|
+
return formatted;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Build channel history as context (OpenClaw style)
|
|
84
|
+
*/
|
|
85
|
+
export function buildHistoryContext(channelId, currentMessage) {
|
|
86
|
+
const history = channelHistoryMap.get(channelId) ?? [];
|
|
87
|
+
if (history.length === 0) {
|
|
88
|
+
return currentMessage;
|
|
89
|
+
}
|
|
90
|
+
// Exclude last entry (prevent duplication with current message)
|
|
91
|
+
const pastEntries = history.slice(0, -1);
|
|
92
|
+
if (pastEntries.length === 0) {
|
|
93
|
+
return currentMessage;
|
|
94
|
+
}
|
|
95
|
+
const historyText = pastEntries.map(formatHistoryEntry).join('\n\n');
|
|
96
|
+
return `${HISTORY_CONTEXT_MARKER}\n${historyText}\n\n${CURRENT_MESSAGE_MARKER}\n${currentMessage}`;
|
|
97
|
+
}
|
|
98
|
+
// Project Context Detection
|
|
99
|
+
import * as projectMapper from '../support/projectMapper.js';
|
|
100
|
+
// Default project scan paths
|
|
101
|
+
const PROJECT_BASE_PATHS = ['~/dev', '~/dev/tools', '~/projects'];
|
|
102
|
+
// Project name patterns (Linear issue IDs, project names, etc.)
|
|
103
|
+
const PROJECT_PATTERNS = [
|
|
104
|
+
// Extract project from Linear issue ID (e.g., INT-123, STONKS-456)
|
|
105
|
+
/\b([A-Z]{2,10})-\d+\b/g,
|
|
106
|
+
// Explicit project mentions
|
|
107
|
+
/\b(STONKS|VELA|PyKIS|pykis|pykiwoom|HIVE|OpenSwarm)\b/gi,
|
|
108
|
+
// "~~ project" pattern (Korean)
|
|
109
|
+
/(\w+)\s*프로젝트/gi,
|
|
110
|
+
];
|
|
111
|
+
// Issue prefix → project name mapping (based on Linear issue IDs)
|
|
112
|
+
const ISSUE_PREFIX_MAP = {
|
|
113
|
+
'INT': 'OpenSwarm', // HIVE project
|
|
114
|
+
'STONKS': 'STONKS',
|
|
115
|
+
'VELA': 'VELA',
|
|
116
|
+
'PYKIS': 'pykis',
|
|
117
|
+
'PKW': 'pykiwoom',
|
|
118
|
+
'SA': 'STONKS', // STONKS-SaaS
|
|
119
|
+
};
|
|
120
|
+
/**
|
|
121
|
+
* Extract project hints from message
|
|
122
|
+
*/
|
|
123
|
+
export function extractProjectHints(message) {
|
|
124
|
+
const hints = new Set();
|
|
125
|
+
for (const pattern of PROJECT_PATTERNS) {
|
|
126
|
+
const matches = message.matchAll(pattern);
|
|
127
|
+
for (const match of matches) {
|
|
128
|
+
const hint = match[1] || match[0];
|
|
129
|
+
hints.add(hint.toUpperCase());
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return Array.from(hints);
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Resolve local path from project hints
|
|
136
|
+
*/
|
|
137
|
+
export async function resolveProjectPath(hints) {
|
|
138
|
+
if (hints.length === 0)
|
|
139
|
+
return null;
|
|
140
|
+
// Scan local projects
|
|
141
|
+
const localProjects = await projectMapper.scanLocalProjects(PROJECT_BASE_PATHS);
|
|
142
|
+
for (const hint of hints) {
|
|
143
|
+
// 1. Check issue prefix mapping
|
|
144
|
+
const mappedName = ISSUE_PREFIX_MAP[hint];
|
|
145
|
+
if (mappedName) {
|
|
146
|
+
const match = projectMapper.findBestMatch(mappedName, localProjects);
|
|
147
|
+
if (match && match.confidence >= 0.7) {
|
|
148
|
+
console.log(`[ProjectContext] Resolved via prefix: ${hint} → ${match.project.path}`);
|
|
149
|
+
return match.project.path;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
// 2. Try direct matching
|
|
153
|
+
const match = projectMapper.findBestMatch(hint, localProjects);
|
|
154
|
+
if (match && match.confidence >= 0.6) {
|
|
155
|
+
console.log(`[ProjectContext] Resolved: ${hint} → ${match.project.path}`);
|
|
156
|
+
return match.project.path;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
// OpenSwarm system prompt - loaded from locale
|
|
162
|
+
export function getSystemPrompt() {
|
|
163
|
+
return getPrompts().systemPrompt;
|
|
164
|
+
}
|
|
165
|
+
// Callback functions (set from service)
|
|
166
|
+
export let onPauseAgent = null;
|
|
167
|
+
export let onResumeAgent = null;
|
|
168
|
+
export let getAgentStatus = null;
|
|
169
|
+
export let getGithubRepos = null;
|
|
170
|
+
// Pair mode configuration
|
|
171
|
+
export let pairModeConfig = null;
|
|
172
|
+
/**
|
|
173
|
+
* Set pair mode configuration
|
|
174
|
+
*/
|
|
175
|
+
export function setPairModeConfig(config) {
|
|
176
|
+
pairModeConfig = config ?? null;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Set callback functions
|
|
180
|
+
*/
|
|
181
|
+
export function setCallbacks(callbacks) {
|
|
182
|
+
onPauseAgent = callbacks.onPause;
|
|
183
|
+
onResumeAgent = callbacks.onResume;
|
|
184
|
+
getAgentStatus = callbacks.getStatus;
|
|
185
|
+
getGithubRepos = callbacks.getRepos;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Initialize and start Discord bot
|
|
189
|
+
*/
|
|
190
|
+
export async function initDiscord(token, channelId) {
|
|
191
|
+
reportChannelId = channelId;
|
|
192
|
+
client = new Client({
|
|
193
|
+
intents: [
|
|
194
|
+
GatewayIntentBits.Guilds,
|
|
195
|
+
GatewayIntentBits.GuildMessages,
|
|
196
|
+
GatewayIntentBits.MessageContent,
|
|
197
|
+
],
|
|
198
|
+
});
|
|
199
|
+
client.once(Events.ClientReady, () => {
|
|
200
|
+
console.log(`Discord bot logged in as ${client?.user?.tag}`);
|
|
201
|
+
});
|
|
202
|
+
client.on('messageCreate', handleMessage);
|
|
203
|
+
await client.login(token);
|
|
204
|
+
}
|
|
205
|
+
// Handler function imports (used within functions to prevent lazy load issues)
|
|
206
|
+
import { handleStatus, handleList, handleRun, handlePause, handleResume, handleIssues, handleIssue, handleLog, handleCI, handleNotifications, handleDev, handleRepos, handleTasks, handleCancel, handleLimits, handleSchedule, handleCodex, handleAuto, handleApprove, handleReject, handleTurbo, } from './discordHandlers.js';
|
|
207
|
+
/**
|
|
208
|
+
* Message handler
|
|
209
|
+
*/
|
|
210
|
+
async function handleMessage(msg) {
|
|
211
|
+
if (msg.author.bot)
|
|
212
|
+
return;
|
|
213
|
+
// Respond to regular messages from allowed users (excluding ! commands)
|
|
214
|
+
if (ALLOWED_USER_IDS.length > 0 &&
|
|
215
|
+
ALLOWED_USER_IDS.includes(msg.author.id) &&
|
|
216
|
+
!msg.content.startsWith('!')) {
|
|
217
|
+
await handleChat(msg);
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
if (!msg.content.startsWith('!'))
|
|
221
|
+
return;
|
|
222
|
+
// Access control: fail-closed (deny if no allowed users configured)
|
|
223
|
+
if (ALLOWED_USER_IDS.length === 0) {
|
|
224
|
+
await msg.reply('⛔ Access denied: DISCORD_ALLOWED_USERS not configured.');
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
if (!ALLOWED_USER_IDS.includes(msg.author.id)) {
|
|
228
|
+
await msg.reply('⛔ Access denied: unauthorized user.');
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
const [command, ...args] = msg.content.slice(1).split(' ');
|
|
232
|
+
try {
|
|
233
|
+
switch (command) {
|
|
234
|
+
case 'status':
|
|
235
|
+
await handleStatus(msg, args[0]);
|
|
236
|
+
break;
|
|
237
|
+
case 'list':
|
|
238
|
+
await handleList(msg);
|
|
239
|
+
break;
|
|
240
|
+
case 'run':
|
|
241
|
+
await handleRun(msg, args);
|
|
242
|
+
break;
|
|
243
|
+
case 'pause':
|
|
244
|
+
await handlePause(msg, args[0]);
|
|
245
|
+
break;
|
|
246
|
+
case 'resume':
|
|
247
|
+
await handleResume(msg, args[0]);
|
|
248
|
+
break;
|
|
249
|
+
case 'issues':
|
|
250
|
+
await handleIssues(msg, args[0]);
|
|
251
|
+
break;
|
|
252
|
+
case 'issue':
|
|
253
|
+
await handleIssue(msg, args[0]);
|
|
254
|
+
break;
|
|
255
|
+
case 'log':
|
|
256
|
+
await handleLog(msg, args[0], parseInt(args[1]) || 30);
|
|
257
|
+
break;
|
|
258
|
+
case 'ci':
|
|
259
|
+
await handleCI(msg);
|
|
260
|
+
break;
|
|
261
|
+
case 'notifications':
|
|
262
|
+
case 'notif':
|
|
263
|
+
await handleNotifications(msg);
|
|
264
|
+
break;
|
|
265
|
+
case 'dev':
|
|
266
|
+
await handleDev(msg, args);
|
|
267
|
+
break;
|
|
268
|
+
case 'repos':
|
|
269
|
+
await handleRepos(msg);
|
|
270
|
+
break;
|
|
271
|
+
case 'tasks':
|
|
272
|
+
await handleTasks(msg);
|
|
273
|
+
break;
|
|
274
|
+
case 'cancel':
|
|
275
|
+
await handleCancel(msg, args[0]);
|
|
276
|
+
break;
|
|
277
|
+
case 'limits':
|
|
278
|
+
await handleLimits(msg);
|
|
279
|
+
break;
|
|
280
|
+
case 'schedule':
|
|
281
|
+
case 'schedules':
|
|
282
|
+
await handleSchedule(msg, args);
|
|
283
|
+
break;
|
|
284
|
+
case 'codex':
|
|
285
|
+
await handleCodex(msg, args);
|
|
286
|
+
break;
|
|
287
|
+
case 'auto':
|
|
288
|
+
await handleAuto(msg, args);
|
|
289
|
+
break;
|
|
290
|
+
case 'approve':
|
|
291
|
+
await handleApprove(msg);
|
|
292
|
+
break;
|
|
293
|
+
case 'reject':
|
|
294
|
+
await handleReject(msg);
|
|
295
|
+
break;
|
|
296
|
+
case 'turbo':
|
|
297
|
+
await handleTurbo(msg, args[0]);
|
|
298
|
+
break;
|
|
299
|
+
case 'pair':
|
|
300
|
+
await handlePair(msg, args);
|
|
301
|
+
break;
|
|
302
|
+
case 'help':
|
|
303
|
+
await handleHelp(msg);
|
|
304
|
+
break;
|
|
305
|
+
default:
|
|
306
|
+
await msg.reply(t('discord.errors.unknownCommand', { command }));
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
catch (err) {
|
|
310
|
+
console.error('Command error:', err);
|
|
311
|
+
await msg.reply(t('discord.errors.commandError', { error: err instanceof Error ? err.message : String(err) }));
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* !help - Show help
|
|
316
|
+
*/
|
|
317
|
+
async function handleHelp(msg) {
|
|
318
|
+
await msg.reply(t('discord.help'));
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Report event to Discord
|
|
322
|
+
*/
|
|
323
|
+
export async function reportEvent(event) {
|
|
324
|
+
if (!client)
|
|
325
|
+
return;
|
|
326
|
+
const channel = await client.channels.fetch(reportChannelId);
|
|
327
|
+
if (!channel || !(channel instanceof TextChannel))
|
|
328
|
+
return;
|
|
329
|
+
const emoji = {
|
|
330
|
+
issue_started: '🚀',
|
|
331
|
+
issue_completed: '✅',
|
|
332
|
+
issue_blocked: '⚠️',
|
|
333
|
+
build_failed: '❌',
|
|
334
|
+
test_failed: '❌',
|
|
335
|
+
ci_failed: '🔴',
|
|
336
|
+
ci_recovered: '🟢',
|
|
337
|
+
github_notification: '📬',
|
|
338
|
+
commit: '📝',
|
|
339
|
+
error: '🔥',
|
|
340
|
+
pr_improved: '🔧',
|
|
341
|
+
pr_failed: '💔',
|
|
342
|
+
pr_conflict_detected: '⚡',
|
|
343
|
+
pr_conflict_resolving: '🔄',
|
|
344
|
+
pr_conflict_resolved: '✅',
|
|
345
|
+
pr_conflict_failed: '💥',
|
|
346
|
+
}[event.type] ?? '📢';
|
|
347
|
+
const embed = new EmbedBuilder()
|
|
348
|
+
.setTitle(`${emoji} [${event.session}] ${event.type.replace(/_/g, ' ')}`)
|
|
349
|
+
.setDescription(event.message)
|
|
350
|
+
.setColor(event.type.includes('failed') || event.type === 'error' ? 0xff0000 : 0x00ae86)
|
|
351
|
+
.setTimestamp(event.timestamp);
|
|
352
|
+
if (event.issueId) {
|
|
353
|
+
embed.addFields({ name: 'Issue', value: event.issueId });
|
|
354
|
+
}
|
|
355
|
+
if (event.url) {
|
|
356
|
+
embed.setURL(event.url);
|
|
357
|
+
}
|
|
358
|
+
await channel.send({ embeds: [embed] });
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Format time (relative)
|
|
362
|
+
*/
|
|
363
|
+
export function formatTimeAgo(timestamp) {
|
|
364
|
+
const diff = Date.now() - timestamp;
|
|
365
|
+
const minutes = Math.floor(diff / 60000);
|
|
366
|
+
const hours = Math.floor(minutes / 60);
|
|
367
|
+
if (hours > 0)
|
|
368
|
+
return t('common.timeAgo.hoursAgo', { n: hours });
|
|
369
|
+
if (minutes > 0)
|
|
370
|
+
return t('common.timeAgo.minutesAgo', { n: minutes });
|
|
371
|
+
return t('common.timeAgo.justNow');
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Stop Discord bot
|
|
375
|
+
*/
|
|
376
|
+
export async function stopDiscord() {
|
|
377
|
+
if (client) {
|
|
378
|
+
await client.destroy();
|
|
379
|
+
client = null;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* Send message to default Discord channel (for external callers)
|
|
384
|
+
*/
|
|
385
|
+
export async function sendToChannel(content) {
|
|
386
|
+
if (!client || !reportChannelId)
|
|
387
|
+
return;
|
|
388
|
+
try {
|
|
389
|
+
const channel = await client.channels.fetch(reportChannelId);
|
|
390
|
+
if (!channel)
|
|
391
|
+
return;
|
|
392
|
+
// If string, respect Discord 4000 char limit (split send)
|
|
393
|
+
if (typeof content === 'string' && content.length > 3900) {
|
|
394
|
+
const chunks = splitForDiscord(content, 3900);
|
|
395
|
+
for (const chunk of chunks) {
|
|
396
|
+
await channel.send(chunk);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
else {
|
|
400
|
+
await channel.send(content);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
catch (err) {
|
|
404
|
+
console.error('[Discord] Send to channel failed:', err);
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
function splitForDiscord(text, maxLen) {
|
|
408
|
+
const chunks = [];
|
|
409
|
+
let remaining = text;
|
|
410
|
+
while (remaining.length > 0) {
|
|
411
|
+
if (remaining.length <= maxLen) {
|
|
412
|
+
chunks.push(remaining);
|
|
413
|
+
break;
|
|
414
|
+
}
|
|
415
|
+
let splitAt = remaining.lastIndexOf('\n', maxLen);
|
|
416
|
+
if (splitAt === -1 || splitAt < maxLen / 2) {
|
|
417
|
+
splitAt = remaining.lastIndexOf(' ', maxLen);
|
|
418
|
+
}
|
|
419
|
+
if (splitAt === -1 || splitAt < maxLen / 2) {
|
|
420
|
+
splitAt = maxLen;
|
|
421
|
+
}
|
|
422
|
+
chunks.push(remaining.slice(0, splitAt));
|
|
423
|
+
remaining = remaining.slice(splitAt).trimStart();
|
|
424
|
+
}
|
|
425
|
+
return chunks;
|
|
426
|
+
}
|
|
427
|
+
/**
|
|
428
|
+
* Send message to Discord thread (for external callers)
|
|
429
|
+
*/
|
|
430
|
+
export async function sendToThread(threadId, content) {
|
|
431
|
+
if (!client)
|
|
432
|
+
return;
|
|
433
|
+
try {
|
|
434
|
+
const thread = await client.channels.fetch(threadId);
|
|
435
|
+
if (!thread || !thread.isThread())
|
|
436
|
+
return;
|
|
437
|
+
if (typeof content === 'string') {
|
|
438
|
+
await thread.send(content);
|
|
439
|
+
}
|
|
440
|
+
else {
|
|
441
|
+
await thread.send({ embeds: [content] });
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
catch (err) {
|
|
445
|
+
console.error('[Discord] Send to thread failed:', err);
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
// OpenSwarm Chat Feature
|
|
449
|
+
// Chat history storage path
|
|
450
|
+
const CHAT_HISTORY_FILE = '/tmp/openswarm-chat-history.json';
|
|
451
|
+
/**
|
|
452
|
+
* Handle general chat (OpenClaw-style history management)
|
|
453
|
+
*/
|
|
454
|
+
export async function handleChat(msg) {
|
|
455
|
+
const content = msg.content.trim();
|
|
456
|
+
if (!content)
|
|
457
|
+
return;
|
|
458
|
+
console.log(`[OpenSwarm] Chat from ${msg.author.username}: ${content.slice(0, 50)}...`);
|
|
459
|
+
const channel = msg.channel;
|
|
460
|
+
const channelId = msg.channel.id;
|
|
461
|
+
// Show typing indicator (refresh every 8 seconds)
|
|
462
|
+
let typingInterval = null;
|
|
463
|
+
if ('sendTyping' in channel) {
|
|
464
|
+
channel.sendTyping();
|
|
465
|
+
typingInterval = setInterval(() => channel.sendTyping(), 8000);
|
|
466
|
+
}
|
|
467
|
+
// Add current message to history (response updated later)
|
|
468
|
+
appendHistoryEntry(channelId, {
|
|
469
|
+
sender: msg.author.username,
|
|
470
|
+
senderId: msg.author.id,
|
|
471
|
+
body: content,
|
|
472
|
+
timestamp: Date.now(),
|
|
473
|
+
messageId: msg.id,
|
|
474
|
+
});
|
|
475
|
+
try {
|
|
476
|
+
// 0. Detect project path (extract hints from message + history)
|
|
477
|
+
const historyMessages = channelHistoryMap.get(channelId) ?? [];
|
|
478
|
+
const allMessages = historyMessages.map(h => h.body).join(' ') + ' ' + content;
|
|
479
|
+
const projectHints = extractProjectHints(allMessages);
|
|
480
|
+
const projectPath = await resolveProjectPath(projectHints);
|
|
481
|
+
if (projectPath) {
|
|
482
|
+
console.log(`[OpenSwarm] Project detected: ${projectPath}`);
|
|
483
|
+
}
|
|
484
|
+
// 1. Build channel history context
|
|
485
|
+
const currentMessageFormatted = `[${new Date().toLocaleTimeString(getDateLocale(), { hour: '2-digit', minute: '2-digit' })}] ${msg.author.username}: ${content}`;
|
|
486
|
+
const historyContext = buildHistoryContext(channelId, currentMessageFormatted);
|
|
487
|
+
// 2. Semantic search (long-term memory)
|
|
488
|
+
const memories = await memory.searchMemory(content, {
|
|
489
|
+
limit: 5,
|
|
490
|
+
minSimilarity: 0.4,
|
|
491
|
+
minTrust: 0.5,
|
|
492
|
+
});
|
|
493
|
+
const memoryContext = memory.formatMemoryContext(memories);
|
|
494
|
+
// 3. Build prompt
|
|
495
|
+
let prompt = getSystemPrompt();
|
|
496
|
+
if (projectPath) {
|
|
497
|
+
prompt += `\n\n## ${t('discord.chatContext')}\n- **${t('discord.projectContext', { path: projectPath })}**`;
|
|
498
|
+
}
|
|
499
|
+
prompt += `\n\n## Chat Context\n${historyContext}`;
|
|
500
|
+
if (memoryContext) {
|
|
501
|
+
prompt += `\n\n${memoryContext}`;
|
|
502
|
+
}
|
|
503
|
+
console.log(`[OpenSwarm] History context: ${channelHistoryMap.get(channelId)?.length ?? 0} messages`);
|
|
504
|
+
// Run Claude CLI
|
|
505
|
+
const { result: response, toolCalls } = await runClaude(prompt, { cwd: projectPath || undefined });
|
|
506
|
+
if (typingInterval)
|
|
507
|
+
clearInterval(typingInterval);
|
|
508
|
+
updateLastHistoryResponse(channelId, response);
|
|
509
|
+
if (toolCalls.length > 0) {
|
|
510
|
+
const toolSummary = toolCalls.slice(0, 10).map(tc => `• ${tc}`).join('\n');
|
|
511
|
+
const toolMsg = `🔧 **${t('discord.toolCalls', { n: toolCalls.length })}**\n${toolSummary}${toolCalls.length > 10 ? `\n... ${t('common.moreItems', { n: toolCalls.length - 10 })}` : ''}`;
|
|
512
|
+
await msg.reply(toolMsg);
|
|
513
|
+
}
|
|
514
|
+
const chunks = splitMessage(response, 2000);
|
|
515
|
+
for (const chunk of chunks) {
|
|
516
|
+
await msg.reply(chunk);
|
|
517
|
+
}
|
|
518
|
+
await saveChatHistory({
|
|
519
|
+
timestamp: new Date().toISOString(),
|
|
520
|
+
user: msg.author.username,
|
|
521
|
+
userId: msg.author.id,
|
|
522
|
+
message: content,
|
|
523
|
+
response: response,
|
|
524
|
+
});
|
|
525
|
+
await memory.saveConversation(channelId, msg.author.id, msg.author.username, content, response);
|
|
526
|
+
console.log(`[OpenSwarm] Response sent (${response.length} chars)`);
|
|
527
|
+
}
|
|
528
|
+
catch (err) {
|
|
529
|
+
if (typingInterval)
|
|
530
|
+
clearInterval(typingInterval);
|
|
531
|
+
console.error('[OpenSwarm] Error:', err);
|
|
532
|
+
await msg.reply(t('discord.chatError'));
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
// Currently running OpenSwarm Claude process
|
|
536
|
+
let currentClaudeProcess = null;
|
|
537
|
+
/**
|
|
538
|
+
* Run Claude CLI
|
|
539
|
+
*/
|
|
540
|
+
async function runClaude(prompt, options) {
|
|
541
|
+
if (currentClaudeProcess) {
|
|
542
|
+
console.log('[Claude CLI] Killing previous process...');
|
|
543
|
+
currentClaudeProcess.kill('SIGKILL');
|
|
544
|
+
currentClaudeProcess = null;
|
|
545
|
+
}
|
|
546
|
+
const workingDir = options?.cwd || process.cwd();
|
|
547
|
+
return new Promise((resolve, reject) => {
|
|
548
|
+
console.log(`[Claude CLI] Starting in ${workingDir}...`);
|
|
549
|
+
const proc = spawn('claude', [
|
|
550
|
+
'-p', prompt,
|
|
551
|
+
'--output-format', 'json',
|
|
552
|
+
'--permission-mode', 'bypassPermissions',
|
|
553
|
+
], {
|
|
554
|
+
shell: false,
|
|
555
|
+
cwd: workingDir,
|
|
556
|
+
env: process.env,
|
|
557
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
558
|
+
});
|
|
559
|
+
currentClaudeProcess = proc;
|
|
560
|
+
let stdout = '';
|
|
561
|
+
let stderr = '';
|
|
562
|
+
proc.stdout?.on('data', (data) => { stdout += data.toString(); });
|
|
563
|
+
proc.stderr?.on('data', (data) => { stderr += data.toString(); });
|
|
564
|
+
proc.on('close', (code) => {
|
|
565
|
+
currentClaudeProcess = null;
|
|
566
|
+
if (code !== 0 && code !== null) {
|
|
567
|
+
console.error('[Claude CLI] Error:', stderr.slice(0, 200));
|
|
568
|
+
reject(new Error(`Claude CLI failed with code ${code}`));
|
|
569
|
+
return;
|
|
570
|
+
}
|
|
571
|
+
resolve(parseClaudeJson(stdout));
|
|
572
|
+
});
|
|
573
|
+
proc.on('error', (err) => {
|
|
574
|
+
currentClaudeProcess = null;
|
|
575
|
+
reject(new Error(`Claude CLI spawn error: ${err.message}`));
|
|
576
|
+
});
|
|
577
|
+
});
|
|
578
|
+
}
|
|
579
|
+
// Destructive command patterns
|
|
580
|
+
const DESTRUCTIVE_PATTERNS = [
|
|
581
|
+
/\brm\s+(-[rf]+\s+)*.*(-[rf]+|--recursive|--force)/i,
|
|
582
|
+
/\bgit\s+(reset\s+--hard|clean\s+-[fd])/i,
|
|
583
|
+
/\b(drop|truncate)\s+(database|table)/i,
|
|
584
|
+
/\bchmod\s+777/i,
|
|
585
|
+
/\bdd\s+if=/i,
|
|
586
|
+
/>\s*\/dev\/sd[a-z]/i,
|
|
587
|
+
];
|
|
588
|
+
/**
|
|
589
|
+
* Parse Claude JSON output
|
|
590
|
+
*/
|
|
591
|
+
function parseClaudeJson(output) {
|
|
592
|
+
const toolCalls = [];
|
|
593
|
+
// Extract cost
|
|
594
|
+
const costInfo = extractCostFromJson(output);
|
|
595
|
+
if (costInfo) {
|
|
596
|
+
console.log(`[Discord] Claude cost: ${formatCost(costInfo)}`);
|
|
597
|
+
}
|
|
598
|
+
try {
|
|
599
|
+
const match = output.match(/\[[\s\S]*\]/);
|
|
600
|
+
if (!match)
|
|
601
|
+
return { result: output.trim() || t('common.fallback.noResponse'), toolCalls };
|
|
602
|
+
const arr = JSON.parse(match[0]);
|
|
603
|
+
let result = t('common.fallback.noResponse');
|
|
604
|
+
for (const item of arr) {
|
|
605
|
+
if (item.type === 'tool_use') {
|
|
606
|
+
const toolName = item.name || 'unknown';
|
|
607
|
+
let toolSummary = toolName;
|
|
608
|
+
if (toolName === 'Bash' && item.input?.command) {
|
|
609
|
+
const cmd = item.input.command.slice(0, 80);
|
|
610
|
+
toolSummary = `Bash: \`${cmd}${item.input.command.length > 80 ? '...' : ''}\``;
|
|
611
|
+
for (const pattern of DESTRUCTIVE_PATTERNS) {
|
|
612
|
+
if (pattern.test(item.input.command)) {
|
|
613
|
+
toolSummary = `⛔ BLOCKED: ${cmd}`;
|
|
614
|
+
console.warn(`[OpenSwarm] Destructive command detected: ${item.input.command}`);
|
|
615
|
+
break;
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
else if (['Read', 'Write', 'Edit'].includes(toolName) && item.input?.file_path) {
|
|
620
|
+
const path = item.input.file_path.split('/').slice(-2).join('/');
|
|
621
|
+
toolSummary = `${toolName}: \`${path}\``;
|
|
622
|
+
}
|
|
623
|
+
else if (toolName === 'Grep' && item.input?.pattern) {
|
|
624
|
+
toolSummary = `Grep: \`${item.input.pattern}\``;
|
|
625
|
+
}
|
|
626
|
+
toolCalls.push(toolSummary);
|
|
627
|
+
}
|
|
628
|
+
if (item.type === 'result' && item.result) {
|
|
629
|
+
result = item.result;
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
return { result, toolCalls };
|
|
633
|
+
}
|
|
634
|
+
catch {
|
|
635
|
+
return { result: output.trim() || t('common.fallback.noResponse'), toolCalls };
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
/**
|
|
639
|
+
* Split message
|
|
640
|
+
*/
|
|
641
|
+
function splitMessage(text, maxLen) {
|
|
642
|
+
if (text.length <= maxLen)
|
|
643
|
+
return [text];
|
|
644
|
+
const chunks = [];
|
|
645
|
+
let remaining = text;
|
|
646
|
+
while (remaining.length > 0) {
|
|
647
|
+
if (remaining.length <= maxLen) {
|
|
648
|
+
chunks.push(remaining);
|
|
649
|
+
break;
|
|
650
|
+
}
|
|
651
|
+
let splitAt = remaining.lastIndexOf('\n', maxLen);
|
|
652
|
+
if (splitAt === -1 || splitAt < maxLen / 2) {
|
|
653
|
+
splitAt = remaining.lastIndexOf(' ', maxLen);
|
|
654
|
+
}
|
|
655
|
+
if (splitAt === -1 || splitAt < maxLen / 2) {
|
|
656
|
+
splitAt = maxLen;
|
|
657
|
+
}
|
|
658
|
+
chunks.push(remaining.slice(0, splitAt));
|
|
659
|
+
remaining = remaining.slice(splitAt).trimStart();
|
|
660
|
+
}
|
|
661
|
+
return chunks;
|
|
662
|
+
}
|
|
663
|
+
/**
|
|
664
|
+
* Save chat history
|
|
665
|
+
*/
|
|
666
|
+
async function saveChatHistory(entry) {
|
|
667
|
+
try {
|
|
668
|
+
let history = [];
|
|
669
|
+
try {
|
|
670
|
+
const data = await fs.readFile(CHAT_HISTORY_FILE, 'utf-8');
|
|
671
|
+
history = JSON.parse(data);
|
|
672
|
+
}
|
|
673
|
+
catch {
|
|
674
|
+
// Empty array if file doesn't exist
|
|
675
|
+
}
|
|
676
|
+
history.push(entry);
|
|
677
|
+
if (history.length > 100) {
|
|
678
|
+
history = history.slice(-100);
|
|
679
|
+
}
|
|
680
|
+
await fs.writeFile(CHAT_HISTORY_FILE, JSON.stringify(history, null, 2));
|
|
681
|
+
}
|
|
682
|
+
catch (err) {
|
|
683
|
+
console.error('[OpenSwarm] Failed to save chat history:', err);
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
/**
|
|
687
|
+
* Get chat history (for web API)
|
|
688
|
+
*/
|
|
689
|
+
export async function getChatHistory() {
|
|
690
|
+
try {
|
|
691
|
+
const data = await fs.readFile(CHAT_HISTORY_FILE, 'utf-8');
|
|
692
|
+
return JSON.parse(data);
|
|
693
|
+
}
|
|
694
|
+
catch {
|
|
695
|
+
return [];
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
//# sourceMappingURL=discordCore.js.map
|