summaryrefslogtreecommitdiffhomepage
path: root/packages/app/src/pages
diff options
context:
space:
mode:
Diffstat (limited to 'packages/app/src/pages')
-rw-r--r--packages/app/src/pages/directory-layout.tsx2
-rw-r--r--packages/app/src/pages/error.tsx10
-rw-r--r--packages/app/src/pages/home.tsx2
-rw-r--r--packages/app/src/pages/layout.tsx40
-rw-r--r--packages/app/src/pages/layout/helpers.ts2
-rw-r--r--packages/app/src/pages/layout/sidebar-items.tsx2
-rw-r--r--packages/app/src/pages/layout/sidebar-project.tsx2
-rw-r--r--packages/app/src/pages/layout/sidebar-workspace.tsx16
-rw-r--r--packages/app/src/pages/session.tsx24
-rw-r--r--packages/app/src/pages/session/composer/session-composer-state.ts55
-rw-r--r--packages/app/src/pages/session/composer/session-todo-dock.tsx22
-rw-r--r--packages/app/src/pages/session/file-tabs.tsx8
-rw-r--r--packages/app/src/pages/session/helpers.ts2
-rw-r--r--packages/app/src/pages/session/message-timeline.tsx10
-rw-r--r--packages/app/src/pages/session/review-tab.tsx2
-rw-r--r--packages/app/src/pages/session/terminal-panel.tsx6
-rw-r--r--packages/app/src/pages/session/use-session-commands.tsx2
17 files changed, 62 insertions, 145 deletions
diff --git a/packages/app/src/pages/directory-layout.tsx b/packages/app/src/pages/directory-layout.tsx
index 427b4823b..f604dd6c5 100644
--- a/packages/app/src/pages/directory-layout.tsx
+++ b/packages/app/src/pages/directory-layout.tsx
@@ -1,6 +1,6 @@
import { DataProvider } from "@opencode-ai/ui/context"
import { showToast } from "@opencode-ai/ui/toast"
-import { base64Encode } from "@opencode-ai/util/encode"
+import { base64Encode } from "@opencode-ai/shared/util/encode"
import { useLocation, useNavigate, useParams } from "@solidjs/router"
import { createEffect, createMemo, type ParentProps, Show } from "solid-js"
import { useLanguage } from "@/context/language"
diff --git a/packages/app/src/pages/error.tsx b/packages/app/src/pages/error.tsx
index 1cdc06116..11284b3d2 100644
--- a/packages/app/src/pages/error.tsx
+++ b/packages/app/src/pages/error.tsx
@@ -1,12 +1,11 @@
import { TextField } from "@opencode-ai/ui/text-field"
import { Logo } from "@opencode-ai/ui/logo"
import { Button } from "@opencode-ai/ui/button"
-import { Component, Show, onMount } from "solid-js"
+import { Component, Show } from "solid-js"
import { createStore } from "solid-js/store"
import { usePlatform } from "@/context/platform"
import { useLanguage } from "@/context/language"
import { Icon } from "@opencode-ai/ui/icon"
-import type { E2EWindow } from "@/testing/terminal"
export type InitError = {
name: string
@@ -227,13 +226,6 @@ export const ErrorPage: Component<ErrorPageProps> = (props) => {
actionError: undefined as string | undefined,
})
- onMount(() => {
- const win = window as E2EWindow
- if (!win.__opencode_e2e) return
- const detail = formatError(props.error, language.t)
- console.error(`[e2e:error-boundary] ${window.location.pathname}\n${detail}`)
- })
-
async function checkForUpdates() {
if (!platform.checkUpdate) return
setStore("checking", true)
diff --git a/packages/app/src/pages/home.tsx b/packages/app/src/pages/home.tsx
index 4c795b968..46cacdf62 100644
--- a/packages/app/src/pages/home.tsx
+++ b/packages/app/src/pages/home.tsx
@@ -3,7 +3,7 @@ import { Button } from "@opencode-ai/ui/button"
import { Logo } from "@opencode-ai/ui/logo"
import { useLayout } from "@/context/layout"
import { useNavigate } from "@solidjs/router"
-import { base64Encode } from "@opencode-ai/util/encode"
+import { base64Encode } from "@opencode-ai/shared/util/encode"
import { Icon } from "@opencode-ai/ui/icon"
import { usePlatform } from "@/context/platform"
import { DateTime } from "luxon"
diff --git a/packages/app/src/pages/layout.tsx b/packages/app/src/pages/layout.tsx
index f402f4bc0..12a2bf763 100644
--- a/packages/app/src/pages/layout.tsx
+++ b/packages/app/src/pages/layout.tsx
@@ -17,7 +17,7 @@ import { useNavigate, useParams } from "@solidjs/router"
import { useLayout, LocalProject } from "@/context/layout"
import { useGlobalSync } from "@/context/global-sync"
import { Persist, persisted } from "@/utils/persist"
-import { base64Encode } from "@opencode-ai/util/encode"
+import { base64Encode } from "@opencode-ai/shared/util/encode"
import { decode64 } from "@/utils/base64"
import { ResizeHandle } from "@opencode-ai/ui/resize-handle"
import { Button } from "@opencode-ai/ui/button"
@@ -25,7 +25,7 @@ import { IconButton } from "@opencode-ai/ui/icon-button"
import { Tooltip } from "@opencode-ai/ui/tooltip"
import { DropdownMenu } from "@opencode-ai/ui/dropdown-menu"
import { Dialog } from "@opencode-ai/ui/dialog"
-import { getFilename } from "@opencode-ai/util/path"
+import { getFilename } from "@opencode-ai/shared/util/path"
import { Session, type Message } from "@opencode-ai/sdk/v2/client"
import { usePlatform } from "@/context/platform"
import { useSettings } from "@/context/settings"
@@ -48,8 +48,8 @@ import {
} from "@/context/global-sync/session-prefetch"
import { useNotification } from "@/context/notification"
import { usePermission } from "@/context/permission"
-import { Binary } from "@opencode-ai/util/binary"
-import { retry } from "@opencode-ai/util/retry"
+import { Binary } from "@opencode-ai/shared/util/binary"
+import { retry } from "@opencode-ai/shared/util/retry"
import { playSoundById } from "@/utils/sound"
import { createAim } from "@/utils/aim"
import { setNavigate } from "@/utils/notification-click"
@@ -132,9 +132,11 @@ export default function Layout(props: ParentProps) {
if (!slug) return { slug, dir: "" }
const dir = decode64(slug)
if (!dir) return { slug, dir: "" }
+ const store = globalSync.peek(dir, { bootstrap: false })
return {
slug,
- dir: globalSync.peek(dir, { bootstrap: false })[0].path.directory || dir,
+ store,
+ dir: store[0].path.directory || dir,
}
})
const availableThemeEntries = createMemo(() => theme.ids().map((id) => [id, theme.themes()[id]] as const))
@@ -704,7 +706,7 @@ export default function Layout(props: ParentProps) {
createEffect(() => {
const active = new Set(visibleSessionDirs())
- for (const directory of [...prefetchedByDir.keys()]) {
+ for (const directory of prefetchedByDir.keys()) {
if (active.has(directory)) continue
prefetchedByDir.delete(directory)
}
@@ -956,7 +958,7 @@ export default function Layout(props: ParentProps) {
// warm up child store to prevent flicker
globalSync.child(target.worktree)
- openProject(target.worktree)
+ void openProject(target.worktree)
}
function navigateSessionByUnseen(offset: number) {
@@ -1094,7 +1096,7 @@ export default function Layout(props: ParentProps) {
disabled: !params.dir || !params.id,
onSelect: () => {
const session = currentSessions().find((s) => s.id === params.id)
- if (session) archiveSession(session)
+ if (session) void archiveSession(session)
},
},
{
@@ -1360,11 +1362,11 @@ export default function Layout(props: ParentProps) {
if (!server.isLocal()) return
for (const directory of collectOpenProjectDeepLinks(urls)) {
- openProject(directory)
+ void openProject(directory)
}
for (const link of collectNewSessionDeepLinks(urls)) {
- openProject(link.directory, false)
+ void openProject(link.directory, false)
const slug = base64Encode(link.directory)
if (link.prompt) {
setSessionHandoff(slug, { prompt: link.prompt })
@@ -1453,11 +1455,11 @@ export default function Layout(props: ParentProps) {
function resolve(result: string | string[] | null) {
if (Array.isArray(result)) {
for (const directory of result) {
- openProject(directory, false)
+ void openProject(directory, false)
}
- navigateToProject(result[0])
+ void navigateToProject(result[0])
} else if (result) {
- openProject(result)
+ void openProject(result)
}
}
@@ -1825,7 +1827,7 @@ export default function Layout(props: ParentProps) {
const next = new Set(dirs)
for (const directory of next) {
if (loadedSessionDirs.has(directory)) continue
- globalSync.project.loadSessions(directory)
+ void globalSync.project.loadSessions(directory)
}
loadedSessionDirs.clear()
@@ -2110,7 +2112,7 @@ export default function Layout(props: ParentProps) {
onSave={(next) => {
const item = project()
if (!item) return
- renameProject(item, next)
+ void renameProject(item, next)
}}
class="text-14-medium text-text-strong truncate"
displayClass="text-14-medium text-text-strong truncate"
@@ -2242,7 +2244,7 @@ export default function Layout(props: ParentProps) {
onClick={() => {
const item = project()
if (!item) return
- createWorkspace(item)
+ void createWorkspace(item)
}}
>
{language.t("workspace.new")}
@@ -2353,8 +2355,14 @@ export default function Layout(props: ParentProps) {
/>
)
+ const [loading] = createResource(
+ () => route()?.store?.[0]?.bootstrapPromise,
+ (p) => p,
+ )
+
return (
<div class="relative bg-background-base flex-1 min-h-0 min-w-0 flex flex-col select-none [&_input]:select-text [&_textarea]:select-text [&_[contenteditable]]:select-text">
+ {(autoselecting(), loading()) ?? ""}
<Titlebar />
<div class="flex-1 min-h-0 min-w-0 flex">
<div class="flex-1 min-h-0 relative">
diff --git a/packages/app/src/pages/layout/helpers.ts b/packages/app/src/pages/layout/helpers.ts
index 48158debb..26b66d166 100644
--- a/packages/app/src/pages/layout/helpers.ts
+++ b/packages/app/src/pages/layout/helpers.ts
@@ -1,4 +1,4 @@
-import { getFilename } from "@opencode-ai/util/path"
+import { getFilename } from "@opencode-ai/shared/util/path"
import { type Session } from "@opencode-ai/sdk/v2/client"
type SessionStore = {
diff --git a/packages/app/src/pages/layout/sidebar-items.tsx b/packages/app/src/pages/layout/sidebar-items.tsx
index e56accfc8..b0f45859a 100644
--- a/packages/app/src/pages/layout/sidebar-items.tsx
+++ b/packages/app/src/pages/layout/sidebar-items.tsx
@@ -4,7 +4,7 @@ import { Icon } from "@opencode-ai/ui/icon"
import { IconButton } from "@opencode-ai/ui/icon-button"
import { Spinner } from "@opencode-ai/ui/spinner"
import { Tooltip } from "@opencode-ai/ui/tooltip"
-import { getFilename } from "@opencode-ai/util/path"
+import { getFilename } from "@opencode-ai/shared/util/path"
import { A, useParams } from "@solidjs/router"
import { type Accessor, createMemo, For, type JSX, Match, Show, Switch } from "solid-js"
import { useGlobalSync } from "@/context/global-sync"
diff --git a/packages/app/src/pages/layout/sidebar-project.tsx b/packages/app/src/pages/layout/sidebar-project.tsx
index 7c9ae1aaf..076e1ef88 100644
--- a/packages/app/src/pages/layout/sidebar-project.tsx
+++ b/packages/app/src/pages/layout/sidebar-project.tsx
@@ -1,6 +1,6 @@
import { createMemo, For, Show, type Accessor, type JSX } from "solid-js"
import { createStore } from "solid-js/store"
-import { base64Encode } from "@opencode-ai/util/encode"
+import { base64Encode } from "@opencode-ai/shared/util/encode"
import { Button } from "@opencode-ai/ui/button"
import { ContextMenu } from "@opencode-ai/ui/context-menu"
import { HoverCard } from "@opencode-ai/ui/hover-card"
diff --git a/packages/app/src/pages/layout/sidebar-workspace.tsx b/packages/app/src/pages/layout/sidebar-workspace.tsx
index 68e36ff77..c1836fa8a 100644
--- a/packages/app/src/pages/layout/sidebar-workspace.tsx
+++ b/packages/app/src/pages/layout/sidebar-workspace.tsx
@@ -3,8 +3,8 @@ import { createEffect, createMemo, For, Show, type Accessor, type JSX } from "so
import { createStore } from "solid-js/store"
import { createSortable } from "@thisbeyond/solid-dnd"
import { createMediaQuery } from "@solid-primitives/media"
-import { base64Encode } from "@opencode-ai/util/encode"
-import { getFilename } from "@opencode-ai/util/path"
+import { base64Encode } from "@opencode-ai/shared/util/encode"
+import { getFilename } from "@opencode-ai/shared/util/path"
import { Button } from "@opencode-ai/ui/button"
import { Collapsible } from "@opencode-ai/ui/collapsible"
import { DropdownMenu } from "@opencode-ai/ui/dropdown-menu"
@@ -14,10 +14,11 @@ import { Spinner } from "@opencode-ai/ui/spinner"
import { Tooltip } from "@opencode-ai/ui/tooltip"
import { type Session } from "@opencode-ai/sdk/v2/client"
import { type LocalProject } from "@/context/layout"
-import { useGlobalSync } from "@/context/global-sync"
+import { loadSessionsQuery, useGlobalSync } from "@/context/global-sync"
import { useLanguage } from "@/context/language"
import { NewSessionItem, SessionItem, SessionSkeleton } from "./sidebar-items"
import { sortedRootSessions, workspaceKey } from "./helpers"
+import { useQuery } from "@tanstack/solid-query"
type InlineEditorComponent = (props: {
id: string
@@ -274,10 +275,10 @@ const WorkspaceSessionList = (props: {
<div class="relative w-full py-1">
<Button
variant="ghost"
- class="flex w-full text-left justify-start text-14-regular text-text-weak pl-9 pr-10"
+ class="flex w-full text-left justify-start text-14-regular text-text-weak pl-2 pr-10"
size="large"
onClick={(e: MouseEvent) => {
- props.loadMore()
+ void props.loadMore()
;(e.currentTarget as HTMLButtonElement).blur()
}}
>
@@ -454,7 +455,8 @@ export const LocalWorkspace = (props: {
const sessions = createMemo(() => sortedRootSessions(workspace().store, props.sortNow()))
const booted = createMemo((prev) => prev || workspace().store.status === "complete", false)
const count = createMemo(() => sessions()?.length ?? 0)
- const loading = createMemo(() => !booted() && count() === 0)
+ const query = useQuery(() => ({ ...loadSessionsQuery(props.project.worktree) }))
+ const loading = createMemo(() => query.isPending && count() === 0)
const hasMore = createMemo(() => workspace().store.sessionTotal > count())
const loadMore = async () => {
workspace().setStore("limit", (limit) => (limit ?? 0) + 5)
@@ -471,7 +473,7 @@ export const LocalWorkspace = (props: {
mobile={props.mobile}
ctx={props.ctx}
showNew={() => false}
- loading={loading}
+ loading={() => query.isLoading}
sessions={sessions}
hasMore={hasMore}
loadMore={loadMore}
diff --git a/packages/app/src/pages/session.tsx b/packages/app/src/pages/session.tsx
index eb6a49411..c4d642bf8 100644
--- a/packages/app/src/pages/session.tsx
+++ b/packages/app/src/pages/session.tsx
@@ -13,6 +13,7 @@ import {
on,
onMount,
untrack,
+ createResource,
} from "solid-js"
import { makeEventListener } from "@solid-primitives/event-listener"
import { createMediaQuery } from "@solid-primitives/media"
@@ -27,7 +28,7 @@ import { createAutoScroll } from "@opencode-ai/ui/hooks"
import { previewSelectedLines } from "@opencode-ai/ui/pierre/selection-bridge"
import { Button } from "@opencode-ai/ui/button"
import { showToast } from "@opencode-ai/ui/toast"
-import { checksum } from "@opencode-ai/util/encode"
+import { checksum } from "@opencode-ai/shared/util/encode"
import { useSearchParams } from "@solidjs/router"
import { NewSessionView, SessionHeader } from "@/components/session"
import { useComments } from "@/context/comments"
@@ -432,8 +433,6 @@ export default function Page() {
const info = createMemo(() => (params.id ? sync.session.get(params.id) : undefined))
const isChildSession = createMemo(() => !!info()?.parentID)
const diffs = createMemo(() => (params.id ? list(sync.data.session_diff[params.id]) : []))
- const sessionCount = createMemo(() => Math.max(info()?.summary?.files ?? 0, diffs().length))
- const hasSessionReview = createMemo(() => sessionCount() > 0)
const canReview = createMemo(() => !!sync.project)
const reviewTab = createMemo(() => isDesktop())
const tabState = createSessionTabs({
@@ -443,8 +442,6 @@ export default function Page() {
review: reviewTab,
hasReview: canReview,
})
- const contextOpen = tabState.contextOpen
- const openedTabs = tabState.openedTabs
const activeTab = tabState.activeTab
const activeFileTab = tabState.activeFileTab
const revertMessageID = createMemo(() => info()?.revert?.messageID)
@@ -487,7 +484,7 @@ export default function Page() {
if (!tab) return
const path = file.pathFromTab(tab)
- if (path) file.load(path)
+ if (path) void file.load(path)
})
createEffect(
@@ -808,8 +805,9 @@ export default function Page() {
const hasScrollGesture = () => Date.now() - ui.scrollGesture < scrollGestureWindowMs
- createEffect(
- on([() => sdk.directory, () => params.id] as const, ([, id]) => {
+ const [sessionSync] = createResource(
+ () => [sdk.directory, params.id] as const,
+ ([directory, id]) => {
if (refreshFrame !== undefined) cancelAnimationFrame(refreshFrame)
if (refreshTimer !== undefined) window.clearTimeout(refreshTimer)
refreshFrame = undefined
@@ -820,13 +818,10 @@ export default function Page() {
const stale = !cached
? false
: (() => {
- const info = getSessionPrefetch(sdk.directory, id)
+ const info = getSessionPrefetch(directory, id)
if (!info) return true
return Date.now() - info.at > SESSION_PREFETCH_TTL
})()
- untrack(() => {
- void sync.session.sync(id)
- })
refreshFrame = requestAnimationFrame(() => {
refreshFrame = undefined
@@ -838,7 +833,9 @@ export default function Page() {
})
}, 0)
})
- }),
+
+ return sync.session.sync(id)
+ },
)
createEffect(
@@ -1885,6 +1882,7 @@ export default function Page() {
return (
<div class="relative bg-background-base size-full overflow-hidden flex flex-col">
+ {sessionSync() ?? ""}
<SessionHeader />
<div class="flex-1 min-h-0 flex flex-col md:flex-row">
<Show when={!isDesktop() && !!params.id}>
diff --git a/packages/app/src/pages/session/composer/session-composer-state.ts b/packages/app/src/pages/session/composer/session-composer-state.ts
index eab210868..525766dcf 100644
--- a/packages/app/src/pages/session/composer/session-composer-state.ts
+++ b/packages/app/src/pages/session/composer/session-composer-state.ts
@@ -1,6 +1,5 @@
-import { createEffect, createMemo, on, onCleanup, onMount } from "solid-js"
+import { createEffect, createMemo, on, onCleanup } from "solid-js"
import { createStore } from "solid-js/store"
-import { makeEventListener } from "@solid-primitives/event-listener"
import type { PermissionRequest, QuestionRequest, Todo } from "@opencode-ai/sdk/v2"
import { useParams } from "@solidjs/router"
import { showToast } from "@opencode-ai/ui/toast"
@@ -9,7 +8,6 @@ import { useLanguage } from "@/context/language"
import { usePermission } from "@/context/permission"
import { useSDK } from "@/context/sdk"
import { useSync } from "@/context/sync"
-import { composerDriver, composerEnabled, composerEvent } from "@/testing/session-composer"
import { sessionPermissionRequest, sessionQuestionRequest } from "./session-request-tree"
export const todoState = (input: {
@@ -49,49 +47,7 @@ export function createSessionComposerState(options?: { closeMs?: number | (() =>
return !!permissionRequest() || !!questionRequest()
})
- const [test, setTest] = createStore({
- on: false,
- live: undefined as boolean | undefined,
- todos: undefined as Todo[] | undefined,
- })
-
- const pull = () => {
- const id = params.id
- if (!id) {
- setTest({ on: false, live: undefined, todos: undefined })
- return
- }
-
- const next = composerDriver(id)
- if (!next) {
- setTest({ on: false, live: undefined, todos: undefined })
- return
- }
-
- setTest({
- on: true,
- live: next.live,
- todos: next.todos?.map((todo) => ({ ...todo })),
- })
- }
-
- onMount(() => {
- if (!composerEnabled()) return
-
- pull()
- createEffect(on(() => params.id, pull, { defer: true }))
-
- const onEvent = (event: Event) => {
- const detail = (event as CustomEvent<{ sessionID?: string }>).detail
- if (detail?.sessionID !== params.id) return
- pull()
- }
-
- makeEventListener(window, composerEvent, onEvent)
- })
-
const todos = createMemo((): Todo[] => {
- if (test.on && test.todos !== undefined) return test.todos
const id = params.id
if (!id) return []
return globalSync.data.session_todo[id] ?? []
@@ -108,10 +64,7 @@ export function createSessionComposerState(options?: { closeMs?: number | (() =>
})
const busy = createMemo(() => status().type !== "idle")
- const live = createMemo(() => {
- if (test.on && test.live !== undefined) return test.live
- return busy() || blocked()
- })
+ const live = createMemo(() => busy() || blocked())
const [store, setStore] = createStore({
responding: undefined as string | undefined,
@@ -163,10 +116,6 @@ export function createSessionComposerState(options?: { closeMs?: number | (() =>
// Keep stale turn todos from reopening if the model never clears them.
const clear = () => {
- if (test.on && test.todos !== undefined) {
- setTest("todos", [])
- return
- }
const id = params.id
if (!id) return
globalSync.todo.set(id, [])
diff --git a/packages/app/src/pages/session/composer/session-todo-dock.tsx b/packages/app/src/pages/session/composer/session-todo-dock.tsx
index 2214248b1..fa8c17734 100644
--- a/packages/app/src/pages/session/composer/session-todo-dock.tsx
+++ b/packages/app/src/pages/session/composer/session-todo-dock.tsx
@@ -7,9 +7,8 @@ import { useSpring } from "@opencode-ai/ui/motion-spring"
import { TextReveal } from "@opencode-ai/ui/text-reveal"
import { TextStrikethrough } from "@opencode-ai/ui/text-strikethrough"
import { createResizeObserver } from "@solid-primitives/resize-observer"
-import { Index, createEffect, createMemo, onCleanup } from "solid-js"
+import { Index, createEffect, createMemo } from "solid-js"
import { createStore } from "solid-js/store"
-import { composerEnabled, composerProbe } from "@/testing/session-composer"
import { useLanguage } from "@/context/language"
const doneToken = "\u0000done\u0000"
@@ -81,8 +80,6 @@ export function SessionTodoDock(props: {
const off = createMemo(() => hide() > 0.98)
const turn = createMemo(() => Math.max(0, Math.min(1, value())))
const full = createMemo(() => Math.max(78, store.height))
- const e2e = composerEnabled()
- const probe = composerProbe(props.sessionID)
let contentRef: HTMLDivElement | undefined
createEffect(() => {
@@ -95,23 +92,6 @@ export function SessionTodoDock(props: {
createResizeObserver(el, update)
})
- createEffect(() => {
- if (!e2e) return
-
- probe.set({
- mounted: true,
- collapsed: store.collapsed,
- hidden: store.collapsed || off(),
- count: props.todos.length,
- states: props.todos.map((todo) => todo.status),
- })
- })
-
- onCleanup(() => {
- if (!e2e) return
- probe.drop()
- })
-
return (
<DockTray
data-component="session-todo-dock"
diff --git a/packages/app/src/pages/session/file-tabs.tsx b/packages/app/src/pages/session/file-tabs.tsx
index cb7617523..37bffcd2f 100644
--- a/packages/app/src/pages/session/file-tabs.tsx
+++ b/packages/app/src/pages/session/file-tabs.tsx
@@ -6,7 +6,7 @@ import type { FileSearchHandle } from "@opencode-ai/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 { sampledChecksum } from "@opencode-ai/util/encode"
+import { sampledChecksum } from "@opencode-ai/shared/util/encode"
import { DropdownMenu } from "@opencode-ai/ui/dropdown-menu"
import { IconButton } from "@opencode-ai/ui/icon-button"
import { Tabs } from "@opencode-ai/ui/tabs"
@@ -378,12 +378,6 @@ export function FileTabContent(props: { tab: string }) {
requestAnimationFrame(() => comments.clearFocus())
})
- const cancelCommenting = () => {
- const p = path()
- if (p) file.setSelectedLines(p, null)
- setNote("commenting", null)
- }
-
let prev = {
loaded: false,
ready: false,
diff --git a/packages/app/src/pages/session/helpers.ts b/packages/app/src/pages/session/helpers.ts
index f3215f685..e136ba999 100644
--- a/packages/app/src/pages/session/helpers.ts
+++ b/packages/app/src/pages/session/helpers.ts
@@ -117,7 +117,7 @@ export const createOpenReviewFile = (input: {
input.openTab(tab)
input.setActive(tab)
}
- if (maybePromise instanceof Promise) maybePromise.then(open)
+ if (maybePromise instanceof Promise) void maybePromise.then(open)
else open()
})
}
diff --git a/packages/app/src/pages/session/message-timeline.tsx b/packages/app/src/pages/session/message-timeline.tsx
index fe6447c2e..978f188b6 100644
--- a/packages/app/src/pages/session/message-timeline.tsx
+++ b/packages/app/src/pages/session/message-timeline.tsx
@@ -15,8 +15,8 @@ import { ScrollView } from "@opencode-ai/ui/scroll-view"
import { TextField } from "@opencode-ai/ui/text-field"
import type { AssistantMessage, Message as MessageType, Part, TextPart, UserMessage } from "@opencode-ai/sdk/v2"
import { showToast } from "@opencode-ai/ui/toast"
-import { Binary } from "@opencode-ai/util/binary"
-import { getFilename } from "@opencode-ai/util/path"
+import { Binary } from "@opencode-ai/shared/util/binary"
+import { getFilename } from "@opencode-ai/shared/util/path"
import { Popover as KobaltePopover } from "@kobalte/core/popover"
import { shouldMarkBoundaryGesture, normalizeWheelDelta } from "@/pages/session/message-gesture"
import { SessionContextUsage } from "@/components/session-context-usage"
@@ -642,10 +642,10 @@ export function MessageTimeline(props: {
onClick={props.onResumeScroll}
>
<div
- class="flex items-center justify-center w-8 h-6 rounded-[6px] border border-[var(--gray-dark-7)] bg-[color-mix(in_srgb,var(--gray-dark-3)_80%,transparent)] backdrop-blur-[0.75px] transition-colors group-hover:border-[var(--gray-dark-8)] [--icon-base:var(--gray-dark-10)] group-hover:[--icon-base:var(--gray-dark-11)]"
+ class="flex items-center justify-center w-8 h-6 rounded-[6px] border border-border-weaker-base bg-[color-mix(in_srgb,var(--surface-raised-stronger-non-alpha)_80%,transparent)] backdrop-blur-[0.75px] transition-colors group-hover:border-[var(--border-weak-base)] group-hover:[--icon-base:var(--icon-hover)]"
style={{
"box-shadow":
- "0 51px 60px 0 rgba(0,0,0,0.13), 0 15.375px 18.088px 0 rgba(0,0,0,0.19), 0 6.386px 7.513px 0 rgba(0,0,0,0.25), 0 2.31px 2.717px 0 rgba(0,0,0,0.38)",
+ "0 51px 60px 0 rgba(0,0,0,0.10), 0 15px 18px 0 rgba(0,0,0,0.12), 0 6.386px 7.513px 0 rgba(0,0,0,0.12), 0 2.31px 2.717px 0 rgba(0,0,0,0.20)",
}}
>
<Icon name="arrow-down-to-line" size="small" />
@@ -791,7 +791,7 @@ export function MessageTimeline(props: {
data-slot="session-title-child"
value={title.draft}
disabled={titleMutation.isPending}
- class="text-14-medium text-text-strong grow-1 min-w-0 rounded-[6px]"
+ class="text-14-medium text-text-strong grow-1 min-w-0 rounded-[6px] pl-1 -ml-1"
style={{ "--inline-input-shadow": "var(--shadow-xs-border-select)" }}
onInput={(event) => setTitle("draft", event.currentTarget.value)}
onKeyDown={(event) => {
diff --git a/packages/app/src/pages/session/review-tab.tsx b/packages/app/src/pages/session/review-tab.tsx
index 71dfe375e..5719fce31 100644
--- a/packages/app/src/pages/session/review-tab.tsx
+++ b/packages/app/src/pages/session/review-tab.tsx
@@ -1,4 +1,4 @@
-import { createEffect, createSignal, onCleanup, type JSX } from "solid-js"
+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"
diff --git a/packages/app/src/pages/session/terminal-panel.tsx b/packages/app/src/pages/session/terminal-panel.tsx
index 1161d565a..2c2d9817f 100644
--- a/packages/app/src/pages/session/terminal-panel.tsx
+++ b/packages/app/src/pages/session/terminal-panel.tsx
@@ -19,7 +19,6 @@ import { terminalTabLabel } from "@/pages/session/terminal-label"
import { createSizing, focusTerminalById } from "@/pages/session/helpers"
import { getTerminalHandoff, setTerminalHandoff } from "@/pages/session/handoff"
import { useSessionLayout } from "@/pages/session/session-layout"
-import { terminalProbe } from "@/testing/terminal"
export function TerminalPanel() {
const delays = [120, 240]
@@ -78,12 +77,9 @@ export function TerminalPanel() {
)
const focus = (id: string) => {
- const probe = terminalProbe(id)
- probe.focus(delays.length + 1)
focusTerminalById(id)
const frame = requestAnimationFrame(() => {
- probe.step()
if (!opened()) return
if (terminal.active() !== id) return
focusTerminalById(id)
@@ -91,7 +87,6 @@ export function TerminalPanel() {
const timers = delays.map((ms) =>
window.setTimeout(() => {
- probe.step()
if (!opened()) return
if (terminal.active() !== id) return
focusTerminalById(id)
@@ -99,7 +94,6 @@ export function TerminalPanel() {
)
return () => {
- probe.focus(0)
cancelAnimationFrame(frame)
for (const timer of timers) clearTimeout(timer)
}
diff --git a/packages/app/src/pages/session/use-session-commands.tsx b/packages/app/src/pages/session/use-session-commands.tsx
index 239795373..b5d254463 100644
--- a/packages/app/src/pages/session/use-session-commands.tsx
+++ b/packages/app/src/pages/session/use-session-commands.tsx
@@ -12,7 +12,7 @@ import { useSDK } from "@/context/sdk"
import { useSync } from "@/context/sync"
import { useTerminal } from "@/context/terminal"
import { showToast } from "@opencode-ai/ui/toast"
-import { findLast } from "@opencode-ai/util/array"
+import { findLast } from "@opencode-ai/shared/util/array"
import { createSessionTabs } from "@/pages/session/helpers"
import { extractPromptFromParts } from "@/utils/prompt"
import { UserMessage } from "@opencode-ai/sdk/v2"