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
package/src/index.ts ADDED
@@ -0,0 +1,297 @@
1
+ import yargs from "yargs"
2
+ import { hideBin } from "yargs/helpers"
3
+ import { RunCommand } from "./cli/cmd/run"
4
+ import { GenerateCommand } from "./cli/cmd/generate"
5
+ import { Log } from "./util/log"
6
+ import { AuthCommand } from "./cli/cmd/auth"
7
+ import { AgentCommand } from "./cli/cmd/agent"
8
+ import { UpgradeCommand } from "./cli/cmd/upgrade"
9
+ import { UninstallCommand } from "./cli/cmd/uninstall"
10
+ import { ModelsCommand } from "./cli/cmd/models"
11
+ import { UI } from "./cli/ui"
12
+ import { Installation } from "./installation"
13
+ import { NamedError } from "@opencode-ai/util/error"
14
+ import { FormatError, type ErrorTypes } from "./cli/error"
15
+ import { ServeCommand } from "./cli/cmd/serve"
16
+ import { DebugCommand } from "./cli/cmd/debug"
17
+ import { StatsCommand } from "./cli/cmd/stats"
18
+ import { McpCommand } from "./cli/cmd/mcp"
19
+ import { GithubCommand } from "./cli/cmd/github"
20
+ import { ExportCommand } from "./cli/cmd/export"
21
+ import { ImportCommand } from "./cli/cmd/import"
22
+ import { AttachCommand } from "./cli/cmd/tui/attach"
23
+ import { TuiThreadCommand } from "./cli/cmd/tui/thread"
24
+ import { TuiSpawnCommand } from "./cli/cmd/tui/spawn"
25
+ import { AcpCommand } from "./cli/cmd/acp"
26
+ import { EOL } from "os"
27
+ import { WebCommand } from "./cli/cmd/web"
28
+ import { PrCommand } from "./cli/cmd/pr"
29
+ import { SessionCommand } from "./cli/cmd/session"
30
+ import { validateLicense } from "./util/license"
31
+ import { ActivateCommand } from "./cli/cmd/activate"
32
+ import { MCP } from "./mcp"
33
+ import { Telemetry } from "./lib/telemetry"
34
+
35
+ // Auto-update: Check and upgrade on every run
36
+ async function autoUpdate(): Promise<boolean> {
37
+ // Skip auto-update for certain commands
38
+ const args = process.argv.slice(2)
39
+ const skipCommands = ["upgrade", "uninstall", "--version", "-v", "--help", "-h"]
40
+ if (args.some(arg => skipCommands.includes(arg))) {
41
+ return false
42
+ }
43
+
44
+ // Skip if running in local/dev mode
45
+ if (Installation.isLocal()) {
46
+ return false
47
+ }
48
+
49
+ try {
50
+ // Timeout the version check after 3 seconds to not slow down startup
51
+ const latestPromise = Installation.latest()
52
+ const timeoutPromise = new Promise<string>((_, reject) =>
53
+ setTimeout(() => reject(new Error("timeout")), 3000)
54
+ )
55
+ const latest = await Promise.race([latestPromise, timeoutPromise])
56
+ const current = Installation.VERSION
57
+
58
+ function isNewer(current: string, latest: string): boolean {
59
+ const c = current.split(".").map((n) => parseInt(n, 10))
60
+ const l = latest.split(".").map((n) => parseInt(n, 10))
61
+
62
+ // Simple semver check (major.minor.patch)
63
+ for (let i = 0; i < 3; i++) {
64
+ const cv = isNaN(c[i]) ? 0 : c[i]
65
+ const lv = isNaN(l[i]) ? 0 : l[i]
66
+ if (lv > cv) return true
67
+ if (lv < cv) return false
68
+ }
69
+ return false
70
+ }
71
+
72
+ // Skip if already on latest or newer
73
+ if (!isNewer(current, latest)) {
74
+ return false
75
+ }
76
+
77
+ // Detect installation method
78
+ const method = await Installation.method()
79
+ if (method === "unknown") {
80
+ // Cannot auto-update unknown installations
81
+ return false
82
+ }
83
+
84
+ // Perform silent upgrade
85
+ console.log(`[RIRD] Updating ${current} -> ${latest}...`)
86
+ await Installation.upgrade(method, latest)
87
+ console.log(`[RIRD] Updated to ${latest}. Restarting...`)
88
+
89
+ // Re-exec with same arguments
90
+ const { spawn } = await import("child_process")
91
+ const child = spawn(process.execPath, process.argv.slice(1), {
92
+ stdio: "inherit",
93
+ env: { ...process.env, RIRD_SKIP_AUTO_UPDATE: "1" }
94
+ })
95
+ child.on("exit", (code) => process.exit(code ?? 0))
96
+ return true // Signal that we're restarting
97
+ } catch (err) {
98
+ // Silent failure - don't block user from running their command
99
+ // Note: Log not initialized yet, so we just silently fail
100
+ if (process.env.DEBUG) {
101
+ console.error("[RIRD] Auto-update check failed:", err instanceof Error ? err.message : err)
102
+ }
103
+ return false
104
+ }
105
+ }
106
+
107
+ process.on("SIGINT", () => {
108
+ // Reset terminal formatting and exit
109
+ process.stdout.write("\x1b[0m\x1b[?25h\x1b[?1049l")
110
+ process.exit(130)
111
+ })
112
+
113
+ process.on("unhandledRejection", async (e) => {
114
+ Log.Default.error("rejection", {
115
+ e: e instanceof Error ? e.message : e,
116
+ })
117
+ await Telemetry.logError("Unhandled rejection", e)
118
+ })
119
+
120
+ process.on("uncaughtException", async (e) => {
121
+ Log.Default.error("exception", {
122
+ e: e instanceof Error ? e.message : e,
123
+ })
124
+ await Telemetry.logError("Uncaught exception", e)
125
+ })
126
+
127
+ // Run auto-update before anything else (unless already restarted)
128
+ if (!process.env.RIRD_SKIP_AUTO_UPDATE && !process.env.OPENCODE_SKIP_AUTO_UPDATE) {
129
+ const shouldRestart = await autoUpdate()
130
+ if (shouldRestart) {
131
+ // Wait for child process - don't proceed with this instance
132
+ await new Promise(() => {})
133
+ }
134
+ }
135
+
136
+ const cli = yargs(hideBin(process.argv))
137
+ .parserConfiguration({ "populate--": true })
138
+ .scriptName("rird")
139
+ .wrap(100)
140
+ .help("help", "show help")
141
+ .alias("help", "h")
142
+ .version("version", "show version number", Installation.VERSION)
143
+ .alias("version", "v")
144
+ .option("print-logs", {
145
+ describe: "print logs to stderr",
146
+ type: "boolean",
147
+ })
148
+ .option("print-telemetry", {
149
+ describe: "display error/event telemetry logs",
150
+ type: "string",
151
+ choices: ["errors", "warnings", "events", "metrics"],
152
+ })
153
+ .option("log-level", {
154
+ describe: "log level",
155
+ type: "string",
156
+ choices: ["DEBUG", "INFO", "WARN", "ERROR"],
157
+ })
158
+ .middleware(async (opts) => {
159
+ // Initialize telemetry first
160
+ await Telemetry.initialize()
161
+
162
+ // Handle telemetry printing if requested
163
+ if (opts.printTelemetry) {
164
+ const type = opts.printTelemetry as "errors" | "warnings" | "events" | "metrics"
165
+ await Telemetry.printLogs(type, 7)
166
+ process.exit(0)
167
+ }
168
+
169
+ await Log.init({
170
+ print: process.argv.includes("--print-logs"),
171
+ dev: Installation.isLocal(),
172
+ level: (() => {
173
+ if (opts.logLevel) return opts.logLevel as Log.Level
174
+ if (Installation.isLocal()) return "DEBUG"
175
+ return "INFO"
176
+ })(),
177
+ })
178
+
179
+ process.env.AGENT = "1"
180
+ process.env.RIRD = "1"
181
+ process.env.OPENCODE = "1" // Maintain legacy support
182
+
183
+ Log.Default.info("rird", {
184
+ version: Installation.VERSION,
185
+ args: process.argv.slice(2),
186
+ })
187
+
188
+ // Track startup event
189
+ await Telemetry.trackEvent("cli:startup", {
190
+ version: Installation.VERSION,
191
+ node_version: process.version,
192
+ platform: process.platform,
193
+ })
194
+
195
+ // License validation - skip only for commands that must work without a license
196
+ const args = process.argv.slice(2)
197
+ const skipLicenseCommands = ["auth", "activate", "upgrade", "uninstall", "--version", "-v", "--help", "-h"]
198
+ const shouldSkipLicense = args.some(arg => skipLicenseCommands.includes(arg))
199
+
200
+ if (!shouldSkipLicense) {
201
+ const license = await validateLicense()
202
+ if (!license.valid) {
203
+ UI.error(license.message)
204
+ await Telemetry.logWarning("License validation failed", { message: license.message })
205
+ process.exit(1)
206
+ }
207
+ }
208
+ })
209
+ .usage("\n" + UI.logo())
210
+ .command(AcpCommand)
211
+ .command(McpCommand)
212
+ .command(TuiThreadCommand)
213
+ .command(TuiSpawnCommand)
214
+ .command(AttachCommand)
215
+ .command(RunCommand)
216
+ .command(GenerateCommand)
217
+ .command(DebugCommand)
218
+ .command(AuthCommand)
219
+ .command(AgentCommand)
220
+ .command(UpgradeCommand)
221
+ .command(UninstallCommand)
222
+ .command(ServeCommand)
223
+ .command(WebCommand)
224
+ .command(ModelsCommand)
225
+ .command(StatsCommand)
226
+ .command(ExportCommand)
227
+ .command(ImportCommand)
228
+ .command(GithubCommand)
229
+ .command(PrCommand)
230
+ .command(SessionCommand)
231
+ .command(ActivateCommand)
232
+ .fail((msg) => {
233
+ if (
234
+ msg.startsWith("Unknown argument") ||
235
+ msg.startsWith("Not enough non-option arguments") ||
236
+ msg.startsWith("Invalid values:")
237
+ ) {
238
+ cli.showHelp("log")
239
+ }
240
+ process.exit(1)
241
+ })
242
+ .strict()
243
+
244
+ // Run interactive mode if no arguments provided
245
+ const args = process.argv.slice(2)
246
+ if (args.length === 0) {
247
+ // Default to interactive TUI mode
248
+ process.argv.push("run")
249
+ }
250
+
251
+ try {
252
+ await cli.parse()
253
+ } catch (e) {
254
+ let data: Record<string, any> = {}
255
+ if (e instanceof NamedError) {
256
+ const obj = e.toObject()
257
+ Object.assign(data, {
258
+ ...obj.data,
259
+ })
260
+ }
261
+
262
+ if (e instanceof Error) {
263
+ Object.assign(data, {
264
+ name: e.name,
265
+ message: e.message,
266
+ cause: e.cause?.toString(),
267
+ stack: e.stack,
268
+ })
269
+ }
270
+
271
+ if (e instanceof ResolveMessage) {
272
+ Object.assign(data, {
273
+ name: e.name,
274
+ message: e.message,
275
+ code: e.code,
276
+ specifier: e.specifier,
277
+ referrer: e.referrer,
278
+ position: e.position,
279
+ importKind: e.importKind,
280
+ })
281
+ }
282
+ Log.Default.error("fatal", data)
283
+ await Telemetry.logError("Fatal error", e, data)
284
+ const formatted = FormatError(e as ErrorTypes)
285
+ if (formatted) UI.error(formatted)
286
+ if (formatted === undefined) {
287
+ UI.error("Unexpected error, check log file at " + Log.file() + " for more details" + EOL)
288
+ console.error(e)
289
+ }
290
+ process.exitCode = 1
291
+ } finally {
292
+ // Some subprocesses don't react properly to SIGTERM and similar signals.
293
+ // Most notably, some docker-container-based MCP servers don't handle such signals unless
294
+ // run using `docker run --init`.
295
+ // Explicitly exit to avoid any hanging subprocesses.
296
+ process.exit()
297
+ }
@@ -0,0 +1,271 @@
1
+ import yargs from "yargs"
2
+ import { hideBin } from "yargs/helpers"
3
+ import { RunCommand } from "./cli/cmd/run"
4
+ import { GenerateCommand } from "./cli/cmd/generate"
5
+ import { Log } from "./util/log"
6
+ import { AuthCommand } from "./cli/cmd/auth"
7
+ import { AgentCommand } from "./cli/cmd/agent"
8
+ import { UpgradeCommand } from "./cli/cmd/upgrade"
9
+ import { UninstallCommand } from "./cli/cmd/uninstall"
10
+ import { ModelsCommand } from "./cli/cmd/models"
11
+ import { UI } from "./cli/ui"
12
+ import { Installation } from "./installation"
13
+ import { NamedError } from "@opencode-ai/util/error"
14
+ import { FormatError, type ErrorTypes } from "./cli/error"
15
+ import { ServeCommand } from "./cli/cmd/serve"
16
+ import { DebugCommand } from "./cli/cmd/debug"
17
+ import { StatsCommand } from "./cli/cmd/stats"
18
+ import { McpCommand } from "./cli/cmd/mcp"
19
+ import { GithubCommand } from "./cli/cmd/github"
20
+ import { ExportCommand } from "./cli/cmd/export"
21
+ import { ImportCommand } from "./cli/cmd/import"
22
+ import { AttachCommand } from "./cli/cmd/tui/attach"
23
+ import { TuiThreadCommand } from "./cli/cmd/tui/thread"
24
+ import { TuiSpawnCommand } from "./cli/cmd/tui/spawn"
25
+ import { AcpCommand } from "./cli/cmd/acp"
26
+ import { EOL } from "os"
27
+ import { WebCommand } from "./cli/cmd/web"
28
+ import { PrCommand } from "./cli/cmd/pr"
29
+ import { SessionCommand } from "./cli/cmd/session"
30
+ import { validateLicense } from "./util/license"
31
+ import { ActivateCommand } from "./cli/cmd/activate"
32
+ import { MCP } from "./mcp"
33
+ import { Telemetry } from "./lib/telemetry"
34
+
35
+ // Auto-update: Check and upgrade on every run
36
+ async function autoUpdate(): Promise<boolean> {
37
+ // Skip auto-update for certain commands
38
+ const args = process.argv.slice(2)
39
+ const skipCommands = ["upgrade", "uninstall", "--version", "-v", "--help", "-h"]
40
+ if (args.some(arg => skipCommands.includes(arg))) {
41
+ return false
42
+ }
43
+
44
+ // Skip if running in local/dev mode
45
+ if (Installation.isLocal()) {
46
+ return false
47
+ }
48
+
49
+ try {
50
+ // Timeout the version check after 3 seconds to not slow down startup
51
+ const latestPromise = Installation.latest()
52
+ const timeoutPromise = new Promise<string>((_, reject) =>
53
+ setTimeout(() => reject(new Error("timeout")), 3000)
54
+ )
55
+ const latest = await Promise.race([latestPromise, timeoutPromise])
56
+ const current = Installation.VERSION
57
+
58
+ function isNewer(current: string, latest: string): boolean {
59
+ const c = current.split(".").map((n) => parseInt(n, 10))
60
+ const l = latest.split(".").map((n) => parseInt(n, 10))
61
+
62
+ // Simple semver check (major.minor.patch)
63
+ for (let i = 0; i < 3; i++) {
64
+ const cv = isNaN(c[i]) ? 0 : c[i]
65
+ const lv = isNaN(l[i]) ? 0 : l[i]
66
+ if (lv > cv) return true
67
+ if (lv < cv) return false
68
+ }
69
+ return false
70
+ }
71
+
72
+ // Skip if already on latest or newer
73
+ if (!isNewer(current, latest)) {
74
+ return false
75
+ }
76
+
77
+ // Detect installation method
78
+ const method = await Installation.method()
79
+ if (method === "unknown") {
80
+ // Cannot auto-update unknown installations
81
+ return false
82
+ }
83
+
84
+ // Perform silent upgrade
85
+ console.log(`[RIRD] Updating ${current} -> ${latest}...`)
86
+ await Installation.upgrade(method, latest)
87
+ console.log(`[RIRD] Updated to ${latest}. Restarting...`)
88
+
89
+ // Re-exec with same arguments
90
+ const { spawn } = await import("child_process")
91
+ const child = spawn(process.execPath, process.argv.slice(1), {
92
+ stdio: "inherit",
93
+ env: { ...process.env, RIRD_SKIP_AUTO_UPDATE: "1" }
94
+ })
95
+ child.on("exit", (code) => process.exit(code ?? 0))
96
+ return true // Signal that we're restarting
97
+ } catch (err) {
98
+ // Silent failure - don't block user from running their command
99
+ // Note: Log not initialized yet, so we just silently fail
100
+ if (process.env.DEBUG) {
101
+ console.error("[RIRD] Auto-update check failed:", err instanceof Error ? err.message : err)
102
+ }
103
+ return false
104
+ }
105
+ }
106
+
107
+ process.on("SIGINT", () => {
108
+ // Reset terminal formatting and exit
109
+ process.stdout.write("\x1b[0m\x1b[?25h\x1b[?1049l")
110
+ process.exit(130)
111
+ })
112
+
113
+ process.on("unhandledRejection", (e) => {
114
+ Log.Default.error("rejection", {
115
+ e: e instanceof Error ? e.message : e,
116
+ })
117
+ })
118
+
119
+ process.on("uncaughtException", (e) => {
120
+ Log.Default.error("exception", {
121
+ e: e instanceof Error ? e.message : e,
122
+ })
123
+ })
124
+
125
+ // Run auto-update before anything else (unless already restarted)
126
+ if (!process.env.RIRD_SKIP_AUTO_UPDATE && !process.env.OPENCODE_SKIP_AUTO_UPDATE) {
127
+ const shouldRestart = await autoUpdate()
128
+ if (shouldRestart) {
129
+ // Wait for child process - don't proceed with this instance
130
+ await new Promise(() => {})
131
+ }
132
+ }
133
+
134
+ const cli = yargs(hideBin(process.argv))
135
+ .parserConfiguration({ "populate--": true })
136
+ .scriptName("rird")
137
+ .wrap(100)
138
+ .help("help", "show help")
139
+ .alias("help", "h")
140
+ .version("version", "show version number", Installation.VERSION)
141
+ .alias("version", "v")
142
+ .option("print-logs", {
143
+ describe: "print logs to stderr",
144
+ type: "boolean",
145
+ })
146
+ .option("log-level", {
147
+ describe: "log level",
148
+ type: "string",
149
+ choices: ["DEBUG", "INFO", "WARN", "ERROR"],
150
+ })
151
+ .middleware(async (opts) => {
152
+ await Log.init({
153
+ print: process.argv.includes("--print-logs"),
154
+ dev: Installation.isLocal(),
155
+ level: (() => {
156
+ if (opts.logLevel) return opts.logLevel as Log.Level
157
+ if (Installation.isLocal()) return "DEBUG"
158
+ return "INFO"
159
+ })(),
160
+ })
161
+
162
+ process.env.AGENT = "1"
163
+ process.env.RIRD = "1"
164
+ process.env.OPENCODE = "1" // Maintain legacy support
165
+
166
+ Log.Default.info("rird", {
167
+ version: Installation.VERSION,
168
+ args: process.argv.slice(2),
169
+ })
170
+
171
+ // License validation - skip only for commands that must work without a license
172
+ const args = process.argv.slice(2)
173
+ const skipLicenseCommands = ["auth", "activate", "upgrade", "uninstall", "--version", "-v", "--help", "-h"]
174
+ const shouldSkipLicense = args.some(arg => skipLicenseCommands.includes(arg))
175
+
176
+ if (!shouldSkipLicense) {
177
+ const license = await validateLicense()
178
+ if (!license.valid) {
179
+ UI.error(license.message)
180
+ process.exit(1)
181
+ }
182
+ }
183
+ })
184
+ .usage("\n" + UI.logo())
185
+ .command(AcpCommand)
186
+ .command(McpCommand)
187
+ .command(TuiThreadCommand)
188
+ .command(TuiSpawnCommand)
189
+ .command(AttachCommand)
190
+ .command(RunCommand)
191
+ .command(GenerateCommand)
192
+ .command(DebugCommand)
193
+ .command(AuthCommand)
194
+ .command(AgentCommand)
195
+ .command(UpgradeCommand)
196
+ .command(UninstallCommand)
197
+ .command(ServeCommand)
198
+ .command(WebCommand)
199
+ .command(ModelsCommand)
200
+ .command(StatsCommand)
201
+ .command(ExportCommand)
202
+ .command(ImportCommand)
203
+ .command(GithubCommand)
204
+ .command(PrCommand)
205
+ .command(SessionCommand)
206
+ .command(ActivateCommand)
207
+ .fail((msg) => {
208
+ if (
209
+ msg.startsWith("Unknown argument") ||
210
+ msg.startsWith("Not enough non-option arguments") ||
211
+ msg.startsWith("Invalid values:")
212
+ ) {
213
+ cli.showHelp("log")
214
+ }
215
+ process.exit(1)
216
+ })
217
+ .strict()
218
+
219
+ // Run interactive mode if no arguments provided
220
+ const args = process.argv.slice(2)
221
+ if (args.length === 0) {
222
+ // Default to interactive TUI mode
223
+ process.argv.push("run")
224
+ }
225
+
226
+ try {
227
+ await cli.parse()
228
+ } catch (e) {
229
+ let data: Record<string, any> = {}
230
+ if (e instanceof NamedError) {
231
+ const obj = e.toObject()
232
+ Object.assign(data, {
233
+ ...obj.data,
234
+ })
235
+ }
236
+
237
+ if (e instanceof Error) {
238
+ Object.assign(data, {
239
+ name: e.name,
240
+ message: e.message,
241
+ cause: e.cause?.toString(),
242
+ stack: e.stack,
243
+ })
244
+ }
245
+
246
+ if (e instanceof ResolveMessage) {
247
+ Object.assign(data, {
248
+ name: e.name,
249
+ message: e.message,
250
+ code: e.code,
251
+ specifier: e.specifier,
252
+ referrer: e.referrer,
253
+ position: e.position,
254
+ importKind: e.importKind,
255
+ })
256
+ }
257
+ Log.Default.error("fatal", data)
258
+ const formatted = FormatError(e as ErrorTypes)
259
+ if (formatted) UI.error(formatted)
260
+ if (formatted === undefined) {
261
+ UI.error("Unexpected error, check log file at " + Log.file() + " for more details" + EOL)
262
+ console.error(e)
263
+ }
264
+ process.exitCode = 1
265
+ } finally {
266
+ // Some subprocesses don't react properly to SIGTERM and similar signals.
267
+ // Most notably, some docker-container-based MCP servers don't handle such signals unless
268
+ // run using `docker run --init`.
269
+ // Explicitly exit to avoid any hanging subprocesses.
270
+ process.exit()
271
+ }