export declare const WORKBENCH_MAIN_ROUTE = "#/agent-workbench"; export declare const WORKBENCH_DOCK_ROUTE = "#/agent-workbench-dock"; export declare const WORKBENCH_RAIL_DEFAULT = 300; export declare const WORKBENCH_RAIL_MIN = 176; export declare const WORKBENCH_RAIL_MAX = 460; export declare const WORKBENCH_RAIL_COLLAPSED = 40; export type WorkbenchSurface = 'main' | 'dock'; export type WorkbenchPaneKind = 'terminal' | 'web'; export type WorkbenchSplitAxis = 'horizontal' | 'vertical'; export type WorkbenchSessionGroup = 'needs-you' | 'active' | 'recent'; /** 列表分组维度。'status' 是默认,也是旧三组(待你处理/进行中/最近)的那套语义。 */ export type WorkbenchGroupDimension = 'status' | 'bot' | 'chat' | 'kind' | 'cli' | 'time'; /** 下拉里的六个维度,顺序即展示顺序。 */ export declare const WORKBENCH_GROUP_DIMENSIONS: readonly { value: WorkbenchGroupDimension; label: string; }[]; export declare function isWorkbenchGroupDimension(value: unknown): value is WorkbenchGroupDimension; export interface WorkbenchPreviewDescriptor { path: string; registeredAt: string; } export interface WorkbenchSessionRow { sessionId: string; status: string; larkAppId?: string; botName?: string; cliId?: string; title?: string; workingDir?: string; repoName?: string; gitBranch?: string; spawnedAt?: number; lastMessageAt?: number; closedAt?: number; chatId?: string; chatType?: 'group' | 'p2p'; chatDisplayName?: string; scope?: 'thread' | 'chat'; feishuChatLink?: string; /** Direct native topic AppLink; absent on legacy sessions without `omt_`. */ feishuThreadLink?: string; webPort?: number | null; proxyPort?: number; riffAccessUrl?: string; preview?: WorkbenchPreviewDescriptor | null; pendingRepo?: boolean; queued?: boolean; tuiPromptActive?: boolean; agentAttention?: { kind?: string; reason?: string; at?: number; } | null; [key: string]: unknown; } export type WorkbenchPaneTree = { type: 'pane'; id: string; pane: WorkbenchPaneKind; } | { type: 'split'; id: string; axis: WorkbenchSplitAxis; ratio: number; first: WorkbenchPaneTree; second: WorkbenchPaneTree; }; export interface WorkbenchLayoutState { version: 1; railWidth: number; railCollapsed: boolean; focus: WorkbenchPaneKind; paneMode: 'focus' | 'split'; splitAxis: WorkbenchSplitAxis; splitRatio: number; chatRequested: boolean; } export interface ResponsiveWorkbenchLayout { mode: 'desktop' | 'mobile'; step: 'full' | 'rail-collapsed' | 'focus' | 'chat-jump' | 'mobile-stack'; railCollapsed: boolean; paneMode: 'focus' | 'split'; chatMode: 'native-split' | 'jump'; } export interface WorkbenchSessionGroups { 'needs-you': WorkbenchSessionRow[]; active: WorkbenchSessionRow[]; recent: WorkbenchSessionRow[]; } /** 一个渲染出来的分组。维度是动态的(机器人名 / 会话名 / CLI 都是数据里来的), * 所以组不再是固定三格,而是一串带 key 和中文标签的桶。`kind` 只区分「待你处理」 * 和普通组——前者永远置顶且用高亮样式,后者一律中性。 */ export interface WorkbenchDynamicGroup { key: string; label: string; kind: 'needs-you' | 'plain'; sessions: WorkbenchSessionRow[]; } export type WorkbenchListItem = { kind: 'header'; key: string; /** 旧三分类,动态维度下只用于样式回退(行前状态点、分组头配色)。 */ group: WorkbenchSessionGroup; /** 所属分组的稳定 key,动态维度下形如 `bot:Builder`。 */ groupKey: string; label: string; count: number; isNeedsYou: boolean; /** 该组当前是折叠的:组头照常渲染,但它下面的会话行一个都不在列表里。 */ collapsed?: boolean; } | { kind: 'session'; key: string; group: WorkbenchSessionGroup; groupKey: string; label: string; isNeedsYou: boolean; session: WorkbenchSessionRow; }; export interface VirtualWindow { start: number; end: number; offsetTop: number; totalHeight: number; positions: number[]; } export declare function validWorkbenchSessionId(value: unknown): value is string; export declare function buildWorkbenchHash(surface: WorkbenchSurface, sessionId?: string): string; export declare function parseWorkbenchHash(hash: string): { surface: WorkbenchSurface; sessionId: string | null; } | null; /** Only the two Workbench routes may cross the H5 login page. */ export declare function safeWorkbenchReturnTo(value: string | null | undefined): string; export declare function clampRailWidth(value: number): number; export declare function clampSplitRatio(value: number): number; export declare function defaultWorkbenchLayout(): WorkbenchLayoutState; export declare function normalizeWorkbenchLayout(value: unknown): WorkbenchLayoutState; export declare function paneTreeForLayout(layout: WorkbenchLayoutState): WorkbenchPaneTree; export declare function isValidPaneTree(value: unknown): value is WorkbenchPaneTree; /** * Ordered 1280px degradation: collapse rail, then Focus, then native Chat jump. * Mobile is a fixed single-column page stack and never restores a split itself. */ export declare function deriveResponsiveWorkbenchLayout(viewportWidth: number, requested: WorkbenchLayoutState): ResponsiveWorkbenchLayout; export declare function attentionSummary(session: WorkbenchSessionRow): string | null; /** 会话类型徽标用的三分类。`null` = 数据不足(旧 daemon 既没给 scope 也没给 * chatType),此时不渲染徽标,而不是猜一个可能是错的标签。 */ export type WorkbenchSessionKind = 'thread' | 'group' | 'p2p'; export declare function workbenchSessionKind(session: WorkbenchSessionRow): WorkbenchSessionKind | null; /** `unread` 为真时,一个没有 attention 理由的会话也算「待你处理」——bot 刚回完话 * 但你还没看。已关闭的会话不参与:它不会再有新回复。旧调用不传第二个参数,行为 * 和以前完全一致。 */ export declare function classifyWorkbenchSession(session: WorkbenchSessionRow, unread?: boolean): WorkbenchSessionGroup; export declare function sessionActivityAt(session: WorkbenchSessionRow): number; export declare function workbenchSessionTitle(session: WorkbenchSessionRow): string; export declare function sessionSearchText(session: WorkbenchSessionRow): string; export declare function groupWorkbenchSessions(sessions: readonly WorkbenchSessionRow[], query?: string): WorkbenchSessionGroups; export interface WorkbenchGroupingOptions { query?: string; dimension: WorkbenchGroupDimension; /** 未读会话 id。它们和 attention 会话一起被抽进置顶的「待你处理」。 */ unreadIds?: ReadonlySet; /** 时间维度分桶的基准时刻,由调用方传入(组件里就是那一帧的 now)。 */ now?: number; } /** * 按维度分组:先抽「待你处理」置顶,剩下的按维度分桶。 * 空桶不产出——动态维度下的组本来就是数据长出来的,一个「0 个会话」的组头只是噪音。 */ export declare function groupWorkbenchSessionsForDimension(sessions: readonly WorkbenchSessionRow[], options: WorkbenchGroupingOptions): WorkbenchDynamicGroup[]; /** * 三组记录和动态组都能拍平;旧调用(dock、脚本、测试)传前者,行为不变。 * `collapsedKeys` 命中的组只留一个组头——会话行不进列表,虚拟滚动的总高度就跟着 * 缩回去,这是折叠真正省下滚动距离的地方。组头上的 count 仍是折叠前的真实条数。 */ export declare function flattenWorkbenchGroups(groups: WorkbenchSessionGroups | readonly WorkbenchDynamicGroup[], collapsedKeys?: ReadonlySet): WorkbenchListItem[]; /** Must match the CSS row height exactly — virtualisation positions rows from * this number, and any disagreement makes the list scroll past its own end. * Touch layouts use taller rows for 44px targets, so the measurement is passed * in rather than assumed. * 桌面 54px 与 style.css 的 `.wb-session-row { height: 54px }` 一一对应;触屏 * 60px 对应 620px 断点里的那条。改一处必须同时改另一处。 */ export declare function workbenchListItemHeight(item: WorkbenchListItem, touch?: boolean): number; export declare function computeVirtualWindow(items: readonly WorkbenchListItem[], scrollTop: number, viewportHeight: number, overscanPx?: number, touch?: boolean): VirtualWindow; export declare function formatWorkbenchRelativeTime(epochMs: number, nowMs?: number, locale?: string): string; export interface WorkbenchTerminalLocation { protocol: string; origin: string; hostname: string; } export declare function workbenchTerminalHref(session: WorkbenchSessionRow, location: WorkbenchTerminalLocation | null): string | null; /** Session metadata may originate in another daemon. Treat external URLs and * preview descriptors as untrusted at the final DOM boundary. */ export declare function workbenchExternalTerminalHref(session: WorkbenchSessionRow): string | null; export declare function workbenchPreviewHref(session: WorkbenchSessionRow): string | null; //# sourceMappingURL=agent-workbench-model.d.ts.map