import type { TuiThemeCurrent } from "@opencode-ai/plugin/tui"; import type { BalanceEntry } from "../balance-providers"; import type { LangCode } from "../i18n"; /** 会话信息(面板消费的字段;SDK Session 类型过严,用宽松接口) */ export interface PanelSession { id: string; title?: string; agent?: string; model?: { providerID?: string; id?: string; }; tokens?: { input?: number; output?: number; reasoning?: number; cache?: { read?: number; write?: number; }; }; cost?: number; [key: string]: unknown; } /** * Panel API 契约:TokenCachePanel 消费的宿主 API 子集。 * V1(TuiPluginApi)天然满足;V2(opencode2 context)由 v2-panel-api 适配实现。 */ export interface PanelApi { kv: { ready: boolean; get(key: string, fallback?: T): T | undefined; set(key: string, value: unknown): void | Promise; }; state: { session: { get(id: string): PanelSession | undefined; /** V1 返回 sdk/v2 的 Message、V2 返回 SessionMessageInfo——统一放宽 */ messages(id: string): readonly any[]; }; provider: readonly Record[]; config: any; part(messageID: string): readonly any[]; path: { directory: string; }; }; event: { on(type: string, handler: (event: unknown) => void): () => void; }; renderer: { terminalWidth: number; }; keys: { formatBindings(binding: unknown): string | undefined; }; tuiConfig: { keybinds: { get(command: string): unknown; }; }; } export interface BalanceState { status: "idle" | "loading" | "ok" | "error"; data: BalanceEntry[] | null; lastFetch: number; error?: string; key?: string; } /** Signals shared between the TUI component and slash commands. * Created in the `tui` function scope so they do not survive module reload — * the component re-creates them on mount and restores user config from kv. */ export interface PanelSignals { currencySymbol: () => string; setCurrencySymbol: (v: string) => void; exchangeRate: () => number; setExchangeRate: (v: number) => void; langCode: () => LangCode; setLangCode: (v: LangCode) => void; sectionDetail: () => boolean; setSectionDetail: (v: boolean) => void; sectionModel: () => boolean; setSectionModel: (v: boolean) => void; sectionDist: () => boolean; setSectionDist: (v: boolean) => void; sectionSkills: () => boolean; setSectionSkills: (v: boolean) => void; sectionBalance: () => boolean; setSectionBalance: (v: boolean) => void; /** Bottom status bar (prompt hint line) visibility. */ sectionBottom: () => boolean; setSectionBottom: (v: boolean) => void; /** Increment to force a balance re-fetch. */ balanceRefresh: () => number; setBalanceRefresh: (v: number) => void; /** Currently selected balance provider id (e.g. "deepseek"). */ balanceProviderId: () => string; setBalanceProviderId: (v: string) => void; /** Auto-switch to the session's provider for balance display. Manual switch disables it. */ autoBalance: () => boolean; setAutoBalance: (v: boolean) => void; /** True when the session's provider has no balance adapter (auto mode). Suppresses balance polling. */ balanceUnsupported: () => boolean; setBalanceUnsupported: (v: boolean) => void; /** Shared balance query state — single source of truth for sidebar and bottom bar. */ balanceState: () => BalanceState; /** Preferred currency code for balance display (CNY / USD / …). Empty = first entry. */ balanceCurrency: () => string; setBalanceCurrency: (v: string) => void; borderVisible: () => boolean; setBorderVisible: (v: boolean) => void; /** When set, the panel renders stats for this session instead of the main one. */ overrideSessionId: () => string | undefined; setOverrideSessionId: (v: string | undefined) => void; /** True while our sidebar panel is mounted — host sidebar is visible (occupies 42 cols). */ sidebarVisible: () => boolean; setSidebarVisible: (v: boolean) => void; } export type { TuiThemeCurrent };