Compare commits

...

1900 Commits

Author SHA1 Message Date
opencode bb14a955a0 release: v0.4.22 2025-08-12 01:07:27 +00:00
Dax Raad dac1506680 update anthropic prompt and variables 2025-08-11 21:01:33 -04:00
opencode 3946a08f40 release: v0.4.21 2025-08-12 00:30:49 +00:00
adamdotdevin ee0519aacc feat: add clangd for cpp 2025-08-11 19:21:59 -05:00
adamdotdevin dec1e3fdda fix: complete item on space 2025-08-11 18:58:42 -05:00
Carl Brugger f54e900716 Fix plugin file name (#1837) 2025-08-11 23:43:43 +00:00
opencode 7e8b5749fa release: v0.4.20 2025-08-11 23:43:43 +00:00
adamdotdevin febf902dc4 Revert "feat: improve file attachment pasting (#1704)"
This reverts commit 81a3e02474.
2025-08-11 18:37:34 -05:00
Jay V 04b51f2610 ignore: share page thinking blocks 2025-08-11 19:36:34 -04:00
Aiden Cline b2a4f57d64 feat: add -c and -s args to tui command following run command pattern (#1835) 2025-08-11 18:32:09 -05:00
Dax Raad 0ce7d92a8b ignore: fix share page 2025-08-11 16:12:26 -04:00
adamdotdevin 7a67fe7dde fix: collapsed tool calls hidden at times 2025-08-11 13:54:58 -05:00
Aiden Cline 00b4670b8b docs: fix instructions (#1827) 2025-08-11 13:44:12 -05:00
Dax Raad 7633a951e6 ignore: test 2025-08-11 14:43:42 -04:00
adamdotdevin 4ff64c6209 fix: take up less vertical space 2025-08-11 13:38:39 -05:00
Dax Raad 22023fa9e7 remove git bash tool coauthor message 2025-08-11 18:36:06 +00:00
opencode 85e0b53c33 release: v0.4.19 2025-08-11 18:36:06 +00:00
Dax Raad 6eaa231587 Update GPT-5 system prompt to use copilot-specific prompt instead of codex prompt
🤖 Generated with [opencode](https://opencode.ai)

Co-Authored-By: opencode <noreply@opencode.ai>
2025-08-11 14:28:49 -04:00
Jay V befb7509de docs: share 2025-08-11 14:19:22 -04:00
Jay V 09bf0b86d8 docs: share page 2025-08-11 14:01:20 -04:00
Jay V b5d45fa9f5 docs: share page 2025-08-11 13:57:41 -04:00
Jay V a6a633d5c1 docs: test share 2025-08-11 13:45:55 -04:00
Jay V e83e8001da docs: test share 2025-08-11 13:38:03 -04:00
Jay V 0386898476 docs: comment out thinking blocks for share page 2025-08-11 13:21:59 -04:00
adamdotdevin 5e777fd2a2 feat: toggle tool details visible 2025-08-11 11:58:46 -05:00
adamdotdevin 3c71fda648 fix: don't display placeholder on error 2025-08-11 11:58:46 -05:00
Jay V 42329a038a docs: share page fix 2025-08-11 12:51:19 -04:00
Jay V 10f3983f0b docs: edits 2025-08-11 12:41:13 -04:00
opencode e9de7f95a7 release: v0.4.18 2025-08-11 16:04:07 +00:00
adamdotdevin a4113acd15 fix: assistant message footer styles 2025-08-11 10:57:18 -05:00
adamdotdevin 9c8e56fc96 fix: assistant message footer styles 2025-08-11 10:52:49 -05:00
adamdotdevin c78cb57c41 fix: assistant message footer styles 2025-08-11 10:50:00 -05:00
opencode eb15b2ba75 release: v0.4.17 2025-08-11 15:15:24 +00:00
Dax Raad 279edb6f24 fix azure gpt config 2025-08-11 10:56:16 -04:00
Dax Raad c51a34bf4b make models key optional in config 2025-08-11 10:54:14 -04:00
adamdotdevin e8d144d2a2 fix: reformat assistant message footer 2025-08-11 09:38:52 -05:00
adamdotdevin a760e8364f feat: placeholder on pending assistant message 2025-08-11 09:29:44 -05:00
adamdotdevin fa7cae59c0 fix: re-render messages on session error 2025-08-11 09:19:45 -05:00
spoons-and-mirrors 8780fa6ccf Fix: Respect agent's preferred model at TUI startup (#1683)
Co-authored-by: opencode <noreply@opencode.ai>
2025-08-11 08:51:35 -05:00
spoons-and-mirrors ab2df0ae33 Feat: Implement Wrap-Around Navigation for List Selection (for Models and Tools modal) (#1768) 2025-08-11 08:47:51 -05:00
Timo Clasen 23757f3ac0 fix: only load the first local and global rule file (#1761) 2025-08-11 08:28:03 -05:00
Aiden Cline df7296cfe1 fix: instructions should be able to handle absolute paths (#1762) 2025-08-11 08:23:41 -05:00
opencode 776276d5a4 release: v0.4.16 2025-08-11 12:59:20 +00:00
Dax Raad eea45a22fa ci: tweak 2025-08-11 08:54:14 -04:00
opencode ddacb04f99 release: v0.4.15 2025-08-11 12:49:52 +00:00
GitHub Action 09561254a8 ignore: update download stats 2025-08-11 2025-08-11 12:04:33 +00:00
spoons-and-mirrors 73a8356b10 Feat: Add F2 Keybind to Cycle Through the 5 Most Recent Models (#1778) 2025-08-11 07:00:32 -05:00
cvzakharchenko 8db75266d0 Issue 1676: Don't eat up the last newline in a multi-line replacement (#1777) 2025-08-11 06:55:45 -05:00
Jake 6c30565d40 Add support for biome.jsonc config file (#1791) 2025-08-11 06:48:46 -05:00
spoons-and-mirrors b223a29603 Fix: Sanitize MCP Tool Names for Consistency in User Expectations (#1769) 2025-08-11 01:59:50 -04:00
Stibbs 8ed72ae087 chore: add OPENCODE env var (#1780) 2025-08-11 01:56:42 -04:00
Aiden Cline 62b8c7aee0 feat (tui): agents dialog (#1802) 2025-08-11 01:46:38 -04:00
Dax Raad 6145dfcca0 fix run command to be less messy 2025-08-11 01:45:05 -04:00
opencode 4580c88c0b release: v0.4.12 2025-08-11 05:28:22 +00:00
Dax Raad 061ba65d20 show combined output of bash tool progressively 2025-08-11 01:23:00 -04:00
Dax Raad 457386ad08 fix plan mode bash tool making changes 2025-08-11 01:15:12 -04:00
opencode fce04dc48b release: v0.4.11 2025-08-11 02:30:21 +00:00
Dax Raad 81534ab387 ci: tweaks 2025-08-10 22:23:59 -04:00
Aiden Cline 409a6f93b2 fix: enforce field requirement for cli cmds (#1796) 2025-08-10 22:17:12 -04:00
opencode 55c294c013 release: v0.4.6 2025-08-11 01:59:27 +00:00
Dax Raad 70db372466 add OPENCODE_DISABLE_AUTOUPDATE flag 2025-08-10 21:52:52 -04:00
Dax Raad 8cc427daba docs: docs agent 2025-08-10 21:40:49 -04:00
Dax Raad 8fde772957 ci: smoke test 2025-08-10 21:37:48 -04:00
Dax Raad d8dc23bde9 pass through additional agent options to the provider 2025-08-10 21:34:46 -04:00
Tom 1c83ef75a2 fix(plugin): prevent compiled binary hang by removing lazy dynamic import (#1794)
Co-authored-by: opencode <noreply@opencode.ai>
2025-08-10 21:31:15 -04:00
opencode 95e410db88 release: v0.4.3 2025-08-11 00:53:06 +00:00
Dax Raad 13d3fba86b switch gpt-5 to codex prompt 2025-08-10 20:47:38 -04:00
Dax Raad 3ab4f42ebb support agent options 2025-08-10 20:30:37 -04:00
adamdotdevin b8d2aebf09 feat: thinking blocks rendered in tui and share page 2025-08-10 19:25:03 -05:00
Frank 20e818ad05 wip gateway 2025-08-10 12:30:52 -04:00
Aiden Cline 542186aa49 feat: webfetch permission support (#1772) 2025-08-10 08:00:44 -05:00
GitHub Action c478d1bdbb ignore: update download stats 2025-08-10 2025-08-10 12:04:14 +00:00
Frank 7fd2222976 wip: gateway 2025-08-10 01:17:48 -04:00
Frank e86adb2ec8 wip: gateway 2025-08-10 01:03:15 -04:00
Frank 34ac0e895d wip: gateway 2025-08-10 00:29:00 -04:00
spoons-and-mirrors bd4319f2bc Feat: Add Agent Name in the LLM Response Footer (and re-order it) (#1770) 2025-08-09 20:22:16 -05:00
Frank 696ab1a752 Update moonshot ai provider doc 2025-08-09 19:22:50 -04:00
Dax Raad d3ff66e911 use minimal reasoning effort for gpt-5 2025-08-09 15:38:48 -04:00
Aiden Cline 1954b59167 feat: eslint lsp (#1744) 2025-08-09 11:04:58 -05:00
Aiden Cline e2fac991dc better permissions ux when denying (#1747) 2025-08-09 11:03:33 -05:00
GitHub Action 8ba35eadd4 ignore: update download stats 2025-08-09 2025-08-09 12:04:16 +00:00
Frank 7446f5ad7b wip gateway 2025-08-09 01:28:27 -04:00
Dominik Engelhardt 81a3e02474 feat: improve file attachment pasting (#1704) 2025-08-08 20:06:38 -05:00
Dax Raad 7bbc643600 remove synthetic message in plan mode, fixes being confused in build mode 2025-08-08 20:45:24 -04:00
Dax Raad 53630ebdce gpt-5 lower verbosity 2025-08-08 20:42:22 -04:00
Dax 85eaa5b58b Remove unused OpenTelemetry tracing and fix overlapping highlights (#1738)
Co-authored-by: opencode <noreply@opencode.ai>
2025-08-08 20:20:01 -04:00
Erick Christian b789844b9c feat(agent): allow mode selection during creation (#1699) 2025-08-08 20:07:20 -04:00
Clayton 9b6ef074f0 Reference the actual name of the windows package (#1700) 2025-08-08 20:07:00 -04:00
zWing 2f4291672b chore(js-sdk): Compatible with nodenext (#1667) 2025-08-08 20:05:50 -04:00
rmoriz 83f4e8e156 Clarify remote mcp error (#1729)
Co-authored-by: opencode <noreply@opencode.ai>
2025-08-08 20:04:26 -04:00
gsbain 7af2771a7e Docs: Homebrew can install Opencode on Linux (#1737) 2025-08-08 20:04:02 -04:00
Frank c9a3b35ac2 fix deploy 2025-08-08 18:39:47 -04:00
Frank 0dde6d0840 fix deploy script 2025-08-08 17:59:21 -04:00
Max Pod d1208bf0a1 docs: Update plugins.mdx (#1690) 2025-08-08 17:11:06 -04:00
Typing Turtle 0a9463541a docs: Adds required models field to variables documentation (#1709) 2025-08-08 16:57:31 -04:00
Yihui Khuu fe26b4a7b1 fix(tui): preserve scroll position when reflowing due to message stream (#1716) 2025-08-08 13:14:09 -05:00
Frank 8c173e18b7 wip: gateway 2025-08-08 13:24:50 -04:00
Frank 183e0911b7 wip: gateway 2025-08-08 13:24:32 -04:00
GitHub Action c7bb19ad07 ignore: update download stats 2025-08-08 2025-08-08 12:04:40 +00:00
Timo Clasen e444d15b57 fix(TUI): enable general (sub-) agent for @ referencing (#1705) 2025-08-08 05:36:55 -05:00
opencode 063d67a046 release: v0.4.1 2025-08-08 03:01:03 +00:00
Dax Raad 4f164c53d2 temporary fix for max output token 2025-08-07 22:54:59 -04:00
Dax Raad 02ef96f89b docs: fix 2025-08-07 21:49:18 -04:00
Dax Raad 8750744068 renable todo tool 2025-08-07 21:47:37 -04:00
Dax Raad 3e74107e36 looser todo tool schema 2025-08-07 21:47:37 -04:00
Jay V 160f839b25 docs: update cli 2025-08-07 19:24:08 -04:00
Jay V bf5b109c1f docs: edit agent doc 2025-08-07 18:51:54 -04:00
Dax Raad 60254d8ac0 docs: remove modes from sidebar navigation
🤖 Generated with [opencode](https://opencode.ai)

Co-Authored-By: opencode <noreply@opencode.ai>
2025-08-07 16:35:35 -04:00
Dax c34aec060f Merge agent and mode into one (#1689)
The concept of mode has been deprecated, there is now only the agent field in the config.

An agent can be cycled through as your primary agent with <tab> or you can spawn a subagent by @ mentioning it. if you include a description of when to use it, the primary agent will try to automatically use it

Full docs here: https://opencode.ai/docs/agents/
2025-08-07 16:32:12 -04:00
Jay V 12f1ad521f docs: slash commands 2025-08-07 16:16:16 -04:00
Timo Clasen 723a37ea9a fix: get session api (#1684) 2025-08-07 15:28:18 -04:00
Aiden Cline c6a46615c0 fix: modal pastes (#1677) 2025-08-07 13:23:58 -05:00
GitHub Action da29380093 ignore: update download stats 2025-08-07 2025-08-07 12:04:29 +00:00
Aiden Cline 7950ae1462 fix: text selection bug (#1664) 2025-08-07 05:32:34 -05:00
opencode 15e830410f release: v0.3.133 2025-08-07 00:30:05 +00:00
Dax Raad 1a561bb512 add api to get session 2025-08-06 20:24:36 -04:00
Jay V fecae609d9 docs: config doc edits 2025-08-06 16:10:17 -04:00
Jay V e01a540b08 docs: typos 2025-08-06 15:45:16 -04:00
Timo Clasen 54457e48bb fix(docs): small_model is not used for summarization (#1360) 2025-08-06 14:03:14 -05:00
Aiden Cline b179d08484 fix: interface conversion panic (#1655) 2025-08-06 14:02:33 -05:00
Jay V d9edd6818f docs: add undo to tutorial 2025-08-06 13:51:47 -04:00
Dax Raad 4217286b72 ignore: remove demo plugin 2025-08-06 11:36:53 -04:00
Dax Raad 28a4517ec6 add snapshot field in config to disable snapshots 2025-08-06 11:35:37 -04:00
Aiden Cline b00b2ded4f docs: update readme (#1654) 2025-08-06 09:35:02 -05:00
Aiden Cline 7b6d5b1429 chore: update marked-shiki, remove patch (#1653) 2025-08-06 08:47:53 -05:00
GitHub Action 7210db19e9 ignore: update download stats 2025-08-06 2025-08-06 12:04:53 +00:00
Yihui Khuu 90d2b26426 fix: run command should use specified model from cli args if provided (#1648) 2025-08-06 05:39:44 -05:00
Aiden Cline 6beba2c04f docs: document permissions (#1638) 2025-08-06 05:18:08 -05:00
Aiden Cline b8a0ecca98 fix: highlight after text wrap (#1640) 2025-08-06 05:17:35 -05:00
Aiden Cline ad10d3a126 fix: handle undefined agent in task tool (#1642) 2025-08-06 05:16:43 -05:00
Aiden Cline a48274f82b permissions disallow support (#1627) 2025-08-05 19:14:28 -05:00
adamdotdevin 6b25b7e95e feat: better assistant message visual 2025-08-05 19:05:44 -05:00
Jay V 030a3a7446 docs: identity 2025-08-05 19:36:10 -04:00
Timo Clasen 1a0e7f1e63 docs(plugins): fix typo (#1621) 2025-08-05 17:16:47 -05:00
Aiden Cline 677fb6032b fix: markdown table renders (#1623) 2025-08-05 17:16:35 -05:00
Timo Clasen 49aa48ce58 fix: prevent title regeneration on auto compact (#1628) 2025-08-05 17:15:50 -05:00
Dax Raad 857a3cd522 hint back to llm when tool does not exist 2025-08-05 15:58:12 -04:00
Jay V 6ed774ef62 docs: edit 2025-08-05 12:55:57 -04:00
adamdotdevin 5e825a4b6a chore: cleanup old sdk 2025-08-05 11:46:12 -05:00
Dax Raad 3db8e7c2b6 ci: send stats to posthog 2025-08-05 12:01:48 -04:00
GitHub Action b459055757 ignore: update download stats 2025-08-05 2025-08-05 12:04:48 +00:00
Yihui Khuu 2b195e82ee fix: allow disabling the default general agent (#1616) 2025-08-05 05:20:00 -05:00
Omar Shaarawi 58e889796c validate file part bounds to prevent panic (#1612) 2025-08-05 05:18:50 -05:00
Aiden Cline 51498c8de4 docs: make formatter docs a bit more clear (#1613) 2025-08-05 05:17:56 -05:00
Aiden Cline 7a495faa49 fix: server.root is not a function (#1614) 2025-08-05 05:17:32 -05:00
Timo Clasen 4957fca718 fix(plugins): improve session idle event (#1615) 2025-08-05 05:16:43 -05:00
opencode 8168626cd3 release: v0.3.130 2025-08-05 03:25:28 +00:00
Dax Raad b824809605 re-export shell $ for plugin 2025-08-04 23:20:04 -04:00
opencode 5536b14347 release: v0.3.129 2025-08-05 01:18:50 +00:00
Dax Raad 01efe236ef fix @opencode-ai/plugin exports 2025-08-04 21:12:18 -04:00
Frank 7a1f96399d sync 2025-08-04 21:09:44 -04:00
Frank 40036abb9d wip: gateway 2025-08-04 21:08:29 -04:00
Jay V 2970ba6416 docs: lock 2025-08-04 19:53:50 -04:00
Jay V 81412b6197 docs: edit new docs 2025-08-04 19:52:03 -04:00
Mahamed-Belkheir 5bf7691ea6 fix: default value for models with no cost object (#1601) 2025-08-04 16:45:35 -05:00
Min Chun Fu b1055a74d3 added vesper theme (#1602) 2025-08-04 16:45:00 -05:00
Aiden Cline ffcb27fa9a docs: make plugins page exposed (#1603) 2025-08-04 16:44:28 -05:00
opencode 38819e89b8 release: v0.3.128 2025-08-04 16:20:39 +00:00
Dax Raad 0a42068fbb hack to return tool call errors back to model 2025-08-04 12:15:24 -04:00
opencode b05decc572 release: v0.3.127 2025-08-04 16:06:13 +00:00
GitHub Action c2f487906a ignore: update download stats 2025-08-04 2025-08-04 12:04:34 +00:00
Aiden Cline ae78ec7a0c fix double help printing (#1580) 2025-08-04 05:03:27 -05:00
Frank e8c03f13dd fix docs 2025-08-04 00:23:02 -04:00
Dax Raad f85d30c484 wip: plugins 2025-08-03 21:43:58 -04:00
Dax Raad 1bac46612c wip: plugin load from package 2025-08-03 21:19:03 -04:00
Dax Raad 9ab3462821 Add workflow_dispatch trigger to typecheck workflow 2025-08-03 17:16:20 -04:00
Aiden Cline 3b36822696 fix: patch marked-shiki (#1569) 2025-08-03 16:13:35 -05:00
Dax Raad 5b731479d5 Add typecheck workflow 2025-08-03 17:12:23 -04:00
Dax Raad a50bef6913 ignore: cleanup 2025-08-03 17:09:30 -04:00
Yordis Prieto ed397c5057 chore: add ts-expected-error (#1575) 2025-08-03 17:09:19 -04:00
Yordis Prieto c9187a9f3a chore: remove unnecessary TypeScript error suppression (#1571) 2025-08-03 15:50:08 -04:00
opencode 2c67b26b5d release: v0.3.126 2025-08-03 19:45:14 +00:00
Dax Raad 170b94a99e ci: ignore 2025-08-03 15:39:34 -04:00
Dax Raad cd58f10e3c ci: ignore 2025-08-03 15:38:39 -04:00
Dax Raad ea85fdf3cd fix bash tool not showing stderr 2025-08-03 15:34:52 -04:00
Aiden Cline edda26ab33 tweak: filter out duplicate instructions (#1567) 2025-08-03 15:10:21 -04:00
Dax Raad ea4e1913c0 increase models.dev polling interval to hourly 2025-08-03 14:58:35 -04:00
Aiden Cline 5eebc8ab51 docs: fix mixed up documentation (#1564) 2025-08-03 13:01:09 -05:00
Dax Raad 21c52fd5cb fix bash tool getting stuck on interactive commands 2025-08-03 13:52:50 -04:00
opencode 5e8634afaf release: v0.3.123 2025-08-03 17:13:33 +00:00
Dax Raad d4bac5cdbd ci: ignore 2025-08-03 13:12:35 -04:00
opencode 263b266476 release: v0.3.122 2025-08-03 16:19:09 +00:00
Dax Raad 06830327e7 more efficient snapshots in parallel toolcalls 2025-08-03 12:12:28 -04:00
Giuseppe Rota 4b204fee58 fix(docs): move disabled providers paragraph to its proper section (#1547) 2025-08-03 11:28:57 -04:00
Dax Raad 99d3a0bb24 more fixes for shell 128 error 2025-08-03 11:25:58 -04:00
opencode 0930f6ac55 release: v0.3.120 2025-08-03 14:59:03 +00:00
Dax Raad 24515162fa ci: ignore 2025-08-03 10:52:35 -04:00
Dax Raad 53aa899e45 ci: ignore 2025-08-03 10:42:52 -04:00
Dax Raad 7e763e1c06 fix shell error 128 2025-08-03 10:30:23 -04:00
GitHub Action b0f2cc0c22 ignore: update download stats 2025-08-03 2025-08-03 12:04:04 +00:00
Aiden Cline f90aa62784 fix: expand tilde for file: references (#1553) 2025-08-03 06:15:06 -05:00
Dax Raad 852191f6cb ci: ignore 2025-08-03 03:54:17 -04:00
Dax Raad c5e9dc081c ci: bun cache 2025-08-03 03:53:31 -04:00
Dax Raad 49c8889228 ci: ignore 2025-08-03 03:45:05 -04:00
Dax Raad f739e1a958 ci: ignore 2025-08-03 03:37:53 -04:00
Dax Raad 841f1907bb ci: ignore 2025-08-03 03:35:17 -04:00
The Pangolier 9255c507d6 Share link hotfix (#1513) 2025-08-03 03:02:24 -04:00
Yordis Prieto 2711047166 remove: delete extension test file (#1554) 2025-08-03 02:58:10 -04:00
Frank 908048baef sync 2025-08-02 21:28:03 -04:00
Frank a9fbe07408 Add Zhipu AI provider 2025-08-02 21:20:44 -04:00
Dax Raad 0ae213ee0e ci: ignore 2025-08-02 18:56:34 -04:00
Dax Raad ca031278ca wip: plugins 2025-08-02 18:50:19 -04:00
Aiden Cline ae6e47bb42 tweak: make gh action ignore url mentions of opencode (#1531) 2025-08-02 09:31:23 -05:00
Dominik Engelhardt 42a5fcead4 Choose model according to the docs (#1536) 2025-08-02 09:29:03 -05:00
Yihui Khuu 8ad83f71a9 fix(tui): attachment highlighting issues in messages (#1534) 2025-08-02 09:26:44 -05:00
Yihui Khuu fa95c09cdc fix(tui): attachment source is not stored when using message from message history (#1542) 2025-08-02 09:23:32 -05:00
Aiden Cline 0b132c032a ignore: fix dev branch (#1529) 2025-08-02 09:11:38 -05:00
GitHub Action 44d7103a42 ignore: update download stats 2025-08-02 2025-08-02 12:04:12 +00:00
Ricardo Gonzalez 8f45a0e227 feat(models): enable Kimi k2 ⇄ Claude trajectory handoff (#1525) 2025-08-01 23:05:06 -04:00
Aiden Cline 6581741318 fix: include stderr in bash tool output (#1511) 2025-08-01 19:20:32 -05:00
Aiden Cline 80d68d01f4 better configuration error messages (#1517) 2025-08-01 19:10:32 -04:00
Jay V fa9db3c167 docs: cerebras 2025-08-01 18:30:29 -04:00
opencode 5a727c0794 release: v0.3.112 2025-08-01 21:53:33 +00:00
Dax Raad 71cd84dbbb force models.dev refresh on auth login 2025-08-01 17:48:01 -04:00
Dax Raad e1b7e25f4d make top_p configurable 2025-08-01 17:03:33 -04:00
Dax Raad 98b6bb218b configurable lsp 2025-08-01 14:52:10 -04:00
Brinsil Elias 5592ce8eaf fix(docs): Fix formatting for Node.js installation section (#1497) 2025-08-01 14:15:38 -04:00
CodinCat 510fe8a72a handle the optional v in upgrade command when using curl (#1500) 2025-08-01 14:15:22 -04:00
Yordis Prieto 04a1ab3893 chore: enhance bash command tests with config mock and timeout adjustments (#1486)
Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
2025-08-01 14:14:54 -04:00
Dax Raad e74b4d098b allow search in provider select 2025-08-01 14:03:22 -04:00
Dax Raad 50e4b3e6a7 add version to user-agent 2025-08-01 12:18:09 -04:00
adamdotdevin 6ebd828aa5 fix: unshare command missing 2025-08-01 09:30:42 -05:00
Aiden Cline 022c979d28 tweak: sanitize mcp server names (#831) 2025-08-01 09:11:40 -05:00
Aiden Cline 4172e3ad28 fix: bash tool errors for chmod (#1502) 2025-08-01 09:10:09 -05:00
Aiden Cline 90d1698aed fix: {file:...} references weren't being parsed correctly in some cases (#1499) 2025-08-01 08:39:21 -05:00
adamdotdevin b0c38ce56b ignore: include usage in local setup 2025-08-01 07:42:36 -05:00
GitHub Action 9b37d0e191 ignore: update download stats 2025-08-01 2025-08-01 12:04:33 +00:00
adamdotdevin ea794a4bf6 chore: add local qwen3 to config 2025-08-01 06:27:08 -05:00
Timo Clasen 52f9b37576 docs(permissions): add wildcard example (#1494) 2025-08-01 05:24:32 -05:00
Dax Raad a0d2e53bde poll for models.dev changes 2025-07-31 23:47:42 -04:00
Dax Raad 851e900982 add user agent for models.dev request 2025-07-31 22:00:45 -04:00
Dax Raad 3aa6eeb426 do not mark errored tool calls as aborted 2025-07-31 21:45:40 -04:00
Dax Raad b6ee8e92f9 better guarding against bash commands that go outside of cwd 2025-07-31 21:42:30 -04:00
Frank 44211e1526 Update STATS.md 2025-07-31 21:42:05 -04:00
Dax Raad 12f84f198f improve wildcard matching for permissions 2025-07-31 20:40:05 -04:00
Dax Raad e6db1cf29d ci: ignore release commits 2025-07-31 19:57:07 -04:00
Dax Raad f07f04d969 fix escape button not canceling if retry in progress 2025-07-31 19:55:57 -04:00
Dax Raad 33d613a470 docs: sync 2025-07-31 19:50:51 -04:00
Dax Raad 0bbd7ea17b docs: formatters 2025-07-31 19:50:31 -04:00
Dax Raad 87f3166437 ignore: config 2025-07-31 19:45:44 -04:00
opencode 7665bd9439 Release v0.3.105 2025-07-31 23:41:27 +00:00
Dax Raad 30e10127f2 formatter config 2025-07-31 19:36:07 -04:00
Jay V 5e66fc2318 docs: edit premissions doc 2025-07-31 19:10:54 -04:00
opencode c1c99c7e0f Release v0.3.104 2025-07-31 23:02:36 +00:00
Dax Raad 04e3e83db3 allow disabling formatter 2025-07-31 18:56:04 -04:00
Dax Raad 4273714a62 fix issue with some bash commands asking for permission 2025-07-31 18:35:51 -04:00
Dax Raad a21e237706 ignore: update opencode.json 2025-07-31 18:13:40 -04:00
Dax Raad aa9105649d docs: permissions 2025-07-31 18:11:34 -04:00
Dax Raad 53be288040 docs: permissions 2025-07-31 18:11:34 -04:00
Frank 13dbf912ca Remove hardcoded vscode extension theme
publish-vscode / publish (push) Has been cancelled
2025-07-31 17:53:18 -04:00
Jay V 69966c73f8 docs: add more providers 2025-07-31 17:47:24 -04:00
opencode a00de2df08 Release v0.3.102 2025-07-31 21:25:12 +00:00
Dax Raad 5e72f50554 wip: permissions 2025-07-31 17:19:56 -04:00
Dax Raad d558f15c91 ignore: ts optimization 2025-07-31 16:54:15 -04:00
Dax Raad 614a23698f wip: permissions 2025-07-31 16:51:55 -04:00
Dax Raad a2191ce6fb wip: permissions 2025-07-31 16:38:37 -04:00
Aiden Cline 168350c981 fix: load global jsonc (#1479) 2025-07-31 15:02:28 -05:00
Aiden Cline f5f55062f1 fix: session ordering (#1474) 2025-07-31 14:17:47 -05:00
Frank 360194e219 Add provider instruction for Azure OpenAI 2025-07-31 14:37:26 -04:00
Jay V 5ee994c31f docs: edit providers doc 2025-07-31 14:11:40 -04:00
opencode-agent[bot] fc73d4b1f9 docs: Enhanced providers docs with troubleshooting (#1441)
Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com>
Co-authored-by: jayair <jayair@users.noreply.github.com>
2025-07-31 13:08:12 -04:00
adamdotdevin 936f4cb0c6 fix: permission state hangs 2025-07-31 11:36:08 -05:00
Dax Raad a5b20f973f wip: refactor permissions 2025-07-31 12:26:47 -04:00
adamdotdevin 872b1e068f feat: more scriptable tui (api) 2025-07-31 11:24:23 -05:00
neolooong e4e0b8fd34 fix(editor): handle UTF-8 characters properly in SetValueWithAttachments (#1469) 2025-07-31 10:45:43 -05:00
adamdotdevin c5368e7412 fix: missing operationId 2025-07-31 10:19:42 -05:00
adamdotdevin 1d682544b9 fix: test 2025-07-31 10:10:34 -05:00
adamdotdevin d9210af98c fix: optional toolCallID 2025-07-31 10:09:44 -05:00
adamdotdevin ef633fe92e fix: test 2025-07-31 10:07:58 -05:00
adamdotdevin 5500698734 wip: tui permissions 2025-07-31 09:59:17 -05:00
opencode e7631763f3 Release v0.3.101 2025-07-31 14:23:13 +00:00
Dax Raad 18a572b079 ci: tweak 2025-07-31 10:09:43 -04:00
Dax Raad 060a62ecfb ci: fix 2025-07-31 09:46:36 -04:00
Dax Raad ac3813549a ci: tweak 2025-07-31 09:39:44 -04:00
Dax Raad b14da5fb1f ci: tweak 2025-07-31 09:35:57 -04:00
Dax Raad 416f2235fc ci: reorder 2025-07-31 09:29:55 -04:00
GitHub Action 4fabca426a ignore: update download stats 2025-07-31 2025-07-31 12:04:25 +00:00
Aiden Cline 7e9050edb9 feat: jsonc configuration file support (#1434) 2025-07-31 06:25:26 -05:00
Aiden Cline 3c49a9b7dd fix: process revert cleanup before creating new messages (#1448) 2025-07-31 05:07:59 -05:00
Dax Raad ad66b97463 ci: stainless 2025-07-31 01:42:52 -04:00
Dax Raad 10a0b7f60c ci: tweak 2025-07-31 01:35:11 -04:00
Dax Raad ac8709ac7a ci: tweak 2025-07-31 01:33:21 -04:00
Dax Raad 2d9ed06367 ci: scripts 2025-07-31 01:25:24 -04:00
Dax Raad 50be2aee39 ci tweaks 2025-07-31 01:20:12 -04:00
Dax 0bdbe6261a ci: new publish method (#1451) 2025-07-31 01:05:35 -04:00
Dax 33cef075d2 ci: new publish method (#1451) 2025-07-31 01:00:29 -04:00
Simon Westlin Green b09ebf4645 Use responses API for Azure (#1428)
publish / publish (push) Has been cancelled
2025-07-30 23:22:59 -04:00
Robert Holden 3268c61813 feat: mode directory markdown configuration loading (#1377) 2025-07-30 23:22:43 -04:00
Josh 4a221868da Add http-referer header for vercel ai gateway requests (#1403) 2025-07-30 23:22:24 -04:00
Yordis Prieto 31b8e3d5ab docs: clarify Bun's default registry resolution in index.ts (#1438) 2025-07-30 23:21:07 -04:00
CodinCat 1a78d833a8 fix typo in bash.ts (#1444) 2025-07-30 23:20:48 -04:00
Dax 18888351e9 use treesitter to parse bash commands and catch commands that go outside of cwd (#1443) 2025-07-30 20:57:52 -04:00
Jay V 3b7085ca28 docs: edit 2025-07-30 19:11:36 -04:00
Jay V 160923dcf0 docs: add new providers doc, reorg sidebar, edits 2025-07-30 18:16:11 -04:00
Yordis Prieto c38b091895 fix: update glob pattern and path in tool test (#1436) 2025-07-30 15:42:13 -05:00
Yordis Prieto eecfd6d0ca fix: unit test assertion (#1435)
Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
2025-07-30 15:13:37 -05:00
Dax Raad 6ef4cfa2fa lower max retries to 3 - ai sdk currently cannot abort during a retry delay so things appear to be frozen
publish / publish (push) Has been cancelled
2025-07-30 15:08:25 -04:00
Dax Raad 190dee080c release undo/redo 2025-07-30 13:09:18 -04:00
Aiden Cline 09074dc639 fix: attachment highlighting (#1427) 2025-07-30 11:43:34 -05:00
Aiden Cline 1b3d58e791 fix: prevent read tool from opening binary files and corrupting session (#1425) 2025-07-30 11:00:23 -05:00
GitHub Action 772c83c1d5 ignore: update download stats 2025-07-30 2025-07-30 12:04:23 +00:00
Sam Huckaby 54dc937fa1 fix: quick grammar and spelling check (#1402) 2025-07-30 05:54:47 -05:00
Aiden Cline b5219f7585 tweak: adjust astro css to render mixed nested lists (#1411) 2025-07-30 05:51:52 -05:00
municorn 0bd0453866 build: add @octokit/rest to opencode dependencies (#1396)
Co-authored-by: Frank <frank@sst.dev>
2025-07-29 22:33:25 -04:00
Dax Raad 8bf36d174b update beast prompt for openai models
publish / publish (push) Has been cancelled
2025-07-29 22:15:13 -04:00
Dax Raad 9bedd62da4 experimental well-known auth support
publish / publish (push) Has been cancelled
2025-07-29 19:30:51 -04:00
Yordis Prieto 4c34b69ae6 chore: fix test to have deterministic testing (#1401) 2025-07-29 17:54:22 -05:00
Dax Raad 7e9ac35666 remove min/max in tool schemas
publish / publish (push) Has been cancelled
2025-07-29 17:39:47 -04:00
Frank 4a46144419 convert share backend to hono app 2025-07-29 16:39:48 -04:00
adamdotdevin a129e122aa feat: show git diff in reverted messages 2025-07-29 13:11:38 -05:00
Yordis Prieto c0ee6a6d05 fix: update file name extraction in uploads test to use __filename (#1395) 2025-07-29 12:28:44 -05:00
Yordis Prieto 68ae0d107c fix: improve handling of global File object in uploads tests (#1394) 2025-07-29 11:30:39 -05:00
Yordis Prieto df63008a94 chore: fix null handling in multipartFormRequestOptions test (#1385) 2025-07-29 11:17:03 -05:00
Andrea Grandi 3bd2b340c8 feat: show current git branch in status bar, and make it responsive (#1339)
Co-authored-by: adamdotdevin <2363879+adamdottv@users.noreply.github.com>
2025-07-29 11:15:04 -05:00
Dax Raad df03e182d2 strip todo tool instructions from non anthropic models 2025-07-29 11:56:53 -04:00
Jacob Hands 862a50d61d feat: add OPENCODE_CONFIG env var for specifying a custom config file (#1370) 2025-07-29 11:03:11 -04:00
GitHub Action a7cfd36b07 ignore: update download stats 2025-07-29 2025-07-29 12:04:40 +00:00
Aiden Cline c165360e17 fix: task type error (#1384) 2025-07-29 06:18:34 -05:00
Dax Raad 9cb0f21b4e trim opencode title 2025-07-28 23:24:38 -04:00
Dax Raad 9c9cbb3e81 wip: undo properly remove messages from UI 2025-07-28 22:58:31 -04:00
Dax Raad c24fbb4292 wip: snapshot 2025-07-28 22:58:31 -04:00
Jay V 99dfe65862 docs: share page hide patch part 2025-07-28 20:04:00 -04:00
Jay V 4506e5a824 docs: adding 2025-07-28 20:00:30 -04:00
Jay V b65172a2b7 Tweak auth cli copy 2025-07-28 20:00:30 -04:00
Dax Raad 081f100c93 ignore: tweak
publish / publish (push) Has been cancelled
2025-07-28 12:20:37 -04:00
Dax Raad f2bdb8159f fix phantom tool call failed messages and empty text parts with some models 2025-07-28 12:19:38 -04:00
GitHub Action 10d749a85e ignore: update download stats 2025-07-28 2025-07-28 12:04:21 +00:00
Frank a07d149e28 vscode: add cmd+shift+esc keybinding
publish-vscode / publish (push) Has been cancelled
2025-07-27 15:54:45 -04:00
Frank 3eb982c8cd vscode: bring oc terminal to front if already opened 2025-07-27 14:57:45 -04:00
Frank 45c4e0b8f8 show opencode button in vscode when focused on terminal 2025-07-27 14:44:14 -04:00
Aiden Cline b18b646f8e fix: attachment bugs (#1335) 2025-07-27 12:21:31 -05:00
Frank 9741a6703c fix input format affected by installing vscode extension
publish / publish (push) Has been cancelled
2025-07-27 11:56:18 -04:00
Frank 27a079d9cb simplify github action 2025-07-27 09:56:09 -04:00
GitHub Action 2eeb987680 ignore: update download stats 2025-07-27 2025-07-27 12:04:15 +00:00
Aiden Cline e827294c9b docs: document small_model cfg option (#1347) 2025-07-26 16:56:38 -05:00
Dax Raad 7cf4ed6ad6 ci: fix opencode github 2025-07-26 10:02:31 -04:00
Aiden Cline ad8a4bc744 fix: strip thinking blocks from title (#1325) 2025-07-26 08:29:04 -05:00
GitHub Action 2630104f18 ignore: update download stats 2025-07-26 2025-07-26 12:03:59 +00:00
Frank 670f470eee wip: github actions
publish / publish (push) Has been cancelled
2025-07-26 02:49:05 -04:00
Frank c2b3c52b76 wip: github action 2025-07-26 01:03:23 -04:00
Frank a007d65f62 wip: github actions
publish / publish (push) Has been cancelled
2025-07-25 20:27:42 -04:00
Didier Durand 2c924b9fdb fixing various typos in text. (#1185) 2025-07-25 20:20:01 -04:00
Dax Raad e8eaa77bf1 better mcp support - should fix hanging when streamable http server is added
publish / publish (push) Has been cancelled
2025-07-25 19:19:47 -04:00
Frank a07f37073b wip: github actions
publish / publish (push) Has been cancelled
2025-07-25 19:05:55 -04:00
Frank 4d760a1984 wip: github action
publish-github-action / publish (push) Has been cancelled
2025-07-25 18:33:45 -04:00
Dax Raad 6b7058fe1c qwen optimizations it works good now 2025-07-25 18:31:08 -04:00
Frank 1149b984d9 wip: github actions
publish-github-action / publish (push) Has been cancelled
publish / publish (push) Has been cancelled
2025-07-25 18:29:53 -04:00
Michael Hanson 81fb1b313e Fix a broken example in the MCP documentation and add more clarity (#1322) 2025-07-25 17:47:01 -04:00
Frank 3a7a2a838e wip: github actions
publish / publish (push) Has been cancelled
2025-07-25 17:34:47 -04:00
Dax Raad 10ae43a121 wip: sync
publish / publish (push) Has been cancelled
2025-07-25 15:52:27 -04:00
Dax Raad c85b970903 wip: drop 2025-07-25 15:51:02 -04:00
Dax Raad 7044662cfa handle uploaded text/plain 2025-07-25 15:48:42 -04:00
kehanzhang 92656fdf29 fix(headless): respect mode passed to /message endpoint (#1300) 2025-07-25 15:26:49 -04:00
Dax Raad c65e7aff86 docs: mode temperature 2025-07-25 13:45:04 -04:00
Dax Raad e97613ef9f allow temperature to be configured per mode
publish / publish (push) Has been cancelled
2025-07-25 13:29:44 -04:00
Dominik Engelhardt 827469c725 fix: apply content-level caching for non-anthropic providers (#1305) 2025-07-25 12:19:44 -04:00
Yihui Khuu 613b5fbe48 feat: add csharp lsp (#1312) 2025-07-25 12:17:06 -04:00
Dax Raad 7ed05962db fix issue with trailing whitespace error in assistant message 2025-07-25 10:56:16 -04:00
Dax Raad 250a86ec52 fix reading model from config
publish / publish (push) Has been cancelled
2025-07-25 10:53:37 -04:00
Yihui Khuu 0795a577e0 fix: header width to display header in one line when sharing disabled (#1310) 2025-07-25 09:32:06 -05:00
Dax Raad 8e5607f9c0 fix double system prompt 2025-07-25 10:28:42 -04:00
Dax Raad d6b3bb0807 disable todo tools by default in agent
publish / publish (push) Has been cancelled
2025-07-25 10:23:23 -04:00
Dax Raad f307a5ce0b fix symlinked agents
publish / publish (push) Has been cancelled
2025-07-25 10:20:16 -04:00
GitHub Action 151c7ed5a2 ignore: update download stats 2025-07-25 2025-07-25 12:04:21 +00:00
Dax Raad fc13d057f8 agents better display when spawning
publish / publish (push) Has been cancelled
2025-07-24 23:08:03 -04:00
Dax Raad fc73d3c523 docs: agents
publish / publish (push) Has been cancelled
2025-07-24 22:18:49 -04:00
Dax Raad 5d871b2075 docs: agents 2025-07-24 22:16:16 -04:00
Dax Raad 529a171d51 docs: agents 2025-07-24 22:07:30 -04:00
Dax Raad 8dcd39f5b7 real life totally configurabl ai subasians
publish / publish (push) Has been cancelled
2025-07-24 21:21:02 -04:00
Frank 88477b3ee7 wip: github actions 2025-07-24 19:03:10 -04:00
Jay V 0c7e529e6d docs: add to quick start 2025-07-24 18:57:54 -04:00
Filip 01f75839a9 Fix: added environment() to summarize() (#1290) 2025-07-24 18:24:54 -04:00
Dax Raad 4306f1a339 wip: handle deleting file 2025-07-24 17:49:23 -04:00
Dax Raad aa2a5057ac wip: fix type errors 2025-07-24 17:38:11 -04:00
Dax Raad 284c01018e wip: more snapshot stuff 2025-07-24 17:38:11 -04:00
Aiden Cline 22c9e2942b (tui) tweak: add setting for scroll speed (#1288) 2025-07-24 16:34:59 -05:00
Clay Warren d50ae8e4d4 feat: Replace unzip with @zip.js/zip.js for Windows compatibility (#662) 2025-07-24 16:49:04 -04:00
Filip e9074e60cf fix: add custom() to system prompt on summarize (#1289) 2025-07-24 16:48:17 -04:00
Filip 541a7a39d3 fix: edit tool (#1287) 2025-07-24 16:18:04 -04:00
Dax Raad 72e464ac3e ci: tweak
publish / publish (push) Has been cancelled
2025-07-24 15:55:45 -04:00
Dax Raad 20bf27feda ci: tweak
publish / publish (push) Has been cancelled
2025-07-24 15:51:33 -04:00
Dax Raad d288d21330 includ baseline builds
publish / publish (push) Has been cancelled
2025-07-24 14:37:38 -04:00
Jesse van der Pluijm 34f6ffe1d7 Check if modelID includes "claude" for antropic/claude prompt caching (#1284) 2025-07-24 11:31:28 -04:00
Dax Raad a11999137f disable snapshots
publish / publish (push) Has been cancelled
2025-07-24 11:08:20 -04:00
Aiden Cline a16554d445 fix: slog error log serialization (#1276) 2025-07-24 07:19:00 -05:00
danielfyhr 2553137395 add aura theme (#1280) 2025-07-24 07:17:27 -05:00
GitHub Action 6b6b81556f ignore: update download stats 2025-07-24 2025-07-24 12:04:18 +00:00
Dax Raad ff23f67ad5 disable undo/redo for now 2025-07-23 21:02:13 -04:00
Rico Sta. Cruz 8f0644e35b fix: update max visible height in list tests (#1269) 2025-07-23 20:49:15 -04:00
Dax Raad 3fdd23df16 fix header width 2025-07-23 20:48:35 -04:00
Dax Raad 2c82ee592c wip: always force create snapshot 2025-07-23 20:46:43 -04:00
Dax Raad 1ad529db59 wip: fix redoing 2025-07-23 20:42:02 -04:00
Dax 96866e52ce basic undo feature (#1268)
Co-authored-by: adamdotdevin <2363879+adamdottv@users.noreply.github.com>
Co-authored-by: Jay V <air@live.ca>
Co-authored-by: Aiden Cline <63023139+rekram1-node@users.noreply.github.com>
Co-authored-by: Andrew Joslin <andrew@ajoslin.com>
Co-authored-by: GitHub Action <action@github.com>
Co-authored-by: Tobias Walle <9933601+tobias-walle@users.noreply.github.com>
2025-07-23 20:30:46 -04:00
Yihui Khuu 507c975e92 feat: pass mode into task tool (#1248) 2025-07-23 20:29:59 -04:00
Aiden Cline 3e69d5276b docs: remove deprecated 'log_level' reference in docs (#1258) 2025-07-23 18:53:58 -04:00
Aiden Cline 289a4d9b18 tweak: handle pasted attachment references (#1257) 2025-07-23 15:41:17 -05:00
Tobias Walle 12bf5f641d fix "working" spinner animation (#1054) (#1259) 2025-07-23 15:40:34 -05:00
Dax Raad 2051e85e96 remove providers path
publish / publish (push) Has been cancelled
2025-07-23 12:15:31 -04:00
Dax Raad 12b86829d9 add debug paths command 2025-07-23 12:14:54 -04:00
GitHub Action 6c9ec54129 ignore: update download stats 2025-07-23 2025-07-23 12:04:18 +00:00
Aiden Cline b7b0cdbd7c tweak: ensure most recently interacted with session appears at the top (#1239) 2025-07-22 22:37:36 -05:00
Dax Raad fd98c3189a config: improve config schema
publish / publish (push) Has been cancelled
2025-07-22 20:35:40 -04:00
Jay V 1278353616 docs: edit ide 2025-07-22 19:02:30 -04:00
Andrew Joslin 638ec7bc50 Allow multiline prompts for github agent (#1225) 2025-07-22 18:30:51 -04:00
Aiden Cline 38ae7d60aa feat(tui): support pipe into tui (#1230) 2025-07-22 17:19:20 -05:00
Jay V 2d1f9fc321 docs: add tutorial closes #740 2025-07-22 17:54:53 -04:00
Frank ee0c8132db wip: vscode extension 2025-07-22 17:13:58 -04:00
Dax Raad c2208fa1f9 ci: error github api fail 2025-07-22 17:06:06 -04:00
Frank bf42d8b011 wip: vscode extension 2025-07-22 16:50:56 -04:00
Frank 0deb85fa45 wip: vscode extension
publish / publish (push) Has been cancelled
2025-07-22 16:46:44 -04:00
Frank da19b10703 wip: vscode extension 2025-07-22 16:46:44 -04:00
Frank 80b17dab44 wip: vscode extension 2025-07-22 16:46:44 -04:00
Dax Raad 6d2ffa82de ignore: lock changes 2025-07-22 15:49:36 -04:00
Dax Raad 7998c3b5ce wip: tui api 2025-07-22 15:49:24 -04:00
Frank 13def91e9a wip: vscode extension
publish-vscode / publish (push) Has been cancelled
2025-07-22 15:36:55 -04:00
Frank 26a40610dd wip: vscode extension 2025-07-22 15:28:09 -04:00
Frank db2fbed691 wip: vscode extension 2025-07-22 13:21:49 -04:00
Aiden Cline 3d4c1425d9 tweak: cleanup cancelled markdown (#1222) 2025-07-22 12:08:03 -05:00
adamdotdevin 10c8b49590 chore: generate sdk into packages/sdk 2025-07-22 11:50:51 -05:00
Dax Raad 500cea5ce7 wip: append-prompt is better 2025-07-22 12:27:02 -04:00
Dax Raad 5aafab118f wip: tui api 2025-07-22 12:15:50 -04:00
Frank 01f8d3b05d wip: vscode extension 2025-07-22 11:21:29 -04:00
adamdotdevin 99d6a28249 fix(tui): more defensive attachment conversion
publish / publish (push) Has been cancelled
2025-07-22 09:28:13 -05:00
GitHub Action 5eaf7ab586 ignore: update download stats 2025-07-22 2025-07-22 12:04:22 +00:00
Aiden Cline e4f754eee7 fix: mouse text selection bug (#1206) 2025-07-21 19:15:36 -05:00
Dax Raad f20ef61bc7 wip: api for tui 2025-07-21 19:53:58 -04:00
Frank 5611ef8b28 wip: vscode extension 2025-07-21 19:10:57 -04:00
Timo Clasen bec796e3c3 feat(tui): add ctrl+p and ctrl-n to history navigation (#1199) 2025-07-21 15:10:50 -05:00
Frank 0bd8b2c72f wip: vscode extension
publish-vscode / publish (push) Has been cancelled
2025-07-21 15:48:46 -04:00
Dax Raad 5550ce47e1 ci: tweaks 2025-07-21 15:45:44 -04:00
Dax Raad 2d84dadc0c fix broken attachments
publish / publish (push) Has been cancelled
2025-07-21 15:38:41 -04:00
Dax Raad 45c0578b22 fix title generation bug
publish / publish (push) Has been cancelled
2025-07-21 15:23:47 -04:00
Dax 1ded535175 message queuing (#1200)
publish / publish (push) Has been cancelled
2025-07-21 15:14:54 -04:00
adamdotdevin d957ab849b fix(tui): up/down arrow handling
publish / publish (push) Has been cancelled
2025-07-21 10:44:21 -05:00
plyght 4b2e52c834 feat(tui): paste minimizing (#784)
Co-authored-by: adamdotdevin <2363879+adamdottv@users.noreply.github.com>
2025-07-21 10:31:29 -05:00
Dax Raad 6867658c0f do not copy empty strings 2025-07-21 11:27:15 -04:00
Dax Raad b8620395cb include newline between messages when copying
publish / publish (push) Has been cancelled
2025-07-21 11:22:51 -04:00
Dax Raad 90d37c98f8 add toast for copy
publish / publish (push) Has been cancelled
2025-07-21 11:19:54 -04:00
adamelmore c9a40917c2 feat(tui): disable keybinds 2025-07-21 10:08:25 -05:00
adamelmore 0aa0e740cd docs: cleanup 2025-07-21 10:02:58 -05:00
adamelmore bb17d14665 feat(tui): theme override with OPENCODE_THEME 2025-07-21 10:02:57 -05:00
adamdotdevin cd0b2ae032 fix(tui): restore spinner ticks
publish / publish (push) Has been cancelled
2025-07-21 05:58:24 -05:00
adamdotdevin 8e8796507d feat(tui): message history select with up/down arrows
publish / publish (push) Has been cancelled
2025-07-21 05:52:11 -05:00
Aiden Cline cef5c29583 fix: pasting issue (#1182) 2025-07-21 04:09:16 -05:00
Aiden Cline acaed1f270 fix: export cmd (#1184) 2025-07-21 04:08:26 -05:00
Dax cda0dbc195 Update STATS.md 2025-07-20 20:36:23 -04:00
Dax Raad 758425a8e4 trimmed selection ui
publish / publish (push) Has been cancelled
2025-07-20 19:36:56 -04:00
Dax Raad 93446df335 ignore: remove log 2025-07-20 19:08:19 -04:00
Dax Raad adc8b90e0f implement copy paste much wow can you believe we went this long without it so stupid i blame adam
publish / publish (push) Has been cancelled
2025-07-20 19:05:38 -04:00
Dax Raad 733c9903ec do not snapshot nongit projects for now
publish / publish (push) Has been cancelled
2025-07-20 13:59:30 -04:00
Frank 7306e20361 wip: vscode extension
publish-vscode / publish (push) Has been cancelled
2025-07-20 13:31:16 -04:00
Frank b4c7042c17 wip: vscode extension
publish-github-action / publish (push) Has been cancelled
publish-vscode / publish (push) Has been cancelled
2025-07-20 13:27:37 -04:00
Frank 6965787b33 wip: vscode extension 2025-07-20 13:17:51 -04:00
Frank ce064b8b0e wip: github action 2025-07-20 13:14:14 -04:00
Frank 0fc546fc6b wip: vscode extension 2025-07-20 13:13:18 -04:00
Frank 77ac9e5ec2 wip: github action 2025-07-20 13:13:00 -04:00
Frank af2c0b3695 wip: github action 2025-07-20 13:07:48 -04:00
Frank 811b22367d wip: github action 2025-07-20 12:41:02 -04:00
Frank 933d50e25a wip: github actions
publish-github-action / publish (push) Has been cancelled
2025-07-20 12:36:53 -04:00
Frank 800bee2722 wip: vscode extension 2025-07-20 12:00:09 -04:00
Dax Raad 5b4fb96c2e wip: make api logger sort correctly 2025-07-20 11:54:56 -04:00
Frank 1d20bf343d wip: vscode extension 2025-07-20 11:54:30 -04:00
Frank 79d9bf57f7 wip: vscode extension 2025-07-20 11:47:18 -04:00
Frank 7b63db6a13 wip: vscode extension 2025-07-20 11:45:35 -04:00
Frank 0e1565449e wip: vscode extension
publish-vscode / publish (push) Has been cancelled
publish / publish (push) Has been cancelled
2025-07-20 11:33:44 -04:00
GitHub Action f9a47fe5a3 ignore: update download stats 2025-07-20 2025-07-20 12:04:10 +00:00
adamdotdevin 2bf9d5d4ec wip: file part source in server/api (optional) 2025-07-20 05:39:18 -05:00
adamdotdevin c18f9ece69 chore: updated tui gitignore 2025-07-20 05:39:18 -05:00
adamdotdevin 4e3c73c4f5 chore: updated stainless script 2025-07-20 05:39:18 -05:00
b0tmtl 8bf2eeccd0 fix(windows): resolve numlock and French keyboard input issues (#1165) 2025-07-20 05:28:15 -05:00
Dax Raad 6232e0fc58 fix bad layout on first render of chat history
publish / publish (push) Has been cancelled
2025-07-19 22:38:36 -04:00
Dax Raad a8b4aed446 fix bash tool rendering
publish / publish (push) Has been cancelled
2025-07-19 22:25:15 -04:00
Aiden Cline 03de0c406d fix: title generation for certain providers (#1159) 2025-07-19 20:01:55 -05:00
Aiden Cline faf8da8743 fix: adjust editor parsing to handle flags like --wait (#1160) 2025-07-19 20:01:25 -05:00
Dax Raad 3386908fd6 ci: ignore
publish / publish (push) Has been cancelled
2025-07-19 19:30:12 -04:00
Dax Raad 5a8847952a ci: ignore
publish / publish (push) Has been cancelled
2025-07-19 19:29:05 -04:00
Dax Raad 87d21ebf2b Revert "fix: prevent sparse spacing in hyphenated words (#1102)"
publish / publish (push) Has been cancelled
This reverts commit 2b44dbdbf1.
2025-07-19 19:25:15 -04:00
Timo Clasen a524fc545c fix(hooks): prevent session_complete hook from firing on subagent sessions (#1149)
publish / publish (push) Has been cancelled
2025-07-19 18:20:07 -05:00
Dax Raad 4316edaf43 fix first run github copilot
publish / publish (push) Has been cancelled
2025-07-19 19:19:38 -04:00
Dax Raad d845924e8b ci: ignore
publish / publish (push) Has been cancelled
2025-07-19 19:00:17 -04:00
Dax Raad a29b322bdd ci: ignore
publish / publish (push) Has been cancelled
2025-07-19 18:54:46 -04:00
Dax Raad 9723ffa7a6 ignore: ci
publish / publish (push) Has been cancelled
2025-07-19 18:48:43 -04:00
Dax Raad f06cd88773 perf: more performance improvements
publish / publish (push) Has been cancelled
2025-07-19 18:41:21 -04:00
Dax Raad 9af92b6914 perf: scroll to bottom in thread
publish / publish (push) Has been cancelled
2025-07-19 17:55:01 -04:00
Dax Raad 8f64c4b312 disable todo tools when running as task
publish / publish (push) Has been cancelled
2025-07-19 15:54:11 -04:00
Dax Raad a32877e908 ignore: create memo abstraction
publish / publish (push) Has been cancelled
2025-07-19 15:26:26 -04:00
Dax Raad 6465c9c44a fix openrouter caching
publish / publish (push) Has been cancelled
2025-07-19 15:11:21 -04:00
Dax Raad 4699739814 shitty hack for terrible charm bubbletea performance
publish / publish (push) Has been cancelled
2025-07-19 15:00:11 -04:00
Dax Raad c1d87c32a2 remove log level from config 2025-07-19 13:37:02 -04:00
Aiden Cline 9c5d9be33a fix: bullet display (#1148) 2025-07-19 12:36:50 -05:00
Aiden Cline 97d9c851e6 fix: escape ansi sequences (#1139) 2025-07-19 12:02:24 -05:00
Dax Raad 76bd702992 docs: fix typo 2025-07-19 12:45:33 -04:00
Yihui Khuu 50c453e577 feat(tui): collapse session header into single line when sharing is disabled (#1145) 2025-07-19 11:43:04 -05:00
Dax Raad 86d5b25d18 pass through model.options properly without having to nest it under provider name. you may have to update your configs see https://opencode.ai/docs/models/#openrouter for an example
publish / publish (push) Has been cancelled
2025-07-19 12:41:58 -04:00
Tom 2b44dbdbf1 fix: prevent sparse spacing in hyphenated words (#1102) 2025-07-19 09:28:40 -05:00
Dax Raad 4bbbbac5f6 vercel ai gateway
publish / publish (push) Has been cancelled
2025-07-19 10:08:36 -04:00
GitHub Action 3c3a997d2a ignore: update download stats 2025-07-19 2025-07-19 12:04:11 +00:00
CodinCat 1676f8b5dd fix table heading rendering (#1138) 2025-07-18 20:17:22 -05:00
Dax Raad c87a7469a0 ci: rollback install script 2025-07-18 18:57:58 -04:00
Michael Hanson 132e26ddbf docs: Clarify MCP config instructions (#1026)
publish / publish (push) Has been cancelled
2025-07-18 16:04:29 -04:00
Rami Chowdhury f1da70b1de feat(provider): add Gemini tool schema sanitization (#1132) 2025-07-18 16:02:54 -04:00
Aiden Cline 5c9d1910af fix: func called before definition (#1134) 2025-07-18 15:00:32 -05:00
Timo Clasen 18abcab208 feat(config): make small model configurable (#1030)
publish / publish (push) Has been cancelled
2025-07-18 14:16:50 -04:00
opencode-agent[bot] 01e7dc2d02 Added install dir priority & user feedback (#1129)
Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com>
Co-authored-by: thdxr <thdxr@users.noreply.github.com>
2025-07-18 14:15:10 -04:00
adamdotdevin 611854e4b6 feat(tui): simpler layout, always stretched 2025-07-18 13:03:27 -05:00
Dax d56dec4ba7 wip: optional IDs in api (#1128)
publish / publish (push) Has been cancelled
2025-07-18 13:42:50 -04:00
Dax Raad c952e9ae3d message rendering performance improvements 2025-07-18 13:40:07 -04:00
GitHub Action 6470243095 ignore: update download stats 2025-07-18 2025-07-18 12:04:28 +00:00
GitHub Action c8321cfbd9 ignore: update download stats 2025-07-18 2025-07-18 12:02:18 +00:00
Yihui Khuu 46c246e01f fix: \{return} should be replaced with new line on all lines (#1119) 2025-07-18 06:22:36 -05:00
adamdotdevin 9964d8e6c0 fix: model cost overrides
publish / publish (push) Has been cancelled
2025-07-18 05:08:35 -05:00
Timo Clasen df33143396 feat(tui): parse for file attachments when exiting EDITOR (#1117) 2025-07-18 04:47:20 -05:00
Aiden Cline 571aeaaea2 tweak: remove needless resorting (#1116) 2025-07-18 04:42:43 -05:00
Aiden Cline edfea03917 tweak: fix [object Object] in logging (#1114) 2025-07-18 04:41:23 -05:00
Tom 81c88cc742 fix(tui): ensure viewport scrolls to bottom on new messages (#1110) 2025-07-18 04:41:03 -05:00
Mike Wallio 99b9390d80 Update to a customized beast mode v3 for opencode. (#1109) 2025-07-17 20:10:06 -05:00
Dax Raad 23c30521d8 only enable ruff if it seems to be used
publish / publish (push) Has been cancelled
2025-07-17 18:07:06 -04:00
Wendell Misiedjan e681d610de feat: support AWS_BEARER_TOKEN_BEDROCK for amazon bedrock provider autoloading (#1094)
publish / publish (push) Has been cancelled
2025-07-17 09:12:30 -05:00
Aiden Cline a1fdeded3e tweak: allow mcp servers to include headers (#1096) 2025-07-17 09:11:48 -05:00
GitHub Action 2051312d12 ignore: update download stats 2025-07-17 2025-07-17 14:07:13 +00:00
Alexander Drottsgård 20cb7a76af feat(tui): highlight current session in sessions modal (#1093) 2025-07-17 07:40:15 -05:00
Timo Clasen a493aec174 feat(tui): remove share commands from help if sharing is disabled (#1087) 2025-07-17 04:28:12 -05:00
Aiden Cline 3ce3ac8e61 fix: message error centering (#1085) 2025-07-17 04:27:40 -05:00
Timo Clasen 91ad64feda fix(tui): user defined ctrl+z should take precedence over suspending (#1088) 2025-07-17 04:27:02 -05:00
Timo Clasen 60b55f9d92 feat(tui): remove sharing info from session header when sharing is disabled (#1076) 2025-07-16 17:36:48 -05:00
Timo Clasen 3c6c2bf13b docs(share): add explicit manual share mode (#1074) 2025-07-16 16:08:25 -05:00
Aiden Cline d4f9375548 fix: type 'reasoning' was provided without its required following item (#1072) 2025-07-16 15:59:40 -05:00
Jay V 28b39f547e docs: edit 2025-07-16 16:59:12 -04:00
Jay V 7520f5efa8 docs: update enterprise doc 2025-07-16 16:44:28 -04:00
Jay V eb4cdf4b20 docs: config doc 2025-07-16 16:27:44 -04:00
Jay V 9f6fc1c3c5 docs: edits 2025-07-16 16:20:09 -04:00
Mike Wallio dfede9ae6e Remove binary file opencode (#1069) 2025-07-16 15:10:40 -05:00
Daniel Saldarriaga López fc45c0c944 docs: fix keybinds documentation to match actual config schema (#867)
publish / publish (push) Has been cancelled
2025-07-16 15:34:52 -04:00
adamdotdevin 9d869f784c fix(tui): expand edit calls 2025-07-16 14:33:57 -05:00
adamdotdevin bd244f73af fix(tui): slightly faster scroll speed 2025-07-16 14:26:46 -05:00
Dax Raad dd34556e9c only include severity 1 diagnostics from lsp in edit tool output
publish / publish (push) Has been cancelled
2025-07-16 15:25:37 -04:00
adamdotdevin f7dd48e60d feat(tui): more ways to quit 2025-07-16 14:20:28 -05:00
Dax Raad 93c779cf48 docs: better variable examples 2025-07-16 14:56:24 -04:00
adamdotdevin 360c04c542 docs: copying text 2025-07-16 13:26:26 -05:00
adamdotdevin 529fd57e75 fix: missing dependency
publish / publish (push) Has been cancelled
2025-07-16 12:58:29 -05:00
adamdotdevin faea3777e1 fix: missing dependency 2025-07-16 12:56:11 -05:00
Aiden Cline a4664e2344 fix: generate title should use same options as model it uses to gen (#1064) 2025-07-16 12:46:52 -05:00
adamdotdevin cdc1d8a94d feat(tui): layout config to render full width
publish / publish (push) Has been cancelled
2025-07-16 12:43:02 -05:00
Jay V fdd6d6600f docs: rename workflow 2025-07-16 13:38:00 -04:00
Jay V 9f44cfd595 docs: discord releases 2025-07-16 13:17:04 -04:00
Aiden Cline 70229b150c Fix: better title generation (needs to change due to small models) (#1059) 2025-07-16 11:47:56 -05:00
John Henry Rudden 050ff943a6 Fix: Add escape sequence for @ symbols to prevent send blocking (#1029) 2025-07-16 11:18:48 -05:00
Tom 88b58fd6a0 fix: Prevent division by zero in context percentage calculation (#1055) 2025-07-16 09:35:20 -05:00
Jeremy Mack 5d67e13df5 fix: grep omitting text after a colon (#1053) 2025-07-16 09:09:05 -05:00
Adi Yeroslav 57d1a60efc feat(tui): shift+tab to cycle modes backward (#1049) 2025-07-16 07:43:48 -05:00
Nipuna Perera add81b9739 Enhance private npm registry support (#998) 2025-07-16 08:31:38 -04:00
GitHub Action 81bdb8e269 ignore: update download stats 2025-07-16 2025-07-16 12:04:30 +00:00
adamdotdevin a563fdd287 fix(tui): diagnostics rendering 2025-07-16 06:55:14 -05:00
adamdotdevin 7c93bf5993 fix(tui): pending tool call width 2025-07-16 06:27:32 -05:00
adamdotdevin 6a5a4247c6 fix(gh): build 2025-07-16 06:13:43 -05:00
adamdotdevin a39136a2a0 fix(tui): render attachments in user messages in accent color 2025-07-16 06:09:27 -05:00
adamdotdevin 9f5b59f336 chore: messages cleanup 2025-07-16 06:09:27 -05:00
adamdotdevin 01c125b058 fix(tui): faster cache algo 2025-07-16 06:09:27 -05:00
adamdotdevin d41aa2bc72 chore(tui): simplify messages component, remove navigate, add copy last message 2025-07-16 06:09:26 -05:00
Robin Moser f45deb37f0 fix: don't sign snapshot commits (#1046) 2025-07-16 04:46:32 -05:00
Matias Insaurralde e89972a396 perf: move ANSI regex compilations to package level (#1040)
Signed-off-by: Matías Insaurralde <matias@insaurral.de>
2025-07-16 04:20:25 -05:00
Frank c3c647a21a wip: github actions 2025-07-16 16:20:06 +08:00
Frank b79167ce66 sync 2025-07-16 16:12:31 +08:00
Frank 7ac0a2bc65 wip: github actions 2025-07-16 16:05:51 +08:00
Frank cb032cff2b wip: github actions 2025-07-16 03:57:14 -04:00
Frank 867a69a751 wip: github actions 2025-07-16 03:54:20 -04:00
Frank 20b8efcc50 wip: github actions 2025-07-16 15:36:23 +08:00
Frank a86d42149f wip: github actions 2025-07-16 14:59:53 +08:00
Frank 82a36acfe3 wip: github action 2025-07-16 14:59:53 +08:00
Dax Raad 0793c3f2a3 clean up export command
publish / publish (push) Has been cancelled
2025-07-15 21:50:43 -04:00
Dax Raad 5c860b0d69 fix share page v1 message 2025-07-15 21:35:32 -04:00
Dax Raad 05bb127a8e enable bash tool in plan mode 2025-07-15 21:28:03 -04:00
aron 1bbd84008f move spoof prompt to support anthropic with custom modes (#1031)
publish / publish (push) Has been cancelled
2025-07-15 21:16:27 -04:00
Stephen Murray fdfd4d69d3 add support for modified gemini-cli system prompt (#1033)
Co-authored-by: Dax Raad <d@ironbay.co>
2025-07-15 21:13:11 -04:00
Jay 7f659cce36 docs: Update README.md 2025-07-15 20:09:26 -04:00
Jay V 48fcaa83be docs: fix config 2025-07-15 19:54:51 -04:00
Jay V 70c16c4c95 docs: adding action to notify discord 2025-07-15 19:49:38 -04:00
Jay V c1e1ef6eb5 docs: readme 2025-07-15 18:32:04 -04:00
Jay V bb155db8b2 docs: share tweak copy button 2025-07-15 18:25:25 -04:00
John Henry Rudden 7c91f668d1 docs: share add copy button to messages in web interface (#902)
Co-authored-by: Jay <air@live.ca>
2025-07-15 17:56:33 -04:00
Jay V 1af103d29e docs: share handle non bundled langs 2025-07-15 17:47:22 -04:00
Jay V 8a3e581edc docs: share fix diff bugs 2025-07-15 17:47:22 -04:00
Jay V 749e7838a4 docs: share page task tool 2025-07-15 17:47:22 -04:00
Dax Raad 73b46c2bf9 docs: document base URL 2025-07-15 14:57:50 -04:00
Joe Schmitt 8bd250fb15 feat(tui): add /export command to export conversation to editor (#989)
Co-authored-by: opencode <noreply@opencode.ai>
2025-07-15 13:53:21 -05:00
Dax Raad b1ab641905 add small model for title generation
publish / publish (push) Has been cancelled
2025-07-15 14:00:52 -04:00
adamdotdevin 76e256ed64 fix(tui): wider max width
publish / publish (push) Has been cancelled
2025-07-15 12:44:41 -05:00
adamdotdevin 4f955f2127 fix(tui): mouse scroll ansi parsing and perf 2025-07-15 12:03:30 -05:00
Aiden Cline bbeb579d3a tweak: (opencode run): adjust tool call rendering, reduce number of "Unknowns" (#1012) 2025-07-15 11:22:57 -05:00
Timo Clasen f707fb3f8d feat(tui): add keymap to remove entries from recently used models (#1019) 2025-07-15 11:20:56 -05:00
adamdotdevin 6b98acb7be chore: update stainless defs 2025-07-15 10:03:11 -05:00
adamdotdevin 2487b18f62 chore: update stainless script to kick off prod build 2025-07-15 08:15:31 -05:00
adamdotdevin 533f64fe26 fix(tui): rework lists and search dialog 2025-07-15 08:07:26 -05:00
Dax Raad b5c85d3806 fix logic for suprpessing snapshots in big directories
publish / publish (push) Has been cancelled
2025-07-15 09:07:04 -04:00
Dax Raad bcf952bc8a upgrade ai sdk 2025-07-15 09:06:35 -04:00
GitHub Action a6dc75a44c ignore: update download stats 2025-07-15 2025-07-15 12:04:28 +00:00
Joohoon Cha 416daca9c6 fix(tui): close completion dialog on ctrl+h (#1005) 2025-07-15 06:24:05 -05:00
Aiden Cline 636fe0fb64 Fix: failed to open session (#999) 2025-07-15 05:40:29 -05:00
Frank 95e0957d64 wip: github actions 2025-07-15 17:45:16 +08:00
Dax Raad 2eefdae6a9 ignore: fix types 2025-07-15 00:56:03 -04:00
Dax Raad d62746ceb7 fix panic
publish / publish (push) Has been cancelled
2025-07-15 00:35:02 -04:00
Dax Raad 4b2ce14ff3 bring back task tool
publish / publish (push) Has been cancelled
2025-07-15 00:05:54 -04:00
Jase Kraft 294a11752e fix: --continue pull the latest session id consistently (#918)
Co-authored-by: Dax Raad <d@ironbay.co>
2025-07-14 20:32:00 -04:00
Dax Raad 1cf1d1f634 docs: fix agents.md 2025-07-14 20:23:05 -04:00
Ryan Roden-Corrent 2ce694d41f Add support for job-control suspend (ctrl+z/SIGSTP). (#944) 2025-07-14 20:13:46 -04:00
CodinCat d6eff3b3a3 improve error handling and logging for GitHub API failures in upgrade and install script (#972) 2025-07-14 20:13:12 -04:00
Dax Raad e63a6d45c1 docs: README 2025-07-14 20:10:43 -04:00
Dax Raad 93686519ba docs: README 2025-07-14 20:06:15 -04:00
Mike Wallio f593792fb5 Standardize parameter description references in Edit and MultiEdit tools (#984) 2025-07-14 20:03:59 -04:00
Dax Raad 2cdb37c32b support anthropic console login flow 2025-07-14 18:07:55 -04:00
Timo Clasen 535d79b64c docs: fix typo (#982) 2025-07-14 16:40:16 -04:00
Dax Raad b4e4c3f662 wip: snapshot 2025-07-14 15:29:08 -04:00
adamdotdevin ba676e7ae0 fix(tui): support readline nav in new search component
publish / publish (push) Has been cancelled
2025-07-14 12:20:58 -05:00
adamdotdevin a1c8e5af45 chore: use new search component in find dialog 2025-07-14 12:15:47 -05:00
adamdotdevin f1e7e7c138 feat(tui): even better model selector 2025-07-14 12:15:46 -05:00
Dax Raad 80b77caec0 ignore: share page fix 2025-07-14 13:13:33 -04:00
Dorian Karter 86a2ea44b5 feat(tui): add support for readline list nav (ctrl-p/ctrl-n) (#955) 2025-07-14 10:21:09 -05:00
Dax Raad a2002c88c6 wip: update sdk
publish / publish (push) Has been cancelled
2025-07-14 11:18:08 -04:00
opencode-agent[bot] d8bcf4f4e7 Fix issue: Option to update username shown in conversations. (#975)
Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com>
Co-authored-by: thdxr <thdxr@users.noreply.github.com>
2025-07-14 11:03:04 -04:00
Dax Raad 31e0326f78 fix init command and escape to cancel
publish / publish (push) Has been cancelled
2025-07-14 10:48:17 -04:00
adamdotdevin a53d2ea356 fix(tui): build and bg color 2025-07-14 09:14:02 -05:00
adamdotdevin 229a280652 fix(tui): find dialog bg color 2025-07-14 09:09:55 -05:00
Nicholas Hamilton 8d0350d923 feat: ability to create new session from session dialog (#920) 2025-07-14 09:04:43 -05:00
Almir Sarajčić 4192d7eacc Fix failing git hooks (#966) 2025-07-14 07:52:29 -05:00
Munawwar Firoz 7b8b4cf8c7 feat: ctrl+left arrow / ctrl+right arrow key support (#969) 2025-07-14 07:16:06 -05:00
Almir Sarajčić 1f4de75348 Explain usage of external references in AGENTS.md (#965) 2025-07-14 07:06:37 -05:00
GitHub Action 457755c690 ignore: update download stats 2025-07-14 2025-07-14 12:04:16 +00:00
Aiden Cline 052a1e7514 fix: file command visual bug (#959) 2025-07-14 07:03:02 -05:00
Daniel Nouri 139d6e2818 Fix clipboard on Wayland systems (#941)
Co-authored-by: Daniel Nouri <daniel@redhotcar>
2025-07-14 06:57:45 -05:00
Dax Raad 06554efdf4 get rid of cli markdown dep
publish / publish (push) Has been cancelled
2025-07-13 23:06:31 -04:00
Dax Raad 67e9bda94f ci
publish / publish (push) Has been cancelled
2025-07-13 22:58:33 -04:00
Dax Raad 53bb6b4c4f fix missing tokens
publish / publish (push) Has been cancelled
2025-07-13 22:56:29 -04:00
Dax Raad 73d54c7068 fix type error 2025-07-13 17:25:13 -04:00
Dax 90d6c4ab41 Part data model (#950) 2025-07-13 17:22:11 -04:00
opencode-agent[bot] 736396fc70 Added sharing config with auto/disabled options (#951)
Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com>
Co-authored-by: thdxr <thdxr@users.noreply.github.com>
2025-07-13 16:43:58 -04:00
Dax Raad 177bfed93e ci: github action 2025-07-13 16:22:58 -04:00
Dax Raad 91f8477ef5 wip: mcp 2025-07-13 16:22:16 -04:00
John Henry Rudden f04a5e50ee fix: deduplicate command suggestions (#934) 2025-07-13 14:47:26 -05:00
Aiden Cline bb28b70700 Fix: title generation (#949) 2025-07-13 14:46:36 -05:00
Frank 7361a02ef3 wip: github actions 2025-07-13 23:59:25 +08:00
GitHub Action d465f150fc ignore: update download stats 2025-07-13 2025-07-13 12:04:11 +00:00
Dax Raad 17fa8c117b fix packages being reinstalled on every start
publish / publish (push) Has been cancelled
2025-07-12 12:41:12 -04:00
Muzammil Khan 9aa0c40a00 feat: add more ignore patterns to the ls tool (#913) 2025-07-12 12:06:58 -04:00
GitHub Action fd4648da17 ignore: update download stats 2025-07-12 2025-07-12 12:03:59 +00:00
Dax Raad aadca5013a fix share page timestamps 2025-07-11 21:49:20 -04:00
Dax Raad 5c3d490e59 share page hide step-finish events 2025-07-11 21:45:56 -04:00
Dax Raad 1254f48135 fix issue preventing things from working when node_modules or package.json present in ~/
publish / publish (push) Has been cancelled
2025-07-11 21:09:39 -04:00
Dax Raad 1729c310d9 switch global config to ~/.config/opencode/opencode.json
publish / publish (push) Has been cancelled
2025-07-11 20:51:23 -04:00
Dax Raad 0130190bbd docs: add model docs 2025-07-11 20:33:06 -04:00
Aiden Cline 97a31ddffc tweak: plan interactions should match web (TUI) (#895) 2025-07-11 18:03:22 -04:00
zWing 3249420ad1 fix: avoid overwriting the provider.option.baseURL (#880) 2025-07-11 18:01:28 -04:00
Dax Raad 4bb8536d34 introduce cache version concept for auto cleanup when breaking cache changes happen
publish / publish (push) Has been cancelled
2025-07-11 17:50:49 -04:00
Jay c73d4a137e docs: Update troubleshooting.mdx 2025-07-11 17:50:25 -04:00
Dax Raad 57ac8f2741 wip: stats 2025-07-11 17:37:41 -04:00
Jay V 2f1acee5a1 docs: share page add time footer back
publish / publish (push) Has been cancelled
2025-07-11 14:24:20 -04:00
Jay V 9ca54020ac docs: share page mobile bugs 2025-07-11 14:24:20 -04:00
Jay V f7d44b178b docs: share fix mobile diffs 2025-07-11 14:24:20 -04:00
Sergii Kozak b4950a157c fix(session): add fallback for undefined output token limit (#860)
Co-authored-by: opencode <noreply@opencode.ai>
2025-07-11 10:55:13 -04:00
alexz dfbef066c7 fix: ENAMETOOLONG: name too long when adding custom mode (#881) 2025-07-11 10:54:52 -04:00
GitHub Action 26fd76fbee ignore: update download stats 2025-07-11 2025-07-11 12:04:08 +00:00
adamdotdevin 04769d8a26 fix(tui): help commands bg color 2025-07-11 06:03:21 -05:00
adamdotdevin 34b576d9b5 fix(tui): don't include /mode trigger 2025-07-11 06:01:51 -05:00
adamdotdevin 22b244f847 fix(tui): actually fix mouse ansi codes leaking 2025-07-11 06:00:20 -05:00
Aiden Cline 7e1fc275e7 fix: avoid worker exception, graceful 404 (#869) 2025-07-11 04:55:56 -05:00
Frank 3b9b391320 wip: github actions 2025-07-11 06:55:13 +08:00
Frank 766bfd025c wip: github actions 2025-07-11 05:23:24 +08:00
Jay V c7f30e1065 docs: share page fix terminal part 2025-07-10 17:21:21 -04:00
Frank 1c4fd7f28f Api: add endpoint for getting github app token 2025-07-11 05:01:27 +08:00
adamdotdevin 85805d2c38 fix(tui): handle SIGTERM, closes #319
publish / publish (push) Has been cancelled
2025-07-10 15:59:03 -05:00
Timo Clasen 982cb3e71a fix(tui): center help dilaog (#853) 2025-07-10 15:56:19 -05:00
adamdotdevin 294d0e7ee3 fix(tui): mouse wheel ansi codes leaking into editor 2025-07-10 15:49:58 -05:00
Jay V 8be1ca836c docs: fix diag styles 2025-07-10 16:38:51 -04:00
Jay V 2e5f96fa41 docs: share page attachment 2025-07-10 16:38:51 -04:00
Dax Raad c056b0add9 add step finish part
publish / publish (push) Has been cancelled
2025-07-10 16:25:38 -04:00
Dax Raad b00bb3c083 run: properly close session.list 2025-07-10 16:13:01 -04:00
Dax Raad d9befd3aa6 disable filewatcher, fixes file descriptor leak
publish / publish (push) Has been cancelled
2025-07-10 15:58:45 -04:00
Dax Raad 49de703ba1 config: escape file: string content
publish / publish (push) Has been cancelled
2025-07-10 15:38:58 -04:00
Dax Raad 22988894c8 ci: slow down stats 2025-07-10 15:31:06 -04:00
adamdotdevin 34b1754f25 docs: clipboard requirements on linux 2025-07-10 13:12:37 -05:00
adamdotdevin 54fe3504ba feat(tui): accent editor border on leader key 2025-07-10 12:57:22 -05:00
Jay V d2c862e32d docs: edit local models 2025-07-10 13:49:24 -04:00
Jay V afc53afb35 docs: edit mode 2025-07-10 13:29:37 -04:00
Gabriel Garrett b56e49c5dc Adds real example in docs of how to configure custom provider (#840) 2025-07-10 13:29:30 -04:00
Aiden Cline 8b2a909e1f fix: encode & decode file paths (#843) 2025-07-10 11:19:54 -05:00
Jay V e9c954d45e docs: add modes to sidebar 2025-07-10 12:07:44 -04:00
Jay V 6f449d13af docs: add modes to sidebar 2025-07-10 12:07:18 -04:00
Dax Raad 6e375bef0d docs: modes
publish / publish (push) Has been cancelled
2025-07-10 11:53:28 -04:00
Dax Raad 67106a6967 docs: add config variable docs 2025-07-10 11:48:55 -04:00
Dax Raad b5d690620d support env and file pointers in config 2025-07-10 11:45:31 -04:00
Dax Raad 9db3ce1d0b opencode run respects mode 2025-07-10 11:28:28 -04:00
Dax Raad 1cc55b68ef wip: scrap 2025-07-10 11:25:37 -04:00
Dax Raad 469f667774 set max output token limit to 32_000 2025-07-10 11:25:37 -04:00
adamdottv 6603d9a9f0 feat: --mode flag passed to tui 2025-07-10 10:19:25 -05:00
adamdottv 5dc1920a4c feat: mode flag in cli run command 2025-07-10 10:13:15 -05:00
adamdottv d3e5f3f3a8 feat(tui): add token and cost info to session header 2025-07-10 10:06:51 -05:00
adamdottv ce4cb820f7 feat(tui): modes 2025-07-10 10:06:51 -05:00
Dax Raad ba5be6b625 make LSP lazy again
publish / publish (push) Has been cancelled
2025-07-10 09:37:40 -04:00
adamdottv f95c3f4177 fix(tui): fouc in textarea on app load 2025-07-10 08:20:17 -05:00
adamdottv d2b1307bff fix(tui): textarea cursor sync issues with attachments 2025-07-10 07:49:36 -05:00
adamdottv b40ba32adc fix(tui): textarea issues 2025-07-10 07:38:57 -05:00
GitHub Action ce0cebb7d7 ignore: update download stats 2025-07-10 2025-07-10 12:04:15 +00:00
Dax Raad f478f89a68 temporary grok 4 patch
publish / publish (push) Has been cancelled
2025-07-10 07:57:55 -04:00
Dax Raad 85d95f0f2b disable lsp on non-git folders 2025-07-10 07:39:02 -04:00
Dax Raad 1515efc77c fix session is busy error
publish / publish (push) Has been cancelled
2025-07-10 07:27:03 -04:00
Josh Medeski 6d393759e1 feat(tui): subsitute cwd home path on status bar (#808) 2025-07-10 06:12:19 -05:00
Adi Yeroslav a1701678cd feat(tui): /editor - change the auto-send behavior to put content in input box instead (#827) 2025-07-10 05:57:52 -05:00
Timo Clasen c411a26d6f feat(tui): hide cost if using subscription model (#828) 2025-07-10 05:56:36 -05:00
adamdottv 85dbfeb314 feat(tui): @symbol attachments 2025-07-10 05:53:00 -05:00
Dax Raad 085c0e4e2b respect go.work when spawning LSP
publish / publish (push) Has been cancelled
2025-07-09 22:54:47 -04:00
Dax Raad 8404a97c3e better detection of prettier formatter
publish / publish (push) Has been cancelled
2025-07-09 22:37:31 -04:00
Dax Raad 0ee3b1ede2 do not wait for LSP to be fully ready
publish / publish (push) Has been cancelled
2025-07-09 21:59:38 -04:00
Dax Raad a826936702 modes concept 2025-07-09 21:59:38 -04:00
Jay V fd4a5d5a63 docs: share doc edit 2025-07-09 20:26:31 -04:00
Jay V 69cf1d7b7e docs: share doc 2025-07-09 20:24:09 -04:00
Jay V 8e0a1d1167 docs: edit troubleshooting 2025-07-09 19:55:14 -04:00
Timo Clasen f22021187d feat(tui): treat pasted text file paths as file references (#809) 2025-07-09 18:37:39 -05:00
Jay V febecc348a docs: enterprise doc 2025-07-09 15:46:57 -04:00
Jay V c5ccfc3e94 docs: share page last part fix 2025-07-09 15:46:57 -04:00
Mike Wallio 1f6efc6b94 Add gpt-4.1 beast prompt (#778)
publish / publish (push) Has been cancelled
Co-authored-by: Dax Raad <d@ironbay.co>
2025-07-09 12:11:54 -04:00
Frank Denis 727fe6f942 LSP: fix SimpleRoots to actually search in the root directory (#795) 2025-07-09 10:35:06 -05:00
Dax Raad a91e79382e ci: remove checked in config.schema.json 2025-07-09 11:30:42 -04:00
Dax Raad 5c626e0a2f ci: generate config schema as part of build 2025-07-09 11:25:58 -04:00
adamdottv 8e9e383219 chore: troubleshooting docs 2025-07-09 10:12:36 -05:00
Dax Raad f383008cc1 lsp: spawn only a single tsserver in project root
publish / publish (push) Has been cancelled
2025-07-09 11:06:44 -04:00
adamdottv 303ade25ed feat: discord redirect 2025-07-09 10:01:42 -05:00
adamdottv 53f8e7850e feat: configurable log levels 2025-07-09 10:00:03 -05:00
adamdottv ca8ce88354 feat(tui): move logging to server logs 2025-07-09 08:16:10 -05:00
adamdottv 37a86439c4 fix(tui): don't panic on missing linux clipboard tool 2025-07-09 06:51:58 -05:00
adamdottv 269b43f4de fix(tui): markdown wrapping off sometimes 2025-07-09 06:41:53 -05:00
adamdottv 3f25e5bf86 chore: internal clipboard package 2025-07-09 04:55:24 -05:00
Aiden Cline 67765fa47c tweak: keep completion options open when trigger is still present (#789) 2025-07-09 04:42:31 -05:00
adamdottv 58b1c58bc5 fix(tui): clear command priority
publish / publish (push) Has been cancelled
2025-07-08 19:26:50 -05:00
Dax Raad d80badc50f ci: ignore chore commits 2025-07-08 20:05:33 -04:00
Dax Raad 75279e5ccf wip: symbols endpoint 2025-07-08 20:05:33 -04:00
Yihui Khuu 7893b84614 Add debounce before exit when using non-leader exit command (#759) 2025-07-08 18:53:38 -05:00
Dax Raad cfc715bd48 wip: remove excess import
publish / publish (push) Has been cancelled
2025-07-08 19:51:09 -04:00
adamdottv 39bcba85a9 chore: vendor clipboard into go package 2025-07-08 18:48:40 -05:00
adamdottv da3df51316 chore: remove clipboard temp 2025-07-08 18:47:59 -05:00
adamdottv 12190e4efc chore: vendor clipboard into go package 2025-07-08 18:46:42 -05:00
Aiden Cline d2a9b2f64a fix: documentation typo (#781) 2025-07-08 18:30:46 -05:00
adamdottv aacadd8a8a fix(tui): panic when reading/writing clipboard on linux 2025-07-08 18:29:45 -05:00
Jay V 969154a473 docs: share page image 2025-07-08 19:24:21 -04:00
Jay V 4d6ca3fab1 docs: share page many model case 2025-07-08 19:08:33 -04:00
Dax Raad 00ea5082e7 add typescript lsp timeout if it fails to start
publish / publish (push) Has been cancelled
2025-07-08 18:33:12 -04:00
Dax Raad 4a878b88c0 properly load typescript lsp in subpaths
publish / publish (push) Has been cancelled
2025-07-08 18:18:45 -04:00
Dax Raad 6de955847c big rework of LSP system 2025-07-08 18:14:49 -04:00
Jay V 3ba5d528b4 docs: share bugs 2025-07-08 18:14:36 -04:00
Jay V f99e2b3429 docs: share error part 2025-07-08 18:00:08 -04:00
Jay V 7e4e6f6e51 docs: share page bugs 2025-07-08 17:18:38 -04:00
Jay V 0514f3f43b docs: share image model 2025-07-08 17:18:38 -04:00
Timo Clasen 1e07384364 fix: make compact command interruptible (#691)
publish / publish (push) Has been cancelled
Co-authored-by: GitHub Action <action@github.com>
2025-07-08 15:37:25 -05:00
strager 4c4739c422 fix(tool): fix ripgrep invocation on Windows (#700)
Co-authored-by: Adam <2363879+adamdotdevin@users.noreply.github.com>
2025-07-08 15:36:26 -05:00
Rami Chowdhury 2d8b90a6ff feat(storage): ensure storage directory exists and handle paths correctly (#771) 2025-07-08 15:34:11 -05:00
Robb Currall a2fa7ffa42 fix: support cancelled task state (#775) 2025-07-08 15:33:39 -05:00
Frank Denis f7d6175283 Add support for the Zig Language Server (ZLS) (#756) 2025-07-08 15:31:11 -05:00
Tommy 9ed187ee52 docs: add terminal requirements (#708) 2025-07-08 15:30:05 -05:00
Gal Schlezinger 14d81e574b [config json schema] declare default values and examples for in-ide documentation (#754) 2025-07-08 15:29:07 -05:00
adamdottv 6efe8cc8df fix: env has to be string
publish / publish (push) Has been cancelled
2025-07-08 14:59:03 -05:00
adamdottv daa5fc916a fix(tui): pasting causes panic on macos 2025-07-08 14:57:17 -05:00
adamdottv c659496b96 fix(tui): model/provider arg parsing 2025-07-08 14:11:57 -05:00
Timo Clasen 21fbf21cb6 fix(copilot): add vision request header (#773) 2025-07-08 14:01:54 -05:00
adamdottv f31cbf2744 fix: image reading
publish / publish (push) Has been cancelled
2025-07-08 13:02:13 -05:00
Aiden Cline 8322f18e03 fix: display errors when using opencode run ... (#751) 2025-07-08 10:38:11 -05:00
adamdottv 562bdb95e2 fix: include symlinks in ripgrep searches 2025-07-08 10:02:19 -05:00
Dax a57ce8365d Update STATS.md 2025-07-08 10:30:02 -04:00
adamdottv 0da83ae67e feat(tui): command aliases 2025-07-08 08:20:55 -05:00
adamdottv 662d022a48 feat(tui): paste images and pdfs 2025-07-08 08:09:01 -05:00
GitHub Action 9efef03919 ignore: update download stats 2025-07-08 2025-07-08 12:04:27 +00:00
GitHub Action 7a9fb3fa92 ignore: update download stats 2025-07-08 2025-07-08 10:51:06 +00:00
adamdottv ea96ead346 feat(tui): handle --model and --prompt flags 2025-07-08 05:50:18 -05:00
Dax Raad 6100a77b85 start file watcher only for tui 2025-07-07 21:05:04 -04:00
Dax Raad c7a59ee2b1 better handling of aborting sessions
publish / publish (push) Has been cancelled
2025-07-07 20:59:00 -04:00
Jay V a272b58fe9 docs: intro 2025-07-07 17:41:46 -04:00
Dax Raad 9948fcf1b6 fix crash when running on new project
publish / publish (push) Has been cancelled
2025-07-07 17:39:52 -04:00
Dax Raad 0d50c867ff fix mcp tools corrupting session
publish / publish (push) Has been cancelled
2025-07-07 17:05:16 -04:00
Dax Raad 27f7e02f12 run: truncate prompt 2025-07-07 16:41:42 -04:00
Jay V 0f93ecd564 docs: canonical url 2025-07-07 16:37:00 -04:00
Dax Raad da909d9684 append piped stdin to prompt
publish / publish (push) Has been cancelled
2025-07-07 16:33:21 -04:00
Jay V facd851b11 docs: dynamic domain 2025-07-07 16:31:15 -04:00
Dax Raad c51de945a5 Add stdin support to run command
Allow piping content to opencode run when no message arguments are provided, enabling standard Unix pipe patterns for better CLI integration.

🤖 Generated with [opencode](https://opencode.ai)

Co-Authored-By: opencode <noreply@opencode.ai>
2025-07-07 16:29:13 -04:00
Jay V 9253a3ca9e docs: debug 2025-07-07 16:26:23 -04:00
Dax Raad 7cfa297a78 wip: model and prompt flags for tui 2025-07-07 16:24:37 -04:00
Jay V 661b74def6 docs: debug info 2025-07-07 16:13:26 -04:00
Dax Raad b478e5655c fix interrupt
publish / publish (push) Has been cancelled
2025-07-07 16:12:47 -04:00
Dax f884766445 v2 message format and upgrade to ai sdk v5 (#743)
publish / publish (push) Has been cancelled
Co-authored-by: GitHub Action <action@github.com>
Co-authored-by: Liang-Shih Lin <liangshihlin@proton.me>
Co-authored-by: Dominik Engelhardt <dominikengelhardt@ymail.com>
Co-authored-by: Jay V <air@live.ca>
Co-authored-by: adamdottv <2363879+adamdottv@users.noreply.github.com>
2025-07-07 15:53:43 -04:00
Jay V 76b2e4539c docs: discord
publish / publish (push) Has been cancelled
2025-07-07 14:44:37 -04:00
Dominik Engelhardt d87922c0eb Fix Elixir LSP startup (#726) 2025-07-06 23:37:46 -04:00
Liang-Shih Lin 2446483df5 fix: Skip opencode upgrade if same version (#720) 2025-07-06 23:36:59 -04:00
GitHub Action f4c453155d Update download stats 2025-07-06 2025-07-06 12:03:56 +00:00
Dax Raad 969ad80ed2 fix openrouter caching with anthropic, should be a lot cheaper 2025-07-05 11:39:54 -04:00
GitHub Action af064b41d7 Update download stats 2025-07-05 2025-07-05 12:03:56 +00:00
Dax Raad ea6bfef21a use full filepath
publish / publish (push) Has been cancelled
2025-07-04 17:58:03 -04:00
Jay V 107363b1d9 docs: fix show more in share page 2025-07-04 17:57:12 -04:00
Dax Raad 85214d7c59 fix input bar not rendering capital letters
publish / publish (push) Has been cancelled
2025-07-04 17:21:51 -04:00
Timo Clasen 997cb2d945 fix(tui): optimistic rendering (#692) 2025-07-04 16:06:57 -05:00
Dax Raad 45b139390c make file attachments work good like
publish / publish (push) Has been cancelled
2025-07-04 16:21:26 -04:00
Jay V 994368de15 docs: share fix scrolling again 2025-07-04 13:53:25 -04:00
Jay V 143fd8e076 docs: share improve markdown rendering of ai responses 2025-07-04 13:53:25 -04:00
Dax Raad 06dba28bd6 wip: fix media type 2025-07-04 12:50:52 -04:00
adamdottv b8d276a049 fix(tui): full paths for attachments 2025-07-04 11:42:22 -05:00
Dax Raad ee01f01271 file attachments 2025-07-04 12:24:01 -04:00
adamdottv 32d5db4f0a fix(tui): markdown wrapping off sometimes 2025-07-04 11:16:38 -05:00
adamdottv f6108b7be8 fix(tui): handle pdf and image @ files 2025-07-04 11:13:09 -05:00
adamdottv 94ef341c9d feat(tui): render attachments 2025-07-04 10:55:02 -05:00
adamdottv f9abc7c84f feat(tui): file attachments 2025-07-04 10:55:02 -05:00
adamdottv 891ed6ebc0 fix(tui): slower startup due to file.status 2025-07-04 10:55:01 -05:00
Dax Raad 163e23a68b removed banned command concept 2025-07-04 11:32:12 -04:00
Vladimir f13b0af491 docs: Fix invalid json in the mcp example config (#645) 2025-07-04 11:24:13 -04:00
Aiden Cline 4a0be45d3d chore: document instructions configuration option (#670) 2025-07-04 11:22:45 -04:00
Dax Raad 23788674c8 disable snapshots temporarily
publish / publish (push) Has been cancelled
2025-07-04 08:45:18 -04:00
GitHub Action 121eb24e73 Update download stats 2025-07-04 2025-07-04 12:26:16 +00:00
Dax Raad 571d60182a improve snapshotting speed further
publish / publish (push) Has been cancelled
2025-07-03 21:36:09 -04:00
Jay V 167a9dcaf3 docs: share fix scroll to anchor 2025-07-03 20:30:21 -04:00
Dax Raad 37327259cb ci: ignore 2025-07-03 20:30:02 -04:00
Dax Raad cdb25656d5 improve snapshot speed
publish / publish (push) Has been cancelled
2025-07-03 20:16:25 -04:00
Jay V 25c876caa2 docs: share fix last message not expandable 2025-07-03 19:33:55 -04:00
Dax Raad cf83e31f23 add elixir lsp support
publish / publish (push) Has been cancelled
2025-07-03 19:29:51 -04:00
Dax Raad 3bc238b58b wip: logs 2025-07-03 19:29:51 -04:00
Jay V b8de69dced docs: fix share page scroll performance 2025-07-03 19:15:38 -04:00
Jay V e7fcb692a4 docs: tweak page title 2025-07-03 16:23:08 -04:00
Timo Clasen dae38574ab chore: add dev script (#666) 2025-07-03 14:43:25 -05:00
Dax Raad ed4f862b49 fix /unshare
publish / publish (push) Has been cancelled
2025-07-03 15:34:04 -04:00
adamdottv fce59db94a chore: simplify completions 2025-07-03 12:48:22 -05:00
Jay V 3e2a0c7281 docs: share handle slow loading pages 2025-07-03 13:15:21 -04:00
adamdottv 5a0910ea79 chore: better local dev with stainless script 2025-07-03 11:49:15 -05:00
adamdottv 1dffabcfda fix(tui): panic on completions failure
publish / publish (push) Has been cancelled
2025-07-03 10:53:43 -05:00
adamdottv c389e0ed43 fix(tui): redundant tool calls in each message in collapsed mode
publish / publish (push) Has been cancelled
2025-07-03 10:42:27 -05:00
Dax Raad 204801052a flag for disabling file watcher 2025-07-03 10:37:08 -04:00
Dax Raad 2528d8cb88 increase max retries to 10
publish / publish (push) Has been cancelled
2025-07-03 10:32:55 -04:00
adamdottv 6b73ffd1c1 fix(tui): include orphaned tool calls 2025-07-03 09:32:44 -05:00
adamdottv 0eadc50a33 fix(tui): selected message visuals 2025-07-03 09:03:04 -05:00
Dax Raad aeea84a877 fix webdomain 2025-07-03 09:58:25 -04:00
GitHub Action a54c5c6298 Update download stats 2025-07-03 2025-07-03 12:26:51 +00:00
adamdottv 8825cd3811 feat(tui): unshare command
publish / publish (push) Has been cancelled
2025-07-03 07:09:09 -05:00
adamdottv 3d9a5d9970 fix(tui): always show status bar 2025-07-03 06:53:05 -05:00
adamdottv 1f9e195fa6 fix(tui): better highlight visuals 2025-07-03 06:49:37 -05:00
Craig Andrews 73c012c76c fix: simplify parallel map using channels (#582) 2025-07-03 05:43:10 -05:00
Lev 2ace57404b fix: properly handle utf-8 in diff highlighting (#585) 2025-07-03 05:42:40 -05:00
Dax Raad 8c4b5e088b do not install gopls if go is not installed
publish / publish (push) Has been cancelled
2025-07-02 23:59:08 -04:00
Jacob Hands 69920a73d7 fix: use correct opencode bin path when running in development mode (#483)
publish / publish (push) Has been cancelled
2025-07-02 23:37:48 -04:00
Timo Clasen ae76a3467a fix: typescript error (#618) 2025-07-02 23:27:43 -04:00
Adi Yeroslav 701107cda4 Update prompt reference from CLAUDE.md to AGENTS.md (#623) 2025-07-02 23:27:22 -04:00
Aiden Cline b99565959b feat: configurable instructions (#624) 2025-07-02 23:27:04 -04:00
andrewxt 67aa7ce04d fix mouse scroll events being interpreted as keyboard input (#628) 2025-07-02 23:26:09 -04:00
Dax Raad c663fbc3ee remove need for glibc
publish / publish (push) Has been cancelled
2025-07-02 22:53:04 -04:00
Dax Raad 2090bab537 fix(tui): change messages layout toggle keybinding from <leader>m to <leader>p
publish / publish (push) Has been cancelled
🤖 Generated with [opencode](https://opencode.ai)

Co-Authored-By: opencode <noreply@opencode.ai>
2025-07-02 20:06:30 -04:00
Aiden Cline 64d5fff9a3 fix: unawaited promise causes opencode to use unenabled formatter (#625)
publish / publish (push) Has been cancelled
2025-07-02 19:19:31 -04:00
Jay V 925f695503 docs: tweak styles 2025-07-02 18:44:05 -04:00
adamdottv f1c925795d fix: typescript error 2025-07-02 16:08:41 -05:00
adamdottv c82a060eca feat(tui): file viewer, select messages 2025-07-02 16:08:11 -05:00
Ciaran McAleer 63e783ef79 Changed handling of OpenRouter requests to add some custom headers so that it can see the app (#613)
Co-authored-by: Dax Raad <d@ironbay.co>
2025-07-02 14:43:59 -04:00
Dax Raad 35d6273fb3 wip: session revert/unrevert 2025-07-02 13:10:36 -04:00
Mark Huggins b89d4a16fd fix: Copilot Premium Requests (#595) 2025-07-02 12:04:53 -04:00
Prashant Choudhary 2799a96032 fix: Ensure shared file previews use truncated content (#607)
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2025-07-02 12:04:10 -04:00
Timo Clasen 8f4b79227c fix(formatting): check for enabled formatters (#611) 2025-07-02 12:03:42 -04:00
Dax Raad c810b6d206 wip: symbols for lsp 2025-07-02 11:35:25 -04:00
Dax Raad fa35407572 fix lazy loading 2025-07-02 11:18:25 -04:00
Dax Raad 8bbbc07aff fix filewatcher not closing cleanly
publish / publish (push) Has been cancelled
2025-07-02 11:15:12 -04:00
GitHub Action 75a21ba3ce Update download stats 2025-07-02
publish / publish (push) Has been cancelled
2025-07-02 12:26:24 +00:00
Timo Clasen 0d6fb68a88 fix(tui): no space between agent and user message (#598) 2025-07-02 05:12:49 -05:00
Jean du Plessis 242b886434 fix: Small typo in CLI --model flag description (#577) 2025-07-02 05:10:58 -05:00
Daniel Vélez caf465a9da chore: rename OpenCode to opencode (#579) 2025-07-02 05:09:51 -05:00
Dax Raad bbf77c6139 improve ripgrep download
publish / publish (push) Has been cancelled
2025-07-01 22:39:17 -04:00
Dax Raad 53b7e04b86 ci: tweaks 2025-07-01 22:25:53 -04:00
Dax Raad 9e75e3ed18 ignore: read deleted files 2025-07-01 20:45:50 -04:00
Dax Raad 6389858d41 ignore: add file status command 2025-07-01 20:44:12 -04:00
Dax Raad 7e5941e14b ignore: add file status command 2025-07-01 20:39:43 -04:00
Dax Raad c68aeed8d9 ignore: fix file read with diff 2025-07-01 20:08:42 -04:00
Aiden Cline b199a609a8 fix: handle null case if tool args are empty for todos (#588) 2025-07-01 18:25:23 -05:00
Frank 4a5a93b3f8 Temporarily add admin unshare api 2025-07-01 18:57:08 -04:00
Dax Raad e99bdcefac fix write tool timeout
publish / publish (push) Has been cancelled
2025-07-01 13:50:57 -04:00
Dax Raad 26dcb85de1 add file watcher 2025-07-01 13:45:25 -04:00
Dax Raad 11d042be25 snapshot functionality 2025-07-01 12:28:34 -04:00
adamdottv 33b5fe236a fix(tui): better message rendering performance
publish / publish (push) Has been cancelled
2025-07-01 07:57:45 -05:00
GitHub Action d56991006c Update download stats 2025-07-01 2025-07-01 12:27:09 +00:00
adamdottv 739a9f71c3 fix(tui): layout issues 2025-07-01 06:41:39 -05:00
Adam Spiers aef81fce0b docs: use correct baseUrl for astro editLink (#507)
Co-authored-by: Adam Spiers <opencode@adamspiers.org>
2025-07-01 05:31:18 -05:00
Timo Clasen 8f3d7b4038 feat: better model dialog with sorting by release date (#563) 2025-07-01 05:28:32 -05:00
Dax Raad de15e67834 fix lsp diagnostic accurancy
publish / publish (push) Has been cancelled
2025-06-30 22:48:32 -04:00
Dax Raad fea56d8de6 fix loading api key from env for openai compatible providers
publish / publish (push) Has been cancelled
2025-06-30 19:07:51 -04:00
Max Rabin 3d71be2b45 Add pyright lsp for Python (#551)
Co-authored-by: Max Rabin <max.rabin@mobileye.com>
2025-06-30 18:17:47 -04:00
adamdottv 58baca2a5b chore: typescript error 2025-06-30 15:46:18 -05:00
adamdottv ef73926db6 chore: include model release date 2025-06-30 15:46:18 -05:00
Dax Raad 9ad1687f04 optimistically boot lsp servers 2025-06-30 16:45:26 -04:00
Jeremy Mack c573270e66 chore: remove duplicate EditTool in TOOLS array (#556) 2025-06-30 15:32:15 -04:00
Dax Raad 9ebad68274 fix bash tool extra line 2025-06-30 15:31:30 -04:00
Dax Raad 03664ba588 fix formatting of bash tools
publish / publish (push) Has been cancelled
2025-06-30 15:28:59 -04:00
adamdottv 5a107b275c fix(tui): layout issues
publish / publish (push) Has been cancelled
2025-06-30 14:04:56 -05:00
Dax Raad dd5736fe5f add back in file hierarchy in system prompt but limit to 200 items
publish / publish (push) Has been cancelled
2025-06-30 14:46:46 -04:00
adamdottv 9f3ba03965 chore: rework layout primitives
publish / publish (push) Has been cancelled
2025-06-30 12:29:29 -05:00
Timo Clasen d090c08ef0 feat: update user and agent messages width and alignment (#515)
Co-authored-by: adamdottv <2363879+adamdottv@users.noreply.github.com>
2025-06-30 11:57:56 -05:00
Dmytro Yankovskyi 68e82e4d94 fix(#467): more granular bedrock modelID based on aws region (#482) 2025-06-30 11:12:30 -04:00
Dax Raad a4aa0e6f8d docs: readme 2025-06-30 10:56:38 -04:00
GitHub Action 8c1ae2717c Update download stats 2025-06-30 2025-06-30 12:26:30 +00:00
Dax Raad 72d48759d7 add ruby formatter and lsp 2025-06-29 22:00:08 -04:00
Timo Clasen 986144b377 docs: how to disable mcp server (#543)
publish / publish (push) Has been cancelled
Co-authored-by: GitHub Action <action@github.com>
2025-06-29 21:33:30 -04:00
Dax Raad 1fdb326aa7 ignore: refactoring 2025-06-29 21:30:23 -04:00
Dax Raad 463257e7e4 add zig, python, clang, and kotlin formatters
Co-authored-by: Suhas-Koheda <Suhas-Koheda@users.noreply.github.com>
Co-authored-by: Polo123456789 <Polo123456789@users.noreply.github.com>
Co-authored-by: theodore-s-beers <theodore-s-beers@users.noreply.github.com>
Co-authored-by: TylerHillery <TylerHillery@users.noreply.github.com>
2025-06-29 21:27:35 -04:00
Dax Raad 0f41e60bd6 restructure formatters 2025-06-29 21:22:21 -04:00
Polo123456789 7df81f7b3e Formatters as plugins (#487) 2025-06-29 21:13:32 -04:00
Adam Spiers dd22cb2bb0 chore: add .editorconfig (#536)
Co-authored-by: Adam Spiers <opencode@adamspiers.org>
2025-06-29 21:12:58 -04:00
Dax Raad 248325925f fix issue with costs resetting once chat is completed
publish / publish (push) Has been cancelled
2025-06-29 19:43:03 -04:00
Dax Raad ca48a4f0fb better amazon bedrock caching with anthropic models
publish / publish (push) Has been cancelled
2025-06-29 19:27:07 -04:00
Dax 98ee5a3d87 Update STATS.md 2025-06-29 13:04:44 -04:00
GitHub Action 67480e5a1c Update download stats 2025-06-29 2025-06-29 12:23:40 +00:00
GitHub Action 2581a9b54c Update download stats 2025-06-29 2025-06-29 02:00:18 +00:00
Dax Raad 14a293e124 ci: stats 2025-06-28 21:59:14 -04:00
Dax Raad 780419ecae ci: daily stats script 2025-06-28 21:57:46 -04:00
Timo Clasen f0962e2d9c Add Option to Disable MCP Servers (#513) 2025-06-28 21:05:31 -04:00
Dax Raad 3a9584a419 fix context display
publish / publish (push) Has been cancelled
2025-06-28 21:01:53 -04:00
adamdottv 196f42cbff fix(tui): share command and error messages
publish / publish (push) Has been cancelled
2025-06-28 17:51:28 -05:00
Dax Raad 322385f6b1 patch for scroll dumping characters into input buffer
publish / publish (push) Has been cancelled
2025-06-28 11:56:47 -04:00
Dax Raad b7446cd7b9 ci: fix
publish / publish (push) Has been cancelled
2025-06-28 09:16:29 -04:00
Gal Schlezinger f618e569ab optimize edit-tool rendering (#463)
publish / publish (push) Has been cancelled
Co-authored-by: opencode <noreply@opencode.ai>
Co-authored-by: Adam <2363879+adamdotdevin@users.noreply.github.com>
2025-06-28 06:01:10 -05:00
Jay V 7b394b91e2 docs: share handle slower code blocks 2025-06-27 20:21:28 -04:00
Jay V 6a7983a4ea docs: adding more share images 2025-06-27 20:03:17 -04:00
Jay V 737146fca1 docs: tweak logo 2025-06-27 19:18:54 -04:00
Jay V 688f3fd12f Merge branch 'jeremyosih-feat/scroll-to-bottom-button' into dev 2025-06-27 19:16:46 -04:00
Jay V 145df08444 docs: share page format 2025-06-27 19:16:33 -04:00
Dax Raad 8b400515ea smooth out initial onboarding flow 2025-06-27 19:10:42 -04:00
Jay V 289797f56d docs: share cleanup title 2025-06-27 19:10:42 -04:00
adamdottv be0811ecc3 chore: rework openapi spec and use stainless sdk 2025-06-27 19:10:42 -04:00
Dax Raad 0676bcd4fd temporary patch for input lag on initial run 2025-06-27 19:10:42 -04:00
Polo123456789 d076def561 feat: Add golang file formatting (#474) 2025-06-27 19:10:42 -04:00
Wendell Misiedjan e0807d7317 fix: bunproc stdout / stderr parsing, error handling for bun ResolveMessage (#468) 2025-06-27 19:10:42 -04:00
Jay V fa2723f2d0 docs: update logo screenshot 2025-06-27 19:10:42 -04:00
Jay V 87d62514db docs: share page write tool bug 2025-06-27 19:10:42 -04:00
Dax Raad 2f8cf9146b ci: ignore 2025-06-27 19:10:42 -04:00
Dax Raad 8e0ec6b037 ci: aur 2025-06-27 19:10:42 -04:00
Dax Raad 6dc434cb83 ignore: cleanup 2025-06-27 19:10:42 -04:00
Dax Raad d972c27f03 lazy load formatters 2025-06-27 19:10:42 -04:00
Ryan Winchester 9e2bb63688 feat: add elixir file formatting (#458) 2025-06-27 19:10:42 -04:00
adamdottv 49053b66a9 fix(web): remove system prompts from share page 2025-06-27 19:10:42 -04:00
TheGoddessInari 47497aef07 scripts/hooks: Change shebang to universal /bin/sh (#453) 2025-06-27 19:10:41 -04:00
adamdottv 8455029de1 fix(tui): min width on user messages 2025-06-27 19:10:41 -04:00
Dax Raad 9f07f89384 fix formatting output going into tui 2025-06-27 19:10:41 -04:00
adamdottv d840d43e8f ignore: more metadata in app info 2025-06-27 19:10:41 -04:00
adamdottv 9ead2f3dfb fix: don't use prettier for langs it doesn't format 2025-06-27 19:10:41 -04:00
Dax Raad f3742ddbb8 ignore: run prettier 2025-06-27 19:10:41 -04:00
Dax Raad b61a841aa8 add auto formatting and experimental hooks feature 2025-06-27 19:10:41 -04:00
Jay V ebcf11e574 docs: lander tweak 2025-06-27 19:10:41 -04:00
Jay V 065f0aaddf docs: tweak lander 2025-06-27 19:10:41 -04:00
Dax Raad c0773dc7c5 smooth out initial onboarding flow 2025-06-27 16:09:59 -04:00
Jay V 1c3c74bd36 docs: share cleanup title 2025-06-27 15:31:21 -04:00
adamdottv 79bbf90b72 chore: rework openapi spec and use stainless sdk 2025-06-27 14:26:25 -05:00
Dax Raad 226a4a7f36 temporary patch for input lag on initial run
publish / publish (push) Has been cancelled
2025-06-27 14:36:03 -04:00
Polo123456789 df3b424830 feat: Add golang file formatting (#474) 2025-06-27 14:11:09 -04:00
Wendell Misiedjan 3cfd9d80bc fix: bunproc stdout / stderr parsing, error handling for bun ResolveMessage (#468) 2025-06-27 14:09:35 -04:00
Jay V e0553b8d2c docs: update logo screenshot 2025-06-27 14:04:09 -04:00
Jay V 391c837b37 docs: share page write tool bug 2025-06-27 13:25:15 -04:00
Dax Raad 5773d9d1a3 ci: ignore
publish / publish (push) Has been cancelled
2025-06-27 12:37:57 -04:00
Dax Raad ce611963c3 ci: aur
publish / publish (push) Has been cancelled
2025-06-27 12:29:13 -04:00
Dax Raad f865cacfb8 ignore: cleanup
publish / publish (push) Has been cancelled
2025-06-27 11:35:57 -04:00
Dax Raad 2ec0611f42 lazy load formatters 2025-06-27 11:33:37 -04:00
Ryan Winchester 334161a30e feat: add elixir file formatting (#458) 2025-06-27 10:15:11 -04:00
adamdottv dbb6e55226 fix(web): remove system prompts from share page 2025-06-27 06:48:44 -05:00
TheGoddessInari d0f9260559 scripts/hooks: Change shebang to universal /bin/sh (#453) 2025-06-27 07:40:22 -04:00
adamdottv d2176064e1 fix(tui): min width on user messages 2025-06-27 06:31:13 -05:00
Dax Raad ed8d277e49 fix formatting output going into tui
publish / publish (push) Has been cancelled
2025-06-27 07:29:41 -04:00
adamdottv 59b3268c64 ignore: more metadata in app info 2025-06-27 06:19:27 -05:00
adamdottv d043f67761 fix: don't use prettier for langs it doesn't format
publish / publish (push) Has been cancelled
2025-06-27 05:47:14 -05:00
Dax Raad 51bf193889 ignore: run prettier
publish / publish (push) Has been cancelled
2025-06-26 22:30:44 -04:00
Dax Raad f8b78f08b4 add auto formatting and experimental hooks feature
publish / publish (push) Has been cancelled
2025-06-26 22:17:08 -04:00
Jay V a4f32d602b docs: lander tweak 2025-06-26 19:47:58 -04:00
Jay V dc3dd21cf3 docs: tweak lander 2025-06-26 19:02:44 -04:00
Jeremy Osih b4c2fcccf5 Merge branch 'sst:dev' into feat/scroll-to-bottom-button 2025-06-27 00:41:20 +02:00
Jeremy Osih e950ad5306 feat(web): add scroll to last message button
Add intelligent floating scroll button for long conversations that:
- Only appears when scrolling down (direction-aware)
- Auto-hides after 3 seconds of inactivity
- Stays visible on hover to prevent accidental disappearance
- Uses consistent design patterns with repo styling
- Includes proper accessibility features

🤖 Generated with [opencode](https://opencode.ai)

Co-Authored-By: Jeremy Osih <osih.jeremy@gmail.com>
Co-Authored-By: opencode <noreply@opencode.ai>
2025-06-27 00:38:14 +02:00
Dax Raad 8ca713b737 disable task tool temporarily
publish / publish (push) Has been cancelled
2025-06-26 18:27:49 -04:00
Jay V 5b54554fd5 docs: edit theme doc 2025-06-26 17:56:31 -04:00
Dax Raad 4bc651f958 fix: improve JSON formatting and add piped output support for run command
🤖 Generated with [opencode](https://opencode.ai)

Co-Authored-By: opencode <noreply@opencode.ai>
2025-06-26 17:32:00 -04:00
Jay V 3b6976a9c8 Merge branch 'rekram1-node-chore/update-config-docs' into dev 2025-06-26 17:24:03 -04:00
Jay V 863d5c1e8e docs: editing rules 2025-06-26 17:23:52 -04:00
adamdottv 97e19e9677 fix(tui): editor styles were off 2025-06-26 17:22:21 -04:00
adamdottv b27851461f feat(tui): more themes 2025-06-26 17:22:21 -04:00
adamdottv 209687377a feat(tui): more themes 2025-06-26 17:22:21 -04:00
adamdottv 90face1c09 fix(tui): editor width issues 2025-06-26 17:22:21 -04:00
adamdottv 936e2ce48b feat(tui): show lsp diagnostics for edit and write tools 2025-06-26 17:22:21 -04:00
adamdottv 16ee8ee379 fix(tui): chat editor aesthetics 2025-06-26 17:22:21 -04:00
adamdottv ac39308dad fix(tui): visual issue with modal selected items in system theme 2025-06-26 17:22:21 -04:00
adamdottv 346b49219d chore: tui agents.md 2025-06-26 17:22:21 -04:00
Jay V d84c1f20c7 docs: social share 2025-06-26 17:22:17 -04:00
adamdottv dfb8777555 fix(tui): editor spinner colors 2025-06-26 17:21:53 -04:00
Jay V 008af18156 docs: share page responsive diff 2025-06-26 17:21:53 -04:00
adamdottv ab23167f80 docs: system theme 2025-06-26 17:21:53 -04:00
adamdottv b17ec46463 fix(tui): make opencode theme default 2025-06-26 17:21:53 -04:00
Adam 2e26b58d16 feat: default system theme (#419)
Co-authored-by: adamdottv <2363879+adamdottv@users.noreply.github.com>
2025-06-26 17:21:53 -04:00
Mike Wallio 31b56e5a05 Fix undefined is not an object (evaluating 'G.title') (#395) 2025-06-26 17:21:53 -04:00
Juhani Pelli 47c401cf25 fix: guard against large output limit causing infinite summarize loop (#399) 2025-06-26 17:21:53 -04:00
Dax Raad fab8dc9e6f more edit tool fixes 2025-06-26 17:21:53 -04:00
Dax Raad f39a2b1f16 integrate gemini-cli strategies for edit tool 2025-06-26 17:21:53 -04:00
Dax Raad 66830ced4e make edit tool more robust 2025-06-26 17:21:53 -04:00
Dax Raad 9d3fad754d ignore: typo 2025-06-26 17:21:53 -04:00
Dax Raad dcd3131f58 add output length errors 2025-06-26 17:21:53 -04:00
Dax Raad 3d02e07161 fix codex not working 2025-06-26 17:21:53 -04:00
Dax Raad 4dbc6a43a6 redirect uncaught errors to log file 2025-06-26 17:21:53 -04:00
adamdottv 5394b5188b fix(tui): editor styles were off
publish / publish (push) Has been cancelled
2025-06-26 15:12:26 -05:00
adamdottv 8e680b3957 feat(tui): more themes
publish / publish (push) Has been cancelled
2025-06-26 15:03:30 -05:00
adamdottv 1b8cd796d6 feat(tui): more themes 2025-06-26 14:54:32 -05:00
adamdottv 35fba793d0 fix(tui): editor width issues
publish / publish (push) Has been cancelled
2025-06-26 12:57:11 -05:00
adamdottv 5358d43b74 feat(tui): show lsp diagnostics for edit and write tools 2025-06-26 12:47:17 -05:00
adamdottv f777347bac fix(tui): chat editor aesthetics 2025-06-26 12:44:44 -05:00
adamdottv 17c8b914df fix(tui): visual issue with modal selected items in system theme
publish / publish (push) Has been cancelled
2025-06-26 12:33:06 -05:00
adamdottv 43b467dd12 chore: tui agents.md 2025-06-26 12:28:29 -05:00
Jay V 0e0770921e docs: social share 2025-06-26 13:21:42 -04:00
adamdottv 8edbb74352 fix(tui): editor spinner colors 2025-06-26 12:21:20 -05:00
Jay V e6bfa95758 docs: share page responsive diff 2025-06-26 13:06:41 -04:00
adamdottv e4120b6287 docs: system theme 2025-06-26 11:33:02 -05:00
adamdottv ccbc9e00f2 fix(tui): make opencode theme default 2025-06-26 11:32:25 -05:00
Adam 7d13baadc8 feat: default system theme (#419)
publish / publish (push) Has been cancelled
Co-authored-by: adamdottv <2363879+adamdottv@users.noreply.github.com>
2025-06-26 10:16:07 -05:00
rekram1-node 9acc83697f chore: document AGENTS.md 2025-06-26 08:28:06 -05:00
Mike Wallio db24bf87c0 Fix undefined is not an object (evaluating 'G.title') (#395)
publish / publish (push) Has been cancelled
2025-06-25 19:40:09 -04:00
Juhani Pelli f4c0d2d2fd fix: guard against large output limit causing infinite summarize loop (#399) 2025-06-25 19:39:51 -04:00
Dax Raad d240f4c676 more edit tool fixes
publish / publish (push) Has been cancelled
2025-06-25 19:22:54 -04:00
Dax Raad 9c90cdbe08 integrate gemini-cli strategies for edit tool
publish / publish (push) Has been cancelled
2025-06-25 17:56:14 -04:00
Dax Raad fc7af31fe5 make edit tool more robust
publish / publish (push) Has been cancelled
2025-06-25 17:10:48 -04:00
Dax Raad 2f8d23ec66 ignore: typo 2025-06-25 11:02:57 -04:00
Dax Raad 77ae3fb9b9 add output length errors 2025-06-25 11:02:09 -04:00
Dax Raad 4e7f6c47fd fix codex not working
publish / publish (push) Has been cancelled
2025-06-25 10:01:35 -04:00
Dax Raad 50469ed750 redirect uncaught errors to log file
publish / publish (push) Has been cancelled
2025-06-25 08:41:10 -04:00
Dax Raad aaab785493 better error message when bad directory is specified to start in 2025-06-24 22:28:25 -04:00
Dax Raad 9751937894 Enhance auth command with environment variable display and add models command
publish / publish (push) Has been cancelled
🤖 Generated with [opencode](https://opencode.ai)

Co-Authored-By: opencode <noreply@opencode.ai>
2025-06-24 22:24:55 -04:00
Dax Raad 0fc8dfc77e do not print error on ctrl+c during prompts 2025-06-24 22:09:43 -04:00
Dax Raad 81b7df61ec ci: bun lock 2025-06-24 21:14:32 -04:00
Dax Raad 8217b96d4a ci: fix type issue 2025-06-24 21:12:32 -04:00
Dax Raad 7dd0918d32 remove accidental opanai autoloader
publish / publish (push) Has been cancelled
2025-06-24 21:11:11 -04:00
Dax Raad 4b26b43855 added opencode serve command
publish / publish (push) Has been cancelled
2025-06-24 20:52:09 -04:00
Jay V 9d7cfda9fe docs: share page styles 2025-06-24 19:34:35 -04:00
Jay V a3cf18c905 docs: share page bash tool output 2025-06-24 19:28:51 -04:00
Aiden Cline 0b1a8ae699 fix: file completions replaced wrong text when paths overlap (#378) 2025-06-24 18:13:15 -05:00
Dax Raad eb70b1e5c8 docs: windows instructions
publish / publish (push) Has been cancelled
2025-06-24 18:54:59 -04:00
Dax Raad 00a3d818b6 ci: windows 2025-06-24 18:46:43 -04:00
Dax Raad 2384c7e734 ci: windows 2025-06-24 18:40:36 -04:00
Dax Raad 1bad3d9894 ci: windows 2025-06-24 18:27:57 -04:00
Dax Raad 4f715e66dc ci: windows 2025-06-24 18:13:15 -04:00
Dax ec001ca02f windows fixes (#374)
Co-authored-by: Matthew Glazar <strager.nds@gmail.com>
2025-06-24 18:05:04 -04:00
Jay a2d3b9f0c8 docs: Share page diff view improvements (#373) 2025-06-24 17:11:43 -04:00
Dax Raad 9cfb6ff964 ignore: revert
publish / publish (push) Has been cancelled
2025-06-24 14:59:27 -04:00
Dax Raad 6ed661c140 ci: upgrade bun 2025-06-24 14:42:25 -04:00
Dax Raad 9dc00edfc9 potential fix for failing to install provider package on first run 2025-06-24 14:33:35 -04:00
Jay V e063bf888e docs: share code blocks in markdown 2025-06-24 13:53:59 -04:00
Adam 6f18475428 feat: delete sessions (#362)
publish / publish (push) Has been cancelled
Co-authored-by: adamdottv <2363879+adamdottv@users.noreply.github.com>
2025-06-24 11:07:41 -05:00
Dax Raad 3664b09812 remove debug code writing to /tmp/message.json
publish / publish (push) Has been cancelled
2025-06-24 11:16:17 -04:00
Dax Raad 7050cc0ac3 ignore: fix type errors 2025-06-24 11:09:36 -04:00
Dax Raad 4d3d63294d externalize github copilot code 2025-06-24 10:42:19 -04:00
Tom 6bc61cbc2d feat(tui): add debounce logic to escape key interrupt (#169)
Co-authored-by: opencode <noreply@opencode.ai>
Co-authored-by: adamdottv <2363879+adamdottv@users.noreply.github.com>
2025-06-24 06:31:02 -05:00
Dax Raad 01d351bebe add HOMEBREW_NO_AUTO_UPDATE to brew upgrades
publish / publish (push) Has been cancelled
2025-06-23 20:36:08 -04:00
Dax Raad dbba4a97aa force use npm registry
publish / publish (push) Has been cancelled
2025-06-23 20:23:37 -04:00
GitMurf 0dc586faef fix: typescript error (any) from models (#347) 2025-06-23 18:44:57 -04:00
Dax Raad f19c6b05f2 glob tool should respect .gitignore
publish / publish (push) Has been cancelled
2025-06-23 17:37:32 -04:00
Dax Raad bc34f08333 bundle models.dev at build time and ignore refresh errors
publish / publish (push) Has been cancelled
2025-06-23 14:50:19 -04:00
Dax Raad b7ee16aabd ignore: remove opencode.json 2025-06-23 14:32:57 -04:00
Lucas Grzegorczyk ed1b0d97bf Fix project folder name starting with "-" in data (#323). Note old session data will still be in the old format in ~/.local/share/opencode/projects - you can remove the leading dash to recover the, 2025-06-23 14:31:51 -04:00
adamdottv 8d3b2fb821 feat(tui): optimistically render user messages
publish / publish (push) Has been cancelled
2025-06-23 12:30:20 -05:00
Jay V fa991920bc fix help copy 2025-06-23 13:00:24 -04:00
adamdottv 5e79e3d7a5 fix(tui): less incorrect escapingn of < and > 2025-06-23 11:32:32 -05:00
adamdottv 966015c9ae fix: overlay border color issues 2025-06-23 11:21:49 -05:00
adamdottv 61f057337a fix: markdown wrapping issue 2025-06-23 11:20:44 -05:00
adamdottv 0b261054a2 chore: unused import 2025-06-23 10:21:57 -05:00
adamdottv e2e481cbb5 docs: disabled_providers 2025-06-23 10:21:25 -05:00
GitMurf 5140e83012 feat(copilot): edit headers for better rate limit avoidance (#321) 2025-06-23 10:44:19 -04:00
Dax Raad 100d6212be more graceful mcp failures
publish / publish (push) Has been cancelled
2025-06-22 21:10:05 -04:00
Dax Raad f0e19a6542 aws autoload include more env vars 2025-06-22 20:16:10 -04:00
Dax Raad 00c4d4f9f8 fix double entry of github copilot in auth login
publish / publish (push) Has been cancelled
2025-06-22 19:13:25 -04:00
Martin Palma 6e6fe6e013 Add Github Copilot OAuth authentication flow (#305) 2025-06-22 19:11:37 -04:00
Dax Raad d05b60291e docs: contributing 2025-06-22 17:55:10 -04:00
adamdottv 5162361372 fix(tui): color contrast fixes for nord 2025-06-22 15:17:18 -05:00
adamdottv d271b9f75b fix(tui): help dialog visuals 2025-06-22 14:28:16 -05:00
Márk Magyar 333569bed3 ignore: fix typos and formatting (#294) 2025-06-22 14:26:46 -04:00
Tom 09b89fdb23 fix: resolve test failures by adding missing zod-openapi import (#301)
Co-authored-by: opencode <noreply@opencode.ai>
2025-06-22 14:25:02 -04:00
Tom 0e8c3359d1 combine stdout and stderr in bash tool output (#300)
Co-authored-by: opencode <noreply@opencode.ai>
Co-authored-by: Dax Raad <d@ironbay.co>
2025-06-22 14:24:35 -04:00
Adam 37e0a7050f fix(tui): mouse wheel escape codes leaking into input 2025-06-22 10:26:44 -05:00
adamdottv 774dcb6980 fix(tui): cleanup help dialog
publish / publish (push) Has been cancelled
2025-06-22 06:44:23 -05:00
phantomreactor 28bc49ad17 fix: invisible html tags and compact long delay (#304) 2025-06-22 06:29:04 -05:00
adamdottv dc1947838c fix(tui): cleanup modal visuals
publish / publish (push) Has been cancelled
2025-06-22 06:09:23 -05:00
adamdottv 3ea2daaa4c fix(tui): theme dialog visuals 2025-06-22 05:34:22 -05:00
Márk Magyar 137e964131 fix: session title generation (#293) 2025-06-21 14:32:11 -05:00
tyrellshawn 8efbe497fd Created a Theme inspired by the matrix (#285) 2025-06-21 07:29:49 -05:00
Thomas Meire 119d2d966c Add error handling on the calls to the server to debug issue #132 (#137) 2025-06-21 07:24:39 -05:00
Dax Raad 194415e785 footer clarifies it's showing context usage, not input token usage 2025-06-20 22:52:51 -04:00
Dax Raad 1684042fb6 huge optimization for token usage with anthropic
publish / publish (push) Has been cancelled
2025-06-20 22:43:04 -04:00
Dax Raad 59f0004d34 Add --method option to upgrade command for manual installation method selection
publish / publish (push) Has been cancelled
🤖 Generated with [opencode](https://opencode.ai)

Co-Authored-By: opencode <noreply@opencode.ai>
2025-06-20 20:48:23 -04:00
Dax Raad da35a64fa1 handle brew upgrades better 2025-06-20 20:27:23 -04:00
Dax Raad 460338ca53 make IDs more random
publish / publish (push) Has been cancelled
2025-06-20 17:39:59 -04:00
Saatvik Arya 53c18a64b4 docs: add API client generation instructions to README and AGENTS.md (#273) 2025-06-20 17:27:58 -04:00
Saatvik Arya b8144c5654 fix: return false for missing AWS_PROFILE in amazon-bedrock provider (#277) 2025-06-20 17:27:27 -04:00
adamdottv 9081e17fcc fix(tui): visual tweaks to themes
publish / publish (push) Has been cancelled
2025-06-20 15:49:51 -05:00
adamdottv ef3fd5900f docs: cleanup casing
publish / publish (push) Has been cancelled
2025-06-20 15:35:25 -05:00
adamdottv 453d690c11 docs: new themes docs 2025-06-20 15:31:38 -05:00
adamdottv c45be6a645 feat(tui): one dark theme 2025-06-20 15:14:23 -05:00
adamdottv 7b9b177088 feat(tui): kanagawa theme 2025-06-20 15:14:23 -05:00
adamdottv 3cee5b0470 feat(tui): gruvbox theme 2025-06-20 15:14:23 -05:00
adamdottv 9246d1c901 feat(tui): catppuccin theme 2025-06-20 15:14:22 -05:00
adamdottv cc12abc83e feat(tui): nord theme 2025-06-20 15:14:22 -05:00
adamdottv 4f7e4a9436 feat(tui): custom themes 2025-06-20 15:14:22 -05:00
Márk Magyar eee396f903 feat(tui): theme switcher with preview (#264) 2025-06-20 15:14:05 -05:00
Jay V 0d2f8e175a docs: share bugs 2025-06-20 15:50:12 -04:00
Jay V 4df40e0d9b docs: share page bugs 2025-06-20 15:50:12 -04:00
Dax Raad b72e17a8b7 fix issue with conversations hanging 2025-06-20 15:49:49 -04:00
Dax Raad 61160dc220 docs: readme 2025-06-20 15:22:41 -04:00
Dax Raad 98734ff28c Consolidate session context handling and add global config support
publish / publish (push) Has been cancelled
Refactored context file discovery by removing separate SessionContext module and integrating functionality into SystemPrompt.context(). Added support for finding AGENTS.md and CLAUDE.md files in global config directories.

🤖 Generated with [opencode](https://opencode.ai)

Co-Authored-By: opencode <noreply@opencode.ai>
2025-06-20 15:14:12 -04:00
Josh 9991352663 feat: forward provider options from model config (#202)
publish / publish (push) Has been cancelled
Co-authored-by: Dax Raad <d@ironbay.co>
2025-06-20 15:03:41 -04:00
Dmytro Yankovskyi 91c4da5dbd fix(#243): claude on aws bedrock (#241)
publish / publish (push) Has been cancelled
Co-authored-by: Dax Raad <d@ironbay.co>
2025-06-20 14:57:33 -04:00
niba 2fd0e7dd6b chore: use client_id everywhere (#260) 2025-06-20 14:56:33 -04:00
adamdottv d50b7ad481 docs: theme schema update 2025-06-20 13:51:32 -05:00
adamdottv df95c49401 docs: theme schema 2025-06-20 13:00:32 -05:00
adamdottv 8b73c52f00 chore(tui): rename theme colors 2025-06-20 13:00:31 -05:00
Jay V 5603098d17 docs: add config 2025-06-20 13:22:31 -04:00
Jay V f436a50125 docs: share header 2025-06-20 13:12:35 -04:00
Jay V e19e977591 docs: test 2025-06-20 13:02:05 -04:00
Jay V addbe295b1 docs: test 2025-06-20 12:59:32 -04:00
Jay V 9a573dedc6 docs: test 2025-06-20 12:56:00 -04:00
adamdottv 9ea0d71e8d fix(tui): async load messages on theme/session switch 2025-06-20 11:25:21 -05:00
adamdottv b1a3599017 fix(tui): input latency optimization 2025-06-20 11:08:08 -05:00
adamdottv 7b0329f67f fix(tui): fetch tool more defensive
publish / publish (push) Has been cancelled
2025-06-20 09:00:28 -05:00
adamdottv 311b9c74dd fix(tui): typeahead open/close perf 2025-06-20 08:20:10 -05:00
adamdottv f7e8dd2ff8 chore: fix typescript issues 2025-06-20 07:48:42 -05:00
adamdottv 40b1dd7ef2 fix(tui): insert newline correctly positioned 2025-06-20 07:42:04 -05:00
adamdottv 261e76e0a3 fix(tui): input feels laggy 2025-06-20 07:31:45 -05:00
Dax Raad a300bfaccb docs: remove opencode.json 2025-06-20 01:00:15 -04:00
Dax Raad 41dba0db08 config validation
publish / publish (push) Has been cancelled
2025-06-20 00:57:28 -04:00
Rohan Godha 6674c6083a fix: phantom input bug on wsl (#200) 2025-06-19 20:08:56 -05:00
Tom Watkins f6afa2c6bb docs: fix typo in config.mdx (#218) 2025-06-19 21:08:21 -04:00
Dax Raad b2fb0508ea fix for azure models not liking tool definitions
publish / publish (push) Has been cancelled
2025-06-19 18:28:42 -04:00
Jay V 93f4252bb1 docs: tweak lander 2025-06-19 18:19:35 -04:00
Jay 46ab9c16dd docs: Update README.md 2025-06-19 18:19:06 -04:00
Dax Raad d869df4fee remove unused permission timeout
publish / publish (push) Has been cancelled
2025-06-19 18:00:53 -04:00
Dax Raad b99d4650ec temporarily disable project details in system prompt
publish / publish (push) Has been cancelled
2025-06-19 17:37:23 -04:00
Frank 261bb7f110 Infra: fix DO tag 2025-06-19 17:20:13 -04:00
Dax Raad 0515fbb260 fix gopls download spewing into terminal
publish / publish (push) Has been cancelled
2025-06-19 17:08:58 -04:00
adamdottv 88211d8c5b fix(tui): upgrade notification
publish / publish (push) Has been cancelled
2025-06-19 16:03:45 -05:00
Jay V a812f95b9d docs: share 2025-06-19 16:57:42 -04:00
adamdottv 3728a12bee fix(tui): better help on home
publish / publish (push) Has been cancelled
2025-06-19 15:56:28 -05:00
Jay V af07e51213 docs: tweak 2025-06-19 16:40:15 -04:00
Jay V 3113788c92 docs: copy 2025-06-19 16:39:36 -04:00
Jay V efb5fe6d4e docs: styles 2025-06-19 16:38:37 -04:00
Jay V 54dd6c644d docs: adding to config 2025-06-19 16:36:17 -04:00
Dax Raad 39ad8f2667 ignore: do migration 2025-06-19 16:32:32 -04:00
Jay V c4a2c84e53 docs: readme
publish / publish (push) Has been cancelled
2025-06-19 16:29:20 -04:00
Jay V 44fe012812 docs: edits 2025-06-19 16:28:11 -04:00
Jay V f5e7f079ea Copy changes 2025-06-19 16:28:03 -04:00
adamdottv 15a8936806 fix(tui): better tool titles 2025-06-19 15:11:53 -05:00
adamdottv 4e4cff49c0 feat(tui): better task tool rendering
publish / publish (push) Has been cancelled
2025-06-19 15:02:13 -05:00
adamdottv 5540503bee fix(tui): sorted tool arg maps 2025-06-19 14:07:33 -05:00
adamdottv 193718034b fix: typescript error 2025-06-19 13:57:25 -05:00
adamdottv 72108c0296 fix(tui): sorted tool arg maps 2025-06-19 13:56:09 -05:00
Dax Raad ec1c9f8cd1 use production share url
publish / publish (push) Has been cancelled
2025-06-19 14:21:00 -04:00
Dax Raad a85b0a370e ci: share 2025-06-19 13:26:15 -04:00
Dax Raad e7784d2864 add schema descriptions to config fields
Enhance configuration schema with descriptive text for all fields to improve developer experience and auto-generated documentation.

🤖 Generated with [opencode](https://opencode.ai)

Co-Authored-By: opencode <noreply@opencode.ai>
2025-06-19 13:12:13 -04:00
Dax Raad 97c4815444 fix task agent performance issues
publish / publish (push) Has been cancelled
2025-06-19 13:00:57 -04:00
Dax Raad 7d1a1663c8 allow selecting model and continuing previous session for opencode run 2025-06-19 13:00:57 -04:00
adamdottv 24c0ce6e53 fix(tui): vscode and mac terminal colors 2025-06-19 11:46:08 -05:00
adamdottv 4cdc86612c fix(tui): overlay border backgrounds 2025-06-19 11:41:30 -05:00
Jay V f1f3f8d12c ignore: share version 2025-06-19 12:20:30 -04:00
adamdottv e78d3b54bf chore: cleanup logs 2025-06-19 10:52:45 -05:00
adamdottv f8a7cd372d fix(tui): toast placement and overlay rendering 2025-06-19 10:45:10 -05:00
adamdottv f48eac638d feat(tui): more toast messages 2025-06-19 10:41:59 -05:00
adamdottv e1f12f93eb feat(tui): toast messages 2025-06-19 10:12:29 -05:00
Dax Raad 7ca8334a8b fix webfetch tool when returning html as text
publish / publish (push) Has been cancelled
2025-06-19 10:43:54 -04:00
Dax Raad f1a2b2eba4 support token caching for anthropic via openrouter
publish / publish (push) Has been cancelled
2025-06-19 10:32:14 -04:00
adamdottv 4b132656df feat(tui): copy share url to clipboard
publish / publish (push) Has been cancelled
2025-06-19 09:06:25 -05:00
Dax Raad 26bab00dab remove opencode_ prefixes from tool names. unfortunately this will break
publish / publish (push) Has been cancelled
all old sessions and share links. we'll be more backwards compatible in
the future once we're more stable.
2025-06-19 09:59:44 -04:00
adamdottv 568c04753e feat(tui): expand input to fit message
publish / publish (push) Has been cancelled
2025-06-19 08:45:27 -05:00
Dax Raad 4a06e164d2 ensure session.info is synced when shared
publish / publish (push) Has been cancelled
2025-06-19 09:41:11 -04:00
adamdottv c57b52c300 fix: include schema in converted toml config 2025-06-19 06:02:02 -05:00
Guillermo Antony Cava Nuñez 0b8f48f17f Fixes tool tip layering (#199) 2025-06-19 00:23:29 -04:00
Dax Raad 3862184ccb hooks 2025-06-19 00:20:03 -04:00
Frank 8619c50976 Update SST 2025-06-18 23:38:06 -04:00
Josh bb6b56b72a fix: incorrect command on main screen for exiting application (#201)
publish / publish (push) Has been cancelled
2025-06-18 23:19:43 -04:00
Dax Raad 1252b65166 stop loading models.dev format from global config
publish / publish (push) Has been cancelled
2025-06-18 23:08:51 -04:00
Dax Raad 6840276dad docs: update README 2025-06-18 23:03:54 -04:00
Dax Raad bd8c3cd0f1 BREAKING CONFIG CHANGE
publish / publish (push) Has been cancelled
We have changed the config format yet again - but this should be the
final time. You can see the readme for more details but the summary is

- got rid of global providers config
- got rid of global toml
- global config is now in `~/.config/opencode/config.json`
- it will be merged with any project level config
2025-06-18 23:01:19 -04:00
Dax Raad e5e9b3e3c0 rework config 2025-06-18 23:01:19 -04:00
Frank 1e8a681de9 Render version 2025-06-18 22:26:51 -04:00
Jay V a834bedc17 ignore: share copy link 2025-06-18 20:18:10 -04:00
Dax Raad 6a3392385e support global config 2025-06-18 18:56:52 -04:00
Jay V 6a00e063c4 ignore: share logo 2025-06-18 18:33:51 -04:00
Jay V 73a0ce2b7d ignore: share 2025-06-18 18:22:19 -04:00
Jay V 4d1afd01fa ignore: share 2025-06-18 18:21:44 -04:00
Jay V 801d5f47bd ignore: share favicon 2025-06-18 18:10:22 -04:00
Jay V b6caae9708 ignore: share 2025-06-18 18:01:34 -04:00
adamdottv 183ca64ef9 feat(tui): show provider next to model 2025-06-18 16:09:49 -05:00
adamdottv 8c32cfe829 chore: tui style tweaks 2025-06-18 15:59:58 -05:00
Jay V 73dcc88da1 ignore: share 2025-06-18 16:54:33 -04:00
Jay V 14bded65dc ignore: share 2025-06-18 16:54:33 -04:00
adamdottv 87d1d3fb62 fix(tui): file completion quirks 2025-06-18 15:51:26 -05:00
Frank e054454109 Api: only return session messages 2025-06-18 16:20:34 -04:00
Dax Raad a6142cf975 ignore: types 2025-06-18 16:20:03 -04:00
Jay V 69332e5fa3 ignore: share 2025-06-18 16:15:22 -04:00
Jay V 20201ba3c4 ignore: share 2025-06-18 16:15:11 -04:00
Dax Raad 658067186a ignore: share page stuff 2025-06-18 16:13:33 -04:00
adamdottv ac777b77cf fix(tui): modal visuals 2025-06-18 15:12:24 -05:00
Dax Raad 5944ae2023 share types 2025-06-18 15:34:13 -04:00
Jay V 2f10961ba8 ignore: share 2025-06-18 15:32:40 -04:00
adamdottv fae97978a3 chore: cleanup logs 2025-06-18 14:18:46 -05:00
Dax Raad 3423415e49 docs: improve keybinds configuration format in README
publish / publish (push) Has been cancelled
Update keybinds configuration example to use proper TOML table syntax instead of dot notation for better readability and standard TOML formatting.

🤖 Generated with [opencode](https://opencode.ai)

Co-Authored-By: opencode <noreply@opencode.ai>
2025-06-18 15:10:46 -04:00
adamdottv 1d0bfc2b2a fix(tui): help dialog sorting 2025-06-18 14:06:20 -05:00
adamdottv bd46cf0f86 feat(tui): configurable keybinds and mouse scroll 2025-06-18 13:56:51 -05:00
Dax Raad d4157d9a96 ctrl+c should gracefully clean up pending sessions
publish / publish (push) Has been cancelled
2025-06-18 14:11:49 -04:00
Jay V 6e4ef585d8 ignore: share error styles 2025-06-18 14:10:14 -04:00
Dax Raad e05c3b7a76 fix panic when invalid config
publish / publish (push) Has been cancelled
2025-06-18 14:03:16 -04:00
Dax Raad f99904bc1c track version on session info
publish / publish (push) Has been cancelled
2025-06-18 13:40:36 -04:00
Jay V b796d6763f ignore: share page styles 2025-06-18 12:53:48 -04:00
Dax Raad c1250abdf8 implemented diff trimming 2025-06-18 11:20:40 -04:00
Dax Raad ebe51534a1 allow setting options in global provider store
publish / publish (push) Has been cancelled
2025-06-18 11:06:16 -04:00
Dax Raad b8bbee4718 fix issue with provider cache
publish / publish (push) Has been cancelled
2025-06-18 10:56:23 -04:00
Dax Raad 8f852b396f fix deploys 2025-06-18 10:47:07 -04:00
Dax Raad ae4d089c06 remove call to npm causing noticible delay when starting chat
publish / publish (push) Has been cancelled
2025-06-18 10:35:41 -04:00
Dax Raad 5110fbdaf9 fix issue when running opencode in empty directory
publish / publish (push) Has been cancelled
2025-06-18 10:29:09 -04:00
Dax Raad e6ddb474fc ignore: sync
publish / publish (push) Has been cancelled
2025-06-18 08:36:25 -04:00
SBSTN 0dc71774ce Add Everforest Theme (#170) 2025-06-18 05:55:38 -05:00
Dax Raad b470466e30 integrate cache read/write data
publish / publish (push) Has been cancelled
2025-06-17 20:51:39 -04:00
Jay V d1f9311931 ignore: share page polish 2025-06-17 20:26:12 -04:00
Dax Raad 1c58023df9 improve anthropic oauth token caching and authentication handling
publish / publish (push) Has been cancelled
🤖 Generated with [opencode](https://opencode.ai)

Co-Authored-By: opencode <noreply@opencode.ai>
2025-06-17 13:23:15 -04:00
Dax Raad 4e0aa58b7e ignore: fix 2025-06-17 13:04:26 -04:00
Dax Raad 23ee34b35f state 2025-06-17 12:29:28 -04:00
Dax Raad 674c9a5220 support disabling providers from automatically being added
publish / publish (push) Has been cancelled
2025-06-17 12:23:04 -04:00
Dax Raad 54c86ed43a docs: readme 2025-06-17 12:17:45 -04:00
Dax Raad 676d75ee75 docs: update README
publish / publish (push) Has been cancelled
2025-06-17 12:14:38 -04:00
Dax Raad 70dc0a12f2 docs: readme 2025-06-17 12:12:33 -04:00
Dax Raad d579c5e8aa support global config for providers 2025-06-17 12:10:44 -04:00
Dax Raad ee91f31313 fix issue with tool schemas and google
publish / publish (push) Has been cancelled
2025-06-17 11:27:07 -04:00
Dax Raad 57b3051024 fix agent getting caught in summary loop
publish / publish (push) Has been cancelled
2025-06-17 10:50:03 -04:00
Dax Raad ae5cf3cc23 ci: fix
publish / publish (push) Has been cancelled
2025-06-17 10:38:01 -04:00
Dax Raad 68e1b3c46c Fix TypeScript compilation errors and consolidate version handling
publish / publish (push) Has been cancelled
🤖 Generated with [opencode](https://opencode.ai)

Co-Authored-By: opencode <noreply@opencode.ai>
2025-06-17 10:27:49 -04:00
adamdottv 2d68814abc feat: better collapsed tool call visuals
publish / publish (push) Has been cancelled
2025-06-17 08:35:18 -05:00
adamdottv a5da5127fa chore: consolidate chat page into tui.go 2025-06-17 07:09:04 -05:00
Dax Raad b5a4439704 Add autoshare configuration and improve run command UI
Enables automatic session sharing via global config or flag, enhances UI with logo display and provider/model info positioning.

🤖 Generated with [opencode](https://opencode.ai)

Co-Authored-By: opencode <noreply@opencode.ai>
2025-06-17 01:45:32 -04:00
Dax Raad 9c5616521d do not autoupgrade snapshot builds
publish / publish (push) Has been cancelled
2025-06-17 01:18:32 -04:00
Dax Raad 3fe163416d autoupgrade
publish / publish (push) Has been cancelled
2025-06-17 01:05:05 -04:00
Dax d054f88130 Improve upgrade command with installation method detection (#158) 2025-06-17 00:07:17 -04:00
Jay b929b4f4b9 docs: Update README.md 2025-06-16 21:01:38 -04:00
Jay V 4c0c83b02d docs: readme 2025-06-16 20:10:19 -04:00
adamdottv d6d45bdc63 feat: share and init commands
publish / publish (push) Has been cancelled
2025-06-16 15:58:52 -05:00
Dax Raad 13a83721b0 ci: fixed ci issue 2025-06-16 16:58:25 -04:00
Dax Raad f0edffbae9 docs: readme 2025-06-16 16:53:43 -04:00
Dax Raad 8131bee49a ignore: logs 2025-06-16 16:02:45 -04:00
Dax Raad b5f44ae13f docs: update readme 2025-06-16 15:42:35 -04:00
Miles Till 0d23f2a7fd fix: incorrect lipgloss version (#131) 2025-06-16 14:35:46 -05:00
Dax Raad ac096d84ad remove windows builds
publish / publish (push) Has been cancelled
2025-06-16 15:11:14 -04:00
Dax Raad fcaf0e6dbf opencode auth login: validation on provider id and better error messages
publish / publish (push) Has been cancelled
2025-06-16 15:09:49 -04:00
Dax Raad 19e259d90d docs: readme 2025-06-16 15:04:32 -04:00
Dax Raad 2c9fd1e776 BREAKING CHANGE: the config structure has changed, custom providers have an npm field now to specify which npm package to load. see examples in README.md 2025-06-16 15:02:25 -04:00
Dax Raad 63996c4189 limit to 4 system prompts cached
publish / publish (push) Has been cancelled
2025-06-16 14:51:59 -04:00
adamdottv c7bb7ce4de fix: include cached tokens in tui 2025-06-16 12:59:38 -05:00
adamdottv c8eb1b24c3 feat: believe it or not, even faster tui init
publish / publish (push) Has been cancelled
2025-06-16 12:34:34 -05:00
adamdottv b9f894f1e9 feat: even faster tui init 2025-06-16 12:24:18 -05:00
adamdottv 7c0d10a4ce feat: faster tui init
publish / publish (push) Has been cancelled
2025-06-16 11:54:55 -05:00
Dax Raad 06af406146 properly track cache token counts
publish / publish (push) Has been cancelled
2025-06-16 12:43:22 -04:00
Dax Raad 0e3458b112 fix cache-control
publish / publish (push) Has been cancelled
2025-06-16 12:07:01 -04:00
adamdottv 2d15c683e0 fix: default provider and model 2025-06-16 10:51:01 -05:00
adamdottv 3c94d26570 chore: remove status service 2025-06-16 10:45:19 -05:00
Dax Raad 1a553e525f enable prompt caching for anthropic
publish / publish (push) Has been cancelled
2025-06-16 11:41:54 -04:00
adamdottv 3c4e966216 fix: spinner background color 2025-06-16 10:03:44 -05:00
Dax Raad 0721620ed8 docs: readme 2025-06-16 10:44:48 -04:00
Thomas Meire 9fc6734f32 ignore: remove log files and add them to gitignore (#138) 2025-06-16 09:30:07 -04:00
Jacob e1733a423d fix: typo and literal wording in packages/opencode/AGENTS.md (#134) 2025-06-16 08:18:29 -05:00
Dax Raad d42e3db7e0 docs: update README 2025-06-15 21:43:20 -04:00
Dax Raad cdb26f6d83 docs: readme 2025-06-15 21:39:02 -04:00
Dax Raad fe05edaa79 enhance ripgrep files function with query filtering and limit support
publish / publish (push) Has been cancelled
🤖 Generated with [opencode](https://opencode.ai)

Co-Authored-By: opencode <noreply@opencode.ai>
2025-06-15 21:26:32 -04:00
Dax Raad 7d174767b0 first pass making system prompt less fast
publish / publish (push) Has been cancelled
2025-06-15 20:25:04 -04:00
George Potoshin c5eefd1752 Fix: Improve Help UI Readability (Issue #99) (#117) 2025-06-15 18:38:44 -05:00
adamdottv 77a6b3bdd6 fix: background color rendering issues
publish / publish (push) Has been cancelled
2025-06-15 15:07:05 -05:00
Pierre B. 7effff56c0 fix: spelling, grammar and typos (#121) 2025-06-15 14:23:18 -05:00
Dax Raad e30fba0d3c Improve LSP server initialization with timeout handling and skip failed servers
publish / publish (push) Has been cancelled
🤖 Generated with [opencode](https://opencode.ai)

Co-Authored-By: opencode <noreply@opencode.ai>
2025-06-15 13:52:57 -04:00
Dax Raad 7fbb2ca9a6 ignore: add timer log helper 2025-06-15 13:33:24 -04:00
Dax Raad 230d0a1510 fix postinstall script for node
publish / publish (push) Has been cancelled
2025-06-15 13:11:11 -04:00
Pierre B. 46ff2c0ae0 chore: ignore intellij, vscode (#122) 2025-06-15 10:40:34 -05:00
adamdottv b8a89dab0f fix: background color rendering issues
publish / publish (push) Has been cancelled
2025-06-15 05:57:15 -05:00
szymon 7351e12886 remove .DS_Store (#112) 2025-06-15 05:34:46 -05:00
Dax Raad 38879dee2d beginning of upgrade command 2025-06-14 22:05:41 -04:00
Dax Raad c4ff8dd205 revert ctrl+d - conflicts with page down
publish / publish (push) Has been cancelled
2025-06-14 21:29:02 -04:00
Dax Raad 0e035b3115 fix aborting issue
publish / publish (push) Has been cancelled
2025-06-14 21:23:57 -04:00
Dax Raad b855511d9a fix issue with follow up tool calls and cancelation
publish / publish (push) Has been cancelled
2025-06-14 21:03:44 -04:00
Dax Raad 783faf554d fix issue continuing session after aborted 2025-06-14 20:24:50 -04:00
nitishxyz bfd4269d7d Add Ayu dark theme (#109)
publish / publish (push) Has been cancelled
2025-06-14 20:08:31 -04:00
Berr 25f78b053b fix: improve browser opening error handling in AuthLoginCommand (#111) 2025-06-14 20:07:41 -04:00
Dax Raad 87f260ee17 sync 2025-06-14 20:04:41 -04:00
Dax Raad 12931a869d ci: ignore commits 2025-06-14 18:59:05 -04:00
Dax Raad f759e1804d docs: typo 2025-06-14 18:58:27 -04:00
Rohan Godha c9b4564d36 tui: fix help dialog background (#110)
publish / publish (push) Has been cancelled
2025-06-14 18:57:15 -04:00
Conor O'Brien d097c546db nit: update commands displayed on home to match commands available (#108) 2025-06-14 18:56:44 -04:00
Gal Schlezinger adb54521b4 make ctrl+d quit too, just like shells (#105) 2025-06-14 18:56:34 -04:00
Dax Raad 2ea0399aa7 docs: use ollama example 2025-06-14 18:55:39 -04:00
Dax Raad fa1266263d downgrade to ai sdk v4.x
publish / publish (push) Has been cancelled
2025-06-14 18:44:08 -04:00
Gal Schlezinger fe109c921e add focus tracking for tui so cursor will hide when not in focus (#103) 2025-06-14 14:53:43 -05:00
Dax Raad 37bb8895fe docs: readme 2025-06-14 14:52:02 -04:00
Dax Raad 89b95be4de docs: provider config 2025-06-14 14:45:59 -04:00
Dax Raad eaf295bac7 docs: faq 2025-06-14 14:39:13 -04:00
Mantena Rama Raju 27d3cec477 typo (#94) 2025-06-14 14:36:29 -04:00
Dax Raad 574d494c3c Enhance provider system with dynamic package resolution and improved logging
publish / publish (push) Has been cancelled
- Add npm registry lookup for AI SDK packages with fallback support
- Enhance error logging with cause information
- Add timing deltas to log output for performance monitoring

🤖 Generated with [opencode](https://opencode.ai)

Co-Authored-By: opencode <noreply@opencode.ai>
2025-06-14 14:35:33 -04:00
Albert Ilagan 0239761f31 tui: remove quit dialog (#97) 2025-06-14 12:47:34 -05:00
Dax Raad a53f9165e9 doc: remove dev script 2025-06-14 13:05:23 -04:00
Dax Raad ffc231bd8b docs: contributing
publish / publish (push) Has been cancelled
2025-06-14 12:45:26 -04:00
Dax Raad 3cf4ef56fb sync 2025-06-14 12:32:41 -04:00
Dax Raad c738e26438 docs: mcp 2025-06-14 12:25:26 -04:00
Dax Raad 9c6aa82ac1 docs: config schema 2025-06-14 12:22:07 -04:00
Dax Raad ef74d97491 ci: update publish script 2025-06-14 12:13:59 -04:00
Dax Raad af892e5432 docs: readme 2025-06-14 12:13:46 -04:00
Dax Raad d7aca6230d naming fixes
publish / publish (push) Has been cancelled
2025-06-14 01:54:28 -04:00
Dax Raad 0f9c2c5c27 Add flag system and auto-share functionality
publish / publish (push) Has been cancelled
- Add Flag module for environment variable configuration
- Implement OPENCODE_AUTO_SHARE flag to automatically share new sessions
- Update session creation to conditionally auto-share based on flag

🤖 Generated with [OpenCode](https://opencode.ai)

Co-Authored-By: OpenCode <noreply@opencode.ai>
2025-06-14 01:51:04 -04:00
Dax Raad 6a261dedb4 Improve logging and simplify fzf implementation
- Refactor fzf search to use Bun's $ syntax for cleaner command execution
- Add request/response duration logging to server middleware
- Set default service name for logging to improve log clarity

🤖 Generated with [OpenCode](https://opencode.ai)

Co-Authored-By: OpenCode <noreply@opencode.ai>
2025-06-14 01:51:04 -04:00
Alireza Bahrami ec928d88b5 fix(install): check if the path export command already exists (#28) 2025-06-13 23:28:33 -04:00
Dax Raad 59a5f120c0 Clean up workflows and enhance file discovery tools to include dot files
publish / publish (push) Has been cancelled
🤖 Generated with [OpenCode](https://opencode.ai)

Co-Authored-By: OpenCode <noreply@opencode.ai>
2025-06-13 23:24:46 -04:00
Dax Raad ce07f80b19 sync 2025-06-13 17:42:56 -04:00
Dax Raad 168fd9b2e3 screenshot 2025-06-13 17:42:14 -04:00
Dax Raad df13b155f9 disable autoshare
publish / publish (push) Has been cancelled
2025-06-13 17:30:17 -04:00
Dax Raad eeed5b8718 sync 2025-06-13 17:24:45 -04:00
Dax Raad 148ef90210 sync
publish / publish (push) Has been cancelled
2025-06-13 17:23:22 -04:00
adamdottv 67023bb007 wip: refactoring tui 2025-06-13 15:56:33 -05:00
Dax Raad a316aed4fe sync
publish / publish (push) Has been cancelled
2025-06-13 16:47:15 -04:00
Dax Raad 9f7c0bd599 sync 2025-06-13 16:46:48 -04:00
Dax Raad c7e1068f90 sync 2025-06-13 16:45:58 -04:00
Dax Raad e2052d790b sync 2025-06-13 16:43:53 -04:00
Dax Raad d3b2763c14 commit and push 2025-06-13 16:42:31 -04:00
Dax Raad c6492de7ac sync 2025-06-13 16:37:58 -04:00
Dax Raad d8fa0fb50c sync
publish / publish (push) Has been cancelled
2025-06-13 16:29:57 -04:00
Dax Raad 18ab8faa1d reset readme 2025-06-13 16:26:34 -04:00
Dax Raad f35ce180e2 ci
publish / publish (push) Has been cancelled
2025-06-13 16:23:38 -04:00
Dax Raad 2bee48a9bc homebrew
publish / publish (push) Has been cancelled
2025-06-13 16:17:27 -04:00
adamdottv 10ddd654cf wip: refactoring tui
publish / publish (push) Has been cancelled
2025-06-13 11:27:05 -05:00
adamdottv 61396b93ed wip: refactoring tui 2025-06-13 11:18:46 -05:00
adamdottv 62b9a30a9c wip: refactoring tui 2025-06-13 10:47:51 -05:00
adamdottv 5706c6ad3a wip: refactoring tui 2025-06-13 09:57:54 -05:00
adamdottv e8e03c895a wip: refactoring tui 2025-06-13 09:44:09 -05:00
adamdottv 38667682a7 wip: refactoring tui 2025-06-13 09:19:51 -05:00
adamdottv d7d5fc39fb wip: refactoring tui 2025-06-13 08:30:57 -05:00
adamdottv 0caf25adee wip: refactoring tui 2025-06-13 08:30:56 -05:00
Dax Raad 37febc6873 do not strip aur package
publish / publish (push) Has been cancelled
2025-06-13 08:27:17 -04:00
adamdottv 4169f0c412 wip: refactoring tui
publish / publish (push) Has been cancelled
2025-06-13 07:01:26 -05:00
adamdottv b7f06bbc1f wip: refactoring tui 2025-06-13 06:56:12 -05:00
adamdottv 1b8cfe9e99 wip: refactoring tui 2025-06-13 06:49:59 -05:00
adamdottv 97837d2d23 wip: refactoring tui 2025-06-13 06:23:12 -05:00
Dax Raad 9abc2a0cf8 load API keys
publish / publish (push) Has been cancelled
2025-06-13 00:53:46 -04:00
Dax Raad 9fb47bc855 Enhance auth command with dynamic provider selection
- Add support for dynamically loading providers from ModelsDev
- Prioritize anthropic as recommended provider
- Add "other" provider option for manual entry
- Include special handling for amazon-bedrock with AWS config guidance
- Expand provider selection UI to show up to 8 providers

🤖 Generated with [OpenCode](https://opencode.ai)

Co-Authored-By: OpenCode <noreply@opencode.ai>
2025-06-13 00:33:54 -04:00
Dax Raad 73e9fb53d5 sync 2025-06-13 00:06:15 -04:00
Dax Raad f03637b1fc Refactor AI SDK provider loading to use BunProc.install
Simplifies provider installation by using BunProc.install() instead of manual path construction and file system checks.

🤖 Generated with [OpenCode](https://opencode.ai)

Co-Authored-By: OpenCode <noreply@opencode.ai>
2025-06-12 23:50:26 -04:00
Dax Raad 2c376c5abc bedrock loader
publish / publish (push) Has been cancelled
2025-06-12 23:39:52 -04:00
Dax Raad 442e1b52ad Update provider configuration and server handling
🤖 Generated with [OpenCode](https://opencode.ai)

Co-Authored-By: OpenCode <noreply@opencode.ai>
2025-06-12 23:10:03 -04:00
Thomas Meire e8c3abc369 Update error message to say opencode instead of sst (#81)
publish / publish (push) Has been cancelled
2025-06-12 18:38:59 -04:00
Dax Raad c8648baba2 ci
publish / publish (push) Has been cancelled
2025-06-12 18:30:19 -04:00
Dax Raad 7b3a799856 ci
publish / publish (push) Has been cancelled
2025-06-12 18:21:08 -04:00
Dax Raad 9356b6c35a sync
publish / publish (push) Has been cancelled
2025-06-12 18:14:04 -04:00
Dax Raad 29a6603a89 Update CLI run command and session handling
publish / publish (push) Has been cancelled
🤖 Generated with [OpenCode](https://opencode.ai)

Co-Authored-By: OpenCode <noreply@opencode.ai>
2025-06-12 18:07:31 -04:00
Dax Raad a454ba8895 subagent 2025-06-12 18:07:31 -04:00
Jay V 5eae7aef0e updating logo 2025-06-12 17:30:24 -04:00
adamdottv 1031bceef7 wip: refactoring tui 2025-06-12 16:04:45 -05:00
adamdottv 653965ef59 wip: refactoring tui 2025-06-12 16:00:26 -05:00
adamdottv ca0ea3f94d wip: refactoring tui 2025-06-12 16:00:25 -05:00
adamdottv 98bd5109c2 wip: refactoring tui 2025-06-12 16:00:25 -05:00
adamdottv 78f65e4789 wip: refactoring tui 2025-06-12 16:00:25 -05:00
adamdottv 75dd2f75aa wip: refactoring tui 2025-06-12 16:00:25 -05:00
adamdottv fe86e58bbb wip: refactoring tui 2025-06-12 16:00:24 -05:00
adamdottv ae339015fc wip: refactoring tui 2025-06-12 16:00:24 -05:00
adamdottv cce2e4ad75 wip: refactoring tui 2025-06-12 16:00:24 -05:00
Dax Raad a1ce35c208 ci 2025-06-12 14:15:44 -04:00
Dax Raad 69d6709a19 sync 2025-06-12 14:11:01 -04:00
Dax Raad 52ec134b2d Update publish workflow to support snapshot releases on dontlook branch
🤖 Generated with [OpenCode](https://opencode.ai)

Co-Authored-By: OpenCode <noreply@opencode.ai>
2025-06-12 14:10:29 -04:00
Dax Raad db88bede05 sync
publish / publish (push) Has been cancelled
2025-06-12 14:06:06 -04:00
Dax Raad d4d218d7d6 Update index.ts
publish / publish (push) Has been cancelled
🤖 Generated with [OpenCode](https://opencode.ai)

Co-Authored-By: OpenCode <noreply@opencode.ai>
2025-06-12 13:59:42 -04:00
Dax Raad 3e086e3ab9 sync
publish / publish (push) Has been cancelled
2025-06-12 13:49:43 -04:00
Jay V 2f5faae34b fix share page edit 2025-06-12 13:42:10 -04:00
Dax Raad e3ad6a0698 do not output bunproc
publish / publish (push) Has been cancelled
2025-06-12 13:39:03 -04:00
Dax Raad b536b45536 Fix AUR SSH key path handling in publish script
publish / publish (push) Has been cancelled
Quote and trim AUR_KEY environment variable to handle paths with spaces and multiline content properly.

🤖 Generated with [OpenCode](https://opencode.ai)

Co-Authored-By: OpenCode <noreply@opencode.ai>
2025-06-12 13:37:12 -04:00
Dax Raad 81c245035f Simplify BunProc.which() to use process.execPath directly
publish / publish (push) Has been cancelled
🤖 Generated with [OpenCode](https://opencode.ai)

Co-Authored-By: OpenCode <noreply@opencode.ai>
2025-06-12 13:32:31 -04:00
Dax Raad dda7059e57 update bun integration
publish / publish (push) Has been cancelled
🤖 Generated with [OpenCode](https://opencode.ai)

Co-Authored-By: OpenCode <noreply@opencode.ai>
2025-06-12 13:29:14 -04:00
Dax Raad 0cca75ef48 sync
publish / publish (push) Has been cancelled
2025-06-12 13:19:24 -04:00
Dax Raad ee1f55dbe2 token
publish / publish (push) Has been cancelled
2025-06-12 13:17:06 -04:00
Dax Raad 2fa50190e5 skip nil values
publish / publish (push) Has been cancelled
2025-06-12 13:13:34 -04:00
Jay V 662b6b1258 share page handle undefined 2025-06-12 13:11:34 -04:00
Dax Raad f0dbe40522 sync
publish / publish (push) Has been cancelled
2025-06-12 13:04:01 -04:00
Dax Raad 41c54f629c sync
release / goreleaser (push) Has been cancelled
2025-06-12 12:48:38 -04:00
Dax Raad 4503201b15 npm token
release / goreleaser (push) Has been cancelled
2025-06-12 12:09:13 -04:00
Dax Raad 120151ee38 sync 2025-06-12 11:58:41 -04:00
Dax Raad 4d2e556713 sync
release / goreleaser (push) Has been cancelled
2025-06-12 11:57:57 -04:00
Dax Raad 54a5d3a9eb sync
release / goreleaser (push) Has been cancelled
2025-06-12 11:56:52 -04:00
Dax Raad 22dc6b6ec9 sync
release / goreleaser (push) Has been cancelled
2025-06-12 11:56:06 -04:00
Dax Raad b5c6ddcd04 tweak
release / goreleaser (push) Has been cancelled
2025-06-12 11:55:07 -04:00
Dax Raad e03ad6c42e sync
release / goreleaser (push) Has been cancelled
2025-06-12 11:18:17 -04:00
Dax Raad 33457d8472 sync
release / goreleaser (push) Has been cancelled
2025-06-12 11:02:51 -04:00
Dax Raad 888105e60f sync
release / goreleaser (push) Has been cancelled
2025-06-12 11:00:37 -04:00
Dax Raad b7b490f67c Add postinstall script and update session/release configuration
release / goreleaser (push) Has been cancelled
🤖 Generated with [OpenCode](https://opencode.ai)

Co-Authored-By: OpenCode <noreply@opencode.ai>
2025-06-12 00:50:49 -04:00
Dax Raad f6ed59bf45 Refactor external tools organization and add file search API endpoint
🤖 Generated with [OpenCode](https://opencode.ai)

Co-Authored-By: OpenCode <noreply@opencode.ai>
2025-06-11 23:59:51 -04:00
Dax Raad 83991bee88 Add search function to fzf and move version constant to namespace level
🤖 Generated with [OpenCode](https://opencode.ai)

Co-Authored-By: OpenCode <noreply@opencode.ai>
2025-06-11 23:58:13 -04:00
Dax Raad 29142eb940 add title temp 2025-06-11 19:09:08 -04:00
Dax Raad aab47714c9 sync 2025-06-11 19:00:09 -04:00
Dax Raad 9b2b610920 sync 2025-06-11 18:45:18 -04:00
Dax Raad 468cec545a sync 2025-06-11 18:19:21 -04:00
adamdottv 3c82fb6818 wip: refactoring tui 2025-06-11 12:05:54 -05:00
adamdottv 8a2f370eda wip: refactoring tui 2025-06-11 11:58:25 -05:00
Dax Raad 636133e6cb sync 2025-06-11 12:58:06 -04:00
Dax Raad 6cf8784ecf sync 2025-06-11 12:44:21 -04:00
adamdottv 95d5e1f231 wip: refactoring tui 2025-06-11 11:43:28 -05:00
Dax Raad 979bad3e64 sync 2025-06-11 12:35:20 -04:00
Dax Raad 300d0474a3 sync 2025-06-11 11:41:10 -04:00
Dax Raad d4379c8c93 turn on tool call streaming 2025-06-11 11:36:12 -04:00
Jay V a9b230f419 share page scroll anchor 2025-06-11 09:43:52 -05:00
Dax Raad 07cffebc8f fix bash 2025-06-11 00:37:43 -04:00
Dax Raad f1de1634d6 Standardize styling in auth commands by replacing Bun.color with UI.Style constants
🤖 Generated with [OpenCode](https://opencode.ai)

Co-Authored-By: OpenCode <noreply@opencode.ai>
2025-06-11 00:34:55 -04:00
Dax Raad 8d8663399d sync 2025-06-11 00:27:46 -04:00
Dax Raad 83eb61fd5f Refactor authentication system to consolidate auth flow and remove provider-based commands
🤖 Generated with [OpenCode](https://opencode.ai)

Co-Authored-By: OpenCode <noreply@opencode.ai>
2025-06-11 00:21:46 -04:00
Dax Raad b8e7d06356 sync 2025-06-10 22:18:27 -04:00
Dax Raad 4543765e3a fix rendering 2025-06-10 19:37:25 -04:00
Dax Raad 28f5cbbfe9 Fix shutdown handling, error management, and process lifecycle issues
🤖 Generated with [OpenCode](https://opencode.ai)

Co-Authored-By: OpenCode <noreply@opencode.ai>
2025-06-10 18:58:47 -04:00
Dax Raad ca3c22dc12 fix bunfile bug 2025-06-10 18:23:19 -04:00
Dax Raad 49110f7412 sync 2025-06-10 18:10:30 -04:00
Dax Raad 14dcf43246 add abort signals 2025-06-10 17:56:05 -04:00
Dax Raad 84e4afc0bd webfetch spoof browser 2025-06-10 16:39:06 -04:00
Dax Raad 1cc8e9a36d kill 2025-06-10 16:35:02 -04:00
Dax Raad 43b429db93 lsp 2025-06-10 16:29:35 -04:00
Dax Raad 6248c1e720 merge deep config 2025-06-10 16:19:02 -04:00
Frank 772e1851c0 Share: render url on frontend 2025-06-10 15:50:42 -04:00
Dax Raad 5ab2ff9589 onboarding progress 2025-06-10 15:43:14 -04:00
Dax Raad a0062d4661 fix share link 2025-06-10 13:36:47 -04:00
Dax Raad ef7f1f0761 sync 2025-06-10 13:30:13 -04:00
Dax Raad 96b5a079ff Update LSP client/server and CLI scrap command functionality
🤖 Generated with [OpenCode](https://opencode.ai)

Co-Authored-By: OpenCode <noreply@opencode.ai>
2025-06-10 13:30:13 -04:00
Jay V 0e58f488df moving share urls 2025-06-10 11:52:02 -05:00
Dax Raad fa7416687b Enhance ripgrep error handling and utility functions
🤖 Generated with [OpenCode](https://opencode.ai)

Co-Authored-By: OpenCode <noreply@opencode.ai>
2025-06-10 11:06:01 -04:00
Jay V c3ab370344 share page fix 2025-06-10 09:33:28 -05:00
Dax Raad bb60aa3060 sync 2025-06-10 10:14:03 -04:00
Dax Raad 34fa8cadd6 Improve ripgrep error handling with structured error types
🤖 Generated with [OpenCode](https://opencode.ai)

Co-Authored-By: OpenCode <noreply@opencode.ai>
2025-06-10 10:14:03 -04:00
Frank edd459ec00 Share: og image 2025-06-09 23:37:32 -04:00
Frank 177875f624 ssr sync 2025-06-09 23:07:29 -04:00
Dax Raad fdaa7f287c aborted toolcalls should be cleaned up 2025-06-09 20:48:50 -04:00
Dax Raad fed659c582 properly support codex mini 2025-06-09 20:24:18 -04:00
Dax Raad bffc612a4e notice 2025-06-09 19:58:08 -04:00
Jay V b97b15e0fe share og image 2025-06-09 16:42:13 -05:00
Jay V fcb972de19 edits 2025-06-09 16:09:15 -05:00
Dax Raad 4478195ea8 file permissions for anthropic credentials 2025-06-09 17:07:52 -04:00
Jay V 54c4a783b3 share page show lsp diag 2025-06-09 15:41:19 -05:00
Jay V c091cbb624 share page fix ai text 2025-06-09 15:02:46 -05:00
Jay V d4f8fd867a fix duplicates models 2025-06-09 15:02:46 -05:00
Dax Raad a2884b08cc improve AGENTS.md 2025-06-09 15:28:06 -04:00
Dax Raad 60faa26a15 sync 2025-06-09 15:00:48 -04:00
Dax Raad d8510ab452 Refactor logging system to centralize initialization and remove printLogs parameter
🤖 Generated with [OpenCode](https://opencode.ai)

Co-Authored-By: OpenCode <noreply@opencode.ai>
2025-06-09 14:52:30 -04:00
Dax Raad 3c23b92bea optional 2025-06-09 14:02:58 -04:00
Dax Raad 021fd3fcb5 sync 2025-06-09 14:01:11 -04:00
Dax Raad fa3253d1b6 Add TypeScript server initialization config to LSP server
🤖 Generated with [OpenCode](https://opencode.ai)

Co-Authored-By: OpenCode <noreply@opencode.ai>
2025-06-08 13:22:07 -04:00
Dax Raad a1cc8f6cdb fix ts lsp 2025-06-08 12:57:33 -04:00
Dax Raad 1bcc02442a sync 2025-06-08 12:46:32 -04:00
Frank 1d782dc19a Share: load server data on page load 2025-06-08 01:17:54 -04:00
Frank 879d02f86c Remove unused package 2025-06-07 23:47:45 -04:00
Frank 028d589ea0 Infra: use Astro component 2025-06-07 23:46:56 -04:00
Dax Raad cdbdb96218 sync 2025-06-07 17:15:40 -04:00
Dax Raad f22c93ba1b logs 2025-06-06 23:58:09 -04:00
Dax Raad b34d5c959b add go version 2025-06-06 23:26:11 -04:00
Dax Raad 32e6a552c0 autodownload lsp 2025-06-06 23:21:57 -04:00
Dax Raad d6afebf22a make lsp better 2025-06-06 17:20:08 -04:00
Jay V b32cb2b932 share page styles 2025-06-06 12:18:02 -04:00
Dax Raad 265f427d2a lsp progress 2025-06-05 23:42:04 -04:00
Dax Raad 16520261f4 update auth and provider configuration
🤖 Generated with [OpenCode](https://opencode.ai)

Co-Authored-By: OpenCode <noreply@opencode.ai>
2025-06-05 20:11:56 -04:00
Jay V 65b2cf73d7 share page markdown 2025-06-05 19:14:35 -04:00
Jay V 95069af03f share write tool 2025-06-05 16:41:44 -04:00
Jay V 3e4ebb6e5d share page 2025-06-05 16:35:23 -04:00
Dax Raad 9147108675 fix webfetch 2025-06-05 15:59:17 -04:00
Jay V ea9dd4e9e2 share ssr 2025-06-05 15:37:23 -04:00
Dax Raad 4a6e36a404 fix cost 2025-06-05 15:06:42 -04:00
Dax Raad db2bb32bcf integrate with models.dev 2025-06-05 14:59:16 -04:00
Jay V 1384a5e3e6 share page fetch 2025-06-05 14:17:43 -04:00
adamdottv 167aea6aaf wip: refactoring tui 2025-06-05 13:10:20 -05:00
Jay V 142056e9af share page todos 2025-06-05 13:52:44 -04:00
Dax Raad 241c366164 sync 2025-06-05 13:51:18 -04:00
Dax Raad 3cd7ae0807 gopls 2025-06-05 13:51:18 -04:00
Dax Raad 299a74061a sync 2025-06-05 13:51:18 -04:00
adamdottv e3d5af2855 wip: refactoring tui 2025-06-05 12:38:25 -05:00
adamdottv bbfa72552a feat: opus 4 2025-06-05 11:39:13 -05:00
Dax Raad 8dfdd3927e sync 2025-06-05 12:06:21 -04:00
Dax Raad 02e326f87f fixed 2025-06-05 11:58:04 -04:00
Dax Raad 35b03e4cb3 claude oauth support 2025-06-05 11:51:06 -04:00
adamdottv b3555cda30 wip: refactoring tui 2025-06-05 10:46:07 -05:00
adamdottv 04bd98cf4d wip: refactoring tui 2025-06-05 05:43:33 -05:00
Dax Raad f3e31130ba fix cost 2025-06-05 02:23:11 -04:00
Dax Raad 671e91f201 Add session share URL display to CLI output
🤖 Generated with [OpenCode](https://opencode.ai)

Co-Authored-By: OpenCode <noreply@opencode.ai>
2025-06-04 21:01:36 -04:00
Dax Raad d334ead84a sync 2025-06-04 20:49:33 -04:00
Jay V 160428d2d4 share page glob 2025-06-04 20:14:14 -04:00
Jay V 0a1f9accd7 share page glob 2025-06-04 19:34:15 -04:00
Jay V a74f27e59a read tool share page 2025-06-04 18:39:06 -04:00
Dax Raad f76cdfff9b sync 2025-06-04 18:32:10 -04:00
Dax Raad 05974ea109 rework 2025-06-04 18:03:04 -04:00
Dax Raad 6cfce1e4da track errors 2025-06-04 17:55:14 -04:00
Jay V e20093678f share page tool args 2025-06-04 17:48:42 -04:00
Dax Raad 7f8f46f9fe Refactor session module structure and improve error handling
- Rename session.ts to index.ts for cleaner module imports
- Update all imports to use new session module structure
- Add error metadata tracking to message schema
- Improve error handling in session stream processing

🤖 Generated with [OpenCode](https://opencode.ai)

Co-Authored-By: OpenCode <noreply@opencode.ai>
2025-06-04 17:38:54 -04:00
Jay V 2dbdecb0f7 styles share 2025-06-04 17:01:04 -04:00
Dax Raad 53b0a25085 implemented todo tool 2025-06-04 15:09:50 -04:00
adamdottv 093e64eb54 wip: refactoring tui 2025-06-04 13:52:23 -05:00
adamdottv f34a3b6f67 wip: refactoring tui 2025-06-04 12:57:17 -05:00
Jay V 484c90ed00 share collapse system prompt 2025-06-04 13:37:07 -04:00
Dax Raad f49694a543 sync 2025-06-04 13:33:53 -04:00
Dax Raad fb88705bdc more tools 2025-06-04 13:33:25 -04:00
Dax Raad 90d85e6393 sync 2025-06-04 13:12:55 -04:00
Dax Raad d13822d26e tool updates 2025-06-04 13:12:48 -04:00
adamdottv a890288900 wip: refactoring tui 2025-06-04 11:48:01 -05:00
adamdottv 31d6e303a6 wip: refactoring tui 2025-06-04 11:48:01 -05:00
Jay V 199c42f726 styles share 2025-06-04 12:44:36 -04:00
Jay V 3211594821 styles 2025-06-04 12:32:25 -04:00
adamdottv 01050a430f wip: refactoring tui 2025-06-04 09:20:48 -05:00
Dax Raad 0b565b18c4 sync 2025-06-04 10:20:29 -04:00
Dax Raad 0791b077d7 fix tokens 2025-06-04 10:14:42 -04:00
Jay V 2fb59fee8e share paage durations 2025-06-03 18:08:46 -04:00
Jay V 8206da4d9e share page bugs 2025-06-03 17:20:30 -04:00
adamdottv 0c6bda8255 wip: refactoring tui 2025-06-03 15:49:41 -05:00
Dax Raad 1e063e7937 fix port issue 2025-06-03 16:35:37 -04:00
Dax Raad 37c34fd39c mcp support 2025-06-03 15:57:48 -04:00
Jay V 3a60ae98f3 styles 2025-06-03 15:57:00 -04:00
Jay V feeb49a42b Styling share 2025-06-03 15:55:34 -04:00
Jay V ad84355ebc lock 2025-06-03 15:55:34 -04:00
Dax Raad e2397a343d Fix bash tool stream handling by ensuring consistent stdout/stderr pipe configuration
🤖 Generated with opencode
Co-Authored-By: opencode <noreply@opencode.ai>
2025-06-03 14:48:05 -04:00
Dax Raad 8e769dcac0 Replace env-paths with xdg-basedir for better XDG compliance and cross-platform directory handling
🤖 Generated with opencode
Co-Authored-By: opencode <noreply@opencode.ai>
2025-06-03 14:46:28 -04:00
Dax Raad 9ad0477af6 change file name again 2025-06-03 14:28:50 -04:00
Dax Raad c5eafd5722 sync 2025-06-03 14:25:25 -04:00
Dax Raad caf9fdc893 initialized 2025-06-03 14:24:45 -04:00
Dax Raad be4155a838 max output tokens 2025-06-03 13:46:39 -04:00
adamdottv b00326a75a wip: refactoring tui 2025-06-03 12:45:28 -05:00
Dax Raad 4cf0aebb2e do not list files if not git 2025-06-03 13:19:44 -04:00
Dax Raad a5a39dada7 include env 2025-06-03 13:18:42 -04:00
Dax Raad 866f22b077 sync 2025-06-03 13:08:47 -04:00
Dax Raad ec7ab16ce4 sync 2025-06-03 13:00:27 -04:00
Dax Raad e5b06a2d95 initialzie 2025-06-03 12:38:48 -04:00
Dax Raad fae49aaf88 sync
release / goreleaser (push) Has been cancelled
2025-06-03 12:08:07 -04:00
Dax Raad 274c8baa34 added app 2025-06-03 12:02:21 -04:00
Dax Raad bfb36a8566 Refactor app context system to use Zod schemas and sync access pattern
🤖 Generated with opencode
Co-Authored-By: opencode <noreply@opencode.ai>
2025-06-03 11:59:03 -04:00
Dax Raad 8487346d3f check in generated files 2025-06-02 22:14:12 -04:00
Dax Raad 54b99cd88a scope filetimes to session 2025-06-02 20:24:32 -04:00
Dax Raad 786db364d2 add permission system 2025-06-02 19:51:37 -04:00
adamdottv 863e7a093e wip: refactoring tui 2025-06-02 14:14:13 -05:00
adamdottv ca87b2806f wip: refactoring tui 2025-06-02 13:33:05 -05:00
adamdottv 2958c6b53c wip: refactoring tui 2025-06-02 12:30:03 -05:00
adamdottv 8b5394e031 wip: refactoring tui 2025-06-02 12:00:21 -05:00
adamdottv da92ee5f09 wip: refactoring tui 2025-06-02 11:33:01 -05:00
Dax Raad 80de5d489f spawn from anywhere in dev mode 2025-06-02 11:40:28 -04:00
Dax Raad ab17578516 remove json 2025-06-01 15:03:25 -04:00
Dax Raad e764525578 sync 2025-06-01 15:01:57 -04:00
Dax Raad a1c4f345a8 Fix TypeScript errors and clean up unused imports
- Remove unused fs import from app.ts
- Remove unused LLM import and missing module reference from server.ts
- Fix parameter naming inconsistency in fetch.ts execute function
- Add missing metadata property to fetch.ts return statement
- Update test file to use correct API signatures and parameter names
- Remove unused parameters from example.ts

🤖 Generated with opencode
Co-Authored-By: opencode <noreply@opencode.ai>
2025-06-01 14:46:04 -04:00
Dax Raad 526a8ea19a Refactor application path handling and data storage architecture
Replace simple directory-based path system with git-aware data management that uses global data directories and proper workspace detection.

🤖 Generated with opencode
Co-Authored-By: opencode <noreply@opencode.ai>
2025-06-01 14:40:44 -04:00
Dax Raad 4be9f7ab9c fix tool name change 2025-05-31 20:33:21 -04:00
Dax Raad 8e40160934 sync
release / goreleaser (push) Has been cancelled
2025-05-31 18:45:36 -04:00
Dax Raad e97ed735d9 sync 2025-05-31 18:42:43 -04:00
Dax Raad 6d21525e71 sync 2025-05-31 18:10:49 -04:00
Dax Raad b4f809559e tool rework
release / goreleaser (push) Has been cancelled
2025-05-31 17:12:16 -04:00
Dax Raad 33109bac4d fix generate 2025-05-31 16:06:51 -04:00
Dax Raad f072ab3276 lazy load LLMs even harder 2025-05-31 16:05:12 -04:00
Dax Raad 3b746162d2 run formatter 2025-05-31 14:41:00 -04:00
Dax Raad 6df19f1828 Standardize code style to no semicolons and remove unused @types/node dependency
🤖 Generated with opencode
Co-Authored-By: opencode <noreply@opencode.ai>
2025-05-30 22:14:09 -04:00
Dax Raad fba56d6871 Update package dependencies and lock file
Synchronized package.json and bun.lock with latest dependency versions and optimized package structure.

🤖 Generated with opencode
Co-Authored-By: opencode <noreply@opencode.ai>
2025-05-30 22:02:22 -04:00
Dax Raad 1472efcbfe Optimize package management with catalog and exact versions
- Add catalog feature to centralize common dependency versions
- Convert all package versions to exact (remove ^ prefixes)
- Move prettier to root package only to reduce duplication
- Configure bunfig.toml for exact dependency installs
- Improve version consistency across workspace packages

🤖 Generated with opencode
Co-Authored-By: opencode <noreply@opencode.ai>
2025-05-30 21:56:37 -04:00
Dax Raad 56a5d58945 sync 2025-05-30 21:42:03 -04:00
Dax Raad f50a57041f embed go 2025-05-30 21:26:53 -04:00
Dax Raad f3da73553c sync 2025-05-30 20:48:36 -04:00
Jay V 9a26b3058f listing themes explicitly 2025-05-30 17:06:03 -04:00
Jay V a09be7cf74 tweaking styles 2025-05-30 17:00:18 -04:00
Dax Raad 91a9e455e2 sync 2025-05-30 16:43:42 -04:00
Jay V c391c6d3f3 tweaking share edit 2025-05-30 16:42:59 -04:00
adamdottv ca562266b7 wip: refactoring tui 2025-05-30 15:37:04 -05:00
adamdottv c69c9327da wip: refactoring tui 2025-05-30 15:34:25 -05:00
Dax Raad f5e2c596d4 sync 2025-05-30 14:45:10 -04:00
Dax Raad e9bad39a7e sync 2025-05-30 14:40:59 -04:00
Dax Raad 42c7880858 sync 2025-05-30 14:40:59 -04:00
Jay V 017a440a70 refactor 2025-05-30 14:08:21 -04:00
Jay V 1ab9547bb2 import 2025-05-30 14:02:15 -04:00
Jay V a4e46e6e18 share page diff 2025-05-30 13:58:34 -04:00
Jay V 680d52016c adding diff 2025-05-30 13:58:34 -04:00
adamdottv 6ebbcb3179 wip: refactoring tui 2025-05-30 12:29:27 -05:00
adamdottv 437de4ee36 wip: refactoring tui 2025-05-30 10:37:09 -05:00
adamdottv a5b28b5cef wip: refactoring tui 2025-05-30 08:35:59 -05:00
adamdottv 9bf024f8be wip: refactoring tui 2025-05-30 08:29:37 -05:00
adamdottv 189d0e5fb2 wip: refactoring tui 2025-05-30 06:47:44 -05:00
adamdottv b1b402faa7 wip: refactoring tui 2025-05-30 06:03:34 -05:00
adamdottv c5413c8c8d wip: refactoring tui 2025-05-30 05:32:42 -05:00
adamdottv da1e8484a9 wip: refactoring tui 2025-05-29 15:42:18 -05:00
adamdottv 4818bc5426 wip: refactoring tui 2025-05-29 15:41:13 -05:00
adamdottv 8a8c6b14af wip: refactoring tui 2025-05-29 15:40:37 -05:00
adamdottv 0e31bbcd93 wip: refactoring tui 2025-05-29 15:37:06 -05:00
adamdottv 913b3434d8 wip: refactoring tui 2025-05-29 15:30:39 -05:00
adamdottv 1c01ee4834 wip: refactoring tui 2025-05-29 15:22:25 -05:00
adamdottv 005d6e0bde wip: refactoring tui 2025-05-29 15:18:47 -05:00
adamdottv 37c0c1f358 wip: refactoring tui 2025-05-29 15:10:44 -05:00
adamdottv 2a132f86d6 wip: refactoring tui 2025-05-29 15:02:22 -05:00
adamdottv 50ba0b380b wip: refactoring tui 2025-05-29 14:39:37 -05:00
adamdottv 6cccbdccd3 wip: refactoring tui 2025-05-29 14:20:55 -05:00
Dax Raad d0ad09d798 Improve async share handling and enhance diagnostic output with filenames
🤖 Generated with opencode
Co-Authored-By: opencode <noreply@opencode.ai>
2025-05-29 15:16:42 -04:00
Dax Raad 4fa4246c10 Fix working indicator to only show when message is incomplete
🤖 Generated with opencode
Co-Authored-By: opencode <noreply@opencode.ai>
2025-05-29 15:10:23 -04:00
Dax Raad 0fe72864f2 remov elog 2025-05-29 15:05:44 -04:00
adamdottv ce5b3126d3 wip: refactoring tui 2025-05-29 14:04:49 -05:00
adamdottv 26606ccbf7 wip: refactoring tui 2025-05-29 14:04:49 -05:00
adamdottv fce9e79d38 wip: refactoring tui 2025-05-29 14:04:48 -05:00
adamdottv 6759674c0f wip: refactoring tui 2025-05-29 14:04:48 -05:00
Dax Raad a9799136fe support continuation 2025-05-29 14:29:08 -04:00
Jay V 7a29af4e30 styling tool calls 2025-05-29 14:24:25 -04:00
Dax Raad d398001f96 Remove React/Ink dependencies and add context window management
- Remove unused React and Ink CLI dependencies to simplify package
- Update provider schema to use maxOutputTokens for clarity
- Add automatic summarization when approaching context window limits
- Simplify message event handling and add cost/token metadata display

🤖 Generated with opencode
Co-Authored-By: opencode <noreply@opencode.ai>
2025-05-29 14:16:15 -04:00
Dax Raad e68747a64a add summarize 2025-05-29 13:17:56 -04:00
Dax Raad d62ce482da fix race 2025-05-29 13:15:58 -04:00
Dax Raad f9f41e205d add summarize 2025-05-29 13:02:48 -04:00
Dax Raad 80597cd3fd type error fix 2025-05-29 11:58:40 -04:00
Dax Raad 48f81fe4d3 sync 2025-05-29 11:38:55 -04:00
Dax Raad a96c2ce65c sync 2025-05-29 11:35:56 -04:00
Dax Raad 6f604bd0f9 remove secondary codegen 2025-05-29 11:32:55 -04:00
Dax Raad 42c1cd6a85 event 2025-05-29 11:17:34 -04:00
Dax Raad 33a831d2be rework types 2025-05-29 10:22:07 -04:00
adamdottv d70201cd93 wip: refactoring tui 2025-05-29 06:45:34 -05:00
adamdottv 9f1a75e938 wip: refactoring tui 2025-05-29 06:42:58 -05:00
adamdottv 2b77a7f714 wip: refactoring tui 2025-05-29 06:32:44 -05:00
Jay V 5974a53071 styling share 2025-05-28 20:04:58 -04:00
Jay V 3d61cc5d2b styling share 2025-05-28 18:32:40 -04:00
Dax Raad a22a2f0f37 autoshare 2025-05-28 17:34:37 -04:00
Dax Raad be65ed6f88 sync 2025-05-28 17:25:00 -04:00
Dax Raad e88264075a sync 2025-05-28 17:24:21 -04:00
Jay V 041a080a13 refactor share 2025-05-28 16:42:44 -04:00
adamdottv 9d7c5efb9b wip: refactoring tui 2025-05-28 15:36:36 -05:00
adamdottv 8863a499a9 wip: refactoring tui 2025-05-28 15:36:35 -05:00
adamdottv 15d21bf04a wip: refactoring tui 2025-05-28 15:36:35 -05:00
adamdottv 5e738ce7d3 wip: refactoring tui 2025-05-28 15:36:35 -05:00
adamdottv 641e9ff664 chore: cleanup unused imports 2025-05-28 15:36:35 -05:00
adamdottv d249766777 chore: remove dead code 2025-05-28 15:36:35 -05:00
Dax Raad 6cf4b7f00b sync 2025-05-28 15:40:35 -04:00
Dax Raad 6183398543 sync 2025-05-28 15:39:51 -04:00
Dax Raad ff786d9139 abort 2025-05-28 15:07:51 -04:00
Dax Raad 4767276a0e more 2025-05-28 14:17:02 -04:00
Jay V 71bab45065 styling share 2025-05-28 14:10:20 -04:00
Dax Raad cb48813c95 sync 2025-05-28 13:58:55 -04:00
Dax Raad 520cd02dd5 added cost field 2025-05-28 13:57:24 -04:00
Dax Raad afe741b63e add cost 2025-05-28 13:57:02 -04:00
Dax Raad f3b224090c better discriminator 2025-05-28 13:35:05 -04:00
Dax Raad 3b7b7f4bea add runtime 2025-05-28 13:24:35 -04:00
Dax Raad 3a4d3b249f generate message type 2025-05-28 13:22:48 -04:00
Dax Raad 55a6fcdd3f add provider_list 2025-05-28 12:53:22 -04:00
Dax Raad 4132fcc1b2 return tool errors properly 2025-05-27 21:53:21 -04:00
Jay V 37082b2176 styling share 2025-05-27 20:38:29 -04:00
Dax Raad b9f009c529 title 2025-05-27 17:22:29 -04:00
Dax Raad 601f610eb7 sync 2025-05-27 16:56:12 -04:00
Dax Raad 2e2bdd46b4 sync 2025-05-27 15:41:44 -04:00
Dax Raad 3a28ce9b0a sync 2025-05-27 15:37:46 -04:00
Dax Raad bb6fc2a1fd regen client 2025-05-27 15:35:48 -04:00
Dax Raad ad76fa8616 fix 2025-05-27 15:35:31 -04:00
Dax Raad bdac7d10dd add session list 2025-05-27 15:34:46 -04:00
Dax Raad 0ecfdd7501 fix type errors 2025-05-27 15:28:58 -04:00
Dax Raad a9758e0db5 vomit 2025-05-27 15:26:49 -04:00
Dax Raad e98f915fd5 stripped 2025-05-27 15:20:43 -04:00
Dax Raad 07f0fea4bf trust sharp 2025-05-27 14:36:23 -04:00
Dax Raad 6a43afc4e7 sync 2025-05-27 14:31:53 -04:00
Dax Raad c01eefc729 Add manual trigger option to deployment workflow
🤖 Generated with opencode
Co-Authored-By: opencode <noreply@opencode.ai>
2025-05-27 14:30:52 -04:00
Dax Raad 5d4ccc8883 Add GitHub Actions deployment workflow to automate deployments
🤖 Generated with opencode
Co-Authored-By: opencode <noreply@opencode.ai>
2025-05-27 14:29:36 -04:00
Dax Raad 98b5390a22 Refactor grep tool output generation and fix ls directory traversal bug
🤖 Generated with opencode
Co-Authored-By: opencode <noreply@opencode.ai>
2025-05-27 02:26:53 -04:00
Dax Raad c040baae11 Refactor LSP tools and add hover functionality
- Split diagnostics tool into separate lsp-diagnostics.ts file
- Add new lsp-hover.ts tool for LSP hover information
- Update tool exports and session integration
- Remove old diagnostics.ts file

🤖 Generated with opencode
Co-Authored-By: opencode <noreply@opencode.ai>
2025-05-27 02:17:35 -04:00
Dax Raad 754cc66741 Add automatic CONTEXT.md loading and improve share sync reliability
🤖 Generated with opencode
Co-Authored-By: opencode <noreply@opencode.ai>
2025-05-26 23:04:40 -04:00
Dax Raad 6ef0b991ec Fix race condition in share sync by implementing request queue
🤖 Generated with opencode
Co-Authored-By: opencode <noreply@opencode.ai>
2025-05-26 22:56:58 -04:00
Dax Raad f6ca06b8ea track tokens progressively 2025-05-26 22:35:30 -04:00
Dax Raad 4c198940d5 Remove debug console.log statements and improve LSP diagnostic handling
🤖 Generated with opencode
Co-Authored-By: opencode <noreply@opencode.ai>
2025-05-26 22:25:17 -04:00
Dax Raad 2e938d9da1 Standardize API parameters to camelCase and improve LSP client reliability
- Convert tool parameters from snake_case to camelCase for consistency
- Add file existence check in LSP client before opening files
- Fix version increment timing in LSP textDocument operations
- Optimize session token tracking using onStepFinish callback
- Add debugging logs for diagnostics troubleshooting

🤖 Generated with opencode
Co-Authored-By: opencode <noreply@opencode.ai>
2025-05-26 22:08:50 -04:00
Dax Raad b840a40759 sync 2025-05-26 21:44:55 -04:00
Dax Raad a1d40f8f28 add context.md 2025-05-26 21:38:17 -04:00
Dax Raad 575d76fa06 Fix session update to use proper getter and correct operation order
🤖 Generated with opencode
Co-Authored-By: opencode <noreply@opencode.ai>
2025-05-26 21:25:20 -04:00
Dax Raad b75456f5dd Clean up code formatting and remove unused imports for better consistency
🤖 Generated with opencode
Co-Authored-By: opencode <noreply@opencode.ai>
2025-05-26 21:22:38 -04:00
Dax Raad eb69cc3943 sync 2025-05-26 21:13:46 -04:00
Dax Raad e524209352 title 2025-05-26 21:08:22 -04:00
Jay V e1c897c1ae styles 2025-05-26 20:33:21 -04:00
Jay V 39f54e83e1 styles 2025-05-26 19:05:17 -04:00
Jay V d34c974996 adding styles 2025-05-26 19:01:50 -04:00
Frank c203891b84 Share: sync 2025-05-26 18:54:11 -04:00
Dax Raad 591bd2a4e3 sync 2025-05-26 18:14:36 -04:00
Dax Raad 94f35130f7 sync 2025-05-26 18:10:10 -04:00
Dax Raad f26873f5de sync 2025-05-26 18:06:47 -04:00
Jay V 66b18959eb Merging docs and share app 2025-05-26 17:25:12 -04:00
Jay V deacf5991a Adding share page 2025-05-26 17:25:12 -04:00
Dax Raad 25623d1f84 sync 2025-05-26 17:22:31 -04:00
Dax Raad de9f144858 sync 2025-05-26 17:15:47 -04:00
Dax Raad 0ad8738933 sync 2025-05-26 17:15:47 -04:00
Frank db5744bbc4 Share: sync 2025-05-26 16:35:03 -04:00
Dax Raad b87ba57819 shutdown 2025-05-26 14:52:38 -04:00
Dax Raad 802389a90e fixed id generation 2025-05-26 14:36:45 -04:00
Dax Raad 4880b08b8a sync 2025-05-26 14:18:07 -04:00
Dax Raad 80555f13e0 more tools 2025-05-26 14:09:17 -04:00
Dax Raad 113c49457f ls tool 2025-05-26 13:44:59 -04:00
Dax Raad e1ec815d1b sync 2025-05-26 13:39:16 -04:00
Dax Raad 2ed17f4877 exit properly 2025-05-26 13:21:15 -04:00
Frank 80118212da Share: sync 2025-05-26 12:40:17 -04:00
Frank 9b3760247a Share: sync 2025-05-26 12:40:17 -04:00
Dax Raad a2d652b13d sync 2025-05-26 12:40:17 -04:00
Dax Raad 5c491758f5 sync 2025-05-26 12:40:17 -04:00
Dax Raad 5f750b7368 share 2025-05-26 12:40:17 -04:00
Frank e2dc5a8faf Share: sync 2025-05-26 12:40:17 -04:00
Frank 72d10a0823 Share: fix types 2025-05-26 12:40:17 -04:00
Frank 7623b33f31 Share: sync 2025-05-26 12:40:17 -04:00
Frank 9b331a917e Share: sync 2025-05-26 12:40:17 -04:00
Frank d51b4263ab Share: sync 2025-05-26 12:40:17 -04:00
Frank 34a2dcb80a Share: sync 2025-05-26 12:40:17 -04:00
Frank 8cbd59296e Share: syc 2025-05-26 12:40:17 -04:00
Frank 83974e0c95 Share: sync 2025-05-26 12:40:17 -04:00
Dax Raad 59d43fa5da add diagnostics meta 2025-05-26 12:40:17 -04:00
Dax Raad e01afb407c add tool tests 2025-05-26 12:40:17 -04:00
Dax Raad f0f55bc75f sync 2025-05-26 12:40:17 -04:00
Dax Raad 2860a2bb1a sync 2025-05-26 12:40:17 -04:00
Dax Raad 9b564f0b73 tool meta 2025-05-26 12:40:17 -04:00
Dax Raad 2437ce3f8b toolz 2025-05-26 12:40:17 -04:00
Dax Raad fa8a46326a codegen 2025-05-26 12:40:17 -04:00
Dax Raad 652429377b sync 2025-05-26 12:40:17 -04:00
Dax Raad 99af6146d5 openapi 2025-05-26 12:40:17 -04:00
Dax Raad 020e0ca039 sync 2025-05-26 12:40:17 -04:00
Dax Raad 0439072420 fix 2025-05-26 12:40:17 -04:00
Dax Raad 49ad2efef6 sync 2025-05-26 12:40:17 -04:00
Dax Raad 0e303e6508 sync 2025-05-26 12:40:17 -04:00
Dax Raad bcd2fd68b7 sync 2025-05-26 12:40:17 -04:00
Dax Raad d0d67029f4 process 2025-05-26 12:40:17 -04:00
Dax Raad a34d020bc6 sync 2025-05-26 12:40:17 -04:00
Martin Palma 96fbc37f01 feat: ayu theme (#60) 2025-05-26 06:45:06 -05:00
Ed Zynda 89e3a72ae1 feat: add support for piped input to CLI (#51) 2025-05-23 06:54:09 -05:00
Ed Zynda b9ebcea82c really disable history nav when completions dialog is open (#50) 2025-05-23 06:43:30 -05:00
Jay f31f92119d Merge pull request #52 from sst/docs
Adding website
2025-05-22 15:23:09 -04:00
Jay V da9b2a18b9 editing docs 2025-05-22 15:10:08 -04:00
Dax Raad 2b258b1473 switch default to claude sonnet 4
release / goreleaser (push) Has been cancelled
2025-05-22 13:17:32 -04:00
Jay V 6f894950a6 adding other chapters 2025-05-21 19:34:50 -04:00
Jay V 9049295cc9 Merge branch 'dev' into docs 2025-05-21 15:01:25 -04:00
Jay V 4526b14b17 Moving readme to docs 2025-05-21 15:01:12 -04:00
Jay V f768313c4f Moving readme to docs 2025-05-21 14:59:09 -04:00
Jay V d9c1b2cc90 adding docs site 2025-05-21 14:58:30 -04:00
Jay V 6cfcf51752 adding docs site 2025-05-21 14:24:53 -04:00
Alvin Johansson dff8e77eb6 docs: add clearer bedrock instructions (#40) 2025-05-20 08:23:51 -05:00
Ed Zynda 6e854a4df4 fix: disable history navigation when filepicker is open (#39) 2025-05-18 18:41:34 -05:00
phantomreactor 2f8984fadb Codex mini (#34) 2025-05-18 08:29:53 -05:00
Ed Zynda c84918cb47 feat: Add message history navigation with arrow keys (#30) 2025-05-17 13:35:49 -05:00
Pierre B. 05bb065d00 fix: log pane text wrapping (#32) 2025-05-17 13:33:47 -05:00
Pierre Berube 3742997889 fix: typo 2025-05-17 08:50:30 -05:00
Pierre Berube daf0305203 fix: split out bedrock models 2025-05-17 08:48:51 -05:00
Ed Zynda 307982a099 feat: Add tool restriction flags for non-interactive mode (#29)
release / goreleaser (push) Has been cancelled
2025-05-17 08:23:13 -05:00
phantomreactor ba416e787b paste images with ctrl+v (#26) 2025-05-16 14:31:50 -05:00
Ed Zynda b71cae63f1 feat: Add tools dialog accessible via F9 (#24)
* Add tools dialog

* Remove sorting and double items

* Update key handling
2025-05-16 10:57:35 -05:00
Ed Zynda c92f7c6630 fix: Show correct file paths in permission window (#25)
* Fix paths in permission window to show relative paths

* Fix paths in permission window to show actual file paths
2025-05-16 10:56:39 -05:00
Ed Zynda 4a444e9c9b feat: Make shell configurable via config file (#23) 2025-05-16 06:27:28 -05:00
Ed Zynda 623d132772 feat: Add non-interactive mode (#18) 2025-05-16 06:06:28 -05:00
adamdottv d127a1c4eb feat: 0-255 color support in custom themes 2025-05-15 19:02:27 -05:00
adamdottv c9cca48d08 fix: layout
release / goreleaser (push) Has been cancelled
2025-05-15 15:57:15 -05:00
adamdottv 3944930fc0 chore: cleanup 2025-05-15 15:45:22 -05:00
adamdottv 825c0b64af fix: build 2025-05-15 14:49:30 -05:00
adamdottv d7af7dd3fe fix: redundant status msg 2025-05-15 14:42:10 -05:00
adamdottv b112216241 fix: build 2025-05-15 13:36:58 -05:00
mineo 87237b6462 feat: support VertexAI provider (#153)
* support: vertexai

fix

fix

set default for vertexai

added comment

fix

fix

* create schema

* fix README.md

* fix order

* added pupularity

* set tools if tools is exists

restore commentout

* fix comment

* set summarizer model
2025-05-15 13:35:06 -05:00
phantomreactor 5f5f9dad87 add support to preview webp images and paste file paths
release / goreleaser (push) Has been cancelled
2025-05-15 12:55:36 -05:00
adamdottv aa8b3ce1ee fix: init ordering 2025-05-15 12:52:42 -05:00
adamdottv a65e593ab4 feat: batch tool 2025-05-15 12:44:16 -05:00
adamdottv 5d9058eb74 fix: tui height 2025-05-15 12:18:28 -05:00
adamdottv a850320fad fix: don't limit session logs 2025-05-15 12:05:26 -05:00
adamdottv ddbb217d0d feat: better status bar 2025-05-15 12:04:15 -05:00
Ed Zynda ab150be7c3 feat: Support named arguments in custom commands (#158)
* Allow multiple named args

* fix: Fix styling in multi-arguments dialog

* Remove old unused modal

* Focus on only one input at a time
2025-05-15 09:43:33 -05:00
Adictya a203fb8ccc fix(complete-module): change completion start key to slash
release / goreleaser (push) Has been cancelled
2025-05-15 08:29:54 -05:00
Adictya acc084c9ea chore(complete-module): lint 2025-05-15 08:29:54 -05:00
Adictya 3ee213081e fix(complete-module): logging 2025-05-15 08:29:54 -05:00
Adictya 15bf40bc10 feat(complete-module): add completions logic, dialog and providers 2025-05-15 08:29:54 -05:00
adamdottv a33e3e25b6 chore: cleanup dead code 2025-05-15 07:19:17 -05:00
adamdottv 658faab2bf chore: update icon in readme 2025-05-15 07:03:58 -05:00
rekram1-node 797045ee29 feat: add configuration persistence for model selections 2025-05-14 16:32:05 -05:00
adamdottv c8f8d67a88 feat: codeAction tool
release / goreleaser (push) Has been cancelled
2025-05-14 14:57:47 -05:00
Dax Raad 182e32e4f7 add screenshot 2025-05-14 15:50:25 -04:00
adamdottv 5ea989fb74 feat: docSymbols and workspaceSymbols tools
release / goreleaser (push) Has been cancelled
2025-05-14 14:40:45 -05:00
adamdottv 45c778b90d feat: definition and references tools 2025-05-14 14:25:15 -05:00
Dax Raad 47cbb650a0 ci
release / goreleaser (push) Has been cancelled
2025-05-14 14:30:47 -04:00
Dax Raad e91371c6a5 ci 2025-05-14 14:27:18 -04:00
adamdottv 9d17314309 fix: tweak 2025-05-14 13:15:39 -05:00
adamdottv 3982be4310 feat: session specific logs 2025-05-14 13:06:09 -05:00
adamdottv 4c998d4f4f chore: remove sourcegraph tool 2025-05-14 10:42:16 -05:00
adamdottv f7849c2d59 fix: log display 2025-05-14 07:47:15 -05:00
adamdottv 463002185b fix: log perf 2025-05-14 07:38:21 -05:00
adamdottv 53a80eac1e chore: cleanup 2025-05-14 06:00:34 -05:00
adamdottv 01b6bf5bb7 chore: refactor db 2025-05-13 13:08:43 -05:00
adamdottv d8f3b60625 chore: refactoring 2025-05-13 11:34:48 -05:00
adamdottv cf8e16018d chore: refactoring 2025-05-13 11:15:14 -05:00
adamdottv 674797bd48 chore: refactoring 2025-05-13 11:07:34 -05:00
adamdottv 1f9610e266 chore: refactoring 2025-05-13 10:45:58 -05:00
adamdottv ae86ef519c chore: refactoring 2025-05-13 10:27:09 -05:00
adamdottv 2391e338b4 chore: rename 2025-05-13 10:02:39 -05:00
adamdottv 1e9399fbee chore: cleanup 2025-05-13 09:26:54 -05:00
adamdottv e9f74b867f chore: cleanup 2025-05-13 07:15:58 -05:00
adamdottv 5079556896 chore: cleanup 2025-05-13 07:04:27 -05:00
adamdottv 7f0e68b933 chore: cleanup 2025-05-13 06:55:18 -05:00
adamdottv 0c21ca5318 chore: cleanup 2025-05-13 06:51:28 -05:00
adamdottv 0117c72a2c chore: refactor diff 2025-05-12 15:17:50 -05:00
adamdottv e3eb9e5435 chore: refactor diff 2025-05-12 14:48:13 -05:00
adamdottv d941be3f1f chore: refactor agent.go 2025-05-12 14:43:12 -05:00
adamdottv 36e5ae804e chore: rename coder -> primary 2025-05-12 14:32:27 -05:00
adamdottv c9b90dd184 fix: show context % 2025-05-12 14:08:57 -05:00
adamdottv 8270a1e4b1 chore: cleanup 2025-05-12 13:01:59 -05:00
adamdottv 7f9c992993 fix: log status messages 2025-05-12 12:53:20 -05:00
adamdottv b6524c0982 chore: cleanup 2025-05-12 11:38:07 -05:00
adamdottv 425c0f1bab fix: timestamp formatting 2025-05-12 11:33:52 -05:00
adamdottv d20d0c5a95 chore: cleanup 2025-05-12 11:22:19 -05:00
adamdottv 5af3c05d41 chore: cleanup 2025-05-12 10:53:13 -05:00
adamdottv df4a9295c0 chore: cleanup 2025-05-12 10:46:14 -05:00
adamdottv 8cbfc581b5 chore: cleanup 2025-05-12 10:45:03 -05:00
Nicholas Hamilton 4bb350a09b Fix filepicker manual input (#146)
* fix: allows to type i while manual inputting filepath

* fix: file selection in filepicker focus mode

* remove duplicate code
2025-05-12 10:01:56 -05:00
adamdottv 17c5b9c12c fix: build 2025-05-12 09:59:57 -05:00
Ed Zynda 1f8580553c feat: custom commands (#133)
* Implement custom commands

* Add User: prefix

* Reuse var

* Check if the agent is busy and if so report a warning

* Update README

* fix typo

* Implement user and project scoped custom commands

* Allow for $ARGUMENTS

* UI tweaks

* Update internal/tui/components/dialog/arguments.go

Co-authored-by: Kujtim Hoxha <kujtimii.h@gmail.com>

* Also search in $HOME/.opencode/commands

---------

Co-authored-by: Kujtim Hoxha <kujtimii.h@gmail.com>
2025-05-12 09:58:59 -05:00
mineo f92b2b76dc replace github.com/google/generative-ai-go with github.com/googleapis/go-genai (#138)
* replace to github.com/googleapis/go-genai

* fix history logic

* small fixes

---------

Co-authored-by: Kujtim Hoxha <kujtimii.h@gmail.com>
2025-05-12 09:56:30 -05:00
adamdottv 1d1a1ddcbf fix: visual tweaks 2025-05-12 09:54:20 -05:00
adamdottv dfe5fd8d97 wip: refactoring 2025-05-12 09:44:56 -05:00
adamdottv ed9fba99c9 wip: refactoring 2025-05-12 08:43:34 -05:00
adamdottv f100777199 wip: logging improvements 2025-05-09 13:37:13 -05:00
adamdottv f41b7bbd0a chore: refactoring status updates 2025-05-08 12:03:59 -05:00
adamdottv e35ea2d448 fix: log page nav 2025-05-08 07:59:15 -05:00
adamdottv bab17d7520 feat: session manager 2025-05-08 07:58:37 -05:00
adamdottv 051d7d7936 chore: logging token usage 2025-05-06 14:40:00 -05:00
adamdottv b638dafe5f feat: better logs page 2025-05-06 14:22:37 -05:00
adamdottv e387b1f16c fix: openrouter require_parameters 2025-05-06 11:17:32 -05:00
adamdottv 71a68dd56d feat: add qwen3 models 2025-05-06 10:19:07 -05:00
adamdottv 3ee8ebd3d3 fix: auto-compact logic 2025-05-06 10:03:21 -05:00
adamdottv ef298b2f18 fix: hide empty messages 2025-05-05 14:38:33 -05:00
adamdottv 3cc08494a5 fix: pubsub leak and shutdown seq 2025-05-05 14:23:29 -05:00
adamdottv afcdabd095 fix: anthropic non-empty blocks 2025-05-05 12:00:09 -05:00
adamdottv efaba6c5b8 feat: hide tool calls 2025-05-05 11:25:34 -05:00
adamdottv 874715838a feat: show sender name and timestamp 2025-05-05 11:02:02 -05:00
adamdottv 167eb9ddfa fix: diagnostics visual in status bar 2025-05-05 07:04:33 -05:00
Joshua LaMorey-Salzmann fba344718f Config fix correcting loose viper string check, default model now set correctly (#147) 2025-05-05 06:56:10 -05:00
adamdottv cdd906e32e fix: bedrock supports attachments 2025-05-02 15:35:24 -05:00
phantomreactor ff0ef3bb43 feat: add support for images 2025-05-02 15:29:46 -05:00
adamdottv 0095832be3 chore: cleanup and logging 2025-05-02 15:24:47 -05:00
adamdottv 406ccf9b87 fix: diagnostics tool init 2025-05-02 15:24:47 -05:00
adamdottv f90d6238ed fix: bedrock context window 2025-05-02 15:24:47 -05:00
adamdottv f004a0b8c3 fix: anthropic non-empty blocks 2025-05-02 15:24:47 -05:00
adamdottv 49423da081 feat: compact command with auto-compact 2025-05-02 15:24:47 -05:00
adamdottv 364cf5b429 feat: write to context.md by default 2025-05-02 15:24:47 -05:00
adamdottv b2f24e38ed feat: better diagnostic visuals in status bar 2025-05-02 15:24:47 -05:00
adamdottv 49037e7b28 feat: better logs page 2025-05-02 15:24:47 -05:00
adamdottv c66832d299 fix: wording 2025-05-01 11:54:35 -05:00
adamdottv 7398b4ce70 fix: don't truncate task tool output 2025-05-01 11:35:54 -05:00
Kujtim Hoxha a61b2026eb add xai support (#135) 2025-05-01 11:08:26 -05:00
Aiden Cline 69ade34c2c fix: tweak the logic in config to ensure that env vs file configurations merge properly (#115) 2025-05-01 11:08:17 -05:00
Garrett Ladley fbca5441f6 feat: test for getContextFromPaths (#105)
* feat: test for getContextFromPaths

* fix: use testify
2025-05-01 11:08:06 -05:00
Kujtim Hoxha e4680caebb some small fixes 2025-05-01 11:07:47 -05:00
adamdottv e760d28c5a feat: show hunk headers 2025-05-01 09:02:14 -05:00
adamdottv 7d5f0f9d18 fix: pass input to EDITOR 2025-05-01 07:58:27 -05:00
adamdottv 515f4e8642 fix: visual tweaks 2025-05-01 07:32:04 -05:00
adamdottv f2b36b9234 fix: remove lsp tool 2025-05-01 07:28:37 -05:00
adamdottv f224978bbc fix: remove manual lsp definition 2025-05-01 07:24:53 -05:00
adamdottv 8819a37a05 fix: logo 2025-05-01 06:43:59 -05:00
adamdottv 769dff00ba fix: don't mark as init 2025-05-01 06:43:30 -05:00
adamdottv d1be7a984e fix: logo 2025-05-01 06:36:30 -05:00
adamdottv 3e30607a6d fix: minor prompt fix 2025-05-01 06:35:47 -05:00
adamdottv d08e58279d feat: lsp discovery 2025-05-01 06:26:20 -05:00
adamdottv 7bc542abff fix: better diagnostics visual 2025-04-30 15:23:19 -05:00
adamdottv ed50c36789 fix: lsp issues with tmp and deleted files 2025-04-30 12:20:51 -05:00
adamdottv 98cf65b425 fix: more intuitive keybinds 2025-04-30 11:34:21 -05:00
adamdottv 5406083850 fix: minor icon tweak 2025-04-30 11:33:30 -05:00
adamdottv 91ae9b33d3 feat: custom themes 2025-04-30 11:05:59 -05:00
adamdottv a42175c067 fix: info and hint icons 2025-04-30 07:47:14 -05:00
adamdottv 8497145db2 fix: status sizing 2025-04-30 07:47:10 -05:00
adamdottv 89544fad61 feat: tron theme 2025-04-30 07:46:35 -05:00
adamdottv 1151accf4b feat: tokyonight theme 2025-04-30 07:46:35 -05:00
adamdottv 1ae3f1830b feat: dracula theme 2025-04-30 07:46:35 -05:00
adamdottv 1e958b62ad feat: opencode theme (default) 2025-04-30 07:46:35 -05:00
adamdottv fdf5367f4f feat: monokai pro theme 2025-04-30 07:46:34 -05:00
adamdottv 0e8842a007 feat: onedark theme 2025-04-30 07:46:34 -05:00
adamdottv 060994f393 feat: flexoki theme 2025-04-30 07:46:34 -05:00
adamdottv 61b605e724 feat: themes 2025-04-30 07:46:34 -05:00
Adam 61d9dc9511 fix: allow text selection (#127) 2025-04-30 12:52:30 +02:00
Hunter Casten 76275e533e fix(openrouter): set api key from env (#129) 2025-04-30 12:50:57 +02:00
Isaac Scarrott 98e2910e82 feat: Add support for OpenRouter (#92)
release / goreleaser (push) Has been cancelled
* Add support for OpenRouter as a new model provider

- Introduced `ProviderOpenRouter` in the `models` package.
- Added OpenRouter-specific models, including `GPT41`, `GPT41Mini`, `GPT4o`, and others, with their configurations and costs.
- Updated `generateSchema` to include OpenRouter as a provider.
- Added OpenRouter-specific environment variable handling (`OPENROUTER_API_KEY`) in `config.go`.
- Implemented default model settings for OpenRouter agents in `setDefaultModelForAgent`.
- Updated `getProviderAPIKey` to retrieve the OpenRouter API key.
- Extended `SupportedModels` to include OpenRouter models.
- Added OpenRouter client initialization in the `provider` package.
- Modified `processGeneration` to handle `FinishReasonUnknown` in addition to `FinishReasonToolUse`.

* [feature/openrouter-provider] Add new models and provider to schema

- Added "deepseek-chat-free" and "deepseek-r1-free" to the list of supported models in `opencode-schema.json`.

* [feature/openrouter-provider] Add OpenRouter provider support and integrate new models

- Updated README.md to include OpenRouter as a supported provider and its configuration details.
- Added `OPENROUTER_API_KEY` to environment variable configuration.
- Introduced OpenRouter-specific models in `internal/llm/models/openrouter.go` with mappings to existing cost and token configurations.
- Updated `internal/config/config.go` to set default models for OpenRouter agents.
- Extended `opencode-schema.json` to include OpenRouter models in the schema definitions.
- Refactored model IDs and names to align with OpenRouter naming conventions.

* [feature/openrouter-provider] Refactor finish reason handling and tool call logic in agent and OpenAI provider

- Simplified finish reason check in `agent.go` by removing redundant variable assignment.
- Updated `openai.go` to override the finish reason to `FinishReasonToolUse` when tool calls are present.
- Ensured consistent finish reason handling in both `send` and `stream` methods of the OpenAI provider.

[feature/openrouter-provider] Refactor finish reason handling and tool call logic in agent and OpenAI provider

- Simplified finish reason check in `agent.go` by removing redundant variable assignment.
- Updated `openai.go` to override the finish reason to `FinishReasonToolUse` when tool calls are present.
- Ensured consistent finish reason handling in both `send` and `stream` methods of the OpenAI provider.

* **[feature/openrouter-provider] Add support for custom headers in OpenAI client configuration**

- Introduced a new `extraHeaders` field in the `openaiOptions` struct to allow specifying additional HTTP headers.
- Added logic in `newOpenAIClient` to apply `extraHeaders` to the OpenAI client configuration.
- Implemented a new option function `WithOpenAIExtraHeaders` to set custom headers in `openaiOptions`.
- Updated the OpenRouter provider configuration in `NewProvider` to include default headers (`HTTP-Referer` and `X-Title`) for OpenRouter API requests.

* Update OpenRouter model config and remove unsupported models

* [feature/openrouter-provider] Update OpenRouter models and default configurations

- Added new OpenRouter models: `claude-3.5-sonnet`, `claude-3-haiku`, `claude-3.7-sonnet`, `claude-3.5-haiku`, and `claude-3-opus` in `openrouter.go`.
- Updated default agent models in `config.go`:
  - `agents.coder.model` now uses `claude-3.7-sonnet`.
  - `agents.task.model` now uses `claude-3.7-sonnet`.
  - `agents.title.model` now uses `claude-3.5-haiku`.
- Updated `opencode-schema.json` to include the new models in the allowed list for schema validation.
- Adjusted logic in `setDefaultModelForAgent` to reflect the new default models.

* [feature/openrouter-provider] Remove unused ProviderEvent emission in stream function

The changes remove the emission of a `ProviderEvent` with type `EventContentStop` in the `stream` function of the `openaiClient` implementation. This event was sent upon successful stream completion but is no longer used.
2025-04-29 13:56:49 +02:00
Kujtim Hoxha 2941137416 fix diagnostics for deleted files 2025-04-28 19:37:42 +02:00
Aiden Cline b3c0285db3 feat: model selection for given provider (#57)
release / goreleaser (push) Has been cancelled
* feat: model selection for given provider

* tweak: adjust cfg validation func, remove duplicated logic, consolidate agent updating into agent.go

* tweak: make the model dialog scrollable, adjust padding slightly for modal"

* feat: add provider selection, add hints, simplify some logic, add horizontal scrolling support, additional scroll indicators"

* remove nav help

* update docs

* increase number of visible models, make horizontal scroll "wrap"

* add provider popularity rankings
2025-04-28 19:25:06 +02:00
YJG 805aeff83c feat: add azure openai models (#74) 2025-04-28 15:42:57 +02:00
Kujtim Hoxha bce2ec5c10 fix duplicate context
release / goreleaser (push) Has been cancelled
2025-04-27 20:43:27 +02:00
Kujtim Hoxha 292e9d90ca remove unnecessary var 2025-04-27 20:34:20 +02:00
Kujtim Hoxha 2b4441a0d1 fix context
release / goreleaser (push) Has been cancelled
2025-04-27 20:31:53 +02:00
Garrett Ladley 8f3a94df92 feat: configure context paths (#86)
release / goreleaser (push) Has been cancelled
2025-04-27 20:11:09 +02:00
Kujtim Hoxha 4415220555 fix minor issue
release / goreleaser (push) Has been cancelled
2025-04-27 19:24:46 +02:00
Kujtim Hoxha a3a04d8a54 fix gemini provider
release / goreleaser (push) Has been cancelled
2025-04-27 19:12:02 +02:00
Lukáš Loukota 792e2b164b fix: gemini tool calling 2025-04-27 19:12:02 +02:00
Kujtim Hoxha 5859dcdc00 small glob fixes 2025-04-27 18:01:31 +02:00
isaac-scarrott 3c2b0f4dd0 [feature/ripgrep-glob] Add ripgrep-based file globbing to improve performance
- Introduced `globWithRipgrep` function to perform file globbing using the `rg` (ripgrep) command.
- Updated `globFiles` to prioritize ripgrep-based globbing and fall back to doublestar-based globbing if ripgrep fails.
- Added logic to handle ripgrep command execution, output parsing, and filtering of hidden files.
- Ensured results are sorted by path length and limited to the specified maximum number of matches.
- Modified imports to include `os/exec` and `bytes` for ripgrep integration.
2025-04-27 18:01:31 +02:00
Kujtim Hoxha 9738886620 fix provider config
release / goreleaser (push) Has been cancelled
2025-04-27 14:44:40 +02:00
Sam Ottenhoff f3dccad54b Handle new Cursor rules format
1. Check if a path ends with a slash (/)
2. If it does, treat it as a directory and read all files within it
3. For directories like .cursor/rules/, it will scan all files and include their content in the prompt
4. Each file from a directory will be prefixed with "# From filename" for clarity
2025-04-27 14:17:06 +02:00
Kujtim Hoxha b3a8dbd0d9 fix retry warning
release / goreleaser (push) Has been cancelled
2025-04-27 14:08:09 +02:00
Garrett Mitchell Ladley d93694a979 feat: simpler diff implementation 2025-04-27 13:56:57 +02:00
Fuad 8a4d4152ce use workingDir if shellInstance is nil otherwise use cwd if shellInstance is not nil 2025-04-27 13:46:59 +02:00
Fuad f12386e558 use provided workingg dir 2025-04-27 13:46:59 +02:00
Fuad 94aeb7b7fe Fix nil pointer dereference in GetPersistentShell
Added nil check in GetPersistentShell before accessing
shellInstance.isAlive
to prevent panic when newPersistentShell returns nil due to shell
startup
errors. This resolves the "invalid memory address or nil pointer
dereference"
error that was occurring in the shell tool.
2025-04-27 13:46:59 +02:00
Kujtim Hoxha a35466cdb3 fix acc error
release / goreleaser (push) Has been cancelled
2025-04-25 21:58:14 +02:00
Kujtim Hoxha 170c7ad67a small fixes 2025-04-25 14:42:47 +02:00
Hunter Casten 7a62ab7675 feat(groq): add support for Groq using the OpenAI provider 2025-04-25 11:11:52 +02:00
Kujtim Hoxha 1586d757dc remove tool timeout 2025-04-24 22:35:17 +02:00
Dax Raad d043526200 add more installation options 2025-04-24 16:34:57 -04:00
Kujtim Hoxha aaf0bc14ba try fix 2025-04-24 22:27:51 +02:00
Kujtim Hoxha f2d9bb7ee3 try fix 2025-04-24 22:27:51 +02:00
Kujtim Hoxha de41703e20 change db driver 2025-04-24 22:27:51 +02:00
Kujtim Hoxha 2c24bfb7b3 fix kitty issues 2025-04-24 19:57:04 +02:00
Dax Raad 47a37b7dd6 back to disablign cgo 2025-04-24 12:46:11 -04:00
Dax Raad bdbf31f0b9 force CGO
release / goreleaser (push) Has been cancelled
2025-04-24 12:34:55 -04:00
Dax Raad 4e6560efb9 turn on cgo
release / goreleaser (push) Has been cancelled
2025-04-24 12:30:33 -04:00
Dax Raad f2f6efdd35 fix version ldflags
release / goreleaser (push) Has been cancelled
2025-04-24 12:26:42 -04:00
Kujtim Hoxha b106787a50 change package name 2025-04-24 18:26:16 +02:00
Kujtim Hoxha e1b2ce483f change additions/removals 2025-04-24 16:40:36 +02:00
Kujtim Hoxha c42d94c465 small fixes 2025-04-24 16:40:36 +02:00
Kujtim Hoxha f879a94c95 update mainter email 2025-04-24 16:40:36 +02:00
Kujtim Hoxha 6d05d5a7c3 small changes 2025-04-24 16:40:36 +02:00
Kujtim Hoxha 2c5003e3fc remove edit/normal mode 2025-04-24 16:40:36 +02:00
Dax Raad 1b22acbc58 sync 2025-04-22 21:29:32 -04:00
Dax Raad 7648a2d790 remove cache
release / goreleaser (push) Has been cancelled
2025-04-22 21:23:20 -04:00
Dax Raad 789ff3c59b sync
release / goreleaser (push) Has been cancelled
2025-04-22 21:21:53 -04:00
Dax Raad 259858df5f attempt cache builds 2025-04-22 21:20:35 -04:00
Dax 289f6af3de CI (#43)
release / goreleaser (push) Has been cancelled
* sync

* ci test

* ci test

* tag

* sync

* sync

* ci

* sync

* enable cgo

* sync

* add back brew

* switch to main
2025-04-22 21:16:14 -04:00
Kujtim Hoxha cded7ee9fd Merge pull request #38 from rgodha24/fix-provider-defaults
fix: set provider defaults correctly in AWS projects
2025-04-22 12:15:27 +02:00
Rohan Godha c02721ce6b fix: set provider defaults correctly in AWS projects 2025-04-22 00:53:05 -04:00
Kujtim Hoxha 5d7a9a98b3 Merge pull request #34 from shreyassanthu77/main 2025-04-22 00:06:03 +02:00
Shreyas Mididoddi ce8bf37f15 look for $HOME/.config for config in addition to $XDG_CONFIG_HOME/ 2025-04-22 00:49:23 +05:30
Kujtim Hoxha f33dff8772 Merge pull request #27 from kujtimiihoxha/opencode
OpenCode - Initial Implementation
2025-04-21 19:59:35 +02:00
702 changed files with 95766 additions and 35208 deletions
+9
View File
@@ -0,0 +1,9 @@
root = true
[*]
charset = utf-8
insert_final_newline = true
end_of_line = lf
indent_style = space
indent_size = 2
max_line_length = 80
+27
View File
@@ -0,0 +1,27 @@
name: deploy
on:
push:
branches:
- dev
- production
workflow_dispatch:
concurrency: ${{ github.workflow }}-${{ github.ref }}
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: oven-sh/setup-bun@v1
with:
bun-version: 1.2.17
- run: bun install
- run: bun sst deploy --stage=${{ github.ref_name }}
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
STRIPE_SECRET_KEY: ${{ github.ref_name == 'production' && secrets.STRIPE_SECRET_KEY_PROD || secrets.STRIPE_SECRET_KEY_DEV }}
+14
View File
@@ -0,0 +1,14 @@
name: discord
on:
release:
types: [published] # fires only when a release is published
jobs:
notify:
runs-on: ubuntu-latest
steps:
- name: Send nicely-formatted embed to Discord
uses: SethCohen/github-releases-to-discord@v1
with:
webhook_url: ${{ secrets.DISCORD_WEBHOOK }}
+29
View File
@@ -0,0 +1,29 @@
name: opencode
on:
issue_comment:
types: [created]
jobs:
opencode:
if: |
contains(github.event.comment.body, ' /oc') ||
startsWith(github.event.comment.body, '/oc') ||
contains(github.event.comment.body, ' /opencode') ||
startsWith(github.event.comment.body, '/opencode')
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Run opencode
uses: sst/opencode/github@latest
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
with:
model: anthropic/claude-sonnet-4-20250514
@@ -0,0 +1,30 @@
name: publish-github-action
on:
workflow_dispatch:
push:
tags:
- "github-v*.*.*"
- "!github-v1"
concurrency: ${{ github.workflow }}-${{ github.ref }}
permissions:
contents: write
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- run: git fetch --force --tags
- name: Publish
run: |
git config --global user.email "opencode@sst.dev"
git config --global user.name "opencode"
./script/publish
working-directory: ./github
+36
View File
@@ -0,0 +1,36 @@
name: publish-vscode
on:
workflow_dispatch:
push:
tags:
- "vscode-v*.*.*"
concurrency: ${{ github.workflow }}-${{ github.ref }}
permissions:
contents: write
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- uses: oven-sh/setup-bun@v2
with:
bun-version: 1.2.17
- run: git fetch --force --tags
- run: bun install -g @vscode/vsce
- name: Publish
run: |
bun install
./script/publish
working-directory: ./sdks/vscode
env:
VSCE_PAT: ${{ secrets.VSCE_PAT }}
OPENVSX_TOKEN: ${{ secrets.OPENVSX_TOKEN }}
+74
View File
@@ -0,0 +1,74 @@
name: publish
run-name: "${{ format('v{0}', inputs.version) }}"
on:
workflow_dispatch:
inputs:
version:
description: "Version to publish"
required: true
type: string
title:
description: "Custom title for this run"
required: false
type: string
concurrency: ${{ github.workflow }}-${{ github.ref }}
permissions:
contents: write
packages: write
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- run: git fetch --force --tags
- uses: actions/setup-go@v5
with:
go-version: ">=1.24.0"
cache: true
cache-dependency-path: go.sum
- uses: oven-sh/setup-bun@v2
with:
bun-version: 1.2.19
- name: Cache ~/.bun
id: cache-bun
uses: actions/cache@v3
with:
path: ~/.bun
key: ${{ runner.os }}-bun-${{ hashFiles('bun.lock') }}
restore-keys: |
${{ runner.os }}-bun-
- name: Install makepkg
run: |
sudo apt-get update
sudo apt-get install -y pacman-package-manager
- name: Setup SSH for AUR
run: |
mkdir -p ~/.ssh
echo "${{ secrets.AUR_KEY }}" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan -H aur.archlinux.org >> ~/.ssh/known_hosts
git config --global user.email "opencode@sst.dev"
git config --global user.name "opencode"
- name: Install dependencies
run: bun install
- name: Publish
run: |
OPENCODE_VERSION=${{ inputs.version }} ./script/publish.ts
env:
GITHUB_TOKEN: ${{ secrets.SST_GITHUB_TOKEN }}
AUR_KEY: ${{ secrets.AUR_KEY }}
NPM_CONFIG_TOKEN: ${{ secrets.NPM_TOKEN }}
+34
View File
@@ -0,0 +1,34 @@
name: stats
on:
schedule:
- cron: "0 12 * * *" # Run daily at 12:00 UTC
workflow_dispatch: # Allow manual trigger
jobs:
stats:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Run stats script
run: bun script/stats.ts
- name: Commit stats
run: |
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
git add STATS.md
git diff --staged --quiet || git commit -m "ignore: update download stats $(date -I)"
git push
env:
POSTHOG_KEY: ${{ secrets.POSTHOG_KEY }}
+24
View File
@@ -0,0 +1,24 @@
name: Typecheck
on:
pull_request:
branches: [dev]
workflow_dispatch:
jobs:
typecheck:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v1
with:
bun-version: 1.2.19
- name: Install dependencies
run: bun install
- name: Run typecheck
run: bun typecheck
+6 -43
View File
@@ -1,45 +1,8 @@
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
# Test binary, built with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
# Dependency directories (remove the comment below to include it)
# vendor/
# Go workspace file
go.work
# IDE specific files
.idea/
.vscode/
*.swp
*.swo
# OS specific files
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db
*.log
# Binary output directory
/bin/
/dist/
# Local environment variables
node_modules
.sst
.env
.env.local
.opencode/
.idea
.vscode
openapi.json
playground
-8
View File
@@ -1,8 +0,0 @@
{
"$schema": "./opencode-schema.json",
"lsp": {
"gopls": {
"command": "gopls"
}
}
}
+14
View File
@@ -0,0 +1,14 @@
---
model: openai/gpt-5
reasoningEffort: medium
description: ALWAYS use this when writing docs
---
You are an expert technical documentation writer
You are not verbose
Every chunk of text should be followed by an example or something besides text
to look at.
Chunks of text should not be more than 2 sentences long.
+12
View File
@@ -0,0 +1,12 @@
## IMPORTANT
- Try to keep things in one function unless composable or reusable
- DO NOT do unnecessary destructuring of variables
- DO NOT use `else` statements unless necessary
- DO NOT use `try`/`catch` if it can be avoided
- AVOID `try`/`catch` where possible
- AVOID `else` statements
- AVOID using `any` type
- AVOID `let` statements
- PREFER single word variable names where possible
- Use as many bun apis as possible like Bun.file()
+1 -1
View File
@@ -1,6 +1,6 @@
MIT License
Copyright (c) 2025 Kujtim Hoxha
Copyright (c) 2025 opencode
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
+72 -339
View File
@@ -1,377 +1,110 @@
# OpenCode
<p align="center">
<a href="https://opencode.ai">
<picture>
<source srcset="packages/web/src/assets/logo-ornate-dark.svg" media="(prefers-color-scheme: dark)">
<source srcset="packages/web/src/assets/logo-ornate-light.svg" media="(prefers-color-scheme: light)">
<img src="packages/web/src/assets/logo-ornate-light.svg" alt="opencode logo">
</picture>
</a>
</p>
<p align="center">AI coding agent, built for the terminal.</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/sst/opencode/actions/workflows/publish.yml"><img alt="Build status" src="https://img.shields.io/github/actions/workflow/status/sst/opencode/publish.yml?style=flat-square&branch=dev" /></a>
</p>
> **⚠️ Early Development Notice:** This project is in early development and is not yet ready for production use. Features may change, break, or be incomplete. Use at your own risk.
[![opencode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai)
A powerful terminal-based AI assistant for developers, providing intelligent coding assistance directly in your terminal.
---
## Overview
OpenCode is a Go-based CLI application that brings AI assistance to your terminal. It provides a TUI (Terminal User Interface) for interacting with various AI models to help with coding tasks, debugging, and more.
## Features
- **Interactive TUI**: Built with [Bubble Tea](https://github.com/charmbracelet/bubbletea) for a smooth terminal experience
- **Multiple AI Providers**: Support for OpenAI, Anthropic Claude, Google Gemini, AWS Bedrock, and Groq
- **Session Management**: Save and manage multiple conversation sessions
- **Tool Integration**: AI can execute commands, search files, and modify code
- **Vim-like Editor**: Integrated editor with text input capabilities
- **Persistent Storage**: SQLite database for storing conversations and sessions
- **LSP Integration**: Language Server Protocol support for code intelligence
- **File Change Tracking**: Track and visualize file changes during sessions
- **External Editor Support**: Open your preferred editor for composing messages
## Installation
### Installation
```bash
# Coming soon
go install github.com/kujtimiihoxha/opencode@latest
# YOLO
curl -fsSL https://opencode.ai/install | bash
# Package managers
npm i -g opencode-ai@latest # or bun/pnpm/yarn
brew install sst/tap/opencode # macOS and Linux
paru -S opencode-bin # Arch Linux
```
## Configuration
> [!TIP]
> Remove versions older than 0.1.x before installing.
OpenCode looks for configuration in the following locations:
#### Installation Directory
- `$HOME/.opencode.json`
- `$XDG_CONFIG_HOME/opencode/.opencode.json`
- `./.opencode.json` (local directory)
The install script respects the following priority order for the installation path:
### Environment Variables
You can configure OpenCode using environment variables:
| Environment Variable | Purpose |
| ----------------------- | ------------------------ |
| `ANTHROPIC_API_KEY` | For Claude models |
| `OPENAI_API_KEY` | For OpenAI models |
| `GEMINI_API_KEY` | For Google Gemini models |
| `GROQ_API_KEY` | For Groq models |
| `AWS_ACCESS_KEY_ID` | For AWS Bedrock (Claude) |
| `AWS_SECRET_ACCESS_KEY` | For AWS Bedrock (Claude) |
| `AWS_REGION` | For AWS Bedrock (Claude) |
### Configuration File Structure
```json
{
"data": {
"directory": ".opencode"
},
"providers": {
"openai": {
"apiKey": "your-api-key",
"disabled": false
},
"anthropic": {
"apiKey": "your-api-key",
"disabled": false
}
},
"agents": {
"coder": {
"model": "claude-3.7-sonnet",
"maxTokens": 5000
},
"task": {
"model": "claude-3.7-sonnet",
"maxTokens": 5000
},
"title": {
"model": "claude-3.7-sonnet",
"maxTokens": 80
}
},
"mcpServers": {
"example": {
"type": "stdio",
"command": "path/to/mcp-server",
"env": [],
"args": []
}
},
"lsp": {
"go": {
"disabled": false,
"command": "gopls"
}
},
"debug": false,
"debugLSP": false
}
```
## Supported AI Models
OpenCode supports a variety of AI models from different providers:
### OpenAI
- GPT-4.1 family (gpt-4.1, gpt-4.1-mini, gpt-4.1-nano)
- GPT-4.5 Preview
- GPT-4o family (gpt-4o, gpt-4o-mini)
- O1 family (o1, o1-pro, o1-mini)
- O3 family (o3, o3-mini)
- O4 Mini
### Anthropic
- Claude 3.5 Sonnet
- Claude 3.5 Haiku
- Claude 3.7 Sonnet
- Claude 3 Haiku
- Claude 3 Opus
### Google
- Gemini 2.5
- Gemini 2.5 Flash
- Gemini 2.0 Flash
- Gemini 2.0 Flash Lite
### AWS Bedrock
- Claude 3.7 Sonnet
## Usage
1. `$OPENCODE_INSTALL_DIR` - Custom installation directory
2. `$XDG_BIN_DIR` - XDG Base Directory Specification compliant path
3. `$HOME/bin` - Standard user binary directory (if exists or can be created)
4. `$HOME/.opencode/bin` - Default fallback
```bash
# Start OpenCode
opencode
# Start with debug logging
opencode -d
# Start with a specific working directory
opencode -c /path/to/project
# Examples
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
```
## Command-line Flags
### Documentation
| Flag | Short | Description |
| --------- | ----- | ----------------------------- |
| `--help` | `-h` | Display help information |
| `--debug` | `-d` | Enable debug mode |
| `--cwd` | `-c` | Set current working directory |
For more info on how to configure opencode [**head over to our docs**](https://opencode.ai/docs).
## Keyboard Shortcuts
### Contributing
### Global Shortcuts
opencode is an opinionated tool so any fundamental feature needs to go through a
design process with the core team.
| Shortcut | Action |
| -------- | ------------------------------------------------------- |
| `Ctrl+C` | Quit application |
| `Ctrl+?` | Toggle help dialog |
| `?` | Toggle help dialog (when not in editing mode) |
| `Ctrl+L` | View logs |
| `Ctrl+A` | Switch session |
| `Ctrl+K` | Command dialog |
| `Esc` | Close current overlay/dialog or return to previous mode |
> [!IMPORTANT]
> We do not accept PRs for core features.
### Chat Page Shortcuts
However we still merge a ton of PRs - you can contribute:
| Shortcut | Action |
| -------- | --------------------------------------- |
| `Ctrl+N` | Create new session |
| `Ctrl+X` | Cancel current operation/generation |
| `i` | Focus editor (when not in writing mode) |
| `Esc` | Exit writing mode and focus messages |
- Bug fixes
- Improvements to LLM performance
- Support for new providers
- Fixes for env specific quirks
- Missing standard behavior
- Documentation
### Editor Shortcuts
Take a look at the git history to see what kind of PRs we end up merging.
| Shortcut | Action |
| ------------------- | ----------------------------------------- |
| `Ctrl+S` | Send message (when editor is focused) |
| `Enter` or `Ctrl+S` | Send message (when editor is not focused) |
| `Ctrl+E` | Open external editor |
| `Esc` | Blur editor and focus messages |
> [!NOTE]
> If you do not follow the above guidelines we might close your PR.
### Session Dialog Shortcuts
To run opencode locally you need.
| Shortcut | Action |
| ---------- | ---------------- |
| `↑` or `k` | Previous session |
| `↓` or `j` | Next session |
| `Enter` | Select session |
| `Esc` | Close dialog |
- Bun
- Golang 1.24.x
### Permission Dialog Shortcuts
| Shortcut | Action |
| ----------------------- | ---------------------------- |
| `←` or `left` | Switch options left |
| `→` or `right` or `tab` | Switch options right |
| `Enter` or `space` | Confirm selection |
| `a` | Allow permission |
| `A` | Allow permission for session |
| `d` | Deny permission |
### Logs Page Shortcuts
| Shortcut | Action |
| ------------------ | ------------------- |
| `Backspace` or `q` | Return to chat page |
## AI Assistant Tools
OpenCode's AI assistant has access to various tools to help with coding tasks:
### File and Code Tools
| Tool | Description | Parameters |
| ------------- | --------------------------- | ---------------------------------------------------------------------------------------- |
| `glob` | Find files by pattern | `pattern` (required), `path` (optional) |
| `grep` | Search file contents | `pattern` (required), `path` (optional), `include` (optional), `literal_text` (optional) |
| `ls` | List directory contents | `path` (optional), `ignore` (optional array of patterns) |
| `view` | View file contents | `file_path` (required), `offset` (optional), `limit` (optional) |
| `write` | Write to files | `file_path` (required), `content` (required) |
| `edit` | Edit files | Various parameters for file editing |
| `patch` | Apply patches to files | `file_path` (required), `diff` (required) |
| `diagnostics` | Get diagnostics information | `file_path` (optional) |
### Other Tools
| Tool | Description | Parameters |
| ------------- | -------------------------------------- | ----------------------------------------------------------------------------------------- |
| `bash` | Execute shell commands | `command` (required), `timeout` (optional) |
| `fetch` | Fetch data from URLs | `url` (required), `format` (required), `timeout` (optional) |
| `sourcegraph` | Search code across public repositories | `query` (required), `count` (optional), `context_window` (optional), `timeout` (optional) |
| `agent` | Run sub-tasks with the AI agent | `prompt` (required) |
## Architecture
OpenCode is built with a modular architecture:
- **cmd**: Command-line interface using Cobra
- **internal/app**: Core application services
- **internal/config**: Configuration management
- **internal/db**: Database operations and migrations
- **internal/llm**: LLM providers and tools integration
- **internal/tui**: Terminal UI components and layouts
- **internal/logging**: Logging infrastructure
- **internal/message**: Message handling
- **internal/session**: Session management
- **internal/lsp**: Language Server Protocol integration
## MCP (Model Context Protocol)
OpenCode implements the Model Context Protocol (MCP) to extend its capabilities through external tools. MCP provides a standardized way for the AI assistant to interact with external services and tools.
### MCP Features
- **External Tool Integration**: Connect to external tools and services via a standardized protocol
- **Tool Discovery**: Automatically discover available tools from MCP servers
- **Multiple Connection Types**:
- **Stdio**: Communicate with tools via standard input/output
- **SSE**: Communicate with tools via Server-Sent Events
- **Security**: Permission system for controlling access to MCP tools
### Configuring MCP Servers
MCP servers are defined in the configuration file under the `mcpServers` section:
```json
{
"mcpServers": {
"example": {
"type": "stdio",
"command": "path/to/mcp-server",
"env": [],
"args": []
},
"web-example": {
"type": "sse",
"url": "https://example.com/mcp",
"headers": {
"Authorization": "Bearer token"
}
}
}
}
```
### MCP Tool Usage
Once configured, MCP tools are automatically available to the AI assistant alongside built-in tools. They follow the same permission model as other tools, requiring user approval before execution.
## LSP (Language Server Protocol)
OpenCode integrates with Language Server Protocol to provide code intelligence features across multiple programming languages.
### LSP Features
- **Multi-language Support**: Connect to language servers for different programming languages
- **Diagnostics**: Receive error checking and linting information
- **File Watching**: Automatically notify language servers of file changes
### Configuring LSP
Language servers are configured in the configuration file under the `lsp` section:
```json
{
"lsp": {
"go": {
"disabled": false,
"command": "gopls"
},
"typescript": {
"disabled": false,
"command": "typescript-language-server",
"args": ["--stdio"]
}
}
}
```
### LSP Integration with AI
The AI assistant can access LSP features through the `diagnostics` tool, allowing it to:
- Check for errors in your code
- Suggest fixes based on diagnostics
While the LSP client implementation supports the full LSP protocol (including completions, hover, definition, etc.), currently only diagnostics are exposed to the AI assistant.
## Development
### Prerequisites
- Go 1.24.0 or higher
### Building from Source
And run.
```bash
# Clone the repository
git clone https://github.com/kujtimiihoxha/opencode.git
cd opencode
# Build
go build -o opencode
# Run
./opencode
$ bun install
$ bun dev
```
## Acknowledgments
#### Development Notes
OpenCode gratefully acknowledges the contributions and support from these key individuals:
**API Client**: After making changes to the TypeScript API endpoints in `packages/opencode/src/server/server.ts`, you will need the opencode team to generate a new stainless sdk for the clients.
- [@isaacphi](https://github.com/isaacphi) - For the [mcp-language-server](https://github.com/isaacphi/mcp-language-server) project which provided the foundation for our LSP client implementation
- [@adamdottv](https://github.com/adamdottv) - For the design direction and UI/UX architecture
### FAQ
Special thanks to the broader open source community whose tools and libraries have made this project possible.
#### How is this different than Claude Code?
## License
It's very similar to Claude Code in terms of capability. Here are the key differences:
OpenCode is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
- 100% open source
- Not coupled to any provider. Although Anthropic is recommended, opencode can be used with OpenAI, Google or even local models. As models evolve the gaps between them will close and pricing will drop so being provider-agnostic is important.
- A focus on TUI. opencode is built by neovim users and the creators of [terminal.shop](https://terminal.shop); we are going to push the limits of what's possible in the terminal.
- A client/server architecture. This for example can allow opencode to run on your computer, while you can drive it remotely from a mobile app. Meaning that the TUI frontend is just one of the possible clients.
## Contributing
#### What's the other repo?
Contributions are welcome! Here's how you can contribute:
The other confusingly named repo has no relation to this one. You can [read the story behind it here](https://x.com/thdxr/status/1933561254481666466).
1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request
---
Please make sure to update tests as appropriate and follow the existing code style.
**Join our community** [Discord](https://discord.gg/opencode) | [YouTube](https://www.youtube.com/c/sst-dev) | [X.com](https://x.com/SST_dev)
+47
View File
@@ -0,0 +1,47 @@
# Download Stats
| Date | GitHub Downloads | npm Downloads | Total |
| ---------- | ---------------- | ---------------- | ---------------- |
| 2025-06-29 | 18,789 (+0) | 39,420 (+0) | 58,209 (+0) |
| 2025-06-30 | 20,127 (+1,338) | 41,059 (+1,639) | 61,186 (+2,977) |
| 2025-07-01 | 22,108 (+1,981) | 43,745 (+2,686) | 65,853 (+4,667) |
| 2025-07-02 | 24,814 (+2,706) | 46,168 (+2,423) | 70,982 (+5,129) |
| 2025-07-03 | 27,834 (+3,020) | 49,955 (+3,787) | 77,789 (+6,807) |
| 2025-07-04 | 30,608 (+2,774) | 54,758 (+4,803) | 85,366 (+7,577) |
| 2025-07-05 | 32,524 (+1,916) | 58,371 (+3,613) | 90,895 (+5,529) |
| 2025-07-06 | 33,766 (+1,242) | 59,694 (+1,323) | 93,460 (+2,565) |
| 2025-07-08 | 38,052 (+4,286) | 64,468 (+4,774) | 102,520 (+9,060) |
| 2025-07-09 | 40,924 (+2,872) | 67,935 (+3,467) | 108,859 (+6,339) |
| 2025-07-10 | 43,796 (+2,872) | 71,402 (+3,467) | 115,198 (+6,339) |
| 2025-07-11 | 46,982 (+3,186) | 77,462 (+6,060) | 124,444 (+9,246) |
| 2025-07-12 | 49,302 (+2,320) | 82,177 (+4,715) | 131,479 (+7,035) |
| 2025-07-13 | 50,803 (+1,501) | 86,394 (+4,217) | 137,197 (+5,718) |
| 2025-07-14 | 53,283 (+2,480) | 87,860 (+1,466) | 141,143 (+3,946) |
| 2025-07-15 | 57,590 (+4,307) | 91,036 (+3,176) | 148,626 (+7,483) |
| 2025-07-16 | 62,313 (+4,723) | 95,258 (+4,222) | 157,571 (+8,945) |
| 2025-07-17 | 66,684 (+4,371) | 100,048 (+4,790) | 166,732 (+9,161) |
| 2025-07-18 | 70,379 (+3,695) | 102,587 (+2,539) | 172,966 (+6,234) |
| 2025-07-19 | 73,497 (+3,117) | 105,904 (+3,317) | 179,401 (+6,434) |
| 2025-07-20 | 76,453 (+2,956) | 109,044 (+3,140) | 185,497 (+6,096) |
| 2025-07-21 | 80,197 (+3,744) | 113,537 (+4,493) | 193,734 (+8,237) |
| 2025-07-22 | 84,251 (+4,054) | 118,073 (+4,536) | 202,324 (+8,590) |
| 2025-07-23 | 88,589 (+4,338) | 121,436 (+3,363) | 210,025 (+7,701) |
| 2025-07-24 | 92,469 (+3,880) | 124,091 (+2,655) | 216,560 (+6,535) |
| 2025-07-25 | 96,417 (+3,948) | 126,985 (+2,894) | 223,402 (+6,842) |
| 2025-07-26 | 100,646 (+4,229) | 131,411 (+4,426) | 232,057 (+8,655) |
| 2025-07-27 | 102,644 (+1,998) | 134,736 (+3,325) | 237,380 (+5,323) |
| 2025-07-28 | 105,446 (+2,802) | 136,016 (+1,280) | 241,462 (+4,082) |
| 2025-07-29 | 108,998 (+3,552) | 137,542 (+1,526) | 246,540 (+5,078) |
| 2025-07-30 | 113,544 (+4,546) | 140,317 (+2,775) | 253,861 (+7,321) |
| 2025-07-31 | 118,339 (+4,795) | 143,344 (+3,027) | 261,683 (+7,822) |
| 2025-08-01 | 123,539 (+5,200) | 146,680 (+3,336) | 270,219 (+8,536) |
| 2025-08-02 | 127,864 (+4,325) | 149,236 (+2,556) | 277,100 (+6,881) |
| 2025-08-03 | 131,397 (+3,533) | 150,451 (+1,215) | 281,848 (+4,748) |
| 2025-08-04 | 136,266 (+4,869) | 153,260 (+2,809) | 289,526 (+7,678) |
| 2025-08-05 | 141,596 (+5,330) | 155,752 (+2,492) | 297,348 (+7,822) |
| 2025-08-06 | 147,067 (+5,471) | 158,309 (+2,557) | 305,376 (+8,028) |
| 2025-08-07 | 152,591 (+5,524) | 160,889 (+2,580) | 313,480 (+8,104) |
| 2025-08-08 | 158,187 (+5,596) | 163,448 (+2,559) | 321,635 (+8,155) |
| 2025-08-09 | 162,770 (+4,583) | 165,721 (+2,273) | 328,491 (+6,856) |
| 2025-08-10 | 165,695 (+2,925) | 167,109 (+1,388) | 332,804 (+4,313) |
| 2025-08-11 | 169,297 (+3,602) | 167,953 (+844) | 337,250 (+4,446) |
+3308
View File
File diff suppressed because it is too large Load Diff
+2
View File
@@ -0,0 +1,2 @@
[install]
exact = true
+20
View File
@@ -0,0 +1,20 @@
import { defineConfig } from "drizzle-kit"
import { Resource } from "sst"
export default defineConfig({
out: "./migrations/",
strict: true,
schema: ["./src/**/*.sql.ts"],
verbose: true,
dialect: "postgresql",
dbCredentials: {
database: Resource.Database.database,
host: Resource.Database.host,
user: Resource.Database.username,
password: Resource.Database.password,
port: Resource.Database.port,
ssl: {
rejectUnauthorized: false,
},
},
})
@@ -0,0 +1,66 @@
CREATE TABLE "billing" (
"id" varchar(30) NOT NULL,
"workspace_id" varchar(30) NOT NULL,
"time_created" timestamp with time zone DEFAULT now() NOT NULL,
"time_deleted" timestamp with time zone,
"customer_id" varchar(255),
"payment_method_id" varchar(255),
"payment_method_last4" varchar(4),
"balance" bigint NOT NULL,
"reload" boolean,
CONSTRAINT "billing_workspace_id_id_pk" PRIMARY KEY("workspace_id","id")
);
--> statement-breakpoint
CREATE TABLE "payment" (
"id" varchar(30) NOT NULL,
"workspace_id" varchar(30) NOT NULL,
"time_created" timestamp with time zone DEFAULT now() NOT NULL,
"time_deleted" timestamp with time zone,
"customer_id" varchar(255),
"payment_id" varchar(255),
"amount" bigint NOT NULL,
CONSTRAINT "payment_workspace_id_id_pk" PRIMARY KEY("workspace_id","id")
);
--> statement-breakpoint
CREATE TABLE "usage" (
"id" varchar(30) NOT NULL,
"workspace_id" varchar(30) NOT NULL,
"time_created" timestamp with time zone DEFAULT now() NOT NULL,
"time_deleted" timestamp with time zone,
"request_id" varchar(255),
"model" varchar(255) NOT NULL,
"input_tokens" integer NOT NULL,
"output_tokens" integer NOT NULL,
"reasoning_tokens" integer,
"cache_read_tokens" integer,
"cache_write_tokens" integer,
"cost" bigint NOT NULL,
CONSTRAINT "usage_workspace_id_id_pk" PRIMARY KEY("workspace_id","id")
);
--> statement-breakpoint
CREATE TABLE "user" (
"id" varchar(30) NOT NULL,
"workspace_id" varchar(30) NOT NULL,
"time_created" timestamp with time zone DEFAULT now() NOT NULL,
"time_deleted" timestamp with time zone,
"email" text NOT NULL,
"name" varchar(255) NOT NULL,
"time_seen" timestamp with time zone,
"color" integer,
CONSTRAINT "user_workspace_id_id_pk" PRIMARY KEY("workspace_id","id")
);
--> statement-breakpoint
CREATE TABLE "workspace" (
"id" varchar(30) PRIMARY KEY NOT NULL,
"slug" varchar(255),
"name" varchar(255),
"time_created" timestamp with time zone DEFAULT now() NOT NULL,
"time_deleted" timestamp with time zone
);
--> statement-breakpoint
ALTER TABLE "billing" ADD CONSTRAINT "billing_workspace_id_workspace_id_fk" FOREIGN KEY ("workspace_id") REFERENCES "public"."workspace"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "payment" ADD CONSTRAINT "payment_workspace_id_workspace_id_fk" FOREIGN KEY ("workspace_id") REFERENCES "public"."workspace"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "usage" ADD CONSTRAINT "usage_workspace_id_workspace_id_fk" FOREIGN KEY ("workspace_id") REFERENCES "public"."workspace"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "user" ADD CONSTRAINT "user_workspace_id_workspace_id_fk" FOREIGN KEY ("workspace_id") REFERENCES "public"."workspace"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
CREATE UNIQUE INDEX "user_email" ON "user" USING btree ("workspace_id","email");--> statement-breakpoint
CREATE UNIQUE INDEX "slug" ON "workspace" USING btree ("slug");
@@ -0,0 +1,8 @@
CREATE TABLE "account" (
"id" varchar(30) NOT NULL,
"time_created" timestamp with time zone DEFAULT now() NOT NULL,
"time_deleted" timestamp with time zone,
"email" varchar(255) NOT NULL
);
--> statement-breakpoint
CREATE UNIQUE INDEX "email" ON "account" USING btree ("email");
@@ -0,0 +1,14 @@
CREATE TABLE "key" (
"id" varchar(30) NOT NULL,
"workspace_id" varchar(30) NOT NULL,
"time_created" timestamp with time zone DEFAULT now() NOT NULL,
"time_deleted" timestamp with time zone,
"user_id" text NOT NULL,
"name" varchar(255) NOT NULL,
"key" varchar(255) NOT NULL,
"time_used" timestamp with time zone,
CONSTRAINT "key_workspace_id_id_pk" PRIMARY KEY("workspace_id","id")
);
--> statement-breakpoint
ALTER TABLE "key" ADD CONSTRAINT "key_workspace_id_workspace_id_fk" FOREIGN KEY ("workspace_id") REFERENCES "public"."workspace"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
CREATE UNIQUE INDEX "global_key" ON "key" USING btree ("key");
@@ -0,0 +1 @@
ALTER TABLE "usage" DROP COLUMN "request_id";
@@ -0,0 +1,461 @@
{
"id": "9b5cec8c-8b59-4d7a-bb5c-76ade1c83d6f",
"prevId": "00000000-0000-0000-0000-000000000000",
"version": "7",
"dialect": "postgresql",
"tables": {
"public.billing": {
"name": "billing",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "varchar(30)",
"primaryKey": false,
"notNull": true
},
"workspace_id": {
"name": "workspace_id",
"type": "varchar(30)",
"primaryKey": false,
"notNull": true
},
"time_created": {
"name": "time_created",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"time_deleted": {
"name": "time_deleted",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"customer_id": {
"name": "customer_id",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false
},
"payment_method_id": {
"name": "payment_method_id",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false
},
"payment_method_last4": {
"name": "payment_method_last4",
"type": "varchar(4)",
"primaryKey": false,
"notNull": false
},
"balance": {
"name": "balance",
"type": "bigint",
"primaryKey": false,
"notNull": true
},
"reload": {
"name": "reload",
"type": "boolean",
"primaryKey": false,
"notNull": false
}
},
"indexes": {},
"foreignKeys": {
"billing_workspace_id_workspace_id_fk": {
"name": "billing_workspace_id_workspace_id_fk",
"tableFrom": "billing",
"tableTo": "workspace",
"columnsFrom": [
"workspace_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {
"billing_workspace_id_id_pk": {
"name": "billing_workspace_id_id_pk",
"columns": [
"workspace_id",
"id"
]
}
},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.payment": {
"name": "payment",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "varchar(30)",
"primaryKey": false,
"notNull": true
},
"workspace_id": {
"name": "workspace_id",
"type": "varchar(30)",
"primaryKey": false,
"notNull": true
},
"time_created": {
"name": "time_created",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"time_deleted": {
"name": "time_deleted",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"customer_id": {
"name": "customer_id",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false
},
"payment_id": {
"name": "payment_id",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false
},
"amount": {
"name": "amount",
"type": "bigint",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {
"payment_workspace_id_workspace_id_fk": {
"name": "payment_workspace_id_workspace_id_fk",
"tableFrom": "payment",
"tableTo": "workspace",
"columnsFrom": [
"workspace_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {
"payment_workspace_id_id_pk": {
"name": "payment_workspace_id_id_pk",
"columns": [
"workspace_id",
"id"
]
}
},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.usage": {
"name": "usage",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "varchar(30)",
"primaryKey": false,
"notNull": true
},
"workspace_id": {
"name": "workspace_id",
"type": "varchar(30)",
"primaryKey": false,
"notNull": true
},
"time_created": {
"name": "time_created",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"time_deleted": {
"name": "time_deleted",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"request_id": {
"name": "request_id",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false
},
"model": {
"name": "model",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true
},
"input_tokens": {
"name": "input_tokens",
"type": "integer",
"primaryKey": false,
"notNull": true
},
"output_tokens": {
"name": "output_tokens",
"type": "integer",
"primaryKey": false,
"notNull": true
},
"reasoning_tokens": {
"name": "reasoning_tokens",
"type": "integer",
"primaryKey": false,
"notNull": false
},
"cache_read_tokens": {
"name": "cache_read_tokens",
"type": "integer",
"primaryKey": false,
"notNull": false
},
"cache_write_tokens": {
"name": "cache_write_tokens",
"type": "integer",
"primaryKey": false,
"notNull": false
},
"cost": {
"name": "cost",
"type": "bigint",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {
"usage_workspace_id_workspace_id_fk": {
"name": "usage_workspace_id_workspace_id_fk",
"tableFrom": "usage",
"tableTo": "workspace",
"columnsFrom": [
"workspace_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {
"usage_workspace_id_id_pk": {
"name": "usage_workspace_id_id_pk",
"columns": [
"workspace_id",
"id"
]
}
},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.user": {
"name": "user",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "varchar(30)",
"primaryKey": false,
"notNull": true
},
"workspace_id": {
"name": "workspace_id",
"type": "varchar(30)",
"primaryKey": false,
"notNull": true
},
"time_created": {
"name": "time_created",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"time_deleted": {
"name": "time_deleted",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"email": {
"name": "email",
"type": "text",
"primaryKey": false,
"notNull": true
},
"name": {
"name": "name",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true
},
"time_seen": {
"name": "time_seen",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"color": {
"name": "color",
"type": "integer",
"primaryKey": false,
"notNull": false
}
},
"indexes": {
"user_email": {
"name": "user_email",
"columns": [
{
"expression": "workspace_id",
"isExpression": false,
"asc": true,
"nulls": "last"
},
{
"expression": "email",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": true,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {
"user_workspace_id_workspace_id_fk": {
"name": "user_workspace_id_workspace_id_fk",
"tableFrom": "user",
"tableTo": "workspace",
"columnsFrom": [
"workspace_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {
"user_workspace_id_id_pk": {
"name": "user_workspace_id_id_pk",
"columns": [
"workspace_id",
"id"
]
}
},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.workspace": {
"name": "workspace",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "varchar(30)",
"primaryKey": true,
"notNull": true
},
"slug": {
"name": "slug",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false
},
"name": {
"name": "name",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false
},
"time_created": {
"name": "time_created",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"time_deleted": {
"name": "time_deleted",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
}
},
"indexes": {
"slug": {
"name": "slug",
"columns": [
{
"expression": "slug",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": true,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
}
},
"enums": {},
"schemas": {},
"sequences": {},
"roles": {},
"policies": {},
"views": {},
"_meta": {
"columns": {},
"schemas": {},
"tables": {}
}
}
@@ -0,0 +1,515 @@
{
"id": "bf9e9084-4073-4ecb-8e56-5610816c9589",
"prevId": "9b5cec8c-8b59-4d7a-bb5c-76ade1c83d6f",
"version": "7",
"dialect": "postgresql",
"tables": {
"public.account": {
"name": "account",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "varchar(30)",
"primaryKey": false,
"notNull": true
},
"time_created": {
"name": "time_created",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"time_deleted": {
"name": "time_deleted",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"email": {
"name": "email",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true
}
},
"indexes": {
"email": {
"name": "email",
"columns": [
{
"expression": "email",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": true,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.billing": {
"name": "billing",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "varchar(30)",
"primaryKey": false,
"notNull": true
},
"workspace_id": {
"name": "workspace_id",
"type": "varchar(30)",
"primaryKey": false,
"notNull": true
},
"time_created": {
"name": "time_created",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"time_deleted": {
"name": "time_deleted",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"customer_id": {
"name": "customer_id",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false
},
"payment_method_id": {
"name": "payment_method_id",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false
},
"payment_method_last4": {
"name": "payment_method_last4",
"type": "varchar(4)",
"primaryKey": false,
"notNull": false
},
"balance": {
"name": "balance",
"type": "bigint",
"primaryKey": false,
"notNull": true
},
"reload": {
"name": "reload",
"type": "boolean",
"primaryKey": false,
"notNull": false
}
},
"indexes": {},
"foreignKeys": {
"billing_workspace_id_workspace_id_fk": {
"name": "billing_workspace_id_workspace_id_fk",
"tableFrom": "billing",
"tableTo": "workspace",
"columnsFrom": [
"workspace_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {
"billing_workspace_id_id_pk": {
"name": "billing_workspace_id_id_pk",
"columns": [
"workspace_id",
"id"
]
}
},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.payment": {
"name": "payment",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "varchar(30)",
"primaryKey": false,
"notNull": true
},
"workspace_id": {
"name": "workspace_id",
"type": "varchar(30)",
"primaryKey": false,
"notNull": true
},
"time_created": {
"name": "time_created",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"time_deleted": {
"name": "time_deleted",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"customer_id": {
"name": "customer_id",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false
},
"payment_id": {
"name": "payment_id",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false
},
"amount": {
"name": "amount",
"type": "bigint",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {
"payment_workspace_id_workspace_id_fk": {
"name": "payment_workspace_id_workspace_id_fk",
"tableFrom": "payment",
"tableTo": "workspace",
"columnsFrom": [
"workspace_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {
"payment_workspace_id_id_pk": {
"name": "payment_workspace_id_id_pk",
"columns": [
"workspace_id",
"id"
]
}
},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.usage": {
"name": "usage",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "varchar(30)",
"primaryKey": false,
"notNull": true
},
"workspace_id": {
"name": "workspace_id",
"type": "varchar(30)",
"primaryKey": false,
"notNull": true
},
"time_created": {
"name": "time_created",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"time_deleted": {
"name": "time_deleted",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"request_id": {
"name": "request_id",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false
},
"model": {
"name": "model",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true
},
"input_tokens": {
"name": "input_tokens",
"type": "integer",
"primaryKey": false,
"notNull": true
},
"output_tokens": {
"name": "output_tokens",
"type": "integer",
"primaryKey": false,
"notNull": true
},
"reasoning_tokens": {
"name": "reasoning_tokens",
"type": "integer",
"primaryKey": false,
"notNull": false
},
"cache_read_tokens": {
"name": "cache_read_tokens",
"type": "integer",
"primaryKey": false,
"notNull": false
},
"cache_write_tokens": {
"name": "cache_write_tokens",
"type": "integer",
"primaryKey": false,
"notNull": false
},
"cost": {
"name": "cost",
"type": "bigint",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {
"usage_workspace_id_workspace_id_fk": {
"name": "usage_workspace_id_workspace_id_fk",
"tableFrom": "usage",
"tableTo": "workspace",
"columnsFrom": [
"workspace_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {
"usage_workspace_id_id_pk": {
"name": "usage_workspace_id_id_pk",
"columns": [
"workspace_id",
"id"
]
}
},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.user": {
"name": "user",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "varchar(30)",
"primaryKey": false,
"notNull": true
},
"workspace_id": {
"name": "workspace_id",
"type": "varchar(30)",
"primaryKey": false,
"notNull": true
},
"time_created": {
"name": "time_created",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"time_deleted": {
"name": "time_deleted",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"email": {
"name": "email",
"type": "text",
"primaryKey": false,
"notNull": true
},
"name": {
"name": "name",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true
},
"time_seen": {
"name": "time_seen",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"color": {
"name": "color",
"type": "integer",
"primaryKey": false,
"notNull": false
}
},
"indexes": {
"user_email": {
"name": "user_email",
"columns": [
{
"expression": "workspace_id",
"isExpression": false,
"asc": true,
"nulls": "last"
},
{
"expression": "email",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": true,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {
"user_workspace_id_workspace_id_fk": {
"name": "user_workspace_id_workspace_id_fk",
"tableFrom": "user",
"tableTo": "workspace",
"columnsFrom": [
"workspace_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {
"user_workspace_id_id_pk": {
"name": "user_workspace_id_id_pk",
"columns": [
"workspace_id",
"id"
]
}
},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.workspace": {
"name": "workspace",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "varchar(30)",
"primaryKey": true,
"notNull": true
},
"slug": {
"name": "slug",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false
},
"name": {
"name": "name",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false
},
"time_created": {
"name": "time_created",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"time_deleted": {
"name": "time_deleted",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
}
},
"indexes": {
"slug": {
"name": "slug",
"columns": [
{
"expression": "slug",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": true,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
}
},
"enums": {},
"schemas": {},
"sequences": {},
"roles": {},
"policies": {},
"views": {},
"_meta": {
"columns": {},
"schemas": {},
"tables": {}
}
}
@@ -0,0 +1,615 @@
{
"id": "351e4956-74e0-4282-a23b-02f1a73fa38c",
"prevId": "bf9e9084-4073-4ecb-8e56-5610816c9589",
"version": "7",
"dialect": "postgresql",
"tables": {
"public.account": {
"name": "account",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "varchar(30)",
"primaryKey": false,
"notNull": true
},
"time_created": {
"name": "time_created",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"time_deleted": {
"name": "time_deleted",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"email": {
"name": "email",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true
}
},
"indexes": {
"email": {
"name": "email",
"columns": [
{
"expression": "email",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": true,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.billing": {
"name": "billing",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "varchar(30)",
"primaryKey": false,
"notNull": true
},
"workspace_id": {
"name": "workspace_id",
"type": "varchar(30)",
"primaryKey": false,
"notNull": true
},
"time_created": {
"name": "time_created",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"time_deleted": {
"name": "time_deleted",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"customer_id": {
"name": "customer_id",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false
},
"payment_method_id": {
"name": "payment_method_id",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false
},
"payment_method_last4": {
"name": "payment_method_last4",
"type": "varchar(4)",
"primaryKey": false,
"notNull": false
},
"balance": {
"name": "balance",
"type": "bigint",
"primaryKey": false,
"notNull": true
},
"reload": {
"name": "reload",
"type": "boolean",
"primaryKey": false,
"notNull": false
}
},
"indexes": {},
"foreignKeys": {
"billing_workspace_id_workspace_id_fk": {
"name": "billing_workspace_id_workspace_id_fk",
"tableFrom": "billing",
"tableTo": "workspace",
"columnsFrom": [
"workspace_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {
"billing_workspace_id_id_pk": {
"name": "billing_workspace_id_id_pk",
"columns": [
"workspace_id",
"id"
]
}
},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.payment": {
"name": "payment",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "varchar(30)",
"primaryKey": false,
"notNull": true
},
"workspace_id": {
"name": "workspace_id",
"type": "varchar(30)",
"primaryKey": false,
"notNull": true
},
"time_created": {
"name": "time_created",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"time_deleted": {
"name": "time_deleted",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"customer_id": {
"name": "customer_id",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false
},
"payment_id": {
"name": "payment_id",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false
},
"amount": {
"name": "amount",
"type": "bigint",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {
"payment_workspace_id_workspace_id_fk": {
"name": "payment_workspace_id_workspace_id_fk",
"tableFrom": "payment",
"tableTo": "workspace",
"columnsFrom": [
"workspace_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {
"payment_workspace_id_id_pk": {
"name": "payment_workspace_id_id_pk",
"columns": [
"workspace_id",
"id"
]
}
},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.usage": {
"name": "usage",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "varchar(30)",
"primaryKey": false,
"notNull": true
},
"workspace_id": {
"name": "workspace_id",
"type": "varchar(30)",
"primaryKey": false,
"notNull": true
},
"time_created": {
"name": "time_created",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"time_deleted": {
"name": "time_deleted",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"request_id": {
"name": "request_id",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false
},
"model": {
"name": "model",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true
},
"input_tokens": {
"name": "input_tokens",
"type": "integer",
"primaryKey": false,
"notNull": true
},
"output_tokens": {
"name": "output_tokens",
"type": "integer",
"primaryKey": false,
"notNull": true
},
"reasoning_tokens": {
"name": "reasoning_tokens",
"type": "integer",
"primaryKey": false,
"notNull": false
},
"cache_read_tokens": {
"name": "cache_read_tokens",
"type": "integer",
"primaryKey": false,
"notNull": false
},
"cache_write_tokens": {
"name": "cache_write_tokens",
"type": "integer",
"primaryKey": false,
"notNull": false
},
"cost": {
"name": "cost",
"type": "bigint",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {
"usage_workspace_id_workspace_id_fk": {
"name": "usage_workspace_id_workspace_id_fk",
"tableFrom": "usage",
"tableTo": "workspace",
"columnsFrom": [
"workspace_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {
"usage_workspace_id_id_pk": {
"name": "usage_workspace_id_id_pk",
"columns": [
"workspace_id",
"id"
]
}
},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.key": {
"name": "key",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "varchar(30)",
"primaryKey": false,
"notNull": true
},
"workspace_id": {
"name": "workspace_id",
"type": "varchar(30)",
"primaryKey": false,
"notNull": true
},
"time_created": {
"name": "time_created",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"time_deleted": {
"name": "time_deleted",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"user_id": {
"name": "user_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"name": {
"name": "name",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true
},
"key": {
"name": "key",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true
},
"time_used": {
"name": "time_used",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
}
},
"indexes": {
"global_key": {
"name": "global_key",
"columns": [
{
"expression": "key",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": true,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {
"key_workspace_id_workspace_id_fk": {
"name": "key_workspace_id_workspace_id_fk",
"tableFrom": "key",
"tableTo": "workspace",
"columnsFrom": [
"workspace_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {
"key_workspace_id_id_pk": {
"name": "key_workspace_id_id_pk",
"columns": [
"workspace_id",
"id"
]
}
},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.user": {
"name": "user",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "varchar(30)",
"primaryKey": false,
"notNull": true
},
"workspace_id": {
"name": "workspace_id",
"type": "varchar(30)",
"primaryKey": false,
"notNull": true
},
"time_created": {
"name": "time_created",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"time_deleted": {
"name": "time_deleted",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"email": {
"name": "email",
"type": "text",
"primaryKey": false,
"notNull": true
},
"name": {
"name": "name",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true
},
"time_seen": {
"name": "time_seen",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"color": {
"name": "color",
"type": "integer",
"primaryKey": false,
"notNull": false
}
},
"indexes": {
"user_email": {
"name": "user_email",
"columns": [
{
"expression": "workspace_id",
"isExpression": false,
"asc": true,
"nulls": "last"
},
{
"expression": "email",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": true,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {
"user_workspace_id_workspace_id_fk": {
"name": "user_workspace_id_workspace_id_fk",
"tableFrom": "user",
"tableTo": "workspace",
"columnsFrom": [
"workspace_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {
"user_workspace_id_id_pk": {
"name": "user_workspace_id_id_pk",
"columns": [
"workspace_id",
"id"
]
}
},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.workspace": {
"name": "workspace",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "varchar(30)",
"primaryKey": true,
"notNull": true
},
"slug": {
"name": "slug",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false
},
"name": {
"name": "name",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false
},
"time_created": {
"name": "time_created",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"time_deleted": {
"name": "time_deleted",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
}
},
"indexes": {
"slug": {
"name": "slug",
"columns": [
{
"expression": "slug",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": true,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
}
},
"enums": {},
"schemas": {},
"sequences": {},
"roles": {},
"policies": {},
"views": {},
"_meta": {
"columns": {},
"schemas": {},
"tables": {}
}
}
@@ -0,0 +1,609 @@
{
"id": "fa935883-9e51-4811-90c7-8967eefe458c",
"prevId": "351e4956-74e0-4282-a23b-02f1a73fa38c",
"version": "7",
"dialect": "postgresql",
"tables": {
"public.account": {
"name": "account",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "varchar(30)",
"primaryKey": false,
"notNull": true
},
"time_created": {
"name": "time_created",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"time_deleted": {
"name": "time_deleted",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"email": {
"name": "email",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true
}
},
"indexes": {
"email": {
"name": "email",
"columns": [
{
"expression": "email",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": true,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.billing": {
"name": "billing",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "varchar(30)",
"primaryKey": false,
"notNull": true
},
"workspace_id": {
"name": "workspace_id",
"type": "varchar(30)",
"primaryKey": false,
"notNull": true
},
"time_created": {
"name": "time_created",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"time_deleted": {
"name": "time_deleted",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"customer_id": {
"name": "customer_id",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false
},
"payment_method_id": {
"name": "payment_method_id",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false
},
"payment_method_last4": {
"name": "payment_method_last4",
"type": "varchar(4)",
"primaryKey": false,
"notNull": false
},
"balance": {
"name": "balance",
"type": "bigint",
"primaryKey": false,
"notNull": true
},
"reload": {
"name": "reload",
"type": "boolean",
"primaryKey": false,
"notNull": false
}
},
"indexes": {},
"foreignKeys": {
"billing_workspace_id_workspace_id_fk": {
"name": "billing_workspace_id_workspace_id_fk",
"tableFrom": "billing",
"tableTo": "workspace",
"columnsFrom": [
"workspace_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {
"billing_workspace_id_id_pk": {
"name": "billing_workspace_id_id_pk",
"columns": [
"workspace_id",
"id"
]
}
},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.payment": {
"name": "payment",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "varchar(30)",
"primaryKey": false,
"notNull": true
},
"workspace_id": {
"name": "workspace_id",
"type": "varchar(30)",
"primaryKey": false,
"notNull": true
},
"time_created": {
"name": "time_created",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"time_deleted": {
"name": "time_deleted",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"customer_id": {
"name": "customer_id",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false
},
"payment_id": {
"name": "payment_id",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false
},
"amount": {
"name": "amount",
"type": "bigint",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {
"payment_workspace_id_workspace_id_fk": {
"name": "payment_workspace_id_workspace_id_fk",
"tableFrom": "payment",
"tableTo": "workspace",
"columnsFrom": [
"workspace_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {
"payment_workspace_id_id_pk": {
"name": "payment_workspace_id_id_pk",
"columns": [
"workspace_id",
"id"
]
}
},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.usage": {
"name": "usage",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "varchar(30)",
"primaryKey": false,
"notNull": true
},
"workspace_id": {
"name": "workspace_id",
"type": "varchar(30)",
"primaryKey": false,
"notNull": true
},
"time_created": {
"name": "time_created",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"time_deleted": {
"name": "time_deleted",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"model": {
"name": "model",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true
},
"input_tokens": {
"name": "input_tokens",
"type": "integer",
"primaryKey": false,
"notNull": true
},
"output_tokens": {
"name": "output_tokens",
"type": "integer",
"primaryKey": false,
"notNull": true
},
"reasoning_tokens": {
"name": "reasoning_tokens",
"type": "integer",
"primaryKey": false,
"notNull": false
},
"cache_read_tokens": {
"name": "cache_read_tokens",
"type": "integer",
"primaryKey": false,
"notNull": false
},
"cache_write_tokens": {
"name": "cache_write_tokens",
"type": "integer",
"primaryKey": false,
"notNull": false
},
"cost": {
"name": "cost",
"type": "bigint",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {
"usage_workspace_id_workspace_id_fk": {
"name": "usage_workspace_id_workspace_id_fk",
"tableFrom": "usage",
"tableTo": "workspace",
"columnsFrom": [
"workspace_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {
"usage_workspace_id_id_pk": {
"name": "usage_workspace_id_id_pk",
"columns": [
"workspace_id",
"id"
]
}
},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.key": {
"name": "key",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "varchar(30)",
"primaryKey": false,
"notNull": true
},
"workspace_id": {
"name": "workspace_id",
"type": "varchar(30)",
"primaryKey": false,
"notNull": true
},
"time_created": {
"name": "time_created",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"time_deleted": {
"name": "time_deleted",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"user_id": {
"name": "user_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"name": {
"name": "name",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true
},
"key": {
"name": "key",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true
},
"time_used": {
"name": "time_used",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
}
},
"indexes": {
"global_key": {
"name": "global_key",
"columns": [
{
"expression": "key",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": true,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {
"key_workspace_id_workspace_id_fk": {
"name": "key_workspace_id_workspace_id_fk",
"tableFrom": "key",
"tableTo": "workspace",
"columnsFrom": [
"workspace_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {
"key_workspace_id_id_pk": {
"name": "key_workspace_id_id_pk",
"columns": [
"workspace_id",
"id"
]
}
},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.user": {
"name": "user",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "varchar(30)",
"primaryKey": false,
"notNull": true
},
"workspace_id": {
"name": "workspace_id",
"type": "varchar(30)",
"primaryKey": false,
"notNull": true
},
"time_created": {
"name": "time_created",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"time_deleted": {
"name": "time_deleted",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"email": {
"name": "email",
"type": "text",
"primaryKey": false,
"notNull": true
},
"name": {
"name": "name",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true
},
"time_seen": {
"name": "time_seen",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"color": {
"name": "color",
"type": "integer",
"primaryKey": false,
"notNull": false
}
},
"indexes": {
"user_email": {
"name": "user_email",
"columns": [
{
"expression": "workspace_id",
"isExpression": false,
"asc": true,
"nulls": "last"
},
{
"expression": "email",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": true,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {
"user_workspace_id_workspace_id_fk": {
"name": "user_workspace_id_workspace_id_fk",
"tableFrom": "user",
"tableTo": "workspace",
"columnsFrom": [
"workspace_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {
"user_workspace_id_id_pk": {
"name": "user_workspace_id_id_pk",
"columns": [
"workspace_id",
"id"
]
}
},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.workspace": {
"name": "workspace",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "varchar(30)",
"primaryKey": true,
"notNull": true
},
"slug": {
"name": "slug",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false
},
"name": {
"name": "name",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false
},
"time_created": {
"name": "time_created",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"time_deleted": {
"name": "time_deleted",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
}
},
"indexes": {
"slug": {
"name": "slug",
"columns": [
{
"expression": "slug",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": true,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
}
},
"enums": {},
"schemas": {},
"sequences": {},
"roles": {},
"policies": {},
"views": {},
"_meta": {
"columns": {},
"schemas": {},
"tables": {}
}
}
+34
View File
@@ -0,0 +1,34 @@
{
"version": "7",
"dialect": "postgresql",
"entries": [
{
"idx": 0,
"version": "7",
"when": 1754518198186,
"tag": "0000_amused_mojo",
"breakpoints": true
},
{
"idx": 1,
"version": "7",
"when": 1754609655262,
"tag": "0001_thankful_chat",
"breakpoints": true
},
{
"idx": 2,
"version": "7",
"when": 1754627626945,
"tag": "0002_stale_jackal",
"breakpoints": true
},
{
"idx": 3,
"version": "7",
"when": 1754672464106,
"tag": "0003_tranquil_spencer_smythe",
"breakpoints": true
}
]
}
+23
View File
@@ -0,0 +1,23 @@
{
"$schema": "https://json.schemastore.org/package.json",
"name": "@opencode/cloud-core",
"version": "0.4.22",
"private": true,
"type": "module",
"dependencies": {
"@aws-sdk/client-sts": "3.782.0",
"drizzle-orm": "0.41.0",
"postgres": "3.4.7",
"stripe": "18.0.0",
"ulid": "3.0.0"
},
"exports": {
"./*": "./src/*"
},
"scripts": {
"db": "sst shell drizzle-kit"
},
"devDependencies": {
"drizzle-kit": "0.30.5"
}
}
+67
View File
@@ -0,0 +1,67 @@
import { z } from "zod"
import { and, eq, getTableColumns, isNull } from "drizzle-orm"
import { fn } from "./util/fn"
import { Database } from "./drizzle"
import { Identifier } from "./identifier"
import { AccountTable } from "./schema/account.sql"
import { Actor } from "./actor"
import { WorkspaceTable } from "./schema/workspace.sql"
import { UserTable } from "./schema/user.sql"
export namespace Account {
export const create = fn(
z.object({
email: z.string().email(),
id: z.string().optional(),
}),
async (input) =>
Database.transaction(async (tx) => {
const id = input.id ?? Identifier.create("account")
await tx.insert(AccountTable).values({
id,
email: input.email,
})
return id
}),
)
export const fromID = fn(z.string(), async (id) =>
Database.transaction(async (tx) => {
return tx
.select()
.from(AccountTable)
.where(eq(AccountTable.id, id))
.execute()
.then((rows) => rows[0])
}),
)
export const fromEmail = fn(z.string().email(), async (email) =>
Database.transaction(async (tx) => {
return tx
.select()
.from(AccountTable)
.where(eq(AccountTable.email, email))
.execute()
.then((rows) => rows[0])
}),
)
export const workspaces = async () => {
const actor = Actor.assert("account")
return Database.transaction(async (tx) =>
tx
.select(getTableColumns(WorkspaceTable))
.from(WorkspaceTable)
.innerJoin(UserTable, eq(UserTable.workspaceID, WorkspaceTable.id))
.where(
and(
eq(UserTable.email, actor.properties.email),
isNull(UserTable.timeDeleted),
isNull(WorkspaceTable.timeDeleted),
),
)
.execute(),
)
}
}
+75
View File
@@ -0,0 +1,75 @@
import { Context } from "./context"
import { Log } from "./util/log"
export namespace Actor {
interface Account {
type: "account"
properties: {
accountID: string
email: string
}
}
interface Public {
type: "public"
properties: {}
}
interface User {
type: "user"
properties: {
userID: string
workspaceID: string
email: string
}
}
interface System {
type: "system"
properties: {
workspaceID: string
}
}
export type Info = Account | Public | User | System
const ctx = Context.create<Info>()
export const use = ctx.use
const log = Log.create().tag("namespace", "actor")
export function provide<R, T extends Info["type"]>(
type: T,
properties: Extract<Info, { type: T }>["properties"],
cb: () => R,
) {
return ctx.provide(
{
type,
properties,
} as any,
() => {
return Log.provide({ ...properties }, () => {
log.info("provided")
return cb()
})
},
)
}
export function assert<T extends Info["type"]>(type: T) {
const actor = use()
if (actor.type !== type) {
throw new Error(`Expected actor type ${type}, got ${actor.type}`)
}
return actor as Extract<Info, { type: T }>
}
export function workspace() {
const actor = use()
if ("workspaceID" in actor.properties) {
return actor.properties.workspaceID
}
throw new Error(`actor of type "${actor.type}" is not associated with a workspace`)
}
}
+71
View File
@@ -0,0 +1,71 @@
import { Resource } from "sst"
import { Stripe } from "stripe"
import { Database, eq, sql } from "./drizzle"
import { BillingTable, UsageTable } from "./schema/billing.sql"
import { Actor } from "./actor"
import { fn } from "./util/fn"
import { z } from "zod"
import { Identifier } from "./identifier"
import { centsToMicroCents } from "./util/price"
export namespace Billing {
export const stripe = () =>
new Stripe(Resource.STRIPE_SECRET_KEY.value, {
apiVersion: "2025-03-31.basil",
})
export const get = async () => {
return Database.use(async (tx) =>
tx
.select({
customerID: BillingTable.customerID,
paymentMethodID: BillingTable.paymentMethodID,
balance: BillingTable.balance,
reload: BillingTable.reload,
})
.from(BillingTable)
.where(eq(BillingTable.workspaceID, Actor.workspace()))
.then((r) => r[0]),
)
}
export const consume = fn(
z.object({
requestID: z.string().optional(),
model: z.string(),
inputTokens: z.number(),
outputTokens: z.number(),
reasoningTokens: z.number().optional(),
cacheReadTokens: z.number().optional(),
cacheWriteTokens: z.number().optional(),
costInCents: z.number(),
}),
async (input) => {
const workspaceID = Actor.workspace()
const cost = centsToMicroCents(input.costInCents)
return await Database.transaction(async (tx) => {
await tx.insert(UsageTable).values({
workspaceID,
id: Identifier.create("usage"),
requestID: input.requestID,
model: input.model,
inputTokens: input.inputTokens,
outputTokens: input.outputTokens,
reasoningTokens: input.reasoningTokens,
cacheReadTokens: input.cacheReadTokens,
cacheWriteTokens: input.cacheWriteTokens,
cost,
})
const [updated] = await tx
.update(BillingTable)
.set({
balance: sql`${BillingTable.balance} - ${cost}`,
})
.where(eq(BillingTable.workspaceID, workspaceID))
.returning()
return updated.balance
})
},
)
}
+21
View File
@@ -0,0 +1,21 @@
import { AsyncLocalStorage } from "node:async_hooks"
export namespace Context {
export class NotFound extends Error {}
export function create<T>() {
const storage = new AsyncLocalStorage<T>()
return {
use() {
const result = storage.getStore()
if (!result) {
throw new NotFound()
}
return result
},
provide<R>(value: T, fn: () => R) {
return storage.run<R>(value, fn)
},
}
}
}
+94
View File
@@ -0,0 +1,94 @@
import { drizzle } from "drizzle-orm/postgres-js"
import { Resource } from "sst"
export * from "drizzle-orm"
import postgres from "postgres"
function createClient() {
const client = postgres({
idle_timeout: 30000,
connect_timeout: 30000,
host: Resource.Database.host,
database: Resource.Database.database,
user: Resource.Database.username,
password: Resource.Database.password,
port: Resource.Database.port,
ssl: {
rejectUnauthorized: false,
},
max: 1,
})
return drizzle(client, {})
}
import { PgTransaction, type PgTransactionConfig } from "drizzle-orm/pg-core"
import type { ExtractTablesWithRelations } from "drizzle-orm"
import type { PostgresJsQueryResultHKT } from "drizzle-orm/postgres-js"
import { Context } from "../context"
export namespace Database {
export type Transaction = PgTransaction<
PostgresJsQueryResultHKT,
Record<string, unknown>,
ExtractTablesWithRelations<Record<string, unknown>>
>
export type TxOrDb = Transaction | ReturnType<typeof createClient>
const TransactionContext = Context.create<{
tx: TxOrDb
effects: (() => void | Promise<void>)[]
}>()
export async function use<T>(callback: (trx: TxOrDb) => Promise<T>) {
try {
const { tx } = TransactionContext.use()
return tx.transaction(callback)
} catch (err) {
if (err instanceof Context.NotFound) {
const client = createClient()
const effects: (() => void | Promise<void>)[] = []
const result = await TransactionContext.provide(
{
effects,
tx: client,
},
() => callback(client),
)
await Promise.all(effects.map((x) => x()))
return result
}
throw err
}
}
export async function fn<Input, T>(callback: (input: Input, trx: TxOrDb) => Promise<T>) {
return (input: Input) => use(async (tx) => callback(input, tx))
}
export async function effect(effect: () => any | Promise<any>) {
try {
const { effects } = TransactionContext.use()
effects.push(effect)
} catch {
await effect()
}
}
export async function transaction<T>(callback: (tx: TxOrDb) => Promise<T>, config?: PgTransactionConfig) {
try {
const { tx } = TransactionContext.use()
return callback(tx)
} catch (err) {
if (err instanceof Context.NotFound) {
const client = createClient()
const effects: (() => void | Promise<void>)[] = []
const result = await client.transaction(async (tx) => {
return TransactionContext.provide({ tx, effects }, () => callback(tx))
}, config)
await Promise.all(effects.map((x) => x()))
return result
}
throw err
}
}
}
+29
View File
@@ -0,0 +1,29 @@
import { bigint, timestamp, varchar } from "drizzle-orm/pg-core"
export const ulid = (name: string) => varchar(name, { length: 30 })
export const workspaceColumns = {
get id() {
return ulid("id").notNull()
},
get workspaceID() {
return ulid("workspace_id").notNull()
},
}
export const id = () => ulid("id").notNull()
export const utc = (name: string) =>
timestamp(name, {
withTimezone: true,
})
export const currency = (name: string) =>
bigint(name, {
mode: "number",
})
export const timestamps = {
timeCreated: utc("time_created").notNull().defaultNow(),
timeDeleted: utc("time_deleted"),
}
+26
View File
@@ -0,0 +1,26 @@
import { ulid } from "ulid"
import { z } from "zod"
export namespace Identifier {
const prefixes = {
account: "acc",
billing: "bil",
key: "key",
payment: "pay",
usage: "usg",
user: "usr",
workspace: "wrk",
} as const
export function create(prefix: keyof typeof prefixes, given?: string): string {
if (given) {
if (given.startsWith(prefixes[prefix])) return given
throw new Error(`ID ${given} does not start with ${prefixes[prefix]}`)
}
return [prefixes[prefix], ulid()].join("_")
}
export function schema(prefix: keyof typeof prefixes) {
return z.string().startsWith(prefixes[prefix])
}
}
+12
View File
@@ -0,0 +1,12 @@
import { pgTable, uniqueIndex, varchar } from "drizzle-orm/pg-core"
import { id, timestamps } from "../drizzle/types"
export const AccountTable = pgTable(
"account",
{
id: id(),
...timestamps,
email: varchar("email", { length: 255 }).notNull(),
},
(table) => [uniqueIndex("email").on(table.email)],
)
+45
View File
@@ -0,0 +1,45 @@
import { bigint, boolean, integer, pgTable, varchar } from "drizzle-orm/pg-core"
import { timestamps, workspaceColumns } from "../drizzle/types"
import { workspaceIndexes } from "./workspace.sql"
export const BillingTable = pgTable(
"billing",
{
...workspaceColumns,
...timestamps,
customerID: varchar("customer_id", { length: 255 }),
paymentMethodID: varchar("payment_method_id", { length: 255 }),
paymentMethodLast4: varchar("payment_method_last4", { length: 4 }),
balance: bigint("balance", { mode: "number" }).notNull(),
reload: boolean("reload"),
},
(table) => [...workspaceIndexes(table)],
)
export const PaymentTable = pgTable(
"payment",
{
...workspaceColumns,
...timestamps,
customerID: varchar("customer_id", { length: 255 }),
paymentID: varchar("payment_id", { length: 255 }),
amount: bigint("amount", { mode: "number" }).notNull(),
},
(table) => [...workspaceIndexes(table)],
)
export const UsageTable = pgTable(
"usage",
{
...workspaceColumns,
...timestamps,
model: varchar("model", { length: 255 }).notNull(),
inputTokens: integer("input_tokens").notNull(),
outputTokens: integer("output_tokens").notNull(),
reasoningTokens: integer("reasoning_tokens"),
cacheReadTokens: integer("cache_read_tokens"),
cacheWriteTokens: integer("cache_write_tokens"),
cost: bigint("cost", { mode: "number" }).notNull(),
},
(table) => [...workspaceIndexes(table)],
)
+16
View File
@@ -0,0 +1,16 @@
import { text, pgTable, varchar, uniqueIndex } from "drizzle-orm/pg-core"
import { timestamps, utc, workspaceColumns } from "../drizzle/types"
import { workspaceIndexes } from "./workspace.sql"
export const KeyTable = pgTable(
"key",
{
...workspaceColumns,
...timestamps,
userID: text("user_id").notNull(),
name: varchar("name", { length: 255 }).notNull(),
key: varchar("key", { length: 255 }).notNull(),
timeUsed: utc("time_used"),
},
(table) => [...workspaceIndexes(table), uniqueIndex("global_key").on(table.key)],
)
+16
View File
@@ -0,0 +1,16 @@
import { text, pgTable, uniqueIndex, varchar, integer } from "drizzle-orm/pg-core"
import { timestamps, utc, workspaceColumns } from "../drizzle/types"
import { workspaceIndexes } from "./workspace.sql"
export const UserTable = pgTable(
"user",
{
...workspaceColumns,
...timestamps,
email: text("email").notNull(),
name: varchar("name", { length: 255 }).notNull(),
timeSeen: utc("time_seen"),
color: integer("color"),
},
(table) => [...workspaceIndexes(table), uniqueIndex("user_email").on(table.workspaceID, table.email)],
)
+25
View File
@@ -0,0 +1,25 @@
import { primaryKey, foreignKey, pgTable, uniqueIndex, varchar } from "drizzle-orm/pg-core"
import { timestamps, ulid } from "../drizzle/types"
export const WorkspaceTable = pgTable(
"workspace",
{
id: ulid("id").notNull().primaryKey(),
slug: varchar("slug", { length: 255 }),
name: varchar("name", { length: 255 }),
...timestamps,
},
(table) => [uniqueIndex("slug").on(table.slug)],
)
export function workspaceIndexes(table: any) {
return [
primaryKey({
columns: [table.workspaceID, table.id],
}),
foreignKey({
foreignColumns: [WorkspaceTable.id],
columns: [table.workspaceID],
}),
]
}
+14
View File
@@ -0,0 +1,14 @@
import { z } from "zod"
export function fn<T extends z.ZodType, Result>(
schema: T,
cb: (input: z.output<T>) => Result,
) {
const result = (input: z.input<T>) => {
const parsed = schema.parse(input)
return cb(parsed)
}
result.force = (input: z.input<T>) => cb(input)
result.schema = schema
return result
}
+55
View File
@@ -0,0 +1,55 @@
import { Context } from "../context"
export namespace Log {
const ctx = Context.create<{
tags: Record<string, any>
}>()
export function create(tags?: Record<string, any>) {
tags = tags || {}
const result = {
info(message?: any, extra?: Record<string, any>) {
const prefix = Object.entries({
...use().tags,
...tags,
...extra,
})
.map(([key, value]) => `${key}=${value}`)
.join(" ")
console.log(prefix, message)
return result
},
tag(key: string, value: string) {
if (tags) tags[key] = value
return result
},
clone() {
return Log.create({ ...tags })
},
}
return result
}
export function provide<R>(tags: Record<string, any>, cb: () => R) {
const existing = use()
return ctx.provide(
{
tags: {
...existing.tags,
...tags,
},
},
cb,
)
}
function use() {
try {
return ctx.use()
} catch (e) {
return { tags: {} }
}
}
}
+3
View File
@@ -0,0 +1,3 @@
export function centsToMicroCents(amount: number) {
return Math.round(amount * 1000000)
}
+48
View File
@@ -0,0 +1,48 @@
import { z } from "zod"
import { fn } from "./util/fn"
import { centsToMicroCents } from "./util/price"
import { Actor } from "./actor"
import { Database, eq } from "./drizzle"
import { Identifier } from "./identifier"
import { UserTable } from "./schema/user.sql"
import { BillingTable } from "./schema/billing.sql"
import { WorkspaceTable } from "./schema/workspace.sql"
export namespace Workspace {
export const create = fn(z.void(), async () => {
const account = Actor.assert("account")
const workspaceID = Identifier.create("workspace")
await Database.transaction(async (tx) => {
await tx.insert(WorkspaceTable).values({
id: workspaceID,
})
await tx.insert(UserTable).values({
workspaceID,
id: Identifier.create("user"),
email: account.properties.email,
name: "",
})
await tx.insert(BillingTable).values({
workspaceID,
id: Identifier.create("billing"),
balance: centsToMicroCents(100),
})
})
return workspaceID
})
export async function list() {
const account = Actor.assert("account")
return Database.use(async (tx) => {
return tx
.select({
id: WorkspaceTable.id,
slug: WorkspaceTable.slug,
name: WorkspaceTable.name,
})
.from(UserTable)
.innerJoin(WorkspaceTable, eq(UserTable.workspaceID, WorkspaceTable.id))
.where(eq(UserTable.email, account.properties.email))
})
}
}
+9
View File
@@ -0,0 +1,9 @@
/* This file is auto-generated by SST. Do not edit. */
/* tslint:disable */
/* eslint-disable */
/* deno-fmt-ignore-file */
/// <reference path="../../sst-env.d.ts" />
import "sst"
export {}
+9
View File
@@ -0,0 +1,9 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"extends": "@tsconfig/node22/tsconfig.json",
"compilerOptions": {
"module": "ESNext",
"moduleResolution": "bundler",
"types": ["@cloudflare/workers-types", "node"]
}
}
+23
View File
@@ -0,0 +1,23 @@
{
"name": "@opencode/cloud-function",
"version": "0.4.22",
"$schema": "https://json.schemastore.org/package.json",
"private": true,
"type": "module",
"devDependencies": {
"@cloudflare/workers-types": "4.20250522.0",
"@types/node": "catalog:",
"openai": "5.11.0",
"typescript": "catalog:"
},
"dependencies": {
"@ai-sdk/anthropic": "2.0.0",
"@ai-sdk/openai": "2.0.2",
"@ai-sdk/openai-compatible": "1.0.1",
"@hono/zod-validator": "catalog:",
"@openauthjs/openauth": "0.0.0-20250322224806",
"ai": "catalog:",
"hono": "catalog:",
"zod": "catalog:"
}
}
+124
View File
@@ -0,0 +1,124 @@
import { Resource } from "sst"
import { z } from "zod"
import { issuer } from "@openauthjs/openauth"
import { createSubjects } from "@openauthjs/openauth/subject"
import { CodeProvider } from "@openauthjs/openauth/provider/code"
import { GithubProvider } from "@openauthjs/openauth/provider/github"
import { GoogleOidcProvider } from "@openauthjs/openauth/provider/google"
import { CloudflareStorage } from "@openauthjs/openauth/storage/cloudflare"
import { Account } from "@opencode/cloud-core/account.js"
type Env = {
AuthStorage: KVNamespace
}
export const subjects = createSubjects({
account: z.object({
accountID: z.string(),
email: z.string(),
}),
user: z.object({
userID: z.string(),
workspaceID: z.string(),
}),
})
export default {
async fetch(request: Request, env: Env, ctx: ExecutionContext) {
return issuer({
providers: {
github: GithubProvider({
clientID: Resource.GITHUB_CLIENT_ID_CONSOLE.value,
clientSecret: Resource.GITHUB_CLIENT_SECRET_CONSOLE.value,
scopes: ["read:user", "user:email"],
}),
google: GoogleOidcProvider({
clientID: Resource.GOOGLE_CLIENT_ID.value,
scopes: ["openid", "email"],
}),
// email: CodeProvider({
// async request(req, state, form, error) {
// console.log(state)
// const params = new URLSearchParams()
// if (error) {
// params.set("error", error.type)
// }
// if (state.type === "start") {
// return Response.redirect(process.env.AUTH_FRONTEND_URL + "/auth/email?" + params.toString(), 302)
// }
//
// if (state.type === "code") {
// return Response.redirect(process.env.AUTH_FRONTEND_URL + "/auth/code?" + params.toString(), 302)
// }
//
// return new Response("ok")
// },
// async sendCode(claims, code) {
// const email = z.string().email().parse(claims.email)
// const cmd = new SendEmailCommand({
// Destination: {
// ToAddresses: [email],
// },
// FromEmailAddress: `SST <auth@${Resource.Email.sender}>`,
// Content: {
// Simple: {
// Body: {
// Html: {
// Data: `Your pin code is <strong>${code}</strong>`,
// },
// Text: {
// Data: `Your pin code is ${code}`,
// },
// },
// Subject: {
// Data: "SST Console Pin Code: " + code,
// },
// },
// },
// })
// await ses.send(cmd)
// },
// }),
},
storage: CloudflareStorage({
namespace: env.AuthStorage,
}),
subjects,
async success(ctx, response) {
console.log(response)
let email: string | undefined
if (response.provider === "github") {
const userResponse = await fetch("https://api.github.com/user", {
headers: {
Authorization: `Bearer ${response.tokenset.access}`,
"User-Agent": "opencode",
Accept: "application/vnd.github+json",
},
})
const user = (await userResponse.json()) as { email: string }
email = user.email
} else if (response.provider === "google") {
if (!response.id.email_verified) throw new Error("Google email not verified")
email = response.id.email as string
}
//if (response.provider === "email") {
// email = response.claims.email
//}
else throw new Error("Unsupported provider")
if (!email) throw new Error("No email found")
let accountID = await Account.fromEmail(email).then((x) => x?.id)
if (!accountID) {
console.log("creating account for", email)
accountID = await Account.create({
email: email!,
})
}
return ctx.subject("account", accountID, { accountID, email })
},
}).fetch(request, env, ctx)
},
}
+909
View File
@@ -0,0 +1,909 @@
import { z } from "zod"
import { Hono, MiddlewareHandler } from "hono"
import { cors } from "hono/cors"
import { HTTPException } from "hono/http-exception"
import { zValidator } from "@hono/zod-validator"
import { Resource } from "sst"
import { type ProviderMetadata, type LanguageModelUsage, generateText, streamText } from "ai"
import { createAnthropic } from "@ai-sdk/anthropic"
import { createOpenAI } from "@ai-sdk/openai"
import { createOpenAICompatible } from "@ai-sdk/openai-compatible"
import type { LanguageModelV2Prompt } from "@ai-sdk/provider"
import { type ChatCompletionCreateParamsBase } from "openai/resources/chat/completions"
import { Actor } from "@opencode/cloud-core/actor.js"
import { and, Database, eq, sql } from "@opencode/cloud-core/drizzle/index.js"
import { UserTable } from "@opencode/cloud-core/schema/user.sql.js"
import { KeyTable } from "@opencode/cloud-core/schema/key.sql.js"
import { createClient } from "@openauthjs/openauth/client"
import { Log } from "@opencode/cloud-core/util/log.js"
import { Billing } from "@opencode/cloud-core/billing.js"
import { Workspace } from "@opencode/cloud-core/workspace.js"
import { BillingTable, PaymentTable, UsageTable } from "@opencode/cloud-core/schema/billing.sql.js"
import { centsToMicroCents } from "@opencode/cloud-core/util/price.js"
import { Identifier } from "../../core/src/identifier"
type Env = {}
let _client: ReturnType<typeof createClient>
const client = () => {
if (_client) return _client
_client = createClient({
clientID: "api",
issuer: Resource.AUTH_API_URL.value,
})
return _client
}
const SUPPORTED_MODELS = {
"anthropic/claude-sonnet-4": {
input: 0.0000015,
output: 0.000006,
reasoning: 0.0000015,
cacheRead: 0.0000001,
cacheWrite: 0.0000001,
model: () =>
createAnthropic({
apiKey: Resource.ANTHROPIC_API_KEY.value,
})("claude-sonnet-4-20250514"),
},
"openai/gpt-4.1": {
input: 0.0000015,
output: 0.000006,
reasoning: 0.0000015,
cacheRead: 0.0000001,
cacheWrite: 0.0000001,
model: () =>
createOpenAI({
apiKey: Resource.OPENAI_API_KEY.value,
})("gpt-4.1"),
},
"zhipuai/glm-4.5-flash": {
input: 0,
output: 0,
reasoning: 0,
cacheRead: 0,
cacheWrite: 0,
model: () =>
createOpenAICompatible({
name: "Zhipu AI",
baseURL: "https://api.z.ai/api/paas/v4",
apiKey: Resource.ZHIPU_API_KEY.value,
})("glm-4.5-flash"),
},
}
const log = Log.create({
namespace: "api",
})
const GatewayAuth: MiddlewareHandler = async (c, next) => {
const authHeader = c.req.header("authorization")
if (!authHeader || !authHeader.startsWith("Bearer ")) {
return c.json(
{
error: {
message: "Missing API key.",
type: "invalid_request_error",
param: null,
code: "unauthorized",
},
},
401,
)
}
const apiKey = authHeader.split(" ")[1]
// Check against KeyTable
const keyRecord = await Database.use((tx) =>
tx
.select({
id: KeyTable.id,
workspaceID: KeyTable.workspaceID,
})
.from(KeyTable)
.where(eq(KeyTable.key, apiKey))
.then((rows) => rows[0]),
)
if (!keyRecord) {
return c.json(
{
error: {
message: "Invalid API key.",
type: "invalid_request_error",
param: null,
code: "unauthorized",
},
},
401,
)
}
c.set("keyRecord", keyRecord)
await next()
}
const RestAuth: MiddlewareHandler = async (c, next) => {
const authorization = c.req.header("authorization")
if (!authorization) {
return Actor.provide("public", {}, next)
}
const token = authorization.split(" ")[1]
if (!token)
throw new HTTPException(403, {
message: "Bearer token is required.",
})
const verified = await client().verify(token)
if (verified.err) {
throw new HTTPException(403, {
message: "Invalid token.",
})
}
let subject = verified.subject as Actor.Info
if (subject.type === "account") {
const workspaceID = c.req.header("x-opencode-workspace")
const email = subject.properties.email
if (workspaceID) {
const user = await Database.use((tx) =>
tx
.select({
id: UserTable.id,
workspaceID: UserTable.workspaceID,
email: UserTable.email,
})
.from(UserTable)
.where(and(eq(UserTable.email, email), eq(UserTable.workspaceID, workspaceID)))
.then((rows) => rows[0]),
)
if (!user)
throw new HTTPException(403, {
message: "You do not have access to this workspace.",
})
subject = {
type: "user",
properties: {
userID: user.id,
workspaceID: workspaceID,
email: user.email,
},
}
}
}
await Actor.provide(subject.type, subject.properties, next)
}
const app = new Hono<{ Bindings: Env; Variables: { keyRecord?: { id: string; workspaceID: string } } }>()
.get("/", (c) => c.text("Hello, world!"))
.post("/v1/chat/completions", GatewayAuth, async (c) => {
const keyRecord = c.get("keyRecord")!
return await Actor.provide("system", { workspaceID: keyRecord.workspaceID }, async () => {
try {
// Check balance
const customer = await Billing.get()
if (customer.balance <= 0) {
return c.json(
{
error: {
message: "Insufficient balance",
type: "insufficient_quota",
param: null,
code: "insufficient_quota",
},
},
401,
)
}
const body = await c.req.json<ChatCompletionCreateParamsBase>()
const model = SUPPORTED_MODELS[body.model as keyof typeof SUPPORTED_MODELS]?.model()
if (!model) throw new Error(`Unsupported model: ${body.model}`)
const requestBody = transformOpenAIRequestToAiSDK()
return body.stream ? await handleStream() : await handleGenerate()
async function handleStream() {
const result = await model.doStream({
...requestBody,
})
const encoder = new TextEncoder()
const stream = new ReadableStream({
async start(controller) {
const id = `chatcmpl-${Date.now()}`
const created = Math.floor(Date.now() / 1000)
try {
for await (const chunk of result.stream) {
console.log("!!! CHUNK !!! : " + chunk.type)
switch (chunk.type) {
case "text-delta": {
const data = {
id,
object: "chat.completion.chunk",
created,
model: body.model,
choices: [
{
index: 0,
delta: {
content: chunk.delta,
},
finish_reason: null,
},
],
}
controller.enqueue(encoder.encode(`data: ${JSON.stringify(data)}\n\n`))
break
}
case "reasoning-delta": {
const data = {
id,
object: "chat.completion.chunk",
created,
model: body.model,
choices: [
{
index: 0,
delta: {
reasoning_content: chunk.delta,
},
finish_reason: null,
},
],
}
controller.enqueue(encoder.encode(`data: ${JSON.stringify(data)}\n\n`))
break
}
case "tool-call": {
const data = {
id,
object: "chat.completion.chunk",
created,
model: body.model,
choices: [
{
index: 0,
delta: {
tool_calls: [
{
index: 0,
id: chunk.toolCallId,
type: "function",
function: {
name: chunk.toolName,
arguments: chunk.input,
},
},
],
},
finish_reason: null,
},
],
}
controller.enqueue(encoder.encode(`data: ${JSON.stringify(data)}\n\n`))
break
}
case "error": {
const data = {
id,
object: "chat.completion.chunk",
created,
model: body.model,
choices: [
{
index: 0,
delta: {},
finish_reason: "stop",
},
],
error: {
message: typeof chunk.error === "string" ? chunk.error : chunk.error,
type: "server_error",
},
}
controller.enqueue(encoder.encode(`data: ${JSON.stringify(data)}\n\n`))
controller.enqueue(encoder.encode("data: [DONE]\n\n"))
controller.close()
break
}
case "finish": {
const data = {
id,
object: "chat.completion.chunk",
created,
model: body.model,
choices: [
{
index: 0,
delta: {},
finish_reason:
{
stop: "stop",
length: "length",
"content-filter": "content_filter",
"tool-calls": "tool_calls",
error: "stop",
other: "stop",
unknown: "stop",
}[chunk.finishReason] || "stop",
},
],
usage: {
prompt_tokens: chunk.usage.inputTokens,
completion_tokens: chunk.usage.outputTokens,
total_tokens: chunk.usage.totalTokens,
completion_tokens_details: {
reasoning_tokens: chunk.usage.reasoningTokens,
},
prompt_tokens_details: {
cached_tokens: chunk.usage.cachedInputTokens,
},
},
}
await trackUsage(body.model, chunk.usage, chunk.providerMetadata)
controller.enqueue(encoder.encode(`data: ${JSON.stringify(data)}\n\n`))
controller.enqueue(encoder.encode("data: [DONE]\n\n"))
controller.close()
break
}
//case "stream-start":
//case "response-metadata":
case "text-start":
case "text-end":
case "reasoning-start":
case "reasoning-end":
case "tool-input-start":
case "tool-input-delta":
case "tool-input-end":
case "raw":
default:
// Log unknown chunk types for debugging
console.warn(`Unknown chunk type: ${(chunk as any).type}`)
break
}
}
} catch (error) {
controller.error(error)
}
},
})
return new Response(stream, {
headers: {
"Content-Type": "text/plain; charset=utf-8",
"Cache-Control": "no-cache",
Connection: "keep-alive",
},
})
}
async function handleGenerate() {
const response = await model.doGenerate({
...requestBody,
})
await trackUsage(body.model, response.usage, response.providerMetadata)
return c.json({
id: `chatcmpl-${Date.now()}`,
object: "chat.completion" as const,
created: Math.floor(Date.now() / 1000),
model: body.model,
choices: [
{
index: 0,
message: {
role: "assistant" as const,
content: response.content?.find((c) => c.type === "text")?.text ?? "",
reasoning_content: response.content?.find((c) => c.type === "reasoning")?.text,
tool_calls: response.content
?.filter((c) => c.type === "tool-call")
.map((toolCall) => ({
id: toolCall.toolCallId,
type: "function" as const,
function: {
name: toolCall.toolName,
arguments: toolCall.input,
},
})),
},
finish_reason:
(
{
stop: "stop",
length: "length",
"content-filter": "content_filter",
"tool-calls": "tool_calls",
error: "stop",
other: "stop",
unknown: "stop",
} as const
)[response.finishReason] || "stop",
},
],
usage: {
prompt_tokens: response.usage?.inputTokens,
completion_tokens: response.usage?.outputTokens,
total_tokens: response.usage?.totalTokens,
completion_tokens_details: {
reasoning_tokens: response.usage?.reasoningTokens,
},
prompt_tokens_details: {
cached_tokens: response.usage?.cachedInputTokens,
},
},
})
}
function transformOpenAIRequestToAiSDK() {
const prompt = transformMessages()
const tools = transformTools()
return {
prompt,
maxOutputTokens: body.max_tokens ?? body.max_completion_tokens ?? undefined,
temperature: body.temperature ?? undefined,
topP: body.top_p ?? undefined,
frequencyPenalty: body.frequency_penalty ?? undefined,
presencePenalty: body.presence_penalty ?? undefined,
providerOptions: body.reasoning_effort
? {
anthropic: {
reasoningEffort: body.reasoning_effort,
},
}
: undefined,
stopSequences: (typeof body.stop === "string" ? [body.stop] : body.stop) ?? undefined,
responseFormat: (() => {
if (!body.response_format) return { type: "text" as const }
if (body.response_format.type === "json_schema")
return {
type: "json" as const,
schema: body.response_format.json_schema.schema,
name: body.response_format.json_schema.name,
description: body.response_format.json_schema.description,
}
if (body.response_format.type === "json_object") return { type: "json" as const }
throw new Error("Unsupported response format")
})(),
seed: body.seed ?? undefined,
tools: tools.tools,
toolChoice: tools.toolChoice,
}
function transformTools() {
const { tools, tool_choice } = body
if (!tools || tools.length === 0) {
return { tools: undefined, toolChoice: undefined }
}
const aiSdkTools = tools.map((tool) => {
return {
type: tool.type,
name: tool.function.name,
description: tool.function.description,
inputSchema: tool.function.parameters!,
}
})
let aiSdkToolChoice
if (tool_choice == null) {
aiSdkToolChoice = undefined
} else if (tool_choice === "auto") {
aiSdkToolChoice = { type: "auto" as const }
} else if (tool_choice === "none") {
aiSdkToolChoice = { type: "none" as const }
} else if (tool_choice === "required") {
aiSdkToolChoice = { type: "required" as const }
} else if (tool_choice.type === "function") {
aiSdkToolChoice = {
type: "tool" as const,
toolName: tool_choice.function.name,
}
}
return { tools: aiSdkTools, toolChoice: aiSdkToolChoice }
}
function transformMessages() {
const { messages } = body
const prompt: LanguageModelV2Prompt = []
for (const message of messages) {
switch (message.role) {
case "system": {
prompt.push({
role: "system",
content: message.content as string,
})
break
}
case "user": {
if (typeof message.content === "string") {
prompt.push({
role: "user",
content: [{ type: "text", text: message.content }],
})
} else {
const content = message.content.map((part) => {
switch (part.type) {
case "text":
return { type: "text" as const, text: part.text }
case "image_url":
return {
type: "file" as const,
mediaType: "image/jpeg" as const,
data: part.image_url.url,
}
default:
throw new Error(`Unsupported content part type: ${(part as any).type}`)
}
})
prompt.push({
role: "user",
content,
})
}
break
}
case "assistant": {
const content: Array<
| { type: "text"; text: string }
| {
type: "tool-call"
toolCallId: string
toolName: string
input: any
}
> = []
if (message.content) {
content.push({
type: "text",
text: message.content as string,
})
}
if (message.tool_calls) {
for (const toolCall of message.tool_calls) {
content.push({
type: "tool-call",
toolCallId: toolCall.id,
toolName: toolCall.function.name,
input: JSON.parse(toolCall.function.arguments),
})
}
}
prompt.push({
role: "assistant",
content,
})
break
}
case "tool": {
prompt.push({
role: "tool",
content: [
{
type: "tool-result",
toolName: "placeholder",
toolCallId: message.tool_call_id,
output: {
type: "text",
value: message.content as string,
},
},
],
})
break
}
default: {
throw new Error(`Unsupported message role: ${message.role}`)
}
}
}
return prompt
}
}
async function trackUsage(model: string, usage: LanguageModelUsage, providerMetadata?: ProviderMetadata) {
const modelData = SUPPORTED_MODELS[model as keyof typeof SUPPORTED_MODELS]
if (!modelData) throw new Error(`Unsupported model: ${model}`)
const inputTokens = usage.inputTokens ?? 0
const outputTokens = usage.outputTokens ?? 0
const reasoningTokens = usage.reasoningTokens ?? 0
const cacheReadTokens = usage.cachedInputTokens ?? 0
const cacheWriteTokens =
providerMetadata?.["anthropic"]?.["cacheCreationInputTokens"] ??
// @ts-expect-error
providerMetadata?.["bedrock"]?.["usage"]?.["cacheWriteInputTokens"] ??
0
const inputCost = modelData.input * inputTokens
const outputCost = modelData.output * outputTokens
const reasoningCost = modelData.reasoning * reasoningTokens
const cacheReadCost = modelData.cacheRead * cacheReadTokens
const cacheWriteCost = modelData.cacheWrite * cacheWriteTokens
const costInCents = (inputCost + outputCost + reasoningCost + cacheReadCost + cacheWriteCost) * 100
await Billing.consume({
model,
inputTokens,
outputTokens,
reasoningTokens,
cacheReadTokens,
cacheWriteTokens,
costInCents,
})
await Database.use((tx) =>
tx
.update(KeyTable)
.set({ timeUsed: sql`now()` })
.where(eq(KeyTable.id, keyRecord.id)),
)
}
} catch (error: any) {
return c.json({ error: { message: error.message } }, 500)
}
})
})
.use("/*", cors())
.use(RestAuth)
.get("/rest/account", async (c) => {
const account = Actor.assert("account")
let workspaces = await Workspace.list()
if (workspaces.length === 0) {
await Workspace.create()
workspaces = await Workspace.list()
}
return c.json({
id: account.properties.accountID,
email: account.properties.email,
workspaces,
})
})
.get("/billing/info", async (c) => {
const billing = await Billing.get()
const payments = await Database.use((tx) =>
tx
.select()
.from(PaymentTable)
.where(eq(PaymentTable.workspaceID, Actor.workspace()))
.orderBy(sql`${PaymentTable.timeCreated} DESC`)
.limit(100),
)
const usage = await Database.use((tx) =>
tx
.select()
.from(UsageTable)
.where(eq(UsageTable.workspaceID, Actor.workspace()))
.orderBy(sql`${UsageTable.timeCreated} DESC`)
.limit(100),
)
return c.json({ billing, payments, usage })
})
.post(
"/billing/checkout",
zValidator(
"json",
z.custom<{
success_url: string
cancel_url: string
}>(),
),
async (c) => {
const account = Actor.assert("user")
const body = await c.req.json()
const customer = await Billing.get()
const session = await Billing.stripe().checkout.sessions.create({
mode: "payment",
line_items: [
{
price_data: {
currency: "usd",
product_data: {
name: "opencode credits",
},
unit_amount: 2000, // $20 minimum
},
quantity: 1,
},
],
payment_intent_data: {
setup_future_usage: "on_session",
},
...(customer.customerID
? { customer: customer.customerID }
: {
customer_email: account.properties.email,
customer_creation: "always",
}),
metadata: {
workspaceID: Actor.workspace(),
},
currency: "usd",
payment_method_types: ["card"],
success_url: body.success_url,
cancel_url: body.cancel_url,
})
return c.json({
url: session.url,
})
},
)
.post("/billing/portal", async (c) => {
const body = await c.req.json()
const customer = await Billing.get()
if (!customer?.customerID) {
throw new Error("No stripe customer ID")
}
const session = await Billing.stripe().billingPortal.sessions.create({
customer: customer.customerID,
return_url: body.return_url,
})
return c.json({
url: session.url,
})
})
.post("/stripe/webhook", async (c) => {
const body = await Billing.stripe().webhooks.constructEventAsync(
await c.req.text(),
c.req.header("stripe-signature")!,
Resource.STRIPE_WEBHOOK_SECRET.value,
)
console.log(body.type, JSON.stringify(body, null, 2))
if (body.type === "checkout.session.completed") {
const workspaceID = body.data.object.metadata?.workspaceID
const customerID = body.data.object.customer as string
const paymentID = body.data.object.payment_intent as string
const amount = body.data.object.amount_total
if (!workspaceID) throw new Error("Workspace ID not found")
if (!customerID) throw new Error("Customer ID not found")
if (!amount) throw new Error("Amount not found")
if (!paymentID) throw new Error("Payment ID not found")
await Actor.provide("system", { workspaceID }, async () => {
const customer = await Billing.get()
if (customer?.customerID && customer.customerID !== customerID) throw new Error("Customer ID mismatch")
// set customer metadata
if (!customer?.customerID) {
await Billing.stripe().customers.update(customerID, {
metadata: {
workspaceID,
},
})
}
// get payment method for the payment intent
const paymentIntent = await Billing.stripe().paymentIntents.retrieve(paymentID, {
expand: ["payment_method"],
})
const paymentMethod = paymentIntent.payment_method
if (!paymentMethod || typeof paymentMethod === "string") throw new Error("Payment method not expanded")
await Database.transaction(async (tx) => {
await tx
.update(BillingTable)
.set({
balance: sql`${BillingTable.balance} + ${centsToMicroCents(amount)}`,
customerID,
paymentMethodID: paymentMethod.id,
paymentMethodLast4: paymentMethod.card!.last4,
})
.where(eq(BillingTable.workspaceID, workspaceID))
await tx.insert(PaymentTable).values({
workspaceID,
id: Identifier.create("payment"),
amount: centsToMicroCents(amount),
paymentID,
customerID,
})
})
})
}
console.log("finished handling")
return c.json("ok", 200)
})
.get("/keys", async (c) => {
const user = Actor.assert("user")
const keys = await Database.use((tx) =>
tx
.select({
id: KeyTable.id,
name: KeyTable.name,
key: KeyTable.key,
userID: KeyTable.userID,
timeCreated: KeyTable.timeCreated,
timeUsed: KeyTable.timeUsed,
})
.from(KeyTable)
.where(eq(KeyTable.workspaceID, user.properties.workspaceID))
.orderBy(sql`${KeyTable.timeCreated} DESC`),
)
return c.json({ keys })
})
.post("/keys", zValidator("json", z.object({ name: z.string().min(1).max(255) })), async (c) => {
const user = Actor.assert("user")
const { name } = c.req.valid("json")
// Generate secret key: sk- + 64 random characters (upper, lower, numbers)
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
let randomPart = ""
for (let i = 0; i < 64; i++) {
randomPart += chars.charAt(Math.floor(Math.random() * chars.length))
}
const secretKey = `sk-${randomPart}`
const keyRecord = await Database.use((tx) =>
tx
.insert(KeyTable)
.values({
id: Identifier.create("key"),
workspaceID: user.properties.workspaceID,
userID: user.properties.userID,
name,
key: secretKey,
timeUsed: null,
})
.returning(),
)
return c.json({
key: secretKey,
id: keyRecord[0].id,
name: keyRecord[0].name,
created: keyRecord[0].timeCreated,
})
})
.delete("/keys/:id", async (c) => {
const user = Actor.assert("user")
const keyId = c.req.param("id")
const result = await Database.use((tx) =>
tx
.delete(KeyTable)
.where(and(eq(KeyTable.id, keyId), eq(KeyTable.workspaceID, user.properties.workspaceID)))
.returning({ id: KeyTable.id }),
)
if (result.length === 0) {
return c.json({ error: "Key not found" }, 404)
}
return c.json({ success: true, id: result[0].id })
})
.all("*", (c) => c.text("Not Found"))
export type ApiType = typeof app
export default app
+92
View File
@@ -0,0 +1,92 @@
/* This file is auto-generated by SST. Do not edit. */
/* tslint:disable */
/* eslint-disable */
/* deno-fmt-ignore-file */
import "sst"
declare module "sst" {
export interface Resource {
"ANTHROPIC_API_KEY": {
"type": "sst.sst.Secret"
"value": string
}
"AUTH_API_URL": {
"type": "sst.sst.Linkable"
"value": string
}
"Console": {
"type": "sst.cloudflare.StaticSite"
"url": string
}
"DATABASE_PASSWORD": {
"type": "sst.sst.Secret"
"value": string
}
"DATABASE_USERNAME": {
"type": "sst.sst.Secret"
"value": string
}
"Database": {
"database": string
"host": string
"password": string
"port": number
"type": "sst.sst.Linkable"
"username": string
}
"GITHUB_APP_ID": {
"type": "sst.sst.Secret"
"value": string
}
"GITHUB_APP_PRIVATE_KEY": {
"type": "sst.sst.Secret"
"value": string
}
"GITHUB_CLIENT_ID_CONSOLE": {
"type": "sst.sst.Secret"
"value": string
}
"GITHUB_CLIENT_SECRET_CONSOLE": {
"type": "sst.sst.Secret"
"value": string
}
"GOOGLE_CLIENT_ID": {
"type": "sst.sst.Secret"
"value": string
}
"OPENAI_API_KEY": {
"type": "sst.sst.Secret"
"value": string
}
"STRIPE_SECRET_KEY": {
"type": "sst.sst.Secret"
"value": string
}
"STRIPE_WEBHOOK_SECRET": {
"type": "sst.sst.Linkable"
"value": string
}
"Web": {
"type": "sst.cloudflare.Astro"
"url": string
}
"ZHIPU_API_KEY": {
"type": "sst.sst.Secret"
"value": string
}
}
}
// cloudflare
import * as cloudflare from "@cloudflare/workers-types";
declare module "sst" {
export interface Resource {
"Api": cloudflare.Service
"AuthApi": cloudflare.Service
"AuthStorage": cloudflare.KVNamespace
"Bucket": cloudflare.R2Bucket
"GatewayApi": cloudflare.Service
}
}
import "sst"
export {}
+9
View File
@@ -0,0 +1,9 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"extends": "@tsconfig/node22/tsconfig.json",
"compilerOptions": {
"module": "ESNext",
"moduleResolution": "bundler",
"types": ["@cloudflare/workers-types", "node"]
}
}
+2
View File
@@ -0,0 +1,2 @@
node_modules
dist
+38
View File
@@ -0,0 +1,38 @@
<!doctype html>
<html lang="en" data-color-mode="dark">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>OpenControl</title>
<link rel="shortcut icon" type="image/ico" href="/favicon.ico" />
<link rel="icon" href="/favicon.ico" sizes="48x48">
<link rel="icon" href="/favicon.svg" media="(prefers-color-scheme: light)">
<link rel="icon" href="/favicon-dark.svg" media="(prefers-color-scheme: dark)">
<link rel="shortcut icon" href="/favicon.svg" type="image/svg+xml">
<meta property="twitter:image" content="%BASE_URL%/social-share.png">
<meta property="og:title" content="OpenControl">
<meta property="og:url" content="%BASE_URL%">
<meta property="og:locale" content="en">
<meta property="og:description" content="Control your infrastructure with AI.">
<meta property="og:site_name" content="OpenControl">
<meta name="twitter:card" content="summary_large_image">
<meta name="description" content="Control your infrastructure with AI.">
<meta property="og:image" content="%BASE_URL%/social-share.png">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600;700&family=Rubik:wght@300..900&display=swap" rel="stylesheet">
<!--ssr-head-->
<!--ssr-assets-->
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root">
<!--ssr-outlet-->
</div>
<script type="module" src="/src/entry-client.tsx"></script>
</body>
</html>
+29
View File
@@ -0,0 +1,29 @@
0 info it worked if it ends with ok
1 verbose cli [
1 verbose cli '/usr/local/bin/node',
1 verbose cli '/Users/frank/Sites/opencode/node_modules/.bin/npm',
1 verbose cli 'run',
1 verbose cli 'dev'
1 verbose cli ]
2 info using npm@2.15.12
3 info using node@v20.18.1
4 verbose stack Error: Invalid name: "@opencode/cloud/web"
4 verbose stack at ensureValidName (/Users/frank/Sites/opencode/node_modules/npm/node_modules/normalize-package-data/lib/fixer.js:336:15)
4 verbose stack at Object.fixNameField (/Users/frank/Sites/opencode/node_modules/npm/node_modules/normalize-package-data/lib/fixer.js:215:5)
4 verbose stack at /Users/frank/Sites/opencode/node_modules/npm/node_modules/normalize-package-data/lib/normalize.js:32:38
4 verbose stack at Array.forEach (<anonymous>)
4 verbose stack at normalize (/Users/frank/Sites/opencode/node_modules/npm/node_modules/normalize-package-data/lib/normalize.js:31:15)
4 verbose stack at final (/Users/frank/Sites/opencode/node_modules/npm/node_modules/read-package-json/read-json.js:349:5)
4 verbose stack at then (/Users/frank/Sites/opencode/node_modules/npm/node_modules/read-package-json/read-json.js:124:5)
4 verbose stack at ReadFileContext.<anonymous> (/Users/frank/Sites/opencode/node_modules/npm/node_modules/read-package-json/read-json.js:295:20)
4 verbose stack at ReadFileContext.callback (/Users/frank/Sites/opencode/node_modules/npm/node_modules/graceful-fs/graceful-fs.js:78:16)
4 verbose stack at FSReqCallback.readFileAfterOpen [as oncomplete] (node:fs:299:13)
5 verbose cwd /Users/frank/Sites/opencode/cloud/web
6 error Darwin 24.5.0
7 error argv "/usr/local/bin/node" "/Users/frank/Sites/opencode/node_modules/.bin/npm" "run" "dev"
8 error node v20.18.1
9 error npm v2.15.12
10 error Invalid name: "@opencode/cloud/web"
11 error If you need help, you may report this error at:
11 error <https://github.com/npm/npm/issues>
12 verbose exit [ 1, true ]
+32
View File
@@ -0,0 +1,32 @@
{
"name": "@opencode/cloud-web",
"version": "0.4.22",
"private": true,
"description": "",
"type": "module",
"scripts": {
"start": "vite",
"dev": "vite",
"build": "bun build:server && bun build:client",
"build:client": "vite build --outDir dist/client",
"build:server": "vite build --ssr src/entry-server.tsx --outDir dist/server",
"serve": "vite preview",
"sst:dev": "bun sst shell --target Console -- bun dev"
},
"license": "MIT",
"devDependencies": {
"typescript": "catalog:",
"vite": "6.2.2",
"vite-plugin-pages": "0.32.5",
"vite-plugin-solid": "2.11.6"
},
"dependencies": {
"@kobalte/core": "0.13.9",
"@openauthjs/solid": "0.0.0-20250322224806",
"@solid-primitives/storage": "4.3.1",
"@solidjs/meta": "0.29.4",
"@solidjs/router": "0.15.3",
"solid-js": "1.9.5",
"solid-list": "0.3.0"
}
}
+3
View File
@@ -0,0 +1,3 @@
<svg width="28" height="32" viewBox="0 0 28 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M14 31.5L0 23.6873V7.81266L14 0L28 7.81266V23.6873L14 31.5ZM14 28.4664L25.3456 22.0251V9.47493L14 2.99209L2.65443 9.47493V22.0251L14 28.4664ZM13.9572 24.6016C12.2732 24.6016 10.7176 24.1999 9.29052 23.3964C7.89195 22.593 6.7788 21.5125 5.95107 20.155C5.12334 18.7698 4.70948 17.2599 4.70948 15.6253C4.70948 13.9908 5.12334 12.4947 5.95107 11.1372C6.7788 9.77968 7.89195 8.69921 9.29052 7.89578C10.7176 7.06464 12.2732 6.64908 13.9572 6.64908C15.6412 6.64908 17.1825 7.06464 18.581 7.89578C19.9796 8.69921 21.0928 9.77968 21.9205 11.1372C22.7768 12.4947 23.2049 13.9908 23.2049 15.6253C23.2049 17.2599 22.791 18.7559 21.9633 20.1135C21.1356 21.471 20.0224 22.5653 18.6239 23.3964C17.2253 24.1999 15.6697 24.6016 13.9572 24.6016ZM13.9572 22.2744C15.213 22.2744 16.3547 21.9697 17.3823 21.3602C18.4098 20.7507 19.2375 19.9472 19.8654 18.9499C20.4934 17.9248 20.8073 16.8166 20.8073 15.6253C20.8073 14.4063 20.4934 13.2982 19.8654 12.3008C19.2375 11.3034 18.4098 10.5 17.3823 9.8905C16.3547 9.281 15.213 8.97625 13.9572 8.97625C12.7299 8.97625 11.5882 9.281 10.5321 9.8905C9.50459 10.5 8.67686 11.3034 8.04893 12.3008C7.421 13.2982 7.10703 14.4063 7.10703 15.6253C7.10703 16.8166 7.421 17.9248 8.04893 18.9499C8.67686 19.9472 9.50459 20.7507 10.5321 21.3602C11.5882 21.9697 12.7299 22.2744 13.9572 22.2744Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 KiB

+3
View File
@@ -0,0 +1,3 @@
<svg width="28" height="32" viewBox="0 0 28 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M14 31.5L0 23.6873V7.81266L14 0L28 7.81266V23.6873L14 31.5ZM14 28.4664L25.3456 22.0251V9.47493L14 2.99209L2.65443 9.47493V22.0251L14 28.4664ZM13.9572 24.6016C12.2732 24.6016 10.7176 24.1999 9.29052 23.3964C7.89195 22.593 6.7788 21.5125 5.95107 20.155C5.12334 18.7698 4.70948 17.2599 4.70948 15.6253C4.70948 13.9908 5.12334 12.4947 5.95107 11.1372C6.7788 9.77968 7.89195 8.69921 9.29052 7.89578C10.7176 7.06464 12.2732 6.64908 13.9572 6.64908C15.6412 6.64908 17.1825 7.06464 18.581 7.89578C19.9796 8.69921 21.0928 9.77968 21.9205 11.1372C22.7768 12.4947 23.2049 13.9908 23.2049 15.6253C23.2049 17.2599 22.791 18.7559 21.9633 20.1135C21.1356 21.471 20.0224 22.5653 18.6239 23.3964C17.2253 24.1999 15.6697 24.6016 13.9572 24.6016ZM13.9572 22.2744C15.213 22.2744 16.3547 21.9697 17.3823 21.3602C18.4098 20.7507 19.2375 19.9472 19.8654 18.9499C20.4934 17.9248 20.8073 16.8166 20.8073 15.6253C20.8073 14.4063 20.4934 13.2982 19.8654 12.3008C19.2375 11.3034 18.4098 10.5 17.3823 9.8905C16.3547 9.281 15.213 8.97625 13.9572 8.97625C12.7299 8.97625 11.5882 9.281 10.5321 9.8905C9.50459 10.5 8.67686 11.3034 8.04893 12.3008C7.421 13.2982 7.10703 14.4063 7.10703 15.6253C7.10703 16.8166 7.421 17.9248 8.04893 18.9499C8.67686 19.9472 9.50459 20.7507 10.5321 21.3602C11.5882 21.9697 12.7299 22.2744 13.9572 22.2744Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

+24
View File
@@ -0,0 +1,24 @@
import fs from "fs"
import path from "path"
import { generateHydrationScript, getAssets } from "solid-js/web"
const dist = import.meta.resolve("../dist").replace("file://", "")
const serverEntry = await import("../dist/server/entry-server.js")
const template = fs.readFileSync(path.join(dist, "client/index.html"), "utf-8")
fs.writeFileSync(path.join(dist, "client/fallback.html"), template)
const routes = ["/", "/foo"]
for (const route of routes) {
const { app } = serverEntry.render({ url: route })
const html = template
.replace("<!--ssr-outlet-->", app)
.replace("<!--ssr-head-->", generateHydrationScript())
.replace("<!--ssr-assets-->", getAssets())
const filePath = dist + `/client${route === "/" ? "/index" : route}.html`
fs.mkdirSync(path.dirname(filePath), {
recursive: true,
})
fs.writeFileSync(filePath, html)
console.log(`Pre-rendered: ${filePath}`)
}
+42
View File
@@ -0,0 +1,42 @@
/// <reference types="vite-plugin-pages/client-solid" />
import { Router } from "@solidjs/router"
import routes from "~solid-pages"
import "./ui/style/index.css"
import { MetaProvider } from "@solidjs/meta"
import { AccountProvider } from "./components/context-account"
import { DialogProvider } from "./ui/context-dialog"
import { DialogString } from "./ui/dialog-string"
import { DialogSelect } from "./ui/dialog-select"
import { ThemeProvider } from "./components/context-theme"
import { Suspense } from "solid-js"
import { OpenAuthProvider } from "./components/context-openauth"
export function App(props: { url?: string }) {
return (
<ThemeProvider>
<Suspense>
<DialogProvider>
<DialogString />
<DialogSelect />
<OpenAuthProvider
clientID="web"
issuer={import.meta.env.VITE_AUTH_URL || "http://dummy"}
>
<AccountProvider>
<MetaProvider>
<Router
children={routes}
url={props.url}
root={(props) => {
return <>{props.children}</>
}}
/>
</MetaProvider>
</AccountProvider>
</OpenAuthProvider>
</DialogProvider>
</Suspense>
</ThemeProvider>
)
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 439 KiB

@@ -0,0 +1,99 @@
import { createContext, createEffect, ParentProps, Suspense, useContext } from "solid-js"
import { makePersisted } from "@solid-primitives/storage"
import { createStore } from "solid-js/store"
import { useOpenAuth } from "./context-openauth"
import { createAsync } from "@solidjs/router"
import { isServer } from "solid-js/web"
type Storage = {
accounts: Record<
string,
{
id: string
email: string
workspaces: {
id: string
name: string
slug: string
}[]
}
>
}
const context = createContext<ReturnType<typeof init>>()
function init() {
const auth = useOpenAuth()
const [store, setStore] = makePersisted(
createStore<Storage>({
accounts: {},
}),
{
name: "opencontrol.account",
},
)
async function refresh(id: string) {
return fetch(import.meta.env.VITE_API_URL + "/rest/account", {
headers: {
authorization: `Bearer ${await auth.access(id)}`,
},
})
.then((val) => val.json())
.then((val) => setStore("accounts", id, val as any))
}
createEffect((previous: string[]) => {
if (Object.keys(auth.all).length === 0) {
return []
}
for (const item of Object.values(auth.all)) {
if (previous.includes(item.id)) continue
refresh(item.id)
}
return Object.keys(auth.all)
}, [] as string[])
const result = {
get all() {
return Object.keys(auth.all)
.map((id) => store.accounts[id])
.filter(Boolean)
},
get current() {
if (!auth.subject) return undefined
return store.accounts[auth.subject.id]
},
refresh,
get ready() {
return Object.keys(auth.all).length === result.all.length
},
}
return result
}
export function AccountProvider(props: ParentProps) {
const ctx = init()
const resource = createAsync(async () => {
await new Promise<void>((resolve) => {
if (isServer) return resolve()
createEffect(() => {
if (ctx.ready) resolve()
})
})
return null
})
return (
<Suspense>
{resource()}
<context.Provider value={ctx}>{props.children}</context.Provider>
</Suspense>
)
}
export function useAccount() {
const result = useContext(context)
if (!result) throw new Error("no account context")
return result
}
@@ -0,0 +1,180 @@
import { createClient } from "@openauthjs/openauth/client"
import { makePersisted } from "@solid-primitives/storage"
import { createAsync } from "@solidjs/router"
import {
batch,
createContext,
createEffect,
createResource,
createSignal,
onMount,
ParentProps,
Show,
Suspense,
useContext,
} from "solid-js"
import { createStore, produce } from "solid-js/store"
import { isServer } from "solid-js/web"
interface Storage {
subjects: Record<string, SubjectInfo>
current?: string
}
interface Context {
all: Record<string, SubjectInfo>
subject?: SubjectInfo
switch(id: string): void
logout(id: string): void
access(id?: string): Promise<string | undefined>
authorize(opts?: AuthorizeOptions): void
}
export interface AuthorizeOptions {
redirectPath?: string
provider?: string
}
interface SubjectInfo {
id: string
refresh: string
}
interface AuthContextOpts {
issuer: string
clientID: string
}
const context = createContext<Context>()
export function OpenAuthProvider(props: ParentProps<AuthContextOpts>) {
const client = createClient({
issuer: props.issuer,
clientID: props.clientID,
})
const [storage, setStorage] = makePersisted(
createStore<Storage>({
subjects: {},
}),
{
name: `${props.issuer}.auth`,
},
)
const resource = createAsync(async () => {
if (isServer) return true
const hash = new URLSearchParams(window.location.search.substring(1))
const code = hash.get("code")
const state = hash.get("state")
if (code && state) {
const oldState = sessionStorage.getItem("openauth.state")
const verifier = sessionStorage.getItem("openauth.verifier")
const redirect = sessionStorage.getItem("openauth.redirect")
if (redirect && verifier && oldState === state) {
const result = await client.exchange(code, redirect, verifier)
if (!result.err) {
const id = result.tokens.refresh.split(":").slice(0, -1).join(":")
batch(() => {
setStorage("subjects", id, {
id: id,
refresh: result.tokens.refresh,
})
setStorage("current", id)
})
}
}
}
return true
})
async function authorize(opts?: AuthorizeOptions) {
const redirect = new URL(window.location.origin + (opts?.redirectPath ?? "/")).toString()
const authorize = await client.authorize(redirect, "code", {
pkce: true,
provider: opts?.provider,
})
sessionStorage.setItem("openauth.state", authorize.challenge.state)
sessionStorage.setItem("openauth.redirect", redirect)
if (authorize.challenge.verifier) sessionStorage.setItem("openauth.verifier", authorize.challenge.verifier)
window.location.href = authorize.url
}
const accessCache = new Map<string, string>()
const pendingRequests = new Map<string, Promise<any>>()
async function access(id: string) {
const pending = pendingRequests.get(id)
if (pending) return pending
const promise = (async () => {
const existing = accessCache.get(id)
const subject = storage.subjects[id]
const access = await client.refresh(subject.refresh, {
access: existing,
})
if (access.err) {
pendingRequests.delete(id)
ctx.logout(id)
return
}
if (access.tokens) {
setStorage("subjects", id, "refresh", access.tokens.refresh)
accessCache.set(id, access.tokens.access)
}
pendingRequests.delete(id)
return access.tokens?.access || existing!
})()
pendingRequests.set(id, promise)
return promise
}
const ctx: Context = {
get all() {
return storage.subjects
},
get subject() {
if (!storage.current) return
return storage.subjects[storage.current!]
},
switch(id: string) {
if (!storage.subjects[id]) return
setStorage("current", id)
},
authorize,
logout(id: string) {
if (!storage.subjects[id]) return
setStorage(
produce((s) => {
delete s.subjects[id]
if (s.current === id) s.current = Object.keys(s.subjects)[0]
}),
)
},
async access(id?: string) {
id = id || storage.current
if (!id) return
return access(id || storage.current!)
},
}
createEffect(() => {
if (!resource()) return
if (storage.current) return
const [first] = Object.keys(storage.subjects)
if (first) {
setStorage("current", first)
return
}
})
return (
<>
{resource()}
<context.Provider value={ctx}>{props.children}</context.Provider>
</>
)
}
export function useOpenAuth() {
const result = useContext(context)
if (!result) throw new Error("no auth context")
return result
}
@@ -0,0 +1,39 @@
import { createStore } from "solid-js/store"
import { makePersisted } from "@solid-primitives/storage"
import { createEffect } from "solid-js"
import { createInitializedContext } from "../util/context"
import { isServer } from "solid-js/web"
interface Storage {
mode: "light" | "dark"
}
export const { provider: ThemeProvider, use: useTheme } =
createInitializedContext("ThemeContext", () => {
const [store, setStore] = makePersisted(
createStore<Storage>({
mode:
!isServer &&
window.matchMedia &&
window.matchMedia("(prefers-color-scheme: dark)").matches
? "dark"
: "light",
}),
{
name: "theme",
},
)
createEffect(() => {
document.documentElement.setAttribute("data-color-mode", store.mode)
})
return {
setMode(mode: Storage["mode"]) {
setStore("mode", mode)
},
get mode() {
return store.mode
},
ready: true,
}
})
+13
View File
@@ -0,0 +1,13 @@
/* @refresh reload */
import { hydrate, render } from "solid-js/web"
import { App } from "./app"
if (import.meta.env.DEV) {
render(() => <App />, document.getElementById("root")!)
}
if (!import.meta.env.DEV) {
if ("_$HY" in window) hydrate(() => <App />, document.getElementById("root")!)
else render(() => <App />, document.getElementById("root")!)
}
+7
View File
@@ -0,0 +1,7 @@
import { renderToStringAsync } from "solid-js/web"
import { App } from "./app"
export async function render(props: { url: string }) {
const app = await renderToStringAsync(() => <App url={props.url} />)
return { app }
}
+11
View File
@@ -0,0 +1,11 @@
import { WorkspaceProvider } from "./components/context-workspace"
import { ParentProps } from "solid-js"
import Layout from "./components/layout"
export default function Index(props: ParentProps) {
return (
<WorkspaceProvider>
<Layout>{props.children}</Layout>
</WorkspaceProvider>
)
}
@@ -0,0 +1,56 @@
.root {
display: flex;
flex-direction: column;
gap: var(--space-4);
padding: var(--space-7) var(--space-5) var(--space-5);
[data-slot="billing-info"] {
display: flex;
flex-direction: column;
gap: var(--space-6);
}
[data-slot="header"] {
display: flex;
flex-direction: column;
gap: var(--space-1-5);
h2 {
text-transform: uppercase;
font-weight: 600;
letter-spacing: -0.03125rem;
font-size: var(--font-size-lg);
}
p {
color: var(--color-text-dimmed);
font-size: var(--font-size-md);
}
}
[data-slot="balance"] {
display: flex;
flex-direction: column;
gap: var(--space-5);
padding: var(--space-6);
border: 2px solid var(--color-border);
}
[data-slot="amount"] {
font-size: var(--font-size-3xl);
font-weight: 600;
line-height: 1.2;
}
@media (min-width: 40rem) {
[data-slot="balance"] {
flex-direction: row;
align-items: center;
justify-content: space-between;
}
[data-slot="amount"] {
margin: 0;
}
}
}
+132
View File
@@ -0,0 +1,132 @@
import { Button } from "../../ui/button"
import { useApi } from "../components/context-api"
import { createEffect, createSignal, createResource, For } from "solid-js"
import { useWorkspace } from "../components/context-workspace"
import style from "./billing.module.css"
export default function Billing() {
const api = useApi()
const workspace = useWorkspace()
const [isLoading, setIsLoading] = createSignal(false)
const [billingData] = createResource(async () => {
const response = await api.billing.info.$get()
return response.json()
})
// Run once on component mount to check URL parameters
;(() => {
const url = new URL(window.location.href)
const result = url.hash
console.log("STRIPE RESULT", result)
if (url.hash === "#success") {
setIsLoading(true)
// Remove the hash from the URL
window.history.replaceState(null, "", window.location.pathname + window.location.search)
}
})()
createEffect((old?: number) => {
if (old && old !== billingData()?.billing?.balance) {
setIsLoading(false)
}
return billingData()?.billing?.balance
})
const handleBuyCredits = async () => {
try {
setIsLoading(true)
const baseUrl = window.location.href
const successUrl = new URL(baseUrl)
successUrl.hash = "success"
const response = await api.billing.checkout
.$post({
json: {
success_url: successUrl.toString(),
cancel_url: baseUrl,
},
})
.then((r) => r.json() as any)
window.location.href = response.url
} catch (error) {
console.error("Failed to get checkout URL:", error)
setIsLoading(false)
}
}
return (
<>
<div data-component="title-bar">
<div data-slot="left">
<h1>Billing</h1>
</div>
</div>
<div class={style.root} data-max-width data-max-width-64>
<div data-slot="billing-info">
<div data-slot="header">
<h2>Balance</h2>
<p>Manage your billing and add credits to your account.</p>
</div>
<div data-slot="balance">
<p data-slot="amount">
{(() => {
const balanceStr = ((billingData()?.billing?.balance ?? 0) / 100000000).toFixed(2)
return `$${balanceStr === "-0.00" ? "0.00" : balanceStr}`
})()}
</p>
<Button color="primary" disabled={isLoading()} onClick={handleBuyCredits}>
{isLoading() ? "Loading..." : "Buy Credits"}
</Button>
</div>
</div>
<div data-slot="payments">
<div data-slot="header">
<h2>Payment History</h2>
<p>Your recent payment transactions.</p>
</div>
<div data-slot="payment-list">
<For each={billingData()?.payments} fallback={<p>No payments found.</p>}>
{(payment) => (
<div data-slot="payment-item">
<span data-slot="payment-id">{payment.id}</span>
{" | "}
<span data-slot="payment-amount">${((payment.amount ?? 0) / 100000000).toFixed(2)}</span>
{" | "}
<span data-slot="payment-date">{new Date(payment.timeCreated).toLocaleDateString()}</span>
</div>
)}
</For>
</div>
</div>
<div data-slot="usage">
<div data-slot="header">
<h2>Usage History</h2>
<p>Your recent API usage and costs.</p>
</div>
<div data-slot="usage-list">
<For each={billingData()?.usage} fallback={<p>No usage found.</p>}>
{(usage) => (
<div data-slot="usage-item">
<span data-slot="usage-model">{usage.model}</span>
{" | "}
<span data-slot="usage-tokens">{usage.inputTokens + usage.outputTokens} tokens</span>
{" | "}
<span data-slot="usage-cost">${((usage.cost ?? 0) / 100000000).toFixed(4)}</span>
{" | "}
<span data-slot="usage-date">{new Date(usage.timeCreated).toLocaleDateString()}</span>
</div>
)}
</For>
</div>
</div>
</div>
</>
)
}
@@ -0,0 +1,11 @@
You are OpenControl, an interactive CLI tool that helps users execute various tasks.
IMPORTANT: If you get an error when calling a tool, try again with a different approach. Be creative, do not give up, try different inputs to the tool. You should chain together multiple tool calls. ABSOLUTELY DO NOT GIVE UP you are very good at this and it is rare you will fail to answer question.
You should be concise, direct, and to the point.
IMPORTANT: You should NOT answer with unnecessary preamble or postamble (such as explaining your code or summarizing your action), unless the user asks you to.
IMPORTANT: You should minimize output tokens as much as possible while maintaining helpfulness, quality, and accuracy. Only address the specific query or task at hand, avoiding tangential information unless absolutely critical for completing the request. If you can answer in 1-3 sentences or a short paragraph, please do.
IMPORTANT: You should NOT answer with unnecessary preamble or postamble (such as explaining your code or summarizing your action), unless the user asks you to.
IMPORTANT: Keep your responses short, since they will be displayed on a command line interface. You MUST answer concisely with fewer than 4 lines (not including tool use or code generation), unless user asks for detail. Answer the user's question directly, without elaboration, explanation, or details. One word answers are best. Avoid introductions, conclusions, and explanations. You MUST avoid text before/after your response, such as "The answer is <answer>.", "Here is the content of the file..." or "Based on the information provided, the answer is..." or "Here is what I will do next...".
@@ -0,0 +1,271 @@
import { createResource } from "solid-js"
import { createStore, produce } from "solid-js/store"
import SYSTEM_PROMPT from "./system.txt?raw"
import type {
LanguageModelV1Prompt,
LanguageModelV1CallOptions,
LanguageModelV1,
} from "ai"
interface Tool {
name: string
description: string
inputSchema: any
}
interface ToolCallerProps {
tool: {
list: () => Promise<Tool[]>
call: (input: { name: string; arguments: any }) => Promise<any>
}
generate: (
prompt: LanguageModelV1CallOptions,
) => Promise<
| { err: "rate" }
| { err: "context" }
| { err: "balance" }
| ({ err: false } & Awaited<ReturnType<LanguageModelV1["doGenerate"]>>)
>
onPromptUpdated?: (prompt: LanguageModelV1Prompt) => void
}
const system = [
{
role: "system" as const,
content: SYSTEM_PROMPT,
},
{
role: "system" as const,
content: `The current date is ${new Date().toDateString()}. Always use this current date when responding to relative date queries.`,
},
]
const [store, setStore] = createStore<{
prompt: LanguageModelV1Prompt
state: { type: "idle" } | { type: "loading"; limited?: boolean }
}>({
prompt: [...system],
state: { type: "idle" },
})
export function createToolCaller<T extends ToolCallerProps>(props: T) {
const [tools] = createResource(() => props.tool.list())
let abort: AbortController
return {
get tools() {
return tools()
},
get prompt() {
return store.prompt
},
get state() {
return store.state
},
clear() {
setStore("prompt", [...system])
},
async chat(input: string) {
if (store.state.type !== "idle") return
abort = new AbortController()
setStore(
produce((s) => {
s.state = {
type: "loading",
limited: false,
}
s.prompt.push({
role: "user",
content: [
{
type: "text",
text: input,
},
],
})
}),
)
props.onPromptUpdated?.(store.prompt)
while (true) {
if (abort.signal.aborted) {
break
}
const response = await props.generate({
inputFormat: "messages",
prompt: store.prompt,
temperature: 0,
seed: 69,
mode: {
type: "regular",
tools: tools()?.map((tool) => ({
type: "function",
name: tool.name,
description: tool.description,
parameters: {
...tool.inputSchema,
},
})),
},
})
if (abort.signal.aborted) continue
if (!response.err) {
setStore("state", {
type: "loading",
})
if (response.text) {
setStore(
produce((s) => {
s.prompt.push({
role: "assistant",
content: [
{
type: "text",
text: response.text || "",
},
],
})
}),
)
props.onPromptUpdated?.(store.prompt)
}
if (response.finishReason === "stop") {
break
}
if (response.finishReason === "tool-calls") {
for (const item of response.toolCalls || []) {
setStore(
produce((s) => {
s.prompt.push({
role: "assistant",
content: [
{
type: "tool-call",
toolName: item.toolName,
args: JSON.parse(item.args),
toolCallId: item.toolCallId,
},
],
})
}),
)
props.onPromptUpdated?.(store.prompt)
const called = await props.tool.call({
name: item.toolName,
arguments: JSON.parse(item.args),
})
setStore(
produce((s) => {
s.prompt.push({
role: "tool",
content: [
{
type: "tool-result",
toolName: item.toolName,
toolCallId: item.toolCallId,
result: called,
},
],
})
}),
)
props.onPromptUpdated?.(store.prompt)
}
}
continue
}
if (response.err === "context") {
setStore(
produce((s) => {
s.prompt.splice(2, 1)
}),
)
props.onPromptUpdated?.(store.prompt)
}
if (response.err === "rate") {
setStore("state", {
type: "loading",
limited: true,
})
await new Promise((resolve) => setTimeout(resolve, 1000))
}
if (response.err === "balance") {
setStore(
produce((s) => {
s.prompt.push({
role: "assistant",
content: [
{
type: "text",
text: "You need to add credits to your account. Please go to Billing and add credits to continue.",
},
],
})
s.state = { type: "idle" }
}),
)
props.onPromptUpdated?.(store.prompt)
break
}
}
setStore("state", { type: "idle" })
},
async cancel() {
abort.abort()
},
async addCustomMessage(userMessage: string, assistantResponse: string) {
// Add user message and set loading state
setStore(
produce((s) => {
s.prompt.push({
role: "user",
content: [
{
type: "text",
text: userMessage,
},
],
})
s.state = {
type: "loading",
limited: false,
}
}),
)
props.onPromptUpdated?.(store.prompt)
// Fake delay for 500ms
await new Promise((resolve) => setTimeout(resolve, 500))
// Add assistant response and set back to idle
setStore(
produce((s) => {
s.prompt.push({
role: "assistant",
content: [
{
type: "text",
text: assistantResponse,
},
],
})
s.state = { type: "idle" }
}),
)
props.onPromptUpdated?.(store.prompt)
},
}
}
@@ -0,0 +1,239 @@
.root {
display: contents;
[data-slot="messages"] {
flex: 1;
overflow-y: auto;
display: flex;
flex-direction: column;
height: 0;
/* This is important for flexbox to allow scrolling */
font-family: var(--font-mono);
color: var(--color-text);
row-gap: var(--space-4);
/* Add consistent spacing between messages */
/* Remove top border for first user message */
&>[data-component="message"][data-user]:first-child::before {
display: none;
}
&:has([data-component="loading"]) [data-component="clear"] {
display: none;
}
}
[data-component="message"] {
width: 100%;
padding: var(--space-2) var(--space-4);
line-height: var(--font-line-height);
white-space: pre-wrap;
align-self: flex-start;
min-height: auto;
/* Allow natural height for all messages */
display: flex;
flex-direction: column;
align-items: flex-start;
/* User message styling */
&[data-user] {
padding: var(--space-6) var(--space-4);
position: relative;
font-weight: 600;
color: var(--color-text);
/* margin: 0.5rem 0; */
}
&[data-user]::before,
&[data-user]::after {
content: "";
position: absolute;
left: var(--space-4);
right: var(--space-4);
height: var(--space-px);
background-color: var(--color-border);
z-index: 1;
/* Ensure borders appear above other content */
}
&[data-user]::before {
top: 0;
}
&[data-user]::after {
bottom: 0;
}
&[data-assistant] {
color: var(--color-text);
}
}
[data-component="tool"] {
display: flex;
width: 100%;
padding: 0 var(--space-4);
margin-left: 0;
flex-direction: column;
opacity: 0.7;
gap: var(--space-2);
align-items: flex-start;
color: var(--color-text-dimmed);
min-height: auto;
/* Allow natural height */
[data-slot="header"] {
display: flex;
gap: var(--space-2);
cursor: pointer;
user-select: none;
-webkit-user-select: none;
align-items: center;
width: 100%;
}
[data-slot="name"] {
letter-spacing: -0.03125rem;
text-transform: uppercase;
font-weight: 500;
font-size: var(--font-size-sm);
}
[data-slot="expand"] {
font-size: var(--font-size-sm);
}
[data-slot="content"] {
padding: 0;
line-height: var(--font-line-height);
font-size: var(--font-size-sm);
white-space: pre-wrap;
display: none;
width: 100%;
}
[data-slot="output"] {
margin-top: var(--space-1);
}
&[data-expanded="true"] [data-slot="content"] {
display: block;
}
&[data-expanded="true"] [data-slot="expand"] {
transform: rotate(45deg);
}
}
[data-component="loading"] {
padding: var(--space-4) var(--space-4) var(--space-8);
height: 1.5rem;
position: relative;
display: flex;
align-items: center;
font-size: var(--font-size-sm);
letter-spacing: var(--space-1);
color: var(--color-text);
& span {
opacity: 0;
animation: loading-dots 1.4s linear infinite;
}
& span:nth-child(2) {
animation-delay: 0.2s;
}
& span:nth-child(3) {
animation-delay: 0.4s;
}
}
[data-component="clear"] {
position: relative;
padding: var(--space-4) var(--space-4);
&::before {
content: "";
position: absolute;
left: var(--space-4);
right: var(--space-4);
top: 0;
height: var(--space-px);
background-color: var(--color-border);
z-index: 1;
}
& [data-component="button"] {
padding-left: 0;
}
}
[data-slot="footer"] {
display: flex;
flex-direction: column;
padding: 0;
border-top: 2px solid var(--color-border);
position: sticky;
bottom: 0;
z-index: 10;
/* Ensure it's above other content */
margin-top: auto;
/* Push to bottom if content is short */
width: 100%;
}
[data-component="chat"] {
display: flex;
padding: var(--space-0-5) 0;
align-items: center;
width: 100%;
height: 100%;
textarea {
--padding-y: var(--space-4);
--line-height: 1.5;
--text-height: calc(var(--line-height) * var(--font-size-lg));
--height: calc(var(--text-height) + var(--padding-y) * 2);
width: 100%;
resize: none;
line-height: var(--line-height);
height: var(--height);
min-height: var(--height);
max-height: calc(5 * var(--text-height) + var(--padding-y) * 2);
padding: var(--padding-y) var(--space-4);
border-radius: 0;
background-color: transparent;
color: var(--color-text);
border: none;
outline: none;
font-size: var(--font-size-lg);
}
textarea::placeholder {
color: var(--color-text-dimmed);
opacity: 0.75;
}
textarea:focus {
outline: 0;
}
& [data-component="button"] {
height: 100%;
}
}
}
@keyframes loading-dots {
0%,
100% {
opacity: 0;
}
40%,
60% {
opacity: 1;
}
}
+18
View File
@@ -0,0 +1,18 @@
import { Button } from "../../ui/button"
import { IconArrowRight } from "../../ui/svg/icons"
import { createSignal, For } from "solid-js"
import { createToolCaller } from "./components/tool"
import { useApi } from "../components/context-api"
import { useWorkspace } from "../components/context-workspace"
import style from "./index.module.css"
export default function Index() {
const api = useApi()
const workspace = useWorkspace()
return (
<div class={style.root}>
<h1>Hello</h1>
</div>
)
}
@@ -0,0 +1,97 @@
.root {
display: flex;
flex-direction: column;
gap: 2rem;
}
.root [data-slot="keys-info"] {
display: flex;
flex-direction: column;
gap: 1rem;
}
.root [data-slot="header"] {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.root [data-slot="header"] h2 {
margin: 0;
font-size: 1.5rem;
font-weight: 600;
}
.root [data-slot="header"] p {
margin: 0;
color: var(--color-text-secondary);
}
.root [data-slot="key-list"] {
display: flex;
flex-direction: column;
gap: 1rem;
}
.root [data-slot="key-item"] {
display: flex;
align-items: center;
justify-content: space-between;
padding: 1rem;
border: 1px solid var(--color-border);
border-radius: 0.5rem;
background: var(--color-background-secondary);
}
.root [data-slot="key-actions"] {
display: flex;
gap: 0.5rem;
}
.root [data-slot="key-info"] {
display: flex;
flex-direction: column;
gap: 0.25rem;
}
.root [data-slot="key-value"] {
font-family: monospace;
font-size: 0.875rem;
color: var(--color-text-primary);
}
.root [data-slot="key-meta"] {
font-size: 0.75rem;
color: var(--color-text-secondary);
}
.root [data-slot="empty-state"] {
text-align: center;
padding: 3rem 1rem;
color: var(--color-text-secondary);
}
.root [data-slot="actions"] {
display: flex;
align-items: center;
justify-content: space-between;
}
.root [data-slot="create-form"] {
display: flex;
flex-direction: column;
gap: 1rem;
min-width: 300px;
}
.root [data-slot="form-actions"] {
display: flex;
gap: 0.5rem;
}
.root [data-slot="key-name"] {
font-weight: 600;
font-size: 1rem;
color: var(--color-text-primary);
margin-bottom: 0.25rem;
}
+151
View File
@@ -0,0 +1,151 @@
import { Button } from "../../ui/button"
import { useApi } from "../components/context-api"
import { createSignal, createResource, For, Show } from "solid-js"
import style from "./keys.module.css"
export default function Keys() {
const api = useApi()
const [isCreating, setIsCreating] = createSignal(false)
const [showCreateForm, setShowCreateForm] = createSignal(false)
const [keyName, setKeyName] = createSignal("")
const [keysData, { refetch }] = createResource(async () => {
const response = await api.keys.$get()
return response.json()
})
const handleCreateKey = async () => {
if (!keyName().trim()) return
try {
setIsCreating(true)
await api.keys.$post({
json: { name: keyName().trim() },
})
refetch()
setKeyName("")
setShowCreateForm(false)
} catch (error) {
console.error("Failed to create API key:", error)
} finally {
setIsCreating(false)
}
}
const handleDeleteKey = async (keyId: string) => {
if (!confirm("Are you sure you want to delete this API key? This action cannot be undone.")) {
return
}
try {
await api.keys[":id"].$delete({
param: { id: keyId },
})
refetch()
} catch (error) {
console.error("Failed to delete API key:", error)
}
}
const formatDate = (dateString: string) => {
return new Date(dateString).toLocaleDateString()
}
const formatKey = (key: string) => {
if (key.length <= 11) return key
return `${key.slice(0, 7)}...${key.slice(-4)}`
}
const copyToClipboard = async (text: string) => {
try {
await navigator.clipboard.writeText(text)
} catch (error) {
console.error("Failed to copy to clipboard:", error)
}
}
return (
<>
<div data-component="title-bar">
<div data-slot="left">
<h1>API Keys</h1>
</div>
</div>
<div class={style.root} data-max-width data-max-width-64>
<div data-slot="keys-info">
<div data-slot="actions">
<div data-slot="header">
<h2>API Keys</h2>
<p>Manage your API keys to access the OpenCode gateway.</p>
</div>
<Show
when={!showCreateForm()}
fallback={
<div data-slot="create-form">
<input
data-component="input"
type="text"
placeholder="Enter key name"
value={keyName()}
onInput={(e) => setKeyName(e.currentTarget.value)}
onKeyPress={(e) => e.key === "Enter" && handleCreateKey()}
/>
<div data-slot="form-actions">
<Button color="primary" disabled={isCreating() || !keyName().trim()} onClick={handleCreateKey}>
{isCreating() ? "Creating..." : "Create"}
</Button>
<Button
color="ghost"
onClick={() => {
setShowCreateForm(false)
setKeyName("")
}}
>
Cancel
</Button>
</div>
</div>
}
>
<Button color="primary" onClick={() => setShowCreateForm(true)}>
Create API Key
</Button>
</Show>
</div>
<div data-slot="key-list">
<For
each={keysData()?.keys}
fallback={
<div data-slot="empty-state">
<p>Create an API key to access opencode gateway</p>
</div>
}
>
{(key) => (
<div data-slot="key-item">
<div data-slot="key-info">
<div data-slot="key-name">{key.name}</div>
<div data-slot="key-value">{formatKey(key.key)}</div>
<div data-slot="key-meta">
Created: {formatDate(key.timeCreated)}
{key.timeUsed && ` • Last used: ${formatDate(key.timeUsed)}`}
</div>
</div>
<div data-slot="key-actions">
<Button color="ghost" onClick={() => copyToClipboard(key.key)} title="Copy API key">
Copy
</Button>
<Button color="ghost" onClick={() => handleDeleteKey(key.id)} title="Delete API key">
Delete
</Button>
</div>
</div>
)}
</For>
</div>
</div>
</div>
</>
)
}
@@ -0,0 +1,24 @@
import { hc } from "hono/client"
import { ApiType } from "@opencode/cloud-function/src/gateway"
import { useWorkspace } from "./context-workspace"
import { useOpenAuth } from "../../components/context-openauth"
export function useApi() {
const workspace = useWorkspace()
const auth = useOpenAuth()
return hc<ApiType>(import.meta.env.VITE_API_URL, {
async fetch(...args: Parameters<typeof fetch>): Promise<Response> {
const [input, init] = args
const request = input instanceof Request ? input : new Request(input, init)
const headers = new Headers(request.headers)
headers.set("authorization", `Bearer ${await auth.access()}`)
headers.set("x-opencode-workspace", workspace.id)
return fetch(
new Request(request, {
...init,
headers,
}),
)
},
})
}
@@ -0,0 +1,38 @@
import { useNavigate, useParams } from "@solidjs/router"
import { createInitializedContext } from "../../util/context"
import { useAccount } from "../../components/context-account"
import { createEffect, createMemo } from "solid-js"
export const { use: useWorkspace, provider: WorkspaceProvider } =
createInitializedContext("WorkspaceProvider", () => {
const params = useParams()
const account = useAccount()
const workspace = createMemo(() =>
account.current?.workspaces.find(
(x) => x.id === params.workspace || x.slug === params.workspace,
),
)
const nav = useNavigate()
createEffect(() => {
if (!workspace()) nav("/")
})
const result = () => workspace()!
result.ready = true
return {
get id() {
return workspace()!.id
},
get slug() {
return workspace()!.slug
},
get name() {
return workspace()!.name
},
get ready() {
return workspace() !== undefined
},
}
})
@@ -0,0 +1,199 @@
.root {
--padding: var(--space-10);
--vertical-padding: var(--space-8);
--heading-font-size: var(--font-size-4xl);
--sidebar-width: 200px;
--mobile-breakpoint: 40rem;
--topbar-height: 60px;
margin: var(--space-4);
border: 2px solid var(--color-border);
height: calc(100vh - var(--space-8));
display: flex;
flex-direction: row;
overflow: hidden;
/* Prevent overall scrolling */
position: relative;
}
[data-component="mobile-top-bar"] {
display: none;
position: fixed;
top: 0;
left: 0;
right: 0;
height: var(--topbar-height);
background: var(--color-background);
border-bottom: 2px solid var(--color-border);
z-index: 20;
align-items: center;
padding: 0 var(--space-4) 0 0;
[data-slot="logo"] {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
div {
text-transform: uppercase;
font-weight: 600;
letter-spacing: -0.03125rem;
}
svg {
height: 28px;
width: auto;
color: var(--color-white);
}
}
[data-slot="toggle"] {
background: transparent;
border: none;
padding: var(--space-4);
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
& svg {
width: 24px;
height: 24px;
color: var(--color-foreground);
}
}
}
[data-component="sidebar"] {
width: var(--sidebar-width);
border-right: 2px solid var(--color-border);
display: flex;
flex-direction: column;
padding: calc(var(--padding) / 2);
overflow-y: auto;
/* Allow scrolling if needed */
position: sticky;
top: 0;
height: 100%;
background-color: var(--color-background);
z-index: 10;
[data-slot="logo"] {
margin-top: 2px;
margin-bottom: var(--space-7);
color: var(--color-white);
& svg {
height: 32px;
width: auto;
}
}
[data-slot="nav"] {
flex: 1;
ul {
list-style-type: none;
padding: 0;
}
li {
margin-bottom: calc(var(--vertical-padding) / 2);
text-transform: uppercase;
font-weight: 500;
}
a {
display: block;
padding: var(--space-2) 0;
}
}
[data-slot="user"] {
[data-component="button"] {
padding-left: 0;
padding-bottom: 0;
height: auto;
}
}
}
.navActiveLink {
cursor: default;
text-decoration: none;
}
[data-slot="main-content"] {
flex: 1;
display: flex;
flex-direction: column;
height: 100%;
/* Full height */
overflow: hidden;
/* Prevent overflow */
position: relative;
/* For positioning footer */
width: 100%;
/* Full width */
}
/* Backdrop for mobile */
[data-component="backdrop"] {
display: none;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
/* background-color: rgba(0, 0, 0, 0.5); */
z-index: 25;
backdrop-filter: blur(2px);
}
/* Mobile styles */
@media (max-width: 40rem) {
.root {
margin: 0;
border: none;
height: 100vh;
}
[data-component="mobile-top-bar"] {
display: flex;
}
[data-component="backdrop"] {
display: block;
}
[data-component="sidebar"] {
position: fixed;
left: -100%;
top: 0;
height: 100vh;
width: 80%;
max-width: 280px;
transition: left 0.3s ease-in-out;
box-shadow: none;
z-index: 30;
padding: var(--space-8);
background-color: var(--color-bg);
&[data-opened="true"] {
left: 0;
box-shadow: 8px 0 0px 0px var(--color-gray-4);
}
}
[data-slot="main-content"] {
padding-top: var(--topbar-height);
/* Add space for the top bar */
overflow-y: auto;
}
/* Hide the logo in the sidebar on mobile since it's in the top bar */
[data-component="sidebar"] [data-slot="logo"] {
display: none;
}
}
+96
View File
@@ -0,0 +1,96 @@
import style from "./layout.module.css"
import { useAccount } from "../../components/context-account"
import { Button } from "../../ui/button"
import { IconLogomark } from "../../ui/svg"
import { IconBars3BottomLeft } from "../../ui/svg/icons"
import { ParentProps, createMemo, createSignal } from "solid-js"
import { A, useLocation } from "@solidjs/router"
import { useOpenAuth } from "../../components/context-openauth"
export default function Layout(props: ParentProps) {
const auth = useOpenAuth()
const account = useAccount()
const [sidebarOpen, setSidebarOpen] = createSignal(false)
const location = useLocation()
const workspaceId = createMemo(() => account.current?.workspaces[0].id)
const pageTitle = createMemo(() => {
const path = location.pathname
if (path.endsWith("/billing")) return "Billing"
if (path.endsWith("/keys")) return "API Keys"
return null
})
function handleLogout() {
auth.logout(auth.subject?.id!)
}
return (
<div class={style.root}>
{/* Mobile top bar */}
<div data-component="mobile-top-bar">
<button data-slot="toggle" onClick={() => setSidebarOpen(!sidebarOpen())}>
<IconBars3BottomLeft />
</button>
<div data-slot="logo">
{pageTitle() ? (
<div>{pageTitle()}</div>
) : (
<A href="/">
<IconLogomark />
</A>
)}
</div>
</div>
{/* Backdrop for mobile sidebar - closes sidebar when clicked */}
{sidebarOpen() && <div data-component="backdrop" onClick={() => setSidebarOpen(false)}></div>}
<div data-component="sidebar" data-opened={sidebarOpen() ? "true" : "false"}>
<div data-slot="logo">
<A href="/">
<IconLogomark />
</A>
</div>
<nav data-slot="nav">
<ul>
<li>
<A end activeClass={style.navActiveLink} href={`/${workspaceId()}`} onClick={() => setSidebarOpen(false)}>
Chat
</A>
</li>
<li>
<A
activeClass={style.navActiveLink}
href={`/${workspaceId()}/billing`}
onClick={() => setSidebarOpen(false)}
>
Billing
</A>
</li>
<li>
<A
activeClass={style.navActiveLink}
href={`/${workspaceId()}/keys`}
onClick={() => setSidebarOpen(false)}
>
API Keys
</A>
</li>
</ul>
</nav>
<div data-slot="user">
<Button color="ghost" onClick={handleLogout} title={account.current?.email || ""}>
Logout
</Button>
</div>
</div>
{/* Main Content */}
<div data-slot="main-content">{props.children}</div>
</div>
)
}
+39
View File
@@ -0,0 +1,39 @@
import { Match, Switch } from "solid-js"
import { useAccount } from "../components/context-account"
import { Navigate } from "@solidjs/router"
import { IconLogo } from "../ui/svg"
import styles from "./lander.module.css"
import { useOpenAuth } from "../components/context-openauth"
export default function Index() {
const auth = useOpenAuth()
const account = useAccount()
return (
<Switch>
<Match when={account.current}>
<Navigate href={`/${account.current!.workspaces[0].id}`} />
</Match>
<Match when={!account.current}>
<div class={styles.lander}>
<div data-slot="hero">
<section data-slot="top">
<div data-slot="logo">
<IconLogo />
</div>
<h1>opencode Gateway Console</h1>
</section>
<section data-slot="cta">
<div>
<span onClick={() => auth.authorize({ provider: "github" })}>Sign in with GitHub</span>
</div>
<div>
<span onClick={() => auth.authorize({ provider: "google" })}>Sign in with Google</span>
</div>
</section>
</div>
</div>
</Match>
</Switch>
)
}
+83
View File
@@ -0,0 +1,83 @@
.lander {
--padding: 3rem;
--vertical-padding: 2rem;
--heading-font-size: 2rem;
margin: 1rem;
@media (max-width: 30rem) {
& {
--padding: 1.5rem;
--vertical-padding: 1rem;
--heading-font-size: 1.5rem;
margin: 0.5rem;
}
}
[data-slot="hero"] {
border: 2px solid var(--color-border);
max-width: 64rem;
margin-left: auto;
margin-right: auto;
width: 100%;
}
[data-slot="top"] {
padding: var(--padding);
h1 {
margin-top: calc(var(--vertical-padding) / 8);
font-size: var(--heading-font-size);
line-height: 1.25;
text-transform: uppercase;
font-weight: 600;
}
[data-slot="logo"] {
width: clamp(200px, 70vw, 400px);
color: var(--color-white);
}
}
[data-slot="cta"] {
display: flex;
flex-direction: row;
justify-content: space-between;
border-top: 2px solid var(--color-border);
& > div {
flex: 1;
line-height: 1.4;
text-align: center;
text-transform: uppercase;
cursor: pointer;
text-decoration: underline;
letter-spacing: -0.03125rem;
&[data-slot="col-2"] {
background-color: var(--color-border);
color: var(--color-text-invert);
font-weight: 600;
}
& > * {
display: block;
width: 100%;
height: 100%;
padding: calc(var(--padding) / 2) 0.5rem;
}
}
@media (max-width: 30rem) {
& > div {
padding-bottom: calc(var(--padding) / 2 + 4px);
}
}
& > div + div {
border-left: 2px solid var(--color-border);
}
}
}
+204
View File
@@ -0,0 +1,204 @@
.pageContainer {
padding: 2rem;
max-width: 1200px;
margin: 0 auto;
}
.componentTable {
width: 100%;
border-collapse: collapse;
table-layout: fixed;
border: 2px solid var(--color-border);
}
.componentCell {
padding: 1rem;
border: 2px solid var(--color-border);
vertical-align: top;
}
.componentLabel {
text-transform: uppercase;
letter-spacing: -0.03125rem;
font-size: 0.85rem;
font-weight: 500;
margin-bottom: 0.75rem;
color: var(--color-text-dimmed);
}
.sectionTitle {
margin-bottom: 1rem;
text-transform: uppercase;
letter-spacing: -0.03125rem;
font-size: 1.2rem;
}
.divider {
height: 2px;
background: var(--color-border);
margin: 3rem 0;
width: 100%;
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 2rem;
}
.buttonSection {
margin-bottom: 4rem;
}
.colorSection {
margin-bottom: 4rem;
}
.labelSection {
margin-bottom: 4rem;
}
.inputSection {
margin-bottom: 4rem;
}
.dialogSection {
margin-bottom: 4rem;
}
.formGroup {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.dialogContent {
padding: 2rem;
}
.dialogContentFooter {
margin-top: 1rem;
}
.pageTitle {
font-size: var(--heading-font-size, 2rem);
text-transform: uppercase;
font-weight: 600;
}
.colorBox {
width: 100%;
height: 80px;
margin-bottom: 0.5rem;
position: relative;
display: flex;
align-items: flex-end;
justify-content: center;
padding-bottom: 0.5rem;
}
.colorOrange {
background-color: var(--color-orange);
}
.colorOrangeLow {
background-color: var(--color-orange-low);
}
.colorOrangeHigh {
background-color: var(--color-orange-high);
}
.colorGreen {
background-color: var(--color-green);
}
.colorGreenLow {
background-color: var(--color-green-low);
}
.colorGreenHigh {
background-color: var(--color-green-high);
}
.colorBlue {
background-color: var(--color-blue);
}
.colorBlueLow {
background-color: var(--color-blue-low);
}
.colorBlueHigh {
background-color: var(--color-blue-high);
}
.colorPurple {
background-color: var(--color-purple);
}
.colorPurpleLow {
background-color: var(--color-purple-low);
}
.colorPurpleHigh {
background-color: var(--color-purple-high);
}
.colorRed {
background-color: var(--color-red);
}
.colorRedLow {
background-color: var(--color-red-low);
}
.colorRedHigh {
background-color: var(--color-red-high);
}
.colorAccent {
background-color: var(--color-accent);
}
.colorAccentLow {
background-color: var(--color-accent-low);
}
.colorAccentHigh {
background-color: var(--color-accent-high);
}
.colorCode {
background-color: rgba(0, 0, 0, 0.5);
color: white;
padding: 4px 8px;
border-radius: 4px;
font-size: 0.8rem;
font-family: monospace;
}
.colorVariants {
display: flex;
gap: 0.5rem;
}
.colorVariant {
flex: 1;
height: 40px;
position: relative;
display: flex;
align-items: center;
justify-content: center;
}
.colorVariantCode {
background-color: rgba(0, 0, 0, 0.5);
color: white;
padding: 2px 4px;
border-radius: 4px;
font-size: 0.65rem;
font-family: monospace;
white-space: nowrap;
}
+562
View File
@@ -0,0 +1,562 @@
import { Button } from "../../ui/button"
import { Dialog } from "../../ui/dialog"
import { Navigate } from "@solidjs/router"
import { createSignal, Show } from "solid-js"
import { IconHome, IconPencilSquare } from "../../ui/svg/icons"
import { useTheme } from "../../components/context-theme"
import { useDialog } from "../../ui/context-dialog"
import { DialogString } from "../../ui/dialog-string"
import { DialogSelect } from "../../ui/dialog-select"
import styles from "./design.module.css"
export default function DesignSystem() {
const dialog = useDialog()
const [dialogOpen, setDialogOpen] = createSignal(false)
const [dialogOpenTransition, setDialogOpenTransition] = createSignal(false)
const theme = useTheme()
// Check if we're running locally
const isLocal = import.meta.env.DEV === true
if (!isLocal) {
return <Navigate href="/" />
}
// Add a toggle button for theme
const toggleTheme = () => {
theme.setMode(theme.mode === "light" ? "dark" : "light")
}
return (
<div class={styles.pageContainer}>
<div class={styles.header}>
<h1 class={styles.pageTitle}>Design System</h1>
<Button onClick={toggleTheme}>
Toggle {theme.mode === "light" ? "Dark" : "Light"} Mode
</Button>
</div>
<section class={styles.colorSection}>
<h2 class={styles.sectionTitle}>Colors</h2>
<table class={styles.componentTable}>
<tbody>
<tr>
<td class={styles.componentCell}>
<h3 class={styles.componentLabel}>Orange</h3>
<div class={`${styles.colorBox} ${styles.colorOrange}`}>
<span class={styles.colorCode}>hsl(41, 82%, 63%)</span>
</div>
<div class={styles.colorVariants}>
<div
class={`${styles.colorVariant} ${styles.colorOrangeLow}`}
>
<span class={styles.colorVariantCode}>
hsl(41, 39%, 22%)
</span>
</div>
<div
class={`${styles.colorVariant} ${styles.colorOrangeHigh}`}
>
<span class={styles.colorVariantCode}>
hsl(41, 82%, 87%)
</span>
</div>
</div>
</td>
<td class={styles.componentCell}>
<h3 class={styles.componentLabel}>Green</h3>
<div class={`${styles.colorBox} ${styles.colorGreen}`}>
<span class={styles.colorCode}>hsl(101, 82%, 63%)</span>
</div>
<div class={styles.colorVariants}>
<div class={`${styles.colorVariant} ${styles.colorGreenLow}`}>
<span class={styles.colorVariantCode}>
hsl(101, 39%, 22%)
</span>
</div>
<div
class={`${styles.colorVariant} ${styles.colorGreenHigh}`}
>
<span class={styles.colorVariantCode}>
hsl(101, 82%, 80%)
</span>
</div>
</div>
</td>
<td class={styles.componentCell}>
<h3 class={styles.componentLabel}>Blue</h3>
<div class={`${styles.colorBox} ${styles.colorBlue}`}>
<span class={styles.colorCode}>hsl(234, 100%, 60%)</span>
</div>
<div class={styles.colorVariants}>
<div class={`${styles.colorVariant} ${styles.colorBlueLow}`}>
<span class={styles.colorVariantCode}>
hsl(234, 54%, 20%)
</span>
</div>
<div class={`${styles.colorVariant} ${styles.colorBlueHigh}`}>
<span class={styles.colorVariantCode}>
hsl(234, 100%, 87%)
</span>
</div>
</div>
</td>
</tr>
<tr>
<td class={styles.componentCell}>
<h3 class={styles.componentLabel}>Purple</h3>
<div class={`${styles.colorBox} ${styles.colorPurple}`}>
<span class={styles.colorCode}>hsl(281, 82%, 63%)</span>
</div>
<div class={styles.colorVariants}>
<div
class={`${styles.colorVariant} ${styles.colorPurpleLow}`}
>
<span class={styles.colorVariantCode}>
hsl(281, 39%, 22%)
</span>
</div>
<div
class={`${styles.colorVariant} ${styles.colorPurpleHigh}`}
>
<span class={styles.colorVariantCode}>
hsl(281, 82%, 89%)
</span>
</div>
</div>
</td>
<td class={styles.componentCell}>
<h3 class={styles.componentLabel}>Red</h3>
<div class={`${styles.colorBox} ${styles.colorRed}`}>
<span class={styles.colorCode}>hsl(339, 82%, 63%)</span>
</div>
<div class={styles.colorVariants}>
<div class={`${styles.colorVariant} ${styles.colorRedLow}`}>
<span class={styles.colorVariantCode}>
hsl(339, 39%, 22%)
</span>
</div>
<div class={`${styles.colorVariant} ${styles.colorRedHigh}`}>
<span class={styles.colorVariantCode}>
hsl(339, 82%, 87%)
</span>
</div>
</div>
</td>
<td class={styles.componentCell}>
<h3 class={styles.componentLabel}>Accent</h3>
<div class={`${styles.colorBox} ${styles.colorAccent}`}>
<span class={styles.colorCode}>hsl(13, 88%, 57%)</span>
</div>
<div class={styles.colorVariants}>
<div
class={`${styles.colorVariant} ${styles.colorAccentLow}`}
>
<span class={styles.colorVariantCode}>
hsl(13, 75%, 30%)
</span>
</div>
<div
class={`${styles.colorVariant} ${styles.colorAccentHigh}`}
>
<span class={styles.colorVariantCode}>
hsl(13, 100%, 78%)
</span>
</div>
</div>
</td>
</tr>
</tbody>
</table>
</section>
<div class={styles.divider}></div>
<section class={styles.buttonSection}>
<h2 class={styles.sectionTitle}>Buttons</h2>
<table class={styles.componentTable}>
<tbody>
<tr>
<td class={styles.componentCell}>
<h3 class={styles.componentLabel}>Primary</h3>
<Button>Primary Button</Button>
</td>
<td class={styles.componentCell}>
<h3 class={styles.componentLabel}>Secondary</h3>
<Button color="secondary">Secondary Button</Button>
</td>
<td class={styles.componentCell}>
<h3 class={styles.componentLabel}>Ghost</h3>
<Button color="ghost">Ghost Button</Button>
</td>
</tr>
<tr>
<td class={styles.componentCell}>
<h3 class={styles.componentLabel}>Primary Disabled</h3>
<Button disabled>Primary Button</Button>
</td>
<td class={styles.componentCell}>
<h3 class={styles.componentLabel}>Secondary Disabled</h3>
<Button color="secondary" disabled>
Secondary Button
</Button>
</td>
<td class={styles.componentCell}>
<h3 class={styles.componentLabel}>Ghost Disabled</h3>
<Button color="ghost" disabled>
Ghost Button
</Button>
</td>
</tr>
<tr>
<td class={styles.componentCell}>
<h3 class={styles.componentLabel}>Small</h3>
<Button size="sm">Small Button</Button>
</td>
<td class={styles.componentCell}>
<h3 class={styles.componentLabel}>Small Secondary</h3>
<Button size="sm" color="secondary">
Small Secondary
</Button>
</td>
<td class={styles.componentCell}>
<h3 class={styles.componentLabel}>Small Ghost</h3>
<Button size="sm" color="ghost">
Small Ghost
</Button>
</td>
</tr>
<tr>
<td class={styles.componentCell}>
<h3 class={styles.componentLabel}>With Icon</h3>
<Button icon={<IconHome />}>With Icon</Button>
</td>
<td class={styles.componentCell}>
<h3 class={styles.componentLabel}>Icon + Secondary</h3>
<Button icon={<IconHome />} color="secondary">
Icon Secondary
</Button>
</td>
<td class={styles.componentCell}>
<h3 class={styles.componentLabel}>Icon + Ghost</h3>
<Button icon={<IconHome />} color="ghost">
Icon Ghost
</Button>
</td>
</tr>
<tr>
<td class={styles.componentCell}>
<h3 class={styles.componentLabel}>Small + Icon</h3>
<Button size="sm" icon={<IconHome />}>
Small Icon
</Button>
</td>
<td class={styles.componentCell}>
<h3 class={styles.componentLabel}>Small + Icon + Secondary</h3>
<Button size="sm" icon={<IconHome />} color="secondary">
Small Icon Secondary
</Button>
</td>
<td class={styles.componentCell}>
<h3 class={styles.componentLabel}>Small + Icon + Ghost</h3>
<Button size="sm" icon={<IconHome />} color="ghost">
Small Icon Ghost
</Button>
</td>
</tr>
<tr>
<td class={styles.componentCell}>
<h3 class={styles.componentLabel}>Icon Only</h3>
<Button icon={<IconHome />}></Button>
</td>
<td class={styles.componentCell}>
<h3 class={styles.componentLabel}>Icon Only + Secondary</h3>
<Button icon={<IconHome />} color="secondary"></Button>
</td>
<td class={styles.componentCell}>
<h3 class={styles.componentLabel}>Icon Only + Ghost</h3>
<Button icon={<IconHome />} color="ghost"></Button>
</td>
</tr>
<tr>
<td class={styles.componentCell}>
<h3 class={styles.componentLabel}>Icon Only Disabled</h3>
<Button icon={<IconHome />} disabled></Button>
</td>
<td class={styles.componentCell}>
<h3 class={styles.componentLabel}>
Icon Only + Secondary Disabled
</h3>
<Button icon={<IconHome />} color="secondary" disabled></Button>
</td>
<td class={styles.componentCell}>
<h3 class={styles.componentLabel}>
Icon Only + Ghost Disabled
</h3>
<Button icon={<IconHome />} color="ghost" disabled></Button>
</td>
</tr>
<tr>
<td class={styles.componentCell}>
<h3 class={styles.componentLabel}>Small Icon Only</h3>
<Button size="sm" icon={<IconHome />}></Button>
</td>
<td class={styles.componentCell}>
<h3 class={styles.componentLabel}>
Small Icon Only + Secondary
</h3>
<Button
size="sm"
icon={<IconHome />}
color="secondary"
></Button>
</td>
<td class={styles.componentCell}>
<h3 class={styles.componentLabel}>Small Icon Only + Ghost</h3>
<Button size="sm" icon={<IconHome />} color="ghost"></Button>
</td>
</tr>
</tbody>
</table>
</section>
<div class={styles.divider}></div>
<section class={styles.labelSection}>
<h2 class={styles.sectionTitle}>Labels</h2>
<table class={styles.componentTable}>
<tbody>
<tr>
<td class={styles.componentCell}>
<h3 class={styles.componentLabel}>Small</h3>
<label data-size="sm" data-component="label">
Small Label Text
</label>
</td>
<td class={styles.componentCell}>
<h3 class={styles.componentLabel}>Medium</h3>
<label data-size="md" data-component="label">
Medium Label Text
</label>
</td>
<td class={styles.componentCell}>
<h3 class={styles.componentLabel}>Large</h3>
<label data-size="lg" data-component="label">
Large Label Text
</label>
</td>
</tr>
</tbody>
</table>
</section>
<div class={styles.divider}></div>
<section class={styles.inputSection}>
<h2 class={styles.sectionTitle}>Inputs</h2>
<table class={styles.componentTable}>
<tbody>
<tr>
<td class={styles.componentCell}>
<h3 class={styles.componentLabel}>Small</h3>
<input
data-component="input"
data-size="sm"
placeholder="Small input field"
/>
</td>
<td class={styles.componentCell}>
<h3 class={styles.componentLabel}>Medium</h3>
<input
data-component="input"
data-size="md"
placeholder="Medium input field"
/>
</td>
<td class={styles.componentCell}>
<h3 class={styles.componentLabel}>Large</h3>
<input
data-component="input"
data-size="lg"
placeholder="Large input field"
/>
</td>
</tr>
<tr>
<td class={styles.componentCell}>
<h3 class={styles.componentLabel}>Disabled</h3>
<input
data-component="input"
data-size="md"
placeholder="Disabled input"
disabled
/>
</td>
<td class={styles.componentCell}>
<h3 class={styles.componentLabel}>With Value</h3>
<input
data-component="input"
data-size="md"
value="Input with preset value"
readOnly
/>
</td>
</tr>
</tbody>
</table>
</section>
<div class={styles.divider}></div>
<section class={styles.dialogSection}>
<h2 class={styles.sectionTitle}>Dialogs</h2>
<table class={styles.componentTable}>
<tbody>
<tr>
<td class={styles.componentCell}>
<h3 class={styles.componentLabel}>Default</h3>
<Button color="secondary" onClick={() => setDialogOpen(true)}>
Open Dialog
</Button>
<Dialog open={dialogOpen()} onOpenChange={setDialogOpen}>
<div data-slot="header">
<div data-slot="title">Dialog Title</div>
</div>
<div data-slot="main">
<p>This is the default dialog content.</p>
</div>
<div data-slot="footer">
<Button onClick={() => setDialogOpen(false)}>Close</Button>
</div>
</Dialog>
</td>
<td class={styles.componentCell}>
<h3 class={styles.componentLabel}>Small With Transition</h3>
<Button
color="secondary"
onClick={() => {
setDialogOpenTransition(true)
}}
>
Small Dialog
</Button>
<Dialog
open={dialogOpenTransition()}
onOpenChange={setDialogOpenTransition}
size="sm"
transition={true}
>
<div class={styles.dialogContent}>
<h2 class={styles.sectionTitle}>Small Dialog</h2>
<p>This is a smaller dialog with transitions.</p>
<div class={styles.dialogContentFooter}>
<Button onClick={() => setDialogOpenTransition(false)}>
Close
</Button>
</div>
</div>
</Dialog>
</td>
<td class={styles.componentCell}>
<h3 class={styles.componentLabel}>Input String</h3>
<Button
color="secondary"
onClick={() =>
dialog.open(DialogString, {
title: "Name",
action: "Change name",
placeholder: "Enter a name",
onSubmit: () => {},
})
}
>
String
</Button>
</td>
</tr>
<tr>
<td class={styles.componentCell}>
<h3 class={styles.componentLabel}>Select Input</h3>
<Button
color="secondary"
onClick={() =>
dialog.open(DialogSelect, {
placeholder: "Select",
title: "User Settings",
options: [
{
display: "Change name",
prefix: <IconPencilSquare />,
onSelect: () => {
dialog.close()
},
},
{
display: "Remove user",
prefix: <IconHome />,
onSelect: () => {
dialog.close()
},
},
],
})
}
>
Select
</Button>
</td>
<td class={styles.componentCell}>
<h3 class={styles.componentLabel}>Select Input</h3>
<Button
color="secondary"
onClick={() =>
dialog.open(DialogSelect, {
placeholder: "Select",
title: "User Settings",
options: [
{
display: "Change name",
onSelect: () => {
dialog.close()
},
},
{
display: "Remove user",
onSelect: () => {
dialog.close()
},
},
],
})
}
>
No Prefix
</Button>
</td>
<td class={styles.componentCell}>
<h3 class={styles.componentLabel}>Select No Options</h3>
<Button
color="secondary"
onClick={() =>
dialog.open(DialogSelect, {
placeholder: "Select",
title: "User Settings",
options: [],
})
}
>
No Options
</Button>
</td>
</tr>
</tbody>
</table>
</section>
</div>
)
}
+12
View File
@@ -0,0 +1,12 @@
/* This file is auto-generated by SST. Do not edit. */
/* tslint:disable */
/* eslint-disable */
/// <reference types="vite/client" />
interface ImportMetaEnv {
readonly VITE_DOCS_URL: string
readonly VITE_API_URL: string
readonly VITE_AUTH_URL: string
}
interface ImportMeta {
readonly env: ImportMetaEnv
}
+24
View File
@@ -0,0 +1,24 @@
import { Button as Kobalte } from "@kobalte/core/button"
import { JSX, Show, splitProps } from "solid-js"
export interface ButtonProps {
color?: "primary" | "secondary" | "ghost"
size?: "md" | "sm"
icon?: JSX.Element
}
export function Button(props: JSX.IntrinsicElements["button"] & ButtonProps) {
const [split, rest] = splitProps(props, ["color", "size", "icon"])
return (
<Kobalte
{...rest}
data-component="button"
data-size={split.size || "md"}
data-color={split.color || "primary"}
>
<Show when={props.icon}>
<div data-slot="icon">{props.icon}</div>
</Show>
{props.children}
</Kobalte>
)
}
+120
View File
@@ -0,0 +1,120 @@
import { createContext, JSX, ParentProps, useContext } from "solid-js"
import { StandardSchemaV1 } from "@standard-schema/spec"
import { createStore } from "solid-js/store"
import { Dialog } from "./dialog"
const Context = createContext<DialogControl>()
type DialogControl = {
open<Schema extends StandardSchemaV1<object>>(
component: DialogComponent<Schema>,
input: StandardSchemaV1.InferInput<Schema>,
): void
close(): void
isOpen(input: any): boolean
size: "sm" | "md"
transition?: boolean
input?: any
}
type DialogProps<Schema extends StandardSchemaV1<object>> = {
input: StandardSchemaV1.InferInput<Schema>
control: DialogControl
}
type DialogComponent<Schema extends StandardSchemaV1<object>> = ReturnType<
typeof createDialog<Schema>
>
export function createDialog<Schema extends StandardSchemaV1<object>>(props: {
schema: Schema
size: "sm" | "md"
render: (props: DialogProps<Schema>) => JSX.Element
}) {
const result = () => {
const dialog = useDialog()
return (
<Dialog
size={dialog.size}
transition={dialog.transition}
open={dialog.isOpen(result)}
onOpenChange={(val) => {
if (!val) dialog.close()
}}
>
{props.render({
input: dialog.input,
control: dialog,
})}
</Dialog>
)
}
result.schema = props.schema
result.size = props.size
return result
}
export function DialogProvider(props: ParentProps) {
const [store, setStore] = createStore<{
dialog?: DialogComponent<any>
input?: any
transition?: boolean
size: "sm" | "md"
}>({
size: "sm",
})
const control: DialogControl = {
get input() {
return store.input
},
get size() {
return store.size
},
get transition() {
return store.transition
},
isOpen(input) {
return store.dialog === input
},
open(component, input) {
setStore({
dialog: component,
input: input,
size: store.dialog !== undefined ? store.size : component.size,
transition: store.dialog !== undefined,
})
setTimeout(() => {
setStore({
size: component.size,
})
}, 0)
setTimeout(() => {
setStore({
transition: false,
})
}, 150)
},
close() {
setStore({
dialog: undefined,
})
},
}
return (
<>
<Context.Provider value={control}>{props.children}</Context.Provider>
</>
)
}
export function useDialog() {
const ctx = useContext(Context)
if (!ctx) {
throw new Error("useDialog must be used within a DialogProvider")
}
return ctx
}
+36
View File
@@ -0,0 +1,36 @@
.options {
margin-top: var(--space-1);
border-top: 2px solid var(--color-border);
padding: var(--space-2);
[data-slot="option"] {
outline: none;
flex-shrink: 0;
height: var(--space-11);
display: flex;
justify-content: start;
align-items: center;
padding: 0 var(--space-2-5);
gap: var(--space-3);
cursor: pointer;
&[data-empty] {
cursor: default;
color: var(--color-text-dimmed);
}
&[data-active] {
background-color: var(--color-bg-surface);
}
[data-slot="title"] {
font-size: var(--font-size-md);
}
[data-slot="prefix"] {
width: var(--space-4);
height: var(--space-4);
}
}
}
+124
View File
@@ -0,0 +1,124 @@
import style from "./dialog-select.module.css"
import { z } from "zod"
import { createMemo, createSignal, For, JSX, onMount } from "solid-js"
import { createList } from "solid-list"
import { createDialog } from "./context-dialog"
export const DialogSelect = createDialog({
size: "md",
schema: z.object({
title: z.string(),
placeholder: z.string(),
onSelect: z
.function(z.tuple([z.any()]))
.returns(z.void())
.optional(),
options: z.array(
z.object({
display: z.string(),
value: z.any().optional(),
onSelect: z.function().returns(z.void()).optional(),
prefix: z.custom<JSX.Element>().optional(),
}),
),
}),
render: (ctx) => {
let input: HTMLInputElement
onMount(() => {
input.focus()
input.value = ""
})
const [filter, setFilter] = createSignal("")
const filtered = createMemo(() =>
ctx.input.options?.filter((i) =>
i.display.toLowerCase().includes(filter().toLowerCase()),
),
)
const list = createList({
loop: true,
initialActive: 0,
items: () => filtered().map((_, i) => i),
handleTab: false,
})
const handleSelection = (index: number) => {
const option = ctx.input.options[index]
// If the option has its own onSelect handler, use it
if (option.onSelect) {
option.onSelect()
}
// Otherwise, if there's a global onSelect handler, call it with the option's value
else if (ctx.input.onSelect) {
ctx.input.onSelect(
option.value !== undefined ? option.value : option.display,
)
}
}
return (
<>
<div data-slot="header">
<label
data-size="md"
data-slot="title"
data-component="label"
for={`dialog-select-${ctx.input.title}`}
>
{ctx.input.title}
</label>
</div>
<div data-slot="main">
<input
data-size="lg"
data-component="input"
value={filter()}
onInput={(e) => {
setFilter(e.target.value)
list.setActive(0)
}}
onKeyDown={(e) => {
if (e.key === "Enter") {
const selected = list.active()
if (selected === null) return
handleSelection(selected)
return
}
if (e.key === "Escape") {
setFilter("")
return
}
list.onKeyDown(e)
}}
id={`dialog-select-${ctx.input.title}`}
ref={(r) => (input = r)}
data-slot="input"
placeholder={ctx.input.placeholder}
/>
</div>
<div data-slot="options" class={style.options}>
<For
each={filtered()}
fallback={
<div data-slot="option" data-empty>
No results
</div>
}
>
{(option, index) => (
<div
onClick={() => handleSelection(index())}
data-slot="option"
data-active={list.active() === index() ? true : undefined}
>
{option.prefix && <div data-slot="prefix">{option.prefix}</div>}
<div data-slot="title">{option.display}</div>
</div>
)}
</For>
</div>
</>
)
},
})
+70
View File
@@ -0,0 +1,70 @@
import { z } from "zod"
import { onMount } from "solid-js"
import { createDialog } from "./context-dialog"
import { Button } from "./button"
export const DialogString = createDialog({
size: "sm",
schema: z.object({
title: z.string(),
placeholder: z.string(),
action: z.string(),
onSubmit: z.function().args(z.string()).returns(z.void()),
}),
render: (ctx) => {
let input: HTMLInputElement
onMount(() => {
setTimeout(() => {
input.focus()
input.value = ""
}, 50)
})
function submit() {
const value = input.value.trim()
if (value) {
ctx.input.onSubmit(value)
ctx.control.close()
}
}
return (
<>
<div data-slot="header">
<label
data-size="md"
data-slot="title"
data-component="label"
for={`dialog-string-${ctx.input.title}`}
>
{ctx.input.title}
</label>
</div>
<div data-slot="main">
<input
data-slot="input"
data-size="lg"
data-component="input"
ref={(r) => (input = r)}
placeholder={ctx.input.placeholder}
id={`dialog-string-${ctx.input.title}`}
onKeyDown={(e) => {
if (e.key === "Enter") {
e.preventDefault()
submit()
}
}}
/>
</div>
<div data-slot="footer">
<Button size="md" color="ghost" onClick={() => ctx.control.close()}>
Cancel
</Button>
<Button size="md" color="secondary" onClick={submit}>
{ctx.input.action}
</Button>
</div>
</>
)
},
})
+27
View File
@@ -0,0 +1,27 @@
import { Dialog as Kobalte } from "@kobalte/core/dialog"
import { ComponentProps, ParentProps } from "solid-js"
export type Props = ParentProps<{
size?: "sm" | "md"
transition?: boolean
}> &
ComponentProps<typeof Kobalte>
export function Dialog(props: Props) {
return (
<Kobalte {...props}>
<Kobalte.Portal>
<Kobalte.Overlay data-component="dialog-overlay" />
<div data-component="dialog-center">
<Kobalte.Content
data-transition={props.transition ? "" : undefined}
data-size={props.size}
data-slot="content"
>
{props.children}
</Kobalte.Content>
</div>
</Kobalte.Portal>
</Kobalte>
)
}
@@ -0,0 +1,78 @@
[data-component="button"] {
width: fit-content;
display: flex;
line-height: 1;
align-items: center;
justify-content: center;
gap: var(--space-2);
font-size: var(--font-size-md);
text-transform: uppercase;
height: var(--space-11);
outline: none;
font-weight: 500;
padding: 0 var(--space-4);
border-width: 2px;
border-color: var(--color-border);
cursor: pointer;
&:disabled {
opacity: 0.5;
cursor: default;
}
&[data-color="primary"] {
background-color: var(--color-text);
border-color: var(--color-text);
color: var(--color-text-invert);
&:active {
border-color: var(--color-accent);
}
}
&[data-color="secondary"] {
&:active {
border-color: var(--color-accent);
}
}
&[data-color="ghost"] {
border: none;
text-decoration: underline;
&:active {
color: var(--color-text-accent);
}
}
&:has([data-slot="icon"]) {
padding-left: var(--space-3);
padding-right: var(--space-3);
}
&[data-size="sm"] {
height: var(--space-8);
padding: var(--space-3);
font-size: var(--font-size-xs);
[data-slot="icon"] {
width: var(--space-3-5);
height: var(--space-3-5);
}
&:has([data-slot="icon"]) {
padding-left: var(--space-2);
padding-right: var(--space-2);
}
}
[data-slot="icon"] {
width: var(--space-4);
height: var(--space-4);
transition: transform 0.2s ease;
}
&[data-rotate] [data-slot="icon"] {
transform: rotate(180deg);
}
}
@@ -0,0 +1,84 @@
[data-component="dialog-overlay"] {
pointer-events: none !important;
position: fixed;
inset: 0;
animation-name: fadeOut;
animation-duration: 200ms;
animation-timing-function: ease;
opacity: 0;
backdrop-filter: blur(2px);
&[data-expanded] {
animation-name: fadeIn;
opacity: 1;
pointer-events: auto !important;
}
}
[data-component="dialog-center"] {
position: fixed;
inset: 0;
padding-top: 10vh;
justify-content: center;
pointer-events: none;
[data-slot="content"] {
width: 45rem;
margin: 0 auto;
transition: 150ms width;
background-color: var(--color-bg);
border-width: 2px;
border-color: var(--color-border);
overflow: hidden;
display: flex;
flex-direction: column;
gap: var(--space-3);
outline: none;
animation-duration: 1ms;
animation-name: zoomOut;
animation-timing-function: ease;
box-shadow: 8px 8px 0px 0px var(--color-gray-4);
&[data-expanded] {
animation-name: zoomIn;
}
&[data-transition] {
animation-duration: 200ms;
}
&[data-size="sm"] {
width: 30rem;
}
[data-slot="header"] {
display: flex;
padding: var(--space-4) var(--space-4) 0;
[data-slot="title"] {
}
}
[data-slot="main"] {
padding: 0 var(--space-4);
&:has([data-slot="options"]) {
padding: 0;
display: flex;
flex-direction: column;
gap: var(--space-4);
}
}
[data-slot="input"] {
}
[data-slot="footer"] {
padding: var(--space-4);
display: flex;
gap: var(--space-4);
justify-content: end;
}
}
}
@@ -0,0 +1,34 @@
[data-component="input"] {
font-size: var(--font-size-md);
background: transparent;
caret-color: var(--color-accent);
font-family: var(--font-mono);
height: var(--space-11);
padding: 0 var(--space-4);
width: 100%;
resize: none;
border: 2px solid var(--color-border);
&::placeholder {
color: var(--color-text-dimmed);
opacity: 0.75;
}
&:focus {
outline: 0;
}
&[data-size="sm"] {
height: var(--space-9);
padding: 0 var(--space-3);
font-size: var(--font-size-xs);
}
&[data-size="md"] {
}
&[data-size="lg"] {
height: var(--space-12);
font-size: var(--font-size-lg);
}
}
@@ -0,0 +1,17 @@
[data-component="label"] {
letter-spacing: -0.03125rem;
text-transform: uppercase;
color: var(--color-text-dimmed);
font-weight: 500;
font-size: var(--font-size-md);
&[data-size="sm"] {
font-size: var(--font-size-sm);
}
&[data-size="md"] {
}
&[data-size="lg"] {
font-size: var(--font-size-lg);
}
}
@@ -0,0 +1,32 @@
[data-component="title-bar"] {
display: flex;
align-items: center;
justify-content: space-between;
height: 72px;
padding: 0 var(--space-4);
border-bottom: 2px solid var(--color-border);
[data-slot="left"] {
display: flex;
flex-direction: column;
gap: var(--space-1-5);
h1 {
letter-spacing: -0.03125rem;
font-size: var(--font-size-xl);
text-transform: uppercase;
font-weight: 600;
}
p {
color: var(--color-text-dimmed);
}
}
}
@media (max-width: 40rem) {
[data-component="title-bar"] {
display: none;
}
}
+50
View File
@@ -0,0 +1,50 @@
/* tokens */
@import "./token/color.css";
@import "./token/reset.css";
@import "./token/animation.css";
@import "./token/font.css";
@import "./token/space.css";
/* components */
@import "./component/label.css";
@import "./component/input.css";
@import "./component/button.css";
@import "./component/dialog.css";
@import "./component/title-bar.css";
body {
font-family: var(--font-mono);
line-height: 1;
color: var(--color-text);
background-color: var(--color-bg);
cursor: default;
user-select: none;
text-underline-offset: 0.1875rem;
}
a {
text-decoration: underline;
&:active {
color: var(--color-text-accent);
}
}
::selection {
background-color: var(--color-text-accent-invert);
}
/* Responsive utilities */
[data-max-width] {
width: 100%;
& > * {
max-width: 90rem;
margin-left: auto;
margin-right: auto;
width: 100%;
}
&[data-max-width-64] > * {
max-width: 64rem;
}
}
@@ -0,0 +1,23 @@
@keyframes zoomIn {
from {
opacity: 0;
transform: scale(0.95);
}
to {
opacity: 1;
transform: scale(1);
}
}
@keyframes zoomOut {
from {
opacity: 1;
transform: scale(1);
}
to {
opacity: 0;
transform: scale(0.95);
}
}
+88
View File
@@ -0,0 +1,88 @@
:root {
--color-white: hsl(0, 0%, 100%);
--color-gray-1: hsl(224, 20%, 94%);
--color-gray-2: hsl(224, 6%, 77%);
--color-gray-3: hsl(224, 6%, 56%);
--color-gray-4: hsl(224, 7%, 36%);
--color-gray-5: hsl(224, 10%, 23%);
--color-gray-6: hsl(224, 14%, 16%);
--color-black: hsl(224, 10%, 10%);
--hue-orange: 41;
--color-orange-low: hsl(var(--hue-orange), 39%, 22%);
--color-orange: hsl(var(--hue-orange), 82%, 63%);
--color-orange-high: hsl(var(--hue-orange), 82%, 87%);
--hue-green: 101;
--color-green-low: hsl(var(--hue-green), 39%, 22%);
--color-green: hsl(var(--hue-green), 82%, 63%);
--color-green-high: hsl(var(--hue-green), 82%, 80%);
--hue-blue: 234;
--color-blue-low: hsl(var(--hue-blue), 54%, 20%);
--color-blue: hsl(var(--hue-blue), 100%, 60%);
--color-blue-high: hsl(var(--hue-blue), 100%, 87%);
--hue-purple: 281;
--color-purple-low: hsl(var(--hue-purple), 39%, 22%);
--color-purple: hsl(var(--hue-purple), 82%, 63%);
--color-purple-high: hsl(var(--hue-purple), 82%, 89%);
--hue-red: 339;
--color-red-low: hsl(var(--hue-red), 39%, 22%);
--color-red: hsl(var(--hue-red), 82%, 63%);
--color-red-high: hsl(var(--hue-red), 82%, 87%);
--color-accent-low: hsl(13, 75%, 30%);
--color-accent: hsl(13, 88%, 57%);
--color-accent-high: hsl(13, 100%, 78%);
--color-text: var(--color-gray-1);
--color-text-dimmed: var(--color-gray-3);
--color-text-accent: var(--color-accent);
--color-text-invert: var(--color-black);
--color-text-accent-invert: var(--color-accent-high);
--color-bg: var(--color-black);
--color-bg-surface: var(--color-gray-5);
--color-bg-accent: var(--color-accent-high);
--color-border: var(--color-gray-2);
--color-backdrop-overlay: hsla(223, 13%, 10%, 0.66);
}
:root[data-color-mode="light"] {
--color-white: hsl(224, 10%, 10%);
--color-gray-1: hsl(224, 14%, 16%);
--color-gray-2: hsl(224, 10%, 23%);
--color-gray-3: hsl(224, 7%, 36%);
--color-gray-4: hsl(224, 6%, 56%);
--color-gray-5: hsl(224, 6%, 77%);
--color-gray-6: hsl(224, 20%, 94%);
--color-gray-7: hsl(224, 19%, 97%);
--color-black: hsl(0, 0%, 100%);
--color-orange-high: hsl(var(--hue-orange), 80%, 25%);
--color-orange: hsl(var(--hue-orange), 90%, 60%);
--color-orange-low: hsl(var(--hue-orange), 90%, 88%);
--color-green-high: hsl(var(--hue-green), 80%, 22%);
--color-green: hsl(var(--hue-green), 90%, 46%);
--color-green-low: hsl(var(--hue-green), 85%, 90%);
--color-blue-high: hsl(var(--hue-blue), 80%, 30%);
--color-blue: hsl(var(--hue-blue), 90%, 60%);
--color-blue-low: hsl(var(--hue-blue), 88%, 90%);
--color-purple-high: hsl(var(--hue-purple), 90%, 30%);
--color-purple: hsl(var(--hue-purple), 90%, 60%);
--color-purple-low: hsl(var(--hue-purple), 80%, 90%);
--color-red-high: hsl(var(--hue-red), 80%, 30%);
--color-red: hsl(var(--hue-red), 90%, 60%);
--color-red-low: hsl(var(--hue-red), 80%, 90%);
--color-accent-high: hsl(13, 75%, 26%);
--color-accent: hsl(13, 88%, 60%);
--color-accent-low: hsl(13, 100%, 89%);
--color-text-accent: var(--color-accent);
--color-text-dimmed: var(--color-gray-4);
--color-text-invert: var(--color-black);
--color-text-accent-invert: var(--color-accent-low);
--color-bg-surface: var(--color-gray-6);
--color-bg-accent: var(--color-accent);
--color-backdrop-overlay: hsla(225, 9%, 36%, 0.66);
}

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