@stonerzju/opencode 1.2.16-offline.1

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 (496) hide show
  1. package/AGENTS.md +10 -0
  2. package/BUN_SHELL_MIGRATION_PLAN.md +136 -0
  3. package/Dockerfile +18 -0
  4. package/README.md +15 -0
  5. package/bin/opencode +179 -0
  6. package/bunfig.toml +7 -0
  7. package/drizzle.config.ts +10 -0
  8. package/migration/20260127222353_familiar_lady_ursula/migration.sql +90 -0
  9. package/migration/20260127222353_familiar_lady_ursula/snapshot.json +796 -0
  10. package/migration/20260211171708_add_project_commands/migration.sql +1 -0
  11. package/migration/20260211171708_add_project_commands/snapshot.json +806 -0
  12. package/migration/20260213144116_wakeful_the_professor/migration.sql +11 -0
  13. package/migration/20260213144116_wakeful_the_professor/snapshot.json +897 -0
  14. package/migration/20260225215848_workspace/migration.sql +7 -0
  15. package/migration/20260225215848_workspace/snapshot.json +959 -0
  16. package/package.json +140 -0
  17. package/package.json.bak +140 -0
  18. package/parsers-config.ts +254 -0
  19. package/script/build.ts +224 -0
  20. package/script/check-migrations.ts +16 -0
  21. package/script/postinstall.mjs +131 -0
  22. package/script/publish.ts +181 -0
  23. package/script/schema.ts +63 -0
  24. package/script/seed-e2e.ts +50 -0
  25. package/src/acp/README.md +174 -0
  26. package/src/acp/agent.ts +1741 -0
  27. package/src/acp/session.ts +116 -0
  28. package/src/acp/types.ts +23 -0
  29. package/src/agent/agent.ts +339 -0
  30. package/src/agent/generate.txt +75 -0
  31. package/src/agent/prompt/compaction.txt +14 -0
  32. package/src/agent/prompt/explore.txt +18 -0
  33. package/src/agent/prompt/summary.txt +11 -0
  34. package/src/agent/prompt/title.txt +44 -0
  35. package/src/auth/index.ts +68 -0
  36. package/src/bun/index.ts +131 -0
  37. package/src/bun/registry.ts +50 -0
  38. package/src/bus/bus-event.ts +43 -0
  39. package/src/bus/global.ts +10 -0
  40. package/src/bus/index.ts +105 -0
  41. package/src/cli/bootstrap.ts +17 -0
  42. package/src/cli/cmd/acp.ts +70 -0
  43. package/src/cli/cmd/agent.ts +257 -0
  44. package/src/cli/cmd/auth.ts +449 -0
  45. package/src/cli/cmd/cmd.ts +7 -0
  46. package/src/cli/cmd/db.ts +118 -0
  47. package/src/cli/cmd/debug/agent.ts +167 -0
  48. package/src/cli/cmd/debug/config.ts +16 -0
  49. package/src/cli/cmd/debug/file.ts +97 -0
  50. package/src/cli/cmd/debug/index.ts +48 -0
  51. package/src/cli/cmd/debug/lsp.ts +52 -0
  52. package/src/cli/cmd/debug/ripgrep.ts +87 -0
  53. package/src/cli/cmd/debug/scrap.ts +16 -0
  54. package/src/cli/cmd/debug/skill.ts +16 -0
  55. package/src/cli/cmd/debug/snapshot.ts +52 -0
  56. package/src/cli/cmd/export.ts +88 -0
  57. package/src/cli/cmd/generate.ts +38 -0
  58. package/src/cli/cmd/github.ts +1631 -0
  59. package/src/cli/cmd/import.ts +170 -0
  60. package/src/cli/cmd/mcp.ts +754 -0
  61. package/src/cli/cmd/models.ts +77 -0
  62. package/src/cli/cmd/pr.ts +112 -0
  63. package/src/cli/cmd/run.ts +625 -0
  64. package/src/cli/cmd/serve.ts +31 -0
  65. package/src/cli/cmd/session.ts +156 -0
  66. package/src/cli/cmd/stats.ts +410 -0
  67. package/src/cli/cmd/tui/app.tsx +845 -0
  68. package/src/cli/cmd/tui/attach.ts +88 -0
  69. package/src/cli/cmd/tui/component/border.tsx +21 -0
  70. package/src/cli/cmd/tui/component/dialog-agent.tsx +31 -0
  71. package/src/cli/cmd/tui/component/dialog-command.tsx +147 -0
  72. package/src/cli/cmd/tui/component/dialog-mcp.tsx +86 -0
  73. package/src/cli/cmd/tui/component/dialog-model.tsx +165 -0
  74. package/src/cli/cmd/tui/component/dialog-provider.tsx +259 -0
  75. package/src/cli/cmd/tui/component/dialog-session-list.tsx +108 -0
  76. package/src/cli/cmd/tui/component/dialog-session-rename.tsx +31 -0
  77. package/src/cli/cmd/tui/component/dialog-skill.tsx +36 -0
  78. package/src/cli/cmd/tui/component/dialog-stash.tsx +87 -0
  79. package/src/cli/cmd/tui/component/dialog-status.tsx +167 -0
  80. package/src/cli/cmd/tui/component/dialog-tag.tsx +44 -0
  81. package/src/cli/cmd/tui/component/dialog-theme-list.tsx +50 -0
  82. package/src/cli/cmd/tui/component/logo.tsx +85 -0
  83. package/src/cli/cmd/tui/component/prompt/autocomplete.tsx +667 -0
  84. package/src/cli/cmd/tui/component/prompt/frecency.tsx +90 -0
  85. package/src/cli/cmd/tui/component/prompt/history.tsx +108 -0
  86. package/src/cli/cmd/tui/component/prompt/index.tsx +1155 -0
  87. package/src/cli/cmd/tui/component/prompt/stash.tsx +101 -0
  88. package/src/cli/cmd/tui/component/spinner.tsx +24 -0
  89. package/src/cli/cmd/tui/component/textarea-keybindings.ts +73 -0
  90. package/src/cli/cmd/tui/component/tips.tsx +152 -0
  91. package/src/cli/cmd/tui/component/todo-item.tsx +32 -0
  92. package/src/cli/cmd/tui/context/args.tsx +15 -0
  93. package/src/cli/cmd/tui/context/directory.ts +13 -0
  94. package/src/cli/cmd/tui/context/exit.tsx +53 -0
  95. package/src/cli/cmd/tui/context/helper.tsx +25 -0
  96. package/src/cli/cmd/tui/context/keybind.tsx +102 -0
  97. package/src/cli/cmd/tui/context/kv.tsx +52 -0
  98. package/src/cli/cmd/tui/context/local.tsx +406 -0
  99. package/src/cli/cmd/tui/context/prompt.tsx +18 -0
  100. package/src/cli/cmd/tui/context/route.tsx +46 -0
  101. package/src/cli/cmd/tui/context/sdk.tsx +101 -0
  102. package/src/cli/cmd/tui/context/sync.tsx +488 -0
  103. package/src/cli/cmd/tui/context/theme/aura.json +69 -0
  104. package/src/cli/cmd/tui/context/theme/ayu.json +80 -0
  105. package/src/cli/cmd/tui/context/theme/carbonfox.json +248 -0
  106. package/src/cli/cmd/tui/context/theme/catppuccin-frappe.json +233 -0
  107. package/src/cli/cmd/tui/context/theme/catppuccin-macchiato.json +233 -0
  108. package/src/cli/cmd/tui/context/theme/catppuccin.json +112 -0
  109. package/src/cli/cmd/tui/context/theme/cobalt2.json +228 -0
  110. package/src/cli/cmd/tui/context/theme/cursor.json +249 -0
  111. package/src/cli/cmd/tui/context/theme/dracula.json +219 -0
  112. package/src/cli/cmd/tui/context/theme/everforest.json +241 -0
  113. package/src/cli/cmd/tui/context/theme/flexoki.json +237 -0
  114. package/src/cli/cmd/tui/context/theme/github.json +233 -0
  115. package/src/cli/cmd/tui/context/theme/gruvbox.json +242 -0
  116. package/src/cli/cmd/tui/context/theme/kanagawa.json +77 -0
  117. package/src/cli/cmd/tui/context/theme/lucent-orng.json +237 -0
  118. package/src/cli/cmd/tui/context/theme/material.json +235 -0
  119. package/src/cli/cmd/tui/context/theme/matrix.json +77 -0
  120. package/src/cli/cmd/tui/context/theme/mercury.json +252 -0
  121. package/src/cli/cmd/tui/context/theme/monokai.json +221 -0
  122. package/src/cli/cmd/tui/context/theme/nightowl.json +221 -0
  123. package/src/cli/cmd/tui/context/theme/nord.json +223 -0
  124. package/src/cli/cmd/tui/context/theme/one-dark.json +84 -0
  125. package/src/cli/cmd/tui/context/theme/orng.json +249 -0
  126. package/src/cli/cmd/tui/context/theme/osaka-jade.json +93 -0
  127. package/src/cli/cmd/tui/context/theme/palenight.json +222 -0
  128. package/src/cli/cmd/tui/context/theme/rosepine.json +234 -0
  129. package/src/cli/cmd/tui/context/theme/solarized.json +223 -0
  130. package/src/cli/cmd/tui/context/theme/synthwave84.json +226 -0
  131. package/src/cli/cmd/tui/context/theme/tokyonight.json +243 -0
  132. package/src/cli/cmd/tui/context/theme/vercel.json +245 -0
  133. package/src/cli/cmd/tui/context/theme/vesper.json +218 -0
  134. package/src/cli/cmd/tui/context/theme/zenburn.json +223 -0
  135. package/src/cli/cmd/tui/context/theme.tsx +1152 -0
  136. package/src/cli/cmd/tui/context/tui-config.tsx +9 -0
  137. package/src/cli/cmd/tui/event.ts +48 -0
  138. package/src/cli/cmd/tui/routes/home.tsx +145 -0
  139. package/src/cli/cmd/tui/routes/session/dialog-fork-from-timeline.tsx +64 -0
  140. package/src/cli/cmd/tui/routes/session/dialog-message.tsx +109 -0
  141. package/src/cli/cmd/tui/routes/session/dialog-subagent.tsx +26 -0
  142. package/src/cli/cmd/tui/routes/session/dialog-timeline.tsx +47 -0
  143. package/src/cli/cmd/tui/routes/session/footer.tsx +91 -0
  144. package/src/cli/cmd/tui/routes/session/header.tsx +135 -0
  145. package/src/cli/cmd/tui/routes/session/index.tsx +2219 -0
  146. package/src/cli/cmd/tui/routes/session/permission.tsx +685 -0
  147. package/src/cli/cmd/tui/routes/session/question.tsx +466 -0
  148. package/src/cli/cmd/tui/routes/session/sidebar.tsx +321 -0
  149. package/src/cli/cmd/tui/thread.ts +199 -0
  150. package/src/cli/cmd/tui/ui/dialog-alert.tsx +59 -0
  151. package/src/cli/cmd/tui/ui/dialog-confirm.tsx +85 -0
  152. package/src/cli/cmd/tui/ui/dialog-export-options.tsx +207 -0
  153. package/src/cli/cmd/tui/ui/dialog-help.tsx +40 -0
  154. package/src/cli/cmd/tui/ui/dialog-prompt.tsx +80 -0
  155. package/src/cli/cmd/tui/ui/dialog-select.tsx +401 -0
  156. package/src/cli/cmd/tui/ui/dialog.tsx +182 -0
  157. package/src/cli/cmd/tui/ui/link.tsx +28 -0
  158. package/src/cli/cmd/tui/ui/spinner.ts +368 -0
  159. package/src/cli/cmd/tui/ui/toast.tsx +100 -0
  160. package/src/cli/cmd/tui/util/clipboard.ts +164 -0
  161. package/src/cli/cmd/tui/util/editor.ts +33 -0
  162. package/src/cli/cmd/tui/util/selection.ts +25 -0
  163. package/src/cli/cmd/tui/util/signal.ts +7 -0
  164. package/src/cli/cmd/tui/util/terminal.ts +114 -0
  165. package/src/cli/cmd/tui/util/transcript.ts +98 -0
  166. package/src/cli/cmd/tui/win32.ts +129 -0
  167. package/src/cli/cmd/tui/worker.ts +157 -0
  168. package/src/cli/cmd/uninstall.ts +356 -0
  169. package/src/cli/cmd/upgrade.ts +73 -0
  170. package/src/cli/cmd/web.ts +81 -0
  171. package/src/cli/cmd/workspace-serve.ts +16 -0
  172. package/src/cli/error.ts +57 -0
  173. package/src/cli/logo.ts +6 -0
  174. package/src/cli/network.ts +60 -0
  175. package/src/cli/ui.ts +116 -0
  176. package/src/cli/upgrade.ts +25 -0
  177. package/src/command/index.ts +150 -0
  178. package/src/command/template/initialize.txt +10 -0
  179. package/src/command/template/review.txt +101 -0
  180. package/src/config/config.ts +1408 -0
  181. package/src/config/markdown.ts +99 -0
  182. package/src/config/migrate-tui-config.ts +155 -0
  183. package/src/config/paths.ts +174 -0
  184. package/src/config/tui-schema.ts +34 -0
  185. package/src/config/tui.ts +118 -0
  186. package/src/control/control.sql.ts +22 -0
  187. package/src/control/index.ts +67 -0
  188. package/src/control-plane/adaptors/index.ts +10 -0
  189. package/src/control-plane/adaptors/types.ts +7 -0
  190. package/src/control-plane/adaptors/worktree.ts +26 -0
  191. package/src/control-plane/config.ts +10 -0
  192. package/src/control-plane/session-proxy-middleware.ts +46 -0
  193. package/src/control-plane/sse.ts +66 -0
  194. package/src/control-plane/workspace-server/routes.ts +33 -0
  195. package/src/control-plane/workspace-server/server.ts +24 -0
  196. package/src/control-plane/workspace.sql.ts +12 -0
  197. package/src/control-plane/workspace.ts +160 -0
  198. package/src/env/index.ts +28 -0
  199. package/src/file/ignore.ts +82 -0
  200. package/src/file/index.ts +646 -0
  201. package/src/file/ripgrep.ts +372 -0
  202. package/src/file/time.ts +71 -0
  203. package/src/file/watcher.ts +128 -0
  204. package/src/flag/flag.ts +109 -0
  205. package/src/format/formatter.ts +395 -0
  206. package/src/format/index.ts +140 -0
  207. package/src/global/index.ts +54 -0
  208. package/src/id/id.ts +84 -0
  209. package/src/ide/index.ts +76 -0
  210. package/src/index.ts +210 -0
  211. package/src/installation/index.ts +266 -0
  212. package/src/lsp/client.ts +251 -0
  213. package/src/lsp/index.ts +485 -0
  214. package/src/lsp/language.ts +120 -0
  215. package/src/lsp/server.ts +2142 -0
  216. package/src/mcp/auth.ts +130 -0
  217. package/src/mcp/index.ts +937 -0
  218. package/src/mcp/oauth-callback.ts +200 -0
  219. package/src/mcp/oauth-provider.ts +176 -0
  220. package/src/patch/index.ts +680 -0
  221. package/src/permission/arity.ts +163 -0
  222. package/src/permission/index.ts +210 -0
  223. package/src/permission/next.ts +286 -0
  224. package/src/plugin/codex.ts +624 -0
  225. package/src/plugin/copilot.ts +327 -0
  226. package/src/plugin/index.ts +143 -0
  227. package/src/project/bootstrap.ts +33 -0
  228. package/src/project/instance.ts +114 -0
  229. package/src/project/project.sql.ts +15 -0
  230. package/src/project/project.ts +441 -0
  231. package/src/project/state.ts +70 -0
  232. package/src/project/vcs.ts +76 -0
  233. package/src/provider/auth.ts +147 -0
  234. package/src/provider/error.ts +189 -0
  235. package/src/provider/models.ts +146 -0
  236. package/src/provider/provider.ts +1338 -0
  237. package/src/provider/sdk/copilot/README.md +5 -0
  238. package/src/provider/sdk/copilot/chat/convert-to-openai-compatible-chat-messages.ts +164 -0
  239. package/src/provider/sdk/copilot/chat/get-response-metadata.ts +15 -0
  240. package/src/provider/sdk/copilot/chat/map-openai-compatible-finish-reason.ts +17 -0
  241. package/src/provider/sdk/copilot/chat/openai-compatible-api-types.ts +64 -0
  242. package/src/provider/sdk/copilot/chat/openai-compatible-chat-language-model.ts +780 -0
  243. package/src/provider/sdk/copilot/chat/openai-compatible-chat-options.ts +28 -0
  244. package/src/provider/sdk/copilot/chat/openai-compatible-metadata-extractor.ts +44 -0
  245. package/src/provider/sdk/copilot/chat/openai-compatible-prepare-tools.ts +87 -0
  246. package/src/provider/sdk/copilot/copilot-provider.ts +100 -0
  247. package/src/provider/sdk/copilot/index.ts +2 -0
  248. package/src/provider/sdk/copilot/openai-compatible-error.ts +27 -0
  249. package/src/provider/sdk/copilot/responses/convert-to-openai-responses-input.ts +303 -0
  250. package/src/provider/sdk/copilot/responses/map-openai-responses-finish-reason.ts +22 -0
  251. package/src/provider/sdk/copilot/responses/openai-config.ts +18 -0
  252. package/src/provider/sdk/copilot/responses/openai-error.ts +22 -0
  253. package/src/provider/sdk/copilot/responses/openai-responses-api-types.ts +207 -0
  254. package/src/provider/sdk/copilot/responses/openai-responses-language-model.ts +1732 -0
  255. package/src/provider/sdk/copilot/responses/openai-responses-prepare-tools.ts +177 -0
  256. package/src/provider/sdk/copilot/responses/openai-responses-settings.ts +1 -0
  257. package/src/provider/sdk/copilot/responses/tool/code-interpreter.ts +88 -0
  258. package/src/provider/sdk/copilot/responses/tool/file-search.ts +128 -0
  259. package/src/provider/sdk/copilot/responses/tool/image-generation.ts +115 -0
  260. package/src/provider/sdk/copilot/responses/tool/local-shell.ts +65 -0
  261. package/src/provider/sdk/copilot/responses/tool/web-search-preview.ts +104 -0
  262. package/src/provider/sdk/copilot/responses/tool/web-search.ts +103 -0
  263. package/src/provider/transform.ts +955 -0
  264. package/src/pty/index.ts +324 -0
  265. package/src/question/index.ts +171 -0
  266. package/src/scheduler/index.ts +61 -0
  267. package/src/server/error.ts +36 -0
  268. package/src/server/event.ts +7 -0
  269. package/src/server/mdns.ts +60 -0
  270. package/src/server/routes/config.ts +92 -0
  271. package/src/server/routes/experimental.ts +270 -0
  272. package/src/server/routes/file.ts +197 -0
  273. package/src/server/routes/global.ts +185 -0
  274. package/src/server/routes/mcp.ts +225 -0
  275. package/src/server/routes/permission.ts +68 -0
  276. package/src/server/routes/project.ts +82 -0
  277. package/src/server/routes/provider.ts +165 -0
  278. package/src/server/routes/pty.ts +200 -0
  279. package/src/server/routes/question.ts +98 -0
  280. package/src/server/routes/session.ts +974 -0
  281. package/src/server/routes/tui.ts +379 -0
  282. package/src/server/routes/workspace.ts +104 -0
  283. package/src/server/server.ts +623 -0
  284. package/src/session/compaction.ts +261 -0
  285. package/src/session/index.ts +877 -0
  286. package/src/session/instruction.ts +192 -0
  287. package/src/session/llm.ts +279 -0
  288. package/src/session/message-v2.ts +899 -0
  289. package/src/session/message.ts +189 -0
  290. package/src/session/processor.ts +421 -0
  291. package/src/session/prompt/anthropic-20250930.txt +166 -0
  292. package/src/session/prompt/anthropic.txt +105 -0
  293. package/src/session/prompt/beast.txt +147 -0
  294. package/src/session/prompt/build-switch.txt +5 -0
  295. package/src/session/prompt/codex_header.txt +79 -0
  296. package/src/session/prompt/copilot-gpt-5.txt +143 -0
  297. package/src/session/prompt/gemini.txt +155 -0
  298. package/src/session/prompt/max-steps.txt +16 -0
  299. package/src/session/prompt/plan-reminder-anthropic.txt +67 -0
  300. package/src/session/prompt/plan.txt +26 -0
  301. package/src/session/prompt/qwen.txt +109 -0
  302. package/src/session/prompt/trinity.txt +97 -0
  303. package/src/session/prompt.ts +1959 -0
  304. package/src/session/retry.ts +101 -0
  305. package/src/session/revert.ts +138 -0
  306. package/src/session/session.sql.ts +88 -0
  307. package/src/session/status.ts +76 -0
  308. package/src/session/summary.ts +161 -0
  309. package/src/session/system.ts +54 -0
  310. package/src/session/todo.ts +56 -0
  311. package/src/share/share-next.ts +210 -0
  312. package/src/share/share.sql.ts +13 -0
  313. package/src/shell/shell.ts +68 -0
  314. package/src/skill/discovery.ts +98 -0
  315. package/src/skill/index.ts +1 -0
  316. package/src/skill/skill.ts +189 -0
  317. package/src/snapshot/index.ts +297 -0
  318. package/src/sql.d.ts +4 -0
  319. package/src/storage/db.ts +155 -0
  320. package/src/storage/json-migration.ts +425 -0
  321. package/src/storage/schema.sql.ts +10 -0
  322. package/src/storage/schema.ts +5 -0
  323. package/src/storage/storage.ts +220 -0
  324. package/src/tool/apply_patch.ts +281 -0
  325. package/src/tool/apply_patch.txt +33 -0
  326. package/src/tool/bash.ts +274 -0
  327. package/src/tool/bash.txt +115 -0
  328. package/src/tool/batch.ts +181 -0
  329. package/src/tool/batch.txt +24 -0
  330. package/src/tool/codesearch.ts +132 -0
  331. package/src/tool/codesearch.txt +12 -0
  332. package/src/tool/edit.ts +654 -0
  333. package/src/tool/edit.txt +10 -0
  334. package/src/tool/external-directory.ts +32 -0
  335. package/src/tool/glob.ts +78 -0
  336. package/src/tool/glob.txt +6 -0
  337. package/src/tool/grep.ts +156 -0
  338. package/src/tool/grep.txt +8 -0
  339. package/src/tool/invalid.ts +17 -0
  340. package/src/tool/ls.ts +121 -0
  341. package/src/tool/ls.txt +1 -0
  342. package/src/tool/lsp.ts +97 -0
  343. package/src/tool/lsp.txt +19 -0
  344. package/src/tool/multiedit.ts +46 -0
  345. package/src/tool/multiedit.txt +41 -0
  346. package/src/tool/plan-enter.txt +14 -0
  347. package/src/tool/plan-exit.txt +13 -0
  348. package/src/tool/plan.ts +131 -0
  349. package/src/tool/question.ts +33 -0
  350. package/src/tool/question.txt +10 -0
  351. package/src/tool/read.ts +293 -0
  352. package/src/tool/read.txt +14 -0
  353. package/src/tool/registry.ts +173 -0
  354. package/src/tool/skill.ts +123 -0
  355. package/src/tool/task.ts +165 -0
  356. package/src/tool/task.txt +60 -0
  357. package/src/tool/todo.ts +53 -0
  358. package/src/tool/todoread.txt +14 -0
  359. package/src/tool/todowrite.txt +167 -0
  360. package/src/tool/tool.ts +89 -0
  361. package/src/tool/truncation.ts +107 -0
  362. package/src/tool/webfetch.ts +206 -0
  363. package/src/tool/webfetch.txt +13 -0
  364. package/src/tool/websearch.ts +150 -0
  365. package/src/tool/websearch.txt +14 -0
  366. package/src/tool/write.ts +84 -0
  367. package/src/tool/write.txt +8 -0
  368. package/src/util/abort.ts +35 -0
  369. package/src/util/archive.ts +16 -0
  370. package/src/util/color.ts +19 -0
  371. package/src/util/context.ts +25 -0
  372. package/src/util/defer.ts +12 -0
  373. package/src/util/eventloop.ts +20 -0
  374. package/src/util/filesystem.ts +189 -0
  375. package/src/util/fn.ts +11 -0
  376. package/src/util/format.ts +20 -0
  377. package/src/util/git.ts +35 -0
  378. package/src/util/glob.ts +34 -0
  379. package/src/util/iife.ts +3 -0
  380. package/src/util/keybind.ts +103 -0
  381. package/src/util/lazy.ts +23 -0
  382. package/src/util/locale.ts +81 -0
  383. package/src/util/lock.ts +98 -0
  384. package/src/util/log.ts +182 -0
  385. package/src/util/process.ts +126 -0
  386. package/src/util/proxied.ts +3 -0
  387. package/src/util/queue.ts +32 -0
  388. package/src/util/rpc.ts +66 -0
  389. package/src/util/scrap.ts +10 -0
  390. package/src/util/signal.ts +12 -0
  391. package/src/util/timeout.ts +14 -0
  392. package/src/util/token.ts +7 -0
  393. package/src/util/wildcard.ts +59 -0
  394. package/src/worktree/index.ts +643 -0
  395. package/sst-env.d.ts +10 -0
  396. package/test/AGENTS.md +81 -0
  397. package/test/acp/agent-interface.test.ts +51 -0
  398. package/test/acp/event-subscription.test.ts +683 -0
  399. package/test/agent/agent.test.ts +689 -0
  400. package/test/bun.test.ts +53 -0
  401. package/test/cli/github-action.test.ts +197 -0
  402. package/test/cli/github-remote.test.ts +80 -0
  403. package/test/cli/import.test.ts +38 -0
  404. package/test/cli/plugin-auth-picker.test.ts +120 -0
  405. package/test/cli/tui/transcript.test.ts +322 -0
  406. package/test/config/agent-color.test.ts +71 -0
  407. package/test/config/config.test.ts +1886 -0
  408. package/test/config/fixtures/empty-frontmatter.md +4 -0
  409. package/test/config/fixtures/frontmatter.md +28 -0
  410. package/test/config/fixtures/markdown-header.md +11 -0
  411. package/test/config/fixtures/no-frontmatter.md +1 -0
  412. package/test/config/fixtures/weird-model-id.md +13 -0
  413. package/test/config/markdown.test.ts +228 -0
  414. package/test/config/tui.test.ts +510 -0
  415. package/test/control-plane/session-proxy-middleware.test.ts +147 -0
  416. package/test/control-plane/sse.test.ts +56 -0
  417. package/test/control-plane/workspace-server-sse.test.ts +65 -0
  418. package/test/control-plane/workspace-sync.test.ts +97 -0
  419. package/test/file/ignore.test.ts +10 -0
  420. package/test/file/index.test.ts +394 -0
  421. package/test/file/path-traversal.test.ts +198 -0
  422. package/test/file/ripgrep.test.ts +39 -0
  423. package/test/file/time.test.ts +361 -0
  424. package/test/fixture/db.ts +11 -0
  425. package/test/fixture/fixture.ts +45 -0
  426. package/test/fixture/lsp/fake-lsp-server.js +77 -0
  427. package/test/fixture/skills/agents-sdk/SKILL.md +152 -0
  428. package/test/fixture/skills/agents-sdk/references/callable.md +92 -0
  429. package/test/fixture/skills/cloudflare/SKILL.md +211 -0
  430. package/test/fixture/skills/index.json +6 -0
  431. package/test/ide/ide.test.ts +82 -0
  432. package/test/keybind.test.ts +421 -0
  433. package/test/lsp/client.test.ts +95 -0
  434. package/test/mcp/headers.test.ts +153 -0
  435. package/test/mcp/oauth-browser.test.ts +249 -0
  436. package/test/memory/abort-leak.test.ts +136 -0
  437. package/test/patch/patch.test.ts +348 -0
  438. package/test/permission/arity.test.ts +33 -0
  439. package/test/permission/next.test.ts +689 -0
  440. package/test/permission-task.test.ts +319 -0
  441. package/test/plugin/auth-override.test.ts +44 -0
  442. package/test/plugin/codex.test.ts +123 -0
  443. package/test/preload.ts +80 -0
  444. package/test/project/project.test.ts +348 -0
  445. package/test/project/worktree-remove.test.ts +65 -0
  446. package/test/provider/amazon-bedrock.test.ts +446 -0
  447. package/test/provider/copilot/convert-to-copilot-messages.test.ts +523 -0
  448. package/test/provider/copilot/copilot-chat-model.test.ts +592 -0
  449. package/test/provider/gitlab-duo.test.ts +262 -0
  450. package/test/provider/provider.test.ts +2220 -0
  451. package/test/provider/transform.test.ts +2353 -0
  452. package/test/pty/pty-output-isolation.test.ts +140 -0
  453. package/test/question/question.test.ts +300 -0
  454. package/test/scheduler.test.ts +73 -0
  455. package/test/server/global-session-list.test.ts +89 -0
  456. package/test/server/session-list.test.ts +90 -0
  457. package/test/server/session-select.test.ts +78 -0
  458. package/test/session/compaction.test.ts +423 -0
  459. package/test/session/instruction.test.ts +170 -0
  460. package/test/session/llm.test.ts +667 -0
  461. package/test/session/message-v2.test.ts +924 -0
  462. package/test/session/prompt.test.ts +211 -0
  463. package/test/session/retry.test.ts +188 -0
  464. package/test/session/revert-compact.test.ts +285 -0
  465. package/test/session/session.test.ts +71 -0
  466. package/test/session/structured-output-integration.test.ts +233 -0
  467. package/test/session/structured-output.test.ts +385 -0
  468. package/test/skill/discovery.test.ts +110 -0
  469. package/test/skill/skill.test.ts +388 -0
  470. package/test/snapshot/snapshot.test.ts +1180 -0
  471. package/test/storage/json-migration.test.ts +846 -0
  472. package/test/tool/__snapshots__/tool.test.ts.snap +9 -0
  473. package/test/tool/apply_patch.test.ts +566 -0
  474. package/test/tool/bash.test.ts +402 -0
  475. package/test/tool/edit.test.ts +496 -0
  476. package/test/tool/external-directory.test.ts +127 -0
  477. package/test/tool/fixtures/large-image.png +0 -0
  478. package/test/tool/fixtures/models-api.json +38413 -0
  479. package/test/tool/grep.test.ts +110 -0
  480. package/test/tool/question.test.ts +107 -0
  481. package/test/tool/read.test.ts +504 -0
  482. package/test/tool/registry.test.ts +122 -0
  483. package/test/tool/skill.test.ts +112 -0
  484. package/test/tool/truncation.test.ts +160 -0
  485. package/test/tool/webfetch.test.ts +100 -0
  486. package/test/tool/write.test.ts +348 -0
  487. package/test/util/filesystem.test.ts +443 -0
  488. package/test/util/format.test.ts +59 -0
  489. package/test/util/glob.test.ts +164 -0
  490. package/test/util/iife.test.ts +36 -0
  491. package/test/util/lazy.test.ts +50 -0
  492. package/test/util/lock.test.ts +72 -0
  493. package/test/util/process.test.ts +59 -0
  494. package/test/util/timeout.test.ts +21 -0
  495. package/test/util/wildcard.test.ts +90 -0
  496. package/tsconfig.json +16 -0
@@ -0,0 +1,110 @@
1
+ import { describe, test, expect, beforeAll, afterAll } from "bun:test"
2
+ import { Discovery } from "../../src/skill/discovery"
3
+ import { Filesystem } from "../../src/util/filesystem"
4
+ import { rm } from "fs/promises"
5
+ import path from "path"
6
+
7
+ let CLOUDFLARE_SKILLS_URL: string
8
+ let server: ReturnType<typeof Bun.serve>
9
+ let downloadCount = 0
10
+
11
+ const fixturePath = path.join(import.meta.dir, "../fixture/skills")
12
+
13
+ beforeAll(async () => {
14
+ await rm(Discovery.dir(), { recursive: true, force: true })
15
+
16
+ server = Bun.serve({
17
+ port: 0,
18
+ async fetch(req) {
19
+ const url = new URL(req.url)
20
+
21
+ // route /.well-known/skills/* to the fixture directory
22
+ if (url.pathname.startsWith("/.well-known/skills/")) {
23
+ const filePath = url.pathname.replace("/.well-known/skills/", "")
24
+ const fullPath = path.join(fixturePath, filePath)
25
+
26
+ if (await Filesystem.exists(fullPath)) {
27
+ if (!fullPath.endsWith("index.json")) {
28
+ downloadCount++
29
+ }
30
+ return new Response(Bun.file(fullPath))
31
+ }
32
+ }
33
+
34
+ return new Response("Not Found", { status: 404 })
35
+ },
36
+ })
37
+
38
+ CLOUDFLARE_SKILLS_URL = `http://localhost:${server.port}/.well-known/skills/`
39
+ })
40
+
41
+ afterAll(async () => {
42
+ server?.stop()
43
+ await rm(Discovery.dir(), { recursive: true, force: true })
44
+ })
45
+
46
+ describe("Discovery.pull", () => {
47
+ test("downloads skills from cloudflare url", async () => {
48
+ const dirs = await Discovery.pull(CLOUDFLARE_SKILLS_URL)
49
+ expect(dirs.length).toBeGreaterThan(0)
50
+ for (const dir of dirs) {
51
+ expect(dir).toStartWith(Discovery.dir())
52
+ const md = path.join(dir, "SKILL.md")
53
+ expect(await Filesystem.exists(md)).toBe(true)
54
+ }
55
+ })
56
+
57
+ test("url without trailing slash works", async () => {
58
+ const dirs = await Discovery.pull(CLOUDFLARE_SKILLS_URL.replace(/\/$/, ""))
59
+ expect(dirs.length).toBeGreaterThan(0)
60
+ for (const dir of dirs) {
61
+ const md = path.join(dir, "SKILL.md")
62
+ expect(await Filesystem.exists(md)).toBe(true)
63
+ }
64
+ })
65
+
66
+ test("returns empty array for invalid url", async () => {
67
+ const dirs = await Discovery.pull(`http://localhost:${server.port}/invalid-url/`)
68
+ expect(dirs).toEqual([])
69
+ })
70
+
71
+ test("returns empty array for non-json response", async () => {
72
+ // any url not explicitly handled in server returns 404 text "Not Found"
73
+ const dirs = await Discovery.pull(`http://localhost:${server.port}/some-other-path/`)
74
+ expect(dirs).toEqual([])
75
+ })
76
+
77
+ test("downloads reference files alongside SKILL.md", async () => {
78
+ const dirs = await Discovery.pull(CLOUDFLARE_SKILLS_URL)
79
+ // find a skill dir that should have reference files (e.g. agents-sdk)
80
+ const agentsSdk = dirs.find((d) => d.endsWith(path.sep + "agents-sdk"))
81
+ expect(agentsSdk).toBeDefined()
82
+ if (agentsSdk) {
83
+ const refs = path.join(agentsSdk, "references")
84
+ expect(await Filesystem.exists(path.join(agentsSdk, "SKILL.md"))).toBe(true)
85
+ // agents-sdk has reference files per the index
86
+ const refDir = await Array.fromAsync(new Bun.Glob("**/*.md").scan({ cwd: refs, onlyFiles: true }))
87
+ expect(refDir.length).toBeGreaterThan(0)
88
+ }
89
+ })
90
+
91
+ test("caches downloaded files on second pull", async () => {
92
+ // clear dir and downloadCount
93
+ await rm(Discovery.dir(), { recursive: true, force: true })
94
+ downloadCount = 0
95
+
96
+ // first pull to populate cache
97
+ const first = await Discovery.pull(CLOUDFLARE_SKILLS_URL)
98
+ expect(first.length).toBeGreaterThan(0)
99
+ const firstCount = downloadCount
100
+ expect(firstCount).toBeGreaterThan(0)
101
+
102
+ // second pull should return same results from cache
103
+ const second = await Discovery.pull(CLOUDFLARE_SKILLS_URL)
104
+ expect(second.length).toBe(first.length)
105
+ expect(second.sort()).toEqual(first.sort())
106
+
107
+ // second pull should NOT increment download count
108
+ expect(downloadCount).toBe(firstCount)
109
+ })
110
+ })
@@ -0,0 +1,388 @@
1
+ import { test, expect } from "bun:test"
2
+ import { Skill } from "../../src/skill"
3
+ import { Instance } from "../../src/project/instance"
4
+ import { tmpdir } from "../fixture/fixture"
5
+ import path from "path"
6
+ import fs from "fs/promises"
7
+
8
+ async function createGlobalSkill(homeDir: string) {
9
+ const skillDir = path.join(homeDir, ".claude", "skills", "global-test-skill")
10
+ await fs.mkdir(skillDir, { recursive: true })
11
+ await Bun.write(
12
+ path.join(skillDir, "SKILL.md"),
13
+ `---
14
+ name: global-test-skill
15
+ description: A global skill from ~/.claude/skills for testing.
16
+ ---
17
+
18
+ # Global Test Skill
19
+
20
+ This skill is loaded from the global home directory.
21
+ `,
22
+ )
23
+ }
24
+
25
+ test("discovers skills from .opencode/skill/ directory", async () => {
26
+ await using tmp = await tmpdir({
27
+ git: true,
28
+ init: async (dir) => {
29
+ const skillDir = path.join(dir, ".opencode", "skill", "test-skill")
30
+ await Bun.write(
31
+ path.join(skillDir, "SKILL.md"),
32
+ `---
33
+ name: test-skill
34
+ description: A test skill for verification.
35
+ ---
36
+
37
+ # Test Skill
38
+
39
+ Instructions here.
40
+ `,
41
+ )
42
+ },
43
+ })
44
+
45
+ await Instance.provide({
46
+ directory: tmp.path,
47
+ fn: async () => {
48
+ const skills = await Skill.all()
49
+ expect(skills.length).toBe(1)
50
+ const testSkill = skills.find((s) => s.name === "test-skill")
51
+ expect(testSkill).toBeDefined()
52
+ expect(testSkill!.description).toBe("A test skill for verification.")
53
+ expect(testSkill!.location).toContain(path.join("skill", "test-skill", "SKILL.md"))
54
+ },
55
+ })
56
+ })
57
+
58
+ test("returns skill directories from Skill.dirs", async () => {
59
+ await using tmp = await tmpdir({
60
+ git: true,
61
+ init: async (dir) => {
62
+ const skillDir = path.join(dir, ".opencode", "skill", "dir-skill")
63
+ await Bun.write(
64
+ path.join(skillDir, "SKILL.md"),
65
+ `---
66
+ name: dir-skill
67
+ description: Skill for dirs test.
68
+ ---
69
+
70
+ # Dir Skill
71
+ `,
72
+ )
73
+ },
74
+ })
75
+
76
+ const home = process.env.OPENCODE_TEST_HOME
77
+ process.env.OPENCODE_TEST_HOME = tmp.path
78
+
79
+ try {
80
+ await Instance.provide({
81
+ directory: tmp.path,
82
+ fn: async () => {
83
+ const dirs = await Skill.dirs()
84
+ const skillDir = path.join(tmp.path, ".opencode", "skill", "dir-skill")
85
+ expect(dirs).toContain(skillDir)
86
+ expect(dirs.length).toBe(1)
87
+ },
88
+ })
89
+ } finally {
90
+ process.env.OPENCODE_TEST_HOME = home
91
+ }
92
+ })
93
+
94
+ test("discovers multiple skills from .opencode/skill/ directory", async () => {
95
+ await using tmp = await tmpdir({
96
+ git: true,
97
+ init: async (dir) => {
98
+ const skillDir1 = path.join(dir, ".opencode", "skill", "skill-one")
99
+ const skillDir2 = path.join(dir, ".opencode", "skill", "skill-two")
100
+ await Bun.write(
101
+ path.join(skillDir1, "SKILL.md"),
102
+ `---
103
+ name: skill-one
104
+ description: First test skill.
105
+ ---
106
+
107
+ # Skill One
108
+ `,
109
+ )
110
+ await Bun.write(
111
+ path.join(skillDir2, "SKILL.md"),
112
+ `---
113
+ name: skill-two
114
+ description: Second test skill.
115
+ ---
116
+
117
+ # Skill Two
118
+ `,
119
+ )
120
+ },
121
+ })
122
+
123
+ await Instance.provide({
124
+ directory: tmp.path,
125
+ fn: async () => {
126
+ const skills = await Skill.all()
127
+ expect(skills.length).toBe(2)
128
+ expect(skills.find((s) => s.name === "skill-one")).toBeDefined()
129
+ expect(skills.find((s) => s.name === "skill-two")).toBeDefined()
130
+ },
131
+ })
132
+ })
133
+
134
+ test("skips skills with missing frontmatter", async () => {
135
+ await using tmp = await tmpdir({
136
+ git: true,
137
+ init: async (dir) => {
138
+ const skillDir = path.join(dir, ".opencode", "skill", "no-frontmatter")
139
+ await Bun.write(
140
+ path.join(skillDir, "SKILL.md"),
141
+ `# No Frontmatter
142
+
143
+ Just some content without YAML frontmatter.
144
+ `,
145
+ )
146
+ },
147
+ })
148
+
149
+ await Instance.provide({
150
+ directory: tmp.path,
151
+ fn: async () => {
152
+ const skills = await Skill.all()
153
+ expect(skills).toEqual([])
154
+ },
155
+ })
156
+ })
157
+
158
+ test("discovers skills from .claude/skills/ directory", async () => {
159
+ await using tmp = await tmpdir({
160
+ git: true,
161
+ init: async (dir) => {
162
+ const skillDir = path.join(dir, ".claude", "skills", "claude-skill")
163
+ await Bun.write(
164
+ path.join(skillDir, "SKILL.md"),
165
+ `---
166
+ name: claude-skill
167
+ description: A skill in the .claude/skills directory.
168
+ ---
169
+
170
+ # Claude Skill
171
+ `,
172
+ )
173
+ },
174
+ })
175
+
176
+ await Instance.provide({
177
+ directory: tmp.path,
178
+ fn: async () => {
179
+ const skills = await Skill.all()
180
+ expect(skills.length).toBe(1)
181
+ const claudeSkill = skills.find((s) => s.name === "claude-skill")
182
+ expect(claudeSkill).toBeDefined()
183
+ expect(claudeSkill!.location).toContain(path.join(".claude", "skills", "claude-skill", "SKILL.md"))
184
+ },
185
+ })
186
+ })
187
+
188
+ test("discovers global skills from ~/.claude/skills/ directory", async () => {
189
+ await using tmp = await tmpdir({ git: true })
190
+
191
+ const originalHome = process.env.OPENCODE_TEST_HOME
192
+ process.env.OPENCODE_TEST_HOME = tmp.path
193
+
194
+ try {
195
+ await createGlobalSkill(tmp.path)
196
+ await Instance.provide({
197
+ directory: tmp.path,
198
+ fn: async () => {
199
+ const skills = await Skill.all()
200
+ expect(skills.length).toBe(1)
201
+ expect(skills[0].name).toBe("global-test-skill")
202
+ expect(skills[0].description).toBe("A global skill from ~/.claude/skills for testing.")
203
+ expect(skills[0].location).toContain(path.join(".claude", "skills", "global-test-skill", "SKILL.md"))
204
+ },
205
+ })
206
+ } finally {
207
+ process.env.OPENCODE_TEST_HOME = originalHome
208
+ }
209
+ })
210
+
211
+ test("returns empty array when no skills exist", async () => {
212
+ await using tmp = await tmpdir({ git: true })
213
+
214
+ await Instance.provide({
215
+ directory: tmp.path,
216
+ fn: async () => {
217
+ const skills = await Skill.all()
218
+ expect(skills).toEqual([])
219
+ },
220
+ })
221
+ })
222
+
223
+ test("discovers skills from .agents/skills/ directory", async () => {
224
+ await using tmp = await tmpdir({
225
+ git: true,
226
+ init: async (dir) => {
227
+ const skillDir = path.join(dir, ".agents", "skills", "agent-skill")
228
+ await Bun.write(
229
+ path.join(skillDir, "SKILL.md"),
230
+ `---
231
+ name: agent-skill
232
+ description: A skill in the .agents/skills directory.
233
+ ---
234
+
235
+ # Agent Skill
236
+ `,
237
+ )
238
+ },
239
+ })
240
+
241
+ await Instance.provide({
242
+ directory: tmp.path,
243
+ fn: async () => {
244
+ const skills = await Skill.all()
245
+ expect(skills.length).toBe(1)
246
+ const agentSkill = skills.find((s) => s.name === "agent-skill")
247
+ expect(agentSkill).toBeDefined()
248
+ expect(agentSkill!.location).toContain(path.join(".agents", "skills", "agent-skill", "SKILL.md"))
249
+ },
250
+ })
251
+ })
252
+
253
+ test("discovers global skills from ~/.agents/skills/ directory", async () => {
254
+ await using tmp = await tmpdir({ git: true })
255
+
256
+ const originalHome = process.env.OPENCODE_TEST_HOME
257
+ process.env.OPENCODE_TEST_HOME = tmp.path
258
+
259
+ try {
260
+ const skillDir = path.join(tmp.path, ".agents", "skills", "global-agent-skill")
261
+ await fs.mkdir(skillDir, { recursive: true })
262
+ await Bun.write(
263
+ path.join(skillDir, "SKILL.md"),
264
+ `---
265
+ name: global-agent-skill
266
+ description: A global skill from ~/.agents/skills for testing.
267
+ ---
268
+
269
+ # Global Agent Skill
270
+
271
+ This skill is loaded from the global home directory.
272
+ `,
273
+ )
274
+
275
+ await Instance.provide({
276
+ directory: tmp.path,
277
+ fn: async () => {
278
+ const skills = await Skill.all()
279
+ expect(skills.length).toBe(1)
280
+ expect(skills[0].name).toBe("global-agent-skill")
281
+ expect(skills[0].description).toBe("A global skill from ~/.agents/skills for testing.")
282
+ expect(skills[0].location).toContain(path.join(".agents", "skills", "global-agent-skill", "SKILL.md"))
283
+ },
284
+ })
285
+ } finally {
286
+ process.env.OPENCODE_TEST_HOME = originalHome
287
+ }
288
+ })
289
+
290
+ test("discovers skills from both .claude/skills/ and .agents/skills/", async () => {
291
+ await using tmp = await tmpdir({
292
+ git: true,
293
+ init: async (dir) => {
294
+ const claudeDir = path.join(dir, ".claude", "skills", "claude-skill")
295
+ const agentDir = path.join(dir, ".agents", "skills", "agent-skill")
296
+ await Bun.write(
297
+ path.join(claudeDir, "SKILL.md"),
298
+ `---
299
+ name: claude-skill
300
+ description: A skill in the .claude/skills directory.
301
+ ---
302
+
303
+ # Claude Skill
304
+ `,
305
+ )
306
+ await Bun.write(
307
+ path.join(agentDir, "SKILL.md"),
308
+ `---
309
+ name: agent-skill
310
+ description: A skill in the .agents/skills directory.
311
+ ---
312
+
313
+ # Agent Skill
314
+ `,
315
+ )
316
+ },
317
+ })
318
+
319
+ await Instance.provide({
320
+ directory: tmp.path,
321
+ fn: async () => {
322
+ const skills = await Skill.all()
323
+ expect(skills.length).toBe(2)
324
+ expect(skills.find((s) => s.name === "claude-skill")).toBeDefined()
325
+ expect(skills.find((s) => s.name === "agent-skill")).toBeDefined()
326
+ },
327
+ })
328
+ })
329
+
330
+ test("properly resolves directories that skills live in", async () => {
331
+ await using tmp = await tmpdir({
332
+ git: true,
333
+ init: async (dir) => {
334
+ const opencodeSkillDir = path.join(dir, ".opencode", "skill", "agent-skill")
335
+ const opencodeSkillsDir = path.join(dir, ".opencode", "skills", "agent-skill")
336
+ const claudeDir = path.join(dir, ".claude", "skills", "claude-skill")
337
+ const agentDir = path.join(dir, ".agents", "skills", "agent-skill")
338
+ await Bun.write(
339
+ path.join(claudeDir, "SKILL.md"),
340
+ `---
341
+ name: claude-skill
342
+ description: A skill in the .claude/skills directory.
343
+ ---
344
+
345
+ # Claude Skill
346
+ `,
347
+ )
348
+ await Bun.write(
349
+ path.join(agentDir, "SKILL.md"),
350
+ `---
351
+ name: agent-skill
352
+ description: A skill in the .agents/skills directory.
353
+ ---
354
+
355
+ # Agent Skill
356
+ `,
357
+ )
358
+ await Bun.write(
359
+ path.join(opencodeSkillDir, "SKILL.md"),
360
+ `---
361
+ name: opencode-skill
362
+ description: A skill in the .opencode/skill directory.
363
+ ---
364
+
365
+ # OpenCode Skill
366
+ `,
367
+ )
368
+ await Bun.write(
369
+ path.join(opencodeSkillsDir, "SKILL.md"),
370
+ `---
371
+ name: opencode-skill
372
+ description: A skill in the .opencode/skills directory.
373
+ ---
374
+
375
+ # OpenCode Skill
376
+ `,
377
+ )
378
+ },
379
+ })
380
+
381
+ await Instance.provide({
382
+ directory: tmp.path,
383
+ fn: async () => {
384
+ const dirs = await Skill.dirs()
385
+ expect(dirs.length).toBe(4)
386
+ },
387
+ })
388
+ })