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,101 @@
1
+ import path from "path"
2
+ import { Global } from "@/global"
3
+ import { onMount } from "solid-js"
4
+ import { createStore, produce } from "solid-js/store"
5
+ import { clone } from "remeda"
6
+ import { createSimpleContext } from "../../context/helper"
7
+ import { appendFile, writeFile } from "fs/promises"
8
+ import type { PromptInfo } from "./history"
9
+
10
+ export type StashEntry = {
11
+ input: string
12
+ parts: PromptInfo["parts"]
13
+ timestamp: number
14
+ }
15
+
16
+ const MAX_STASH_ENTRIES = 50
17
+
18
+ export const { use: usePromptStash, provider: PromptStashProvider } = createSimpleContext({
19
+ name: "PromptStash",
20
+ init: () => {
21
+ const stashFile = Bun.file(path.join(Global.Path.state, "prompt-stash.jsonl"))
22
+ onMount(async () => {
23
+ const text = await stashFile.text().catch(() => "")
24
+ const lines = text
25
+ .split("\n")
26
+ .filter(Boolean)
27
+ .map((line) => {
28
+ try {
29
+ return JSON.parse(line)
30
+ } catch {
31
+ return null
32
+ }
33
+ })
34
+ .filter((line): line is StashEntry => line !== null)
35
+ .slice(-MAX_STASH_ENTRIES)
36
+
37
+ setStore("entries", lines)
38
+
39
+ // Rewrite file with only valid entries to self-heal corruption
40
+ if (lines.length > 0) {
41
+ const content = lines.map((line) => JSON.stringify(line)).join("\n") + "\n"
42
+ writeFile(stashFile.name!, content).catch(() => {})
43
+ }
44
+ })
45
+
46
+ const [store, setStore] = createStore({
47
+ entries: [] as StashEntry[],
48
+ })
49
+
50
+ return {
51
+ list() {
52
+ return store.entries
53
+ },
54
+ push(entry: Omit<StashEntry, "timestamp">) {
55
+ const stash = clone({ ...entry, timestamp: Date.now() })
56
+ let trimmed = false
57
+ setStore(
58
+ produce((draft) => {
59
+ draft.entries.push(stash)
60
+ if (draft.entries.length > MAX_STASH_ENTRIES) {
61
+ draft.entries = draft.entries.slice(-MAX_STASH_ENTRIES)
62
+ trimmed = true
63
+ }
64
+ }),
65
+ )
66
+
67
+ if (trimmed) {
68
+ const content = store.entries.map((line) => JSON.stringify(line)).join("\n") + "\n"
69
+ writeFile(stashFile.name!, content).catch(() => {})
70
+ return
71
+ }
72
+
73
+ appendFile(stashFile.name!, JSON.stringify(stash) + "\n").catch(() => {})
74
+ },
75
+ pop() {
76
+ if (store.entries.length === 0) return undefined
77
+ const entry = store.entries[store.entries.length - 1]
78
+ setStore(
79
+ produce((draft) => {
80
+ draft.entries.pop()
81
+ }),
82
+ )
83
+ const content =
84
+ store.entries.length > 0 ? store.entries.map((line) => JSON.stringify(line)).join("\n") + "\n" : ""
85
+ writeFile(stashFile.name!, content).catch(() => {})
86
+ return entry
87
+ },
88
+ remove(index: number) {
89
+ if (index < 0 || index >= store.entries.length) return
90
+ setStore(
91
+ produce((draft) => {
92
+ draft.entries.splice(index, 1)
93
+ }),
94
+ )
95
+ const content =
96
+ store.entries.length > 0 ? store.entries.map((line) => JSON.stringify(line)).join("\n") + "\n" : ""
97
+ writeFile(stashFile.name!, content).catch(() => {})
98
+ },
99
+ }
100
+ },
101
+ })
@@ -0,0 +1,27 @@
1
+ export const TIPS = [
2
+ "Just type what you want the browser to do - RIRD understands natural language.",
3
+ "Example: {highlight}Go to amazon.com and search for headphones under $50{/highlight}",
4
+ "Example: {highlight}Log into my LinkedIn account and send a message to John Smith{/highlight}",
5
+ "Example: {highlight}Fill out the contact form on example.com with my info{/highlight}",
6
+ "Press {highlight}Escape{/highlight} to stop the agent mid-task.",
7
+ "Press {highlight}Ctrl+C{/highlight} when typing to clear the input field.",
8
+ "Press {highlight}Shift+Enter{/highlight} or {highlight}Ctrl+J{/highlight} to add newlines in your prompt.",
9
+ "Use {highlight}/new{/highlight} or {highlight}Ctrl+X N{/highlight} to start a fresh session.",
10
+ "Use {highlight}/sessions{/highlight} to see and continue previous browser sessions.",
11
+ "Press {highlight}PageUp{/highlight}/{highlight}PageDown{/highlight} to scroll through the conversation.",
12
+ "RIRD handles CAPTCHAs, popups, and cookie banners automatically.",
13
+ "RIRD uses high-integrity browsing protocols to ensure reliable access to public information.",
14
+ "You can mention passwords or logins - sensitive data never leaves your device.",
15
+ "Run {highlight}rird status{/highlight} to check your license and account info.",
16
+ "Run {highlight}rird activate <key>{/highlight} to activate your license.",
17
+ "Use {highlight}--headful{/highlight} flag to see the browser window while it works.",
18
+ "Example: {highlight}Take a screenshot of the Google homepage{/highlight}",
19
+ "Example: {highlight}Extract all product prices from this page{/highlight}",
20
+ "Example: {highlight}Click the Submit button after filling the form{/highlight}",
21
+ "RIRD automatically waits for pages to load before taking actions.",
22
+ "If a site blocks you, RIRD will try different approaches automatically.",
23
+ "Use {highlight}/help{/highlight} to see available commands.",
24
+ "Press {highlight}Ctrl+P{/highlight} to see all available actions.",
25
+ "Run {highlight}rird run \"your task\"{/highlight} for non-interactive scripting.",
26
+ "Use {highlight}--format json{/highlight} for machine-readable output in scripts.",
27
+ ]
@@ -0,0 +1,32 @@
1
+ import { useTheme } from "../context/theme"
2
+
3
+ export interface TodoItemProps {
4
+ status: string
5
+ content: string
6
+ }
7
+
8
+ export function TodoItem(props: TodoItemProps) {
9
+ const { theme } = useTheme()
10
+
11
+ return (
12
+ <box flexDirection="row" gap={0}>
13
+ <text
14
+ flexShrink={0}
15
+ style={{
16
+ fg: props.status === "in_progress" ? theme.warning : theme.textMuted,
17
+ }}
18
+ >
19
+ [{props.status === "completed" ? "✓" : props.status === "in_progress" ? "•" : " "}]{" "}
20
+ </text>
21
+ <text
22
+ flexGrow={1}
23
+ wrapMode="word"
24
+ style={{
25
+ fg: props.status === "in_progress" ? theme.warning : theme.textMuted,
26
+ }}
27
+ >
28
+ {props.content}
29
+ </text>
30
+ </box>
31
+ )
32
+ }
@@ -0,0 +1,14 @@
1
+ import { createSimpleContext } from "./helper"
2
+
3
+ export interface Args {
4
+ model?: string
5
+ agent?: string
6
+ prompt?: string
7
+ continue?: boolean
8
+ sessionID?: string
9
+ }
10
+
11
+ export const { use: useArgs, provider: ArgsProvider } = createSimpleContext({
12
+ name: "Args",
13
+ init: (props: Args) => props,
14
+ })
@@ -0,0 +1,13 @@
1
+ import { createMemo } from "solid-js"
2
+ import { useSync } from "./sync"
3
+ import { Global } from "@/global"
4
+
5
+ export function useDirectory() {
6
+ const sync = useSync()
7
+ return createMemo(() => {
8
+ const directory = sync.data.path.directory || process.cwd()
9
+ const result = directory.replace(Global.Path.home, "~")
10
+ if (sync.data.vcs?.branch) return result + ":" + sync.data.vcs.branch
11
+ return result
12
+ })
13
+ }
@@ -0,0 +1,23 @@
1
+ import { useRenderer } from "@opentui/solid"
2
+ import { createSimpleContext } from "./helper"
3
+ import { FormatError, FormatUnknownError } from "@/cli/error"
4
+
5
+ export const { use: useExit, provider: ExitProvider } = createSimpleContext({
6
+ name: "Exit",
7
+ init: (input: { onExit?: () => Promise<void> }) => {
8
+ const renderer = useRenderer()
9
+ return async (reason?: any) => {
10
+ // Reset window title before destroying renderer
11
+ renderer.setTerminalTitle("")
12
+ renderer.destroy()
13
+ await input.onExit?.()
14
+ if (reason) {
15
+ const formatted = FormatError(reason) ?? FormatUnknownError(reason)
16
+ if (formatted) {
17
+ process.stderr.write(formatted + "\n")
18
+ }
19
+ }
20
+ process.exit(0)
21
+ }
22
+ },
23
+ })
@@ -0,0 +1,25 @@
1
+ import { createContext, Show, useContext, type ParentProps } from "solid-js"
2
+
3
+ export function createSimpleContext<T, Props extends Record<string, any>>(input: {
4
+ name: string
5
+ init: ((input: Props) => T) | (() => T)
6
+ }) {
7
+ const ctx = createContext<T>()
8
+
9
+ return {
10
+ provider: (props: ParentProps<Props>) => {
11
+ const init = input.init(props)
12
+ return (
13
+ // @ts-expect-error
14
+ <Show when={init.ready === undefined || init.ready === true}>
15
+ <ctx.Provider value={init}>{props.children}</ctx.Provider>
16
+ </Show>
17
+ )
18
+ },
19
+ use() {
20
+ const value = useContext(ctx)
21
+ if (!value) throw new Error(`${input.name} context must be used within a context provider`)
22
+ return value
23
+ },
24
+ }
25
+ }
@@ -0,0 +1,101 @@
1
+ import { createMemo } from "solid-js"
2
+ import { useSync } from "@tui/context/sync"
3
+ import { Keybind } from "@/util/keybind"
4
+ import { pipe, mapValues } from "remeda"
5
+ import type { KeybindsConfig } from "@opencode-ai/sdk/v2"
6
+ import type { ParsedKey, Renderable } from "@opentui/core"
7
+ import { createStore } from "solid-js/store"
8
+ import { useKeyboard, useRenderer } from "@opentui/solid"
9
+ import { createSimpleContext } from "./helper"
10
+
11
+ export const { use: useKeybind, provider: KeybindProvider } = createSimpleContext({
12
+ name: "Keybind",
13
+ init: () => {
14
+ const sync = useSync()
15
+ const keybinds = createMemo(() => {
16
+ return pipe(
17
+ sync.data.config.keybinds ?? {},
18
+ mapValues((value) => Keybind.parse(value)),
19
+ )
20
+ })
21
+ const [store, setStore] = createStore({
22
+ leader: false,
23
+ })
24
+ const renderer = useRenderer()
25
+
26
+ let focus: Renderable | null
27
+ let timeout: NodeJS.Timeout
28
+ function leader(active: boolean) {
29
+ if (active) {
30
+ setStore("leader", true)
31
+ focus = renderer.currentFocusedRenderable
32
+ focus?.blur()
33
+ if (timeout) clearTimeout(timeout)
34
+ timeout = setTimeout(() => {
35
+ if (!store.leader) return
36
+ leader(false)
37
+ if (focus) {
38
+ focus.focus()
39
+ }
40
+ }, 2000)
41
+ return
42
+ }
43
+
44
+ if (!active) {
45
+ if (focus && !renderer.currentFocusedRenderable) {
46
+ focus.focus()
47
+ }
48
+ setStore("leader", false)
49
+ }
50
+ }
51
+
52
+ useKeyboard(async (evt) => {
53
+ if (!store.leader && result.match("leader", evt)) {
54
+ leader(true)
55
+ return
56
+ }
57
+
58
+ if (store.leader && evt.name) {
59
+ setImmediate(() => {
60
+ if (focus && renderer.currentFocusedRenderable === focus) {
61
+ focus.focus()
62
+ }
63
+ leader(false)
64
+ })
65
+ }
66
+ })
67
+
68
+ const result = {
69
+ get all() {
70
+ return keybinds()
71
+ },
72
+ get leader() {
73
+ return store.leader
74
+ },
75
+ parse(evt: ParsedKey): Keybind.Info {
76
+ // Handle special case for Ctrl+Underscore (represented as \x1F)
77
+ if (evt.name === "\x1F") {
78
+ return Keybind.fromParsedKey({ ...evt, name: "_", ctrl: true }, store.leader)
79
+ }
80
+ return Keybind.fromParsedKey(evt, store.leader)
81
+ },
82
+ match(key: keyof KeybindsConfig, evt: ParsedKey) {
83
+ const keybind = keybinds()[key]
84
+ if (!keybind) return false
85
+ const parsed: Keybind.Info = result.parse(evt)
86
+ for (const key of keybind) {
87
+ if (Keybind.match(key, parsed)) {
88
+ return true
89
+ }
90
+ }
91
+ },
92
+ print(key: keyof KeybindsConfig) {
93
+ const first = keybinds()[key]?.at(0)
94
+ if (!first) return ""
95
+ const result = Keybind.toString(first)
96
+ return result.replace("<leader>", Keybind.toString(keybinds().leader![0]!))
97
+ },
98
+ }
99
+ return result
100
+ },
101
+ })
@@ -0,0 +1,49 @@
1
+ import { Global } from "@/global"
2
+ import { createSignal, type Setter } from "solid-js"
3
+ import { createStore } from "solid-js/store"
4
+ import { createSimpleContext } from "./helper"
5
+ import path from "path"
6
+
7
+ export const { use: useKV, provider: KVProvider } = createSimpleContext({
8
+ name: "KV",
9
+ init: () => {
10
+ const [ready, setReady] = createSignal(false)
11
+ const [kvStore, setKvStore] = createStore<Record<string, any>>()
12
+ const file = Bun.file(path.join(Global.Path.state, "kv.json"))
13
+
14
+ file
15
+ .json()
16
+ .then((x) => {
17
+ setKvStore(x)
18
+ })
19
+ .catch(() => {})
20
+ .finally(() => {
21
+ setReady(true)
22
+ })
23
+
24
+ const result = {
25
+ get ready() {
26
+ return ready()
27
+ },
28
+ signal<T>(name: string, defaultValue: T) {
29
+ if (!kvStore[name]) setKvStore(name, defaultValue)
30
+ return [
31
+ function () {
32
+ return result.get(name)
33
+ },
34
+ function setter(next: Setter<T>) {
35
+ result.set(name, next)
36
+ },
37
+ ] as const
38
+ },
39
+ get(key: string, defaultValue?: any) {
40
+ return kvStore[key] ?? defaultValue
41
+ },
42
+ set(key: string, value: any) {
43
+ setKvStore(key, value)
44
+ Bun.write(file, JSON.stringify(kvStore, null, 2))
45
+ },
46
+ }
47
+ return result
48
+ },
49
+ })