From 04c1730c90e22e7a779b36570c0b7ad779c871b5 Mon Sep 17 00:00:00 2001 From: Victor Navarro Date: Wed, 24 Jun 2026 16:56:09 +0200 Subject: [PATCH] refactor(ui): isolate session components (#33670) --- .github/workflows/storybook.yml | 2 + bun.lock | 53 ++++++++++++++- packages/app/package.json | 1 + packages/app/src/app.tsx | 2 +- .../session/session-context-tab.tsx | 4 +- .../src/context/global-sync/bootstrap.test.ts | 2 +- .../app/src/context/global-sync/bootstrap.ts | 2 +- .../context/global-sync/child-store.test.ts | 2 +- .../src/context/global-sync/child-store.ts | 2 +- packages/app/src/context/global-sync/types.ts | 2 +- packages/app/src/context/global-sync/utils.ts | 2 +- packages/app/src/context/server-sync.tsx | 3 +- packages/app/src/index.css | 1 + packages/app/src/pages/directory-layout.tsx | 2 +- packages/app/src/pages/home.tsx | 2 +- .../src/pages/layout/session-tab-avatar.tsx | 2 +- packages/app/src/pages/session.tsx | 2 +- .../composer/session-permission-dock.tsx | 2 +- .../composer/session-question-dock.tsx | 2 +- .../composer}/todo-panel-motion.stories.tsx | 0 packages/app/src/pages/session/file-tabs.tsx | 6 +- packages/app/src/pages/session/review-tab.tsx | 4 +- .../session/timeline/message-timeline.tsx | 6 +- .../app/src/pages/session/timeline/rows.ts | 2 +- .../pages/session/use-session-commands.tsx | 2 +- packages/enterprise/package.json | 1 + packages/enterprise/src/app.css | 1 + .../enterprise/src/routes/share/[shareID].tsx | 12 ++-- packages/session-ui/package.json | 67 +++++++++++++++++++ .../src/components/apply-patch-file.test.ts | 0 .../src/components/apply-patch-file.ts | 0 .../src/components/basic-tool.css | 0 .../src/components/basic-tool.stories.tsx | 2 +- .../src/components/basic-tool.tsx | 8 +-- .../src/components/dock-prompt.stories.tsx | 2 +- .../src/components/dock-prompt.tsx | 2 +- .../src/components/file-media.tsx | 2 +- .../src/components/file-search.tsx | 4 +- .../src/components/file-ssr.tsx | 2 +- .../src/components/file.css | 0 .../src/components/file.tsx | 0 .../components/line-comment-annotations.tsx | 2 +- .../src/components/line-comment-styles.ts | 0 .../src/components/line-comment.stories.tsx | 0 .../src/components/line-comment.tsx | 8 +-- .../src/components/markdown-cache.tsx | 0 .../components/markdown-code-state.test.ts | 0 .../src/components/markdown-code-state.ts | 0 .../src/components/markdown-preload.test.ts | 0 .../src/components/markdown-shiki.worker.ts | 0 .../src/components/markdown-stream.test.ts | 0 .../src/components/markdown-stream.ts | 0 .../markdown-worker-protocol.test.ts | 0 .../components/markdown-worker-protocol.ts | 0 .../components/markdown-worker-queue.test.ts | 0 .../src/components/markdown-worker-queue.ts | 0 .../markdown-worker-transport.test.ts | 0 .../components/markdown-worker-transport.ts | 0 .../src/components/markdown-worker.ts | 2 +- .../src/components/markdown.css | 0 .../src/components/markdown.stories.tsx | 4 +- .../src/components/markdown.tsx | 4 +- .../src/components/message-file.test.ts | 0 .../src/components/message-file.ts | 0 .../src/components/message-nav.css | 0 .../src/components/message-nav.stories.tsx | 2 +- .../src/components/message-nav.tsx | 4 +- .../src/components/message-part-text.ts | 0 .../src/components/message-part.css | 0 .../src/components/message-part.stories.tsx | 2 +- .../src/components/message-part.test.ts | 0 .../src/components/message-part.tsx | 32 ++++----- .../src/components/session-diff.test.ts | 0 .../src/components/session-diff.ts | 0 .../src/components/session-retry.tsx | 8 +-- .../src/components/session-review.css | 0 .../src/components/session-review.stories.tsx | 2 +- .../src/components/session-review.tsx | 26 +++---- .../src/components/session-turn.css | 0 .../src/components/session-turn.stories.tsx | 2 +- .../src/components/session-turn.tsx | 20 +++--- .../shell-submessage-motion.stories.tsx | 0 .../src/components/shell-submessage.css | 0 .../timeline-playground.stories.tsx | 4 +- .../src/components/tool-count-label.css | 0 .../src/components/tool-count-label.tsx | 2 +- .../src/components/tool-count-summary.css | 0 .../components/tool-count-summary.stories.tsx | 0 .../src/components/tool-count-summary.tsx | 0 .../src/components/tool-error-card.css | 0 .../components/tool-error-card.stories.tsx | 0 .../src/components/tool-error-card.tsx | 12 ++-- .../src/components/tool-status-title.css | 0 .../src/components/tool-status-title.tsx | 2 +- .../{ui => session-ui}/src/context/data.tsx | 2 +- packages/session-ui/src/context/index.ts | 1 + .../src/pierre/comment-hover.ts | 0 .../src/pierre/commented-lines.ts | 0 .../src/pierre/diff-selection.ts | 0 .../src/pierre/file-find.ts | 0 .../src/pierre/file-runtime.ts | 0 .../src/pierre/file-selection.ts | 0 .../{ui => session-ui}/src/pierre/index.ts | 0 .../{ui => session-ui}/src/pierre/media.ts | 0 .../src/pierre/selection-bridge.ts | 0 .../src/pierre/virtualizer.ts | 0 .../{ui => session-ui}/src/pierre/worker.ts | 0 packages/session-ui/src/styles/index.css | 14 ++++ .../src/v2/components/basic-tool-v2.css | 0 .../v2/components/basic-tool-v2.stories.tsx | 0 .../src/v2/components/basic-tool-v2.tsx | 4 +- .../session-progress-indicator-v2.css | 0 .../session-progress-indicator-v2.stories.tsx | 0 .../session-progress-indicator-v2.tsx | 0 .../src/v2/components/tool-error-card-v2.css | 0 .../components/tool-error-card-v2.stories.tsx | 2 +- .../src/v2/components/tool-error-card-v2.tsx | 0 packages/session-ui/tsconfig.json | 19 ++++++ packages/storybook/.storybook/main.ts | 9 ++- .../.storybook/playground-css-plugin.ts | 8 +-- packages/storybook/.storybook/preview.tsx | 1 + packages/storybook/package.json | 1 + packages/ui/package.json | 7 +- packages/ui/src/context/index.ts | 1 - packages/ui/src/styles/index.css | 12 ---- turbo.json | 4 ++ 126 files changed, 294 insertions(+), 142 deletions(-) rename packages/{ui/src/components => app/src/pages/session/composer}/todo-panel-motion.stories.tsx (100%) create mode 100644 packages/session-ui/package.json rename packages/{ui => session-ui}/src/components/apply-patch-file.test.ts (100%) rename packages/{ui => session-ui}/src/components/apply-patch-file.ts (100%) rename packages/{ui => session-ui}/src/components/basic-tool.css (100%) rename packages/{ui => session-ui}/src/components/basic-tool.stories.tsx (97%) rename packages/{ui => session-ui}/src/components/basic-tool.tsx (97%) rename packages/{ui => session-ui}/src/components/dock-prompt.stories.tsx (95%) rename packages/{ui => session-ui}/src/components/dock-prompt.tsx (91%) rename packages/{ui => session-ui}/src/components/file-media.tsx (99%) rename packages/{ui => session-ui}/src/components/file-search.tsx (96%) rename packages/{ui => session-ui}/src/components/file-ssr.tsx (98%) rename packages/{ui => session-ui}/src/components/file.css (100%) rename packages/{ui => session-ui}/src/components/file.tsx (100%) rename packages/{ui => session-ui}/src/components/line-comment-annotations.tsx (99%) rename packages/{ui => session-ui}/src/components/line-comment-styles.ts (100%) rename packages/{ui => session-ui}/src/components/line-comment.stories.tsx (100%) rename packages/{ui => session-ui}/src/components/line-comment.tsx (98%) rename packages/{ui => session-ui}/src/components/markdown-cache.tsx (100%) rename packages/{ui => session-ui}/src/components/markdown-code-state.test.ts (100%) rename packages/{ui => session-ui}/src/components/markdown-code-state.ts (100%) rename packages/{ui => session-ui}/src/components/markdown-preload.test.ts (100%) rename packages/{ui => session-ui}/src/components/markdown-shiki.worker.ts (100%) rename packages/{ui => session-ui}/src/components/markdown-stream.test.ts (100%) rename packages/{ui => session-ui}/src/components/markdown-stream.ts (100%) rename packages/{ui => session-ui}/src/components/markdown-worker-protocol.test.ts (100%) rename packages/{ui => session-ui}/src/components/markdown-worker-protocol.ts (100%) rename packages/{ui => session-ui}/src/components/markdown-worker-queue.test.ts (100%) rename packages/{ui => session-ui}/src/components/markdown-worker-queue.ts (100%) rename packages/{ui => session-ui}/src/components/markdown-worker-transport.test.ts (100%) rename packages/{ui => session-ui}/src/components/markdown-worker-transport.ts (100%) rename packages/{ui => session-ui}/src/components/markdown-worker.ts (98%) rename packages/{ui => session-ui}/src/components/markdown.css (100%) rename packages/{ui => session-ui}/src/components/markdown.stories.tsx (89%) rename packages/{ui => session-ui}/src/components/markdown.tsx (99%) rename packages/{ui => session-ui}/src/components/message-file.test.ts (100%) rename packages/{ui => session-ui}/src/components/message-file.ts (100%) rename packages/{ui => session-ui}/src/components/message-nav.css (100%) rename packages/{ui => session-ui}/src/components/message-nav.stories.tsx (80%) rename packages/{ui => session-ui}/src/components/message-nav.tsx (96%) rename packages/{ui => session-ui}/src/components/message-part-text.ts (100%) rename packages/{ui => session-ui}/src/components/message-part.css (100%) rename packages/{ui => session-ui}/src/components/message-part.stories.tsx (80%) rename packages/{ui => session-ui}/src/components/message-part.test.ts (100%) rename packages/{ui => session-ui}/src/components/message-part.tsx (98%) rename packages/{ui => session-ui}/src/components/session-diff.test.ts (100%) rename packages/{ui => session-ui}/src/components/session-diff.ts (100%) rename packages/{ui => session-ui}/src/components/session-retry.tsx (93%) rename packages/{ui => session-ui}/src/components/session-review.css (100%) rename packages/{ui => session-ui}/src/components/session-review.stories.tsx (81%) rename packages/{ui => session-ui}/src/components/session-review.tsx (97%) rename packages/{ui => session-ui}/src/components/session-turn.css (100%) rename packages/{ui => session-ui}/src/components/session-turn.stories.tsx (80%) rename packages/{ui => session-ui}/src/components/session-turn.tsx (97%) rename packages/{ui => session-ui}/src/components/shell-submessage-motion.stories.tsx (100%) rename packages/{ui => session-ui}/src/components/shell-submessage.css (100%) rename packages/{ui => session-ui}/src/components/timeline-playground.stories.tsx (99%) rename packages/{ui => session-ui}/src/components/tool-count-label.css (100%) rename packages/{ui => session-ui}/src/components/tool-count-label.tsx (97%) rename packages/{ui => session-ui}/src/components/tool-count-summary.css (100%) rename packages/{ui => session-ui}/src/components/tool-count-summary.stories.tsx (100%) rename packages/{ui => session-ui}/src/components/tool-count-summary.tsx (100%) rename packages/{ui => session-ui}/src/components/tool-error-card.css (100%) rename packages/{ui => session-ui}/src/components/tool-error-card.stories.tsx (100%) rename packages/{ui => session-ui}/src/components/tool-error-card.tsx (94%) rename packages/{ui => session-ui}/src/components/tool-status-title.css (100%) rename packages/{ui => session-ui}/src/components/tool-status-title.tsx (98%) rename packages/{ui => session-ui}/src/context/data.tsx (95%) create mode 100644 packages/session-ui/src/context/index.ts rename packages/{ui => session-ui}/src/pierre/comment-hover.ts (100%) rename packages/{ui => session-ui}/src/pierre/commented-lines.ts (100%) rename packages/{ui => session-ui}/src/pierre/diff-selection.ts (100%) rename packages/{ui => session-ui}/src/pierre/file-find.ts (100%) rename packages/{ui => session-ui}/src/pierre/file-runtime.ts (100%) rename packages/{ui => session-ui}/src/pierre/file-selection.ts (100%) rename packages/{ui => session-ui}/src/pierre/index.ts (100%) rename packages/{ui => session-ui}/src/pierre/media.ts (100%) rename packages/{ui => session-ui}/src/pierre/selection-bridge.ts (100%) rename packages/{ui => session-ui}/src/pierre/virtualizer.ts (100%) rename packages/{ui => session-ui}/src/pierre/worker.ts (100%) create mode 100644 packages/session-ui/src/styles/index.css rename packages/{ui => session-ui}/src/v2/components/basic-tool-v2.css (100%) rename packages/{ui => session-ui}/src/v2/components/basic-tool-v2.stories.tsx (100%) rename packages/{ui => session-ui}/src/v2/components/basic-tool-v2.tsx (97%) rename packages/{ui => session-ui}/src/v2/components/session-progress-indicator-v2.css (100%) rename packages/{ui => session-ui}/src/v2/components/session-progress-indicator-v2.stories.tsx (100%) rename packages/{ui => session-ui}/src/v2/components/session-progress-indicator-v2.tsx (100%) rename packages/{ui => session-ui}/src/v2/components/tool-error-card-v2.css (100%) rename packages/{ui => session-ui}/src/v2/components/tool-error-card-v2.stories.tsx (97%) rename packages/{ui => session-ui}/src/v2/components/tool-error-card-v2.tsx (100%) create mode 100644 packages/session-ui/tsconfig.json diff --git a/.github/workflows/storybook.yml b/.github/workflows/storybook.yml index 1e652104d6..be2e099d0e 100644 --- a/.github/workflows/storybook.yml +++ b/.github/workflows/storybook.yml @@ -9,6 +9,7 @@ on: - "bun.lock" - "packages/storybook/**" - "packages/ui/**" + - "packages/session-ui/**" pull_request: branches: [dev] paths: @@ -17,6 +18,7 @@ on: - "bun.lock" - "packages/storybook/**" - "packages/ui/**" + - "packages/session-ui/**" workflow_dispatch: concurrency: diff --git a/bun.lock b/bun.lock index 9dc9eed534..411c09c8ff 100644 --- a/bun.lock +++ b/bun.lock @@ -34,6 +34,7 @@ "@kobalte/core": "catalog:", "@opencode-ai/core": "workspace:*", "@opencode-ai/sdk": "workspace:*", + "@opencode-ai/session-ui": "workspace:*", "@opencode-ai/ui": "workspace:*", "@pierre/trees": "1.0.0-beta.4", "@sentry/solid": "catalog:", @@ -417,6 +418,7 @@ "dependencies": { "@hono/standard-validator": "catalog:", "@opencode-ai/core": "workspace:*", + "@opencode-ai/session-ui": "workspace:*", "@opencode-ai/ui": "workspace:*", "@pierre/diffs": "catalog:", "@solidjs/meta": "catalog:", @@ -703,6 +705,50 @@ "@typescript/native-preview": "catalog:", }, }, + "packages/session-ui": { + "name": "@opencode-ai/session-ui", + "version": "1.17.9", + "dependencies": { + "@kobalte/core": "catalog:", + "@opencode-ai/core": "workspace:*", + "@opencode-ai/sdk": "workspace:*", + "@opencode-ai/ui": "workspace:*", + "@pierre/diffs": "catalog:", + "@shikijs/stream": "catalog:", + "@shikijs/transformers": "3.9.2", + "@solid-primitives/bounds": "0.1.3", + "@solid-primitives/event-listener": "2.4.5", + "@solid-primitives/media": "2.3.3", + "@solid-primitives/resize-observer": "2.1.3", + "@solidjs/meta": "catalog:", + "@solidjs/router": "catalog:", + "diff": "catalog:", + "dompurify": "3.3.1", + "fuzzysort": "catalog:", + "katex": "0.16.27", + "luxon": "catalog:", + "marked": "catalog:", + "marked-katex-extension": "5.1.6", + "marked-shiki": "catalog:", + "morphdom": "2.7.8", + "motion": "12.34.5", + "remeda": "catalog:", + "remend": "catalog:", + "shiki": "catalog:", + "solid-js": "catalog:", + "solid-list": "catalog:", + "strip-ansi": "7.1.2", + }, + "devDependencies": { + "@tsconfig/node22": "catalog:", + "@types/bun": "catalog:", + "@types/katex": "0.16.7", + "@types/luxon": "catalog:", + "@typescript/native-preview": "catalog:", + "typescript": "catalog:", + "vite": "catalog:", + }, + }, "packages/slack": { "name": "@opencode-ai/slack", "version": "1.17.9", @@ -789,6 +835,7 @@ "packages/storybook": { "name": "@opencode-ai/storybook", "devDependencies": { + "@opencode-ai/session-ui": "workspace:*", "@opencode-ai/ui": "workspace:*", "@solidjs/meta": "catalog:", "@storybook/addon-a11y": "^10.2.13", @@ -840,8 +887,6 @@ "version": "1.17.9", "dependencies": { "@kobalte/core": "catalog:", - "@opencode-ai/core": "workspace:*", - "@opencode-ai/sdk": "workspace:*", "@pierre/diffs": "catalog:", "@shikijs/stream": "catalog:", "@shikijs/transformers": "3.9.2", @@ -1825,6 +1870,8 @@ "@opencode-ai/server": ["@opencode-ai/server@workspace:packages/server"], + "@opencode-ai/session-ui": ["@opencode-ai/session-ui@workspace:packages/session-ui"], + "@opencode-ai/slack": ["@opencode-ai/slack@workspace:packages/slack"], "@opencode-ai/stats-app": ["@opencode-ai/stats-app@workspace:packages/stats/app"], @@ -5843,6 +5890,8 @@ "@opencode-ai/llm/@smithy/util-utf8": ["@smithy/util-utf8@4.2.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw=="], + "@opencode-ai/session-ui/@solid-primitives/resize-observer": ["@solid-primitives/resize-observer@2.1.3", "", { "dependencies": { "@solid-primitives/event-listener": "^2.4.3", "@solid-primitives/rootless": "^1.5.2", "@solid-primitives/static-store": "^0.1.2", "@solid-primitives/utils": "^6.3.2" }, "peerDependencies": { "solid-js": "^1.6.12" } }, "sha512-zBLje5E06TgOg93S7rGPldmhDnouNGhvfZVKOp+oG2XU8snA+GoCSSCz1M+jpNAg5Ek2EakU5UVQqL152WmdXQ=="], + "@opencode-ai/ui/@solid-primitives/resize-observer": ["@solid-primitives/resize-observer@2.1.3", "", { "dependencies": { "@solid-primitives/event-listener": "^2.4.3", "@solid-primitives/rootless": "^1.5.2", "@solid-primitives/static-store": "^0.1.2", "@solid-primitives/utils": "^6.3.2" }, "peerDependencies": { "solid-js": "^1.6.12" } }, "sha512-zBLje5E06TgOg93S7rGPldmhDnouNGhvfZVKOp+oG2XU8snA+GoCSSCz1M+jpNAg5Ek2EakU5UVQqL152WmdXQ=="], "@opencode-ai/web/@shikijs/transformers": ["@shikijs/transformers@3.20.0", "", { "dependencies": { "@shikijs/core": "3.20.0", "@shikijs/types": "3.20.0" } }, "sha512-PrHHMRr3Q5W1qB/42kJW6laqFyWdhrPF2hNR9qjOm1xcSiAO3hAHo7HaVyHE6pMyevmy3i51O8kuGGXC78uK3g=="], diff --git a/packages/app/package.json b/packages/app/package.json index e4906b9ea4..b3648e3a9c 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -47,6 +47,7 @@ "@kobalte/core": "catalog:", "@opencode-ai/core": "workspace:*", "@opencode-ai/sdk": "workspace:*", + "@opencode-ai/session-ui": "workspace:*", "@opencode-ai/ui": "workspace:*", "@pierre/trees": "1.0.0-beta.4", "@sentry/solid": "catalog:", diff --git a/packages/app/src/app.tsx b/packages/app/src/app.tsx index 7152e7a0c9..9062b715cc 100644 --- a/packages/app/src/app.tsx +++ b/packages/app/src/app.tsx @@ -4,7 +4,7 @@ import { I18nProvider } from "@opencode-ai/ui/context" import { DialogProvider } from "@opencode-ai/ui/context/dialog" import { FileComponentProvider } from "@opencode-ai/ui/context/file" import { MarkedProvider } from "@opencode-ai/ui/context/marked" -import { File } from "@opencode-ai/ui/file" +import { File } from "@opencode-ai/session-ui/file" import { Font } from "@opencode-ai/ui/font" import { Splash } from "@opencode-ai/ui/logo" import { ThemeProvider } from "@opencode-ai/ui/theme/context" diff --git a/packages/app/src/components/session/session-context-tab.tsx b/packages/app/src/components/session/session-context-tab.tsx index a601928de4..a44bfa2ec7 100644 --- a/packages/app/src/components/session/session-context-tab.tsx +++ b/packages/app/src/components/session/session-context-tab.tsx @@ -7,8 +7,8 @@ import { same } from "@/utils/same" import { Icon } from "@opencode-ai/ui/icon" import { Accordion } from "@opencode-ai/ui/accordion" import { StickyAccordionHeader } from "@opencode-ai/ui/sticky-accordion-header" -import { File } from "@opencode-ai/ui/file" -import { Markdown } from "@opencode-ai/ui/markdown" +import { File } from "@opencode-ai/session-ui/file" +import { Markdown } from "@opencode-ai/session-ui/markdown" import { ScrollView } from "@opencode-ai/ui/scroll-view" import type { Message, Part, UserMessage } from "@opencode-ai/sdk/v2/client" import { useLanguage } from "@/context/language" diff --git a/packages/app/src/context/global-sync/bootstrap.test.ts b/packages/app/src/context/global-sync/bootstrap.test.ts index 8393b04742..2e85f4850a 100644 --- a/packages/app/src/context/global-sync/bootstrap.test.ts +++ b/packages/app/src/context/global-sync/bootstrap.test.ts @@ -2,7 +2,7 @@ import { describe, expect, test } from "bun:test" import { createStore } from "solid-js/store" import { QueryClient } from "@tanstack/solid-query" import type { Config, OpencodeClient, Project } from "@opencode-ai/sdk/v2/client" -import type { NormalizedProviderListResponse } from "@opencode-ai/ui/context" +import type { NormalizedProviderListResponse } from "@opencode-ai/session-ui/context" import { bootstrapDirectory, loadPathQuery, loadProvidersQuery } from "./bootstrap" import type { State, VcsCache } from "./types" import { ServerScope } from "@/utils/server-scope" diff --git a/packages/app/src/context/global-sync/bootstrap.ts b/packages/app/src/context/global-sync/bootstrap.ts index bac9c69280..b24bdda811 100644 --- a/packages/app/src/context/global-sync/bootstrap.ts +++ b/packages/app/src/context/global-sync/bootstrap.ts @@ -19,7 +19,7 @@ import { cmp, normalizeAgentList, normalizeProviderList } from "./utils" import { formatServerError } from "@/utils/server-errors" import { QueryClient, queryOptions } from "@tanstack/solid-query" import { loadMcpQuery } from "../server-sync" -import { NormalizedProviderListResponse } from "@opencode-ai/ui/context" +import { NormalizedProviderListResponse } from "@opencode-ai/session-ui/context" import { ScopedKey, type ServerScope } from "@/utils/server-scope" type GlobalStore = { diff --git a/packages/app/src/context/global-sync/child-store.test.ts b/packages/app/src/context/global-sync/child-store.test.ts index 6d4b14e8c0..31c7519d84 100644 --- a/packages/app/src/context/global-sync/child-store.test.ts +++ b/packages/app/src/context/global-sync/child-store.test.ts @@ -1,7 +1,7 @@ import { beforeAll, describe, expect, mock, test } from "bun:test" import { createRoot, getOwner, type Owner } from "solid-js" import { createStore } from "solid-js/store" -import type { NormalizedProviderListResponse } from "@opencode-ai/ui/context" +import type { NormalizedProviderListResponse } from "@opencode-ai/session-ui/context" import type { State } from "./types" import type { QueryOptionsApi } from "../server-sync" import { ServerScope } from "@/utils/server-scope" diff --git a/packages/app/src/context/global-sync/child-store.ts b/packages/app/src/context/global-sync/child-store.ts index e9ab8fa2a3..65011e8b09 100644 --- a/packages/app/src/context/global-sync/child-store.ts +++ b/packages/app/src/context/global-sync/child-store.ts @@ -17,7 +17,7 @@ import { canDisposeDirectory, pickDirectoriesToEvict } from "./eviction" import { useQuery } from "@tanstack/solid-query" import { QueryOptionsApi } from "../server-sync" import { directoryKey, type DirectoryKey } from "./utils" -import { NormalizedProviderListResponse } from "@opencode-ai/ui/context" +import { NormalizedProviderListResponse } from "@opencode-ai/session-ui/context" import type { ServerScope } from "@/utils/server-scope" export function createChildStoreManager(input: { diff --git a/packages/app/src/context/global-sync/types.ts b/packages/app/src/context/global-sync/types.ts index 8db24b904b..9fb86d6d35 100644 --- a/packages/app/src/context/global-sync/types.ts +++ b/packages/app/src/context/global-sync/types.ts @@ -15,7 +15,7 @@ import type { Todo, VcsInfo, } from "@opencode-ai/sdk/v2/client" -import { NormalizedProviderListResponse } from "@opencode-ai/ui/context" +import { NormalizedProviderListResponse } from "@opencode-ai/session-ui/context" import type { Accessor } from "solid-js" import type { SetStoreFunction, Store } from "solid-js/store" diff --git a/packages/app/src/context/global-sync/utils.ts b/packages/app/src/context/global-sync/utils.ts index 2515a593fb..e54bc88d4d 100644 --- a/packages/app/src/context/global-sync/utils.ts +++ b/packages/app/src/context/global-sync/utils.ts @@ -1,5 +1,5 @@ import type { Agent, Project, ProviderListResponse } from "@opencode-ai/sdk/v2/client" -import { NormalizedProviderListResponse } from "@opencode-ai/ui/context" +import { NormalizedProviderListResponse } from "@opencode-ai/session-ui/context" export { pathKey as directoryKey, type PathKey as DirectoryKey } from "@/utils/path-key" export const cmp = (a: string, b: string) => (a < b ? -1 : a > b ? 1 : 0) diff --git a/packages/app/src/context/server-sync.tsx b/packages/app/src/context/server-sync.tsx index 7d714240f6..db1a57d2b2 100644 --- a/packages/app/src/context/server-sync.tsx +++ b/packages/app/src/context/server-sync.tsx @@ -29,7 +29,8 @@ import { createRefreshQueue } from "./global-sync/queue" import { directoryKey } from "./global-sync/utils" import { PathKey } from "@/utils/path-key" import { createDirSyncContext } from "./directory-sync" -import { createSimpleContext, NormalizedProviderListResponse } from "@opencode-ai/ui/context" +import { createSimpleContext } from "@opencode-ai/ui/context" +import { NormalizedProviderListResponse } from "@opencode-ai/session-ui/context" import { createRefCountMap } from "@/utils/refcount" import { useGlobal } from "./global" import { ServerConnection, useServer } from "./server" diff --git a/packages/app/src/index.css b/packages/app/src/index.css index 467f4ac81e..df7e7f44cf 100644 --- a/packages/app/src/index.css +++ b/packages/app/src/index.css @@ -1,4 +1,5 @@ @import "@opencode-ai/ui/styles/tailwind"; +@import "@opencode-ai/session-ui/styles"; @import "@opencode-ai/ui/v2/styles/tailwind.css"; @font-face { diff --git a/packages/app/src/pages/directory-layout.tsx b/packages/app/src/pages/directory-layout.tsx index 73ed1ac273..b2704c2862 100644 --- a/packages/app/src/pages/directory-layout.tsx +++ b/packages/app/src/pages/directory-layout.tsx @@ -1,4 +1,4 @@ -import { DataProvider } from "@opencode-ai/ui/context" +import { DataProvider } from "@opencode-ai/session-ui/context" import { showToast } from "@/utils/toast" import { base64Encode } from "@opencode-ai/core/util/encode" import { useLocation, useNavigate, useParams } from "@solidjs/router" diff --git a/packages/app/src/pages/home.tsx b/packages/app/src/pages/home.tsx index 907ea91f15..12934aebea 100644 --- a/packages/app/src/pages/home.tsx +++ b/packages/app/src/pages/home.tsx @@ -60,7 +60,7 @@ import { ServerHealthIndicator } from "@/components/server/server-row" import { type ServerHealth } from "@/utils/server-health" import { Persist, persisted } from "@/utils/persist" import { useMarked } from "@opencode-ai/ui/context/marked" -import { preloadMarkdown } from "@opencode-ai/ui/markdown-cache" +import { preloadMarkdown } from "@opencode-ai/session-ui/markdown-cache" const HOME_SESSION_LIMIT = 64 const HOME_ROW_LAYOUT = diff --git a/packages/app/src/pages/layout/session-tab-avatar.tsx b/packages/app/src/pages/layout/session-tab-avatar.tsx index 951bce96e2..bc816fda74 100644 --- a/packages/app/src/pages/layout/session-tab-avatar.tsx +++ b/packages/app/src/pages/layout/session-tab-avatar.tsx @@ -3,7 +3,7 @@ import { getProjectAvatarVariant } from "@/context/layout" import { displayName, getProjectAvatarSource } from "@/pages/layout/helpers" import { useSessionTabAvatarState } from "@/pages/layout/project-avatar-state" import { ProjectAvatar } from "@opencode-ai/ui/v2/project-avatar-v2" -import { SessionProgressIndicatorV2 } from "@opencode-ai/ui/v2/session-progress-indicator-v2" +import { SessionProgressIndicatorV2 } from "@opencode-ai/session-ui/v2/session-progress-indicator-v2" import { Show } from "solid-js" export function SessionTabAvatar(props: { diff --git a/packages/app/src/pages/session.tsx b/packages/app/src/pages/session.tsx index 7528534e56..6c9d1732f9 100644 --- a/packages/app/src/pages/session.tsx +++ b/packages/app/src/pages/session.tsx @@ -25,7 +25,7 @@ import { ResizeHandle } from "@opencode-ai/ui/resize-handle" import { Select } from "@opencode-ai/ui/select" import { Tabs } from "@opencode-ai/ui/tabs" import { createAutoScroll } from "@opencode-ai/ui/hooks" -import { previewSelectedLines } from "@opencode-ai/ui/pierre/selection-bridge" +import { previewSelectedLines } from "@opencode-ai/session-ui/pierre/selection-bridge" import { Button } from "@opencode-ai/ui/button" import { showToast } from "@/utils/toast" import { base64Encode, checksum } from "@opencode-ai/core/util/encode" diff --git a/packages/app/src/pages/session/composer/session-permission-dock.tsx b/packages/app/src/pages/session/composer/session-permission-dock.tsx index 06ff4f4aa7..35a62f75cf 100644 --- a/packages/app/src/pages/session/composer/session-permission-dock.tsx +++ b/packages/app/src/pages/session/composer/session-permission-dock.tsx @@ -1,7 +1,7 @@ import { For, Show } from "solid-js" import type { PermissionRequest } from "@opencode-ai/sdk/v2" import { Button } from "@opencode-ai/ui/button" -import { DockPrompt } from "@opencode-ai/ui/dock-prompt" +import { DockPrompt } from "@opencode-ai/session-ui/dock-prompt" import { Icon } from "@opencode-ai/ui/icon" import { useLanguage } from "@/context/language" diff --git a/packages/app/src/pages/session/composer/session-question-dock.tsx b/packages/app/src/pages/session/composer/session-question-dock.tsx index 5fa0c97fb3..32d2bc4fe5 100644 --- a/packages/app/src/pages/session/composer/session-question-dock.tsx +++ b/packages/app/src/pages/session/composer/session-question-dock.tsx @@ -2,7 +2,7 @@ import { For, Show, createMemo, onCleanup, onMount, type Component } from "solid import { createStore } from "solid-js/store" import { useMutation } from "@tanstack/solid-query" import { Button } from "@opencode-ai/ui/button" -import { DockPrompt } from "@opencode-ai/ui/dock-prompt" +import { DockPrompt } from "@opencode-ai/session-ui/dock-prompt" import { Icon } from "@opencode-ai/ui/icon" import { showToast } from "@/utils/toast" import type { QuestionAnswer, QuestionRequest } from "@opencode-ai/sdk/v2" diff --git a/packages/ui/src/components/todo-panel-motion.stories.tsx b/packages/app/src/pages/session/composer/todo-panel-motion.stories.tsx similarity index 100% rename from packages/ui/src/components/todo-panel-motion.stories.tsx rename to packages/app/src/pages/session/composer/todo-panel-motion.stories.tsx diff --git a/packages/app/src/pages/session/file-tabs.tsx b/packages/app/src/pages/session/file-tabs.tsx index 06d6637b37..7d110ee544 100644 --- a/packages/app/src/pages/session/file-tabs.tsx +++ b/packages/app/src/pages/session/file-tabs.tsx @@ -2,10 +2,10 @@ import { createEffect, createMemo, createSignal, Match, on, onCleanup, Switch } import { createStore } from "solid-js/store" import { Dynamic } from "solid-js/web" import { makeEventListener } from "@solid-primitives/event-listener" -import type { FileSearchHandle } from "@opencode-ai/ui/file" +import type { FileSearchHandle } from "@opencode-ai/session-ui/file" import { useFileComponent } from "@opencode-ai/ui/context/file" -import { cloneSelectedLineRange, previewSelectedLines } from "@opencode-ai/ui/pierre/selection-bridge" -import { createLineCommentController } from "@opencode-ai/ui/line-comment-annotations" +import { cloneSelectedLineRange, previewSelectedLines } from "@opencode-ai/session-ui/pierre/selection-bridge" +import { createLineCommentController } from "@opencode-ai/session-ui/line-comment-annotations" import { sampledChecksum } from "@opencode-ai/core/util/encode" import { DropdownMenu } from "@opencode-ai/ui/dropdown-menu" import { IconButton } from "@opencode-ai/ui/icon-button" diff --git a/packages/app/src/pages/session/review-tab.tsx b/packages/app/src/pages/session/review-tab.tsx index 9b5bf93cd4..3854bf0276 100644 --- a/packages/app/src/pages/session/review-tab.tsx +++ b/packages/app/src/pages/session/review-tab.tsx @@ -1,12 +1,12 @@ import { createEffect, onCleanup, type JSX } from "solid-js" import { makeEventListener } from "@solid-primitives/event-listener" import type { SnapshotFileDiff, VcsFileDiff } from "@opencode-ai/sdk/v2" -import { SessionReview } from "@opencode-ai/ui/session-review" +import { SessionReview } from "@opencode-ai/session-ui/session-review" import type { SessionReviewCommentActions, SessionReviewCommentDelete, SessionReviewCommentUpdate, -} from "@opencode-ai/ui/session-review" +} from "@opencode-ai/session-ui/session-review" import type { SelectedLineRange } from "@/context/file" import { useSDK } from "@/context/sdk" import { useLayout } from "@/context/layout" diff --git a/packages/app/src/pages/session/timeline/message-timeline.tsx b/packages/app/src/pages/session/timeline/message-timeline.tsx index aedfa5b598..e546fedf2b 100644 --- a/packages/app/src/pages/session/timeline/message-timeline.tsx +++ b/packages/app/src/pages/session/timeline/message-timeline.tsx @@ -26,7 +26,7 @@ import { Part as MessagePart, partDefaultOpen, type UserActions, -} from "@opencode-ai/ui/message-part" +} from "@opencode-ai/session-ui/message-part" import { DiffChanges } from "@opencode-ai/ui/diff-changes" import { FileIcon } from "@opencode-ai/ui/file-icon" import { Icon } from "@opencode-ai/ui/icon" @@ -35,7 +35,7 @@ import { DropdownMenu } from "@opencode-ai/ui/dropdown-menu" import { Dialog } from "@opencode-ai/ui/dialog" import { InlineInput } from "@opencode-ai/ui/inline-input" import { Spinner } from "@opencode-ai/ui/spinner" -import { SessionRetry } from "@opencode-ai/ui/session-retry" +import { SessionRetry } from "@opencode-ai/session-ui/session-retry" import { ScrollView } from "@opencode-ai/ui/scroll-view" import { StickyAccordionHeader } from "@opencode-ai/ui/sticky-accordion-header" import { TextField } from "@opencode-ai/ui/text-field" @@ -51,7 +51,7 @@ import type { import { showToast } from "@/utils/toast" import { getDirectory, getFilename } from "@opencode-ai/core/util/path" import { Popover as KobaltePopover } from "@kobalte/core/popover" -import { normalize } from "@opencode-ai/ui/session-diff" +import { normalize } from "@opencode-ai/session-ui/session-diff" import { useFileComponent } from "@opencode-ai/ui/context/file" import { shouldMarkBoundaryGesture, normalizeWheelDelta } from "@/pages/session/message-gesture" import { SessionContextUsage } from "@/components/session-context-usage" diff --git a/packages/app/src/pages/session/timeline/rows.ts b/packages/app/src/pages/session/timeline/rows.ts index bc5719bdcf..5e023b83f4 100644 --- a/packages/app/src/pages/session/timeline/rows.ts +++ b/packages/app/src/pages/session/timeline/rows.ts @@ -1,6 +1,6 @@ import { parseCommentNote, readCommentMetadata } from "@/utils/comment-note" import { AssistantMessage, Part, SessionStatus, SnapshotFileDiff, UserMessage } from "@opencode-ai/sdk/v2" -import { groupParts, PartGroup, renderable } from "@opencode-ai/ui/message-part" +import { groupParts, PartGroup, renderable } from "@opencode-ai/session-ui/message-part" import { Data, Equal } from "effect" export type SummaryDiff = SnapshotFileDiff & { file: string } diff --git a/packages/app/src/pages/session/use-session-commands.tsx b/packages/app/src/pages/session/use-session-commands.tsx index f64c5c26ae..fa35204596 100644 --- a/packages/app/src/pages/session/use-session-commands.tsx +++ b/packages/app/src/pages/session/use-session-commands.tsx @@ -1,7 +1,7 @@ import { useNavigate } from "@solidjs/router" import { useCommand, type CommandOption } from "@/context/command" import { useDialog } from "@opencode-ai/ui/context/dialog" -import { previewSelectedLines } from "@opencode-ai/ui/pierre/selection-bridge" +import { previewSelectedLines } from "@opencode-ai/session-ui/pierre/selection-bridge" import { useFile, selectionFromLines, type FileSelection, type SelectedLineRange } from "@/context/file" import { useLanguage } from "@/context/language" import { useLayout } from "@/context/layout" diff --git a/packages/enterprise/package.json b/packages/enterprise/package.json index 69534b07f7..0ba9259e12 100644 --- a/packages/enterprise/package.json +++ b/packages/enterprise/package.json @@ -14,6 +14,7 @@ }, "dependencies": { "@opencode-ai/core": "workspace:*", + "@opencode-ai/session-ui": "workspace:*", "@opencode-ai/ui": "workspace:*", "aws4fetch": "^1.0.20", "@pierre/diffs": "catalog:", diff --git a/packages/enterprise/src/app.css b/packages/enterprise/src/app.css index 4af87bca63..1d3a4abf85 100644 --- a/packages/enterprise/src/app.css +++ b/packages/enterprise/src/app.css @@ -1 +1,2 @@ @import "@opencode-ai/ui/styles/tailwind"; +@import "@opencode-ai/session-ui/styles"; diff --git a/packages/enterprise/src/routes/share/[shareID].tsx b/packages/enterprise/src/routes/share/[shareID].tsx index 6d83fb4598..8c8ac59f7a 100644 --- a/packages/enterprise/src/routes/share/[shareID].tsx +++ b/packages/enterprise/src/routes/share/[shareID].tsx @@ -1,7 +1,7 @@ import { Message, Model, Part, Session, SessionStatus, SnapshotFileDiff, UserMessage } from "@opencode-ai/sdk/v2" -import { SessionTurn } from "@opencode-ai/ui/session-turn" -import { SessionReview } from "@opencode-ai/ui/session-review" -import { DataProvider } from "@opencode-ai/ui/context" +import { SessionTurn } from "@opencode-ai/session-ui/session-turn" +import { SessionReview } from "@opencode-ai/session-ui/session-review" +import { DataProvider } from "@opencode-ai/session-ui/context" import { FileComponentProvider } from "@opencode-ai/ui/context/file" import { WorkerPoolProvider } from "@opencode-ai/ui/context/worker-pool" import { createAsync, query, useParams } from "@solidjs/router" @@ -17,15 +17,15 @@ import { DateTime } from "luxon" import { createStore } from "solid-js/store" import NotFound from "../[...404]" import { Tabs } from "@opencode-ai/ui/tabs" -import { MessageNav } from "@opencode-ai/ui/message-nav" -import { FileSSR } from "@opencode-ai/ui/file-ssr" +import { MessageNav } from "@opencode-ai/session-ui/message-nav" +import { FileSSR } from "@opencode-ai/session-ui/file-ssr" import { clientOnly } from "@solidjs/start" import { Meta, Title } from "@solidjs/meta" import { Base64 } from "js-base64" import { getRequestEvent } from "solid-js/web" const ClientOnlyWorkerPoolProvider = clientOnly(() => - import("@opencode-ai/ui/pierre/worker").then((m) => ({ + import("@opencode-ai/session-ui/pierre/worker").then((m) => ({ default: (props: { children: any }) => ( {props.children} ), diff --git a/packages/session-ui/package.json b/packages/session-ui/package.json new file mode 100644 index 0000000000..e2b579b426 --- /dev/null +++ b/packages/session-ui/package.json @@ -0,0 +1,67 @@ +{ + "name": "@opencode-ai/session-ui", + "version": "1.17.9", + "private": true, + "type": "module", + "license": "MIT", + "exports": { + "./*": "./src/components/*.tsx", + "./session-diff": "./src/components/session-diff.ts", + "./message-file": "./src/components/message-file.ts", + "./message-part-text": "./src/components/message-part-text.ts", + "./markdown-stream": "./src/components/markdown-stream.ts", + "./markdown-cache": "./src/components/markdown-cache.tsx", + "./line-comment-styles": "./src/components/line-comment-styles.ts", + "./pierre": "./src/pierre/index.ts", + "./pierre/*": "./src/pierre/*.ts", + "./context": "./src/context/index.ts", + "./context/*": "./src/context/*.tsx", + "./styles": "./src/styles/index.css", + "./v2/*.css": "./src/v2/components/*.css", + "./v2/*": "./src/v2/components/*.tsx" + }, + "scripts": { + "typecheck": "tsgo --noEmit", + "test": "bun test src --only-failures" + }, + "devDependencies": { + "@tsconfig/node22": "catalog:", + "@types/bun": "catalog:", + "@types/katex": "0.16.7", + "@types/luxon": "catalog:", + "@typescript/native-preview": "catalog:", + "typescript": "catalog:", + "vite": "catalog:" + }, + "dependencies": { + "@kobalte/core": "catalog:", + "@opencode-ai/core": "workspace:*", + "@opencode-ai/sdk": "workspace:*", + "@opencode-ai/ui": "workspace:*", + "@pierre/diffs": "catalog:", + "@shikijs/stream": "catalog:", + "@shikijs/transformers": "3.9.2", + "@solid-primitives/bounds": "0.1.3", + "@solid-primitives/event-listener": "2.4.5", + "@solid-primitives/media": "2.3.3", + "@solid-primitives/resize-observer": "2.1.3", + "@solidjs/meta": "catalog:", + "@solidjs/router": "catalog:", + "diff": "catalog:", + "dompurify": "3.3.1", + "fuzzysort": "catalog:", + "katex": "0.16.27", + "luxon": "catalog:", + "marked": "catalog:", + "marked-katex-extension": "5.1.6", + "marked-shiki": "catalog:", + "morphdom": "2.7.8", + "motion": "12.34.5", + "remeda": "catalog:", + "remend": "catalog:", + "shiki": "catalog:", + "solid-js": "catalog:", + "solid-list": "catalog:", + "strip-ansi": "7.1.2" + } +} diff --git a/packages/ui/src/components/apply-patch-file.test.ts b/packages/session-ui/src/components/apply-patch-file.test.ts similarity index 100% rename from packages/ui/src/components/apply-patch-file.test.ts rename to packages/session-ui/src/components/apply-patch-file.test.ts diff --git a/packages/ui/src/components/apply-patch-file.ts b/packages/session-ui/src/components/apply-patch-file.ts similarity index 100% rename from packages/ui/src/components/apply-patch-file.ts rename to packages/session-ui/src/components/apply-patch-file.ts diff --git a/packages/ui/src/components/basic-tool.css b/packages/session-ui/src/components/basic-tool.css similarity index 100% rename from packages/ui/src/components/basic-tool.css rename to packages/session-ui/src/components/basic-tool.css diff --git a/packages/ui/src/components/basic-tool.stories.tsx b/packages/session-ui/src/components/basic-tool.stories.tsx similarity index 97% rename from packages/ui/src/components/basic-tool.stories.tsx rename to packages/session-ui/src/components/basic-tool.stories.tsx index 9d9d97acfe..5fb366c016 100644 --- a/packages/ui/src/components/basic-tool.stories.tsx +++ b/packages/session-ui/src/components/basic-tool.stories.tsx @@ -1,7 +1,7 @@ // @ts-nocheck import { createSignal } from "solid-js" import * as mod from "./basic-tool" -import { create } from "../storybook/scaffold" +import { create } from "@opencode-ai/ui/storybook/scaffold" const docs = `### Overview Expandable tool panel with a structured trigger and optional details. diff --git a/packages/ui/src/components/basic-tool.tsx b/packages/session-ui/src/components/basic-tool.tsx similarity index 97% rename from packages/ui/src/components/basic-tool.tsx rename to packages/session-ui/src/components/basic-tool.tsx index 2477ff99b5..4f2a4ced6f 100644 --- a/packages/ui/src/components/basic-tool.tsx +++ b/packages/session-ui/src/components/basic-tool.tsx @@ -1,10 +1,10 @@ import { createEffect, For, Match, on, onCleanup, onMount, Show, Switch, type Accessor, type JSX } from "solid-js" import { animate, type AnimationPlaybackControls } from "motion" -import { useI18n } from "../context/i18n" +import { useI18n } from "@opencode-ai/ui/context/i18n" import { createStore } from "solid-js/store" -import { Collapsible } from "./collapsible" -import type { IconProps } from "./icon" -import { TextShimmer } from "./text-shimmer" +import { Collapsible } from "@opencode-ai/ui/collapsible" +import type { IconProps } from "@opencode-ai/ui/icon" +import { TextShimmer } from "@opencode-ai/ui/text-shimmer" export type TriggerTitle = { title: string diff --git a/packages/ui/src/components/dock-prompt.stories.tsx b/packages/session-ui/src/components/dock-prompt.stories.tsx similarity index 95% rename from packages/ui/src/components/dock-prompt.stories.tsx rename to packages/session-ui/src/components/dock-prompt.stories.tsx index de017a1ba2..f75b04bc21 100644 --- a/packages/ui/src/components/dock-prompt.stories.tsx +++ b/packages/session-ui/src/components/dock-prompt.stories.tsx @@ -1,6 +1,6 @@ // @ts-nocheck import * as mod from "./dock-prompt" -import { create } from "../storybook/scaffold" +import { create } from "@opencode-ai/ui/storybook/scaffold" const docs = `### Overview Docked prompt layout for questions and permission requests. diff --git a/packages/ui/src/components/dock-prompt.tsx b/packages/session-ui/src/components/dock-prompt.tsx similarity index 91% rename from packages/ui/src/components/dock-prompt.tsx rename to packages/session-ui/src/components/dock-prompt.tsx index 01f1848c84..75563e47b8 100644 --- a/packages/ui/src/components/dock-prompt.tsx +++ b/packages/session-ui/src/components/dock-prompt.tsx @@ -1,5 +1,5 @@ import type { JSX } from "solid-js" -import { DockShell, DockTray } from "./dock-surface" +import { DockShell, DockTray } from "@opencode-ai/ui/dock-surface" export function DockPrompt(props: { kind: "question" | "permission" diff --git a/packages/ui/src/components/file-media.tsx b/packages/session-ui/src/components/file-media.tsx similarity index 99% rename from packages/ui/src/components/file-media.tsx rename to packages/session-ui/src/components/file-media.tsx index f066019d72..7e26853f08 100644 --- a/packages/ui/src/components/file-media.tsx +++ b/packages/session-ui/src/components/file-media.tsx @@ -1,6 +1,6 @@ import type { FileContent } from "@opencode-ai/sdk/v2" import { createEffect, createMemo, createResource, Match, on, Show, Switch, type JSX } from "solid-js" -import { useI18n } from "../context/i18n" +import { useI18n } from "@opencode-ai/ui/context/i18n" import { dataUrlFromMediaValue, hasMediaValue, diff --git a/packages/ui/src/components/file-search.tsx b/packages/session-ui/src/components/file-search.tsx similarity index 96% rename from packages/ui/src/components/file-search.tsx rename to packages/session-ui/src/components/file-search.tsx index 244e9c2733..181ff9fea8 100644 --- a/packages/ui/src/components/file-search.tsx +++ b/packages/session-ui/src/components/file-search.tsx @@ -1,6 +1,6 @@ import { Portal } from "solid-js/web" -import { useI18n } from "../context/i18n" -import { Icon } from "./icon" +import { useI18n } from "@opencode-ai/ui/context/i18n" +import { Icon } from "@opencode-ai/ui/icon" export function FileSearchBar(props: { pos: () => { top: number; right: number } diff --git a/packages/ui/src/components/file-ssr.tsx b/packages/session-ui/src/components/file-ssr.tsx similarity index 98% rename from packages/ui/src/components/file-ssr.tsx rename to packages/session-ui/src/components/file-ssr.tsx index 6f11ca2433..68b5568edc 100644 --- a/packages/ui/src/components/file-ssr.tsx +++ b/packages/session-ui/src/components/file-ssr.tsx @@ -2,7 +2,7 @@ import { DIFFS_TAG_NAME, FileDiff, VirtualizedFileDiff } from "@pierre/diffs" import { type PreloadFileDiffResult, type PreloadMultiFileDiffResult } from "@pierre/diffs/ssr" import { createEffect, onCleanup, onMount, Show, splitProps } from "solid-js" import { Dynamic, isServer } from "solid-js/web" -import { useWorkerPool } from "../context/worker-pool" +import { useWorkerPool } from "@opencode-ai/ui/context/worker-pool" import { createDefaultOptions, styleVariables } from "../pierre" import { markCommentedDiffLines } from "../pierre/commented-lines" import { fixDiffSelection } from "../pierre/diff-selection" diff --git a/packages/ui/src/components/file.css b/packages/session-ui/src/components/file.css similarity index 100% rename from packages/ui/src/components/file.css rename to packages/session-ui/src/components/file.css diff --git a/packages/ui/src/components/file.tsx b/packages/session-ui/src/components/file.tsx similarity index 100% rename from packages/ui/src/components/file.tsx rename to packages/session-ui/src/components/file.tsx diff --git a/packages/ui/src/components/line-comment-annotations.tsx b/packages/session-ui/src/components/line-comment-annotations.tsx similarity index 99% rename from packages/ui/src/components/line-comment-annotations.tsx rename to packages/session-ui/src/components/line-comment-annotations.tsx index c8fe70c758..edff8c00ad 100644 --- a/packages/ui/src/components/line-comment-annotations.tsx +++ b/packages/session-ui/src/components/line-comment-annotations.tsx @@ -2,7 +2,7 @@ import { type DiffLineAnnotation, type SelectedLineRange } from "@pierre/diffs" import { createEffect, createMemo, createSignal, onCleanup, Show, type Accessor, type JSX } from "solid-js" import { createStore } from "solid-js/store" import { render as renderSolid } from "solid-js/web" -import { useI18n } from "../context/i18n" +import { useI18n } from "@opencode-ai/ui/context/i18n" import { createHoverCommentUtility } from "../pierre/comment-hover" import { cloneSelectedLineRange, formatSelectedLineLabel, lineInSelectedRange } from "../pierre/selection-bridge" import { LineComment, LineCommentEditor, type LineCommentEditorProps } from "./line-comment" diff --git a/packages/ui/src/components/line-comment-styles.ts b/packages/session-ui/src/components/line-comment-styles.ts similarity index 100% rename from packages/ui/src/components/line-comment-styles.ts rename to packages/session-ui/src/components/line-comment-styles.ts diff --git a/packages/ui/src/components/line-comment.stories.tsx b/packages/session-ui/src/components/line-comment.stories.tsx similarity index 100% rename from packages/ui/src/components/line-comment.stories.tsx rename to packages/session-ui/src/components/line-comment.stories.tsx diff --git a/packages/ui/src/components/line-comment.tsx b/packages/session-ui/src/components/line-comment.tsx similarity index 98% rename from packages/ui/src/components/line-comment.tsx rename to packages/session-ui/src/components/line-comment.tsx index 983cf0ed10..0ad1a590e7 100644 --- a/packages/ui/src/components/line-comment.tsx +++ b/packages/session-ui/src/components/line-comment.tsx @@ -1,11 +1,11 @@ import { useFilteredList } from "@opencode-ai/ui/hooks" import { getDirectory, getFilename } from "@opencode-ai/core/util/path" import { createSignal, For, onMount, Show, splitProps, type JSX } from "solid-js" -import { Button } from "./button" -import { FileIcon } from "./file-icon" -import { Icon } from "./icon" +import { Button } from "@opencode-ai/ui/button" +import { FileIcon } from "@opencode-ai/ui/file-icon" +import { Icon } from "@opencode-ai/ui/icon" import { installLineCommentStyles } from "./line-comment-styles" -import { useI18n } from "../context/i18n" +import { useI18n } from "@opencode-ai/ui/context/i18n" installLineCommentStyles() diff --git a/packages/ui/src/components/markdown-cache.tsx b/packages/session-ui/src/components/markdown-cache.tsx similarity index 100% rename from packages/ui/src/components/markdown-cache.tsx rename to packages/session-ui/src/components/markdown-cache.tsx diff --git a/packages/ui/src/components/markdown-code-state.test.ts b/packages/session-ui/src/components/markdown-code-state.test.ts similarity index 100% rename from packages/ui/src/components/markdown-code-state.test.ts rename to packages/session-ui/src/components/markdown-code-state.test.ts diff --git a/packages/ui/src/components/markdown-code-state.ts b/packages/session-ui/src/components/markdown-code-state.ts similarity index 100% rename from packages/ui/src/components/markdown-code-state.ts rename to packages/session-ui/src/components/markdown-code-state.ts diff --git a/packages/ui/src/components/markdown-preload.test.ts b/packages/session-ui/src/components/markdown-preload.test.ts similarity index 100% rename from packages/ui/src/components/markdown-preload.test.ts rename to packages/session-ui/src/components/markdown-preload.test.ts diff --git a/packages/ui/src/components/markdown-shiki.worker.ts b/packages/session-ui/src/components/markdown-shiki.worker.ts similarity index 100% rename from packages/ui/src/components/markdown-shiki.worker.ts rename to packages/session-ui/src/components/markdown-shiki.worker.ts diff --git a/packages/ui/src/components/markdown-stream.test.ts b/packages/session-ui/src/components/markdown-stream.test.ts similarity index 100% rename from packages/ui/src/components/markdown-stream.test.ts rename to packages/session-ui/src/components/markdown-stream.test.ts diff --git a/packages/ui/src/components/markdown-stream.ts b/packages/session-ui/src/components/markdown-stream.ts similarity index 100% rename from packages/ui/src/components/markdown-stream.ts rename to packages/session-ui/src/components/markdown-stream.ts diff --git a/packages/ui/src/components/markdown-worker-protocol.test.ts b/packages/session-ui/src/components/markdown-worker-protocol.test.ts similarity index 100% rename from packages/ui/src/components/markdown-worker-protocol.test.ts rename to packages/session-ui/src/components/markdown-worker-protocol.test.ts diff --git a/packages/ui/src/components/markdown-worker-protocol.ts b/packages/session-ui/src/components/markdown-worker-protocol.ts similarity index 100% rename from packages/ui/src/components/markdown-worker-protocol.ts rename to packages/session-ui/src/components/markdown-worker-protocol.ts diff --git a/packages/ui/src/components/markdown-worker-queue.test.ts b/packages/session-ui/src/components/markdown-worker-queue.test.ts similarity index 100% rename from packages/ui/src/components/markdown-worker-queue.test.ts rename to packages/session-ui/src/components/markdown-worker-queue.test.ts diff --git a/packages/ui/src/components/markdown-worker-queue.ts b/packages/session-ui/src/components/markdown-worker-queue.ts similarity index 100% rename from packages/ui/src/components/markdown-worker-queue.ts rename to packages/session-ui/src/components/markdown-worker-queue.ts diff --git a/packages/ui/src/components/markdown-worker-transport.test.ts b/packages/session-ui/src/components/markdown-worker-transport.test.ts similarity index 100% rename from packages/ui/src/components/markdown-worker-transport.test.ts rename to packages/session-ui/src/components/markdown-worker-transport.test.ts diff --git a/packages/ui/src/components/markdown-worker-transport.ts b/packages/session-ui/src/components/markdown-worker-transport.ts similarity index 100% rename from packages/ui/src/components/markdown-worker-transport.ts rename to packages/session-ui/src/components/markdown-worker-transport.ts diff --git a/packages/ui/src/components/markdown-worker.ts b/packages/session-ui/src/components/markdown-worker.ts similarity index 98% rename from packages/ui/src/components/markdown-worker.ts rename to packages/session-ui/src/components/markdown-worker.ts index a48e98bbd0..1ca87467bb 100644 --- a/packages/ui/src/components/markdown-worker.ts +++ b/packages/session-ui/src/components/markdown-worker.ts @@ -1,5 +1,5 @@ import MarkdownShikiWorkerUrl from "./markdown-shiki.worker.ts?worker&url" -import { OpenCodeTheme } from "../context/marked" +import { OpenCodeTheme } from "@opencode-ai/ui/context/marked" import { applyMarkdownWorkerResponse, shouldReleaseMarkdownWorkerState, diff --git a/packages/ui/src/components/markdown.css b/packages/session-ui/src/components/markdown.css similarity index 100% rename from packages/ui/src/components/markdown.css rename to packages/session-ui/src/components/markdown.css diff --git a/packages/ui/src/components/markdown.stories.tsx b/packages/session-ui/src/components/markdown.stories.tsx similarity index 89% rename from packages/ui/src/components/markdown.stories.tsx rename to packages/session-ui/src/components/markdown.stories.tsx index cae4294869..c4f99dc2f1 100644 --- a/packages/ui/src/components/markdown.stories.tsx +++ b/packages/session-ui/src/components/markdown.stories.tsx @@ -1,7 +1,7 @@ // @ts-nocheck import * as mod from "./markdown" -import { create } from "../storybook/scaffold" -import { markdown } from "../storybook/fixtures" +import { create } from "@opencode-ai/ui/storybook/scaffold" +import { markdown } from "@opencode-ai/ui/storybook/fixtures" const docs = `### Overview Render sanitized Markdown with code blocks, inline code, and safe links. diff --git a/packages/ui/src/components/markdown.tsx b/packages/session-ui/src/components/markdown.tsx similarity index 99% rename from packages/ui/src/components/markdown.tsx rename to packages/session-ui/src/components/markdown.tsx index ee21803851..97dc9e1062 100644 --- a/packages/ui/src/components/markdown.tsx +++ b/packages/session-ui/src/components/markdown.tsx @@ -1,5 +1,5 @@ -import { useMarked } from "../context/marked" -import { useI18n } from "../context/i18n" +import { useMarked } from "@opencode-ai/ui/context/marked" +import { useI18n } from "@opencode-ai/ui/context/i18n" import morphdom from "morphdom" import { checksum } from "@opencode-ai/core/util/encode" import { diff --git a/packages/ui/src/components/message-file.test.ts b/packages/session-ui/src/components/message-file.test.ts similarity index 100% rename from packages/ui/src/components/message-file.test.ts rename to packages/session-ui/src/components/message-file.test.ts diff --git a/packages/ui/src/components/message-file.ts b/packages/session-ui/src/components/message-file.ts similarity index 100% rename from packages/ui/src/components/message-file.ts rename to packages/session-ui/src/components/message-file.ts diff --git a/packages/ui/src/components/message-nav.css b/packages/session-ui/src/components/message-nav.css similarity index 100% rename from packages/ui/src/components/message-nav.css rename to packages/session-ui/src/components/message-nav.css diff --git a/packages/ui/src/components/message-nav.stories.tsx b/packages/session-ui/src/components/message-nav.stories.tsx similarity index 80% rename from packages/ui/src/components/message-nav.stories.tsx rename to packages/session-ui/src/components/message-nav.stories.tsx index 7ce31a7bed..2bd4532506 100644 --- a/packages/ui/src/components/message-nav.stories.tsx +++ b/packages/session-ui/src/components/message-nav.stories.tsx @@ -1,6 +1,6 @@ // @ts-nocheck import * as mod from "./message-nav" -import { create } from "../storybook/scaffold" +import { create } from "@opencode-ai/ui/storybook/scaffold" const story = create({ title: "UI/MessageNav", mod }) export default { title: "UI/MessageNav", id: "components-message-nav", component: story.meta.component } diff --git a/packages/ui/src/components/message-nav.tsx b/packages/session-ui/src/components/message-nav.tsx similarity index 96% rename from packages/ui/src/components/message-nav.tsx rename to packages/session-ui/src/components/message-nav.tsx index 4a061c90a6..85db1e1bcd 100644 --- a/packages/ui/src/components/message-nav.tsx +++ b/packages/session-ui/src/components/message-nav.tsx @@ -1,8 +1,8 @@ import { UserMessage } from "@opencode-ai/sdk/v2" import { HoverCard } from "@kobalte/core/hover-card" import { ComponentProps, For, Match, Show, createSignal, splitProps, Switch } from "solid-js" -import { DiffChanges } from "./diff-changes" -import { useI18n } from "../context/i18n" +import { DiffChanges } from "@opencode-ai/ui/diff-changes" +import { useI18n } from "@opencode-ai/ui/context/i18n" export function MessageNav( props: ComponentProps<"ul"> & { diff --git a/packages/ui/src/components/message-part-text.ts b/packages/session-ui/src/components/message-part-text.ts similarity index 100% rename from packages/ui/src/components/message-part-text.ts rename to packages/session-ui/src/components/message-part-text.ts diff --git a/packages/ui/src/components/message-part.css b/packages/session-ui/src/components/message-part.css similarity index 100% rename from packages/ui/src/components/message-part.css rename to packages/session-ui/src/components/message-part.css diff --git a/packages/ui/src/components/message-part.stories.tsx b/packages/session-ui/src/components/message-part.stories.tsx similarity index 80% rename from packages/ui/src/components/message-part.stories.tsx rename to packages/session-ui/src/components/message-part.stories.tsx index 28489dc7b1..f32f8b281f 100644 --- a/packages/ui/src/components/message-part.stories.tsx +++ b/packages/session-ui/src/components/message-part.stories.tsx @@ -1,6 +1,6 @@ // @ts-nocheck import * as mod from "./message-part" -import { create } from "../storybook/scaffold" +import { create } from "@opencode-ai/ui/storybook/scaffold" const story = create({ title: "UI/MessagePart", mod }) export default { title: "UI/MessagePart", id: "components-message-part", component: story.meta.component } diff --git a/packages/ui/src/components/message-part.test.ts b/packages/session-ui/src/components/message-part.test.ts similarity index 100% rename from packages/ui/src/components/message-part.test.ts rename to packages/session-ui/src/components/message-part.test.ts diff --git a/packages/ui/src/components/message-part.tsx b/packages/session-ui/src/components/message-part.tsx similarity index 98% rename from packages/ui/src/components/message-part.tsx rename to packages/session-ui/src/components/message-part.tsx index 47ae745e4c..4af05c2584 100644 --- a/packages/ui/src/components/message-part.tsx +++ b/packages/session-ui/src/components/message-part.tsx @@ -31,26 +31,26 @@ import { QuestionInfo, } from "@opencode-ai/sdk/v2" import { useData } from "../context" -import { useFileComponent } from "../context/file" -import { useDialog } from "../context/dialog" -import { type UiI18n, useI18n } from "../context/i18n" +import { useFileComponent } from "@opencode-ai/ui/context/file" +import { useDialog } from "@opencode-ai/ui/context/dialog" +import { type UiI18n, useI18n } from "@opencode-ai/ui/context/i18n" import { BasicTool, GenericTool } from "./basic-tool" -import { Accordion } from "./accordion" -import { StickyAccordionHeader } from "./sticky-accordion-header" -import { Collapsible } from "./collapsible" -import { FileIcon } from "./file-icon" -import { Icon } from "./icon" +import { Accordion } from "@opencode-ai/ui/accordion" +import { StickyAccordionHeader } from "@opencode-ai/ui/sticky-accordion-header" +import { Collapsible } from "@opencode-ai/ui/collapsible" +import { FileIcon } from "@opencode-ai/ui/file-icon" +import { Icon } from "@opencode-ai/ui/icon" import { ToolErrorCard } from "./tool-error-card" -import { Checkbox } from "./checkbox" -import { DiffChanges } from "./diff-changes" +import { Checkbox } from "@opencode-ai/ui/checkbox" +import { DiffChanges } from "@opencode-ai/ui/diff-changes" import { Markdown } from "./markdown" -import { ImagePreview } from "./image-preview" +import { ImagePreview } from "@opencode-ai/ui/image-preview" import { getDirectory as _getDirectory, getFilename } from "@opencode-ai/core/util/path" import { checksum } from "@opencode-ai/core/util/encode" -import { Tooltip } from "./tooltip" -import { IconButton } from "./icon-button" -import { Spinner } from "./spinner" -import { TextShimmer } from "./text-shimmer" +import { Tooltip } from "@opencode-ai/ui/tooltip" +import { IconButton } from "@opencode-ai/ui/icon-button" +import { Spinner } from "@opencode-ai/ui/spinner" +import { TextShimmer } from "@opencode-ai/ui/text-shimmer" import { AnimatedCountList } from "./tool-count-summary" import { ToolStatusTitle } from "./tool-status-title" import { patchFiles } from "./apply-patch-file" @@ -303,7 +303,7 @@ function getDirectory(path: string | undefined) { return relativizeProjectPath(_getDirectory(path), data.directory) } -import type { IconProps } from "./icon" +import type { IconProps } from "@opencode-ai/ui/icon" import { normalize, resolveFileDiff } from "./session-diff" export type ToolInfo = { diff --git a/packages/ui/src/components/session-diff.test.ts b/packages/session-ui/src/components/session-diff.test.ts similarity index 100% rename from packages/ui/src/components/session-diff.test.ts rename to packages/session-ui/src/components/session-diff.test.ts diff --git a/packages/ui/src/components/session-diff.ts b/packages/session-ui/src/components/session-diff.ts similarity index 100% rename from packages/ui/src/components/session-diff.ts rename to packages/session-ui/src/components/session-diff.ts diff --git a/packages/ui/src/components/session-retry.tsx b/packages/session-ui/src/components/session-retry.tsx similarity index 93% rename from packages/ui/src/components/session-retry.tsx rename to packages/session-ui/src/components/session-retry.tsx index ac0eb035d9..cf2d6c9459 100644 --- a/packages/ui/src/components/session-retry.tsx +++ b/packages/session-ui/src/components/session-retry.tsx @@ -1,9 +1,9 @@ import { createEffect, createMemo, createSignal, on, onCleanup, Show } from "solid-js" import type { SessionStatus } from "@opencode-ai/sdk/v2/client" -import { useI18n } from "../context/i18n" -import { Card } from "./card" -import { Tooltip } from "./tooltip" -import { Spinner } from "./spinner" +import { useI18n } from "@opencode-ai/ui/context/i18n" +import { Card } from "@opencode-ai/ui/card" +import { Tooltip } from "@opencode-ai/ui/tooltip" +import { Spinner } from "@opencode-ai/ui/spinner" export function SessionRetry(props: { status: SessionStatus; show?: boolean }) { const i18n = useI18n() diff --git a/packages/ui/src/components/session-review.css b/packages/session-ui/src/components/session-review.css similarity index 100% rename from packages/ui/src/components/session-review.css rename to packages/session-ui/src/components/session-review.css diff --git a/packages/ui/src/components/session-review.stories.tsx b/packages/session-ui/src/components/session-review.stories.tsx similarity index 81% rename from packages/ui/src/components/session-review.stories.tsx rename to packages/session-ui/src/components/session-review.stories.tsx index 7ab1eb2038..c09717384c 100644 --- a/packages/ui/src/components/session-review.stories.tsx +++ b/packages/session-ui/src/components/session-review.stories.tsx @@ -1,6 +1,6 @@ // @ts-nocheck import * as mod from "./session-review" -import { create } from "../storybook/scaffold" +import { create } from "@opencode-ai/ui/storybook/scaffold" const story = create({ title: "UI/SessionReview", mod }) export default { title: "UI/SessionReview", id: "components-session-review", component: story.meta.component } diff --git a/packages/ui/src/components/session-review.tsx b/packages/session-ui/src/components/session-review.tsx similarity index 97% rename from packages/ui/src/components/session-review.tsx rename to packages/session-ui/src/components/session-review.tsx index 7aad942c5d..8db21f025b 100644 --- a/packages/ui/src/components/session-review.tsx +++ b/packages/session-ui/src/components/session-review.tsx @@ -1,16 +1,16 @@ -import { Accordion } from "./accordion" -import { Button } from "./button" -import { DropdownMenu } from "./dropdown-menu" -import { RadioGroup } from "./radio-group" -import { DiffChanges } from "./diff-changes" -import { FileIcon } from "./file-icon" -import { Icon } from "./icon" -import { IconButton } from "./icon-button" -import { StickyAccordionHeader } from "./sticky-accordion-header" -import { Tooltip } from "./tooltip" -import { ScrollView } from "./scroll-view" -import { useFileComponent } from "../context/file" -import { useI18n } from "../context/i18n" +import { Accordion } from "@opencode-ai/ui/accordion" +import { Button } from "@opencode-ai/ui/button" +import { DropdownMenu } from "@opencode-ai/ui/dropdown-menu" +import { RadioGroup } from "@opencode-ai/ui/radio-group" +import { DiffChanges } from "@opencode-ai/ui/diff-changes" +import { FileIcon } from "@opencode-ai/ui/file-icon" +import { Icon } from "@opencode-ai/ui/icon" +import { IconButton } from "@opencode-ai/ui/icon-button" +import { StickyAccordionHeader } from "@opencode-ai/ui/sticky-accordion-header" +import { Tooltip } from "@opencode-ai/ui/tooltip" +import { ScrollView } from "@opencode-ai/ui/scroll-view" +import { useFileComponent } from "@opencode-ai/ui/context/file" +import { useI18n } from "@opencode-ai/ui/context/i18n" import { getDirectory, getFilename } from "@opencode-ai/core/util/path" import { checksum } from "@opencode-ai/core/util/encode" import { createEffect, createMemo, For, Match, onCleanup, Show, Switch, untrack, type JSX } from "solid-js" diff --git a/packages/ui/src/components/session-turn.css b/packages/session-ui/src/components/session-turn.css similarity index 100% rename from packages/ui/src/components/session-turn.css rename to packages/session-ui/src/components/session-turn.css diff --git a/packages/ui/src/components/session-turn.stories.tsx b/packages/session-ui/src/components/session-turn.stories.tsx similarity index 80% rename from packages/ui/src/components/session-turn.stories.tsx rename to packages/session-ui/src/components/session-turn.stories.tsx index 927402c8db..4b43fd20d0 100644 --- a/packages/ui/src/components/session-turn.stories.tsx +++ b/packages/session-ui/src/components/session-turn.stories.tsx @@ -1,6 +1,6 @@ // @ts-nocheck import * as mod from "./session-turn" -import { create } from "../storybook/scaffold" +import { create } from "@opencode-ai/ui/storybook/scaffold" const story = create({ title: "UI/SessionTurn", mod }) export default { title: "UI/SessionTurn", id: "components-session-turn", component: story.meta.component } diff --git a/packages/ui/src/components/session-turn.tsx b/packages/session-ui/src/components/session-turn.tsx similarity index 97% rename from packages/ui/src/components/session-turn.tsx rename to packages/session-ui/src/components/session-turn.tsx index a39b9a7f64..4ebf6459b1 100644 --- a/packages/ui/src/components/session-turn.tsx +++ b/packages/session-ui/src/components/session-turn.tsx @@ -6,7 +6,7 @@ import { } from "@opencode-ai/sdk/v2/client" import type { SessionStatus } from "@opencode-ai/sdk/v2" import { useData } from "../context" -import { useFileComponent } from "../context/file" +import { useFileComponent } from "@opencode-ai/ui/context/file" import { Binary } from "@opencode-ai/core/util/binary" import { getDirectory, getFilename } from "@opencode-ai/core/util/path" @@ -14,16 +14,16 @@ import { createEffect, createMemo, createSignal, For, on, ParentProps, Show } fr import { createStore } from "solid-js/store" import { Dynamic } from "solid-js/web" import { AssistantParts, Message, MessageDivider, PART_MAPPING, type UserActions } from "./message-part" -import { Card } from "./card" -import { Accordion } from "./accordion" -import { StickyAccordionHeader } from "./sticky-accordion-header" -import { DiffChanges } from "./diff-changes" -import { Icon } from "./icon" -import { TextShimmer } from "./text-shimmer" +import { Card } from "@opencode-ai/ui/card" +import { Accordion } from "@opencode-ai/ui/accordion" +import { StickyAccordionHeader } from "@opencode-ai/ui/sticky-accordion-header" +import { DiffChanges } from "@opencode-ai/ui/diff-changes" +import { Icon } from "@opencode-ai/ui/icon" +import { TextShimmer } from "@opencode-ai/ui/text-shimmer" import { SessionRetry } from "./session-retry" -import { TextReveal } from "./text-reveal" -import { createAutoScroll } from "../hooks" -import { useI18n } from "../context/i18n" +import { TextReveal } from "@opencode-ai/ui/text-reveal" +import { createAutoScroll } from "@opencode-ai/ui/hooks" +import { useI18n } from "@opencode-ai/ui/context/i18n" import { normalize } from "./session-diff" function record(value: unknown): value is Record { diff --git a/packages/ui/src/components/shell-submessage-motion.stories.tsx b/packages/session-ui/src/components/shell-submessage-motion.stories.tsx similarity index 100% rename from packages/ui/src/components/shell-submessage-motion.stories.tsx rename to packages/session-ui/src/components/shell-submessage-motion.stories.tsx diff --git a/packages/ui/src/components/shell-submessage.css b/packages/session-ui/src/components/shell-submessage.css similarity index 100% rename from packages/ui/src/components/shell-submessage.css rename to packages/session-ui/src/components/shell-submessage.css diff --git a/packages/ui/src/components/timeline-playground.stories.tsx b/packages/session-ui/src/components/timeline-playground.stories.tsx similarity index 99% rename from packages/ui/src/components/timeline-playground.stories.tsx rename to packages/session-ui/src/components/timeline-playground.stories.tsx index a189e3d0f3..491ba2063c 100644 --- a/packages/ui/src/components/timeline-playground.stories.tsx +++ b/packages/session-ui/src/components/timeline-playground.stories.tsx @@ -13,7 +13,7 @@ import type { AgentPart, } from "@opencode-ai/sdk/v2" import { DataProvider } from "../context/data" -import { FileComponentProvider } from "../context/file" +import { FileComponentProvider } from "@opencode-ai/ui/context/file" import { SessionTurn } from "./session-turn" // --------------------------------------------------------------------------- @@ -558,7 +558,7 @@ function toolPart(sample: (typeof TOOL_SAMPLES)[keyof typeof TOOL_SAMPLES], stat // CSS Controls definition // --------------------------------------------------------------------------- -// Source file basenames inside packages/ui/src/components/ +// Source file basenames inside the UI component packages. const MD = "markdown.css" const MP = "message-part.css" const ST = "session-turn.css" diff --git a/packages/ui/src/components/tool-count-label.css b/packages/session-ui/src/components/tool-count-label.css similarity index 100% rename from packages/ui/src/components/tool-count-label.css rename to packages/session-ui/src/components/tool-count-label.css diff --git a/packages/ui/src/components/tool-count-label.tsx b/packages/session-ui/src/components/tool-count-label.tsx similarity index 97% rename from packages/ui/src/components/tool-count-label.tsx rename to packages/session-ui/src/components/tool-count-label.tsx index 67e861cdcb..715f37ef0a 100644 --- a/packages/ui/src/components/tool-count-label.tsx +++ b/packages/session-ui/src/components/tool-count-label.tsx @@ -1,5 +1,5 @@ import { createMemo } from "solid-js" -import { AnimatedNumber } from "./animated-number" +import { AnimatedNumber } from "@opencode-ai/ui/animated-number" function split(text: string) { const match = /{{\s*count\s*}}/.exec(text) diff --git a/packages/ui/src/components/tool-count-summary.css b/packages/session-ui/src/components/tool-count-summary.css similarity index 100% rename from packages/ui/src/components/tool-count-summary.css rename to packages/session-ui/src/components/tool-count-summary.css diff --git a/packages/ui/src/components/tool-count-summary.stories.tsx b/packages/session-ui/src/components/tool-count-summary.stories.tsx similarity index 100% rename from packages/ui/src/components/tool-count-summary.stories.tsx rename to packages/session-ui/src/components/tool-count-summary.stories.tsx diff --git a/packages/ui/src/components/tool-count-summary.tsx b/packages/session-ui/src/components/tool-count-summary.tsx similarity index 100% rename from packages/ui/src/components/tool-count-summary.tsx rename to packages/session-ui/src/components/tool-count-summary.tsx diff --git a/packages/ui/src/components/tool-error-card.css b/packages/session-ui/src/components/tool-error-card.css similarity index 100% rename from packages/ui/src/components/tool-error-card.css rename to packages/session-ui/src/components/tool-error-card.css diff --git a/packages/ui/src/components/tool-error-card.stories.tsx b/packages/session-ui/src/components/tool-error-card.stories.tsx similarity index 100% rename from packages/ui/src/components/tool-error-card.stories.tsx rename to packages/session-ui/src/components/tool-error-card.stories.tsx diff --git a/packages/ui/src/components/tool-error-card.tsx b/packages/session-ui/src/components/tool-error-card.tsx similarity index 94% rename from packages/ui/src/components/tool-error-card.tsx rename to packages/session-ui/src/components/tool-error-card.tsx index ade7cc4b01..35720a2753 100644 --- a/packages/ui/src/components/tool-error-card.tsx +++ b/packages/session-ui/src/components/tool-error-card.tsx @@ -1,11 +1,11 @@ import { type ComponentProps, createMemo, Show, splitProps } from "solid-js" import { createStore } from "solid-js/store" -import { Card, CardDescription } from "./card" -import { Collapsible } from "./collapsible" -import { Icon } from "./icon" -import { IconButton } from "./icon-button" -import { Tooltip } from "./tooltip" -import { useI18n } from "../context/i18n" +import { Card, CardDescription } from "@opencode-ai/ui/card" +import { Collapsible } from "@opencode-ai/ui/collapsible" +import { Icon } from "@opencode-ai/ui/icon" +import { IconButton } from "@opencode-ai/ui/icon-button" +import { Tooltip } from "@opencode-ai/ui/tooltip" +import { useI18n } from "@opencode-ai/ui/context/i18n" export interface ToolErrorCardProps extends Omit, "children" | "variant"> { tool: string diff --git a/packages/ui/src/components/tool-status-title.css b/packages/session-ui/src/components/tool-status-title.css similarity index 100% rename from packages/ui/src/components/tool-status-title.css rename to packages/session-ui/src/components/tool-status-title.css diff --git a/packages/ui/src/components/tool-status-title.tsx b/packages/session-ui/src/components/tool-status-title.tsx similarity index 98% rename from packages/ui/src/components/tool-status-title.tsx rename to packages/session-ui/src/components/tool-status-title.tsx index 5c46593f71..589effc1f0 100644 --- a/packages/ui/src/components/tool-status-title.tsx +++ b/packages/session-ui/src/components/tool-status-title.tsx @@ -1,6 +1,6 @@ import { Show, createEffect, createMemo, on, onCleanup } from "solid-js" import { createStore } from "solid-js/store" -import { TextShimmer } from "./text-shimmer" +import { TextShimmer } from "@opencode-ai/ui/text-shimmer" function common(active: string, done: string) { const a = Array.from(active) diff --git a/packages/ui/src/context/data.tsx b/packages/session-ui/src/context/data.tsx similarity index 95% rename from packages/ui/src/context/data.tsx rename to packages/session-ui/src/context/data.tsx index cf776c5104..999ff510d5 100644 --- a/packages/ui/src/context/data.tsx +++ b/packages/session-ui/src/context/data.tsx @@ -1,5 +1,5 @@ import type { Message, Session, Part, SnapshotFileDiff, SessionStatus, Provider } from "@opencode-ai/sdk/v2" -import { createSimpleContext } from "./helper" +import { createSimpleContext } from "@opencode-ai/ui/context" import { PreloadMultiFileDiffResult } from "@pierre/diffs/ssr" export type NormalizedProviderListResponse = { diff --git a/packages/session-ui/src/context/index.ts b/packages/session-ui/src/context/index.ts new file mode 100644 index 0000000000..b07252ef84 --- /dev/null +++ b/packages/session-ui/src/context/index.ts @@ -0,0 +1 @@ +export * from "./data" diff --git a/packages/ui/src/pierre/comment-hover.ts b/packages/session-ui/src/pierre/comment-hover.ts similarity index 100% rename from packages/ui/src/pierre/comment-hover.ts rename to packages/session-ui/src/pierre/comment-hover.ts diff --git a/packages/ui/src/pierre/commented-lines.ts b/packages/session-ui/src/pierre/commented-lines.ts similarity index 100% rename from packages/ui/src/pierre/commented-lines.ts rename to packages/session-ui/src/pierre/commented-lines.ts diff --git a/packages/ui/src/pierre/diff-selection.ts b/packages/session-ui/src/pierre/diff-selection.ts similarity index 100% rename from packages/ui/src/pierre/diff-selection.ts rename to packages/session-ui/src/pierre/diff-selection.ts diff --git a/packages/ui/src/pierre/file-find.ts b/packages/session-ui/src/pierre/file-find.ts similarity index 100% rename from packages/ui/src/pierre/file-find.ts rename to packages/session-ui/src/pierre/file-find.ts diff --git a/packages/ui/src/pierre/file-runtime.ts b/packages/session-ui/src/pierre/file-runtime.ts similarity index 100% rename from packages/ui/src/pierre/file-runtime.ts rename to packages/session-ui/src/pierre/file-runtime.ts diff --git a/packages/ui/src/pierre/file-selection.ts b/packages/session-ui/src/pierre/file-selection.ts similarity index 100% rename from packages/ui/src/pierre/file-selection.ts rename to packages/session-ui/src/pierre/file-selection.ts diff --git a/packages/ui/src/pierre/index.ts b/packages/session-ui/src/pierre/index.ts similarity index 100% rename from packages/ui/src/pierre/index.ts rename to packages/session-ui/src/pierre/index.ts diff --git a/packages/ui/src/pierre/media.ts b/packages/session-ui/src/pierre/media.ts similarity index 100% rename from packages/ui/src/pierre/media.ts rename to packages/session-ui/src/pierre/media.ts diff --git a/packages/ui/src/pierre/selection-bridge.ts b/packages/session-ui/src/pierre/selection-bridge.ts similarity index 100% rename from packages/ui/src/pierre/selection-bridge.ts rename to packages/session-ui/src/pierre/selection-bridge.ts diff --git a/packages/ui/src/pierre/virtualizer.ts b/packages/session-ui/src/pierre/virtualizer.ts similarity index 100% rename from packages/ui/src/pierre/virtualizer.ts rename to packages/session-ui/src/pierre/virtualizer.ts diff --git a/packages/ui/src/pierre/worker.ts b/packages/session-ui/src/pierre/worker.ts similarity index 100% rename from packages/ui/src/pierre/worker.ts rename to packages/session-ui/src/pierre/worker.ts diff --git a/packages/session-ui/src/styles/index.css b/packages/session-ui/src/styles/index.css new file mode 100644 index 0000000000..24f78feb73 --- /dev/null +++ b/packages/session-ui/src/styles/index.css @@ -0,0 +1,14 @@ +@layer theme, base, components, utilities; + +@import "../components/basic-tool.css" layer(components); +@import "../components/file.css" layer(components); +@import "../components/markdown.css" layer(components); +@import "../components/message-part.css" layer(components); +@import "../components/message-nav.css" layer(components); +@import "../components/session-review.css" layer(components); +@import "../components/session-turn.css" layer(components); +@import "../components/shell-submessage.css" layer(components); +@import "../components/tool-count-label.css" layer(components); +@import "../components/tool-count-summary.css" layer(components); +@import "../components/tool-error-card.css" layer(components); +@import "../components/tool-status-title.css" layer(components); diff --git a/packages/ui/src/v2/components/basic-tool-v2.css b/packages/session-ui/src/v2/components/basic-tool-v2.css similarity index 100% rename from packages/ui/src/v2/components/basic-tool-v2.css rename to packages/session-ui/src/v2/components/basic-tool-v2.css diff --git a/packages/ui/src/v2/components/basic-tool-v2.stories.tsx b/packages/session-ui/src/v2/components/basic-tool-v2.stories.tsx similarity index 100% rename from packages/ui/src/v2/components/basic-tool-v2.stories.tsx rename to packages/session-ui/src/v2/components/basic-tool-v2.stories.tsx diff --git a/packages/ui/src/v2/components/basic-tool-v2.tsx b/packages/session-ui/src/v2/components/basic-tool-v2.tsx similarity index 97% rename from packages/ui/src/v2/components/basic-tool-v2.tsx rename to packages/session-ui/src/v2/components/basic-tool-v2.tsx index cf9d771b02..70bb87cce7 100644 --- a/packages/ui/src/v2/components/basic-tool-v2.tsx +++ b/packages/session-ui/src/v2/components/basic-tool-v2.tsx @@ -1,7 +1,7 @@ import { Collapsible } from "@kobalte/core/collapsible" import { type ComponentProps, type JSX, For, Show, createMemo, splitProps } from "solid-js" -import { DiffChanges } from "./diff-changes-v2" -import { TextShimmerV2 } from "./text-shimmer-v2" +import { DiffChanges } from "@opencode-ai/ui/v2/diff-changes-v2" +import { TextShimmerV2 } from "@opencode-ai/ui/v2/text-shimmer-v2" import "./basic-tool-v2.css" function ChevronIcon() { diff --git a/packages/ui/src/v2/components/session-progress-indicator-v2.css b/packages/session-ui/src/v2/components/session-progress-indicator-v2.css similarity index 100% rename from packages/ui/src/v2/components/session-progress-indicator-v2.css rename to packages/session-ui/src/v2/components/session-progress-indicator-v2.css diff --git a/packages/ui/src/v2/components/session-progress-indicator-v2.stories.tsx b/packages/session-ui/src/v2/components/session-progress-indicator-v2.stories.tsx similarity index 100% rename from packages/ui/src/v2/components/session-progress-indicator-v2.stories.tsx rename to packages/session-ui/src/v2/components/session-progress-indicator-v2.stories.tsx diff --git a/packages/ui/src/v2/components/session-progress-indicator-v2.tsx b/packages/session-ui/src/v2/components/session-progress-indicator-v2.tsx similarity index 100% rename from packages/ui/src/v2/components/session-progress-indicator-v2.tsx rename to packages/session-ui/src/v2/components/session-progress-indicator-v2.tsx diff --git a/packages/ui/src/v2/components/tool-error-card-v2.css b/packages/session-ui/src/v2/components/tool-error-card-v2.css similarity index 100% rename from packages/ui/src/v2/components/tool-error-card-v2.css rename to packages/session-ui/src/v2/components/tool-error-card-v2.css diff --git a/packages/ui/src/v2/components/tool-error-card-v2.stories.tsx b/packages/session-ui/src/v2/components/tool-error-card-v2.stories.tsx similarity index 97% rename from packages/ui/src/v2/components/tool-error-card-v2.stories.tsx rename to packages/session-ui/src/v2/components/tool-error-card-v2.stories.tsx index ae5c62bfdf..1642e53a81 100644 --- a/packages/ui/src/v2/components/tool-error-card-v2.stories.tsx +++ b/packages/session-ui/src/v2/components/tool-error-card-v2.stories.tsx @@ -1,5 +1,5 @@ import { createSignal } from "solid-js" -import { ButtonV2 } from "./button-v2" +import { ButtonV2 } from "@opencode-ai/ui/v2/button-v2" import { ToolErrorCardV2, type ToolErrorCardV2Props } from "./tool-error-card-v2" const docs = `### Overview diff --git a/packages/ui/src/v2/components/tool-error-card-v2.tsx b/packages/session-ui/src/v2/components/tool-error-card-v2.tsx similarity index 100% rename from packages/ui/src/v2/components/tool-error-card-v2.tsx rename to packages/session-ui/src/v2/components/tool-error-card-v2.tsx diff --git a/packages/session-ui/tsconfig.json b/packages/session-ui/tsconfig.json new file mode 100644 index 0000000000..b234c74822 --- /dev/null +++ b/packages/session-ui/tsconfig.json @@ -0,0 +1,19 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "extends": "@tsconfig/node22/tsconfig.json", + "compilerOptions": { + "jsx": "preserve", + "jsxImportSource": "solid-js", + "target": "ESNext", + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "isolatedModules": true, + "module": "ESNext", + "moduleResolution": "bundler", + "noEmit": true, + "lib": ["es2023", "dom", "dom.iterable"], + "strict": true, + "types": ["vite/client", "bun"] + }, + "exclude": ["**/*.stories.*", "**/*.mdx"] +} diff --git a/packages/storybook/.storybook/main.ts b/packages/storybook/.storybook/main.ts index 7b42abd67c..f592863e56 100644 --- a/packages/storybook/.storybook/main.ts +++ b/packages/storybook/.storybook/main.ts @@ -6,6 +6,7 @@ import { playgroundCss } from "./playground-css-plugin" const here = path.dirname(fileURLToPath(import.meta.url)) const ui = path.resolve(here, "../../ui") +const sessionUi = path.resolve(here, "../../session-ui") const app = path.resolve(here, "../../app/src") const mocks = path.resolve(here, "./mocks") @@ -21,7 +22,11 @@ export default defineMain({ "@storybook/addon-a11y", "@storybook/addon-vitest", ], - stories: ["../../ui/src/**/*.stories.@(js|jsx|mjs|ts|tsx)", "../../app/src/**/*.stories.@(js|jsx|mjs|ts|tsx)"], + stories: [ + "../../ui/src/**/*.stories.@(js|jsx|mjs|ts|tsx)", + "../../session-ui/src/**/*.stories.@(js|jsx|mjs|ts|tsx)", + "../../app/src/**/*.stories.@(js|jsx|mjs|ts|tsx)", + ], async viteFinal(config) { const { mergeConfig, searchForWorkspaceRoot } = await import("vite") return mergeConfig(config, { @@ -59,7 +64,7 @@ export default defineMain({ }, server: { fs: { - allow: [searchForWorkspaceRoot(process.cwd()), ui, app, mocks], + allow: [searchForWorkspaceRoot(process.cwd()), ui, sessionUi, app, mocks], }, }, }) diff --git a/packages/storybook/.storybook/playground-css-plugin.ts b/packages/storybook/.storybook/playground-css-plugin.ts index 23bb20b7dd..567ea9a5fc 100644 --- a/packages/storybook/.storybook/playground-css-plugin.ts +++ b/packages/storybook/.storybook/playground-css-plugin.ts @@ -7,7 +7,7 @@ * * For each edit the plugin finds `anchor` in the file, then locates the * next `prop: ;` after it and replaces the value portion. - * `file` is a basename resolved relative to packages/ui/src/components/. + * `file` is a basename resolved against the UI component packages. */ import type { Plugin } from "vite" import type { IncomingMessage, ServerResponse } from "node:http" @@ -16,7 +16,7 @@ import path from "node:path" import { fileURLToPath } from "node:url" const here = path.dirname(fileURLToPath(import.meta.url)) -const root = path.resolve(here, "../../ui/src/components") +const roots = [path.resolve(here, "../../session-ui/src/components"), path.resolve(here, "../../ui/src/components")] const ENDPOINT = "/__playground/apply-css" @@ -97,8 +97,8 @@ export function playgroundCss(): Plugin { const grouped = new Map() for (const edit of payload.edits) { if (!edit.file || !edit.anchor || !edit.prop || edit.value === undefined) continue - const abs = path.resolve(root, edit.file) - if (!abs.startsWith(root)) continue + const abs = roots.map((root) => path.resolve(root, edit.file)).find((file) => fs.existsSync(file)) + if (!abs || !roots.some((root) => abs.startsWith(root))) continue const key = abs if (!grouped.has(key)) grouped.set(key, []) grouped.get(key)!.push(edit) diff --git a/packages/storybook/.storybook/preview.tsx b/packages/storybook/.storybook/preview.tsx index 7b892f7683..76fb3abec9 100644 --- a/packages/storybook/.storybook/preview.tsx +++ b/packages/storybook/.storybook/preview.tsx @@ -1,4 +1,5 @@ import "@opencode-ai/ui/styles/tailwind" +import "@opencode-ai/session-ui/styles" import "@opencode-ai/ui/v2/styles/tailwind.css" import { createEffect, onCleanup, onMount } from "solid-js" diff --git a/packages/storybook/package.json b/packages/storybook/package.json index b1dae1c956..f7089bafa3 100644 --- a/packages/storybook/package.json +++ b/packages/storybook/package.json @@ -9,6 +9,7 @@ }, "devDependencies": { "@tailwindcss/vite": "catalog:", + "@opencode-ai/session-ui": "workspace:*", "@opencode-ai/ui": "workspace:*", "@solidjs/meta": "catalog:", "@storybook/addon-a11y": "^10.2.13", diff --git a/packages/ui/package.json b/packages/ui/package.json index 489396ad49..3ec943187e 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -6,13 +6,12 @@ "exports": { "./package.json": "./package.json", "./*": "./src/components/*.tsx", - "./session-diff": "./src/components/session-diff.ts", "./i18n/*": "./src/i18n/*.ts", - "./pierre": "./src/pierre/index.ts", - "./pierre/*": "./src/pierre/*.ts", "./hooks": "./src/hooks/index.ts", "./context": "./src/context/index.ts", "./context/*": "./src/context/*.tsx", + "./storybook/scaffold": "./src/storybook/scaffold.tsx", + "./storybook/fixtures": "./src/storybook/fixtures.ts", "./styles": "./src/styles/index.css", "./styles/tailwind": "./src/styles/tailwind/index.css", "./theme": "./src/theme/index.ts", @@ -49,8 +48,6 @@ }, "dependencies": { "@kobalte/core": "catalog:", - "@opencode-ai/core": "workspace:*", - "@opencode-ai/sdk": "workspace:*", "@pierre/diffs": "catalog:", "@shikijs/transformers": "3.9.2", "@solid-primitives/bounds": "0.1.3", diff --git a/packages/ui/src/context/index.ts b/packages/ui/src/context/index.ts index 2db004985f..7cbf02c4ee 100644 --- a/packages/ui/src/context/index.ts +++ b/packages/ui/src/context/index.ts @@ -1,5 +1,4 @@ export * from "./helper" -export * from "./data" export * from "./file" export * from "./dialog" export * from "./i18n" diff --git a/packages/ui/src/styles/index.css b/packages/ui/src/styles/index.css index 1b17f6c2b7..729e19cd33 100644 --- a/packages/ui/src/styles/index.css +++ b/packages/ui/src/styles/index.css @@ -10,12 +10,9 @@ @import "../components/animated-number.css" layer(components); @import "../components/app-icon.css" layer(components); @import "../components/avatar.css" layer(components); -@import "../components/basic-tool.css" layer(components); @import "../components/button.css" layer(components); @import "../components/card.css" layer(components); -@import "../components/tool-error-card.css" layer(components); @import "../components/checkbox.css" layer(components); -@import "../components/file.css" layer(components); @import "../components/collapsible.css" layer(components); @import "../components/diff-changes.css" layer(components); @import "../components/context-menu.css" layer(components); @@ -33,9 +30,6 @@ @import "../components/inline-input.css" layer(components); @import "../components/list.css" layer(components); @import "../components/logo.css" layer(components); -@import "../components/markdown.css" layer(components); -@import "../components/message-part.css" layer(components); -@import "../components/message-nav.css" layer(components); @import "../components/popover.css" layer(components); @import "../components/progress.css" layer(components); @import "../components/progress-circle.css" layer(components); @@ -45,18 +39,12 @@ @import "../components/spinner.css" layer(components); @import "../components/switch.css" layer(components); @import "../components/scroll-view.css" layer(components); -@import "../components/session-review.css" layer(components); -@import "../components/session-turn.css" layer(components); -@import "../components/shell-submessage.css" layer(components); @import "../components/sticky-accordion-header.css" layer(components); @import "../components/tabs.css" layer(components); @import "../components/tag.css" layer(components); @import "../components/text-reveal.css" layer(components); @import "../components/text-strikethrough.css" layer(components); @import "../components/text-shimmer.css" layer(components); -@import "../components/tool-count-label.css" layer(components); -@import "../components/tool-count-summary.css" layer(components); -@import "../components/tool-status-title.css" layer(components); @import "../components/toast.css" layer(components); @import "../components/tooltip.css" layer(components); @import "../components/typewriter.css" layer(components); diff --git a/turbo.json b/turbo.json index c9255902c5..5e93640b1f 100644 --- a/turbo.json +++ b/turbo.json @@ -24,6 +24,10 @@ "@opencode-ai/ui#test": { "dependsOn": ["^build"], "outputs": [] + }, + "@opencode-ai/session-ui#test": { + "dependsOn": ["^build"], + "outputs": [] } } }