@nexus-cortex/executors 4.26.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 (365) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +2 -0
  3. package/README.md +13 -0
  4. package/dist/ExecutorRegistry.d.ts +89 -0
  5. package/dist/ExecutorRegistry.d.ts.map +1 -0
  6. package/dist/ExecutorRegistry.js +219 -0
  7. package/dist/ExecutorRegistry.js.map +1 -0
  8. package/dist/base/BaseTool.d.ts +108 -0
  9. package/dist/base/BaseTool.d.ts.map +1 -0
  10. package/dist/base/BaseTool.js +111 -0
  11. package/dist/base/BaseTool.js.map +1 -0
  12. package/dist/base/ToolRegistry.d.ts +141 -0
  13. package/dist/base/ToolRegistry.d.ts.map +1 -0
  14. package/dist/base/ToolRegistry.js +241 -0
  15. package/dist/base/ToolRegistry.js.map +1 -0
  16. package/dist/base/ToolResult.d.ts +63 -0
  17. package/dist/base/ToolResult.d.ts.map +1 -0
  18. package/dist/base/ToolResult.js +8 -0
  19. package/dist/base/ToolResult.js.map +1 -0
  20. package/dist/base/index.d.ts +10 -0
  21. package/dist/base/index.d.ts.map +1 -0
  22. package/dist/base/index.js +8 -0
  23. package/dist/base/index.js.map +1 -0
  24. package/dist/implementations/addon/CreateArtifactTool.d.ts +221 -0
  25. package/dist/implementations/addon/CreateArtifactTool.d.ts.map +1 -0
  26. package/dist/implementations/addon/CreateArtifactTool.js +1042 -0
  27. package/dist/implementations/addon/CreateArtifactTool.js.map +1 -0
  28. package/dist/implementations/addon/FrameDiffCache.d.ts +166 -0
  29. package/dist/implementations/addon/FrameDiffCache.d.ts.map +1 -0
  30. package/dist/implementations/addon/FrameDiffCache.js +395 -0
  31. package/dist/implementations/addon/FrameDiffCache.js.map +1 -0
  32. package/dist/implementations/addon/H264StreamEncoder.d.ts +84 -0
  33. package/dist/implementations/addon/H264StreamEncoder.d.ts.map +1 -0
  34. package/dist/implementations/addon/H264StreamEncoder.js +203 -0
  35. package/dist/implementations/addon/H264StreamEncoder.js.map +1 -0
  36. package/dist/implementations/addon/HybridScreenshotManager.d.ts +197 -0
  37. package/dist/implementations/addon/HybridScreenshotManager.d.ts.map +1 -0
  38. package/dist/implementations/addon/HybridScreenshotManager.js +415 -0
  39. package/dist/implementations/addon/HybridScreenshotManager.js.map +1 -0
  40. package/dist/implementations/addon/InspectSandboxTool.d.ts +54 -0
  41. package/dist/implementations/addon/InspectSandboxTool.d.ts.map +1 -0
  42. package/dist/implementations/addon/InspectSandboxTool.js +226 -0
  43. package/dist/implementations/addon/InspectSandboxTool.js.map +1 -0
  44. package/dist/implementations/addon/InteractWithSandboxTool.d.ts +90 -0
  45. package/dist/implementations/addon/InteractWithSandboxTool.d.ts.map +1 -0
  46. package/dist/implementations/addon/InteractWithSandboxTool.js +367 -0
  47. package/dist/implementations/addon/InteractWithSandboxTool.js.map +1 -0
  48. package/dist/implementations/addon/KeyframeDetector.d.ts +140 -0
  49. package/dist/implementations/addon/KeyframeDetector.d.ts.map +1 -0
  50. package/dist/implementations/addon/KeyframeDetector.js +390 -0
  51. package/dist/implementations/addon/KeyframeDetector.js.map +1 -0
  52. package/dist/implementations/addon/ModifySandboxTool.d.ts +62 -0
  53. package/dist/implementations/addon/ModifySandboxTool.d.ts.map +1 -0
  54. package/dist/implementations/addon/ModifySandboxTool.js +266 -0
  55. package/dist/implementations/addon/ModifySandboxTool.js.map +1 -0
  56. package/dist/implementations/addon/ReactArtifactBuilder.d.ts +27 -0
  57. package/dist/implementations/addon/ReactArtifactBuilder.d.ts.map +1 -0
  58. package/dist/implementations/addon/ReactArtifactBuilder.js +198 -0
  59. package/dist/implementations/addon/ReactArtifactBuilder.js.map +1 -0
  60. package/dist/implementations/addon/SandboxEventBroadcaster.d.ts +143 -0
  61. package/dist/implementations/addon/SandboxEventBroadcaster.d.ts.map +1 -0
  62. package/dist/implementations/addon/SandboxEventBroadcaster.js +258 -0
  63. package/dist/implementations/addon/SandboxEventBroadcaster.js.map +1 -0
  64. package/dist/implementations/addon/SandboxIntrospectionTools.d.ts +77 -0
  65. package/dist/implementations/addon/SandboxIntrospectionTools.d.ts.map +1 -0
  66. package/dist/implementations/addon/SandboxIntrospectionTools.js +292 -0
  67. package/dist/implementations/addon/SandboxIntrospectionTools.js.map +1 -0
  68. package/dist/implementations/addon/SandboxViewServer.d.ts +127 -0
  69. package/dist/implementations/addon/SandboxViewServer.d.ts.map +1 -0
  70. package/dist/implementations/addon/SandboxViewServer.js +775 -0
  71. package/dist/implementations/addon/SandboxViewServer.js.map +1 -0
  72. package/dist/implementations/addon/ScreenStream.d.ts +149 -0
  73. package/dist/implementations/addon/ScreenStream.d.ts.map +1 -0
  74. package/dist/implementations/addon/ScreenStream.js +306 -0
  75. package/dist/implementations/addon/ScreenStream.js.map +1 -0
  76. package/dist/implementations/addon/StopSandboxTool.d.ts +61 -0
  77. package/dist/implementations/addon/StopSandboxTool.d.ts.map +1 -0
  78. package/dist/implementations/addon/StopSandboxTool.js +252 -0
  79. package/dist/implementations/addon/StopSandboxTool.js.map +1 -0
  80. package/dist/implementations/addon/TerminalSandbox.d.ts +111 -0
  81. package/dist/implementations/addon/TerminalSandbox.d.ts.map +1 -0
  82. package/dist/implementations/addon/TerminalSandbox.js +345 -0
  83. package/dist/implementations/addon/TerminalSandbox.js.map +1 -0
  84. package/dist/implementations/addon/VisualFeedbackBridge.d.ts +367 -0
  85. package/dist/implementations/addon/VisualFeedbackBridge.d.ts.map +1 -0
  86. package/dist/implementations/addon/VisualFeedbackBridge.js +888 -0
  87. package/dist/implementations/addon/VisualFeedbackBridge.js.map +1 -0
  88. package/dist/implementations/addon/WindowManager.d.ts +138 -0
  89. package/dist/implementations/addon/WindowManager.d.ts.map +1 -0
  90. package/dist/implementations/addon/WindowManager.js +276 -0
  91. package/dist/implementations/addon/WindowManager.js.map +1 -0
  92. package/dist/implementations/addon/index.d.ts +29 -0
  93. package/dist/implementations/addon/index.d.ts.map +1 -0
  94. package/dist/implementations/addon/index.js +29 -0
  95. package/dist/implementations/addon/index.js.map +1 -0
  96. package/dist/implementations/addon/injectables/reactIntrospection.d.ts +57 -0
  97. package/dist/implementations/addon/injectables/reactIntrospection.d.ts.map +1 -0
  98. package/dist/implementations/addon/injectables/reactIntrospection.js +480 -0
  99. package/dist/implementations/addon/injectables/reactIntrospection.js.map +1 -0
  100. package/dist/implementations/addon/terminal-client.html +253 -0
  101. package/dist/implementations/agent/PRAgentTool.d.ts +37 -0
  102. package/dist/implementations/agent/PRAgentTool.d.ts.map +1 -0
  103. package/dist/implementations/agent/PRAgentTool.js +257 -0
  104. package/dist/implementations/agent/PRAgentTool.js.map +1 -0
  105. package/dist/implementations/agent/TaskTool.d.ts +76 -0
  106. package/dist/implementations/agent/TaskTool.d.ts.map +1 -0
  107. package/dist/implementations/agent/TaskTool.js +424 -0
  108. package/dist/implementations/agent/TaskTool.js.map +1 -0
  109. package/dist/implementations/agent/index.d.ts +5 -0
  110. package/dist/implementations/agent/index.d.ts.map +1 -0
  111. package/dist/implementations/agent/index.js +3 -0
  112. package/dist/implementations/agent/index.js.map +1 -0
  113. package/dist/implementations/execution/BackgroundProcessRegistry.d.ts +68 -0
  114. package/dist/implementations/execution/BackgroundProcessRegistry.d.ts.map +1 -0
  115. package/dist/implementations/execution/BackgroundProcessRegistry.js +146 -0
  116. package/dist/implementations/execution/BackgroundProcessRegistry.js.map +1 -0
  117. package/dist/implementations/execution/BashOutputTool.d.ts +42 -0
  118. package/dist/implementations/execution/BashOutputTool.d.ts.map +1 -0
  119. package/dist/implementations/execution/BashOutputTool.js +168 -0
  120. package/dist/implementations/execution/BashOutputTool.js.map +1 -0
  121. package/dist/implementations/execution/CodeExecuteTool.d.ts +31 -0
  122. package/dist/implementations/execution/CodeExecuteTool.d.ts.map +1 -0
  123. package/dist/implementations/execution/CodeExecuteTool.js +127 -0
  124. package/dist/implementations/execution/CodeExecuteTool.js.map +1 -0
  125. package/dist/implementations/execution/KillShellTool.d.ts +37 -0
  126. package/dist/implementations/execution/KillShellTool.d.ts.map +1 -0
  127. package/dist/implementations/execution/KillShellTool.js +144 -0
  128. package/dist/implementations/execution/KillShellTool.js.map +1 -0
  129. package/dist/implementations/execution/SearchToolsTool.d.ts +32 -0
  130. package/dist/implementations/execution/SearchToolsTool.d.ts.map +1 -0
  131. package/dist/implementations/execution/SearchToolsTool.js +109 -0
  132. package/dist/implementations/execution/SearchToolsTool.js.map +1 -0
  133. package/dist/implementations/execution/ShellTool.d.ts +108 -0
  134. package/dist/implementations/execution/ShellTool.d.ts.map +1 -0
  135. package/dist/implementations/execution/ShellTool.js +546 -0
  136. package/dist/implementations/execution/ShellTool.js.map +1 -0
  137. package/dist/implementations/execution/WorkspaceManagerTool.d.ts +40 -0
  138. package/dist/implementations/execution/WorkspaceManagerTool.d.ts.map +1 -0
  139. package/dist/implementations/execution/WorkspaceManagerTool.js +370 -0
  140. package/dist/implementations/execution/WorkspaceManagerTool.js.map +1 -0
  141. package/dist/implementations/execution/index.d.ts +13 -0
  142. package/dist/implementations/execution/index.d.ts.map +1 -0
  143. package/dist/implementations/execution/index.js +13 -0
  144. package/dist/implementations/execution/index.js.map +1 -0
  145. package/dist/implementations/extensions/EndTurnTool.d.ts +62 -0
  146. package/dist/implementations/extensions/EndTurnTool.d.ts.map +1 -0
  147. package/dist/implementations/extensions/EndTurnTool.js +172 -0
  148. package/dist/implementations/extensions/EndTurnTool.js.map +1 -0
  149. package/dist/implementations/extensions/ResearchBacklogTool.d.ts +37 -0
  150. package/dist/implementations/extensions/ResearchBacklogTool.d.ts.map +1 -0
  151. package/dist/implementations/extensions/ResearchBacklogTool.js +102 -0
  152. package/dist/implementations/extensions/ResearchBacklogTool.js.map +1 -0
  153. package/dist/implementations/extensions/SkillTool.d.ts +108 -0
  154. package/dist/implementations/extensions/SkillTool.d.ts.map +1 -0
  155. package/dist/implementations/extensions/SkillTool.js +351 -0
  156. package/dist/implementations/extensions/SkillTool.js.map +1 -0
  157. package/dist/implementations/extensions/SlashCommandTool.d.ts +112 -0
  158. package/dist/implementations/extensions/SlashCommandTool.d.ts.map +1 -0
  159. package/dist/implementations/extensions/SlashCommandTool.js +315 -0
  160. package/dist/implementations/extensions/SlashCommandTool.js.map +1 -0
  161. package/dist/implementations/extensions/index.d.ts +14 -0
  162. package/dist/implementations/extensions/index.d.ts.map +1 -0
  163. package/dist/implementations/extensions/index.js +10 -0
  164. package/dist/implementations/extensions/index.js.map +1 -0
  165. package/dist/implementations/file/EditTool.d.ts +232 -0
  166. package/dist/implementations/file/EditTool.d.ts.map +1 -0
  167. package/dist/implementations/file/EditTool.js +707 -0
  168. package/dist/implementations/file/EditTool.js.map +1 -0
  169. package/dist/implementations/file/ReadFileTool.d.ts +49 -0
  170. package/dist/implementations/file/ReadFileTool.d.ts.map +1 -0
  171. package/dist/implementations/file/ReadFileTool.js +225 -0
  172. package/dist/implementations/file/ReadFileTool.js.map +1 -0
  173. package/dist/implementations/file/WriteBinaryTool.d.ts +21 -0
  174. package/dist/implementations/file/WriteBinaryTool.d.ts.map +1 -0
  175. package/dist/implementations/file/WriteBinaryTool.js +153 -0
  176. package/dist/implementations/file/WriteBinaryTool.js.map +1 -0
  177. package/dist/implementations/file/WriteFileTool.d.ts +41 -0
  178. package/dist/implementations/file/WriteFileTool.d.ts.map +1 -0
  179. package/dist/implementations/file/WriteFileTool.js +220 -0
  180. package/dist/implementations/file/WriteFileTool.js.map +1 -0
  181. package/dist/implementations/file/index.d.ts +8 -0
  182. package/dist/implementations/file/index.d.ts.map +1 -0
  183. package/dist/implementations/file/index.js +8 -0
  184. package/dist/implementations/file/index.js.map +1 -0
  185. package/dist/implementations/historical/GetConversationSegmentTool.d.ts +44 -0
  186. package/dist/implementations/historical/GetConversationSegmentTool.d.ts.map +1 -0
  187. package/dist/implementations/historical/GetConversationSegmentTool.js +220 -0
  188. package/dist/implementations/historical/GetConversationSegmentTool.js.map +1 -0
  189. package/dist/implementations/historical/ListCompactionBoundariesTool.d.ts +36 -0
  190. package/dist/implementations/historical/ListCompactionBoundariesTool.d.ts.map +1 -0
  191. package/dist/implementations/historical/ListCompactionBoundariesTool.js +174 -0
  192. package/dist/implementations/historical/ListCompactionBoundariesTool.js.map +1 -0
  193. package/dist/implementations/historical/ListSessionsTool.d.ts +38 -0
  194. package/dist/implementations/historical/ListSessionsTool.d.ts.map +1 -0
  195. package/dist/implementations/historical/ListSessionsTool.js +140 -0
  196. package/dist/implementations/historical/ListSessionsTool.js.map +1 -0
  197. package/dist/implementations/historical/LoadSessionTool.d.ts +39 -0
  198. package/dist/implementations/historical/LoadSessionTool.d.ts.map +1 -0
  199. package/dist/implementations/historical/LoadSessionTool.js +171 -0
  200. package/dist/implementations/historical/LoadSessionTool.js.map +1 -0
  201. package/dist/implementations/historical/RequestHistoricalContextTool.d.ts +46 -0
  202. package/dist/implementations/historical/RequestHistoricalContextTool.d.ts.map +1 -0
  203. package/dist/implementations/historical/RequestHistoricalContextTool.js +224 -0
  204. package/dist/implementations/historical/RequestHistoricalContextTool.js.map +1 -0
  205. package/dist/implementations/historical/SearchConversationHistoryTool.d.ts +51 -0
  206. package/dist/implementations/historical/SearchConversationHistoryTool.d.ts.map +1 -0
  207. package/dist/implementations/historical/SearchConversationHistoryTool.js +306 -0
  208. package/dist/implementations/historical/SearchConversationHistoryTool.js.map +1 -0
  209. package/dist/implementations/historical/index.d.ts +12 -0
  210. package/dist/implementations/historical/index.d.ts.map +1 -0
  211. package/dist/implementations/historical/index.js +12 -0
  212. package/dist/implementations/historical/index.js.map +1 -0
  213. package/dist/implementations/index.d.ts +16 -0
  214. package/dist/implementations/index.d.ts.map +1 -0
  215. package/dist/implementations/index.js +28 -0
  216. package/dist/implementations/index.js.map +1 -0
  217. package/dist/implementations/mcp/DiscoveredMcpTool.d.ts +58 -0
  218. package/dist/implementations/mcp/DiscoveredMcpTool.d.ts.map +1 -0
  219. package/dist/implementations/mcp/DiscoveredMcpTool.js +269 -0
  220. package/dist/implementations/mcp/DiscoveredMcpTool.js.map +1 -0
  221. package/dist/implementations/mcp/index.d.ts +9 -0
  222. package/dist/implementations/mcp/index.d.ts.map +1 -0
  223. package/dist/implementations/mcp/index.js +8 -0
  224. package/dist/implementations/mcp/index.js.map +1 -0
  225. package/dist/implementations/notebook/NotebookEditTool.d.ts +96 -0
  226. package/dist/implementations/notebook/NotebookEditTool.d.ts.map +1 -0
  227. package/dist/implementations/notebook/NotebookEditTool.js +390 -0
  228. package/dist/implementations/notebook/NotebookEditTool.js.map +1 -0
  229. package/dist/implementations/notebook/index.d.ts +7 -0
  230. package/dist/implementations/notebook/index.d.ts.map +1 -0
  231. package/dist/implementations/notebook/index.js +7 -0
  232. package/dist/implementations/notebook/index.js.map +1 -0
  233. package/dist/implementations/search/GlobTool.d.ts +73 -0
  234. package/dist/implementations/search/GlobTool.d.ts.map +1 -0
  235. package/dist/implementations/search/GlobTool.js +213 -0
  236. package/dist/implementations/search/GlobTool.js.map +1 -0
  237. package/dist/implementations/search/GrepTool.d.ts +102 -0
  238. package/dist/implementations/search/GrepTool.d.ts.map +1 -0
  239. package/dist/implementations/search/GrepTool.js +754 -0
  240. package/dist/implementations/search/GrepTool.js.map +1 -0
  241. package/dist/implementations/search/index.d.ts +6 -0
  242. package/dist/implementations/search/index.d.ts.map +1 -0
  243. package/dist/implementations/search/index.js +6 -0
  244. package/dist/implementations/search/index.js.map +1 -0
  245. package/dist/implementations/tmux/TmuxSessionTool.d.ts +82 -0
  246. package/dist/implementations/tmux/TmuxSessionTool.d.ts.map +1 -0
  247. package/dist/implementations/tmux/TmuxSessionTool.js +371 -0
  248. package/dist/implementations/tmux/TmuxSessionTool.js.map +1 -0
  249. package/dist/implementations/tmux/TmuxViewServer.d.ts +86 -0
  250. package/dist/implementations/tmux/TmuxViewServer.d.ts.map +1 -0
  251. package/dist/implementations/tmux/TmuxViewServer.js +480 -0
  252. package/dist/implementations/tmux/TmuxViewServer.js.map +1 -0
  253. package/dist/implementations/tmux/index.d.ts +6 -0
  254. package/dist/implementations/tmux/index.d.ts.map +1 -0
  255. package/dist/implementations/tmux/index.js +6 -0
  256. package/dist/implementations/tmux/index.js.map +1 -0
  257. package/dist/implementations/ui/AskUserQuestionTool.d.ts +77 -0
  258. package/dist/implementations/ui/AskUserQuestionTool.d.ts.map +1 -0
  259. package/dist/implementations/ui/AskUserQuestionTool.js +241 -0
  260. package/dist/implementations/ui/AskUserQuestionTool.js.map +1 -0
  261. package/dist/implementations/ui/ExitPlanModeTool.d.ts +44 -0
  262. package/dist/implementations/ui/ExitPlanModeTool.d.ts.map +1 -0
  263. package/dist/implementations/ui/ExitPlanModeTool.js +150 -0
  264. package/dist/implementations/ui/ExitPlanModeTool.js.map +1 -0
  265. package/dist/implementations/ui/TodoWriteTool.d.ts +59 -0
  266. package/dist/implementations/ui/TodoWriteTool.d.ts.map +1 -0
  267. package/dist/implementations/ui/TodoWriteTool.js +315 -0
  268. package/dist/implementations/ui/TodoWriteTool.js.map +1 -0
  269. package/dist/implementations/ui/index.d.ts +9 -0
  270. package/dist/implementations/ui/index.d.ts.map +1 -0
  271. package/dist/implementations/ui/index.js +9 -0
  272. package/dist/implementations/ui/index.js.map +1 -0
  273. package/dist/implementations/web/BrowseTool.d.ts +43 -0
  274. package/dist/implementations/web/BrowseTool.d.ts.map +1 -0
  275. package/dist/implementations/web/BrowseTool.js +181 -0
  276. package/dist/implementations/web/BrowseTool.js.map +1 -0
  277. package/dist/implementations/web/SandboxTransferTool.d.ts +30 -0
  278. package/dist/implementations/web/SandboxTransferTool.d.ts.map +1 -0
  279. package/dist/implementations/web/SandboxTransferTool.js +261 -0
  280. package/dist/implementations/web/SandboxTransferTool.js.map +1 -0
  281. package/dist/implementations/web/WebFetchTool.d.ts +93 -0
  282. package/dist/implementations/web/WebFetchTool.d.ts.map +1 -0
  283. package/dist/implementations/web/WebFetchTool.js +484 -0
  284. package/dist/implementations/web/WebFetchTool.js.map +1 -0
  285. package/dist/implementations/web/WebSearchTool.d.ts +53 -0
  286. package/dist/implementations/web/WebSearchTool.d.ts.map +1 -0
  287. package/dist/implementations/web/WebSearchTool.js +227 -0
  288. package/dist/implementations/web/WebSearchTool.js.map +1 -0
  289. package/dist/implementations/web/escalateDirective.d.ts +11 -0
  290. package/dist/implementations/web/escalateDirective.d.ts.map +1 -0
  291. package/dist/implementations/web/escalateDirective.js +20 -0
  292. package/dist/implementations/web/escalateDirective.js.map +1 -0
  293. package/dist/implementations/web/index.d.ts +10 -0
  294. package/dist/implementations/web/index.d.ts.map +1 -0
  295. package/dist/implementations/web/index.js +10 -0
  296. package/dist/implementations/web/index.js.map +1 -0
  297. package/dist/implementations/web/webBackends.d.ts +65 -0
  298. package/dist/implementations/web/webBackends.d.ts.map +1 -0
  299. package/dist/implementations/web/webBackends.js +430 -0
  300. package/dist/implementations/web/webBackends.js.map +1 -0
  301. package/dist/implementations/web/webFetchRequestInit.d.ts +9 -0
  302. package/dist/implementations/web/webFetchRequestInit.d.ts.map +1 -0
  303. package/dist/implementations/web/webFetchRequestInit.js +21 -0
  304. package/dist/implementations/web/webFetchRequestInit.js.map +1 -0
  305. package/dist/index.d.ts +14 -0
  306. package/dist/index.d.ts.map +1 -0
  307. package/dist/index.js +18 -0
  308. package/dist/index.js.map +1 -0
  309. package/dist/utils/ArtifactRegistry.d.ts +138 -0
  310. package/dist/utils/ArtifactRegistry.d.ts.map +1 -0
  311. package/dist/utils/ArtifactRegistry.js +259 -0
  312. package/dist/utils/ArtifactRegistry.js.map +1 -0
  313. package/dist/utils/ChromiumBrowserManager.d.ts +56 -0
  314. package/dist/utils/ChromiumBrowserManager.d.ts.map +1 -0
  315. package/dist/utils/ChromiumBrowserManager.js +243 -0
  316. package/dist/utils/ChromiumBrowserManager.js.map +1 -0
  317. package/dist/utils/FileUtils.d.ts +81 -0
  318. package/dist/utils/FileUtils.d.ts.map +1 -0
  319. package/dist/utils/FileUtils.js +148 -0
  320. package/dist/utils/FileUtils.js.map +1 -0
  321. package/dist/utils/GitPolicy.d.ts +70 -0
  322. package/dist/utils/GitPolicy.d.ts.map +1 -0
  323. package/dist/utils/GitPolicy.js +166 -0
  324. package/dist/utils/GitPolicy.js.map +1 -0
  325. package/dist/utils/GitUtils.d.ts +18 -0
  326. package/dist/utils/GitUtils.d.ts.map +1 -0
  327. package/dist/utils/GitUtils.js +62 -0
  328. package/dist/utils/GitUtils.js.map +1 -0
  329. package/dist/utils/SandboxRegistry.d.ts +110 -0
  330. package/dist/utils/SandboxRegistry.d.ts.map +1 -0
  331. package/dist/utils/SandboxRegistry.js +220 -0
  332. package/dist/utils/SandboxRegistry.js.map +1 -0
  333. package/dist/utils/SchemaValidator.d.ts +21 -0
  334. package/dist/utils/SchemaValidator.d.ts.map +1 -0
  335. package/dist/utils/SchemaValidator.js +67 -0
  336. package/dist/utils/SchemaValidator.js.map +1 -0
  337. package/dist/utils/SessionLock.d.ts +96 -0
  338. package/dist/utils/SessionLock.d.ts.map +1 -0
  339. package/dist/utils/SessionLock.js +276 -0
  340. package/dist/utils/SessionLock.js.map +1 -0
  341. package/dist/utils/SessionPersistence.d.ts +89 -0
  342. package/dist/utils/SessionPersistence.d.ts.map +1 -0
  343. package/dist/utils/SessionPersistence.js +244 -0
  344. package/dist/utils/SessionPersistence.js.map +1 -0
  345. package/dist/utils/TextUtils.d.ts +77 -0
  346. package/dist/utils/TextUtils.d.ts.map +1 -0
  347. package/dist/utils/TextUtils.js +112 -0
  348. package/dist/utils/TextUtils.js.map +1 -0
  349. package/dist/utils/TmuxCapture.d.ts +94 -0
  350. package/dist/utils/TmuxCapture.d.ts.map +1 -0
  351. package/dist/utils/TmuxCapture.js +131 -0
  352. package/dist/utils/TmuxCapture.js.map +1 -0
  353. package/dist/utils/TmuxManager.d.ts +65 -0
  354. package/dist/utils/TmuxManager.d.ts.map +1 -0
  355. package/dist/utils/TmuxManager.js +304 -0
  356. package/dist/utils/TmuxManager.js.map +1 -0
  357. package/dist/utils/autoResearchPlanGate.d.ts +10 -0
  358. package/dist/utils/autoResearchPlanGate.d.ts.map +1 -0
  359. package/dist/utils/autoResearchPlanGate.js +57 -0
  360. package/dist/utils/autoResearchPlanGate.js.map +1 -0
  361. package/dist/utils/index.d.ts +19 -0
  362. package/dist/utils/index.d.ts.map +1 -0
  363. package/dist/utils/index.js +13 -0
  364. package/dist/utils/index.js.map +1 -0
  365. package/package.json +83 -0
