mirror of
https://github.com/sst/opencode.git
synced 2025-12-23 10:11:41 +00:00
Merge branch 'dev' of https://github.com/sst/opencode into dev
This commit is contained in:
commit
58b30d678a
35 changed files with 338 additions and 143 deletions
|
|
@ -1,9 +1,9 @@
|
|||
{
|
||||
"$schema": "https://opencode.ai/config.json",
|
||||
"plugin": ["opencode-openai-codex-auth"],
|
||||
"enterprise": {
|
||||
"url": "https://enterprise.dev.opencode.ai",
|
||||
},
|
||||
// "enterprise": {
|
||||
// "url": "https://enterprise.dev.opencode.ai",
|
||||
// },
|
||||
"provider": {
|
||||
"opencode": {
|
||||
"options": {
|
||||
|
|
|
|||
1
STATS.md
1
STATS.md
|
|
@ -157,3 +157,4 @@
|
|||
| 2025-11-29 | 908,689 (+6,948) | 863,361 (+6,879) | 1,772,050 (+13,827) |
|
||||
| 2025-11-30 | 916,116 (+7,427) | 870,194 (+6,833) | 1,786,310 (+14,260) |
|
||||
| 2025-12-01 | 925,898 (+9,782) | 876,500 (+6,306) | 1,802,398 (+16,088) |
|
||||
| 2025-12-02 | 939,250 (+13,352) | 890,919 (+14,419) | 1,830,169 (+27,771) |
|
||||
|
|
|
|||
34
bun.lock
34
bun.lock
|
|
@ -20,7 +20,7 @@
|
|||
},
|
||||
"packages/console/app": {
|
||||
"name": "@opencode-ai/console-app",
|
||||
"version": "1.0.126",
|
||||
"version": "1.0.127",
|
||||
"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.126",
|
||||
"version": "1.0.127",
|
||||
"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.126",
|
||||
"version": "1.0.127",
|
||||
"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.126",
|
||||
"version": "1.0.127",
|
||||
"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.126",
|
||||
"version": "1.0.127",
|
||||
"dependencies": {
|
||||
"@kobalte/core": "catalog:",
|
||||
"@opencode-ai/sdk": "workspace:*",
|
||||
|
|
@ -164,7 +164,7 @@
|
|||
},
|
||||
"packages/enterprise": {
|
||||
"name": "@opencode-ai/enterprise",
|
||||
"version": "1.0.126",
|
||||
"version": "1.0.127",
|
||||
"dependencies": {
|
||||
"@opencode-ai/ui": "workspace:*",
|
||||
"@opencode-ai/util": "workspace:*",
|
||||
|
|
@ -192,7 +192,7 @@
|
|||
},
|
||||
"packages/function": {
|
||||
"name": "@opencode-ai/function",
|
||||
"version": "1.0.126",
|
||||
"version": "1.0.127",
|
||||
"dependencies": {
|
||||
"@octokit/auth-app": "8.0.1",
|
||||
"@octokit/rest": "22.0.0",
|
||||
|
|
@ -208,7 +208,7 @@
|
|||
},
|
||||
"packages/opencode": {
|
||||
"name": "opencode",
|
||||
"version": "1.0.126",
|
||||
"version": "1.0.127",
|
||||
"bin": {
|
||||
"opencode": "./bin/opencode",
|
||||
},
|
||||
|
|
@ -297,7 +297,7 @@
|
|||
},
|
||||
"packages/plugin": {
|
||||
"name": "@opencode-ai/plugin",
|
||||
"version": "1.0.126",
|
||||
"version": "1.0.127",
|
||||
"dependencies": {
|
||||
"@opencode-ai/sdk": "workspace:*",
|
||||
"zod": "catalog:",
|
||||
|
|
@ -317,7 +317,7 @@
|
|||
},
|
||||
"packages/sdk/js": {
|
||||
"name": "@opencode-ai/sdk",
|
||||
"version": "1.0.126",
|
||||
"version": "1.0.127",
|
||||
"devDependencies": {
|
||||
"@hey-api/openapi-ts": "0.81.0",
|
||||
"@tsconfig/node22": "catalog:",
|
||||
|
|
@ -328,7 +328,7 @@
|
|||
},
|
||||
"packages/slack": {
|
||||
"name": "@opencode-ai/slack",
|
||||
"version": "1.0.126",
|
||||
"version": "1.0.127",
|
||||
"dependencies": {
|
||||
"@opencode-ai/sdk": "workspace:*",
|
||||
"@slack/bolt": "^3.17.1",
|
||||
|
|
@ -341,7 +341,7 @@
|
|||
},
|
||||
"packages/tauri": {
|
||||
"name": "@opencode-ai/tauri",
|
||||
"version": "1.0.126",
|
||||
"version": "1.0.127",
|
||||
"dependencies": {
|
||||
"@tauri-apps/api": "^2",
|
||||
"@tauri-apps/plugin-opener": "^2",
|
||||
|
|
@ -354,7 +354,7 @@
|
|||
},
|
||||
"packages/ui": {
|
||||
"name": "@opencode-ai/ui",
|
||||
"version": "1.0.126",
|
||||
"version": "1.0.127",
|
||||
"dependencies": {
|
||||
"@kobalte/core": "catalog:",
|
||||
"@opencode-ai/sdk": "workspace:*",
|
||||
|
|
@ -386,7 +386,7 @@
|
|||
},
|
||||
"packages/util": {
|
||||
"name": "@opencode-ai/util",
|
||||
"version": "1.0.126",
|
||||
"version": "1.0.127",
|
||||
"dependencies": {
|
||||
"zod": "catalog:",
|
||||
},
|
||||
|
|
@ -397,7 +397,7 @@
|
|||
},
|
||||
"packages/web": {
|
||||
"name": "@opencode-ai/web",
|
||||
"version": "1.0.126",
|
||||
"version": "1.0.127",
|
||||
"dependencies": {
|
||||
"@astrojs/cloudflare": "12.6.3",
|
||||
"@astrojs/markdown-remark": "6.3.1",
|
||||
|
|
@ -443,7 +443,7 @@
|
|||
"@hono/zod-validator": "0.4.2",
|
||||
"@kobalte/core": "0.13.11",
|
||||
"@openauthjs/openauth": "0.0.0-20250322224806",
|
||||
"@pierre/precision-diffs": "0.5.7",
|
||||
"@pierre/precision-diffs": "0.6.0-beta.3",
|
||||
"@solidjs/meta": "0.29.4",
|
||||
"@solidjs/router": "0.15.4",
|
||||
"@solidjs/start": "https://pkg.pr.new/@solidjs/start@dfb2020",
|
||||
|
|
@ -1218,7 +1218,7 @@
|
|||
|
||||
"@petamoriken/float16": ["@petamoriken/float16@3.9.3", "", {}, "sha512-8awtpHXCx/bNpFt4mt2xdkgtgVvKqty8VbjHI/WWWQuEw+KLzFot3f4+LkQY9YmOtq7A5GdOnqoIC8Pdygjk2g=="],
|
||||
|
||||
"@pierre/precision-diffs": ["@pierre/precision-diffs@0.5.7", "", { "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", "shiki": "3.15.0" }, "peerDependencies": { "react": "^18.3.1 || ^19.0.0", "react-dom": "^18.3.1 || ^19.0.0" } }, "sha512-Y+e4kJ9pT2I4NS5fE39KdoiXtwMkVPRvrwLM6O2IqO7PDCRWLBS7CYxcSgSyngEndccUll2krx66I2QnfO0Ovg=="],
|
||||
"@pierre/precision-diffs": ["@pierre/precision-diffs@0.6.0-beta.3", "", { "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", "shiki": "3.15.0" }, "peerDependencies": { "react": "^18.3.1 || ^19.0.0", "react-dom": "^18.3.1 || ^19.0.0" } }, "sha512-1FBm9jhLWZvs7BqN3yG2Wh9SpGuO1us2QsKZlQqSwyCctMr9DRGzYQJ9lF6yR03LHzXs3fuIzO++d9sCObYzrQ=="],
|
||||
|
||||
"@pkgjs/parseargs": ["@pkgjs/parseargs@0.11.0", "", {}, "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg=="],
|
||||
|
||||
|
|
|
|||
6
flake.lock
generated
6
flake.lock
generated
|
|
@ -2,11 +2,11 @@
|
|||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1764587062,
|
||||
"narHash": "sha256-hdFa0TAVQAQLDF31cEW3enWmBP+b592OvHs6WVe3D8k=",
|
||||
"lastModified": 1764611609,
|
||||
"narHash": "sha256-yU9BNcP0oadUKupw0UKmO9BKDOVIg9NStdJosEbXf8U=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "c1cb7d097cb250f6e1904aacd5f2ba5ffd8a49ce",
|
||||
"rev": "8c29968b3a942f2903f90797f9623737c215737c",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
{
|
||||
"nodeModules": "sha256-9BfJ3dFq/UYyhsnK3Sfx6rb6CT8bCvFOFOqD2+W1WQE="
|
||||
"nodeModules": "sha256-HyH219sZn4gOPyVg/bij7K3mfZ0MnBSM/7NmsOyrD4o="
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.5.7",
|
||||
"@pierre/precision-diffs": "0.6.0-beta.3",
|
||||
"@tailwindcss/vite": "4.1.11",
|
||||
"diff": "8.0.2",
|
||||
"ai": "5.0.97",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opencode-ai/console-app",
|
||||
"version": "1.0.126",
|
||||
"version": "1.0.127",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"typecheck": "tsgo --noEmit",
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"name": "@opencode-ai/console-core",
|
||||
"version": "1.0.126",
|
||||
"version": "1.0.127",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opencode-ai/console-function",
|
||||
"version": "1.0.126",
|
||||
"version": "1.0.127",
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opencode-ai/console-mail",
|
||||
"version": "1.0.126",
|
||||
"version": "1.0.127",
|
||||
"dependencies": {
|
||||
"@jsx-email/all": "2.2.3",
|
||||
"@jsx-email/cli": "1.4.3",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opencode-ai/desktop",
|
||||
"version": "1.0.126",
|
||||
"version": "1.0.127",
|
||||
"description": "",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import { useSync } from "@/context/sync"
|
|||
import { useSession } from "@/context/session"
|
||||
import { useLayout } from "@/context/layout"
|
||||
import { getDirectory, getFilename } from "@opencode-ai/util/path"
|
||||
import { Diff } from "@opencode-ai/ui/diff"
|
||||
|
||||
export default function Page() {
|
||||
const layout = useLayout()
|
||||
|
|
@ -357,6 +358,7 @@ export default function Page() {
|
|||
content: "pb-20",
|
||||
container: "w-full " + (wide() ? "max-w-146 mx-auto px-6" : "pr-6 pl-18"),
|
||||
}}
|
||||
diffComponent={Diff}
|
||||
/>
|
||||
</div>
|
||||
</Match>
|
||||
|
|
@ -405,6 +407,7 @@ export default function Page() {
|
|||
container: "px-6",
|
||||
}}
|
||||
diffs={session.diffs()}
|
||||
diffComponent={Diff}
|
||||
actions={
|
||||
<Tooltip value="Open in tab">
|
||||
<IconButton
|
||||
|
|
@ -436,6 +439,7 @@ export default function Page() {
|
|||
container: "px-6",
|
||||
}}
|
||||
diffs={session.diffs()}
|
||||
diffComponent={Diff}
|
||||
split
|
||||
/>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opencode-ai/enterprise",
|
||||
"version": "1.0.126",
|
||||
"version": "1.0.127",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
|
|
|||
|
|
@ -18,6 +18,10 @@ import z from "zod"
|
|||
import NotFound from "../[...404]"
|
||||
import { Tabs } from "@opencode-ai/ui/tabs"
|
||||
import { preloadMultiFileDiff, PreloadMultiFileDiffResult } from "@pierre/precision-diffs/ssr"
|
||||
import { Diff } from "@opencode-ai/ui/diff-ssr"
|
||||
import { clientOnly } from "@solidjs/start"
|
||||
|
||||
const ClientOnlyDiff = clientOnly(() => import("@opencode-ai/ui/diff").then((m) => ({ default: m.Diff })))
|
||||
|
||||
const SessionDataMissingError = NamedError.create(
|
||||
"SessionDataMissingError",
|
||||
|
|
@ -230,6 +234,7 @@ export default function () {
|
|||
"flex flex-col justify-between !overflow-visible [&_[data-slot=session-turn-message-header]]:top-[-32px]",
|
||||
container: "px-4",
|
||||
}}
|
||||
diffComponent={ClientOnlyDiff}
|
||||
/>
|
||||
)}
|
||||
</For>
|
||||
|
|
@ -299,6 +304,7 @@ export default function () {
|
|||
content: "flex flex-col justify-between items-start",
|
||||
container: "w-full pb-20 " + (wide() ? "max-w-146 mx-auto px-6" : "pr-6 pl-18"),
|
||||
}}
|
||||
diffComponent={ClientOnlyDiff}
|
||||
>
|
||||
<div classList={{ "w-full flex items-center justify-center pb-8 shrink-0": true }}>
|
||||
<Logo class="w-58.5 opacity-12" />
|
||||
|
|
@ -311,6 +317,7 @@ export default function () {
|
|||
<SessionReview
|
||||
class="@4xl:hidden"
|
||||
diffs={diffs()}
|
||||
diffComponent={Diff}
|
||||
classes={{
|
||||
root: "pb-20",
|
||||
header: "px-6",
|
||||
|
|
@ -318,9 +325,10 @@ export default function () {
|
|||
}}
|
||||
/>
|
||||
<SessionReview
|
||||
class="hidden @4xl:flex"
|
||||
split
|
||||
class="hidden @4xl:flex"
|
||||
diffs={splitDiffs()}
|
||||
diffComponent={Diff}
|
||||
classes={{
|
||||
root: "pb-20",
|
||||
header: "px-6",
|
||||
|
|
@ -352,6 +360,7 @@ export default function () {
|
|||
<div class="relative h-full pt-8 overflow-y-auto no-scrollbar">
|
||||
<SessionReview
|
||||
diffs={diffs()}
|
||||
diffComponent={Diff}
|
||||
classes={{
|
||||
root: "pb-20",
|
||||
header: "px-4",
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
id = "opencode"
|
||||
name = "OpenCode"
|
||||
description = "The AI coding agent built for the terminal"
|
||||
version = "1.0.126"
|
||||
version = "1.0.127"
|
||||
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.126/opencode-darwin-arm64.zip"
|
||||
archive = "https://github.com/sst/opencode/releases/download/v1.0.127/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.126/opencode-darwin-x64.zip"
|
||||
archive = "https://github.com/sst/opencode/releases/download/v1.0.127/opencode-darwin-x64.zip"
|
||||
cmd = "./opencode"
|
||||
args = ["acp"]
|
||||
|
||||
[agent_servers.opencode.targets.linux-aarch64]
|
||||
archive = "https://github.com/sst/opencode/releases/download/v1.0.126/opencode-linux-arm64.zip"
|
||||
archive = "https://github.com/sst/opencode/releases/download/v1.0.127/opencode-linux-arm64.zip"
|
||||
cmd = "./opencode"
|
||||
args = ["acp"]
|
||||
|
||||
[agent_servers.opencode.targets.linux-x86_64]
|
||||
archive = "https://github.com/sst/opencode/releases/download/v1.0.126/opencode-linux-x64.zip"
|
||||
archive = "https://github.com/sst/opencode/releases/download/v1.0.127/opencode-linux-x64.zip"
|
||||
cmd = "./opencode"
|
||||
args = ["acp"]
|
||||
|
||||
[agent_servers.opencode.targets.windows-x86_64]
|
||||
archive = "https://github.com/sst/opencode/releases/download/v1.0.126/opencode-windows-x64.zip"
|
||||
archive = "https://github.com/sst/opencode/releases/download/v1.0.127/opencode-windows-x64.zip"
|
||||
cmd = "./opencode.exe"
|
||||
args = ["acp"]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opencode-ai/function",
|
||||
"version": "1.0.126",
|
||||
"version": "1.0.127",
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"version": "1.0.126",
|
||||
"version": "1.0.127",
|
||||
"name": "opencode",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
|
|
|
|||
|
|
@ -169,6 +169,9 @@ function resolveTheme(theme: ThemeJson, mode: "dark" | "light") {
|
|||
throw new Error(`Color reference "${c}" not found in defs or theme`)
|
||||
}
|
||||
}
|
||||
if (typeof c === "number") {
|
||||
return ansiToRgba(c)
|
||||
}
|
||||
return resolveColor(c[mode])
|
||||
}
|
||||
|
||||
|
|
@ -203,6 +206,51 @@ function resolveTheme(theme: ThemeJson, mode: "dark" | "light") {
|
|||
} as Theme
|
||||
}
|
||||
|
||||
function ansiToRgba(code: number): RGBA {
|
||||
// Standard ANSI colors (0-15)
|
||||
if (code < 16) {
|
||||
const ansiColors = [
|
||||
"#000000", // Black
|
||||
"#800000", // Red
|
||||
"#008000", // Green
|
||||
"#808000", // Yellow
|
||||
"#000080", // Blue
|
||||
"#800080", // Magenta
|
||||
"#008080", // Cyan
|
||||
"#c0c0c0", // White
|
||||
"#808080", // Bright Black
|
||||
"#ff0000", // Bright Red
|
||||
"#00ff00", // Bright Green
|
||||
"#ffff00", // Bright Yellow
|
||||
"#0000ff", // Bright Blue
|
||||
"#ff00ff", // Bright Magenta
|
||||
"#00ffff", // Bright Cyan
|
||||
"#ffffff", // Bright White
|
||||
]
|
||||
return RGBA.fromHex(ansiColors[code] ?? "#000000")
|
||||
}
|
||||
|
||||
// 6x6x6 Color Cube (16-231)
|
||||
if (code < 232) {
|
||||
const index = code - 16
|
||||
const b = index % 6
|
||||
const g = Math.floor(index / 6) % 6
|
||||
const r = Math.floor(index / 36)
|
||||
|
||||
const val = (x: number) => (x === 0 ? 0 : x * 40 + 55)
|
||||
return RGBA.fromInts(val(r), val(g), val(b))
|
||||
}
|
||||
|
||||
// Grayscale Ramp (232-255)
|
||||
if (code < 256) {
|
||||
const gray = (code - 232) * 10 + 8
|
||||
return RGBA.fromInts(gray, gray, gray)
|
||||
}
|
||||
|
||||
// Fallback for invalid codes
|
||||
return RGBA.fromInts(0, 0, 0)
|
||||
}
|
||||
|
||||
export const { use: useTheme, provider: ThemeProvider } = createSimpleContext({
|
||||
name: "Theme",
|
||||
init: (props: { mode: "dark" | "light" }) => {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"name": "@opencode-ai/plugin",
|
||||
"version": "1.0.126",
|
||||
"version": "1.0.127",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"typecheck": "tsgo --noEmit",
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"name": "@opencode-ai/sdk",
|
||||
"version": "1.0.126",
|
||||
"version": "1.0.127",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"typecheck": "tsgo --noEmit",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opencode-ai/slack",
|
||||
"version": "1.0.126",
|
||||
"version": "1.0.127",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "bun run src/index.ts",
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "@opencode-ai/tauri",
|
||||
"private": true,
|
||||
"version": "1.0.126",
|
||||
"version": "1.0.127",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
{
|
||||
"name": "@opencode-ai/ui",
|
||||
"version": "1.0.126",
|
||||
"version": "1.0.127",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
"./*": "./src/components/*.tsx",
|
||||
"./pierre": "./src/components/pierre.ts",
|
||||
"./pierre": "./src/pierre/index.ts",
|
||||
"./hooks": "./src/hooks/index.ts",
|
||||
"./context": "./src/context/index.ts",
|
||||
"./context/*": "./src/context/*.tsx",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,22 @@
|
|||
import { type FileContents, File, FileOptions, LineAnnotation } from "@pierre/precision-diffs"
|
||||
import { ComponentProps, createEffect, splitProps } from "solid-js"
|
||||
import { createDefaultOptions, styleVariables } from "./pierre"
|
||||
import { createDefaultOptions, styleVariables } from "../pierre"
|
||||
import { getOrCreateWorkerPoolSingleton } from "@pierre/precision-diffs/worker"
|
||||
import { workerFactory } from "../pierre/worker"
|
||||
|
||||
const workerPool = getOrCreateWorkerPoolSingleton({
|
||||
poolOptions: {
|
||||
workerFactory,
|
||||
// poolSize defaults to 8. More workers = more parallelism but
|
||||
// also more memory. Too many can actually slow things down.
|
||||
// poolSize: 8,
|
||||
},
|
||||
highlighterOptions: {
|
||||
theme: "OpenCode",
|
||||
// Optionally preload languages to avoid lazy-loading delays
|
||||
// langs: ["typescript", "javascript", "css", "html"],
|
||||
},
|
||||
})
|
||||
|
||||
export type CodeProps<T = {}> = FileOptions<T> & {
|
||||
file: FileContents
|
||||
|
|
@ -14,10 +30,13 @@ export function Code<T>(props: CodeProps<T>) {
|
|||
const [local, others] = splitProps(props, ["file", "class", "classList", "annotations"])
|
||||
|
||||
createEffect(() => {
|
||||
const instance = new File<T>({
|
||||
...createDefaultOptions<T>("unified"),
|
||||
...others,
|
||||
})
|
||||
const instance = new File<T>(
|
||||
{
|
||||
...createDefaultOptions<T>("unified"),
|
||||
...others,
|
||||
},
|
||||
workerPool,
|
||||
)
|
||||
|
||||
container.innerHTML = ""
|
||||
instance.render({
|
||||
|
|
|
|||
75
packages/ui/src/components/diff-ssr.tsx
Normal file
75
packages/ui/src/components/diff-ssr.tsx
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
import { FileDiff } from "@pierre/precision-diffs"
|
||||
import { PreloadMultiFileDiffResult } from "@pierre/precision-diffs/ssr"
|
||||
import { onCleanup, onMount, Show, splitProps } from "solid-js"
|
||||
import { isServer } from "solid-js/web"
|
||||
import { createDefaultOptions, styleVariables, type DiffProps } from "../pierre"
|
||||
|
||||
export type SSRDiffProps<T = {}> = DiffProps<T> & {
|
||||
preloadedDiff: PreloadMultiFileDiffResult<T>
|
||||
}
|
||||
|
||||
export function Diff<T>(props: SSRDiffProps<T>) {
|
||||
let container!: HTMLDivElement
|
||||
let fileDiffRef!: HTMLElement
|
||||
const [local, others] = splitProps(props, ["before", "after", "class", "classList", "annotations"])
|
||||
|
||||
let fileDiffInstance: FileDiff<T> | undefined
|
||||
const cleanupFunctions: Array<() => void> = []
|
||||
|
||||
onMount(() => {
|
||||
if (isServer || !props.preloadedDiff) return
|
||||
fileDiffInstance = new FileDiff<T>({
|
||||
...createDefaultOptions(props.diffStyle),
|
||||
...others,
|
||||
...props.preloadedDiff,
|
||||
})
|
||||
// @ts-expect-error - fileContainer is private but needed for SSR hydration
|
||||
fileDiffInstance.fileContainer = fileDiffRef
|
||||
fileDiffInstance.hydrate({
|
||||
oldFile: local.before,
|
||||
newFile: local.after,
|
||||
lineAnnotations: local.annotations,
|
||||
fileContainer: fileDiffRef,
|
||||
containerWrapper: container,
|
||||
})
|
||||
|
||||
// Hydrate annotation slots with interactive SolidJS components
|
||||
// if (props.annotations.length > 0 && props.renderAnnotation != null) {
|
||||
// for (const annotation of props.annotations) {
|
||||
// const slotName = `annotation-${annotation.side}-${annotation.lineNumber}`;
|
||||
// const slotElement = fileDiffRef.querySelector(
|
||||
// `[slot="${slotName}"]`
|
||||
// ) as HTMLElement;
|
||||
//
|
||||
// if (slotElement != null) {
|
||||
// // Clear the static server-rendered content from the slot
|
||||
// slotElement.innerHTML = '';
|
||||
//
|
||||
// // Mount a fresh SolidJS component into this slot using render().
|
||||
// // This enables full SolidJS reactivity (signals, effects, etc.)
|
||||
// const dispose = render(
|
||||
// () => props.renderAnnotation!(annotation),
|
||||
// slotElement
|
||||
// );
|
||||
// cleanupFunctions.push(dispose);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
})
|
||||
|
||||
onCleanup(() => {
|
||||
// Clean up FileDiff event handlers and dispose SolidJS components
|
||||
fileDiffInstance?.cleanUp()
|
||||
cleanupFunctions.forEach((dispose) => dispose())
|
||||
})
|
||||
|
||||
return (
|
||||
<div data-component="diff" style={styleVariables} ref={container}>
|
||||
<file-diff ref={fileDiffRef} id="ssr-diff">
|
||||
<Show when={isServer}>
|
||||
<template shadowrootmode="open" innerHTML={props.preloadedDiff.prerenderedHTML} />
|
||||
</Show>
|
||||
</file-diff>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
@ -1,17 +1,22 @@
|
|||
import { type FileContents, FileDiff, type DiffLineAnnotation, FileDiffOptions } from "@pierre/precision-diffs"
|
||||
import { PreloadMultiFileDiffResult } from "@pierre/precision-diffs/ssr"
|
||||
import { ComponentProps, createEffect, onCleanup, onMount, Show, splitProps } from "solid-js"
|
||||
import { isServer } from "solid-js/web"
|
||||
import { createDefaultOptions, styleVariables } from "./pierre"
|
||||
import { FileDiff } from "@pierre/precision-diffs"
|
||||
import { getOrCreateWorkerPoolSingleton } from "@pierre/precision-diffs/worker"
|
||||
import { createEffect, onCleanup, splitProps } from "solid-js"
|
||||
import { createDefaultOptions, type DiffProps, styleVariables } from "../pierre"
|
||||
import { workerFactory } from "../pierre/worker"
|
||||
|
||||
export type DiffProps<T = {}> = FileDiffOptions<T> & {
|
||||
preloadedDiff?: PreloadMultiFileDiffResult<T>
|
||||
before: FileContents
|
||||
after: FileContents
|
||||
annotations?: DiffLineAnnotation<T>[]
|
||||
class?: string
|
||||
classList?: ComponentProps<"div">["classList"]
|
||||
}
|
||||
const workerPool = getOrCreateWorkerPoolSingleton({
|
||||
poolOptions: {
|
||||
workerFactory,
|
||||
// poolSize defaults to 8. More workers = more parallelism but
|
||||
// also more memory. Too many can actually slow things down.
|
||||
// poolSize: 8,
|
||||
},
|
||||
highlighterOptions: {
|
||||
theme: "OpenCode",
|
||||
// Optionally preload languages to avoid lazy-loading delays
|
||||
// langs: ["typescript", "javascript", "css", "html"],
|
||||
},
|
||||
})
|
||||
|
||||
// interface ThreadMetadata {
|
||||
// threadId: string
|
||||
|
|
@ -21,21 +26,21 @@ export type DiffProps<T = {}> = FileDiffOptions<T> & {
|
|||
|
||||
export function Diff<T>(props: DiffProps<T>) {
|
||||
let container!: HTMLDivElement
|
||||
let fileDiffRef!: HTMLElement
|
||||
const [local, others] = splitProps(props, ["before", "after", "class", "classList", "annotations"])
|
||||
|
||||
let fileDiffInstance: FileDiff<T> | undefined
|
||||
const cleanupFunctions: Array<() => void> = []
|
||||
|
||||
createEffect(() => {
|
||||
if (props.preloadedDiff) return
|
||||
container.innerHTML = ""
|
||||
if (!fileDiffInstance) {
|
||||
fileDiffInstance = new FileDiff<T>({
|
||||
...createDefaultOptions(props.diffStyle),
|
||||
...others,
|
||||
...(props.preloadedDiff ?? {}),
|
||||
})
|
||||
fileDiffInstance = new FileDiff<T>(
|
||||
{
|
||||
...createDefaultOptions(props.diffStyle),
|
||||
...others,
|
||||
},
|
||||
workerPool,
|
||||
)
|
||||
}
|
||||
fileDiffInstance.render({
|
||||
oldFile: local.before,
|
||||
|
|
@ -45,60 +50,11 @@ export function Diff<T>(props: DiffProps<T>) {
|
|||
})
|
||||
})
|
||||
|
||||
onMount(() => {
|
||||
if (isServer || !props.preloadedDiff) return
|
||||
fileDiffInstance = new FileDiff<T>({
|
||||
...createDefaultOptions(props.diffStyle),
|
||||
...others,
|
||||
...(props.preloadedDiff ?? {}),
|
||||
})
|
||||
// @ts-expect-error - fileContainer is private but needed for SSR hydration
|
||||
fileDiffInstance.fileContainer = fileDiffRef
|
||||
fileDiffInstance.hydrate({
|
||||
oldFile: local.before,
|
||||
newFile: local.after,
|
||||
lineAnnotations: local.annotations,
|
||||
fileContainer: fileDiffRef,
|
||||
containerWrapper: container,
|
||||
})
|
||||
|
||||
// Hydrate annotation slots with interactive SolidJS components
|
||||
// if (props.annotations.length > 0 && props.renderAnnotation != null) {
|
||||
// for (const annotation of props.annotations) {
|
||||
// const slotName = `annotation-${annotation.side}-${annotation.lineNumber}`;
|
||||
// const slotElement = fileDiffRef.querySelector(
|
||||
// `[slot="${slotName}"]`
|
||||
// ) as HTMLElement;
|
||||
//
|
||||
// if (slotElement != null) {
|
||||
// // Clear the static server-rendered content from the slot
|
||||
// slotElement.innerHTML = '';
|
||||
//
|
||||
// // Mount a fresh SolidJS component into this slot using render().
|
||||
// // This enables full SolidJS reactivity (signals, effects, etc.)
|
||||
// const dispose = render(
|
||||
// () => props.renderAnnotation!(annotation),
|
||||
// slotElement
|
||||
// );
|
||||
// cleanupFunctions.push(dispose);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
})
|
||||
|
||||
onCleanup(() => {
|
||||
// Clean up FileDiff event handlers and dispose SolidJS components
|
||||
fileDiffInstance?.cleanUp()
|
||||
cleanupFunctions.forEach((dispose) => dispose())
|
||||
})
|
||||
|
||||
return (
|
||||
<div data-component="diff" style={styleVariables} ref={container}>
|
||||
<file-diff ref={fileDiffRef} id="ssr-diff">
|
||||
<Show when={isServer && props.preloadedDiff}>
|
||||
{(preloadedDiff) => <template shadowrootmode="open" innerHTML={preloadedDiff().prerenderedHTML} />}
|
||||
</Show>
|
||||
</file-diff>
|
||||
</div>
|
||||
)
|
||||
return <div data-component="diff" style={styleVariables} ref={container} />
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Component, createMemo, For, Match, Show, Switch } from "solid-js"
|
||||
import { Component, createMemo, For, Match, Show, Switch, ValidComponent } from "solid-js"
|
||||
import { Dynamic } from "solid-js/web"
|
||||
import {
|
||||
AssistantMessage,
|
||||
|
|
@ -13,7 +13,6 @@ import { GenericTool } from "./basic-tool"
|
|||
import { Card } from "./card"
|
||||
import { Icon } from "./icon"
|
||||
import { Checkbox } from "./checkbox"
|
||||
import { Diff } from "./diff"
|
||||
import { DiffChanges } from "./diff-changes"
|
||||
import { Markdown } from "./markdown"
|
||||
import { getDirectory, getFilename } from "@opencode-ai/util/path"
|
||||
|
|
@ -23,12 +22,14 @@ import { unwrap } from "solid-js/store"
|
|||
export interface MessageProps {
|
||||
message: MessageType
|
||||
parts: PartType[]
|
||||
diffComponent: ValidComponent
|
||||
sanitize?: RegExp
|
||||
}
|
||||
|
||||
export interface MessagePartProps {
|
||||
part: PartType
|
||||
message: MessageType
|
||||
diffComponent: ValidComponent
|
||||
hideDetails?: boolean
|
||||
sanitize?: RegExp
|
||||
}
|
||||
|
|
@ -53,6 +54,7 @@ export function Message(props: MessageProps) {
|
|||
message={assistantMessage() as AssistantMessage}
|
||||
parts={props.parts}
|
||||
sanitize={props.sanitize}
|
||||
diffComponent={props.diffComponent}
|
||||
/>
|
||||
)}
|
||||
</Match>
|
||||
|
|
@ -60,7 +62,12 @@ export function Message(props: MessageProps) {
|
|||
)
|
||||
}
|
||||
|
||||
export function AssistantMessageDisplay(props: { message: AssistantMessage; parts: PartType[]; sanitize?: RegExp }) {
|
||||
export function AssistantMessageDisplay(props: {
|
||||
message: AssistantMessage
|
||||
parts: PartType[]
|
||||
sanitize?: RegExp
|
||||
diffComponent: ValidComponent
|
||||
}) {
|
||||
const filteredParts = createMemo(() => {
|
||||
return props.parts?.filter((x) => {
|
||||
if (x.type === "reasoning") return false
|
||||
|
|
@ -68,7 +75,11 @@ export function AssistantMessageDisplay(props: { message: AssistantMessage; part
|
|||
})
|
||||
})
|
||||
return (
|
||||
<For each={filteredParts()}>{(part) => <Part part={part} message={props.message} sanitize={props.sanitize} />}</For>
|
||||
<For each={filteredParts()}>
|
||||
{(part) => (
|
||||
<Part part={part} message={props.message} sanitize={props.sanitize} diffComponent={props.diffComponent} />
|
||||
)}
|
||||
</For>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -87,7 +98,13 @@ export function Part(props: MessagePartProps) {
|
|||
const part = createMemo(() => sanitizePart(unwrap(props.part), props.sanitize))
|
||||
return (
|
||||
<Show when={component()}>
|
||||
<Dynamic component={component()} part={part()} message={props.message} hideDetails={props.hideDetails} />
|
||||
<Dynamic
|
||||
component={component()}
|
||||
part={part()}
|
||||
message={props.message}
|
||||
diffComponent={props.diffComponent}
|
||||
hideDetails={props.hideDetails}
|
||||
/>
|
||||
</Show>
|
||||
)
|
||||
}
|
||||
|
|
@ -96,6 +113,7 @@ export interface ToolProps {
|
|||
input: Record<string, any>
|
||||
metadata: Record<string, any>
|
||||
tool: string
|
||||
diffComponent: ValidComponent
|
||||
output?: string
|
||||
hideDetails?: boolean
|
||||
}
|
||||
|
|
@ -162,6 +180,7 @@ PART_MAPPING["tool"] = function ToolPartDisplay(props) {
|
|||
component={render}
|
||||
input={input}
|
||||
tool={part.tool}
|
||||
diffComponent={props.diffComponent}
|
||||
metadata={metadata}
|
||||
output={part.state.status === "completed" ? part.state.output : undefined}
|
||||
hideDetails={props.hideDetails}
|
||||
|
|
@ -361,7 +380,8 @@ ToolRegistry.register({
|
|||
>
|
||||
<Show when={props.metadata.filediff}>
|
||||
<div data-component="edit-content">
|
||||
<Diff
|
||||
<Dynamic
|
||||
component={props.diffComponent}
|
||||
before={{
|
||||
name: getFilename(props.metadata.filediff.path),
|
||||
contents: props.metadata.filediff.before,
|
||||
|
|
|
|||
|
|
@ -1,10 +1,27 @@
|
|||
import { For, JSXElement, Match, Show, Switch, createEffect, createMemo, createSignal, onCleanup } from "solid-js"
|
||||
import {
|
||||
For,
|
||||
JSXElement,
|
||||
Match,
|
||||
Show,
|
||||
Switch,
|
||||
ValidComponent,
|
||||
createEffect,
|
||||
createMemo,
|
||||
createSignal,
|
||||
onCleanup,
|
||||
} from "solid-js"
|
||||
import { Part } from "./message-part"
|
||||
import { Spinner } from "./spinner"
|
||||
import { useData } from "../context/data"
|
||||
import type { AssistantMessage as AssistantMessageType, ToolPart } from "@opencode-ai/sdk"
|
||||
|
||||
export function MessageProgress(props: { assistantMessages: () => AssistantMessageType[]; done?: boolean }) {
|
||||
export interface MessageProgressProps {
|
||||
assistantMessages: () => AssistantMessageType[]
|
||||
diffComponent: ValidComponent
|
||||
done?: boolean
|
||||
}
|
||||
|
||||
export function MessageProgress(props: MessageProgressProps) {
|
||||
const data = useData()
|
||||
const sanitizer = createMemo(() => (data.directory ? new RegExp(`${data.directory}/`, "g") : undefined))
|
||||
const parts = createMemo(() => props.assistantMessages().flatMap((m) => data.store.part[m.id]))
|
||||
|
|
@ -155,7 +172,12 @@ export function MessageProgress(props: { assistantMessages: () => AssistantMessa
|
|||
)
|
||||
return (
|
||||
<div data-slot="message-progress-item">
|
||||
<Part message={message()!} part={part} sanitize={sanitizer()} />
|
||||
<Part
|
||||
message={message()!}
|
||||
part={part}
|
||||
sanitize={sanitizer()}
|
||||
diffComponent={props.diffComponent}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -1,15 +1,15 @@
|
|||
import { Accordion } from "./accordion"
|
||||
import { Button } from "./button"
|
||||
import { Diff } from "./diff"
|
||||
import { DiffChanges } from "./diff-changes"
|
||||
import { FileIcon } from "./file-icon"
|
||||
import { Icon } from "./icon"
|
||||
import { StickyAccordionHeader } from "./sticky-accordion-header"
|
||||
import { getDirectory, getFilename } from "@opencode-ai/util/path"
|
||||
import { For, Match, Show, Switch, type JSX } from "solid-js"
|
||||
import { For, Match, Show, Switch, ValidComponent, type JSX } from "solid-js"
|
||||
import { createStore } from "solid-js/store"
|
||||
import { type FileDiff } from "@opencode-ai/sdk"
|
||||
import { PreloadMultiFileDiffResult } from "@pierre/precision-diffs/ssr"
|
||||
import { Dynamic } from "solid-js/web"
|
||||
|
||||
export interface SessionReviewProps {
|
||||
split?: boolean
|
||||
|
|
@ -18,6 +18,7 @@ export interface SessionReviewProps {
|
|||
classes?: { root?: string; header?: string; container?: string }
|
||||
actions?: JSX.Element
|
||||
diffs: (FileDiff & { preloaded?: PreloadMultiFileDiffResult<any> })[]
|
||||
diffComponent: ValidComponent
|
||||
}
|
||||
|
||||
export const SessionReview = (props: SessionReviewProps) => {
|
||||
|
|
@ -96,7 +97,8 @@ export const SessionReview = (props: SessionReviewProps) => {
|
|||
</Accordion.Trigger>
|
||||
</StickyAccordionHeader>
|
||||
<Accordion.Content data-slot="session-review-accordion-content">
|
||||
<Diff
|
||||
<Dynamic
|
||||
component={props.diffComponent}
|
||||
preloadedDiff={diff.preloaded}
|
||||
diffStyle={props.split ? "split" : "unified"}
|
||||
before={{
|
||||
|
|
|
|||
|
|
@ -2,7 +2,18 @@ import { AssistantMessage } from "@opencode-ai/sdk"
|
|||
import { useData } from "../context"
|
||||
import { Binary } from "@opencode-ai/util/binary"
|
||||
import { getDirectory, getFilename } from "@opencode-ai/util/path"
|
||||
import { createEffect, createMemo, createSignal, For, Match, onMount, ParentProps, Show, Switch } from "solid-js"
|
||||
import {
|
||||
createEffect,
|
||||
createMemo,
|
||||
createSignal,
|
||||
For,
|
||||
Match,
|
||||
onMount,
|
||||
ParentProps,
|
||||
Show,
|
||||
Switch,
|
||||
ValidComponent,
|
||||
} from "solid-js"
|
||||
import { DiffChanges } from "./diff-changes"
|
||||
import { Typewriter } from "./typewriter"
|
||||
import { Message } from "./message-part"
|
||||
|
|
@ -11,10 +22,10 @@ import { Accordion } from "./accordion"
|
|||
import { StickyAccordionHeader } from "./sticky-accordion-header"
|
||||
import { FileIcon } from "./file-icon"
|
||||
import { Icon } from "./icon"
|
||||
import { Diff } from "./diff"
|
||||
import { Card } from "./card"
|
||||
import { MessageProgress } from "./message-progress"
|
||||
import { Collapsible } from "./collapsible"
|
||||
import { Dynamic } from "solid-js/web"
|
||||
|
||||
export function SessionTurn(
|
||||
props: ParentProps<{
|
||||
|
|
@ -25,6 +36,7 @@ export function SessionTurn(
|
|||
content?: string
|
||||
container?: string
|
||||
}
|
||||
diffComponent: ValidComponent
|
||||
}>,
|
||||
) {
|
||||
const data = useData()
|
||||
|
|
@ -117,7 +129,7 @@ export function SessionTurn(
|
|||
</div>
|
||||
</div>
|
||||
<div data-slot="session-turn-message-content">
|
||||
<Message message={msg()} parts={parts()} sanitize={sanitizer()} />
|
||||
<Message message={msg()} parts={parts()} sanitize={sanitizer()} diffComponent={props.diffComponent} />
|
||||
</div>
|
||||
{/* Summary */}
|
||||
<Show when={completed()}>
|
||||
|
|
@ -167,7 +179,8 @@ export function SessionTurn(
|
|||
</Accordion.Trigger>
|
||||
</StickyAccordionHeader>
|
||||
<Accordion.Content data-slot="session-turn-accordion-content">
|
||||
<Diff
|
||||
<Dynamic
|
||||
component={props.diffComponent}
|
||||
before={{
|
||||
name: diff.file!,
|
||||
contents: diff.before!,
|
||||
|
|
@ -193,7 +206,11 @@ export function SessionTurn(
|
|||
<div data-slot="session-turn-response-section">
|
||||
<Switch>
|
||||
<Match when={!completed()}>
|
||||
<MessageProgress assistantMessages={assistantMessages} done={!messageWorking()} />
|
||||
<MessageProgress
|
||||
assistantMessages={assistantMessages}
|
||||
done={!messageWorking()}
|
||||
diffComponent={props.diffComponent}
|
||||
/>
|
||||
</Match>
|
||||
<Match when={completed() && hasToolPart()}>
|
||||
<Collapsible variant="ghost" open={detailsExpanded()} onOpenChange={setDetailsExpanded}>
|
||||
|
|
@ -224,10 +241,18 @@ export function SessionTurn(
|
|||
message={assistantMessage}
|
||||
parts={parts().filter((p) => p?.id !== last()?.id)}
|
||||
sanitize={sanitizer()}
|
||||
diffComponent={props.diffComponent}
|
||||
/>
|
||||
)
|
||||
}
|
||||
return <Message message={assistantMessage} parts={parts()} sanitize={sanitizer()} />
|
||||
return (
|
||||
<Message
|
||||
message={assistantMessage}
|
||||
parts={parts()}
|
||||
sanitize={sanitizer()}
|
||||
diffComponent={props.diffComponent}
|
||||
/>
|
||||
)
|
||||
}}
|
||||
</For>
|
||||
<Show when={error()}>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,13 @@
|
|||
import { FileDiffOptions } from "@pierre/precision-diffs"
|
||||
import { DiffLineAnnotation, FileContents, FileDiffOptions } from "@pierre/precision-diffs"
|
||||
import { ComponentProps } from "solid-js"
|
||||
|
||||
export type DiffProps<T = {}> = FileDiffOptions<T> & {
|
||||
before: FileContents
|
||||
after: FileContents
|
||||
annotations?: DiffLineAnnotation<T>[]
|
||||
class?: string
|
||||
classList?: ComponentProps<"div">["classList"]
|
||||
}
|
||||
|
||||
export function createDefaultOptions<T>(style: FileDiffOptions<T>["diffStyle"]) {
|
||||
return {
|
||||
5
packages/ui/src/pierre/worker.ts
Normal file
5
packages/ui/src/pierre/worker.ts
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
import ShikiWorkerUrl from "@pierre/precision-diffs/worker/shiki-worker.js?worker&url"
|
||||
|
||||
export function workerFactory(): Worker {
|
||||
return new Worker(ShikiWorkerUrl, { type: "module" })
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opencode-ai/util",
|
||||
"version": "1.0.126",
|
||||
"version": "1.0.127",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"exports": {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "@opencode-ai/web",
|
||||
"type": "module",
|
||||
"version": "1.0.126",
|
||||
"version": "1.0.127",
|
||||
"scripts": {
|
||||
"dev": "astro dev",
|
||||
"dev:remote": "VITE_API_URL=https://api.opencode.ai astro dev",
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
"name": "opencode",
|
||||
"displayName": "opencode",
|
||||
"description": "opencode for VS Code",
|
||||
"version": "1.0.126",
|
||||
"version": "1.0.127",
|
||||
"publisher": "sst-dev",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue