@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,34 @@
|
|
|
1
|
+
import {useTheme} from '@/hooks/useTheme';
|
|
2
|
+
import {parseMarkdown} from '@/markdown-parser/index';
|
|
3
|
+
import type {AssistantMessageProps} from '@/types/index';
|
|
4
|
+
import {Box, Text} from 'ink';
|
|
5
|
+
import {memo, useMemo} from 'react';
|
|
6
|
+
|
|
7
|
+
export default memo(function AssistantMessage({
|
|
8
|
+
message,
|
|
9
|
+
model,
|
|
10
|
+
}: AssistantMessageProps) {
|
|
11
|
+
const {colors} = useTheme();
|
|
12
|
+
|
|
13
|
+
// Render markdown to terminal-formatted text with theme colors
|
|
14
|
+
// Add trailing newline to ensure consistent spacing after message
|
|
15
|
+
const renderedMessage = useMemo(() => {
|
|
16
|
+
try {
|
|
17
|
+
return parseMarkdown(message, colors).trimEnd() + '\n';
|
|
18
|
+
} catch {
|
|
19
|
+
// Fallback to plain text if markdown parsing fails
|
|
20
|
+
return message.trimEnd() + '\n';
|
|
21
|
+
}
|
|
22
|
+
}, [message, colors]);
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<Box flexDirection="column" marginBottom={1}>
|
|
26
|
+
<Box marginBottom={1}>
|
|
27
|
+
<Text color={colors.primary} bold>
|
|
28
|
+
{model}:
|
|
29
|
+
</Text>
|
|
30
|
+
</Box>
|
|
31
|
+
<Text>{renderedMessage}</Text>
|
|
32
|
+
</Box>
|
|
33
|
+
);
|
|
34
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import {useTheme} from '@/hooks/useTheme';
|
|
2
|
+
import type {BashExecutionIndicatorProps} from '@/types/index';
|
|
3
|
+
import {Box, Text} from 'ink';
|
|
4
|
+
import {memo} from 'react';
|
|
5
|
+
|
|
6
|
+
export default memo(function BashExecutionIndicator({
|
|
7
|
+
command,
|
|
8
|
+
}: BashExecutionIndicatorProps) {
|
|
9
|
+
const {colors} = useTheme();
|
|
10
|
+
return (
|
|
11
|
+
<Box flexDirection="column" marginBottom={1}>
|
|
12
|
+
<Box flexDirection="row">
|
|
13
|
+
<Text color={colors.tool}>● Executing: </Text>
|
|
14
|
+
<Text color={colors.secondary}>{command}</Text>
|
|
15
|
+
</Box>
|
|
16
|
+
<Box marginTop={1}>
|
|
17
|
+
<Text color={colors.secondary}>Press Escape to cancel</Text>
|
|
18
|
+
</Box>
|
|
19
|
+
</Box>
|
|
20
|
+
);
|
|
21
|
+
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { useTheme } from '@/hooks/useTheme';
|
|
2
|
+
import { Box, Text } from 'ink';
|
|
3
|
+
import RandomSpinner from '@/components/random-spinner';
|
|
4
|
+
import { memo } from 'react';
|
|
5
|
+
|
|
6
|
+
export default memo(function CancellingIndicator() {
|
|
7
|
+
const { colors } = useTheme();
|
|
8
|
+
return (
|
|
9
|
+
<Box flexDirection="column" marginBottom={1}>
|
|
10
|
+
<Box>
|
|
11
|
+
<RandomSpinner />
|
|
12
|
+
<Text color={colors.secondary}> Cancelling...</Text>
|
|
13
|
+
</Box>
|
|
14
|
+
</Box>
|
|
15
|
+
);
|
|
16
|
+
});
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import test from 'ava';
|
|
2
|
+
import {Box} from 'ink';
|
|
3
|
+
import {render} from 'ink-testing-library';
|
|
4
|
+
import React from 'react';
|
|
5
|
+
import ChatQueue from './chat-queue';
|
|
6
|
+
|
|
7
|
+
test('ChatQueue renders without components', t => {
|
|
8
|
+
t.notThrows(() => {
|
|
9
|
+
render(<ChatQueue staticComponents={[]} queuedComponents={[]} />);
|
|
10
|
+
});
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
test('ChatQueue renders with static components', t => {
|
|
14
|
+
const components = [
|
|
15
|
+
<Box key="1">First message</Box>,
|
|
16
|
+
<Box key="2">Second message</Box>,
|
|
17
|
+
];
|
|
18
|
+
|
|
19
|
+
t.notThrows(() => {
|
|
20
|
+
render(<ChatQueue staticComponents={components} queuedComponents={[]} />);
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test('ChatQueue renders with queued components', t => {
|
|
25
|
+
const components = [
|
|
26
|
+
<Box key="1">Queued message</Box>,
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
t.notThrows(() => {
|
|
30
|
+
render(<ChatQueue staticComponents={[]} queuedComponents={components} />);
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
test('ChatQueue renders with both static and queued components', t => {
|
|
35
|
+
const staticComponents = [
|
|
36
|
+
<Box key="1">Static message</Box>,
|
|
37
|
+
];
|
|
38
|
+
const queuedComponents = [
|
|
39
|
+
<Box key="2">Queued message</Box>,
|
|
40
|
+
];
|
|
41
|
+
|
|
42
|
+
t.notThrows(() => {
|
|
43
|
+
render(
|
|
44
|
+
<ChatQueue staticComponents={staticComponents} queuedComponents={queuedComponents} />,
|
|
45
|
+
);
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
test('ChatQueue merges static and queued components', t => {
|
|
50
|
+
const {lastFrame} = render(
|
|
51
|
+
<ChatQueue
|
|
52
|
+
staticComponents={[<Box key="1">Static</Box>]}
|
|
53
|
+
queuedComponents={[<Box key="2">Queued</Box>]}
|
|
54
|
+
/>,
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
const output = lastFrame();
|
|
58
|
+
t.truthy(output);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test('ChatQueue component can be unmounted', t => {
|
|
62
|
+
const {unmount} = render(<ChatQueue staticComponents={[]} queuedComponents={[]} />);
|
|
63
|
+
|
|
64
|
+
t.notThrows(() => {
|
|
65
|
+
unmount();
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
test('ChatQueue re-renders without crashing', t => {
|
|
70
|
+
const {rerender} = render(<ChatQueue staticComponents={[]} queuedComponents={[]} />);
|
|
71
|
+
|
|
72
|
+
t.notThrows(() => {
|
|
73
|
+
rerender(<ChatQueue staticComponents={[]} queuedComponents={[]} />);
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
test('ChatQueue handles components without keys', t => {
|
|
78
|
+
const components = [<Box key="1">No key component</Box>];
|
|
79
|
+
|
|
80
|
+
t.notThrows(() => {
|
|
81
|
+
render(<ChatQueue staticComponents={components} queuedComponents={[]} />);
|
|
82
|
+
});
|
|
83
|
+
});
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type {ChatQueueProps} from '@/types/index';
|
|
2
|
+
import {Box, Static} from 'ink';
|
|
3
|
+
import {Fragment, memo, useMemo} from 'react';
|
|
4
|
+
|
|
5
|
+
export default memo(function ChatQueue({
|
|
6
|
+
staticComponents = [],
|
|
7
|
+
queuedComponents = [],
|
|
8
|
+
}: ChatQueueProps) {
|
|
9
|
+
// Move ALL messages to static - prevents any re-renders
|
|
10
|
+
// All messages are now immutable once rendered
|
|
11
|
+
const allStaticComponents = useMemo(
|
|
12
|
+
() => [...staticComponents, ...queuedComponents],
|
|
13
|
+
[staticComponents, queuedComponents],
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<Box flexDirection="column">
|
|
18
|
+
{/* All content is static to prevent re-renders */}
|
|
19
|
+
{allStaticComponents.length > 0 && (
|
|
20
|
+
<Static items={allStaticComponents}>
|
|
21
|
+
{(component, index) => {
|
|
22
|
+
const key =
|
|
23
|
+
component &&
|
|
24
|
+
typeof component === 'object' &&
|
|
25
|
+
'key' in component &&
|
|
26
|
+
component.key
|
|
27
|
+
? component.key
|
|
28
|
+
: `static-${index}`;
|
|
29
|
+
|
|
30
|
+
return <Fragment key={key}>{component}</Fragment>;
|
|
31
|
+
}}
|
|
32
|
+
</Static>
|
|
33
|
+
)}
|
|
34
|
+
</Box>
|
|
35
|
+
);
|
|
36
|
+
});
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import {renderWithTheme} from '@/test-utils/render-with-theme';
|
|
2
|
+
import type {CheckpointListItem} from '@/types/checkpoint';
|
|
3
|
+
import test from 'ava';
|
|
4
|
+
import React from 'react';
|
|
5
|
+
import {CheckpointListDisplay} from './checkpoint-display';
|
|
6
|
+
|
|
7
|
+
const createMockCheckpoint = (
|
|
8
|
+
name: string,
|
|
9
|
+
overrides: Partial<CheckpointListItem> = {},
|
|
10
|
+
): CheckpointListItem => ({
|
|
11
|
+
name,
|
|
12
|
+
metadata: {
|
|
13
|
+
name,
|
|
14
|
+
timestamp: new Date().toISOString(),
|
|
15
|
+
messageCount: 10,
|
|
16
|
+
filesChanged: ['file1.ts', 'file2.ts'],
|
|
17
|
+
provider: {name: 'Test Provider', model: 'test-model'},
|
|
18
|
+
description: 'Test checkpoint',
|
|
19
|
+
},
|
|
20
|
+
sizeBytes: 1024,
|
|
21
|
+
...overrides,
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test('CheckpointListDisplay renders empty state when no checkpoints', t => {
|
|
25
|
+
const {lastFrame} = renderWithTheme(
|
|
26
|
+
<CheckpointListDisplay checkpoints={[]} />,
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
const output = lastFrame() || '';
|
|
30
|
+
t.true(output.includes('No checkpoints found'));
|
|
31
|
+
t.true(output.includes('/checkpoint create'));
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
test('CheckpointListDisplay renders with default title', t => {
|
|
35
|
+
const checkpoints = [createMockCheckpoint('test-checkpoint')];
|
|
36
|
+
const {lastFrame} = renderWithTheme(
|
|
37
|
+
<CheckpointListDisplay checkpoints={checkpoints} />,
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
const output = lastFrame() || '';
|
|
41
|
+
t.true(output.includes('Available Checkpoints'));
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
test('CheckpointListDisplay renders with custom title', t => {
|
|
45
|
+
const checkpoints = [createMockCheckpoint('test-checkpoint')];
|
|
46
|
+
const {lastFrame} = renderWithTheme(
|
|
47
|
+
<CheckpointListDisplay checkpoints={checkpoints} title="My Checkpoints" />,
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
const output = lastFrame() || '';
|
|
51
|
+
t.true(output.includes('My Checkpoints'));
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test('CheckpointListDisplay renders checkpoint name', t => {
|
|
55
|
+
const checkpoints = [createMockCheckpoint('my-test-checkpoint')];
|
|
56
|
+
const {lastFrame} = renderWithTheme(
|
|
57
|
+
<CheckpointListDisplay checkpoints={checkpoints} />,
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
const output = lastFrame() || '';
|
|
61
|
+
t.true(output.includes('my-test-checkpoint'));
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
test('CheckpointListDisplay truncates long checkpoint names', t => {
|
|
65
|
+
const longName = 'this-is-a-very-long-checkpoint-name-that-exceeds-limit';
|
|
66
|
+
const checkpoints = [createMockCheckpoint(longName)];
|
|
67
|
+
const {lastFrame} = renderWithTheme(
|
|
68
|
+
<CheckpointListDisplay checkpoints={checkpoints} />,
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
const output = lastFrame() || '';
|
|
72
|
+
// Should be truncated with ...
|
|
73
|
+
t.true(output.includes('...'));
|
|
74
|
+
t.false(output.includes(longName)); // Full name should not appear
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
test('CheckpointListDisplay renders message count', t => {
|
|
78
|
+
const checkpoints = [
|
|
79
|
+
createMockCheckpoint('test', {
|
|
80
|
+
metadata: {
|
|
81
|
+
name: 'test',
|
|
82
|
+
timestamp: new Date().toISOString(),
|
|
83
|
+
messageCount: 42,
|
|
84
|
+
filesChanged: [],
|
|
85
|
+
provider: {name: 'Test', model: 'model'},
|
|
86
|
+
},
|
|
87
|
+
}),
|
|
88
|
+
];
|
|
89
|
+
const {lastFrame} = renderWithTheme(
|
|
90
|
+
<CheckpointListDisplay checkpoints={checkpoints} />,
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
const output = lastFrame() || '';
|
|
94
|
+
t.true(output.includes('42'));
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
test('CheckpointListDisplay renders files count', t => {
|
|
98
|
+
const checkpoints = [
|
|
99
|
+
createMockCheckpoint('test', {
|
|
100
|
+
metadata: {
|
|
101
|
+
name: 'test',
|
|
102
|
+
timestamp: new Date().toISOString(),
|
|
103
|
+
messageCount: 10,
|
|
104
|
+
filesChanged: ['a.ts', 'b.ts', 'c.ts'],
|
|
105
|
+
provider: {name: 'Test', model: 'model'},
|
|
106
|
+
},
|
|
107
|
+
}),
|
|
108
|
+
];
|
|
109
|
+
const {lastFrame} = renderWithTheme(
|
|
110
|
+
<CheckpointListDisplay checkpoints={checkpoints} />,
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
const output = lastFrame() || '';
|
|
114
|
+
t.true(output.includes('3'));
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
test('CheckpointListDisplay renders size in KB', t => {
|
|
118
|
+
const checkpoints = [createMockCheckpoint('test', {sizeBytes: 2048})];
|
|
119
|
+
const {lastFrame} = renderWithTheme(
|
|
120
|
+
<CheckpointListDisplay checkpoints={checkpoints} />,
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
const output = lastFrame() || '';
|
|
124
|
+
t.true(output.includes('2KB'));
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
test('CheckpointListDisplay renders size in MB', t => {
|
|
128
|
+
const checkpoints = [
|
|
129
|
+
createMockCheckpoint('test', {sizeBytes: 2 * 1024 * 1024}),
|
|
130
|
+
];
|
|
131
|
+
const {lastFrame} = renderWithTheme(
|
|
132
|
+
<CheckpointListDisplay checkpoints={checkpoints} />,
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
const output = lastFrame() || '';
|
|
136
|
+
t.true(output.includes('2.0MB'));
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
test('CheckpointListDisplay renders size in bytes for small files', t => {
|
|
140
|
+
const checkpoints = [createMockCheckpoint('test', {sizeBytes: 500})];
|
|
141
|
+
const {lastFrame} = renderWithTheme(
|
|
142
|
+
<CheckpointListDisplay checkpoints={checkpoints} />,
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
const output = lastFrame() || '';
|
|
146
|
+
t.true(output.includes('500B'));
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
test('CheckpointListDisplay renders multiple checkpoints', t => {
|
|
150
|
+
const checkpoints = [
|
|
151
|
+
createMockCheckpoint('checkpoint-1'),
|
|
152
|
+
createMockCheckpoint('checkpoint-2'),
|
|
153
|
+
createMockCheckpoint('checkpoint-3'),
|
|
154
|
+
];
|
|
155
|
+
const {lastFrame} = renderWithTheme(
|
|
156
|
+
<CheckpointListDisplay checkpoints={checkpoints} />,
|
|
157
|
+
);
|
|
158
|
+
|
|
159
|
+
const output = lastFrame() || '';
|
|
160
|
+
t.true(output.includes('checkpoint-1'));
|
|
161
|
+
t.true(output.includes('checkpoint-2'));
|
|
162
|
+
t.true(output.includes('checkpoint-3'));
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
test('CheckpointListDisplay renders table headers', t => {
|
|
166
|
+
const checkpoints = [createMockCheckpoint('test')];
|
|
167
|
+
const {lastFrame} = renderWithTheme(
|
|
168
|
+
<CheckpointListDisplay checkpoints={checkpoints} />,
|
|
169
|
+
);
|
|
170
|
+
|
|
171
|
+
const output = lastFrame() || '';
|
|
172
|
+
t.true(output.includes('Name'));
|
|
173
|
+
t.true(output.includes('Created'));
|
|
174
|
+
t.true(output.includes('Messages'));
|
|
175
|
+
t.true(output.includes('Files'));
|
|
176
|
+
t.true(output.includes('Size'));
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
test('CheckpointListDisplay renders relative time', t => {
|
|
180
|
+
const checkpoints = [
|
|
181
|
+
createMockCheckpoint('test', {
|
|
182
|
+
metadata: {
|
|
183
|
+
name: 'test',
|
|
184
|
+
timestamp: new Date().toISOString(), // Just now
|
|
185
|
+
messageCount: 10,
|
|
186
|
+
filesChanged: [],
|
|
187
|
+
provider: {name: 'Test', model: 'model'},
|
|
188
|
+
},
|
|
189
|
+
}),
|
|
190
|
+
];
|
|
191
|
+
const {lastFrame} = renderWithTheme(
|
|
192
|
+
<CheckpointListDisplay checkpoints={checkpoints} />,
|
|
193
|
+
);
|
|
194
|
+
|
|
195
|
+
const output = lastFrame() || '';
|
|
196
|
+
t.true(output.includes('Just now'));
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
test('CheckpointListDisplay handles empty size', t => {
|
|
200
|
+
const checkpoints = [createMockCheckpoint('test', {sizeBytes: undefined})];
|
|
201
|
+
const {lastFrame} = renderWithTheme(
|
|
202
|
+
<CheckpointListDisplay checkpoints={checkpoints} />,
|
|
203
|
+
);
|
|
204
|
+
|
|
205
|
+
// Should render without crashing
|
|
206
|
+
const output = lastFrame() || '';
|
|
207
|
+
t.true(output.includes('test'));
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
test('CheckpointListDisplay handles zero size', t => {
|
|
211
|
+
const checkpoints = [createMockCheckpoint('test', {sizeBytes: 0})];
|
|
212
|
+
const {lastFrame} = renderWithTheme(
|
|
213
|
+
<CheckpointListDisplay checkpoints={checkpoints} />,
|
|
214
|
+
);
|
|
215
|
+
|
|
216
|
+
// Should render without crashing (empty string for 0 bytes)
|
|
217
|
+
const output = lastFrame() || '';
|
|
218
|
+
t.true(output.includes('test'));
|
|
219
|
+
});
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import {useTheme} from '@/hooks/useTheme';
|
|
2
|
+
import type {CheckpointListItem} from '@/types/checkpoint';
|
|
3
|
+
import {formatRelativeTime} from '@/utils/checkpoint-utils';
|
|
4
|
+
import {Box, Text} from 'ink';
|
|
5
|
+
|
|
6
|
+
interface CheckpointListDisplayProps {
|
|
7
|
+
checkpoints: CheckpointListItem[];
|
|
8
|
+
title?: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function CheckpointListDisplay({
|
|
12
|
+
checkpoints,
|
|
13
|
+
title = 'Available Checkpoints',
|
|
14
|
+
}: CheckpointListDisplayProps) {
|
|
15
|
+
const {colors} = useTheme();
|
|
16
|
+
|
|
17
|
+
const formatSize = (bytes?: number): string => {
|
|
18
|
+
if (!bytes) return '';
|
|
19
|
+
|
|
20
|
+
const kb = bytes / 1024;
|
|
21
|
+
const mb = kb / 1024;
|
|
22
|
+
|
|
23
|
+
if (mb >= 1) {
|
|
24
|
+
return `${mb.toFixed(1)}MB`;
|
|
25
|
+
} else if (kb >= 1) {
|
|
26
|
+
return `${kb.toFixed(0)}KB`;
|
|
27
|
+
} else {
|
|
28
|
+
return `${bytes}B`;
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
if (checkpoints.length === 0) {
|
|
33
|
+
return (
|
|
34
|
+
<Box flexDirection="column" marginY={1}>
|
|
35
|
+
<Text color={colors.secondary}>
|
|
36
|
+
No checkpoints found. Create one with /checkpoint create [name]
|
|
37
|
+
</Text>
|
|
38
|
+
</Box>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<Box flexDirection="column" marginY={1}>
|
|
44
|
+
<Box
|
|
45
|
+
borderStyle="round"
|
|
46
|
+
borderColor={colors.primary}
|
|
47
|
+
paddingX={2}
|
|
48
|
+
paddingY={1}
|
|
49
|
+
>
|
|
50
|
+
<Box flexDirection="column">
|
|
51
|
+
<Text bold color={colors.primary}>
|
|
52
|
+
{title}
|
|
53
|
+
</Text>
|
|
54
|
+
<Box marginTop={1} flexDirection="column">
|
|
55
|
+
{/* Header */}
|
|
56
|
+
<Box flexDirection="row">
|
|
57
|
+
<Box width={20}>
|
|
58
|
+
<Text bold color={colors.info}>
|
|
59
|
+
Name
|
|
60
|
+
</Text>
|
|
61
|
+
</Box>
|
|
62
|
+
<Box width={15}>
|
|
63
|
+
<Text bold color={colors.info}>
|
|
64
|
+
Created
|
|
65
|
+
</Text>
|
|
66
|
+
</Box>
|
|
67
|
+
<Box width={10}>
|
|
68
|
+
<Text bold color={colors.info}>
|
|
69
|
+
Messages
|
|
70
|
+
</Text>
|
|
71
|
+
</Box>
|
|
72
|
+
<Box width={8}>
|
|
73
|
+
<Text bold color={colors.info}>
|
|
74
|
+
Files
|
|
75
|
+
</Text>
|
|
76
|
+
</Box>
|
|
77
|
+
<Box width={8}>
|
|
78
|
+
<Text bold color={colors.info}>
|
|
79
|
+
Size
|
|
80
|
+
</Text>
|
|
81
|
+
</Box>
|
|
82
|
+
</Box>
|
|
83
|
+
|
|
84
|
+
{/* Separator */}
|
|
85
|
+
<Box>
|
|
86
|
+
<Text color={colors.secondary}>{'─'.repeat(50)}</Text>
|
|
87
|
+
</Box>
|
|
88
|
+
|
|
89
|
+
{/* Rows */}
|
|
90
|
+
{checkpoints.map(checkpoint => (
|
|
91
|
+
<Box key={checkpoint.name} flexDirection="row">
|
|
92
|
+
<Box width={20}>
|
|
93
|
+
<Text color={colors.white}>
|
|
94
|
+
{checkpoint.name.length > 18
|
|
95
|
+
? checkpoint.name.substring(0, 15) + '...'
|
|
96
|
+
: checkpoint.name}
|
|
97
|
+
</Text>
|
|
98
|
+
</Box>
|
|
99
|
+
<Box width={15}>
|
|
100
|
+
<Text color={colors.secondary}>
|
|
101
|
+
{formatRelativeTime(checkpoint.metadata.timestamp)}
|
|
102
|
+
</Text>
|
|
103
|
+
</Box>
|
|
104
|
+
<Box width={10}>
|
|
105
|
+
<Text color={colors.white}>
|
|
106
|
+
{checkpoint.metadata.messageCount}
|
|
107
|
+
</Text>
|
|
108
|
+
</Box>
|
|
109
|
+
<Box width={8}>
|
|
110
|
+
<Text color={colors.white}>
|
|
111
|
+
{checkpoint.metadata.filesChanged.length}
|
|
112
|
+
</Text>
|
|
113
|
+
</Box>
|
|
114
|
+
<Box width={8}>
|
|
115
|
+
<Text color={colors.secondary}>
|
|
116
|
+
{formatSize(checkpoint.sizeBytes)}
|
|
117
|
+
</Text>
|
|
118
|
+
</Box>
|
|
119
|
+
</Box>
|
|
120
|
+
))}
|
|
121
|
+
</Box>
|
|
122
|
+
</Box>
|
|
123
|
+
</Box>
|
|
124
|
+
</Box>
|
|
125
|
+
);
|
|
126
|
+
}
|