@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.
Files changed (414) hide show
  1. package/.editorconfig +16 -0
  2. package/.env.example +63 -0
  3. package/.gitattributes +1 -0
  4. package/.semgrepignore +19 -0
  5. package/coder-dummy-file.ts +52 -0
  6. package/coder.config.example.json +59 -0
  7. package/coder.config.json +13 -0
  8. package/color_picker.html +36 -0
  9. package/package.json +2 -14
  10. package/scripts/extract-changelog.js +73 -0
  11. package/scripts/fetch-models.js +143 -0
  12. package/scripts/test.sh +40 -0
  13. package/scripts/update-homebrew-formula.sh +125 -0
  14. package/scripts/update-nix-version.sh +157 -0
  15. package/source/ai-sdk-client/AISDKClient.spec.ts +117 -0
  16. package/source/ai-sdk-client/AISDKClient.ts +155 -0
  17. package/source/ai-sdk-client/chat/chat-handler.spec.ts +121 -0
  18. package/source/ai-sdk-client/chat/chat-handler.ts +276 -0
  19. package/source/ai-sdk-client/chat/streaming-handler.spec.ts +173 -0
  20. package/source/ai-sdk-client/chat/streaming-handler.ts +110 -0
  21. package/source/ai-sdk-client/chat/tool-processor.spec.ts +92 -0
  22. package/source/ai-sdk-client/chat/tool-processor.ts +70 -0
  23. package/source/ai-sdk-client/converters/message-converter.spec.ts +220 -0
  24. package/source/ai-sdk-client/converters/message-converter.ts +113 -0
  25. package/source/ai-sdk-client/converters/tool-converter.spec.ts +90 -0
  26. package/source/ai-sdk-client/converters/tool-converter.ts +46 -0
  27. package/source/ai-sdk-client/error-handling/error-extractor.spec.ts +55 -0
  28. package/source/ai-sdk-client/error-handling/error-extractor.ts +15 -0
  29. package/source/ai-sdk-client/error-handling/error-parser.spec.ts +169 -0
  30. package/source/ai-sdk-client/error-handling/error-parser.ts +161 -0
  31. package/source/ai-sdk-client/index.ts +7 -0
  32. package/source/ai-sdk-client/providers/provider-factory.spec.ts +71 -0
  33. package/source/ai-sdk-client/providers/provider-factory.ts +41 -0
  34. package/source/ai-sdk-client/types.ts +9 -0
  35. package/source/ai-sdk-client-empty-message.spec.ts +141 -0
  36. package/source/ai-sdk-client-error-handling.spec.ts +186 -0
  37. package/source/ai-sdk-client-maxretries.spec.ts +114 -0
  38. package/source/ai-sdk-client-preparestep.spec.ts +279 -0
  39. package/source/app/App.spec.tsx +32 -0
  40. package/source/app/App.tsx +480 -0
  41. package/source/app/components/AppContainer.spec.tsx +96 -0
  42. package/source/app/components/AppContainer.tsx +56 -0
  43. package/source/app/components/ChatInterface.spec.tsx +163 -0
  44. package/source/app/components/ChatInterface.tsx +144 -0
  45. package/source/app/components/ModalSelectors.spec.tsx +141 -0
  46. package/source/app/components/ModalSelectors.tsx +135 -0
  47. package/source/app/helpers.spec.ts +97 -0
  48. package/source/app/helpers.ts +63 -0
  49. package/source/app/index.ts +4 -0
  50. package/source/app/types.ts +39 -0
  51. package/source/app/utils/appUtils.ts +294 -0
  52. package/source/app/utils/conversationState.ts +310 -0
  53. package/source/app.spec.tsx +244 -0
  54. package/source/cli.spec.ts +73 -0
  55. package/source/cli.tsx +51 -0
  56. package/source/client-factory.spec.ts +48 -0
  57. package/source/client-factory.ts +178 -0
  58. package/source/command-parser.spec.ts +127 -0
  59. package/source/command-parser.ts +36 -0
  60. package/source/commands/checkpoint.spec.tsx +277 -0
  61. package/source/commands/checkpoint.tsx +366 -0
  62. package/source/commands/clear.tsx +22 -0
  63. package/source/commands/custom-commands.tsx +121 -0
  64. package/source/commands/exit.ts +21 -0
  65. package/source/commands/export.spec.tsx +131 -0
  66. package/source/commands/export.tsx +79 -0
  67. package/source/commands/help.tsx +120 -0
  68. package/source/commands/index.ts +17 -0
  69. package/source/commands/init.tsx +339 -0
  70. package/source/commands/lsp-command.spec.tsx +281 -0
  71. package/source/commands/lsp.tsx +120 -0
  72. package/source/commands/mcp-command.spec.tsx +313 -0
  73. package/source/commands/mcp.tsx +162 -0
  74. package/source/commands/model-database.spec.tsx +758 -0
  75. package/source/commands/model-database.tsx +418 -0
  76. package/source/commands/model.ts +12 -0
  77. package/source/commands/provider.ts +12 -0
  78. package/source/commands/setup-config.tsx +16 -0
  79. package/source/commands/simple-commands.spec.tsx +175 -0
  80. package/source/commands/status.ts +12 -0
  81. package/source/commands/theme.ts +12 -0
  82. package/source/commands/update.spec.tsx +261 -0
  83. package/source/commands/update.tsx +201 -0
  84. package/source/commands/usage.spec.tsx +495 -0
  85. package/source/commands/usage.tsx +100 -0
  86. package/source/commands.spec.ts +436 -0
  87. package/source/commands.ts +83 -0
  88. package/source/components/assistant-message.spec.tsx +796 -0
  89. package/source/components/assistant-message.tsx +34 -0
  90. package/source/components/bash-execution-indicator.tsx +21 -0
  91. package/source/components/cancelling-indicator.tsx +16 -0
  92. package/source/components/chat-queue.spec.tsx +83 -0
  93. package/source/components/chat-queue.tsx +36 -0
  94. package/source/components/checkpoint-display.spec.tsx +219 -0
  95. package/source/components/checkpoint-display.tsx +126 -0
  96. package/source/components/checkpoint-selector.spec.tsx +173 -0
  97. package/source/components/checkpoint-selector.tsx +173 -0
  98. package/source/components/development-mode-indicator.spec.tsx +268 -0
  99. package/source/components/development-mode-indicator.tsx +38 -0
  100. package/source/components/message-box.spec.tsx +427 -0
  101. package/source/components/message-box.tsx +87 -0
  102. package/source/components/model-selector.tsx +132 -0
  103. package/source/components/provider-selector.tsx +75 -0
  104. package/source/components/random-spinner.tsx +19 -0
  105. package/source/components/security-disclaimer.tsx +73 -0
  106. package/source/components/status-connection-display.spec.tsx +133 -0
  107. package/source/components/status.tsx +267 -0
  108. package/source/components/theme-selector.tsx +126 -0
  109. package/source/components/tool-confirmation.tsx +190 -0
  110. package/source/components/tool-execution-indicator.tsx +33 -0
  111. package/source/components/tool-message.tsx +85 -0
  112. package/source/components/ui/titled-box.spec.tsx +207 -0
  113. package/source/components/ui/titled-box.tsx +57 -0
  114. package/source/components/usage/progress-bar.spec.tsx +398 -0
  115. package/source/components/usage/progress-bar.tsx +30 -0
  116. package/source/components/usage/usage-display.spec.tsx +780 -0
  117. package/source/components/usage/usage-display.tsx +291 -0
  118. package/source/components/user-input.spec.tsx +327 -0
  119. package/source/components/user-input.tsx +533 -0
  120. package/source/components/user-message.spec.tsx +230 -0
  121. package/source/components/user-message.tsx +84 -0
  122. package/source/components/welcome-message.tsx +76 -0
  123. package/source/config/env-substitution.ts +65 -0
  124. package/source/config/index.spec.ts +171 -0
  125. package/source/config/index.ts +154 -0
  126. package/source/config/paths.spec.ts +241 -0
  127. package/source/config/paths.ts +55 -0
  128. package/source/config/preferences.ts +51 -0
  129. package/source/config/themes.ts +315 -0
  130. package/source/constants.ts +130 -0
  131. package/source/context/mode-context.spec.ts +79 -0
  132. package/source/context/mode-context.ts +24 -0
  133. package/source/custom-commands/executor.spec.ts +142 -0
  134. package/source/custom-commands/executor.ts +64 -0
  135. package/source/custom-commands/loader.spec.ts +314 -0
  136. package/source/custom-commands/loader.ts +153 -0
  137. package/source/custom-commands/parser.ts +196 -0
  138. package/source/hooks/chat-handler/conversation/conversation-loop.spec.ts +39 -0
  139. package/source/hooks/chat-handler/conversation/conversation-loop.tsx +511 -0
  140. package/source/hooks/chat-handler/conversation/tool-executor.spec.ts +50 -0
  141. package/source/hooks/chat-handler/conversation/tool-executor.tsx +109 -0
  142. package/source/hooks/chat-handler/index.ts +12 -0
  143. package/source/hooks/chat-handler/state/streaming-state.spec.ts +26 -0
  144. package/source/hooks/chat-handler/state/streaming-state.ts +19 -0
  145. package/source/hooks/chat-handler/types.ts +38 -0
  146. package/source/hooks/chat-handler/useChatHandler.spec.tsx +321 -0
  147. package/source/hooks/chat-handler/useChatHandler.tsx +194 -0
  148. package/source/hooks/chat-handler/utils/context-checker.spec.ts +60 -0
  149. package/source/hooks/chat-handler/utils/context-checker.tsx +73 -0
  150. package/source/hooks/chat-handler/utils/message-helpers.spec.ts +42 -0
  151. package/source/hooks/chat-handler/utils/message-helpers.tsx +36 -0
  152. package/source/hooks/chat-handler/utils/tool-filters.spec.ts +109 -0
  153. package/source/hooks/chat-handler/utils/tool-filters.ts +64 -0
  154. package/source/hooks/useAppHandlers.tsx +291 -0
  155. package/source/hooks/useAppInitialization.tsx +422 -0
  156. package/source/hooks/useAppState.tsx +311 -0
  157. package/source/hooks/useDirectoryTrust.tsx +98 -0
  158. package/source/hooks/useInputState.ts +414 -0
  159. package/source/hooks/useModeHandlers.tsx +302 -0
  160. package/source/hooks/useNonInteractiveMode.ts +140 -0
  161. package/source/hooks/useTerminalWidth.tsx +81 -0
  162. package/source/hooks/useTheme.ts +18 -0
  163. package/source/hooks/useToolHandler.tsx +349 -0
  164. package/source/hooks/useUIState.ts +61 -0
  165. package/source/init/agents-template-generator.ts +421 -0
  166. package/source/init/existing-rules-extractor.ts +319 -0
  167. package/source/init/file-scanner.spec.ts +227 -0
  168. package/source/init/file-scanner.ts +238 -0
  169. package/source/init/framework-detector.ts +382 -0
  170. package/source/init/language-detector.ts +269 -0
  171. package/source/init/project-analyzer.spec.ts +231 -0
  172. package/source/init/project-analyzer.ts +458 -0
  173. package/source/lsp/index.ts +31 -0
  174. package/source/lsp/lsp-client.spec.ts +508 -0
  175. package/source/lsp/lsp-client.ts +487 -0
  176. package/source/lsp/lsp-manager.spec.ts +477 -0
  177. package/source/lsp/lsp-manager.ts +419 -0
  178. package/source/lsp/protocol.spec.ts +502 -0
  179. package/source/lsp/protocol.ts +360 -0
  180. package/source/lsp/server-discovery.spec.ts +654 -0
  181. package/source/lsp/server-discovery.ts +515 -0
  182. package/source/markdown-parser/html-entities.spec.ts +88 -0
  183. package/source/markdown-parser/html-entities.ts +45 -0
  184. package/source/markdown-parser/index.spec.ts +281 -0
  185. package/source/markdown-parser/index.ts +126 -0
  186. package/source/markdown-parser/table-parser.spec.ts +133 -0
  187. package/source/markdown-parser/table-parser.ts +114 -0
  188. package/source/markdown-parser/utils.spec.ts +70 -0
  189. package/source/markdown-parser/utils.ts +13 -0
  190. package/source/mcp/mcp-client.spec.ts +81 -0
  191. package/source/mcp/mcp-client.ts +625 -0
  192. package/source/mcp/transport-factory.spec.ts +406 -0
  193. package/source/mcp/transport-factory.ts +312 -0
  194. package/source/message-handler.ts +67 -0
  195. package/source/model-database/database-engine.spec.ts +494 -0
  196. package/source/model-database/database-engine.ts +50 -0
  197. package/source/model-database/model-database.spec.ts +363 -0
  198. package/source/model-database/model-database.ts +91 -0
  199. package/source/model-database/model-engine.spec.ts +447 -0
  200. package/source/model-database/model-engine.ts +65 -0
  201. package/source/model-database/model-fetcher.spec.ts +583 -0
  202. package/source/model-database/model-fetcher.ts +330 -0
  203. package/source/models/index.ts +1 -0
  204. package/source/models/models-cache.spec.ts +214 -0
  205. package/source/models/models-cache.ts +78 -0
  206. package/source/models/models-dev-client.spec.ts +379 -0
  207. package/source/models/models-dev-client.ts +329 -0
  208. package/source/models/models-types.ts +68 -0
  209. package/source/prompt-history.ts +155 -0
  210. package/source/security/command-injection.spec.ts +240 -0
  211. package/source/services/checkpoint-manager.spec.ts +523 -0
  212. package/source/services/checkpoint-manager.ts +466 -0
  213. package/source/services/file-snapshot.spec.ts +569 -0
  214. package/source/services/file-snapshot.ts +220 -0
  215. package/source/test-utils/render-with-theme.tsx +48 -0
  216. package/source/tokenization/index.ts +1 -0
  217. package/source/tokenization/tokenizer-factory.spec.ts +170 -0
  218. package/source/tokenization/tokenizer-factory.ts +125 -0
  219. package/source/tokenization/tokenizers/anthropic-tokenizer.spec.ts +200 -0
  220. package/source/tokenization/tokenizers/anthropic-tokenizer.ts +43 -0
  221. package/source/tokenization/tokenizers/fallback-tokenizer.spec.ts +236 -0
  222. package/source/tokenization/tokenizers/fallback-tokenizer.ts +26 -0
  223. package/source/tokenization/tokenizers/llama-tokenizer.spec.ts +224 -0
  224. package/source/tokenization/tokenizers/llama-tokenizer.ts +41 -0
  225. package/source/tokenization/tokenizers/openai-tokenizer.spec.ts +184 -0
  226. package/source/tokenization/tokenizers/openai-tokenizer.ts +57 -0
  227. package/source/tool-calling/index.ts +5 -0
  228. package/source/tool-calling/json-parser.spec.ts +639 -0
  229. package/source/tool-calling/json-parser.ts +247 -0
  230. package/source/tool-calling/tool-parser.spec.ts +395 -0
  231. package/source/tool-calling/tool-parser.ts +120 -0
  232. package/source/tool-calling/xml-parser.spec.ts +662 -0
  233. package/source/tool-calling/xml-parser.ts +289 -0
  234. package/source/tools/execute-bash.spec.tsx +353 -0
  235. package/source/tools/execute-bash.tsx +219 -0
  236. package/source/tools/execute-function.spec.ts +130 -0
  237. package/source/tools/fetch-url.spec.tsx +342 -0
  238. package/source/tools/fetch-url.tsx +172 -0
  239. package/source/tools/find-files.spec.tsx +924 -0
  240. package/source/tools/find-files.tsx +293 -0
  241. package/source/tools/index.ts +102 -0
  242. package/source/tools/lsp-get-diagnostics.tsx +192 -0
  243. package/source/tools/needs-approval.spec.ts +282 -0
  244. package/source/tools/read-file.spec.tsx +801 -0
  245. package/source/tools/read-file.tsx +387 -0
  246. package/source/tools/search-file-contents.spec.tsx +1273 -0
  247. package/source/tools/search-file-contents.tsx +293 -0
  248. package/source/tools/string-replace.spec.tsx +730 -0
  249. package/source/tools/string-replace.tsx +548 -0
  250. package/source/tools/tool-manager.ts +210 -0
  251. package/source/tools/tool-registry.spec.ts +415 -0
  252. package/source/tools/tool-registry.ts +228 -0
  253. package/source/tools/web-search.tsx +223 -0
  254. package/source/tools/write-file.spec.tsx +559 -0
  255. package/source/tools/write-file.tsx +228 -0
  256. package/source/types/app.ts +37 -0
  257. package/source/types/checkpoint.ts +48 -0
  258. package/source/types/commands.ts +46 -0
  259. package/source/types/components.ts +27 -0
  260. package/source/types/config.ts +103 -0
  261. package/source/types/core-connection-status.spec.ts +67 -0
  262. package/source/types/core.ts +181 -0
  263. package/source/types/hooks.ts +50 -0
  264. package/source/types/index.ts +12 -0
  265. package/source/types/markdown-parser.ts +11 -0
  266. package/source/types/mcp.ts +52 -0
  267. package/source/types/system.ts +16 -0
  268. package/source/types/tokenization.ts +41 -0
  269. package/source/types/ui.ts +40 -0
  270. package/source/types/usage.ts +58 -0
  271. package/source/types/utils.ts +16 -0
  272. package/source/usage/calculator.spec.ts +385 -0
  273. package/source/usage/calculator.ts +104 -0
  274. package/source/usage/storage.spec.ts +703 -0
  275. package/source/usage/storage.ts +238 -0
  276. package/source/usage/tracker.spec.ts +456 -0
  277. package/source/usage/tracker.ts +102 -0
  278. package/source/utils/atomic-deletion.spec.ts +194 -0
  279. package/source/utils/atomic-deletion.ts +127 -0
  280. package/source/utils/bounded-map.spec.ts +300 -0
  281. package/source/utils/bounded-map.ts +193 -0
  282. package/source/utils/checkpoint-utils.spec.ts +222 -0
  283. package/source/utils/checkpoint-utils.ts +92 -0
  284. package/source/utils/error-formatter.spec.ts +169 -0
  285. package/source/utils/error-formatter.ts +194 -0
  286. package/source/utils/file-autocomplete.spec.ts +173 -0
  287. package/source/utils/file-autocomplete.ts +196 -0
  288. package/source/utils/file-cache.spec.ts +309 -0
  289. package/source/utils/file-cache.ts +195 -0
  290. package/source/utils/file-content-loader.spec.ts +180 -0
  291. package/source/utils/file-content-loader.ts +179 -0
  292. package/source/utils/file-mention-handler.spec.ts +261 -0
  293. package/source/utils/file-mention-handler.ts +84 -0
  294. package/source/utils/file-mention-parser.spec.ts +182 -0
  295. package/source/utils/file-mention-parser.ts +170 -0
  296. package/source/utils/fuzzy-matching.spec.ts +149 -0
  297. package/source/utils/fuzzy-matching.ts +146 -0
  298. package/source/utils/indentation-normalizer.spec.ts +216 -0
  299. package/source/utils/indentation-normalizer.ts +76 -0
  300. package/source/utils/installation-detector.spec.ts +178 -0
  301. package/source/utils/installation-detector.ts +153 -0
  302. package/source/utils/logging/config.spec.ts +311 -0
  303. package/source/utils/logging/config.ts +210 -0
  304. package/source/utils/logging/console-facade.spec.ts +184 -0
  305. package/source/utils/logging/console-facade.ts +384 -0
  306. package/source/utils/logging/correlation.spec.ts +679 -0
  307. package/source/utils/logging/correlation.ts +474 -0
  308. package/source/utils/logging/formatters.spec.ts +464 -0
  309. package/source/utils/logging/formatters.ts +207 -0
  310. package/source/utils/logging/health-monitor/alerts/alert-manager.spec.ts +93 -0
  311. package/source/utils/logging/health-monitor/alerts/alert-manager.ts +79 -0
  312. package/source/utils/logging/health-monitor/checks/configuration-check.spec.ts +56 -0
  313. package/source/utils/logging/health-monitor/checks/configuration-check.ts +43 -0
  314. package/source/utils/logging/health-monitor/checks/logging-check.spec.ts +56 -0
  315. package/source/utils/logging/health-monitor/checks/logging-check.ts +58 -0
  316. package/source/utils/logging/health-monitor/checks/memory-check.spec.ts +100 -0
  317. package/source/utils/logging/health-monitor/checks/memory-check.ts +78 -0
  318. package/source/utils/logging/health-monitor/checks/performance-check.spec.ts +56 -0
  319. package/source/utils/logging/health-monitor/checks/performance-check.ts +56 -0
  320. package/source/utils/logging/health-monitor/checks/request-check.spec.ts +56 -0
  321. package/source/utils/logging/health-monitor/checks/request-check.ts +76 -0
  322. package/source/utils/logging/health-monitor/core/health-check-runner.spec.ts +70 -0
  323. package/source/utils/logging/health-monitor/core/health-check-runner.ts +138 -0
  324. package/source/utils/logging/health-monitor/core/health-monitor.spec.ts +58 -0
  325. package/source/utils/logging/health-monitor/core/health-monitor.ts +344 -0
  326. package/source/utils/logging/health-monitor/core/scoring.spec.ts +65 -0
  327. package/source/utils/logging/health-monitor/core/scoring.ts +91 -0
  328. package/source/utils/logging/health-monitor/index.ts +15 -0
  329. package/source/utils/logging/health-monitor/instances.ts +48 -0
  330. package/source/utils/logging/health-monitor/middleware/http-middleware.spec.ts +141 -0
  331. package/source/utils/logging/health-monitor/middleware/http-middleware.ts +75 -0
  332. package/source/utils/logging/health-monitor/types.ts +126 -0
  333. package/source/utils/logging/index.spec.ts +284 -0
  334. package/source/utils/logging/index.ts +236 -0
  335. package/source/utils/logging/integration.spec.ts +441 -0
  336. package/source/utils/logging/log-method-factory.spec.ts +573 -0
  337. package/source/utils/logging/log-method-factory.ts +233 -0
  338. package/source/utils/logging/log-query/aggregation/aggregator.spec.ts +277 -0
  339. package/source/utils/logging/log-query/aggregation/aggregator.ts +159 -0
  340. package/source/utils/logging/log-query/aggregation/facet-generator.spec.ts +159 -0
  341. package/source/utils/logging/log-query/aggregation/facet-generator.ts +47 -0
  342. package/source/utils/logging/log-query/index.ts +23 -0
  343. package/source/utils/logging/log-query/query/filter-predicates.spec.ts +247 -0
  344. package/source/utils/logging/log-query/query/filter-predicates.ts +154 -0
  345. package/source/utils/logging/log-query/query/query-builder.spec.ts +182 -0
  346. package/source/utils/logging/log-query/query/query-builder.ts +151 -0
  347. package/source/utils/logging/log-query/query/query-engine.spec.ts +214 -0
  348. package/source/utils/logging/log-query/query/query-engine.ts +45 -0
  349. package/source/utils/logging/log-query/storage/circular-buffer.spec.ts +143 -0
  350. package/source/utils/logging/log-query/storage/circular-buffer.ts +75 -0
  351. package/source/utils/logging/log-query/storage/index-manager.spec.ts +150 -0
  352. package/source/utils/logging/log-query/storage/index-manager.ts +71 -0
  353. package/source/utils/logging/log-query/storage/log-storage.spec.ts +257 -0
  354. package/source/utils/logging/log-query/storage/log-storage.ts +80 -0
  355. package/source/utils/logging/log-query/types.ts +163 -0
  356. package/source/utils/logging/log-query/utils/helpers.spec.ts +263 -0
  357. package/source/utils/logging/log-query/utils/helpers.ts +72 -0
  358. package/source/utils/logging/log-query/utils/sorting.spec.ts +182 -0
  359. package/source/utils/logging/log-query/utils/sorting.ts +61 -0
  360. package/source/utils/logging/logger-provider.spec.ts +262 -0
  361. package/source/utils/logging/logger-provider.ts +362 -0
  362. package/source/utils/logging/performance.spec.ts +209 -0
  363. package/source/utils/logging/performance.ts +757 -0
  364. package/source/utils/logging/pino-logger.spec.ts +425 -0
  365. package/source/utils/logging/pino-logger.ts +514 -0
  366. package/source/utils/logging/redaction.spec.ts +490 -0
  367. package/source/utils/logging/redaction.ts +267 -0
  368. package/source/utils/logging/request-tracker.spec.ts +1198 -0
  369. package/source/utils/logging/request-tracker.ts +803 -0
  370. package/source/utils/logging/transports.spec.ts +505 -0
  371. package/source/utils/logging/transports.ts +305 -0
  372. package/source/utils/logging/types.ts +216 -0
  373. package/source/utils/message-builder.spec.ts +179 -0
  374. package/source/utils/message-builder.ts +101 -0
  375. package/source/utils/message-queue.tsx +486 -0
  376. package/source/utils/paste-detection.spec.ts +69 -0
  377. package/source/utils/paste-detection.ts +124 -0
  378. package/source/utils/paste-roundtrip.spec.ts +442 -0
  379. package/source/utils/paste-utils.spec.ts +128 -0
  380. package/source/utils/paste-utils.ts +52 -0
  381. package/source/utils/programming-language-helper.spec.ts +74 -0
  382. package/source/utils/programming-language-helper.ts +32 -0
  383. package/source/utils/prompt-assembly.spec.ts +221 -0
  384. package/source/utils/prompt-processor.ts +173 -0
  385. package/source/utils/tool-args-parser.spec.ts +136 -0
  386. package/source/utils/tool-args-parser.ts +54 -0
  387. package/source/utils/tool-cancellation.spec.ts +230 -0
  388. package/source/utils/tool-cancellation.ts +28 -0
  389. package/source/utils/tool-result-display.spec.tsx +469 -0
  390. package/source/utils/tool-result-display.tsx +90 -0
  391. package/source/utils/update-checker.spec.ts +383 -0
  392. package/source/utils/update-checker.ts +183 -0
  393. package/source/wizard/config-wizard.spec.tsx +103 -0
  394. package/source/wizard/config-wizard.tsx +382 -0
  395. package/source/wizard/steps/location-step.spec.tsx +186 -0
  396. package/source/wizard/steps/location-step.tsx +147 -0
  397. package/source/wizard/steps/mcp-step.spec.tsx +607 -0
  398. package/source/wizard/steps/mcp-step.tsx +632 -0
  399. package/source/wizard/steps/provider-step.spec.tsx +342 -0
  400. package/source/wizard/steps/provider-step.tsx +957 -0
  401. package/source/wizard/steps/summary-step.spec.tsx +749 -0
  402. package/source/wizard/steps/summary-step.tsx +228 -0
  403. package/source/wizard/templates/mcp-templates.spec.ts +613 -0
  404. package/source/wizard/templates/mcp-templates.ts +570 -0
  405. package/source/wizard/templates/provider-templates.spec.ts +152 -0
  406. package/source/wizard/templates/provider-templates.ts +485 -0
  407. package/source/wizard/utils/fetch-cloud-models.spec.ts +428 -0
  408. package/source/wizard/utils/fetch-cloud-models.ts +223 -0
  409. package/source/wizard/utils/fetch-local-models.spec.ts +297 -0
  410. package/source/wizard/utils/fetch-local-models.ts +192 -0
  411. package/source/wizard/validation-array.spec.ts +264 -0
  412. package/source/wizard/validation.spec.ts +373 -0
  413. package/source/wizard/validation.ts +232 -0
  414. 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
+ }