@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,230 @@
1
+ import test from 'ava';
2
+ import {render} from 'ink-testing-library';
3
+ import React from 'react';
4
+ import {themes} from '../config/themes';
5
+ import {ThemeContext} from '../hooks/useTheme';
6
+ import UserMessage from './user-message';
7
+
8
+ console.log(`\nuser-message.spec.tsx – ${React.version}`);
9
+
10
+ // Mock ThemeProvider for testing
11
+ const MockThemeProvider = ({children}: {children: React.ReactNode}) => {
12
+ const mockTheme = {
13
+ currentTheme: 'tokyo-night' as const,
14
+ colors: themes['tokyo-night'].colors,
15
+ setCurrentTheme: () => {},
16
+ };
17
+
18
+ return (
19
+ <ThemeContext.Provider value={mockTheme}>{children}</ThemeContext.Provider>
20
+ );
21
+ };
22
+
23
+ // ============================================================================
24
+ // Component Rendering Tests
25
+ // ============================================================================
26
+
27
+ test('UserMessage renders with basic message', t => {
28
+ const {lastFrame} = render(
29
+ <MockThemeProvider>
30
+ <UserMessage message="Hello world" />
31
+ </MockThemeProvider>,
32
+ );
33
+
34
+ const output = lastFrame();
35
+ t.truthy(output);
36
+ t.regex(output!, /You:/);
37
+ t.regex(output!, /Hello world/);
38
+ });
39
+
40
+ test('UserMessage renders without file placeholders', t => {
41
+ const {lastFrame} = render(
42
+ <MockThemeProvider>
43
+ <UserMessage message="This is a normal message" />
44
+ </MockThemeProvider>,
45
+ );
46
+
47
+ const output = lastFrame();
48
+ t.truthy(output);
49
+ t.regex(output!, /This is a normal message/);
50
+ });
51
+
52
+ test('UserMessage renders with file placeholder', t => {
53
+ const {lastFrame} = render(
54
+ <MockThemeProvider>
55
+ <UserMessage message="Check [@src/app.tsx] for details" />
56
+ </MockThemeProvider>,
57
+ );
58
+
59
+ const output = lastFrame();
60
+ t.truthy(output);
61
+ t.regex(output!, /\[@src\/app\.tsx\]/);
62
+ t.regex(output!, /Check/);
63
+ t.regex(output!, /for details/);
64
+ });
65
+
66
+ test('UserMessage renders with file placeholder with line range', t => {
67
+ const {lastFrame} = render(
68
+ <MockThemeProvider>
69
+ <UserMessage message="Look at [@file.ts:10-20] please" />
70
+ </MockThemeProvider>,
71
+ );
72
+
73
+ const output = lastFrame();
74
+ t.truthy(output);
75
+ t.regex(output!, /\[@file\.ts:10-20\]/);
76
+ });
77
+
78
+ test('UserMessage renders with file placeholder with single line', t => {
79
+ const {lastFrame} = render(
80
+ <MockThemeProvider>
81
+ <UserMessage message="Check [@utils.ts:42] specifically" />
82
+ </MockThemeProvider>,
83
+ );
84
+
85
+ const output = lastFrame();
86
+ t.truthy(output);
87
+ t.regex(output!, /\[@utils\.ts:42\]/);
88
+ });
89
+
90
+ test('UserMessage renders with multiple file placeholders', t => {
91
+ const {lastFrame} = render(
92
+ <MockThemeProvider>
93
+ <UserMessage message="Compare [@src/app.tsx] with [@src/index.tsx]" />
94
+ </MockThemeProvider>,
95
+ );
96
+
97
+ const output = lastFrame();
98
+ t.truthy(output);
99
+ t.regex(output!, /\[@src\/app\.tsx\]/);
100
+ t.regex(output!, /\[@src\/index\.tsx\]/);
101
+ t.regex(output!, /Compare/);
102
+ t.regex(output!, /with/);
103
+ });
104
+
105
+ test('UserMessage renders multi-line message', t => {
106
+ const {lastFrame} = render(
107
+ <MockThemeProvider>
108
+ <UserMessage message="Line 1\nLine 2\nLine 3" />
109
+ </MockThemeProvider>,
110
+ );
111
+
112
+ const output = lastFrame();
113
+ t.truthy(output);
114
+ t.regex(output!, /Line 1/);
115
+ t.regex(output!, /Line 2/);
116
+ t.regex(output!, /Line 3/);
117
+ });
118
+
119
+ test('UserMessage renders multi-line message with file placeholders', t => {
120
+ const {lastFrame} = render(
121
+ <MockThemeProvider>
122
+ <UserMessage message="Check these files:\n[@src/app.tsx]\n[@src/utils.ts]" />
123
+ </MockThemeProvider>,
124
+ );
125
+
126
+ const output = lastFrame();
127
+ t.truthy(output);
128
+ t.regex(output!, /Check these files:/);
129
+ t.regex(output!, /\[@src\/app\.tsx\]/);
130
+ t.regex(output!, /\[@src\/utils\.ts\]/);
131
+ });
132
+
133
+ test('UserMessage renders file placeholder at start of message', t => {
134
+ const {lastFrame} = render(
135
+ <MockThemeProvider>
136
+ <UserMessage message="[@package.json] shows dependencies" />
137
+ </MockThemeProvider>,
138
+ );
139
+
140
+ const output = lastFrame();
141
+ t.truthy(output);
142
+ t.regex(output!, /\[@package\.json\]/);
143
+ });
144
+
145
+ test('UserMessage renders file placeholder at end of message', t => {
146
+ const {lastFrame} = render(
147
+ <MockThemeProvider>
148
+ <UserMessage message="Check the config in [@tsconfig.json]" />
149
+ </MockThemeProvider>,
150
+ );
151
+
152
+ const output = lastFrame();
153
+ t.truthy(output);
154
+ t.regex(output!, /\[@tsconfig\.json\]/);
155
+ });
156
+
157
+ test('UserMessage renders with empty message', t => {
158
+ const {lastFrame} = render(
159
+ <MockThemeProvider>
160
+ <UserMessage message="" />
161
+ </MockThemeProvider>,
162
+ );
163
+
164
+ const output = lastFrame();
165
+ t.truthy(output);
166
+ t.regex(output!, /You:/);
167
+ });
168
+
169
+ test('UserMessage handles file placeholder with special characters in path', t => {
170
+ const {lastFrame} = render(
171
+ <MockThemeProvider>
172
+ <UserMessage message="Check [@src/my-file.spec.ts:100-200]" />
173
+ </MockThemeProvider>,
174
+ );
175
+
176
+ const output = lastFrame();
177
+ t.truthy(output);
178
+ t.regex(output!, /\[@src\/my-file\.spec\.ts:100-200\]/);
179
+ });
180
+
181
+ test('UserMessage handles multiple placeholders on same line', t => {
182
+ const {lastFrame} = render(
183
+ <MockThemeProvider>
184
+ <UserMessage message="Compare [@a.ts] and [@b.ts] and [@c.ts]" />
185
+ </MockThemeProvider>,
186
+ );
187
+
188
+ const output = lastFrame();
189
+ t.truthy(output);
190
+ t.regex(output!, /\[@a\.ts\]/);
191
+ t.regex(output!, /\[@b\.ts\]/);
192
+ t.regex(output!, /\[@c\.ts\]/);
193
+ });
194
+
195
+ test('UserMessage does not render @ symbols that are not placeholders', t => {
196
+ const {lastFrame} = render(
197
+ <MockThemeProvider>
198
+ <UserMessage message="Email me at user@example.com" />
199
+ </MockThemeProvider>,
200
+ );
201
+
202
+ const output = lastFrame();
203
+ t.truthy(output);
204
+ t.regex(output!, /user@example\.com/);
205
+ // Should NOT have placeholder styling since it's not in [@...] format
206
+ });
207
+
208
+ test('UserMessage renders paragraphs with spacing', t => {
209
+ const {lastFrame} = render(
210
+ <MockThemeProvider>
211
+ <UserMessage message="First paragraph\n\nSecond paragraph\n\nThird paragraph" />
212
+ </MockThemeProvider>,
213
+ );
214
+
215
+ const output = lastFrame();
216
+ t.truthy(output);
217
+ t.regex(output!, /First paragraph/);
218
+ t.regex(output!, /Second paragraph/);
219
+ t.regex(output!, /Third paragraph/);
220
+ });
221
+
222
+ test('UserMessage renders without crashing', t => {
223
+ const {lastFrame} = render(
224
+ <MockThemeProvider>
225
+ <UserMessage message="Test" />
226
+ </MockThemeProvider>,
227
+ );
228
+
229
+ t.truthy(lastFrame());
230
+ });
@@ -0,0 +1,84 @@
1
+ import {useTheme} from '@/hooks/useTheme';
2
+ import type {UserMessageProps} from '@/types/index';
3
+ import {Box, Text} from 'ink';
4
+ import {memo} from 'react';
5
+
6
+ // Parse a line and return segments with file placeholders highlighted
7
+ function parseLineWithPlaceholders(line: string) {
8
+ const segments: Array<{text: string; isPlaceholder: boolean}> = [];
9
+ const filePattern = /\[@[^\]]+\]/g;
10
+ let lastIndex = 0;
11
+ let match;
12
+
13
+ while ((match = filePattern.exec(line)) !== null) {
14
+ // Add text before the placeholder
15
+ if (match.index > lastIndex) {
16
+ segments.push({
17
+ text: line.slice(lastIndex, match.index),
18
+ isPlaceholder: false,
19
+ });
20
+ }
21
+
22
+ // Add the placeholder
23
+ segments.push({
24
+ text: match[0],
25
+ isPlaceholder: true,
26
+ });
27
+
28
+ lastIndex = match.index + match[0].length;
29
+ }
30
+
31
+ // Add remaining text
32
+ if (lastIndex < line.length) {
33
+ segments.push({
34
+ text: line.slice(lastIndex),
35
+ isPlaceholder: false,
36
+ });
37
+ }
38
+
39
+ return segments;
40
+ }
41
+
42
+ export default memo(function UserMessage({message}: UserMessageProps) {
43
+ const {colors} = useTheme();
44
+
45
+ const lines = message.split('\n');
46
+
47
+ return (
48
+ <Box flexDirection="column" marginBottom={1}>
49
+ <Box>
50
+ <Text color={colors.secondary} bold>
51
+ You:
52
+ </Text>
53
+ </Box>
54
+ <Box flexDirection="column">
55
+ {lines.map((line, lineIndex) => {
56
+ // Skip empty lines - they create paragraph spacing via marginBottom
57
+ if (line.trim() === '') {
58
+ return null;
59
+ }
60
+
61
+ const segments = parseLineWithPlaceholders(line);
62
+ const isEndOfParagraph =
63
+ lineIndex + 1 < lines.length && lines[lineIndex + 1].trim() === '';
64
+
65
+ return (
66
+ <Box key={lineIndex} marginBottom={isEndOfParagraph ? 1 : 0}>
67
+ <Text>
68
+ {segments.map((segment, segIndex) => (
69
+ <Text
70
+ key={segIndex}
71
+ color={segment.isPlaceholder ? colors.info : colors.white}
72
+ bold={segment.isPlaceholder}
73
+ >
74
+ {segment.text}
75
+ </Text>
76
+ ))}
77
+ </Text>
78
+ </Box>
79
+ );
80
+ })}
81
+ </Box>
82
+ </Box>
83
+ );
84
+ });
@@ -0,0 +1,76 @@
1
+ import {Box, Text} from 'ink';
2
+ import {memo} from 'react';
3
+
4
+ import {TitledBox} from '@/components/ui/titled-box';
5
+ import {useResponsiveTerminal} from '@/hooks/useTerminalWidth';
6
+ import {useTheme} from '@/hooks/useTheme';
7
+
8
+ import fs from 'fs';
9
+ import path from 'path';
10
+ import {fileURLToPath} from 'url';
11
+ import BigText from 'ink-big-text';
12
+ import Gradient from 'ink-gradient';
13
+
14
+ const __filename = fileURLToPath(import.meta.url);
15
+ const __dirname = path.dirname(__filename);
16
+
17
+ // Read package.json once at module load time to avoid repeated file reads
18
+ const packageJson = JSON.parse(
19
+ fs.readFileSync(path.join(__dirname, '../../package.json'), 'utf8'),
20
+ ) as {version: string};
21
+
22
+ export default memo(function WelcomeMessage() {
23
+ const {boxWidth, isNarrow, isNormal} = useResponsiveTerminal();
24
+ const {colors} = useTheme();
25
+
26
+ return (
27
+ <>
28
+ {/* Narrow terminal: simple text without boxes */}
29
+ {isNarrow ? (
30
+ <>
31
+ <Gradient colors={[colors.primary, colors.tool]}>
32
+ <BigText text="coder" font="tiny" />
33
+ </Gradient>
34
+ <Box
35
+ flexDirection="column"
36
+ marginBottom={1}
37
+ borderStyle="round"
38
+ borderColor={colors.primary}
39
+ paddingY={1}
40
+ paddingX={2}
41
+ >
42
+ <Box marginBottom={1}>
43
+ <Text color={colors.primary} bold>
44
+ ✻ Version {packageJson.version}
45
+ </Text>
46
+ </Box>
47
+ <Text color={colors.white}>Tips:</Text>
48
+ <Text color={colors.secondary}>• Use natural language</Text>
49
+ <Text color={colors.secondary}>• /help for commands</Text>
50
+ <Text color={colors.secondary}>• Ctrl+C to quit</Text>
51
+ </Box>
52
+ </>
53
+ ) : (
54
+ /* Normal/Wide terminal: full version with TitledBox */
55
+ <>
56
+ <Gradient colors={[colors.primary, colors.tool]}>
57
+ <BigText text="coder" font="tiny" />
58
+ </Gradient>
59
+ <TitledBox
60
+ title={packageJson.version}
61
+ width={boxWidth}
62
+ borderColor={colors.primary}
63
+ paddingX={2}
64
+ paddingY={1}
65
+ flexDirection="column"
66
+ marginBottom={1}
67
+ >
68
+ <Box>
69
+ <Text color={colors.white}>🎊✨ Happy New Year 2026!🎉 /help for help</Text>
70
+ </Box>
71
+ </TitledBox>
72
+ </>
73
+ )}
74
+ </>
75
+ );
76
+ });
@@ -0,0 +1,65 @@
1
+ import {logError} from '@/utils/message-queue';
2
+
3
+ // Expand environment variable references in a string
4
+ function expandEnvVar(str: string): string {
5
+ if (typeof str !== 'string') {
6
+ return str;
7
+ }
8
+
9
+ const regex = /\$\{([A-Z_][A-Z0-9_]*)(?::-(.*?))?\}|\$([A-Z_][A-Z0-9_]*)/g;
10
+
11
+ return str.replace(
12
+ regex,
13
+ (
14
+ _match: string,
15
+ bracedVarName: string | undefined,
16
+ defaultValue: string | undefined,
17
+ unbracedVarName: string | undefined,
18
+ ) => {
19
+ const varName = bracedVarName || unbracedVarName;
20
+ if (!varName) return '';
21
+
22
+ const envValue = process.env[varName];
23
+
24
+ if (envValue !== undefined) {
25
+ return envValue;
26
+ }
27
+
28
+ if (defaultValue !== undefined) {
29
+ return defaultValue;
30
+ }
31
+
32
+ logError(
33
+ `Environment variable ${varName} not found in config, using empty string`,
34
+ );
35
+
36
+ return '';
37
+ },
38
+ );
39
+ }
40
+
41
+ // Recursively substitute environment variables in objects, arrays, and strings
42
+ export function substituteEnvVars<T>(value: T): T {
43
+ if (value === null || value === undefined) {
44
+ return value;
45
+ }
46
+
47
+ if (typeof value === 'string') {
48
+ return expandEnvVar(value) as T;
49
+ }
50
+
51
+ if (Array.isArray(value)) {
52
+ return value.map((item: unknown) => substituteEnvVars(item)) as T;
53
+ }
54
+
55
+ if (typeof value === 'object') {
56
+ const result: Record<string, unknown> = {};
57
+ for (const [key, val] of Object.entries(value)) {
58
+ result[key] = substituteEnvVars(val);
59
+ }
60
+
61
+ return result as T;
62
+ }
63
+
64
+ return value;
65
+ }
@@ -0,0 +1,171 @@
1
+ import {existsSync, mkdirSync, readFileSync, rmSync, writeFileSync} from 'fs';
2
+ import {tmpdir} from 'os';
3
+ import {join} from 'path';
4
+ import test from 'ava';
5
+ import {confDirMap, getClosestConfigFile, reloadAppConfig} from './index';
6
+
7
+ console.log(`\nindex.spec.ts`);
8
+
9
+ // Create a temporary test directory
10
+ const testDir = join(tmpdir(), `coder-test-${Date.now()}`);
11
+
12
+ test.before(() => {
13
+ // Create test directory
14
+ mkdirSync(testDir, {recursive: true});
15
+ });
16
+
17
+ test.after.always(() => {
18
+ // Clean up test directory
19
+ if (existsSync(testDir)) {
20
+ rmSync(testDir, {recursive: true, force: true});
21
+ }
22
+ });
23
+
24
+ test('getClosestConfigFile creates default config if none exists', t => {
25
+ const fileName = 'test-config.json';
26
+ const configPath = getClosestConfigFile(fileName);
27
+
28
+ t.true(existsSync(configPath), 'Config file should be created');
29
+ t.true(configPath.includes(fileName), 'Config path should include filename');
30
+
31
+ // Clean up
32
+ if (existsSync(configPath)) {
33
+ rmSync(configPath, {force: true});
34
+ }
35
+ });
36
+
37
+ test('getClosestConfigFile prefers cwd config over home config', t => {
38
+ const fileName = 'test-priority.json';
39
+ const cwdConfig = join(process.cwd(), fileName);
40
+
41
+ // Create a config in cwd
42
+ writeFileSync(cwdConfig, JSON.stringify({test: 'cwd'}), 'utf-8');
43
+
44
+ try {
45
+ const configPath = getClosestConfigFile(fileName);
46
+ t.is(configPath, cwdConfig, 'Should prefer cwd config');
47
+ t.is(confDirMap[fileName], cwdConfig, 'Should store cwd path in map');
48
+
49
+ // Verify it returns the cwd config content
50
+ const content = JSON.parse(readFileSync(configPath, 'utf-8'));
51
+ t.deepEqual(content, {test: 'cwd'});
52
+ } finally {
53
+ // Clean up
54
+ if (existsSync(cwdConfig)) {
55
+ rmSync(cwdConfig, {force: true});
56
+ }
57
+ }
58
+ });
59
+
60
+ test('confDirMap stores config file locations', t => {
61
+ const fileName = 'test-map.json';
62
+
63
+ // Clear any existing entry
64
+ delete confDirMap[fileName];
65
+
66
+ const configPath = getClosestConfigFile(fileName);
67
+
68
+ t.true(fileName in confDirMap, 'Config map should have entry');
69
+ t.is(
70
+ confDirMap[fileName],
71
+ configPath,
72
+ 'Config map should store correct path',
73
+ );
74
+
75
+ // Clean up
76
+ if (existsSync(configPath)) {
77
+ rmSync(configPath, {force: true});
78
+ }
79
+ });
80
+
81
+ test('getClosestConfigFile handles missing config directory gracefully', t => {
82
+ const fileName = 'new-config.json';
83
+
84
+ // This should create the config directory and file
85
+ t.notThrows(() => {
86
+ const configPath = getClosestConfigFile(fileName);
87
+ t.true(existsSync(configPath), 'Should create config file');
88
+ });
89
+
90
+ // Clean up
91
+ const configPath = confDirMap[fileName];
92
+ if (configPath && existsSync(configPath)) {
93
+ rmSync(configPath, {force: true});
94
+ }
95
+ });
96
+
97
+ test('reloadAppConfig can be called without errors', t => {
98
+ // This test ensures reloadAppConfig doesn't throw
99
+ t.notThrows(() => {
100
+ reloadAppConfig();
101
+ });
102
+ });
103
+
104
+ test('default config file contains valid JSON', t => {
105
+ const fileName = 'test-default.json';
106
+ const configPath = getClosestConfigFile(fileName);
107
+
108
+ // Read and parse the created config
109
+ const content = readFileSync(configPath, 'utf-8');
110
+
111
+ t.notThrows(() => {
112
+ JSON.parse(content);
113
+ }, 'Default config should be valid JSON');
114
+
115
+ // Clean up
116
+ if (existsSync(configPath)) {
117
+ rmSync(configPath, {force: true});
118
+ }
119
+ });
120
+
121
+ test('promptPath points to main-prompt.md', async t => {
122
+ // Dynamic import to get the promptPath
123
+ const {promptPath} = await import('./index.js');
124
+
125
+ t.true(
126
+ promptPath.includes('main-prompt.md'),
127
+ 'promptPath should point to main-prompt.md',
128
+ );
129
+ t.true(
130
+ promptPath.includes('source/app/prompts'),
131
+ 'promptPath should include source/app/prompts directory',
132
+ );
133
+ });
134
+
135
+ test('loadAppConfig handles malformed JSON gracefully', async t => {
136
+ const fileName = 'malformed-config.json';
137
+ const configPath = getClosestConfigFile(fileName);
138
+
139
+ // Write malformed JSON to the config file
140
+ writeFileSync(configPath, '{ "coder": { "providers": [ }, "mcpServers": [ ] }', 'utf-8');
141
+
142
+ try {
143
+ // This should not throw, but should log a warning
144
+ const {reloadAppConfig} = await import('./index.js');
145
+ reloadAppConfig();
146
+ t.pass('Should handle malformed JSON without throwing');
147
+ } finally {
148
+ // Clean up
149
+ if (existsSync(configPath)) {
150
+ rmSync(configPath, {force: true});
151
+ }
152
+ }
153
+ });
154
+
155
+ test('loadAppConfig handles missing file gracefully', async t => {
156
+ // This test ensures that when the config file is missing,
157
+ // the function falls back to defaults without throwing
158
+ const originalCwd = process.cwd();
159
+
160
+ try {
161
+ // Change to a directory where the config file doesn't exist
162
+ process.chdir(testDir);
163
+
164
+ const {reloadAppConfig} = await import('./index.js');
165
+ reloadAppConfig();
166
+ t.pass('Should handle missing config file without throwing');
167
+ } finally {
168
+ // Restore original directory
169
+ process.chdir(originalCwd);
170
+ }
171
+ });