openhorse 0.1.5
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 +460 -0
- package/bin/openhorse +56 -0
- package/dist/agents/coder.d.ts +12 -0
- package/dist/agents/coder.d.ts.map +1 -0
- package/dist/agents/coder.js +48 -0
- package/dist/agents/coder.js.map +1 -0
- package/dist/agents/leader.d.ts +12 -0
- package/dist/agents/leader.d.ts.map +1 -0
- package/dist/agents/leader.js +49 -0
- package/dist/agents/leader.js.map +1 -0
- package/dist/agents/router.d.ts +59 -0
- package/dist/agents/router.d.ts.map +1 -0
- package/dist/agents/router.js +193 -0
- package/dist/agents/router.js.map +1 -0
- package/dist/cli-ink.d.ts +7 -0
- package/dist/cli-ink.d.ts.map +1 -0
- package/dist/cli-ink.js +135 -0
- package/dist/cli-ink.js.map +1 -0
- package/dist/cli.d.ts +7 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +638 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/index.d.ts +12 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +1095 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/parser.d.ts +26 -0
- package/dist/commands/parser.d.ts.map +1 -0
- package/dist/commands/parser.js +61 -0
- package/dist/commands/parser.js.map +1 -0
- package/dist/commands/types.d.ts +61 -0
- package/dist/commands/types.d.ts.map +1 -0
- package/dist/commands/types.js +32 -0
- package/dist/commands/types.js.map +1 -0
- package/dist/core/agent.d.ts +66 -0
- package/dist/core/agent.d.ts.map +1 -0
- package/dist/core/agent.js +55 -0
- package/dist/core/agent.js.map +1 -0
- package/dist/core/brain.d.ts +41 -0
- package/dist/core/brain.d.ts.map +1 -0
- package/dist/core/brain.js +92 -0
- package/dist/core/brain.js.map +1 -0
- package/dist/core/cost-tracker.d.ts +107 -0
- package/dist/core/cost-tracker.d.ts.map +1 -0
- package/dist/core/cost-tracker.js +199 -0
- package/dist/core/cost-tracker.js.map +1 -0
- package/dist/core/strategy-tracker.d.ts +61 -0
- package/dist/core/strategy-tracker.d.ts.map +1 -0
- package/dist/core/strategy-tracker.js +124 -0
- package/dist/core/strategy-tracker.js.map +1 -0
- package/dist/framework/index.d.ts +20 -0
- package/dist/framework/index.d.ts.map +1 -0
- package/dist/framework/index.js +29 -0
- package/dist/framework/index.js.map +1 -0
- package/dist/framework/prompt.d.ts +40 -0
- package/dist/framework/prompt.d.ts.map +1 -0
- package/dist/framework/prompt.js +112 -0
- package/dist/framework/prompt.js.map +1 -0
- package/dist/framework/query.d.ts +86 -0
- package/dist/framework/query.d.ts.map +1 -0
- package/dist/framework/query.js +177 -0
- package/dist/framework/query.js.map +1 -0
- package/dist/framework/store.d.ts +64 -0
- package/dist/framework/store.d.ts.map +1 -0
- package/dist/framework/store.js +78 -0
- package/dist/framework/store.js.map +1 -0
- package/dist/framework/tool-state.d.ts +22 -0
- package/dist/framework/tool-state.d.ts.map +1 -0
- package/dist/framework/tool-state.js +40 -0
- package/dist/framework/tool-state.js.map +1 -0
- package/dist/framework/tool.d.ts +88 -0
- package/dist/framework/tool.d.ts.map +1 -0
- package/dist/framework/tool.js +60 -0
- package/dist/framework/tool.js.map +1 -0
- package/dist/harness/harness.d.ts +96 -0
- package/dist/harness/harness.d.ts.map +1 -0
- package/dist/harness/harness.js +224 -0
- package/dist/harness/harness.js.map +1 -0
- package/dist/harness/safety.d.ts +89 -0
- package/dist/harness/safety.d.ts.map +1 -0
- package/dist/harness/safety.js +178 -0
- package/dist/harness/safety.js.map +1 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +57 -0
- package/dist/index.js.map +1 -0
- package/dist/init.d.ts +178 -0
- package/dist/init.d.ts.map +1 -0
- package/dist/init.js +473 -0
- package/dist/init.js.map +1 -0
- package/dist/ink/bidi.d.ts +16 -0
- package/dist/ink/bidi.d.ts.map +1 -0
- package/dist/ink/bidi.js +124 -0
- package/dist/ink/bidi.js.map +1 -0
- package/dist/ink/clearTerminal.d.ts +14 -0
- package/dist/ink/clearTerminal.d.ts.map +1 -0
- package/dist/ink/clearTerminal.js +63 -0
- package/dist/ink/clearTerminal.js.map +1 -0
- package/dist/ink/colorize.d.ts +17 -0
- package/dist/ink/colorize.d.ts.map +1 -0
- package/dist/ink/colorize.js +208 -0
- package/dist/ink/colorize.js.map +1 -0
- package/dist/ink/components/App.d.ts +73 -0
- package/dist/ink/components/App.d.ts.map +1 -0
- package/dist/ink/components/App.js +646 -0
- package/dist/ink/components/App.js.map +1 -0
- package/dist/ink/components/AppContext.d.ts +12 -0
- package/dist/ink/components/AppContext.d.ts.map +1 -0
- package/dist/ink/components/AppContext.js +14 -0
- package/dist/ink/components/AppContext.js.map +1 -0
- package/dist/ink/components/Box.d.ts +44 -0
- package/dist/ink/components/Box.d.ts.map +1 -0
- package/dist/ink/components/Box.js +191 -0
- package/dist/ink/components/Box.js.map +1 -0
- package/dist/ink/components/ClockContext.d.ts +9 -0
- package/dist/ink/components/ClockContext.d.ts.map +1 -0
- package/dist/ink/components/ClockContext.js +146 -0
- package/dist/ink/components/ClockContext.js.map +1 -0
- package/dist/ink/components/CursorDeclarationContext.d.ts +23 -0
- package/dist/ink/components/CursorDeclarationContext.d.ts.map +1 -0
- package/dist/ink/components/CursorDeclarationContext.js +6 -0
- package/dist/ink/components/CursorDeclarationContext.js.map +1 -0
- package/dist/ink/components/ErrorOverview.d.ts +6 -0
- package/dist/ink/components/ErrorOverview.d.ts.map +1 -0
- package/dist/ink/components/ErrorOverview.js +27 -0
- package/dist/ink/components/ErrorOverview.js.map +1 -0
- package/dist/ink/components/Newline.d.ts +13 -0
- package/dist/ink/components/Newline.d.ts.map +1 -0
- package/dist/ink/components/Newline.js +36 -0
- package/dist/ink/components/Newline.js.map +1 -0
- package/dist/ink/components/NoSelect.d.ts +20 -0
- package/dist/ink/components/NoSelect.d.ts.map +1 -0
- package/dist/ink/components/NoSelect.js +63 -0
- package/dist/ink/components/NoSelect.js.map +1 -0
- package/dist/ink/components/RawAnsi.d.ts +17 -0
- package/dist/ink/components/RawAnsi.d.ts.map +1 -0
- package/dist/ink/components/RawAnsi.js +52 -0
- package/dist/ink/components/RawAnsi.js.map +1 -0
- package/dist/ink/components/Spacer.d.ts +6 -0
- package/dist/ink/components/Spacer.d.ts.map +1 -0
- package/dist/ink/components/Spacer.js +26 -0
- package/dist/ink/components/Spacer.js.map +1 -0
- package/dist/ink/components/StdinContext.d.ts +28 -0
- package/dist/ink/components/StdinContext.d.ts.map +1 -0
- package/dist/ink/components/StdinContext.js +19 -0
- package/dist/ink/components/StdinContext.js.map +1 -0
- package/dist/ink/components/TerminalFocusContext.d.ts +10 -0
- package/dist/ink/components/TerminalFocusContext.d.ts.map +1 -0
- package/dist/ink/components/TerminalFocusContext.js +81 -0
- package/dist/ink/components/TerminalFocusContext.js.map +1 -0
- package/dist/ink/components/TerminalSizeContext.d.ts +6 -0
- package/dist/ink/components/TerminalSizeContext.d.ts.map +1 -0
- package/dist/ink/components/TerminalSizeContext.js +6 -0
- package/dist/ink/components/TerminalSizeContext.js.map +1 -0
- package/dist/ink/components/Text.d.ts +56 -0
- package/dist/ink/components/Text.d.ts.map +1 -0
- package/dist/ink/components/Text.js +201 -0
- package/dist/ink/components/Text.js.map +1 -0
- package/dist/ink/constants.d.ts +2 -0
- package/dist/ink/constants.d.ts.map +1 -0
- package/dist/ink/constants.js +6 -0
- package/dist/ink/constants.js.map +1 -0
- package/dist/ink/devtools.d.ts +3 -0
- package/dist/ink/devtools.d.ts.map +1 -0
- package/dist/ink/devtools.js +5 -0
- package/dist/ink/devtools.js.map +1 -0
- package/dist/ink/dom.d.ts +77 -0
- package/dist/ink/dom.d.ts.map +1 -0
- package/dist/ink/dom.js +322 -0
- package/dist/ink/dom.js.map +1 -0
- package/dist/ink/events/click-event.d.ts +32 -0
- package/dist/ink/events/click-event.d.ts.map +1 -0
- package/dist/ink/events/click-event.js +30 -0
- package/dist/ink/events/click-event.js.map +1 -0
- package/dist/ink/events/dispatcher.d.ts +41 -0
- package/dist/ink/events/dispatcher.d.ts.map +1 -0
- package/dist/ink/events/dispatcher.js +181 -0
- package/dist/ink/events/dispatcher.js.map +1 -0
- package/dist/ink/events/emitter.d.ts +6 -0
- package/dist/ink/events/emitter.d.ts.map +1 -0
- package/dist/ink/events/emitter.js +36 -0
- package/dist/ink/events/emitter.js.map +1 -0
- package/dist/ink/events/event-handlers.d.ts +47 -0
- package/dist/ink/events/event-handlers.d.ts.map +1 -0
- package/dist/ink/events/event-handlers.js +34 -0
- package/dist/ink/events/event-handlers.js.map +1 -0
- package/dist/ink/events/event.d.ts +6 -0
- package/dist/ink/events/event.d.ts.map +1 -0
- package/dist/ink/events/event.js +16 -0
- package/dist/ink/events/event.js.map +1 -0
- package/dist/ink/events/focus-event.d.ts +14 -0
- package/dist/ink/events/focus-event.d.ts.map +1 -0
- package/dist/ink/events/focus-event.js +20 -0
- package/dist/ink/events/focus-event.js.map +1 -0
- package/dist/ink/events/input-event.d.ts +31 -0
- package/dist/ink/events/input-event.d.ts.map +1 -0
- package/dist/ink/events/input-event.js +163 -0
- package/dist/ink/events/input-event.js.map +1 -0
- package/dist/ink/events/keyboard-event.d.ts +20 -0
- package/dist/ink/events/keyboard-event.d.ts.map +1 -0
- package/dist/ink/events/keyboard-event.js +44 -0
- package/dist/ink/events/keyboard-event.js.map +1 -0
- package/dist/ink/events/terminal-event.d.ts +55 -0
- package/dist/ink/events/terminal-event.d.ts.map +1 -0
- package/dist/ink/events/terminal-event.js +79 -0
- package/dist/ink/events/terminal-event.js.map +1 -0
- package/dist/ink/events/terminal-focus-event.d.ts +14 -0
- package/dist/ink/events/terminal-focus-event.d.ts.map +1 -0
- package/dist/ink/events/terminal-focus-event.js +19 -0
- package/dist/ink/events/terminal-focus-event.js.map +1 -0
- package/dist/ink/focus.d.ts +44 -0
- package/dist/ink/focus.d.ts.map +1 -0
- package/dist/ink/focus.js +164 -0
- package/dist/ink/focus.js.map +1 -0
- package/dist/ink/frame.d.ts +95 -0
- package/dist/ink/frame.d.ts.map +1 -0
- package/dist/ink/frame.js +35 -0
- package/dist/ink/frame.js.map +1 -0
- package/dist/ink/get-max-width.d.ts +18 -0
- package/dist/ink/get-max-width.d.ts.map +1 -0
- package/dist/ink/get-max-width.js +26 -0
- package/dist/ink/get-max-width.js.map +1 -0
- package/dist/ink/hit-test.d.ts +34 -0
- package/dist/ink/hit-test.d.ts.map +1 -0
- package/dist/ink/hit-test.js +119 -0
- package/dist/ink/hit-test.js.map +1 -0
- package/dist/ink/hooks/use-animation-frame.d.ts +27 -0
- package/dist/ink/hooks/use-animation-frame.d.ts.map +1 -0
- package/dist/ink/hooks/use-animation-frame.js +52 -0
- package/dist/ink/hooks/use-animation-frame.js.map +1 -0
- package/dist/ink/hooks/use-app.d.ts +6 -0
- package/dist/ink/hooks/use-app.d.ts.map +1 -0
- package/dist/ink/hooks/use-app.js +13 -0
- package/dist/ink/hooks/use-app.js.map +1 -0
- package/dist/ink/hooks/use-declared-cursor.d.ts +27 -0
- package/dist/ink/hooks/use-declared-cursor.d.ts.map +1 -0
- package/dist/ink/hooks/use-declared-cursor.js +67 -0
- package/dist/ink/hooks/use-declared-cursor.js.map +1 -0
- package/dist/ink/hooks/use-input.d.ts +38 -0
- package/dist/ink/hooks/use-input.d.ts.map +1 -0
- package/dist/ink/hooks/use-input.js +86 -0
- package/dist/ink/hooks/use-input.js.map +1 -0
- package/dist/ink/hooks/use-interval.d.ts +19 -0
- package/dist/ink/hooks/use-interval.d.ts.map +1 -0
- package/dist/ink/hooks/use-interval.js +59 -0
- package/dist/ink/hooks/use-interval.js.map +1 -0
- package/dist/ink/hooks/use-search-highlight.d.ts +31 -0
- package/dist/ink/hooks/use-search-highlight.d.ts.map +1 -0
- package/dist/ink/hooks/use-search-highlight.js +39 -0
- package/dist/ink/hooks/use-search-highlight.js.map +1 -0
- package/dist/ink/hooks/use-selection.d.ts +40 -0
- package/dist/ink/hooks/use-selection.d.ts.map +1 -0
- package/dist/ink/hooks/use-selection.js +68 -0
- package/dist/ink/hooks/use-selection.js.map +1 -0
- package/dist/ink/hooks/use-stdin.d.ts +6 -0
- package/dist/ink/hooks/use-stdin.d.ts.map +1 -0
- package/dist/ink/hooks/use-stdin.js +13 -0
- package/dist/ink/hooks/use-stdin.js.map +1 -0
- package/dist/ink/hooks/use-tab-status.d.ts +14 -0
- package/dist/ink/hooks/use-tab-status.d.ts.map +1 -0
- package/dist/ink/hooks/use-tab-status.js +61 -0
- package/dist/ink/hooks/use-tab-status.js.map +1 -0
- package/dist/ink/hooks/use-terminal-focus.d.ts +11 -0
- package/dist/ink/hooks/use-terminal-focus.d.ts.map +1 -0
- package/dist/ink/hooks/use-terminal-focus.js +22 -0
- package/dist/ink/hooks/use-terminal-focus.js.map +1 -0
- package/dist/ink/hooks/use-terminal-title.d.ts +13 -0
- package/dist/ink/hooks/use-terminal-title.d.ts.map +1 -0
- package/dist/ink/hooks/use-terminal-title.js +36 -0
- package/dist/ink/hooks/use-terminal-title.js.map +1 -0
- package/dist/ink/hooks/use-terminal-viewport.d.ts +30 -0
- package/dist/ink/hooks/use-terminal-viewport.d.ts.map +1 -0
- package/dist/ink/hooks/use-terminal-viewport.js +81 -0
- package/dist/ink/hooks/use-terminal-viewport.js.map +1 -0
- package/dist/ink/index.d.ts +54 -0
- package/dist/ink/index.d.ts.map +1 -0
- package/dist/ink/index.js +111 -0
- package/dist/ink/index.js.map +1 -0
- package/dist/ink/ink.d.ts +371 -0
- package/dist/ink/ink.d.ts.map +1 -0
- package/dist/ink/ink.js +1686 -0
- package/dist/ink/ink.js.map +1 -0
- package/dist/ink/instances.d.ts +4 -0
- package/dist/ink/instances.d.ts.map +1 -0
- package/dist/ink/instances.js +10 -0
- package/dist/ink/instances.js.map +1 -0
- package/dist/ink/line-width-cache.d.ts +2 -0
- package/dist/ink/line-width-cache.d.ts.map +1 -0
- package/dist/ink/line-width-cache.js +23 -0
- package/dist/ink/line-width-cache.js.map +1 -0
- package/dist/ink/log-update.d.ts +18 -0
- package/dist/ink/log-update.d.ts.map +1 -0
- package/dist/ink/log-update.js +637 -0
- package/dist/ink/log-update.js.map +1 -0
- package/dist/ink/measure-element.d.ts +17 -0
- package/dist/ink/measure-element.d.ts.map +1 -0
- package/dist/ink/measure-element.js +11 -0
- package/dist/ink/measure-element.js.map +1 -0
- package/dist/ink/measure-text.d.ts +7 -0
- package/dist/ink/measure-text.d.ts.map +1 -0
- package/dist/ink/measure-text.js +38 -0
- package/dist/ink/measure-text.js.map +1 -0
- package/dist/ink/node-cache.d.ts +21 -0
- package/dist/ink/node-cache.d.ts.map +1 -0
- package/dist/ink/node-cache.js +36 -0
- package/dist/ink/node-cache.js.map +1 -0
- package/dist/ink/optimizer.d.ts +16 -0
- package/dist/ink/optimizer.d.ts.map +1 -0
- package/dist/ink/optimizer.js +85 -0
- package/dist/ink/optimizer.js.map +1 -0
- package/dist/ink/output.d.ts +120 -0
- package/dist/ink/output.d.ts.map +1 -0
- package/dist/ink/output.js +559 -0
- package/dist/ink/output.js.map +1 -0
- package/dist/ink/parse-keypress.d.ts +112 -0
- package/dist/ink/parse-keypress.d.ts.map +1 -0
- package/dist/ink/parse-keypress.js +719 -0
- package/dist/ink/parse-keypress.js.map +1 -0
- package/dist/ink/parse-keypress.test.d.ts +2 -0
- package/dist/ink/parse-keypress.test.d.ts.map +1 -0
- package/dist/ink/parse-keypress.test.js +37 -0
- package/dist/ink/parse-keypress.test.js.map +1 -0
- package/dist/ink/reconciler.d.ts +12 -0
- package/dist/ink/reconciler.d.ts.map +1 -0
- package/dist/ink/reconciler.js +456 -0
- package/dist/ink/reconciler.js.map +1 -0
- package/dist/ink/render-border.d.ts +25 -0
- package/dist/ink/render-border.d.ts.map +1 -0
- package/dist/ink/render-border.js +141 -0
- package/dist/ink/render-border.js.map +1 -0
- package/dist/ink/render-node-to-output.d.ts +46 -0
- package/dist/ink/render-node-to-output.d.ts.map +1 -0
- package/dist/ink/render-node-to-output.js +1257 -0
- package/dist/ink/render-node-to-output.js.map +1 -0
- package/dist/ink/render-to-screen.d.ts +47 -0
- package/dist/ink/render-to-screen.d.ts.map +1 -0
- package/dist/ink/render-to-screen.js +213 -0
- package/dist/ink/render-to-screen.js.map +1 -0
- package/dist/ink/renderer.d.ts +15 -0
- package/dist/ink/renderer.d.ts.map +1 -0
- package/dist/ink/renderer.js +169 -0
- package/dist/ink/renderer.js.map +1 -0
- package/dist/ink/root.d.ts +75 -0
- package/dist/ink/root.d.ts.map +1 -0
- package/dist/ink/root.js +89 -0
- package/dist/ink/root.js.map +1 -0
- package/dist/ink/screen.d.ts +270 -0
- package/dist/ink/screen.d.ts.map +1 -0
- package/dist/ink/screen.js +1194 -0
- package/dist/ink/screen.js.map +1 -0
- package/dist/ink/searchHighlight.d.ts +21 -0
- package/dist/ink/searchHighlight.d.ts.map +1 -0
- package/dist/ink/searchHighlight.js +82 -0
- package/dist/ink/searchHighlight.js.map +1 -0
- package/dist/ink/selection.d.ts +230 -0
- package/dist/ink/selection.d.ts.map +1 -0
- package/dist/ink/selection.js +814 -0
- package/dist/ink/selection.js.map +1 -0
- package/dist/ink/squash-text-nodes.d.ts +23 -0
- package/dist/ink/squash-text-nodes.d.ts.map +1 -0
- package/dist/ink/squash-text-nodes.js +60 -0
- package/dist/ink/squash-text-nodes.js.map +1 -0
- package/dist/ink/stringWidth.d.ts +2 -0
- package/dist/ink/stringWidth.d.ts.map +1 -0
- package/dist/ink/stringWidth.js +207 -0
- package/dist/ink/stringWidth.js.map +1 -0
- package/dist/ink/styles.d.ts +307 -0
- package/dist/ink/styles.d.ts.map +1 -0
- package/dist/ink/styles.js +302 -0
- package/dist/ink/styles.js.map +1 -0
- package/dist/ink/supports-hyperlinks.d.ts +14 -0
- package/dist/ink/supports-hyperlinks.d.ts.map +1 -0
- package/dist/ink/supports-hyperlinks.js +48 -0
- package/dist/ink/supports-hyperlinks.js.map +1 -0
- package/dist/ink/tabstops.d.ts +2 -0
- package/dist/ink/tabstops.d.ts.map +1 -0
- package/dist/ink/tabstops.js +43 -0
- package/dist/ink/tabstops.js.map +1 -0
- package/dist/ink/terminal-focus-state.d.ts +7 -0
- package/dist/ink/terminal-focus-state.d.ts.map +1 -0
- package/dist/ink/terminal-focus-state.js +43 -0
- package/dist/ink/terminal-focus-state.js.map +1 -0
- package/dist/ink/terminal-querier.d.ts +130 -0
- package/dist/ink/terminal-querier.d.ts.map +1 -0
- package/dist/ink/terminal-querier.js +184 -0
- package/dist/ink/terminal-querier.js.map +1 -0
- package/dist/ink/terminal.d.ts +56 -0
- package/dist/ink/terminal.d.ts.map +1 -0
- package/dist/ink/terminal.js +249 -0
- package/dist/ink/terminal.js.map +1 -0
- package/dist/ink/termio/csi.d.ts +166 -0
- package/dist/ink/termio/csi.d.ts.map +1 -0
- package/dist/ink/termio/csi.js +285 -0
- package/dist/ink/termio/csi.js.map +1 -0
- package/dist/ink/termio/dec.d.ts +38 -0
- package/dist/ink/termio/dec.d.ts.map +1 -0
- package/dist/ink/termio/dec.js +59 -0
- package/dist/ink/termio/dec.js.map +1 -0
- package/dist/ink/termio.d.ts +25 -0
- package/dist/ink/termio.d.ts.map +1 -0
- package/dist/ink/termio.js +32 -0
- package/dist/ink/termio.js.map +1 -0
- package/dist/ink/useTerminalNotification.d.ts +27 -0
- package/dist/ink/useTerminalNotification.d.ts.map +1 -0
- package/dist/ink/useTerminalNotification.js +62 -0
- package/dist/ink/useTerminalNotification.js.map +1 -0
- package/dist/ink/warn.d.ts +2 -0
- package/dist/ink/warn.d.ts.map +1 -0
- package/dist/ink/warn.js +14 -0
- package/dist/ink/warn.js.map +1 -0
- package/dist/ink/widest-line.d.ts +2 -0
- package/dist/ink/widest-line.d.ts.map +1 -0
- package/dist/ink/widest-line.js +18 -0
- package/dist/ink/widest-line.js.map +1 -0
- package/dist/ink/wrap-text.d.ts +3 -0
- package/dist/ink/wrap-text.d.ts.map +1 -0
- package/dist/ink/wrap-text.js +61 -0
- package/dist/ink/wrap-text.js.map +1 -0
- package/dist/ink/wrapAnsi.d.ts +8 -0
- package/dist/ink/wrapAnsi.d.ts.map +1 -0
- package/dist/ink/wrapAnsi.js +13 -0
- package/dist/ink/wrapAnsi.js.map +1 -0
- package/dist/memory/embeddings.d.ts +33 -0
- package/dist/memory/embeddings.d.ts.map +1 -0
- package/dist/memory/embeddings.js +123 -0
- package/dist/memory/embeddings.js.map +1 -0
- package/dist/memory/index.d.ts +14 -0
- package/dist/memory/index.d.ts.map +1 -0
- package/dist/memory/index.js +31 -0
- package/dist/memory/index.js.map +1 -0
- package/dist/memory/prompts.d.ts +12 -0
- package/dist/memory/prompts.d.ts.map +1 -0
- package/dist/memory/prompts.js +117 -0
- package/dist/memory/prompts.js.map +1 -0
- package/dist/memory/semantic-search.d.ts +45 -0
- package/dist/memory/semantic-search.d.ts.map +1 -0
- package/dist/memory/semantic-search.js +112 -0
- package/dist/memory/semantic-search.js.map +1 -0
- package/dist/memory/storage.d.ts +79 -0
- package/dist/memory/storage.d.ts.map +1 -0
- package/dist/memory/storage.js +285 -0
- package/dist/memory/storage.js.map +1 -0
- package/dist/memory/store.d.ts +103 -0
- package/dist/memory/store.d.ts.map +1 -0
- package/dist/memory/store.js +226 -0
- package/dist/memory/store.js.map +1 -0
- package/dist/memory/types.d.ts +40 -0
- package/dist/memory/types.d.ts.map +1 -0
- package/dist/memory/types.js +71 -0
- package/dist/memory/types.js.map +1 -0
- package/dist/memory/validation.d.ts +28 -0
- package/dist/memory/validation.d.ts.map +1 -0
- package/dist/memory/validation.js +147 -0
- package/dist/memory/validation.js.map +1 -0
- package/dist/memory/vector-store.d.ts +49 -0
- package/dist/memory/vector-store.d.ts.map +1 -0
- package/dist/memory/vector-store.js +259 -0
- package/dist/memory/vector-store.js.map +1 -0
- package/dist/screens/REPL.d.ts +21 -0
- package/dist/screens/REPL.d.ts.map +1 -0
- package/dist/screens/REPL.js +139 -0
- package/dist/screens/REPL.js.map +1 -0
- package/dist/services/agent-runner.d.ts +68 -0
- package/dist/services/agent-runner.d.ts.map +1 -0
- package/dist/services/agent-runner.js +186 -0
- package/dist/services/agent-runner.js.map +1 -0
- package/dist/services/atomic-write.d.ts +12 -0
- package/dist/services/atomic-write.d.ts.map +1 -0
- package/dist/services/atomic-write.js +27 -0
- package/dist/services/atomic-write.js.map +1 -0
- package/dist/services/config-dir.d.ts +55 -0
- package/dist/services/config-dir.d.ts.map +1 -0
- package/dist/services/config-dir.js +136 -0
- package/dist/services/config-dir.js.map +1 -0
- package/dist/services/config.d.ts +54 -0
- package/dist/services/config.d.ts.map +1 -0
- package/dist/services/config.js +98 -0
- package/dist/services/config.js.map +1 -0
- package/dist/services/file-glob.d.ts +26 -0
- package/dist/services/file-glob.d.ts.map +1 -0
- package/dist/services/file-glob.js +134 -0
- package/dist/services/file-glob.js.map +1 -0
- package/dist/services/global-config.d.ts +109 -0
- package/dist/services/global-config.d.ts.map +1 -0
- package/dist/services/global-config.js +211 -0
- package/dist/services/global-config.js.map +1 -0
- package/dist/services/llm.d.ts +139 -0
- package/dist/services/llm.d.ts.map +1 -0
- package/dist/services/llm.js +376 -0
- package/dist/services/llm.js.map +1 -0
- package/dist/services/memory.d.ts +39 -0
- package/dist/services/memory.d.ts.map +1 -0
- package/dist/services/memory.js +88 -0
- package/dist/services/memory.js.map +1 -0
- package/dist/services/session-storage.d.ts +136 -0
- package/dist/services/session-storage.d.ts.map +1 -0
- package/dist/services/session-storage.js +304 -0
- package/dist/services/session-storage.js.map +1 -0
- package/dist/services/task-manager.d.ts +154 -0
- package/dist/services/task-manager.d.ts.map +1 -0
- package/dist/services/task-manager.js +288 -0
- package/dist/services/task-manager.js.map +1 -0
- package/dist/services/yaml-config.d.ts +57 -0
- package/dist/services/yaml-config.d.ts.map +1 -0
- package/dist/services/yaml-config.js +176 -0
- package/dist/services/yaml-config.js.map +1 -0
- package/dist/skills/discovery.d.ts +22 -0
- package/dist/skills/discovery.d.ts.map +1 -0
- package/dist/skills/discovery.js +75 -0
- package/dist/skills/discovery.js.map +1 -0
- package/dist/skills/index.d.ts +10 -0
- package/dist/skills/index.d.ts.map +1 -0
- package/dist/skills/index.js +26 -0
- package/dist/skills/index.js.map +1 -0
- package/dist/skills/loader.d.ts +48 -0
- package/dist/skills/loader.d.ts.map +1 -0
- package/dist/skills/loader.js +231 -0
- package/dist/skills/loader.js.map +1 -0
- package/dist/skills/registry.d.ts +37 -0
- package/dist/skills/registry.d.ts.map +1 -0
- package/dist/skills/registry.js +134 -0
- package/dist/skills/registry.js.map +1 -0
- package/dist/skills/types.d.ts +89 -0
- package/dist/skills/types.d.ts.map +1 -0
- package/dist/skills/types.js +24 -0
- package/dist/skills/types.js.map +1 -0
- package/dist/tools/bash_security.d.ts +64 -0
- package/dist/tools/bash_security.d.ts.map +1 -0
- package/dist/tools/bash_security.js +291 -0
- package/dist/tools/bash_security.js.map +1 -0
- package/dist/tools/index.d.ts +23 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +965 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/mcp.d.ts +72 -0
- package/dist/tools/mcp.d.ts.map +1 -0
- package/dist/tools/mcp.js +422 -0
- package/dist/tools/mcp.js.map +1 -0
- package/dist/tools/plan.d.ts +18 -0
- package/dist/tools/plan.d.ts.map +1 -0
- package/dist/tools/plan.js +75 -0
- package/dist/tools/plan.js.map +1 -0
- package/dist/tools/todo.d.ts +18 -0
- package/dist/tools/todo.d.ts.map +1 -0
- package/dist/tools/todo.js +153 -0
- package/dist/tools/todo.js.map +1 -0
- package/dist/tools/web.d.ts +13 -0
- package/dist/tools/web.d.ts.map +1 -0
- package/dist/tools/web.js +377 -0
- package/dist/tools/web.js.map +1 -0
- package/dist/ui/box.d.ts +56 -0
- package/dist/ui/box.d.ts.map +1 -0
- package/dist/ui/box.js +241 -0
- package/dist/ui/box.js.map +1 -0
- package/dist/ui/command-panel.d.ts +55 -0
- package/dist/ui/command-panel.d.ts.map +1 -0
- package/dist/ui/command-panel.js +212 -0
- package/dist/ui/command-panel.js.map +1 -0
- package/dist/ui/file-completion.d.ts +62 -0
- package/dist/ui/file-completion.d.ts.map +1 -0
- package/dist/ui/file-completion.js +209 -0
- package/dist/ui/file-completion.js.map +1 -0
- package/dist/ui/markdown.d.ts +12 -0
- package/dist/ui/markdown.d.ts.map +1 -0
- package/dist/ui/markdown.js +215 -0
- package/dist/ui/markdown.js.map +1 -0
- package/dist/ui/multiline-input.d.ts +47 -0
- package/dist/ui/multiline-input.d.ts.map +1 -0
- package/dist/ui/multiline-input.js +94 -0
- package/dist/ui/multiline-input.js.map +1 -0
- package/dist/ui/status-bar.d.ts +33 -0
- package/dist/ui/status-bar.d.ts.map +1 -0
- package/dist/ui/status-bar.js +96 -0
- package/dist/ui/status-bar.js.map +1 -0
- package/dist/ui/stream-markdown.d.ts +35 -0
- package/dist/ui/stream-markdown.d.ts.map +1 -0
- package/dist/ui/stream-markdown.js +138 -0
- package/dist/ui/stream-markdown.js.map +1 -0
- package/dist/ui/suggestions.d.ts +35 -0
- package/dist/ui/suggestions.d.ts.map +1 -0
- package/dist/ui/suggestions.js +118 -0
- package/dist/ui/suggestions.js.map +1 -0
- package/dist/ui/tool-preview.d.ts +34 -0
- package/dist/ui/tool-preview.d.ts.map +1 -0
- package/dist/ui/tool-preview.js +128 -0
- package/dist/ui/tool-preview.js.map +1 -0
- package/package.json +93 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* openhorse - Plan Mode Tools
|
|
4
|
+
*
|
|
5
|
+
* enter_plan_mode: Enter planning mode for complex tasks
|
|
6
|
+
* exit_plan_mode: Exit planning mode with a plan
|
|
7
|
+
*
|
|
8
|
+
* State is held in the shared tool-state module so the CLI can mirror it
|
|
9
|
+
* into the main Store.
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.PLAN_TOOLS = exports.exitPlanModeTool = exports.enterPlanModeTool = void 0;
|
|
13
|
+
exports.isInPlanMode = isInPlanMode;
|
|
14
|
+
exports.getCurrentPlan = getCurrentPlan;
|
|
15
|
+
const tool_1 = require("../framework/tool");
|
|
16
|
+
const tool_state_1 = require("../framework/tool-state");
|
|
17
|
+
exports.enterPlanModeTool = (0, tool_1.buildTool)({
|
|
18
|
+
name: 'enter_plan_mode',
|
|
19
|
+
description: `Enter plan mode for complex tasks requiring exploration and planning.
|
|
20
|
+
In plan mode, you should explore the project structure, understand the problem,
|
|
21
|
+
and create a detailed implementation plan WITHOUT executing any code changes.
|
|
22
|
+
Use this when the task is complex, ambiguous, or requires careful consideration.`,
|
|
23
|
+
parameters: {
|
|
24
|
+
type: 'object',
|
|
25
|
+
properties: {},
|
|
26
|
+
},
|
|
27
|
+
execute: async () => {
|
|
28
|
+
(0, tool_state_1.setToolState)({ planMode: true, currentPlan: null });
|
|
29
|
+
return {
|
|
30
|
+
success: true,
|
|
31
|
+
output: 'Entered plan mode. Explore the project, understand the problem, and create a plan. Use exit_plan_mode when ready with your plan.',
|
|
32
|
+
};
|
|
33
|
+
},
|
|
34
|
+
isReadOnly: () => true,
|
|
35
|
+
isConcurrencySafe: () => true,
|
|
36
|
+
checkPermissions: () => ({ behavior: 'allow', reason: 'Safe mode change' }),
|
|
37
|
+
userFacingName: () => 'Enter plan mode',
|
|
38
|
+
});
|
|
39
|
+
exports.exitPlanModeTool = (0, tool_1.buildTool)({
|
|
40
|
+
name: 'exit_plan_mode',
|
|
41
|
+
description: `Exit plan mode and save the implementation plan.
|
|
42
|
+
This tool finalizes the plan and returns to execution mode.`,
|
|
43
|
+
parameters: {
|
|
44
|
+
type: 'object',
|
|
45
|
+
properties: {
|
|
46
|
+
plan: {
|
|
47
|
+
type: 'string',
|
|
48
|
+
description: 'The detailed implementation plan',
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
required: ['plan'],
|
|
52
|
+
},
|
|
53
|
+
execute: async (args) => {
|
|
54
|
+
const plan = args.plan;
|
|
55
|
+
(0, tool_state_1.setToolState)({ planMode: false, currentPlan: plan });
|
|
56
|
+
return {
|
|
57
|
+
success: true,
|
|
58
|
+
output: `Exited plan mode. Plan saved:\n\n${plan}`,
|
|
59
|
+
};
|
|
60
|
+
},
|
|
61
|
+
isReadOnly: () => false,
|
|
62
|
+
isConcurrencySafe: () => true,
|
|
63
|
+
checkPermissions: () => ({ behavior: 'allow', reason: 'Safe mode change' }),
|
|
64
|
+
userFacingName: () => 'Exit plan mode',
|
|
65
|
+
});
|
|
66
|
+
/** Check if currently in plan mode */
|
|
67
|
+
function isInPlanMode() {
|
|
68
|
+
return (0, tool_state_1.getToolState)().planMode;
|
|
69
|
+
}
|
|
70
|
+
/** Get current plan */
|
|
71
|
+
function getCurrentPlan() {
|
|
72
|
+
return (0, tool_state_1.getToolState)().currentPlan ?? '';
|
|
73
|
+
}
|
|
74
|
+
exports.PLAN_TOOLS = [exports.enterPlanModeTool, exports.exitPlanModeTool];
|
|
75
|
+
//# sourceMappingURL=plan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan.js","sourceRoot":"","sources":["../../src/tools/plan.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;AAyDH,oCAEC;AAGD,wCAEC;AA9DD,4CAAkE;AAClE,wDAAqE;AAExD,QAAA,iBAAiB,GAAkB,IAAA,gBAAS,EAAC;IACxD,IAAI,EAAE,iBAAiB;IACvB,WAAW,EAAE;;;iFAGkE;IAC/E,UAAU,EAAE;QACV,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE,EAAE;KACf;IACD,OAAO,EAAE,KAAK,IAAI,EAAE;QAClB,IAAA,yBAAY,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;QACpD,OAAO;YACL,OAAO,EAAE,IAAI;YACb,MAAM,EAAE,kIAAkI;SAC3I,CAAC;IACJ,CAAC;IACD,UAAU,EAAE,GAAG,EAAE,CAAC,IAAI;IACtB,iBAAiB,EAAE,GAAG,EAAE,CAAC,IAAI;IAC7B,gBAAgB,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAC3E,cAAc,EAAE,GAAG,EAAE,CAAC,iBAAiB;CACxC,CAAC,CAAC;AAEU,QAAA,gBAAgB,GAAkB,IAAA,gBAAS,EAAC;IACvD,IAAI,EAAE,gBAAgB;IACtB,WAAW,EAAE;4DAC6C;IAC1D,UAAU,EAAE;QACV,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,IAAI,EAAE;gBACJ,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,kCAAkC;aAChD;SACF;QACD,QAAQ,EAAE,CAAC,MAAM,CAAC;KACnB;IACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QACtB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAc,CAAC;QACjC,IAAA,yBAAY,EAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;QACrD,OAAO;YACL,OAAO,EAAE,IAAI;YACb,MAAM,EAAE,oCAAoC,IAAI,EAAE;SACnD,CAAC;IACJ,CAAC;IACD,UAAU,EAAE,GAAG,EAAE,CAAC,KAAK;IACvB,iBAAiB,EAAE,GAAG,EAAE,CAAC,IAAI;IAC7B,gBAAgB,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAC3E,cAAc,EAAE,GAAG,EAAE,CAAC,gBAAgB;CACvC,CAAC,CAAC;AAEH,sCAAsC;AACtC,SAAgB,YAAY;IAC1B,OAAO,IAAA,yBAAY,GAAE,CAAC,QAAQ,CAAC;AACjC,CAAC;AAED,uBAAuB;AACvB,SAAgB,cAAc;IAC5B,OAAO,IAAA,yBAAY,GAAE,CAAC,WAAW,IAAI,EAAE,CAAC;AAC1C,CAAC;AAEY,QAAA,UAAU,GAAoB,CAAC,yBAAiB,EAAE,wBAAgB,CAAC,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* openhorse - TodoWrite Tool
|
|
3
|
+
*
|
|
4
|
+
* Manage task progress during coding sessions.
|
|
5
|
+
*
|
|
6
|
+
* State is held in the shared tool-state module so the CLI can mirror it
|
|
7
|
+
* into the main Store and render it in the UI.
|
|
8
|
+
*/
|
|
9
|
+
import { type OpenHorseTool } from '../framework/tool';
|
|
10
|
+
import { type TodoItem } from '../framework/tool-state';
|
|
11
|
+
export declare const todoWriteTool: OpenHorseTool;
|
|
12
|
+
/** Get current todos (for UI display) */
|
|
13
|
+
export declare function getCurrentTodos(): TodoItem[];
|
|
14
|
+
/** Format todos for display */
|
|
15
|
+
export declare function formatTodosForDisplay(todos: TodoItem[]): string;
|
|
16
|
+
export type { TodoItem };
|
|
17
|
+
export declare const TODO_TOOLS: OpenHorseTool[];
|
|
18
|
+
//# sourceMappingURL=todo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"todo.d.ts","sourceRoot":"","sources":["../../src/tools/todo.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAa,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,EAA8B,KAAK,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AA4CpF,eAAO,MAAM,aAAa,EAAE,aAmF1B,CAAC;AAEH,yCAAyC;AACzC,wBAAgB,eAAe,IAAI,QAAQ,EAAE,CAE5C;AAED,+BAA+B;AAC/B,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,MAAM,CAc/D;AAED,YAAY,EAAE,QAAQ,EAAE,CAAC;AACzB,eAAO,MAAM,UAAU,EAAE,aAAa,EAAoB,CAAC"}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* openhorse - TodoWrite Tool
|
|
4
|
+
*
|
|
5
|
+
* Manage task progress during coding sessions.
|
|
6
|
+
*
|
|
7
|
+
* State is held in the shared tool-state module so the CLI can mirror it
|
|
8
|
+
* into the main Store and render it in the UI.
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.TODO_TOOLS = exports.todoWriteTool = void 0;
|
|
12
|
+
exports.getCurrentTodos = getCurrentTodos;
|
|
13
|
+
exports.formatTodosForDisplay = formatTodosForDisplay;
|
|
14
|
+
const tool_1 = require("../framework/tool");
|
|
15
|
+
const tool_state_1 = require("../framework/tool-state");
|
|
16
|
+
// ============================================================================
|
|
17
|
+
// TodoWrite Tool
|
|
18
|
+
// ============================================================================
|
|
19
|
+
const TODO_PROMPT = `Use this tool to create and manage a structured task list for your current coding session. This helps you track progress, organize complex tasks, and demonstrate thoroughness to the user.
|
|
20
|
+
|
|
21
|
+
## When to Use This Tool
|
|
22
|
+
|
|
23
|
+
1. Complex multi-step tasks - When a task requires 3 or more distinct steps
|
|
24
|
+
2. Non-trivial tasks - Tasks that require careful planning or multiple operations
|
|
25
|
+
3. User explicitly requests todo list
|
|
26
|
+
4. User provides multiple tasks (numbered or comma-separated)
|
|
27
|
+
5. After receiving new instructions - Immediately capture user requirements
|
|
28
|
+
6. When you start working on a task - Mark it as in_progress BEFORE beginning
|
|
29
|
+
7. After completing a task - Mark it completed immediately
|
|
30
|
+
|
|
31
|
+
## When NOT to Use
|
|
32
|
+
|
|
33
|
+
1. Single, straightforward task
|
|
34
|
+
2. Trivial task with no organizational benefit
|
|
35
|
+
3. Purely conversational or informational
|
|
36
|
+
|
|
37
|
+
## Task States
|
|
38
|
+
|
|
39
|
+
- pending: Task not yet started
|
|
40
|
+
- in_progress: Currently working on (limit to ONE task at a time)
|
|
41
|
+
- completed: Task finished successfully
|
|
42
|
+
|
|
43
|
+
## Task Format
|
|
44
|
+
|
|
45
|
+
Each todo must have:
|
|
46
|
+
- content: Imperative form ("Run tests")
|
|
47
|
+
- activeForm: Present continuous form ("Running tests")
|
|
48
|
+
- status: pending | in_progress | completed
|
|
49
|
+
|
|
50
|
+
## Rules
|
|
51
|
+
|
|
52
|
+
- Exactly ONE task should be in_progress at any time
|
|
53
|
+
- Mark tasks complete IMMEDIATELY after finishing
|
|
54
|
+
- Remove tasks that are no longer relevant
|
|
55
|
+
- Only mark completed when FULLY accomplished`;
|
|
56
|
+
exports.todoWriteTool = (0, tool_1.buildTool)({
|
|
57
|
+
name: 'todo_write',
|
|
58
|
+
description: `Update the todo list for the current session.
|
|
59
|
+
|
|
60
|
+
${TODO_PROMPT}`,
|
|
61
|
+
parameters: {
|
|
62
|
+
type: 'object',
|
|
63
|
+
properties: {
|
|
64
|
+
todos: {
|
|
65
|
+
type: 'string',
|
|
66
|
+
description: 'JSON array of todos: [{"content":"Task","status":"pending|in_progress|completed","activeForm":"Doing task"}]',
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
required: ['todos'],
|
|
70
|
+
},
|
|
71
|
+
execute: async (args) => {
|
|
72
|
+
let todos;
|
|
73
|
+
try {
|
|
74
|
+
todos = JSON.parse(args.todos);
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return { success: false, output: '', error: 'todos must be valid JSON array' };
|
|
78
|
+
}
|
|
79
|
+
if (!Array.isArray(todos)) {
|
|
80
|
+
return { success: false, output: '', error: 'todos must be an array' };
|
|
81
|
+
}
|
|
82
|
+
for (const todo of todos) {
|
|
83
|
+
if (!todo.content || typeof todo.content !== 'string') {
|
|
84
|
+
return { success: false, output: '', error: 'Each todo must have a content string' };
|
|
85
|
+
}
|
|
86
|
+
if (!todo.activeForm || typeof todo.activeForm !== 'string') {
|
|
87
|
+
return { success: false, output: '', error: 'Each todo must have an activeForm string' };
|
|
88
|
+
}
|
|
89
|
+
if (!['pending', 'in_progress', 'completed'].includes(todo.status)) {
|
|
90
|
+
return { success: false, output: '', error: `Invalid status: ${todo.status}` };
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
const inProgressCount = todos.filter(t => t.status === 'in_progress').length;
|
|
94
|
+
if (inProgressCount > 1) {
|
|
95
|
+
return {
|
|
96
|
+
success: false,
|
|
97
|
+
output: '',
|
|
98
|
+
error: 'Only one task can be in_progress at a time',
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
(0, tool_state_1.setToolState)({ todos });
|
|
102
|
+
const lines = [];
|
|
103
|
+
lines.push('Todo list updated:');
|
|
104
|
+
lines.push('');
|
|
105
|
+
for (let i = 0; i < todos.length; i++) {
|
|
106
|
+
const todo = todos[i];
|
|
107
|
+
const icon = todo.status === 'completed' ? '✅' : todo.status === 'in_progress' ? '⏳' : '⬚';
|
|
108
|
+
lines.push(`${i + 1}. [${icon}] ${todo.content}`);
|
|
109
|
+
if (todo.status === 'in_progress') {
|
|
110
|
+
lines.push(` → ${todo.activeForm}`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
lines.push('');
|
|
114
|
+
lines.push(`Summary: ${todos.length} tasks, ${todos.filter(t => t.status === 'completed').length} completed, ${inProgressCount} in progress`);
|
|
115
|
+
return {
|
|
116
|
+
success: true,
|
|
117
|
+
output: lines.join('\n'),
|
|
118
|
+
};
|
|
119
|
+
},
|
|
120
|
+
isReadOnly: () => false,
|
|
121
|
+
checkPermissions: () => {
|
|
122
|
+
return { behavior: 'allow', reason: 'Todo operations are safe' };
|
|
123
|
+
},
|
|
124
|
+
userFacingName: (args) => {
|
|
125
|
+
try {
|
|
126
|
+
const todos = JSON.parse(args.todos);
|
|
127
|
+
return `Update ${todos.length} todos`;
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
return 'Update todos';
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
});
|
|
134
|
+
/** Get current todos (for UI display) */
|
|
135
|
+
function getCurrentTodos() {
|
|
136
|
+
return (0, tool_state_1.getToolState)().todos;
|
|
137
|
+
}
|
|
138
|
+
/** Format todos for display */
|
|
139
|
+
function formatTodosForDisplay(todos) {
|
|
140
|
+
if (todos.length === 0)
|
|
141
|
+
return 'No active tasks';
|
|
142
|
+
const lines = [];
|
|
143
|
+
lines.push('Tasks:');
|
|
144
|
+
lines.push('');
|
|
145
|
+
for (let i = 0; i < todos.length; i++) {
|
|
146
|
+
const todo = todos[i];
|
|
147
|
+
const icon = todo.status === 'completed' ? '✅' : todo.status === 'in_progress' ? '⏳' : '⬚';
|
|
148
|
+
lines.push(`${i + 1}. [${icon}] ${todo.status === 'in_progress' ? todo.activeForm : todo.content}`);
|
|
149
|
+
}
|
|
150
|
+
return lines.join('\n');
|
|
151
|
+
}
|
|
152
|
+
exports.TODO_TOOLS = [exports.todoWriteTool];
|
|
153
|
+
//# sourceMappingURL=todo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"todo.js","sourceRoot":"","sources":["../../src/tools/todo.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* openhorse - Web Tools
|
|
3
|
+
*
|
|
4
|
+
* WebFetch: Fetch URL content and process with prompt
|
|
5
|
+
* WebSearch: Search the web for information
|
|
6
|
+
*/
|
|
7
|
+
import { type OpenHorseTool } from '../framework/tool';
|
|
8
|
+
/** Clear the fetch cache (test helper / debugging) */
|
|
9
|
+
export declare function clearWebFetchCache(): void;
|
|
10
|
+
export declare const webFetchTool: OpenHorseTool;
|
|
11
|
+
export declare const webSearchTool: OpenHorseTool;
|
|
12
|
+
export declare const WEB_TOOLS: OpenHorseTool[];
|
|
13
|
+
//# sourceMappingURL=web.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web.d.ts","sourceRoot":"","sources":["../../src/tools/web.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAa,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAiLlE,sDAAsD;AACtD,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC;AA0BD,eAAO,MAAM,YAAY,EAAE,aA4EzB,CAAC;AAiFH,eAAO,MAAM,aAAa,EAAE,aAqD1B,CAAC;AAMH,eAAO,MAAM,SAAS,EAAE,aAAa,EAAkC,CAAC"}
|
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* openhorse - Web Tools
|
|
4
|
+
*
|
|
5
|
+
* WebFetch: Fetch URL content and process with prompt
|
|
6
|
+
* WebSearch: Search the web for information
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.WEB_TOOLS = exports.webSearchTool = exports.webFetchTool = void 0;
|
|
10
|
+
exports.clearWebFetchCache = clearWebFetchCache;
|
|
11
|
+
const tool_1 = require("../framework/tool");
|
|
12
|
+
// ============================================================================
|
|
13
|
+
// WebFetch Tool
|
|
14
|
+
// ============================================================================
|
|
15
|
+
/** Preapproved hosts that don't need permission */
|
|
16
|
+
const PREAPPROVED_HOSTS = [
|
|
17
|
+
'github.com',
|
|
18
|
+
'docs.google.com',
|
|
19
|
+
'stackoverflow.com',
|
|
20
|
+
'npmjs.com',
|
|
21
|
+
'nodejs.org',
|
|
22
|
+
'typescriptlang.org',
|
|
23
|
+
'reactjs.org',
|
|
24
|
+
'vuejs.org',
|
|
25
|
+
'python.org',
|
|
26
|
+
'golang.org',
|
|
27
|
+
'rust-lang.org',
|
|
28
|
+
'mdn.mozilla.org',
|
|
29
|
+
'developer.mozilla.org',
|
|
30
|
+
'wikipedia.org',
|
|
31
|
+
'arxiv.org',
|
|
32
|
+
];
|
|
33
|
+
const MAX_MARKDOWN_LENGTH = 100000;
|
|
34
|
+
const FETCH_CACHE_TTL_MS = 15 * 60 * 1000;
|
|
35
|
+
const FETCH_CACHE_MAX_ENTRIES = 50;
|
|
36
|
+
const fetchCache = new Map();
|
|
37
|
+
function cacheGet(url) {
|
|
38
|
+
const entry = fetchCache.get(url);
|
|
39
|
+
if (!entry)
|
|
40
|
+
return null;
|
|
41
|
+
if (Date.now() - entry.ts > FETCH_CACHE_TTL_MS) {
|
|
42
|
+
fetchCache.delete(url);
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
return entry.data;
|
|
46
|
+
}
|
|
47
|
+
function cacheSet(url, data) {
|
|
48
|
+
// Cap size — drop oldest entry when full
|
|
49
|
+
if (fetchCache.size >= FETCH_CACHE_MAX_ENTRIES) {
|
|
50
|
+
const oldest = fetchCache.keys().next().value;
|
|
51
|
+
if (oldest)
|
|
52
|
+
fetchCache.delete(oldest);
|
|
53
|
+
}
|
|
54
|
+
fetchCache.set(url, { ts: Date.now(), data });
|
|
55
|
+
}
|
|
56
|
+
function isPreapprovedHost(hostname, pathname) {
|
|
57
|
+
return PREAPPROVED_HOSTS.some(host => hostname === host || hostname.endsWith('.' + host));
|
|
58
|
+
}
|
|
59
|
+
/** Simple HTML to Markdown converter */
|
|
60
|
+
function htmlToMarkdown(html) {
|
|
61
|
+
let md = html;
|
|
62
|
+
// Remove script, style, nav, header, footer tags
|
|
63
|
+
md = md.replace(/<script[^>]*>[\s\S]*?<\/script>/gi, '');
|
|
64
|
+
md = md.replace(/<style[^>]*>[\s\S]*?<\/style>/gi, '');
|
|
65
|
+
md = md.replace(/<nav[^>]*>[\s\S]*?<\/nav>/gi, '');
|
|
66
|
+
md = md.replace(/<header[^>]*>[\s\S]*?<\/header>/gi, '');
|
|
67
|
+
md = md.replace(/<footer[^>]*>[\s\S]*?<\/footer>/gi, '');
|
|
68
|
+
// Convert headings
|
|
69
|
+
md = md.replace(/<h1[^>]*>([\s\S]*?)<\/h1>/gi, '# $1\n\n');
|
|
70
|
+
md = md.replace(/<h2[^>]*>([\s\S]*?)<\/h2>/gi, '## $1\n\n');
|
|
71
|
+
md = md.replace(/<h3[^>]*>([\s\S]*?)<\/h3>/gi, '### $1\n\n');
|
|
72
|
+
md = md.replace(/<h4[^>]*>([\s\S]*?)<\/h4>/gi, '#### $1\n\n');
|
|
73
|
+
md = md.replace(/<h5[^>]*>([\s\S]*?)<\/h5>/gi, '##### $1\n\n');
|
|
74
|
+
md = md.replace(/<h6[^>]*>([\s\S]*?)<\/h6>/gi, '###### $1\n\n');
|
|
75
|
+
// Bold and italic
|
|
76
|
+
md = md.replace(/<strong[^>]*>([\s\S]*?)<\/strong>/gi, '**$1**');
|
|
77
|
+
md = md.replace(/<b[^>]*>([\s\S]*?)<\/b>/gi, '**$1**');
|
|
78
|
+
md = md.replace(/<em[^>]*>([\s\S]*?)<\/em>/gi, '*$1*');
|
|
79
|
+
md = md.replace(/<i[^>]*>([\s\S]*?)<\/i>/gi, '*$1*');
|
|
80
|
+
// Links
|
|
81
|
+
md = md.replace(/<a[^>]*href="([^"]*)"[^>]*>([\s\S]*?)<\/a>/gi, '[$2]($1)');
|
|
82
|
+
// Code blocks
|
|
83
|
+
md = md.replace(/<pre[^>]*><code[^>]*>([\s\S]*?)<\/code><\/pre>/gi, '\n```\n$1\n```\n');
|
|
84
|
+
md = md.replace(/<code[^>]*>([\s\S]*?)<\/code>/gi, '`$1`');
|
|
85
|
+
// Lists
|
|
86
|
+
md = md.replace(/<li[^>]*>([\s\S]*?)<\/li>/gi, '- $1\n');
|
|
87
|
+
md = md.replace(/<ul[^>]*>([\s\S]*?)<\/ul>/gi, '$1');
|
|
88
|
+
md = md.replace(/<ol[^>]*>([\s\S]*?)<\/ol>/gi, '$1');
|
|
89
|
+
// Paragraphs and divs
|
|
90
|
+
md = md.replace(/<p[^>]*>([\s\S]*?)<\/p>/gi, '$1\n\n');
|
|
91
|
+
md = md.replace(/<div[^>]*>([\s\S]*?)<\/div>/gi, '$1\n');
|
|
92
|
+
md = md.replace(/<br\s*\/?>/gi, '\n');
|
|
93
|
+
// Remove remaining tags
|
|
94
|
+
md = md.replace(/<[^>]+>/g, '');
|
|
95
|
+
// Clean up whitespace
|
|
96
|
+
md = md.replace(/\n{3,}/g, '\n\n');
|
|
97
|
+
md = md.trim();
|
|
98
|
+
return md;
|
|
99
|
+
}
|
|
100
|
+
async function fetchUrl(url) {
|
|
101
|
+
const cached = cacheGet(url);
|
|
102
|
+
if (cached)
|
|
103
|
+
return cached;
|
|
104
|
+
try {
|
|
105
|
+
const response = await fetch(url, {
|
|
106
|
+
headers: {
|
|
107
|
+
'User-Agent': 'OpenHorse/0.1.4',
|
|
108
|
+
'Accept': 'text/html,application/xhtml+xml,text/markdown,text/plain,*/*',
|
|
109
|
+
},
|
|
110
|
+
});
|
|
111
|
+
const contentType = response.headers.get('content-type') || 'text/plain';
|
|
112
|
+
if (!response.ok) {
|
|
113
|
+
return {
|
|
114
|
+
content: `HTTP Error ${response.status}: ${response.statusText}`,
|
|
115
|
+
code: response.status,
|
|
116
|
+
contentType,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
// Check for redirect to different host
|
|
120
|
+
if (response.redirected) {
|
|
121
|
+
const redirectUrl = response.url;
|
|
122
|
+
const originalHost = new URL(url).hostname;
|
|
123
|
+
const redirectHost = new URL(redirectUrl).hostname;
|
|
124
|
+
if (originalHost !== redirectHost) {
|
|
125
|
+
return {
|
|
126
|
+
content: `REDIRECT DETECTED: URL redirects to a different host.\nOriginal: ${url}\nRedirect: ${redirectUrl}\nPlease fetch the redirect URL instead.`,
|
|
127
|
+
code: 302,
|
|
128
|
+
contentType: 'text/plain',
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
const text = await response.text();
|
|
133
|
+
// Convert to markdown if HTML
|
|
134
|
+
let content = text;
|
|
135
|
+
if (contentType.includes('text/html')) {
|
|
136
|
+
content = htmlToMarkdown(text);
|
|
137
|
+
}
|
|
138
|
+
// Truncate if too large
|
|
139
|
+
if (content.length > MAX_MARKDOWN_LENGTH) {
|
|
140
|
+
content = content.slice(0, MAX_MARKDOWN_LENGTH) + '\n\n[... content truncated]';
|
|
141
|
+
}
|
|
142
|
+
const result = {
|
|
143
|
+
content,
|
|
144
|
+
code: response.status,
|
|
145
|
+
contentType,
|
|
146
|
+
};
|
|
147
|
+
if (response.ok)
|
|
148
|
+
cacheSet(url, result);
|
|
149
|
+
return result;
|
|
150
|
+
}
|
|
151
|
+
catch (err) {
|
|
152
|
+
return {
|
|
153
|
+
content: `Fetch error: ${err.message}`,
|
|
154
|
+
code: 0,
|
|
155
|
+
contentType: 'text/plain',
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
/** Clear the fetch cache (test helper / debugging) */
|
|
160
|
+
function clearWebFetchCache() {
|
|
161
|
+
fetchCache.clear();
|
|
162
|
+
}
|
|
163
|
+
/** Apply prompt to content using simple extraction */
|
|
164
|
+
function applyPromptToContent(content, prompt) {
|
|
165
|
+
// For simple prompts, return the content directly
|
|
166
|
+
const lowerPrompt = prompt.toLowerCase();
|
|
167
|
+
if (lowerPrompt.includes('title') || lowerPrompt.includes('name')) {
|
|
168
|
+
// Try to extract title
|
|
169
|
+
const titleMatch = content.match(/^#\s+(.+)$/m);
|
|
170
|
+
if (titleMatch) {
|
|
171
|
+
return `Title: ${titleMatch[1]}\n\n${content}`;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
if (lowerPrompt.includes('summary') || lowerPrompt.includes('summarize')) {
|
|
175
|
+
// Return first few paragraphs as summary
|
|
176
|
+
const paragraphs = content.split('\n\n').filter(p => p.length > 50);
|
|
177
|
+
const summary = paragraphs.slice(0, 3).join('\n\n');
|
|
178
|
+
return `Summary:\n${summary}\n\n---\n\nFull content:\n${content}`;
|
|
179
|
+
}
|
|
180
|
+
// Default: return content with prompt context
|
|
181
|
+
return `Prompt: "${prompt}"\n\nContent:\n${content}`;
|
|
182
|
+
}
|
|
183
|
+
exports.webFetchTool = (0, tool_1.buildTool)({
|
|
184
|
+
name: 'web_fetch',
|
|
185
|
+
description: `Fetch content from a URL and process with a prompt.
|
|
186
|
+
IMPORTANT: WebFetch WILL FAIL for authenticated or private URLs.
|
|
187
|
+
Before using this tool, check if the URL points to an authenticated service (e.g. Google Docs, Confluence, Jira, GitHub).`,
|
|
188
|
+
parameters: {
|
|
189
|
+
type: 'object',
|
|
190
|
+
properties: {
|
|
191
|
+
url: {
|
|
192
|
+
type: 'string',
|
|
193
|
+
description: 'The URL to fetch content from (must be a valid URL)',
|
|
194
|
+
},
|
|
195
|
+
prompt: {
|
|
196
|
+
type: 'string',
|
|
197
|
+
description: 'The prompt to run on the fetched content (e.g. "extract the title", "summarize the content")',
|
|
198
|
+
},
|
|
199
|
+
},
|
|
200
|
+
required: ['url', 'prompt'],
|
|
201
|
+
},
|
|
202
|
+
execute: async (args) => {
|
|
203
|
+
const url = args.url;
|
|
204
|
+
const prompt = args.prompt;
|
|
205
|
+
if (!url || typeof url !== 'string') {
|
|
206
|
+
return { success: false, output: '', error: 'web_fetch requires a url parameter' };
|
|
207
|
+
}
|
|
208
|
+
if (!prompt || typeof prompt !== 'string') {
|
|
209
|
+
return { success: false, output: '', error: 'web_fetch requires a prompt parameter' };
|
|
210
|
+
}
|
|
211
|
+
// Validate URL
|
|
212
|
+
try {
|
|
213
|
+
const parsed = new URL(url);
|
|
214
|
+
if (!parsed.protocol.startsWith('http')) {
|
|
215
|
+
return { success: false, output: '', error: 'URL must use http or https protocol' };
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
catch {
|
|
219
|
+
return { success: false, output: '', error: `Invalid URL: ${url}` };
|
|
220
|
+
}
|
|
221
|
+
const { content, code, contentType } = await fetchUrl(url);
|
|
222
|
+
if (code !== 200) {
|
|
223
|
+
return { success: false, output: content, error: `HTTP ${code}` };
|
|
224
|
+
}
|
|
225
|
+
const result = applyPromptToContent(content, prompt);
|
|
226
|
+
return {
|
|
227
|
+
success: true,
|
|
228
|
+
output: result,
|
|
229
|
+
};
|
|
230
|
+
},
|
|
231
|
+
isReadOnly: () => true,
|
|
232
|
+
isConcurrencySafe: () => true,
|
|
233
|
+
checkPermissions: (args) => {
|
|
234
|
+
const url = args.url;
|
|
235
|
+
try {
|
|
236
|
+
const parsed = new URL(url);
|
|
237
|
+
if (isPreapprovedHost(parsed.hostname, parsed.pathname)) {
|
|
238
|
+
return { behavior: 'allow', reason: 'Preapproved host' };
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
catch {
|
|
242
|
+
// Invalid URL - will fail in execute
|
|
243
|
+
}
|
|
244
|
+
return { behavior: 'ask', reason: 'Fetching external URL' };
|
|
245
|
+
},
|
|
246
|
+
userFacingName: (args) => {
|
|
247
|
+
try {
|
|
248
|
+
const url = new URL(args.url);
|
|
249
|
+
return `Fetch ${url.hostname}`;
|
|
250
|
+
}
|
|
251
|
+
catch {
|
|
252
|
+
return `Fetch ${args.url}`;
|
|
253
|
+
}
|
|
254
|
+
},
|
|
255
|
+
});
|
|
256
|
+
// ============================================================================
|
|
257
|
+
// WebSearch Tool
|
|
258
|
+
// ============================================================================
|
|
259
|
+
/** DuckDuckGo search (free, no API key required) */
|
|
260
|
+
async function duckDuckGoSearch(query, limit) {
|
|
261
|
+
try {
|
|
262
|
+
const searchUrl = `https://duckduckgo.com/html/?q=${encodeURIComponent(query)}`;
|
|
263
|
+
const response = await fetch(searchUrl, {
|
|
264
|
+
headers: {
|
|
265
|
+
'User-Agent': 'Mozilla/5.0 (compatible; OpenHorse/0.1.4)',
|
|
266
|
+
},
|
|
267
|
+
});
|
|
268
|
+
if (!response.ok) {
|
|
269
|
+
throw new Error(`Search failed: HTTP ${response.status}`);
|
|
270
|
+
}
|
|
271
|
+
const html = await response.text();
|
|
272
|
+
const results = [];
|
|
273
|
+
// Parse search results from HTML
|
|
274
|
+
const resultRegex = /<a[^>]*class="result__a"[^>]*href="([^"]*)"[^>]*>([^<]*)<\/a>/g;
|
|
275
|
+
let match;
|
|
276
|
+
let count = 0;
|
|
277
|
+
while ((match = resultRegex.exec(html)) !== null && count < limit) {
|
|
278
|
+
const url = match[1];
|
|
279
|
+
const title = match[2].trim();
|
|
280
|
+
// DuckDuckGo redirects through their URL - extract actual URL
|
|
281
|
+
let actualUrl = url;
|
|
282
|
+
const uddgMatch = url.match(/uddg=([^&]+)/);
|
|
283
|
+
if (uddgMatch) {
|
|
284
|
+
actualUrl = decodeURIComponent(uddgMatch[1]);
|
|
285
|
+
}
|
|
286
|
+
results.push({
|
|
287
|
+
title,
|
|
288
|
+
url: actualUrl,
|
|
289
|
+
description: '',
|
|
290
|
+
});
|
|
291
|
+
count++;
|
|
292
|
+
}
|
|
293
|
+
return results;
|
|
294
|
+
}
|
|
295
|
+
catch (err) {
|
|
296
|
+
throw new Error(`DuckDuckGo search error: ${err.message}`);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
/** Format search results */
|
|
300
|
+
function formatSearchResults(results, query) {
|
|
301
|
+
if (results.length === 0) {
|
|
302
|
+
return `No results found for query: "${query}"`;
|
|
303
|
+
}
|
|
304
|
+
const lines = [];
|
|
305
|
+
lines.push(`Search results for "${query}":`);
|
|
306
|
+
lines.push('');
|
|
307
|
+
for (let i = 0; i < results.length; i++) {
|
|
308
|
+
const r = results[i];
|
|
309
|
+
lines.push(`${i + 1}. **${r.title}**`);
|
|
310
|
+
lines.push(` URL: ${r.url}`);
|
|
311
|
+
if (r.description) {
|
|
312
|
+
lines.push(` ${r.description}`);
|
|
313
|
+
}
|
|
314
|
+
lines.push('');
|
|
315
|
+
}
|
|
316
|
+
lines.push('Sources:');
|
|
317
|
+
for (const r of results) {
|
|
318
|
+
lines.push(`- [${r.title}](${r.url})`);
|
|
319
|
+
}
|
|
320
|
+
return lines.join('\n');
|
|
321
|
+
}
|
|
322
|
+
exports.webSearchTool = (0, tool_1.buildTool)({
|
|
323
|
+
name: 'web_search',
|
|
324
|
+
description: `Search the web for information using DuckDuckGo.
|
|
325
|
+
Returns search results with titles, URLs, and descriptions.
|
|
326
|
+
You MUST include the Sources section with markdown hyperlinks in your response.`,
|
|
327
|
+
parameters: {
|
|
328
|
+
type: 'object',
|
|
329
|
+
properties: {
|
|
330
|
+
query: {
|
|
331
|
+
type: 'string',
|
|
332
|
+
description: 'The search query (minimum 2 characters)',
|
|
333
|
+
},
|
|
334
|
+
limit: {
|
|
335
|
+
type: 'number',
|
|
336
|
+
description: 'Maximum number of results (optional, default 5)',
|
|
337
|
+
},
|
|
338
|
+
},
|
|
339
|
+
required: ['query'],
|
|
340
|
+
},
|
|
341
|
+
execute: async (args) => {
|
|
342
|
+
const query = args.query;
|
|
343
|
+
const limit = args.limit || 5;
|
|
344
|
+
if (!query || typeof query !== 'string') {
|
|
345
|
+
return { success: false, output: '', error: 'web_search requires a query parameter' };
|
|
346
|
+
}
|
|
347
|
+
if (query.length < 2) {
|
|
348
|
+
return { success: false, output: '', error: 'Query must be at least 2 characters' };
|
|
349
|
+
}
|
|
350
|
+
try {
|
|
351
|
+
const results = await duckDuckGoSearch(query, limit);
|
|
352
|
+
const output = formatSearchResults(results, query);
|
|
353
|
+
return {
|
|
354
|
+
success: true,
|
|
355
|
+
output,
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
catch (err) {
|
|
359
|
+
return {
|
|
360
|
+
success: false,
|
|
361
|
+
output: '',
|
|
362
|
+
error: err.message,
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
},
|
|
366
|
+
isReadOnly: () => true,
|
|
367
|
+
isConcurrencySafe: () => true,
|
|
368
|
+
checkPermissions: () => {
|
|
369
|
+
return { behavior: 'ask', reason: 'Web search may query external services' };
|
|
370
|
+
},
|
|
371
|
+
userFacingName: (args) => `Search "${args.query?.slice(0, 30)}"`,
|
|
372
|
+
});
|
|
373
|
+
// ============================================================================
|
|
374
|
+
// Export
|
|
375
|
+
// ============================================================================
|
|
376
|
+
exports.WEB_TOOLS = [exports.webFetchTool, exports.webSearchTool];
|
|
377
|
+
//# sourceMappingURL=web.js.map
|