octo-vec 1.0.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/README.md +646 -0
- package/core/prompts/architect.md +124 -0
- package/core/prompts/ba.md +117 -0
- package/core/prompts/backend.md +154 -0
- package/core/prompts/compliance.md +127 -0
- package/core/prompts/dataanalyst.md +126 -0
- package/core/prompts/dataengineer.md +155 -0
- package/core/prompts/dba.md +155 -0
- package/core/prompts/designer.md +145 -0
- package/core/prompts/dev.md +148 -0
- package/core/prompts/devops.md +127 -0
- package/core/prompts/frontend.md +151 -0
- package/core/prompts/mlengineer.md +156 -0
- package/core/prompts/mobile.md +155 -0
- package/core/prompts/pm.md +182 -0
- package/core/prompts/productowner.md +122 -0
- package/core/prompts/qa.md +135 -0
- package/core/prompts/releasemanager.md +138 -0
- package/core/prompts/researcher.md +122 -0
- package/core/prompts/scrummaster.md +125 -0
- package/core/prompts/security.md +127 -0
- package/core/prompts/sre.md +141 -0
- package/core/prompts/support.md +138 -0
- package/core/prompts/techwriter.md +123 -0
- package/core/roster.json +1161 -0
- package/dashboard/dist/assets/index--L-aFRgh.css +1 -0
- package/dashboard/dist/assets/index-BoOVmAFf.js +523 -0
- package/dashboard/dist/icons/integrations/gitleaks.svg +6 -0
- package/dashboard/dist/icons/integrations/searxng.svg +5 -0
- package/dashboard/dist/icons/integrations/semgrep.svg +4 -0
- package/dashboard/dist/icons/integrations/slack.svg +6 -0
- package/dashboard/dist/icons/integrations/sonarqube.svg +5 -0
- package/dashboard/dist/icons/integrations/telegram.svg +4 -0
- package/dashboard/dist/icons/integrations/trivy.svg +5 -0
- package/dashboard/dist/icons/providers/anthropic.svg +1 -0
- package/dashboard/dist/icons/providers/antigravity.svg +1 -0
- package/dashboard/dist/icons/providers/azure.svg +1 -0
- package/dashboard/dist/icons/providers/bedrock.svg +1 -0
- package/dashboard/dist/icons/providers/cerebras.svg +1 -0
- package/dashboard/dist/icons/providers/chatglm.svg +1 -0
- package/dashboard/dist/icons/providers/codex.svg +1 -0
- package/dashboard/dist/icons/providers/gemini.svg +1 -0
- package/dashboard/dist/icons/providers/githubcopilot.svg +1 -0
- package/dashboard/dist/icons/providers/googlecloud.svg +1 -0
- package/dashboard/dist/icons/providers/groq.svg +1 -0
- package/dashboard/dist/icons/providers/huggingface.svg +1 -0
- package/dashboard/dist/icons/providers/kimi.svg +1 -0
- package/dashboard/dist/icons/providers/minimax.svg +1 -0
- package/dashboard/dist/icons/providers/mistral.svg +1 -0
- package/dashboard/dist/icons/providers/openai.svg +1 -0
- package/dashboard/dist/icons/providers/openrouter.svg +1 -0
- package/dashboard/dist/icons/providers/vercel.svg +1 -0
- package/dashboard/dist/icons/providers/xai.svg +1 -0
- package/dashboard/dist/index.html +17 -0
- package/dist/agents/pmAgent.d.ts +40 -0
- package/dist/agents/pmAgent.d.ts.map +1 -0
- package/dist/agents/pmAgent.js +181 -0
- package/dist/agents/pmAgent.js.map +1 -0
- package/dist/ar/baseSpecialist.d.ts +36 -0
- package/dist/ar/baseSpecialist.d.ts.map +1 -0
- package/dist/ar/baseSpecialist.js +292 -0
- package/dist/ar/baseSpecialist.js.map +1 -0
- package/dist/ar/promptLoader.d.ts +10 -0
- package/dist/ar/promptLoader.d.ts.map +1 -0
- package/dist/ar/promptLoader.js +22 -0
- package/dist/ar/promptLoader.js.map +1 -0
- package/dist/ar/registry.d.ts +12 -0
- package/dist/ar/registry.d.ts.map +1 -0
- package/dist/ar/registry.js +22 -0
- package/dist/ar/registry.js.map +1 -0
- package/dist/ar/roster.d.ts +104 -0
- package/dist/ar/roster.d.ts.map +1 -0
- package/dist/ar/roster.js +245 -0
- package/dist/ar/roster.js.map +1 -0
- package/dist/ar/toolProfiles.d.ts +18 -0
- package/dist/ar/toolProfiles.d.ts.map +1 -0
- package/dist/ar/toolProfiles.js +89 -0
- package/dist/ar/toolProfiles.js.map +1 -0
- package/dist/atp/agentGroups.d.ts +39 -0
- package/dist/atp/agentGroups.d.ts.map +1 -0
- package/dist/atp/agentGroups.js +109 -0
- package/dist/atp/agentGroups.js.map +1 -0
- package/dist/atp/agentInterrupt.d.ts +31 -0
- package/dist/atp/agentInterrupt.d.ts.map +1 -0
- package/dist/atp/agentInterrupt.js +51 -0
- package/dist/atp/agentInterrupt.js.map +1 -0
- package/dist/atp/agentMessageQueue.d.ts +74 -0
- package/dist/atp/agentMessageQueue.d.ts.map +1 -0
- package/dist/atp/agentMessageQueue.js +218 -0
- package/dist/atp/agentMessageQueue.js.map +1 -0
- package/dist/atp/agentRuntime.d.ts +67 -0
- package/dist/atp/agentRuntime.d.ts.map +1 -0
- package/dist/atp/agentRuntime.js +279 -0
- package/dist/atp/agentRuntime.js.map +1 -0
- package/dist/atp/agentStreamBus.d.ts +35 -0
- package/dist/atp/agentStreamBus.d.ts.map +1 -0
- package/dist/atp/agentStreamBus.js +159 -0
- package/dist/atp/agentStreamBus.js.map +1 -0
- package/dist/atp/agentToolConfig.d.ts +38 -0
- package/dist/atp/agentToolConfig.d.ts.map +1 -0
- package/dist/atp/agentToolConfig.js +225 -0
- package/dist/atp/agentToolConfig.js.map +1 -0
- package/dist/atp/chatLog.d.ts +34 -0
- package/dist/atp/chatLog.d.ts.map +1 -0
- package/dist/atp/chatLog.js +59 -0
- package/dist/atp/chatLog.js.map +1 -0
- package/dist/atp/codexAuth.d.ts +6 -0
- package/dist/atp/codexAuth.d.ts.map +1 -0
- package/dist/atp/codexAuth.js +44 -0
- package/dist/atp/codexAuth.js.map +1 -0
- package/dist/atp/database.d.ts +54 -0
- package/dist/atp/database.d.ts.map +1 -0
- package/dist/atp/database.js +323 -0
- package/dist/atp/database.js.map +1 -0
- package/dist/atp/eventLog.d.ts +12 -0
- package/dist/atp/eventLog.d.ts.map +1 -0
- package/dist/atp/eventLog.js +60 -0
- package/dist/atp/eventLog.js.map +1 -0
- package/dist/atp/inboxLoop.d.ts +72 -0
- package/dist/atp/inboxLoop.d.ts.map +1 -0
- package/dist/atp/inboxLoop.js +482 -0
- package/dist/atp/inboxLoop.js.map +1 -0
- package/dist/atp/llmDebug.d.ts +18 -0
- package/dist/atp/llmDebug.d.ts.map +1 -0
- package/dist/atp/llmDebug.js +97 -0
- package/dist/atp/llmDebug.js.map +1 -0
- package/dist/atp/messageDebouncer.d.ts +34 -0
- package/dist/atp/messageDebouncer.d.ts.map +1 -0
- package/dist/atp/messageDebouncer.js +60 -0
- package/dist/atp/messageDebouncer.js.map +1 -0
- package/dist/atp/messageQueue.d.ts +17 -0
- package/dist/atp/messageQueue.d.ts.map +1 -0
- package/dist/atp/messageQueue.js +69 -0
- package/dist/atp/messageQueue.js.map +1 -0
- package/dist/atp/modelConfig.d.ts +46 -0
- package/dist/atp/modelConfig.d.ts.map +1 -0
- package/dist/atp/modelConfig.js +232 -0
- package/dist/atp/modelConfig.js.map +1 -0
- package/dist/atp/models.d.ts +87 -0
- package/dist/atp/models.d.ts.map +1 -0
- package/dist/atp/models.js +45 -0
- package/dist/atp/models.js.map +1 -0
- package/dist/atp/postTaskHooks.d.ts +21 -0
- package/dist/atp/postTaskHooks.d.ts.map +1 -0
- package/dist/atp/postTaskHooks.js +89 -0
- package/dist/atp/postTaskHooks.js.map +1 -0
- package/dist/atp/tokenTracker.d.ts +46 -0
- package/dist/atp/tokenTracker.d.ts.map +1 -0
- package/dist/atp/tokenTracker.js +120 -0
- package/dist/atp/tokenTracker.js.map +1 -0
- package/dist/channels/activeChannel.d.ts +14 -0
- package/dist/channels/activeChannel.d.ts.map +1 -0
- package/dist/channels/activeChannel.js +18 -0
- package/dist/channels/activeChannel.js.map +1 -0
- package/dist/channels/channelConfig.d.ts +61 -0
- package/dist/channels/channelConfig.d.ts.map +1 -0
- package/dist/channels/channelConfig.js +130 -0
- package/dist/channels/channelConfig.js.map +1 -0
- package/dist/channels/channelManager.d.ts +22 -0
- package/dist/channels/channelManager.d.ts.map +1 -0
- package/dist/channels/channelManager.js +77 -0
- package/dist/channels/channelManager.js.map +1 -0
- package/dist/channels/discord.d.ts +24 -0
- package/dist/channels/discord.d.ts.map +1 -0
- package/dist/channels/discord.js +276 -0
- package/dist/channels/discord.js.map +1 -0
- package/dist/channels/slack.d.ts +25 -0
- package/dist/channels/slack.d.ts.map +1 -0
- package/dist/channels/slack.js +313 -0
- package/dist/channels/slack.js.map +1 -0
- package/dist/channels/telegram.d.ts +20 -0
- package/dist/channels/telegram.d.ts.map +1 -0
- package/dist/channels/telegram.js +273 -0
- package/dist/channels/telegram.js.map +1 -0
- package/dist/channels/types.d.ts +12 -0
- package/dist/channels/types.d.ts.map +1 -0
- package/dist/channels/types.js +5 -0
- package/dist/channels/types.js.map +1 -0
- package/dist/config.d.ts +82 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +144 -0
- package/dist/config.js.map +1 -0
- package/dist/dashboard/security.d.ts +68 -0
- package/dist/dashboard/security.d.ts.map +1 -0
- package/dist/dashboard/security.js +178 -0
- package/dist/dashboard/security.js.map +1 -0
- package/dist/dashboard/securityHelpers.d.ts +10 -0
- package/dist/dashboard/securityHelpers.d.ts.map +1 -0
- package/dist/dashboard/securityHelpers.js +22 -0
- package/dist/dashboard/securityHelpers.js.map +1 -0
- package/dist/dashboard/server.d.ts +18 -0
- package/dist/dashboard/server.d.ts.map +1 -0
- package/dist/dashboard/server.js +3207 -0
- package/dist/dashboard/server.js.map +1 -0
- package/dist/flows/codeScanFlow.d.ts +14 -0
- package/dist/flows/codeScanFlow.d.ts.map +1 -0
- package/dist/flows/codeScanFlow.js +204 -0
- package/dist/flows/codeScanFlow.js.map +1 -0
- package/dist/flows/gitleaksScanFlow.d.ts +12 -0
- package/dist/flows/gitleaksScanFlow.d.ts.map +1 -0
- package/dist/flows/gitleaksScanFlow.js +205 -0
- package/dist/flows/gitleaksScanFlow.js.map +1 -0
- package/dist/flows/index.d.ts +30 -0
- package/dist/flows/index.d.ts.map +1 -0
- package/dist/flows/index.js +43 -0
- package/dist/flows/index.js.map +1 -0
- package/dist/flows/semgrepScanFlow.d.ts +13 -0
- package/dist/flows/semgrepScanFlow.d.ts.map +1 -0
- package/dist/flows/semgrepScanFlow.js +211 -0
- package/dist/flows/semgrepScanFlow.js.map +1 -0
- package/dist/flows/trivyScanFlow.d.ts +13 -0
- package/dist/flows/trivyScanFlow.d.ts.map +1 -0
- package/dist/flows/trivyScanFlow.js +198 -0
- package/dist/flows/trivyScanFlow.js.map +1 -0
- package/dist/identity.d.ts +22 -0
- package/dist/identity.d.ts.map +1 -0
- package/dist/identity.js +34 -0
- package/dist/identity.js.map +1 -0
- package/dist/init.d.ts +8 -0
- package/dist/init.d.ts.map +1 -0
- package/dist/init.js +27 -0
- package/dist/init.js.map +1 -0
- package/dist/integrations/integrationConfig.d.ts +80 -0
- package/dist/integrations/integrationConfig.d.ts.map +1 -0
- package/dist/integrations/integrationConfig.js +146 -0
- package/dist/integrations/integrationConfig.js.map +1 -0
- package/dist/mcp/mcpBridge.d.ts +36 -0
- package/dist/mcp/mcpBridge.d.ts.map +1 -0
- package/dist/mcp/mcpBridge.js +157 -0
- package/dist/mcp/mcpBridge.js.map +1 -0
- package/dist/memory/agentMemory.d.ts +32 -0
- package/dist/memory/agentMemory.d.ts.map +1 -0
- package/dist/memory/agentMemory.js +116 -0
- package/dist/memory/agentMemory.js.map +1 -0
- package/dist/memory/autoCompaction.d.ts +46 -0
- package/dist/memory/autoCompaction.d.ts.map +1 -0
- package/dist/memory/autoCompaction.js +220 -0
- package/dist/memory/autoCompaction.js.map +1 -0
- package/dist/memory/compaction.d.ts +17 -0
- package/dist/memory/compaction.d.ts.map +1 -0
- package/dist/memory/compaction.js +27 -0
- package/dist/memory/compaction.js.map +1 -0
- package/dist/memory/messageHistory.d.ts +28 -0
- package/dist/memory/messageHistory.d.ts.map +1 -0
- package/dist/memory/messageHistory.js +60 -0
- package/dist/memory/messageHistory.js.map +1 -0
- package/dist/memory/sessionLifecycle.d.ts +30 -0
- package/dist/memory/sessionLifecycle.d.ts.map +1 -0
- package/dist/memory/sessionLifecycle.js +63 -0
- package/dist/memory/sessionLifecycle.js.map +1 -0
- package/dist/migrate.d.ts +8 -0
- package/dist/migrate.d.ts.map +1 -0
- package/dist/migrate.js +83 -0
- package/dist/migrate.js.map +1 -0
- package/dist/onboarding.d.ts +8 -0
- package/dist/onboarding.d.ts.map +1 -0
- package/dist/onboarding.js +188 -0
- package/dist/onboarding.js.map +1 -0
- package/dist/tools/domain/baFileTools.d.ts +7 -0
- package/dist/tools/domain/baFileTools.d.ts.map +1 -0
- package/dist/tools/domain/baFileTools.js +46 -0
- package/dist/tools/domain/baFileTools.js.map +1 -0
- package/dist/tools/domain/baTools.d.ts +6 -0
- package/dist/tools/domain/baTools.d.ts.map +1 -0
- package/dist/tools/domain/baTools.js +160 -0
- package/dist/tools/domain/baTools.js.map +1 -0
- package/dist/tools/domain/baseSpecialistTools.d.ts +22 -0
- package/dist/tools/domain/baseSpecialistTools.d.ts.map +1 -0
- package/dist/tools/domain/baseSpecialistTools.js +183 -0
- package/dist/tools/domain/baseSpecialistTools.js.map +1 -0
- package/dist/tools/domain/devTools.d.ts +6 -0
- package/dist/tools/domain/devTools.d.ts.map +1 -0
- package/dist/tools/domain/devTools.js +191 -0
- package/dist/tools/domain/devTools.js.map +1 -0
- package/dist/tools/domain/gitTools.d.ts +36 -0
- package/dist/tools/domain/gitTools.d.ts.map +1 -0
- package/dist/tools/domain/gitTools.js +279 -0
- package/dist/tools/domain/gitTools.js.map +1 -0
- package/dist/tools/domain/qaTools.d.ts +6 -0
- package/dist/tools/domain/qaTools.d.ts.map +1 -0
- package/dist/tools/domain/qaTools.js +275 -0
- package/dist/tools/domain/qaTools.js.map +1 -0
- package/dist/tools/domain/securityFlowTools.d.ts +6 -0
- package/dist/tools/domain/securityFlowTools.d.ts.map +1 -0
- package/dist/tools/domain/securityFlowTools.js +156 -0
- package/dist/tools/domain/securityFlowTools.js.map +1 -0
- package/dist/tools/pm/employeeTools.d.ts +15 -0
- package/dist/tools/pm/employeeTools.d.ts.map +1 -0
- package/dist/tools/pm/employeeTools.js +117 -0
- package/dist/tools/pm/employeeTools.js.map +1 -0
- package/dist/tools/pm/taskTools.d.ts +31 -0
- package/dist/tools/pm/taskTools.d.ts.map +1 -0
- package/dist/tools/pm/taskTools.js +534 -0
- package/dist/tools/pm/taskTools.js.map +1 -0
- package/dist/tools/shared/dateTools.d.ts +7 -0
- package/dist/tools/shared/dateTools.d.ts.map +1 -0
- package/dist/tools/shared/dateTools.js +35 -0
- package/dist/tools/shared/dateTools.js.map +1 -0
- package/dist/tools/shared/fileTools.d.ts +33 -0
- package/dist/tools/shared/fileTools.d.ts.map +1 -0
- package/dist/tools/shared/fileTools.js +312 -0
- package/dist/tools/shared/fileTools.js.map +1 -0
- package/dist/tools/shared/memoryTools.d.ts +18 -0
- package/dist/tools/shared/memoryTools.d.ts.map +1 -0
- package/dist/tools/shared/memoryTools.js +275 -0
- package/dist/tools/shared/memoryTools.js.map +1 -0
- package/dist/tools/shared/messagingTools.d.ts +14 -0
- package/dist/tools/shared/messagingTools.d.ts.map +1 -0
- package/dist/tools/shared/messagingTools.js +95 -0
- package/dist/tools/shared/messagingTools.js.map +1 -0
- package/dist/tools/shared/webTools.d.ts +12 -0
- package/dist/tools/shared/webTools.d.ts.map +1 -0
- package/dist/tools/shared/webTools.js +140 -0
- package/dist/tools/shared/webTools.js.map +1 -0
- package/dist/tower.d.ts +8 -0
- package/dist/tower.d.ts.map +1 -0
- package/dist/tower.js +774 -0
- package/dist/tower.js.map +1 -0
- package/package.json +71 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postTaskHooks.d.ts","sourceRoot":"","sources":["../../src/atp/postTaskHooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAkBH;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC,CAmDf"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Post-task hooks — automated security scans that run after coding tasks complete.
|
|
3
|
+
*
|
|
4
|
+
* When a coding agent finishes a task and auto-commits, these hooks fire:
|
|
5
|
+
* 1. secret-scan (Gitleaks) — detect leaked credentials
|
|
6
|
+
* 2. sast-scan (Semgrep) — static application security testing
|
|
7
|
+
* 3. sca-scan (Trivy) — dependency vulnerability scanning
|
|
8
|
+
* 4. code-scan (SonarQube) — only if SONAR_TOKEN is configured
|
|
9
|
+
*
|
|
10
|
+
* Results are sent to the QA agent's inbox as a structured report.
|
|
11
|
+
* Scans run sequentially to avoid Docker resource contention.
|
|
12
|
+
* Failures are logged but never crash the agent runtime.
|
|
13
|
+
*/
|
|
14
|
+
import { runFlow } from "../flows/index.js";
|
|
15
|
+
import { AgentMessageQueue, AGENT_DISPLAY_NAMES } from "./agentMessageQueue.js";
|
|
16
|
+
import { EventLog } from "./eventLog.js";
|
|
17
|
+
import { EventType } from "./models.js";
|
|
18
|
+
import { config } from "../config.js";
|
|
19
|
+
// ── Main entry point ─────────────────────────────────────────────────────────
|
|
20
|
+
/**
|
|
21
|
+
* Run all configured post-task security scans against a project directory.
|
|
22
|
+
* Sends a summary report to the QA agent's inbox.
|
|
23
|
+
*
|
|
24
|
+
* This function is fire-and-forget — callers should `.catch()` the promise.
|
|
25
|
+
*/
|
|
26
|
+
export async function runPostTaskScans(taskId, agentId, projectDir) {
|
|
27
|
+
if (!config.postTaskScansEnabled)
|
|
28
|
+
return;
|
|
29
|
+
EventLog.log(EventType.SCAN_COMPLETED, agentId, taskId, `Post-task scans starting for ${taskId}`);
|
|
30
|
+
// Determine which scans to run
|
|
31
|
+
const scansToRun = ["secret-scan", "sast-scan", "sca-scan"];
|
|
32
|
+
if (config.sonarToken)
|
|
33
|
+
scansToRun.push("code-scan");
|
|
34
|
+
const results = [];
|
|
35
|
+
// Run scans sequentially — they spawn Docker containers, parallel would overwhelm
|
|
36
|
+
for (const flowName of scansToRun) {
|
|
37
|
+
try {
|
|
38
|
+
const result = await runFlow(flowName, {
|
|
39
|
+
taskId,
|
|
40
|
+
agentId,
|
|
41
|
+
targetPath: projectDir,
|
|
42
|
+
});
|
|
43
|
+
results.push({ flowName, result });
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
results.push({
|
|
47
|
+
flowName,
|
|
48
|
+
result: { success: false, summary: `Hook error: ${err}` },
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// Build summary and send to QA agent
|
|
53
|
+
const summary = buildScanSummary(taskId, agentId, results);
|
|
54
|
+
AgentMessageQueue.push("system", "qa", taskId, summary, "normal");
|
|
55
|
+
// Log completion
|
|
56
|
+
const passed = results.every((r) => r.result.success);
|
|
57
|
+
const failCount = results.filter((r) => !r.result.success).length;
|
|
58
|
+
EventLog.log(EventType.SCAN_COMPLETED, agentId, taskId, passed
|
|
59
|
+
? `Post-task scans PASSED for ${taskId} (${results.length}/${results.length} clean)`
|
|
60
|
+
: `Post-task scans: ${failCount}/${results.length} FAILED for ${taskId}`);
|
|
61
|
+
}
|
|
62
|
+
// ── Report builder ───────────────────────────────────────────────────────────
|
|
63
|
+
function buildScanSummary(taskId, agentId, results) {
|
|
64
|
+
const agentName = AGENT_DISPLAY_NAMES[agentId] ?? agentId;
|
|
65
|
+
const passed = results.filter((r) => r.result.success).length;
|
|
66
|
+
const total = results.length;
|
|
67
|
+
const lines = [
|
|
68
|
+
`POST-TASK SCAN REPORT -- ${taskId}`,
|
|
69
|
+
`Agent: ${agentName}`,
|
|
70
|
+
`Scans completed: ${total}/${total}`,
|
|
71
|
+
``,
|
|
72
|
+
];
|
|
73
|
+
for (const { flowName, result } of results) {
|
|
74
|
+
const icon = result.success ? "[PASS]" : "[FAIL]";
|
|
75
|
+
lines.push(`${icon} ${flowName}: ${result.summary}`);
|
|
76
|
+
if (result.reportPath) {
|
|
77
|
+
lines.push(` Report: ${result.reportPath}`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
lines.push(``);
|
|
81
|
+
if (passed < total) {
|
|
82
|
+
lines.push(`Action required: Review the failed scan reports above and create follow-up bug tasks if needed.`);
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
lines.push(`All scans passed -- no action required.`);
|
|
86
|
+
}
|
|
87
|
+
return lines.join("\n");
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=postTaskHooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postTaskHooks.js","sourceRoot":"","sources":["../../src/atp/postTaskHooks.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TokenTracker — tracks per-agent token usage from stream events.
|
|
3
|
+
*
|
|
4
|
+
* Estimates token counts from streamed text (≈4 chars per token).
|
|
5
|
+
* Accumulates per-agent stats: turns, estimated input/output tokens,
|
|
6
|
+
* and estimated cost based on configurable pricing.
|
|
7
|
+
*
|
|
8
|
+
* Persists to data/token-usage.json so stats survive restarts.
|
|
9
|
+
*/
|
|
10
|
+
export interface AgentUsage {
|
|
11
|
+
agentId: string;
|
|
12
|
+
turns: number;
|
|
13
|
+
inputTokens: number;
|
|
14
|
+
outputTokens: number;
|
|
15
|
+
totalTokens: number;
|
|
16
|
+
costUsd: number;
|
|
17
|
+
lastActivity: string;
|
|
18
|
+
model?: string;
|
|
19
|
+
}
|
|
20
|
+
/** Call when an agent starts a turn. */
|
|
21
|
+
export declare function trackTurnStart(agentId: string): void;
|
|
22
|
+
/** Call with each text/thinking delta to accumulate output chars. */
|
|
23
|
+
export declare function trackOutputChars(agentId: string, chars: number): void;
|
|
24
|
+
/** Call when an agent finishes a turn. Uses real usage data if provided, else estimates. */
|
|
25
|
+
export declare function trackTurnEnd(agentId: string, opts?: {
|
|
26
|
+
model?: string;
|
|
27
|
+
inputTokens?: number;
|
|
28
|
+
outputTokens?: number;
|
|
29
|
+
costUsd?: number;
|
|
30
|
+
inputCostPerM?: number;
|
|
31
|
+
outputCostPerM?: number;
|
|
32
|
+
}): void;
|
|
33
|
+
/** Get usage for all agents. */
|
|
34
|
+
export declare function getAllUsage(): AgentUsage[];
|
|
35
|
+
/** Get aggregate totals. */
|
|
36
|
+
export declare function getTotals(): {
|
|
37
|
+
totalTurns: number;
|
|
38
|
+
totalInputTokens: number;
|
|
39
|
+
totalOutputTokens: number;
|
|
40
|
+
totalTokens: number;
|
|
41
|
+
totalCostUsd: number;
|
|
42
|
+
sessionStart: string;
|
|
43
|
+
};
|
|
44
|
+
/** Reset all usage data. */
|
|
45
|
+
export declare function resetUsage(): void;
|
|
46
|
+
//# sourceMappingURL=tokenTracker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokenTracker.d.ts","sourceRoot":"","sources":["../../src/atp/tokenTracker.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAeH,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AA4DD,wCAAwC;AACxC,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAEpD;AAED,qEAAqE;AACrE,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAErE;AAED,4FAA4F;AAC5F,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;IACnD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,GAAG,IAAI,CAgCP;AAED,gCAAgC;AAChC,wBAAgB,WAAW,IAAI,UAAU,EAAE,CAE1C;AAED,4BAA4B;AAC5B,wBAAgB,SAAS,IAAI;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;CACtB,CAUA;AAED,4BAA4B;AAC5B,wBAAgB,UAAU,IAAI,IAAI,CAGjC"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TokenTracker — tracks per-agent token usage from stream events.
|
|
3
|
+
*
|
|
4
|
+
* Estimates token counts from streamed text (≈4 chars per token).
|
|
5
|
+
* Accumulates per-agent stats: turns, estimated input/output tokens,
|
|
6
|
+
* and estimated cost based on configurable pricing.
|
|
7
|
+
*
|
|
8
|
+
* Persists to data/token-usage.json so stats survive restarts.
|
|
9
|
+
*/
|
|
10
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from "fs";
|
|
11
|
+
import { join } from "path";
|
|
12
|
+
import { config } from "../config.js";
|
|
13
|
+
const USAGE_PATH = join(config.dataDir, "token-usage.json");
|
|
14
|
+
// ── Fallback pricing (USD per 1M tokens) ─────────────────────────────────────
|
|
15
|
+
// Used only when real per-model cost data isn't available from the provider.
|
|
16
|
+
const FALLBACK_INPUT_PER_M = parseFloat(process.env.VEC_INPUT_COST_PER_M ?? "0.50");
|
|
17
|
+
const FALLBACK_OUTPUT_PER_M = parseFloat(process.env.VEC_OUTPUT_COST_PER_M ?? "1.50");
|
|
18
|
+
// ── In-memory state ──────────────────────────────────────────────────────────
|
|
19
|
+
let store = loadStore();
|
|
20
|
+
// Track chars accumulated during current turn (per agent)
|
|
21
|
+
const _turnChars = {};
|
|
22
|
+
function loadStore() {
|
|
23
|
+
try {
|
|
24
|
+
if (existsSync(USAGE_PATH)) {
|
|
25
|
+
return JSON.parse(readFileSync(USAGE_PATH, "utf-8"));
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
catch { /* ignore corrupt file */ }
|
|
29
|
+
return { agents: {}, sessionStart: new Date().toISOString() };
|
|
30
|
+
}
|
|
31
|
+
function saveStore() {
|
|
32
|
+
try {
|
|
33
|
+
mkdirSync(config.dataDir, { recursive: true });
|
|
34
|
+
writeFileSync(USAGE_PATH, JSON.stringify(store, null, 2));
|
|
35
|
+
}
|
|
36
|
+
catch { /* best-effort persist */ }
|
|
37
|
+
}
|
|
38
|
+
function ensureAgent(agentId) {
|
|
39
|
+
if (!store.agents[agentId]) {
|
|
40
|
+
store.agents[agentId] = {
|
|
41
|
+
agentId,
|
|
42
|
+
turns: 0,
|
|
43
|
+
inputTokens: 0,
|
|
44
|
+
outputTokens: 0,
|
|
45
|
+
totalTokens: 0,
|
|
46
|
+
costUsd: 0,
|
|
47
|
+
lastActivity: new Date().toISOString(),
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
return store.agents[agentId];
|
|
51
|
+
}
|
|
52
|
+
function charsToTokens(chars) {
|
|
53
|
+
return Math.ceil(chars / 4);
|
|
54
|
+
}
|
|
55
|
+
function computeCostUsd(inputTokens, outputTokens, inputPerM = FALLBACK_INPUT_PER_M, outputPerM = FALLBACK_OUTPUT_PER_M) {
|
|
56
|
+
return (inputTokens * inputPerM + outputTokens * outputPerM) / 1_000_000;
|
|
57
|
+
}
|
|
58
|
+
// ── Public API ───────────────────────────────────────────────────────────────
|
|
59
|
+
/** Call when an agent starts a turn. */
|
|
60
|
+
export function trackTurnStart(agentId) {
|
|
61
|
+
_turnChars[agentId] = 0;
|
|
62
|
+
}
|
|
63
|
+
/** Call with each text/thinking delta to accumulate output chars. */
|
|
64
|
+
export function trackOutputChars(agentId, chars) {
|
|
65
|
+
_turnChars[agentId] = (_turnChars[agentId] ?? 0) + chars;
|
|
66
|
+
}
|
|
67
|
+
/** Call when an agent finishes a turn. Uses real usage data if provided, else estimates. */
|
|
68
|
+
export function trackTurnEnd(agentId, opts) {
|
|
69
|
+
const agent = ensureAgent(agentId);
|
|
70
|
+
let inputTokens;
|
|
71
|
+
let outputTokens;
|
|
72
|
+
let cost;
|
|
73
|
+
if (opts?.inputTokens != null && opts?.outputTokens != null) {
|
|
74
|
+
// Real usage data from the provider
|
|
75
|
+
inputTokens = opts.inputTokens;
|
|
76
|
+
outputTokens = opts.outputTokens;
|
|
77
|
+
cost = opts.costUsd != null
|
|
78
|
+
? opts.costUsd
|
|
79
|
+
: computeCostUsd(inputTokens, outputTokens, opts.inputCostPerM, opts.outputCostPerM);
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
// Fallback: estimate from streamed chars
|
|
83
|
+
const outputChars = _turnChars[agentId] ?? 0;
|
|
84
|
+
outputTokens = charsToTokens(outputChars);
|
|
85
|
+
inputTokens = Math.ceil(outputTokens * 2.5);
|
|
86
|
+
cost = computeCostUsd(inputTokens, outputTokens);
|
|
87
|
+
}
|
|
88
|
+
agent.turns += 1;
|
|
89
|
+
agent.outputTokens += outputTokens;
|
|
90
|
+
agent.inputTokens += inputTokens;
|
|
91
|
+
agent.totalTokens += inputTokens + outputTokens;
|
|
92
|
+
agent.costUsd += cost;
|
|
93
|
+
agent.lastActivity = new Date().toISOString();
|
|
94
|
+
if (opts?.model)
|
|
95
|
+
agent.model = opts.model;
|
|
96
|
+
delete _turnChars[agentId];
|
|
97
|
+
saveStore();
|
|
98
|
+
}
|
|
99
|
+
/** Get usage for all agents. */
|
|
100
|
+
export function getAllUsage() {
|
|
101
|
+
return Object.values(store.agents);
|
|
102
|
+
}
|
|
103
|
+
/** Get aggregate totals. */
|
|
104
|
+
export function getTotals() {
|
|
105
|
+
const agents = Object.values(store.agents);
|
|
106
|
+
return {
|
|
107
|
+
totalTurns: agents.reduce((s, a) => s + a.turns, 0),
|
|
108
|
+
totalInputTokens: agents.reduce((s, a) => s + a.inputTokens, 0),
|
|
109
|
+
totalOutputTokens: agents.reduce((s, a) => s + a.outputTokens, 0),
|
|
110
|
+
totalTokens: agents.reduce((s, a) => s + a.totalTokens, 0),
|
|
111
|
+
totalCostUsd: agents.reduce((s, a) => s + a.costUsd, 0),
|
|
112
|
+
sessionStart: store.sessionStart,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
/** Reset all usage data. */
|
|
116
|
+
export function resetUsage() {
|
|
117
|
+
store = { agents: {}, sessionStart: new Date().toISOString() };
|
|
118
|
+
saveStore();
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=tokenTracker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokenTracker.js","sourceRoot":"","sources":["../../src/atp/tokenTracker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Active channel tracker — which channel sent the most recent message to PM.
|
|
3
|
+
*
|
|
4
|
+
* Used to route PM replies back to the originating channel only:
|
|
5
|
+
* - telegram → reply goes to Telegram only (not Dashboard Teams)
|
|
6
|
+
* - dashboard → reply goes to Dashboard Teams only (not Telegram)
|
|
7
|
+
* - cli → reply goes to CLI + Dashboard Teams (default)
|
|
8
|
+
*/
|
|
9
|
+
export type ActiveChannel = "cli" | "telegram" | "dashboard" | "slack" | "discord";
|
|
10
|
+
export declare const ActiveChannelState: {
|
|
11
|
+
set(ch: ActiveChannel): void;
|
|
12
|
+
get(): ActiveChannel;
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=activeChannel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"activeChannel.d.ts","sourceRoot":"","sources":["../../src/channels/activeChannel.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,UAAU,GAAG,WAAW,GAAG,OAAO,GAAG,SAAS,CAAC;AAInF,eAAO,MAAM,kBAAkB;YACrB,aAAa,GAAG,IAAI;WAGrB,aAAa;CAGrB,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Active channel tracker — which channel sent the most recent message to PM.
|
|
3
|
+
*
|
|
4
|
+
* Used to route PM replies back to the originating channel only:
|
|
5
|
+
* - telegram → reply goes to Telegram only (not Dashboard Teams)
|
|
6
|
+
* - dashboard → reply goes to Dashboard Teams only (not Telegram)
|
|
7
|
+
* - cli → reply goes to CLI + Dashboard Teams (default)
|
|
8
|
+
*/
|
|
9
|
+
let _current = "cli";
|
|
10
|
+
export const ActiveChannelState = {
|
|
11
|
+
set(ch) {
|
|
12
|
+
_current = ch;
|
|
13
|
+
},
|
|
14
|
+
get() {
|
|
15
|
+
return _current;
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=activeChannel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"activeChannel.js","sourceRoot":"","sources":["../../src/channels/activeChannel.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,IAAI,QAAQ,GAAkB,KAAK,CAAC;AAEpC,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,GAAG,CAAC,EAAiB;QACnB,QAAQ,GAAG,EAAE,CAAC;IAChB,CAAC;IACD,GAAG;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON-backed storage for channel credentials (Telegram, Slack).
|
|
3
|
+
* Follows the same pattern as modelConfig.ts setProviderApiKey.
|
|
4
|
+
*
|
|
5
|
+
* Security:
|
|
6
|
+
* - Raw credentials are stored in data/channel-config.json (gitignored)
|
|
7
|
+
* - getChannelConfigMasked() returns masked tokens for UI display
|
|
8
|
+
* - No endpoint should ever return raw credentials to the browser
|
|
9
|
+
*/
|
|
10
|
+
export interface TelegramCredentials {
|
|
11
|
+
botToken: string;
|
|
12
|
+
chatId: string;
|
|
13
|
+
}
|
|
14
|
+
export interface SlackCredentials {
|
|
15
|
+
botToken: string;
|
|
16
|
+
appToken: string;
|
|
17
|
+
channelId: string;
|
|
18
|
+
}
|
|
19
|
+
export interface DiscordCredentials {
|
|
20
|
+
botToken: string;
|
|
21
|
+
channelId: string;
|
|
22
|
+
}
|
|
23
|
+
export interface ChannelConfig {
|
|
24
|
+
telegram?: TelegramCredentials;
|
|
25
|
+
slack?: SlackCredentials;
|
|
26
|
+
discord?: DiscordCredentials;
|
|
27
|
+
}
|
|
28
|
+
export interface MaskedChannelInfo {
|
|
29
|
+
configured: boolean;
|
|
30
|
+
connected: boolean;
|
|
31
|
+
botToken: string | null;
|
|
32
|
+
chatId?: string | null;
|
|
33
|
+
appToken?: string | null;
|
|
34
|
+
channelId?: string | null;
|
|
35
|
+
}
|
|
36
|
+
export declare function loadChannelConfig(): ChannelConfig;
|
|
37
|
+
/**
|
|
38
|
+
* Save credentials for a channel. Pass null to clear.
|
|
39
|
+
* Also injects into process.env so channels can be (re)started immediately.
|
|
40
|
+
*/
|
|
41
|
+
export declare function saveChannelCredentials(channel: "telegram", creds: TelegramCredentials | null): void;
|
|
42
|
+
export declare function saveChannelCredentials(channel: "slack", creds: SlackCredentials | null): void;
|
|
43
|
+
export declare function saveChannelCredentials(channel: "discord", creds: DiscordCredentials | null): void;
|
|
44
|
+
/**
|
|
45
|
+
* Load saved channel config into process.env on startup.
|
|
46
|
+
* JSON file takes precedence over .env if both are set.
|
|
47
|
+
*/
|
|
48
|
+
export declare function injectChannelEnv(): void;
|
|
49
|
+
/**
|
|
50
|
+
* Return channel config with all tokens masked. Safe to send to the browser.
|
|
51
|
+
*/
|
|
52
|
+
export declare function getChannelConfigMasked(connected: {
|
|
53
|
+
telegram: boolean;
|
|
54
|
+
slack: boolean;
|
|
55
|
+
discord: boolean;
|
|
56
|
+
}): {
|
|
57
|
+
telegram: MaskedChannelInfo;
|
|
58
|
+
slack: MaskedChannelInfo;
|
|
59
|
+
discord: MaskedChannelInfo;
|
|
60
|
+
};
|
|
61
|
+
//# sourceMappingURL=channelConfig.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"channelConfig.d.ts","sourceRoot":"","sources":["../../src/channels/channelConfig.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAUH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,mBAAmB,CAAC;IAC/B,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB,OAAO,CAAC,EAAE,kBAAkB,CAAC;CAC9B;AAED,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAYD,wBAAgB,iBAAiB,IAAI,aAAa,CAQjD;AAOD;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,UAAU,EACnB,KAAK,EAAE,mBAAmB,GAAG,IAAI,GAChC,IAAI,CAAC;AACR,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,gBAAgB,GAAG,IAAI,GAC7B,IAAI,CAAC;AACR,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,SAAS,EAClB,KAAK,EAAE,kBAAkB,GAAG,IAAI,GAC/B,IAAI,CAAC;AA+CR;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAevC;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE;IAAE,QAAQ,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GAAG;IAC1G,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,KAAK,EAAE,iBAAiB,CAAC;IACzB,OAAO,EAAE,iBAAiB,CAAC;CAC5B,CAuBA"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON-backed storage for channel credentials (Telegram, Slack).
|
|
3
|
+
* Follows the same pattern as modelConfig.ts setProviderApiKey.
|
|
4
|
+
*
|
|
5
|
+
* Security:
|
|
6
|
+
* - Raw credentials are stored in data/channel-config.json (gitignored)
|
|
7
|
+
* - getChannelConfigMasked() returns masked tokens for UI display
|
|
8
|
+
* - No endpoint should ever return raw credentials to the browser
|
|
9
|
+
*/
|
|
10
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
|
|
11
|
+
import { join } from "path";
|
|
12
|
+
import { config } from "../config.js";
|
|
13
|
+
const CONFIG_PATH = join(config.dataDir, "channel-config.json");
|
|
14
|
+
// ── Masking ──────────────────────────────────────────────────────────────────
|
|
15
|
+
function maskToken(token) {
|
|
16
|
+
if (!token)
|
|
17
|
+
return null;
|
|
18
|
+
if (token.length <= 8)
|
|
19
|
+
return "****";
|
|
20
|
+
return token.slice(0, 4) + "****" + token.slice(-4);
|
|
21
|
+
}
|
|
22
|
+
// ── Storage ──────────────────────────────────────────────────────────────────
|
|
23
|
+
export function loadChannelConfig() {
|
|
24
|
+
try {
|
|
25
|
+
if (!existsSync(CONFIG_PATH))
|
|
26
|
+
return {};
|
|
27
|
+
const raw = readFileSync(CONFIG_PATH, "utf-8").trim();
|
|
28
|
+
return raw ? JSON.parse(raw) : {};
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return {};
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function saveRaw(cfg) {
|
|
35
|
+
mkdirSync(config.dataDir, { recursive: true });
|
|
36
|
+
writeFileSync(CONFIG_PATH, JSON.stringify(cfg, null, 2), "utf-8");
|
|
37
|
+
}
|
|
38
|
+
export function saveChannelCredentials(channel, creds) {
|
|
39
|
+
const cfg = loadChannelConfig();
|
|
40
|
+
if (channel === "telegram") {
|
|
41
|
+
if (creds) {
|
|
42
|
+
const tc = creds;
|
|
43
|
+
cfg.telegram = tc;
|
|
44
|
+
process.env.TELEGRAM_BOT_TOKEN = tc.botToken;
|
|
45
|
+
process.env.TELEGRAM_CHAT_ID = tc.chatId;
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
delete cfg.telegram;
|
|
49
|
+
delete process.env.TELEGRAM_BOT_TOKEN;
|
|
50
|
+
delete process.env.TELEGRAM_CHAT_ID;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
else if (channel === "slack") {
|
|
54
|
+
if (creds) {
|
|
55
|
+
const sc = creds;
|
|
56
|
+
cfg.slack = sc;
|
|
57
|
+
process.env.SLACK_BOT_TOKEN = sc.botToken;
|
|
58
|
+
process.env.SLACK_APP_TOKEN = sc.appToken;
|
|
59
|
+
process.env.SLACK_CHANNEL_ID = sc.channelId;
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
delete cfg.slack;
|
|
63
|
+
delete process.env.SLACK_BOT_TOKEN;
|
|
64
|
+
delete process.env.SLACK_APP_TOKEN;
|
|
65
|
+
delete process.env.SLACK_CHANNEL_ID;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
if (creds) {
|
|
70
|
+
const dc = creds;
|
|
71
|
+
cfg.discord = dc;
|
|
72
|
+
process.env.DISCORD_BOT_TOKEN = dc.botToken;
|
|
73
|
+
process.env.DISCORD_CHANNEL_ID = dc.channelId;
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
delete cfg.discord;
|
|
77
|
+
delete process.env.DISCORD_BOT_TOKEN;
|
|
78
|
+
delete process.env.DISCORD_CHANNEL_ID;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
saveRaw(cfg);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Load saved channel config into process.env on startup.
|
|
85
|
+
* JSON file takes precedence over .env if both are set.
|
|
86
|
+
*/
|
|
87
|
+
export function injectChannelEnv() {
|
|
88
|
+
const cfg = loadChannelConfig();
|
|
89
|
+
if (cfg.telegram) {
|
|
90
|
+
process.env.TELEGRAM_BOT_TOKEN = cfg.telegram.botToken;
|
|
91
|
+
process.env.TELEGRAM_CHAT_ID = cfg.telegram.chatId;
|
|
92
|
+
}
|
|
93
|
+
if (cfg.slack) {
|
|
94
|
+
process.env.SLACK_BOT_TOKEN = cfg.slack.botToken;
|
|
95
|
+
process.env.SLACK_APP_TOKEN = cfg.slack.appToken;
|
|
96
|
+
process.env.SLACK_CHANNEL_ID = cfg.slack.channelId;
|
|
97
|
+
}
|
|
98
|
+
if (cfg.discord) {
|
|
99
|
+
process.env.DISCORD_BOT_TOKEN = cfg.discord.botToken;
|
|
100
|
+
process.env.DISCORD_CHANNEL_ID = cfg.discord.channelId;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Return channel config with all tokens masked. Safe to send to the browser.
|
|
105
|
+
*/
|
|
106
|
+
export function getChannelConfigMasked(connected) {
|
|
107
|
+
const cfg = loadChannelConfig();
|
|
108
|
+
return {
|
|
109
|
+
telegram: {
|
|
110
|
+
configured: !!(cfg.telegram?.botToken && cfg.telegram?.chatId),
|
|
111
|
+
connected: connected.telegram,
|
|
112
|
+
botToken: maskToken(cfg.telegram?.botToken),
|
|
113
|
+
chatId: cfg.telegram?.chatId ?? null,
|
|
114
|
+
},
|
|
115
|
+
slack: {
|
|
116
|
+
configured: !!(cfg.slack?.botToken && cfg.slack?.appToken && cfg.slack?.channelId),
|
|
117
|
+
connected: connected.slack,
|
|
118
|
+
botToken: maskToken(cfg.slack?.botToken),
|
|
119
|
+
appToken: maskToken(cfg.slack?.appToken),
|
|
120
|
+
channelId: cfg.slack?.channelId ?? null,
|
|
121
|
+
},
|
|
122
|
+
discord: {
|
|
123
|
+
configured: !!(cfg.discord?.botToken && cfg.discord?.channelId),
|
|
124
|
+
connected: connected.discord,
|
|
125
|
+
botToken: maskToken(cfg.discord?.botToken),
|
|
126
|
+
channelId: cfg.discord?.channelId ?? null,
|
|
127
|
+
},
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=channelConfig.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"channelConfig.js","sourceRoot":"","sources":["../../src/channels/channelConfig.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ChannelManager — singleton that holds active Telegram/Slack/Discord channel instances
|
|
3
|
+
* and exposes stop/restart capability for hot-reload from the dashboard.
|
|
4
|
+
*/
|
|
5
|
+
import type { VECChannel } from "./types.js";
|
|
6
|
+
import type { PMAgent } from "../agents/pmAgent.js";
|
|
7
|
+
type ChannelId = "telegram" | "slack" | "discord";
|
|
8
|
+
export declare const channelManager: {
|
|
9
|
+
/** Called once from tower.ts during startup. */
|
|
10
|
+
initChannels(pmAgent: PMAgent): Promise<void>;
|
|
11
|
+
getChannel(id: ChannelId): VECChannel | null;
|
|
12
|
+
isConnected(id: ChannelId): boolean;
|
|
13
|
+
/** Stop a channel gracefully. */
|
|
14
|
+
stopChannel(id: ChannelId): Promise<void>;
|
|
15
|
+
/** Stop the old instance, create a new one from current process.env, and start it. */
|
|
16
|
+
restartChannel(id: ChannelId): Promise<{
|
|
17
|
+
ok: boolean;
|
|
18
|
+
error?: string;
|
|
19
|
+
}>;
|
|
20
|
+
};
|
|
21
|
+
export {};
|
|
22
|
+
//# sourceMappingURL=channelManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"channelManager.d.ts","sourceRoot":"","sources":["../../src/channels/channelManager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAKpD,KAAK,SAAS,GAAG,UAAU,GAAG,OAAO,GAAG,SAAS,CAAC;AASlD,eAAO,MAAM,cAAc;IACzB,gDAAgD;0BACpB,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;mBAUpC,SAAS,GAAG,UAAU,GAAG,IAAI;oBAI5B,SAAS,GAAG,OAAO;IAInC,iCAAiC;oBACX,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ/C,sFAAsF;uBAC7D,SAAS,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CA+B9E,CAAC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ChannelManager — singleton that holds active Telegram/Slack/Discord channel instances
|
|
3
|
+
* and exposes stop/restart capability for hot-reload from the dashboard.
|
|
4
|
+
*/
|
|
5
|
+
import { createTelegramChannel } from "./telegram.js";
|
|
6
|
+
import { createSlackChannel } from "./slack.js";
|
|
7
|
+
import { createDiscordChannel } from "./discord.js";
|
|
8
|
+
let _pmAgent = null;
|
|
9
|
+
const _channels = {
|
|
10
|
+
telegram: null,
|
|
11
|
+
slack: null,
|
|
12
|
+
discord: null,
|
|
13
|
+
};
|
|
14
|
+
export const channelManager = {
|
|
15
|
+
/** Called once from tower.ts during startup. */
|
|
16
|
+
async initChannels(pmAgent) {
|
|
17
|
+
_pmAgent = pmAgent;
|
|
18
|
+
_channels.telegram = createTelegramChannel(pmAgent);
|
|
19
|
+
if (_channels.telegram)
|
|
20
|
+
await _channels.telegram.start();
|
|
21
|
+
_channels.slack = createSlackChannel(pmAgent);
|
|
22
|
+
if (_channels.slack)
|
|
23
|
+
await _channels.slack.start();
|
|
24
|
+
_channels.discord = createDiscordChannel(pmAgent);
|
|
25
|
+
if (_channels.discord)
|
|
26
|
+
await _channels.discord.start();
|
|
27
|
+
},
|
|
28
|
+
getChannel(id) {
|
|
29
|
+
return _channels[id];
|
|
30
|
+
},
|
|
31
|
+
isConnected(id) {
|
|
32
|
+
return _channels[id] !== null;
|
|
33
|
+
},
|
|
34
|
+
/** Stop a channel gracefully. */
|
|
35
|
+
async stopChannel(id) {
|
|
36
|
+
const ch = _channels[id];
|
|
37
|
+
if (ch) {
|
|
38
|
+
try {
|
|
39
|
+
await ch.stop();
|
|
40
|
+
}
|
|
41
|
+
catch { /* best-effort */ }
|
|
42
|
+
_channels[id] = null;
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
/** Stop the old instance, create a new one from current process.env, and start it. */
|
|
46
|
+
async restartChannel(id) {
|
|
47
|
+
if (!_pmAgent)
|
|
48
|
+
return { ok: false, error: "PM agent not initialized" };
|
|
49
|
+
// Stop existing
|
|
50
|
+
await this.stopChannel(id);
|
|
51
|
+
// Create new from current env
|
|
52
|
+
try {
|
|
53
|
+
const creators = {
|
|
54
|
+
telegram: () => createTelegramChannel(_pmAgent),
|
|
55
|
+
slack: () => createSlackChannel(_pmAgent),
|
|
56
|
+
discord: () => createDiscordChannel(_pmAgent),
|
|
57
|
+
};
|
|
58
|
+
const labels = {
|
|
59
|
+
telegram: "Telegram",
|
|
60
|
+
slack: "Slack",
|
|
61
|
+
discord: "Discord",
|
|
62
|
+
};
|
|
63
|
+
const ch = creators[id]();
|
|
64
|
+
if (ch) {
|
|
65
|
+
await ch.start();
|
|
66
|
+
_channels[id] = ch;
|
|
67
|
+
return { ok: true };
|
|
68
|
+
}
|
|
69
|
+
return { ok: false, error: `Missing or invalid ${labels[id]} credentials` };
|
|
70
|
+
}
|
|
71
|
+
catch (err) {
|
|
72
|
+
_channels[id] = null;
|
|
73
|
+
return { ok: false, error: err?.message ?? "Failed to start channel" };
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
//# sourceMappingURL=channelManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"channelManager.js","sourceRoot":"","sources":["../../src/channels/channelManager.ts"],"names":[],"mappings":"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"}
|