lonny-agent 0.2.6 → 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/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/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 +89 -26
- package/dist/agent/prompt-builder.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 +16 -3
- 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 +15 -17
- package/dist/agent/session.d.ts.map +1 -1
- package/dist/agent/session.js +226 -608
- 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/index.js +24 -3
- package/dist/index.js.map +1 -1
- package/dist/tools/__tests__/bash.test.js +168 -1
- package/dist/tools/__tests__/bash.test.js.map +1 -1
- package/dist/tools/__tests__/edit.test.js +253 -6
- 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 +1 -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__/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 +659 -39
- 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.map +1 -1
- package/dist/tools/edit.js +66 -1
- 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 +2 -0
- 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 -2
- package/dist/tools/registry.d.ts.map +1 -1
- package/dist/tools/registry.js +112 -17
- 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/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 +60 -122
- package/dist/web/index.js.map +1 -1
- package/dist/web/public/index.html +1 -1
- package/dist/web/public/messages.js +41 -25
- package/dist/web/public/state.js +72 -72
- package/dist/web/public/style.css +1126 -996
- package/dist/web/public/websocket.js +267 -267
- package/dist/web/session-bridge.d.ts.map +1 -1
- package/dist/web/session-bridge.js +82 -3
- package/dist/web/session-bridge.js.map +1 -1
- package/docs/ast-tools.md +117 -0
- package/package.json +60 -55
- package/scripts/check-line-count.mjs +53 -0
- package/scripts/copy-ast-wasm.mjs +32 -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 +30 -25
- package/src/agent/memory.ts +60 -0
- package/src/agent/prompt-builder.ts +100 -26
- package/src/agent/providers/anthropic.ts +179 -179
- package/src/agent/providers/google.ts +210 -210
- package/src/agent/providers/ollama.ts +186 -186
- package/src/agent/providers/openai.ts +18 -3
- 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 +261 -718
- package/src/cli/index.ts +73 -4
- package/src/config/index.ts +342 -342
- package/src/index.ts +30 -3
- package/src/tools/__tests__/bash.test.ts +187 -1
- package/src/tools/__tests__/edit.test.ts +275 -11
- 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 +1 -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} +4 -2
- 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 +119 -19
- 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 +335 -786
- package/src/tui/overlays.ts +203 -0
- package/src/tui/themes.ts +41 -0
- package/src/web/index.ts +64 -127
- package/src/web/public/index.html +1 -1
- package/src/web/public/messages.js +41 -25
- package/src/web/public/state.js +72 -72
- package/src/web/public/style.css +1126 -996
- package/src/web/public/websocket.js +267 -267
- package/src/web/session-bridge.ts +272 -193
- package/AGENT.md +0 -99
- package/src/tools/bash.ts +0 -125
- package/src/tools/edit.ts +0 -747
- package/src/tools/git.ts +0 -76
- package/src/tools/install_skill.ts +0 -539
- package/src/tui/components.ts +0 -635
|
@@ -1,193 +1,272 @@
|
|
|
1
|
-
import { EventChannels, getGlobalEventBus } from '../agent/event-bus.js'
|
|
2
|
-
import type { Session } from '../agent/session.js'
|
|
3
|
-
import type { Config } from '../config/index.js'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Bridge between Session/EventBus and WebSocket.
|
|
7
|
-
* Listens to EventBus events and forwards them as JSON messages.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
/** Strip ANSI escape codes from a string (terminal colors are meaningless in the browser) */
|
|
11
|
-
function stripAnsi(text: string): string {
|
|
12
|
-
return text.replace(/\x1b\[[0-9;]*m/g, '')
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export interface WsMessage {
|
|
16
|
-
type: string
|
|
17
|
-
[key: string]: unknown
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export type SendFn = (msg: WsMessage) => void
|
|
21
|
-
|
|
22
|
-
const WS_PROTOCOL_VERSION = 1
|
|
23
|
-
|
|
24
|
-
export function startSessionBridge(
|
|
25
|
-
session: Session,
|
|
26
|
-
config: Config,
|
|
27
|
-
send: SendFn,
|
|
28
|
-
): { close: () => void; sendMessage: (text: string) => Promise<void> } {
|
|
29
|
-
const bus = getGlobalEventBus()
|
|
30
|
-
|
|
31
|
-
// Send initial handshake with current token stats
|
|
32
|
-
send({
|
|
33
|
-
type: 'hello',
|
|
34
|
-
version: WS_PROTOCOL_VERSION,
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
send({
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
}
|
|
1
|
+
import { EventChannels, getGlobalEventBus } from '../agent/event-bus.js'
|
|
2
|
+
import type { Session } from '../agent/session.js'
|
|
3
|
+
import type { Config } from '../config/index.js'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Bridge between Session/EventBus and WebSocket.
|
|
7
|
+
* Listens to EventBus events and forwards them as JSON messages.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/** Strip ANSI escape codes from a string (terminal colors are meaningless in the browser) */
|
|
11
|
+
function stripAnsi(text: string): string {
|
|
12
|
+
return text.replace(/\x1b\[[0-9;]*m/g, '')
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface WsMessage {
|
|
16
|
+
type: string
|
|
17
|
+
[key: string]: unknown
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export type SendFn = (msg: WsMessage) => void
|
|
21
|
+
|
|
22
|
+
const WS_PROTOCOL_VERSION = 1
|
|
23
|
+
|
|
24
|
+
export function startSessionBridge(
|
|
25
|
+
session: Session,
|
|
26
|
+
config: Config,
|
|
27
|
+
send: SendFn,
|
|
28
|
+
): { close: () => void; sendMessage: (text: string) => Promise<void> } {
|
|
29
|
+
const bus = getGlobalEventBus()
|
|
30
|
+
|
|
31
|
+
// Send initial handshake with current token stats and session info
|
|
32
|
+
send({
|
|
33
|
+
type: 'hello',
|
|
34
|
+
version: WS_PROTOCOL_VERSION,
|
|
35
|
+
sessionId: session.sessionId,
|
|
36
|
+
sessionTitle: session.sessionTitle || undefined,
|
|
37
|
+
mode: config.mode,
|
|
38
|
+
model: config.model,
|
|
39
|
+
provider: config.provider,
|
|
40
|
+
totalIn: session.totalInputTokens,
|
|
41
|
+
totalOut: session.totalOutputTokens,
|
|
42
|
+
totalApi: session.totalApiCalls,
|
|
43
|
+
totalCacheHit: session.totalCacheHitTokens || undefined,
|
|
44
|
+
totalCacheMiss: session.totalCacheMissTokens || undefined,
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
// ── Subscribe to EventBus ──
|
|
48
|
+
|
|
49
|
+
const unsubTurnStart = bus.on(EventChannels.TURN_START, data => {
|
|
50
|
+
const d = data as { prompt?: string }
|
|
51
|
+
send({ type: 'turn_start', prompt: d.prompt || '' })
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
const unsubToolCall = bus.on(EventChannels.TOOL_CALL, data => {
|
|
55
|
+
const d = data as { name: string; input: Record<string, unknown>; id: string }
|
|
56
|
+
send({ type: 'tool_call', name: d.name, input: d.input, id: d.id })
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
const unsubToolResult = bus.on(EventChannels.TOOL_RESULT, data => {
|
|
60
|
+
const d = data as { name: string; id: string; output: string }
|
|
61
|
+
send({
|
|
62
|
+
type: 'tool_result',
|
|
63
|
+
name: d.name,
|
|
64
|
+
id: d.id,
|
|
65
|
+
success: true,
|
|
66
|
+
output: d.name === 'edit' ? d.output : stripAnsi(d.output),
|
|
67
|
+
})
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
const unsubToolError = bus.on(EventChannels.TOOL_ERROR, data => {
|
|
71
|
+
const d = data as { name: string; id: string; error: string }
|
|
72
|
+
send({ type: 'tool_result', name: d.name, id: d.id, success: false, error: stripAnsi(d.error) })
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
const unsubTurnEnd = bus.on(EventChannels.TURN_END, data => {
|
|
76
|
+
const d = data as { iterations: number; toolCallCount: number }
|
|
77
|
+
send({ type: 'turn_end', iterations: d.iterations, toolCallCount: d.toolCallCount })
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
const unsubThinking = bus.on(EventChannels.THINKING, data => {
|
|
81
|
+
const d = data as { text: string }
|
|
82
|
+
send({ type: 'thinking', text: d.text })
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
const unsubThinkingEnd = bus.on(EventChannels.THINKING_END, () => {
|
|
86
|
+
send({ type: 'thinking_end' })
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
const unsubCompaction = bus.on(EventChannels.COMPACTION_TRIGGERED, data => {
|
|
90
|
+
const d = data as { before: number; after: number }
|
|
91
|
+
send({ type: 'compaction', before: d.before, after: d.after })
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
const unsubTokenStats = bus.on(EventChannels.TOKEN_STATS, data => {
|
|
95
|
+
const d = data as {
|
|
96
|
+
turnIn: number
|
|
97
|
+
turnOut: number
|
|
98
|
+
totalIn: number
|
|
99
|
+
totalOut: number
|
|
100
|
+
turnApi: number
|
|
101
|
+
totalApi: number
|
|
102
|
+
turnCacheHit?: number
|
|
103
|
+
turnCacheMiss?: number
|
|
104
|
+
totalCacheHit?: number
|
|
105
|
+
totalCacheMiss?: number
|
|
106
|
+
}
|
|
107
|
+
send({ type: 'token_stats', ...d })
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
// ── Handle incoming messages from client ──
|
|
111
|
+
|
|
112
|
+
async function handleClientMessage(msg: WsMessage): Promise<void> {
|
|
113
|
+
switch (msg.type) {
|
|
114
|
+
case 'message': {
|
|
115
|
+
const text = String(msg.text || '')
|
|
116
|
+
if (!text.trim()) return
|
|
117
|
+
|
|
118
|
+
// Handle slash commands
|
|
119
|
+
if (text.startsWith('/')) {
|
|
120
|
+
const parts = text.slice(1).split(/\s+/)
|
|
121
|
+
const cmd = parts[0]
|
|
122
|
+
const arg = parts.slice(1).join(' ')
|
|
123
|
+
|
|
124
|
+
if (
|
|
125
|
+
cmd === 'mode' &&
|
|
126
|
+
(arg === 'code' || arg === 'plan' || arg === 'ask' || arg === 'loop')
|
|
127
|
+
) {
|
|
128
|
+
session.setMode(arg as 'code' | 'plan' | 'ask' | 'loop')
|
|
129
|
+
send({ type: 'mode_changed', mode: arg })
|
|
130
|
+
return
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (cmd === 'model' && arg) {
|
|
134
|
+
session.config.model = arg
|
|
135
|
+
session.setMode(session.config.mode)
|
|
136
|
+
send({ type: 'model_changed', model: arg })
|
|
137
|
+
return
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (cmd === 'help') {
|
|
141
|
+
send({
|
|
142
|
+
type: 'help',
|
|
143
|
+
commands: [
|
|
144
|
+
'/mode code|plan|ask|loop - Switch mode',
|
|
145
|
+
'/model <name> - Switch model',
|
|
146
|
+
'/sessions - List saved sessions',
|
|
147
|
+
'/session - Show current session info',
|
|
148
|
+
'/session title <name> - Name current session',
|
|
149
|
+
'/session delete <id> - Delete a session',
|
|
150
|
+
'/fork - Fork a new session from current context',
|
|
151
|
+
'/new - Start a new session',
|
|
152
|
+
'/help - Show this help',
|
|
153
|
+
],
|
|
154
|
+
})
|
|
155
|
+
return
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (cmd === 'sessions') {
|
|
159
|
+
const { Session } = await import('../agent/session.js')
|
|
160
|
+
const allSessions = Session.listSessions()
|
|
161
|
+
send({
|
|
162
|
+
type: 'sessions',
|
|
163
|
+
sessions: allSessions.map(s => ({
|
|
164
|
+
id: s.id,
|
|
165
|
+
cwd: s.cwd,
|
|
166
|
+
title: s.title,
|
|
167
|
+
messageCount: s.messageCount,
|
|
168
|
+
mode: s.mode,
|
|
169
|
+
model: s.model,
|
|
170
|
+
provider: s.provider,
|
|
171
|
+
totalInputTokens: s.totalInputTokens,
|
|
172
|
+
totalOutputTokens: s.totalOutputTokens,
|
|
173
|
+
totalApiCalls: s.totalApiCalls,
|
|
174
|
+
createdAt: s.createdAt,
|
|
175
|
+
updatedAt: s.updatedAt,
|
|
176
|
+
})),
|
|
177
|
+
})
|
|
178
|
+
return
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
if (cmd === 'session') {
|
|
182
|
+
if (arg === 'delete' || arg.startsWith('delete ')) {
|
|
183
|
+
const { Session } = await import('../agent/session.js')
|
|
184
|
+
const id = arg.slice(arg.startsWith('delete ') ? 7 : 6).trim()
|
|
185
|
+
const deleted = id ? Session.deleteSession(id) : false
|
|
186
|
+
send({ type: 'session_deleted', id, success: deleted })
|
|
187
|
+
} else if (arg.startsWith('title ')) {
|
|
188
|
+
const title = arg.slice(6).trim()
|
|
189
|
+
if (title) {
|
|
190
|
+
session.sessionTitle = title
|
|
191
|
+
session.save()
|
|
192
|
+
send({ type: 'session_titled', title })
|
|
193
|
+
} else {
|
|
194
|
+
send({ type: 'error', message: 'Usage: /session title <name>' })
|
|
195
|
+
}
|
|
196
|
+
} else if (arg === 'export') {
|
|
197
|
+
try {
|
|
198
|
+
const filePath = session.exportSession()
|
|
199
|
+
send({ type: 'session_exported', filePath })
|
|
200
|
+
} catch (err) {
|
|
201
|
+
send({ type: 'error', message: `Export failed: ${err}` })
|
|
202
|
+
}
|
|
203
|
+
} else {
|
|
204
|
+
send({
|
|
205
|
+
type: 'session_info',
|
|
206
|
+
id: session.sessionId,
|
|
207
|
+
title: session.sessionTitle || '(untitled)',
|
|
208
|
+
mode: session.config.mode,
|
|
209
|
+
model: session.config.model,
|
|
210
|
+
provider: session.config.provider,
|
|
211
|
+
messageCount: session.messages.length,
|
|
212
|
+
totalInputTokens: session.totalInputTokens,
|
|
213
|
+
totalOutputTokens: session.totalOutputTokens,
|
|
214
|
+
totalApiCalls: session.totalApiCalls,
|
|
215
|
+
createdAt: session.sessionCreatedAt,
|
|
216
|
+
})
|
|
217
|
+
}
|
|
218
|
+
return
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
if (cmd === 'fork') {
|
|
222
|
+
const forked = session.fork()
|
|
223
|
+
send({ type: 'session_forked', id: forked.sessionId, title: forked.sessionTitle })
|
|
224
|
+
return
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
send({ type: 'error', message: `Unknown command: ${cmd}` })
|
|
228
|
+
return
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// Send user message to session
|
|
232
|
+
try {
|
|
233
|
+
await session.chat(text)
|
|
234
|
+
send({ type: 'done', reason: 'stop' })
|
|
235
|
+
} catch (err) {
|
|
236
|
+
const errMsg = err instanceof Error ? err.message : String(err)
|
|
237
|
+
send({ type: 'error', message: errMsg })
|
|
238
|
+
send({ type: 'done', reason: 'error' })
|
|
239
|
+
}
|
|
240
|
+
return
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
case 'ping':
|
|
244
|
+
send({ type: 'pong' })
|
|
245
|
+
return
|
|
246
|
+
|
|
247
|
+
case 'stop':
|
|
248
|
+
session.stop()
|
|
249
|
+
return
|
|
250
|
+
|
|
251
|
+
default:
|
|
252
|
+
send({ type: 'error', message: `Unknown message type: ${msg.type}` })
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
return {
|
|
257
|
+
close: () => {
|
|
258
|
+
unsubTurnStart()
|
|
259
|
+
unsubToolCall()
|
|
260
|
+
unsubToolResult()
|
|
261
|
+
unsubToolError()
|
|
262
|
+
unsubTurnEnd()
|
|
263
|
+
unsubThinking()
|
|
264
|
+
unsubThinkingEnd()
|
|
265
|
+
unsubCompaction()
|
|
266
|
+
unsubTokenStats()
|
|
267
|
+
},
|
|
268
|
+
sendMessage: async (text: string) => {
|
|
269
|
+
await handleClientMessage({ type: 'message', text })
|
|
270
|
+
},
|
|
271
|
+
}
|
|
272
|
+
}
|
package/AGENT.md
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
# CLAUDE.md — lonny-agent
|
|
2
|
-
|
|
3
|
-
This file provides guidance to AI coding agents working with this repository.
|
|
4
|
-
|
|
5
|
-
## Project Overview
|
|
6
|
-
|
|
7
|
-
**lonny-agent** is a per-call-pricing-optimized AI coding assistant that runs in the terminal. It supports three modes (`code`, `plan`, `ask`), multiple LLM providers (Anthropic, OpenAI, Google, Ollama), and features a TUI built with `@earendil-works/pi-tui`.
|
|
8
|
-
|
|
9
|
-
### Key Architecture
|
|
10
|
-
|
|
11
|
-
```
|
|
12
|
-
src/
|
|
13
|
-
├── agent/ # Core agent loop, session management, LLM providers
|
|
14
|
-
│ ├── session.ts # Main session loop (message handling, tool dispatch)
|
|
15
|
-
│ ├── llm.ts # LLM provider interface
|
|
16
|
-
│ ├── event-bus.ts # Decoupled event system for TUI ↔ agent communication
|
|
17
|
-
│ ├── compaction.ts # Context compaction (message history summarization)
|
|
18
|
-
│ ├── prompt-builder.ts # System prompt construction
|
|
19
|
-
│ └── providers/ # Anthropic, OpenAI, Google, Ollama
|
|
20
|
-
├── cli/ # CLI argument parsing (commander)
|
|
21
|
-
├── config/ # Configuration loading (env, file, defaults)
|
|
22
|
-
├── diff/ # File read tracking and edit validation
|
|
23
|
-
├── tools/ # Tool implementations (read, edit, bash, glob, grep, etc.)
|
|
24
|
-
│ ├── registry.ts # ToolRegistry with plugin support
|
|
25
|
-
│ ├── exec.ts # JavaScript sandbox executor (inspired by Codex CLI)
|
|
26
|
-
│ └── types.ts # Tool interface definitions
|
|
27
|
-
├── tui/ # Terminal UI (landing page, chat display, status bar)
|
|
28
|
-
└── index.ts # Entry point
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
### Core Design Decisions
|
|
32
|
-
|
|
33
|
-
1. **Per-call cost optimization**: System prompt tells the model to batch operations into as few API calls as possible
|
|
34
|
-
2. **Three modes**: `code` (direct editing), `plan` (analysis + plan document), `ask` (Q&A only)
|
|
35
|
-
3. **Event bus decoupling**: TUI and agent communicate through an event bus, not direct method calls
|
|
36
|
-
4. **Exec sandbox**: JavaScript VM sandbox lets the model orchestrate multi-step operations in one API call
|
|
37
|
-
5. **File read tracking**: Prevents editing files that haven't been read or were modified externally
|
|
38
|
-
6. **Context compaction**: Summarizes older conversation turns when token budget is exceeded
|
|
39
|
-
|
|
40
|
-
## Git Commit Convention
|
|
41
|
-
|
|
42
|
-
Use **Conventional Commits**:
|
|
43
|
-
|
|
44
|
-
```
|
|
45
|
-
<type>: <description>
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
Types: `feat`, `fix`, `docs`, `chore`, `refactor`, `test`
|
|
49
|
-
|
|
50
|
-
Examples:
|
|
51
|
-
- `feat: add Tavily web search tool`
|
|
52
|
-
- `fix: handle CRLF line endings in edit tool`
|
|
53
|
-
- `chore: add Biome + husky code quality pipeline`
|
|
54
|
-
|
|
55
|
-
## Commands
|
|
56
|
-
|
|
57
|
-
```bash
|
|
58
|
-
npm install # Install dependencies
|
|
59
|
-
npm run dev # Dev mode (tsx watch)
|
|
60
|
-
npm run build # Build (tsc)
|
|
61
|
-
npm start # Run built version
|
|
62
|
-
npm test # Run tests (vitest)
|
|
63
|
-
npm test:watch # Watch mode tests
|
|
64
|
-
|
|
65
|
-
# Lint & Format (Biome)
|
|
66
|
-
npm run lint # Check only
|
|
67
|
-
npm run lint:fix # Auto-fix
|
|
68
|
-
npm run format # Format all
|
|
69
|
-
npm run check # Lint + format check
|
|
70
|
-
npm run check:fix # Lint + format auto-fix
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
## Code Quality
|
|
74
|
-
|
|
75
|
-
- **Formatter**: Biome (2-space indent, 100 line width, single quotes, as-needed semicolons)
|
|
76
|
-
- **Pre-commit**: husky + lint-staged (auto-fix staged files with Biome)
|
|
77
|
-
- **TypeScript**: strict mode, no unchecked index access
|
|
78
|
-
- **Testing**: vitest with `.test.ts` files co-located in `__tests__/` directories
|
|
79
|
-
|
|
80
|
-
## Architecture Notes
|
|
81
|
-
|
|
82
|
-
### Tool System
|
|
83
|
-
- `ToolRegistry` (registry.ts) manages tool registration and dispatch
|
|
84
|
-
- Tools implement `Tool` interface (definition + execute method)
|
|
85
|
-
- Plugin system allows external tool registration via `registerPlugin()`
|
|
86
|
-
- `exec` tool exposes all registered tools as `await tools.xxx(args)` in a sandboxed VM
|
|
87
|
-
|
|
88
|
-
### Session Flow
|
|
89
|
-
1. User sends message → `Session.chat()`
|
|
90
|
-
2. System prompt + message history + tool definitions → LLM provider
|
|
91
|
-
3. LLM streams response (text + tool calls)
|
|
92
|
-
4. Tool calls dispatched via `ToolRegistry.dispatch()`
|
|
93
|
-
5. Results appended to message history
|
|
94
|
-
6. Compaction triggered if token budget exceeded
|
|
95
|
-
|
|
96
|
-
### Testing
|
|
97
|
-
- Unit tests: `src/**/__tests__/*.test.ts`
|
|
98
|
-
- Mock strategy: mock only modules with side effects (network, filesystem)
|
|
99
|
-
- Avoid mocking pure functions or data modules
|