@gguf/coder 0.2.9 → 0.3.1
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/.editorconfig +16 -0
- package/.env.example +63 -0
- package/.gitattributes +1 -0
- package/.semgrepignore +19 -0
- package/coder-dummy-file.ts +52 -0
- package/coder.config.example.json +59 -0
- package/coder.config.json +13 -0
- package/color_picker.html +36 -0
- package/dist/tools/execute-bash.js +3 -3
- package/dist/tools/execute-bash.js.map +1 -1
- package/dist/tools/fetch-url.js +3 -3
- package/dist/tools/fetch-url.js.map +1 -1
- package/dist/tools/find-files.d.ts.map +1 -1
- package/dist/tools/find-files.js +1 -1
- package/dist/tools/find-files.js.map +1 -1
- package/dist/tools/lsp-get-diagnostics.js +1 -1
- package/dist/tools/lsp-get-diagnostics.js.map +1 -1
- package/dist/tools/read-file.d.ts.map +1 -1
- package/dist/tools/read-file.js +6 -6
- package/dist/tools/read-file.js.map +1 -1
- package/dist/tools/search-file-contents.d.ts.map +1 -1
- package/dist/tools/search-file-contents.js +1 -1
- package/dist/tools/search-file-contents.js.map +1 -1
- package/dist/tools/string-replace.js +11 -11
- package/dist/tools/string-replace.js.map +1 -1
- package/dist/tools/web-search.d.ts.map +1 -1
- package/dist/tools/web-search.js +3 -3
- package/dist/tools/web-search.js.map +1 -1
- package/dist/tools/write-file.js +4 -4
- package/dist/tools/write-file.js.map +1 -1
- package/dist/utils/tool-result-display.d.ts.map +1 -1
- package/dist/utils/tool-result-display.js +3 -3
- package/dist/utils/tool-result-display.js.map +1 -1
- package/package.json +2 -14
- package/scripts/extract-changelog.js +73 -0
- package/scripts/fetch-models.js +143 -0
- package/scripts/test.sh +40 -0
- package/scripts/update-homebrew-formula.sh +125 -0
- package/scripts/update-nix-version.sh +157 -0
- package/source/ai-sdk-client/AISDKClient.spec.ts +117 -0
- package/source/ai-sdk-client/AISDKClient.ts +155 -0
- package/source/ai-sdk-client/chat/chat-handler.spec.ts +121 -0
- package/source/ai-sdk-client/chat/chat-handler.ts +276 -0
- package/source/ai-sdk-client/chat/streaming-handler.spec.ts +173 -0
- package/source/ai-sdk-client/chat/streaming-handler.ts +110 -0
- package/source/ai-sdk-client/chat/tool-processor.spec.ts +92 -0
- package/source/ai-sdk-client/chat/tool-processor.ts +70 -0
- package/source/ai-sdk-client/converters/message-converter.spec.ts +220 -0
- package/source/ai-sdk-client/converters/message-converter.ts +113 -0
- package/source/ai-sdk-client/converters/tool-converter.spec.ts +90 -0
- package/source/ai-sdk-client/converters/tool-converter.ts +46 -0
- package/source/ai-sdk-client/error-handling/error-extractor.spec.ts +55 -0
- package/source/ai-sdk-client/error-handling/error-extractor.ts +15 -0
- package/source/ai-sdk-client/error-handling/error-parser.spec.ts +169 -0
- package/source/ai-sdk-client/error-handling/error-parser.ts +161 -0
- package/source/ai-sdk-client/index.ts +7 -0
- package/source/ai-sdk-client/providers/provider-factory.spec.ts +71 -0
- package/source/ai-sdk-client/providers/provider-factory.ts +41 -0
- package/source/ai-sdk-client/types.ts +9 -0
- package/source/ai-sdk-client-empty-message.spec.ts +141 -0
- package/source/ai-sdk-client-error-handling.spec.ts +186 -0
- package/source/ai-sdk-client-maxretries.spec.ts +114 -0
- package/source/ai-sdk-client-preparestep.spec.ts +279 -0
- package/source/app/App.spec.tsx +32 -0
- package/source/app/App.tsx +480 -0
- package/source/app/components/AppContainer.spec.tsx +96 -0
- package/source/app/components/AppContainer.tsx +56 -0
- package/source/app/components/ChatInterface.spec.tsx +163 -0
- package/source/app/components/ChatInterface.tsx +144 -0
- package/source/app/components/ModalSelectors.spec.tsx +141 -0
- package/source/app/components/ModalSelectors.tsx +135 -0
- package/source/app/helpers.spec.ts +97 -0
- package/source/app/helpers.ts +63 -0
- package/source/app/index.ts +4 -0
- package/source/app/types.ts +39 -0
- package/source/app/utils/appUtils.ts +294 -0
- package/source/app/utils/conversationState.ts +310 -0
- package/source/app.spec.tsx +244 -0
- package/source/cli.spec.ts +73 -0
- package/source/cli.tsx +51 -0
- package/source/client-factory.spec.ts +48 -0
- package/source/client-factory.ts +178 -0
- package/source/command-parser.spec.ts +127 -0
- package/source/command-parser.ts +36 -0
- package/source/commands/checkpoint.spec.tsx +277 -0
- package/source/commands/checkpoint.tsx +366 -0
- package/source/commands/clear.tsx +22 -0
- package/source/commands/custom-commands.tsx +121 -0
- package/source/commands/exit.ts +21 -0
- package/source/commands/export.spec.tsx +131 -0
- package/source/commands/export.tsx +79 -0
- package/source/commands/help.tsx +120 -0
- package/source/commands/index.ts +17 -0
- package/source/commands/init.tsx +339 -0
- package/source/commands/lsp-command.spec.tsx +281 -0
- package/source/commands/lsp.tsx +120 -0
- package/source/commands/mcp-command.spec.tsx +313 -0
- package/source/commands/mcp.tsx +162 -0
- package/source/commands/model-database.spec.tsx +758 -0
- package/source/commands/model-database.tsx +418 -0
- package/source/commands/model.ts +12 -0
- package/source/commands/provider.ts +12 -0
- package/source/commands/setup-config.tsx +16 -0
- package/source/commands/simple-commands.spec.tsx +175 -0
- package/source/commands/status.ts +12 -0
- package/source/commands/theme.ts +12 -0
- package/source/commands/update.spec.tsx +261 -0
- package/source/commands/update.tsx +201 -0
- package/source/commands/usage.spec.tsx +495 -0
- package/source/commands/usage.tsx +100 -0
- package/source/commands.spec.ts +436 -0
- package/source/commands.ts +83 -0
- package/source/components/assistant-message.spec.tsx +796 -0
- package/source/components/assistant-message.tsx +34 -0
- package/source/components/bash-execution-indicator.tsx +21 -0
- package/source/components/cancelling-indicator.tsx +16 -0
- package/source/components/chat-queue.spec.tsx +83 -0
- package/source/components/chat-queue.tsx +36 -0
- package/source/components/checkpoint-display.spec.tsx +219 -0
- package/source/components/checkpoint-display.tsx +126 -0
- package/source/components/checkpoint-selector.spec.tsx +173 -0
- package/source/components/checkpoint-selector.tsx +173 -0
- package/source/components/development-mode-indicator.spec.tsx +268 -0
- package/source/components/development-mode-indicator.tsx +38 -0
- package/source/components/message-box.spec.tsx +427 -0
- package/source/components/message-box.tsx +87 -0
- package/source/components/model-selector.tsx +132 -0
- package/source/components/provider-selector.tsx +75 -0
- package/source/components/random-spinner.tsx +19 -0
- package/source/components/security-disclaimer.tsx +73 -0
- package/source/components/status-connection-display.spec.tsx +133 -0
- package/source/components/status.tsx +267 -0
- package/source/components/theme-selector.tsx +126 -0
- package/source/components/tool-confirmation.tsx +190 -0
- package/source/components/tool-execution-indicator.tsx +33 -0
- package/source/components/tool-message.tsx +85 -0
- package/source/components/ui/titled-box.spec.tsx +207 -0
- package/source/components/ui/titled-box.tsx +57 -0
- package/source/components/usage/progress-bar.spec.tsx +398 -0
- package/source/components/usage/progress-bar.tsx +30 -0
- package/source/components/usage/usage-display.spec.tsx +780 -0
- package/source/components/usage/usage-display.tsx +291 -0
- package/source/components/user-input.spec.tsx +327 -0
- package/source/components/user-input.tsx +533 -0
- package/source/components/user-message.spec.tsx +230 -0
- package/source/components/user-message.tsx +84 -0
- package/source/components/welcome-message.tsx +76 -0
- package/source/config/env-substitution.ts +65 -0
- package/source/config/index.spec.ts +171 -0
- package/source/config/index.ts +154 -0
- package/source/config/paths.spec.ts +241 -0
- package/source/config/paths.ts +55 -0
- package/source/config/preferences.ts +51 -0
- package/source/config/themes.ts +315 -0
- package/source/constants.ts +130 -0
- package/source/context/mode-context.spec.ts +79 -0
- package/source/context/mode-context.ts +24 -0
- package/source/custom-commands/executor.spec.ts +142 -0
- package/source/custom-commands/executor.ts +64 -0
- package/source/custom-commands/loader.spec.ts +314 -0
- package/source/custom-commands/loader.ts +153 -0
- package/source/custom-commands/parser.ts +196 -0
- package/source/hooks/chat-handler/conversation/conversation-loop.spec.ts +39 -0
- package/source/hooks/chat-handler/conversation/conversation-loop.tsx +511 -0
- package/source/hooks/chat-handler/conversation/tool-executor.spec.ts +50 -0
- package/source/hooks/chat-handler/conversation/tool-executor.tsx +109 -0
- package/source/hooks/chat-handler/index.ts +12 -0
- package/source/hooks/chat-handler/state/streaming-state.spec.ts +26 -0
- package/source/hooks/chat-handler/state/streaming-state.ts +19 -0
- package/source/hooks/chat-handler/types.ts +38 -0
- package/source/hooks/chat-handler/useChatHandler.spec.tsx +321 -0
- package/source/hooks/chat-handler/useChatHandler.tsx +194 -0
- package/source/hooks/chat-handler/utils/context-checker.spec.ts +60 -0
- package/source/hooks/chat-handler/utils/context-checker.tsx +73 -0
- package/source/hooks/chat-handler/utils/message-helpers.spec.ts +42 -0
- package/source/hooks/chat-handler/utils/message-helpers.tsx +36 -0
- package/source/hooks/chat-handler/utils/tool-filters.spec.ts +109 -0
- package/source/hooks/chat-handler/utils/tool-filters.ts +64 -0
- package/source/hooks/useAppHandlers.tsx +291 -0
- package/source/hooks/useAppInitialization.tsx +422 -0
- package/source/hooks/useAppState.tsx +311 -0
- package/source/hooks/useDirectoryTrust.tsx +98 -0
- package/source/hooks/useInputState.ts +414 -0
- package/source/hooks/useModeHandlers.tsx +302 -0
- package/source/hooks/useNonInteractiveMode.ts +140 -0
- package/source/hooks/useTerminalWidth.tsx +81 -0
- package/source/hooks/useTheme.ts +18 -0
- package/source/hooks/useToolHandler.tsx +349 -0
- package/source/hooks/useUIState.ts +61 -0
- package/source/init/agents-template-generator.ts +421 -0
- package/source/init/existing-rules-extractor.ts +319 -0
- package/source/init/file-scanner.spec.ts +227 -0
- package/source/init/file-scanner.ts +238 -0
- package/source/init/framework-detector.ts +382 -0
- package/source/init/language-detector.ts +269 -0
- package/source/init/project-analyzer.spec.ts +231 -0
- package/source/init/project-analyzer.ts +458 -0
- package/source/lsp/index.ts +31 -0
- package/source/lsp/lsp-client.spec.ts +508 -0
- package/source/lsp/lsp-client.ts +487 -0
- package/source/lsp/lsp-manager.spec.ts +477 -0
- package/source/lsp/lsp-manager.ts +419 -0
- package/source/lsp/protocol.spec.ts +502 -0
- package/source/lsp/protocol.ts +360 -0
- package/source/lsp/server-discovery.spec.ts +654 -0
- package/source/lsp/server-discovery.ts +515 -0
- package/source/markdown-parser/html-entities.spec.ts +88 -0
- package/source/markdown-parser/html-entities.ts +45 -0
- package/source/markdown-parser/index.spec.ts +281 -0
- package/source/markdown-parser/index.ts +126 -0
- package/source/markdown-parser/table-parser.spec.ts +133 -0
- package/source/markdown-parser/table-parser.ts +114 -0
- package/source/markdown-parser/utils.spec.ts +70 -0
- package/source/markdown-parser/utils.ts +13 -0
- package/source/mcp/mcp-client.spec.ts +81 -0
- package/source/mcp/mcp-client.ts +625 -0
- package/source/mcp/transport-factory.spec.ts +406 -0
- package/source/mcp/transport-factory.ts +312 -0
- package/source/message-handler.ts +67 -0
- package/source/model-database/database-engine.spec.ts +494 -0
- package/source/model-database/database-engine.ts +50 -0
- package/source/model-database/model-database.spec.ts +363 -0
- package/source/model-database/model-database.ts +91 -0
- package/source/model-database/model-engine.spec.ts +447 -0
- package/source/model-database/model-engine.ts +65 -0
- package/source/model-database/model-fetcher.spec.ts +583 -0
- package/source/model-database/model-fetcher.ts +330 -0
- package/source/models/index.ts +1 -0
- package/source/models/models-cache.spec.ts +214 -0
- package/source/models/models-cache.ts +78 -0
- package/source/models/models-dev-client.spec.ts +379 -0
- package/source/models/models-dev-client.ts +329 -0
- package/source/models/models-types.ts +68 -0
- package/source/prompt-history.ts +155 -0
- package/source/security/command-injection.spec.ts +240 -0
- package/source/services/checkpoint-manager.spec.ts +523 -0
- package/source/services/checkpoint-manager.ts +466 -0
- package/source/services/file-snapshot.spec.ts +569 -0
- package/source/services/file-snapshot.ts +220 -0
- package/source/test-utils/render-with-theme.tsx +48 -0
- package/source/tokenization/index.ts +1 -0
- package/source/tokenization/tokenizer-factory.spec.ts +170 -0
- package/source/tokenization/tokenizer-factory.ts +125 -0
- package/source/tokenization/tokenizers/anthropic-tokenizer.spec.ts +200 -0
- package/source/tokenization/tokenizers/anthropic-tokenizer.ts +43 -0
- package/source/tokenization/tokenizers/fallback-tokenizer.spec.ts +236 -0
- package/source/tokenization/tokenizers/fallback-tokenizer.ts +26 -0
- package/source/tokenization/tokenizers/llama-tokenizer.spec.ts +224 -0
- package/source/tokenization/tokenizers/llama-tokenizer.ts +41 -0
- package/source/tokenization/tokenizers/openai-tokenizer.spec.ts +184 -0
- package/source/tokenization/tokenizers/openai-tokenizer.ts +57 -0
- package/source/tool-calling/index.ts +5 -0
- package/source/tool-calling/json-parser.spec.ts +639 -0
- package/source/tool-calling/json-parser.ts +247 -0
- package/source/tool-calling/tool-parser.spec.ts +395 -0
- package/source/tool-calling/tool-parser.ts +120 -0
- package/source/tool-calling/xml-parser.spec.ts +662 -0
- package/source/tool-calling/xml-parser.ts +289 -0
- package/source/tools/execute-bash.spec.tsx +353 -0
- package/source/tools/execute-bash.tsx +219 -0
- package/source/tools/execute-function.spec.ts +130 -0
- package/source/tools/fetch-url.spec.tsx +342 -0
- package/source/tools/fetch-url.tsx +172 -0
- package/source/tools/find-files.spec.tsx +924 -0
- package/source/tools/find-files.tsx +293 -0
- package/source/tools/index.ts +102 -0
- package/source/tools/lsp-get-diagnostics.tsx +192 -0
- package/source/tools/needs-approval.spec.ts +282 -0
- package/source/tools/read-file.spec.tsx +801 -0
- package/source/tools/read-file.tsx +387 -0
- package/source/tools/search-file-contents.spec.tsx +1273 -0
- package/source/tools/search-file-contents.tsx +293 -0
- package/source/tools/string-replace.spec.tsx +730 -0
- package/source/tools/string-replace.tsx +548 -0
- package/source/tools/tool-manager.ts +210 -0
- package/source/tools/tool-registry.spec.ts +415 -0
- package/source/tools/tool-registry.ts +228 -0
- package/source/tools/web-search.tsx +223 -0
- package/source/tools/write-file.spec.tsx +559 -0
- package/source/tools/write-file.tsx +228 -0
- package/source/types/app.ts +37 -0
- package/source/types/checkpoint.ts +48 -0
- package/source/types/commands.ts +46 -0
- package/source/types/components.ts +27 -0
- package/source/types/config.ts +103 -0
- package/source/types/core-connection-status.spec.ts +67 -0
- package/source/types/core.ts +181 -0
- package/source/types/hooks.ts +50 -0
- package/source/types/index.ts +12 -0
- package/source/types/markdown-parser.ts +11 -0
- package/source/types/mcp.ts +52 -0
- package/source/types/system.ts +16 -0
- package/source/types/tokenization.ts +41 -0
- package/source/types/ui.ts +40 -0
- package/source/types/usage.ts +58 -0
- package/source/types/utils.ts +16 -0
- package/source/usage/calculator.spec.ts +385 -0
- package/source/usage/calculator.ts +104 -0
- package/source/usage/storage.spec.ts +703 -0
- package/source/usage/storage.ts +238 -0
- package/source/usage/tracker.spec.ts +456 -0
- package/source/usage/tracker.ts +102 -0
- package/source/utils/atomic-deletion.spec.ts +194 -0
- package/source/utils/atomic-deletion.ts +127 -0
- package/source/utils/bounded-map.spec.ts +300 -0
- package/source/utils/bounded-map.ts +193 -0
- package/source/utils/checkpoint-utils.spec.ts +222 -0
- package/source/utils/checkpoint-utils.ts +92 -0
- package/source/utils/error-formatter.spec.ts +169 -0
- package/source/utils/error-formatter.ts +194 -0
- package/source/utils/file-autocomplete.spec.ts +173 -0
- package/source/utils/file-autocomplete.ts +196 -0
- package/source/utils/file-cache.spec.ts +309 -0
- package/source/utils/file-cache.ts +195 -0
- package/source/utils/file-content-loader.spec.ts +180 -0
- package/source/utils/file-content-loader.ts +179 -0
- package/source/utils/file-mention-handler.spec.ts +261 -0
- package/source/utils/file-mention-handler.ts +84 -0
- package/source/utils/file-mention-parser.spec.ts +182 -0
- package/source/utils/file-mention-parser.ts +170 -0
- package/source/utils/fuzzy-matching.spec.ts +149 -0
- package/source/utils/fuzzy-matching.ts +146 -0
- package/source/utils/indentation-normalizer.spec.ts +216 -0
- package/source/utils/indentation-normalizer.ts +76 -0
- package/source/utils/installation-detector.spec.ts +178 -0
- package/source/utils/installation-detector.ts +153 -0
- package/source/utils/logging/config.spec.ts +311 -0
- package/source/utils/logging/config.ts +210 -0
- package/source/utils/logging/console-facade.spec.ts +184 -0
- package/source/utils/logging/console-facade.ts +384 -0
- package/source/utils/logging/correlation.spec.ts +679 -0
- package/source/utils/logging/correlation.ts +474 -0
- package/source/utils/logging/formatters.spec.ts +464 -0
- package/source/utils/logging/formatters.ts +207 -0
- package/source/utils/logging/health-monitor/alerts/alert-manager.spec.ts +93 -0
- package/source/utils/logging/health-monitor/alerts/alert-manager.ts +79 -0
- package/source/utils/logging/health-monitor/checks/configuration-check.spec.ts +56 -0
- package/source/utils/logging/health-monitor/checks/configuration-check.ts +43 -0
- package/source/utils/logging/health-monitor/checks/logging-check.spec.ts +56 -0
- package/source/utils/logging/health-monitor/checks/logging-check.ts +58 -0
- package/source/utils/logging/health-monitor/checks/memory-check.spec.ts +100 -0
- package/source/utils/logging/health-monitor/checks/memory-check.ts +78 -0
- package/source/utils/logging/health-monitor/checks/performance-check.spec.ts +56 -0
- package/source/utils/logging/health-monitor/checks/performance-check.ts +56 -0
- package/source/utils/logging/health-monitor/checks/request-check.spec.ts +56 -0
- package/source/utils/logging/health-monitor/checks/request-check.ts +76 -0
- package/source/utils/logging/health-monitor/core/health-check-runner.spec.ts +70 -0
- package/source/utils/logging/health-monitor/core/health-check-runner.ts +138 -0
- package/source/utils/logging/health-monitor/core/health-monitor.spec.ts +58 -0
- package/source/utils/logging/health-monitor/core/health-monitor.ts +344 -0
- package/source/utils/logging/health-monitor/core/scoring.spec.ts +65 -0
- package/source/utils/logging/health-monitor/core/scoring.ts +91 -0
- package/source/utils/logging/health-monitor/index.ts +15 -0
- package/source/utils/logging/health-monitor/instances.ts +48 -0
- package/source/utils/logging/health-monitor/middleware/http-middleware.spec.ts +141 -0
- package/source/utils/logging/health-monitor/middleware/http-middleware.ts +75 -0
- package/source/utils/logging/health-monitor/types.ts +126 -0
- package/source/utils/logging/index.spec.ts +284 -0
- package/source/utils/logging/index.ts +236 -0
- package/source/utils/logging/integration.spec.ts +441 -0
- package/source/utils/logging/log-method-factory.spec.ts +573 -0
- package/source/utils/logging/log-method-factory.ts +233 -0
- package/source/utils/logging/log-query/aggregation/aggregator.spec.ts +277 -0
- package/source/utils/logging/log-query/aggregation/aggregator.ts +159 -0
- package/source/utils/logging/log-query/aggregation/facet-generator.spec.ts +159 -0
- package/source/utils/logging/log-query/aggregation/facet-generator.ts +47 -0
- package/source/utils/logging/log-query/index.ts +23 -0
- package/source/utils/logging/log-query/query/filter-predicates.spec.ts +247 -0
- package/source/utils/logging/log-query/query/filter-predicates.ts +154 -0
- package/source/utils/logging/log-query/query/query-builder.spec.ts +182 -0
- package/source/utils/logging/log-query/query/query-builder.ts +151 -0
- package/source/utils/logging/log-query/query/query-engine.spec.ts +214 -0
- package/source/utils/logging/log-query/query/query-engine.ts +45 -0
- package/source/utils/logging/log-query/storage/circular-buffer.spec.ts +143 -0
- package/source/utils/logging/log-query/storage/circular-buffer.ts +75 -0
- package/source/utils/logging/log-query/storage/index-manager.spec.ts +150 -0
- package/source/utils/logging/log-query/storage/index-manager.ts +71 -0
- package/source/utils/logging/log-query/storage/log-storage.spec.ts +257 -0
- package/source/utils/logging/log-query/storage/log-storage.ts +80 -0
- package/source/utils/logging/log-query/types.ts +163 -0
- package/source/utils/logging/log-query/utils/helpers.spec.ts +263 -0
- package/source/utils/logging/log-query/utils/helpers.ts +72 -0
- package/source/utils/logging/log-query/utils/sorting.spec.ts +182 -0
- package/source/utils/logging/log-query/utils/sorting.ts +61 -0
- package/source/utils/logging/logger-provider.spec.ts +262 -0
- package/source/utils/logging/logger-provider.ts +362 -0
- package/source/utils/logging/performance.spec.ts +209 -0
- package/source/utils/logging/performance.ts +757 -0
- package/source/utils/logging/pino-logger.spec.ts +425 -0
- package/source/utils/logging/pino-logger.ts +514 -0
- package/source/utils/logging/redaction.spec.ts +490 -0
- package/source/utils/logging/redaction.ts +267 -0
- package/source/utils/logging/request-tracker.spec.ts +1198 -0
- package/source/utils/logging/request-tracker.ts +803 -0
- package/source/utils/logging/transports.spec.ts +505 -0
- package/source/utils/logging/transports.ts +305 -0
- package/source/utils/logging/types.ts +216 -0
- package/source/utils/message-builder.spec.ts +179 -0
- package/source/utils/message-builder.ts +101 -0
- package/source/utils/message-queue.tsx +486 -0
- package/source/utils/paste-detection.spec.ts +69 -0
- package/source/utils/paste-detection.ts +124 -0
- package/source/utils/paste-roundtrip.spec.ts +442 -0
- package/source/utils/paste-utils.spec.ts +128 -0
- package/source/utils/paste-utils.ts +52 -0
- package/source/utils/programming-language-helper.spec.ts +74 -0
- package/source/utils/programming-language-helper.ts +32 -0
- package/source/utils/prompt-assembly.spec.ts +221 -0
- package/source/utils/prompt-processor.ts +173 -0
- package/source/utils/tool-args-parser.spec.ts +136 -0
- package/source/utils/tool-args-parser.ts +54 -0
- package/source/utils/tool-cancellation.spec.ts +230 -0
- package/source/utils/tool-cancellation.ts +28 -0
- package/source/utils/tool-result-display.spec.tsx +469 -0
- package/source/utils/tool-result-display.tsx +90 -0
- package/source/utils/update-checker.spec.ts +383 -0
- package/source/utils/update-checker.ts +183 -0
- package/source/wizard/config-wizard.spec.tsx +103 -0
- package/source/wizard/config-wizard.tsx +382 -0
- package/source/wizard/steps/location-step.spec.tsx +186 -0
- package/source/wizard/steps/location-step.tsx +147 -0
- package/source/wizard/steps/mcp-step.spec.tsx +607 -0
- package/source/wizard/steps/mcp-step.tsx +632 -0
- package/source/wizard/steps/provider-step.spec.tsx +342 -0
- package/source/wizard/steps/provider-step.tsx +957 -0
- package/source/wizard/steps/summary-step.spec.tsx +749 -0
- package/source/wizard/steps/summary-step.tsx +228 -0
- package/source/wizard/templates/mcp-templates.spec.ts +613 -0
- package/source/wizard/templates/mcp-templates.ts +570 -0
- package/source/wizard/templates/provider-templates.spec.ts +152 -0
- package/source/wizard/templates/provider-templates.ts +485 -0
- package/source/wizard/utils/fetch-cloud-models.spec.ts +428 -0
- package/source/wizard/utils/fetch-cloud-models.ts +223 -0
- package/source/wizard/utils/fetch-local-models.spec.ts +297 -0
- package/source/wizard/utils/fetch-local-models.ts +192 -0
- package/source/wizard/validation-array.spec.ts +264 -0
- package/source/wizard/validation.spec.ts +373 -0
- package/source/wizard/validation.ts +232 -0
- package/source/app/prompts/main-prompt.md +0 -122
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Format timestamp to relative time string
|
|
3
|
+
*/
|
|
4
|
+
export function formatRelativeTime(timestamp: string): string {
|
|
5
|
+
const now = new Date();
|
|
6
|
+
const checkpointTime = new Date(timestamp);
|
|
7
|
+
const diffMs = now.getTime() - checkpointTime.getTime();
|
|
8
|
+
const diffMinutes = Math.floor(diffMs / 60000);
|
|
9
|
+
const diffHours = Math.floor(diffMinutes / 60);
|
|
10
|
+
const diffDays = Math.floor(diffHours / 24);
|
|
11
|
+
|
|
12
|
+
if (diffMinutes < 1) {
|
|
13
|
+
return 'Just now';
|
|
14
|
+
} else if (diffMinutes < 60) {
|
|
15
|
+
return `${diffMinutes} min${diffMinutes === 1 ? '' : 's'} ago`;
|
|
16
|
+
} else if (diffHours < 24) {
|
|
17
|
+
return `${diffHours} hr${diffHours === 1 ? '' : 's'} ago`;
|
|
18
|
+
} else if (diffDays < 7) {
|
|
19
|
+
return `${diffDays} day${diffDays === 1 ? '' : 's'} ago`;
|
|
20
|
+
} else {
|
|
21
|
+
return checkpointTime.toLocaleDateString();
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Validate checkpoint name for invalid characters and length
|
|
27
|
+
*/
|
|
28
|
+
export function validateCheckpointName(name: string): {
|
|
29
|
+
valid: boolean;
|
|
30
|
+
error?: string;
|
|
31
|
+
} {
|
|
32
|
+
if (!name || name.trim().length === 0) {
|
|
33
|
+
return {valid: false, error: 'Checkpoint name cannot be empty'};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (name.length > 100) {
|
|
37
|
+
return {
|
|
38
|
+
valid: false,
|
|
39
|
+
error: 'Checkpoint name must be 100 characters or less',
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Check for invalid characters (filesystem-unsafe characters)
|
|
44
|
+
const invalidChars = /[<>:"/\\|?*]/;
|
|
45
|
+
if (invalidChars.test(name)) {
|
|
46
|
+
return {valid: false, error: 'Checkpoint name contains invalid characters'};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Check for reserved names (Windows)
|
|
50
|
+
const reservedNames = [
|
|
51
|
+
'CON',
|
|
52
|
+
'PRN',
|
|
53
|
+
'AUX',
|
|
54
|
+
'NUL',
|
|
55
|
+
'COM1',
|
|
56
|
+
'COM2',
|
|
57
|
+
'COM3',
|
|
58
|
+
'COM4',
|
|
59
|
+
'COM5',
|
|
60
|
+
'COM6',
|
|
61
|
+
'COM7',
|
|
62
|
+
'COM8',
|
|
63
|
+
'COM9',
|
|
64
|
+
'LPT1',
|
|
65
|
+
'LPT2',
|
|
66
|
+
'LPT3',
|
|
67
|
+
'LPT4',
|
|
68
|
+
'LPT5',
|
|
69
|
+
'LPT6',
|
|
70
|
+
'LPT7',
|
|
71
|
+
'LPT8',
|
|
72
|
+
'LPT9',
|
|
73
|
+
];
|
|
74
|
+
if (reservedNames.includes(name.toUpperCase())) {
|
|
75
|
+
return {valid: false, error: 'Checkpoint name is reserved by the system'};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Check if name starts or ends with dot or space
|
|
79
|
+
if (
|
|
80
|
+
name.startsWith('.') ||
|
|
81
|
+
name.endsWith('.') ||
|
|
82
|
+
name.startsWith(' ') ||
|
|
83
|
+
name.endsWith(' ')
|
|
84
|
+
) {
|
|
85
|
+
return {
|
|
86
|
+
valid: false,
|
|
87
|
+
error: 'Checkpoint name cannot start or end with a dot or space',
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return {valid: true};
|
|
92
|
+
}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import test from 'ava';
|
|
2
|
+
import {formatError} from './error-formatter';
|
|
3
|
+
|
|
4
|
+
console.log(`\nerror-formatter.spec.ts`);
|
|
5
|
+
|
|
6
|
+
// Tests for Error instances
|
|
7
|
+
test('formatError - formats standard Error instance', t => {
|
|
8
|
+
const error = new Error('Something went wrong');
|
|
9
|
+
const result = formatError(error);
|
|
10
|
+
t.is(result, 'Something went wrong');
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
test('formatError - formats Error with empty message', t => {
|
|
14
|
+
const error = new Error('');
|
|
15
|
+
const result = formatError(error);
|
|
16
|
+
t.is(result, '');
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
test('formatError - formats TypeError instance', t => {
|
|
20
|
+
const error = new TypeError('Invalid type');
|
|
21
|
+
const result = formatError(error);
|
|
22
|
+
t.is(result, 'Invalid type');
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
test('formatError - formats RangeError instance', t => {
|
|
26
|
+
const error = new RangeError('Out of range');
|
|
27
|
+
const result = formatError(error);
|
|
28
|
+
t.is(result, 'Out of range');
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test('formatError - formats SyntaxError instance', t => {
|
|
32
|
+
const error = new SyntaxError('Unexpected token');
|
|
33
|
+
const result = formatError(error);
|
|
34
|
+
t.is(result, 'Unexpected token');
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test('formatError - formats custom Error subclass', t => {
|
|
38
|
+
class CustomError extends Error {
|
|
39
|
+
constructor(message: string) {
|
|
40
|
+
super(message);
|
|
41
|
+
this.name = 'CustomError';
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
const error = new CustomError('Custom error message');
|
|
45
|
+
const result = formatError(error);
|
|
46
|
+
t.is(result, 'Custom error message');
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
// Tests for non-Error types
|
|
50
|
+
test('formatError - formats string error', t => {
|
|
51
|
+
const error = 'Simple error string';
|
|
52
|
+
const result = formatError(error);
|
|
53
|
+
t.is(result, 'Simple error string');
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
test('formatError - formats number error', t => {
|
|
57
|
+
const error = 404;
|
|
58
|
+
const result = formatError(error);
|
|
59
|
+
t.is(result, '404');
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
test('formatError - formats boolean error', t => {
|
|
63
|
+
const error = false;
|
|
64
|
+
const result = formatError(error);
|
|
65
|
+
t.is(result, 'false');
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
test('formatError - formats null error', t => {
|
|
69
|
+
const error = null;
|
|
70
|
+
const result = formatError(error);
|
|
71
|
+
t.is(result, 'null');
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
test('formatError - formats undefined error', t => {
|
|
75
|
+
const error = undefined;
|
|
76
|
+
const result = formatError(error);
|
|
77
|
+
t.is(result, 'undefined');
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
test('formatError - formats object error', t => {
|
|
81
|
+
const error = {code: 'ERR_001', message: 'Custom error'};
|
|
82
|
+
const result = formatError(error);
|
|
83
|
+
t.is(result, '[object Object]');
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
test('formatError - formats array error', t => {
|
|
87
|
+
const error = ['error1', 'error2'];
|
|
88
|
+
const result = formatError(error);
|
|
89
|
+
t.is(result, 'error1,error2');
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
test('formatError - formats object with toString method', t => {
|
|
93
|
+
const error = {
|
|
94
|
+
toString() {
|
|
95
|
+
return 'Custom toString';
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
const result = formatError(error);
|
|
99
|
+
t.is(result, 'Custom toString');
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
// Edge cases
|
|
103
|
+
test('formatError - formats Error with multiline message', t => {
|
|
104
|
+
const error = new Error('Line 1\nLine 2\nLine 3');
|
|
105
|
+
const result = formatError(error);
|
|
106
|
+
t.is(result, 'Line 1\nLine 2\nLine 3');
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
test('formatError - formats Error with special characters', t => {
|
|
110
|
+
const error = new Error('Error: "quoted" \'text\' with\ttabs');
|
|
111
|
+
const result = formatError(error);
|
|
112
|
+
t.is(result, 'Error: "quoted" \'text\' with\ttabs');
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
test('formatError - formats Error with unicode characters', t => {
|
|
116
|
+
const error = new Error('Error: 日本語 emoji 🚀');
|
|
117
|
+
const result = formatError(error);
|
|
118
|
+
t.is(result, 'Error: 日本語 emoji 🚀');
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
test('formatError - handles Error.cause if present', t => {
|
|
122
|
+
const error = new Error('Main error');
|
|
123
|
+
// Note: Error.cause is a modern feature, just test that formatError still works
|
|
124
|
+
const result = formatError(error);
|
|
125
|
+
t.is(result, 'Main error');
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
// Type consistency tests
|
|
129
|
+
test('formatError - always returns string type for Error', t => {
|
|
130
|
+
const error = new Error('Test');
|
|
131
|
+
const result = formatError(error);
|
|
132
|
+
t.is(typeof result, 'string');
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
test('formatError - always returns string type for non-Error', t => {
|
|
136
|
+
const error = {custom: 'object'};
|
|
137
|
+
const result = formatError(error);
|
|
138
|
+
t.is(typeof result, 'string');
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
// Real-world scenario tests
|
|
142
|
+
test('formatError - handles JSON parse error', t => {
|
|
143
|
+
let error: unknown;
|
|
144
|
+
try {
|
|
145
|
+
JSON.parse('{invalid}');
|
|
146
|
+
} catch (e) {
|
|
147
|
+
error = e;
|
|
148
|
+
}
|
|
149
|
+
const result = formatError(error);
|
|
150
|
+
t.true(result.includes('JSON') || result.includes('Unexpected'));
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
test('formatError - handles fetch-like error', t => {
|
|
154
|
+
const error = new Error('Failed to fetch: Network error');
|
|
155
|
+
const result = formatError(error);
|
|
156
|
+
t.is(result, 'Failed to fetch: Network error');
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
test('formatError - handles validation error object', t => {
|
|
160
|
+
const error = {
|
|
161
|
+
field: 'email',
|
|
162
|
+
message: 'Invalid email format',
|
|
163
|
+
toString() {
|
|
164
|
+
return `${this.field}: ${this.message}`;
|
|
165
|
+
},
|
|
166
|
+
};
|
|
167
|
+
const result = formatError(error);
|
|
168
|
+
t.is(result, 'email: Invalid email format');
|
|
169
|
+
});
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enhanced error formatting utilities with structured logging integration
|
|
3
|
+
* Handles Error instances and unknown error types consistently
|
|
4
|
+
*
|
|
5
|
+
* This utility provides comprehensive error analysis and formatting
|
|
6
|
+
* with integration to the structured logging system for better debugging.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
// Import logging utilities with dependency injection pattern
|
|
10
|
+
import {generateCorrelationId} from '@/utils/logging';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Enhanced error information with structured metadata
|
|
14
|
+
*/
|
|
15
|
+
export interface ErrorInfo {
|
|
16
|
+
message: string;
|
|
17
|
+
name?: string;
|
|
18
|
+
stack?: string;
|
|
19
|
+
code?: string | number;
|
|
20
|
+
type: 'Error' | 'String' | 'Object' | 'Unknown';
|
|
21
|
+
originalType: string;
|
|
22
|
+
hasStack: boolean;
|
|
23
|
+
isNetworkError: boolean;
|
|
24
|
+
isTimeoutError: boolean;
|
|
25
|
+
isValidationError: boolean;
|
|
26
|
+
timestamp: string;
|
|
27
|
+
correlationId?: string;
|
|
28
|
+
cause?: unknown;
|
|
29
|
+
context?: Record<string, unknown>;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Format error objects into string messages
|
|
34
|
+
* Handles Error instances and unknown error types consistently
|
|
35
|
+
*
|
|
36
|
+
* This utility eliminates the repeated pattern of:
|
|
37
|
+
* ```
|
|
38
|
+
* error instanceof Error ? error.message : String(error)
|
|
39
|
+
* ```
|
|
40
|
+
*
|
|
41
|
+
* @param error - Error of any type (Error instance, string, object, etc.)
|
|
42
|
+
* @returns Formatted error message string
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* try {
|
|
46
|
+
* await doSomething();
|
|
47
|
+
* } catch (error) {
|
|
48
|
+
* const message = formatError(error);
|
|
49
|
+
* console.error(message);
|
|
50
|
+
* }
|
|
51
|
+
*/
|
|
52
|
+
export function formatError(error: unknown): string {
|
|
53
|
+
if (error instanceof Error) {
|
|
54
|
+
return error.message;
|
|
55
|
+
}
|
|
56
|
+
return String(error);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Create comprehensive error information with logging
|
|
61
|
+
*
|
|
62
|
+
* @param error - Error of any type
|
|
63
|
+
* @param context - Additional context information
|
|
64
|
+
* @param correlationId - Optional correlation ID for tracking
|
|
65
|
+
* @returns Enhanced error information object
|
|
66
|
+
*/
|
|
67
|
+
export function createErrorInfo(
|
|
68
|
+
error: unknown,
|
|
69
|
+
context?: Record<string, unknown>,
|
|
70
|
+
correlationId?: string,
|
|
71
|
+
): ErrorInfo {
|
|
72
|
+
const timestamp = new Date().toISOString();
|
|
73
|
+
const effectiveCorrelationId = correlationId || generateCorrelationId();
|
|
74
|
+
|
|
75
|
+
// Determine error type and extract information
|
|
76
|
+
if (error instanceof Error) {
|
|
77
|
+
const errorInfo: ErrorInfo = {
|
|
78
|
+
message: error.message,
|
|
79
|
+
name: error.name,
|
|
80
|
+
stack: error.stack,
|
|
81
|
+
type: 'Error',
|
|
82
|
+
originalType: error.constructor.name,
|
|
83
|
+
hasStack: !!error.stack,
|
|
84
|
+
isNetworkError: isNetworkError(error),
|
|
85
|
+
isTimeoutError: isTimeoutError(error),
|
|
86
|
+
isValidationError: isValidationError(error),
|
|
87
|
+
timestamp,
|
|
88
|
+
correlationId: effectiveCorrelationId,
|
|
89
|
+
context,
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
// Extract cause if available
|
|
93
|
+
if (error.cause) {
|
|
94
|
+
errorInfo.cause = error.cause;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Extract error code if available
|
|
98
|
+
const errorCode = extractErrorCode(error);
|
|
99
|
+
if (errorCode) {
|
|
100
|
+
errorInfo.code = errorCode;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return errorInfo;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Handle non-Error objects
|
|
107
|
+
const errorType = typeof error;
|
|
108
|
+
const message = String(error);
|
|
109
|
+
|
|
110
|
+
return {
|
|
111
|
+
message,
|
|
112
|
+
type:
|
|
113
|
+
errorType === 'string'
|
|
114
|
+
? 'String'
|
|
115
|
+
: errorType === 'object' && error !== null
|
|
116
|
+
? 'Object'
|
|
117
|
+
: 'Unknown',
|
|
118
|
+
originalType: errorType,
|
|
119
|
+
hasStack: false,
|
|
120
|
+
isNetworkError: false,
|
|
121
|
+
isTimeoutError: false,
|
|
122
|
+
isValidationError: false,
|
|
123
|
+
timestamp,
|
|
124
|
+
correlationId: effectiveCorrelationId,
|
|
125
|
+
context,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Check if error is a network-related error
|
|
131
|
+
*/
|
|
132
|
+
function isNetworkError(error: Error): boolean {
|
|
133
|
+
return (
|
|
134
|
+
error.name === 'NetworkError' ||
|
|
135
|
+
error.name === 'FetchError' ||
|
|
136
|
+
error.name === 'ECONNREFUSED' ||
|
|
137
|
+
error.name === 'ENOTFOUND' ||
|
|
138
|
+
error.name === 'ECONNRESET' ||
|
|
139
|
+
error.name === 'ETIMEDOUT' ||
|
|
140
|
+
error.message.includes('network') ||
|
|
141
|
+
error.message.includes('fetch') ||
|
|
142
|
+
error.message.includes('connection')
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Check if error is a timeout error
|
|
148
|
+
*/
|
|
149
|
+
function isTimeoutError(error: Error): boolean {
|
|
150
|
+
return (
|
|
151
|
+
error.name === 'TimeoutError' ||
|
|
152
|
+
error.name === 'ETIMEDOUT' ||
|
|
153
|
+
error.message.includes('timeout') ||
|
|
154
|
+
error.message.includes('timed out')
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Check if error is a validation error
|
|
160
|
+
*/
|
|
161
|
+
function isValidationError(error: Error): boolean {
|
|
162
|
+
return (
|
|
163
|
+
error.name === 'ValidationError' ||
|
|
164
|
+
error.name === 'ZodError' ||
|
|
165
|
+
error.message.includes('validation') ||
|
|
166
|
+
error.message.includes('invalid') ||
|
|
167
|
+
error.message.includes('required')
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Extract error code from error object
|
|
173
|
+
*/
|
|
174
|
+
function extractErrorCode(error: Error): string | number | undefined {
|
|
175
|
+
// Try common properties for error codes
|
|
176
|
+
if ('status' in error) {
|
|
177
|
+
// biome-ignore lint/suspicious/noExplicitAny: Dynamic error type
|
|
178
|
+
return (error as any).status;
|
|
179
|
+
}
|
|
180
|
+
if ('statusCode' in error) {
|
|
181
|
+
// biome-ignore lint/suspicious/noExplicitAny: Dynamic error type
|
|
182
|
+
return (error as any).statusCode;
|
|
183
|
+
}
|
|
184
|
+
if ('code' in error) {
|
|
185
|
+
// biome-ignore lint/suspicious/noExplicitAny: Dynamic error type
|
|
186
|
+
return (error as any).code;
|
|
187
|
+
}
|
|
188
|
+
if ('errorCode' in error) {
|
|
189
|
+
// biome-ignore lint/suspicious/noExplicitAny: Dynamic error type
|
|
190
|
+
return (error as any).errorCode;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
return undefined;
|
|
194
|
+
}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import test from 'ava';
|
|
2
|
+
import {
|
|
3
|
+
clearFileListCache,
|
|
4
|
+
getCurrentFileMention,
|
|
5
|
+
} from './file-autocomplete.js';
|
|
6
|
+
import {fuzzyScoreFilePath} from './fuzzy-matching.js';
|
|
7
|
+
|
|
8
|
+
console.log(`\nfile-autocomplete.spec.ts`);
|
|
9
|
+
|
|
10
|
+
// Test fuzzyScoreFilePath()
|
|
11
|
+
test('fuzzy score: exact match gets highest score', t => {
|
|
12
|
+
const score = fuzzyScoreFilePath('app.tsx', 'app.tsx');
|
|
13
|
+
t.is(score, 1000);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
test('fuzzy score: exact filename match', t => {
|
|
17
|
+
const score = fuzzyScoreFilePath('src/components/app.tsx', 'app.tsx');
|
|
18
|
+
t.is(score, 900);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test('fuzzy score: path ends with query', t => {
|
|
22
|
+
const score = fuzzyScoreFilePath('src/components/Button.tsx', 'Button.tsx');
|
|
23
|
+
// This matches exact filename, so it gets 900 not 850
|
|
24
|
+
t.is(score, 900);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
test('fuzzy score: filename starts with query', t => {
|
|
28
|
+
const score = fuzzyScoreFilePath('src/components/Button.tsx', 'butt');
|
|
29
|
+
t.is(score, 800);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
test('fuzzy score: path starts with query', t => {
|
|
33
|
+
const score = fuzzyScoreFilePath('src/components/Button.tsx', 'src/comp');
|
|
34
|
+
t.is(score, 750);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test('fuzzy score: filename contains query', t => {
|
|
38
|
+
const score = fuzzyScoreFilePath('src/components/Button.tsx', 'ton');
|
|
39
|
+
t.is(score, 700);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
test('fuzzy score: path contains query', t => {
|
|
43
|
+
const score = fuzzyScoreFilePath('src/components/Button.tsx', 'compo');
|
|
44
|
+
// "compo" is a substring in path but doesn't start the path
|
|
45
|
+
t.is(score, 600);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
test('fuzzy score: sequential character match', t => {
|
|
49
|
+
const score = fuzzyScoreFilePath('src/components/Button.tsx', 'btn');
|
|
50
|
+
t.true(score > 0 && score < 600);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
test('fuzzy score: no match returns 0', t => {
|
|
54
|
+
const score = fuzzyScoreFilePath('app.tsx', 'xyz');
|
|
55
|
+
t.is(score, 0);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
test('fuzzy score: empty query returns 0', t => {
|
|
59
|
+
const score = fuzzyScoreFilePath('app.tsx', '');
|
|
60
|
+
t.is(score, 0);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
test('fuzzy score: case insensitive', t => {
|
|
64
|
+
const score1 = fuzzyScoreFilePath('App.tsx', 'app');
|
|
65
|
+
const score2 = fuzzyScoreFilePath('app.tsx', 'APP');
|
|
66
|
+
t.true(score1 > 0);
|
|
67
|
+
t.true(score2 > 0);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
test('fuzzy score: prefers shorter paths', t => {
|
|
71
|
+
const shortPath = fuzzyScoreFilePath('app.tsx', 'app');
|
|
72
|
+
const longPath = fuzzyScoreFilePath('src/components/nested/app.tsx', 'app');
|
|
73
|
+
// Both match filename "app.tsx" starting with "app", so they get same score
|
|
74
|
+
// The scoring doesn't currently prefer shorter paths
|
|
75
|
+
t.is(shortPath, longPath);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
test('fuzzy score: consecutive matches get bonus', t => {
|
|
79
|
+
// "but" matches consecutively in "Button"
|
|
80
|
+
const consecutive = fuzzyScoreFilePath('Button.tsx', 'but');
|
|
81
|
+
// "btn" requires skipping characters
|
|
82
|
+
const nonConsecutive = fuzzyScoreFilePath('Button.tsx', 'btn');
|
|
83
|
+
t.true(consecutive > nonConsecutive);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
// Test getCurrentFileMention()
|
|
87
|
+
test('extracts mention at end of string', t => {
|
|
88
|
+
const result = getCurrentFileMention('Fix @src/app');
|
|
89
|
+
t.truthy(result);
|
|
90
|
+
t.is(result!.mention, 'src/app');
|
|
91
|
+
t.is(result!.startIndex, 4);
|
|
92
|
+
t.is(result!.endIndex, 12);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
test('extracts mention in middle of string', t => {
|
|
96
|
+
// Cursor at position 15 is right after "x" in ".tsx"
|
|
97
|
+
const result = getCurrentFileMention('Check @app.tsx please', 14);
|
|
98
|
+
t.truthy(result);
|
|
99
|
+
t.is(result!.mention, 'app.tsx');
|
|
100
|
+
t.is(result!.startIndex, 6);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
test('extracts mention with cursor in middle', t => {
|
|
104
|
+
const result = getCurrentFileMention('Fix @src/ap', 11);
|
|
105
|
+
t.truthy(result);
|
|
106
|
+
t.is(result!.mention, 'src/ap');
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
test('returns null when no @ symbol', t => {
|
|
110
|
+
const result = getCurrentFileMention('Just regular text');
|
|
111
|
+
t.is(result, null);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
test('returns null when @ is after cursor', t => {
|
|
115
|
+
const result = getCurrentFileMention('Text @file.txt', 3);
|
|
116
|
+
t.is(result, null);
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
test('returns null when @ is followed by space', t => {
|
|
120
|
+
const result = getCurrentFileMention('Fix @ file.txt');
|
|
121
|
+
t.is(result, null);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
test('strips line range from mention', t => {
|
|
125
|
+
const result = getCurrentFileMention('Fix @app.tsx:10-20');
|
|
126
|
+
t.truthy(result);
|
|
127
|
+
t.is(result!.mention, 'app.tsx');
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
test('strips single line number from mention', t => {
|
|
131
|
+
const result = getCurrentFileMention('Fix @app.tsx:10');
|
|
132
|
+
t.truthy(result);
|
|
133
|
+
t.is(result!.mention, 'app.tsx');
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
test('handles multiple @ symbols', t => {
|
|
137
|
+
const result = getCurrentFileMention('Compare @a.ts and @b.ts', 24);
|
|
138
|
+
t.truthy(result);
|
|
139
|
+
t.is(result!.mention, 'b.ts');
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
test('handles @ at start of string', t => {
|
|
143
|
+
const result = getCurrentFileMention('@app.tsx');
|
|
144
|
+
t.truthy(result);
|
|
145
|
+
t.is(result!.mention, 'app.tsx');
|
|
146
|
+
t.is(result!.startIndex, 0);
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
test('handles path with slashes', t => {
|
|
150
|
+
const result = getCurrentFileMention('@src/components/Button.tsx');
|
|
151
|
+
t.truthy(result);
|
|
152
|
+
t.is(result!.mention, 'src/components/Button.tsx');
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
test('stops at whitespace', t => {
|
|
156
|
+
// When cursor is at end (after "here"), we look back and hit whitespace
|
|
157
|
+
// So we should use cursor position right after the file mention
|
|
158
|
+
const result = getCurrentFileMention('@app.tsx here', 8);
|
|
159
|
+
t.truthy(result);
|
|
160
|
+
t.is(result!.mention, 'app.tsx');
|
|
161
|
+
t.is(result!.endIndex, 8);
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
test('stops at next @ symbol', t => {
|
|
165
|
+
const result = getCurrentFileMention('@app.tsx@other', 8);
|
|
166
|
+
t.truthy(result);
|
|
167
|
+
t.is(result!.mention, 'app.tsx');
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
// Clear cache between tests (if needed)
|
|
171
|
+
test.afterEach(() => {
|
|
172
|
+
clearFileListCache();
|
|
173
|
+
});
|