explorbot 0.0.1 → 0.1.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/README.md +80 -26
- package/bin/explorbot-cli.ts +680 -0
- package/boat/api-tester/src/ai/chief/styles.ts +15 -0
- package/boat/api-tester/src/ai/chief.ts +335 -0
- package/boat/api-tester/src/ai/curler-tools.ts +278 -0
- package/boat/api-tester/src/ai/curler.ts +306 -0
- package/boat/api-tester/src/api-client.ts +28 -0
- package/boat/api-tester/src/apibot.ts +203 -0
- package/boat/api-tester/src/cli.ts +301 -0
- package/boat/api-tester/src/config.ts +190 -0
- package/dist/bin/explorbot-cli.js +23 -101
- package/dist/boat/api-tester/bin/apibot-cli.js +0 -1
- package/dist/boat/api-tester/src/ai/chief/styles.js +0 -1
- package/dist/boat/api-tester/src/ai/chief.js +0 -1
- package/dist/boat/api-tester/src/ai/curler-tools.js +0 -1
- package/dist/boat/api-tester/src/ai/curler.js +0 -1
- package/dist/boat/api-tester/src/api-client.js +0 -1
- package/dist/boat/api-tester/src/apibot.js +0 -1
- package/dist/boat/api-tester/src/cli.js +0 -1
- package/dist/boat/api-tester/src/config.js +0 -1
- package/dist/src/action-result.js +0 -1
- package/dist/src/action.js +14 -12
- package/dist/src/activity.js +0 -1
- package/dist/src/ai/agent.js +0 -1
- package/dist/src/ai/bosun.js +0 -1
- package/dist/src/ai/captain/idle-mode.js +0 -1
- package/dist/src/ai/captain/mixin.js +0 -1
- package/dist/src/ai/captain/test-mode.js +0 -1
- package/dist/src/ai/captain/web-mode.js +0 -1
- package/dist/src/ai/captain.js +0 -1
- package/dist/src/ai/conversation.js +0 -1
- package/dist/src/ai/experience-compactor.js +0 -1
- package/dist/src/ai/fisherman-tools.js +0 -1
- package/dist/src/ai/fisherman.js +0 -1
- package/dist/src/ai/historian.js +0 -1
- package/dist/src/ai/navigator.js +0 -1
- package/dist/src/ai/pilot.js +0 -1
- package/dist/src/ai/planner/session-dedup.js +0 -1
- package/dist/src/ai/planner/styles.js +0 -1
- package/dist/src/ai/planner/subpages.js +42 -7
- package/dist/src/ai/planner.js +15 -4
- package/dist/src/ai/provider.js +0 -1
- package/dist/src/ai/quartermaster.js +0 -1
- package/dist/src/ai/researcher/cache.js +13 -9
- package/dist/src/ai/researcher/coordinates.js +4 -3
- package/dist/src/ai/researcher/deep-analysis.js +16 -20
- package/dist/src/ai/researcher/fingerprint-worker.js +0 -1
- package/dist/src/ai/researcher/focus.js +0 -1
- package/dist/src/ai/researcher/locators.js +1 -2
- package/dist/src/ai/researcher/mixin.js +0 -1
- package/dist/src/ai/researcher/parser.js +4 -4
- package/dist/src/ai/researcher/research-result.js +2 -1
- package/dist/src/ai/researcher.js +6 -6
- package/dist/src/ai/rules.js +0 -1
- package/dist/src/ai/task-agent.js +0 -1
- package/dist/src/ai/tester.js +0 -1
- package/dist/src/ai/tools.js +4 -1
- package/dist/src/api/api-client.js +0 -1
- package/dist/src/api/request-result.js +0 -1
- package/dist/src/api/request-store.js +0 -1
- package/dist/src/api/spec-reader.js +0 -1
- package/dist/src/api/xhr-capture.js +0 -1
- package/dist/src/browser-server.js +0 -1
- package/dist/src/command-handler.js +0 -1
- package/dist/src/commands/add-rule-command.js +0 -1
- package/dist/src/commands/base-command.js +0 -1
- package/dist/src/commands/clean-command.js +0 -1
- package/dist/src/commands/context-aria-command.js +0 -1
- package/dist/src/commands/context-command.js +2 -3
- package/dist/src/commands/context-data-command.js +0 -1
- package/dist/src/commands/context-experience-command.js +0 -1
- package/dist/src/commands/context-html-command.js +0 -1
- package/dist/src/commands/context-knowledge-command.js +0 -1
- package/dist/src/commands/debug-command.js +0 -1
- package/dist/src/commands/drill-command.js +0 -1
- package/dist/src/commands/exit-command.js +0 -1
- package/dist/src/commands/explore-command.js +3 -3
- package/dist/src/commands/freesail-command.js +0 -1
- package/dist/src/commands/help-command.js +0 -1
- package/dist/src/commands/index.js +0 -1
- package/dist/src/commands/init-command.js +117 -0
- package/dist/src/commands/knows-command.js +0 -1
- package/dist/src/commands/learn-command.js +0 -1
- package/dist/src/commands/navigate-command.js +0 -1
- package/dist/src/commands/path-command.js +0 -1
- package/dist/src/commands/plan-clear-command.js +0 -1
- package/dist/src/commands/plan-command.js +6 -2
- package/dist/src/commands/plan-edit-command.js +0 -1
- package/dist/src/commands/plan-load-command.js +0 -1
- package/dist/src/commands/plan-reload-command.js +0 -1
- package/dist/src/commands/plan-save-command.js +0 -1
- package/dist/src/commands/research-command.js +0 -1
- package/dist/src/commands/start-command.js +0 -1
- package/dist/src/commands/status-command.js +0 -1
- package/dist/src/commands/test-command.js +0 -1
- package/dist/src/components/ActivityPane.js +0 -1
- package/dist/src/components/AddKnowledge.js +0 -1
- package/dist/src/components/AddRule.js +0 -1
- package/dist/src/components/App.js +0 -1
- package/dist/src/components/Autocomplete.js +0 -1
- package/dist/src/components/InputPane.js +0 -1
- package/dist/src/components/InputReadline.js +0 -1
- package/dist/src/components/LogPane.js +0 -1
- package/dist/src/components/PlanEditor.js +0 -1
- package/dist/src/components/PlanPane.js +0 -1
- package/dist/src/components/SessionTimer.js +0 -1
- package/dist/src/components/StateTransitionPane.js +0 -1
- package/dist/src/components/StatusPane.js +0 -1
- package/dist/src/components/TaskPane.js +0 -1
- package/dist/src/components/Welcome.js +0 -1
- package/dist/src/components/WelcomeChecklist.js +0 -1
- package/dist/src/components/WelcomeCommands.js +0 -1
- package/dist/src/components/autocomplete-store.js +0 -1
- package/dist/src/components/parse-keypress.js +0 -1
- package/dist/src/config.js +0 -1
- package/dist/src/execution-controller.js +0 -1
- package/dist/src/experience-tracker.js +0 -1
- package/dist/src/explorbot.js +1 -2
- package/dist/src/explorer.js +58 -17
- package/dist/src/index.js +0 -1
- package/dist/src/knowledge-tracker.js +2 -2
- package/dist/src/observability.js +0 -1
- package/dist/src/reporter.js +0 -1
- package/dist/src/state-manager.js +0 -1
- package/dist/src/stats.js +0 -1
- package/dist/src/test-plan.js +0 -1
- package/dist/src/utils/aria.js +0 -1
- package/dist/src/utils/cli-name.js +16 -0
- package/dist/src/utils/code-extractor.js +0 -1
- package/dist/src/utils/context-formatter.js +0 -1
- package/dist/src/utils/error-page.js +0 -1
- package/dist/src/utils/expandable.js +0 -1
- package/dist/src/utils/hooks-runner.js +0 -1
- package/dist/src/utils/html-diff.js +0 -1
- package/dist/src/utils/html.js +0 -1
- package/dist/src/utils/logger.js +0 -1
- package/dist/src/utils/loop.js +0 -1
- package/dist/src/utils/markdown-parser.js +0 -1
- package/dist/src/utils/markdown-query.js +0 -1
- package/dist/src/utils/markdown-terminal.js +0 -1
- package/dist/src/utils/research-parser.js +0 -1
- package/dist/src/utils/retry.js +0 -1
- package/dist/src/utils/rules-loader.js +0 -1
- package/dist/src/utils/strings.js +0 -1
- package/dist/src/utils/test-plan-markdown.js +0 -1
- package/dist/src/utils/throttle.js +0 -1
- package/dist/src/utils/unique-names.js +0 -1
- package/dist/src/utils/url-matcher.js +0 -1
- package/dist/src/utils/web-element.js +6 -5
- package/dist/src/utils/xpath.js +0 -1
- package/package.json +28 -4
- package/src/action-result.ts +694 -0
- package/src/action.ts +449 -0
- package/src/activity.ts +111 -0
- package/src/ai/agent.ts +3 -0
- package/src/ai/bosun.ts +557 -0
- package/src/ai/captain/idle-mode.ts +116 -0
- package/src/ai/captain/mixin.ts +22 -0
- package/src/ai/captain/test-mode.ts +262 -0
- package/src/ai/captain/web-mode.ts +136 -0
- package/src/ai/captain.ts +504 -0
- package/src/ai/conversation.ts +205 -0
- package/src/ai/experience-compactor.ts +284 -0
- package/src/ai/fisherman-tools.ts +181 -0
- package/src/ai/fisherman.ts +223 -0
- package/src/ai/historian.ts +457 -0
- package/src/ai/navigator.ts +572 -0
- package/src/ai/pilot.ts +776 -0
- package/src/ai/planner/session-dedup.ts +35 -0
- package/src/ai/planner/styles.ts +17 -0
- package/src/ai/planner/subpages.ts +171 -0
- package/src/ai/planner.ts +549 -0
- package/src/ai/provider.ts +613 -0
- package/src/ai/quartermaster.ts +286 -0
- package/src/ai/researcher/cache.ts +109 -0
- package/src/ai/researcher/coordinates.ts +239 -0
- package/src/ai/researcher/deep-analysis.ts +412 -0
- package/src/ai/researcher/fingerprint-worker.ts +59 -0
- package/src/ai/researcher/focus.ts +42 -0
- package/src/ai/researcher/locators.ts +282 -0
- package/src/ai/researcher/mixin.ts +4 -0
- package/src/ai/researcher/parser.ts +186 -0
- package/src/ai/researcher/research-result.ts +116 -0
- package/src/ai/researcher.ts +858 -0
- package/src/ai/rules.ts +376 -0
- package/src/ai/task-agent.ts +141 -0
- package/src/ai/tester.ts +939 -0
- package/src/ai/tools.ts +1122 -0
- package/src/api/api-client.ts +109 -0
- package/src/api/request-result.ts +212 -0
- package/src/api/request-store.ts +130 -0
- package/src/api/spec-reader.ts +174 -0
- package/src/api/xhr-capture.ts +100 -0
- package/src/browser-server.ts +74 -0
- package/src/command-handler.ts +454 -0
- package/src/commands/add-rule-command.ts +63 -0
- package/src/commands/base-command.ts +27 -0
- package/src/commands/clean-command.ts +73 -0
- package/src/commands/context-aria-command.ts +22 -0
- package/src/commands/context-command.ts +67 -0
- package/src/commands/context-data-command.ts +30 -0
- package/src/commands/context-experience-command.ts +48 -0
- package/src/commands/context-html-command.ts +33 -0
- package/src/commands/context-knowledge-command.ts +43 -0
- package/src/commands/debug-command.ts +13 -0
- package/src/commands/drill-command.ts +34 -0
- package/src/commands/exit-command.ts +32 -0
- package/src/commands/explore-command.ts +129 -0
- package/src/commands/freesail-command.ts +95 -0
- package/src/commands/help-command.ts +8 -0
- package/src/commands/index.ts +69 -0
- package/src/commands/init-command.ts +131 -0
- package/src/commands/knows-command.ts +68 -0
- package/src/commands/learn-command.ts +44 -0
- package/src/commands/navigate-command.ts +18 -0
- package/src/commands/path-command.ts +83 -0
- package/src/commands/plan-clear-command.ts +14 -0
- package/src/commands/plan-command.ts +46 -0
- package/src/commands/plan-edit-command.ts +9 -0
- package/src/commands/plan-load-command.ts +18 -0
- package/src/commands/plan-reload-command.ts +28 -0
- package/src/commands/plan-save-command.ts +25 -0
- package/src/commands/research-command.ts +45 -0
- package/src/commands/start-command.ts +13 -0
- package/src/commands/status-command.tsx +23 -0
- package/src/commands/test-command.ts +84 -0
- package/src/components/ActivityPane.tsx +80 -0
- package/src/components/AddKnowledge.tsx +169 -0
- package/src/components/AddRule.tsx +174 -0
- package/src/components/App.tsx +377 -0
- package/src/components/Autocomplete.tsx +63 -0
- package/src/components/InputPane.tsx +259 -0
- package/src/components/InputReadline.tsx +704 -0
- package/src/components/LogPane.tsx +187 -0
- package/src/components/PlanEditor.tsx +150 -0
- package/src/components/PlanPane.tsx +71 -0
- package/src/components/SessionTimer.tsx +35 -0
- package/src/components/StateTransitionPane.tsx +149 -0
- package/src/components/StatusPane.tsx +62 -0
- package/src/components/TaskPane.tsx +119 -0
- package/src/components/Welcome.tsx +83 -0
- package/src/components/WelcomeChecklist.tsx +118 -0
- package/src/components/WelcomeCommands.tsx +102 -0
- package/src/components/autocomplete-store.ts +35 -0
- package/src/components/parse-keypress.ts +170 -0
- package/src/config.ts +491 -0
- package/src/execution-controller.ts +109 -0
- package/src/experience-tracker.ts +350 -0
- package/src/explorbot.ts +405 -0
- package/src/explorer.ts +760 -0
- package/src/index.tsx +62 -0
- package/src/knowledge-tracker.ts +230 -0
- package/src/observability.ts +150 -0
- package/src/reporter.ts +224 -0
- package/src/state-manager.ts +556 -0
- package/src/stats.ts +53 -0
- package/src/test-plan.ts +432 -0
- package/src/utils/aria.ts +629 -0
- package/src/utils/cli-name.ts +13 -0
- package/src/utils/code-extractor.ts +22 -0
- package/src/utils/context-formatter.ts +239 -0
- package/src/utils/error-page.ts +23 -0
- package/src/utils/expandable.ts +38 -0
- package/src/utils/hooks-runner.ts +79 -0
- package/src/utils/html-diff.ts +918 -0
- package/src/utils/html.ts +1316 -0
- package/src/utils/logger.ts +534 -0
- package/src/utils/loop.ts +176 -0
- package/src/utils/markdown-parser.ts +127 -0
- package/src/utils/markdown-query.ts +466 -0
- package/src/utils/markdown-terminal.ts +43 -0
- package/src/utils/research-parser.ts +11 -0
- package/src/utils/retry.ts +73 -0
- package/src/utils/rules-loader.ts +118 -0
- package/src/utils/strings.ts +13 -0
- package/src/utils/test-plan-markdown.ts +332 -0
- package/src/utils/throttle.ts +18 -0
- package/src/utils/unique-names.ts +14 -0
- package/src/utils/url-matcher.ts +45 -0
- package/src/utils/web-element.ts +147 -0
- package/src/utils/xpath.ts +129 -0
- package/dist/bin/explorbot-cli.js.map +0 -1
- package/dist/boat/api-tester/bin/apibot-cli.js.map +0 -1
- package/dist/boat/api-tester/example/apibot.config.js +0 -31
- package/dist/boat/api-tester/example/apibot.config.js.map +0 -1
- package/dist/boat/api-tester/src/ai/chief/styles.js.map +0 -1
- package/dist/boat/api-tester/src/ai/chief.js.map +0 -1
- package/dist/boat/api-tester/src/ai/curler-tools.js.map +0 -1
- package/dist/boat/api-tester/src/ai/curler.js.map +0 -1
- package/dist/boat/api-tester/src/api-client.js.map +0 -1
- package/dist/boat/api-tester/src/apibot.js.map +0 -1
- package/dist/boat/api-tester/src/cli.js.map +0 -1
- package/dist/boat/api-tester/src/config.js.map +0 -1
- package/dist/prompts/audit-rules.md +0 -124
- package/dist/src/action-result.js.map +0 -1
- package/dist/src/action.js.map +0 -1
- package/dist/src/activity.js.map +0 -1
- package/dist/src/ai/agent.js.map +0 -1
- package/dist/src/ai/bosun.js.map +0 -1
- package/dist/src/ai/captain/idle-mode.js.map +0 -1
- package/dist/src/ai/captain/mixin.js.map +0 -1
- package/dist/src/ai/captain/test-mode.js.map +0 -1
- package/dist/src/ai/captain/web-mode.js.map +0 -1
- package/dist/src/ai/captain.js.map +0 -1
- package/dist/src/ai/conversation.js.map +0 -1
- package/dist/src/ai/experience-compactor.js.map +0 -1
- package/dist/src/ai/fisherman-tools.js.map +0 -1
- package/dist/src/ai/fisherman.js.map +0 -1
- package/dist/src/ai/historian.js.map +0 -1
- package/dist/src/ai/navigator.js.map +0 -1
- package/dist/src/ai/pilot.js.map +0 -1
- package/dist/src/ai/planner/session-dedup.js.map +0 -1
- package/dist/src/ai/planner/styles.js.map +0 -1
- package/dist/src/ai/planner/subpages.js.map +0 -1
- package/dist/src/ai/planner.js.map +0 -1
- package/dist/src/ai/provider.js.map +0 -1
- package/dist/src/ai/quartermaster.js.map +0 -1
- package/dist/src/ai/researcher/cache.js.map +0 -1
- package/dist/src/ai/researcher/coordinates.js.map +0 -1
- package/dist/src/ai/researcher/deep-analysis.js.map +0 -1
- package/dist/src/ai/researcher/fingerprint-worker.js.map +0 -1
- package/dist/src/ai/researcher/focus.js.map +0 -1
- package/dist/src/ai/researcher/locators.js.map +0 -1
- package/dist/src/ai/researcher/mixin.js.map +0 -1
- package/dist/src/ai/researcher/parser.js.map +0 -1
- package/dist/src/ai/researcher/research-result.js.map +0 -1
- package/dist/src/ai/researcher.js.map +0 -1
- package/dist/src/ai/rules.js.map +0 -1
- package/dist/src/ai/task-agent.js.map +0 -1
- package/dist/src/ai/tester.js.map +0 -1
- package/dist/src/ai/tools.js.map +0 -1
- package/dist/src/api/api-client.js.map +0 -1
- package/dist/src/api/request-result.js.map +0 -1
- package/dist/src/api/request-store.js.map +0 -1
- package/dist/src/api/spec-reader.js.map +0 -1
- package/dist/src/api/xhr-capture.js.map +0 -1
- package/dist/src/browser-server.js.map +0 -1
- package/dist/src/command-handler.js.map +0 -1
- package/dist/src/commands/add-rule-command.js.map +0 -1
- package/dist/src/commands/base-command.js.map +0 -1
- package/dist/src/commands/clean-command.js.map +0 -1
- package/dist/src/commands/context-aria-command.js.map +0 -1
- package/dist/src/commands/context-command.js.map +0 -1
- package/dist/src/commands/context-data-command.js.map +0 -1
- package/dist/src/commands/context-experience-command.js.map +0 -1
- package/dist/src/commands/context-html-command.js.map +0 -1
- package/dist/src/commands/context-knowledge-command.js.map +0 -1
- package/dist/src/commands/debug-command.js.map +0 -1
- package/dist/src/commands/drill-command.js.map +0 -1
- package/dist/src/commands/exit-command.js.map +0 -1
- package/dist/src/commands/explore-command.js.map +0 -1
- package/dist/src/commands/freesail-command.js.map +0 -1
- package/dist/src/commands/help-command.js.map +0 -1
- package/dist/src/commands/index.js.map +0 -1
- package/dist/src/commands/knows-command.js.map +0 -1
- package/dist/src/commands/learn-command.js.map +0 -1
- package/dist/src/commands/navigate-command.js.map +0 -1
- package/dist/src/commands/path-command.js.map +0 -1
- package/dist/src/commands/plan-clear-command.js.map +0 -1
- package/dist/src/commands/plan-command.js.map +0 -1
- package/dist/src/commands/plan-edit-command.js.map +0 -1
- package/dist/src/commands/plan-load-command.js.map +0 -1
- package/dist/src/commands/plan-reload-command.js.map +0 -1
- package/dist/src/commands/plan-save-command.js.map +0 -1
- package/dist/src/commands/research-command.js.map +0 -1
- package/dist/src/commands/start-command.js.map +0 -1
- package/dist/src/commands/status-command.js.map +0 -1
- package/dist/src/commands/test-command.js.map +0 -1
- package/dist/src/components/ActivityPane.js.map +0 -1
- package/dist/src/components/AddKnowledge.js.map +0 -1
- package/dist/src/components/AddRule.js.map +0 -1
- package/dist/src/components/App.js.map +0 -1
- package/dist/src/components/Autocomplete.js.map +0 -1
- package/dist/src/components/InputPane.js.map +0 -1
- package/dist/src/components/InputReadline.js.map +0 -1
- package/dist/src/components/LogPane.js.map +0 -1
- package/dist/src/components/PlanEditor.js.map +0 -1
- package/dist/src/components/PlanPane.js.map +0 -1
- package/dist/src/components/SessionTimer.js.map +0 -1
- package/dist/src/components/StateTransitionPane.js.map +0 -1
- package/dist/src/components/StatusPane.js.map +0 -1
- package/dist/src/components/TaskPane.js.map +0 -1
- package/dist/src/components/Welcome.js.map +0 -1
- package/dist/src/components/WelcomeChecklist.js.map +0 -1
- package/dist/src/components/WelcomeCommands.js.map +0 -1
- package/dist/src/components/autocomplete-store.js.map +0 -1
- package/dist/src/components/parse-keypress.js.map +0 -1
- package/dist/src/config.js.map +0 -1
- package/dist/src/execution-controller.js.map +0 -1
- package/dist/src/experience-tracker.js.map +0 -1
- package/dist/src/explorbot.js.map +0 -1
- package/dist/src/explorer.js.map +0 -1
- package/dist/src/index.js.map +0 -1
- package/dist/src/knowledge-tracker.js.map +0 -1
- package/dist/src/observability.js.map +0 -1
- package/dist/src/reporter.js.map +0 -1
- package/dist/src/state-manager.js.map +0 -1
- package/dist/src/stats.js.map +0 -1
- package/dist/src/test-plan.js.map +0 -1
- package/dist/src/utils/aria.js.map +0 -1
- package/dist/src/utils/code-extractor.js.map +0 -1
- package/dist/src/utils/context-formatter.js.map +0 -1
- package/dist/src/utils/error-page.js.map +0 -1
- package/dist/src/utils/expandable.js.map +0 -1
- package/dist/src/utils/hooks-runner.js.map +0 -1
- package/dist/src/utils/html-diff.js.map +0 -1
- package/dist/src/utils/html.js.map +0 -1
- package/dist/src/utils/logger.js.map +0 -1
- package/dist/src/utils/loop.js.map +0 -1
- package/dist/src/utils/markdown-parser.js.map +0 -1
- package/dist/src/utils/markdown-query.js.map +0 -1
- package/dist/src/utils/markdown-terminal.js.map +0 -1
- package/dist/src/utils/research-parser.js.map +0 -1
- package/dist/src/utils/retry.js.map +0 -1
- package/dist/src/utils/rules-loader.js.map +0 -1
- package/dist/src/utils/strings.js.map +0 -1
- package/dist/src/utils/test-plan-markdown.js.map +0 -1
- package/dist/src/utils/throttle.js.map +0 -1
- package/dist/src/utils/unique-names.js.map +0 -1
- package/dist/src/utils/url-matcher.js.map +0 -1
- package/dist/src/utils/web-element.js.map +0 -1
- package/dist/src/utils/xpath.js.map +0 -1
- package/prompts/audit-rules.md +0 -124
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
import { tool } from 'ai';
|
|
2
|
+
import dedent from 'dedent';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import type { WebPageState } from '../../state-manager.ts';
|
|
5
|
+
import { toolExecutionLabel } from '../conversation.ts';
|
|
6
|
+
import { type Constructor, type ModeContext, debugLog } from './mixin.ts';
|
|
7
|
+
|
|
8
|
+
export function WithTestMode<T extends Constructor>(Base: T) {
|
|
9
|
+
return class extends Base {
|
|
10
|
+
testModeTools(ctx: ModeContext): Record<string, any> {
|
|
11
|
+
return {
|
|
12
|
+
test: tool({
|
|
13
|
+
description: dedent`
|
|
14
|
+
Inspect test execution data. Use flags to control output depth.
|
|
15
|
+
Tests are identified by sessionName (e.g. "brave-fox123").
|
|
16
|
+
|
|
17
|
+
Examples:
|
|
18
|
+
test() — summary of all tests in plan (with sessionNames)
|
|
19
|
+
test --session brave-fox123 — overview with structured timeline (step, action, success, state, url)
|
|
20
|
+
test --session brave-fox123 --step 5 — drill into step 5: full commands, code, attempts, error, suggestion
|
|
21
|
+
test --session brave-fox123 --log — full chronological execution log
|
|
22
|
+
test --session brave-fox123 --code — generated CodeceptJS code
|
|
23
|
+
test --session brave-fox123 --pilot — Pilot's last analysis
|
|
24
|
+
`,
|
|
25
|
+
inputSchema: z.object({
|
|
26
|
+
session: z.string().optional().describe('Test sessionName (e.g. "brave-fox123"). Omit for plan summary.'),
|
|
27
|
+
step: z.number().optional().describe('Drill into step N from timeline — shows full commands, code, attempts, suggestions'),
|
|
28
|
+
log: z.boolean().optional().describe('Include full execution log'),
|
|
29
|
+
code: z.boolean().optional().describe('Include generated CodeceptJS code'),
|
|
30
|
+
pilot: z.boolean().optional().describe('Include Pilot analysis'),
|
|
31
|
+
}),
|
|
32
|
+
execute: async ({ session, step, log, code, pilot }) => {
|
|
33
|
+
const plan = ctx.explorBot.getCurrentPlan();
|
|
34
|
+
if (!plan || plan.tests.length === 0) return { success: false, message: 'No plan or tests available' };
|
|
35
|
+
|
|
36
|
+
if (!session) {
|
|
37
|
+
return {
|
|
38
|
+
success: true,
|
|
39
|
+
planTitle: plan.title,
|
|
40
|
+
tests: plan.tests.map((t) => ({
|
|
41
|
+
session: t.sessionName,
|
|
42
|
+
scenario: t.scenario,
|
|
43
|
+
status: t.status,
|
|
44
|
+
result: t.result,
|
|
45
|
+
priority: t.priority,
|
|
46
|
+
})),
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const t = plan.tests.find((test) => test.sessionName === session);
|
|
51
|
+
if (!t) return { success: false, message: `Test "${session}" not found` };
|
|
52
|
+
|
|
53
|
+
const testerConv = ctx.explorBot.agentTester().getConversation();
|
|
54
|
+
|
|
55
|
+
if (step !== undefined) {
|
|
56
|
+
if (!testerConv) return { success: false, message: 'No tester conversation available' };
|
|
57
|
+
const execs = testerConv.getToolExecutions();
|
|
58
|
+
if (step < 0 || step >= execs.length) return { success: false, message: `Step ${step} not found (${execs.length} steps available)` };
|
|
59
|
+
const e = execs[step];
|
|
60
|
+
return {
|
|
61
|
+
success: true,
|
|
62
|
+
step,
|
|
63
|
+
action: e.toolName,
|
|
64
|
+
explanation: toolExecutionLabel(e.input),
|
|
65
|
+
commands: e.input?.commands || null,
|
|
66
|
+
code: e.output?.code || null,
|
|
67
|
+
attempts: e.output?.attempts || null,
|
|
68
|
+
suggestion: e.output?.suggestion || null,
|
|
69
|
+
wasSuccessful: e.wasSuccessful,
|
|
70
|
+
error: e.wasSuccessful ? null : e.output?.message || null,
|
|
71
|
+
ariaChanges: e.output?.pageDiff?.ariaChanges || null,
|
|
72
|
+
url: e.output?.pageDiff?.currentUrl || null,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const result: Record<string, any> = {
|
|
77
|
+
success: true,
|
|
78
|
+
session: t.sessionName,
|
|
79
|
+
scenario: t.scenario,
|
|
80
|
+
status: t.status,
|
|
81
|
+
result: t.result,
|
|
82
|
+
priority: t.priority,
|
|
83
|
+
startUrl: t.startUrl,
|
|
84
|
+
expected: t.expected,
|
|
85
|
+
notes: t.notesToString(),
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
if (testerConv) {
|
|
89
|
+
const execs = testerConv.getToolExecutions();
|
|
90
|
+
let currentStateIdx = -1;
|
|
91
|
+
let currentUrl = t.startUrl;
|
|
92
|
+
|
|
93
|
+
result.timeline = execs.map((e, i) => {
|
|
94
|
+
const newUrl = e.output?.pageDiff?.currentUrl;
|
|
95
|
+
if (newUrl && newUrl !== currentUrl) {
|
|
96
|
+
currentUrl = newUrl;
|
|
97
|
+
currentStateIdx = t.states.findIndex((s, idx) => idx > currentStateIdx && s.url === newUrl);
|
|
98
|
+
if (currentStateIdx === -1) currentStateIdx = t.states.length - 1;
|
|
99
|
+
}
|
|
100
|
+
const entry: Record<string, any> = {
|
|
101
|
+
step: i,
|
|
102
|
+
action: e.toolName,
|
|
103
|
+
explanation: toolExecutionLabel(e.input),
|
|
104
|
+
success: e.wasSuccessful,
|
|
105
|
+
url: currentUrl,
|
|
106
|
+
};
|
|
107
|
+
if (currentStateIdx >= 0) entry.state = currentStateIdx;
|
|
108
|
+
if (!e.wasSuccessful) entry.error = e.output?.message || null;
|
|
109
|
+
if (e.output?.pageDiff?.ariaChanges) entry.ariaChanges = e.output.pageDiff.ariaChanges;
|
|
110
|
+
return entry;
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (log) result.log = t.getLogString();
|
|
115
|
+
|
|
116
|
+
if (code) result.generatedCode = t.generatedCode || 'Not generated yet';
|
|
117
|
+
|
|
118
|
+
if (pilot) {
|
|
119
|
+
result.pilotAnalysis = ctx.explorBot.agentPilot().getLastAnalysis() || 'No analysis available';
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return result;
|
|
123
|
+
},
|
|
124
|
+
}),
|
|
125
|
+
|
|
126
|
+
inspectState: tool({
|
|
127
|
+
description: dedent`
|
|
128
|
+
Inspect previously visited page states. Shows URL, title, headings, associated files, and changes from previous state.
|
|
129
|
+
Use bash('cat <file>') to read HTML/log files. Use navigate() to go to the state's URL.
|
|
130
|
+
|
|
131
|
+
inspectState() — list all states from current page history
|
|
132
|
+
inspectState --session brave-fox123 — list all states from test session
|
|
133
|
+
inspectState --session brave-fox123 --index 2 — details of state 2: headings, ARIA, files, diff from state 1
|
|
134
|
+
`,
|
|
135
|
+
inputSchema: z.object({
|
|
136
|
+
session: z.string().optional().describe('Test session name. Uses current page history if omitted.'),
|
|
137
|
+
index: z.number().optional().describe('State index for detailed inspection'),
|
|
138
|
+
}),
|
|
139
|
+
execute: async ({ session, index }) => {
|
|
140
|
+
let states: WebPageState[];
|
|
141
|
+
|
|
142
|
+
if (session) {
|
|
143
|
+
const plan = ctx.explorBot.getCurrentPlan();
|
|
144
|
+
if (!plan) return { success: false, message: 'No plan available' };
|
|
145
|
+
const t = plan.tests.find((test) => test.sessionName === session);
|
|
146
|
+
if (!t) return { success: false, message: `Test "${session}" not found` };
|
|
147
|
+
states = t.states;
|
|
148
|
+
} else {
|
|
149
|
+
const stateManager = ctx.explorBot.getExplorer().getStateManager();
|
|
150
|
+
const history = stateManager.getStateHistory();
|
|
151
|
+
const seen = new Set<string>();
|
|
152
|
+
states = history
|
|
153
|
+
.map((t) => t.toState)
|
|
154
|
+
.filter((s) => {
|
|
155
|
+
const key = s.hash || s.url;
|
|
156
|
+
if (seen.has(key)) return false;
|
|
157
|
+
seen.add(key);
|
|
158
|
+
return true;
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (states.length === 0) return { success: true, states: [], message: 'No states recorded' };
|
|
163
|
+
|
|
164
|
+
if (index === undefined) {
|
|
165
|
+
return {
|
|
166
|
+
success: true,
|
|
167
|
+
states: states.map((s, i) => ({
|
|
168
|
+
index: i,
|
|
169
|
+
url: s.url,
|
|
170
|
+
title: s.title,
|
|
171
|
+
h1: s.h1,
|
|
172
|
+
})),
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (index < 0 || index >= states.length) {
|
|
177
|
+
return { success: false, message: `State ${index} not found (${states.length} states available)` };
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const state = states[index];
|
|
181
|
+
const prev = index > 0 ? states[index - 1] : null;
|
|
182
|
+
|
|
183
|
+
const changes: string[] = [];
|
|
184
|
+
if (prev) {
|
|
185
|
+
if (prev.url !== state.url) changes.push(`URL changed from ${prev.url} to ${state.url}`);
|
|
186
|
+
if (prev.h1 !== state.h1 && state.h1) changes.push(`new H1: ${state.h1}`);
|
|
187
|
+
if (prev.title !== state.title && state.title) changes.push(`title changed to: ${state.title}`);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const files: Record<string, string | null> = {
|
|
191
|
+
html: state.htmlFile || null,
|
|
192
|
+
screenshot: state.screenshotFile || null,
|
|
193
|
+
log: state.logFile || null,
|
|
194
|
+
aria: state.ariaSnapshotFile || null,
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
const suggestions: string[] = [];
|
|
198
|
+
if (state.htmlFile) suggestions.push(`Use bash('cat ${state.htmlFile}') to see full HTML.`);
|
|
199
|
+
if (state.url) suggestions.push(`Use navigate('${state.url}') to go to this page.`);
|
|
200
|
+
|
|
201
|
+
debugLog('inspectState index=%d url=%s', index, state.url);
|
|
202
|
+
|
|
203
|
+
return {
|
|
204
|
+
success: true,
|
|
205
|
+
index,
|
|
206
|
+
url: state.url,
|
|
207
|
+
title: state.title,
|
|
208
|
+
h1: state.h1,
|
|
209
|
+
h2: state.h2,
|
|
210
|
+
h3: state.h3,
|
|
211
|
+
h4: state.h4,
|
|
212
|
+
ariaSnapshot: state.ariaSnapshot,
|
|
213
|
+
files,
|
|
214
|
+
changesFromPrevious: changes.length > 0 ? changes.join(', ') : null,
|
|
215
|
+
suggestion: suggestions.join(' '),
|
|
216
|
+
};
|
|
217
|
+
},
|
|
218
|
+
}),
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
testModePrompt(): string {
|
|
223
|
+
return dedent`
|
|
224
|
+
<test_capabilities>
|
|
225
|
+
- Test inspection: test() — timeline, steps, log, code, pilot analysis
|
|
226
|
+
- State inspection: inspectState() — traverse previously visited page states
|
|
227
|
+
- Test control: runCommand("/test stop"), runCommand("/test skip")
|
|
228
|
+
</test_capabilities>
|
|
229
|
+
|
|
230
|
+
<debugging_skill>
|
|
231
|
+
When user asks "why did X fail?" or about test problems:
|
|
232
|
+
|
|
233
|
+
1. IDENTIFY — test() without flags to list all tests. Name the failed test.
|
|
234
|
+
2. OVERVIEW — test --session <name> to read the timeline. Find the step where behavior diverged.
|
|
235
|
+
3. DRILL — test --session <name> --step N to inspect the failing step details.
|
|
236
|
+
4. INSPECT STATE — inspectState --session <name> --index N to see page ARIA at that point.
|
|
237
|
+
5. CONTEXT — Use bash('cat <file>') to read HTML/log files referenced by inspectState.
|
|
238
|
+
6. REPORT — Explain with specifics: test name, which step failed, what was attempted, your hypothesis.
|
|
239
|
+
|
|
240
|
+
Always name the test session and scenario when discussing results.
|
|
241
|
+
Do NOT call done() after just reading data — investigate first.
|
|
242
|
+
</debugging_skill>
|
|
243
|
+
`;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
testModeRules(): string {
|
|
247
|
+
return dedent`
|
|
248
|
+
- Use test() to inspect what the tester is doing
|
|
249
|
+
- Use inspectState() to explore page states — use bash('cat <file>') for HTML/logs
|
|
250
|
+
- When debugging test failures, follow <debugging_skill> — do not summarize without investigating
|
|
251
|
+
- Use test() with minimal flags first, then drill into timeline steps and states as needed
|
|
252
|
+
- Prefer ARIA over HTML — avoid full HTML reads
|
|
253
|
+
`;
|
|
254
|
+
}
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
export interface TestModeMethods {
|
|
259
|
+
testModeTools(ctx: ModeContext): Record<string, any>;
|
|
260
|
+
testModePrompt(): string;
|
|
261
|
+
testModeRules(): string;
|
|
262
|
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { tool } from 'ai';
|
|
2
|
+
import dedent from 'dedent';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import { actionRule, locatorRule, sectionContextRule } from '../rules.ts';
|
|
5
|
+
import { createAgentTools, createCodeceptJSTools } from '../tools.ts';
|
|
6
|
+
import { type Constructor, type ModeContext, debugLog } from './mixin.ts';
|
|
7
|
+
|
|
8
|
+
export function WithWebMode<T extends Constructor>(Base: T) {
|
|
9
|
+
return class extends Base {
|
|
10
|
+
webModeTools(ctx: ModeContext): Record<string, any> {
|
|
11
|
+
const explorer = ctx.explorBot.getExplorer();
|
|
12
|
+
const codeceptTools = createCodeceptJSTools(explorer, ctx.task);
|
|
13
|
+
const agentTools = createAgentTools({
|
|
14
|
+
explorer,
|
|
15
|
+
researcher: ctx.explorBot.agentResearcher(),
|
|
16
|
+
navigator: ctx.explorBot.agentNavigator(),
|
|
17
|
+
});
|
|
18
|
+
const { see, context, visualClick } = agentTools;
|
|
19
|
+
|
|
20
|
+
return {
|
|
21
|
+
navigate: tool({
|
|
22
|
+
description: 'Navigate to a URL or page description using AI-powered navigation.',
|
|
23
|
+
inputSchema: z.object({
|
|
24
|
+
destination: z.string().describe('URL path or page description, e.g. "/login", "go to user settings"'),
|
|
25
|
+
}),
|
|
26
|
+
execute: async ({ destination }) => {
|
|
27
|
+
try {
|
|
28
|
+
debugLog('navigate', destination);
|
|
29
|
+
await ctx.explorBot.agentNavigator().visit(destination);
|
|
30
|
+
const stateManager = ctx.explorBot.getExplorer().getStateManager();
|
|
31
|
+
const state = stateManager.getCurrentState();
|
|
32
|
+
return { success: true, url: state?.url, title: state?.title };
|
|
33
|
+
} catch (error: any) {
|
|
34
|
+
return { success: false, message: `Navigation failed: ${error.message}` };
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
}),
|
|
38
|
+
|
|
39
|
+
browser: tool({
|
|
40
|
+
description: dedent`
|
|
41
|
+
Direct browser access via Playwright. Use for diagnostics and browser management.
|
|
42
|
+
Actions:
|
|
43
|
+
- evaluate: Run JavaScript in browser context (localStorage, cookies, DOM, console)
|
|
44
|
+
- closeTabs: Close all browser tabs except the current one
|
|
45
|
+
- screenshot: Take a screenshot of current page
|
|
46
|
+
- reload: Reload the current page
|
|
47
|
+
`,
|
|
48
|
+
inputSchema: z.object({
|
|
49
|
+
action: z.enum(['evaluate', 'closeTabs', 'screenshot', 'reload']).describe('Browser action to perform'),
|
|
50
|
+
code: z.string().optional().describe('JavaScript code for evaluate action'),
|
|
51
|
+
}),
|
|
52
|
+
execute: async ({ action, code }) => {
|
|
53
|
+
const page = ctx.explorBot.getExplorer().playwrightHelper?.page;
|
|
54
|
+
if (!page) return { success: false, message: 'No browser page available' };
|
|
55
|
+
|
|
56
|
+
if (action === 'evaluate') {
|
|
57
|
+
if (!code) return { success: false, message: 'Code required for evaluate action' };
|
|
58
|
+
try {
|
|
59
|
+
const result = await page.evaluate(code);
|
|
60
|
+
const serialized = typeof result === 'object' ? JSON.stringify(result, null, 2) : String(result ?? '');
|
|
61
|
+
return { success: true, result: serialized.length > 2000 ? `${serialized.slice(0, 2000)}\n...truncated` : serialized };
|
|
62
|
+
} catch (error: any) {
|
|
63
|
+
return { success: false, message: `Evaluate failed: ${error.message}` };
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (action === 'closeTabs') {
|
|
68
|
+
const browserContext = page.context();
|
|
69
|
+
const pages = browserContext.pages();
|
|
70
|
+
let closed = 0;
|
|
71
|
+
for (const p of pages) {
|
|
72
|
+
if (p !== page) {
|
|
73
|
+
await p.close();
|
|
74
|
+
closed++;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return { success: true, message: `Closed ${closed} tab(s), ${pages.length - closed} remaining` };
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (action === 'screenshot') {
|
|
81
|
+
const buffer = await page.screenshot({ type: 'png' });
|
|
82
|
+
const base64 = buffer.toString('base64');
|
|
83
|
+
return { success: true, screenshot: base64.length > 5000 ? `${base64.slice(0, 5000)}...truncated` : base64 };
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (action === 'reload') {
|
|
87
|
+
await page.reload();
|
|
88
|
+
return { success: true, message: 'Page reloaded' };
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return { success: false, message: `Unknown action: ${action}` };
|
|
92
|
+
},
|
|
93
|
+
}),
|
|
94
|
+
|
|
95
|
+
...codeceptTools,
|
|
96
|
+
see,
|
|
97
|
+
context,
|
|
98
|
+
visualClick,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
webModePrompt(): string {
|
|
103
|
+
return dedent`
|
|
104
|
+
<web_capabilities>
|
|
105
|
+
- Page actions: click, pressKey, form (CodeceptJS tools)
|
|
106
|
+
- Navigation: navigate() — AI-powered navigation to URLs or page descriptions
|
|
107
|
+
- Browser diagnostics: browser() — evaluate JS, close tabs, screenshot, reload
|
|
108
|
+
- Visual analysis: see() — screenshot-based page verification
|
|
109
|
+
- Context refresh: context() — get fresh HTML/ARIA snapshot
|
|
110
|
+
- Visual fallback: visualClick() — coordinate-based click when locators fail
|
|
111
|
+
</web_capabilities>
|
|
112
|
+
|
|
113
|
+
${locatorRule}
|
|
114
|
+
|
|
115
|
+
${actionRule}
|
|
116
|
+
|
|
117
|
+
${sectionContextRule}
|
|
118
|
+
`;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
webModeRules(): string {
|
|
122
|
+
return dedent`
|
|
123
|
+
- Follow <locator_priority> rules when selecting locators for all tools
|
|
124
|
+
- click() accepts array of commands to try in order — include ARIA, CSS, XPath variants
|
|
125
|
+
- If click() fails with all provided commands, use visualClick() tool as fallback
|
|
126
|
+
- When an action fails or result is unexpected, investigate or inform the user instead of retrying silently
|
|
127
|
+
`;
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export interface WebModeMethods {
|
|
133
|
+
webModeTools(ctx: ModeContext): Record<string, any>;
|
|
134
|
+
webModePrompt(): string;
|
|
135
|
+
webModeRules(): string;
|
|
136
|
+
}
|