@gguf/coder 0.2.9 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (439) 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/dist/tools/execute-bash.js +3 -3
  10. package/dist/tools/execute-bash.js.map +1 -1
  11. package/dist/tools/fetch-url.js +3 -3
  12. package/dist/tools/fetch-url.js.map +1 -1
  13. package/dist/tools/find-files.d.ts.map +1 -1
  14. package/dist/tools/find-files.js +1 -1
  15. package/dist/tools/find-files.js.map +1 -1
  16. package/dist/tools/lsp-get-diagnostics.js +1 -1
  17. package/dist/tools/lsp-get-diagnostics.js.map +1 -1
  18. package/dist/tools/read-file.d.ts.map +1 -1
  19. package/dist/tools/read-file.js +6 -6
  20. package/dist/tools/read-file.js.map +1 -1
  21. package/dist/tools/search-file-contents.d.ts.map +1 -1
  22. package/dist/tools/search-file-contents.js +1 -1
  23. package/dist/tools/search-file-contents.js.map +1 -1
  24. package/dist/tools/string-replace.js +11 -11
  25. package/dist/tools/string-replace.js.map +1 -1
  26. package/dist/tools/web-search.d.ts.map +1 -1
  27. package/dist/tools/web-search.js +3 -3
  28. package/dist/tools/web-search.js.map +1 -1
  29. package/dist/tools/write-file.js +4 -4
  30. package/dist/tools/write-file.js.map +1 -1
  31. package/dist/utils/tool-result-display.d.ts.map +1 -1
  32. package/dist/utils/tool-result-display.js +3 -3
  33. package/dist/utils/tool-result-display.js.map +1 -1
  34. package/package.json +2 -14
  35. package/scripts/extract-changelog.js +73 -0
  36. package/scripts/fetch-models.js +143 -0
  37. package/scripts/test.sh +40 -0
  38. package/scripts/update-homebrew-formula.sh +125 -0
  39. package/scripts/update-nix-version.sh +157 -0
  40. package/source/ai-sdk-client/AISDKClient.spec.ts +117 -0
  41. package/source/ai-sdk-client/AISDKClient.ts +155 -0
  42. package/source/ai-sdk-client/chat/chat-handler.spec.ts +121 -0
  43. package/source/ai-sdk-client/chat/chat-handler.ts +276 -0
  44. package/source/ai-sdk-client/chat/streaming-handler.spec.ts +173 -0
  45. package/source/ai-sdk-client/chat/streaming-handler.ts +110 -0
  46. package/source/ai-sdk-client/chat/tool-processor.spec.ts +92 -0
  47. package/source/ai-sdk-client/chat/tool-processor.ts +70 -0
  48. package/source/ai-sdk-client/converters/message-converter.spec.ts +220 -0
  49. package/source/ai-sdk-client/converters/message-converter.ts +113 -0
  50. package/source/ai-sdk-client/converters/tool-converter.spec.ts +90 -0
  51. package/source/ai-sdk-client/converters/tool-converter.ts +46 -0
  52. package/source/ai-sdk-client/error-handling/error-extractor.spec.ts +55 -0
  53. package/source/ai-sdk-client/error-handling/error-extractor.ts +15 -0
  54. package/source/ai-sdk-client/error-handling/error-parser.spec.ts +169 -0
  55. package/source/ai-sdk-client/error-handling/error-parser.ts +161 -0
  56. package/source/ai-sdk-client/index.ts +7 -0
  57. package/source/ai-sdk-client/providers/provider-factory.spec.ts +71 -0
  58. package/source/ai-sdk-client/providers/provider-factory.ts +41 -0
  59. package/source/ai-sdk-client/types.ts +9 -0
  60. package/source/ai-sdk-client-empty-message.spec.ts +141 -0
  61. package/source/ai-sdk-client-error-handling.spec.ts +186 -0
  62. package/source/ai-sdk-client-maxretries.spec.ts +114 -0
  63. package/source/ai-sdk-client-preparestep.spec.ts +279 -0
  64. package/source/app/App.spec.tsx +32 -0
  65. package/source/app/App.tsx +480 -0
  66. package/source/app/components/AppContainer.spec.tsx +96 -0
  67. package/source/app/components/AppContainer.tsx +56 -0
  68. package/source/app/components/ChatInterface.spec.tsx +163 -0
  69. package/source/app/components/ChatInterface.tsx +144 -0
  70. package/source/app/components/ModalSelectors.spec.tsx +141 -0
  71. package/source/app/components/ModalSelectors.tsx +135 -0
  72. package/source/app/helpers.spec.ts +97 -0
  73. package/source/app/helpers.ts +63 -0
  74. package/source/app/index.ts +4 -0
  75. package/source/app/types.ts +39 -0
  76. package/source/app/utils/appUtils.ts +294 -0
  77. package/source/app/utils/conversationState.ts +310 -0
  78. package/source/app.spec.tsx +244 -0
  79. package/source/cli.spec.ts +73 -0
  80. package/source/cli.tsx +51 -0
  81. package/source/client-factory.spec.ts +48 -0
  82. package/source/client-factory.ts +178 -0
  83. package/source/command-parser.spec.ts +127 -0
  84. package/source/command-parser.ts +36 -0
  85. package/source/commands/checkpoint.spec.tsx +277 -0
  86. package/source/commands/checkpoint.tsx +366 -0
  87. package/source/commands/clear.tsx +22 -0
  88. package/source/commands/custom-commands.tsx +121 -0
  89. package/source/commands/exit.ts +21 -0
  90. package/source/commands/export.spec.tsx +131 -0
  91. package/source/commands/export.tsx +79 -0
  92. package/source/commands/help.tsx +120 -0
  93. package/source/commands/index.ts +17 -0
  94. package/source/commands/init.tsx +339 -0
  95. package/source/commands/lsp-command.spec.tsx +281 -0
  96. package/source/commands/lsp.tsx +120 -0
  97. package/source/commands/mcp-command.spec.tsx +313 -0
  98. package/source/commands/mcp.tsx +162 -0
  99. package/source/commands/model-database.spec.tsx +758 -0
  100. package/source/commands/model-database.tsx +418 -0
  101. package/source/commands/model.ts +12 -0
  102. package/source/commands/provider.ts +12 -0
  103. package/source/commands/setup-config.tsx +16 -0
  104. package/source/commands/simple-commands.spec.tsx +175 -0
  105. package/source/commands/status.ts +12 -0
  106. package/source/commands/theme.ts +12 -0
  107. package/source/commands/update.spec.tsx +261 -0
  108. package/source/commands/update.tsx +201 -0
  109. package/source/commands/usage.spec.tsx +495 -0
  110. package/source/commands/usage.tsx +100 -0
  111. package/source/commands.spec.ts +436 -0
  112. package/source/commands.ts +83 -0
  113. package/source/components/assistant-message.spec.tsx +796 -0
  114. package/source/components/assistant-message.tsx +34 -0
  115. package/source/components/bash-execution-indicator.tsx +21 -0
  116. package/source/components/cancelling-indicator.tsx +16 -0
  117. package/source/components/chat-queue.spec.tsx +83 -0
  118. package/source/components/chat-queue.tsx +36 -0
  119. package/source/components/checkpoint-display.spec.tsx +219 -0
  120. package/source/components/checkpoint-display.tsx +126 -0
  121. package/source/components/checkpoint-selector.spec.tsx +173 -0
  122. package/source/components/checkpoint-selector.tsx +173 -0
  123. package/source/components/development-mode-indicator.spec.tsx +268 -0
  124. package/source/components/development-mode-indicator.tsx +38 -0
  125. package/source/components/message-box.spec.tsx +427 -0
  126. package/source/components/message-box.tsx +87 -0
  127. package/source/components/model-selector.tsx +132 -0
  128. package/source/components/provider-selector.tsx +75 -0
  129. package/source/components/random-spinner.tsx +19 -0
  130. package/source/components/security-disclaimer.tsx +73 -0
  131. package/source/components/status-connection-display.spec.tsx +133 -0
  132. package/source/components/status.tsx +267 -0
  133. package/source/components/theme-selector.tsx +126 -0
  134. package/source/components/tool-confirmation.tsx +190 -0
  135. package/source/components/tool-execution-indicator.tsx +33 -0
  136. package/source/components/tool-message.tsx +85 -0
  137. package/source/components/ui/titled-box.spec.tsx +207 -0
  138. package/source/components/ui/titled-box.tsx +57 -0
  139. package/source/components/usage/progress-bar.spec.tsx +398 -0
  140. package/source/components/usage/progress-bar.tsx +30 -0
  141. package/source/components/usage/usage-display.spec.tsx +780 -0
  142. package/source/components/usage/usage-display.tsx +291 -0
  143. package/source/components/user-input.spec.tsx +327 -0
  144. package/source/components/user-input.tsx +533 -0
  145. package/source/components/user-message.spec.tsx +230 -0
  146. package/source/components/user-message.tsx +84 -0
  147. package/source/components/welcome-message.tsx +76 -0
  148. package/source/config/env-substitution.ts +65 -0
  149. package/source/config/index.spec.ts +171 -0
  150. package/source/config/index.ts +154 -0
  151. package/source/config/paths.spec.ts +241 -0
  152. package/source/config/paths.ts +55 -0
  153. package/source/config/preferences.ts +51 -0
  154. package/source/config/themes.ts +315 -0
  155. package/source/constants.ts +130 -0
  156. package/source/context/mode-context.spec.ts +79 -0
  157. package/source/context/mode-context.ts +24 -0
  158. package/source/custom-commands/executor.spec.ts +142 -0
  159. package/source/custom-commands/executor.ts +64 -0
  160. package/source/custom-commands/loader.spec.ts +314 -0
  161. package/source/custom-commands/loader.ts +153 -0
  162. package/source/custom-commands/parser.ts +196 -0
  163. package/source/hooks/chat-handler/conversation/conversation-loop.spec.ts +39 -0
  164. package/source/hooks/chat-handler/conversation/conversation-loop.tsx +511 -0
  165. package/source/hooks/chat-handler/conversation/tool-executor.spec.ts +50 -0
  166. package/source/hooks/chat-handler/conversation/tool-executor.tsx +109 -0
  167. package/source/hooks/chat-handler/index.ts +12 -0
  168. package/source/hooks/chat-handler/state/streaming-state.spec.ts +26 -0
  169. package/source/hooks/chat-handler/state/streaming-state.ts +19 -0
  170. package/source/hooks/chat-handler/types.ts +38 -0
  171. package/source/hooks/chat-handler/useChatHandler.spec.tsx +321 -0
  172. package/source/hooks/chat-handler/useChatHandler.tsx +194 -0
  173. package/source/hooks/chat-handler/utils/context-checker.spec.ts +60 -0
  174. package/source/hooks/chat-handler/utils/context-checker.tsx +73 -0
  175. package/source/hooks/chat-handler/utils/message-helpers.spec.ts +42 -0
  176. package/source/hooks/chat-handler/utils/message-helpers.tsx +36 -0
  177. package/source/hooks/chat-handler/utils/tool-filters.spec.ts +109 -0
  178. package/source/hooks/chat-handler/utils/tool-filters.ts +64 -0
  179. package/source/hooks/useAppHandlers.tsx +291 -0
  180. package/source/hooks/useAppInitialization.tsx +422 -0
  181. package/source/hooks/useAppState.tsx +311 -0
  182. package/source/hooks/useDirectoryTrust.tsx +98 -0
  183. package/source/hooks/useInputState.ts +414 -0
  184. package/source/hooks/useModeHandlers.tsx +302 -0
  185. package/source/hooks/useNonInteractiveMode.ts +140 -0
  186. package/source/hooks/useTerminalWidth.tsx +81 -0
  187. package/source/hooks/useTheme.ts +18 -0
  188. package/source/hooks/useToolHandler.tsx +349 -0
  189. package/source/hooks/useUIState.ts +61 -0
  190. package/source/init/agents-template-generator.ts +421 -0
  191. package/source/init/existing-rules-extractor.ts +319 -0
  192. package/source/init/file-scanner.spec.ts +227 -0
  193. package/source/init/file-scanner.ts +238 -0
  194. package/source/init/framework-detector.ts +382 -0
  195. package/source/init/language-detector.ts +269 -0
  196. package/source/init/project-analyzer.spec.ts +231 -0
  197. package/source/init/project-analyzer.ts +458 -0
  198. package/source/lsp/index.ts +31 -0
  199. package/source/lsp/lsp-client.spec.ts +508 -0
  200. package/source/lsp/lsp-client.ts +487 -0
  201. package/source/lsp/lsp-manager.spec.ts +477 -0
  202. package/source/lsp/lsp-manager.ts +419 -0
  203. package/source/lsp/protocol.spec.ts +502 -0
  204. package/source/lsp/protocol.ts +360 -0
  205. package/source/lsp/server-discovery.spec.ts +654 -0
  206. package/source/lsp/server-discovery.ts +515 -0
  207. package/source/markdown-parser/html-entities.spec.ts +88 -0
  208. package/source/markdown-parser/html-entities.ts +45 -0
  209. package/source/markdown-parser/index.spec.ts +281 -0
  210. package/source/markdown-parser/index.ts +126 -0
  211. package/source/markdown-parser/table-parser.spec.ts +133 -0
  212. package/source/markdown-parser/table-parser.ts +114 -0
  213. package/source/markdown-parser/utils.spec.ts +70 -0
  214. package/source/markdown-parser/utils.ts +13 -0
  215. package/source/mcp/mcp-client.spec.ts +81 -0
  216. package/source/mcp/mcp-client.ts +625 -0
  217. package/source/mcp/transport-factory.spec.ts +406 -0
  218. package/source/mcp/transport-factory.ts +312 -0
  219. package/source/message-handler.ts +67 -0
  220. package/source/model-database/database-engine.spec.ts +494 -0
  221. package/source/model-database/database-engine.ts +50 -0
  222. package/source/model-database/model-database.spec.ts +363 -0
  223. package/source/model-database/model-database.ts +91 -0
  224. package/source/model-database/model-engine.spec.ts +447 -0
  225. package/source/model-database/model-engine.ts +65 -0
  226. package/source/model-database/model-fetcher.spec.ts +583 -0
  227. package/source/model-database/model-fetcher.ts +330 -0
  228. package/source/models/index.ts +1 -0
  229. package/source/models/models-cache.spec.ts +214 -0
  230. package/source/models/models-cache.ts +78 -0
  231. package/source/models/models-dev-client.spec.ts +379 -0
  232. package/source/models/models-dev-client.ts +329 -0
  233. package/source/models/models-types.ts +68 -0
  234. package/source/prompt-history.ts +155 -0
  235. package/source/security/command-injection.spec.ts +240 -0
  236. package/source/services/checkpoint-manager.spec.ts +523 -0
  237. package/source/services/checkpoint-manager.ts +466 -0
  238. package/source/services/file-snapshot.spec.ts +569 -0
  239. package/source/services/file-snapshot.ts +220 -0
  240. package/source/test-utils/render-with-theme.tsx +48 -0
  241. package/source/tokenization/index.ts +1 -0
  242. package/source/tokenization/tokenizer-factory.spec.ts +170 -0
  243. package/source/tokenization/tokenizer-factory.ts +125 -0
  244. package/source/tokenization/tokenizers/anthropic-tokenizer.spec.ts +200 -0
  245. package/source/tokenization/tokenizers/anthropic-tokenizer.ts +43 -0
  246. package/source/tokenization/tokenizers/fallback-tokenizer.spec.ts +236 -0
  247. package/source/tokenization/tokenizers/fallback-tokenizer.ts +26 -0
  248. package/source/tokenization/tokenizers/llama-tokenizer.spec.ts +224 -0
  249. package/source/tokenization/tokenizers/llama-tokenizer.ts +41 -0
  250. package/source/tokenization/tokenizers/openai-tokenizer.spec.ts +184 -0
  251. package/source/tokenization/tokenizers/openai-tokenizer.ts +57 -0
  252. package/source/tool-calling/index.ts +5 -0
  253. package/source/tool-calling/json-parser.spec.ts +639 -0
  254. package/source/tool-calling/json-parser.ts +247 -0
  255. package/source/tool-calling/tool-parser.spec.ts +395 -0
  256. package/source/tool-calling/tool-parser.ts +120 -0
  257. package/source/tool-calling/xml-parser.spec.ts +662 -0
  258. package/source/tool-calling/xml-parser.ts +289 -0
  259. package/source/tools/execute-bash.spec.tsx +353 -0
  260. package/source/tools/execute-bash.tsx +219 -0
  261. package/source/tools/execute-function.spec.ts +130 -0
  262. package/source/tools/fetch-url.spec.tsx +342 -0
  263. package/source/tools/fetch-url.tsx +172 -0
  264. package/source/tools/find-files.spec.tsx +924 -0
  265. package/source/tools/find-files.tsx +293 -0
  266. package/source/tools/index.ts +102 -0
  267. package/source/tools/lsp-get-diagnostics.tsx +192 -0
  268. package/source/tools/needs-approval.spec.ts +282 -0
  269. package/source/tools/read-file.spec.tsx +801 -0
  270. package/source/tools/read-file.tsx +387 -0
  271. package/source/tools/search-file-contents.spec.tsx +1273 -0
  272. package/source/tools/search-file-contents.tsx +293 -0
  273. package/source/tools/string-replace.spec.tsx +730 -0
  274. package/source/tools/string-replace.tsx +548 -0
  275. package/source/tools/tool-manager.ts +210 -0
  276. package/source/tools/tool-registry.spec.ts +415 -0
  277. package/source/tools/tool-registry.ts +228 -0
  278. package/source/tools/web-search.tsx +223 -0
  279. package/source/tools/write-file.spec.tsx +559 -0
  280. package/source/tools/write-file.tsx +228 -0
  281. package/source/types/app.ts +37 -0
  282. package/source/types/checkpoint.ts +48 -0
  283. package/source/types/commands.ts +46 -0
  284. package/source/types/components.ts +27 -0
  285. package/source/types/config.ts +103 -0
  286. package/source/types/core-connection-status.spec.ts +67 -0
  287. package/source/types/core.ts +181 -0
  288. package/source/types/hooks.ts +50 -0
  289. package/source/types/index.ts +12 -0
  290. package/source/types/markdown-parser.ts +11 -0
  291. package/source/types/mcp.ts +52 -0
  292. package/source/types/system.ts +16 -0
  293. package/source/types/tokenization.ts +41 -0
  294. package/source/types/ui.ts +40 -0
  295. package/source/types/usage.ts +58 -0
  296. package/source/types/utils.ts +16 -0
  297. package/source/usage/calculator.spec.ts +385 -0
  298. package/source/usage/calculator.ts +104 -0
  299. package/source/usage/storage.spec.ts +703 -0
  300. package/source/usage/storage.ts +238 -0
  301. package/source/usage/tracker.spec.ts +456 -0
  302. package/source/usage/tracker.ts +102 -0
  303. package/source/utils/atomic-deletion.spec.ts +194 -0
  304. package/source/utils/atomic-deletion.ts +127 -0
  305. package/source/utils/bounded-map.spec.ts +300 -0
  306. package/source/utils/bounded-map.ts +193 -0
  307. package/source/utils/checkpoint-utils.spec.ts +222 -0
  308. package/source/utils/checkpoint-utils.ts +92 -0
  309. package/source/utils/error-formatter.spec.ts +169 -0
  310. package/source/utils/error-formatter.ts +194 -0
  311. package/source/utils/file-autocomplete.spec.ts +173 -0
  312. package/source/utils/file-autocomplete.ts +196 -0
  313. package/source/utils/file-cache.spec.ts +309 -0
  314. package/source/utils/file-cache.ts +195 -0
  315. package/source/utils/file-content-loader.spec.ts +180 -0
  316. package/source/utils/file-content-loader.ts +179 -0
  317. package/source/utils/file-mention-handler.spec.ts +261 -0
  318. package/source/utils/file-mention-handler.ts +84 -0
  319. package/source/utils/file-mention-parser.spec.ts +182 -0
  320. package/source/utils/file-mention-parser.ts +170 -0
  321. package/source/utils/fuzzy-matching.spec.ts +149 -0
  322. package/source/utils/fuzzy-matching.ts +146 -0
  323. package/source/utils/indentation-normalizer.spec.ts +216 -0
  324. package/source/utils/indentation-normalizer.ts +76 -0
  325. package/source/utils/installation-detector.spec.ts +178 -0
  326. package/source/utils/installation-detector.ts +153 -0
  327. package/source/utils/logging/config.spec.ts +311 -0
  328. package/source/utils/logging/config.ts +210 -0
  329. package/source/utils/logging/console-facade.spec.ts +184 -0
  330. package/source/utils/logging/console-facade.ts +384 -0
  331. package/source/utils/logging/correlation.spec.ts +679 -0
  332. package/source/utils/logging/correlation.ts +474 -0
  333. package/source/utils/logging/formatters.spec.ts +464 -0
  334. package/source/utils/logging/formatters.ts +207 -0
  335. package/source/utils/logging/health-monitor/alerts/alert-manager.spec.ts +93 -0
  336. package/source/utils/logging/health-monitor/alerts/alert-manager.ts +79 -0
  337. package/source/utils/logging/health-monitor/checks/configuration-check.spec.ts +56 -0
  338. package/source/utils/logging/health-monitor/checks/configuration-check.ts +43 -0
  339. package/source/utils/logging/health-monitor/checks/logging-check.spec.ts +56 -0
  340. package/source/utils/logging/health-monitor/checks/logging-check.ts +58 -0
  341. package/source/utils/logging/health-monitor/checks/memory-check.spec.ts +100 -0
  342. package/source/utils/logging/health-monitor/checks/memory-check.ts +78 -0
  343. package/source/utils/logging/health-monitor/checks/performance-check.spec.ts +56 -0
  344. package/source/utils/logging/health-monitor/checks/performance-check.ts +56 -0
  345. package/source/utils/logging/health-monitor/checks/request-check.spec.ts +56 -0
  346. package/source/utils/logging/health-monitor/checks/request-check.ts +76 -0
  347. package/source/utils/logging/health-monitor/core/health-check-runner.spec.ts +70 -0
  348. package/source/utils/logging/health-monitor/core/health-check-runner.ts +138 -0
  349. package/source/utils/logging/health-monitor/core/health-monitor.spec.ts +58 -0
  350. package/source/utils/logging/health-monitor/core/health-monitor.ts +344 -0
  351. package/source/utils/logging/health-monitor/core/scoring.spec.ts +65 -0
  352. package/source/utils/logging/health-monitor/core/scoring.ts +91 -0
  353. package/source/utils/logging/health-monitor/index.ts +15 -0
  354. package/source/utils/logging/health-monitor/instances.ts +48 -0
  355. package/source/utils/logging/health-monitor/middleware/http-middleware.spec.ts +141 -0
  356. package/source/utils/logging/health-monitor/middleware/http-middleware.ts +75 -0
  357. package/source/utils/logging/health-monitor/types.ts +126 -0
  358. package/source/utils/logging/index.spec.ts +284 -0
  359. package/source/utils/logging/index.ts +236 -0
  360. package/source/utils/logging/integration.spec.ts +441 -0
  361. package/source/utils/logging/log-method-factory.spec.ts +573 -0
  362. package/source/utils/logging/log-method-factory.ts +233 -0
  363. package/source/utils/logging/log-query/aggregation/aggregator.spec.ts +277 -0
  364. package/source/utils/logging/log-query/aggregation/aggregator.ts +159 -0
  365. package/source/utils/logging/log-query/aggregation/facet-generator.spec.ts +159 -0
  366. package/source/utils/logging/log-query/aggregation/facet-generator.ts +47 -0
  367. package/source/utils/logging/log-query/index.ts +23 -0
  368. package/source/utils/logging/log-query/query/filter-predicates.spec.ts +247 -0
  369. package/source/utils/logging/log-query/query/filter-predicates.ts +154 -0
  370. package/source/utils/logging/log-query/query/query-builder.spec.ts +182 -0
  371. package/source/utils/logging/log-query/query/query-builder.ts +151 -0
  372. package/source/utils/logging/log-query/query/query-engine.spec.ts +214 -0
  373. package/source/utils/logging/log-query/query/query-engine.ts +45 -0
  374. package/source/utils/logging/log-query/storage/circular-buffer.spec.ts +143 -0
  375. package/source/utils/logging/log-query/storage/circular-buffer.ts +75 -0
  376. package/source/utils/logging/log-query/storage/index-manager.spec.ts +150 -0
  377. package/source/utils/logging/log-query/storage/index-manager.ts +71 -0
  378. package/source/utils/logging/log-query/storage/log-storage.spec.ts +257 -0
  379. package/source/utils/logging/log-query/storage/log-storage.ts +80 -0
  380. package/source/utils/logging/log-query/types.ts +163 -0
  381. package/source/utils/logging/log-query/utils/helpers.spec.ts +263 -0
  382. package/source/utils/logging/log-query/utils/helpers.ts +72 -0
  383. package/source/utils/logging/log-query/utils/sorting.spec.ts +182 -0
  384. package/source/utils/logging/log-query/utils/sorting.ts +61 -0
  385. package/source/utils/logging/logger-provider.spec.ts +262 -0
  386. package/source/utils/logging/logger-provider.ts +362 -0
  387. package/source/utils/logging/performance.spec.ts +209 -0
  388. package/source/utils/logging/performance.ts +757 -0
  389. package/source/utils/logging/pino-logger.spec.ts +425 -0
  390. package/source/utils/logging/pino-logger.ts +514 -0
  391. package/source/utils/logging/redaction.spec.ts +490 -0
  392. package/source/utils/logging/redaction.ts +267 -0
  393. package/source/utils/logging/request-tracker.spec.ts +1198 -0
  394. package/source/utils/logging/request-tracker.ts +803 -0
  395. package/source/utils/logging/transports.spec.ts +505 -0
  396. package/source/utils/logging/transports.ts +305 -0
  397. package/source/utils/logging/types.ts +216 -0
  398. package/source/utils/message-builder.spec.ts +179 -0
  399. package/source/utils/message-builder.ts +101 -0
  400. package/source/utils/message-queue.tsx +486 -0
  401. package/source/utils/paste-detection.spec.ts +69 -0
  402. package/source/utils/paste-detection.ts +124 -0
  403. package/source/utils/paste-roundtrip.spec.ts +442 -0
  404. package/source/utils/paste-utils.spec.ts +128 -0
  405. package/source/utils/paste-utils.ts +52 -0
  406. package/source/utils/programming-language-helper.spec.ts +74 -0
  407. package/source/utils/programming-language-helper.ts +32 -0
  408. package/source/utils/prompt-assembly.spec.ts +221 -0
  409. package/source/utils/prompt-processor.ts +173 -0
  410. package/source/utils/tool-args-parser.spec.ts +136 -0
  411. package/source/utils/tool-args-parser.ts +54 -0
  412. package/source/utils/tool-cancellation.spec.ts +230 -0
  413. package/source/utils/tool-cancellation.ts +28 -0
  414. package/source/utils/tool-result-display.spec.tsx +469 -0
  415. package/source/utils/tool-result-display.tsx +90 -0
  416. package/source/utils/update-checker.spec.ts +383 -0
  417. package/source/utils/update-checker.ts +183 -0
  418. package/source/wizard/config-wizard.spec.tsx +103 -0
  419. package/source/wizard/config-wizard.tsx +382 -0
  420. package/source/wizard/steps/location-step.spec.tsx +186 -0
  421. package/source/wizard/steps/location-step.tsx +147 -0
  422. package/source/wizard/steps/mcp-step.spec.tsx +607 -0
  423. package/source/wizard/steps/mcp-step.tsx +632 -0
  424. package/source/wizard/steps/provider-step.spec.tsx +342 -0
  425. package/source/wizard/steps/provider-step.tsx +957 -0
  426. package/source/wizard/steps/summary-step.spec.tsx +749 -0
  427. package/source/wizard/steps/summary-step.tsx +228 -0
  428. package/source/wizard/templates/mcp-templates.spec.ts +613 -0
  429. package/source/wizard/templates/mcp-templates.ts +570 -0
  430. package/source/wizard/templates/provider-templates.spec.ts +152 -0
  431. package/source/wizard/templates/provider-templates.ts +485 -0
  432. package/source/wizard/utils/fetch-cloud-models.spec.ts +428 -0
  433. package/source/wizard/utils/fetch-cloud-models.ts +223 -0
  434. package/source/wizard/utils/fetch-local-models.spec.ts +297 -0
  435. package/source/wizard/utils/fetch-local-models.ts +192 -0
  436. package/source/wizard/validation-array.spec.ts +264 -0
  437. package/source/wizard/validation.spec.ts +373 -0
  438. package/source/wizard/validation.ts +232 -0
  439. package/source/app/prompts/main-prompt.md +0 -122
