@stonerzju/opencode 1.2.17 → 1.2.18

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 (261) hide show
  1. package/bin/opencode +29 -157
  2. package/package.json +29 -29
  3. package/src/acp/agent.ts +4 -4
  4. package/src/acp/session.ts +1 -1
  5. package/src/agent/agent.ts +3 -3
  6. package/src/bun/index.ts +2 -2
  7. package/src/cli/cmd/acp.ts +3 -3
  8. package/src/cli/cmd/debug/file.ts +1 -1
  9. package/src/cli/cmd/github.ts +2 -2
  10. package/src/cli/cmd/pr.ts +1 -1
  11. package/src/cli/cmd/tui/app.tsx +24 -24
  12. package/src/cli/cmd/tui/attach.ts +3 -3
  13. package/src/cli/cmd/tui/component/dialog-agent.tsx +3 -3
  14. package/src/cli/cmd/tui/component/dialog-command.tsx +3 -3
  15. package/src/cli/cmd/tui/component/dialog-mcp.tsx +5 -5
  16. package/src/cli/cmd/tui/component/dialog-model.tsx +4 -4
  17. package/src/cli/cmd/tui/component/dialog-provider.tsx +4 -4
  18. package/src/cli/cmd/tui/component/dialog-session-list.tsx +5 -5
  19. package/src/cli/cmd/tui/component/dialog-session-rename.tsx +3 -3
  20. package/src/cli/cmd/tui/component/dialog-skill.tsx +3 -3
  21. package/src/cli/cmd/tui/component/dialog-stash.tsx +3 -3
  22. package/src/cli/cmd/tui/component/dialog-status.tsx +2 -2
  23. package/src/cli/cmd/tui/component/dialog-tag.tsx +3 -3
  24. package/src/cli/cmd/tui/component/logo.tsx +2 -2
  25. package/src/cli/cmd/tui/component/prompt/autocomplete.tsx +6 -6
  26. package/src/cli/cmd/tui/component/prompt/frecency.tsx +2 -2
  27. package/src/cli/cmd/tui/component/prompt/history.tsx +2 -2
  28. package/src/cli/cmd/tui/component/prompt/index.tsx +14 -14
  29. package/src/cli/cmd/tui/component/prompt/stash.tsx +2 -2
  30. package/src/cli/cmd/tui/component/textarea-keybindings.ts +1 -1
  31. package/src/cli/cmd/tui/component/tips.tsx +1 -1
  32. package/src/cli/cmd/tui/context/directory.ts +1 -1
  33. package/src/cli/cmd/tui/context/exit.tsx +1 -1
  34. package/src/cli/cmd/tui/context/keybind.tsx +2 -2
  35. package/src/cli/cmd/tui/context/kv.tsx +2 -2
  36. package/src/cli/cmd/tui/context/local.tsx +6 -6
  37. package/src/cli/cmd/tui/context/sync.tsx +4 -4
  38. package/src/cli/cmd/tui/context/theme/opencode.json +245 -0
  39. package/src/cli/cmd/tui/context/theme.tsx +2 -2
  40. package/src/cli/cmd/tui/context/tui-config.tsx +1 -1
  41. package/src/cli/cmd/tui/event.ts +2 -2
  42. package/src/cli/cmd/tui/routes/home.tsx +6 -6
  43. package/src/cli/cmd/tui/routes/session/dialog-fork-from-timeline.tsx +6 -6
  44. package/src/cli/cmd/tui/routes/session/dialog-message.tsx +6 -6
  45. package/src/cli/cmd/tui/routes/session/dialog-subagent.tsx +2 -2
  46. package/src/cli/cmd/tui/routes/session/dialog-timeline.tsx +3 -3
  47. package/src/cli/cmd/tui/routes/session/header.tsx +5 -5
  48. package/src/cli/cmd/tui/routes/session/index.tsx +32 -32
  49. package/src/cli/cmd/tui/routes/session/permission.tsx +4 -4
  50. package/src/cli/cmd/tui/routes/session/sidebar.tsx +4 -4
  51. package/src/cli/cmd/tui/thread.ts +9 -9
  52. package/src/cli/cmd/tui/ui/dialog-confirm.tsx +1 -1
  53. package/src/cli/cmd/tui/ui/dialog-help.tsx +2 -2
  54. package/src/cli/cmd/tui/ui/dialog-select.tsx +5 -5
  55. package/src/cli/cmd/tui/ui/dialog.tsx +3 -3
  56. package/src/cli/cmd/tui/ui/toast.tsx +1 -1
  57. package/src/cli/cmd/tui/util/editor.ts +3 -3
  58. package/src/cli/cmd/tui/util/transcript.ts +1 -1
  59. package/src/cli/cmd/tui/worker.ts +10 -10
  60. package/src/cli/error.ts +1 -1
  61. package/src/cli/ui.ts +1 -1
  62. package/src/cli/upgrade.ts +4 -4
  63. package/src/command/index.ts +1 -1
  64. package/src/config/config.ts +10 -10
  65. package/src/config/markdown.ts +1 -1
  66. package/src/config/migrate-tui-config.ts +5 -5
  67. package/src/config/paths.ts +4 -4
  68. package/src/config/tui.ts +4 -4
  69. package/src/control/control.sql.ts +1 -1
  70. package/src/control/index.ts +1 -1
  71. package/src/control-plane/adaptors/worktree.ts +1 -1
  72. package/src/control-plane/session-proxy-middleware.ts +1 -1
  73. package/src/control-plane/workspace.sql.ts +1 -1
  74. package/src/control-plane/workspace.ts +7 -7
  75. package/src/file/index.ts +1 -1
  76. package/src/file/ripgrep.ts +2 -2
  77. package/src/file/watcher.ts +5 -5
  78. package/src/format/formatter.ts +1 -1
  79. package/src/ide/index.ts +3 -3
  80. package/src/index.ts +1 -1
  81. package/src/installation/index.ts +3 -3
  82. package/src/lsp/client.ts +3 -3
  83. package/src/lsp/index.ts +3 -3
  84. package/src/mcp/index.ts +4 -4
  85. package/src/permission/index.ts +2 -2
  86. package/src/permission/next.ts +10 -10
  87. package/src/plugin/codex.ts +1 -1
  88. package/src/plugin/copilot.ts +2 -2
  89. package/src/plugin/index.ts +1 -1
  90. package/src/project/bootstrap.ts +2 -2
  91. package/src/project/instance.ts +4 -4
  92. package/src/project/project.sql.ts +1 -1
  93. package/src/project/project.ts +5 -5
  94. package/src/project/state.ts +1 -1
  95. package/src/project/vcs.ts +4 -4
  96. package/src/provider/auth.ts +4 -4
  97. package/src/provider/error.ts +1 -1
  98. package/src/provider/models-snapshot.ts +2 -0
  99. package/src/provider/models.ts +1 -1
  100. package/src/provider/provider.ts +2 -2
  101. package/src/provider/transform.ts +2 -2
  102. package/src/pty/index.ts +5 -5
  103. package/src/question/index.ts +5 -5
  104. package/src/server/event.ts +1 -1
  105. package/src/server/mdns.ts +1 -1
  106. package/src/server/routes/global.ts +3 -3
  107. package/src/server/routes/permission.ts +1 -1
  108. package/src/server/routes/pty.ts +1 -1
  109. package/src/server/routes/session.ts +4 -4
  110. package/src/server/routes/tui.ts +1 -1
  111. package/src/server/server.ts +3 -3
  112. package/src/session/compaction.ts +7 -7
  113. package/src/session/index.ts +10 -10
  114. package/src/session/instruction.ts +1 -1
  115. package/src/session/llm.ts +11 -11
  116. package/src/session/message-v2.ts +10 -10
  117. package/src/session/message.ts +1 -1
  118. package/src/session/processor.ts +10 -10
  119. package/src/session/prompt.ts +8 -8
  120. package/src/session/retry.ts +2 -2
  121. package/src/session/revert.ts +1 -1
  122. package/src/session/session.sql.ts +3 -3
  123. package/src/session/status.ts +3 -3
  124. package/src/session/summary.ts +5 -5
  125. package/src/session/system.ts +1 -1
  126. package/src/session/todo.ts +2 -2
  127. package/src/share/share-next.ts +7 -7
  128. package/src/share/share.sql.ts +1 -1
  129. package/src/shell/shell.ts +3 -3
  130. package/src/skill/skill.ts +6 -6
  131. package/src/storage/db.ts +1 -1
  132. package/src/storage/storage.ts +1 -1
  133. package/src/tool/bash.ts +6 -6
  134. package/src/tool/edit.ts +1 -1
  135. package/src/tool/registry.ts +2 -2
  136. package/src/tool/skill.ts +1 -1
  137. package/src/tool/task.ts +3 -3
  138. package/src/util/array.ts +10 -0
  139. package/src/util/binary.ts +41 -0
  140. package/src/util/encode.ts +51 -0
  141. package/src/util/error.ts +54 -0
  142. package/src/util/identifier.ts +48 -0
  143. package/src/util/lazy.ts +4 -16
  144. package/src/util/path.ts +37 -0
  145. package/src/util/retry.ts +41 -0
  146. package/src/util/slug.ts +74 -0
  147. package/src/worktree/index.ts +3 -3
  148. package/AGENTS.md +0 -10
  149. package/BUN_SHELL_MIGRATION_PLAN.md +0 -136
  150. package/Dockerfile +0 -18
  151. package/README.md +0 -15
  152. package/bunfig.toml +0 -7
  153. package/drizzle.config.ts +0 -10
  154. package/script/build.ts +0 -224
  155. package/script/check-migrations.ts +0 -16
  156. package/script/postinstall.mjs +0 -131
  157. package/script/publish.ts +0 -181
  158. package/script/schema.ts +0 -63
  159. package/script/seed-e2e.ts +0 -50
  160. package/sst-env.d.ts +0 -10
  161. package/test/AGENTS.md +0 -81
  162. package/test/acp/agent-interface.test.ts +0 -51
  163. package/test/acp/event-subscription.test.ts +0 -683
  164. package/test/agent/agent.test.ts +0 -689
  165. package/test/bun.test.ts +0 -53
  166. package/test/cli/github-action.test.ts +0 -197
  167. package/test/cli/github-remote.test.ts +0 -80
  168. package/test/cli/import.test.ts +0 -38
  169. package/test/cli/plugin-auth-picker.test.ts +0 -120
  170. package/test/cli/tui/transcript.test.ts +0 -322
  171. package/test/config/agent-color.test.ts +0 -71
  172. package/test/config/config.test.ts +0 -1886
  173. package/test/config/fixtures/empty-frontmatter.md +0 -4
  174. package/test/config/fixtures/frontmatter.md +0 -28
  175. package/test/config/fixtures/markdown-header.md +0 -11
  176. package/test/config/fixtures/no-frontmatter.md +0 -1
  177. package/test/config/fixtures/weird-model-id.md +0 -13
  178. package/test/config/markdown.test.ts +0 -228
  179. package/test/config/tui.test.ts +0 -510
  180. package/test/control-plane/session-proxy-middleware.test.ts +0 -147
  181. package/test/control-plane/sse.test.ts +0 -56
  182. package/test/control-plane/workspace-server-sse.test.ts +0 -65
  183. package/test/control-plane/workspace-sync.test.ts +0 -97
  184. package/test/file/ignore.test.ts +0 -10
  185. package/test/file/index.test.ts +0 -394
  186. package/test/file/path-traversal.test.ts +0 -198
  187. package/test/file/ripgrep.test.ts +0 -39
  188. package/test/file/time.test.ts +0 -361
  189. package/test/fixture/db.ts +0 -11
  190. package/test/fixture/fixture.ts +0 -45
  191. package/test/fixture/lsp/fake-lsp-server.js +0 -77
  192. package/test/fixture/skills/agents-sdk/SKILL.md +0 -152
  193. package/test/fixture/skills/agents-sdk/references/callable.md +0 -92
  194. package/test/fixture/skills/cloudflare/SKILL.md +0 -211
  195. package/test/fixture/skills/index.json +0 -6
  196. package/test/ide/ide.test.ts +0 -82
  197. package/test/keybind.test.ts +0 -421
  198. package/test/lsp/client.test.ts +0 -95
  199. package/test/mcp/headers.test.ts +0 -153
  200. package/test/mcp/oauth-browser.test.ts +0 -249
  201. package/test/memory/abort-leak.test.ts +0 -136
  202. package/test/patch/patch.test.ts +0 -348
  203. package/test/permission/arity.test.ts +0 -33
  204. package/test/permission/next.test.ts +0 -689
  205. package/test/permission-task.test.ts +0 -319
  206. package/test/plugin/auth-override.test.ts +0 -44
  207. package/test/plugin/codex.test.ts +0 -123
  208. package/test/preload.ts +0 -80
  209. package/test/project/project.test.ts +0 -348
  210. package/test/project/worktree-remove.test.ts +0 -65
  211. package/test/provider/amazon-bedrock.test.ts +0 -446
  212. package/test/provider/copilot/convert-to-copilot-messages.test.ts +0 -523
  213. package/test/provider/copilot/copilot-chat-model.test.ts +0 -592
  214. package/test/provider/gitlab-duo.test.ts +0 -262
  215. package/test/provider/provider.test.ts +0 -2220
  216. package/test/provider/transform.test.ts +0 -2353
  217. package/test/pty/pty-output-isolation.test.ts +0 -140
  218. package/test/question/question.test.ts +0 -300
  219. package/test/scheduler.test.ts +0 -73
  220. package/test/server/global-session-list.test.ts +0 -89
  221. package/test/server/session-list.test.ts +0 -90
  222. package/test/server/session-select.test.ts +0 -78
  223. package/test/session/compaction.test.ts +0 -423
  224. package/test/session/instruction.test.ts +0 -170
  225. package/test/session/llm.test.ts +0 -667
  226. package/test/session/message-v2.test.ts +0 -924
  227. package/test/session/prompt.test.ts +0 -211
  228. package/test/session/retry.test.ts +0 -188
  229. package/test/session/revert-compact.test.ts +0 -285
  230. package/test/session/session.test.ts +0 -71
  231. package/test/session/structured-output-integration.test.ts +0 -233
  232. package/test/session/structured-output.test.ts +0 -385
  233. package/test/skill/discovery.test.ts +0 -110
  234. package/test/skill/skill.test.ts +0 -388
  235. package/test/snapshot/snapshot.test.ts +0 -1180
  236. package/test/storage/json-migration.test.ts +0 -846
  237. package/test/tool/__snapshots__/tool.test.ts.snap +0 -9
  238. package/test/tool/apply_patch.test.ts +0 -566
  239. package/test/tool/bash.test.ts +0 -402
  240. package/test/tool/edit.test.ts +0 -496
  241. package/test/tool/external-directory.test.ts +0 -127
  242. package/test/tool/fixtures/large-image.png +0 -0
  243. package/test/tool/fixtures/models-api.json +0 -38413
  244. package/test/tool/grep.test.ts +0 -110
  245. package/test/tool/question.test.ts +0 -107
  246. package/test/tool/read.test.ts +0 -504
  247. package/test/tool/registry.test.ts +0 -122
  248. package/test/tool/skill.test.ts +0 -112
  249. package/test/tool/truncation.test.ts +0 -160
  250. package/test/tool/webfetch.test.ts +0 -100
  251. package/test/tool/write.test.ts +0 -348
  252. package/test/util/filesystem.test.ts +0 -443
  253. package/test/util/format.test.ts +0 -59
  254. package/test/util/glob.test.ts +0 -164
  255. package/test/util/iife.test.ts +0 -36
  256. package/test/util/lazy.test.ts +0 -50
  257. package/test/util/lock.test.ts +0 -72
  258. package/test/util/process.test.ts +0 -59
  259. package/test/util/timeout.test.ts +0 -21
  260. package/test/util/wildcard.test.ts +0 -90
  261. package/tsconfig.json +0 -16
