@tyvm/knowhow 0.0.47 → 0.0.48
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/benchmarks/results/27b0a06/2025-09-27/xai/xai-grok-code-fast-1.json +2909 -0
- package/benchmarks/results/4057aed/2025-08-14/anthropic/anthropic-claude-sonnet-4-20250514.json +1671 -0
- package/jest.config.js +2 -2
- package/package.json +8 -3
- package/src/agents/base/base.ts +30 -24
- package/src/agents/patcher/patcher.ts +26 -5
- package/src/agents/tools/agentCall.ts +4 -2
- package/src/agents/tools/aiClient.ts +3 -11
- package/src/agents/tools/ast/astAppendNode.ts +90 -0
- package/src/agents/tools/ast/astDeleteNode.ts +88 -0
- package/src/agents/tools/ast/astEditNode.ts +95 -0
- package/src/agents/tools/ast/astGetPathForLine.ts +73 -0
- package/src/agents/tools/ast/astListPaths.ts +66 -0
- package/src/agents/tools/ast/index.ts +7 -0
- package/src/agents/tools/callPlugin.ts +8 -2
- package/src/agents/tools/embeddingSearch.ts +2 -1
- package/src/agents/tools/execCommand.ts +239 -94
- package/src/agents/tools/fileSearch.ts +15 -17
- package/src/agents/tools/index.ts +1 -0
- package/src/agents/tools/language/definitions.ts +10 -2
- package/src/agents/tools/language/index.ts +3 -2
- package/src/agents/tools/lintFile.ts +4 -2
- package/src/agents/tools/list.ts +203 -62
- package/src/agents/tools/patch.ts +48 -14
- package/src/agents/tools/readBlocks.ts +34 -0
- package/src/agents/tools/readFile.ts +23 -0
- package/src/agents/tools/stringReplace.ts +33 -9
- package/src/agents/tools/writeFile.ts +55 -0
- package/src/agents/tools/ycmd/server.ts +14 -4
- package/src/chat/CliChatService.ts +6 -1
- package/src/chat/modules/AgentModule.ts +107 -64
- package/src/chat/modules/AskModule.ts +0 -1
- package/src/chat/modules/SetupModule.ts +4 -4
- package/src/chat/modules/SystemModule.ts +28 -5
- package/src/chat/types.ts +2 -0
- package/src/chat-old.ts +2 -2
- package/src/clients/anthropic.ts +22 -1
- package/src/clients/openai.ts +1 -1
- package/src/clients/xai.ts +15 -5
- package/src/config.ts +17 -5
- package/src/dataset/diffs/generate.ts +2 -2
- package/src/dataset/diffs/jsonl.ts +0 -1
- package/src/embeddings.ts +6 -4
- package/src/index.ts +11 -5
- package/src/plugins/GitPlugin.ts +530 -0
- package/src/plugins/LinterPlugin.ts +89 -0
- package/src/plugins/PluginBase.ts +4 -2
- package/src/plugins/asana.ts +4 -2
- package/src/plugins/downloader/plugin.ts +5 -2
- package/src/plugins/embedding.ts +24 -4
- package/src/plugins/figma.ts +7 -3
- package/src/plugins/github.ts +4 -2
- package/src/plugins/jira.ts +4 -2
- package/src/plugins/language.ts +134 -27
- package/src/plugins/linear.ts +4 -2
- package/src/plugins/notion.ts +4 -2
- package/src/plugins/plugins.ts +27 -16
- package/src/plugins/tree-sitter/editor.ts +369 -0
- package/src/plugins/tree-sitter/lang-packs/index.ts +23 -0
- package/src/plugins/tree-sitter/lang-packs/java.ts +59 -0
- package/src/plugins/tree-sitter/lang-packs/javascript.ts +57 -0
- package/src/plugins/tree-sitter/lang-packs/python.ts +45 -0
- package/src/plugins/tree-sitter/lang-packs/types.ts +79 -0
- package/src/plugins/tree-sitter/lang-packs/typescript.ts +49 -0
- package/src/plugins/tree-sitter/parser.ts +444 -0
- package/src/plugins/tree-sitter/simple-paths.ts +467 -0
- package/src/plugins/types.ts +11 -0
- package/src/plugins/url.ts +5 -3
- package/src/plugins/vim.ts +8 -5
- package/src/processors/CustomVariables.ts +19 -7
- package/src/processors/TokenCompressor.ts +13 -13
- package/src/processors/ToolResponseCache.ts +15 -6
- package/src/services/EmbeddingService.ts +18 -9
- package/src/services/EventService.ts +80 -0
- package/src/services/Mcp.ts +5 -0
- package/src/services/S3.ts +4 -3
- package/src/services/Tools.ts +125 -53
- package/src/services/index.ts +16 -11
- package/src/services/types.ts +3 -3
- package/src/types.ts +7 -2
- package/src/worker.ts +14 -1
- package/test-comprehensive.ts +31 -0
- package/tests/clients/AIClient.test.ts +490 -0
- package/tests/manual/agent-events/run-test.ts +203 -0
- package/tests/{integration → manual/file-edits}/figma.test.ts +1 -1
- package/tests/{integration → manual/file-edits}/fileblocks/readwrite.test.ts +7 -3
- package/tests/{integration → manual/file-edits}/patching.test.ts +11 -8
- package/tests/plugins/language/languagePlugin-content-triggers.test.ts +332 -0
- package/tests/plugins/language/languagePlugin-integration.test.ts +456 -0
- package/tests/plugins/language/languagePlugin.test.ts +363 -0
- package/tests/processors/Base64ImageDetector.test.ts +403 -0
- package/tests/processors/CustomVariables.test.ts +430 -0
- package/tests/processors/HarmonyToolProcessor.test.ts +490 -0
- package/tests/processors/TokenCompressor.test.ts +391 -0
- package/tests/processors/ToolResponseCache.test.ts +688 -0
- package/tests/services/Tools.test.ts +1339 -0
- package/tests/test.spec.ts +162 -117
- package/tests/tree-sitter/editor.test.ts +113 -0
- package/tests/tree-sitter/invalid.test.ts +299 -0
- package/tests/tree-sitter/paths/common-edits.test.ts +564 -0
- package/tests/tree-sitter/paths/debug-exact-position.test.ts +44 -0
- package/tests/tree-sitter/paths/debug-line-indexing.test.ts +49 -0
- package/tests/tree-sitter/paths/debug-paths.test.ts +90 -0
- package/tests/tree-sitter/paths/paths.test.ts +170 -0
- package/tests/tree-sitter/paths/simple-paths.test.ts +367 -0
- package/tests/tree-sitter/sample-after.ts +48 -0
- package/tests/tree-sitter/sample-before.ts +25 -0
- package/tests/tree-sitter/test-files/completely-broken.ts +7 -0
- package/tests/tree-sitter/test-files/duplicate-braces.ts +39 -0
- package/tests/tree-sitter/test-files/invalid-nesting.ts +39 -0
- package/tests/tree-sitter/test-files/malformed-signature.ts +39 -0
- package/tests/tree-sitter/test-files/mismatched-parens.ts +39 -0
- package/tests/tree-sitter/test-files/missing-semicolon.ts +39 -0
- package/tests/tree-sitter/test-files/partially-broken.ts +20 -0
- package/tests/tree-sitter/test-files/specific-errors.ts +14 -0
- package/tests/tree-sitter/test-files/unclosed-string.ts +39 -0
- package/tests/tree-sitter/tree-sitter.test.ts +251 -0
- package/ts_build/package.json +8 -3
- package/ts_build/src/agents/base/base.d.ts +2 -2
- package/ts_build/src/agents/base/base.js +24 -20
- package/ts_build/src/agents/base/base.js.map +1 -1
- package/ts_build/src/agents/patcher/patcher.js +26 -5
- package/ts_build/src/agents/patcher/patcher.js.map +1 -1
- package/ts_build/src/agents/tools/agentCall.js +2 -1
- package/ts_build/src/agents/tools/agentCall.js.map +1 -1
- package/ts_build/src/agents/tools/aiClient.d.ts +7 -8
- package/ts_build/src/agents/tools/aiClient.js.map +1 -1
- package/ts_build/src/agents/tools/ast/astAppendNode.d.ts +1 -0
- package/ts_build/src/agents/tools/ast/astAppendNode.js +96 -0
- package/ts_build/src/agents/tools/ast/astAppendNode.js.map +1 -0
- package/ts_build/src/agents/tools/ast/astDeleteNode.d.ts +1 -0
- package/ts_build/src/agents/tools/ast/astDeleteNode.js +94 -0
- package/ts_build/src/agents/tools/ast/astDeleteNode.js.map +1 -0
- package/ts_build/src/agents/tools/ast/astEditNode.d.ts +1 -0
- package/ts_build/src/agents/tools/ast/astEditNode.js +96 -0
- package/ts_build/src/agents/tools/ast/astEditNode.js.map +1 -0
- package/ts_build/src/agents/tools/ast/astGetPathForLine.d.ts +1 -0
- package/ts_build/src/agents/tools/ast/astGetPathForLine.js +78 -0
- package/ts_build/src/agents/tools/ast/astGetPathForLine.js.map +1 -0
- package/ts_build/src/agents/tools/ast/astListPaths.d.ts +1 -0
- package/ts_build/src/agents/tools/ast/astListPaths.js +78 -0
- package/ts_build/src/agents/tools/ast/astListPaths.js.map +1 -0
- package/ts_build/src/agents/tools/ast/index.d.ts +5 -0
- package/ts_build/src/agents/tools/ast/index.js +14 -0
- package/ts_build/src/agents/tools/ast/index.js.map +1 -0
- package/ts_build/src/agents/tools/astAppendNode.d.ts +1 -0
- package/ts_build/src/agents/tools/astAppendNode.js +98 -0
- package/ts_build/src/agents/tools/astAppendNode.js.map +1 -0
- package/ts_build/src/agents/tools/astDeleteNode.d.ts +1 -0
- package/ts_build/src/agents/tools/astDeleteNode.js +95 -0
- package/ts_build/src/agents/tools/astDeleteNode.js.map +1 -0
- package/ts_build/src/agents/tools/astEditNode.d.ts +1 -0
- package/ts_build/src/agents/tools/astEditNode.js +98 -0
- package/ts_build/src/agents/tools/astEditNode.js.map +1 -0
- package/ts_build/src/agents/tools/astGetPathForLine.d.ts +1 -0
- package/ts_build/src/agents/tools/astGetPathForLine.js +89 -0
- package/ts_build/src/agents/tools/astGetPathForLine.js.map +1 -0
- package/ts_build/src/agents/tools/astListPaths.d.ts +1 -0
- package/ts_build/src/agents/tools/astListPaths.js +82 -0
- package/ts_build/src/agents/tools/astListPaths.js.map +1 -0
- package/ts_build/src/agents/tools/callPlugin.js +4 -2
- package/ts_build/src/agents/tools/callPlugin.js.map +1 -1
- package/ts_build/src/agents/tools/embeddingSearch.js +3 -2
- package/ts_build/src/agents/tools/embeddingSearch.js.map +1 -1
- package/ts_build/src/agents/tools/execCommand.d.ts +2 -2
- package/ts_build/src/agents/tools/execCommand.js +201 -67
- package/ts_build/src/agents/tools/execCommand.js.map +1 -1
- package/ts_build/src/agents/tools/fileSearch.d.ts +1 -1
- package/ts_build/src/agents/tools/fileSearch.js +11 -15
- package/ts_build/src/agents/tools/fileSearch.js.map +1 -1
- package/ts_build/src/agents/tools/github/index.d.ts +1 -1
- package/ts_build/src/agents/tools/index.d.ts +1 -0
- package/ts_build/src/agents/tools/index.js +1 -0
- package/ts_build/src/agents/tools/index.js.map +1 -1
- package/ts_build/src/agents/tools/language/definitions.js +11 -2
- package/ts_build/src/agents/tools/language/definitions.js.map +1 -1
- package/ts_build/src/agents/tools/language/index.js +4 -3
- package/ts_build/src/agents/tools/language/index.js.map +1 -1
- package/ts_build/src/agents/tools/lintFile.js +4 -2
- package/ts_build/src/agents/tools/lintFile.js.map +1 -1
- package/ts_build/src/agents/tools/list.js +185 -49
- package/ts_build/src/agents/tools/list.js.map +1 -1
- package/ts_build/src/agents/tools/patch.js +33 -10
- package/ts_build/src/agents/tools/patch.js.map +1 -1
- package/ts_build/src/agents/tools/readBlocks.js +23 -0
- package/ts_build/src/agents/tools/readBlocks.js.map +1 -1
- package/ts_build/src/agents/tools/readFile.js +14 -0
- package/ts_build/src/agents/tools/readFile.js.map +1 -1
- package/ts_build/src/agents/tools/stringReplace.js +19 -2
- package/ts_build/src/agents/tools/stringReplace.js.map +1 -1
- package/ts_build/src/agents/tools/writeFile.js +40 -0
- package/ts_build/src/agents/tools/writeFile.js.map +1 -1
- package/ts_build/src/agents/tools/ycmd/server.js +5 -0
- package/ts_build/src/agents/tools/ycmd/server.js.map +1 -1
- package/ts_build/src/chat/CliChatService.d.ts +1 -0
- package/ts_build/src/chat/CliChatService.js +6 -2
- package/ts_build/src/chat/CliChatService.js.map +1 -1
- package/ts_build/src/chat/modules/AgentModule.d.ts +5 -1
- package/ts_build/src/chat/modules/AgentModule.js +53 -31
- package/ts_build/src/chat/modules/AgentModule.js.map +1 -1
- package/ts_build/src/chat/modules/AskModule.js.map +1 -1
- package/ts_build/src/chat/modules/SetupModule.js +4 -3
- package/ts_build/src/chat/modules/SetupModule.js.map +1 -1
- package/ts_build/src/chat/modules/SystemModule.js +19 -4
- package/ts_build/src/chat/modules/SystemModule.js.map +1 -1
- package/ts_build/src/chat/modules/index.d.ts +5 -0
- package/ts_build/src/chat/modules/index.js +14 -0
- package/ts_build/src/chat/modules/index.js.map +1 -0
- package/ts_build/src/chat/types.d.ts +2 -0
- package/ts_build/src/chat-old.js +3 -3
- package/ts_build/src/chat-old.js.map +1 -1
- package/ts_build/src/clients/anthropic.d.ts +1 -0
- package/ts_build/src/clients/anthropic.js +22 -1
- package/ts_build/src/clients/anthropic.js.map +1 -1
- package/ts_build/src/clients/openai.js +1 -1
- package/ts_build/src/clients/openai.js.map +1 -1
- package/ts_build/src/clients/xai.d.ts +7 -0
- package/ts_build/src/clients/xai.js +13 -4
- package/ts_build/src/clients/xai.js.map +1 -1
- package/ts_build/src/config.js +14 -3
- package/ts_build/src/config.js.map +1 -1
- package/ts_build/src/dataset/diffs/generate.js +2 -2
- package/ts_build/src/dataset/diffs/generate.js.map +1 -1
- package/ts_build/src/dataset/diffs/jsonl.js.map +1 -1
- package/ts_build/src/embeddings.js +7 -9
- package/ts_build/src/embeddings.js.map +1 -1
- package/ts_build/src/index.js +10 -10
- package/ts_build/src/index.js.map +1 -1
- package/ts_build/src/plugins/GitPlugin.d.ts +39 -0
- package/ts_build/src/plugins/GitPlugin.js +439 -0
- package/ts_build/src/plugins/GitPlugin.js.map +1 -0
- package/ts_build/src/plugins/LinterPlugin.d.ts +15 -0
- package/ts_build/src/plugins/LinterPlugin.js +65 -0
- package/ts_build/src/plugins/LinterPlugin.js.map +1 -0
- package/ts_build/src/plugins/PluginBase.d.ts +4 -3
- package/ts_build/src/plugins/PluginBase.js +3 -3
- package/ts_build/src/plugins/PluginBase.js.map +1 -1
- package/ts_build/src/plugins/asana.d.ts +3 -1
- package/ts_build/src/plugins/asana.js +3 -2
- package/ts_build/src/plugins/asana.js.map +1 -1
- package/ts_build/src/plugins/downloader/plugin.d.ts +3 -1
- package/ts_build/src/plugins/downloader/plugin.js +3 -2
- package/ts_build/src/plugins/downloader/plugin.js.map +1 -1
- package/ts_build/src/plugins/embedding.d.ts +5 -1
- package/ts_build/src/plugins/embedding.js +15 -3
- package/ts_build/src/plugins/embedding.js.map +1 -1
- package/ts_build/src/plugins/figma.d.ts +3 -1
- package/ts_build/src/plugins/figma.js +28 -4
- package/ts_build/src/plugins/figma.js.map +1 -1
- package/ts_build/src/plugins/github.d.ts +3 -1
- package/ts_build/src/plugins/github.js +3 -2
- package/ts_build/src/plugins/github.js.map +1 -1
- package/ts_build/src/plugins/jira.d.ts +3 -1
- package/ts_build/src/plugins/jira.js +3 -2
- package/ts_build/src/plugins/jira.js.map +1 -1
- package/ts_build/src/plugins/language.d.ts +7 -4
- package/ts_build/src/plugins/language.js +85 -20
- package/ts_build/src/plugins/language.js.map +1 -1
- package/ts_build/src/plugins/linear.d.ts +3 -1
- package/ts_build/src/plugins/linear.js +3 -2
- package/ts_build/src/plugins/linear.js.map +1 -1
- package/ts_build/src/plugins/notion.d.ts +3 -1
- package/ts_build/src/plugins/notion.js +3 -2
- package/ts_build/src/plugins/notion.js.map +1 -1
- package/ts_build/src/plugins/plugins.d.ts +4 -3
- package/ts_build/src/plugins/plugins.js +24 -14
- package/ts_build/src/plugins/plugins.js.map +1 -1
- package/ts_build/src/plugins/tree-sitter/editor.d.ts +34 -0
- package/ts_build/src/plugins/tree-sitter/editor.js +218 -0
- package/ts_build/src/plugins/tree-sitter/editor.js.map +1 -0
- package/ts_build/src/plugins/tree-sitter/human-readable-paths-new.d.ts +29 -0
- package/ts_build/src/plugins/tree-sitter/human-readable-paths-new.js +538 -0
- package/ts_build/src/plugins/tree-sitter/human-readable-paths-new.js.map +1 -0
- package/ts_build/src/plugins/tree-sitter/human-readable-paths.d.ts +22 -0
- package/ts_build/src/plugins/tree-sitter/human-readable-paths.js +332 -0
- package/ts_build/src/plugins/tree-sitter/human-readable-paths.js.map +1 -0
- package/ts_build/src/plugins/tree-sitter/lang-packs/index.d.ts +8 -0
- package/ts_build/src/plugins/tree-sitter/lang-packs/index.js +26 -0
- package/ts_build/src/plugins/tree-sitter/lang-packs/index.js.map +1 -0
- package/ts_build/src/plugins/tree-sitter/lang-packs/java.d.ts +2 -0
- package/ts_build/src/plugins/tree-sitter/lang-packs/java.js +61 -0
- package/ts_build/src/plugins/tree-sitter/lang-packs/java.js.map +1 -0
- package/ts_build/src/plugins/tree-sitter/lang-packs/javascript.d.ts +2 -0
- package/ts_build/src/plugins/tree-sitter/lang-packs/javascript.js +59 -0
- package/ts_build/src/plugins/tree-sitter/lang-packs/javascript.js.map +1 -0
- package/ts_build/src/plugins/tree-sitter/lang-packs/python.d.ts +2 -0
- package/ts_build/src/plugins/tree-sitter/lang-packs/python.js +47 -0
- package/ts_build/src/plugins/tree-sitter/lang-packs/python.js.map +1 -0
- package/ts_build/src/plugins/tree-sitter/lang-packs/types.d.ts +43 -0
- package/ts_build/src/plugins/tree-sitter/lang-packs/types.js +3 -0
- package/ts_build/src/plugins/tree-sitter/lang-packs/types.js.map +1 -0
- package/ts_build/src/plugins/tree-sitter/lang-packs/typescript.d.ts +2 -0
- package/ts_build/src/plugins/tree-sitter/lang-packs/typescript.js +50 -0
- package/ts_build/src/plugins/tree-sitter/lang-packs/typescript.js.map +1 -0
- package/ts_build/src/plugins/tree-sitter/parser.d.ts +75 -0
- package/ts_build/src/plugins/tree-sitter/parser.js +306 -0
- package/ts_build/src/plugins/tree-sitter/parser.js.map +1 -0
- package/ts_build/src/plugins/tree-sitter/simple-paths.d.ts +22 -0
- package/ts_build/src/plugins/tree-sitter/simple-paths.js +332 -0
- package/ts_build/src/plugins/tree-sitter/simple-paths.js.map +1 -0
- package/ts_build/src/plugins/types.d.ts +10 -0
- package/ts_build/src/plugins/url.d.ts +3 -2
- package/ts_build/src/plugins/url.js +3 -2
- package/ts_build/src/plugins/url.js.map +1 -1
- package/ts_build/src/plugins/vim.d.ts +4 -2
- package/ts_build/src/plugins/vim.js +6 -8
- package/ts_build/src/plugins/vim.js.map +1 -1
- package/ts_build/src/processors/CustomVariables.js +12 -3
- package/ts_build/src/processors/CustomVariables.js.map +1 -1
- package/ts_build/src/processors/TokenCompressor.js +8 -11
- package/ts_build/src/processors/TokenCompressor.js.map +1 -1
- package/ts_build/src/processors/ToolResponseCache.d.ts +2 -2
- package/ts_build/src/processors/ToolResponseCache.js +12 -2
- package/ts_build/src/processors/ToolResponseCache.js.map +1 -1
- package/ts_build/src/services/EmbeddingService.d.ts +10 -1
- package/ts_build/src/services/EmbeddingService.js +12 -12
- package/ts_build/src/services/EmbeddingService.js.map +1 -1
- package/ts_build/src/services/EventService.d.ts +7 -0
- package/ts_build/src/services/EventService.js +49 -0
- package/ts_build/src/services/EventService.js.map +1 -1
- package/ts_build/src/services/Mcp.js +8 -0
- package/ts_build/src/services/Mcp.js.map +1 -1
- package/ts_build/src/services/S3.js +4 -3
- package/ts_build/src/services/S3.js.map +1 -1
- package/ts_build/src/services/Tools.d.ts +1 -0
- package/ts_build/src/services/Tools.js +97 -35
- package/ts_build/src/services/Tools.js.map +1 -1
- package/ts_build/src/services/index.d.ts +4 -5
- package/ts_build/src/services/index.js +14 -9
- package/ts_build/src/services/index.js.map +1 -1
- package/ts_build/src/services/types.js +3 -3
- package/ts_build/src/services/types.js.map +1 -1
- package/ts_build/src/types.d.ts +7 -1
- package/ts_build/src/types.js +4 -0
- package/ts_build/src/types.js.map +1 -1
- package/ts_build/src/worker.js +12 -1
- package/ts_build/src/worker.js.map +1 -1
- package/ts_build/tests/clients/AIClient.test.d.ts +1 -0
- package/ts_build/tests/clients/AIClient.test.js +377 -0
- package/ts_build/tests/clients/AIClient.test.js.map +1 -0
- package/ts_build/tests/languagePlugin.test.js +217 -11
- package/ts_build/tests/languagePlugin.test.js.map +1 -1
- package/ts_build/tests/manual/agent-events/event-handler-reliability.test.d.ts +1 -0
- package/ts_build/tests/manual/agent-events/event-handler-reliability.test.js +315 -0
- package/ts_build/tests/manual/agent-events/event-handler-reliability.test.js.map +1 -0
- package/ts_build/tests/manual/agent-events/run-test.d.ts +2 -0
- package/ts_build/tests/manual/agent-events/run-test.js +148 -0
- package/ts_build/tests/manual/agent-events/run-test.js.map +1 -0
- package/ts_build/tests/manual/file-edits/figma.test.d.ts +1 -0
- package/ts_build/tests/manual/file-edits/figma.test.js +47 -0
- package/ts_build/tests/manual/file-edits/figma.test.js.map +1 -0
- package/ts_build/tests/manual/file-edits/fileblocks/readwrite.test.d.ts +1 -0
- package/ts_build/tests/manual/file-edits/fileblocks/readwrite.test.js +100 -0
- package/ts_build/tests/manual/file-edits/fileblocks/readwrite.test.js.map +1 -0
- package/ts_build/tests/manual/file-edits/patching.test.d.ts +1 -0
- package/ts_build/tests/manual/file-edits/patching.test.js +119 -0
- package/ts_build/tests/manual/file-edits/patching.test.js.map +1 -0
- package/ts_build/tests/plugins/language/languagePlugin-content-triggers.test.d.ts +1 -0
- package/ts_build/tests/plugins/language/languagePlugin-content-triggers.test.js +277 -0
- package/ts_build/tests/plugins/language/languagePlugin-content-triggers.test.js.map +1 -0
- package/ts_build/tests/plugins/language/languagePlugin-integration.test.d.ts +1 -0
- package/ts_build/tests/plugins/language/languagePlugin-integration.test.js +331 -0
- package/ts_build/tests/plugins/language/languagePlugin-integration.test.js.map +1 -0
- package/ts_build/tests/plugins/language/languagePlugin.test.d.ts +1 -0
- package/ts_build/tests/plugins/language/languagePlugin.test.js +286 -0
- package/ts_build/tests/plugins/language/languagePlugin.test.js.map +1 -0
- package/ts_build/tests/processors/Base64ImageDetector.test.d.ts +1 -0
- package/ts_build/tests/processors/Base64ImageDetector.test.js +351 -0
- package/ts_build/tests/processors/Base64ImageDetector.test.js.map +1 -0
- package/ts_build/tests/processors/CustomVariables.test.d.ts +1 -0
- package/ts_build/tests/processors/CustomVariables.test.js +351 -0
- package/ts_build/tests/processors/CustomVariables.test.js.map +1 -0
- package/ts_build/tests/processors/HarmonyToolProcessor.test.d.ts +1 -0
- package/ts_build/tests/processors/HarmonyToolProcessor.test.js +382 -0
- package/ts_build/tests/processors/HarmonyToolProcessor.test.js.map +1 -0
- package/ts_build/tests/processors/TokenCompressor.test.d.ts +1 -0
- package/ts_build/tests/processors/TokenCompressor.test.js +300 -0
- package/ts_build/tests/processors/TokenCompressor.test.js.map +1 -0
- package/ts_build/tests/processors/ToolResponseCache.test.d.ts +1 -0
- package/ts_build/tests/processors/ToolResponseCache.test.js +539 -0
- package/ts_build/tests/processors/ToolResponseCache.test.js.map +1 -0
- package/ts_build/tests/services/Plugins/plugin-event-integration.test.d.ts +1 -0
- package/ts_build/tests/services/Plugins/plugin-event-integration.test.js +232 -0
- package/ts_build/tests/services/Plugins/plugin-event-integration.test.js.map +1 -0
- package/ts_build/tests/services/Tools.test.d.ts +1 -0
- package/ts_build/tests/services/Tools.test.js +1059 -0
- package/ts_build/tests/services/Tools.test.js.map +1 -0
- package/ts_build/tests/test.spec.js +110 -68
- package/ts_build/tests/test.spec.js.map +1 -1
- package/ts_build/tests/tree-sitter/editor.test.d.ts +1 -0
- package/ts_build/tests/tree-sitter/editor.test.js +85 -0
- package/ts_build/tests/tree-sitter/editor.test.js.map +1 -0
- package/ts_build/tests/tree-sitter/invalid.test.d.ts +1 -0
- package/ts_build/tests/tree-sitter/invalid.test.js +198 -0
- package/ts_build/tests/tree-sitter/invalid.test.js.map +1 -0
- package/ts_build/tests/tree-sitter/paths/common-edits.test.d.ts +1 -0
- package/ts_build/tests/tree-sitter/paths/common-edits.test.js +347 -0
- package/ts_build/tests/tree-sitter/paths/common-edits.test.js.map +1 -0
- package/ts_build/tests/tree-sitter/paths/debug-exact-position.test.d.ts +1 -0
- package/ts_build/tests/tree-sitter/paths/debug-exact-position.test.js +35 -0
- package/ts_build/tests/tree-sitter/paths/debug-exact-position.test.js.map +1 -0
- package/ts_build/tests/tree-sitter/paths/debug-line-indexing.test.d.ts +1 -0
- package/ts_build/tests/tree-sitter/paths/debug-line-indexing.test.js +38 -0
- package/ts_build/tests/tree-sitter/paths/debug-line-indexing.test.js.map +1 -0
- package/ts_build/tests/tree-sitter/paths/debug-paths.test.d.ts +1 -0
- package/ts_build/tests/tree-sitter/paths/debug-paths.test.js +74 -0
- package/ts_build/tests/tree-sitter/paths/debug-paths.test.js.map +1 -0
- package/ts_build/tests/tree-sitter/paths/human-readable-paths.test.d.ts +1 -0
- package/ts_build/tests/tree-sitter/paths/human-readable-paths.test.js +302 -0
- package/ts_build/tests/tree-sitter/paths/human-readable-paths.test.js.map +1 -0
- package/ts_build/tests/tree-sitter/paths/paths.test.d.ts +1 -0
- package/ts_build/tests/tree-sitter/paths/paths.test.js +116 -0
- package/ts_build/tests/tree-sitter/paths/paths.test.js.map +1 -0
- package/ts_build/tests/tree-sitter/paths/simple-paths.test.d.ts +1 -0
- package/ts_build/tests/tree-sitter/paths/simple-paths.test.js +302 -0
- package/ts_build/tests/tree-sitter/paths/simple-paths.test.js.map +1 -0
- package/ts_build/tests/tree-sitter/sample-after.d.ts +11 -0
- package/ts_build/tests/tree-sitter/sample-after.js +44 -0
- package/ts_build/tests/tree-sitter/sample-after.js.map +1 -0
- package/ts_build/tests/tree-sitter/sample-before.d.ts +9 -0
- package/ts_build/tests/tree-sitter/sample-before.js +28 -0
- package/ts_build/tests/tree-sitter/sample-before.js.map +1 -0
- package/ts_build/tests/tree-sitter/test-files/completely-broken.d.ts +2 -0
- package/ts_build/tests/tree-sitter/test-files/completely-broken.js +17 -0
- package/ts_build/tests/tree-sitter/test-files/completely-broken.js.map +1 -0
- package/ts_build/tests/tree-sitter/test-files/duplicate-braces.d.ts +8 -0
- package/ts_build/tests/tree-sitter/test-files/duplicate-braces.js +38 -0
- package/ts_build/tests/tree-sitter/test-files/duplicate-braces.js.map +1 -0
- package/ts_build/tests/tree-sitter/test-files/invalid-nesting.d.ts +8 -0
- package/ts_build/tests/tree-sitter/test-files/invalid-nesting.js +38 -0
- package/ts_build/tests/tree-sitter/test-files/invalid-nesting.js.map +1 -0
- package/ts_build/tests/tree-sitter/test-files/malformed-signature.d.ts +8 -0
- package/ts_build/tests/tree-sitter/test-files/malformed-signature.js +38 -0
- package/ts_build/tests/tree-sitter/test-files/malformed-signature.js.map +1 -0
- package/ts_build/tests/tree-sitter/test-files/mismatched-parens.d.ts +10 -0
- package/ts_build/tests/tree-sitter/test-files/mismatched-parens.js +38 -0
- package/ts_build/tests/tree-sitter/test-files/mismatched-parens.js.map +1 -0
- package/ts_build/tests/tree-sitter/test-files/missing-semicolon.d.ts +8 -0
- package/ts_build/tests/tree-sitter/test-files/missing-semicolon.js +38 -0
- package/ts_build/tests/tree-sitter/test-files/missing-semicolon.js.map +1 -0
- package/ts_build/tests/tree-sitter/test-files/partially-broken.d.ts +6 -0
- package/ts_build/tests/tree-sitter/test-files/partially-broken.js +20 -0
- package/ts_build/tests/tree-sitter/test-files/partially-broken.js.map +1 -0
- package/ts_build/tests/tree-sitter/test-files/specific-errors.d.ts +7 -0
- package/ts_build/tests/tree-sitter/test-files/specific-errors.js +14 -0
- package/ts_build/tests/tree-sitter/test-files/specific-errors.js.map +1 -0
- package/ts_build/tests/tree-sitter/test-files/unclosed-string.d.ts +8 -0
- package/ts_build/tests/tree-sitter/test-files/unclosed-string.js +38 -0
- package/ts_build/tests/tree-sitter/test-files/unclosed-string.js.map +1 -0
- package/ts_build/tests/tree-sitter/tree-sitter.test.d.ts +1 -0
- package/ts_build/tests/tree-sitter/tree-sitter.test.js +185 -0
- package/ts_build/tests/tree-sitter/tree-sitter.test.js.map +1 -0
- package/tsconfig.json +2 -1
- package/tests/languagePlugin.test.ts +0 -74
- /package/src/chat/modules/{index.js → index.ts} +0 -0
- /package/tests/{integration → manual/file-edits}/patching/input.txt +0 -0
- /package/tests/{integration → manual/file-edits}/patching/output.txt +0 -0
- /package/tests/{integration → manual/file-edits}/patching/patch.txt +0 -0
- /package/tests/{integration → manual/file-edits}/patching/unseen.txt +0 -0
package/jest.config.js
CHANGED
|
@@ -12,8 +12,8 @@ module.exports = {
|
|
|
12
12
|
],
|
|
13
13
|
},
|
|
14
14
|
testEnvironment: 'node',
|
|
15
|
-
testRegex: '/tests/.*\.(test|spec)
|
|
15
|
+
testRegex: '/tests/.*\.(test|spec)\.(ts|tsx|js)$',
|
|
16
16
|
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
|
|
17
17
|
modulePathIgnorePatterns: ["ts_build", "benchmarks"],
|
|
18
|
-
testPathIgnorePatterns: ["<rootDir>/benchmarks/"]
|
|
18
|
+
testPathIgnorePatterns: ["<rootDir>/benchmarks/", "<rootDir>/tests/manual/"],
|
|
19
19
|
};
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tyvm/knowhow",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.48",
|
|
4
4
|
"description": "ai cli with plugins and agents",
|
|
5
5
|
"main": "ts_build/src/index.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"knowhow": "ts_build/src/cli.js"
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
|
-
"test": "jest --
|
|
10
|
+
"test": "jest --testTimeout 300000",
|
|
11
11
|
"test:debug": "node --inspect-brk ../../node_modules/jest/bin/jest.js --detectOpenHandles --forceExit --testTimeout 300000",
|
|
12
12
|
"compile": "tsc",
|
|
13
13
|
"start": "npm run compile && node ts_build/src/server/index.js",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"@anthropic-ai/sdk": "^0.39.0",
|
|
42
42
|
"@aws-sdk/client-s3": "^3.588.0",
|
|
43
43
|
"@google/genai": "^0.14.1",
|
|
44
|
-
"@inquirer/editor": "^
|
|
44
|
+
"@inquirer/editor": "^4.2.18",
|
|
45
45
|
"@linear/sdk": "^12.0.0",
|
|
46
46
|
"@modelcontextprotocol/sdk": "^1.13.3",
|
|
47
47
|
"@notionhq/client": "^2.2.14",
|
|
@@ -56,11 +56,13 @@
|
|
|
56
56
|
"express": "^4.19.2",
|
|
57
57
|
"figma-js": "^1.16.1-0",
|
|
58
58
|
"gitignore-to-glob": "^0.3.0",
|
|
59
|
+
"glob": "11.0.3",
|
|
59
60
|
"ink": "^6.0.1",
|
|
60
61
|
"isolated-vm": "^5.0.4",
|
|
61
62
|
"jira-client": "^8.2.2",
|
|
62
63
|
"marked": "^10.0.0",
|
|
63
64
|
"marked-terminal": "^6.2.0",
|
|
65
|
+
"minimatch": "^10.0.3",
|
|
64
66
|
"morgan": "^1.10.0",
|
|
65
67
|
"node-fetch": "^3.2.3",
|
|
66
68
|
"node-jq": "^6.0.1",
|
|
@@ -77,6 +79,9 @@
|
|
|
77
79
|
"puppeteer-extra-plugin-stealth": "^2.11.2",
|
|
78
80
|
"react": "^19.1.0",
|
|
79
81
|
"source-map-support": "^0.5.21",
|
|
82
|
+
"tree-sitter": "^0.21.1",
|
|
83
|
+
"tree-sitter-javascript": "^0.23.1",
|
|
84
|
+
"tree-sitter-typescript": "^0.23.1",
|
|
80
85
|
"typescript": "^4.6.3",
|
|
81
86
|
"ws": "^8.18.1",
|
|
82
87
|
"youtube-dl-exec": "^2.5.5",
|
package/src/agents/base/base.ts
CHANGED
|
@@ -55,6 +55,7 @@ export abstract class BaseAgent implements IAgent {
|
|
|
55
55
|
protected pendingUserMessages = [] as Message[];
|
|
56
56
|
protected taskBreakdown = "";
|
|
57
57
|
protected summaries = [] as string[];
|
|
58
|
+
protected currentTaskId: string | null = null;
|
|
58
59
|
|
|
59
60
|
public agentEvents = new EventEmitter();
|
|
60
61
|
public eventTypes = {
|
|
@@ -87,6 +88,15 @@ export abstract class BaseAgent implements IAgent {
|
|
|
87
88
|
if (!this.events) {
|
|
88
89
|
throw new Error("EventService is required for BaseAgent");
|
|
89
90
|
}
|
|
91
|
+
|
|
92
|
+
// Subscribe to "agent:msg" events for dynamic context loading
|
|
93
|
+
this.events.on("agent:msg", (eventData: any) => {
|
|
94
|
+
const message = {
|
|
95
|
+
role: "user",
|
|
96
|
+
content: JSON.stringify(eventData),
|
|
97
|
+
} as Message;
|
|
98
|
+
this.addPendingUserMessage(message);
|
|
99
|
+
});
|
|
90
100
|
}
|
|
91
101
|
|
|
92
102
|
setMaxTurns(maxTurns: number | null) {
|
|
@@ -101,7 +111,7 @@ export abstract class BaseAgent implements IAgent {
|
|
|
101
111
|
this.maxRunTimeMs = maxRunTimeMs;
|
|
102
112
|
}
|
|
103
113
|
|
|
104
|
-
newTask() {
|
|
114
|
+
newTask(taskId?: string) {
|
|
105
115
|
this.currentThread = 0;
|
|
106
116
|
this.threads = [];
|
|
107
117
|
this.taskBreakdown = "";
|
|
@@ -110,6 +120,13 @@ export abstract class BaseAgent implements IAgent {
|
|
|
110
120
|
this.status = "in_progress";
|
|
111
121
|
this.turnCount = 0;
|
|
112
122
|
this.startTimeMs = Date.now();
|
|
123
|
+
this.currentTaskId = taskId || this.startTimeMs.toString();
|
|
124
|
+
|
|
125
|
+
// Emit event for plugin integration
|
|
126
|
+
const id = taskId || this.startTimeMs.toString();
|
|
127
|
+
this.events.emit("agent:newTask", {
|
|
128
|
+
taskId: id,
|
|
129
|
+
});
|
|
113
130
|
}
|
|
114
131
|
|
|
115
132
|
register() {
|
|
@@ -143,6 +160,7 @@ export abstract class BaseAgent implements IAgent {
|
|
|
143
160
|
|
|
144
161
|
setModel(value: string) {
|
|
145
162
|
this.modelName = value;
|
|
163
|
+
this.client = null; // Reset client to force re-fetch
|
|
146
164
|
}
|
|
147
165
|
|
|
148
166
|
getProvider() {
|
|
@@ -151,6 +169,7 @@ export abstract class BaseAgent implements IAgent {
|
|
|
151
169
|
|
|
152
170
|
setProvider(value: keyof typeof Clients.clients) {
|
|
153
171
|
this.provider = value;
|
|
172
|
+
this.client = null; // Reset client to force re-fetch
|
|
154
173
|
}
|
|
155
174
|
|
|
156
175
|
getClient() {
|
|
@@ -416,27 +435,6 @@ export abstract class BaseAgent implements IAgent {
|
|
|
416
435
|
});
|
|
417
436
|
}
|
|
418
437
|
|
|
419
|
-
async resume(resumeReason: string) {
|
|
420
|
-
const reason = resumeReason ? `Reason for resuming: ${resumeReason}` : "";
|
|
421
|
-
|
|
422
|
-
// Create resume prompt
|
|
423
|
-
const resumePrompt = `We are resuming a previously started task. Here's the context:
|
|
424
|
-
ORIGINAL REQUEST:
|
|
425
|
-
${this.taskBreakdown}
|
|
426
|
-
|
|
427
|
-
LAST Progress State:
|
|
428
|
-
${JSON.stringify(this.threads[this.currentThread], null, 2)}
|
|
429
|
-
|
|
430
|
-
Please continue from where you left off and complete the original request.
|
|
431
|
-
${reason}
|
|
432
|
-
|
|
433
|
-
`;
|
|
434
|
-
|
|
435
|
-
const lastThread = this.threads[this.currentThread] || [];
|
|
436
|
-
this.status = "in_progress";
|
|
437
|
-
this.call(resumePrompt, lastThread);
|
|
438
|
-
}
|
|
439
|
-
|
|
440
438
|
async kill() {
|
|
441
439
|
console.log("Killing agent");
|
|
442
440
|
this.agentEvents.emit(this.eventTypes.kill, this);
|
|
@@ -564,6 +562,14 @@ ${reason}
|
|
|
564
562
|
);
|
|
565
563
|
|
|
566
564
|
if (finalMessage) {
|
|
565
|
+
// Emit task completion event for plugins (like GitPlugin)
|
|
566
|
+
this.events.emit("agent:taskComplete", {
|
|
567
|
+
taskId:
|
|
568
|
+
this.currentTaskId ||
|
|
569
|
+
this.startTimeMs?.toString() ||
|
|
570
|
+
Date.now().toString(),
|
|
571
|
+
result: finalMessage.content || "Done",
|
|
572
|
+
});
|
|
567
573
|
const doneMsg = finalMessage.content || "Done";
|
|
568
574
|
this.agentEvents.emit(this.eventTypes.done, doneMsg);
|
|
569
575
|
this.status = this.eventTypes.done;
|
|
@@ -620,7 +626,7 @@ ${reason}
|
|
|
620
626
|
|
|
621
627
|
if (
|
|
622
628
|
this.getMessagesLength(messages) > compressThreshold &&
|
|
623
|
-
messages.length >
|
|
629
|
+
messages.length > 20
|
|
624
630
|
) {
|
|
625
631
|
const taskBreakdown = await this.getTaskBreakdown(messages);
|
|
626
632
|
console.log(
|
|
@@ -702,7 +708,7 @@ ${reason}
|
|
|
702
708
|
|
|
703
709
|
addPendingUserMessage(message: Message) {
|
|
704
710
|
if (this.status === this.eventTypes.done) {
|
|
705
|
-
|
|
711
|
+
console.warn("Agent is done, cannot take more messages");
|
|
706
712
|
} else {
|
|
707
713
|
this.pendingUserMessages.push(message);
|
|
708
714
|
}
|
|
@@ -79,11 +79,9 @@ export class PatchingAgent extends BaseAgent {
|
|
|
79
79
|
super(context);
|
|
80
80
|
|
|
81
81
|
this.setModelPreferences([
|
|
82
|
-
{ model: Models.anthropic.
|
|
83
|
-
{
|
|
84
|
-
|
|
85
|
-
provider: "openai",
|
|
86
|
-
},
|
|
82
|
+
{ model: Models.anthropic.Sonnet4_5, provider: "anthropic" },
|
|
83
|
+
{ model: Models.xai.GrokCodeFast, provider: "xai" },
|
|
84
|
+
{ model: Models.openai.GPT_5, provider: "openai" },
|
|
87
85
|
]);
|
|
88
86
|
}
|
|
89
87
|
|
|
@@ -102,6 +100,29 @@ export class PatchingAgent extends BaseAgent {
|
|
|
102
100
|
This helps ensure accurate modifications and can suggest fixes for compilation errors.
|
|
103
101
|
|
|
104
102
|
IF you fail twice to patch a file, you may switch using writeFileChunk to rewrite the whole file.
|
|
103
|
+
|
|
104
|
+
If you need to know about a type, you should use the ycmd completion tool to discovery the properties, and fallback to reading the source files if the ycmd tools are not available.
|
|
105
|
+
|
|
106
|
+
# Debugging Workflow
|
|
107
|
+
If a build or test command fails due to compilation errors:
|
|
108
|
+
|
|
109
|
+
ALWAYS start by running ycmdDiagnostics on the file with errors to get a structured list of issues.
|
|
110
|
+
|
|
111
|
+
Address the errors one at a time, from top to bottom.
|
|
112
|
+
|
|
113
|
+
For each error, use ycmdGoTo to find the correct definition or readFile on the relevant source file to understand the correct implementation.
|
|
114
|
+
|
|
115
|
+
If an error is related to properties not being named correctly, you can use ycmdCompletion to get suggestions for the correct property or method names.
|
|
116
|
+
|
|
117
|
+
Apply a small, targeted patch to fix only that single error.
|
|
118
|
+
|
|
119
|
+
After every 2-3 fixes, run ycmdDiagnostics again to confirm progress.
|
|
120
|
+
|
|
121
|
+
# Test Writing Workflow
|
|
122
|
+
When writing tests, you proceed incrementally, writing one test, verifying it compiles and works before moving on to the next test.
|
|
123
|
+
You ALWAYS get to a stable state with tests compiling / running before adding the next test.
|
|
124
|
+
When writing tests, you never change the source code to pass the test, you always change the test to match the existing source code.
|
|
125
|
+
|
|
105
126
|
`,
|
|
106
127
|
},
|
|
107
128
|
{ role: "user", content: userInput },
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { getConfig } from "../../config";
|
|
2
|
-
import { ToolsService } from "../../services";
|
|
2
|
+
import { services, ToolsService } from "../../services";
|
|
3
3
|
|
|
4
4
|
export async function agentCall(agentName: string, userInput: string) {
|
|
5
5
|
return new Promise(async (resolve, reject) => {
|
|
6
6
|
const config = await getConfig();
|
|
7
|
-
const toolService =
|
|
7
|
+
const toolService = (
|
|
8
|
+
this instanceof ToolsService ? this : services().Tools
|
|
9
|
+
) as ToolsService;
|
|
8
10
|
|
|
9
11
|
const { Events, Plugins } = toolService.getContext();
|
|
10
12
|
|
|
@@ -9,7 +9,6 @@ import {
|
|
|
9
9
|
import { services } from "../../services";
|
|
10
10
|
|
|
11
11
|
export function createAiCompletion(
|
|
12
|
-
this: ToolsService,
|
|
13
12
|
provider: string,
|
|
14
13
|
options: CompletionOptions
|
|
15
14
|
): Promise<CompletionResponse> {
|
|
@@ -29,7 +28,6 @@ export function createAiCompletion(
|
|
|
29
28
|
}
|
|
30
29
|
|
|
31
30
|
export function createEmbedding(
|
|
32
|
-
this: ToolsService,
|
|
33
31
|
provider: string,
|
|
34
32
|
options: EmbeddingOptions
|
|
35
33
|
): Promise<EmbeddingResponse> {
|
|
@@ -49,7 +47,6 @@ export function createEmbedding(
|
|
|
49
47
|
}
|
|
50
48
|
|
|
51
49
|
export async function listModelsForProvider(
|
|
52
|
-
this: ToolsService,
|
|
53
50
|
provider: string
|
|
54
51
|
): Promise<string[]> {
|
|
55
52
|
// Get context from bound ToolsService
|
|
@@ -68,7 +65,6 @@ export async function listModelsForProvider(
|
|
|
68
65
|
}
|
|
69
66
|
|
|
70
67
|
export async function listAllModels(
|
|
71
|
-
this: ToolsService
|
|
72
68
|
): Promise<Record<string, string[]>> {
|
|
73
69
|
// Get context from bound ToolsService
|
|
74
70
|
const toolService = (
|
|
@@ -85,7 +81,7 @@ export async function listAllModels(
|
|
|
85
81
|
return contextClients.listAllModels();
|
|
86
82
|
}
|
|
87
83
|
|
|
88
|
-
export async function listAllProviders(
|
|
84
|
+
export async function listAllProviders(): Promise<string[]> {
|
|
89
85
|
// Get context from bound ToolsService
|
|
90
86
|
const toolService = (
|
|
91
87
|
this instanceof ToolsService ? this : services().Tools
|
|
@@ -101,9 +97,7 @@ export async function listAllProviders(this: ToolsService): Promise<string[]> {
|
|
|
101
97
|
return contextClients.listAllProviders();
|
|
102
98
|
}
|
|
103
99
|
|
|
104
|
-
export async function listAllCompletionModels(
|
|
105
|
-
this: ToolsService
|
|
106
|
-
): Promise<Record<string, string[]>> {
|
|
100
|
+
export async function listAllCompletionModels(): Promise<Record<string, string[]>> {
|
|
107
101
|
// Get context from bound ToolsService
|
|
108
102
|
const toolService = (
|
|
109
103
|
this instanceof ToolsService ? this : services().Tools
|
|
@@ -119,9 +113,7 @@ export async function listAllCompletionModels(
|
|
|
119
113
|
return contextClients.listAllCompletionModels();
|
|
120
114
|
}
|
|
121
115
|
|
|
122
|
-
export async function listAllEmbeddingModels(
|
|
123
|
-
this: ToolsService
|
|
124
|
-
): Promise<Record<string, string[]>> {
|
|
116
|
+
export async function listAllEmbeddingModels(): Promise<Record<string, string[]>> {
|
|
125
117
|
// Get context from bound ToolsService
|
|
126
118
|
const toolService = (
|
|
127
119
|
this instanceof ToolsService ? this : services().Tools
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import { fileExists } from "../../../utils";
|
|
3
|
+
import { services, ToolsService } from "../../../services";
|
|
4
|
+
import { LanguageAgnosticParser } from "../../../plugins/tree-sitter/parser";
|
|
5
|
+
import { TreeEditor } from "../../../plugins/tree-sitter/editor";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Append a child node to a specific path in a file using tree-sitter AST parsing
|
|
9
|
+
*/
|
|
10
|
+
export async function astAppendNode(filePath: string, parentPath: string, newContent: string): Promise<string> {
|
|
11
|
+
// Get context from bound ToolsService
|
|
12
|
+
const toolService = (
|
|
13
|
+
this instanceof ToolsService ? this : services().Tools
|
|
14
|
+
) as ToolsService;
|
|
15
|
+
|
|
16
|
+
const context = toolService.getContext();
|
|
17
|
+
|
|
18
|
+
const exists = await fileExists(filePath);
|
|
19
|
+
if (!exists) {
|
|
20
|
+
throw new Error(`File not found: ${filePath}`);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Read original content for event emission
|
|
24
|
+
let originalContent = "";
|
|
25
|
+
try {
|
|
26
|
+
originalContent = fs.readFileSync(filePath, "utf8");
|
|
27
|
+
} catch (error) {
|
|
28
|
+
throw new Error(`Failed to read file ${filePath}: ${error.message}`);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Emit pre-edit blocking event
|
|
32
|
+
if (context.Events) {
|
|
33
|
+
await context.Events.emitBlocking("file:pre-edit", {
|
|
34
|
+
filePath,
|
|
35
|
+
operation: "ast-append-node",
|
|
36
|
+
content: newContent,
|
|
37
|
+
originalContent,
|
|
38
|
+
astParentPath: parentPath,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
try {
|
|
43
|
+
if (!LanguageAgnosticParser.supportsFile(filePath)) {
|
|
44
|
+
throw new Error(`Unsupported file type for AST parsing: ${filePath}`);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const parser = LanguageAgnosticParser.createParserForFile(filePath);
|
|
48
|
+
const editor = new TreeEditor(parser, originalContent);
|
|
49
|
+
const updatedEditor = editor.appendChild(parentPath, newContent);
|
|
50
|
+
const updatedContent = updatedEditor.getCurrentText();
|
|
51
|
+
|
|
52
|
+
// Write the updated content back to the file
|
|
53
|
+
fs.writeFileSync(filePath, updatedContent, "utf8");
|
|
54
|
+
|
|
55
|
+
// Emit post-edit blocking event (only on success)
|
|
56
|
+
let eventResults: any[] = [];
|
|
57
|
+
if (context.Events) {
|
|
58
|
+
eventResults = await context.Events.emitBlocking("file:post-edit", {
|
|
59
|
+
filePath,
|
|
60
|
+
operation: "ast-append-node",
|
|
61
|
+
content: newContent,
|
|
62
|
+
originalContent,
|
|
63
|
+
updatedContent,
|
|
64
|
+
astParentPath: parentPath,
|
|
65
|
+
success: true,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const result = {
|
|
70
|
+
file: filePath,
|
|
71
|
+
parentPath,
|
|
72
|
+
action: "appendChild",
|
|
73
|
+
success: true,
|
|
74
|
+
message: `Successfully appended child node to path: ${parentPath}`,
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
// Format event results
|
|
78
|
+
let eventResultsText = "";
|
|
79
|
+
if (eventResults && eventResults.length > 0) {
|
|
80
|
+
eventResultsText =
|
|
81
|
+
"\n\nAdditional Information:\n" +
|
|
82
|
+
JSON.stringify(eventResults, null, 2);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return JSON.stringify(result, null, 2) + eventResultsText;
|
|
86
|
+
} catch (error: any) {
|
|
87
|
+
// Do NOT emit post-edit event on error
|
|
88
|
+
throw new Error(`Failed to append node in ${filePath}: ${error.message}`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import { fileExists } from "../../../utils";
|
|
3
|
+
import { services, ToolsService } from "../../../services";
|
|
4
|
+
import { LanguageAgnosticParser } from "../../../plugins/tree-sitter/parser";
|
|
5
|
+
import { TreeEditor } from "../../../plugins/tree-sitter/editor";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Delete a node at a specific path in a file using tree-sitter AST parsing
|
|
9
|
+
*/
|
|
10
|
+
export async function astDeleteNode(filePath: string, path: string): Promise<string> {
|
|
11
|
+
// Get context from bound ToolsService
|
|
12
|
+
const toolService = (
|
|
13
|
+
this instanceof ToolsService ? this : services().Tools
|
|
14
|
+
) as ToolsService;
|
|
15
|
+
|
|
16
|
+
const context = toolService.getContext();
|
|
17
|
+
|
|
18
|
+
const exists = await fileExists(filePath);
|
|
19
|
+
if (!exists) {
|
|
20
|
+
throw new Error(`File not found: ${filePath}`);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Read original content for event emission
|
|
24
|
+
let originalContent = "";
|
|
25
|
+
try {
|
|
26
|
+
originalContent = fs.readFileSync(filePath, "utf8");
|
|
27
|
+
} catch (error) {
|
|
28
|
+
throw new Error(`Failed to read file ${filePath}: ${error.message}`);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Emit pre-edit blocking event
|
|
32
|
+
if (context.Events) {
|
|
33
|
+
await context.Events.emitBlocking("file:pre-edit", {
|
|
34
|
+
filePath,
|
|
35
|
+
operation: "ast-delete-node",
|
|
36
|
+
originalContent,
|
|
37
|
+
astPath: path,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
try {
|
|
42
|
+
if (!LanguageAgnosticParser.supportsFile(filePath)) {
|
|
43
|
+
throw new Error(`Unsupported file type for AST parsing: ${filePath}`);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const parser = LanguageAgnosticParser.createParserForFile(filePath);
|
|
47
|
+
const editor = new TreeEditor(parser, originalContent);
|
|
48
|
+
const updatedEditor = editor.deleteNodeByPath(path);
|
|
49
|
+
const updatedContent = updatedEditor.getCurrentText();
|
|
50
|
+
|
|
51
|
+
// Write the updated content back to the file
|
|
52
|
+
fs.writeFileSync(filePath, updatedContent, "utf8");
|
|
53
|
+
|
|
54
|
+
// Emit post-edit blocking event (only on success)
|
|
55
|
+
let eventResults: any[] = [];
|
|
56
|
+
if (context.Events) {
|
|
57
|
+
eventResults = await context.Events.emitBlocking("file:post-edit", {
|
|
58
|
+
filePath,
|
|
59
|
+
operation: "ast-delete-node",
|
|
60
|
+
originalContent,
|
|
61
|
+
updatedContent,
|
|
62
|
+
astPath: path,
|
|
63
|
+
success: true,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const result = {
|
|
68
|
+
file: filePath,
|
|
69
|
+
path,
|
|
70
|
+
action: "delete",
|
|
71
|
+
success: true,
|
|
72
|
+
message: `Successfully deleted node at path: ${path}`,
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
// Format event results
|
|
76
|
+
let eventResultsText = "";
|
|
77
|
+
if (eventResults && eventResults.length > 0) {
|
|
78
|
+
eventResultsText =
|
|
79
|
+
"\n\nAdditional Information:\n" +
|
|
80
|
+
JSON.stringify(eventResults, null, 2);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return JSON.stringify(result, null, 2) + eventResultsText;
|
|
84
|
+
} catch (error: any) {
|
|
85
|
+
// Do NOT emit post-edit event on error
|
|
86
|
+
throw new Error(`Failed to delete node in ${filePath}: ${error.message}`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import { fileExists } from "../../../utils";
|
|
3
|
+
import { services, ToolsService } from "../../../services";
|
|
4
|
+
import { LanguageAgnosticParser } from "../../../plugins/tree-sitter/parser";
|
|
5
|
+
import { TreeEditor } from "../../../plugins/tree-sitter/editor";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Update a node at a specific path in a file using tree-sitter AST parsing
|
|
9
|
+
*/
|
|
10
|
+
export async function astEditNode(
|
|
11
|
+
filePath: string,
|
|
12
|
+
path: string,
|
|
13
|
+
newContent: string
|
|
14
|
+
): Promise<string> {
|
|
15
|
+
// Get context from bound ToolsService
|
|
16
|
+
const toolService = (
|
|
17
|
+
this instanceof ToolsService ? this : services().Tools
|
|
18
|
+
) as ToolsService;
|
|
19
|
+
|
|
20
|
+
const context = toolService.getContext();
|
|
21
|
+
|
|
22
|
+
const exists = await fileExists(filePath);
|
|
23
|
+
if (!exists) {
|
|
24
|
+
throw new Error(`File not found: ${filePath}`);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Read original content for event emission
|
|
28
|
+
let originalContent = "";
|
|
29
|
+
try {
|
|
30
|
+
originalContent = fs.readFileSync(filePath, "utf8");
|
|
31
|
+
} catch (error) {
|
|
32
|
+
throw new Error(`Failed to read file ${filePath}: ${error.message}`);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Emit pre-edit blocking event
|
|
36
|
+
if (context.Events) {
|
|
37
|
+
await context.Events.emitBlocking("file:pre-edit", {
|
|
38
|
+
filePath,
|
|
39
|
+
operation: "ast-edit-node",
|
|
40
|
+
content: newContent,
|
|
41
|
+
originalContent,
|
|
42
|
+
astPath: path,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
try {
|
|
47
|
+
if (!LanguageAgnosticParser.supportsFile(filePath)) {
|
|
48
|
+
throw new Error(`Unsupported file type for AST parsing: ${filePath}`);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const parser = LanguageAgnosticParser.createParserForFile(filePath);
|
|
52
|
+
const editor = new TreeEditor(parser, originalContent);
|
|
53
|
+
const updatedEditor = editor.updateNodeByPath(path, newContent);
|
|
54
|
+
const updatedContent = updatedEditor.getCurrentText();
|
|
55
|
+
|
|
56
|
+
// Write the updated content back to the file
|
|
57
|
+
fs.writeFileSync(filePath, updatedContent, "utf8");
|
|
58
|
+
|
|
59
|
+
// Emit post-edit blocking event
|
|
60
|
+
let eventResults: any[] = [];
|
|
61
|
+
if (context.Events) {
|
|
62
|
+
eventResults = await context.Events.emitBlocking("file:post-edit", {
|
|
63
|
+
filePath,
|
|
64
|
+
operation: "ast-edit-node",
|
|
65
|
+
content: newContent,
|
|
66
|
+
originalContent,
|
|
67
|
+
updatedContent,
|
|
68
|
+
astPath: path,
|
|
69
|
+
success: true,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const result = {
|
|
74
|
+
file: filePath,
|
|
75
|
+
path,
|
|
76
|
+
action: "update",
|
|
77
|
+
success: true,
|
|
78
|
+
message: `Successfully updated node at path: ${path}`,
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
// Format event results
|
|
82
|
+
let eventResultsText = "";
|
|
83
|
+
if (eventResults && eventResults.length > 0) {
|
|
84
|
+
eventResultsText =
|
|
85
|
+
"\n\nAdditional Information:\n" +
|
|
86
|
+
JSON.stringify(eventResults, null, 2);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return JSON.stringify(result, null, 2) + eventResultsText;
|
|
90
|
+
} catch (error: any) {
|
|
91
|
+
// Do NOT emit post-edit event on error
|
|
92
|
+
|
|
93
|
+
throw new Error(`Failed to edit node in ${filePath}: ${error.message}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import { fileExists } from "../../../utils";
|
|
3
|
+
import { services, ToolsService } from "../../../services";
|
|
4
|
+
import { LanguageAgnosticParser } from "../../../plugins/tree-sitter/parser";
|
|
5
|
+
import { TreeEditor } from "../../../plugins/tree-sitter/editor";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Get the AST path for a specific line of text in a file using tree-sitter parsing
|
|
9
|
+
*/
|
|
10
|
+
export async function astGetPathForLine(
|
|
11
|
+
filePath: string,
|
|
12
|
+
searchText: string
|
|
13
|
+
): Promise<string> {
|
|
14
|
+
// Get context from bound ToolsService
|
|
15
|
+
const toolService = (
|
|
16
|
+
this instanceof ToolsService ? this : services().Tools
|
|
17
|
+
) as ToolsService;
|
|
18
|
+
|
|
19
|
+
const context = toolService.getContext();
|
|
20
|
+
|
|
21
|
+
// Emit pre-action event
|
|
22
|
+
if (context.Events) {
|
|
23
|
+
await context.Events.emitBlocking("ast:pre-get-path-for-line", {
|
|
24
|
+
filePath,
|
|
25
|
+
searchText,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const exists = await fileExists(filePath);
|
|
30
|
+
if (!exists) {
|
|
31
|
+
throw new Error(`File not found: ${filePath}`);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
try {
|
|
35
|
+
const content = fs.readFileSync(filePath, "utf8");
|
|
36
|
+
|
|
37
|
+
if (!LanguageAgnosticParser.supportsFile(filePath)) {
|
|
38
|
+
throw new Error(`Unsupported file type for AST parsing: ${filePath}`);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const parser = LanguageAgnosticParser.createParserForFile(filePath);
|
|
42
|
+
const tree = parser.parseString(content);
|
|
43
|
+
const pathLocations = parser.findPathsForLine(tree, searchText);
|
|
44
|
+
|
|
45
|
+
// Emit post-action event
|
|
46
|
+
if (context.Events) {
|
|
47
|
+
await context.Events.emitNonBlocking("ast:post-get-path-for-line", {
|
|
48
|
+
filePath,
|
|
49
|
+
searchText,
|
|
50
|
+
pathCount: pathLocations.length,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const result = {
|
|
55
|
+
file: filePath,
|
|
56
|
+
searchText,
|
|
57
|
+
language: parser.getLanguage(),
|
|
58
|
+
totalMatches: pathLocations.length,
|
|
59
|
+
matches: pathLocations.map((loc) => ({
|
|
60
|
+
path: loc.path,
|
|
61
|
+
line: loc.row + 1, // Convert from 0-based to 1-based line numbering
|
|
62
|
+
column: loc.column + 1, // Convert from 0-based to 1-based column numbering
|
|
63
|
+
text: loc.text,
|
|
64
|
+
})),
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
return JSON.stringify(result, null, 2);
|
|
68
|
+
} catch (error: any) {
|
|
69
|
+
throw new Error(
|
|
70
|
+
`Failed to get path for line in ${filePath}: ${error.message}`
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
}
|