@johpaz/hive-sdk 0.0.12 → 0.0.15

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.
Files changed (199) hide show
  1. package/.github/CODEOWNERS +9 -0
  2. package/.github/workflows/publish.yml +89 -0
  3. package/.github/workflows/version-bump.yml +102 -0
  4. package/CHANGELOG.md +38 -0
  5. package/README.md +158 -0
  6. package/bun.lock +543 -0
  7. package/bunfig.toml +7 -0
  8. package/docs/API-AGENTS.md +316 -0
  9. package/docs/API-CONTEXT-COMPILER.md +252 -0
  10. package/docs/API-DAG-SCHEDULER.md +273 -0
  11. package/docs/API-TOOLS-SKILLS-CHANNELS.md +293 -0
  12. package/docs/API-WORKERS-EVENTS.md +152 -0
  13. package/docs/INDEX.md +141 -0
  14. package/docs/README.md +68 -0
  15. package/package.json +54 -105
  16. package/packages/cli/package.json +17 -0
  17. package/packages/cli/src/commands/init.ts +56 -0
  18. package/packages/cli/src/commands/run.ts +45 -0
  19. package/packages/cli/src/commands/test.ts +42 -0
  20. package/packages/cli/src/commands/trace.ts +55 -0
  21. package/packages/cli/src/index.ts +43 -0
  22. package/packages/core/package.json +58 -0
  23. package/packages/core/src/ace/Curator.ts +158 -0
  24. package/packages/core/src/ace/Reflector.ts +200 -0
  25. package/packages/core/src/ace/Tracer.ts +100 -0
  26. package/packages/core/src/ace/index.ts +4 -0
  27. package/packages/core/src/agent/AgentRunner.ts +699 -0
  28. package/packages/core/src/agent/Compaction.ts +221 -0
  29. package/packages/core/src/agent/ContextCompiler.ts +567 -0
  30. package/packages/core/src/agent/ContextGuard.ts +91 -0
  31. package/packages/core/src/agent/ConversationStore.ts +244 -0
  32. package/packages/core/src/agent/Hooks.ts +166 -0
  33. package/packages/core/src/agent/NativeTools.ts +31 -0
  34. package/packages/core/src/agent/PromptBuilder.ts +169 -0
  35. package/packages/core/src/agent/Service.ts +267 -0
  36. package/packages/core/src/agent/StuckLoop.ts +133 -0
  37. package/packages/core/src/agent/index.ts +12 -0
  38. package/packages/core/src/agent/providers/LLMClient.ts +149 -0
  39. package/packages/core/src/agent/providers/anthropic.ts +212 -0
  40. package/packages/core/src/agent/providers/gemini.ts +215 -0
  41. package/packages/core/src/agent/providers/index.ts +199 -0
  42. package/packages/core/src/agent/providers/interface.ts +195 -0
  43. package/packages/core/src/agent/providers/ollama.ts +175 -0
  44. package/packages/core/src/agent/providers/openai-compat.ts +231 -0
  45. package/packages/core/src/agent/providers.ts +1 -0
  46. package/packages/core/src/agent/selectors/PlaybookSelector.ts +147 -0
  47. package/packages/core/src/agent/selectors/SkillSelector.ts +478 -0
  48. package/packages/core/src/agent/selectors/ToolSelector.ts +577 -0
  49. package/packages/core/src/agent/selectors/index.ts +6 -0
  50. package/packages/core/src/api/createAgent.test.ts +48 -0
  51. package/packages/core/src/api/createAgent.ts +122 -0
  52. package/packages/core/src/api/index.ts +2 -0
  53. package/packages/core/src/canvas/CanvasManager.ts +390 -0
  54. package/packages/core/src/canvas/a2ui-tools.ts +255 -0
  55. package/packages/core/src/canvas/canvas-tools.ts +448 -0
  56. package/packages/core/src/canvas/emitter.ts +149 -0
  57. package/packages/core/src/canvas/index.ts +6 -0
  58. package/packages/core/src/config/index.ts +2 -0
  59. package/packages/core/src/config/loader.ts +554 -0
  60. package/packages/core/src/ethics/EthicsGuard.test.ts +54 -0
  61. package/packages/core/src/ethics/EthicsGuard.ts +66 -0
  62. package/packages/core/src/ethics/index.ts +2 -0
  63. package/packages/core/src/gateway/channel-notify.test.ts +14 -0
  64. package/packages/core/src/gateway/channel-notify.ts +12 -0
  65. package/packages/core/src/gateway/index.ts +1 -0
  66. package/packages/core/src/index.ts +37 -0
  67. package/packages/core/src/mcp/MCPClient.ts +439 -0
  68. package/packages/core/src/mcp/MCPToolAdapter.ts +176 -0
  69. package/packages/core/src/mcp/config.ts +13 -0
  70. package/packages/core/src/mcp/hot-reload.ts +147 -0
  71. package/packages/core/src/mcp/index.ts +11 -0
  72. package/packages/core/src/mcp/logger.ts +42 -0
  73. package/packages/core/src/mcp/singleton.ts +21 -0
  74. package/packages/core/src/mcp/transports/index.ts +67 -0
  75. package/packages/core/src/mcp/transports/sse.ts +241 -0
  76. package/packages/core/src/mcp/transports/websocket.ts +159 -0
  77. package/packages/core/src/memory/Scratchpad.test.ts +47 -0
  78. package/packages/core/src/memory/Scratchpad.ts +37 -0
  79. package/packages/core/src/memory/Storage.ts +6 -0
  80. package/packages/core/src/memory/index.ts +2 -0
  81. package/packages/core/src/multimodal/VisionService.ts +293 -0
  82. package/packages/core/src/multimodal/index.ts +2 -0
  83. package/packages/core/src/multimodal/types.ts +28 -0
  84. package/packages/core/src/security/Pairing.ts +250 -0
  85. package/packages/core/src/security/RateLimit.ts +270 -0
  86. package/packages/core/src/security/index.ts +4 -0
  87. package/packages/core/src/skills/SkillLoader.ts +388 -0
  88. package/packages/core/src/skills/bundled-data.generated.ts +3332 -0
  89. package/packages/core/src/skills/defineSkill.ts +18 -0
  90. package/packages/core/src/skills/index.ts +4 -0
  91. package/packages/core/src/state/index.ts +2 -0
  92. package/packages/core/src/state/store.ts +312 -0
  93. package/packages/core/src/storage/SQLiteStorage.ts +407 -0
  94. package/packages/core/src/storage/crypto.ts +101 -0
  95. package/packages/core/src/storage/index.ts +10 -0
  96. package/packages/core/src/storage/onboarding.ts +1603 -0
  97. package/packages/core/src/storage/schema.ts +689 -0
  98. package/packages/core/src/storage/seed.ts +740 -0
  99. package/packages/core/src/storage/usage.ts +374 -0
  100. package/packages/core/src/swarm/AgentBus.ts +460 -0
  101. package/packages/core/src/swarm/AgentExecutor.ts +53 -0
  102. package/packages/core/src/swarm/Coordinator.ts +251 -0
  103. package/packages/core/src/swarm/EventBridge.ts +122 -0
  104. package/packages/core/src/swarm/EventBus.ts +169 -0
  105. package/packages/core/src/swarm/TaskGraph.ts +192 -0
  106. package/packages/core/src/swarm/TaskNode.ts +97 -0
  107. package/packages/core/src/swarm/TaskResult.ts +22 -0
  108. package/packages/core/src/swarm/WorkerPool.ts +236 -0
  109. package/packages/core/src/swarm/errors.ts +37 -0
  110. package/packages/core/src/swarm/index.ts +30 -0
  111. package/packages/core/src/swarm/presets/HiveLearnPreset.ts +99 -0
  112. package/packages/core/src/swarm/presets/ResearchPreset.ts +97 -0
  113. package/packages/core/src/swarm/presets/index.ts +4 -0
  114. package/packages/core/src/swarm/strategies/ParallelStrategy.ts +21 -0
  115. package/packages/core/src/swarm/strategies/PriorityStrategy.ts +46 -0
  116. package/packages/core/src/swarm/strategies/index.ts +3 -0
  117. package/packages/core/src/swarm/types.ts +164 -0
  118. package/packages/core/src/tools/ToolExecutor.ts +58 -0
  119. package/packages/core/src/tools/ToolRegistry.test.ts +98 -0
  120. package/packages/core/src/tools/ToolRegistry.ts +61 -0
  121. package/packages/core/src/tools/agents/get-available-models.ts +118 -0
  122. package/packages/core/src/tools/agents/index.ts +715 -0
  123. package/packages/core/src/tools/bridge-events.ts +26 -0
  124. package/packages/core/src/tools/canvas/index.ts +375 -0
  125. package/packages/core/src/tools/cli/index.ts +142 -0
  126. package/packages/core/src/tools/codebridge/index.ts +342 -0
  127. package/packages/core/src/tools/core/index.ts +476 -0
  128. package/packages/core/src/tools/cron/index.ts +626 -0
  129. package/packages/core/src/tools/filesystem/fs-delete.ts +78 -0
  130. package/packages/core/src/tools/filesystem/fs-edit.ts +106 -0
  131. package/packages/core/src/tools/filesystem/fs-exists.ts +63 -0
  132. package/packages/core/src/tools/filesystem/fs-glob.ts +108 -0
  133. package/packages/core/src/tools/filesystem/fs-list.ts +129 -0
  134. package/packages/core/src/tools/filesystem/fs-read.ts +72 -0
  135. package/packages/core/src/tools/filesystem/fs-write.ts +67 -0
  136. package/packages/core/src/tools/filesystem/index.ts +34 -0
  137. package/packages/core/src/tools/filesystem/workspace-guard.ts +62 -0
  138. package/packages/core/src/tools/index.ts +231 -0
  139. package/packages/core/src/tools/meeting/index.ts +363 -0
  140. package/packages/core/src/tools/office/index.ts +47 -0
  141. package/packages/core/src/tools/office/office-escribir-docx.ts +192 -0
  142. package/packages/core/src/tools/office/office-escribir-pdf.ts +172 -0
  143. package/packages/core/src/tools/office/office-escribir-pptx.ts +174 -0
  144. package/packages/core/src/tools/office/office-escribir-xlsx.ts +116 -0
  145. package/packages/core/src/tools/office/office-leer-docx.ts +93 -0
  146. package/packages/core/src/tools/office/office-leer-pdf.ts +114 -0
  147. package/packages/core/src/tools/office/office-leer-pptx.ts +136 -0
  148. package/packages/core/src/tools/office/office-leer-xlsx.ts +124 -0
  149. package/packages/core/src/tools/projects/index.ts +37 -0
  150. package/packages/core/src/tools/projects/project-create.ts +94 -0
  151. package/packages/core/src/tools/projects/project-done.ts +66 -0
  152. package/packages/core/src/tools/projects/project-fail.ts +66 -0
  153. package/packages/core/src/tools/projects/project-list.ts +96 -0
  154. package/packages/core/src/tools/projects/project-update.ts +72 -0
  155. package/packages/core/src/tools/projects/task-create.ts +68 -0
  156. package/packages/core/src/tools/projects/task-evaluate.ts +93 -0
  157. package/packages/core/src/tools/projects/task-update.ts +93 -0
  158. package/packages/core/src/tools/types.ts +39 -0
  159. package/packages/core/src/tools/voice/index.ts +104 -0
  160. package/packages/core/src/tools/web/browser-click.ts +78 -0
  161. package/packages/core/src/tools/web/browser-extract.ts +139 -0
  162. package/packages/core/src/tools/web/browser-navigate.ts +106 -0
  163. package/packages/core/src/tools/web/browser-screenshot.ts +87 -0
  164. package/packages/core/src/tools/web/browser-script.ts +88 -0
  165. package/packages/core/src/tools/web/browser-service.ts +554 -0
  166. package/packages/core/src/tools/web/browser-type.ts +101 -0
  167. package/packages/core/src/tools/web/browser-wait.ts +136 -0
  168. package/packages/core/src/tools/web/index.ts +41 -0
  169. package/packages/core/src/tools/web/web-fetch.ts +78 -0
  170. package/packages/core/src/tools/web/web-search.ts +123 -0
  171. package/packages/core/src/utils/benchmark.ts +80 -0
  172. package/packages/core/src/utils/crypto.ts +73 -0
  173. package/packages/core/src/utils/date.ts +42 -0
  174. package/packages/core/src/utils/index.ts +10 -0
  175. package/packages/core/src/utils/logger.ts +389 -0
  176. package/packages/core/src/utils/retry.ts +70 -0
  177. package/packages/core/src/utils/toon.ts +253 -0
  178. package/packages/core/src/voice/index.ts +656 -0
  179. package/test/setup-db.ts +216 -0
  180. package/tsconfig.json +39 -0
  181. package/src/agents.ts +0 -1
  182. package/src/canvas.ts +0 -1
  183. package/src/channels.ts +0 -1
  184. package/src/config.ts +0 -1
  185. package/src/events.ts +0 -1
  186. package/src/gateway.ts +0 -1
  187. package/src/index.ts +0 -304
  188. package/src/mcp.ts +0 -1
  189. package/src/multimodal.ts +0 -1
  190. package/src/scheduler.ts +0 -1
  191. package/src/security.ts +0 -1
  192. package/src/skills.ts +0 -1
  193. package/src/state.ts +0 -1
  194. package/src/storage.ts +0 -1
  195. package/src/tools.ts +0 -1
  196. package/src/tts.ts +0 -1
  197. package/src/types.ts +0 -82
  198. package/src/utils.ts +0 -1
  199. package/src/voice.ts +0 -1
