Compare commits

..

10 Commits

Author SHA1 Message Date
opencode cf05e6e02b release: v1.0.156 2025-12-15 19:28:02 +00:00
Adam 7e49d0fb15 fix: connect provider on homepage 2025-12-15 13:24:30 -06:00
Adam c4f63824df fix: terminal in desktop 2025-12-15 13:09:13 -06:00
Adam 4236744fb5 fix: image attachments in desktop 2025-12-15 12:01:11 -06:00
Github Action 284c045795 Update Nix flake.lock and hashes 2025-12-15 16:57:28 +00:00
Dax Raad 2c53abd70c docs: update header navigation to include desktop download 2025-12-15 11:56:53 -05:00
Adam b7a9cbfc68 fix: share page 2025-12-15 10:56:07 -06:00
Dax Raad 46a35dfc1b docs: restore desktop beta banner to homepage 2025-12-15 11:54:09 -05:00
GitHub Action b7597c12dd chore: format code 2025-12-15 16:52:45 +00:00
Nalin Singh 6830590183 feat: add F# language server support (#5549) 2025-12-15 10:52:16 -06:00
44 changed files with 275 additions and 165 deletions
+32 -30
View File
@@ -20,7 +20,7 @@
},
"packages/console/app": {
"name": "@opencode-ai/console-app",
"version": "1.0.155",
"version": "1.0.156",
"dependencies": {
"@cloudflare/vite-plugin": "1.15.2",
"@ibm/plex": "6.4.1",
@@ -48,7 +48,7 @@
},
"packages/console/core": {
"name": "@opencode-ai/console-core",
"version": "1.0.155",
"version": "1.0.156",
"dependencies": {
"@aws-sdk/client-sts": "3.782.0",
"@jsx-email/render": "1.1.1",
@@ -75,7 +75,7 @@
},
"packages/console/function": {
"name": "@opencode-ai/console-function",
"version": "1.0.155",
"version": "1.0.156",
"dependencies": {
"@ai-sdk/anthropic": "2.0.0",
"@ai-sdk/openai": "2.0.2",
@@ -99,7 +99,7 @@
},
"packages/console/mail": {
"name": "@opencode-ai/console-mail",
"version": "1.0.155",
"version": "1.0.156",
"dependencies": {
"@jsx-email/all": "2.2.3",
"@jsx-email/cli": "1.4.3",
@@ -123,7 +123,7 @@
},
"packages/desktop": {
"name": "@opencode-ai/desktop",
"version": "1.0.155",
"version": "1.0.156",
"dependencies": {
"@kobalte/core": "catalog:",
"@opencode-ai/sdk": "workspace:*",
@@ -170,11 +170,11 @@
},
"packages/enterprise": {
"name": "@opencode-ai/enterprise",
"version": "1.0.155",
"version": "1.0.156",
"dependencies": {
"@opencode-ai/ui": "workspace:*",
"@opencode-ai/util": "workspace:*",
"@pierre/precision-diffs": "catalog:",
"@pierre/diffs": "catalog:",
"@solidjs/meta": "catalog:",
"@solidjs/router": "catalog:",
"@solidjs/start": "catalog:",
@@ -199,7 +199,7 @@
},
"packages/function": {
"name": "@opencode-ai/function",
"version": "1.0.155",
"version": "1.0.156",
"dependencies": {
"@octokit/auth-app": "8.0.1",
"@octokit/rest": "22.0.0",
@@ -215,7 +215,7 @@
},
"packages/opencode": {
"name": "opencode",
"version": "1.0.155",
"version": "1.0.156",
"bin": {
"opencode": "./bin/opencode",
},
@@ -248,7 +248,7 @@
"@opentui/core": "0.0.0-20251211-4403a69a",
"@opentui/solid": "0.0.0-20251211-4403a69a",
"@parcel/watcher": "2.5.1",
"@pierre/precision-diffs": "catalog:",
"@pierre/diffs": "catalog:",
"@solid-primitives/event-bus": "1.1.2",
"@standard-schema/spec": "1.0.0",
"@zip.js/zip.js": "2.7.62",
@@ -307,7 +307,7 @@
},
"packages/plugin": {
"name": "@opencode-ai/plugin",
"version": "1.0.155",
"version": "1.0.156",
"dependencies": {
"@opencode-ai/sdk": "workspace:*",
"zod": "catalog:",
@@ -327,7 +327,7 @@
},
"packages/sdk/js": {
"name": "@opencode-ai/sdk",
"version": "1.0.155",
"version": "1.0.156",
"devDependencies": {
"@hey-api/openapi-ts": "0.88.1",
"@tsconfig/node22": "catalog:",
@@ -338,7 +338,7 @@
},
"packages/slack": {
"name": "@opencode-ai/slack",
"version": "1.0.155",
"version": "1.0.156",
"dependencies": {
"@opencode-ai/sdk": "workspace:*",
"@slack/bolt": "^3.17.1",
@@ -351,7 +351,7 @@
},
"packages/tauri": {
"name": "@opencode-ai/tauri",
"version": "1.0.155",
"version": "1.0.156",
"dependencies": {
"@opencode-ai/desktop": "workspace:*",
"@tauri-apps/api": "^2",
@@ -376,12 +376,12 @@
},
"packages/ui": {
"name": "@opencode-ai/ui",
"version": "1.0.155",
"version": "1.0.156",
"dependencies": {
"@kobalte/core": "catalog:",
"@opencode-ai/sdk": "workspace:*",
"@opencode-ai/util": "workspace:*",
"@pierre/precision-diffs": "catalog:",
"@pierre/diffs": "catalog:",
"@shikijs/transformers": "3.9.2",
"@solid-primitives/bounds": "0.1.3",
"@solid-primitives/resize-observer": "2.1.3",
@@ -411,7 +411,7 @@
},
"packages/util": {
"name": "@opencode-ai/util",
"version": "1.0.155",
"version": "1.0.156",
"dependencies": {
"zod": "catalog:",
},
@@ -422,7 +422,7 @@
},
"packages/web": {
"name": "@opencode-ai/web",
"version": "1.0.155",
"version": "1.0.156",
"dependencies": {
"@astrojs/cloudflare": "12.6.3",
"@astrojs/markdown-remark": "6.3.1",
@@ -471,7 +471,7 @@
"@hono/zod-validator": "0.4.2",
"@kobalte/core": "0.13.11",
"@openauthjs/openauth": "0.0.0-20250322224806",
"@pierre/precision-diffs": "0.6.1",
"@pierre/diffs": "1.0.0-beta.3",
"@solidjs/meta": "0.29.4",
"@solidjs/router": "0.15.4",
"@solidjs/start": "https://pkg.pr.new/@solidjs/start@dfb2020",
@@ -1286,7 +1286,7 @@
"@petamoriken/float16": ["@petamoriken/float16@3.9.3", "", {}, "sha512-8awtpHXCx/bNpFt4mt2xdkgtgVvKqty8VbjHI/WWWQuEw+KLzFot3f4+LkQY9YmOtq7A5GdOnqoIC8Pdygjk2g=="],
"@pierre/precision-diffs": ["@pierre/precision-diffs@0.6.1", "", { "dependencies": { "@shikijs/core": "3.15.0", "@shikijs/transformers": "3.15.0", "diff": "8.0.2", "fast-deep-equal": "3.1.3", "hast-util-to-html": "9.0.5", "lru_map": "0.4.1", "shiki": "3.15.0" }, "peerDependencies": { "react": "^18.3.1 || ^19.0.0", "react-dom": "^18.3.1 || ^19.0.0" } }, "sha512-HXafRSOly6B0rRt6fuP0yy1MimHJMQ2NNnBGcIHhHwsgK4WWs+SBWRWt1usdgz0NIuSgXdIyQn8HY3F1jKyDBQ=="],
"@pierre/diffs": ["@pierre/diffs@1.0.0-beta.3", "", { "dependencies": { "@shikijs/core": "3.19.0", "@shikijs/engine-javascript": "3.19.0", "@shikijs/transformers": "3.19.0", "diff": "8.0.2", "hast-util-to-html": "9.0.5", "lru_map": "0.4.1", "shiki": "3.19.0" }, "peerDependencies": { "react": "^18.3.1 || ^19.0.0", "react-dom": "^18.3.1 || ^19.0.0" } }, "sha512-W3dFWdFOBZ9OskGSOgN16aci8dsUyAavCxz3ZvbbVLTb2qRzMZ7H90qdfON13/N2l1HTyh84lkrCs1/sDvnRjQ=="],
"@pkgjs/parseargs": ["@pkgjs/parseargs@0.11.0", "", {}, "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg=="],
@@ -4112,11 +4112,13 @@
"@parcel/watcher/node-addon-api": ["node-addon-api@7.1.1", "", {}, "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ=="],
"@pierre/precision-diffs/@shikijs/core": ["@shikijs/core@3.15.0", "", { "dependencies": { "@shikijs/types": "3.15.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-8TOG6yG557q+fMsSVa8nkEDOZNTSxjbbR8l6lF2gyr6Np+jrPlslqDxQkN6rMXCECQ3isNPZAGszAfYoJOPGlg=="],
"@pierre/diffs/@shikijs/core": ["@shikijs/core@3.19.0", "", { "dependencies": { "@shikijs/types": "3.19.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-L7SrRibU7ZoYi1/TrZsJOFAnnHyLTE1SwHG1yNWjZIVCqjOEmCSuK2ZO9thnRbJG6TOkPp+Z963JmpCNw5nzvA=="],
"@pierre/precision-diffs/@shikijs/transformers": ["@shikijs/transformers@3.15.0", "", { "dependencies": { "@shikijs/core": "3.15.0", "@shikijs/types": "3.15.0" } }, "sha512-Hmwip5ovvSkg+Kc41JTvSHHVfCYF+C8Cp1omb5AJj4Xvd+y9IXz2rKJwmFRGsuN0vpHxywcXJ1+Y4B9S7EG1/A=="],
"@pierre/diffs/@shikijs/engine-javascript": ["@shikijs/engine-javascript@3.19.0", "", { "dependencies": { "@shikijs/types": "3.19.0", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^4.3.4" } }, "sha512-ZfWJNm2VMhKkQIKT9qXbs76RRcT0SF/CAvEz0+RkpUDAoDaCx0uFdCGzSRiD9gSlhm6AHkjdieOBJMaO2eC1rQ=="],
"@pierre/precision-diffs/shiki": ["shiki@3.15.0", "", { "dependencies": { "@shikijs/core": "3.15.0", "@shikijs/engine-javascript": "3.15.0", "@shikijs/engine-oniguruma": "3.15.0", "@shikijs/langs": "3.15.0", "@shikijs/themes": "3.15.0", "@shikijs/types": "3.15.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-kLdkY6iV3dYbtPwS9KXU7mjfmDm25f5m0IPNFnaXO7TBPcvbUOY72PYXSuSqDzwp+vlH/d7MXpHlKO/x+QoLXw=="],
"@pierre/diffs/@shikijs/transformers": ["@shikijs/transformers@3.19.0", "", { "dependencies": { "@shikijs/core": "3.19.0", "@shikijs/types": "3.19.0" } }, "sha512-e6vwrsyw+wx4OkcrDbL+FVCxwx8jgKiCoXzakVur++mIWVcgpzIi8vxf4/b4dVTYrV/nUx5RjinMf4tq8YV8Fw=="],
"@pierre/diffs/shiki": ["shiki@3.19.0", "", { "dependencies": { "@shikijs/core": "3.19.0", "@shikijs/engine-javascript": "3.19.0", "@shikijs/engine-oniguruma": "3.19.0", "@shikijs/langs": "3.19.0", "@shikijs/themes": "3.19.0", "@shikijs/types": "3.19.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-77VJr3OR/VUZzPiStyRhADmO2jApMM0V2b1qf0RpfWya8Zr1PeZev5AEpPGAAKWdiYUtcZGBE4F5QvJml1PvWA=="],
"@poppinss/dumper/supports-color": ["supports-color@10.2.2", "", {}, "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g=="],
@@ -4670,19 +4672,19 @@
"@opentui/solid/@babel/core/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
"@pierre/precision-diffs/@shikijs/core/@shikijs/types": ["@shikijs/types@3.15.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-BnP+y/EQnhihgHy4oIAN+6FFtmfTekwOLsQbRw9hOKwqgNy8Bdsjq8B05oAt/ZgvIWWFrshV71ytOrlPfYjIJw=="],
"@pierre/diffs/@shikijs/core/@shikijs/types": ["@shikijs/types@3.19.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-Z2hdeEQlzuntf/BZpFG8a+Fsw9UVXdML7w0o3TgSXV3yNESGon+bs9ITkQb3Ki7zxoXOOu5oJWqZ2uto06V9iQ=="],
"@pierre/precision-diffs/@shikijs/transformers/@shikijs/types": ["@shikijs/types@3.15.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-BnP+y/EQnhihgHy4oIAN+6FFtmfTekwOLsQbRw9hOKwqgNy8Bdsjq8B05oAt/ZgvIWWFrshV71ytOrlPfYjIJw=="],
"@pierre/diffs/@shikijs/engine-javascript/@shikijs/types": ["@shikijs/types@3.19.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-Z2hdeEQlzuntf/BZpFG8a+Fsw9UVXdML7w0o3TgSXV3yNESGon+bs9ITkQb3Ki7zxoXOOu5oJWqZ2uto06V9iQ=="],
"@pierre/precision-diffs/shiki/@shikijs/engine-javascript": ["@shikijs/engine-javascript@3.15.0", "", { "dependencies": { "@shikijs/types": "3.15.0", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^4.3.3" } }, "sha512-ZedbOFpopibdLmvTz2sJPJgns8Xvyabe2QbmqMTz07kt1pTzfEvKZc5IqPVO/XFiEbbNyaOpjPBkkr1vlwS+qg=="],
"@pierre/diffs/@shikijs/transformers/@shikijs/types": ["@shikijs/types@3.19.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-Z2hdeEQlzuntf/BZpFG8a+Fsw9UVXdML7w0o3TgSXV3yNESGon+bs9ITkQb3Ki7zxoXOOu5oJWqZ2uto06V9iQ=="],
"@pierre/precision-diffs/shiki/@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@3.15.0", "", { "dependencies": { "@shikijs/types": "3.15.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "sha512-HnqFsV11skAHvOArMZdLBZZApRSYS4LSztk2K3016Y9VCyZISnlYUYsL2hzlS7tPqKHvNqmI5JSUJZprXloMvA=="],
"@pierre/diffs/shiki/@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@3.19.0", "", { "dependencies": { "@shikijs/types": "3.19.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "sha512-1hRxtYIJfJSZeM5ivbUXv9hcJP3PWRo5prG/V2sWwiubUKTa+7P62d2qxCW8jiVFX4pgRHhnHNp+qeR7Xl+6kg=="],
"@pierre/precision-diffs/shiki/@shikijs/langs": ["@shikijs/langs@3.15.0", "", { "dependencies": { "@shikijs/types": "3.15.0" } }, "sha512-WpRvEFvkVvO65uKYW4Rzxs+IG0gToyM8SARQMtGGsH4GDMNZrr60qdggXrFOsdfOVssG/QQGEl3FnJ3EZ+8w8A=="],
"@pierre/diffs/shiki/@shikijs/langs": ["@shikijs/langs@3.19.0", "", { "dependencies": { "@shikijs/types": "3.19.0" } }, "sha512-dBMFzzg1QiXqCVQ5ONc0z2ebyoi5BKz+MtfByLm0o5/nbUu3Iz8uaTCa5uzGiscQKm7lVShfZHU1+OG3t5hgwg=="],
"@pierre/precision-diffs/shiki/@shikijs/themes": ["@shikijs/themes@3.15.0", "", { "dependencies": { "@shikijs/types": "3.15.0" } }, "sha512-8ow2zWb1IDvCKjYb0KiLNrK4offFdkfNVPXb1OZykpLCzRU6j+efkY+Y7VQjNlNFXonSw+4AOdGYtmqykDbRiQ=="],
"@pierre/diffs/shiki/@shikijs/themes": ["@shikijs/themes@3.19.0", "", { "dependencies": { "@shikijs/types": "3.19.0" } }, "sha512-H36qw+oh91Y0s6OlFfdSuQ0Ld+5CgB/VE6gNPK+Hk4VRbVG/XQgkjnt4KzfnnoO6tZPtKJKHPjwebOCfjd6F8A=="],
"@pierre/precision-diffs/shiki/@shikijs/types": ["@shikijs/types@3.15.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-BnP+y/EQnhihgHy4oIAN+6FFtmfTekwOLsQbRw9hOKwqgNy8Bdsjq8B05oAt/ZgvIWWFrshV71ytOrlPfYjIJw=="],
"@pierre/diffs/shiki/@shikijs/types": ["@shikijs/types@3.19.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-Z2hdeEQlzuntf/BZpFG8a+Fsw9UVXdML7w0o3TgSXV3yNESGon+bs9ITkQb3Ki7zxoXOOu5oJWqZ2uto06V9iQ=="],
"@slack/web-api/form-data/mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="],
Generated
+3 -3
View File
@@ -2,11 +2,11 @@
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1765644376,
"narHash": "sha256-yqHBL2wYGwjGL2GUF2w3tofWl8qO9tZEuI4wSqbCrtE=",
"lastModified": 1765772535,
"narHash": "sha256-aq+dQoaPONOSjtFIBnAXseDm9TUhIbe215TPmkfMYww=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "23735a82a828372c4ef92c660864e82fbe2f5fbe",
"rev": "09b8fda8959d761445f12b55f380d90375a1d6bb",
"type": "github"
},
"original": {
+1 -1
View File
@@ -1,3 +1,3 @@
{
"nodeModules": "sha256-lgPsYtNJT7a+mDk5cTiEJLlBnTMTjxZCl8bw5WxcuaM="
"nodeModules": "sha256-PyoVOza+3WnwZbtpPF6uSN1zkyLsSG2VsgBfIMvIFAs="
}
+1 -1
View File
@@ -30,7 +30,7 @@
"@tsconfig/bun": "1.0.9",
"@cloudflare/workers-types": "4.20251008.0",
"@openauthjs/openauth": "0.0.0-20250322224806",
"@pierre/precision-diffs": "0.6.1",
"@pierre/diffs": "1.0.0-beta.3",
"@tailwindcss/vite": "4.1.11",
"diff": "8.0.2",
"ai": "5.0.97",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@opencode-ai/console-app",
"version": "1.0.155",
"version": "1.0.156",
"type": "module",
"scripts": {
"typecheck": "tsgo --noEmit",
@@ -169,6 +169,25 @@ export function Header(props: { zen?: boolean; hideGetStarted?: boolean }) {
</Match>
</Switch>
</li>
<Show when={!props.hideGetStarted}>
{" "}
<li>
{" "}
<A href="/download" data-slot="cta-button">
{" "}
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
{" "}
<path
d="M12.1875 9.75L9.00001 12.9375L5.8125 9.75M9.00001 2.0625L9 12.375M14.4375 15.9375H3.5625"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="square"
/>{" "}
</svg>{" "}
Free{" "}
</A>{" "}
</li>
</Show>
</ul>
</nav>
<nav data-component="nav-mobile">
+15
View File
@@ -52,6 +52,21 @@ export default function Home() {
<div data-component="content">
<section data-component="hero">
<div data-component="desktop-app-banner">
<span data-slot="badge">New</span>
<div data-slot="content">
<span data-slot="text">
Desktop app available in beta<span data-slot="platforms"> on macOS, Windows, and Linux</span>.
</span>
<a href="/download" data-slot="link">
Download now
</a>
<a href="/download" data-slot="link-mobile">
Download the desktop beta now
</a>
</div>
</div>
<div data-slot="hero-copy">
{/*<a data-slot="releases"*/}
{/* href={release()?.url ?? `${config.github.repoUrl}/releases`}*/}
+1 -1
View File
@@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/package.json",
"name": "@opencode-ai/console-core",
"version": "1.0.155",
"version": "1.0.156",
"private": true,
"type": "module",
"dependencies": {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@opencode-ai/console-function",
"version": "1.0.155",
"version": "1.0.156",
"$schema": "https://json.schemastore.org/package.json",
"private": true,
"type": "module",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@opencode-ai/console-mail",
"version": "1.0.155",
"version": "1.0.156",
"dependencies": {
"@jsx-email/all": "2.2.3",
"@jsx-email/cli": "1.4.3",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@opencode-ai/desktop",
"version": "1.0.155",
"version": "1.0.156",
"description": "",
"type": "module",
"exports": {
+33 -28
View File
@@ -12,7 +12,7 @@ import { GlobalSDKProvider } from "@/context/global-sdk"
import { TerminalProvider } from "@/context/terminal"
import { PromptProvider } from "@/context/prompt"
import { NotificationProvider } from "@/context/notification"
import { DialogProvider } from "@opencode-ai/ui/context/dialog"
import { DialogProvider, DialogRoot } from "@opencode-ai/ui/context/dialog"
import { CommandProvider } from "@/context/command"
import Layout from "@/pages/layout"
import Home from "@/pages/home"
@@ -41,33 +41,38 @@ export function App() {
<GlobalSDKProvider url={url}>
<GlobalSyncProvider>
<LayoutProvider>
<DialogProvider>
<CommandProvider>
<NotificationProvider>
<MetaProvider>
<Font />
<Router root={Layout}>
<Route path="/" component={Home} />
<Route path="/:dir" component={DirectoryLayout}>
<Route path="/" component={() => <Navigate href="session" />} />
<Route
path="/session/:id?"
component={(p) => (
<Show when={p.params.id || true} keyed>
<TerminalProvider>
<PromptProvider>
<Session />
</PromptProvider>
</TerminalProvider>
</Show>
)}
/>
</Route>
</Router>
</MetaProvider>
</NotificationProvider>
</CommandProvider>
</DialogProvider>
<NotificationProvider>
<MetaProvider>
<Font />
<Router
root={(props) => (
<DialogProvider>
<CommandProvider>
<DialogRoot />
<Layout>{props.children}</Layout>
</CommandProvider>
</DialogProvider>
)}
>
<Route path="/" component={Home} />
<Route path="/:dir" component={DirectoryLayout}>
<Route path="/" component={() => <Navigate href="session" />} />
<Route
path="/session/:id?"
component={(p) => (
<Show when={p.params.id || true} keyed>
<TerminalProvider>
<PromptProvider>
<Session />
</PromptProvider>
</TerminalProvider>
</Show>
)}
/>
</Route>
</Router>
</MetaProvider>
</NotificationProvider>
</LayoutProvider>
</GlobalSyncProvider>
</GlobalSDKProvider>
@@ -79,6 +79,7 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
const providers = useProviders()
const command = useCommand()
let editorRef!: HTMLDivElement
let fileInputRef!: HTMLInputElement
const sessionKey = createMemo(() => `${params.dir}${params.id ? "/" + params.id : ""}`)
const tabs = createMemo(() => layout.tabs(sessionKey()))
@@ -791,7 +792,7 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
<Show when={store.dragging}>
<div class="absolute inset-0 z-10 flex items-center justify-center bg-surface-raised-stronger-non-alpha/90 pointer-events-none">
<div class="flex flex-col items-center gap-2 text-text-weak">
<Icon name="plus" class="size-8" />
<Icon name="photo" class="size-8" />
<span class="text-14-regular">Drop images or PDFs here</span>
</div>
</div>
@@ -871,34 +872,56 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
<Icon name="chevron-down" size="small" />
</Button>
</div>
<Tooltip
placement="top"
inactive={!prompt.dirty() && !working()}
value={
<Switch>
<Match when={working()}>
<div class="flex items-center gap-2">
<span>Stop</span>
<span class="text-icon-base text-12-medium text-[10px]!">ESC</span>
</div>
</Match>
<Match when={true}>
<div class="flex items-center gap-2">
<span>Send</span>
<Icon name="enter" size="small" class="text-icon-base" />
</div>
</Match>
</Switch>
}
>
<IconButton
type="submit"
disabled={!prompt.dirty() && store.imageAttachments.length === 0 && !working()}
icon={working() ? "stop" : "arrow-up"}
variant="primary"
class="h-10 w-8 absolute right-2 bottom-2"
<div class="flex items-center gap-1 absolute right-2 bottom-2">
<input
ref={fileInputRef}
type="file"
accept={ACCEPTED_IMAGE_TYPES.join(",")}
class="hidden"
onChange={(e) => {
const file = e.currentTarget.files?.[0]
if (file) addImageAttachment(file)
e.currentTarget.value = ""
}}
/>
</Tooltip>
<Tooltip placement="top" value="Attach image">
<IconButton
type="button"
icon="photo"
variant="ghost"
class="h-10 w-8"
onClick={() => fileInputRef.click()}
/>
</Tooltip>
<Tooltip
placement="top"
inactive={!prompt.dirty() && !working()}
value={
<Switch>
<Match when={working()}>
<div class="flex items-center gap-2">
<span>Stop</span>
<span class="text-icon-base text-12-medium text-[10px]!">ESC</span>
</div>
</Match>
<Match when={true}>
<div class="flex items-center gap-2">
<span>Send</span>
<Icon name="enter" size="small" class="text-icon-base" />
</div>
</Match>
</Switch>
}
>
<IconButton
type="submit"
disabled={!prompt.dirty() && store.imageAttachments.length === 0 && !working()}
icon={working() ? "stop" : "arrow-up"}
variant="primary"
class="h-10 w-8"
/>
</Tooltip>
</div>
</div>
</form>
</div>
@@ -6,7 +6,7 @@ import { LocalProvider } from "@/context/local"
import { base64Decode } from "@opencode-ai/util/encode"
import { DataProvider } from "@opencode-ai/ui/context"
import { iife } from "@opencode-ai/util/iife"
import { DialogRoot } from "@opencode-ai/ui/context/dialog"
import { DialogProvider, DialogRoot } from "@opencode-ai/ui/context/dialog"
export default function Layout(props: ParentProps) {
const params = useParams()
@@ -22,7 +22,9 @@ export default function Layout(props: ParentProps) {
return (
<DataProvider data={sync.data} directory={directory()}>
<LocalProvider>
<DialogRoot>{props.children}</DialogRoot>
<DialogProvider>
<DialogRoot>{props.children}</DialogRoot>
</DialogProvider>
</LocalProvider>
</DataProvider>
)
+1 -2
View File
@@ -496,11 +496,10 @@ export default function Layout(props: ParentProps) {
}
const SortableProject = (props: { project: Project & { expanded: boolean } }): JSX.Element => {
const notification = useNotification()
const sortable = createSortable(props.project.worktree)
const slug = createMemo(() => base64Encode(props.project.worktree))
const name = createMemo(() => getFilename(props.project.worktree))
const [store, setStore] = globalSync.child(props.project.worktree)
const [store] = globalSync.child(props.project.worktree)
const sessions = createMemo(() => store.session ?? [])
const rootSessions = createMemo(() => sessions().filter((s) => !s.parentID))
const childSessionsByParent = createMemo(() => {
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@opencode-ai/enterprise",
"version": "1.0.155",
"version": "1.0.156",
"private": true,
"type": "module",
"scripts": {
@@ -14,7 +14,7 @@
"@opencode-ai/util": "workspace:*",
"@opencode-ai/ui": "workspace:*",
"aws4fetch": "^1.0.20",
"@pierre/precision-diffs": "catalog:",
"@pierre/diffs": "catalog:",
"@solidjs/router": "catalog:",
"@solidjs/start": "catalog:",
"@solidjs/meta": "catalog:",
@@ -19,7 +19,7 @@ import { createStore } from "solid-js/store"
import z from "zod"
import NotFound from "../[...404]"
import { Tabs } from "@opencode-ai/ui/tabs"
import { preloadMultiFileDiff, PreloadMultiFileDiffResult } from "@pierre/precision-diffs/ssr"
import { preloadMultiFileDiff, PreloadMultiFileDiffResult } from "@pierre/diffs/ssr"
import { Diff as SSRDiff } from "@opencode-ai/ui/diff-ssr"
import { clientOnly } from "@solidjs/start"
import { type IconName } from "@opencode-ai/ui/icons/provider"
+6 -6
View File
@@ -1,7 +1,7 @@
id = "opencode"
name = "OpenCode"
description = "The open source coding agent."
version = "1.0.155"
version = "1.0.156"
schema_version = 1
authors = ["Anomaly"]
repository = "https://github.com/sst/opencode"
@@ -11,26 +11,26 @@ name = "OpenCode"
icon = "./icons/opencode.svg"
[agent_servers.opencode.targets.darwin-aarch64]
archive = "https://github.com/sst/opencode/releases/download/v1.0.155/opencode-darwin-arm64.zip"
archive = "https://github.com/sst/opencode/releases/download/v1.0.156/opencode-darwin-arm64.zip"
cmd = "./opencode"
args = ["acp"]
[agent_servers.opencode.targets.darwin-x86_64]
archive = "https://github.com/sst/opencode/releases/download/v1.0.155/opencode-darwin-x64.zip"
archive = "https://github.com/sst/opencode/releases/download/v1.0.156/opencode-darwin-x64.zip"
cmd = "./opencode"
args = ["acp"]
[agent_servers.opencode.targets.linux-aarch64]
archive = "https://github.com/sst/opencode/releases/download/v1.0.155/opencode-linux-arm64.tar.gz"
archive = "https://github.com/sst/opencode/releases/download/v1.0.156/opencode-linux-arm64.tar.gz"
cmd = "./opencode"
args = ["acp"]
[agent_servers.opencode.targets.linux-x86_64]
archive = "https://github.com/sst/opencode/releases/download/v1.0.155/opencode-linux-x64.tar.gz"
archive = "https://github.com/sst/opencode/releases/download/v1.0.156/opencode-linux-x64.tar.gz"
cmd = "./opencode"
args = ["acp"]
[agent_servers.opencode.targets.windows-x86_64]
archive = "https://github.com/sst/opencode/releases/download/v1.0.155/opencode-windows-x64.zip"
archive = "https://github.com/sst/opencode/releases/download/v1.0.156/opencode-windows-x64.zip"
cmd = "./opencode.exe"
args = ["acp"]
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@opencode-ai/function",
"version": "1.0.155",
"version": "1.0.156",
"$schema": "https://json.schemastore.org/package.json",
"private": true,
"type": "module",
+2 -2
View File
@@ -1,6 +1,6 @@
{
"$schema": "https://json.schemastore.org/package.json",
"version": "1.0.155",
"version": "1.0.156",
"name": "opencode",
"type": "module",
"private": true,
@@ -74,7 +74,7 @@
"@opentui/core": "0.0.0-20251211-4403a69a",
"@opentui/solid": "0.0.0-20251211-4403a69a",
"@parcel/watcher": "2.5.1",
"@pierre/precision-diffs": "catalog:",
"@pierre/diffs": "catalog:",
"@solid-primitives/event-bus": "1.1.2",
"@standard-schema/spec": "1.0.0",
"@zip.js/zip.js": "2.7.62",
+40
View File
@@ -610,6 +610,46 @@ export namespace LSPServer {
},
}
export const FSharp: Info = {
id: "fsharp",
root: NearestRoot([".sln", ".fsproj", "global.json"]),
extensions: [".fs", ".fsi", ".fsx", ".fsscript"],
async spawn(root) {
let bin = Bun.which("fsautocomplete", {
PATH: process.env["PATH"] + ":" + Global.Path.bin,
})
if (!bin) {
if (!Bun.which("dotnet")) {
log.error(".NET SDK is required to install fsautocomplete")
return
}
if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
log.info("installing fsautocomplete via dotnet tool")
const proc = Bun.spawn({
cmd: ["dotnet", "tool", "install", "fsautocomplete", "--tool-path", Global.Path.bin],
stdout: "pipe",
stderr: "pipe",
stdin: "pipe",
})
const exit = await proc.exited
if (exit !== 0) {
log.error("Failed to install fsautocomplete")
return
}
bin = path.join(Global.Path.bin, "fsautocomplete" + (process.platform === "win32" ? ".exe" : ""))
log.info(`installed fsautocomplete`, { bin })
}
return {
process: spawn(bin, {
cwd: root,
}),
}
},
}
export const SourceKit: Info = {
id: "sourcekit-lsp",
extensions: [".swift", ".objc", "objcpp"],
+5 -1
View File
@@ -114,8 +114,12 @@ export namespace Pty {
const id = Identifier.create("pty", false)
const command = input.command || Shell.preferred()
const args = input.args || []
if (command.endsWith("sh")) {
args.push("-l")
}
const cwd = input.cwd || Instance.directory
const env = { ...process.env, ...input.env } as Record<string, string>
const env = { ...process.env, ...input.env, TERM: "xterm-256color" } as Record<string, string>
log.info("creating session", { id, cmd: command, args, cwd })
const spawn = await pty()
+1 -1
View File
@@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/package.json",
"name": "@opencode-ai/plugin",
"version": "1.0.155",
"version": "1.0.156",
"type": "module",
"scripts": {
"typecheck": "tsgo --noEmit",
+1 -1
View File
@@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/package.json",
"name": "@opencode-ai/sdk",
"version": "1.0.155",
"version": "1.0.156",
"type": "module",
"scripts": {
"typecheck": "tsgo --noEmit",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@opencode-ai/slack",
"version": "1.0.155",
"version": "1.0.156",
"type": "module",
"scripts": {
"dev": "bun run src/index.ts",
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@opencode-ai/tauri",
"private": true,
"version": "1.0.155",
"version": "1.0.156",
"type": "module",
"scripts": {
"typecheck": "tsgo -b",
+1
View File
@@ -183,6 +183,7 @@ pub fn run() {
.inner_size(size.width as f64, size.height as f64)
.decorations(true)
.zoom_hotkeys_enabled(true)
.disable_drag_drop_handler()
.initialization_script(format!(
r#"
window.__OPENCODE__ ??= {{}};
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@opencode-ai/ui",
"version": "1.0.155",
"version": "1.0.156",
"type": "module",
"exports": {
"./*": "./src/components/*.tsx",
@@ -35,7 +35,7 @@
"@kobalte/core": "catalog:",
"@opencode-ai/sdk": "workspace:*",
"@opencode-ai/util": "workspace:*",
"@pierre/precision-diffs": "catalog:",
"@pierre/diffs": "catalog:",
"@shikijs/transformers": "3.9.2",
"@solid-primitives/bounds": "0.1.3",
"@solid-primitives/resize-observer": "2.1.3",
+1 -1
View File
@@ -1,4 +1,4 @@
import { type FileContents, File, FileOptions, LineAnnotation } from "@pierre/precision-diffs"
import { type FileContents, File, FileOptions, LineAnnotation } from "@pierre/diffs"
import { ComponentProps, createEffect, createMemo, splitProps } from "solid-js"
import { createDefaultOptions, styleVariables } from "../pierre"
import { workerPool } from "../pierre/worker"
+4 -4
View File
@@ -1,5 +1,5 @@
import { FileDiff } from "@pierre/precision-diffs"
import { PreloadMultiFileDiffResult } from "@pierre/precision-diffs/ssr"
import { FileDiff } from "@pierre/diffs"
import { PreloadMultiFileDiffResult } from "@pierre/diffs/ssr"
import { onCleanup, onMount, Show, splitProps } from "solid-js"
import { isServer } from "solid-js/web"
import { createDefaultOptions, styleVariables, type DiffProps } from "../pierre"
@@ -65,11 +65,11 @@ export function Diff<T>(props: SSRDiffProps<T>) {
return (
<div data-component="diff" style={styleVariables} ref={container}>
<file-diff ref={fileDiffRef} id="ssr-diff">
<diffs-container ref={fileDiffRef} id="ssr-diff">
<Show when={isServer}>
<template shadowrootmode="open" innerHTML={props.preloadedDiff.prerenderedHTML} />
</Show>
</file-diff>
</diffs-container>
</div>
)
}
+2 -2
View File
@@ -19,8 +19,8 @@
position: sticky;
background-color: var(--surface-diff-hidden-base);
color: var(--text-base);
width: var(--pjs-column-content-width);
left: var(--pjs-column-number-width);
width: var(--diffs-column-content-width);
left: var(--diffs-column-number-width);
padding-left: 8px;
user-select: none;
cursor: default;
+1 -1
View File
@@ -1,4 +1,4 @@
import { FileDiff } from "@pierre/precision-diffs"
import { FileDiff } from "@pierre/diffs"
import { createEffect, createMemo, onCleanup, splitProps } from "solid-js"
import { createDefaultOptions, type DiffProps, styleVariables } from "../pierre"
import { workerPool } from "../pierre/worker"
+1
View File
@@ -51,6 +51,7 @@ const icons = {
"circle-check": `<path d="M12.4987 7.91732L8.7487 12.5007L7.08203 10.834M17.9154 10.0007C17.9154 14.3729 14.371 17.9173 9.9987 17.9173C5.62644 17.9173 2.08203 14.3729 2.08203 10.0007C2.08203 5.6284 5.62644 2.08398 9.9987 2.08398C14.371 2.08398 17.9154 5.6284 17.9154 10.0007Z" stroke="currentColor" stroke-linecap="square"/>`,
copy: `<path d="M6.2513 6.24935V2.91602H17.0846V13.7493H13.7513M13.7513 6.24935V17.0827H2.91797V6.24935H13.7513Z" stroke="currentColor" stroke-linecap="round"/>`,
check: `<path d="M5 11.9657L8.37838 14.7529L15 5.83398" stroke="currentColor" stroke-linecap="square"/>`,
photo: `<path d="M16.6665 16.6666L11.6665 11.6666L9.99984 13.3333L6.6665 9.99996L3.08317 13.5833M2.9165 2.91663H17.0832V17.0833H2.9165V2.91663ZM13.3332 7.49996C13.3332 8.30537 12.6803 8.95829 11.8748 8.95829C11.0694 8.95829 10.4165 8.30537 10.4165 7.49996C10.4165 6.69454 11.0694 6.04163 11.8748 6.04163C12.6803 6.04163 13.3332 6.69454 13.3332 7.49996Z" stroke="currentColor" stroke-linecap="square"/>`,
}
export interface IconProps extends ComponentProps<"svg"> {
+13 -15
View File
@@ -19,8 +19,6 @@ import { Checkbox } from "./checkbox"
import { DiffChanges } from "./diff-changes"
import { Markdown } from "./markdown"
import { getDirectory as _getDirectory, getFilename } from "@opencode-ai/util/path"
import { Code } from "./code"
import { checksum } from "@opencode-ai/util/encode"
export interface MessageProps {
message: MessageType
@@ -509,19 +507,19 @@ ToolRegistry.register({
</div>
}
>
<Show when={props.input.content}>
<div data-component="write-content">
<Code
file={{
name: props.input.filePath,
contents: props.input.content,
cacheKey: checksum(props.input.content),
}}
overflow="scroll"
class="pb-40"
/>
</div>
</Show>
{/* <Show when={props.input.content}> */}
{/* <div data-component="write-content"> */}
{/* <Code */}
{/* file={{ */}
{/* name: props.input.filePath, */}
{/* contents: props.input.content, */}
{/* cacheKey: checksum(props.input.content), */}
{/* }} */}
{/* overflow="scroll" */}
{/* class="pb-40" */}
{/* /> */}
{/* </div> */}
{/* </Show> */}
</BasicTool>
)
},
@@ -9,7 +9,7 @@ import { getDirectory, getFilename } from "@opencode-ai/util/path"
import { For, Match, Show, Switch, type JSX } from "solid-js"
import { createStore } from "solid-js/store"
import { type FileDiff } from "@opencode-ai/sdk/v2"
import { PreloadMultiFileDiffResult } from "@pierre/precision-diffs/ssr"
import { PreloadMultiFileDiffResult } from "@pierre/diffs/ssr"
import { Dynamic } from "solid-js/web"
import { checksum } from "@opencode-ai/util/encode"
+1 -1
View File
@@ -1,6 +1,6 @@
import type { Message, Session, Part, FileDiff, SessionStatus } from "@opencode-ai/sdk/v2"
import { createSimpleContext } from "./helper"
import { PreloadMultiFileDiffResult } from "@pierre/precision-diffs/ssr"
import { PreloadMultiFileDiffResult } from "@pierre/diffs/ssr"
type Data = {
session: Session[]
+1 -1
View File
@@ -2,7 +2,7 @@ import { marked } from "marked"
import markedShiki from "marked-shiki"
import { bundledLanguages, type BundledLanguage } from "shiki"
import { createSimpleContext } from "./helper"
import { getSharedHighlighter, registerCustomTheme, ThemeRegistrationResolved } from "@pierre/precision-diffs"
import { getSharedHighlighter, registerCustomTheme, ThemeRegistrationResolved } from "@pierre/diffs"
registerCustomTheme("OpenCode", () => {
return Promise.resolve({
+4 -4
View File
@@ -1,12 +1,12 @@
/**
* TypeScript declaration for the <file-diff> custom element.
* This tells TypeScript that <file-diff> is a valid JSX element in SolidJS.
* Required for using the precision-diffs web component in .tsx files.
* TypeScript declaration for the <diffs-container> custom element.
* This tells TypeScript that <diffs-container> is a valid JSX element in SolidJS.
* Required for using the @pierre/diffs web component in .tsx files.
*/
declare module "solid-js" {
namespace JSX {
interface IntrinsicElements {
"file-diff": HTMLAttributes<HTMLElement>
"diffs-container": HTMLAttributes<HTMLElement>
}
}
}
+11 -11
View File
@@ -1,4 +1,4 @@
import { DiffLineAnnotation, FileContents, FileDiffOptions } from "@pierre/precision-diffs"
import { DiffLineAnnotation, FileContents, FileDiffOptions } from "@pierre/diffs"
import { ComponentProps } from "solid-js"
export type DiffProps<T = {}> = FileDiffOptions<T> & {
@@ -10,8 +10,8 @@ export type DiffProps<T = {}> = FileDiffOptions<T> & {
}
const unsafeCSS = `
[data-pjs-header],
[data-pjs] {
[data-diffs-header],
[data-diffs] {
[data-separator-wrapper] {
margin: 0 !important;
border-radius: 0 !important;
@@ -71,12 +71,12 @@ export function createDefaultOptions<T>(style: FileDiffOptions<T>["diffStyle"])
}
export const styleVariables = {
"--pjs-font-family": "var(--font-family-mono)",
"--pjs-font-size": "var(--font-size-small)",
"--pjs-line-height": "24px",
"--pjs-tab-size": 2,
"--pjs-font-features": "var(--font-family-mono--font-feature-settings)",
"--pjs-header-font-family": "var(--font-family-sans)",
"--pjs-gap-block": 0,
"--pjs-min-number-column-width": "4ch",
"--diffs-font-family": "var(--font-family-mono)",
"--diffs-font-size": "var(--font-size-small)",
"--diffs-line-height": "24px",
"--diffs-tab-size": 2,
"--diffs-font-features": "var(--font-family-mono--font-feature-settings)",
"--diffs-header-font-family": "var(--font-family-sans)",
"--diffs-gap-block": 0,
"--diffs-min-number-column-width": "4ch",
}
+2 -2
View File
@@ -1,5 +1,5 @@
import { getOrCreateWorkerPoolSingleton } from "@pierre/precision-diffs/worker"
import ShikiWorkerUrl from "@pierre/precision-diffs/worker/worker.js?worker&url"
import { getOrCreateWorkerPoolSingleton } from "@pierre/diffs/worker"
import ShikiWorkerUrl from "@pierre/diffs/worker/worker.js?worker&url"
export function workerFactory(): Worker {
return new Worker(ShikiWorkerUrl, { type: "module" })
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@opencode-ai/util",
"version": "1.0.155",
"version": "1.0.156",
"private": true,
"type": "module",
"exports": {
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@opencode-ai/web",
"type": "module",
"version": "1.0.155",
"version": "1.0.156",
"scripts": {
"dev": "astro dev",
"dev:remote": "VITE_API_URL=https://api.opencode.ai astro dev",
+1
View File
@@ -22,6 +22,7 @@ OpenCode comes with several built-in LSP servers for popular languages:
| elixir-ls | .ex, .exs | `elixir` command available |
| zls | .zig, .zon | `zig` command available |
| csharp | .cs | `.NET SDK` installed |
| fsharp | .fs, .fsi, .fsx, .fsscript | `.NET SDK` installed |
| vue | .vue | Auto-installs for Vue projects |
| rust | .rs | `rust-analyzer` command available |
| clangd | .c, .cpp, .cc, .cxx, .c++, .h, .hpp, .hh, .hxx, .h++ | Auto-installs for C/C++ projects |
+1 -1
View File
@@ -2,7 +2,7 @@
"name": "opencode",
"displayName": "opencode",
"description": "opencode for VS Code",
"version": "1.0.155",
"version": "1.0.156",
"publisher": "sst-dev",
"repository": {
"type": "git",