distill-mcp 0.6.0-beta
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/bin/cli.js +133 -0
- package/dist/analytics/session-tracker.d.ts +74 -0
- package/dist/analytics/session-tracker.d.ts.map +1 -0
- package/dist/analytics/session-tracker.js +123 -0
- package/dist/ast/benchmark.test.d.ts +7 -0
- package/dist/ast/benchmark.test.d.ts.map +1 -0
- package/dist/ast/benchmark.test.js +175 -0
- package/dist/ast/go/index.d.ts +9 -0
- package/dist/ast/go/index.d.ts.map +1 -0
- package/dist/ast/go/index.js +8 -0
- package/dist/ast/go/parser.d.ts +31 -0
- package/dist/ast/go/parser.d.ts.map +1 -0
- package/dist/ast/go/parser.js +428 -0
- package/dist/ast/go/parser.test.d.ts +5 -0
- package/dist/ast/go/parser.test.d.ts.map +1 -0
- package/dist/ast/go/parser.test.js +241 -0
- package/dist/ast/go/queries.d.ts +51 -0
- package/dist/ast/go/queries.d.ts.map +1 -0
- package/dist/ast/go/queries.js +114 -0
- package/dist/ast/go/utils.d.ts +66 -0
- package/dist/ast/go/utils.d.ts.map +1 -0
- package/dist/ast/go/utils.js +140 -0
- package/dist/ast/index.d.ts +39 -0
- package/dist/ast/index.d.ts.map +1 -0
- package/dist/ast/index.js +245 -0
- package/dist/ast/php/index.d.ts +9 -0
- package/dist/ast/php/index.d.ts.map +1 -0
- package/dist/ast/php/index.js +8 -0
- package/dist/ast/php/parser.d.ts +31 -0
- package/dist/ast/php/parser.d.ts.map +1 -0
- package/dist/ast/php/parser.js +388 -0
- package/dist/ast/php/parser.test.d.ts +5 -0
- package/dist/ast/php/parser.test.d.ts.map +1 -0
- package/dist/ast/php/parser.test.js +328 -0
- package/dist/ast/php/queries.d.ts +61 -0
- package/dist/ast/php/queries.d.ts.map +1 -0
- package/dist/ast/php/queries.js +117 -0
- package/dist/ast/php/utils.d.ts +83 -0
- package/dist/ast/php/utils.d.ts.map +1 -0
- package/dist/ast/php/utils.js +246 -0
- package/dist/ast/python/index.d.ts +9 -0
- package/dist/ast/python/index.d.ts.map +1 -0
- package/dist/ast/python/index.js +8 -0
- package/dist/ast/python/parser.d.ts +32 -0
- package/dist/ast/python/parser.d.ts.map +1 -0
- package/dist/ast/python/parser.js +422 -0
- package/dist/ast/python/parser.test.d.ts +5 -0
- package/dist/ast/python/parser.test.d.ts.map +1 -0
- package/dist/ast/python/parser.test.js +186 -0
- package/dist/ast/python/queries.d.ts +73 -0
- package/dist/ast/python/queries.d.ts.map +1 -0
- package/dist/ast/python/queries.js +137 -0
- package/dist/ast/python/utils.d.ts +63 -0
- package/dist/ast/python/utils.d.ts.map +1 -0
- package/dist/ast/python/utils.js +159 -0
- package/dist/ast/quick-scan.d.ts +40 -0
- package/dist/ast/quick-scan.d.ts.map +1 -0
- package/dist/ast/quick-scan.js +287 -0
- package/dist/ast/rust/index.d.ts +9 -0
- package/dist/ast/rust/index.d.ts.map +1 -0
- package/dist/ast/rust/index.js +8 -0
- package/dist/ast/rust/parser.d.ts +31 -0
- package/dist/ast/rust/parser.d.ts.map +1 -0
- package/dist/ast/rust/parser.js +416 -0
- package/dist/ast/rust/parser.test.d.ts +5 -0
- package/dist/ast/rust/parser.test.d.ts.map +1 -0
- package/dist/ast/rust/parser.test.js +329 -0
- package/dist/ast/rust/queries.d.ts +66 -0
- package/dist/ast/rust/queries.d.ts.map +1 -0
- package/dist/ast/rust/queries.js +132 -0
- package/dist/ast/rust/utils.d.ts +91 -0
- package/dist/ast/rust/utils.d.ts.map +1 -0
- package/dist/ast/rust/utils.js +254 -0
- package/dist/ast/swift/index.d.ts +10 -0
- package/dist/ast/swift/index.d.ts.map +1 -0
- package/dist/ast/swift/index.js +8 -0
- package/dist/ast/swift/parser.d.ts +31 -0
- package/dist/ast/swift/parser.d.ts.map +1 -0
- package/dist/ast/swift/parser.js +554 -0
- package/dist/ast/swift/parser.test.d.ts +5 -0
- package/dist/ast/swift/parser.test.d.ts.map +1 -0
- package/dist/ast/swift/parser.test.js +398 -0
- package/dist/ast/swift/queries.d.ts +71 -0
- package/dist/ast/swift/queries.d.ts.map +1 -0
- package/dist/ast/swift/queries.js +137 -0
- package/dist/ast/swift/utils.d.ts +94 -0
- package/dist/ast/swift/utils.d.ts.map +1 -0
- package/dist/ast/swift/utils.js +411 -0
- package/dist/ast/types.d.ts +96 -0
- package/dist/ast/types.d.ts.map +1 -0
- package/dist/ast/types.js +21 -0
- package/dist/ast/typescript.d.ts +24 -0
- package/dist/ast/typescript.d.ts.map +1 -0
- package/dist/ast/typescript.js +357 -0
- package/dist/cache/file-hash.d.ts +33 -0
- package/dist/cache/file-hash.d.ts.map +1 -0
- package/dist/cache/file-hash.js +59 -0
- package/dist/cache/index.d.ts +9 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +8 -0
- package/dist/cache/smart-cache.d.ts +68 -0
- package/dist/cache/smart-cache.d.ts.map +1 -0
- package/dist/cache/smart-cache.js +266 -0
- package/dist/cache/types.d.ts +102 -0
- package/dist/cache/types.d.ts.map +1 -0
- package/dist/cache/types.js +6 -0
- package/dist/cli/analyze.d.ts +43 -0
- package/dist/cli/analyze.d.ts.map +1 -0
- package/dist/cli/analyze.js +250 -0
- package/dist/cli/doctor.d.ts +2 -0
- package/dist/cli/doctor.d.ts.map +1 -0
- package/dist/cli/doctor.js +127 -0
- package/dist/cli/hooks.d.ts +14 -0
- package/dist/cli/hooks.d.ts.map +1 -0
- package/dist/cli/hooks.js +229 -0
- package/dist/cli/index.d.ts +5 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +4 -0
- package/dist/cli/setup.d.ts +10 -0
- package/dist/cli/setup.d.ts.map +1 -0
- package/dist/cli/setup.js +117 -0
- package/dist/cli/utils.d.ts +30 -0
- package/dist/cli/utils.d.ts.map +1 -0
- package/dist/cli/utils.js +116 -0
- package/dist/compressors/config.d.ts +9 -0
- package/dist/compressors/config.d.ts.map +1 -0
- package/dist/compressors/config.js +183 -0
- package/dist/compressors/conversation.d.ts +109 -0
- package/dist/compressors/conversation.d.ts.map +1 -0
- package/dist/compressors/conversation.js +404 -0
- package/dist/compressors/diff.d.ts +35 -0
- package/dist/compressors/diff.d.ts.map +1 -0
- package/dist/compressors/diff.js +389 -0
- package/dist/compressors/generic.d.ts +9 -0
- package/dist/compressors/generic.d.ts.map +1 -0
- package/dist/compressors/generic.js +188 -0
- package/dist/compressors/index.d.ts +31 -0
- package/dist/compressors/index.d.ts.map +1 -0
- package/dist/compressors/index.js +82 -0
- package/dist/compressors/logs.d.ts +9 -0
- package/dist/compressors/logs.d.ts.map +1 -0
- package/dist/compressors/logs.js +245 -0
- package/dist/compressors/multifile.d.ts +106 -0
- package/dist/compressors/multifile.d.ts.map +1 -0
- package/dist/compressors/multifile.js +498 -0
- package/dist/compressors/semantic.d.ts +33 -0
- package/dist/compressors/semantic.d.ts.map +1 -0
- package/dist/compressors/semantic.js +233 -0
- package/dist/compressors/stacktrace.d.ts +9 -0
- package/dist/compressors/stacktrace.d.ts.map +1 -0
- package/dist/compressors/stacktrace.js +259 -0
- package/dist/compressors/types.d.ts +146 -0
- package/dist/compressors/types.d.ts.map +1 -0
- package/dist/compressors/types.js +6 -0
- package/dist/config/output-config.d.ts +56 -0
- package/dist/config/output-config.d.ts.map +1 -0
- package/dist/config/output-config.js +78 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +27 -0
- package/dist/middleware/chain.d.ts +49 -0
- package/dist/middleware/chain.d.ts.map +1 -0
- package/dist/middleware/chain.js +126 -0
- package/dist/middleware/index.d.ts +4 -0
- package/dist/middleware/index.d.ts.map +1 -0
- package/dist/middleware/index.js +3 -0
- package/dist/middleware/logging.d.ts +8 -0
- package/dist/middleware/logging.d.ts.map +1 -0
- package/dist/middleware/logging.js +71 -0
- package/dist/middleware/types.d.ts +58 -0
- package/dist/middleware/types.d.ts.map +1 -0
- package/dist/middleware/types.js +7 -0
- package/dist/parsers/eslint.d.ts +8 -0
- package/dist/parsers/eslint.d.ts.map +1 -0
- package/dist/parsers/eslint.js +132 -0
- package/dist/parsers/generic.d.ts +8 -0
- package/dist/parsers/generic.d.ts.map +1 -0
- package/dist/parsers/generic.js +234 -0
- package/dist/parsers/index.d.ts +34 -0
- package/dist/parsers/index.d.ts.map +1 -0
- package/dist/parsers/index.js +216 -0
- package/dist/parsers/types.d.ts +84 -0
- package/dist/parsers/types.d.ts.map +1 -0
- package/dist/parsers/types.js +6 -0
- package/dist/parsers/typescript.d.ts +8 -0
- package/dist/parsers/typescript.d.ts.map +1 -0
- package/dist/parsers/typescript.js +107 -0
- package/dist/pipelines/definitions.d.ts +50 -0
- package/dist/pipelines/definitions.d.ts.map +1 -0
- package/dist/pipelines/definitions.js +206 -0
- package/dist/sandbox/executor.d.ts +12 -0
- package/dist/sandbox/executor.d.ts.map +1 -0
- package/dist/sandbox/executor.js +191 -0
- package/dist/sandbox/index.d.ts +11 -0
- package/dist/sandbox/index.d.ts.map +1 -0
- package/dist/sandbox/index.js +9 -0
- package/dist/sandbox/sandbox.test.d.ts +7 -0
- package/dist/sandbox/sandbox.test.d.ts.map +1 -0
- package/dist/sandbox/sandbox.test.js +202 -0
- package/dist/sandbox/sdk/analyze.d.ts +36 -0
- package/dist/sandbox/sdk/analyze.d.ts.map +1 -0
- package/dist/sandbox/sdk/analyze.js +413 -0
- package/dist/sandbox/sdk/analyze.test.d.ts +7 -0
- package/dist/sandbox/sdk/analyze.test.d.ts.map +1 -0
- package/dist/sandbox/sdk/analyze.test.js +191 -0
- package/dist/sandbox/sdk/code.d.ts +20 -0
- package/dist/sandbox/sdk/code.d.ts.map +1 -0
- package/dist/sandbox/sdk/code.js +104 -0
- package/dist/sandbox/sdk/compress.d.ts +23 -0
- package/dist/sandbox/sdk/compress.d.ts.map +1 -0
- package/dist/sandbox/sdk/compress.js +107 -0
- package/dist/sandbox/sdk/conversation.d.ts +148 -0
- package/dist/sandbox/sdk/conversation.d.ts.map +1 -0
- package/dist/sandbox/sdk/conversation.js +177 -0
- package/dist/sandbox/sdk/files.d.ts +29 -0
- package/dist/sandbox/sdk/files.d.ts.map +1 -0
- package/dist/sandbox/sdk/files.js +41 -0
- package/dist/sandbox/sdk/git.d.ts +37 -0
- package/dist/sandbox/sdk/git.d.ts.map +1 -0
- package/dist/sandbox/sdk/git.js +313 -0
- package/dist/sandbox/sdk/git.test.d.ts +8 -0
- package/dist/sandbox/sdk/git.test.d.ts.map +1 -0
- package/dist/sandbox/sdk/git.test.js +160 -0
- package/dist/sandbox/sdk/index.d.ts +16 -0
- package/dist/sandbox/sdk/index.d.ts.map +1 -0
- package/dist/sandbox/sdk/index.js +15 -0
- package/dist/sandbox/sdk/multifile.d.ts +63 -0
- package/dist/sandbox/sdk/multifile.d.ts.map +1 -0
- package/dist/sandbox/sdk/multifile.js +130 -0
- package/dist/sandbox/sdk/pipeline.d.ts +16 -0
- package/dist/sandbox/sdk/pipeline.d.ts.map +1 -0
- package/dist/sandbox/sdk/pipeline.js +454 -0
- package/dist/sandbox/sdk/pipeline.test.d.ts +7 -0
- package/dist/sandbox/sdk/pipeline.test.d.ts.map +1 -0
- package/dist/sandbox/sdk/pipeline.test.js +197 -0
- package/dist/sandbox/sdk/search.d.ts +36 -0
- package/dist/sandbox/sdk/search.d.ts.map +1 -0
- package/dist/sandbox/sdk/search.js +338 -0
- package/dist/sandbox/sdk/search.test.d.ts +7 -0
- package/dist/sandbox/sdk/search.test.d.ts.map +1 -0
- package/dist/sandbox/sdk/search.test.js +183 -0
- package/dist/sandbox/sdk/utils.d.ts +18 -0
- package/dist/sandbox/sdk/utils.d.ts.map +1 -0
- package/dist/sandbox/sdk/utils.js +24 -0
- package/dist/sandbox/security/code-analyzer.d.ts +15 -0
- package/dist/sandbox/security/code-analyzer.d.ts.map +1 -0
- package/dist/sandbox/security/code-analyzer.js +87 -0
- package/dist/sandbox/security/index.d.ts +6 -0
- package/dist/sandbox/security/index.d.ts.map +1 -0
- package/dist/sandbox/security/index.js +5 -0
- package/dist/sandbox/security/path-validator.d.ts +23 -0
- package/dist/sandbox/security/path-validator.d.ts.map +1 -0
- package/dist/sandbox/security/path-validator.js +113 -0
- package/dist/sandbox/types.d.ts +577 -0
- package/dist/sandbox/types.d.ts.map +1 -0
- package/dist/sandbox/types.js +14 -0
- package/dist/server.d.ts +36 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +133 -0
- package/dist/summarizers/build-logs.d.ts +11 -0
- package/dist/summarizers/build-logs.d.ts.map +1 -0
- package/dist/summarizers/build-logs.js +234 -0
- package/dist/summarizers/generic.d.ts +11 -0
- package/dist/summarizers/generic.d.ts.map +1 -0
- package/dist/summarizers/generic.js +93 -0
- package/dist/summarizers/index.d.ts +20 -0
- package/dist/summarizers/index.d.ts.map +1 -0
- package/dist/summarizers/index.js +43 -0
- package/dist/summarizers/server-logs.d.ts +11 -0
- package/dist/summarizers/server-logs.d.ts.map +1 -0
- package/dist/summarizers/server-logs.js +215 -0
- package/dist/summarizers/test-logs.d.ts +11 -0
- package/dist/summarizers/test-logs.d.ts.map +1 -0
- package/dist/summarizers/test-logs.js +258 -0
- package/dist/summarizers/types.d.ts +146 -0
- package/dist/summarizers/types.d.ts.map +1 -0
- package/dist/summarizers/types.js +21 -0
- package/dist/tools/analyze-build-output.d.ts +30 -0
- package/dist/tools/analyze-build-output.d.ts.map +1 -0
- package/dist/tools/analyze-build-output.js +45 -0
- package/dist/tools/analyze-context.d.ts +23 -0
- package/dist/tools/analyze-context.d.ts.map +1 -0
- package/dist/tools/analyze-context.js +78 -0
- package/dist/tools/auto-optimize.d.ts +9 -0
- package/dist/tools/auto-optimize.d.ts.map +1 -0
- package/dist/tools/auto-optimize.js +191 -0
- package/dist/tools/code-execute.d.ts +9 -0
- package/dist/tools/code-execute.d.ts.map +1 -0
- package/dist/tools/code-execute.js +84 -0
- package/dist/tools/code-skeleton.d.ts +33 -0
- package/dist/tools/code-skeleton.d.ts.map +1 -0
- package/dist/tools/code-skeleton.js +206 -0
- package/dist/tools/compress-context.d.ts +33 -0
- package/dist/tools/compress-context.d.ts.map +1 -0
- package/dist/tools/compress-context.js +64 -0
- package/dist/tools/context-budget.d.ts +43 -0
- package/dist/tools/context-budget.d.ts.map +1 -0
- package/dist/tools/context-budget.js +260 -0
- package/dist/tools/context-budget.test.d.ts +5 -0
- package/dist/tools/context-budget.test.d.ts.map +1 -0
- package/dist/tools/context-budget.test.js +219 -0
- package/dist/tools/conversation-compress.d.ts +46 -0
- package/dist/tools/conversation-compress.d.ts.map +1 -0
- package/dist/tools/conversation-compress.js +78 -0
- package/dist/tools/conversation-memory.d.ts +75 -0
- package/dist/tools/conversation-memory.d.ts.map +1 -0
- package/dist/tools/conversation-memory.js +289 -0
- package/dist/tools/deduplicate-errors.d.ts +30 -0
- package/dist/tools/deduplicate-errors.d.ts.map +1 -0
- package/dist/tools/deduplicate-errors.js +72 -0
- package/dist/tools/detect-retry-loop.d.ts +40 -0
- package/dist/tools/detect-retry-loop.d.ts.map +1 -0
- package/dist/tools/detect-retry-loop.js +212 -0
- package/dist/tools/diff-compress.d.ts +40 -0
- package/dist/tools/diff-compress.d.ts.map +1 -0
- package/dist/tools/diff-compress.js +94 -0
- package/dist/tools/discover-tools.d.ts +11 -0
- package/dist/tools/discover-tools.d.ts.map +1 -0
- package/dist/tools/discover-tools.js +163 -0
- package/dist/tools/dynamic-loader.d.ts +131 -0
- package/dist/tools/dynamic-loader.d.ts.map +1 -0
- package/dist/tools/dynamic-loader.js +378 -0
- package/dist/tools/dynamic-loader.test.d.ts +10 -0
- package/dist/tools/dynamic-loader.test.d.ts.map +1 -0
- package/dist/tools/dynamic-loader.test.js +164 -0
- package/dist/tools/lazy-mcp.d.ts +31 -0
- package/dist/tools/lazy-mcp.d.ts.map +1 -0
- package/dist/tools/lazy-mcp.js +151 -0
- package/dist/tools/lazy-mcp.test.d.ts +10 -0
- package/dist/tools/lazy-mcp.test.d.ts.map +1 -0
- package/dist/tools/lazy-mcp.test.js +172 -0
- package/dist/tools/multifile-compress.d.ts +36 -0
- package/dist/tools/multifile-compress.d.ts.map +1 -0
- package/dist/tools/multifile-compress.js +223 -0
- package/dist/tools/optimization-tips.d.ts +18 -0
- package/dist/tools/optimization-tips.d.ts.map +1 -0
- package/dist/tools/optimization-tips.js +133 -0
- package/dist/tools/registry.d.ts +70 -0
- package/dist/tools/registry.d.ts.map +1 -0
- package/dist/tools/registry.js +169 -0
- package/dist/tools/semantic-compress.d.ts +39 -0
- package/dist/tools/semantic-compress.d.ts.map +1 -0
- package/dist/tools/semantic-compress.js +113 -0
- package/dist/tools/semantic-compress.test.d.ts +5 -0
- package/dist/tools/semantic-compress.test.d.ts.map +1 -0
- package/dist/tools/semantic-compress.test.js +182 -0
- package/dist/tools/session-stats.d.ts +34 -0
- package/dist/tools/session-stats.d.ts.map +1 -0
- package/dist/tools/session-stats.js +194 -0
- package/dist/tools/set-output-config.d.ts +38 -0
- package/dist/tools/set-output-config.d.ts.map +1 -0
- package/dist/tools/set-output-config.js +122 -0
- package/dist/tools/smart-cache-tool.d.ts +38 -0
- package/dist/tools/smart-cache-tool.d.ts.map +1 -0
- package/dist/tools/smart-cache-tool.js +224 -0
- package/dist/tools/smart-file-read.d.ts +52 -0
- package/dist/tools/smart-file-read.d.ts.map +1 -0
- package/dist/tools/smart-file-read.js +481 -0
- package/dist/tools/smart-pipeline.d.ts +40 -0
- package/dist/tools/smart-pipeline.d.ts.map +1 -0
- package/dist/tools/smart-pipeline.js +295 -0
- package/dist/tools/summarize-logs.d.ts +36 -0
- package/dist/tools/summarize-logs.d.ts.map +1 -0
- package/dist/tools/summarize-logs.js +184 -0
- package/dist/tools/token-budget.test.d.ts +11 -0
- package/dist/tools/token-budget.test.d.ts.map +1 -0
- package/dist/tools/token-budget.test.js +275 -0
- package/dist/utils/bm25.d.ts +86 -0
- package/dist/utils/bm25.d.ts.map +1 -0
- package/dist/utils/bm25.js +153 -0
- package/dist/utils/bm25.test.d.ts +5 -0
- package/dist/utils/bm25.test.d.ts.map +1 -0
- package/dist/utils/bm25.test.js +156 -0
- package/dist/utils/command-normalizer.d.ts +39 -0
- package/dist/utils/command-normalizer.d.ts.map +1 -0
- package/dist/utils/command-normalizer.js +90 -0
- package/dist/utils/content-detector.d.ts +27 -0
- package/dist/utils/content-detector.d.ts.map +1 -0
- package/dist/utils/content-detector.js +127 -0
- package/dist/utils/embeddings.d.ts +54 -0
- package/dist/utils/embeddings.d.ts.map +1 -0
- package/dist/utils/embeddings.js +97 -0
- package/dist/utils/embeddings.test.d.ts +8 -0
- package/dist/utils/embeddings.test.d.ts.map +1 -0
- package/dist/utils/embeddings.test.js +96 -0
- package/dist/utils/error-normalizer.d.ts +39 -0
- package/dist/utils/error-normalizer.d.ts.map +1 -0
- package/dist/utils/error-normalizer.js +233 -0
- package/dist/utils/hybrid-search.d.ts +79 -0
- package/dist/utils/hybrid-search.d.ts.map +1 -0
- package/dist/utils/hybrid-search.js +146 -0
- package/dist/utils/hybrid-search.test.d.ts +5 -0
- package/dist/utils/hybrid-search.test.d.ts.map +1 -0
- package/dist/utils/hybrid-search.test.js +172 -0
- package/dist/utils/index.d.ts +13 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +12 -0
- package/dist/utils/language-detector.d.ts +27 -0
- package/dist/utils/language-detector.d.ts.map +1 -0
- package/dist/utils/language-detector.js +94 -0
- package/dist/utils/log-parser.d.ts +46 -0
- package/dist/utils/log-parser.d.ts.map +1 -0
- package/dist/utils/log-parser.js +287 -0
- package/dist/utils/output-estimator.d.ts +54 -0
- package/dist/utils/output-estimator.d.ts.map +1 -0
- package/dist/utils/output-estimator.js +119 -0
- package/dist/utils/output-estimator.test.d.ts +5 -0
- package/dist/utils/output-estimator.test.d.ts.map +1 -0
- package/dist/utils/output-estimator.test.js +115 -0
- package/dist/utils/output-similarity.d.ts +48 -0
- package/dist/utils/output-similarity.d.ts.map +1 -0
- package/dist/utils/output-similarity.js +140 -0
- package/dist/utils/project-detector.d.ts +16 -0
- package/dist/utils/project-detector.d.ts.map +1 -0
- package/dist/utils/project-detector.js +119 -0
- package/dist/utils/segment-scorer.d.ts +99 -0
- package/dist/utils/segment-scorer.d.ts.map +1 -0
- package/dist/utils/segment-scorer.js +148 -0
- package/dist/utils/signature-grouper.d.ts +58 -0
- package/dist/utils/signature-grouper.d.ts.map +1 -0
- package/dist/utils/signature-grouper.js +185 -0
- package/dist/utils/tfidf.d.ts +45 -0
- package/dist/utils/tfidf.d.ts.map +1 -0
- package/dist/utils/tfidf.js +204 -0
- package/dist/utils/tfidf.test.d.ts +5 -0
- package/dist/utils/tfidf.test.d.ts.map +1 -0
- package/dist/utils/tfidf.test.js +115 -0
- package/dist/utils/token-counter.d.ts +35 -0
- package/dist/utils/token-counter.d.ts.map +1 -0
- package/dist/utils/token-counter.js +83 -0
- package/dist/utils/toon-serializer.d.ts +120 -0
- package/dist/utils/toon-serializer.d.ts.map +1 -0
- package/dist/utils/toon-serializer.js +472 -0
- package/dist/utils/toon-serializer.test.d.ts +7 -0
- package/dist/utils/toon-serializer.test.d.ts.map +1 -0
- package/dist/utils/toon-serializer.test.js +290 -0
- package/package.json +63 -0
- package/scripts/install.ps1 +133 -0
- package/scripts/install.sh +183 -0
- package/scripts/pre-commit-hook.sh +86 -0
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dynamic Tool Loader
|
|
3
|
+
*
|
|
4
|
+
* Manages lazy loading of MCP tools to reduce token consumption.
|
|
5
|
+
* Only core tools are loaded at startup; others are loaded on-demand.
|
|
6
|
+
*/
|
|
7
|
+
import { createBM25Index } from "../utils/bm25.js";
|
|
8
|
+
import { createHybridSearchIndex, } from "../utils/hybrid-search.js";
|
|
9
|
+
/**
|
|
10
|
+
* Tool catalog with metadata for discovery
|
|
11
|
+
* Full tool definitions are loaded lazily via the loader function
|
|
12
|
+
*/
|
|
13
|
+
export const TOOL_CATALOG = [
|
|
14
|
+
// Core tools (always loaded)
|
|
15
|
+
{
|
|
16
|
+
name: "auto_optimize",
|
|
17
|
+
category: "core",
|
|
18
|
+
keywords: ["optimize", "auto", "detect", "compress"],
|
|
19
|
+
description: "Auto-detect content type and apply optimal compression",
|
|
20
|
+
loader: async () => (await import("./auto-optimize.js")).autoOptimizeTool,
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
name: "smart_file_read",
|
|
24
|
+
category: "core",
|
|
25
|
+
keywords: ["file", "read", "ast", "code", "extract"],
|
|
26
|
+
description: "Read files with AST-based extraction",
|
|
27
|
+
loader: async () => (await import("./smart-file-read.js")).smartFileReadTool,
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: "code_execute",
|
|
31
|
+
category: "core",
|
|
32
|
+
keywords: ["execute", "code", "sdk", "typescript", "script", "sandbox"],
|
|
33
|
+
description: "Execute TypeScript with ctxopt SDK (98% token savings)",
|
|
34
|
+
loader: async () => (await import("./code-execute.js")).codeExecuteTool,
|
|
35
|
+
},
|
|
36
|
+
// Compress category
|
|
37
|
+
{
|
|
38
|
+
name: "compress_context",
|
|
39
|
+
category: "compress",
|
|
40
|
+
keywords: ["compress", "context", "reduce", "shrink", "generic"],
|
|
41
|
+
description: "Compress generic text content (logs, configs)",
|
|
42
|
+
loader: async () => (await import("./compress-context.js")).compressContextTool,
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
name: "semantic_compress",
|
|
46
|
+
category: "compress",
|
|
47
|
+
keywords: ["semantic", "compress", "tfidf", "importance"],
|
|
48
|
+
description: "TF-IDF based semantic compression",
|
|
49
|
+
loader: async () => (await import("./semantic-compress.js")).semanticCompressTool,
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
name: "diff_compress",
|
|
53
|
+
category: "compress",
|
|
54
|
+
keywords: ["diff", "git", "compress", "changes"],
|
|
55
|
+
description: "Compress git diff output",
|
|
56
|
+
loader: async () => (await import("./diff-compress.js")).diffCompressTool,
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
name: "conversation_compress",
|
|
60
|
+
category: "compress",
|
|
61
|
+
keywords: ["conversation", "chat", "history", "compress", "messages"],
|
|
62
|
+
description: "Compress conversation history",
|
|
63
|
+
loader: async () => (await import("./conversation-compress.js")).conversationCompressTool,
|
|
64
|
+
},
|
|
65
|
+
// Analyze category
|
|
66
|
+
{
|
|
67
|
+
name: "analyze_context",
|
|
68
|
+
category: "analyze",
|
|
69
|
+
keywords: ["analyze", "context", "tokens", "cost", "estimate"],
|
|
70
|
+
description: "Analyze prompt for token usage and cost",
|
|
71
|
+
loader: async () => {
|
|
72
|
+
const mod = await import("./analyze-context.js");
|
|
73
|
+
return {
|
|
74
|
+
name: "analyze_context",
|
|
75
|
+
description: "Analyze a prompt or context for token usage and optimization opportunities.",
|
|
76
|
+
inputSchema: mod.analyzeContextSchema,
|
|
77
|
+
execute: async (args) => mod.analyzeContext(args, {}),
|
|
78
|
+
};
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
name: "analyze_build_output",
|
|
83
|
+
category: "analyze",
|
|
84
|
+
keywords: ["build", "error", "typescript", "eslint", "webpack", "compile"],
|
|
85
|
+
description: "Parse and compress build errors",
|
|
86
|
+
loader: async () => (await import("./analyze-build-output.js")).analyzeBuildOutputTool,
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
name: "context_budget",
|
|
90
|
+
category: "analyze",
|
|
91
|
+
keywords: ["budget", "tokens", "limit", "estimate", "cost"],
|
|
92
|
+
description: "Pre-flight token budget estimation",
|
|
93
|
+
loader: async () => (await import("./context-budget.js")).contextBudgetTool,
|
|
94
|
+
},
|
|
95
|
+
// Logs category
|
|
96
|
+
{
|
|
97
|
+
name: "summarize_logs",
|
|
98
|
+
category: "logs",
|
|
99
|
+
keywords: ["logs", "summarize", "server", "test", "output"],
|
|
100
|
+
description: "Summarize verbose log output",
|
|
101
|
+
loader: async () => (await import("./summarize-logs.js")).summarizeLogsTool,
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
name: "deduplicate_errors",
|
|
105
|
+
category: "logs",
|
|
106
|
+
keywords: ["deduplicate", "errors", "group", "repeat"],
|
|
107
|
+
description: "Group and deduplicate repeated errors",
|
|
108
|
+
loader: async () => (await import("./deduplicate-errors.js")).deduplicateErrorsTool,
|
|
109
|
+
},
|
|
110
|
+
// Code category
|
|
111
|
+
{
|
|
112
|
+
name: "code_skeleton",
|
|
113
|
+
category: "code",
|
|
114
|
+
keywords: ["skeleton", "signatures", "code", "structure", "overview"],
|
|
115
|
+
description: "Extract function/class signatures only",
|
|
116
|
+
loader: async () => (await import("./code-skeleton.js")).codeSkeletonTool,
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
name: "smart_cache",
|
|
120
|
+
category: "code",
|
|
121
|
+
keywords: ["cache", "store", "retrieve", "invalidate"],
|
|
122
|
+
description: "Manage parsed file cache",
|
|
123
|
+
loader: async () => (await import("./smart-cache-tool.js")).smartCacheTool,
|
|
124
|
+
},
|
|
125
|
+
// Pipeline category
|
|
126
|
+
{
|
|
127
|
+
name: "smart_pipeline",
|
|
128
|
+
category: "pipeline",
|
|
129
|
+
keywords: ["pipeline", "chain", "auto", "multi-step"],
|
|
130
|
+
description: "Chain multiple compression tools automatically",
|
|
131
|
+
loader: async () => (await import("./smart-pipeline.js")).smartPipelineTool,
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
name: "optimization_tips",
|
|
135
|
+
category: "pipeline",
|
|
136
|
+
keywords: ["tips", "best-practices", "optimize", "help"],
|
|
137
|
+
description: "Get context optimization best practices",
|
|
138
|
+
loader: async () => {
|
|
139
|
+
const mod = await import("./optimization-tips.js");
|
|
140
|
+
return {
|
|
141
|
+
name: "optimization_tips",
|
|
142
|
+
description: "Get context engineering best practices and optimization tips.",
|
|
143
|
+
inputSchema: mod.optimizationTipsSchema,
|
|
144
|
+
execute: async (args) => mod.optimizationTips(args, {}),
|
|
145
|
+
};
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
// Intelligence layer
|
|
149
|
+
{
|
|
150
|
+
name: "detect_retry_loop",
|
|
151
|
+
category: "analyze",
|
|
152
|
+
keywords: ["retry", "loop", "build", "test", "fail", "repeat", "stuck"],
|
|
153
|
+
description: "Detect retry loops in command history",
|
|
154
|
+
loader: async () => (await import("./detect-retry-loop.js")).detectRetryLoopTool,
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
name: "session_stats",
|
|
158
|
+
category: "core",
|
|
159
|
+
keywords: ["session", "stats", "statistics", "tokens", "saved", "analytics"],
|
|
160
|
+
description: "Get session-wide token savings and usage statistics",
|
|
161
|
+
loader: async () => (await import("./session-stats.js")).sessionStatsTool,
|
|
162
|
+
},
|
|
163
|
+
// Phase 6: Advanced Compression
|
|
164
|
+
{
|
|
165
|
+
name: "set_output_config",
|
|
166
|
+
category: "pipeline",
|
|
167
|
+
keywords: ["config", "output", "format", "toon", "verbosity", "settings"],
|
|
168
|
+
description: "Configure global output format and verbosity",
|
|
169
|
+
loader: async () => (await import("./set-output-config.js")).setOutputConfigTool,
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
name: "multifile_compress",
|
|
173
|
+
category: "compress",
|
|
174
|
+
keywords: ["multifile", "deduplicate", "shared", "imports", "types", "chunk", "context"],
|
|
175
|
+
description: "Compress multiple files with cross-file deduplication",
|
|
176
|
+
loader: async () => (await import("./multifile-compress.js")).multifileCompressTool,
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
name: "conversation_memory",
|
|
180
|
+
category: "compress",
|
|
181
|
+
keywords: ["conversation", "memory", "decisions", "restore", "context", "history"],
|
|
182
|
+
description: "Manage long conversation context with decision extraction",
|
|
183
|
+
loader: async () => (await import("./conversation-memory.js")).conversationMemoryTool,
|
|
184
|
+
},
|
|
185
|
+
];
|
|
186
|
+
/**
|
|
187
|
+
* Dynamic Tool Loader
|
|
188
|
+
*
|
|
189
|
+
* Manages tool loading and provides discovery capabilities.
|
|
190
|
+
*/
|
|
191
|
+
export class DynamicToolLoader {
|
|
192
|
+
loadedTools = new Map();
|
|
193
|
+
onChangeCallbacks = [];
|
|
194
|
+
bm25Index = null;
|
|
195
|
+
hybridIndex = null;
|
|
196
|
+
/**
|
|
197
|
+
* Get searchable text from tool metadata
|
|
198
|
+
*/
|
|
199
|
+
static getSearchableText(tool) {
|
|
200
|
+
return `${tool.name} ${tool.keywords.join(" ")} ${tool.description}`;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Get or create BM25 search index (lazy initialization)
|
|
204
|
+
*/
|
|
205
|
+
getBM25Index() {
|
|
206
|
+
if (!this.bm25Index) {
|
|
207
|
+
this.bm25Index = createBM25Index(TOOL_CATALOG, DynamicToolLoader.getSearchableText, { k1: 1.2, b: 0.75 });
|
|
208
|
+
}
|
|
209
|
+
return this.bm25Index;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Get or create hybrid search index (lazy initialization)
|
|
213
|
+
*/
|
|
214
|
+
getHybridIndex() {
|
|
215
|
+
if (!this.hybridIndex) {
|
|
216
|
+
this.hybridIndex = createHybridSearchIndex(TOOL_CATALOG, DynamicToolLoader.getSearchableText, { bm25Weight: 0.4, semanticWeight: 0.6 });
|
|
217
|
+
}
|
|
218
|
+
return this.hybridIndex;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Get metadata for all available tools (without loading them)
|
|
222
|
+
*/
|
|
223
|
+
getAvailableTools() {
|
|
224
|
+
return TOOL_CATALOG.map((t) => ({
|
|
225
|
+
name: t.name,
|
|
226
|
+
category: t.category,
|
|
227
|
+
description: t.description,
|
|
228
|
+
}));
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Search tools by query string using BM25 ranking
|
|
232
|
+
* Returns results sorted by relevance score (most relevant first)
|
|
233
|
+
*/
|
|
234
|
+
searchTools(query) {
|
|
235
|
+
const index = this.getBM25Index();
|
|
236
|
+
const results = index.search(query);
|
|
237
|
+
return results.map((r) => r.item);
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Search tools with BM25 scores and matched terms
|
|
241
|
+
* Useful for debugging or displaying search relevance
|
|
242
|
+
*/
|
|
243
|
+
searchToolsWithScores(query) {
|
|
244
|
+
const index = this.getBM25Index();
|
|
245
|
+
return index.search(query);
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Hybrid search combining BM25 (lexical) and semantic similarity
|
|
249
|
+
*
|
|
250
|
+
* This method finds tools even when the query uses different words
|
|
251
|
+
* than the tool description (e.g., "shrink output" → compress).
|
|
252
|
+
*
|
|
253
|
+
* @param query - Search query
|
|
254
|
+
* @returns Ranked results with both BM25 and semantic scores
|
|
255
|
+
*/
|
|
256
|
+
async searchToolsHybrid(query) {
|
|
257
|
+
const index = this.getHybridIndex();
|
|
258
|
+
return index.search(query);
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Preload semantic embeddings for faster hybrid search
|
|
262
|
+
*
|
|
263
|
+
* Call this during idle time to avoid latency on first hybrid search.
|
|
264
|
+
* The embedding model (~23MB) is downloaded and cached on first use.
|
|
265
|
+
*/
|
|
266
|
+
async preloadSemanticSearch() {
|
|
267
|
+
const index = this.getHybridIndex();
|
|
268
|
+
await index.precomputeEmbeddings();
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Check if semantic search is ready (embeddings loaded)
|
|
272
|
+
*/
|
|
273
|
+
isSemanticSearchReady() {
|
|
274
|
+
return this.hybridIndex?.isSemanticReady() ?? false;
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Get tools by category
|
|
278
|
+
*/
|
|
279
|
+
getToolsByCategory(category) {
|
|
280
|
+
return TOOL_CATALOG.filter((t) => t.category === category);
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Load core tools (called at startup)
|
|
284
|
+
*/
|
|
285
|
+
async loadCoreTools() {
|
|
286
|
+
const coreTools = TOOL_CATALOG.filter((t) => t.category === "core");
|
|
287
|
+
return this.loadToolsFromMetadata(coreTools);
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Load tools by category
|
|
291
|
+
*/
|
|
292
|
+
async loadByCategory(category) {
|
|
293
|
+
const tools = this.getToolsByCategory(category);
|
|
294
|
+
return this.loadToolsFromMetadata(tools);
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Load tools matching a query
|
|
298
|
+
*/
|
|
299
|
+
async loadByQuery(query) {
|
|
300
|
+
const tools = this.searchTools(query);
|
|
301
|
+
return this.loadToolsFromMetadata(tools);
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Load specific tools by name
|
|
305
|
+
*/
|
|
306
|
+
async loadByNames(names) {
|
|
307
|
+
const tools = TOOL_CATALOG.filter((t) => names.includes(t.name));
|
|
308
|
+
return this.loadToolsFromMetadata(tools);
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Load all tools (fallback for clients that don't support dynamic loading)
|
|
312
|
+
*/
|
|
313
|
+
async loadAllTools() {
|
|
314
|
+
return this.loadToolsFromMetadata(TOOL_CATALOG);
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Get already loaded tools
|
|
318
|
+
*/
|
|
319
|
+
getLoadedTools() {
|
|
320
|
+
return Array.from(this.loadedTools.values());
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Check if a tool is loaded
|
|
324
|
+
*/
|
|
325
|
+
isLoaded(name) {
|
|
326
|
+
return this.loadedTools.has(name);
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* Register callback for tool list changes
|
|
330
|
+
*/
|
|
331
|
+
onToolsChanged(callback) {
|
|
332
|
+
this.onChangeCallbacks.push(callback);
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Internal: Load tools from metadata array
|
|
336
|
+
*/
|
|
337
|
+
async loadToolsFromMetadata(metadata) {
|
|
338
|
+
const newlyLoaded = [];
|
|
339
|
+
for (const meta of metadata) {
|
|
340
|
+
if (!this.loadedTools.has(meta.name)) {
|
|
341
|
+
const tool = await meta.loader();
|
|
342
|
+
this.loadedTools.set(meta.name, tool);
|
|
343
|
+
newlyLoaded.push(tool);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
// Notify if new tools were loaded
|
|
347
|
+
if (newlyLoaded.length > 0) {
|
|
348
|
+
this.emitChange();
|
|
349
|
+
}
|
|
350
|
+
return newlyLoaded;
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* Emit change notification
|
|
354
|
+
*/
|
|
355
|
+
emitChange() {
|
|
356
|
+
for (const cb of this.onChangeCallbacks) {
|
|
357
|
+
try {
|
|
358
|
+
cb();
|
|
359
|
+
}
|
|
360
|
+
catch {
|
|
361
|
+
// Ignore callback errors
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Singleton instance
|
|
368
|
+
*/
|
|
369
|
+
let loaderInstance = null;
|
|
370
|
+
export function getDynamicLoader() {
|
|
371
|
+
if (!loaderInstance) {
|
|
372
|
+
loaderInstance = new DynamicToolLoader();
|
|
373
|
+
}
|
|
374
|
+
return loaderInstance;
|
|
375
|
+
}
|
|
376
|
+
export function resetDynamicLoader() {
|
|
377
|
+
loaderInstance = null;
|
|
378
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dynamic Tool Loader Tests
|
|
3
|
+
*
|
|
4
|
+
* Tests for lazy loading functionality to ensure:
|
|
5
|
+
* 1. Only core tools are loaded at startup
|
|
6
|
+
* 2. Non-core tools are loaded on-demand
|
|
7
|
+
* 3. Token savings from lazy loading
|
|
8
|
+
*/
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=dynamic-loader.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dynamic-loader.test.d.ts","sourceRoot":"","sources":["../../src/tools/dynamic-loader.test.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dynamic Tool Loader Tests
|
|
3
|
+
*
|
|
4
|
+
* Tests for lazy loading functionality to ensure:
|
|
5
|
+
* 1. Only core tools are loaded at startup
|
|
6
|
+
* 2. Non-core tools are loaded on-demand
|
|
7
|
+
* 3. Token savings from lazy loading
|
|
8
|
+
*/
|
|
9
|
+
import { describe, it, expect, beforeEach } from "vitest";
|
|
10
|
+
import { getDynamicLoader, resetDynamicLoader, TOOL_CATALOG, } from "./dynamic-loader.js";
|
|
11
|
+
import { countTokens } from "../utils/token-counter.js";
|
|
12
|
+
describe("DynamicToolLoader", () => {
|
|
13
|
+
let loader;
|
|
14
|
+
beforeEach(() => {
|
|
15
|
+
resetDynamicLoader();
|
|
16
|
+
loader = getDynamicLoader();
|
|
17
|
+
});
|
|
18
|
+
describe("Core tools loading", () => {
|
|
19
|
+
it("should only load core tools at startup", async () => {
|
|
20
|
+
const coreTools = await loader.loadCoreTools();
|
|
21
|
+
// Should only load tools marked as "core"
|
|
22
|
+
const coreNames = coreTools.map((t) => t.name);
|
|
23
|
+
expect(coreNames).toContain("auto_optimize");
|
|
24
|
+
expect(coreNames).toContain("smart_file_read");
|
|
25
|
+
// Should NOT load non-core tools
|
|
26
|
+
expect(coreNames).not.toContain("compress_context");
|
|
27
|
+
expect(coreNames).not.toContain("analyze_build_output");
|
|
28
|
+
expect(coreNames).not.toContain("summarize_logs");
|
|
29
|
+
});
|
|
30
|
+
it("should have fewer loaded tools than total catalog", async () => {
|
|
31
|
+
await loader.loadCoreTools();
|
|
32
|
+
const loadedTools = loader.getLoadedTools();
|
|
33
|
+
expect(loadedTools.length).toBeLessThan(TOOL_CATALOG.length);
|
|
34
|
+
console.log(` Core tools: ${loadedTools.length}/${TOOL_CATALOG.length} (${Math.round((loadedTools.length / TOOL_CATALOG.length) * 100)}%)`);
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
describe("On-demand loading", () => {
|
|
38
|
+
it("should load tools by category", async () => {
|
|
39
|
+
await loader.loadCoreTools();
|
|
40
|
+
const beforeCount = loader.getLoadedTools().length;
|
|
41
|
+
const compressTools = await loader.loadByCategory("compress");
|
|
42
|
+
const afterCount = loader.getLoadedTools().length;
|
|
43
|
+
expect(afterCount).toBeGreaterThan(beforeCount);
|
|
44
|
+
// Verify compress tools are loaded
|
|
45
|
+
const loadedNames = loader.getLoadedTools().map((t) => t.name);
|
|
46
|
+
expect(loadedNames).toContain("compress_context");
|
|
47
|
+
});
|
|
48
|
+
it("should load tools by name", async () => {
|
|
49
|
+
await loader.loadCoreTools();
|
|
50
|
+
expect(loader.isLoaded("summarize_logs")).toBe(false);
|
|
51
|
+
await loader.loadByNames(["summarize_logs"]);
|
|
52
|
+
expect(loader.isLoaded("summarize_logs")).toBe(true);
|
|
53
|
+
});
|
|
54
|
+
it("should load tools by query", async () => {
|
|
55
|
+
await loader.loadCoreTools();
|
|
56
|
+
const beforeCount = loader.getLoadedTools().length;
|
|
57
|
+
await loader.loadByQuery("build");
|
|
58
|
+
const afterCount = loader.getLoadedTools().length;
|
|
59
|
+
expect(afterCount).toBeGreaterThan(beforeCount);
|
|
60
|
+
});
|
|
61
|
+
it("should not duplicate already loaded tools", async () => {
|
|
62
|
+
await loader.loadCoreTools();
|
|
63
|
+
const firstCount = loader.getLoadedTools().length;
|
|
64
|
+
await loader.loadCoreTools(); // Load again
|
|
65
|
+
const secondCount = loader.getLoadedTools().length;
|
|
66
|
+
expect(secondCount).toBe(firstCount);
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
describe("Token savings from lazy loading", () => {
|
|
70
|
+
it("should save tokens by loading only core tools", async () => {
|
|
71
|
+
// Calculate tokens for core tools only
|
|
72
|
+
const coreTools = await loader.loadCoreTools();
|
|
73
|
+
const coreTokens = coreTools.reduce((sum, tool) => {
|
|
74
|
+
const serialized = JSON.stringify({
|
|
75
|
+
name: tool.name,
|
|
76
|
+
description: tool.description,
|
|
77
|
+
inputSchema: tool.inputSchema,
|
|
78
|
+
});
|
|
79
|
+
return sum + countTokens(serialized);
|
|
80
|
+
}, 0);
|
|
81
|
+
// Reset and load all tools
|
|
82
|
+
resetDynamicLoader();
|
|
83
|
+
const freshLoader = getDynamicLoader();
|
|
84
|
+
const allTools = await freshLoader.loadAllTools();
|
|
85
|
+
const allTokens = allTools.reduce((sum, tool) => {
|
|
86
|
+
const serialized = JSON.stringify({
|
|
87
|
+
name: tool.name,
|
|
88
|
+
description: tool.description,
|
|
89
|
+
inputSchema: tool.inputSchema,
|
|
90
|
+
});
|
|
91
|
+
return sum + countTokens(serialized);
|
|
92
|
+
}, 0);
|
|
93
|
+
// Core tools should use significantly fewer tokens
|
|
94
|
+
const savings = Math.round((1 - coreTokens / allTokens) * 100);
|
|
95
|
+
expect(savings).toBeGreaterThan(50); // At least 50% savings
|
|
96
|
+
console.log(` Token savings: ${allTokens} → ${coreTokens} (-${savings}%)`);
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
describe("Tool catalog integrity", () => {
|
|
100
|
+
it("should have all required categories", () => {
|
|
101
|
+
const categories = new Set(TOOL_CATALOG.map((t) => t.category));
|
|
102
|
+
expect(categories).toContain("core");
|
|
103
|
+
expect(categories).toContain("compress");
|
|
104
|
+
expect(categories).toContain("analyze");
|
|
105
|
+
expect(categories).toContain("logs");
|
|
106
|
+
expect(categories).toContain("code");
|
|
107
|
+
expect(categories).toContain("pipeline");
|
|
108
|
+
});
|
|
109
|
+
it("should have unique tool names", () => {
|
|
110
|
+
const names = TOOL_CATALOG.map((t) => t.name);
|
|
111
|
+
const uniqueNames = new Set(names);
|
|
112
|
+
expect(uniqueNames.size).toBe(names.length);
|
|
113
|
+
});
|
|
114
|
+
it("should have loaders that resolve", async () => {
|
|
115
|
+
for (const meta of TOOL_CATALOG) {
|
|
116
|
+
const tool = await meta.loader();
|
|
117
|
+
expect(tool).toBeDefined();
|
|
118
|
+
expect(tool.name).toBe(meta.name);
|
|
119
|
+
expect(tool.execute).toBeInstanceOf(Function);
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
describe("Change notifications", () => {
|
|
124
|
+
it("should notify when new tools are loaded", async () => {
|
|
125
|
+
let notified = false;
|
|
126
|
+
loader.onToolsChanged(() => {
|
|
127
|
+
notified = true;
|
|
128
|
+
});
|
|
129
|
+
await loader.loadCoreTools();
|
|
130
|
+
expect(notified).toBe(true);
|
|
131
|
+
});
|
|
132
|
+
it("should not notify when no new tools are loaded", async () => {
|
|
133
|
+
await loader.loadCoreTools();
|
|
134
|
+
let notified = false;
|
|
135
|
+
loader.onToolsChanged(() => {
|
|
136
|
+
notified = true;
|
|
137
|
+
});
|
|
138
|
+
await loader.loadCoreTools(); // Load same tools again
|
|
139
|
+
expect(notified).toBe(false);
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
describe("Metadata-only discovery", () => {
|
|
144
|
+
let loader;
|
|
145
|
+
beforeEach(() => {
|
|
146
|
+
resetDynamicLoader();
|
|
147
|
+
loader = getDynamicLoader();
|
|
148
|
+
});
|
|
149
|
+
it("should get available tools without loading them", () => {
|
|
150
|
+
const available = loader.getAvailableTools();
|
|
151
|
+
expect(available.length).toBe(TOOL_CATALOG.length);
|
|
152
|
+
expect(loader.getLoadedTools().length).toBe(0);
|
|
153
|
+
});
|
|
154
|
+
it("should search tools without loading them", () => {
|
|
155
|
+
const results = loader.searchTools("compress");
|
|
156
|
+
expect(results.length).toBeGreaterThan(0);
|
|
157
|
+
expect(loader.getLoadedTools().length).toBe(0);
|
|
158
|
+
});
|
|
159
|
+
it("should get tools by category without loading them", () => {
|
|
160
|
+
const results = loader.getToolsByCategory("logs");
|
|
161
|
+
expect(results.length).toBeGreaterThan(0);
|
|
162
|
+
expect(loader.getLoadedTools().length).toBe(0);
|
|
163
|
+
});
|
|
164
|
+
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lazy MCP - Pattern for 95% token reduction
|
|
3
|
+
*
|
|
4
|
+
* Implements the lazy-mcp pattern where only 2 meta-tools are exposed:
|
|
5
|
+
* - browse_tools: Navigate the tool hierarchy
|
|
6
|
+
* - run_tool: Execute any tool by name
|
|
7
|
+
*
|
|
8
|
+
* This reduces initial context from ~15,000 tokens to ~800 tokens.
|
|
9
|
+
*
|
|
10
|
+
* @see https://github.com/voicetreelab/lazy-mcp
|
|
11
|
+
*/
|
|
12
|
+
import type { ToolDefinition, ToolExecuteResult } from "./registry.js";
|
|
13
|
+
export declare const browseToolsTool: ToolDefinition;
|
|
14
|
+
/**
|
|
15
|
+
* Set the registry reference for tool execution
|
|
16
|
+
* Called by the server during initialization
|
|
17
|
+
*/
|
|
18
|
+
export declare function setLazyMcpRegistry(registry: {
|
|
19
|
+
execute: (name: string, args: unknown) => Promise<ToolExecuteResult>;
|
|
20
|
+
}): void;
|
|
21
|
+
export declare const runToolTool: ToolDefinition;
|
|
22
|
+
export declare const lazyMcpTools: ToolDefinition[];
|
|
23
|
+
/**
|
|
24
|
+
* Calculate token savings from lazy loading
|
|
25
|
+
*/
|
|
26
|
+
export declare function calculateLazySavings(): {
|
|
27
|
+
lazyTokens: number;
|
|
28
|
+
fullTokens: number;
|
|
29
|
+
savingsPercent: number;
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=lazy-mcp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lazy-mcp.d.ts","sourceRoot":"","sources":["../../src/tools/lazy-mcp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAkEvE,eAAO,MAAM,eAAe,EAAE,cAK7B,CAAC;AAyBF;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE;IAC3C,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,KAAK,OAAO,CAAC,iBAAiB,CAAC,CAAC;CACtE,GAAG,IAAI,CAEP;AAgDD,eAAO,MAAM,WAAW,EAAE,cAKzB,CAAC;AAMF,eAAO,MAAM,YAAY,EAAE,cAAc,EAAmC,CAAC;AAE7E;;GAEG;AACH,wBAAgB,oBAAoB,IAAI;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;CACxB,CAUA"}
|