@@ -0,0 +1,559 @@
1
+ import {mkdtemp, readFile, rm, writeFile} from 'node:fs/promises';
2
+ import {tmpdir} from 'node:os';
3
+ import {join} from 'node:path';
4
+ import test from 'ava';
5
+ import {render} from 'ink-testing-library';
6
+ import React from 'react';
7
+ import {themes} from '../config/themes.js';
8
+ import {setCurrentMode} from '../context/mode-context.js';
9
+ import {ThemeContext} from '../hooks/useTheme.js';
10
+ import {writeFileTool} from './write-file.js';
11
+
12
+ // ============================================================================
13
+ // Test Helpers
14
+ // ============================================================================
15
+
16
+ console.log(`\nwrite-file.spec.tsx – ${React.version}`);
17
+
18
+ // Create a mock theme provider for tests
19
+ function TestThemeProvider({children}: {children: React.ReactNode}) {
20
+ const themeContextValue = {
21
+ currentTheme: 'tokyo-night' as const,
22
+ colors: themes['tokyo-night'].colors,
23
+ setCurrentTheme: () => {},
24
+ };
25
+
26
+ return (
27
+ <ThemeContext.Provider value={themeContextValue}>
28
+ {children}
29
+ </ThemeContext.Provider>
30
+ );
31
+ }
32
+
33
+ let testDir: string;
34
+
35
+ // Create a temporary directory before each test
36
+ test.beforeEach(async () => {
37
+ testDir = await mkdtemp(join(tmpdir(), 'write-file-test-'));
38
+ });
39
+
40
+ // Clean up temporary directory after each test
41
+ test.afterEach(async () => {
42
+ if (testDir) {
43
+ await rm(testDir, {recursive: true, force: true});
44
+ }
45
+ });
46
+
47
+ // Helper to execute the write_file tool
48
+ async function executeWriteFile(args: {
49
+ path: string;
50
+ content: string;
51
+ }): Promise<string> {
52
+ // biome-ignore lint/suspicious/noExplicitAny: Tool internals require any
53
+ return await (writeFileTool.tool as any).execute(args, {
54
+ toolCallId: 'test',
55
+ messages: [],
56
+ });
57
+ }
58
+
59
+ // Helper to create a test file
60
+ async function createTestFile(
61
+ filename: string,
62
+ content: string,
63
+ ): Promise<string> {
64
+ const filePath = join(testDir, filename);
65
+ await writeFile(filePath, content, 'utf-8');
66
+ return filePath;
67
+ }
68
+
69
+ // ============================================================================
70
+ // Approval Tests
71
+ // ============================================================================
72
+
73
+ test('write_file requires approval in normal mode', async t => {
74
+ setCurrentMode('normal');
75
+ const needsApproval = writeFileTool.tool.needsApproval;
76
+
77
+ if (typeof needsApproval === 'function') {
78
+ const result = await needsApproval(
79
+ {
80
+ path: 'test.txt',
81
+ content: 'test',
82
+ },
83
+ {toolCallId: 'test', messages: []},
84
+ );
85
+ t.true(result);
86
+ } else {
87
+ t.is(needsApproval, true);
88
+ }
89
+ });
90
+
91
+ test('write_file does NOT require approval in auto-accept mode', async t => {
92
+ setCurrentMode('auto-accept');
93
+ const needsApproval = writeFileTool.tool.needsApproval;
94
+
95
+ if (typeof needsApproval === 'function') {
96
+ const result = await needsApproval(
97
+ {
98
+ path: 'test.txt',
99
+ content: 'test',
100
+ },
101
+ {toolCallId: 'test', messages: []},
102
+ );
103
+ t.false(result);
104
+ } else {
105
+ t.is(needsApproval, false);
106
+ }
107
+ });
108
+
109
+ test('write_file requires approval in plan mode', async t => {
110
+ setCurrentMode('plan');
111
+ const needsApproval = writeFileTool.tool.needsApproval;
112
+
113
+ if (typeof needsApproval === 'function') {
114
+ const result = await needsApproval(
115
+ {
116
+ path: 'test.txt',
117
+ content: 'test',
118
+ },
119
+ {toolCallId: 'test', messages: []},
120
+ );
121
+ t.true(result);
122
+ } else {
123
+ t.is(needsApproval, true);
124
+ }
125
+ });
126
+
127
+ // ============================================================================
128
+ // Basic Write Tests
129
+ // ============================================================================
130
+
131
+ test('write_file: create new file', async t => {
132
+ const filePath = join(testDir, 'new.txt');
133
+
134
+ const result = await executeWriteFile({
135
+ path: filePath,
136
+ content: 'Hello World\n',
137
+ });
138
+
139
+ const content = await readFile(filePath, 'utf-8');
140
+ t.is(content, 'Hello World\n');
141
+ t.true(result.includes('File written successfully'));
142
+ t.true(result.includes('File contents after write:'));
143
+ });
144
+
145
+ test('write_file: overwrite existing file', async t => {
146
+ const filePath = await createTestFile('existing.txt', 'Old content\n');
147
+
148
+ const result = await executeWriteFile({
149
+ path: filePath,
150
+ content: 'New content\n',
151
+ });
152
+
153
+ const content = await readFile(filePath, 'utf-8');
154
+ t.is(content, 'New content\n');
155
+ t.true(result.includes('File overwritten successfully'));
156
+ t.true(result.includes('File contents after write:'));
157
+ });
158
+
159
+ test('write_file: write empty file', async t => {
160
+ const filePath = join(testDir, 'empty.txt');
161
+
162
+ const result = await executeWriteFile({
163
+ path: filePath,
164
+ content: '',
165
+ });
166
+
167
+ const content = await readFile(filePath, 'utf-8');
168
+ t.is(content, '');
169
+ t.true(result.includes('File written successfully'));
170
+ });
171
+
172
+ test('write_file: write multi-line content', async t => {
173
+ const filePath = join(testDir, 'multi.txt');
174
+ const testContent = 'Line 1\nLine 2\nLine 3';
175
+
176
+ const result = await executeWriteFile({
177
+ path: filePath,
178
+ content: testContent,
179
+ });
180
+
181
+ const content = await readFile(filePath, 'utf-8');
182
+ t.is(content, testContent);
183
+ t.true(result.includes('3 lines'));
184
+ });
185
+
186
+ test('write_file: write large file', async t => {
187
+ const filePath = join(testDir, 'large.txt');
188
+ const largeContent = Array.from({length: 1000}, (_, i) => `Line ${i + 1}`).join(
189
+ '\n',
190
+ );
191
+
192
+ const result = await executeWriteFile({
193
+ path: filePath,
194
+ content: largeContent,
195
+ });
196
+
197
+ const content = await readFile(filePath, 'utf-8');
198
+ t.is(content, largeContent);
199
+ t.true(result.includes('1000 lines'));
200
+ });
201
+
202
+ test('write_file: preserves exact content including whitespace', async t => {
203
+ const filePath = join(testDir, 'whitespace.txt');
204
+ const testContent = ' indented\n\ttabbed\n \t mixed\n';
205
+
206
+ await executeWriteFile({
207
+ path: filePath,
208
+ content: testContent,
209
+ });
210
+
211
+ const content = await readFile(filePath, 'utf-8');
212
+ t.is(content, testContent);
213
+ });
214
+
215
+ // ============================================================================
216
+ // Read-After-Write Verification Tests
217
+ // ============================================================================
218
+
219
+ test('write_file: returns file contents after write', async t => {
220
+ const filePath = join(testDir, 'verify.txt');
221
+
222
+ const result = await executeWriteFile({
223
+ path: filePath,
224
+ content: 'Test content\nLine 2',
225
+ });
226
+
227
+ // Check that result includes the actual file contents
228
+ t.true(result.includes('File contents after write:'));
229
+ t.true(result.includes('Test content'));
230
+ t.true(result.includes('Line 2'));
231
+ t.true(result.includes('2 lines'));
232
+ });
233
+
234
+ test('write_file: detects token count', async t => {
235
+ const filePath = join(testDir, 'tokens.txt');
236
+ const content = 'x'.repeat(400); // ~100 tokens
237
+
238
+ const result = await executeWriteFile({
239
+ path: filePath,
240
+ content,
241
+ });
242
+
243
+ t.true(result.includes('~100 tokens'));
244
+ });
245
+
246
+ // ============================================================================
247
+ // Validator Tests
248
+ // ============================================================================
249
+
250
+ test('write_file validator: accepts valid path', async t => {
251
+ const filePath = join(testDir, 'valid.txt');
252
+
253
+ if (!writeFileTool.validator) {
254
+ t.fail('Validator not defined');
255
+ return;
256
+ }
257
+
258
+ const result = await writeFileTool.validator({
259
+ path: filePath,
260
+ content: 'test',
261
+ });
262
+
263
+ t.true(result.valid);
264
+ });
265
+
266
+ test('write_file validator: rejects non-existent parent directory', async t => {
267
+ const filePath = join(testDir, 'nonexistent', 'file.txt');
268
+
269
+ if (!writeFileTool.validator) {
270
+ t.fail('Validator not defined');
271
+ return;
272
+ }
273
+
274
+ const result = await writeFileTool.validator({
275
+ path: filePath,
276
+ content: 'test',
277
+ });
278
+
279
+ t.false(result.valid);
280
+ if (!result.valid) {
281
+ t.true(result.error.includes('Parent directory does not exist'));
282
+ }
283
+ });
284
+
285
+ test('write_file validator: rejects system directories', async t => {
286
+ if (!writeFileTool.validator) {
287
+ t.fail('Validator not defined');
288
+ return;
289
+ }
290
+
291
+ const systemPaths = ['/etc/test.txt', '/sys/test.txt', '/proc/test.txt'];
292
+
293
+ for (const path of systemPaths) {
294
+ const result = await writeFileTool.validator({
295
+ path,
296
+ content: 'test',
297
+ });
298
+
299
+ t.false(result.valid);
300
+ if (!result.valid) {
301
+ t.true(
302
+ result.error.includes('system directory') ||
303
+ result.error.includes('Parent directory does not exist'),
304
+ );
305
+ }
306
+ }
307
+ });
308
+
309
+ // ============================================================================
310
+ // Special Content Tests
311
+ // ============================================================================
312
+
313
+ test('write_file: handles special characters', async t => {
314
+ const filePath = join(testDir, 'special.txt');
315
+ const content = 'Special: \n\t"quotes"\n\'apostrophes\'\n\\backslash\n';
316
+
317
+ await executeWriteFile({
318
+ path: filePath,
319
+ content,
320
+ });
321
+
322
+ const actual = await readFile(filePath, 'utf-8');
323
+ t.is(actual, content);
324
+ });
325
+
326
+ test('write_file: handles unicode', async t => {
327
+ const filePath = join(testDir, 'unicode.txt');
328
+ const content = 'Unicode: 你好世界 🚀 émoji\n';
329
+
330
+ await executeWriteFile({
331
+ path: filePath,
332
+ content,
333
+ });
334
+
335
+ const actual = await readFile(filePath, 'utf-8');
336
+ t.is(actual, content);
337
+ });
338
+
339
+ // ============================================================================
340
+ // Comparison with create_file
341
+ // ============================================================================
342
+
343
+ test('write_file: can overwrite files (unlike create_file)', async t => {
344
+ const filePath = await createTestFile('existing.txt', 'Original\n');
345
+
346
+ // write_file should succeed
347
+ await t.notThrowsAsync(async () => {
348
+ await executeWriteFile({
349
+ path: filePath,
350
+ content: 'Overwritten\n',
351
+ });
352
+ });
353
+
354
+ const content = await readFile(filePath, 'utf-8');
355
+ t.is(content, 'Overwritten\n');
356
+ });
357
+
358
+ // ============================================================================
359
+ // Formatter Tests (Visual Display with Ink)
360
+ // ============================================================================
361
+
362
+ test('write_file formatter: renders file content preview', async t => {
363
+ const formatter = writeFileTool.formatter;
364
+ if (!formatter) {
365
+ t.fail('Formatter not defined');
366
+ return;
367
+ }
368
+
369
+ const element = await formatter({
370
+ path: 'test.ts',
371
+ content: 'const x = 1;\nconst y = 2;\n',
372
+ });
373
+
374
+ const {lastFrame} = render(<TestThemeProvider>{element}</TestThemeProvider>);
375
+ const output = lastFrame();
376
+
377
+ t.truthy(output);
378
+ t.regex(output!, /write_file/);
379
+ t.regex(output!, /test\.ts/);
380
+ t.regex(output!, /3 lines/); // Trailing newline creates 3 lines
381
+ t.regex(output!, /File content:/);
382
+ });
383
+
384
+ test('write_file formatter: shows normalized indentation for deeply indented code', async t => {
385
+ const formatter = writeFileTool.formatter;
386
+ if (!formatter) {
387
+ t.fail('Formatter not defined');
388
+ return;
389
+ }
390
+
391
+ const element = await formatter({
392
+ path: 'nested.jsx',
393
+ content: ' function Component() {\n return (\n <div>Hello</div>\n );\n }\n',
394
+ });
395
+
396
+ const {lastFrame} = render(<TestThemeProvider>{element}</TestThemeProvider>);
397
+ const output = lastFrame();
398
+
399
+ t.truthy(output);
400
+ // Should show normalized indentation (leftmost code at column 0)
401
+ t.regex(output!, /write_file/);
402
+ t.regex(output!, /nested\.jsx/);
403
+ t.regex(output!, /6 lines/); // Trailing newline creates 6 lines
404
+ });
405
+
406
+ test('write_file formatter: displays token count', async t => {
407
+ const formatter = writeFileTool.formatter;
408
+ if (!formatter) {
409
+ t.fail('Formatter not defined');
410
+ return;
411
+ }
412
+
413
+ const content = 'x'.repeat(400); // ~100 tokens
414
+
415
+ const element = await formatter({
416
+ path: 'large.txt',
417
+ content,
418
+ });
419
+
420
+ const {lastFrame} = render(<TestThemeProvider>{element}</TestThemeProvider>);
421
+ const output = lastFrame();
422
+
423
+ t.truthy(output);
424
+ t.regex(output!, /~100 tokens/);
425
+ });
426
+
427
+ test('write_file formatter: handles empty file', async t => {
428
+ const formatter = writeFileTool.formatter;
429
+ if (!formatter) {
430
+ t.fail('Formatter not defined');
431
+ return;
432
+ }
433
+
434
+ const element = await formatter({
435
+ path: 'empty.txt',
436
+ content: '',
437
+ });
438
+
439
+ const {lastFrame} = render(<TestThemeProvider>{element}</TestThemeProvider>);
440
+ const output = lastFrame();
441
+
442
+ t.truthy(output);
443
+ t.regex(output!, /write_file/);
444
+ t.regex(output!, /File will be empty/);
445
+ });
446
+
447
+ test('write_file formatter: shows line numbers with content', async t => {
448
+ const formatter = writeFileTool.formatter;
449
+ if (!formatter) {
450
+ t.fail('Formatter not defined');
451
+ return;
452
+ }
453
+
454
+ const element = await formatter({
455
+ path: 'numbered.ts',
456
+ content: 'line1\nline2\nline3\n',
457
+ });
458
+
459
+ const {lastFrame} = render(<TestThemeProvider>{element}</TestThemeProvider>);
460
+ const output = lastFrame();
461
+
462
+ t.truthy(output);
463
+ // Line numbers should be padded to 4 spaces
464
+ t.regex(output!, /1\s+line1/);
465
+ t.regex(output!, /2\s+line2/);
466
+ t.regex(output!, /3\s+line3/);
467
+ });
468
+
469
+ test('write_file formatter: normalizes tabs to 2 spaces', async t => {
470
+ const formatter = writeFileTool.formatter;
471
+ if (!formatter) {
472
+ t.fail('Formatter not defined');
473
+ return;
474
+ }
475
+
476
+ const element = await formatter({
477
+ path: 'tabs.go',
478
+ content: '\t\tfunc main() {\n\t\t\tfmt.Println("hello")\n\t\t}\n',
479
+ });
480
+
481
+ const {lastFrame} = render(<TestThemeProvider>{element}</TestThemeProvider>);
482
+ const output = lastFrame();
483
+
484
+ t.truthy(output);
485
+ // Should normalize tabs to spaces for display
486
+ t.regex(output!, /write_file/);
487
+ t.regex(output!, /tabs\.go/);
488
+ t.regex(output!, /4 lines/); // Trailing newline creates 4 lines
489
+ });
490
+
491
+ test('write_file formatter: handles JSX with normalized indentation', async t => {
492
+ const formatter = writeFileTool.formatter;
493
+ if (!formatter) {
494
+ t.fail('Formatter not defined');
495
+ return;
496
+ }
497
+
498
+ const element = await formatter({
499
+ path: 'component.jsx',
500
+ content: ' export function Button() {\n return <button>Click me</button>;\n }\n',
501
+ });
502
+
503
+ const {lastFrame} = render(<TestThemeProvider>{element}</TestThemeProvider>);
504
+ const output = lastFrame();
505
+
506
+ t.truthy(output);
507
+ t.regex(output!, /write_file/);
508
+ t.regex(output!, /component\.jsx/);
509
+ // Indentation should be normalized
510
+ });
511
+
512
+ test('write_file formatter: shows character count', async t => {
513
+ const formatter = writeFileTool.formatter;
514
+ if (!formatter) {
515
+ t.fail('Formatter not defined');
516
+ return;
517
+ }
518
+
519
+ const element = await formatter({
520
+ path: 'size.txt',
521
+ content: 'Hello World!', // 12 characters
522
+ });
523
+
524
+ const {lastFrame} = render(<TestThemeProvider>{element}</TestThemeProvider>);
525
+ const output = lastFrame();
526
+
527
+ t.truthy(output);
528
+ t.regex(output!, /12 characters/);
529
+ });
530
+
531
+ test('write_file formatter: renders syntax highlighting for code', async t => {
532
+ const formatter = writeFileTool.formatter;
533
+ if (!formatter) {
534
+ t.fail('Formatter not defined');
535
+ return;
536
+ }
537
+
538
+ const element = await formatter({
539
+ path: 'code.ts',
540
+ content: 'const greeting = "Hello";\nconsole.log(greeting);\n',
541
+ });
542
+
543
+ const {lastFrame} = render(<TestThemeProvider>{element}</TestThemeProvider>);
544
+ const output = lastFrame();
545
+
546
+ t.truthy(output);
547
+ t.regex(output!, /write_file/);
548
+ t.regex(output!, /code\.ts/);
549
+ // Content should be present (syntax highlighting adds ANSI codes)
550
+ t.regex(output!, /greeting/);
551
+ });
552
+
553
+ // ============================================================================
554
+ // Cleanup
555
+ // ============================================================================
556
+
557
+ test.after(() => {
558
+ setCurrentMode('normal');
559
+ });