dsh-context 0.22.1 → 0.22.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/client.js +36 -6
- package/lib/client.js.map +1 -1
- package/package.json +1 -1
package/lib/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","names":["MarkdownText","IconPlusOutline16","IconBranchOutline16"],"sources":["../src/client/i18n.ts","../src/client/modalStore.ts","../src/client/command.ts","../src/client/categories.ts","../src/client/headline.ts","../src/client/services.ts","../src/client/assemble.ts","../src/client/react.ts","../src/client/components/nodes.tsx","../src/client/format.ts","../src/client/components/images.tsx","../src/client/components/richText.tsx","../src/client/components/browser.tsx","../src/client/components/stackedBar.tsx","../src/client/components/currentComposition.tsx","../src/client/components/errorBoundary.tsx","../src/client/components/contextModal.tsx","../src/client/components/events.tsx","../src/client/meta.ts","../src/client/latestVersion.ts","../src/client/components/pluginInfo.tsx","../src/client/components/requestDetail.tsx","../src/client/cost.ts","../src/client/components/statsBoard.tsx","../src/client/components/trendChart.tsx","../src/client/components/contextView.tsx","../src/client/viewkit.ts","../src/client/index.ts"],"sourcesContent":["/**\n * Bilingual dictionaries (zh/en) for every UI string. Missing keys fall back\n * to zh, then the key itself (handled by the harness locale service).\n */\n\nexport type Translate = (key: string, params?: Record<string, string | number>) => string\n\nexport const DICT_ZH: Record<string, string> = {\n 'tab': '上下文',\n 'cat.system': '系统提示词', 'cat.tools': '工具定义', 'cat.user': '用户消息',\n 'cat.inject': '注入内容', 'cat.assistant': '助手消息', 'cat.tool': '工具结果',\n 'overview.title': '当前构成',\n 'overview.estimate': 'tokens(估算)',\n 'overview.free': '剩余窗口',\n 'overview.used': '上下文已用',\n 'overview.ofUsed': '占已用上下文',\n 'overview.compactReserve': '自动压缩预留:占用达 {pct}% 窗口时触发压缩,此区域一般不实际占用',\n 'stats.title': '上下文统计',\n 'stats.hint': '统计当前保留的历史窗口(与趋势图一致)',\n 'stats.turns': '轮次', 'stats.steps': '步数',\n 'stats.injects': '注入',\n 'stats.compactions': '压缩',\n 'stats.prunes': '剪枝',\n 'stats.cacheHit': '缓存命中',\n 'stats.cost': '预估费用',\n 'stats.costTip': '按 DeepSeek 官方刊例价估算整个会话的累计费用:输入区分缓存命中/未命中,输出含思考;按请求时间区分高峰(UTC 01:00–04:00、06:00–10:00)与空闲时段(半价)。适用于 deepseek-v4-flash / deepseek-v4-pro(不限 provider),价格写死在代码中,仅供参考。',\n 'stats.costPriceHead': '每百万 tokens 价格(高峰 | 空闲半价):',\n 'stats.costHit': '命中', 'stats.costMiss': '未命中', 'stats.costOut': '输出',\n 'plugin.title': '插件信息',\n 'plugin.hint': 'The best DSH context plugin ⭐',\n 'plugin.name': '插件',\n 'plugin.github': 'GitHub',\n 'tools.top': '工具定义 Top:',\n 'tools.more': '等 {n} 个',\n 'trend.title': '历史趋势',\n 'gran.step': '步骤', 'gran.turn': '轮次',\n 'trend.hint': '悬停查看详情,✂ 表示压缩/剪枝,Step/Turn 切换粒度',\n 'trend.empty': '发起一轮对话后,这里会展示每次模型请求的上下文构成',\n 'detail.step': '第 {t} 轮 · 第 {s} 步',\n 'detail.turn': '第 {t} 轮 · 共 {n} 步',\n 'detail.lastStep': '末步',\n 'detail.estTotal': '估算合计 ≈ {n}',\n 'detail.actual': '实际 prompt {n}',\n 'detail.output': '输出 {n}',\n 'events.title': '上下文事件',\n 'events.empty': '暂无上下文事件(压缩、注入、模型切换会出现在这里)',\n 'events.at': '第 {t} 轮 · 第 {s} 步',\n 'events.range': '第 {t} 轮 · 第 {a}→{b} 步',\n 'events.rangeTo': '第 {a} 轮 · 第 {as} 步 → 第 {b} 轮 · 第 {bs} 步',\n 'kind.inject': '注入', 'kind.compaction': '压缩', 'kind.prune': '剪枝', 'kind.model': '切换',\n 'nodes.title': '消息构成',\n 'nodes.hint': '当前模型可见的消息,最新在前',\n 'nodes.more': '… 更早的 {n} 条消息已省略',\n 'nodes.empty': '当前没有模型可见的消息',\n 'loading': '正在读取会话日志…',\n 'error': '上下文数据读取失败:',\n 'error.retry': '重试',\n 'footer': '估算口径:与 dsh 内置 tokenMeter 相同的固定密度启发式(约 4 字符 ≈ 1 token);「实际」为供应商上报用量。',\n 'tip.step': '第 {t} 轮 · 第{s}步',\n 'tip.turn': '第 {t} 轮 · 共 {n} 步',\n 'tip.total': '合计 ≈ {n}',\n 'tip.actual': '(实际 {n})',\n 'ev.compaction': '压缩上下文(摘要替换 {n} 条消息)',\n 'ev.prune': '剪枝工具输出',\n 'ev.skill': 'Skill 注入({name})',\n 'ev.model': '模型切换:{a} → {b}',\n 'form.instructions': '指令注入', 'form.catalog': '目录更新', 'form.snapshot': '状态快照',\n 'form.notice': '通知', 'form.relay': '代理转发', 'form.recall': '历史召回', 'form.context': '上下文注入',\n 'node.toolResult': '工具结果',\n 'node.calls': '调用 ',\n 'node.empty': '(空回复)',\n 'node.nonText': '(非文本消息)',\n 'node.snapshot': '快照: ',\n 'cmd.desc': '查看当前上下文构成,浏览各步骤组成',\n 'cmd.close': '关闭',\n 'browser.title': '上下文浏览器',\n 'browser.live': '当前(下一次请求)',\n 'browser.liveNow': '当前 · 下一次请求',\n 'browser.items': '{n} 项',\n 'browser.missingLive': '… 另有 {n} 条更早的消息也在上下文中(超出展示窗口)',\n 'browser.approx': '该步骤涉及的部分已移除消息超出保留范围,以下为近似构成',\n 'browser.deltaHint': '对比上轮末步的变动',\n 'browser.noHeader': '此数据来自旧版插件:仅提供 token 估算,无实际内容',\n 'browser.noEpoch': '该步骤的头部内容(系统提示词 / 工具定义)不在保留范围内',\n 'browser.noContent': '完整内容不在当前加载的消息窗口内(在聊天页加载更早历史后可查看)',\n 'browser.loading': '正在从更早的会话历史加载完整内容…',\n 'browser.preview': '预览',\n // Tool schema browser card: parsed parameter table sits above the (collapsed\n // by default) raw JSON so the common case — skimming arguments — stays\n // scannable; the JSON is still one click away for the full payload.\n 'tool.desc': '描述',\n 'tool.params': '参数',\n 'tool.paramsEmpty': '(无参数)',\n 'tool.jsonToggle': '查看原始 JSON',\n 'tool.jsonHide': '收起',\n // Detail-card view switch (system prompt / tool description / message and\n // injection bodies): a segmented pill — segment labels + tooltips.\n 'rich.raw': '原文',\n 'rich.md': 'Markdown',\n 'rich.toMd': '按 Markdown 渲染查看',\n 'rich.toRaw': '查看原始文本',\n // Assistant-message block titles inside the detail card: the reasoning\n // trace and the response each carry a small label (Reasoning / Response,\n // mirroring the harness's own block + locale vocabulary).\n 'block.thinking': '思考',\n 'block.answer': '回答',\n // Attachment cards in a message detail: image refs render as thumbnail\n // cards (name + normalized dims + stored size), anything unrecognized\n // falls into the generic raw-JSON card.\n 'attach.images': '图片附件',\n 'attach.other': '其他内容',\n 'attach.image': '图片',\n 'attach.open': '查看原图',\n 'attach.loading': '…',\n 'attach.loadFailed': '加载失败 · 点击重试',\n 'attach.orig': '原图 {d}',\n}\n\nexport const DICT_EN: Record<string, string> = {\n 'tab': 'Context',\n 'cat.system': 'System Prompt', 'cat.tools': 'Tool Schemas', 'cat.user': 'User Messages',\n 'cat.inject': 'Injected Context', 'cat.assistant': 'Assistant Messages', 'cat.tool': 'Tool Results',\n 'overview.title': 'Current Context',\n 'overview.estimate': 'tokens (estimated)',\n 'overview.free': 'Free Window',\n 'overview.used': 'of context used',\n 'overview.ofUsed': 'of used context',\n 'overview.compactReserve': 'Auto-compaction reserve: auto-compaction triggers at {pct}% of the window — this area is normally kept as headroom, not actually used',\n 'stats.title': 'Context Stats',\n 'stats.hint': 'Over the retained history window (same as the History chart)',\n 'stats.turns': 'Turns', 'stats.steps': 'Steps',\n 'stats.injects': 'Injections',\n 'stats.compactions': 'Compactions',\n 'stats.prunes': 'Prunes',\n 'stats.cacheHit': 'Cache Hits',\n 'stats.cost': 'Est. Cost',\n 'stats.costTip': 'Rough cumulative cost of the whole session at DeepSeek’s list prices: input split by cache hit/miss, output includes reasoning; each request is priced at the peak (01:00–04:00, 06:00–10:00 UTC) or half-price off-peak rate by its time. Applies to deepseek-v4-flash / deepseek-v4-pro on any provider; prices are hardcoded, for reference only.',\n 'stats.costPriceHead': 'Per-1M-token rates (peak | off-peak at half price):',\n 'stats.costHit': 'hit', 'stats.costMiss': 'miss', 'stats.costOut': 'output',\n 'plugin.title': 'Plugin Info',\n 'plugin.hint': 'The best DSH context plugin ⭐',\n 'plugin.name': 'Plugin',\n 'plugin.github': 'GitHub',\n 'tools.top': 'Top Tool Schemas:',\n 'tools.more': 'of {n}',\n 'trend.title': 'Context History',\n 'gran.step': 'Step', 'gran.turn': 'Turn',\n 'trend.hint': 'Hover to view details, ✂ marks compaction/prune, Step/Turn switches granularity',\n 'trend.empty': 'Send a message and each model request’s context makeup shows up here',\n 'detail.step': 'Turn {t} · Step {s}',\n 'detail.turn': 'Turn {t} · {n} steps',\n 'detail.lastStep': 'Last Step',\n 'detail.estTotal': 'Estimated ≈ {n}',\n 'detail.actual': 'Actual Prompt {n}',\n 'detail.output': 'Output {n}',\n 'events.title': 'Context Events',\n 'events.empty': 'No context events yet (compaction, injections, model switches appear here)',\n 'events.at': 'Turn {t} · Step {s}',\n 'events.range': 'Turn {t} · Step {a}→{b}',\n 'events.rangeTo': 'Turn {a} · Step {as} → Turn {b} · Step {bs}',\n 'kind.inject': 'Inject', 'kind.compaction': 'Compact', 'kind.prune': 'Prune', 'kind.model': 'Switch',\n 'nodes.title': 'Messages',\n 'nodes.hint': 'currently model-visible, newest first',\n 'nodes.more': '… {n} earlier messages omitted',\n 'nodes.empty': 'No model-visible messages right now',\n 'loading': 'Reading the session log…',\n 'error': 'Failed to read context data: ',\n 'error.retry': 'Retry',\n 'footer': 'Estimate: same fixed-density heuristic as dsh’s built-in tokenMeter (~4 chars ≈ 1 token); “actual” is provider-reported usage.',\n 'tip.step': 'Turn {t} · Step {s}',\n 'tip.turn': 'Turn {t} · {n} steps',\n 'tip.total': 'Total ≈ {n}',\n 'tip.actual': ' (actual {n})',\n 'ev.compaction': 'Context compacted (summary replaced {n} messages)',\n 'ev.prune': 'Tool output pruned',\n 'ev.skill': 'Skill injected ({name})',\n 'ev.model': 'Model switched: {a} → {b}',\n 'form.instructions': 'Instructions', 'form.catalog': 'Catalog Update', 'form.snapshot': 'State Snapshot',\n 'form.notice': 'Notice', 'form.relay': 'Agent Relay', 'form.recall': 'Recall', 'form.context': 'Context Injection',\n 'node.toolResult': 'Tool Result',\n 'node.calls': 'Calls ',\n 'node.empty': '(empty reply)',\n 'node.nonText': '(non-text message)',\n 'node.snapshot': 'Snapshot: ',\n 'cmd.desc': 'View current context makeup, browse per-step composition',\n 'cmd.close': 'Close',\n 'browser.title': 'Context Browser',\n 'browser.live': 'Live (Next Request)',\n 'browser.liveNow': 'Live · Next Request',\n 'browser.items': '{n} Items',\n 'browser.missingLive': '… {n} earlier messages are also part of the context (outside the served window)',\n 'browser.approx': 'Some removed messages of this step exceed retention — the makeup below is approximate',\n 'browser.deltaHint': 'vs previous turn',\n 'browser.noHeader': 'Served by an older plugin build: token estimates only, no content',\n 'browser.noEpoch': 'The header content (System Prompt / Tool Schemas) of this step is outside retention',\n 'browser.noContent': 'Full content is outside the loaded message window (load older history in Chat to view)',\n 'browser.loading': 'Loading full content from older session history…',\n 'browser.preview': 'Preview',\n // Tool schema browser card: parsed parameter table sits above the (collapsed\n // by default) raw JSON so the common case — skimming arguments — stays\n // scannable; the JSON is still one click away for the full payload.\n 'tool.desc': 'Description',\n 'tool.params': 'Parameters',\n 'tool.paramsEmpty': '(no parameters)',\n 'tool.jsonToggle': 'View Raw JSON',\n 'tool.jsonHide': 'Collapse',\n // Detail-card view switch (system prompt / tool description / message and\n // injection bodies): a segmented pill — segment labels + tooltips.\n 'rich.raw': 'Raw',\n 'rich.md': 'Markdown',\n 'rich.toMd': 'View as Markdown',\n 'rich.toRaw': 'View Raw Text',\n // Assistant-message block titles inside the detail card: the reasoning\n // trace and the response each carry a small label (Reasoning / Response,\n // mirroring the harness's own block + locale vocabulary).\n 'block.thinking': 'Reasoning',\n 'block.answer': 'Response',\n // Attachment cards in a message detail: image refs render as thumbnail\n // cards (name + normalized dims + stored size), anything unrecognized\n // falls into the generic raw-JSON card.\n 'attach.images': 'Images',\n 'attach.other': 'Other content',\n 'attach.image': 'Image',\n 'attach.open': 'Open full image',\n 'attach.loading': '…',\n 'attach.loadFailed': 'Load failed · click to retry',\n 'attach.orig': 'original {d}',\n}\n","/**\n * Per-session open-state stores for the /context modal, plus the deferred\n * token-consume guards. Module-level so the state survives overlay remounts;\n * the trigger source (pick/enter) opens it, the overlay component subscribes\n * and renders. Implements the ObservableSnapshot pair the slot `hooks`\n * compartment binds as a `useContextModal` selector hook.\n */\n\nimport type { TokenSpan } from './services'\n\nexport interface ModalStore {\n subscribe(listener: () => void): () => void\n getSnapshot(): boolean\n set(open: boolean): void\n}\n\nconst stores = new Map<string, ModalStore>()\n\nexport function modalStoreOf(sessionId: string): ModalStore {\n const existing = stores.get(sessionId)\n if (existing !== undefined) return existing\n let open = false\n const listeners = new Set<() => void>()\n const store: ModalStore = {\n subscribe(listener) {\n listeners.add(listener)\n return () => { listeners.delete(listener) }\n },\n getSnapshot: () => open,\n set(next) {\n if (next === open) return\n open = next\n for (const listener of listeners) listener()\n },\n }\n stores.set(sessionId, store)\n return store\n}\n\n// ---- deferred token consumption -------------------------------------------\n// The `/context` token stays in the composer while the modal is open and is\n// consumed only when the modal closes. Each open path records the guard the\n// input shell understands (span CAS for menu picks, bare-token equality for\n// enter); the close path takes it and dispatches the scoped\n// `slash/input-consume-token` event. A stale guard (the user typed meanwhile)\n// fails soft inside the shell — the draft is left untouched.\n\nexport type ConsumeGuard =\n | { kind: 'span'; span: TokenSpan }\n | { kind: 'bare-token'; token: string }\n\nconst pendingConsume = new Map<string, ConsumeGuard>()\n\nexport function setPendingConsume(sessionId: string, guard: ConsumeGuard): void {\n pendingConsume.set(sessionId, guard)\n}\n\n/** Take (and clear) the guard recorded by the open path, if any. */\nexport function takePendingConsume(sessionId: string): ConsumeGuard | undefined {\n const guard = pendingConsume.get(sessionId)\n if (guard !== undefined) pendingConsume.delete(sessionId)\n return guard\n}\n","/**\n * `/context` — a client-owned slash command that opens the context modal\n * (current composition + recent trend) in the center of the page.\n *\n * Implemented as the plugin's own '/' trigger source instead of a host\n * command: nothing is dispatched to the host, no session log records are\n * written, and nothing becomes model-visible — the invocation never enters\n * the message history. Both paths answer `'handled'` and open the modal,\n * leaving the `/context` token in the composer while it is open; the modal's\n * close path consumes the token then (see modalStore.ts).\n */\n\nimport { modalStoreOf, setPendingConsume } from './modalStore'\nimport type { ClientCtx, InputTriggersFace } from './services'\nimport type { ViewKit } from './viewkit'\n\nconst COMMAND = 'context'\nconst LINE = '/' + COMMAND\n\nexport function registerContextCommand(ctx: ClientCtx, kit: ViewKit): void {\n ctx.effect(() => {\n // Soft dependency (ctx.get, not the inject list): a harness without the\n // input-trigger service keeps the tab working and only the command\n // absent.\n const inputTriggers = ctx.get('inputTriggers') as InputTriggersFace | undefined\n if (inputTriggers === undefined) return () => {}\n\n return inputTriggers.registerSource({\n trigger: '/',\n name: COMMAND,\n order: 1,\n candidates: (_session, req) => {\n if (req.position !== 'leading') return Promise.resolve([])\n const query = req.query.trim().toLowerCase()\n if (query !== '' && !COMMAND.startsWith(query)) return Promise.resolve([])\n return Promise.resolve([{ name: COMMAND, description: kit.t('cmd.desc') }])\n },\n onPick: (pick) => {\n // Open and remember the token span: the modal's close path consumes\n // it (span CAS — a draft changed meanwhile is left untouched).\n setPendingConsume(pick.session.sessionId, { kind: 'span', span: pick.span })\n modalStoreOf(pick.session.sessionId).set(true)\n return 'handled'\n },\n matchEnter: (session, line) => {\n if (line !== LINE) return Promise.resolve(undefined)\n // Same deferred consume, bare-token guard (the trimmed draft must\n // still equal the command line when the modal closes).\n setPendingConsume(session.sessionId, { kind: 'bare-token', token: LINE })\n modalStoreOf(session.sessionId).set(true)\n return Promise.resolve<'handled'>('handled')\n },\n })\n }, 'dsh-context: /context command')\n}\n","/**\n * Category presentation config: the six priced buckets (system, tool\n * schemas, and the four surface categories) with their chart colors, plus\n * `partsOf` which projects a token breakdown (snapshot current or a request\n * record) into renderable parts.\n */\n\nimport type { Category, RequestRecord, Snapshot } from '../shared/types'\n\nexport interface PartsPart { key: string; color: string; value: number }\n\nexport const CATS: { key: Category | 'system' | 'tools'; color: string }[] = [\n { key: 'system', color: '#6366f1' },\n { key: 'tools', color: '#f59e0b' },\n { key: 'user', color: '#22c55e' },\n { key: 'inject', color: '#a855f7' },\n { key: 'assistant', color: '#3b82f6' },\n { key: 'tool', color: '#14b8a6' },\n]\n\nexport function partsOf(breakdown: Snapshot['current'] | RequestRecord): PartsPart[] {\n return CATS.map((c) => {\n return { key: c.key, color: c.color, value: breakdown[c.key] || 0 }\n })\n}\n\n/**\n * Reproportion heuristic parts so they sum to a provider-anchored target —\n * the same trick the official ContextMeter uses: the heuristic breakdown\n * supplies the composition RATIOS, the provider sample the total. Returns\n * the parts unchanged when no anchor applies.\n */\nexport function anchoredParts(parts: PartsPart[], target: number | null): PartsPart[] {\n if (target === null || target <= 0) return parts\n let total = 0\n for (const p of parts) total += p.value\n if (total <= 0 || total === target) return parts\n const scale = target / total\n return parts.map(p => ({ ...p, value: Math.round(p.value * scale) }))\n}\n","/**\n * Provider-anchored headline derivation, shared by the Context tab and the\n * /context popup: the best-known occupancy of the next request, the route\n * capacity it scales against, and the composition parts anchored to that\n * total (heuristic ratios, provider-anchored sum).\n *\n * The provider anchor is the OFFICIAL token-meter `contextPressure`\n * projection (read via `useProjection('contextPressure')`) — the same\n * \"projectedTokens\" the chat's context ring displays; the Host no longer\n * mirrors it inside `contextTimeline`. When the projection is absent (older\n * harness, or the meter is not composed), the headline falls back to the\n * newest request's provider prompt plus the heuristic surface movement since\n * it was logged, and finally to the raw heuristic total.\n */\n\nimport type { ContextPressure, ContextTimeline } from '../shared/types'\nimport { anchoredParts, partsOf, type PartsPart } from './categories'\n\nexport interface Headline {\n /** Best-known occupancy of the next request (projected ?? derived ?? heuristic total). */\n tokens: number\n /** Route capacity the headline scales against (may be unknown). */\n window?: number\n /** tokens / window, clamped to 100; null without a window. */\n pct: number | null\n /** Composition parts anchored to the provider total when one exists. */\n parts: PartsPart[]\n}\n\nexport function headlineOf(data: ContextTimeline, pressure: ContextPressure | null = null): Headline {\n const current = data.current\n // The official projection's whole value is the newest usage sample carried\n // forward by the heuristic surface movement since it was taken — the same\n // formula the chat ring displays. Fields are last-wins; absent until a\n // provider reports usage.\n const projected = pressure !== null && typeof pressure.projectedTokens === 'number'\n ? pressure.projectedTokens\n : undefined\n const requests = data.requests\n const lastReq = requests.length > 0 ? requests[requests.length - 1] : null\n // Fallback anchor: the newest request's provider prompt plus the heuristic\n // surface movement since it was logged (same shape as the projection, one\n // request behind).\n const derived = lastReq !== null && typeof lastReq.prompt === 'number'\n ? lastReq.prompt + (current.total - lastReq.total)\n : undefined\n const occupancyTokens = projected ?? derived ?? null\n const window = pressure !== null && typeof pressure.contextWindow === 'number'\n ? pressure.contextWindow\n : data.contextWindow\n const tokens = occupancyTokens ?? current.total\n const pct = window !== undefined && window > 0 ? Math.min(100, Math.round(tokens / window * 100)) : null\n const parts = anchoredParts(partsOf(current), occupancyTokens !== null && tokens > 0 ? tokens : null)\n return { tokens, window, pct, parts }\n}\n","/**\n * Client-side service contracts — the exact API surface this plugin consumes\n * from the harness web half.\n *\n * The plugin bundles its own code but relies on the reader to deliver the\n * framework standard kit to slot components (`sessionId`, `useSession`,\n * `useProjection`, `t` …); only the small faces below are referenced across\n * modules. These are TYPE-ONLY: the runtime services come from the user's\n * harness. This plugin no longer calls any RPC — data arrives as pushed\n * session projections (`useProjection` standard seat).\n */\n\nimport type { Context } from '@deepseek-ai/cordis'\nimport type { ContextHeaders, ContextPressure, ContextTimeline, TokenUsage } from '../shared/types'\n\nexport interface LocaleService {\n register(ns: string, dicts: Record<string, Record<string, string>>): () => void\n bind(ns: string): (key: string, params?: Record<string, string | number>) => string\n subscribe(fn: () => void): () => void\n /** The current immutable locale snapshot (harness locale runtime). */\n getLocale?(): { active: string }\n}\n\nexport interface SlotRegistration {\n name: string\n id: string\n order: number\n /** optional dictionary namespace; the framework then synthesizes the `t` seat. */\n locale?: string\n label?: () => string\n /** optional business face factory; a `hooks` compartment binds selector hooks onto props. */\n inject?: (sessionId: string) => unknown\n}\n\nexport interface SlotsService {\n inject(name: string, callback: () => unknown): unknown\n register(\n registration: SlotRegistration,\n component: (props: { sessionId?: string }) => unknown,\n ): unknown\n}\n\n/**\n * The conversation node, as far as the Context browser consumes it: the\n * framework's finalized chat nodes carry the source surface event's `seq`\n * plus the full content — the browser joins its surface nodes on `seq` to\n * show actual content without carrying it through the projection.\n */\nexport interface ConversationNodeLike {\n kind: string\n seq: number\n content?: readonly unknown[]\n blocks?: readonly unknown[]\n call?: { name: string; argsRaw: string } | null\n isError?: boolean\n summary?: string | null\n}\n\n/**\n * A durable image attachment reference, as far as this plugin consumes it\n * (dsh's `ImageAttachmentRef`, minimally re-typed so the plugin stays free\n * of an attachment-package dependency). The durable log holds only this ref\n * — never inline bytes. Since dsh 0.1.1 the width/height/bytes describe the\n * NORMALIZED raster (long edge 2048px); `originalDimensions` carries the\n * pre-normalization size when normalization reduced the image.\n */\nexport interface ImageRefLike {\n attachmentId: string\n name?: string\n bytes?: number\n width?: number\n height?: number\n originalDimensions?: { width: number; height: number }\n}\n\n/** Loads a session-authorized display URL for one durable image reference. */\nexport type ImageLoader = (attachment: ImageRefLike) => Promise<string>\n\n/**\n * The harness conversation client service (`ctx.conversation`), minimally\n * typed for image resolution — the same call the chat view's own message\n * images ride on.\n */\nexport interface ConversationFace {\n resolveImage(sessionId: string, attachment: ImageRefLike): Promise<string>\n}\n\n/** The conversation-snapshot selector hook, minimally typed for this plugin. */\nexport type UseSessionLike = <T>(\n selector: (snapshot: {\n nodes?: readonly ConversationNodeLike[]\n /** whether older history remains outside the loaded window */\n hasMore?: boolean\n /** whether an older-history page is currently being pulled */\n loadingOlder?: boolean\n }) => T,\n) => T\n\n/**\n * The framework standard kit of a session-scope slot component, as far as\n * this plugin consumes it: the resolve session id and the key-addressed\n * projection reader that delivers the `contextTimeline` value (undefined =\n * the host unit is absent or no value has arrived yet).\n */\nexport interface SessionStandardProps {\n sessionId?: string\n useProjection?: (key: string) => unknown\n useSession?: UseSessionLike\n /**\n * History-pagination verb this plugin contributes through the harness's\n * `sessions.provide` channel (one call prepends one older page to the\n * conversation window). Absent on older hosts without the channel — the\n * Context browser then keeps its preview-plus-hint degradation.\n */\n loadOlderHistory?: () => Promise<void>\n}\n\n/** The client context: cordis plus the services this plugin injects. */\nexport type ClientCtx = Context & {\n locale: LocaleService\n slots: SlotsService\n}\n\n/**\n * Narrow an unknown projection value to a string-keyed record, or null when\n * it is not one. The boundary type is Record<string, unknown> on purpose:\n * every field read below must re-prove itself (the no-white-screen\n * guarantee), so no field may borrow the wire type before its check.\n */\nfunction asRecord(value: unknown): Record<string, unknown> | null {\n if (value === null || value === undefined || typeof value !== 'object') return null\n return value as Record<string, unknown>\n}\n\n/**\n * Safe finite-number read: a missing/non-numeric/NaN field degrades to 0\n * instead of leaking into the UI as NaN percentages or broken arithmetic.\n */\nexport function numOf(value: unknown): number {\n return typeof value === 'number' && Number.isFinite(value) ? value : 0\n}\n\n/** The usable (non-null object) entries of a delivered list; [] when the field is not a list. */\nfunction objectsOf<T>(value: unknown): T[] {\n if (!Array.isArray(value)) return []\n return value.filter((v): v is T => v !== null && typeof v === 'object')\n}\n\n/**\n * Narrow a delivered projection value to a RENDER-SAFE context timeline —\n * the client's no-white-screen guarantee against backend/parse failures.\n *\n * A value that is not a record at all (capability absent, nothing delivered\n * yet) stays `null` and callers show the loading screen. A record that fails\n * the wire shape (corrupt checkpoint restore, a failed/older host payload,\n * plugin drift) is SANITIZED instead of rejected: every collection becomes\n * an array, non-object entries are dropped, `current` becomes a numeric\n * breakdown, and wrong-typed scalars are dropped or zeroed — so the whole\n * tab still renders with every usable piece of data instead of throwing\n * during render and unmounting the conversation view.\n */\nexport function timelineOf(value: unknown): ContextTimeline | null {\n const data = asRecord(value)\n if (data === null) return null\n const current = data.current\n // The wire shape check for the cheap pass-through path: `current` must be\n // a full numeric breakdown (the host always sends all seven fields), and\n // every collection must be a real list. Anything else takes the slow path\n // and is rebuilt into the safe shape below.\n const numericBreakdown = current !== null && typeof current === 'object'\n && ['system', 'tools', 'user', 'inject', 'assistant', 'tool', 'total']\n .every(k => typeof (current as Record<string, unknown>)[k] === 'number')\n if (numericBreakdown\n && Array.isArray(data.requests)\n && Array.isArray(data.events)\n && Array.isArray(data.nodes)\n && Array.isArray(data.archive)\n && Array.isArray(data.toolList)) {\n // Well-formed: pass the delivered value through untouched (cheap, and\n // reference-stable so plain re-renders stay zero-copy).\n return data as unknown as ContextTimeline\n }\n // Malformed: rebuild with safe defaults, keeping every usable piece.\n const safeCurrent: Record<string, unknown> = current !== null && typeof current === 'object' ? current as Record<string, unknown> : {}\n const cost = typeof data.cost === 'object' && data.cost !== null && !Array.isArray(data.cost)\n ? data.cost as ContextTimeline['cost']\n : undefined\n return {\n ok: true,\n ...(typeof data.model === 'string' ? { model: data.model } : {}),\n ...(typeof data.provider === 'string' ? { provider: data.provider } : {}),\n ...(typeof data.contextWindow === 'number' ? { contextWindow: data.contextWindow } : {}),\n current: {\n system: numOf(safeCurrent.system),\n tools: numOf(safeCurrent.tools),\n user: numOf(safeCurrent.user),\n inject: numOf(safeCurrent.inject),\n assistant: numOf(safeCurrent.assistant),\n tool: numOf(safeCurrent.tool),\n total: numOf(safeCurrent.total),\n },\n toolList: objectsOf(data.toolList),\n requests: objectsOf(data.requests),\n events: objectsOf(data.events),\n nodes: objectsOf(data.nodes),\n droppedNodes: numOf(data.droppedNodes),\n archive: objectsOf(data.archive),\n ...(cost !== undefined ? { cost } : {}),\n ...(typeof data.surfaceFloor === 'number' ? { surfaceFloor: data.surfaceFloor } : {}),\n ...(typeof data.archiveFloor === 'number' ? { archiveFloor: data.archiveFloor } : {}),\n }\n}\n\n/**\n * Narrow a delivered projection value to the official token-meter\n * `contextPressure` projection (provider-anchored occupancy of the next\n * request). Absent key or value = the meter's projection is not composed\n * (e.g. a harness without the session-projection registry) — callers fall\n * back to their derived anchor, so the UI degrades gracefully.\n */\nexport function contextPressureOf(value: unknown): ContextPressure | null {\n const data: unknown = asRecord(value)\n return data as ContextPressure | null\n}\n\n/**\n * Narrow a delivered projection value to the official token-meter\n * `tokenUsage` projection (durable cumulative provider usage). Absent key or\n * value = the meter's projection is not composed (or no request has reported\n * usage yet) — callers drop the cache-hit cell to a dash.\n */\nexport function tokenUsageOf(value: unknown): TokenUsage | null {\n const data: unknown = asRecord(value)\n return data as TokenUsage | null\n}\n\n/**\n * Narrow a delivered projection value to the plugin's `contextHeaders`\n * (request-header content epochs). Absent key = an older Host half without\n * the companion unit — the Context browser degrades its system/tools\n * sections to tokens-only with a note.\n *\n * Entry-level shape is checked too: a malformed epoch (corrupt payload with\n * a missing tools list or wrong-typed system prompt) would crash the\n * browser's tools/sections reads, so the WHOLE projection degrades to null\n * and the card falls back to its tokens-only note.\n */\nexport function headersOf(value: unknown): ContextHeaders | null {\n const headers = asRecord(value)\n if (headers === null || !Array.isArray(headers.headers)) return null\n for (const h of headers.headers as unknown[]) {\n if (h === null || typeof h !== 'object') return null\n const entry = h as { tools?: unknown; system?: unknown }\n if (!Array.isArray(entry.tools)) return null\n if (entry.system !== undefined && typeof entry.system !== 'string') return null\n }\n return headers as unknown as ContextHeaders\n}\n\n// ---- /context command faces (framework `inputTriggers` service) ----\n\n/** One menu candidate offered by a trigger source. */\nexport interface TriggerCandidate {\n name: string\n description?: string\n}\n\n/** Pick-moment snapshot of the trigger token span (draftRev CAS). */\nexport interface TokenSpan {\n start: number\n end: number\n draftRev: number\n}\n\n/** Everything a source receives on a menu pick. */\nexport interface TriggerPick {\n candidate: TriggerCandidate\n session: { sessionId: string }\n position: string\n via: string\n span: TokenSpan\n}\n\n/** The pick outcomes this plugin produces (see the framework's PickOutcome). */\nexport type SourcePickOutcome = 'handled' | undefined\n\n/**\n * The harness input-trigger service (`ctx.inputTriggers`), as far as this\n * plugin consumes it: registering one '/' source whose candidates, picks,\n * and enter adjudication all stay on the client.\n */\nexport interface InputTriggersFace {\n registerSource(src: {\n trigger: '/'\n name: string\n order?: number\n candidates(\n session: { sessionId: string },\n req: { query: string; position: string; signal: AbortSignal },\n ): Promise<readonly TriggerCandidate[]>\n onPick(pick: TriggerPick): SourcePickOutcome\n matchEnter?(\n session: { sessionId: string },\n line: string,\n signal: AbortSignal,\n ): Promise<SourcePickOutcome>\n }): () => void\n}\n\n/** The session scope (`ctx.sessions.scope`), used to dispatch the scoped consume-token event. */\nexport interface SessionScopeFace {\n bail(subject: unknown, event: string, payload: unknown): unknown\n}\n\n/**\n * One standard-props contribution to the harness's `sessions.provide`\n * channel: declared members are resolved per session and delivered to every\n * session-scope slot component (hooks become `use<Name>` selector hooks,\n * props spread verbatim). Minimally typed against the runtime contract.\n */\nexport interface SessionProvideDescriptorLike {\n hooks?: readonly string[]\n props?: readonly string[]\n resolve(binding: { session: { loadOlder(): Promise<void> } }): {\n hooks?: Record<string, unknown>\n props?: Record<string, unknown>\n }\n}\n\n/** The session runtime (`ctx.sessions`), as consumed here. */\nexport interface SessionsFace {\n scope(id: string): SessionScopeFace | undefined\n /**\n * The standard-props provide channel (absent on older hosts). Throws on a\n * misdeclared or duplicate contribution — callers fail soft.\n */\n provide?(descriptor: SessionProvideDescriptorLike): () => void\n}\n","/**\n * Per-step context assembly — the pure reconstruction behind the Context\n * browser card.\n *\n * A request record R was snapshotted by the Host exactly as dispatched:\n * header in force + the model-visible surface BEFORE the response landed.\n * Given the timeline's live `nodes` (newest tail) and `archive` (removed\n * nodes stamped with `gone`), the surface assembled into R is:\n *\n * every node with seq < R.seq AND (gone undefined OR gone > R.seq)\n *\n * For the LIVE view (the next request's context) it is simply the current\n * live nodes. Coverage is honest: when the served window cannot contain the\n * full answer (older live nodes dropped, or removals older than the archive\n * retention), the result carries the flags the UI turns into notices.\n */\n\nimport type { ContextHeaders, ContextTimeline, HeaderRecord, SurfaceNode } from '../shared/types'\n\nexport interface Assembled {\n /** True when browsing the live surface (the next request's context). */\n live: boolean\n /** The header epoch in force (null = headers projection absent or none yet). */\n header: HeaderRecord | null\n /** The assembled surface messages, in seq order. */\n nodes: SurfaceNode[]\n /** Live nodes outside the served window that are also part of the context. */\n missingLive: number\n /** True when removals this step depends on may exceed archive retention. */\n approximate: boolean\n}\n\n/** The header epoch in force at `seq` (last logged before it), or the newest. */\nexport function headerAt(headers: ContextHeaders | null, seq: number | null): HeaderRecord | null {\n if (headers === null || headers.headers.length === 0) return null\n if (seq === null) return headers.headers[headers.headers.length - 1]\n for (let i = headers.headers.length - 1; i >= 0; i--) {\n if (headers.headers[i].seq < seq) return headers.headers[i]\n }\n return null\n}\n\n/**\n * Reconstruct the assembled surface for one step (`seq` = the request\n * record's seq) or the live surface (`seq` = null).\n */\nexport function assemble(data: ContextTimeline, headers: ContextHeaders | null, seq: number | null): Assembled {\n const live = seq === null\n let nodes: SurfaceNode[]\n if (live) {\n nodes = data.nodes.slice()\n } else {\n const picked: SurfaceNode[] = []\n for (const n of data.nodes) {\n if (n.seq < seq) picked.push(n)\n }\n for (const n of data.archive) {\n if (n.seq < seq && n.gone !== undefined && n.gone > seq) picked.push(n)\n }\n nodes = picked\n }\n nodes.sort((a, b) => a.seq - b.seq)\n\n let missingLive = 0\n if (data.droppedNodes > 0) {\n // Live: every dropped live node is part of the current context. A past\n // step: the dropped slice sits at or below `surfaceFloor`, so a step\n // after it contains them all (an older step's unknown subset is left\n // unflagged rather than overstated).\n if (live || (data.surfaceFloor !== undefined && seq > data.surfaceFloor)) {\n missingLive = data.droppedNodes\n }\n }\n const approximate = !live\n && data.archiveFloor !== undefined\n && seq < data.archiveFloor\n\n return { live, header: headerAt(headers, seq), nodes, missingLive, approximate }\n}\n","/**\n * The browser module table supplies React through the injected `require` —\n * every component imports it from here instead of repeating the require.\n */\n\nimport type * as ReactNS from 'react'\n\n// The loader contract: a closure-factory bundle has no ESM imports; the\n// browser module table answers this injected require.\n// oxlint-disable-next-line typescript/no-require-imports\nexport const React: typeof ReactNS = require('react') as typeof ReactNS\nexport const h = React.createElement\n","/**\n * NodeList — the current model-visible message list (newest first).\n * JSX function component; no framework primitives needed (rows are bespoke\n * data-viz chrome, styled through the shared `--dsw-alias-*` tokens).\n */\n\nimport type * as ReactNS from 'react'\nimport type { SurfaceNode } from '../../shared/types'\nimport { CATS } from '../categories'\nimport type { ViewKit } from '../viewkit'\n\nimport { React } from '../react'\n\nexport interface NodeListProps { nodes: SurfaceNode[]; dropped: number }\n\n/** One-line preview of a surface node (shared by the node list and the Context browser's element rows). */\nexport function makeNodeText(kit: ViewKit): (n: SurfaceNode) => string {\n const { t } = kit\n return function nodeText(n: SurfaceNode): string {\n if (n.cat === 'tool') {\n return t('node.toolResult') + (n.tool ? ' ← ' + n.tool : '') + (n.err ? ' ⚠' : '')\n }\n if (n.skill) return 'Skill: ' + n.skill\n if (n.calls) return t('node.calls') + n.calls.join(', ')\n if (n.text) return n.form === 'snapshot' ? t('node.snapshot') + n.text : n.text\n if (n.cat === 'assistant') return t('node.empty')\n if (n.cat === 'inject') return t('form.' + (n.form || 'context'))\n return t('node.nonText')\n }\n}\n\nexport function makeNodeList(kit: ViewKit): (props: NodeListProps) => ReactNS.ReactElement {\n const { t, fmt, fmtTime } = kit\n const nodeText = makeNodeText(kit)\n\n return function NodeList(props: NodeListProps): ReactNS.ReactElement {\n if (props.nodes.length === 0) {\n return <div className=\"lc-empty\">{t('nodes.empty')}</div>\n }\n const catColor: Record<string, string> = {}\n for (const c of CATS) catColor[c.key] = c.color\n const rows = props.nodes.slice().reverse()\n return (\n <div className=\"lc-nodes\">\n {props.dropped > 0\n ? <div className=\"lc-nodes-more\">{t('nodes.more', { n: props.dropped })}</div>\n : null}\n {rows.map((n) => {\n const text = nodeText(n)\n return (\n <div key={n.seq} className=\"lc-node\">\n <i style={{ background: catColor[n.cat] || '#999' }} />\n <span className=\"lc-node-preview\" title={text}>{text}</span>\n {/* Timestamp when the host event carried one. */}\n {typeof n.time === 'number' ? <span className=\"lc-node-time\">{fmtTime(n.time)}</span> : null}\n <span className=\"lc-node-tokens\">{fmt(n.tokens)}</span>\n </div>\n )\n })}\n </div>\n )\n }\n}\n","/**\n * Number/time formatting for the UI. `fmt` uses the same k/M suffix style\n * everywhere (bars, details, stats); `fmtTime` renders a local HH:MM:SS.\n */\n\nexport function fmt(n: number | null | undefined): string {\n if (n === undefined || n === null || isNaN(n)) return '—'\n if (n >= 1e6) return (n / 1e6).toFixed(1) + 'M'\n if (n >= 1000) return (n / 1000).toFixed(1) + 'k'\n return String(Math.round(n))\n}\n\n/** Byte sizes for attachment metadata (1 kB = 1000 B, matching the k/M style of `fmt`). */\nexport function fmtBytes(n: number | null | undefined): string {\n if (n === undefined || n === null || isNaN(n) || n < 0) return '—'\n if (n >= 1e6) return (n / 1e6).toFixed(1) + ' MB'\n if (n >= 1000) return (n / 1000).toFixed(1) + ' kB'\n return String(Math.round(n)) + ' B'\n}\n\nexport function fmtTime(t: number): string {\n // en-GB with a 24-hour clock renders the same local HH:MM:SS the manual\n // zero-pad produced, without the hand-rolled p() helper.\n // An invalid timestamp (garbage from a corrupt payload) must show a dash,\n // never throw — `toLocaleTimeString` raises RangeError on Invalid Date.\n const d = new Date(t)\n if (isNaN(d.getTime())) return '—'\n return d.toLocaleTimeString('en-GB', { hour12: false })\n}\n","/**\n * ImageCards — durable image attachment rendering for the Context browser.\n *\n * dsh 0.1.1's multimodal pipeline stores only a normalized reference per\n * image (never inline bytes), so a message block carries everything a card\n * needs except the display URL: that comes from the harness conversation\n * service's `resolveImage` (the same loader the chat history rides on),\n * handed down as `load`. Absent loader or a failed load degrades to the\n * metadata row alone — the card never throws.\n */\n\nimport type * as ReactNS from 'react'\nimport { fmtBytes } from '../format'\nimport { React } from '../react'\nimport type { ImageLoader, ImageRefLike } from '../services'\nimport type { ViewKit } from '../viewkit'\n\n/** The image-rendering handoff threaded through the browser's bodies. */\nexport interface ImageKit {\n Card: (props: { attachment: ImageRefLike; load?: ImageLoader }) => ReactNS.ReactElement\n /** Session-authorized URL loader (absent = metadata-only cards). */\n load?: ImageLoader\n}\n\n/**\n * Narrow an unknown content block to a durable image reference. Accepts both\n * raw message blocks (`{ type: 'image', attachment }`) and the conversation\n * snapshot's assistant blocks (`{ kind: 'image', attachment }`); everything\n * else returns null. Lenient on the ref's optional facts (name/bytes/dims) —\n * `resolveImage` reads only `attachmentId`.\n */\nexport function imageRefOf(block: unknown): ImageRefLike | null {\n if (block === null || typeof block !== 'object') return null\n const b = block as { type?: unknown; kind?: unknown; attachment?: unknown }\n if (b.type !== 'image' && b.kind !== 'image') return null\n const a = b.attachment\n if (a === null || typeof a !== 'object') return null\n const r = a as Record<string, unknown>\n if (typeof r.attachmentId !== 'string' || r.attachmentId === '') return null\n const num = (v: unknown): number | undefined =>\n typeof v === 'number' && Number.isFinite(v) && v > 0 ? v : undefined\n const orig = r.originalDimensions !== null && typeof r.originalDimensions === 'object'\n ? r.originalDimensions as Record<string, unknown>\n : undefined\n const origDims = orig !== undefined && num(orig.width) !== undefined && num(orig.height) !== undefined\n ? { width: num(orig.width) as number, height: num(orig.height) as number }\n : undefined\n return {\n attachmentId: r.attachmentId,\n ...(typeof r.name === 'string' && r.name !== '' ? { name: r.name } : {}),\n ...(num(r.bytes) !== undefined ? { bytes: num(r.bytes) } : {}),\n ...(num(r.width) !== undefined ? { width: num(r.width) } : {}),\n ...(num(r.height) !== undefined ? { height: num(r.height) } : {}),\n ...(origDims !== undefined ? { originalDimensions: origDims } : {}),\n }\n}\n\n/**\n * One attachment card: a 64px cover tile (click opens the full image in a\n * new tab; load failures retry on click) beside a metadata column — display\n * name, normalized dimensions (plus the pre-normalization size dsh 0.1.1\n * records), and the stored byte size.\n */\nexport function makeImageCard(kit: ViewKit): ImageKit['Card'] {\n const { t } = kit\n return function ImageCard(props: { attachment: ImageRefLike; load?: ImageLoader }): ReactNS.ReactElement {\n const { attachment, load } = props\n const [src, setSrc] = React.useState<string | null>(null)\n const [error, setError] = React.useState(false)\n // Retry re-arms the one load effect, so every attempt runs under the\n // same liveness guard and the same reset.\n const [attempt, setAttempt] = React.useState(0)\n\n React.useEffect(() => {\n if (load === undefined) return\n let live = true\n setError(false)\n setSrc(null)\n void load(attachment).then((url) => { if (live) setSrc(url) }).catch(() => { if (live) setError(true) })\n return () => { live = false }\n }, [attachment, load, attempt])\n\n const name = attachment.name ?? t('attach.image')\n const dims = attachment.width !== undefined && attachment.height !== undefined\n ? `${attachment.width}×${attachment.height}`\n : null\n const orig = attachment.originalDimensions\n const facts: string[] = []\n if (dims !== null) facts.push(dims)\n if (orig !== undefined) facts.push(t('attach.orig', { d: `${orig.width}×${orig.height}` }))\n if (attachment.bytes !== undefined) facts.push(fmtBytes(attachment.bytes))\n\n const open = (): void => {\n if (src === null) return\n try { window.open(src, '_blank', 'noopener') } catch { /* popup blocked: ignore */ }\n }\n return (\n <div className=\"lc-att-item\">\n <button\n type=\"button\"\n className=\"lc-att-thumb\"\n title={error ? t('attach.loadFailed') : t('attach.open')}\n onClick={error ? () => { setAttempt(a => a + 1) } : open}\n >\n {src !== null\n ? <img src={src} alt={name} />\n : (\n <span className={error ? 'lc-att-err' : 'lc-att-ph'}>\n {error ? '⚠' : load === undefined ? '🖼' : t('attach.loading')}\n </span>\n )}\n </button>\n <div className=\"lc-att-meta\">\n <span className=\"lc-att-name\" title={name}>{name}</span>\n {facts.length > 0 ? <span className=\"lc-att-dims\">{facts.join(' · ')}</span> : null}\n </div>\n </div>\n )\n }\n}\n","/**\n * RichText — the raw/markdown view switch shared by the Context browser's\n * detail cards (system prompt, tool description, user/assistant message and\n * injection bodies).\n *\n * `RichCard` owns the per-card mode state and places a small segmented\n * switch (the same pill chrome as the trend chart's 步骤/轮次 control) at\n * the card's top-right corner; `RichText` renders one text block in the\n * handed-down mode — rendered markdown via the harness's shared\n * MarkdownText renderer (the default; GFM, sanitized, resolved from the\n * platform module table — zero plugin-side markdown dependency) or the raw\n * <pre>. The mode crosses component boundaries explicitly through render\n * props/props (no React context), and each card keeps its own state so two\n * open details switch independently.\n */\n\nimport type * as ReactNS from 'react'\nimport { MarkdownText } from '@deepseek-ai/dsh-client-ui-primitives'\nimport { React } from '../react'\nimport type { ViewKit } from '../viewkit'\n\n/** Detail-body view mode: raw source text or rendered markdown. */\nexport type RichMode = 'raw' | 'md'\n\nexport interface RichKit {\n /** One text block in the given mode: raw <pre> or rendered markdown. */\n RichText: (props: {\n text: string\n mode: RichMode\n /** Chrome of the raw block (defaults to the browser's `lc-br-pre`). */\n rawClass?: string\n /** Chrome of the markdown box (defaults to `lc-br-md`). */\n mdClass?: string\n }) => ReactNS.ReactElement\n /**\n * Detail card wrapper: renders the mode switch as a small segmented pill\n * on the card's top-right edge and hands the current mode to its `render`\n * prop (an explicit prop, not function-children, so the mode hand-off is\n * visible in the props object).\n */\n RichCard: (props: {\n className?: string\n render: (mode: RichMode) => ReactNS.ReactNode\n }) => ReactNS.ReactElement\n /** The segmented switch alone, for cards that place it in their own head row. */\n RichSwitch: (props: { mode: RichMode; onPick: (mode: RichMode) => void; inHead?: boolean }) => ReactNS.ReactElement\n /** Per-card mode state for bodies that place the switch themselves. */\n useRichMode: () => [RichMode, (mode: RichMode) => void]\n}\n\nexport function makeRichText(kit: ViewKit): RichKit {\n const { t } = kit\n\n function useRichMode(): [RichMode, (mode: RichMode) => void] {\n // Markdown is the default view: the detail cards hold prose (prompts,\n // descriptions, messages), which reads better rendered; raw stays one\n // click away for exact source inspection.\n const [mode, setMode] = React.useState<RichMode>('md')\n return [mode, setMode]\n }\n\n // Two-option pill mirroring the trend chart's 步骤/轮次 control: one\n // segment per view, the active segment highlighted; each segment's\n // tooltip spells its view out (localized).\n function RichSwitch(props: { mode: RichMode; onPick: (mode: RichMode) => void; inHead?: boolean }): ReactNS.ReactElement {\n const seg = (m: RichMode, label: string, tip: string) => (\n <button\n type=\"button\"\n className={'lc-rich-seg-btn' + (props.mode === m ? ' lc-rich-seg-on' : '')}\n title={tip}\n onClick={() => { props.onPick(m) }}\n >{label}</button>\n )\n return (\n <span className={'lc-rich-seg' + (props.inHead === true ? ' lc-rich-seg-head' : '')}>\n {seg('raw', t('rich.raw'), t('rich.toRaw'))}\n {seg('md', t('rich.md'), t('rich.toMd'))}\n </span>\n )\n }\n\n function RichText(props: {\n text: string\n mode: RichMode\n rawClass?: string\n mdClass?: string\n }): ReactNS.ReactElement {\n if (props.mode === 'md') {\n return <div className={props.mdClass ?? 'lc-br-md'}><MarkdownText text={props.text} /></div>\n }\n return <pre className={props.rawClass ?? 'lc-br-pre'}>{props.text}</pre>\n }\n\n function RichCard(props: {\n className?: string\n render: (mode: RichMode) => ReactNS.ReactNode\n }): ReactNS.ReactElement {\n const [mode, setMode] = useRichMode()\n return (\n <div className={props.className ?? 'lc-br-content'}>\n <RichSwitch mode={mode} onPick={setMode} />\n {props.render(mode)}\n </div>\n )\n }\n\n return { RichText, RichCard, RichSwitch, useRichMode }\n}\n","/**\n * ContextBrowser — the \"Context 浏览器\" card: pick the live surface or any\n * retained step and browse what the request was actually assembled from.\n *\n * Layout follows progressive disclosure instead of a flat dump:\n * step picker + composition bar\n * → six category sections (accordion: dot, label, element count, tokens)\n * → element rows (one per message / prompt / tool schema)\n * → the element's ACTUAL content, rendered per kind (text, reasoning,\n * tool call + result, injection notice, system prompt, JSON schema).\n *\n * Data sources: the `contextTimeline` projection (structure + token prices,\n * per-step reconstruction via the removed-node archive), the `contextHeaders`\n * projection (full system prompt + tool schemas — absent on older hosts,\n * degrading those two sections to tokens-only), and the framework\n * conversation snapshot (full message content joined by event seq; nodes\n * outside the loaded window fall back to the 80-char preview with a note).\n */\n\nimport type * as ReactNS from 'react'\nimport type { Category, ContextHeaders, ContextTimeline, HeaderTool, RequestRecord, SurfaceNode } from '../../shared/types'\nimport { assemble } from '../assemble'\nimport type { Assembled } from '../assemble'\nimport { CATS, partsOf } from '../categories'\nimport { React } from '../react'\nimport type { ConversationNodeLike, UseSessionLike } from '../services'\nimport type { ViewKit } from '../viewkit'\nimport { makeNodeText } from './nodes'\nimport { imageRefOf, makeImageCard } from './images'\nimport type { ImageKit } from './images'\nimport { makeRichText } from './richText'\nimport type { RichKit, RichMode } from './richText'\nimport type { StackedBarProps } from './stackedBar'\nimport type { ImageLoader, ImageRefLike } from '../services'\n\nexport interface ContextBrowserProps {\n data: ContextTimeline\n headers: ContextHeaders | null\n useSession?: UseSessionLike\n /** History-pagination verb contributed via `sessions.provide` (absent on older hosts). */\n loadOlderHistory?: () => Promise<void>\n /**\n * Trend-chart hover linkage: the seq of the bar under the pointer. While\n * set, the browser transiently previews that step; the picker's own\n * selection resumes when the pointer leaves the chart.\n */\n previewSeq?: number | null\n /**\n * Trend-chart pin linkage: the seq of the bar pinned by a click. The\n * browser's own step picker follows it — a pin selects that step, an\n * unpin (pinSeq back to null) returns the browser to the live surface.\n */\n pinSeq?: number | null\n /**\n * Current-composition hover link, shared with the Current Composition card\n * (its bar + legend): the active category key, reported via onHoverKey.\n * The browser joins the link ONLY while it shows the LIVE step — a pinned\n * or previewed step's composition differs, so its hover must not light the\n * overview (and the overview's hover must not highlight another step).\n */\n hoverKey?: string | null\n onHoverKey?: (key: string | null) => void\n /**\n * Overview tool-chip bridge: a click on the overview card's \"工具定义 Top\"\n * label (`tool` omitted) or one of its chips (`tool: name`) asks this\n * browser to reveal that section. A one-shot request — it is applied once\n * (switch to the live surface, open the \"tools\" category, and when a\n * specific tool is named expand its row), then handed back through\n * `onToolFocusHandled` so the same chip can be clicked again.\n */\n toolFocus?: { tool?: string } | null\n /** Called once a one-shot `toolFocus` request has been applied; the parent clears it. */\n onToolFocusHandled?: () => void\n /**\n * Session-authorized image URL loader (built by the Context view from the\n * harness conversation service). Absent = image cards render metadata only.\n */\n loadImage?: ImageLoader\n}\n\n/** The JSON Schema fragment describing one parameter's type, defensively narrowed. */\ninterface ParamSchema {\n type?: unknown\n description?: unknown\n // JSON Schema vocabulary used by tool inputs the browser needs to display\n // meaningfully: enum values (render as a comma-joined inline list), an\n // array's `items` (render the element type), and `anyOf`/`oneOf` (render\n // the alternation as a `/`-joined list). Anything else falls back to a\n // plain `type` string or `object` if absent.\n enum?: unknown\n items?: unknown\n anyOf?: unknown\n oneOf?: unknown\n}\n\n/** Flatten the `anyOf` / `oneOf` alternation into one displayable string. */\nfunction unionTypesOf(p: ParamSchema): string | null {\n const branches: unknown[] = []\n if (Array.isArray(p.anyOf)) branches.push(...p.anyOf as unknown[])\n if (Array.isArray(p.oneOf)) branches.push(...p.oneOf as unknown[])\n if (branches.length === 0) return null\n const parts: string[] = []\n for (const b of branches) {\n if (b !== null && typeof b === 'object') parts.push(typeOf(b))\n }\n return parts.length > 0 ? parts.join(' | ') : null\n}\n\n/**\n * Derive a short, human-readable type label from a JSON Schema fragment.\n * Arrays show their element type (`array<number>`); unions fold into\n * `a | b`; enums collapse into `(enum)`. Returns `unknown` when the schema\n * carries no usable signal — the row falls back to its description then.\n */\nfunction typeOf(p: ParamSchema): string {\n const u = unionTypesOf(p)\n if (u !== null) return u\n const t = p.type\n if (t === 'array') {\n const items = p.items\n if (items !== null && typeof items === 'object') {\n const inner = typeOf(items)\n return 'array<' + inner + '>'\n }\n return 'array'\n }\n if (typeof t === 'string') {\n if (t === 'object') {\n const props = (p as { properties?: unknown }).properties\n if (props !== null && typeof props === 'object' && Object.keys(props).length > 0) {\n return `object{${Object.keys(props).length}}`\n }\n }\n if (Array.isArray(p.enum) && p.enum.length > 0) {\n return t + ' (enum)'\n }\n return t\n }\n if (Array.isArray(p.enum) && p.enum.length > 0) return '(enum)'\n return 'unknown'\n}\n\n/**\n * Locate the parameter-bearing object inside a raw tool schema. Producers\n * may nest it under `parameters`, `input_schema`, `inputSchema`, or hand\n * the schema as the bare JSON Schema (when `type === 'object'`).\n */\nfunction paramsOf(schema: unknown): ParamSchema | null {\n if (schema === null || typeof schema !== 'object') return null\n const s = schema as Record<string, unknown>\n const candidate = (v: unknown): ParamSchema | null =>\n v !== null && typeof v === 'object' ? v : null\n const nested = candidate(s.parameters) ?? candidate(s.input_schema)\n ?? candidate(s.inputSchema)\n if (nested !== null) return nested\n // Bare JSON Schema: a `{ type: 'object', properties: {...} }` at the root\n // is itself the parameter object — no inner wrapper.\n if (s.type === 'object' && s.properties !== undefined && typeof s.properties === 'object') {\n return s\n }\n return null\n}\n\n/**\n * One row of the parsed parameter table — name (mono-styled, with a\n * required chip), short type label, and the description on its own line\n * (so a long blurb never breaks the name/type rhythm).\n */\nfunction ParamRow(props: {\n name: string\n schema: ParamSchema\n required: boolean\n}): ReactNS.ReactElement {\n const typeLabel = typeOf(props.schema)\n const desc = props.schema.description\n return (\n <div className=\"lc-ts-param-row\">\n <span className=\"lc-ts-param-name\">{props.name}</span>\n <span className=\"lc-ts-param-type\">{typeLabel}</span>\n <span className={props.required ? 'lc-ts-param-req' : 'lc-ts-param-req-off'}>\n {props.required ? '✓' : '·'}\n </span>\n {typeof desc === 'string' && desc !== ''\n ? <span className=\"lc-ts-param-desc\">{desc}</span>\n : null}\n </div>\n )\n}\n\n/**\n * The full body of one expanded tool row: description, a parsed parameter\n * table (when the schema carries one), and the raw JSON behind a toggle.\n * Owns its own open/closed state for the JSON so two expanded tools stay\n * independent. The description card carries the shared raw/markdown view\n * toggle in its head (per-card state via `rich.useRichMode`).\n */\nfunction ToolSchema(props: {\n description: string | undefined\n schema: unknown\n /** Rich-text toggle kit (description card: raw <pre> vs markdown). */\n rich: RichKit\n /** Localized labels for the card titles, empty-state line, and toggle. */\n labels: {\n desc: string\n title: string\n empty: string\n show: string\n hide: string\n }\n}): ReactNS.ReactElement {\n const { rich } = props\n const [jsonOpen, setJsonOpen] = React.useState(false)\n const [descMode, setDescMode] = rich.useRichMode()\n const params = React.useMemo(() => paramsOf(props.schema), [props.schema])\n // Pull `properties` + `required` out of the parameter object as plain\n // values (avoids re-deriving the same shape in every row).\n const rows = React.useMemo<{ name: string; schema: ParamSchema; required: boolean }[]>(() => {\n if (params === null) return []\n const props = (params as { properties?: unknown }).properties\n if (props === null || typeof props !== 'object') return []\n const req = Array.isArray((params as { required?: unknown }).required)\n ? new Set(((params as { required: unknown[] }).required)\n .filter((x): x is string => typeof x === 'string'))\n : new Set<string>()\n const out: { name: string; schema: ParamSchema; required: boolean }[] = []\n for (const k of Object.keys(props)) {\n const v = (props as Record<string, unknown>)[k]\n if (v === null || typeof v !== 'object') continue\n out.push({ name: k, schema: v, required: req.has(k) })\n }\n return out\n }, [params])\n const schemaJson = React.useMemo(\n () => props.schema !== undefined ? JSON.stringify(props.schema, null, 2) : '',\n [props.schema],\n )\n return (\n <>\n {props.description !== undefined ? (\n <div className=\"lc-ts-card\">\n <div className=\"lc-ts-card-head\">\n <b>{props.labels.desc}</b>\n <rich.RichSwitch mode={descMode} onPick={setDescMode} inHead />\n </div>\n <rich.RichText\n text={props.description}\n mode={descMode}\n rawClass=\"lc-ts-desc-body\"\n mdClass=\"lc-ts-desc-md\"\n />\n </div>\n ) : null}\n {params !== null && rows.length > 0 ? (\n <div className=\"lc-ts-card\">\n <div className=\"lc-ts-card-head\">\n <b>{props.labels.title}</b>\n <span className=\"lc-ts-card-count\">{rows.length}</span>\n </div>\n {rows.map(r => <ParamRow key={r.name} name={r.name} schema={r.schema} required={r.required} />)}\n </div>\n ) : params !== null ? (\n <div className=\"lc-ts-params-empty\">{props.labels.empty}</div>\n ) : null}\n {schemaJson !== '' ? (\n <div className=\"lc-ts-json\">\n <button\n type=\"button\"\n className=\"lc-ts-json-toggle\"\n onClick={() => { setJsonOpen(o => !o) }}\n >{(jsonOpen ? '▾ ' : '▸ ') + (jsonOpen ? props.labels.hide : props.labels.show)}</button>\n {jsonOpen ? <pre className=\"lc-br-pre lc-br-dim\">{schemaJson}</pre> : null}\n </div>\n ) : null}\n </>\n )\n}\n\n/** One raw content block (text/reasoning/tool-result/image/…), rendered defensively. */\nfunction RawBlocks(props: { blocks: readonly unknown[]; mode: RichMode; rich: RichKit; img: ImageKit }): ReactNS.ReactElement {\n const { rich, img } = props\n return (\n <>\n {props.blocks.map((b, i) => {\n const blk = b !== null && typeof b === 'object' ? b as { type?: string; text?: unknown; content?: unknown } : null\n if (blk !== null\n && (blk.type === 'text' || blk.type === 'reasoning') && typeof blk.text === 'string') {\n // Reasoning stays raw in either mode (plain model trace, not\n // prose); text blocks follow the card's view mode.\n if (blk.type === 'reasoning') {\n return <pre key={i} className=\"lc-br-pre lc-br-dim\">{blk.text}</pre>\n }\n return <rich.RichText key={i} text={blk.text} mode={props.mode} />\n }\n const image = imageRefOf(b)\n if (image !== null) return <img.Card key={i} attachment={image} load={img.load} />\n if (blk !== null && blk.type === 'tool-result' && Array.isArray(blk.content)) {\n return <RawBlocks key={i} blocks={blk.content as unknown[]} mode={props.mode} rich={rich} img={img} />\n }\n return <pre key={i} className=\"lc-br-pre lc-br-dim\">{JSON.stringify(b, null, 2)}</pre>\n })}\n </>\n )\n}\n\n/**\n * One assistant-message block (thinking / answer) as its own card: the\n * title row carries the block label plus the block's OWN raw/markdown\n * switch (per-card state via `rich.useRichMode`, mirroring the tool\n * description card), so a mixed reply's parts toggle independently.\n */\nfunction BlockCard(props: { label: string; text: string; rich: RichKit }): ReactNS.ReactElement {\n const { rich } = props\n const [mode, setMode] = rich.useRichMode()\n return (\n <div className=\"lc-ts-card\">\n <div className=\"lc-ts-card-head\">\n <b>{props.label}</b>\n <rich.RichSwitch mode={mode} onPick={setMode} inHead />\n </div>\n <rich.RichText\n text={props.text}\n mode={mode}\n rawClass=\"lc-ts-desc-body\"\n mdClass=\"lc-ts-desc-md\"\n />\n </div>\n )\n}\n\n/** The actual content of one surface element, joined from the conversation snapshot. */\nfunction NodeContent(props: {\n node: SurfaceNode\n conv: ConversationNodeLike | undefined\n hint: string\n rich: RichKit\n img: ImageKit\n labels: { thinking: string; answer: string; images: string; other: string }\n}): ReactNS.ReactElement {\n const { node, conv, rich, img } = props\n // The raw/markdown toggle serves the prose bodies (user / injection text,\n // compaction summaries); assistant thinking/answer blocks each carry\n // their own per-card switch (BlockCard); tool results stay raw\n // (structured payload, not prose).\n const richable = node.cat === 'user' || node.cat === 'assistant' || node.cat === 'inject'\n const wrap = (render: (mode: RichMode) => ReactNS.ReactNode): ReactNS.ReactElement =>\n richable\n ? <rich.RichCard render={render} />\n : <div className=\"lc-br-content\">{render('raw')}</div>\n\n if (conv === undefined) {\n if (node.text === undefined || node.text === '') {\n return <div className=\"lc-br-content\"><div className=\"lc-br-note\">{props.hint}</div></div>\n }\n return wrap(mode => (\n <>\n <rich.RichText text={node.text ?? ''} mode={mode} />\n <div className=\"lc-br-note\">{props.hint}</div>\n </>\n ))\n }\n if (conv.kind === 'assistant' && Array.isArray(conv.blocks)) {\n // Thinking and answer blocks render as SEPARATE cards, each owning its\n // raw/markdown switch; tool calls and images keep their raw forms.\n return (\n <div className=\"lc-br-content\">\n {conv.blocks.map((b, i) => {\n const blk = b as { kind?: string; text?: unknown; name?: string; argsRaw?: unknown }\n if (blk.kind === 'text' && typeof blk.text === 'string') {\n return <BlockCard key={i} label={props.labels.answer} text={blk.text} rich={rich} />\n }\n if (blk.kind === 'reasoning' && typeof blk.text === 'string') {\n return <BlockCard key={i} label={props.labels.thinking} text={blk.text} rich={rich} />\n }\n if (blk.kind === 'tool-call') {\n return (\n <div key={i} className=\"lc-br-call\">\n <span className=\"lc-br-tag\">{'→ ' + (blk.name ?? '?')}</span>\n {typeof blk.argsRaw === 'string' && blk.argsRaw !== ''\n ? <pre className=\"lc-br-pre lc-br-dim\">{blk.argsRaw}</pre>\n : null}\n </div>\n )\n }\n const image = imageRefOf(b)\n if (image !== null) return <img.Card key={i} attachment={image} load={img.load} />\n return null\n })}\n </div>\n )\n }\n if (conv.kind === 'tool-result') {\n return (\n <div className=\"lc-br-content\">\n {conv.call != null\n ? (\n <div className=\"lc-br-call\">\n <span className=\"lc-br-tag\">{'← ' + conv.call.name}</span>\n {conv.call.argsRaw !== '' ? <pre className=\"lc-br-pre lc-br-dim\">{conv.call.argsRaw}</pre> : null}\n </div>\n )\n : null}\n {Array.isArray(conv.content) ? <RawBlocks blocks={conv.content} mode=\"raw\" rich={rich} img={img} /> : null}\n </div>\n )\n }\n if (conv.kind === 'compaction') {\n return wrap(mode => (\n <>\n {typeof conv.summary === 'string' && conv.summary !== ''\n ? <rich.RichText text={conv.summary} mode={mode} />\n : null}\n </>\n ))\n }\n if (Array.isArray(conv.content)) {\n const blocks = conv.content as unknown[]\n // User messages get the card layout: prose in the toggle-served text\n // card, durable image refs as attachment cards (thumbnail + name + dims\n // + size), and anything else as a raw JSON card. A text-only message\n // renders exactly as before — one rich card and nothing else.\n if (node.cat !== 'user') {\n return wrap(mode => <RawBlocks blocks={blocks} mode={mode} rich={rich} img={img} />)\n }\n const texts: string[] = []\n const images: ImageRefLike[] = []\n const others: unknown[] = []\n for (const b of blocks) {\n const blk = b as { type?: string; text?: unknown } | null\n if (blk !== null && typeof blk === 'object' && blk.type === 'text' && typeof blk.text === 'string') {\n texts.push(blk.text)\n continue\n }\n const image = imageRefOf(b)\n if (image !== null) { images.push(image); continue }\n others.push(b)\n }\n return (\n <div className=\"lc-br-content\">\n {texts.length > 0 ? (\n // Un-padded RichCard: the outer lc-br-content already owns the\n // body indent, so the text card aligns with the attachment cards\n // instead of sitting one indent deeper.\n <rich.RichCard className=\"lc-br-rich-inline\" render={mode => (\n <>\n {texts.map((text, i) => <rich.RichText key={i} text={text} mode={mode} />)}\n </>\n )} />\n ) : null}\n {images.length > 0 ? (\n <div className=\"lc-ts-card\">\n <div className=\"lc-ts-card-head\">\n <b>{props.labels.images}</b>\n <span className=\"lc-ts-card-count\">{images.length}</span>\n </div>\n <div className=\"lc-att-grid\">\n {images.map((a, i) => <img.Card key={`${a.attachmentId}:${i}`} attachment={a} load={img.load} />)}\n </div>\n </div>\n ) : null}\n {others.length > 0 ? (\n <div className=\"lc-ts-card\">\n <div className=\"lc-ts-card-head\">\n <b>{props.labels.other}</b>\n <span className=\"lc-ts-card-count\">{others.length}</span>\n </div>\n {others.map((b, i) => <pre key={i} className=\"lc-br-pre lc-br-dim\">{JSON.stringify(b, null, 2)}</pre>)}\n </div>\n ) : null}\n </div>\n )\n }\n return <div className=\"lc-br-content\"><div className=\"lc-br-note\">{props.hint}</div></div>\n}\n\n/** Group an assembled surface's nodes by category (for per-category counts). */\nfunction byCatOf(asm: Assembled): Partial<Record<Category, SurfaceNode[]>> {\n const m: Partial<Record<Category, SurfaceNode[]>> = {}\n for (const n of asm.nodes) (m[n.cat] ??= []).push(n)\n return m\n}\n\n/** Count one category's elements in an assembled surface (header cats included). */\nfunction countOf(asm: Assembled, c: string): number {\n if (c === 'system') return asm.header !== null && asm.header.system !== undefined ? 1 : 0\n if (c === 'tools') return asm.header !== null ? asm.header.tools.length : 0\n return byCatOf(asm)[c as Category]?.length ?? 0\n}\n\n/** The last request of `turn` in a seq-ordered timeline, or null. */\nfunction lastOfTurn(requests: RequestRecord[], turn: number): RequestRecord | null {\n for (let i = requests.length - 1; i >= 0; i--) if ((requests[i].turn ?? 0) === turn) return requests[i]\n return null\n}\n\nexport function makeContextBrowser(\n kit: ViewKit,\n StackedBar: (props: StackedBarProps) => ReactNS.ReactElement,\n): (props: ContextBrowserProps) => ReactNS.ReactElement {\n const { t, fmt, fmtTime, catLabel } = kit\n const nodeText = makeNodeText(kit)\n const rich = makeRichText(kit)\n const ImageCard = makeImageCard(kit)\n const catColor: Record<string, string> = {}\n for (const c of CATS) catColor[c.key] = c.color\n\n // Auto-load ceiling: one expand pulls older pages (50 events each) until\n // the element's seq enters the window, history runs out, or this cap is\n // hit — a guard against seqs that never land in the conversation snapshot.\n const MAX_AUTO_PAGES = 20\n\n return function ContextBrowser(props: ContextBrowserProps): ReactNS.ReactElement {\n const { data, headers } = props\n // 'live' = the current surface (the NEXT request's context); a number =\n // the seq of a retained request record (a past step).\n const [sel, setSel] = React.useState<'live' | number>('live')\n const [openCat, setOpenCat] = React.useState<string | null>(null)\n const [openElem, setOpenElem] = React.useState<string | null>(null)\n\n // Full message content, joined from the conversation snapshot by the\n // surface event seq. `s.nodes` is a stable reference per snapshot; the\n // seq map is memoized over it.\n const convNodes = typeof props.useSession === 'function'\n ? props.useSession(s => s.nodes)\n : undefined\n const bySeq = React.useMemo(() => {\n const m = new Map<number, ConversationNodeLike>()\n for (const n of convNodes ?? []) m.set(n.seq, n)\n return m\n }, [convNodes])\n\n // Window state for on-demand history pagination (primitive selectors, so\n // the component re-renders only when a page actually lands or runs out).\n const hasMore = typeof props.useSession === 'function'\n ? props.useSession(s => s.hasMore === true)\n : false\n const loadingOlder = typeof props.useSession === 'function'\n ? props.useSession(s => s.loadingOlder === true)\n : false\n\n // The open element's surface-node seq ('sys'/'tool:*' keys never join).\n const openSeq = openElem !== null && openElem.startsWith('n')\n ? Number(openElem.slice(1))\n : null\n const missingSeq = openSeq !== null && !bySeq.has(openSeq) ? openSeq : null\n // Auto-load: expanding an out-of-window element pages older history in\n // until its seq joins (one page in flight, sequenced by the snapshot's\n // own loadingOlder flag). `exhausted` latches the cap/history-end so the\n // hint falls back to the static note instead of \"loading\" forever.\n const [exhausted, setExhausted] = React.useState(false)\n const pagesRef = React.useRef(0)\n React.useEffect(() => {\n pagesRef.current = 0\n setExhausted(false)\n }, [openElem])\n const loadOlderHistory = props.loadOlderHistory\n React.useEffect(() => {\n if (missingSeq === null || !hasMore || loadingOlder || exhausted) return\n if (loadOlderHistory === undefined) return\n if (pagesRef.current >= MAX_AUTO_PAGES) {\n setExhausted(true)\n return\n }\n pagesRef.current += 1\n void loadOlderHistory()\n }, [missingSeq, hasMore, loadingOlder, exhausted, bySeq, loadOlderHistory])\n React.useEffect(() => {\n // History ran out with the seq still missing: stop showing \"loading\".\n if (!hasMore && missingSeq !== null && !exhausted) setExhausted(true)\n }, [hasMore, missingSeq, exhausted])\n // History-chart pin linkage: a pinned bar selects its step in the picker,\n // an unpin returns to live — the same accordion reset a manual pick\n // performs. (Live is also the right target while unpinned: a manual pick\n // made here is overridden only when a NEW pin lands.)\n const pinSeq = props.pinSeq\n React.useEffect(() => {\n setSel(pinSeq === null || pinSeq === undefined ? 'live' : pinSeq)\n setOpenCat(null)\n setOpenElem(null)\n }, [pinSeq])\n // Overview tool-link bridge: apply a one-shot request (switch to the LIVE\n // surface — the overview's Top chips rank the current header's tools —\n // open the tools category, expand the clicked tool), then hand it back so\n // the parent can issue the same focus again on the next click.\n const toolFocus = props.toolFocus\n React.useEffect(() => {\n if (toolFocus === null || toolFocus === undefined) return\n setSel('live')\n setOpenCat('tools')\n setOpenElem(toolFocus.tool !== undefined ? 'tool:' + toolFocus.tool : null)\n if (props.onToolFocusHandled !== undefined) props.onToolFocusHandled()\n }, [toolFocus, props.onToolFocusHandled])\n const awaiting = missingSeq !== null && !exhausted && loadOlderHistory !== undefined && hasMore\n\n const requests = data.requests\n // Trend-chart hover linkage: the bar under the pointer transiently\n // previews its step (unknown seq = trimmed out of retention, ignored);\n // the picker's own selection resumes when the pointer leaves the chart.\n const hoverReq = props.previewSeq !== null && props.previewSeq !== undefined\n ? requests.find(r => r.seq === props.previewSeq) ?? null\n : null\n const req = hoverReq ?? (sel === 'live' ? null : requests.find(r => r.seq === sel) ?? null)\n // A pinned step trimmed out of retention falls back to live.\n const seq = req !== null ? req.seq : null\n // Current-composition hover link: the browser joins the Current\n // Composition card's shared hover only while it shows the LIVE step —\n // a pinned/previewed step has a different composition, so its hover must\n // not light the overview (and the overview's hover must not highlight\n // this step's parts). The mirror filter drops the overview's FREE-track\n // key, which has no segment in the browser's bar.\n const linked = req === null && props.onHoverKey !== undefined\n const linkKey = linked && props.hoverKey !== null && props.hoverKey !== 'free'\n ? props.hoverKey\n : null\n const view = assemble(data, headers, seq)\n const breakdown = req !== null ? req : data.current\n const parts = partsOf(breakdown)\n const total = breakdown.total\n const pick = (v: string) => {\n setSel(v === 'live' ? 'live' : Number(v))\n setOpenCat(null)\n setOpenElem(null)\n }\n\n // δ baselines against the PREVIOUS TURN's last request — one stable unit\n // whatever step (or live surface) is shown: a step of turn T reads\n // against turn T−1's final step, avoiding the misleading \"change\" a\n // same-turn neighbour would imply. Live refers to the most recent\n // request, itself a turn's last step.\n const refReq = req === null\n ? requests.length > 0 ? requests[requests.length - 1] : null\n : lastOfTurn(requests, (req.turn ?? 0) - 1)\n const prevView = refReq !== null ? assemble(data, headers, refReq.seq) : null\n\n const byCat = byCatOf(view)\n\n const toolCount = (c: string): number => countOf(view, c)\n\n const toggleCat = (c: string) => {\n // Empty categories stay shut — EXCEPT system/tools with a missing\n // header epoch: those open to explain the degradation note.\n const openable = toolCount(c) > 0\n || ((c === 'system' || c === 'tools') && view.header === null)\n if (!openable) return\n setOpenCat(openCat === c ? null : c)\n setOpenElem(null)\n }\n const toggleElem = (key: string) => { setOpenElem(openElem === key ? null : key) }\n\n /** One expandable element row (preview line; content when open). */\n const elemRow = (\n key: string, tag: string | null, preview: string,\n tokens: number, time: number | undefined, body: ReactNS.ReactNode,\n ) => {\n const open = openElem === key\n return (\n <div key={key} className={'lc-br-elem' + (open ? ' lc-br-elem-on' : '')}>\n <button type=\"button\" className=\"lc-br-elem-row\" onClick={() => { toggleElem(key) }}>\n <span className={'lc-br-chev' + (open ? ' lc-br-chev-on' : '')}>{'▸'}</span>\n {tag !== null ? <span className=\"lc-br-tag\">{tag}</span> : null}\n <span className=\"lc-br-preview\">{preview}</span>\n {time !== undefined ? <span className=\"lc-br-time\">{fmtTime(time)}</span> : null}\n <span className=\"lc-br-tokens\">{'≈' + fmt(tokens)}</span>\n </button>\n {open ? body : null}\n </div>\n )\n }\n\n const catBody = (c: string): ReactNS.ReactNode => {\n if (c === 'system') {\n if (view.header === null) return <div className=\"lc-br-note\">{t(headers === null ? 'browser.noHeader' : 'browser.noEpoch')}</div>\n const system = view.header.system\n if (system === undefined) return null\n return elemRow('sys', null, system.replace(/\\s+/g, ' ').trim().slice(0, 80), breakdown.system, undefined,\n <rich.RichCard render={mode => <rich.RichText text={system} mode={mode} />} />)\n }\n if (c === 'tools') {\n if (view.header === null) return <div className=\"lc-br-note\">{t(headers === null ? 'browser.noHeader' : 'browser.noEpoch')}</div>\n // Schemas rank by token price (largest first), mirroring the overview's\n // \"工具定义 Top\" chips; the producer's header order is not meaningful.\n // Localized labels for the per-tool parameter table / JSON toggle:\n // passed in by the parent so the body component stays a pure function\n // of its props (testable in isolation, no closure over `t`).\n const labels = {\n desc: t('tool.desc'),\n title: t('tool.params'),\n empty: t('tool.paramsEmpty'),\n show: t('tool.jsonToggle'),\n hide: t('tool.jsonHide'),\n }\n return view.header.tools.slice().sort((a, b) => b.tokens - a.tokens).map((tool: HeaderTool) => {\n return elemRow('tool:' + tool.name, null, tool.name, tool.tokens, undefined,\n <div className=\"lc-br-content\">\n <ToolSchema description={tool.description} schema={tool.schema} rich={rich} labels={labels} />\n </div>)\n })\n }\n // Surface-node categories carry per-element timestamps; list them\n // newest first, mirroring the NodeList card.\n const nodes = (byCat[c as Category] ?? []).slice().reverse()\n return nodes.map((n) => {\n // Tag/preview split: the compact chip carries the compact fact (tool\n // name, injection form), the preview line carries the text — each\n // fact shown once. Skill/calls previews already name themselves.\n let tag: string | null = null\n let preview = nodeText(n)\n if (n.cat === 'tool') {\n tag = (n.tool ?? '?') + (n.err ? ' ⚠' : '')\n preview = t('node.toolResult') + (n.err ? ' ⚠' : '')\n } else if (n.cat === 'inject' && !n.skill) {\n tag = t('form.' + (n.form || 'context'))\n if (n.text !== undefined && n.text !== '') {\n preview = n.form === 'snapshot' ? t('node.snapshot') + n.text : n.text\n }\n }\n return elemRow(`n${n.seq}`, tag, preview, n.tokens, n.time,\n <NodeContent\n node={n}\n conv={bySeq.get(n.seq)}\n rich={rich}\n img={{ Card: ImageCard, load: props.loadImage }}\n // Localized block/section titles (thinking / answer / image and\n // other-content cards), handed in by the parent so the body\n // stays a pure function of props.\n labels={{\n thinking: t('block.thinking'),\n answer: t('block.answer'),\n images: t('attach.images'),\n other: t('attach.other'),\n }}\n // This row's body renders only while it is the open element, so\n // `awaiting` (open seq missing, pagination armed) means THIS join\n // is the one pages are being pulled for.\n hint={bySeq.get(n.seq) === undefined && awaiting\n ? t('browser.loading')\n : t('browser.noContent')}\n />)\n })\n }\n\n return (\n <div className=\"lc-card\">\n <div className=\"lc-card-title\">\n <span className=\"lc-card-title-text\">{t('browser.title')}</span>\n <span className=\"lc-br-hint\">{t('browser.deltaHint')}</span>\n <select\n className=\"lc-br-pick\"\n value={seq === null ? 'live' : String(seq)}\n onChange={(e) => { pick(e.target.value) }}\n >\n <option value=\"live\">{t('browser.live')}</option>\n {requests.slice().reverse().map(r => (\n <option key={r.seq} value={String(r.seq)}>\n {t('detail.step', { t: r.turn ?? 0, s: r.step ?? 0 }) + ' · ' + fmtTime(r.time)}\n </option>\n ))}\n </select>\n </div>\n\n <div className=\"lc-br-meta\">\n <b>{req !== null\n ? t('detail.step', { t: req.turn ?? 0, s: req.step ?? 0 })\n : t('browser.liveNow')}</b>\n {req !== null ? <span>{fmtTime(req.time)}</span> : null}\n {hoverReq !== null ? <span className=\"lc-card-sub\">{t('browser.preview')}</span> : null}\n <span>{t('detail.estTotal', { n: fmt(total) })}</span>\n {req !== null && req.prompt !== undefined\n ? <span className=\"lc-actual\">{t('detail.actual', { n: fmt(req.prompt) })}</span>\n : null}\n </div>\n\n <div className=\"lc-br-bar\">\n <StackedBar\n parts={parts}\n height={10}\n // Mirrored hover link (see `linked` above): while the browser\n // shows the live surface, its bar highlights the shared category\n // key and reports its own hovers back to the Current Composition\n // card. The tip stays off — a cross-card hover must not float a\n // second tooltip over a bar the pointer does not rest on.\n hoverKey={linked ? linkKey : undefined}\n onHoverKey={linked ? props.onHoverKey : undefined}\n tip={false}\n />\n </div>\n\n {view.missingLive > 0\n ? <div className=\"lc-br-note\">{t('browser.missingLive', { n: view.missingLive })}</div>\n : null}\n {view.approximate\n ? <div className=\"lc-br-note\">{t('browser.approx')}</div>\n : null}\n\n <div className=\"lc-br-cats\">\n {CATS.map((c) => {\n const count = toolCount(c.key)\n const v = breakdown[c.key] || 0\n // Δ vs the reference step: element-count badge (hidden when the\n // count held), token swing in the badge's tooltip — the same two\n // figures the row already shows, over the deepest step in scope.\n const prevCount = prevView !== null ? countOf(prevView, c.key) : null\n const countDelta = prevCount !== null ? count - prevCount : null\n const prevTokens = refReq !== null ? (refReq[c.key] || 0) : null\n const tokenDelta = prevTokens !== null ? v - prevTokens : null\n const openable = count > 0\n || ((c.key === 'system' || c.key === 'tools') && view.header === null)\n const open = openCat === c.key && openable\n return (\n <div key={c.key} className={'lc-br-cat' + (openable ? '' : ' lc-br-cat-empty')}>\n <button\n type=\"button\"\n className={'lc-br-cat-row' + (linked && props.hoverKey === c.key ? ' lc-br-cat-on' : '')}\n onMouseEnter={linked ? () => { if (props.onHoverKey !== undefined) props.onHoverKey(c.key) } : undefined}\n onMouseLeave={linked ? () => { if (props.onHoverKey !== undefined) props.onHoverKey(null) } : undefined}\n onClick={() => { toggleCat(c.key) }}\n >\n <span className={'lc-br-chev' + (open ? ' lc-br-chev-on' : '')}>{'▸'}</span>\n <i style={{ background: c.color }} />\n <span className=\"lc-br-cat-label\">{catLabel(c.key)}</span>\n {/* Count + Δ pill sit as one attached group (tight inner gap),\n the group absorbs the row's free space so tokens/percent\n stay right-aligned. */}\n <span className=\"lc-br-count-grp\">\n <span className=\"lc-br-cat-count\">{t('browser.items', { n: count })}</span>\n {countDelta !== null && countDelta !== 0 ? (\n <span className={'lc-br-delta lc-br-delta-' + (countDelta > 0 ? 'up' : 'down')}>\n {`${countDelta > 0 ? '+' : ''}${countDelta}`}\n </span>\n ) : null}\n </span>\n {/* Token Δ pill hugs the left of the token figure — its own\n direction-colored pill, hidden while the count held. */}\n <span className=\"lc-br-tokens-grp\">\n {tokenDelta !== null && tokenDelta !== 0 ? (\n <span className={'lc-br-tdelta lc-br-tdelta-' + (tokenDelta > 0 ? 'up' : 'down')}>\n {(tokenDelta > 0 ? '+' : '') + fmt(tokenDelta)}\n </span>\n ) : null}\n <span className=\"lc-br-tokens\">{'≈' + fmt(v)}</span>\n </span>\n <span className=\"lc-br-pct\">{total > 0 ? `${Math.round(v / total * 100)}%` : ''}</span>\n </button>\n {open ? <div className=\"lc-br-body\">{catBody(c.key)}</div> : null}\n </div>\n )\n })}\n </div>\n </div>\n )\n }\n}\n","/**\n * StackedBar + Legend — the composition bar (overview card) and its legend.\n * Hovering a segment or its legend chip lights the same segment and shows\n * the same tooltip; the free window space (blank track) is hoverable too.\n * JSX components; the shared hover-link tooltip is bespoke (no shared\n * primitive reproduces the cross-segment/legend linkage), so it stays custom\n * but styled through the shared `--dsw-alias-*` tokens.\n */\n\nimport type * as ReactNS from 'react'\nimport type { PartsPart } from '../categories'\nimport type { ViewKit } from '../viewkit'\n\nimport { React } from '../react'\n\n/**\n * DSH's automatic compaction trigger as a fraction of the routed context\n * window — the default `thresholdRatio` of `@deepseek-ai/dsh-compaction-basic`\n * (it compacts at step boundaries once `floor(contextWindow × ratio)` is\n * reached). DSH does not publish the configured ratio to plugins or clients,\n * so the UI mirrors the default here; deployments that tune `thresholdRatio`\n * / `modelPolicies` can adjust it if they want the reserve band to match.\n */\nexport const AUTO_COMPACT_RATIO = 0.8\n\nexport interface StackedBarProps {\n parts: PartsPart[]\n max?: number\n height?: number\n /** Optional hover link: the active segment key, reported via onHoverKey. */\n hoverKey?: string | null\n onHoverKey?: (key: string | null) => void\n /** Render the hover tooltip (default true). A mirrored bar that only echoes\n * another card's hover turns it off, so the tooltip floats only over the\n * surface the pointer actually rests on. */\n tip?: boolean\n /**\n * Optional auto-compaction reserve band: the rightmost `(1 − ratio)` of the\n * window, drawn as striped \"headroom\" — the region the session normally\n * avoids filling because automatic compaction triggers past the threshold.\n * Only rendered when `max` (the window) is a positive number. `label` is the\n * translated hover explanation shown over the band.\n */\n reserve?: { ratio: number; label: string }\n}\n\nexport function makeStackedBar(kit: ViewKit): (props: StackedBarProps) => ReactNS.ReactElement {\n const { t, fmt, catLabel } = kit\n return function StackedBar(props: StackedBarProps): ReactNS.ReactElement {\n // Hovering the reserve band shows its explanation (not a segment's); the\n // flag lives here so the single tooltip slot serves both.\n const [reserveOn, setReserveOn] = React.useState(false)\n // props.parts: [{key,color,value}]; optional props.max: when max exceeds\n // the parts' total, the remainder shows as an empty, hoverable track\n // (\"free window\" — the space left in the context window).\n let total = 0\n for (const p of props.parts) total += p.value\n const scale = props.max !== undefined && props.max > total ? props.max : total\n const free = props.max !== undefined && props.max > total ? props.max - total : 0\n // Segment widths are laid out against the FULL window (scale), but their\n // legend/tooltip percentages are shares of the OCCUPIED total — so on\n // hover we frame the occupied region (width = used/scale) with a solid\n // box that makes that reference frame visible. Only when a free track\n // exists (otherwise width already equals the percentage).\n const usedPct = scale > 0 ? total / scale * 100 : 0\n const hovering = props.hoverKey !== null && props.hoverKey !== undefined\n const showBox = free > 0 && hovering\n\n // The reserve band is laid out in WINDOW units (`ratio × max` → `max`)\n // scaled onto whatever total the bar spans, so it stays the same physical\n // slice whether or not a free track exists (once used exceeds the window,\n // the stripes sit over the outermost segments).\n const reserve = props.reserve !== undefined && props.max !== undefined && props.max > 0\n // Carry the checked max into the object: the non-null reserve below\n // then proves max is present, no assertion needed.\n ? { ...props.reserve, max: props.max }\n : null\n // Round to one decimal: the ratios are float-y (0.8 × max / scale) and a\n // style % with a long decimal tail is noise (would render the same).\n const reserveLeft = reserve !== null ? Math.round(reserve.max * reserve.ratio / scale * 1000) / 10 : 0\n const reserveWidth = reserve !== null ? Math.round((1 - reserve.ratio) * reserve.max / scale * 1000) / 10 : 0\n\n // The tooltip is DERIVED from the shared hover key, so hovering either a\n // segment or its legend chip lights the same segment and shows the same\n // tooltip (centered on the segment; percentage positioning needs no\n // measuring). The wrapper keeps the tooltip outside the clipped stack.\n // Hovering the RESERVE band overrides the slot with its own explanation,\n // centered over the band's middle.\n let tip: { text: string; leftPct: number } | null = null\n if (reserveOn && reserve !== null) {\n tip = {\n text: reserve.label,\n leftPct: Math.max(12, Math.min(reserveLeft + reserveWidth / 2, 88)),\n }\n } else if (props.hoverKey !== null && props.hoverKey !== undefined) {\n if (props.hoverKey === 'free' && free > 0) {\n const pct = scale > 0 ? free / scale * 100 : 0\n tip = {\n text: `${t('overview.free')} ${fmt(free)} (${Math.round(pct)}%)`,\n leftPct: Math.max(12, Math.min((total / scale * 100) + pct / 2, 88)),\n }\n } else {\n let acc = 0\n for (const p of props.parts) {\n const pct = scale > 0 ? p.value / scale * 100 : 0\n if (p.key === props.hoverKey && p.value > 0) {\n tip = {\n // \"(pct%)\" is a share of the OCCUPIED total — the solid box\n // that appears on hover frames exactly this reference region.\n text: `${catLabel(p.key)} ≈${fmt(p.value)} (${Math.round(p.value / total * 100)}%) `\n + t('overview.ofUsed'),\n leftPct: Math.max(12, Math.min(acc + pct / 2, 88)),\n }\n break\n }\n acc += pct\n }\n }\n }\n\n return (\n <div className=\"lc-stacked-wrap\">\n <div\n // Hover focus: dim everything except the hovered part and show the\n // occupied-region frame (`.lc-stacked-dim` + `.lc-occupied-box`).\n className={'lc-stacked' + (hovering ? ' lc-stacked-dim' : '')}\n style={{ height: `${props.height || 14}px` }}\n onMouseLeave={() => {\n if (props.onHoverKey !== undefined) props.onHoverKey(null)\n setReserveOn(false)\n }}\n >\n {total > 0\n ? props.parts.map((p) => {\n if (!p.value) return null\n const on = props.hoverKey !== undefined && props.hoverKey === p.key\n return (\n <div\n key={p.key}\n className={'lc-stacked-seg' + (on ? ' lc-stacked-seg-on' : '')}\n style={{ width: `${p.value / scale * 100}%`, background: p.color }}\n onMouseEnter={() => { if (props.onHoverKey !== undefined) props.onHoverKey(p.key) }}\n />\n )\n })\n : null}\n {free > 0 ? (\n <div\n key=\"free\"\n className={'lc-stacked-free' + (props.hoverKey === 'free' ? ' lc-stacked-free-on' : '')}\n style={{ width: `${free / scale * 100}%` }}\n onMouseEnter={() => { if (props.onHoverKey !== undefined) props.onHoverKey('free') }}\n />\n ) : null}\n {/* Auto-compaction reserve band: the rightmost (1−ratio) of the\n window, striped like a warning plate to read as \"headroom, not\n real usage\". Painted above the track/segments so the stripes\n overlay them, owns the pointer so its own explanation shows\n (and the segment hover link is cleared while exploring it). */}\n {reserve !== null ? (\n <div\n className=\"lc-reserve\"\n style={{ left: `${reserveLeft}%`, width: `${reserveWidth}%` }}\n onMouseEnter={() => {\n setReserveOn(true)\n if (props.onHoverKey !== undefined) props.onHoverKey(null)\n }}\n onMouseLeave={() => { setReserveOn(false) }}\n />\n ) : null}\n {/* Hover reference frame: the occupied region (outside the free\n track) — the region the legend/tooltip percentages refer to.\n Painted last so its border stays above the segments. Always\n mounted (`.lc-occupied-box-on` toggles opacity) so the frame\n fades out on leave instead of unmounting instantly. */}\n <div\n className={'lc-occupied-box' + (showBox ? ' lc-occupied-box-on' : '')}\n style={{ width: `${usedPct}%` }}\n />\n </div>\n {/* The hover tooltip is always mounted too (opacity toggles via\n `.lc-bar-tip-on`) so it fades in AND out; hidden it holds no\n pointer events and no width of its own. */}\n {props.tip !== false\n ? (\n <div\n className={'lc-bar-tip' + (tip ? ' lc-bar-tip-on' : '')}\n style={{ left: tip ? `${tip.leftPct}%` : '50%' }}\n >{tip ? tip.text : ''}</div>\n )\n : null}\n </div>\n )\n }\n}\n\nexport function makeLegend(kit: ViewKit): (props: {\n parts: PartsPart[]\n hoverKey?: string | null\n onHoverKey?: (key: string | null) => void\n}) => ReactNS.ReactElement {\n const { t, fmt, catLabel } = kit\n return function Legend(props: {\n parts: PartsPart[]\n hoverKey?: string | null\n onHoverKey?: (key: string | null) => void\n }): ReactNS.ReactElement {\n let total = 0\n for (const p of props.parts) total += p.value\n return (\n <div className=\"lc-legend\">\n {props.parts.map((p) => {\n const on = props.hoverKey !== undefined && props.hoverKey === p.key\n return (\n <span\n key={p.key}\n className={'lc-chip' + (on ? ' lc-chip-on' : '')}\n title={t('overview.ofUsed')}\n onMouseEnter={() => { if (props.onHoverKey !== undefined) props.onHoverKey(p.key) }}\n onMouseLeave={() => { if (props.onHoverKey !== undefined) props.onHoverKey(null) }}\n >\n <i style={{ background: p.color }} />\n <span className=\"lc-chip-label\">{catLabel(p.key)}</span>\n <span className=\"lc-chip-nums\">\n {'≈' + fmt(p.value)}\n {total > 0 ? <em>{`${Math.round(p.value / total * 100)}%`}</em> : null}\n </span>\n </span>\n )\n })}\n </div>\n )\n }\n}\n","/**\n * CurrentComposition — the \"当前构成\" card shared by the Context tab and the\n * /context popup: the composition headline (occupancy vs window), the\n * composition bar (with the auto-compaction reserve band), the legend, and —\n * when a tool bridge is wired — the ranked \"工具定义 Top\" chips that jump the\n * Context browser to a tool section.\n *\n * JSX function component, pure (no state): everything flows through props so\n * either host drives the shared hover link and the tool focus identically.\n */\n\nimport type * as ReactNS from 'react'\nimport type { PartsPart } from '../categories'\nimport type { Headline } from '../headline'\nimport type { ViewKit } from '../viewkit'\nimport { AUTO_COMPACT_RATIO } from './stackedBar'\nimport type { StackedBarProps } from './stackedBar'\n\nimport { React } from '../react'\n\ntype LegendFn = (props: {\n parts: PartsPart[]\n hoverKey?: string | null\n onHoverKey?: (key: string | null) => void\n}) => ReactNS.ReactElement\n\nexport interface CurrentCompositionProps {\n head: Headline\n /** Card subtitle (model / provider); empty hides it. */\n subtitle?: string\n /** Shared hover link (bar + legend + browser while it shows the live step). */\n hoverKey?: string | null\n onHoverKey?: (key: string | null) => void\n /** Optional ranked tool schemas for the \"工具定义 Top\" row (absent = no chips). */\n tools?: { name: string; tokens: number }[]\n /** One-shot tool-focus request into the Context browser (omitted = no chips). */\n onToolFocus?: (focus: { tool?: string } | null) => void\n}\n\nexport function makeCurrentComposition(\n kit: ViewKit,\n StackedBar: (props: StackedBarProps) => ReactNS.ReactElement,\n Legend: LegendFn,\n): (props: CurrentCompositionProps) => ReactNS.ReactElement {\n const { t, fmt } = kit\n return function CurrentComposition(props: CurrentCompositionProps): ReactNS.ReactElement {\n const head = props.head\n const reserve = head.window != null && head.window > 0\n ? { ratio: AUTO_COMPACT_RATIO, label: t('overview.compactReserve', { pct: Math.round(AUTO_COMPACT_RATIO * 100) }) }\n : undefined\n return (\n <div className=\"lc-card\">\n <div className=\"lc-card-title\">\n <span className=\"lc-card-title-text\">{t('overview.title')}</span>\n {props.subtitle !== undefined && props.subtitle !== ''\n ? <span className=\"lc-card-sub\">{props.subtitle}</span>\n : null}\n </div>\n <div className=\"lc-overview-num\">\n <b>{fmt(head.tokens)}</b>\n <span>\n {head.window\n ? ' / ' + fmt(head.window) + ' tokens'\n : ' ' + t('overview.estimate')}\n </span>\n {head.pct !== null ? (\n <span className=\"lc-overview-pct\">\n <b>{`${head.pct}%`}</b>\n {t('overview.used')}\n </span>\n ) : null}\n </div>\n <StackedBar\n parts={head.parts}\n height={16}\n max={head.window}\n hoverKey={props.hoverKey}\n onHoverKey={props.onHoverKey}\n reserve={reserve}\n />\n <Legend parts={head.parts} hoverKey={props.hoverKey} onHoverKey={props.onHoverKey} />\n {props.tools !== undefined && props.tools.length > 0 ? (\n <div className=\"lc-tools\">\n <button type=\"button\" className=\"lc-tools-label\" onClick={() => { if (props.onToolFocus !== undefined) props.onToolFocus({}) }}>\n {t('tools.top')}\n </button>\n {props.tools.slice().sort((a, b) => b.tokens - a.tokens).slice(0, 5).map(tool => (\n <button key={tool.name} type=\"button\" className=\"lc-tool-chip\" onClick={() => { if (props.onToolFocus !== undefined) props.onToolFocus({ tool: tool.name }) }}>\n {tool.name + ' ' + fmt(tool.tokens)}\n </button>\n ))}\n {props.tools.length > 5\n ? (\n <button type=\"button\" className=\"lc-tools-more\" onClick={() => { if (props.onToolFocus !== undefined) props.onToolFocus({}) }}>\n {t('tools.more', { n: props.tools.length })}\n </button>\n )\n : null}\n </div>\n ) : null}\n </div>\n )\n }\n}\n","/**\n * ErrorBoundary — the tab's no-white-screen guarantee.\n *\n * A render error anywhere in the subtree (a foreign or corrupt projection\n * value that slips past the shape guards in services.ts, a framework\n * surprise, a future bug) would otherwise propagate into the harness's slot\n * renderer and unmount the whole conversation view. This boundary catches\n * render errors of its subtree and degrades to a styled error card with the\n * offending message — the surrounding harness UI (chat, tabs, composer)\n * keeps working as if nothing happened.\n *\n * A class component: the only React primitive that can catch render errors\n * of a subtree (there is no hook-based boundary in React 18). The Retry\n * button resets the boundary; if the underlying condition persists the\n * boundary catches again, once a healthy value arrives the tab resumes.\n */\n\nimport type * as ReactNS from 'react'\nimport type { Translate } from '../i18n'\n\nimport { React } from '../react'\n\nexport function makeErrorBoundary(t: Translate): ReactNS.ComponentType<{ children?: ReactNS.ReactNode }> {\n return class ErrorBoundary extends React.Component<{ children?: ReactNS.ReactNode }, { error: Error | null }> {\n constructor(props: { children?: ReactNS.ReactNode }) {\n super(props)\n this.state = { error: null }\n }\n\n static getDerivedStateFromError(error: unknown): { error: Error | null } {\n return { error: error instanceof Error ? error : new Error(String(error)) }\n }\n\n render(): ReactNS.ReactNode {\n const error = this.state.error\n if (error === null) return this.props.children\n return (\n <div className=\"lc-root\">\n <div className=\"lc-empty lc-error\">\n <span>{t('error')}</span>\n <code className=\"lc-error-msg\">{error.message}</code>\n <button\n type=\"button\"\n className=\"lc-error-retry\"\n onClick={() => { this.setState({ error: null }) }}\n >{t('error.retry')}</button>\n </div>\n </div>\n )\n }\n }\n}\n","/**\n * ContextModal — the /context command's centered dialog: the same data as\n * the Context tab (the pushed `contextTimeline` projection) distilled to\n * the current-composition overview (headline + composition bar + legend)\n * and the shared Context browser (browse any retained step's assembled\n * surface). Rendered from the `conversation.input.overlay` slot; opens and\n * closes through the per-session modal store (the trigger source flips it,\n * so no message ever enters the session history).\n */\n\nimport type * as ReactNS from 'react'\nimport { headlineOf } from '../headline'\nimport { modalStoreOf, takePendingConsume } from '../modalStore'\nimport type { ClientCtx, SessionStandardProps, SessionsFace } from '../services'\nimport { contextPressureOf, headersOf, timelineOf } from '../services'\nimport type { ViewKit } from '../viewkit'\nimport { makeContextBrowser } from './browser'\nimport { makeCurrentComposition } from './currentComposition'\nimport { makeErrorBoundary } from './errorBoundary'\nimport { makeLegend, makeStackedBar } from './stackedBar'\n\nimport { React, h } from '../react'\n\nexport interface ContextModalProps extends SessionStandardProps {\n /** Bound selector hook over the per-session open flag (hooks compartment). */\n useContextModal?: (sel: (open: boolean) => boolean) => boolean\n}\n\nexport function makeContextModal(ctx: ClientCtx, kit: ViewKit): (props: ContextModalProps) => ReactNS.ReactElement | null {\n const { t } = kit\n const sessions = ctx.get('sessions') as SessionsFace | undefined\n const StackedBar = makeStackedBar(kit)\n const Legend = makeLegend(kit)\n // The /context popup reuses the SAME cards as the Context tab — no\n // duplicated browsing logic; picking, accordion, reconstruction and paging\n // all ride the shared components (joining the modal overview's hover link\n // while the browser shows the live step, and the tool chips jumping it).\n const CurrentComposition = makeCurrentComposition(kit, StackedBar, Legend)\n const ContextBrowser = makeContextBrowser(kit, StackedBar)\n const ErrorBoundary = makeErrorBoundary(t)\n\n // The body holds all hooks and data reads inside the error boundary (same\n // arrangement as the Context tab): a corrupt projection value or framework\n // surprise degrades to a styled error card inside the dialog instead of\n // breaking the conversation input overlay around it.\n function ContextModalBody(props: ContextModalProps): ReactNS.ReactElement | null {\n const sessionId = typeof props.sessionId === 'string' ? props.sessionId : ''\n const open = typeof props.useContextModal === 'function' ? props.useContextModal(s => s) : false\n const data = typeof props.useProjection === 'function'\n ? timelineOf(props.useProjection('contextTimeline'))\n : null\n // Provider-anchored occupancy from the official token-meter\n // `contextPressure` projection (same key the chat ring reads); absent\n // value degrades to the derived fallback inside headlineOf.\n const pressure = typeof props.useProjection === 'function'\n ? contextPressureOf(props.useProjection('contextPressure'))\n : null\n // Header-content epochs for the browser's system/tools sections (absent\n // on older hosts -> tokens-only degradation, same as the Context tab).\n const headers = typeof props.useProjection === 'function'\n ? headersOf(props.useProjection('contextHeaders'))\n : null\n const [hoverCat, setHoverCat] = React.useState<string | null>(null)\n // One-shot tool-focus from the CurrentComposition card's chips into the\n // embedded Context browser (label = category-only, chip = specific tool).\n const [toolFocus, setToolFocus] = React.useState<{ tool?: string } | null>(null)\n\n const close = React.useCallback(() => {\n if (sessionId === '') return\n modalStoreOf(sessionId).set(false)\n // Deferred token consumption: the `/context` token stayed in the\n // composer while the modal was open; consume it now through the scoped\n // input event (a stale guard — the user typed meanwhile — fails soft\n // inside the shell and leaves the draft untouched).\n const guard = takePendingConsume(sessionId)\n if (guard === undefined || sessions === undefined) return\n const scope = sessions.scope(sessionId)\n if (scope !== undefined) scope.bail(scope, 'slash/input-consume-token', { guard })\n }, [sessionId])\n\n // Escape closes; on open the current focus (the composer) is captured\n // and restored on close, so typing resumes exactly where it stopped.\n React.useEffect(() => {\n if (!open) return undefined\n const previous = document.activeElement instanceof HTMLElement ? document.activeElement : null\n const onKey = (ev: KeyboardEvent) => {\n if (ev.key !== 'Escape') return\n ev.preventDefault()\n ev.stopPropagation()\n close()\n }\n window.addEventListener('keydown', onKey, true)\n return () => {\n window.removeEventListener('keydown', onKey, true)\n if (previous !== null && document.contains(previous)) previous.focus()\n }\n }, [open, close])\n\n if (!open) return null\n\n const head = data !== null ? headlineOf(data, pressure) : null\n // The composition card carries the model/provider subtitle; keep the\n // dialog header to just the title + close (model/provider below once).\n const subtitle = data !== null ? (data.model ? data.model : '') + (data.provider ? ' · ' + data.provider : '') : ''\n\n return (\n <div className=\"lc-modal-backdrop\" onClick={close}>\n <div className=\"lc-modal-card\" onClick={(ev) => { ev.stopPropagation() }}>\n <div className=\"lc-modal-head\">\n <span className=\"lc-modal-title\">{t('tab')}</span>\n <button className=\"lc-modal-close\" aria-label={t('cmd.close')} onClick={close}>×</button>\n </div>\n\n {data === null || head === null ? (\n <div className=\"lc-empty\">{t('loading')}</div>\n ) : (\n <div>\n <CurrentComposition\n head={head}\n subtitle={subtitle}\n hoverKey={hoverCat}\n onHoverKey={setHoverCat}\n tools={data.toolList}\n onToolFocus={setToolFocus}\n />\n <ContextBrowser\n data={data}\n headers={headers}\n useSession={props.useSession}\n loadOlderHistory={props.loadOlderHistory}\n hoverKey={hoverCat}\n onHoverKey={setHoverCat}\n toolFocus={toolFocus}\n onToolFocusHandled={() => { setToolFocus(null) }}\n />\n </div>\n )}\n </div>\n </div>\n )\n }\n\n return function ContextModal(props: ContextModalProps): ReactNS.ReactElement | null {\n return h(ErrorBoundary, null, h(ContextModalBody, props))\n }\n}\n","/**\n * Context events — event text helpers (label + timeline range) and the\n * EventList component that renders the events column.\n *\n * JSX function components: glyphs for injection/model-switch reuse the\n * harness's shared icon set (`@deepseek-ai/dsh-client-ui-primitives`, a\n * platform seed word resolved from the loader module table); compaction and\n * prune keep the ✂ marker (product vocabulary, no shared glyph exists).\n * Each row carries a kind chip (注入/压缩/剪枝/切换) so the classification is\n * readable at a glance; chip color matches the impact direction (+ adds,\n * − frees, ⇄ neutral), mirroring the token sign colors. Long labels truncate\n * with an ellipsis; the native title tooltip is attached only while the\n * label actually overflows (re-measured on every render and on resize).\n */\n\nimport type * as ReactNS from 'react'\nimport type { ContextEventRecord } from '../../shared/types'\nimport { IconBranchOutline16, IconPlusOutline16 } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { Translate } from '../i18n'\nimport type { ViewKit } from '../viewkit'\n\nimport { React } from '../react'\n\nexport const EVENT_ICONS: Record<string, string> = { compaction: '✂', prune: '✂', inject: '+', model: '⇄' }\n\nexport interface EventListProps { events: ContextEventRecord[] }\n\n/** Build the event text helpers bound to the translate function. */\nexport function makeEventText(t: Translate): {\n eventLabel: (ev: ContextEventRecord) => string\n eventAt: (ev: ContextEventRecord) => string | null\n} {\n function eventLabel(ev: ContextEventRecord): string {\n if (ev.kind === 'compaction') return t('ev.compaction', { n: ev.count || 0 })\n if (ev.kind === 'prune') return t('ev.prune')\n if (ev.kind === 'model') return t('ev.model', { a: ev.from || '?', b: ev.to || '?' })\n // The kind union narrows to 'inject' here; a future kind breaks the\n // compile (ev.sub ev.form ev.name are inject-only), forcing a label.\n if (ev.sub === 'skill') return t('ev.skill', { name: ev.name || '?' })\n const base = t('form.' + (ev.form || 'context'))\n return ev.name ? base + ' · ' + ev.name : base\n }\n\n /**\n * Where this event sits in the request timeline, as a label or null.\n * Boundary events (compaction/prune) show the GAP they sit in: same-turn\n * \"Step 2→3\", cross-turn \"Turn 50 · Step 8 → Turn 51 · Step 1\". Injections\n * and model switches belong to one request and keep the single point.\n * Events with no following request (in flight) stay unlabeled.\n */\n function eventAt(ev: ContextEventRecord): string | null {\n if (ev.kind === 'compaction' || ev.kind === 'prune') {\n if (typeof ev.turn === 'number' && typeof ev.step === 'number') {\n if (typeof ev.fromTurn === 'number' && typeof ev.fromStep === 'number') {\n if (ev.fromTurn === ev.turn) return t('events.range', { t: ev.turn, a: ev.fromStep, b: ev.step })\n return t('events.rangeTo', { a: ev.fromTurn, as: ev.fromStep, b: ev.turn, bs: ev.step })\n }\n return t('events.at', { t: ev.turn, s: ev.step })\n }\n return null\n }\n if (typeof ev.turn === 'number' && typeof ev.step === 'number') {\n return t('events.at', { t: ev.turn, s: ev.step })\n }\n return null\n }\n\n return { eventLabel, eventAt }\n}\n\nexport function makeEventList(kit: ViewKit): (props: EventListProps) => ReactNS.ReactElement {\n const { t, fmt, fmtTime, eventLabel, eventAt } = kit\n return function EventList(props: EventListProps): ReactNS.ReactElement {\n if (props.events.length === 0) {\n return <div className=\"lc-empty\">{t('events.empty')}</div>\n }\n const rootRef = React.useRef<HTMLDivElement | null>(null)\n // Attach the native tooltip only where the ellipsis actually truncates:\n // re-sync after every render (events/width change) and on window resize,\n // reading scrollWidth vs clientWidth on the live row.\n React.useLayoutEffect(() => {\n const root = rootRef.current\n if (!root) return\n const sync = () => {\n for (const el of root.querySelectorAll<HTMLElement>('.lc-event-label')) {\n el.title = el.scrollWidth > el.clientWidth ? el.textContent || '' : ''\n }\n }\n sync()\n window.addEventListener('resize', sync)\n return () => { window.removeEventListener('resize', sync) }\n })\n const sorted = props.events.slice().reverse()\n return (\n <div className=\"lc-events\" ref={rootRef}>\n {sorted.map((ev, i) => {\n const label = eventLabel(ev)\n const at = eventAt(ev)\n const glyph = ev.kind === 'inject' ? <IconPlusOutline16 />\n : ev.kind === 'model' ? <IconBranchOutline16 />\n : EVENT_ICONS[ev.kind] || '•'\n return (\n <div key={`${ev.seq}-${i}`} className=\"lc-event\">\n <span className={'lc-event-icon lc-event-' + ev.kind}>{glyph}</span>\n <span className={'lc-kind lc-kind-' + ev.kind}>{t('kind.' + ev.kind)}</span>\n <span className=\"lc-event-label\">{label}</span>\n {at !== null ? <span className=\"lc-event-at\">{at}</span> : null}\n {ev.tokens ? (\n <span className={'lc-event-tokens' + (ev.kind === 'inject' ? ' lc-up' : ' lc-down')}>\n {(ev.kind === 'inject' ? '+' : '−') + fmt(ev.tokens)}\n </span>\n ) : null}\n <span className=\"lc-event-time\">{fmtTime(ev.time)}</span>\n </div>\n )\n })}\n </div>\n )\n }\n}\n","/**\n * Plugin self-metadata for the Plugin info card. Version is substituted at\n * build time (tsdown `define` in tsdown.config.ts, read from package.json);\n * the typeof guard keeps a dev/test bundle built without defines working.\n */\n\ndeclare const __DSH_CTX_VERSION__: string | undefined\ndeclare const __DSH_CTX_REPO__: string | undefined\n\nexport const PLUGIN_NAME = 'dsh-context'\nexport const PLUGIN_VERSION: string =\n typeof __DSH_CTX_VERSION__ === 'string' ? __DSH_CTX_VERSION__ : '0.0.0-dev'\nexport const PLUGIN_REPO: string =\n typeof __DSH_CTX_REPO__ === 'string' ? __DSH_CTX_REPO__ : 'https://github.com/bowenliang123/dsh-context'\n/** Short `owner/repo` form of the GitHub URL, for display only. */\nexport const PLUGIN_REPO_SHORT = PLUGIN_REPO.replace(/^https?:\\/\\/github\\.com\\//, '')\n","/**\n * Latest published version of this plugin on the npm registry — the one\n * live check the Plugin info card performs. Fetched lazily on the first\n * card mount and cached with a 1-hour TTL, so the registry is hit at most\n * once per hour per page. Every failure mode (offline, CSP-blocked,\n * non-200, malformed body) narrows to null = no upgrade hint, so the card\n * silently keeps its static version.\n */\n\nimport { PLUGIN_NAME } from './meta'\n\nconst REGISTRY_URL = 'https://registry.npmjs.org/' + PLUGIN_NAME + '/latest'\n\n/** How long a registry result stays fresh before the next check refetches. */\nconst TTL_MS = 60 * 60 * 1000\n\nlet cached: { at: number; promise: Promise<string | null> } | null = null\n\nexport function fetchLatestVersion(): Promise<string | null> {\n if (!cached || Date.now() - cached.at >= TTL_MS) {\n cached = {\n at: Date.now(),\n promise: fetch(REGISTRY_URL)\n .then(res => (res.ok ? res.json() as Promise<{ version?: unknown }> : null))\n .then(body => (body !== null && typeof body.version === 'string' ? body.version : null))\n .catch(() => null),\n }\n }\n return cached.promise\n}\n\n/** Numeric semver compare (pre-release suffix ignored): is `latest` strictly newer than `current`? */\nexport function isNewerVersion(latest: string, current: string): boolean {\n const parse = (v: string): number[] =>\n v.replace(/^v/, '').split('-', 1)[0].split('.').map(n => parseInt(n, 10) || 0)\n const a = parse(latest)\n const b = parse(current)\n for (let i = 0; i < Math.max(a.length, b.length); i++) {\n const x = a[i] || 0\n const y = b[i] || 0\n if (x !== y) return x > y\n }\n return false\n}\n","/**\n * PluginInfo — the card beside Context stats introducing the plugin itself.\n * Every row is one whole-row link: the anchor wraps the label + value so the\n * entire key/value cell is one hit target. Row 1 (Plugin name + version) →\n * the repo's releases page, row 2 (the short owner/repo label) → the repo\n * root; hovering a row underlines its value. Metadata is baked into the\n * bundle from package.json via tsdown `define` (see src/client/meta.ts +\n * tsdown.config.ts). One live check rides on top: the card asks the npm\n * registry for the latest published version (cached with a 1-hour TTL, see\n * ../latestVersion.ts) and shows an `↑ vX.Y.Z` chip when it is newer.\n *\n * Layout: exactly two full-width rows, each a single horizontal line with\n * the label on the left and the value on the right — a compact definition\n * list instead of a multi-cell grid.\n */\n\nimport type * as ReactNS from 'react'\nimport { fetchLatestVersion, isNewerVersion } from '../latestVersion'\nimport { PLUGIN_NAME, PLUGIN_REPO, PLUGIN_REPO_SHORT, PLUGIN_VERSION } from '../meta'\nimport type { ViewKit } from '../viewkit'\n\nimport { React } from '../react'\n\nexport function makePluginInfo(kit: ViewKit): () => ReactNS.ReactElement {\n const { t } = kit\n const row = (label: string, value: ReactNS.ReactNode, href: string) => (\n <a className=\"lc-pi-row\" href={href} target=\"_blank\" rel=\"noreferrer\">\n <div className=\"lc-pi-label\">{label}</div>\n <div className=\"lc-pi-value\">{value}</div>\n </a>\n )\n return function PluginInfo(): ReactNS.ReactElement {\n const [latest, setLatest] = React.useState<string | null>(null)\n React.useEffect(() => {\n // Dev bundles carry a `0.0.0-dev` placeholder version: skip the check.\n if (PLUGIN_VERSION.includes('-dev')) return\n let on = true\n // Fire-and-forget: fetchLatestVersion never rejects (every failure\n // narrows to null), and the `on` flag drops late results.\n void fetchLatestVersion().then((v) => { if (on && v) setLatest(v) })\n return () => { on = false }\n }, [])\n const update = latest !== null && isNewerVersion(latest, PLUGIN_VERSION) ? latest : null\n const nameValue: ReactNS.ReactNode[] = [PLUGIN_NAME + ' (v' + PLUGIN_VERSION + ')']\n if (update) nameValue.push(<span key=\"update\" className=\"lc-pi-update\">{'↑ v' + update}</span>)\n return (\n <div className=\"lc-card\">\n <div className=\"lc-card-title\">\n <span className=\"lc-card-title-text\">{t('plugin.title')}</span>\n <span className=\"lc-card-sub\">{t('plugin.hint')}</span>\n </div>\n <div className=\"lc-pi-grid\">\n {row(t('plugin.name'), nameValue, PLUGIN_REPO + '/releases')}\n {row(t('plugin.github'), PLUGIN_REPO_SHORT, PLUGIN_REPO)}\n </div>\n </div>\n )\n }\n}\n","/**\n * RequestDetail — the breakdown panel under the history chart for the\n * active (hovered/pinned/newest) request. The header names the request and,\n * when the bar carries a boundary event, a ✂ chip shows where the event\n * happened (the gap between the request before and after). JSX component.\n */\n\nimport type * as ReactNS from 'react'\nimport type { ContextEventRecord, RequestRecord } from '../../shared/types'\nimport { partsOf, CATS } from '../categories'\nimport type { StackedBarProps } from './stackedBar'\nimport type { ViewKit } from '../viewkit'\n\nimport { React } from '../react'\n\nexport interface RequestDetailProps {\n request: RequestRecord | null\n /** The boundary event attached to this request (✂ chip in the header). */\n marker?: ContextEventRecord | null\n}\n\nexport function makeRequestDetail(\n kit: ViewKit,\n StackedBar: (props: StackedBarProps) => ReactNS.ReactElement,\n): (props: RequestDetailProps) => ReactNS.ReactElement | null {\n const { t, fmt, fmtTime, catLabel, eventLabel, eventAt } = kit\n return function RequestDetail(props: RequestDetailProps): ReactNS.ReactElement | null {\n const req = props.request\n if (!req) return null\n // Turn aggregates are labeled with their step count, and the breakdown\n // below is explicitly tagged as the turn's LAST step (that is the record\n // the bar carries).\n const isTurn = req.stepCount !== undefined && req.stepCount > 1\n const head = isTurn\n ? t('detail.turn', { t: req.turn ?? 0, n: req.stepCount ?? 0 })\n : t('detail.step', { t: req.turn ?? 0, s: req.step ?? 0 })\n // When this bar carries a boundary event (compaction/prune), the header\n // also shows WHERE the event happened: the gap between the request\n // before and the request after (e.g. \"✂ Turn 49 · Step 2→3\").\n const marker = props.marker ?? null\n const markerAt = marker !== null ? eventAt(marker) : null\n return (\n <div className=\"lc-detail\">\n <div className=\"lc-detail-head\">\n <b>{head}</b>\n {marker !== null && markerAt !== null\n ? <span className=\"lc-detail-marker\" title={eventLabel(marker)}>{'✂ ' + markerAt}</span>\n : null}\n {isTurn ? <span className=\"lc-detail-tag\">{t('detail.lastStep')}</span> : null}\n <span>{fmtTime(req.time)}</span>\n <span>{t('detail.estTotal', { n: fmt(req.total) })}</span>\n {req.prompt !== undefined\n ? <span className=\"lc-actual\">{t('detail.actual', { n: fmt(req.prompt) })}</span>\n : null}\n {req.output !== undefined\n ? <span>{t('detail.output', { n: fmt(req.output) })}</span>\n : null}\n </div>\n <StackedBar parts={partsOf(req)} height={10} />\n <div className=\"lc-detail-rows\">\n {CATS.map((c) => {\n const v = req[c.key] || 0\n return (\n <div key={c.key} className=\"lc-detail-row\">\n <i style={{ background: c.color }} />\n <span className=\"lc-detail-label\">{catLabel(c.key)}</span>\n <span className=\"lc-bar-track\">\n <span className=\"lc-bar-fill\" style={{ width: `${req.total > 0 ? v / req.total * 100 : 0}%`, background: c.color }} />\n </span>\n <span className=\"lc-detail-num\">{'≈' + fmt(v)}</span>\n <span className=\"lc-detail-pct\">{req.total > 0 ? `${Math.round(v / req.total * 100)}%` : ''}</span>\n </div>\n )\n })}\n </div>\n </div>\n )\n }\n}\n","/**\n * Session-cost estimate — prices the host-folded cumulative billed-token\n * totals (SessionCostUsage) with DeepSeek's V4 list prices, HARDCODED for\n * now (per request; revisit when DeepSeek adjusts prices). Source:\n * https://api-docs.deepseek.com/quick_start/pricing/ (USD) and\n * https://api-docs.deepseek.com/zh-cn/quick_start/pricing/ (CNY).\n *\n * Peak windows are 01:00-04:00 and 06:00-10:00 UTC (off-peak is half the\n * peak rate); the Host already split the totals by period, so pricing here\n * is a pure lookup. Both currencies the UI ships are tabulated — the locale\n * picks which one the stats board shows.\n */\n\nimport type { CostBucketTotals, SessionCostUsage } from '../shared/types'\nimport { numOf } from './services'\n\n/** Per-1M-token rates: cache-hit input, cache-miss input, output. */\nexport interface PriceTriple { hit: number; miss: number; out: number }\n\nconst PRICES = {\n usd: {\n flash: { peak: { hit: 0.014, miss: 0.44, out: 1.32 }, off: { hit: 0.007, miss: 0.22, out: 0.66 } },\n pro: { peak: { hit: 0.044, miss: 1.32, out: 3.96 }, off: { hit: 0.022, miss: 0.66, out: 1.98 } },\n },\n cny: {\n flash: { peak: { hit: 0.10, miss: 3.0, out: 9.0 }, off: { hit: 0.05, miss: 1.5, out: 4.5 } },\n pro: { peak: { hit: 0.30, miss: 9.0, out: 27.0 }, off: { hit: 0.15, miss: 4.5, out: 13.5 } },\n },\n} as const\n\nexport type CostCurrency = keyof typeof PRICES\n\n/**\n * Price the session's cumulative billed-token totals. Cache reads bill at\n * the hit rate; uncached input AND cache writes bill at the miss rate;\n * output (reasoning included) bills at the out rate. Null when nothing was\n * priced (no DeepSeek V4 usage folded yet), so the cell can show a dash.\n */\nexport function estimateSessionCost(usage: SessionCostUsage | null | undefined, currency: CostCurrency): number | null {\n if (usage === null || usage === undefined) return null\n let total = 0\n let any = false\n for (const family of ['flash', 'pro'] as const) {\n const fam = usage[family]\n if (fam === undefined) continue\n for (const period of ['peak', 'off'] as const) {\n const b: CostBucketTotals | undefined = fam[period]\n if (b === undefined) continue\n const p: PriceTriple = PRICES[currency][family][period]\n total += (numOf(b.cacheRead) * p.hit + (numOf(b.uncached) + numOf(b.cacheWrite)) * p.miss + numOf(b.output) * p.out) / 1e6\n any = true\n }\n }\n return any ? total : null\n}\n\n/** Short money format: two decimals at and above one unit, two significant digits below. */\nexport function formatCost(amount: number, currency: CostCurrency): string {\n const symbol = currency === 'cny' ? '¥' : '$'\n return symbol + (amount >= 1 ? amount.toFixed(2) : amount.toPrecision(2))\n}\n\n/**\n * All priced model families for one currency, in display order, with their\n * peak/off-peak rate triples — the raw material of the stats-board tooltip's\n * price list. The numbers stay hardcoded in PRICES above; this function only\n * reshapes the table for display, so what the tooltip prints can never drift\n * from the math that prices the session.\n */\nexport function sessionPrices(currency: CostCurrency): { family: string; peak: PriceTriple; off: PriceTriple }[] {\n return (['flash', 'pro'] as const).map(id => ({\n family: id === 'flash' ? 'deepseek-v4-flash' : 'deepseek-v4-pro',\n peak: PRICES[currency][id].peak,\n off: PRICES[currency][id].off,\n }))\n}\n\n/** Price-list figure: the same money format as formatCost, trailing zeros trimmed (¥3.00 → ¥3, $0.0070 → $0.007). */\nexport function formatPriceRate(amount: number, currency: CostCurrency): string {\n return formatCost(amount, currency).replace(/0+$/, '').replace(/\\.$/, '')\n}\n","/**\n * StatsBoard — the session context statistics card above the composition:\n * conversation size (turns/steps), context churn (compaction count,\n * prune count, injection count), the cache-hit share, and the estimated\n * cumulative session cost. The counts cover the retained history window,\n * matching the History chart; the cache-hit figure reuses the official\n * token-meter `tokenUsage` projection verbatim — the exact same data and\n * formula as the chat stats line below the input box — and the cost cell\n * prices the host-folded cumulative billed-token totals (complete session\n * log) with the hardcoded DeepSeek V4 list prices (cost.ts), in the\n * locale's currency. The cost cell's hover bubble (a \"?\" marker plus a\n * styled DOM tip — the harness GUI never shows native `title` tooltips)\n * explains the whole-session estimate and lists the per-1M-token price\n * table straight from cost.ts, so the printed rates can never drift from\n * the math. JSX component.\n */\n\nimport type * as ReactNS from 'react'\nimport type { ContextEventRecord, RequestRecord, SessionCostUsage, TokenUsage } from '../../shared/types'\nimport { estimateSessionCost, formatCost, formatPriceRate, sessionPrices } from '../cost'\nimport type { CostCurrency } from '../cost'\nimport { numOf } from '../services'\nimport type { ViewKit } from '../viewkit'\n\nimport { React } from '../react'\n\n/**\n * Cache-hit share of billed prompt-side input — same buckets as the harness's\n * chat stats line below the input box (`cacheReadTokens` over the three\n * disjoint billed buckets: uncached + reads + writes). Unlike that line's\n * whole-percent rounding, this one TRUNCATES to two decimal places (cut, not\n * round). Null when no input was billed. A tiny epsilon keeps a double stored\n * a hair below a cent boundary (e.g. 80.00 as 79.9999999999…) from losing its\n * last digit — with integer token counts no genuine value ever sits that close\n * to a boundary, so the epsilon can only absorb float noise. Bucket reads go\n * through numOf so a malformed payload degrades to a dash instead of NaN text.\n */\nfunction cacheHitPercent(usage: TokenUsage): string | null {\n const uncached = numOf(usage.uncachedInputTokens)\n const reads = numOf(usage.cacheReadTokens)\n const writes = numOf(usage.cacheWriteTokens)\n const billed = uncached + reads + writes\n if (billed === 0) return null\n const hundredths = Math.trunc((reads / billed) * 10000 + 1e-9)\n return `${Math.floor(hundredths / 100)}.${String(hundredths % 100).padStart(2, '0')}`\n}\n\nexport function makeStatsBoard(kit: ViewKit): (props: {\n requests: RequestRecord[]\n events: ContextEventRecord[]\n usage: TokenUsage | null\n /** Session-cost raw material from the timeline (undefined: nothing priced). */\n cost?: SessionCostUsage\n /** Active locale id — zh prices in CNY, everything else in USD. */\n locale: string\n}) => ReactNS.ReactElement {\n const { t, fmt } = kit\n return function StatsBoard(props: {\n requests: RequestRecord[]\n events: ContextEventRecord[]\n usage: TokenUsage | null\n cost?: SessionCostUsage\n locale: string\n }): ReactNS.ReactElement {\n const turns = new Set<number>()\n let steps = 0, compactions = 0, prunes = 0, injects = 0\n for (const req of props.requests) {\n turns.add(req.turn ?? 0)\n steps++\n }\n for (const ev of props.events) {\n if (ev.kind === 'compaction') compactions++\n else if (ev.kind === 'prune') prunes++\n else if (ev.kind === 'inject') injects++\n }\n const hit = props.usage !== null ? cacheHitPercent(props.usage) : null\n const currency: CostCurrency = props.locale === 'zh' ? 'cny' : 'usd'\n const cost = estimateSessionCost(props.cost, currency)\n const fmtRate = (n: number) => formatPriceRate(n, currency)\n // Cost-cell tooltip content: the intro sentence (whole-session estimate,\n // peak/off-peak windows) followed by the actual per-1M-token price list\n // for the locale's currency, straight from cost.ts's PRICES table.\n const costTip: ReactNS.ReactNode = [\n t('stats.costTip'),\n <span key=\"prices\" className=\"lc-stat-tip-prices\">\n <span className=\"lc-stat-tip-head\">{t('stats.costPriceHead')}</span>\n {sessionPrices(currency).map(r => (\n <span key={r.family} className=\"lc-stat-tip-row\">\n <b className=\"lc-stat-tip-model\">{r.family}</b>\n {' '}{t('stats.costHit')} {fmtRate(r.peak.hit)}/{fmtRate(r.off.hit)}\n {' · '}{t('stats.costMiss')} {fmtRate(r.peak.miss)}/{fmtRate(r.off.miss)}\n {' · '}{t('stats.costOut')} {fmtRate(r.peak.out)}/{fmtRate(r.off.out)}\n </span>\n ))}\n </span>,\n ]\n // A cell may carry an explanation bubble: the label then shows a \"?\"\n // marker and the styled tip (`.lc-stat-tip`, revealed on cell hover) —\n // the native `title` attribute is invisible in the harness GUI.\n const cell = (label: string, value: string, tip?: ReactNS.ReactNode) => (\n <div className={'lc-stat' + (tip === undefined ? '' : ' lc-stat-tipped')}>\n <span className=\"lc-stat-label\">\n {label}\n {tip !== undefined && <i className=\"lc-stat-q\" aria-hidden=\"true\">?</i>}\n </span>\n <b className=\"lc-stat-value\">{value}</b>\n {tip !== undefined && <span className=\"lc-stat-tip\" role=\"tooltip\">{tip}</span>}\n </div>\n )\n return (\n <div className=\"lc-card lc-col lc-col-stats\">\n <div className=\"lc-card-title\">\n <span className=\"lc-card-title-text\">{t('stats.title')}</span>\n <span className=\"lc-card-sub\">{t('stats.hint')}</span>\n </div>\n <div className=\"lc-stats\">\n {cell(t('stats.turns'), fmt(turns.size))}\n {cell(t('stats.steps'), fmt(steps))}\n {cell(t('stats.injects'), fmt(injects))}\n {cell(t('stats.compactions'), fmt(compactions))}\n {cell(t('stats.prunes'), fmt(prunes))}\n {cell(t('stats.cacheHit'), hit === null ? '—' : hit + '%')}\n {cell(t('stats.cost'), cost === null ? '—' : formatCost(cost, currency), costTip)}\n </div>\n </div>\n )\n }\n}\n","/**\n * TrendChart — the per-request history chart: fixed-width stacked bars with\n * a horizontal scroll (newest anchored right), a turn color strip below,\n * ✂ markers for boundary events, and edge fades. Includes the data\n * preparation helpers (aggregateByTurn, attachMarkers) used by ContextView.\n * JSX component; the chart chrome is bespoke data-viz (no shared primitive),\n * styled through the shared `--dsw-alias-*` tokens.\n */\n\nimport type * as ReactNS from 'react'\nimport type { ContextEventRecord, RequestRecord } from '../../shared/types'\nimport { CATS } from '../categories'\nimport type { ViewKit } from '../viewkit'\n\nimport { React } from '../react'\n\nexport interface TrendChartProps {\n requests: RequestRecord[]\n /** One boundary event (compaction/prune) per request index, if attached. */\n markers: (ContextEventRecord | undefined)[]\n selectedSeq: number | null\n hoveredSeq: number | null\n /** The turn currently highlighted (from the turn strip or a hovered bar). */\n activeTurn: number | null\n /** Display granularity; a switch re-anchors the chart at the newest bars. */\n granularity: 'step' | 'turn'\n onSelect: (seq: number | null) => void\n onHover: (seq: number | null) => void\n onHoverTurn: (turn: number | null) => void\n}\n\n/**\n * Collapse a per-step request timeline into one bar per turn: each turn is\n * represented by its LAST step's record (the context state when the turn\n * finished), tagged with the number of steps the turn spans so the bar can\n * keep the turn's column width and the detail can label it. Requests of one\n * turn are consecutive in the log, so a run of equal turns is replaced by\n * its final record.\n */\nexport function aggregateByTurn(requests: RequestRecord[]): RequestRecord[] {\n const out: RequestRecord[] = []\n let runSteps = 0\n for (const req of requests) {\n const last = out.length > 0 ? out[out.length - 1] : null\n if (last !== null && (last.turn ?? 0) === (req.turn ?? 0)) {\n runSteps++\n out[out.length - 1] = { ...req, stepCount: runSteps }\n } else {\n runSteps = 1\n out.push({ ...req, stepCount: 1 })\n }\n }\n return out\n}\n\n/**\n * Attach each boundary event (compaction/prune) to the first request\n * logged after it — one entry per request index, for the ✂ marker above\n * the bar and the range chip in the detail header. Shared by TrendChart\n * and the detail panel so both show the SAME event for a request.\n */\nexport function attachMarkers(requests: RequestRecord[], events: ContextEventRecord[]): (ContextEventRecord | undefined)[] {\n const markers: (ContextEventRecord | undefined)[] = new Array<ContextEventRecord | undefined>(requests.length)\n for (const ev of events) {\n if (ev.kind !== 'compaction' && ev.kind !== 'prune') continue\n for (let r = 0; r < requests.length; r++) {\n if (requests[r].seq >= ev.seq) {\n if (markers[r] === undefined) markers[r] = ev\n break\n }\n }\n }\n return markers\n}\n\nexport function makeTrendChart(kit: ViewKit): (props: TrendChartProps) => ReactNS.ReactElement {\n const { t, fmt, fmtTime, eventLabel, eventAt } = kit\n\n // Plot height in px (the marker lane above it is 18px).\n const CHART_H = 112\n // Fixed column geometry: constant bar width keeps sparse histories from\n // stretching bars, and dense histories scroll horizontally instead of\n // compressing. The turn strip below mirrors the same column grid.\n const BAR_W = 14\n const BAR_GAP = 2\n // Turn strip fills: a neutral zebra, deliberately DISJOINT from the\n // category palette — the strip sits directly under the bars, and the old\n // per-turn palette (identical to the six category colors) made it read as\n // a detached, misaligned bottom segment of the composition bars.\n const TURN_FILLS = ['rgba(128,128,128,0.12)', 'rgba(128,128,128,0.26)']\n\n return function TrendChart(props: TrendChartProps): ReactNS.ReactElement {\n const requests = props.requests\n const markers = props.markers\n // Anchor each bar to the provider-reported prompt size when the request\n // carried usage: the heuristic categories keep their ratios but the bar\n // HEIGHT tracks the real billed tokens (matching the overview card and\n // the official chat ring) instead of the underpriced raw estimate.\n const anchorOf = (req: RequestRecord): number =>\n typeof req.prompt === 'number' && req.prompt > 0 && req.total > 0 ? req.prompt / req.total : 1\n const barTotalOf = (req: RequestRecord): number =>\n typeof req.prompt === 'number' && req.prompt > 0 ? req.prompt : req.total\n let maxTotal = 1\n for (const req of requests) {\n const bt = barTotalOf(req)\n if (bt > maxTotal) maxTotal = bt\n }\n\n // Consecutive requests of the same turn collapse into one labeled range.\n // `span` is the number of STEP columns the group covers (step records\n // count one each). In turn granularity the bars are uniform width, so\n // the strip blocks are uniform too; in step granularity they span their\n // steps' columns. Either way bars and blocks stay aligned.\n const groups: { turn: number; count: number; span: number; agg: boolean }[] = []\n for (const req of requests) {\n let grp = groups.length > 0 ? groups[groups.length - 1] : null\n if (grp === null || grp.turn !== (req.turn ?? 0)) {\n grp = { turn: req.turn ?? 0, count: 0, span: 0, agg: req.stepCount !== undefined }\n groups.push(grp)\n }\n grp.count++\n grp.span += req.stepCount ?? 1\n }\n\n // Default anchor: the newest bars at the RIGHT edge. The first layout\n // after mount scrolls unconditionally; a GRANULARITY SWITCH re-anchors\n // the same way (returning to step mode must show the newest bars, not\n // the stale left edge from the narrow turn chart); otherwise the chart\n // only sticks to the end while the user is already near it (scrolling\n // away is respected). useLayoutEffect avoids a first-paint flash at the\n // left. Edge fades stay in sync with the scroll position.\n const scrollRef = React.useRef<HTMLDivElement | null>(null)\n const scrolledOnce = React.useRef(false)\n const lastGranRef = React.useRef(props.granularity)\n const [edges, setEdges] = React.useState<{ left: boolean; right: boolean }>({ left: false, right: false })\n // Mirror of the last computed fades. The layout effect below runs after\n // EVERY render (no deps), so it must not dispatch a setState unless the\n // values truly changed: on a granularity switch the first dispatch\n // schedules a sync re-render whose fiber still has pending lanes, which\n // disables React's same-value eager bailout — every subsequent commit\n // then enqueues yet another update and the queue grows without bound\n // (React error #185, maximum update depth — the tab whites out).\n const edgesRef = React.useRef(edges)\n const updateEdges = (el: HTMLDivElement): void => {\n const left = el.scrollLeft > 4\n const right = el.scrollLeft + el.clientWidth < el.scrollWidth - 4\n const prev = edgesRef.current\n if (prev.left === left && prev.right === right) return\n edgesRef.current = { left, right }\n setEdges({ left, right })\n }\n React.useLayoutEffect(() => {\n const el = scrollRef.current\n if (el === null) return\n if (props.granularity !== lastGranRef.current) {\n lastGranRef.current = props.granularity\n scrolledOnce.current = false // re-anchor on every granularity switch\n }\n if (!scrolledOnce.current) {\n scrolledOnce.current = true\n el.scrollLeft = el.scrollWidth\n } else if (el.scrollLeft + el.clientWidth >= el.scrollWidth - 24) {\n el.scrollLeft = el.scrollWidth\n }\n updateEdges(el)\n })\n\n // Compact single-line hover tooltip (shown instantly by the custom\n // `.lc-chart-tip`, replacing the delayed native title): position, time,\n // estimated total, and the provider-reported prompt when available. The\n // per-category breakdown lives in the detail panel below.\n const tipOf = (req: RequestRecord): string => {\n const head = req.stepCount !== undefined && req.stepCount > 1\n ? t('tip.turn', { t: req.turn ?? 0, n: req.stepCount })\n : t('tip.step', { t: req.turn ?? 0, s: req.step ?? 0 })\n return head + ' · ' + fmtTime(req.time) + ' · ' + t('tip.total', { n: fmt(req.total) })\n + (req.prompt !== undefined ? ' · ' + t('tip.actual', { n: fmt(req.prompt) }) : '')\n }\n const hoveredIdx = props.hoveredSeq !== null ? requests.findIndex(r => r.seq === props.hoveredSeq) : -1\n const hoveredReq = hoveredIdx >= 0 ? requests[hoveredIdx] : null\n\n return (\n <div className=\"lc-chartrow\">\n <div className=\"lc-axis\">\n <span className=\"lc-axis-top\">{fmt(maxTotal)}</span>\n <span className=\"lc-axis-mid\">{fmt(Math.round(maxTotal / 2))}</span>\n <span className=\"lc-axis-bot\">{'0'}</span>\n </div>\n <div\n // Turn-aware dim scope: while a turn is focused (bar or strip hover),\n // bars and strip blocks OUTSIDE the active turn fade to 35%.\n className={'lc-chart-scroll' + (props.activeTurn !== null ? ' lc-chart-dim' : '')}\n ref={scrollRef}\n onScroll={(e: ReactNS.UIEvent<HTMLDivElement>) => { updateEdges(e.currentTarget) }}\n >\n {/* Edge fades: visible whenever more history sits beyond the viewport,\n so the horizontal scroll affordance is obvious. */}\n {edges.left ? <div className=\"lc-chart-fade lc-chart-fade-l\" /> : null}\n {/* Hovering a bar previews it in the detail below; leaving the plot\n clears the preview (a pinned selection, if any, takes over again). */}\n <div\n className=\"lc-chart\"\n onMouseLeave={() => { props.onHover(null) }}\n >\n <div className=\"lc-grid lc-grid-top\" />\n <div className=\"lc-grid lc-grid-mid\" />\n {requests.map((req, i) => {\n const marker = markers[i]\n const markerAt = marker !== undefined ? eventAt(marker) : null\n const selected = props.selectedSeq === req.seq\n const hovered = props.hoveredSeq === req.seq\n const inTurn = props.activeTurn !== null && (req.turn ?? 0) === props.activeTurn\n return (\n <div\n key={req.seq}\n // Uniform column width in BOTH granularities: turn aggregates\n // keep the same fixed width as step bars.\n className={'lc-bar'\n + (selected ? ' lc-bar-selected' : '')\n + (hovered ? ' lc-bar-hovered' : '')\n + (inTurn ? ' lc-bar-in-turn' : '')}\n style={{ width: `${BAR_W}px` }}\n onClick={() => { props.onSelect(selected ? null : req.seq) }}\n onMouseEnter={() => { props.onHover(req.seq) }}\n >\n {/* The ✂ tooltip names the event AND where it happened: the\n gap between the request before and the request after. */}\n {marker !== undefined ? (\n <span\n className=\"lc-bar-marker\"\n title={'✂ ' + (markerAt !== null ? markerAt + ' — ' : '') + eventLabel(marker)}\n >{'✂'}</span>\n ) : null}\n <div className=\"lc-bar-stack\">\n {CATS.map((c) => {\n const v = (req[c.key] || 0) * anchorOf(req)\n if (!v) return null\n // px heights: the stack's height is content-driven, so\n // percentage heights would collapse against an indefinite base.\n return <div key={c.key} style={{ height: `${Math.max(1, Math.round(v / maxTotal * CHART_H))}px`, background: c.color }} />\n })}\n </div>\n </div>\n )\n })}\n </div>\n {/* Instant hover tooltip, glued to its bar's column (it lives in the\n scrolling content, so it follows the bar while the chart scrolls). */}\n {hoveredReq !== null ? (\n <div\n className=\"lc-chart-tip\"\n style={{ left: `${hoveredIdx * (BAR_W + BAR_GAP) + BAR_W / 2}px` }}\n >{tipOf(hoveredReq)}</div>\n ) : null}\n {/* Turn strip: one COLOR BLOCK per turn, spanning exactly its bars'\n columns, so the partition reads at a glance and lines up with the\n steps above. Hovering a block highlights that turn's bars in the\n chart (and hovering a bar highlights its block — the active turn\n is shared hover-only state). */}\n <div className=\"lc-turns\" onMouseLeave={() => { props.onHoverTurn(null) }}>\n {groups.map((grp, gi) => {\n // Turn mode: uniform blocks under uniform bars (1:1). Step mode:\n // blocks span their steps' columns. The flex gap between blocks\n // mirrors the bar gap, so blocks always line up with the bars.\n const on = props.activeTurn === grp.turn\n const blockW = grp.agg ? BAR_W : grp.span * (BAR_W + BAR_GAP) - BAR_GAP\n return (\n <span\n key={`turn-${gi}`}\n className={'lc-turn' + (on ? ' lc-turn-on' : '')}\n style={{\n width: `${blockW}px`,\n background: TURN_FILLS[gi % TURN_FILLS.length],\n }}\n title={`T${grp.turn}`}\n onMouseEnter={() => { props.onHoverTurn(grp.turn) }}\n >{`T${grp.turn}`}</span>\n )\n })}\n </div>\n </div>\n {edges.right ? <div className=\"lc-chart-fade lc-chart-fade-r\" /> : null}\n </div>\n )\n }\n}\n","/**\n * ContextView — the root component of the Context tab: renders the\n * `contextTimeline` session projection delivered by the framework (finished\n * value, pushed by the Host half) and composes the stats board, composition\n * bar, history chart + detail, events and message columns.\n *\n * JSX functional component. All data comes through the framework standard\n * kit (`useProjection`); the component never calls any RPC and holds no\n * cache — the harness owns the projection pipeline end to end.\n */\n\nimport type * as ReactNS from 'react'\nimport type { ContextEventRecord, RequestRecord } from '../../shared/types'\nimport { headlineOf } from '../headline'\nimport type { SessionStandardProps } from '../services'\nimport { contextPressureOf, headersOf, timelineOf, tokenUsageOf } from '../services'\nimport type { ClientCtx, ConversationFace, ImageRefLike } from '../services'\nimport type { ViewKit } from '../viewkit'\nimport { makeContextBrowser } from './browser'\nimport { makeCurrentComposition } from './currentComposition'\nimport { makeEventList } from './events'\nimport { makeNodeList } from './nodes'\nimport { makePluginInfo } from './pluginInfo'\nimport { makeRequestDetail } from './requestDetail'\nimport { makeStatsBoard } from './statsBoard'\nimport { makeLegend, makeStackedBar } from './stackedBar'\nimport { aggregateByTurn, attachMarkers, makeTrendChart } from './trendChart'\n\nimport { React, h } from '../react'\nimport { makeErrorBoundary } from './errorBoundary'\n\n// The context page scrolls inside the conversation's shared page scroller\n// (`[data-conversation-scroll]`) — the same container the chat auto-scrolls\n// to the bottom on every visit. Without a position ledger of its own, a\n// context mount inherits wherever the chat left that container, so the tab\n// opens at the bottom and stays locked there (each chat visit re-scrolls it).\n// Mirror the chat's chatScroll pattern: remember where the reader left each\n// session's context page (module-level, so it survives tab remounts) and\n// restore it once the content renders — first visits start at the top.\nconst viewScroll = new Map<string, number>()\n\n// The four event kinds, in display order (toggles + filter share the list).\nconst EVENT_KINDS = ['inject', 'compaction', 'prune', 'model'] as const\n\nexport type ContextViewProps = SessionStandardProps\n\nexport function makeContextView(ctx: ClientCtx, kit: ViewKit): (props: ContextViewProps) => ReactNS.ReactElement {\n const { t } = kit\n const StackedBar = makeStackedBar(kit)\n const Legend = makeLegend(kit)\n const CurrentComposition = makeCurrentComposition(kit, StackedBar, Legend)\n const TrendChart = makeTrendChart(kit)\n const RequestDetail = makeRequestDetail(kit, StackedBar)\n const EventList = makeEventList(kit)\n const NodeList = makeNodeList(kit)\n const StatsBoard = makeStatsBoard(kit)\n const PluginInfo = makePluginInfo(kit)\n const ContextBrowser = makeContextBrowser(kit, StackedBar)\n const ErrorBoundary = makeErrorBoundary(t)\n\n // The data-driven body lives inside the error boundary: any render error\n // (a corrupt projection value that slips past the timelineOf shape guard,\n // a framework surprise) degrades to a styled error card inside the tab\n // instead of white-screening the whole conversation view. The boundary is\n // a separate component with NO hooks of its own, so the body's hook order\n // and the loading/data control flow stay exactly as they were.\n function ContextViewBody(props: ContextViewProps): ReactNS.ReactElement {\n const sessionId = props.sessionId\n // The finished value the harness pushes for this session: the\n // `contextTimeline` projection key (capability-absent until a value\n // arrives -> loading screen, mirroring the old first-poll wait).\n const data = typeof props.useProjection === 'function'\n ? timelineOf(props.useProjection('contextTimeline'))\n : null\n // Provider-anchored occupancy comes from the OFFICIAL token-meter\n // `contextPressure` projection (the same key the chat's context ring\n // reads) — token-meter owns estimation and replay, the Host no longer\n // mirrors it. Absent key/value degrades to the derived fallback.\n const pressure = typeof props.useProjection === 'function'\n ? contextPressureOf(props.useProjection('contextPressure'))\n : null\n // Durable provider-reported usage comes from the OFFICIAL token-meter\n // `tokenUsage` projection — the exact same data the chat stats line below\n // the input box reads for its \"缓存命中\" figure, so the stats board's\n // cache-hit cell reuses it verbatim. Absent key/value drops the cell to a\n // dash instead of estimating.\n const usage = typeof props.useProjection === 'function'\n ? tokenUsageOf(props.useProjection('tokenUsage'))\n : null\n // The header-content companion projection (full system prompt + tool\n // schemas) for the Context browser card; absent key = older Host half,\n // the card degrades those sections to tokens-only with a note.\n const headers = typeof props.useProjection === 'function'\n ? headersOf(props.useProjection('contextHeaders'))\n : null\n const [selectedSeq, setSelectedSeq] = React.useState<number | null>(null)\n const [hoveredSeq, setHoveredSeq] = React.useState<number | null>(null)\n const [hoverTurn, setHoverTurn] = React.useState<number | null>(null)\n const [tick, setTick] = React.useState(0)\n const [granularity, setGranularity] = React.useState<'step' | 'turn'>('step')\n // Shared hover link between the composition bar and its legend below.\n const [hoverCat, setHoverCat] = React.useState<string | null>(null)\n // Kind picker for the events column, every kind picked by default (all\n // shown). Clicking an unpicked kind adds it (A -> A+B -> ...); clicking\n // the only remaining picked kind resets to all; clicking a picked kind\n // among several removes it.\n const [pickedKinds, setPickedKinds] = React.useState<string[]>([...EVENT_KINDS])\n const toggleKind = (k: string) => {\n setPickedKinds((p) => {\n // All picked -> narrow to this kind only (that's the \"点击后只显示该分类\" entry).\n if (p.length === EVENT_KINDS.length) return [k]\n // Unpicked -> add it (A -> A+B -> ...).\n if (!p.includes(k)) return [...p, k]\n // Picked -> remove it; removing the last one resets to all.\n return p.length === 1 ? [...EVENT_KINDS] : p.filter(x => x !== k)\n })\n }\n // Tool-link bridge to the Context browser: clicking the overview's\n // \"工具定义 Top\" label (category focus) or one of its chips (specific\n // tool focus) asks the browser to reveal the corresponding section.\n // One-shot — the browser applies it and clears it back through\n // `onToolFocusHandled`, so clicking the same chip again re-triggers.\n const [toolFocus, setToolFocus] = React.useState<{ tool?: string } | null>(null)\n const clearToolFocus = React.useCallback(() => { setToolFocus(null) }, [])\n\n // Session-authorized durable-image loader for the Context browser's\n // attachment cards, resolved through the harness conversation service —\n // the same `resolveImage` the chat history's message images ride on.\n // Absent service (or a missing session id) degrades the cards to\n // metadata-only, never an error.\n const loadImage = React.useMemo(() => {\n if (typeof sessionId !== 'string' || sessionId === '') return undefined\n const conversation = ctx.get('conversation') as ConversationFace | undefined\n if (conversation === undefined || typeof conversation.resolveImage !== 'function') return undefined\n return (attachment: ImageRefLike) => conversation.resolveImage(sessionId, attachment)\n }, [sessionId])\n\n // ---- page-scroller ownership (see `viewScroll` above) ----\n const rootRef = React.useRef<HTMLDivElement | null>(null)\n const scrollerRef = React.useRef<HTMLElement | null>(null)\n // The session whose position was already applied this mount: re-renders\n // must never re-apply, or they would yank the reader's scroll.\n const restoredRef = React.useRef<string | null>(null)\n\n // Restore this session's saved position (or the top on a first visit) as\n // soon as the content renders — a layout effect, so the reader never sees\n // the chat's bottom-anchored position flash in first.\n React.useLayoutEffect(() => {\n if (typeof sessionId !== 'string' || sessionId === '' || data === null) return\n if (restoredRef.current === sessionId) return\n restoredRef.current = sessionId\n const scroller = rootRef.current !== null\n ? rootRef.current.closest('[data-conversation-scroll]')\n : null\n if (scroller === null) return\n scrollerRef.current = scroller as HTMLElement\n scroller.scrollTop = viewScroll.get(sessionId) ?? 0\n }, [sessionId, data])\n\n // Save where the reader left this session's context page. Runs on unmount\n // (tab switch) and on session change — a layout-effect cleanup, so it\n // fires before the incoming view's own layout effects re-scroll the\n // shared container.\n React.useLayoutEffect(() => {\n return () => {\n if (typeof sessionId !== 'string' || sessionId === '') return\n const scroller = scrollerRef.current\n if (scroller === null) return\n viewScroll.set(sessionId, scroller.scrollTop)\n }\n }, [sessionId])\n\n // Re-render on locale switch.\n React.useEffect(() => {\n const localeSvc = ctx.get('locale')\n if (!localeSvc) return undefined\n return localeSvc.subscribe(() => { setTick(x => x + 1) })\n }, [])\n\n void tick\n\n if (!data) {\n return <div className=\"lc-root\" ref={rootRef}><div className=\"lc-empty\">{t('loading')}</div></div>\n }\n\n const requests = data.requests\n const events = data.events\n // The events column filters to the picked kinds (all picked = all shown);\n // the stats board keeps the full log regardless.\n const shownEvents = pickedKinds.length === EVENT_KINDS.length ? events : events.filter(e => pickedKinds.includes(e.kind))\n const nodes = data.nodes\n // Display granularity: one bar per step (default) or one bar per turn\n // (each turn shown by its LAST step's record).\n const displayRequests = granularity === 'turn' ? aggregateByTurn(requests) : requests\n // Boundary events attach to the first request after them; the same\n // attachment drives the ✂ marker above the bar and the detail chip.\n const markers = attachMarkers(displayRequests, events)\n const markerOf = (req: RequestRecord): ContextEventRecord | undefined => {\n const i = displayRequests.indexOf(req)\n return i >= 0 ? markers[i] : undefined\n }\n\n // The detail below follows the pointer: hover previews a bar, a pinned\n // click takes over when the pointer leaves, and both fall back to the\n // newest request. The active turn (for strip/bar highlighting) follows\n // the turn strip hover, or the hovered bar's turn.\n let pinnedReq: RequestRecord | null = null\n for (const req of displayRequests) if (req.seq === selectedSeq) pinnedReq = req\n let activeReq: RequestRecord | null = null\n if (hoveredSeq !== null) {\n for (const req of displayRequests) if (req.seq === hoveredSeq) activeReq = req\n }\n if (activeReq === null) activeReq = pinnedReq\n if (activeReq === null && displayRequests.length > 0) activeReq = displayRequests[displayRequests.length - 1]\n\n // The turn highlight is hover-only: the turn strip hover wins, then the\n // hovered bar's turn (no fallback — a pinned or default selection must\n // not keep a turn glowing).\n let activeTurn: number | null = hoverTurn\n if (activeTurn === null && hoveredSeq !== null) {\n for (const req of displayRequests) if (req.seq === hoveredSeq) { activeTurn = req.turn ?? null; break }\n }\n\n // Provider-anchored CURRENT occupancy from the official chat ring\n // (contextPressure.projectedTokens): the newest usage sample (input +\n // cache) carried forward by the heuristic surface movement since it was\n // taken. The provider's tokenizer counts the real billed tokens, which\n // the fixed 4-chars/token heuristic can undercount by ~10-15% on\n // CJK-heavy sessions — so this is the headline, and the heuristic\n // composition below is anchored to it (proportions stay heuristic).\n // Shared with the /context popup (headline.ts).\n const head = headlineOf(data, pressure)\n\n // The cost cell prices in the locale's currency (zh -> CNY, else USD);\n // read the active locale at render time — the locale subscription above\n // already re-renders on a switch. Older hosts without getLocale fall\n // back to USD.\n const localeSvc = ctx.get('locale')\n const activeLocale = localeSvc !== undefined && typeof localeSvc.getLocale === 'function'\n ? localeSvc.getLocale().active\n : 'en'\n\n return (\n <div className=\"lc-root\" ref={rootRef}>\n\n {/* ---- session context stats + plugin info, side by side (7 : 3) ---- */}\n <div className=\"lc-cols lc-head\">\n <StatsBoard requests={requests} events={events} usage={usage} cost={data.cost} locale={activeLocale} />\n <PluginInfo />\n </div>\n\n {/* ---- main split: overview + trend stacked in the left column,\n the context browser in the right column (shared lc-cols flex,\n wraps to one column on narrow widths) ---- */}\n <div className=\"lc-cols\">\n <div className=\"lc-col\">\n {/* ---- overview (shared CurrentComposition card) ---- */}\n <CurrentComposition\n head={head}\n subtitle={(data.model ? data.model : '') + (data.provider ? ' · ' + data.provider : '')}\n hoverKey={hoverCat}\n onHoverKey={setHoverCat}\n tools={data.toolList}\n onToolFocus={setToolFocus}\n />\n\n {/* ---- trend ---- */}\n <div className=\"lc-card\">\n <div className=\"lc-card-title\">\n <span className=\"lc-card-title-text\">{t('trend.title')}</span>\n <span className=\"lc-card-sub\">{t('trend.hint')}</span>\n <div className=\"lc-gran\">\n <button\n className={'lc-gran-btn' + (granularity === 'step' ? ' lc-gran-on' : '')}\n onClick={() => { setGranularity('step') }}\n >{t('gran.step')}</button>\n <button\n className={'lc-gran-btn' + (granularity === 'turn' ? ' lc-gran-on' : '')}\n onClick={() => { setGranularity('turn') }}\n >{t('gran.turn')}</button>\n </div>\n </div>\n {displayRequests.length === 0\n ? <div className=\"lc-empty\">{t('trend.empty')}</div>\n : (\n <div>\n <TrendChart\n // Remount per session: switching sessions re-anchors the chart\n // at the newest bars instead of inheriting stale scroll state.\n key={sessionId}\n // The host caps the log at 160 requests; render them ALL so\n // earlier turns/steps stay reachable via horizontal scroll.\n requests={displayRequests}\n markers={markers}\n selectedSeq={pinnedReq ? pinnedReq.seq : null}\n hoveredSeq={hoveredSeq}\n activeTurn={activeTurn}\n granularity={granularity}\n onSelect={setSelectedSeq}\n onHover={setHoveredSeq}\n onHoverTurn={setHoverTurn}\n />\n <RequestDetail request={activeReq} marker={activeReq !== null ? markerOf(activeReq) : undefined} />\n </div>\n )}\n </div>\n </div>\n\n {/* ---- context browser: the assembled content of the live surface\n or a picked step; follows the trend chart's hovered bar ---- */}\n <div className=\"lc-col\">\n <ContextBrowser\n data={data}\n headers={headers}\n useSession={props.useSession}\n loadOlderHistory={props.loadOlderHistory}\n previewSeq={hoveredSeq}\n // History-chart pin linkage: a clicked (locked) bar pins the\n // browser on that step; unpinning returns it to live.\n pinSeq={pinnedReq !== null ? pinnedReq.seq : null}\n // Shared current-composition hover link (bar + legend + browser\n // category rows); the browser joins only while it shows the\n // live step, gated inside the browser itself.\n hoverKey={hoverCat}\n onHoverKey={setHoverCat}\n // Tool-link bridge from the overview (\"工具定义 Top\" chips).\n toolFocus={toolFocus}\n onToolFocusHandled={clearToolFocus}\n loadImage={loadImage}\n />\n </div>\n </div>\n\n {/* ---- events + messages ---- */}\n <div className=\"lc-cols\">\n <div className=\"lc-card lc-col\">\n <div className=\"lc-card-title\">\n <span className=\"lc-card-title-text\">{t('events.title')}</span>\n <div className=\"lc-kinds\">\n {EVENT_KINDS.map(k => (\n <button\n key={k}\n className={'lc-gran-btn' + (pickedKinds.includes(k) ? ' lc-gran-on lc-kind-' + k : '')}\n onClick={() => { toggleKind(k) }}\n >{t('kind.' + k)}</button>\n ))}\n </div>\n </div>\n <EventList events={shownEvents} />\n </div>\n <div className=\"lc-card lc-col\">\n <div className=\"lc-card-title\">\n <span className=\"lc-card-title-text\">{t('nodes.title')}</span>\n <span className=\"lc-card-sub\">{t('nodes.hint')}</span>\n </div>\n <NodeList nodes={nodes} dropped={data.droppedNodes || 0} />\n </div>\n </div>\n\n <div className=\"lc-foot\">{t('footer')}</div>\n </div>\n )\n }\n\n return function ContextView(props: ContextViewProps): ReactNS.ReactElement {\n // The whole body — hooks, projection reads, derivation, and all child\n // cards — renders under the boundary (see ContextViewBody above).\n return h(ErrorBoundary, null, h(ContextViewBody, props))\n }\n}\n","/**\n * ViewKit — the shared dependency bag every component factory receives.\n * Built once per `makeView` (i.e. once per plugin apply): translation\n * (bound to the active locale), formatters, category labels, and the event\n * text helpers (event label + boundary range) that several components use.\n */\n\nimport type { ContextEventRecord } from '../shared/types'\nimport { fmt, fmtTime } from './format'\nimport { makeEventText } from './components/events'\nimport type { Translate } from './i18n'\n\nexport interface ViewKit {\n t: Translate\n fmt: typeof fmt\n fmtTime: typeof fmtTime\n catLabel: (key: string) => string\n eventLabel: (ev: ContextEventRecord) => string\n /** Where the event sits in the request timeline, as a label or null. */\n eventAt: (ev: ContextEventRecord) => string | null\n}\n\nexport function makeViewKit(t: Translate): ViewKit {\n const { eventLabel, eventAt } = makeEventText(t)\n return {\n t,\n fmt,\n fmtTime,\n catLabel: (key: string) => t('cat.' + key),\n eventLabel,\n eventAt,\n }\n}\n","/**\n * dsh-context — Client half (installed package bundle entry).\n *\n * Registers a \"上下文/Context\" tab in the conversation view ring\n * (`conversation.view` slot, beside Chat/Trajectory) and renders the\n * context-composition timeline: current makeup, per-request stacked-bar\n * history, context events, and the live message list.\n *\n * Since v0.9 the tab needs no custom data plane: the Host half pushes its\n * fold through the harness's session-projection pipeline\n * (`contextTimeline` projection key), and this half reads the finished value\n * from the framework standard kit (`useProjection('contextTimeline')`, a\n * standard prop on every session-scope slot component). No polling, no RPC,\n * no client-side cache.\n *\n * This module is the body of the package's `./client` bundle: tsdown\n * (tsdown.config.ts) bundles it (external `react` — the browser module table\n * supplies it via the injected `require`) into the web boot handoff\n * (`window.__ModuleLoader__.load({id, factory})`). All imports from other\n * client modules are inlined by the bundler; everything here is zero-runtime\n * beyond the bundled source.\n */\n\nimport { DICT_EN, DICT_ZH } from './i18n'\nimport { registerContextCommand } from './command'\nimport { makeContextModal } from './components/contextModal'\nimport { modalStoreOf } from './modalStore'\nimport type { ClientCtx, SessionsFace } from './services'\nimport { makeContextView } from './components/contextView'\nimport { makeViewKit } from './viewkit'\n\n// Theme-native styles: the bundle's global-CSS channel injects the sheet as\n// a plugin-owned <style data-plugin> tag at factory execution (the web boot\n// loader and the HMR receiver claim tags carrying data-plugin).\nimport './styles.css'\n\nimport { h } from './react'\n\nconst NS = 'dsh-context'\n\nfunction apply(ctx: ClientCtx): void {\n // Bilingual dictionaries; the tab label thunk and all UI text follow the\n // active locale through the bound translate (missing keys fall back to\n // zh, then the key itself). The registration rides ctx.effect, so a stop\n // or HMR reload disposes it.\n ctx.effect(() => {\n return ctx.locale.register(NS, { zh: DICT_ZH, en: DICT_EN })\n }, 'dsh-context: dictionaries')\n const t = ctx.locale.bind(NS)\n\n const kit = makeViewKit(t)\n const ContextView = makeContextView(ctx, kit)\n\n // Contribute the history-pagination verb as a standard prop, so the\n // Context browser can pull older conversation pages on demand when the\n // reader expands an element outside the loaded window. Fail-soft: hosts\n // without the provide channel (or a duplicate-name refusal) keep the\n // preview-plus-hint degradation.\n ctx.effect(() => {\n const noop = (): void => {}\n const sessions = ctx.get('sessions') as SessionsFace | undefined\n if (sessions === undefined || typeof sessions.provide !== 'function') return noop\n try {\n return sessions.provide({\n props: ['loadOlderHistory'],\n resolve: binding => ({ props: { loadOlderHistory: () => binding.session.loadOlder() } }),\n })\n } catch {\n return noop\n }\n }, 'dsh-context: loadOlderHistory prop')\n\n ctx.slots.inject('conversation.view', () => {\n return ctx.slots.register(\n // order 20 renders right of Chat (0) and Trajectory (10); the locale\n // namespace put the framework `t` seat on the component's props too.\n { name: 'conversation.view', id: 'context', order: 20, locale: NS, label: () => t('tab') },\n props => h(ContextView, props),\n )\n })\n\n // `/context` slash command: opens the context modal (see command.ts for\n // the trigger source). The modal itself renders from the input overlay\n // slot, opened per session through the hooks-compartment store.\n registerContextCommand(ctx, kit)\n const ContextModal = makeContextModal(ctx, kit)\n ctx.slots.inject('conversation.input.overlay', () => {\n return ctx.slots.register(\n { name: 'conversation.input.overlay', id: 'context-modal', order: 10, locale: NS,\n inject: (sessionId: string) => ({ hooks: { contextModal: modalStoreOf(sessionId) } }) },\n props => h(ContextModal, props),\n )\n })\n}\n\nmodule.exports = {\n name: 'dsh-context',\n inject: ['slots', 'locale'],\n apply,\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"client.js","names":["MarkdownText","IconPlusOutline16","IconBranchOutline16"],"sources":["../src/client/i18n.ts","../src/client/modalStore.ts","../src/client/command.ts","../src/client/categories.ts","../src/client/headline.ts","../src/client/services.ts","../src/client/assemble.ts","../src/client/react.ts","../src/client/components/nodes.tsx","../src/client/format.ts","../src/client/components/images.tsx","../src/client/components/richText.tsx","../src/client/components/browser.tsx","../src/client/components/stackedBar.tsx","../src/client/components/currentComposition.tsx","../src/client/components/errorBoundary.tsx","../src/client/components/contextModal.tsx","../src/client/components/events.tsx","../src/client/meta.ts","../src/client/latestVersion.ts","../src/client/components/pluginInfo.tsx","../src/client/components/requestDetail.tsx","../src/client/cost.ts","../src/client/components/statsBoard.tsx","../src/client/components/trendChart.tsx","../src/client/components/contextView.tsx","../src/client/viewkit.ts","../src/client/index.ts"],"sourcesContent":["/**\n * Bilingual dictionaries (zh/en) for every UI string. Missing keys fall back\n * to zh, then the key itself (handled by the harness locale service).\n */\n\nexport type Translate = (key: string, params?: Record<string, string | number>) => string\n\nexport const DICT_ZH: Record<string, string> = {\n 'tab': '上下文',\n 'cat.system': '系统提示词', 'cat.tools': '工具定义', 'cat.user': '用户消息',\n 'cat.inject': '注入内容', 'cat.assistant': '助手消息', 'cat.tool': '工具结果',\n 'overview.title': '当前构成',\n 'overview.estimate': 'tokens(估算)',\n 'overview.free': '剩余窗口',\n 'overview.used': '上下文已用',\n 'overview.ofUsed': '占已用上下文',\n 'overview.compactReserve': '自动压缩预留:占用达 {pct}% 窗口时触发压缩,此区域一般不实际占用',\n 'stats.title': '上下文统计',\n 'stats.hint': '统计当前保留的历史窗口(与趋势图一致)',\n 'stats.turns': '轮次', 'stats.steps': '步数',\n 'stats.injects': '注入',\n 'stats.compactions': '压缩',\n 'stats.prunes': '剪枝',\n 'stats.cacheHit': '缓存命中',\n 'stats.cost': '预估费用',\n 'stats.costTip': '按 DeepSeek 官方刊例价估算整个会话的累计费用:输入区分缓存命中/未命中,输出含思考;按请求时间区分高峰(UTC 01:00–04:00、06:00–10:00)与空闲时段(半价)。适用于 deepseek-v4-flash / deepseek-v4-pro(不限 provider),价格写死在代码中,仅供参考。',\n 'stats.costPriceHead': '每百万 tokens 价格(高峰 | 空闲半价):',\n 'stats.costHit': '命中', 'stats.costMiss': '未命中', 'stats.costOut': '输出',\n 'plugin.title': '插件信息',\n 'plugin.hint': 'The best DSH context plugin ⭐',\n 'plugin.name': '插件',\n 'plugin.github': 'GitHub',\n 'tools.top': '工具定义 Top:',\n 'tools.more': '等 {n} 个',\n 'trend.title': '历史趋势',\n 'gran.step': '步骤', 'gran.turn': '轮次',\n 'trend.hint': '悬停查看详情,✂ 表示压缩/剪枝,Step/Turn 切换粒度',\n 'trend.empty': '发起一轮对话后,这里会展示每次模型请求的上下文构成',\n 'detail.step': '第 {t} 轮 · 第 {s} 步',\n 'detail.turn': '第 {t} 轮 · 共 {n} 步',\n 'detail.lastStep': '末步',\n 'detail.estTotal': '估算合计 ≈ {n}',\n 'detail.actual': '实际 prompt {n}',\n 'detail.output': '输出 {n}',\n 'events.title': '上下文事件',\n 'events.empty': '暂无上下文事件(压缩、注入、模型切换会出现在这里)',\n 'events.at': '第 {t} 轮 · 第 {s} 步',\n 'events.range': '第 {t} 轮 · 第 {a}→{b} 步',\n 'events.rangeTo': '第 {a} 轮 · 第 {as} 步 → 第 {b} 轮 · 第 {bs} 步',\n 'kind.inject': '注入', 'kind.compaction': '压缩', 'kind.prune': '剪枝', 'kind.model': '切换',\n 'nodes.title': '消息构成',\n 'nodes.hint': '当前模型可见的消息,最新在前',\n 'nodes.more': '… 更早的 {n} 条消息已省略',\n 'nodes.empty': '当前没有模型可见的消息',\n 'loading': '正在读取会话日志…',\n 'error': '上下文数据读取失败:',\n 'error.retry': '重试',\n 'footer': '估算口径:与 dsh 内置 tokenMeter 相同的固定密度启发式(约 4 字符 ≈ 1 token);「实际」为供应商上报用量。',\n 'tip.step': '第 {t} 轮 · 第{s}步',\n 'tip.turn': '第 {t} 轮 · 共 {n} 步',\n 'tip.total': '合计 ≈ {n}',\n 'tip.actual': '(实际 {n})',\n 'ev.compaction': '压缩上下文(摘要替换 {n} 条消息)',\n 'ev.prune': '剪枝工具输出',\n 'ev.skill': 'Skill 注入({name})',\n 'ev.model': '模型切换:{a} → {b}',\n 'form.instructions': '指令注入', 'form.catalog': '目录更新', 'form.snapshot': '状态快照',\n 'form.notice': '通知', 'form.relay': '代理转发', 'form.recall': '历史召回', 'form.context': '上下文注入',\n 'node.toolResult': '工具结果',\n 'node.calls': '调用 ',\n 'node.empty': '(空回复)',\n 'node.nonText': '(非文本消息)',\n 'node.snapshot': '快照: ',\n 'cmd.desc': '查看当前上下文构成,浏览各步骤组成',\n 'cmd.close': '关闭',\n 'browser.title': '上下文浏览器',\n 'browser.live': '当前(下一次请求)',\n 'browser.liveNow': '当前 · 下一次请求',\n 'browser.items': '{n} 项',\n 'browser.missingLive': '… 另有 {n} 条更早的消息也在上下文中(超出展示窗口)',\n 'browser.approx': '该步骤涉及的部分已移除消息超出保留范围,以下为近似构成',\n 'browser.deltaHint': '对比上轮末步的变动',\n 'browser.noHeader': '此数据来自旧版插件:仅提供 token 估算,无实际内容',\n 'browser.noEpoch': '该步骤的头部内容(系统提示词 / 工具定义)不在保留范围内',\n 'browser.noContent': '完整内容不在当前加载的消息窗口内(在聊天页加载更早历史后可查看)',\n 'browser.loading': '正在从更早的会话历史加载完整内容…',\n 'browser.preview': '预览',\n // Tool schema browser card: parsed parameter table sits above the (collapsed\n // by default) raw JSON so the common case — skimming arguments — stays\n // scannable; the JSON is still one click away for the full payload.\n 'tool.desc': '描述',\n 'tool.params': '参数',\n 'tool.paramsEmpty': '(无参数)',\n 'tool.jsonToggle': '查看原始 JSON',\n 'tool.jsonHide': '收起',\n // Detail-card view switch (system prompt / tool description / message and\n // injection bodies): a segmented pill — segment labels + tooltips.\n 'rich.raw': '原文',\n 'rich.md': 'Markdown',\n 'rich.toMd': '按 Markdown 渲染查看',\n 'rich.toRaw': '查看原始文本',\n // Assistant-message block titles inside the detail card: the reasoning\n // trace and the response each carry a small label (Reasoning / Response,\n // mirroring the harness's own block + locale vocabulary).\n 'block.thinking': '思考',\n 'block.answer': '回答',\n // Attachment cards in a message detail: image refs render as thumbnail\n // cards (name + normalized dims + stored size), anything unrecognized\n // falls into the generic raw-JSON card.\n 'attach.images': '图片附件',\n 'attach.other': '其他内容',\n 'attach.image': '图片',\n 'attach.open': '查看原图',\n 'attach.loading': '…',\n 'attach.loadFailed': '加载失败 · 点击重试',\n 'attach.orig': '原图 {d}',\n}\n\nexport const DICT_EN: Record<string, string> = {\n 'tab': 'Context',\n 'cat.system': 'System Prompt', 'cat.tools': 'Tool Schemas', 'cat.user': 'User Messages',\n 'cat.inject': 'Injected Context', 'cat.assistant': 'Assistant Messages', 'cat.tool': 'Tool Results',\n 'overview.title': 'Current Context',\n 'overview.estimate': 'tokens (estimated)',\n 'overview.free': 'Free Window',\n 'overview.used': 'of context used',\n 'overview.ofUsed': 'of used context',\n 'overview.compactReserve': 'Auto-compaction reserve: auto-compaction triggers at {pct}% of the window — this area is normally kept as headroom, not actually used',\n 'stats.title': 'Context Stats',\n 'stats.hint': 'Over the retained history window (same as the History chart)',\n 'stats.turns': 'Turns', 'stats.steps': 'Steps',\n 'stats.injects': 'Injections',\n 'stats.compactions': 'Compactions',\n 'stats.prunes': 'Prunes',\n 'stats.cacheHit': 'Cache Hits',\n 'stats.cost': 'Est. Cost',\n 'stats.costTip': 'Rough cumulative cost of the whole session at DeepSeek’s list prices: input split by cache hit/miss, output includes reasoning; each request is priced at the peak (01:00–04:00, 06:00–10:00 UTC) or half-price off-peak rate by its time. Applies to deepseek-v4-flash / deepseek-v4-pro on any provider; prices are hardcoded, for reference only.',\n 'stats.costPriceHead': 'Per-1M-token rates (peak | off-peak at half price):',\n 'stats.costHit': 'hit', 'stats.costMiss': 'miss', 'stats.costOut': 'output',\n 'plugin.title': 'Plugin Info',\n 'plugin.hint': 'The best DSH context plugin ⭐',\n 'plugin.name': 'Plugin',\n 'plugin.github': 'GitHub',\n 'tools.top': 'Top Tool Schemas:',\n 'tools.more': 'of {n}',\n 'trend.title': 'Context History',\n 'gran.step': 'Step', 'gran.turn': 'Turn',\n 'trend.hint': 'Hover to view details, ✂ marks compaction/prune, Step/Turn switches granularity',\n 'trend.empty': 'Send a message and each model request’s context makeup shows up here',\n 'detail.step': 'Turn {t} · Step {s}',\n 'detail.turn': 'Turn {t} · {n} steps',\n 'detail.lastStep': 'Last Step',\n 'detail.estTotal': 'Estimated ≈ {n}',\n 'detail.actual': 'Actual Prompt {n}',\n 'detail.output': 'Output {n}',\n 'events.title': 'Context Events',\n 'events.empty': 'No context events yet (compaction, injections, model switches appear here)',\n 'events.at': 'Turn {t} · Step {s}',\n 'events.range': 'Turn {t} · Step {a}→{b}',\n 'events.rangeTo': 'Turn {a} · Step {as} → Turn {b} · Step {bs}',\n 'kind.inject': 'Inject', 'kind.compaction': 'Compact', 'kind.prune': 'Prune', 'kind.model': 'Switch',\n 'nodes.title': 'Messages',\n 'nodes.hint': 'currently model-visible, newest first',\n 'nodes.more': '… {n} earlier messages omitted',\n 'nodes.empty': 'No model-visible messages right now',\n 'loading': 'Reading the session log…',\n 'error': 'Failed to read context data: ',\n 'error.retry': 'Retry',\n 'footer': 'Estimate: same fixed-density heuristic as dsh’s built-in tokenMeter (~4 chars ≈ 1 token); “actual” is provider-reported usage.',\n 'tip.step': 'Turn {t} · Step {s}',\n 'tip.turn': 'Turn {t} · {n} steps',\n 'tip.total': 'Total ≈ {n}',\n 'tip.actual': ' (actual {n})',\n 'ev.compaction': 'Context compacted (summary replaced {n} messages)',\n 'ev.prune': 'Tool output pruned',\n 'ev.skill': 'Skill injected ({name})',\n 'ev.model': 'Model switched: {a} → {b}',\n 'form.instructions': 'Instructions', 'form.catalog': 'Catalog Update', 'form.snapshot': 'State Snapshot',\n 'form.notice': 'Notice', 'form.relay': 'Agent Relay', 'form.recall': 'Recall', 'form.context': 'Context Injection',\n 'node.toolResult': 'Tool Result',\n 'node.calls': 'Calls ',\n 'node.empty': '(empty reply)',\n 'node.nonText': '(non-text message)',\n 'node.snapshot': 'Snapshot: ',\n 'cmd.desc': 'View current context makeup, browse per-step composition',\n 'cmd.close': 'Close',\n 'browser.title': 'Context Browser',\n 'browser.live': 'Live (Next Request)',\n 'browser.liveNow': 'Live · Next Request',\n 'browser.items': '{n} Items',\n 'browser.missingLive': '… {n} earlier messages are also part of the context (outside the served window)',\n 'browser.approx': 'Some removed messages of this step exceed retention — the makeup below is approximate',\n 'browser.deltaHint': 'vs previous turn',\n 'browser.noHeader': 'Served by an older plugin build: token estimates only, no content',\n 'browser.noEpoch': 'The header content (System Prompt / Tool Schemas) of this step is outside retention',\n 'browser.noContent': 'Full content is outside the loaded message window (load older history in Chat to view)',\n 'browser.loading': 'Loading full content from older session history…',\n 'browser.preview': 'Preview',\n // Tool schema browser card: parsed parameter table sits above the (collapsed\n // by default) raw JSON so the common case — skimming arguments — stays\n // scannable; the JSON is still one click away for the full payload.\n 'tool.desc': 'Description',\n 'tool.params': 'Parameters',\n 'tool.paramsEmpty': '(no parameters)',\n 'tool.jsonToggle': 'View Raw JSON',\n 'tool.jsonHide': 'Collapse',\n // Detail-card view switch (system prompt / tool description / message and\n // injection bodies): a segmented pill — segment labels + tooltips.\n 'rich.raw': 'Raw',\n 'rich.md': 'Markdown',\n 'rich.toMd': 'View as Markdown',\n 'rich.toRaw': 'View Raw Text',\n // Assistant-message block titles inside the detail card: the reasoning\n // trace and the response each carry a small label (Reasoning / Response,\n // mirroring the harness's own block + locale vocabulary).\n 'block.thinking': 'Reasoning',\n 'block.answer': 'Response',\n // Attachment cards in a message detail: image refs render as thumbnail\n // cards (name + normalized dims + stored size), anything unrecognized\n // falls into the generic raw-JSON card.\n 'attach.images': 'Images',\n 'attach.other': 'Other content',\n 'attach.image': 'Image',\n 'attach.open': 'Open full image',\n 'attach.loading': '…',\n 'attach.loadFailed': 'Load failed · click to retry',\n 'attach.orig': 'original {d}',\n}\n","/**\n * Per-session open-state stores for the /context modal, plus the deferred\n * token-consume guards. Module-level so the state survives overlay remounts;\n * the trigger source (pick/enter) opens it, the overlay component subscribes\n * and renders. Implements the ObservableSnapshot pair the slot `hooks`\n * compartment binds as a `useContextModal` selector hook.\n */\n\nimport type { TokenSpan } from './services'\n\nexport interface ModalStore {\n subscribe(listener: () => void): () => void\n getSnapshot(): boolean\n set(open: boolean): void\n}\n\nconst stores = new Map<string, ModalStore>()\n\nexport function modalStoreOf(sessionId: string): ModalStore {\n const existing = stores.get(sessionId)\n if (existing !== undefined) return existing\n let open = false\n const listeners = new Set<() => void>()\n const store: ModalStore = {\n subscribe(listener) {\n listeners.add(listener)\n return () => { listeners.delete(listener) }\n },\n getSnapshot: () => open,\n set(next) {\n if (next === open) return\n open = next\n for (const listener of listeners) listener()\n },\n }\n stores.set(sessionId, store)\n return store\n}\n\n// ---- deferred token consumption -------------------------------------------\n// The `/context` token stays in the composer while the modal is open and is\n// consumed only when the modal closes. Each open path records the guard the\n// input shell understands (span CAS for menu picks, bare-token equality for\n// enter); the close path takes it and dispatches the scoped\n// `slash/input-consume-token` event. A stale guard (the user typed meanwhile)\n// fails soft inside the shell — the draft is left untouched.\n\nexport type ConsumeGuard =\n | { kind: 'span'; span: TokenSpan }\n | { kind: 'bare-token'; token: string }\n\nconst pendingConsume = new Map<string, ConsumeGuard>()\n\nexport function setPendingConsume(sessionId: string, guard: ConsumeGuard): void {\n pendingConsume.set(sessionId, guard)\n}\n\n/** Take (and clear) the guard recorded by the open path, if any. */\nexport function takePendingConsume(sessionId: string): ConsumeGuard | undefined {\n const guard = pendingConsume.get(sessionId)\n if (guard !== undefined) pendingConsume.delete(sessionId)\n return guard\n}\n","/**\n * `/context` — a client-owned slash command that opens the context modal\n * (current composition + recent trend) in the center of the page.\n *\n * Implemented as the plugin's own '/' trigger source instead of a host\n * command: nothing is dispatched to the host, no session log records are\n * written, and nothing becomes model-visible — the invocation never enters\n * the message history. Both paths answer `'handled'` and open the modal,\n * leaving the `/context` token in the composer while it is open; the modal's\n * close path consumes the token then (see modalStore.ts).\n */\n\nimport { modalStoreOf, setPendingConsume } from './modalStore'\nimport type { ClientCtx, InputTriggersFace } from './services'\nimport type { ViewKit } from './viewkit'\n\nconst COMMAND = 'context'\nconst LINE = '/' + COMMAND\n\nexport function registerContextCommand(ctx: ClientCtx, kit: ViewKit): void {\n ctx.effect(() => {\n // Soft dependency (ctx.get, not the inject list): a harness without the\n // input-trigger service keeps the tab working and only the command\n // absent.\n const inputTriggers = ctx.get('inputTriggers') as InputTriggersFace | undefined\n if (inputTriggers === undefined) return () => {}\n\n return inputTriggers.registerSource({\n trigger: '/',\n name: COMMAND,\n order: 1,\n candidates: (_session, req) => {\n if (req.position !== 'leading') return Promise.resolve([])\n const query = req.query.trim().toLowerCase()\n if (query !== '' && !COMMAND.startsWith(query)) return Promise.resolve([])\n return Promise.resolve([{ name: COMMAND, description: kit.t('cmd.desc') }])\n },\n onPick: (pick) => {\n // Open and remember the token span: the modal's close path consumes\n // it (span CAS — a draft changed meanwhile is left untouched).\n setPendingConsume(pick.session.sessionId, { kind: 'span', span: pick.span })\n modalStoreOf(pick.session.sessionId).set(true)\n return 'handled'\n },\n matchEnter: (session, line) => {\n if (line !== LINE) return Promise.resolve(undefined)\n // Same deferred consume, bare-token guard (the trimmed draft must\n // still equal the command line when the modal closes).\n setPendingConsume(session.sessionId, { kind: 'bare-token', token: LINE })\n modalStoreOf(session.sessionId).set(true)\n return Promise.resolve<'handled'>('handled')\n },\n })\n }, 'dsh-context: /context command')\n}\n","/**\n * Category presentation config: the six priced buckets (system, tool\n * schemas, and the four surface categories) with their chart colors, plus\n * `partsOf` which projects a token breakdown (snapshot current or a request\n * record) into renderable parts.\n */\n\nimport type { Category, RequestRecord, Snapshot } from '../shared/types'\n\nexport interface PartsPart { key: string; color: string; value: number }\n\nexport const CATS: { key: Category | 'system' | 'tools'; color: string }[] = [\n { key: 'system', color: '#6366f1' },\n { key: 'tools', color: '#f59e0b' },\n { key: 'user', color: '#22c55e' },\n { key: 'inject', color: '#a855f7' },\n { key: 'assistant', color: '#3b82f6' },\n { key: 'tool', color: '#14b8a6' },\n]\n\nexport function partsOf(breakdown: Snapshot['current'] | RequestRecord): PartsPart[] {\n return CATS.map((c) => {\n return { key: c.key, color: c.color, value: breakdown[c.key] || 0 }\n })\n}\n\n/**\n * Reproportion heuristic parts so they sum to a provider-anchored target —\n * the same trick the official ContextMeter uses: the heuristic breakdown\n * supplies the composition RATIOS, the provider sample the total. Returns\n * the parts unchanged when no anchor applies.\n */\nexport function anchoredParts(parts: PartsPart[], target: number | null): PartsPart[] {\n if (target === null || target <= 0) return parts\n let total = 0\n for (const p of parts) total += p.value\n if (total <= 0 || total === target) return parts\n const scale = target / total\n return parts.map(p => ({ ...p, value: Math.round(p.value * scale) }))\n}\n","/**\n * Provider-anchored headline derivation, shared by the Context tab and the\n * /context popup: the best-known occupancy of the next request, the route\n * capacity it scales against, and the composition parts anchored to that\n * total (heuristic ratios, provider-anchored sum).\n *\n * The provider anchor is the OFFICIAL token-meter `contextPressure`\n * projection (read via `useProjection('contextPressure')`) — the same\n * \"projectedTokens\" the chat's context ring displays; the Host no longer\n * mirrors it inside `contextTimeline`. When the projection is absent (older\n * harness, or the meter is not composed), the headline falls back to the\n * newest request's provider prompt plus the heuristic surface movement since\n * it was logged, and finally to the raw heuristic total.\n */\n\nimport type { ContextPressure, ContextTimeline } from '../shared/types'\nimport { anchoredParts, partsOf, type PartsPart } from './categories'\n\nexport interface Headline {\n /** Best-known occupancy of the next request (projected ?? derived ?? heuristic total). */\n tokens: number\n /** Route capacity the headline scales against (may be unknown). */\n window?: number\n /** tokens / window, clamped to 100; null without a window. */\n pct: number | null\n /** Composition parts anchored to the provider total when one exists. */\n parts: PartsPart[]\n}\n\nexport function headlineOf(data: ContextTimeline, pressure: ContextPressure | null = null): Headline {\n const current = data.current\n // The official projection's whole value is the newest usage sample carried\n // forward by the heuristic surface movement since it was taken — the same\n // formula the chat ring displays. Fields are last-wins; absent until a\n // provider reports usage.\n const projected = pressure !== null && typeof pressure.projectedTokens === 'number'\n ? pressure.projectedTokens\n : undefined\n const requests = data.requests\n const lastReq = requests.length > 0 ? requests[requests.length - 1] : null\n // Fallback anchor: the newest request's provider prompt plus the heuristic\n // surface movement since it was logged (same shape as the projection, one\n // request behind).\n const derived = lastReq !== null && typeof lastReq.prompt === 'number'\n ? lastReq.prompt + (current.total - lastReq.total)\n : undefined\n const occupancyTokens = projected ?? derived ?? null\n const window = pressure !== null && typeof pressure.contextWindow === 'number'\n ? pressure.contextWindow\n : data.contextWindow\n const tokens = occupancyTokens ?? current.total\n const pct = window !== undefined && window > 0 ? Math.min(100, Math.round(tokens / window * 100)) : null\n const parts = anchoredParts(partsOf(current), occupancyTokens !== null && tokens > 0 ? tokens : null)\n return { tokens, window, pct, parts }\n}\n","/**\n * Client-side service contracts — the exact API surface this plugin consumes\n * from the harness web half.\n *\n * The plugin bundles its own code but relies on the reader to deliver the\n * framework standard kit to slot components (`sessionId`, `useSession`,\n * `useProjection`, `t` …); only the small faces below are referenced across\n * modules. These are TYPE-ONLY: the runtime services come from the user's\n * harness. This plugin no longer calls any RPC — data arrives as pushed\n * session projections (`useProjection` standard seat).\n */\n\nimport type { Context } from '@deepseek-ai/cordis'\nimport type { ContextHeaders, ContextPressure, ContextTimeline, TokenUsage } from '../shared/types'\n\nexport interface LocaleService {\n register(ns: string, dicts: Record<string, Record<string, string>>): () => void\n bind(ns: string): (key: string, params?: Record<string, string | number>) => string\n subscribe(fn: () => void): () => void\n /** The current immutable locale snapshot (harness locale runtime). */\n getLocale?(): { active: string }\n}\n\nexport interface SlotRegistration {\n name: string\n id: string\n order: number\n /** optional dictionary namespace; the framework then synthesizes the `t` seat. */\n locale?: string\n label?: () => string\n /** optional business face factory; a `hooks` compartment binds selector hooks onto props. */\n inject?: (sessionId: string) => unknown\n}\n\nexport interface SlotsService {\n inject(name: string, callback: () => unknown): unknown\n register(\n registration: SlotRegistration,\n component: (props: { sessionId?: string }) => unknown,\n ): unknown\n}\n\n/**\n * The conversation node, as far as the Context browser consumes it: the\n * framework's finalized chat nodes carry the source surface event's `seq`\n * plus the full content — the browser joins its surface nodes on `seq` to\n * show actual content without carrying it through the projection.\n */\nexport interface ConversationNodeLike {\n kind: string\n seq: number\n content?: readonly unknown[]\n blocks?: readonly unknown[]\n call?: { name: string; argsRaw: string } | null\n isError?: boolean\n summary?: string | null\n}\n\n/**\n * A durable image attachment reference, as far as this plugin consumes it\n * (dsh's `ImageAttachmentRef`, minimally re-typed so the plugin stays free\n * of an attachment-package dependency). The durable log holds only this ref\n * — never inline bytes. Since dsh 0.1.1 the width/height/bytes describe the\n * NORMALIZED raster (long edge 2048px); `originalDimensions` carries the\n * pre-normalization size when normalization reduced the image.\n */\nexport interface ImageRefLike {\n attachmentId: string\n name?: string\n bytes?: number\n width?: number\n height?: number\n originalDimensions?: { width: number; height: number }\n}\n\n/** Loads a session-authorized display URL for one durable image reference. */\nexport type ImageLoader = (attachment: ImageRefLike) => Promise<string>\n\n/**\n * The harness conversation client service (`ctx.conversation`), minimally\n * typed for image resolution — the same call the chat view's own message\n * images ride on.\n */\nexport interface ConversationFace {\n resolveImage(sessionId: string, attachment: ImageRefLike): Promise<string>\n}\n\n/** The conversation-snapshot selector hook, minimally typed for this plugin. */\nexport type UseSessionLike = <T>(\n selector: (snapshot: {\n nodes?: readonly ConversationNodeLike[]\n /** whether older history remains outside the loaded window */\n hasMore?: boolean\n /** whether an older-history page is currently being pulled */\n loadingOlder?: boolean\n }) => T,\n) => T\n\n/**\n * The framework standard kit of a session-scope slot component, as far as\n * this plugin consumes it: the resolve session id and the key-addressed\n * projection reader that delivers the `contextTimeline` value (undefined =\n * the host unit is absent or no value has arrived yet).\n */\nexport interface SessionStandardProps {\n sessionId?: string\n useProjection?: (key: string) => unknown\n useSession?: UseSessionLike\n /**\n * History-pagination verb this plugin contributes through the harness's\n * `sessions.provide` channel (one call prepends one older page to the\n * conversation window). Absent on older hosts without the channel — the\n * Context browser then keeps its preview-plus-hint degradation.\n */\n loadOlderHistory?: () => Promise<void>\n}\n\n/** The client context: cordis plus the services this plugin injects. */\nexport type ClientCtx = Context & {\n locale: LocaleService\n slots: SlotsService\n}\n\n/**\n * Narrow an unknown projection value to a string-keyed record, or null when\n * it is not one. The boundary type is Record<string, unknown> on purpose:\n * every field read below must re-prove itself (the no-white-screen\n * guarantee), so no field may borrow the wire type before its check.\n */\nfunction asRecord(value: unknown): Record<string, unknown> | null {\n if (value === null || value === undefined || typeof value !== 'object') return null\n return value as Record<string, unknown>\n}\n\n/**\n * Safe finite-number read: a missing/non-numeric/NaN field degrades to 0\n * instead of leaking into the UI as NaN percentages or broken arithmetic.\n */\nexport function numOf(value: unknown): number {\n return typeof value === 'number' && Number.isFinite(value) ? value : 0\n}\n\n/** The usable (non-null object) entries of a delivered list; [] when the field is not a list. */\nfunction objectsOf<T>(value: unknown): T[] {\n if (!Array.isArray(value)) return []\n return value.filter((v): v is T => v !== null && typeof v === 'object')\n}\n\n/**\n * Narrow a delivered projection value to a RENDER-SAFE context timeline —\n * the client's no-white-screen guarantee against backend/parse failures.\n *\n * A value that is not a record at all (capability absent, nothing delivered\n * yet) stays `null` and callers show the loading screen. A record that fails\n * the wire shape (corrupt checkpoint restore, a failed/older host payload,\n * plugin drift) is SANITIZED instead of rejected: every collection becomes\n * an array, non-object entries are dropped, `current` becomes a numeric\n * breakdown, and wrong-typed scalars are dropped or zeroed — so the whole\n * tab still renders with every usable piece of data instead of throwing\n * during render and unmounting the conversation view.\n */\nexport function timelineOf(value: unknown): ContextTimeline | null {\n const data = asRecord(value)\n if (data === null) return null\n const current = data.current\n // The wire shape check for the cheap pass-through path: `current` must be\n // a full numeric breakdown (the host always sends all seven fields), and\n // every collection must be a real list. Anything else takes the slow path\n // and is rebuilt into the safe shape below.\n const numericBreakdown = current !== null && typeof current === 'object'\n && ['system', 'tools', 'user', 'inject', 'assistant', 'tool', 'total']\n .every(k => typeof (current as Record<string, unknown>)[k] === 'number')\n if (numericBreakdown\n && Array.isArray(data.requests)\n && Array.isArray(data.events)\n && Array.isArray(data.nodes)\n && Array.isArray(data.archive)\n && Array.isArray(data.toolList)) {\n // Well-formed: pass the delivered value through untouched (cheap, and\n // reference-stable so plain re-renders stay zero-copy).\n return data as unknown as ContextTimeline\n }\n // Malformed: rebuild with safe defaults, keeping every usable piece.\n const safeCurrent: Record<string, unknown> = current !== null && typeof current === 'object' ? current as Record<string, unknown> : {}\n const cost = typeof data.cost === 'object' && data.cost !== null && !Array.isArray(data.cost)\n ? data.cost as ContextTimeline['cost']\n : undefined\n return {\n ok: true,\n ...(typeof data.model === 'string' ? { model: data.model } : {}),\n ...(typeof data.provider === 'string' ? { provider: data.provider } : {}),\n ...(typeof data.contextWindow === 'number' ? { contextWindow: data.contextWindow } : {}),\n current: {\n system: numOf(safeCurrent.system),\n tools: numOf(safeCurrent.tools),\n user: numOf(safeCurrent.user),\n inject: numOf(safeCurrent.inject),\n assistant: numOf(safeCurrent.assistant),\n tool: numOf(safeCurrent.tool),\n total: numOf(safeCurrent.total),\n },\n toolList: objectsOf(data.toolList),\n requests: objectsOf(data.requests),\n events: objectsOf(data.events),\n nodes: objectsOf(data.nodes),\n droppedNodes: numOf(data.droppedNodes),\n archive: objectsOf(data.archive),\n ...(cost !== undefined ? { cost } : {}),\n ...(typeof data.surfaceFloor === 'number' ? { surfaceFloor: data.surfaceFloor } : {}),\n ...(typeof data.archiveFloor === 'number' ? { archiveFloor: data.archiveFloor } : {}),\n }\n}\n\n/**\n * Narrow a delivered projection value to the official token-meter\n * `contextPressure` projection (provider-anchored occupancy of the next\n * request). Absent key or value = the meter's projection is not composed\n * (e.g. a harness without the session-projection registry) — callers fall\n * back to their derived anchor, so the UI degrades gracefully.\n */\nexport function contextPressureOf(value: unknown): ContextPressure | null {\n const data: unknown = asRecord(value)\n return data as ContextPressure | null\n}\n\n/**\n * Narrow a delivered projection value to the official token-meter\n * `tokenUsage` projection (durable cumulative provider usage). Absent key or\n * value = the meter's projection is not composed (or no request has reported\n * usage yet) — callers drop the cache-hit cell to a dash.\n */\nexport function tokenUsageOf(value: unknown): TokenUsage | null {\n const data: unknown = asRecord(value)\n return data as TokenUsage | null\n}\n\n/**\n * Narrow a delivered projection value to the plugin's `contextHeaders`\n * (request-header content epochs). Absent key = an older Host half without\n * the companion unit — the Context browser degrades its system/tools\n * sections to tokens-only with a note.\n *\n * Entry-level shape is checked too: a malformed epoch (corrupt payload with\n * a missing tools list or wrong-typed system prompt) would crash the\n * browser's tools/sections reads, so the WHOLE projection degrades to null\n * and the card falls back to its tokens-only note.\n */\nexport function headersOf(value: unknown): ContextHeaders | null {\n const headers = asRecord(value)\n if (headers === null || !Array.isArray(headers.headers)) return null\n for (const h of headers.headers as unknown[]) {\n if (h === null || typeof h !== 'object') return null\n const entry = h as { tools?: unknown; system?: unknown }\n if (!Array.isArray(entry.tools)) return null\n if (entry.system !== undefined && typeof entry.system !== 'string') return null\n }\n return headers as unknown as ContextHeaders\n}\n\n// ---- /context command faces (framework `inputTriggers` service) ----\n\n/** One menu candidate offered by a trigger source. */\nexport interface TriggerCandidate {\n name: string\n description?: string\n}\n\n/** Pick-moment snapshot of the trigger token span (draftRev CAS). */\nexport interface TokenSpan {\n start: number\n end: number\n draftRev: number\n}\n\n/** Everything a source receives on a menu pick. */\nexport interface TriggerPick {\n candidate: TriggerCandidate\n session: { sessionId: string }\n position: string\n via: string\n span: TokenSpan\n}\n\n/** The pick outcomes this plugin produces (see the framework's PickOutcome). */\nexport type SourcePickOutcome = 'handled' | undefined\n\n/**\n * The harness input-trigger service (`ctx.inputTriggers`), as far as this\n * plugin consumes it: registering one '/' source whose candidates, picks,\n * and enter adjudication all stay on the client.\n */\nexport interface InputTriggersFace {\n registerSource(src: {\n trigger: '/'\n name: string\n order?: number\n candidates(\n session: { sessionId: string },\n req: { query: string; position: string; signal: AbortSignal },\n ): Promise<readonly TriggerCandidate[]>\n onPick(pick: TriggerPick): SourcePickOutcome\n matchEnter?(\n session: { sessionId: string },\n line: string,\n signal: AbortSignal,\n ): Promise<SourcePickOutcome>\n }): () => void\n}\n\n/** The session scope (`ctx.sessions.scope`), used to dispatch the scoped consume-token event. */\nexport interface SessionScopeFace {\n bail(subject: unknown, event: string, payload: unknown): unknown\n}\n\n/**\n * One standard-props contribution to the harness's `sessions.provide`\n * channel: declared members are resolved per session and delivered to every\n * session-scope slot component (hooks become `use<Name>` selector hooks,\n * props spread verbatim). Minimally typed against the runtime contract.\n */\nexport interface SessionProvideDescriptorLike {\n hooks?: readonly string[]\n props?: readonly string[]\n resolve(binding: { session: { loadOlder(): Promise<void> } }): {\n hooks?: Record<string, unknown>\n props?: Record<string, unknown>\n }\n}\n\n/** The session runtime (`ctx.sessions`), as consumed here. */\nexport interface SessionsFace {\n scope(id: string): SessionScopeFace | undefined\n /**\n * The standard-props provide channel (absent on older hosts). Throws on a\n * misdeclared or duplicate contribution — callers fail soft.\n */\n provide?(descriptor: SessionProvideDescriptorLike): () => void\n}\n","/**\n * Per-step context assembly — the pure reconstruction behind the Context\n * browser card.\n *\n * A request record R was snapshotted by the Host exactly as dispatched:\n * header in force + the model-visible surface BEFORE the response landed.\n * Given the timeline's live `nodes` (newest tail) and `archive` (removed\n * nodes stamped with `gone`), the surface assembled into R is:\n *\n * every node with seq < R.seq AND (gone undefined OR gone > R.seq)\n *\n * For the LIVE view (the next request's context) it is simply the current\n * live nodes. Coverage is honest: when the served window cannot contain the\n * full answer (older live nodes dropped, or removals older than the archive\n * retention), the result carries the flags the UI turns into notices.\n */\n\nimport type { ContextHeaders, ContextTimeline, HeaderRecord, SurfaceNode } from '../shared/types'\n\nexport interface Assembled {\n /** True when browsing the live surface (the next request's context). */\n live: boolean\n /** The header epoch in force (null = headers projection absent or none yet). */\n header: HeaderRecord | null\n /** The assembled surface messages, in seq order. */\n nodes: SurfaceNode[]\n /** Live nodes outside the served window that are also part of the context. */\n missingLive: number\n /** True when removals this step depends on may exceed archive retention. */\n approximate: boolean\n}\n\n/** The header epoch in force at `seq` (last logged before it), or the newest. */\nexport function headerAt(headers: ContextHeaders | null, seq: number | null): HeaderRecord | null {\n if (headers === null || headers.headers.length === 0) return null\n if (seq === null) return headers.headers[headers.headers.length - 1]\n for (let i = headers.headers.length - 1; i >= 0; i--) {\n if (headers.headers[i].seq < seq) return headers.headers[i]\n }\n return null\n}\n\n/**\n * Reconstruct the assembled surface for one step (`seq` = the request\n * record's seq) or the live surface (`seq` = null).\n */\nexport function assemble(data: ContextTimeline, headers: ContextHeaders | null, seq: number | null): Assembled {\n const live = seq === null\n let nodes: SurfaceNode[]\n if (live) {\n nodes = data.nodes.slice()\n } else {\n const picked: SurfaceNode[] = []\n for (const n of data.nodes) {\n if (n.seq < seq) picked.push(n)\n }\n for (const n of data.archive) {\n if (n.seq < seq && n.gone !== undefined && n.gone > seq) picked.push(n)\n }\n nodes = picked\n }\n nodes.sort((a, b) => a.seq - b.seq)\n\n let missingLive = 0\n if (data.droppedNodes > 0) {\n // Live: every dropped live node is part of the current context. A past\n // step: the dropped slice sits at or below `surfaceFloor`, so a step\n // after it contains them all (an older step's unknown subset is left\n // unflagged rather than overstated).\n if (live || (data.surfaceFloor !== undefined && seq > data.surfaceFloor)) {\n missingLive = data.droppedNodes\n }\n }\n const approximate = !live\n && data.archiveFloor !== undefined\n && seq < data.archiveFloor\n\n return { live, header: headerAt(headers, seq), nodes, missingLive, approximate }\n}\n","/**\n * The browser module table supplies React through the injected `require` —\n * every component imports it from here instead of repeating the require.\n */\n\nimport type * as ReactNS from 'react'\n\n// The loader contract: a closure-factory bundle has no ESM imports; the\n// browser module table answers this injected require.\n// oxlint-disable-next-line typescript/no-require-imports\nexport const React: typeof ReactNS = require('react') as typeof ReactNS\nexport const h = React.createElement\n","/**\n * NodeList — the current model-visible message list (newest first).\n * JSX function component; no framework primitives needed (rows are bespoke\n * data-viz chrome, styled through the shared `--dsw-alias-*` tokens).\n */\n\nimport type * as ReactNS from 'react'\nimport type { SurfaceNode } from '../../shared/types'\nimport { CATS } from '../categories'\nimport type { ViewKit } from '../viewkit'\n\nimport { React } from '../react'\n\nexport interface NodeListProps { nodes: SurfaceNode[]; dropped: number }\n\n/** One-line preview of a surface node (shared by the node list and the Context browser's element rows). */\nexport function makeNodeText(kit: ViewKit): (n: SurfaceNode) => string {\n const { t } = kit\n return function nodeText(n: SurfaceNode): string {\n if (n.cat === 'tool') {\n return t('node.toolResult') + (n.tool ? ' ← ' + n.tool : '') + (n.err ? ' ⚠' : '')\n }\n if (n.skill) return 'Skill: ' + n.skill\n if (n.calls) return t('node.calls') + n.calls.join(', ')\n if (n.text) return n.form === 'snapshot' ? t('node.snapshot') + n.text : n.text\n if (n.cat === 'assistant') return t('node.empty')\n if (n.cat === 'inject') return t('form.' + (n.form || 'context'))\n return t('node.nonText')\n }\n}\n\nexport function makeNodeList(kit: ViewKit): (props: NodeListProps) => ReactNS.ReactElement {\n const { t, fmt, fmtTime } = kit\n const nodeText = makeNodeText(kit)\n\n return function NodeList(props: NodeListProps): ReactNS.ReactElement {\n if (props.nodes.length === 0) {\n return <div className=\"lc-empty\">{t('nodes.empty')}</div>\n }\n const catColor: Record<string, string> = {}\n for (const c of CATS) catColor[c.key] = c.color\n const rows = props.nodes.slice().reverse()\n return (\n <div className=\"lc-nodes\">\n {props.dropped > 0\n ? <div className=\"lc-nodes-more\">{t('nodes.more', { n: props.dropped })}</div>\n : null}\n {rows.map((n) => {\n const text = nodeText(n)\n return (\n <div key={n.seq} className=\"lc-node\">\n <i style={{ background: catColor[n.cat] || '#999' }} />\n <span className=\"lc-node-preview\" title={text}>{text}</span>\n {/* Timestamp when the host event carried one. */}\n {typeof n.time === 'number' ? <span className=\"lc-node-time\">{fmtTime(n.time)}</span> : null}\n <span className=\"lc-node-tokens\">{fmt(n.tokens)}</span>\n </div>\n )\n })}\n </div>\n )\n }\n}\n","/**\n * Number/time formatting for the UI. `fmt` uses the same k/M suffix style\n * everywhere (bars, details, stats); `fmtTime` renders a local HH:MM:SS.\n */\n\nexport function fmt(n: number | null | undefined): string {\n if (n === undefined || n === null || isNaN(n)) return '—'\n if (n >= 1e6) return (n / 1e6).toFixed(1) + 'M'\n if (n >= 1000) return (n / 1000).toFixed(1) + 'k'\n return String(Math.round(n))\n}\n\n/** Byte sizes for attachment metadata (1 kB = 1000 B, matching the k/M style of `fmt`). */\nexport function fmtBytes(n: number | null | undefined): string {\n if (n === undefined || n === null || isNaN(n) || n < 0) return '—'\n if (n >= 1e6) return (n / 1e6).toFixed(1) + ' MB'\n if (n >= 1000) return (n / 1000).toFixed(1) + ' kB'\n return String(Math.round(n)) + ' B'\n}\n\nexport function fmtTime(t: number): string {\n // en-GB with a 24-hour clock renders the same local HH:MM:SS the manual\n // zero-pad produced, without the hand-rolled p() helper.\n // An invalid timestamp (garbage from a corrupt payload) must show a dash,\n // never throw — `toLocaleTimeString` raises RangeError on Invalid Date.\n const d = new Date(t)\n if (isNaN(d.getTime())) return '—'\n return d.toLocaleTimeString('en-GB', { hour12: false })\n}\n","/**\n * ImageCards — durable image attachment rendering for the Context browser.\n *\n * dsh 0.1.1's multimodal pipeline stores only a normalized reference per\n * image (never inline bytes), so a message block carries everything a card\n * needs except the display URL: that comes from the harness conversation\n * service's `resolveImage` (the same loader the chat history rides on),\n * handed down as `load`. Absent loader or a failed load degrades to the\n * metadata row alone — the card never throws.\n */\n\nimport type * as ReactNS from 'react'\nimport { fmtBytes } from '../format'\nimport { React } from '../react'\nimport type { ImageLoader, ImageRefLike } from '../services'\nimport type { ViewKit } from '../viewkit'\n\n/** The image-rendering handoff threaded through the browser's bodies. */\nexport interface ImageKit {\n Card: (props: { attachment: ImageRefLike; load?: ImageLoader }) => ReactNS.ReactElement\n /** Session-authorized URL loader (absent = metadata-only cards). */\n load?: ImageLoader\n}\n\n/**\n * Narrow an unknown content block to a durable image reference. Accepts both\n * raw message blocks (`{ type: 'image', attachment }`) and the conversation\n * snapshot's assistant blocks (`{ kind: 'image', attachment }`); everything\n * else returns null. Lenient on the ref's optional facts (name/bytes/dims) —\n * `resolveImage` reads only `attachmentId`.\n */\nexport function imageRefOf(block: unknown): ImageRefLike | null {\n if (block === null || typeof block !== 'object') return null\n const b = block as { type?: unknown; kind?: unknown; attachment?: unknown }\n if (b.type !== 'image' && b.kind !== 'image') return null\n const a = b.attachment\n if (a === null || typeof a !== 'object') return null\n const r = a as Record<string, unknown>\n if (typeof r.attachmentId !== 'string' || r.attachmentId === '') return null\n const num = (v: unknown): number | undefined =>\n typeof v === 'number' && Number.isFinite(v) && v > 0 ? v : undefined\n const orig = r.originalDimensions !== null && typeof r.originalDimensions === 'object'\n ? r.originalDimensions as Record<string, unknown>\n : undefined\n const origDims = orig !== undefined && num(orig.width) !== undefined && num(orig.height) !== undefined\n ? { width: num(orig.width) as number, height: num(orig.height) as number }\n : undefined\n return {\n attachmentId: r.attachmentId,\n ...(typeof r.name === 'string' && r.name !== '' ? { name: r.name } : {}),\n ...(num(r.bytes) !== undefined ? { bytes: num(r.bytes) } : {}),\n ...(num(r.width) !== undefined ? { width: num(r.width) } : {}),\n ...(num(r.height) !== undefined ? { height: num(r.height) } : {}),\n ...(origDims !== undefined ? { originalDimensions: origDims } : {}),\n }\n}\n\n/**\n * One attachment card: a 64px cover tile (click opens the full image in a\n * new tab; load failures retry on click) beside a metadata column — display\n * name, normalized dimensions (plus the pre-normalization size dsh 0.1.1\n * records), and the stored byte size.\n */\nexport function makeImageCard(kit: ViewKit): ImageKit['Card'] {\n const { t } = kit\n return function ImageCard(props: { attachment: ImageRefLike; load?: ImageLoader }): ReactNS.ReactElement {\n const { attachment, load } = props\n const [src, setSrc] = React.useState<string | null>(null)\n const [error, setError] = React.useState(false)\n // Retry re-arms the one load effect, so every attempt runs under the\n // same liveness guard and the same reset.\n const [attempt, setAttempt] = React.useState(0)\n\n React.useEffect(() => {\n if (load === undefined) return\n let live = true\n setError(false)\n setSrc(null)\n void load(attachment).then((url) => { if (live) setSrc(url) }).catch(() => { if (live) setError(true) })\n return () => { live = false }\n }, [attachment, load, attempt])\n\n const name = attachment.name ?? t('attach.image')\n const dims = attachment.width !== undefined && attachment.height !== undefined\n ? `${attachment.width}×${attachment.height}`\n : null\n const orig = attachment.originalDimensions\n const facts: string[] = []\n if (dims !== null) facts.push(dims)\n if (orig !== undefined) facts.push(t('attach.orig', { d: `${orig.width}×${orig.height}` }))\n if (attachment.bytes !== undefined) facts.push(fmtBytes(attachment.bytes))\n\n const open = (): void => {\n if (src === null) return\n try { window.open(src, '_blank', 'noopener') } catch { /* popup blocked: ignore */ }\n }\n return (\n <div className=\"lc-att-item\">\n <button\n type=\"button\"\n className=\"lc-att-thumb\"\n title={error ? t('attach.loadFailed') : t('attach.open')}\n onClick={error ? () => { setAttempt(a => a + 1) } : open}\n >\n {src !== null\n ? <img src={src} alt={name} />\n : (\n <span className={error ? 'lc-att-err' : 'lc-att-ph'}>\n {error ? '⚠' : load === undefined ? '🖼' : t('attach.loading')}\n </span>\n )}\n </button>\n <div className=\"lc-att-meta\">\n <span className=\"lc-att-name\" title={name}>{name}</span>\n {facts.length > 0 ? <span className=\"lc-att-dims\">{facts.join(' · ')}</span> : null}\n </div>\n </div>\n )\n }\n}\n","/**\n * RichText — the raw/markdown view switch shared by the Context browser's\n * detail cards (system prompt, tool description, user/assistant message and\n * injection bodies).\n *\n * `RichCard` owns the per-card mode state and places a small segmented\n * switch (the same pill chrome as the trend chart's 步骤/轮次 control) at\n * the card's top-right corner; `RichText` renders one text block in the\n * handed-down mode — rendered markdown via the harness's shared\n * MarkdownText renderer (the default; GFM, sanitized, resolved from the\n * platform module table — zero plugin-side markdown dependency) or the raw\n * <pre>. The mode crosses component boundaries explicitly through render\n * props/props (no React context), and each card keeps its own state so two\n * open details switch independently.\n */\n\nimport type * as ReactNS from 'react'\nimport { MarkdownText } from '@deepseek-ai/dsh-client-ui-primitives'\nimport { React } from '../react'\nimport type { ViewKit } from '../viewkit'\n\n/** Detail-body view mode: raw source text or rendered markdown. */\nexport type RichMode = 'raw' | 'md'\n\nexport interface RichKit {\n /** One text block in the given mode: raw <pre> or rendered markdown. */\n RichText: (props: {\n text: string\n mode: RichMode\n /** Chrome of the raw block (defaults to the browser's `lc-br-pre`). */\n rawClass?: string\n /** Chrome of the markdown box (defaults to `lc-br-md`). */\n mdClass?: string\n }) => ReactNS.ReactElement\n /**\n * Detail card wrapper: renders the mode switch as a small segmented pill\n * on the card's top-right edge and hands the current mode to its `render`\n * prop (an explicit prop, not function-children, so the mode hand-off is\n * visible in the props object).\n */\n RichCard: (props: {\n className?: string\n render: (mode: RichMode) => ReactNS.ReactNode\n }) => ReactNS.ReactElement\n /** The segmented switch alone, for cards that place it in their own head row. */\n RichSwitch: (props: { mode: RichMode; onPick: (mode: RichMode) => void; inHead?: boolean }) => ReactNS.ReactElement\n /** Per-card mode state for bodies that place the switch themselves. */\n useRichMode: () => [RichMode, (mode: RichMode) => void]\n}\n\nexport function makeRichText(kit: ViewKit): RichKit {\n const { t } = kit\n\n function useRichMode(): [RichMode, (mode: RichMode) => void] {\n // Markdown is the default view: the detail cards hold prose (prompts,\n // descriptions, messages), which reads better rendered; raw stays one\n // click away for exact source inspection.\n const [mode, setMode] = React.useState<RichMode>('md')\n return [mode, setMode]\n }\n\n // Two-option pill mirroring the trend chart's 步骤/轮次 control: one\n // segment per view, the active segment highlighted; each segment's\n // tooltip spells its view out (localized).\n function RichSwitch(props: { mode: RichMode; onPick: (mode: RichMode) => void; inHead?: boolean }): ReactNS.ReactElement {\n const seg = (m: RichMode, label: string, tip: string) => (\n <button\n type=\"button\"\n className={'lc-rich-seg-btn' + (props.mode === m ? ' lc-rich-seg-on' : '')}\n title={tip}\n onClick={() => { props.onPick(m) }}\n >{label}</button>\n )\n return (\n <span className={'lc-rich-seg' + (props.inHead === true ? ' lc-rich-seg-head' : '')}>\n {seg('raw', t('rich.raw'), t('rich.toRaw'))}\n {seg('md', t('rich.md'), t('rich.toMd'))}\n </span>\n )\n }\n\n function RichText(props: {\n text: string\n mode: RichMode\n rawClass?: string\n mdClass?: string\n }): ReactNS.ReactElement {\n if (props.mode === 'md') {\n return <div className={props.mdClass ?? 'lc-br-md'}><MarkdownText text={props.text} /></div>\n }\n return <pre className={props.rawClass ?? 'lc-br-pre'}>{props.text}</pre>\n }\n\n function RichCard(props: {\n className?: string\n render: (mode: RichMode) => ReactNS.ReactNode\n }): ReactNS.ReactElement {\n const [mode, setMode] = useRichMode()\n return (\n <div className={props.className ?? 'lc-br-content'}>\n <RichSwitch mode={mode} onPick={setMode} />\n {props.render(mode)}\n </div>\n )\n }\n\n return { RichText, RichCard, RichSwitch, useRichMode }\n}\n","/**\n * ContextBrowser — the \"Context 浏览器\" card: pick the live surface or any\n * retained step and browse what the request was actually assembled from.\n *\n * Layout follows progressive disclosure instead of a flat dump:\n * step picker + composition bar\n * → six category sections (accordion: dot, label, element count, tokens)\n * → element rows (one per message / prompt / tool schema)\n * → the element's ACTUAL content, rendered per kind (text, reasoning,\n * tool call + result, injection notice, system prompt, JSON schema).\n *\n * Data sources: the `contextTimeline` projection (structure + token prices,\n * per-step reconstruction via the removed-node archive), the `contextHeaders`\n * projection (full system prompt + tool schemas — absent on older hosts,\n * degrading those two sections to tokens-only), and the framework\n * conversation snapshot (full message content joined by event seq; nodes\n * outside the loaded window fall back to the 80-char preview with a note).\n */\n\nimport type * as ReactNS from 'react'\nimport type { Category, ContextHeaders, ContextTimeline, HeaderTool, RequestRecord, SurfaceNode } from '../../shared/types'\nimport { assemble } from '../assemble'\nimport type { Assembled } from '../assemble'\nimport { CATS, partsOf } from '../categories'\nimport { React } from '../react'\nimport type { ConversationNodeLike, UseSessionLike } from '../services'\nimport type { ViewKit } from '../viewkit'\nimport { makeNodeText } from './nodes'\nimport { imageRefOf, makeImageCard } from './images'\nimport type { ImageKit } from './images'\nimport { makeRichText } from './richText'\nimport type { RichKit, RichMode } from './richText'\nimport type { StackedBarProps } from './stackedBar'\nimport type { ImageLoader, ImageRefLike } from '../services'\n\nexport interface ContextBrowserProps {\n data: ContextTimeline\n headers: ContextHeaders | null\n useSession?: UseSessionLike\n /** History-pagination verb contributed via `sessions.provide` (absent on older hosts). */\n loadOlderHistory?: () => Promise<void>\n /**\n * Trend-chart hover linkage: the seq of the bar under the pointer. While\n * set, the browser transiently previews that step; the picker's own\n * selection resumes when the pointer leaves the chart.\n */\n previewSeq?: number | null\n /**\n * Trend-chart pin linkage: the seq of the bar pinned by a click. The\n * browser's own step picker follows it — a pin selects that step, an\n * unpin (pinSeq back to null) returns the browser to the live surface.\n */\n pinSeq?: number | null\n /**\n * Current-composition hover link, shared with the Current Composition card\n * (its bar + legend): the active category key, reported via onHoverKey.\n * The browser joins the link ONLY while it shows the LIVE step — a pinned\n * or previewed step's composition differs, so its hover must not light the\n * overview (and the overview's hover must not highlight another step).\n */\n hoverKey?: string | null\n onHoverKey?: (key: string | null) => void\n /**\n * Overview tool-chip bridge: a click on the overview card's \"工具定义 Top\"\n * label (`tool` omitted) or one of its chips (`tool: name`) asks this\n * browser to reveal that section. A one-shot request — it is applied once\n * (switch to the live surface, open the \"tools\" category, and when a\n * specific tool is named expand its row), then handed back through\n * `onToolFocusHandled` so the same chip can be clicked again.\n */\n toolFocus?: { tool?: string } | null\n /** Called once a one-shot `toolFocus` request has been applied; the parent clears it. */\n onToolFocusHandled?: () => void\n /**\n * Session-authorized image URL loader (built by the Context view from the\n * harness conversation service). Absent = image cards render metadata only.\n */\n loadImage?: ImageLoader\n}\n\n/** The JSON Schema fragment describing one parameter's type, defensively narrowed. */\ninterface ParamSchema {\n type?: unknown\n description?: unknown\n // JSON Schema vocabulary used by tool inputs the browser needs to display\n // meaningfully: enum values (render as a comma-joined inline list), an\n // array's `items` (render the element type), and `anyOf`/`oneOf` (render\n // the alternation as a `/`-joined list). Anything else falls back to a\n // plain `type` string or `object` if absent.\n enum?: unknown\n items?: unknown\n anyOf?: unknown\n oneOf?: unknown\n}\n\n/** Flatten the `anyOf` / `oneOf` alternation into one displayable string. */\nfunction unionTypesOf(p: ParamSchema): string | null {\n const branches: unknown[] = []\n if (Array.isArray(p.anyOf)) branches.push(...p.anyOf as unknown[])\n if (Array.isArray(p.oneOf)) branches.push(...p.oneOf as unknown[])\n if (branches.length === 0) return null\n const parts: string[] = []\n for (const b of branches) {\n if (b !== null && typeof b === 'object') parts.push(typeOf(b))\n }\n return parts.length > 0 ? parts.join(' | ') : null\n}\n\n/**\n * Derive a short, human-readable type label from a JSON Schema fragment.\n * Arrays show their element type (`array<number>`); unions fold into\n * `a | b`; enums collapse into `(enum)`. Returns `unknown` when the schema\n * carries no usable signal — the row falls back to its description then.\n */\nfunction typeOf(p: ParamSchema): string {\n const u = unionTypesOf(p)\n if (u !== null) return u\n const t = p.type\n if (t === 'array') {\n const items = p.items\n if (items !== null && typeof items === 'object') {\n const inner = typeOf(items)\n return 'array<' + inner + '>'\n }\n return 'array'\n }\n if (typeof t === 'string') {\n if (t === 'object') {\n const props = (p as { properties?: unknown }).properties\n if (props !== null && typeof props === 'object' && Object.keys(props).length > 0) {\n return `object{${Object.keys(props).length}}`\n }\n }\n if (Array.isArray(p.enum) && p.enum.length > 0) {\n return t + ' (enum)'\n }\n return t\n }\n if (Array.isArray(p.enum) && p.enum.length > 0) return '(enum)'\n return 'unknown'\n}\n\n/**\n * Locate the parameter-bearing object inside a raw tool schema. Producers\n * may nest it under `parameters`, `input_schema`, `inputSchema`, or hand\n * the schema as the bare JSON Schema (when `type === 'object'`).\n */\nfunction paramsOf(schema: unknown): ParamSchema | null {\n if (schema === null || typeof schema !== 'object') return null\n const s = schema as Record<string, unknown>\n const candidate = (v: unknown): ParamSchema | null =>\n v !== null && typeof v === 'object' ? v : null\n const nested = candidate(s.parameters) ?? candidate(s.input_schema)\n ?? candidate(s.inputSchema)\n if (nested !== null) return nested\n // Bare JSON Schema: a `{ type: 'object', properties: {...} }` at the root\n // is itself the parameter object — no inner wrapper.\n if (s.type === 'object' && s.properties !== undefined && typeof s.properties === 'object') {\n return s\n }\n return null\n}\n\n/**\n * One row of the parsed parameter table — name (mono-styled, with a\n * required chip), short type label, and the description on its own line\n * (so a long blurb never breaks the name/type rhythm).\n */\nfunction ParamRow(props: {\n name: string\n schema: ParamSchema\n required: boolean\n}): ReactNS.ReactElement {\n const typeLabel = typeOf(props.schema)\n const desc = props.schema.description\n return (\n <div className=\"lc-ts-param-row\">\n <span className=\"lc-ts-param-name\">{props.name}</span>\n <span className=\"lc-ts-param-type\">{typeLabel}</span>\n <span className={props.required ? 'lc-ts-param-req' : 'lc-ts-param-req-off'}>\n {props.required ? '✓' : '·'}\n </span>\n {typeof desc === 'string' && desc !== ''\n ? <span className=\"lc-ts-param-desc\">{desc}</span>\n : null}\n </div>\n )\n}\n\n/**\n * The full body of one expanded tool row: description, a parsed parameter\n * table (when the schema carries one), and the raw JSON behind a toggle.\n * Owns its own open/closed state for the JSON so two expanded tools stay\n * independent. The description card carries the shared raw/markdown view\n * toggle in its head (per-card state via `rich.useRichMode`).\n */\nfunction ToolSchema(props: {\n description: string | undefined\n schema: unknown\n /** Rich-text toggle kit (description card: raw <pre> vs markdown). */\n rich: RichKit\n /** Localized labels for the card titles, empty-state line, and toggle. */\n labels: {\n desc: string\n title: string\n empty: string\n show: string\n hide: string\n }\n}): ReactNS.ReactElement {\n const { rich } = props\n const [jsonOpen, setJsonOpen] = React.useState(false)\n const [descMode, setDescMode] = rich.useRichMode()\n const params = React.useMemo(() => paramsOf(props.schema), [props.schema])\n // Pull `properties` + `required` out of the parameter object as plain\n // values (avoids re-deriving the same shape in every row).\n const rows = React.useMemo<{ name: string; schema: ParamSchema; required: boolean }[]>(() => {\n if (params === null) return []\n const props = (params as { properties?: unknown }).properties\n if (props === null || typeof props !== 'object') return []\n const req = Array.isArray((params as { required?: unknown }).required)\n ? new Set(((params as { required: unknown[] }).required)\n .filter((x): x is string => typeof x === 'string'))\n : new Set<string>()\n const out: { name: string; schema: ParamSchema; required: boolean }[] = []\n for (const k of Object.keys(props)) {\n const v = (props as Record<string, unknown>)[k]\n if (v === null || typeof v !== 'object') continue\n out.push({ name: k, schema: v, required: req.has(k) })\n }\n return out\n }, [params])\n const schemaJson = React.useMemo(\n () => props.schema !== undefined ? JSON.stringify(props.schema, null, 2) : '',\n [props.schema],\n )\n return (\n <>\n {props.description !== undefined ? (\n <div className=\"lc-ts-card\">\n <div className=\"lc-ts-card-head\">\n <b>{props.labels.desc}</b>\n <rich.RichSwitch mode={descMode} onPick={setDescMode} inHead />\n </div>\n <rich.RichText\n text={props.description}\n mode={descMode}\n rawClass=\"lc-ts-desc-body\"\n mdClass=\"lc-ts-desc-md\"\n />\n </div>\n ) : null}\n {params !== null && rows.length > 0 ? (\n <div className=\"lc-ts-card\">\n <div className=\"lc-ts-card-head\">\n <b>{props.labels.title}</b>\n <span className=\"lc-ts-card-count\">{rows.length}</span>\n </div>\n {rows.map(r => <ParamRow key={r.name} name={r.name} schema={r.schema} required={r.required} />)}\n </div>\n ) : params !== null ? (\n <div className=\"lc-ts-params-empty\">{props.labels.empty}</div>\n ) : null}\n {schemaJson !== '' ? (\n <div className=\"lc-ts-json\">\n <button\n type=\"button\"\n className=\"lc-ts-json-toggle\"\n onClick={() => { setJsonOpen(o => !o) }}\n >{(jsonOpen ? '▾ ' : '▸ ') + (jsonOpen ? props.labels.hide : props.labels.show)}</button>\n {jsonOpen ? <pre className=\"lc-br-pre lc-br-dim\">{schemaJson}</pre> : null}\n </div>\n ) : null}\n </>\n )\n}\n\n/** One raw content block (text/reasoning/tool-result/image/…), rendered defensively. */\nfunction RawBlocks(props: { blocks: readonly unknown[]; mode: RichMode; rich: RichKit; img: ImageKit }): ReactNS.ReactElement {\n const { rich, img } = props\n return (\n <>\n {props.blocks.map((b, i) => {\n const blk = b !== null && typeof b === 'object' ? b as { type?: string; text?: unknown; content?: unknown } : null\n if (blk !== null\n && (blk.type === 'text' || blk.type === 'reasoning') && typeof blk.text === 'string') {\n // Reasoning stays raw in either mode (plain model trace, not\n // prose); text blocks follow the card's view mode.\n if (blk.type === 'reasoning') {\n return <pre key={i} className=\"lc-br-pre lc-br-dim\">{blk.text}</pre>\n }\n return <rich.RichText key={i} text={blk.text} mode={props.mode} />\n }\n const image = imageRefOf(b)\n if (image !== null) return <img.Card key={i} attachment={image} load={img.load} />\n if (blk !== null && blk.type === 'tool-result' && Array.isArray(blk.content)) {\n return <RawBlocks key={i} blocks={blk.content as unknown[]} mode={props.mode} rich={rich} img={img} />\n }\n return <pre key={i} className=\"lc-br-pre lc-br-dim\">{JSON.stringify(b, null, 2)}</pre>\n })}\n </>\n )\n}\n\n/**\n * One assistant-message block (thinking / answer) as its own card: the\n * title row carries the block label plus the block's OWN raw/markdown\n * switch (per-card state via `rich.useRichMode`, mirroring the tool\n * description card), so a mixed reply's parts toggle independently.\n */\nfunction BlockCard(props: { label: string; text: string; rich: RichKit }): ReactNS.ReactElement {\n const { rich } = props\n const [mode, setMode] = rich.useRichMode()\n return (\n <div className=\"lc-ts-card\">\n <div className=\"lc-ts-card-head\">\n <b>{props.label}</b>\n <rich.RichSwitch mode={mode} onPick={setMode} inHead />\n </div>\n <rich.RichText\n text={props.text}\n mode={mode}\n rawClass=\"lc-ts-desc-body\"\n mdClass=\"lc-ts-desc-md\"\n />\n </div>\n )\n}\n\n/**\n * One assistant tool call as its own card, mirroring the tool-definition\n * parameter card: the head names the call target (with the parsed argument\n * count), the body lists the arguments as name/type/value rows. Arguments\n * that are not a parseable JSON object fall back to the raw payload inside\n * the same card.\n */\nfunction ToolCallCard(props: { name: string; argsRaw: unknown }): ReactNS.ReactElement {\n const args = React.useMemo<Record<string, unknown> | null>(() => {\n if (typeof props.argsRaw !== 'string' || props.argsRaw === '') return null\n try {\n const parsed: unknown = JSON.parse(props.argsRaw)\n return parsed !== null && typeof parsed === 'object' && !Array.isArray(parsed)\n ? parsed as Record<string, unknown>\n : null\n } catch {\n return null\n }\n }, [props.argsRaw])\n return (\n <div className=\"lc-ts-card\">\n <div className=\"lc-ts-card-head\">\n <b>{'→ ' + props.name}</b>\n {args !== null ? <span className=\"lc-ts-card-count\">{Object.keys(args).length}</span> : null}\n </div>\n {args !== null\n ? Object.keys(args).map(k => <CallArgRow key={k} name={k} value={args[k]} />)\n : typeof props.argsRaw === 'string' && props.argsRaw !== ''\n ? <pre className=\"lc-br-pre lc-br-dim\">{props.argsRaw}</pre>\n : null}\n </div>\n )\n}\n\n/** One parsed call argument: name, value type, and the value itself (full-width line). */\nfunction CallArgRow(props: { name: string; value: unknown }): ReactNS.ReactElement {\n const v = props.value\n const text = typeof v === 'string' ? v\n : v === undefined ? ''\n : JSON.stringify(v)\n return (\n <div className=\"lc-ts-param-row\">\n <span className=\"lc-ts-param-name\">{props.name}</span>\n <span className=\"lc-ts-param-type\">{v === null ? 'null' : Array.isArray(v) ? 'array' : typeof v}</span>\n <span className=\"lc-ts-param-desc\">{text}</span>\n </div>\n )\n}\n\n/** The actual content of one surface element, joined from the conversation snapshot. */\nfunction NodeContent(props: {\n node: SurfaceNode\n conv: ConversationNodeLike | undefined\n hint: string\n rich: RichKit\n img: ImageKit\n labels: { thinking: string; answer: string; images: string; other: string }\n}): ReactNS.ReactElement {\n const { node, conv, rich, img } = props\n // The raw/markdown toggle serves the prose bodies (user / injection text,\n // compaction summaries); assistant thinking/answer blocks each carry\n // their own per-card switch (BlockCard); tool results stay raw\n // (structured payload, not prose).\n const richable = node.cat === 'user' || node.cat === 'assistant' || node.cat === 'inject'\n const wrap = (render: (mode: RichMode) => ReactNS.ReactNode): ReactNS.ReactElement =>\n richable\n ? <rich.RichCard render={render} />\n : <div className=\"lc-br-content\">{render('raw')}</div>\n\n if (conv === undefined) {\n if (node.text === undefined || node.text === '') {\n return <div className=\"lc-br-content\"><div className=\"lc-br-note\">{props.hint}</div></div>\n }\n return wrap(mode => (\n <>\n <rich.RichText text={node.text ?? ''} mode={mode} />\n <div className=\"lc-br-note\">{props.hint}</div>\n </>\n ))\n }\n if (conv.kind === 'assistant' && Array.isArray(conv.blocks)) {\n // Thinking, answer, and tool-call blocks render as SEPARATE cards (the\n // prose cards own a raw/markdown switch, the call card parses its\n // arguments into rows); images keep their raw form.\n return (\n <div className=\"lc-br-content\">\n {conv.blocks.map((b, i) => {\n const blk = b as { kind?: string; text?: unknown; name?: string; argsRaw?: unknown }\n if (blk.kind === 'text' && typeof blk.text === 'string') {\n return <BlockCard key={i} label={props.labels.answer} text={blk.text} rich={rich} />\n }\n if (blk.kind === 'reasoning' && typeof blk.text === 'string') {\n return <BlockCard key={i} label={props.labels.thinking} text={blk.text} rich={rich} />\n }\n if (blk.kind === 'tool-call') {\n return <ToolCallCard key={i} name={blk.name ?? '?'} argsRaw={blk.argsRaw} />\n }\n const image = imageRefOf(b)\n if (image !== null) return <img.Card key={i} attachment={image} load={img.load} />\n return null\n })}\n </div>\n )\n }\n if (conv.kind === 'tool-result') {\n return (\n <div className=\"lc-br-content\">\n {conv.call != null\n ? (\n <div className=\"lc-br-call\">\n <span className=\"lc-br-tag\">{'← ' + conv.call.name}</span>\n {conv.call.argsRaw !== '' ? <pre className=\"lc-br-pre lc-br-dim\">{conv.call.argsRaw}</pre> : null}\n </div>\n )\n : null}\n {Array.isArray(conv.content) ? <RawBlocks blocks={conv.content} mode=\"raw\" rich={rich} img={img} /> : null}\n </div>\n )\n }\n if (conv.kind === 'compaction') {\n return wrap(mode => (\n <>\n {typeof conv.summary === 'string' && conv.summary !== ''\n ? <rich.RichText text={conv.summary} mode={mode} />\n : null}\n </>\n ))\n }\n if (Array.isArray(conv.content)) {\n const blocks = conv.content as unknown[]\n // User messages get the card layout: prose in the toggle-served text\n // card, durable image refs as attachment cards (thumbnail + name + dims\n // + size), and anything else as a raw JSON card. A text-only message\n // renders exactly as before — one rich card and nothing else.\n if (node.cat !== 'user') {\n return wrap(mode => <RawBlocks blocks={blocks} mode={mode} rich={rich} img={img} />)\n }\n const texts: string[] = []\n const images: ImageRefLike[] = []\n const others: unknown[] = []\n for (const b of blocks) {\n const blk = b as { type?: string; text?: unknown } | null\n if (blk !== null && typeof blk === 'object' && blk.type === 'text' && typeof blk.text === 'string') {\n texts.push(blk.text)\n continue\n }\n const image = imageRefOf(b)\n if (image !== null) { images.push(image); continue }\n others.push(b)\n }\n return (\n <div className=\"lc-br-content\">\n {texts.length > 0 ? (\n // Un-padded RichCard: the outer lc-br-content already owns the\n // body indent, so the text card aligns with the attachment cards\n // instead of sitting one indent deeper.\n <rich.RichCard className=\"lc-br-rich-inline\" render={mode => (\n <>\n {texts.map((text, i) => <rich.RichText key={i} text={text} mode={mode} />)}\n </>\n )} />\n ) : null}\n {images.length > 0 ? (\n <div className=\"lc-ts-card\">\n <div className=\"lc-ts-card-head\">\n <b>{props.labels.images}</b>\n <span className=\"lc-ts-card-count\">{images.length}</span>\n </div>\n <div className=\"lc-att-grid\">\n {images.map((a, i) => <img.Card key={`${a.attachmentId}:${i}`} attachment={a} load={img.load} />)}\n </div>\n </div>\n ) : null}\n {others.length > 0 ? (\n <div className=\"lc-ts-card\">\n <div className=\"lc-ts-card-head\">\n <b>{props.labels.other}</b>\n <span className=\"lc-ts-card-count\">{others.length}</span>\n </div>\n {others.map((b, i) => <pre key={i} className=\"lc-br-pre lc-br-dim\">{JSON.stringify(b, null, 2)}</pre>)}\n </div>\n ) : null}\n </div>\n )\n }\n return <div className=\"lc-br-content\"><div className=\"lc-br-note\">{props.hint}</div></div>\n}\n\n/** Group an assembled surface's nodes by category (for per-category counts). */\nfunction byCatOf(asm: Assembled): Partial<Record<Category, SurfaceNode[]>> {\n const m: Partial<Record<Category, SurfaceNode[]>> = {}\n for (const n of asm.nodes) (m[n.cat] ??= []).push(n)\n return m\n}\n\n/** Count one category's elements in an assembled surface (header cats included). */\nfunction countOf(asm: Assembled, c: string): number {\n if (c === 'system') return asm.header !== null && asm.header.system !== undefined ? 1 : 0\n if (c === 'tools') return asm.header !== null ? asm.header.tools.length : 0\n return byCatOf(asm)[c as Category]?.length ?? 0\n}\n\n/** The last request of `turn` in a seq-ordered timeline, or null. */\nfunction lastOfTurn(requests: RequestRecord[], turn: number): RequestRecord | null {\n for (let i = requests.length - 1; i >= 0; i--) if ((requests[i].turn ?? 0) === turn) return requests[i]\n return null\n}\n\nexport function makeContextBrowser(\n kit: ViewKit,\n StackedBar: (props: StackedBarProps) => ReactNS.ReactElement,\n): (props: ContextBrowserProps) => ReactNS.ReactElement {\n const { t, fmt, fmtTime, catLabel } = kit\n const nodeText = makeNodeText(kit)\n const rich = makeRichText(kit)\n const ImageCard = makeImageCard(kit)\n const catColor: Record<string, string> = {}\n for (const c of CATS) catColor[c.key] = c.color\n\n // Auto-load ceiling: one expand pulls older pages (50 events each) until\n // the element's seq enters the window, history runs out, or this cap is\n // hit — a guard against seqs that never land in the conversation snapshot.\n const MAX_AUTO_PAGES = 20\n\n return function ContextBrowser(props: ContextBrowserProps): ReactNS.ReactElement {\n const { data, headers } = props\n // 'live' = the current surface (the NEXT request's context); a number =\n // the seq of a retained request record (a past step).\n const [sel, setSel] = React.useState<'live' | number>('live')\n const [openCat, setOpenCat] = React.useState<string | null>(null)\n const [openElem, setOpenElem] = React.useState<string | null>(null)\n\n // Full message content, joined from the conversation snapshot by the\n // surface event seq. `s.nodes` is a stable reference per snapshot; the\n // seq map is memoized over it.\n const convNodes = typeof props.useSession === 'function'\n ? props.useSession(s => s.nodes)\n : undefined\n const bySeq = React.useMemo(() => {\n const m = new Map<number, ConversationNodeLike>()\n for (const n of convNodes ?? []) m.set(n.seq, n)\n return m\n }, [convNodes])\n\n // Window state for on-demand history pagination (primitive selectors, so\n // the component re-renders only when a page actually lands or runs out).\n const hasMore = typeof props.useSession === 'function'\n ? props.useSession(s => s.hasMore === true)\n : false\n const loadingOlder = typeof props.useSession === 'function'\n ? props.useSession(s => s.loadingOlder === true)\n : false\n\n // The open element's surface-node seq ('sys'/'tool:*' keys never join).\n const openSeq = openElem !== null && openElem.startsWith('n')\n ? Number(openElem.slice(1))\n : null\n const missingSeq = openSeq !== null && !bySeq.has(openSeq) ? openSeq : null\n // Auto-load: expanding an out-of-window element pages older history in\n // until its seq joins (one page in flight, sequenced by the snapshot's\n // own loadingOlder flag). `exhausted` latches the cap/history-end so the\n // hint falls back to the static note instead of \"loading\" forever.\n const [exhausted, setExhausted] = React.useState(false)\n const pagesRef = React.useRef(0)\n React.useEffect(() => {\n pagesRef.current = 0\n setExhausted(false)\n }, [openElem])\n const loadOlderHistory = props.loadOlderHistory\n React.useEffect(() => {\n if (missingSeq === null || !hasMore || loadingOlder || exhausted) return\n if (loadOlderHistory === undefined) return\n if (pagesRef.current >= MAX_AUTO_PAGES) {\n setExhausted(true)\n return\n }\n pagesRef.current += 1\n void loadOlderHistory()\n }, [missingSeq, hasMore, loadingOlder, exhausted, bySeq, loadOlderHistory])\n React.useEffect(() => {\n // History ran out with the seq still missing: stop showing \"loading\".\n if (!hasMore && missingSeq !== null && !exhausted) setExhausted(true)\n }, [hasMore, missingSeq, exhausted])\n // History-chart pin linkage: a pinned bar selects its step in the picker,\n // an unpin returns to live — the same accordion reset a manual pick\n // performs. (Live is also the right target while unpinned: a manual pick\n // made here is overridden only when a NEW pin lands.)\n const pinSeq = props.pinSeq\n React.useEffect(() => {\n setSel(pinSeq === null || pinSeq === undefined ? 'live' : pinSeq)\n setOpenCat(null)\n setOpenElem(null)\n }, [pinSeq])\n // Overview tool-link bridge: apply a one-shot request (switch to the LIVE\n // surface — the overview's Top chips rank the current header's tools —\n // open the tools category, expand the clicked tool), then hand it back so\n // the parent can issue the same focus again on the next click.\n const toolFocus = props.toolFocus\n React.useEffect(() => {\n if (toolFocus === null || toolFocus === undefined) return\n setSel('live')\n setOpenCat('tools')\n setOpenElem(toolFocus.tool !== undefined ? 'tool:' + toolFocus.tool : null)\n if (props.onToolFocusHandled !== undefined) props.onToolFocusHandled()\n }, [toolFocus, props.onToolFocusHandled])\n const awaiting = missingSeq !== null && !exhausted && loadOlderHistory !== undefined && hasMore\n\n const requests = data.requests\n // Trend-chart hover linkage: the bar under the pointer transiently\n // previews its step (unknown seq = trimmed out of retention, ignored);\n // the picker's own selection resumes when the pointer leaves the chart.\n const hoverReq = props.previewSeq !== null && props.previewSeq !== undefined\n ? requests.find(r => r.seq === props.previewSeq) ?? null\n : null\n const req = hoverReq ?? (sel === 'live' ? null : requests.find(r => r.seq === sel) ?? null)\n // A pinned step trimmed out of retention falls back to live.\n const seq = req !== null ? req.seq : null\n // Current-composition hover link: the browser joins the Current\n // Composition card's shared hover only while it shows the LIVE step —\n // a pinned/previewed step has a different composition, so its hover must\n // not light the overview (and the overview's hover must not highlight\n // this step's parts). The mirror filter drops the overview's FREE-track\n // key, which has no segment in the browser's bar.\n const linked = req === null && props.onHoverKey !== undefined\n const linkKey = linked && props.hoverKey !== null && props.hoverKey !== 'free'\n ? props.hoverKey\n : null\n const view = assemble(data, headers, seq)\n const breakdown = req !== null ? req : data.current\n const parts = partsOf(breakdown)\n const total = breakdown.total\n const pick = (v: string) => {\n setSel(v === 'live' ? 'live' : Number(v))\n setOpenCat(null)\n setOpenElem(null)\n }\n\n // δ baselines against the PREVIOUS TURN's last request — one stable unit\n // whatever step (or live surface) is shown: a step of turn T reads\n // against turn T−1's final step, avoiding the misleading \"change\" a\n // same-turn neighbour would imply. Live refers to the most recent\n // request, itself a turn's last step.\n const refReq = req === null\n ? requests.length > 0 ? requests[requests.length - 1] : null\n : lastOfTurn(requests, (req.turn ?? 0) - 1)\n const prevView = refReq !== null ? assemble(data, headers, refReq.seq) : null\n\n const byCat = byCatOf(view)\n\n const toolCount = (c: string): number => countOf(view, c)\n\n const toggleCat = (c: string) => {\n // Empty categories stay shut — EXCEPT system/tools with a missing\n // header epoch: those open to explain the degradation note.\n const openable = toolCount(c) > 0\n || ((c === 'system' || c === 'tools') && view.header === null)\n if (!openable) return\n setOpenCat(openCat === c ? null : c)\n setOpenElem(null)\n }\n const toggleElem = (key: string) => { setOpenElem(openElem === key ? null : key) }\n\n /** One expandable element row (preview line; content when open). */\n const elemRow = (\n key: string, tag: string | null, preview: string,\n tokens: number, time: number | undefined, body: ReactNS.ReactNode,\n ) => {\n const open = openElem === key\n return (\n <div key={key} className={'lc-br-elem' + (open ? ' lc-br-elem-on' : '')}>\n <button type=\"button\" className=\"lc-br-elem-row\" onClick={() => { toggleElem(key) }}>\n <span className={'lc-br-chev' + (open ? ' lc-br-chev-on' : '')}>{'▸'}</span>\n {tag !== null ? <span className=\"lc-br-tag\">{tag}</span> : null}\n <span className=\"lc-br-preview\">{preview}</span>\n {time !== undefined ? <span className=\"lc-br-time\">{fmtTime(time)}</span> : null}\n <span className=\"lc-br-tokens\">{'≈' + fmt(tokens)}</span>\n </button>\n {open ? body : null}\n </div>\n )\n }\n\n const catBody = (c: string): ReactNS.ReactNode => {\n if (c === 'system') {\n if (view.header === null) return <div className=\"lc-br-note\">{t(headers === null ? 'browser.noHeader' : 'browser.noEpoch')}</div>\n const system = view.header.system\n if (system === undefined) return null\n return elemRow('sys', null, system.replace(/\\s+/g, ' ').trim().slice(0, 80), breakdown.system, undefined,\n <rich.RichCard render={mode => <rich.RichText text={system} mode={mode} />} />)\n }\n if (c === 'tools') {\n if (view.header === null) return <div className=\"lc-br-note\">{t(headers === null ? 'browser.noHeader' : 'browser.noEpoch')}</div>\n // Schemas rank by token price (largest first), mirroring the overview's\n // \"工具定义 Top\" chips; the producer's header order is not meaningful.\n // Localized labels for the per-tool parameter table / JSON toggle:\n // passed in by the parent so the body component stays a pure function\n // of its props (testable in isolation, no closure over `t`).\n const labels = {\n desc: t('tool.desc'),\n title: t('tool.params'),\n empty: t('tool.paramsEmpty'),\n show: t('tool.jsonToggle'),\n hide: t('tool.jsonHide'),\n }\n return view.header.tools.slice().sort((a, b) => b.tokens - a.tokens).map((tool: HeaderTool) => {\n return elemRow('tool:' + tool.name, null, tool.name, tool.tokens, undefined,\n <div className=\"lc-br-content\">\n <ToolSchema description={tool.description} schema={tool.schema} rich={rich} labels={labels} />\n </div>)\n })\n }\n // Surface-node categories carry per-element timestamps; list them\n // newest first, mirroring the NodeList card.\n const nodes = (byCat[c as Category] ?? []).slice().reverse()\n return nodes.map((n) => {\n // Tag/preview split: the compact chip carries the compact fact (tool\n // name, injection form), the preview line carries the text — each\n // fact shown once. Skill/calls previews already name themselves.\n let tag: string | null = null\n let preview = nodeText(n)\n if (n.cat === 'tool') {\n tag = (n.tool ?? '?') + (n.err ? ' ⚠' : '')\n preview = t('node.toolResult') + (n.err ? ' ⚠' : '')\n } else if (n.cat === 'inject' && !n.skill) {\n tag = t('form.' + (n.form || 'context'))\n if (n.text !== undefined && n.text !== '') {\n preview = n.form === 'snapshot' ? t('node.snapshot') + n.text : n.text\n }\n }\n return elemRow(`n${n.seq}`, tag, preview, n.tokens, n.time,\n <NodeContent\n node={n}\n conv={bySeq.get(n.seq)}\n rich={rich}\n img={{ Card: ImageCard, load: props.loadImage }}\n // Localized block/section titles (thinking / answer / image and\n // other-content cards), handed in by the parent so the body\n // stays a pure function of props.\n labels={{\n thinking: t('block.thinking'),\n answer: t('block.answer'),\n images: t('attach.images'),\n other: t('attach.other'),\n }}\n // This row's body renders only while it is the open element, so\n // `awaiting` (open seq missing, pagination armed) means THIS join\n // is the one pages are being pulled for.\n hint={bySeq.get(n.seq) === undefined && awaiting\n ? t('browser.loading')\n : t('browser.noContent')}\n />)\n })\n }\n\n return (\n <div className=\"lc-card\">\n <div className=\"lc-card-title\">\n <span className=\"lc-card-title-text\">{t('browser.title')}</span>\n <span className=\"lc-br-hint\">{t('browser.deltaHint')}</span>\n <select\n className=\"lc-br-pick\"\n value={seq === null ? 'live' : String(seq)}\n onChange={(e) => { pick(e.target.value) }}\n >\n <option value=\"live\">{t('browser.live')}</option>\n {requests.slice().reverse().map(r => (\n <option key={r.seq} value={String(r.seq)}>\n {t('detail.step', { t: r.turn ?? 0, s: r.step ?? 0 }) + ' · ' + fmtTime(r.time)}\n </option>\n ))}\n </select>\n </div>\n\n <div className=\"lc-br-meta\">\n <b>{req !== null\n ? t('detail.step', { t: req.turn ?? 0, s: req.step ?? 0 })\n : t('browser.liveNow')}</b>\n {req !== null ? <span>{fmtTime(req.time)}</span> : null}\n {hoverReq !== null ? <span className=\"lc-card-sub\">{t('browser.preview')}</span> : null}\n <span>{t('detail.estTotal', { n: fmt(total) })}</span>\n {req !== null && req.prompt !== undefined\n ? <span className=\"lc-actual\">{t('detail.actual', { n: fmt(req.prompt) })}</span>\n : null}\n </div>\n\n <div className=\"lc-br-bar\">\n <StackedBar\n parts={parts}\n height={10}\n // Mirrored hover link (see `linked` above): while the browser\n // shows the live surface, its bar highlights the shared category\n // key and reports its own hovers back to the Current Composition\n // card. The tip stays off — a cross-card hover must not float a\n // second tooltip over a bar the pointer does not rest on.\n hoverKey={linked ? linkKey : undefined}\n onHoverKey={linked ? props.onHoverKey : undefined}\n tip={false}\n />\n </div>\n\n {view.missingLive > 0\n ? <div className=\"lc-br-note\">{t('browser.missingLive', { n: view.missingLive })}</div>\n : null}\n {view.approximate\n ? <div className=\"lc-br-note\">{t('browser.approx')}</div>\n : null}\n\n <div className=\"lc-br-cats\">\n {CATS.map((c) => {\n const count = toolCount(c.key)\n const v = breakdown[c.key] || 0\n // Δ vs the reference step: element-count badge (hidden when the\n // count held), token swing in the badge's tooltip — the same two\n // figures the row already shows, over the deepest step in scope.\n const prevCount = prevView !== null ? countOf(prevView, c.key) : null\n const countDelta = prevCount !== null ? count - prevCount : null\n const prevTokens = refReq !== null ? (refReq[c.key] || 0) : null\n const tokenDelta = prevTokens !== null ? v - prevTokens : null\n const openable = count > 0\n || ((c.key === 'system' || c.key === 'tools') && view.header === null)\n const open = openCat === c.key && openable\n return (\n <div key={c.key} className={'lc-br-cat' + (openable ? '' : ' lc-br-cat-empty')}>\n <button\n type=\"button\"\n className={'lc-br-cat-row' + (linked && props.hoverKey === c.key ? ' lc-br-cat-on' : '')}\n onMouseEnter={linked ? () => { if (props.onHoverKey !== undefined) props.onHoverKey(c.key) } : undefined}\n onMouseLeave={linked ? () => { if (props.onHoverKey !== undefined) props.onHoverKey(null) } : undefined}\n onClick={() => { toggleCat(c.key) }}\n >\n <span className={'lc-br-chev' + (open ? ' lc-br-chev-on' : '')}>{'▸'}</span>\n <i style={{ background: c.color }} />\n <span className=\"lc-br-cat-label\">{catLabel(c.key)}</span>\n {/* Count + Δ pill sit as one attached group (tight inner gap),\n the group absorbs the row's free space so tokens/percent\n stay right-aligned. */}\n <span className=\"lc-br-count-grp\">\n <span className=\"lc-br-cat-count\">{t('browser.items', { n: count })}</span>\n {countDelta !== null && countDelta !== 0 ? (\n <span className={'lc-br-delta lc-br-delta-' + (countDelta > 0 ? 'up' : 'down')}>\n {`${countDelta > 0 ? '+' : ''}${countDelta}`}\n </span>\n ) : null}\n </span>\n {/* Token Δ pill hugs the left of the token figure — its own\n direction-colored pill, hidden while the count held. */}\n <span className=\"lc-br-tokens-grp\">\n {tokenDelta !== null && tokenDelta !== 0 ? (\n <span className={'lc-br-tdelta lc-br-tdelta-' + (tokenDelta > 0 ? 'up' : 'down')}>\n {(tokenDelta > 0 ? '+' : '') + fmt(tokenDelta)}\n </span>\n ) : null}\n <span className=\"lc-br-tokens\">{'≈' + fmt(v)}</span>\n </span>\n <span className=\"lc-br-pct\">{total > 0 ? `${Math.round(v / total * 100)}%` : ''}</span>\n </button>\n {open ? <div className=\"lc-br-body\">{catBody(c.key)}</div> : null}\n </div>\n )\n })}\n </div>\n </div>\n )\n }\n}\n","/**\n * StackedBar + Legend — the composition bar (overview card) and its legend.\n * Hovering a segment or its legend chip lights the same segment and shows\n * the same tooltip; the free window space (blank track) is hoverable too.\n * JSX components; the shared hover-link tooltip is bespoke (no shared\n * primitive reproduces the cross-segment/legend linkage), so it stays custom\n * but styled through the shared `--dsw-alias-*` tokens.\n */\n\nimport type * as ReactNS from 'react'\nimport type { PartsPart } from '../categories'\nimport type { ViewKit } from '../viewkit'\n\nimport { React } from '../react'\n\n/**\n * DSH's automatic compaction trigger as a fraction of the routed context\n * window — the default `thresholdRatio` of `@deepseek-ai/dsh-compaction-basic`\n * (it compacts at step boundaries once `floor(contextWindow × ratio)` is\n * reached). DSH does not publish the configured ratio to plugins or clients,\n * so the UI mirrors the default here; deployments that tune `thresholdRatio`\n * / `modelPolicies` can adjust it if they want the reserve band to match.\n */\nexport const AUTO_COMPACT_RATIO = 0.8\n\nexport interface StackedBarProps {\n parts: PartsPart[]\n max?: number\n height?: number\n /** Optional hover link: the active segment key, reported via onHoverKey. */\n hoverKey?: string | null\n onHoverKey?: (key: string | null) => void\n /** Render the hover tooltip (default true). A mirrored bar that only echoes\n * another card's hover turns it off, so the tooltip floats only over the\n * surface the pointer actually rests on. */\n tip?: boolean\n /**\n * Optional auto-compaction reserve band: the rightmost `(1 − ratio)` of the\n * window, drawn as striped \"headroom\" — the region the session normally\n * avoids filling because automatic compaction triggers past the threshold.\n * Only rendered when `max` (the window) is a positive number. `label` is the\n * translated hover explanation shown over the band.\n */\n reserve?: { ratio: number; label: string }\n}\n\nexport function makeStackedBar(kit: ViewKit): (props: StackedBarProps) => ReactNS.ReactElement {\n const { t, fmt, catLabel } = kit\n return function StackedBar(props: StackedBarProps): ReactNS.ReactElement {\n // Hovering the reserve band shows its explanation (not a segment's); the\n // flag lives here so the single tooltip slot serves both.\n const [reserveOn, setReserveOn] = React.useState(false)\n // props.parts: [{key,color,value}]; optional props.max: when max exceeds\n // the parts' total, the remainder shows as an empty, hoverable track\n // (\"free window\" — the space left in the context window).\n let total = 0\n for (const p of props.parts) total += p.value\n const scale = props.max !== undefined && props.max > total ? props.max : total\n const free = props.max !== undefined && props.max > total ? props.max - total : 0\n // Segment widths are laid out against the FULL window (scale), but their\n // legend/tooltip percentages are shares of the OCCUPIED total — so on\n // hover we frame the occupied region (width = used/scale) with a solid\n // box that makes that reference frame visible. Only when a free track\n // exists (otherwise width already equals the percentage).\n const usedPct = scale > 0 ? total / scale * 100 : 0\n const hovering = props.hoverKey !== null && props.hoverKey !== undefined\n const showBox = free > 0 && hovering\n\n // The reserve band is laid out in WINDOW units (`ratio × max` → `max`)\n // scaled onto whatever total the bar spans, so it stays the same physical\n // slice whether or not a free track exists (once used exceeds the window,\n // the stripes sit over the outermost segments).\n const reserve = props.reserve !== undefined && props.max !== undefined && props.max > 0\n // Carry the checked max into the object: the non-null reserve below\n // then proves max is present, no assertion needed.\n ? { ...props.reserve, max: props.max }\n : null\n // Round to one decimal: the ratios are float-y (0.8 × max / scale) and a\n // style % with a long decimal tail is noise (would render the same).\n const reserveLeft = reserve !== null ? Math.round(reserve.max * reserve.ratio / scale * 1000) / 10 : 0\n const reserveWidth = reserve !== null ? Math.round((1 - reserve.ratio) * reserve.max / scale * 1000) / 10 : 0\n\n // The tooltip is DERIVED from the shared hover key, so hovering either a\n // segment or its legend chip lights the same segment and shows the same\n // tooltip (centered on the segment; percentage positioning needs no\n // measuring). The wrapper keeps the tooltip outside the clipped stack.\n // Hovering the RESERVE band overrides the slot with its own explanation,\n // centered over the band's middle.\n let tip: { text: string; leftPct: number } | null = null\n if (reserveOn && reserve !== null) {\n tip = {\n text: reserve.label,\n leftPct: Math.max(12, Math.min(reserveLeft + reserveWidth / 2, 88)),\n }\n } else if (props.hoverKey !== null && props.hoverKey !== undefined) {\n if (props.hoverKey === 'free' && free > 0) {\n const pct = scale > 0 ? free / scale * 100 : 0\n tip = {\n text: `${t('overview.free')} ${fmt(free)} (${Math.round(pct)}%)`,\n leftPct: Math.max(12, Math.min((total / scale * 100) + pct / 2, 88)),\n }\n } else {\n let acc = 0\n for (const p of props.parts) {\n const pct = scale > 0 ? p.value / scale * 100 : 0\n if (p.key === props.hoverKey && p.value > 0) {\n tip = {\n // \"(pct%)\" is a share of the OCCUPIED total — the solid box\n // that appears on hover frames exactly this reference region.\n text: `${catLabel(p.key)} ≈${fmt(p.value)} (${Math.round(p.value / total * 100)}%) `\n + t('overview.ofUsed'),\n leftPct: Math.max(12, Math.min(acc + pct / 2, 88)),\n }\n break\n }\n acc += pct\n }\n }\n }\n\n return (\n <div className=\"lc-stacked-wrap\">\n <div\n // Hover focus: dim everything except the hovered part and show the\n // occupied-region frame (`.lc-stacked-dim` + `.lc-occupied-box`).\n className={'lc-stacked' + (hovering ? ' lc-stacked-dim' : '')}\n style={{ height: `${props.height || 14}px` }}\n onMouseLeave={() => {\n if (props.onHoverKey !== undefined) props.onHoverKey(null)\n setReserveOn(false)\n }}\n >\n {total > 0\n ? props.parts.map((p) => {\n if (!p.value) return null\n const on = props.hoverKey !== undefined && props.hoverKey === p.key\n return (\n <div\n key={p.key}\n className={'lc-stacked-seg' + (on ? ' lc-stacked-seg-on' : '')}\n style={{ width: `${p.value / scale * 100}%`, background: p.color }}\n onMouseEnter={() => { if (props.onHoverKey !== undefined) props.onHoverKey(p.key) }}\n />\n )\n })\n : null}\n {free > 0 ? (\n <div\n key=\"free\"\n className={'lc-stacked-free' + (props.hoverKey === 'free' ? ' lc-stacked-free-on' : '')}\n style={{ width: `${free / scale * 100}%` }}\n onMouseEnter={() => { if (props.onHoverKey !== undefined) props.onHoverKey('free') }}\n />\n ) : null}\n {/* Auto-compaction reserve band: the rightmost (1−ratio) of the\n window, striped like a warning plate to read as \"headroom, not\n real usage\". Painted above the track/segments so the stripes\n overlay them, owns the pointer so its own explanation shows\n (and the segment hover link is cleared while exploring it). */}\n {reserve !== null ? (\n <div\n className=\"lc-reserve\"\n style={{ left: `${reserveLeft}%`, width: `${reserveWidth}%` }}\n onMouseEnter={() => {\n setReserveOn(true)\n if (props.onHoverKey !== undefined) props.onHoverKey(null)\n }}\n onMouseLeave={() => { setReserveOn(false) }}\n />\n ) : null}\n {/* Hover reference frame: the occupied region (outside the free\n track) — the region the legend/tooltip percentages refer to.\n Painted last so its border stays above the segments. Always\n mounted (`.lc-occupied-box-on` toggles opacity) so the frame\n fades out on leave instead of unmounting instantly. */}\n <div\n className={'lc-occupied-box' + (showBox ? ' lc-occupied-box-on' : '')}\n style={{ width: `${usedPct}%` }}\n />\n </div>\n {/* The hover tooltip is always mounted too (opacity toggles via\n `.lc-bar-tip-on`) so it fades in AND out; hidden it holds no\n pointer events and no width of its own. */}\n {props.tip !== false\n ? (\n <div\n className={'lc-bar-tip' + (tip ? ' lc-bar-tip-on' : '')}\n style={{ left: tip ? `${tip.leftPct}%` : '50%' }}\n >{tip ? tip.text : ''}</div>\n )\n : null}\n </div>\n )\n }\n}\n\nexport function makeLegend(kit: ViewKit): (props: {\n parts: PartsPart[]\n hoverKey?: string | null\n onHoverKey?: (key: string | null) => void\n}) => ReactNS.ReactElement {\n const { t, fmt, catLabel } = kit\n return function Legend(props: {\n parts: PartsPart[]\n hoverKey?: string | null\n onHoverKey?: (key: string | null) => void\n }): ReactNS.ReactElement {\n let total = 0\n for (const p of props.parts) total += p.value\n return (\n <div className=\"lc-legend\">\n {props.parts.map((p) => {\n const on = props.hoverKey !== undefined && props.hoverKey === p.key\n return (\n <span\n key={p.key}\n className={'lc-chip' + (on ? ' lc-chip-on' : '')}\n title={t('overview.ofUsed')}\n onMouseEnter={() => { if (props.onHoverKey !== undefined) props.onHoverKey(p.key) }}\n onMouseLeave={() => { if (props.onHoverKey !== undefined) props.onHoverKey(null) }}\n >\n <i style={{ background: p.color }} />\n <span className=\"lc-chip-label\">{catLabel(p.key)}</span>\n <span className=\"lc-chip-nums\">\n {'≈' + fmt(p.value)}\n {total > 0 ? <em>{`${Math.round(p.value / total * 100)}%`}</em> : null}\n </span>\n </span>\n )\n })}\n </div>\n )\n }\n}\n","/**\n * CurrentComposition — the \"当前构成\" card shared by the Context tab and the\n * /context popup: the composition headline (occupancy vs window), the\n * composition bar (with the auto-compaction reserve band), the legend, and —\n * when a tool bridge is wired — the ranked \"工具定义 Top\" chips that jump the\n * Context browser to a tool section.\n *\n * JSX function component, pure (no state): everything flows through props so\n * either host drives the shared hover link and the tool focus identically.\n */\n\nimport type * as ReactNS from 'react'\nimport type { PartsPart } from '../categories'\nimport type { Headline } from '../headline'\nimport type { ViewKit } from '../viewkit'\nimport { AUTO_COMPACT_RATIO } from './stackedBar'\nimport type { StackedBarProps } from './stackedBar'\n\nimport { React } from '../react'\n\ntype LegendFn = (props: {\n parts: PartsPart[]\n hoverKey?: string | null\n onHoverKey?: (key: string | null) => void\n}) => ReactNS.ReactElement\n\nexport interface CurrentCompositionProps {\n head: Headline\n /** Card subtitle (model / provider); empty hides it. */\n subtitle?: string\n /** Shared hover link (bar + legend + browser while it shows the live step). */\n hoverKey?: string | null\n onHoverKey?: (key: string | null) => void\n /** Optional ranked tool schemas for the \"工具定义 Top\" row (absent = no chips). */\n tools?: { name: string; tokens: number }[]\n /** One-shot tool-focus request into the Context browser (omitted = no chips). */\n onToolFocus?: (focus: { tool?: string } | null) => void\n}\n\nexport function makeCurrentComposition(\n kit: ViewKit,\n StackedBar: (props: StackedBarProps) => ReactNS.ReactElement,\n Legend: LegendFn,\n): (props: CurrentCompositionProps) => ReactNS.ReactElement {\n const { t, fmt } = kit\n return function CurrentComposition(props: CurrentCompositionProps): ReactNS.ReactElement {\n const head = props.head\n const reserve = head.window != null && head.window > 0\n ? { ratio: AUTO_COMPACT_RATIO, label: t('overview.compactReserve', { pct: Math.round(AUTO_COMPACT_RATIO * 100) }) }\n : undefined\n return (\n <div className=\"lc-card\">\n <div className=\"lc-card-title\">\n <span className=\"lc-card-title-text\">{t('overview.title')}</span>\n {props.subtitle !== undefined && props.subtitle !== ''\n ? <span className=\"lc-card-sub\">{props.subtitle}</span>\n : null}\n </div>\n <div className=\"lc-overview-num\">\n <b>{fmt(head.tokens)}</b>\n <span>\n {head.window\n ? ' / ' + fmt(head.window) + ' tokens'\n : ' ' + t('overview.estimate')}\n </span>\n {head.pct !== null ? (\n <span className=\"lc-overview-pct\">\n <b>{`${head.pct}%`}</b>\n {t('overview.used')}\n </span>\n ) : null}\n </div>\n <StackedBar\n parts={head.parts}\n height={16}\n max={head.window}\n hoverKey={props.hoverKey}\n onHoverKey={props.onHoverKey}\n reserve={reserve}\n />\n <Legend parts={head.parts} hoverKey={props.hoverKey} onHoverKey={props.onHoverKey} />\n {props.tools !== undefined && props.tools.length > 0 ? (\n <div className=\"lc-tools\">\n <button type=\"button\" className=\"lc-tools-label\" onClick={() => { if (props.onToolFocus !== undefined) props.onToolFocus({}) }}>\n {t('tools.top')}\n </button>\n {props.tools.slice().sort((a, b) => b.tokens - a.tokens).slice(0, 5).map(tool => (\n <button key={tool.name} type=\"button\" className=\"lc-tool-chip\" onClick={() => { if (props.onToolFocus !== undefined) props.onToolFocus({ tool: tool.name }) }}>\n {tool.name + ' ' + fmt(tool.tokens)}\n </button>\n ))}\n {props.tools.length > 5\n ? (\n <button type=\"button\" className=\"lc-tools-more\" onClick={() => { if (props.onToolFocus !== undefined) props.onToolFocus({}) }}>\n {t('tools.more', { n: props.tools.length })}\n </button>\n )\n : null}\n </div>\n ) : null}\n </div>\n )\n }\n}\n","/**\n * ErrorBoundary — the tab's no-white-screen guarantee.\n *\n * A render error anywhere in the subtree (a foreign or corrupt projection\n * value that slips past the shape guards in services.ts, a framework\n * surprise, a future bug) would otherwise propagate into the harness's slot\n * renderer and unmount the whole conversation view. This boundary catches\n * render errors of its subtree and degrades to a styled error card with the\n * offending message — the surrounding harness UI (chat, tabs, composer)\n * keeps working as if nothing happened.\n *\n * A class component: the only React primitive that can catch render errors\n * of a subtree (there is no hook-based boundary in React 18). The Retry\n * button resets the boundary; if the underlying condition persists the\n * boundary catches again, once a healthy value arrives the tab resumes.\n */\n\nimport type * as ReactNS from 'react'\nimport type { Translate } from '../i18n'\n\nimport { React } from '../react'\n\nexport function makeErrorBoundary(t: Translate): ReactNS.ComponentType<{ children?: ReactNS.ReactNode }> {\n return class ErrorBoundary extends React.Component<{ children?: ReactNS.ReactNode }, { error: Error | null }> {\n constructor(props: { children?: ReactNS.ReactNode }) {\n super(props)\n this.state = { error: null }\n }\n\n static getDerivedStateFromError(error: unknown): { error: Error | null } {\n return { error: error instanceof Error ? error : new Error(String(error)) }\n }\n\n render(): ReactNS.ReactNode {\n const error = this.state.error\n if (error === null) return this.props.children\n return (\n <div className=\"lc-root\">\n <div className=\"lc-empty lc-error\">\n <span>{t('error')}</span>\n <code className=\"lc-error-msg\">{error.message}</code>\n <button\n type=\"button\"\n className=\"lc-error-retry\"\n onClick={() => { this.setState({ error: null }) }}\n >{t('error.retry')}</button>\n </div>\n </div>\n )\n }\n }\n}\n","/**\n * ContextModal — the /context command's centered dialog: the same data as\n * the Context tab (the pushed `contextTimeline` projection) distilled to\n * the current-composition overview (headline + composition bar + legend)\n * and the shared Context browser (browse any retained step's assembled\n * surface). Rendered from the `conversation.input.overlay` slot; opens and\n * closes through the per-session modal store (the trigger source flips it,\n * so no message ever enters the session history).\n */\n\nimport type * as ReactNS from 'react'\nimport { headlineOf } from '../headline'\nimport { modalStoreOf, takePendingConsume } from '../modalStore'\nimport type { ClientCtx, SessionStandardProps, SessionsFace } from '../services'\nimport { contextPressureOf, headersOf, timelineOf } from '../services'\nimport type { ViewKit } from '../viewkit'\nimport { makeContextBrowser } from './browser'\nimport { makeCurrentComposition } from './currentComposition'\nimport { makeErrorBoundary } from './errorBoundary'\nimport { makeLegend, makeStackedBar } from './stackedBar'\n\nimport { React, h } from '../react'\n\nexport interface ContextModalProps extends SessionStandardProps {\n /** Bound selector hook over the per-session open flag (hooks compartment). */\n useContextModal?: (sel: (open: boolean) => boolean) => boolean\n}\n\nexport function makeContextModal(ctx: ClientCtx, kit: ViewKit): (props: ContextModalProps) => ReactNS.ReactElement | null {\n const { t } = kit\n const sessions = ctx.get('sessions') as SessionsFace | undefined\n const StackedBar = makeStackedBar(kit)\n const Legend = makeLegend(kit)\n // The /context popup reuses the SAME cards as the Context tab — no\n // duplicated browsing logic; picking, accordion, reconstruction and paging\n // all ride the shared components (joining the modal overview's hover link\n // while the browser shows the live step, and the tool chips jumping it).\n const CurrentComposition = makeCurrentComposition(kit, StackedBar, Legend)\n const ContextBrowser = makeContextBrowser(kit, StackedBar)\n const ErrorBoundary = makeErrorBoundary(t)\n\n // The body holds all hooks and data reads inside the error boundary (same\n // arrangement as the Context tab): a corrupt projection value or framework\n // surprise degrades to a styled error card inside the dialog instead of\n // breaking the conversation input overlay around it.\n function ContextModalBody(props: ContextModalProps): ReactNS.ReactElement | null {\n const sessionId = typeof props.sessionId === 'string' ? props.sessionId : ''\n const open = typeof props.useContextModal === 'function' ? props.useContextModal(s => s) : false\n const data = typeof props.useProjection === 'function'\n ? timelineOf(props.useProjection('contextTimeline'))\n : null\n // Provider-anchored occupancy from the official token-meter\n // `contextPressure` projection (same key the chat ring reads); absent\n // value degrades to the derived fallback inside headlineOf.\n const pressure = typeof props.useProjection === 'function'\n ? contextPressureOf(props.useProjection('contextPressure'))\n : null\n // Header-content epochs for the browser's system/tools sections (absent\n // on older hosts -> tokens-only degradation, same as the Context tab).\n const headers = typeof props.useProjection === 'function'\n ? headersOf(props.useProjection('contextHeaders'))\n : null\n const [hoverCat, setHoverCat] = React.useState<string | null>(null)\n // One-shot tool-focus from the CurrentComposition card's chips into the\n // embedded Context browser (label = category-only, chip = specific tool).\n const [toolFocus, setToolFocus] = React.useState<{ tool?: string } | null>(null)\n\n const close = React.useCallback(() => {\n if (sessionId === '') return\n modalStoreOf(sessionId).set(false)\n // Deferred token consumption: the `/context` token stayed in the\n // composer while the modal was open; consume it now through the scoped\n // input event (a stale guard — the user typed meanwhile — fails soft\n // inside the shell and leaves the draft untouched).\n const guard = takePendingConsume(sessionId)\n if (guard === undefined || sessions === undefined) return\n const scope = sessions.scope(sessionId)\n if (scope !== undefined) scope.bail(scope, 'slash/input-consume-token', { guard })\n }, [sessionId])\n\n // Escape closes; on open the current focus (the composer) is captured\n // and restored on close, so typing resumes exactly where it stopped.\n React.useEffect(() => {\n if (!open) return undefined\n const previous = document.activeElement instanceof HTMLElement ? document.activeElement : null\n const onKey = (ev: KeyboardEvent) => {\n if (ev.key !== 'Escape') return\n ev.preventDefault()\n ev.stopPropagation()\n close()\n }\n window.addEventListener('keydown', onKey, true)\n return () => {\n window.removeEventListener('keydown', onKey, true)\n if (previous !== null && document.contains(previous)) previous.focus()\n }\n }, [open, close])\n\n if (!open) return null\n\n const head = data !== null ? headlineOf(data, pressure) : null\n // The composition card carries the model/provider subtitle; keep the\n // dialog header to just the title + close (model/provider below once).\n const subtitle = data !== null ? (data.model ? data.model : '') + (data.provider ? ' · ' + data.provider : '') : ''\n\n return (\n <div className=\"lc-modal-backdrop\" onClick={close}>\n <div className=\"lc-modal-card\" onClick={(ev) => { ev.stopPropagation() }}>\n <div className=\"lc-modal-head\">\n <span className=\"lc-modal-title\">{t('tab')}</span>\n <button className=\"lc-modal-close\" aria-label={t('cmd.close')} onClick={close}>×</button>\n </div>\n\n {data === null || head === null ? (\n <div className=\"lc-empty\">{t('loading')}</div>\n ) : (\n <div>\n <CurrentComposition\n head={head}\n subtitle={subtitle}\n hoverKey={hoverCat}\n onHoverKey={setHoverCat}\n tools={data.toolList}\n onToolFocus={setToolFocus}\n />\n <ContextBrowser\n data={data}\n headers={headers}\n useSession={props.useSession}\n loadOlderHistory={props.loadOlderHistory}\n hoverKey={hoverCat}\n onHoverKey={setHoverCat}\n toolFocus={toolFocus}\n onToolFocusHandled={() => { setToolFocus(null) }}\n />\n </div>\n )}\n </div>\n </div>\n )\n }\n\n return function ContextModal(props: ContextModalProps): ReactNS.ReactElement | null {\n return h(ErrorBoundary, null, h(ContextModalBody, props))\n }\n}\n","/**\n * Context events — event text helpers (label + timeline range) and the\n * EventList component that renders the events column.\n *\n * JSX function components: glyphs for injection/model-switch reuse the\n * harness's shared icon set (`@deepseek-ai/dsh-client-ui-primitives`, a\n * platform seed word resolved from the loader module table); compaction and\n * prune keep the ✂ marker (product vocabulary, no shared glyph exists).\n * Each row carries a kind chip (注入/压缩/剪枝/切换) so the classification is\n * readable at a glance; chip color matches the impact direction (+ adds,\n * − frees, ⇄ neutral), mirroring the token sign colors. Long labels truncate\n * with an ellipsis; the native title tooltip is attached only while the\n * label actually overflows (re-measured on every render and on resize).\n */\n\nimport type * as ReactNS from 'react'\nimport type { ContextEventRecord } from '../../shared/types'\nimport { IconBranchOutline16, IconPlusOutline16 } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { Translate } from '../i18n'\nimport type { ViewKit } from '../viewkit'\n\nimport { React } from '../react'\n\nexport const EVENT_ICONS: Record<string, string> = { compaction: '✂', prune: '✂', inject: '+', model: '⇄' }\n\nexport interface EventListProps { events: ContextEventRecord[] }\n\n/** Build the event text helpers bound to the translate function. */\nexport function makeEventText(t: Translate): {\n eventLabel: (ev: ContextEventRecord) => string\n eventAt: (ev: ContextEventRecord) => string | null\n} {\n function eventLabel(ev: ContextEventRecord): string {\n if (ev.kind === 'compaction') return t('ev.compaction', { n: ev.count || 0 })\n if (ev.kind === 'prune') return t('ev.prune')\n if (ev.kind === 'model') return t('ev.model', { a: ev.from || '?', b: ev.to || '?' })\n // The kind union narrows to 'inject' here; a future kind breaks the\n // compile (ev.sub ev.form ev.name are inject-only), forcing a label.\n if (ev.sub === 'skill') return t('ev.skill', { name: ev.name || '?' })\n const base = t('form.' + (ev.form || 'context'))\n return ev.name ? base + ' · ' + ev.name : base\n }\n\n /**\n * Where this event sits in the request timeline, as a label or null.\n * Boundary events (compaction/prune) show the GAP they sit in: same-turn\n * \"Step 2→3\", cross-turn \"Turn 50 · Step 8 → Turn 51 · Step 1\". Injections\n * and model switches belong to one request and keep the single point.\n * Events with no following request (in flight) stay unlabeled.\n */\n function eventAt(ev: ContextEventRecord): string | null {\n if (ev.kind === 'compaction' || ev.kind === 'prune') {\n if (typeof ev.turn === 'number' && typeof ev.step === 'number') {\n if (typeof ev.fromTurn === 'number' && typeof ev.fromStep === 'number') {\n if (ev.fromTurn === ev.turn) return t('events.range', { t: ev.turn, a: ev.fromStep, b: ev.step })\n return t('events.rangeTo', { a: ev.fromTurn, as: ev.fromStep, b: ev.turn, bs: ev.step })\n }\n return t('events.at', { t: ev.turn, s: ev.step })\n }\n return null\n }\n if (typeof ev.turn === 'number' && typeof ev.step === 'number') {\n return t('events.at', { t: ev.turn, s: ev.step })\n }\n return null\n }\n\n return { eventLabel, eventAt }\n}\n\nexport function makeEventList(kit: ViewKit): (props: EventListProps) => ReactNS.ReactElement {\n const { t, fmt, fmtTime, eventLabel, eventAt } = kit\n return function EventList(props: EventListProps): ReactNS.ReactElement {\n if (props.events.length === 0) {\n return <div className=\"lc-empty\">{t('events.empty')}</div>\n }\n const rootRef = React.useRef<HTMLDivElement | null>(null)\n // Attach the native tooltip only where the ellipsis actually truncates:\n // re-sync after every render (events/width change) and on window resize,\n // reading scrollWidth vs clientWidth on the live row.\n React.useLayoutEffect(() => {\n const root = rootRef.current\n if (!root) return\n const sync = () => {\n for (const el of root.querySelectorAll<HTMLElement>('.lc-event-label')) {\n el.title = el.scrollWidth > el.clientWidth ? el.textContent || '' : ''\n }\n }\n sync()\n window.addEventListener('resize', sync)\n return () => { window.removeEventListener('resize', sync) }\n })\n const sorted = props.events.slice().reverse()\n return (\n <div className=\"lc-events\" ref={rootRef}>\n {sorted.map((ev, i) => {\n const label = eventLabel(ev)\n const at = eventAt(ev)\n const glyph = ev.kind === 'inject' ? <IconPlusOutline16 />\n : ev.kind === 'model' ? <IconBranchOutline16 />\n : EVENT_ICONS[ev.kind] || '•'\n return (\n <div key={`${ev.seq}-${i}`} className=\"lc-event\">\n <span className={'lc-event-icon lc-event-' + ev.kind}>{glyph}</span>\n <span className={'lc-kind lc-kind-' + ev.kind}>{t('kind.' + ev.kind)}</span>\n <span className=\"lc-event-label\">{label}</span>\n {at !== null ? <span className=\"lc-event-at\">{at}</span> : null}\n {ev.tokens ? (\n <span className={'lc-event-tokens' + (ev.kind === 'inject' ? ' lc-up' : ' lc-down')}>\n {(ev.kind === 'inject' ? '+' : '−') + fmt(ev.tokens)}\n </span>\n ) : null}\n <span className=\"lc-event-time\">{fmtTime(ev.time)}</span>\n </div>\n )\n })}\n </div>\n )\n }\n}\n","/**\n * Plugin self-metadata for the Plugin info card. Version is substituted at\n * build time (tsdown `define` in tsdown.config.ts, read from package.json);\n * the typeof guard keeps a dev/test bundle built without defines working.\n */\n\ndeclare const __DSH_CTX_VERSION__: string | undefined\ndeclare const __DSH_CTX_REPO__: string | undefined\n\nexport const PLUGIN_NAME = 'dsh-context'\nexport const PLUGIN_VERSION: string =\n typeof __DSH_CTX_VERSION__ === 'string' ? __DSH_CTX_VERSION__ : '0.0.0-dev'\nexport const PLUGIN_REPO: string =\n typeof __DSH_CTX_REPO__ === 'string' ? __DSH_CTX_REPO__ : 'https://github.com/bowenliang123/dsh-context'\n/** Short `owner/repo` form of the GitHub URL, for display only. */\nexport const PLUGIN_REPO_SHORT = PLUGIN_REPO.replace(/^https?:\\/\\/github\\.com\\//, '')\n","/**\n * Latest published version of this plugin on the npm registry — the one\n * live check the Plugin info card performs. Fetched lazily on the first\n * card mount and cached with a 1-hour TTL, so the registry is hit at most\n * once per hour per page. Every failure mode (offline, CSP-blocked,\n * non-200, malformed body) narrows to null = no upgrade hint, so the card\n * silently keeps its static version.\n */\n\nimport { PLUGIN_NAME } from './meta'\n\nconst REGISTRY_URL = 'https://registry.npmjs.org/' + PLUGIN_NAME + '/latest'\n\n/** How long a registry result stays fresh before the next check refetches. */\nconst TTL_MS = 60 * 60 * 1000\n\nlet cached: { at: number; promise: Promise<string | null> } | null = null\n\nexport function fetchLatestVersion(): Promise<string | null> {\n if (!cached || Date.now() - cached.at >= TTL_MS) {\n cached = {\n at: Date.now(),\n promise: fetch(REGISTRY_URL)\n .then(res => (res.ok ? res.json() as Promise<{ version?: unknown }> : null))\n .then(body => (body !== null && typeof body.version === 'string' ? body.version : null))\n .catch(() => null),\n }\n }\n return cached.promise\n}\n\n/** Numeric semver compare (pre-release suffix ignored): is `latest` strictly newer than `current`? */\nexport function isNewerVersion(latest: string, current: string): boolean {\n const parse = (v: string): number[] =>\n v.replace(/^v/, '').split('-', 1)[0].split('.').map(n => parseInt(n, 10) || 0)\n const a = parse(latest)\n const b = parse(current)\n for (let i = 0; i < Math.max(a.length, b.length); i++) {\n const x = a[i] || 0\n const y = b[i] || 0\n if (x !== y) return x > y\n }\n return false\n}\n","/**\n * PluginInfo — the card beside Context stats introducing the plugin itself.\n * Every row is one whole-row link: the anchor wraps the label + value so the\n * entire key/value cell is one hit target. Row 1 (Plugin name + version) →\n * the repo's releases page, row 2 (the short owner/repo label) → the repo\n * root; hovering a row underlines its value. Metadata is baked into the\n * bundle from package.json via tsdown `define` (see src/client/meta.ts +\n * tsdown.config.ts). One live check rides on top: the card asks the npm\n * registry for the latest published version (cached with a 1-hour TTL, see\n * ../latestVersion.ts) and shows an `↑ vX.Y.Z` chip when it is newer.\n *\n * Layout: exactly two full-width rows, each a single horizontal line with\n * the label on the left and the value on the right — a compact definition\n * list instead of a multi-cell grid.\n */\n\nimport type * as ReactNS from 'react'\nimport { fetchLatestVersion, isNewerVersion } from '../latestVersion'\nimport { PLUGIN_NAME, PLUGIN_REPO, PLUGIN_REPO_SHORT, PLUGIN_VERSION } from '../meta'\nimport type { ViewKit } from '../viewkit'\n\nimport { React } from '../react'\n\nexport function makePluginInfo(kit: ViewKit): () => ReactNS.ReactElement {\n const { t } = kit\n const row = (label: string, value: ReactNS.ReactNode, href: string) => (\n <a className=\"lc-pi-row\" href={href} target=\"_blank\" rel=\"noreferrer\">\n <div className=\"lc-pi-label\">{label}</div>\n <div className=\"lc-pi-value\">{value}</div>\n </a>\n )\n return function PluginInfo(): ReactNS.ReactElement {\n const [latest, setLatest] = React.useState<string | null>(null)\n React.useEffect(() => {\n // Dev bundles carry a `0.0.0-dev` placeholder version: skip the check.\n if (PLUGIN_VERSION.includes('-dev')) return\n let on = true\n // Fire-and-forget: fetchLatestVersion never rejects (every failure\n // narrows to null), and the `on` flag drops late results.\n void fetchLatestVersion().then((v) => { if (on && v) setLatest(v) })\n return () => { on = false }\n }, [])\n const update = latest !== null && isNewerVersion(latest, PLUGIN_VERSION) ? latest : null\n const nameValue: ReactNS.ReactNode[] = [PLUGIN_NAME + ' (v' + PLUGIN_VERSION + ')']\n if (update) nameValue.push(<span key=\"update\" className=\"lc-pi-update\">{'↑ v' + update}</span>)\n return (\n <div className=\"lc-card\">\n <div className=\"lc-card-title\">\n <span className=\"lc-card-title-text\">{t('plugin.title')}</span>\n <span className=\"lc-card-sub\">{t('plugin.hint')}</span>\n </div>\n <div className=\"lc-pi-grid\">\n {row(t('plugin.name'), nameValue, PLUGIN_REPO + '/releases')}\n {row(t('plugin.github'), PLUGIN_REPO_SHORT, PLUGIN_REPO)}\n </div>\n </div>\n )\n }\n}\n","/**\n * RequestDetail — the breakdown panel under the history chart for the\n * active (hovered/pinned/newest) request. The header names the request and,\n * when the bar carries a boundary event, a ✂ chip shows where the event\n * happened (the gap between the request before and after). JSX component.\n */\n\nimport type * as ReactNS from 'react'\nimport type { ContextEventRecord, RequestRecord } from '../../shared/types'\nimport { partsOf, CATS } from '../categories'\nimport type { StackedBarProps } from './stackedBar'\nimport type { ViewKit } from '../viewkit'\n\nimport { React } from '../react'\n\nexport interface RequestDetailProps {\n request: RequestRecord | null\n /** The boundary event attached to this request (✂ chip in the header). */\n marker?: ContextEventRecord | null\n}\n\nexport function makeRequestDetail(\n kit: ViewKit,\n StackedBar: (props: StackedBarProps) => ReactNS.ReactElement,\n): (props: RequestDetailProps) => ReactNS.ReactElement | null {\n const { t, fmt, fmtTime, catLabel, eventLabel, eventAt } = kit\n return function RequestDetail(props: RequestDetailProps): ReactNS.ReactElement | null {\n const req = props.request\n if (!req) return null\n // Turn aggregates are labeled with their step count, and the breakdown\n // below is explicitly tagged as the turn's LAST step (that is the record\n // the bar carries).\n const isTurn = req.stepCount !== undefined && req.stepCount > 1\n const head = isTurn\n ? t('detail.turn', { t: req.turn ?? 0, n: req.stepCount ?? 0 })\n : t('detail.step', { t: req.turn ?? 0, s: req.step ?? 0 })\n // When this bar carries a boundary event (compaction/prune), the header\n // also shows WHERE the event happened: the gap between the request\n // before and the request after (e.g. \"✂ Turn 49 · Step 2→3\").\n const marker = props.marker ?? null\n const markerAt = marker !== null ? eventAt(marker) : null\n return (\n <div className=\"lc-detail\">\n <div className=\"lc-detail-head\">\n <b>{head}</b>\n {marker !== null && markerAt !== null\n ? <span className=\"lc-detail-marker\" title={eventLabel(marker)}>{'✂ ' + markerAt}</span>\n : null}\n {isTurn ? <span className=\"lc-detail-tag\">{t('detail.lastStep')}</span> : null}\n <span>{fmtTime(req.time)}</span>\n <span>{t('detail.estTotal', { n: fmt(req.total) })}</span>\n {req.prompt !== undefined\n ? <span className=\"lc-actual\">{t('detail.actual', { n: fmt(req.prompt) })}</span>\n : null}\n {req.output !== undefined\n ? <span>{t('detail.output', { n: fmt(req.output) })}</span>\n : null}\n </div>\n <StackedBar parts={partsOf(req)} height={10} />\n <div className=\"lc-detail-rows\">\n {CATS.map((c) => {\n const v = req[c.key] || 0\n return (\n <div key={c.key} className=\"lc-detail-row\">\n <i style={{ background: c.color }} />\n <span className=\"lc-detail-label\">{catLabel(c.key)}</span>\n <span className=\"lc-bar-track\">\n <span className=\"lc-bar-fill\" style={{ width: `${req.total > 0 ? v / req.total * 100 : 0}%`, background: c.color }} />\n </span>\n <span className=\"lc-detail-num\">{'≈' + fmt(v)}</span>\n <span className=\"lc-detail-pct\">{req.total > 0 ? `${Math.round(v / req.total * 100)}%` : ''}</span>\n </div>\n )\n })}\n </div>\n </div>\n )\n }\n}\n","/**\n * Session-cost estimate — prices the host-folded cumulative billed-token\n * totals (SessionCostUsage) with DeepSeek's V4 list prices, HARDCODED for\n * now (per request; revisit when DeepSeek adjusts prices). Source:\n * https://api-docs.deepseek.com/quick_start/pricing/ (USD) and\n * https://api-docs.deepseek.com/zh-cn/quick_start/pricing/ (CNY).\n *\n * Peak windows are 01:00-04:00 and 06:00-10:00 UTC (off-peak is half the\n * peak rate); the Host already split the totals by period, so pricing here\n * is a pure lookup. Both currencies the UI ships are tabulated — the locale\n * picks which one the stats board shows.\n */\n\nimport type { CostBucketTotals, SessionCostUsage } from '../shared/types'\nimport { numOf } from './services'\n\n/** Per-1M-token rates: cache-hit input, cache-miss input, output. */\nexport interface PriceTriple { hit: number; miss: number; out: number }\n\nconst PRICES = {\n usd: {\n flash: { peak: { hit: 0.014, miss: 0.44, out: 1.32 }, off: { hit: 0.007, miss: 0.22, out: 0.66 } },\n pro: { peak: { hit: 0.044, miss: 1.32, out: 3.96 }, off: { hit: 0.022, miss: 0.66, out: 1.98 } },\n },\n cny: {\n flash: { peak: { hit: 0.10, miss: 3.0, out: 9.0 }, off: { hit: 0.05, miss: 1.5, out: 4.5 } },\n pro: { peak: { hit: 0.30, miss: 9.0, out: 27.0 }, off: { hit: 0.15, miss: 4.5, out: 13.5 } },\n },\n} as const\n\nexport type CostCurrency = keyof typeof PRICES\n\n/**\n * Price the session's cumulative billed-token totals. Cache reads bill at\n * the hit rate; uncached input AND cache writes bill at the miss rate;\n * output (reasoning included) bills at the out rate. Null when nothing was\n * priced (no DeepSeek V4 usage folded yet), so the cell can show a dash.\n */\nexport function estimateSessionCost(usage: SessionCostUsage | null | undefined, currency: CostCurrency): number | null {\n if (usage === null || usage === undefined) return null\n let total = 0\n let any = false\n for (const family of ['flash', 'pro'] as const) {\n const fam = usage[family]\n if (fam === undefined) continue\n for (const period of ['peak', 'off'] as const) {\n const b: CostBucketTotals | undefined = fam[period]\n if (b === undefined) continue\n const p: PriceTriple = PRICES[currency][family][period]\n total += (numOf(b.cacheRead) * p.hit + (numOf(b.uncached) + numOf(b.cacheWrite)) * p.miss + numOf(b.output) * p.out) / 1e6\n any = true\n }\n }\n return any ? total : null\n}\n\n/** Short money format: two decimals at and above one unit, two significant digits below. */\nexport function formatCost(amount: number, currency: CostCurrency): string {\n const symbol = currency === 'cny' ? '¥' : '$'\n return symbol + (amount >= 1 ? amount.toFixed(2) : amount.toPrecision(2))\n}\n\n/**\n * All priced model families for one currency, in display order, with their\n * peak/off-peak rate triples — the raw material of the stats-board tooltip's\n * price list. The numbers stay hardcoded in PRICES above; this function only\n * reshapes the table for display, so what the tooltip prints can never drift\n * from the math that prices the session.\n */\nexport function sessionPrices(currency: CostCurrency): { family: string; peak: PriceTriple; off: PriceTriple }[] {\n return (['flash', 'pro'] as const).map(id => ({\n family: id === 'flash' ? 'deepseek-v4-flash' : 'deepseek-v4-pro',\n peak: PRICES[currency][id].peak,\n off: PRICES[currency][id].off,\n }))\n}\n\n/** Price-list figure: the same money format as formatCost, trailing zeros trimmed (¥3.00 → ¥3, $0.0070 → $0.007). */\nexport function formatPriceRate(amount: number, currency: CostCurrency): string {\n return formatCost(amount, currency).replace(/0+$/, '').replace(/\\.$/, '')\n}\n","/**\n * StatsBoard — the session context statistics card above the composition:\n * conversation size (turns/steps), context churn (compaction count,\n * prune count, injection count), the cache-hit share, and the estimated\n * cumulative session cost. The counts cover the retained history window,\n * matching the History chart; the cache-hit figure reuses the official\n * token-meter `tokenUsage` projection verbatim — the exact same data and\n * formula as the chat stats line below the input box — and the cost cell\n * prices the host-folded cumulative billed-token totals (complete session\n * log) with the hardcoded DeepSeek V4 list prices (cost.ts), in the\n * locale's currency. The cost cell's hover bubble (a \"?\" marker plus a\n * styled DOM tip — the harness GUI never shows native `title` tooltips)\n * explains the whole-session estimate and lists the per-1M-token price\n * table straight from cost.ts, so the printed rates can never drift from\n * the math. JSX component.\n */\n\nimport type * as ReactNS from 'react'\nimport type { ContextEventRecord, RequestRecord, SessionCostUsage, TokenUsage } from '../../shared/types'\nimport { estimateSessionCost, formatCost, formatPriceRate, sessionPrices } from '../cost'\nimport type { CostCurrency } from '../cost'\nimport { numOf } from '../services'\nimport type { ViewKit } from '../viewkit'\n\nimport { React } from '../react'\n\n/**\n * Cache-hit share of billed prompt-side input — same buckets as the harness's\n * chat stats line below the input box (`cacheReadTokens` over the three\n * disjoint billed buckets: uncached + reads + writes). Unlike that line's\n * whole-percent rounding, this one TRUNCATES to two decimal places (cut, not\n * round). Null when no input was billed. A tiny epsilon keeps a double stored\n * a hair below a cent boundary (e.g. 80.00 as 79.9999999999…) from losing its\n * last digit — with integer token counts no genuine value ever sits that close\n * to a boundary, so the epsilon can only absorb float noise. Bucket reads go\n * through numOf so a malformed payload degrades to a dash instead of NaN text.\n */\nfunction cacheHitPercent(usage: TokenUsage): string | null {\n const uncached = numOf(usage.uncachedInputTokens)\n const reads = numOf(usage.cacheReadTokens)\n const writes = numOf(usage.cacheWriteTokens)\n const billed = uncached + reads + writes\n if (billed === 0) return null\n const hundredths = Math.trunc((reads / billed) * 10000 + 1e-9)\n return `${Math.floor(hundredths / 100)}.${String(hundredths % 100).padStart(2, '0')}`\n}\n\nexport function makeStatsBoard(kit: ViewKit): (props: {\n requests: RequestRecord[]\n events: ContextEventRecord[]\n usage: TokenUsage | null\n /** Session-cost raw material from the timeline (undefined: nothing priced). */\n cost?: SessionCostUsage\n /** Active locale id — zh prices in CNY, everything else in USD. */\n locale: string\n}) => ReactNS.ReactElement {\n const { t, fmt } = kit\n return function StatsBoard(props: {\n requests: RequestRecord[]\n events: ContextEventRecord[]\n usage: TokenUsage | null\n cost?: SessionCostUsage\n locale: string\n }): ReactNS.ReactElement {\n const turns = new Set<number>()\n let steps = 0, compactions = 0, prunes = 0, injects = 0\n for (const req of props.requests) {\n turns.add(req.turn ?? 0)\n steps++\n }\n for (const ev of props.events) {\n if (ev.kind === 'compaction') compactions++\n else if (ev.kind === 'prune') prunes++\n else if (ev.kind === 'inject') injects++\n }\n const hit = props.usage !== null ? cacheHitPercent(props.usage) : null\n const currency: CostCurrency = props.locale === 'zh' ? 'cny' : 'usd'\n const cost = estimateSessionCost(props.cost, currency)\n const fmtRate = (n: number) => formatPriceRate(n, currency)\n // Cost-cell tooltip content: the intro sentence (whole-session estimate,\n // peak/off-peak windows) followed by the actual per-1M-token price list\n // for the locale's currency, straight from cost.ts's PRICES table.\n const costTip: ReactNS.ReactNode = [\n t('stats.costTip'),\n <span key=\"prices\" className=\"lc-stat-tip-prices\">\n <span className=\"lc-stat-tip-head\">{t('stats.costPriceHead')}</span>\n {sessionPrices(currency).map(r => (\n <span key={r.family} className=\"lc-stat-tip-row\">\n <b className=\"lc-stat-tip-model\">{r.family}</b>\n {' '}{t('stats.costHit')} {fmtRate(r.peak.hit)}/{fmtRate(r.off.hit)}\n {' · '}{t('stats.costMiss')} {fmtRate(r.peak.miss)}/{fmtRate(r.off.miss)}\n {' · '}{t('stats.costOut')} {fmtRate(r.peak.out)}/{fmtRate(r.off.out)}\n </span>\n ))}\n </span>,\n ]\n // A cell may carry an explanation bubble: the label then shows a \"?\"\n // marker and the styled tip (`.lc-stat-tip`, revealed on cell hover) —\n // the native `title` attribute is invisible in the harness GUI.\n const cell = (label: string, value: string, tip?: ReactNS.ReactNode) => (\n <div className={'lc-stat' + (tip === undefined ? '' : ' lc-stat-tipped')}>\n <span className=\"lc-stat-label\">\n {label}\n {tip !== undefined && <i className=\"lc-stat-q\" aria-hidden=\"true\">?</i>}\n </span>\n <b className=\"lc-stat-value\">{value}</b>\n {tip !== undefined && <span className=\"lc-stat-tip\" role=\"tooltip\">{tip}</span>}\n </div>\n )\n return (\n <div className=\"lc-card lc-col lc-col-stats\">\n <div className=\"lc-card-title\">\n <span className=\"lc-card-title-text\">{t('stats.title')}</span>\n <span className=\"lc-card-sub\">{t('stats.hint')}</span>\n </div>\n <div className=\"lc-stats\">\n {cell(t('stats.turns'), fmt(turns.size))}\n {cell(t('stats.steps'), fmt(steps))}\n {cell(t('stats.injects'), fmt(injects))}\n {cell(t('stats.compactions'), fmt(compactions))}\n {cell(t('stats.prunes'), fmt(prunes))}\n {cell(t('stats.cacheHit'), hit === null ? '—' : hit + '%')}\n {cell(t('stats.cost'), cost === null ? '—' : formatCost(cost, currency), costTip)}\n </div>\n </div>\n )\n }\n}\n","/**\n * TrendChart — the per-request history chart: fixed-width stacked bars with\n * a horizontal scroll (newest anchored right), a turn color strip below,\n * ✂ markers for boundary events, and edge fades. Includes the data\n * preparation helpers (aggregateByTurn, attachMarkers) used by ContextView.\n * JSX component; the chart chrome is bespoke data-viz (no shared primitive),\n * styled through the shared `--dsw-alias-*` tokens.\n */\n\nimport type * as ReactNS from 'react'\nimport type { ContextEventRecord, RequestRecord } from '../../shared/types'\nimport { CATS } from '../categories'\nimport type { ViewKit } from '../viewkit'\n\nimport { React } from '../react'\n\nexport interface TrendChartProps {\n requests: RequestRecord[]\n /** One boundary event (compaction/prune) per request index, if attached. */\n markers: (ContextEventRecord | undefined)[]\n selectedSeq: number | null\n hoveredSeq: number | null\n /** The turn currently highlighted (from the turn strip or a hovered bar). */\n activeTurn: number | null\n /** Display granularity; a switch re-anchors the chart at the newest bars. */\n granularity: 'step' | 'turn'\n onSelect: (seq: number | null) => void\n onHover: (seq: number | null) => void\n onHoverTurn: (turn: number | null) => void\n}\n\n/**\n * Collapse a per-step request timeline into one bar per turn: each turn is\n * represented by its LAST step's record (the context state when the turn\n * finished), tagged with the number of steps the turn spans so the bar can\n * keep the turn's column width and the detail can label it. Requests of one\n * turn are consecutive in the log, so a run of equal turns is replaced by\n * its final record.\n */\nexport function aggregateByTurn(requests: RequestRecord[]): RequestRecord[] {\n const out: RequestRecord[] = []\n let runSteps = 0\n for (const req of requests) {\n const last = out.length > 0 ? out[out.length - 1] : null\n if (last !== null && (last.turn ?? 0) === (req.turn ?? 0)) {\n runSteps++\n out[out.length - 1] = { ...req, stepCount: runSteps }\n } else {\n runSteps = 1\n out.push({ ...req, stepCount: 1 })\n }\n }\n return out\n}\n\n/**\n * Attach each boundary event (compaction/prune) to the first request\n * logged after it — one entry per request index, for the ✂ marker above\n * the bar and the range chip in the detail header. Shared by TrendChart\n * and the detail panel so both show the SAME event for a request.\n */\nexport function attachMarkers(requests: RequestRecord[], events: ContextEventRecord[]): (ContextEventRecord | undefined)[] {\n const markers: (ContextEventRecord | undefined)[] = new Array<ContextEventRecord | undefined>(requests.length)\n for (const ev of events) {\n if (ev.kind !== 'compaction' && ev.kind !== 'prune') continue\n for (let r = 0; r < requests.length; r++) {\n if (requests[r].seq >= ev.seq) {\n if (markers[r] === undefined) markers[r] = ev\n break\n }\n }\n }\n return markers\n}\n\nexport function makeTrendChart(kit: ViewKit): (props: TrendChartProps) => ReactNS.ReactElement {\n const { t, fmt, fmtTime, eventLabel, eventAt } = kit\n\n // Plot height in px (the marker lane above it is 18px).\n const CHART_H = 112\n // Fixed column geometry: constant bar width keeps sparse histories from\n // stretching bars, and dense histories scroll horizontally instead of\n // compressing. The turn strip below mirrors the same column grid.\n const BAR_W = 14\n const BAR_GAP = 2\n // Turn strip fills: a neutral zebra, deliberately DISJOINT from the\n // category palette — the strip sits directly under the bars, and the old\n // per-turn palette (identical to the six category colors) made it read as\n // a detached, misaligned bottom segment of the composition bars.\n const TURN_FILLS = ['rgba(128,128,128,0.12)', 'rgba(128,128,128,0.26)']\n\n return function TrendChart(props: TrendChartProps): ReactNS.ReactElement {\n const requests = props.requests\n const markers = props.markers\n // Anchor each bar to the provider-reported prompt size when the request\n // carried usage: the heuristic categories keep their ratios but the bar\n // HEIGHT tracks the real billed tokens (matching the overview card and\n // the official chat ring) instead of the underpriced raw estimate.\n const anchorOf = (req: RequestRecord): number =>\n typeof req.prompt === 'number' && req.prompt > 0 && req.total > 0 ? req.prompt / req.total : 1\n const barTotalOf = (req: RequestRecord): number =>\n typeof req.prompt === 'number' && req.prompt > 0 ? req.prompt : req.total\n let maxTotal = 1\n for (const req of requests) {\n const bt = barTotalOf(req)\n if (bt > maxTotal) maxTotal = bt\n }\n\n // Consecutive requests of the same turn collapse into one labeled range.\n // `span` is the number of STEP columns the group covers (step records\n // count one each). In turn granularity the bars are uniform width, so\n // the strip blocks are uniform too; in step granularity they span their\n // steps' columns. Either way bars and blocks stay aligned.\n const groups: { turn: number; count: number; span: number; agg: boolean }[] = []\n for (const req of requests) {\n let grp = groups.length > 0 ? groups[groups.length - 1] : null\n if (grp === null || grp.turn !== (req.turn ?? 0)) {\n grp = { turn: req.turn ?? 0, count: 0, span: 0, agg: req.stepCount !== undefined }\n groups.push(grp)\n }\n grp.count++\n grp.span += req.stepCount ?? 1\n }\n\n // Default anchor: the newest bars at the RIGHT edge. The first layout\n // after mount scrolls unconditionally; a GRANULARITY SWITCH re-anchors\n // the same way (returning to step mode must show the newest bars, not\n // the stale left edge from the narrow turn chart); otherwise the chart\n // only sticks to the end while the user is already near it (scrolling\n // away is respected). useLayoutEffect avoids a first-paint flash at the\n // left. Edge fades stay in sync with the scroll position.\n const scrollRef = React.useRef<HTMLDivElement | null>(null)\n const scrolledOnce = React.useRef(false)\n const lastGranRef = React.useRef(props.granularity)\n const [edges, setEdges] = React.useState<{ left: boolean; right: boolean }>({ left: false, right: false })\n // Mirror of the last computed fades. The layout effect below runs after\n // EVERY render (no deps), so it must not dispatch a setState unless the\n // values truly changed: on a granularity switch the first dispatch\n // schedules a sync re-render whose fiber still has pending lanes, which\n // disables React's same-value eager bailout — every subsequent commit\n // then enqueues yet another update and the queue grows without bound\n // (React error #185, maximum update depth — the tab whites out).\n const edgesRef = React.useRef(edges)\n const updateEdges = (el: HTMLDivElement): void => {\n const left = el.scrollLeft > 4\n const right = el.scrollLeft + el.clientWidth < el.scrollWidth - 4\n const prev = edgesRef.current\n if (prev.left === left && prev.right === right) return\n edgesRef.current = { left, right }\n setEdges({ left, right })\n }\n React.useLayoutEffect(() => {\n const el = scrollRef.current\n if (el === null) return\n if (props.granularity !== lastGranRef.current) {\n lastGranRef.current = props.granularity\n scrolledOnce.current = false // re-anchor on every granularity switch\n }\n if (!scrolledOnce.current) {\n scrolledOnce.current = true\n el.scrollLeft = el.scrollWidth\n } else if (el.scrollLeft + el.clientWidth >= el.scrollWidth - 24) {\n el.scrollLeft = el.scrollWidth\n }\n updateEdges(el)\n })\n\n // Compact single-line hover tooltip (shown instantly by the custom\n // `.lc-chart-tip`, replacing the delayed native title): position, time,\n // estimated total, and the provider-reported prompt when available. The\n // per-category breakdown lives in the detail panel below.\n const tipOf = (req: RequestRecord): string => {\n const head = req.stepCount !== undefined && req.stepCount > 1\n ? t('tip.turn', { t: req.turn ?? 0, n: req.stepCount })\n : t('tip.step', { t: req.turn ?? 0, s: req.step ?? 0 })\n return head + ' · ' + fmtTime(req.time) + ' · ' + t('tip.total', { n: fmt(req.total) })\n + (req.prompt !== undefined ? ' · ' + t('tip.actual', { n: fmt(req.prompt) }) : '')\n }\n const hoveredIdx = props.hoveredSeq !== null ? requests.findIndex(r => r.seq === props.hoveredSeq) : -1\n const hoveredReq = hoveredIdx >= 0 ? requests[hoveredIdx] : null\n\n return (\n <div className=\"lc-chartrow\">\n <div className=\"lc-axis\">\n <span className=\"lc-axis-top\">{fmt(maxTotal)}</span>\n <span className=\"lc-axis-mid\">{fmt(Math.round(maxTotal / 2))}</span>\n <span className=\"lc-axis-bot\">{'0'}</span>\n </div>\n <div\n // Turn-aware dim scope: while a turn is focused (bar or strip hover),\n // bars and strip blocks OUTSIDE the active turn fade to 35%.\n className={'lc-chart-scroll' + (props.activeTurn !== null ? ' lc-chart-dim' : '')}\n ref={scrollRef}\n onScroll={(e: ReactNS.UIEvent<HTMLDivElement>) => { updateEdges(e.currentTarget) }}\n >\n {/* Edge fades: visible whenever more history sits beyond the viewport,\n so the horizontal scroll affordance is obvious. */}\n {edges.left ? <div className=\"lc-chart-fade lc-chart-fade-l\" /> : null}\n {/* Hovering a bar previews it in the detail below; leaving the plot\n clears the preview (a pinned selection, if any, takes over again). */}\n <div\n className=\"lc-chart\"\n onMouseLeave={() => { props.onHover(null) }}\n >\n <div className=\"lc-grid lc-grid-top\" />\n <div className=\"lc-grid lc-grid-mid\" />\n {requests.map((req, i) => {\n const marker = markers[i]\n const markerAt = marker !== undefined ? eventAt(marker) : null\n const selected = props.selectedSeq === req.seq\n const hovered = props.hoveredSeq === req.seq\n const inTurn = props.activeTurn !== null && (req.turn ?? 0) === props.activeTurn\n return (\n <div\n key={req.seq}\n // Uniform column width in BOTH granularities: turn aggregates\n // keep the same fixed width as step bars.\n className={'lc-bar'\n + (selected ? ' lc-bar-selected' : '')\n + (hovered ? ' lc-bar-hovered' : '')\n + (inTurn ? ' lc-bar-in-turn' : '')}\n style={{ width: `${BAR_W}px` }}\n onClick={() => { props.onSelect(selected ? null : req.seq) }}\n onMouseEnter={() => { props.onHover(req.seq) }}\n >\n {/* The ✂ tooltip names the event AND where it happened: the\n gap between the request before and the request after. */}\n {marker !== undefined ? (\n <span\n className=\"lc-bar-marker\"\n title={'✂ ' + (markerAt !== null ? markerAt + ' — ' : '') + eventLabel(marker)}\n >{'✂'}</span>\n ) : null}\n <div className=\"lc-bar-stack\">\n {CATS.map((c) => {\n const v = (req[c.key] || 0) * anchorOf(req)\n if (!v) return null\n // px heights: the stack's height is content-driven, so\n // percentage heights would collapse against an indefinite base.\n return <div key={c.key} style={{ height: `${Math.max(1, Math.round(v / maxTotal * CHART_H))}px`, background: c.color }} />\n })}\n </div>\n </div>\n )\n })}\n </div>\n {/* Instant hover tooltip, glued to its bar's column (it lives in the\n scrolling content, so it follows the bar while the chart scrolls). */}\n {hoveredReq !== null ? (\n <div\n className=\"lc-chart-tip\"\n style={{ left: `${hoveredIdx * (BAR_W + BAR_GAP) + BAR_W / 2}px` }}\n >{tipOf(hoveredReq)}</div>\n ) : null}\n {/* Turn strip: one COLOR BLOCK per turn, spanning exactly its bars'\n columns, so the partition reads at a glance and lines up with the\n steps above. Hovering a block highlights that turn's bars in the\n chart (and hovering a bar highlights its block — the active turn\n is shared hover-only state). */}\n <div className=\"lc-turns\" onMouseLeave={() => { props.onHoverTurn(null) }}>\n {groups.map((grp, gi) => {\n // Turn mode: uniform blocks under uniform bars (1:1). Step mode:\n // blocks span their steps' columns. The flex gap between blocks\n // mirrors the bar gap, so blocks always line up with the bars.\n const on = props.activeTurn === grp.turn\n const blockW = grp.agg ? BAR_W : grp.span * (BAR_W + BAR_GAP) - BAR_GAP\n return (\n <span\n key={`turn-${gi}`}\n className={'lc-turn' + (on ? ' lc-turn-on' : '')}\n style={{\n width: `${blockW}px`,\n background: TURN_FILLS[gi % TURN_FILLS.length],\n }}\n title={`T${grp.turn}`}\n onMouseEnter={() => { props.onHoverTurn(grp.turn) }}\n >{`T${grp.turn}`}</span>\n )\n })}\n </div>\n </div>\n {edges.right ? <div className=\"lc-chart-fade lc-chart-fade-r\" /> : null}\n </div>\n )\n }\n}\n","/**\n * ContextView — the root component of the Context tab: renders the\n * `contextTimeline` session projection delivered by the framework (finished\n * value, pushed by the Host half) and composes the stats board, composition\n * bar, history chart + detail, events and message columns.\n *\n * JSX functional component. All data comes through the framework standard\n * kit (`useProjection`); the component never calls any RPC and holds no\n * cache — the harness owns the projection pipeline end to end.\n */\n\nimport type * as ReactNS from 'react'\nimport type { ContextEventRecord, RequestRecord } from '../../shared/types'\nimport { headlineOf } from '../headline'\nimport type { SessionStandardProps } from '../services'\nimport { contextPressureOf, headersOf, timelineOf, tokenUsageOf } from '../services'\nimport type { ClientCtx, ConversationFace, ImageRefLike } from '../services'\nimport type { ViewKit } from '../viewkit'\nimport { makeContextBrowser } from './browser'\nimport { makeCurrentComposition } from './currentComposition'\nimport { makeEventList } from './events'\nimport { makeNodeList } from './nodes'\nimport { makePluginInfo } from './pluginInfo'\nimport { makeRequestDetail } from './requestDetail'\nimport { makeStatsBoard } from './statsBoard'\nimport { makeLegend, makeStackedBar } from './stackedBar'\nimport { aggregateByTurn, attachMarkers, makeTrendChart } from './trendChart'\n\nimport { React, h } from '../react'\nimport { makeErrorBoundary } from './errorBoundary'\n\n// The context page scrolls inside the conversation's shared page scroller\n// (`[data-conversation-scroll]`) — the same container the chat auto-scrolls\n// to the bottom on every visit. Without a position ledger of its own, a\n// context mount inherits wherever the chat left that container, so the tab\n// opens at the bottom and stays locked there (each chat visit re-scrolls it).\n// Mirror the chat's chatScroll pattern: remember where the reader left each\n// session's context page (module-level, so it survives tab remounts) and\n// restore it once the content renders — first visits start at the top.\nconst viewScroll = new Map<string, number>()\n\n// The four event kinds, in display order (toggles + filter share the list).\nconst EVENT_KINDS = ['inject', 'compaction', 'prune', 'model'] as const\n\nexport type ContextViewProps = SessionStandardProps\n\nexport function makeContextView(ctx: ClientCtx, kit: ViewKit): (props: ContextViewProps) => ReactNS.ReactElement {\n const { t } = kit\n const StackedBar = makeStackedBar(kit)\n const Legend = makeLegend(kit)\n const CurrentComposition = makeCurrentComposition(kit, StackedBar, Legend)\n const TrendChart = makeTrendChart(kit)\n const RequestDetail = makeRequestDetail(kit, StackedBar)\n const EventList = makeEventList(kit)\n const NodeList = makeNodeList(kit)\n const StatsBoard = makeStatsBoard(kit)\n const PluginInfo = makePluginInfo(kit)\n const ContextBrowser = makeContextBrowser(kit, StackedBar)\n const ErrorBoundary = makeErrorBoundary(t)\n\n // The data-driven body lives inside the error boundary: any render error\n // (a corrupt projection value that slips past the timelineOf shape guard,\n // a framework surprise) degrades to a styled error card inside the tab\n // instead of white-screening the whole conversation view. The boundary is\n // a separate component with NO hooks of its own, so the body's hook order\n // and the loading/data control flow stay exactly as they were.\n function ContextViewBody(props: ContextViewProps): ReactNS.ReactElement {\n const sessionId = props.sessionId\n // The finished value the harness pushes for this session: the\n // `contextTimeline` projection key (capability-absent until a value\n // arrives -> loading screen, mirroring the old first-poll wait).\n const data = typeof props.useProjection === 'function'\n ? timelineOf(props.useProjection('contextTimeline'))\n : null\n // Provider-anchored occupancy comes from the OFFICIAL token-meter\n // `contextPressure` projection (the same key the chat's context ring\n // reads) — token-meter owns estimation and replay, the Host no longer\n // mirrors it. Absent key/value degrades to the derived fallback.\n const pressure = typeof props.useProjection === 'function'\n ? contextPressureOf(props.useProjection('contextPressure'))\n : null\n // Durable provider-reported usage comes from the OFFICIAL token-meter\n // `tokenUsage` projection — the exact same data the chat stats line below\n // the input box reads for its \"缓存命中\" figure, so the stats board's\n // cache-hit cell reuses it verbatim. Absent key/value drops the cell to a\n // dash instead of estimating.\n const usage = typeof props.useProjection === 'function'\n ? tokenUsageOf(props.useProjection('tokenUsage'))\n : null\n // The header-content companion projection (full system prompt + tool\n // schemas) for the Context browser card; absent key = older Host half,\n // the card degrades those sections to tokens-only with a note.\n const headers = typeof props.useProjection === 'function'\n ? headersOf(props.useProjection('contextHeaders'))\n : null\n const [selectedSeq, setSelectedSeq] = React.useState<number | null>(null)\n const [hoveredSeq, setHoveredSeq] = React.useState<number | null>(null)\n const [hoverTurn, setHoverTurn] = React.useState<number | null>(null)\n const [tick, setTick] = React.useState(0)\n const [granularity, setGranularity] = React.useState<'step' | 'turn'>('step')\n // Shared hover link between the composition bar and its legend below.\n const [hoverCat, setHoverCat] = React.useState<string | null>(null)\n // Kind picker for the events column, every kind picked by default (all\n // shown). Clicking an unpicked kind adds it (A -> A+B -> ...); clicking\n // the only remaining picked kind resets to all; clicking a picked kind\n // among several removes it.\n const [pickedKinds, setPickedKinds] = React.useState<string[]>([...EVENT_KINDS])\n const toggleKind = (k: string) => {\n setPickedKinds((p) => {\n // All picked -> narrow to this kind only (that's the \"点击后只显示该分类\" entry).\n if (p.length === EVENT_KINDS.length) return [k]\n // Unpicked -> add it (A -> A+B -> ...).\n if (!p.includes(k)) return [...p, k]\n // Picked -> remove it; removing the last one resets to all.\n return p.length === 1 ? [...EVENT_KINDS] : p.filter(x => x !== k)\n })\n }\n // Tool-link bridge to the Context browser: clicking the overview's\n // \"工具定义 Top\" label (category focus) or one of its chips (specific\n // tool focus) asks the browser to reveal the corresponding section.\n // One-shot — the browser applies it and clears it back through\n // `onToolFocusHandled`, so clicking the same chip again re-triggers.\n const [toolFocus, setToolFocus] = React.useState<{ tool?: string } | null>(null)\n const clearToolFocus = React.useCallback(() => { setToolFocus(null) }, [])\n\n // Session-authorized durable-image loader for the Context browser's\n // attachment cards, resolved through the harness conversation service —\n // the same `resolveImage` the chat history's message images ride on.\n // Absent service (or a missing session id) degrades the cards to\n // metadata-only, never an error.\n const loadImage = React.useMemo(() => {\n if (typeof sessionId !== 'string' || sessionId === '') return undefined\n const conversation = ctx.get('conversation') as ConversationFace | undefined\n if (conversation === undefined || typeof conversation.resolveImage !== 'function') return undefined\n return (attachment: ImageRefLike) => conversation.resolveImage(sessionId, attachment)\n }, [sessionId])\n\n // ---- page-scroller ownership (see `viewScroll` above) ----\n const rootRef = React.useRef<HTMLDivElement | null>(null)\n const scrollerRef = React.useRef<HTMLElement | null>(null)\n // The session whose position was already applied this mount: re-renders\n // must never re-apply, or they would yank the reader's scroll.\n const restoredRef = React.useRef<string | null>(null)\n\n // Restore this session's saved position (or the top on a first visit) as\n // soon as the content renders — a layout effect, so the reader never sees\n // the chat's bottom-anchored position flash in first.\n React.useLayoutEffect(() => {\n if (typeof sessionId !== 'string' || sessionId === '' || data === null) return\n if (restoredRef.current === sessionId) return\n restoredRef.current = sessionId\n const scroller = rootRef.current !== null\n ? rootRef.current.closest('[data-conversation-scroll]')\n : null\n if (scroller === null) return\n scrollerRef.current = scroller as HTMLElement\n scroller.scrollTop = viewScroll.get(sessionId) ?? 0\n }, [sessionId, data])\n\n // Save where the reader left this session's context page. Runs on unmount\n // (tab switch) and on session change — a layout-effect cleanup, so it\n // fires before the incoming view's own layout effects re-scroll the\n // shared container.\n React.useLayoutEffect(() => {\n return () => {\n if (typeof sessionId !== 'string' || sessionId === '') return\n const scroller = scrollerRef.current\n if (scroller === null) return\n viewScroll.set(sessionId, scroller.scrollTop)\n }\n }, [sessionId])\n\n // Re-render on locale switch.\n React.useEffect(() => {\n const localeSvc = ctx.get('locale')\n if (!localeSvc) return undefined\n return localeSvc.subscribe(() => { setTick(x => x + 1) })\n }, [])\n\n void tick\n\n if (!data) {\n return <div className=\"lc-root\" ref={rootRef}><div className=\"lc-empty\">{t('loading')}</div></div>\n }\n\n const requests = data.requests\n const events = data.events\n // The events column filters to the picked kinds (all picked = all shown);\n // the stats board keeps the full log regardless.\n const shownEvents = pickedKinds.length === EVENT_KINDS.length ? events : events.filter(e => pickedKinds.includes(e.kind))\n const nodes = data.nodes\n // Display granularity: one bar per step (default) or one bar per turn\n // (each turn shown by its LAST step's record).\n const displayRequests = granularity === 'turn' ? aggregateByTurn(requests) : requests\n // Boundary events attach to the first request after them; the same\n // attachment drives the ✂ marker above the bar and the detail chip.\n const markers = attachMarkers(displayRequests, events)\n const markerOf = (req: RequestRecord): ContextEventRecord | undefined => {\n const i = displayRequests.indexOf(req)\n return i >= 0 ? markers[i] : undefined\n }\n\n // The detail below follows the pointer: hover previews a bar, a pinned\n // click takes over when the pointer leaves, and both fall back to the\n // newest request. The active turn (for strip/bar highlighting) follows\n // the turn strip hover, or the hovered bar's turn.\n let pinnedReq: RequestRecord | null = null\n for (const req of displayRequests) if (req.seq === selectedSeq) pinnedReq = req\n let activeReq: RequestRecord | null = null\n if (hoveredSeq !== null) {\n for (const req of displayRequests) if (req.seq === hoveredSeq) activeReq = req\n }\n if (activeReq === null) activeReq = pinnedReq\n if (activeReq === null && displayRequests.length > 0) activeReq = displayRequests[displayRequests.length - 1]\n\n // The turn highlight is hover-only: the turn strip hover wins, then the\n // hovered bar's turn (no fallback — a pinned or default selection must\n // not keep a turn glowing).\n let activeTurn: number | null = hoverTurn\n if (activeTurn === null && hoveredSeq !== null) {\n for (const req of displayRequests) if (req.seq === hoveredSeq) { activeTurn = req.turn ?? null; break }\n }\n\n // Provider-anchored CURRENT occupancy from the official chat ring\n // (contextPressure.projectedTokens): the newest usage sample (input +\n // cache) carried forward by the heuristic surface movement since it was\n // taken. The provider's tokenizer counts the real billed tokens, which\n // the fixed 4-chars/token heuristic can undercount by ~10-15% on\n // CJK-heavy sessions — so this is the headline, and the heuristic\n // composition below is anchored to it (proportions stay heuristic).\n // Shared with the /context popup (headline.ts).\n const head = headlineOf(data, pressure)\n\n // The cost cell prices in the locale's currency (zh -> CNY, else USD);\n // read the active locale at render time — the locale subscription above\n // already re-renders on a switch. Older hosts without getLocale fall\n // back to USD.\n const localeSvc = ctx.get('locale')\n const activeLocale = localeSvc !== undefined && typeof localeSvc.getLocale === 'function'\n ? localeSvc.getLocale().active\n : 'en'\n\n return (\n <div className=\"lc-root\" ref={rootRef}>\n\n {/* ---- session context stats + plugin info, side by side (7 : 3) ---- */}\n <div className=\"lc-cols lc-head\">\n <StatsBoard requests={requests} events={events} usage={usage} cost={data.cost} locale={activeLocale} />\n <PluginInfo />\n </div>\n\n {/* ---- main split: overview + trend stacked in the left column,\n the context browser in the right column (shared lc-cols flex,\n wraps to one column on narrow widths) ---- */}\n <div className=\"lc-cols\">\n <div className=\"lc-col\">\n {/* ---- overview (shared CurrentComposition card) ---- */}\n <CurrentComposition\n head={head}\n subtitle={(data.model ? data.model : '') + (data.provider ? ' · ' + data.provider : '')}\n hoverKey={hoverCat}\n onHoverKey={setHoverCat}\n tools={data.toolList}\n onToolFocus={setToolFocus}\n />\n\n {/* ---- trend ---- */}\n <div className=\"lc-card\">\n <div className=\"lc-card-title\">\n <span className=\"lc-card-title-text\">{t('trend.title')}</span>\n <span className=\"lc-card-sub\">{t('trend.hint')}</span>\n <div className=\"lc-gran\">\n <button\n className={'lc-gran-btn' + (granularity === 'step' ? ' lc-gran-on' : '')}\n onClick={() => { setGranularity('step') }}\n >{t('gran.step')}</button>\n <button\n className={'lc-gran-btn' + (granularity === 'turn' ? ' lc-gran-on' : '')}\n onClick={() => { setGranularity('turn') }}\n >{t('gran.turn')}</button>\n </div>\n </div>\n {displayRequests.length === 0\n ? <div className=\"lc-empty\">{t('trend.empty')}</div>\n : (\n <div>\n <TrendChart\n // Remount per session: switching sessions re-anchors the chart\n // at the newest bars instead of inheriting stale scroll state.\n key={sessionId}\n // The host caps the log at 160 requests; render them ALL so\n // earlier turns/steps stay reachable via horizontal scroll.\n requests={displayRequests}\n markers={markers}\n selectedSeq={pinnedReq ? pinnedReq.seq : null}\n hoveredSeq={hoveredSeq}\n activeTurn={activeTurn}\n granularity={granularity}\n onSelect={setSelectedSeq}\n onHover={setHoveredSeq}\n onHoverTurn={setHoverTurn}\n />\n <RequestDetail request={activeReq} marker={activeReq !== null ? markerOf(activeReq) : undefined} />\n </div>\n )}\n </div>\n </div>\n\n {/* ---- context browser: the assembled content of the live surface\n or a picked step; follows the trend chart's hovered bar ---- */}\n <div className=\"lc-col\">\n <ContextBrowser\n data={data}\n headers={headers}\n useSession={props.useSession}\n loadOlderHistory={props.loadOlderHistory}\n previewSeq={hoveredSeq}\n // History-chart pin linkage: a clicked (locked) bar pins the\n // browser on that step; unpinning returns it to live.\n pinSeq={pinnedReq !== null ? pinnedReq.seq : null}\n // Shared current-composition hover link (bar + legend + browser\n // category rows); the browser joins only while it shows the\n // live step, gated inside the browser itself.\n hoverKey={hoverCat}\n onHoverKey={setHoverCat}\n // Tool-link bridge from the overview (\"工具定义 Top\" chips).\n toolFocus={toolFocus}\n onToolFocusHandled={clearToolFocus}\n loadImage={loadImage}\n />\n </div>\n </div>\n\n {/* ---- events + messages ---- */}\n <div className=\"lc-cols\">\n <div className=\"lc-card lc-col\">\n <div className=\"lc-card-title\">\n <span className=\"lc-card-title-text\">{t('events.title')}</span>\n <div className=\"lc-kinds\">\n {EVENT_KINDS.map(k => (\n <button\n key={k}\n className={'lc-gran-btn' + (pickedKinds.includes(k) ? ' lc-gran-on lc-kind-' + k : '')}\n onClick={() => { toggleKind(k) }}\n >{t('kind.' + k)}</button>\n ))}\n </div>\n </div>\n <EventList events={shownEvents} />\n </div>\n <div className=\"lc-card lc-col\">\n <div className=\"lc-card-title\">\n <span className=\"lc-card-title-text\">{t('nodes.title')}</span>\n <span className=\"lc-card-sub\">{t('nodes.hint')}</span>\n </div>\n <NodeList nodes={nodes} dropped={data.droppedNodes || 0} />\n </div>\n </div>\n\n <div className=\"lc-foot\">{t('footer')}</div>\n </div>\n )\n }\n\n return function ContextView(props: ContextViewProps): ReactNS.ReactElement {\n // The whole body — hooks, projection reads, derivation, and all child\n // cards — renders under the boundary (see ContextViewBody above).\n return h(ErrorBoundary, null, h(ContextViewBody, props))\n }\n}\n","/**\n * ViewKit — the shared dependency bag every component factory receives.\n * Built once per `makeView` (i.e. once per plugin apply): translation\n * (bound to the active locale), formatters, category labels, and the event\n * text helpers (event label + boundary range) that several components use.\n */\n\nimport type { ContextEventRecord } from '../shared/types'\nimport { fmt, fmtTime } from './format'\nimport { makeEventText } from './components/events'\nimport type { Translate } from './i18n'\n\nexport interface ViewKit {\n t: Translate\n fmt: typeof fmt\n fmtTime: typeof fmtTime\n catLabel: (key: string) => string\n eventLabel: (ev: ContextEventRecord) => string\n /** Where the event sits in the request timeline, as a label or null. */\n eventAt: (ev: ContextEventRecord) => string | null\n}\n\nexport function makeViewKit(t: Translate): ViewKit {\n const { eventLabel, eventAt } = makeEventText(t)\n return {\n t,\n fmt,\n fmtTime,\n catLabel: (key: string) => t('cat.' + key),\n eventLabel,\n eventAt,\n }\n}\n","/**\n * dsh-context — Client half (installed package bundle entry).\n *\n * Registers a \"上下文/Context\" tab in the conversation view ring\n * (`conversation.view` slot, beside Chat/Trajectory) and renders the\n * context-composition timeline: current makeup, per-request stacked-bar\n * history, context events, and the live message list.\n *\n * Since v0.9 the tab needs no custom data plane: the Host half pushes its\n * fold through the harness's session-projection pipeline\n * (`contextTimeline` projection key), and this half reads the finished value\n * from the framework standard kit (`useProjection('contextTimeline')`, a\n * standard prop on every session-scope slot component). No polling, no RPC,\n * no client-side cache.\n *\n * This module is the body of the package's `./client` bundle: tsdown\n * (tsdown.config.ts) bundles it (external `react` — the browser module table\n * supplies it via the injected `require`) into the web boot handoff\n * (`window.__ModuleLoader__.load({id, factory})`). All imports from other\n * client modules are inlined by the bundler; everything here is zero-runtime\n * beyond the bundled source.\n */\n\nimport { DICT_EN, DICT_ZH } from './i18n'\nimport { registerContextCommand } from './command'\nimport { makeContextModal } from './components/contextModal'\nimport { modalStoreOf } from './modalStore'\nimport type { ClientCtx, SessionsFace } from './services'\nimport { makeContextView } from './components/contextView'\nimport { makeViewKit } from './viewkit'\n\n// Theme-native styles: the bundle's global-CSS channel injects the sheet as\n// a plugin-owned <style data-plugin> tag at factory execution (the web boot\n// loader and the HMR receiver claim tags carrying data-plugin).\nimport './styles.css'\n\nimport { h } from './react'\n\nconst NS = 'dsh-context'\n\nfunction apply(ctx: ClientCtx): void {\n // Bilingual dictionaries; the tab label thunk and all UI text follow the\n // active locale through the bound translate (missing keys fall back to\n // zh, then the key itself). The registration rides ctx.effect, so a stop\n // or HMR reload disposes it.\n ctx.effect(() => {\n return ctx.locale.register(NS, { zh: DICT_ZH, en: DICT_EN })\n }, 'dsh-context: dictionaries')\n const t = ctx.locale.bind(NS)\n\n const kit = makeViewKit(t)\n const ContextView = makeContextView(ctx, kit)\n\n // Contribute the history-pagination verb as a standard prop, so the\n // Context browser can pull older conversation pages on demand when the\n // reader expands an element outside the loaded window. Fail-soft: hosts\n // without the provide channel (or a duplicate-name refusal) keep the\n // preview-plus-hint degradation.\n ctx.effect(() => {\n const noop = (): void => {}\n const sessions = ctx.get('sessions') as SessionsFace | undefined\n if (sessions === undefined || typeof sessions.provide !== 'function') return noop\n try {\n return sessions.provide({\n props: ['loadOlderHistory'],\n resolve: binding => ({ props: { loadOlderHistory: () => binding.session.loadOlder() } }),\n })\n } catch {\n return noop\n }\n }, 'dsh-context: loadOlderHistory prop')\n\n ctx.slots.inject('conversation.view', () => {\n return ctx.slots.register(\n // order 20 renders right of Chat (0) and Trajectory (10); the locale\n // namespace put the framework `t` seat on the component's props too.\n { name: 'conversation.view', id: 'context', order: 20, locale: NS, label: () => t('tab') },\n props => h(ContextView, props),\n )\n })\n\n // `/context` slash command: opens the context modal (see command.ts for\n // the trigger source). The modal itself renders from the input overlay\n // slot, opened per session through the hooks-compartment store.\n registerContextCommand(ctx, kit)\n const ContextModal = makeContextModal(ctx, kit)\n ctx.slots.inject('conversation.input.overlay', () => {\n return ctx.slots.register(\n { name: 'conversation.input.overlay', id: 'context-modal', order: 10, locale: NS,\n inject: (sessionId: string) => ({ hooks: { contextModal: modalStoreOf(sessionId) } }) },\n props => h(ContextModal, props),\n )\n })\n}\n\nmodule.exports = {\n name: 'dsh-context',\n inject: ['slots', 'locale'],\n apply,\n}\n"],"mappings":"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"}
|