@@ -0,0 +1,342 @@
1
+ /**
2
+ * CodeBridge Tools - 3 tools
3
+ *
4
+ * @category codebridge
5
+ */
6
+
7
+ import type { Tool } from "../types.ts";
8
+ import { logger } from "../../utils/logger.ts";
9
+ import { emitBridgeEvent } from "../bridge-events.ts";
10
+
11
+ const log = logger.child("codebridge");
12
+ const CODE_BRIDGE_PORT = parseInt(process.env.CODE_BRIDGE_PORT ?? "18791", 10);
13
+ const CODE_BRIDGE_URL = `ws://localhost:${CODE_BRIDGE_PORT}/ws`;
14
+ const CODE_BRIDGE_BASE = `http://localhost:${CODE_BRIDGE_PORT}`;
15
+
16
+ // ─── codebridge_launch ───────────────────────────────────────────────────────
17
+
18
+ export const codebridgeLaunchTool: Tool = {
19
+ name: "codebridge_launch",
20
+ description: "Launch an external coding CLI subagent (Claude Code, Qwen CLI, Gemini CLI, OpenCode CLI) to execute a coding task locally. Spanish: lanzar agente de código, iniciar Claude Code, Qwen CLI, Gemini CLI, OpenCode, subagente externo de programación",
21
+ parameters: {
22
+ type: "object",
23
+ properties: {
24
+ cli: {
25
+ type: "string",
26
+ enum: ["qwen", "claude", "opencode", "gemini"],
27
+ description: "CLI command to run (alias: agent)",
28
+ },
29
+ agent: {
30
+ type: "string",
31
+ enum: ["qwen", "claude", "opencode", "gemini"],
32
+ description: "Alias for cli (deprecated, use cli instead)",
33
+ },
34
+ prompt: {
35
+ type: "string",
36
+ description: "The prompt/task for the subagent",
37
+ },
38
+ role: {
39
+ type: "string",
40
+ enum: ["architecture", "development", "testing", "documentation"],
41
+ description: "Role of the subagent",
42
+ },
43
+ timeoutSeconds: {
44
+ type: "number",
45
+ description: "Timeout in seconds (default: 600)",
46
+ },
47
+ },
48
+ required: ["prompt"],
49
+ },
50
+ execute: async (params: Record<string, unknown>) => {
51
+ // Support both 'cli' and 'agent' (deprecated alias)
52
+ const cli = (params.cli as string) ?? (params.agent as string);
53
+ const prompt = params.prompt as string;
54
+ const role = (params.role as string) ?? "development";
55
+ const timeoutSeconds = (params.timeoutSeconds as number) ?? 600;
56
+
57
+ if (!cli) {
58
+ log.error(`[codebridge_launch] ❌ Error: falta parámetro 'cli' o 'agent'`);
59
+ return {
60
+ ok: false,
61
+ error: "Missing required parameter: 'cli' or 'agent'. Use: codebridge_launch({ cli: 'qwen', prompt: '...' })",
62
+ };
63
+ }
64
+
65
+ if (!prompt) {
66
+ log.error(`[codebridge_launch] ❌ Error: falta parámetro 'prompt'`);
67
+ return {
68
+ ok: false,
69
+ error: "Missing required parameter: 'prompt'. Use: codebridge_launch({ cli: 'qwen', prompt: '...' })",
70
+ };
71
+ }
72
+
73
+ log.info(`[codebridge_launch] Iniciando subagente ${cli} para rol: ${role}`);
74
+ log.info(`[codebridge_launch] Code Bridge URL: ${CODE_BRIDGE_URL}`);
75
+ log.info(`[codebridge_launch] Code Bridge Base: ${CODE_BRIDGE_BASE}`);
76
+
77
+ try {
78
+ // Check if Code Bridge is available
79
+ log.info(`[codebridge_launch] Verificando disponibilidad de Code Bridge...`);
80
+ const controller = new AbortController();
81
+ const timeout = setTimeout(() => controller.abort(), 1000);
82
+ const response = await fetch(`${CODE_BRIDGE_BASE}/health`, { signal: controller.signal });
83
+ clearTimeout(timeout);
84
+
85
+ if (!response.ok) {
86
+ log.error(`[codebridge_launch] Code Bridge respondió con estado ${response.status}`);
87
+ return {
88
+ ok: false,
89
+ error: "Code Bridge not available. Start with: bun run packages/code-bridge/src/index.ts",
90
+ };
91
+ }
92
+
93
+ log.info(`[codebridge_launch] ✅ Code Bridge disponible`);
94
+
95
+ // Launch via WebSocket
96
+ log.info(`[codebridge_launch] Conectando WebSocket a ${CODE_BRIDGE_URL}...`);
97
+ const ws = new WebSocket(CODE_BRIDGE_URL);
98
+ const taskId = `task_${Date.now()}`;
99
+ log.info(`[codebridge_launch] Task ID generado: ${taskId}`);
100
+
101
+ return new Promise((resolve) => {
102
+ let resolved = false;
103
+ let timeoutHandle: ReturnType<typeof setTimeout>;
104
+
105
+ const done = () => {
106
+ clearTimeout(timeoutHandle);
107
+ ws.close();
108
+ };
109
+
110
+ ws.onopen = () => {
111
+ log.info(`[codebridge_launch] ✅ WebSocket conectado`);
112
+ log.info(`[codebridge_launch] Enviando comando launch para task ${taskId}...`);
113
+ log.info(`[codebridge_launch] Parámetros: cli=${cli}, prompt=${prompt?.substring(0, 50)}..., role=${role}, timeout=${timeoutSeconds}`);
114
+
115
+ const launchCmd = {
116
+ cmd: "launch",
117
+ taskId,
118
+ config: { role, cli, timeoutSeconds },
119
+ prompt,
120
+ };
121
+
122
+ log.info(`[codebridge_launch] Comando JSON: ${JSON.stringify(launchCmd, null, 2).substring(0, 200)}...`);
123
+ ws.send(JSON.stringify(launchCmd));
124
+ };
125
+
126
+ ws.onmessage = (event) => {
127
+ let data: any;
128
+ try { data = JSON.parse(event.data as string); } catch { return; }
129
+
130
+ log.info(`[codebridge_launch] 📩 WebSocket message: ${data.type}`, data.taskId ? `task: ${data.taskId}` : "");
131
+
132
+ if (data.type === "ack" && !resolved) {
133
+ resolved = true;
134
+ clearTimeout(timeoutHandle);
135
+ log.info(`[codebridge_launch] ✅ Launch ACK recibido - PID: ${data.pid}`);
136
+ emitBridgeEvent({ type: "bridge:cmd_start", data: { processId: taskId, command: cli, name: role } });
137
+ resolve({
138
+ ok: true,
139
+ taskId,
140
+ pid: data.pid,
141
+ message: `Launched ${cli} with PID ${data.pid}`,
142
+ });
143
+ // Keep WS open to relay subsequent events
144
+ return;
145
+ }
146
+
147
+ if (data.taskId !== taskId) return;
148
+
149
+ if (data.type === "agent:output") {
150
+ emitBridgeEvent({ type: "bridge:cmd_output", data: { processId: taskId, chunk: data.chunk, stream: data.stream ?? "stdout" } });
151
+ } else if (data.type === "agent:finished") {
152
+ log.info(`[codebridge_launch] ✅ Agente finalizado - Exit code: ${data.exitCode ?? 0}`);
153
+ emitBridgeEvent({ type: "bridge:cmd_done", data: { processId: taskId, exitCode: data.exitCode ?? 0, success: true } });
154
+ done();
155
+ } else if (data.type === "agent:error") {
156
+ log.error(`[codebridge_launch] ❌ Error del agente: ${data.message}`);
157
+ emitBridgeEvent({ type: "bridge:cmd_error", data: { processId: taskId, message: data.message } });
158
+ done();
159
+ } else if (data.type === "agent:cancelled") {
160
+ log.warn(`[codebridge_launch] ⚠️ Agente cancelado`);
161
+ emitBridgeEvent({ type: "bridge:cmd_done", data: { processId: taskId, exitCode: -1, success: false } });
162
+ done();
163
+ }
164
+ };
165
+
166
+ ws.onerror = () => {
167
+ log.error(`[codebridge_launch] ❌ Error de WebSocket`);
168
+ if (!resolved) {
169
+ resolved = true;
170
+ clearTimeout(timeoutHandle);
171
+ resolve({ ok: false, error: "Failed to connect to Code Bridge" });
172
+ }
173
+ };
174
+
175
+ timeoutHandle = setTimeout(() => {
176
+ if (!resolved) {
177
+ log.error(`[codebridge_launch] ⏱️ Timeout esperando respuesta de Code Bridge`);
178
+ resolved = true;
179
+ ws.close();
180
+ resolve({ ok: false, error: "Timeout connecting to Code Bridge" });
181
+ }
182
+ }, 5000);
183
+ });
184
+ } catch (error) {
185
+ log.error(`[codebridge_launch] ❌ Error fatal: ${(error as Error).message}`);
186
+ return {
187
+ ok: false,
188
+ error: `Failed to launch: ${(error as Error).message}`,
189
+ };
190
+ }
191
+ },
192
+ };
193
+
194
+ // ─── codebridge_status ───────────────────────────────────────────────────────
195
+
196
+ export const codebridgeStatusTool: Tool = {
197
+ name: "codebridge_status",
198
+ description: "Check the status and output of a running CodeBridge subagent. Spanish: estado agente de código, verificar Claude Code, progreso subagente externo",
199
+ parameters: {
200
+ type: "object",
201
+ properties: {
202
+ taskId: {
203
+ type: "string",
204
+ description: "Task ID to check status for",
205
+ },
206
+ },
207
+ required: ["taskId"],
208
+ },
209
+ execute: async (params: Record<string, unknown>) => {
210
+ const taskId = params.taskId as string;
211
+
212
+ try {
213
+ const response = await fetch(`${CODE_BRIDGE_BASE}/status/${taskId}`);
214
+
215
+ if (!response.ok) {
216
+ return { ok: false, error: `Task not found: ${taskId}` };
217
+ }
218
+
219
+ const data = await response.json();
220
+ return { ok: true, ...data };
221
+ } catch (error) {
222
+ return {
223
+ ok: false,
224
+ error: `Failed to get status: ${(error as Error).message}`,
225
+ };
226
+ }
227
+ },
228
+ };
229
+
230
+ // ─── codebridge_cancel ───────────────────────────────────────────────────────
231
+
232
+ export const codebridgeCancelTool: Tool = {
233
+ name: "codebridge_cancel",
234
+ description: "Cancel and terminate a running CodeBridge subagent process. Spanish: cancelar agente de código, detener Claude Code, terminar subagente externo",
235
+ parameters: {
236
+ type: "object",
237
+ properties: {
238
+ taskId: {
239
+ type: "string",
240
+ description: "Task ID to cancel",
241
+ },
242
+ },
243
+ required: ["taskId"],
244
+ },
245
+ execute: async (params: Record<string, unknown>) => {
246
+ const taskId = params.taskId as string;
247
+
248
+ try {
249
+ const response = await fetch(`${CODE_BRIDGE_BASE}/cancel/${taskId}`, { method: "POST" });
250
+
251
+ if (!response.ok) {
252
+ return { ok: false, error: `Failed to cancel: ${taskId}` };
253
+ }
254
+
255
+ return { ok: true, taskId, message: "Task cancelled." };
256
+ } catch (error) {
257
+ return {
258
+ ok: false,
259
+ error: `Failed to cancel: ${(error as Error).message}`,
260
+ };
261
+ }
262
+ },
263
+ };
264
+
265
+ // ─── codebridge_feedback ───────────────────────────────────────────────────────
266
+
267
+ export const codebridgeFeedbackTool: Tool = {
268
+ name: "codebridge_feedback",
269
+ description: "Send feedback or additional instructions to a running CodeBridge subagent. Use for course correction, clarifications, or iterative improvements during long-running code tasks. Spanish: enviar feedback, corregir rumbo, aclaraciones, mejoras iterativas",
270
+ parameters: {
271
+ type: "object",
272
+ properties: {
273
+ taskId: {
274
+ type: "string",
275
+ description: "Task ID to send feedback to",
276
+ },
277
+ feedback: {
278
+ type: "string",
279
+ description: "Feedback message or additional instructions for the running agent",
280
+ },
281
+ },
282
+ required: ["taskId", "feedback"],
283
+ },
284
+ execute: async (params: Record<string, unknown>) => {
285
+ const taskId = params.taskId as string;
286
+ const feedback = params.feedback as string;
287
+
288
+ try {
289
+ const ws = new WebSocket(CODE_BRIDGE_URL);
290
+
291
+ return new Promise((resolve) => {
292
+ ws.onopen = () => {
293
+ ws.send(JSON.stringify({
294
+ cmd: "feedback",
295
+ taskId,
296
+ feedback,
297
+ }));
298
+ };
299
+
300
+ ws.onmessage = (event) => {
301
+ try {
302
+ const data = JSON.parse(event.data);
303
+ if (data.type === "feedback:ack") {
304
+ resolve({
305
+ ok: data.delivered,
306
+ taskId,
307
+ delivered: data.delivered,
308
+ reason: data.reason,
309
+ message: data.delivered
310
+ ? "Feedback delivered to running agent"
311
+ : `Feedback not delivered: ${data.reason}`,
312
+ });
313
+ }
314
+ } catch {
315
+ resolve({ ok: false, error: "Failed to parse feedback response" });
316
+ }
317
+ ws.close();
318
+ };
319
+
320
+ ws.onerror = () => {
321
+ resolve({ ok: false, error: "WebSocket error" });
322
+ ws.close();
323
+ };
324
+
325
+ // Timeout after 5 seconds
326
+ setTimeout(() => {
327
+ resolve({ ok: false, error: "Feedback timeout" });
328
+ ws.close();
329
+ }, 5000);
330
+ });
331
+ } catch (error) {
332
+ return {
333
+ ok: false,
334
+ error: `Failed to send feedback: ${(error as Error).message}`,
335
+ };
336
+ }
337
+ },
338
+ };
339
+
340
+ export function createTools(): Tool[] {
341
+ return [codebridgeLaunchTool, codebridgeStatusTool, codebridgeCancelTool, codebridgeFeedbackTool];
342
+ }