lonny-agent 0.2.4 → 0.2.7
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/.github/workflows/ci.yml +21 -0
- package/AGENTS.md +106 -0
- package/CHANGELOG.md +24 -0
- package/README.md +326 -326
- package/dist/agent/__tests__/session-restore.test.d.ts +2 -0
- package/dist/agent/__tests__/session-restore.test.d.ts.map +1 -0
- package/dist/agent/__tests__/session-restore.test.js +260 -0
- package/dist/agent/__tests__/session-restore.test.js.map +1 -0
- package/dist/agent/commands.d.ts +26 -0
- package/dist/agent/commands.d.ts.map +1 -0
- package/dist/agent/commands.js +253 -0
- package/dist/agent/commands.js.map +1 -0
- package/dist/agent/compaction.js +8 -1
- package/dist/agent/compaction.js.map +1 -1
- package/dist/agent/index.d.ts +2 -1
- package/dist/agent/index.d.ts.map +1 -1
- package/dist/agent/index.js +2 -2
- package/dist/agent/index.js.map +1 -1
- package/dist/agent/llm.d.ts +4 -0
- package/dist/agent/llm.d.ts.map +1 -1
- package/dist/agent/memory.d.ts +12 -0
- package/dist/agent/memory.d.ts.map +1 -0
- package/dist/agent/memory.js +51 -0
- package/dist/agent/memory.js.map +1 -0
- package/dist/agent/prompt-builder.d.ts +6 -1
- package/dist/agent/prompt-builder.d.ts.map +1 -1
- package/dist/agent/prompt-builder.js +100 -33
- package/dist/agent/prompt-builder.js.map +1 -1
- package/dist/agent/providers/google.d.ts.map +1 -1
- package/dist/agent/providers/google.js.map +1 -1
- package/dist/agent/providers/openai.d.ts +1 -0
- package/dist/agent/providers/openai.d.ts.map +1 -1
- package/dist/agent/providers/openai.js +59 -6
- package/dist/agent/providers/openai.js.map +1 -1
- package/dist/agent/session-chat.d.ts +3 -0
- package/dist/agent/session-chat.d.ts.map +1 -0
- package/dist/agent/session-chat.js +384 -0
- package/dist/agent/session-chat.js.map +1 -0
- package/dist/agent/session-display.d.ts +29 -0
- package/dist/agent/session-display.d.ts.map +1 -0
- package/dist/agent/session-display.js +179 -0
- package/dist/agent/session-display.js.map +1 -0
- package/dist/agent/session-persistence.d.ts +55 -0
- package/dist/agent/session-persistence.d.ts.map +1 -0
- package/dist/agent/session-persistence.js +101 -0
- package/dist/agent/session-persistence.js.map +1 -0
- package/dist/agent/session-utils.d.ts +5 -0
- package/dist/agent/session-utils.d.ts.map +1 -0
- package/dist/agent/session-utils.js +51 -0
- package/dist/agent/session-utils.js.map +1 -0
- package/dist/agent/session.d.ts +19 -17
- package/dist/agent/session.d.ts.map +1 -1
- package/dist/agent/session.js +234 -578
- package/dist/agent/session.js.map +1 -1
- package/dist/cli/index.d.ts +4 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +67 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/config/index.d.ts +2 -2
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +7 -1
- package/dist/config/index.js.map +1 -1
- package/dist/index.js +24 -3
- package/dist/index.js.map +1 -1
- package/dist/tools/__tests__/bash.test.js +169 -2
- package/dist/tools/__tests__/bash.test.js.map +1 -1
- package/dist/tools/__tests__/edit.test.js +1091 -340
- package/dist/tools/__tests__/edit.test.js.map +1 -1
- package/dist/tools/__tests__/fetch.test.js +1 -1
- package/dist/tools/__tests__/fetch.test.js.map +1 -1
- package/dist/tools/__tests__/glob.test.js +1 -1
- package/dist/tools/__tests__/glob.test.js.map +1 -1
- package/dist/tools/__tests__/grep.test.js +33 -1
- package/dist/tools/__tests__/grep.test.js.map +1 -1
- package/dist/tools/__tests__/ls.test.js +1 -1
- package/dist/tools/__tests__/ls.test.js.map +1 -1
- package/dist/tools/__tests__/read.test.js +1 -1
- package/dist/tools/__tests__/read.test.js.map +1 -1
- package/dist/tools/__tests__/registry.test.js +313 -0
- package/dist/tools/__tests__/registry.test.js.map +1 -1
- package/dist/tools/__tests__/sed.test.d.ts +2 -0
- package/dist/tools/__tests__/sed.test.d.ts.map +1 -0
- package/dist/tools/__tests__/sed.test.js +228 -0
- package/dist/tools/__tests__/sed.test.js.map +1 -0
- package/dist/tools/__tests__/write_plan.test.js +1 -1
- package/dist/tools/__tests__/write_plan.test.js.map +1 -1
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/bash.js +711 -18
- package/dist/tools/bash.js.map +1 -1
- package/dist/tools/codebase/ast/__tests__/ast-edit-demo.d.ts +2 -0
- package/dist/tools/codebase/ast/__tests__/ast-edit-demo.d.ts.map +1 -0
- package/dist/tools/codebase/ast/__tests__/ast-edit-demo.js +7 -0
- package/dist/tools/codebase/ast/__tests__/ast-edit-demo.js.map +1 -0
- package/dist/tools/codebase/ast/__tests__/ast-edit-final.d.ts +6 -0
- package/dist/tools/codebase/ast/__tests__/ast-edit-final.d.ts.map +1 -0
- package/dist/tools/codebase/ast/__tests__/ast-edit-final.js +11 -0
- package/dist/tools/codebase/ast/__tests__/ast-edit-final.js.map +1 -0
- package/dist/tools/codebase/ast/__tests__/ast-edit-test.d.ts +2 -0
- package/dist/tools/codebase/ast/__tests__/ast-edit-test.d.ts.map +1 -0
- package/dist/tools/codebase/ast/__tests__/ast-edit-test.js +9 -0
- package/dist/tools/codebase/ast/__tests__/ast-edit-test.js.map +1 -0
- package/dist/tools/codebase/ast/__tests__/integration.test.d.ts +2 -0
- package/dist/tools/codebase/ast/__tests__/integration.test.d.ts.map +1 -0
- package/dist/tools/codebase/ast/__tests__/integration.test.js +415 -0
- package/dist/tools/codebase/ast/__tests__/integration.test.js.map +1 -0
- package/dist/tools/codebase/ast/__tests__/tree-sitter.test.d.ts +2 -0
- package/dist/tools/codebase/ast/__tests__/tree-sitter.test.d.ts.map +1 -0
- package/dist/tools/codebase/ast/__tests__/tree-sitter.test.js +414 -0
- package/dist/tools/codebase/ast/__tests__/tree-sitter.test.js.map +1 -0
- package/dist/tools/codebase/ast/adapter.d.ts +23 -0
- package/dist/tools/codebase/ast/adapter.d.ts.map +1 -0
- package/dist/tools/codebase/ast/adapter.js +11 -0
- package/dist/tools/codebase/ast/adapter.js.map +1 -0
- package/dist/tools/codebase/ast/tools.d.ts +3 -0
- package/dist/tools/codebase/ast/tools.d.ts.map +1 -0
- package/dist/tools/codebase/ast/tools.js +286 -0
- package/dist/tools/codebase/ast/tools.js.map +1 -0
- package/dist/tools/codebase/ast/tree-sitter-adapter.d.ts +3 -0
- package/dist/tools/codebase/ast/tree-sitter-adapter.d.ts.map +1 -0
- package/dist/tools/codebase/ast/tree-sitter-adapter.js +412 -0
- package/dist/tools/codebase/ast/tree-sitter-adapter.js.map +1 -0
- package/dist/tools/codebase/ast/tree-sitter-converters.d.ts +4 -0
- package/dist/tools/codebase/ast/tree-sitter-converters.d.ts.map +1 -0
- package/dist/tools/codebase/ast/tree-sitter-converters.js +447 -0
- package/dist/tools/codebase/ast/tree-sitter-converters.js.map +1 -0
- package/dist/tools/codebase/ast/types.d.ts +103 -0
- package/dist/tools/codebase/ast/types.d.ts.map +1 -0
- package/dist/tools/codebase/ast/types.js +2 -0
- package/dist/tools/codebase/ast/types.js.map +1 -0
- package/dist/tools/codebase/ast/wasm/tree-sitter-python.wasm +0 -0
- package/dist/tools/codebase/ast/wasm/tree-sitter-tsx.wasm +0 -0
- package/dist/tools/codebase/ast/wasm/tree-sitter-typescript.wasm +0 -0
- package/dist/tools/codebase/ast/wasm/tree-sitter.wasm +0 -0
- package/dist/tools/codebase/ast/wasm/web-tree-sitter.wasm +0 -0
- package/dist/tools/codebase/find.d.ts +3 -0
- package/dist/tools/codebase/find.d.ts.map +1 -0
- package/dist/tools/codebase/find.js +61 -0
- package/dist/tools/codebase/find.js.map +1 -0
- package/dist/tools/codebase/glob.d.ts +3 -0
- package/dist/tools/codebase/glob.d.ts.map +1 -0
- package/dist/tools/codebase/glob.js +37 -0
- package/dist/tools/codebase/glob.js.map +1 -0
- package/dist/tools/codebase/grep.d.ts +3 -0
- package/dist/tools/codebase/grep.d.ts.map +1 -0
- package/dist/tools/codebase/grep.js +169 -0
- package/dist/tools/codebase/grep.js.map +1 -0
- package/dist/tools/codebase/ls.d.ts +3 -0
- package/dist/tools/codebase/ls.d.ts.map +1 -0
- package/dist/tools/codebase/ls.js +39 -0
- package/dist/tools/codebase/ls.js.map +1 -0
- package/dist/tools/codebase/read.d.ts +10 -0
- package/dist/tools/codebase/read.d.ts.map +1 -0
- package/dist/tools/codebase/read.js +81 -0
- package/dist/tools/codebase/read.js.map +1 -0
- package/dist/tools/delete_memory.d.ts +3 -0
- package/dist/tools/delete_memory.d.ts.map +1 -0
- package/dist/tools/delete_memory.js +46 -0
- package/dist/tools/delete_memory.js.map +1 -0
- package/dist/tools/edit/diff-compute.d.ts +4 -0
- package/dist/tools/edit/diff-compute.d.ts.map +1 -0
- package/dist/tools/edit/diff-compute.js +18 -0
- package/dist/tools/edit/diff-compute.js.map +1 -0
- package/dist/tools/edit/diff-render.d.ts +18 -0
- package/dist/tools/edit/diff-render.d.ts.map +1 -0
- package/dist/tools/edit/diff-render.js +128 -0
- package/dist/tools/edit/diff-render.js.map +1 -0
- package/dist/tools/edit/edit.d.ts +4 -0
- package/dist/tools/edit/edit.d.ts.map +1 -0
- package/dist/tools/edit/edit.js +440 -0
- package/dist/tools/edit/edit.js.map +1 -0
- package/dist/tools/edit/matcher.d.ts +24 -0
- package/dist/tools/edit/matcher.d.ts.map +1 -0
- package/dist/tools/edit/matcher.js +66 -0
- package/dist/tools/edit/matcher.js.map +1 -0
- package/dist/tools/edit/parser.d.ts +10 -0
- package/dist/tools/edit/parser.d.ts.map +1 -0
- package/dist/tools/edit/parser.js +120 -0
- package/dist/tools/edit/parser.js.map +1 -0
- package/dist/tools/edit/types.d.ts +16 -0
- package/dist/tools/edit/types.d.ts.map +1 -0
- package/dist/tools/edit/types.js +2 -0
- package/dist/tools/edit/types.js.map +1 -0
- package/dist/tools/edit/write_plan.d.ts +5 -0
- package/dist/tools/edit/write_plan.d.ts.map +1 -0
- package/dist/tools/edit/write_plan.js +98 -0
- package/dist/tools/edit/write_plan.js.map +1 -0
- package/dist/tools/edit.d.ts +50 -9
- package/dist/tools/edit.d.ts.map +1 -1
- package/dist/tools/edit.js +394 -159
- package/dist/tools/edit.js.map +1 -1
- package/dist/tools/execute/bash/constants.d.ts +24 -0
- package/dist/tools/execute/bash/constants.d.ts.map +1 -0
- package/dist/tools/execute/bash/constants.js +88 -0
- package/dist/tools/execute/bash/constants.js.map +1 -0
- package/dist/tools/execute/bash/errors.d.ts +39 -0
- package/dist/tools/execute/bash/errors.d.ts.map +1 -0
- package/dist/tools/execute/bash/errors.js +249 -0
- package/dist/tools/execute/bash/errors.js.map +1 -0
- package/dist/tools/execute/bash/execution.d.ts +18 -0
- package/dist/tools/execute/bash/execution.d.ts.map +1 -0
- package/dist/tools/execute/bash/execution.js +207 -0
- package/dist/tools/execute/bash/execution.js.map +1 -0
- package/dist/tools/execute/bash/index.d.ts +3 -0
- package/dist/tools/execute/bash/index.d.ts.map +1 -0
- package/dist/tools/execute/bash/index.js +117 -0
- package/dist/tools/execute/bash/index.js.map +1 -0
- package/dist/tools/execute/bash/platform.d.ts +6 -0
- package/dist/tools/execute/bash/platform.d.ts.map +1 -0
- package/dist/tools/execute/bash/platform.js +64 -0
- package/dist/tools/execute/bash/platform.js.map +1 -0
- package/dist/tools/execute/bash/security.d.ts +12 -0
- package/dist/tools/execute/bash/security.d.ts.map +1 -0
- package/dist/tools/execute/bash/security.js +26 -0
- package/dist/tools/execute/bash/security.js.map +1 -0
- package/dist/tools/execute/bash/validation.d.ts +16 -0
- package/dist/tools/execute/bash/validation.d.ts.map +1 -0
- package/dist/tools/execute/bash/validation.js +57 -0
- package/dist/tools/execute/bash/validation.js.map +1 -0
- package/dist/tools/execute/bash.d.ts +3 -0
- package/dist/tools/execute/bash.d.ts.map +1 -0
- package/dist/tools/execute/bash.js +728 -0
- package/dist/tools/execute/bash.js.map +1 -0
- package/dist/tools/execute/git.d.ts +3 -0
- package/dist/tools/execute/git.d.ts.map +1 -0
- package/dist/tools/execute/git.js +183 -0
- package/dist/tools/execute/git.js.map +1 -0
- package/dist/tools/execute/task_complete.d.ts +7 -0
- package/dist/tools/execute/task_complete.d.ts.map +1 -0
- package/dist/tools/execute/task_complete.js +38 -0
- package/dist/tools/execute/task_complete.js.map +1 -0
- package/dist/tools/fetch.d.ts.map +1 -1
- package/dist/tools/fetch.js +2 -0
- package/dist/tools/fetch.js.map +1 -1
- package/dist/tools/find.d.ts.map +1 -1
- package/dist/tools/find.js +2 -0
- package/dist/tools/find.js.map +1 -1
- package/dist/tools/git.d.ts.map +1 -1
- package/dist/tools/git.js +2 -0
- package/dist/tools/git.js.map +1 -1
- package/dist/tools/glob.d.ts.map +1 -1
- package/dist/tools/glob.js +2 -0
- package/dist/tools/glob.js.map +1 -1
- package/dist/tools/grep.d.ts.map +1 -1
- package/dist/tools/grep.js +56 -30
- package/dist/tools/grep.js.map +1 -1
- package/dist/tools/install/clawhub.d.ts +26 -0
- package/dist/tools/install/clawhub.d.ts.map +1 -0
- package/dist/tools/install/clawhub.js +182 -0
- package/dist/tools/install/clawhub.js.map +1 -0
- package/dist/tools/install/constants.d.ts +5 -0
- package/dist/tools/install/constants.d.ts.map +1 -0
- package/dist/tools/install/constants.js +5 -0
- package/dist/tools/install/constants.js.map +1 -0
- package/dist/tools/install/install_skill.d.ts +3 -0
- package/dist/tools/install/install_skill.d.ts.map +1 -0
- package/dist/tools/install/install_skill.js +132 -0
- package/dist/tools/install/install_skill.js.map +1 -0
- package/dist/tools/install/npm.d.ts +8 -0
- package/dist/tools/install/npm.d.ts.map +1 -0
- package/dist/tools/install/npm.js +52 -0
- package/dist/tools/install/npm.js.map +1 -0
- package/dist/tools/install/skill-content.d.ts +9 -0
- package/dist/tools/install/skill-content.d.ts.map +1 -0
- package/dist/tools/install/skill-content.js +89 -0
- package/dist/tools/install/skill-content.js.map +1 -0
- package/dist/tools/install_skill.d.ts.map +1 -1
- package/dist/tools/install_skill.js +2 -0
- package/dist/tools/install_skill.js.map +1 -1
- package/dist/tools/list_memory.d.ts +3 -0
- package/dist/tools/list_memory.d.ts.map +1 -0
- package/dist/tools/list_memory.js +55 -0
- package/dist/tools/list_memory.js.map +1 -0
- package/dist/tools/ls.d.ts.map +1 -1
- package/dist/tools/ls.js +2 -0
- package/dist/tools/ls.js.map +1 -1
- package/dist/tools/memory/delete_memory.d.ts +3 -0
- package/dist/tools/memory/delete_memory.d.ts.map +1 -0
- package/dist/tools/memory/delete_memory.js +46 -0
- package/dist/tools/memory/delete_memory.js.map +1 -0
- package/dist/tools/memory/list_memory.d.ts +3 -0
- package/dist/tools/memory/list_memory.d.ts.map +1 -0
- package/dist/tools/memory/list_memory.js +55 -0
- package/dist/tools/memory/list_memory.js.map +1 -0
- package/dist/tools/memory/save_memory.d.ts +3 -0
- package/dist/tools/memory/save_memory.d.ts.map +1 -0
- package/dist/tools/memory/save_memory.js +45 -0
- package/dist/tools/memory/save_memory.js.map +1 -0
- package/dist/tools/read.d.ts.map +1 -1
- package/dist/tools/read.js +2 -0
- package/dist/tools/read.js.map +1 -1
- package/dist/tools/registry.d.ts +7 -8
- package/dist/tools/registry.d.ts.map +1 -1
- package/dist/tools/registry.js +114 -46
- package/dist/tools/registry.js.map +1 -1
- package/dist/tools/save_memory.d.ts +3 -0
- package/dist/tools/save_memory.d.ts.map +1 -0
- package/dist/tools/save_memory.js +45 -0
- package/dist/tools/save_memory.js.map +1 -0
- package/dist/tools/search.d.ts.map +1 -1
- package/dist/tools/search.js +2 -0
- package/dist/tools/search.js.map +1 -1
- package/dist/tools/sed.d.ts +4 -0
- package/dist/tools/sed.d.ts.map +1 -0
- package/dist/tools/sed.js +121 -0
- package/dist/tools/sed.js.map +1 -0
- package/dist/tools/tree.d.ts +12 -0
- package/dist/tools/tree.d.ts.map +1 -0
- package/dist/tools/tree.js +87 -0
- package/dist/tools/tree.js.map +1 -0
- package/dist/tools/types.d.ts +12 -0
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/tools/web/fetch.d.ts +3 -0
- package/dist/tools/web/fetch.d.ts.map +1 -0
- package/dist/tools/web/fetch.js +49 -0
- package/dist/tools/web/fetch.js.map +1 -0
- package/dist/tools/web/search.d.ts +3 -0
- package/dist/tools/web/search.d.ts.map +1 -0
- package/dist/tools/web/search.js +134 -0
- package/dist/tools/web/search.js.map +1 -0
- package/dist/tools/write_plan.d.ts.map +1 -1
- package/dist/tools/write_plan.js +2 -0
- package/dist/tools/write_plan.js.map +1 -1
- package/dist/tui/commands.d.ts +4 -0
- package/dist/tui/commands.d.ts.map +1 -0
- package/dist/tui/commands.js +118 -0
- package/dist/tui/commands.js.map +1 -0
- package/dist/tui/components/colors.d.ts +36 -0
- package/dist/tui/components/colors.d.ts.map +1 -0
- package/dist/tui/components/colors.js +48 -0
- package/dist/tui/components/colors.js.map +1 -0
- package/dist/tui/components/header-bar.d.ts +26 -0
- package/dist/tui/components/header-bar.d.ts.map +1 -0
- package/dist/tui/components/header-bar.js +78 -0
- package/dist/tui/components/header-bar.js.map +1 -0
- package/dist/tui/components/index.d.ts +9 -0
- package/dist/tui/components/index.d.ts.map +1 -0
- package/dist/tui/components/index.js +9 -0
- package/dist/tui/components/index.js.map +1 -0
- package/dist/tui/components/landing-screen.d.ts +12 -0
- package/dist/tui/components/landing-screen.d.ts.map +1 -0
- package/dist/tui/components/landing-screen.js +53 -0
- package/dist/tui/components/landing-screen.js.map +1 -0
- package/dist/tui/components/pixel-logo.d.ts +5 -0
- package/dist/tui/components/pixel-logo.d.ts.map +1 -0
- package/dist/tui/components/pixel-logo.js +27 -0
- package/dist/tui/components/pixel-logo.js.map +1 -0
- package/dist/tui/components/plan-utils.d.ts +11 -0
- package/dist/tui/components/plan-utils.d.ts.map +1 -0
- package/dist/tui/components/plan-utils.js +62 -0
- package/dist/tui/components/plan-utils.js.map +1 -0
- package/dist/tui/components/plans-list.d.ts +18 -0
- package/dist/tui/components/plans-list.d.ts.map +1 -0
- package/dist/tui/components/plans-list.js +46 -0
- package/dist/tui/components/plans-list.js.map +1 -0
- package/dist/tui/components/rich-footer.d.ts +29 -0
- package/dist/tui/components/rich-footer.d.ts.map +1 -0
- package/dist/tui/components/rich-footer.js +124 -0
- package/dist/tui/components/rich-footer.js.map +1 -0
- package/dist/tui/components/todo-panel.d.ts +14 -0
- package/dist/tui/components/todo-panel.d.ts.map +1 -0
- package/dist/tui/components/todo-panel.js +83 -0
- package/dist/tui/components/todo-panel.js.map +1 -0
- package/dist/tui/components.d.ts.map +1 -1
- package/dist/tui/components.js +14 -7
- package/dist/tui/components.js.map +1 -1
- package/dist/tui/index.d.ts +2 -1
- package/dist/tui/index.d.ts.map +1 -1
- package/dist/tui/index.js +99 -505
- package/dist/tui/index.js.map +1 -1
- package/dist/tui/overlays.d.ts +28 -0
- package/dist/tui/overlays.d.ts.map +1 -0
- package/dist/tui/overlays.js +154 -0
- package/dist/tui/overlays.js.map +1 -0
- package/dist/tui/themes.d.ts +5 -0
- package/dist/tui/themes.d.ts.map +1 -0
- package/dist/tui/themes.js +38 -0
- package/dist/tui/themes.js.map +1 -0
- package/dist/web/index.d.ts.map +1 -1
- package/dist/web/index.js +62 -101
- package/dist/web/index.js.map +1 -1
- package/dist/web/public/app.js +5 -855
- package/dist/web/public/confirm.js +70 -0
- package/dist/web/public/index.html +121 -120
- package/dist/web/public/input.js +107 -0
- package/dist/web/public/messages.js +411 -0
- package/dist/web/public/sidebar.js +82 -0
- package/dist/web/public/state.js +72 -0
- package/dist/web/public/style.css +247 -70
- package/dist/web/public/utils.js +37 -0
- package/dist/web/public/websocket.js +267 -0
- package/dist/web/public/ws.js +19 -0
- package/dist/web/session-bridge.d.ts.map +1 -1
- package/dist/web/session-bridge.js +85 -10
- package/dist/web/session-bridge.js.map +1 -1
- package/docs/ast-tools.md +117 -0
- package/package.json +11 -5
- package/scripts/check-line-count.mjs +53 -0
- package/scripts/copy-ast-wasm.mjs +32 -0
- package/scripts/copy-native.mjs +24 -0
- package/scripts/copy-web.mjs +15 -0
- package/src/agent/__tests__/session-restore.test.ts +284 -0
- package/src/agent/commands.ts +274 -0
- package/src/agent/compaction.ts +9 -2
- package/src/agent/index.ts +7 -2
- package/src/agent/llm.ts +4 -0
- package/src/agent/memory.ts +60 -0
- package/src/agent/prompt-builder.ts +111 -33
- package/src/agent/providers/google.ts +0 -1
- package/src/agent/providers/openai.ts +79 -8
- package/src/agent/session-chat.ts +480 -0
- package/src/agent/session-display.ts +195 -0
- package/src/agent/session-persistence.ts +146 -0
- package/src/agent/session-utils.ts +54 -0
- package/src/agent/session.ts +269 -670
- package/src/cli/index.ts +73 -4
- package/src/config/index.ts +14 -7
- package/src/index.ts +30 -3
- package/src/tools/__tests__/bash.test.ts +188 -2
- package/src/tools/__tests__/edit.test.ts +1216 -356
- package/src/tools/__tests__/fetch.test.ts +1 -1
- package/src/tools/__tests__/glob.test.ts +1 -1
- package/src/tools/__tests__/grep.test.ts +36 -1
- package/src/tools/__tests__/ls.test.ts +1 -1
- package/src/tools/__tests__/read.test.ts +1 -1
- package/src/tools/__tests__/registry.test.ts +332 -0
- package/src/tools/__tests__/write_plan.test.ts +1 -1
- package/src/tools/codebase/ast/__tests__/integration.test.ts +452 -0
- package/src/tools/codebase/ast/__tests__/tree-sitter.test.ts +466 -0
- package/src/tools/codebase/ast/adapter.ts +44 -0
- package/src/tools/codebase/ast/tools.ts +322 -0
- package/src/tools/codebase/ast/tree-sitter-adapter.ts +468 -0
- package/src/tools/codebase/ast/tree-sitter-converters.ts +480 -0
- package/src/tools/codebase/ast/types.ts +102 -0
- package/src/tools/codebase/ast/wasm/tree-sitter-python.wasm +0 -0
- package/src/tools/codebase/ast/wasm/tree-sitter-tsx.wasm +0 -0
- package/src/tools/codebase/ast/wasm/tree-sitter-typescript.wasm +0 -0
- package/src/tools/codebase/ast/wasm/tree-sitter.wasm +0 -0
- package/src/tools/codebase/ast/wasm/web-tree-sitter.wasm +0 -0
- package/src/tools/{find.ts → codebase/find.ts} +4 -2
- package/src/tools/{glob.ts → codebase/glob.ts} +4 -2
- package/src/tools/{grep.ts → codebase/grep.ts} +61 -32
- package/src/tools/{ls.ts → codebase/ls.ts} +4 -2
- package/src/tools/{read.ts → codebase/read.ts} +5 -3
- package/src/tools/edit/diff-compute.ts +21 -0
- package/src/tools/edit/diff-render.ts +145 -0
- package/src/tools/edit/edit.ts +468 -0
- package/src/tools/edit/matcher.ts +70 -0
- package/src/tools/edit/parser.ts +131 -0
- package/src/tools/edit/types.ts +19 -0
- package/src/tools/{write_plan.ts → edit/write_plan.ts} +4 -2
- package/src/tools/execute/bash/constants.ts +93 -0
- package/src/tools/execute/bash/errors.ts +304 -0
- package/src/tools/execute/bash/execution.ts +211 -0
- package/src/tools/execute/bash/index.ts +131 -0
- package/src/tools/execute/bash/platform.ts +65 -0
- package/src/tools/execute/bash/security.ts +28 -0
- package/src/tools/execute/bash/validation.ts +78 -0
- package/src/tools/execute/git.ts +209 -0
- package/src/tools/execute/task_complete.ts +40 -0
- package/src/tools/install/clawhub.ts +222 -0
- package/src/tools/install/constants.ts +4 -0
- package/src/tools/install/install_skill.ts +150 -0
- package/src/tools/install/npm.ts +60 -0
- package/src/tools/install/skill-content.ts +108 -0
- package/src/tools/memory/delete_memory.ts +46 -0
- package/src/tools/memory/list_memory.ts +53 -0
- package/src/tools/memory/save_memory.ts +45 -0
- package/src/tools/registry.ts +121 -50
- package/src/tools/tree.ts +103 -0
- package/src/tools/types.ts +13 -0
- package/src/tools/{fetch.ts → web/fetch.ts} +4 -2
- package/src/tools/{search.ts → web/search.ts} +4 -2
- package/src/tui/commands.ts +135 -0
- package/src/tui/components/colors.ts +52 -0
- package/src/tui/components/header-bar.ts +88 -0
- package/src/tui/components/index.ts +8 -0
- package/src/tui/components/landing-screen.ts +67 -0
- package/src/tui/components/pixel-logo.ts +33 -0
- package/src/tui/components/plan-utils.ts +69 -0
- package/src/tui/components/plans-list.ts +55 -0
- package/src/tui/components/rich-footer.ts +146 -0
- package/src/tui/components/todo-panel.ts +95 -0
- package/src/tui/index.ts +110 -561
- package/src/tui/overlays.ts +203 -0
- package/src/tui/themes.ts +41 -0
- package/src/web/index.ts +66 -107
- package/src/web/public/app.js +5 -855
- package/src/web/public/confirm.js +70 -0
- package/src/web/public/index.html +121 -120
- package/src/web/public/input.js +107 -0
- package/src/web/public/messages.js +411 -0
- package/src/web/public/sidebar.js +82 -0
- package/src/web/public/state.js +72 -0
- package/src/web/public/style.css +247 -70
- package/src/web/public/utils.js +37 -0
- package/src/web/public/websocket.js +267 -0
- package/src/web/public/ws.js +19 -0
- package/src/web/session-bridge.ts +90 -12
- package/.claude/settings.local.json +0 -14
- package/.kilo/plans/1780064105789-mighty-pixel.md +0 -171
- package/.kilo/plans/1780293725888-quick-wizard.md +0 -62
- package/.lonny/plan-web-cwd-status.md +0 -38
- package/AGENT.md +0 -99
- package/src/tools/bash.ts +0 -39
- package/src/tools/edit.ts +0 -554
- package/src/tools/exec.ts +0 -348
- package/src/tools/git.ts +0 -76
- package/src/tools/install_skill.ts +0 -539
- package/src/tui/components.ts +0 -635
package/src/tools/registry.ts
CHANGED
|
@@ -1,23 +1,33 @@
|
|
|
1
1
|
import type { FileReadTracker } from '../diff/apply.js'
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { createAstTools } from './codebase/ast/tools.js'
|
|
3
|
+
import { createFindTool } from './codebase/find.js'
|
|
4
|
+
import { globTool } from './codebase/glob.js'
|
|
5
|
+
import { createGrepTool } from './codebase/grep.js'
|
|
6
|
+
import { createLsTool } from './codebase/ls.js'
|
|
7
|
+
import { createReadTool } from './codebase/read.js'
|
|
8
|
+
import { createEditTool } from './edit/edit.js'
|
|
9
|
+
import { createWritePlanTool } from './edit/write_plan.js'
|
|
4
10
|
import { fmtErr } from './errors.js'
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import { createLsTool } from './ls.js'
|
|
13
|
-
import { createReadTool } from './read.js'
|
|
14
|
-
import { searchTool } from './search.js'
|
|
11
|
+
import { bashTool } from './execute/bash/index.js'
|
|
12
|
+
import { createGitTool } from './execute/git.js'
|
|
13
|
+
import { taskCompleteTool } from './execute/task_complete.js'
|
|
14
|
+
import { createInstallSkillTool } from './install/install_skill.js'
|
|
15
|
+
import { createDeleteMemoryTool } from './memory/delete_memory.js'
|
|
16
|
+
import { createListMemoryTool } from './memory/list_memory.js'
|
|
17
|
+
import { createSaveMemoryTool } from './memory/save_memory.js'
|
|
15
18
|
import type { Tool, ToolCall, ToolDefinition, ToolResult } from './types.js'
|
|
16
|
-
import {
|
|
19
|
+
import { fetchTool } from './web/fetch.js'
|
|
20
|
+
import { searchTool } from './web/search.js'
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Tools in this set are passed directly to the LLM API's `tools` parameter.
|
|
24
|
+
* All other tools must be invoked via the `tool()` gateway.
|
|
25
|
+
*/
|
|
26
|
+
const CORE_TOOL_NAMES = new Set(['read', 'edit', 'bash', 'glob', 'grep', 'task_complete'])
|
|
17
27
|
|
|
18
28
|
/**
|
|
19
29
|
* Normalize tool input to prevent common LLM call misuses.
|
|
20
|
-
* The LLM sometimes passes parameters in the wrong format
|
|
30
|
+
* The LLM sometimes passes parameters in the wrong format �?this function
|
|
21
31
|
* auto-corrects those patterns so tools work reliably.
|
|
22
32
|
*
|
|
23
33
|
* Common misuses handled:
|
|
@@ -50,9 +60,6 @@ function normalizeToolInput(
|
|
|
50
60
|
if (toolName === 'write_plan') {
|
|
51
61
|
return { filename: input, content: input }
|
|
52
62
|
}
|
|
53
|
-
if (toolName === 'exec') {
|
|
54
|
-
return { code: input }
|
|
55
|
-
}
|
|
56
63
|
// For tools that take a single string param, guess from the definition
|
|
57
64
|
const params = Object.keys(_definition.parameters)
|
|
58
65
|
if (params.length === 1) {
|
|
@@ -79,7 +86,7 @@ export interface ToolContext {
|
|
|
79
86
|
cwd: string
|
|
80
87
|
autoApprove: boolean
|
|
81
88
|
applier: FileReadTracker
|
|
82
|
-
mode: 'code' | 'plan' | 'ask'
|
|
89
|
+
mode: 'code' | 'plan' | 'ask' | 'loop'
|
|
83
90
|
onPlanWritten?: (display: string) => void
|
|
84
91
|
}
|
|
85
92
|
|
|
@@ -97,17 +104,67 @@ export class ToolRegistry {
|
|
|
97
104
|
private tools: Map<string, Tool> = new Map()
|
|
98
105
|
private context: ToolContext
|
|
99
106
|
private plugins: Map<string, ToolPlugin> = new Map()
|
|
100
|
-
|
|
101
|
-
private execTool: Tool | null = null
|
|
107
|
+
private gatewayTool: Tool
|
|
102
108
|
|
|
103
109
|
constructor(context: ToolContext) {
|
|
104
110
|
this.context = context
|
|
111
|
+
this.gatewayTool = this.createGatewayTool()
|
|
105
112
|
this.registerBuiltins()
|
|
106
113
|
}
|
|
107
114
|
|
|
115
|
+
/** Create the `tool()` gateway that proxies calls to extended (non-core) tools */
|
|
116
|
+
private createGatewayTool(): Tool {
|
|
117
|
+
const dispatch = this.dispatch.bind(this)
|
|
118
|
+
return {
|
|
119
|
+
definition: {
|
|
120
|
+
name: 'tool',
|
|
121
|
+
description: `Invoke an extended tool. Use this for tools not in the direct-access core set.
|
|
122
|
+
|
|
123
|
+
The core tools are: read, edit, bash, glob, grep �?use them directly.
|
|
124
|
+
For everything else, call tool() with the tool name and its parameters.
|
|
125
|
+
|
|
126
|
+
Examples:
|
|
127
|
+
tool({ name: "git", params: { command: "status" } })
|
|
128
|
+
tool({ name: "ls", params: { path: "src" } })
|
|
129
|
+
tool({ name: "find", params: { pattern: "*.ts" } })
|
|
130
|
+
tool({ name: "fetch", params: { url: "https://example.com" } })`,
|
|
131
|
+
parameters: {
|
|
132
|
+
name: {
|
|
133
|
+
type: 'string',
|
|
134
|
+
description: 'The extended tool name to invoke',
|
|
135
|
+
required: true,
|
|
136
|
+
},
|
|
137
|
+
params: {
|
|
138
|
+
type: 'object',
|
|
139
|
+
description: 'Tool-specific parameters as a JSON object',
|
|
140
|
+
required: true,
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
async execute(input) {
|
|
145
|
+
const name = input.name as string | undefined
|
|
146
|
+
if (!name || typeof name !== 'string') {
|
|
147
|
+
return { success: false, output: '', error: 'tool() requires a "name" field (string)' }
|
|
148
|
+
}
|
|
149
|
+
if (name === 'tool') {
|
|
150
|
+
return { success: false, output: '', error: 'Cannot call tool() recursively' }
|
|
151
|
+
}
|
|
152
|
+
const call: ToolCall = {
|
|
153
|
+
id: `gateway-${Date.now()}`,
|
|
154
|
+
name,
|
|
155
|
+
input: (input.params || {}) as Record<string, unknown>,
|
|
156
|
+
}
|
|
157
|
+
return dispatch(call)
|
|
158
|
+
},
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
108
162
|
/** Register all built-in tools */
|
|
109
163
|
private registerBuiltins(): void {
|
|
110
|
-
//
|
|
164
|
+
// Register the gateway tool first so it's always available
|
|
165
|
+
this.register(this.gatewayTool)
|
|
166
|
+
|
|
167
|
+
// ask mode: only fetch and search
|
|
111
168
|
if (this.context.mode === 'ask') {
|
|
112
169
|
this.register(fetchTool)
|
|
113
170
|
this.register(searchTool)
|
|
@@ -122,56 +179,54 @@ export class ToolRegistry {
|
|
|
122
179
|
this.register(fetchTool)
|
|
123
180
|
this.register(searchTool)
|
|
124
181
|
|
|
125
|
-
if (this.context.mode === 'code') {
|
|
126
|
-
// Code mode: full toolset including write operations
|
|
182
|
+
if (this.context.mode === 'code' || this.context.mode === 'loop') {
|
|
183
|
+
// Code/Loop mode: full toolset including write operations
|
|
127
184
|
this.register(bashTool)
|
|
128
185
|
this.register(createGitTool(this.context.cwd))
|
|
129
186
|
this.register(createInstallSkillTool(this.context.cwd))
|
|
130
187
|
this.register(createEditTool(this.context.applier, this.context.cwd))
|
|
131
|
-
|
|
188
|
+
// Register save_memory tool (simple on-disk writer)
|
|
189
|
+
try {
|
|
190
|
+
this.register(createSaveMemoryTool(this.context.cwd))
|
|
191
|
+
this.register(createListMemoryTool(this.context.cwd))
|
|
192
|
+
this.register(createDeleteMemoryTool(this.context.cwd))
|
|
193
|
+
} catch (err) {
|
|
194
|
+
// If for some reason the tool can't be created, ignore — not critical
|
|
195
|
+
console.error('[ToolRegistry] Failed to register memory tools:', err)
|
|
196
|
+
}
|
|
197
|
+
// Register AST tools (ast_query, ast_edit)
|
|
198
|
+
for (const tool of createAstTools()) {
|
|
199
|
+
this.register(tool)
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// Register task_complete tool so the model can explicitly signal completion
|
|
203
|
+
// (most useful in loop mode, but available in code mode too)
|
|
204
|
+
this.register(taskCompleteTool)
|
|
132
205
|
} else {
|
|
133
206
|
// Plan mode: read-only investigation + write_plan
|
|
134
207
|
this.register(createWritePlanTool(this.context.cwd, this.context.onPlanWritten))
|
|
135
208
|
}
|
|
136
209
|
}
|
|
137
210
|
|
|
138
|
-
|
|
139
|
-
private registerExecTool(): void {
|
|
140
|
-
const execTool = createExecTool(() => Array.from(this.tools.values()))
|
|
141
|
-
this.execTool = execTool
|
|
142
|
-
this.register(execTool)
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/** Refresh the exec tool's description to include current tool type declarations */
|
|
146
|
-
private refreshExecDescription(): void {
|
|
147
|
-
if (this.execTool) {
|
|
148
|
-
updateExecToolDefinition(this.execTool, this.getDefinitions())
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
setMode(mode: 'code' | 'plan' | 'ask'): void {
|
|
211
|
+
setMode(mode: 'code' | 'plan' | 'ask' | 'loop'): void {
|
|
153
212
|
// Update context.mode FIRST so registerBuiltins() and mode-based logic
|
|
154
213
|
// use the NEW mode, not the stale one (fixes bug when switching from
|
|
155
214
|
// ask→code or plan→code where all tools would be missing)
|
|
156
215
|
this.context.mode = mode
|
|
157
216
|
|
|
158
|
-
if (mode === 'code') {
|
|
159
|
-
// Re-register all built-in tools for
|
|
217
|
+
if (mode === 'code' || mode === 'loop') {
|
|
218
|
+
// Code/Loop mode: Re-register all built-in tools for full toolset
|
|
160
219
|
this.tools.clear()
|
|
161
|
-
this.execTool = null
|
|
162
220
|
this.registerBuiltins()
|
|
163
221
|
} else if (mode === 'plan') {
|
|
164
|
-
// Keep existing tools but swap edit/write_plan
|
|
222
|
+
// Keep existing tools but swap edit/write_plan
|
|
165
223
|
if (!this.tools.has('write_plan')) {
|
|
166
224
|
this.register(createWritePlanTool(this.context.cwd, this.context.onPlanWritten))
|
|
167
225
|
}
|
|
168
226
|
this.tools.delete('edit')
|
|
169
|
-
this.tools.delete('exec')
|
|
170
|
-
this.execTool = null
|
|
171
227
|
} else if (mode === 'ask') {
|
|
172
228
|
// Ask mode: only fetch and search
|
|
173
229
|
this.tools.clear()
|
|
174
|
-
this.execTool = null
|
|
175
230
|
this.register(fetchTool)
|
|
176
231
|
this.register(searchTool)
|
|
177
232
|
}
|
|
@@ -180,10 +235,6 @@ export class ToolRegistry {
|
|
|
180
235
|
/** Register a single tool */
|
|
181
236
|
register(tool: Tool): void {
|
|
182
237
|
this.tools.set(tool.definition.name, tool)
|
|
183
|
-
// Refresh exec tool description to include the new tool's type declarations
|
|
184
|
-
if (this.execTool && tool.definition.name !== 'exec') {
|
|
185
|
-
this.refreshExecDescription()
|
|
186
|
-
}
|
|
187
238
|
}
|
|
188
239
|
|
|
189
240
|
/** Register a tool plugin (lazy creation pattern) */
|
|
@@ -228,6 +279,26 @@ export class ToolRegistry {
|
|
|
228
279
|
return Array.from(this.tools.values()).map(t => t.definition)
|
|
229
280
|
}
|
|
230
281
|
|
|
282
|
+
/** Get definitions for the core tool set + gateway (for LLM API's tools parameter) */
|
|
283
|
+
getCoreDefinitions(): ToolDefinition[] {
|
|
284
|
+
// Ask mode has only 2 tools �?pass them directly, no gateway needed
|
|
285
|
+
if (this.context.mode === 'ask') {
|
|
286
|
+
return Array.from(this.tools.values())
|
|
287
|
+
.filter(t => t.definition.name !== 'tool')
|
|
288
|
+
.map(t => t.definition)
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
const core: ToolDefinition[] = []
|
|
292
|
+
for (const [name, tool] of this.tools) {
|
|
293
|
+
if (CORE_TOOL_NAMES.has(name)) {
|
|
294
|
+
core.push(tool.definition)
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
// Always include the gateway tool so the model can reach extended tools
|
|
298
|
+
core.push(this.gatewayTool.definition)
|
|
299
|
+
return core
|
|
300
|
+
}
|
|
301
|
+
|
|
231
302
|
async dispatch(call: ToolCall): Promise<ToolResult> {
|
|
232
303
|
const tool = this.tools.get(call.name)
|
|
233
304
|
if (!tool) {
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import type { ToolDefinition, ToolTreeNode } from './types.js'
|
|
2
|
+
|
|
3
|
+
function normalizeLabel(value: string | undefined, fallback: string): string {
|
|
4
|
+
const trimmed = value?.trim()
|
|
5
|
+
return trimmed && trimmed !== 'Unclassified' ? trimmed : fallback
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
function createToolNode(def: ToolDefinition, depth: number): ToolTreeNode {
|
|
9
|
+
return {
|
|
10
|
+
type: 'tool',
|
|
11
|
+
name: def.name,
|
|
12
|
+
description: def.description,
|
|
13
|
+
toolName: def.name,
|
|
14
|
+
depth,
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function buildToolTree(definitions: ToolDefinition[]): ToolTreeNode[] {
|
|
19
|
+
const root: ToolTreeNode[] = []
|
|
20
|
+
const groups = new Map<string, ToolTreeNode>()
|
|
21
|
+
|
|
22
|
+
function getOrCreate(parts: string[], depth: number): ToolTreeNode {
|
|
23
|
+
const key = parts.join('/')
|
|
24
|
+
let node = groups.get(key)
|
|
25
|
+
if (!node) {
|
|
26
|
+
node = {
|
|
27
|
+
type: 'group',
|
|
28
|
+
name: parts[parts.length - 1] || 'Other',
|
|
29
|
+
children: [],
|
|
30
|
+
depth,
|
|
31
|
+
}
|
|
32
|
+
groups.set(key, node)
|
|
33
|
+
|
|
34
|
+
if (parts.length === 1) {
|
|
35
|
+
root.push(node)
|
|
36
|
+
} else {
|
|
37
|
+
const parent = groups.get(parts.slice(0, -1).join('/'))
|
|
38
|
+
parent?.children?.push(node)
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return node
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
for (const def of definitions) {
|
|
45
|
+
const category = normalizeLabel(def.category, 'Other')
|
|
46
|
+
const rawGroup = normalizeLabel(def.group, 'Unclassified')
|
|
47
|
+
|
|
48
|
+
// Build path: category first, then split group by '/' for multi-level nesting
|
|
49
|
+
const parts = [category]
|
|
50
|
+
if (rawGroup && rawGroup !== 'Unclassified') {
|
|
51
|
+
parts.push(
|
|
52
|
+
...rawGroup
|
|
53
|
+
.split('/')
|
|
54
|
+
.map(p => p.trim())
|
|
55
|
+
.filter(Boolean),
|
|
56
|
+
)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Create all intermediate group nodes (parents before children)
|
|
60
|
+
for (let i = 1; i <= parts.length; i++) {
|
|
61
|
+
const node = getOrCreate(parts.slice(0, i), i - 1)
|
|
62
|
+
if (i === parts.length) {
|
|
63
|
+
node.children?.push(createToolNode(def, i))
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return root
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Format the tool tree for inclusion in the system prompt.
|
|
73
|
+
*
|
|
74
|
+
* @param definitions - All tool definitions (for building the full tree)
|
|
75
|
+
* @param coreNames - Optional set of core tool names. When provided, tools NOT
|
|
76
|
+
* in this set are annotated with "(via tool)" to indicate they require the
|
|
77
|
+
* `tool()` gateway.
|
|
78
|
+
*/
|
|
79
|
+
export function formatToolTreeForPrompt(
|
|
80
|
+
definitions: ToolDefinition[],
|
|
81
|
+
coreNames?: Set<string>,
|
|
82
|
+
): string {
|
|
83
|
+
const lines: string[] = []
|
|
84
|
+
|
|
85
|
+
function render(node: ToolTreeNode, level: number): void {
|
|
86
|
+
const indent = ' '.repeat(level)
|
|
87
|
+
if (node.type === 'group') {
|
|
88
|
+
lines.push(`${indent}- ${node.name}`)
|
|
89
|
+
} else {
|
|
90
|
+
const suffix = coreNames && !coreNames.has(node.name) ? ' (via tool gateway)' : ''
|
|
91
|
+
lines.push(`${indent}- \`${node.name}\`: ${node.description || ''}${suffix}`)
|
|
92
|
+
}
|
|
93
|
+
for (const child of node.children || []) {
|
|
94
|
+
render(child, level + 1)
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
for (const node of buildToolTree(definitions)) {
|
|
99
|
+
render(node, 0)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return lines.join('\n')
|
|
103
|
+
}
|
package/src/tools/types.ts
CHANGED
|
@@ -9,6 +9,10 @@ export interface ToolDefinition {
|
|
|
9
9
|
name: string
|
|
10
10
|
description: string
|
|
11
11
|
parameters: Record<string, ToolParameter>
|
|
12
|
+
/** Top-level category used for hierarchical tool trees, e.g. "File I/O". */
|
|
13
|
+
category?: string
|
|
14
|
+
/** Second-level group used for hierarchical tool trees, e.g. "Read". */
|
|
15
|
+
group?: string
|
|
12
16
|
}
|
|
13
17
|
|
|
14
18
|
export interface ToolCall {
|
|
@@ -27,3 +31,12 @@ export interface Tool {
|
|
|
27
31
|
definition: ToolDefinition
|
|
28
32
|
execute(input: Record<string, unknown>): Promise<ToolResult>
|
|
29
33
|
}
|
|
34
|
+
|
|
35
|
+
export interface ToolTreeNode {
|
|
36
|
+
type: 'group' | 'tool'
|
|
37
|
+
name: string
|
|
38
|
+
description?: string
|
|
39
|
+
children?: ToolTreeNode[]
|
|
40
|
+
toolName?: string
|
|
41
|
+
depth: number
|
|
42
|
+
}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import { fmtErr } from '
|
|
2
|
-
import type { Tool, ToolResult } from '
|
|
1
|
+
import { fmtErr } from '../errors.js'
|
|
2
|
+
import type { Tool, ToolResult } from '../types.js'
|
|
3
3
|
|
|
4
4
|
export const fetchTool: Tool = {
|
|
5
5
|
definition: {
|
|
6
6
|
name: 'fetch',
|
|
7
|
+
category: 'Web',
|
|
8
|
+
group: 'Fetch',
|
|
7
9
|
description: 'Fetch content from a URL. Returns the response body as text.',
|
|
8
10
|
parameters: {
|
|
9
11
|
url: { type: 'string', description: 'URL to fetch', required: true },
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as fs from 'node:fs'
|
|
2
2
|
import * as os from 'node:os'
|
|
3
3
|
import * as path from 'node:path'
|
|
4
|
-
import { fmtErr } from '
|
|
5
|
-
import type { Tool, ToolResult } from '
|
|
4
|
+
import { fmtErr } from '../errors.js'
|
|
5
|
+
import type { Tool, ToolResult } from '../types.js'
|
|
6
6
|
|
|
7
7
|
interface TavilyConfig {
|
|
8
8
|
tavilyApiKey?: string
|
|
@@ -30,6 +30,8 @@ const TAVILY_API_URL = 'https://api.tavily.com/search'
|
|
|
30
30
|
export const searchTool: Tool = {
|
|
31
31
|
definition: {
|
|
32
32
|
name: 'search',
|
|
33
|
+
category: 'Web',
|
|
34
|
+
group: 'Search Engine',
|
|
33
35
|
description:
|
|
34
36
|
'Search the web using the Tavily search engine. Returns a summary answer and a list of relevant results with titles, URLs, and content snippets.',
|
|
35
37
|
parameters: {
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import type { CommandUI } from '../agent/commands.js'
|
|
2
|
+
import { dispatchCommand } from '../agent/commands.js'
|
|
3
|
+
import { fmtErr } from '../tools/errors.js'
|
|
4
|
+
import { colors } from './components/index.js'
|
|
5
|
+
import type { TuiContext } from './overlays.js'
|
|
6
|
+
import {
|
|
7
|
+
refreshBalance,
|
|
8
|
+
refreshPlans,
|
|
9
|
+
showHelpOverlay,
|
|
10
|
+
showPlansOverlay,
|
|
11
|
+
updateFooter,
|
|
12
|
+
} from './overlays.js'
|
|
13
|
+
|
|
14
|
+
export function handleConfirmInput(ctx: TuiContext, data: string): boolean {
|
|
15
|
+
if (!ctx.pendingConfirmResolve) return false
|
|
16
|
+
const key = data.trim().toLowerCase()
|
|
17
|
+
if (key === 'y' || key === 'yes') {
|
|
18
|
+
ctx.pendingConfirmResolve(true)
|
|
19
|
+
ctx.pendingConfirmResolve = null
|
|
20
|
+
ctx.chatContent += 'y\n'
|
|
21
|
+
ctx.chatMarkdown.setText(ctx.chatContent)
|
|
22
|
+
ctx.tui.requestRender(true)
|
|
23
|
+
return true
|
|
24
|
+
} else if (key === 'n' || key === 'no' || key === '\r' || key === '') {
|
|
25
|
+
ctx.pendingConfirmResolve(false)
|
|
26
|
+
ctx.pendingConfirmResolve = null
|
|
27
|
+
ctx.chatContent += 'N\n'
|
|
28
|
+
ctx.chatMarkdown.setText(ctx.chatContent)
|
|
29
|
+
ctx.tui.requestRender(true)
|
|
30
|
+
return true
|
|
31
|
+
}
|
|
32
|
+
return false
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function makeCommandUI(ctx: TuiContext): CommandUI {
|
|
36
|
+
return {
|
|
37
|
+
write: (text: string) => {
|
|
38
|
+
ctx.chatContent += '\n' + text + '\n'
|
|
39
|
+
ctx.chatMarkdown.setText(ctx.chatContent)
|
|
40
|
+
},
|
|
41
|
+
replaceContent: (text: string) => {
|
|
42
|
+
ctx.chatContent = text
|
|
43
|
+
ctx.chatMarkdown.setText(text)
|
|
44
|
+
},
|
|
45
|
+
onStateChange: () => {
|
|
46
|
+
updateFooter(ctx)
|
|
47
|
+
},
|
|
48
|
+
onNewSession: (session: any) => {
|
|
49
|
+
ctx.session = session
|
|
50
|
+
ctx.session.onPlanWritten = ctx.planCb
|
|
51
|
+
ctx.plansList.clearFilter()
|
|
52
|
+
;(ctx.editor as any).undoStack.clear()
|
|
53
|
+
;(ctx.editor as any).history = []
|
|
54
|
+
;(ctx.editor as any).killRing.ring = []
|
|
55
|
+
},
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export async function sendMessage(ctx: TuiContext, text: string): Promise<void> {
|
|
60
|
+
const trimmed = text.trim()
|
|
61
|
+
if (!trimmed) return
|
|
62
|
+
ctx.editor.setText('')
|
|
63
|
+
ctx.editor.addToHistory(trimmed)
|
|
64
|
+
|
|
65
|
+
if (trimmed.startsWith('/')) {
|
|
66
|
+
const parts = trimmed.slice(1).split(/\s+/)
|
|
67
|
+
const cmd = parts[0]
|
|
68
|
+
const arg = parts.slice(1).join(' ')
|
|
69
|
+
|
|
70
|
+
// TUI-specific commands
|
|
71
|
+
if (cmd === 'exit' || cmd === 'quit') {
|
|
72
|
+
ctx.chatContent += `\n${colors.dim('Goodbye!')}\n`
|
|
73
|
+
ctx.chatMarkdown.setText(ctx.chatContent)
|
|
74
|
+
ctx.tui.stop()
|
|
75
|
+
process.exit(0)
|
|
76
|
+
return
|
|
77
|
+
}
|
|
78
|
+
if (cmd === 'plans') {
|
|
79
|
+
showPlansOverlay(ctx)
|
|
80
|
+
return
|
|
81
|
+
}
|
|
82
|
+
if (cmd === 'filter') {
|
|
83
|
+
ctx.plansList.setFilter(arg)
|
|
84
|
+
ctx.tui.requestRender(true)
|
|
85
|
+
return
|
|
86
|
+
}
|
|
87
|
+
if (cmd === 'help' || cmd === '?') {
|
|
88
|
+
showHelpOverlay(ctx)
|
|
89
|
+
return
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Shared commands
|
|
93
|
+
const ui = makeCommandUI(ctx)
|
|
94
|
+
const handled = await dispatchCommand(
|
|
95
|
+
{ session: ctx.session, config: ctx.config, ui, isRunning: ctx.isRunning },
|
|
96
|
+
cmd,
|
|
97
|
+
arg,
|
|
98
|
+
)
|
|
99
|
+
if (handled) {
|
|
100
|
+
ctx.tui.requestRender(true)
|
|
101
|
+
return
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
ctx.chatContent += `\n${colors.error('\u2716')} Unknown command: /${cmd}. ${colors.dim('Type /help for available commands.')}\n`
|
|
105
|
+
ctx.chatMarkdown.setText(ctx.chatContent)
|
|
106
|
+
return
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (ctx.isRunning) return
|
|
110
|
+
|
|
111
|
+
ctx.isRunning = true
|
|
112
|
+
ctx.loader.setMessage('thinking...')
|
|
113
|
+
ctx.tui.setShowHardwareCursor(false)
|
|
114
|
+
updateFooter(ctx)
|
|
115
|
+
|
|
116
|
+
ctx.session
|
|
117
|
+
.chat(trimmed)
|
|
118
|
+
.then(() => {
|
|
119
|
+
ctx.isRunning = false
|
|
120
|
+
ctx.loader.setMessage('')
|
|
121
|
+
refreshPlans(ctx)
|
|
122
|
+
ctx.tui.setShowHardwareCursor(true)
|
|
123
|
+
updateFooter(ctx)
|
|
124
|
+
refreshBalance(ctx)
|
|
125
|
+
})
|
|
126
|
+
.catch((err: unknown) => {
|
|
127
|
+
ctx.isRunning = false
|
|
128
|
+
ctx.loader.setMessage('')
|
|
129
|
+
const errMsg = fmtErr(err)
|
|
130
|
+
ctx.chatContent += `\n${colors.error('\u2716 Error:')} ${errMsg}\n`
|
|
131
|
+
ctx.chatMarkdown.setText(ctx.chatContent)
|
|
132
|
+
ctx.tui.setShowHardwareCursor(true)
|
|
133
|
+
updateFooter(ctx)
|
|
134
|
+
})
|
|
135
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import * as fs from 'node:fs'
|
|
2
|
+
|
|
3
|
+
function safeBg(text: string, bg: string): string {
|
|
4
|
+
return `\x1b[${bg}m${text.replace(/\x1b\[0m/g, `\x1b[0m\x1b[${bg}m`)}\x1b[0m`
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export { safeBg }
|
|
8
|
+
|
|
9
|
+
export const colors = {
|
|
10
|
+
bgDark: (text: string) => safeBg(text, '48;2;30;30;30'),
|
|
11
|
+
bgDim: (text: string) => safeBg(text, '48;2;25;25;25'),
|
|
12
|
+
headerBg: (text: string) => safeBg(text, '48;2;170;170;170'),
|
|
13
|
+
separator: (text: string) => `\x1b[38;2;60;60;60m${text}\x1b[0m`,
|
|
14
|
+
statusBg: (text: string) => safeBg(text, '48;2;25;25;35'),
|
|
15
|
+
running: (text: string) => `\x1b[38;2;0;255;100m${text}\x1b[0m`,
|
|
16
|
+
idle: (text: string) => `\x1b[38;2;150;150;150m${text}\x1b[0m`,
|
|
17
|
+
doneTodo: (text: string) => `\x1b[38;2;100;200;100m${text}\x1b[0m`,
|
|
18
|
+
todo: (text: string) => `\x1b[38;2;150;150;150m${text}\x1b[0m`,
|
|
19
|
+
accent: (text: string) => `\x1b[38;2;0;170;255m${text}\x1b[0m`,
|
|
20
|
+
dim: (text: string) => `\x1b[38;2;90;90;90m${text}\x1b[0m`,
|
|
21
|
+
userLabel: (text: string) => `\x1b[38;2;255;200;50m${text}\x1b[0m`,
|
|
22
|
+
assistantLabel: (text: string) => `\x1b[38;2;0;255;150m${text}\x1b[0m`,
|
|
23
|
+
error: (text: string) => `\x1b[38;2;255;80;80m${text}\x1b[0m`,
|
|
24
|
+
success: (text: string) => `\x1b[38;2;0;200;100m${text}\x1b[0m`,
|
|
25
|
+
inputPrompt: (text: string) => `\x1b[38;2;0;170;255m${text}\x1b[0m`,
|
|
26
|
+
warn: (text: string) => `\x1b[38;2;255;200;50m${text}\x1b[0m`,
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const APP_VERSION: string = (() => {
|
|
30
|
+
try {
|
|
31
|
+
const pkgPath = new URL('../../package.json', import.meta.url)
|
|
32
|
+
const raw = fs.readFileSync(pkgPath, 'utf-8')
|
|
33
|
+
return JSON.parse(raw).version || '0.1.0'
|
|
34
|
+
} catch {
|
|
35
|
+
return '0.1.0'
|
|
36
|
+
}
|
|
37
|
+
})()
|
|
38
|
+
|
|
39
|
+
export { APP_VERSION }
|
|
40
|
+
|
|
41
|
+
export const landingColors = {
|
|
42
|
+
inputBg: '\x1b[48;2;35;35;35m',
|
|
43
|
+
inputBorder: '\x1b[38;2;60;60;60m',
|
|
44
|
+
cyanBar: '\x1b[38;2;0;200;255m',
|
|
45
|
+
placeholderDim: '\x1b[38;2;130;130;130m',
|
|
46
|
+
placeholderQuote: '\x1b[38;2;160;160;160m',
|
|
47
|
+
inputText: '\x1b[38;2;220;220;220m',
|
|
48
|
+
statusBg: '\x1b[48;2;18;18;18m',
|
|
49
|
+
statusText: '\x1b[38;2;110;110;110m',
|
|
50
|
+
statusAccent: '\x1b[38;2;0;170;255m',
|
|
51
|
+
reset: '\x1b[0m',
|
|
52
|
+
}
|