@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,775 @@
1
+ import express from 'express';
2
+ import { createServer } from 'http';
3
+ import { Server as SocketIOServer } from 'socket.io';
4
+ import { broadcaster } from './SandboxEventBroadcaster.js';
5
+ import { CreateArtifactToolExecutor } from './CreateArtifactTool.js';
6
+ import { ArtifactRegistry } from '../../utils/ArtifactRegistry.js';
7
+ /**
8
+ * SandboxViewServer - Real-time sandbox viewing server
9
+ *
10
+ * Provides a web-based dashboard for users to view sandbox operations in real-time.
11
+ * Features:
12
+ * - Embedded iframe showing sandbox UI
13
+ * - Live console logs via WebSocket
14
+ * - File change notifications
15
+ * - Screenshot gallery with timeline
16
+ * - Network request monitoring
17
+ * - Multi-sandbox management
18
+ *
19
+ * Architecture:
20
+ * - Express HTTP server serves HTML dashboard
21
+ * - Socket.io WebSocket server broadcasts events
22
+ * - SandboxEventBroadcaster provides events
23
+ * - Each sandbox gets a unique room for isolated events
24
+ *
25
+ * User Flow:
26
+ * 1. Model creates sandbox → Server auto-starts (if not running)
27
+ * 2. Server emits view URL: http://localhost:4001/sandbox/{sandboxId}
28
+ * 3. User opens URL in browser
29
+ * 4. Dashboard loads with embedded iframe of sandbox UI
30
+ * 5. WebSocket subscribes to sandbox events
31
+ * 6. As model interacts, user sees live updates:
32
+ * - Console logs appear in sidebar
33
+ * - Files changed trigger reload notifications
34
+ * - Screenshots appear in gallery
35
+ * - Network requests show in timeline
36
+ *
37
+ * Example Usage:
38
+ * ```
39
+ * // Start server
40
+ * const server = SandboxViewServer.getInstance();
41
+ * await server.start(4001);
42
+ *
43
+ * // View URL auto-included in CreateAddon output
44
+ * // User opens: http://localhost:4001/sandbox/abc-123
45
+ *
46
+ * // Server automatically streams events via WebSocket
47
+ * ```
48
+ */
49
+ export class SandboxViewServer {
50
+ static instance;
51
+ app;
52
+ httpServer;
53
+ io;
54
+ port = Number(process.env.DASHBOARD_PORT) || 4001;
55
+ isRunning = false;
56
+ constructor() {
57
+ this.app = express();
58
+ this.httpServer = createServer(this.app);
59
+ this.io = new SocketIOServer(this.httpServer, {
60
+ cors: {
61
+ origin: '*',
62
+ methods: ['GET', 'POST']
63
+ }
64
+ });
65
+ this.setupRoutes();
66
+ this.setupWebSocket();
67
+ }
68
+ /**
69
+ * Get singleton instance
70
+ */
71
+ static getInstance() {
72
+ if (!SandboxViewServer.instance) {
73
+ SandboxViewServer.instance = new SandboxViewServer();
74
+ }
75
+ return SandboxViewServer.instance;
76
+ }
77
+ /**
78
+ * Master switch for the dashboard/view-server system (tmux viewer + sandbox
79
+ * viewer share this one server). When false, the dashboard NEVER binds a port —
80
+ * not at server boot and not via the tools' demand-start paths.
81
+ */
82
+ static isEnabled() {
83
+ return process.env.ENABLE_DASHBOARD === 'true';
84
+ }
85
+ /**
86
+ * Agent-facing guidance for when the dashboard is disabled or fails to start.
87
+ * Surfaced through tool results so the model knows exactly how to proceed.
88
+ */
89
+ static DISABLED_NOTICE = 'Tmux/sandbox web dashboard is DISABLED (ENABLE_DASHBOARD is not "true"). ' +
90
+ 'Live view URLs are unavailable. To use the dashboard: set ENABLE_DASHBOARD=true ' +
91
+ 'in the .env (or environment) and restart the harness. If it still fails to start ' +
92
+ 'after enabling, check for a port conflict on DASHBOARD_PORT (default 4001 — the ' +
93
+ 'server retries up to 10 consecutive ports before giving up).';
94
+ /**
95
+ * Start the server with dynamic port conflict resolution
96
+ */
97
+ async start(startPort) {
98
+ if (!SandboxViewServer.isEnabled()) {
99
+ throw new Error(SandboxViewServer.DISABLED_NOTICE);
100
+ }
101
+ if (this.isRunning) {
102
+ console.log(` View server already running on http://localhost:${this.port}`);
103
+ return;
104
+ }
105
+ // Dashboard port: DASHBOARD_PORT env wins, then the caller's arg, then 4001.
106
+ // Try starting on that port, with automatic retry on next port if occupied.
107
+ let currentPort = Number(process.env.DASHBOARD_PORT) || startPort || 4001;
108
+ const maxAttempts = 10; // Try up to 10 ports
109
+ let lastError = null;
110
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
111
+ try {
112
+ await this.tryStartOnPort(currentPort);
113
+ // Success! Server started
114
+ this.port = currentPort;
115
+ this.isRunning = true;
116
+ console.log(` Sandbox View Server started on http://localhost:${currentPort}`);
117
+ console.log(` - Dashboard: http://localhost:${currentPort}/`);
118
+ console.log(` - Sandbox view: http://localhost:${currentPort}/sandbox/{sandboxId}`);
119
+ return;
120
+ }
121
+ catch (error) {
122
+ if (error.code === 'EADDRINUSE') {
123
+ lastError = error;
124
+ console.log(`Port ${currentPort} in use, trying ${currentPort + 1}...`);
125
+ currentPort++;
126
+ }
127
+ else {
128
+ // Non-port-conflict error, throw immediately
129
+ console.error(`[ERROR] Failed to start view server:`, error);
130
+ throw error;
131
+ }
132
+ }
133
+ }
134
+ // If we get here, we exhausted all attempts
135
+ const errorMsg = `Failed to start view server after ${maxAttempts} attempts (ports ${startPort}-${currentPort - 1})`;
136
+ console.error(`[ERROR] ${errorMsg}`);
137
+ throw new Error(errorMsg);
138
+ }
139
+ /**
140
+ * Try to start server on a specific port
141
+ */
142
+ async tryStartOnPort(port) {
143
+ return new Promise((resolve, reject) => {
144
+ const onListening = () => {
145
+ cleanup();
146
+ resolve();
147
+ };
148
+ const onError = (error) => {
149
+ cleanup();
150
+ reject(error);
151
+ };
152
+ const cleanup = () => {
153
+ this.httpServer.removeListener('listening', onListening);
154
+ this.httpServer.removeListener('error', onError);
155
+ };
156
+ this.httpServer.once('listening', onListening);
157
+ this.httpServer.once('error', onError);
158
+ this.httpServer.listen(port, '0.0.0.0');
159
+ });
160
+ }
161
+ /**
162
+ * Stop the server
163
+ */
164
+ async stop() {
165
+ if (!this.isRunning) {
166
+ return;
167
+ }
168
+ return new Promise((resolve) => {
169
+ this.io.close();
170
+ this.httpServer.close(() => {
171
+ this.isRunning = false;
172
+ console.log(` View server stopped`);
173
+ resolve();
174
+ });
175
+ });
176
+ }
177
+ /**
178
+ * Get view URL for a sandbox
179
+ */
180
+ getViewUrl(sandboxId) {
181
+ return `http://localhost:${this.port}/sandbox/${sandboxId}`;
182
+ }
183
+ /**
184
+ * Setup HTTP routes
185
+ */
186
+ setupRoutes() {
187
+ // Serve dashboard homepage
188
+ this.app.get('/', (req, res) => {
189
+ res.send(this.generateDashboardHTML());
190
+ });
191
+ // Serve sandbox-specific view
192
+ this.app.get('/sandbox/:sandboxId', (req, res) => {
193
+ const sandboxId = req.params.sandboxId;
194
+ const session = CreateArtifactToolExecutor.getActiveSandbox(sandboxId);
195
+ if (!session) {
196
+ res.status(404).send(this.generate404HTML(sandboxId));
197
+ return;
198
+ }
199
+ res.send(this.generateSandboxViewHTML(session));
200
+ });
201
+ // API: Get sandbox list (from persistent registry)
202
+ this.app.get('/api/sandboxes', (req, res) => {
203
+ try {
204
+ const registry = ArtifactRegistry.getInstance(process.env.PROJECT_ROOT || process.cwd());
205
+ const artifacts = registry.getAll();
206
+ res.json({
207
+ sandboxes: artifacts.map(a => ({
208
+ id: a.id,
209
+ name: a.name,
210
+ url: a.url,
211
+ mode: a.mode,
212
+ status: 'running', // Assume running if in registry (could check PID)
213
+ createdAt: a.created,
214
+ lastActivity: a.lastUsed
215
+ }))
216
+ });
217
+ }
218
+ catch (error) {
219
+ console.error('Failed to get artifacts from registry:', error);
220
+ // Fallback to in-memory
221
+ const sessions = CreateArtifactToolExecutor.getActiveSandboxes();
222
+ res.json({
223
+ sandboxes: sessions.map(s => ({
224
+ id: s.id,
225
+ name: s.name,
226
+ url: s.url,
227
+ mode: s.mode,
228
+ status: s.process ? 'running' : 'stopped',
229
+ createdAt: s.startTime,
230
+ lastActivity: s.lastActivity
231
+ }))
232
+ });
233
+ }
234
+ });
235
+ // API: Get event history
236
+ this.app.get('/api/sandbox/:sandboxId/events', (req, res) => {
237
+ const sandboxId = req.params.sandboxId;
238
+ const limitParam = req.query.limit;
239
+ const limit = limitParam ? parseInt(limitParam) : undefined;
240
+ const events = broadcaster.getHistory(sandboxId, limit);
241
+ res.json({ events });
242
+ });
243
+ // Artifact lifecycle API endpoints
244
+ this.app.post('/api/artifacts/:id/stop', async (req, res) => {
245
+ try {
246
+ const id = req.params.id;
247
+ if (!id) {
248
+ res.status(400).json({ success: false, message: 'Artifact ID is required' });
249
+ return;
250
+ }
251
+ const stopped = CreateArtifactToolExecutor.stopSandbox(id);
252
+ if (stopped) {
253
+ res.json({ success: true, message: 'Artifact stopped successfully' });
254
+ }
255
+ else {
256
+ res.status(404).json({ success: false, message: 'Artifact not found or already stopped' });
257
+ }
258
+ }
259
+ catch (error) {
260
+ res.status(500).json({ success: false, message: error.message });
261
+ }
262
+ });
263
+ this.app.post('/api/artifacts/:id/restart', async (req, res) => {
264
+ try {
265
+ const id = req.params.id;
266
+ if (!id) {
267
+ res.status(400).json({ success: false, message: 'Artifact ID is required' });
268
+ return;
269
+ }
270
+ // Get artifact metadata from registry
271
+ const registry = ArtifactRegistry.getInstance(process.env.PROJECT_ROOT || process.cwd());
272
+ await registry.initialize();
273
+ const metadata = await registry.get(id);
274
+ if (!metadata) {
275
+ res.status(404).json({ success: false, message: 'Artifact not found in registry' });
276
+ return;
277
+ }
278
+ // Stop the artifact first
279
+ const stopped = CreateArtifactToolExecutor.stopSandbox(id);
280
+ if (!stopped) {
281
+ console.warn(`Artifact ${id} was not running, proceeding with restart anyway`);
282
+ }
283
+ // Wait a moment for cleanup
284
+ await new Promise(resolve => setTimeout(resolve, 1000));
285
+ // Find a new available port dynamically by checking registry
286
+ // Use only ports that have external mappings in .replit configuration
287
+ // Infrastructure ports (reserved): 4000 (server), 4001 (dashboard)
288
+ // Available artifact ports with external mappings:
289
+ const ACCESSIBLE_PORTS = [
290
+ 3001, // → 6800
291
+ 3004, // → 4200
292
+ 3005, // → 8081
293
+ 3011, // → 9000
294
+ 4002, // → 3002
295
+ 4003, // → 3003
296
+ 4004, // → 5173
297
+ 4005, // → 5000
298
+ 5000, // → 80
299
+ 8000, // → 8008
300
+ 8080, // → 8080
301
+ 24678, // → 8000
302
+ 36655, // → 6000
303
+ 46323 // → 8099
304
+ ];
305
+ const usedPorts = new Set(registry.getUsedPorts());
306
+ let newPort = null;
307
+ for (const port of ACCESSIBLE_PORTS) {
308
+ if (!usedPorts.has(port)) {
309
+ newPort = port;
310
+ break;
311
+ }
312
+ }
313
+ if (newPort === null) {
314
+ res.status(500).json({
315
+ success: false,
316
+ message: `All ${ACCESSIBLE_PORTS.length} accessible ports are currently in use. Stop an artifact first to free up a port.`
317
+ });
318
+ return;
319
+ }
320
+ console.log(` Restarting artifact ${id} on port ${newPort} (was ${metadata.port})`);
321
+ // Restart based on runtime type
322
+ const TmuxManager = (await import('../../utils/TmuxManager.js')).TmuxManager;
323
+ const tmux = TmuxManager.getInstance();
324
+ if (metadata.tmuxSession) {
325
+ console.log(`[Restart] Processing tmux artifact ${id}`);
326
+ console.log(`[Restart] Session name: ${metadata.tmuxSession}`);
327
+ console.log(`[Restart] Workspace: ${metadata.workspaceDir}`);
328
+ console.log(`[Restart] Runtime: ${metadata.runtime}`);
329
+ console.log(`[Restart] Entry point: ${metadata.entryPoint}`);
330
+ // Kill old tmux session if it exists
331
+ const exists = await tmux.sessionExists(metadata.tmuxSession);
332
+ console.log(`[Restart] Session exists: ${exists}`);
333
+ if (exists) {
334
+ console.log(`[Restart] Killing existing session...`);
335
+ await tmux.killSession(metadata.tmuxSession);
336
+ console.log(`[Restart] Session killed`);
337
+ }
338
+ // Create new tmux session
339
+ console.log(`[Restart] Creating new tmux session...`);
340
+ try {
341
+ await tmux.createSession(metadata.tmuxSession, metadata.workspaceDir);
342
+ console.log(`[Restart] [OK] Tmux session created successfully`);
343
+ }
344
+ catch (err) {
345
+ console.error(`[Restart] [ERROR] Failed to create tmux session:`, err.message);
346
+ throw new Error(`Tmux session creation failed: ${err.message}`);
347
+ }
348
+ // Verify session was created
349
+ const sessionCreated = await tmux.sessionExists(metadata.tmuxSession);
350
+ console.log(`[Restart] Session verification: ${sessionCreated}`);
351
+ if (!sessionCreated) {
352
+ throw new Error('Tmux session was not created successfully');
353
+ }
354
+ // Start the appropriate server based on runtime with NEW PORT
355
+ let startCommand = '';
356
+ if (metadata.runtime === 'tmux+http-server') {
357
+ startCommand = `npx http-server -p ${newPort}`;
358
+ }
359
+ else if (metadata.runtime === 'tmux+node') {
360
+ startCommand = `PORT=${newPort} node ${metadata.entryPoint}`;
361
+ }
362
+ else if (metadata.runtime === 'tmux+python') {
363
+ startCommand = `PORT=${newPort} python ${metadata.entryPoint}`;
364
+ }
365
+ else {
366
+ // For tmux+custom, tmux+shell, etc., just start a shell
367
+ startCommand = 'bash';
368
+ }
369
+ console.log(`[Restart] Start command: ${startCommand}`);
370
+ console.log(`[Restart] Sending keys to tmux session...`);
371
+ try {
372
+ await tmux.sendKeys(metadata.tmuxSession, `cd ${metadata.workspaceDir} && ${startCommand}`);
373
+ console.log(`[Restart] [OK] Command sent to tmux`);
374
+ }
375
+ catch (err) {
376
+ console.error(`[Restart] [ERROR] Failed to send keys:`, err.message);
377
+ throw new Error(`Failed to send command to tmux: ${err.message}`);
378
+ }
379
+ // Wait a moment for the process to start
380
+ await new Promise(resolve => setTimeout(resolve, 2000));
381
+ // Update registry with new port and URL
382
+ await registry.update(id, {
383
+ port: newPort,
384
+ url: `http://localhost:${newPort}`,
385
+ lastUsed: new Date().toISOString()
386
+ });
387
+ res.json({
388
+ success: true,
389
+ message: `Artifact "${metadata.name}" restarted on NEW PORT ${newPort} (was ${metadata.port})`
390
+ });
391
+ }
392
+ else {
393
+ // Non-tmux artifacts (process, docker) - spawn new process
394
+ const { exec } = await import('child_process');
395
+ const { promisify } = await import('util');
396
+ const execAsync = promisify(exec);
397
+ const command = `npx http-server ${metadata.workspaceDir} -p ${newPort} &`;
398
+ await execAsync(command, { cwd: metadata.workspaceDir });
399
+ // Update registry with new port and URL
400
+ await registry.update(id, {
401
+ port: newPort,
402
+ url: `http://localhost:${newPort}`,
403
+ lastUsed: new Date().toISOString()
404
+ });
405
+ res.json({
406
+ success: true,
407
+ message: `Artifact "${metadata.name}" restarted on NEW PORT ${newPort} (was ${metadata.port})`
408
+ });
409
+ }
410
+ }
411
+ catch (error) {
412
+ console.error('Restart error:', error);
413
+ res.status(500).json({ success: false, message: error.message });
414
+ }
415
+ });
416
+ // Health check
417
+ this.app.get('/health', (req, res) => {
418
+ res.json({ status: 'ok', uptime: process.uptime() });
419
+ });
420
+ }
421
+ /**
422
+ * Setup WebSocket event streaming
423
+ */
424
+ setupWebSocket() {
425
+ this.io.on('connection', (socket) => {
426
+ console.log(` Client connected: ${socket.id}`);
427
+ // Client subscribes to a specific sandbox
428
+ socket.on('subscribe', (sandboxId) => {
429
+ console.log(` Client ${socket.id} subscribed to sandbox: ${sandboxId}`);
430
+ socket.join(sandboxId);
431
+ // Send recent event history
432
+ const history = broadcaster.getHistory(sandboxId, 50);
433
+ socket.emit('history', { events: history });
434
+ });
435
+ // Client unsubscribes
436
+ socket.on('unsubscribe', (sandboxId) => {
437
+ console.log(` Client ${socket.id} unsubscribed from sandbox: ${sandboxId}`);
438
+ socket.leave(sandboxId);
439
+ });
440
+ // Disconnect
441
+ socket.on('disconnect', () => {
442
+ console.log(` Client disconnected: ${socket.id}`);
443
+ });
444
+ });
445
+ // Listen to broadcaster events and forward to WebSocket clients
446
+ broadcaster.subscribeToAll((event) => {
447
+ // Emit to all clients in the sandbox's room
448
+ this.io.to(event.sandboxId).emit(event.type, event);
449
+ });
450
+ }
451
+ /**
452
+ * Generate multi-sandbox dashboard HTML
453
+ */
454
+ generateDashboardHTML() {
455
+ return `
456
+ <!DOCTYPE html>
457
+ <html lang="en">
458
+ <head>
459
+ <meta charset="UTF-8">
460
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
461
+ <title>Cortex Intelligence // Sandboxes</title>
462
+ <link rel="preconnect" href="https://fonts.googleapis.com">
463
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
464
+ <link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;500;700&family=Oxygen+Mono&display=swap" rel="stylesheet">
465
+ <style>
466
+ :root {
467
+ --cx-primary: #4a90d9; --cx-primary-rgb: 74, 144, 217;
468
+ --cx-positive: #4ade80; --cx-positive-rgb: 74, 222, 128;
469
+ --cx-negative: #f87171; --cx-negative-rgb: 248, 113, 113;
470
+ --cx-warning: #fbbf24;
471
+ --cx-bg: #0f172a; --cx-bg2: #1e293b; --cx-bg3: #253347; --cx-bg4: #2d3d53;
472
+ --cx-text: #e2e8f0; --cx-text2: #b0b8c4; --cx-muted: #94a3b8; --cx-heading: #f8fafc;
473
+ --cx-border: #334155; --cx-border2: #283548;
474
+ --cx-radius: 6px;
475
+ --cx-font: 'Oxygen Mono', monospace;
476
+ }
477
+ * { margin: 0; padding: 0; box-sizing: border-box; }
478
+ body { font-family: var(--cx-font); font-size: 12px; line-height: 1.5; color: var(--cx-text); background: var(--cx-bg); padding: 24px 20px; min-height: 100vh; }
479
+ body::before { content: ''; position: fixed; inset: 0; background: radial-gradient(ellipse at 20% 50%, rgba(var(--cx-primary-rgb), 0.04) 0%, transparent 60%), linear-gradient(180deg, var(--cx-bg) 0%, #080818 100%); pointer-events: none; z-index: 0; }
480
+ .shell { position: relative; z-index: 1; max-width: 1440px; margin: 0 auto; }
481
+ .header-bar { display: flex; align-items: center; justify-content: space-between; padding: 12px 16px; background: var(--cx-bg2); border: 1px solid var(--cx-border); border-radius: var(--cx-radius); margin-bottom: 20px; }
482
+ .header-bar h1 { font-family: 'Orbitron', var(--cx-font); font-size: 14px; font-weight: 500; letter-spacing: 0.12em; text-transform: uppercase; color: var(--cx-heading); }
483
+ .header-bar .badge { font-size: 10px; color: var(--cx-muted); padding: 2px 8px; border: 1px solid var(--cx-border2); border-radius: var(--cx-radius); }
484
+ .subtitle { font-size: 11px; color: var(--cx-muted); letter-spacing: 0.04em; }
485
+ .sandbox-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(340px, 1fr)); gap: 12px; margin-top: 16px; }
486
+ .sandbox-card { background: var(--cx-bg2); border: 1px solid var(--cx-border); border-radius: var(--cx-radius); padding: 16px; transition: all 200ms ease; }
487
+ .sandbox-card:hover { border-color: rgba(var(--cx-primary-rgb), 0.5); box-shadow: 0 0 16px rgba(var(--cx-primary-rgb), 0.1); }
488
+ .sandbox-name { font-size: 13px; font-weight: 400; color: var(--cx-heading); margin-bottom: 10px; letter-spacing: 0.04em; }
489
+ .sandbox-actions { display: flex; gap: 6px; margin-bottom: 10px; }
490
+ .sandbox-btn { flex: 1; padding: 7px 10px; border-radius: var(--cx-radius); font-family: var(--cx-font); font-size: 10px; letter-spacing: 0.06em; text-transform: uppercase; text-align: center; text-decoration: none; cursor: pointer; transition: all 200ms ease; border: 1px solid var(--cx-border); background: transparent; color: var(--cx-text2); }
491
+ .sandbox-btn.primary { color: var(--cx-positive); border-color: rgba(var(--cx-positive-rgb), 0.3); }
492
+ .sandbox-btn.primary:hover { background: rgba(var(--cx-positive-rgb), 0.08); border-color: rgba(var(--cx-positive-rgb), 0.5); }
493
+ .sandbox-btn.secondary { color: var(--cx-primary); border-color: rgba(var(--cx-primary-rgb), 0.3); }
494
+ .sandbox-btn.secondary:hover { background: rgba(var(--cx-primary-rgb), 0.08); border-color: rgba(var(--cx-primary-rgb), 0.5); }
495
+ .sandbox-btn.danger { color: var(--cx-negative); border-color: rgba(var(--cx-negative-rgb), 0.3); flex: 0.5; }
496
+ .sandbox-btn.danger:hover { background: rgba(var(--cx-negative-rgb), 0.08); }
497
+ .sandbox-btn.warning { color: var(--cx-warning); border-color: rgba(255, 187, 36, 0.3); flex: 0.5; }
498
+ .sandbox-btn.warning:hover { background: rgba(255, 187, 36, 0.08); }
499
+ .sandbox-btn:disabled { opacity: 0.3; cursor: not-allowed; }
500
+ .sandbox-meta { display: flex; gap: 12px; font-size: 10px; color: var(--cx-muted); letter-spacing: 0.04em; }
501
+ .status { display: inline-flex; align-items: center; gap: 5px; }
502
+ .status-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--cx-positive); box-shadow: 0 0 6px rgba(var(--cx-positive-rgb), 0.5); }
503
+ .status-dot.stopped { background: var(--cx-negative); box-shadow: 0 0 6px rgba(var(--cx-negative-rgb), 0.5); }
504
+ .empty-state { text-align: center; padding: 60px 20px; color: var(--cx-muted); }
505
+ .empty-state h2 { font-size: 14px; font-weight: 400; color: var(--cx-text2); margin-bottom: 8px; letter-spacing: 0.06em; }
506
+ .empty-state p { font-size: 11px; }
507
+ .refresh-btn { font-family: var(--cx-font); font-size: 10px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--cx-primary); background: var(--cx-bg2); border: 1px solid rgba(var(--cx-primary-rgb), 0.3); border-radius: var(--cx-radius); padding: 8px 16px; cursor: pointer; transition: all 200ms ease; margin-top: 12px; }
508
+ .refresh-btn:hover { background: rgba(var(--cx-primary-rgb), 0.08); border-color: rgba(var(--cx-primary-rgb), 0.5); }
509
+ .nav-link { font-size: 10px; color: var(--cx-primary); text-decoration: none; letter-spacing: 0.04em; transition: color 200ms; }
510
+ .nav-link:hover { color: var(--cx-heading); }
511
+ @keyframes fade-up { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }
512
+ .anim-in { animation: fade-up 400ms ease both; }
513
+ </style>
514
+ </head>
515
+ <body>
516
+ <div class="shell">
517
+ <div class="header-bar anim-in">
518
+ <div style="display: flex; align-items: center; gap: 12px;">
519
+ <h1>Cortex Intelligence // Sandboxes</h1>
520
+ <span class="badge">ARTIFACTS</span>
521
+ </div>
522
+ <div style="display: flex; align-items: center; gap: 16px;">
523
+ <a href="/tmux" class="nav-link">Tmux Sessions</a>
524
+ <span class="subtitle">Real-time artifact monitoring</span>
525
+ </div>
526
+ </div>
527
+
528
+ <div id="sandbox-list" class="sandbox-grid"></div>
529
+ </div>
530
+
531
+ <script>
532
+ async function loadSandboxes() {
533
+ try {
534
+ const response = await fetch('/api/sandboxes');
535
+ const data = await response.json();
536
+ const container = document.getElementById('sandbox-list');
537
+
538
+ if (data.sandboxes.length === 0) {
539
+ container.innerHTML = \`
540
+ <div class="empty-state anim-in">
541
+ <h2>No Active Sandboxes</h2>
542
+ <p>Create a sandbox using CreateArtifactTool to see it here</p>
543
+ <button class="refresh-btn" onclick="loadSandboxes()">Refresh</button>
544
+ </div>
545
+ \`;
546
+ return;
547
+ }
548
+
549
+ container.innerHTML = data.sandboxes.map((sandbox, i) => \`
550
+ <div class="sandbox-card anim-in" style="animation-delay: \${i * 60}ms">
551
+ <div class="sandbox-name">\${sandbox.name}</div>
552
+ <div class="sandbox-actions">
553
+ <a class="sandbox-btn primary" href="\${sandbox.url}" target="_blank">View Artifact</a>
554
+ <a class="sandbox-btn secondary" href="/sandbox/\${sandbox.id}">Console</a>
555
+ </div>
556
+ <div class="sandbox-actions">
557
+ <button class="sandbox-btn danger" onclick="stopArtifact('\${sandbox.id}', '\${sandbox.name}')" \${sandbox.status !== 'running' ? 'disabled' : ''}>Stop</button>
558
+ <button class="sandbox-btn warning" onclick="restartArtifact('\${sandbox.id}', '\${sandbox.name}')" \${sandbox.status !== 'running' ? 'disabled' : ''}>Restart</button>
559
+ </div>
560
+ <div class="sandbox-meta">
561
+ <span class="status">
562
+ <span class="status-dot \${sandbox.status === 'running' ? '' : 'stopped'}"></span>
563
+ \${sandbox.status}
564
+ </span>
565
+ <span>Mode: \${sandbox.mode}</span>
566
+ </div>
567
+ </div>
568
+ \`).join('');
569
+ } catch (error) {
570
+ console.error('Failed to load sandboxes:', error);
571
+ }
572
+ }
573
+
574
+ async function stopArtifact(id, name) {
575
+ if (!confirm('Stop artifact "' + name + '"?')) return;
576
+ try {
577
+ const r = await fetch('/api/artifacts/' + id + '/stop', { method: 'POST' });
578
+ const result = await r.json();
579
+ if (result.success) loadSandboxes();
580
+ else alert('Failed: ' + result.message);
581
+ } catch (e) { alert('Error: ' + e.message); }
582
+ }
583
+
584
+ async function restartArtifact(id, name) {
585
+ if (!confirm('Restart artifact "' + name + '"?')) return;
586
+ try {
587
+ const r = await fetch('/api/artifacts/' + id + '/restart', { method: 'POST' });
588
+ const result = await r.json();
589
+ if (result.success) loadSandboxes();
590
+ else alert('Failed: ' + result.message);
591
+ } catch (e) { alert('Error: ' + e.message); }
592
+ }
593
+
594
+ loadSandboxes();
595
+ setInterval(loadSandboxes, 5000);
596
+ </script>
597
+ </body>
598
+ </html>
599
+ `;
600
+ }
601
+ /**
602
+ * Generate sandbox-specific view HTML
603
+ */
604
+ generateSandboxViewHTML(session) {
605
+ return `
606
+ <!DOCTYPE html>
607
+ <html lang="en">
608
+ <head>
609
+ <meta charset="UTF-8">
610
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
611
+ <title>Cortex Intelligence // ${session.name}</title>
612
+ <link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;500;700&family=Oxygen+Mono&display=swap" rel="stylesheet">
613
+ <script src="https://cdn.socket.io/4.5.4/socket.io.min.js"></script>
614
+ <style>
615
+ :root {
616
+ --cx-primary: #4a90d9; --cx-primary-rgb: 74, 144, 217;
617
+ --cx-positive: #4ade80; --cx-positive-rgb: 74, 222, 128;
618
+ --cx-negative: #f87171; --cx-warning: #fbbf24;
619
+ --cx-bg: #0f172a; --cx-bg2: #1e293b; --cx-bg3: #253347;
620
+ --cx-text: #e2e8f0; --cx-text2: #b0b8c4; --cx-muted: #94a3b8; --cx-heading: #f8fafc;
621
+ --cx-border: #334155; --cx-border2: #283548;
622
+ --cx-radius: 6px;
623
+ --cx-font: 'Oxygen Mono', monospace;
624
+ }
625
+ * { margin: 0; padding: 0; box-sizing: border-box; }
626
+ body { font-family: var(--cx-font); font-size: 12px; color: var(--cx-text); background: var(--cx-bg); overflow: hidden; }
627
+ .container { display: grid; grid-template-rows: 48px 1fr; height: 100vh; }
628
+ .header { background: var(--cx-bg2); border-bottom: 1px solid var(--cx-border); padding: 0 16px; display: flex; align-items: center; justify-content: space-between; }
629
+ .header .title { font-family: 'Orbitron', var(--cx-font); font-size: 13px; font-weight: 500; color: var(--cx-heading); letter-spacing: 0.1em; text-transform: uppercase; }
630
+ .header .nav-link { font-size: 10px; color: var(--cx-primary); text-decoration: none; letter-spacing: 0.04em; }
631
+ .header .nav-link:hover { color: var(--cx-heading); }
632
+ .status { display: flex; align-items: center; gap: 6px; font-size: 10px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--cx-positive); }
633
+ .status-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--cx-positive); box-shadow: 0 0 8px rgba(var(--cx-positive-rgb), 0.6); animation: pulse 2s ease-in-out infinite; }
634
+ @keyframes pulse { 0%, 100% { box-shadow: 0 0 8px rgba(var(--cx-positive-rgb), 0.6); } 50% { box-shadow: 0 0 14px rgba(var(--cx-positive-rgb), 0.9); } }
635
+ .main-content { display: grid; grid-template-columns: 1fr 360px; height: 100%; }
636
+ .preview-pane { background: #fff; position: relative; }
637
+ .preview-pane iframe { width: 100%; height: 100%; border: none; }
638
+ .sidebar { background: var(--cx-bg); border-left: 1px solid var(--cx-border); display: flex; flex-direction: column; }
639
+ .tabs { display: flex; background: var(--cx-bg2); border-bottom: 1px solid var(--cx-border); }
640
+ .tab { flex: 1; padding: 10px; text-align: center; cursor: pointer; border-bottom: 2px solid transparent; transition: all 200ms; font-size: 10px; text-transform: uppercase; letter-spacing: 0.08em; color: var(--cx-muted); font-family: var(--cx-font); }
641
+ .tab:hover { background: var(--cx-bg3); color: var(--cx-text2); }
642
+ .tab.active { border-bottom-color: var(--cx-primary); color: var(--cx-primary); }
643
+ .tab-content { flex: 1; overflow-y: auto; padding: 10px; scrollbar-width: thin; scrollbar-color: var(--cx-border) var(--cx-bg); }
644
+ .console-line { font-size: 11px; padding: 3px 8px; border-left: 2px solid transparent; margin-bottom: 1px; }
645
+ .console-log { color: var(--cx-text); border-left-color: var(--cx-primary); }
646
+ .console-error { color: var(--cx-negative); border-left-color: var(--cx-negative); }
647
+ .console-warn { color: var(--cx-warning); border-left-color: var(--cx-warning); }
648
+ .timestamp { color: var(--cx-muted); margin-right: 8px; font-size: 10px; }
649
+ .screenshot-item { margin-bottom: 12px; }
650
+ .screenshot-item img { width: 100%; border-radius: var(--cx-radius); border: 1px solid var(--cx-border); }
651
+ .screenshot-meta { font-size: 10px; color: var(--cx-muted); margin-top: 4px; }
652
+ .network-item { padding: 6px 8px; margin-bottom: 2px; background: var(--cx-bg2); border-radius: var(--cx-radius); font-size: 11px; }
653
+ .network-method { color: var(--cx-primary); font-weight: 400; margin-right: 8px; }
654
+ .network-url { color: var(--cx-text2); }
655
+ .network-status { float: right; color: var(--cx-positive); }
656
+ .reload-notification { position: absolute; top: 16px; left: 50%; transform: translateX(-50%); background: var(--cx-bg2); color: var(--cx-primary); padding: 8px 20px; border-radius: var(--cx-radius); border: 1px solid rgba(var(--cx-primary-rgb), 0.3); box-shadow: 0 4px 12px rgba(0,0,0,0.4); z-index: 1000; display: none; font-family: var(--cx-font); font-size: 11px; letter-spacing: 0.04em; }
657
+ .reload-notification.show { display: block; animation: slideDown 0.3s; }
658
+ @keyframes slideDown { from { transform: translateX(-50%) translateY(-12px); opacity: 0; } to { transform: translateX(-50%) translateY(0); opacity: 1; } }
659
+ </style>
660
+ </head>
661
+ <body>
662
+ <div class="container">
663
+ <div class="header">
664
+ <div style="display: flex; align-items: center; gap: 16px;">
665
+ <a href="/" class="nav-link">&larr; Dashboard</a>
666
+ <span class="title">${session.name}</span>
667
+ </div>
668
+ <div class="status"><span class="status-dot"></span> Running</div>
669
+ </div>
670
+ <div class="main-content">
671
+ <div class="preview-pane">
672
+ <div class="reload-notification" id="reload-notification">Reloading...</div>
673
+ <iframe id="sandbox-iframe" src="${session.url}"></iframe>
674
+ </div>
675
+ <div class="sidebar">
676
+ <div class="tabs">
677
+ <div class="tab active" onclick="switchTab('console')">Console</div>
678
+ <div class="tab" onclick="switchTab('screenshots')">Screenshots</div>
679
+ <div class="tab" onclick="switchTab('network')">Network</div>
680
+ </div>
681
+ <div class="tab-content" id="console-content"></div>
682
+ <div class="tab-content" id="screenshots-content" style="display:none;"></div>
683
+ <div class="tab-content" id="network-content" style="display:none;"></div>
684
+ </div>
685
+ </div>
686
+ </div>
687
+ <script>
688
+ const socket = io();
689
+ const sandboxId = '${session.id}';
690
+ socket.emit('subscribe', sandboxId);
691
+ socket.on('console-log', (e) => addConsoleLog('log', e.data.message));
692
+ socket.on('console-error', (e) => addConsoleLog('error', e.data.message));
693
+ socket.on('console-warn', (e) => addConsoleLog('warn', e.data.message));
694
+ socket.on('file-changed', () => { showReloadNotification(); setTimeout(() => { document.getElementById('sandbox-iframe').src = '${session.url}?' + Date.now(); }, 1000); });
695
+ socket.on('screenshot-captured', (e) => addScreenshot(e.data.screenshot, e.data.url));
696
+ socket.on('network-request', (e) => addNetworkRequest(e.data.method, e.data.url, e.data.status));
697
+ socket.on('network-response', (e) => addNetworkRequest(e.data.method, e.data.url, e.data.status));
698
+ socket.on('history', (data) => { data.events.forEach(e => { if (e.type.startsWith('console-')) addConsoleLog(e.data.level, e.data.message); else if (e.type === 'screenshot-captured') addScreenshot(e.data.screenshot, e.data.url); else if (e.type.startsWith('network-')) addNetworkRequest(e.data.method, e.data.url, e.data.status); }); });
699
+ function addConsoleLog(level, message) { const c = document.getElementById('console-content'); const l = document.createElement('div'); l.className = 'console-line console-' + level; l.innerHTML = '<span class="timestamp">' + new Date().toLocaleTimeString() + '</span>' + message; c.appendChild(l); c.scrollTop = c.scrollHeight; }
700
+ function addScreenshot(base64, url) { const c = document.getElementById('screenshots-content'); const i = document.createElement('div'); i.className = 'screenshot-item'; i.innerHTML = '<img src="data:image/png;base64,' + base64 + '" alt="Screenshot"><div class="screenshot-meta">' + new Date().toLocaleString() + '</div>'; c.insertBefore(i, c.firstChild); }
701
+ function addNetworkRequest(method, url, status) { const c = document.getElementById('network-content'); const i = document.createElement('div'); i.className = 'network-item'; i.innerHTML = '<span class="network-method">' + method + '</span><span class="network-url">' + url + '</span>' + (status ? '<span class="network-status">' + status + '</span>' : ''); c.insertBefore(i, c.firstChild); }
702
+ function showReloadNotification() { const n = document.getElementById('reload-notification'); n.classList.add('show'); setTimeout(() => n.classList.remove('show'), 2000); }
703
+ function switchTab(tab) { document.querySelectorAll('.tab').forEach(t => t.classList.remove('active')); event.target.classList.add('active'); ['console','screenshots','network'].forEach(t => { document.getElementById(t + '-content').style.display = t === tab ? 'block' : 'none'; }); }
704
+ addConsoleLog('log', 'Sandbox viewer connected');
705
+ </script>
706
+ </body>
707
+ </html>
708
+ `;
709
+ }
710
+ /**
711
+ * Generate 404 page
712
+ */
713
+ generate404HTML(sandboxId) {
714
+ return `
715
+ <!DOCTYPE html>
716
+ <html lang="en">
717
+ <head>
718
+ <meta charset="UTF-8">
719
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
720
+ <title>Cortex Intelligence // Not Found</title>
721
+ <link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;500;700&family=Oxygen+Mono&display=swap" rel="stylesheet">
722
+ <style>
723
+ * { margin: 0; padding: 0; box-sizing: border-box; }
724
+ body { font-family: 'Oxygen Mono', monospace; font-size: 12px; background: #0f172a; color: #e2e8f0; display: flex; align-items: center; justify-content: center; height: 100vh; text-align: center; }
725
+ .error-container { max-width: 440px; padding: 40px; background: #1e293b; border: 1px solid #334155; border-radius: 6px; }
726
+ h1 { font-size: 14px; font-weight: 400; letter-spacing: 0.08em; text-transform: uppercase; margin-bottom: 12px; color: #f8fafc; }
727
+ p { color: #94a3b8; font-size: 11px; margin-bottom: 8px; }
728
+ .sandbox-id { background: #253347; padding: 8px 12px; border-radius: 6px; margin: 16px 0; color: #f87171; font-size: 11px; border: 1px solid #283548; }
729
+ a { color: #4a90d9; text-decoration: none; font-size: 11px; letter-spacing: 0.04em; }
730
+ a:hover { color: #f8fafc; }
731
+ </style>
732
+ </head>
733
+ <body>
734
+ <div class="error-container">
735
+ <h1>Sandbox Not Found</h1>
736
+ <p>The sandbox you're looking for doesn't exist or has been stopped.</p>
737
+ <div class="sandbox-id">${sandboxId}</div>
738
+ <p><a href="/">&larr; Back to Dashboard</a></p>
739
+ </div>
740
+ </body>
741
+ </html>
742
+ `;
743
+ }
744
+ /**
745
+ * Check if server is running
746
+ */
747
+ isServerRunning() {
748
+ return this.isRunning;
749
+ }
750
+ /**
751
+ * Get current port
752
+ */
753
+ getPort() {
754
+ return this.port;
755
+ }
756
+ /**
757
+ * Get Express app instance for route registration
758
+ * Allows other servers (like TmuxViewServer) to add routes
759
+ */
760
+ getApp() {
761
+ return this.app;
762
+ }
763
+ /**
764
+ * Get Socket.IO server instance for WebSocket handling
765
+ * Allows other servers to register WebSocket event handlers
766
+ */
767
+ getIO() {
768
+ return this.io;
769
+ }
770
+ }
771
+ /**
772
+ * Export singleton instance
773
+ */
774
+ export const viewServer = SandboxViewServer.getInstance();
775
+ //# sourceMappingURL=SandboxViewServer.js.map