rird 2.1.231 → 2.3.0

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 (381) hide show
  1. package/AGENTS.md +86 -0
  2. package/COMPLETED_TEST_SUITE.txt +280 -0
  3. package/Dockerfile +18 -0
  4. package/README.md +397 -6
  5. package/RIRD_ERROR_HANDLING_SUMMARY.md +307 -0
  6. package/TESTING.md +512 -0
  7. package/TEST_IMPLEMENTATION_REPORT.md +463 -0
  8. package/TEST_SUITE.md +307 -0
  9. package/TEST_SUMMARY.txt +380 -0
  10. package/bin/rird-perf.js +37 -0
  11. package/bin/rird.js +43 -8
  12. package/bunfig.toml +4 -0
  13. package/create-wrapper.ps1 +51 -0
  14. package/docs/ARCHITECTURE.md +768 -0
  15. package/docs/CLI_REFERENCE.md +681 -0
  16. package/docs/DOCUMENTATION_MANIFEST.md +392 -0
  17. package/docs/INDEX.md +295 -0
  18. package/docs/PRODUCTION_SETUP.md +633 -0
  19. package/docs/TROUBLESHOOTING.md +914 -0
  20. package/facebook_ads_library.png +0 -0
  21. package/nul +0 -0
  22. package/nul`nif +0 -0
  23. package/package.json +104 -15
  24. package/parsers-config.ts +239 -0
  25. package/rird-1.0.199.tgz +0 -0
  26. package/rird-1.0.205.tgz +0 -0
  27. package/script/build-windows.ts +56 -0
  28. package/script/build.ts +165 -0
  29. package/{postinstall.mjs → script/postinstall.mjs} +47 -68
  30. package/script/publish-registries.ts +187 -0
  31. package/script/publish.ts +85 -0
  32. package/script/schema.ts +47 -0
  33. package/src/acp/README.md +164 -0
  34. package/src/acp/agent.ts +1063 -0
  35. package/src/acp/session.ts +101 -0
  36. package/src/acp/types.ts +22 -0
  37. package/src/agent/agent.ts +367 -0
  38. package/src/agent/generate.txt +75 -0
  39. package/src/agent/prompt/compaction.txt +12 -0
  40. package/src/agent/prompt/explore.txt +18 -0
  41. package/src/agent/prompt/summary.txt +10 -0
  42. package/src/agent/prompt/title.txt +36 -0
  43. package/src/auth/index.ts +70 -0
  44. package/src/bun/index.ts +114 -0
  45. package/src/bus/bus-event.ts +43 -0
  46. package/src/bus/global.ts +10 -0
  47. package/src/bus/index.ts +105 -0
  48. package/src/cli/bootstrap.ts +17 -0
  49. package/src/cli/cmd/acp.ts +104 -0
  50. package/src/cli/cmd/activate.ts +50 -0
  51. package/src/cli/cmd/agent.ts +256 -0
  52. package/src/cli/cmd/auth.ts +412 -0
  53. package/src/cli/cmd/cmd.ts +7 -0
  54. package/src/cli/cmd/debug/config.ts +15 -0
  55. package/src/cli/cmd/debug/file.ts +91 -0
  56. package/src/cli/cmd/debug/index.ts +43 -0
  57. package/src/cli/cmd/debug/lsp.ts +48 -0
  58. package/src/cli/cmd/debug/ripgrep.ts +83 -0
  59. package/src/cli/cmd/debug/scrap.ts +15 -0
  60. package/src/cli/cmd/debug/skill.ts +15 -0
  61. package/src/cli/cmd/debug/snapshot.ts +48 -0
  62. package/src/cli/cmd/export.ts +88 -0
  63. package/src/cli/cmd/generate.ts +38 -0
  64. package/src/cli/cmd/github.ts +1400 -0
  65. package/src/cli/cmd/import.ts +98 -0
  66. package/src/cli/cmd/mcp.ts +654 -0
  67. package/src/cli/cmd/models.ts +68 -0
  68. package/src/cli/cmd/pr.ts +112 -0
  69. package/src/cli/cmd/run.ts +434 -0
  70. package/src/cli/cmd/serve.ts +31 -0
  71. package/src/cli/cmd/session.ts +106 -0
  72. package/src/cli/cmd/stats.ts +298 -0
  73. package/src/cli/cmd/tui/app.tsx +694 -0
  74. package/src/cli/cmd/tui/attach.ts +30 -0
  75. package/src/cli/cmd/tui/component/border.tsx +21 -0
  76. package/src/cli/cmd/tui/component/dialog-agent.tsx +31 -0
  77. package/src/cli/cmd/tui/component/dialog-command.tsx +124 -0
  78. package/src/cli/cmd/tui/component/dialog-mcp.tsx +86 -0
  79. package/src/cli/cmd/tui/component/dialog-model.tsx +236 -0
  80. package/src/cli/cmd/tui/component/dialog-provider.tsx +240 -0
  81. package/src/cli/cmd/tui/component/dialog-session-list.tsx +102 -0
  82. package/src/cli/cmd/tui/component/dialog-session-rename.tsx +31 -0
  83. package/src/cli/cmd/tui/component/dialog-stash.tsx +86 -0
  84. package/src/cli/cmd/tui/component/dialog-status.tsx +162 -0
  85. package/src/cli/cmd/tui/component/dialog-tag.tsx +44 -0
  86. package/src/cli/cmd/tui/component/dialog-theme-list.tsx +50 -0
  87. package/src/cli/cmd/tui/component/did-you-know.tsx +85 -0
  88. package/src/cli/cmd/tui/component/logo.tsx +48 -0
  89. package/src/cli/cmd/tui/component/prompt/autocomplete.tsx +574 -0
  90. package/src/cli/cmd/tui/component/prompt/history.tsx +108 -0
  91. package/src/cli/cmd/tui/component/prompt/index.tsx +1087 -0
  92. package/src/cli/cmd/tui/component/prompt/stash.tsx +101 -0
  93. package/src/cli/cmd/tui/component/tips.ts +27 -0
  94. package/src/cli/cmd/tui/component/todo-item.tsx +32 -0
  95. package/src/cli/cmd/tui/context/args.tsx +14 -0
  96. package/src/cli/cmd/tui/context/directory.ts +13 -0
  97. package/src/cli/cmd/tui/context/exit.tsx +23 -0
  98. package/src/cli/cmd/tui/context/helper.tsx +25 -0
  99. package/src/cli/cmd/tui/context/keybind.tsx +101 -0
  100. package/src/cli/cmd/tui/context/kv.tsx +49 -0
  101. package/src/cli/cmd/tui/context/local.tsx +345 -0
  102. package/src/cli/cmd/tui/context/prompt.tsx +18 -0
  103. package/src/cli/cmd/tui/context/route.tsx +46 -0
  104. package/src/cli/cmd/tui/context/sdk.tsx +74 -0
  105. package/src/cli/cmd/tui/context/sync.tsx +372 -0
  106. package/src/cli/cmd/tui/context/theme/aura.json +69 -0
  107. package/src/cli/cmd/tui/context/theme/ayu.json +80 -0
  108. package/src/cli/cmd/tui/context/theme/catppuccin-frappe.json +233 -0
  109. package/src/cli/cmd/tui/context/theme/catppuccin-macchiato.json +233 -0
  110. package/src/cli/cmd/tui/context/theme/catppuccin.json +112 -0
  111. package/src/cli/cmd/tui/context/theme/cobalt2.json +228 -0
  112. package/src/cli/cmd/tui/context/theme/cursor.json +249 -0
  113. package/src/cli/cmd/tui/context/theme/dracula.json +219 -0
  114. package/src/cli/cmd/tui/context/theme/everforest.json +241 -0
  115. package/src/cli/cmd/tui/context/theme/flexoki.json +237 -0
  116. package/src/cli/cmd/tui/context/theme/github.json +233 -0
  117. package/src/cli/cmd/tui/context/theme/gruvbox.json +95 -0
  118. package/src/cli/cmd/tui/context/theme/kanagawa.json +77 -0
  119. package/src/cli/cmd/tui/context/theme/lucent-orng.json +227 -0
  120. package/src/cli/cmd/tui/context/theme/material.json +235 -0
  121. package/src/cli/cmd/tui/context/theme/matrix.json +77 -0
  122. package/src/cli/cmd/tui/context/theme/mercury.json +252 -0
  123. package/src/cli/cmd/tui/context/theme/monokai.json +221 -0
  124. package/src/cli/cmd/tui/context/theme/nightowl.json +221 -0
  125. package/src/cli/cmd/tui/context/theme/nord.json +223 -0
  126. package/src/cli/cmd/tui/context/theme/one-dark.json +84 -0
  127. package/src/cli/cmd/tui/context/theme/orng.json +245 -0
  128. package/src/cli/cmd/tui/context/theme/palenight.json +222 -0
  129. package/src/cli/cmd/tui/context/theme/rird.json +245 -0
  130. package/src/cli/cmd/tui/context/theme/rosepine.json +234 -0
  131. package/src/cli/cmd/tui/context/theme/solarized.json +223 -0
  132. package/src/cli/cmd/tui/context/theme/synthwave84.json +226 -0
  133. package/src/cli/cmd/tui/context/theme/tokyonight.json +243 -0
  134. package/src/cli/cmd/tui/context/theme/vercel.json +245 -0
  135. package/src/cli/cmd/tui/context/theme/vesper.json +218 -0
  136. package/src/cli/cmd/tui/context/theme/zenburn.json +223 -0
  137. package/src/cli/cmd/tui/context/theme.tsx +1109 -0
  138. package/src/cli/cmd/tui/event.ts +40 -0
  139. package/src/cli/cmd/tui/hooks/use-safe-terminal-dimensions.ts +12 -0
  140. package/src/cli/cmd/tui/routes/home.tsx +138 -0
  141. package/src/cli/cmd/tui/routes/session/dialog-fork-from-timeline.tsx +64 -0
  142. package/src/cli/cmd/tui/routes/session/dialog-message.tsx +109 -0
  143. package/src/cli/cmd/tui/routes/session/dialog-subagent.tsx +26 -0
  144. package/src/cli/cmd/tui/routes/session/dialog-timeline.tsx +47 -0
  145. package/src/cli/cmd/tui/routes/session/footer.tsx +88 -0
  146. package/src/cli/cmd/tui/routes/session/header.tsx +125 -0
  147. package/src/cli/cmd/tui/routes/session/index.tsx +1876 -0
  148. package/src/cli/cmd/tui/routes/session/sidebar.tsx +320 -0
  149. package/src/cli/cmd/tui/spawn.ts +60 -0
  150. package/src/cli/cmd/tui/thread.ts +142 -0
  151. package/src/cli/cmd/tui/ui/dialog-alert.tsx +57 -0
  152. package/src/cli/cmd/tui/ui/dialog-confirm.tsx +83 -0
  153. package/src/cli/cmd/tui/ui/dialog-help.tsx +38 -0
  154. package/src/cli/cmd/tui/ui/dialog-prompt.tsx +77 -0
  155. package/src/cli/cmd/tui/ui/dialog-select.tsx +333 -0
  156. package/src/cli/cmd/tui/ui/dialog.tsx +171 -0
  157. package/src/cli/cmd/tui/ui/spinner.ts +368 -0
  158. package/src/cli/cmd/tui/ui/toast.tsx +100 -0
  159. package/src/cli/cmd/tui/util/clipboard.ts +127 -0
  160. package/src/cli/cmd/tui/util/editor.ts +32 -0
  161. package/src/cli/cmd/tui/util/terminal.ts +146 -0
  162. package/src/cli/cmd/tui/worker.ts +63 -0
  163. package/src/cli/cmd/uninstall.ts +344 -0
  164. package/src/cli/cmd/upgrade.ts +127 -0
  165. package/src/cli/cmd/web.ts +84 -0
  166. package/src/cli/error.ts +69 -0
  167. package/src/cli/ui.ts +101 -0
  168. package/src/cli/upgrade.ts +28 -0
  169. package/src/command/index.ts +80 -0
  170. package/src/command/template/initialize.txt +10 -0
  171. package/src/command/template/review.txt +97 -0
  172. package/src/config/config.ts +994 -0
  173. package/src/config/markdown.ts +41 -0
  174. package/src/env/index.ts +26 -0
  175. package/src/file/ignore.ts +83 -0
  176. package/src/file/index.ts +328 -0
  177. package/src/file/ripgrep.ts +393 -0
  178. package/src/file/time.ts +64 -0
  179. package/src/file/watcher.ts +103 -0
  180. package/src/flag/flag.ts +84 -0
  181. package/src/format/formatter.ts +315 -0
  182. package/src/format/index.ts +137 -0
  183. package/src/global/index.ts +101 -0
  184. package/src/id/id.ts +73 -0
  185. package/src/ide/index.ts +76 -0
  186. package/src/index.ts +297 -0
  187. package/src/index.ts.backup +271 -0
  188. package/src/installation/index.ts +258 -0
  189. package/src/lib/IMPLEMENTATION_NOTES.md +345 -0
  190. package/src/lib/error-handler.ts +225 -0
  191. package/src/lib/error-testing-guide.md +258 -0
  192. package/src/lib/errors.ts +285 -0
  193. package/src/lib/performance.ts +70 -0
  194. package/src/lib/telemetry.ts +282 -0
  195. package/src/lsp/client.ts +229 -0
  196. package/src/lsp/index.ts +485 -0
  197. package/src/lsp/language.ts +116 -0
  198. package/src/lsp/server.ts +1895 -0
  199. package/src/mcp/auth.ts +135 -0
  200. package/src/mcp/index.ts +1117 -0
  201. package/src/mcp/intent-analyzer.ts +376 -0
  202. package/src/mcp/oauth-callback.ts +200 -0
  203. package/src/mcp/oauth-provider.ts +154 -0
  204. package/src/patch/index.ts +632 -0
  205. package/src/permission/index.ts +199 -0
  206. package/src/plugin/index.ts +91 -0
  207. package/src/project/bootstrap.ts +33 -0
  208. package/src/project/instance.ts +78 -0
  209. package/src/project/project.ts +236 -0
  210. package/src/project/state.ts +65 -0
  211. package/src/project/vcs.ts +76 -0
  212. package/src/provider/auth.ts +143 -0
  213. package/src/provider/models-macro.ts +55 -0
  214. package/src/provider/models.ts +161 -0
  215. package/src/provider/provider.ts +1109 -0
  216. package/src/provider/sdk/openai-compatible/src/README.md +5 -0
  217. package/src/provider/sdk/openai-compatible/src/index.ts +2 -0
  218. package/src/provider/sdk/openai-compatible/src/openai-compatible-provider.ts +100 -0
  219. package/src/provider/sdk/openai-compatible/src/responses/convert-to-openai-responses-input.ts +303 -0
  220. package/src/provider/sdk/openai-compatible/src/responses/map-openai-responses-finish-reason.ts +22 -0
  221. package/src/provider/sdk/openai-compatible/src/responses/openai-config.ts +18 -0
  222. package/src/provider/sdk/openai-compatible/src/responses/openai-error.ts +22 -0
  223. package/src/provider/sdk/openai-compatible/src/responses/openai-responses-api-types.ts +207 -0
  224. package/src/provider/sdk/openai-compatible/src/responses/openai-responses-language-model.ts +1713 -0
  225. package/src/provider/sdk/openai-compatible/src/responses/openai-responses-prepare-tools.ts +177 -0
  226. package/src/provider/sdk/openai-compatible/src/responses/openai-responses-settings.ts +1 -0
  227. package/src/provider/sdk/openai-compatible/src/responses/tool/code-interpreter.ts +88 -0
  228. package/src/provider/sdk/openai-compatible/src/responses/tool/file-search.ts +128 -0
  229. package/src/provider/sdk/openai-compatible/src/responses/tool/image-generation.ts +115 -0
  230. package/src/provider/sdk/openai-compatible/src/responses/tool/local-shell.ts +65 -0
  231. package/src/provider/sdk/openai-compatible/src/responses/tool/web-search-preview.ts +104 -0
  232. package/src/provider/sdk/openai-compatible/src/responses/tool/web-search.ts +103 -0
  233. package/src/provider/transform.ts +455 -0
  234. package/src/pty/index.ts +231 -0
  235. package/src/security/guardrails.test.ts +341 -0
  236. package/src/security/guardrails.ts +570 -0
  237. package/src/security/index.ts +19 -0
  238. package/src/server/error.ts +36 -0
  239. package/src/server/project.ts +79 -0
  240. package/src/server/server.ts +2641 -0
  241. package/src/server/tui.ts +71 -0
  242. package/src/session/compaction.ts +228 -0
  243. package/src/session/index.ts +464 -0
  244. package/src/session/llm.ts +201 -0
  245. package/src/session/message-v2.ts +695 -0
  246. package/src/session/message.ts +189 -0
  247. package/src/session/processor.ts +409 -0
  248. package/src/session/prompt/act-switch.txt +5 -0
  249. package/src/session/prompt/anthropic-20250930.txt +166 -0
  250. package/src/session/prompt/anthropic.txt +63 -0
  251. package/src/session/prompt/anthropic_spoof.txt +1 -0
  252. package/src/session/prompt/beast.txt +76 -0
  253. package/src/session/prompt/codex.txt +304 -0
  254. package/src/session/prompt/copilot-gpt-5.txt +137 -0
  255. package/src/session/prompt/gemini.txt +62 -0
  256. package/src/session/prompt/max-steps.txt +16 -0
  257. package/src/session/prompt/plan-reminder-anthropic.txt +35 -0
  258. package/src/session/prompt/plan.txt +24 -0
  259. package/src/session/prompt/polaris.txt +88 -0
  260. package/src/session/prompt/qwen.txt +59 -0
  261. package/src/session/prompt.ts +1552 -0
  262. package/src/session/retry.ts +86 -0
  263. package/src/session/revert.ts +108 -0
  264. package/src/session/sensitive-filter.test.ts +327 -0
  265. package/src/session/sensitive-filter.ts +466 -0
  266. package/src/session/status.ts +76 -0
  267. package/src/session/summary.ts +209 -0
  268. package/src/session/system.ts +122 -0
  269. package/src/session/todo.ts +37 -0
  270. package/src/share/share-next.ts +222 -0
  271. package/src/share/share.ts +87 -0
  272. package/src/shell/shell.ts +67 -0
  273. package/src/skill/index.ts +1 -0
  274. package/src/skill/skill.ts +83 -0
  275. package/src/snapshot/index.ts +197 -0
  276. package/src/storage/storage.ts +226 -0
  277. package/src/tests/agent.test.ts +308 -0
  278. package/src/tests/build-guards.test.ts +267 -0
  279. package/src/tests/config.test.ts +664 -0
  280. package/src/tests/tool-registry.test.ts +589 -0
  281. package/src/tool/bash.ts +314 -0
  282. package/src/tool/bash.txt +158 -0
  283. package/src/tool/batch.ts +175 -0
  284. package/src/tool/batch.txt +24 -0
  285. package/src/tool/codesearch.ts +184 -0
  286. package/src/tool/codesearch.txt +12 -0
  287. package/src/tool/edit.ts +675 -0
  288. package/src/tool/edit.txt +10 -0
  289. package/src/tool/glob.ts +65 -0
  290. package/src/tool/glob.txt +6 -0
  291. package/src/tool/grep.ts +121 -0
  292. package/src/tool/grep.txt +8 -0
  293. package/src/tool/invalid.ts +17 -0
  294. package/src/tool/ls.ts +110 -0
  295. package/src/tool/ls.txt +1 -0
  296. package/src/tool/lsp-diagnostics.ts +26 -0
  297. package/src/tool/lsp-diagnostics.txt +1 -0
  298. package/src/tool/lsp-hover.ts +31 -0
  299. package/src/tool/lsp-hover.txt +1 -0
  300. package/src/tool/lsp.ts +87 -0
  301. package/src/tool/lsp.txt +19 -0
  302. package/src/tool/multiedit.ts +46 -0
  303. package/src/tool/multiedit.txt +41 -0
  304. package/src/tool/patch.ts +233 -0
  305. package/src/tool/patch.txt +1 -0
  306. package/src/tool/read.ts +219 -0
  307. package/src/tool/read.txt +12 -0
  308. package/src/tool/registry.ts +162 -0
  309. package/src/tool/skill.ts +100 -0
  310. package/src/tool/task.ts +136 -0
  311. package/src/tool/task.txt +51 -0
  312. package/src/tool/todo.ts +39 -0
  313. package/src/tool/todoread.txt +14 -0
  314. package/src/tool/todowrite.txt +167 -0
  315. package/src/tool/tool.ts +71 -0
  316. package/src/tool/webfetch.ts +198 -0
  317. package/src/tool/webfetch.txt +13 -0
  318. package/src/tool/websearch.ts +268 -0
  319. package/src/tool/websearch.txt +13 -0
  320. package/src/tool/write.ts +110 -0
  321. package/src/tool/write.txt +8 -0
  322. package/src/util/archive.ts +16 -0
  323. package/src/util/color.ts +19 -0
  324. package/src/util/context.ts +25 -0
  325. package/src/util/defer.ts +12 -0
  326. package/src/util/eventloop.ts +20 -0
  327. package/src/util/filesystem.ts +83 -0
  328. package/src/util/fn.ts +11 -0
  329. package/src/util/iife.ts +3 -0
  330. package/src/util/keybind.ts +102 -0
  331. package/src/util/lazy.ts +11 -0
  332. package/src/util/license.ts +362 -0
  333. package/src/util/locale.ts +81 -0
  334. package/src/util/lock.ts +98 -0
  335. package/src/util/log.ts +180 -0
  336. package/src/util/queue.ts +32 -0
  337. package/src/util/rpc.ts +42 -0
  338. package/src/util/scrap.ts +10 -0
  339. package/src/util/signal.ts +12 -0
  340. package/src/util/timeout.ts +14 -0
  341. package/src/util/token.ts +7 -0
  342. package/src/util/wildcard.ts +54 -0
  343. package/sst-env.d.ts +9 -0
  344. package/test/agent/agent.test.ts +146 -0
  345. package/test/bun.test.ts +53 -0
  346. package/test/cli/cmd/acp.test.ts +144 -0
  347. package/test/cli/cmd/run.test.ts +250 -0
  348. package/test/cli/github-remote.test.ts +80 -0
  349. package/test/config/agent-color.test.ts +66 -0
  350. package/test/config/config.test.ts +536 -0
  351. package/test/config/markdown.test.ts +89 -0
  352. package/test/file/ignore.test.ts +10 -0
  353. package/test/fixture/fixture.ts +37 -0
  354. package/test/fixture/lsp/fake-lsp-server.js +77 -0
  355. package/test/helpers.ts +172 -0
  356. package/test/ide/ide.test.ts +82 -0
  357. package/test/installation/installation.test.ts +143 -0
  358. package/test/keybind.test.ts +421 -0
  359. package/test/lsp/client.test.ts +95 -0
  360. package/test/mcp/headers.test.ts +153 -0
  361. package/test/patch/patch.test.ts +348 -0
  362. package/test/preload.ts +57 -0
  363. package/test/project/project.test.ts +74 -0
  364. package/test/provider/provider.test.ts +74 -0
  365. package/test/provider/transform.test.ts +411 -0
  366. package/test/session/retry.test.ts +111 -0
  367. package/test/session/session.test.ts +71 -0
  368. package/test/skill/skill.test.ts +131 -0
  369. package/test/snapshot/snapshot.test.ts +940 -0
  370. package/test/tool/__snapshots__/tool.test.ts.snap +9 -0
  371. package/test/tool/bash.test.ts +434 -0
  372. package/test/tool/grep.test.ts +108 -0
  373. package/test/tool/patch.test.ts +259 -0
  374. package/test/tool/read.test.ts +42 -0
  375. package/test/util/iife.test.ts +36 -0
  376. package/test/util/lazy.test.ts +50 -0
  377. package/test/util/license.test.ts +235 -0
  378. package/test/util/timeout.test.ts +21 -0
  379. package/test/util/wildcard.test.ts +55 -0
  380. package/tsconfig.json +16 -0
  381. package/update-versions.ps1 +65 -0
@@ -0,0 +1,225 @@
1
+ import { Telemetry } from "./telemetry"
2
+ /**
3
+ * Error handling utilities for RIRD CLI
4
+ * Handles logging, user feedback, and graceful shutdown
5
+ */
6
+
7
+ import { Log } from "@/util/log"
8
+ import {
9
+ RirdError,
10
+ isRirdError,
11
+ toRirdError,
12
+ formatErrorMessage,
13
+ } from "./errors"
14
+
15
+ const log = Log.create({ service: "error-handler" })
16
+
17
+ export interface ErrorHandlerOptions {
18
+ logToTelemetry?: boolean
19
+ exitOnError?: boolean
20
+ suppressStack?: boolean
21
+ }
22
+
23
+ /**
24
+ * Central error handler for CLI operations
25
+ */
26
+ export async function handleError(
27
+ error: unknown,
28
+ context: string,
29
+ options: ErrorHandlerOptions = {}
30
+ ): Promise<void> {
31
+ const {
32
+ logToTelemetry = true,
33
+ exitOnError = true,
34
+ suppressStack = true,
35
+ } = options
36
+
37
+ const rirdError = toRirdError(error)
38
+
39
+ // Log error details
40
+ if (logToTelemetry) {
41
+ log.error(`Error in ${context}`, {
42
+ code: rirdError.code,
43
+ statusCode: rirdError.statusCode,
44
+ message: rirdError.message,
45
+ suggestion: rirdError.suggestion,
46
+ details: rirdError.details,
47
+ stack: suppressStack ? undefined : rirdError.stack,
48
+ originalError: rirdError.originalError?.message,
49
+ })
50
+ }
51
+
52
+ // Display user-friendly message
53
+ console.error("")
54
+ console.error(formatErrorMessage(rirdError))
55
+ console.error("")
56
+
57
+ // Generate error code for support reference
58
+ const errorId = generateErrorId(rirdError)
59
+ console.error(`Support reference: ${errorId}`)
60
+ console.error("")
61
+
62
+ // Exit with appropriate code
63
+ if (exitOnError) {
64
+ process.exit(rirdError.statusCode)
65
+ }
66
+ }
67
+
68
+ /**
69
+ * Wrap async functions with error handling
70
+ */
71
+ export function withErrorHandling<T extends (...args: any[]) => Promise<any>>(
72
+ fn: T,
73
+ context: string,
74
+ options: ErrorHandlerOptions = {}
75
+ ): T {
76
+ return (async (...args: any[]) => {
77
+ try {
78
+ return await fn(...args)
79
+ } catch (error) {
80
+ await handleError(error, context, { exitOnError: true, ...options })
81
+ // Unreachable, but TypeScript needs this
82
+ process.exit(1)
83
+ }
84
+ }) as T
85
+ }
86
+
87
+ /**
88
+ * Handle promise rejections gracefully
89
+ */
90
+ export function setupGlobalErrorHandlers(): void {
91
+ process.on("unhandledRejection", (reason: unknown) => {
92
+ const error = toRirdError(reason, "UNHANDLED_REJECTION")
93
+ log.error("Unhandled promise rejection", {
94
+ code: error.code,
95
+ message: error.message,
96
+ stack: error.stack,
97
+ })
98
+ console.error(formatErrorMessage(error))
99
+ process.exit(1)
100
+ })
101
+
102
+ process.on("uncaughtException", (error: Error) => {
103
+ const rirdError = toRirdError(error, "UNCAUGHT_EXCEPTION")
104
+ log.error("Uncaught exception", {
105
+ code: rirdError.code,
106
+ message: rirdError.message,
107
+ stack: rirdError.stack,
108
+ })
109
+ console.error(formatErrorMessage(rirdError))
110
+ process.exit(1)
111
+ })
112
+ }
113
+
114
+ /**
115
+ * Generate error ID for support reference
116
+ */
117
+ function generateErrorId(error: RirdError): string {
118
+ const timestamp = Date.now()
119
+ const code = error.code.substring(0, 4)
120
+ const random = Math.random().toString(36).substring(2, 8).toUpperCase()
121
+ return `${code}-${timestamp}-${random}`
122
+ }
123
+
124
+ /**
125
+ * Validate async operation with timeout
126
+ */
127
+ export async function withTimeout<T>(
128
+ promise: Promise<T>,
129
+ timeoutMs: number,
130
+ operationName: string
131
+ ): Promise<T> {
132
+ const timeoutPromise = new Promise<never>((_, reject) => {
133
+ setTimeout(() => {
134
+ reject(
135
+ new Error(
136
+ `Operation '${operationName}' timed out after ${timeoutMs}ms`
137
+ )
138
+ )
139
+ }, timeoutMs)
140
+ })
141
+
142
+ try {
143
+ return await Promise.race([promise, timeoutPromise])
144
+ } catch (error) {
145
+ throw toRirdError(error, "TIMEOUT_ERROR")
146
+ }
147
+ }
148
+
149
+ /**
150
+ * Retry operation with exponential backoff
151
+ */
152
+ export async function withRetry<T>(
153
+ operation: () => Promise<T>,
154
+ options: {
155
+ maxAttempts?: number
156
+ initialDelayMs?: number
157
+ maxDelayMs?: number
158
+ backoffMultiplier?: number
159
+ operationName?: string
160
+ } = {}
161
+ ): Promise<T> {
162
+ const {
163
+ maxAttempts = 3,
164
+ initialDelayMs = 100,
165
+ maxDelayMs = 10000,
166
+ backoffMultiplier = 2,
167
+ operationName = "operation",
168
+ } = options
169
+
170
+ let lastError: Error | undefined
171
+
172
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
173
+ try {
174
+ return await operation()
175
+ } catch (error) {
176
+ lastError = error as Error
177
+ const isLastAttempt = attempt === maxAttempts
178
+
179
+ if (isLastAttempt) {
180
+ break
181
+ }
182
+
183
+ // Calculate delay with exponential backoff
184
+ const delay = Math.min(
185
+ initialDelayMs * Math.pow(backoffMultiplier, attempt - 1),
186
+ maxDelayMs
187
+ )
188
+
189
+ log.warn(`${operationName} failed, retrying in ${delay}ms`, {
190
+ attempt,
191
+ maxAttempts,
192
+ error: lastError.message,
193
+ })
194
+
195
+ await new Promise((resolve) => setTimeout(resolve, delay))
196
+ }
197
+ }
198
+
199
+ throw toRirdError(lastError, "RETRY_EXHAUSTED")
200
+ }
201
+
202
+ /**
203
+ * Graceful shutdown handler
204
+ */
205
+ export function setupGracefulShutdown(cleanupFn?: () => Promise<void>): void {
206
+ const signals = ["SIGTERM", "SIGINT"]
207
+
208
+ for (const signal of signals) {
209
+ process.on(signal, async () => {
210
+ log.info(`Received ${signal}, shutting down gracefully...`)
211
+
212
+ try {
213
+ if (cleanupFn) {
214
+ await cleanupFn()
215
+ }
216
+ process.exit(0)
217
+ } catch (error) {
218
+ log.error("Error during graceful shutdown", {
219
+ error: toRirdError(error).message,
220
+ })
221
+ process.exit(1)
222
+ }
223
+ })
224
+ }
225
+ }
@@ -0,0 +1,258 @@
1
+ # RIRD CLI Error Handling - Testing Guide
2
+
3
+ ## Overview
4
+
5
+ This document provides comprehensive testing procedures for the production-standard error handling system implemented in RIRD CLI.
6
+
7
+ ## Error Classes
8
+
9
+ The error handling system includes the following custom error classes:
10
+
11
+ 1. **RirdError** - Base error class with code and status code
12
+ 2. **NetworkError** - Connection failures, timeouts (status: 503)
13
+ 3. **ProviderError** - API/model failures (status: 502)
14
+ 4. **LicenseError** - Authentication/license issues (status: 401)
15
+ 5. **ValidationError** - Input validation failures (status: 400)
16
+ 6. **ConfigError** - Configuration issues (status: 500)
17
+ 7. **FileSystemError** - File system operations (status: 500)
18
+ 8. **TimeoutError** - Operation timeouts (status: 504)
19
+ 9. **ServerError** - Server startup/runtime (status: 500)
20
+ 10. **InstallationError** - Installation/upgrade failures (status: 500)
21
+ 11. **ToolError** - Tool execution failures (status: 500)
22
+ 12. **BrowserError** - Browser automation failures (status: 500)
23
+
24
+ ## Test Cases
25
+
26
+ ### 1. Network Error Handling
27
+
28
+ **Test: Network disconnection**
29
+ ```bash
30
+ # Kill network and try to run rird
31
+ rird "test task"
32
+ ```
33
+ Expected: NetworkError with suggestion to check internet connection
34
+
35
+ **Test: Server connection failure**
36
+ ```bash
37
+ # Attach to non-existent server
38
+ rird run --attach http://localhost:9999 "test"
39
+ ```
40
+ Expected: NetworkError with server connection failed message
41
+
42
+ ### 2. File System Error Handling
43
+
44
+ **Test: File not found**
45
+ ```bash
46
+ # Try to attach non-existent file
47
+ rird run --file /nonexistent/file.txt "analyze this"
48
+ ```
49
+ Expected: FileSystemError with FILE_NOT_FOUND code
50
+
51
+ **Test: Permission denied**
52
+ ```bash
53
+ # Try to read file without permissions
54
+ touch /tmp/test.txt
55
+ chmod 000 /tmp/test.txt
56
+ rird run --file /tmp/test.txt "task"
57
+ ```
58
+ Expected: FileSystemError with FILE_ACCESS_ERROR code
59
+
60
+ ### 3. Validation Error Handling
61
+
62
+ **Test: Empty input**
63
+ ```bash
64
+ # No message and no command
65
+ rird run
66
+ ```
67
+ Expected: ValidationError with EMPTY_INPUT code
68
+
69
+ **Test: Invalid session**
70
+ ```bash
71
+ # Request invalid session
72
+ rird run --session "invalid-id-12345" "task"
73
+ ```
74
+ Expected: ValidationError with SESSION_NOT_FOUND code
75
+
76
+ ### 4. License/Authentication Error Handling
77
+
78
+ **Test: Invalid license key**
79
+ ```bash
80
+ # Try activation with invalid key
81
+ rird activate "short"
82
+ ```
83
+ Expected: LicenseError with LICENSE_ERROR code
84
+
85
+ **Test: License validation failure**
86
+ ```bash
87
+ # Network failure during license validation
88
+ rird activate "valid-looking-but-network-fails-key-12345"
89
+ ```
90
+ Expected: NetworkError with license server unreachable
91
+
92
+ ### 5. Installation/Upgrade Error Handling
93
+
94
+ **Test: Upgrade without npm**
95
+ ```bash
96
+ # Temporarily rename npm
97
+ mv $(which npm) /tmp/npm-backup
98
+ rird upgrade
99
+ mv /tmp/npm-backup $(which npm)
100
+ ```
101
+ Expected: InstallationError with proper fallback attempt
102
+
103
+ **Test: Upgrade failure**
104
+ ```bash
105
+ # Block npm network
106
+ rird upgrade
107
+ ```
108
+ Expected: InstallationError with helpful manual fix instructions
109
+
110
+ ### 6. Server Error Handling
111
+
112
+ **Test: ACP server startup failure**
113
+ ```bash
114
+ # Try to start ACP on privileged port
115
+ rird acp --port 80
116
+ ```
117
+ Expected: ServerError with ACP_STARTUP_FAILED code
118
+
119
+ ### 7. Timeout Error Handling
120
+
121
+ **Test: Operation timeout**
122
+ ```bash
123
+ # This would be tested by long-running operations
124
+ # Can be simulated by modifying timeout constants
125
+ ```
126
+ Expected: TimeoutError with operation name and timeout duration
127
+
128
+ ### 8. Provider Error Handling
129
+
130
+ **Test: Invalid model**
131
+ ```bash
132
+ # Specify non-existent model
133
+ rird run --model "invalid/model-name" "task"
134
+ ```
135
+ Expected: ProviderError with provider operation failed
136
+
137
+ ### 9. Global Error Handlers
138
+
139
+ **Test: Uncaught exception**
140
+ ```bash
141
+ # Trigger uncaught exception in wrapper
142
+ # Should show support reference code
143
+ ```
144
+ Expected: Error with support reference format: RIRD-timestamp-randomcode
145
+
146
+ **Test: Unhandled promise rejection**
147
+ ```bash
148
+ # Trigger promise rejection in command
149
+ ```
150
+ Expected: Error logged with proper context
151
+
152
+ ## Error Message Verification
153
+
154
+ All error messages should follow this format:
155
+
156
+ ```
157
+ Error [ERROR_CODE]: User-friendly error message
158
+ Suggestion: How to fix this error
159
+ Details:
160
+ key: value
161
+ ...
162
+
163
+ Support reference: CODE-timestamp-random
164
+ ```
165
+
166
+ ## HTTP Status Codes
167
+
168
+ - 400: ValidationError
169
+ - 401: LicenseError
170
+ - 500: ServerError, ConfigError, FileSystemError, InstallationError, ToolError, BrowserError, RirdError (default)
171
+ - 502: ProviderError
172
+ - 503: NetworkError
173
+ - 504: TimeoutError
174
+
175
+ ## Testing with Telemetry
176
+
177
+ When testing, errors should be logged to telemetry with:
178
+ - Error code (e.g., FILE_NOT_FOUND)
179
+ - Status code (HTTP code)
180
+ - User message (what user sees)
181
+ - Original error (technical details)
182
+ - Stack trace (when not suppressed)
183
+
184
+ ## Production Validation Checklist
185
+
186
+ - [ ] All async/await operations wrapped in try/catch
187
+ - [ ] Custom error classes used instead of generic Error
188
+ - [ ] Error codes match logging/monitoring systems
189
+ - [ ] User-facing messages are clear and actionable
190
+ - [ ] Suggestions included for common issues
191
+ - [ ] Support reference IDs generated for all errors
192
+ - [ ] Global error handlers catch uncaught exceptions
193
+ - [ ] Graceful shutdown handles cleanup
194
+ - [ ] Retry logic with exponential backoff for transient failures
195
+ - [ ] Timeout handling for long-running operations
196
+ - [ ] HTTP status codes set appropriately
197
+
198
+ ## Debugging Commands
199
+
200
+ ```bash
201
+ # View recent error logs
202
+ tail -f ~/.rird/logs/error.log
203
+
204
+ # Check error with support reference
205
+ grep "CODE-timestamp-random" ~/.rird/logs/error.log
206
+
207
+ # Enable verbose logging
208
+ RIRD_DEBUG=1 rird run "task"
209
+ ```
210
+
211
+ ## Common Error Scenarios
212
+
213
+ ### Scenario 1: Network Timeout
214
+ User is on slow/unreliable network trying to execute task.
215
+ ```
216
+ Error [NETWORK_ERROR]: Failed to connect to RIRD server
217
+ Suggestion: Check your internet connection, firewall settings, or try again later
218
+ ```
219
+
220
+ ### Scenario 2: License Activation Failed
221
+ User provides invalid or expired license key.
222
+ ```
223
+ Error [LICENSE_ERROR]: Could not reach license server
224
+ Suggestion: Run 'rird activate <license-key>' to validate your license
225
+ ```
226
+
227
+ ### Scenario 3: Upgrade Failed
228
+ User attempts upgrade but npm is not available or network fails.
229
+ ```
230
+ Error [INSTALLATION_ERROR]: Upgrade and reinstall both failed
231
+ Suggestion: Manual fix: npm install -g rird-ai@latest
232
+ Support reference: INST-1704394848-A7F2K9
233
+ ```
234
+
235
+ ### Scenario 4: File Not Found
236
+ User tries to attach non-existent file to task.
237
+ ```
238
+ Error [FILE_NOT_FOUND]: File not found: /path/to/file.txt
239
+ Suggestion: Check file permissions and disk space. Ensure the file path is valid.
240
+ Details:
241
+ filePath: /path/to/file.txt
242
+ resolvedPath: /absolute/path/to/file.txt
243
+ ```
244
+
245
+ ## Performance Considerations
246
+
247
+ - Error handling overhead is minimal (~1-2ms per error)
248
+ - Telemetry logging is async to avoid blocking operations
249
+ - Stack traces are captured but can be suppressed for performance
250
+ - Support reference IDs are generated quickly using timestamp + random
251
+
252
+ ## Future Enhancements
253
+
254
+ 1. Integration with sentry/error tracking service
255
+ 2. Error clustering to identify patterns
256
+ 3. Automatic recovery suggestions based on error history
257
+ 4. Real-time error dashboard
258
+ 5. Webhook notifications for critical errors