package/script/build.ts DELETED
@@ -1,224 +0,0 @@
1
- #!/usr/bin/env bun
2
-
3
- import { $ } from "bun"
4
- import fs from "fs"
5
- import path from "path"
6
- import { fileURLToPath } from "url"
7
- import solidPlugin from "../node_modules/@opentui/solid/scripts/solid-plugin"
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 { Script } from "@opencode-ai/script"
16
- import pkg from "../package.json"
17
-
18
- const modelsUrl = process.env.OPENCODE_MODELS_URL || "https://models.dev"
19
- // Fetch and generate models.dev snapshot
20
- const modelsData = process.env.MODELS_DEV_API_JSON
21
- ? await Bun.file(process.env.MODELS_DEV_API_JSON).text()
22
- : await fetch(`${modelsUrl}/api.json`).then((x) => x.text())
23
- await Bun.write(
24
- path.join(dir, "src/provider/models-snapshot.ts"),
25
- `// Auto-generated by build.ts - do not edit\nexport const snapshot = ${modelsData} as const\n`,
26
- )
27
- console.log("Generated models-snapshot.ts")
28
-
29
- // Load migrations from migration directories
30
- const migrationDirs = (
31
- await fs.promises.readdir(path.join(dir, "migration"), {
32
- withFileTypes: true,
33
- })
34
- )
35
- .filter((entry) => entry.isDirectory() && /^\d{4}\d{2}\d{2}\d{2}\d{2}\d{2}/.test(entry.name))
36
- .map((entry) => entry.name)
37
- .sort()
38
-
39
- const migrations = await Promise.all(
40
- migrationDirs.map(async (name) => {
41
- const file = path.join(dir, "migration", name, "migration.sql")
42
- const sql = await Bun.file(file).text()
43
- const match = /^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/.exec(name)
44
- const timestamp = match
45
- ? Date.UTC(
46
- Number(match[1]),
47
- Number(match[2]) - 1,
48
- Number(match[3]),
49
- Number(match[4]),
50
- Number(match[5]),
51
- Number(match[6]),
52
- )
53
- : 0
54
- return { sql, timestamp }
55
- }),
56
- )
57
- console.log(`Loaded ${migrations.length} migrations`)
58
-
59
- const singleFlag = process.argv.includes("--single")
60
- const baselineFlag = process.argv.includes("--baseline")
61
- const skipInstall = process.argv.includes("--skip-install")
62
-
63
- const allTargets: {
64
- os: string
65
- arch: "arm64" | "x64"
66
- abi?: "musl"
67
- avx2?: false
68
- }[] = [
69
- {
70
- os: "linux",
71
- arch: "arm64",
72
- },
73
- {
74
- os: "linux",
75
- arch: "x64",
76
- },
77
- {
78
- os: "linux",
79
- arch: "x64",
80
- avx2: false,
81
- },
82
- {
83
- os: "linux",
84
- arch: "arm64",
85
- abi: "musl",
86
- },
87
- {
88
- os: "linux",
89
- arch: "x64",
90
- abi: "musl",
91
- },
92
- {
93
- os: "linux",
94
- arch: "x64",
95
- abi: "musl",
96
- avx2: false,
97
- },
98
- {
99
- os: "darwin",
100
- arch: "arm64",
101
- },
102
- {
103
- os: "darwin",
104
- arch: "x64",
105
- },
106
- {
107
- os: "darwin",
108
- arch: "x64",
109
- avx2: false,
110
- },
111
- {
112
- os: "win32",
113
- arch: "x64",
114
- },
115
- {
116
- os: "win32",
117
- arch: "x64",
118
- avx2: false,
119
- },
120
- ]
121
-
122
- const targets = singleFlag
123
- ? allTargets.filter((item) => {
124
- if (item.os !== process.platform || item.arch !== process.arch) {
125
- return false
126
- }
127
-
128
- // When building for the current platform, prefer a single native binary by default.
129
- // Baseline binaries require additional Bun artifacts and can be flaky to download.
130
- if (item.avx2 === false) {
131
- return baselineFlag
132
- }
133
-
134
- // also skip abi-specific builds for the same reason
135
- if (item.abi !== undefined) {
136
- return false
137
- }
138
-
139
- return true
140
- })
141
- : allTargets
142
-
143
- await $`rm -rf dist`
144
-
145
- const binaries: Record<string, string> = {}
146
- if (!skipInstall) {
147
- await $`bun install --os="*" --cpu="*" @opentui/core@${pkg.dependencies["@opentui/core"]}`
148
- await $`bun install --os="*" --cpu="*" @parcel/watcher@${pkg.dependencies["@parcel/watcher"]}`
149
- }
150
- for (const item of targets) {
151
- const name = [
152
- pkg.name,
153
- // changing to win32 flags npm for some reason
154
- item.os === "win32" ? "windows" : item.os,
155
- item.arch,
156
- item.avx2 === false ? "baseline" : undefined,
157
- item.abi === undefined ? undefined : item.abi,
158
- ]
159
- .filter(Boolean)
160
- .join("-")
161
- console.log(`building ${name}`)
162
- await $`mkdir -p dist/${name}/bin`
163
-
164
- const parserWorker = fs.realpathSync(path.resolve(dir, "./node_modules/@opentui/core/parser.worker.js"))
165
- const workerPath = "./src/cli/cmd/tui/worker.ts"
166
-
167
- // Use platform-specific bunfs root path based on target OS
168
- const bunfsRoot = item.os === "win32" ? "B:/~BUN/root/" : "/$bunfs/root/"
169
- const workerRelativePath = path.relative(dir, parserWorker).replaceAll("\\", "/")
170
-
171
- await Bun.build({
172
- conditions: ["browser"],
173
- tsconfig: "./tsconfig.json",
174
- plugins: [solidPlugin],
175
- sourcemap: "external",
176
- compile: {
177
- autoloadBunfig: false,
178
- autoloadDotenv: false,
179
- autoloadTsconfig: true,
180
- autoloadPackageJson: true,
181
- target: name.replace(pkg.name, "bun") as any,
182
- outfile: `dist/${name}/bin/opencode`,
183
- execArgv: [`--user-agent=opencode/${Script.version}`, "--use-system-ca", "--"],
184
- windows: {},
185
- },
186
- entrypoints: ["./src/index.ts", parserWorker, workerPath],
187
- define: {
188
- OPENCODE_VERSION: `'${Script.version}'`,
189
- OPENCODE_MIGRATIONS: JSON.stringify(migrations),
190
- OTUI_TREE_SITTER_WORKER_PATH: bunfsRoot + workerRelativePath,
191
- OPENCODE_WORKER_PATH: workerPath,
192
- OPENCODE_CHANNEL: `'${Script.channel}'`,
193
- OPENCODE_LIBC: item.os === "linux" ? `'${item.abi ?? "glibc"}'` : "",
194
- },
195
- })
196
-
197
- await $`rm -rf ./dist/${name}/bin/tui`
198
- await Bun.file(`dist/${name}/package.json`).write(
199
- JSON.stringify(
200
- {
201
- name,
202
- version: Script.version,
203
- os: [item.os],
204
- cpu: [item.arch],
205
- },
206
- null,
207
- 2,
208
- ),
209
- )
210
- binaries[name] = Script.version
211
- }
212
-
213
- if (Script.release) {
214
- for (const key of Object.keys(binaries)) {
215
- if (key.includes("linux")) {
216
- await $`tar -czf ../../${key}.tar.gz *`.cwd(`dist/${key}/bin`)
217
- } else {
218
- await $`zip -r ../../${key}.zip *`.cwd(`dist/${key}/bin`)
219
- }
220
- }
221
- await $`gh release upload v${Script.version} ./dist/*.zip ./dist/*.tar.gz --clobber --repo ${process.env.GH_REPO}`
222
- }
223
-
224
- export { binaries }
@@ -1,16 +0,0 @@
1
- #!/usr/bin/env bun
2
-
3
- import { $ } from "bun"
4
-
5
- // drizzle-kit check compares schema to migrations, exits non-zero if drift
6
- const result = await $`bun drizzle-kit check`.quiet().nothrow()
7
-
8
- if (result.exitCode !== 0) {
9
- console.error("Schema has changes not captured in migrations!")
10
- console.error("Run: bun drizzle-kit generate")
11
- console.error("")
12
- console.error(result.stderr.toString())
13
- process.exit(1)
14
- }
15
-
16
- console.log("Migrations are up to date")
@@ -1,131 +0,0 @@
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
- const target = path.join(__dirname, "bin", ".opencode")
113
- if (fs.existsSync(target)) fs.unlinkSync(target)
114
- try {
115
- fs.linkSync(binaryPath, target)
116
- } catch {
117
- fs.copyFileSync(binaryPath, target)
118
- }
119
- fs.chmodSync(target, 0o755)
120
- } catch (error) {
121
- console.error("Failed to setup opencode binary:", error.message)
122
- process.exit(1)
123
- }
124
- }
125
-
126
- try {
127
- main()
128
- } catch (error) {
129
- console.error("Postinstall script error:", error.message)
130
- process.exit(0)
131
- }
package/script/publish.ts DELETED
@@ -1,181 +0,0 @@
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/anomalyco/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/anomalyco/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/anomalyco/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/anomalyco/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/anomalyco/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/anomalyco/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/anomalyco/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/anomalyco/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/anomalyco/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/anomalyco/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
- }
package/script/schema.ts DELETED
@@ -1,63 +0,0 @@
1
- #!/usr/bin/env bun
2
-
3
- import { z } from "zod"
4
- import { Config } from "../src/config/config"
5
- import { TuiConfig } from "../src/config/tui"
6
-
7
- function generate(schema: z.ZodType) {
8
- const result = z.toJSONSchema(schema, {
9
- io: "input", // Generate input shape (treats optional().default() as not required)
10
- /**
11
- * We'll use the `default` values of the field as the only value in `examples`.
12
- * This will ensure no docs are needed to be read, as the configuration is
13
- * self-documenting.
14
- *
15
- * See https://json-schema.org/draft/2020-12/draft-bhutton-json-schema-validation-00#rfc.section.9.5
16
- */
17
- override(ctx) {
18
- const schema = ctx.jsonSchema
19
-
20
- // Preserve strictness: set additionalProperties: false for objects
21
- if (
22
- schema &&
23
- typeof schema === "object" &&
24
- schema.type === "object" &&
25
- schema.additionalProperties === undefined
26
- ) {
27
- schema.additionalProperties = false
28
- }
29
-
30
- // Add examples and default descriptions for string fields with defaults
31
- if (schema && typeof schema === "object" && "type" in schema && schema.type === "string" && schema?.default) {
32
- if (!schema.examples) {
33
- schema.examples = [schema.default]
34
- }
35
-
36
- schema.description = [schema.description || "", `default: \`${schema.default}\``]
37
- .filter(Boolean)
38
- .join("\n\n")
39
- .trim()
40
- }
41
- },
42
- }) as Record<string, unknown> & {
43
- allowComments?: boolean
44
- allowTrailingCommas?: boolean
45
- }
46
-
47
- // used for json lsps since config supports jsonc
48
- result.allowComments = true
49
- result.allowTrailingCommas = true
50
-
51
- return result
52
- }
53
-
54
- const configFile = process.argv[2]
55
- const tuiFile = process.argv[3]
56
-
57
- console.log(configFile)
58
- await Bun.write(configFile, JSON.stringify(generate(Config.Info), null, 2))
59
-
60
- if (tuiFile) {
61
- console.log(tuiFile)
62
- await Bun.write(tuiFile, JSON.stringify(generate(TuiConfig.Info), null, 2))
63
- }
@@ -1,50 +0,0 @@
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()
package/sst-env.d.ts DELETED
@@ -1,10 +0,0 @@
1
- /* This file is auto-generated by SST. Do not edit. */
2
- /* tslint:disable */
3
- /* eslint-disable */
4
- /* deno-fmt-ignore-file */
5
- /* biome-ignore-all lint: auto-generated */
6
-
7
- /// <reference path="../../sst-env.d.ts" />
8
-
9
- import "sst"
10
- export {}