rird 1.0.200

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 (350) hide show
  1. package/AGENTS.md +27 -0
  2. package/Dockerfile +18 -0
  3. package/README.md +15 -0
  4. package/bin/opencode +336 -0
  5. package/bin/pty-wrapper.js +285 -0
  6. package/bunfig.toml +4 -0
  7. package/facebook_ads_library.png +0 -0
  8. package/nul`nif +0 -0
  9. package/package.json +111 -0
  10. package/parsers-config.ts +239 -0
  11. package/rird-1.0.199.tgz +0 -0
  12. package/script/build-windows.ts +54 -0
  13. package/script/build.ts +167 -0
  14. package/script/postinstall.mjs +544 -0
  15. package/script/publish-registries.ts +187 -0
  16. package/script/publish.ts +72 -0
  17. package/script/schema.ts +47 -0
  18. package/src/acp/README.md +164 -0
  19. package/src/acp/agent.ts +1063 -0
  20. package/src/acp/session.ts +101 -0
  21. package/src/acp/types.ts +22 -0
  22. package/src/agent/agent.ts +367 -0
  23. package/src/agent/generate.txt +75 -0
  24. package/src/agent/prompt/compaction.txt +12 -0
  25. package/src/agent/prompt/explore.txt +18 -0
  26. package/src/agent/prompt/summary.txt +10 -0
  27. package/src/agent/prompt/title.txt +36 -0
  28. package/src/auth/index.ts +70 -0
  29. package/src/bun/index.ts +114 -0
  30. package/src/bus/bus-event.ts +43 -0
  31. package/src/bus/global.ts +10 -0
  32. package/src/bus/index.ts +105 -0
  33. package/src/cli/bootstrap.ts +17 -0
  34. package/src/cli/cmd/acp.ts +88 -0
  35. package/src/cli/cmd/agent.ts +256 -0
  36. package/src/cli/cmd/auth.ts +391 -0
  37. package/src/cli/cmd/cmd.ts +7 -0
  38. package/src/cli/cmd/debug/config.ts +15 -0
  39. package/src/cli/cmd/debug/file.ts +91 -0
  40. package/src/cli/cmd/debug/index.ts +43 -0
  41. package/src/cli/cmd/debug/lsp.ts +48 -0
  42. package/src/cli/cmd/debug/ripgrep.ts +83 -0
  43. package/src/cli/cmd/debug/scrap.ts +15 -0
  44. package/src/cli/cmd/debug/skill.ts +15 -0
  45. package/src/cli/cmd/debug/snapshot.ts +48 -0
  46. package/src/cli/cmd/export.ts +88 -0
  47. package/src/cli/cmd/generate.ts +38 -0
  48. package/src/cli/cmd/github.ts +1400 -0
  49. package/src/cli/cmd/import.ts +98 -0
  50. package/src/cli/cmd/mcp.ts +654 -0
  51. package/src/cli/cmd/models.ts +77 -0
  52. package/src/cli/cmd/pr.ts +112 -0
  53. package/src/cli/cmd/run.ts +368 -0
  54. package/src/cli/cmd/serve.ts +31 -0
  55. package/src/cli/cmd/session.ts +106 -0
  56. package/src/cli/cmd/stats.ts +298 -0
  57. package/src/cli/cmd/tui/app.tsx +696 -0
  58. package/src/cli/cmd/tui/attach.ts +30 -0
  59. package/src/cli/cmd/tui/component/border.tsx +21 -0
  60. package/src/cli/cmd/tui/component/dialog-agent.tsx +31 -0
  61. package/src/cli/cmd/tui/component/dialog-command.tsx +124 -0
  62. package/src/cli/cmd/tui/component/dialog-mcp.tsx +86 -0
  63. package/src/cli/cmd/tui/component/dialog-model.tsx +245 -0
  64. package/src/cli/cmd/tui/component/dialog-provider.tsx +224 -0
  65. package/src/cli/cmd/tui/component/dialog-session-list.tsx +102 -0
  66. package/src/cli/cmd/tui/component/dialog-session-rename.tsx +31 -0
  67. package/src/cli/cmd/tui/component/dialog-stash.tsx +86 -0
  68. package/src/cli/cmd/tui/component/dialog-status.tsx +162 -0
  69. package/src/cli/cmd/tui/component/dialog-tag.tsx +44 -0
  70. package/src/cli/cmd/tui/component/dialog-theme-list.tsx +50 -0
  71. package/src/cli/cmd/tui/component/did-you-know.tsx +85 -0
  72. package/src/cli/cmd/tui/component/logo.tsx +35 -0
  73. package/src/cli/cmd/tui/component/prompt/autocomplete.tsx +574 -0
  74. package/src/cli/cmd/tui/component/prompt/history.tsx +108 -0
  75. package/src/cli/cmd/tui/component/prompt/index.tsx +1090 -0
  76. package/src/cli/cmd/tui/component/prompt/stash.tsx +101 -0
  77. package/src/cli/cmd/tui/component/tips.ts +27 -0
  78. package/src/cli/cmd/tui/component/todo-item.tsx +32 -0
  79. package/src/cli/cmd/tui/context/args.tsx +14 -0
  80. package/src/cli/cmd/tui/context/directory.ts +13 -0
  81. package/src/cli/cmd/tui/context/exit.tsx +23 -0
  82. package/src/cli/cmd/tui/context/helper.tsx +25 -0
  83. package/src/cli/cmd/tui/context/keybind.tsx +101 -0
  84. package/src/cli/cmd/tui/context/kv.tsx +49 -0
  85. package/src/cli/cmd/tui/context/local.tsx +354 -0
  86. package/src/cli/cmd/tui/context/prompt.tsx +18 -0
  87. package/src/cli/cmd/tui/context/route.tsx +46 -0
  88. package/src/cli/cmd/tui/context/sdk.tsx +74 -0
  89. package/src/cli/cmd/tui/context/sync.tsx +372 -0
  90. package/src/cli/cmd/tui/context/theme/aura.json +69 -0
  91. package/src/cli/cmd/tui/context/theme/ayu.json +80 -0
  92. package/src/cli/cmd/tui/context/theme/catppuccin-frappe.json +233 -0
  93. package/src/cli/cmd/tui/context/theme/catppuccin-macchiato.json +233 -0
  94. package/src/cli/cmd/tui/context/theme/catppuccin.json +112 -0
  95. package/src/cli/cmd/tui/context/theme/cobalt2.json +228 -0
  96. package/src/cli/cmd/tui/context/theme/cursor.json +249 -0
  97. package/src/cli/cmd/tui/context/theme/dracula.json +219 -0
  98. package/src/cli/cmd/tui/context/theme/everforest.json +241 -0
  99. package/src/cli/cmd/tui/context/theme/flexoki.json +237 -0
  100. package/src/cli/cmd/tui/context/theme/github.json +233 -0
  101. package/src/cli/cmd/tui/context/theme/gruvbox.json +95 -0
  102. package/src/cli/cmd/tui/context/theme/kanagawa.json +77 -0
  103. package/src/cli/cmd/tui/context/theme/lucent-orng.json +227 -0
  104. package/src/cli/cmd/tui/context/theme/material.json +235 -0
  105. package/src/cli/cmd/tui/context/theme/matrix.json +77 -0
  106. package/src/cli/cmd/tui/context/theme/mercury.json +252 -0
  107. package/src/cli/cmd/tui/context/theme/monokai.json +221 -0
  108. package/src/cli/cmd/tui/context/theme/nightowl.json +221 -0
  109. package/src/cli/cmd/tui/context/theme/nord.json +223 -0
  110. package/src/cli/cmd/tui/context/theme/one-dark.json +84 -0
  111. package/src/cli/cmd/tui/context/theme/orng.json +245 -0
  112. package/src/cli/cmd/tui/context/theme/palenight.json +222 -0
  113. package/src/cli/cmd/tui/context/theme/rird.json +245 -0
  114. package/src/cli/cmd/tui/context/theme/rosepine.json +234 -0
  115. package/src/cli/cmd/tui/context/theme/solarized.json +223 -0
  116. package/src/cli/cmd/tui/context/theme/synthwave84.json +226 -0
  117. package/src/cli/cmd/tui/context/theme/tokyonight.json +243 -0
  118. package/src/cli/cmd/tui/context/theme/vercel.json +245 -0
  119. package/src/cli/cmd/tui/context/theme/vesper.json +218 -0
  120. package/src/cli/cmd/tui/context/theme/zenburn.json +223 -0
  121. package/src/cli/cmd/tui/context/theme.tsx +1109 -0
  122. package/src/cli/cmd/tui/event.ts +40 -0
  123. package/src/cli/cmd/tui/routes/home.tsx +138 -0
  124. package/src/cli/cmd/tui/routes/session/dialog-fork-from-timeline.tsx +64 -0
  125. package/src/cli/cmd/tui/routes/session/dialog-message.tsx +109 -0
  126. package/src/cli/cmd/tui/routes/session/dialog-subagent.tsx +26 -0
  127. package/src/cli/cmd/tui/routes/session/dialog-timeline.tsx +47 -0
  128. package/src/cli/cmd/tui/routes/session/footer.tsx +88 -0
  129. package/src/cli/cmd/tui/routes/session/header.tsx +125 -0
  130. package/src/cli/cmd/tui/routes/session/index.tsx +1864 -0
  131. package/src/cli/cmd/tui/routes/session/sidebar.tsx +318 -0
  132. package/src/cli/cmd/tui/spawn.ts +60 -0
  133. package/src/cli/cmd/tui/thread.ts +142 -0
  134. package/src/cli/cmd/tui/ui/dialog-alert.tsx +57 -0
  135. package/src/cli/cmd/tui/ui/dialog-confirm.tsx +83 -0
  136. package/src/cli/cmd/tui/ui/dialog-help.tsx +38 -0
  137. package/src/cli/cmd/tui/ui/dialog-prompt.tsx +77 -0
  138. package/src/cli/cmd/tui/ui/dialog-select.tsx +332 -0
  139. package/src/cli/cmd/tui/ui/dialog.tsx +170 -0
  140. package/src/cli/cmd/tui/ui/spinner.ts +368 -0
  141. package/src/cli/cmd/tui/ui/toast.tsx +100 -0
  142. package/src/cli/cmd/tui/util/clipboard.ts +127 -0
  143. package/src/cli/cmd/tui/util/editor.ts +32 -0
  144. package/src/cli/cmd/tui/util/terminal.ts +114 -0
  145. package/src/cli/cmd/tui/worker.ts +63 -0
  146. package/src/cli/cmd/uninstall.ts +344 -0
  147. package/src/cli/cmd/upgrade.ts +100 -0
  148. package/src/cli/cmd/web.ts +84 -0
  149. package/src/cli/error.ts +56 -0
  150. package/src/cli/ui.ts +84 -0
  151. package/src/cli/upgrade.ts +25 -0
  152. package/src/command/index.ts +80 -0
  153. package/src/command/template/initialize.txt +10 -0
  154. package/src/command/template/review.txt +97 -0
  155. package/src/config/config.ts +995 -0
  156. package/src/config/markdown.ts +41 -0
  157. package/src/env/index.ts +26 -0
  158. package/src/file/ignore.ts +83 -0
  159. package/src/file/index.ts +328 -0
  160. package/src/file/ripgrep.ts +393 -0
  161. package/src/file/time.ts +64 -0
  162. package/src/file/watcher.ts +103 -0
  163. package/src/flag/flag.ts +46 -0
  164. package/src/format/formatter.ts +315 -0
  165. package/src/format/index.ts +137 -0
  166. package/src/global/index.ts +52 -0
  167. package/src/id/id.ts +73 -0
  168. package/src/ide/index.ts +76 -0
  169. package/src/index.ts +240 -0
  170. package/src/installation/index.ts +239 -0
  171. package/src/lsp/client.ts +229 -0
  172. package/src/lsp/index.ts +485 -0
  173. package/src/lsp/language.ts +116 -0
  174. package/src/lsp/server.ts +1895 -0
  175. package/src/mcp/auth.ts +135 -0
  176. package/src/mcp/index.ts +690 -0
  177. package/src/mcp/oauth-callback.ts +200 -0
  178. package/src/mcp/oauth-provider.ts +154 -0
  179. package/src/patch/index.ts +622 -0
  180. package/src/permission/index.ts +199 -0
  181. package/src/plugin/index.ts +91 -0
  182. package/src/project/bootstrap.ts +31 -0
  183. package/src/project/instance.ts +78 -0
  184. package/src/project/project.ts +221 -0
  185. package/src/project/state.ts +65 -0
  186. package/src/project/vcs.ts +76 -0
  187. package/src/provider/auth.ts +143 -0
  188. package/src/provider/models-macro.ts +11 -0
  189. package/src/provider/models.ts +106 -0
  190. package/src/provider/provider.ts +1071 -0
  191. package/src/provider/sdk/openai-compatible/src/README.md +5 -0
  192. package/src/provider/sdk/openai-compatible/src/index.ts +2 -0
  193. package/src/provider/sdk/openai-compatible/src/openai-compatible-provider.ts +100 -0
  194. package/src/provider/sdk/openai-compatible/src/responses/convert-to-openai-responses-input.ts +303 -0
  195. package/src/provider/sdk/openai-compatible/src/responses/map-openai-responses-finish-reason.ts +22 -0
  196. package/src/provider/sdk/openai-compatible/src/responses/openai-config.ts +18 -0
  197. package/src/provider/sdk/openai-compatible/src/responses/openai-error.ts +22 -0
  198. package/src/provider/sdk/openai-compatible/src/responses/openai-responses-api-types.ts +207 -0
  199. package/src/provider/sdk/openai-compatible/src/responses/openai-responses-language-model.ts +1713 -0
  200. package/src/provider/sdk/openai-compatible/src/responses/openai-responses-prepare-tools.ts +177 -0
  201. package/src/provider/sdk/openai-compatible/src/responses/openai-responses-settings.ts +1 -0
  202. package/src/provider/sdk/openai-compatible/src/responses/tool/code-interpreter.ts +88 -0
  203. package/src/provider/sdk/openai-compatible/src/responses/tool/file-search.ts +128 -0
  204. package/src/provider/sdk/openai-compatible/src/responses/tool/image-generation.ts +115 -0
  205. package/src/provider/sdk/openai-compatible/src/responses/tool/local-shell.ts +65 -0
  206. package/src/provider/sdk/openai-compatible/src/responses/tool/web-search-preview.ts +104 -0
  207. package/src/provider/sdk/openai-compatible/src/responses/tool/web-search.ts +103 -0
  208. package/src/provider/transform.ts +455 -0
  209. package/src/pty/index.ts +231 -0
  210. package/src/security/guardrails.test.ts +341 -0
  211. package/src/security/guardrails.ts +558 -0
  212. package/src/security/index.ts +19 -0
  213. package/src/server/error.ts +36 -0
  214. package/src/server/project.ts +79 -0
  215. package/src/server/server.ts +2642 -0
  216. package/src/server/tui.ts +71 -0
  217. package/src/session/compaction.ts +223 -0
  218. package/src/session/index.ts +461 -0
  219. package/src/session/llm.ts +201 -0
  220. package/src/session/message-v2.ts +690 -0
  221. package/src/session/message.ts +189 -0
  222. package/src/session/processor.ts +409 -0
  223. package/src/session/prompt/act-switch.txt +5 -0
  224. package/src/session/prompt/anthropic-20250930.txt +166 -0
  225. package/src/session/prompt/anthropic.txt +85 -0
  226. package/src/session/prompt/anthropic_spoof.txt +1 -0
  227. package/src/session/prompt/beast.txt +103 -0
  228. package/src/session/prompt/codex.txt +304 -0
  229. package/src/session/prompt/copilot-gpt-5.txt +138 -0
  230. package/src/session/prompt/gemini.txt +85 -0
  231. package/src/session/prompt/max-steps.txt +16 -0
  232. package/src/session/prompt/plan-reminder-anthropic.txt +35 -0
  233. package/src/session/prompt/plan.txt +24 -0
  234. package/src/session/prompt/polaris.txt +84 -0
  235. package/src/session/prompt/qwen.txt +106 -0
  236. package/src/session/prompt.ts +1509 -0
  237. package/src/session/retry.ts +86 -0
  238. package/src/session/revert.ts +108 -0
  239. package/src/session/sensitive-filter.test.ts +327 -0
  240. package/src/session/sensitive-filter.ts +466 -0
  241. package/src/session/status.ts +76 -0
  242. package/src/session/summary.ts +194 -0
  243. package/src/session/system.ts +120 -0
  244. package/src/session/todo.ts +37 -0
  245. package/src/share/share-next.ts +194 -0
  246. package/src/share/share.ts +87 -0
  247. package/src/shell/shell.ts +67 -0
  248. package/src/skill/index.ts +1 -0
  249. package/src/skill/skill.ts +83 -0
  250. package/src/snapshot/index.ts +197 -0
  251. package/src/storage/storage.ts +226 -0
  252. package/src/tests/agent.test.ts +308 -0
  253. package/src/tests/build-guards.test.ts +267 -0
  254. package/src/tests/config.test.ts +664 -0
  255. package/src/tests/tool-registry.test.ts +589 -0
  256. package/src/tool/bash.ts +317 -0
  257. package/src/tool/bash.txt +158 -0
  258. package/src/tool/batch.ts +175 -0
  259. package/src/tool/batch.txt +24 -0
  260. package/src/tool/codesearch.ts +168 -0
  261. package/src/tool/codesearch.txt +12 -0
  262. package/src/tool/edit.ts +675 -0
  263. package/src/tool/edit.txt +10 -0
  264. package/src/tool/glob.ts +65 -0
  265. package/src/tool/glob.txt +6 -0
  266. package/src/tool/grep.ts +121 -0
  267. package/src/tool/grep.txt +8 -0
  268. package/src/tool/invalid.ts +17 -0
  269. package/src/tool/ls.ts +110 -0
  270. package/src/tool/ls.txt +1 -0
  271. package/src/tool/lsp-diagnostics.ts +26 -0
  272. package/src/tool/lsp-diagnostics.txt +1 -0
  273. package/src/tool/lsp-hover.ts +31 -0
  274. package/src/tool/lsp-hover.txt +1 -0
  275. package/src/tool/lsp.ts +87 -0
  276. package/src/tool/lsp.txt +19 -0
  277. package/src/tool/multiedit.ts +46 -0
  278. package/src/tool/multiedit.txt +41 -0
  279. package/src/tool/patch.ts +233 -0
  280. package/src/tool/patch.txt +1 -0
  281. package/src/tool/read.ts +219 -0
  282. package/src/tool/read.txt +12 -0
  283. package/src/tool/registry.ts +162 -0
  284. package/src/tool/skill.ts +100 -0
  285. package/src/tool/task.ts +136 -0
  286. package/src/tool/task.txt +51 -0
  287. package/src/tool/todo.ts +39 -0
  288. package/src/tool/todoread.txt +14 -0
  289. package/src/tool/todowrite.txt +167 -0
  290. package/src/tool/tool.ts +71 -0
  291. package/src/tool/webfetch.ts +198 -0
  292. package/src/tool/webfetch.txt +13 -0
  293. package/src/tool/websearch.ts +180 -0
  294. package/src/tool/websearch.txt +11 -0
  295. package/src/tool/write.ts +110 -0
  296. package/src/tool/write.txt +8 -0
  297. package/src/util/archive.ts +16 -0
  298. package/src/util/color.ts +19 -0
  299. package/src/util/context.ts +25 -0
  300. package/src/util/defer.ts +12 -0
  301. package/src/util/eventloop.ts +20 -0
  302. package/src/util/filesystem.ts +83 -0
  303. package/src/util/fn.ts +11 -0
  304. package/src/util/iife.ts +3 -0
  305. package/src/util/keybind.ts +102 -0
  306. package/src/util/lazy.ts +11 -0
  307. package/src/util/license.ts +325 -0
  308. package/src/util/locale.ts +81 -0
  309. package/src/util/lock.ts +98 -0
  310. package/src/util/log.ts +180 -0
  311. package/src/util/queue.ts +32 -0
  312. package/src/util/rpc.ts +42 -0
  313. package/src/util/scrap.ts +10 -0
  314. package/src/util/signal.ts +12 -0
  315. package/src/util/timeout.ts +14 -0
  316. package/src/util/token.ts +7 -0
  317. package/src/util/wildcard.ts +54 -0
  318. package/sst-env.d.ts +9 -0
  319. package/test/agent/agent.test.ts +146 -0
  320. package/test/bun.test.ts +53 -0
  321. package/test/cli/github-remote.test.ts +80 -0
  322. package/test/config/agent-color.test.ts +66 -0
  323. package/test/config/config.test.ts +535 -0
  324. package/test/config/markdown.test.ts +89 -0
  325. package/test/file/ignore.test.ts +10 -0
  326. package/test/fixture/fixture.ts +36 -0
  327. package/test/fixture/lsp/fake-lsp-server.js +77 -0
  328. package/test/ide/ide.test.ts +82 -0
  329. package/test/keybind.test.ts +421 -0
  330. package/test/lsp/client.test.ts +95 -0
  331. package/test/mcp/headers.test.ts +153 -0
  332. package/test/patch/patch.test.ts +348 -0
  333. package/test/preload.ts +57 -0
  334. package/test/project/project.test.ts +72 -0
  335. package/test/provider/provider.test.ts +1809 -0
  336. package/test/provider/transform.test.ts +411 -0
  337. package/test/session/retry.test.ts +111 -0
  338. package/test/session/session.test.ts +71 -0
  339. package/test/skill/skill.test.ts +131 -0
  340. package/test/snapshot/snapshot.test.ts +939 -0
  341. package/test/tool/__snapshots__/tool.test.ts.snap +9 -0
  342. package/test/tool/bash.test.ts +434 -0
  343. package/test/tool/grep.test.ts +108 -0
  344. package/test/tool/patch.test.ts +259 -0
  345. package/test/tool/read.test.ts +42 -0
  346. package/test/util/iife.test.ts +36 -0
  347. package/test/util/lazy.test.ts +50 -0
  348. package/test/util/timeout.test.ts +21 -0
  349. package/test/util/wildcard.test.ts +55 -0
  350. package/tsconfig.json +16 -0
@@ -0,0 +1,544 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * RIRD AI Browser Agent - Cross-platform Postinstall
4
+ * Mirrors the install.sh setup for Windows/Mac/Linux
5
+ */
6
+
7
+ import fs from "fs"
8
+ import path from "path"
9
+ import os from "os"
10
+ import { fileURLToPath } from "url"
11
+ import { createRequire } from "module"
12
+ import { execSync, spawnSync } from "child_process"
13
+
14
+ const __dirname = path.dirname(fileURLToPath(import.meta.url))
15
+ const require = createRequire(import.meta.url)
16
+
17
+ // RIRD paths
18
+ const RIRD_HOME = process.env.RIRD_HOME || path.join(os.homedir(), ".rird")
19
+ const BIN_DIR = path.join(RIRD_HOME, "bin")
20
+ const ENGINE_DIR = path.join(RIRD_HOME, "engine")
21
+ const VENV_DIR = path.join(RIRD_HOME, "venv")
22
+ const MCP_DIR = path.join(ENGINE_DIR, "stealth-browser-mcp")
23
+
24
+ // Installation mode: A = Browser + Files, B = Full Computer Use
25
+ const INSTALL_MODE = process.env.RIRD_MODE || "A"
26
+
27
+ const isWindows = os.platform() === "win32"
28
+ const isMac = os.platform() === "darwin"
29
+ const isLinux = os.platform() === "linux"
30
+
31
+ function log(msg) {
32
+ console.log(`[RIRD] ${msg}`)
33
+ }
34
+
35
+ function execSafe(cmd, options = {}) {
36
+ try {
37
+ return execSync(cmd, { stdio: "pipe", timeout: 120000, ...options })
38
+ } catch (e) {
39
+ return null
40
+ }
41
+ }
42
+
43
+ function detectPlatformAndArch() {
44
+ let platform
45
+ switch (os.platform()) {
46
+ case "darwin": platform = "darwin"; break
47
+ case "linux": platform = "linux"; break
48
+ case "win32": platform = "windows"; break
49
+ default: platform = os.platform(); break
50
+ }
51
+
52
+ let arch
53
+ switch (os.arch()) {
54
+ case "x64": arch = "x64"; break
55
+ case "arm64": arch = "arm64"; break
56
+ case "arm": arch = "arm"; break
57
+ default: arch = os.arch(); break
58
+ }
59
+
60
+ return { platform, arch }
61
+ }
62
+
63
+ // Check for Python
64
+ function checkPython() {
65
+ const cmds = isWindows ? ["python", "python3", "py"] : ["python3", "python"]
66
+ for (const cmd of cmds) {
67
+ const result = execSafe(`${cmd} --version`)
68
+ if (result) {
69
+ log(`Found Python: ${result.toString().trim()}`)
70
+ return cmd
71
+ }
72
+ }
73
+ log("Python not found - install from https://python.org")
74
+ return null
75
+ }
76
+
77
+ // Check for pip
78
+ function checkPip(pythonCmd) {
79
+ const cmds = isWindows ? ["pip", "pip3"] : ["pip3", "pip"]
80
+ for (const cmd of cmds) {
81
+ if (execSafe(`${cmd} --version`)) return cmd
82
+ }
83
+ // Try python -m pip
84
+ if (execSafe(`${pythonCmd} -m pip --version`)) return `${pythonCmd} -m pip`
85
+ return null
86
+ }
87
+
88
+ // Install Python dependencies
89
+ function installPythonDeps(pipCmd) {
90
+ log("Installing Python dependencies...")
91
+ const deps = [
92
+ "httpx", "loguru", "Pillow", "nodriver", "fastmcp",
93
+ "patchright", "beautifulsoup4", "lxml", "pydantic",
94
+ "psutil", "python-dotenv", "aiohttp", "requests"
95
+ ]
96
+ execSafe(`${pipCmd} install --user ${deps.join(" ")}`, { stdio: "inherit" })
97
+ }
98
+
99
+ // Clone stealth-browser-mcp
100
+ function cloneStealthBrowserMcp() {
101
+ if (fs.existsSync(MCP_DIR)) {
102
+ log("stealth-browser-mcp already installed")
103
+ return true
104
+ }
105
+
106
+ log("Cloning stealth-browser-mcp...")
107
+
108
+ // Try git clone
109
+ if (execSafe("git --version")) {
110
+ const result = execSafe(`git clone --depth 1 https://github.com/vibheksoni/stealth-browser-mcp "${MCP_DIR}"`, { stdio: "inherit" })
111
+ if (result !== null || fs.existsSync(MCP_DIR)) {
112
+ log("stealth-browser-mcp cloned successfully")
113
+ return true
114
+ }
115
+ }
116
+
117
+ // Fallback: download zip
118
+ log("Git not available, trying zip download...")
119
+ // Create placeholder for now
120
+ fs.mkdirSync(path.join(MCP_DIR, "src"), { recursive: true })
121
+ fs.writeFileSync(path.join(MCP_DIR, "src", "server.py"), `#!/usr/bin/env python3
122
+ # Placeholder - run: git clone https://github.com/vibheksoni/stealth-browser-mcp ~/.rird/engine/stealth-browser-mcp
123
+ print("stealth-browser-mcp not installed. Clone manually.")
124
+ `)
125
+ return false
126
+ }
127
+
128
+ // Create license validator
129
+ function createLicenseValidator() {
130
+ const validatorPath = path.join(ENGINE_DIR, "license_validator.py")
131
+ if (fs.existsSync(validatorPath)) return
132
+
133
+ log("Creating license validator...")
134
+ const content = `#!/usr/bin/env python3
135
+ """RIRD License Validator"""
136
+ import os, json, hashlib, platform
137
+ from pathlib import Path
138
+ from datetime import datetime, timedelta
139
+ import urllib.request, urllib.error
140
+
141
+ LICENSE_CACHE_PATH = Path.home() / ".rird" / "license_cache.json"
142
+ RIRD_API_URL = "https://rird.ai/api/desktop/validate-license"
143
+
144
+ def get_device_fingerprint():
145
+ parts = [platform.node(), platform.system(), platform.machine(),
146
+ os.getenv("USER", os.getenv("USERNAME", "unknown"))]
147
+ return hashlib.sha256("|".join(parts).encode()).hexdigest()[:32]
148
+
149
+ def load_license_cache():
150
+ try:
151
+ if LICENSE_CACHE_PATH.exists():
152
+ data = json.loads(LICENSE_CACHE_PATH.read_text())
153
+ cached_at = datetime.fromisoformat(data.get("cached_at", "2000-01-01"))
154
+ if datetime.now() - cached_at < timedelta(hours=24):
155
+ return data
156
+ except: pass
157
+ return None
158
+
159
+ def save_license_cache(data):
160
+ try:
161
+ LICENSE_CACHE_PATH.parent.mkdir(parents=True, exist_ok=True)
162
+ data["cached_at"] = datetime.now().isoformat()
163
+ LICENSE_CACHE_PATH.write_text(json.dumps(data))
164
+ except: pass
165
+
166
+ def get_license_key():
167
+ key = os.getenv("RIRD_LICENSE_KEY")
168
+ if key: return key.strip()
169
+ config_path = Path.home() / ".rird" / "license.key"
170
+ if config_path.exists():
171
+ try: return config_path.read_text().strip()
172
+ except: pass
173
+ return None
174
+
175
+ def save_license_key(key):
176
+ config_path = Path.home() / ".rird" / "license.key"
177
+ config_path.parent.mkdir(parents=True, exist_ok=True)
178
+ config_path.write_text(key)
179
+
180
+ def validate_license_online(key):
181
+ try:
182
+ payload = json.dumps({
183
+ "license_key": key,
184
+ "device_fingerprint": get_device_fingerprint(),
185
+ "version": "1.0.0",
186
+ "platform": platform.system(),
187
+ }).encode()
188
+ req = urllib.request.Request(RIRD_API_URL, data=payload,
189
+ headers={"Content-Type": "application/json"}, method="POST")
190
+ with urllib.request.urlopen(req, timeout=10) as resp:
191
+ data = json.loads(resp.read().decode())
192
+ if data.get("valid"):
193
+ return True, "License valid", data.get("user")
194
+ return False, data.get("error", "Invalid license"), None
195
+ except urllib.error.HTTPError as e:
196
+ if e.code == 401: return False, "Invalid license key", None
197
+ if e.code == 403: return False, "Subscription inactive", None
198
+ return True, "Server unavailable - using cached", None
199
+ except:
200
+ return True, "Offline - using cached", None
201
+
202
+ def validate_license_sync():
203
+ key = get_license_key()
204
+ if not key:
205
+ return False, "No license key. Run: rird activate YOUR_KEY"
206
+ cached = load_license_cache()
207
+ if cached and cached.get("license_key") == key and cached.get("valid"):
208
+ return True, f"License valid (cached) - {cached.get('email', 'unknown')}"
209
+ valid, msg, user = validate_license_online(key)
210
+ if valid and user:
211
+ save_license_cache({"license_key": key, "valid": True,
212
+ "email": user.get("email"), "plan": user.get("plan")})
213
+ return True, f"License valid - {user.get('email', 'unknown')}"
214
+ return valid, msg
215
+
216
+ def activate_license(key):
217
+ valid, msg, user = validate_license_online(key)
218
+ if valid and user:
219
+ save_license_key(key)
220
+ save_license_cache({"license_key": key, "valid": True,
221
+ "email": user.get("email"), "plan": user.get("plan")})
222
+ return True, f"License activated for {user.get('email')}"
223
+ return False, msg
224
+
225
+ if __name__ == "__main__":
226
+ import sys
227
+ if len(sys.argv) < 2:
228
+ print("Usage: license_validator.py <activate|status|validate> [key]")
229
+ sys.exit(1)
230
+ cmd = sys.argv[1]
231
+ if cmd == "activate":
232
+ if len(sys.argv) < 3:
233
+ print("Usage: license_validator.py activate KEY")
234
+ sys.exit(1)
235
+ ok, msg = activate_license(sys.argv[2])
236
+ print(msg)
237
+ sys.exit(0 if ok else 1)
238
+ elif cmd == "status":
239
+ ok, msg = validate_license_sync()
240
+ print(msg)
241
+ sys.exit(0 if ok else 1)
242
+ elif cmd == "validate":
243
+ ok, msg = validate_license_sync()
244
+ print(msg)
245
+ sys.exit(0 if ok else 1)
246
+ `
247
+ fs.writeFileSync(validatorPath, content)
248
+ }
249
+
250
+ // Create rird.json config
251
+ function createConfig(pythonCmd) {
252
+ const configPath = path.join(ENGINE_DIR, "rird.json")
253
+
254
+ log(`Creating config (Mode ${INSTALL_MODE})...`)
255
+
256
+ const mcpConfig = {
257
+ "stealth-browser": {
258
+ type: "local",
259
+ command: [pythonCmd, path.join(MCP_DIR, "src", "server.py"), "--minimal"],
260
+ environment: {
261
+ FASTMCP_DISABLE_BANNER: "1",
262
+ PYTHONPATH: path.join(MCP_DIR, "src"),
263
+ RIRD_PROXIES: "${ROYAL_PROXY}"
264
+ },
265
+ timeout: 30000
266
+ }
267
+ }
268
+
269
+ // Mode B: Add computer-use MCP
270
+ if (INSTALL_MODE === "B") {
271
+ if (isWindows) {
272
+ mcpConfig["computer-use"] = {
273
+ type: "local",
274
+ command: ["uvx", "windows-mcp"],
275
+ environment: {},
276
+ timeout: 30000,
277
+ enabled: true
278
+ }
279
+ } else if (isMac) {
280
+ mcpConfig["computer-use"] = {
281
+ type: "local",
282
+ command: ["bun", "run", path.join(RIRD_HOME, "mcp", "automation-mcp", "index.ts"), "--stdio"],
283
+ environment: {},
284
+ timeout: 30000,
285
+ enabled: true
286
+ }
287
+ } else if (isLinux) {
288
+ mcpConfig["computer-use"] = {
289
+ type: "local",
290
+ command: ["npx", "-y", "mcp-desktop-automation"],
291
+ environment: { DISPLAY: process.env.DISPLAY || ":0" },
292
+ timeout: 30000,
293
+ enabled: true
294
+ }
295
+ }
296
+ }
297
+
298
+ const instructions = INSTALL_MODE === "B"
299
+ ? [
300
+ "=== RIRD AI - rird.ai ===",
301
+ "I am your AI assistant that can browse the web and automate tasks.",
302
+ "",
303
+ "=== WHAT I CAN DO ===",
304
+ "- Browse websites and interact with web pages",
305
+ "- Fill out forms and click buttons",
306
+ "- Extract data from websites",
307
+ "- Read and write files on your computer",
308
+ "- Control your mouse and keyboard",
309
+ "- Launch and interact with desktop applications",
310
+ "- Take screenshots and analyze what's on screen",
311
+ "",
312
+ "=== HOW I WORK ===",
313
+ "1. WEB SEARCH:",
314
+ " - Finding URLs, quick facts, lists of companies or profiles",
315
+ " - Fast lookups that don't require visiting a page",
316
+ "",
317
+ "2. BROWSER AUTOMATION:",
318
+ " - Navigating to websites and interacting with them",
319
+ " - Logging into accounts and filling forms",
320
+ " - Extracting content from web pages",
321
+ "",
322
+ "3. COMPUTER CONTROL:",
323
+ " - Desktop applications and system tasks",
324
+ " - Mouse and keyboard automation",
325
+ " - File and folder operations"
326
+ ]
327
+ : [
328
+ "=== RIRD AI - rird.ai ===",
329
+ "I am your AI assistant that can browse the web and automate tasks.",
330
+ "",
331
+ "=== WHAT I CAN DO ===",
332
+ "- Browse websites and interact with web pages",
333
+ "- Fill out forms and click buttons",
334
+ "- Extract data from websites",
335
+ "- Read and write files on your computer",
336
+ "",
337
+ "=== HOW I WORK ===",
338
+ "1. WEB SEARCH:",
339
+ " - Finding URLs, quick facts, lists of companies or profiles",
340
+ " - Fast lookups that don't require visiting a page",
341
+ "",
342
+ "2. BROWSER AUTOMATION:",
343
+ " - Navigating to websites and interacting with them",
344
+ " - Logging into accounts and filling forms",
345
+ " - Extracting content from web pages"
346
+ ]
347
+
348
+ const config = {
349
+ model: "deepseek/deepseek-reasoner",
350
+ small_model: "siliconflow/Qwen/Qwen3-8B",
351
+ visionModel: "siliconflow/Qwen/Qwen2.5-VL-7B-Instruct",
352
+ agent: {
353
+ plan: { model: "deepseek/deepseek-reasoner" },
354
+ build: { model: "deepseek/deepseek-reasoner" }
355
+ },
356
+ provider: {
357
+ deepseek: {
358
+ models: {
359
+ "deepseek-reasoner": {
360
+ id: "deepseek-reasoner",
361
+ name: "DeepSeek Reasoner",
362
+ release_date: "2024-12-26",
363
+ attachment: true,
364
+ reasoning: true,
365
+ temperature: true,
366
+ tool_call: true,
367
+ limit: { context: 64000, output: 8000 },
368
+ options: {}
369
+ }
370
+ },
371
+ options: { apiKey: "" }
372
+ },
373
+ siliconflow: {
374
+ models: {
375
+ "Qwen/Qwen3-8B": {
376
+ id: "Qwen/Qwen3-8B",
377
+ name: "Qwen 3 8B",
378
+ release_date: "2024-12-26",
379
+ attachment: true,
380
+ reasoning: false,
381
+ temperature: true,
382
+ tool_call: true,
383
+ limit: { context: 32000, output: 4000 },
384
+ options: {}
385
+ },
386
+ "Qwen/Qwen2.5-VL-7B-Instruct": {
387
+ id: "Qwen/Qwen2.5-VL-7B-Instruct",
388
+ name: "Qwen 2.5 VL 7B",
389
+ release_date: "2024-12-26",
390
+ attachment: true,
391
+ reasoning: false,
392
+ temperature: true,
393
+ tool_call: true,
394
+ limit: { context: 32000, output: 4000 },
395
+ modalities: { input: ["text", "image"], output: ["text"] },
396
+ options: {}
397
+ }
398
+ },
399
+ options: { apiKey: "", baseUrl: "https://api.siliconflow.com/v1" }
400
+ }
401
+ },
402
+ instructions,
403
+ mcp: mcpConfig,
404
+ permission: {
405
+ edit: "allow",
406
+ bash: "allow",
407
+ skill: "allow",
408
+ webfetch: "allow",
409
+ external_directory: "allow"
410
+ },
411
+ autoupdate: false,
412
+ $schema: "https://rird.ai/config.json"
413
+ }
414
+
415
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2))
416
+ log(`Config saved to ${configPath}`)
417
+ }
418
+
419
+ // Install computer-use MCP (Mode B)
420
+ function installComputerUseMcp() {
421
+ if (INSTALL_MODE !== "B") return
422
+
423
+ log("Installing computer-use MCP...")
424
+
425
+ if (isWindows) {
426
+ log("Windows: computer-use via uvx windows-mcp")
427
+ execSafe("pip install uv", { stdio: "inherit" })
428
+ } else if (isMac) {
429
+ log("macOS: Requires automation-mcp + Accessibility permissions")
430
+ const mcpPath = path.join(RIRD_HOME, "mcp", "automation-mcp")
431
+ if (!fs.existsSync(mcpPath)) {
432
+ fs.mkdirSync(path.join(RIRD_HOME, "mcp"), { recursive: true })
433
+ execSafe(`git clone --depth 1 https://github.com/ashwwwin/automation-mcp "${mcpPath}"`, { stdio: "inherit" })
434
+ if (fs.existsSync(mcpPath)) {
435
+ execSafe("bun install", { cwd: mcpPath, stdio: "inherit" })
436
+ }
437
+ }
438
+ } else if (isLinux) {
439
+ log("Linux: computer-use via npx mcp-desktop-automation")
440
+ // Pre-cache the package
441
+ execSafe("npx -y mcp-desktop-automation --version", { stdio: "pipe" })
442
+ // Install xdotool as fallback
443
+ execSafe("sudo apt install -y xdotool 2>/dev/null || true", { stdio: "pipe" })
444
+ }
445
+ }
446
+
447
+ // Find and symlink binary (non-Windows)
448
+ function findBinary() {
449
+ const { platform, arch } = detectPlatformAndArch()
450
+ const packageName = `rird-${platform}-${arch}`
451
+ const binaryName = platform === "windows" ? "opencode.exe" : "opencode"
452
+
453
+ try {
454
+ const packageJsonPath = require.resolve(`${packageName}/package.json`)
455
+ const packageDir = path.dirname(packageJsonPath)
456
+ const binaryPath = path.join(packageDir, "bin", binaryName)
457
+
458
+ if (!fs.existsSync(binaryPath)) {
459
+ throw new Error(`Binary not found at ${binaryPath}`)
460
+ }
461
+ return { binaryPath, binaryName }
462
+ } catch (error) {
463
+ throw new Error(`Could not find package ${packageName}: ${error.message}`)
464
+ }
465
+ }
466
+
467
+ function symlinkBinary(sourcePath, binaryName) {
468
+ const binDir = path.join(__dirname, "..", "bin")
469
+ const targetPath = path.join(binDir, binaryName)
470
+
471
+ if (!fs.existsSync(binDir)) {
472
+ fs.mkdirSync(binDir, { recursive: true })
473
+ }
474
+
475
+ if (fs.existsSync(targetPath)) {
476
+ fs.unlinkSync(targetPath)
477
+ }
478
+
479
+ fs.symlinkSync(sourcePath, targetPath)
480
+ log(`Binary symlinked: ${targetPath} -> ${sourcePath}`)
481
+ }
482
+
483
+ // Main
484
+ async function main() {
485
+ log("Setting up RIRD AI...")
486
+ log(`Mode: ${INSTALL_MODE === "B" ? "Full Computer Use" : "Browser + Files"}`)
487
+ log(`Platform: ${os.platform()}-${os.arch()}`)
488
+
489
+ // Create directories
490
+ fs.mkdirSync(BIN_DIR, { recursive: true })
491
+ fs.mkdirSync(ENGINE_DIR, { recursive: true })
492
+
493
+ // Check Python
494
+ const pythonCmd = checkPython()
495
+ if (!pythonCmd) {
496
+ log("Warning: Python not found. Some features may not work.")
497
+ } else {
498
+ const pipCmd = checkPip(pythonCmd)
499
+ if (pipCmd) {
500
+ installPythonDeps(pipCmd)
501
+ }
502
+ }
503
+
504
+ // Clone stealth-browser-mcp
505
+ cloneStealthBrowserMcp()
506
+
507
+ // Create license validator
508
+ createLicenseValidator()
509
+
510
+ // Create config
511
+ createConfig(pythonCmd || "python3")
512
+
513
+ // Install computer-use MCP (Mode B)
514
+ installComputerUseMcp()
515
+
516
+ // Setup binary symlink (non-Windows)
517
+ if (!isWindows) {
518
+ try {
519
+ const { binaryPath, binaryName } = findBinary()
520
+ symlinkBinary(binaryPath, binaryName)
521
+ } catch (e) {
522
+ log(`Binary setup: ${e.message}`)
523
+ }
524
+ }
525
+
526
+ log("")
527
+ log("Setup complete!")
528
+ log("")
529
+ log("Next steps:")
530
+ log(" 1. Get license at: rird.ai")
531
+ log(" 2. Activate: rird activate YOUR_LICENSE_KEY")
532
+ log(" 3. Run a task: rird \"go to google and search for AI\"")
533
+ log("")
534
+ if (INSTALL_MODE === "B") {
535
+ log("Full computer use mode enabled!")
536
+ }
537
+ }
538
+
539
+ try {
540
+ main()
541
+ } catch (error) {
542
+ console.error("[RIRD] Setup error:", error.message)
543
+ process.exit(0) // Don't fail npm install
544
+ }