@gguf/coder 0.3.0 → 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/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,466 @@
|
|
|
1
|
+
import {existsSync} from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import {TRUNCATION_DESCRIPTION_LENGTH} from '@/constants';
|
|
4
|
+
import type {
|
|
5
|
+
CheckpointConversation,
|
|
6
|
+
CheckpointData,
|
|
7
|
+
CheckpointListItem,
|
|
8
|
+
CheckpointMetadata,
|
|
9
|
+
CheckpointRestoreOptions,
|
|
10
|
+
CheckpointValidationResult,
|
|
11
|
+
} from '@/types/checkpoint';
|
|
12
|
+
import type {Message} from '@/types/core';
|
|
13
|
+
import {validateCheckpointName} from '@/utils/checkpoint-utils';
|
|
14
|
+
import {logWarning} from '@/utils/message-queue';
|
|
15
|
+
import * as fs from 'fs/promises';
|
|
16
|
+
import {FileSnapshotService} from './file-snapshot';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Service for managing conversation checkpoints.
|
|
20
|
+
* Checkpoints are stored in .coder/checkpoints/ within the workspace root.
|
|
21
|
+
*/
|
|
22
|
+
export class CheckpointManager {
|
|
23
|
+
private readonly checkpointsDir: string;
|
|
24
|
+
private readonly fileSnapshotService: FileSnapshotService;
|
|
25
|
+
|
|
26
|
+
constructor(workspaceRoot: string = process.cwd()) {
|
|
27
|
+
// nosemgrep
|
|
28
|
+
this.checkpointsDir = path.join(workspaceRoot, '.coder', 'checkpoints'); // nosemgrep
|
|
29
|
+
this.fileSnapshotService = new FileSnapshotService(workspaceRoot);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Initialize the checkpoints directory
|
|
34
|
+
*/
|
|
35
|
+
private async ensureCheckpointsDir(): Promise<void> {
|
|
36
|
+
if (!existsSync(this.checkpointsDir)) {
|
|
37
|
+
await fs.mkdir(this.checkpointsDir, {recursive: true});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Generate a checkpoint name based on timestamp
|
|
43
|
+
*/
|
|
44
|
+
private generateCheckpointName(): string {
|
|
45
|
+
const now = new Date();
|
|
46
|
+
const timestamp = now
|
|
47
|
+
.toISOString()
|
|
48
|
+
.replace(/[:.]/g, '-')
|
|
49
|
+
.replace('T', '-')
|
|
50
|
+
.split('.')[0];
|
|
51
|
+
return `checkpoint-${timestamp}`;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Get the directory path for a specific checkpoint
|
|
56
|
+
*/
|
|
57
|
+
// nosemgrep
|
|
58
|
+
private getCheckpointDir(name: string): string {
|
|
59
|
+
return path.join(this.checkpointsDir, name); // nosemgrep
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Validate checkpoint name using shared utility
|
|
64
|
+
*/
|
|
65
|
+
private validateName(name: string): void {
|
|
66
|
+
const result = validateCheckpointName(name);
|
|
67
|
+
if (!result.valid) {
|
|
68
|
+
throw new Error(result.error || 'Invalid checkpoint name');
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Generate metadata description from messages
|
|
74
|
+
*/
|
|
75
|
+
private generateDescription(messages: Message[]): string {
|
|
76
|
+
const userMessages = messages.filter(m => m.role === 'user');
|
|
77
|
+
if (userMessages.length === 0) {
|
|
78
|
+
return 'Empty conversation';
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const firstMessage = userMessages[0].content;
|
|
82
|
+
// Take first characters and add ellipsis if longer
|
|
83
|
+
return firstMessage.length > TRUNCATION_DESCRIPTION_LENGTH
|
|
84
|
+
? `${firstMessage.substring(0, TRUNCATION_DESCRIPTION_LENGTH)}...`
|
|
85
|
+
: firstMessage;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Save a checkpoint
|
|
90
|
+
*/
|
|
91
|
+
async saveCheckpoint(
|
|
92
|
+
name: string | undefined,
|
|
93
|
+
messages: Message[],
|
|
94
|
+
provider: string,
|
|
95
|
+
model: string,
|
|
96
|
+
modifiedFiles?: string[],
|
|
97
|
+
): Promise<CheckpointMetadata> {
|
|
98
|
+
await this.ensureCheckpointsDir();
|
|
99
|
+
|
|
100
|
+
// Generate name if not provided
|
|
101
|
+
const checkpointName = name || this.generateCheckpointName();
|
|
102
|
+
this.validateName(checkpointName);
|
|
103
|
+
|
|
104
|
+
const checkpointDir = this.getCheckpointDir(checkpointName);
|
|
105
|
+
|
|
106
|
+
// Check if checkpoint already exists
|
|
107
|
+
if (existsSync(checkpointDir)) {
|
|
108
|
+
throw new Error(`Checkpoint '${checkpointName}' already exists`);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Get modified files if not provided
|
|
112
|
+
const filesToSnapshot =
|
|
113
|
+
modifiedFiles || this.fileSnapshotService.getModifiedFiles();
|
|
114
|
+
|
|
115
|
+
// Capture file snapshots
|
|
116
|
+
const fileSnapshots =
|
|
117
|
+
await this.fileSnapshotService.captureFiles(filesToSnapshot);
|
|
118
|
+
|
|
119
|
+
// Create metadata
|
|
120
|
+
const metadata: CheckpointMetadata = {
|
|
121
|
+
name: checkpointName,
|
|
122
|
+
timestamp: new Date().toISOString(),
|
|
123
|
+
messageCount: messages.length,
|
|
124
|
+
filesChanged: Array.from(fileSnapshots.keys()),
|
|
125
|
+
provider: {name: provider, model},
|
|
126
|
+
description: this.generateDescription(messages),
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
// Create conversation data
|
|
130
|
+
const conversation: CheckpointConversation = {
|
|
131
|
+
messages: messages.map(msg => ({...msg})), // Deep copy
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
// Create checkpoint directory and files
|
|
135
|
+
await fs.mkdir(checkpointDir, {recursive: true});
|
|
136
|
+
|
|
137
|
+
// nosemgrep
|
|
138
|
+
// Save metadata
|
|
139
|
+
await fs.writeFile(
|
|
140
|
+
path.join(checkpointDir, 'metadata.json'), // nosemgrep
|
|
141
|
+
JSON.stringify(metadata, null, 2),
|
|
142
|
+
'utf-8',
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
// nosemgrep
|
|
146
|
+
// Save conversation
|
|
147
|
+
await fs.writeFile(
|
|
148
|
+
path.join(checkpointDir, 'conversation.json'), // nosemgrep
|
|
149
|
+
JSON.stringify(conversation, null, 2),
|
|
150
|
+
'utf-8',
|
|
151
|
+
);
|
|
152
|
+
|
|
153
|
+
// nosemgrep
|
|
154
|
+
// Save file snapshots
|
|
155
|
+
if (fileSnapshots.size > 0) {
|
|
156
|
+
const filesDir = path.join(checkpointDir, 'files'); // nosemgrep
|
|
157
|
+
await fs.mkdir(filesDir, {recursive: true});
|
|
158
|
+
|
|
159
|
+
for (const [relativePath, content] of fileSnapshots) {
|
|
160
|
+
const filePath = path.join(filesDir, relativePath); // nosemgrep
|
|
161
|
+
const fileDir = path.dirname(filePath);
|
|
162
|
+
await fs.mkdir(fileDir, {recursive: true});
|
|
163
|
+
await fs.writeFile(filePath, content, 'utf-8');
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return metadata;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Load a checkpoint
|
|
172
|
+
*/
|
|
173
|
+
async loadCheckpoint(
|
|
174
|
+
name: string,
|
|
175
|
+
options: CheckpointRestoreOptions = {},
|
|
176
|
+
): Promise<CheckpointData> {
|
|
177
|
+
const checkpointDir = this.getCheckpointDir(name);
|
|
178
|
+
|
|
179
|
+
if (!existsSync(checkpointDir)) {
|
|
180
|
+
throw new Error(`Checkpoint '${name}' does not exist`);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Validate checkpoint if requested
|
|
184
|
+
if (options.validateIntegrity) {
|
|
185
|
+
const validation = await this.validateCheckpoint(name);
|
|
186
|
+
if (!validation.valid) {
|
|
187
|
+
throw new Error(
|
|
188
|
+
`Checkpoint validation failed: ${validation.errors.join(', ')}`,
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// nosemgrep
|
|
194
|
+
// Load metadata
|
|
195
|
+
const metadataPath = path.join(checkpointDir, 'metadata.json'); // nosemgrep
|
|
196
|
+
const metadataContent = await fs.readFile(metadataPath, 'utf-8');
|
|
197
|
+
const metadata = JSON.parse(metadataContent) as CheckpointMetadata;
|
|
198
|
+
|
|
199
|
+
// nosemgrep
|
|
200
|
+
// Load conversation
|
|
201
|
+
const conversationPath = path.join(checkpointDir, 'conversation.json'); // nosemgrep
|
|
202
|
+
const conversationContent = await fs.readFile(conversationPath, 'utf-8');
|
|
203
|
+
const conversation = JSON.parse(
|
|
204
|
+
conversationContent,
|
|
205
|
+
) as CheckpointConversation;
|
|
206
|
+
|
|
207
|
+
// nosemgrep
|
|
208
|
+
// Load file snapshots
|
|
209
|
+
const fileSnapshots = new Map<string, string>();
|
|
210
|
+
const filesDir = path.join(checkpointDir, 'files'); // nosemgrep
|
|
211
|
+
|
|
212
|
+
if (existsSync(filesDir)) {
|
|
213
|
+
for (const relativePath of metadata.filesChanged) {
|
|
214
|
+
try {
|
|
215
|
+
const filePath = path.join(filesDir, relativePath); // nosemgrep
|
|
216
|
+
const content = await fs.readFile(filePath, 'utf-8');
|
|
217
|
+
fileSnapshots.set(relativePath, content);
|
|
218
|
+
} catch (error) {
|
|
219
|
+
logWarning('Could not load file snapshot', true, {
|
|
220
|
+
context: {
|
|
221
|
+
relativePath,
|
|
222
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
223
|
+
},
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
return {
|
|
230
|
+
metadata,
|
|
231
|
+
conversation,
|
|
232
|
+
fileSnapshots,
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* List all available checkpoints
|
|
238
|
+
*/
|
|
239
|
+
async listCheckpoints(): Promise<CheckpointListItem[]> {
|
|
240
|
+
await this.ensureCheckpointsDir();
|
|
241
|
+
|
|
242
|
+
try {
|
|
243
|
+
const entries = await fs.readdir(this.checkpointsDir);
|
|
244
|
+
const checkpoints: CheckpointListItem[] = [];
|
|
245
|
+
|
|
246
|
+
for (const entry of entries) {
|
|
247
|
+
try {
|
|
248
|
+
const checkpointDir = path.join(this.checkpointsDir, entry); // nosemgrep
|
|
249
|
+
const stat = await fs.stat(checkpointDir);
|
|
250
|
+
|
|
251
|
+
if (stat.isDirectory()) {
|
|
252
|
+
const metadataPath = path.join(checkpointDir, 'metadata.json'); // nosemgrep
|
|
253
|
+
if (existsSync(metadataPath)) {
|
|
254
|
+
const metadataContent = await fs.readFile(metadataPath, 'utf-8');
|
|
255
|
+
const metadata = JSON.parse(
|
|
256
|
+
metadataContent,
|
|
257
|
+
) as CheckpointMetadata;
|
|
258
|
+
|
|
259
|
+
// Calculate directory size
|
|
260
|
+
const sizeBytes =
|
|
261
|
+
await this.calculateDirectorySize(checkpointDir);
|
|
262
|
+
|
|
263
|
+
checkpoints.push({
|
|
264
|
+
name: entry,
|
|
265
|
+
metadata,
|
|
266
|
+
sizeBytes,
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
} catch (error) {
|
|
271
|
+
logWarning('Could not read checkpoint', true, {
|
|
272
|
+
context: {
|
|
273
|
+
checkpointName: entry,
|
|
274
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
275
|
+
},
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// Sort by timestamp (newest first)
|
|
281
|
+
checkpoints.sort(
|
|
282
|
+
(a, b) =>
|
|
283
|
+
new Date(b.metadata.timestamp).getTime() -
|
|
284
|
+
new Date(a.metadata.timestamp).getTime(),
|
|
285
|
+
);
|
|
286
|
+
|
|
287
|
+
return checkpoints;
|
|
288
|
+
} catch (error) {
|
|
289
|
+
throw new Error(
|
|
290
|
+
`Failed to list checkpoints: ${
|
|
291
|
+
error instanceof Error ? error.message : 'Unknown error'
|
|
292
|
+
}`,
|
|
293
|
+
);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Delete a checkpoint
|
|
299
|
+
*/
|
|
300
|
+
async deleteCheckpoint(name: string): Promise<void> {
|
|
301
|
+
const checkpointDir = this.getCheckpointDir(name);
|
|
302
|
+
|
|
303
|
+
if (!existsSync(checkpointDir)) {
|
|
304
|
+
throw new Error(`Checkpoint '${name}' does not exist`);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
try {
|
|
308
|
+
await fs.rm(checkpointDir, {recursive: true, force: true});
|
|
309
|
+
} catch (error) {
|
|
310
|
+
throw new Error(
|
|
311
|
+
`Failed to delete checkpoint '${name}': ${
|
|
312
|
+
error instanceof Error ? error.message : 'Unknown error'
|
|
313
|
+
}`,
|
|
314
|
+
);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Validate checkpoint integrity
|
|
320
|
+
*/
|
|
321
|
+
async validateCheckpoint(name: string): Promise<CheckpointValidationResult> {
|
|
322
|
+
const checkpointDir = this.getCheckpointDir(name);
|
|
323
|
+
const errors: string[] = [];
|
|
324
|
+
const warnings: string[] = [];
|
|
325
|
+
|
|
326
|
+
// Check if checkpoint directory exists
|
|
327
|
+
if (!existsSync(checkpointDir)) {
|
|
328
|
+
errors.push('Checkpoint directory does not exist');
|
|
329
|
+
return {valid: false, errors, warnings};
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// Check metadata file
|
|
333
|
+
const metadataPath = path.join(checkpointDir, 'metadata.json'); // nosemgrep
|
|
334
|
+
if (!existsSync(metadataPath)) {
|
|
335
|
+
errors.push('Missing metadata.json file');
|
|
336
|
+
} else {
|
|
337
|
+
try {
|
|
338
|
+
const metadataContent = await fs.readFile(metadataPath, 'utf-8');
|
|
339
|
+
const metadata = JSON.parse(metadataContent) as CheckpointMetadata;
|
|
340
|
+
|
|
341
|
+
// Validate metadata structure
|
|
342
|
+
if (
|
|
343
|
+
!metadata.name ||
|
|
344
|
+
!metadata.timestamp ||
|
|
345
|
+
typeof metadata.messageCount !== 'number'
|
|
346
|
+
) {
|
|
347
|
+
errors.push('Invalid metadata structure');
|
|
348
|
+
}
|
|
349
|
+
} catch (error) {
|
|
350
|
+
errors.push(
|
|
351
|
+
`Invalid metadata.json: ${
|
|
352
|
+
error instanceof Error ? error.message : 'Unknown error'
|
|
353
|
+
}`,
|
|
354
|
+
);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// Check conversation file
|
|
359
|
+
const conversationPath = path.join(checkpointDir, 'conversation.json'); // nosemgrep
|
|
360
|
+
if (!existsSync(conversationPath)) {
|
|
361
|
+
errors.push('Missing conversation.json file');
|
|
362
|
+
} else {
|
|
363
|
+
try {
|
|
364
|
+
const conversationContent = await fs.readFile(
|
|
365
|
+
conversationPath,
|
|
366
|
+
'utf-8',
|
|
367
|
+
);
|
|
368
|
+
const conversation = JSON.parse(
|
|
369
|
+
conversationContent,
|
|
370
|
+
) as CheckpointConversation;
|
|
371
|
+
|
|
372
|
+
// Validate conversation structure
|
|
373
|
+
if (!Array.isArray(conversation.messages)) {
|
|
374
|
+
errors.push('Invalid conversation structure');
|
|
375
|
+
}
|
|
376
|
+
} catch (error) {
|
|
377
|
+
errors.push(
|
|
378
|
+
`Invalid conversation.json: ${
|
|
379
|
+
error instanceof Error ? error.message : 'Unknown error'
|
|
380
|
+
}`,
|
|
381
|
+
);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
return {
|
|
386
|
+
valid: errors.length === 0,
|
|
387
|
+
errors,
|
|
388
|
+
warnings,
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* Restore files from a checkpoint
|
|
394
|
+
*/
|
|
395
|
+
async restoreFiles(checkpointData: CheckpointData): Promise<void> {
|
|
396
|
+
if (checkpointData.fileSnapshots.size === 0) {
|
|
397
|
+
return; // No files to restore
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// Validate restore paths
|
|
401
|
+
const validation = await this.fileSnapshotService.validateRestorePath(
|
|
402
|
+
checkpointData.fileSnapshots,
|
|
403
|
+
);
|
|
404
|
+
if (!validation.valid) {
|
|
405
|
+
throw new Error(`Cannot restore files: ${validation.errors.join(', ')}`);
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
// Restore files
|
|
409
|
+
await this.fileSnapshotService.restoreFiles(checkpointData.fileSnapshots);
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
/**
|
|
413
|
+
* Calculate the total size of a directory
|
|
414
|
+
*/
|
|
415
|
+
private async calculateDirectorySize(dirPath: string): Promise<number> {
|
|
416
|
+
let totalSize = 0;
|
|
417
|
+
|
|
418
|
+
try {
|
|
419
|
+
const entries = await fs.readdir(dirPath, {withFileTypes: true});
|
|
420
|
+
|
|
421
|
+
for (const entry of entries) {
|
|
422
|
+
const fullPath = path.join(dirPath, entry.name); // nosemgrep
|
|
423
|
+
|
|
424
|
+
if (entry.isDirectory()) {
|
|
425
|
+
totalSize += await this.calculateDirectorySize(fullPath);
|
|
426
|
+
} else {
|
|
427
|
+
const stat = await fs.stat(fullPath);
|
|
428
|
+
totalSize += stat.size;
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
} catch (error) {
|
|
432
|
+
// If we can't read the directory, just return 0
|
|
433
|
+
logWarning('Could not calculate directory size', true, {
|
|
434
|
+
context: {
|
|
435
|
+
dirPath,
|
|
436
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
437
|
+
},
|
|
438
|
+
});
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
return totalSize;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
/**
|
|
445
|
+
* Check if a checkpoint exists
|
|
446
|
+
*/
|
|
447
|
+
checkpointExists(name: string): boolean {
|
|
448
|
+
const checkpointDir = this.getCheckpointDir(name);
|
|
449
|
+
return existsSync(checkpointDir);
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
/**
|
|
453
|
+
* Get checkpoint metadata without loading full data
|
|
454
|
+
*/
|
|
455
|
+
async getCheckpointMetadata(name: string): Promise<CheckpointMetadata> {
|
|
456
|
+
const checkpointDir = this.getCheckpointDir(name);
|
|
457
|
+
|
|
458
|
+
if (!existsSync(checkpointDir)) {
|
|
459
|
+
throw new Error(`Checkpoint '${name}' does not exist`);
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
const metadataPath = path.join(checkpointDir, 'metadata.json'); // nosemgrep
|
|
463
|
+
const metadataContent = await fs.readFile(metadataPath, 'utf-8');
|
|
464
|
+
return JSON.parse(metadataContent) as CheckpointMetadata;
|
|
465
|
+
}
|
|
466
|
+
}
|