@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,220 @@
1
+ import {execSync} from 'child_process';
2
+ import {existsSync} from 'fs';
3
+ import * as path from 'path';
4
+ import {MAX_CHECKPOINT_FILES} from '@/constants';
5
+ import {logWarning} from '@/utils/message-queue';
6
+ import * as fs from 'fs/promises';
7
+
8
+ /**
9
+ * Service for capturing and restoring file snapshots for checkpoints
10
+ */
11
+ export class FileSnapshotService {
12
+ private readonly workspaceRoot: string;
13
+
14
+ constructor(workspaceRoot: string = process.cwd()) {
15
+ this.workspaceRoot = workspaceRoot;
16
+ }
17
+
18
+ /**
19
+ * Capture the contents of specified files
20
+ */
21
+ async captureFiles(filePaths: string[]): Promise<Map<string, string>> {
22
+ const snapshots = new Map<string, string>();
23
+
24
+ for (const filePath of filePaths) {
25
+ try {
26
+ const absolutePath = path.resolve(this.workspaceRoot, filePath); // nosemgrep
27
+ const content = await fs.readFile(absolutePath, 'utf-8');
28
+ const relativePath = path.relative(this.workspaceRoot, absolutePath);
29
+ snapshots.set(relativePath, content);
30
+ } catch (error) {
31
+ logWarning('Could not capture file', true, {
32
+ context: {
33
+ filePath,
34
+ error: error instanceof Error ? error.message : 'Unknown error',
35
+ },
36
+ });
37
+ }
38
+ }
39
+
40
+ return snapshots;
41
+ }
42
+
43
+ /**
44
+ * Restore files from snapshots
45
+ */
46
+ async restoreFiles(snapshots: Map<string, string>): Promise<void> {
47
+ const errors: string[] = [];
48
+
49
+ for (const [relativePath, content] of snapshots) {
50
+ try {
51
+ const absolutePath = path.resolve(this.workspaceRoot, relativePath);
52
+ const directory = path.dirname(absolutePath);
53
+
54
+ await fs.mkdir(directory, {recursive: true});
55
+ await fs.writeFile(absolutePath, content, 'utf-8');
56
+ } catch (error) {
57
+ errors.push(
58
+ `Failed to restore ${relativePath}: ${
59
+ error instanceof Error ? error.message : 'Unknown error'
60
+ }`,
61
+ );
62
+ }
63
+ }
64
+
65
+ if (errors.length > 0) {
66
+ throw new Error(`Failed to restore some files:\n${errors.join('\n')}`);
67
+ }
68
+ }
69
+
70
+ /**
71
+ * Get list of modified files in the workspace
72
+ * Uses git to detect modified files if available, otherwise returns empty array
73
+ */
74
+ getModifiedFiles(): string[] {
75
+ try {
76
+ const modifiedOutput = execSync('git diff --name-only HEAD', {
77
+ cwd: this.workspaceRoot,
78
+ encoding: 'utf-8',
79
+ stdio: ['pipe', 'pipe', 'pipe'],
80
+ }).trim();
81
+
82
+ const untrackedOutput = execSync(
83
+ 'git ls-files --others --exclude-standard',
84
+ {
85
+ cwd: this.workspaceRoot,
86
+ encoding: 'utf-8',
87
+ stdio: ['pipe', 'pipe', 'pipe'],
88
+ },
89
+ ).trim();
90
+
91
+ const modifiedFiles = modifiedOutput
92
+ ? modifiedOutput.split('\n').filter(Boolean)
93
+ : [];
94
+ const untrackedFiles = untrackedOutput
95
+ ? untrackedOutput.split('\n').filter(Boolean)
96
+ : [];
97
+
98
+ const allFiles = [...new Set([...modifiedFiles, ...untrackedFiles])];
99
+
100
+ const filtered = allFiles.filter(file => {
101
+ const ignorePatterns = [
102
+ 'node_modules/',
103
+ 'dist/',
104
+ 'build/',
105
+ '.git/',
106
+ '.coder/',
107
+ 'coverage/',
108
+ '*.log',
109
+ ];
110
+
111
+ return !ignorePatterns.some(pattern => {
112
+ if (pattern.endsWith('/')) {
113
+ return file.startsWith(pattern);
114
+ }
115
+ if (pattern.startsWith('*.')) {
116
+ return file.endsWith(pattern.slice(1));
117
+ }
118
+ return file.includes(pattern);
119
+ });
120
+ });
121
+
122
+ if (filtered.length > MAX_CHECKPOINT_FILES) {
123
+ logWarning(
124
+ 'Too many modified files detected, limiting to maximum',
125
+ true,
126
+ {
127
+ context: {
128
+ fileCount: filtered.length,
129
+ maxFiles: MAX_CHECKPOINT_FILES,
130
+ },
131
+ },
132
+ );
133
+ return filtered.slice(0, MAX_CHECKPOINT_FILES);
134
+ }
135
+
136
+ return filtered;
137
+ } catch {
138
+ logWarning('Git not available for file tracking', true, {
139
+ context: {
140
+ workspaceRoot: this.workspaceRoot,
141
+ },
142
+ });
143
+ return [];
144
+ }
145
+ }
146
+
147
+ /**
148
+ * Get the size of a file snapshot
149
+ */
150
+ getSnapshotSize(snapshots: Map<string, string>): number {
151
+ let totalSize = 0;
152
+ for (const content of snapshots.values()) {
153
+ totalSize += Buffer.byteLength(content, 'utf-8');
154
+ }
155
+ return totalSize;
156
+ }
157
+
158
+ /**
159
+ * Validate that all files in the snapshot can be written to their locations
160
+ */
161
+ async validateRestorePath(
162
+ snapshots: Map<string, string>,
163
+ ): Promise<{valid: boolean; errors: string[]}> {
164
+ const errors: string[] = [];
165
+
166
+ for (const relativePath of snapshots.keys()) {
167
+ const absolutePath = path.resolve(this.workspaceRoot, relativePath); // nosemgrep
168
+ const directory = path.dirname(absolutePath);
169
+
170
+ try {
171
+ let dirWritable = true;
172
+ try {
173
+ await fs.access(directory, fs.constants.W_OK);
174
+ } catch (_err) {
175
+ // Directory is not writable or does not exist, so try to create it
176
+ try {
177
+ await fs.mkdir(directory, {recursive: true});
178
+ } catch (mkdirError) {
179
+ dirWritable = false;
180
+ errors.push(
181
+ `Cannot create directory "${directory}": ${mkdirError instanceof Error ? mkdirError.message : 'Unknown error'}`,
182
+ );
183
+ }
184
+ }
185
+
186
+ // After attempting to create the directory, verify it's writable
187
+ if (dirWritable) {
188
+ try {
189
+ await fs.access(directory, fs.constants.W_OK);
190
+ } catch (accessError) {
191
+ dirWritable = false;
192
+ errors.push(
193
+ `Directory "${directory}" is not writable: ${accessError instanceof Error ? accessError.message : 'Unknown error'}`,
194
+ );
195
+ }
196
+ }
197
+
198
+ // If directory is not writable or was not successfully created, skip further checks for this file
199
+ if (!dirWritable) {
200
+ continue;
201
+ }
202
+
203
+ if (existsSync(absolutePath)) {
204
+ try {
205
+ await fs.access(absolutePath, fs.constants.W_OK);
206
+ } catch (fileError) {
207
+ errors.push(
208
+ `Cannot write to file "${absolutePath}": ${fileError instanceof Error ? fileError.message : 'Unknown error'}`,
209
+ );
210
+ }
211
+ }
212
+ } catch (error) {
213
+ errors.push(
214
+ `Cannot validate path for ${relativePath}: ${error instanceof Error ? error.message : 'Unknown error'}`,
215
+ );
216
+ }
217
+ }
218
+ return {valid: errors.length === 0, errors};
219
+ }
220
+ }
@@ -0,0 +1,48 @@
1
+ import {ThemeContext} from '@/hooks/useTheme';
2
+ import type {Colors, ThemePreset} from '@/types/ui';
3
+ import {render} from 'ink-testing-library';
4
+ import React from 'react';
5
+
6
+ // Default test colors that match the structure used in the app
7
+ const testColors: Colors = {
8
+ primary: 'blue',
9
+ secondary: 'gray',
10
+ white: 'white',
11
+ black: 'black',
12
+ info: 'cyan',
13
+ warning: 'yellow',
14
+ error: 'red',
15
+ success: 'green',
16
+ tool: 'magenta',
17
+ diffAdded: 'green',
18
+ diffRemoved: 'red',
19
+ diffAddedText: 'white',
20
+ diffRemovedText: 'white',
21
+ };
22
+
23
+ // Test theme context value
24
+ const testThemeContext = {
25
+ currentTheme: 'tokyo-night' as ThemePreset,
26
+ colors: testColors,
27
+ setCurrentTheme: () => {},
28
+ };
29
+
30
+ /**
31
+ * Wrapper component that provides ThemeContext for tests
32
+ */
33
+ function TestThemeProvider({children}: {children: React.ReactNode}) {
34
+ return (
35
+ <ThemeContext.Provider value={testThemeContext}>
36
+ {children}
37
+ </ThemeContext.Provider>
38
+ );
39
+ }
40
+
41
+ /**
42
+ * Render a component wrapped with ThemeContext for testing
43
+ */
44
+ export function renderWithTheme(
45
+ element: React.ReactElement,
46
+ ): ReturnType<typeof render> {
47
+ return render(<TestThemeProvider>{element}</TestThemeProvider>);
48
+ }
@@ -0,0 +1 @@
1
+ export {createTokenizer} from './tokenizer-factory.js';
@@ -0,0 +1,170 @@
1
+ /**
2
+ * Tests for tokenizer-factory.ts
3
+ */
4
+
5
+ import test from 'ava';
6
+ import {
7
+ createTokenizer,
8
+ createTokenizerForProvider,
9
+ } from './tokenizer-factory.js';
10
+ import {AnthropicTokenizer} from './tokenizers/anthropic-tokenizer.js';
11
+ import {FallbackTokenizer} from './tokenizers/fallback-tokenizer.js';
12
+ import {LlamaTokenizer} from './tokenizers/llama-tokenizer.js';
13
+ import {OpenAITokenizer} from './tokenizers/openai-tokenizer.js';
14
+
15
+ console.log(`\ntokenizer-factory.spec.ts`);
16
+
17
+ // Test createTokenizer with OpenAI provider detection
18
+ test('createTokenizer detects OpenAI from provider name', t => {
19
+ const tokenizer = createTokenizer('openai', 'custom-model');
20
+ t.true(tokenizer instanceof OpenAITokenizer);
21
+ t.is(tokenizer.getName(), 'openai-custom-model');
22
+ });
23
+
24
+ test('createTokenizer detects OpenAI from GPT model name', t => {
25
+ const tokenizer = createTokenizer('custom', 'gpt-4-turbo');
26
+ t.true(tokenizer instanceof OpenAITokenizer);
27
+ });
28
+
29
+ test('createTokenizer detects OpenAI from model name with openai keyword', t => {
30
+ const tokenizer = createTokenizer('custom', 'openai-model');
31
+ t.true(tokenizer instanceof OpenAITokenizer);
32
+ });
33
+
34
+ // Test createTokenizer with Anthropic provider detection
35
+ test('createTokenizer detects Anthropic from provider name', t => {
36
+ const tokenizer = createTokenizer('anthropic', 'custom-model');
37
+ t.true(tokenizer instanceof AnthropicTokenizer);
38
+ });
39
+
40
+ test('createTokenizer detects Anthropic from provider name with claude keyword', t => {
41
+ const tokenizer = createTokenizer('claude-provider', 'model');
42
+ t.true(tokenizer instanceof AnthropicTokenizer);
43
+ });
44
+
45
+ test('createTokenizer detects Anthropic from claude model name', t => {
46
+ const tokenizer = createTokenizer('custom', 'claude-3-opus');
47
+ t.true(tokenizer instanceof AnthropicTokenizer);
48
+ });
49
+
50
+ // Test createTokenizer with Llama provider detection
51
+ test('createTokenizer detects Llama from llama model name', t => {
52
+ const tokenizer = createTokenizer('custom', 'llama-3-8b');
53
+ t.true(tokenizer instanceof LlamaTokenizer);
54
+ });
55
+
56
+ test('createTokenizer detects Llama from mistral model name', t => {
57
+ const tokenizer = createTokenizer('custom', 'mistral-7b');
58
+ t.true(tokenizer instanceof LlamaTokenizer);
59
+ });
60
+
61
+ test('createTokenizer detects Llama from qwen model name', t => {
62
+ const tokenizer = createTokenizer('custom', 'qwen-2.5');
63
+ t.true(tokenizer instanceof LlamaTokenizer);
64
+ });
65
+
66
+ test('createTokenizer detects Llama from gemma model name', t => {
67
+ const tokenizer = createTokenizer('custom', 'gemma-2b');
68
+ t.true(tokenizer instanceof LlamaTokenizer);
69
+ });
70
+
71
+ test('createTokenizer detects Llama from phi model name', t => {
72
+ const tokenizer = createTokenizer('custom', 'phi-3');
73
+ t.true(tokenizer instanceof LlamaTokenizer);
74
+ });
75
+
76
+ test('createTokenizer detects Llama from codellama model name', t => {
77
+ const tokenizer = createTokenizer('custom', 'codellama-7b');
78
+ t.true(tokenizer instanceof LlamaTokenizer);
79
+ });
80
+
81
+ test('createTokenizer detects Llama from deepseek model name', t => {
82
+ const tokenizer = createTokenizer('custom', 'deepseek-coder');
83
+ t.true(tokenizer instanceof LlamaTokenizer);
84
+ });
85
+
86
+ test('createTokenizer detects Llama from mixtral model name', t => {
87
+ const tokenizer = createTokenizer('custom', 'mixtral-8x7b');
88
+ t.true(tokenizer instanceof LlamaTokenizer);
89
+ });
90
+
91
+ test('createTokenizer detects Llama from ollama provider', t => {
92
+ const tokenizer = createTokenizer('ollama', 'custom-model');
93
+ t.true(tokenizer instanceof LlamaTokenizer);
94
+ });
95
+
96
+ test('createTokenizer detects Llama from llama.cpp provider', t => {
97
+ const tokenizer = createTokenizer('llama.cpp', 'custom-model');
98
+ t.true(tokenizer instanceof LlamaTokenizer);
99
+ });
100
+
101
+ test('createTokenizer detects Llama from local provider', t => {
102
+ const tokenizer = createTokenizer('local', 'custom-model');
103
+ t.true(tokenizer instanceof LlamaTokenizer);
104
+ });
105
+
106
+ // Test createTokenizer with fallback
107
+ test('createTokenizer returns FallbackTokenizer for unknown provider', t => {
108
+ const tokenizer = createTokenizer('unknown', 'unknown-model');
109
+ t.true(tokenizer instanceof FallbackTokenizer);
110
+ });
111
+
112
+ // Test cloud suffix stripping
113
+ test('createTokenizer strips :cloud suffix from model name', t => {
114
+ const tokenizer = createTokenizer('ollama', 'llama-3:cloud');
115
+ t.true(tokenizer instanceof LlamaTokenizer);
116
+ t.is(tokenizer.getName(), 'llama-llama-3');
117
+ });
118
+
119
+ test('createTokenizer strips -cloud suffix from model name', t => {
120
+ const tokenizer = createTokenizer('ollama', 'llama-3-cloud');
121
+ t.true(tokenizer instanceof LlamaTokenizer);
122
+ t.is(tokenizer.getName(), 'llama-llama-3');
123
+ });
124
+
125
+ // Test case insensitivity
126
+ test('createTokenizer is case insensitive for provider detection', t => {
127
+ const tokenizer = createTokenizer('OPENAI', 'model');
128
+ t.true(tokenizer instanceof OpenAITokenizer);
129
+ });
130
+
131
+ test('createTokenizer is case insensitive for model detection', t => {
132
+ const tokenizer = createTokenizer('custom', 'GPT-4-TURBO');
133
+ t.true(tokenizer instanceof OpenAITokenizer);
134
+ });
135
+
136
+ // Test createTokenizerForProvider
137
+ test('createTokenizerForProvider creates OpenAI tokenizer', t => {
138
+ const tokenizer = createTokenizerForProvider('openai', 'gpt-4');
139
+ t.true(tokenizer instanceof OpenAITokenizer);
140
+ });
141
+
142
+ test('createTokenizerForProvider creates Anthropic tokenizer', t => {
143
+ const tokenizer = createTokenizerForProvider('anthropic', 'claude-3');
144
+ t.true(tokenizer instanceof AnthropicTokenizer);
145
+ });
146
+
147
+ test('createTokenizerForProvider creates Llama tokenizer', t => {
148
+ const tokenizer = createTokenizerForProvider('llama', 'llama-3');
149
+ t.true(tokenizer instanceof LlamaTokenizer);
150
+ });
151
+
152
+ test('createTokenizerForProvider creates FallbackTokenizer', t => {
153
+ const tokenizer = createTokenizerForProvider('fallback');
154
+ t.true(tokenizer instanceof FallbackTokenizer);
155
+ });
156
+
157
+ test('createTokenizerForProvider handles auto mode with model ID', t => {
158
+ const tokenizer = createTokenizerForProvider('auto', 'gpt-4');
159
+ t.true(tokenizer instanceof OpenAITokenizer);
160
+ });
161
+
162
+ test('createTokenizerForProvider handles auto mode without model ID', t => {
163
+ const tokenizer = createTokenizerForProvider('auto');
164
+ t.true(tokenizer instanceof FallbackTokenizer);
165
+ });
166
+
167
+ test('createTokenizerForProvider works without model ID', t => {
168
+ const tokenizer = createTokenizerForProvider('openai');
169
+ t.true(tokenizer instanceof OpenAITokenizer);
170
+ });
@@ -0,0 +1,125 @@
1
+ /**
2
+ * Tokenizer factory
3
+ * Creates appropriate tokenizer based on provider and model
4
+ */
5
+
6
+ import type {Tokenizer, TokenizerProvider} from '../types/tokenization.js';
7
+ import {AnthropicTokenizer} from './tokenizers/anthropic-tokenizer.js';
8
+ import {FallbackTokenizer} from './tokenizers/fallback-tokenizer.js';
9
+ import {LlamaTokenizer} from './tokenizers/llama-tokenizer.js';
10
+ import {OpenAITokenizer} from './tokenizers/openai-tokenizer.js';
11
+
12
+ /**
13
+ * Detect provider from model ID or provider name
14
+ */
15
+ function detectProvider(
16
+ providerName: string,
17
+ modelId: string,
18
+ ): TokenizerProvider {
19
+ const lowerProvider = providerName.toLowerCase();
20
+ const lowerModel = modelId.toLowerCase();
21
+
22
+ // Check provider name
23
+ if (lowerProvider.includes('openai')) {
24
+ return 'openai';
25
+ }
26
+
27
+ if (lowerProvider.includes('anthropic') || lowerProvider.includes('claude')) {
28
+ return 'anthropic';
29
+ }
30
+
31
+ // Check model ID for common patterns
32
+ if (lowerModel.includes('gpt') || lowerModel.includes('openai')) {
33
+ return 'openai';
34
+ }
35
+
36
+ if (lowerModel.includes('claude')) {
37
+ return 'anthropic';
38
+ }
39
+
40
+ if (
41
+ lowerModel.includes('llama') ||
42
+ lowerModel.includes('mistral') ||
43
+ lowerModel.includes('qwen') ||
44
+ lowerModel.includes('gemma') ||
45
+ lowerModel.includes('phi') ||
46
+ lowerModel.includes('codellama') ||
47
+ lowerModel.includes('deepseek') ||
48
+ lowerModel.includes('mixtral')
49
+ ) {
50
+ return 'llama';
51
+ }
52
+
53
+ // Default to llama for local models (most common for local inference)
54
+ if (
55
+ lowerProvider.includes('ollama') ||
56
+ lowerProvider.includes('llama.cpp') ||
57
+ lowerProvider.includes('local')
58
+ ) {
59
+ return 'llama';
60
+ }
61
+
62
+ return 'fallback';
63
+ }
64
+
65
+ /**
66
+ * Create a tokenizer based on provider and model
67
+ */
68
+ export function createTokenizer(
69
+ providerName: string,
70
+ modelId: string,
71
+ ): Tokenizer {
72
+ // Strip :cloud suffix if present (Ollama cloud models)
73
+ const normalizedModelId =
74
+ modelId.endsWith(':cloud') || modelId.endsWith('-cloud')
75
+ ? modelId.slice(0, -6)
76
+ : modelId;
77
+
78
+ const provider = detectProvider(providerName, normalizedModelId);
79
+
80
+ switch (provider) {
81
+ case 'openai':
82
+ return new OpenAITokenizer(normalizedModelId);
83
+
84
+ case 'anthropic':
85
+ return new AnthropicTokenizer(normalizedModelId);
86
+
87
+ case 'llama':
88
+ return new LlamaTokenizer(normalizedModelId);
89
+
90
+ case 'fallback':
91
+ default:
92
+ return new FallbackTokenizer();
93
+ }
94
+ }
95
+
96
+ /**
97
+ * Create a tokenizer with explicit provider
98
+ */
99
+ export function createTokenizerForProvider(
100
+ provider: TokenizerProvider,
101
+ modelId?: string,
102
+ ): Tokenizer {
103
+ switch (provider) {
104
+ case 'openai':
105
+ return new OpenAITokenizer(modelId);
106
+
107
+ case 'anthropic':
108
+ return new AnthropicTokenizer(modelId);
109
+
110
+ case 'llama':
111
+ return new LlamaTokenizer(modelId);
112
+
113
+ case 'auto':
114
+ // Auto-detect based on model ID if provided
115
+ if (modelId) {
116
+ return createTokenizer('', modelId);
117
+ }
118
+
119
+ return new FallbackTokenizer();
120
+
121
+ case 'fallback':
122
+ default:
123
+ return new FallbackTokenizer();
124
+ }
125
+ }