diff --git a/packages/opencode/src/cli/cmd/tui/component/border.tsx b/packages/opencode/src/cli/cmd/tui/component/border.tsx index bbf84e8a2..82b942c94 100644 --- a/packages/opencode/src/cli/cmd/tui/component/border.tsx +++ b/packages/opencode/src/cli/cmd/tui/component/border.tsx @@ -1,4 +1,4 @@ -import { Theme } from "../context/theme" +import { Theme } from "@tui/context/theme" export const SplitBorder = { border: ["left" as const, "right" as const], diff --git a/packages/opencode/src/cli/cmd/tui/component/dialog-agent.tsx b/packages/opencode/src/cli/cmd/tui/component/dialog-agent.tsx index 246c8be41..65aaeb22b 100644 --- a/packages/opencode/src/cli/cmd/tui/component/dialog-agent.tsx +++ b/packages/opencode/src/cli/cmd/tui/component/dialog-agent.tsx @@ -1,7 +1,7 @@ import { createMemo } from "solid-js" -import { useLocal } from "../context/local" -import { DialogSelect } from "../ui/dialog-select" -import { useDialog } from "../ui/dialog" +import { useLocal } from "@tui/context/local" +import { DialogSelect } from "@tui/ui/dialog-select" +import { useDialog } from "@tui/ui/dialog" export function DialogAgent() { const local = useLocal() diff --git a/packages/opencode/src/cli/cmd/tui/component/dialog-command.tsx b/packages/opencode/src/cli/cmd/tui/component/dialog-command.tsx index 4641c9121..4babe4d36 100644 --- a/packages/opencode/src/cli/cmd/tui/component/dialog-command.tsx +++ b/packages/opencode/src/cli/cmd/tui/component/dialog-command.tsx @@ -1,5 +1,5 @@ -import { useDialog } from "../ui/dialog" -import { DialogSelect, type DialogSelectOption } from "../ui/dialog-select" +import { useDialog } from "@tui/ui/dialog" +import { DialogSelect, type DialogSelectOption } from "@tui/ui/dialog-select" import { createContext, createMemo, @@ -10,7 +10,7 @@ import { type ParentProps, } from "solid-js" import { useKeyboard } from "@opentui/solid" -import { useKeybind } from "../context/keybind" +import { useKeybind } from "@tui/context/keybind" type Context = ReturnType const ctx = createContext() @@ -26,6 +26,7 @@ function init() { useKeyboard((evt) => { for (const option of options()) { if (option.keybind && keybind.match(option.keybind, evt)) { + evt.preventDefault() option.onSelect?.(dialog) return } diff --git a/packages/opencode/src/cli/cmd/tui/component/dialog-model.tsx b/packages/opencode/src/cli/cmd/tui/component/dialog-model.tsx index e255efc50..d797ce987 100644 --- a/packages/opencode/src/cli/cmd/tui/component/dialog-model.tsx +++ b/packages/opencode/src/cli/cmd/tui/component/dialog-model.tsx @@ -1,9 +1,9 @@ import { createMemo } from "solid-js" -import { useLocal } from "../context/local" -import { useSync } from "../context/sync" +import { useLocal } from "@tui/context/local" +import { useSync } from "@tui/context/sync" import { map, pipe, flatMap, entries, filter, isDeepEqual } from "remeda" -import { DialogSelect } from "../ui/dialog-select" -import { useDialog } from "../ui/dialog" +import { DialogSelect } from "@tui/ui/dialog-select" +import { useDialog } from "@tui/ui/dialog" export function DialogModel() { const local = useLocal() diff --git a/packages/opencode/src/cli/cmd/tui/component/dialog-session-list.tsx b/packages/opencode/src/cli/cmd/tui/component/dialog-session-list.tsx index 8fcd445e3..6db67c942 100644 --- a/packages/opencode/src/cli/cmd/tui/component/dialog-session-list.tsx +++ b/packages/opencode/src/cli/cmd/tui/component/dialog-session-list.tsx @@ -1,8 +1,9 @@ -import { useDialog } from "../ui/dialog" -import { DialogSelect } from "../ui/dialog-select" -import { useRoute } from "../context/route" -import { useSync } from "../context/sync" +import { useDialog } from "@tui/ui/dialog" +import { DialogSelect } from "@tui/ui/dialog-select" +import { useRoute } from "@tui/context/route" +import { useSync } from "@tui/context/sync" import { createMemo, onMount } from "solid-js" +import { Locale } from "@/util/locale" export function DialogSessionList() { const dialog = useDialog() @@ -12,7 +13,8 @@ export function DialogSessionList() { const options = createMemo(() => { const today = new Date().toDateString() return sync.data.session.map((x) => { - let category = new Date(x.time.created).toDateString() + const date = new Date(x.time.updated) + let category = date.toDateString() if (category === today) { category = "Today" } @@ -20,6 +22,7 @@ export function DialogSessionList() { title: x.title, value: x.id, category, + footer: Locale.time(x.time.updated), } }) }) @@ -32,6 +35,7 @@ export function DialogSessionList() { { route.navigate({ type: "session", diff --git a/packages/opencode/src/cli/cmd/tui/component/dialog-tag.tsx b/packages/opencode/src/cli/cmd/tui/component/dialog-tag.tsx index af5320d4e..652c6a841 100644 --- a/packages/opencode/src/cli/cmd/tui/component/dialog-tag.tsx +++ b/packages/opencode/src/cli/cmd/tui/component/dialog-tag.tsx @@ -1,7 +1,7 @@ import { createMemo, createResource } from "solid-js" -import { DialogSelect } from "../ui/dialog-select" -import { useDialog } from "../ui/dialog" -import { useSDK } from "../context/sdk" +import { DialogSelect } from "@tui/ui/dialog-select" +import { useDialog } from "@tui/ui/dialog" +import { useSDK } from "@tui/context/sdk" import { createStore } from "solid-js/store" export function DialogTag(props: { onSelect?: (value: string) => void }) { diff --git a/packages/opencode/src/cli/cmd/tui/component/prompt.tsx b/packages/opencode/src/cli/cmd/tui/component/prompt.tsx index 5d2fe2d3e..2ea2cb6eb 100644 --- a/packages/opencode/src/cli/cmd/tui/component/prompt.tsx +++ b/packages/opencode/src/cli/cmd/tui/component/prompt.tsx @@ -1,20 +1,20 @@ import { InputRenderable, TextAttributes, BoxRenderable, type ParsedKey } from "@opentui/core" import { createEffect, createMemo, createResource, For, Match, onMount, Show, Switch } from "solid-js" import { firstBy } from "remeda" -import { useLocal } from "../context/local" -import { Theme } from "../context/theme" -import { useDialog } from "../ui/dialog" -import { SplitBorder } from "./border" -import { useSDK } from "../context/sdk" -import { useRoute } from "../context/route" -import { useSync } from "../context/sync" -import { Identifier } from "../../../../id/id" +import { useLocal } from "@tui/context/local" +import { Theme } from "@tui/context/theme" +import { useDialog } from "@tui/ui/dialog" +import { SplitBorder } from "@tui/component/border" +import { useSDK } from "@tui/context/sdk" +import { useRoute } from "@tui/context/route" +import { useSync } from "@tui/context/sync" +import { Identifier } from "@/id/id" import { createStore, produce } from "solid-js/store" import type { FilePart } from "@opencode-ai/sdk" import fuzzysort from "fuzzysort" -import { useCommandDialog } from "./dialog-command" -import { useKeybind } from "../context/keybind" -import { Clipboard } from "../../../../util/clipboard" +import { useCommandDialog } from "@tui/component/dialog-command" +import { useKeybind } from "@tui/context/keybind" +import { Clipboard } from "@/util/clipboard" export type PromptProps = { sessionID?: string diff --git a/packages/opencode/src/cli/cmd/tui/context/keybind.tsx b/packages/opencode/src/cli/cmd/tui/context/keybind.tsx index ee6431420..4c8de8a9e 100644 --- a/packages/opencode/src/cli/cmd/tui/context/keybind.tsx +++ b/packages/opencode/src/cli/cmd/tui/context/keybind.tsx @@ -1,13 +1,13 @@ import { createMemo, useContext, type ParentProps } from "solid-js" -import { useSync } from "./sync" -import { Keybind } from "../../../../util/keybind" +import { useSync } from "@tui/context/sync" +import { Keybind } from "@/util/keybind" import { pipe, mapValues } from "remeda" import type { KeybindsConfig } from "@opencode-ai/sdk" import { createContext } from "solid-js" import type { ParsedKey, Renderable } from "@opentui/core" import { createStore } from "solid-js/store" import { useKeyboard, useRenderer } from "@opentui/solid" -import { Instance } from "../../../../project/instance" +import { Instance } from "@/project/instance" export function init() { const sync = useSync() diff --git a/packages/opencode/src/cli/cmd/tui/context/local.tsx b/packages/opencode/src/cli/cmd/tui/context/local.tsx index 6d196be20..f3dc2135d 100644 --- a/packages/opencode/src/cli/cmd/tui/context/local.tsx +++ b/packages/opencode/src/cli/cmd/tui/context/local.tsx @@ -1,10 +1,10 @@ import { createStore } from "solid-js/store" import { batch, createContext, createEffect, createMemo, useContext, type ParentProps } from "solid-js" -import { useSync } from "./sync" -import { Theme } from "./theme" +import { useSync } from "@tui/context/sync" +import { Theme } from "@tui/context/theme" import { uniqueBy } from "remeda" import path from "path" -import { Global } from "../../../../global" +import { Global } from "@/global" function init() { const sync = useSync() diff --git a/packages/opencode/src/cli/cmd/tui/context/sdk.tsx b/packages/opencode/src/cli/cmd/tui/context/sdk.tsx index b7ec3f89c..76c1f7648 100644 --- a/packages/opencode/src/cli/cmd/tui/context/sdk.tsx +++ b/packages/opencode/src/cli/cmd/tui/context/sdk.tsx @@ -1,6 +1,6 @@ import { createContext, useContext, type ParentProps } from "solid-js" import { createOpencodeClient } from "@opencode-ai/sdk" -import { Server } from "../../../../server/server" +import { Server } from "@/server/server" function init() { const client = createOpencodeClient({ diff --git a/packages/opencode/src/cli/cmd/tui/context/sync.tsx b/packages/opencode/src/cli/cmd/tui/context/sync.tsx index 053c66797..516791752 100644 --- a/packages/opencode/src/cli/cmd/tui/context/sync.tsx +++ b/packages/opencode/src/cli/cmd/tui/context/sync.tsx @@ -1,8 +1,8 @@ import type { Message, Agent, Provider, Session, Part, Config, Todo, Command } from "@opencode-ai/sdk" import { createStore, produce, reconcile } from "solid-js/store" -import { useSDK } from "./sdk" +import { useSDK } from "@tui/context/sdk" import { createContext, Show, useContext, type ParentProps } from "solid-js" -import { Binary } from "../../../../util/binary" +import { Binary } from "@/util/binary" function init() { const [store, setStore] = createStore<{ diff --git a/packages/opencode/src/cli/cmd/tui/context/theme.tsx b/packages/opencode/src/cli/cmd/tui/context/theme.tsx index fe39d89a9..629daffd2 100644 --- a/packages/opencode/src/cli/cmd/tui/context/theme.tsx +++ b/packages/opencode/src/cli/cmd/tui/context/theme.tsx @@ -255,7 +255,7 @@ type Theme = { } import { createContext, useContext, createSignal, createEffect, onMount } from "solid-js" -import { Storage } from "../../../../storage/storage" +import { Storage } from "@/storage/storage" export const Theme = Object.entries(OPENCODE_THEME).reduce((acc, [key, value]) => { acc[key as keyof Theme] = value.dark diff --git a/packages/opencode/src/cli/cmd/tui/home.tsx b/packages/opencode/src/cli/cmd/tui/routes/home.tsx similarity index 91% rename from packages/opencode/src/cli/cmd/tui/home.tsx rename to packages/opencode/src/cli/cmd/tui/routes/home.tsx index 8878c548f..842c7a2ab 100644 --- a/packages/opencode/src/cli/cmd/tui/home.tsx +++ b/packages/opencode/src/cli/cmd/tui/routes/home.tsx @@ -1,7 +1,7 @@ -import { Installation } from "../../../installation" -import { useTheme } from "./context/theme" +import { Installation } from "@/installation" +import { useTheme } from "@tui/context/theme" import { TextAttributes } from "@opentui/core" -import { Prompt } from "./component/prompt" +import { Prompt } from "@tui/component/prompt" import { For } from "solid-js" export function Home() { @@ -41,7 +41,7 @@ function HelpRow(props: { children: string; slash: string; theme: any }) { return ( /{props.slash.padEnd(10, " ")} - {props.children.padEnd(15, " ")} + {props.children.padEnd(19, " ")} ctrl+x n ) diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/header.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/header.tsx new file mode 100644 index 000000000..041130340 --- /dev/null +++ b/packages/opencode/src/cli/cmd/tui/routes/session/header.tsx @@ -0,0 +1,63 @@ +import { createMemo, Match, Show, Switch } from "solid-js" +import { useRouteData } from "@tui/context/route" +import { useSync } from "@tui/context/sync" +import { pipe, sumBy } from "remeda" +import { Theme } from "@tui/context/theme" +import { SplitBorder } from "@tui/component/border" +import { Locale } from "@/util/locale" +import type { AssistantMessage } from "@opencode-ai/sdk" + +export function Header() { + const route = useRouteData("session") + const sync = useSync() + const session = createMemo(() => sync.session.get(route.sessionID)!) + const messages = createMemo(() => sync.data.message[route.sessionID] ?? []) + + const cost = createMemo(() => { + const total = pipe( + messages(), + sumBy((x) => (x.role === "assistant" ? x.cost : 0)), + ) + return new Intl.NumberFormat("en-US", { + style: "currency", + currency: "USD", + }).format(total) + }) + + const context = createMemo(() => { + const last = messages().findLast((x) => x.role === "assistant" && x.tokens.output > 0) as AssistantMessage + if (!last) return + const total = + last.tokens.input + last.tokens.output + last.tokens.reasoning + last.tokens.cache.read + last.tokens.cache.write + const model = sync.data.provider.find((x) => x.id === last.providerID)?.models[last.modelID] + return { + total: Locale.number(total), + percentage: (model ? Locale.number(Math.round((total / model.limit.context) * 100)) : "0") + "%", + } + }) + + return ( + + + # {session().title} + + + + + {session().share!.url} + + + + /share to create a shareable link + + + + + + {context()!.total}/{context()!.percentage} ({cost()}) + + + + + ) +} diff --git a/packages/opencode/src/cli/cmd/tui/session.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx similarity index 90% rename from packages/opencode/src/cli/cmd/tui/session.tsx rename to packages/opencode/src/cli/cmd/tui/routes/session/index.tsx index 7ae0094a1..cc863953b 100644 --- a/packages/opencode/src/cli/cmd/tui/session.tsx +++ b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx @@ -1,32 +1,33 @@ import { createEffect, createMemo, For, Match, Show, Switch, type Component } from "solid-js" import { Dynamic } from "solid-js/web" import path from "path" -import { useRouteData } from "./context/route" -import { useSync } from "./context/sync" -import { SplitBorder } from "./component/border" -import { Theme } from "./context/theme" +import { useRouteData } from "@tui/context/route" +import { useSync } from "@tui/context/sync" +import { SplitBorder } from "@tui/component/border" +import { Theme } from "@tui/context/theme" import { BoxRenderable, ScrollBoxRenderable } from "@opentui/core" -import { Prompt } from "./component/prompt" +import { Prompt } from "@tui/component/prompt" import type { AssistantMessage, Part, ToolPart, UserMessage, TextPart } from "@opencode-ai/sdk" -import { useLocal } from "./context/local" -import { Locale } from "../../../util/locale" -import type { Tool } from "../../../tool/tool" -import type { ReadTool } from "../../../tool/read" -import type { WriteTool } from "../../../tool/write" -import { BashTool } from "../../../tool/bash" -import type { GlobTool } from "../../../tool/glob" -import { TodoWriteTool } from "../../../tool/todo" -import type { GrepTool } from "../../../tool/grep" -import type { ListTool } from "../../../tool/ls" -import type { EditTool } from "../../../tool/edit" -import type { PatchTool } from "../../../tool/patch" -import type { WebFetchTool } from "../../../tool/webfetch" -import type { TaskTool } from "../../../tool/task" +import { useLocal } from "@tui/context/local" +import { Locale } from "@/util/locale" +import type { Tool } from "@/tool/tool" +import type { ReadTool } from "@/tool/read" +import type { WriteTool } from "@/tool/write" +import { BashTool } from "@/tool/bash" +import type { GlobTool } from "@/tool/glob" +import { TodoWriteTool } from "@/tool/todo" +import type { GrepTool } from "@/tool/grep" +import type { ListTool } from "@/tool/ls" +import type { EditTool } from "@/tool/edit" +import type { PatchTool } from "@/tool/patch" +import type { WebFetchTool } from "@/tool/webfetch" +import type { TaskTool } from "@/tool/task" import { useKeyboard, type BoxProps, type JSX } from "@opentui/solid" -import { useSDK } from "./context/sdk" -import { useCommandDialog } from "./component/dialog-command" -import { Shimmer } from "./ui/shimmer" -import { useKeybind } from "./context/keybind" +import { useSDK } from "@tui/context/sdk" +import { useCommandDialog } from "@tui/component/dialog-command" +import { Shimmer } from "@tui/ui/shimmer" +import { useKeybind } from "@tui/context/keybind" +import { Header } from "./header" export function Session() { const route = useRouteData("session") @@ -102,24 +103,7 @@ export function Session() { return ( - - - #{" "} - {session().title} - - - - - {session().share!.url} - - - - /share to create a shareable link - - - - - +
(scroll = r)} scrollbarOptions={{ visible: false }} diff --git a/packages/opencode/src/cli/cmd/tui/tui.tsx b/packages/opencode/src/cli/cmd/tui/tui.tsx index 3ef6d1772..df134b59d 100644 --- a/packages/opencode/src/cli/cmd/tui/tui.tsx +++ b/packages/opencode/src/cli/cmd/tui/tui.tsx @@ -1,24 +1,25 @@ -import { cmd } from "../cmd" +import { cmd } from "@/cli/cmd/cmd" import { render, useKeyboard, useRenderer, useTerminalDimensions } from "@opentui/solid" import { TextAttributes } from "@opentui/core" -import { RouteProvider, useRoute } from "./context/route" -import { Home } from "./home" +import { RouteProvider, useRoute } from "@tui/context/route" import { Switch, Match, createEffect } from "solid-js" -import { ThemeProvider, useTheme } from "./context/theme" -import { Installation } from "../../../installation" -import { Global } from "../../../global" -import { DialogProvider, useDialog } from "./ui/dialog" -import { SDKProvider } from "./context/sdk" -import { SyncProvider } from "./context/sync" -import { LocalProvider, useLocal } from "./context/local" -import { DialogModel } from "./component/dialog-model" -import { Session } from "./session" -import { CommandProvider, useCommandDialog } from "./component/dialog-command" -import { DialogAgent } from "./component/dialog-agent" -import { DialogSessionList } from "./component/dialog-session-list" -import { KeybindProvider, useKeybind } from "./context/keybind" -import { Config } from "../../../config/config" -import { Instance } from "../../../project/instance" +import { ThemeProvider, useTheme } from "@tui/context/theme" +import { Installation } from "@/installation" +import { Global } from "@/global" +import { DialogProvider, useDialog } from "@tui/ui/dialog" +import { SDKProvider } from "@tui/context/sdk" +import { SyncProvider } from "@tui/context/sync" +import { LocalProvider, useLocal } from "@tui/context/local" +import { DialogModel } from "@tui/component/dialog-model" +import { CommandProvider, useCommandDialog } from "@tui/component/dialog-command" +import { DialogAgent } from "@tui/component/dialog-agent" +import { DialogSessionList } from "@tui/component/dialog-session-list" +import { KeybindProvider, useKeybind } from "@tui/context/keybind" +import { Config } from "@/config/config" +import { Instance } from "@/project/instance" + +import { Home } from "@tui/routes/home" +import { Session } from "@tui/routes/session" export const TuiCommand = cmd({ command: "$0 [project]", diff --git a/packages/opencode/src/cli/cmd/tui/ui/dialog-select.tsx b/packages/opencode/src/cli/cmd/tui/ui/dialog-select.tsx index 1bcf9174a..479dff354 100644 --- a/packages/opencode/src/cli/cmd/tui/ui/dialog-select.tsx +++ b/packages/opencode/src/cli/cmd/tui/ui/dialog-select.tsx @@ -1,20 +1,21 @@ import { InputRenderable, RGBA, ScrollBoxRenderable, TextAttributes } from "@opentui/core" -import { Theme } from "../context/theme" -import { entries, filter, flatMap, groupBy, pipe } from "remeda" +import { Theme } from "@tui/context/theme" +import { entries, filter, flatMap, groupBy, pipe, take } from "remeda" import { batch, createEffect, createMemo, For, Show } from "solid-js" import { createStore } from "solid-js/store" import { useKeyboard } from "@opentui/solid" import * as fuzzysort from "fuzzysort" import { isDeepEqual } from "remeda" -import { useDialog, type DialogContext } from "./dialog" +import { useDialog, type DialogContext } from "@tui/ui/dialog" import type { KeybindsConfig } from "@opencode-ai/sdk" -import { useKeybind } from "../context/keybind" +import { useKeybind } from "@tui/context/keybind" export interface DialogSelectProps { title: string options: DialogSelectOption[] onFilter?: (query: string) => void onSelect?: (option: DialogSelectOption) => void + limit?: number current?: T } @@ -23,6 +24,7 @@ export interface DialogSelectOption { value: T keybind?: keyof KeybindsConfig description?: string + footer?: string category?: string disabled?: boolean onSelect?: (ctx: DialogContext) => void @@ -42,6 +44,7 @@ export function DialogSelect(props: DialogSelectProps) { const result = pipe( props.options, filter((x) => x.disabled !== false), + take(props.limit ?? Infinity), (x) => (!needle ? x : fuzzysort.go(needle, x, { keys: ["title", "category"] }).map((x) => x.obj)), groupBy((x) => x.category ?? ""), // mapValues((x) => x.sort((a, b) => a.title.localeCompare(b.title))), @@ -64,7 +67,7 @@ export function DialogSelect(props: DialogSelectProps) { scroll.scrollTo(0) }) - function move(direction: -1 | 1) { + function move(direction: number) { let next = store.selected + direction if (next < 0) next = flat().length - 1 if (next >= flat().length) next = 0 @@ -89,6 +92,8 @@ export function DialogSelect(props: DialogSelectProps) { useKeyboard((evt) => { if (evt.name === "up") move(-1) if (evt.name === "down") move(1) + if (evt.name === "pageup") move(-10) + if (evt.name === "pagedown") move(10) if (evt.name === "return") { const option = selected() if (option.onSelect) option.onSelect(dialog) @@ -97,6 +102,7 @@ export function DialogSelect(props: DialogSelectProps) { }) let scroll: ScrollBoxRenderable + const keybind = useKeybind() return ( @@ -147,7 +153,7 @@ export function DialogSelect(props: DialogSelectProps) { - - {keybind.print(props.keybind as any)} + + {props.footer} ) diff --git a/packages/opencode/src/cli/cmd/tui/ui/dialog.tsx b/packages/opencode/src/cli/cmd/tui/ui/dialog.tsx index c03ca22af..f020acd64 100644 --- a/packages/opencode/src/cli/cmd/tui/ui/dialog.tsx +++ b/packages/opencode/src/cli/cmd/tui/ui/dialog.tsx @@ -1,6 +1,6 @@ import { useKeyboard, useTerminalDimensions } from "@opentui/solid" import { createContext, For, Show, useContext, type JSX, type ParentProps } from "solid-js" -import { Theme } from "../context/theme" +import { Theme } from "@tui/context/theme" import { RGBA } from "@opentui/core" import { createStore, produce } from "solid-js/store" diff --git a/packages/opencode/src/util/locale.ts b/packages/opencode/src/util/locale.ts index 66233e5a1..79920107c 100644 --- a/packages/opencode/src/util/locale.ts +++ b/packages/opencode/src/util/locale.ts @@ -7,4 +7,13 @@ export namespace Locale { const date = new Date(input) return date.toLocaleTimeString() } + + export function number(num: number): string { + if (num >= 1000000) { + return (num / 1000000).toFixed(1) + "M" + } else if (num >= 1000) { + return (num / 1000).toFixed(1) + "K" + } + return num.toString() + } } diff --git a/packages/opencode/tsconfig.json b/packages/opencode/tsconfig.json index 68f410196..b19ea7c77 100644 --- a/packages/opencode/tsconfig.json +++ b/packages/opencode/tsconfig.json @@ -5,6 +5,11 @@ "jsx": "preserve", "jsxImportSource": "@opentui/solid", "lib": ["ESNext", "DOM", "DOM.Iterable"], - "customConditions": ["development", "browser"] + "customConditions": ["development", "browser"], + "baseUrl": ".", + "paths": { + "@/*": ["./src/*"], + "@tui/*": ["./src/cli/cmd/tui/*"] + } } }