@@ -0,0 +1,1042 @@
1
+ import { BaseTool } from '../../base/BaseTool.js';
2
+ import { spawn } from 'child_process';
3
+ import { promises as fs } from 'fs';
4
+ import { join } from 'path';
5
+ import { randomUUID } from 'crypto';
6
+ import { buildReactArtifact } from './ReactArtifactBuilder.js';
7
+ import { watch } from 'fs';
8
+ import { exec } from 'child_process';
9
+ import { promisify } from 'util';
10
+ import { visualBridge } from './VisualFeedbackBridge.js';
11
+ import { broadcaster } from './SandboxEventBroadcaster.js';
12
+ import { viewServer, SandboxViewServer } from './SandboxViewServer.js';
13
+ import { SandboxRegistry } from '../../utils/SandboxRegistry.js';
14
+ import { ArtifactRegistry } from '../../utils/ArtifactRegistry.js';
15
+ import { TmuxManager } from '../../utils/TmuxManager.js';
16
+ import { SessionPersistence } from '../../utils/SessionPersistence.js';
17
+ const execAsync = promisify(exec);
18
+ /**
19
+ * Active artifactes registry
20
+ */
21
+ const activeArtifactes = new Map();
22
+ /**
23
+ * CreateAddonToolEnhanced - Next-generation dynamic tool creation
24
+ *
25
+ * Features:
26
+ * - UV + NIX package manager support
27
+ * - Dev mode with hot reloading
28
+ * - Automatic UI display (browser popup)
29
+ * - Persistent artifact sessions
30
+ * - Live editing with file watching
31
+ * - Multi-step orchestration
32
+ * - WebSocket live updates
33
+ *
34
+ * Example: TradeStation Proxy
35
+ * ```
36
+ * Model creates:
37
+ * 1. Proxy server (Express.js)
38
+ * 2. Traffic monitor (captures inbound/outbound)
39
+ * 3. Real-time dashboard (React/Socket.io)
40
+ * 4. Auto-opens browser at localhost:3000
41
+ * 5. Hot reloads on code changes
42
+ * ```
43
+ */
44
+ export class CreateArtifactToolExecutor extends BaseTool {
45
+ artifactDir;
46
+ workingDirectory;
47
+ constructor(config) {
48
+ const schema = {
49
+ type: 'object',
50
+ properties: {
51
+ name: {
52
+ type: 'string',
53
+ description: 'Unique name for the addon tool'
54
+ },
55
+ description: {
56
+ type: 'string',
57
+ description: 'What the tool does'
58
+ },
59
+ parameters: {
60
+ type: 'object',
61
+ description: 'JSON Schema for tool parameters'
62
+ },
63
+ implementation: {
64
+ type: 'object',
65
+ properties: {
66
+ language: {
67
+ type: 'string',
68
+ enum: ['javascript', 'python'],
69
+ description: 'Programming language'
70
+ },
71
+ code: {
72
+ type: 'string',
73
+ description: 'Source code'
74
+ },
75
+ dependencies: {
76
+ type: 'array',
77
+ items: { type: 'string' },
78
+ description: 'Required packages'
79
+ },
80
+ packageManager: {
81
+ type: 'string',
82
+ enum: ['npm', 'pip', 'uv', 'nix'],
83
+ description: 'Package manager (npm, pip, uv, nix)'
84
+ }
85
+ },
86
+ required: ['language', 'code']
87
+ },
88
+ mode: {
89
+ type: 'string',
90
+ enum: ['oneshot', 'dev', 'persistent'],
91
+ description: 'Execution mode: oneshot (default), dev (hot reload), persistent (keep alive)'
92
+ },
93
+ enableVisualFeedback: {
94
+ type: 'boolean',
95
+ description: 'Enable comprehensive visual feedback system for you (the model) to see and iterate on your creations. Captures: (1) screenshots (base64 PNG) of actual UI rendering, (2) DOM structure (HTML), (3) console logs (runtime output), (4) network requests (API calls), (5) performance metrics. Visual data is included in response metadata, allowing you to analyze what you built, identify issues, and make improvements. Essential for iterative UI development.'
96
+ },
97
+ enableReactIntrospection: {
98
+ type: 'boolean',
99
+ description: 'Include a framework report (React/Vue/Svelte detection, React version, renderer count) in the initial visual snapshot. The sandbox_scan / sandbox_grab / sandbox_detect_framework tools work regardless of this flag (they enable introspection on first use). Default: false.'
100
+ },
101
+ devConfig: {
102
+ type: 'object',
103
+ properties: {
104
+ hotReload: {
105
+ type: 'boolean',
106
+ description: 'Enable hot reload on file changes'
107
+ },
108
+ watchFiles: {
109
+ type: 'array',
110
+ items: { type: 'string' },
111
+ description: 'Files to watch for changes'
112
+ },
113
+ openBrowser: {
114
+ type: 'boolean',
115
+ description: 'Auto-open browser on start'
116
+ },
117
+ liveBridge: {
118
+ type: 'boolean',
119
+ description: 'Enable WebSocket live updates'
120
+ }
121
+ }
122
+ },
123
+ uiConfig: {
124
+ type: 'object',
125
+ properties: {
126
+ type: {
127
+ type: 'string',
128
+ enum: ['web', 'terminal', 'both'],
129
+ description: 'UI display type'
130
+ },
131
+ framework: {
132
+ type: 'string',
133
+ enum: ['express', 'fastapi', 'flask', 'nextjs', 'react'],
134
+ description: "Web framework. Use 'react' to build a React artifact from a component in implementation.code (define or default-export `App`). React artifacts are served statically and are introspectable via sandbox_scan/sandbox_grab/sandbox_detect_framework."
135
+ },
136
+ reactMode: {
137
+ type: 'string',
138
+ enum: ['cdn', 'bundled'],
139
+ description: "React only. 'bundled' (default when esbuild is available): real source maps, sandbox_grab returns real src/App.tsx:line. 'cdn': zero-install in-browser Babel, faster to start."
140
+ },
141
+ additionalFiles: {
142
+ type: 'array',
143
+ items: {
144
+ type: 'object',
145
+ properties: {
146
+ path: { type: 'string', description: "Path under src/, e.g. 'components/Button.tsx'" },
147
+ code: { type: 'string', description: 'Module source' }
148
+ },
149
+ required: ['path', 'code']
150
+ },
151
+ description: 'React bundled mode only: extra source modules importable from App.'
152
+ },
153
+ autoStart: {
154
+ type: 'boolean',
155
+ description: 'Start UI server automatically'
156
+ }
157
+ }
158
+ },
159
+ artifactConfig: {
160
+ type: 'object',
161
+ properties: {
162
+ type: {
163
+ type: 'string',
164
+ enum: ['docker', 'local', 'nix'],
165
+ description: 'Artifact type'
166
+ },
167
+ nixConfig: {
168
+ type: 'object',
169
+ properties: {
170
+ packages: {
171
+ type: 'array',
172
+ items: { type: 'string' },
173
+ description: 'Nix packages to install'
174
+ },
175
+ shellHook: {
176
+ type: 'string',
177
+ description: 'Shell initialization script'
178
+ }
179
+ }
180
+ }
181
+ }
182
+ }
183
+ },
184
+ required: ['name', 'description', 'parameters', 'implementation']
185
+ };
186
+ super('CreateArtifactTool', 'CreateArtifactTool', 'Create persistent artifacts (web apps, tools, scripts) with hot reload, UV/NIX support, and auto UI display. Enable visual feedback to see your own creations: capture screenshots, DOM structure, console logs, network activity, and performance metrics. Use this data to iteratively improve and debug your work.', schema);
187
+ this.workingDirectory = config.workingDirectory;
188
+ // Use unified artifacts directory structure
189
+ this.artifactDir = join(config.workingDirectory, '.cortex', 'artifacts');
190
+ // Initialize unified artifact registry (singleton)
191
+ const registry = ArtifactRegistry.getInstance(config.workingDirectory);
192
+ registry.initialize().catch((error) => {
193
+ console.error(`⚠ Failed to initialize ArtifactRegistry: ${error.message}`);
194
+ });
195
+ // Also initialize sandbox registry for backwards compatibility
196
+ const sandboxRegistry = SandboxRegistry.getInstance(config.workingDirectory);
197
+ sandboxRegistry.initialize().catch((error) => {
198
+ console.error(`⚠ Failed to initialize SandboxRegistry: ${error.message}`);
199
+ });
200
+ }
201
+ /**
202
+ * Sanitize name to filesystem-safe format (kebab-case slug)
203
+ * Industry best practice: Accept human-friendly input, auto-convert to system-safe format
204
+ */
205
+ sanitizeName(name) {
206
+ return name
207
+ .trim()
208
+ .toLowerCase()
209
+ .replace(/[^a-z0-9]+/g, '-') // Replace non-alphanumeric with hyphens
210
+ .replace(/^-+|-+$/g, '') // Remove leading/trailing hyphens
211
+ .replace(/-{2,}/g, '-') // Collapse multiple hyphens
212
+ || 'unnamed-tool'; // Fallback if empty after sanitization
213
+ }
214
+ validateToolParams(params) {
215
+ // Basic validation
216
+ if (!params.name || params.name.trim().length === 0) {
217
+ return 'name must be a non-empty string';
218
+ }
219
+ // #18 — restore 64-char name cap (dropped during the CreateAddonTool →
220
+ // CreateArtifactTool rename refactor; unanimously diagnosed as a silent
221
+ // regression by the round-10 multi-agent audit). Checked BEFORE
222
+ // sanitization so callers see the same length contract they passed in;
223
+ // sanitization would only shrink a too-long name, masking the error.
224
+ if (params.name.length > 64) {
225
+ return 'name must be 64 characters or less';
226
+ }
227
+ // Auto-sanitize name instead of rejecting
228
+ // This accepts "Stock Chart App" and converts to "stock-chart-app"
229
+ const originalName = params.name;
230
+ params.name = this.sanitizeName(params.name);
231
+ if (params.name.length === 0 || params.name === 'unnamed-tool') {
232
+ return `name "${originalName}" contains no valid characters (letters, numbers)`;
233
+ }
234
+ if (!params.description || params.description.trim().length === 0) {
235
+ return 'description must be a non-empty string';
236
+ }
237
+ if (!params.implementation?.code) {
238
+ return 'implementation.code is required';
239
+ }
240
+ if (!['javascript', 'python'].includes(params.implementation.language)) {
241
+ return 'language must be javascript or python';
242
+ }
243
+ // Validate package manager
244
+ if (params.implementation.packageManager) {
245
+ const validManagers = ['npm', 'pip', 'uv', 'nix'];
246
+ if (!validManagers.includes(params.implementation.packageManager)) {
247
+ return `packageManager must be one of: ${validManagers.join(', ')}`;
248
+ }
249
+ }
250
+ // Validate mode
251
+ if (params.mode && !['oneshot', 'dev', 'persistent'].includes(params.mode)) {
252
+ return 'mode must be oneshot, dev, or persistent';
253
+ }
254
+ return null;
255
+ }
256
+ async execute(params, signal) {
257
+ const startTime = Date.now();
258
+ const originalName = params.name; // Preserve original before sanitization
259
+ const validationError = this.validateToolParams(params);
260
+ if (validationError) {
261
+ return this.createErrorResult(validationError);
262
+ }
263
+ // Notify if name was sanitized
264
+ const nameSanitized = originalName !== params.name;
265
+ try {
266
+ await fs.mkdir(this.artifactDir, { recursive: true });
267
+ const mode = params.mode || 'oneshot';
268
+ const artifactId = randomUUID();
269
+ // Create artifact directory with workspace subdirectory
270
+ const artifactPath = join(this.artifactDir, artifactId);
271
+ const workspacePath = join(artifactPath, 'workspace');
272
+ await fs.mkdir(artifactPath, { recursive: true });
273
+ await fs.mkdir(workspacePath, { recursive: true });
274
+ await fs.mkdir(join(artifactPath, 'snapshots'), { recursive: true });
275
+ // React artifacts: introspection on by default so the initial snapshot (and the
276
+ // sandbox_scan/grab/detect tools) report the fiber tree. Opt out by passing false.
277
+ if (params.uiConfig?.framework === 'react' && params.enableReactIntrospection === undefined) {
278
+ params.enableReactIntrospection = true;
279
+ }
280
+ // Install dependencies in workspace
281
+ await this.installDependencies(params.implementation, workspacePath, signal);
282
+ // Write code files to workspace
283
+ await this.writeToolFiles(params.implementation, params.uiConfig, workspacePath);
284
+ // Launch artifact based on mode
285
+ let session = null;
286
+ if (mode === 'dev' || mode === 'persistent') {
287
+ session = await this.launchPersistentArtifact(artifactId, params, workspacePath, signal);
288
+ }
289
+ else {
290
+ // Oneshot execution
291
+ const result = await this.executeOneshot(params.implementation, workspacePath, signal);
292
+ await fs.rm(artifactPath, { recursive: true, force: true });
293
+ return {
294
+ ...this.createSuccessResult(result.output),
295
+ metadata: {
296
+ executionTime: Date.now() - startTime,
297
+ toolName: params.name,
298
+ mode: 'oneshot',
299
+ success: result.success
300
+ }
301
+ };
302
+ }
303
+ // Format output for persistent/dev mode
304
+ const output = this.formatPersistentOutput(session, params, nameSanitized ? originalName : undefined);
305
+ return {
306
+ ...this.createSuccessResult(output),
307
+ metadata: {
308
+ executionTime: Date.now() - startTime,
309
+ toolName: params.name,
310
+ originalName: nameSanitized ? originalName : undefined,
311
+ sanitized: nameSanitized,
312
+ mode,
313
+ artifactId: session.id,
314
+ url: session.url,
315
+ port: session.port,
316
+ status: 'running',
317
+ visualFeedbackEnabled: params.enableVisualFeedback || false,
318
+ hasVisualSnapshot: !!session.visualSnapshot
319
+ }
320
+ };
321
+ }
322
+ catch (error) {
323
+ return this.createErrorResult(`Failed to create addon tool: ${error.message}`);
324
+ }
325
+ }
326
+ /**
327
+ * Install dependencies using specified package manager
328
+ */
329
+ async installDependencies(implementation, artifactPath, signal) {
330
+ if (!implementation.dependencies || implementation.dependencies.length === 0) {
331
+ return;
332
+ }
333
+ const packageManager = implementation.packageManager ||
334
+ (implementation.language === 'javascript' ? 'npm' : 'pip');
335
+ switch (packageManager) {
336
+ case 'npm':
337
+ await this.installNpm(implementation.dependencies, artifactPath, signal);
338
+ break;
339
+ case 'pip':
340
+ await this.installPip(implementation.dependencies, artifactPath, signal);
341
+ break;
342
+ case 'uv':
343
+ await this.installUv(implementation.dependencies, artifactPath, signal);
344
+ break;
345
+ case 'nix':
346
+ // Nix handles dependencies declaratively in shell.nix
347
+ await this.setupNix(implementation.dependencies, artifactPath);
348
+ break;
349
+ }
350
+ }
351
+ /**
352
+ * Install with npm
353
+ */
354
+ async installNpm(deps, artifactPath, signal) {
355
+ const packageJson = {
356
+ name: 'addon-tool',
357
+ version: '1.0.0',
358
+ dependencies: Object.fromEntries(deps.map(d => [d, 'latest']))
359
+ };
360
+ await fs.writeFile(join(artifactPath, 'package.json'), JSON.stringify(packageJson, null, 2));
361
+ await this.runCommand('npm', ['install'], artifactPath, signal);
362
+ }
363
+ /**
364
+ * Install with pip
365
+ */
366
+ async installPip(deps, artifactPath, signal) {
367
+ await fs.writeFile(join(artifactPath, 'requirements.txt'), deps.join('\n'));
368
+ await this.runCommand('pip3', ['install', '-r', 'requirements.txt'], artifactPath, signal);
369
+ }
370
+ /**
371
+ * Install with UV (fast Python package manager)
372
+ */
373
+ async installUv(deps, artifactPath, signal) {
374
+ // Check if UV is installed
375
+ try {
376
+ await execAsync('uv --version');
377
+ }
378
+ catch {
379
+ throw new Error('UV is not installed. Install with: curl -LsSf https://astral.sh/uv/install.sh | sh');
380
+ }
381
+ await fs.writeFile(join(artifactPath, 'requirements.txt'), deps.join('\n'));
382
+ // UV is 10-100x faster than pip
383
+ await this.runCommand('uv', ['pip', 'install', '-r', 'requirements.txt'], artifactPath, signal);
384
+ }
385
+ /**
386
+ * Setup Nix environment
387
+ */
388
+ async setupNix(deps, artifactPath) {
389
+ // Create shell.nix for declarative environment
390
+ const shellNix = `
391
+ { pkgs ? import <nixpkgs> {} }:
392
+
393
+ pkgs.mkShell {
394
+ buildInputs = with pkgs; [
395
+ ${deps.map(d => ` ${d}`).join('\n')}
396
+ ];
397
+
398
+ shellHook = ''
399
+ echo "Nix environment activated"
400
+ echo "Packages: ${deps.join(', ')}"
401
+ '';
402
+ }
403
+ `;
404
+ await fs.writeFile(join(artifactPath, 'shell.nix'), shellNix);
405
+ }
406
+ /**
407
+ * Write tool files to artifact
408
+ */
409
+ async writeToolFiles(implementation, uiConfig, artifactPath) {
410
+ // React artifact: build a static dir (index.html [+ dist/bundle.js, src/*]) served by http-server.
411
+ if (uiConfig?.framework === 'react') {
412
+ const result = await buildReactArtifact(artifactPath, {
413
+ code: implementation.code,
414
+ reactMode: uiConfig.reactMode,
415
+ additionalFiles: uiConfig.additionalFiles
416
+ });
417
+ console.log(`[CreateArtifactTool] React artifact built (${result.mode} mode)` +
418
+ (result.warnings.length ? ` — ${result.warnings.join('; ')}` : ''));
419
+ return;
420
+ }
421
+ // Detect if code is HTML (starts with <!DOCTYPE or <html)
422
+ const isHtml = implementation.code.trim().match(/^<!DOCTYPE|^<html/i);
423
+ let fileName;
424
+ let code = implementation.code;
425
+ if (isHtml) {
426
+ // HTML file - save as index.html
427
+ fileName = 'index.html';
428
+ }
429
+ else {
430
+ // Regular script file
431
+ fileName = implementation.language === 'javascript' ? 'index.js' : 'main.py';
432
+ // If UI framework specified, wrap code with framework boilerplate
433
+ if (uiConfig?.framework) {
434
+ code = this.wrapWithFramework(implementation.code, uiConfig.framework, implementation.language);
435
+ }
436
+ else {
437
+ // Post-process: Replace hardcoded ports with process.env.PORT for Node.js/Python servers
438
+ // This ensures artifacts use dynamically assigned ports instead of hardcoded values
439
+ if (implementation.language === 'javascript') {
440
+ // Replace common Node.js/Express server port patterns
441
+ code = code
442
+ // Match: server.listen(3000) or server.listen(3000, ...)
443
+ .replace(/\.listen\((\d{4,5})(\s*[,)])/g, '.listen(process.env.PORT || $1$2')
444
+ // Match: const PORT = 3000
445
+ .replace(/\b(const|let|var)\s+PORT\s*=\s*(\d{4,5})\b/g, '$1 PORT = process.env.PORT || $2')
446
+ // Match: app.listen(3000)
447
+ .replace(/app\.listen\((\d{4,5})(\s*[,)])/g, 'app.listen(process.env.PORT || $1$2');
448
+ console.log(`[CreateArtifactTool] Post-processed JavaScript code to use process.env.PORT`);
449
+ }
450
+ else if (implementation.language === 'python') {
451
+ // Replace common Flask/FastAPI port patterns
452
+ code = code
453
+ // Match: app.run(port=5000)
454
+ .replace(/\.run\((.*?)port\s*=\s*(\d{4,5})/g, (match, before, port) => {
455
+ return `.run(${before}port=int(os.getenv('PORT', ${port}))`;
456
+ })
457
+ // Match: uvicorn.run(..., port=8000)
458
+ .replace(/uvicorn\.run\((.*?)port\s*=\s*(\d{4,5})/g, (match, before, port) => {
459
+ return `uvicorn.run(${before}port=int(os.getenv('PORT', ${port}))`;
460
+ });
461
+ // Ensure os module is imported
462
+ if (!code.includes('import os')) {
463
+ code = 'import os\n' + code;
464
+ }
465
+ console.log(`[CreateArtifactTool] Post-processed Python code to use os.getenv('PORT')`);
466
+ }
467
+ }
468
+ }
469
+ const filePath = join(artifactPath, fileName);
470
+ await fs.writeFile(filePath, code);
471
+ }
472
+ /**
473
+ * Wrap user code with web framework boilerplate
474
+ */
475
+ wrapWithFramework(code, framework, language) {
476
+ if (language === 'javascript') {
477
+ switch (framework) {
478
+ case 'express':
479
+ return `
480
+ const express = require('express');
481
+ const app = express();
482
+ const PORT = process.env.PORT || 3000;
483
+
484
+ app.use(express.json());
485
+ app.use(express.static('public'));
486
+
487
+ // User code
488
+ ${code}
489
+
490
+ // Default route
491
+ app.get('/', (req, res) => {
492
+ res.send('<h1>Tool Running</h1><p>Port: ' + PORT + '</p>');
493
+ });
494
+
495
+ app.listen(PORT, () => {
496
+ console.log(\` Server running at http://localhost:\${PORT}\`);
497
+ });
498
+ `;
499
+ case 'nextjs':
500
+ return `
501
+ // Next.js API route wrapper
502
+ ${code}
503
+
504
+ export default async function handler(req, res) {
505
+ const result = await main(req.body || req.query);
506
+ res.status(200).json(result);
507
+ }
508
+ `;
509
+ default:
510
+ return code;
511
+ }
512
+ }
513
+ else {
514
+ // Python
515
+ switch (framework) {
516
+ case 'fastapi':
517
+ return `
518
+ from fastapi import FastAPI
519
+ from fastapi.responses import HTMLResponse
520
+ import uvicorn
521
+
522
+ app = FastAPI()
523
+
524
+ # User code
525
+ ${code}
526
+
527
+ @app.get("/", response_class=HTMLResponse)
528
+ async def root():
529
+ return "<h1>Tool Running</h1><p>Port: 8000</p>"
530
+
531
+ if __name__ == "__main__":
532
+ print(" Server running at http://localhost:8000")
533
+ uvicorn.run(app, host="0.0.0.0", port=8000)
534
+ `;
535
+ case 'flask':
536
+ return `
537
+ from flask import Flask, request, jsonify
538
+ app = Flask(__name__)
539
+
540
+ # User code
541
+ ${code}
542
+
543
+ @app.route('/')
544
+ def index():
545
+ return '<h1>Tool Running</h1><p>Port: 5000</p>'
546
+
547
+ if __name__ == '__main__':
548
+ print(' Server running at http://localhost:5000')
549
+ app.run(host='0.0.0.0', port=5000, debug=True)
550
+ `;
551
+ default:
552
+ return code;
553
+ }
554
+ }
555
+ }
556
+ /**
557
+ * Find an available port starting from a base port
558
+ */
559
+ async findAvailablePort(startPort = 3000) {
560
+ const net = await import('net');
561
+ const isPortAvailable = (port) => {
562
+ return new Promise((resolve) => {
563
+ const server = net.createServer();
564
+ server.once('error', () => resolve(false));
565
+ server.once('listening', () => {
566
+ server.close();
567
+ resolve(true);
568
+ });
569
+ server.listen(port);
570
+ });
571
+ };
572
+ let port = startPort;
573
+ while (port < startPort + 100) {
574
+ if (await isPortAvailable(port)) {
575
+ return port;
576
+ }
577
+ port++;
578
+ }
579
+ throw new Error(`No available ports found in range ${startPort}-${startPort + 99}`);
580
+ }
581
+ /**
582
+ * Launch persistent artifact with tmux integration
583
+ * Supports arbitrary languages and custom commands
584
+ */
585
+ async launchPersistentArtifact(artifactId, params, artifactPath, signal) {
586
+ let fileName;
587
+ let command;
588
+ let runtime;
589
+ // If user provides custom command, use it directly
590
+ if (params.implementation.command) {
591
+ command = params.implementation.command;
592
+ fileName = params.implementation.fileName || params.implementation.entryPoint || 'artifact';
593
+ runtime = `tmux+custom`;
594
+ }
595
+ else {
596
+ // Auto-detect based on language or content
597
+ const isHtml = params.implementation.code.trim().match(/^<!DOCTYPE|^<html/i);
598
+ const isReact = params.uiConfig?.framework === 'react';
599
+ if (isReact || isHtml || params.implementation.language === 'html') {
600
+ // HTML file - serve with http-server
601
+ fileName = params.implementation.fileName || 'index.html';
602
+ command = `npx http-server -p ${params.artifactConfig?.ports?.[0] || 3000} -c-1 --silent`;
603
+ runtime = 'tmux+http-server';
604
+ }
605
+ else if (params.implementation.language === 'javascript') {
606
+ fileName = params.implementation.fileName || 'index.js';
607
+ command = `node ${fileName}`;
608
+ runtime = 'tmux+node';
609
+ }
610
+ else if (params.implementation.language === 'python') {
611
+ fileName = params.implementation.fileName || 'main.py';
612
+ command = `python3 ${fileName}`;
613
+ runtime = 'tmux+python';
614
+ }
615
+ else if (params.implementation.language === 'rust') {
616
+ fileName = params.implementation.fileName || 'main.rs';
617
+ command = params.implementation.buildCommand
618
+ ? `${params.implementation.buildCommand} && cargo run --release`
619
+ : 'cargo run';
620
+ runtime = 'tmux+rust';
621
+ }
622
+ else if (params.implementation.language === 'go') {
623
+ fileName = params.implementation.fileName || 'main.go';
624
+ command = params.implementation.buildCommand
625
+ ? `${params.implementation.buildCommand} && ./artifact`
626
+ : `go run ${fileName}`;
627
+ runtime = 'tmux+go';
628
+ }
629
+ else if (params.implementation.language === 'shell') {
630
+ fileName = params.implementation.fileName || 'run.sh';
631
+ command = `chmod +x ${fileName} && ./${fileName}`;
632
+ runtime = 'tmux+shell';
633
+ }
634
+ else {
635
+ // Generic/other - use custom command or fail
636
+ fileName = params.implementation.fileName || 'artifact';
637
+ command = params.implementation.command || `echo "No command specified for language: ${params.implementation.language}"`;
638
+ runtime = 'tmux+other';
639
+ }
640
+ }
641
+ // Find an available port dynamically
642
+ // Port 4000 = API server, Port 4001 = Dashboard
643
+ // Artifacts start from port 3000 and increment (3000, 3001, 3002, etc.)
644
+ const requestedPort = params.artifactConfig?.ports?.[0] || 3000;
645
+ const port = await this.findAvailablePort(requestedPort);
646
+ const url = `http://localhost:${port}`;
647
+ // Update command with actual port if it's http-server or contains port reference
648
+ if (command.includes('http-server')) {
649
+ command = command.replace(/\-p \d+/, `-p ${port}`);
650
+ }
651
+ // For Node.js/JavaScript artifacts, inject PORT environment variable
652
+ if (runtime === 'tmux+node' || params.implementation.language === 'javascript') {
653
+ command = `PORT=${port} ${command}`;
654
+ }
655
+ // For Python artifacts, inject PORT environment variable
656
+ if (runtime === 'tmux+python' || params.implementation.language === 'python') {
657
+ command = `PORT=${port} ${command}`;
658
+ }
659
+ // Initialize tmux manager
660
+ const tmuxManager = TmuxManager.getInstance();
661
+ // Check if tmux is available
662
+ const tmuxAvailable = await tmuxManager.isAvailable();
663
+ if (!tmuxAvailable) {
664
+ throw new Error('tmux is not installed. Persistent mode requires tmux for session management.');
665
+ }
666
+ // Create tmux session with artifact ID as session name
667
+ const tmuxSessionId = `artifact-${artifactId.substring(0, 8)}`;
668
+ await tmuxManager.createSession(tmuxSessionId, artifactPath);
669
+ // Send command to tmux session
670
+ await tmuxManager.sendKeys(tmuxSessionId, command);
671
+ // Wait a moment for process to start
672
+ await new Promise(resolve => setTimeout(resolve, 1000));
673
+ // Save tmux session metadata for dashboard
674
+ const sessionPersistence = new SessionPersistence(this.workingDirectory);
675
+ await sessionPersistence.saveSession({
676
+ sessionId: tmuxSessionId,
677
+ created: new Date(),
678
+ lastUsed: new Date(),
679
+ cwd: artifactPath,
680
+ env: {}
681
+ });
682
+ const session = {
683
+ id: artifactId,
684
+ name: params.name,
685
+ tmuxSessionId,
686
+ url,
687
+ port,
688
+ mode: params.mode || 'persistent',
689
+ startTime: new Date(),
690
+ lastActivity: new Date(),
691
+ watchers: [],
692
+ path: artifactPath // served/built dir (the workspace) — edits + rebuilds target this
693
+ };
694
+ // Store session in memory
695
+ activeArtifactes.set(artifactId, session);
696
+ // Store in unified artifact registry
697
+ const artifactRegistry = ArtifactRegistry.getInstance(this.workingDirectory);
698
+ await artifactRegistry.register({
699
+ id: artifactId,
700
+ name: params.name,
701
+ type: 'web-app',
702
+ runtime,
703
+ created: new Date().toISOString(),
704
+ lastUsed: new Date().toISOString(),
705
+ workspaceDir: artifactPath,
706
+ entryPoint: fileName,
707
+ mode: params.mode || 'persistent',
708
+ port,
709
+ url,
710
+ tmuxSession: tmuxSessionId,
711
+ description: params.description
712
+ });
713
+ // Also store in sandbox registry for backwards compatibility
714
+ const sandboxRegistry = SandboxRegistry.getInstance(this.workingDirectory);
715
+ await sandboxRegistry.register({
716
+ id: artifactId,
717
+ name: params.name,
718
+ port,
719
+ url,
720
+ pid: undefined, // No PID for tmux sessions, use tmux session ID instead
721
+ mode: params.mode || 'persistent',
722
+ startTime: new Date().toISOString(),
723
+ lastActivity: new Date().toISOString(),
724
+ path: artifactPath
725
+ });
726
+ // Emit artifact created event
727
+ broadcaster.emitSandboxEvent({
728
+ type: 'sandbox-created',
729
+ sandboxId: session.id,
730
+ timestamp: Date.now(),
731
+ data: {
732
+ name: session.name,
733
+ url: session.url,
734
+ mode: session.mode,
735
+ port: session.port,
736
+ tmuxSession: tmuxSessionId
737
+ }
738
+ });
739
+ // Start view server if not already running. ENABLE_DASHBOARD is the master
740
+ // switch for the dashboard system — when off, skip silently (the sandbox
741
+ // itself works; only the web viewer is unavailable).
742
+ if (SandboxViewServer.isEnabled() && !viewServer.isServerRunning()) {
743
+ await viewServer.start().catch(err => {
744
+ console.warn('Could not start view server:', err);
745
+ });
746
+ }
747
+ // Setup hot reload if dev mode
748
+ if (params.mode === 'dev' && params.devConfig?.hotReload) {
749
+ await this.setupHotReload(session, artifactPath, fileName, command, params.enableVisualFeedback);
750
+ }
751
+ // Open browser if requested
752
+ if (params.devConfig?.openBrowser) {
753
+ await this.openBrowser(url);
754
+ }
755
+ // Initialize visual feedback if requested
756
+ if (params.enableVisualFeedback) {
757
+ await this.initializeVisualFeedback(session, params);
758
+ }
759
+ // Log tmux session info
760
+ console.log(`[${params.name}] Running in tmux session: ${tmuxSessionId}`);
761
+ console.log(`[${params.name}] Access at: ${url}`);
762
+ console.log(`[${params.name}] View output: tmux attach -t ${tmuxSessionId}`);
763
+ return session;
764
+ }
765
+ /**
766
+ * Setup hot reload with file watching
767
+ */
768
+ async setupHotReload(session, artifactPath, fileName, command, enableVisualFeedback) {
769
+ const filePath = join(artifactPath, fileName);
770
+ const watcher = watch(filePath, async (eventType) => {
771
+ if (eventType === 'change') {
772
+ console.log(` File changed, reloading ${session.name}...`);
773
+ // Emit file changed event
774
+ broadcaster.emitFileChange(session.id, fileName, 'modified');
775
+ // Emit hot reload triggered event
776
+ broadcaster.emitHotReload(session.id, fileName);
777
+ // Kill old process
778
+ session.process?.kill();
779
+ // Start new process
780
+ const newProcess = spawn(command, [fileName], {
781
+ cwd: artifactPath,
782
+ stdio: ['pipe', 'pipe', 'pipe']
783
+ });
784
+ session.process = newProcess;
785
+ session.lastActivity = new Date();
786
+ console.log(`[OK] ${session.name} reloaded`);
787
+ // Emit process restarted event
788
+ broadcaster.emitProcessRestart(session.id, 'Hot reload triggered');
789
+ // Capture new visual snapshot after reload
790
+ if (enableVisualFeedback && session.url) {
791
+ // Wait for server to restart
792
+ await new Promise(resolve => setTimeout(resolve, 2000));
793
+ try {
794
+ console.log(` Capturing updated visual snapshot...`);
795
+ session.visualSnapshot = await visualBridge.captureSnapshot(session.url);
796
+ console.log(`[OK] Visual snapshot updated`);
797
+ // Emit screenshot captured event
798
+ broadcaster.emitScreenshot(session.id, session.visualSnapshot.screenshot, session.url);
799
+ }
800
+ catch (error) {
801
+ console.warn(`⚠ Could not update visual snapshot: ${error}`);
802
+ broadcaster.emitError(session.id, error);
803
+ }
804
+ }
805
+ }
806
+ });
807
+ session.watchers = [watcher];
808
+ }
809
+ /**
810
+ * Initialize visual feedback bridge
811
+ */
812
+ async initializeVisualFeedback(session, params) {
813
+ try {
814
+ // Initialize Playwright browser
815
+ await visualBridge.initialize();
816
+ // Opt-in React introspection: inject the fiber pre-load BEFORE the first
817
+ // navigation so the initial snapshot carries the framework report.
818
+ if (params.enableReactIntrospection) {
819
+ await visualBridge.enableReactIntrospection();
820
+ }
821
+ // Wait for server to be ready (give it 2 seconds)
822
+ await new Promise(resolve => setTimeout(resolve, 2000));
823
+ // Capture initial snapshot
824
+ if (session.url) {
825
+ console.log(` Capturing visual snapshot of ${params.name}...`);
826
+ session.visualSnapshot = await visualBridge.captureSnapshot(session.url);
827
+ console.log(`[OK] Visual snapshot captured (${session.visualSnapshot.screenshot.length} bytes)`);
828
+ // Emit screenshot captured event
829
+ broadcaster.emitScreenshot(session.id, session.visualSnapshot.screenshot, session.url);
830
+ }
831
+ }
832
+ catch (error) {
833
+ console.warn(`⚠ Could not capture visual snapshot: ${error}`);
834
+ broadcaster.emitError(session.id, error);
835
+ }
836
+ }
837
+ /**
838
+ * Open browser automatically
839
+ */
840
+ async openBrowser(url) {
841
+ const platform = process.platform;
842
+ let command;
843
+ if (platform === 'darwin') {
844
+ command = `open ${url}`;
845
+ }
846
+ else if (platform === 'win32') {
847
+ command = `start ${url}`;
848
+ }
849
+ else {
850
+ command = `xdg-open ${url}`;
851
+ }
852
+ try {
853
+ await execAsync(command);
854
+ console.log(` Opened browser at ${url}`);
855
+ }
856
+ catch (error) {
857
+ console.warn(`Could not open browser: ${error}`);
858
+ }
859
+ }
860
+ /**
861
+ * Execute tool in oneshot mode
862
+ */
863
+ async executeOneshot(implementation, artifactPath, signal) {
864
+ const fileName = implementation.language === 'javascript' ? 'index.js' : 'main.py';
865
+ const command = implementation.language === 'javascript' ? 'node' : 'python3';
866
+ const result = await this.runCommand(command, [fileName], artifactPath, signal);
867
+ return {
868
+ success: result.exitCode === 0,
869
+ output: result.stdout
870
+ };
871
+ }
872
+ /**
873
+ * Run command and capture output
874
+ */
875
+ async runCommand(command, args, cwd, signal) {
876
+ return new Promise((resolve) => {
877
+ const child = spawn(command, args, { cwd });
878
+ let stdout = '';
879
+ let stderr = '';
880
+ child.stdout?.on('data', (data) => {
881
+ stdout += data.toString();
882
+ });
883
+ child.stderr?.on('data', (data) => {
884
+ stderr += data.toString();
885
+ });
886
+ child.on('close', (exitCode) => {
887
+ resolve({ stdout, stderr, exitCode: exitCode || 0 });
888
+ });
889
+ signal.addEventListener('abort', () => {
890
+ child.kill();
891
+ });
892
+ });
893
+ }
894
+ /**
895
+ * Format output for persistent/dev artifact
896
+ */
897
+ formatPersistentOutput(session, params, originalName) {
898
+ const lines = [];
899
+ lines.push(`# ${params.name} - ${params.mode?.toUpperCase()} MODE`);
900
+ lines.push('');
901
+ // Notify if name was auto-sanitized
902
+ if (originalName && originalName !== params.name) {
903
+ lines.push(`_Note: Name auto-sanitized from "${originalName}" to "${params.name}" (filesystem-safe format)_`);
904
+ lines.push('');
905
+ }
906
+ lines.push(`**Status**: Running`);
907
+ lines.push(`**URL**: ${session.url}`);
908
+ lines.push(`**Port**: ${session.port}`);
909
+ lines.push(`**Artifact ID**: ${session.id}`);
910
+ lines.push('');
911
+ if (params.mode === 'dev') {
912
+ lines.push('## Dev Mode Features');
913
+ lines.push('');
914
+ if (params.devConfig?.hotReload) {
915
+ lines.push('[OK] Hot reload enabled');
916
+ }
917
+ if (params.devConfig?.openBrowser) {
918
+ lines.push('[OK] Browser auto-opened');
919
+ }
920
+ if (params.devConfig?.liveBridge) {
921
+ lines.push('[OK] Live WebSocket updates');
922
+ }
923
+ lines.push('');
924
+ }
925
+ lines.push('## Package Manager');
926
+ lines.push('');
927
+ lines.push(`**Manager**: ${params.implementation.packageManager || 'default'}`);
928
+ if (params.implementation.dependencies) {
929
+ lines.push(`**Dependencies**: ${params.implementation.dependencies.join(', ')}`);
930
+ }
931
+ lines.push('');
932
+ lines.push('## Access');
933
+ lines.push('');
934
+ lines.push(`**Artifact URL**: ${session.url}`);
935
+ lines.push(`**View Dashboard**: ${viewServer.getViewUrl(session.id)}`);
936
+ lines.push('');
937
+ lines.push('The dashboard provides:');
938
+ lines.push('- Live preview of artifact UI');
939
+ lines.push('- Real-time console logs');
940
+ lines.push('- Screenshot history');
941
+ lines.push('- Network request monitoring');
942
+ lines.push('');
943
+ if (params.mode === 'dev') {
944
+ lines.push('Edit files in the artifact to see live updates in both the artifact and dashboard!');
945
+ }
946
+ // Include visual snapshot if available
947
+ if (session.visualSnapshot) {
948
+ lines.push('');
949
+ lines.push('---');
950
+ lines.push('');
951
+ lines.push('## Visual Snapshot');
952
+ lines.push('');
953
+ lines.push('The model can now SEE its creation!');
954
+ lines.push('');
955
+ lines.push(visualBridge.formatForModel(session.visualSnapshot));
956
+ lines.push('');
957
+ lines.push('**Note**: The model can use this visual feedback to iterate and improve the tool.');
958
+ lines.push('');
959
+ }
960
+ return lines.join('\n');
961
+ }
962
+ /**
963
+ * Get active artifact by ID
964
+ */
965
+ static getActiveArtifact(id) {
966
+ return activeArtifactes.get(id);
967
+ }
968
+ /**
969
+ * List all active artifactes
970
+ */
971
+ static listActiveArtifactes() {
972
+ return Array.from(activeArtifactes.values());
973
+ }
974
+ /**
975
+ * Get all active artifactes (alias for listActiveArtifactes)
976
+ */
977
+ static getActiveArtifactes() {
978
+ return Array.from(activeArtifactes.values());
979
+ }
980
+ /**
981
+ * Stop a artifact
982
+ */
983
+ static stopArtifact(id) {
984
+ const session = activeArtifactes.get(id);
985
+ if (!session)
986
+ return false;
987
+ session.process?.kill();
988
+ session.watchers?.forEach(w => w.close());
989
+ activeArtifactes.delete(id);
990
+ return true;
991
+ }
992
+ /**
993
+ * Get visual snapshot for a artifact
994
+ */
995
+ static getVisualSnapshot(id) {
996
+ const session = activeArtifactes.get(id);
997
+ return session?.visualSnapshot;
998
+ }
999
+ /**
1000
+ * Capture fresh visual snapshot for a running artifact
1001
+ */
1002
+ static async refreshVisualSnapshot(id) {
1003
+ const session = activeArtifactes.get(id);
1004
+ if (!session || !session.url)
1005
+ return null;
1006
+ try {
1007
+ await visualBridge.initialize();
1008
+ session.visualSnapshot = await visualBridge.captureSnapshot(session.url);
1009
+ return session.visualSnapshot;
1010
+ }
1011
+ catch (error) {
1012
+ console.error(`Failed to refresh visual snapshot: ${error}`);
1013
+ return null;
1014
+ }
1015
+ }
1016
+ // ===== BACKWARDS COMPATIBILITY ALIASES (for sandbox tools) =====
1017
+ /**
1018
+ * @deprecated Use getActiveArtifact instead
1019
+ */
1020
+ static getActiveSandbox(id) {
1021
+ return this.getActiveArtifact(id);
1022
+ }
1023
+ /**
1024
+ * @deprecated Use listActiveArtifactes instead
1025
+ */
1026
+ static getActiveSandboxes() {
1027
+ return this.listActiveArtifactes();
1028
+ }
1029
+ /**
1030
+ * @deprecated Use listActiveArtifactes instead
1031
+ */
1032
+ static listActiveSandboxes() {
1033
+ return this.listActiveArtifactes();
1034
+ }
1035
+ /**
1036
+ * @deprecated Use stopArtifact instead
1037
+ */
1038
+ static stopSandbox(id) {
1039
+ return this.stopArtifact(id);
1040
+ }
1041
+ }
1042
+ //# sourceMappingURL=CreateArtifactTool.js.map