opencode-v2 1.1.53

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (439) hide show
  1. package/AGENTS.md +27 -0
  2. package/Dockerfile +18 -0
  3. package/README.md +15 -0
  4. package/bin/opencode +84 -0
  5. package/bunfig.toml +5 -0
  6. package/package.json +126 -0
  7. package/parsers-config.ts +253 -0
  8. package/script/build.ts +193 -0
  9. package/script/postinstall.mjs +125 -0
  10. package/script/publish.ts +181 -0
  11. package/script/schema.ts +47 -0
  12. package/script/seed-e2e.ts +50 -0
  13. package/src/acp/README.md +164 -0
  14. package/src/acp/agent.ts +1676 -0
  15. package/src/acp/session.ts +117 -0
  16. package/src/acp/types.ts +23 -0
  17. package/src/agent/agent.ts +414 -0
  18. package/src/agent/generate.txt +75 -0
  19. package/src/agent/prompt/compaction.txt +12 -0
  20. package/src/agent/prompt/explore.txt +18 -0
  21. package/src/agent/prompt/summary.txt +11 -0
  22. package/src/agent/prompt/title.txt +44 -0
  23. package/src/auth/index.ts +70 -0
  24. package/src/bun/index.ts +137 -0
  25. package/src/bun/registry.ts +48 -0
  26. package/src/bus/bus-event.ts +43 -0
  27. package/src/bus/global.ts +10 -0
  28. package/src/bus/index.ts +105 -0
  29. package/src/cli/bootstrap.ts +17 -0
  30. package/src/cli/cmd/acp.ts +70 -0
  31. package/src/cli/cmd/agent.ts +257 -0
  32. package/src/cli/cmd/auth.ts +400 -0
  33. package/src/cli/cmd/cmd.ts +7 -0
  34. package/src/cli/cmd/debug/agent.ts +167 -0
  35. package/src/cli/cmd/debug/config.ts +16 -0
  36. package/src/cli/cmd/debug/file.ts +97 -0
  37. package/src/cli/cmd/debug/index.ts +48 -0
  38. package/src/cli/cmd/debug/lsp.ts +52 -0
  39. package/src/cli/cmd/debug/ripgrep.ts +87 -0
  40. package/src/cli/cmd/debug/scrap.ts +16 -0
  41. package/src/cli/cmd/debug/skill.ts +16 -0
  42. package/src/cli/cmd/debug/snapshot.ts +52 -0
  43. package/src/cli/cmd/export.ts +88 -0
  44. package/src/cli/cmd/generate.ts +38 -0
  45. package/src/cli/cmd/github.ts +1540 -0
  46. package/src/cli/cmd/import.ts +147 -0
  47. package/src/cli/cmd/mcp.ts +755 -0
  48. package/src/cli/cmd/models.ts +77 -0
  49. package/src/cli/cmd/pr.ts +112 -0
  50. package/src/cli/cmd/run.ts +617 -0
  51. package/src/cli/cmd/serve.ts +20 -0
  52. package/src/cli/cmd/session.ts +135 -0
  53. package/src/cli/cmd/stats.ts +426 -0
  54. package/src/cli/cmd/tui/app.tsx +801 -0
  55. package/src/cli/cmd/tui/attach.ts +52 -0
  56. package/src/cli/cmd/tui/component/border.tsx +21 -0
  57. package/src/cli/cmd/tui/component/dialog-agent.tsx +31 -0
  58. package/src/cli/cmd/tui/component/dialog-command.tsx +148 -0
  59. package/src/cli/cmd/tui/component/dialog-mcp.tsx +86 -0
  60. package/src/cli/cmd/tui/component/dialog-model.tsx +234 -0
  61. package/src/cli/cmd/tui/component/dialog-provider.tsx +266 -0
  62. package/src/cli/cmd/tui/component/dialog-session-list.tsx +108 -0
  63. package/src/cli/cmd/tui/component/dialog-session-rename.tsx +31 -0
  64. package/src/cli/cmd/tui/component/dialog-skill.tsx +36 -0
  65. package/src/cli/cmd/tui/component/dialog-stash.tsx +87 -0
  66. package/src/cli/cmd/tui/component/dialog-status.tsx +177 -0
  67. package/src/cli/cmd/tui/component/dialog-tag.tsx +44 -0
  68. package/src/cli/cmd/tui/component/dialog-theme-list.tsx +50 -0
  69. package/src/cli/cmd/tui/component/logo.tsx +85 -0
  70. package/src/cli/cmd/tui/component/prompt/autocomplete.tsx +666 -0
  71. package/src/cli/cmd/tui/component/prompt/frecency.tsx +89 -0
  72. package/src/cli/cmd/tui/component/prompt/history.tsx +108 -0
  73. package/src/cli/cmd/tui/component/prompt/index.tsx +1132 -0
  74. package/src/cli/cmd/tui/component/prompt/stash.tsx +101 -0
  75. package/src/cli/cmd/tui/component/spinner.tsx +24 -0
  76. package/src/cli/cmd/tui/component/textarea-keybindings.ts +73 -0
  77. package/src/cli/cmd/tui/component/tips.tsx +153 -0
  78. package/src/cli/cmd/tui/component/todo-item.tsx +32 -0
  79. package/src/cli/cmd/tui/context/args.tsx +15 -0
  80. package/src/cli/cmd/tui/context/directory.ts +13 -0
  81. package/src/cli/cmd/tui/context/exit.tsx +52 -0
  82. package/src/cli/cmd/tui/context/helper.tsx +25 -0
  83. package/src/cli/cmd/tui/context/keybind.tsx +100 -0
  84. package/src/cli/cmd/tui/context/kv.tsx +52 -0
  85. package/src/cli/cmd/tui/context/local.tsx +409 -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 +101 -0
  89. package/src/cli/cmd/tui/context/sync.tsx +470 -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/carbonfox.json +248 -0
  93. package/src/cli/cmd/tui/context/theme/catppuccin-frappe.json +233 -0
  94. package/src/cli/cmd/tui/context/theme/catppuccin-macchiato.json +233 -0
  95. package/src/cli/cmd/tui/context/theme/catppuccin.json +112 -0
  96. package/src/cli/cmd/tui/context/theme/cobalt2.json +228 -0
  97. package/src/cli/cmd/tui/context/theme/cursor.json +249 -0
  98. package/src/cli/cmd/tui/context/theme/dracula.json +219 -0
  99. package/src/cli/cmd/tui/context/theme/everforest.json +241 -0
  100. package/src/cli/cmd/tui/context/theme/flexoki.json +237 -0
  101. package/src/cli/cmd/tui/context/theme/github.json +233 -0
  102. package/src/cli/cmd/tui/context/theme/gruvbox.json +242 -0
  103. package/src/cli/cmd/tui/context/theme/kanagawa.json +77 -0
  104. package/src/cli/cmd/tui/context/theme/lucent-orng.json +237 -0
  105. package/src/cli/cmd/tui/context/theme/material.json +235 -0
  106. package/src/cli/cmd/tui/context/theme/matrix.json +77 -0
  107. package/src/cli/cmd/tui/context/theme/mercury.json +252 -0
  108. package/src/cli/cmd/tui/context/theme/monokai.json +221 -0
  109. package/src/cli/cmd/tui/context/theme/nightowl.json +221 -0
  110. package/src/cli/cmd/tui/context/theme/nord.json +223 -0
  111. package/src/cli/cmd/tui/context/theme/one-dark.json +84 -0
  112. package/src/cli/cmd/tui/context/theme/orng.json +249 -0
  113. package/src/cli/cmd/tui/context/theme/osaka-jade.json +93 -0
  114. package/src/cli/cmd/tui/context/theme/palenight.json +222 -0
  115. package/src/cli/cmd/tui/context/theme/rosepine.json +234 -0
  116. package/src/cli/cmd/tui/context/theme/solarized.json +223 -0
  117. package/src/cli/cmd/tui/context/theme/synthwave84.json +226 -0
  118. package/src/cli/cmd/tui/context/theme/tokyonight.json +243 -0
  119. package/src/cli/cmd/tui/context/theme/vercel.json +245 -0
  120. package/src/cli/cmd/tui/context/theme/vesper.json +218 -0
  121. package/src/cli/cmd/tui/context/theme/zenburn.json +223 -0
  122. package/src/cli/cmd/tui/context/theme.tsx +1152 -0
  123. package/src/cli/cmd/tui/event.ts +48 -0
  124. package/src/cli/cmd/tui/routes/home.tsx +140 -0
  125. package/src/cli/cmd/tui/routes/session/dialog-fork-from-timeline.tsx +64 -0
  126. package/src/cli/cmd/tui/routes/session/dialog-message.tsx +109 -0
  127. package/src/cli/cmd/tui/routes/session/dialog-subagent.tsx +26 -0
  128. package/src/cli/cmd/tui/routes/session/dialog-timeline.tsx +47 -0
  129. package/src/cli/cmd/tui/routes/session/footer.tsx +91 -0
  130. package/src/cli/cmd/tui/routes/session/header.tsx +142 -0
  131. package/src/cli/cmd/tui/routes/session/index.tsx +2126 -0
  132. package/src/cli/cmd/tui/routes/session/permission.tsx +508 -0
  133. package/src/cli/cmd/tui/routes/session/question.tsx +466 -0
  134. package/src/cli/cmd/tui/routes/session/sidebar.tsx +313 -0
  135. package/src/cli/cmd/tui/thread.ts +175 -0
  136. package/src/cli/cmd/tui/ui/dialog-alert.tsx +68 -0
  137. package/src/cli/cmd/tui/ui/dialog-confirm.tsx +93 -0
  138. package/src/cli/cmd/tui/ui/dialog-export-options.tsx +215 -0
  139. package/src/cli/cmd/tui/ui/dialog-help.tsx +49 -0
  140. package/src/cli/cmd/tui/ui/dialog-prompt.tsx +88 -0
  141. package/src/cli/cmd/tui/ui/dialog-select.tsx +399 -0
  142. package/src/cli/cmd/tui/ui/dialog.tsx +167 -0
  143. package/src/cli/cmd/tui/ui/link.tsx +28 -0
  144. package/src/cli/cmd/tui/ui/spinner.ts +368 -0
  145. package/src/cli/cmd/tui/ui/toast.tsx +100 -0
  146. package/src/cli/cmd/tui/util/clipboard.ts +159 -0
  147. package/src/cli/cmd/tui/util/editor.ts +32 -0
  148. package/src/cli/cmd/tui/util/signal.ts +7 -0
  149. package/src/cli/cmd/tui/util/terminal.ts +114 -0
  150. package/src/cli/cmd/tui/util/transcript.ts +98 -0
  151. package/src/cli/cmd/tui/worker.ts +152 -0
  152. package/src/cli/cmd/uninstall.ts +357 -0
  153. package/src/cli/cmd/upgrade.ts +73 -0
  154. package/src/cli/cmd/web.ts +81 -0
  155. package/src/cli/error.ts +57 -0
  156. package/src/cli/logo.ts +6 -0
  157. package/src/cli/network.ts +60 -0
  158. package/src/cli/ui.ts +113 -0
  159. package/src/cli/upgrade.ts +25 -0
  160. package/src/command/index.ts +150 -0
  161. package/src/command/template/initialize.txt +10 -0
  162. package/src/command/template/review.txt +99 -0
  163. package/src/config/config.ts +1477 -0
  164. package/src/config/markdown.ts +98 -0
  165. package/src/env/index.ts +28 -0
  166. package/src/file/ignore.ts +83 -0
  167. package/src/file/index.ts +583 -0
  168. package/src/file/ripgrep.ts +375 -0
  169. package/src/file/time.ts +69 -0
  170. package/src/file/watcher.ts +127 -0
  171. package/src/flag/flag.ts +97 -0
  172. package/src/format/formatter.ts +366 -0
  173. package/src/format/index.ts +137 -0
  174. package/src/global/index.ts +55 -0
  175. package/src/id/id.ts +83 -0
  176. package/src/ide/index.ts +76 -0
  177. package/src/index.ts +159 -0
  178. package/src/installation/index.ts +246 -0
  179. package/src/lsp/client.ts +252 -0
  180. package/src/lsp/index.ts +485 -0
  181. package/src/lsp/language.ts +119 -0
  182. package/src/lsp/server.ts +2046 -0
  183. package/src/mcp/auth.ts +132 -0
  184. package/src/mcp/index.ts +934 -0
  185. package/src/mcp/oauth-callback.ts +200 -0
  186. package/src/mcp/oauth-provider.ts +154 -0
  187. package/src/patch/index.ts +680 -0
  188. package/src/permission/arity.ts +163 -0
  189. package/src/permission/index.ts +210 -0
  190. package/src/permission/next.ts +280 -0
  191. package/src/plugin/codex.ts +624 -0
  192. package/src/plugin/copilot.ts +327 -0
  193. package/src/plugin/index.ts +138 -0
  194. package/src/project/bootstrap.ts +35 -0
  195. package/src/project/instance.ts +114 -0
  196. package/src/project/project.ts +371 -0
  197. package/src/project/state.ts +70 -0
  198. package/src/project/vcs.ts +76 -0
  199. package/src/provider/auth.ts +147 -0
  200. package/src/provider/models.ts +133 -0
  201. package/src/provider/provider.ts +1262 -0
  202. package/src/provider/sdk/copilot/README.md +5 -0
  203. package/src/provider/sdk/copilot/chat/convert-to-openai-compatible-chat-messages.ts +164 -0
  204. package/src/provider/sdk/copilot/chat/get-response-metadata.ts +15 -0
  205. package/src/provider/sdk/copilot/chat/map-openai-compatible-finish-reason.ts +17 -0
  206. package/src/provider/sdk/copilot/chat/openai-compatible-api-types.ts +64 -0
  207. package/src/provider/sdk/copilot/chat/openai-compatible-chat-language-model.ts +780 -0
  208. package/src/provider/sdk/copilot/chat/openai-compatible-chat-options.ts +28 -0
  209. package/src/provider/sdk/copilot/chat/openai-compatible-metadata-extractor.ts +44 -0
  210. package/src/provider/sdk/copilot/chat/openai-compatible-prepare-tools.ts +87 -0
  211. package/src/provider/sdk/copilot/copilot-provider.ts +100 -0
  212. package/src/provider/sdk/copilot/index.ts +2 -0
  213. package/src/provider/sdk/copilot/openai-compatible-error.ts +27 -0
  214. package/src/provider/sdk/copilot/responses/convert-to-openai-responses-input.ts +303 -0
  215. package/src/provider/sdk/copilot/responses/map-openai-responses-finish-reason.ts +22 -0
  216. package/src/provider/sdk/copilot/responses/openai-config.ts +18 -0
  217. package/src/provider/sdk/copilot/responses/openai-error.ts +22 -0
  218. package/src/provider/sdk/copilot/responses/openai-responses-api-types.ts +207 -0
  219. package/src/provider/sdk/copilot/responses/openai-responses-language-model.ts +1732 -0
  220. package/src/provider/sdk/copilot/responses/openai-responses-prepare-tools.ts +177 -0
  221. package/src/provider/sdk/copilot/responses/openai-responses-settings.ts +1 -0
  222. package/src/provider/sdk/copilot/responses/tool/code-interpreter.ts +88 -0
  223. package/src/provider/sdk/copilot/responses/tool/file-search.ts +128 -0
  224. package/src/provider/sdk/copilot/responses/tool/image-generation.ts +115 -0
  225. package/src/provider/sdk/copilot/responses/tool/local-shell.ts +65 -0
  226. package/src/provider/sdk/copilot/responses/tool/web-search-preview.ts +104 -0
  227. package/src/provider/sdk/copilot/responses/tool/web-search.ts +103 -0
  228. package/src/provider/transform.ts +828 -0
  229. package/src/pty/index.ts +250 -0
  230. package/src/question/index.ts +171 -0
  231. package/src/scheduler/index.ts +61 -0
  232. package/src/server/error.ts +36 -0
  233. package/src/server/event.ts +7 -0
  234. package/src/server/mdns.ts +60 -0
  235. package/src/server/routes/config.ts +92 -0
  236. package/src/server/routes/experimental.ts +208 -0
  237. package/src/server/routes/file.ts +197 -0
  238. package/src/server/routes/global.ts +183 -0
  239. package/src/server/routes/mcp.ts +225 -0
  240. package/src/server/routes/permission.ts +68 -0
  241. package/src/server/routes/project.ts +82 -0
  242. package/src/server/routes/provider.ts +165 -0
  243. package/src/server/routes/pty.ts +169 -0
  244. package/src/server/routes/question.ts +98 -0
  245. package/src/server/routes/session.ts +939 -0
  246. package/src/server/routes/tui.ts +379 -0
  247. package/src/server/server.ts +613 -0
  248. package/src/session/compaction.ts +226 -0
  249. package/src/session/index.ts +524 -0
  250. package/src/session/instruction.ts +197 -0
  251. package/src/session/llm.ts +289 -0
  252. package/src/session/message-v2.ts +802 -0
  253. package/src/session/message.ts +189 -0
  254. package/src/session/processor.ts +407 -0
  255. package/src/session/prompt/agent.txt +43 -0
  256. package/src/session/prompt/anthropic-20250930.txt +166 -0
  257. package/src/session/prompt/anthropic.txt +105 -0
  258. package/src/session/prompt/beast.txt +147 -0
  259. package/src/session/prompt/build-switch.txt +5 -0
  260. package/src/session/prompt/codex_header.txt +79 -0
  261. package/src/session/prompt/copilot-gpt-5.txt +143 -0
  262. package/src/session/prompt/gemini.txt +155 -0
  263. package/src/session/prompt/max-steps.txt +16 -0
  264. package/src/session/prompt/plan-reminder-anthropic.txt +67 -0
  265. package/src/session/prompt/plan.txt +26 -0
  266. package/src/session/prompt/qwen.txt +109 -0
  267. package/src/session/prompt/research.txt +81 -0
  268. package/src/session/prompt/trinity.txt +97 -0
  269. package/src/session/prompt.ts +1952 -0
  270. package/src/session/retry.ts +97 -0
  271. package/src/session/revert.ts +121 -0
  272. package/src/session/status.ts +76 -0
  273. package/src/session/summary.ts +217 -0
  274. package/src/session/system.ts +54 -0
  275. package/src/session/todo.ts +37 -0
  276. package/src/share/share-next.ts +200 -0
  277. package/src/share/share.ts +92 -0
  278. package/src/shell/shell.ts +67 -0
  279. package/src/skill/discovery.ts +97 -0
  280. package/src/skill/index.ts +1 -0
  281. package/src/skill/skill.ts +188 -0
  282. package/src/snapshot/index.ts +255 -0
  283. package/src/storage/storage.ts +227 -0
  284. package/src/tool/agent-enter.txt +1 -0
  285. package/src/tool/agent-exit.txt +1 -0
  286. package/src/tool/agent.ts +237 -0
  287. package/src/tool/apply_patch.ts +281 -0
  288. package/src/tool/apply_patch.txt +33 -0
  289. package/src/tool/bash.ts +269 -0
  290. package/src/tool/bash.txt +115 -0
  291. package/src/tool/batch.ts +175 -0
  292. package/src/tool/batch.txt +24 -0
  293. package/src/tool/chat-enter.txt +15 -0
  294. package/src/tool/chat-exit.txt +7 -0
  295. package/src/tool/chat.ts +217 -0
  296. package/src/tool/codesearch.ts +132 -0
  297. package/src/tool/codesearch.txt +12 -0
  298. package/src/tool/edit.ts +655 -0
  299. package/src/tool/edit.txt +10 -0
  300. package/src/tool/external-directory.ts +32 -0
  301. package/src/tool/glob.ts +78 -0
  302. package/src/tool/glob.txt +6 -0
  303. package/src/tool/grep.ts +147 -0
  304. package/src/tool/grep.txt +8 -0
  305. package/src/tool/invalid.ts +17 -0
  306. package/src/tool/ls.ts +121 -0
  307. package/src/tool/ls.txt +1 -0
  308. package/src/tool/lsp.ts +96 -0
  309. package/src/tool/lsp.txt +19 -0
  310. package/src/tool/multiedit.ts +46 -0
  311. package/src/tool/multiedit.txt +41 -0
  312. package/src/tool/plan-enter.txt +14 -0
  313. package/src/tool/plan-exit.txt +13 -0
  314. package/src/tool/plan.ts +130 -0
  315. package/src/tool/question.ts +33 -0
  316. package/src/tool/question.txt +10 -0
  317. package/src/tool/read.ts +211 -0
  318. package/src/tool/read.txt +12 -0
  319. package/src/tool/registry.ts +167 -0
  320. package/src/tool/research-enter.txt +1 -0
  321. package/src/tool/research-exit.txt +1 -0
  322. package/src/tool/research.ts +134 -0
  323. package/src/tool/skill.ts +123 -0
  324. package/src/tool/task.ts +165 -0
  325. package/src/tool/task.txt +60 -0
  326. package/src/tool/todo.ts +53 -0
  327. package/src/tool/todoread.txt +14 -0
  328. package/src/tool/todowrite.txt +167 -0
  329. package/src/tool/tool.ts +89 -0
  330. package/src/tool/truncation.ts +106 -0
  331. package/src/tool/webfetch.ts +186 -0
  332. package/src/tool/webfetch.txt +13 -0
  333. package/src/tool/websearch.ts +150 -0
  334. package/src/tool/websearch.txt +14 -0
  335. package/src/tool/write.ts +85 -0
  336. package/src/tool/write.txt +8 -0
  337. package/src/util/abort.ts +35 -0
  338. package/src/util/archive.ts +16 -0
  339. package/src/util/color.ts +19 -0
  340. package/src/util/context.ts +25 -0
  341. package/src/util/defer.ts +12 -0
  342. package/src/util/eventloop.ts +20 -0
  343. package/src/util/filesystem.ts +93 -0
  344. package/src/util/fn.ts +11 -0
  345. package/src/util/format.ts +20 -0
  346. package/src/util/iife.ts +3 -0
  347. package/src/util/keybind.ts +103 -0
  348. package/src/util/lazy.ts +18 -0
  349. package/src/util/locale.ts +81 -0
  350. package/src/util/lock.ts +98 -0
  351. package/src/util/log.ts +180 -0
  352. package/src/util/proxied.ts +3 -0
  353. package/src/util/queue.ts +32 -0
  354. package/src/util/rpc.ts +66 -0
  355. package/src/util/scrap.ts +10 -0
  356. package/src/util/signal.ts +12 -0
  357. package/src/util/timeout.ts +14 -0
  358. package/src/util/token.ts +7 -0
  359. package/src/util/wildcard.ts +56 -0
  360. package/src/worktree/index.ts +574 -0
  361. package/sst-env.d.ts +9 -0
  362. package/test/acp/agent-interface.test.ts +51 -0
  363. package/test/acp/event-subscription.test.ts +436 -0
  364. package/test/agent/agent.test.ts +675 -0
  365. package/test/bun.test.ts +53 -0
  366. package/test/cli/github-action.test.ts +161 -0
  367. package/test/cli/github-remote.test.ts +80 -0
  368. package/test/cli/import.test.ts +38 -0
  369. package/test/cli/tui/transcript.test.ts +322 -0
  370. package/test/config/agent-color.test.ts +71 -0
  371. package/test/config/config.test.ts +1802 -0
  372. package/test/config/fixtures/empty-frontmatter.md +4 -0
  373. package/test/config/fixtures/frontmatter.md +28 -0
  374. package/test/config/fixtures/markdown-header.md +11 -0
  375. package/test/config/fixtures/no-frontmatter.md +1 -0
  376. package/test/config/fixtures/weird-model-id.md +13 -0
  377. package/test/config/markdown.test.ts +228 -0
  378. package/test/file/ignore.test.ts +10 -0
  379. package/test/file/path-traversal.test.ts +198 -0
  380. package/test/file/ripgrep.test.ts +39 -0
  381. package/test/fixture/fixture.ts +45 -0
  382. package/test/fixture/lsp/fake-lsp-server.js +77 -0
  383. package/test/ide/ide.test.ts +82 -0
  384. package/test/keybind.test.ts +421 -0
  385. package/test/lsp/client.test.ts +95 -0
  386. package/test/mcp/headers.test.ts +153 -0
  387. package/test/mcp/oauth-browser.test.ts +249 -0
  388. package/test/memory/abort-leak.test.ts +136 -0
  389. package/test/patch/patch.test.ts +348 -0
  390. package/test/permission/arity.test.ts +33 -0
  391. package/test/permission/next.test.ts +690 -0
  392. package/test/permission-task.test.ts +319 -0
  393. package/test/plugin/auth-override.test.ts +44 -0
  394. package/test/plugin/codex.test.ts +123 -0
  395. package/test/preload.ts +63 -0
  396. package/test/project/project.test.ts +120 -0
  397. package/test/provider/amazon-bedrock.test.ts +445 -0
  398. package/test/provider/copilot/convert-to-copilot-messages.test.ts +523 -0
  399. package/test/provider/copilot/copilot-chat-model.test.ts +592 -0
  400. package/test/provider/gitlab-duo.test.ts +262 -0
  401. package/test/provider/provider.test.ts +2129 -0
  402. package/test/provider/transform.test.ts +2022 -0
  403. package/test/question/question.test.ts +300 -0
  404. package/test/scheduler.test.ts +73 -0
  405. package/test/server/session-list.test.ts +39 -0
  406. package/test/server/session-select.test.ts +78 -0
  407. package/test/session/compaction.test.ts +293 -0
  408. package/test/session/instruction.test.ts +170 -0
  409. package/test/session/llm.test.ts +691 -0
  410. package/test/session/message-v2.test.ts +786 -0
  411. package/test/session/prompt-missing-file.test.ts +53 -0
  412. package/test/session/prompt-special-chars.test.ts +56 -0
  413. package/test/session/prompt-variant.test.ts +60 -0
  414. package/test/session/retry.test.ts +179 -0
  415. package/test/session/revert-compact.test.ts +285 -0
  416. package/test/session/session.test.ts +71 -0
  417. package/test/skill/discovery.test.ts +60 -0
  418. package/test/skill/skill.test.ts +388 -0
  419. package/test/snapshot/snapshot.test.ts +1040 -0
  420. package/test/tool/__snapshots__/tool.test.ts.snap +9 -0
  421. package/test/tool/apply_patch.test.ts +559 -0
  422. package/test/tool/bash.test.ts +399 -0
  423. package/test/tool/external-directory.test.ts +127 -0
  424. package/test/tool/fixtures/large-image.png +0 -0
  425. package/test/tool/fixtures/models-api.json +38413 -0
  426. package/test/tool/grep.test.ts +110 -0
  427. package/test/tool/question.test.ts +107 -0
  428. package/test/tool/read.test.ts +358 -0
  429. package/test/tool/registry.test.ts +122 -0
  430. package/test/tool/skill.test.ts +112 -0
  431. package/test/tool/truncation.test.ts +159 -0
  432. package/test/util/filesystem.test.ts +39 -0
  433. package/test/util/format.test.ts +59 -0
  434. package/test/util/iife.test.ts +36 -0
  435. package/test/util/lazy.test.ts +50 -0
  436. package/test/util/lock.test.ts +72 -0
  437. package/test/util/timeout.test.ts +21 -0
  438. package/test/util/wildcard.test.ts +75 -0
  439. package/tsconfig.json +16 -0
