diff --git a/packages/app/e2e/performance/timeline/session-tab-switch-probe.ts b/packages/app/e2e/performance/timeline/session-tab-switch-probe.ts
index 955da80367d..5dcfc3ac6b3 100644
--- a/packages/app/e2e/performance/timeline/session-tab-switch-probe.ts
+++ b/packages/app/e2e/performance/timeline/session-tab-switch-probe.ts
@@ -25,7 +25,7 @@ async function installSessionSwitchProbe(
let running = true
const reviewLevels: Record = {
panel: "#review-panel",
- tabs: '#review-panel [data-component="tabs"]',
+ tabs: '#review-panel [data-component="tabs"]',
body: '#review-panel [data-slot="session-review-v2-body"]',
review: '#review-panel [data-component="session-review-v2"]',
preview: '#review-panel [data-slot="session-review-v2-preview"]',
diff --git a/packages/app/e2e/regression/session-request-docks.spec.ts b/packages/app/e2e/regression/session-request-docks.spec.ts
index 356c0b7d466..b15dfb7a3e9 100644
--- a/packages/app/e2e/regression/session-request-docks.spec.ts
+++ b/packages/app/e2e/regression/session-request-docks.spec.ts
@@ -52,7 +52,7 @@ test("shows a pending question dock", async ({ page }) => {
rejectRequests.push(request.url())
})
- await question.locator('[data-component="icon-button"][data-icon="chevron-down"]').click()
+ await question.getByRole("button", { name: "Minimize question" }).click()
await expect(question).toBeVisible()
await expect(question.getByText("Which implementation should be used?")).toBeVisible()
await expect(question.getByText("Select one answer")).toBeHidden()
@@ -63,7 +63,7 @@ test("shows a pending question dock", async ({ page }) => {
await expect(page.locator('[data-component="question-minimized-dock"]')).toHaveCount(0)
expect(rejectRequests).toEqual([])
- await question.locator('[data-component="icon-button"][data-icon="chevron-down"]').click()
+ await question.getByRole("button", { name: "Restore question" }).click()
await expect(question).toBeVisible()
await expect(question.getByText("Which implementation should be used?")).toBeVisible()
await expect(question.getByRole("radio", { name: /Minimal/ })).toBeVisible()
diff --git a/packages/app/e2e/regression/session-timeline-tool-projection.spec.ts b/packages/app/e2e/regression/session-timeline-tool-projection.spec.ts
index 85485acbfeb..d7c44d96f17 100644
--- a/packages/app/e2e/regression/session-timeline-tool-projection.spec.ts
+++ b/packages/app/e2e/regression/session-timeline-tool-projection.spec.ts
@@ -131,15 +131,14 @@ test("labels V2 skill tools from IDs and result metadata", async ({ page }) => {
"aria-label",
"sample-skill",
)
- await expect(page.locator(`[data-timeline-part-id="${completed}"] [data-component="text-shimmer"]`)).toHaveAttribute(
- "aria-label",
- "OpenCode",
- )
+ await expect(
+ page.locator(`[data-timeline-part-id="${completed}"] [data-component="text-shimmer"]`),
+ ).toHaveAttribute("aria-label", "OpenCode")
for (const id of [pending, completed]) {
const skill = page.locator(`[data-timeline-part-id="${id}"]`)
await expect(skill.locator('[data-slot="skill-tool-label"]')).toHaveText("Skill")
await expect(skill.locator('[data-slot="skill-tool-separator"]')).toHaveText("·")
- await expect(skill.locator('use[href="#opencode-icon-post-skill"]')).toBeVisible()
+ await expect(skill.locator('use[href="#opencode-v2-icon-post-skill"]')).toBeVisible()
}
})
diff --git a/packages/app/e2e/smoke/session-timeline.spec.ts b/packages/app/e2e/smoke/session-timeline.spec.ts
index f4371a305da..d0fb0922f4f 100644
--- a/packages/app/e2e/smoke/session-timeline.spec.ts
+++ b/packages/app/e2e/smoke/session-timeline.spec.ts
@@ -477,7 +477,7 @@ async function configureSmokePage(page: Page, directory: string) {
}
let recordFrame: number | undefined
const record = () => {
- for (const toast of document.querySelectorAll('[data-component="toast"][data-variant="error"]')) {
+ for (const toast of document.querySelectorAll(".toast-v2--error")) {
const text = toast.textContent?.trim()
if (text && !smoke.__timelineSmokeErrorToasts!.includes(text)) smoke.__timelineSmokeErrorToasts!.push(text)
}
diff --git a/packages/app/src/components/debug-bar.tsx b/packages/app/src/components/debug-bar.tsx
index 67cd0da0e92..94447b14608 100644
--- a/packages/app/src/components/debug-bar.tsx
+++ b/packages/app/src/components/debug-bar.tsx
@@ -3,7 +3,6 @@ import { batch, createEffect, onCleanup, onMount, Show } from "solid-js"
import { createStore } from "solid-js/store"
import { makeEventListener } from "@solid-primitives/event-listener"
import { Tooltip } from "@opencode-ai/ui/tooltip"
-import { TooltipV2 } from "@opencode-ai/ui/v2/tooltip-v2"
import { useLanguage } from "@/context/language"
import { usePlatform } from "@/context/platform"
@@ -102,16 +101,8 @@ function Cell(props: {
)
- if (props.inline) {
- return (
-
- {content()}
-
- )
- }
-
return (
-
+
{content()}
)
@@ -151,16 +142,8 @@ function ToggleCell(props: {
)
- if (props.inline) {
- return (
-
- {content()}
-
- )
- }
-
return (
-
+
{content()}
)
diff --git a/packages/app/src/components/dialog-command-palette-v2.tsx b/packages/app/src/components/dialog-command-palette-v2.tsx
index 2756c2094dd..e2b11699f2f 100644
--- a/packages/app/src/components/dialog-command-palette-v2.tsx
+++ b/packages/app/src/components/dialog-command-palette-v2.tsx
@@ -1,10 +1,10 @@
import { getDirectory, getFilename } from "@opencode-ai/util/path"
import { FileIcon } from "@opencode-ai/ui/file-icon"
import { ScrollView } from "@opencode-ai/ui/scroll-view"
-import { Dialog, DialogBody } from "@opencode-ai/ui/v2/dialog-v2"
-import { Icon } from "@opencode-ai/ui/v2/icon"
-import { KeybindV2 } from "@opencode-ai/ui/v2/keybind-v2"
-import { TextInputV2 } from "@opencode-ai/ui/v2/text-input-v2"
+import { Dialog, DialogBody } from "@opencode-ai/ui/dialog"
+import { Icon } from "@opencode-ai/ui/icon"
+import { Keybind } from "@opencode-ai/ui/keybind"
+import { TextInput } from "@opencode-ai/ui/text-input"
import { useDialog } from "@opencode-ai/ui/context/dialog"
import { createEffect, createMemo, createResource, createSignal, For, Match, onCleanup, Show, Switch } from "solid-js"
import { commandPaletteOptions, formatKeybindParts, useCommand } from "@/context/command"
@@ -191,7 +191,7 @@ function CommandPaletteView(props: {
)
}
@@ -168,7 +167,7 @@ function ProviderPicker(props: { directory?: string; onSelect: (provider: string
return (
-
-
+
{language.t("common.continue")}
@@ -516,7 +515,7 @@ function ProviderConnection(props: {
)
@@ -585,7 +584,7 @@ function ProviderConnection(props: {
)
diff --git a/packages/app/src/components/dialog-custom-provider.tsx b/packages/app/src/components/dialog-custom-provider.tsx
index 4adc8d37f7b..e14995c0dd3 100644
--- a/packages/app/src/components/dialog-custom-provider.tsx
+++ b/packages/app/src/components/dialog-custom-provider.tsx
@@ -1,6 +1,7 @@
import { Button } from "@opencode-ai/ui/button"
import { useDialog } from "@opencode-ai/ui/context/dialog"
-import { Dialog } from "@opencode-ai/ui/dialog"
+import { Dialog, DialogBody, DialogHeader, DialogTitle } from "@opencode-ai/ui/dialog"
+import { Icon } from "@opencode-ai/ui/icon"
import { IconButton } from "@opencode-ai/ui/icon-button"
import { ProviderIcon } from "@opencode-ai/ui/provider-icon"
import { useMutation } from "@tanstack/solid-query"
@@ -21,20 +22,21 @@ export function DialogCustomProvider(props: Props) {
const language = useLanguage()
return (
-
- }
- transition
- >
-
+
)
}
@@ -238,7 +240,7 @@ export function CustomProviderForm(props: { autofocus?: boolean } = {}) {
}
variant="ghost"
class="mt-1.5"
onClick={() => removeModel(i())}
@@ -282,7 +284,7 @@ export function CustomProviderForm(props: { autofocus?: boolean } = {}) {
}
variant="ghost"
class="mt-1.5"
onClick={() => removeHeader(i())}
@@ -301,7 +303,7 @@ export function CustomProviderForm(props: { autofocus?: boolean } = {}) {
class="w-auto self-start"
type="submit"
size="large"
- variant="primary"
+ variant="contrast"
disabled={saveMutation.isPending}
>
{saveMutation.isPending ? language.t("common.saving") : language.t("common.submit")}
diff --git a/packages/app/src/components/dialog-edit-project-v2.tsx b/packages/app/src/components/dialog-edit-project-v2.tsx
index fc5d958c5f0..2bcb518d435 100644
--- a/packages/app/src/components/dialog-edit-project-v2.tsx
+++ b/packages/app/src/components/dialog-edit-project-v2.tsx
@@ -1,12 +1,11 @@
-import { ButtonV2 } from "@opencode-ai/ui/v2/button-v2"
-import { Dialog, DialogFooter } from "@opencode-ai/ui/v2/dialog-v2"
-import { Field } from "@opencode-ai/ui/v2/field-v2"
-import { Icon as IconV2 } from "@opencode-ai/ui/v2/icon"
+import { Button } from "@opencode-ai/ui/button"
+import { Dialog, DialogFooter } from "@opencode-ai/ui/dialog"
+import { Field } from "@opencode-ai/ui/field"
import { Icon } from "@opencode-ai/ui/icon"
-import { ProjectAvatar, PROJECT_AVATAR_VARIANTS } from "@opencode-ai/ui/v2/project-avatar-v2"
-import { TabsV2 } from "@opencode-ai/ui/v2/tabs-v2"
-import { TextareaV2 } from "@opencode-ai/ui/v2/textarea-v2"
-import { TextInputV2 } from "@opencode-ai/ui/v2/text-input-v2"
+import { ProjectAvatar, PROJECT_AVATAR_VARIANTS } from "@opencode-ai/ui/project-avatar"
+import { Tabs } from "@opencode-ai/ui/tabs"
+import { Textarea } from "@opencode-ai/ui/textarea"
+import { TextInput } from "@opencode-ai/ui/text-input"
import { For, Show, createSignal, startTransition } from "solid-js"
import { useLanguage } from "@/context/language"
import { getProjectAvatarVariant, type LocalProject } from "@/context/layout"
@@ -37,46 +36,46 @@ function ProjectSettingsDialog(props: { project: LocalProject; server: ServerCon
const Footer = () => (
-
+
{language.t("common.cancel")}
-
-
+
+
{model.save.isPending ? language.t("common.saving") : language.t("common.save")}
-
+
)
return (
)
@@ -394,7 +394,7 @@ function HomeProjectEmpty(
disabled={unreachable()}
onClick={() => props.onChooseProject(props.server)}
>
-
+
{props.language.t("home.project.add")}
0}>
@@ -423,7 +423,7 @@ function HomeRecentlyClosedRow(
return worktree
}
return (
-
+
{displayName(props.project)}
-
+
)
}
@@ -523,55 +523,55 @@ function HomeProjectRow(
`}
data-menu={props.contextMenuOpen(contextMenuID())}
>
- props.onSetContextMenuOpen(contextMenuID(), open)}
>
- }
+ icon={}
aria-label={props.language.t("common.moreOptions")}
/>
-
-
- props.onOpenProjectNewSession(props.server, props.project.worktree)}>
+
+
+ props.onOpenProjectNewSession(props.server, props.project.worktree)}>
{props.language.t("command.session.new")}
-
- props.onEditProject(props.server, props.project)}>
+
+ props.onEditProject(props.server, props.project)}>
{props.language.t("dialog.project.edit.title")}
-
+
- props.onRevealProject(props.server, props.project)}>
+ props.onRevealProject(props.server, props.project)}>
{props.language.t(
fileManagerApp(platform.platform === "desktop" ? (platform.os ?? "unknown") : "unknown")
.actionLabel,
)}
-
+
- props.onClearNotifications(props.server, props.project)}
>
{props.language.t("sidebar.project.clearNotifications")}
-
-
- props.onCloseProject(props.server, props.project.worktree)}>
+
+
+ props.onCloseProject(props.server, props.project.worktree)}>
{props.language.t("common.close")}
-
-
-
-
-
+
+
+
+ }
+ icon={}
aria-label={props.language.t("command.session.new")}
onClick={() => props.onOpenProjectNewSession(props.server, props.project.worktree)}
/>
diff --git a/packages/app/src/pages/home/home-sessions-view.tsx b/packages/app/src/pages/home/home-sessions-view.tsx
index 1d6133ba81a..1b3c64b15eb 100644
--- a/packages/app/src/pages/home/home-sessions-view.tsx
+++ b/packages/app/src/pages/home/home-sessions-view.tsx
@@ -2,10 +2,10 @@ import type { SessionInfo } from "@opencode-ai/client/promise"
import { createMemo, For, Show, Suspense } from "solid-js"
import { Spinner } from "@opencode-ai/ui/spinner"
import { ScrollView } from "@opencode-ai/ui/scroll-view"
-import { ButtonV2 } from "@opencode-ai/ui/v2/button-v2"
-import { Icon as IconV2 } from "@opencode-ai/ui/v2/icon"
-import { IconButtonV2 } from "@opencode-ai/ui/v2/icon-button-v2"
-import { TooltipV2 } from "@opencode-ai/ui/v2/tooltip-v2"
+import { Button } from "@opencode-ai/ui/button"
+import { Icon } from "@opencode-ai/ui/icon"
+import { IconButton } from "@opencode-ai/ui/icon-button"
+import { Tooltip } from "@opencode-ai/ui/tooltip"
import { useLanguage } from "@/context/language"
import { ServerConnection } from "@/context/servers"
import { SessionTabAvatarView } from "@/pages/layout/session-tab-avatar"
@@ -83,7 +83,7 @@ export function HomeSessionsView(props: HomeSessionsViewProps) {
0 && props.canCreateSession}>
-
{props.language.t("command.session.new")}
-
+
@@ -273,7 +273,7 @@ function HomeSessionSearch(props: HomeSessionsViewProps) {
duration-[120ms] ease-in-out hover:bg-v2-background-bg-layer-02 focus-within:bg-v2-background-bg-layer-02
`}
>
-
+
- }
+ icon={}
aria-label={props.searchPlaceholder}
onClick={() => {
props.onSearchClose()
@@ -458,12 +458,12 @@ function HomeSessionRow(props: HomeSessionsViewProps & { record: HomeSessionReco
group-hover/session:opacity-100 focus-within:opacity-100
`}
>
-
-
+ }
+ icon={}
aria-label={props.language.t("common.archive")}
onClick={(event) => {
event.preventDefault()
@@ -471,7 +471,7 @@ function HomeSessionRow(props: HomeSessionsViewProps & { record: HomeSessionReco
void props.onArchiveSession(props.record.session)
}}
/>
-
+
@@ -525,9 +525,9 @@ function HomeSessionsEmpty(props: { onNewSession?: () => void; language: ReturnT
{(onNewSession) => (
-
+
{props.language.t("command.session.new")}
-
+
)}
diff --git a/packages/app/src/pages/layout/session-tab-avatar.tsx b/packages/app/src/pages/layout/session-tab-avatar.tsx
index 8a8ef28a5a3..2e1b820bd4e 100644
--- a/packages/app/src/pages/layout/session-tab-avatar.tsx
+++ b/packages/app/src/pages/layout/session-tab-avatar.tsx
@@ -1,9 +1,8 @@
-import type { LocalProject } from "@/context/layout"
-import { getProjectAvatarVariant } from "@/context/layout"
+import { getProjectAvatarVariant, type LocalProject } from "@/context/layout"
import type { ServerConnection } from "@/context/servers"
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 { ProjectAvatar } from "@opencode-ai/ui/project-avatar"
import { SessionProgressIndicatorV2 } from "@opencode-ai/session-ui/v2/session-progress-indicator-v2"
import { Show } from "solid-js"
diff --git a/packages/app/src/pages/new-session/new-session-view.tsx b/packages/app/src/pages/new-session/new-session-view.tsx
index 86f523642d8..6cd73f4ae1b 100644
--- a/packages/app/src/pages/new-session/new-session-view.tsx
+++ b/packages/app/src/pages/new-session/new-session-view.tsx
@@ -1,8 +1,7 @@
import { useDialog } from "@opencode-ai/ui/context/dialog"
import { Tooltip } from "@opencode-ai/ui/tooltip"
-import { Icon } from "@opencode-ai/ui/v2/icon"
-import { TooltipV2 } from "@opencode-ai/ui/v2/tooltip-v2"
-import { WordmarkV2 } from "@opencode-ai/ui/v2/wordmark-v2"
+import { Icon } from "@opencode-ai/ui/icon"
+import { Wordmark } from "@opencode-ai/ui/wordmark"
import { Show, createMemo, createSignal } from "solid-js"
import { createStore } from "solid-js/store"
import { Portal } from "solid-js/web"
@@ -47,7 +46,7 @@ export function NewSessionView(props: {
>
-
+
@@ -96,7 +95,7 @@ export function NewSessionStatus(props: { mount: HTMLElement | null; visible: bo
{(mount) => (
-
+
@@ -153,7 +152,7 @@ function ProviderTip() {
-
-
+
diff --git a/packages/app/src/pages/new-session/use-new-session-commands.tsx b/packages/app/src/pages/new-session/use-new-session-commands.tsx
index a0d835f97f5..342dc7a0856 100644
--- a/packages/app/src/pages/new-session/use-new-session-commands.tsx
+++ b/packages/app/src/pages/new-session/use-new-session-commands.tsx
@@ -21,8 +21,8 @@ export function useNewSessionCommands(input: {
title: language.t("command.palette"),
hidden: true,
onSelect: async () => {
- const { DialogSelectFile } = await import("@/components/dialog-select-file")
- void dialog.show(() =>
)
+ const { DialogCommandPaletteV2 } = await import("@/components/dialog-command-palette-v2")
+ void dialog.show(() =>
)
},
},
{
diff --git a/packages/app/src/pages/session.tsx b/packages/app/src/pages/session.tsx
index 0b3405996a7..1f7402427bf 100644
--- a/packages/app/src/pages/session.tsx
+++ b/packages/app/src/pages/session.tsx
@@ -30,10 +30,9 @@ import { createStore } from "solid-js/store"
import type { SessionReviewLineComment } from "@opencode-ai/session-ui/session-review"
import { ResizeHandle } from "@opencode-ai/ui/resize-handle"
import { Select } from "@opencode-ai/ui/select"
-import { SelectV2 } from "@opencode-ai/ui/v2/select-v2"
import { isScrollKeyTarget, scrollKey, scrollKeyOwner } from "@opencode-ai/ui/scroll-view"
import { Tabs } from "@opencode-ai/ui/tabs"
-import { ButtonV2 } from "@opencode-ai/ui/v2/button-v2"
+import { Button } from "@opencode-ai/ui/button"
import { createAutoScroll } from "@opencode-ai/ui/hooks"
import { previewSelectedLines } from "@opencode-ai/session-ui/pierre/selection-bridge"
import { showToast } from "@/utils/toast"
@@ -195,9 +194,9 @@ function SessionErrorFallback(props: { error: unknown; sessionID?: string; serve
)}
-
+
{language.t("session.error.notFound.closeTab")}
-
+
)
@@ -1039,25 +1038,6 @@ export default function Page() {
return (