synapsexcoder 6.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.
Files changed (705) hide show
  1. package/.opencode/opencode.jsonc +102 -0
  2. package/README.md +353 -0
  3. package/dist/agents/agent-config-manager.d.ts +58 -0
  4. package/dist/agents/agent-config-manager.d.ts.map +1 -0
  5. package/dist/agents/agent-config-manager.js +313 -0
  6. package/dist/agents/agent-config-manager.js.map +1 -0
  7. package/dist/agents/base-agents.d.ts +352 -0
  8. package/dist/agents/base-agents.d.ts.map +1 -0
  9. package/dist/agents/base-agents.js +3961 -0
  10. package/dist/agents/base-agents.js.map +1 -0
  11. package/dist/agents/gated-subagent.d.ts +126 -0
  12. package/dist/agents/gated-subagent.d.ts.map +1 -0
  13. package/dist/agents/gated-subagent.js +591 -0
  14. package/dist/agents/gated-subagent.js.map +1 -0
  15. package/dist/agents/gated-subagents.d.ts +130 -0
  16. package/dist/agents/gated-subagents.d.ts.map +1 -0
  17. package/dist/agents/gated-subagents.js +2014 -0
  18. package/dist/agents/gated-subagents.js.map +1 -0
  19. package/dist/agents/internal-gatekeeper.d.ts +167 -0
  20. package/dist/agents/internal-gatekeeper.d.ts.map +1 -0
  21. package/dist/agents/internal-gatekeeper.js +1130 -0
  22. package/dist/agents/internal-gatekeeper.js.map +1 -0
  23. package/dist/agents/verification-agent.d.ts +86 -0
  24. package/dist/agents/verification-agent.d.ts.map +1 -0
  25. package/dist/agents/verification-agent.js +211 -0
  26. package/dist/agents/verification-agent.js.map +1 -0
  27. package/dist/analytics/analytics-types.d.ts +113 -0
  28. package/dist/analytics/analytics-types.d.ts.map +1 -0
  29. package/dist/analytics/analytics-types.js +8 -0
  30. package/dist/analytics/analytics-types.js.map +1 -0
  31. package/dist/analytics/dashboard-generator.d.ts +35 -0
  32. package/dist/analytics/dashboard-generator.d.ts.map +1 -0
  33. package/dist/analytics/dashboard-generator.js +365 -0
  34. package/dist/analytics/dashboard-generator.js.map +1 -0
  35. package/dist/analytics/index.d.ts +12 -0
  36. package/dist/analytics/index.d.ts.map +1 -0
  37. package/dist/analytics/index.js +12 -0
  38. package/dist/analytics/index.js.map +1 -0
  39. package/dist/analytics/metrics-aggregator.d.ts +88 -0
  40. package/dist/analytics/metrics-aggregator.d.ts.map +1 -0
  41. package/dist/analytics/metrics-aggregator.js +280 -0
  42. package/dist/analytics/metrics-aggregator.js.map +1 -0
  43. package/dist/cli/index.d.ts +36 -0
  44. package/dist/cli/index.d.ts.map +1 -0
  45. package/dist/cli/index.js +2677 -0
  46. package/dist/cli/index.js.map +1 -0
  47. package/dist/cli/normalize_patch.d.ts +3 -0
  48. package/dist/cli/normalize_patch.d.ts.map +1 -0
  49. package/dist/cli/normalize_patch.js +34 -0
  50. package/dist/cli/normalize_patch.js.map +1 -0
  51. package/dist/commands/command-processor.d.ts +58 -0
  52. package/dist/commands/command-processor.d.ts.map +1 -0
  53. package/dist/commands/command-processor.js +796 -0
  54. package/dist/commands/command-processor.js.map +1 -0
  55. package/dist/config/compliance-checker.d.ts +93 -0
  56. package/dist/config/compliance-checker.d.ts.map +1 -0
  57. package/dist/config/compliance-checker.js +424 -0
  58. package/dist/config/compliance-checker.js.map +1 -0
  59. package/dist/config/enterprise-config.d.ts +173 -0
  60. package/dist/config/enterprise-config.d.ts.map +1 -0
  61. package/dist/config/enterprise-config.js +190 -0
  62. package/dist/config/enterprise-config.js.map +1 -0
  63. package/dist/config/index.d.ts +13 -0
  64. package/dist/config/index.d.ts.map +1 -0
  65. package/dist/config/index.js +11 -0
  66. package/dist/config/index.js.map +1 -0
  67. package/dist/context/context-system.d.ts +97 -0
  68. package/dist/context/context-system.d.ts.map +1 -0
  69. package/dist/context/context-system.js +880 -0
  70. package/dist/context/context-system.js.map +1 -0
  71. package/dist/context/store.d.ts +123 -0
  72. package/dist/context/store.d.ts.map +1 -0
  73. package/dist/context/store.js +281 -0
  74. package/dist/context/store.js.map +1 -0
  75. package/dist/dasp/dasp-controller.d.ts +83 -0
  76. package/dist/dasp/dasp-controller.d.ts.map +1 -0
  77. package/dist/dasp/dasp-controller.js +190 -0
  78. package/dist/dasp/dasp-controller.js.map +1 -0
  79. package/dist/dasp/feedback-adapter.d.ts +56 -0
  80. package/dist/dasp/feedback-adapter.d.ts.map +1 -0
  81. package/dist/dasp/feedback-adapter.js +158 -0
  82. package/dist/dasp/feedback-adapter.js.map +1 -0
  83. package/dist/dasp/index.d.ts +14 -0
  84. package/dist/dasp/index.d.ts.map +1 -0
  85. package/dist/dasp/index.js +10 -0
  86. package/dist/dasp/index.js.map +1 -0
  87. package/dist/dasp/prompt-templates.d.ts +38 -0
  88. package/dist/dasp/prompt-templates.d.ts.map +1 -0
  89. package/dist/dasp/prompt-templates.js +406 -0
  90. package/dist/dasp/prompt-templates.js.map +1 -0
  91. package/dist/dasp/vault-rag-provider.d.ts +51 -0
  92. package/dist/dasp/vault-rag-provider.d.ts.map +1 -0
  93. package/dist/dasp/vault-rag-provider.js +125 -0
  94. package/dist/dasp/vault-rag-provider.js.map +1 -0
  95. package/dist/distribution/cli-distribution.d.ts +68 -0
  96. package/dist/distribution/cli-distribution.d.ts.map +1 -0
  97. package/dist/distribution/cli-distribution.js +941 -0
  98. package/dist/distribution/cli-distribution.js.map +1 -0
  99. package/dist/docs/doc-generator.d.ts +78 -0
  100. package/dist/docs/doc-generator.d.ts.map +1 -0
  101. package/dist/docs/doc-generator.js +297 -0
  102. package/dist/docs/doc-generator.js.map +1 -0
  103. package/dist/docs/index.d.ts +13 -0
  104. package/dist/docs/index.d.ts.map +1 -0
  105. package/dist/docs/index.js +11 -0
  106. package/dist/docs/index.js.map +1 -0
  107. package/dist/docs/site-builder.d.ts +58 -0
  108. package/dist/docs/site-builder.d.ts.map +1 -0
  109. package/dist/docs/site-builder.js +229 -0
  110. package/dist/docs/site-builder.js.map +1 -0
  111. package/dist/ecosystem/adapters/claude-adapter.d.ts +29 -0
  112. package/dist/ecosystem/adapters/claude-adapter.d.ts.map +1 -0
  113. package/dist/ecosystem/adapters/claude-adapter.js +116 -0
  114. package/dist/ecosystem/adapters/claude-adapter.js.map +1 -0
  115. package/dist/ecosystem/adapters/cursor-adapter.d.ts +27 -0
  116. package/dist/ecosystem/adapters/cursor-adapter.d.ts.map +1 -0
  117. package/dist/ecosystem/adapters/cursor-adapter.js +93 -0
  118. package/dist/ecosystem/adapters/cursor-adapter.js.map +1 -0
  119. package/dist/ecosystem/adapters/v0-adapter.d.ts +30 -0
  120. package/dist/ecosystem/adapters/v0-adapter.d.ts.map +1 -0
  121. package/dist/ecosystem/adapters/v0-adapter.js +112 -0
  122. package/dist/ecosystem/adapters/v0-adapter.js.map +1 -0
  123. package/dist/ecosystem/ecosystem-router.d.ts +80 -0
  124. package/dist/ecosystem/ecosystem-router.d.ts.map +1 -0
  125. package/dist/ecosystem/ecosystem-router.js +241 -0
  126. package/dist/ecosystem/ecosystem-router.js.map +1 -0
  127. package/dist/ecosystem/ecosystem-types.d.ts +94 -0
  128. package/dist/ecosystem/ecosystem-types.d.ts.map +1 -0
  129. package/dist/ecosystem/ecosystem-types.js +27 -0
  130. package/dist/ecosystem/ecosystem-types.js.map +1 -0
  131. package/dist/ecosystem/index.d.ts +10 -0
  132. package/dist/ecosystem/index.d.ts.map +1 -0
  133. package/dist/ecosystem/index.js +9 -0
  134. package/dist/ecosystem/index.js.map +1 -0
  135. package/dist/integration/agentic-integration.d.ts +73 -0
  136. package/dist/integration/agentic-integration.d.ts.map +1 -0
  137. package/dist/integration/agentic-integration.js +253 -0
  138. package/dist/integration/agentic-integration.js.map +1 -0
  139. package/dist/integration/background-agents-integration.d.ts +54 -0
  140. package/dist/integration/background-agents-integration.d.ts.map +1 -0
  141. package/dist/integration/background-agents-integration.js +225 -0
  142. package/dist/integration/background-agents-integration.js.map +1 -0
  143. package/dist/integration/dcp-integration.d.ts +81 -0
  144. package/dist/integration/dcp-integration.d.ts.map +1 -0
  145. package/dist/integration/dcp-integration.js +189 -0
  146. package/dist/integration/dcp-integration.js.map +1 -0
  147. package/dist/integration/firecrawl-integration.d.ts +61 -0
  148. package/dist/integration/firecrawl-integration.d.ts.map +1 -0
  149. package/dist/integration/firecrawl-integration.js +246 -0
  150. package/dist/integration/firecrawl-integration.js.map +1 -0
  151. package/dist/integration/index.d.ts +40 -0
  152. package/dist/integration/index.d.ts.map +1 -0
  153. package/dist/integration/index.js +43 -0
  154. package/dist/integration/index.js.map +1 -0
  155. package/dist/integration/integration-hub.d.ts +43 -0
  156. package/dist/integration/integration-hub.d.ts.map +1 -0
  157. package/dist/integration/integration-hub.js +507 -0
  158. package/dist/integration/integration-hub.js.map +1 -0
  159. package/dist/integration/integration-loader.d.ts +42 -0
  160. package/dist/integration/integration-loader.d.ts.map +1 -0
  161. package/dist/integration/integration-loader.js +240 -0
  162. package/dist/integration/integration-loader.js.map +1 -0
  163. package/dist/integration/md-table-formatter-integration.d.ts +41 -0
  164. package/dist/integration/md-table-formatter-integration.d.ts.map +1 -0
  165. package/dist/integration/md-table-formatter-integration.js +183 -0
  166. package/dist/integration/md-table-formatter-integration.js.map +1 -0
  167. package/dist/integration/native/agentic/agentic-engine.d.ts +52 -0
  168. package/dist/integration/native/agentic/agentic-engine.d.ts.map +1 -0
  169. package/dist/integration/native/agentic/agentic-engine.js +267 -0
  170. package/dist/integration/native/agentic/agentic-engine.js.map +1 -0
  171. package/dist/integration/native/background/background-engine.d.ts +62 -0
  172. package/dist/integration/native/background/background-engine.d.ts.map +1 -0
  173. package/dist/integration/native/background/background-engine.js +167 -0
  174. package/dist/integration/native/background/background-engine.js.map +1 -0
  175. package/dist/integration/native/dcp/dcp-engine.d.ts +55 -0
  176. package/dist/integration/native/dcp/dcp-engine.d.ts.map +1 -0
  177. package/dist/integration/native/dcp/dcp-engine.js +168 -0
  178. package/dist/integration/native/dcp/dcp-engine.js.map +1 -0
  179. package/dist/integration/native/firecrawl/firecrawl-engine.d.ts +66 -0
  180. package/dist/integration/native/firecrawl/firecrawl-engine.d.ts.map +1 -0
  181. package/dist/integration/native/firecrawl/firecrawl-engine.js +221 -0
  182. package/dist/integration/native/firecrawl/firecrawl-engine.js.map +1 -0
  183. package/dist/integration/native/formatter/formatter-engine.d.ts +47 -0
  184. package/dist/integration/native/formatter/formatter-engine.d.ts.map +1 -0
  185. package/dist/integration/native/formatter/formatter-engine.js +130 -0
  186. package/dist/integration/native/formatter/formatter-engine.js.map +1 -0
  187. package/dist/integration/native/index.d.ts +41 -0
  188. package/dist/integration/native/index.d.ts.map +1 -0
  189. package/dist/integration/native/index.js +80 -0
  190. package/dist/integration/native/index.js.map +1 -0
  191. package/dist/integration/native/orchestration/orchestration-engine.d.ts +62 -0
  192. package/dist/integration/native/orchestration/orchestration-engine.d.ts.map +1 -0
  193. package/dist/integration/native/orchestration/orchestration-engine.js +177 -0
  194. package/dist/integration/native/orchestration/orchestration-engine.js.map +1 -0
  195. package/dist/integration/native/pty/pty-engine.d.ts +45 -0
  196. package/dist/integration/native/pty/pty-engine.d.ts.map +1 -0
  197. package/dist/integration/native/pty/pty-engine.js +103 -0
  198. package/dist/integration/native/pty/pty-engine.js.map +1 -0
  199. package/dist/integration/native/shell-strategy.d.ts +60 -0
  200. package/dist/integration/native/shell-strategy.d.ts.map +1 -0
  201. package/dist/integration/native/shell-strategy.js +131 -0
  202. package/dist/integration/native/shell-strategy.js.map +1 -0
  203. package/dist/integration/native/skillful/skillful-engine.d.ts +53 -0
  204. package/dist/integration/native/skillful/skillful-engine.d.ts.map +1 -0
  205. package/dist/integration/native/skillful/skillful-engine.js +127 -0
  206. package/dist/integration/native/skillful/skillful-engine.js.map +1 -0
  207. package/dist/integration/native/subtask2/subtask2-engine.d.ts +50 -0
  208. package/dist/integration/native/subtask2/subtask2-engine.d.ts.map +1 -0
  209. package/dist/integration/native/subtask2/subtask2-engine.js +158 -0
  210. package/dist/integration/native/subtask2/subtask2-engine.js.map +1 -0
  211. package/dist/integration/native/supermemory/supermemory-engine.d.ts +63 -0
  212. package/dist/integration/native/supermemory/supermemory-engine.d.ts.map +1 -0
  213. package/dist/integration/native/supermemory/supermemory-engine.js +127 -0
  214. package/dist/integration/native/supermemory/supermemory-engine.js.map +1 -0
  215. package/dist/integration/native/workspace/workspace-engine.d.ts +75 -0
  216. package/dist/integration/native/workspace/workspace-engine.d.ts.map +1 -0
  217. package/dist/integration/native/workspace/workspace-engine.js +216 -0
  218. package/dist/integration/native/workspace/workspace-engine.js.map +1 -0
  219. package/dist/integration/oh-my-opencode-integration.d.ts +59 -0
  220. package/dist/integration/oh-my-opencode-integration.d.ts.map +1 -0
  221. package/dist/integration/oh-my-opencode-integration.js +180 -0
  222. package/dist/integration/oh-my-opencode-integration.js.map +1 -0
  223. package/dist/integration/openagents-control-integration.d.ts +81 -0
  224. package/dist/integration/openagents-control-integration.d.ts.map +1 -0
  225. package/dist/integration/openagents-control-integration.js +273 -0
  226. package/dist/integration/openagents-control-integration.js.map +1 -0
  227. package/dist/integration/pty-integration.d.ts +64 -0
  228. package/dist/integration/pty-integration.d.ts.map +1 -0
  229. package/dist/integration/pty-integration.js +180 -0
  230. package/dist/integration/pty-integration.js.map +1 -0
  231. package/dist/integration/shell-strategy-integration.d.ts +26 -0
  232. package/dist/integration/shell-strategy-integration.d.ts.map +1 -0
  233. package/dist/integration/shell-strategy-integration.js +110 -0
  234. package/dist/integration/shell-strategy-integration.js.map +1 -0
  235. package/dist/integration/skillful-integration.d.ts +74 -0
  236. package/dist/integration/skillful-integration.d.ts.map +1 -0
  237. package/dist/integration/skillful-integration.js +317 -0
  238. package/dist/integration/skillful-integration.js.map +1 -0
  239. package/dist/integration/subtask2-integration.d.ts +71 -0
  240. package/dist/integration/subtask2-integration.d.ts.map +1 -0
  241. package/dist/integration/subtask2-integration.js +240 -0
  242. package/dist/integration/subtask2-integration.js.map +1 -0
  243. package/dist/integration/supermemory-integration.d.ts +82 -0
  244. package/dist/integration/supermemory-integration.d.ts.map +1 -0
  245. package/dist/integration/supermemory-integration.js +252 -0
  246. package/dist/integration/supermemory-integration.js.map +1 -0
  247. package/dist/integration/types.d.ts +218 -0
  248. package/dist/integration/types.d.ts.map +1 -0
  249. package/dist/integration/types.js +5 -0
  250. package/dist/integration/types.js.map +1 -0
  251. package/dist/integration/workspace-integration.d.ts +46 -0
  252. package/dist/integration/workspace-integration.d.ts.map +1 -0
  253. package/dist/integration/workspace-integration.js +181 -0
  254. package/dist/integration/workspace-integration.js.map +1 -0
  255. package/dist/knowledge-vault/deepwiki-sync.d.ts +99 -0
  256. package/dist/knowledge-vault/deepwiki-sync.d.ts.map +1 -0
  257. package/dist/knowledge-vault/deepwiki-sync.js +381 -0
  258. package/dist/knowledge-vault/deepwiki-sync.js.map +1 -0
  259. package/dist/knowledge-vault/index.d.ts +11 -0
  260. package/dist/knowledge-vault/index.d.ts.map +1 -0
  261. package/dist/knowledge-vault/index.js +8 -0
  262. package/dist/knowledge-vault/index.js.map +1 -0
  263. package/dist/knowledge-vault/knowledge-vault.d.ts +38 -0
  264. package/dist/knowledge-vault/knowledge-vault.d.ts.map +1 -0
  265. package/dist/knowledge-vault/knowledge-vault.js +284 -0
  266. package/dist/knowledge-vault/knowledge-vault.js.map +1 -0
  267. package/dist/knowledge-vault/opencode-doc-ingest.d.ts +23 -0
  268. package/dist/knowledge-vault/opencode-doc-ingest.d.ts.map +1 -0
  269. package/dist/knowledge-vault/opencode-doc-ingest.js +48 -0
  270. package/dist/knowledge-vault/opencode-doc-ingest.js.map +1 -0
  271. package/dist/knowledge-vault/types.d.ts +61 -0
  272. package/dist/knowledge-vault/types.d.ts.map +1 -0
  273. package/dist/knowledge-vault/types.js +5 -0
  274. package/dist/knowledge-vault/types.js.map +1 -0
  275. package/dist/knowledge-vault/vault-config.d.ts +12 -0
  276. package/dist/knowledge-vault/vault-config.d.ts.map +1 -0
  277. package/dist/knowledge-vault/vault-config.js +24 -0
  278. package/dist/knowledge-vault/vault-config.js.map +1 -0
  279. package/dist/mcp/index.d.ts +28 -0
  280. package/dist/mcp/index.d.ts.map +1 -0
  281. package/dist/mcp/index.js +29 -0
  282. package/dist/mcp/index.js.map +1 -0
  283. package/dist/mcp/mcp-manager.d.ts +181 -0
  284. package/dist/mcp/mcp-manager.d.ts.map +1 -0
  285. package/dist/mcp/mcp-manager.js +621 -0
  286. package/dist/mcp/mcp-manager.js.map +1 -0
  287. package/dist/mcp/mcp-types.d.ts +199 -0
  288. package/dist/mcp/mcp-types.d.ts.map +1 -0
  289. package/dist/mcp/mcp-types.js +152 -0
  290. package/dist/mcp/mcp-types.js.map +1 -0
  291. package/dist/mcp/servers/mcp-server-bridge.d.ts +64 -0
  292. package/dist/mcp/servers/mcp-server-bridge.d.ts.map +1 -0
  293. package/dist/mcp/servers/mcp-server-bridge.js +189 -0
  294. package/dist/mcp/servers/mcp-server-bridge.js.map +1 -0
  295. package/dist/messages/message-bus.d.ts +148 -0
  296. package/dist/messages/message-bus.d.ts.map +1 -0
  297. package/dist/messages/message-bus.js +432 -0
  298. package/dist/messages/message-bus.js.map +1 -0
  299. package/dist/modes/custom-mode-registry.d.ts +121 -0
  300. package/dist/modes/custom-mode-registry.d.ts.map +1 -0
  301. package/dist/modes/custom-mode-registry.js +306 -0
  302. package/dist/modes/custom-mode-registry.js.map +1 -0
  303. package/dist/modes/index.d.ts +10 -0
  304. package/dist/modes/index.d.ts.map +1 -0
  305. package/dist/modes/index.js +8 -0
  306. package/dist/modes/index.js.map +1 -0
  307. package/dist/modes/mode-designer.d.ts +89 -0
  308. package/dist/modes/mode-designer.d.ts.map +1 -0
  309. package/dist/modes/mode-designer.js +485 -0
  310. package/dist/modes/mode-designer.js.map +1 -0
  311. package/dist/modes/mode-manager.d.ts +27 -0
  312. package/dist/modes/mode-manager.d.ts.map +1 -0
  313. package/dist/modes/mode-manager.js +68 -0
  314. package/dist/modes/mode-manager.js.map +1 -0
  315. package/dist/modes/synapse-modes.d.ts +26 -0
  316. package/dist/modes/synapse-modes.d.ts.map +1 -0
  317. package/dist/modes/synapse-modes.js +69 -0
  318. package/dist/modes/synapse-modes.js.map +1 -0
  319. package/dist/opencode/agent-delegate.d.ts +3 -0
  320. package/dist/opencode/agent-delegate.d.ts.map +1 -0
  321. package/dist/opencode/agent-delegate.js +3 -0
  322. package/dist/opencode/agent-delegate.js.map +1 -0
  323. package/dist/opencode/tool-bridge.d.ts +3 -0
  324. package/dist/opencode/tool-bridge.d.ts.map +1 -0
  325. package/dist/opencode/tool-bridge.js +3 -0
  326. package/dist/opencode/tool-bridge.js.map +1 -0
  327. package/dist/optimization/token-optimizer-v2.d.ts +18 -0
  328. package/dist/optimization/token-optimizer-v2.d.ts.map +1 -0
  329. package/dist/optimization/token-optimizer-v2.js +23 -0
  330. package/dist/optimization/token-optimizer-v2.js.map +1 -0
  331. package/dist/optimization/token-optimizer.d.ts +90 -0
  332. package/dist/optimization/token-optimizer.d.ts.map +1 -0
  333. package/dist/optimization/token-optimizer.js +399 -0
  334. package/dist/optimization/token-optimizer.js.map +1 -0
  335. package/dist/parallel/agent-farm.d.ts +123 -0
  336. package/dist/parallel/agent-farm.d.ts.map +1 -0
  337. package/dist/parallel/agent-farm.js +501 -0
  338. package/dist/parallel/agent-farm.js.map +1 -0
  339. package/dist/parallel/farm-scheduler.d.ts +115 -0
  340. package/dist/parallel/farm-scheduler.d.ts.map +1 -0
  341. package/dist/parallel/farm-scheduler.js +356 -0
  342. package/dist/parallel/farm-scheduler.js.map +1 -0
  343. package/dist/parallel/farm-types.d.ts +104 -0
  344. package/dist/parallel/farm-types.d.ts.map +1 -0
  345. package/dist/parallel/farm-types.js +9 -0
  346. package/dist/parallel/farm-types.js.map +1 -0
  347. package/dist/parallel/farm-worker.d.ts +62 -0
  348. package/dist/parallel/farm-worker.d.ts.map +1 -0
  349. package/dist/parallel/farm-worker.js +268 -0
  350. package/dist/parallel/farm-worker.js.map +1 -0
  351. package/dist/parallel/index.d.ts +14 -0
  352. package/dist/parallel/index.d.ts.map +1 -0
  353. package/dist/parallel/index.js +14 -0
  354. package/dist/parallel/index.js.map +1 -0
  355. package/dist/plugin/native-tools.d.ts +8 -0
  356. package/dist/plugin/native-tools.d.ts.map +1 -0
  357. package/dist/plugin/native-tools.js +147 -0
  358. package/dist/plugin/native-tools.js.map +1 -0
  359. package/dist/plugin/opencode-plugin.d.ts +32 -0
  360. package/dist/plugin/opencode-plugin.d.ts.map +1 -0
  361. package/dist/plugin/opencode-plugin.js +119 -0
  362. package/dist/plugin/opencode-plugin.js.map +1 -0
  363. package/dist/plugins/plugin-system.d.ts +108 -0
  364. package/dist/plugins/plugin-system.d.ts.map +1 -0
  365. package/dist/plugins/plugin-system.js +707 -0
  366. package/dist/plugins/plugin-system.js.map +1 -0
  367. package/dist/profiler/cpu-profiler.d.ts +53 -0
  368. package/dist/profiler/cpu-profiler.d.ts.map +1 -0
  369. package/dist/profiler/cpu-profiler.js +233 -0
  370. package/dist/profiler/cpu-profiler.js.map +1 -0
  371. package/dist/profiler/index.d.ts +36 -0
  372. package/dist/profiler/index.d.ts.map +1 -0
  373. package/dist/profiler/index.js +122 -0
  374. package/dist/profiler/index.js.map +1 -0
  375. package/dist/profiler/memory-profiler.d.ts +45 -0
  376. package/dist/profiler/memory-profiler.d.ts.map +1 -0
  377. package/dist/profiler/memory-profiler.js +211 -0
  378. package/dist/profiler/memory-profiler.js.map +1 -0
  379. package/dist/profiler/profiler-types.d.ts +234 -0
  380. package/dist/profiler/profiler-types.d.ts.map +1 -0
  381. package/dist/profiler/profiler-types.js +89 -0
  382. package/dist/profiler/profiler-types.js.map +1 -0
  383. package/dist/profiler/query-profiler.d.ts +48 -0
  384. package/dist/profiler/query-profiler.d.ts.map +1 -0
  385. package/dist/profiler/query-profiler.js +210 -0
  386. package/dist/profiler/query-profiler.js.map +1 -0
  387. package/dist/profiler/report-generator.d.ts +17 -0
  388. package/dist/profiler/report-generator.d.ts.map +1 -0
  389. package/dist/profiler/report-generator.js +329 -0
  390. package/dist/profiler/report-generator.js.map +1 -0
  391. package/dist/sdk/api.d.ts +85 -0
  392. package/dist/sdk/api.d.ts.map +1 -0
  393. package/dist/sdk/api.js +155 -0
  394. package/dist/sdk/api.js.map +1 -0
  395. package/dist/sdk/hooks.d.ts +58 -0
  396. package/dist/sdk/hooks.d.ts.map +1 -0
  397. package/dist/sdk/hooks.js +115 -0
  398. package/dist/sdk/hooks.js.map +1 -0
  399. package/dist/sdk/index.d.ts +17 -0
  400. package/dist/sdk/index.d.ts.map +1 -0
  401. package/dist/sdk/index.js +14 -0
  402. package/dist/sdk/index.js.map +1 -0
  403. package/dist/sdk/plugin-base.d.ts +198 -0
  404. package/dist/sdk/plugin-base.d.ts.map +1 -0
  405. package/dist/sdk/plugin-base.js +227 -0
  406. package/dist/sdk/plugin-base.js.map +1 -0
  407. package/dist/security/audit-rules.d.ts +12 -0
  408. package/dist/security/audit-rules.d.ts.map +1 -0
  409. package/dist/security/audit-rules.js +214 -0
  410. package/dist/security/audit-rules.js.map +1 -0
  411. package/dist/security/index.d.ts +13 -0
  412. package/dist/security/index.d.ts.map +1 -0
  413. package/dist/security/index.js +13 -0
  414. package/dist/security/index.js.map +1 -0
  415. package/dist/security/sarif-exporter.d.ts +36 -0
  416. package/dist/security/sarif-exporter.d.ts.map +1 -0
  417. package/dist/security/sarif-exporter.js +216 -0
  418. package/dist/security/sarif-exporter.js.map +1 -0
  419. package/dist/security/security-auditor.d.ts +30 -0
  420. package/dist/security/security-auditor.d.ts.map +1 -0
  421. package/dist/security/security-auditor.js +295 -0
  422. package/dist/security/security-auditor.js.map +1 -0
  423. package/dist/security/security-types.d.ts +132 -0
  424. package/dist/security/security-types.d.ts.map +1 -0
  425. package/dist/security/security-types.js +7 -0
  426. package/dist/security/security-types.js.map +1 -0
  427. package/dist/synapsexcoder/agent-delegate.d.ts +128 -0
  428. package/dist/synapsexcoder/agent-delegate.d.ts.map +1 -0
  429. package/dist/synapsexcoder/agent-delegate.js +837 -0
  430. package/dist/synapsexcoder/agent-delegate.js.map +1 -0
  431. package/dist/synapsexcoder/agent-mailbox.d.ts +26 -0
  432. package/dist/synapsexcoder/agent-mailbox.d.ts.map +1 -0
  433. package/dist/synapsexcoder/agent-mailbox.js +64 -0
  434. package/dist/synapsexcoder/agent-mailbox.js.map +1 -0
  435. package/dist/synapsexcoder/ast-grep/ast-grep-api.d.ts +62 -0
  436. package/dist/synapsexcoder/ast-grep/ast-grep-api.d.ts.map +1 -0
  437. package/dist/synapsexcoder/ast-grep/ast-grep-api.js +223 -0
  438. package/dist/synapsexcoder/ast-grep/ast-grep-api.js.map +1 -0
  439. package/dist/synapsexcoder/cited-search.d.ts +32 -0
  440. package/dist/synapsexcoder/cited-search.d.ts.map +1 -0
  441. package/dist/synapsexcoder/cited-search.js +141 -0
  442. package/dist/synapsexcoder/cited-search.js.map +1 -0
  443. package/dist/synapsexcoder/credential-store.d.ts +42 -0
  444. package/dist/synapsexcoder/credential-store.d.ts.map +1 -0
  445. package/dist/synapsexcoder/credential-store.js +165 -0
  446. package/dist/synapsexcoder/credential-store.js.map +1 -0
  447. package/dist/synapsexcoder/devcontainer-awareness.d.ts +35 -0
  448. package/dist/synapsexcoder/devcontainer-awareness.d.ts.map +1 -0
  449. package/dist/synapsexcoder/devcontainer-awareness.js +133 -0
  450. package/dist/synapsexcoder/devcontainer-awareness.js.map +1 -0
  451. package/dist/synapsexcoder/execution-loops/helix-loop.d.ts +31 -0
  452. package/dist/synapsexcoder/execution-loops/helix-loop.d.ts.map +1 -0
  453. package/dist/synapsexcoder/execution-loops/helix-loop.js +93 -0
  454. package/dist/synapsexcoder/execution-loops/helix-loop.js.map +1 -0
  455. package/dist/synapsexcoder/execution-loops/ralp-loop.d.ts +28 -0
  456. package/dist/synapsexcoder/execution-loops/ralp-loop.d.ts.map +1 -0
  457. package/dist/synapsexcoder/execution-loops/ralp-loop.js +77 -0
  458. package/dist/synapsexcoder/execution-loops/ralp-loop.js.map +1 -0
  459. package/dist/synapsexcoder/feature-names.d.ts +27 -0
  460. package/dist/synapsexcoder/feature-names.d.ts.map +1 -0
  461. package/dist/synapsexcoder/feature-names.js +40 -0
  462. package/dist/synapsexcoder/feature-names.js.map +1 -0
  463. package/dist/synapsexcoder/index.d.ts +39 -0
  464. package/dist/synapsexcoder/index.d.ts.map +1 -0
  465. package/dist/synapsexcoder/index.js +23 -0
  466. package/dist/synapsexcoder/index.js.map +1 -0
  467. package/dist/synapsexcoder/knowledge-provider.d.ts +44 -0
  468. package/dist/synapsexcoder/knowledge-provider.d.ts.map +1 -0
  469. package/dist/synapsexcoder/knowledge-provider.js +107 -0
  470. package/dist/synapsexcoder/knowledge-provider.js.map +1 -0
  471. package/dist/synapsexcoder/lsp/lsp-layer.d.ts +51 -0
  472. package/dist/synapsexcoder/lsp/lsp-layer.d.ts.map +1 -0
  473. package/dist/synapsexcoder/lsp/lsp-layer.js +302 -0
  474. package/dist/synapsexcoder/lsp/lsp-layer.js.map +1 -0
  475. package/dist/synapsexcoder/migration/opencode-config-migrator.d.ts +37 -0
  476. package/dist/synapsexcoder/migration/opencode-config-migrator.d.ts.map +1 -0
  477. package/dist/synapsexcoder/migration/opencode-config-migrator.js +100 -0
  478. package/dist/synapsexcoder/migration/opencode-config-migrator.js.map +1 -0
  479. package/dist/synapsexcoder/runtime-environment.d.ts +35 -0
  480. package/dist/synapsexcoder/runtime-environment.d.ts.map +1 -0
  481. package/dist/synapsexcoder/runtime-environment.js +108 -0
  482. package/dist/synapsexcoder/runtime-environment.js.map +1 -0
  483. package/dist/synapsexcoder/secret-guard.d.ts +18 -0
  484. package/dist/synapsexcoder/secret-guard.d.ts.map +1 -0
  485. package/dist/synapsexcoder/secret-guard.js +69 -0
  486. package/dist/synapsexcoder/secret-guard.js.map +1 -0
  487. package/dist/synapsexcoder/self-prompt-engine.d.ts +15 -0
  488. package/dist/synapsexcoder/self-prompt-engine.d.ts.map +1 -0
  489. package/dist/synapsexcoder/self-prompt-engine.js +11 -0
  490. package/dist/synapsexcoder/self-prompt-engine.js.map +1 -0
  491. package/dist/synapsexcoder/session-observability.d.ts +44 -0
  492. package/dist/synapsexcoder/session-observability.d.ts.map +1 -0
  493. package/dist/synapsexcoder/session-observability.js +115 -0
  494. package/dist/synapsexcoder/session-observability.js.map +1 -0
  495. package/dist/synapsexcoder/specialist-agents.d.ts +38 -0
  496. package/dist/synapsexcoder/specialist-agents.d.ts.map +1 -0
  497. package/dist/synapsexcoder/specialist-agents.js +192 -0
  498. package/dist/synapsexcoder/specialist-agents.js.map +1 -0
  499. package/dist/synapsexcoder/swarm/kanban-board.d.ts +34 -0
  500. package/dist/synapsexcoder/swarm/kanban-board.d.ts.map +1 -0
  501. package/dist/synapsexcoder/swarm/kanban-board.js +85 -0
  502. package/dist/synapsexcoder/swarm/kanban-board.js.map +1 -0
  503. package/dist/synapsexcoder/swarm/swarm-mailbox.d.ts +38 -0
  504. package/dist/synapsexcoder/swarm/swarm-mailbox.d.ts.map +1 -0
  505. package/dist/synapsexcoder/swarm/swarm-mailbox.js +93 -0
  506. package/dist/synapsexcoder/swarm/swarm-mailbox.js.map +1 -0
  507. package/dist/synapsexcoder/tool-bridge.d.ts +277 -0
  508. package/dist/synapsexcoder/tool-bridge.d.ts.map +1 -0
  509. package/dist/synapsexcoder/tool-bridge.js +1356 -0
  510. package/dist/synapsexcoder/tool-bridge.js.map +1 -0
  511. package/dist/synapsexcoder/tool-routing.d.ts +28 -0
  512. package/dist/synapsexcoder/tool-routing.d.ts.map +1 -0
  513. package/dist/synapsexcoder/tool-routing.js +79 -0
  514. package/dist/synapsexcoder/tool-routing.js.map +1 -0
  515. package/dist/synapsexcoder/type-injector.d.ts +26 -0
  516. package/dist/synapsexcoder/type-injector.d.ts.map +1 -0
  517. package/dist/synapsexcoder/type-injector.js +124 -0
  518. package/dist/synapsexcoder/type-injector.js.map +1 -0
  519. package/dist/synapsexcoder/utils/fuzzy-match.d.ts +25 -0
  520. package/dist/synapsexcoder/utils/fuzzy-match.d.ts.map +1 -0
  521. package/dist/synapsexcoder/utils/fuzzy-match.js +83 -0
  522. package/dist/synapsexcoder/utils/fuzzy-match.js.map +1 -0
  523. package/dist/synapsexcoder/vault-crawl.d.ts +29 -0
  524. package/dist/synapsexcoder/vault-crawl.d.ts.map +1 -0
  525. package/dist/synapsexcoder/vault-crawl.js +103 -0
  526. package/dist/synapsexcoder/vault-crawl.js.map +1 -0
  527. package/dist/synapsexcoder/verified-apply.d.ts +39 -0
  528. package/dist/synapsexcoder/verified-apply.d.ts.map +1 -0
  529. package/dist/synapsexcoder/verified-apply.js +81 -0
  530. package/dist/synapsexcoder/verified-apply.js.map +1 -0
  531. package/dist/synapsexcoder/verified-context-editing.d.ts +34 -0
  532. package/dist/synapsexcoder/verified-context-editing.d.ts.map +1 -0
  533. package/dist/synapsexcoder/verified-context-editing.js +80 -0
  534. package/dist/synapsexcoder/verified-context-editing.js.map +1 -0
  535. package/dist/synapsexcoder/worker-pool.d.ts +47 -0
  536. package/dist/synapsexcoder/worker-pool.d.ts.map +1 -0
  537. package/dist/synapsexcoder/worker-pool.js +120 -0
  538. package/dist/synapsexcoder/worker-pool.js.map +1 -0
  539. package/dist/synapsexcoder/workspace-intelligence.d.ts +35 -0
  540. package/dist/synapsexcoder/workspace-intelligence.d.ts.map +1 -0
  541. package/dist/synapsexcoder/workspace-intelligence.js +126 -0
  542. package/dist/synapsexcoder/workspace-intelligence.js.map +1 -0
  543. package/dist/synapsexcoder/worktree-manager.d.ts +31 -0
  544. package/dist/synapsexcoder/worktree-manager.d.ts.map +1 -0
  545. package/dist/synapsexcoder/worktree-manager.js +100 -0
  546. package/dist/synapsexcoder/worktree-manager.js.map +1 -0
  547. package/dist/team/index.d.ts +17 -0
  548. package/dist/team/index.d.ts.map +1 -0
  549. package/dist/team/index.js +13 -0
  550. package/dist/team/index.js.map +1 -0
  551. package/dist/team/team-audit.d.ts +120 -0
  552. package/dist/team/team-audit.d.ts.map +1 -0
  553. package/dist/team/team-audit.js +357 -0
  554. package/dist/team/team-audit.js.map +1 -0
  555. package/dist/team/team-collaboration.d.ts +150 -0
  556. package/dist/team/team-collaboration.d.ts.map +1 -0
  557. package/dist/team/team-collaboration.js +495 -0
  558. package/dist/team/team-collaboration.js.map +1 -0
  559. package/dist/team/team-rbac.d.ts +84 -0
  560. package/dist/team/team-rbac.d.ts.map +1 -0
  561. package/dist/team/team-rbac.js +259 -0
  562. package/dist/team/team-rbac.js.map +1 -0
  563. package/dist/team/team-session-manager.d.ts +100 -0
  564. package/dist/team/team-session-manager.d.ts.map +1 -0
  565. package/dist/team/team-session-manager.js +255 -0
  566. package/dist/team/team-session-manager.js.map +1 -0
  567. package/dist/thoughts/thoughts-manager.d.ts +52 -0
  568. package/dist/thoughts/thoughts-manager.d.ts.map +1 -0
  569. package/dist/thoughts/thoughts-manager.js +271 -0
  570. package/dist/thoughts/thoughts-manager.js.map +1 -0
  571. package/dist/tools/api-validator/index.d.ts +97 -0
  572. package/dist/tools/api-validator/index.d.ts.map +1 -0
  573. package/dist/tools/api-validator/index.js +312 -0
  574. package/dist/tools/api-validator/index.js.map +1 -0
  575. package/dist/tools/code-archaeology/index.d.ts +193 -0
  576. package/dist/tools/code-archaeology/index.d.ts.map +1 -0
  577. package/dist/tools/code-archaeology/index.js +468 -0
  578. package/dist/tools/code-archaeology/index.js.map +1 -0
  579. package/dist/tools/codebase-search/index.d.ts +126 -0
  580. package/dist/tools/codebase-search/index.d.ts.map +1 -0
  581. package/dist/tools/codebase-search/index.js +437 -0
  582. package/dist/tools/codebase-search/index.js.map +1 -0
  583. package/dist/tools/context/index.d.ts +162 -0
  584. package/dist/tools/context/index.d.ts.map +1 -0
  585. package/dist/tools/context/index.js +332 -0
  586. package/dist/tools/context/index.js.map +1 -0
  587. package/dist/tools/deepwiki/analyzer.d.ts +167 -0
  588. package/dist/tools/deepwiki/analyzer.d.ts.map +1 -0
  589. package/dist/tools/deepwiki/analyzer.js +925 -0
  590. package/dist/tools/deepwiki/analyzer.js.map +1 -0
  591. package/dist/tools/deepwiki/extractor.d.ts +151 -0
  592. package/dist/tools/deepwiki/extractor.d.ts.map +1 -0
  593. package/dist/tools/deepwiki/extractor.js +923 -0
  594. package/dist/tools/deepwiki/extractor.js.map +1 -0
  595. package/dist/tools/deepwiki/generator.d.ts +89 -0
  596. package/dist/tools/deepwiki/generator.d.ts.map +1 -0
  597. package/dist/tools/deepwiki/generator.js +638 -0
  598. package/dist/tools/deepwiki/generator.js.map +1 -0
  599. package/dist/tools/deepwiki/index.d.ts +96 -0
  600. package/dist/tools/deepwiki/index.d.ts.map +1 -0
  601. package/dist/tools/deepwiki/index.js +282 -0
  602. package/dist/tools/deepwiki/index.js.map +1 -0
  603. package/dist/tools/deepwiki/types.d.ts +370 -0
  604. package/dist/tools/deepwiki/types.d.ts.map +1 -0
  605. package/dist/tools/deepwiki/types.js +21 -0
  606. package/dist/tools/deepwiki/types.js.map +1 -0
  607. package/dist/tools/dependency-mapper/index.d.ts +212 -0
  608. package/dist/tools/dependency-mapper/index.d.ts.map +1 -0
  609. package/dist/tools/dependency-mapper/index.js +592 -0
  610. package/dist/tools/dependency-mapper/index.js.map +1 -0
  611. package/dist/tools/memory/index.d.ts +120 -0
  612. package/dist/tools/memory/index.d.ts.map +1 -0
  613. package/dist/tools/memory/index.js +275 -0
  614. package/dist/tools/memory/index.js.map +1 -0
  615. package/dist/tools/normalize_patch.d.ts +3 -0
  616. package/dist/tools/normalize_patch.d.ts.map +1 -0
  617. package/dist/tools/normalize_patch.js +22 -0
  618. package/dist/tools/normalize_patch.js.map +1 -0
  619. package/dist/tools/pattern-detector/index.d.ts +105 -0
  620. package/dist/tools/pattern-detector/index.d.ts.map +1 -0
  621. package/dist/tools/pattern-detector/index.js +526 -0
  622. package/dist/tools/pattern-detector/index.js.map +1 -0
  623. package/dist/tools/performance-profiler/index.d.ts +50 -0
  624. package/dist/tools/performance-profiler/index.d.ts.map +1 -0
  625. package/dist/tools/performance-profiler/index.js +164 -0
  626. package/dist/tools/performance-profiler/index.js.map +1 -0
  627. package/dist/tools/refactoring-engine/index.d.ts +63 -0
  628. package/dist/tools/refactoring-engine/index.d.ts.map +1 -0
  629. package/dist/tools/refactoring-engine/index.js +270 -0
  630. package/dist/tools/refactoring-engine/index.js.map +1 -0
  631. package/dist/tools/registry.d.ts +36 -0
  632. package/dist/tools/registry.d.ts.map +1 -0
  633. package/dist/tools/registry.js +499 -0
  634. package/dist/tools/registry.js.map +1 -0
  635. package/dist/tools/test-generator/index.d.ts +152 -0
  636. package/dist/tools/test-generator/index.d.ts.map +1 -0
  637. package/dist/tools/test-generator/index.js +448 -0
  638. package/dist/tools/test-generator/index.js.map +1 -0
  639. package/dist/types/index.d.ts +565 -0
  640. package/dist/types/index.d.ts.map +1 -0
  641. package/dist/types/index.js +7 -0
  642. package/dist/types/index.js.map +1 -0
  643. package/dist/utils/path-validator.d.ts +94 -0
  644. package/dist/utils/path-validator.d.ts.map +1 -0
  645. package/dist/utils/path-validator.js +192 -0
  646. package/dist/utils/path-validator.js.map +1 -0
  647. package/dist/utils/secure-exec.d.ts +92 -0
  648. package/dist/utils/secure-exec.d.ts.map +1 -0
  649. package/dist/utils/secure-exec.js +230 -0
  650. package/dist/utils/secure-exec.js.map +1 -0
  651. package/dist/verification/claim-parser.d.ts +37 -0
  652. package/dist/verification/claim-parser.d.ts.map +1 -0
  653. package/dist/verification/claim-parser.js +231 -0
  654. package/dist/verification/claim-parser.js.map +1 -0
  655. package/dist/verification/cross-reference-engine.d.ts +55 -0
  656. package/dist/verification/cross-reference-engine.d.ts.map +1 -0
  657. package/dist/verification/cross-reference-engine.js +149 -0
  658. package/dist/verification/cross-reference-engine.js.map +1 -0
  659. package/dist/verification/discrepancy-tracker.d.ts +73 -0
  660. package/dist/verification/discrepancy-tracker.d.ts.map +1 -0
  661. package/dist/verification/discrepancy-tracker.js +196 -0
  662. package/dist/verification/discrepancy-tracker.js.map +1 -0
  663. package/dist/verification/feature-reconciler.d.ts +90 -0
  664. package/dist/verification/feature-reconciler.d.ts.map +1 -0
  665. package/dist/verification/feature-reconciler.js +264 -0
  666. package/dist/verification/feature-reconciler.js.map +1 -0
  667. package/dist/verification/index.d.ts +16 -0
  668. package/dist/verification/index.d.ts.map +1 -0
  669. package/dist/verification/index.js +19 -0
  670. package/dist/verification/index.js.map +1 -0
  671. package/dist/verification/integration-verifier.d.ts +66 -0
  672. package/dist/verification/integration-verifier.d.ts.map +1 -0
  673. package/dist/verification/integration-verifier.js +210 -0
  674. package/dist/verification/integration-verifier.js.map +1 -0
  675. package/dist/verification/recursive-audit-loop.d.ts +56 -0
  676. package/dist/verification/recursive-audit-loop.d.ts.map +1 -0
  677. package/dist/verification/recursive-audit-loop.js +136 -0
  678. package/dist/verification/recursive-audit-loop.js.map +1 -0
  679. package/dist/verification/runtime-verifier.d.ts +37 -0
  680. package/dist/verification/runtime-verifier.d.ts.map +1 -0
  681. package/dist/verification/runtime-verifier.js +221 -0
  682. package/dist/verification/runtime-verifier.js.map +1 -0
  683. package/dist/verification/types.d.ts +88 -0
  684. package/dist/verification/types.d.ts.map +1 -0
  685. package/dist/verification/types.js +5 -0
  686. package/dist/verification/types.js.map +1 -0
  687. package/dist/verification/verification-engine.d.ts +48 -0
  688. package/dist/verification/verification-engine.d.ts.map +1 -0
  689. package/dist/verification/verification-engine.js +203 -0
  690. package/dist/verification/verification-engine.js.map +1 -0
  691. package/opencode-agents/synapse-analyzer.md +64 -0
  692. package/opencode-agents/synapse-debugger.md +43 -0
  693. package/opencode-agents/synapse-diff-validator.md +42 -0
  694. package/opencode-agents/synapse-gatekeeper.md +273 -0
  695. package/opencode-agents/synapse-master.md +167 -0
  696. package/opencode-agents/synapse-planner.md +55 -0
  697. package/opencode-agents/synapse-researcher.md +61 -0
  698. package/opencode-agents/synapse-reviewer.md +64 -0
  699. package/opencode-agents/synapse-rewriter.md +62 -0
  700. package/opencode-agents/synapse-strategist.md +50 -0
  701. package/opencode-agents/synapse-test-runner.md +43 -0
  702. package/opencode-agents/synapse-ui-designer.md +61 -0
  703. package/opencode-agents/synapse-verifier.md +544 -0
  704. package/package.json +108 -0
  705. package/src/plugin/opencode-plugin.ts +141 -0
@@ -0,0 +1,2014 @@
1
+ // @ts-nocheck
2
+ /**
3
+ * Gated Subagents — Multi-Step Pipeline with Internal Gatekeeper
4
+ *
5
+ * Implements the full Gated Subagent Pipeline:
6
+ * 1. Plan Mode: Decompose task into phases
7
+ * 2. Execute Phase: Run each phase with appropriate agent
8
+ * 3. Gatekeeper Review: Internal gatekeeper reviews output
9
+ * 4. Decision: APPROVE / DECLINE / RESTART
10
+ * 5. Retry: If declined, retry with modified approach
11
+ */
12
+ import { GatedSubAgent } from "./gated-subagent.js";
13
+ // ============================================================================
14
+ // Gated Planner Agent
15
+ // ============================================================================
16
+ export class GatedPlannerAgent extends GatedSubAgent {
17
+ constructor(messageBus, toolBridge, config) {
18
+ super("planner", config || {}, messageBus, toolBridge, {
19
+ maxRetries: 3,
20
+ strictMode: true,
21
+ });
22
+ }
23
+ async performTask(task) {
24
+ this.updateStatus("running", "Creating execution plan");
25
+ const prompt = `Create a detailed execution plan for the following task:
26
+
27
+ Task: ${task.prompt}
28
+
29
+ Context: ${task.context.files.length} files provided, mode: ${task.context.metadata?.mode || "full"}
30
+
31
+ Please provide a structured plan with:
32
+ 1. Goal analysis
33
+ 2. Step-by-step breakdown
34
+ 3. Estimated complexity (low/medium/high)
35
+ 4. Estimated time
36
+ 5. Required tools/resources
37
+ 6. Potential risks
38
+
39
+ Format as structured JSON.`;
40
+ const response = await this.callModel(prompt);
41
+ if (!response) {
42
+ return this.localPlanFallback(task);
43
+ }
44
+ try {
45
+ return JSON.parse(response);
46
+ }
47
+ catch {
48
+ return {
49
+ goal: task.prompt,
50
+ plan: response,
51
+ ...this.estimateComplexityFromText(task.prompt),
52
+ };
53
+ }
54
+ }
55
+ /**
56
+ * Local fallback: tokenize the task description, extract action verbs,
57
+ * detect complexity from keyword signals, and build a real numbered step
58
+ * list with dependency chains. No hardcoded data.
59
+ */
60
+ localPlanFallback(task) {
61
+ const description = task.prompt || "";
62
+ const lower = description.toLowerCase();
63
+ const fileCount = task.context.files.length;
64
+ // --- Extract action verbs and targets from the task description ---
65
+ const actionPatterns = [
66
+ {
67
+ verb: "create",
68
+ regex: /\b(?:create|build|generate|scaffold|add|implement|write)\s+(?:a\s+)?(.+?)(?:\s+(?:and|then|,|\.)|$)/gi,
69
+ },
70
+ {
71
+ verb: "refactor",
72
+ regex: /\b(?:refactor|restructure|reorganize|redesign)\s+(?:the\s+)?(.+?)(?:\s+(?:and|then|,|\.)|$)/gi,
73
+ },
74
+ {
75
+ verb: "fix",
76
+ regex: /\b(?:fix|repair|resolve|patch|debug)\s+(?:the\s+)?(.+?)(?:\s+(?:and|then|,|\.)|$)/gi,
77
+ },
78
+ {
79
+ verb: "update",
80
+ regex: /\b(?:update|modify|change|edit|adjust|improve)\s+(?:the\s+)?(.+?)(?:\s+(?:and|then|,|\.)|$)/gi,
81
+ },
82
+ {
83
+ verb: "test",
84
+ regex: /\b(?:test|verify|validate|check)\s+(?:the\s+)?(.+?)(?:\s+(?:and|then|,|\.)|$)/gi,
85
+ },
86
+ {
87
+ verb: "delete",
88
+ regex: /\b(?:delete|remove|drop|clean\s*up)\s+(?:the\s+)?(.+?)(?:\s+(?:and|then|,|\.)|$)/gi,
89
+ },
90
+ {
91
+ verb: "migrate",
92
+ regex: /\b(?:migrate|move|transfer|port)\s+(?:the\s+)?(.+?)(?:\s+(?:and|then|,|\.)|$)/gi,
93
+ },
94
+ {
95
+ verb: "deploy",
96
+ regex: /\b(?:deploy|publish|release|ship)\s+(?:the\s+)?(.+?)(?:\s+(?:and|then|,|\.)|$)/gi,
97
+ },
98
+ {
99
+ verb: "analyze",
100
+ regex: /\b(?:analyze|inspect|examine|review|audit)\s+(?:the\s+)?(.+?)(?:\s+(?:and|then|,|\.)|$)/gi,
101
+ },
102
+ {
103
+ verb: "configure",
104
+ regex: /\b(?:configure|setup|set\s*up|initialize|install)\s+(?:the\s+)?(.+?)(?:\s+(?:and|then|,|\.)|$)/gi,
105
+ },
106
+ ];
107
+ const extractedActions = [];
108
+ for (const { verb, regex } of actionPatterns) {
109
+ let match;
110
+ while ((match = regex.exec(description)) !== null) {
111
+ const target = match[1]?.trim().substring(0, 80) || "the task";
112
+ if (target.length > 2) {
113
+ extractedActions.push({ verb, target });
114
+ }
115
+ }
116
+ }
117
+ // --- Build steps from extracted actions or sentence splitting ---
118
+ let steps;
119
+ if (extractedActions.length > 0) {
120
+ steps = extractedActions.map((action, idx) => ({
121
+ step: idx + 1,
122
+ action: action.verb,
123
+ description: `${action.verb.charAt(0).toUpperCase() + action.verb.slice(1)} ${action.target}`,
124
+ dependsOn: idx > 0 ? [idx] : [],
125
+ }));
126
+ }
127
+ else {
128
+ // Split by conjunctions, commas, or sentence boundaries
129
+ const segments = description
130
+ .split(/(?:\s+and\s+|\s*,\s*|\.\s+|\s+then\s+)/i)
131
+ .map((s) => s.trim())
132
+ .filter((s) => s.length > 3);
133
+ if (segments.length > 1) {
134
+ steps = segments.map((seg, idx) => ({
135
+ step: idx + 1,
136
+ action: "execute",
137
+ description: seg.charAt(0).toUpperCase() + seg.slice(1),
138
+ dependsOn: idx > 0 ? [idx] : [],
139
+ }));
140
+ }
141
+ else {
142
+ // Single task — generate analyze → implement → verify chain
143
+ steps = [
144
+ {
145
+ step: 1,
146
+ action: "analyze",
147
+ description: `Analyze requirements: ${description.substring(0, 100)}`,
148
+ dependsOn: [],
149
+ },
150
+ {
151
+ step: 2,
152
+ action: "implement",
153
+ description: `Implement changes for: ${description.substring(0, 80)}`,
154
+ dependsOn: [1],
155
+ },
156
+ {
157
+ step: 3,
158
+ action: "verify",
159
+ description: "Verify implementation and check for regressions",
160
+ dependsOn: [2],
161
+ },
162
+ ];
163
+ }
164
+ }
165
+ // Add file-scan step if files are present
166
+ if (fileCount > 0 && steps.length > 0) {
167
+ steps.unshift({
168
+ step: 0,
169
+ action: "scan",
170
+ description: `Scan ${fileCount} provided file(s) for context`,
171
+ dependsOn: [],
172
+ });
173
+ // Re-number and adjust deps
174
+ steps = steps.map((s, idx) => ({
175
+ ...s,
176
+ step: idx + 1,
177
+ dependsOn: idx === 0 ? [] : s.dependsOn.map((d) => d + 1),
178
+ }));
179
+ }
180
+ // --- Complexity from keyword signals ---
181
+ const complexity = this.estimateComplexityFromText(lower);
182
+ // --- Required tools based on keywords ---
183
+ const tools = [];
184
+ if (/\b(file|read|write|edit|create)\b/i.test(lower))
185
+ tools.push("file_operations");
186
+ if (/\b(test|spec|jest|mocha|vitest)\b/i.test(lower))
187
+ tools.push("testing_framework");
188
+ if (/\b(git|commit|branch|merge|pr)\b/i.test(lower))
189
+ tools.push("version_control");
190
+ if (/\b(npm|yarn|pnpm|install|package)\b/i.test(lower))
191
+ tools.push("package_manager");
192
+ if (/\b(api|endpoint|http|fetch|request)\b/i.test(lower))
193
+ tools.push("http_client");
194
+ if (/\b(db|database|sql|query|schema|migration)\b/i.test(lower))
195
+ tools.push("database");
196
+ if (/\b(docker|container|deploy|ci|cd)\b/i.test(lower))
197
+ tools.push("devops");
198
+ if (tools.length === 0)
199
+ tools.push("code_editor");
200
+ // --- Risk factors ---
201
+ const risks = [];
202
+ if (/\b(refactor|migrate|restructure)\b/i.test(lower))
203
+ risks.push("Breaking changes in dependent code");
204
+ if (/\b(delete|remove|drop)\b/i.test(lower))
205
+ risks.push("Data or code loss if not backed up");
206
+ if (/\b(security|auth|password|token|secret)\b/i.test(lower))
207
+ risks.push("Security-sensitive changes require careful review");
208
+ if (fileCount > 10)
209
+ risks.push(`Large scope: ${fileCount} files may have cascading impacts`);
210
+ if (/\b(production|prod|live)\b/i.test(lower))
211
+ risks.push("Changes target production environment");
212
+ if (risks.length === 0)
213
+ risks.push("Standard development risk — verify with tests");
214
+ return {
215
+ goal: task.prompt,
216
+ steps,
217
+ ...complexity,
218
+ requiredTools: tools,
219
+ risks,
220
+ fileScope: fileCount,
221
+ note: "Plan generated via local keyword analysis (model unavailable)",
222
+ };
223
+ }
224
+ /**
225
+ * Estimate complexity and time from task text keyword signals.
226
+ */
227
+ estimateComplexityFromText(text) {
228
+ const lower = text.toLowerCase();
229
+ const wordCount = text.split(/\s+/).length;
230
+ const highKeywords = /\b(refactor|migrate|integrate|redesign|architect|overhaul|rewrite|restructure|distributed|concurrent|multi.?thread)\b/i;
231
+ const lowKeywords = /\b(rename|move|delete|remove|typo|comment|log|print|bump|update version|fix typo)\b/i;
232
+ let estimatedComplexity;
233
+ let estimatedTime;
234
+ if (highKeywords.test(lower) || wordCount > 80) {
235
+ estimatedComplexity = "high";
236
+ estimatedTime = "15-30 minutes";
237
+ }
238
+ else if (lowKeywords.test(lower) && wordCount < 20) {
239
+ estimatedComplexity = "low";
240
+ estimatedTime = "1-3 minutes";
241
+ }
242
+ else {
243
+ estimatedComplexity = "medium";
244
+ estimatedTime = "5-10 minutes";
245
+ }
246
+ return { estimatedComplexity, estimatedTime };
247
+ }
248
+ }
249
+ // ============================================================================
250
+ // Gated Analyzer Agent
251
+ // ============================================================================
252
+ export class GatedAnalyzerAgent extends GatedSubAgent {
253
+ constructor(messageBus, toolBridge, config) {
254
+ super("analyzer", config || {}, messageBus, toolBridge, {
255
+ maxRetries: 3,
256
+ strictMode: true,
257
+ });
258
+ }
259
+ async performTask(task) {
260
+ this.updateStatus("running", "Analyzing code");
261
+ const files = task.context.files;
262
+ const fileContents = files
263
+ .map((f) => `File: ${f.path}\n\n${f.content}`)
264
+ .join("\n\n---\n\n");
265
+ const prompt = `Analyze the following code files for issues, patterns, and improvements:
266
+
267
+ ${fileContents}
268
+
269
+ Please provide:
270
+ 1. Code quality issues
271
+ 2. Security vulnerabilities
272
+ 3. Performance bottlenecks
273
+ 4. Best practice violations
274
+ 5. Complexity metrics
275
+ 6. Maintainability assessment
276
+
277
+ Format as structured JSON.`;
278
+ const response = await this.callModel(prompt);
279
+ if (!response) {
280
+ return this.localAnalysisFallback(files);
281
+ }
282
+ // Parse AI response
283
+ try {
284
+ const analysis = JSON.parse(response);
285
+ return analysis;
286
+ }
287
+ catch {
288
+ return {
289
+ file: task.context.files[0]?.path || "unknown",
290
+ analysis: response,
291
+ issues: [],
292
+ metrics: this.computeFileMetrics(files),
293
+ };
294
+ }
295
+ }
296
+ /**
297
+ * Local fallback: perform real static analysis on provided files.
298
+ * Detects: console.log, TODO/FIXME, 'any' types, deep nesting, long
299
+ * functions, missing error handling, potential hardcoded secrets,
300
+ * unused imports, high cyclomatic complexity.
301
+ */
302
+ localAnalysisFallback(files) {
303
+ const allIssues = [];
304
+ const perFileMetrics = [];
305
+ for (const file of files) {
306
+ const content = file.content || "";
307
+ const lines = content.split("\n");
308
+ const lineCount = lines.length;
309
+ let blankLines = 0;
310
+ let commentLines = 0;
311
+ let importCount = 0;
312
+ let exportCount = 0;
313
+ const functionMatches = content.match(/\b(?:function\s+\w+|(?:const|let|var)\s+\w+\s*=\s*(?:async\s+)?(?:\([^)]*\)|[a-zA-Z_$]\w*)\s*=>|(?:async\s+)?(?:get|set|static\s+)?\w+\s*\([^)]*\)\s*\{)/g) || [];
314
+ const classMatches = content.match(/\bclass\s+\w+/g) || [];
315
+ // Cyclomatic complexity: count decision points
316
+ let cyclomaticComplexity = 1;
317
+ const decisionPattern = /\b(?:if|else\s+if|case|for|while|do|catch|\?\?|&&|\|\||[?]:)/g;
318
+ let decMatch;
319
+ while ((decMatch = decisionPattern.exec(content)) !== null) {
320
+ void decMatch; // suppress noUnusedLocals
321
+ cyclomaticComplexity++;
322
+ }
323
+ // Max nesting depth via brace counting
324
+ let maxNesting = 0;
325
+ let currentNesting = 0;
326
+ for (const ch of content) {
327
+ if (ch === "{") {
328
+ currentNesting++;
329
+ if (currentNesting > maxNesting)
330
+ maxNesting = currentNesting;
331
+ }
332
+ else if (ch === "}") {
333
+ currentNesting = Math.max(0, currentNesting - 1);
334
+ }
335
+ }
336
+ // Longest function length
337
+ let longestFn = 0;
338
+ let fnNesting = 0;
339
+ let fnStartLine = -1;
340
+ for (let i = 0; i < lines.length; i++) {
341
+ const line = lines[i];
342
+ const trimmed = line.trim();
343
+ if (trimmed === "") {
344
+ blankLines++;
345
+ }
346
+ else if (trimmed.startsWith("//") ||
347
+ trimmed.startsWith("/*") ||
348
+ trimmed.startsWith("*")) {
349
+ commentLines++;
350
+ }
351
+ if (/^import\s/.test(trimmed))
352
+ importCount++;
353
+ if (/^export\s/.test(trimmed))
354
+ exportCount++;
355
+ if (/(?:function\s+\w+|=>\s*\{|\)\s*\{)\s*$/.test(trimmed) &&
356
+ fnStartLine === -1) {
357
+ fnStartLine = i;
358
+ fnNesting = 0;
359
+ }
360
+ if (fnStartLine !== -1) {
361
+ for (const ch of line) {
362
+ if (ch === "{")
363
+ fnNesting++;
364
+ if (ch === "}")
365
+ fnNesting--;
366
+ }
367
+ if (fnNesting <= 0 && fnStartLine !== -1) {
368
+ const fnLen = i - fnStartLine + 1;
369
+ if (fnLen > longestFn)
370
+ longestFn = fnLen;
371
+ fnStartLine = -1;
372
+ }
373
+ }
374
+ }
375
+ perFileMetrics.push({
376
+ file: file.path,
377
+ linesOfCode: lineCount,
378
+ blankLines,
379
+ commentLines,
380
+ functions: functionMatches.length,
381
+ classes: classMatches.length,
382
+ imports: importCount,
383
+ exports: exportCount,
384
+ cyclomaticComplexity,
385
+ maxNestingDepth: maxNesting,
386
+ longestFunctionLength: longestFn,
387
+ });
388
+ // --- Issue detection ---
389
+ if (longestFn > 50) {
390
+ allIssues.push({
391
+ type: "maintainability",
392
+ severity: longestFn > 100 ? "high" : "medium",
393
+ file: file.path,
394
+ description: `Longest function is ${longestFn} lines (threshold: 50)`,
395
+ recommendation: "Break large functions into smaller, focused helper functions",
396
+ });
397
+ }
398
+ if (maxNesting > 4) {
399
+ allIssues.push({
400
+ type: "complexity",
401
+ severity: maxNesting > 6 ? "high" : "medium",
402
+ file: file.path,
403
+ description: `Maximum nesting depth is ${maxNesting} levels (threshold: 4)`,
404
+ recommendation: "Use early returns, guard clauses, or extract nested logic into functions",
405
+ });
406
+ }
407
+ if (cyclomaticComplexity > 20) {
408
+ allIssues.push({
409
+ type: "complexity",
410
+ severity: cyclomaticComplexity > 40 ? "high" : "medium",
411
+ file: file.path,
412
+ description: `Cyclomatic complexity is ${cyclomaticComplexity} (threshold: 20)`,
413
+ recommendation: "Simplify control flow; consider strategy pattern or lookup tables",
414
+ });
415
+ }
416
+ // TODO / FIXME scan with line numbers
417
+ for (let i = 0; i < lines.length; i++) {
418
+ const line = lines[i];
419
+ if (/\bTODO\b/i.test(line)) {
420
+ allIssues.push({
421
+ type: "best_practice",
422
+ severity: "low",
423
+ file: file.path,
424
+ line: i + 1,
425
+ description: `TODO comment: ${line.trim().substring(0, 100)}`,
426
+ recommendation: "Address TODO items or create tracking issues",
427
+ });
428
+ }
429
+ if (/\bFIXME\b/i.test(line)) {
430
+ allIssues.push({
431
+ type: "best_practice",
432
+ severity: "medium",
433
+ file: file.path,
434
+ line: i + 1,
435
+ description: `FIXME comment: ${line.trim().substring(0, 100)}`,
436
+ recommendation: "FIXME indicates known bugs — prioritize fixing",
437
+ });
438
+ }
439
+ }
440
+ // console.log / debug statements
441
+ const consoleLogLines = [];
442
+ for (let i = 0; i < lines.length; i++) {
443
+ if (/\bconsole\.(log|debug|info)\b/.test(lines[i]) &&
444
+ !/\/\//.test(lines[i].split("console")[0])) {
445
+ consoleLogLines.push(i + 1);
446
+ }
447
+ }
448
+ if (consoleLogLines.length > 0) {
449
+ allIssues.push({
450
+ type: "best_practice",
451
+ severity: "low",
452
+ file: file.path,
453
+ line: consoleLogLines[0],
454
+ description: `Found ${consoleLogLines.length} console.log/debug/info statement(s) at lines: ${consoleLogLines.slice(0, 5).join(", ")}${consoleLogLines.length > 5 ? "..." : ""}`,
455
+ recommendation: "Remove debug logging or replace with a proper logging framework",
456
+ });
457
+ }
458
+ // Unused imports detection (basic: named imports not used in rest of file)
459
+ const importLines = lines.filter((l) => /^import\s/.test(l.trim()));
460
+ for (const impLine of importLines) {
461
+ const namedImports = impLine.match(/\{\s*([^}]+)\s*\}/);
462
+ if (namedImports) {
463
+ const names = namedImports[1]
464
+ .split(",")
465
+ .map((n) => n
466
+ .trim()
467
+ .split(/\s+as\s+/)
468
+ .pop()
469
+ ?.trim())
470
+ .filter(Boolean);
471
+ for (const name of names) {
472
+ if (!name)
473
+ continue;
474
+ const restOfFile = lines
475
+ .filter((l) => !/^import\s/.test(l.trim()))
476
+ .join("\n");
477
+ const nameRegex = new RegExp(`\\b${name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\b`, "g");
478
+ const usageCount = (restOfFile.match(nameRegex) || []).length;
479
+ if (usageCount === 0) {
480
+ allIssues.push({
481
+ type: "best_practice",
482
+ severity: "low",
483
+ file: file.path,
484
+ description: `Potentially unused import: '${name}'`,
485
+ recommendation: "Remove unused imports to keep the codebase clean",
486
+ });
487
+ }
488
+ }
489
+ }
490
+ }
491
+ // TypeScript 'any' usage
492
+ if (/\.tsx?$/.test(file.path)) {
493
+ const anyMatches = [];
494
+ for (let i = 0; i < lines.length; i++) {
495
+ if (/:\s*any\b|as\s+any\b|<any>/.test(lines[i])) {
496
+ anyMatches.push(i + 1);
497
+ }
498
+ }
499
+ if (anyMatches.length > 0) {
500
+ allIssues.push({
501
+ type: "type_safety",
502
+ severity: anyMatches.length > 5 ? "medium" : "low",
503
+ file: file.path,
504
+ line: anyMatches[0],
505
+ description: `Found ${anyMatches.length} 'any' type usage(s) at lines: ${anyMatches.slice(0, 5).join(", ")}${anyMatches.length > 5 ? "..." : ""}`,
506
+ recommendation: "Replace 'any' with specific types for better type safety",
507
+ });
508
+ }
509
+ }
510
+ // Missing error handling for async functions
511
+ const asyncFnPattern = /\basync\s+(?:function\s+\w+|\w+\s*=\s*async|\([^)]*\)\s*=>)/g;
512
+ const asyncCount = (content.match(asyncFnPattern) || []).length;
513
+ const tryCatchCount = (content.match(/\btry\s*\{/g) || []).length;
514
+ const catchCount = (content.match(/\.catch\s*\(/g) || []).length;
515
+ if (asyncCount > 0 && tryCatchCount + catchCount < asyncCount * 0.5) {
516
+ allIssues.push({
517
+ type: "error_handling",
518
+ severity: "medium",
519
+ file: file.path,
520
+ description: `${asyncCount} async function(s) but only ${tryCatchCount + catchCount} error handler(s) — potential unhandled rejections`,
521
+ recommendation: "Wrap async operations in try/catch or add .catch() handlers",
522
+ });
523
+ }
524
+ // Potential hardcoded secrets
525
+ for (let i = 0; i < lines.length; i++) {
526
+ if (/(?:password|secret|apiKey|api_key|token|AUTH)\s*[:=]\s*["'][^"']{8,}["']/i.test(lines[i])) {
527
+ allIssues.push({
528
+ type: "security",
529
+ severity: "high",
530
+ file: file.path,
531
+ line: i + 1,
532
+ description: "Potential hardcoded secret or credential detected",
533
+ recommendation: "Move secrets to environment variables or a secure vault",
534
+ });
535
+ }
536
+ }
537
+ // Very long lines
538
+ const longLines = lines.filter((l) => l.length > 120).length;
539
+ if (longLines > 10) {
540
+ allIssues.push({
541
+ type: "style",
542
+ severity: "low",
543
+ file: file.path,
544
+ description: `${longLines} lines exceed 120 characters`,
545
+ recommendation: "Consider reformatting for readability (use prettier or similar)",
546
+ });
547
+ }
548
+ }
549
+ // --- Aggregate metrics ---
550
+ const totalLOC = perFileMetrics.reduce((s, m) => s + m.linesOfCode, 0);
551
+ const totalFunctions = perFileMetrics.reduce((s, m) => s + m.functions, 0);
552
+ const totalClasses = perFileMetrics.reduce((s, m) => s + m.classes, 0);
553
+ const avgComplexity = perFileMetrics.length > 0
554
+ ? perFileMetrics.reduce((s, m) => s + m.cyclomaticComplexity, 0) /
555
+ perFileMetrics.length
556
+ : 0;
557
+ const commentRatio = totalLOC > 0
558
+ ? perFileMetrics.reduce((s, m) => s + m.commentLines, 0) / totalLOC
559
+ : 0;
560
+ const avgNesting = perFileMetrics.length > 0
561
+ ? perFileMetrics.reduce((s, m) => s + m.maxNestingDepth, 0) /
562
+ perFileMetrics.length
563
+ : 0;
564
+ const maintainabilityIndex = Math.max(0, Math.min(100, 100 - avgComplexity * 0.5 - avgNesting * 3 + commentRatio * 30));
565
+ const severityOrder = {
566
+ high: 0,
567
+ medium: 1,
568
+ low: 2,
569
+ };
570
+ allIssues.sort((a, b) => (severityOrder[a.severity] ?? 3) - (severityOrder[b.severity] ?? 3));
571
+ return {
572
+ filesAnalyzed: files.map((f) => f.path),
573
+ issues: allIssues,
574
+ metrics: {
575
+ totalLinesOfCode: totalLOC,
576
+ totalFunctions,
577
+ totalClasses,
578
+ averageCyclomaticComplexity: Math.round(avgComplexity * 10) / 10,
579
+ maintainabilityIndex: Math.round(maintainabilityIndex * 10) / 10,
580
+ },
581
+ perFileMetrics,
582
+ summary: {
583
+ totalIssues: allIssues.length,
584
+ highSeverity: allIssues.filter((i) => i.severity === "high").length,
585
+ mediumSeverity: allIssues.filter((i) => i.severity === "medium").length,
586
+ lowSeverity: allIssues.filter((i) => i.severity === "low").length,
587
+ issueTypes: [...new Set(allIssues.map((i) => i.type))],
588
+ },
589
+ note: "Analysis performed via local static analysis (model unavailable)",
590
+ };
591
+ }
592
+ /**
593
+ * Basic file metrics for the JSON-parse fallback path.
594
+ */
595
+ computeFileMetrics(files) {
596
+ const totalLOC = files.reduce((sum, f) => sum + (f.content || "").split("\n").length, 0);
597
+ const totalFunctions = files.reduce((sum, f) => sum + ((f.content || "").match(/\bfunction\s+\w+/g) || []).length, 0);
598
+ const avgLineLength = totalLOC > 0
599
+ ? Math.round(files.reduce((sum, f) => sum + f.content.length, 0) / totalLOC)
600
+ : 0;
601
+ return {
602
+ linesOfCode: totalLOC,
603
+ functions: totalFunctions,
604
+ averageLineLength: avgLineLength,
605
+ };
606
+ }
607
+ }
608
+ // ============================================================================
609
+ // Gated Reviewer Agent
610
+ // ============================================================================
611
+ export class GatedReviewerAgent extends GatedSubAgent {
612
+ constructor(messageBus, toolBridge, config) {
613
+ super("reviewer", config || {}, messageBus, toolBridge, {
614
+ maxRetries: 3,
615
+ strictMode: true,
616
+ });
617
+ }
618
+ async performTask(task) {
619
+ this.updateStatus("running", "Reviewing changes");
620
+ const analysisOutput = task.context.metadata?.analyze_output;
621
+ const prompt = `Review the following code analysis and provide feedback:
622
+
623
+ Analysis: ${JSON.stringify(analysisOutput, null, 2)}
624
+
625
+ Task: ${task.prompt}
626
+
627
+ Please provide:
628
+ 1. Overall assessment
629
+ 2. Fixes reviewed
630
+ 3. Blocking issues (if any)
631
+ 4. Recommendations for improvement
632
+
633
+ Format as structured JSON.`;
634
+ const response = await this.callModel(prompt);
635
+ if (!response) {
636
+ return this.localReviewFallback(task);
637
+ }
638
+ try {
639
+ return JSON.parse(response);
640
+ }
641
+ catch {
642
+ return {
643
+ reviewId: crypto.randomUUID(),
644
+ review: response,
645
+ ...this.localReviewFallback(task),
646
+ };
647
+ }
648
+ }
649
+ /**
650
+ * Local fallback: examine file content for error handling, null safety,
651
+ * TypeScript type coverage, naming hygiene, and hardcoded values.
652
+ * Derives a real approved/rejected decision — never hardcodes "approved".
653
+ */
654
+ localReviewFallback(task) {
655
+ const analysisOutput = task.context.metadata?.analyze_output;
656
+ const files = task.context.files;
657
+ const fixesReviewed = [];
658
+ const blockingIssues = [];
659
+ const recommendations = [];
660
+ let assessmentPoints = 0;
661
+ let maxPoints = 0;
662
+ // --- Review analysis output if present ---
663
+ if (analysisOutput && typeof analysisOutput === "object") {
664
+ const analysis = analysisOutput;
665
+ const issues = analysis.issues || [];
666
+ for (const issue of issues) {
667
+ const severity = issue.severity || "low";
668
+ if (severity === "high" || severity === "critical") {
669
+ blockingIssues.push({
670
+ severity,
671
+ description: issue.description ||
672
+ "High severity issue from analysis",
673
+ file: issue.file,
674
+ });
675
+ }
676
+ }
677
+ if (issues.length > 0) {
678
+ fixesReviewed.push({
679
+ file: "analysis",
680
+ status: blockingIssues.length > 0 ? "needs_attention" : "reviewed",
681
+ notes: `Analysis found ${issues.length} issue(s), ${blockingIssues.length} blocking`,
682
+ });
683
+ }
684
+ }
685
+ // --- Per-file quality checks ---
686
+ for (const file of files) {
687
+ const content = file.content || "";
688
+ const lines = content.split("\n");
689
+ const fileIssues = [];
690
+ maxPoints += 5; // 5 checks per file
691
+ // 1. Error handling
692
+ const hasAsync = /\basync\b/.test(content);
693
+ const hasTryCatch = /\btry\s*\{/.test(content);
694
+ const hasCatch = /\.catch\s*\(/.test(content);
695
+ if (hasAsync && !hasTryCatch && !hasCatch) {
696
+ fileIssues.push("Missing error handling for async operations");
697
+ }
698
+ else {
699
+ assessmentPoints++;
700
+ }
701
+ // 2. TypeScript type safety
702
+ if (/\.tsx?$/.test(file.path)) {
703
+ const anyCount = (content.match(/:\s*any\b|as\s+any\b/g) || []).length;
704
+ if (anyCount > 3) {
705
+ fileIssues.push(`Excessive 'any' types (${anyCount} occurrences) — weakens type safety`);
706
+ }
707
+ else {
708
+ assessmentPoints++;
709
+ }
710
+ }
711
+ else {
712
+ assessmentPoints++;
713
+ }
714
+ // 3. Naming conventions
715
+ const badNames = content.match(/\b(?:const|let|var)\s+(?:[a-z]|_\d)\s*=/g) || [];
716
+ const singleCharVars = badNames.filter((m) => /\s[a-z_]\s*=/.test(m) && !/\b(i|j|k|x|y|z|e|_)\s*=/.test(m));
717
+ if (singleCharVars.length > 3) {
718
+ fileIssues.push("Multiple single-character variable names — use descriptive names");
719
+ }
720
+ else {
721
+ assessmentPoints++;
722
+ }
723
+ // 4. Null/undefined safety
724
+ const nullAccess = (content.match(/\.\w+\.\w+/g) || []).length;
725
+ const optionalChaining = (content.match(/\?\./g) || []).length;
726
+ const nullChecks = (content.match(/!==?\s*(?:null|undefined)|typeof\s+\w+\s*!==?\s*["']undefined["']/g) || []).length;
727
+ if (nullAccess > 10 && optionalChaining === 0 && nullChecks < 2) {
728
+ fileIssues.push("Multiple property chains without null checks — consider optional chaining (?.)");
729
+ }
730
+ else {
731
+ assessmentPoints++;
732
+ }
733
+ // 5. Hardcoded magic numbers
734
+ const hardcoded = [];
735
+ for (let i = 0; i < lines.length; i++) {
736
+ if (/(?:timeout|delay|interval|limit|max|min|size|count|threshold)\s*[:=]\s*\d{3,}/i.test(lines[i])) {
737
+ hardcoded.push(`line ${i + 1}`);
738
+ }
739
+ }
740
+ if (hardcoded.length > 2) {
741
+ fileIssues.push(`${hardcoded.length} hardcoded magic numbers — extract as named constants`);
742
+ }
743
+ else {
744
+ assessmentPoints++;
745
+ }
746
+ if (fileIssues.length > 0) {
747
+ fixesReviewed.push({
748
+ file: file.path,
749
+ status: fileIssues.some((i) => i.includes("error handling") || i.includes("type safety"))
750
+ ? "needs_attention"
751
+ : "minor_issues",
752
+ notes: fileIssues.join("; "),
753
+ });
754
+ for (const issue of fileIssues) {
755
+ recommendations.push(`[${file.path}] ${issue}`);
756
+ }
757
+ }
758
+ else {
759
+ fixesReviewed.push({
760
+ file: file.path,
761
+ status: "passed",
762
+ notes: "No significant quality issues detected",
763
+ });
764
+ }
765
+ }
766
+ // Confidence derived from how many checks passed
767
+ const confidence = maxPoints > 0
768
+ ? Math.round((assessmentPoints / maxPoints) * 100) / 100
769
+ : 0.3;
770
+ // Real overall assessment — not hardcoded
771
+ let overallAssessment;
772
+ if (blockingIssues.length > 0) {
773
+ overallAssessment = `Blocking issues found: ${blockingIssues.length} high/critical issue(s) require attention before proceeding.`;
774
+ }
775
+ else if (recommendations.length > 3) {
776
+ overallAssessment = `Code has ${recommendations.length} quality concerns that should be addressed. Review the recommendations for improvements.`;
777
+ }
778
+ else if (recommendations.length > 0) {
779
+ overallAssessment = `Code is generally acceptable with ${recommendations.length} minor suggestion(s). Consider addressing them in a follow-up.`;
780
+ }
781
+ else if (files.length === 0) {
782
+ overallAssessment =
783
+ "No files provided for review. Unable to perform meaningful analysis.";
784
+ }
785
+ else {
786
+ overallAssessment = `Code passed basic quality checks across ${files.length} file(s). No significant issues detected.`;
787
+ }
788
+ if (files.length > 0) {
789
+ const totalLOC = files.reduce((s, f) => s + (f.content || "").split("\n").length, 0);
790
+ if (totalLOC > 500 && !files.some((f) => /test|spec/i.test(f.path))) {
791
+ recommendations.push("Consider adding unit tests — no test files detected for this codebase");
792
+ }
793
+ }
794
+ return {
795
+ reviewId: crypto.randomUUID(),
796
+ fixesReviewed,
797
+ overallAssessment,
798
+ blockingIssues,
799
+ recommendations,
800
+ confidence,
801
+ qualityScore: maxPoints > 0 ? `${assessmentPoints}/${maxPoints}` : "N/A",
802
+ note: "Review performed via local static analysis (model unavailable)",
803
+ };
804
+ }
805
+ }
806
+ // ============================================================================
807
+ // Gated Rewriter Agent
808
+ // ============================================================================
809
+ export class GatedRewriterAgent extends GatedSubAgent {
810
+ constructor(messageBus, toolBridge, config) {
811
+ super("rewriter", config || {}, messageBus, toolBridge, {
812
+ maxRetries: 3,
813
+ strictMode: true,
814
+ });
815
+ }
816
+ async performTask(task) {
817
+ this.updateStatus("running", "Applying fixes");
818
+ const analysisOutput = task.context.metadata?.analyze_output;
819
+ const reviewOutput = task.context.metadata?.review_output;
820
+ const files = task.context.files;
821
+ const fileContents = files
822
+ .map((f) => `File: ${f.path}\n\n${f.content}`)
823
+ .join("\n\n---\n\n");
824
+ const prompt = `Apply fixes to the following code based on the analysis and review:
825
+
826
+ Analysis: ${JSON.stringify(analysisOutput, null, 2)}
827
+
828
+ Review: ${JSON.stringify(reviewOutput, null, 2)}
829
+
830
+ Task: ${task.prompt}
831
+
832
+ Code Files:
833
+ ${fileContents}
834
+
835
+ Please provide:
836
+ 1. Specific code changes needed
837
+ 2. New files to create (if any)
838
+ 3. Files to delete (if any)
839
+ 4. Explanation of each change
840
+
841
+ Format as structured JSON with file paths as keys and change objects as values.`;
842
+ const response = await this.callModel(prompt);
843
+ if (!response) {
844
+ return this.localRewriteFallback(files);
845
+ }
846
+ try {
847
+ return JSON.parse(response);
848
+ }
849
+ catch {
850
+ return {
851
+ changes: [],
852
+ newFiles: [],
853
+ deletedFiles: [],
854
+ explanation: response,
855
+ };
856
+ }
857
+ }
858
+ /**
859
+ * Local fallback: apply deterministic code improvements without a model.
860
+ * Transformations: trailing whitespace, CRLF→LF, mixed indentation,
861
+ * missing semicolons (JS/TS), alphabetical import sorting, collapsed
862
+ * blank lines, trailing newline. Returns actually-transformed code.
863
+ */
864
+ localRewriteFallback(files) {
865
+ const changes = [];
866
+ for (const file of files) {
867
+ const content = file.content || "";
868
+ if (!content.trim())
869
+ continue;
870
+ const transformations = [];
871
+ let result = content;
872
+ // 1. Remove trailing whitespace
873
+ const beforeTrailing = result;
874
+ result = result.replace(/[ \t]+$/gm, "");
875
+ if (result !== beforeTrailing) {
876
+ transformations.push("Removed trailing whitespace");
877
+ }
878
+ // 2. Normalize CRLF → LF
879
+ if (result.includes("\r\n")) {
880
+ result = result.replace(/\r\n/g, "\n");
881
+ transformations.push("Normalized line endings (CRLF → LF)");
882
+ }
883
+ // 3. Mixed indentation: convert tabs to 2-space when spaces dominate
884
+ const ls = result.split("\n");
885
+ const tabLines = ls.filter((l) => l.startsWith("\t")).length;
886
+ const spaceLines = ls.filter((l) => /^ {2,}/.test(l)).length;
887
+ if (tabLines > 0 && spaceLines > tabLines * 2) {
888
+ result = result.replace(/^\t+/gm, (m) => " ".repeat(m.length));
889
+ transformations.push("Converted tab indentation to 2-space");
890
+ }
891
+ // 4. Add missing semicolons for JS/TS files
892
+ if (/\.[jt]sx?$/.test(file.path)) {
893
+ const resultLines = result.split("\n");
894
+ const semiFixed = resultLines.map((line) => {
895
+ const trimmed = line.trim();
896
+ if (!trimmed ||
897
+ trimmed.endsWith(";") ||
898
+ trimmed.endsWith("{") ||
899
+ trimmed.endsWith("}") ||
900
+ trimmed.endsWith("(") ||
901
+ trimmed.endsWith(",") ||
902
+ trimmed.endsWith("*/") ||
903
+ trimmed.startsWith("//") ||
904
+ trimmed.startsWith("/*") ||
905
+ trimmed.startsWith("*") ||
906
+ trimmed.startsWith("import ") ||
907
+ trimmed.startsWith("export ") ||
908
+ /^(?:if|else|for|while|switch|case|default|try|catch|finally|do|class|interface|type|enum)\b/.test(trimmed) ||
909
+ trimmed.endsWith("=>") ||
910
+ trimmed.endsWith("?") ||
911
+ trimmed.endsWith(":") ||
912
+ trimmed.endsWith("||") ||
913
+ trimmed.endsWith("&&")) {
914
+ return line;
915
+ }
916
+ if (/(?:\)|\]|['"`]|\w)\s*$/.test(trimmed)) {
917
+ if (/^(?:return|throw|const|let|var|yield)\b/.test(trimmed) ||
918
+ /^[\w$]+\s*[+\-*/]?=\s/.test(trimmed) ||
919
+ /^(?:await\s+)?[\w$]+\s*\(/.test(trimmed)) {
920
+ return line.replace(/\s*$/, ";");
921
+ }
922
+ }
923
+ return line;
924
+ });
925
+ const semiResult = semiFixed.join("\n");
926
+ if (semiResult !== result) {
927
+ result = semiResult;
928
+ transformations.push("Added missing semicolons to statement lines");
929
+ }
930
+ }
931
+ // 5. Sort imports alphabetically (JS/TS)
932
+ if (/\.[jt]sx?$/.test(file.path)) {
933
+ const sorted = this.sortImports(result);
934
+ if (sorted !== result) {
935
+ result = sorted;
936
+ transformations.push("Sorted import statements alphabetically");
937
+ }
938
+ }
939
+ // 6. Collapse excessive blank lines (>2 consecutive)
940
+ const beforeBlank = result;
941
+ result = result.replace(/\n{3,}/g, "\n\n");
942
+ if (result !== beforeBlank) {
943
+ transformations.push("Collapsed excessive blank lines");
944
+ }
945
+ // 7. Ensure trailing newline
946
+ if (!result.endsWith("\n")) {
947
+ result += "\n";
948
+ transformations.push("Added trailing newline");
949
+ }
950
+ if (transformations.length > 0) {
951
+ changes.push({
952
+ file: file.path,
953
+ original: content,
954
+ rewritten: result,
955
+ transformations,
956
+ });
957
+ }
958
+ }
959
+ return {
960
+ changes,
961
+ newFiles: [],
962
+ deletedFiles: [],
963
+ summary: changes.length > 0
964
+ ? `Applied basic formatting transformations to ${changes.length} file(s): ${changes.map((c) => c.transformations.join(", ")).join("; ")}`
965
+ : "No transformations needed — files already well-formatted",
966
+ note: "Only basic static code formatting applied (model unavailable for semantic rewrites)",
967
+ };
968
+ }
969
+ /**
970
+ * Sort import statement groups alphabetically by module specifier.
971
+ */
972
+ sortImports(content) {
973
+ const lines = content.split("\n");
974
+ const importGroups = [];
975
+ let groupStart = -1;
976
+ let currentImports = [];
977
+ for (let i = 0; i < lines.length; i++) {
978
+ const trimmed = lines[i].trim();
979
+ if (/^import\s/.test(trimmed)) {
980
+ if (groupStart === -1)
981
+ groupStart = i;
982
+ currentImports.push(lines[i]);
983
+ }
984
+ else {
985
+ if (currentImports.length > 1) {
986
+ importGroups.push({
987
+ start: groupStart,
988
+ end: groupStart + currentImports.length - 1,
989
+ imports: [...currentImports],
990
+ });
991
+ }
992
+ groupStart = -1;
993
+ currentImports = [];
994
+ }
995
+ }
996
+ if (currentImports.length > 1) {
997
+ importGroups.push({
998
+ start: groupStart,
999
+ end: groupStart + currentImports.length - 1,
1000
+ imports: [...currentImports],
1001
+ });
1002
+ }
1003
+ if (importGroups.length === 0)
1004
+ return content;
1005
+ const resultLines = [...lines];
1006
+ let changed = false;
1007
+ for (const group of importGroups) {
1008
+ const sorted = [...group.imports].sort((a, b) => {
1009
+ const srcA = (a.match(/from\s+["']([^"']+)["']/) || [])[1] || a;
1010
+ const srcB = (b.match(/from\s+["']([^"']+)["']/) || [])[1] || b;
1011
+ return srcA.localeCompare(srcB);
1012
+ });
1013
+ const alreadySorted = sorted.every((line, idx) => line === group.imports[idx]);
1014
+ if (!alreadySorted) {
1015
+ for (let i = 0; i < sorted.length; i++) {
1016
+ resultLines[group.start + i] = sorted[i];
1017
+ }
1018
+ changed = true;
1019
+ }
1020
+ }
1021
+ return changed ? resultLines.join("\n") : content;
1022
+ }
1023
+ }
1024
+ // ============================================================================
1025
+ // Gated UI Designer Agent
1026
+ // ============================================================================
1027
+ export class GatedUiDesignerAgent extends GatedSubAgent {
1028
+ constructor(messageBus, toolBridge, config) {
1029
+ super("ui_designer", config || {}, messageBus, toolBridge, {
1030
+ maxRetries: 3,
1031
+ strictMode: false,
1032
+ });
1033
+ }
1034
+ async performTask(task) {
1035
+ this.updateStatus("running", "Generating UI mockups");
1036
+ const files = task.context.files;
1037
+ const uiFiles = files.filter((f) => f.content.includes("div") ||
1038
+ f.content.includes("button") ||
1039
+ f.content.includes("<") ||
1040
+ /\.(tsx?|jsx?|html|svelte|vue)$/.test(f.path));
1041
+ if (uiFiles.length === 0) {
1042
+ return this.localUiDesignFallback([], task);
1043
+ }
1044
+ const uiContent = uiFiles
1045
+ .map((f) => `File: ${f.path}\n\n${f.content}`)
1046
+ .join("\n\n---\n\n");
1047
+ const prompt = `Design UI improvements for the following code:
1048
+
1049
+ ${uiContent}
1050
+
1051
+ Task: ${task.prompt}
1052
+
1053
+ Please provide:
1054
+ 1. Detected UI frameworks
1055
+ 2. ASCII mockups for new UI components
1056
+ 3. Accessibility issues
1057
+ 4. Design suggestions
1058
+
1059
+ Format as structured JSON.`;
1060
+ const response = await this.callModel(prompt);
1061
+ if (!response) {
1062
+ return this.localUiDesignFallback(uiFiles, task);
1063
+ }
1064
+ try {
1065
+ return JSON.parse(response);
1066
+ }
1067
+ catch {
1068
+ return {
1069
+ detectedFrameworks: this.detectFrameworks(uiFiles),
1070
+ mockups: [
1071
+ {
1072
+ type: "ascii",
1073
+ content: response,
1074
+ viewport: "desktop",
1075
+ },
1076
+ ],
1077
+ accessibilityIssues: this.detectA11yIssues(uiFiles),
1078
+ designSuggestions: [],
1079
+ };
1080
+ }
1081
+ }
1082
+ /**
1083
+ * Local fallback: parse the task prompt for UI component keywords,
1084
+ * detect the framework from file content, scan for ARIA/accessibility
1085
+ * issues, and return a real semantic HTML or React component scaffold
1086
+ * with an ASCII mockup. Never returns placeholder strings.
1087
+ */
1088
+ localUiDesignFallback(uiFiles, task) {
1089
+ const prompt = task.prompt || "";
1090
+ const lower = prompt.toLowerCase();
1091
+ const frameworks = this.detectFrameworks(uiFiles);
1092
+ // Map task keywords to component types
1093
+ const uiKeywords = {
1094
+ form: [
1095
+ "form",
1096
+ "input",
1097
+ "submit",
1098
+ "field",
1099
+ "validation",
1100
+ "textarea",
1101
+ "select",
1102
+ ],
1103
+ button: ["button", "btn", "click", "action", "cta"],
1104
+ layout: [
1105
+ "layout",
1106
+ "grid",
1107
+ "flex",
1108
+ "container",
1109
+ "wrapper",
1110
+ "sidebar",
1111
+ "header",
1112
+ "footer",
1113
+ ],
1114
+ page: ["page", "view", "screen", "route", "dashboard"],
1115
+ modal: ["modal", "dialog", "popup", "overlay"],
1116
+ list: ["list", "table", "grid", "card", "item", "row"],
1117
+ nav: ["nav", "navigation", "menu", "breadcrumb", "tab", "sidebar"],
1118
+ };
1119
+ const detectedTypes = [];
1120
+ for (const [type, keywords] of Object.entries(uiKeywords)) {
1121
+ if (keywords.some((kw) => lower.includes(kw))) {
1122
+ detectedTypes.push(type);
1123
+ }
1124
+ }
1125
+ if (detectedTypes.length === 0)
1126
+ detectedTypes.push("component");
1127
+ const accessibilityIssues = this.detectA11yIssues(uiFiles);
1128
+ const primaryType = detectedTypes[0];
1129
+ const componentName = this.inferComponentName(prompt);
1130
+ const isReact = frameworks.includes("react") || frameworks.includes("next.js");
1131
+ let componentCode;
1132
+ let asciiMockup;
1133
+ switch (primaryType) {
1134
+ case "form":
1135
+ asciiMockup = [
1136
+ `+${"─".repeat(40)}+`,
1137
+ `│ ${componentName.padEnd(38)}│`,
1138
+ `│${"─".repeat(40)}│`,
1139
+ `│ Label: │`,
1140
+ `│ ┌──────────────────────────────────┐ │`,
1141
+ `│ │ Input field │ │`,
1142
+ `│ └──────────────────────────────────┘ │`,
1143
+ `│ Label: │`,
1144
+ `│ ┌──────────────────────────────────┐ │`,
1145
+ `│ │ Input field │ │`,
1146
+ `│ └──────────────────────────────────┘ │`,
1147
+ `│ │`,
1148
+ `│ ┌──────────────────────┐ │`,
1149
+ `│ │ Submit │ │`,
1150
+ `│ └──────────────────────┘ │`,
1151
+ `+${"─".repeat(40)}+`,
1152
+ ].join("\n");
1153
+ componentCode = isReact
1154
+ ? this.generateReactForm(componentName)
1155
+ : this.generateHtmlForm(componentName);
1156
+ break;
1157
+ case "modal":
1158
+ asciiMockup = [
1159
+ ` ┌${"─".repeat(36)}┐`,
1160
+ ` │ ${componentName.padEnd(30)} [X] │`,
1161
+ ` │${"─".repeat(36)}│`,
1162
+ ` │ │`,
1163
+ ` │ Content area │`,
1164
+ ` │ │`,
1165
+ ` │${"─".repeat(36)}│`,
1166
+ ` │ [Cancel] [Confirm] │`,
1167
+ ` └${"─".repeat(36)}┘`,
1168
+ ].join("\n");
1169
+ componentCode = isReact
1170
+ ? this.generateReactModal(componentName)
1171
+ : this.generateHtmlModal(componentName);
1172
+ break;
1173
+ case "nav":
1174
+ asciiMockup = [
1175
+ `+${"─".repeat(50)}+`,
1176
+ `│ Logo │ Home │ About │ Contact │ ☰ │`,
1177
+ `+${"─".repeat(50)}+`,
1178
+ ].join("\n");
1179
+ componentCode = isReact
1180
+ ? this.generateReactNav(componentName)
1181
+ : `<nav role="navigation" aria-label="Main navigation">\n <ul>\n <li><a href="/">Home</a></li>\n <li><a href="/about">About</a></li>\n <li><a href="/contact">Contact</a></li>\n </ul>\n</nav>`;
1182
+ break;
1183
+ case "list":
1184
+ asciiMockup = [
1185
+ `+${"─".repeat(42)}+`,
1186
+ `│ ${componentName.padEnd(40)}│`,
1187
+ `│${"─".repeat(42)}│`,
1188
+ `│ ┌──────────────────────────────────┐ │`,
1189
+ `│ │ Item 1 [Action] │ │`,
1190
+ `│ ├──────────────────────────────────┤ │`,
1191
+ `│ │ Item 2 [Action] │ │`,
1192
+ `│ ├──────────────────────────────────┤ │`,
1193
+ `│ │ Item 3 [Action] │ │`,
1194
+ `│ └──────────────────────────────────┘ │`,
1195
+ `+${"─".repeat(42)}+`,
1196
+ ].join("\n");
1197
+ componentCode = isReact
1198
+ ? this.generateReactList(componentName)
1199
+ : `<section aria-label="${componentName}">\n <h2>${componentName}</h2>\n <ul role="list">\n <li role="listitem">Item 1</li>\n <li role="listitem">Item 2</li>\n </ul>\n</section>`;
1200
+ break;
1201
+ default: // generic component / page / layout / button
1202
+ asciiMockup = [
1203
+ `+${"─".repeat(44)}+`,
1204
+ `│ ${componentName.padEnd(42)}│`,
1205
+ `│${"─".repeat(44)}│`,
1206
+ `│ │`,
1207
+ `│ ┌────────────────────────────────────────┐│`,
1208
+ `│ │ ││`,
1209
+ `│ │ Main Content Area ││`,
1210
+ `│ │ ││`,
1211
+ `│ └────────────────────────────────────────┘│`,
1212
+ `│ │`,
1213
+ `│ [Primary Action] [Secondary Action] │`,
1214
+ `+${"─".repeat(44)}+`,
1215
+ ].join("\n");
1216
+ componentCode = isReact
1217
+ ? this.generateReactComponent(componentName)
1218
+ : `<section aria-label="${componentName}">\n <h2>${componentName}</h2>\n <div class="content">\n <p>Main content area</p>\n </div>\n <div class="actions">\n <button type="button">Primary Action</button>\n </div>\n</section>`;
1219
+ }
1220
+ // Design suggestions based on what's missing in the existing files
1221
+ const designSuggestions = [];
1222
+ if (!uiFiles.some((f) => f.content.includes("@media") || f.content.includes("responsive"))) {
1223
+ designSuggestions.push("Add responsive breakpoints for mobile/tablet viewports");
1224
+ }
1225
+ if (!uiFiles.some((f) => f.content.includes("dark") || f.content.includes("theme"))) {
1226
+ designSuggestions.push("Consider implementing dark mode / theme support");
1227
+ }
1228
+ if (!uiFiles.some((f) => /loading|spinner|skeleton/i.test(f.content))) {
1229
+ designSuggestions.push("Add loading states (skeleton screens or spinners) for async content");
1230
+ }
1231
+ if (!uiFiles.some((f) => /error|fallback/i.test(f.content))) {
1232
+ designSuggestions.push("Add error boundary and fallback UI for graceful error handling");
1233
+ }
1234
+ designSuggestions.push("Ensure consistent spacing and typography using design tokens");
1235
+ return {
1236
+ detectedFrameworks: frameworks,
1237
+ detectedComponentTypes: detectedTypes,
1238
+ mockups: [
1239
+ {
1240
+ type: "ascii",
1241
+ content: asciiMockup,
1242
+ viewport: "desktop",
1243
+ componentName,
1244
+ },
1245
+ ],
1246
+ generatedComponent: {
1247
+ name: componentName,
1248
+ code: componentCode,
1249
+ framework: isReact ? "React/TSX" : "HTML",
1250
+ },
1251
+ accessibilityIssues,
1252
+ designSuggestions,
1253
+ note: "UI design generated via local keyword analysis (model unavailable)",
1254
+ };
1255
+ }
1256
+ /** Detect UI frameworks from file content. */
1257
+ detectFrameworks(files) {
1258
+ const frameworks = new Set();
1259
+ for (const file of files) {
1260
+ const c = file.content || "";
1261
+ if (/\bimport\s.*from\s+["']react["']|React\.createElement|jsx/i.test(c))
1262
+ frameworks.add("react");
1263
+ if (/\bimport\s.*from\s+["']next/i.test(c) ||
1264
+ /\bgetServerSideProps|getStaticProps\b/.test(c))
1265
+ frameworks.add("next.js");
1266
+ if (/\bimport\s.*from\s+["']vue["']|createApp|defineComponent/.test(c))
1267
+ frameworks.add("vue");
1268
+ if (/\bimport\s.*from\s+["']svelte["']|<script\s+lang=["']ts["']/.test(c) &&
1269
+ file.path.endsWith(".svelte"))
1270
+ frameworks.add("svelte");
1271
+ if (/tailwind|className=["'][^"']*(?:flex|grid|p-|m-|text-)/.test(c))
1272
+ frameworks.add("tailwind");
1273
+ if (/\bimport\s.*from\s+["']@radix-ui/.test(c))
1274
+ frameworks.add("radix-ui");
1275
+ if (/\bimport\s.*from\s+["']@shadcn/.test(c) ||
1276
+ /\bimport\s.*from\s+["']@\/components\/ui/.test(c))
1277
+ frameworks.add("shadcn/ui");
1278
+ if (/<html|<body|<head/i.test(c))
1279
+ frameworks.add("html");
1280
+ }
1281
+ return [...frameworks];
1282
+ }
1283
+ /** Detect accessibility issues in UI files. */
1284
+ detectA11yIssues(files) {
1285
+ const issues = [];
1286
+ for (const file of files) {
1287
+ const c = file.content || "";
1288
+ if (/<img\b(?![^>]*\balt\b)/i.test(c)) {
1289
+ issues.push({
1290
+ file: file.path,
1291
+ issue: "Image element missing 'alt' attribute",
1292
+ severity: "high",
1293
+ });
1294
+ }
1295
+ if (/<button[^>]*>\s*<(?:img|svg|icon)/i.test(c) &&
1296
+ !/<button[^>]*aria-label/i.test(c)) {
1297
+ issues.push({
1298
+ file: file.path,
1299
+ issue: "Icon-only button missing aria-label",
1300
+ severity: "high",
1301
+ });
1302
+ }
1303
+ if (/\bonClick\b.*<(?:div|span|p)\b/i.test(c) &&
1304
+ !/role=["']button["']/i.test(c)) {
1305
+ issues.push({
1306
+ file: file.path,
1307
+ issue: "Click handler on non-interactive element without role='button'",
1308
+ severity: "medium",
1309
+ });
1310
+ }
1311
+ if (/<input\b(?![^>]*aria-label)(?![^>]*id=["'](\w+)["'])/i.test(c)) {
1312
+ issues.push({
1313
+ file: file.path,
1314
+ issue: "Form input potentially missing associated label",
1315
+ severity: "medium",
1316
+ });
1317
+ }
1318
+ if (/<html\b(?![^>]*\blang\b)/i.test(c)) {
1319
+ issues.push({
1320
+ file: file.path,
1321
+ issue: "HTML element missing 'lang' attribute",
1322
+ severity: "medium",
1323
+ });
1324
+ }
1325
+ if (/color:\s*#(?:eee|ddd|ccc|fff|fafafa)/i.test(c)) {
1326
+ issues.push({
1327
+ file: file.path,
1328
+ issue: "Potentially low color contrast text detected",
1329
+ severity: "low",
1330
+ });
1331
+ }
1332
+ }
1333
+ return issues;
1334
+ }
1335
+ /** Infer a PascalCase component name from the task prompt. */
1336
+ inferComponentName(prompt) {
1337
+ const match = prompt.match(/(?:create|build|generate|design|add)\s+(?:a\s+)?(\w[\w\s]{1,30}?)(?:\s+(?:component|page|form|modal|dialog|view|section|panel|widget))?$/i);
1338
+ if (match) {
1339
+ return match[1]
1340
+ .trim()
1341
+ .split(/\s+/)
1342
+ .map((w) => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase())
1343
+ .join("");
1344
+ }
1345
+ return "Component";
1346
+ }
1347
+ generateReactForm(name) {
1348
+ return `import React, { FormEvent, useState } from "react";
1349
+
1350
+ interface ${name}Props {
1351
+ onSubmit?: (data: Record<string, string>) => void;
1352
+ }
1353
+
1354
+ export function ${name}({ onSubmit }: ${name}Props) {
1355
+ const [formData, setFormData] = useState<Record<string, string>>({});
1356
+
1357
+ const handleSubmit = (e: FormEvent) => {
1358
+ e.preventDefault();
1359
+ onSubmit?.(formData);
1360
+ };
1361
+
1362
+ return (
1363
+ <form onSubmit={handleSubmit} role="form" aria-label="${name}">
1364
+ <fieldset>
1365
+ <legend>${name}</legend>
1366
+ <div>
1367
+ <label htmlFor="${name.toLowerCase()}-field-1">Field 1</label>
1368
+ <input
1369
+ id="${name.toLowerCase()}-field-1"
1370
+ type="text"
1371
+ required
1372
+ aria-required="true"
1373
+ onChange={(e) => setFormData(prev => ({ ...prev, field1: e.target.value }))}
1374
+ />
1375
+ </div>
1376
+ <div>
1377
+ <label htmlFor="${name.toLowerCase()}-field-2">Field 2</label>
1378
+ <input
1379
+ id="${name.toLowerCase()}-field-2"
1380
+ type="text"
1381
+ onChange={(e) => setFormData(prev => ({ ...prev, field2: e.target.value }))}
1382
+ />
1383
+ </div>
1384
+ <button type="submit">Submit</button>
1385
+ </fieldset>
1386
+ </form>
1387
+ );
1388
+ }`;
1389
+ }
1390
+ generateHtmlForm(name) {
1391
+ return `<form role="form" aria-label="${name}">
1392
+ <fieldset>
1393
+ <legend>${name}</legend>
1394
+ <div>
1395
+ <label for="${name.toLowerCase()}-field-1">Field 1</label>
1396
+ <input id="${name.toLowerCase()}-field-1" type="text" required aria-required="true" />
1397
+ </div>
1398
+ <div>
1399
+ <label for="${name.toLowerCase()}-field-2">Field 2</label>
1400
+ <input id="${name.toLowerCase()}-field-2" type="text" />
1401
+ </div>
1402
+ <button type="submit">Submit</button>
1403
+ </fieldset>
1404
+ </form>`;
1405
+ }
1406
+ generateReactModal(name) {
1407
+ return `import React, { useEffect, useRef } from "react";
1408
+
1409
+ interface ${name}Props {
1410
+ isOpen: boolean;
1411
+ onClose: () => void;
1412
+ title: string;
1413
+ children: React.ReactNode;
1414
+ }
1415
+
1416
+ export function ${name}({ isOpen, onClose, title, children }: ${name}Props) {
1417
+ const dialogRef = useRef<HTMLDialogElement>(null);
1418
+
1419
+ useEffect(() => {
1420
+ if (isOpen) {
1421
+ dialogRef.current?.showModal();
1422
+ } else {
1423
+ dialogRef.current?.close();
1424
+ }
1425
+ }, [isOpen]);
1426
+
1427
+ return (
1428
+ <dialog
1429
+ ref={dialogRef}
1430
+ role="dialog"
1431
+ aria-modal="true"
1432
+ aria-label={title}
1433
+ onClose={onClose}
1434
+ >
1435
+ <header>
1436
+ <h2>{title}</h2>
1437
+ <button type="button" onClick={onClose} aria-label="Close dialog">✕</button>
1438
+ </header>
1439
+ <div role="document">{children}</div>
1440
+ <footer>
1441
+ <button type="button" onClick={onClose}>Cancel</button>
1442
+ <button type="button">Confirm</button>
1443
+ </footer>
1444
+ </dialog>
1445
+ );
1446
+ }`;
1447
+ }
1448
+ generateHtmlModal(name) {
1449
+ return `<dialog role="dialog" aria-modal="true" aria-label="${name}">
1450
+ <header>
1451
+ <h2>${name}</h2>
1452
+ <button type="button" aria-label="Close dialog">✕</button>
1453
+ </header>
1454
+ <div role="document">
1455
+ <p>Modal content goes here</p>
1456
+ </div>
1457
+ <footer>
1458
+ <button type="button">Cancel</button>
1459
+ <button type="button">Confirm</button>
1460
+ </footer>
1461
+ </dialog>`;
1462
+ }
1463
+ generateReactNav(name) {
1464
+ return `import React from "react";
1465
+
1466
+ interface NavItem {
1467
+ label: string;
1468
+ href: string;
1469
+ active?: boolean;
1470
+ }
1471
+
1472
+ interface ${name}Props {
1473
+ items: NavItem[];
1474
+ logo?: React.ReactNode;
1475
+ }
1476
+
1477
+ export function ${name}({ items, logo }: ${name}Props) {
1478
+ return (
1479
+ <nav role="navigation" aria-label="Main navigation">
1480
+ {logo && <div aria-hidden="true">{logo}</div>}
1481
+ <ul role="menubar">
1482
+ {items.map((item) => (
1483
+ <li key={item.href} role="none">
1484
+ <a
1485
+ href={item.href}
1486
+ role="menuitem"
1487
+ aria-current={item.active ? "page" : undefined}
1488
+ >
1489
+ {item.label}
1490
+ </a>
1491
+ </li>
1492
+ ))}
1493
+ </ul>
1494
+ </nav>
1495
+ );
1496
+ }`;
1497
+ }
1498
+ generateReactList(name) {
1499
+ return `import React from "react";
1500
+
1501
+ interface ListItem {
1502
+ id: string;
1503
+ title: string;
1504
+ description?: string;
1505
+ }
1506
+
1507
+ interface ${name}Props {
1508
+ items: ListItem[];
1509
+ onAction?: (id: string) => void;
1510
+ emptyMessage?: string;
1511
+ }
1512
+
1513
+ export function ${name}({ items, onAction, emptyMessage = "No items found" }: ${name}Props) {
1514
+ if (items.length === 0) {
1515
+ return (
1516
+ <section aria-label="${name}">
1517
+ <p role="status">{emptyMessage}</p>
1518
+ </section>
1519
+ );
1520
+ }
1521
+
1522
+ return (
1523
+ <section aria-label="${name}">
1524
+ <h2>${name}</h2>
1525
+ <ul role="list">
1526
+ {items.map((item) => (
1527
+ <li key={item.id} role="listitem">
1528
+ <div>
1529
+ <h3>{item.title}</h3>
1530
+ {item.description && <p>{item.description}</p>}
1531
+ </div>
1532
+ {onAction && (
1533
+ <button
1534
+ type="button"
1535
+ onClick={() => onAction(item.id)}
1536
+ aria-label={\`Action for \${item.title}\`}
1537
+ >
1538
+ Action
1539
+ </button>
1540
+ )}
1541
+ </li>
1542
+ ))}
1543
+ </ul>
1544
+ </section>
1545
+ );
1546
+ }`;
1547
+ }
1548
+ generateReactComponent(name) {
1549
+ return `import React from "react";
1550
+
1551
+ interface ${name}Props {
1552
+ title?: string;
1553
+ children?: React.ReactNode;
1554
+ }
1555
+
1556
+ export function ${name}({ title = "${name}", children }: ${name}Props) {
1557
+ return (
1558
+ <section aria-label={title}>
1559
+ <header>
1560
+ <h2>{title}</h2>
1561
+ </header>
1562
+ <div role="region" aria-label="Content">
1563
+ {children || <p>Main content area</p>}
1564
+ </div>
1565
+ <footer>
1566
+ <button type="button">Primary Action</button>
1567
+ </footer>
1568
+ </section>
1569
+ );
1570
+ }`;
1571
+ }
1572
+ }
1573
+ // ============================================================================
1574
+ // Gated Researcher Agent
1575
+ // ============================================================================
1576
+ export class GatedResearcherAgent extends GatedSubAgent {
1577
+ constructor(messageBus, toolBridge, config) {
1578
+ super("researcher", config || {}, messageBus, toolBridge, {
1579
+ maxRetries: 3,
1580
+ strictMode: false,
1581
+ });
1582
+ }
1583
+ async performTask(task) {
1584
+ this.updateStatus("running", "Researching information");
1585
+ const query = task.prompt;
1586
+ let webResult = null;
1587
+ try {
1588
+ webResult = await this.webSearch(query, 3);
1589
+ }
1590
+ catch (error) {
1591
+ console.warn(`Web search failed for query "${query}": ${error}`);
1592
+ }
1593
+ if (webResult) {
1594
+ const analysisPrompt = `Analyze the following web search results for the query "${query}":
1595
+
1596
+ ${webResult}
1597
+
1598
+ Please extract:
1599
+ 1. Key findings
1600
+ 2. Verified facts
1601
+ 3. Relevant sources
1602
+ 4. Summary
1603
+
1604
+ Format as structured JSON.`;
1605
+ const analysisResponse = await this.callModel(analysisPrompt);
1606
+ if (analysisResponse) {
1607
+ try {
1608
+ return JSON.parse(analysisResponse);
1609
+ }
1610
+ catch {
1611
+ // Fall through to local fallback with web results included
1612
+ }
1613
+ }
1614
+ }
1615
+ return this.localResearchFallback(query, webResult, task);
1616
+ }
1617
+ /**
1618
+ * Local fallback: extract key terms from the query, scan context files
1619
+ * for those terms, identify technical concepts by category, and return
1620
+ * real findings with file paths, matched topics, and surrounding snippets.
1621
+ * Makes clear that model-assisted deep research was unavailable.
1622
+ */
1623
+ localResearchFallback(query, webResult, task) {
1624
+ // --- Extract key topics, filtering stop words ---
1625
+ const stopWords = new Set([
1626
+ "the",
1627
+ "a",
1628
+ "an",
1629
+ "and",
1630
+ "or",
1631
+ "but",
1632
+ "in",
1633
+ "on",
1634
+ "at",
1635
+ "to",
1636
+ "for",
1637
+ "of",
1638
+ "with",
1639
+ "by",
1640
+ "from",
1641
+ "is",
1642
+ "are",
1643
+ "was",
1644
+ "were",
1645
+ "be",
1646
+ "been",
1647
+ "being",
1648
+ "have",
1649
+ "has",
1650
+ "had",
1651
+ "do",
1652
+ "does",
1653
+ "did",
1654
+ "will",
1655
+ "would",
1656
+ "could",
1657
+ "should",
1658
+ "may",
1659
+ "might",
1660
+ "must",
1661
+ "can",
1662
+ "this",
1663
+ "that",
1664
+ "these",
1665
+ "those",
1666
+ "what",
1667
+ "how",
1668
+ "why",
1669
+ "when",
1670
+ "where",
1671
+ "which",
1672
+ "who",
1673
+ "about",
1674
+ "into",
1675
+ "through",
1676
+ "during",
1677
+ "before",
1678
+ "after",
1679
+ "it",
1680
+ "its",
1681
+ "my",
1682
+ "your",
1683
+ "we",
1684
+ "they",
1685
+ "them",
1686
+ "our",
1687
+ "not",
1688
+ "no",
1689
+ "if",
1690
+ ]);
1691
+ const words = query
1692
+ .split(/\W+/)
1693
+ .filter((w) => w.length > 2 && !stopWords.has(w.toLowerCase()));
1694
+ const topics = [...new Set(words.map((w) => w.toLowerCase()))];
1695
+ // --- Identify technical concept categories ---
1696
+ const technicalPatterns = {
1697
+ programming_language: /\b(typescript|javascript|python|rust|go|java|c\+\+|ruby|php|swift|kotlin)\b/i,
1698
+ framework: /\b(react|next\.?js|vue|angular|svelte|express|fastify|django|flask|spring)\b/i,
1699
+ tool: /\b(webpack|vite|esbuild|rollup|babel|eslint|prettier|jest|vitest|docker|kubernetes)\b/i,
1700
+ concept: /\b(api|rest|graphql|websocket|auth|oauth|jwt|database|sql|nosql|cache|queue|cicd|devops)\b/i,
1701
+ pattern: /\b(singleton|factory|observer|strategy|decorator|middleware|hook|context|provider|reducer)\b/i,
1702
+ };
1703
+ const identifiedConcepts = {};
1704
+ for (const [category, pattern] of Object.entries(technicalPatterns)) {
1705
+ const matches = query.match(pattern);
1706
+ if (matches) {
1707
+ identifiedConcepts[category] = [
1708
+ ...new Set(matches.map((m) => m.toLowerCase())),
1709
+ ];
1710
+ }
1711
+ }
1712
+ // --- Scan local context files for topic matches ---
1713
+ const localFindings = [];
1714
+ const contextFiles = task.context.files;
1715
+ for (const file of contextFiles) {
1716
+ const content = (file.content || "").toLowerCase();
1717
+ const matchedTopics = topics.filter((topic) => content.includes(topic));
1718
+ if (matchedTopics.length > 0) {
1719
+ const matchRatio = matchedTopics.length / Math.max(topics.length, 1);
1720
+ const relevance = matchRatio > 0.5 ? "high" : matchRatio > 0.2 ? "medium" : "low";
1721
+ const snippet = this.extractRelevantSnippet(file.content || "", matchedTopics);
1722
+ localFindings.push({
1723
+ file: file.path,
1724
+ relevance,
1725
+ matchedTopics,
1726
+ snippet,
1727
+ });
1728
+ }
1729
+ }
1730
+ // Sort by relevance
1731
+ const relevanceOrder = {
1732
+ high: 0,
1733
+ medium: 1,
1734
+ low: 2,
1735
+ };
1736
+ localFindings.sort((a, b) => (relevanceOrder[a.relevance] ?? 3) - (relevanceOrder[b.relevance] ?? 3));
1737
+ // --- Build results array ---
1738
+ const results = [];
1739
+ if (webResult) {
1740
+ results.push({
1741
+ title: "Web Search Results",
1742
+ url: "",
1743
+ snippet: webResult.substring(0, 500),
1744
+ relevance: 0.7,
1745
+ source: "web_search",
1746
+ });
1747
+ }
1748
+ for (const finding of localFindings.slice(0, 10)) {
1749
+ results.push({
1750
+ title: `Local: ${finding.file}`,
1751
+ url: finding.file,
1752
+ snippet: finding.snippet,
1753
+ relevance: finding.relevance === "high"
1754
+ ? 0.9
1755
+ : finding.relevance === "medium"
1756
+ ? 0.6
1757
+ : 0.3,
1758
+ source: "local_file",
1759
+ });
1760
+ }
1761
+ // --- Key findings ---
1762
+ const keyFindings = [];
1763
+ if (localFindings.length > 0) {
1764
+ keyFindings.push(`Found ${localFindings.length} relevant local file(s) matching query topics`);
1765
+ const highRelevance = localFindings.filter((f) => f.relevance === "high");
1766
+ if (highRelevance.length > 0) {
1767
+ keyFindings.push(`High relevance files: ${highRelevance.map((f) => f.file).join(", ")}`);
1768
+ }
1769
+ }
1770
+ for (const [category, concepts] of Object.entries(identifiedConcepts)) {
1771
+ keyFindings.push(`Identified ${category}: ${concepts.join(", ")}`);
1772
+ }
1773
+ if (webResult) {
1774
+ keyFindings.push("Web search results retrieved but model-assisted analysis was unavailable");
1775
+ }
1776
+ if (keyFindings.length === 0) {
1777
+ keyFindings.push("No matching content found in local project files");
1778
+ keyFindings.push("External research requires a model connection for deeper analysis");
1779
+ }
1780
+ return {
1781
+ query,
1782
+ topics,
1783
+ identifiedConcepts,
1784
+ results,
1785
+ localFindings: localFindings.map((f) => ({
1786
+ file: f.file,
1787
+ relevance: f.relevance,
1788
+ matchedTopics: f.matchedTopics,
1789
+ })),
1790
+ keyFindings,
1791
+ verifiedFacts: [],
1792
+ limitations: [
1793
+ webResult
1794
+ ? "Web results retrieved but could not be analyzed without a model"
1795
+ : "Web search unavailable — results limited to local file scanning",
1796
+ "Deep semantic analysis requires model availability",
1797
+ ],
1798
+ note: "Research performed via local keyword matching and project file scanning (model unavailable)",
1799
+ };
1800
+ }
1801
+ /**
1802
+ * Extract a representative code snippet around the first topic match.
1803
+ */
1804
+ extractRelevantSnippet(content, topics) {
1805
+ const lines = content.split("\n");
1806
+ for (let i = 0; i < lines.length; i++) {
1807
+ const lower = lines[i].toLowerCase();
1808
+ if (topics.some((t) => lower.includes(t))) {
1809
+ const start = Math.max(0, i - 2);
1810
+ const end = Math.min(lines.length, i + 3);
1811
+ return lines.slice(start, end).join("\n").substring(0, 300);
1812
+ }
1813
+ }
1814
+ return content.substring(0, 200);
1815
+ }
1816
+ }
1817
+ export function createGatedSubAgent(type, messageBus, toolBridge, config) {
1818
+ switch (type) {
1819
+ case "planner":
1820
+ return new GatedPlannerAgent(messageBus, toolBridge, config);
1821
+ case "analyzer":
1822
+ return new GatedAnalyzerAgent(messageBus, toolBridge, config);
1823
+ case "reviewer":
1824
+ return new GatedReviewerAgent(messageBus, toolBridge, config);
1825
+ case "rewriter":
1826
+ return new GatedRewriterAgent(messageBus, toolBridge, config);
1827
+ case "ui_designer":
1828
+ return new GatedUiDesignerAgent(messageBus, toolBridge, config);
1829
+ case "researcher":
1830
+ return new GatedResearcherAgent(messageBus, toolBridge, config);
1831
+ case "verifier":
1832
+ return new GatedVerifierAgent(messageBus, toolBridge, config);
1833
+ case "strategist":
1834
+ return new GatedStrategistAgent(messageBus, toolBridge, config);
1835
+ case "diff_validator":
1836
+ return new GatedDiffValidatorAgent(messageBus, toolBridge, config);
1837
+ case "debugger":
1838
+ return new GatedDebuggerAgent(messageBus, toolBridge, config);
1839
+ case "test_runner":
1840
+ return new GatedTestRunnerAgent(messageBus, toolBridge, config);
1841
+ default:
1842
+ throw new Error(`Unknown gated subagent type: ${type}`);
1843
+ }
1844
+ }
1845
+ // ============================================================================
1846
+ // Gated Verifier Agent (Synapse v4 Verification)
1847
+ // ============================================================================
1848
+ export class GatedVerifierAgent extends GatedSubAgent {
1849
+ constructor(messageBus, toolBridge, config) {
1850
+ super("verifier", config || {}, messageBus, toolBridge, {
1851
+ maxRetries: 2,
1852
+ strictMode: true,
1853
+ });
1854
+ }
1855
+ async performTask(task) {
1856
+ this.updateStatus("running", "Verifying implementation");
1857
+ // Verification logic - parses claims and verifies implementation
1858
+ const verificationPrompt = task.prompt;
1859
+ // Call model to perform verification
1860
+ const response = await this.callModel(verificationPrompt);
1861
+ if (response) {
1862
+ try {
1863
+ // Try to parse as structured verification result
1864
+ return JSON.parse(response);
1865
+ }
1866
+ catch {
1867
+ return { rawOutput: response, parsed: false };
1868
+ }
1869
+ }
1870
+ return { error: "Verification failed - no response from model" };
1871
+ }
1872
+ }
1873
+ // ============================================================================
1874
+ // Gated Strategist Agent (Mission/Milestone decomposition)
1875
+ // ============================================================================
1876
+ export class GatedStrategistAgent extends GatedSubAgent {
1877
+ constructor(messageBus, toolBridge, config) {
1878
+ super("strategist", config || {}, messageBus, toolBridge, {
1879
+ maxRetries: 2,
1880
+ strictMode: false,
1881
+ });
1882
+ }
1883
+ async performTask(task) {
1884
+ this.updateStatus("running", "Breaking down goals into milestones");
1885
+ const strategyPrompt = `Break down the following goal into missions and milestones:
1886
+
1887
+ ${task.prompt}
1888
+
1889
+ Provide:
1890
+ 1. High-level missions (distinct major phases)
1891
+ 2. Each mission's key milestones
1892
+ 3. Dependencies between milestones
1893
+ 4. Priority ordering
1894
+ 5. Estimated complexity per milestone
1895
+
1896
+ Format as structured JSON.`;
1897
+ const response = await this.callModel(strategyPrompt);
1898
+ if (response) {
1899
+ try {
1900
+ return JSON.parse(response);
1901
+ }
1902
+ catch {
1903
+ return { rawStrategy: response };
1904
+ }
1905
+ }
1906
+ return { error: "Strategy generation failed" };
1907
+ }
1908
+ }
1909
+ // ============================================================================
1910
+ // Gated Diff Validator Agent (Original vs Modified comparison)
1911
+ // ============================================================================
1912
+ export class GatedDiffValidatorAgent extends GatedSubAgent {
1913
+ constructor(messageBus, toolBridge, config) {
1914
+ super("diff_validator", config || {}, messageBus, toolBridge, {
1915
+ maxRetries: 2,
1916
+ strictMode: true,
1917
+ });
1918
+ }
1919
+ async performTask(task) {
1920
+ this.updateStatus("running", "Validating code changes");
1921
+ const validationPrompt = `Compare original vs modified code and validate correctness:
1922
+
1923
+ ${task.prompt}
1924
+
1925
+ Check for:
1926
+ 1. Behavioral preservation (same output for same input)
1927
+ 2. Syntax correctness
1928
+ 3. No unintended modifications
1929
+ 4. Structural integrity
1930
+
1931
+ Provide validation report as JSON.`;
1932
+ const response = await this.callModel(validationPrompt);
1933
+ if (response) {
1934
+ try {
1935
+ return JSON.parse(response);
1936
+ }
1937
+ catch {
1938
+ return { rawValidation: response };
1939
+ }
1940
+ }
1941
+ return { error: "Diff validation failed" };
1942
+ }
1943
+ }
1944
+ // ============================================================================
1945
+ // Gated Debugger Agent (Auto-fix on failure)
1946
+ // ============================================================================
1947
+ export class GatedDebuggerAgent extends GatedSubAgent {
1948
+ constructor(messageBus, toolBridge, config) {
1949
+ super("debugger", config || {}, messageBus, toolBridge, {
1950
+ maxRetries: 3,
1951
+ strictMode: false,
1952
+ });
1953
+ }
1954
+ async performTask(task) {
1955
+ this.updateStatus("running", "Analyzing and fixing errors");
1956
+ const debugPrompt = `Analyze error messages/stack traces and identify root cause:
1957
+
1958
+ ${task.prompt}
1959
+
1960
+ Provide:
1961
+ 1. Root cause analysis
1962
+ 2. Proposed fix (if possible)
1963
+ 3. Files that need modification
1964
+ 4. Confidence level
1965
+
1966
+ Format as JSON.`;
1967
+ const response = await this.callModel(debugPrompt);
1968
+ if (response) {
1969
+ try {
1970
+ return JSON.parse(response);
1971
+ }
1972
+ catch {
1973
+ return { rawDebug: response };
1974
+ }
1975
+ }
1976
+ return { error: "Debug analysis failed" };
1977
+ }
1978
+ }
1979
+ // ============================================================================
1980
+ // Gated Test Runner Agent (Validation tests execution)
1981
+ // ============================================================================
1982
+ export class GatedTestRunnerAgent extends GatedSubAgent {
1983
+ constructor(messageBus, toolBridge, config) {
1984
+ super("test_runner", config || {}, messageBus, toolBridge, {
1985
+ maxRetries: 2,
1986
+ strictMode: true,
1987
+ });
1988
+ }
1989
+ async performTask(task) {
1990
+ this.updateStatus("running", "Running validation tests");
1991
+ const testPrompt = `Execute validation tests and report results:
1992
+
1993
+ ${task.prompt}
1994
+
1995
+ Provide:
1996
+ 1. Test results (pass/fail)
1997
+ 2. Any runtime errors detected
1998
+ 3. Expected vs actual behavior comparison
1999
+ 4. Test failure diagnostics
2000
+
2001
+ Format as JSON.`;
2002
+ const response = await this.callModel(testPrompt);
2003
+ if (response) {
2004
+ try {
2005
+ return JSON.parse(response);
2006
+ }
2007
+ catch {
2008
+ return { rawTestResults: response };
2009
+ }
2010
+ }
2011
+ return { error: "Test execution failed" };
2012
+ }
2013
+ }
2014
+ //# sourceMappingURL=gated-subagents.js.map