explorbot 0.0.1
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 +94 -0
- package/README.md +267 -0
- package/assets/sample-files/sample.docx +0 -0
- package/assets/sample-files/sample.mp3 +0 -0
- package/assets/sample-files/sample.mp4 +0 -0
- package/assets/sample-files/sample.pdf +21 -0
- package/assets/sample-files/sample.png +0 -0
- package/assets/sample-files/sample.xlsx +0 -0
- package/assets/sample-files/sample.zip +0 -0
- package/dist/assets/sample-files/sample.docx +0 -0
- package/dist/assets/sample-files/sample.mp3 +0 -0
- package/dist/assets/sample-files/sample.mp4 +0 -0
- package/dist/assets/sample-files/sample.pdf +21 -0
- package/dist/assets/sample-files/sample.png +0 -0
- package/dist/assets/sample-files/sample.xlsx +0 -0
- package/dist/assets/sample-files/sample.zip +0 -0
- package/dist/bin/explorbot-cli.js +683 -0
- package/dist/bin/explorbot-cli.js.map +1 -0
- package/dist/boat/api-tester/bin/apibot-cli.js +5 -0
- package/dist/boat/api-tester/bin/apibot-cli.js.map +1 -0
- package/dist/boat/api-tester/example/apibot.config.js +31 -0
- package/dist/boat/api-tester/example/apibot.config.js.map +1 -0
- package/dist/boat/api-tester/src/ai/chief/styles.js +13 -0
- package/dist/boat/api-tester/src/ai/chief/styles.js.map +1 -0
- package/dist/boat/api-tester/src/ai/chief.js +301 -0
- package/dist/boat/api-tester/src/ai/chief.js.map +1 -0
- package/dist/boat/api-tester/src/ai/curler-tools.js +263 -0
- package/dist/boat/api-tester/src/ai/curler-tools.js.map +1 -0
- package/dist/boat/api-tester/src/ai/curler.js +271 -0
- package/dist/boat/api-tester/src/ai/curler.js.map +1 -0
- package/dist/boat/api-tester/src/api-client.js +26 -0
- package/dist/boat/api-tester/src/api-client.js.map +1 -0
- package/dist/boat/api-tester/src/apibot.js +166 -0
- package/dist/boat/api-tester/src/apibot.js.map +1 -0
- package/dist/boat/api-tester/src/cli.js +262 -0
- package/dist/boat/api-tester/src/cli.js.map +1 -0
- package/dist/boat/api-tester/src/config.js +159 -0
- package/dist/boat/api-tester/src/config.js.map +1 -0
- package/dist/prompts/audit-rules.md +124 -0
- package/dist/rules/chief/general.md +11 -0
- package/dist/rules/chief/styles/curious.md +12 -0
- package/dist/rules/chief/styles/hacker.md +19 -0
- package/dist/rules/chief/styles/normal.md +11 -0
- package/dist/rules/chief/styles/psycho.md +17 -0
- package/dist/rules/navigator/multiple-locator.md +47 -0
- package/dist/rules/navigator/output.md +69 -0
- package/dist/rules/navigator/verification-actions.md +122 -0
- package/dist/rules/navigator/verification-output.md +53 -0
- package/dist/rules/planner/styles/curious.md +39 -0
- package/dist/rules/planner/styles/normal.md +21 -0
- package/dist/rules/planner/styles/psycho.md +14 -0
- package/dist/rules/researcher/list-element.md +11 -0
- package/dist/rules/researcher/screenshot-ui-map.md +30 -0
- package/dist/rules/researcher/section-ui-map.md +18 -0
- package/dist/rules/researcher/ui-map-table.md +18 -0
- package/dist/src/action-result.js +574 -0
- package/dist/src/action-result.js.map +1 -0
- package/dist/src/action.js +388 -0
- package/dist/src/action.js.map +1 -0
- package/dist/src/activity.js +86 -0
- package/dist/src/activity.js.map +1 -0
- package/dist/src/ai/agent.js +2 -0
- package/dist/src/ai/agent.js.map +1 -0
- package/dist/src/ai/bosun.js +443 -0
- package/dist/src/ai/bosun.js.map +1 -0
- package/dist/src/ai/captain/idle-mode.js +102 -0
- package/dist/src/ai/captain/idle-mode.js.map +1 -0
- package/dist/src/ai/captain/mixin.js +11 -0
- package/dist/src/ai/captain/mixin.js.map +1 -0
- package/dist/src/ai/captain/test-mode.js +251 -0
- package/dist/src/ai/captain/test-mode.js.map +1 -0
- package/dist/src/ai/captain/web-mode.js +124 -0
- package/dist/src/ai/captain/web-mode.js.map +1 -0
- package/dist/src/ai/captain.js +442 -0
- package/dist/src/ai/captain.js.map +1 -0
- package/dist/src/ai/conversation.js +176 -0
- package/dist/src/ai/conversation.js.map +1 -0
- package/dist/src/ai/experience-compactor.js +232 -0
- package/dist/src/ai/experience-compactor.js.map +1 -0
- package/dist/src/ai/fisherman-tools.js +154 -0
- package/dist/src/ai/fisherman-tools.js.map +1 -0
- package/dist/src/ai/fisherman.js +184 -0
- package/dist/src/ai/fisherman.js.map +1 -0
- package/dist/src/ai/historian.js +384 -0
- package/dist/src/ai/historian.js.map +1 -0
- package/dist/src/ai/navigator.js +493 -0
- package/dist/src/ai/navigator.js.map +1 -0
- package/dist/src/ai/pilot.js +684 -0
- package/dist/src/ai/pilot.js.map +1 -0
- package/dist/src/ai/planner/session-dedup.js +28 -0
- package/dist/src/ai/planner/session-dedup.js.map +1 -0
- package/dist/src/ai/planner/styles.js +15 -0
- package/dist/src/ai/planner/styles.js.map +1 -0
- package/dist/src/ai/planner/subpages.js +118 -0
- package/dist/src/ai/planner/subpages.js.map +1 -0
- package/dist/src/ai/planner.js +486 -0
- package/dist/src/ai/planner.js.map +1 -0
- package/dist/src/ai/provider.js +540 -0
- package/dist/src/ai/provider.js.map +1 -0
- package/dist/src/ai/quartermaster.js +210 -0
- package/dist/src/ai/quartermaster.js.map +1 -0
- package/dist/src/ai/researcher/cache.js +95 -0
- package/dist/src/ai/researcher/cache.js.map +1 -0
- package/dist/src/ai/researcher/coordinates.js +210 -0
- package/dist/src/ai/researcher/coordinates.js.map +1 -0
- package/dist/src/ai/researcher/deep-analysis.js +364 -0
- package/dist/src/ai/researcher/deep-analysis.js.map +1 -0
- package/dist/src/ai/researcher/fingerprint-worker.js +46 -0
- package/dist/src/ai/researcher/fingerprint-worker.js.map +1 -0
- package/dist/src/ai/researcher/focus.js +37 -0
- package/dist/src/ai/researcher/focus.js.map +1 -0
- package/dist/src/ai/researcher/locators.js +242 -0
- package/dist/src/ai/researcher/locators.js.map +1 -0
- package/dist/src/ai/researcher/mixin.js +3 -0
- package/dist/src/ai/researcher/mixin.js.map +1 -0
- package/dist/src/ai/researcher/parser.js +160 -0
- package/dist/src/ai/researcher/parser.js.map +1 -0
- package/dist/src/ai/researcher/research-result.js +110 -0
- package/dist/src/ai/researcher/research-result.js.map +1 -0
- package/dist/src/ai/researcher.js +776 -0
- package/dist/src/ai/researcher.js.map +1 -0
- package/dist/src/ai/rules.js +368 -0
- package/dist/src/ai/rules.js.map +1 -0
- package/dist/src/ai/task-agent.js +110 -0
- package/dist/src/ai/task-agent.js.map +1 -0
- package/dist/src/ai/tester.js +840 -0
- package/dist/src/ai/tester.js.map +1 -0
- package/dist/src/ai/tools.js +980 -0
- package/dist/src/ai/tools.js.map +1 -0
- package/dist/src/api/api-client.js +91 -0
- package/dist/src/api/api-client.js.map +1 -0
- package/dist/src/api/request-result.js +177 -0
- package/dist/src/api/request-result.js.map +1 -0
- package/dist/src/api/request-store.js +109 -0
- package/dist/src/api/request-store.js.map +1 -0
- package/dist/src/api/spec-reader.js +148 -0
- package/dist/src/api/spec-reader.js.map +1 -0
- package/dist/src/api/xhr-capture.js +91 -0
- package/dist/src/api/xhr-capture.js.map +1 -0
- package/dist/src/browser-server.js +67 -0
- package/dist/src/browser-server.js.map +1 -0
- package/dist/src/command-handler.js +363 -0
- package/dist/src/command-handler.js.map +1 -0
- package/dist/src/commands/add-rule-command.js +52 -0
- package/dist/src/commands/add-rule-command.js.map +1 -0
- package/dist/src/commands/base-command.js +14 -0
- package/dist/src/commands/base-command.js.map +1 -0
- package/dist/src/commands/clean-command.js +67 -0
- package/dist/src/commands/clean-command.js.map +1 -0
- package/dist/src/commands/context-aria-command.js +18 -0
- package/dist/src/commands/context-aria-command.js.map +1 -0
- package/dist/src/commands/context-command.js +57 -0
- package/dist/src/commands/context-command.js.map +1 -0
- package/dist/src/commands/context-data-command.js +25 -0
- package/dist/src/commands/context-data-command.js.map +1 -0
- package/dist/src/commands/context-experience-command.js +41 -0
- package/dist/src/commands/context-experience-command.js.map +1 -0
- package/dist/src/commands/context-html-command.js +26 -0
- package/dist/src/commands/context-html-command.js.map +1 -0
- package/dist/src/commands/context-knowledge-command.js +36 -0
- package/dist/src/commands/context-knowledge-command.js.map +1 -0
- package/dist/src/commands/debug-command.js +12 -0
- package/dist/src/commands/debug-command.js.map +1 -0
- package/dist/src/commands/drill-command.js +29 -0
- package/dist/src/commands/drill-command.js.map +1 -0
- package/dist/src/commands/exit-command.js +26 -0
- package/dist/src/commands/exit-command.js.map +1 -0
- package/dist/src/commands/explore-command.js +124 -0
- package/dist/src/commands/explore-command.js.map +1 -0
- package/dist/src/commands/freesail-command.js +84 -0
- package/dist/src/commands/freesail-command.js.map +1 -0
- package/dist/src/commands/help-command.js +7 -0
- package/dist/src/commands/help-command.js.map +1 -0
- package/dist/src/commands/index.js +63 -0
- package/dist/src/commands/index.js.map +1 -0
- package/dist/src/commands/knows-command.js +54 -0
- package/dist/src/commands/knows-command.js.map +1 -0
- package/dist/src/commands/learn-command.js +35 -0
- package/dist/src/commands/learn-command.js.map +1 -0
- package/dist/src/commands/navigate-command.js +16 -0
- package/dist/src/commands/navigate-command.js.map +1 -0
- package/dist/src/commands/path-command.js +70 -0
- package/dist/src/commands/path-command.js.map +1 -0
- package/dist/src/commands/plan-clear-command.js +13 -0
- package/dist/src/commands/plan-clear-command.js.map +1 -0
- package/dist/src/commands/plan-command.js +36 -0
- package/dist/src/commands/plan-command.js.map +1 -0
- package/dist/src/commands/plan-edit-command.js +8 -0
- package/dist/src/commands/plan-edit-command.js.map +1 -0
- package/dist/src/commands/plan-load-command.js +16 -0
- package/dist/src/commands/plan-load-command.js.map +1 -0
- package/dist/src/commands/plan-reload-command.js +23 -0
- package/dist/src/commands/plan-reload-command.js.map +1 -0
- package/dist/src/commands/plan-save-command.js +22 -0
- package/dist/src/commands/plan-save-command.js.map +1 -0
- package/dist/src/commands/research-command.js +38 -0
- package/dist/src/commands/research-command.js.map +1 -0
- package/dist/src/commands/start-command.js +12 -0
- package/dist/src/commands/start-command.js.map +1 -0
- package/dist/src/commands/status-command.js +19 -0
- package/dist/src/commands/status-command.js.map +1 -0
- package/dist/src/commands/test-command.js +85 -0
- package/dist/src/commands/test-command.js.map +1 -0
- package/dist/src/components/ActivityPane.js +55 -0
- package/dist/src/components/ActivityPane.js.map +1 -0
- package/dist/src/components/AddKnowledge.js +122 -0
- package/dist/src/components/AddKnowledge.js.map +1 -0
- package/dist/src/components/AddRule.js +117 -0
- package/dist/src/components/AddRule.js.map +1 -0
- package/dist/src/components/App.js +313 -0
- package/dist/src/components/App.js.map +1 -0
- package/dist/src/components/Autocomplete.js +43 -0
- package/dist/src/components/Autocomplete.js.map +1 -0
- package/dist/src/components/InputPane.js +207 -0
- package/dist/src/components/InputPane.js.map +1 -0
- package/dist/src/components/InputReadline.js +598 -0
- package/dist/src/components/InputReadline.js.map +1 -0
- package/dist/src/components/LogPane.js +123 -0
- package/dist/src/components/LogPane.js.map +1 -0
- package/dist/src/components/PlanEditor.js +126 -0
- package/dist/src/components/PlanEditor.js.map +1 -0
- package/dist/src/components/PlanPane.js +51 -0
- package/dist/src/components/PlanPane.js.map +1 -0
- package/dist/src/components/SessionTimer.js +26 -0
- package/dist/src/components/SessionTimer.js.map +1 -0
- package/dist/src/components/StateTransitionPane.js +107 -0
- package/dist/src/components/StateTransitionPane.js.map +1 -0
- package/dist/src/components/StatusPane.js +37 -0
- package/dist/src/components/StatusPane.js.map +1 -0
- package/dist/src/components/TaskPane.js +96 -0
- package/dist/src/components/TaskPane.js.map +1 -0
- package/dist/src/components/Welcome.js +52 -0
- package/dist/src/components/Welcome.js.map +1 -0
- package/dist/src/components/WelcomeChecklist.js +96 -0
- package/dist/src/components/WelcomeChecklist.js.map +1 -0
- package/dist/src/components/WelcomeCommands.js +61 -0
- package/dist/src/components/WelcomeCommands.js.map +1 -0
- package/dist/src/components/autocomplete-store.js +22 -0
- package/dist/src/components/autocomplete-store.js.map +1 -0
- package/dist/src/components/parse-keypress.js +174 -0
- package/dist/src/components/parse-keypress.js.map +1 -0
- package/dist/src/config.js +249 -0
- package/dist/src/config.js.map +1 -0
- package/dist/src/execution-controller.js +92 -0
- package/dist/src/execution-controller.js.map +1 -0
- package/dist/src/experience-tracker.js +294 -0
- package/dist/src/experience-tracker.js.map +1 -0
- package/dist/src/explorbot.js +348 -0
- package/dist/src/explorbot.js.map +1 -0
- package/dist/src/explorer.js +611 -0
- package/dist/src/explorer.js.map +1 -0
- package/dist/src/index.js +56 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/knowledge-tracker.js +184 -0
- package/dist/src/knowledge-tracker.js.map +1 -0
- package/dist/src/observability.js +126 -0
- package/dist/src/observability.js.map +1 -0
- package/dist/src/reporter.js +185 -0
- package/dist/src/reporter.js.map +1 -0
- package/dist/src/state-manager.js +427 -0
- package/dist/src/state-manager.js.map +1 -0
- package/dist/src/stats.js +44 -0
- package/dist/src/stats.js.map +1 -0
- package/dist/src/test-plan.js +343 -0
- package/dist/src/test-plan.js.map +1 -0
- package/dist/src/utils/aria.js +588 -0
- package/dist/src/utils/aria.js.map +1 -0
- package/dist/src/utils/code-extractor.js +21 -0
- package/dist/src/utils/code-extractor.js.map +1 -0
- package/dist/src/utils/context-formatter.js +205 -0
- package/dist/src/utils/context-formatter.js.map +1 -0
- package/dist/src/utils/error-page.js +19 -0
- package/dist/src/utils/error-page.js.map +1 -0
- package/dist/src/utils/expandable.js +35 -0
- package/dist/src/utils/expandable.js.map +1 -0
- package/dist/src/utils/hooks-runner.js +77 -0
- package/dist/src/utils/hooks-runner.js.map +1 -0
- package/dist/src/utils/html-diff.js +734 -0
- package/dist/src/utils/html-diff.js.map +1 -0
- package/dist/src/utils/html.js +1163 -0
- package/dist/src/utils/html.js.map +1 -0
- package/dist/src/utils/logger.js +465 -0
- package/dist/src/utils/logger.js.map +1 -0
- package/dist/src/utils/loop.js +126 -0
- package/dist/src/utils/loop.js.map +1 -0
- package/dist/src/utils/markdown-parser.js +117 -0
- package/dist/src/utils/markdown-parser.js.map +1 -0
- package/dist/src/utils/markdown-query.js +393 -0
- package/dist/src/utils/markdown-query.js.map +1 -0
- package/dist/src/utils/markdown-terminal.js +40 -0
- package/dist/src/utils/markdown-terminal.js.map +1 -0
- package/dist/src/utils/research-parser.js +2 -0
- package/dist/src/utils/research-parser.js.map +1 -0
- package/dist/src/utils/retry.js +55 -0
- package/dist/src/utils/retry.js.map +1 -0
- package/dist/src/utils/rules-loader.js +104 -0
- package/dist/src/utils/rules-loader.js.map +1 -0
- package/dist/src/utils/strings.js +14 -0
- package/dist/src/utils/strings.js.map +1 -0
- package/dist/src/utils/test-plan-markdown.js +301 -0
- package/dist/src/utils/test-plan-markdown.js.map +1 -0
- package/dist/src/utils/throttle.js +16 -0
- package/dist/src/utils/throttle.js.map +1 -0
- package/dist/src/utils/unique-names.js +13 -0
- package/dist/src/utils/unique-names.js.map +1 -0
- package/dist/src/utils/url-matcher.js +48 -0
- package/dist/src/utils/url-matcher.js.map +1 -0
- package/dist/src/utils/web-element.js +131 -0
- package/dist/src/utils/web-element.js.map +1 -0
- package/dist/src/utils/xpath.js +110 -0
- package/dist/src/utils/xpath.js.map +1 -0
- package/package.json +119 -0
- package/prompts/audit-rules.md +124 -0
- package/rules/chief/general.md +11 -0
- package/rules/chief/styles/curious.md +12 -0
- package/rules/chief/styles/hacker.md +19 -0
- package/rules/chief/styles/normal.md +11 -0
- package/rules/chief/styles/psycho.md +17 -0
- package/rules/navigator/multiple-locator.md +47 -0
- package/rules/navigator/output.md +69 -0
- package/rules/navigator/verification-actions.md +122 -0
- package/rules/navigator/verification-output.md +53 -0
- package/rules/planner/styles/curious.md +39 -0
- package/rules/planner/styles/normal.md +21 -0
- package/rules/planner/styles/psycho.md +14 -0
- package/rules/researcher/list-element.md +11 -0
- package/rules/researcher/screenshot-ui-map.md +30 -0
- package/rules/researcher/section-ui-map.md +18 -0
- package/rules/researcher/ui-map-table.md +18 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Box, Text } from 'ink';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { useEffect, useState } from 'react';
|
|
4
|
+
import { addActivityListener, removeActivityListener } from "../activity.js";
|
|
5
|
+
const ActivityPane = React.memo(({ isInputVisible = false }) => {
|
|
6
|
+
const [activity, setActivity] = useState(null);
|
|
7
|
+
const [animationState, setAnimationState] = useState(0);
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
const listener = (newActivity) => {
|
|
10
|
+
setActivity(newActivity);
|
|
11
|
+
};
|
|
12
|
+
addActivityListener(listener);
|
|
13
|
+
return () => {
|
|
14
|
+
removeActivityListener(listener);
|
|
15
|
+
};
|
|
16
|
+
}, []);
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
if (!activity)
|
|
19
|
+
return;
|
|
20
|
+
const interval = setInterval(() => {
|
|
21
|
+
setAnimationState((prev) => (prev + 1) % 4);
|
|
22
|
+
}, 1200);
|
|
23
|
+
return () => clearInterval(interval);
|
|
24
|
+
}, [activity]);
|
|
25
|
+
if (!activity) {
|
|
26
|
+
if (isInputVisible) {
|
|
27
|
+
return (React.createElement(Box, { height: 1, paddingX: 1 },
|
|
28
|
+
React.createElement(Text, { dimColor: true }, "Enter command or press Enter to continue")));
|
|
29
|
+
}
|
|
30
|
+
return (React.createElement(Box, { height: 1, paddingX: 1 },
|
|
31
|
+
React.createElement(Text, { dimColor: true }, "Done. Press [ESC] to enable input. Press [CTRL + t] to toggle session timer.")));
|
|
32
|
+
}
|
|
33
|
+
const getActivityColor = (type) => {
|
|
34
|
+
switch (type) {
|
|
35
|
+
case 'ai':
|
|
36
|
+
return 'cyan';
|
|
37
|
+
case 'action':
|
|
38
|
+
return 'green';
|
|
39
|
+
case 'navigation':
|
|
40
|
+
return 'blue';
|
|
41
|
+
default:
|
|
42
|
+
return 'yellow';
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
const getDots = () => {
|
|
46
|
+
return '.'.repeat(animationState);
|
|
47
|
+
};
|
|
48
|
+
const isDimmed = animationState % 2 === 0;
|
|
49
|
+
return (React.createElement(Box, { height: 1, marginY: 1, paddingX: 1 },
|
|
50
|
+
React.createElement(Text, { color: getActivityColor(activity.type), dimColor: isDimmed },
|
|
51
|
+
activity.message,
|
|
52
|
+
getDots())));
|
|
53
|
+
});
|
|
54
|
+
export default ActivityPane;
|
|
55
|
+
//# sourceMappingURL=ActivityPane.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ActivityPane.js","sourceRoot":"","sources":["../../../src/components/ActivityPane.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAsB,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAMjG,MAAM,YAAY,GAAgC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,cAAc,GAAG,KAAK,EAAE,EAAE,EAAE;IAC1F,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAuB,IAAI,CAAC,CAAC;IACrE,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAExD,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,QAAQ,GAAG,CAAC,WAAiC,EAAE,EAAE;YACrD,WAAW,CAAC,WAAW,CAAC,CAAC;QAC3B,CAAC,CAAC;QAEF,mBAAmB,CAAC,QAAQ,CAAC,CAAC;QAE9B,OAAO,GAAG,EAAE;YACV,sBAAsB,CAAC,QAAQ,CAAC,CAAC;QACnC,CAAC,CAAC;IACJ,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,QAAQ;YAAE,OAAO;QAEtB,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,EAAE;YAChC,iBAAiB,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAC9C,CAAC,EAAE,IAAI,CAAC,CAAC;QAET,OAAO,GAAG,EAAE,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IACvC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEf,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,IAAI,cAAc,EAAE,CAAC;YACnB,OAAO,CACL,oBAAC,GAAG,IAAC,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC;gBACzB,oBAAC,IAAI,IAAC,QAAQ,qDAAgD,CAC1D,CACP,CAAC;QACJ,CAAC;QACD,OAAO,CACL,oBAAC,GAAG,IAAC,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC;YACzB,oBAAC,IAAI,IAAC,QAAQ,yFAAoF,CAC9F,CACP,CAAC;IACJ,CAAC;IAED,MAAM,gBAAgB,GAAG,CAAC,IAA2B,EAAE,EAAE;QACvD,QAAQ,IAAI,EAAE,CAAC;YACb,KAAK,IAAI;gBACP,OAAO,MAAM,CAAC;YAChB,KAAK,QAAQ;gBACX,OAAO,OAAO,CAAC;YACjB,KAAK,YAAY;gBACf,OAAO,MAAM,CAAC;YAChB;gBACE,OAAO,QAAQ,CAAC;QACpB,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,OAAO,GAAG,GAAG,EAAE;QACnB,OAAO,GAAG,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;IACpC,CAAC,CAAC;IAEF,MAAM,QAAQ,GAAG,cAAc,GAAG,CAAC,KAAK,CAAC,CAAC;IAE1C,OAAO,CACL,oBAAC,GAAG,IAAC,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC;QACrC,oBAAC,IAAI,IAAC,KAAK,EAAE,gBAAgB,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,QAAQ;YAC7D,QAAQ,CAAC,OAAO;YAChB,OAAO,EAAE,CACL,CACH,CACP,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,eAAe,YAAY,CAAC"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { Box, Text, useInput } from 'ink';
|
|
2
|
+
import React, { useEffect, useState } from 'react';
|
|
3
|
+
import { KnowledgeTracker } from '../knowledge-tracker.js';
|
|
4
|
+
import InputReadline from './InputReadline.js';
|
|
5
|
+
const AddKnowledge = ({ initialUrl = '', onComplete, onCancel }) => {
|
|
6
|
+
const [urlPattern, setUrlPattern] = useState(initialUrl);
|
|
7
|
+
const [description, setDescription] = useState('');
|
|
8
|
+
const [activeField, setActiveField] = useState(initialUrl ? 'description' : 'url');
|
|
9
|
+
const [suggestedUrls, setSuggestedUrls] = useState([]);
|
|
10
|
+
const [existingKnowledge, setExistingKnowledge] = useState([]);
|
|
11
|
+
const isStandalone = !onComplete;
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
try {
|
|
14
|
+
const knowledgeTracker = new KnowledgeTracker();
|
|
15
|
+
const urls = knowledgeTracker.getExistingUrls();
|
|
16
|
+
setSuggestedUrls(urls);
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
console.error('Failed to load suggestions:', error);
|
|
20
|
+
}
|
|
21
|
+
}, []);
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
if (urlPattern.trim()) {
|
|
24
|
+
try {
|
|
25
|
+
const knowledgeTracker = new KnowledgeTracker();
|
|
26
|
+
const knowledge = knowledgeTracker.getKnowledgeForUrl(urlPattern);
|
|
27
|
+
setExistingKnowledge(knowledge);
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
console.error('Failed to load existing knowledge:', error);
|
|
31
|
+
setExistingKnowledge([]);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
setExistingKnowledge([]);
|
|
36
|
+
}
|
|
37
|
+
}, [urlPattern]);
|
|
38
|
+
const handleSave = () => {
|
|
39
|
+
if (!urlPattern.trim() || !description.trim()) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
try {
|
|
43
|
+
const knowledgeTracker = new KnowledgeTracker();
|
|
44
|
+
const result = knowledgeTracker.addKnowledge(urlPattern.trim(), description.trim());
|
|
45
|
+
const action = result.isNewFile ? 'Created' : 'Updated';
|
|
46
|
+
console.log(`\nKnowledge ${action} in: ${result.filename}`);
|
|
47
|
+
if (isStandalone) {
|
|
48
|
+
process.exit(0);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
onComplete?.();
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
console.error(`\nFailed to save knowledge: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
56
|
+
if (isStandalone) {
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
const handleUrlSubmit = () => {
|
|
62
|
+
if (urlPattern.trim()) {
|
|
63
|
+
setActiveField('description');
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
const handleDescriptionSubmit = () => {
|
|
67
|
+
if (description.trim()) {
|
|
68
|
+
handleSave();
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
useInput((input, key) => {
|
|
72
|
+
if (key.ctrl && input === 'c') {
|
|
73
|
+
if (isStandalone) {
|
|
74
|
+
process.exit(0);
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
onCancel?.();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (key.escape) {
|
|
81
|
+
if (!isStandalone) {
|
|
82
|
+
onCancel?.();
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
if (key.tab) {
|
|
86
|
+
if (activeField === 'url' && urlPattern.trim()) {
|
|
87
|
+
setActiveField('description');
|
|
88
|
+
}
|
|
89
|
+
else if (activeField === 'description') {
|
|
90
|
+
setActiveField('url');
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
return (React.createElement(Box, { flexDirection: "column", padding: 1 },
|
|
95
|
+
React.createElement(Box, { marginBottom: 1 },
|
|
96
|
+
React.createElement(Text, { color: "cyan", bold: true }, "Add Knowledge")),
|
|
97
|
+
React.createElement(Box, { marginBottom: 1, flexDirection: "column" },
|
|
98
|
+
React.createElement(Box, { marginBottom: 1 },
|
|
99
|
+
React.createElement(Text, { color: activeField === 'url' ? 'blue' : 'gray' }, "URL Pattern:")),
|
|
100
|
+
React.createElement(Box, { borderStyle: "single", borderColor: activeField === 'url' ? 'blue' : 'gray', paddingX: 1 },
|
|
101
|
+
React.createElement(InputReadline, { value: urlPattern, onChange: setUrlPattern, onSubmit: handleUrlSubmit, placeholder: suggestedUrls.length > 0 ? suggestedUrls[0] : '/login, *, ^/admin', isActive: activeField === 'url', showPrompt: false })),
|
|
102
|
+
React.createElement(Text, { color: "gray", dimColor: true }, "Wildcards (*) or regexes (^pattern, ~pattern)")),
|
|
103
|
+
existingKnowledge.length > 0 && (React.createElement(Box, { marginBottom: 1, flexDirection: "column" },
|
|
104
|
+
React.createElement(Box, { marginBottom: 1 },
|
|
105
|
+
React.createElement(Text, { color: "yellow", bold: true }, "Existing Knowledge:")),
|
|
106
|
+
React.createElement(Box, { borderStyle: "single", borderColor: "gray", paddingX: 1, flexDirection: "column" }, existingKnowledge.map((knowledge, index) => (React.createElement(Box, { key: index, flexDirection: "column", marginBottom: index < existingKnowledge.length - 1 ? 1 : 0 },
|
|
107
|
+
React.createElement(Text, { color: "gray" }, knowledge),
|
|
108
|
+
index < existingKnowledge.length - 1 && (React.createElement(Text, { color: "gray", dimColor: true }, "---")))))))),
|
|
109
|
+
React.createElement(Box, { marginBottom: 1, flexDirection: "column" },
|
|
110
|
+
React.createElement(Box, { marginBottom: 1 },
|
|
111
|
+
React.createElement(Text, { color: activeField === 'description' ? 'blue' : 'gray' }, "Description:")),
|
|
112
|
+
React.createElement(Box, { borderStyle: "single", borderColor: activeField === 'description' ? 'blue' : 'gray', paddingX: 1 },
|
|
113
|
+
React.createElement(InputReadline, { value: description, onChange: setDescription, onSubmit: handleDescriptionSubmit, placeholder: "Describe actions, locators, or page behavior...", isActive: activeField === 'description', showPrompt: false })),
|
|
114
|
+
React.createElement(Text, { color: "gray", dimColor: true }, "Actions, locators, validation rules")),
|
|
115
|
+
React.createElement(Box, { marginTop: 1 },
|
|
116
|
+
React.createElement(Text, { color: "gray", dimColor: true },
|
|
117
|
+
"Tab: Switch | Enter: Next/Save | ",
|
|
118
|
+
isStandalone ? 'Ctrl+C' : 'Esc',
|
|
119
|
+
": Exit"))));
|
|
120
|
+
};
|
|
121
|
+
export default AddKnowledge;
|
|
122
|
+
//# sourceMappingURL=AddKnowledge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AddKnowledge.js","sourceRoot":"","sources":["../../../src/components/AddKnowledge.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { existsSync, readdirSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { Box, Text, useInput } from 'ink';
|
|
4
|
+
import React, { useEffect, useState } from 'react';
|
|
5
|
+
import { AddRuleCommand } from '../commands/add-rule-command.js';
|
|
6
|
+
import InputReadline from './InputReadline.js';
|
|
7
|
+
const KNOWN_AGENTS = ['researcher', 'tester', 'planner', 'pilot', 'captain', 'bosun', 'navigator'];
|
|
8
|
+
const AddRule = ({ initialAgent = '', initialName = '', onComplete, onCancel }) => {
|
|
9
|
+
const [agent, setAgent] = useState(initialAgent);
|
|
10
|
+
const [ruleName, setRuleName] = useState(initialName);
|
|
11
|
+
const [urlPattern, setUrlPattern] = useState('');
|
|
12
|
+
const [content, setContent] = useState('');
|
|
13
|
+
const [activeField, setActiveField] = useState(initialAgent ? (initialName ? 'url' : 'name') : 'agent');
|
|
14
|
+
const [existingRules, setExistingRules] = useState([]);
|
|
15
|
+
const isStandalone = !onComplete;
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
if (!agent.trim()) {
|
|
18
|
+
setExistingRules([]);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const rulesDir = join(process.cwd(), 'rules', agent);
|
|
22
|
+
if (!existsSync(rulesDir)) {
|
|
23
|
+
setExistingRules([]);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const files = readdirSync(rulesDir)
|
|
27
|
+
.filter((f) => f.endsWith('.md'))
|
|
28
|
+
.map((f) => f.replace(/\.md$/, ''));
|
|
29
|
+
setExistingRules(files);
|
|
30
|
+
}, [agent]);
|
|
31
|
+
const handleSave = () => {
|
|
32
|
+
if (!agent.trim() || !ruleName.trim() || !content.trim())
|
|
33
|
+
return;
|
|
34
|
+
const result = AddRuleCommand.createRuleFile(agent.trim(), ruleName.trim(), {
|
|
35
|
+
content: content.trim(),
|
|
36
|
+
urlPattern: urlPattern.trim() || undefined,
|
|
37
|
+
});
|
|
38
|
+
if (isStandalone) {
|
|
39
|
+
process.exit(result ? 0 : 1);
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
onComplete?.();
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
const fields = ['agent', 'name', 'url', 'content'];
|
|
46
|
+
const advanceField = () => {
|
|
47
|
+
const idx = fields.indexOf(activeField);
|
|
48
|
+
if (idx < fields.length - 1) {
|
|
49
|
+
setActiveField(fields[idx + 1]);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
useInput((input, key) => {
|
|
53
|
+
if (key.ctrl && input === 'c') {
|
|
54
|
+
if (isStandalone) {
|
|
55
|
+
process.exit(0);
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
onCancel?.();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (key.escape && !isStandalone) {
|
|
62
|
+
onCancel?.();
|
|
63
|
+
}
|
|
64
|
+
if (key.tab) {
|
|
65
|
+
advanceField();
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
return (React.createElement(Box, { flexDirection: "column", padding: 1 },
|
|
69
|
+
React.createElement(Box, { marginBottom: 1 },
|
|
70
|
+
React.createElement(Text, { color: "cyan", bold: true }, "Add Rule")),
|
|
71
|
+
React.createElement(Box, { marginBottom: 1, flexDirection: "column" },
|
|
72
|
+
React.createElement(Box, { marginBottom: 1 },
|
|
73
|
+
React.createElement(Text, { color: activeField === 'agent' ? 'blue' : 'gray' }, "Agent:")),
|
|
74
|
+
React.createElement(Box, { borderStyle: "single", borderColor: activeField === 'agent' ? 'blue' : 'gray', paddingX: 1 },
|
|
75
|
+
React.createElement(InputReadline, { value: agent, onChange: setAgent, onSubmit: () => {
|
|
76
|
+
if (agent.trim())
|
|
77
|
+
advanceField();
|
|
78
|
+
}, placeholder: KNOWN_AGENTS.join(', '), isActive: activeField === 'agent', showPrompt: false }))),
|
|
79
|
+
existingRules.length > 0 && (React.createElement(Box, { marginBottom: 1, flexDirection: "column" },
|
|
80
|
+
React.createElement(Text, { color: "yellow" },
|
|
81
|
+
"Existing rules: ",
|
|
82
|
+
existingRules.join(', ')))),
|
|
83
|
+
React.createElement(Box, { marginBottom: 1, flexDirection: "column" },
|
|
84
|
+
React.createElement(Box, { marginBottom: 1 },
|
|
85
|
+
React.createElement(Text, { color: activeField === 'name' ? 'blue' : 'gray' }, "Rule name:")),
|
|
86
|
+
React.createElement(Box, { borderStyle: "single", borderColor: activeField === 'name' ? 'blue' : 'gray', paddingX: 1 },
|
|
87
|
+
React.createElement(InputReadline, { value: ruleName, onChange: setRuleName, onSubmit: () => {
|
|
88
|
+
if (ruleName.trim())
|
|
89
|
+
advanceField();
|
|
90
|
+
}, placeholder: "e.g. check-tooltips, wait-for-toasts", isActive: activeField === 'name', showPrompt: false })),
|
|
91
|
+
React.createElement(Text, { color: "gray", dimColor: true },
|
|
92
|
+
"Saved as rules/",
|
|
93
|
+
agent || '<agent>',
|
|
94
|
+
"/",
|
|
95
|
+
ruleName || '<name>',
|
|
96
|
+
".md")),
|
|
97
|
+
React.createElement(Box, { marginBottom: 1, flexDirection: "column" },
|
|
98
|
+
React.createElement(Box, { marginBottom: 1 },
|
|
99
|
+
React.createElement(Text, { color: activeField === 'url' ? 'blue' : 'gray' }, "URL pattern (optional):")),
|
|
100
|
+
React.createElement(Box, { borderStyle: "single", borderColor: activeField === 'url' ? 'blue' : 'gray', paddingX: 1 },
|
|
101
|
+
React.createElement(InputReadline, { value: urlPattern, onChange: setUrlPattern, onSubmit: advanceField, placeholder: "Leave empty for all URLs, or /admin/*, /checkout, etc.", isActive: activeField === 'url', showPrompt: false }))),
|
|
102
|
+
React.createElement(Box, { marginBottom: 1, flexDirection: "column" },
|
|
103
|
+
React.createElement(Box, { marginBottom: 1 },
|
|
104
|
+
React.createElement(Text, { color: activeField === 'content' ? 'blue' : 'gray' }, "Rule content:")),
|
|
105
|
+
React.createElement(Box, { borderStyle: "single", borderColor: activeField === 'content' ? 'blue' : 'gray', paddingX: 1 },
|
|
106
|
+
React.createElement(InputReadline, { value: content, onChange: setContent, onSubmit: () => {
|
|
107
|
+
if (content.trim())
|
|
108
|
+
handleSave();
|
|
109
|
+
}, placeholder: "Instructions for the agent...", isActive: activeField === 'content', showPrompt: false }))),
|
|
110
|
+
React.createElement(Box, { marginTop: 1 },
|
|
111
|
+
React.createElement(Text, { color: "gray", dimColor: true },
|
|
112
|
+
"Tab: Next field | Enter: Next/Save | ",
|
|
113
|
+
isStandalone ? 'Ctrl+C' : 'Esc',
|
|
114
|
+
": Exit"))));
|
|
115
|
+
};
|
|
116
|
+
export default AddRule;
|
|
117
|
+
//# sourceMappingURL=AddRule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AddRule.js","sourceRoot":"","sources":["../../../src/components/AddRule.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
import { Box, Text, useInput } from 'ink';
|
|
2
|
+
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
3
|
+
import { CommandHandler } from '../command-handler.js';
|
|
4
|
+
import { executionController } from "../execution-controller.js";
|
|
5
|
+
import { tag } from '../utils/logger.js';
|
|
6
|
+
import ActivityPane from './ActivityPane.js';
|
|
7
|
+
import Autocomplete from './Autocomplete.js';
|
|
8
|
+
import InputReadline from './InputReadline.js';
|
|
9
|
+
import LogPane from './LogPane.js';
|
|
10
|
+
import PlanEditor from './PlanEditor.js';
|
|
11
|
+
import PlanPane from './PlanPane.js';
|
|
12
|
+
import SessionTimer from './SessionTimer.js';
|
|
13
|
+
import StateTransitionPane from './StateTransitionPane.js';
|
|
14
|
+
import TaskPane, { WINDOW_SIZE } from './TaskPane.js';
|
|
15
|
+
import WelcomeChecklist from './WelcomeChecklist.js';
|
|
16
|
+
import WelcomeCommands from './WelcomeCommands.js';
|
|
17
|
+
export function App({ explorBot, initialShowInput = false, exitOnEmptyInput = false }) {
|
|
18
|
+
const sessionStartedAtRef = useRef(Date.now());
|
|
19
|
+
const InputComponent = InputReadline;
|
|
20
|
+
const [showSessionTimer, setShowSessionTimer] = useState(false);
|
|
21
|
+
const [showInput, setShowInput] = useState(initialShowInput);
|
|
22
|
+
const [interruptPrompt, setInterruptPrompt] = useState(null);
|
|
23
|
+
const [currentState, setCurrentState] = useState(null);
|
|
24
|
+
const [lastTransition, setLastTransition] = useState(null);
|
|
25
|
+
const [tasks, setTasks] = useState([]);
|
|
26
|
+
const tasksRef = useRef([]);
|
|
27
|
+
const [showPlanEditor, setShowPlanEditor] = useState(false);
|
|
28
|
+
const [taskScrollOffset, setTaskScrollOffset] = useState(0);
|
|
29
|
+
const [commandHandler] = useState(() => new CommandHandler(explorBot));
|
|
30
|
+
const [checklistData, setChecklistData] = useState(null);
|
|
31
|
+
const [showWelcome, setShowWelcome] = useState(false);
|
|
32
|
+
const userInputPromiseRef = useRef(null);
|
|
33
|
+
const interruptResolveRef = useRef(null);
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
// biome-ignore lint/style/useConst: assigned after declaration in useEffect pattern
|
|
36
|
+
let unsubscribe;
|
|
37
|
+
let mounted = true;
|
|
38
|
+
process.env.INK_RUNNING = 'true';
|
|
39
|
+
explorBot.setUserResolve(async (error, showWelcomeFlag) => {
|
|
40
|
+
if (error) {
|
|
41
|
+
console.error('Error occurred:', error.message);
|
|
42
|
+
}
|
|
43
|
+
if (showWelcomeFlag) {
|
|
44
|
+
setShowWelcome(true);
|
|
45
|
+
}
|
|
46
|
+
setShowInput(true);
|
|
47
|
+
return new Promise((resolve, reject) => {
|
|
48
|
+
userInputPromiseRef.current = { resolve, reject };
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
const manager = explorBot.getExplorer().getStateManager();
|
|
52
|
+
unsubscribe = manager.onStateChange((transition) => {
|
|
53
|
+
if (mounted) {
|
|
54
|
+
setLastTransition(transition);
|
|
55
|
+
setCurrentState(transition.toState);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
const initialState = manager.getCurrentState();
|
|
59
|
+
if (initialState && mounted) {
|
|
60
|
+
setCurrentState(initialState);
|
|
61
|
+
}
|
|
62
|
+
return () => {
|
|
63
|
+
mounted = false;
|
|
64
|
+
if (unsubscribe) {
|
|
65
|
+
unsubscribe();
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
}, [explorBot]);
|
|
69
|
+
const [inputCallbackReady, setInputCallbackReady] = useState(false);
|
|
70
|
+
useEffect(() => {
|
|
71
|
+
executionController.setInputCallback(async (prompt) => {
|
|
72
|
+
setInterruptPrompt(prompt);
|
|
73
|
+
setShowInput(true);
|
|
74
|
+
return new Promise((resolve) => {
|
|
75
|
+
interruptResolveRef.current = resolve;
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
const handleIdle = () => {
|
|
79
|
+
setShowInput(true);
|
|
80
|
+
};
|
|
81
|
+
executionController.on('idle', handleIdle);
|
|
82
|
+
setInputCallbackReady(true);
|
|
83
|
+
return () => {
|
|
84
|
+
executionController.off('idle', handleIdle);
|
|
85
|
+
executionController.reset();
|
|
86
|
+
};
|
|
87
|
+
}, []);
|
|
88
|
+
useEffect(() => {
|
|
89
|
+
if (!inputCallbackReady)
|
|
90
|
+
return;
|
|
91
|
+
let mounted = true;
|
|
92
|
+
const visitInitial = async () => {
|
|
93
|
+
try {
|
|
94
|
+
await explorBot.visitInitialState();
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
98
|
+
tag('error').log('Failed to start:', message);
|
|
99
|
+
}
|
|
100
|
+
if (!mounted)
|
|
101
|
+
return;
|
|
102
|
+
setChecklistData({
|
|
103
|
+
config: explorBot.getConfig(),
|
|
104
|
+
knowledgeTracker: explorBot.getKnowledgeTracker(),
|
|
105
|
+
});
|
|
106
|
+
setShowWelcome(true);
|
|
107
|
+
setShowInput(true);
|
|
108
|
+
};
|
|
109
|
+
visitInitial();
|
|
110
|
+
return () => {
|
|
111
|
+
mounted = false;
|
|
112
|
+
};
|
|
113
|
+
}, [explorBot, inputCallbackReady]);
|
|
114
|
+
const planRef = useRef(undefined);
|
|
115
|
+
const unsubscribeRef = useRef(undefined);
|
|
116
|
+
const [completedPlans, setCompletedPlans] = useState([]);
|
|
117
|
+
const [activePlanInfo, setActivePlanInfo] = useState(null);
|
|
118
|
+
useEffect(() => {
|
|
119
|
+
const makeSummary = (plan) => {
|
|
120
|
+
const enabled = plan.tests.filter((t) => t.enabled);
|
|
121
|
+
return {
|
|
122
|
+
title: plan.title,
|
|
123
|
+
testCount: enabled.length,
|
|
124
|
+
passed: enabled.filter((t) => t.isSuccessful).length,
|
|
125
|
+
failed: enabled.filter((t) => t.hasFailed).length,
|
|
126
|
+
};
|
|
127
|
+
};
|
|
128
|
+
const subscribeToPlan = (plan) => {
|
|
129
|
+
if (unsubscribeRef.current)
|
|
130
|
+
unsubscribeRef.current();
|
|
131
|
+
if (planRef.current && planRef.current !== plan && planRef.current.tests.length > 0) {
|
|
132
|
+
const summary = makeSummary(planRef.current);
|
|
133
|
+
setCompletedPlans((prev) => {
|
|
134
|
+
if (prev.some((p) => p.title === summary.title))
|
|
135
|
+
return prev;
|
|
136
|
+
return [...prev, summary];
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
planRef.current = plan;
|
|
140
|
+
tasksRef.current = [...plan.tests];
|
|
141
|
+
setTasks(tasksRef.current);
|
|
142
|
+
setTaskScrollOffset(0);
|
|
143
|
+
setActivePlanInfo(makeSummary(plan));
|
|
144
|
+
let lastInProgressIdx = -1;
|
|
145
|
+
unsubscribeRef.current = plan.onTestsChange((updatedTests) => {
|
|
146
|
+
tasksRef.current = [...updatedTests];
|
|
147
|
+
setTasks(tasksRef.current);
|
|
148
|
+
setActivePlanInfo(makeSummary(plan));
|
|
149
|
+
const inProgressIdx = updatedTests.findIndex((t) => t.status === 'in_progress' && t.enabled);
|
|
150
|
+
if (inProgressIdx >= 0 && inProgressIdx !== lastInProgressIdx) {
|
|
151
|
+
lastInProgressIdx = inProgressIdx;
|
|
152
|
+
setTaskScrollOffset(Math.max(0, inProgressIdx - Math.floor(WINDOW_SIZE / 2)));
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
};
|
|
156
|
+
const initialPlan = explorBot.getCurrentPlan();
|
|
157
|
+
if (initialPlan)
|
|
158
|
+
subscribeToPlan(initialPlan);
|
|
159
|
+
const interval = setInterval(() => {
|
|
160
|
+
const currentPlan = explorBot.getCurrentPlan();
|
|
161
|
+
if (currentPlan && currentPlan !== planRef.current) {
|
|
162
|
+
subscribeToPlan(currentPlan);
|
|
163
|
+
}
|
|
164
|
+
else if (!currentPlan && planRef.current) {
|
|
165
|
+
if (unsubscribeRef.current)
|
|
166
|
+
unsubscribeRef.current();
|
|
167
|
+
if (planRef.current.tests.length > 0) {
|
|
168
|
+
const summary = makeSummary(planRef.current);
|
|
169
|
+
setCompletedPlans((prev) => {
|
|
170
|
+
if (prev.some((p) => p.title === summary.title))
|
|
171
|
+
return prev;
|
|
172
|
+
return [...prev, summary];
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
planRef.current = undefined;
|
|
176
|
+
tasksRef.current = [];
|
|
177
|
+
setTasks([]);
|
|
178
|
+
setActivePlanInfo(null);
|
|
179
|
+
}
|
|
180
|
+
}, 2000);
|
|
181
|
+
return () => {
|
|
182
|
+
clearInterval(interval);
|
|
183
|
+
if (unsubscribeRef.current)
|
|
184
|
+
unsubscribeRef.current();
|
|
185
|
+
};
|
|
186
|
+
}, [explorBot]);
|
|
187
|
+
useInput((input, key) => {
|
|
188
|
+
if (key.escape) {
|
|
189
|
+
if (!showInput) {
|
|
190
|
+
executionController.interrupt();
|
|
191
|
+
}
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
if (key.ctrl) {
|
|
195
|
+
if (input === 'c') {
|
|
196
|
+
explorBot.stop().then(() => {
|
|
197
|
+
process.exit(0);
|
|
198
|
+
});
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
if (input === 't') {
|
|
202
|
+
setShowSessionTimer((prev) => !prev);
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
if (input === 'e' && tasksRef.current.length > 0) {
|
|
206
|
+
setShowPlanEditor(true);
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
if (!showInput && !showPlanEditor) {
|
|
211
|
+
if (key.upArrow) {
|
|
212
|
+
setTaskScrollOffset((prev) => Math.max(0, prev - 1));
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
if (key.downArrow) {
|
|
216
|
+
setTaskScrollOffset((prev) => prev + 1);
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
const handleInputSubmit = useCallback(async (input) => {
|
|
222
|
+
const trimmed = input.trim();
|
|
223
|
+
if (!trimmed)
|
|
224
|
+
return;
|
|
225
|
+
if (trimmed.toLowerCase() === '/help') {
|
|
226
|
+
setShowWelcome(true);
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
setShowWelcome(false);
|
|
230
|
+
}
|
|
231
|
+
tag('input').log(`> ${trimmed}`);
|
|
232
|
+
const isCommand = trimmed.startsWith('/') || trimmed.startsWith('I.') || trimmed.startsWith('page.') || trimmed.startsWith('await ');
|
|
233
|
+
if (trimmed.toLowerCase() === '/plan:edit') {
|
|
234
|
+
if (tasksRef.current.length > 0)
|
|
235
|
+
setShowPlanEditor(true);
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
if (isCommand) {
|
|
239
|
+
setInterruptPrompt(null);
|
|
240
|
+
setShowInput(false);
|
|
241
|
+
interruptResolveRef.current = null;
|
|
242
|
+
executionController.startExecution();
|
|
243
|
+
try {
|
|
244
|
+
await commandHandler.executeCommand(trimmed);
|
|
245
|
+
}
|
|
246
|
+
catch (error) {
|
|
247
|
+
if (error?.name === 'AbortError') {
|
|
248
|
+
tag('info').log('Operation cancelled');
|
|
249
|
+
}
|
|
250
|
+
else {
|
|
251
|
+
throw error;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
setShowInput(true);
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
if (interruptResolveRef.current) {
|
|
258
|
+
interruptResolveRef.current(input);
|
|
259
|
+
interruptResolveRef.current = null;
|
|
260
|
+
setInterruptPrompt(null);
|
|
261
|
+
setShowInput(false);
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
if (userInputPromiseRef.current) {
|
|
265
|
+
userInputPromiseRef.current.resolve(input);
|
|
266
|
+
userInputPromiseRef.current = null;
|
|
267
|
+
setShowInput(false);
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
setShowInput(false);
|
|
271
|
+
executionController.startExecution();
|
|
272
|
+
try {
|
|
273
|
+
await commandHandler.executeCommand(trimmed);
|
|
274
|
+
}
|
|
275
|
+
catch (error) {
|
|
276
|
+
if (error?.name === 'AbortError') {
|
|
277
|
+
tag('info').log('Operation cancelled');
|
|
278
|
+
}
|
|
279
|
+
else {
|
|
280
|
+
throw error;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
setShowInput(true);
|
|
284
|
+
}, [commandHandler]);
|
|
285
|
+
const handleCommandStart = useCallback(() => {
|
|
286
|
+
setShowInput(false);
|
|
287
|
+
}, []);
|
|
288
|
+
const handleCommandComplete = useCallback(() => {
|
|
289
|
+
setShowInput(true);
|
|
290
|
+
}, []);
|
|
291
|
+
return (React.createElement(Box, { flexDirection: "column" },
|
|
292
|
+
checklistData && React.createElement(WelcomeChecklist, { config: checklistData.config, knowledgeTracker: checklistData.knowledgeTracker }),
|
|
293
|
+
React.createElement(Box, { flexDirection: "column", flexGrow: 1 },
|
|
294
|
+
React.createElement(LogPane, { verboseMode: explorBot.getOptions()?.verbose || false })),
|
|
295
|
+
showPlanEditor && React.createElement(PlanEditor, { tasks: tasks, onClose: () => setShowPlanEditor(false), isActive: showPlanEditor }),
|
|
296
|
+
React.createElement(Box, { height: 3, flexDirection: "row", justifyContent: "space-between", alignItems: "center", paddingX: 1 },
|
|
297
|
+
React.createElement(ActivityPane, { isInputVisible: showInput }),
|
|
298
|
+
showSessionTimer && React.createElement(SessionTimer, { startedAt: sessionStartedAtRef.current })),
|
|
299
|
+
showWelcome && React.createElement(WelcomeCommands, { hasKnowledge: explorBot.getKnowledgeTracker().listAllKnowledge().length > 0 }),
|
|
300
|
+
showInput && React.createElement(Box, { height: 1 }),
|
|
301
|
+
interruptPrompt && showInput && (React.createElement(Box, { paddingX: 1 },
|
|
302
|
+
React.createElement(Text, { color: "yellow" }, interruptPrompt))),
|
|
303
|
+
React.createElement(Box, { display: showInput ? 'flex' : 'none' },
|
|
304
|
+
React.createElement(InputComponent, { commandHandler: commandHandler, onSubmit: handleInputSubmit, onCommandStart: handleCommandStart, onCommandComplete: handleCommandComplete, isActive: showInput && !showPlanEditor, visible: true })),
|
|
305
|
+
React.createElement(Box, { flexDirection: "row", alignItems: "flex-start", columnGap: 1, minHeight: 5 },
|
|
306
|
+
currentState && (React.createElement(Box, { width: tasks.length > 0 ? '50%' : '100%' },
|
|
307
|
+
React.createElement(StateTransitionPane, { currentState: currentState }))),
|
|
308
|
+
tasks.length > 0 && (React.createElement(Box, { width: currentState ? '50%' : '100%' },
|
|
309
|
+
React.createElement(TaskPane, { tasks: tasks, scrollOffset: taskScrollOffset }))),
|
|
310
|
+
React.createElement(Autocomplete, null)),
|
|
311
|
+
React.createElement(PlanPane, { completedPlans: completedPlans, activePlan: activePlanInfo })));
|
|
312
|
+
}
|
|
313
|
+
//# sourceMappingURL=App.js.map
|