@@ -0,0 +1,193 @@
1
+ #!/usr/bin/env bun
2
+
3
+ import solidPlugin from "../node_modules/@opentui/solid/scripts/solid-plugin"
4
+ import path from "path"
5
+ import fs from "fs"
6
+ import { $ } from "bun"
7
+ import { fileURLToPath } from "url"
8
+
9
+ const __filename = fileURLToPath(import.meta.url)
10
+ const __dirname = path.dirname(__filename)
11
+ const dir = path.resolve(__dirname, "..")
12
+
13
+ process.chdir(dir)
14
+
15
+ import pkg from "../package.json"
16
+ import { Script } from "@opencode-ai/script"
17
+ const modelsUrl = process.env.OPENCODE_MODELS_URL || "https://models.dev"
18
+ // Fetch and generate models.dev snapshot
19
+ const modelsData = process.env.MODELS_DEV_API_JSON
20
+ ? await Bun.file(process.env.MODELS_DEV_API_JSON).text()
21
+ : await fetch(`${modelsUrl}/api.json`).then((x) => x.text())
22
+ await Bun.write(
23
+ path.join(dir, "src/provider/models-snapshot.ts"),
24
+ `// Auto-generated by build.ts - do not edit\nexport const snapshot = ${modelsData} as const\n`,
25
+ )
26
+ console.log("Generated models-snapshot.ts")
27
+
28
+ const singleFlag = process.argv.includes("--single")
29
+ const baselineFlag = process.argv.includes("--baseline")
30
+ const skipInstall = process.argv.includes("--skip-install")
31
+
32
+ const allTargets: {
33
+ os: string
34
+ arch: "arm64" | "x64"
35
+ abi?: "musl"
36
+ avx2?: false
37
+ }[] = [
38
+ {
39
+ os: "linux",
40
+ arch: "arm64",
41
+ },
42
+ {
43
+ os: "linux",
44
+ arch: "x64",
45
+ },
46
+ {
47
+ os: "linux",
48
+ arch: "x64",
49
+ avx2: false,
50
+ },
51
+ {
52
+ os: "linux",
53
+ arch: "arm64",
54
+ abi: "musl",
55
+ },
56
+ {
57
+ os: "linux",
58
+ arch: "x64",
59
+ abi: "musl",
60
+ },
61
+ {
62
+ os: "linux",
63
+ arch: "x64",
64
+ abi: "musl",
65
+ avx2: false,
66
+ },
67
+ {
68
+ os: "darwin",
69
+ arch: "arm64",
70
+ },
71
+ {
72
+ os: "darwin",
73
+ arch: "x64",
74
+ },
75
+ {
76
+ os: "darwin",
77
+ arch: "x64",
78
+ avx2: false,
79
+ },
80
+ {
81
+ os: "win32",
82
+ arch: "x64",
83
+ },
84
+ {
85
+ os: "win32",
86
+ arch: "x64",
87
+ avx2: false,
88
+ },
89
+ ]
90
+
91
+ const targets = singleFlag
92
+ ? allTargets.filter((item) => {
93
+ if (item.os !== process.platform || item.arch !== process.arch) {
94
+ return false
95
+ }
96
+
97
+ // When building for the current platform, prefer a single native binary by default.
98
+ // Baseline binaries require additional Bun artifacts and can be flaky to download.
99
+ if (item.avx2 === false) {
100
+ return baselineFlag
101
+ }
102
+
103
+ // also skip abi-specific builds for the same reason
104
+ if (item.abi !== undefined) {
105
+ return false
106
+ }
107
+
108
+ return true
109
+ })
110
+ : allTargets
111
+
112
+ await $`rm -rf dist`
113
+
114
+ const binaries: Record<string, string> = {}
115
+ if (!skipInstall) {
116
+ await $`bun install --os="*" --cpu="*" @opentui/core@${pkg.dependencies["@opentui/core"]}`
117
+ await $`bun install --os="*" --cpu="*" @parcel/watcher@${pkg.dependencies["@parcel/watcher"]}`
118
+ }
119
+ for (const item of targets) {
120
+ const name = [
121
+ pkg.name,
122
+ // changing to win32 flags npm for some reason
123
+ item.os === "win32" ? "windows" : item.os,
124
+ item.arch,
125
+ item.avx2 === false ? "baseline" : undefined,
126
+ item.abi === undefined ? undefined : item.abi,
127
+ ]
128
+ .filter(Boolean)
129
+ .join("-")
130
+ console.log(`building ${name}`)
131
+ await $`mkdir -p dist/${name}/bin`
132
+
133
+ const parserWorker = fs.realpathSync(path.resolve(dir, "./node_modules/@opentui/core/parser.worker.js"))
134
+ const workerPath = "./src/cli/cmd/tui/worker.ts"
135
+
136
+ // Use platform-specific bunfs root path based on target OS
137
+ const bunfsRoot = item.os === "win32" ? "B:/~BUN/root/" : "/$bunfs/root/"
138
+ const workerRelativePath = path.relative(dir, parserWorker).replaceAll("\\", "/")
139
+
140
+ await Bun.build({
141
+ conditions: ["browser"],
142
+ tsconfig: "./tsconfig.json",
143
+ plugins: [solidPlugin],
144
+ sourcemap: "external",
145
+ compile: {
146
+ autoloadBunfig: false,
147
+ autoloadDotenv: false,
148
+ //@ts-ignore (bun types aren't up to date)
149
+ autoloadTsconfig: true,
150
+ autoloadPackageJson: true,
151
+ target: name.replace(pkg.name, "bun") as any,
152
+ outfile: `dist/${name}/bin/opencode`,
153
+ execArgv: [`--user-agent=opencode/${Script.version}`, "--use-system-ca", "--"],
154
+ windows: {},
155
+ },
156
+ entrypoints: ["./src/index.ts", parserWorker, workerPath],
157
+ define: {
158
+ OPENCODE_VERSION: `'${Script.version}'`,
159
+ OTUI_TREE_SITTER_WORKER_PATH: bunfsRoot + workerRelativePath,
160
+ OPENCODE_WORKER_PATH: workerPath,
161
+ OPENCODE_CHANNEL: `'${Script.channel}'`,
162
+ OPENCODE_LIBC: item.os === "linux" ? `'${item.abi ?? "glibc"}'` : "",
163
+ },
164
+ })
165
+
166
+ await $`rm -rf ./dist/${name}/bin/tui`
167
+ await Bun.file(`dist/${name}/package.json`).write(
168
+ JSON.stringify(
169
+ {
170
+ name,
171
+ version: Script.version,
172
+ os: [item.os],
173
+ cpu: [item.arch],
174
+ },
175
+ null,
176
+ 2,
177
+ ),
178
+ )
179
+ binaries[name] = Script.version
180
+ }
181
+
182
+ if (Script.release) {
183
+ for (const key of Object.keys(binaries)) {
184
+ if (key.includes("linux")) {
185
+ await $`tar -czf ../../${key}.tar.gz *`.cwd(`dist/${key}/bin`)
186
+ } else {
187
+ await $`zip -r ../../${key}.zip *`.cwd(`dist/${key}/bin`)
188
+ }
189
+ }
190
+ await $`gh release upload v${Script.version} ./dist/*.zip ./dist/*.tar.gz --clobber`
191
+ }
192
+
193
+ export { binaries }
@@ -0,0 +1,125 @@
1
+ #!/usr/bin/env node
2
+
3
+ import fs from "fs"
4
+ import path from "path"
5
+ import os from "os"
6
+ import { fileURLToPath } from "url"
7
+ import { createRequire } from "module"
8
+
9
+ const __dirname = path.dirname(fileURLToPath(import.meta.url))
10
+ const require = createRequire(import.meta.url)
11
+
12
+ function detectPlatformAndArch() {
13
+ // Map platform names
14
+ let platform
15
+ switch (os.platform()) {
16
+ case "darwin":
17
+ platform = "darwin"
18
+ break
19
+ case "linux":
20
+ platform = "linux"
21
+ break
22
+ case "win32":
23
+ platform = "windows"
24
+ break
25
+ default:
26
+ platform = os.platform()
27
+ break
28
+ }
29
+
30
+ // Map architecture names
31
+ let arch
32
+ switch (os.arch()) {
33
+ case "x64":
34
+ arch = "x64"
35
+ break
36
+ case "arm64":
37
+ arch = "arm64"
38
+ break
39
+ case "arm":
40
+ arch = "arm"
41
+ break
42
+ default:
43
+ arch = os.arch()
44
+ break
45
+ }
46
+
47
+ return { platform, arch }
48
+ }
49
+
50
+ function findBinary() {
51
+ const { platform, arch } = detectPlatformAndArch()
52
+ const packageName = `opencode-${platform}-${arch}`
53
+ const binaryName = platform === "windows" ? "opencode.exe" : "opencode"
54
+
55
+ try {
56
+ // Use require.resolve to find the package
57
+ const packageJsonPath = require.resolve(`${packageName}/package.json`)
58
+ const packageDir = path.dirname(packageJsonPath)
59
+ const binaryPath = path.join(packageDir, "bin", binaryName)
60
+
61
+ if (!fs.existsSync(binaryPath)) {
62
+ throw new Error(`Binary not found at ${binaryPath}`)
63
+ }
64
+
65
+ return { binaryPath, binaryName }
66
+ } catch (error) {
67
+ throw new Error(`Could not find package ${packageName}: ${error.message}`)
68
+ }
69
+ }
70
+
71
+ function prepareBinDirectory(binaryName) {
72
+ const binDir = path.join(__dirname, "bin")
73
+ const targetPath = path.join(binDir, binaryName)
74
+
75
+ // Ensure bin directory exists
76
+ if (!fs.existsSync(binDir)) {
77
+ fs.mkdirSync(binDir, { recursive: true })
78
+ }
79
+
80
+ // Remove existing binary/symlink if it exists
81
+ if (fs.existsSync(targetPath)) {
82
+ fs.unlinkSync(targetPath)
83
+ }
84
+
85
+ return { binDir, targetPath }
86
+ }
87
+
88
+ function symlinkBinary(sourcePath, binaryName) {
89
+ const { targetPath } = prepareBinDirectory(binaryName)
90
+
91
+ fs.symlinkSync(sourcePath, targetPath)
92
+ console.log(`opencode binary symlinked: ${targetPath} -> ${sourcePath}`)
93
+
94
+ // Verify the file exists after operation
95
+ if (!fs.existsSync(targetPath)) {
96
+ throw new Error(`Failed to symlink binary to ${targetPath}`)
97
+ }
98
+ }
99
+
100
+ async function main() {
101
+ try {
102
+ if (os.platform() === "win32") {
103
+ // On Windows, the .exe is already included in the package and bin field points to it
104
+ // No postinstall setup needed
105
+ console.log("Windows detected: binary setup not needed (using packaged .exe)")
106
+ return
107
+ }
108
+
109
+ // On non-Windows platforms, just verify the binary package exists
110
+ // Don't replace the wrapper script - it handles binary execution
111
+ const { binaryPath } = findBinary()
112
+ console.log(`Platform binary verified at: ${binaryPath}`)
113
+ console.log("Wrapper script will handle binary execution")
114
+ } catch (error) {
115
+ console.error("Failed to setup opencode binary:", error.message)
116
+ process.exit(1)
117
+ }
118
+ }
119
+
120
+ try {
121
+ main()
122
+ } catch (error) {
123
+ console.error("Postinstall script error:", error.message)
124
+ process.exit(0)
125
+ }
@@ -0,0 +1,181 @@
1
+ #!/usr/bin/env bun
2
+ import { $ } from "bun"
3
+ import pkg from "../package.json"
4
+ import { Script } from "@opencode-ai/script"
5
+ import { fileURLToPath } from "url"
6
+
7
+ const dir = fileURLToPath(new URL("..", import.meta.url))
8
+ process.chdir(dir)
9
+
10
+ const binaries: Record<string, string> = {}
11
+ for (const filepath of new Bun.Glob("*/package.json").scanSync({ cwd: "./dist" })) {
12
+ const pkg = await Bun.file(`./dist/${filepath}`).json()
13
+ binaries[pkg.name] = pkg.version
14
+ }
15
+ console.log("binaries", binaries)
16
+ const version = Object.values(binaries)[0]
17
+
18
+ await $`mkdir -p ./dist/${pkg.name}`
19
+ await $`cp -r ./bin ./dist/${pkg.name}/bin`
20
+ await $`cp ./script/postinstall.mjs ./dist/${pkg.name}/postinstall.mjs`
21
+ await Bun.file(`./dist/${pkg.name}/LICENSE`).write(await Bun.file("../../LICENSE").text())
22
+
23
+ await Bun.file(`./dist/${pkg.name}/package.json`).write(
24
+ JSON.stringify(
25
+ {
26
+ name: pkg.name + "-ai",
27
+ bin: {
28
+ [pkg.name]: `./bin/${pkg.name}`,
29
+ },
30
+ scripts: {
31
+ postinstall: "bun ./postinstall.mjs || node ./postinstall.mjs",
32
+ },
33
+ version: version,
34
+ license: pkg.license,
35
+ optionalDependencies: binaries,
36
+ },
37
+ null,
38
+ 2,
39
+ ),
40
+ )
41
+
42
+ const tasks = Object.entries(binaries).map(async ([name]) => {
43
+ if (process.platform !== "win32") {
44
+ await $`chmod -R 755 .`.cwd(`./dist/${name}`)
45
+ }
46
+ await $`bun pm pack`.cwd(`./dist/${name}`)
47
+ await $`npm publish *.tgz --access public --tag ${Script.channel}`.cwd(`./dist/${name}`)
48
+ })
49
+ await Promise.all(tasks)
50
+ await $`cd ./dist/${pkg.name} && bun pm pack && npm publish *.tgz --access public --tag ${Script.channel}`
51
+
52
+ const image = "ghcr.io/openclawd-bot/opencode"
53
+ const platforms = "linux/amd64,linux/arm64"
54
+ const tags = [`${image}:${version}`, `${image}:${Script.channel}`]
55
+ const tagFlags = tags.flatMap((t) => ["-t", t])
56
+ await $`docker buildx build --platform ${platforms} ${tagFlags} --push .`
57
+
58
+ // registries
59
+ if (!Script.preview) {
60
+ // Calculate SHA values
61
+ const arm64Sha = await $`sha256sum ./dist/opencode-linux-arm64.tar.gz | cut -d' ' -f1`.text().then((x) => x.trim())
62
+ const x64Sha = await $`sha256sum ./dist/opencode-linux-x64.tar.gz | cut -d' ' -f1`.text().then((x) => x.trim())
63
+ const macX64Sha = await $`sha256sum ./dist/opencode-darwin-x64.zip | cut -d' ' -f1`.text().then((x) => x.trim())
64
+ const macArm64Sha = await $`sha256sum ./dist/opencode-darwin-arm64.zip | cut -d' ' -f1`.text().then((x) => x.trim())
65
+
66
+ const [pkgver, _subver = ""] = Script.version.split(/(-.*)/, 2)
67
+
68
+ // arch
69
+ const binaryPkgbuild = [
70
+ "# Maintainer: dax",
71
+ "# Maintainer: adam",
72
+ "",
73
+ "pkgname='opencode-bin'",
74
+ `pkgver=${pkgver}`,
75
+ `_subver=${_subver}`,
76
+ "options=('!debug' '!strip')",
77
+ "pkgrel=1",
78
+ "pkgdesc='The AI coding agent built for the terminal.'",
79
+ "url='https://github.com/openclawd-bot/opencode'",
80
+ "arch=('aarch64' 'x86_64')",
81
+ "license=('MIT')",
82
+ "provides=('opencode')",
83
+ "conflicts=('opencode')",
84
+ "depends=('ripgrep')",
85
+ "",
86
+ `source_aarch64=("\${pkgname}_\${pkgver}_aarch64.tar.gz::https://github.com/openclawd-bot/opencode/releases/download/v\${pkgver}\${_subver}/opencode-linux-arm64.tar.gz")`,
87
+ `sha256sums_aarch64=('${arm64Sha}')`,
88
+
89
+ `source_x86_64=("\${pkgname}_\${pkgver}_x86_64.tar.gz::https://github.com/openclawd-bot/opencode/releases/download/v\${pkgver}\${_subver}/opencode-linux-x64.tar.gz")`,
90
+ `sha256sums_x86_64=('${x64Sha}')`,
91
+ "",
92
+ "package() {",
93
+ ' install -Dm755 ./opencode "${pkgdir}/usr/bin/opencode"',
94
+ "}",
95
+ "",
96
+ ].join("\n")
97
+
98
+ for (const [pkg, pkgbuild] of [["opencode-bin", binaryPkgbuild]]) {
99
+ for (let i = 0; i < 30; i++) {
100
+ try {
101
+ await $`rm -rf ./dist/aur-${pkg}`
102
+ await $`git clone ssh://aur@aur.archlinux.org/${pkg}.git ./dist/aur-${pkg}`
103
+ await $`cd ./dist/aur-${pkg} && git checkout master`
104
+ await Bun.file(`./dist/aur-${pkg}/PKGBUILD`).write(pkgbuild)
105
+ await $`cd ./dist/aur-${pkg} && makepkg --printsrcinfo > .SRCINFO`
106
+ await $`cd ./dist/aur-${pkg} && git add PKGBUILD .SRCINFO`
107
+ await $`cd ./dist/aur-${pkg} && git commit -m "Update to v${Script.version}"`
108
+ await $`cd ./dist/aur-${pkg} && git push`
109
+ break
110
+ } catch (e) {
111
+ continue
112
+ }
113
+ }
114
+ }
115
+
116
+ // Homebrew formula
117
+ const homebrewFormula = [
118
+ "# typed: false",
119
+ "# frozen_string_literal: true",
120
+ "",
121
+ "# This file was generated by GoReleaser. DO NOT EDIT.",
122
+ "class Opencode < Formula",
123
+ ` desc "The AI coding agent built for the terminal."`,
124
+ ` homepage "https://github.com/openclawd-bot/opencode"`,
125
+ ` version "${Script.version.split("-")[0]}"`,
126
+ "",
127
+ ` depends_on "ripgrep"`,
128
+ "",
129
+ " on_macos do",
130
+ " if Hardware::CPU.intel?",
131
+ ` url "https://github.com/openclawd-bot/opencode/releases/download/v${Script.version}/opencode-darwin-x64.zip"`,
132
+ ` sha256 "${macX64Sha}"`,
133
+ "",
134
+ " def install",
135
+ ' bin.install "opencode"',
136
+ " end",
137
+ " end",
138
+ " if Hardware::CPU.arm?",
139
+ ` url "https://github.com/openclawd-bot/opencode/releases/download/v${Script.version}/opencode-darwin-arm64.zip"`,
140
+ ` sha256 "${macArm64Sha}"`,
141
+ "",
142
+ " def install",
143
+ ' bin.install "opencode"',
144
+ " end",
145
+ " end",
146
+ " end",
147
+ "",
148
+ " on_linux do",
149
+ " if Hardware::CPU.intel? and Hardware::CPU.is_64_bit?",
150
+ ` url "https://github.com/openclawd-bot/opencode/releases/download/v${Script.version}/opencode-linux-x64.tar.gz"`,
151
+ ` sha256 "${x64Sha}"`,
152
+ " def install",
153
+ ' bin.install "opencode"',
154
+ " end",
155
+ " end",
156
+ " if Hardware::CPU.arm? and Hardware::CPU.is_64_bit?",
157
+ ` url "https://github.com/openclawd-bot/opencode/releases/download/v${Script.version}/opencode-linux-arm64.tar.gz"`,
158
+ ` sha256 "${arm64Sha}"`,
159
+ " def install",
160
+ ' bin.install "opencode"',
161
+ " end",
162
+ " end",
163
+ " end",
164
+ "end",
165
+ "",
166
+ "",
167
+ ].join("\n")
168
+
169
+ const token = process.env.GITHUB_TOKEN
170
+ if (!token) {
171
+ console.error("GITHUB_TOKEN is required to update homebrew tap")
172
+ process.exit(1)
173
+ }
174
+ const tap = `https://x-access-token:${token}@github.com/openclawd-bot/homebrew-tap.git`
175
+ await $`rm -rf ./dist/homebrew-tap`
176
+ await $`git clone ${tap} ./dist/homebrew-tap`
177
+ await Bun.file("./dist/homebrew-tap/opencode.rb").write(homebrewFormula)
178
+ await $`cd ./dist/homebrew-tap && git add opencode.rb`
179
+ await $`cd ./dist/homebrew-tap && git commit -m "Update to v${Script.version}"`
180
+ await $`cd ./dist/homebrew-tap && git push`
181
+ }
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env bun
2
+
3
+ import { z } from "zod"
4
+ import { Config } from "../src/config/config"
5
+
6
+ const file = process.argv[2]
7
+ console.log(file)
8
+
9
+ const result = z.toJSONSchema(Config.Info, {
10
+ io: "input", // Generate input shape (treats optional().default() as not required)
11
+ /**
12
+ * We'll use the `default` values of the field as the only value in `examples`.
13
+ * This will ensure no docs are needed to be read, as the configuration is
14
+ * self-documenting.
15
+ *
16
+ * See https://json-schema.org/draft/2020-12/draft-bhutton-json-schema-validation-00#rfc.section.9.5
17
+ */
18
+ override(ctx) {
19
+ const schema = ctx.jsonSchema
20
+
21
+ // Preserve strictness: set additionalProperties: false for objects
22
+ if (schema && typeof schema === "object" && schema.type === "object" && schema.additionalProperties === undefined) {
23
+ schema.additionalProperties = false
24
+ }
25
+
26
+ // Add examples and default descriptions for string fields with defaults
27
+ if (schema && typeof schema === "object" && "type" in schema && schema.type === "string" && schema?.default) {
28
+ if (!schema.examples) {
29
+ schema.examples = [schema.default]
30
+ }
31
+
32
+ schema.description = [schema.description || "", `default: \`${schema.default}\``]
33
+ .filter(Boolean)
34
+ .join("\n\n")
35
+ .trim()
36
+ }
37
+ },
38
+ }) as Record<string, unknown> & {
39
+ allowComments?: boolean
40
+ allowTrailingCommas?: boolean
41
+ }
42
+
43
+ // used for json lsps since config supports jsonc
44
+ result.allowComments = true
45
+ result.allowTrailingCommas = true
46
+
47
+ await Bun.write(file, JSON.stringify(result, null, 2))
@@ -0,0 +1,50 @@
1
+ const dir = process.env.OPENCODE_E2E_PROJECT_DIR ?? process.cwd()
2
+ const title = process.env.OPENCODE_E2E_SESSION_TITLE ?? "E2E Session"
3
+ const text = process.env.OPENCODE_E2E_MESSAGE ?? "Seeded for UI e2e"
4
+ const model = process.env.OPENCODE_E2E_MODEL ?? "opencode/gpt-5-nano"
5
+ const parts = model.split("/")
6
+ const providerID = parts[0] ?? "opencode"
7
+ const modelID = parts[1] ?? "gpt-5-nano"
8
+ const now = Date.now()
9
+
10
+ const seed = async () => {
11
+ const { Instance } = await import("../src/project/instance")
12
+ const { InstanceBootstrap } = await import("../src/project/bootstrap")
13
+ const { Session } = await import("../src/session")
14
+ const { Identifier } = await import("../src/id/id")
15
+ const { Project } = await import("../src/project/project")
16
+
17
+ await Instance.provide({
18
+ directory: dir,
19
+ init: InstanceBootstrap,
20
+ fn: async () => {
21
+ const session = await Session.create({ title })
22
+ const messageID = Identifier.descending("message")
23
+ const partID = Identifier.descending("part")
24
+ const message = {
25
+ id: messageID,
26
+ sessionID: session.id,
27
+ role: "user" as const,
28
+ time: { created: now },
29
+ agent: "build",
30
+ model: {
31
+ providerID,
32
+ modelID,
33
+ },
34
+ }
35
+ const part = {
36
+ id: partID,
37
+ sessionID: session.id,
38
+ messageID,
39
+ type: "text" as const,
40
+ text,
41
+ time: { start: now },
42
+ }
43
+ await Session.updateMessage(message)
44
+ await Session.updatePart(part)
45
+ await Project.update({ projectID: Instance.project.id, name: "E2E Project" })
46
+ },
47
+ })
48
+ }
49
+
50
+ await seed()