/** * Dashboard overview card. * * Sources from the shared overview endpoint and presents the same navigation * order as the Web Dashboard: sessions, groups, schedules, settings. * Drilldown buttons rebuild the target Feishu card in-place rather than using * external links, preserving invoker-lock and callback state. * * Non-200 Route B responses become error toasts, never empty cards. Successful * callbacks return card-only so Lark replaces the card in a single pass. */ import type { DaemonClient } from '../../dashboard/daemon-internal-client.js'; import type { DashboardSettingsInput } from '../../dashboard/settings-card-model.js'; import type { ScheduleCardTaskInput } from '../../dashboard/schedule-card-model.js'; import type { SessionRow } from '../../core/dashboard-rows.js'; import { type Locale } from '../../i18n/index.js'; import { type WorkbenchButtonLinks } from '../../core/workbench-link.js'; import type { CardActionData } from './card-handler.js'; export declare const OVERVIEW_ACTION_REFRESH: "dash_overview_refresh"; export declare const OVERVIEW_ACTION_GOTO_SESSIONS: "dash_overview_goto_sessions"; export declare const OVERVIEW_ACTION_GOTO_SCHEDULES: "dash_overview_goto_schedules"; export declare const OVERVIEW_ACTION_GOTO_SETTINGS: "dash_overview_goto_settings"; export declare const OVERVIEW_ACTION_GOTO_GROUPS: "dash_overview_goto_groups"; /** Sessions count buckets the summary line surfaces. */ export interface SessionCounts { active: number; idle: number; closed: number; } /** Schedules count buckets the summary line surfaces. */ export interface ScheduleCounts { enabled: number; paused: number; /** Schedules whose last run errored — counted regardless of enabled state, * to match the schedules list-card's ⚠️ semantics (see countSchedules * docblock + `schedule-card-model.ts`). */ errors: number; } /** Count session rows into (active / idle / closed) buckets. */ export declare function countSessions(rows: ReadonlyArray): SessionCounts; /** * Count schedule rows into (enabled / paused / errors-in-last-run) buckets. * * `errors` counts every task whose last run failed, regardless of `enabled`. * This matches the schedules list-card semantics: `schedule-card-model.ts` * sets `errorIndicator = task.lastStatus === 'error'` independent of the * paused/enabled state, and `schedules-card.ts` paints the ⚠️ glyph * on any such row. Keeping the same definition prevents an undercount where * overview reads "上次错误 0" while drilling into schedules surfaces a * paused task with ⚠️. */ export declare function countSchedules(tasks: ReadonlyArray): ScheduleCounts; /** * Build the read-only settings summary line. Local helper — deliberately * separate from `settings-card.ts:successResult` (which projects through * `composeSections` and renders an interactive segmented card). The two * share input shape but never share output text, so a future change to one * cannot drift the other. */ export declare function buildSettingsSummary(settings: DashboardSettingsInput, locale: Locale): string; export interface BuildOverviewCardOpts { invokerOpenId: string; locale: Locale; /** * 「打开工作台」入口的目标。缺省(读不到 dashboard 端口等)就整块不渲染, * 而不是渲染一个点了没反应的死链。链接怎么来的见 `core/workbench-link.ts`。 * * ⚠️ 这条链接携带**长期 Dashboard token**,常驻不过期——这是产品 owner 拍板的 * 决策反转(此前是 30 分钟短票,见 workbench-link.ts 顶部「为什么链接里是长期 * token」)。自部署用户要的是一条能收藏的入口,泄漏风险由 * `botmux dashboard rotate` 兜底。 * * 正因为它是常驻凭证,**发出前的门禁一层都不能放宽**:命令入口在 * `dashboard-command/owner-gate.ts` 拦,回调入口在下面 `handleOverviewCardAction` * 的 invoker-lock + `isDashboardAdmin` 拦,卡片是私信给发起人本人。 */ workbench?: { appLink: string; webUrl: string; credentialed: boolean; }; } export interface OverviewSnapshotInput { sessions: ReadonlyArray; schedules: ReadonlyArray; settings: DashboardSettingsInput; } /** Build the overview card JSON. Pure (counts + projects + renders). */ export declare function buildOverviewCard(snapshot: OverviewSnapshotInput, opts: BuildOverviewCardOpts): string; /** ─── Handler ─────────────────────────────────────────────────────────── */ export interface OverviewCardHandlerDeps { getOwnerOpenId?: (larkAppId: string) => string | undefined; getDashboardAdminOpenIds?: (larkAppId: string) => ReadonlyArray | undefined; createClient: (larkAppId: string) => DaemonClient; locale?: Locale; /** Override `Date.now()` so tests are deterministic. */ nowMs?: () => number; /** Override the workbench link resolution (reads dashboard port/token from * disk in production). Tests inject a fixed value. */ resolveWorkbench?: (larkAppId: string) => WorkbenchButtonLinks | undefined; } export interface OverviewCardHandlerResult { toast?: { type: 'info' | 'success' | 'error'; content: string; }; card?: { type: 'raw'; data: Record; }; } /** * Dispatch a `dash_overview_*` action callback. Uses the same fail-closed * identity pipeline as other dashboard cards; success returns `{ card }` only. * * Goto callbacks rebuild the TARGET module's card by re-fetching its own * dedicated endpoint (sessions-list / schedules-list / settings-snapshot) * — they intentionally do NOT mutate state. The user lands on the target * card in the SAME callback response (no `multi_url` cross-card jump). */ export declare function handleOverviewCardAction(data: CardActionData, larkAppId: string, deps: OverviewCardHandlerDeps): Promise; //# sourceMappingURL=overview-card.d.ts.map