@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.
- package/LICENSE +202 -0
- package/NOTICE +2 -0
- package/README.md +13 -0
- package/dist/ExecutorRegistry.d.ts +89 -0
- package/dist/ExecutorRegistry.d.ts.map +1 -0
- package/dist/ExecutorRegistry.js +219 -0
- package/dist/ExecutorRegistry.js.map +1 -0
- package/dist/base/BaseTool.d.ts +108 -0
- package/dist/base/BaseTool.d.ts.map +1 -0
- package/dist/base/BaseTool.js +111 -0
- package/dist/base/BaseTool.js.map +1 -0
- package/dist/base/ToolRegistry.d.ts +141 -0
- package/dist/base/ToolRegistry.d.ts.map +1 -0
- package/dist/base/ToolRegistry.js +241 -0
- package/dist/base/ToolRegistry.js.map +1 -0
- package/dist/base/ToolResult.d.ts +63 -0
- package/dist/base/ToolResult.d.ts.map +1 -0
- package/dist/base/ToolResult.js +8 -0
- package/dist/base/ToolResult.js.map +1 -0
- package/dist/base/index.d.ts +10 -0
- package/dist/base/index.d.ts.map +1 -0
- package/dist/base/index.js +8 -0
- package/dist/base/index.js.map +1 -0
- package/dist/implementations/addon/CreateArtifactTool.d.ts +221 -0
- package/dist/implementations/addon/CreateArtifactTool.d.ts.map +1 -0
- package/dist/implementations/addon/CreateArtifactTool.js +1042 -0
- package/dist/implementations/addon/CreateArtifactTool.js.map +1 -0
- package/dist/implementations/addon/FrameDiffCache.d.ts +166 -0
- package/dist/implementations/addon/FrameDiffCache.d.ts.map +1 -0
- package/dist/implementations/addon/FrameDiffCache.js +395 -0
- package/dist/implementations/addon/FrameDiffCache.js.map +1 -0
- package/dist/implementations/addon/H264StreamEncoder.d.ts +84 -0
- package/dist/implementations/addon/H264StreamEncoder.d.ts.map +1 -0
- package/dist/implementations/addon/H264StreamEncoder.js +203 -0
- package/dist/implementations/addon/H264StreamEncoder.js.map +1 -0
- package/dist/implementations/addon/HybridScreenshotManager.d.ts +197 -0
- package/dist/implementations/addon/HybridScreenshotManager.d.ts.map +1 -0
- package/dist/implementations/addon/HybridScreenshotManager.js +415 -0
- package/dist/implementations/addon/HybridScreenshotManager.js.map +1 -0
- package/dist/implementations/addon/InspectSandboxTool.d.ts +54 -0
- package/dist/implementations/addon/InspectSandboxTool.d.ts.map +1 -0
- package/dist/implementations/addon/InspectSandboxTool.js +226 -0
- package/dist/implementations/addon/InspectSandboxTool.js.map +1 -0
- package/dist/implementations/addon/InteractWithSandboxTool.d.ts +90 -0
- package/dist/implementations/addon/InteractWithSandboxTool.d.ts.map +1 -0
- package/dist/implementations/addon/InteractWithSandboxTool.js +367 -0
- package/dist/implementations/addon/InteractWithSandboxTool.js.map +1 -0
- package/dist/implementations/addon/KeyframeDetector.d.ts +140 -0
- package/dist/implementations/addon/KeyframeDetector.d.ts.map +1 -0
- package/dist/implementations/addon/KeyframeDetector.js +390 -0
- package/dist/implementations/addon/KeyframeDetector.js.map +1 -0
- package/dist/implementations/addon/ModifySandboxTool.d.ts +62 -0
- package/dist/implementations/addon/ModifySandboxTool.d.ts.map +1 -0
- package/dist/implementations/addon/ModifySandboxTool.js +266 -0
- package/dist/implementations/addon/ModifySandboxTool.js.map +1 -0
- package/dist/implementations/addon/ReactArtifactBuilder.d.ts +27 -0
- package/dist/implementations/addon/ReactArtifactBuilder.d.ts.map +1 -0
- package/dist/implementations/addon/ReactArtifactBuilder.js +198 -0
- package/dist/implementations/addon/ReactArtifactBuilder.js.map +1 -0
- package/dist/implementations/addon/SandboxEventBroadcaster.d.ts +143 -0
- package/dist/implementations/addon/SandboxEventBroadcaster.d.ts.map +1 -0
- package/dist/implementations/addon/SandboxEventBroadcaster.js +258 -0
- package/dist/implementations/addon/SandboxEventBroadcaster.js.map +1 -0
- package/dist/implementations/addon/SandboxIntrospectionTools.d.ts +77 -0
- package/dist/implementations/addon/SandboxIntrospectionTools.d.ts.map +1 -0
- package/dist/implementations/addon/SandboxIntrospectionTools.js +292 -0
- package/dist/implementations/addon/SandboxIntrospectionTools.js.map +1 -0
- package/dist/implementations/addon/SandboxViewServer.d.ts +127 -0
- package/dist/implementations/addon/SandboxViewServer.d.ts.map +1 -0
- package/dist/implementations/addon/SandboxViewServer.js +775 -0
- package/dist/implementations/addon/SandboxViewServer.js.map +1 -0
- package/dist/implementations/addon/ScreenStream.d.ts +149 -0
- package/dist/implementations/addon/ScreenStream.d.ts.map +1 -0
- package/dist/implementations/addon/ScreenStream.js +306 -0
- package/dist/implementations/addon/ScreenStream.js.map +1 -0
- package/dist/implementations/addon/StopSandboxTool.d.ts +61 -0
- package/dist/implementations/addon/StopSandboxTool.d.ts.map +1 -0
- package/dist/implementations/addon/StopSandboxTool.js +252 -0
- package/dist/implementations/addon/StopSandboxTool.js.map +1 -0
- package/dist/implementations/addon/TerminalSandbox.d.ts +111 -0
- package/dist/implementations/addon/TerminalSandbox.d.ts.map +1 -0
- package/dist/implementations/addon/TerminalSandbox.js +345 -0
- package/dist/implementations/addon/TerminalSandbox.js.map +1 -0
- package/dist/implementations/addon/VisualFeedbackBridge.d.ts +367 -0
- package/dist/implementations/addon/VisualFeedbackBridge.d.ts.map +1 -0
- package/dist/implementations/addon/VisualFeedbackBridge.js +888 -0
- package/dist/implementations/addon/VisualFeedbackBridge.js.map +1 -0
- package/dist/implementations/addon/WindowManager.d.ts +138 -0
- package/dist/implementations/addon/WindowManager.d.ts.map +1 -0
- package/dist/implementations/addon/WindowManager.js +276 -0
- package/dist/implementations/addon/WindowManager.js.map +1 -0
- package/dist/implementations/addon/index.d.ts +29 -0
- package/dist/implementations/addon/index.d.ts.map +1 -0
- package/dist/implementations/addon/index.js +29 -0
- package/dist/implementations/addon/index.js.map +1 -0
- package/dist/implementations/addon/injectables/reactIntrospection.d.ts +57 -0
- package/dist/implementations/addon/injectables/reactIntrospection.d.ts.map +1 -0
- package/dist/implementations/addon/injectables/reactIntrospection.js +480 -0
- package/dist/implementations/addon/injectables/reactIntrospection.js.map +1 -0
- package/dist/implementations/addon/terminal-client.html +253 -0
- package/dist/implementations/agent/PRAgentTool.d.ts +37 -0
- package/dist/implementations/agent/PRAgentTool.d.ts.map +1 -0
- package/dist/implementations/agent/PRAgentTool.js +257 -0
- package/dist/implementations/agent/PRAgentTool.js.map +1 -0
- package/dist/implementations/agent/TaskTool.d.ts +76 -0
- package/dist/implementations/agent/TaskTool.d.ts.map +1 -0
- package/dist/implementations/agent/TaskTool.js +424 -0
- package/dist/implementations/agent/TaskTool.js.map +1 -0
- package/dist/implementations/agent/index.d.ts +5 -0
- package/dist/implementations/agent/index.d.ts.map +1 -0
- package/dist/implementations/agent/index.js +3 -0
- package/dist/implementations/agent/index.js.map +1 -0
- package/dist/implementations/execution/BackgroundProcessRegistry.d.ts +68 -0
- package/dist/implementations/execution/BackgroundProcessRegistry.d.ts.map +1 -0
- package/dist/implementations/execution/BackgroundProcessRegistry.js +146 -0
- package/dist/implementations/execution/BackgroundProcessRegistry.js.map +1 -0
- package/dist/implementations/execution/BashOutputTool.d.ts +42 -0
- package/dist/implementations/execution/BashOutputTool.d.ts.map +1 -0
- package/dist/implementations/execution/BashOutputTool.js +168 -0
- package/dist/implementations/execution/BashOutputTool.js.map +1 -0
- package/dist/implementations/execution/CodeExecuteTool.d.ts +31 -0
- package/dist/implementations/execution/CodeExecuteTool.d.ts.map +1 -0
- package/dist/implementations/execution/CodeExecuteTool.js +127 -0
- package/dist/implementations/execution/CodeExecuteTool.js.map +1 -0
- package/dist/implementations/execution/KillShellTool.d.ts +37 -0
- package/dist/implementations/execution/KillShellTool.d.ts.map +1 -0
- package/dist/implementations/execution/KillShellTool.js +144 -0
- package/dist/implementations/execution/KillShellTool.js.map +1 -0
- package/dist/implementations/execution/SearchToolsTool.d.ts +32 -0
- package/dist/implementations/execution/SearchToolsTool.d.ts.map +1 -0
- package/dist/implementations/execution/SearchToolsTool.js +109 -0
- package/dist/implementations/execution/SearchToolsTool.js.map +1 -0
- package/dist/implementations/execution/ShellTool.d.ts +108 -0
- package/dist/implementations/execution/ShellTool.d.ts.map +1 -0
- package/dist/implementations/execution/ShellTool.js +546 -0
- package/dist/implementations/execution/ShellTool.js.map +1 -0
- package/dist/implementations/execution/WorkspaceManagerTool.d.ts +40 -0
- package/dist/implementations/execution/WorkspaceManagerTool.d.ts.map +1 -0
- package/dist/implementations/execution/WorkspaceManagerTool.js +370 -0
- package/dist/implementations/execution/WorkspaceManagerTool.js.map +1 -0
- package/dist/implementations/execution/index.d.ts +13 -0
- package/dist/implementations/execution/index.d.ts.map +1 -0
- package/dist/implementations/execution/index.js +13 -0
- package/dist/implementations/execution/index.js.map +1 -0
- package/dist/implementations/extensions/EndTurnTool.d.ts +62 -0
- package/dist/implementations/extensions/EndTurnTool.d.ts.map +1 -0
- package/dist/implementations/extensions/EndTurnTool.js +172 -0
- package/dist/implementations/extensions/EndTurnTool.js.map +1 -0
- package/dist/implementations/extensions/ResearchBacklogTool.d.ts +37 -0
- package/dist/implementations/extensions/ResearchBacklogTool.d.ts.map +1 -0
- package/dist/implementations/extensions/ResearchBacklogTool.js +102 -0
- package/dist/implementations/extensions/ResearchBacklogTool.js.map +1 -0
- package/dist/implementations/extensions/SkillTool.d.ts +108 -0
- package/dist/implementations/extensions/SkillTool.d.ts.map +1 -0
- package/dist/implementations/extensions/SkillTool.js +351 -0
- package/dist/implementations/extensions/SkillTool.js.map +1 -0
- package/dist/implementations/extensions/SlashCommandTool.d.ts +112 -0
- package/dist/implementations/extensions/SlashCommandTool.d.ts.map +1 -0
- package/dist/implementations/extensions/SlashCommandTool.js +315 -0
- package/dist/implementations/extensions/SlashCommandTool.js.map +1 -0
- package/dist/implementations/extensions/index.d.ts +14 -0
- package/dist/implementations/extensions/index.d.ts.map +1 -0
- package/dist/implementations/extensions/index.js +10 -0
- package/dist/implementations/extensions/index.js.map +1 -0
- package/dist/implementations/file/EditTool.d.ts +232 -0
- package/dist/implementations/file/EditTool.d.ts.map +1 -0
- package/dist/implementations/file/EditTool.js +707 -0
- package/dist/implementations/file/EditTool.js.map +1 -0
- package/dist/implementations/file/ReadFileTool.d.ts +49 -0
- package/dist/implementations/file/ReadFileTool.d.ts.map +1 -0
- package/dist/implementations/file/ReadFileTool.js +225 -0
- package/dist/implementations/file/ReadFileTool.js.map +1 -0
- package/dist/implementations/file/WriteBinaryTool.d.ts +21 -0
- package/dist/implementations/file/WriteBinaryTool.d.ts.map +1 -0
- package/dist/implementations/file/WriteBinaryTool.js +153 -0
- package/dist/implementations/file/WriteBinaryTool.js.map +1 -0
- package/dist/implementations/file/WriteFileTool.d.ts +41 -0
- package/dist/implementations/file/WriteFileTool.d.ts.map +1 -0
- package/dist/implementations/file/WriteFileTool.js +220 -0
- package/dist/implementations/file/WriteFileTool.js.map +1 -0
- package/dist/implementations/file/index.d.ts +8 -0
- package/dist/implementations/file/index.d.ts.map +1 -0
- package/dist/implementations/file/index.js +8 -0
- package/dist/implementations/file/index.js.map +1 -0
- package/dist/implementations/historical/GetConversationSegmentTool.d.ts +44 -0
- package/dist/implementations/historical/GetConversationSegmentTool.d.ts.map +1 -0
- package/dist/implementations/historical/GetConversationSegmentTool.js +220 -0
- package/dist/implementations/historical/GetConversationSegmentTool.js.map +1 -0
- package/dist/implementations/historical/ListCompactionBoundariesTool.d.ts +36 -0
- package/dist/implementations/historical/ListCompactionBoundariesTool.d.ts.map +1 -0
- package/dist/implementations/historical/ListCompactionBoundariesTool.js +174 -0
- package/dist/implementations/historical/ListCompactionBoundariesTool.js.map +1 -0
- package/dist/implementations/historical/ListSessionsTool.d.ts +38 -0
- package/dist/implementations/historical/ListSessionsTool.d.ts.map +1 -0
- package/dist/implementations/historical/ListSessionsTool.js +140 -0
- package/dist/implementations/historical/ListSessionsTool.js.map +1 -0
- package/dist/implementations/historical/LoadSessionTool.d.ts +39 -0
- package/dist/implementations/historical/LoadSessionTool.d.ts.map +1 -0
- package/dist/implementations/historical/LoadSessionTool.js +171 -0
- package/dist/implementations/historical/LoadSessionTool.js.map +1 -0
- package/dist/implementations/historical/RequestHistoricalContextTool.d.ts +46 -0
- package/dist/implementations/historical/RequestHistoricalContextTool.d.ts.map +1 -0
- package/dist/implementations/historical/RequestHistoricalContextTool.js +224 -0
- package/dist/implementations/historical/RequestHistoricalContextTool.js.map +1 -0
- package/dist/implementations/historical/SearchConversationHistoryTool.d.ts +51 -0
- package/dist/implementations/historical/SearchConversationHistoryTool.d.ts.map +1 -0
- package/dist/implementations/historical/SearchConversationHistoryTool.js +306 -0
- package/dist/implementations/historical/SearchConversationHistoryTool.js.map +1 -0
- package/dist/implementations/historical/index.d.ts +12 -0
- package/dist/implementations/historical/index.d.ts.map +1 -0
- package/dist/implementations/historical/index.js +12 -0
- package/dist/implementations/historical/index.js.map +1 -0
- package/dist/implementations/index.d.ts +16 -0
- package/dist/implementations/index.d.ts.map +1 -0
- package/dist/implementations/index.js +28 -0
- package/dist/implementations/index.js.map +1 -0
- package/dist/implementations/mcp/DiscoveredMcpTool.d.ts +58 -0
- package/dist/implementations/mcp/DiscoveredMcpTool.d.ts.map +1 -0
- package/dist/implementations/mcp/DiscoveredMcpTool.js +269 -0
- package/dist/implementations/mcp/DiscoveredMcpTool.js.map +1 -0
- package/dist/implementations/mcp/index.d.ts +9 -0
- package/dist/implementations/mcp/index.d.ts.map +1 -0
- package/dist/implementations/mcp/index.js +8 -0
- package/dist/implementations/mcp/index.js.map +1 -0
- package/dist/implementations/notebook/NotebookEditTool.d.ts +96 -0
- package/dist/implementations/notebook/NotebookEditTool.d.ts.map +1 -0
- package/dist/implementations/notebook/NotebookEditTool.js +390 -0
- package/dist/implementations/notebook/NotebookEditTool.js.map +1 -0
- package/dist/implementations/notebook/index.d.ts +7 -0
- package/dist/implementations/notebook/index.d.ts.map +1 -0
- package/dist/implementations/notebook/index.js +7 -0
- package/dist/implementations/notebook/index.js.map +1 -0
- package/dist/implementations/search/GlobTool.d.ts +73 -0
- package/dist/implementations/search/GlobTool.d.ts.map +1 -0
- package/dist/implementations/search/GlobTool.js +213 -0
- package/dist/implementations/search/GlobTool.js.map +1 -0
- package/dist/implementations/search/GrepTool.d.ts +102 -0
- package/dist/implementations/search/GrepTool.d.ts.map +1 -0
- package/dist/implementations/search/GrepTool.js +754 -0
- package/dist/implementations/search/GrepTool.js.map +1 -0
- package/dist/implementations/search/index.d.ts +6 -0
- package/dist/implementations/search/index.d.ts.map +1 -0
- package/dist/implementations/search/index.js +6 -0
- package/dist/implementations/search/index.js.map +1 -0
- package/dist/implementations/tmux/TmuxSessionTool.d.ts +82 -0
- package/dist/implementations/tmux/TmuxSessionTool.d.ts.map +1 -0
- package/dist/implementations/tmux/TmuxSessionTool.js +371 -0
- package/dist/implementations/tmux/TmuxSessionTool.js.map +1 -0
- package/dist/implementations/tmux/TmuxViewServer.d.ts +86 -0
- package/dist/implementations/tmux/TmuxViewServer.d.ts.map +1 -0
- package/dist/implementations/tmux/TmuxViewServer.js +480 -0
- package/dist/implementations/tmux/TmuxViewServer.js.map +1 -0
- package/dist/implementations/tmux/index.d.ts +6 -0
- package/dist/implementations/tmux/index.d.ts.map +1 -0
- package/dist/implementations/tmux/index.js +6 -0
- package/dist/implementations/tmux/index.js.map +1 -0
- package/dist/implementations/ui/AskUserQuestionTool.d.ts +77 -0
- package/dist/implementations/ui/AskUserQuestionTool.d.ts.map +1 -0
- package/dist/implementations/ui/AskUserQuestionTool.js +241 -0
- package/dist/implementations/ui/AskUserQuestionTool.js.map +1 -0
- package/dist/implementations/ui/ExitPlanModeTool.d.ts +44 -0
- package/dist/implementations/ui/ExitPlanModeTool.d.ts.map +1 -0
- package/dist/implementations/ui/ExitPlanModeTool.js +150 -0
- package/dist/implementations/ui/ExitPlanModeTool.js.map +1 -0
- package/dist/implementations/ui/TodoWriteTool.d.ts +59 -0
- package/dist/implementations/ui/TodoWriteTool.d.ts.map +1 -0
- package/dist/implementations/ui/TodoWriteTool.js +315 -0
- package/dist/implementations/ui/TodoWriteTool.js.map +1 -0
- package/dist/implementations/ui/index.d.ts +9 -0
- package/dist/implementations/ui/index.d.ts.map +1 -0
- package/dist/implementations/ui/index.js +9 -0
- package/dist/implementations/ui/index.js.map +1 -0
- package/dist/implementations/web/BrowseTool.d.ts +43 -0
- package/dist/implementations/web/BrowseTool.d.ts.map +1 -0
- package/dist/implementations/web/BrowseTool.js +181 -0
- package/dist/implementations/web/BrowseTool.js.map +1 -0
- package/dist/implementations/web/SandboxTransferTool.d.ts +30 -0
- package/dist/implementations/web/SandboxTransferTool.d.ts.map +1 -0
- package/dist/implementations/web/SandboxTransferTool.js +261 -0
- package/dist/implementations/web/SandboxTransferTool.js.map +1 -0
- package/dist/implementations/web/WebFetchTool.d.ts +93 -0
- package/dist/implementations/web/WebFetchTool.d.ts.map +1 -0
- package/dist/implementations/web/WebFetchTool.js +484 -0
- package/dist/implementations/web/WebFetchTool.js.map +1 -0
- package/dist/implementations/web/WebSearchTool.d.ts +53 -0
- package/dist/implementations/web/WebSearchTool.d.ts.map +1 -0
- package/dist/implementations/web/WebSearchTool.js +227 -0
- package/dist/implementations/web/WebSearchTool.js.map +1 -0
- package/dist/implementations/web/escalateDirective.d.ts +11 -0
- package/dist/implementations/web/escalateDirective.d.ts.map +1 -0
- package/dist/implementations/web/escalateDirective.js +20 -0
- package/dist/implementations/web/escalateDirective.js.map +1 -0
- package/dist/implementations/web/index.d.ts +10 -0
- package/dist/implementations/web/index.d.ts.map +1 -0
- package/dist/implementations/web/index.js +10 -0
- package/dist/implementations/web/index.js.map +1 -0
- package/dist/implementations/web/webBackends.d.ts +65 -0
- package/dist/implementations/web/webBackends.d.ts.map +1 -0
- package/dist/implementations/web/webBackends.js +430 -0
- package/dist/implementations/web/webBackends.js.map +1 -0
- package/dist/implementations/web/webFetchRequestInit.d.ts +9 -0
- package/dist/implementations/web/webFetchRequestInit.d.ts.map +1 -0
- package/dist/implementations/web/webFetchRequestInit.js +21 -0
- package/dist/implementations/web/webFetchRequestInit.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/utils/ArtifactRegistry.d.ts +138 -0
- package/dist/utils/ArtifactRegistry.d.ts.map +1 -0
- package/dist/utils/ArtifactRegistry.js +259 -0
- package/dist/utils/ArtifactRegistry.js.map +1 -0
- package/dist/utils/ChromiumBrowserManager.d.ts +56 -0
- package/dist/utils/ChromiumBrowserManager.d.ts.map +1 -0
- package/dist/utils/ChromiumBrowserManager.js +243 -0
- package/dist/utils/ChromiumBrowserManager.js.map +1 -0
- package/dist/utils/FileUtils.d.ts +81 -0
- package/dist/utils/FileUtils.d.ts.map +1 -0
- package/dist/utils/FileUtils.js +148 -0
- package/dist/utils/FileUtils.js.map +1 -0
- package/dist/utils/GitPolicy.d.ts +70 -0
- package/dist/utils/GitPolicy.d.ts.map +1 -0
- package/dist/utils/GitPolicy.js +166 -0
- package/dist/utils/GitPolicy.js.map +1 -0
- package/dist/utils/GitUtils.d.ts +18 -0
- package/dist/utils/GitUtils.d.ts.map +1 -0
- package/dist/utils/GitUtils.js +62 -0
- package/dist/utils/GitUtils.js.map +1 -0
- package/dist/utils/SandboxRegistry.d.ts +110 -0
- package/dist/utils/SandboxRegistry.d.ts.map +1 -0
- package/dist/utils/SandboxRegistry.js +220 -0
- package/dist/utils/SandboxRegistry.js.map +1 -0
- package/dist/utils/SchemaValidator.d.ts +21 -0
- package/dist/utils/SchemaValidator.d.ts.map +1 -0
- package/dist/utils/SchemaValidator.js +67 -0
- package/dist/utils/SchemaValidator.js.map +1 -0
- package/dist/utils/SessionLock.d.ts +96 -0
- package/dist/utils/SessionLock.d.ts.map +1 -0
- package/dist/utils/SessionLock.js +276 -0
- package/dist/utils/SessionLock.js.map +1 -0
- package/dist/utils/SessionPersistence.d.ts +89 -0
- package/dist/utils/SessionPersistence.d.ts.map +1 -0
- package/dist/utils/SessionPersistence.js +244 -0
- package/dist/utils/SessionPersistence.js.map +1 -0
- package/dist/utils/TextUtils.d.ts +77 -0
- package/dist/utils/TextUtils.d.ts.map +1 -0
- package/dist/utils/TextUtils.js +112 -0
- package/dist/utils/TextUtils.js.map +1 -0
- package/dist/utils/TmuxCapture.d.ts +94 -0
- package/dist/utils/TmuxCapture.d.ts.map +1 -0
- package/dist/utils/TmuxCapture.js +131 -0
- package/dist/utils/TmuxCapture.js.map +1 -0
- package/dist/utils/TmuxManager.d.ts +65 -0
- package/dist/utils/TmuxManager.d.ts.map +1 -0
- package/dist/utils/TmuxManager.js +304 -0
- package/dist/utils/TmuxManager.js.map +1 -0
- package/dist/utils/autoResearchPlanGate.d.ts +10 -0
- package/dist/utils/autoResearchPlanGate.d.ts.map +1 -0
- package/dist/utils/autoResearchPlanGate.js +57 -0
- package/dist/utils/autoResearchPlanGate.js.map +1 -0
- package/dist/utils/index.d.ts +19 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +13 -0
- package/dist/utils/index.js.map +1 -0
- package/package.json +83 -0
|
@@ -0,0 +1,888 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Visual Feedback Bridge
|
|
3
|
+
*
|
|
4
|
+
* Enables the MODEL to see and interact with tools it creates.
|
|
5
|
+
*
|
|
6
|
+
* Flow:
|
|
7
|
+
* 1. Model creates tool → UI spins up
|
|
8
|
+
* 2. Bridge captures screenshot/DOM
|
|
9
|
+
* 3. Returns visual data to model
|
|
10
|
+
* 4. Model analyzes output
|
|
11
|
+
* 5. Model edits code or spawns interaction agent
|
|
12
|
+
* 6. Hot reload applies changes
|
|
13
|
+
* 7. Repeat until satisfied
|
|
14
|
+
*/
|
|
15
|
+
import { chromium } from 'playwright';
|
|
16
|
+
import { getChromiumBinary } from '../../utils/ChromiumBrowserManager.js';
|
|
17
|
+
import { PRELOAD_SCRIPT, DETECT_SCRIPT, SCAN_SCRIPT, GRAB_SCRIPT, TREE_SCRIPT, TRACE_START_SCRIPT, TRACE_REPORT_SCRIPT } from './injectables/reactIntrospection.js';
|
|
18
|
+
/**
|
|
19
|
+
* Visual Feedback Bridge
|
|
20
|
+
*
|
|
21
|
+
* Allows model to:
|
|
22
|
+
* - See its creations (screenshot + DOM)
|
|
23
|
+
* - Interact with UI (Playwright automation)
|
|
24
|
+
* - Iterate rapidly (hot reload + visual diff)
|
|
25
|
+
* - Delegate to sub-agents (complex interactions)
|
|
26
|
+
*/
|
|
27
|
+
export class VisualFeedbackBridge {
|
|
28
|
+
browser = null;
|
|
29
|
+
page = null;
|
|
30
|
+
consoleLogs = [];
|
|
31
|
+
networkRequests = [];
|
|
32
|
+
reactIntrospection = false;
|
|
33
|
+
/**
|
|
34
|
+
* Enable React introspection for all SUBSEQUENT navigations: installs the
|
|
35
|
+
* DevTools-hook shim + fiber utilities via addInitScript (must run before the
|
|
36
|
+
* page's React loads — addInitScript guarantees pre-script execution).
|
|
37
|
+
* Idempotent; safe to call lazily because captureSnapshot/sandboxScan/etc.
|
|
38
|
+
* always navigate after this.
|
|
39
|
+
*/
|
|
40
|
+
async enableReactIntrospection() {
|
|
41
|
+
if (this.reactIntrospection)
|
|
42
|
+
return;
|
|
43
|
+
if (!this.page)
|
|
44
|
+
throw new Error('Browser not initialized');
|
|
45
|
+
await this.page.addInitScript(PRELOAD_SCRIPT);
|
|
46
|
+
this.reactIntrospection = true;
|
|
47
|
+
}
|
|
48
|
+
isReactIntrospectionEnabled() {
|
|
49
|
+
return this.reactIntrospection;
|
|
50
|
+
}
|
|
51
|
+
/** Ensure the page is on the given URL (navigates only when needed). */
|
|
52
|
+
async ensureOnUrl(url) {
|
|
53
|
+
if (!this.page)
|
|
54
|
+
throw new Error('Browser not initialized');
|
|
55
|
+
// Normalize before comparing — the browser adds a trailing slash to an origin-only URL
|
|
56
|
+
// (http://host:port -> http://host:port/). Without this, every call re-navigates, which
|
|
57
|
+
// (critically) resets the in-page render-trace counters between start and report.
|
|
58
|
+
const norm = (u) => { try {
|
|
59
|
+
return new URL(u).href;
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return u;
|
|
63
|
+
} };
|
|
64
|
+
if (norm(this.page.url()) !== norm(url)) {
|
|
65
|
+
await this.page.goto(url, { waitUntil: 'networkidle' });
|
|
66
|
+
// Settle for client-side frameworks. The definitive "React rendered" signal is the
|
|
67
|
+
// introspection commit hook setting __lastRoot; for non-React/SSR pages, fall back to
|
|
68
|
+
// the mount point gaining children. Generous timeout for cold bundle parse + mount.
|
|
69
|
+
await this.page
|
|
70
|
+
.waitForFunction(() => {
|
|
71
|
+
const cr = window.__cortexReact;
|
|
72
|
+
if (cr && cr.__lastRoot)
|
|
73
|
+
return true; // React committed
|
|
74
|
+
const m = document.querySelector('#root, #app, [data-reactroot]');
|
|
75
|
+
return !m || m.childElementCount > 0; // non-React or DOM populated
|
|
76
|
+
}, { timeout: 2500 })
|
|
77
|
+
.catch(() => { });
|
|
78
|
+
await this.page.waitForTimeout(200);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Wait for React to have committed at least once (the introspection commit hook sets
|
|
83
|
+
* __lastRoot) — runs even when ensureOnUrl did NOT navigate, so a tree/scan/grab/trace
|
|
84
|
+
* call on an already-loaded page doesn't race a still-mounting app. No-op for non-React.
|
|
85
|
+
*/
|
|
86
|
+
async awaitReactReady() {
|
|
87
|
+
if (!this.page)
|
|
88
|
+
return;
|
|
89
|
+
await this.page
|
|
90
|
+
.waitForFunction(() => {
|
|
91
|
+
const cr = window.__cortexReact;
|
|
92
|
+
if (cr && cr.__lastRoot)
|
|
93
|
+
return true; // React committed
|
|
94
|
+
const m = document.querySelector('#root, #app, [data-reactroot]');
|
|
95
|
+
return !m || m.childElementCount > 0; // non-React or DOM populated
|
|
96
|
+
}, { timeout: 2500 })
|
|
97
|
+
.catch(() => { });
|
|
98
|
+
}
|
|
99
|
+
/** Is a render trace currently active on the live page? (no navigation) */
|
|
100
|
+
async isTraceActive() {
|
|
101
|
+
if (!this.page)
|
|
102
|
+
return false;
|
|
103
|
+
try {
|
|
104
|
+
return await this.page.evaluate(() => !!(window.__cortexRenderTrace && window.__cortexRenderTrace.enabled));
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/** detect_framework against the given sandbox URL (nexus-browser schema). */
|
|
111
|
+
async sandboxDetect(url) {
|
|
112
|
+
await this.enableReactIntrospection();
|
|
113
|
+
await this.ensureOnUrl(url);
|
|
114
|
+
await this.awaitReactReady();
|
|
115
|
+
return (await this.page.evaluate(DETECT_SCRIPT));
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Element discovery (nexus-browser scan contract): elements carry a unique
|
|
119
|
+
* cssSelector + isInteractive/relevanceScore, and componentName on React pages.
|
|
120
|
+
*/
|
|
121
|
+
async sandboxScan(url, args = {}) {
|
|
122
|
+
await this.enableReactIntrospection();
|
|
123
|
+
await this.ensureOnUrl(url);
|
|
124
|
+
await this.awaitReactReady();
|
|
125
|
+
return await this.page.evaluate(`(${SCAN_SCRIPT})(${JSON.stringify(args)})`);
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Single-element query by selector or coordinates (nexus-browser grab contract),
|
|
129
|
+
* auto-enriched with react:{componentName,componentStack,props,sourceLocation}.
|
|
130
|
+
*/
|
|
131
|
+
async sandboxGrab(url, args) {
|
|
132
|
+
await this.enableReactIntrospection();
|
|
133
|
+
await this.ensureOnUrl(url);
|
|
134
|
+
await this.awaitReactReady();
|
|
135
|
+
return await this.page.evaluate(`(${GRAB_SCRIPT})(${JSON.stringify(args)})`);
|
|
136
|
+
}
|
|
137
|
+
/** Component hierarchy of the React tree (component-tree role). */
|
|
138
|
+
async sandboxComponentTree(url, args = {}) {
|
|
139
|
+
await this.enableReactIntrospection();
|
|
140
|
+
await this.ensureOnUrl(url);
|
|
141
|
+
await this.awaitReactReady();
|
|
142
|
+
return await this.page.evaluate(`(${TREE_SCRIPT})(${JSON.stringify(args)})`);
|
|
143
|
+
}
|
|
144
|
+
/** Begin a render trace (react-scan role). Resets + enables the commit interceptor. */
|
|
145
|
+
async sandboxTraceStart(url) {
|
|
146
|
+
await this.enableReactIntrospection();
|
|
147
|
+
await this.ensureOnUrl(url);
|
|
148
|
+
await this.awaitReactReady();
|
|
149
|
+
return await this.page.evaluate(TRACE_START_SCRIPT);
|
|
150
|
+
}
|
|
151
|
+
/** Stop (or peek) a render trace and return per-component render counts/timings. */
|
|
152
|
+
async sandboxTraceReport(url, args = {}) {
|
|
153
|
+
await this.enableReactIntrospection();
|
|
154
|
+
await this.ensureOnUrl(url);
|
|
155
|
+
return await this.page.evaluate(`(${TRACE_REPORT_SCRIPT})(${JSON.stringify(args)})`);
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Initialize browser for visual feedback
|
|
159
|
+
* @param config Optional configuration for browser launch
|
|
160
|
+
*/
|
|
161
|
+
async initialize(config = {}) {
|
|
162
|
+
if (this.browser)
|
|
163
|
+
return;
|
|
164
|
+
const launchOptions = {
|
|
165
|
+
headless: config.headless ?? true,
|
|
166
|
+
slowMo: config.slowMo ?? 0,
|
|
167
|
+
args: [
|
|
168
|
+
'--no-sandbox',
|
|
169
|
+
'--disable-setuid-sandbox',
|
|
170
|
+
'--disable-dev-shm-usage', // Prevent shared memory issues
|
|
171
|
+
'--disable-gpu' // Disable GPU for headless
|
|
172
|
+
]
|
|
173
|
+
};
|
|
174
|
+
// Use system chromium if specified, otherwise auto-detect
|
|
175
|
+
if (config.executablePath) {
|
|
176
|
+
launchOptions.executablePath = config.executablePath;
|
|
177
|
+
console.log(`[VisualFeedbackBridge] Using provided chromium: ${config.executablePath}`);
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
// Auto-detect chromium binary
|
|
181
|
+
const chromiumBin = getChromiumBinary();
|
|
182
|
+
if (chromiumBin) {
|
|
183
|
+
launchOptions.executablePath = chromiumBin;
|
|
184
|
+
console.log(`[VisualFeedbackBridge] Using auto-detected chromium: ${chromiumBin}`);
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
console.warn(`[VisualFeedbackBridge] No chromium binary found, using Playwright's bundled browser (may require dependencies)`);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
// Add user data directory if specified (for persistent profiles)
|
|
191
|
+
if (config.userDataDir) {
|
|
192
|
+
launchOptions.args.push(`--user-data-dir=${config.userDataDir}`);
|
|
193
|
+
}
|
|
194
|
+
this.browser = await chromium.launch(launchOptions);
|
|
195
|
+
this.page = await this.browser.newPage();
|
|
196
|
+
// Capture console logs
|
|
197
|
+
this.page.on('console', (msg) => {
|
|
198
|
+
this.consoleLogs.push(`[${msg.type()}] ${msg.text()}`);
|
|
199
|
+
});
|
|
200
|
+
// Capture network requests
|
|
201
|
+
this.page.on('request', (request) => {
|
|
202
|
+
// Track requests
|
|
203
|
+
});
|
|
204
|
+
this.page.on('response', async (response) => {
|
|
205
|
+
try {
|
|
206
|
+
const request = response.request();
|
|
207
|
+
this.networkRequests.push({
|
|
208
|
+
url: request.url(),
|
|
209
|
+
method: request.method(),
|
|
210
|
+
status: response.status(),
|
|
211
|
+
timing: 0 // TODO: Calculate from timing API
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
catch (error) {
|
|
215
|
+
// Ignore errors
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Get the Playwright page instance
|
|
221
|
+
*/
|
|
222
|
+
getPage() {
|
|
223
|
+
return this.page;
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Navigate to a URL
|
|
227
|
+
*/
|
|
228
|
+
async navigate(url) {
|
|
229
|
+
if (!this.page) {
|
|
230
|
+
throw new Error('Browser not initialized');
|
|
231
|
+
}
|
|
232
|
+
await this.page.goto(url, { waitUntil: 'networkidle' });
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Capture screenshot of current page
|
|
236
|
+
*/
|
|
237
|
+
async captureScreenshot() {
|
|
238
|
+
if (!this.page) {
|
|
239
|
+
throw new Error('Browser not initialized');
|
|
240
|
+
}
|
|
241
|
+
return await this.page.screenshot({ type: 'png', fullPage: true });
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Navigate to tool URL and capture snapshot
|
|
245
|
+
*/
|
|
246
|
+
async captureSnapshot(url) {
|
|
247
|
+
if (!this.page) {
|
|
248
|
+
throw new Error('Browser not initialized');
|
|
249
|
+
}
|
|
250
|
+
// Reset tracking
|
|
251
|
+
this.consoleLogs = [];
|
|
252
|
+
this.networkRequests = [];
|
|
253
|
+
// Navigate to page
|
|
254
|
+
const startTime = Date.now();
|
|
255
|
+
await this.page.goto(url, { waitUntil: 'networkidle' });
|
|
256
|
+
const loadTime = Date.now() - startTime;
|
|
257
|
+
// Wait for render
|
|
258
|
+
await this.page.waitForTimeout(1000);
|
|
259
|
+
// Capture screenshot
|
|
260
|
+
const screenshot = await this.page.screenshot({
|
|
261
|
+
type: 'png',
|
|
262
|
+
fullPage: true
|
|
263
|
+
});
|
|
264
|
+
// Get DOM structure
|
|
265
|
+
const dom = await this.page.content();
|
|
266
|
+
// Get performance metrics
|
|
267
|
+
const performanceMetrics = await this.page.evaluate(() => {
|
|
268
|
+
const perf = performance.getEntriesByType?.('navigation')?.[0];
|
|
269
|
+
return {
|
|
270
|
+
loadTime: perf?.loadEventEnd - perf?.fetchStart || 0,
|
|
271
|
+
renderTime: perf?.domContentLoadedEventEnd - perf?.fetchStart || 0,
|
|
272
|
+
memoryUsage: performance.memory?.usedJSHeapSize || 0
|
|
273
|
+
};
|
|
274
|
+
});
|
|
275
|
+
// Get accessibility tree
|
|
276
|
+
const accessibilityTree = await this.captureAccessibilityTree();
|
|
277
|
+
// Framework detection (only when React introspection is enabled)
|
|
278
|
+
let frameworkReport;
|
|
279
|
+
if (this.reactIntrospection) {
|
|
280
|
+
try {
|
|
281
|
+
frameworkReport = (await this.page.evaluate(DETECT_SCRIPT));
|
|
282
|
+
}
|
|
283
|
+
catch { /* introspection is optional — never fail the snapshot */ }
|
|
284
|
+
}
|
|
285
|
+
return {
|
|
286
|
+
...(frameworkReport ? { react: frameworkReport } : {}),
|
|
287
|
+
screenshot: screenshot.toString('base64'),
|
|
288
|
+
dom,
|
|
289
|
+
console: this.consoleLogs,
|
|
290
|
+
network: this.networkRequests,
|
|
291
|
+
performance: {
|
|
292
|
+
loadTime,
|
|
293
|
+
renderTime: performanceMetrics.renderTime,
|
|
294
|
+
memoryUsage: performanceMetrics.memoryUsage
|
|
295
|
+
},
|
|
296
|
+
accessibility: accessibilityTree
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Capture accessibility tree for semantic understanding
|
|
301
|
+
*/
|
|
302
|
+
async captureAccessibilityTree() {
|
|
303
|
+
if (!this.page) {
|
|
304
|
+
throw new Error('Browser not initialized');
|
|
305
|
+
}
|
|
306
|
+
const snapshot = await this.page.accessibility.snapshot();
|
|
307
|
+
const roles = [];
|
|
308
|
+
const labels = [];
|
|
309
|
+
const traverse = (node) => {
|
|
310
|
+
if (!node)
|
|
311
|
+
return;
|
|
312
|
+
if (node.role)
|
|
313
|
+
roles.push(node.role);
|
|
314
|
+
if (node.name)
|
|
315
|
+
labels.push(node.name);
|
|
316
|
+
if (node.children) {
|
|
317
|
+
node.children.forEach(traverse);
|
|
318
|
+
}
|
|
319
|
+
};
|
|
320
|
+
traverse(snapshot);
|
|
321
|
+
return {
|
|
322
|
+
roles: Array.from(new Set(roles)),
|
|
323
|
+
labels: Array.from(new Set(labels)),
|
|
324
|
+
structure: snapshot
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Execute interaction command
|
|
329
|
+
*/
|
|
330
|
+
async interact(command) {
|
|
331
|
+
if (!this.page) {
|
|
332
|
+
throw new Error('Browser not initialized');
|
|
333
|
+
}
|
|
334
|
+
switch (command.type) {
|
|
335
|
+
case 'click':
|
|
336
|
+
if (command.selector) {
|
|
337
|
+
await this.page.click(command.selector);
|
|
338
|
+
}
|
|
339
|
+
else if (command.coordinates) {
|
|
340
|
+
await this.page.mouse.click(command.coordinates.x, command.coordinates.y);
|
|
341
|
+
}
|
|
342
|
+
break;
|
|
343
|
+
case 'type':
|
|
344
|
+
if (command.selector && command.value) {
|
|
345
|
+
await this.page.fill(command.selector, command.value);
|
|
346
|
+
}
|
|
347
|
+
break;
|
|
348
|
+
case 'navigate':
|
|
349
|
+
if (command.value) {
|
|
350
|
+
await this.page.goto(command.value);
|
|
351
|
+
}
|
|
352
|
+
break;
|
|
353
|
+
case 'scroll':
|
|
354
|
+
if (command.selector) {
|
|
355
|
+
await this.page.locator(command.selector).scrollIntoViewIfNeeded();
|
|
356
|
+
}
|
|
357
|
+
else if (command.deltaX !== undefined || command.deltaY !== undefined) {
|
|
358
|
+
await this.scroll({ deltaX: command.deltaX, deltaY: command.deltaY });
|
|
359
|
+
}
|
|
360
|
+
else if (command.coordinates) {
|
|
361
|
+
// Legacy support
|
|
362
|
+
await this.page.mouse.wheel(0, command.coordinates.y);
|
|
363
|
+
}
|
|
364
|
+
break;
|
|
365
|
+
case 'select':
|
|
366
|
+
if (command.selector && command.value) {
|
|
367
|
+
await this.page.selectOption(command.selector, command.value);
|
|
368
|
+
}
|
|
369
|
+
break;
|
|
370
|
+
case 'hover':
|
|
371
|
+
if (command.selector) {
|
|
372
|
+
await this.page.hover(command.selector);
|
|
373
|
+
}
|
|
374
|
+
break;
|
|
375
|
+
case 'keypress':
|
|
376
|
+
if (command.key) {
|
|
377
|
+
await this.keyPress(command.key, command.modifiers);
|
|
378
|
+
}
|
|
379
|
+
break;
|
|
380
|
+
case 'zoom':
|
|
381
|
+
if (command.zoomLevel) {
|
|
382
|
+
await this.zoom(command.zoomLevel);
|
|
383
|
+
}
|
|
384
|
+
break;
|
|
385
|
+
}
|
|
386
|
+
// Wait for any animations/updates
|
|
387
|
+
await this.page.waitForTimeout(500);
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
390
|
+
* Press keyboard key or key combination
|
|
391
|
+
* @param key Key to press ('Enter', 'Escape', 'a', 'Ctrl+V', etc.)
|
|
392
|
+
* @param modifiers Optional modifier keys (['Control', 'Shift', 'Alt', 'Meta'])
|
|
393
|
+
*/
|
|
394
|
+
async keyPress(key, modifiers) {
|
|
395
|
+
if (!this.page) {
|
|
396
|
+
throw new Error('Browser not initialized');
|
|
397
|
+
}
|
|
398
|
+
// Handle shorthand notation like 'Ctrl+V'
|
|
399
|
+
if (key.includes('+')) {
|
|
400
|
+
const parts = key.split('+');
|
|
401
|
+
if (parts.length >= 2 && parts[0] && parts[1]) {
|
|
402
|
+
const modifier = parts[0].toLowerCase();
|
|
403
|
+
const actualKey = parts[1];
|
|
404
|
+
// Convert shorthand to Playwright format
|
|
405
|
+
const modifierMap = {
|
|
406
|
+
'ctrl': 'Control',
|
|
407
|
+
'control': 'Control',
|
|
408
|
+
'shift': 'Shift',
|
|
409
|
+
'alt': 'Alt',
|
|
410
|
+
'meta': 'Meta',
|
|
411
|
+
'cmd': 'Meta',
|
|
412
|
+
'command': 'Meta'
|
|
413
|
+
};
|
|
414
|
+
const playwrightModifier = modifierMap[modifier] || modifier;
|
|
415
|
+
await this.page.keyboard.press(`${playwrightModifier}+${actualKey}`);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
else if (modifiers && modifiers.length > 0) {
|
|
419
|
+
// Use explicit modifiers
|
|
420
|
+
const modifierString = modifiers.join('+');
|
|
421
|
+
await this.page.keyboard.press(`${modifierString}+${key}`);
|
|
422
|
+
}
|
|
423
|
+
else {
|
|
424
|
+
// Simple key press
|
|
425
|
+
await this.page.keyboard.press(key);
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
/**
|
|
429
|
+
* Scroll the page
|
|
430
|
+
* @param delta Scroll delta { deltaX, deltaY }
|
|
431
|
+
*/
|
|
432
|
+
async scroll(delta) {
|
|
433
|
+
if (!this.page) {
|
|
434
|
+
throw new Error('Browser not initialized');
|
|
435
|
+
}
|
|
436
|
+
await this.page.mouse.wheel(delta.deltaX || 0, delta.deltaY || 0);
|
|
437
|
+
}
|
|
438
|
+
/**
|
|
439
|
+
* Zoom the page
|
|
440
|
+
* @param level Zoom level (1.0 = 100%, 1.5 = 150%, 0.5 = 50%)
|
|
441
|
+
*/
|
|
442
|
+
async zoom(level) {
|
|
443
|
+
if (!this.page) {
|
|
444
|
+
throw new Error('Browser not initialized');
|
|
445
|
+
}
|
|
446
|
+
await this.page.evaluate((zoomLevel) => {
|
|
447
|
+
document.body.style.zoom = `${zoomLevel * 100}%`;
|
|
448
|
+
}, level);
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* Copy text to clipboard
|
|
452
|
+
* @param text Text to copy to clipboard
|
|
453
|
+
*/
|
|
454
|
+
async copyToClipboard(text) {
|
|
455
|
+
if (!this.page) {
|
|
456
|
+
throw new Error('Browser not initialized');
|
|
457
|
+
}
|
|
458
|
+
await this.page.evaluate((textToCopy) => {
|
|
459
|
+
return navigator.clipboard.writeText(textToCopy);
|
|
460
|
+
}, text);
|
|
461
|
+
}
|
|
462
|
+
/**
|
|
463
|
+
* Get text from clipboard
|
|
464
|
+
* @returns Text from clipboard
|
|
465
|
+
*/
|
|
466
|
+
async getClipboard() {
|
|
467
|
+
if (!this.page) {
|
|
468
|
+
throw new Error('Browser not initialized');
|
|
469
|
+
}
|
|
470
|
+
return await this.page.evaluate(() => {
|
|
471
|
+
return navigator.clipboard.readText();
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
/**
|
|
475
|
+
* Paste text from clipboard at current focus
|
|
476
|
+
* Combines clipboard.writeText() with Ctrl+V keypress
|
|
477
|
+
* @param text Text to paste
|
|
478
|
+
*/
|
|
479
|
+
async paste(text) {
|
|
480
|
+
if (!this.page) {
|
|
481
|
+
throw new Error('Browser not initialized');
|
|
482
|
+
}
|
|
483
|
+
// Write to clipboard
|
|
484
|
+
await this.copyToClipboard(text);
|
|
485
|
+
// Wait a moment for clipboard to be ready
|
|
486
|
+
await this.page.waitForTimeout(100);
|
|
487
|
+
// Press Ctrl+V to paste
|
|
488
|
+
await this.keyPress('Ctrl+V');
|
|
489
|
+
}
|
|
490
|
+
/**
|
|
491
|
+
* Execute JavaScript code in page context
|
|
492
|
+
* Much faster than visual parsing for data extraction
|
|
493
|
+
*
|
|
494
|
+
* @param code JavaScript code to execute (string or function)
|
|
495
|
+
* @returns Result of the execution
|
|
496
|
+
*
|
|
497
|
+
* @example
|
|
498
|
+
* // Get all button texts
|
|
499
|
+
* const buttons = await executeJS(() => {
|
|
500
|
+
* return Array.from(document.querySelectorAll('button'))
|
|
501
|
+
* .map(b => b.textContent);
|
|
502
|
+
* });
|
|
503
|
+
*/
|
|
504
|
+
async executeJS(code) {
|
|
505
|
+
if (!this.page) {
|
|
506
|
+
throw new Error('Browser not initialized');
|
|
507
|
+
}
|
|
508
|
+
if (typeof code === 'function') {
|
|
509
|
+
return await this.page.evaluate(code);
|
|
510
|
+
}
|
|
511
|
+
else {
|
|
512
|
+
return await this.page.evaluate(code);
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
/**
|
|
516
|
+
* Execute JavaScript with arguments
|
|
517
|
+
* @param fn Function to execute in page context
|
|
518
|
+
* @param args Arguments to pass to the function
|
|
519
|
+
*/
|
|
520
|
+
async executeJSWithArgs(fn, ...args) {
|
|
521
|
+
if (!this.page) {
|
|
522
|
+
throw new Error('Browser not initialized');
|
|
523
|
+
}
|
|
524
|
+
// Playwright evaluate accepts (fn, arg) format, not spread args
|
|
525
|
+
return await this.page.evaluate(fn, args.length === 1 ? args[0] : args);
|
|
526
|
+
}
|
|
527
|
+
/**
|
|
528
|
+
* Get complete page state including JavaScript runtime data
|
|
529
|
+
* Much faster and more comprehensive than visual parsing
|
|
530
|
+
*/
|
|
531
|
+
async getPageState() {
|
|
532
|
+
if (!this.page) {
|
|
533
|
+
throw new Error('Browser not initialized');
|
|
534
|
+
}
|
|
535
|
+
return await this.page.evaluate(() => {
|
|
536
|
+
// @ts-ignore - Runs in browser context
|
|
537
|
+
return {
|
|
538
|
+
// Interactive elements
|
|
539
|
+
buttons: Array.from(document.querySelectorAll('button')).map((b) => ({
|
|
540
|
+
text: b.textContent?.trim(),
|
|
541
|
+
id: b.id,
|
|
542
|
+
className: b.className,
|
|
543
|
+
disabled: b.disabled,
|
|
544
|
+
visible: b.offsetParent !== null,
|
|
545
|
+
position: b.getBoundingClientRect()
|
|
546
|
+
})),
|
|
547
|
+
inputs: Array.from(document.querySelectorAll('input, textarea')).map((i) => ({
|
|
548
|
+
type: i.type,
|
|
549
|
+
name: i.name,
|
|
550
|
+
id: i.id,
|
|
551
|
+
value: i.value,
|
|
552
|
+
placeholder: i.placeholder,
|
|
553
|
+
required: i.required,
|
|
554
|
+
disabled: i.disabled
|
|
555
|
+
})),
|
|
556
|
+
forms: Array.from(document.querySelectorAll('form')).map((f) => ({
|
|
557
|
+
id: f.id,
|
|
558
|
+
name: f.name,
|
|
559
|
+
action: f.action,
|
|
560
|
+
method: f.method,
|
|
561
|
+
elements: f.elements.length
|
|
562
|
+
})),
|
|
563
|
+
links: Array.from(document.querySelectorAll('a')).map((a) => ({
|
|
564
|
+
text: a.textContent?.trim(),
|
|
565
|
+
href: a.href,
|
|
566
|
+
target: a.target
|
|
567
|
+
})),
|
|
568
|
+
// Page metadata
|
|
569
|
+
meta: {
|
|
570
|
+
title: document.title,
|
|
571
|
+
url: window.location.href,
|
|
572
|
+
referrer: document.referrer,
|
|
573
|
+
readyState: document.readyState
|
|
574
|
+
},
|
|
575
|
+
// Storage
|
|
576
|
+
storage: {
|
|
577
|
+
localStorage: { ...localStorage },
|
|
578
|
+
sessionStorage: { ...sessionStorage },
|
|
579
|
+
cookies: document.cookie
|
|
580
|
+
},
|
|
581
|
+
// Scripts and styles
|
|
582
|
+
resources: {
|
|
583
|
+
scripts: Array.from(document.scripts).map((s) => ({
|
|
584
|
+
src: s.src,
|
|
585
|
+
type: s.type,
|
|
586
|
+
async: s.async,
|
|
587
|
+
defer: s.defer
|
|
588
|
+
})),
|
|
589
|
+
stylesheets: Array.from(document.styleSheets).map((s) => ({
|
|
590
|
+
href: s.href,
|
|
591
|
+
disabled: s.disabled
|
|
592
|
+
}))
|
|
593
|
+
},
|
|
594
|
+
// Viewport and dimensions
|
|
595
|
+
viewport: {
|
|
596
|
+
width: window.innerWidth,
|
|
597
|
+
height: window.innerHeight,
|
|
598
|
+
scrollX: window.scrollX,
|
|
599
|
+
scrollY: window.scrollY,
|
|
600
|
+
scrollHeight: document.documentElement.scrollHeight,
|
|
601
|
+
scrollWidth: document.documentElement.scrollWidth
|
|
602
|
+
}
|
|
603
|
+
};
|
|
604
|
+
});
|
|
605
|
+
}
|
|
606
|
+
/**
|
|
607
|
+
* Get JavaScript errors from the page
|
|
608
|
+
* Uses Chrome DevTools Protocol for deep inspection
|
|
609
|
+
*/
|
|
610
|
+
async getJavaScriptErrors() {
|
|
611
|
+
if (!this.page) {
|
|
612
|
+
throw new Error('Browser not initialized');
|
|
613
|
+
}
|
|
614
|
+
const errors = [];
|
|
615
|
+
// Listen for runtime exceptions
|
|
616
|
+
this.page.on('pageerror', (error) => {
|
|
617
|
+
errors.push({
|
|
618
|
+
message: error.message,
|
|
619
|
+
stack: error.stack || '',
|
|
620
|
+
timestamp: Date.now()
|
|
621
|
+
});
|
|
622
|
+
});
|
|
623
|
+
return errors;
|
|
624
|
+
}
|
|
625
|
+
/**
|
|
626
|
+
* Enable Chrome DevTools Protocol for advanced debugging
|
|
627
|
+
* Returns CDP session for direct protocol access
|
|
628
|
+
*/
|
|
629
|
+
async enableDevTools() {
|
|
630
|
+
if (!this.page) {
|
|
631
|
+
throw new Error('Browser not initialized');
|
|
632
|
+
}
|
|
633
|
+
const client = await this.page.context().newCDPSession(this.page);
|
|
634
|
+
// Enable various DevTools domains
|
|
635
|
+
await client.send('Runtime.enable');
|
|
636
|
+
await client.send('Debugger.enable');
|
|
637
|
+
await client.send('Network.enable');
|
|
638
|
+
await client.send('Performance.enable');
|
|
639
|
+
// Listen to JavaScript exceptions
|
|
640
|
+
client.on('Runtime.exceptionThrown', (exception) => {
|
|
641
|
+
console.log('[CDP] JS Exception:', exception);
|
|
642
|
+
});
|
|
643
|
+
// Listen to console API calls
|
|
644
|
+
client.on('Runtime.consoleAPICalled', (call) => {
|
|
645
|
+
console.log('[CDP] Console call:', call);
|
|
646
|
+
});
|
|
647
|
+
return client;
|
|
648
|
+
}
|
|
649
|
+
/**
|
|
650
|
+
* Get detailed performance metrics from browser
|
|
651
|
+
* Uses Chrome DevTools Protocol Performance domain
|
|
652
|
+
*/
|
|
653
|
+
async getDetailedPerformanceMetrics() {
|
|
654
|
+
if (!this.page) {
|
|
655
|
+
throw new Error('Browser not initialized');
|
|
656
|
+
}
|
|
657
|
+
const client = await this.page.context().newCDPSession(this.page);
|
|
658
|
+
await client.send('Performance.enable');
|
|
659
|
+
const metrics = await client.send('Performance.getMetrics');
|
|
660
|
+
const getMetric = (name) => metrics.metrics.find((m) => m.name === name)?.value || 0;
|
|
661
|
+
return {
|
|
662
|
+
scriptDuration: getMetric('ScriptDuration'),
|
|
663
|
+
layoutDuration: getMetric('LayoutDuration'),
|
|
664
|
+
recalcStyleDuration: getMetric('RecalcStyleDuration'),
|
|
665
|
+
taskDuration: getMetric('TaskDuration'),
|
|
666
|
+
jsHeapUsedSize: getMetric('JSHeapUsedSize'),
|
|
667
|
+
jsHeapTotalSize: getMetric('JSHeapTotalSize'),
|
|
668
|
+
domNodes: getMetric('Nodes'),
|
|
669
|
+
layoutCount: getMetric('LayoutCount'),
|
|
670
|
+
recalcStyleCount: getMetric('RecalcStyleCount')
|
|
671
|
+
};
|
|
672
|
+
}
|
|
673
|
+
/**
|
|
674
|
+
* Comprehensive parallel analysis - visual + structural + performance
|
|
675
|
+
* Runs all analysis types simultaneously for maximum speed
|
|
676
|
+
*/
|
|
677
|
+
async comprehensiveAnalysis() {
|
|
678
|
+
if (!this.page) {
|
|
679
|
+
throw new Error('Browser not initialized');
|
|
680
|
+
}
|
|
681
|
+
const url = this.page.url();
|
|
682
|
+
// Run ALL analyses in parallel for speed!
|
|
683
|
+
const [screenshot, dom, pageState, accessibilityTree, performanceMetrics] = await Promise.all([
|
|
684
|
+
this.page.screenshot({ type: 'png', fullPage: true }),
|
|
685
|
+
this.page.content(),
|
|
686
|
+
this.getPageState(),
|
|
687
|
+
this.captureAccessibilityTree(),
|
|
688
|
+
this.getDetailedPerformanceMetrics()
|
|
689
|
+
]);
|
|
690
|
+
return {
|
|
691
|
+
url,
|
|
692
|
+
timestamp: Date.now(),
|
|
693
|
+
visual: {
|
|
694
|
+
screenshot: screenshot.toString('base64'),
|
|
695
|
+
viewport: pageState.viewport
|
|
696
|
+
},
|
|
697
|
+
structural: {
|
|
698
|
+
dom,
|
|
699
|
+
pageState,
|
|
700
|
+
accessibility: accessibilityTree
|
|
701
|
+
},
|
|
702
|
+
runtime: {
|
|
703
|
+
console: [...this.consoleLogs],
|
|
704
|
+
network: [...this.networkRequests],
|
|
705
|
+
performance: performanceMetrics
|
|
706
|
+
}
|
|
707
|
+
};
|
|
708
|
+
}
|
|
709
|
+
/**
|
|
710
|
+
* Execute batch of interactions
|
|
711
|
+
*/
|
|
712
|
+
async interactBatch(commands) {
|
|
713
|
+
for (const command of commands) {
|
|
714
|
+
await this.interact(command);
|
|
715
|
+
}
|
|
716
|
+
// Capture state after interactions
|
|
717
|
+
return await this.captureSnapshot(this.page.url());
|
|
718
|
+
}
|
|
719
|
+
/**
|
|
720
|
+
* Extract structured data from page
|
|
721
|
+
*/
|
|
722
|
+
async extractData(selector) {
|
|
723
|
+
if (!this.page) {
|
|
724
|
+
throw new Error('Browser not initialized');
|
|
725
|
+
}
|
|
726
|
+
if (selector) {
|
|
727
|
+
// @ts-ignore - This code runs in browser context where document exists
|
|
728
|
+
return await this.page.evaluate((sel) => {
|
|
729
|
+
const element = document.querySelector(sel);
|
|
730
|
+
return element ? element.textContent : null;
|
|
731
|
+
}, selector);
|
|
732
|
+
}
|
|
733
|
+
// Extract all structured data
|
|
734
|
+
// @ts-ignore - This code runs in browser context where document exists
|
|
735
|
+
return await this.page.evaluate(() => {
|
|
736
|
+
const data = {
|
|
737
|
+
title: document.title,
|
|
738
|
+
headings: Array.from(document.querySelectorAll('h1, h2, h3')).map((h) => h.textContent),
|
|
739
|
+
buttons: Array.from(document.querySelectorAll('button')).map((b) => ({
|
|
740
|
+
text: b.textContent,
|
|
741
|
+
disabled: b.disabled
|
|
742
|
+
})),
|
|
743
|
+
inputs: Array.from(document.querySelectorAll('input')).map((i) => ({
|
|
744
|
+
type: i.type,
|
|
745
|
+
placeholder: i.placeholder,
|
|
746
|
+
value: i.value
|
|
747
|
+
})),
|
|
748
|
+
links: Array.from(document.querySelectorAll('a')).map((a) => ({
|
|
749
|
+
text: a.textContent,
|
|
750
|
+
href: a.href
|
|
751
|
+
}))
|
|
752
|
+
};
|
|
753
|
+
return data;
|
|
754
|
+
});
|
|
755
|
+
}
|
|
756
|
+
/**
|
|
757
|
+
* Get visual diff between snapshots
|
|
758
|
+
*/
|
|
759
|
+
async compareSnapshots(before, after) {
|
|
760
|
+
// TODO: Implement visual diff using pixelmatch or similar
|
|
761
|
+
// For now, return DOM differences
|
|
762
|
+
const domDiff = [];
|
|
763
|
+
// Simple text diff (in production, use proper diff algorithm)
|
|
764
|
+
if (before.dom !== after.dom) {
|
|
765
|
+
domDiff.push('DOM structure changed');
|
|
766
|
+
}
|
|
767
|
+
const behaviorDiff = [];
|
|
768
|
+
// Check console logs
|
|
769
|
+
const newLogs = after.console.filter(log => !before.console.includes(log));
|
|
770
|
+
if (newLogs.length > 0) {
|
|
771
|
+
behaviorDiff.push(`New console logs: ${newLogs.length}`);
|
|
772
|
+
}
|
|
773
|
+
// Check network requests
|
|
774
|
+
if (after.network.length !== before.network.length) {
|
|
775
|
+
behaviorDiff.push(`Network requests changed: ${before.network.length} → ${after.network.length}`);
|
|
776
|
+
}
|
|
777
|
+
return {
|
|
778
|
+
imageDiff: '', // TODO: Implement pixel diff
|
|
779
|
+
domDiff,
|
|
780
|
+
behaviorDiff
|
|
781
|
+
};
|
|
782
|
+
}
|
|
783
|
+
/**
|
|
784
|
+
* Cleanup
|
|
785
|
+
*/
|
|
786
|
+
async close() {
|
|
787
|
+
if (this.page) {
|
|
788
|
+
await this.page.close();
|
|
789
|
+
this.page = null;
|
|
790
|
+
}
|
|
791
|
+
if (this.browser) {
|
|
792
|
+
await this.browser.close();
|
|
793
|
+
this.browser = null;
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
/**
|
|
797
|
+
* Format snapshot for model consumption
|
|
798
|
+
*/
|
|
799
|
+
formatForModel(snapshot) {
|
|
800
|
+
const lines = [];
|
|
801
|
+
lines.push('# Visual Snapshot');
|
|
802
|
+
lines.push('');
|
|
803
|
+
// Screenshot (model can see this with vision models)
|
|
804
|
+
lines.push('## Screenshot');
|
|
805
|
+
lines.push('');
|
|
806
|
+
lines.push(`}...)`);
|
|
807
|
+
lines.push('');
|
|
808
|
+
lines.push('*Note: Full screenshot available as base64 in metadata*');
|
|
809
|
+
lines.push('');
|
|
810
|
+
// Framework report (when React introspection is enabled)
|
|
811
|
+
if (snapshot.react) {
|
|
812
|
+
const r = snapshot.react;
|
|
813
|
+
lines.push('## Framework');
|
|
814
|
+
lines.push('');
|
|
815
|
+
if (r.react) {
|
|
816
|
+
lines.push(`React ${r.reactVersion ?? '(version unknown)'} detected (${r.rendererCount} renderer${r.rendererCount === 1 ? '' : 's'})${r.next ? ' + Next.js' : ''}`);
|
|
817
|
+
lines.push('Use sandbox_scan / sandbox_grab for component-level inspection (componentName, props, source).');
|
|
818
|
+
}
|
|
819
|
+
else {
|
|
820
|
+
const other = ['vue', 'svelte', 'angular'].filter((k) => r[k]);
|
|
821
|
+
lines.push(other.length ? `Framework: ${other.join(', ')}` : 'No framework detected (vanilla page)');
|
|
822
|
+
}
|
|
823
|
+
if (r.heavyLibraries.length)
|
|
824
|
+
lines.push(`Heavy libraries: ${r.heavyLibraries.join(', ')}`);
|
|
825
|
+
lines.push('');
|
|
826
|
+
}
|
|
827
|
+
// Structured data the model can easily parse
|
|
828
|
+
lines.push('## Page Structure');
|
|
829
|
+
lines.push('');
|
|
830
|
+
lines.push('```html');
|
|
831
|
+
lines.push(this.simplifyDOM(snapshot.dom));
|
|
832
|
+
lines.push('```');
|
|
833
|
+
lines.push('');
|
|
834
|
+
// Accessibility tree (semantic structure)
|
|
835
|
+
lines.push('## Semantic Structure');
|
|
836
|
+
lines.push('');
|
|
837
|
+
lines.push(`**Roles**: ${snapshot.accessibility.roles.join(', ')}`);
|
|
838
|
+
lines.push(`**Labels**: ${snapshot.accessibility.labels.slice(0, 10).join(', ')}`);
|
|
839
|
+
lines.push('');
|
|
840
|
+
// Console output
|
|
841
|
+
if (snapshot.console.length > 0) {
|
|
842
|
+
lines.push('## Console Output');
|
|
843
|
+
lines.push('');
|
|
844
|
+
lines.push('```');
|
|
845
|
+
snapshot.console.forEach(log => lines.push(log));
|
|
846
|
+
lines.push('```');
|
|
847
|
+
lines.push('');
|
|
848
|
+
}
|
|
849
|
+
// Network activity
|
|
850
|
+
if (snapshot.network.length > 0) {
|
|
851
|
+
lines.push('## Network Activity');
|
|
852
|
+
lines.push('');
|
|
853
|
+
snapshot.network.slice(0, 10).forEach(req => {
|
|
854
|
+
lines.push(`- ${req.method} ${req.url} → ${req.status}`);
|
|
855
|
+
});
|
|
856
|
+
lines.push('');
|
|
857
|
+
}
|
|
858
|
+
// Performance
|
|
859
|
+
lines.push('## Performance');
|
|
860
|
+
lines.push('');
|
|
861
|
+
lines.push(`- Load Time: ${snapshot.performance.loadTime}ms`);
|
|
862
|
+
lines.push(`- Render Time: ${snapshot.performance.renderTime}ms`);
|
|
863
|
+
lines.push(`- Memory: ${(snapshot.performance.memoryUsage / 1024 / 1024).toFixed(2)} MB`);
|
|
864
|
+
lines.push('');
|
|
865
|
+
return lines.join('\n');
|
|
866
|
+
}
|
|
867
|
+
/**
|
|
868
|
+
* Simplify DOM for model understanding
|
|
869
|
+
*/
|
|
870
|
+
simplifyDOM(html) {
|
|
871
|
+
// Remove scripts, styles, comments
|
|
872
|
+
let simplified = html
|
|
873
|
+
.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '')
|
|
874
|
+
.replace(/<style\b[^<]*(?:(?!<\/style>)<[^<]*)*<\/style>/gi, '')
|
|
875
|
+
.replace(/<!--[\s\S]*?-->/g, '');
|
|
876
|
+
// Extract key structure
|
|
877
|
+
const lines = simplified.split('\n')
|
|
878
|
+
.filter(line => line.trim())
|
|
879
|
+
.map(line => line.trim())
|
|
880
|
+
.slice(0, 50); // Limit to first 50 lines
|
|
881
|
+
return lines.join('\n');
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
/**
|
|
885
|
+
* Singleton instance
|
|
886
|
+
*/
|
|
887
|
+
export const visualBridge = new VisualFeedbackBridge();
|
|
888
|
+
//# sourceMappingURL=VisualFeedbackBridge.js.map
|