Compare commits

...

1374 Commits

Author SHA1 Message Date
Aiden Cline 78829463ec chore: remove dead code for todoread tool (#19128)
publish-github-action / publish (push) Waiting to run
2026-03-25 16:21:42 +00:00
Adam 1a233e5928 chore: cleanup 2026-03-25 11:15:34 -05:00
opencode-agent[bot] dc3ca3bd3d chore: update nix node_modules hashes 2026-03-25 16:08:30 +00:00
opencode-agent[bot] ef5b7f07b5 chore: generate 2026-03-25 15:40:53 +00:00
Shoubhit Dash 973ad436e1 feat: restore git-backed review modes with effectful git service (#18900) 2026-03-25 21:09:53 +05:30
Adam 4a7091c988 chore: storybook tweaks 2026-03-25 10:20:19 -05:00
Aiden Cline 8b0654dbd5 chore: bump modelcontextprotocol/sdk to 1.27.1 (#19064) 2026-03-25 10:00:39 -05:00
opencode-agent[bot] a53518d64b chore: generate 2026-03-25 14:48:44 +00:00
James Long 87d41cd5ac feat(core): initial implementation of syncing (#17814) 2026-03-25 10:47:40 -04:00
Adam 04da047809 chore(app): markdown playground in storyboard 2026-03-25 09:14:35 -05:00
Adam 0684cdc468 chore(app): markdown playground in storyboard 2026-03-25 09:14:35 -05:00
Adam 00c9fd819e fix(app): opencode web server url 2026-03-25 06:41:00 -05:00
Adam 870a2f8773 Reapply "fix(app): startup efficiency"
This reverts commit 24f93b627b.
2026-03-25 06:25:57 -05:00
Adam 24f93b627b Revert "fix(app): startup efficiency" 2026-03-25 06:25:05 -05:00
Adam 7957a49217 fix(app): hash inline script for csp 2026-03-25 05:59:06 -05:00
Adam c21949be00 Reapply "fix(app): more startup efficiency (#18985)"
This reverts commit e514bfd49e.
2026-03-25 05:59:06 -05:00
Adam eba2f67227 Reapply "fix(app): startup efficiency (#18854)"
This reverts commit 311a58a8c8.
2026-03-25 05:59:05 -05:00
Shoubhit Dash 66444a700a fix(app): move message navigation off cmd+arrow (#18728) 2026-03-25 05:24:55 -05:00
Brendan Allan 42b1d9f9eb app: pre-warm project globalSync state when navigate project via keybind (#19088) 2026-03-25 17:32:49 +08:00
Brendan Allan d5b2a6ac72 electron: remove file extension from electron-store wrapper (#19082) 2026-03-25 07:57:27 +00:00
Brendan Allan 0f8d7f1f5c electron: add createDirectory to open directory picker (#19071) 2026-03-25 06:25:51 +00:00
Luke Parker 81c4d85eb7 fix: unblock beta conflict recovery (#19068) 2026-03-25 06:14:38 +00:00
Luke Parker 8a987ee885 fix: beta resolver typecheck + build smoke check (#19060) 2026-03-25 05:45:30 +00:00
Aiden Cline bba2963719 tweak: only spawn lsp servers for files in current instance (or cwd if instance is global) (#19058) 2026-03-25 00:31:29 -05:00
Luke Parker 110c3bd372 fix: provide merge context to beta conflict resolver (#19055) 2026-03-25 04:45:37 +00:00
Dax 771508a2d4 fix(opencode): avoid snapshotting files over 2MB (#19043) 2026-03-25 04:43:48 +00:00
Dax Raad d01a4e4d28 Change issue close reason from not_planned to completed 2026-03-24 23:55:10 -04:00
Dax Raad 468eec0ed8 Process issues sequentially to avoid rate limits 2026-03-24 23:54:27 -04:00
Dax Raad ede2f19985 Fix close-issues workflow permissions
- Add contents: read permission for checkout
- Use github.token instead of secrets.GITHUB_TOKEN
2026-03-24 23:51:46 -04:00
Dax Raad 32c5aabdb9 Add close-issues script and GitHub Action
- Create script/github/close-issues.ts to close stale issues after 60 days
- Add GitHub Action workflow to run daily at 2 AM
- Remove old stale-issues workflow to avoid conflicts
2026-03-24 23:50:35 -04:00
Dax Raad 14d65e9c2b fix: increase operations-per-run to 1000 and pin stale action to v10.2.0
The stale-issues workflow was hitting the default 30 operations limit,
preventing it from processing all 2900+ issues/PRs. Increased to 1000
to handle the full backlog. Also pinned to exact v10.2.0 for reproducibility.
2026-03-24 23:38:15 -04:00
Kit Langton 8610313b6a effectify Worktree service (#18679) 2026-03-24 20:26:21 -04:00
Adam 311a58a8c8 Revert "fix(app): startup efficiency (#18854)"
This reverts commit 824d903e86.
2026-03-24 18:36:37 -05:00
Adam e514bfd49e Revert "fix(app): more startup efficiency (#18985)"
This reverts commit dcca493ece.
2026-03-24 18:36:25 -05:00
Kit Langton 57bc933abd fix(opencode): skip typechecking generated models snapshot (#19018) 2026-03-24 19:11:45 -04:00
opencode 84de2c4832 release: v1.3.2 2026-03-24 22:50:35 +00:00
Dax Raad 268a777129 change model for changelog 2026-03-24 18:25:52 -04:00
Dax Raad ff043c204a ci 2026-03-24 18:24:34 -04:00
Dax 16a38009ee feat(tui): add heap snapshot functionality for TUI and server (#19028) 2026-03-24 18:20:11 -04:00
opencode-agent[bot] e426ed3e9a chore: update nix node_modules hashes 2026-03-24 22:07:32 +00:00
Jay V 1d7e22d716 tweak: use theme tokens for debug bar surface 2026-03-24 22:07:32 +00:00
opencode 1158f4f6a5 release: v1.3.1 2026-03-24 22:07:24 +00:00
Dax 50ac413272 fix(core): restore SIGHUP exit handler (#16057) (#18527) 2026-03-24 17:42:58 -04:00
Kamil Jopek d858439803 feat: add Poe OAuth auth plugin (#18477) 2026-03-24 16:17:47 -05:00
Adam fbac9617ff fix(app): session timeline jumping on scroll (#18993) 2026-03-24 13:51:09 -05:00
opencode-agent[bot] c2c4a476ef chore: generate 2026-03-24 18:43:20 +00:00
Nicholas Hansen 948aad44c8 feat(bedrock): Add token caching for any amazon-bedrock provider (#18959) 2026-03-24 13:42:20 -05:00
opencode-agent[bot] 235f8771bf chore: update nix node_modules hashes 2026-03-24 18:40:28 +00:00
Adam 22e7516a47 fix(app): sidebar ux 2026-03-24 13:35:20 -05:00
Adam dcca493ece fix(app): more startup efficiency (#18985) 2026-03-24 13:23:41 -05:00
Aiden Cline 67a30121a9 chore: effectify agent.ts (#18971)
Co-authored-by: Kit Langton <kit.langton@gmail.com>
2026-03-24 18:15:23 +00:00
Caleb Norton 2465e8d47d fix: nix hash update parsing... again (#18989) 2026-03-24 13:06:46 -05:00
opencode-agent[bot] 156f7fdb1a chore: generate 2026-03-24 18:05:43 +00:00
Adam 70289b7236 fix(app): sidebar truncation 2026-03-24 13:04:32 -05:00
Kit Langton a6ed355ed1 effectify Project service (#18808) 2026-03-24 14:04:22 -04:00
Ryan Skidmore fbbd8c5ee8 fix: improve plugin system robustness — agent/command resolution, async errors, hook timing, two-phase init (#18280)
Co-authored-by: Aiden Cline <63023139+rekram1-node@users.noreply.github.com>
2026-03-24 12:50:55 -05:00
Caleb Norton 0299ab17fa chore: update flake.lock (#18976)
Co-authored-by: Aiden Cline <63023139+rekram1-node@users.noreply.github.com>
2026-03-24 12:50:25 -05:00
Vladimir Glafirov c5e80e7454 fix: route GitLab Duo Workflow system prompt via flowConfig (#18928) 2026-03-24 12:33:18 -05:00
Caleb Norton 2a10f0d418 fix: nix hash update parsing (#18979) 2026-03-24 12:32:48 -05:00
opencode-agent[bot] d68d4ef387 chore: generate 2026-03-24 17:05:02 +00:00
Kit Langton 9519186313 fix: remove flaky cross-spawn spawner tests (#18977) 2026-03-24 13:04:04 -04:00
Jack fb1f1b24fb fix: update Feishu community links for zh locales (#18975) 2026-03-25 01:03:01 +08:00
opencode-agent[bot] a83ebab843 chore: update nix node_modules hashes 2026-03-24 16:43:24 +00:00
Caleb Norton 973103d552 fix: better nix hash detection (#18957) 2026-03-24 11:30:39 -05:00
Kit Langton 7fcc8d6ad5 fix: restore cross-spawn behavior for effect child processes (#18798) 2026-03-24 10:35:24 -04:00
Adam 824d903e86 fix(app): startup efficiency (#18854) 2026-03-24 09:10:24 -05:00
Burak Yigit Kaya cde5e4b899 fix(ui): eliminate N+1 reactive subscriptions in SessionTurn (#18924) 2026-03-24 09:02:22 -05:00
Burak Yigit Kaya 035f9d9e6d fix(app): use optional chaining for model.current() in ProviderIcon (#18927) 2026-03-24 09:01:58 -05:00
Burak Yigit Kaya 32e89036ec fix(app): filter non-renderable part types from browser store (#18926) 2026-03-24 09:01:25 -05:00
Shoubhit Dash 751bc0a117 fix(app): stop terminal autofocus on shortcuts (#18931) 2026-03-24 11:16:16 +00:00
Sebastian 62b3869f0d manually lock/unlock theme mode (#18905) 2026-03-24 10:00:19 +01:00
Frank 4d24f97b2f sync 2026-03-24 01:00:20 -04:00
opencode-agent[bot] bc2cdbc319 chore: update nix node_modules hashes 2026-03-24 03:14:22 +00:00
Vladimir Glafirov abc6d9d2ca chore: bump gitlab-ai-provider to 5.3.1 for GPT-5.4 model support (#18849) 2026-03-23 22:00:36 -05:00
Frank f6e8d78e6d wip: zen 2026-03-23 22:24:58 -04:00
Frank 476da1afbf Zen: adjust cache tokens 2026-03-23 20:33:11 -04:00
Sebastian 4a96259b39 use renderer theme mode to switch dark/light mode (#18851) 2026-03-24 00:32:48 +01:00
opencode-agent[bot] ffa297cdeb chore: generate 2026-03-23 17:12:55 +00:00
Kit Langton 9530074d34 fix console account URL handling (#18809) 2026-03-23 13:11:38 -04:00
Frank 39c617e0a7 ci: fix 2026-03-23 12:47:42 -04:00
Aiden Cline 3484d75370 tweak: add back setting user agent in requests (#18795) 2026-03-23 15:34:59 +00:00
Abhishek Keshri 1dc24d4b38 feat(tui): add syntax highlighting for kotlin, hcl, lua, toml (#18198) 2026-03-23 16:15:24 +01:00
David Hill 72835aee86 tui: keep file tree open at its minimum resized width (#18777) 2026-03-23 20:06:43 +08:00
Brendan Allan 1bcf0e8e34 fix(app): only navigate prompt history when input is empty (#18775) 2026-03-23 11:48:34 +00:00
opencode-agent[bot] 131cca1fcd chore: update nix node_modules hashes 2026-03-23 10:52:56 +00:00
opencode-agent[bot] 988f548fc9 chore: update nix node_modules hashes 2026-03-23 10:37:23 +00:00
opencode-agent[bot] 32be4661d5 chore: generate 2026-03-23 10:35:30 +00:00
Brendan Allan bda7879e25 fix(app): handle session busy state better (#18758) 2026-03-23 10:34:32 +00:00
Brendan Allan 21ed03a5dc fix(app): lift up project hover state to layout (#18732) 2026-03-23 08:58:20 +00:00
Brendan Allan e457633e93 electron: more robust sidecar kill handling (#18742) 2026-03-23 08:44:23 +00:00
Shoubhit Dash ac936c9ee0 fix(app): prefer cmd+k for command palette (#18731) 2026-03-23 08:00:24 +00:00
Shoubhit Dash 23d37d87dc fix(app): prevent stale session hover preview on refocus (#18727) 2026-03-23 07:25:30 +00:00
Shoubhit Dash 7cc9d15cc6 fix(app): batch multi-file prompt attachments (#18722) 2026-03-23 06:44:17 +00:00
github-actions[bot] 7de12e7f29 Update VOUCHED list
https://github.com/anomalyco/opencode/issues/18718#issuecomment-4108322776
2026-03-23 06:28:47 +00:00
Luke Parker 440a7693f4 Add 'write' role to vouch manage action (#18718) 2026-03-23 06:27:35 +00:00
James Long fa54dd86f7 fix(core): fix file watcher test (#18698) 2026-03-23 03:35:17 +00:00
opencode-agent[bot] 14c98756df chore: update nix node_modules hashes 2026-03-23 01:03:20 +00:00
Sebastian 3ab06799e4 Upgrade opentui to 0.1.90 (#18551) 2026-03-23 01:45:34 +01:00
David Hill 4e9cf57b60 tui: keep patch tool counts visible with long filenames (#18678) 2026-03-23 00:45:11 +00:00
Luke Parker 233dd46542 fix(app): restore keyboard project switching in open sidebar (#18682) 2026-03-23 00:39:46 +00:00
opencode-agent[bot] b42f24b16d chore: update nix node_modules hashes 2026-03-23 00:29:45 +00:00
David Hill c9c025d3b9 tweak(ui): fix padding bottom on the context tab (#18680) 2026-03-23 00:23:45 +00:00
David Hill c606f956f8 tui: prevent project avatar popover flicker when switching projects (#18660)
Co-authored-by: LukeParkerDev <10430890+Hona@users.noreply.github.com>
2026-03-23 10:20:49 +10:00
Luke Parker d56481b2d1 chore: bump Bun to 1.3.11 (#18144) 2026-03-23 10:19:21 +10:00
Dax Raad 08da7fd04b changelog slash command 2026-03-22 19:45:23 -04:00
opencode-agent[bot] c7d639bea8 chore: generate 2026-03-22 23:32:09 +00:00
opencode 4e248b3830 release: v1.3.0 2026-03-22 23:32:01 +00:00
Dax a65e6119ad feat: interactive update flow for non-patch releases (#18662) 2026-03-22 23:12:40 +00:00
David Hill e765ccb0e3 fix(ui): stop auto close of sidebar on resize (#18647) 2026-03-23 08:53:12 +10:00
Filip ce6f9bccb4 fix(app): terminal rename from context menu (#18263)
Co-authored-by: Brendan Allan <brendonovich@outlook.com>
2026-03-22 04:39:51 +00:00
Kit Langton 36f76fdf16 effectify Pty service (#18572) 2026-03-22 01:17:13 +00:00
Kit Langton 22d942cba2 effectify ToolRegistry service (#18571) 2026-03-22 01:06:01 +00:00
opencode-agent[bot] 919ab3e898 chore: generate 2026-03-22 00:51:19 +00:00
Kit Langton 6fcdb273eb effectify Plugin service (#18570) 2026-03-22 00:50:22 +00:00
Kit Langton 65d4fcaf4e effectify Command service (#18568) 2026-03-22 00:21:41 +00:00
Kit Langton ccbd2936d2 effectify SessionStatus service (#18565) 2026-03-21 23:55:07 +00:00
opencode-agent[bot] 05e7b6e5a8 chore: update nix node_modules hashes 2026-03-21 19:17:12 +00:00
Sebastian f9fd9c27bd Upgrade opentui to 0.1.88 (#18079) 2026-03-21 19:00:42 +00:00
Protocol Zero 73bff070e1 fix(provider): only set thinkingConfig for models with reasoning capability (#18283) 2026-03-21 11:57:52 -05:00
opencode-agent[bot] d234f92039 chore: update nix node_modules hashes 2026-03-21 15:47:15 +00:00
opencode-agent[bot] 80342b9679 chore: generate 2026-03-21 15:34:05 +00:00
Brendan Allan 34f9f99462 app: manage mutation loading states with tanstack query (#18501) 2026-03-21 23:33:04 +08:00
Brendan Allan 9a68318aaa app: allow navigating projects with keybinds (#18502) 2026-03-21 22:13:09 +08:00
opencode-agent[bot] 69bbc9f1cd chore: generate 2026-03-21 13:12:54 +00:00
Dax Raad 2c47881bdf fix annotation 2026-03-21 09:11:15 -04:00
Frank a42b2a0ddb wip: zen 2026-03-21 04:07:51 -04:00
opencode-agent[bot] fd9a27ae04 chore: generate 2026-03-21 04:52:23 +00:00
Kit Langton b6aa472839 Move service state into InstanceState, flatten service facades (#18483) 2026-03-21 04:51:35 +00:00
opencode-agent[bot] 2a81d70eb0 chore: generate 2026-03-21 03:11:28 +00:00
Kit Langton 45a3b2ca05 fix(zen): emit cost chunk in client-facing format, not upstream format (#16817) 2026-03-20 23:10:34 -04:00
Dax Raad cb807850b5 allow customizing DB location 2026-03-20 22:49:55 -04:00
Aiden Cline 71ccf72898 ignore: add danieljoshuanazareth to disavow list (#18476) 2026-03-20 21:34:07 -04:00
github-actions[bot] 1477804b1c Update VOUCHED list
https://github.com/anomalyco/opencode/issues/18464#issuecomment-4101766628
2026-03-21 01:28:40 +00:00
Dax Raad d2273f3e88 ci 2026-03-20 17:00:05 -04:00
Kit Langton 9eafdc92ec fix: switch consumers to service imports to break bundle cycles (#18438) 2026-03-20 20:55:46 +00:00
Dax Raad f891192f86 commit and push 2026-03-20 16:36:19 -04:00
Dax Raad 1953f5cfa5 fix question cross out 2026-03-20 15:50:04 -04:00
Kit Langton 0457745593 fix: update stale account url/email on re-login (#18426) 2026-03-20 14:50:01 -04:00
opencode-agent[bot] 8dcdcdad90 chore: generate 2026-03-20 18:38:08 +00:00
Kit Langton 42a5ceb048 fix: apply Layer.fresh at instance service definition site (#18418) 2026-03-20 14:37:12 -04:00
opencode-agent[bot] cef5ab2e54 chore: update nix node_modules hashes 2026-03-20 18:16:17 +00:00
Vladimir Glafirov 1fb2ef5ec2 feat: enable GitLab Agent Platform with workflow model discovery (#18014) 2026-03-20 12:55:22 -05:00
opencode-agent[bot] d79132c5c1 chore: generate 2026-03-20 16:11:21 +00:00
Kit Langton c71771dcf2 effectify Installation service, drop Effect suffix from namespaces (#18266) 2026-03-20 12:10:33 -04:00
Aiden Cline 371aca7729 tweak: adjust codex plugin logic so that codex instruction isn't always added (oauth plan no longer enforces instruction whitelisting) (#18337) 2026-03-20 10:37:47 -05:00
MC bf916a653c docs: add Cloudflare Workers AI provider (#18322)
Co-authored-by: Aiden Cline <63023139+rekram1-node@users.noreply.github.com>
2026-03-20 10:10:22 -05:00
Brendan Allan bec6f54109 app: file type filter on desktop + multiple files (#18403) 2026-03-20 15:02:07 +00:00
Shoubhit Dash 884e6c4b26 fix(app): align review file comments with diff comments (#18406) 2026-03-20 14:44:18 +00:00
Luke Parker 4ccb32aca8 deslopity deslopity (#18343) 2026-03-20 05:24:27 +00:00
opencode-agent[bot] 205df45a9b chore: update nix node_modules hashes 2026-03-20 05:14:32 +00:00
Brendan Allan 6c7d5eaaab patch solid to try fix memo undefined under transition bug (#18338) 2026-03-20 14:58:35 +10:00
Luke Parker 763c116502 fix: lots of desktop stability, better e2e error logging (#18300) 2026-03-20 00:12:06 -04:00
Luke Parker ebbb4124b8 fix: avoid truncate permission import cycle (#18292) 2026-03-19 23:52:04 -04:00
opencode-agent[bot] 16a0abc970 chore: update nix node_modules hashes 2026-03-20 02:21:29 +00:00
Dax f07cdc7072 fix: miscellaneous small fixes (#18328) 2026-03-19 22:20:29 -04:00
Jaaneek 5126f77686 feat: switch xai provider to responses API (#18175)
Co-authored-by: Jaaneek <jankiewiczmilosz@gmail.com>
2026-03-19 21:09:49 -05:00
opencode-agent[bot] 6875f2bad8 chore: update nix node_modules hashes 2026-03-20 01:36:22 +00:00
Dax 8158f21835 feat: add Node.js entry point and build script (#18324) 2026-03-19 21:35:07 -04:00
Dax ce01d92ef8 fix: include cache bin directory in which() lookups (#18320) 2026-03-19 21:21:55 -04:00
Dax ff945d8632 refactor: replace Bun shell execution with portable Process utilities (#18318) 2026-03-19 21:17:06 -04:00
Dax ed094f2196 refactor: abstract SQLite behind runtime-conditional #db import (#18316) 2026-03-19 21:15:35 -04:00
Dax fb1b5328d7 refactor(tui): replace Bun-specific APIs with portable alternatives (#18304) 2026-03-19 19:32:59 -04:00
Frank 8570353f0c doc: update translator to gpt model 2026-03-19 19:07:02 -04:00
Dax 0848f630b2 chore: inline tool descriptions, remove separate .txt files (#18303) 2026-03-19 19:02:42 -04:00
Frank 9d48e1e13c go: upi translation 2026-03-19 18:54:32 -04:00
Dax 8ecde3ae5f refactor: replace Bun.sleep with node:timers/promises sleep (#18301) 2026-03-19 18:50:40 -04:00
Frank 7a43e617fb go: upi payment 2026-03-19 18:44:24 -04:00
opencode-agent[bot] 922a8abb7c chore: generate 2026-03-19 20:21:10 +00:00
Kit Langton c6bc3028a6 fix(account): handle pending console login polling (#18281) 2026-03-19 16:18:28 -04:00
opencode-agent[bot] aead63e1db chore: generate 2026-03-19 20:05:33 +00:00
jorge g 8fa53ae5a5 fix: stabilize agent and skill ordering in prompt descriptions (#18261)
Co-authored-by: Aiden Cline <aidenpcline@gmail.com>
Co-authored-by: Aiden Cline <63023139+rekram1-node@users.noreply.github.com>
2026-03-19 15:04:03 -05:00
James Long b9929cc644 Fix base64Decode import in workspaces.spec.ts (#18274) 2026-03-19 15:38:54 -04:00
James Long 159096c4d5 fix(core): disable chunk timeout by default (#18264) 2026-03-19 14:30:08 -04:00
opencode-agent[bot] ccd4d75ba4 chore: generate 2026-03-19 17:52:50 +00:00
James Long 32a14ba2ea fix(core): use a queue to process events in event routes (#18259) 2026-03-19 13:51:14 -04:00
opencode-agent[bot] d2beddb249 chore: generate 2026-03-19 16:16:29 +00:00
Aiden Cline d210d67f1e ignore: revert 3 commits that broke dev branch (#18260) 2026-03-19 11:15:07 -05:00
Kit Langton 35dffce18d fix forked prompt attachments losing file parts (#17815) 2026-03-19 12:00:32 -04:00
Shoubhit Dash 7d4b36643a fix(app): show review on the empty session route (#18251) 2026-03-19 19:51:32 +05:30
opencode-agent[bot] b32c51b146 chore: generate 2026-03-19 14:00:32 +00:00
Shoubhit Dash 1725f7bb2e feat: add git-backed session review modes (#17961) 2026-03-19 19:29:29 +05:30
Brendan Allan c3ec0622de app: fix workspace flicker when switching directories (#18207)
Co-authored-by: Shoubhit Dash <shoubhit2005@gmail.com>
2026-03-19 19:29:14 +05:30
Brendan Allan ec90203990 electron: lazily read updater enabled 2026-03-19 21:47:47 +08:00
OpeOginni 6d61ebeff8 fix(desktop): remote server switching (#17214)
Co-authored-by: Brendan Allan <git@brendonovich.dev>
2026-03-19 13:32:11 +00:00
Andrew Maguire 50ccbaa571 fix(app): ignore repeated Enter submits in prompt input (#18148)
Co-authored-by: Shoubhit Dash <shoubhit2005@gmail.com>
2026-03-19 11:53:44 +00:00
opencode-agent[bot] afdc427871 chore: generate 2026-03-19 04:46:39 +00:00
Dax a84103459a anthropic legal requests (#18186) 2026-03-19 04:45:24 +00:00
Aiden Cline 6a9ff35baf feat: integrate multistep auth flows into desktop app (#18103) 2026-03-19 13:47:51 +10:00
Kit Langton ed45bd6de1 fix(session): preserve tagged error messages (#18165) 2026-03-18 20:36:53 -04:00
Frank fd5599bd87 zen: add mimo pro/omni models 2026-03-18 20:28:41 -04:00
opencode-agent[bot] a241f5ae26 chore: update nix node_modules hashes 2026-03-19 00:08:27 +00:00
opencode-agent[bot] a65004283f chore: update nix node_modules hashes 2026-03-19 00:07:30 +00:00
Luke Parker fcedc54b02 fix: restore recent test regressions and upgrade effect beta (#18158) 2026-03-19 09:54:01 +10:00
Kit Langton c325ac5b5b feat(filesystem): add AppFileSystem service, migrate Snapshot (#18138) 2026-03-18 19:52:43 -04:00
opencode-agent[bot] a8274af78b chore: generate 2026-03-18 23:45:03 +00:00
Kit Langton ae15341ffe chore: type Provider.list() as Record<ProviderID, Info>, delete dead code (#18123) 2026-03-18 19:43:12 -04:00
opencode-agent[bot] 2e4326bb36 chore: update nix node_modules hashes 2026-03-18 23:03:55 +00:00
Luke Parker 2728950929 fix(windows): use cross-spawn for shim-backed commands (#18010) 2026-03-19 08:49:16 +10:00
Aiden Cline 6d979838b6 tweak: remove unnecessary parts from the fallback system prompt (#18140) 2026-03-18 17:27:47 -05:00
Frank dd43bafeb0 docs: update go models 2026-03-18 17:48:39 -04:00
Frank 8cdff61352 fix: docs 2026-03-18 16:30:33 -04:00
Frank b8795208f0 zen: minimax m2.7 2026-03-18 14:30:55 -04:00
Frank 651e672db3 zen: minimax m2.7 2026-03-18 14:15:00 -04:00
opencode-agent[bot] 4af0e6d5d2 chore: generate 2026-03-18 17:37:40 +00:00
Kit Langton 05f98c0e42 refactor(effect): unify service namespaces and align naming (#18093) 2026-03-18 13:34:36 -04:00
Aiden Cline 5ece9ea6a1 feat: integrate support for multi step auth flows for providers that require additional questions (#18035) 2026-03-18 11:36:19 -05:00
Aiden Cline 3a89645257 tweak: update gpt subscription model list (#18101) 2026-03-18 10:51:39 -05:00
Frank 5c21abc6c4 zen: fix routing non OC traffic 2026-03-18 10:59:56 -04:00
OpeOginni 55cb0a2ab0 fix(desktop): fix error handling by adding errorName function to identify NotFoundError rather than statusCode (#17591) 2026-03-18 19:27:56 +05:30
David Hill 2952da2736 tweak(ui): theme overrides (#17958) 2026-03-18 19:26:32 +05:30
David Hill 40792c96c7 tui: make the title bar search easier to scan without a redundant icon 2026-03-18 13:52:57 +00:00
David Hill ab8bd02a48 Revert "tui: clean up search button in session header by removing magnifying glass icon and excess padding"
This reverts commit b22cc3eac2.
2026-03-18 13:52:36 +00:00
David Hill b22cc3eac2 tui: clean up search button in session header by removing magnifying glass icon and excess padding 2026-03-18 13:49:58 +00:00
opencode-agent[bot] 486e797f81 chore: generate 2026-03-18 12:58:46 +00:00
OpeOginni 2499e69b88 docs(cli): update experimental TY LSP flag description for clarity across multiple languages (#14770) 2026-03-18 18:27:42 +05:30
Brendan Allan 3a1f2f7905 app: remove debug text 2026-03-18 17:02:23 +08:00
Brendan Allan d8199b91d7 app: replace autoselect effects with single resource 2026-03-18 17:01:38 +08:00
Brendan Allan a1353899bc app: initialize command catalog more efficiently
cuts down load times by like 30-50%
2026-03-18 14:46:53 +08:00
Frank b5503f1c86 zen: gpt 5.4 mini and nano 2026-03-18 02:12:30 -04:00
Johannes Loher ca7cb89cb0 fix(core): detect vLLM context overflow errors (#17763)
Co-authored-by: Aiden Cline <63023139+rekram1-node@users.noreply.github.com>
2026-03-17 23:52:16 -05:00
Frank 5cc809edcd wip: zen 2026-03-17 23:31:14 -04:00
Frank d4c69eec62 wip: zen 2026-03-17 22:50:54 -04:00
Ryan Vogel 23791c6657 feat(enterprise): contact form now pushes to salesforce 🙄 (#17964)
Co-authored-by: slickstef11 <stefan@wundergraph.com>
Co-authored-by: Frank <frank@anoma.ly>
2026-03-17 22:43:43 -04:00
opencode-agent[bot] 855a0d72a2 chore: generate 2026-03-18 02:01:02 +00:00
Kit Langton 2a6909cd07 refactor(truncation): effectify TruncateService, delete Scheduler (#17957) 2026-03-17 21:59:54 -04:00
Ariane Emory 8f3cb8b609 fix: Add apply_patch to EDIT_TOOLS filter (#18009) 2026-03-17 20:11:42 -05:00
opencode-agent[bot] 4cee904375 chore: generate 2026-03-18 01:05:16 +00:00
Kit Langton 0782c757be refactor(snapshot): effectify SnapshotService (#17878) 2026-03-17 21:04:16 -04:00
Kit Langton 90f66d356d add prompt schema validation debug logs (#17812) 2026-03-17 19:18:16 -04:00
Frank 7afb3e3de5 wip: zen 2026-03-17 19:06:22 -04:00
Frank edd365a417 zen: add missing model lab names 2026-03-17 18:41:38 -04:00
Frank ea856eb472 zen: error logging 2026-03-17 16:53:10 -04:00
David Hill 96ecc010bc tweak(ui): add an empty state to the sidebar when no projects (#17971)
Co-authored-by: Shoubhit Dash <shoubhit2005@gmail.com>
2026-03-17 19:54:14 +00:00
Frank eca94bcba5 wip: zen 2026-03-17 15:00:44 -04:00
Frank 7cb5dc27eb zen: deprecate gemini 3 pro 2026-03-17 12:31:54 -04:00
OpeOginni a5f0b7be4e docs: mark tools config as deprecated (#17951) 2026-03-17 10:07:35 -05:00
Shoubhit Dash b21adc16ee fix: inline review comment submit and layout (#17948) 2026-03-17 19:54:20 +05:30
Brendan Allan 728d8c72df app: inherit owner when creating prompt session 2026-03-17 19:47:06 +08:00
opencode-agent[bot] 8e8276dfca chore: generate 2026-03-17 11:15:35 +00:00
Luke Parker 1ed580cef1 fix(app): avoid prompt tooltip Switch on startup (#17857) 2026-03-17 06:14:30 -05:00
opencode-agent[bot] 666ad5b9b2 chore: generate 2026-03-17 03:47:33 +00:00
Kyle Altendorf 8d8c2d645c docs: add describe annotation to snapshot config field (#17861)
Co-authored-by: Aiden Cline <63023139+rekram1-node@users.noreply.github.com>
2026-03-16 22:46:09 -05:00
Aiden Cline 2dd6e169a1 chore: denounce ai spammer (#17901) 2026-03-16 22:38:15 -05:00
Luke Parker 80358a80f7 test(app): deflake slash terminal toggle flow (#17881) 2026-03-17 12:55:58 +10:00
Luke Parker 1a7c45c770 test(opencode): deflake file and tool timing (#17859) 2026-03-17 00:49:04 +00:00
Kyle Altendorf 31f5c3eb93 fix(tui): check for selected text instead of any selection in dialog escape handler (#16779) 2026-03-17 10:25:03 +10:00
opencode-agent[bot] 47e83d74a9 chore: update nix node_modules hashes 2026-03-17 00:05:19 +00:00
opencode-agent[bot] 9cdef4e301 chore: update nix node_modules hashes 2026-03-16 23:54:30 +00:00
opencode-agent[bot] 508f5def47 chore: generate 2026-03-16 23:52:10 +00:00
Kit Langton cbb2e9b0f4 refactor(skill): effectify SkillService as scoped service (#17849) 2026-03-16 23:51:07 +00:00
AbigailJixiangyuyu 4c056c026d fix(windows): restore /editor support on Windows (#17146) 2026-03-17 08:11:02 +10:00
Aiden Cline fb33a71539 fix: github copilot enterprise integration (#17847) 2026-03-16 17:05:14 -05:00
opencode-agent[bot] 7256de81d3 chore: generate 2026-03-16 20:19:50 +00:00
Kit Langton 3355d71a20 refactor(file): effectify FileService as scoped service (#17845) 2026-03-16 16:18:39 -04:00
opencode-agent[bot] 036f3dc22e chore: generate 2026-03-16 19:59:49 +00:00
Kit Langton c3de254735 refactor(format): effectify FormatService as scoped service (#17675) 2026-03-16 15:58:36 -04:00
opencode-agent[bot] febd77140d chore: generate 2026-03-16 18:24:21 +00:00
Kit Langton 184fc0b796 refactor(file-time): effectify FileTimeService with Semaphore locks (#17835) 2026-03-16 18:23:13 +00:00
opencode-agent[bot] 3831fdaac4 chore: generate 2026-03-16 18:00:18 +00:00
Kit Langton 9edca88956 fix+refactor(vcs): fix HEAD filter bug and effectify VcsService (#17829) 2026-03-16 13:59:11 -04:00
opencode-agent[bot] 387cb0d2d2 chore: generate 2026-03-16 17:19:44 +00:00
Kit Langton 6696517665 stack: effectify-file-watcher-service (#17827) 2026-03-16 13:18:40 -04:00
opencode-agent[bot] fbfb2fc514 chore: generate 2026-03-16 16:56:12 +00:00
Kit Langton c4ae100b70 refactor(instance): move scoped services to LayerMap (#17544) 2026-03-16 12:55:14 -04:00
DS 0d9fe65a58 fix(opencode): apply message transforms during compaction (#17823) 2026-03-16 11:32:53 -05:00
Johannes Loher 3202268123 fix(core): consider code: context_length_exceeded as context overflow in API call errors (#17748) 2026-03-16 10:25:24 -05:00
Michal Šlesár 0a292ad568 fix(app): agent switch should not reset thinking level (#17470) 2026-03-16 19:43:29 +05:30
Kit Langton 70d3e316b3 fix(cli): scope active org labels to the active account (#16957) 2026-03-16 10:01:42 -04:00
Shoubhit Dash d8dc149251 Wrap question option descriptions instead of truncating (#17782) 2026-03-16 11:29:18 +00:00
Luke Parker 3a91561593 fix(ci): workaround by using hoisted Bun linker on Windows (#17751) 2026-03-16 08:39:06 +00:00
Luke Parker 157f5755ac fix(opencode): teach Kit's test what an ID is (#17745) 2026-03-16 18:08:27 +10:00
Jason Quense b04934aa25 fix(opencode): preserve prompt tool enables with empty agent permissions (#17064)
Co-authored-by: jquense <jquense@ramp.com>
2026-03-15 23:01:46 -05:00
opencode 575159f225 release: v1.2.27 2026-03-16 02:33:48 +00:00
Aiden Cline 02f3ba0600 fix: vcs watcher if statement (#17673) 2026-03-15 19:20:39 -05:00
Erik Engervall 393aa80cae docs: Add opencode-firecrawl to ecosystem documentation (#17672) 2026-03-15 18:56:24 -05:00
Frank 57f814c579 zen: update claude prices 2026-03-15 10:54:40 -04:00
David Hill 382c63bb3f tweak(ui): remove open label (#17512) 2026-03-15 08:25:40 -05:00
Orlando Ascanio 5f32c5f8a0 docs(es): fix Spanish intro page translation, grammar, and terminology (#17563) 2026-03-15 08:22:32 -05:00
Kit Langton b216fd0062 chore(permission): delete legacy permission module (#17534) 2026-03-14 20:56:52 -05:00
Kit Langton 7c49041c37 fix(question): clean up pending entry on abort (#17533) 2026-03-15 00:49:49 +00:00
Sebastian ba8ff3a7b8 remove sighup exit (#17254) 2026-03-15 00:52:28 +01:00
opencode-agent[bot] 8e49012eec chore: generate 2026-03-14 18:29:06 +00:00
Kit Langton 90618eda13 refactor(permission): effectify PermissionNext + fix InstanceState ALS bug (#17511) 2026-03-14 18:28:00 +00:00
Shoubhit Dash 72fed20caa fix(app): handle multiline web paste in prompt composer (#17509) 2026-03-14 22:51:45 +05:30
Kit Langton 641b426f7b refactor(schema): inline branded ID schemas (#17504) 2026-03-14 16:14:46 +00:00
opencode-agent[bot] cab828c262 chore: generate 2026-03-14 15:59:01 +00:00
Kit Langton 4df2577034 refactor(question): effectify QuestionService (#17432) 2026-03-14 11:58:00 -04:00
Aiden Cline a2f522c8c5 tweak: ensure that compaction message is tracked as agent initiated (#17431) 2026-03-14 10:46:24 -05:00
James Long 726caa9bd2 fix(core): increase default chunk timeout from 2 min to 5 min (#17490) 2026-03-14 14:27:06 +00:00
Marcus Schiesser 53e8eccbf2 fix(ui): prevent long filenames from overlapping actions (#17151) 2026-03-13 16:17:15 -05:00
Michael Dwan 3ee10d49a5 fix(opencode): lost sessions across worktrees and orphan branches (#16389)
Co-authored-by: Aiden Cline <63023139+rekram1-node@users.noreply.github.com>
2026-03-13 15:51:55 -04:00
David Hill 3e4f676789 tui: update compaction status message to use Session instead of History across all languages
The compaction message now correctly indicates the current session was compacted rather than the entire history, making it clearer to users which conversation data was optimized.
2026-03-13 16:33:01 +00:00
opencode bc499c9aeb release: v1.2.26 2026-03-13 16:32:53 +00:00
Adam a65fb9a7a9 fix(app): model selection persist by session (#17348) 2026-03-13 11:05:08 -05:00
David Hill 4a931d8a4f fix(app): polish prompt composer controls (#17388) 2026-03-13 10:48:10 -05:00
Adam 9146b837b1 fix(app): sidebar sync 2026-03-13 10:47:45 -05:00
David Hill ee7a5685bd tweak(ui): use new-session icon in sidebar buttons 2026-03-13 10:18:08 -05:00
David Hill e67b88cca2 fix(app): avoid clipping new session during sidebar anim 2026-03-13 10:18:03 -05:00
David Hill 170e5777c2 fix(app): animate titlebar controls on sidebar open 2026-03-13 10:17:56 -05:00
David Hill 524f5de7c2 fix(app): restore sidebar dash and sync session spinner colors (#17384) 2026-03-13 10:08:23 -05:00
Kit Langton 39cee82010 feat(schema): scaffold effect-to-zod bridge (#17273) 2026-03-13 10:59:57 -04:00
Adam 1fefd34c54 fix(app): fork should copy prompt into new session (#17375) 2026-03-13 09:59:11 -05:00
Jack fd986f015a fix(ui): force wasm highlighter for markdown code blocks (#17373) 2026-03-13 09:57:14 -05:00
David Hill 03069399bc fix(app): sidebar spacing + session list spinner transition (#17355) 2026-03-13 09:19:02 -05:00
Adam 4b5fd4683a fix(app): terminal cloning without retry (#17354) 2026-03-13 08:56:48 -05:00
Adam 7e0a596cf0 fix(app): scroll falls behind prompt input 2026-03-13 08:39:42 -05:00
Adam e43f0ff375 fix(app): tooltip quirks 2026-03-13 08:38:32 -05:00
Adam 052e3fecdf fix(app): todo spacing 2026-03-13 07:43:50 -05:00
Adam a559ef332b fix(app): better optimistic prompt submit (#17337) 2026-03-13 07:38:03 -05:00
Shoubhit Dash e7bccd6d12 fix(opencode): serialize config bun installs (#17342) 2026-03-13 17:58:00 +05:30
Adam 9b5acb0919 fix(app): oc-2 went too dark 2026-03-13 07:25:42 -05:00
Adam ac0640f4ca fix(app): support text attachments (#17335) 2026-03-13 06:58:24 -05:00
Adam 01dea97657 chore(app): i18n sync (#17283) 2026-03-13 06:48:38 -05:00
Adam cff676ae63 chore: cleanup (#17284) 2026-03-13 06:27:58 -05:00
Shoubhit Dash 0e3cb695d5 perf(app): use cursor session history loading (#17329) 2026-03-13 16:43:41 +05:30
David Hill 440a8d9290 Remove prompt mode toggle (#17216) 2026-03-13 05:38:34 -05:00
opencode-agent[bot] 864e46215e chore: generate 2026-03-13 10:19:52 +00:00
Shoubhit Dash 984e0b66ad perf(server): paginate session history (#17134) 2026-03-13 15:48:43 +05:30
Adam d62c4c41fe fix(app): simplify themes (#17274) 2026-03-13 10:12:58 +00:00
Frank 26c12a7898 go: upi pay 2026-03-13 03:24:33 -04:00
Aiden Cline b9fc95af48 chore: cleanup migrate from global code (#17292) 2026-03-12 23:54:11 -05:00
Michael Dwan f02ea4d115 fix(opencode): sessions lost after git init in existing project (#16814)
Co-authored-by: Aiden Cline <63023139+rekram1-node@users.noreply.github.com>
2026-03-12 23:18:59 -05:00
Luke Parker bf6b51e4aa fix(e2e): fail fast on config dependency installs (#17280) 2026-03-13 14:08:51 +10:00
Adam 11a0607d93 fix(app): list item background colors 2026-03-12 22:23:51 -05:00
Adam 11ef4651a4 feat(app): missing themes (#17275) 2026-03-12 22:21:02 -05:00
Tom Ryder 16edfe662d fix: filter empty content blocks for Bedrock provider (#14586) 2026-03-12 22:13:09 -05:00
opencode-agent[bot] 2327da1c18 chore: generate 2026-03-13 02:33:45 +00:00
Kit Langton d3b47c2390 fix(cli): hide console command from help output (#17277) 2026-03-12 22:22:16 -04:00
Luke Parker 8ea7713f54 fix(app): stabilize todo dock e2e with composer probe (#17267) 2026-03-13 12:21:50 +10:00
opencode-agent[bot] 2ebfc38700 chore: generate 2026-03-13 02:10:27 +00:00
Kit Langton 35f8e9ca55 refactor(provider): effectify ProviderAuthService (#17227) 2026-03-13 02:08:37 +00:00
Brendan Allan 9175eeca8f desktop: multi-window support in electron (#17155) 2026-03-13 09:18:27 +08:00
Kit Langton 9077726a47 feat(cli): add console account subcommands (#17265) 2026-03-13 00:56:40 +00:00
Kit Langton 4a4b0edc48 refactor(auth): effectify AuthService (#17212) 2026-03-12 20:43:24 -04:00
Aiden Cline d318add4a0 tweak: rm openrouter warning (#17259) 2026-03-12 19:42:31 -05:00
Luke Parker 0ae4558ce9 fix(app): increase CI e2e workers (#17263) 2026-03-13 10:15:34 +10:00
Kit Langton a14e43828f reorder provider list in providers login (#17262) 2026-03-13 00:09:30 +00:00
Adam 68fc806548 feat(app): interruption state 2026-03-12 19:07:23 -05:00
Luke Parker f6c30b85cf fix(ci): keep test runs on dev (#17260) 2026-03-13 09:54:34 +10:00
opencode 2a959e034e release: v1.2.25 2026-03-12 23:34:11 +00:00
Frank 9f2549fe7e zen: handle cache key 2026-03-12 19:10:58 -04:00
Adam 8607793180 fix(app): sidebar re-rendering too often 2026-03-12 16:27:15 -05:00
Adam c34e94b4f5 fix(app): task error state 2026-03-12 16:25:49 -05:00
Adam 9e4fa3c2c7 fix(app): message loading 2026-03-12 16:25:48 -05:00
Aiden Cline 4178addbca fix: if server password exists, use basic auth for plugin client by default (#17213) 2026-03-12 15:41:46 -05:00
Adam 21ee9d3500 feat(app): follow-up behavior (#17233) 2026-03-12 20:17:36 +00:00
Adam 618e35dec7 fix(app): optimistic revert/restore 2026-03-12 15:04:27 -05:00
Adam 0f31266217 feat(app): AMOLED theme 2026-03-12 14:11:22 -05:00
Adam 7964158f5a fix(app): not loading message nav 2026-03-12 13:33:17 -05:00
David Hill 9dbe0d1016 fix(app): titlebar cleanup (#17206) 2026-03-12 18:26:50 +00:00
Frank 7450452ecd zen: fix nemotron issue 2026-03-12 14:17:36 -04:00
Adam 8a09348b2d chore: cleanup (#17197) 2026-03-12 11:32:05 -05:00
Adam 7f4314d0a9 feat: session load perf (#17186) 2026-03-12 11:31:52 -05:00
Adam cbfdbad4f0 feat(app): better themes (#16889) 2026-03-12 10:35:23 -05:00
opencode-agent[bot] d4bd1d430d chore: update nix node_modules hashes 2026-03-12 15:07:54 +00:00
Aiden Cline c7cc49da66 fix: non openai azure models that use completions endpoints (#17128) 2026-03-12 10:05:00 -05:00
Kit Langton 423a0b25a9 refactor(import): use .parse() at boundaries instead of manual .make() (#17106) 2026-03-12 10:52:20 -04:00
opencode-agent[bot] a8a1b40406 chore: generate 2026-03-12 14:49:22 +00:00
Kit Langton 82307f8a45 refactor(provider): flow branded ProviderID/ModelID through internal signatures (#17182) 2026-03-12 14:48:17 +00:00
Wang Siyuan aee9982537 docs: clarify subagent session navigation keybinds (#16455) 2026-03-12 09:45:46 -05:00
Adam ace51ae703 chore: cleanup (#17184) 2026-03-12 08:52:51 -05:00
max tomashevsky a0e74f99c7 fix(web): fix broken mobile sidebar (in workflows mode) sizing issue by adding flex-1 (#17055) 2026-03-12 08:46:41 -05:00
Adam e4bb560e99 fix(app): terminal animation 2026-03-12 08:43:25 -05:00
Adam f47f1871c2 chore: cleanup 2026-03-12 08:41:22 -05:00
opencode-agent[bot] 7ae87da35a chore: generate 2026-03-12 13:28:46 +00:00
Kit Langton 36aee4908f feat(id): brand ProviderID and ModelID (#17110) 2026-03-12 09:27:52 -04:00
Adam cb35c58c45 fix(app): sidebar quirks 2026-03-12 07:51:31 -05:00
Adam 7c1e2a6df4 chore: cleanup (#17115) 2026-03-12 12:26:43 +00:00
opencode-agent[bot] 4a100d6b59 chore: update nix node_modules hashes 2026-03-12 08:26:49 +00:00
Brendan Allan 54adc3111e refactor(desktop): rework default server initialization and connection handling (#16965) 2026-03-12 08:10:52 +00:00
opencode-agent[bot] f58ccb50ac chore: generate 2026-03-12 07:36:35 +00:00
Luke Parker 035e39752e Fix terminal e2e flakiness with a real terminal driver (#17144) 2026-03-12 17:35:26 +10:00
OpeOginni 530d45695d fix(desktop): set default WebSocket username and prevent repeated calling of terminal spawn properly closing the terminal (#17061) 2026-03-12 14:48:44 +08:00
Luke Parker 7bd3d7d03f fix(electron): theme Windows titlebar overlay (#16843)
Co-authored-by: Brendan Allan <brendonovich@outlook.com>
2026-03-12 16:38:56 +10:00
Luke Parker 46c9443913 fix(desktop-electron): fix resource loading under file:// protocol (#17125) 2026-03-12 12:19:44 +08:00
opencode-agent[bot] b4f2ba4ca9 chore: generate 2026-03-12 03:56:04 +00:00
Luke Parker 411fdfc405 fix(app): guard comment accessor in message timeline (#17126) 2026-03-12 13:55:16 +10:00
Dax Raad cdb4e87872 Merge remote-tracking branch 'origin/dev' into dev 2026-03-11 23:24:38 -04:00
Dax Raad bd1dbc02db core: remove external sourcemap generation to reduce build artifacts 2026-03-11 23:24:26 -04:00
Luke Parker ec4b4dc0c3 fix(ci): use dynamic bun cache path for cross-platform support (#17120) 2026-03-12 03:19:28 +00:00
opencode-agent[bot] 49de3431b3 chore: generate 2026-03-12 02:04:26 +00:00
Luke Parker 99ca8955b6 fix(e2e): re-focus prompt after terminal opens in slash-terminal test (#17113) 2026-03-12 12:03:38 +10:00
opencode-agent[bot] 78b0b92f2f chore: generate 2026-03-12 01:50:44 +00:00
Kit Langton a0e83f2c5f feat(id): brand PermissionID, PtyID, QuestionID, and ToolID (#17042) 2026-03-12 01:49:57 +00:00
opencode-agent[bot] 74984fdfc6 chore: generate 2026-03-12 00:26:05 +00:00
Luke Parker 8c6ddb0afe feat(windows): add arm64 release targets for cli and desktop (#16696) 2026-03-12 00:25:09 +00:00
opencode-agent[bot] 2eb28003d6 chore: generate 2026-03-11 23:41:43 +00:00
Kit Langton 2a225d7c72 feat(id): brand PartID through Drizzle and Zod schemas (#16966) 2026-03-11 23:40:50 +00:00
opencode-agent[bot] dfb60d16f3 chore: generate 2026-03-11 23:31:07 +00:00
Kit Langton b9eaabe80b feat(id): brand WorkspaceID through Drizzle and Zod schemas (#16964) 2026-03-11 23:30:17 +00:00
John Mylchreest 86b5c7dd61 fix: resolve symlinks in Instance cache to prevent duplicate contexts (#16651)
Co-authored-by: LukeParkerDev <10430890+Hona@users.noreply.github.com>
2026-03-11 23:26:54 +00:00
opencode-agent[bot] 0f854235ee chore: generate 2026-03-11 23:17:42 +00:00
Kit Langton 4401c08142 feat(id): brand SessionID through Drizzle and Zod schemas (#16953) 2026-03-11 23:16:56 +00:00
Frank 07da695d86 wip: zen 2026-03-11 19:00:05 -04:00
Frank ecca6985ac wip: zen 2026-03-11 18:50:49 -04:00
Frank 27d7b71393 docs: go pricing 2026-03-11 18:09:41 -04:00
Frank 3a5dc9c7f8 docs: zen update models 2026-03-11 18:09:41 -04:00
Frank 5feba1f51d wip: zen 2026-03-11 18:09:41 -04:00
Frank d64a6fdb28 go: dashboard design 2026-03-11 18:09:41 -04:00
Frank 61330dfb8a go: first month discount 2026-03-11 18:09:41 -04:00
Frank 734aff9848 zen: update discount copy on lander 2026-03-11 18:09:41 -04:00
Frank 9e554fe940 zen: add alipay for adding balance 2026-03-11 18:09:41 -04:00
Frank 928d025f14 zen: add alipay for go sub 2026-03-11 18:09:41 -04:00
Frank cfe86a403f zen: add Go page 2026-03-11 18:09:41 -04:00
Frank 93c73eae7a zen: add usage section 2026-03-11 18:09:40 -04:00
Frank a925d7293b zen: update usage graph on landing page 2026-03-11 18:09:40 -04:00
Frank 1044c92aec zen: update header 2026-03-11 18:09:40 -04:00
Dax Raad 27d07c7e23 core: restore plugin serverUrl getter so plugins can connect to local server 2026-03-11 17:41:51 -04:00
Adam cb257cf5ce feat(app): restore to message and fork session (#17092) 2026-03-11 21:34:48 +00:00
Adam f814e7a828 chore: skip test 2026-03-11 16:21:04 -05:00
Noam Bressler c717c8c67e fix: re-enable snapshot in acp (#14918) 2026-03-11 16:18:40 -05:00
Adam 827c26921a chore: fix test 2026-03-11 16:11:02 -05:00
Aiden Cline 88a6d5445c tweak: adjust skill presentation to be a little less token heavy (#17098) 2026-03-11 16:03:15 -05:00
Adam 37b095bba7 chore: fix test 2026-03-11 16:02:11 -05:00
Kit Langton 9ef3ec79cd feat(id): brand ProjectID through Drizzle and Zod schemas (#16948) 2026-03-11 16:44:26 -04:00
Adam 04c61aef6f fix(app): todos not clearing 2026-03-11 14:42:34 -05:00
Chris Yang 711b84442b fix(app): skip editor reconcile during IME composition (#17041) 2026-03-11 13:40:06 -05:00
Kit Langton 65569dbdb1 refactor(account): tighten effect-based account flows (#17072) 2026-03-11 18:18:58 +00:00
Johannes Loher a34083a54e fix(core): read stdout and stderr in PackageRegistry.info before waiting for the process to exit (#16998) 2026-03-11 13:10:45 -05:00
Adam 2034d916b9 chore(app): simplify review pane (#17066) 2026-03-11 12:24:51 -05:00
xinxin d7707e5bae docs(providers): clarify npm choice for chat vs responses APIs (#16974)
Co-authored-by: wangxinxin <xinxin.wang@pharmbrain.com>
2026-03-11 10:35:16 -05:00
Aiden Cline 250925fca8 tweak: adjust way skills are presented to agent to increase likelyhood of skill invocations. (#17053) 2026-03-11 10:24:55 -05:00
Shoubhit Dash e1ccd985c6 perf(app): trim session render work (#16987) 2026-03-11 18:19:17 +05:30
Filip 053ae6ccc9 fix(app): make error tool card respect settings (#17005) 2026-03-11 14:52:33 +05:30
Brendan Allan b534031e0d ci: setup node in tauri build 2026-03-11 16:09:17 +08:00
opencode-agent[bot] 4970adae6f chore: generate 2026-03-11 03:34:02 +00:00
Luke Parker 52e829aa32 fix(electron): hide Windows background consoles (#16842)
Co-authored-by: Brendan Allan <git@brendonovich.dev>
2026-03-11 13:33:06 +10:00
SOUMITRA-SAHA 3c48a076ce fix: add GOOGLE_VERTEX_LOCATION env var support for Vertex AI (#16922)
Co-authored-by: Aiden Cline <63023139+rekram1-node@users.noreply.github.com>
2026-03-10 22:32:39 -05:00
Jack 8fb936ecc7 feat(web): use Feishu for Chinese community links (#16908)
Co-authored-by: Frank <frank@anoma.ly>
2026-03-11 11:07:13 +08:00
Kit Langton 4dc6e6fc99 fix(account): resilient orgs fetch (#16944) 2026-03-11 00:39:07 +00:00
Dax Raad 1c7ae1f24a sync 2026-03-10 20:13:56 -04:00
Adam d7b497a0ce chore(app): fix tests 2026-03-10 19:03:44 -05:00
Aiden Cline 9e441a3ec3 chore: kill old copilot 403 message that was used for old plugin migration (#16904) 2026-03-10 16:20:41 -05:00
Dax Raad fad2b23698 ci: cancel duplicate workflow runs and add read permissions
- Add concurrency settings to cancel outdated runs when new commits are pushed
- Add contents: read permission for security hardening
- Remove redundant required job that checked test results
2026-03-10 17:17:11 -04:00
Frank a06e67fdfc zen: raise limit 2026-03-10 15:22:02 -04:00
David Hill 7524ce20f4 feat(ui): restyle Card and improve tool error cards (#16888)
Co-authored-by: Adam <2363879+adamdotdevin@users.noreply.github.com>
2026-03-10 13:52:32 -05:00
Frank de8b9215fb zen: raise limit 2026-03-10 14:40:18 -04:00
Dax Raad a3acc03f22 ci: exclude draft PRs from beta labeling process to prevent unfinished work from being included in releases 2026-03-10 14:08:55 -04:00
Dax Raad 3ee64041c5 ci: install setuptools to prevent Python distutils errors during dependency installation 2026-03-10 14:08:38 -04:00
Adam 3b090b22e8 chore: cleanup 2026-03-10 13:00:14 -05:00
Adam 7e290fd1b8 fix(app): terminal jank 2026-03-10 13:00:14 -05:00
Adam 1fdfc6ad32 fix(app): terminal focus issues and jank 2026-03-10 13:00:14 -05:00
opencode-agent[bot] c7f573b041 chore: update nix node_modules hashes 2026-03-10 17:14:55 +00:00
Dax 9ab72a07ed Fix ESM imports for @opencode-ai/plugin (#16916) 2026-03-10 13:11:36 -04:00
opencode-agent[bot] b407d86f88 chore: generate 2026-03-10 16:56:30 +00:00
Dax f56e6684a6 core: make account login upgrades safe while adding multi-account workspace auth (#15487)
Co-authored-by: Kit Langton <kit.langton@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 12:53:47 -04:00
Adam 540acca843 fix(core): don't permit access to system directories (#16891) 2026-03-10 11:32:05 -05:00
Aiden Cline 2a6964e3e1 chore: rekram1-node is no longer on vacation (#16905) 2026-03-10 10:27:04 -05:00
opencode-agent[bot] c992241079 chore: generate 2026-03-10 15:14:46 +00:00
James Long df704db089 feat(core): allow passing workspaceID into session create endpoint (#16798) 2026-03-10 11:12:51 -04:00
James Long 01233eab2e fix(core): a chunk timeout when processing llm stream (#16366) 2026-03-10 11:12:14 -04:00
James Long 03c8b44189 fix(core): make worktrees read the project id from local workspace (#16795) 2026-03-10 11:11:28 -04:00
opencode-agent[bot] 01d2dd20f9 chore: generate 2026-03-10 15:07:35 +00:00
Jérôme Benoit 565aefc073 fix(opencode): add thinking variants support for SAP AI provider (#14958)
Co-authored-by: Test <test@test.com>
Co-authored-by: Stephen Collings <stevoland@gmail.com>
2026-03-10 10:05:45 -05:00
Adam 87d5c9087f chore(app): debug window 2026-03-10 07:05:54 -05:00
opencode-agent[bot] 22b8b6e23f chore: generate 2026-03-10 11:01:22 +00:00
bhaktatejas922 2c7fa0067c docs: update opencode-morph-plugin in all language ecosystem pages (#16869) 2026-03-10 06:00:13 -05:00
opencode-agent[bot] e2edb87a8d chore: update nix node_modules hashes 2026-03-10 10:16:15 +00:00
Sebastian 6b1f91ce2d upgrade opentui to v0.1.87 (#16772) 2026-03-10 11:03:05 +01:00
opencode-agent[bot] 937d1f4565 chore: generate 2026-03-10 02:02:18 +00:00
adam jones 3910ef3ce3 fix(mcp): fix OAuth auto-connect failing on first connection (#15547)
Co-authored-by: Aiden Cline <63023139+rekram1-node@users.noreply.github.com>
2026-03-09 21:01:19 -05:00
Dax Raad 7e10f80b49 refactor(server): extract createApp function for server initialization
- Replace Server.App() with Server.Default() for internal server access
- Extract server app creation into Server.createApp(opts) for testability
- Move CORS whitelist from module-level variable to function parameter
- Update all tests to use Server.Default() instead of Server.App()
2026-03-09 17:13:52 -04:00
Adam 0a06fac8fb chore(app): dev stats 2026-03-09 15:57:24 -05:00
Adam 230e82d5a4 fix(app): terminal state corruption 2026-03-09 15:28:35 -05:00
Adam 4d591d245d chore: cleanup 2026-03-09 15:28:35 -05:00
Adam 12836be1aa chore: cleanup 2026-03-09 15:28:35 -05:00
opencode-agent[bot] 60d24b76a9 chore: generate 2026-03-09 20:15:31 +00:00
James Long fea9bc2077 fix(core): put workspace routing behind OPENCODE_EXPERIMENTAL_WORKSPACES flag (#16775) 2026-03-09 16:14:19 -04:00
opencode-agent[bot] 4f7a1faf56 chore: update nix node_modules hashes 2026-03-09 19:51:58 +00:00
opencode-agent[bot] 353dc441fe chore: update nix node_modules hashes 2026-03-09 19:49:01 +00:00
bhaktatejas922 3745f25a75 docs: update opencode-morph-fast-apply to opencode-morph-plugin in ecosystem (#16634) 2026-03-09 14:39:06 -05:00
opencode-agent[bot] a4c3be1b1a chore: generate 2026-03-09 19:31:33 +00:00
Dax Raad 887debd8fa Merge remote-tracking branch 'origin/dev' into dev 2026-03-09 15:30:15 -04:00
Dax Raad a10faea93a refactor: replace bun semver with npm semver package 2026-03-09 15:29:55 -04:00
Kyle Altendorf 4da2d0150d fix(tui): wait for model store before auto-submitting --prompt (#7476) 2026-03-09 14:22:38 -05:00
Dax 89f4344882 refactor(opencode): replace Bun shell in core flows (#16286) 2026-03-09 15:19:50 -04:00
Dax Raad c854a6917d refactor: change pathToFileURL imports from bun to url module 2026-03-09 14:52:25 -04:00
James Long 665cdf6986 fix(tui): handle error when creating a session (#16767) 2026-03-09 12:13:32 -04:00
Stephen Collings e7796d4973 fix: Multiple jdtls LSPs eating memory in java monorepos (#12123) 2026-03-09 16:09:43 +00:00
opencode bc8f94a5ff release: v1.2.24 2026-03-09 16:09:34 +00:00
Adam 53ecb769dc fix(app): scroll jitter/loop 2026-03-09 10:44:02 -05:00
Dax Raad 914a2adca0 core: prevent accidental edits to migration files by restricting agent access 2026-03-09 11:25:58 -04:00
David Hill 3d941a6672 fix(app): session title turn spinner (#16764) 2026-03-09 09:46:15 -05:00
Filip 6fabb4f996 fix(app): dismiss toast notifications when questions or permissions a… (#16758) 2026-03-09 09:36:57 -05:00
Karan Handa b6484e6bdb fix(storybook): add ci build workflow (#16760) 2026-03-09 09:33:19 -05:00
James Long 1aff94d7ad feat(tui): add initial support for workspaces into the tui (#16230) 2026-03-09 10:28:04 -04:00
Armin Pašalić 4204c932d0 feat(gitlab): send context-1m-2025-08-07 beta header to enable 1M context window (#16153)
Co-authored-by: Aiden Cline <63023139+rekram1-node@users.noreply.github.com>
2026-03-09 09:22:00 -05:00
Jack 5712554c4a add copilot gpt-5.4 xhigh support (#16294) 2026-03-09 22:07:12 +08:00
opencode d13753e7c4 release: v1.2.23 2026-03-09 13:50:43 +00:00
Adam 3b59be4dd8 fix(app): remove oc-1 theme 2026-03-09 08:25:41 -05:00
David Hill 56af5f592b tui: fix sidebar workspace container sizing by adding box-border class to prevent content overflow issues 2026-03-09 13:05:43 +00:00
Adam 645ca29992 fix(app): don't animate review panel in/out 2026-03-09 07:49:11 -05:00
opencode-agent[bot] a9632aa16e chore: update nix node_modules hashes 2026-03-09 12:46:47 +00:00
Adam a267c02d2a revert(app): "STUPID SEXY TIMELINE (#16420)" (#16745) 2026-03-09 07:36:39 -05:00
Luke Parker 3ddf338d8c fix(app): sanitize workspace store filenames on Windows (#16703) 2026-03-09 20:26:53 +10:00
Yihui Khuu fd2d06459f fix(app): fix issue with scroll jumping when pressing escape in comment text area (#15374) 2026-03-09 15:29:24 +05:30
Eric Clemmons dec0a3b85f fix(opencode): pass missing auth headers in run --attach (#16097)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Shoubhit Dash <shoubhit2005@gmail.com>
2026-03-09 07:32:13 +00:00
opencode-agent[bot] 18977bf9bc docs(i18n): sync locale docs from english changes 2026-03-09 02:08:46 +00:00
Ariane Emory 9a9f0ca08c docs: add session_child_first keybinding to documentation (#16631) 2026-03-08 21:03:52 -05:00
Adam ef130a7417 feat(app): generate color palettes (#16232) 2026-03-08 19:28:58 -05:00
Dax Raad 8a26bc33cf disable fallback to free nano for small model 2026-03-08 19:27:15 -04:00
opencode 7d837b6f1c release: v1.2.22 2026-03-08 22:34:59 +00:00
Sebastian 496f96721f guard tui exit (#16640) 2026-03-08 23:14:41 +01:00
Luke Parker 7c79a5a849 fix(tui): canonicalize cwd after chdir (#16641) 2026-03-09 07:57:48 +10:00
David Hill d512909fc5 tui: fix sidebar background color when collapsed
When the sidebar was collapsed (not on mobile), the background color was showing as the stronger variant instead of matching the base background. This fixes the hover state detection so users see a consistent lighter background when the sidebar is in collapsed mode.
2026-03-08 13:34:56 +00:00
David Hill 7d903b7f34 app: suppress hover when opening project menu or right-clicking to prevent flickering 2026-03-08 13:31:18 +00:00
Shoubhit Dash 008ac7eae9 fix: trim retained desktop terminal buffers (#16583) 2026-03-08 07:50:04 -05:00
opencode-agent[bot] e8b2a58f88 chore: update nix node_modules hashes 2026-03-08 12:25:35 +00:00
Adam 21373267cf fix(app): less auto-expand/collapse 2026-03-08 07:11:15 -05:00
Adam 3b2ae9d2a1 chore: refactoring ui hooks 2026-03-08 07:11:15 -05:00
Adam 48a19c2391 fix(app): messages not loading reliably 2026-03-08 07:11:15 -05:00
Shoubhit Dash fe109b3f17 fix: prune and evict stale app session caches (#16584) 2026-03-08 07:10:00 -05:00
Shoubhit Dash 096f2c698f test: make process cwd check cross-platform (#16594) 2026-03-08 06:56:45 -05:00
Roy Bruschini 6f3c73898c docs(zen.mdx): correct Italian grammar and punctuation errors (#16590) 2026-03-08 16:40:06 +05:30
tobwen 9130c188d6 fix(opencode): avoid TTY corruption from double cleanup (#16565)
Co-authored-by: Shoubhit Dash <shoubhit2005@gmail.com>
2026-03-08 13:55:33 +05:30
Nate Williams b022adb41c fix(tui): fix broken /mcp toggling (#16431)
Co-authored-by: Shoubhit Dash <shoubhit2005@gmail.com>
2026-03-08 13:31:09 +05:30
Dax 442ecf5ee0 test: remove unused Ripgrep.search coverage (#16554) 2026-03-07 21:40:57 -05:00
David Hill bd42be52a7 Revert "tui: dock auto-accept after thinking and move Add file to bottom-left"
This reverts commit 4c457ba392.
2026-03-08 01:31:09 +00:00
David Hill b53991ee03 Revert "tui: keep model + thinking selectors beside Add file"
This reverts commit e22cd8bd4e.
2026-03-08 01:31:06 +00:00
David Hill 2db0ac25cb Revert "tui: add more editor bottom padding for prompt controls"
This reverts commit bf1e48ff8e.
2026-03-08 01:31:03 +00:00
David Hill 7585aabf0f Revert "tui: expose auto-accept as a permissions select"
This reverts commit ef0f922461.
2026-03-08 01:31:00 +00:00
David Hill 53798b2c3b Revert "tui: use text-base color for prompt selects"
This reverts commit 31745d8009.
2026-03-08 01:30:55 +00:00
David Hill d999d6d48b Revert "tui: remove prompt model/thinking/permissions selectors on dev so the composer stays simple"
This reverts commit d4eec7e5da.
2026-03-08 01:27:45 +00:00
David Hill d4eec7e5da tui: remove prompt model/thinking/permissions selectors on dev so the composer stays simple 2026-03-08 01:21:45 +00:00
David Hill aa419b050d tui: restore new-session logo on dev so users recognize OpenCode immediately 2026-03-08 01:18:42 +00:00
David Hill e02914f18a tui: revert new-session logo on dev so this UI change only ships with auto-accept-permissions 2026-03-08 01:10:52 +00:00
David Hill 86051adc9d tui: add opencode logo to new session screen so users can immediately identify the app when starting a fresh session 2026-03-08 00:59:03 +00:00
David Hill 31745d8009 tui: use text-base color for prompt selects
Select triggers in the composer now use the normal text color so model/thinking/permissions controls read consistently with the rest of the input UI.
2026-03-08 00:53:57 +00:00
David Hill ef0f922461 tui: expose auto-accept as a permissions select
Lets people explicitly choose between normal permission prompts and auto-accept while composing, without relying on an ambiguous icon state.
2026-03-08 00:53:57 +00:00
David Hill bf1e48ff8e tui: add more editor bottom padding for prompt controls
Gives typed text more breathing room above the Add file/model/thinking row so the controls don’t visually crowd what you’re writing.
2026-03-08 00:53:57 +00:00
David Hill e22cd8bd4e tui: keep model + thinking selectors beside Add file
People change models and thinking settings while composing, so keeping those controls next to the Add file button avoids hunting in the footer and reduces context switching mid-message.
2026-03-08 00:53:57 +00:00
David Hill 4c457ba392 tui: dock auto-accept after thinking and move Add file to bottom-left
Auto-accept now lives in the footer dock beside the thinking control so it stays easy to find without crowding the text box.

The Add file button moves to the bottom-left of the editor and the input gets a bit more bottom padding so the control row doesn’t overlap what you’re typing.
2026-03-08 00:53:57 +00:00
Dax Raad 9685f7dbaa test: normalize ripgrep path assertion on windows 2026-03-07 19:47:57 -05:00
opencode-agent[bot] 832c086822 chore: generate 2026-03-08 00:31:35 +00:00
Dax Raad 8330999cea test: lock in process, ripgrep, and installation helpers 2026-03-07 19:30:32 -05:00
David Hill 64858dc353 tui: revert prompt control docking
Restore the previous prompt control layout after the dock/position changes made the composer feel less familiar.

This brings auto-accept back to its prior spot and returns Add file to the previous placement.
2026-03-08 00:17:28 +00:00
David Hill ff5dbb8474 tui: dock auto-accept after thinking and move Add file to bottom-left
Auto-accept now lives in the footer dock beside the thinking control so it stays easy to find without crowding the text box.

The Add file button moves to the bottom-left of the editor and the input gets a bit more bottom padding so the control row doesn’t overlap what you’re typing.
2026-03-08 00:08:37 +00:00
Dax Raad 62fe4ae644 core: update database path test to verify correct channel-based filename
The test now validates that the database file is named according to the current installation channel (latest/beta get 'opencode.db', others get sanitized names). This ensures users' data is stored in the correct location based on their update channel.
2026-03-07 18:53:29 -05:00
Dax Raad f6c48cf6b2 core: allow beta channel to share database with stable channel 2026-03-07 18:53:29 -05:00
David Hill 64d04a91b7 tui: balance titlebar columns so center content doesn't get squeezed by long side content 2026-03-07 23:50:23 +00:00
David Hill 05362100f7 tui: align numeric displays consistently across tool outputs and diff counters using tabular numerals 2026-03-07 23:49:10 +00:00
David Hill c9533ac67a tui: center empty states vertically in session view and improve review panel messaging for projects without version control 2026-03-07 23:45:16 +00:00
Dax Raad 35e1142383 core: add OPENCODE_SKIP_MIGRATIONS flag to bypass database migrations
Allows users to skip automatic database migrations by setting the
OPENCODE_SKIP_MIGRATIONS environment variable. Useful for testing
scenarios or when manually managing database state.
2026-03-07 16:17:00 -05:00
Frank 2675680768 zen: fix graph legend 2026-03-07 14:28:36 -05:00
Adam 56ba5c7fce fix(app): review panel transition 2026-03-07 13:27:44 -06:00
opencode 29f129acbb release: v1.2.21 2026-03-07 18:00:39 +00:00
Karan Handa 9f1ab5e855 fix(storybook): restore build by mocking useLocation (#16472) 2026-03-07 09:55:43 -06:00
Eric Guo a1bb6a4047 fix(app): text-shimmer undefined length (#16475) 2026-03-07 09:53:32 -06:00
SANGWOO PARK 5b6fba32f0 fix(app): guard session-header current() against undefined when options is empty (#16478) 2026-03-07 09:51:21 -06:00
Filip 879a092d9b fix(app): preserve file tree tab on reopen + fix e2e test regressions (#16482) 2026-03-07 09:47:45 -06:00
David Hill 8cfd7c4066 tui: remove close button from project hover popover (#16403)
Co-authored-by: Adam <2363879+adamdotdevin@users.noreply.github.com>
2026-03-07 07:00:58 -06:00
Adam 792f3363ba fix(app): new session uses agent model/variant 2026-03-07 07:00:38 -06:00
Adam 38add89866 fix(app): model sticks to session 2026-03-07 06:57:00 -06:00
Adam 482538010c fix(app): all panels transition 2026-03-07 06:48:37 -06:00
Adam 28afc494ac fix(app): can't scroll files 2026-03-07 06:47:11 -06:00
Adam 1ce8b0f17f fix(app): task agent title 2026-03-07 06:03:30 -06:00
Adam 0b54f0c92a chore: update web stats 2026-03-07 05:47:47 -06:00
Adam 97a068cb7f fix(app): fix max-width on timeline 2026-03-07 05:45:30 -06:00
David Hill c67ac136d4 tui: align session empty states (#16412) 2026-03-07 05:39:43 -06:00
opencode-agent[bot] 18a9142252 chore: generate 2026-03-07 11:26:12 +00:00
Kit Langton 07121ef1a6 STUPID SEXY TIMELINE (#16420) 2026-03-07 05:25:22 -06:00
Luke Parker f83cd8f1bc test(app): share workspace slug wait helper across e2e specs (#16446) 2026-03-07 07:48:30 +00:00
Quan Ran d66fc779dc fix(opencode): preserve original line endings in 'edit' tool (#9443)
Co-authored-by: LukeParkerDev <10430890+Hona@users.noreply.github.com>
2026-03-07 07:42:54 +00:00
Nate Williams e83bc8c43c fix(tui): fix broken /export toggling (#16443) 2026-03-07 12:52:17 +05:30
Luke Parker 32deb1a227 test(app): abort sessions and wait for idle before e2e cleanup (#16439) 2026-03-07 16:33:12 +10:00
Karan Handa e8b0f38508 fix(config): point GitHub PR search tool at current repository (#16441) 2026-03-07 05:53:28 +00:00
Luke Parker c47c5ec9a0 fix(windows): git path resolution for modified files across Git Bash, MSYS2, and Cygwin (#16422) 2026-03-07 15:42:14 +10:00
opencode-agent[bot] 5d128075c1 chore: generate 2026-03-07 04:54:05 +00:00
kikuchan b95c982987 fix(pty): pty session handle leak (#15599) 2026-03-07 14:53:11 +10:00
Luke Parker 8589da78bc feat(desktop): show skill issue when snapshotting is off (#16432) 2026-03-07 04:52:04 +00:00
Luke Parker 3ca580177b fix(opencode): sanitize preview database filenames (#16430) 2026-03-07 04:34:29 +00:00
opencode-agent[bot] ed8068d156 chore: update nix node_modules hashes 2026-03-07 02:35:17 +00:00
David Hill 7a097c6325 app: fix portal positioning for sidebar menus and tooltips by removing conditional mount logic 2026-03-07 00:30:51 +00:00
Jay V c9d2ca8126 docs: update legal policies for 2026 terms refresh 2026-03-06 18:31:02 -05:00
Filip a3bc0bcf09 tests(app): e2e tests part 67 (#16406) 2026-03-06 17:08:59 -06:00
opencode-agent[bot] cb55da8f03 chore: generate 2026-03-06 22:34:25 +00:00
David Hill fdd5375bca feat(app): sidebar reveal animation, hover peek overlay, and weaker dividers (#16374)
Co-authored-by: Adam <2363879+adamdotdevin@users.noreply.github.com>
2026-03-06 16:33:34 -06:00
James Long cd70c57e99 fix(core): log stack trace when schema validation fails (#16401) 2026-03-06 17:04:22 -05:00
Dax Raad 0c1fee138a fix issue with migration 2026-03-06 16:44:49 -05:00
David Hill 507f773bca fix(app): better review/filetree empty states (#16221)
Co-authored-by: Adam <2363879+adamdotdevin@users.noreply.github.com>
2026-03-06 15:39:31 -06:00
Adam d147b7b915 chore: fix test 2026-03-06 15:27:49 -06:00
opencode-agent[bot] 524b9b9167 chore: generate 2026-03-06 19:40:36 +00:00
Shoubhit Dash eafc014be6 feat: add project git init api (#16383) 2026-03-06 13:39:50 -06:00
Alexandre Reyes Martins 4dc578b822 fix(app): enable Safari autocorrect in normal mode, disable in shell mode (#15563) 2026-03-06 22:36:27 +05:30
Adam ae93b9f16d fix(app): stale keyed show errors 2026-03-06 11:03:37 -06:00
Hoshiumi Arata 8f1b1f26b7 fix(ui): prevent unwanted key events during composition in LineCommentEditor (#16361) 2026-03-06 11:01:13 -06:00
Dax Raad 9f34ffff3d chore(storage): update drizzle and channel db handling 2026-03-06 10:58:19 -05:00
Adam c6c0d8ec04 fix(app): part type gate 2026-03-06 09:56:02 -06:00
Shoubhit Dash e38846ef43 share: speed up share loads (#16165) 2026-03-06 06:49:15 -06:00
Adam ef1cec6a9f Revert "fix(app): stale read error"
This reverts commit a27ea86940.
2026-03-06 05:52:48 -06:00
Adam 278c1d8b3e Revert "fix(app): stale keyed show errors"
This reverts commit b72468d5fc.
2026-03-06 05:52:47 -06:00
opencode-agent[bot] dc13b0275f chore: generate 2026-03-06 11:48:31 +00:00
Kirill Tregubov 57475232a3 fix(app): add english to locale matchers (#16280) 2026-03-06 05:47:39 -06:00
D c6158b508d feat: Add Vietnamese README and update all language navigation links … (#16322) 2026-03-06 05:46:53 -06:00
opencode-agent[bot] ee9e8e9e34 chore: generate 2026-03-06 10:50:00 +00:00
Luis Felipe Cordeiro Sena e41a64d035 fix(app): enable auto-accept keybind regardless of permission config (#16259) 2026-03-06 04:49:12 -06:00
opencode 2401e05023 release: v1.2.20 2026-03-06 07:29:34 +00:00
Dax 0e44e3803a fix: restore Bun stdin reads for prompt input (#16300) 2026-03-06 02:08:10 -05:00
Luke Parker aa99b73b59 fix(git): stop leaking fsmonitor daemons e.g. 60GB+ of commited memory after running tests (#16249) 2026-03-06 15:42:08 +10:00
opencode-agent[bot] f99c8c2784 chore: update nix node_modules hashes 2026-03-06 05:31:01 +00:00
Dax 46beeaa585 refactor(opencode): replace Bun.which with npm which (#15012) 2026-03-06 05:18:29 +00:00
opencode 899d08f869 release: v1.2.19 2026-03-06 04:29:10 +00:00
Sadık 5634202382 feat: add "gpt-5.4" to codex allowed models list (#16274) 2026-03-05 23:03:01 -05:00
Dax Raad 493ad25b2c refactor: replace Bun.stderr and Bun.color with Node.js equivalents 2026-03-05 22:20:16 -05:00
Dax Raad 8f6e3ad6de refactor: replace Bun.connect with net.createConnection 2026-03-05 22:17:08 -05:00
Dax Raad fbce003e15 fix: use sha1 for hash instead of unsupported xxhash3-xxh64 2026-03-05 22:12:10 -05:00
Dax Raad a289e15cb0 refactor: use node:stream/consumers for stdin reading 2026-03-05 22:08:50 -05:00
Dax Raad 1aa25a9ea3 refactor: replace Bun.stdin.text with Node.js stream reading 2026-03-05 22:04:20 -05:00
Dax Raad 25643cffc4 refactor: replace Bun.hash with Hash.fast using xxhash3-xxh64 2026-03-05 22:03:24 -05:00
Dax Raad 67827c5cb1 refactor: replace Bun.write with Filesystem.write in config files 2026-03-05 21:59:20 -05:00
Dax Raad f8c6032d3c refactor: replace Bun.write/file with Filesystem utilities in snapshot 2026-03-05 21:56:41 -05:00
Dax 9c6d6ca359 refactor: replace Bun.sleep with node timers (#15013)
publish-github-action / publish (push) Waiting to run
2026-03-05 21:54:06 -05:00
Filip a9853eae40 fix(app): stale show (#16236) 2026-03-05 18:23:48 -06:00
David Hill 548d9ed634 tui: remove keyboard shortcut tooltips from new session and new workspace buttons in the sidebar 2026-03-05 23:44:00 +00:00
Frank 463180fe3d zen: gpt 5.4 pro 2026-03-05 18:39:17 -05:00
Frank db90149ea1 ci: fix 2026-03-05 15:46:17 -05:00
Frank d5c9cb7566 zen: gpt5.3 codex spark 2026-03-05 15:40:51 -05:00
Jun ec77b3cb1a fix(console): follow-up for #13108 docs/en routing and locale cookie sync (#13608) 2026-03-05 14:31:38 -06:00
Adam 6be25b332c fix(app): load tab on open file 2026-03-05 13:40:25 -06:00
opencode-agent[bot] 054619aede docs(i18n): sync locale docs from english changes 2026-03-05 19:01:10 +00:00
Frank f8f051cdda zen: gpt5.4 2026-03-05 19:01:10 +00:00
opencode e772e618d8 release: v1.2.18 2026-03-05 19:01:03 +00:00
opencode-agent[bot] 4ccafbc0ff chore: update nix node_modules hashes 2026-03-05 15:09:14 +00:00
Dax e0127541a6 feat(tui): add onClick handler to InlineTool and Task components (#16187) 2026-03-05 15:02:30 +00:00
Adam adefbd022f chore(app): ghostty-web fork 2026-03-05 08:58:11 -06:00
Dax Raad 061001b601 ci: remove unused publishConfig that was breaking npm publishing 2026-03-05 09:45:30 -05:00
Dax Raad 42cec1212d update sdk package.json 2026-03-05 09:45:30 -05:00
Adam b72468d5fc fix(app): stale keyed show errors 2026-03-05 08:42:50 -06:00
Adam 4f4f040751 fix(app): locale error 2026-03-05 08:10:36 -06:00
Adam a27ea86940 fix(app): stale read error 2026-03-05 08:09:29 -06:00
Adam c4208ff5f7 fix(app): websearch and codesearch tool rendering 2026-03-05 08:00:42 -06:00
Adam 6dc718265a fix(app): provider settings consistency 2026-03-05 08:00:42 -06:00
Adam 11e7928ee0 fix(app): file icon stability 2026-03-05 08:00:42 -06:00
Adam 7bc431939c fix(app): file path truncation in session turn 2026-03-05 08:00:42 -06:00
Adam 7378b9487b fix(app): file icon stability 2026-03-05 08:00:41 -06:00
ismeth b1cc87e0c1 fix(app): preserve question dock state across session switches (#16173) 2026-03-05 19:05:16 +05:30
Adam f0e9fb9211 fix(app): icon jiggle 2026-03-05 07:00:21 -06:00
Adam 1398e42e38 chore(console): go page i18n 2026-03-05 06:59:04 -06:00
Adam 29e1711e6c fix(app): mod+f always opens search 2026-03-05 06:57:50 -06:00
Adam 92d9f224d1 fix(app): no delay on tooltip close 2026-03-05 06:44:11 -06:00
OpeOginni b38173c537 refactor(desktop): improve error handling and translation in server error formatting (#16171) 2026-03-05 06:28:17 -06:00
opencode-agent[bot] d109d853bc chore: generate 2026-03-05 12:27:12 +00:00
OpeOginni 4e9b789667 fix(app): improve agent selection logic passing in configured models and variants correctly (#16072) 2026-03-05 06:26:20 -06:00
Shoubhit Dash 81ff804a8d desktop: remove unnecessary macOS entitlements (#16161) 2026-03-05 05:43:21 -06:00
Brendan Allan f5b6bc0de1 desktop: new-session deeplink (#15322) 2026-03-05 09:15:14 +00:00
Brendan Allan 4db91c973d desktop-electon: handle latest version update check properly 2026-03-05 17:00:13 +08:00
opencode-agent[bot] 9d7cebafe3 chore: update nix node_modules hashes 2026-03-05 06:53:43 +00:00
Brendan Allan ef5a68543b app: prefer using useLocation instead of window.location (#15989) 2026-03-05 14:41:12 +08:00
Daniel Polito bc4aa7f5e5 feat(opencode): Adding options to auth login to skip questions (#14470)
Co-authored-by: Shoubhit Dash <shoubhit2005@gmail.com>
2026-03-05 06:16:53 +00:00
Frank 8b92f6d7aa zen: update go page 2026-03-04 22:23:22 -05:00
Anton Volkov 08cc307b4d chore: update turborepo (#16061) 2026-03-05 09:49:11 +10:00
Luke Parker fd7634ebee dont let dax touch the ui (#16060) 2026-03-04 23:31:48 +00:00
Frank ada0ec009c wip: zen 2026-03-04 18:29:38 -05:00
James Long 59eb5322a0 fix(core): handle SIGHUP and kill process (#16057) 2026-03-04 23:12:05 +00:00
Frank a178477eb8 Merge branch 'go-page' into dev 2026-03-04 18:00:11 -05:00
David Hill c298aed94c tui: prevent Go pricing graph from overflowing on medium screens by constraining width and moving axis labels outside SVG for sharper rendering 2026-03-04 22:31:23 +00:00
David Hill 39d6d36a70 tui: clearer graph labels and responsive layout for usage visualization
Improve readability of the usage graph y-axis label by spelling out
'Requests per 5 hour' instead of the abbreviated 'Requests/5h'. Fix
layout on smaller screens by removing negative margin that was
causing the graph to overflow its container.
2026-03-04 22:19:28 +00:00
David Hill b046d25c14 tui: clarify free tier includes Big Pickle and promotional requests on Go pricing page 2026-03-04 22:16:30 +00:00
David Hill fa61ed7c63 wip: Make bar colors in limit graph customizable via CSS variables for consistent theming across the go route visualization 2026-03-04 22:10:17 +00:00
David Hill 5a80a3d465 docs: redesign Go pricing graph with horizontal bars and inline request labels
Improve visual clarity of request limits on the Go pricing page by replacing
dot-based chart with animated horizontal bars that directly show model names
and exact request counts. Add proper OpenGraph and Twitter Card meta tags for
better social sharing discovery.
2026-03-04 22:07:49 +00:00
opencode-agent[bot] 9883d17ac1 docs(i18n): sync locale docs from english changes 2026-03-04 18:39:59 +00:00
Scott Tolinski 37fb3a3102 docs: Add opencode-sentry-monitor to ecosystem documentation (#16037) 2026-03-04 13:34:17 -05:00
David Hill 45072f5ba1 ci: make tsgo available for pre-push typechecks 2026-03-04 16:48:29 +00:00
David Hill 37f8625be3 chore(ui): remove quotes 2026-03-04 16:45:34 +00:00
David Hill 0c3bee1450 tweak(ui): darker text 2026-03-04 16:43:43 +00:00
David Hill 7d5d3a3e2c tweak(ui): remove section 2026-03-04 16:42:30 +00:00
David Hill 23902e7af9 tui: show Go request limits per 5-hour session 2026-03-04 16:35:03 +00:00
David Hill b139965bc2 tui: clarify which models are available in Go subscription
Adds list of included AI models (GLM-5, Kimi K2.5, and MiniMax M2.5) to the Go page so users know exactly what model access their subscription provides
2026-03-04 16:19:06 +00:00
Frank 1541868d36 Merge branch 'dev' into go-page 2026-03-04 11:13:14 -05:00
David Hill 9a49f46fb0 tui: reduce excessive spacing in go route layout to improve visual balance 2026-03-04 16:09:51 +00:00
David Hill f71f5f1391 docs: make Go hero CTA translatable with pricing emphasis 2026-03-04 16:02:37 +00:00
David Hill b9ce65e2ad docs: localize Go graph and testimonial copy 2026-03-04 15:58:58 +00:00
David Hill 6066ae3a66 docs: de-link Go testimonials and swap Zen→Go 2026-03-04 15:49:45 +00:00
David Hill c6e46e701a docs: update Go privacy copy for global hosting 2026-03-04 15:47:53 +00:00
David Hill 2b70c8c049 docs: clarify Go models in FAQ answer 2026-03-04 15:24:51 +00:00
David Hill d427fc4435 docs: replace Go landing page video with interactive limits graph
Users can now see a clear visual comparison of request limits between Free tier and Go tier across all available models, making it easier to understand the value of a Go subscription at a glance.
2026-03-04 15:21:07 +00:00
opencode 11a575ece6 release: v1.2.17 2026-03-04 14:58:04 +00:00
Brendan Allan b2b29ac148 ci: remove electron beta requirement 2026-03-04 22:38:23 +08:00
Brendan Allan f82d73e2b9 ci: only publish electron on beta 2026-03-04 22:21:56 +08:00
Dax Raad 09904ef0ad remove build from typecheck 2026-03-04 09:20:24 -05:00
Sebastian 2f97b14e05 show scrollbar by default (#15282) 2026-03-04 15:10:27 +01:00
Adam fbb0a8273a fix(app): remove blur from todos 2026-03-04 07:43:28 -06:00
Adam a33f80d486 fix(app): delay dock animation on session load 2026-03-04 07:39:34 -06:00
Adam 234078addd fix(app): remove diff lines from sessions in sidebar 2026-03-04 07:36:10 -06:00
David Hill f3846adff3 chore(console): update copy 2026-03-04 13:24:08 +00:00
Adam 3e071c30ee fix(app): loading session should be scrolled to the bottom 2026-03-04 07:18:09 -06:00
David Hill 315f23519b chore(console): edit copy 2026-03-04 13:08:21 +00:00
David Hill 0e4a81fc11 docs: send Go landing page links to Go docs 2026-03-04 13:05:19 +00:00
Adam a276c2a79a fix(app): terminal tab close 2026-03-04 07:04:03 -06:00
David Hill 1d4405fe04 chore(console): switch /go page to go.* i18n keys 2026-03-04 12:57:49 +00:00
David Hill 85917abfb1 chore(console): use Go ornate logo on /go 2026-03-04 12:15:40 +00:00
David Hill 03a7629cbd chore(console): refine /go hero and pricing copy 2026-03-04 12:01:15 +00:00
David Hill 8e529da4fd chore(console): hide Go nav item on /go 2026-03-04 11:46:30 +00:00
David Hill 61714a6255 chore(console): update /go hero body 2026-03-04 11:34:44 +00:00
opencode-agent[bot] 7e2c6a8527 docs(i18n): sync locale docs from english changes 2026-03-04 11:27:41 +00:00
David Hill 5d5d01d985 chore(console): move login to end on zen/go 2026-03-04 11:26:50 +00:00
shivam kr chaudhary b644c528cc fix(docs): update dead opencode-daytona ecosystem link (#15979)
Co-authored-by: Shoubhit Dash <shoubhit2005@gmail.com>
2026-03-04 11:18:28 +00:00
Brendan Allan db0e0b1e2d ui: rely on task part href instead of onClick handler (#15978) 2026-03-04 16:41:20 +08:00
opencode-agent[bot] 8312acc19b chore: update nix node_modules hashes 2026-03-04 07:35:19 +00:00
Brendan Allan dffd2d0ae4 desktop: add electron version (#15663) 2026-03-04 15:12:34 +08:00
Frank 5dc630ea80 zen: fix aws bedrock header 2026-03-03 23:45:43 -05:00
Dax 2bb68320ac fix(process): prevent orphaned opencode subprocesses on shutdown (#15924) 2026-03-03 22:14:28 -05:00
opencode-agent[bot] 4f1d8293cf chore: generate 2026-03-04 02:36:18 +00:00
James Long 113baa876e feat(core): rework workspace integration and adaptor interface (#15895) 2026-03-03 21:35:38 -05:00
Dax 48b7e8a908 docs(bash): clarify output capture guidance (#15928) 2026-03-03 21:10:26 -05:00
Andrea Alberti f85648c660 fix: run --attach agent validation (#11812)
Co-authored-by: LukeParkerDev <10430890+Hona@users.noreply.github.com>
2026-03-03 22:30:16 +00:00
Copilot d63e724e68 revert: undo turbo typecheck dependency change from #14828 (#15902)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Hona <10430890+Hona@users.noreply.github.com>
2026-03-04 07:35:24 +10:00
opencode 57d918be0c release: v1.2.16 2026-03-03 21:08:35 +00:00
Dax Raad a92b065107 tui: replace curved arrow with straight arrow for better terminal compatibility 2026-03-03 15:25:11 -05:00
Dax Raad 6e752828dd tui: show pending toolcall count instead of generic 'Running...' message 2026-03-03 15:08:11 -05:00
Dax dc479bdf5f tui: use arrow indicator for active tool execution (#15887) 2026-03-03 14:46:07 -05:00
David Hill 759a3ccfb3 chore(console): trim /go model logos 2026-03-03 19:04:48 +00:00
David Hill c35d20f0e6 chore(console): update /go hero copy 2026-03-03 19:01:24 +00:00
David Hill 6a7513600c chore(console): move Enterprise after Go 2026-03-03 18:51:53 +00:00
Matt Silverlock 4e510bd94f fix(auth): normalize trailing slashes in auth login URLs (#15874) 2026-03-03 13:35:49 -05:00
Frank 7c6e6e8af1 wip: zen 2026-03-03 13:30:34 -05:00
David Hill 2d71185b86 chore(console): add Go to nav 2026-03-03 18:30:04 +00:00
David Hill e1520e89ed feat(console): add /go landing page 2026-03-03 18:29:42 +00:00
Adam ce8629c506 fix(app): defer diff rendering 2026-03-03 11:14:03 -06:00
Adam 4e7ef5e08b fix(app): defer diff rendering 2026-03-03 11:00:06 -06:00
Adam 6d62be48d0 chore: cleanup 2026-03-03 10:25:49 -06:00
opencode-agent[bot] 266735929c chore: update nix node_modules hashes 2026-03-03 15:52:03 +00:00
Sebastian 8ade9e4e30 Upgrade opentui to v0.1.86 and activate markdown renderable by default (#14974) 2026-03-03 15:42:27 +00:00
opencode-agent[bot] 3d36c06659 docs(i18n): sync locale docs from english changes 2026-03-03 15:03:53 +00:00
Frank 87a9b477e6 wip: zen 2026-03-03 09:44:34 -05:00
Adam db728098bc fix(app): timeline jank 2026-03-03 08:28:56 -06:00
Adam 21a10a5ccf fix(app): tighten up header elements 2026-03-03 07:19:24 -06:00
Adam 78d63d9062 chore: cleanup 2026-03-03 07:10:52 -06:00
Adam d5f54bf94e chore: tr glossary 2026-03-03 07:10:52 -06:00
opencode-agent[bot] b9f2f59fd1 chore: generate 2026-03-03 12:28:35 +00:00
İbrahim Hakkı Ergin eabf8b4202 fix: update Turkish translations (#15835) 2026-03-03 06:27:54 -06:00
Jack f746f38c79 fix(app): stabilize project close navigation (#15817)
Co-authored-by: Adam <2363879+adamdotdevin@users.noreply.github.com>
2026-03-03 06:25:55 -06:00
Adam 5728c25c00 chore: cleanup 2026-03-03 06:20:48 -06:00
Adam 18accb3326 chore: fix test 2026-03-03 05:53:03 -06:00
Adam f9fcdc4102 fix(app): timeline jank 2026-03-03 05:35:15 -06:00
Adam 44aaba9a17 fix(app): timeline jank 2026-03-03 05:35:15 -06:00
Jérôme Benoit 71bfe2487e fix(opencode): disable session navigation commands when no parent session (#15762)
Co-authored-by: Test User <test@test.com>
Co-authored-by: Shoubhit Dash <shoubhit2005@gmail.com>
2026-03-03 16:00:25 +05:30
Caleb Norton 5cc07df342 chore: nix flake update for bun 1.3.10 (#15648)
Co-authored-by: Jérôme Benoit <jerome.benoit@piment-noir.org>
2026-03-03 12:16:43 +05:00
Frank 5f069421a1 zen: docs 2026-03-03 01:27:55 -05:00
Frank 425b6b2ede wip: zen 2026-03-03 01:00:50 -05:00
Frank da845488a5 wip: zen 2026-03-03 00:52:12 -05:00
opencode-agent[bot] b6c82d5b5b chore: generate 2026-03-03 05:26:22 +00:00
Frank 1f33b986e4 wip: zen 2026-03-03 00:25:03 -05:00
opencode-agent[bot] a0be4ad767 chore: generate 2026-03-03 04:41:52 +00:00
Shoubhit Dash eeaf8b888e fix(opencode): avoid gemini combiner schema sibling injection (#15318) 2026-03-03 10:11:05 +05:30
opencode-agent[bot] 1409bd2df3 chore: generate 2026-03-03 03:53:50 +00:00
Ryan Skidmore 2bcf5e371c fix(provider): forward metadata options to cloudflare-ai-gateway provider (#15619) 2026-03-02 22:53:03 -05:00
Ryan Skidmore 02603fef14 fix(opencode): clone part data in Bus event to preserve token values (#15780) 2026-03-02 22:52:43 -05:00
opencode-agent[bot] 580f19ad1c chore: update nix node_modules hashes 2026-03-02 22:38:45 +00:00
opencode-agent[bot] 8562463036 chore: generate 2026-03-02 22:25:39 +00:00
Kit Langton 848b3d658e Animation Smorgasbord (#15637)
Co-authored-by: Adam <2363879+adamdotdevin@users.noreply.github.com>
2026-03-02 16:24:32 -06:00
Adam b84ebce1fc fix(app): default auto-respond to false 2026-03-02 13:10:37 -06:00
Adam 9c52e2b4cb chore: fix docs sync permissions 2026-03-02 11:42:20 -06:00
Adam a08c524902 chore(app): solidjs refactoring (#13399) 2026-03-02 10:50:50 -06:00
David Hill e597187254 ui: move session review bottom padding
Remove bottom padding from the scroll wrapper and apply it to the accordion content instead.
2026-03-02 16:19:35 +00:00
David Hill 29adce71de ui: avoid session review header clipping
Move the session review header outside the scroll viewport and drop strict containment so shadows can render without being cropped.
2026-03-02 16:05:16 +00:00
David Hill cbc865ebe7 ui: tighten scroll thumb and review padding
Keep the scroll thumb visually slim (4px) while preserving a 12px drag target, and remove extra right padding in session review content.
2026-03-02 15:37:41 +00:00
David Hill 01f184c8ed ui: widen scroll thumb hit area
Make the thumb overlay 12px wide while keeping the visible bar 6px centered for easier hover/drag.
2026-03-02 15:26:55 +00:00
David Hill 34e88a2ecf core: keep review header buttons visible when scroll thumb shows 2026-03-02 14:59:12 +00:00
Filip 5657c76fa6 feat(app): show which messages are queued (#15587) 2026-03-02 13:27:34 +05:30
opencode-agent[bot] 2200846808 chore: generate 2026-03-02 07:41:53 +00:00
bentrd 6ccc8b01f7 fix: recover from 413 Request Entity Too Large via auto-compaction (#14707)
Co-authored-by: Noam Bressler <noamzbr@gmail.com>
2026-03-02 13:10:55 +05:30
Noam Bressler 7e1a425e6a fix: project ID conflict, and update on same session id (#15596) 2026-03-02 13:09:53 +05:30
Brendan Allan b3ce2e0390 desktop: fix latest.json finalizer 2026-03-02 14:36:35 +08:00
Shoubhit Dash eefaa49ef8 Revert "fix(i18n): polish turkish translations" (#15656) 2026-03-02 06:03:50 +00:00
Brendan Allan fc8b415706 desktop: use correct download link in finalize-latest-json 2026-03-02 11:21:17 +08:00
opencode-agent[bot] 6a7f159779 chore: generate 2026-03-01 19:17:56 +00:00
Kit Langton 2fef1e912c perf(session): faster session switching via windowed rendering and staged timeline (#15474) 2026-03-01 13:17:04 -06:00
Frank 977c938536 doc: add zen deprecated models 2026-03-01 13:21:34 -05:00
Dax a308132036 feat(tui): improve task tool display with subagent keybind hints and spinner animations (#15607) 2026-03-01 17:46:10 +00:00
Rian van der Merwe e55c250aa5 fix(opencode): show human-readable message for HTML error responses (#15407) 2026-03-01 09:24:57 -06:00
Filip 5515cd3242 feat(app): add compact ui (#15578) 2026-03-01 08:41:47 -06:00
Filip 8d4aa4b80e fix(app): make provider icon resolved id reactive (#15583) 2026-03-01 08:40:04 -06:00
Uğur Murat Altıntas a765489e36 fix(i18n): polish turkish translations (#15491) 2026-03-01 06:48:26 -06:00
Filip f6caa856b6 fix(app): show proper usage limit errors (#15496) 2026-03-01 06:48:11 -06:00
ryanwyler 149f21f42d fix: kill orphaned MCP child processes and expose OPENCODE_PID on shu… (#15516) 2026-03-01 18:08:17 +05:30
opencode-agent[bot] 72b7b0545f chore: generate 2026-03-01 04:44:37 +00:00
inkdust2021 797ffabdd5 docs(ecosystem): add opencode-vibeguard (#15464) 2026-03-01 10:13:52 +05:30
opencode-agent[bot] 3721849168 chore: generate 2026-03-01 03:10:46 +00:00
James Long e34419afc8 feat(core): add workspace_id to session table (#15410) 2026-02-28 22:09:53 -05:00
opencode-agent[bot] d1025def50 chore: generate 2026-03-01 01:45:44 +00:00
James Long 40723568ef feat(core): add WorkspaceContext (#15409) 2026-02-28 20:44:54 -05:00
Dax Raad 880d7bd656 docs: fix broken config imports in translated documentation
Fixed incorrect relative import paths in Bosnian, French, Italian,
Korean, Norwegian, Portuguese, Turkish, and Chinese docs that were
referencing config.mjs from the wrong directory level. This resolves
build errors when viewing translated documentation pages.
2026-02-28 18:54:18 -05:00
Adam d7334fe4e5 chore(docs): i18n sync (#15417) 2026-02-28 15:27:11 -06:00
mridul ee008b99a3 fix(app): fallback to synthetic icon for unknown provider IDs (#15295) 2026-02-28 15:13:23 -06:00
Alex Yaroshuk e135277228 fix(app): display skill name in skill tool call (#15413) 2026-02-27 19:18:14 -06:00
Adam c97fd4b692 chore: cleanup 2026-02-27 19:12:19 -06:00
Jay ccd5717c0c docs: Update OpenCode Go subscription and usage details (#15415) 2026-02-27 16:04:53 -08:00
Frank 185552ce0e doc: go 2026-02-27 18:03:39 -05:00
Frank 20a2c796b5 doc: opencode go 2026-02-27 17:38:30 -05:00
opencode-agent[bot] 562b3af498 chore: update nix node_modules hashes 2026-02-27 21:59:23 +00:00
Adam cbe364db32 chore(console): i18n sync (#15360) 2026-02-27 15:50:50 -06:00
Adam 406885abd3 chore(app): deps 2026-02-27 15:49:38 -06:00
opencode-agent[bot] af88d19018 chore: generate 2026-02-27 21:17:37 +00:00
Alex Yaroshuk 31708751b8 fix(app): make bash output selectable (#15378) 2026-02-27 15:16:33 -06:00
shivam kr chaudhary 903fe5d6bb docs: add missing Bosanski link to Arabic README (#15399) 2026-02-27 15:15:48 -06:00
opencode-agent[bot] 19fcdf46fe chore: generate 2026-02-27 20:37:28 +00:00
James Long a5c224f2ae feat(core): basic implementation of remote workspace support (#15120) 2026-02-27 15:36:39 -05:00
Adam feb6a247ea fix(app): scroll issues 2026-02-27 09:47:56 -06:00
Adam 8fbb7bba36 chore(app): i18n sync (#15362) 2026-02-27 09:45:00 -06:00
Adam 39350b7429 chore: update translator model 2026-02-27 09:27:12 -06:00
Adam f51f3a8bb5 chore: update docs locale sync workflow 2026-02-27 09:18:17 -06:00
Kit Langton bfa4f1978b feat(app): add Warp to the open menu (#15368) 2026-02-27 09:44:01 -05:00
Kit Langton 1bbed4526a chore(script): source team members from TEAM_MEMBERS (#15369) 2026-02-27 09:43:51 -05:00
James Long 039b68e12d Change keybindings to navigate between child sessions (#14814) 2026-02-27 09:41:23 -05:00
Adam 90cc1400ed chore: update test 2026-02-27 06:54:15 -06:00
Brendan Allan e9057b39b5 desktop: add latest.json finalizer script (#15335) 2026-02-27 20:18:21 +08:00
Adam 410c8dc5e8 fix(app): auto-accept permissions 2026-02-27 06:17:40 -06:00
Adam db7a8218cd fix(app): update provider sprite 2026-02-27 06:01:00 -06:00
opencode-agent[bot] ccb5edd693 chore: generate 2026-02-27 11:41:55 +00:00
vaur94 4ea76090ce feat(app): add Turkish (tr) locale for app and ui packages (#15278)
Co-authored-by: Ugur <ugur@example.com>
2026-02-27 05:41:06 -06:00
Pirro Zani c033104007 docs(readme): add Greek translation and update language navigation (#15281) 2026-02-27 05:39:56 -06:00
Filip 06aee9d60e feat(app): recent projects section in command pallette (#15270) 2026-02-27 05:33:22 -06:00
Frank 9ac2938922 wip: zen 2026-02-27 02:56:43 -05:00
Brendan Allan 3651b6ca7c desktop: move open_path to rust (#15323) 2026-02-27 06:17:24 +00:00
Frank bb5bd0346b wip: zen 2026-02-27 00:30:14 -05:00
Brendan Allan 9182513e03 app: allow providing username and password when connecting to remote server (#14872) 2026-02-27 13:26:15 +08:00
Frank 3db0159453 zen: fix go plan usage limit 2026-02-26 23:20:05 -05:00
Adam 99d43f72de fix(app): scroll jacking 2026-02-26 20:41:35 -06:00
Adam c86ef19da5 fix(app): permission indicator 2026-02-26 20:40:39 -06:00
Adam 1f416ba16f fix(app): permission notifications 2026-02-26 20:36:10 -06:00
David Hill 55feba49f8 tweak(app): show keybind on context tab close 2026-02-27 00:29:02 +00:00
Adam 4a37b76340 feat(app): better diff/code comments (#14621)
Co-authored-by: adamelmore <2363879+adamdottv@users.noreply.github.com>
Co-authored-by: David Hill <iamdavidhill@gmail.com>
2026-02-26 18:23:04 -06:00
Kit Langton 32fa0b40d7 refactor(app): dedupe filetree scroll state 2026-02-26 19:20:56 -05:00
David Hill 6e70bf75ed tweak(app): align review changes select height 2026-02-27 00:18:14 +00:00
David Hill 6c131eb34b fix(ui): mute inactive file tab icons 2026-02-27 00:18:14 +00:00
David Hill 44c10a5931 tweak(ui): max-width on session when the review is closed but the file tree is open 2026-02-27 00:18:14 +00:00
Adam 8e647926a4 fix: test 2026-02-26 18:11:05 -06:00
Adam 72793481ee Revert "fix(ui): prevent filename and diff count overlap in session changes (#14773)"
This reverts commit 007788ec9f.
2026-02-26 18:11:05 -06:00
David Hill c466e0ac3a tweak(ui): add border to filetree on scroll 2026-02-26 23:18:35 +00:00
David Hill 5211e969dc tui: fix session tab alignment in compact view to prevent vertical overflow 2026-02-26 22:54:49 +00:00
opencode-agent[bot] 01800334d0 chore: update nix node_modules hashes 2026-02-26 22:18:33 +00:00
Adam 073fc8b3dc chore: storybook (#15285)
Co-authored-by: David Hill <iamdavidhill@gmail.com>
2026-02-26 16:05:04 -06:00
Adam 60ca2c4bf0 fix(app): terminal issues 2026-02-26 15:52:35 -06:00
Shoubhit Dash 007788ec9f fix(ui): prevent filename and diff count overlap in session changes (#14773) 2026-02-26 15:42:24 -06:00
Shoubhit Dash 26e1174b02 fix(ui): avoid truncating workspace paths in assistant text (#14584) 2026-02-26 15:41:58 -06:00
Adam d0020d4f8f feat(app): new tabs styling (#15284)
Co-authored-by: David Hill <iamdavidhill@gmail.com>
2026-02-26 15:39:45 -06:00
Adam b9f7ea0442 feat(app): auto-accept all permissions mode 2026-02-26 15:23:26 -06:00
OpeOginni 75879315fb refactor(desktop): enhance project tile interaction with suppress hover functionality (#15214) 2026-02-26 11:00:11 -06:00
Niu Shuai f055903464 docs: Sync zh_CN docs with English Version (#15228) 2026-02-26 10:59:45 -06:00
Frank 01f319fb56 wip: zen 2026-02-26 11:17:19 -05:00
adamelmore 3cc7a6c255 chore: fix flaky test 2026-02-26 08:53:40 -06:00
Adam 5724c58d24 fix(app): simplify review layout (#14953)
Co-authored-by: adamelmore <2363879+adamdottv@users.noreply.github.com>
2026-02-26 08:51:58 -06:00
David Hill e00660647a feat: opencode go provider list (#15203) 2026-02-26 14:37:33 +00:00
Shoubhit Dash daaddc084b fix(desktop): restore shell path env for desktop sidecar (#15211) 2026-02-26 18:35:21 +05:30
Filip b1596dca43 fix(app): open in powershell (#15112) 2026-02-26 16:39:55 +08:00
opencode 941f7ef778 release: v1.2.15 2026-02-26 08:22:25 +00:00
Luke Parker 3409375fd6 fix: most segfaults on windows with Bun v1.3.10 stable (#15181) 2026-02-26 17:55:01 +10:00
Stefan 27f440caa8 fix(app): middle-click tab close in scrollable tab bar (#15081)
Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com>
2026-02-26 12:29:08 +05:30
kil-penguin 1a2e4f419c fix(desktop): remove interactive shell flag from sidecar spawn to prevent hang on macOS (#15136)
Co-authored-by: kil-penguin <hyeonjun@gameduo.net>
2026-02-26 14:02:40 +08:00
Frank c73be95e88 wip: zen 2026-02-25 23:06:16 -05:00
Adam 4e6d2907cc fix(app): permissions and questions from child sessions (#15105)
Co-authored-by: adamelmore <2363879+adamdottv@users.noreply.github.com>
2026-02-26 01:05:08 +00:00
OpeOginni 9ddeee914b fix(docs): update schema URL in share configuration examples across multiple languages (#15114) 2026-02-25 18:16:39 -05:00
opencode-agent[bot] 270424448f chore: generate 2026-02-25 22:55:09 +00:00
Sebastian e0d78a4445 split tui/server config (#13968) 2026-02-25 23:53:09 +01:00
Frank 0c5e2b5fef wip: zen go 2026-02-25 12:39:50 -05:00
adamelmore b73992034a chore: move glossary 2026-02-25 10:29:05 -06:00
David Hill c31d02046e tweak(ui): keep reasoning inline code subdued in dark mode 2026-02-25 15:18:05 +00:00
Filip 9666a5af1a fix(app): keyboard navigation previous/next message (#15047) 2026-02-25 08:57:13 -06:00
Oleksii Pavliuk 249174de94 fix(app): correct Copilot provider description in i18n files (#15071) 2026-02-25 14:56:03 +00:00
Ryan Vogel 6ec0996134 chore(workflows): label vouched users and restrict vouch managers (#15075) 2026-02-25 14:56:03 +00:00
opencode-agent[bot] 641f2f35c9 chore: generate 2026-02-25 14:56:03 +00:00
opencode d9b15a31f6 release: v1.2.14 2026-02-25 14:55:56 +00:00
Shantur Rathore a19e39dd5a feat(core): add message delete endpoint (#14417) 2026-02-25 09:25:26 -05:00
Ayush Thakur 4510f17ef5 fix: consume stdout concurrently with process exit in auth login (#15058) 2026-02-25 08:22:52 -05:00
opencode 4fe679b14c release: v1.2.13 2026-02-25 07:27:19 +00:00
Dax Raad ad3ba109ee opencode go copy 2026-02-25 01:54:28 -05:00
Dax Raad 2a605b20e1 sync 2026-02-25 01:48:10 -05:00
Filip 26c58e184c feat(desktop): enhance Windows app resolution and UI loading states (#13320)
Co-authored-by: Brendan Allan <git@brendonovich.dev>
Co-authored-by: Brendan Allan <brendonovich@outlook.com>
2026-02-25 14:39:58 +08:00
Frank bc924c452f zen: go 2026-02-25 01:25:08 -05:00
Frank 11529bc636 wip: zen go 2026-02-25 00:48:14 -05:00
Frank b12976b7b0 wip: zen go 2026-02-25 00:47:04 -05:00
Frank 546fccbea8 wip: zen go 2026-02-25 00:42:33 -05:00
Frank 5a3d09bd39 zen: go 2026-02-25 00:31:48 -05:00
Brendan Allan 131462ea55 desktop: make readme more accurate 2026-02-25 12:28:48 +08:00
Dax Raad 9b2d662f8a ci: switch beta script to gpt-5.3-codex for improved code generation quality 2026-02-24 23:26:03 -05:00
Dax Raad 93a88697ac ci: specify opencode/kimi-k2.5 model in beta script to ensure consistent PR processing 2026-02-24 23:22:56 -05:00
Dax Raad 81ca7c0479 ci: auto-resolve merge conflicts in beta sync using opencode
When merging PRs into the beta branch, the sync script now attempts to automatically resolve merge conflicts using opencode before failing. This reduces manual intervention needed for beta releases when multiple PRs have overlapping changes.
2026-02-24 23:17:31 -05:00
Dax 08538a751f feat: show LSP errors for apply_patch tool (#14715) 2026-02-25 04:15:11 +00:00
Dax Raad aa3ce4063b core: temporarily disable plan enter tool to prevent unintended mode switches during task execution 2026-02-24 23:05:26 -05:00
Dax 78e670e201 refactor: migrate Bun.spawn to Process utility with timeout and cleanup (#14448) 2026-02-24 23:04:15 -05:00
Luke Parker c10388cb99 fix(opencode): disable config bun cache in CI (#14985) 2026-02-25 11:38:23 +10:00
Luke Parker 301b1bf205 fix(project): await git id cache write (#14977) 2026-02-25 00:46:12 +00:00
Luke Parker 5faa5683c8 fix(opencode): import custom tools via file URL (#14971) 2026-02-25 10:24:47 +10:00
opencode 033836ddf3 release: v1.2.11 2026-02-24 23:29:02 +00:00
James Long 49ca7efa7e feat(core): add workspace-serve command (experimental) (#14960) 2026-02-24 17:34:34 -05:00
Frank 3aed817a34 zen: gpt 5.3 codex 2026-02-24 14:49:07 -05:00
adamelmore 257cfaae6f fix(app): ignore stale part deltas 2026-02-24 11:48:29 -06:00
Frank ba7b852b9e zen: restrict alpha models to admin workspaces 2026-02-24 09:56:11 -05:00
Filip 8ac0c2be94 fix(app): on cancel comment unhighlight lines (#14103) 2026-02-24 22:55:17 +08:00
opencode-agent[bot] 012af78f58 chore: generate 2026-02-24 14:49:52 +00:00
OpeOginni 781bf27efe refactor: replace error handling with serverErrorMessage utility and checks for if error is ConfigInvalidError (#14685) 2026-02-24 14:48:59 +00:00
Frank 738377cab8 zen: remove alpha models from models endpoint 2026-02-24 09:43:18 -05:00
adamelmore ba1f669d3d chore: cleanup 2026-02-24 08:21:05 -06:00
Luke Parker 0f4d997a50 fix(app): preserve native path separators in file path helpers (#14912) 2026-02-25 00:03:15 +10:00
Noam Bressler c2c179eccc fix: ACP both live and load share synthetic pending status preceeding… (#14916) 2026-02-24 23:54:10 +10:00
adamelmore 184e91765a fix(app): remove filetree tooltips 2026-02-24 07:32:12 -06:00
Luke Parker f85737fcc0 fix(test): replace structuredClone with spread for process.env (#14908) 2026-02-24 23:16:24 +10:00
Luke Parker 0e3f1e9904 fix(win32): add 50ms tolerance for NTFS mtime fuzziness in FileTime assert (#14907) 2026-02-24 23:10:10 +10:00
Luke Parker 6bd81f419c fix(test): replace Unix-only assumptions with cross-platform alternatives (#14906) 2026-02-24 23:03:18 +10:00
Luke Parker 555a409fa4 fix(test): use path.sep in discovery test for cross-platform path matching (#14905) 2026-02-24 22:51:56 +10:00
Luke Parker e0474520a1 fix(win32): normalize backslash paths in config rel() and file ignore (#14903) 2026-02-24 22:42:48 +10:00
Luke Parker fa24663269 fix(win32): fix plugin resolution with createRequire fallback (#14898) 2026-02-24 22:20:57 +10:00
Luke Parker cd2e2d6292 fix(test): harden preload cleanup against Windows EBUSY (#14895) 2026-02-24 21:59:14 +10:00
Luke Parker bec0b6529a fix(test): normalize git excludesFile path for Windows (#14893) 2026-02-24 21:40:38 +10:00
opencode-agent[bot] 8a8dbfcfbc chore: generate 2026-02-24 11:15:39 +00:00
Noam Bressler 59bbbb909e feat: ACP - stream bash output and synthetic pending events (#14079)
Co-authored-by: Aiden Cline <63023139+rekram1-node@users.noreply.github.com>
2026-02-24 21:14:47 +10:00
Luke Parker 7122c38d71 fix(win32): add git flags for snapshot operations and fix tests for cross-platform (#14890) 2026-02-24 21:14:16 +10:00
Luke Parker f03025d369 fix(win32): handle CRLF line endings in markdown frontmatter parsing (#14886) 2026-02-24 20:33:22 +10:00
Luke Parker 2d99c035cd fix(win32): add bun prefix to console app build scripts (#14884) 2026-02-24 20:25:15 +10:00
Luke Parker 0732c96591 fix(test): use path.join for cross-platform glob test assertions (#14837) 2026-02-24 20:07:56 +10:00
Luke Parker bf72313a7e fix: update createOpenReviewFile test to match new call order (#14881) 2026-02-24 19:56:41 +10:00
opencode-agent[bot] 117203373b chore: generate 2026-02-24 09:47:20 +00:00
Frank dce32f14bb wip: zen lite 2026-02-24 04:45:41 -05:00
Frank 0c557e9cc9 wip: zen lite 2026-02-24 04:45:41 -05:00
Brendan Allan aa87043dd1 app: wait for loadFile before opening file tab 2026-02-24 16:47:55 +08:00
Luke Parker 173b320bec upgrade to bun 1.3.10 canary and force baseline builds always (#14843) 2026-02-24 16:06:45 +10:00
Luke Parker a8c67558f4 ci: use bun baseline build to avoid segfaults (#14839) 2026-02-24 10:15:19 +10:00
Luke Parker 22ec72c5f7 ci: add Windows to unit test matrix (#14836) 2026-02-24 09:33:33 +10:00
Luke Parker 8e3ba49de1 fix(win32): e2e sometimes fails because windows is weird and sometimes ipv6 (#14833) 2026-02-24 09:27:00 +10:00
Frank 487fc478c0 zen: display BYOK cost 2026-02-23 18:18:47 -05:00
Luke Parker 5e39fd384d fix(win32): scripts/turbo commands would not run (#14829) 2026-02-24 09:15:25 +10:00
Luke Parker 3fffaf4a90 fix(cicd): flakey typecheck (#14828) 2026-02-24 09:13:31 +10:00
Ryan Vogel 4ae6dd6c09 fix: update workflows for better automation (#14809) 2026-02-23 16:51:29 -05:00
adamelmore 234981b470 fix(app): duplicate markdown 2026-02-23 09:54:26 -06:00
adamelmore f4562c7d99 fix(app): duplicate markdown 2026-02-23 08:23:56 -06:00
Shawn 4de6413715 fix(app): correct inverted chevron direction in todo list (#14628)
Co-authored-by: shenghui kevin <shenghuikevin@shenghuideMac-mini.local>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 13:41:33 +05:30
adamelmore cf8e450b22 Revert "fix(app): terminal issues"
This reverts commit dcd0169e72.
2026-02-22 21:27:25 -06:00
opencode-agent[bot] e262d4e835 chore: generate 2026-02-23 03:21:03 +00:00
Frank 82f876660b wip: zen lite 2026-02-22 22:20:00 -05:00
Frank bdeea0d10b zen: display session in usage 2026-02-22 22:19:44 -05:00
Frank ca408f4666 zen: track session in usage 2026-02-22 22:19:44 -05:00
Luke Parker 605ea75ddb fix(win32): normalize paths at permission boundaries (#14738) 2026-02-23 12:05:21 +10:00
Erik Demaine d29240c192 fix: Windows path support and canonicalization (#13671)
Co-authored-by: LukeParkerDev <10430890+Hona@users.noreply.github.com>
2026-02-23 10:10:27 +10:00
opencode-agent[bot] 82aff481fd chore: update nix node_modules hashes 2026-02-23 00:00:47 +00:00
Sebastian 39e489821c upgrade opentui to v0.1.81 (#14605) 2026-02-23 00:51:50 +01:00
opencode-agent[bot] 0693db20eb chore: generate 2026-02-22 23:49:51 +00:00
Erik Demaine 90d2e6b775 fix(desktop): change detection on Windows, especially Cygwin (#13659)
Co-authored-by: LukeParkerDev <10430890+Hona@users.noreply.github.com>
2026-02-23 09:49:05 +10:00
github-actions[bot] 199b57d2d7 Update VOUCHED list
https://github.com/anomalyco/opencode/issues/13659#issuecomment-3941825887
2026-02-22 22:28:32 +00:00
Adam f57585f51a feat(app): feed customization options 2026-02-22 11:36:00 -06:00
Adam dcd0169e72 fix(app): terminal issues 2026-02-22 06:17:59 -06:00
Pirro Zani d33a5d08c6 docs(tui): correct typo in TUI documentation (#14604) 2026-02-22 13:59:50 +05:30
github-actions[bot] a001e278fd Update VOUCHED list
https://github.com/anomalyco/opencode/issues/14616#issuecomment-3939773562
2026-02-22 00:23:58 +00:00
Jun 4da629e2cf docs(ko): improve wording in gitlab, ide, index, keybinds, and lsp docs (#14517) 2026-02-21 07:01:53 -06:00
Adam 90c0bdbd2d chore: updated locale glossaries and docs sync workflow 2026-02-21 04:58:27 -06:00
Adam 9154ed6434 chore: locale specific glossaries 2026-02-21 04:58:26 -06:00
Brendan Allan 880416b489 desktop: beta icon 2026-02-21 11:11:08 +08:00
Adam 21510ac641 fix: e2e test outdated 2026-02-20 19:44:06 -06:00
Adam e2761591d2 chore: cleanup 2026-02-20 19:37:35 -06:00
Frank d506162627 wip: zen lite 2026-02-20 19:38:29 -05:00
opencode-agent[bot] a70271f9e1 chore: generate 2026-02-21 00:18:43 +00:00
Tuhin Mahmud ba7d9a198c docs: add Bangla README translation (#14331) 2026-02-20 18:17:47 -06:00
Adam 691bc3ab94 fix(app): remove double-border in share button 2026-02-20 16:20:13 -06:00
Adam c9ad8fce0b chore: cleanup 2026-02-20 16:05:41 -06:00
Adam 62ce430350 fix(app): better sound effect disabling ux 2026-02-20 16:05:41 -06:00
Aiden Cline 936c69b08d ci: temporarily disable assigning of issues to rekram1-node (#14486) 2026-02-20 13:56:29 -06:00
Aiden Cline c3dbd03f08 cache platform binary in postinstall for faster startup (#14467) 2026-02-20 12:19:17 -06:00
Adam 09427ce448 fix(app): session review re-rendering too aggressively 2026-02-20 11:11:48 -06:00
Adam 846249a891 chore: cleanup 2026-02-20 10:54:17 -06:00
Adam f1a0fe3aca wip(app): custom scroll view 2026-02-20 10:54:17 -06:00
Frank a33b9646b4 zen: gpt safety_identifier 2026-02-20 11:28:19 -05:00
Adam f6c6bf36e2 feat(app): show/hide reasoning summaries 2026-02-20 10:05:09 -06:00
Adam ed1e1d0beb fix(app): stay pinned with auto-scroll on todos/questions/perms 2026-02-20 10:00:56 -06:00
Aiden Cline f11caadf70 Revert "cache platform binary in postinstall for faster startup" (#14457) 2026-02-20 09:28:49 -06:00
Aiden Cline 6294c7fcd9 cache platform binary in postinstall for faster startup (#14396) 2026-02-20 09:26:13 -06:00
Adam a534bf261b fix(app): patch tool renders like edit tool 2026-02-20 09:13:17 -06:00
Brendan Allan 3fbd2363db desktop: publish betas to separate repo (#14376) 2026-02-20 22:33:21 +08:00
Brendan Allan 7693f37029 desktop: bring back -i in sidecar arguments
shell configs like .zshrc don't get loaded without it
2026-02-20 22:03:23 +08:00
opencode-agent[bot] 9963b362e9 chore: generate 2026-02-20 13:46:03 +00:00
Ryan Vogel 4efb61414b feat: add list sessions for all sessions (experimental) (#14038) 2026-02-20 08:45:12 -05:00
Adam cdcf6313fe fix(app): large text pasted into prompt-input causes main thread lock 2026-02-20 07:38:22 -06:00
Adam e10054f274 fix(app): terminal issues (#14435) 2026-02-20 07:34:36 -06:00
Adam cf9cd38626 chore: update agent 2026-02-20 07:29:02 -06:00
Matt Silverlock 1532e9b9c6 fix(github): support variant in github action and opencode github run (#14431)
publish-github-action / publish (push) Waiting to run
2026-02-20 13:20:54 +00:00
Shoubhit Dash 548e79c8b9 fix(ui): preserve url slashes for root workspace (#14294) 2026-02-20 07:02:48 -06:00
Shoubhit Dash ed9335d434 fix(snapshot): respect info exclude in snapshot staging (#13495) 2026-02-20 07:02:25 -06:00
Shoubhit Dash 152e6aa38a fix(ui): show full turn duration in assistant meta (#14378) 2026-02-20 07:01:13 -06:00
Matt Silverlock c032681cad fix(cli): missing plugin deps cause TUI to black screen (#14432) 2026-02-20 07:39:15 -05:00
Adam 7ce629820e chore: cleanup 2026-02-20 06:30:19 -06:00
opencode 0127fc2c70 release: v1.2.10 2026-02-20 11:18:40 +00:00
Brendan Allan 11f0559f17 sdk: build to dist/ instead of dist/src (#14383) 2026-02-20 14:10:38 +08:00
Brendan Allan 670c2e40f4 desktop: don't spawn sidecar if default is localhost server 2026-02-20 12:18:39 +08:00
Rafi Khardalian f10cd92f54 docs: clarify tool name collision precedence (#14313)
Co-authored-by: Aiden Cline <63023139+rekram1-node@users.noreply.github.com>
2026-02-19 22:00:06 -06:00
Aiden Cline b4a0f89315 test: merge test files into a single file (#14366) 2026-02-19 20:32:01 -06:00
opencode f9c5d42112 release: v1.2.9 2026-02-20 01:45:20 +00:00
Aiden Cline a79b490989 fix: issue from structuredClone addition by using unwrap (#14359) 2026-02-19 19:28:06 -06:00
David Hill 6779a70420 tweak(ui): adjust session feed spacing 2026-02-20 01:22:12 +00:00
David Hill 49c9e680d5 tweak(ui): tone down reasoning emphasis 2026-02-20 01:17:48 +00:00
David Hill 46604515c4 tweak(ui): refine session feed spacing 2026-02-20 01:17:48 +00:00
David Hill 17ad75f582 fix(desktop): restore settings header mask 2026-02-19 18:37:56 -06:00
David Hill e01514e27b tweak(ui): nudge edited files chevron 2026-02-19 18:37:56 -06:00
David Hill e48f68e006 tweak(ui): stabilize collapsible chevron hover 2026-02-19 18:37:56 -06:00
NatChung d06ff01505 fix: add missing id/sessionID/messageID to MCP tool attachments (#14345) 2026-02-19 18:37:56 -06:00
Michael Hart f82eecbc7b Use structuredClone instead of remeda's clone (#14351)
Co-authored-by: Dax Raad <d@ironbay.co>
Co-authored-by: Dax <mail@thdxr.com>
2026-02-19 18:37:56 -06:00
Dax 4e95f2112e remove unnecessary deep clones from session loop and LLM stream (#14354) 2026-02-19 18:37:55 -06:00
Dax Raad 81286a1009 fix(web): correct config import path in Korean enterprise docs 2026-02-19 18:37:55 -06:00
Jay V 60969e4eda docs: update providers layout and Windows sidebar label 2026-02-19 18:37:55 -06:00
Dax Raad 908faf067b core: remove User-Agent header assertion from LLM test to fix failing test 2026-02-19 18:37:55 -06:00
opencode 2e50664b8b release: v1.2.8 2026-02-19 22:38:42 +00:00
Adam 58cb85473d fix(app): black screen on launch with sidecar server 2026-02-19 16:23:33 -06:00
opencode-agent[bot] d398de6672 chore: generate 2026-02-19 22:19:09 +00:00
tctev 17fdd50b98 feat(opencode): support adaptive thinking for claude sonnet 4.6 (#14283)
Co-authored-by: tctev <224793535+tctev@users.noreply.github.com>
Co-authored-by: Aiden Cline <63023139+rekram1-node@users.noreply.github.com>
Co-authored-by: Aiden Cline <aidenpcline@gmail.com>
2026-02-19 16:17:57 -06:00
Yanosh Kunsh e6a27e069f feat(tui): add custom tool and mcp call responses visible and collapsable (#10649)
Co-authored-by: Aiden Cline <63023139+rekram1-node@users.noreply.github.com>
2026-02-19 15:36:40 -06:00
Adam fb78475c3f chore: cleanup 2026-02-19 21:27:39 +00:00
Adam a1b3d266c1 fix(app): clear todos on abort 2026-02-19 21:27:39 +00:00
opencode a19e0061be release: v1.2.7 2026-02-19 21:27:31 +00:00
Matt Silverlock 9e4a788d22 fix(github): action branch detection and 422 handling (#14322)
Co-authored-by: Aiden Cline <63023139+rekram1-node@users.noreply.github.com>
2026-02-19 15:11:59 -06:00
Adam f86aaf3b25 chore: cleanup 2026-02-19 15:09:24 -06:00
Adam 89b66c6e22 chore: refactor composer/dock components (#14328) 2026-02-19 15:02:45 -06:00
Adam a8e2f75c60 fix(app): terminal issues (#14329) 2026-02-19 14:54:09 -06:00
Adam 5015cfa274 chore: cleanup 2026-02-19 14:34:49 -06:00
Adam 3c35e85056 chore: cleanup 2026-02-19 14:31:22 -06:00
Adam 3ccd35851c chore: cleanup 2026-02-19 14:25:12 -06:00
Shintaro Jokagi 0603cc4295 feat(i18n): update Japanese translations to WSL integration (#13160) 2026-02-19 14:18:52 -06:00
Shantur Rathore 1e482a5f1a fix(core): normalize file.status paths relative to instance dir (#14207) 2026-02-19 14:17:36 -06:00
Jun 7ded917a00 docs(ko): improve wording in ecosystem, enterprise, formatters, and github docs (#14220) 2026-02-19 14:17:15 -06:00
opencode-agent[bot] f3f154613b chore: generate 2026-02-19 20:12:16 +00:00
Aiden Cline a927251493 test: fix discovery test to boot up server instead of relying on 3rd party (#14327) 2026-02-19 14:11:23 -06:00
opencode-agent[bot] b3d348107e chore: update nix node_modules hashes 2026-02-19 18:56:40 +00:00
Dax f03cb504c4 refactor: migrate from Bun.Glob to npm glob package (#14317) 2026-02-19 13:40:09 -05:00
Aiden Cline aff1465aab core: bump ai sdk packages for google, google vertex, anthropic, bedrock, and provider utils (#14318) 2026-02-19 12:35:51 -06:00
Aiden Cline 5b59d06f0a tweak: add support for medium reasoning w/ gemini 3.1 (#14316) 2026-02-19 12:00:56 -06:00
opencode-agent[bot] eb98c4729e chore: update nix node_modules hashes 2026-02-19 18:00:22 +00:00
opencode-agent[bot] a27f008a6c chore: update nix node_modules hashes 2026-02-19 17:52:03 +00:00
Dax Raad 350a377fca Revert "refactor: migrate from Bun.Glob to npm glob package"
This reverts commit 25917459f0.
2026-02-19 12:48:43 -05:00
Brendan Allan bc16c88464 app: make localhost urls work in isLocal 2026-02-20 01:38:39 +08:00
Adam 342e7c38d6 chore: cleanup 2026-02-19 11:36:37 -06:00
Dax Raad 25917459f0 refactor: migrate from Bun.Glob to npm glob package
Replace Bun.Glob usage with a new Glob utility wrapper around the npm 'glob' package.
This moves us off Bun-specific APIs toward standard Node.js compatible solutions.

Changes:
- Add new src/util/glob.ts utility module with scan(), scanSync(), and match()
- Default include option is 'file' (only returns files, not directories)
- Add symlink option (default: false) to control symlink following
- Migrate all 12 files using Bun.Glob to use the new Glob utility
- Add comprehensive tests for the glob utility

Breaking changes:
- Removed support for include: 'dir' option (use include: 'all' and filter manually)
- symlink now defaults to false (was true in most Bun.Glob usages)

Files migrated:
- src/util/log.ts
- src/util/filesystem.ts
- src/tool/truncation.ts
- src/session/instruction.ts
- src/storage/json-migration.ts
- src/storage/storage.ts
- src/project/project.ts
- src/cli/cmd/tui/context/theme.tsx
- src/config/config.ts
- src/tool/registry.ts
- src/skill/skill.ts
- src/file/ignore.ts
2026-02-19 12:34:18 -05:00
Adam 17ad6d2a7d chore: cleanup 2026-02-19 11:12:56 -06:00
Adam ea041e239c fix(app): navigate to last session on project nav 2026-02-19 11:12:56 -06:00
Frank f059463ccf zen: gemini 3.1 pro 2026-02-19 11:43:14 -05:00
Dax 019134be58 Remove use of Bun.file (#14215) 2026-02-19 11:32:32 -05:00
Adam 56d85c9c9d chore: cleanup 2026-02-19 09:00:43 -06:00
Adam cdf8ff4d95 fix(app): accordion styles 2026-02-19 09:00:43 -06:00
Adam 5e9ca9b152 fix(core): text files missclassified as binary 2026-02-19 07:32:58 -06:00
Adam 3f506d9d98 chore: cleanup 2026-02-19 07:32:58 -06:00
Brendan Allan 5053f09d8f app: fix typecheck 2026-02-19 21:27:44 +08:00
Brendan Allan da0d89f301 desktop: fetch defaultServer at top level 2026-02-19 21:14:59 +08:00
Adam 90cfdd1dba fix(app): terminal rework (#14217) 2026-02-19 06:35:14 -06:00
opencode-agent[bot] 457747dea0 chore: update nix node_modules hashes 2026-02-19 06:40:44 +00:00
Aiden Cline 3359967745 tweak: bake in the aws and google auth pkgs (#14241) 2026-02-19 00:31:33 -06:00
opencode-agent[bot] 41faa69de3 chore: generate 2026-02-19 05:19:18 +00:00
Ariane Emory a0c7dd68b4 fix: token substitution in OPENCODE_CONFIG_CONTENT (alternate take) (#14047) 2026-02-18 23:18:24 -06:00
Dax Raad 76540602d4 sdk: fix nested exports transformation in publish script
The publish script now recursively transforms export paths to handle nested export objects. This ensures all SDK entry points are correctly mapped to their compiled dist/ locations and type definitions when publishing to npm.
2026-02-18 20:43:50 -05:00
Dax Raad fd2d827df4 tui: ensure onExit callback fires after terminal output is written 2026-02-18 20:43:50 -05:00
Brendan Allan ce27ba4f43 app: deduplicate allServers list 2026-02-19 09:34:23 +08:00
Dax Raad 1567fa548c Revert: all refactor commits migrating from Bun.file() to Filesystem module 2026-02-18 19:41:14 -05:00
Dax f7f149a396 refactor: migrate src/project/project.ts from Bun.file() to Filesystem/stat modules (#14126) 2026-02-18 19:37:10 -05:00
David Hill d7930e092e tweak(ui): rotate collapsible chevron icon 2026-02-19 00:35:12 +00:00
David Hill 6b69644455 tweak(ui): rtl-truncate edited file paths 2026-02-19 00:32:12 +00:00
David Hill 5392fa6d1a tweak(app): adjust session turn horizontal padding 2026-02-19 00:32:12 +00:00
David Hill 50e698b704 tweak(app): tighten prompt dock padding 2026-02-19 00:32:12 +00:00
David Hill 6b823b56ad tweak(ui): add open-file tooltip icon 2026-02-19 00:32:12 +00:00
David Hill c8d7ba66fe tweak(ui): use chevron icons for review diff rows 2026-02-19 00:32:12 +00:00
David Hill 8429974061 tweak(ui): tighten review diff file info gap 2026-02-19 00:32:12 +00:00
David Hill e2f303b71d tweak(ui): show added diff counts in review 2026-02-19 00:32:12 +00:00
David Hill 867efc6b80 tweak(ui): group edited files list styling 2026-02-19 00:32:12 +00:00
David Hill 391ef196b0 Update oc-2.json 2026-02-19 00:32:12 +00:00
David Hill 4adadb3a80 tweak(ui): combine diffs in review into one group 2026-02-19 00:32:12 +00:00
Dax 70d98c3e73 refactor: migrate src/tool/read.ts from Bun.file() to Filesystem module (#14118) 2026-02-18 19:29:11 -05:00
Dax de3c09c4f6 refactor: migrate src/tool/write.ts from Bun.file() to Filesystem module (#14119) 2026-02-18 19:27:11 -05:00
Dax a085913d37 refactor: migrate src/tool/edit.ts from Bun.file() to Filesystem module (#14120) 2026-02-18 19:26:45 -05:00
Dax 52c5e68217 refactor: migrate remaining tool files from Bun.file() to Filesystem/stat modules (#14121) 2026-02-18 19:24:21 -05:00
Dax d64cacad6b refactor: migrate src/storage/storage.ts from Bun.file()/Bun.write() to Filesystem module (#14122) 2026-02-18 19:21:21 -05:00
Dax 9dd856849b refactor: migrate src/storage/json-migration.ts from Bun.file() to Filesystem module (#14123) 2026-02-18 19:20:40 -05:00
Dax 034a62badd refactor: migrate src/mcp/auth.ts from Bun.file()/Bun.write() to Filesystem module (#14125) 2026-02-18 19:20:16 -05:00
Dax 45d66763ea refactor: migrate src/storage/db.ts from Bun.file() to statSync (#14124) 2026-02-18 19:20:03 -05:00
Dax 02f05a0da6 refactor: migrate src/session/prompt.ts from Bun.file() to Filesystem/stat modules (#14128) 2026-02-19 00:18:05 +00:00
Ryan Vogel b24620bb0f chore: skip PR standards checks for PRs created before Feb 18 2026 6PM EST (#14208) 2026-02-18 18:16:43 -05:00
Aiden Cline b755d919a4 fix: opencode run crashing, and show errored tool calls in output (#14206) 2026-02-18 17:13:01 -06:00
Dax f28d2c5fe8 refactor: migrate src/skill/discovery.ts from Bun.file()/Bun.write() to Filesystem module (#14133) 2026-02-18 23:10:24 +00:00
Dax 9c120dfc5d refactor: migrate src/session/instruction.ts from Bun.file() to Filesystem module (#14130) 2026-02-18 18:09:45 -05:00
Dax 5a30e55da0 refactor: migrate src/provider/provider.ts from Bun.file() to Filesystem module (#14132) 2026-02-18 18:08:48 -05:00
Dax 6f95b8615b refactor: migrate src/shell/shell.ts from Bun.file() to statSync (#14134) 2026-02-18 22:55:50 +00:00
Dax d804fadbe4 refactor: migrate src/cli/cmd/tui/thread.ts from Bun.file() to Filesystem module (#14135) 2026-02-18 17:28:41 -05:00
Dax aa0a87de70 refactor: migrate src/util/log.ts from Bun.file() to Node.js fs module (#14136) 2026-02-18 17:28:08 -05:00
Dax 80dc0b3d38 refactor: migrate src/provider/models.ts from Bun.file()/Bun.write() to Filesystem module (#14131) 2026-02-18 17:26:13 -05:00
Dax 4d64284f28 refactor: migrate src/lsp/client.ts from Bun.file() to Filesystem module (#14137) 2026-02-18 17:22:06 -05:00
opencode-agent[bot] a2d4ae9f82 chore: generate 2026-02-18 22:21:17 +00:00
Ryan Vogel 77595cb3ce chore: add compliance checks for issues and PRs with recheck on edit (#14170) 2026-02-18 17:20:23 -05:00
Luke Parker b997638973 fix(win32): Sidecar spawning a window (#14197) 2026-02-19 08:18:15 +10:00
Eduardo Bellido Bellido d00ea65e93 fix(lsp): use HashiCorp releases API for installing terraform-ls (#14200) 2026-02-18 16:11:57 -06:00
Dax a65664fd28 refactor: migrate src/lsp/server.ts from Bun.file()/Bun.write() to Filesystem module (#14138) 2026-02-18 21:41:07 +00:00
David Hill 6814972e36 tweak(app): delay prompt mode toggle tooltip 2026-02-18 21:33:14 +00:00
David Hill c39d981341 tweak(app): shorten prompt mode toggle tooltips 2026-02-18 21:33:14 +00:00
David Hill cc1911cc30 tweak(ui): restyle reasoning blocks 2026-02-18 21:33:14 +00:00
Dax c25a927e33 refactor: migrate src/file/time.ts from Bun.file() to stat (#14141) 2026-02-18 21:22:08 +00:00
Dax 9cee311f00 refactor: migrate src/cli/cmd/session.ts from Bun.file() to statSync (#14144) 2026-02-18 16:20:58 -05:00
Dax 72c7f3d31f refactor: migrate src/acp/agent.ts from Bun.file() to Filesystem module (#14139) 2026-02-18 16:14:20 -05:00
Dax 551cfce7bb refactor: migrate src/auth/index.ts from Bun.file()/Bun.write() to Filesystem module (#14140) 2026-02-18 16:13:50 -05:00
Dax f643d5d306 refactor: migrate src/cli/cmd/agent.ts from Bun.file()/Bun.write() to Filesystem module (#14142) 2026-02-18 21:08:01 +00:00
Dax a20871382b refactor: migrate src/cli/cmd/import.ts from Bun.file() to Filesystem module (#14143) 2026-02-18 21:07:32 +00:00
David Hill 29a893a50a Update oc-2.json 2026-02-18 20:32:54 +00:00
opencode-agent[bot] 6bedaa4396 chore: generate 2026-02-18 20:19:27 +00:00
David Hill 475149fba9 tweak(ui): reduce review panel padding 2026-02-18 20:18:17 +00:00
David Hill a5d85f6567 Update oc-2.json 2026-02-18 20:18:17 +00:00
David Hill 8d68bcd9db tweak(ui): remove pressed scale for secondary buttons 2026-02-18 20:18:17 +00:00
David Hill 1b877dc2f0 tweak(ui): shrink review expand/collapse width 2026-02-18 20:18:17 +00:00
David Hill 9aa9582e65 tweak(ui): tighten review header action spacing 2026-02-18 20:18:17 +00:00
David Hill ba0770adf5 tweak(ui): adjust review diff style hover radius 2026-02-18 20:18:17 +00:00
David Hill e452f29ac4 Update oc-2.json 2026-02-18 20:18:17 +00:00
David Hill 9bdb191a3c tweak(ui): override for the radio group in the review 2026-02-18 20:18:17 +00:00
David Hill fedd2cd252 Update radio-group.css 2026-02-18 20:18:17 +00:00
David Hill d26305a4ae tweak(ui): use default cursor for segmented control 2026-02-18 20:18:17 +00:00
David Hill bfe53507d2 tweak(ui): shrink review diff style toggle 2026-02-18 20:18:17 +00:00
David Hill 09385e7ea0 Update oc-2.json 2026-02-18 20:18:17 +00:00
David Hill 058a8c53a8 Update icon-button.css 2026-02-18 20:18:17 +00:00
David Hill 979a296316 tweak(ui): search button style 2026-02-18 20:18:17 +00:00
David Hill 0fea8f24cd tweak(ui): remove pressed transition for secondary buttons 2026-02-18 20:18:17 +00:00
David Hill 59c3f97d1c Update oc-2.json 2026-02-18 20:18:17 +00:00
David Hill cb245de544 tweak(ui): expanded color state on titlebar buttons 2026-02-18 20:18:17 +00:00
David Hill a0fbd348cf tweak(ui): oc-2 theme updates 2026-02-18 20:18:17 +00:00
David Hill 34a0b53eb8 tweak(ui): hover and active styles for filetree tabs 2026-02-18 20:18:17 +00:00
David Hill 58fc8384a9 tweak(ui): hover and active styles for title bar buttons 2026-02-18 20:18:17 +00:00
David Hill d0efb621b2 tweak(ui): hover and active styles for title bar buttons 2026-02-18 20:18:17 +00:00
David Hill 3e20c45703 tweak(ui): update oc-2 secondary button colors 2026-02-18 20:18:17 +00:00
David Hill e5ba22c7b0 tweak(ui): use weak border and base icon color for secondary 2026-02-18 20:18:17 +00:00
David Hill 2e4eb68207 tweak(ui): theme color updates 2026-02-18 20:18:17 +00:00
David Hill 487ac97563 tweak(ui): shrink filetree tab height 2026-02-18 20:18:17 +00:00
David Hill 16c920d7ce tweak(ui): align pill tabs pressed background 2026-02-18 20:18:16 +00:00
David Hill 7a3faf1b44 tweak(ui): unify titlebar expanded button background 2026-02-18 20:18:16 +00:00
David Hill 70c7334e67 tweak(ui): share button border 2026-02-18 20:18:16 +00:00
David Hill b5601d49ca tweak(ui): file tree background color 2026-02-18 20:18:16 +00:00
David Hill bd10f3e7f9 fix(ui): add previous smoke colors 2026-02-18 20:18:16 +00:00
David Hill 5731324002 button style tweaks 2026-02-18 20:18:16 +00:00
David Hill 7a9994fb64 oc-2 theme init 2026-02-18 20:18:16 +00:00
David Hill 301c9aeee3 Update colors.css 2026-02-18 20:18:16 +00:00
opencode-agent[bot] d38fc241db chore: generate 2026-02-18 20:15:14 +00:00
Helge Tesdal 27a5de8ce1 feat(plugin): pass sessionID and callID to shell.env hook input (#13662) 2026-02-18 14:14:18 -06:00
Adam 63dfadaef9 fix(app): terminal cross-talk (#14184) 2026-02-18 13:56:05 -06:00
Adam ef78e79c2c chore: cleanup 2026-02-18 13:38:51 -06:00
Adam 3e731b8eec chore: cleanup (#14181) 2026-02-18 13:23:20 -06:00
opencode-agent[bot] 021587cfb2 chore: update nix node_modules hashes 2026-02-18 19:08:12 +00:00
Frank fc109e49df zen: update sst version
publish-github-action / publish (push) Waiting to run
2026-02-18 13:54:23 -05:00
Dax 1554d6bd5d refactor: migrate src/global/index.ts from Bun.file() to Filesystem module (#14146) 2026-02-18 13:25:18 -05:00
OpeOginni 017abc9bc3 fix(opencode): update pasteImage to only increment count when the previous attachment is an image too (#14173) 2026-02-18 12:09:09 -06:00
Adam 35a21fc8e4 chore: cleanup 2026-02-18 11:55:08 -06:00
Adam 454ad699d7 chore: cleanup 2026-02-18 11:48:25 -06:00
Adam ab69827b21 chore: cleanup 2026-02-18 11:48:25 -06:00
Adam ecfbb262bf chore: cleanup 2026-02-18 11:48:25 -06:00
Matt Silverlock 0ca00dbc0f fix(github): emit PROMPT_TOO_LARGE error on context overflow (#14166) 2026-02-18 11:45:27 -06:00
Dax 9440a78163 refactor: migrate editor.ts from Bun.file()/Bun.write() to Filesystem module (#14149) 2026-02-18 17:44:33 +00:00
Dax fb762b4be7 refactor: migrate clipboard.ts from Bun.file() to Filesystem module (#14148) 2026-02-18 12:38:44 -05:00
Dax 905cb27dca refactor: migrate src/bun/index.ts from Bun.file()/Bun.write() to Filesystem module (#14147) 2026-02-18 12:38:30 -05:00
Dax bb81cf4767 refactor: migrate uninstall.ts from Bun.file()/Bun.write() to Filesystem module (#14150) 2026-02-18 12:35:55 -05:00
Dax cf25de510c refactor: migrate config/markdown.ts from Bun.file() to Filesystem module (#14151) 2026-02-18 12:35:32 -05:00
Dax 5b87e19ba6 refactor: migrate file/index.ts from Bun.file() to Filesystem module (#14152) 2026-02-18 12:33:20 -05:00
Dax 365e3f49d9 refactor: migrate cli/cmd/github.ts from Bun.write() to Filesystem module (#14154) 2026-02-18 12:33:05 -05:00
Dax 1781a53cd9 refactor: migrate format/formatter.ts from Bun.file() to Filesystem module (#14153) 2026-02-18 12:31:35 -05:00
Dax Raad 7bb954f4eb ci: switch to standard GitHub cache action for Bun dependencies 2026-02-18 12:24:17 -05:00
Dax a8cf960a09 refactor: migrate cli/cmd/run.ts from Bun.file() to Filesystem/stat modules (#14155) 2026-02-18 17:22:46 +00:00
Dax Raad da303416fa core: allow readJson to be called without explicit type parameter
Added default type parameter 'any' to readJson<T> so users can call it without specifying a type when they don't need strict typing. This reduces boilerplate for quick JSON reads where type safety isn't required.
2026-02-18 12:21:25 -05:00
Dax fdc707d73a refactor: migrate file/ripgrep.ts from Bun.file()/Bun.write() to Filesystem module (#14159) 2026-02-18 12:10:42 -05:00
opencode-agent[bot] 39d6af2a26 chore: update nix node_modules hashes 2026-02-18 17:08:31 +00:00
Dax afa481ce44 refactor: migrate index.ts from Bun.file() to Filesystem module (#14160) 2026-02-18 12:03:24 -05:00
Alexander Abramov c09286bc03 feat: add Julia language server support (#14129)
Co-authored-by: Alexander Abramov <abramov231@gmail.com>
2026-02-18 11:02:29 -06:00
Aiden Cline bba9b7750f ignore: tweak contributing md (#14168) 2026-02-18 11:01:59 -06:00
Vladimir Glafirov 53a332b7cc feat: GitLab Duo - bump gitlab-ai-provider to 3.6.0 (adds Sonnet 4.6) (#14115) 2026-02-18 10:58:38 -06:00
Mike Harris de6dfc48ce fix(cli): session list --max-count not honored, shows too few sessions (#14162) 2026-02-18 10:56:37 -06:00
Brendan Allan aaad357f96 desktop: handle sidecar key in projectsKey 2026-02-19 00:05:50 +08:00
Brendan Allan d4243d2d81 desktop: fix isLocal 2026-02-19 00:03:08 +08:00
opencode-agent[bot] 550943051f chore: update nix node_modules hashes 2026-02-18 15:41:20 +00:00
Dax fec69d7af8 feat: Add centralized filesystem module for Bun.file migration (#14117) 2026-02-18 15:30:52 +00:00
Brendan Allan 1601d31c7a app: refactor server management backend (#13813) 2026-02-18 23:03:24 +08:00
Adam 96f20a89f4 fix(app): lower threshold for diff hiding 2026-02-18 08:40:05 -06:00
Adam cf85390af2 chore: cleanup (#14113) 2026-02-18 08:26:15 -06:00
Dax Raad 7954da6dee docs: add policy about AI-generated security reports
We receive a large number of AI-generated security reports and don't have the resources to review them all. This policy clarifies that such submissions will result in an automatic ban to protect our maintainers' time.
2026-02-18 09:15:18 -05:00
Adam 8eb3beb9c0 chore: cleanup 2026-02-18 07:22:36 -06:00
David Hill 63604b9cba fix: use group-hover for file tree icon color swap at all nesting levels 2026-02-18 13:20:02 +00:00
Adam 7a1a870346 chore: cleanup 2026-02-18 07:12:54 -06:00
David Hill 5f6698b9da tui: simplify mode toggle icon styling
Use consistent strong color for active mode icons instead of different
colors for shell vs normal mode, making the active state more visually
clear to users.
2026-02-18 12:35:28 +00:00
Adam 7939eae540 chore: cleanup 2026-02-18 06:32:35 -06:00
Brendan Allan 7dd5d260cd desktop: cleanup 2026-02-18 16:24:28 +08:00
Brendan Allan c210be655d desktop: temporarily disable wsl 2026-02-18 16:10:07 +08:00
Caleb Norton 83cc44f616 ci: allow commits on top of beta PRs (#11924) 2026-02-18 00:20:05 -06:00
Salam Elbilig ffcd51cd13 fix(opencode): fix Clojure syntax highlighting (#13453)
Co-authored-by: Aiden Cline <63023139+rekram1-node@users.noreply.github.com>
2026-02-18 00:18:18 -06:00
Jérôme Benoit 27c2823865 ci: add nix-eval workflow for cross-platform flake evaluation (#12175) 2026-02-18 00:03:37 -06:00
Aiden Cline a0ff03304e fix: ensure explore subagent has external_directory perm set to ask instead of auto denying (#14060) 2026-02-17 20:16:55 -06:00
Aiden Cline e31e36bfc0 fix: dont autoload kilo (#14052) 2026-02-17 18:42:18 -06:00
opencode-agent[bot] a21d6a3d5b chore: generate 2026-02-17 23:53:22 +00:00
RAMA d82e1bf458 feat: add Kilo as a native provider (#13765) 2026-02-17 17:52:21 -06:00
legao 670e4a22bc refactor: simplify redundant ternary in updateMessage (#13954) 2026-02-17 17:40:14 -06:00
opencode-agent[bot] d0a54d4f15 chore: generate 2026-02-17 23:36:08 +00:00
Aiden Cline 1a18dc4252 ci: ensure triage adds acp label (#14039) 2026-02-17 17:34:47 -06:00
Dax Raad 2eb31d01dd tui: exit cleanly without hanging after session ends
- Force process exit after TUI thread completes to prevent lingering processes
- Add 5-second timeout to worker shutdown to prevent indefinite hangs during cleanup
2026-02-17 17:56:39 -05:00
Anton Volkov ad860d3e7a fix(tui): style scrollbox for permission and sidebar (#12752) 2026-02-17 16:24:01 -06:00
Anton Volkov 4087389035 chore: remove leftover patch (#13749) 2026-02-17 16:22:38 -06:00
Aiden Cline 819ee7de5f tweak: ensure read tool uses fs/promises for all paths (#14027) 2026-02-17 16:05:22 -06:00
jackarch-2 3ce013993c chore: add missing newline (#13992) 2026-02-17 16:04:58 -06:00
Adam 5ae4929863 fix(app): better tool call batching 2026-02-17 15:57:50 -06:00
Adam 74ef186e34 chore: cleanup 2026-02-17 15:54:59 -06:00
Adam 097dd4b782 chore(app): use radio group in prompt input (#14025) 2026-02-17 15:53:38 -06:00
Aiden Cline f60db9f708 fix: make read tool more mem efficient (#14009) 2026-02-17 15:36:45 -06:00
opencode-agent[bot] 3d8819a53c chore: generate 2026-02-17 21:23:23 +00:00
Nathan Anderson 04750ce489 feat: surface plugin auth providers in the login picker (#13921)
Co-authored-by: Aiden Cline <63023139+rekram1-node@users.noreply.github.com>
2026-02-17 15:21:49 -06:00
David Hill 36d303d7bb tui: simplify prompt mode toggle icon colors via CSS and tighten message timeline padding 2026-02-17 20:10:16 +00:00
Adam 4e9dfb776c fix(app): prompt input quirks 2026-02-17 13:10:43 -06:00
Frank 43d86c3fb3 zen: sonnet 4.6 2026-02-17 14:10:21 -05:00
Adam b1ef451f67 fix(app): virtualizer getting wrong scroll root 2026-02-17 12:57:40 -06:00
Adam 7bdeca3216 fix(app): terminal disconnect and resync (#14004) 2026-02-17 12:54:28 -06:00
Eduardo Gomes a59b97e7b5 fix: Invalidate oauth credentials when oauth provider says so (#14007)
Co-authored-by: Eduardo Gomes <egomes@cloudflare.com>
2026-02-17 12:46:26 -06:00
Brendan Allan 7ae273aaeb desktop: replicate tauri-plugin-shell logic (#13986) 2026-02-18 02:40:52 +08:00
David Hill 7cc3a3c1f9 tui: improve modified file visibility and button spacing
- Replace warning yellow with distinct orange color for modified files in git diff indicators
- Increase button padding for better visual balance in session header and status popover
2026-02-17 18:39:21 +00:00
David Hill 654371e152 tui: show monochrome file icons by default in tree view, revealing colors on hover to reduce visual clutter and help users focus on code content 2026-02-17 18:23:04 +00:00
David Hill ebda560dcd tui: fix share button text styling to use consistent 12px regular font weight 2026-02-17 17:55:55 +00:00
David Hill f1c0afd831 tweak(ui): update icon transparency 2026-02-17 17:52:29 +00:00
David Hill 0f578ffd67 fix(ui): use icon-strong-base for active titlebar icon buttons 2026-02-17 17:51:49 +00:00
David Hill aa96cc2450 tweak(ui): icon-interactive-base color change dark mode 2026-02-17 17:43:37 +00:00
David Hill de5ab6670c tui: add warning icon to permission requests for better visibility
Adds a visual warning indicator to permission request dialogs to make

them more noticeable and help users understand when the agent needs

approval to use tools. Also improves the layout with consistent

spacing and icon alignment.
2026-02-17 17:43:37 +00:00
David Hill eb74287766 refactor(ui): extract dock prompt shell 2026-02-17 17:43:37 +00:00
David Hill b0df665f7f tweak(ui): bump button heights and align permission prompt layout 2026-02-17 17:43:37 +00:00
Aiden Cline 5db4881590 ci: rm remap for jlongster since he is in org now (#14000) 2026-02-17 11:08:35 -06:00
Caleb Norton fe3cf3fb4e fix: don't fetch models.dev on completion (#13997) 2026-02-17 10:41:03 -06:00
Alex Carpenter 748441e94f fix: Homepage video section layout shift (#13987) 2026-02-17 21:22:47 +05:30
Filip fcdeb539e1 fix(app): ui flashing when switching tabs (#13978) 2026-02-17 21:19:20 +05:30
Chris Yang 2e70bb8536 fix(desktop): avoid sidecar health-check timeout on shell startup (#13925)
Co-authored-by: Brendan Allan <brendonovich@outlook.com>
2026-02-17 15:34:16 +00:00
David Hill 3f758a45ac tui: increase prompt mode toggle height for better clickability 2026-02-17 15:28:35 +00:00
David Hill 78d7941b03 ui: add clearer 'Copy response' tooltip label for text parts 2026-02-17 15:19:30 +00:00
David Hill fb55cdfa31 tweak(ui): allow full-width user message meta
Moves the user message meta row out of the bubble width constraints and truncates long metadata while keeping the timestamp visible with consistent middot spacing.
2026-02-17 15:16:07 +00:00
David Hill 3e05628d2d tweak(ui): show assistant response meta on hover
Adds hover-only metadata after the assistant copy icon showing agent, provider, model, and response duration.
2026-02-17 15:16:07 +00:00
David Hill d452d7ba0b tweak(ui): refine user message hover meta
Moves the interrupted state into the user message hover metadata and updates the copy tooltip to 'Copy message'.
2026-02-17 15:16:07 +00:00
David Hill ce98e719df tweak(ui): use provider catalog names
Renders provider and model display names from the provider list instead of raw IDs in user message hover metadata.
2026-02-17 15:16:07 +00:00
David Hill 53bda77a24 tweak(ui): show user message meta on hover
Adds a hover-only metadata line under user messages showing agent, provider, model, and timestamp for quicker context.
2026-02-17 15:16:07 +00:00
opencode-agent[bot] 0040434203 chore: generate 2026-02-17 14:43:42 +00:00
Filip 46b82d4b18 feat(desktop): more e2e tests (#13975) 2026-02-17 08:42:50 -06:00
David Hill 18676b27ed tweak(ui): update magnifying-glass icon
Replace the magnifying-glass glyph with a 16px viewBox variant and keep default 1px stroke; adjust the titlebar search to render the icon at 16x16.
2026-02-17 14:37:44 +00:00
David Hill ebbbe1b542 tweak(app): tighten titlebar action padding
Use pr-2 for the status and fallback copy-path actions, and tighten the copy icon/text gap to 1.5.
2026-02-17 14:37:44 +00:00
David Hill 11057f3e19 tweak(app): refine titlebar search and open padding
Ensure the titlebar search placeholder truncates cleanly and left-aligns; match the fallback copy-path button left padding to the open action.
2026-02-17 14:37:44 +00:00
David Hill 43980f5f7f tweak(ui): center titlebar search and soften keybind
Mount the titlebar search in the center area and tune its sizing/spacing; use regular weight for the keybind pill text.
2026-02-17 14:37:44 +00:00
David Hill 10ebb7bc8d tweak(app): align titlebar search text size
Use the same 12px text style for the titlebar search placeholder as the status and open actions.
2026-02-17 14:37:44 +00:00
David Hill dbfe349835 tweak(app): match titlebar active bg to hover
Use the ghost hover background for active/expanded titlebar actions and tighten titlebar popover gutters to 4px.
2026-02-17 14:37:44 +00:00
David Hill 13215893c7 tweak(app): use weak borders in titlebar actions
Use border-border-weak-base for the titlebar status and open actions (including the open button divider) and adjust the English copy-path label casing.
2026-02-17 14:37:44 +00:00
David Hill 36c5099526 tweak(app): reduce titlebar right padding
Use pr-2 (instead of pr-6) on the titlebar right section when not on Windows.
2026-02-17 14:37:44 +00:00
David Hill 46445637c0 tweak(app): keep file tree toggle visible
Always show the titlebar file tree button (and space the right-side icon buttons at 4px) so it stays accessible regardless of the review panel state.
2026-02-17 14:37:44 +00:00
opencode-agent[bot] 78b151a6ce chore: generate 2026-02-17 13:45:58 +00:00
David Hill bcf3147de2 tweak(ui): icon button spacing 2026-02-17 13:44:59 +00:00
Adam 0def91889d chore: app polish (#13976)
Co-authored-by: David Hill <iamdavidhill@gmail.com>
2026-02-17 07:34:02 -06:00
Adam e356fe0b53 feat(app): session timeline/turn rework (#13196)
Co-authored-by: David Hill <iamdavidhill@gmail.com>
2026-02-17 07:16:23 -06:00
Shoubhit Dash 8450e352cc fix(app): recover state after sse reconnect and harden sse streams (#13973) 2026-02-17 07:10:39 -06:00
David Hill 39d6c83c2f tweak(tui): new session banner with logo and details (#13970) 2026-02-17 07:43:55 -05:00
opencode-agent[bot] 2129adeceb chore: generate 2026-02-17 12:08:03 +00:00
Minung Han ee74657e6a fix(docs): correct reversed meaning in Korean plugins logging section (#13945) 2026-02-17 06:07:09 -06:00
chenmi d77c4f8cf6 docs: improve zh-cn and zh-tw documentation translations (#13942) 2026-02-17 06:06:39 -06:00
vynn e4cd36df5c docs(ko): improve Korean translation accuracy and clarity in Zen docs (#13951) 2026-02-17 06:05:37 -06:00
Ganesh 8dce263980 fix(app): keep Escape handling local to prompt input on macOS desktop (#13963) 2026-02-17 06:04:11 -06:00
Aiden Cline 22cf274844 ci: update triage workflow (#13944) 2026-02-17 01:05:56 -06:00
Frank 6c7ef3861d wip: zen 2026-02-17 01:32:57 -05:00
Frank 212d0f536c zen: glm 5 free 2026-02-17 01:12:13 -05:00
Brendan Allan c76e89645e Hide server CLI on windows (#13936) 2026-02-17 12:43:25 +08:00
Goni Zahavy 483f0e31a5 ci: fixed missing if condition (#13934) 2026-02-17 12:42:55 +08:00
Goni Zahavy 283c2209d5 ci: fixed Rust cache for 'cargo install' in publish.yml (#13907) 2026-02-17 12:13:33 +08:00
Aiden Cline f79ecdf133 core: keep message part order stable when files resolve asynchronously (#13915) 2026-02-16 18:45:11 -06:00
Goni Zahavy c4159b7b23 ci: use useblacksmith/stickydisk on linux runners only (#13909) 2026-02-16 18:27:04 -06:00
Goni Zahavy 69ab1be1a4 ci: fixed apt cache not working in publish.yml (#13897) 2026-02-16 17:31:38 -06:00
James Long ec37a942f0 fix(website): fix site in safari 18 (#13894) 2026-02-16 17:39:28 -05:00
Aiden Cline b650f36291 tweak: drop ids from attachments in tools, assign them in prompt.ts instead (#13890) 2026-02-16 14:59:57 -06:00
ImmuneFOMO 4bbf818885 feat(acp): add opt-in flag for question tool (#13562)
Co-authored-by: Aiden Cline <63023139+rekram1-node@users.noreply.github.com>
Co-authored-by: Aiden Cline <aidenpcline@gmail.com>
2026-02-16 14:20:41 -06:00
Zhiyuan Zheng 0cf00abdaf fix(opencode): ACP sessions never get LLM-generated titles (#13095) 2026-02-16 14:16:17 -06:00
Ariane Emory 06ed74fbfc feat(cli): add session delete command (#13571) 2026-02-16 14:15:34 -06:00
opencode 4fde8a4bd1 release: v1.2.6 2026-02-16 19:57:09 +00:00
Robert Schadek d9738369c7 feat(opencode): add dfmt formatter support for D language files (#13867) 2026-02-16 13:14:35 -06:00
OpeOginni 1c00beffce fix(tui): make use of server dir path for file references in prompts (#13781) 2026-02-16 13:14:08 -06:00
Aiden Cline ce14b70575 ignore: rm random comment on opencode.jsonc 2026-02-16 13:09:39 -06:00
Dax 608ed34b3e feat(cli): add db migrate command for JSON to SQLite migration (#13874) 2026-02-16 19:05:21 +00:00
Ryan Vogel 8f80fdc586 feat(cli): add --continue and --fork flags to attach command (#13879) 2026-02-16 13:45:00 -05:00
opencode-agent[bot] 1a2dfee1a0 chore: update nix node_modules hashes 2026-02-16 17:38:43 +00:00
Vladimir Glafirov 2bd6db464f fix: bump GitLab provider and auth plugin for mid-session token refresh (#13850) 2026-02-16 10:01:17 -06:00
Imanol Maiztegui a0cc83399f fix (tui): Inaccurate tips (#13845) 2026-02-16 09:08:04 -05:00
Adam d77cda69e3 chore: cleanup 2026-02-16 07:58:18 -06:00
Rafi Khardalian 60cebc3f94 fix(core): remove unnecessary per-message title LLM calls (#13804) 2026-02-16 06:04:20 -06:00
Chujiang 92acf8710a fix(docs): correct critical translation errors in Russian zen page (#13830) 2026-02-16 06:02:48 -06:00
Aiden Cline 31a30bea6b fix: google vertex var priority (#13816) 2026-02-16 02:41:52 -06:00
opencode-agent[bot] d21dab6a62 chore: generate 2026-02-16 08:32:34 +00:00
Jhin Lee b299880f49 feat: add openai-compatible endpoint support for google-vertex provider (#10303)
Co-authored-by: BlueT - Matthew Lien - 練喆明 <BlueT@BlueT.org>
Co-authored-by: Aiden Cline <63023139+rekram1-node@users.noreply.github.com>
Co-authored-by: Aiden Cline <aidenpcline@gmail.com>
2026-02-16 02:31:48 -06:00
bnema 527bbd2ab2 fix(desktop): normalize Linux Wayland/X11 backend and decoration policy (#13143)
Co-authored-by: Brendan Allan <brendonovich@outlook.com>
2026-02-16 13:24:28 +08:00
dpuyosa 94e2af3c60 feat(opencode): Add Venice support in temperature, topP, topK and smallOption (#13553) 2026-02-15 22:24:24 -06:00
Brendan Allan 9ae9e4ca40 desktop: use process-wrap instead of manual job object (#13431) 2026-02-16 04:14:24 +00:00
opencode-agent[bot] 4505bacd12 chore: generate 2026-02-15 22:31:40 +00:00
Pan Kaixin c82822acfe fix(website): correct zh-CN translation of proprietary terms in zen.mdx (#13734)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2026-02-15 16:30:47 -06:00
Salam Elbilig a3955fbd94 feat(opencode): add cljfmt formatter support for Clojure files (#13426) 2026-02-15 15:21:57 -06:00
opencode bdf6ef7a03 release: v1.2.5 2026-02-15 18:49:52 +00:00
Alex Yaroshuk cd18f1ecfd feat(app): localize "free usage exceeded" error & "Add credits" clickable link (#13652) 2026-02-15 10:40:09 -06:00
Shane Bishop 3becafd7c1 fix(desktop): issue viewing new files opened from the file tree (#13689) 2026-02-15 09:48:40 -06:00
Shoubhit Dash 9d1538d054 fix(app): only navigate prompt history at input boundaries (#13690) 2026-02-15 07:47:19 -06:00
Filip 548cd157e0 fix(app): keybind [shift+tab] (#13695) 2026-02-15 07:46:56 -06:00
Denys 5bade9b029 docs: add Ukrainian README translation (#13697) 2026-02-15 07:46:19 -06:00
zerone0x 130bb1193e fix(desktop): focus window after update/relaunch (#13701) 2026-02-15 07:45:34 -06:00
Brandon Julio Thenaro 67493eca3c feat: Add GeistMono Nerd Font to available mono font options (#13720) 2026-02-15 07:44:21 -06:00
Aiden Cline 9ebad0abf2 fix: ensure sqlite migration logs to stderr instead of stdout (#13691) 2026-02-15 00:41:16 -06:00
opencode 77efa92bfe release: v1.2.4 2026-02-15 01:55:33 +00:00
Dax Raad d53ded7e9f core: add db command for database inspection and querying 2026-02-14 20:37:17 -05:00
Dax Raad 8047a789ab test: add tests for path-derived IDs in json migration
Tests verify that file paths are used for IDs even when JSON contains
different values - ensuring robustness against stale JSON content.
2026-02-14 20:37:17 -05:00
Dax Raad 69f47bbead fix: derive all IDs from file paths during json migration
Earlier migrations moved data to new directories without updating JSON
fields. Now consistently derives all IDs from file paths:

- Projects: id from filename
- Sessions: id from filename, projectID from parent directory
- Messages: id from filename, sessionID from parent directory
- Parts: id from filename, messageID from parent directory

This ensures migrated data matches the actual file layout regardless of
stale values in JSON content.
2026-02-14 20:37:17 -05:00
Adam 47f48aecef feat(app): clear notifications action (#13668)
Co-authored-by: adamelmore <2363879+adamdottv@users.noreply.github.com>
2026-02-14 19:33:22 -06:00
Adam 8671381071 fix(app): stack overflow in filetree (#13667)
Co-authored-by: adamelmore <2363879+adamdottv@users.noreply.github.com>
2026-02-14 19:24:48 -06:00
opencode 69d967dc74 release: v1.2.3 2026-02-15 00:34:56 +00:00
opencode-agent[bot] af5452b624 chore: update nix node_modules hashes 2026-02-14 20:38:57 +00:00
Aiden Cline b4bd78ce79 fix: ensure anthropic models on OR also have variant support (#13498) 2026-02-14 14:30:07 -06:00
Dax a16afa7f25 fix: add WAL checkpoint on database open (#13633) 2026-02-14 19:33:08 +00:00
Alberto Valverde 8a4643fee4 chore: bump nixpkgs to get bun 1.3.9 (#13302) 2026-02-14 13:21:31 -06:00
Aiden Cline eb3e9c74c6 fix: ensure vercel variants pass amazon models under bedrock key (#13631) 2026-02-14 13:18:52 -06:00
opencode d28116ff35 release: v1.2.2 2026-02-14 19:08:58 +00:00
Dax Raad 595aab70c5 core: add comprehensive test coverage for Session.list() filters
Adds test cases for filtering sessions by directory, root sessions only,

start time, search terms, and result limits to ensure the listing

functionality works correctly for all filter combinations.
2026-02-14 13:43:41 -05:00
Dax Raad 0b5c218fd3 core: filter sessions at database level to improve session list loading performance 2026-02-14 13:41:15 -05:00
opencode-agent[bot] f96f5bfaff chore: update nix node_modules hashes 2026-02-14 18:38:18 +00:00
Aiden Cline 442fc7c1c7 fix vercel gateway variants (#13541)
Co-authored-by: Benjamin Woodruff <github@benjam.info>"
2026-02-14 12:32:29 -06:00
Aiden Cline f32d70e2b3 bump vertex ai packages (#13625) 2026-02-14 12:29:01 -06:00
Brendan Allan d9cf22304e ci: move signpath policy 2026-02-14 14:47:50 +08:00
Brendan Allan cb8fbbb52c ci: test-signing signpath policy 2026-02-14 06:39:53 +00:00
opencode 8b7b63e86b release: v1.2.1 2026-02-14 06:39:47 +00:00
Dax Raad 8aa91f5646 tui: show all project sessions from any working directory
Previously sessions were only listed if they were created in the current
working directory or its subdirectories. Users can now view and switch
to any session in the project regardless of which directory they're in.
2026-02-14 01:21:41 -05:00
Aiden Cline 580474d9c9 fix: tweak websearch tool description date info to avoid cache busts (#13559) 2026-02-13 23:59:10 -06:00
Frank a9aef2452b zen: minimax m2.5 & glm5 2026-02-14 00:47:26 -05:00
opencode 2f9fddc3c1 release: v1.2.0 2026-02-14 05:20:11 +00:00
Brendan Allan 1c4a2f364c desktop: fix rust 2026-02-14 12:48:16 +08:00
opencode-agent[bot] 320089517f chore: update nix node_modules hashes 2026-02-14 04:28:27 +00:00
Brendan Allan 5e6542a048 desktop: remote OPENCODE_SQLITE env (#13545) 2026-02-13 23:20:09 -05:00
opencode-agent[bot] 90f1ec7aa1 chore: generate 2026-02-14 04:19:48 +00:00
Dax 3010323ee0 sqlite again (#10597)
Co-authored-by: Github Action <action@github.com>
Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com>
Co-authored-by: Brendan Allan <git@brendonovich.dev>
2026-02-14 04:19:02 +00:00
Kevin 3585a8b57a fix: prevent opencode run crash on malformed tool inputs (#13051)
Co-authored-by: 0xK3vin <kevin@git-pu.sh>
2026-02-13 20:54:20 -06:00
Kit Langton d1383711cf fix(ui): support cmd-click links in inline code (#12552) 2026-02-13 13:57:38 -06:00
Niu Shuai 784ed20f89 fix: standardize zh-CN docs character set and terminology (#13500) 2026-02-13 12:58:12 -06:00
严浩 42b479ca38 fix(test): move timeout config to CLI flag (#13494)
Co-authored-by: 严浩 <h_mini2024@oo1.dev>
2026-02-13 10:20:02 -05:00
G36maid f01a65b9f2 docs: add pacman installation option for Arch Linux alongside AUR (#13293) 2026-02-13 09:07:48 -06:00
Jun ba69269b31 docs(ko): polish Korean phrasing in acp, agents, config, and custom-tools docs (#13446) 2026-02-13 09:05:29 -06:00
Adam 54d541a20e chore: cleanup 2026-02-13 05:52:43 -06:00
Adam 71578b0944 fix(app): terminal resize 2026-02-13 05:52:42 -06:00
eytans 6f912fab89 fix(web): use prompt_async endpoint to avoid timeout over VPN/tunnel (#12749) 2026-02-13 05:25:47 -06:00
opencode-agent[bot] 17c0f8d126 chore: generate 2026-02-13 11:19:37 +00:00
Annopick 5e74a01d6c docs: Fix zh-cn translation mistake in tools.mdx (#13407) 2026-02-13 05:18:47 -06:00
Chris Yang fdd054e79a fix(app): remount SDK/sync tree when server URL changes (#13437) 2026-02-13 05:16:14 -06:00
Jun 8e3ef4ef40 fix(web): sync docs locale cookie on alias redirects (#13109) 2026-02-13 05:12:28 -06:00
Filip fc2f7b2e2e fix(desktop): performance optimization for showing large diff & files (#13460) 2026-02-13 05:08:13 -06:00
opencode-agent[bot] 066b5fd157 chore: update nix node_modules hashes 2026-02-13 07:06:28 +00:00
Rahul Mishra f8e94fd002 feat(cli): add --dir option to run command (#12443) 2026-02-13 00:59:37 -06:00
Aiden Cline b4fe75a169 feat: update some ai sdk packages and uuse adaptive reasoning for opus 4.6 on vertex/bedrock/anthropic (#13439) 2026-02-13 00:56:11 -06:00
opencode 87f670136c release: v1.1.65 2026-02-13 05:51:04 +00:00
Aiden Cline 231fcfe6fd Revert "fix: token substitution in OPENCODE_CONFIG_CONTENT" (#13429) 2026-02-12 23:24:31 -06:00
Aiden Cline b672abb2f4 fix: ensure @-ing a dir uses the read tool instead of dead list tool (#13428) 2026-02-12 23:20:33 -06:00
Spoon 6bb8334384 feat(hook): add tool.definition hook for plugins to modify tool description and parameters (#4956) 2026-02-12 22:52:17 -06:00
Brendan Allan 9d626c92bb ci: remove signpath policy 2026-02-13 10:46:45 +08:00
Adam 51d41ac541 fix(app): reconnect event stream on disconnect 2026-02-12 20:20:24 -06:00
Adam 859142d98e feat(app): toggle all provider models 2026-02-12 20:19:26 -06:00
Brendan Allan 0d1314716b cleanup desktop loading page 2026-02-13 10:15:36 +08:00
Adam 894252dae2 fix(app): emoji as avatar 2026-02-12 20:05:58 -06:00
Adam 24b0ba5af7 fix(app): notification should navigate to session 2026-02-12 20:04:36 -06:00
Adam 4ac7e2c1c4 fix(app): prompt input quirks 2026-02-12 19:58:57 -06:00
Adam adee23caee chore: cleanup 2026-02-12 19:52:20 -06:00
Adam 4588a0f6dc fix(app): worktree delete 2026-02-12 19:38:13 -06:00
Adam 0fe62dda07 fix(app): failed to create store 2026-02-12 19:38:06 -06:00
Brendan Allan aed38b4179 desktop: only show loading window if sqlite migration is necessary 2026-02-13 08:49:52 +08:00
projectArtur a9e44df330 fix: resolve ACP hanging indefinitely in thinking state on Windows (#13222)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: LukeParkerDev <10430890+Hona@users.noreply.github.com>
Co-authored-by: Aiden Cline <63023139+rekram1-node@users.noreply.github.com>
Co-authored-by: Aiden Cline <aidenpcline@gmail.com>
2026-02-12 18:20:00 -06:00
opencode 71564d475e release: v1.1.64 2026-02-12 23:18:40 +00:00
Ariane Emory b833c4de7d fix: token substitution in OPENCODE_CONFIG_CONTENT (#13384) 2026-02-12 16:59:44 -06:00
Aiden Cline 56f63313f3 chore: cleanup flag code (#13389) 2026-02-12 22:38:51 +00:00
opencode-agent[bot] 51f3a5e7a3 chore: generate 2026-02-12 22:14:45 +00:00
Smit Chaudhary 939c63627e fix: look for recent model in fallback in cli (#12582) 2026-02-12 16:13:48 -06:00
opencode-agent[bot] 8f424fefbe chore: update nix node_modules hashes 2026-02-12 22:04:31 +00:00
Luke Parker 4ac99b73d8 fix: baseline CPU detection (#13371) 2026-02-13 07:50:43 +10:00
Luke Parker 2dd654eea6 feat: windows selection behavior, manual ctrl+c (#13315) 2026-02-13 07:38:27 +10:00
Sebastian 89a6043fa5 do not open console on error (#13374) 2026-02-12 21:29:58 +00:00
opencode-agent[bot] 95ef7ef7e6 chore: generate 2026-02-12 21:23:32 +00:00
Aman Kalra 9ab6f85b04 docs: update STACKIT provider documentation with typo fix (#13357)
Co-authored-by: amankalra172 <aman.kalra@st.ovgu.de>
2026-02-12 15:22:35 -06:00
Adam e01225bf8c fix(app): terminal pty isolation 2026-02-12 15:15:34 -06:00
Adam 2109a38435 feat(app): option to turn off sound effects 2026-02-12 15:03:05 -06:00
Adam 4141e50ff4 fix(app): normalize oauth error messages 2026-02-12 14:58:25 -06:00
Adam 31ffb33678 chore: cleanup 2026-02-12 14:48:09 -06:00
Adam 1f08c79612 chore: cleanup 2026-02-12 14:43:20 -06:00
Adam fb5082f677 chore: cleanup 2026-02-12 14:39:02 -06:00
Adam f678b09a5a chore: cleanup 2026-02-12 14:32:31 -06:00
Adam 411cc62153 chore: cleanup 2026-02-12 14:24:19 -06:00
Adam 72802e39be fix(app): suggestion active state broken 2026-02-12 14:17:05 -06:00
Adam 0985166f1d fix(app): remote http server connections 2026-02-12 13:41:22 -06:00
Aiden Cline b4aac36f17 test: add more test cases for project.test.ts (#13355) 2026-02-12 18:46:44 +00:00
2075 changed files with 224379 additions and 91932 deletions
+15
View File
@@ -0,0 +1,15 @@
adamdotdevin
Brendonovich
fwang
Hona
iamdavidhill
jayair
jlongster
kitlangton
kommander
MrMushrooooom
nexxeln
R44VC0RP
rekram1-node
RhysSullivan
thdxr
+6
View File
@@ -8,13 +8,19 @@
# - Denounce with minus prefix: -username or -platform:username.
# - Optional details after a space following the handle.
adamdotdevin
-agusbasari29 AI PR slop
ariane-emory
-atharvau AI review spamming literally every PR
-danieljoshuanazareth
-danieljoshuanazareth
edemaine
-florianleibert
fwang
iamdavidhill
jayair
kitlangton
kommander
-opencode2026
r44vc0rp
rekram1-node
-spider-yamet clawdbot/llm psychosis, spam pinging the team
+41 -7
View File
@@ -3,17 +3,51 @@ description: "Setup Bun with caching and install dependencies"
runs:
using: "composite"
steps:
- name: Mount Bun Cache
uses: useblacksmith/stickydisk@v1
with:
key: ${{ github.repository }}-bun-cache-${{ runner.os }}
path: ~/.bun
- name: Get baseline download URL
id: bun-url
shell: bash
run: |
if [ "$RUNNER_ARCH" = "X64" ]; then
V=$(node -p "require('./package.json').packageManager.split('@')[1]")
case "$RUNNER_OS" in
macOS) OS=darwin ;;
Linux) OS=linux ;;
Windows) OS=windows ;;
esac
echo "url=https://github.com/oven-sh/bun/releases/download/bun-v${V}/bun-${OS}-x64-baseline.zip" >> "$GITHUB_OUTPUT"
fi
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version-file: package.json
bun-version-file: ${{ !steps.bun-url.outputs.url && 'package.json' || '' }}
bun-download-url: ${{ steps.bun-url.outputs.url }}
- name: Get cache directory
id: cache
shell: bash
run: echo "dir=$(bun pm cache)" >> "$GITHUB_OUTPUT"
- name: Cache Bun dependencies
uses: actions/cache@v4
with:
path: ${{ steps.cache.outputs.dir }}
key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lock') }}
restore-keys: |
${{ runner.os }}-bun-
- name: Install setuptools for distutils compatibility
run: python3 -m pip install setuptools || pip install setuptools || true
shell: bash
- name: Install dependencies
run: bun install
run: |
# Workaround for patched peer variants
# e.g. ./patches/ for standard-openapi
# https://github.com/oven-sh/bun/issues/28147
if [ "$RUNNER_OS" = "Windows" ]; then
bun install --linker hoisted
else
bun install
fi
shell: bash
+23 -1
View File
@@ -1,7 +1,29 @@
### Issue for this PR
Closes #
### Type of change
- [ ] Bug fix
- [ ] New feature
- [ ] Refactor / code improvement
- [ ] Documentation
### What does this PR do?
Please provide a description of the issue (if there is one), the changes you made to fix it, and why they work. It is expected that you understand why your changes work and if you do not understand why at least say as much so a maintainer knows how much to value the PR.
Please provide a description of the issue, the changes you made to fix it, and why they work. It is expected that you understand why your changes work and if you do not understand why at least say as much so a maintainer knows how much to value the PR.
**If you paste a large clearly AI generated description here your PR may be IGNORED or CLOSED!**
### How did you verify your code works?
### Screenshots / recordings
_If this is a UI change, please include a screenshot or recording._
### Checklist
- [ ] I have tested my changes locally
- [ ] I have not included unrelated changes in this PR
_If you do not follow this template your PR will be automatically rejected._
+4
View File
@@ -27,7 +27,11 @@ jobs:
opencode-app-id: ${{ vars.OPENCODE_APP_ID }}
opencode-app-secret: ${{ secrets.OPENCODE_APP_SECRET }}
- name: Install OpenCode
run: bun i -g opencode-ai
- name: Sync beta branch
env:
GH_TOKEN: ${{ steps.setup-git-committer.outputs.token }}
OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }}
run: bun script/beta.ts
+24
View File
@@ -0,0 +1,24 @@
name: close-issues
on:
schedule:
- cron: "0 2 * * *" # Daily at 2:00 AM
workflow_dispatch:
jobs:
close:
runs-on: ubuntu-latest
permissions:
contents: read
issues: write
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Close stale issues
env:
GITHUB_TOKEN: ${{ github.token }}
run: bun script/github/close-issues.ts
+9
View File
@@ -65,6 +65,15 @@ jobs:
body: closeMessage,
});
try {
await github.rest.issues.removeLabel({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: item.number,
name: 'needs:compliance',
});
} catch (e) {}
if (isPR) {
await github.rest.pulls.update({
owner: context.repo.owner,
+1 -1
View File
@@ -11,7 +11,7 @@ concurrency: ${{ github.workflow }}-${{ github.ref }}
jobs:
deploy:
runs-on: blacksmith-4vcpu-ubuntu-2404
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
+24 -10
View File
@@ -12,13 +12,14 @@ jobs:
if: github.actor != 'opencode-agent[bot]'
runs-on: blacksmith-4vcpu-ubuntu-2404
permissions:
id-token: write
contents: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
persist-credentials: false
fetch-depth: 0
ref: ${{ github.ref_name }}
- name: Setup Bun
uses: ./.github/actions/setup-bun
@@ -46,15 +47,26 @@ jobs:
echo "EOF"
} >> "$GITHUB_OUTPUT"
- name: Install OpenCode
if: steps.changes.outputs.has_changes == 'true'
run: curl -fsSL https://opencode.ai/install | bash
- name: Sync locale docs with OpenCode
if: steps.changes.outputs.has_changes == 'true'
uses: sst/opencode/github@latest
env:
OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }}
with:
model: opencode/gpt-5.2
agent: docs
prompt: |
OPENCODE_CONFIG_CONTENT: |
{
"permission": {
"*": "deny",
"read": "allow",
"edit": "allow",
"glob": "allow",
"task": "allow"
}
}
run: |
opencode run --agent docs --model opencode/gpt-5.3-codex <<'EOF'
Update localized docs to match the latest English docs changes.
Changed English doc files:
@@ -67,10 +79,12 @@ jobs:
2. You MUST use the Task tool for translation work and launch subagents with subagent_type `translator` (defined in .opencode/agent/translator.md).
3. Do not translate directly in the primary agent. Use translator subagent output as the source for locale text updates.
4. Run translator subagent Task calls in parallel whenever file/locale translation work is independent.
5. Preserve frontmatter keys, internal links, code blocks, and existing locale-specific metadata unless the English change requires an update.
6. Keep locale docs structure aligned with their corresponding English pages.
7. Do not modify English source docs in packages/web/src/content/docs/*.mdx.
8. If no locale updates are needed, make no changes.
5. Use only the minimum tools needed for this task (read/glob, file edits, and translator Task). Do not use shell, web, search, or GitHub tools for translation work.
6. Preserve frontmatter keys, internal links, code blocks, and existing locale-specific metadata unless the English change requires an update.
7. Keep locale docs structure aligned with their corresponding English pages.
8. Do not modify English source docs in packages/web/src/content/docs/*.mdx.
9. If no locale updates are needed, make no changes.
EOF
- name: Commit and push locale docs updates
if: steps.changes.outputs.has_changes == 'true'
+62 -2
View File
@@ -2,10 +2,11 @@ name: duplicate-issues
on:
issues:
types: [opened]
types: [opened, edited]
jobs:
check-duplicates:
if: github.event.action == 'opened'
runs-on: blacksmith-4vcpu-ubuntu-2404
permissions:
contents: read
@@ -34,7 +35,7 @@ jobs:
"webfetch": "deny"
}
run: |
opencode run -m opencode/claude-haiku-4-5 "A new issue has been created:
opencode run -m opencode/claude-sonnet-4-6 "A new issue has been created:
Issue number: ${{ github.event.issue.number }}
@@ -115,3 +116,62 @@ jobs:
If you believe this was flagged incorrectly, please let a maintainer know.
Remember: post at most ONE comment combining all findings. If everything is fine, post nothing."
recheck-compliance:
if: github.event.action == 'edited' && contains(github.event.issue.labels.*.name, 'needs:compliance')
runs-on: blacksmith-4vcpu-ubuntu-2404
permissions:
contents: read
issues: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 1
- uses: ./.github/actions/setup-bun
- name: Install opencode
run: curl -fsSL https://opencode.ai/install | bash
- name: Recheck compliance
env:
OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
OPENCODE_PERMISSION: |
{
"bash": {
"*": "deny",
"gh issue*": "allow"
},
"webfetch": "deny"
}
run: |
opencode run -m opencode/claude-sonnet-4-6 "Issue #${{ github.event.issue.number }} was previously flagged as non-compliant and has been edited.
Lookup this issue with gh issue view ${{ github.event.issue.number }}.
Re-check whether the issue now follows our contributing guidelines and issue templates.
This project has three issue templates that every issue MUST use one of:
1. Bug Report - requires a Description field with real content
2. Feature Request - requires a verification checkbox and description, title should start with [FEATURE]:
3. Question - requires the Question field with real content
Additionally check:
- No AI-generated walls of text (long, AI-generated descriptions are not acceptable)
- The issue has real content, not just template placeholder text left unchanged
- Bug reports should include some context about how to reproduce
- Feature requests should explain the problem or need
- We want to push for having the user provide system description & information
Do NOT be nitpicky about optional fields. Only flag real problems like: no template used, required fields empty or placeholder text only, obviously AI-generated walls of text, or completely empty/nonsensical content.
If the issue is NOW compliant:
1. Remove the needs:compliance label: gh issue edit ${{ github.event.issue.number }} --remove-label needs:compliance
2. Find and delete the previous compliance comment (the one containing <!-- issue-compliance -->) using: gh api repos/${{ github.repository }}/issues/${{ github.event.issue.number }}/comments --jq '.[] | select(.body | contains(\"<!-- issue-compliance -->\")) | .id' then delete it with: gh api -X DELETE repos/${{ github.repository }}/issues/${{ github.event.issue.number }}/comments/{id}
3. Post a short comment thanking them for updating the issue.
If the issue is STILL not compliant:
Post a comment explaining what still needs to be fixed. Keep the needs:compliance label."
@@ -1,46 +0,0 @@
name: nix-desktop
on:
push:
branches: [dev]
paths:
- "flake.nix"
- "flake.lock"
- "nix/**"
- "packages/app/**"
- "packages/desktop/**"
- ".github/workflows/nix-desktop.yml"
pull_request:
paths:
- "flake.nix"
- "flake.lock"
- "nix/**"
- "packages/app/**"
- "packages/desktop/**"
- ".github/workflows/nix-desktop.yml"
workflow_dispatch:
jobs:
nix-desktop:
strategy:
fail-fast: false
matrix:
os:
- blacksmith-4vcpu-ubuntu-2404
- blacksmith-4vcpu-ubuntu-2404-arm
- macos-15-intel
- macos-latest
runs-on: ${{ matrix.os }}
timeout-minutes: 60
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Setup Nix
uses: nixbuild/nix-quick-install-action@v34
- name: Build desktop via flake
run: |
set -euo pipefail
nix --version
nix build .#desktop -L
+95
View File
@@ -0,0 +1,95 @@
name: nix-eval
on:
push:
branches: [dev]
pull_request:
branches: [dev]
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
nix-eval:
runs-on: blacksmith-4vcpu-ubuntu-2404
timeout-minutes: 15
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Setup Nix
uses: nixbuild/nix-quick-install-action@v34
- name: Evaluate flake outputs (all systems)
run: |
set -euo pipefail
nix --version
echo "=== Flake metadata ==="
nix flake metadata
echo ""
echo "=== Flake structure ==="
nix flake show --all-systems
SYSTEMS="x86_64-linux aarch64-linux x86_64-darwin aarch64-darwin"
PACKAGES="opencode"
# TODO: move 'desktop' to PACKAGES when #11755 is fixed
OPTIONAL_PACKAGES="desktop"
echo ""
echo "=== Evaluating packages for all systems ==="
for system in $SYSTEMS; do
echo ""
echo "--- $system ---"
for pkg in $PACKAGES; do
printf " %s: " "$pkg"
if output=$(nix eval ".#packages.$system.$pkg.drvPath" --raw 2>&1); then
echo "✓"
else
echo "✗"
echo "::error::Evaluation failed for packages.$system.$pkg"
echo "$output"
exit 1
fi
done
done
echo ""
echo "=== Evaluating optional packages ==="
for system in $SYSTEMS; do
echo ""
echo "--- $system ---"
for pkg in $OPTIONAL_PACKAGES; do
printf " %s: " "$pkg"
if output=$(nix eval ".#packages.$system.$pkg.drvPath" --raw 2>&1); then
echo "✓"
else
echo "✗"
echo "::warning::Evaluation failed for packages.$system.$pkg"
echo "$output"
fi
done
done
echo ""
echo "=== Evaluating devShells for all systems ==="
for system in $SYSTEMS; do
printf "%s: " "$system"
if output=$(nix eval ".#devShells.$system.default.drvPath" --raw 2>&1); then
echo "✓"
else
echo "✗"
echo "::error::Evaluation failed for devShells.$system.default"
echo "$output"
exit 1
fi
done
echo ""
echo "=== All evaluations passed ==="
+2 -2
View File
@@ -6,7 +6,7 @@ permissions:
on:
workflow_dispatch:
push:
branches: [dev]
branches: [dev, beta]
paths:
- "bun.lock"
- "package.json"
@@ -56,7 +56,7 @@ jobs:
nix build ".#packages.${SYSTEM}.node_modules_updater" --no-link 2>&1 | tee "$BUILD_LOG" || true
# Extract hash from build log with portability
HASH="$(grep -oE 'sha256-[A-Za-z0-9+/=]+' "$BUILD_LOG" | tail -n1 || true)"
HASH="$(nix run --inputs-from . nixpkgs#gnugrep -- -oP 'got:\s*\Ksha256-[A-Za-z0-9+/=]+' "$BUILD_LOG" | tail -n1 || true)"
if [ -z "$HASH" ]; then
echo "::error::Failed to compute hash for ${SYSTEM}"
+16 -11
View File
@@ -6,17 +6,6 @@ on:
jobs:
check-duplicates:
if: |
github.event.pull_request.user.login != 'actions-user' &&
github.event.pull_request.user.login != 'opencode' &&
github.event.pull_request.user.login != 'rekram1-node' &&
github.event.pull_request.user.login != 'thdxr' &&
github.event.pull_request.user.login != 'kommander' &&
github.event.pull_request.user.login != 'jayair' &&
github.event.pull_request.user.login != 'fwang' &&
github.event.pull_request.user.login != 'adamdotdevin' &&
github.event.pull_request.user.login != 'iamdavidhill' &&
github.event.pull_request.user.login != 'opencode-agent[bot]'
runs-on: blacksmith-4vcpu-ubuntu-2404
permissions:
contents: read
@@ -27,16 +16,31 @@ jobs:
with:
fetch-depth: 1
- name: Check team membership
id: team-check
run: |
LOGIN="${{ github.event.pull_request.user.login }}"
if [ "$LOGIN" = "opencode-agent[bot]" ] || grep -qxF "$LOGIN" .github/TEAM_MEMBERS; then
echo "is_team=true" >> "$GITHUB_OUTPUT"
echo "Skipping: $LOGIN is a team member or bot"
else
echo "is_team=false" >> "$GITHUB_OUTPUT"
fi
- name: Setup Bun
if: steps.team-check.outputs.is_team != 'true'
uses: ./.github/actions/setup-bun
- name: Install dependencies
if: steps.team-check.outputs.is_team != 'true'
run: bun install
- name: Install opencode
if: steps.team-check.outputs.is_team != 'true'
run: curl -fsSL https://opencode.ai/install | bash
- name: Build prompt
if: steps.team-check.outputs.is_team != 'true'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUMBER: ${{ github.event.pull_request.number }}
@@ -53,6 +57,7 @@ jobs:
} > pr_info.txt
- name: Check for duplicate PRs
if: steps.team-check.outputs.is_team != 'true'
env:
OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+226 -14
View File
@@ -6,19 +6,9 @@ on:
jobs:
check-standards:
if: |
github.event.pull_request.user.login != 'actions-user' &&
github.event.pull_request.user.login != 'opencode' &&
github.event.pull_request.user.login != 'rekram1-node' &&
github.event.pull_request.user.login != 'thdxr' &&
github.event.pull_request.user.login != 'kommander' &&
github.event.pull_request.user.login != 'jayair' &&
github.event.pull_request.user.login != 'fwang' &&
github.event.pull_request.user.login != 'adamdotdevin' &&
github.event.pull_request.user.login != 'iamdavidhill' &&
github.event.pull_request.user.login != 'opencode-agent[bot]'
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- name: Check PR standards
@@ -26,6 +16,30 @@ jobs:
with:
script: |
const pr = context.payload.pull_request;
const login = pr.user.login;
// Skip PRs older than Feb 18, 2026 at 6PM EST (Feb 19, 2026 00:00 UTC)
const cutoff = new Date('2026-02-19T00:00:00Z');
const prCreated = new Date(pr.created_at);
if (prCreated < cutoff) {
console.log(`Skipping: PR #${pr.number} was created before cutoff (${prCreated.toISOString()})`);
return;
}
// Check if author is a team member or bot
if (login === 'opencode-agent[bot]') return;
const { data: file } = await github.rest.repos.getContent({
owner: context.repo.owner,
repo: context.repo.repo,
path: '.github/TEAM_MEMBERS',
ref: 'dev'
});
const members = Buffer.from(file.content, 'base64').toString().split('\n').map(l => l.trim()).filter(Boolean);
if (members.includes(login)) {
console.log(`Skipping: ${login} is a team member`);
return;
}
const title = pr.title;
async function addLabel(label) {
@@ -94,11 +108,11 @@ jobs:
await removeLabel('needs:title');
// Step 2: Check for linked issue (skip for docs/refactor PRs)
const skipIssueCheck = /^(docs|refactor)\s*(\([a-zA-Z0-9-]+\))?\s*:/.test(title);
// Step 2: Check for linked issue (skip for docs/refactor/feat PRs)
const skipIssueCheck = /^(docs|refactor|feat)\s*(\([a-zA-Z0-9-]+\))?\s*:/.test(title);
if (skipIssueCheck) {
await removeLabel('needs:issue');
console.log('Skipping issue check for docs/refactor PR');
console.log('Skipping issue check for docs/refactor/feat PR');
return;
}
const query = `
@@ -137,3 +151,201 @@ jobs:
await removeLabel('needs:issue');
console.log('PR meets all standards');
check-compliance:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- name: Check PR template compliance
uses: actions/github-script@v7
with:
script: |
const pr = context.payload.pull_request;
const login = pr.user.login;
// Skip PRs older than Feb 18, 2026 at 6PM EST (Feb 19, 2026 00:00 UTC)
const cutoff = new Date('2026-02-19T00:00:00Z');
const prCreated = new Date(pr.created_at);
if (prCreated < cutoff) {
console.log(`Skipping: PR #${pr.number} was created before cutoff (${prCreated.toISOString()})`);
return;
}
// Check if author is a team member or bot
if (login === 'opencode-agent[bot]') return;
const { data: file } = await github.rest.repos.getContent({
owner: context.repo.owner,
repo: context.repo.repo,
path: '.github/TEAM_MEMBERS',
ref: 'dev'
});
const members = Buffer.from(file.content, 'base64').toString().split('\n').map(l => l.trim()).filter(Boolean);
if (members.includes(login)) {
console.log(`Skipping: ${login} is a team member`);
return;
}
const body = pr.body || '';
const title = pr.title;
const isDocsRefactorOrFeat = /^(docs|refactor|feat)\s*(\([a-zA-Z0-9-]+\))?\s*:/.test(title);
const issues = [];
// Check: template sections exist
const hasWhatSection = /### What does this PR do\?/.test(body);
const hasTypeSection = /### Type of change/.test(body);
const hasVerifySection = /### How did you verify your code works\?/.test(body);
const hasChecklistSection = /### Checklist/.test(body);
const hasIssueSection = /### Issue for this PR/.test(body);
if (!hasWhatSection || !hasTypeSection || !hasVerifySection || !hasChecklistSection || !hasIssueSection) {
issues.push('PR description is missing required template sections. Please use the [PR template](../blob/dev/.github/pull_request_template.md).');
}
// Check: "What does this PR do?" has real content (not just placeholder text)
if (hasWhatSection) {
const whatMatch = body.match(/### What does this PR do\?\s*\n([\s\S]*?)(?=###|$)/);
const whatContent = whatMatch ? whatMatch[1].trim() : '';
const placeholder = 'Please provide a description of the issue';
const onlyPlaceholder = whatContent.includes(placeholder) && whatContent.replace(placeholder, '').replace(/[*\s]/g, '').length < 20;
if (!whatContent || onlyPlaceholder) {
issues.push('"What does this PR do?" section is empty or only contains placeholder text. Please describe your changes.');
}
}
// Check: at least one "Type of change" checkbox is checked
if (hasTypeSection) {
const typeMatch = body.match(/### Type of change\s*\n([\s\S]*?)(?=###|$)/);
const typeContent = typeMatch ? typeMatch[1] : '';
const hasCheckedBox = /- \[x\]/i.test(typeContent);
if (!hasCheckedBox) {
issues.push('No "Type of change" checkbox is checked. Please select at least one.');
}
}
// Check: issue reference (skip for docs/refactor/feat)
if (!isDocsRefactorOrFeat && hasIssueSection) {
const issueMatch = body.match(/### Issue for this PR\s*\n([\s\S]*?)(?=###|$)/);
const issueContent = issueMatch ? issueMatch[1].trim() : '';
const hasIssueRef = /(closes|fixes|resolves)\s+#\d+/i.test(issueContent) || /#\d+/.test(issueContent);
if (!hasIssueRef) {
issues.push('No issue referenced. Please add `Closes #<number>` linking to the relevant issue.');
}
}
// Check: "How did you verify" has content
if (hasVerifySection) {
const verifyMatch = body.match(/### How did you verify your code works\?\s*\n([\s\S]*?)(?=###|$)/);
const verifyContent = verifyMatch ? verifyMatch[1].trim() : '';
if (!verifyContent) {
issues.push('"How did you verify your code works?" section is empty. Please explain how you tested.');
}
}
// Check: checklist boxes are checked
if (hasChecklistSection) {
const checklistMatch = body.match(/### Checklist\s*\n([\s\S]*?)(?=###|$)/);
const checklistContent = checklistMatch ? checklistMatch[1] : '';
const unchecked = (checklistContent.match(/- \[ \]/g) || []).length;
const checked = (checklistContent.match(/- \[x\]/gi) || []).length;
if (checked < 2) {
issues.push('Not all checklist items are checked. Please confirm you have tested locally and have not included unrelated changes.');
}
}
// Helper functions
async function addLabel(label) {
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr.number,
labels: [label]
});
}
async function removeLabel(label) {
try {
await github.rest.issues.removeLabel({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr.number,
name: label
});
} catch (e) {}
}
const hasComplianceLabel = pr.labels.some(l => l.name === 'needs:compliance');
if (issues.length > 0) {
// Non-compliant
if (!hasComplianceLabel) {
await addLabel('needs:compliance');
}
const marker = '<!-- issue-compliance -->';
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr.number
});
const existing = comments.find(c => c.body.includes(marker));
const body_text = `${marker}
This PR doesn't fully meet our [contributing guidelines](../blob/dev/CONTRIBUTING.md) and [PR template](../blob/dev/.github/pull_request_template.md).
**What needs to be fixed:**
${issues.map(i => `- ${i}`).join('\n')}
Please edit this PR description to address the above within **2 hours**, or it will be automatically closed.
If you believe this was flagged incorrectly, please let a maintainer know.`;
if (existing) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: existing.id,
body: body_text
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr.number,
body: body_text
});
}
console.log(`PR #${pr.number} is non-compliant: ${issues.join(', ')}`);
} else if (hasComplianceLabel) {
// Was non-compliant, now fixed
await removeLabel('needs:compliance');
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr.number
});
const marker = '<!-- issue-compliance -->';
const existing = comments.find(c => c.body.includes(marker));
if (existing) {
await github.rest.issues.deleteComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: existing.id
});
}
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr.number,
body: 'Thanks for updating your PR! It now meets our contributing guidelines. :+1:'
});
console.log(`PR #${pr.number} is now compliant, label removed`);
} else {
console.log(`PR #${pr.number} is compliant`);
}
+187 -11
View File
@@ -41,6 +41,13 @@ jobs:
- uses: ./.github/actions/setup-bun
- name: Setup git committer
id: committer
uses: ./.github/actions/setup-git-committer
with:
opencode-app-id: ${{ vars.OPENCODE_APP_ID }}
opencode-app-secret: ${{ secrets.OPENCODE_APP_SECRET }}
- name: Install OpenCode
if: inputs.bump || inputs.version
run: bun i -g opencode-ai
@@ -49,14 +56,16 @@ jobs:
run: |
./script/version.ts
env:
GH_TOKEN: ${{ github.token }}
GH_TOKEN: ${{ steps.committer.outputs.token }}
OPENCODE_BUMP: ${{ inputs.bump }}
OPENCODE_VERSION: ${{ inputs.version }}
OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }}
GH_REPO: ${{ (github.ref_name == 'beta' && 'anomalyco/opencode-beta') || github.repository }}
outputs:
version: ${{ steps.version.outputs.version }}
release: ${{ steps.version.outputs.release }}
tag: ${{ steps.version.outputs.tag }}
repo: ${{ steps.version.outputs.repo }}
build-cli:
needs: version
@@ -69,6 +78,13 @@ jobs:
- uses: ./.github/actions/setup-bun
- name: Setup git committer
id: committer
uses: ./.github/actions/setup-git-committer
with:
opencode-app-id: ${{ vars.OPENCODE_APP_ID }}
opencode-app-secret: ${{ secrets.OPENCODE_APP_SECRET }}
- name: Build
id: build
run: |
@@ -76,13 +92,13 @@ jobs:
env:
OPENCODE_VERSION: ${{ needs.version.outputs.version }}
OPENCODE_RELEASE: ${{ needs.version.outputs.release }}
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ needs.version.outputs.repo }}
GH_TOKEN: ${{ steps.committer.outputs.token }}
- uses: actions/upload-artifact@v4
with:
name: opencode-cli
path: packages/opencode/dist
outputs:
version: ${{ needs.version.outputs.version }}
@@ -99,6 +115,9 @@ jobs:
target: x86_64-apple-darwin
- host: macos-latest
target: aarch64-apple-darwin
# github-hosted: blacksmith lacks ARM64 MSVC cross-compilation toolchain
- host: windows-2025
target: aarch64-pc-windows-msvc
- host: blacksmith-4vcpu-windows-2025
target: x86_64-pc-windows-msvc
- host: blacksmith-4vcpu-ubuntu-2404
@@ -133,11 +152,15 @@ jobs:
- uses: ./.github/actions/setup-bun
- uses: actions/setup-node@v4
with:
node-version: "24"
- name: Cache apt packages
if: contains(matrix.settings.host, 'ubuntu')
uses: actions/cache@v4
with:
path: /var/cache/apt/archives
path: ~/apt-cache
key: ${{ runner.os }}-${{ matrix.settings.target }}-apt-${{ hashFiles('.github/workflows/publish.yml') }}
restore-keys: |
${{ runner.os }}-${{ matrix.settings.target }}-apt-
@@ -145,8 +168,10 @@ jobs:
- name: install dependencies (ubuntu only)
if: contains(matrix.settings.host, 'ubuntu')
run: |
mkdir -p ~/apt-cache && chmod -R a+rw ~/apt-cache
sudo apt-get update
sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf
sudo apt-get install -y --no-install-recommends -o dir::cache::archives="$HOME/apt-cache" libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf
sudo chmod -R a+rw ~/apt-cache
- name: install Rust stable
uses: dtolnay/rust-toolchain@stable
@@ -169,13 +194,30 @@ jobs:
GH_TOKEN: ${{ github.token }}
GITHUB_RUN_ID: ${{ github.run_id }}
- name: Resolve tauri portable SHA
if: contains(matrix.settings.host, 'ubuntu')
run: echo "TAURI_PORTABLE_SHA=$(git ls-remote https://github.com/tauri-apps/tauri.git refs/heads/feat/truly-portable-appimage | cut -f1)" >> "$GITHUB_ENV"
# Fixes AppImage build issues, can be removed when https://github.com/tauri-apps/tauri/pull/12491 is released
- name: Install tauri-cli from portable appimage branch
uses: taiki-e/cache-cargo-install-action@v3
if: contains(matrix.settings.host, 'ubuntu')
run: |
cargo install tauri-cli --git https://github.com/tauri-apps/tauri --branch feat/truly-portable-appimage --force
echo "Installed tauri-cli version:"
cargo tauri --version
with:
tool: tauri-cli
git: https://github.com/tauri-apps/tauri
# branch: feat/truly-portable-appimage
rev: ${{ env.TAURI_PORTABLE_SHA }}
- name: Show tauri-cli version
if: contains(matrix.settings.host, 'ubuntu')
run: cargo tauri --version
- name: Setup git committer
id: committer
uses: ./.github/actions/setup-git-committer
with:
opencode-app-id: ${{ vars.OPENCODE_APP_ID }}
opencode-app-secret: ${{ secrets.OPENCODE_APP_SECRET }}
- name: Build and upload artifacts
uses: tauri-apps/tauri-action@390cbe447412ced1303d35abe75287949e43437a
@@ -184,14 +226,16 @@ jobs:
projectPath: packages/desktop
uploadWorkflowArtifacts: true
tauriScript: ${{ (contains(matrix.settings.host, 'ubuntu') && 'cargo tauri') || '' }}
args: --target ${{ matrix.settings.target }} --config ./src-tauri/tauri.prod.conf.json --verbose
args: --target ${{ matrix.settings.target }} --config ${{ (github.ref_name == 'beta' && './src-tauri/tauri.beta.conf.json') || './src-tauri/tauri.prod.conf.json' }} --verbose
updaterJsonPreferNsis: true
releaseId: ${{ needs.version.outputs.release }}
tagName: ${{ needs.version.outputs.tag }}
releaseDraft: true
releaseAssetNamePattern: opencode-desktop-[platform]-[arch][ext]
repo: ${{ (github.ref_name == 'beta' && 'opencode-beta') || '' }}
releaseCommitish: ${{ github.sha }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ steps.committer.outputs.token }}
TAURI_BUNDLER_NEW_APPIMAGE_FORMAT: true
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
@@ -202,11 +246,135 @@ jobs:
APPLE_API_KEY: ${{ secrets.APPLE_API_KEY }}
APPLE_API_KEY_PATH: ${{ runner.temp }}/apple-api-key.p8
build-electron:
needs:
- build-cli
- version
continue-on-error: false
strategy:
fail-fast: false
matrix:
settings:
- host: macos-latest
target: x86_64-apple-darwin
platform_flag: --mac --x64
- host: macos-latest
target: aarch64-apple-darwin
platform_flag: --mac --arm64
# github-hosted: blacksmith lacks ARM64 MSVC cross-compilation toolchain
- host: "windows-2025"
target: aarch64-pc-windows-msvc
platform_flag: --win --arm64
- host: "blacksmith-4vcpu-windows-2025"
target: x86_64-pc-windows-msvc
platform_flag: --win
- host: "blacksmith-4vcpu-ubuntu-2404"
target: x86_64-unknown-linux-gnu
platform_flag: --linux
- host: "blacksmith-4vcpu-ubuntu-2404"
target: aarch64-unknown-linux-gnu
platform_flag: --linux
runs-on: ${{ matrix.settings.host }}
# if: github.ref_name == 'beta'
steps:
- uses: actions/checkout@v3
- uses: apple-actions/import-codesign-certs@v2
if: runner.os == 'macOS'
with:
keychain: build
p12-file-base64: ${{ secrets.APPLE_CERTIFICATE }}
p12-password: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
- name: Setup Apple API Key
if: runner.os == 'macOS'
run: echo "${{ secrets.APPLE_API_KEY_PATH }}" > $RUNNER_TEMP/apple-api-key.p8
- uses: ./.github/actions/setup-bun
- uses: actions/setup-node@v4
with:
node-version: "24"
- name: Cache apt packages
if: contains(matrix.settings.host, 'ubuntu')
uses: actions/cache@v4
with:
path: ~/apt-cache
key: ${{ runner.os }}-${{ matrix.settings.target }}-apt-electron-${{ hashFiles('.github/workflows/publish.yml') }}
restore-keys: |
${{ runner.os }}-${{ matrix.settings.target }}-apt-electron-
- name: Install dependencies (ubuntu only)
if: contains(matrix.settings.host, 'ubuntu')
run: |
mkdir -p ~/apt-cache && chmod -R a+rw ~/apt-cache
sudo apt-get update
sudo apt-get install -y --no-install-recommends -o dir::cache::archives="$HOME/apt-cache" rpm
sudo chmod -R a+rw ~/apt-cache
- name: Setup git committer
id: committer
uses: ./.github/actions/setup-git-committer
with:
opencode-app-id: ${{ vars.OPENCODE_APP_ID }}
opencode-app-secret: ${{ secrets.OPENCODE_APP_SECRET }}
- name: Prepare
run: bun ./scripts/prepare.ts
working-directory: packages/desktop-electron
env:
OPENCODE_VERSION: ${{ needs.version.outputs.version }}
OPENCODE_CHANNEL: ${{ (github.ref_name == 'beta' && 'beta') || 'prod' }}
RUST_TARGET: ${{ matrix.settings.target }}
GH_TOKEN: ${{ github.token }}
GITHUB_RUN_ID: ${{ github.run_id }}
- name: Build
run: bun run build
working-directory: packages/desktop-electron
env:
OPENCODE_CHANNEL: ${{ (github.ref_name == 'beta' && 'beta') || 'prod' }}
- name: Package and publish
if: needs.version.outputs.release
run: npx electron-builder ${{ matrix.settings.platform_flag }} --publish always --config electron-builder.config.ts
working-directory: packages/desktop-electron
timeout-minutes: 60
env:
OPENCODE_CHANNEL: ${{ (github.ref_name == 'beta' && 'beta') || 'prod' }}
GH_TOKEN: ${{ steps.committer.outputs.token }}
CSC_LINK: ${{ secrets.APPLE_CERTIFICATE }}
CSC_KEY_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
APPLE_API_KEY: ${{ runner.temp }}/apple-api-key.p8
APPLE_API_KEY_ID: ${{ secrets.APPLE_API_KEY }}
APPLE_API_ISSUER: ${{ secrets.APPLE_API_ISSUER }}
- name: Package (no publish)
if: ${{ !needs.version.outputs.release }}
run: npx electron-builder ${{ matrix.settings.platform_flag }} --publish never --config electron-builder.config.ts
working-directory: packages/desktop-electron
timeout-minutes: 60
env:
OPENCODE_CHANNEL: ${{ (github.ref_name == 'beta' && 'beta') || 'prod' }}
- uses: actions/upload-artifact@v4
with:
name: opencode-electron-${{ matrix.settings.target }}
path: packages/desktop-electron/dist/*
- uses: actions/upload-artifact@v4
if: needs.version.outputs.release
with:
name: latest-yml-${{ matrix.settings.target }}
path: packages/desktop-electron/dist/latest*.yml
publish:
needs:
- version
- build-cli
- build-tauri
- build-electron
runs-on: blacksmith-4vcpu-ubuntu-2404
steps:
- uses: actions/checkout@v3
@@ -243,6 +411,12 @@ jobs:
name: opencode-cli
path: packages/opencode/dist
- uses: actions/download-artifact@v4
if: needs.version.outputs.release
with:
pattern: latest-yml-*
path: /tmp/latest-yml
- name: Cache apt packages (AUR)
uses: actions/cache@v4
with:
@@ -268,4 +442,6 @@ jobs:
OPENCODE_RELEASE: ${{ needs.version.outputs.release }}
AUR_KEY: ${{ secrets.AUR_KEY }}
GITHUB_TOKEN: ${{ steps.committer.outputs.token }}
GH_REPO: ${{ needs.version.outputs.repo }}
NPM_CONFIG_PROVENANCE: false
LATEST_YML_DIR: /tmp/latest-yml
-33
View File
@@ -1,33 +0,0 @@
name: stale-issues
on:
schedule:
- cron: "30 1 * * *" # Daily at 1:30 AM
workflow_dispatch:
env:
DAYS_BEFORE_STALE: 90
DAYS_BEFORE_CLOSE: 7
jobs:
stale:
runs-on: ubuntu-latest
permissions:
issues: write
steps:
- uses: actions/stale@v10
with:
days-before-stale: ${{ env.DAYS_BEFORE_STALE }}
days-before-close: ${{ env.DAYS_BEFORE_CLOSE }}
stale-issue-label: "stale"
close-issue-message: |
[automated] Closing due to ${{ env.DAYS_BEFORE_STALE }}+ days of inactivity.
Feel free to reopen if you still need this!
stale-issue-message: |
[automated] This issue has had no activity for ${{ env.DAYS_BEFORE_STALE }} days.
It will be closed in ${{ env.DAYS_BEFORE_CLOSE }} days if there's no new activity.
remove-stale-when-updated: true
exempt-issue-labels: "pinned,security,feature-request,on-hold"
start-date: "2025-12-27"
+38
View File
@@ -0,0 +1,38 @@
name: storybook
on:
push:
branches: [dev]
paths:
- ".github/workflows/storybook.yml"
- "package.json"
- "bun.lock"
- "packages/storybook/**"
- "packages/ui/**"
pull_request:
branches: [dev]
paths:
- ".github/workflows/storybook.yml"
- "package.json"
- "bun.lock"
- "packages/storybook/**"
- "packages/ui/**"
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build:
name: storybook build
runs-on: blacksmith-4vcpu-ubuntu-2404
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Bun
uses: ./.github/actions/setup-bun
- name: Build Storybook
run: bun --cwd packages/storybook build
+42 -23
View File
@@ -6,10 +6,28 @@ on:
- dev
pull_request:
workflow_dispatch:
concurrency:
# Keep every run on dev so cancelled checks do not pollute the default branch
# commit history. PRs and other branches still share a group and cancel stale runs.
group: ${{ case(github.ref == 'refs/heads/dev', format('{0}-{1}', github.workflow, github.run_id), format('{0}-{1}', github.workflow, github.event.pull_request.number || github.ref)) }}
cancel-in-progress: true
permissions:
contents: read
jobs:
unit:
name: unit (linux)
runs-on: blacksmith-4vcpu-ubuntu-2404
name: unit (${{ matrix.settings.name }})
strategy:
fail-fast: false
matrix:
settings:
- name: linux
host: blacksmith-4vcpu-ubuntu-2404
- name: windows
host: blacksmith-4vcpu-windows-2025
runs-on: ${{ matrix.settings.host }}
defaults:
run:
shell: bash
@@ -32,20 +50,17 @@ jobs:
e2e:
name: e2e (${{ matrix.settings.name }})
needs: unit
strategy:
fail-fast: false
matrix:
settings:
- name: linux
host: blacksmith-4vcpu-ubuntu-2404
playwright: bunx playwright install --with-deps
- name: windows
host: blacksmith-4vcpu-windows-2025
playwright: bunx playwright install
runs-on: ${{ matrix.settings.host }}
env:
PLAYWRIGHT_BROWSERS_PATH: 0
PLAYWRIGHT_BROWSERS_PATH: ${{ github.workspace }}/.playwright-browsers
defaults:
run:
shell: bash
@@ -58,9 +73,28 @@ jobs:
- name: Setup Bun
uses: ./.github/actions/setup-bun
- name: Install Playwright browsers
- name: Read Playwright version
id: playwright-version
run: |
version=$(node -e 'console.log(require("./packages/app/package.json").devDependencies["@playwright/test"])')
echo "version=$version" >> "$GITHUB_OUTPUT"
- name: Cache Playwright browsers
id: playwright-cache
uses: actions/cache@v4
with:
path: ${{ github.workspace }}/.playwright-browsers
key: ${{ runner.os }}-${{ runner.arch }}-playwright-${{ steps.playwright-version.outputs.version }}-chromium
- name: Install Playwright system dependencies
if: runner.os == 'Linux'
working-directory: packages/app
run: ${{ matrix.settings.playwright }}
run: bunx playwright install-deps chromium
- name: Install Playwright browsers
if: steps.playwright-cache.outputs.cache-hit != 'true'
working-directory: packages/app
run: bunx playwright install chromium
- name: Run app e2e tests
run: bun --cwd packages/app test:e2e:local
@@ -78,18 +112,3 @@ jobs:
path: |
packages/app/e2e/test-results
packages/app/e2e/playwright-report
required:
name: test (linux)
runs-on: blacksmith-4vcpu-ubuntu-2404
needs:
- unit
- e2e
if: always()
steps:
- name: Verify upstream test jobs passed
run: |
echo "unit=${{ needs.unit.result }}"
echo "e2e=${{ needs.e2e.result }}"
test "${{ needs.unit.result }}" = "success"
test "${{ needs.e2e.result }}" = "success"
+39 -19
View File
@@ -42,15 +42,17 @@ jobs:
throw error;
}
// Parse the .td file for denounced users
// Parse the .td file for vouched and denounced users
const vouched = new Set();
const denounced = new Map();
for (const line of content.split('\n')) {
const trimmed = line.trim();
if (!trimmed || trimmed.startsWith('#')) continue;
if (!trimmed.startsWith('-')) continue;
const rest = trimmed.slice(1).trim();
const isDenounced = trimmed.startsWith('-');
const rest = isDenounced ? trimmed.slice(1).trim() : trimmed;
if (!rest) continue;
const spaceIdx = rest.indexOf(' ');
const handle = spaceIdx === -1 ? rest : rest.slice(0, spaceIdx);
const reason = spaceIdx === -1 ? null : rest.slice(spaceIdx + 1).trim();
@@ -65,32 +67,50 @@ jobs:
const username = colonIdx === -1 ? handle : handle.slice(colonIdx + 1);
if (!username) continue;
denounced.set(username.toLowerCase(), reason);
if (isDenounced) {
denounced.set(username.toLowerCase(), reason);
continue;
}
vouched.add(username.toLowerCase());
}
// Check if the author is denounced
const reason = denounced.get(author.toLowerCase());
if (reason === undefined) {
core.info(`User ${author} is not denounced. Allowing issue.`);
if (reason !== undefined) {
// Author is denounced — close the issue
const body = 'This issue has been automatically closed.';
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueNumber,
body,
});
await github.rest.issues.update({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueNumber,
state: 'closed',
state_reason: 'not_planned',
});
core.info(`Closed issue #${issueNumber} from denounced user ${author}`);
return;
}
// Author is denounced — close the issue
const body = 'This issue has been automatically closed.';
// Author is positively vouched — add label
if (!vouched.has(author.toLowerCase())) {
core.info(`User ${author} is not denounced or vouched. Allowing issue.`);
return;
}
await github.rest.issues.createComment({
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueNumber,
body,
labels: ['Vouched'],
});
await github.rest.issues.update({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueNumber,
state: 'closed',
state_reason: 'not_planned',
});
core.info(`Closed issue #${issueNumber} from denounced user ${author}`);
core.info(`Added vouched label to issue #${issueNumber} from ${author}`);
+38 -17
View File
@@ -6,6 +6,7 @@ on:
permissions:
contents: read
issues: write
pull-requests: write
jobs:
@@ -42,15 +43,17 @@ jobs:
throw error;
}
// Parse the .td file for denounced users
// Parse the .td file for vouched and denounced users
const vouched = new Set();
const denounced = new Map();
for (const line of content.split('\n')) {
const trimmed = line.trim();
if (!trimmed || trimmed.startsWith('#')) continue;
if (!trimmed.startsWith('-')) continue;
const rest = trimmed.slice(1).trim();
const isDenounced = trimmed.startsWith('-');
const rest = isDenounced ? trimmed.slice(1).trim() : trimmed;
if (!rest) continue;
const spaceIdx = rest.indexOf(' ');
const handle = spaceIdx === -1 ? rest : rest.slice(0, spaceIdx);
const reason = spaceIdx === -1 ? null : rest.slice(spaceIdx + 1).trim();
@@ -65,29 +68,47 @@ jobs:
const username = colonIdx === -1 ? handle : handle.slice(colonIdx + 1);
if (!username) continue;
denounced.set(username.toLowerCase(), reason);
if (isDenounced) {
denounced.set(username.toLowerCase(), reason);
continue;
}
vouched.add(username.toLowerCase());
}
// Check if the author is denounced
const reason = denounced.get(author.toLowerCase());
if (reason === undefined) {
core.info(`User ${author} is not denounced. Allowing PR.`);
if (reason !== undefined) {
// Author is denounced — close the PR
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
body: 'This pull request has been automatically closed.',
});
await github.rest.pulls.update({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: prNumber,
state: 'closed',
});
core.info(`Closed PR #${prNumber} from denounced user ${author}`);
return;
}
// Author is denounced — close the PR
await github.rest.issues.createComment({
// Author is positively vouched — add label
if (!vouched.has(author.toLowerCase())) {
core.info(`User ${author} is not denounced or vouched. Allowing PR.`);
return;
}
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
body: 'This pull request has been automatically closed.',
labels: ['Vouched'],
});
await github.rest.pulls.update({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: prNumber,
state: 'closed',
});
core.info(`Closed PR #${prNumber} from denounced user ${author}`);
core.info(`Added vouched label to PR #${prNumber} from ${author}`);
@@ -33,5 +33,6 @@ jobs:
with:
issue-id: ${{ github.event.issue.number }}
comment-id: ${{ github.event.comment.id }}
roles: admin,maintain,write
env:
GITHUB_TOKEN: ${{ steps.committer.outputs.token }}
+2 -1
View File
@@ -17,7 +17,7 @@ ts-dist
/result
refs
Session.vim
opencode.json
/opencode.json
a.out
target
.scripts
@@ -27,3 +27,4 @@ target
opencode-dev
logs/
*.bun-build
tsconfig.tsbuildinfo
+5 -2
View File
@@ -1,3 +1,6 @@
plans/
bun.lock
node_modules
plans
package.json
bun.lock
.gitignore
package-lock.json
+18 -1
View File
@@ -1,7 +1,7 @@
---
description: Translate content for a specified locale while preserving technical terms
mode: subagent
model: opencode/gemini-3-pro
model: opencode/gpt-5.4
---
You are a professional translator and localization specialist.
@@ -13,10 +13,25 @@ Requirements:
- Preserve meaning, intent, tone, and formatting (including Markdown/MDX structure).
- Preserve all technical terms and artifacts exactly: product/company names, API names, identifiers, code, commands/flags, file paths, URLs, versions, error messages, config keys/values, and anything inside inline code or code blocks.
- Also preserve every term listed in the Do-Not-Translate glossary below.
- Also apply locale-specific guidance from `.opencode/glossary/<locale>.md` when available (for example, `zh-cn.md`).
- Do not modify fenced code blocks.
- Output ONLY the translation (no commentary).
If the target locale is missing, ask the user to provide it.
If no locale-specific glossary exists, use the global glossary only.
---
# Locale-Specific Glossaries
When a locale glossary exists, use it to:
- Apply preferred wording for recurring UI/docs terms in that locale
- Preserve locale-specific do-not-translate terms and casing decisions
- Prefer natural phrasing over literal translation when the locale file calls it out
- If the repo uses a locale alias slug, apply that file too (for example, `pt-BR` maps to `br.md` in this repo)
Locale guidance does not override code/command preservation rules or the global Do-Not-Translate glossary below.
---
@@ -359,6 +374,7 @@ opencode serve --hostname 0.0.0.0 --port 4096
opencode serve [--port <number>] [--hostname <string>] [--cors <origin>]
opencode session [command]
opencode session list
opencode session delete <sessionID>
opencode stats
opencode uninstall
opencode upgrade
@@ -598,6 +614,7 @@ OPENCODE_EXPERIMENTAL_MARKDOWN
OPENCODE_EXPERIMENTAL_OUTPUT_TOKEN_MAX
OPENCODE_EXPERIMENTAL_OXFMT
OPENCODE_EXPERIMENTAL_PLAN_MODE
OPENCODE_ENABLE_QUESTION_TOOL
OPENCODE_FAKE_VCS
OPENCODE_GIT_BASH_PATH
OPENCODE_MODEL
+70 -8
View File
@@ -1,7 +1,7 @@
---
mode: primary
hidden: true
model: opencode/claude-haiku-4-5
model: opencode/minimax-m2.5
color: "#44BA81"
tools:
"*": false
@@ -12,6 +12,8 @@ You are a triage agent responsible for triaging github issues.
Use your github-triage tool to triage issues.
This file is the source of truth for ownership/routing rules.
## Labels
### windows
@@ -43,12 +45,34 @@ Desktop app issues:
**Only** add if the issue explicitly mentions nix.
If the issue does not mention nix, do not add nix.
If the issue mentions nix, assign to `rekram1-node`.
#### zen
**Only** add if the issue mentions "zen" or "opencode zen" or "opencode black".
If the issue doesn't have "zen" or "opencode black" in it then don't add zen label
#### core
Use for core server issues in `packages/opencode/`, excluding `packages/opencode/src/cli/cmd/tui/`.
Examples:
- LSP server behavior
- Harness behavior (agent + tools)
- Feature requests for server behavior
- Agent context construction
- API endpoints
- Provider integration issues
- New, broken, or poor-quality models
#### acp
If the issue mentions acp support, assign acp label.
#### docs
Add if the issue requests better documentation or docs updates.
@@ -66,13 +90,51 @@ TUI issues potentially caused by our underlying TUI library:
When assigning to people here are the following rules:
adamdotdev:
ONLY assign adam if the issue will have the "desktop" label.
Desktop / Web:
Use for desktop-labeled issues only.
fwang:
ONLY assign fwang if the issue will have the "zen" label.
- adamdotdevin
- iamdavidhill
- Brendonovich
- nexxeln
jayair:
ONLY assign jayair if the issue will have the "docs" label.
Zen:
ONLY assign if the issue will have the "zen" label.
In all other cases use best judgment. Avoid assigning to kommander needlessly, when in doubt assign to rekram1-node.
- fwang
- MrMushrooooom
TUI (`packages/opencode/src/cli/cmd/tui/...`):
- thdxr for TUI UX/UI product decisions and interaction flow
- kommander for OpenTUI engine issues: rendering artifacts, keybind handling, terminal compatibility, SSH behavior, and low-level perf bottlenecks
- rekram1-node for TUI bugs that are not clearly OpenTUI engine issues
Core (`packages/opencode/...`, excluding TUI subtree):
- thdxr for sqlite/snapshot/memory bugs and larger architectural core features
- jlongster for opencode server + API feature work (tool currently remaps jlongster -> thdxr until assignable)
- rekram1-node for harness issues, provider issues, and other bug-squashing
For core bugs that do not clearly map, either thdxr or rekram1-node is acceptable.
Docs:
- R44VC0RP
Windows:
- Hona (assign any issue that mentions Windows or is likely Windows-specific)
Determinism rules:
- If title + body does not contain "zen", do not add the "zen" label
- If "nix" label is added but title + body does not mention nix/nixos, the tool will drop "nix"
- If title + body mentions nix/nixos, assign to `rekram1-node`
- If "desktop" label is added, the tool will override assignee and randomly pick one Desktop / Web owner
In all other cases, choose the team/section with the most overlap with the issue and assign a member from that team at random.
ACP:
- rekram1-node (assign any acp issues to rekram1-node)
+21
View File
@@ -0,0 +1,21 @@
---
model: opencode/kimi-k2.5
---
create UPCOMING_CHANGELOG.md
it should have sections
```
# TUI
# Desktop
# Core
# Misc
```
go through each PR merged since the last tag
for each PR spawn a subagent to summarize what the PR was about. focus on user facing changes. if it was entirely internal or code related you can ignore it. also skip docs updates. each subagent should append its summary to UPCOMING_CHANGELOG.md into the appropriate section.
-3
View File
@@ -16,15 +16,12 @@ wip:
For anything in the packages/web use the docs: prefix.
For anything in the packages/app use the ignore: prefix.
prefer to explain WHY something was done from an end user perspective instead of
WHAT was done.
do not do generic messages like "improved agent experience" be very specific
about what user facing changes were made
if there are changes do a git pull --rebase
if there are conflicts DO NOT FIX THEM. notify me and I will fix them
## GIT DIFF
+63
View File
@@ -0,0 +1,63 @@
# Locale Glossaries
Use this folder for locale-specific translation guidance that supplements `.opencode/agent/translator.md`.
The global glossary in `translator.md` remains the source of truth for shared do-not-translate terms (commands, code, paths, product names, etc.). These locale files capture community learnings about phrasing and terminology preferences.
## File Naming
- One file per locale
- Use lowercase locale slugs that match docs locales when possible (for example, `zh-cn.md`, `zh-tw.md`)
- If only language-level guidance exists, use the language code (for example, `fr.md`)
- Some repo locale slugs may be aliases/non-BCP47 for consistency (for example, `br` for Brazilian Portuguese / `pt-BR`)
## What To Put In A Locale File
- **Sources**: PRs/issues/discussions that motivated the guidance
- **Do Not Translate (Locale Additions)**: locale-specific terms or casing decisions
- **Preferred Terms**: recurring UI/docs words with preferred translations
- **Guidance**: tone, style, and consistency notes
- **Avoid** (optional): common literal translations or wording we should avoid
- If the repo uses a locale alias slug, document the alias in **Guidance** (for example, prose may mention `pt-BR` while config/examples use `br`)
Prefer guidance that is:
- Repeated across multiple docs/screens
- Easy to apply consistently
- Backed by a community contribution or review discussion
## Template
```md
# <locale> Glossary
## Sources
- PR #12345: https://github.com/anomalyco/opencode/pull/12345
## Do Not Translate (Locale Additions)
- `OpenCode` (preserve casing)
## Preferred Terms
| English | Preferred | Notes |
| ------- | --------- | --------- |
| prompt | ... | preferred |
| session | ... | preferred |
## Guidance
- Prefer natural phrasing over literal translation
## Avoid
- Avoid ... when ...
```
## Contribution Notes
- Mark entries as preferred when they may evolve
- Keep examples short
- Add or update the `Sources` section whenever you add a new rule
- Prefer PR-backed guidance over invented term mappings; start with general guidance if no term-level corrections exist yet
+28
View File
@@ -0,0 +1,28 @@
# ar Glossary
## Sources
- PR #9947: https://github.com/anomalyco/opencode/pull/9947
## Do Not Translate (Locale Additions)
- `OpenCode` (preserve casing in prose; keep `opencode` only in commands, package names, paths, or code)
- `OpenCode CLI`
- `CLI`, `TUI`, `MCP`, `OAuth`
- Commands, flags, file paths, and code literals (keep exactly as written)
## Preferred Terms
No PR-backed term mappings yet. Add entries here when review PRs introduce repeated wording corrections.
## Guidance
- Prefer natural Arabic phrasing over literal translation
- Keep tone clear and direct in UI labels and docs prose
- Preserve technical artifacts exactly: commands, flags, code, URLs, model IDs, and file paths
- For RTL text, treat code, commands, and paths as LTR artifacts and keep their character order unchanged
## Avoid
- Avoid translating product and protocol names that are fixed identifiers
- Avoid mixing multiple Arabic terms for the same recurring UI action once a preferred term is established
+34
View File
@@ -0,0 +1,34 @@
# br Glossary
## Sources
- PR #10086: https://github.com/anomalyco/opencode/pull/10086
## Do Not Translate (Locale Additions)
- `OpenCode` (preserve casing in prose; keep `opencode` only in commands, package names, paths, or code)
- `OpenCode CLI`
- `CLI`, `TUI`, `MCP`, `OAuth`
- Locale code `br` in repo config, code, and paths (repo alias for Brazilian Portuguese)
## Preferred Terms
These are PR-backed locale naming preferences and may evolve.
| English / Context | Preferred | Notes |
| ---------------------------------------- | ------------------------------ | ------------------------------------------------------------- |
| Brazilian Portuguese (prose locale name) | `pt-BR` | Use standard locale naming in prose when helpful |
| Repo locale slug (code/config) | `br` | PR #10086 uses `br` for consistency/simplicity |
| Browser locale detection | `pt`, `pt-br`, `pt-BR` -> `br` | Preserve this mapping in docs/examples about locale detection |
## Guidance
- This file covers Brazilian Portuguese (`pt-BR`), but the repo locale code is `br`
- Use natural Brazilian Portuguese phrasing over literal translation
- Preserve technical artifacts exactly: commands, flags, code, URLs, model IDs, and file paths
- Keep repo locale identifiers as implemented in code/config (`br`) even when prose mentions `pt-BR`
## Avoid
- Avoid changing repo locale code references from `br` to `pt-br` in code snippets, paths, or config examples
- Avoid mixing Portuguese variants when a Brazilian Portuguese form is established
+33
View File
@@ -0,0 +1,33 @@
# bs Glossary
## Sources
- PR #12283: https://github.com/anomalyco/opencode/pull/12283
## Do Not Translate (Locale Additions)
- `OpenCode` (preserve casing in prose; keep `opencode` only in commands, package names, paths, or code)
- `OpenCode CLI`
- `CLI`, `TUI`, `MCP`, `OAuth`
- Commands, flags, file paths, and code literals (keep exactly as written)
## Preferred Terms
These are PR-backed locale naming preferences and may evolve.
| English / Context | Preferred | Notes |
| ---------------------------------- | ---------- | ------------------------------------------------- |
| Bosnian language label (UI) | `Bosanski` | PR #12283 tested switching language to `Bosanski` |
| Repo locale slug (code/config) | `bs` | Preserve in code, config, paths, and examples |
| Browser locale detection (Bosnian) | `bs` | PR #12283 added `bs` locale auto-detection |
## Guidance
- Use natural Bosnian phrasing over literal translation
- Preserve technical artifacts exactly: commands, flags, code, URLs, model IDs, and file paths
- Keep repo locale references as `bs` in code/config, and use `Bosanski` for the user-facing language name when applicable
## Avoid
- Avoid changing repo locale references from `bs` to another slug in code snippets or config examples
- Avoid translating product and protocol names that are fixed identifiers
+27
View File
@@ -0,0 +1,27 @@
# da Glossary
## Sources
- PR #9821: https://github.com/anomalyco/opencode/pull/9821
## Do Not Translate (Locale Additions)
- `OpenCode` (preserve casing in prose; keep `opencode` only in commands, package names, paths, or code)
- `OpenCode CLI`
- `CLI`, `TUI`, `MCP`, `OAuth`
- Commands, flags, file paths, and code literals (keep exactly as written)
## Preferred Terms
No PR-backed term mappings yet. Add entries here when review PRs introduce repeated wording corrections.
## Guidance
- Prefer natural Danish phrasing over literal translation
- Keep tone clear and direct in UI labels and docs prose
- Preserve technical artifacts exactly: commands, flags, code, URLs, model IDs, and file paths
## Avoid
- Avoid translating product and protocol names that are fixed identifiers
- Avoid mixing multiple Danish terms for the same recurring UI action once a preferred term is established
+27
View File
@@ -0,0 +1,27 @@
# de Glossary
## Sources
- PR #9817: https://github.com/anomalyco/opencode/pull/9817
## Do Not Translate (Locale Additions)
- `OpenCode` (preserve casing in prose; keep `opencode` only in commands, package names, paths, or code)
- `OpenCode CLI`
- `CLI`, `TUI`, `MCP`, `OAuth`
- Commands, flags, file paths, and code literals (keep exactly as written)
## Preferred Terms
No PR-backed term mappings yet. Add entries here when review PRs introduce repeated wording corrections.
## Guidance
- Prefer natural German phrasing over literal translation
- Keep tone clear and direct in UI labels and docs prose
- Preserve technical artifacts exactly: commands, flags, code, URLs, model IDs, and file paths
## Avoid
- Avoid translating product and protocol names that are fixed identifiers
- Avoid mixing multiple German terms for the same recurring UI action once a preferred term is established
+27
View File
@@ -0,0 +1,27 @@
# es Glossary
## Sources
- PR #9817: https://github.com/anomalyco/opencode/pull/9817
## Do Not Translate (Locale Additions)
- `OpenCode` (preserve casing in prose; keep `opencode` only in commands, package names, paths, or code)
- `OpenCode CLI`
- `CLI`, `TUI`, `MCP`, `OAuth`
- Commands, flags, file paths, and code literals (keep exactly as written)
## Preferred Terms
No PR-backed term mappings yet. Add entries here when review PRs introduce repeated wording corrections.
## Guidance
- Prefer natural Spanish phrasing over literal translation
- Keep tone clear and direct in UI labels and docs prose
- Preserve technical artifacts exactly: commands, flags, code, URLs, model IDs, and file paths
## Avoid
- Avoid translating product and protocol names that are fixed identifiers
- Avoid mixing multiple Spanish terms for the same recurring UI action once a preferred term is established
+27
View File
@@ -0,0 +1,27 @@
# fr Glossary
## Sources
- PR #9821: https://github.com/anomalyco/opencode/pull/9821
## Do Not Translate (Locale Additions)
- `OpenCode` (preserve casing in prose; keep `opencode` only in commands, package names, paths, or code)
- `OpenCode CLI`
- `CLI`, `TUI`, `MCP`, `OAuth`
- Commands, flags, file paths, and code literals (keep exactly as written)
## Preferred Terms
No PR-backed term mappings yet. Add entries here when review PRs introduce repeated wording corrections.
## Guidance
- Prefer natural French phrasing over literal translation
- Keep tone clear and direct in UI labels and docs prose
- Preserve technical artifacts exactly: commands, flags, code, URLs, model IDs, and file paths
## Avoid
- Avoid translating product and protocol names that are fixed identifiers
- Avoid mixing multiple French terms for the same recurring UI action once a preferred term is established
+33
View File
@@ -0,0 +1,33 @@
# ja Glossary
## Sources
- PR #9821: https://github.com/anomalyco/opencode/pull/9821
- PR #13160: https://github.com/anomalyco/opencode/pull/13160
## Do Not Translate (Locale Additions)
- `OpenCode` (preserve casing in prose; keep `opencode` only in commands, package names, paths, or code)
- `OpenCode CLI`
- `CLI`, `TUI`, `MCP`, `OAuth`
- Commands, flags, file paths, and code literals (keep exactly as written)
## Preferred Terms
These are PR-backed wording preferences and may evolve.
| English / Context | Preferred | Notes |
| --------------------------- | ----------------------- | ------------------------------------- |
| WSL integration (UI label) | `WSL連携` | PR #13160 prefers this over `WSL統合` |
| WSL integration description | `WindowsのWSL環境で...` | PR #13160 improved phrasing naturally |
## Guidance
- Prefer natural Japanese phrasing over literal translation
- Preserve technical artifacts exactly: commands, flags, code, URLs, model IDs, and file paths
- In WSL integration text, follow PR #13160 wording direction for more natural Japanese phrasing
## Avoid
- Avoid `WSL統合` in the WSL integration UI context where `WSL連携` is the reviewed wording
- Avoid translating product and protocol names that are fixed identifiers
+27
View File
@@ -0,0 +1,27 @@
# ko Glossary
## Sources
- PR #9817: https://github.com/anomalyco/opencode/pull/9817
## Do Not Translate (Locale Additions)
- `OpenCode` (preserve casing in prose; keep `opencode` only in commands, package names, paths, or code)
- `OpenCode CLI`
- `CLI`, `TUI`, `MCP`, `OAuth`
- Commands, flags, file paths, and code literals (keep exactly as written)
## Preferred Terms
No PR-backed term mappings yet. Add entries here when review PRs introduce repeated wording corrections.
## Guidance
- Prefer natural Korean phrasing over literal translation
- Keep tone clear and direct in UI labels and docs prose
- Preserve technical artifacts exactly: commands, flags, code, URLs, model IDs, and file paths
## Avoid
- Avoid translating product and protocol names that are fixed identifiers
- Avoid mixing multiple Korean terms for the same recurring UI action once a preferred term is established
+38
View File
@@ -0,0 +1,38 @@
# no Glossary
## Sources
- PR #10018: https://github.com/anomalyco/opencode/pull/10018
- PR #12935: https://github.com/anomalyco/opencode/pull/12935
## Do Not Translate (Locale Additions)
- `OpenCode` (preserve casing in prose; keep `opencode` only in commands, package names, paths, or code)
- `OpenCode CLI`
- `CLI`, `TUI`, `MCP`, `OAuth`
- Sound names (PR #10018 notes these were intentionally left untranslated)
## Preferred Terms
These are PR-backed corrections and may evolve.
| English / Context | Preferred | Notes |
| ----------------------------------- | ------------ | ----------------------------- |
| Save (data persistence action) | `Lagre` | Prefer over `Spare` |
| Disabled (feature/state) | `deaktivert` | Prefer over `funksjonshemmet` |
| API keys | `API Nøkler` | Prefer over `API Taster` |
| Cost (noun) | `Kostnad` | Prefer over verb form `Koste` |
| Show/View (imperative button label) | `Vis` | Prefer over `Utsikt` |
## Guidance
- Prefer natural Norwegian Bokmal (Bokmål) wording over literal translation
- Keep tone clear and practical in UI labels
- Preserve technical artifacts exactly: commands, flags, code, URLs, model IDs, and file paths
- Keep recurring UI terms consistent once a preferred term is chosen
## Avoid
- Avoid `Spare` for save actions in persistence contexts
- Avoid `funksjonshemmet` for disabled feature states
- Avoid `API Taster`, `Koste`, and `Utsikt` in the corrected contexts above
+27
View File
@@ -0,0 +1,27 @@
# pl Glossary
## Sources
- PR #9884: https://github.com/anomalyco/opencode/pull/9884
## Do Not Translate (Locale Additions)
- `OpenCode` (preserve casing in prose; keep `opencode` only in commands, package names, paths, or code)
- `OpenCode CLI`
- `CLI`, `TUI`, `MCP`, `OAuth`
- Commands, flags, file paths, and code literals (keep exactly as written)
## Preferred Terms
No PR-backed term mappings yet. Add entries here when review PRs introduce repeated wording corrections.
## Guidance
- Prefer natural Polish phrasing over literal translation
- Keep tone clear and direct in UI labels and docs prose
- Preserve technical artifacts exactly: commands, flags, code, URLs, model IDs, and file paths
## Avoid
- Avoid translating product and protocol names that are fixed identifiers
- Avoid mixing multiple Polish terms for the same recurring UI action once a preferred term is established
+27
View File
@@ -0,0 +1,27 @@
# ru Glossary
## Sources
- PR #9882: https://github.com/anomalyco/opencode/pull/9882
## Do Not Translate (Locale Additions)
- `OpenCode` (preserve casing in prose; keep `opencode` only in commands, package names, paths, or code)
- `OpenCode CLI`
- `CLI`, `TUI`, `MCP`, `OAuth`
- Commands, flags, file paths, and code literals (keep exactly as written)
## Preferred Terms
No PR-backed term mappings yet. Add entries here when review PRs introduce repeated wording corrections.
## Guidance
- Prefer natural Russian phrasing over literal translation
- Keep tone clear and direct in UI labels and docs prose
- Preserve technical artifacts exactly: commands, flags, code, URLs, model IDs, and file paths
## Avoid
- Avoid translating product and protocol names that are fixed identifiers
- Avoid mixing multiple Russian terms for the same recurring UI action once a preferred term is established
+34
View File
@@ -0,0 +1,34 @@
# th Glossary
## Sources
- PR #10809: https://github.com/anomalyco/opencode/pull/10809
- PR #11496: https://github.com/anomalyco/opencode/pull/11496
## Do Not Translate (Locale Additions)
- `OpenCode` (preserve casing in prose; keep `opencode` only in commands, package names, paths, or code)
- `OpenCode CLI`
- `CLI`, `TUI`, `MCP`, `OAuth`
- Commands, flags, file paths, and code literals (keep exactly as written)
## Preferred Terms
These are PR-backed preferences and may evolve.
| English / Context | Preferred | Notes |
| ------------------------------------- | --------------------- | -------------------------------------------------------------------------------- |
| Thai language label in language lists | `ไทย` | PR #10809 standardized this across locales |
| Language names in language pickers | Native names (static) | PR #11496: keep names like `English`, `Deutsch`, `ไทย` consistent across locales |
## Guidance
- Prefer natural Thai phrasing over literal translation
- Keep tone short and clear for buttons and labels
- Preserve technical artifacts exactly: commands, flags, code, URLs, model IDs, and file paths
- Keep language names static/native in language pickers instead of translating them per current locale (PR #11496)
## Avoid
- Avoid translating language names differently per current locale in language lists
- Avoid changing `ไทย` to another display form for the Thai language option unless the product standard changes
+38
View File
@@ -0,0 +1,38 @@
# tr Glossary
## Sources
- PR #15835: https://github.com/anomalyco/opencode/pull/15835
## Do Not Translate (Locale Additions)
- `OpenCode` (preserve casing in prose, docs, and UI copy)
- Keep lowercase `opencode` in commands, package names, paths, URLs, and other exact identifiers
- `<TAB>` stays the literal key token in code blocks; use `Tab` for the nearby explanatory label in prose
- Commands, flags, file paths, and code literals (keep exactly as written)
## Preferred Terms
These are PR-backed wording preferences and may evolve.
| English / Context | Preferred | Notes |
| ------------------------- | --------------------------------------- | ------------------------------------------------------------- |
| available in beta | `beta olarak mevcut` | Prefer this over `beta olarak kullanılabilir` |
| privacy-first | `Gizlilik öncelikli tasarlandı` | Prefer this over `Önce gizlilik için tasarlandı` |
| connect your local models | `yerel modellerinizi bağlayabilirsiniz` | Use the fuller, more direct action phrase |
| `<TAB>` key label | `Tab` | Use `Tab` in prose; keep `<TAB>` in literal UI or code blocks |
| cross-platform | `cross-platform (tüm platformlarda)` | Keep the English term, add a short clarification when helpful |
## Guidance
- Prefer natural Turkish phrasing over literal translation
- Merge broken sentence fragments into one clear sentence when the source is a single thought
- Keep product naming consistent: `OpenCode` in prose, `opencode` only for exact technical identifiers
- When an English technical term is intentionally kept, add a short Turkish clarification only if it improves readability
## Avoid
- Avoid `beta olarak kullanılabilir` when `beta olarak mevcut` fits
- Avoid `Önce gizlilik için tasarlandı`; use the more natural reviewed wording instead
- Avoid `Sekme` for the translated key label in prose when referring to `<TAB>`
- Avoid changing `opencode` to `OpenCode` inside commands, URLs, package names, or code literals
+42
View File
@@ -0,0 +1,42 @@
# zh-cn Glossary
## Sources
- PR #13942: https://github.com/anomalyco/opencode/pull/13942
## Do Not Translate (Locale Additions)
- `OpenCode` (preserve casing in prose; keep `opencode` only when it is part of commands, package names, paths, or code)
- `OpenCode Zen`
- `OpenCode CLI`
- `CLI`, `TUI`, `MCP`, `OAuth`
- `Model Context Protocol` (prefer the English expansion when introducing `MCP`)
## Preferred Terms
These are preferred terms for docs/UI prose and may evolve.
| English | Preferred | Notes |
| ----------------------- | --------- | ------------------------------------------- |
| prompt | 提示词 | Keep `--prompt` unchanged in flags/code |
| session | 会话 | |
| provider | 提供商 | |
| share link / shared URL | 分享链接 | Prefer `分享` for user-facing share actions |
| headless (server) | 无界面 | Docs wording |
| authentication | 认证 | Prefer in auth/OAuth contexts |
| cache | 缓存 | |
| keybind / shortcut | 快捷键 | User-facing docs wording |
| workflow | 工作流 | e.g. GitHub Actions workflow |
## Guidance
- Prefer natural, concise phrasing over literal translation
- Keep the tone direct and friendly (PR #13942 consistently moved wording in this direction)
- Preserve technical artifacts exactly: commands, flags, code, inline code, URLs, file paths, model IDs
- Keep enum-like values in English when they are literals (for example, `default`, `json`)
- Prefer consistent terminology across pages once a term is chosen (`会话`, `提供商`, `提示词`, etc.)
## Avoid
- Avoid `opencode` in prose when referring to the product name; use `OpenCode`
- Avoid mixing alternative terms for the same concept across docs when a preferred term is already established
+42
View File
@@ -0,0 +1,42 @@
# zh-tw Glossary
## Sources
- PR #13942: https://github.com/anomalyco/opencode/pull/13942
## Do Not Translate (Locale Additions)
- `OpenCode` (preserve casing in prose; keep `opencode` only when it is part of commands, package names, paths, or code)
- `OpenCode Zen`
- `OpenCode CLI`
- `CLI`, `TUI`, `MCP`, `OAuth`
- `Model Context Protocol` (prefer the English expansion when introducing `MCP`)
## Preferred Terms
These are preferred terms for docs/UI prose and may evolve.
| English | Preferred | Notes |
| ----------------------- | --------- | ------------------------------------------- |
| prompt | 提示詞 | Keep `--prompt` unchanged in flags/code |
| session | 工作階段 | |
| provider | 供應商 | |
| share link / shared URL | 分享連結 | Prefer `分享` for user-facing share actions |
| headless (server) | 無介面 | Docs wording |
| authentication | 認證 | Prefer in auth/OAuth contexts |
| cache | 快取 | |
| keybind / shortcut | 快捷鍵 | User-facing docs wording |
| workflow | 工作流程 | e.g. GitHub Actions workflow |
## Guidance
- Prefer natural, concise phrasing over literal translation
- Keep the tone direct and friendly (PR #13942 consistently moved wording in this direction)
- Preserve technical artifacts exactly: commands, flags, code, inline code, URLs, file paths, model IDs
- Keep enum-like values in English when they are literals (for example, `default`, `json`)
- Prefer consistent terminology across pages once a term is chosen (`工作階段`, `供應商`, `提示詞`, etc.)
## Avoid
- Avoid `opencode` in prose when referring to the product name; use `OpenCode`
- Avoid mixing alternative terms for the same concept across docs when a preferred term is already established
+5 -3
View File
@@ -1,13 +1,15 @@
{
"$schema": "https://opencode.ai/config.json",
// "enterprise": {
// "url": "https://enterprise.dev.opencode.ai",
// },
"provider": {
"opencode": {
"options": {},
},
},
"permission": {
"edit": {
"packages/opencode/migration/*": "deny",
},
},
"mcp": {},
"tools": {
"github-triage": false,
-42
View File
@@ -1,42 +0,0 @@
---
name: bun-file-io
description: Use this when you are working on file operations like reading, writing, scanning, or deleting files. It summarizes the preferred file APIs and patterns used in this repo. It also notes when to use filesystem helpers for directories.
---
## Use this when
- Editing file I/O or scans in `packages/opencode`
- Handling directory operations or external tools
## Bun file APIs (from Bun docs)
- `Bun.file(path)` is lazy; call `text`, `json`, `stream`, `arrayBuffer`, `bytes`, `exists` to read.
- Metadata: `file.size`, `file.type`, `file.name`.
- `Bun.write(dest, input)` writes strings, buffers, Blobs, Responses, or files.
- `Bun.file(...).delete()` deletes a file.
- `file.writer()` returns a FileSink for incremental writes.
- `Bun.Glob` + `Array.fromAsync(glob.scan({ cwd, absolute, onlyFiles, dot }))` for scans.
- Use `Bun.which` to find a binary, then `Bun.spawn` to run it.
- `Bun.readableStreamToText/Bytes/JSON` for stream output.
## When to use node:fs
- Use `node:fs/promises` for directories (`mkdir`, `readdir`, recursive operations).
## Repo patterns
- Prefer Bun APIs over Node `fs` for file access.
- Check `Bun.file(...).exists()` before reading.
- For binary/large files use `arrayBuffer()` and MIME checks via `file.type`.
- Use `Bun.Glob` + `Array.fromAsync` for scans.
- Decode tool stderr with `Bun.readableStreamToText`.
- For large writes, use `Bun.write(Bun.file(path), text)`.
NOTE: Bun.file(...).exists() will return `false` if the value is a directory.
Use Filesystem.exists(...) instead if path can be file or directory
## Quick checklist
- Use Bun APIs first.
- Use `path.join`/`path.resolve` for paths.
- Prefer promise `.catch(...)` over `try/catch` when possible.
+10 -3
View File
@@ -1,7 +1,5 @@
/// <reference path="../env.d.ts" />
import { tool } from "@opencode-ai/plugin"
import DESCRIPTION from "./github-pr-search.txt"
async function githubFetch(endpoint: string, options: RequestInit = {}) {
const response = await fetch(`https://api.github.com${endpoint}`, {
...options,
@@ -24,7 +22,16 @@ interface PR {
}
export default tool({
description: DESCRIPTION,
description: `Use this tool to search GitHub pull requests by title and description.
This tool searches PRs in the anomalyco/opencode repository and returns LLM-friendly results including:
- PR number and title
- Author
- State (open/closed/merged)
- Labels
- Description snippet
Use the query parameter to search for keywords that might appear in PR titles or descriptions.`,
args: {
query: tool.schema.string().describe("Search query for PR titles and descriptions"),
limit: tool.schema.number().describe("Maximum number of results to return").default(10),
-10
View File
@@ -1,10 +0,0 @@
Use this tool to search GitHub pull requests by title and description.
This tool searches PRs in the sst/opencode repository and returns LLM-friendly results including:
- PR number and title
- Author
- State (open/closed/merged)
- Labels
- Description snippet
Use the query parameter to search for keywords that might appear in PR titles or descriptions.
+54 -28
View File
@@ -1,7 +1,19 @@
/// <reference path="../env.d.ts" />
// import { Octokit } from "@octokit/rest"
import { tool } from "@opencode-ai/plugin"
import DESCRIPTION from "./github-triage.txt"
const TEAM = {
desktop: ["adamdotdevin", "iamdavidhill", "Brendonovich", "nexxeln"],
zen: ["fwang", "MrMushrooooom"],
tui: ["thdxr", "kommander", "rekram1-node"],
core: ["thdxr", "rekram1-node", "jlongster"],
docs: ["R44VC0RP"],
windows: ["Hona"],
} as const
const ASSIGNEES = [...new Set(Object.values(TEAM).flat())]
function pick<T>(items: readonly T[]) {
return items[Math.floor(Math.random() * items.length)]!
}
function getIssueNumber(): number {
const issue = parseInt(process.env.ISSUE_NUMBER ?? "", 10)
@@ -26,63 +38,77 @@ async function githubFetch(endpoint: string, options: RequestInit = {}) {
}
export default tool({
description: DESCRIPTION,
description: `Use this tool to assign and/or label a GitHub issue.
Choose labels and assignee using the current triage policy and ownership rules.
Pick the most fitting labels for the issue and assign one owner.
If unsure, choose the team/section with the most overlap with the issue and assign a member from that team at random.`,
args: {
assignee: tool.schema
.enum(["thdxr", "adamdotdevin", "rekram1-node", "fwang", "jayair", "kommander"])
.enum(ASSIGNEES as [string, ...string[]])
.describe("The username of the assignee")
.default("rekram1-node"),
labels: tool.schema
.array(tool.schema.enum(["nix", "opentui", "perf", "desktop", "zen", "docs", "windows"]))
.array(tool.schema.enum(["nix", "opentui", "perf", "web", "desktop", "zen", "docs", "windows", "core"]))
.describe("The labels(s) to add to the issue")
.default([]),
},
async execute(args) {
const issue = getIssueNumber()
// const octokit = new Octokit({ auth: process.env.GITHUB_TOKEN })
const owner = "anomalyco"
const repo = "opencode"
const results: string[] = []
let labels = [...new Set(args.labels.map((x) => (x === "desktop" ? "web" : x)))]
const web = labels.includes("web")
const text = `${process.env.ISSUE_TITLE ?? ""}\n${process.env.ISSUE_BODY ?? ""}`.toLowerCase()
const zen = /\bzen\b/.test(text) || text.includes("opencode black")
const nix = /\bnix(os)?\b/.test(text)
if (args.assignee === "adamdotdevin" && !args.labels.includes("desktop")) {
throw new Error("Only desktop issues should be assigned to adamdotdevin")
if (labels.includes("nix") && !nix) {
labels = labels.filter((x) => x !== "nix")
results.push("Dropped label: nix (issue does not mention nix)")
}
if (args.assignee === "fwang" && !args.labels.includes("zen")) {
throw new Error("Only zen issues should be assigned to fwang")
const assignee = nix ? "rekram1-node" : web ? pick(TEAM.desktop) : args.assignee
if (labels.includes("zen") && !zen) {
throw new Error("Only add the zen label when issue title/body contains 'zen'")
}
if (args.assignee === "kommander" && !args.labels.includes("opentui")) {
if (web && !nix && !(TEAM.desktop as readonly string[]).includes(assignee)) {
throw new Error("Web issues must be assigned to adamdotdevin, iamdavidhill, Brendonovich, or nexxeln")
}
if ((TEAM.zen as readonly string[]).includes(assignee) && !labels.includes("zen")) {
throw new Error("Only zen issues should be assigned to fwang or MrMushrooooom")
}
if (assignee === "Hona" && !labels.includes("windows")) {
throw new Error("Only windows issues should be assigned to Hona")
}
if (assignee === "R44VC0RP" && !labels.includes("docs")) {
throw new Error("Only docs issues should be assigned to R44VC0RP")
}
if (assignee === "kommander" && !labels.includes("opentui")) {
throw new Error("Only opentui issues should be assigned to kommander")
}
// await octokit.rest.issues.addAssignees({
// owner,
// repo,
// issue_number: issue,
// assignees: [args.assignee],
// })
await githubFetch(`/repos/${owner}/${repo}/issues/${issue}/assignees`, {
method: "POST",
body: JSON.stringify({ assignees: [args.assignee] }),
body: JSON.stringify({ assignees: [assignee] }),
})
results.push(`Assigned @${args.assignee} to issue #${issue}`)
const labels: string[] = args.labels.map((label) => (label === "desktop" ? "web" : label))
results.push(`Assigned @${assignee} to issue #${issue}`)
if (labels.length > 0) {
// await octokit.rest.issues.addLabels({
// owner,
// repo,
// issue_number: issue,
// labels,
// })
await githubFetch(`/repos/${owner}/${repo}/issues/${issue}/labels`, {
method: "POST",
body: JSON.stringify({ labels }),
})
results.push(`Added labels: ${args.labels.join(", ")}`)
results.push(`Added labels: ${labels.join(", ")}`)
}
return results.join("\n")
-88
View File
@@ -1,88 +0,0 @@
Use this tool to assign and/or label a GitHub issue.
You can assign the following users:
- thdxr
- adamdotdevin
- fwang
- jayair
- kommander
- rekram1-node
You can use the following labels:
- nix
- opentui
- perf
- web
- zen
- docs
Always try to assign an issue, if in doubt, assign rekram1-node to it.
## Breakdown of responsibilities:
### thdxr
Dax is responsible for managing core parts of the application, for large feature requests, api changes, or things that require significant changes to the codebase assign him.
This relates to OpenCode server primarily but has overlap with just about anything
### adamdotdevin
Adam is responsible for managing the Desktop/Web app. If there is an issue relating to the desktop app or `opencode web` command. Assign him.
### fwang
Frank is responsible for managing Zen, if you see complaints about OpenCode Zen, maybe it's the dashboard, the model quality, billing issues, etc. Assign him to the issue.
### jayair
Jay is responsible for documentation. If there is an issue relating to documentation assign him.
### kommander
Sebastian is responsible for managing an OpenTUI (a library for building terminal user interfaces). OpenCode's TUI is built with OpenTUI. If there are issues about:
- random characters on screen
- keybinds not working on different terminals
- general terminal stuff
Then assign the issue to Him.
### rekram1-node
ALL BUGS SHOULD BE assigned to rekram1-node unless they have the `opentui` label.
Assign Aiden to an issue as a catch all, if you can't assign anyone else. Most of the time this will be bugs/polish things.
If no one else makes sense to assign, assign rekram1-node to it.
Always assign to aiden if the issue mentions "acp", "zed", or model performance issues
## Breakdown of Labels:
### nix
Any issue that mentions nix, or nixos should have a nix label
### opentui
Anything relating to the TUI itself should have an opentui label
### perf
Anything related to slow performance, high ram, high cpu usage, or any other performance related issue should have a perf label
### desktop
Anything related to `opencode web` command or the desktop app should have a desktop label. Never add this label for anything terminal/tui related
### zen
Anything related to OpenCode Zen, billing, or model quality from Zen should have a zen label
### docs
Anything related to the documentation should have a docs label
### windows
Use for any issue that involves the windows OS
+1 -3
View File
@@ -1,7 +1,5 @@
github-policies:
runners:
allowed_groups:
- "GitHub Actions"
- "blacksmith runners 01kbd5v56sg8tz7rea39b7ygpt"
build:
disallow_reruns: false
branch_rulesets:
+9
View File
@@ -0,0 +1,9 @@
{
"format_on_save": "on",
"formatter": {
"external": {
"command": "bunx",
"arguments": ["prettier", "--stdin-filepath", "{buffer_path}"]
}
}
}
+16
View File
@@ -20,6 +20,17 @@
Prefer single word names for variables and functions. Only use multiple words if necessary.
### Naming Enforcement (Read This)
THIS RULE IS MANDATORY FOR AGENT WRITTEN CODE.
- Use single word names by default for new locals, params, and helper functions.
- Multi-word names are allowed only when a single word would be unclear or ambiguous.
- Do not introduce new camelCase compounds when a short single-word alternative is clear.
- Before finishing edits, review touched lines and shorten newly introduced identifiers where possible.
- Good short names to prefer: `pid`, `cfg`, `err`, `opts`, `dir`, `root`, `child`, `state`, `timeout`.
- Examples to avoid unless truly required: `inputPID`, `existingClient`, `connectTimeout`, `workerPath`.
```ts
// Good
const foo = 1
@@ -110,3 +121,8 @@ const table = sqliteTable("session", {
- Avoid mocks as much as possible
- Test actual implementation, do not duplicate logic into tests
- Tests cannot run from repo root (guard: `do-not-run-tests-from-root`); run from package dirs like `packages/opencode`.
## Type Checking
- Always run `bun typecheck` from package directories (e.g., `packages/opencode`), never `tsc` directly.
+5
View File
@@ -24,6 +24,11 @@ If you are unsure if a PR would be accepted, feel free to ask a maintainer or lo
Want to take on an issue? Leave a comment and a maintainer may assign it to you unless it is something we are already working on.
## Adding New Providers
New providers shouldn't require many if ANY code changes, but if you want to add support for a new provider first make a PR to:
https://github.com/anomalyco/models.dev
## Developing OpenCode
- Requirements: Bun 1.3+
+8 -2
View File
@@ -27,11 +27,16 @@
<a href="README.ja.md">日本語</a> |
<a href="README.pl.md">Polski</a> |
<a href="README.ru.md">Русский</a> |
<a href="README.bs.md">Bosanski</a> |
<a href="README.ar.md">العربية</a> |
<a href="README.no.md">Norsk</a> |
<a href="README.br.md">Português (Brasil)</a> |
<a href="README.th.md">ไทย</a> |
<a href="README.tr.md">Türkçe</a>
<a href="README.tr.md">Türkçe</a> |
<a href="README.uk.md">Українська</a> |
<a href="README.bn.md">বাংলা</a> |
<a href="README.gr.md">Ελληνικά</a> |
<a href="README.vi.md">Tiếng Việt</a>
</p>
[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai)
@@ -50,7 +55,8 @@ scoop install opencode # Windows
choco install opencode # Windows
brew install anomalyco/tap/opencode # macOS و Linux (موصى به، دائما محدث)
brew install opencode # macOS و Linux (صيغة brew الرسمية، تحديث اقل)
paru -S opencode-bin # Arch Linux
sudo pacman -S opencode # Arch Linux (Stable)
paru -S opencode-bin # Arch Linux (Latest from AUR)
mise use -g opencode # اي نظام
nix run nixpkgs#opencode # او github:anomalyco/opencode لاحدث فرع dev
```
+141
View File
@@ -0,0 +1,141 @@
<p align="center">
<a href="https://opencode.ai">
<picture>
<source srcset="packages/console/app/src/asset/logo-ornate-dark.svg" media="(prefers-color-scheme: dark)">
<source srcset="packages/console/app/src/asset/logo-ornate-light.svg" media="(prefers-color-scheme: light)">
<img src="packages/console/app/src/asset/logo-ornate-light.svg" alt="OpenCode logo">
</picture>
</a>
</p>
<p align="center">ওপেন সোর্স এআই কোডিং এজেন্ট।</p>
<p align="center">
<a href="https://opencode.ai/discord"><img alt="Discord" src="https://img.shields.io/discord/1391832426048651334?style=flat-square&label=discord" /></a>
<a href="https://www.npmjs.com/package/opencode-ai"><img alt="npm" src="https://img.shields.io/npm/v/opencode-ai?style=flat-square" /></a>
<a href="https://github.com/anomalyco/opencode/actions/workflows/publish.yml"><img alt="Build status" src="https://img.shields.io/github/actions/workflow/status/anomalyco/opencode/publish.yml?style=flat-square&branch=dev" /></a>
</p>
<p align="center">
<a href="README.md">English</a> |
<a href="README.zh.md">简体中文</a> |
<a href="README.zht.md">繁體中文</a> |
<a href="README.ko.md">한국어</a> |
<a href="README.de.md">Deutsch</a> |
<a href="README.es.md">Español</a> |
<a href="README.fr.md">Français</a> |
<a href="README.it.md">Italiano</a> |
<a href="README.da.md">Dansk</a> |
<a href="README.ja.md">日本語</a> |
<a href="README.pl.md">Polski</a> |
<a href="README.ru.md">Русский</a> |
<a href="README.bs.md">Bosanski</a> |
<a href="README.ar.md">العربية</a> |
<a href="README.no.md">Norsk</a> |
<a href="README.br.md">Português (Brasil)</a> |
<a href="README.th.md">ไทย</a> |
<a href="README.tr.md">Türkçe</a> |
<a href="README.uk.md">Українська</a> |
<a href="README.bn.md">বাংলা</a> |
<a href="README.gr.md">Ελληνικά</a> |
<a href="README.vi.md">Tiếng Việt</a>
</p>
[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai)
---
### ইনস্টলেশন (Installation)
```bash
# YOLO
curl -fsSL https://opencode.ai/install | bash
# Package managers
npm i -g opencode-ai@latest # or bun/pnpm/yarn
scoop install opencode # Windows
choco install opencode # Windows
brew install anomalyco/tap/opencode # macOS and Linux (recommended, always up to date)
brew install opencode # macOS and Linux (official brew formula, updated less)
sudo pacman -S opencode # Arch Linux (Stable)
paru -S opencode-bin # Arch Linux (Latest from AUR)
mise use -g opencode # Any OS
nix run nixpkgs#opencode # or github:anomalyco/opencode for latest dev branch
```
> [!TIP]
> ইনস্টল করার আগে ০.১.x এর চেয়ে পুরোনো ভার্সনগুলো মুছে ফেলুন।
### ডেস্কটপ অ্যাপ (BETA)
OpenCode ডেস্কটপ অ্যাপ্লিকেশন হিসেবেও উপলব্ধ। সরাসরি [রিলিজ পেজ](https://github.com/anomalyco/opencode/releases) অথবা [opencode.ai/download](https://opencode.ai/download) থেকে ডাউনলোড করুন।
| প্ল্যাটফর্ম | ডাউনলোড |
| --------------------- | ------------------------------------- |
| macOS (Apple Silicon) | `opencode-desktop-darwin-aarch64.dmg` |
| macOS (Intel) | `opencode-desktop-darwin-x64.dmg` |
| Windows | `opencode-desktop-windows-x64.exe` |
| Linux | `.deb`, `.rpm`, or AppImage |
```bash
# macOS (Homebrew)
brew install --cask opencode-desktop
# Windows (Scoop)
scoop bucket add extras; scoop install extras/opencode-desktop
```
#### ইনস্টলেশন ডিরেক্টরি (Installation Directory)
ইনস্টল স্ক্রিপ্টটি ইনস্টলেশন পাতের জন্য নিম্নলিখিত অগ্রাধিকার ক্রম মেনে চলে:
1. `$OPENCODE_INSTALL_DIR` - কাস্টম ইনস্টলেশন ডিরেক্টরি
2. `$XDG_BIN_DIR` - XDG বেস ডিরেক্টরি স্পেসিফিকেশন সমর্থিত পাথ
3. `$HOME/bin` - সাধারণ ব্যবহারকারী বাইনারি ডিরেক্টরি (যদি বিদ্যমান থাকে বা তৈরি করা যায়)
4. `$HOME/.opencode/bin` - ডিফল্ট ফলব্যাক
```bash
# উদাহরণ
OPENCODE_INSTALL_DIR=/usr/local/bin curl -fsSL https://opencode.ai/install | bash
XDG_BIN_DIR=$HOME/.local/bin curl -fsSL https://opencode.ai/install | bash
```
### এজেন্টস (Agents)
OpenCode এ দুটি বিল্ট-ইন এজেন্ট রয়েছে যা আপনি `Tab` কি(key) দিয়ে পরিবর্তন করতে পারবেন।
- **build** - ডিফল্ট, ডেভেলপমেন্টের কাজের জন্য সম্পূর্ণ অ্যাক্সেসযুক্ত এজেন্ট
- **plan** - বিশ্লেষণ এবং কোড এক্সপ্লোরেশনের জন্য রিড-ওনলি এজেন্ট
- ডিফল্টভাবে ফাইল এডিট করতে দেয় না
- ব্যাশ কমান্ড চালানোর আগে অনুমতি চায়
- অপরিচিত কোডবেস এক্সপ্লোর করা বা পরিবর্তনের পরিকল্পনা করার জন্য আদর্শ
এছাড়াও জটিল অনুসন্ধান এবং মাল্টিস্টেপ টাস্কের জন্য একটি **general** সাবএজেন্ট অন্তর্ভুক্ত রয়েছে।
এটি অভ্যন্তরীণভাবে ব্যবহৃত হয় এবং মেসেজে `@general` লিখে ব্যবহার করা যেতে পারে।
এজেন্টদের সম্পর্কে আরও জানুন: [docs](https://opencode.ai/docs/agents)।
### ডকুমেন্টেশন (Documentation)
কিভাবে OpenCode কনফিগার করবেন সে সম্পর্কে আরও তথ্যের জন্য, [**আমাদের ডকস দেখুন**](https://opencode.ai/docs)।
### অবদান (Contributing)
আপনি যদি OpenCode এ অবদান রাখতে চান, অনুগ্রহ করে একটি পুল রিকোয়েস্ট সাবমিট করার আগে আমাদের [কন্ট্রিবিউটিং ডকস](./CONTRIBUTING.md) পড়ে নিন।
### OpenCode এর উপর বিল্ডিং (Building on OpenCode)
আপনি যদি এমন প্রজেক্টে কাজ করেন যা OpenCode এর সাথে সম্পর্কিত এবং প্রজেক্টের নামের অংশ হিসেবে "opencode" ব্যবহার করেন, উদাহরণস্বরূপ "opencode-dashboard" বা "opencode-mobile", তবে দয়া করে আপনার README তে একটি নোট যোগ করে স্পষ্ট করুন যে এই প্রজেক্টটি OpenCode দল দ্বারা তৈরি হয়নি এবং আমাদের সাথে এর কোনো সরাসরি সম্পর্ক নেই।
### সচরাচর জিজ্ঞাসিত প্রশ্নাবলী (FAQ)
#### এটি ক্লড কোড (Claude Code) থেকে কীভাবে আলাদা?
ক্যাপাবিলিটির দিক থেকে এটি ক্লড কোডের (Claude Code) মতই। এখানে মূল পার্থক্যগুলো দেওয়া হলো:
- ১০০% ওপেন সোর্স
- কোনো প্রোভাইডারের সাথে আবদ্ধ নয়। যদিও আমরা [OpenCode Zen](https://opencode.ai/zen) এর মাধ্যমে মডেলসমূহ ব্যবহারের পরামর্শ দিই, OpenCode ক্লড (Claude), ওপেনএআই (OpenAI), গুগল (Google), অথবা লোকাল মডেলগুলোর সাথেও ব্যবহার করা যেতে পারে। যেমন যেমন মডেলগুলো উন্নত হবে, তাদের মধ্যকার পার্থক্য কমে আসবে এবং দামও কমবে, তাই প্রোভাইডার-অজ্ঞাস্টিক হওয়া খুবই গুরুত্বপূর্ণ।
- আউট-অফ-দ্য-বক্স LSP সাপোর্ট
- TUI এর উপর ফোকাস। OpenCode নিওভিম (neovim) ব্যবহারকারী এবং [terminal.shop](https://terminal.shop) এর নির্মাতাদের দ্বারা তৈরি; আমরা টার্মিনালে কী কী সম্ভব তার সীমাবদ্ধতা ছাড়িয়ে যাওয়ার চেষ্টা করছি।
- ক্লায়েন্ট/সার্ভার আর্কিটেকচার। এটি যেমন OpenCode কে আপনার কম্পিউটারে চালানোর সুযোগ দেয়, তেমনি আপনি মোবাইল অ্যাপ থেকে রিমোটলি এটি নিয়ন্ত্রণ করতে পারবেন, অর্থাৎ TUI ফ্রন্টএন্ড কেবল সম্ভাব্য ক্লায়েন্টগুলোর মধ্যে একটি।
---
**আমাদের কমিউনিটিতে যুক্ত হোন** [Discord](https://discord.gg/opencode) | [X.com](https://x.com/opencode)
+8 -2
View File
@@ -27,11 +27,16 @@
<a href="README.ja.md">日本語</a> |
<a href="README.pl.md">Polski</a> |
<a href="README.ru.md">Русский</a> |
<a href="README.bs.md">Bosanski</a> |
<a href="README.ar.md">العربية</a> |
<a href="README.no.md">Norsk</a> |
<a href="README.br.md">Português (Brasil)</a> |
<a href="README.th.md">ไทย</a> |
<a href="README.tr.md">Türkçe</a>
<a href="README.tr.md">Türkçe</a> |
<a href="README.uk.md">Українська</a> |
<a href="README.bn.md">বাংলা</a> |
<a href="README.gr.md">Ελληνικά</a> |
<a href="README.vi.md">Tiếng Việt</a>
</p>
[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai)
@@ -50,7 +55,8 @@ scoop install opencode # Windows
choco install opencode # Windows
brew install anomalyco/tap/opencode # macOS e Linux (recomendado, sempre atualizado)
brew install opencode # macOS e Linux (fórmula oficial do brew, atualiza menos)
paru -S opencode-bin # Arch Linux
sudo pacman -S opencode # Arch Linux (Stable)
paru -S opencode-bin # Arch Linux (Latest from AUR)
mise use -g opencode # qualquer sistema
nix run nixpkgs#opencode # ou github:anomalyco/opencode para a branch dev mais recente
```
+7 -2
View File
@@ -32,7 +32,11 @@
<a href="README.no.md">Norsk</a> |
<a href="README.br.md">Português (Brasil)</a> |
<a href="README.th.md">ไทย</a> |
<a href="README.tr.md">Türkçe</a>
<a href="README.tr.md">Türkçe</a> |
<a href="README.uk.md">Українська</a> |
<a href="README.bn.md">বাংলা</a> |
<a href="README.gr.md">Ελληνικά</a> |
<a href="README.vi.md">Tiếng Việt</a>
</p>
[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai)
@@ -51,7 +55,8 @@ scoop install opencode # Windows
choco install opencode # Windows
brew install anomalyco/tap/opencode # macOS i Linux (preporučeno, uvijek ažurno)
brew install opencode # macOS i Linux (zvanična brew formula, rjeđe se ažurira)
paru -S opencode-bin # Arch Linux
sudo pacman -S opencode # Arch Linux (Stable)
paru -S opencode-bin # Arch Linux (Latest from AUR)
mise use -g opencode # Bilo koji OS
nix run nixpkgs#opencode # ili github:anomalyco/opencode za najnoviji dev branch
```
+8 -2
View File
@@ -27,11 +27,16 @@
<a href="README.ja.md">日本語</a> |
<a href="README.pl.md">Polski</a> |
<a href="README.ru.md">Русский</a> |
<a href="README.bs.md">Bosanski</a> |
<a href="README.ar.md">العربية</a> |
<a href="README.no.md">Norsk</a> |
<a href="README.br.md">Português (Brasil)</a> |
<a href="README.th.md">ไทย</a> |
<a href="README.tr.md">Türkçe</a>
<a href="README.tr.md">Türkçe</a> |
<a href="README.uk.md">Українська</a> |
<a href="README.bn.md">বাংলা</a> |
<a href="README.gr.md">Ελληνικά</a> |
<a href="README.vi.md">Tiếng Việt</a>
</p>
[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai)
@@ -50,7 +55,8 @@ scoop install opencode # Windows
choco install opencode # Windows
brew install anomalyco/tap/opencode # macOS og Linux (anbefalet, altid up to date)
brew install opencode # macOS og Linux (officiel brew formula, opdateres sjældnere)
paru -S opencode-bin # Arch Linux
sudo pacman -S opencode # Arch Linux (Stable)
paru -S opencode-bin # Arch Linux (Latest from AUR)
mise use -g opencode # alle OS
nix run nixpkgs#opencode # eller github:anomalyco/opencode for nyeste dev-branch
```
+8 -2
View File
@@ -27,11 +27,16 @@
<a href="README.ja.md">日本語</a> |
<a href="README.pl.md">Polski</a> |
<a href="README.ru.md">Русский</a> |
<a href="README.bs.md">Bosanski</a> |
<a href="README.ar.md">العربية</a> |
<a href="README.no.md">Norsk</a> |
<a href="README.br.md">Português (Brasil)</a> |
<a href="README.th.md">ไทย</a> |
<a href="README.tr.md">Türkçe</a>
<a href="README.tr.md">Türkçe</a> |
<a href="README.uk.md">Українська</a> |
<a href="README.bn.md">বাংলা</a> |
<a href="README.gr.md">Ελληνικά</a> |
<a href="README.vi.md">Tiếng Việt</a>
</p>
[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai)
@@ -50,7 +55,8 @@ scoop install opencode # Windows
choco install opencode # Windows
brew install anomalyco/tap/opencode # macOS und Linux (empfohlen, immer aktuell)
brew install opencode # macOS und Linux (offizielle Brew-Formula, seltener aktualisiert)
paru -S opencode-bin # Arch Linux
sudo pacman -S opencode # Arch Linux (Stable)
paru -S opencode-bin # Arch Linux (Latest from AUR)
mise use -g opencode # jedes Betriebssystem
nix run nixpkgs#opencode # oder github:anomalyco/opencode für den neuesten dev-Branch
```
+8 -2
View File
@@ -27,11 +27,16 @@
<a href="README.ja.md">日本語</a> |
<a href="README.pl.md">Polski</a> |
<a href="README.ru.md">Русский</a> |
<a href="README.bs.md">Bosanski</a> |
<a href="README.ar.md">العربية</a> |
<a href="README.no.md">Norsk</a> |
<a href="README.br.md">Português (Brasil)</a> |
<a href="README.th.md">ไทย</a> |
<a href="README.tr.md">Türkçe</a>
<a href="README.tr.md">Türkçe</a> |
<a href="README.uk.md">Українська</a> |
<a href="README.bn.md">বাংলা</a> |
<a href="README.gr.md">Ελληνικά</a> |
<a href="README.vi.md">Tiếng Việt</a>
</p>
[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai)
@@ -50,7 +55,8 @@ scoop install opencode # Windows
choco install opencode # Windows
brew install anomalyco/tap/opencode # macOS y Linux (recomendado, siempre al día)
brew install opencode # macOS y Linux (fórmula oficial de brew, se actualiza menos)
paru -S opencode-bin # Arch Linux
sudo pacman -S opencode # Arch Linux (Stable)
paru -S opencode-bin # Arch Linux (Latest from AUR)
mise use -g opencode # cualquier sistema
nix run nixpkgs#opencode # o github:anomalyco/opencode para la rama dev más reciente
```
+8 -2
View File
@@ -27,11 +27,16 @@
<a href="README.ja.md">日本語</a> |
<a href="README.pl.md">Polski</a> |
<a href="README.ru.md">Русский</a> |
<a href="README.bs.md">Bosanski</a> |
<a href="README.ar.md">العربية</a> |
<a href="README.no.md">Norsk</a> |
<a href="README.br.md">Português (Brasil)</a> |
<a href="README.th.md">ไทย</a> |
<a href="README.tr.md">Türkçe</a>
<a href="README.tr.md">Türkçe</a> |
<a href="README.uk.md">Українська</a> |
<a href="README.bn.md">বাংলা</a> |
<a href="README.gr.md">Ελληνικά</a> |
<a href="README.vi.md">Tiếng Việt</a>
</p>
[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai)
@@ -50,7 +55,8 @@ scoop install opencode # Windows
choco install opencode # Windows
brew install anomalyco/tap/opencode # macOS et Linux (recommandé, toujours à jour)
brew install opencode # macOS et Linux (formule officielle brew, mise à jour moins fréquente)
paru -S opencode-bin # Arch Linux
sudo pacman -S opencode # Arch Linux (Stable)
paru -S opencode-bin # Arch Linux (Latest from AUR)
mise use -g opencode # n'importe quel OS
nix run nixpkgs#opencode # ou github:anomalyco/opencode pour la branche dev la plus récente
```
+141
View File
@@ -0,0 +1,141 @@
<p align="center">
<a href="https://opencode.ai">
<picture>
<source srcset="packages/console/app/src/asset/logo-ornate-dark.svg" media="(prefers-color-scheme: dark)">
<source srcset="packages/console/app/src/asset/logo-ornate-light.svg" media="(prefers-color-scheme: light)">
<img src="packages/console/app/src/asset/logo-ornate-light.svg" alt="OpenCode logo">
</picture>
</a>
</p>
<p align="center">Ο πράκτορας τεχνητής νοημοσύνης ανοικτού κώδικα για προγραμματισμό.</p>
<p align="center">
<a href="https://opencode.ai/discord"><img alt="Discord" src="https://img.shields.io/discord/1391832426048651334?style=flat-square&label=discord" /></a>
<a href="https://www.npmjs.com/package/opencode-ai"><img alt="npm" src="https://img.shields.io/npm/v/opencode-ai?style=flat-square" /></a>
<a href="https://github.com/anomalyco/opencode/actions/workflows/publish.yml"><img alt="Build status" src="https://img.shields.io/github/actions/workflow/status/anomalyco/opencode/publish.yml?style=flat-square&branch=dev" /></a>
</p>
<p align="center">
<a href="README.md">English</a> |
<a href="README.zh.md">简体中文</a> |
<a href="README.zht.md">繁體中文</a> |
<a href="README.ko.md">한국어</a> |
<a href="README.de.md">Deutsch</a> |
<a href="README.es.md">Español</a> |
<a href="README.fr.md">Français</a> |
<a href="README.it.md">Italiano</a> |
<a href="README.da.md">Dansk</a> |
<a href="README.ja.md">日本語</a> |
<a href="README.pl.md">Polski</a> |
<a href="README.ru.md">Русский</a> |
<a href="README.bs.md">Bosanski</a> |
<a href="README.ar.md">العربية</a> |
<a href="README.no.md">Norsk</a> |
<a href="README.br.md">Português (Brasil)</a> |
<a href="README.th.md">ไทย</a> |
<a href="README.tr.md">Türkçe</a> |
<a href="README.uk.md">Українська</a> |
<a href="README.bn.md">বাংলা</a> |
<a href="README.gr.md">Ελληνικά</a> |
<a href="README.vi.md">Tiếng Việt</a>
</p>
[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai)
---
### Εγκατάσταση
```bash
# YOLO
curl -fsSL https://opencode.ai/install | bash
# Διαχειριστές πακέτων
npm i -g opencode-ai@latest # ή bun/pnpm/yarn
scoop install opencode # Windows
choco install opencode # Windows
brew install anomalyco/tap/opencode # macOS και Linux (προτείνεται, πάντα ενημερωμένο)
brew install opencode # macOS και Linux (επίσημος τύπος brew, λιγότερο συχνές ενημερώσεις)
sudo pacman -S opencode # Arch Linux (Σταθερό)
paru -S opencode-bin # Arch Linux (Τελευταία έκδοση από AUR)
mise use -g opencode # Οποιοδήποτε λειτουργικό σύστημα
nix run nixpkgs#opencode # ή github:anomalyco/opencode με βάση την πιο πρόσφατη αλλαγή από το dev branch
```
> [!TIP]
> Αφαίρεσε παλαιότερες εκδόσεις από τη 0.1.x πριν από την εγκατάσταση.
### Εφαρμογή Desktop (BETA)
Το OpenCode είναι επίσης διαθέσιμο ως εφαρμογή. Κατέβασε το απευθείας από τη [σελίδα εκδόσεων](https://github.com/anomalyco/opencode/releases) ή το [opencode.ai/download](https://opencode.ai/download).
| Πλατφόρμα | Λήψη |
| --------------------- | ------------------------------------- |
| macOS (Apple Silicon) | `opencode-desktop-darwin-aarch64.dmg` |
| macOS (Intel) | `opencode-desktop-darwin-x64.dmg` |
| Windows | `opencode-desktop-windows-x64.exe` |
| Linux | `.deb`, `.rpm`, ή AppImage |
```bash
# macOS (Homebrew)
brew install --cask opencode-desktop
# Windows (Scoop)
scoop bucket add extras; scoop install extras/opencode-desktop
```
#### Κατάλογος Εγκατάστασης
Το script εγκατάστασης τηρεί την ακόλουθη σειρά προτεραιότητας για τη διαδρομή εγκατάστασης:
1. `$OPENCODE_INSTALL_DIR` - Προσαρμοσμένος κατάλογος εγκατάστασης
2. `$XDG_BIN_DIR` - Διαδρομή συμβατή με τις προδιαγραφές XDG Base Directory
3. `$HOME/bin` - Τυπικός κατάλογος εκτελέσιμων αρχείων χρήστη (εάν υπάρχει ή μπορεί να δημιουργηθεί)
4. `$HOME/.opencode/bin` - Προεπιλεγμένη εφεδρική διαδρομή
```bash
# Παραδείγματα
OPENCODE_INSTALL_DIR=/usr/local/bin curl -fsSL https://opencode.ai/install | bash
XDG_BIN_DIR=$HOME/.local/bin curl -fsSL https://opencode.ai/install | bash
```
### Πράκτορες
Το OpenCode περιλαμβάνει δύο ενσωματωμένους πράκτορες μεταξύ των οποίων μπορείτε να εναλλάσσεστε με το πλήκτρο `Tab`.
- **build** - Προεπιλεγμένος πράκτορας με πλήρη πρόσβαση για εργασία πάνω σε κώδικα
- **plan** - Πράκτορας μόνο ανάγνωσης για ανάλυση και εξερεύνηση κώδικα
- Αρνείται την επεξεργασία αρχείων από προεπιλογή
- Ζητά άδεια πριν εκτελέσει εντολές bash
- Ιδανικός για εξερεύνηση άγνωστων αρχείων πηγαίου κώδικα ή σχεδιασμό αλλαγών
Περιλαμβάνεται επίσης ένας **general** υποπράκτορας για σύνθετες αναζητήσεις και πολυβηματικές διεργασίες.
Χρησιμοποιείται εσωτερικά και μπορεί να κληθεί χρησιμοποιώντας `@general` στα μηνύματα.
Μάθετε περισσότερα για τους [πράκτορες](https://opencode.ai/docs/agents).
### Οδηγός Χρήσης
Για περισσότερες πληροφορίες σχετικά με τη ρύθμιση του OpenCode, [**πλοηγήσου στον οδηγό χρήσης μας**](https://opencode.ai/docs).
### Συνεισφορά
Εάν ενδιαφέρεσαι να συνεισφέρεις στο OpenCode, διαβάστε τα [οδηγό χρήσης συνεισφοράς](./CONTRIBUTING.md) πριν υποβάλεις ένα pull request.
### Δημιουργία πάνω στο OpenCode
Εάν εργάζεσαι σε ένα έργο σχετικό με το OpenCode και χρησιμοποιείτε το "opencode" ως μέρος του ονόματός του, για παράδειγμα "opencode-dashboard" ή "opencode-mobile", πρόσθεσε μια σημείωση στο README σας για να διευκρινίσεις ότι δεν είναι κατασκευασμένο από την ομάδα του OpenCode και δεν έχει καμία σχέση με εμάς.
### Συχνές Ερωτήσεις
#### Πώς διαφέρει αυτό από το Claude Code;
Είναι πολύ παρόμοιο με το Claude Code ως προς τις δυνατότητες. Ακολουθούν οι βασικές διαφορές:
- 100% ανοιχτού κώδικα
- Δεν είναι συνδεδεμένο με κανέναν πάροχο. Αν και συνιστούμε τα μοντέλα που παρέχουμε μέσω του [OpenCode Zen](https://opencode.ai/zen), το OpenCode μπορεί να χρησιμοποιηθεί με Claude, OpenAI, Google, ή ακόμα και τοπικά μοντέλα. Καθώς τα μοντέλα εξελίσσονται, τα κενά μεταξύ τους θα κλείσουν και οι τιμές θα μειωθούν, οπότε είναι σημαντικό να είσαι ανεξάρτητος από τον πάροχο.
- Out-of-the-box υποστήριξη LSP
- Εστίαση στο TUI. Το OpenCode είναι κατασκευασμένο από χρήστες που χρησιμοποιούν neovim και τους δημιουργούς του [terminal.shop](https://terminal.shop)· θα εξαντλήσουμε τα όρια του τι είναι δυνατό στο terminal.
- Αρχιτεκτονική client/server. Αυτό, για παράδειγμα, μπορεί να επιτρέψει στο OpenCode να τρέχει στον υπολογιστή σου ενώ το χειρίζεσαι εξ αποστάσεως από μια εφαρμογή κινητού, που σημαίνει ότι το TUI frontend είναι μόνο ένας από τους πιθανούς clients.
---
**Γίνε μέλος της κοινότητάς μας** [Discord](https://discord.gg/opencode) | [X.com](https://x.com/opencode)
+8 -2
View File
@@ -27,11 +27,16 @@
<a href="README.ja.md">日本語</a> |
<a href="README.pl.md">Polski</a> |
<a href="README.ru.md">Русский</a> |
<a href="README.bs.md">Bosanski</a> |
<a href="README.ar.md">العربية</a> |
<a href="README.no.md">Norsk</a> |
<a href="README.br.md">Português (Brasil)</a> |
<a href="README.th.md">ไทย</a> |
<a href="README.tr.md">Türkçe</a>
<a href="README.tr.md">Türkçe</a> |
<a href="README.uk.md">Українська</a> |
<a href="README.bn.md">বাংলা</a> |
<a href="README.gr.md">Ελληνικά</a> |
<a href="README.vi.md">Tiếng Việt</a>
</p>
[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai)
@@ -50,7 +55,8 @@ scoop install opencode # Windows
choco install opencode # Windows
brew install anomalyco/tap/opencode # macOS e Linux (consigliato, sempre aggiornato)
brew install opencode # macOS e Linux (formula brew ufficiale, aggiornata meno spesso)
paru -S opencode-bin # Arch Linux
sudo pacman -S opencode # Arch Linux (Stable)
paru -S opencode-bin # Arch Linux (Latest from AUR)
mise use -g opencode # Qualsiasi OS
nix run nixpkgs#opencode # oppure github:anomalyco/opencode per lultima branch di sviluppo
```
+8 -2
View File
@@ -27,11 +27,16 @@
<a href="README.ja.md">日本語</a> |
<a href="README.pl.md">Polski</a> |
<a href="README.ru.md">Русский</a> |
<a href="README.bs.md">Bosanski</a> |
<a href="README.ar.md">العربية</a> |
<a href="README.no.md">Norsk</a> |
<a href="README.br.md">Português (Brasil)</a> |
<a href="README.th.md">ไทย</a> |
<a href="README.tr.md">Türkçe</a>
<a href="README.tr.md">Türkçe</a> |
<a href="README.uk.md">Українська</a> |
<a href="README.bn.md">বাংলা</a> |
<a href="README.gr.md">Ελληνικά</a> |
<a href="README.vi.md">Tiếng Việt</a>
</p>
[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai)
@@ -50,7 +55,8 @@ scoop install opencode # Windows
choco install opencode # Windows
brew install anomalyco/tap/opencode # macOS と Linux(推奨。常に最新)
brew install opencode # macOS と Linux(公式 brew formula。更新頻度は低め)
paru -S opencode-bin # Arch Linux
sudo pacman -S opencode # Arch Linux (Stable)
paru -S opencode-bin # Arch Linux (Latest from AUR)
mise use -g opencode # どのOSでも
nix run nixpkgs#opencode # または github:anomalyco/opencode で最新 dev ブランチ
```
+8 -2
View File
@@ -27,11 +27,16 @@
<a href="README.ja.md">日本語</a> |
<a href="README.pl.md">Polski</a> |
<a href="README.ru.md">Русский</a> |
<a href="README.bs.md">Bosanski</a> |
<a href="README.ar.md">العربية</a> |
<a href="README.no.md">Norsk</a> |
<a href="README.br.md">Português (Brasil)</a> |
<a href="README.th.md">ไทย</a> |
<a href="README.tr.md">Türkçe</a>
<a href="README.tr.md">Türkçe</a> |
<a href="README.uk.md">Українська</a> |
<a href="README.bn.md">বাংলা</a> |
<a href="README.gr.md">Ελληνικά</a> |
<a href="README.vi.md">Tiếng Việt</a>
</p>
[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai)
@@ -50,7 +55,8 @@ scoop install opencode # Windows
choco install opencode # Windows
brew install anomalyco/tap/opencode # macOS 및 Linux (권장, 항상 최신)
brew install opencode # macOS 및 Linux (공식 brew formula, 업데이트 빈도 낮음)
paru -S opencode-bin # Arch Linux
sudo pacman -S opencode # Arch Linux (Stable)
paru -S opencode-bin # Arch Linux (Latest from AUR)
mise use -g opencode # 어떤 OS든
nix run nixpkgs#opencode # 또는 github:anomalyco/opencode 로 최신 dev 브랜치
```
+7 -2
View File
@@ -32,7 +32,11 @@
<a href="README.no.md">Norsk</a> |
<a href="README.br.md">Português (Brasil)</a> |
<a href="README.th.md">ไทย</a> |
<a href="README.tr.md">Türkçe</a>
<a href="README.tr.md">Türkçe</a> |
<a href="README.uk.md">Українська</a> |
<a href="README.bn.md">বাংলা</a> |
<a href="README.gr.md">Ελληνικά</a> |
<a href="README.vi.md">Tiếng Việt</a>
</p>
[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai)
@@ -51,7 +55,8 @@ scoop install opencode # Windows
choco install opencode # Windows
brew install anomalyco/tap/opencode # macOS and Linux (recommended, always up to date)
brew install opencode # macOS and Linux (official brew formula, updated less)
paru -S opencode-bin # Arch Linux
sudo pacman -S opencode # Arch Linux (Stable)
paru -S opencode-bin # Arch Linux (Latest from AUR)
mise use -g opencode # Any OS
nix run nixpkgs#opencode # or github:anomalyco/opencode for latest dev branch
```
+8 -2
View File
@@ -27,11 +27,16 @@
<a href="README.ja.md">日本語</a> |
<a href="README.pl.md">Polski</a> |
<a href="README.ru.md">Русский</a> |
<a href="README.bs.md">Bosanski</a> |
<a href="README.ar.md">العربية</a> |
<a href="README.no.md">Norsk</a> |
<a href="README.br.md">Português (Brasil)</a> |
<a href="README.th.md">ไทย</a> |
<a href="README.tr.md">Türkçe</a>
<a href="README.tr.md">Türkçe</a> |
<a href="README.uk.md">Українська</a> |
<a href="README.bn.md">বাংলা</a> |
<a href="README.gr.md">Ελληνικά</a> |
<a href="README.vi.md">Tiếng Việt</a>
</p>
[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai)
@@ -50,7 +55,8 @@ scoop install opencode # Windows
choco install opencode # Windows
brew install anomalyco/tap/opencode # macOS og Linux (anbefalt, alltid oppdatert)
brew install opencode # macOS og Linux (offisiell brew-formel, oppdateres sjeldnere)
paru -S opencode-bin # Arch Linux
sudo pacman -S opencode # Arch Linux (Stable)
paru -S opencode-bin # Arch Linux (Latest from AUR)
mise use -g opencode # alle OS
nix run nixpkgs#opencode # eller github:anomalyco/opencode for nyeste dev-branch
```
+8 -2
View File
@@ -27,11 +27,16 @@
<a href="README.ja.md">日本語</a> |
<a href="README.pl.md">Polski</a> |
<a href="README.ru.md">Русский</a> |
<a href="README.bs.md">Bosanski</a> |
<a href="README.ar.md">العربية</a> |
<a href="README.no.md">Norsk</a> |
<a href="README.br.md">Português (Brasil)</a> |
<a href="README.th.md">ไทย</a> |
<a href="README.tr.md">Türkçe</a>
<a href="README.tr.md">Türkçe</a> |
<a href="README.uk.md">Українська</a> |
<a href="README.bn.md">বাংলা</a> |
<a href="README.gr.md">Ελληνικά</a> |
<a href="README.vi.md">Tiếng Việt</a>
</p>
[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai)
@@ -50,7 +55,8 @@ scoop install opencode # Windows
choco install opencode # Windows
brew install anomalyco/tap/opencode # macOS i Linux (polecane, zawsze aktualne)
brew install opencode # macOS i Linux (oficjalna formuła brew, rzadziej aktualizowana)
paru -S opencode-bin # Arch Linux
sudo pacman -S opencode # Arch Linux (Stable)
paru -S opencode-bin # Arch Linux (Latest from AUR)
mise use -g opencode # dowolny system
nix run nixpkgs#opencode # lub github:anomalyco/opencode dla najnowszej gałęzi dev
```
+8 -2
View File
@@ -27,11 +27,16 @@
<a href="README.ja.md">日本語</a> |
<a href="README.pl.md">Polski</a> |
<a href="README.ru.md">Русский</a> |
<a href="README.bs.md">Bosanski</a> |
<a href="README.ar.md">العربية</a> |
<a href="README.no.md">Norsk</a> |
<a href="README.br.md">Português (Brasil)</a> |
<a href="README.th.md">ไทย</a> |
<a href="README.tr.md">Türkçe</a>
<a href="README.tr.md">Türkçe</a> |
<a href="README.uk.md">Українська</a> |
<a href="README.bn.md">বাংলা</a> |
<a href="README.gr.md">Ελληνικά</a> |
<a href="README.vi.md">Tiếng Việt</a>
</p>
[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai)
@@ -50,7 +55,8 @@ scoop install opencode # Windows
choco install opencode # Windows
brew install anomalyco/tap/opencode # macOS и Linux (рекомендуем, всегда актуально)
brew install opencode # macOS и Linux (официальная формула brew, обновляется реже)
paru -S opencode-bin # Arch Linux
sudo pacman -S opencode # Arch Linux (Stable)
paru -S opencode-bin # Arch Linux (Latest from AUR)
mise use -g opencode # любая ОС
nix run nixpkgs#opencode # или github:anomalyco/opencode для самой свежей ветки dev
```
+8 -2
View File
@@ -27,11 +27,16 @@
<a href="README.ja.md">日本語</a> |
<a href="README.pl.md">Polski</a> |
<a href="README.ru.md">Русский</a> |
<a href="README.bs.md">Bosanski</a> |
<a href="README.ar.md">العربية</a> |
<a href="README.no.md">Norsk</a> |
<a href="README.br.md">Português (Brasil)</a> |
<a href="README.th.md">ไทย</a> |
<a href="README.tr.md">Türkçe</a>
<a href="README.tr.md">Türkçe</a> |
<a href="README.uk.md">Українська</a> |
<a href="README.bn.md">বাংলা</a> |
<a href="README.gr.md">Ελληνικά</a> |
<a href="README.vi.md">Tiếng Việt</a>
</p>
[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai)
@@ -50,7 +55,8 @@ scoop install opencode # Windows
choco install opencode # Windows
brew install anomalyco/tap/opencode # macOS และ Linux (แนะนำ อัปเดตเสมอ)
brew install opencode # macOS และ Linux (brew formula อย่างเป็นทางการ อัปเดตน้อยกว่า)
paru -S opencode-bin # Arch Linux
sudo pacman -S opencode # Arch Linux (Stable)
paru -S opencode-bin # Arch Linux (Latest from AUR)
mise use -g opencode # ระบบปฏิบัติการใดก็ได้
nix run nixpkgs#opencode # หรือ github:anomalyco/opencode สำหรับสาขาพัฒนาล่าสุด
```
+8 -2
View File
@@ -27,11 +27,16 @@
<a href="README.ja.md">日本語</a> |
<a href="README.pl.md">Polski</a> |
<a href="README.ru.md">Русский</a> |
<a href="README.bs.md">Bosanski</a> |
<a href="README.ar.md">العربية</a> |
<a href="README.no.md">Norsk</a> |
<a href="README.br.md">Português (Brasil)</a> |
<a href="README.th.md">ไทย</a> |
<a href="README.tr.md">Türkçe</a>
<a href="README.tr.md">Türkçe</a> |
<a href="README.uk.md">Українська</a> |
<a href="README.bn.md">বাংলা</a> |
<a href="README.gr.md">Ελληνικά</a> |
<a href="README.vi.md">Tiếng Việt</a>
</p>
[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai)
@@ -50,7 +55,8 @@ scoop install opencode # Windows
choco install opencode # Windows
brew install anomalyco/tap/opencode # macOS ve Linux (önerilir, her zaman güncel)
brew install opencode # macOS ve Linux (resmi brew formülü, daha az güncellenir)
paru -S opencode-bin # Arch Linux
sudo pacman -S opencode # Arch Linux (Stable)
paru -S opencode-bin # Arch Linux (Latest from AUR)
mise use -g opencode # Tüm işletim sistemleri
nix run nixpkgs#opencode # veya en güncel geliştirme dalı için github:anomalyco/opencode
```
+142
View File
@@ -0,0 +1,142 @@
<p align="center">
<a href="https://opencode.ai">
<picture>
<source srcset="packages/console/app/src/asset/logo-ornate-dark.svg" media="(prefers-color-scheme: dark)">
<source srcset="packages/console/app/src/asset/logo-ornate-light.svg" media="(prefers-color-scheme: light)">
<img src="packages/console/app/src/asset/logo-ornate-light.svg" alt="OpenCode logo">
</picture>
</a>
</p>
<p align="center">AI-агент для програмування з відкритим кодом.</p>
<p align="center">
<a href="https://opencode.ai/discord"><img alt="Discord" src="https://img.shields.io/discord/1391832426048651334?style=flat-square&label=discord" /></a>
<a href="https://www.npmjs.com/package/opencode-ai"><img alt="npm" src="https://img.shields.io/npm/v/opencode-ai?style=flat-square" /></a>
<a href="https://github.com/anomalyco/opencode/actions/workflows/publish.yml"><img alt="Build status" src="https://img.shields.io/github/actions/workflow/status/anomalyco/opencode/publish.yml?style=flat-square&branch=dev" /></a>
</p>
<p align="center">
<a href="README.md">English</a> |
<a href="README.zh.md">简体中文</a> |
<a href="README.zht.md">繁體中文</a> |
<a href="README.ko.md">한국어</a> |
<a href="README.de.md">Deutsch</a> |
<a href="README.es.md">Español</a> |
<a href="README.fr.md">Français</a> |
<a href="README.it.md">Italiano</a> |
<a href="README.da.md">Dansk</a> |
<a href="README.ja.md">日本語</a> |
<a href="README.pl.md">Polski</a> |
<a href="README.ru.md">Русский</a> |
<a href="README.bs.md">Bosanski</a> |
<a href="README.ar.md">العربية</a> |
<a href="README.no.md">Norsk</a> |
<a href="README.br.md">Português (Brasil)</a> |
<a href="README.th.md">ไทย</a> |
<a href="README.tr.md">Türkçe</a> |
<a href="README.uk.md">Українська</a> |
<a href="README.bn.md">বাংলা</a> |
<a href="README.gr.md">Ελληνικά</a> |
<a href="README.vi.md">Tiếng Việt</a>
</p>
[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai)
---
### Встановлення
```bash
# YOLO
curl -fsSL https://opencode.ai/install | bash
# Менеджери пакетів
npm i -g opencode-ai@latest # або bun/pnpm/yarn
scoop install opencode # Windows
choco install opencode # Windows
brew install anomalyco/tap/opencode # macOS і Linux (рекомендовано, завжди актуально)
brew install opencode # macOS і Linux (офіційна формула Homebrew, оновлюється рідше)
sudo pacman -S opencode # Arch Linux (Stable)
paru -S opencode-bin # Arch Linux (Latest from AUR)
mise use -g opencode # Будь-яка ОС
nix run nixpkgs#opencode # або github:anomalyco/opencode для найновішої dev-гілки
```
> [!TIP]
> Перед встановленням видаліть версії старші за 0.1.x.
### Десктопний застосунок (BETA)
OpenCode також доступний як десктопний застосунок. Завантажуйте напряму зі [сторінки релізів](https://github.com/anomalyco/opencode/releases) або [opencode.ai/download](https://opencode.ai/download).
| Платформа | Завантаження |
| --------------------- | ------------------------------------- |
| macOS (Apple Silicon) | `opencode-desktop-darwin-aarch64.dmg` |
| macOS (Intel) | `opencode-desktop-darwin-x64.dmg` |
| Windows | `opencode-desktop-windows-x64.exe` |
| Linux | `.deb`, `.rpm` або AppImage |
```bash
# macOS (Homebrew)
brew install --cask opencode-desktop
# Windows (Scoop)
scoop bucket add extras; scoop install extras/opencode-desktop
```
#### Каталог встановлення
Скрипт встановлення дотримується такого порядку пріоритету для шляху встановлення:
1. `$OPENCODE_INSTALL_DIR` - Користувацький каталог встановлення
2. `$XDG_BIN_DIR` - Шлях, сумісний зі специфікацією XDG Base Directory
3. `$HOME/bin` - Стандартний каталог користувацьких бінарників (якщо існує або його можна створити)
4. `$HOME/.opencode/bin` - Резервний варіант за замовчуванням
```bash
# Приклади
OPENCODE_INSTALL_DIR=/usr/local/bin curl -fsSL https://opencode.ai/install | bash
XDG_BIN_DIR=$HOME/.local/bin curl -fsSL https://opencode.ai/install | bash
```
### Агенти
OpenCode містить два вбудовані агенти, між якими можна перемикатися клавішею `Tab`.
- **build** - Агент за замовчуванням із повним доступом для завдань розробки
- **plan** - Агент лише для читання для аналізу та дослідження коду
- За замовчуванням забороняє редагування файлів
- Запитує дозвіл перед запуском bash-команд
- Ідеально підходить для дослідження незнайомих кодових баз або планування змін
Також доступний допоміжний агент **general** для складного пошуку та багатокрокових завдань.
Він використовується всередині системи й може бути викликаний у повідомленнях через `@general`.
Дізнайтеся більше про [agents](https://opencode.ai/docs/agents).
### Документація
Щоб дізнатися більше про налаштування OpenCode, [**перейдіть до нашої документації**](https://opencode.ai/docs).
### Внесок
Якщо ви хочете зробити внесок в OpenCode, будь ласка, прочитайте нашу [документацію для контриб'юторів](./CONTRIBUTING.md) перед надсиланням pull request.
### Проєкти на базі OpenCode
Якщо ви працюєте над проєктом, пов'язаним з OpenCode, і використовуєте "opencode" у назві, наприклад "opencode-dashboard" або "opencode-mobile", додайте примітку до свого README.
Уточніть, що цей проєкт не створений командою OpenCode і жодним чином не афілійований із нами.
### FAQ
#### Чим це відрізняється від Claude Code?
За можливостями це дуже схоже на Claude Code. Ось ключові відмінності:
- 100% open source
- Немає прив'язки до конкретного провайдера. Ми рекомендуємо моделі, які надаємо через [OpenCode Zen](https://opencode.ai/zen), але OpenCode також працює з Claude, OpenAI, Google і навіть локальними моделями. З розвитком моделей різниця між ними зменшуватиметься, а ціни падатимуть, тому незалежність від провайдера має значення.
- Підтримка LSP з коробки
- Фокус на TUI. OpenCode створено користувачами neovim та авторами [terminal.shop](https://terminal.shop); ми й надалі розширюватимемо межі можливого в терміналі.
- Клієнт-серверна архітектура. Наприклад, це дає змогу запускати OpenCode на вашому комп'ютері й керувати ним віддалено з мобільного застосунку, тобто TUI-фронтенд - лише один із можливих клієнтів.
---
**Приєднуйтеся до нашої спільноти** [Discord](https://discord.gg/opencode) | [X.com](https://x.com/opencode)
+141
View File
@@ -0,0 +1,141 @@
<p align="center">
<a href="https://opencode.ai">
<picture>
<source srcset="packages/console/app/src/asset/logo-ornate-dark.svg" media="(prefers-color-scheme: dark)">
<source srcset="packages/console/app/src/asset/logo-ornate-light.svg" media="(prefers-color-scheme: light)">
<img src="packages/console/app/src/asset/logo-ornate-light.svg" alt="OpenCode logo">
</picture>
</a>
</p>
<p align="center">Trợ lý lập trình AI mã nguồn mở.</p>
<p align="center">
<a href="https://opencode.ai/discord"><img alt="Discord" src="https://img.shields.io/discord/1391832426048651334?style=flat-square&label=discord" /></a>
<a href="https://www.npmjs.com/package/opencode-ai"><img alt="npm" src="https://img.shields.io/npm/v/opencode-ai?style=flat-square" /></a>
<a href="https://github.com/anomalyco/opencode/actions/workflows/publish.yml"><img alt="Build status" src="https://img.shields.io/github/actions/workflow/status/anomalyco/opencode/publish.yml?style=flat-square&branch=dev" /></a>
</p>
<p align="center">
<a href="README.md">English</a> |
<a href="README.zh.md">简体中文</a> |
<a href="README.zht.md">繁體中文</a> |
<a href="README.ko.md">한국어</a> |
<a href="README.de.md">Deutsch</a> |
<a href="README.es.md">Español</a> |
<a href="README.fr.md">Français</a> |
<a href="README.it.md">Italiano</a> |
<a href="README.da.md">Dansk</a> |
<a href="README.ja.md">日本語</a> |
<a href="README.pl.md">Polski</a> |
<a href="README.ru.md">Русский</a> |
<a href="README.bs.md">Bosanski</a> |
<a href="README.ar.md">العربية</a> |
<a href="README.no.md">Norsk</a> |
<a href="README.br.md">Português (Brasil)</a> |
<a href="README.th.md">ไทย</a> |
<a href="README.tr.md">Türkçe</a> |
<a href="README.uk.md">Українська</a> |
<a href="README.bn.md">বাংলা</a> |
<a href="README.gr.md">Ελληνικά</a> |
<a href="README.vi.md">Tiếng Việt</a>
</p>
[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai)
---
### Cài đặt
```bash
# YOLO
curl -fsSL https://opencode.ai/install | bash
# Các trình quản lý gói (Package managers)
npm i -g opencode-ai@latest # hoặc bun/pnpm/yarn
scoop install opencode # Windows
choco install opencode # Windows
brew install anomalyco/tap/opencode # macOS và Linux (khuyên dùng, luôn cập nhật)
brew install opencode # macOS và Linux (công thức brew chính thức, ít cập nhật hơn)
sudo pacman -S opencode # Arch Linux (Bản ổn định)
paru -S opencode-bin # Arch Linux (Bản mới nhất từ AUR)
mise use -g opencode # Mọi hệ điều hành
nix run nixpkgs#opencode # hoặc github:anomalyco/opencode cho nhánh dev mới nhất
```
> [!TIP]
> Hãy xóa các phiên bản cũ hơn 0.1.x trước khi cài đặt.
### Ứng dụng Desktop (BETA)
OpenCode cũng có sẵn dưới dạng ứng dụng desktop. Tải trực tiếp từ [trang releases](https://github.com/anomalyco/opencode/releases) hoặc [opencode.ai/download](https://opencode.ai/download).
| Nền tảng | Tải xuống |
| --------------------- | ------------------------------------- |
| macOS (Apple Silicon) | `opencode-desktop-darwin-aarch64.dmg` |
| macOS (Intel) | `opencode-desktop-darwin-x64.dmg` |
| Windows | `opencode-desktop-windows-x64.exe` |
| Linux | `.deb`, `.rpm`, hoặc AppImage |
```bash
# macOS (Homebrew)
brew install --cask opencode-desktop
# Windows (Scoop)
scoop bucket add extras; scoop install extras/opencode-desktop
```
#### Thư mục cài đặt
Tập lệnh cài đặt tuân theo thứ tự ưu tiên sau cho đường dẫn cài đặt:
1. `$OPENCODE_INSTALL_DIR` - Thư mục cài đặt tùy chỉnh
2. `$XDG_BIN_DIR` - Đường dẫn tuân thủ XDG Base Directory Specification
3. `$HOME/bin` - Thư mục nhị phân tiêu chuẩn của người dùng (nếu tồn tại hoặc có thể tạo)
4. `$HOME/.opencode/bin` - Mặc định dự phòng
```bash
# Ví dụ
OPENCODE_INSTALL_DIR=/usr/local/bin curl -fsSL https://opencode.ai/install | bash
XDG_BIN_DIR=$HOME/.local/bin curl -fsSL https://opencode.ai/install | bash
```
### Agents (Đại diện)
OpenCode bao gồm hai agent được tích hợp sẵn mà bạn có thể chuyển đổi bằng phím `Tab`.
- **build** - Agent mặc định, có toàn quyền truy cập cho công việc lập trình
- **plan** - Agent chỉ đọc dùng để phân tích và khám phá mã nguồn
- Mặc định từ chối việc chỉnh sửa tệp
- Hỏi quyền trước khi chạy các lệnh bash
- Lý tưởng để khám phá các codebase lạ hoặc lên kế hoạch thay đổi
Ngoài ra còn có một subagent **general** dùng cho các tìm kiếm phức tạp và tác vụ nhiều bước.
Agent này được sử dụng nội bộ và có thể gọi bằng cách dùng `@general` trong tin nhắn.
Tìm hiểu thêm về [agents](https://opencode.ai/docs/agents).
### Tài liệu
Để biết thêm thông tin về cách cấu hình OpenCode, [**hãy truy cập tài liệu của chúng tôi**](https://opencode.ai/docs).
### Đóng góp
Nếu bạn muốn đóng góp cho OpenCode, vui lòng đọc [tài liệu hướng dẫn đóng góp](./CONTRIBUTING.md) trước khi gửi pull request.
### Xây dựng trên nền tảng OpenCode
Nếu bạn đang làm việc trên một dự án liên quan đến OpenCode và sử dụng "opencode" như một phần của tên dự án, ví dụ "opencode-dashboard" hoặc "opencode-mobile", vui lòng thêm một ghi chú vào README của bạn để làm rõ rằng dự án đó không được xây dựng bởi đội ngũ OpenCode và không liên kết với chúng tôi dưới bất kỳ hình thức nào.
### Các câu hỏi thường gặp (FAQ)
#### OpenCode khác biệt thế nào so với Claude Code?
Về mặt tính năng, nó rất giống Claude Code. Dưới đây là những điểm khác biệt chính:
- 100% mã nguồn mở
- Không bị ràng buộc với bất kỳ nhà cung cấp nào. Mặc dù chúng tôi khuyên dùng các mô hình được cung cấp qua [OpenCode Zen](https://opencode.ai/zen), OpenCode có thể được sử dụng với Claude, OpenAI, Google, hoặc thậm chí các mô hình chạy cục bộ. Khi các mô hình phát triển, khoảng cách giữa chúng sẽ thu hẹp lại và giá cả sẽ giảm, vì vậy việc không phụ thuộc vào nhà cung cấp là rất quan trọng.
- Hỗ trợ LSP ngay từ đầu
- Tập trung vào TUI (Giao diện người dùng dòng lệnh). OpenCode được xây dựng bởi những người dùng neovim và đội ngũ tạo ra [terminal.shop](https://terminal.shop); chúng tôi sẽ đẩy giới hạn của những gì có thể làm được trên terminal lên mức tối đa.
- Kiến trúc client/server. Chẳng hạn, điều này cho phép OpenCode chạy trên máy tính của bạn trong khi bạn điều khiển nó từ xa qua một ứng dụng di động, nghĩa là frontend TUI chỉ là một trong những client có thể dùng.
---
**Tham gia cộng đồng của chúng tôi** [Discord](https://discord.gg/opencode) | [X.com](https://x.com/opencode)
+9 -3
View File
@@ -27,11 +27,16 @@
<a href="README.ja.md">日本語</a> |
<a href="README.pl.md">Polski</a> |
<a href="README.ru.md">Русский</a> |
<a href="README.bs.md">Bosanski</a> |
<a href="README.ar.md">العربية</a> |
<a href="README.no.md">Norsk</a> |
<a href="README.br.md">Português (Brasil)</a> |
<a href="README.th.md">ไทย</a> |
<a href="README.tr.md">Türkçe</a>
<a href="README.tr.md">Türkçe</a> |
<a href="README.uk.md">Українська</a> |
<a href="README.bn.md">বাংলা</a> |
<a href="README.gr.md">Ελληνικά</a> |
<a href="README.vi.md">Tiếng Việt</a>
</p>
[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai)
@@ -50,7 +55,8 @@ scoop install opencode # Windows
choco install opencode # Windows
brew install anomalyco/tap/opencode # macOS 和 Linux(推荐,始终保持最新)
brew install opencode # macOS 和 Linux(官方 brew formula,更新频率较低)
paru -S opencode-bin # Arch Linux
sudo pacman -S opencode # Arch Linux (Stable)
paru -S opencode-bin # Arch Linux (Latest from AUR)
mise use -g opencode # 任意系统
nix run nixpkgs#opencode # 或用 github:anomalyco/opencode 获取最新 dev 分支
```
@@ -131,4 +137,4 @@ OpenCode 内置两种 Agent,可用 `Tab` 键快速切换:
---
**加入我们的社区** [Discord](https://discord.gg/opencode) | [X.com](https://x.com/opencode)
**加入我们的社区** [飞书](https://applink.feishu.cn/client/chat/chatter/add_by_link?link_token=738j8655-cd59-4633-a30a-1124e0096789&qr_code=true) | [X.com](https://x.com/opencode)
+9 -3
View File
@@ -27,11 +27,16 @@
<a href="README.ja.md">日本語</a> |
<a href="README.pl.md">Polski</a> |
<a href="README.ru.md">Русский</a> |
<a href="README.bs.md">Bosanski</a> |
<a href="README.ar.md">العربية</a> |
<a href="README.no.md">Norsk</a> |
<a href="README.br.md">Português (Brasil)</a> |
<a href="README.th.md">ไทย</a> |
<a href="README.tr.md">Türkçe</a>
<a href="README.tr.md">Türkçe</a> |
<a href="README.uk.md">Українська</a> |
<a href="README.bn.md">বাংলা</a> |
<a href="README.gr.md">Ελληνικά</a> |
<a href="README.vi.md">Tiếng Việt</a>
</p>
[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai)
@@ -50,7 +55,8 @@ scoop install opencode # Windows
choco install opencode # Windows
brew install anomalyco/tap/opencode # macOS 與 Linux(推薦,始終保持最新)
brew install opencode # macOS 與 Linux(官方 brew formula,更新頻率較低)
paru -S opencode-bin # Arch Linux
sudo pacman -S opencode # Arch Linux (Stable)
paru -S opencode-bin # Arch Linux (Latest from AUR)
mise use -g opencode # 任何作業系統
nix run nixpkgs#opencode # 或使用 github:anomalyco/opencode 以取得最新開發分支
```
@@ -131,4 +137,4 @@ OpenCode 內建了兩種 Agent,您可以使用 `Tab` 鍵快速切換。
---
**加入我們的社群** [Discord](https://discord.gg/opencode) | [X.com](https://x.com/opencode)
**加入我們的社群** [飞书](https://applink.feishu.cn/client/chat/chatter/add_by_link?link_token=738j8655-cd59-4633-a30a-1124e0096789&qr_code=true) | [X.com](https://x.com/opencode)
+6
View File
@@ -1,5 +1,11 @@
# Security
## IMPORTANT
We do not accept AI generated security reports. We receive a large number of
these and we absolutely do not have the resources to review them all. If you
submit one that will be an automatic ban from the project.
## Threat Model
### Overview
+1859 -459
View File
File diff suppressed because it is too large Load Diff
Generated
+3 -3
View File
@@ -2,11 +2,11 @@
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1770073757,
"narHash": "sha256-Vy+G+F+3E/Tl+GMNgiHl9Pah2DgShmIUBJXmbiQPHbI=",
"lastModified": 1773909469,
"narHash": "sha256-vglVrLfHjFIzIdV9A27Ugul6rh3I1qHbbitGW7dk420=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "47472570b1e607482890801aeaf29bfb749884f6",
"rev": "7149c06513f335be57f26fcbbbe34afda923882b",
"type": "github"
},
"original": {
+5
View File
@@ -30,6 +30,10 @@ inputs:
description: "Comma-separated list of trigger phrases (case-insensitive). Defaults to '/opencode,/oc'"
required: false
variant:
description: "Model variant for provider-specific reasoning effort (e.g., high, max, minimal)"
required: false
oidc_base_url:
description: "Base URL for OIDC token exchange API. Only required when running a custom GitHub App install. Defaults to https://api.opencode.ai"
required: false
@@ -71,4 +75,5 @@ runs:
PROMPT: ${{ inputs.prompt }}
USE_GITHUB_TOKEN: ${{ inputs.use_github_token }}
MENTIONS: ${{ inputs.mentions }}
VARIANT: ${{ inputs.variant }}
OIDC_BASE_URL: ${{ inputs.oidc_base_url }}
+2 -2
View File
@@ -8,6 +8,7 @@ import type { Context as GitHubContext } from "@actions/github/lib/context"
import type { IssueCommentEvent, PullRequestReviewCommentEvent } from "@octokit/webhooks-types"
import { createOpencodeClient } from "@opencode-ai/sdk"
import { spawn } from "node:child_process"
import { setTimeout as sleep } from "node:timers/promises"
type GitHubAuthor = {
login: string
@@ -281,7 +282,7 @@ async function assertOpencodeConnected() {
connected = true
break
} catch (e) {}
await Bun.sleep(300)
await sleep(300)
} while (retry++ < 30)
if (!connected) {
@@ -495,7 +496,6 @@ async function subscribeSessionEvents() {
const TOOL: Record<string, [string, string]> = {
todowrite: ["Todo", "\x1b[33m\x1b[1m"],
todoread: ["Todo", "\x1b[33m\x1b[1m"],
bash: ["Bash", "\x1b[31m\x1b[1m"],
edit: ["Edit", "\x1b[32m\x1b[1m"],
glob: ["Glob", "\x1b[34m\x1b[1m"],
+1
View File
@@ -2,6 +2,7 @@
/* tslint:disable */
/* eslint-disable */
/* deno-fmt-ignore-file */
/* biome-ignore-all lint: auto-generated */
/// <reference path="../sst-env.d.ts" />
+57 -13
View File
@@ -100,29 +100,55 @@ export const stripeWebhook = new stripe.WebhookEndpoint("StripeWebhookEndpoint",
],
})
const zenProduct = new stripe.Product("ZenBlack", {
const zenLiteProduct = new stripe.Product("ZenLite", {
name: "OpenCode Go",
})
const zenLiteCouponFirstMonth50 = new stripe.Coupon("ZenLiteCouponFirstMonth50", {
name: "First month 50% off",
percentOff: 50,
appliesToProducts: [zenLiteProduct.id],
duration: "once",
})
const zenLitePrice = new stripe.Price("ZenLitePrice", {
product: zenLiteProduct.id,
currency: "usd",
recurring: {
interval: "month",
intervalCount: 1,
},
unitAmount: 1000,
})
const ZEN_LITE_PRICE = new sst.Linkable("ZEN_LITE_PRICE", {
properties: {
product: zenLiteProduct.id,
price: zenLitePrice.id,
priceInr: 92900,
firstMonth50Coupon: zenLiteCouponFirstMonth50.id,
},
})
const zenBlackProduct = new stripe.Product("ZenBlack", {
name: "OpenCode Black",
})
const zenPriceProps = {
product: zenProduct.id,
const zenBlackPriceProps = {
product: zenBlackProduct.id,
currency: "usd",
recurring: {
interval: "month",
intervalCount: 1,
},
}
const zenPrice200 = new stripe.Price("ZenBlackPrice", { ...zenPriceProps, unitAmount: 20000 })
const zenPrice100 = new stripe.Price("ZenBlack100Price", { ...zenPriceProps, unitAmount: 10000 })
const zenPrice20 = new stripe.Price("ZenBlack20Price", { ...zenPriceProps, unitAmount: 2000 })
const zenBlackPrice200 = new stripe.Price("ZenBlackPrice", { ...zenBlackPriceProps, unitAmount: 20000 })
const zenBlackPrice100 = new stripe.Price("ZenBlack100Price", { ...zenBlackPriceProps, unitAmount: 10000 })
const zenBlackPrice20 = new stripe.Price("ZenBlack20Price", { ...zenBlackPriceProps, unitAmount: 2000 })
const ZEN_BLACK_PRICE = new sst.Linkable("ZEN_BLACK_PRICE", {
properties: {
product: zenProduct.id,
plan200: zenPrice200.id,
plan100: zenPrice100.id,
plan20: zenPrice20.id,
product: zenBlackProduct.id,
plan200: zenBlackPrice200.id,
plan100: zenBlackPrice100.id,
plan20: zenBlackPrice20.id,
},
})
const ZEN_BLACK_LIMITS = new sst.Secret("ZEN_BLACK_LIMITS")
const ZEN_MODELS = [
new sst.Secret("ZEN_MODELS1"),
@@ -145,6 +171,16 @@ const ZEN_MODELS = [
new sst.Secret("ZEN_MODELS18"),
new sst.Secret("ZEN_MODELS19"),
new sst.Secret("ZEN_MODELS20"),
new sst.Secret("ZEN_MODELS21"),
new sst.Secret("ZEN_MODELS22"),
new sst.Secret("ZEN_MODELS23"),
new sst.Secret("ZEN_MODELS24"),
new sst.Secret("ZEN_MODELS25"),
new sst.Secret("ZEN_MODELS26"),
new sst.Secret("ZEN_MODELS27"),
new sst.Secret("ZEN_MODELS28"),
new sst.Secret("ZEN_MODELS29"),
new sst.Secret("ZEN_MODELS30"),
]
const STRIPE_SECRET_KEY = new sst.Secret("STRIPE_SECRET_KEY")
const STRIPE_PUBLISHABLE_KEY = new sst.Secret("STRIPE_PUBLISHABLE_KEY")
@@ -166,6 +202,10 @@ const bucketNew = new sst.cloudflare.Bucket("ZenDataNew")
const AWS_SES_ACCESS_KEY_ID = new sst.Secret("AWS_SES_ACCESS_KEY_ID")
const AWS_SES_SECRET_ACCESS_KEY = new sst.Secret("AWS_SES_SECRET_ACCESS_KEY")
const SALESFORCE_CLIENT_ID = new sst.Secret("SALESFORCE_CLIENT_ID")
const SALESFORCE_CLIENT_SECRET = new sst.Secret("SALESFORCE_CLIENT_SECRET")
const SALESFORCE_INSTANCE_URL = new sst.Secret("SALESFORCE_INSTANCE_URL")
const logProcessor = new sst.cloudflare.Worker("LogProcessor", {
handler: "packages/console/function/src/log-processor.ts",
link: [new sst.Secret("HONEYCOMB_API_KEY")],
@@ -184,8 +224,12 @@ new sst.cloudflare.x.SolidStart("Console", {
EMAILOCTOPUS_API_KEY,
AWS_SES_ACCESS_KEY_ID,
AWS_SES_SECRET_ACCESS_KEY,
SALESFORCE_CLIENT_ID,
SALESFORCE_CLIENT_SECRET,
SALESFORCE_INSTANCE_URL,
ZEN_BLACK_PRICE,
ZEN_BLACK_LIMITS,
ZEN_LITE_PRICE,
new sst.Secret("ZEN_LIMITS"),
new sst.Secret("ZEN_SESSION_SECRET"),
...ZEN_MODELS,
...($dev
@@ -204,9 +248,9 @@ new sst.cloudflare.x.SolidStart("Console", {
},
transform: {
server: {
placement: { region: "aws:us-east-1" },
transform: {
worker: {
placement: { mode: "smart" },
tailConsumers: [{ service: logProcessor.nodes.worker.scriptName }],
},
},
+15 -1
View File
@@ -130,7 +130,7 @@ else
needs_baseline=false
if [ "$arch" = "x64" ]; then
if [ "$os" = "linux" ]; then
if ! grep -qi avx2 /proc/cpuinfo 2>/dev/null; then
if ! grep -qwi avx2 /proc/cpuinfo 2>/dev/null; then
needs_baseline=true
fi
fi
@@ -141,6 +141,20 @@ else
needs_baseline=true
fi
fi
if [ "$os" = "windows" ]; then
ps="(Add-Type -MemberDefinition \"[DllImport(\"\"kernel32.dll\"\")] public static extern bool IsProcessorFeaturePresent(int ProcessorFeature);\" -Name Kernel32 -Namespace Win32 -PassThru)::IsProcessorFeaturePresent(40)"
out=""
if command -v powershell.exe >/dev/null 2>&1; then
out=$(powershell.exe -NoProfile -NonInteractive -Command "$ps" 2>/dev/null || true)
elif command -v pwsh >/dev/null 2>&1; then
out=$(pwsh -NoProfile -NonInteractive -Command "$ps" 2>/dev/null || true)
fi
out=$(echo "$out" | tr -d '\r' | tr '[:upper:]' '[:lower:]' | tr -d '[:space:]')
if [ "$out" != "true" ] && [ "$out" != "1" ]; then
needs_baseline=true
fi
fi
fi
target="$os-$arch"
+4 -4
View File
@@ -1,8 +1,8 @@
{
"nodeModules": {
"x86_64-linux": "sha256-saYZlUTkBfg9vp5J1CrJUM1PBXK4xKwyz28RKlT0JWo=",
"aarch64-linux": "sha256-qoiX2CpOD+HSI+eLh3I84TTPdhWdG6MzfkDAXE6ldPo=",
"aarch64-darwin": "sha256-LbAvdaOBuftBoHvQPFwJGr0smg8vH4wNHS6BYdyXdDs=",
"x86_64-darwin": "sha256-bv5qb9Fi8SyrgZFhcdlvYNc4bjyvdyHY3YgUpmkEH2U="
"x86_64-linux": "sha256-l3k/1fRIAQkj7zdVj2Ad3QZWeTOf1CuIM6vgMHRaK1s=",
"aarch64-linux": "sha256-iN3YtrKAUTK1GIwVMoVYkMXhtDZOiP7sSJ+Z8v4B5xw=",
"aarch64-darwin": "sha256-FFedoiPyfHGdzQnITz1SRV7xv2XoT9vzxIDp4EcVdkU=",
"x86_64-darwin": "sha256-0HiHkhJiN73UixUq5CC6YP6DkZzLar8lKnEL1aoiiHg="
}
}
+1
View File
@@ -31,6 +31,7 @@ stdenvNoCC.mkDerivation {
../package.json
../patches
../install # required by desktop build (cli.rs include_str!)
../.github/TEAM_MEMBERS # required by @opencode-ai/script
]
);
};
+20 -7
View File
@@ -4,11 +4,13 @@
"description": "AI-powered development tool",
"private": true,
"type": "module",
"packageManager": "bun@1.3.5",
"packageManager": "bun@1.3.11",
"scripts": {
"dev": "bun run --cwd packages/opencode --conditions=browser src/index.ts",
"dev:desktop": "bun --cwd packages/desktop tauri dev",
"dev:web": "bun --cwd packages/app dev",
"dev:console": "ulimit -n 10240 2>/dev/null; bun run --cwd packages/console/app dev",
"dev:storybook": "bun --cwd packages/storybook storybook",
"typecheck": "bun turbo typecheck",
"prepare": "husky",
"random": "echo 'Random script'",
@@ -23,7 +25,8 @@
"packages/slack"
],
"catalog": {
"@types/bun": "1.3.5",
"@effect/platform-node": "4.0.0-beta.35",
"@types/bun": "1.3.11",
"@octokit/rest": "22.0.0",
"@hono/zod-validator": "0.4.2",
"ulid": "3.0.1",
@@ -35,11 +38,14 @@
"@tsconfig/bun": "1.0.9",
"@cloudflare/workers-types": "4.20251008.0",
"@openauthjs/openauth": "0.0.0-20250322224806",
"@pierre/diffs": "1.1.0-beta.13",
"@pierre/diffs": "1.1.0-beta.18",
"@solid-primitives/storage": "4.3.3",
"@tailwindcss/vite": "4.1.11",
"diff": "8.0.2",
"dompurify": "3.3.1",
"drizzle-kit": "1.0.0-beta.19-d95b7a4",
"drizzle-orm": "1.0.0-beta.19-d95b7a4",
"effect": "4.0.0-beta.35",
"ai": "5.0.124",
"hono": "4.10.7",
"hono-openapi": "1.1.2",
@@ -67,11 +73,14 @@
"devDependencies": {
"@actions/artifact": "5.0.1",
"@tsconfig/bun": "catalog:",
"@types/mime-types": "3.0.1",
"@typescript/native-preview": "catalog:",
"glob": "13.0.5",
"husky": "9.1.7",
"prettier": "3.6.2",
"semver": "^7.6.0",
"sst": "3.17.23",
"turbo": "2.5.6"
"sst": "3.18.10",
"turbo": "2.8.13"
},
"dependencies": {
"@aws-sdk/client-s3": "3.933.0",
@@ -94,13 +103,17 @@
"protobufjs",
"tree-sitter",
"tree-sitter-bash",
"web-tree-sitter"
"web-tree-sitter",
"electron"
],
"overrides": {
"@types/bun": "catalog:",
"@types/node": "catalog:"
},
"patchedDependencies": {
"@standard-community/standard-openapi@0.2.9": "patches/@standard-community%2Fstandard-openapi@0.2.9.patch"
"@standard-community/standard-openapi@0.2.9": "patches/@standard-community%2Fstandard-openapi@0.2.9.patch",
"@openrouter/ai-sdk-provider@1.5.4": "patches/@openrouter%2Fai-sdk-provider@1.5.4.patch",
"@ai-sdk/xai@2.0.51": "patches/@ai-sdk%2Fxai@2.0.51.patch",
"solid-js@1.9.10": "patches/solid-js@1.9.10.patch"
}
}
@@ -0,0 +1,515 @@
# CreateEffect Simplification Implementation Spec
Reduce reactive misuse across `packages/app`.
---
## Context
This work targets `packages/app/src`, which currently has 101 `createEffect` calls across 37 files.
The biggest clusters are `pages/session.tsx` (19), `pages/layout.tsx` (13), `pages/session/file-tabs.tsx` (6), and several context providers that mirror one store into another.
Key issues from the audit:
- Derived state is being written through effects instead of computed directly
- Session and file resets are handled by watch-and-clear effects instead of keyed state boundaries
- User-driven actions are hidden inside reactive effects
- Context layers mirror and hydrate child stores with multiple sync effects
- Several areas repeat the same imperative trigger pattern in multiple effects
Keep the implementation focused on removing unnecessary effects, not on broad UI redesign.
## Goals
- Cut high-churn `createEffect` usage in the hottest files first
- Replace effect-driven derived state with reactive derivation
- Replace reset-on-key effects with keyed ownership boundaries
- Move event-driven work to direct actions and write paths
- Remove mirrored store hydration where a single source of truth can exist
- Leave necessary external sync effects in place, but make them narrower and clearer
## Non-Goals
- Do not rewrite unrelated component structure just to reduce the count
- Do not change product behavior, navigation flow, or persisted data shape unless required for a cleaner write boundary
- Do not remove effects that bridge to DOM, editors, polling, or external APIs unless there is a clearly safer equivalent
- Do not attempt a repo-wide cleanup outside `packages/app`
## Effect Taxonomy And Replacement Rules
Use these rules during implementation.
### Prefer `createMemo`
Use `createMemo` when the target value is pure derived state from other signals or stores.
Do this when an effect only reads reactive inputs and writes another reactive value that could be computed instead.
Apply this to:
- `packages/app/src/pages/session.tsx:141`
- `packages/app/src/pages/layout.tsx:557`
- `packages/app/src/components/terminal.tsx:261`
- `packages/app/src/components/session/session-header.tsx:309`
Rules:
- If no external system is touched, do not use `createEffect`
- Derive once, then read the memo where needed
- If normalization is required, prefer normalizing at the write boundary before falling back to a memo
### Prefer Keyed Remounts
Use keyed remounts when local UI state should reset because an identity changed.
Do this with `sessionKey`, `scope()`, or another stable identity instead of watching the key and manually clearing signals.
Apply this to:
- `packages/app/src/pages/session.tsx:325`
- `packages/app/src/pages/session.tsx:336`
- `packages/app/src/pages/session.tsx:477`
- `packages/app/src/pages/session.tsx:869`
- `packages/app/src/pages/session.tsx:963`
- `packages/app/src/pages/session/message-timeline.tsx:149`
- `packages/app/src/context/file.tsx:100`
Rules:
- If the desired behavior is "new identity, fresh local state," key the owner subtree
- Keep state local to the keyed boundary so teardown and recreation handle the reset naturally
### Prefer Event Handlers And Actions
Use direct handlers, store actions, and async command functions when work happens because a user clicked, selected, reloaded, or navigated.
Do this when an effect is just watching for a flag change, command token, or event-bus signal to trigger imperative logic.
Apply this to:
- `packages/app/src/pages/layout.tsx:484`
- `packages/app/src/pages/layout.tsx:652`
- `packages/app/src/pages/layout.tsx:776`
- `packages/app/src/pages/layout.tsx:1489`
- `packages/app/src/pages/layout.tsx:1519`
- `packages/app/src/components/file-tree.tsx:328`
- `packages/app/src/pages/session/terminal-panel.tsx:55`
- `packages/app/src/context/global-sync.tsx:148`
- Duplicated trigger sets in:
- `packages/app/src/pages/session/review-tab.tsx:122`
- `packages/app/src/pages/session/review-tab.tsx:130`
- `packages/app/src/pages/session/review-tab.tsx:138`
- `packages/app/src/pages/session/file-tabs.tsx:367`
- `packages/app/src/pages/session/file-tabs.tsx:378`
- `packages/app/src/pages/session/file-tabs.tsx:389`
- `packages/app/src/pages/session/use-session-hash-scroll.ts:144`
- `packages/app/src/pages/session/use-session-hash-scroll.ts:149`
- `packages/app/src/pages/session/use-session-hash-scroll.ts:167`
Rules:
- If the trigger is user intent, call the action at the source of that intent
- If the same imperative work is triggered from multiple places, extract one function and call it directly
### Prefer `onMount` And `onCleanup`
Use `onMount` and `onCleanup` for lifecycle-only setup and teardown.
This is the right fit for subscriptions, one-time wiring, timers, and imperative integration that should not rerun for ordinary reactive changes.
Use this when:
- Setup should happen once per owner lifecycle
- Cleanup should always pair with teardown
- The work is not conceptually derived state
### Keep `createEffect` When It Is A Real Bridge
Keep `createEffect` when it synchronizes reactive data to an external imperative sink.
Examples that should remain, though they may be narrowed or split:
- DOM/editor sync in `packages/app/src/components/prompt-input.tsx:690`
- Scroll sync in `packages/app/src/pages/session.tsx:685`
- Scroll/hash sync in `packages/app/src/pages/session/use-session-hash-scroll.ts:149`
- External sync in:
- `packages/app/src/context/language.tsx:207`
- `packages/app/src/context/settings.tsx:110`
- `packages/app/src/context/sdk.tsx:26`
- Polling in:
- `packages/app/src/components/status-popover.tsx:59`
- `packages/app/src/components/dialog-select-server.tsx:273`
Rules:
- Keep the effect single-purpose
- Make dependencies explicit and narrow
- Avoid writing back into the same reactive graph unless absolutely required
## Implementation Plan
### Phase 0: Classification Pass
Before changing code, tag each targeted effect as one of: derive, reset, event, lifecycle, or external bridge.
Acceptance criteria:
- Every targeted effect in this spec is tagged with a replacement strategy before refactoring starts
- Shared helpers to be introduced are identified up front to avoid repeating patterns
### Phase 1: Derived-State Cleanup
Tackle highest-value, lowest-risk derived-state cleanup first.
Priority items:
- Normalize tabs at write boundaries and remove `packages/app/src/pages/session.tsx:141`
- Stop syncing `workspaceOrder` in `packages/app/src/pages/layout.tsx:557`
- Make prompt slash filtering reactive so `packages/app/src/components/prompt-input.tsx:652` can be removed
- Replace other obvious derived-state effects in terminal and session header
Acceptance criteria:
- No behavior change in tab ordering, prompt filtering, terminal display, or header state
- Targeted derived-state effects are deleted, not just moved
### Phase 2: Keyed Reset Cleanup
Replace reset-on-key effects with keyed ownership boundaries.
Priority items:
- Key session-scoped UI and state by `sessionKey`
- Key file-scoped state by `scope()`
- Remove manual clear-and-reseed effects in session and file context
Acceptance criteria:
- Switching session or file scope recreates the intended local state cleanly
- No stale state leaks across session or scope changes
- Target reset effects are deleted
### Phase 3: Event-Driven Work Extraction
Move event-driven work out of reactive effects.
Priority items:
- Replace `globalStore.reload` effect dispatching with direct calls
- Split mixed-responsibility effect in `packages/app/src/pages/layout.tsx:1489`
- Collapse duplicated imperative trigger triplets into single functions
- Move file-tree and terminal-panel imperative work to explicit handlers
Acceptance criteria:
- User-triggered behavior still fires exactly once per intended action
- No effect remains whose only job is to notice a command-like state and trigger an imperative function
### Phase 4: Context Ownership Cleanup
Remove mirrored child-store hydration patterns.
Priority items:
- Remove child-store hydration mirrors in `packages/app/src/context/global-sync/child-store.ts:184`, `:190`, `:193`
- Simplify mirror logic in `packages/app/src/context/global-sync.tsx:130`, `:138`
- Revisit `packages/app/src/context/layout.tsx:424` if it still mirrors instead of deriving
Acceptance criteria:
- There is one clear source of truth for each synced value
- Child stores no longer need effect-based hydration to stay consistent
- Initialization and updates both work without manual mirror effects
### Phase 5: Cleanup And Keeper Review
Clean up remaining targeted hotspots and narrow the effects that should stay.
Acceptance criteria:
- Remaining `createEffect` calls in touched files are all true bridges or clearly justified lifecycle sync
- Mixed-responsibility effects are split into smaller units where still needed
## Detailed Work Items By Area
### 1. Normalize Tab State
Files:
- `packages/app/src/pages/session.tsx:141`
Work:
- Move tab normalization into the functions that create, load, or update tab state
- Make readers consume already-normalized tab data
- Remove the effect that rewrites derived tab state after the fact
Rationale:
- Tabs should become valid when written, not be repaired later
- This removes a feedback loop and makes state easier to trust
Acceptance criteria:
- The effect at `packages/app/src/pages/session.tsx:141` is removed
- Newly created and restored tabs are normalized before they enter local state
- Tab rendering still matches current behavior for valid and edge-case inputs
### 2. Key Session-Owned State
Files:
- `packages/app/src/pages/session.tsx:325`
- `packages/app/src/pages/session.tsx:336`
- `packages/app/src/pages/session.tsx:477`
- `packages/app/src/pages/session.tsx:869`
- `packages/app/src/pages/session.tsx:963`
- `packages/app/src/pages/session/message-timeline.tsx:149`
Work:
- Identify state that should reset when `sessionKey` changes
- Move that state under a keyed subtree or keyed owner boundary
- Remove effects that watch `sessionKey` just to clear local state, refs, or temporary UI flags
Rationale:
- Session identity already defines the lifetime of this UI state
- Keyed ownership makes reset behavior automatic and easier to reason about
Acceptance criteria:
- The targeted reset effects are removed
- Changing sessions resets only the intended session-local state
- Scroll and editor state that should persist are not accidentally reset
### 3. Derive Workspace Order
Files:
- `packages/app/src/pages/layout.tsx:557`
Work:
- Stop writing `workspaceOrder` from live workspace data in an effect
- Represent user overrides separately from live workspace data
- Compute effective order from current data plus overrides with a memo or pure helper
Rationale:
- Persisted user intent and live source data should not mirror each other through an effect
- A computed effective order avoids drift and racey resync behavior
Acceptance criteria:
- The effect at `packages/app/src/pages/layout.tsx:557` is removed
- Workspace order updates correctly when workspaces appear, disappear, or are reordered by the user
- User overrides persist without requiring a sync-back effect
### 4. Remove Child-Store Mirrors
Files:
- `packages/app/src/context/global-sync.tsx:130`
- `packages/app/src/context/global-sync.tsx:138`
- `packages/app/src/context/global-sync.tsx:148`
- `packages/app/src/context/global-sync/child-store.ts:184`
- `packages/app/src/context/global-sync/child-store.ts:190`
- `packages/app/src/context/global-sync/child-store.ts:193`
- `packages/app/src/context/layout.tsx:424`
Work:
- Trace the actual ownership of global and child store values
- Replace hydration and mirror effects with explicit initialization and direct updates
- Remove the `globalStore.reload` event-bus pattern and call the needed reload paths directly
Rationale:
- Mirrors make it hard to tell which state is authoritative
- Event-bus style state toggles hide control flow and create accidental reruns
Acceptance criteria:
- Child store hydration no longer depends on effect-based copying
- Reload work can be followed from the event source to the handler without a reactive relay
- State remains correct on first load, child creation, and subsequent updates
### 5. Key File-Scoped State
Files:
- `packages/app/src/context/file.tsx:100`
Work:
- Move file-scoped local state under a boundary keyed by `scope()`
- Remove any effect that watches `scope()` only to reset file-local state
Rationale:
- File scope changes are identity changes
- Keyed ownership gives a cleaner reset than manual clear logic
Acceptance criteria:
- The effect at `packages/app/src/context/file.tsx:100` is removed
- Switching scopes resets only scope-local state
- No previous-scope data appears after a scope change
### 6. Split Layout Side Effects
Files:
- `packages/app/src/pages/layout.tsx:1489`
- Related event-driven effects near `packages/app/src/pages/layout.tsx:484`, `:652`, `:776`, `:1519`
Work:
- Break the mixed-responsibility effect at `:1489` into direct actions and smaller bridge effects only where required
- Move user-triggered branches into the actual command or handler that causes them
- Remove any branch that only exists because one effect is handling unrelated concerns
Rationale:
- Mixed effects hide cause and make reruns hard to predict
- Smaller units reduce accidental coupling and make future cleanup safer
Acceptance criteria:
- The effect at `packages/app/src/pages/layout.tsx:1489` no longer mixes unrelated responsibilities
- Event-driven branches execute from direct handlers
- Remaining effects in this area each have one clear external sync purpose
### 7. Remove Duplicate Triggers
Files:
- `packages/app/src/pages/session/review-tab.tsx:122`
- `packages/app/src/pages/session/review-tab.tsx:130`
- `packages/app/src/pages/session/review-tab.tsx:138`
- `packages/app/src/pages/session/file-tabs.tsx:367`
- `packages/app/src/pages/session/file-tabs.tsx:378`
- `packages/app/src/pages/session/file-tabs.tsx:389`
- `packages/app/src/pages/session/use-session-hash-scroll.ts:144`
- `packages/app/src/pages/session/use-session-hash-scroll.ts:149`
- `packages/app/src/pages/session/use-session-hash-scroll.ts:167`
Work:
- Extract one explicit imperative function per behavior
- Call that function from each source event instead of replicating the same effect pattern multiple times
- Preserve the scroll-sync effect that is truly syncing with the DOM, but remove duplicate trigger scaffolding around it
Rationale:
- Duplicate triggers make it easy to miss a case or fire twice
- One named action is easier to test and reason about
Acceptance criteria:
- Repeated imperative effect triplets are collapsed into shared functions
- Scroll behavior still works, including hash-based navigation
- No duplicate firing is introduced
### 8. Make Prompt Filtering Reactive
Files:
- `packages/app/src/components/prompt-input.tsx:652`
- Keep `packages/app/src/components/prompt-input.tsx:690` as needed
Work:
- Convert slash filtering into a pure reactive derivation from the current input and candidate command list
- Keep only the editor or DOM bridge effect if it is still needed for imperative syncing
Rationale:
- Filtering is classic derived state
- It should not need an effect if it can be computed from current inputs
Acceptance criteria:
- The effect at `packages/app/src/components/prompt-input.tsx:652` is removed
- Filtered slash-command results update correctly as the input changes
- The editor sync effect at `:690` still behaves correctly
### 9. Clean Up Smaller Derived-State Cases
Files:
- `packages/app/src/components/terminal.tsx:261`
- `packages/app/src/components/session/session-header.tsx:309`
Work:
- Replace effect-written local state with memos or inline derivation
- Remove intermediate setters when the value can be computed directly
Rationale:
- These are low-risk wins that reinforce the same pattern
- They also help keep follow-up cleanup consistent
Acceptance criteria:
- Targeted effects are removed
- UI output remains unchanged under the same inputs
## Verification And Regression Checks
Run focused checks after each phase, not only at the end.
### Suggested Verification
- Switch between sessions rapidly and confirm local session UI resets only where intended
- Open, close, and reorder tabs and confirm order and normalization remain stable
- Change workspaces, reload workspace data, and verify effective ordering is correct
- Change file scope and confirm stale file state does not bleed across scopes
- Trigger layout actions that previously depended on effects and confirm they still fire once
- Use slash commands in the prompt and verify filtering updates as you type
- Test review tab, file tab, and hash-scroll flows for duplicate or missing triggers
- Verify global sync initialization, reload, and child-store creation paths
### Regression Checks
- No accidental infinite reruns
- No double-firing network or command actions
- No lost cleanup for listeners, timers, or scroll handlers
- No preserved stale state after identity changes
- No removed effect that was actually bridging to DOM or an external API
If available, add or update tests around pure helpers introduced during this cleanup.
Favor tests for derived ordering, normalization, and action extraction, since those are easiest to lock down.
## Definition Of Done
This work is done when all of the following are true:
- The highest-leverage targets in this spec are implemented
- Each removed effect has been replaced by a clearer pattern: memo, keyed boundary, direct action, or lifecycle hook
- The "should remain" effects still exist only where they serve a real external sync purpose
- Touched files have fewer mixed-responsibility effects and clearer ownership of state
- Manual verification covers session switching, file scope changes, workspace ordering, prompt filtering, and reload flows
- No behavior regressions are found in the targeted areas
A reduced raw `createEffect` count is helpful, but it is not the main success metric.
The main success metric is clearer ownership and fewer effect-driven state repairs.
## Risks And Rollout Notes
Main risks:
- Keyed remounts can reset too much if state boundaries are drawn too high
- Store mirror removal can break initialization order if ownership is not mapped first
- Moving event work out of effects can accidentally skip triggers that were previously implicit
Rollout notes:
- Land in small phases, with each phase keeping the app behaviorally stable
- Prefer isolated PRs by phase or by file cluster, especially for context-store changes
- Review each remaining effect in touched files and leave it only if it clearly bridges to something external
+54 -4
View File
@@ -70,7 +70,15 @@ test("test description", async ({ page, sdk, gotoSession }) => {
- `openSettings(page)` - Open settings dialog
- `closeDialog(page, dialog)` - Close any dialog
- `openSidebar(page)` / `closeSidebar(page)` - Toggle sidebar
- `waitTerminalReady(page, { term? })` - Wait for a mounted terminal to connect and finish rendering output
- `runTerminal(page, { cmd, token, term?, timeout? })` - Type into the terminal via the browser and wait for rendered output
- `withSession(sdk, title, callback)` - Create temp session
- `withProject(...)` - Create temp project/workspace
- `sessionIDFromUrl(url)` - Read session ID from URL
- `slugFromUrl(url)` - Read workspace slug from URL
- `waitSlug(page, skip?)` - Wait for resolved workspace slug
- `trackSession(sessionID, directory?)` - Register session for fixture cleanup
- `trackDirectory(directory)` - Register directory for fixture cleanup
- `clickListItem(container, filter)` - Click list item by key/text
**Selectors** (`selectors.ts`):
@@ -109,7 +117,7 @@ import { test, expect } from "@playwright/test"
### Error Handling
Tests should clean up after themselves:
Tests should clean up after themselves. Prefer fixture-managed cleanup:
```typescript
test("test with cleanup", async ({ page, sdk, gotoSession }) => {
@@ -120,6 +128,11 @@ test("test with cleanup", async ({ page, sdk, gotoSession }) => {
})
```
- Prefer `withSession(...)` for temp sessions
- In `withProject(...)` tests that create sessions or extra workspaces, call `trackSession(sessionID, directory?)` and `trackDirectory(directory)`
- This lets fixture teardown abort, wait for idle, and clean up safely under CI concurrency
- Avoid calling `sdk.session.delete(...)` directly
### Timeouts
Default: 60s per test, 10s per assertion. Override when needed:
@@ -156,14 +169,51 @@ await page.keyboard.press(`${modKey}+B`) // Toggle sidebar
await page.keyboard.press(`${modKey}+Comma`) // Open settings
```
### Terminal Tests
- In terminal tests, type through the browser. Do not write to the PTY through the SDK.
- Use `waitTerminalReady(page, { term? })` and `runTerminal(page, { cmd, token, term?, timeout? })` from `actions.ts`.
- These helpers use the fixture-enabled test-only terminal driver and wait for output after the terminal writer settles.
- After opening the terminal, use `waitTerminalFocusIdle(...)` before the next keyboard action when prompt focus or keyboard routing matters.
- This avoids racing terminal mount, focus handoff, and prompt readiness when the next step types or sends shortcuts.
- Avoid `waitForTimeout` and custom DOM or `data-*` readiness checks.
### Wait on state
- Never use wall-clock waits like `page.waitForTimeout(...)` to make a test pass
- Avoid race-prone flows that assume work is finished after an action
- Wait or poll on observable state with `expect(...)`, `expect.poll(...)`, or existing helpers
- Prefer locator assertions like `toBeVisible()`, `toHaveCount(0)`, and `toHaveAttribute(...)` for normal UI state, and reserve `expect.poll(...)` for probe, mock, or backend state
- Prefer semantic app state over transient DOM visibility when behavior depends on active selection, focus ownership, or async retry loops
- Do not treat a visible element as proof that the app will route the next action to it
- When fixing a flake, validate with `--repeat-each` and multiple workers when practical
### Add hooks
- If required state is not observable from the UI, add a small test-only driver or probe in app code instead of sleeps or fragile DOM checks
- Keep these hooks minimal and purpose-built, following the style of `packages/app/src/testing/terminal.ts`
- Test-only hooks must be inert unless explicitly enabled; do not add normal-runtime listeners, reactive subscriptions, or per-update allocations for e2e ceremony
- When mocking routes or APIs, expose explicit mock state and wait on that before asserting post-action UI
- Add minimal test-only probes for semantic state like the active list item or selected command when DOM intermediates are unstable
- Prefer probing committed app state over asserting on transient highlight, visibility, or animation states
### Prefer helpers
- Prefer fluent helpers and drivers when they make intent obvious and reduce locator-heavy noise
- Use direct locators when the interaction is simple and a helper would not add clarity
- Prefer helpers that both perform an action and verify the app consumed it
- Avoid composing helpers redundantly when one already includes the other or already waits for the resulting state
- If a helper already covers the required wait or verification, use it directly instead of layering extra clicks, keypresses, or assertions
## Writing New Tests
1. Choose appropriate folder or create new one
2. Import from `../fixtures`
3. Use helper functions from `../actions` and `../selectors`
4. Clean up any created resources
5. Use specific selectors (avoid CSS classes)
6. Test one feature per test file
4. When validating routing, use shared helpers from `../actions`. Workspace URL slugs can be canonicalized on Windows, so assert against canonical or resolved workspace slugs.
5. Clean up any created resources
6. Use specific selectors (avoid CSS classes)
7. Test one feature per test file
## Local Development
+653 -56
View File
@@ -1,24 +1,38 @@
import { base64Decode, base64Encode } from "@opencode-ai/util/encode"
import { expect, type Locator, type Page } from "@playwright/test"
import fs from "node:fs/promises"
import os from "node:os"
import path from "node:path"
import { execSync } from "node:child_process"
import { modKey, serverUrl } from "./utils"
import { terminalAttr, type E2EWindow } from "../src/testing/terminal"
import { createSdk, modKey, resolveDirectory, serverUrl } from "./utils"
import {
sessionItemSelector,
dropdownMenuTriggerSelector,
dropdownMenuContentSelector,
projectSwitchSelector,
projectMenuTriggerSelector,
projectCloseMenuSelector,
projectWorkspacesToggleSelector,
titlebarRightSelector,
popoverBodySelector,
listItemSelector,
listItemKeySelector,
listItemKeyStartsWithSelector,
promptSelector,
terminalSelector,
workspaceItemSelector,
workspaceMenuTriggerSelector,
} from "./selectors"
import type { createSdk } from "./utils"
const phase = new WeakMap<Page, "test" | "cleanup">()
export function setHealthPhase(page: Page, value: "test" | "cleanup") {
phase.set(page, value)
}
export function healthPhase(page: Page) {
return phase.get(page) ?? "test"
}
export async function defocus(page: Page) {
await page
@@ -29,9 +43,141 @@ export async function defocus(page: Page) {
.catch(() => undefined)
}
export async function openPalette(page: Page) {
async function terminalID(term: Locator) {
const id = await term.getAttribute(terminalAttr)
if (id) return id
throw new Error(`Active terminal missing ${terminalAttr}`)
}
export async function terminalConnects(page: Page, input?: { term?: Locator }) {
const term = input?.term ?? page.locator(terminalSelector).first()
const id = await terminalID(term)
return page.evaluate((id) => {
return (window as E2EWindow).__opencode_e2e?.terminal?.terminals?.[id]?.connects ?? 0
}, id)
}
export async function disconnectTerminal(page: Page, input?: { term?: Locator }) {
const term = input?.term ?? page.locator(terminalSelector).first()
const id = await terminalID(term)
await page.evaluate((id) => {
;(window as E2EWindow).__opencode_e2e?.terminal?.controls?.[id]?.disconnect?.()
}, id)
}
async function terminalReady(page: Page, term?: Locator) {
const next = term ?? page.locator(terminalSelector).first()
const id = await terminalID(next)
return page.evaluate((id) => {
const state = (window as E2EWindow).__opencode_e2e?.terminal?.terminals?.[id]
return !!state?.connected && (state.settled ?? 0) > 0
}, id)
}
async function terminalFocusIdle(page: Page, term?: Locator) {
const next = term ?? page.locator(terminalSelector).first()
const id = await terminalID(next)
return page.evaluate((id) => {
const state = (window as E2EWindow).__opencode_e2e?.terminal?.terminals?.[id]
return (state?.focusing ?? 0) === 0
}, id)
}
async function terminalHas(page: Page, input: { term?: Locator; token: string }) {
const next = input.term ?? page.locator(terminalSelector).first()
const id = await terminalID(next)
return page.evaluate(
(input) => {
const state = (window as E2EWindow).__opencode_e2e?.terminal?.terminals?.[input.id]
return state?.rendered.includes(input.token) ?? false
},
{ id, token: input.token },
)
}
async function promptSlashActive(page: Page, id: string) {
return page.evaluate((id) => {
const state = (window as E2EWindow).__opencode_e2e?.prompt?.current
if (state?.popover !== "slash") return false
if (!state.slash.ids.includes(id)) return false
return state.slash.active === id
}, id)
}
async function promptSlashSelects(page: Page) {
return page.evaluate(() => {
return (window as E2EWindow).__opencode_e2e?.prompt?.current?.selects ?? 0
})
}
async function promptSlashSelected(page: Page, input: { id: string; count: number }) {
return page.evaluate((input) => {
const state = (window as E2EWindow).__opencode_e2e?.prompt?.current
if (!state) return false
return state.selected === input.id && state.selects >= input.count
}, input)
}
export async function waitTerminalReady(page: Page, input?: { term?: Locator; timeout?: number }) {
const term = input?.term ?? page.locator(terminalSelector).first()
const timeout = input?.timeout ?? 10_000
await expect(term).toBeVisible()
await expect(term.locator("textarea")).toHaveCount(1)
await expect.poll(() => terminalReady(page, term), { timeout }).toBe(true)
}
export async function waitTerminalFocusIdle(page: Page, input?: { term?: Locator; timeout?: number }) {
const term = input?.term ?? page.locator(terminalSelector).first()
const timeout = input?.timeout ?? 10_000
await waitTerminalReady(page, { term, timeout })
await expect.poll(() => terminalFocusIdle(page, term), { timeout }).toBe(true)
}
export async function showPromptSlash(
page: Page,
input: { id: string; text: string; prompt?: Locator; timeout?: number },
) {
const prompt = input.prompt ?? page.locator(promptSelector)
const timeout = input.timeout ?? 10_000
await expect
.poll(
async () => {
await prompt.click().catch(() => false)
await prompt.fill(input.text).catch(() => false)
return promptSlashActive(page, input.id).catch(() => false)
},
{ timeout },
)
.toBe(true)
}
export async function runPromptSlash(
page: Page,
input: { id: string; text: string; prompt?: Locator; timeout?: number },
) {
const prompt = input.prompt ?? page.locator(promptSelector)
const timeout = input.timeout ?? 10_000
const count = await promptSlashSelects(page)
await showPromptSlash(page, input)
await prompt.press("Enter")
await expect.poll(() => promptSlashSelected(page, { id: input.id, count: count + 1 }), { timeout }).toBe(true)
}
export async function runTerminal(page: Page, input: { cmd: string; token: string; term?: Locator; timeout?: number }) {
const term = input.term ?? page.locator(terminalSelector).first()
const timeout = input.timeout ?? 10_000
await waitTerminalReady(page, { term, timeout })
const textarea = term.locator("textarea")
await term.click()
await expect(textarea).toBeFocused()
await page.keyboard.type(input.cmd)
await page.keyboard.press("Enter")
await expect.poll(() => terminalHas(page, { term, token: input.token }), { timeout }).toBe(true)
}
export async function openPalette(page: Page, key = "K") {
await defocus(page)
await page.keyboard.press(`${modKey}+P`)
await page.keyboard.press(`${modKey}+${key}`)
const dialog = page.getByRole("dialog")
await expect(dialog).toBeVisible()
@@ -61,9 +207,49 @@ export async function closeDialog(page: Page, dialog: Locator) {
}
export async function isSidebarClosed(page: Page) {
const main = page.locator("main")
const classes = (await main.getAttribute("class")) ?? ""
return classes.includes("xl:border-l")
const button = await waitSidebarButton(page, "isSidebarClosed")
return (await button.getAttribute("aria-expanded")) !== "true"
}
async function errorBoundaryText(page: Page) {
const title = page.getByRole("heading", { name: /something went wrong/i }).first()
if (!(await title.isVisible().catch(() => false))) return
const description = await page
.getByText(/an error occurred while loading the application\./i)
.first()
.textContent()
.catch(() => "")
const detail = await page
.getByRole("textbox", { name: /error details/i })
.first()
.inputValue()
.catch(async () =>
(
(await page
.getByRole("textbox", { name: /error details/i })
.first()
.textContent()
.catch(() => "")) ?? ""
).trim(),
)
return [title ? "Error boundary" : "", description ?? "", detail ?? ""].filter(Boolean).join("\n")
}
export async function assertHealthy(page: Page, context: string) {
const text = await errorBoundaryText(page)
if (!text) return
console.log(`[e2e:error-boundary][${context}]\n${text}`)
throw new Error(`Error boundary during ${context}\n${text}`)
}
async function waitSidebarButton(page: Page, context: string) {
const button = page.getByRole("button", { name: /toggle sidebar/i }).first()
const boundary = page.getByRole("heading", { name: /something went wrong/i }).first()
await button.or(boundary).first().waitFor({ state: "visible", timeout: 10_000 })
await assertHealthy(page, context)
return button
}
export async function toggleSidebar(page: Page) {
@@ -74,52 +260,39 @@ export async function toggleSidebar(page: Page) {
export async function openSidebar(page: Page) {
if (!(await isSidebarClosed(page))) return
const button = page.getByRole("button", { name: /toggle sidebar/i }).first()
const visible = await button
.isVisible()
.then((x) => x)
.catch(() => false)
const button = await waitSidebarButton(page, "openSidebar")
await button.click()
if (visible) await button.click()
if (!visible) await toggleSidebar(page)
const main = page.locator("main")
const opened = await expect(main)
.not.toHaveClass(/xl:border-l/, { timeout: 1500 })
const opened = await expect(button)
.toHaveAttribute("aria-expanded", "true", { timeout: 1500 })
.then(() => true)
.catch(() => false)
if (opened) return
await toggleSidebar(page)
await expect(main).not.toHaveClass(/xl:border-l/)
await expect(button).toHaveAttribute("aria-expanded", "true")
}
export async function closeSidebar(page: Page) {
if (await isSidebarClosed(page)) return
const button = page.getByRole("button", { name: /toggle sidebar/i }).first()
const visible = await button
.isVisible()
.then((x) => x)
.catch(() => false)
const button = await waitSidebarButton(page, "closeSidebar")
await button.click()
if (visible) await button.click()
if (!visible) await toggleSidebar(page)
const main = page.locator("main")
const closed = await expect(main)
.toHaveClass(/xl:border-l/, { timeout: 1500 })
const closed = await expect(button)
.toHaveAttribute("aria-expanded", "false", { timeout: 1500 })
.then(() => true)
.catch(() => false)
if (closed) return
await toggleSidebar(page)
await expect(main).toHaveClass(/xl:border-l/)
await expect(button).toHaveAttribute("aria-expanded", "false")
}
export async function openSettings(page: Page) {
await assertHealthy(page, "openSettings")
await defocus(page)
const dialog = page.getByRole("dialog")
@@ -132,6 +305,8 @@ export async function openSettings(page: Page) {
if (opened) return dialog
await assertHealthy(page, "openSettings")
await page.getByRole("button", { name: "Settings" }).first().click()
await expect(dialog).toBeVisible()
return dialog
@@ -193,21 +368,154 @@ export async function seedProjects(page: Page, input: { directory: string; extra
export async function createTestProject() {
const root = await fs.mkdtemp(path.join(os.tmpdir(), "opencode-e2e-project-"))
const id = `e2e-${path.basename(root)}`
await fs.writeFile(path.join(root, "README.md"), "# e2e\n")
await fs.writeFile(path.join(root, "README.md"), `# e2e\n\n${id}\n`)
execSync("git init", { cwd: root, stdio: "ignore" })
await fs.writeFile(path.join(root, ".git", "opencode"), id)
execSync("git config core.fsmonitor false", { cwd: root, stdio: "ignore" })
execSync("git add -A", { cwd: root, stdio: "ignore" })
execSync('git -c user.name="e2e" -c user.email="e2e@example.com" commit -m "init" --allow-empty', {
cwd: root,
stdio: "ignore",
})
return root
return resolveDirectory(root)
}
export async function cleanupTestProject(directory: string) {
await fs.rm(directory, { recursive: true, force: true }).catch(() => undefined)
try {
execSync("git fsmonitor--daemon stop", { cwd: directory, stdio: "ignore" })
} catch {}
await fs.rm(directory, { recursive: true, force: true, maxRetries: 5, retryDelay: 100 }).catch(() => undefined)
}
export function slugFromUrl(url: string) {
return /\/([^/]+)\/session(?:[/?#]|$)/.exec(url)?.[1] ?? ""
}
async function probeSession(page: Page) {
return page
.evaluate(() => {
const win = window as E2EWindow
const current = win.__opencode_e2e?.model?.current
if (!current) return null
return { dir: current.dir, sessionID: current.sessionID }
})
.catch(() => null as { dir?: string; sessionID?: string } | null)
}
export async function waitSlug(page: Page, skip: string[] = []) {
let prev = ""
let next = ""
await expect
.poll(
async () => {
await assertHealthy(page, "waitSlug")
const slug = slugFromUrl(page.url())
if (!slug) return ""
if (skip.includes(slug)) return ""
if (slug !== prev) {
prev = slug
next = ""
return ""
}
next = slug
return slug
},
{ timeout: 45_000 },
)
.not.toBe("")
return next
}
export async function resolveSlug(slug: string) {
const directory = base64Decode(slug)
if (!directory) throw new Error(`Failed to decode workspace slug: ${slug}`)
const resolved = await resolveDirectory(directory)
return { directory: resolved, slug: base64Encode(resolved), raw: slug }
}
export async function waitDir(page: Page, directory: string) {
const target = await resolveDirectory(directory)
await expect
.poll(
async () => {
await assertHealthy(page, "waitDir")
const slug = slugFromUrl(page.url())
if (!slug) return ""
return resolveSlug(slug)
.then((item) => item.directory)
.catch(() => "")
},
{ timeout: 45_000 },
)
.toBe(target)
return { directory: target, slug: base64Encode(target) }
}
export async function waitSession(page: Page, input: { directory: string; sessionID?: string }) {
const target = await resolveDirectory(input.directory)
await expect
.poll(
async () => {
await assertHealthy(page, "waitSession")
const slug = slugFromUrl(page.url())
if (!slug) return false
const resolved = await resolveSlug(slug).catch(() => undefined)
if (!resolved || resolved.directory !== target) return false
if (input.sessionID && sessionIDFromUrl(page.url()) !== input.sessionID) return false
const state = await probeSession(page)
if (input.sessionID && (!state || state.sessionID !== input.sessionID)) return false
if (state?.dir) {
const dir = await resolveDirectory(state.dir).catch(() => state.dir ?? "")
if (dir !== target) return false
}
return page
.locator(promptSelector)
.first()
.isVisible()
.catch(() => false)
},
{ timeout: 45_000 },
)
.toBe(true)
return { directory: target, slug: base64Encode(target) }
}
export async function waitSessionSaved(directory: string, sessionID: string, timeout = 30_000) {
const sdk = createSdk(directory)
const target = await resolveDirectory(directory)
await expect
.poll(
async () => {
const data = await sdk.session
.get({ sessionID })
.then((x) => x.data)
.catch(() => undefined)
if (!data?.directory) return ""
return resolveDirectory(data.directory).catch(() => data.directory)
},
{ timeout },
)
.toBe(target)
await expect
.poll(
async () => {
const items = await sdk.session
.messages({ sessionID, limit: 20 })
.then((x) => x.data ?? [])
.catch(() => [])
return items.some((item) => item.info.role === "user")
},
{ timeout },
)
.toBe(true)
}
export function sessionIDFromUrl(url: string) {
@@ -216,7 +524,7 @@ export function sessionIDFromUrl(url: string) {
}
export async function hoverSessionItem(page: Page, sessionID: string) {
const sessionEl = page.locator(sessionItemSelector(sessionID)).first()
const sessionEl = page.locator(`[data-session-id="${sessionID}"]`).last()
await expect(sessionEl).toBeVisible()
await sessionEl.hover()
return sessionEl
@@ -225,7 +533,7 @@ export async function hoverSessionItem(page: Page, sessionID: string) {
export async function openSessionMoreMenu(page: Page, sessionID: string) {
await expect(page).toHaveURL(new RegExp(`/session/${sessionID}(?:[/?#]|$)`))
const scroller = page.locator(".session-scroller").first()
const scroller = page.locator(".scroll-view__viewport").first()
await expect(scroller).toBeVisible()
await expect(scroller.getByRole("heading", { level: 1 }).first()).toBeVisible({ timeout: 30_000 })
@@ -317,6 +625,57 @@ export async function clickListItem(
return item
}
async function status(sdk: ReturnType<typeof createSdk>, sessionID: string) {
const data = await sdk.session
.status()
.then((x) => x.data ?? {})
.catch(() => undefined)
return data?.[sessionID]
}
async function stable(sdk: ReturnType<typeof createSdk>, sessionID: string, timeout = 10_000) {
let prev = ""
await expect
.poll(
async () => {
const info = await sdk.session
.get({ sessionID })
.then((x) => x.data)
.catch(() => undefined)
if (!info) return true
const next = `${info.title}:${info.time.updated ?? info.time.created}`
if (next !== prev) {
prev = next
return false
}
return true
},
{ timeout },
)
.toBe(true)
}
export async function waitSessionIdle(sdk: ReturnType<typeof createSdk>, sessionID: string, timeout = 30_000) {
await expect.poll(() => status(sdk, sessionID).then((x) => !x || x.type === "idle"), { timeout }).toBe(true)
}
export async function cleanupSession(input: {
sessionID: string
directory?: string
sdk?: ReturnType<typeof createSdk>
}) {
const sdk = input.sdk ?? (input.directory ? createSdk(input.directory) : undefined)
if (!sdk) throw new Error("cleanupSession requires sdk or directory")
await waitSessionIdle(sdk, input.sessionID, 5_000).catch(() => undefined)
const current = await status(sdk, input.sessionID).catch(() => undefined)
if (current && current.type !== "idle") {
await sdk.session.abort({ sessionID: input.sessionID }).catch(() => undefined)
await waitSessionIdle(sdk, input.sessionID).catch(() => undefined)
}
await stable(sdk, input.sessionID).catch(() => undefined)
await sdk.session.delete({ sessionID: input.sessionID }).catch(() => undefined)
}
export async function withSession<T>(
sdk: ReturnType<typeof createSdk>,
title: string,
@@ -328,10 +687,225 @@ export async function withSession<T>(
try {
return await callback(session)
} finally {
await sdk.session.delete({ sessionID: session.id }).catch(() => undefined)
await cleanupSession({ sdk, sessionID: session.id })
}
}
const seedSystem = [
"You are seeding deterministic e2e UI state.",
"Follow the user's instruction exactly.",
"When asked to call a tool, call exactly that tool exactly once with the exact JSON input.",
"Do not call any extra tools.",
].join(" ")
const wait = async <T>(input: { probe: () => Promise<T | undefined>; timeout?: number }) => {
const timeout = input.timeout ?? 30_000
const end = Date.now() + timeout
while (Date.now() < end) {
const value = await input.probe()
if (value !== undefined) return value
await new Promise((resolve) => setTimeout(resolve, 250))
}
}
const seed = async <T>(input: {
sessionID: string
prompt: string
sdk: ReturnType<typeof createSdk>
probe: () => Promise<T | undefined>
timeout?: number
attempts?: number
}) => {
for (let i = 0; i < (input.attempts ?? 2); i++) {
await input.sdk.session.promptAsync({
sessionID: input.sessionID,
agent: "build",
system: seedSystem,
parts: [{ type: "text", text: input.prompt }],
})
const value = await wait({ probe: input.probe, timeout: input.timeout })
if (value !== undefined) return value
}
}
export async function seedSessionQuestion(
sdk: ReturnType<typeof createSdk>,
input: {
sessionID: string
questions: Array<{
header: string
question: string
options: Array<{ label: string; description: string }>
multiple?: boolean
custom?: boolean
}>
},
) {
const first = input.questions[0]
if (!first) throw new Error("Question seed requires at least one question")
const text = [
"Your only valid response is one question tool call.",
`Use this JSON input: ${JSON.stringify({ questions: input.questions })}`,
"Do not output plain text.",
"After calling the tool, wait for the user response.",
].join("\n")
const result = await seed({
sdk,
sessionID: input.sessionID,
prompt: text,
timeout: 30_000,
probe: async () => {
const list = await sdk.question.list().then((x) => x.data ?? [])
return list.find((item) => item.sessionID === input.sessionID && item.questions[0]?.header === first.header)
},
})
if (!result) throw new Error("Timed out seeding question request")
return { id: result.id }
}
export async function seedSessionPermission(
sdk: ReturnType<typeof createSdk>,
input: {
sessionID: string
permission: string
patterns: string[]
description?: string
},
) {
const text = [
"Your only valid response is one bash tool call.",
`Use this JSON input: ${JSON.stringify({
command: input.patterns[0] ? `ls ${JSON.stringify(input.patterns[0])}` : "pwd",
workdir: "/",
description: input.description ?? `seed ${input.permission} permission request`,
})}`,
"Do not output plain text.",
].join("\n")
const result = await seed({
sdk,
sessionID: input.sessionID,
prompt: text,
timeout: 30_000,
probe: async () => {
const list = await sdk.permission.list().then((x) => x.data ?? [])
return list.find((item) => item.sessionID === input.sessionID)
},
})
if (!result) throw new Error("Timed out seeding permission request")
return { id: result.id }
}
export async function seedSessionTask(
sdk: ReturnType<typeof createSdk>,
input: {
sessionID: string
description: string
prompt: string
subagentType?: string
},
) {
const text = [
"Your only valid response is one task tool call.",
`Use this JSON input: ${JSON.stringify({
description: input.description,
prompt: input.prompt,
subagent_type: input.subagentType ?? "general",
})}`,
"Do not output plain text.",
"Wait for the task to start and return the child session id.",
].join("\n")
const result = await seed({
sdk,
sessionID: input.sessionID,
prompt: text,
timeout: 90_000,
probe: async () => {
const messages = await sdk.session.messages({ sessionID: input.sessionID, limit: 50 }).then((x) => x.data ?? [])
const part = messages
.flatMap((message) => message.parts)
.find((part) => {
if (part.type !== "tool" || part.tool !== "task") return false
if (!("state" in part) || !part.state || typeof part.state !== "object") return false
if (!("input" in part.state) || !part.state.input || typeof part.state.input !== "object") return false
if (!("description" in part.state.input) || part.state.input.description !== input.description) return false
if (!("metadata" in part.state) || !part.state.metadata || typeof part.state.metadata !== "object")
return false
if (!("sessionId" in part.state.metadata)) return false
return typeof part.state.metadata.sessionId === "string" && part.state.metadata.sessionId.length > 0
})
if (!part || !("state" in part) || !part.state || typeof part.state !== "object") return
if (!("metadata" in part.state) || !part.state.metadata || typeof part.state.metadata !== "object") return
if (!("sessionId" in part.state.metadata)) return
const id = part.state.metadata.sessionId
if (typeof id !== "string" || !id) return
const child = await sdk.session
.get({ sessionID: id })
.then((x) => x.data)
.catch(() => undefined)
if (!child?.id) return
return { sessionID: id }
},
})
if (!result) throw new Error("Timed out seeding task tool")
return result
}
export async function seedSessionTodos(
sdk: ReturnType<typeof createSdk>,
input: {
sessionID: string
todos: Array<{ content: string; status: string; priority: string }>
},
) {
const text = [
"Your only valid response is one todowrite tool call.",
`Use this JSON input: ${JSON.stringify({ todos: input.todos })}`,
"Do not output plain text.",
].join("\n")
const target = JSON.stringify(input.todos)
const result = await seed({
sdk,
sessionID: input.sessionID,
prompt: text,
timeout: 30_000,
probe: async () => {
const todos = await sdk.session.todo({ sessionID: input.sessionID }).then((x) => x.data ?? [])
if (JSON.stringify(todos) !== target) return
return true
},
})
if (!result) throw new Error("Timed out seeding todos")
return true
}
export async function clearSessionDockSeed(sdk: ReturnType<typeof createSdk>, sessionID: string) {
const [questions, permissions] = await Promise.all([
sdk.question.list().then((x) => x.data ?? []),
sdk.permission.list().then((x) => x.data ?? []),
])
await Promise.all([
...questions
.filter((item) => item.sessionID === sessionID)
.map((item) => sdk.question.reject({ requestID: item.id }).catch(() => undefined)),
...permissions
.filter((item) => item.sessionID === sessionID)
.map((item) => sdk.permission.reply({ requestID: item.id, reply: "reject" }).catch(() => undefined)),
])
return true
}
export async function openStatusPopover(page: Page) {
await defocus(page)
@@ -355,35 +929,51 @@ export async function openStatusPopover(page: Page) {
}
export async function openProjectMenu(page: Page, projectSlug: string) {
await openSidebar(page)
const item = page.locator(projectSwitchSelector(projectSlug)).first()
await expect(item).toBeVisible()
await item.hover()
const trigger = page.locator(projectMenuTriggerSelector(projectSlug)).first()
await expect(trigger).toHaveCount(1)
await expect(trigger).toBeVisible()
const menu = page
.locator(dropdownMenuContentSelector)
.filter({ has: page.locator(projectCloseMenuSelector(projectSlug)) })
.first()
const close = menu.locator(projectCloseMenuSelector(projectSlug)).first()
const clicked = await trigger
.click({ force: true, timeout: 1500 })
.then(() => true)
.catch(() => false)
if (clicked) {
const opened = await menu
.waitFor({ state: "visible", timeout: 1500 })
.then(() => true)
.catch(() => false)
if (opened) {
await expect(close).toBeVisible()
return menu
}
}
await trigger.focus()
await page.keyboard.press("Enter")
const menu = page.locator(dropdownMenuContentSelector).first()
const opened = await menu
.waitFor({ state: "visible", timeout: 1500 })
.then(() => true)
.catch(() => false)
if (opened) {
const viewport = page.viewportSize()
const x = viewport ? Math.max(viewport.width - 5, 0) : 1200
const y = viewport ? Math.max(viewport.height - 5, 0) : 800
await page.mouse.move(x, y)
await expect(close).toBeVisible()
return menu
}
await trigger.click({ force: true })
await expect(menu).toBeVisible()
const viewport = page.viewportSize()
const x = viewport ? Math.max(viewport.width - 5, 0) : 1200
const y = viewport ? Math.max(viewport.height - 5, 0) : 800
await page.mouse.move(x, y)
return menu
throw new Error(`Failed to open project menu: ${projectSlug}`)
}
export async function setWorkspacesEnabled(page: Page, projectSlug: string, enabled: boolean) {
@@ -396,11 +986,18 @@ export async function setWorkspacesEnabled(page: Page, projectSlug: string, enab
if (current === enabled) return
await openProjectMenu(page, projectSlug)
const flip = async (timeout?: number) => {
const menu = await openProjectMenu(page, projectSlug)
const toggle = menu.locator(projectWorkspacesToggleSelector(projectSlug)).first()
await expect(toggle).toBeVisible()
return toggle.click({ force: true, timeout })
}
const toggle = page.locator(projectWorkspacesToggleSelector(projectSlug)).first()
await expect(toggle).toBeVisible()
await toggle.click({ force: true })
const flipped = await flip(1500)
.then(() => true)
.catch(() => false)
if (!flipped) await flip()
const expected = enabled ? "New workspace" : "New session"
await expect(page.getByRole("button", { name: expected }).first()).toBeVisible()
+6 -3
View File
@@ -1,17 +1,20 @@
import { test, expect } from "../fixtures"
import { serverName } from "../utils"
import { serverNamePattern } from "../utils"
test("home renders and shows core entrypoints", async ({ page }) => {
await page.goto("/")
const nav = page.locator('[data-component="sidebar-nav-desktop"]')
await expect(page.getByRole("button", { name: "Open project" }).first()).toBeVisible()
await expect(page.getByRole("button", { name: serverName })).toBeVisible()
await expect(nav.getByText("No projects open")).toBeVisible()
await expect(nav.getByText("Open a project to get started")).toBeVisible()
await expect(page.getByRole("button", { name: serverNamePattern })).toBeVisible()
})
test("server picker dialog opens from home", async ({ page }) => {
await page.goto("/")
const trigger = page.getByRole("button", { name: serverName })
const trigger = page.getByRole("button", { name: serverNamePattern })
await expect(trigger).toBeVisible()
await trigger.click()
+10 -1
View File
@@ -1,5 +1,5 @@
import { test, expect } from "../fixtures"
import { openPalette } from "../actions"
import { closeDialog, openPalette } from "../actions"
test("search palette opens and closes", async ({ page, gotoSession }) => {
await gotoSession()
@@ -9,3 +9,12 @@ test("search palette opens and closes", async ({ page, gotoSession }) => {
await page.keyboard.press("Escape")
await expect(dialog).toHaveCount(0)
})
test("search palette also opens with cmd+p", async ({ page, gotoSession }) => {
await gotoSession()
const dialog = await openPalette(page, "P")
await closeDialog(page, dialog)
await expect(dialog).toHaveCount(0)
})
+11 -8
View File
@@ -1,6 +1,6 @@
import { test, expect } from "../fixtures"
import { serverName, serverUrl } from "../utils"
import { clickListItem, closeDialog, clickMenuItem } from "../actions"
import { serverNamePattern, serverUrls } from "../utils"
import { closeDialog, clickMenuItem } from "../actions"
const DEFAULT_SERVER_URL_KEY = "opencode.settings.dat:defaultServerUrl"
@@ -31,10 +31,9 @@ test("can set a default server on web", async ({ page, gotoSession }) => {
const dialog = page.getByRole("dialog")
await expect(dialog).toBeVisible()
const row = dialog.locator('[data-slot="list-item"]').filter({ hasText: serverName }).first()
await expect(row).toBeVisible()
await expect(dialog.getByText(serverNamePattern).first()).toBeVisible()
const menuTrigger = row.locator('[data-slot="dropdown-menu-trigger"]').first()
const menuTrigger = dialog.locator('[data-slot="dropdown-menu-trigger"]').first()
await expect(menuTrigger).toBeVisible()
await menuTrigger.click({ force: true })
@@ -42,14 +41,18 @@ test("can set a default server on web", async ({ page, gotoSession }) => {
await expect(menu).toBeVisible()
await clickMenuItem(menu, /set as default/i)
await expect.poll(() => page.evaluate((key) => localStorage.getItem(key), DEFAULT_SERVER_URL_KEY)).toBe(serverUrl)
await expect(row.getByText("Default", { exact: true })).toBeVisible()
await expect
.poll(async () =>
serverUrls.includes((await page.evaluate((key) => localStorage.getItem(key), DEFAULT_SERVER_URL_KEY)) ?? ""),
)
.toBe(true)
await expect(dialog.getByText("Default", { exact: true })).toBeVisible()
await closeDialog(page, dialog)
await ensurePopoverOpen()
const serverRow = popover.locator("button").filter({ hasText: serverName }).first()
const serverRow = popover.locator("button").filter({ hasText: serverNamePattern }).first()
await expect(serverRow).toBeVisible()
await expect(serverRow.getByText("Default", { exact: true })).toBeVisible()
})
@@ -16,7 +16,6 @@ test("titlebar back/forward navigates between sessions", async ({ page, slug, sd
const link = page.locator(`[data-session-id="${two.id}"] a`).first()
await expect(link).toBeVisible()
await link.scrollIntoViewIfNeeded()
await link.click()
await expect(page).toHaveURL(new RegExp(`/${slug}/session/${two.id}(?:\\?|#|$)`))
@@ -56,7 +55,6 @@ test("titlebar forward is cleared after branching history from sidebar", async (
const second = page.locator(`[data-session-id="${b.id}"] a`).first()
await expect(second).toBeVisible()
await second.scrollIntoViewIfNeeded()
await second.click()
await expect(page).toHaveURL(new RegExp(`/${slug}/session/${b.id}(?:\\?|#|$)`))
@@ -76,7 +74,6 @@ test("titlebar forward is cleared after branching history from sidebar", async (
const third = page.locator(`[data-session-id="${c.id}"] a`).first()
await expect(third).toBeVisible()
await third.scrollIntoViewIfNeeded()
await third.click()
await expect(page).toHaveURL(new RegExp(`/${slug}/session/${c.id}(?:\\?|#|$)`))
@@ -102,7 +99,6 @@ test("keyboard shortcuts navigate titlebar history", async ({ page, slug, sdk, g
const link = page.locator(`[data-session-id="${two.id}"] a`).first()
await expect(link).toBeVisible()
await link.scrollIntoViewIfNeeded()
await link.click()
await expect(page).toHaveURL(new RegExp(`/${slug}/session/${two.id}(?:\\?|#|$)`))
@@ -0,0 +1,15 @@
import { test, expect } from "../fixtures"
import { promptSelector } from "../selectors"
test("ctrl+l focuses the prompt", async ({ page, gotoSession }) => {
await gotoSession()
const prompt = page.locator(promptSelector)
await expect(prompt).toBeVisible()
await page.locator("main").click({ position: { x: 5, y: 5 } })
await expect(prompt).not.toBeFocused()
await page.keyboard.press("Control+L")
await expect(prompt).toBeFocused()
})
+33
View File
@@ -0,0 +1,33 @@
import { test, expect } from "../fixtures"
import { modKey } from "../utils"
const expanded = async (el: { getAttribute: (name: string) => Promise<string | null> }) => {
const value = await el.getAttribute("aria-expanded")
if (value !== "true" && value !== "false") throw new Error(`Expected aria-expanded to be true|false, got: ${value}`)
return value === "true"
}
test("review panel can be toggled via keybind", async ({ page, gotoSession }) => {
await gotoSession()
const reviewPanel = page.locator("#review-panel")
const treeToggle = page.getByRole("button", { name: "Toggle file tree" }).first()
await expect(treeToggle).toBeVisible()
if (await expanded(treeToggle)) await treeToggle.click()
await expect(treeToggle).toHaveAttribute("aria-expanded", "false")
const reviewToggle = page.getByRole("button", { name: "Toggle review" }).first()
await expect(reviewToggle).toBeVisible()
if (await expanded(reviewToggle)) await reviewToggle.click()
await expect(reviewToggle).toHaveAttribute("aria-expanded", "false")
await expect(reviewPanel).toHaveAttribute("aria-hidden", "true")
await page.keyboard.press(`${modKey}+Shift+R`)
await expect(reviewToggle).toHaveAttribute("aria-expanded", "true")
await expect(reviewPanel).toHaveAttribute("aria-hidden", "false")
await page.keyboard.press(`${modKey}+Shift+R`)
await expect(reviewToggle).toHaveAttribute("aria-expanded", "false")
await expect(reviewPanel).toHaveAttribute("aria-hidden", "true")
})
@@ -0,0 +1,32 @@
import { test, expect } from "../fixtures"
import { promptSelector } from "../selectors"
import { modKey } from "../utils"
test("mod+w closes the active file tab", async ({ page, gotoSession }) => {
await gotoSession()
await page.locator(promptSelector).click()
await page.keyboard.type("/open")
await expect(page.locator('[data-slash-id="file.open"]').first()).toBeVisible()
await page.keyboard.press("Enter")
const dialog = page
.getByRole("dialog")
.filter({ has: page.getByPlaceholder(/search files/i) })
.first()
await expect(dialog).toBeVisible()
await dialog.getByRole("textbox").first().fill("package.json")
const item = dialog.locator('[data-slot="list-item"][data-key^="file:"]').first()
await expect(item).toBeVisible({ timeout: 30_000 })
await item.click()
await expect(dialog).toHaveCount(0)
const tab = page.getByRole("tab", { name: "package.json" }).first()
await expect(tab).toBeVisible()
await tab.click()
await expect(tab).toHaveAttribute("aria-selected", "true")
await page.keyboard.press(`${modKey}+W`)
await expect(page.getByRole("tab", { name: "package.json" })).toHaveCount(0)
})
+10 -3
View File
@@ -43,7 +43,14 @@ test("file tree can expand folders and open a file", async ({ page, gotoSession
await tab.click()
await expect(tab).toHaveAttribute("aria-selected", "true")
const code = page.locator('[data-component="code"]').first()
await expect(code).toBeVisible()
await expect(code).toContainText("export default function FileTree")
await toggle.click()
await expect(toggle).toHaveAttribute("aria-expanded", "false")
await toggle.click()
await expect(toggle).toHaveAttribute("aria-expanded", "true")
await expect(allTab).toHaveAttribute("aria-selected", "true")
const viewer = page.locator('[data-component="file"][data-mode="text"]').first()
await expect(viewer).toBeVisible()
await expect(viewer).toContainText("export default function FileTree")
})
+110 -3
View File
@@ -1,5 +1,6 @@
import { test, expect } from "../fixtures"
import { promptSelector } from "../selectors"
import { modKey } from "../utils"
test("smoke file viewer renders real file content", async ({ page, gotoSession }) => {
await gotoSession()
@@ -43,7 +44,113 @@ test("smoke file viewer renders real file content", async ({ page, gotoSession }
await expect(tab).toBeVisible()
await tab.click()
const code = page.locator('[data-component="code"]').first()
await expect(code).toBeVisible()
await expect(code.getByText(/"name"\s*:\s*"@opencode-ai\/app"/)).toBeVisible()
const viewer = page.locator('[data-component="file"][data-mode="text"]').first()
await expect(viewer).toBeVisible()
await expect(viewer.getByText(/"name"\s*:\s*"@opencode-ai\/app"/)).toBeVisible()
})
test("cmd+f opens text viewer search while prompt is focused", async ({ page, gotoSession }) => {
await gotoSession()
await page.locator(promptSelector).click()
await page.keyboard.type("/open")
const command = page.locator('[data-slash-id="file.open"]').first()
await expect(command).toBeVisible()
await page.keyboard.press("Enter")
const dialog = page
.getByRole("dialog")
.filter({ has: page.getByPlaceholder(/search files/i) })
.first()
await expect(dialog).toBeVisible()
const input = dialog.getByRole("textbox").first()
await input.fill("package.json")
const items = dialog.locator('[data-slot="list-item"][data-key^="file:"]')
let index = -1
await expect
.poll(
async () => {
const keys = await items.evaluateAll((nodes) => nodes.map((node) => node.getAttribute("data-key") ?? ""))
index = keys.findIndex((key) => /packages[\\/]+app[\\/]+package\.json$/i.test(key.replace(/^file:/, "")))
return index >= 0
},
{ timeout: 30_000 },
)
.toBe(true)
const item = items.nth(index)
await expect(item).toBeVisible()
await item.click()
await expect(dialog).toHaveCount(0)
const tab = page.getByRole("tab", { name: "package.json" })
await expect(tab).toBeVisible()
await tab.click()
const viewer = page.locator('[data-component="file"][data-mode="text"]').first()
await expect(viewer).toBeVisible()
await page.locator(promptSelector).click()
await page.keyboard.press(`${modKey}+f`)
const findInput = page.getByPlaceholder("Find")
await expect(findInput).toBeVisible()
await expect(findInput).toBeFocused()
})
test("cmd+f opens text viewer search while prompt is not focused", async ({ page, gotoSession }) => {
await gotoSession()
await page.locator(promptSelector).click()
await page.keyboard.type("/open")
const command = page.locator('[data-slash-id="file.open"]').first()
await expect(command).toBeVisible()
await page.keyboard.press("Enter")
const dialog = page
.getByRole("dialog")
.filter({ has: page.getByPlaceholder(/search files/i) })
.first()
await expect(dialog).toBeVisible()
const input = dialog.getByRole("textbox").first()
await input.fill("package.json")
const items = dialog.locator('[data-slot="list-item"][data-key^="file:"]')
let index = -1
await expect
.poll(
async () => {
const keys = await items.evaluateAll((nodes) => nodes.map((node) => node.getAttribute("data-key") ?? ""))
index = keys.findIndex((key) => /packages[\\/]+app[\\/]+package\.json$/i.test(key.replace(/^file:/, "")))
return index >= 0
},
{ timeout: 30_000 },
)
.toBe(true)
const item = items.nth(index)
await expect(item).toBeVisible()
await item.click()
await expect(dialog).toHaveCount(0)
const tab = page.getByRole("tab", { name: "package.json" })
await expect(tab).toBeVisible()
await tab.click()
const viewer = page.locator('[data-component="file"][data-mode="text"]').first()
await expect(viewer).toBeVisible()
await viewer.click()
await page.keyboard.press(`${modKey}+f`)
const findInput = page.getByPlaceholder("Find")
await expect(findInput).toBeVisible()
await expect(findInput).toBeFocused()
})

Some files were not shown because too many files have changed in this diff Show More