@klarkxy/dsh-session-manager 0.1.2 → 0.2.0
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/README.md +1 -1
- package/README.zh-CN.md +1 -1
- package/lib/client.inner.cjs.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.js +85 -11
- package/lib/index.js.map +1 -1
- package/package.json +3 -3
package/lib/client.inner.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.inner.cjs","names":["useState","useRef","Toast","useSyncExternalStore","Modal","Button","useRef","useSyncExternalStore","useState","useRef","useCallback","Menu","IconFolderCloseRegular","IconPlusOutlineRegular","Modal","Button","useSyncExternalStore","useRef","Tooltip","Button","Modal","useState","MenuItemButton","useSyncExternalStore"],"sources":["../src/contracts.ts","../src/copy-action.ts","../src/copy-shortcut.tsx","../src/context-menu.ts","../../dsh-plugin-kit/src/official-ui.ts","../src/styles.ts","../src/ui-copy.ts","../src/free-panel.tsx","../src/temporary-picker.tsx","../src/temporary-workspace.ts","../src/session-actions.ts","../src/user-actions.tsx","../src/client.tsx"],"sourcesContent":["/** Shared names and bounds for cross-session discovery. */\n\nexport const PLUGIN_NAME = '@klarkxy/dsh-session-manager'\nexport const COPY_THREAD_MENU_ID = '@klarkxy/dsh-session-manager.copy-thread-id'\nexport const COPY_THREAD_SHORTCUT_ID = 'session-manager.copy-thread-id'\n/** After the shipped pin/rename/fork/archive rows (100–400). */\nexport const COPY_THREAD_MENU_ORDER = 500\n/** Temporary-workspace row inside the New Session workspace picker (host list slot). */\nexport const TEMP_WORKSPACE_ITEM_ID = '@klarkxy/dsh-session-manager.temp-workspace'\nexport const TEMP_WORKSPACE_CHANNEL = '/dsh-session-manager'\nexport const TEMP_WORKSPACE_FLOW_SLOT = 'session-manager.workspace.directoryFlow'\nexport const USER_ACTIONS_SLOT = 'conversation.chat.user-actions'\nexport const USER_ACTIONS_ID = '@klarkxy/dsh-session-manager.user-actions'\nexport const DELETE_DIALOG_ID = '@klarkxy/dsh-session-manager.delete-chat'\n\nexport const LIST_TOOL = 'list_sessions'\nexport const SEARCH_TOOL = 'search_sessions'\nexport const READ_TOOL = 'read_session'\n\nexport const DEFAULT_PAGE_CHARS = 4_000\nexport const MIN_PAGE_CHARS = 200\nexport const MAX_PAGE_CHARS = 16_000\nexport const DEFAULT_LIST_LIMIT = 20\nexport const MAX_LIST_LIMIT = 100\nexport const DEFAULT_SEARCH_LIMIT = 20\nexport const MAX_SEARCH_LIMIT = 50\nexport const TOOL_SUMMARY_CHARS = 160\n\nexport interface Config {\n /** Maximum serialized UTF-8 bytes of one read_session item page, including item metadata. */\n pageChars?: number\n /** Maximum sessions returned by one list_sessions page. */\n listLimit?: number\n /** Maximum sessions returned by one search_sessions page. */\n searchLimit?: number\n}\n\nexport interface ResolvedConfig {\n readonly pageChars: number\n readonly listLimit: number\n readonly searchLimit: number\n}\n\nexport function resolveConfig(config: Config = {}): ResolvedConfig {\n return {\n pageChars: boundInteger(config.pageChars, DEFAULT_PAGE_CHARS, MIN_PAGE_CHARS, MAX_PAGE_CHARS, 'pageChars'),\n listLimit: boundInteger(config.listLimit, DEFAULT_LIST_LIMIT, 1, MAX_LIST_LIMIT, 'listLimit'),\n searchLimit: boundInteger(config.searchLimit, DEFAULT_SEARCH_LIMIT, 1, MAX_SEARCH_LIMIT, 'searchLimit'),\n }\n}\n\nfunction boundInteger(value: number | undefined, fallback: number, min: number, max: number, name: string): number {\n const resolved = value ?? fallback\n if (!Number.isInteger(resolved) || resolved < min || resolved > max) {\n throw new TypeError(`${PLUGIN_NAME}: ${name} must be an integer from ${min} to ${max}`)\n }\n return resolved\n}\n","/** Clipboard result shown on the session-row menu. */\n\nexport type CopyLocale = 'zh' | 'en'\n\nexport const COPY_THREAD_LABEL: Record<CopyLocale, string> = {\n zh: '复制线程 ID',\n en: 'Copy thread ID',\n}\n\nexport const COPY_THREAD_FAILED: Record<CopyLocale, string> = {\n zh: '无法复制线程 ID',\n en: 'Could not copy the thread ID',\n}\n\nexport const COPY_THREAD_COPIED: Record<CopyLocale, string> = {\n zh: '已复制线程 ID',\n en: 'Thread ID copied',\n}\n\nexport const COPY_THREAD_NO_SESSION: Record<CopyLocale, string> = {\n zh: '请先打开一个会话',\n en: 'Open a session first',\n}\n\nexport function copyLocale(active: string | undefined): CopyLocale {\n return active?.toLowerCase().startsWith('zh') ? 'zh' : 'en'\n}\n\n/** Copy one session id. Rejection stays with the caller so the menu can show it. */\nexport async function copyThreadId(sessionId: string, writeText: (value: string) => Promise<void>): Promise<void> {\n await writeText(sessionId)\n}\n","import type { Context } from '@deepseek-ai/cordis'\n// ui-workspace's public contracts load the host shortcuts Context augmentation.\nimport type {} from '@deepseek-ai/dsh-client-ui-workspace/client'\nimport { Toast } from '@deepseek-ai/dsh-client-ui-primitives'\nimport { useEffect, useRef, useState } from 'react'\nimport { COPY_THREAD_SHORTCUT_ID } from './contracts.ts'\nimport { COPY_THREAD_COPIED, COPY_THREAD_FAILED, COPY_THREAD_LABEL, COPY_THREAD_NO_SESSION, copyLocale, copyThreadId, type CopyLocale } from './copy-action.ts'\nimport type { ObservableList } from './session-actions.ts'\n\nexport type HostShortcuts = Context['shortcuts']\n\nexport async function writeClipboard(value: string): Promise<void> {\n const clipboard = globalThis.navigator?.clipboard\n if (clipboard === undefined) throw new Error('clipboard unavailable')\n await clipboard.writeText(value)\n}\n\n/** Uses the same mainView reference as ui-workspace/src/client/shortcuts.ts.\n * The host registry owns key dispatch, remapping, conflicts, IME and repeat guards.\n */\nexport function CopyThreadShortcutNotice({ shortcuts, list, locale, currentLocale, writeText = writeClipboard }: {\n shortcuts?: HostShortcuts\n list?: ObservableList\n locale: CopyLocale\n currentLocale: () => string | undefined\n writeText?: (value: string) => Promise<void>\n}) {\n const [notice, setNotice] = useState<{ copied: boolean; seq: number } | null>(null)\n const sequence = useRef(0)\n useEffect(() => {\n if (shortcuts === undefined) return\n let active = true\n const notify = (copied: boolean) => {\n if (active) setNotice({ copied, seq: ++sequence.current })\n }\n const binding = { code: 'KeyC', modifiers: ['primary', 'alt'] as const }\n const stop = shortcuts.register({\n id: COPY_THREAD_SHORTCUT_ID as Parameters<HostShortcuts['register']>[0]['id'],\n label: () => COPY_THREAD_LABEL[copyLocale(currentLocale())],\n aliases: ['copy thread id', 'copy session id', '复制线程 ID'],\n defaults: {\n 'desktop:windows': binding, 'desktop:macos': binding,\n 'web:windows': binding, 'web:macos': binding,\n },\n regions: ['page', 'editable'],\n modals: [],\n resolve(context) {\n const target = Object.values(list?.getSnapshot().byId ?? {})\n .find(row => (row?.retainedBy?.mainView ?? 0) > 0)\n if (target === undefined || context.modal !== null || context.region === 'terminal') {\n return { status: 'blocked', reason: COPY_THREAD_NO_SESSION[copyLocale(currentLocale())] }\n }\n return { status: 'handled', run() {\n void copyThreadId(target.id, writeText).then(\n () => notify(true),\n () => notify(false),\n )\n } }\n },\n })\n return () => { active = false; stop() }\n }, [shortcuts, list, currentLocale, writeText])\n return notice === null ? null : <Toast\n key={notice.seq}\n text={(notice.copied ? COPY_THREAD_COPIED : COPY_THREAD_FAILED)[locale]}\n tone={notice.copied ? 'success' : undefined}\n onDone={() => setNotice(null)}\n />\n}\n","/**\n * Right-click forwarding for the sidebar browser: a `contextmenu` gesture on a\n * session or workspace row clicks that row's native \"...\" trigger, so the\n * host's own menu — including every `sidebar.workspaces.session.menu.item`\n * slot contribution, this plugin's rows included — opens exactly as a\n * left-click on the trigger would. The host owns the menu; this module only\n * relays the gesture. No host code registers a contextmenu listener, so the\n * capture-phase relay does not fight an existing handler.\n *\n * DOM contract (dsh-client-ui-workspace 0.2.0-rc.2, lib/client.js):\n * - Rows are `div[role=\"treeitem\"][data-row-key=\"session:<id>\"]` or\n * `data-row-key=\"workspace:<id>\"` inside `div[role=\"tree\"]`. Overflow and\n * empty rows carry other prefixes, search rows carry no `data-row-key`, and\n * AnimatedRows exit clones have the attribute removed — all are ignored by\n * the prefix match. (client.js:1287, 1590-1596, 1729, 1842-1846)\n * - The trigger is the first `button[type=\"button\"]` inside the row's trailing\n * `span` whose CSS-module class ends in `_rowActions`. It stays mounted —\n * CSS `display:none` until hover or menu-open — so a programmatic click\n * toggles the menu. Blank new-session rows and the ungrouped bucket render\n * no trigger; right-click does nothing there. (client.js:1061, 1314-1340,\n * 1640-1660)\n * - Class names carry a per-build hash prefix and the trigger's aria-label is\n * localized; only `data-row-key` and the structural suffix are stable.\n * - The opened menu portals to `document.body`, outside the tree, so a\n * right-click on a menu row never re-enters this relay.\n */\n\nconst ROW_SELECTOR = '[data-row-key^=\"session:\"], [data-row-key^=\"workspace:\"]'\nconst TRIGGER_SELECTOR = 'span[class*=\"rowActions\"] button[type=\"button\"]'\n\n/** Resolve the native \"...\" trigger of the row containing `target`, if any. */\nexport function findRowMenuTrigger(target: Element): HTMLElement | null {\n if (typeof target.closest !== 'function') return null\n const row = target.closest(ROW_SELECTOR)\n if (row === null || row.closest('[role=\"tree\"]') === null) return null\n const trigger = row.querySelector(TRIGGER_SELECTOR)\n if (trigger === null || typeof (trigger as HTMLElement).click !== 'function') return null\n return trigger as HTMLElement\n}\n\n/**\n * Forward one `contextmenu` event to the row's native menu trigger.\n * Returns true when the gesture was relayed (and the default suppressed).\n */\nexport function forwardContextMenu(event: Event): boolean {\n const target = event.target\n if (target === null || typeof (target as Element).closest !== 'function') return false\n const trigger = findRowMenuTrigger(target as Element)\n if (trigger === null) return false\n event.preventDefault()\n trigger.click()\n return true\n}\n\n/** Capture-phase relay on the document; the returned disposer uninstalls it. */\nexport function installContextMenuForwarding(doc: Document): () => void {\n const listener = (event: Event) => { forwardContextMenu(event) }\n doc.addEventListener('contextmenu', listener, true)\n return () => { doc.removeEventListener('contextmenu', listener, true) }\n}\n","/**\n * Shared contract that keeps every plugin's browser-side UI on the official\n * DeepSeek Harness Web design language.\n *\n * Two rules produce that language, and both are load-bearing here:\n *\n * 1. Colour, radius, elevation and focus come from the host theme's real\n * `--dsw-*` tokens, written under their own names. Plugins never invent a\n * token, never alias the official ones behind a private palette (a private\n * alias is just a second, diverging theme), and never carries a literal\n * fallback — the host publishes light and dark, and a literal would pin one\n * of them. The only non-colour custom properties used are the host's own\n * content-font axis and frame clearance.\n *\n * 2. Anything the host already ships is used, not reimplemented. Controls come\n * from `@deepseek-ai/dsh-client-ui-primitives` (`Button`, `Input`,\n * `Checkbox`, `Switch`, `Tag`, `Pill`, `SegmentedControl`, `Menu`, `Modal`,\n * `Tooltip`, `Toast`, `DisclosureRow`, `StateDot`, `PathLabel`, the settings\n * form suite). This module only styles what primitives do not cover: page\n * scaffolding, field layout, banners, empty states and scroll regions.\n *\n * The metrics below are transcribed from the primitives' own CSS modules so a\n * feature panel lines up pixel-for-pixel with a native one: the 14/22 body and\n * 13/20 compact type tiers, the 0.5px hairline scale, and the elevation family\n * that draws a surface's edge in its shadow (`border: 0`) instead of a border.\n */\n\n/**\n * Every `--dsw-*` token this repo is allowed to reference, grouped by role.\n *\n * Plugins may only colour through this list. It is exported so the guard test\n * can fail a build when a stylesheet reaches for anything else — the failure\n * mode this prevents is silent: an unknown token resolves to nothing, so a\n * border disappears or a label inherits the wrong colour with no error anywhere.\n */\nexport const OFFICIAL_THEME_TOKENS = {\n /** Surfaces, from the page up to the topmost nested card. */\n surface: [\n '--dsw-alias-bg-base',\n '--dsw-alias-bg-layer-1',\n '--dsw-alias-bg-layer-2',\n '--dsw-alias-bg-layer-3',\n '--dsw-alias-bg-layer-4',\n '--dsw-alias-bg-module-platform',\n '--dsw-alias-bg-overlay',\n ],\n /** Hairlines. l1 is near-invisible on a menu surface, so menus use l2+. */\n border: ['--dsw-alias-border-l1', '--dsw-alias-border-l2', '--dsw-alias-border-l3', '--dsw-alias-border-l4'],\n /** Text. `caption` is menu shortcut text, `dimmed` is placeholder text. */\n label: [\n '--dsw-alias-label-primary',\n '--dsw-alias-label-secondary',\n '--dsw-alias-label-tertiary',\n '--dsw-alias-label-caption',\n '--dsw-alias-label-dimmed',\n '--dsw-alias-label-error',\n '--dsw-alias-label-primary-foreground',\n ],\n /** Interactive fills. The `-danger` hover belongs to destructive rows. */\n interactive: [\n '--dsw-alias-interactive-bg-hover',\n '--dsw-alias-interactive-bg-active',\n '--dsw-alias-interactive-bg-hover-danger',\n ],\n /** Accent and status. `business` is the focus ring's default colour. */\n accent: [\n '--dsw-alias-brand-primary',\n '--dsw-alias-button-primary-fill',\n '--dsw-alias-button-primary-hover',\n '--dsw-alias-button-tool-bar-fill',\n '--dsw-alias-button-tool-bar-hover',\n '--dsw-alias-button-ghost-active-fill',\n '--dsw-alias-button-ghost-active-border',\n ],\n state: [\n '--dsw-alias-state-business-primary',\n '--dsw-alias-state-success-primary',\n '--dsw-alias-state-warn-primary',\n '--dsw-alias-state-error-primary',\n '--dsw-alias-state-idle-primary',\n ],\n /** Corner scale: sm 8, md 12, lg the large card, panel the modal. */\n radius: ['--dsw-radius-sm', '--dsw-radius-md', '--dsw-radius-lg', '--dsw-radius-panel'],\n /** An elevated surface draws its edge in the shadow, so it keeps border: 0. */\n elevation: [\n '--dsw-elevation-soft',\n '--dsw-elevation-stroke',\n '--dsw-elevation-stroke-color',\n '--dsw-elevation-panel',\n '--dsw-elevation-prominent',\n ],\n /** Floats, masks and scrollbars. */\n overlay: [\n '--dsw-menu-surface-fill',\n '--dsw-menu-backdrop-filter',\n '--dsw-mask-blur',\n '--dsw-alias-bg-mask-1',\n '--dsw-alias-menu-icon',\n '--dsw-alias-scrollbar-bg-l2',\n '--dsw-alias-scrollbar-hover-l2',\n '--dsw-shadow-lv3',\n ],\n /** Motion, focus and type axis, published by the host rather than by a component. */\n system: [\n '--dsw-focus-ring-width',\n '--dsw-focus-ring-color',\n '--dsw-font-markdown-code-font-family',\n '--ds-transition-duration',\n '--ds-ease-in-out',\n '--ds-font-family-code',\n '--dsh-scrollbar-thumb',\n '--dsh-scrollbar-thumb-hover',\n '--dsh-content-font-size-secondary',\n '--dsh-content-font-delta',\n '--dsh-frame-top-clearance',\n ],\n} as const\n\n/** Every official token name, flat. Used by the token guard test. */\nexport const OFFICIAL_THEME_TOKEN_NAMES: readonly string[] = Object.values(OFFICIAL_THEME_TOKENS).flat()\n\n/** The elevation steps a surface can be raised by, softest first. */\nexport type OfficialElevation = 'soft' | 'stroke' | 'panel' | 'prominent'\n\n/**\n * The host's focus ring shorthand, verbatim. Writing this per control is how\n * rings drift apart; a stylesheet that draws its own focus style should use\n * {@link officialFocus} instead. The colour fallback is the host's own default.\n */\nexport const OFFICIAL_FOCUS_RING =\n 'var(--dsw-focus-ring-width) solid var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary))'\n\n/**\n * A complete `outline` declaration at the official geometry. `offset` defaults\n * to the 2px the native controls use; the host's inline field rules sit at 1px\n * and a segmented tab pulls the ring inside itself at -2px.\n */\nexport function officialFocus(offset = '2px'): string {\n return `outline: ${OFFICIAL_FOCUS_RING}; outline-offset: ${offset}`\n}\n\n/**\n * An elevated surface. The host draws a raised surface's edge inside its\n * shadow rather than as a border, so a card sets `border: 0` and takes the edge\n * from the elevation — which is also why its border stays off the alias-border\n * set that a flat, non-elevated rule would use.\n */\nexport function officialElevation(level: OfficialElevation): string {\n return `border: 0; box-shadow: var(--dsw-elevation-${level})`\n}\n\n/**\n * An elevated surface whose edge should read as a specific hairline. Rebinding\n * the stroke colour is how a menu card picks l1 while a panel picks l3, without\n * the two growing apart by hand.\n */\nexport function officialStrokedElevation(level: OfficialElevation, color: string): string {\n return `--dsw-elevation-stroke-color: ${color}; ${officialElevation(level)}`\n}\n\n/**\n * The shared stylesheet for a plugin UI, scoped under that plugin's root class.\n *\n * Scoping is what keeps this safe to always-bundle into every client: the rules\n * can only match inside the plugin's own subtree, so two plugins can both mount\n * `dsh-ui-card` without either styling the other's markup.\n *\n * Each recipe matches the root element *and* its descendants, because the\n * commonest arrangement is one element that is both — a surface that carries\n * the root class and `dsh-ui-card`, or a portaled dialog that is the root and\n * the `dsh-ui-surface`. A descendant-only scope would silently leave those\n * unstyled, with no error anywhere.\n *\n * A caveat worth knowing: `Modal` and `Menu` portal to `document.body`, so their\n * content leaves the plugin's subtree entirely. A portaled surface therefore\n * needs its own root class on an element inside the portal.\n *\n * Only patterns that primitives do not provide live here. If a control appears\n * below that `Button`/`Input`/`Switch`/`Tag`/`Menu` already covers, that is a\n * bug in this file: use the primitive and delete the recipe.\n */\nexport function officialUiCss(roots: string | readonly string[]): string {\n // One plugin often mounts several unrelated surfaces (a settings seat, a chat\n // card, a header menu), so the caller names every root. The rules below are\n // nested under a single selector list and use `&`, which the browser expands\n // per root — so one stylesheet covers all of them without duplicating itself.\n const scope = (typeof roots === 'string' ? [roots] : roots).map(root => `.${root}`).join(', ')\n const sheet = `\n/* Official DSH Web UI contract. Generated by @klarkxy/dsh-plugin-kit/official-ui.\n * Do not hand-edit the copy inside a plugin: change this module so every plugin\n * moves together. Scope: ${scope} */\n/* The scope rule below stays open for the whole sheet: every rule after it\n * nests with the parent selector, so one stylesheet can cover several unrelated\n * roots without leaking into a neighbouring plugin. Its closing brace is last. */\n${scope} {\n color: var(--dsw-alias-label-primary);\n font-family: inherit;\n font-size: 14px;\n line-height: 22px;\n min-width: 0;\n\n& *, & *::before, & *::after { box-sizing: border-box; }\n& h1, & h2, & h3, & h4, & p, & figure { margin: 0; }\n/* Keyboard focus only: pointer input keeps the native resting appearance. The\n * ring needs no radius of its own — the outline already follows the control's\n * own border-radius, and overriding it here would flatten every control. */\n& :focus-visible { ${officialFocus()}; }\n& [hidden] { display: none !important; }\n\n/* --- Type tiers. The same 14/22 and 13/20 steps the primitives use. --- */\n& .dsh-ui-title { font-size: 16px; line-height: 24px; font-weight: 500; color: var(--dsw-alias-label-primary); }\n& .dsh-ui-heading { font-size: 14px; line-height: 22px; font-weight: 500; color: var(--dsw-alias-label-primary); }\n& .dsh-ui-compact { font-size: 13px; line-height: 20px; color: var(--dsw-alias-label-primary); }\n& .dsh-ui-meta { font-size: 12px; line-height: 18px; color: var(--dsw-alias-label-secondary); }\n& .dsh-ui-hint { font-size: 12px; line-height: 18px; color: var(--dsw-alias-label-tertiary); }\n& .dsh-ui-error { font-size: 12px; line-height: 18px; color: var(--dsw-alias-state-error-primary); }\n& .dsh-ui-warn { color: var(--dsw-alias-state-warn-primary); }\n& .dsh-ui-success { color: var(--dsw-alias-state-success-primary); }\n& .dsh-ui-muted { color: var(--dsw-alias-label-tertiary); }\n& .dsh-ui-truncate { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n& .dsh-ui-wrap { min-width: 0; overflow-wrap: anywhere; }\n\n/* --- Layout scaffolding. --- */\n& .dsh-ui-stack { display: flex; flex-direction: column; gap: 12px; }\n& .dsh-ui-stack-lg { display: flex; flex-direction: column; gap: 20px; }\n& .dsh-ui-row { display: flex; align-items: center; gap: 8px; min-width: 0; }\n& .dsh-ui-row-wrap { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }\n& .dsh-ui-spacer { flex: 1; min-width: 0; }\n/* A 0.5px l2 rule is the host's section divider; reserve the same rhythm. */\n& .dsh-ui-divider { height: 0.5px; background: var(--dsw-alias-border-l2); }\n& .dsh-ui-section { display: flex; flex-direction: column; gap: 12px; padding-top: 16px; border-top: 0.5px solid var(--dsw-alias-border-l2); }\n\n/* --- Card: a raised surface whose edge lives in the shadow. --- */\n& .dsh-ui-card {\n ${officialElevation('stroke')}\n display: flex;\n flex-direction: column;\n gap: 12px;\n padding: 16px;\n border-radius: var(--dsw-radius-lg);\n background: var(--dsw-alias-bg-layer-1);\n color: var(--dsw-alias-label-primary);\n min-width: 0;\n}\n& .dsh-ui-card--flat { border: 0.5px solid var(--dsw-alias-border-l3); box-shadow: none; }\n& .dsh-ui-card--nested { background: var(--dsw-alias-bg-layer-2); }\n& .dsh-ui-card--plain { background: none; }\n\n/* --- Field: label, control, help, error. The control itself is an\n * official primitive, so this only owns the vertical rhythm. --- */\n& .dsh-ui-field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }\n& .dsh-ui-field + .dsh-ui-field { border-top: 0.5px solid var(--dsw-alias-border-l2); padding-top: 12px; }\n& .dsh-ui-label { display: flex; align-items: center; gap: 6px; font-size: 13px; line-height: 20px; font-weight: 500; color: var(--dsw-alias-label-primary); }\n& .dsh-ui-label-row { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }\n& .dsh-ui-help { font-size: 12px; line-height: 1.6; color: var(--dsw-alias-label-secondary); }\n& .dsh-ui-help p { margin: 0; }\n& .dsh-ui-help p + p { margin-top: 8px; }\n& .dsh-ui-required { color: var(--dsw-alias-state-error-primary); }\n& .dsh-ui-control { width: 100%; min-width: 0; }\n/* An invalid control is marked on the control, not only in the message. */\n& .dsh-ui-control[aria-invalid='true'] { border-color: var(--dsw-alias-state-error-primary); }\n& .dsh-ui-readonly { display: flex; flex-direction: column; gap: 4px; min-width: 0; }\n& .dsh-ui-readonly > dt { font-size: 12px; line-height: 18px; color: var(--dsw-alias-label-tertiary); }\n& .dsh-ui-readonly > dd { margin: 0; font-size: 13px; line-height: 20px; overflow-wrap: anywhere; }\n\n/* --- Buttons row. A no-op container: it exists so actions line up on the\n * trailing edge the way every native panel does. --- */\n& .dsh-ui-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding-top: 4px; }\n& .dsh-ui-actions-end { justify-content: flex-end; }\n\n/* --- Banners. A banner is a left-rail notice, the shape used for warnings,\n * deprecations and blocking instructions. --- */\n& .dsh-ui-banner {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 10px 14px;\n border: 0.5px solid var(--dsw-alias-border-l3);\n border-left: 3px solid var(--dsw-alias-state-warn-primary);\n border-radius: var(--dsw-radius-md);\n background: var(--dsw-alias-bg-layer-1);\n font-size: 13px;\n line-height: 20px;\n color: var(--dsw-alias-label-secondary);\n}\n& .dsh-ui-banner-title { font-weight: 500; color: var(--dsw-alias-state-warn-primary); }\n& .dsh-ui-banner--info { border-left-color: var(--dsw-alias-state-business-primary); }\n& .dsh-ui-banner--danger { border-left-color: var(--dsw-alias-state-error-primary); }\n& .dsh-ui-banner--success { border-left-color: var(--dsw-alias-state-success-primary); }\n& .dsh-ui-banner p { margin: 0; }\n\n/* --- Inline notice: a transient confirmation with no chrome of its own. --- */\n& .dsh-ui-notice { display: flex; align-items: center; gap: 6px; font-size: 12px; line-height: 18px; color: var(--dsw-alias-state-success-primary); }\n& .dsh-ui-notice--error { color: var(--dsw-alias-state-error-primary); }\n\n/* --- Empty and loading states. Both sit in a dashed well so an empty panel\n * reads as \"nothing here yet\" rather than as a broken layout. --- */\n& .dsh-ui-empty {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 6px;\n padding: 20px 16px;\n border: 0.5px dashed var(--dsw-alias-border-l3);\n border-radius: var(--dsw-radius-md);\n font-size: 13px;\n line-height: 20px;\n color: var(--dsw-alias-label-secondary);\n}\n& .dsh-ui-loading { display: flex; align-items: center; gap: 8px; padding: 20px 0; font-size: 13px; line-height: 20px; color: var(--dsw-alias-label-secondary); }\n\n/* --- Selectable list. A row is a button-sized target with a hover fill and\n * a selected fill; the name carries the weight, the description does not. --- */\n& .dsh-ui-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; min-width: 0; }\n& .dsh-ui-list-scroll { max-height: min(66vh, 760px); overflow-y: auto; overflow-x: hidden; }\n& .dsh-ui-list-row { border-radius: var(--dsw-radius-md); }\n& .dsh-ui-list-row:hover { background: var(--dsw-alias-interactive-bg-hover); }\n& .dsh-ui-list-row[aria-selected='true'], & .dsh-ui-list-row[data-selected] { background: var(--dsw-alias-interactive-bg-active); }\n& .dsh-ui-list-item {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 4px;\n width: 100%;\n min-width: 0;\n padding: 10px 12px;\n border: 0;\n border-radius: var(--dsw-radius-md);\n background: none;\n font: inherit;\n color: inherit;\n text-align: start;\n cursor: pointer;\n}\n& .dsh-ui-list-item:disabled { cursor: default; }\n& .dsh-ui-list-item:disabled:hover { background: none; }\n& .dsh-ui-list-name { font-size: 14px; line-height: 22px; font-weight: 500; color: var(--dsw-alias-label-primary); overflow-wrap: anywhere; }\n& .dsh-ui-list-desc { font-size: 12px; line-height: 18px; color: var(--dsw-alias-label-tertiary); }\n\n/* --- Code and structured output. Wraps rather than scrolls, because a\n * feature panel is read rather than scanned. --- */\n& .dsh-ui-code {\n padding: 10px 12px;\n border: 0.5px solid var(--dsw-alias-border-l3);\n border-radius: var(--dsw-radius-md);\n background: var(--dsw-alias-bg-layer-1);\n font-family: var(--ds-font-family-code);\n font-size: 12px;\n line-height: 20px;\n color: var(--dsw-alias-label-secondary);\n overflow-wrap: anywhere;\n white-space: pre-wrap;\n}\n& .dsh-ui-scroll { max-height: 60vh; overflow: auto; overscroll-behavior: contain; }\n\n/* --- A toggle row: label on the left, switch on the trailing edge. This is\n * layout only; the switch itself is the official primitive. --- */\n& .dsh-ui-toggle-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; min-width: 0; padding: 12px 0; }\n& .dsh-ui-toggle-row + .dsh-ui-toggle-row { border-top: 0.5px solid var(--dsw-alias-border-l2); }\n& .dsh-ui-toggle-text { display: flex; flex-direction: column; gap: 4px; min-width: 0; }\n& .dsh-ui-toggle-label { font-size: 14px; line-height: 22px; font-weight: 500; color: var(--dsw-alias-label-primary); }\n\n/* --- Floating surface: a panel anchored to a trigger. This is the material\n * a menu card is made of — the translucent fill plus its backdrop blur, with\n * the edge riding inside the prominent elevation. A plugin that hand-rolls this\n * is how tokens like --dsw-specific-menu get invented; use this instead. --- */\n& .dsh-ui-surface {\n --dsw-elevation-stroke-color: var(--dsw-alias-border-l1);\n --dsh-scrollbar-thumb: var(--dsw-alias-scrollbar-bg-l2);\n --dsh-scrollbar-thumb-hover: var(--dsw-alias-scrollbar-hover-l2);\n position: relative;\n display: flex;\n flex-direction: column;\n border: 0;\n border-radius: var(--dsw-radius-lg);\n background: var(--dsw-menu-surface-fill);\n backdrop-filter: var(--dsw-menu-backdrop-filter);\n box-shadow: var(--dsw-elevation-prominent);\n color: var(--dsw-alias-label-primary);\n font-size: 13px;\n line-height: 20px;\n min-width: 0;\n}\n& .dsh-ui-surface-body { display: flex; flex-direction: column; gap: 8px; padding: 12px 14px 14px; overflow-y: auto; }\n& .dsh-ui-surface-head { display: flex; align-items: center; gap: 8px; min-width: 0; }\n& .dsh-ui-surface-title { font-size: 14px; line-height: 22px; font-weight: 500; color: var(--dsw-alias-label-primary); }\n\n/* --- Native select. The primitives ship no select, so a plugin that offers a\n * closed list of choices keeps the platform control and matches the official\n * settings field geometry exactly (34px, 0.5px l4, radius-md, layer-3). A\n * SegmentedControl is the primitive to reach for when the choices are few\n * enough to show at once. --- */\n& .dsh-ui-select {\n box-sizing: border-box;\n width: 100%;\n min-width: 0;\n height: 34px;\n padding: 0 12px;\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: var(--dsw-radius-md);\n background: var(--dsw-alias-bg-layer-3);\n font: inherit;\n font-size: 13px;\n line-height: 1.5;\n color: var(--dsw-alias-label-primary);\n cursor: pointer;\n}\n& .dsh-ui-select:focus-visible { outline: none; border-color: var(--dsw-alias-state-business-primary); }\n& .dsh-ui-select:disabled { color: var(--dsw-alias-label-tertiary); cursor: default; }\n& .dsh-ui-select[aria-invalid='true'] { border-color: var(--dsw-alias-state-error-primary); }\n\n/* Long panels scroll inside themselves instead of growing the host page. */\n& .dsh-ui-panel { display: flex; flex-direction: column; gap: 16px; min-width: 0; }\n& .dsh-ui-panel-wide { max-width: 100%; }\n\n@media (prefers-reduced-motion: reduce) {\n & *, & *::before, & *::after { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; }\n}\n}\n`\n // Widen every recipe from \"a descendant of the root\" to \"the root, or one of\n // its descendants\". Written as a transform rather than by hand so no recipe\n // can be added later with only the descendant form. The pattern is narrow on\n // purpose: a leading `&` followed by one recipe class and no combinator, so\n // sibling and child rules such as `.dsh-ui-field + .dsh-ui-field` keep their\n // own meaning and are left alone.\n return sheet.replace(/^& (\\.dsh-ui-[a-z0-9-]+)(?![+>~])/gm, (_match, className: string) =>\n `&${className}, & ${className}`)\n}\n","import { officialUiCss } from '@klarkxy/dsh-plugin-kit/official-ui'\n\nexport const FREE_CHAT_ROOT = 'dsh-free-chat'\n\n/** Host tokens and official scaffolding. Only the edit draft, the inline action row,\n * and the alert line survive the panel removal; the modals reuse the root class. */\nexport const freeChatCss = `${officialUiCss(FREE_CHAT_ROOT)}\n.${FREE_CHAT_ROOT} .dsh-free-draft {\n box-sizing: border-box;\n width: 100%;\n min-height: 8em;\n padding: 8px 12px;\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: var(--dsw-radius-md);\n background: var(--dsw-alias-bg-layer-3);\n color: var(--dsw-alias-label-primary);\n font: inherit;\n font-size: 14px;\n line-height: 22px;\n resize: vertical;\n}\n.${FREE_CHAT_ROOT} .dsh-free-actions {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n min-width: 0;\n}\n.${FREE_CHAT_ROOT} .dsh-free-alert { margin: 0; }\n`\n","import { copyLocale, type CopyLocale } from './copy-action.ts'\n\nexport type { CopyLocale }\nexport { copyLocale }\n\n/** Failure identity stored by the UI. The sentence is derived from the active locale. */\nexport interface OperationFailure {\n readonly code: string\n readonly reason?: string\n}\n\nconst reasons = {\n zh: {\n modified: '后续操作可能涉及修改,暂时不能重试。',\n unknown: '无法确认这个操作的结果。',\n pending: '这条消息还在等待处理。',\n stale: '这个聊天已经更新,请再试一次。',\n running: '这个聊天仍在运行。请等待当前工作结束后再试。',\n cleanup: '清理没有完成。',\n unsupported: '当前版本不能完成这个操作。',\n },\n en: {\n modified: 'Later operations may have made changes. Retry is unavailable.',\n unknown: \"This action's result could not be confirmed.\",\n pending: 'This message is still pending.',\n stale: 'This chat has changed. Try again.',\n running: 'This chat is still running. Wait for the current work to finish, then try again.',\n cleanup: 'Cleanup did not finish.',\n unsupported: 'This runtime cannot complete that action.',\n },\n} as const\n\nexport type FailureReason = keyof typeof reasons.zh\n\nconst text = {\n zh: {\n tempWorkspace: '临时工作区',\n createFailed: '无法创建临时工作区',\n retryList: '重试',\n deleteChat: '删除聊天',\n deleting: '正在删除',\n deleteFree: '将删除这个聊天及其拥有的文件。',\n deleteOrdinary: '将删除这个聊天。项目文件会保留。',\n cancel: '取消',\n close: '关闭',\n retry: '重试',\n edit: '编辑并重发',\n send: '发送',\n editTitle: '编辑并重发',\n draft: '消息文本',\n },\n en: {\n tempWorkspace: 'Temporary Workspace',\n createFailed: 'Could not create the temporary workspace',\n retryList: 'Retry',\n deleteChat: 'Delete chat',\n deleting: 'Deleting',\n deleteFree: 'This deletes this chat and its owned files.',\n deleteOrdinary: 'This deletes this chat. Project files remain.',\n cancel: 'Cancel',\n close: 'Close',\n retry: 'Retry',\n edit: 'Edit and resend',\n send: 'Send',\n editTitle: 'Edit and resend',\n draft: 'Message text',\n },\n} as const\n\nexport type UiTextKey = keyof typeof text.zh\n\nexport function uiText(locale: CopyLocale, key: UiTextKey): string {\n return text[locale][key]\n}\n\nexport function failureReason(failure: OperationFailure): FailureReason {\n if (failure.code === 'session/lifecycle-unavailable' || failure.code === 'session/fork-unavailable') return 'unsupported'\n if (\n failure.code === 'session/retry-revision'\n || failure.code === 'session/branch-moved'\n || failure.code === 'session/retry-input'\n || failure.code === 'session/retry-conflict'\n ) return 'stale'\n if (failure.code === 'session/delete-pending') return 'cleanup'\n if (failure.code === 'session/agent-busy' && failure.reason === 'free-session-work-active') return 'running'\n if (failure.reason === 'modified' || failure.reason === 'pending' || failure.reason === 'running' || failure.reason === 'stale') {\n return failure.reason\n }\n if (failure.reason === 'stop-failed' || failure.reason === 'not-quiet') return 'running'\n if (failure.reason === 'not-human-prompt' || failure.reason === 'missing-evidence') return 'unknown'\n return 'unknown'\n}\n\nexport function failureText(locale: CopyLocale, failure: OperationFailure): string {\n return reasons[locale][failureReason(failure)]\n}\n\nexport function deleteBody(locale: CopyLocale, classification: 'free' | 'ordinary'): string {\n return classification === 'free' ? text[locale].deleteFree : text[locale].deleteOrdinary\n}\n","import { useEffect, useRef, useSyncExternalStore } from 'react'\nimport { Button, Modal } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { FreeChatModel } from './session-actions.ts'\nimport { FREE_CHAT_ROOT } from './styles.ts'\nimport { deleteBody, failureText, uiText, type CopyLocale } from './ui-copy.ts'\n\nexport function FreeChatIcon({ size }: { size: number; active?: boolean }): React.ReactElement {\n return (\n <svg width={size} height={size} viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <path\n d=\"M2.5 3.5h11v7.5h-4.2L6 13.5V11H2.5z\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.2\"\n />\n </svg>\n )\n}\n\n/** Create failures used to surface inside the standalone panel. The panel is gone,\n * so they get a small overlay instead; closing it dismisses the stored notice. */\nexport function CreateNoticeDialog(props: { model: FreeChatModel; locale: CopyLocale }): React.ReactElement | null {\n const snapshot = useSyncExternalStore(props.model.subscribe, props.model.getSnapshot, props.model.getSnapshot)\n const notice = snapshot.notice\n if (notice === undefined) return null\n const copy = (key: Parameters<typeof uiText>[1]) => uiText(props.locale, key)\n return (\n <Modal\n open\n className={FREE_CHAT_ROOT}\n title={copy('createFailed')}\n closeLabel={copy('close')}\n onClose={() => { props.model.dismissNotice() }}\n footer={(\n <Button variant=\"primary\" data-modal-autofocus onClick={() => { props.model.dismissNotice() }}>\n {copy('close')}\n </Button>\n )}\n >\n <p className=\"dsh-ui-error dsh-free-alert\" role=\"alert\">{failureText(props.locale, notice)}</p>\n </Modal>\n )\n}\n\nexport function DeleteChatDialog(props: { model: FreeChatModel; locale: CopyLocale }): React.ReactElement | null {\n const snapshot = useSyncExternalStore(props.model.subscribe, props.model.getSnapshot, props.model.getSnapshot)\n const request = snapshot.deleteRequest\n const confirmRef = useRef<HTMLButtonElement>(null)\n useEffect(() => {\n if (request?.failure) confirmRef.current?.focus()\n }, [request?.failure])\n if (request === undefined) return null\n const copy = (key: Parameters<typeof uiText>[1]) => uiText(props.locale, key)\n const label = request.busy ? copy('deleting') : request.failure ? copy('retryList') : copy('deleteChat')\n return (\n <Modal\n open\n className={FREE_CHAT_ROOT}\n title={copy('deleteChat')}\n closeLabel={copy('close')}\n description={deleteBody(props.locale, request.classification)}\n onClose={() => { props.model.cancelDelete() }}\n footer={(\n <>\n <Button variant=\"ghost\" disabled={request.busy} onClick={() => { props.model.cancelDelete() }}>{copy('cancel')}</Button>\n <Button\n ref={confirmRef}\n variant=\"primary\"\n data-modal-autofocus\n disabled={request.busy}\n onClick={() => { void props.model.confirmDelete() }}\n >\n {label}\n </Button>\n </>\n )}\n >\n <p>{request.title}</p>\n {request.failure ? <p className=\"dsh-ui-error dsh-free-alert\" role=\"alert\">{failureText(props.locale, request.failure)}</p> : null}\n </Modal>\n )\n}\n","import { useCallback, useEffect, useRef, useState, useSyncExternalStore, type ReactNode, type RefObject } from 'react'\nimport { Button, IconFolderCloseRegular, IconPlusOutlineRegular, Menu, Modal } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { StoredEntry } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { DirectoryFlowOwnerProps, WorkspacePickerProps } from '@deepseek-ai/dsh-client-ui-workspace/client'\nimport { FreeChatIcon } from './free-panel.tsx'\nimport { TEMP_WORKSPACE_FLOW_SLOT } from './contracts.ts'\nimport { uiText, type CopyLocale } from './ui-copy.ts'\nimport type { TemporaryWorkspaceModel } from './temporary-workspace.ts'\nimport { copyLocale } from './copy-action.ts'\n\nconst PICKER_SLOT = 'conversation.hero.workspace'\nconst DIRECTORY_SLOT = 'conversation.hero.workspace.directoryFlow'\n\n/** Public registry faces used by the version-bounded directory-flow compatibility adapter. */\nexport interface PickerRegistry {\n inject(key: string, callback: () => (() => void) | void): () => void\n register(options: Record<string, unknown>, component: unknown): () => void\n entriesOfSlot(key: string): readonly StoredEntry[]\n spec(key: string): { kind: string; scope: string } | undefined\n subscribe(key: string, listener: () => void): () => void\n onEntryError?(listener: (key: string, entry: StoredEntry, error: unknown) => void): () => void\n}\n\n/** Keep the host's native/web picker implementation and its injected capabilities.\n * Standard rc.2 offers no exported directory-flow factory. Only its simple root\n * registration can be mirrored; more complex future registrations restore the host picker.\n * Original entries and their ownership ledger are never changed.\n */\nexport function installTemporaryWorkspacePicker(slots: PickerRegistry, model: TemporaryWorkspaceModel,\n createWorkspace: (path: string) => Promise<{ workspaceId: string }>, locale?: {\n getSnapshot(): { active: string }; subscribe(listener: () => void): () => void\n }): () => void {\n if (typeof slots.entriesOfSlot !== 'function' || typeof slots.spec !== 'function' || typeof slots.subscribe !== 'function') {\n model.reportFailure(copyLocale(locale?.getSnapshot().active) === 'zh'\n ? '当前版本无法扩展工作区菜单,已保留原菜单。' : 'Could not extend the workspace menu. The original menu has been preserved.')\n return () => {}\n }\n return slots.inject(PICKER_SLOT, () => {\n let mirror: StoredEntry | undefined, stopMirror = () => {}, restored = false\n const failureMessage = () => copyLocale(locale?.getSnapshot().active) === 'zh'\n ? '当前版本无法扩展工作区菜单,已保留原菜单。' : 'Could not extend the workspace menu. The original menu has been preserved.'\n const renderPicker = (props: PickerProps) => <TemporaryWorkspacePicker {...props} model={model} createWorkspace={createWorkspace} locale={locale}\n getDirectoryFlow={() => mirror} subscribeFlow={listener => slots.subscribe(DIRECTORY_SLOT, listener)} />\n const stopPicker = slots.register({ name: PICKER_SLOT, priority: -10, locale: 'workspace',\n children: { [TEMP_WORKSPACE_FLOW_SLOT]: { kind: 'single', scope: 'root' } },\n }, renderPicker)\n const stopErrors = slots.onEntryError?.((key, entry) => {\n if (restored || (key !== TEMP_WORKSPACE_FLOW_SLOT && !(key === PICKER_SLOT && entry.component === renderPicker))) return\n restored = true; stopMirror(); mirror = undefined; stopPicker()\n model.reportFailure(failureMessage())\n }) ?? (() => {})\n const sync = () => {\n if (restored) return\n const next = slots.entriesOfSlot(DIRECTORY_SLOT)[0]\n if (next === mirror) return\n stopMirror(); stopMirror = () => {}; mirror = undefined\n if (next === undefined) return\n const spec = slots.spec(DIRECTORY_SLOT)\n if (spec?.kind !== 'single' || spec.scope !== 'root' || typeof next.component !== 'function'\n || next.children !== undefined || next.store !== undefined || next.locale !== undefined || next.select !== undefined) {\n restored = true; stopPicker()\n model.reportFailure(failureMessage())\n return\n }\n try {\n stopMirror = slots.register({ name: TEMP_WORKSPACE_FLOW_SLOT, ...next.inject ? { inject: next.inject } : {} }, next.component)\n mirror = next\n } catch (error) {\n restored = true; stopPicker()\n model.reportFailure(error instanceof Error ? error.message : 'Could not extend the workspace picker')\n }\n }\n const stopSource = slots.subscribe(DIRECTORY_SLOT, sync)\n sync()\n return () => { restored = true; stopErrors(); stopSource(); stopMirror(); stopPicker() }\n })\n}\n\n/** Standard conversation hero owner share; some published type graphs omit its merge. */\ntype PickerProps = Pick<WorkspacePickerProps, 'useWorkspaces'> & {\n open: boolean\n anchorRef?: RefObject<HTMLElement | null>\n selectedId?: string\n onPick(workspaceId: string): void\n onClose(): void\n t(key: string): string\n renderSlot(key: typeof TEMP_WORKSPACE_FLOW_SLOT, owner: DirectoryFlowOwnerProps): ReactNode\n}\n\nfunction TemporaryWorkspacePicker(props: PickerProps & {\n model: TemporaryWorkspaceModel; createWorkspace(path: string): Promise<{ workspaceId: string }>\n getDirectoryFlow(): StoredEntry | undefined; subscribeFlow(listener: () => void): () => void\n locale?: { getSnapshot(): { active: string }; subscribe(listener: () => void): () => void }\n}) {\n const workspaces = props.useWorkspaces(snapshot => snapshot)\n const state = useSyncExternalStore(props.model.subscribe, props.model.getSnapshot, props.model.getSnapshot)\n const source = useSyncExternalStore(props.subscribeFlow, props.getDirectoryFlow, props.getDirectoryFlow)\n const available = source !== undefined\n const locale = copyLocale(useSyncExternalStore(listener => props.locale?.subscribe(listener) ?? (() => {}),\n () => props.locale?.getSnapshot().active ?? 'en', () => 'en'))\n const [flowOpen, setFlowOpen] = useState(false), [adopting, setAdopting] = useState(false)\n const [failure, setFailure] = useState<string>()\n const epoch = useRef(0)\n useEffect(() => () => { epoch.current++ }, [])\n useEffect(() => { epoch.current++; setFlowOpen(false); setAdopting(false) }, [source])\n const busy = flowOpen || adopting || state.creating\n const getAnchorRect = useCallback(() => props.anchorRef?.current?.getBoundingClientRect() ?? null, [props.anchorRef])\n const openDirectory = () => { props.onClose(); setFailure(undefined); setFlowOpen(true) }\n return <>\n <Menu open={props.open} anchor={null} portal getAnchorRect={getAnchorRect} selectedId={props.selectedId}\n onClose={props.onClose} items={workspaces.items.map(workspace => ({ id: workspace.workspaceId,\n // The standard registry's first-use title is language-neutral; all user titles stay verbatim.\n label: workspace.title === 'default-workspace' ? props.t('workspace.defaultName') : workspace.title,\n icon: <IconFolderCloseRegular size={16} />, disabled: busy }))}\n footer={[\n ...available ? [{ id: '::add-workspace', label: props.t('menu.addWorkspace'), icon: <IconPlusOutlineRegular size={16} />, disabled: busy }] : [],\n { id: '::temporary-workspace', label: uiText(locale, 'tempWorkspace'), icon: <FreeChatIcon size={16} />, disabled: busy },\n ]}\n onSelect={id => {\n if (id === '::add-workspace') openDirectory()\n else if (id === '::temporary-workspace') { props.onClose(); void props.model.create() }\n else props.onPick(id as never)\n }} />\n {props.open && workspaces.phase === 'pending' && <span role=\"status\">{props.t('picker.loading')}</span>}\n {props.renderSlot(TEMP_WORKSPACE_FLOW_SLOT, {\n open: flowOpen, busy: adopting,\n onCancel: () => { epoch.current++; setFlowOpen(false); setAdopting(false) },\n onError: message => { epoch.current++; setFlowOpen(false); setAdopting(false); setFailure(message) },\n onPicked: path => {\n if (adopting) return\n const ticket = ++epoch.current\n setAdopting(true)\n void props.createWorkspace(path).then(workspace => {\n if (ticket !== epoch.current) return\n setFlowOpen(false); props.onPick(workspace.workspaceId as never)\n }, error => {\n if (ticket !== epoch.current) return\n setFlowOpen(false); setFailure(error instanceof Error ? error.message : String(error))\n }).finally(() => { if (ticket === epoch.current) setAdopting(false) })\n },\n })}\n <Modal open={failure !== undefined} title={props.t('folderError.title')} closeLabel={props.t('close')}\n onClose={() => setFailure(undefined)} footer={<>\n <Button variant=\"outline\" onClick={() => setFailure(undefined)}>{props.t('cancel')}</Button>\n <Button variant=\"primary\" disabled={!available} onClick={openDirectory}>{props.t('folderError.retry')}</Button>\n </>}><p role=\"alert\">{failure}</p></Modal>\n </>\n}\n\nexport function TemporaryWorkspaceNotice({ model, locale }: { model: TemporaryWorkspaceModel; locale: CopyLocale }) {\n const state = useSyncExternalStore(model.subscribe, model.getSnapshot, model.getSnapshot)\n return <Modal open={state.failure !== undefined} title={uiText(locale, 'createFailed')}\n closeLabel={uiText(locale, 'close')} onClose={model.dismissFailure} footer={<>\n <Button variant=\"outline\" onClick={model.dismissFailure}>{uiText(locale, 'close')}</Button>\n <Button variant=\"primary\" disabled={state.creating} onClick={() => { void model.create() }}>{uiText(locale, 'retry')}</Button>\n </>}><p role=\"alert\">{state.failure}</p></Modal>\n}\n","import { TEMP_WORKSPACE_CHANNEL } from './contracts.ts'\n\nexport interface TemporaryWorkspaceHost {\n beginNavigation(): AbortSignal\n allocate(requestId: string, signal: AbortSignal): Promise<{ requestId: string; path: string }>\n createWorkspace(path: string): Promise<{ workspaceId: string }>\n renameWorkspace(workspaceId: string, title: string): Promise<unknown>\n openWorkspace(workspaceId: string, beforeOpen: () => void): Promise<void>\n}\n\nexport interface TemporaryWorkspaceSnapshot {\n readonly creating: boolean\n readonly failure?: string\n}\n\nexport function createTemporaryWorkspaceModel(host: TemporaryWorkspaceHost, ids = () => crypto.randomUUID(), label = () => 'Temporary Workspace') {\n const lifetime = new AbortController(), listeners = new Set<() => void>()\n let snapshot: TemporaryWorkspaceSnapshot = { creating: false }\n let pending: { requestId: string; title: string; path?: string; workspaceId?: string; named?: boolean } | undefined\n const publish = (next: TemporaryWorkspaceSnapshot) => {\n if (lifetime.signal.aborted) return\n snapshot = next\n for (const listener of listeners) listener()\n }\n return {\n getSnapshot: () => snapshot,\n subscribe(listener: () => void) { listeners.add(listener); return () => { listeners.delete(listener) } },\n dismissFailure() { publish({ creating: snapshot.creating }) },\n reportFailure(failure: string) { publish({ ...snapshot, failure }) },\n async create() {\n if (snapshot.creating || lifetime.signal.aborted) return\n // Capture before allocation/adoption so late completion cannot steal a newer navigation.\n const signal = AbortSignal.any([host.beginNavigation(), lifetime.signal])\n const action = pending ??= { requestId: ids(), title: label() }\n let opening = false\n publish({ creating: true })\n try {\n signal.throwIfAborted()\n if (action.path === undefined) {\n const allocated = await host.allocate(action.requestId, signal)\n if (allocated.requestId !== action.requestId || !allocated.path) throw new Error('Invalid temporary workspace response')\n action.path = allocated.path\n }\n signal.throwIfAborted()\n if (action.workspaceId === undefined) action.workspaceId = (await host.createWorkspace(action.path)).workspaceId\n signal.throwIfAborted()\n if (!action.named) {\n await host.renameWorkspace(action.workspaceId, `${action.title} ${action.requestId.slice(0, 8)}`)\n action.named = true\n }\n signal.throwIfAborted()\n opening = true\n await host.openWorkspace(action.workspaceId, () => lifetime.signal.throwIfAborted())\n // openWorkspace starts its own fenced navigation, invalidating our earlier signal.\n if (!lifetime.signal.aborted) pending = undefined\n } catch (error) {\n if (!lifetime.signal.aborted && (opening ? !(error instanceof Error && error.name === 'AbortError') : !signal.aborted)) {\n publish({ creating: false, failure: error instanceof Error ? error.message : 'Could not create the temporary workspace' })\n }\n } finally {\n publish({ ...snapshot, creating: false })\n }\n },\n cancel() { lifetime.abort(); listeners.clear() },\n }\n}\n\nexport type TemporaryWorkspaceModel = ReturnType<typeof createTemporaryWorkspaceModel>\n\nexport function bindTemporaryWorkspaceHost(ctx: {\n layout: { beginNavigation(): AbortSignal }\n connection: { rpc: { call(channel: string, endpoint: string, payload: unknown, signal?: AbortSignal): Promise<unknown> } }\n workspaces: { create(input: { path: string }): Promise<{ workspaceId: string }>; rename(workspaceId: string, title: string): Promise<unknown> }\n uiWorkspace: { openWorkspace(workspaceId: string, beforeOpen?: () => void): Promise<void> }\n}): TemporaryWorkspaceHost {\n return {\n beginNavigation: () => ctx.layout.beginNavigation(),\n async allocate(requestId, signal) {\n const raw = await ctx.connection.rpc.call(TEMP_WORKSPACE_CHANNEL, 'temporary.allocate', { requestId }, signal)\n const response = raw as { ok?: boolean; value?: { requestId: string; path: string }; error?: { message?: string } }\n if (response?.ok !== true || typeof response.value?.path !== 'string' || typeof response.value.requestId !== 'string') {\n throw new Error(response?.error?.message ?? 'Could not allocate the temporary workspace')\n }\n return response.value\n },\n createWorkspace: path => ctx.workspaces.create({ path }),\n renameWorkspace: (workspaceId, title) => ctx.workspaces.rename(workspaceId, title),\n openWorkspace: (workspaceId, beforeOpen) => ctx.uiWorkspace.openWorkspace(workspaceId, beforeOpen),\n }\n}\n","/**\n * Narrow client faces the host owner still has to publish.\n * Call these only when the live service actually has the method.\n * Do not call the session remote directly: manager.create still drops `kind`,\n * and delete/retry have to update the catalog and the open selection.\n */\nimport type { OperationFailure } from './ui-copy.ts'\nimport type { SessionListSnapshot } from './free-list.ts'\n\nexport interface SessionCapabilities {\n readonly retry: boolean\n readonly freeSession: boolean\n readonly deleteSession: boolean\n}\n\nexport const UNSUPPORTED_CAPABILITIES: SessionCapabilities = {\n retry: false,\n freeSession: false,\n deleteSession: false,\n}\n\n/**\n * `inputRevision` is an opaque token from preview.\n * An eligible preview without it is not a supported retry.\n */\nexport interface RetryPreview {\n readonly branchRevision: number\n readonly inputRevision: string\n readonly eligible: boolean\n readonly reason?: string\n}\n\n/** Direct retry omits `text` so the host keeps the original attachments. */\nexport interface DirectRetryRequest {\n readonly sessionId: string\n readonly messageId: string\n readonly expectedRevision: number\n readonly expectedInputRevision: string\n readonly requestId: string\n}\n\n/** Edit sends plain text only. The host keeps attachments. */\nexport interface EditRetryRequest extends DirectRetryRequest {\n readonly text: string\n}\n\nexport interface DeleteOutcome {\n readonly phase: 'deleted' | 'cleanup-pending'\n}\n\nexport interface ObservableList {\n getSnapshot(): SessionListSnapshot\n subscribe(listener: () => void): () => void\n}\n\nexport interface SessionHost {\n readonly list: ObservableList\n capabilities?: () => Promise<unknown> | unknown\n create?: (opts: { kind: 'free' }) => Promise<unknown>\n previewRetry?: (request: { sessionId: string; messageId: string }) => Promise<unknown>\n retry?: (request: DirectRetryRequest | EditRetryRequest) => Promise<unknown>\n openSession?: (sessionId: string) => void\n deleteSession?: (sessionId: string, requestId: string) => Promise<unknown>\n}\n\ninterface RemoteFailure {\n readonly code?: string\n readonly message?: string\n readonly details?: { readonly reason?: string }\n}\n\ninterface RemoteResult {\n readonly ok: boolean\n readonly value?: unknown\n readonly error?: RemoteFailure\n}\n\nexport function isRecoverable(failure: OperationFailure): boolean {\n return failure.code === 'transport' || failure.code === 'session/delete-pending'\n}\n\nexport function readFailure(error: unknown): OperationFailure {\n if (isFailure(error)) return { code: error.code, ...error.reason === undefined ? {} : { reason: error.reason } }\n if (typeof error === 'object' && error !== null) {\n const record = error as { code?: unknown; reason?: unknown; message?: unknown; rpcError?: RemoteFailure }\n const rpc = record.rpcError\n if (typeof rpc?.code === 'string') {\n return { code: rpc.code, ...reasonOf(rpc) === undefined ? {} : { reason: reasonOf(rpc) } }\n }\n if (typeof record.code === 'string') {\n const reason = typeof record.reason === 'string' ? record.reason : undefined\n return { code: record.code, ...reason === undefined ? {} : { reason } }\n }\n }\n return { code: 'transport', reason: 'unknown' }\n}\n\nfunction isFailure(error: unknown): error is OperationFailure {\n return typeof error === 'object' && error !== null && 'code' in error && typeof (error as { code: unknown }).code === 'string'\n && (error as { name?: string }).name === 'HostOperationError'\n}\n\nexport class HostOperationError extends Error implements OperationFailure {\n override readonly name = 'HostOperationError'\n readonly reason?: string\n constructor(readonly code: string, reason?: string) {\n super(code)\n if (reason !== undefined) this.reason = reason\n }\n}\n\nfunction reasonOf(error: RemoteFailure | undefined): string | undefined {\n return typeof error?.details?.reason === 'string' ? error.details.reason : undefined\n}\n\nfunction isRemoteResult(value: unknown): value is RemoteResult {\n if (typeof value !== 'object' || value === null || !('ok' in value)) return false\n const ok = (value as { ok: unknown }).ok\n return typeof ok === 'boolean' && ('value' in value || 'error' in value)\n}\n\nexport async function unwrap(value: unknown): Promise<unknown> {\n const resolved = await value\n if (!isRemoteResult(resolved)) return resolved\n if (!resolved.ok) {\n throw new HostOperationError(resolved.error?.code ?? 'transport', reasonOf(resolved.error))\n }\n return resolved.value\n}\n\nexport async function readCapabilities(host: SessionHost): Promise<SessionCapabilities> {\n if (typeof host.capabilities !== 'function') return UNSUPPORTED_CAPABILITIES\n try {\n const value = await unwrap(host.capabilities())\n if (typeof value !== 'object' || value === null) return UNSUPPORTED_CAPABILITIES\n const record = value as Partial<SessionCapabilities>\n return {\n retry: record.retry === true,\n freeSession: record.freeSession === true,\n deleteSession: record.deleteSession === true,\n }\n } catch {\n return UNSUPPORTED_CAPABILITIES\n }\n}\n\nexport function controlsFor(capabilities: SessionCapabilities, ready: boolean, host: SessionHost): {\n create: boolean\n delete: boolean\n retry: boolean\n} {\n return {\n create: ready && capabilities.freeSession && typeof host.create === 'function',\n delete: ready && capabilities.deleteSession && typeof host.deleteSession === 'function',\n retry: ready && capabilities.retry && typeof host.previewRetry === 'function' && typeof host.retry === 'function',\n }\n}\n\nfunction sessionIdOf(value: unknown): string {\n if (typeof value === 'string' && value !== '') return value\n if (typeof value === 'object' && value !== null && typeof (value as { sessionId?: unknown }).sessionId === 'string') {\n return (value as { sessionId: string }).sessionId\n }\n throw new HostOperationError('session/lifecycle-unavailable')\n}\n\n/** Pass only `{ kind: 'free' }`. A cwd or workspace is rejected by free create, and must not be invented. */\nexport async function createFreeSession(host: SessionHost): Promise<string> {\n if (typeof host.create !== 'function') throw new HostOperationError('session/lifecycle-unavailable')\n return sessionIdOf(await unwrap(host.create({ kind: 'free' })))\n}\n\nexport async function deleteOwnedSession(host: SessionHost, sessionId: string, requestId: string): Promise<DeleteOutcome> {\n if (typeof host.deleteSession !== 'function') throw new HostOperationError('session/lifecycle-unavailable')\n const value = await unwrap(host.deleteSession(sessionId, requestId))\n if (typeof value !== 'object' || value === null) throw new HostOperationError('session/delete-pending', 'missing-outcome')\n const phase = (value as { phase?: unknown }).phase\n if (phase !== 'deleted' && phase !== 'cleanup-pending') {\n throw new HostOperationError('session/delete-pending', 'missing-outcome')\n }\n return { phase }\n}\n\nexport function directRetryRequest(input: {\n sessionId: string\n messageId: string\n expectedRevision: number\n expectedInputRevision: string\n requestId: string\n}): DirectRetryRequest {\n return {\n sessionId: input.sessionId,\n messageId: input.messageId,\n expectedRevision: input.expectedRevision,\n expectedInputRevision: input.expectedInputRevision,\n requestId: input.requestId,\n }\n}\n\nexport function editRetryRequest(input: DirectRetryRequest & { text: string }): EditRetryRequest {\n return { ...directRetryRequest(input), text: input.text }\n}\n\nexport class SubmissionLedger {\n private active = false\n private unresolved: DirectRetryRequest | EditRetryRequest | undefined\n\n get busy(): boolean {\n return this.active\n }\n\n pending(): DirectRetryRequest | EditRetryRequest | undefined {\n return this.unresolved\n }\n\n /** Resend the stored body. A non-recoverable result drops it; a lost reply keeps it. */\n async replay(execute: (body: DirectRetryRequest | EditRetryRequest) => Promise<unknown>): Promise<void> {\n const body = this.unresolved\n if (body === undefined) return\n if (this.active) throw new HostOperationError('busy', 'running')\n this.active = true\n try {\n await execute(body)\n this.unresolved = undefined\n } catch (error) {\n const failure = readFailure(error)\n if (!isRecoverable(failure) && failure.reason !== 'aborted') this.unresolved = undefined\n throw error instanceof HostOperationError ? error : new HostOperationError(failure.code, failure.reason)\n } finally {\n this.active = false\n }\n }\n\n /** First submission of a body built from the current preview. */\n async submit(body: DirectRetryRequest | EditRetryRequest, execute: () => Promise<unknown>): Promise<void> {\n if (this.active || this.unresolved !== undefined) throw new HostOperationError('busy', 'running')\n this.active = true\n try {\n await execute()\n this.unresolved = undefined\n } catch (error) {\n const failure = readFailure(error)\n this.unresolved = isRecoverable(failure) ? body : undefined\n throw error instanceof HostOperationError ? error : new HostOperationError(failure.code, failure.reason)\n } finally {\n this.active = false\n }\n }\n}\n\ninterface Listener {\n (): void\n}\n\nfunction store() {\n const listeners = new Set<Listener>()\n return {\n subscribe(listener: Listener): () => void {\n listeners.add(listener)\n return () => { listeners.delete(listener) }\n },\n emit(): void {\n for (const listener of listeners) listener()\n },\n }\n}\n\nexport interface DeleteRequestState {\n readonly sessionId: string\n readonly title: string\n readonly classification: 'free' | 'ordinary'\n readonly requestId: string\n readonly busy: boolean\n readonly failure?: OperationFailure\n}\n\nexport interface FreeChatSnapshot {\n readonly controls: ReturnType<typeof controlsFor>\n readonly capabilitiesReady: boolean\n readonly creating: boolean\n readonly notice?: OperationFailure\n readonly deleteRequest?: DeleteRequestState\n}\n\nexport interface FreeChatModel {\n subscribe(listener: Listener): () => void\n getSnapshot(): FreeChatSnapshot\n reloadCapabilities(): Promise<void>\n create(): Promise<void>\n dismissNotice(): void\n requestDelete(sessionId: string): void\n cancelDelete(): void\n confirmDelete(): Promise<void>\n cancel(): void\n}\n\nexport function createFreeChatModel(host: SessionHost, ids: () => string = () => crypto.randomUUID()): FreeChatModel {\n const events = store()\n let capabilities = UNSUPPORTED_CAPABILITIES\n let capabilitiesReady = false\n let creating = false\n let notice: OperationFailure | undefined\n let deleteRequest: DeleteRequestState | undefined\n let generation = 0\n let snapshot: FreeChatSnapshot = build()\n\n function build(): FreeChatSnapshot {\n return {\n controls: controlsFor(capabilities, capabilitiesReady, host),\n capabilitiesReady,\n creating,\n ...notice === undefined ? {} : { notice },\n ...deleteRequest === undefined ? {} : { deleteRequest },\n }\n }\n\n function publish(): void {\n snapshot = build()\n events.emit()\n }\n\n return {\n subscribe: events.subscribe,\n getSnapshot: () => snapshot,\n async reloadCapabilities() {\n capabilities = await readCapabilities(host)\n capabilitiesReady = true\n publish()\n },\n async create() {\n if (!controlsFor(capabilities, capabilitiesReady, host).create || creating) return\n const ticket = generation\n creating = true\n notice = undefined\n publish()\n try {\n const id = await createFreeSession(host)\n if (ticket !== generation) return\n if (typeof host.openSession !== 'function') throw new HostOperationError('session/lifecycle-unavailable', 'open-session')\n host.openSession(id)\n } catch (error) {\n if (ticket !== generation) return\n notice = readFailure(error)\n } finally {\n if (ticket === generation) {\n creating = false\n publish()\n }\n }\n },\n dismissNotice() {\n if (notice === undefined) return\n notice = undefined\n publish()\n },\n requestDelete(sessionId) {\n if (!controlsFor(capabilities, capabilitiesReady, host).delete) return\n const row = host.list.getSnapshot().byId[sessionId]\n deleteRequest = {\n sessionId,\n title: row?.displayTitle ?? row?.title ?? sessionId,\n classification: row?.classification === 'free' ? 'free' : 'ordinary',\n requestId: ids(),\n busy: false,\n }\n publish()\n },\n cancelDelete() {\n if (deleteRequest?.busy) return\n deleteRequest = undefined\n publish()\n },\n async confirmDelete() {\n const current = deleteRequest\n if (current === undefined || current.busy) return\n const ticket = generation\n deleteRequest = { ...current, busy: true, failure: undefined }\n publish()\n try {\n const outcome = await deleteOwnedSession(host, current.sessionId, current.requestId)\n if (ticket !== generation) return\n if (outcome.phase !== 'deleted') {\n deleteRequest = {\n ...current,\n busy: false,\n failure: { code: 'session/delete-pending', reason: 'pending' },\n }\n publish()\n return\n }\n // The host clears the open selection itself; there is no panel to jump to.\n deleteRequest = undefined\n } catch (error) {\n if (ticket !== generation) return\n const failure = readFailure(error)\n deleteRequest = { ...current, busy: false, failure }\n }\n if (ticket === generation) publish()\n },\n cancel() {\n generation += 1\n creating = false\n notice = undefined\n deleteRequest = undefined\n publish()\n },\n }\n}\n\nexport interface RetrySnapshot {\n readonly controlsRetry: boolean\n readonly busy: boolean\n readonly editing: boolean\n readonly draft: string\n readonly sessionId: string\n readonly messageId: string\n readonly failure?: OperationFailure\n}\n\nexport interface RetryModel {\n subscribe(listener: Listener): () => void\n getSnapshot(): RetrySnapshot\n load(): Promise<void>\n retry(sessionId: string, messageId: string, signal: AbortSignal): Promise<void>\n beginEdit(sessionId: string, messageId: string, text: string, signal: AbortSignal): Promise<void>\n setDraft(text: string): void\n cancelEdit(): void\n sendEdit(sessionId: string, messageId: string, signal: AbortSignal): Promise<void>\n retire(sessionId: string, messageId: string): void\n cancel(): void\n}\n\nexport function createRetryModel(host: SessionHost, ids: () => string = () => crypto.randomUUID()): RetryModel {\n const events = store()\n const ledger = new SubmissionLedger()\n let capabilities = UNSUPPORTED_CAPABILITIES\n let ready = false\n let busy = false\n let editing = false\n let draft = ''\n let failure: OperationFailure | undefined\n let expectedRevision = 0\n let expectedInputRevision = ''\n let ownerSession = ''\n let ownerMessage = ''\n let call = 0\n let snapshot: RetrySnapshot = build()\n\n function build(): RetrySnapshot {\n return {\n controlsRetry: controlsFor(capabilities, ready, host).retry,\n busy,\n editing,\n draft,\n sessionId: ownerSession,\n messageId: ownerMessage,\n ...failure === undefined ? {} : { failure },\n }\n }\n\n function publish(): void {\n snapshot = build()\n events.emit()\n }\n\n function readPreview(value: unknown): RetryPreview {\n if (typeof value !== 'object' || value === null || typeof (value as { branchRevision?: unknown }).branchRevision !== 'number') {\n throw new HostOperationError('session/lifecycle-unavailable')\n }\n const record = value as { branchRevision: number; eligible?: boolean; reason?: string; inputRevision?: unknown }\n const inputRevision = typeof record.inputRevision === 'string' ? record.inputRevision : ''\n const eligible = record.eligible === true\n if (eligible && inputRevision === '') throw new HostOperationError('session/lifecycle-unavailable', 'input-revision')\n return {\n branchRevision: record.branchRevision,\n inputRevision,\n eligible,\n ...typeof record.reason === 'string' ? { reason: record.reason } : {},\n }\n }\n\n async function preview(sessionId: string, id: string, signal: AbortSignal, ticket: number): Promise<RetryPreview | undefined> {\n if (ticket !== call || signal.aborted) return undefined\n if (typeof host.previewRetry !== 'function') throw new HostOperationError('session/lifecycle-unavailable')\n const value = await unwrap(host.previewRetry({ sessionId, messageId: id }))\n if (ticket !== call || signal.aborted) return undefined\n return readPreview(value)\n }\n\n async function callRetry(body: DirectRetryRequest | EditRetryRequest, signal: AbortSignal, ticket: number): Promise<void> {\n if (signal.aborted || ticket !== call) throw new HostOperationError('busy', 'aborted')\n if (typeof host.retry !== 'function') throw new HostOperationError('session/lifecycle-unavailable')\n await unwrap(host.retry(body))\n }\n\n function settle(): void {\n if (!ledger.busy) busy = false\n publish()\n }\n\n async function replaySame(signal: AbortSignal): Promise<void> {\n if (signal.aborted) return\n const pending = ledger.pending()\n const ticket = ++call\n busy = true\n failure = undefined\n publish()\n try {\n await ledger.replay(async body => { await callRetry(body, signal, ticket) })\n if (\n pending !== undefined\n && ticket === call\n && !signal.aborted\n && ownerSession === pending.sessionId\n && ownerMessage === pending.messageId\n ) editing = false\n } catch (error) {\n if (ticket === call && !signal.aborted) failure = readFailure(error)\n } finally {\n settle()\n }\n }\n\n function samePending(sessionId: string, id: string): boolean {\n const pending = ledger.pending()\n return pending !== undefined && pending.sessionId === sessionId && pending.messageId === id\n }\n\n return {\n subscribe: events.subscribe,\n getSnapshot: () => snapshot,\n async load() {\n capabilities = await readCapabilities(host)\n ready = true\n publish()\n },\n async retry(sessionId, id, signal) {\n if (busy || !controlsFor(capabilities, ready, host).retry || signal.aborted) return\n if (ledger.pending() !== undefined) {\n if (!samePending(sessionId, id)) return\n await replaySame(signal)\n return\n }\n const ticket = ++call\n busy = true\n failure = undefined\n editing = false\n ownerSession = sessionId\n ownerMessage = id\n publish()\n try {\n const seen = await preview(sessionId, id, signal, ticket)\n if (seen === undefined) return\n if (!seen.eligible) {\n failure = { code: 'session/retry-blocked', reason: seen.reason ?? 'unknown' }\n return\n }\n if (signal.aborted || ticket !== call) return\n expectedRevision = seen.branchRevision\n expectedInputRevision = seen.inputRevision\n const body = directRetryRequest({\n sessionId,\n messageId: id,\n expectedRevision: seen.branchRevision,\n expectedInputRevision: seen.inputRevision,\n requestId: ids(),\n })\n await ledger.submit(body, () => callRetry(body, signal, ticket))\n } catch (error) {\n if (ticket === call && !signal.aborted) failure = readFailure(error)\n } finally {\n settle()\n }\n },\n async beginEdit(sessionId, id, text, signal) {\n if (busy || !controlsFor(capabilities, ready, host).retry || signal.aborted) return\n if (ledger.pending() !== undefined) {\n if (!samePending(sessionId, id)) return\n await replaySame(signal)\n return\n }\n const ticket = ++call\n busy = true\n failure = undefined\n ownerSession = sessionId\n ownerMessage = id\n publish()\n try {\n const seen = await preview(sessionId, id, signal, ticket)\n if (seen === undefined) return\n if (!seen.eligible) {\n failure = { code: 'session/retry-blocked', reason: seen.reason ?? 'unknown' }\n return\n }\n if (signal.aborted || ticket !== call) return\n expectedRevision = seen.branchRevision\n expectedInputRevision = seen.inputRevision\n draft = text\n editing = true\n } catch (error) {\n if (ticket === call && !signal.aborted) failure = readFailure(error)\n } finally {\n settle()\n }\n },\n setDraft(text) {\n if (!editing || ownerSession === '' || ownerMessage === '') return\n draft = text\n publish()\n },\n cancelEdit() {\n if (busy) return\n editing = false\n publish()\n },\n async sendEdit(sessionId, id, signal) {\n if (signal.aborted || busy || !controlsFor(capabilities, ready, host).retry) return\n if (!editing || ownerSession !== sessionId || ownerMessage !== id) return\n if (ledger.pending() !== undefined) {\n if (!samePending(sessionId, id)) return\n await replaySame(signal)\n return\n }\n const ticket = ++call\n busy = true\n failure = undefined\n const text = draft\n publish()\n try {\n if (signal.aborted || ticket !== call) return\n const body = editRetryRequest({\n sessionId,\n messageId: id,\n expectedRevision,\n expectedInputRevision,\n requestId: ids(),\n text,\n })\n await ledger.submit(body, () => callRetry(body, signal, ticket))\n if (ticket === call && !signal.aborted) editing = false\n } catch (error) {\n if (ticket === call && !signal.aborted) failure = readFailure(error)\n } finally {\n settle()\n }\n },\n retire(sessionId, messageId) {\n if (ownerSession !== sessionId || ownerMessage !== messageId) return\n call += 1\n editing = false\n failure = undefined\n draft = ''\n if (!ledger.busy) busy = false\n publish()\n },\n cancel() {\n call += 1\n editing = false\n failure = undefined\n if (!ledger.busy) busy = false\n publish()\n },\n }\n}\n\nexport function bindHost(ctx: {\n sessions?: {\n list?: ObservableList\n capabilities?: SessionHost['capabilities']\n create?: (opts?: { workspaceId?: string; cwd?: string; sessionId?: string }) => Promise<unknown>\n previewRetry?: SessionHost['previewRetry']\n retry?: SessionHost['retry']\n }\n uiWorkspace?: {\n openSession?: SessionHost['openSession']\n deleteSession?: SessionHost['deleteSession']\n }\n}): SessionHost {\n const sessions = ctx.sessions\n const workspace = ctx.uiWorkspace\n const empty: ObservableList = {\n getSnapshot: () => ({ ids: [], byId: {}, phase: 'ready' }),\n subscribe: () => () => {},\n }\n return {\n list: sessions?.list ?? empty,\n ...typeof sessions?.capabilities === 'function' ? { capabilities: () => sessions.capabilities!() } : {},\n ...typeof sessions?.create === 'function'\n ? { create: (opts: { kind: 'free' }) => (sessions.create as (input: { kind: 'free' }) => Promise<unknown>)(opts) }\n : {},\n ...typeof sessions?.previewRetry === 'function' ? { previewRetry: request => sessions.previewRetry!(request) } : {},\n ...typeof sessions?.retry === 'function' ? { retry: request => sessions.retry!(request) } : {},\n ...typeof workspace?.openSession === 'function' ? { openSession: sessionId => workspace.openSession!(sessionId) } : {},\n ...typeof workspace?.deleteSession === 'function' ? { deleteSession: (sessionId, requestId) => workspace.deleteSession!(sessionId, requestId) } : {},\n }\n}\n","import { useEffect, useRef, useSyncExternalStore } from 'react'\nimport { Button, Modal, Tooltip } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { RetryModel } from './session-actions.ts'\nimport { FREE_CHAT_ROOT } from './styles.ts'\nimport { failureText, uiText, type CopyLocale } from './ui-copy.ts'\n\nexport function UserMessageActions(props: {\n messageId: string\n text: string\n sessionId: string\n locale: CopyLocale\n model: RetryModel\n}): React.ReactElement | null {\n const snapshot = useSyncExternalStore(props.model.subscribe, props.model.getSnapshot, props.model.getSnapshot)\n const signal = useRef<AbortController>(new AbortController())\n useEffect(() => {\n const controller = new AbortController()\n signal.current = controller\n return () => {\n controller.abort()\n props.model.retire(props.sessionId, props.messageId)\n }\n }, [props.model, props.sessionId, props.messageId])\n if (props.sessionId === '' || !snapshot.controlsRetry) return null\n const mine = snapshot.sessionId === props.sessionId && snapshot.messageId === props.messageId\n const copy = (key: Parameters<typeof uiText>[1]) => uiText(props.locale, key)\n const failure = mine ? snapshot.failure : undefined\n const editing = mine && snapshot.editing\n const draft = mine ? snapshot.draft : props.text\n return (\n <span className={`${FREE_CHAT_ROOT} dsh-free-actions`}>\n <Tooltip label={copy('retry')} side=\"bottom\">\n <Button\n size=\"sm\"\n variant=\"ghost\"\n aria-label={copy('retry')}\n disabled={snapshot.busy}\n onClick={() => { void props.model.retry(props.sessionId, props.messageId, signal.current.signal) }}\n >\n {copy('retry')}\n </Button>\n </Tooltip>\n <Tooltip label={copy('edit')} side=\"bottom\">\n <Button\n size=\"sm\"\n variant=\"ghost\"\n aria-label={copy('edit')}\n disabled={snapshot.busy}\n onClick={() => { void props.model.beginEdit(props.sessionId, props.messageId, props.text, signal.current.signal) }}\n >\n {copy('edit')}\n </Button>\n </Tooltip>\n {failure ? <span className=\"dsh-ui-error dsh-free-alert\" role=\"alert\">{failureText(props.locale, failure)}</span> : null}\n <Modal\n open={editing}\n className={FREE_CHAT_ROOT}\n title={copy('editTitle')}\n closeLabel={copy('close')}\n onClose={() => { props.model.cancelEdit() }}\n footer={(\n <>\n <Button variant=\"ghost\" disabled={snapshot.busy} onClick={() => { props.model.cancelEdit() }}>{copy('cancel')}</Button>\n <Button\n variant=\"primary\"\n data-modal-autofocus\n disabled={snapshot.busy}\n onClick={() => { void props.model.sendEdit(props.sessionId, props.messageId, signal.current.signal) }}\n >\n {copy('send')}\n </Button>\n </>\n )}\n >\n <textarea\n className=\"dsh-free-draft\"\n aria-label={copy('draft')}\n value={draft}\n onChange={event => { props.model.setDraft(event.target.value) }}\n />\n </Modal>\n </span>\n )\n}\n","import type { Context } from '@deepseek-ai/cordis'\nimport { MenuItemButton } from '@deepseek-ai/dsh-client-ui-primitives'\nimport { useState, useSyncExternalStore, type ComponentProps } from 'react'\nimport { CopyThreadShortcutNotice, writeClipboard, type HostShortcuts } from './copy-shortcut.tsx'\nimport {\n COPY_THREAD_FAILED,\n COPY_THREAD_LABEL,\n copyLocale,\n copyThreadId,\n type CopyLocale,\n} from './copy-action.ts'\nimport {\n COPY_THREAD_MENU_ID,\n COPY_THREAD_MENU_ORDER,\n COPY_THREAD_SHORTCUT_ID,\n DELETE_DIALOG_ID,\n USER_ACTIONS_ID,\n USER_ACTIONS_SLOT,\n} from './contracts.ts'\nimport { installContextMenuForwarding } from './context-menu.ts'\nimport { CreateNoticeDialog, DeleteChatDialog } from './free-panel.tsx'\nimport { installTemporaryWorkspacePicker, TemporaryWorkspaceNotice, type PickerRegistry } from './temporary-picker.tsx'\nimport { bindTemporaryWorkspaceHost, createTemporaryWorkspaceModel } from './temporary-workspace.ts'\nimport { bindHost, createFreeChatModel, createRetryModel, type FreeChatModel, type RetryModel } from './session-actions.ts'\nimport { freeChatCss } from './styles.ts'\nimport { UserMessageActions } from './user-actions.tsx'\nimport { uiText } from './ui-copy.ts'\n\nexport const name = 'dsh-session-manager-client'\nexport const inject = ['slots', 'locale', 'sessions', 'uiWorkspace', 'shortcuts', 'connection', 'workspaces', 'layout'] as const\n\ninterface LocaleService {\n getSnapshot(): { active: string }\n subscribe(listener: () => void): () => void\n register?(namespace: string, dictionaries: { zh: Record<string, string>; en: Record<string, string> }): (() => void) | void\n}\n\ninterface MenuProps {\n sessionId: string\n useMenuOpenState: () => [boolean, (open: boolean) => void]\n}\n\ninterface SlotRegistry {\n inject(key: string, callback: () => (() => void) | void): () => void\n register(spec: Record<string, unknown>, render: (props: never) => unknown): () => void\n}\n\ntype Client = Context & {\n slots: SlotRegistry\n locale?: LocaleService\n sessions?: Parameters<typeof bindHost>[0]['sessions']\n uiWorkspace?: Parameters<typeof bindHost>[0]['uiWorkspace']\n shortcuts?: HostShortcuts\n on?(name: string, listener: () => void): () => void\n}\n\nexport function CopyThreadMenuItem(props: MenuProps & {\n locale: CopyLocale\n writeText?: (value: string) => Promise<void>\n shortcut?: ComponentProps<typeof MenuItemButton>['shortcut']\n}) {\n const [failed, setFailed] = useState(false)\n const [, setMenuOpen] = props.useMenuOpenState()\n const label = failed ? COPY_THREAD_FAILED[props.locale] : COPY_THREAD_LABEL[props.locale]\n const onSelect = () => copyThreadId(props.sessionId, props.writeText ?? writeClipboard).then(() => {\n setFailed(false)\n setMenuOpen(false)\n }, () => {\n setFailed(true)\n })\n // MenuItemButton activates through the button click. A keydown wrapper here\n // would run before ui-primitives Menu.tsx applies its composition, modifier,\n // and repeat guards (packages/client/ui-primitives/src/Menu.tsx).\n return (\n <MenuItemButton separatorBefore shortcut={props.shortcut} onSelect={onSelect}>\n {label}\n </MenuItemButton>\n )\n}\n\n\nexport function apply(ctx: Context): void {\n const client = ctx as Client\n const host = bindHost(client)\n const chats = createFreeChatModel(host)\n const retries = createRetryModel(host)\n const temporaryHost = bindTemporaryWorkspaceHost(client as unknown as Parameters<typeof bindTemporaryWorkspaceHost>[0])\n const temporary = createTemporaryWorkspaceModel(temporaryHost, undefined,\n () => uiText(copyLocale(client.locale?.getSnapshot().active), 'tempWorkspace'))\n const currentLocale = () => client.locale?.getSnapshot().active\n client.effect(() => {\n const stops: Array<() => void> = []\n // The relay needs no host slot and no service; a non-browser host simply skips it.\n if (typeof document !== 'undefined') stops.push(installContextMenuForwarding(document))\n stops.push(client.slots.inject('sidebar.workspaces.session.menu.item', () => (\n client.slots.register({\n name: 'sidebar.workspaces.session.menu.item',\n id: COPY_THREAD_MENU_ID,\n order: COPY_THREAD_MENU_ORDER,\n }, props => <CopyThreadSlot locale={client.locale} shortcuts={client.shortcuts} {...props as MenuProps} />)\n )))\n stops.push(client.slots.inject('sidebar.workspaces.session.menu.item', () => (\n client.slots.register({\n name: 'sidebar.workspaces.session.menu.item',\n id: DELETE_DIALOG_ID,\n order: COPY_THREAD_MENU_ORDER + 10,\n }, props => <DeleteMenuItem locale={client.locale} model={chats} {...props as MenuProps} />)\n )))\n stops.push(installTemporaryWorkspacePicker(client.slots as unknown as PickerRegistry, temporary,\n temporaryHost.createWorkspace, client.locale))\n stops.push(client.slots.inject(USER_ACTIONS_SLOT, () => (\n client.slots.register({\n name: USER_ACTIONS_SLOT,\n id: USER_ACTIONS_ID,\n order: 10,\n inject: (sessionId: string) => ({ sessionId }),\n }, props => (\n <UserMessageActions\n messageId={(props as { messageId: string }).messageId}\n text={(props as { text: string }).text}\n sessionId={(props as { sessionId?: string }).sessionId ?? ''}\n locale={useLiveLocale(client.locale)}\n model={retries}\n />\n ))\n )))\n stops.push(client.slots.inject('shell.overlay', () => (\n client.slots.register({\n name: 'shell.overlay',\n id: DELETE_DIALOG_ID,\n order: 40,\n }, () => {\n const locale = useLiveLocale(client.locale)\n return (\n <>\n <style>{freeChatCss}</style>\n <CopyThreadShortcutNotice shortcuts={client.shortcuts} list={client.sessions?.list} locale={locale} currentLocale={currentLocale} />\n <TemporaryWorkspaceNotice model={temporary} locale={locale} />\n <DeleteChatDialog model={chats} locale={locale} />\n <CreateNoticeDialog model={chats} locale={locale} />\n </>\n )\n })\n )))\n const reset = client.on?.('connection/reset', () => {\n void chats.reloadCapabilities()\n void retries.load()\n })\n if (typeof reset === 'function') stops.push(reset)\n void chats.reloadCapabilities()\n void retries.load()\n return () => {\n chats.cancel()\n retries.cancel()\n temporary.cancel()\n for (const stop of stops) stop()\n }\n })\n}\n\nconst EMPTY_SHORTCUTS: ReturnType<HostShortcuts['catalog']['getSnapshot']> = []\n\nfunction CopyThreadSlot(props: MenuProps & { locale?: LocaleService; shortcuts?: HostShortcuts }) {\n const locale = useLiveLocale(props.locale)\n const shortcuts = useSyncExternalStore(\n listener => props.shortcuts?.catalog.subscribe(listener) ?? (() => {}),\n () => props.shortcuts?.catalog.getSnapshot() ?? EMPTY_SHORTCUTS,\n () => EMPTY_SHORTCUTS,\n )\n return <CopyThreadMenuItem sessionId={props.sessionId} useMenuOpenState={props.useMenuOpenState} locale={locale}\n shortcut={shortcuts.find(row => row.id === COPY_THREAD_SHORTCUT_ID)} />\n}\n\nfunction DeleteMenuItem(props: MenuProps & { locale?: LocaleService; model: FreeChatModel }): React.ReactElement | null {\n const locale = useLiveLocale(props.locale)\n const snapshot = useSyncExternalStore(props.model.subscribe, props.model.getSnapshot, props.model.getSnapshot)\n const [, setMenuOpen] = props.useMenuOpenState()\n if (!snapshot.controls.delete) return null\n return (\n <MenuItemButton onSelect={() => {\n props.model.requestDelete(props.sessionId)\n setMenuOpen(false)\n }}>\n {uiText(locale, 'deleteChat')}\n </MenuItemButton>\n )\n}\n\nfunction useLiveLocale(locale: LocaleService | undefined): CopyLocale {\n const active = useSyncExternalStore(\n listener => locale?.subscribe(listener) ?? (() => {}),\n () => locale?.getSnapshot().active ?? 'en',\n () => locale?.getSnapshot().active ?? 'en',\n )\n return copyLocale(active)\n}\n\nexport type { FreeChatModel, RetryModel }\n"],"mappings":";;;;;AAGA,MAAa,sBAAsB;AACnC,MAAa,0BAA0B;AAKvC,MAAa,yBAAyB;AACtC,MAAa,2BAA2B;AACxC,MAAa,oBAAoB;AACjC,MAAa,kBAAkB;AAC/B,MAAa,mBAAmB;;;ACThC,MAAa,oBAAgD;CAC3D,IAAI;CACJ,IAAI;AACN;AAEA,MAAa,qBAAiD;CAC5D,IAAI;CACJ,IAAI;AACN;AAEA,MAAa,qBAAiD;CAC5D,IAAI;CACJ,IAAI;AACN;AAEA,MAAa,yBAAqD;CAChE,IAAI;CACJ,IAAI;AACN;AAEA,SAAgB,WAAW,QAAwC;CACjE,OAAO,QAAQ,YAAY,CAAC,CAAC,WAAW,IAAI,IAAI,OAAO;AACzD;;AAGA,eAAsB,aAAa,WAAmB,WAA4D;CAChH,MAAM,UAAU,SAAS;AAC3B;;;ACpBA,eAAsB,eAAe,OAA8B;CACjE,MAAM,YAAY,WAAW,WAAW;CACxC,IAAI,cAAc,KAAA,GAAW,MAAM,IAAI,MAAM,uBAAuB;CACpE,MAAM,UAAU,UAAU,KAAK;AACjC;;;;AAKA,SAAgB,yBAAyB,EAAE,WAAW,MAAM,QAAQ,eAAe,YAAY,kBAM5F;CACD,MAAM,CAAC,QAAQ,cAAA,GAAaA,MAAAA,SAAAA,CAAkD,IAAI;CAClF,MAAM,YAAA,GAAWC,MAAAA,OAAAA,CAAO,CAAC;CACzB,CAAA,GAAA,MAAA,UAAA,OAAgB;EACd,IAAI,cAAc,KAAA,GAAW;EAC7B,IAAI,SAAS;EACb,MAAM,UAAU,WAAoB;GAClC,IAAI,QAAQ,UAAU;IAAE;IAAQ,KAAK,EAAE,SAAS;GAAQ,CAAC;EAC3D;EACA,MAAM,UAAU;GAAE,MAAM;GAAQ,WAAW,CAAC,WAAW,KAAK;EAAW;EACvE,MAAM,OAAO,UAAU,SAAS;GAC9B,IAAI;GACJ,aAAa,kBAAkB,WAAW,cAAc,CAAC;GACzD,SAAS;IAAC;IAAkB;IAAmB;GAAS;GACxD,UAAU;IACR,mBAAmB;IAAS,iBAAiB;IAC7C,eAAe;IAAS,aAAa;GACvC;GACA,SAAS,CAAC,QAAQ,UAAU;GAC5B,QAAQ,CAAC;GACT,QAAQ,SAAS;IACf,MAAM,SAAS,OAAO,OAAO,MAAM,YAAY,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CACzD,MAAK,SAAQ,KAAK,YAAY,YAAY,KAAK,CAAC;IACnD,IAAI,WAAW,KAAA,KAAa,QAAQ,UAAU,QAAQ,QAAQ,WAAW,YACvE,OAAO;KAAE,QAAQ;KAAW,QAAQ,uBAAuB,WAAW,cAAc,CAAC;IAAG;IAE1F,OAAO;KAAE,QAAQ;KAAW,MAAM;MAChC,aAAkB,OAAO,IAAI,SAAS,CAAC,CAAC,WAChC,OAAO,IAAI,SACX,OAAO,KAAK,CACpB;KACF;IAAE;GACJ;EACF,CAAC;EACD,aAAa;GAAE,SAAS;GAAO,KAAK;EAAE;CACxC,GAAG;EAAC;EAAW;EAAM;EAAe;CAAS,CAAC;CAC9C,OAAO,WAAW,OAAO,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAACC,sCAAAA,OAAD;EAE9B,OAAO,OAAO,SAAS,qBAAqB,mBAAA,CAAoB;EAChE,MAAM,OAAO,SAAS,YAAY,KAAA;EAClC,cAAc,UAAU,IAAI;CAC7B,GAJM,OAAO,GAIb;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACzCA,MAAM,eAAe;AACrB,MAAM,mBAAmB;;AAGzB,SAAgB,mBAAmB,QAAqC;CACtE,IAAI,OAAO,OAAO,YAAY,YAAY,OAAO;CACjD,MAAM,MAAM,OAAO,QAAQ,YAAY;CACvC,IAAI,QAAQ,QAAQ,IAAI,QAAQ,iBAAe,MAAM,MAAM,OAAO;CAClE,MAAM,UAAU,IAAI,cAAc,gBAAgB;CAClD,IAAI,YAAY,QAAQ,OAAQ,QAAwB,UAAU,YAAY,OAAO;CACrF,OAAO;AACT;;;;;AAMA,SAAgB,mBAAmB,OAAuB;CACxD,MAAM,SAAS,MAAM;CACrB,IAAI,WAAW,QAAQ,OAAQ,OAAmB,YAAY,YAAY,OAAO;CACjF,MAAM,UAAU,mBAAmB,MAAiB;CACpD,IAAI,YAAY,MAAM,OAAO;CAC7B,MAAM,eAAe;CACrB,QAAQ,MAAM;CACd,OAAO;AACT;;AAGA,SAAgB,6BAA6B,KAA2B;CACtE,MAAM,YAAY,UAAiB;EAAE,mBAAmB,KAAK;CAAE;CAC/D,IAAI,iBAAiB,eAAe,UAAU,IAAI;CAClD,aAAa;EAAE,IAAI,oBAAoB,eAAe,UAAU,IAAI;CAAE;AACxE;AC4D6D,OAAO,OAAO;;CAlFzE,SAAS;EACP;EACA;EACA;EACA;EACA;EACA;EACA;CACF;;CAEA,QAAQ;EAAC;EAAyB;EAAyB;EAAyB;CAAuB;;CAE3G,OAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;CACF;;CAEA,aAAa;EACX;EACA;EACA;CACF;;CAEA,QAAQ;EACN;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,OAAO;EACL;EACA;EACA;EACA;EACA;CACF;;CAEA,QAAQ;EAAC;EAAmB;EAAmB;EAAmB;CAAoB;;CAEtF,WAAW;EACT;EACA;EACA;EACA;EACA;CACF;;CAEA,SAAS;EACP;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;;CAEA,QAAQ;EACN;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;AAIyE,CAAqB,CAAC,CAAC,KAAK;;;;;;AAUvG,MAAa,sBACX;;;;;;AAOF,SAAgB,cAAc,SAAS,OAAe;CACpD,OAAO,YAAY,oBAAoB,oBAAoB;AAC7D;;;;;;;AAQA,SAAgB,kBAAkB,OAAkC;CAClE,OAAO,8CAA8C,MAAM;AAC7D;;;;;;;;;;;;;;;;;;;;;;AAgCA,SAAgB,cAAc,OAA2C;CAKvE,MAAM,SAAS,OAAO,UAAU,WAAW,CAAC,KAAK,IAAI,MAAA,CAAO,KAAI,SAAQ,IAAI,MAAM,CAAC,CAAC,KAAK,IAAI;CAgP7F,OAAO;;;4BA5OmB,MAAM;;;;EAIhC,MAAM;;;;;;;;;;;;qBAYa,cAAc,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA4BjC,kBAAkB,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgMjB,QAAQ,wCAAwC,QAAQ,cACnE,IAAI,UAAU,MAAM,WAAW;AACnC;;;AC1aA,MAAa,iBAAiB;;;AAI9B,MAAa,cAAc,GAAG,cAAc,cAAc,EAAE;GACzD,eAAe;;;;;;;;;;;;;;GAcf,eAAe;;;;;;GAMf,eAAe;;;;AChBlB,MAAM,UAAU;CACd,IAAI;EACF,UAAU;EACV,SAAS;EACT,SAAS;EACT,OAAO;EACP,SAAS;EACT,SAAS;EACT,aAAa;CACf;CACA,IAAI;EACF,UAAU;EACV,SAAS;EACT,SAAS;EACT,OAAO;EACP,SAAS;EACT,SAAS;EACT,aAAa;CACf;AACF;AAIA,MAAM,OAAO;CACX,IAAI;EACF,eAAe;EACf,cAAc;EACd,WAAW;EACX,YAAY;EACZ,UAAU;EACV,YAAY;EACZ,gBAAgB;EAChB,QAAQ;EACR,OAAO;EACP,OAAO;EACP,MAAM;EACN,MAAM;EACN,WAAW;EACX,OAAO;CACT;CACA,IAAI;EACF,eAAe;EACf,cAAc;EACd,WAAW;EACX,YAAY;EACZ,UAAU;EACV,YAAY;EACZ,gBAAgB;EAChB,QAAQ;EACR,OAAO;EACP,OAAO;EACP,MAAM;EACN,MAAM;EACN,WAAW;EACX,OAAO;CACT;AACF;AAIA,SAAgB,OAAO,QAAoB,KAAwB;CACjE,OAAO,KAAK,OAAO,CAAC;AACtB;AAEA,SAAgB,cAAc,SAA0C;CACtE,IAAI,QAAQ,SAAS,mCAAmC,QAAQ,SAAS,4BAA4B,OAAO;CAC5G,IACE,QAAQ,SAAS,4BACd,QAAQ,SAAS,0BACjB,QAAQ,SAAS,yBACjB,QAAQ,SAAS,0BACpB,OAAO;CACT,IAAI,QAAQ,SAAS,0BAA0B,OAAO;CACtD,IAAI,QAAQ,SAAS,wBAAwB,QAAQ,WAAW,4BAA4B,OAAO;CACnG,IAAI,QAAQ,WAAW,cAAc,QAAQ,WAAW,aAAa,QAAQ,WAAW,aAAa,QAAQ,WAAW,SACtH,OAAO,QAAQ;CAEjB,IAAI,QAAQ,WAAW,iBAAiB,QAAQ,WAAW,aAAa,OAAO;CAC/E,IAAI,QAAQ,WAAW,sBAAsB,QAAQ,WAAW,oBAAoB,OAAO;CAC3F,OAAO;AACT;AAEA,SAAgB,YAAY,QAAoB,SAAmC;CACjF,OAAO,QAAQ,OAAO,CAAC,cAAc,OAAO;AAC9C;AAEA,SAAgB,WAAW,QAAoB,gBAA6C;CAC1F,OAAO,mBAAmB,SAAS,KAAK,OAAO,CAAC,aAAa,KAAK,OAAO,CAAC;AAC5E;;;AC7FA,SAAgB,aAAa,EAAE,QAAgE;CAC7F,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;EAAK,OAAO;EAAM,QAAQ;EAAM,SAAQ;EAAY,eAAY;EAC9D,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;GACE,GAAE;GACF,MAAK;GACL,QAAO;GACP,aAAY;EACb,CAAA;CACE,CAAA;AAET;;;AAIA,SAAgB,mBAAmB,OAAgF;CAEjH,MAAM,UAAA,GADWC,MAAAA,qBAAAA,CAAqB,MAAM,MAAM,WAAW,MAAM,MAAM,aAAa,MAAM,MAAM,WAC5E,CAAC,CAAC;CACxB,IAAI,WAAW,KAAA,GAAW,OAAO;CACjC,MAAM,QAAQ,QAAsC,OAAO,MAAM,QAAQ,GAAG;CAC5E,OACE,iBAAA,GAAA,kBAAA,IAAA,CAACC,sCAAAA,OAAD;EACE,MAAA;EACA,WAAW;EACX,OAAO,KAAK,cAAc;EAC1B,YAAY,KAAK,OAAO;EACxB,eAAe;GAAE,MAAM,MAAM,cAAc;EAAE;EAC7C,QACE,iBAAA,GAAA,kBAAA,IAAA,CAACC,sCAAAA,QAAD;GAAQ,SAAQ;GAAU,wBAAA;GAAqB,eAAe;IAAE,MAAM,MAAM,cAAc;GAAE;GACzF,UAAA,KAAK,OAAO;EACP,CAAA;EAGV,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;GAAG,WAAU;GAA8B,MAAK;GAAS,UAAA,YAAY,MAAM,QAAQ,MAAM;EAAK,CAAA;CACzF,CAAA;AAEX;AAEA,SAAgB,iBAAiB,OAAgF;CAE/G,MAAM,WAAA,GADWF,MAAAA,qBAAAA,CAAqB,MAAM,MAAM,WAAW,MAAM,MAAM,aAAa,MAAM,MAAM,WAC3E,CAAC,CAAC;CACzB,MAAM,cAAA,GAAaG,MAAAA,OAAAA,CAA0B,IAAI;CACjD,CAAA,GAAA,MAAA,UAAA,OAAgB;EACd,IAAI,SAAS,SAAS,WAAW,SAAS,MAAM;CAClD,GAAG,CAAC,SAAS,OAAO,CAAC;CACrB,IAAI,YAAY,KAAA,GAAW,OAAO;CAClC,MAAM,QAAQ,QAAsC,OAAO,MAAM,QAAQ,GAAG;CAC5E,MAAM,QAAQ,QAAQ,OAAO,KAAK,UAAU,IAAI,QAAQ,UAAU,KAAK,WAAW,IAAI,KAAK,YAAY;CACvG,OACE,iBAAA,GAAA,kBAAA,KAAA,CAACF,sCAAAA,OAAD;EACE,MAAA;EACA,WAAW;EACX,OAAO,KAAK,YAAY;EACxB,YAAY,KAAK,OAAO;EACxB,aAAa,WAAW,MAAM,QAAQ,QAAQ,cAAc;EAC5D,eAAe;GAAE,MAAM,MAAM,aAAa;EAAE;EAC5C,QACE,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAACC,sCAAAA,QAAD;GAAQ,SAAQ;GAAQ,UAAU,QAAQ;GAAM,eAAe;IAAE,MAAM,MAAM,aAAa;GAAE;GAAI,UAAA,KAAK,QAAQ;EAAU,CAAA,GACvH,iBAAA,GAAA,kBAAA,IAAA,CAACA,sCAAAA,QAAD;GACE,KAAK;GACL,SAAQ;GACR,wBAAA;GACA,UAAU,QAAQ;GAClB,eAAe;IAAE,MAAW,MAAM,cAAc;GAAE;GAEjD,UAAA;EACK,CAAA,CACR,EAAA,CAAA;EAnBN,UAAA,CAsBE,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD,EAAA,UAAI,QAAQ,MAAS,CAAA,GACpB,QAAQ,UAAU,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;GAAG,WAAU;GAA8B,MAAK;GAAS,UAAA,YAAY,MAAM,QAAQ,QAAQ,OAAO;EAAK,CAAA,IAAI,IACzH;;AAEX;;;ACvEA,MAAM,cAAc;AACpB,MAAM,iBAAiB;;;;;;AAiBvB,SAAgB,gCAAgC,OAAuB,OACrE,iBAAqE,QAEtD;CACf,IAAI,OAAO,MAAM,kBAAkB,cAAc,OAAO,MAAM,SAAS,cAAc,OAAO,MAAM,cAAc,YAAY;EAC1H,MAAM,cAAc,WAAW,QAAQ,YAAY,CAAC,CAAC,MAAM,MAAM,OAC7D,0BAA0B,4EAA4E;EAC1G,aAAa,CAAC;CAChB;CACA,OAAO,MAAM,OAAO,mBAAmB;EACrC,IAAI,QAAiC,mBAAmB,CAAC,GAAG,WAAW;EACvE,MAAM,uBAAuB,WAAW,QAAQ,YAAY,CAAC,CAAC,MAAM,MAAM,OACtE,0BAA0B;EAC9B,MAAM,gBAAgB,UAAuB,iBAAA,GAAA,kBAAA,IAAA,CAAC,0BAAD;GAA0B,GAAI;GAAc;GAAwB;GAAyB;GACxI,wBAAwB;GAAQ,gBAAe,aAAY,MAAM,UAAU,gBAAgB,QAAQ;EAAI,CAAA;EACzG,MAAM,aAAa,MAAM,SAAS;GAAE,MAAM;GAAa,UAAU;GAAK,QAAQ;GAC5E,UAAU,GAAG,2BAA2B;IAAE,MAAM;IAAU,OAAO;GAAO,EAAE;EAC5E,GAAG,YAAY;EACf,MAAM,aAAa,MAAM,gBAAgB,KAAK,UAAU;GACtD,IAAI,YAAa,QAAA,6CAAoC,EAAE,QAAQ,eAAe,MAAM,cAAc,eAAgB;GAClH,WAAW;GAAM,WAAW;GAAG,SAAS,KAAA;GAAW,WAAW;GAC9D,MAAM,cAAc,eAAe,CAAC;EACtC,CAAC,YAAY,CAAC;EACd,MAAM,aAAa;GACjB,IAAI,UAAU;GACd,MAAM,OAAO,MAAM,cAAc,cAAc,CAAC,CAAC;GACjD,IAAI,SAAS,QAAQ;GACrB,WAAW;GAAG,mBAAmB,CAAC;GAAG,SAAS,KAAA;GAC9C,IAAI,SAAS,KAAA,GAAW;GACxB,MAAM,OAAO,MAAM,KAAK,cAAc;GACtC,IAAI,MAAM,SAAS,YAAY,KAAK,UAAU,UAAU,OAAO,KAAK,cAAc,cAC7E,KAAK,aAAa,KAAA,KAAa,KAAK,UAAU,KAAA,KAAa,KAAK,WAAW,KAAA,KAAa,KAAK,WAAW,KAAA,GAAW;IACtH,WAAW;IAAM,WAAW;IAC5B,MAAM,cAAc,eAAe,CAAC;IACpC;GACF;GACA,IAAI;IACF,aAAa,MAAM,SAAS;KAAE,MAAM;KAA0B,GAAG,KAAK,SAAS,EAAE,QAAQ,KAAK,OAAO,IAAI,CAAC;IAAE,GAAG,KAAK,SAAS;IAC7H,SAAS;GACX,SAAS,OAAO;IACd,WAAW;IAAM,WAAW;IAC5B,MAAM,cAAc,iBAAiB,QAAQ,MAAM,UAAU,uCAAuC;GACtG;EACF;EACA,MAAM,aAAa,MAAM,UAAU,gBAAgB,IAAI;EACvD,KAAK;EACL,aAAa;GAAE,WAAW;GAAM,WAAW;GAAG,WAAW;GAAG,WAAW;GAAG,WAAW;EAAE;CACzF,CAAC;AACH;AAaA,SAAS,yBAAyB,OAI/B;CACD,MAAM,aAAa,MAAM,eAAc,aAAY,QAAQ;CAC3D,MAAM,SAAA,GAAQE,MAAAA,qBAAAA,CAAqB,MAAM,MAAM,WAAW,MAAM,MAAM,aAAa,MAAM,MAAM,WAAW;CAC1G,MAAM,UAAA,GAASA,MAAAA,qBAAAA,CAAqB,MAAM,eAAe,MAAM,kBAAkB,MAAM,gBAAgB;CACvG,MAAM,YAAY,WAAW,KAAA;CAC7B,MAAM,SAAS,YAAA,GAAWA,MAAAA,qBAAAA,EAAqB,aAAY,MAAM,QAAQ,UAAU,QAAQ,YAAY,CAAC,UAChG,MAAM,QAAQ,YAAY,CAAC,CAAC,UAAU,YAAY,IAAI,CAAC;CAC/D,MAAM,CAAC,UAAU,gBAAA,GAAeC,MAAAA,SAAAA,CAAS,KAAK,GAAG,CAAC,UAAU,gBAAA,GAAeA,MAAAA,SAAAA,CAAS,KAAK;CACzF,MAAM,CAAC,SAAS,eAAA,GAAcA,MAAAA,SAAAA,CAAiB;CAC/C,MAAM,SAAA,GAAQC,MAAAA,OAAAA,CAAO,CAAC;CACtB,CAAA,GAAA,MAAA,UAAA,aAAsB;EAAE,MAAM;CAAU,GAAG,CAAC,CAAC;CAC7C,CAAA,GAAA,MAAA,UAAA,OAAgB;EAAE,MAAM;EAAW,YAAY,KAAK;EAAG,YAAY,KAAK;CAAE,GAAG,CAAC,MAAM,CAAC;CACrF,MAAM,OAAO,YAAY,YAAY,MAAM;CAC3C,MAAM,iBAAA,GAAgBC,MAAAA,YAAAA,OAAkB,MAAM,WAAW,SAAS,sBAAsB,KAAK,MAAM,CAAC,MAAM,SAAS,CAAC;CACpH,MAAM,sBAAsB;EAAE,MAAM,QAAQ;EAAG,WAAW,KAAA,CAAS;EAAG,YAAY,IAAI;CAAE;CACxF,OAAO,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA;EACL,iBAAA,GAAA,kBAAA,IAAA,CAACC,sCAAAA,MAAD;GAAM,MAAM,MAAM;GAAM,QAAQ;GAAM,QAAA;GAAsB;GAAe,YAAY,MAAM;GAC3F,SAAS,MAAM;GAAS,OAAO,WAAW,MAAM,KAAI,eAAc;IAAE,IAAI,UAAU;IAEhF,OAAO,UAAU,UAAU,sBAAsB,MAAM,EAAE,uBAAuB,IAAI,UAAU;IAC9F,MAAM,iBAAA,GAAA,kBAAA,IAAA,CAACC,sCAAAA,wBAAD,EAAwB,MAAM,GAAK,CAAA;IAAG,UAAU;GAAK,EAAE;GAC/D,QAAQ,CACN,GAAG,YAAY,CAAC;IAAE,IAAI;IAAmB,OAAO,MAAM,EAAE,mBAAmB;IAAG,MAAM,iBAAA,GAAA,kBAAA,IAAA,CAACC,sCAAAA,wBAAD,EAAwB,MAAM,GAAK,CAAA;IAAG,UAAU;GAAK,CAAC,IAAI,CAAC,GAC/I;IAAE,IAAI;IAAyB,OAAO,OAAO,QAAQ,eAAe;IAAG,MAAM,iBAAA,GAAA,kBAAA,IAAA,CAAC,cAAD,EAAc,MAAM,GAAK,CAAA;IAAG,UAAU;GAAK,CAC1H;GACA,WAAU,OAAM;IACd,IAAI,OAAO,mBAAmB,cAAc;SACvC,IAAI,OAAO,yBAAyB;KAAE,MAAM,QAAQ;KAAG,MAAW,MAAM,OAAO;IAAE,OACjF,MAAM,OAAO,EAAW;GAC/B;EAAI,CAAA;EACL,MAAM,QAAQ,WAAW,UAAU,aAAa,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;GAAM,MAAK;GAAU,UAAA,MAAM,EAAE,gBAAgB;EAAQ,CAAA;EACrG,MAAM,WAAW,0BAA0B;GAC1C,MAAM;GAAU,MAAM;GACtB,gBAAgB;IAAE,MAAM;IAAW,YAAY,KAAK;IAAG,YAAY,KAAK;GAAE;GAC1E,UAAS,YAAW;IAAE,MAAM;IAAW,YAAY,KAAK;IAAG,YAAY,KAAK;IAAG,WAAW,OAAO;GAAE;GACnG,WAAU,SAAQ;IAChB,IAAI,UAAU;IACd,MAAM,SAAS,EAAE,MAAM;IACvB,YAAY,IAAI;IAChB,MAAW,gBAAgB,IAAI,CAAC,CAAC,MAAK,cAAa;KACjD,IAAI,WAAW,MAAM,SAAS;KAC9B,YAAY,KAAK;KAAG,MAAM,OAAO,UAAU,WAAoB;IACjE,IAAG,UAAS;KACV,IAAI,WAAW,MAAM,SAAS;KAC9B,YAAY,KAAK;KAAG,WAAW,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;IACvF,CAAC,CAAC,CAAC,cAAc;KAAE,IAAI,WAAW,MAAM,SAAS,YAAY,KAAK;IAAE,CAAC;GACvE;EACF,CAAC;EACD,iBAAA,GAAA,kBAAA,IAAA,CAACC,sCAAAA,OAAD;GAAO,MAAM,YAAY,KAAA;GAAW,OAAO,MAAM,EAAE,mBAAmB;GAAG,YAAY,MAAM,EAAE,OAAO;GAClG,eAAe,WAAW,KAAA,CAAS;GAAG,QAAQ,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA,CAC5C,iBAAA,GAAA,kBAAA,IAAA,CAACC,sCAAAA,QAAD;IAAQ,SAAQ;IAAU,eAAe,WAAW,KAAA,CAAS;IAAI,UAAA,MAAM,EAAE,QAAQ;GAAU,CAAA,GAC3F,iBAAA,GAAA,kBAAA,IAAA,CAACA,sCAAAA,QAAD;IAAQ,SAAQ;IAAU,UAAU,CAAC;IAAW,SAAS;IAAgB,UAAA,MAAM,EAAE,mBAAmB;GAAU,CAAA,CAC9G,EAAA,CAAA;GAAG,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;IAAG,MAAK;IAAS,UAAA;GAAW,CAAA;EAAQ,CAAA;CAC3C,EAAA,CAAA;AACJ;AAEA,SAAgB,yBAAyB,EAAE,OAAO,UAAkE;CAClH,MAAM,SAAA,GAAQR,MAAAA,qBAAAA,CAAqB,MAAM,WAAW,MAAM,aAAa,MAAM,WAAW;CACxF,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAACO,sCAAAA,OAAD;EAAO,MAAM,MAAM,YAAY,KAAA;EAAW,OAAO,OAAO,QAAQ,cAAc;EACnF,YAAY,OAAO,QAAQ,OAAO;EAAG,SAAS,MAAM;EAAgB,QAAQ,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA,CAC1E,iBAAA,GAAA,kBAAA,IAAA,CAACC,sCAAAA,QAAD;GAAQ,SAAQ;GAAU,SAAS,MAAM;GAAiB,UAAA,OAAO,QAAQ,OAAO;EAAU,CAAA,GAC1F,iBAAA,GAAA,kBAAA,IAAA,CAACA,sCAAAA,QAAD;GAAQ,SAAQ;GAAU,UAAU,MAAM;GAAU,eAAe;IAAE,MAAW,OAAO;GAAE;GAAI,UAAA,OAAO,QAAQ,OAAO;EAAU,CAAA,CAC7H,EAAA,CAAA;EAAG,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;GAAG,MAAK;GAAS,UAAA,MAAM;EAAW,CAAA;CAAQ,CAAA;AACnD;;;AC7IA,SAAgB,8BAA8B,MAA8B,YAAY,OAAO,WAAW,GAAG,cAAc,uBAAuB;CAChJ,MAAM,WAAW,IAAI,gBAAgB,GAAG,4BAAY,IAAI,IAAgB;CACxE,IAAI,WAAuC,EAAE,UAAU,MAAM;CAC7D,IAAI;CACJ,MAAM,WAAW,SAAqC;EACpD,IAAI,SAAS,OAAO,SAAS;EAC7B,WAAW;EACX,KAAK,MAAM,YAAY,WAAW,SAAS;CAC7C;CACA,OAAO;EACL,mBAAmB;EACnB,UAAU,UAAsB;GAAE,UAAU,IAAI,QAAQ;GAAG,aAAa;IAAE,UAAU,OAAO,QAAQ;GAAE;EAAE;EACvG,iBAAiB;GAAE,QAAQ,EAAE,UAAU,SAAS,SAAS,CAAC;EAAE;EAC5D,cAAc,SAAiB;GAAE,QAAQ;IAAE,GAAG;IAAU;GAAQ,CAAC;EAAE;EACnE,MAAM,SAAS;GACb,IAAI,SAAS,YAAY,SAAS,OAAO,SAAS;GAElD,MAAM,SAAS,YAAY,IAAI,CAAC,KAAK,gBAAgB,GAAG,SAAS,MAAM,CAAC;GACxE,MAAM,SAAS,YAAY;IAAE,WAAW,IAAI;IAAG,OAAO,MAAM;GAAE;GAC9D,IAAI,UAAU;GACd,QAAQ,EAAE,UAAU,KAAK,CAAC;GAC1B,IAAI;IACF,OAAO,eAAe;IACtB,IAAI,OAAO,SAAS,KAAA,GAAW;KAC7B,MAAM,YAAY,MAAM,KAAK,SAAS,OAAO,WAAW,MAAM;KAC9D,IAAI,UAAU,cAAc,OAAO,aAAa,CAAC,UAAU,MAAM,MAAM,IAAI,MAAM,sCAAsC;KACvH,OAAO,OAAO,UAAU;IAC1B;IACA,OAAO,eAAe;IACtB,IAAI,OAAO,gBAAgB,KAAA,GAAW,OAAO,eAAe,MAAM,KAAK,gBAAgB,OAAO,IAAI,EAAA,CAAG;IACrG,OAAO,eAAe;IACtB,IAAI,CAAC,OAAO,OAAO;KACjB,MAAM,KAAK,gBAAgB,OAAO,aAAa,GAAG,OAAO,MAAM,GAAG,OAAO,UAAU,MAAM,GAAG,CAAC,GAAG;KAChG,OAAO,QAAQ;IACjB;IACA,OAAO,eAAe;IACtB,UAAU;IACV,MAAM,KAAK,cAAc,OAAO,mBAAmB,SAAS,OAAO,eAAe,CAAC;IAEnF,IAAI,CAAC,SAAS,OAAO,SAAS,UAAU,KAAA;GAC1C,SAAS,OAAO;IACd,IAAI,CAAC,SAAS,OAAO,YAAY,UAAU,EAAE,iBAAiB,SAAS,MAAM,SAAS,gBAAgB,CAAC,OAAO,UAC5G,QAAQ;KAAE,UAAU;KAAO,SAAS,iBAAiB,QAAQ,MAAM,UAAU;IAA2C,CAAC;GAE7H,UAAU;IACR,QAAQ;KAAE,GAAG;KAAU,UAAU;IAAM,CAAC;GAC1C;EACF;EACA,SAAS;GAAE,SAAS,MAAM;GAAG,UAAU,MAAM;EAAE;CACjD;AACF;AAIA,SAAgB,2BAA2B,KAKhB;CACzB,OAAO;EACL,uBAAuB,IAAI,OAAO,gBAAgB;EAClD,MAAM,SAAS,WAAW,QAAQ;GAEhC,MAAM,WAAW,MADC,IAAI,WAAW,IAAI,KAAK,wBAAwB,sBAAsB,EAAE,UAAU,GAAG,MAAM;GAE7G,IAAI,UAAU,OAAO,QAAQ,OAAO,SAAS,OAAO,SAAS,YAAY,OAAO,SAAS,MAAM,cAAc,UAC3G,MAAM,IAAI,MAAM,UAAU,OAAO,WAAW,4CAA4C;GAE1F,OAAO,SAAS;EAClB;EACA,kBAAiB,SAAQ,IAAI,WAAW,OAAO,EAAE,KAAK,CAAC;EACvD,kBAAkB,aAAa,UAAU,IAAI,WAAW,OAAO,aAAa,KAAK;EACjF,gBAAgB,aAAa,eAAe,IAAI,YAAY,cAAc,aAAa,UAAU;CACnG;AACF;;;AC1EA,MAAa,2BAAgD;CAC3D,OAAO;CACP,aAAa;CACb,eAAe;AACjB;AA0DA,SAAgB,cAAc,SAAoC;CAChE,OAAO,QAAQ,SAAS,eAAe,QAAQ,SAAS;AAC1D;AAEA,SAAgB,YAAY,OAAkC;CAC5D,IAAI,UAAU,KAAK,GAAG,OAAO;EAAE,MAAM,MAAM;EAAM,GAAG,MAAM,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ,MAAM,OAAO;CAAE;CAC/G,IAAI,OAAO,UAAU,YAAY,UAAU,MAAM;EAC/C,MAAM,SAAS;EACf,MAAM,MAAM,OAAO;EACnB,IAAI,OAAO,KAAK,SAAS,UACvB,OAAO;GAAE,MAAM,IAAI;GAAM,GAAG,SAAS,GAAG,MAAM,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ,SAAS,GAAG,EAAE;EAAE;EAE3F,IAAI,OAAO,OAAO,SAAS,UAAU;GACnC,MAAM,SAAS,OAAO,OAAO,WAAW,WAAW,OAAO,SAAS,KAAA;GACnE,OAAO;IAAE,MAAM,OAAO;IAAM,GAAG,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO;GAAE;EACxE;CACF;CACA,OAAO;EAAE,MAAM;EAAa,QAAQ;CAAU;AAChD;AAEA,SAAS,UAAU,OAA2C;CAC5D,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,UAAU,SAAS,OAAQ,MAA4B,SAAS,YAChH,MAA4B,SAAS;AAC7C;AAEA,IAAa,qBAAb,cAAwC,MAAkC;CAGnD;CAFrB,OAAyB;CACzB;CACA,YAAY,MAAuB,QAAiB;EAClD,MAAM,IAAI;EADS,KAAA,OAAA;EAEnB,IAAI,WAAW,KAAA,GAAW,KAAK,SAAS;CAC1C;AACF;AAEA,SAAS,SAAS,OAAsD;CACtE,OAAO,OAAO,OAAO,SAAS,WAAW,WAAW,MAAM,QAAQ,SAAS,KAAA;AAC7E;AAEA,SAAS,eAAe,OAAuC;CAC7D,IAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,EAAE,QAAQ,QAAQ,OAAO;CAE5E,OAAO,OADK,MAA0B,OACjB,cAAc,WAAW,SAAS,WAAW;AACpE;AAEA,eAAsB,OAAO,OAAkC;CAC7D,MAAM,WAAW,MAAM;CACvB,IAAI,CAAC,eAAe,QAAQ,GAAG,OAAO;CACtC,IAAI,CAAC,SAAS,IACZ,MAAM,IAAI,mBAAmB,SAAS,OAAO,QAAQ,aAAa,SAAS,SAAS,KAAK,CAAC;CAE5F,OAAO,SAAS;AAClB;AAEA,eAAsB,iBAAiB,MAAiD;CACtF,IAAI,OAAO,KAAK,iBAAiB,YAAY,OAAO;CACpD,IAAI;EACF,MAAM,QAAQ,MAAM,OAAO,KAAK,aAAa,CAAC;EAC9C,IAAI,OAAO,UAAU,YAAY,UAAU,MAAM,OAAO;EACxD,MAAM,SAAS;EACf,OAAO;GACL,OAAO,OAAO,UAAU;GACxB,aAAa,OAAO,gBAAgB;GACpC,eAAe,OAAO,kBAAkB;EAC1C;CACF,QAAQ;EACN,OAAO;CACT;AACF;AAEA,SAAgB,YAAY,cAAmC,OAAgB,MAI7E;CACA,OAAO;EACL,QAAQ,SAAS,aAAa,eAAe,OAAO,KAAK,WAAW;EACpE,QAAQ,SAAS,aAAa,iBAAiB,OAAO,KAAK,kBAAkB;EAC7E,OAAO,SAAS,aAAa,SAAS,OAAO,KAAK,iBAAiB,cAAc,OAAO,KAAK,UAAU;CACzG;AACF;AAEA,SAAS,YAAY,OAAwB;CAC3C,IAAI,OAAO,UAAU,YAAY,UAAU,IAAI,OAAO;CACtD,IAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,OAAQ,MAAkC,cAAc,UACzG,OAAQ,MAAgC;CAE1C,MAAM,IAAI,mBAAmB,+BAA+B;AAC9D;;AAGA,eAAsB,kBAAkB,MAAoC;CAC1E,IAAI,OAAO,KAAK,WAAW,YAAY,MAAM,IAAI,mBAAmB,+BAA+B;CACnG,OAAO,YAAY,MAAM,OAAO,KAAK,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC;AAChE;AAEA,eAAsB,mBAAmB,MAAmB,WAAmB,WAA2C;CACxH,IAAI,OAAO,KAAK,kBAAkB,YAAY,MAAM,IAAI,mBAAmB,+BAA+B;CAC1G,MAAM,QAAQ,MAAM,OAAO,KAAK,cAAc,WAAW,SAAS,CAAC;CACnE,IAAI,OAAO,UAAU,YAAY,UAAU,MAAM,MAAM,IAAI,mBAAmB,0BAA0B,iBAAiB;CACzH,MAAM,QAAS,MAA8B;CAC7C,IAAI,UAAU,aAAa,UAAU,mBACnC,MAAM,IAAI,mBAAmB,0BAA0B,iBAAiB;CAE1E,OAAO,EAAE,MAAM;AACjB;AAEA,SAAgB,mBAAmB,OAMZ;CACrB,OAAO;EACL,WAAW,MAAM;EACjB,WAAW,MAAM;EACjB,kBAAkB,MAAM;EACxB,uBAAuB,MAAM;EAC7B,WAAW,MAAM;CACnB;AACF;AAEA,SAAgB,iBAAiB,OAAgE;CAC/F,OAAO;EAAE,GAAG,mBAAmB,KAAK;EAAG,MAAM,MAAM;CAAK;AAC1D;AAEA,IAAa,mBAAb,MAA8B;CAC5B,SAAiB;CACjB;CAEA,IAAI,OAAgB;EAClB,OAAO,KAAK;CACd;CAEA,UAA6D;EAC3D,OAAO,KAAK;CACd;;CAGA,MAAM,OAAO,SAA2F;EACtG,MAAM,OAAO,KAAK;EAClB,IAAI,SAAS,KAAA,GAAW;EACxB,IAAI,KAAK,QAAQ,MAAM,IAAI,mBAAmB,QAAQ,SAAS;EAC/D,KAAK,SAAS;EACd,IAAI;GACF,MAAM,QAAQ,IAAI;GAClB,KAAK,aAAa,KAAA;EACpB,SAAS,OAAO;GACd,MAAM,UAAU,YAAY,KAAK;GACjC,IAAI,CAAC,cAAc,OAAO,KAAK,QAAQ,WAAW,WAAW,KAAK,aAAa,KAAA;GAC/E,MAAM,iBAAiB,qBAAqB,QAAQ,IAAI,mBAAmB,QAAQ,MAAM,QAAQ,MAAM;EACzG,UAAU;GACR,KAAK,SAAS;EAChB;CACF;;CAGA,MAAM,OAAO,MAA6C,SAAgD;EACxG,IAAI,KAAK,UAAU,KAAK,eAAe,KAAA,GAAW,MAAM,IAAI,mBAAmB,QAAQ,SAAS;EAChG,KAAK,SAAS;EACd,IAAI;GACF,MAAM,QAAQ;GACd,KAAK,aAAa,KAAA;EACpB,SAAS,OAAO;GACd,MAAM,UAAU,YAAY,KAAK;GACjC,KAAK,aAAa,cAAc,OAAO,IAAI,OAAO,KAAA;GAClD,MAAM,iBAAiB,qBAAqB,QAAQ,IAAI,mBAAmB,QAAQ,MAAM,QAAQ,MAAM;EACzG,UAAU;GACR,KAAK,SAAS;EAChB;CACF;AACF;AAMA,SAAS,QAAQ;CACf,MAAM,4BAAY,IAAI,IAAc;CACpC,OAAO;EACL,UAAU,UAAgC;GACxC,UAAU,IAAI,QAAQ;GACtB,aAAa;IAAE,UAAU,OAAO,QAAQ;GAAE;EAC5C;EACA,OAAa;GACX,KAAK,MAAM,YAAY,WAAW,SAAS;EAC7C;CACF;AACF;AA+BA,SAAgB,oBAAoB,MAAmB,YAA0B,OAAO,WAAW,GAAkB;CACnH,MAAM,SAAS,MAAM;CACrB,IAAI,eAAe;CACnB,IAAI,oBAAoB;CACxB,IAAI,WAAW;CACf,IAAI;CACJ,IAAI;CACJ,IAAI,aAAa;CACjB,IAAI,WAA6B,MAAM;CAEvC,SAAS,QAA0B;EACjC,OAAO;GACL,UAAU,YAAY,cAAc,mBAAmB,IAAI;GAC3D;GACA;GACA,GAAG,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO;GACxC,GAAG,kBAAkB,KAAA,IAAY,CAAC,IAAI,EAAE,cAAc;EACxD;CACF;CAEA,SAAS,UAAgB;EACvB,WAAW,MAAM;EACjB,OAAO,KAAK;CACd;CAEA,OAAO;EACL,WAAW,OAAO;EAClB,mBAAmB;EACnB,MAAM,qBAAqB;GACzB,eAAe,MAAM,iBAAiB,IAAI;GAC1C,oBAAoB;GACpB,QAAQ;EACV;EACA,MAAM,SAAS;GACb,IAAI,CAAC,YAAY,cAAc,mBAAmB,IAAI,CAAC,CAAC,UAAU,UAAU;GAC5E,MAAM,SAAS;GACf,WAAW;GACX,SAAS,KAAA;GACT,QAAQ;GACR,IAAI;IACF,MAAM,KAAK,MAAM,kBAAkB,IAAI;IACvC,IAAI,WAAW,YAAY;IAC3B,IAAI,OAAO,KAAK,gBAAgB,YAAY,MAAM,IAAI,mBAAmB,iCAAiC,cAAc;IACxH,KAAK,YAAY,EAAE;GACrB,SAAS,OAAO;IACd,IAAI,WAAW,YAAY;IAC3B,SAAS,YAAY,KAAK;GAC5B,UAAU;IACR,IAAI,WAAW,YAAY;KACzB,WAAW;KACX,QAAQ;IACV;GACF;EACF;EACA,gBAAgB;GACd,IAAI,WAAW,KAAA,GAAW;GAC1B,SAAS,KAAA;GACT,QAAQ;EACV;EACA,cAAc,WAAW;GACvB,IAAI,CAAC,YAAY,cAAc,mBAAmB,IAAI,CAAC,CAAC,QAAQ;GAChE,MAAM,MAAM,KAAK,KAAK,YAAY,CAAC,CAAC,KAAK;GACzC,gBAAgB;IACd;IACA,OAAO,KAAK,gBAAgB,KAAK,SAAS;IAC1C,gBAAgB,KAAK,mBAAmB,SAAS,SAAS;IAC1D,WAAW,IAAI;IACf,MAAM;GACR;GACA,QAAQ;EACV;EACA,eAAe;GACb,IAAI,eAAe,MAAM;GACzB,gBAAgB,KAAA;GAChB,QAAQ;EACV;EACA,MAAM,gBAAgB;GACpB,MAAM,UAAU;GAChB,IAAI,YAAY,KAAA,KAAa,QAAQ,MAAM;GAC3C,MAAM,SAAS;GACf,gBAAgB;IAAE,GAAG;IAAS,MAAM;IAAM,SAAS,KAAA;GAAU;GAC7D,QAAQ;GACR,IAAI;IACF,MAAM,UAAU,MAAM,mBAAmB,MAAM,QAAQ,WAAW,QAAQ,SAAS;IACnF,IAAI,WAAW,YAAY;IAC3B,IAAI,QAAQ,UAAU,WAAW;KAC/B,gBAAgB;MACd,GAAG;MACH,MAAM;MACN,SAAS;OAAE,MAAM;OAA0B,QAAQ;MAAU;KAC/D;KACA,QAAQ;KACR;IACF;IAEA,gBAAgB,KAAA;GAClB,SAAS,OAAO;IACd,IAAI,WAAW,YAAY;IAC3B,MAAM,UAAU,YAAY,KAAK;IACjC,gBAAgB;KAAE,GAAG;KAAS,MAAM;KAAO;IAAQ;GACrD;GACA,IAAI,WAAW,YAAY,QAAQ;EACrC;EACA,SAAS;GACP,cAAc;GACd,WAAW;GACX,SAAS,KAAA;GACT,gBAAgB,KAAA;GAChB,QAAQ;EACV;CACF;AACF;AAyBA,SAAgB,iBAAiB,MAAmB,YAA0B,OAAO,WAAW,GAAe;CAC7G,MAAM,SAAS,MAAM;CACrB,MAAM,SAAS,IAAI,iBAAiB;CACpC,IAAI,eAAe;CACnB,IAAI,QAAQ;CACZ,IAAI,OAAO;CACX,IAAI,UAAU;CACd,IAAI,QAAQ;CACZ,IAAI;CACJ,IAAI,mBAAmB;CACvB,IAAI,wBAAwB;CAC5B,IAAI,eAAe;CACnB,IAAI,eAAe;CACnB,IAAI,OAAO;CACX,IAAI,WAA0B,MAAM;CAEpC,SAAS,QAAuB;EAC9B,OAAO;GACL,eAAe,YAAY,cAAc,OAAO,IAAI,CAAC,CAAC;GACtD;GACA;GACA;GACA,WAAW;GACX,WAAW;GACX,GAAG,YAAY,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ;EAC5C;CACF;CAEA,SAAS,UAAgB;EACvB,WAAW,MAAM;EACjB,OAAO,KAAK;CACd;CAEA,SAAS,YAAY,OAA8B;EACjD,IAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,OAAQ,MAAuC,mBAAmB,UACnH,MAAM,IAAI,mBAAmB,+BAA+B;EAE9D,MAAM,SAAS;EACf,MAAM,gBAAgB,OAAO,OAAO,kBAAkB,WAAW,OAAO,gBAAgB;EACxF,MAAM,WAAW,OAAO,aAAa;EACrC,IAAI,YAAY,kBAAkB,IAAI,MAAM,IAAI,mBAAmB,iCAAiC,gBAAgB;EACpH,OAAO;GACL,gBAAgB,OAAO;GACvB;GACA;GACA,GAAG,OAAO,OAAO,WAAW,WAAW,EAAE,QAAQ,OAAO,OAAO,IAAI,CAAC;EACtE;CACF;CAEA,eAAe,QAAQ,WAAmB,IAAY,QAAqB,QAAmD;EAC5H,IAAI,WAAW,QAAQ,OAAO,SAAS,OAAO,KAAA;EAC9C,IAAI,OAAO,KAAK,iBAAiB,YAAY,MAAM,IAAI,mBAAmB,+BAA+B;EACzG,MAAM,QAAQ,MAAM,OAAO,KAAK,aAAa;GAAE;GAAW,WAAW;EAAG,CAAC,CAAC;EAC1E,IAAI,WAAW,QAAQ,OAAO,SAAS,OAAO,KAAA;EAC9C,OAAO,YAAY,KAAK;CAC1B;CAEA,eAAe,UAAU,MAA6C,QAAqB,QAA+B;EACxH,IAAI,OAAO,WAAW,WAAW,MAAM,MAAM,IAAI,mBAAmB,QAAQ,SAAS;EACrF,IAAI,OAAO,KAAK,UAAU,YAAY,MAAM,IAAI,mBAAmB,+BAA+B;EAClG,MAAM,OAAO,KAAK,MAAM,IAAI,CAAC;CAC/B;CAEA,SAAS,SAAe;EACtB,IAAI,CAAC,OAAO,MAAM,OAAO;EACzB,QAAQ;CACV;CAEA,eAAe,WAAW,QAAoC;EAC5D,IAAI,OAAO,SAAS;EACpB,MAAM,UAAU,OAAO,QAAQ;EAC/B,MAAM,SAAS,EAAE;EACjB,OAAO;EACP,UAAU,KAAA;EACV,QAAQ;EACR,IAAI;GACF,MAAM,OAAO,OAAO,OAAM,SAAQ;IAAE,MAAM,UAAU,MAAM,QAAQ,MAAM;GAAE,CAAC;GAC3E,IACE,YAAY,KAAA,KACT,WAAW,QACX,CAAC,OAAO,WACR,iBAAiB,QAAQ,aACzB,iBAAiB,QAAQ,WAC5B,UAAU;EACd,SAAS,OAAO;GACd,IAAI,WAAW,QAAQ,CAAC,OAAO,SAAS,UAAU,YAAY,KAAK;EACrE,UAAU;GACR,OAAO;EACT;CACF;CAEA,SAAS,YAAY,WAAmB,IAAqB;EAC3D,MAAM,UAAU,OAAO,QAAQ;EAC/B,OAAO,YAAY,KAAA,KAAa,QAAQ,cAAc,aAAa,QAAQ,cAAc;CAC3F;CAEA,OAAO;EACL,WAAW,OAAO;EAClB,mBAAmB;EACnB,MAAM,OAAO;GACX,eAAe,MAAM,iBAAiB,IAAI;GAC1C,QAAQ;GACR,QAAQ;EACV;EACA,MAAM,MAAM,WAAW,IAAI,QAAQ;GACjC,IAAI,QAAQ,CAAC,YAAY,cAAc,OAAO,IAAI,CAAC,CAAC,SAAS,OAAO,SAAS;GAC7E,IAAI,OAAO,QAAQ,MAAM,KAAA,GAAW;IAClC,IAAI,CAAC,YAAY,WAAW,EAAE,GAAG;IACjC,MAAM,WAAW,MAAM;IACvB;GACF;GACA,MAAM,SAAS,EAAE;GACjB,OAAO;GACP,UAAU,KAAA;GACV,UAAU;GACV,eAAe;GACf,eAAe;GACf,QAAQ;GACR,IAAI;IACF,MAAM,OAAO,MAAM,QAAQ,WAAW,IAAI,QAAQ,MAAM;IACxD,IAAI,SAAS,KAAA,GAAW;IACxB,IAAI,CAAC,KAAK,UAAU;KAClB,UAAU;MAAE,MAAM;MAAyB,QAAQ,KAAK,UAAU;KAAU;KAC5E;IACF;IACA,IAAI,OAAO,WAAW,WAAW,MAAM;IACvC,mBAAmB,KAAK;IACxB,wBAAwB,KAAK;IAC7B,MAAM,OAAO,mBAAmB;KAC9B;KACA,WAAW;KACX,kBAAkB,KAAK;KACvB,uBAAuB,KAAK;KAC5B,WAAW,IAAI;IACjB,CAAC;IACD,MAAM,OAAO,OAAO,YAAY,UAAU,MAAM,QAAQ,MAAM,CAAC;GACjE,SAAS,OAAO;IACd,IAAI,WAAW,QAAQ,CAAC,OAAO,SAAS,UAAU,YAAY,KAAK;GACrE,UAAU;IACR,OAAO;GACT;EACF;EACA,MAAM,UAAU,WAAW,IAAI,MAAM,QAAQ;GAC3C,IAAI,QAAQ,CAAC,YAAY,cAAc,OAAO,IAAI,CAAC,CAAC,SAAS,OAAO,SAAS;GAC7E,IAAI,OAAO,QAAQ,MAAM,KAAA,GAAW;IAClC,IAAI,CAAC,YAAY,WAAW,EAAE,GAAG;IACjC,MAAM,WAAW,MAAM;IACvB;GACF;GACA,MAAM,SAAS,EAAE;GACjB,OAAO;GACP,UAAU,KAAA;GACV,eAAe;GACf,eAAe;GACf,QAAQ;GACR,IAAI;IACF,MAAM,OAAO,MAAM,QAAQ,WAAW,IAAI,QAAQ,MAAM;IACxD,IAAI,SAAS,KAAA,GAAW;IACxB,IAAI,CAAC,KAAK,UAAU;KAClB,UAAU;MAAE,MAAM;MAAyB,QAAQ,KAAK,UAAU;KAAU;KAC5E;IACF;IACA,IAAI,OAAO,WAAW,WAAW,MAAM;IACvC,mBAAmB,KAAK;IACxB,wBAAwB,KAAK;IAC7B,QAAQ;IACR,UAAU;GACZ,SAAS,OAAO;IACd,IAAI,WAAW,QAAQ,CAAC,OAAO,SAAS,UAAU,YAAY,KAAK;GACrE,UAAU;IACR,OAAO;GACT;EACF;EACA,SAAS,MAAM;GACb,IAAI,CAAC,WAAW,iBAAiB,MAAM,iBAAiB,IAAI;GAC5D,QAAQ;GACR,QAAQ;EACV;EACA,aAAa;GACX,IAAI,MAAM;GACV,UAAU;GACV,QAAQ;EACV;EACA,MAAM,SAAS,WAAW,IAAI,QAAQ;GACpC,IAAI,OAAO,WAAW,QAAQ,CAAC,YAAY,cAAc,OAAO,IAAI,CAAC,CAAC,OAAO;GAC7E,IAAI,CAAC,WAAW,iBAAiB,aAAa,iBAAiB,IAAI;GACnE,IAAI,OAAO,QAAQ,MAAM,KAAA,GAAW;IAClC,IAAI,CAAC,YAAY,WAAW,EAAE,GAAG;IACjC,MAAM,WAAW,MAAM;IACvB;GACF;GACA,MAAM,SAAS,EAAE;GACjB,OAAO;GACP,UAAU,KAAA;GACV,MAAM,OAAO;GACb,QAAQ;GACR,IAAI;IACF,IAAI,OAAO,WAAW,WAAW,MAAM;IACvC,MAAM,OAAO,iBAAiB;KAC5B;KACA,WAAW;KACX;KACA;KACA,WAAW,IAAI;KACf;IACF,CAAC;IACD,MAAM,OAAO,OAAO,YAAY,UAAU,MAAM,QAAQ,MAAM,CAAC;IAC/D,IAAI,WAAW,QAAQ,CAAC,OAAO,SAAS,UAAU;GACpD,SAAS,OAAO;IACd,IAAI,WAAW,QAAQ,CAAC,OAAO,SAAS,UAAU,YAAY,KAAK;GACrE,UAAU;IACR,OAAO;GACT;EACF;EACA,OAAO,WAAW,WAAW;GAC3B,IAAI,iBAAiB,aAAa,iBAAiB,WAAW;GAC9D,QAAQ;GACR,UAAU;GACV,UAAU,KAAA;GACV,QAAQ;GACR,IAAI,CAAC,OAAO,MAAM,OAAO;GACzB,QAAQ;EACV;EACA,SAAS;GACP,QAAQ;GACR,UAAU;GACV,UAAU,KAAA;GACV,IAAI,CAAC,OAAO,MAAM,OAAO;GACzB,QAAQ;EACV;CACF;AACF;AAEA,SAAgB,SAAS,KAYT;CACd,MAAM,WAAW,IAAI;CACrB,MAAM,YAAY,IAAI;CAKtB,OAAO;EACL,MAAM,UAAU,QAAQ;GAJxB,oBAAoB;IAAE,KAAK,CAAC;IAAG,MAAM,CAAC;IAAG,OAAO;GAAQ;GACxD,uBAAuB,CAAC;EAGI;EAC5B,GAAG,OAAO,UAAU,iBAAiB,aAAa,EAAE,oBAAoB,SAAS,aAAc,EAAE,IAAI,CAAC;EACtG,GAAG,OAAO,UAAU,WAAW,aAC3B,EAAE,SAAS,SAA4B,SAAS,OAAyD,IAAI,EAAE,IAC/G,CAAC;EACL,GAAG,OAAO,UAAU,iBAAiB,aAAa,EAAE,eAAc,YAAW,SAAS,aAAc,OAAO,EAAE,IAAI,CAAC;EAClH,GAAG,OAAO,UAAU,UAAU,aAAa,EAAE,QAAO,YAAW,SAAS,MAAO,OAAO,EAAE,IAAI,CAAC;EAC7F,GAAG,OAAO,WAAW,gBAAgB,aAAa,EAAE,cAAa,cAAa,UAAU,YAAa,SAAS,EAAE,IAAI,CAAC;EACrH,GAAG,OAAO,WAAW,kBAAkB,aAAa,EAAE,gBAAgB,WAAW,cAAc,UAAU,cAAe,WAAW,SAAS,EAAE,IAAI,CAAC;CACrJ;AACF;;;ACjrBA,SAAgB,mBAAmB,OAML;CAC5B,MAAM,YAAA,GAAWC,MAAAA,qBAAAA,CAAqB,MAAM,MAAM,WAAW,MAAM,MAAM,aAAa,MAAM,MAAM,WAAW;CAC7G,MAAM,UAAA,GAASC,MAAAA,OAAAA,CAAwB,IAAI,gBAAgB,CAAC;CAC5D,CAAA,GAAA,MAAA,UAAA,OAAgB;EACd,MAAM,aAAa,IAAI,gBAAgB;EACvC,OAAO,UAAU;EACjB,aAAa;GACX,WAAW,MAAM;GACjB,MAAM,MAAM,OAAO,MAAM,WAAW,MAAM,SAAS;EACrD;CACF,GAAG;EAAC,MAAM;EAAO,MAAM;EAAW,MAAM;CAAS,CAAC;CAClD,IAAI,MAAM,cAAc,MAAM,CAAC,SAAS,eAAe,OAAO;CAC9D,MAAM,OAAO,SAAS,cAAc,MAAM,aAAa,SAAS,cAAc,MAAM;CACpF,MAAM,QAAQ,QAAsC,OAAO,MAAM,QAAQ,GAAG;CAC5E,MAAM,UAAU,OAAO,SAAS,UAAU,KAAA;CAC1C,MAAM,UAAU,QAAQ,SAAS;CACjC,MAAM,QAAQ,OAAO,SAAS,QAAQ,MAAM;CAC5C,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;EAAM,WAAW,GAAG,eAAe;EAAnC,UAAA;GACE,iBAAA,GAAA,kBAAA,IAAA,CAACC,sCAAAA,SAAD;IAAS,OAAO,KAAK,OAAO;IAAG,MAAK;IAClC,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAACC,sCAAAA,QAAD;KACE,MAAK;KACL,SAAQ;KACR,cAAY,KAAK,OAAO;KACxB,UAAU,SAAS;KACnB,eAAe;MAAE,MAAW,MAAM,MAAM,MAAM,WAAW,MAAM,WAAW,OAAO,QAAQ,MAAM;KAAE;KAEhG,UAAA,KAAK,OAAO;IACP,CAAA;GACD,CAAA;GACT,iBAAA,GAAA,kBAAA,IAAA,CAACD,sCAAAA,SAAD;IAAS,OAAO,KAAK,MAAM;IAAG,MAAK;IACjC,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAACC,sCAAAA,QAAD;KACE,MAAK;KACL,SAAQ;KACR,cAAY,KAAK,MAAM;KACvB,UAAU,SAAS;KACnB,eAAe;MAAE,MAAW,MAAM,UAAU,MAAM,WAAW,MAAM,WAAW,MAAM,MAAM,OAAO,QAAQ,MAAM;KAAE;KAEhH,UAAA,KAAK,MAAM;IACN,CAAA;GACD,CAAA;GACR,UAAU,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;IAAM,WAAU;IAA8B,MAAK;IAAS,UAAA,YAAY,MAAM,QAAQ,OAAO;GAAQ,CAAA,IAAI;GACpH,iBAAA,GAAA,kBAAA,IAAA,CAACC,sCAAAA,OAAD;IACE,MAAM;IACN,WAAW;IACX,OAAO,KAAK,WAAW;IACvB,YAAY,KAAK,OAAO;IACxB,eAAe;KAAE,MAAM,MAAM,WAAW;IAAE;IAC1C,QACE,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAACD,sCAAAA,QAAD;KAAQ,SAAQ;KAAQ,UAAU,SAAS;KAAM,eAAe;MAAE,MAAM,MAAM,WAAW;KAAE;KAAI,UAAA,KAAK,QAAQ;IAAU,CAAA,GACtH,iBAAA,GAAA,kBAAA,IAAA,CAACA,sCAAAA,QAAD;KACE,SAAQ;KACR,wBAAA;KACA,UAAU,SAAS;KACnB,eAAe;MAAE,MAAW,MAAM,SAAS,MAAM,WAAW,MAAM,WAAW,OAAO,QAAQ,MAAM;KAAE;KAEnG,UAAA,KAAK,MAAM;IACN,CAAA,CACR,EAAA,CAAA;IAGJ,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,YAAD;KACE,WAAU;KACV,cAAY,KAAK,OAAO;KACxB,OAAO;KACP,WAAU,UAAS;MAAE,MAAM,MAAM,SAAS,MAAM,OAAO,KAAK;KAAE;IAC/D,CAAA;GACI,CAAA;EACH;;AAEV;;;ACvDA,MAAa,OAAO;AACpB,MAAa,SAAS;CAAC;CAAS;CAAU;CAAY;CAAe;CAAa;CAAc;CAAc;AAAQ;AA2BtH,SAAgB,mBAAmB,OAIhC;CACD,MAAM,CAAC,QAAQ,cAAA,GAAaE,MAAAA,SAAAA,CAAS,KAAK;CAC1C,MAAM,GAAG,eAAe,MAAM,iBAAiB;CAC/C,MAAM,QAAQ,SAAS,mBAAmB,MAAM,UAAU,kBAAkB,MAAM;CAClF,MAAM,iBAAiB,aAAa,MAAM,WAAW,MAAM,aAAa,cAAc,CAAC,CAAC,WAAW;EACjG,UAAU,KAAK;EACf,YAAY,KAAK;CACnB,SAAS;EACP,UAAU,IAAI;CAChB,CAAC;CAID,OACE,iBAAA,GAAA,kBAAA,IAAA,CAACC,sCAAAA,gBAAD;EAAgB,iBAAA;EAAgB,UAAU,MAAM;EAAoB;EACjE,UAAA;CACa,CAAA;AAEpB;AAGA,SAAgB,MAAM,KAAoB;CACxC,MAAM,SAAS;CACf,MAAM,OAAO,SAAS,MAAM;CAC5B,MAAM,QAAQ,oBAAoB,IAAI;CACtC,MAAM,UAAU,iBAAiB,IAAI;CACrC,MAAM,gBAAgB,2BAA2B,MAAqE;CACtH,MAAM,YAAY,8BAA8B,eAAe,KAAA,SACvD,OAAO,WAAW,OAAO,QAAQ,YAAY,CAAC,CAAC,MAAM,GAAG,eAAe,CAAC;CAChF,MAAM,sBAAsB,OAAO,QAAQ,YAAY,CAAC,CAAC;CACzD,OAAO,aAAa;EAClB,MAAM,QAA2B,CAAC;EAElC,IAAI,OAAO,aAAa,aAAa,MAAM,KAAK,6BAA6B,QAAQ,CAAC;EACtF,MAAM,KAAK,OAAO,MAAM,OAAO,8CAC7B,OAAO,MAAM,SAAS;GACpB,MAAM;GACN,IAAI;GACJ,OAAA;EACF,IAAG,UAAS,iBAAA,GAAA,kBAAA,IAAA,CAAC,gBAAD;GAAgB,QAAQ,OAAO;GAAQ,WAAW,OAAO;GAAW,GAAI;EAAqB,CAAA,CAAC,CAC3G,CAAC;EACF,MAAM,KAAK,OAAO,MAAM,OAAO,8CAC7B,OAAO,MAAM,SAAS;GACpB,MAAM;GACN,IAAI;GACJ,OAAA;EACF,IAAG,UAAS,iBAAA,GAAA,kBAAA,IAAA,CAAC,gBAAD;GAAgB,QAAQ,OAAO;GAAQ,OAAO;GAAO,GAAI;EAAqB,CAAA,CAAC,CAC5F,CAAC;EACF,MAAM,KAAK,gCAAgC,OAAO,OAAoC,WACpF,cAAc,iBAAiB,OAAO,MAAM,CAAC;EAC/C,MAAM,KAAK,OAAO,MAAM,OAAO,yBAC7B,OAAO,MAAM,SAAS;GACpB,MAAM;GACN,IAAI;GACJ,OAAO;GACP,SAAS,eAAuB,EAAE,UAAU;EAC9C,IAAG,UACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,oBAAD;GACE,WAAY,MAAgC;GAC5C,MAAO,MAA2B;GAClC,WAAY,MAAiC,aAAa;GAC1D,QAAQ,cAAc,OAAO,MAAM;GACnC,OAAO;EACR,CAAA,CACF,CACF,CAAC;EACF,MAAM,KAAK,OAAO,MAAM,OAAO,uBAC7B,OAAO,MAAM,SAAS;GACpB,MAAM;GACN,IAAI;GACJ,OAAO;EACT,SAAS;GACP,MAAM,SAAS,cAAc,OAAO,MAAM;GAC1C,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA;IACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD,EAAA,UAAQ,YAAmB,CAAA;IAC3B,iBAAA,GAAA,kBAAA,IAAA,CAAC,0BAAD;KAA0B,WAAW,OAAO;KAAW,MAAM,OAAO,UAAU;KAAc;KAAuB;IAAgB,CAAA;IACnI,iBAAA,GAAA,kBAAA,IAAA,CAAC,0BAAD;KAA0B,OAAO;KAAmB;IAAS,CAAA;IAC7D,iBAAA,GAAA,kBAAA,IAAA,CAAC,kBAAD;KAAkB,OAAO;KAAe;IAAS,CAAA;IACjD,iBAAA,GAAA,kBAAA,IAAA,CAAC,oBAAD;KAAoB,OAAO;KAAe;IAAS,CAAA;GACnD,EAAA,CAAA;EAEN,CAAC,CACF,CAAC;EACF,MAAM,QAAQ,OAAO,KAAK,0BAA0B;GAClD,MAAW,mBAAmB;GAC9B,QAAa,KAAK;EACpB,CAAC;EACD,IAAI,OAAO,UAAU,YAAY,MAAM,KAAK,KAAK;EACjD,MAAW,mBAAmB;EAC9B,QAAa,KAAK;EAClB,aAAa;GACX,MAAM,OAAO;GACb,QAAQ,OAAO;GACf,UAAU,OAAO;GACjB,KAAK,MAAM,QAAQ,OAAO,KAAK;EACjC;CACF,CAAC;AACH;AAEA,MAAM,kBAAuE,CAAC;AAE9E,SAAS,eAAe,OAA0E;CAChG,MAAM,SAAS,cAAc,MAAM,MAAM;CACzC,MAAM,aAAA,GAAYC,MAAAA,qBAAAA,EAChB,aAAY,MAAM,WAAW,QAAQ,UAAU,QAAQ,YAAY,CAAC,UAC9D,MAAM,WAAW,QAAQ,YAAY,KAAK,uBAC1C,eACR;CACA,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,oBAAD;EAAoB,WAAW,MAAM;EAAW,kBAAkB,MAAM;EAA0B;EACvG,UAAU,UAAU,MAAK,QAAO,IAAI,OAAO,uBAAuB;CAAI,CAAA;AAC1E;AAEA,SAAS,eAAe,OAAgG;CACtH,MAAM,SAAS,cAAc,MAAM,MAAM;CACzC,MAAM,YAAA,GAAWA,MAAAA,qBAAAA,CAAqB,MAAM,MAAM,WAAW,MAAM,MAAM,aAAa,MAAM,MAAM,WAAW;CAC7G,MAAM,GAAG,eAAe,MAAM,iBAAiB;CAC/C,IAAI,CAAC,SAAS,SAAS,QAAQ,OAAO;CACtC,OACE,iBAAA,GAAA,kBAAA,IAAA,CAACD,sCAAAA,gBAAD;EAAgB,gBAAgB;GAC9B,MAAM,MAAM,cAAc,MAAM,SAAS;GACzC,YAAY,KAAK;EACnB;EACG,UAAA,OAAO,QAAQ,YAAY;CACd,CAAA;AAEpB;AAEA,SAAS,cAAc,QAA+C;CAMpE,OAAO,YALD,GAASC,MAAAA,qBAAAA,EACb,aAAY,QAAQ,UAAU,QAAQ,YAAY,CAAC,UAC7C,QAAQ,YAAY,CAAC,CAAC,UAAU,YAChC,QAAQ,YAAY,CAAC,CAAC,UAAU,IAEtB,CAAM;AAC1B"}
|
|
1
|
+
{"version":3,"file":"client.inner.cjs","names":["useState","useRef","Toast","useSyncExternalStore","Modal","Button","useRef","useSyncExternalStore","useState","useRef","useCallback","Menu","IconFolderCloseRegular","IconPlusOutlineRegular","Modal","Button","useSyncExternalStore","useRef","Tooltip","Button","Modal","useState","MenuItemButton","useSyncExternalStore"],"sources":["../src/contracts.ts","../src/copy-action.ts","../src/copy-shortcut.tsx","../src/context-menu.ts","../../dsh-plugin-kit/src/official-ui.ts","../src/styles.ts","../src/ui-copy.ts","../src/free-panel.tsx","../src/temporary-picker.tsx","../src/temporary-workspace.ts","../src/session-actions.ts","../src/user-actions.tsx","../src/client.tsx"],"sourcesContent":["/** Shared names and bounds for cross-session discovery. */\n\nexport const PLUGIN_NAME = '@klarkxy/dsh-session-manager'\nexport const COPY_THREAD_MENU_ID = '@klarkxy/dsh-session-manager.copy-thread-id'\nexport const COPY_THREAD_SHORTCUT_ID = 'session-manager.copy-thread-id'\n/** After the shipped pin/rename/fork/archive rows (100–400). */\nexport const COPY_THREAD_MENU_ORDER = 500\n/** Temporary-workspace row inside the New Session workspace picker (host list slot). */\nexport const TEMP_WORKSPACE_ITEM_ID = '@klarkxy/dsh-session-manager.temp-workspace'\nexport const TEMP_WORKSPACE_CHANNEL = '/dsh-session-manager'\nexport const TEMP_WORKSPACE_FLOW_SLOT = 'session-manager.workspace.directoryFlow'\nexport const USER_ACTIONS_SLOT = 'conversation.chat.user-actions'\nexport const USER_ACTIONS_ID = '@klarkxy/dsh-session-manager.user-actions'\nexport const DELETE_DIALOG_ID = '@klarkxy/dsh-session-manager.delete-chat'\n\nexport const LIST_TOOL = 'list_sessions'\nexport const SEARCH_TOOL = 'search_sessions'\nexport const READ_TOOL = 'read_session'\n\nexport const DEFAULT_PAGE_CHARS = 4_000\nexport const MIN_PAGE_CHARS = 200\nexport const MAX_PAGE_CHARS = 16_000\nexport const DEFAULT_LIST_LIMIT = 20\nexport const MAX_LIST_LIMIT = 100\nexport const DEFAULT_SEARCH_LIMIT = 20\nexport const MAX_SEARCH_LIMIT = 50\nexport const TOOL_SUMMARY_CHARS = 160\n\n/** Conversation reading pages by turn count, never by output size. */\nexport const DEFAULT_TURN_LIMIT = 5\nexport const MAX_TURN_LIMIT = 20\n/** Deterministic preview caps in Unicode code points; full text stays in details mode. */\nexport const PREVIEW_REQUEST_CHARS = 256\nexport const PREVIEW_CONTEXT_CHARS = 128\nexport const PREVIEW_RESPONSE_CHARS = 512\n\nexport interface Config {\n /** Maximum serialized UTF-8 bytes of one read_session details/handoff page, including item metadata. Conversation turn previews do not use this budget. */\n pageChars?: number\n /** Maximum sessions returned by one list_sessions page. */\n listLimit?: number\n /** Maximum sessions returned by one search_sessions page. */\n searchLimit?: number\n}\n\nexport interface ResolvedConfig {\n readonly pageChars: number\n readonly listLimit: number\n readonly searchLimit: number\n}\n\nexport function resolveConfig(config: Config = {}): ResolvedConfig {\n return {\n pageChars: boundInteger(config.pageChars, DEFAULT_PAGE_CHARS, MIN_PAGE_CHARS, MAX_PAGE_CHARS, 'pageChars'),\n listLimit: boundInteger(config.listLimit, DEFAULT_LIST_LIMIT, 1, MAX_LIST_LIMIT, 'listLimit'),\n searchLimit: boundInteger(config.searchLimit, DEFAULT_SEARCH_LIMIT, 1, MAX_SEARCH_LIMIT, 'searchLimit'),\n }\n}\n\nfunction boundInteger(value: number | undefined, fallback: number, min: number, max: number, name: string): number {\n const resolved = value ?? fallback\n if (!Number.isInteger(resolved) || resolved < min || resolved > max) {\n throw new TypeError(`${PLUGIN_NAME}: ${name} must be an integer from ${min} to ${max}`)\n }\n return resolved\n}\n","/** Clipboard result shown on the session-row menu. */\n\nexport type CopyLocale = 'zh' | 'en'\n\nexport const COPY_THREAD_LABEL: Record<CopyLocale, string> = {\n zh: '复制线程 ID',\n en: 'Copy thread ID',\n}\n\nexport const COPY_THREAD_FAILED: Record<CopyLocale, string> = {\n zh: '无法复制线程 ID',\n en: 'Could not copy the thread ID',\n}\n\nexport const COPY_THREAD_COPIED: Record<CopyLocale, string> = {\n zh: '已复制线程 ID',\n en: 'Thread ID copied',\n}\n\nexport const COPY_THREAD_NO_SESSION: Record<CopyLocale, string> = {\n zh: '请先打开一个会话',\n en: 'Open a session first',\n}\n\nexport function copyLocale(active: string | undefined): CopyLocale {\n return active?.toLowerCase().startsWith('zh') ? 'zh' : 'en'\n}\n\n/** Copy one session id. Rejection stays with the caller so the menu can show it. */\nexport async function copyThreadId(sessionId: string, writeText: (value: string) => Promise<void>): Promise<void> {\n await writeText(sessionId)\n}\n","import type { Context } from '@deepseek-ai/cordis'\n// ui-workspace's public contracts load the host shortcuts Context augmentation.\nimport type {} from '@deepseek-ai/dsh-client-ui-workspace/client'\nimport { Toast } from '@deepseek-ai/dsh-client-ui-primitives'\nimport { useEffect, useRef, useState } from 'react'\nimport { COPY_THREAD_SHORTCUT_ID } from './contracts.ts'\nimport { COPY_THREAD_COPIED, COPY_THREAD_FAILED, COPY_THREAD_LABEL, COPY_THREAD_NO_SESSION, copyLocale, copyThreadId, type CopyLocale } from './copy-action.ts'\nimport type { ObservableList } from './session-actions.ts'\n\nexport type HostShortcuts = Context['shortcuts']\n\nexport async function writeClipboard(value: string): Promise<void> {\n const clipboard = globalThis.navigator?.clipboard\n if (clipboard === undefined) throw new Error('clipboard unavailable')\n await clipboard.writeText(value)\n}\n\n/** Uses the same mainView reference as ui-workspace/src/client/shortcuts.ts.\n * The host registry owns key dispatch, remapping, conflicts, IME and repeat guards.\n */\nexport function CopyThreadShortcutNotice({ shortcuts, list, locale, currentLocale, writeText = writeClipboard }: {\n shortcuts?: HostShortcuts\n list?: ObservableList\n locale: CopyLocale\n currentLocale: () => string | undefined\n writeText?: (value: string) => Promise<void>\n}) {\n const [notice, setNotice] = useState<{ copied: boolean; seq: number } | null>(null)\n const sequence = useRef(0)\n useEffect(() => {\n if (shortcuts === undefined) return\n let active = true\n const notify = (copied: boolean) => {\n if (active) setNotice({ copied, seq: ++sequence.current })\n }\n const binding = { code: 'KeyC', modifiers: ['primary', 'alt'] as const }\n const stop = shortcuts.register({\n id: COPY_THREAD_SHORTCUT_ID as Parameters<HostShortcuts['register']>[0]['id'],\n label: () => COPY_THREAD_LABEL[copyLocale(currentLocale())],\n aliases: ['copy thread id', 'copy session id', '复制线程 ID'],\n defaults: {\n 'desktop:windows': binding, 'desktop:macos': binding,\n 'web:windows': binding, 'web:macos': binding,\n },\n regions: ['page', 'editable'],\n modals: [],\n resolve(context) {\n const target = Object.values(list?.getSnapshot().byId ?? {})\n .find(row => (row?.retainedBy?.mainView ?? 0) > 0)\n if (target === undefined || context.modal !== null || context.region === 'terminal') {\n return { status: 'blocked', reason: COPY_THREAD_NO_SESSION[copyLocale(currentLocale())] }\n }\n return { status: 'handled', run() {\n void copyThreadId(target.id, writeText).then(\n () => notify(true),\n () => notify(false),\n )\n } }\n },\n })\n return () => { active = false; stop() }\n }, [shortcuts, list, currentLocale, writeText])\n return notice === null ? null : <Toast\n key={notice.seq}\n text={(notice.copied ? COPY_THREAD_COPIED : COPY_THREAD_FAILED)[locale]}\n tone={notice.copied ? 'success' : undefined}\n onDone={() => setNotice(null)}\n />\n}\n","/**\n * Right-click forwarding for the sidebar browser: a `contextmenu` gesture on a\n * session or workspace row clicks that row's native \"...\" trigger, so the\n * host's own menu — including every `sidebar.workspaces.session.menu.item`\n * slot contribution, this plugin's rows included — opens exactly as a\n * left-click on the trigger would. The host owns the menu; this module only\n * relays the gesture. No host code registers a contextmenu listener, so the\n * capture-phase relay does not fight an existing handler.\n *\n * DOM contract (dsh-client-ui-workspace 0.2.0-rc.2, lib/client.js):\n * - Rows are `div[role=\"treeitem\"][data-row-key=\"session:<id>\"]` or\n * `data-row-key=\"workspace:<id>\"` inside `div[role=\"tree\"]`. Overflow and\n * empty rows carry other prefixes, search rows carry no `data-row-key`, and\n * AnimatedRows exit clones have the attribute removed — all are ignored by\n * the prefix match. (client.js:1287, 1590-1596, 1729, 1842-1846)\n * - The trigger is the first `button[type=\"button\"]` inside the row's trailing\n * `span` whose CSS-module class ends in `_rowActions`. It stays mounted —\n * CSS `display:none` until hover or menu-open — so a programmatic click\n * toggles the menu. Blank new-session rows and the ungrouped bucket render\n * no trigger; right-click does nothing there. (client.js:1061, 1314-1340,\n * 1640-1660)\n * - Class names carry a per-build hash prefix and the trigger's aria-label is\n * localized; only `data-row-key` and the structural suffix are stable.\n * - The opened menu portals to `document.body`, outside the tree, so a\n * right-click on a menu row never re-enters this relay.\n */\n\nconst ROW_SELECTOR = '[data-row-key^=\"session:\"], [data-row-key^=\"workspace:\"]'\nconst TRIGGER_SELECTOR = 'span[class*=\"rowActions\"] button[type=\"button\"]'\n\n/** Resolve the native \"...\" trigger of the row containing `target`, if any. */\nexport function findRowMenuTrigger(target: Element): HTMLElement | null {\n if (typeof target.closest !== 'function') return null\n const row = target.closest(ROW_SELECTOR)\n if (row === null || row.closest('[role=\"tree\"]') === null) return null\n const trigger = row.querySelector(TRIGGER_SELECTOR)\n if (trigger === null || typeof (trigger as HTMLElement).click !== 'function') return null\n return trigger as HTMLElement\n}\n\n/**\n * Forward one `contextmenu` event to the row's native menu trigger.\n * Returns true when the gesture was relayed (and the default suppressed).\n */\nexport function forwardContextMenu(event: Event): boolean {\n const target = event.target\n if (target === null || typeof (target as Element).closest !== 'function') return false\n const trigger = findRowMenuTrigger(target as Element)\n if (trigger === null) return false\n event.preventDefault()\n trigger.click()\n return true\n}\n\n/** Capture-phase relay on the document; the returned disposer uninstalls it. */\nexport function installContextMenuForwarding(doc: Document): () => void {\n const listener = (event: Event) => { forwardContextMenu(event) }\n doc.addEventListener('contextmenu', listener, true)\n return () => { doc.removeEventListener('contextmenu', listener, true) }\n}\n","/**\n * Shared contract that keeps every plugin's browser-side UI on the official\n * DeepSeek Harness Web design language.\n *\n * Two rules produce that language, and both are load-bearing here:\n *\n * 1. Colour, radius, elevation and focus come from the host theme's real\n * `--dsw-*` tokens, written under their own names. Plugins never invent a\n * token, never alias the official ones behind a private palette (a private\n * alias is just a second, diverging theme), and never carries a literal\n * fallback — the host publishes light and dark, and a literal would pin one\n * of them. The only non-colour custom properties used are the host's own\n * content-font axis and frame clearance.\n *\n * 2. Anything the host already ships is used, not reimplemented. Controls come\n * from `@deepseek-ai/dsh-client-ui-primitives` (`Button`, `Input`,\n * `Checkbox`, `Switch`, `Tag`, `Pill`, `SegmentedControl`, `Menu`, `Modal`,\n * `Tooltip`, `Toast`, `DisclosureRow`, `StateDot`, `PathLabel`, the settings\n * form suite). This module only styles what primitives do not cover: page\n * scaffolding, field layout, banners, empty states and scroll regions.\n *\n * The metrics below are transcribed from the primitives' own CSS modules so a\n * feature panel lines up pixel-for-pixel with a native one: the 14/22 body and\n * 13/20 compact type tiers, the 0.5px hairline scale, and the elevation family\n * that draws a surface's edge in its shadow (`border: 0`) instead of a border.\n */\n\n/**\n * Every `--dsw-*` token this repo is allowed to reference, grouped by role.\n *\n * Plugins may only colour through this list. It is exported so the guard test\n * can fail a build when a stylesheet reaches for anything else — the failure\n * mode this prevents is silent: an unknown token resolves to nothing, so a\n * border disappears or a label inherits the wrong colour with no error anywhere.\n */\nexport const OFFICIAL_THEME_TOKENS = {\n /** Surfaces, from the page up to the topmost nested card. */\n surface: [\n '--dsw-alias-bg-base',\n '--dsw-alias-bg-layer-1',\n '--dsw-alias-bg-layer-2',\n '--dsw-alias-bg-layer-3',\n '--dsw-alias-bg-layer-4',\n '--dsw-alias-bg-module-platform',\n '--dsw-alias-bg-overlay',\n ],\n /** Hairlines. l1 is near-invisible on a menu surface, so menus use l2+. */\n border: ['--dsw-alias-border-l1', '--dsw-alias-border-l2', '--dsw-alias-border-l3', '--dsw-alias-border-l4'],\n /** Text. `caption` is menu shortcut text, `dimmed` is placeholder text. */\n label: [\n '--dsw-alias-label-primary',\n '--dsw-alias-label-secondary',\n '--dsw-alias-label-tertiary',\n '--dsw-alias-label-caption',\n '--dsw-alias-label-dimmed',\n '--dsw-alias-label-error',\n '--dsw-alias-label-primary-foreground',\n ],\n /** Interactive fills. The `-danger` hover belongs to destructive rows. */\n interactive: [\n '--dsw-alias-interactive-bg-hover',\n '--dsw-alias-interactive-bg-active',\n '--dsw-alias-interactive-bg-hover-danger',\n ],\n /** Accent and status. `business` is the focus ring's default colour. */\n accent: [\n '--dsw-alias-brand-primary',\n '--dsw-alias-button-primary-fill',\n '--dsw-alias-button-primary-hover',\n '--dsw-alias-button-tool-bar-fill',\n '--dsw-alias-button-tool-bar-hover',\n '--dsw-alias-button-ghost-active-fill',\n '--dsw-alias-button-ghost-active-border',\n ],\n state: [\n '--dsw-alias-state-business-primary',\n '--dsw-alias-state-success-primary',\n '--dsw-alias-state-warn-primary',\n '--dsw-alias-state-error-primary',\n '--dsw-alias-state-idle-primary',\n ],\n /** Corner scale: sm 8, md 12, lg the large card, panel the modal. */\n radius: ['--dsw-radius-sm', '--dsw-radius-md', '--dsw-radius-lg', '--dsw-radius-panel'],\n /** An elevated surface draws its edge in the shadow, so it keeps border: 0. */\n elevation: [\n '--dsw-elevation-soft',\n '--dsw-elevation-stroke',\n '--dsw-elevation-stroke-color',\n '--dsw-elevation-panel',\n '--dsw-elevation-prominent',\n ],\n /** Floats, masks and scrollbars. */\n overlay: [\n '--dsw-menu-surface-fill',\n '--dsw-menu-backdrop-filter',\n '--dsw-mask-blur',\n '--dsw-alias-bg-mask-1',\n '--dsw-alias-menu-icon',\n '--dsw-alias-scrollbar-bg-l2',\n '--dsw-alias-scrollbar-hover-l2',\n '--dsw-shadow-lv3',\n ],\n /** Motion, focus and type axis, published by the host rather than by a component. */\n system: [\n '--dsw-focus-ring-width',\n '--dsw-focus-ring-color',\n '--dsw-font-markdown-code-font-family',\n '--ds-transition-duration',\n '--ds-ease-in-out',\n '--ds-font-family-code',\n '--dsh-scrollbar-thumb',\n '--dsh-scrollbar-thumb-hover',\n '--dsh-content-font-size-secondary',\n '--dsh-content-font-delta',\n '--dsh-frame-top-clearance',\n ],\n} as const\n\n/** Every official token name, flat. Used by the token guard test. */\nexport const OFFICIAL_THEME_TOKEN_NAMES: readonly string[] = Object.values(OFFICIAL_THEME_TOKENS).flat()\n\n/** The elevation steps a surface can be raised by, softest first. */\nexport type OfficialElevation = 'soft' | 'stroke' | 'panel' | 'prominent'\n\n/**\n * The host's focus ring shorthand, verbatim. Writing this per control is how\n * rings drift apart; a stylesheet that draws its own focus style should use\n * {@link officialFocus} instead. The colour fallback is the host's own default.\n */\nexport const OFFICIAL_FOCUS_RING =\n 'var(--dsw-focus-ring-width) solid var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary))'\n\n/**\n * A complete `outline` declaration at the official geometry. `offset` defaults\n * to the 2px the native controls use; the host's inline field rules sit at 1px\n * and a segmented tab pulls the ring inside itself at -2px.\n */\nexport function officialFocus(offset = '2px'): string {\n return `outline: ${OFFICIAL_FOCUS_RING}; outline-offset: ${offset}`\n}\n\n/**\n * An elevated surface. The host draws a raised surface's edge inside its\n * shadow rather than as a border, so a card sets `border: 0` and takes the edge\n * from the elevation — which is also why its border stays off the alias-border\n * set that a flat, non-elevated rule would use.\n */\nexport function officialElevation(level: OfficialElevation): string {\n return `border: 0; box-shadow: var(--dsw-elevation-${level})`\n}\n\n/**\n * An elevated surface whose edge should read as a specific hairline. Rebinding\n * the stroke colour is how a menu card picks l1 while a panel picks l3, without\n * the two growing apart by hand.\n */\nexport function officialStrokedElevation(level: OfficialElevation, color: string): string {\n return `--dsw-elevation-stroke-color: ${color}; ${officialElevation(level)}`\n}\n\n/**\n * The shared stylesheet for a plugin UI, scoped under that plugin's root class.\n *\n * Scoping is what keeps this safe to always-bundle into every client: the rules\n * can only match inside the plugin's own subtree, so two plugins can both mount\n * `dsh-ui-card` without either styling the other's markup.\n *\n * Each recipe matches the root element *and* its descendants, because the\n * commonest arrangement is one element that is both — a surface that carries\n * the root class and `dsh-ui-card`, or a portaled dialog that is the root and\n * the `dsh-ui-surface`. A descendant-only scope would silently leave those\n * unstyled, with no error anywhere.\n *\n * A caveat worth knowing: `Modal` and `Menu` portal to `document.body`, so their\n * content leaves the plugin's subtree entirely. A portaled surface therefore\n * needs its own root class on an element inside the portal.\n *\n * Only patterns that primitives do not provide live here. If a control appears\n * below that `Button`/`Input`/`Switch`/`Tag`/`Menu` already covers, that is a\n * bug in this file: use the primitive and delete the recipe.\n */\nexport function officialUiCss(roots: string | readonly string[]): string {\n // One plugin often mounts several unrelated surfaces (a settings seat, a chat\n // card, a header menu), so the caller names every root. The rules below are\n // nested under a single selector list and use `&`, which the browser expands\n // per root — so one stylesheet covers all of them without duplicating itself.\n const scope = (typeof roots === 'string' ? [roots] : roots).map(root => `.${root}`).join(', ')\n const sheet = `\n/* Official DSH Web UI contract. Generated by @klarkxy/dsh-plugin-kit/official-ui.\n * Do not hand-edit the copy inside a plugin: change this module so every plugin\n * moves together. Scope: ${scope} */\n/* The scope rule below stays open for the whole sheet: every rule after it\n * nests with the parent selector, so one stylesheet can cover several unrelated\n * roots without leaking into a neighbouring plugin. Its closing brace is last. */\n${scope} {\n color: var(--dsw-alias-label-primary);\n font-family: inherit;\n font-size: 14px;\n line-height: 22px;\n min-width: 0;\n\n& *, & *::before, & *::after { box-sizing: border-box; }\n& h1, & h2, & h3, & h4, & p, & figure { margin: 0; }\n/* Keyboard focus only: pointer input keeps the native resting appearance. The\n * ring needs no radius of its own — the outline already follows the control's\n * own border-radius, and overriding it here would flatten every control. */\n& :focus-visible { ${officialFocus()}; }\n& [hidden] { display: none !important; }\n\n/* --- Type tiers. The same 14/22 and 13/20 steps the primitives use. --- */\n& .dsh-ui-title { font-size: 16px; line-height: 24px; font-weight: 500; color: var(--dsw-alias-label-primary); }\n& .dsh-ui-heading { font-size: 14px; line-height: 22px; font-weight: 500; color: var(--dsw-alias-label-primary); }\n& .dsh-ui-compact { font-size: 13px; line-height: 20px; color: var(--dsw-alias-label-primary); }\n& .dsh-ui-meta { font-size: 12px; line-height: 18px; color: var(--dsw-alias-label-secondary); }\n& .dsh-ui-hint { font-size: 12px; line-height: 18px; color: var(--dsw-alias-label-tertiary); }\n& .dsh-ui-error { font-size: 12px; line-height: 18px; color: var(--dsw-alias-state-error-primary); }\n& .dsh-ui-warn { color: var(--dsw-alias-state-warn-primary); }\n& .dsh-ui-success { color: var(--dsw-alias-state-success-primary); }\n& .dsh-ui-muted { color: var(--dsw-alias-label-tertiary); }\n& .dsh-ui-truncate { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n& .dsh-ui-wrap { min-width: 0; overflow-wrap: anywhere; }\n\n/* --- Layout scaffolding. --- */\n& .dsh-ui-stack { display: flex; flex-direction: column; gap: 12px; }\n& .dsh-ui-stack-lg { display: flex; flex-direction: column; gap: 20px; }\n& .dsh-ui-row { display: flex; align-items: center; gap: 8px; min-width: 0; }\n& .dsh-ui-row-wrap { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }\n& .dsh-ui-spacer { flex: 1; min-width: 0; }\n/* A 0.5px l2 rule is the host's section divider; reserve the same rhythm. */\n& .dsh-ui-divider { height: 0.5px; background: var(--dsw-alias-border-l2); }\n& .dsh-ui-section { display: flex; flex-direction: column; gap: 12px; padding-top: 16px; border-top: 0.5px solid var(--dsw-alias-border-l2); }\n\n/* --- Card: a raised surface whose edge lives in the shadow. --- */\n& .dsh-ui-card {\n ${officialElevation('stroke')}\n display: flex;\n flex-direction: column;\n gap: 12px;\n padding: 16px;\n border-radius: var(--dsw-radius-lg);\n background: var(--dsw-alias-bg-layer-1);\n color: var(--dsw-alias-label-primary);\n min-width: 0;\n}\n& .dsh-ui-card--flat { border: 0.5px solid var(--dsw-alias-border-l3); box-shadow: none; }\n& .dsh-ui-card--nested { background: var(--dsw-alias-bg-layer-2); }\n& .dsh-ui-card--plain { background: none; }\n\n/* --- Field: label, control, help, error. The control itself is an\n * official primitive, so this only owns the vertical rhythm. --- */\n& .dsh-ui-field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }\n& .dsh-ui-field + .dsh-ui-field { border-top: 0.5px solid var(--dsw-alias-border-l2); padding-top: 12px; }\n& .dsh-ui-label { display: flex; align-items: center; gap: 6px; font-size: 13px; line-height: 20px; font-weight: 500; color: var(--dsw-alias-label-primary); }\n& .dsh-ui-label-row { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }\n& .dsh-ui-help { font-size: 12px; line-height: 1.6; color: var(--dsw-alias-label-secondary); }\n& .dsh-ui-help p { margin: 0; }\n& .dsh-ui-help p + p { margin-top: 8px; }\n& .dsh-ui-required { color: var(--dsw-alias-state-error-primary); }\n& .dsh-ui-control { width: 100%; min-width: 0; }\n/* An invalid control is marked on the control, not only in the message. */\n& .dsh-ui-control[aria-invalid='true'] { border-color: var(--dsw-alias-state-error-primary); }\n& .dsh-ui-readonly { display: flex; flex-direction: column; gap: 4px; min-width: 0; }\n& .dsh-ui-readonly > dt { font-size: 12px; line-height: 18px; color: var(--dsw-alias-label-tertiary); }\n& .dsh-ui-readonly > dd { margin: 0; font-size: 13px; line-height: 20px; overflow-wrap: anywhere; }\n\n/* --- Buttons row. A no-op container: it exists so actions line up on the\n * trailing edge the way every native panel does. --- */\n& .dsh-ui-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding-top: 4px; }\n& .dsh-ui-actions-end { justify-content: flex-end; }\n\n/* --- Banners. A banner is a left-rail notice, the shape used for warnings,\n * deprecations and blocking instructions. --- */\n& .dsh-ui-banner {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 10px 14px;\n border: 0.5px solid var(--dsw-alias-border-l3);\n border-left: 3px solid var(--dsw-alias-state-warn-primary);\n border-radius: var(--dsw-radius-md);\n background: var(--dsw-alias-bg-layer-1);\n font-size: 13px;\n line-height: 20px;\n color: var(--dsw-alias-label-secondary);\n}\n& .dsh-ui-banner-title { font-weight: 500; color: var(--dsw-alias-state-warn-primary); }\n& .dsh-ui-banner--info { border-left-color: var(--dsw-alias-state-business-primary); }\n& .dsh-ui-banner--danger { border-left-color: var(--dsw-alias-state-error-primary); }\n& .dsh-ui-banner--success { border-left-color: var(--dsw-alias-state-success-primary); }\n& .dsh-ui-banner p { margin: 0; }\n\n/* --- Inline notice: a transient confirmation with no chrome of its own. --- */\n& .dsh-ui-notice { display: flex; align-items: center; gap: 6px; font-size: 12px; line-height: 18px; color: var(--dsw-alias-state-success-primary); }\n& .dsh-ui-notice--error { color: var(--dsw-alias-state-error-primary); }\n\n/* --- Empty and loading states. Both sit in a dashed well so an empty panel\n * reads as \"nothing here yet\" rather than as a broken layout. --- */\n& .dsh-ui-empty {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 6px;\n padding: 20px 16px;\n border: 0.5px dashed var(--dsw-alias-border-l3);\n border-radius: var(--dsw-radius-md);\n font-size: 13px;\n line-height: 20px;\n color: var(--dsw-alias-label-secondary);\n}\n& .dsh-ui-loading { display: flex; align-items: center; gap: 8px; padding: 20px 0; font-size: 13px; line-height: 20px; color: var(--dsw-alias-label-secondary); }\n\n/* --- Selectable list. A row is a button-sized target with a hover fill and\n * a selected fill; the name carries the weight, the description does not. --- */\n& .dsh-ui-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; min-width: 0; }\n& .dsh-ui-list-scroll { max-height: min(66vh, 760px); overflow-y: auto; overflow-x: hidden; }\n& .dsh-ui-list-row { border-radius: var(--dsw-radius-md); }\n& .dsh-ui-list-row:hover { background: var(--dsw-alias-interactive-bg-hover); }\n& .dsh-ui-list-row[aria-selected='true'], & .dsh-ui-list-row[data-selected] { background: var(--dsw-alias-interactive-bg-active); }\n& .dsh-ui-list-item {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 4px;\n width: 100%;\n min-width: 0;\n padding: 10px 12px;\n border: 0;\n border-radius: var(--dsw-radius-md);\n background: none;\n font: inherit;\n color: inherit;\n text-align: start;\n cursor: pointer;\n}\n& .dsh-ui-list-item:disabled { cursor: default; }\n& .dsh-ui-list-item:disabled:hover { background: none; }\n& .dsh-ui-list-name { font-size: 14px; line-height: 22px; font-weight: 500; color: var(--dsw-alias-label-primary); overflow-wrap: anywhere; }\n& .dsh-ui-list-desc { font-size: 12px; line-height: 18px; color: var(--dsw-alias-label-tertiary); }\n\n/* --- Code and structured output. Wraps rather than scrolls, because a\n * feature panel is read rather than scanned. --- */\n& .dsh-ui-code {\n padding: 10px 12px;\n border: 0.5px solid var(--dsw-alias-border-l3);\n border-radius: var(--dsw-radius-md);\n background: var(--dsw-alias-bg-layer-1);\n font-family: var(--ds-font-family-code);\n font-size: 12px;\n line-height: 20px;\n color: var(--dsw-alias-label-secondary);\n overflow-wrap: anywhere;\n white-space: pre-wrap;\n}\n& .dsh-ui-scroll { max-height: 60vh; overflow: auto; overscroll-behavior: contain; }\n\n/* --- A toggle row: label on the left, switch on the trailing edge. This is\n * layout only; the switch itself is the official primitive. --- */\n& .dsh-ui-toggle-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; min-width: 0; padding: 12px 0; }\n& .dsh-ui-toggle-row + .dsh-ui-toggle-row { border-top: 0.5px solid var(--dsw-alias-border-l2); }\n& .dsh-ui-toggle-text { display: flex; flex-direction: column; gap: 4px; min-width: 0; }\n& .dsh-ui-toggle-label { font-size: 14px; line-height: 22px; font-weight: 500; color: var(--dsw-alias-label-primary); }\n\n/* --- Floating surface: a panel anchored to a trigger. This is the material\n * a menu card is made of — the translucent fill plus its backdrop blur, with\n * the edge riding inside the prominent elevation. A plugin that hand-rolls this\n * is how tokens like --dsw-specific-menu get invented; use this instead. --- */\n& .dsh-ui-surface {\n --dsw-elevation-stroke-color: var(--dsw-alias-border-l1);\n --dsh-scrollbar-thumb: var(--dsw-alias-scrollbar-bg-l2);\n --dsh-scrollbar-thumb-hover: var(--dsw-alias-scrollbar-hover-l2);\n position: relative;\n display: flex;\n flex-direction: column;\n border: 0;\n border-radius: var(--dsw-radius-lg);\n background: var(--dsw-menu-surface-fill);\n backdrop-filter: var(--dsw-menu-backdrop-filter);\n box-shadow: var(--dsw-elevation-prominent);\n color: var(--dsw-alias-label-primary);\n font-size: 13px;\n line-height: 20px;\n min-width: 0;\n}\n& .dsh-ui-surface-body { display: flex; flex-direction: column; gap: 8px; padding: 12px 14px 14px; overflow-y: auto; }\n& .dsh-ui-surface-head { display: flex; align-items: center; gap: 8px; min-width: 0; }\n& .dsh-ui-surface-title { font-size: 14px; line-height: 22px; font-weight: 500; color: var(--dsw-alias-label-primary); }\n\n/* --- Native select. The primitives ship no select, so a plugin that offers a\n * closed list of choices keeps the platform control and matches the official\n * settings field geometry exactly (34px, 0.5px l4, radius-md, layer-3). A\n * SegmentedControl is the primitive to reach for when the choices are few\n * enough to show at once. --- */\n& .dsh-ui-select {\n box-sizing: border-box;\n width: 100%;\n min-width: 0;\n height: 34px;\n padding: 0 12px;\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: var(--dsw-radius-md);\n background: var(--dsw-alias-bg-layer-3);\n font: inherit;\n font-size: 13px;\n line-height: 1.5;\n color: var(--dsw-alias-label-primary);\n cursor: pointer;\n}\n& .dsh-ui-select:focus-visible { outline: none; border-color: var(--dsw-alias-state-business-primary); }\n& .dsh-ui-select:disabled { color: var(--dsw-alias-label-tertiary); cursor: default; }\n& .dsh-ui-select[aria-invalid='true'] { border-color: var(--dsw-alias-state-error-primary); }\n\n/* Long panels scroll inside themselves instead of growing the host page. */\n& .dsh-ui-panel { display: flex; flex-direction: column; gap: 16px; min-width: 0; }\n& .dsh-ui-panel-wide { max-width: 100%; }\n\n@media (prefers-reduced-motion: reduce) {\n & *, & *::before, & *::after { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; }\n}\n}\n`\n // Widen every recipe from \"a descendant of the root\" to \"the root, or one of\n // its descendants\". Written as a transform rather than by hand so no recipe\n // can be added later with only the descendant form. The pattern is narrow on\n // purpose: a leading `&` followed by one recipe class and no combinator, so\n // sibling and child rules such as `.dsh-ui-field + .dsh-ui-field` keep their\n // own meaning and are left alone.\n return sheet.replace(/^& (\\.dsh-ui-[a-z0-9-]+)(?![+>~])/gm, (_match, className: string) =>\n `&${className}, & ${className}`)\n}\n","import { officialUiCss } from '@klarkxy/dsh-plugin-kit/official-ui'\n\nexport const FREE_CHAT_ROOT = 'dsh-free-chat'\n\n/** Host tokens and official scaffolding. Only the edit draft, the inline action row,\n * and the alert line survive the panel removal; the modals reuse the root class. */\nexport const freeChatCss = `${officialUiCss(FREE_CHAT_ROOT)}\n.${FREE_CHAT_ROOT} .dsh-free-draft {\n box-sizing: border-box;\n width: 100%;\n min-height: 8em;\n padding: 8px 12px;\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: var(--dsw-radius-md);\n background: var(--dsw-alias-bg-layer-3);\n color: var(--dsw-alias-label-primary);\n font: inherit;\n font-size: 14px;\n line-height: 22px;\n resize: vertical;\n}\n.${FREE_CHAT_ROOT} .dsh-free-actions {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n min-width: 0;\n}\n.${FREE_CHAT_ROOT} .dsh-free-alert { margin: 0; }\n`\n","import { copyLocale, type CopyLocale } from './copy-action.ts'\n\nexport type { CopyLocale }\nexport { copyLocale }\n\n/** Failure identity stored by the UI. The sentence is derived from the active locale. */\nexport interface OperationFailure {\n readonly code: string\n readonly reason?: string\n}\n\nconst reasons = {\n zh: {\n modified: '后续操作可能涉及修改,暂时不能重试。',\n unknown: '无法确认这个操作的结果。',\n pending: '这条消息还在等待处理。',\n stale: '这个聊天已经更新,请再试一次。',\n running: '这个聊天仍在运行。请等待当前工作结束后再试。',\n cleanup: '清理没有完成。',\n unsupported: '当前版本不能完成这个操作。',\n },\n en: {\n modified: 'Later operations may have made changes. Retry is unavailable.',\n unknown: \"This action's result could not be confirmed.\",\n pending: 'This message is still pending.',\n stale: 'This chat has changed. Try again.',\n running: 'This chat is still running. Wait for the current work to finish, then try again.',\n cleanup: 'Cleanup did not finish.',\n unsupported: 'This runtime cannot complete that action.',\n },\n} as const\n\nexport type FailureReason = keyof typeof reasons.zh\n\nconst text = {\n zh: {\n tempWorkspace: '临时工作区',\n createFailed: '无法创建临时工作区',\n retryList: '重试',\n deleteChat: '删除聊天',\n deleting: '正在删除',\n deleteFree: '将删除这个聊天及其拥有的文件。',\n deleteOrdinary: '将删除这个聊天。项目文件会保留。',\n cancel: '取消',\n close: '关闭',\n retry: '重试',\n edit: '编辑并重发',\n send: '发送',\n editTitle: '编辑并重发',\n draft: '消息文本',\n },\n en: {\n tempWorkspace: 'Temporary Workspace',\n createFailed: 'Could not create the temporary workspace',\n retryList: 'Retry',\n deleteChat: 'Delete chat',\n deleting: 'Deleting',\n deleteFree: 'This deletes this chat and its owned files.',\n deleteOrdinary: 'This deletes this chat. Project files remain.',\n cancel: 'Cancel',\n close: 'Close',\n retry: 'Retry',\n edit: 'Edit and resend',\n send: 'Send',\n editTitle: 'Edit and resend',\n draft: 'Message text',\n },\n} as const\n\nexport type UiTextKey = keyof typeof text.zh\n\nexport function uiText(locale: CopyLocale, key: UiTextKey): string {\n return text[locale][key]\n}\n\nexport function failureReason(failure: OperationFailure): FailureReason {\n if (failure.code === 'session/lifecycle-unavailable' || failure.code === 'session/fork-unavailable') return 'unsupported'\n if (\n failure.code === 'session/retry-revision'\n || failure.code === 'session/branch-moved'\n || failure.code === 'session/retry-input'\n || failure.code === 'session/retry-conflict'\n ) return 'stale'\n if (failure.code === 'session/delete-pending') return 'cleanup'\n if (failure.code === 'session/agent-busy' && failure.reason === 'free-session-work-active') return 'running'\n if (failure.reason === 'modified' || failure.reason === 'pending' || failure.reason === 'running' || failure.reason === 'stale') {\n return failure.reason\n }\n if (failure.reason === 'stop-failed' || failure.reason === 'not-quiet') return 'running'\n if (failure.reason === 'not-human-prompt' || failure.reason === 'missing-evidence') return 'unknown'\n return 'unknown'\n}\n\nexport function failureText(locale: CopyLocale, failure: OperationFailure): string {\n return reasons[locale][failureReason(failure)]\n}\n\nexport function deleteBody(locale: CopyLocale, classification: 'free' | 'ordinary'): string {\n return classification === 'free' ? text[locale].deleteFree : text[locale].deleteOrdinary\n}\n","import { useEffect, useRef, useSyncExternalStore } from 'react'\nimport { Button, Modal } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { FreeChatModel } from './session-actions.ts'\nimport { FREE_CHAT_ROOT } from './styles.ts'\nimport { deleteBody, failureText, uiText, type CopyLocale } from './ui-copy.ts'\n\nexport function FreeChatIcon({ size }: { size: number; active?: boolean }): React.ReactElement {\n return (\n <svg width={size} height={size} viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <path\n d=\"M2.5 3.5h11v7.5h-4.2L6 13.5V11H2.5z\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.2\"\n />\n </svg>\n )\n}\n\n/** Create failures used to surface inside the standalone panel. The panel is gone,\n * so they get a small overlay instead; closing it dismisses the stored notice. */\nexport function CreateNoticeDialog(props: { model: FreeChatModel; locale: CopyLocale }): React.ReactElement | null {\n const snapshot = useSyncExternalStore(props.model.subscribe, props.model.getSnapshot, props.model.getSnapshot)\n const notice = snapshot.notice\n if (notice === undefined) return null\n const copy = (key: Parameters<typeof uiText>[1]) => uiText(props.locale, key)\n return (\n <Modal\n open\n className={FREE_CHAT_ROOT}\n title={copy('createFailed')}\n closeLabel={copy('close')}\n onClose={() => { props.model.dismissNotice() }}\n footer={(\n <Button variant=\"primary\" data-modal-autofocus onClick={() => { props.model.dismissNotice() }}>\n {copy('close')}\n </Button>\n )}\n >\n <p className=\"dsh-ui-error dsh-free-alert\" role=\"alert\">{failureText(props.locale, notice)}</p>\n </Modal>\n )\n}\n\nexport function DeleteChatDialog(props: { model: FreeChatModel; locale: CopyLocale }): React.ReactElement | null {\n const snapshot = useSyncExternalStore(props.model.subscribe, props.model.getSnapshot, props.model.getSnapshot)\n const request = snapshot.deleteRequest\n const confirmRef = useRef<HTMLButtonElement>(null)\n useEffect(() => {\n if (request?.failure) confirmRef.current?.focus()\n }, [request?.failure])\n if (request === undefined) return null\n const copy = (key: Parameters<typeof uiText>[1]) => uiText(props.locale, key)\n const label = request.busy ? copy('deleting') : request.failure ? copy('retryList') : copy('deleteChat')\n return (\n <Modal\n open\n className={FREE_CHAT_ROOT}\n title={copy('deleteChat')}\n closeLabel={copy('close')}\n description={deleteBody(props.locale, request.classification)}\n onClose={() => { props.model.cancelDelete() }}\n footer={(\n <>\n <Button variant=\"ghost\" disabled={request.busy} onClick={() => { props.model.cancelDelete() }}>{copy('cancel')}</Button>\n <Button\n ref={confirmRef}\n variant=\"primary\"\n data-modal-autofocus\n disabled={request.busy}\n onClick={() => { void props.model.confirmDelete() }}\n >\n {label}\n </Button>\n </>\n )}\n >\n <p>{request.title}</p>\n {request.failure ? <p className=\"dsh-ui-error dsh-free-alert\" role=\"alert\">{failureText(props.locale, request.failure)}</p> : null}\n </Modal>\n )\n}\n","import { useCallback, useEffect, useRef, useState, useSyncExternalStore, type ReactNode, type RefObject } from 'react'\nimport { Button, IconFolderCloseRegular, IconPlusOutlineRegular, Menu, Modal } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { StoredEntry } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { DirectoryFlowOwnerProps, WorkspacePickerProps } from '@deepseek-ai/dsh-client-ui-workspace/client'\nimport { FreeChatIcon } from './free-panel.tsx'\nimport { TEMP_WORKSPACE_FLOW_SLOT } from './contracts.ts'\nimport { uiText, type CopyLocale } from './ui-copy.ts'\nimport type { TemporaryWorkspaceModel } from './temporary-workspace.ts'\nimport { copyLocale } from './copy-action.ts'\n\nconst PICKER_SLOT = 'conversation.hero.workspace'\nconst DIRECTORY_SLOT = 'conversation.hero.workspace.directoryFlow'\n\n/** Public registry faces used by the version-bounded directory-flow compatibility adapter. */\nexport interface PickerRegistry {\n inject(key: string, callback: () => (() => void) | void): () => void\n register(options: Record<string, unknown>, component: unknown): () => void\n entriesOfSlot(key: string): readonly StoredEntry[]\n spec(key: string): { kind: string; scope: string } | undefined\n subscribe(key: string, listener: () => void): () => void\n onEntryError?(listener: (key: string, entry: StoredEntry, error: unknown) => void): () => void\n}\n\n/** Keep the host's native/web picker implementation and its injected capabilities.\n * Standard rc.2 offers no exported directory-flow factory. Only its simple root\n * registration can be mirrored; more complex future registrations restore the host picker.\n * Original entries and their ownership ledger are never changed.\n */\nexport function installTemporaryWorkspacePicker(slots: PickerRegistry, model: TemporaryWorkspaceModel,\n createWorkspace: (path: string) => Promise<{ workspaceId: string }>, locale?: {\n getSnapshot(): { active: string }; subscribe(listener: () => void): () => void\n }): () => void {\n if (typeof slots.entriesOfSlot !== 'function' || typeof slots.spec !== 'function' || typeof slots.subscribe !== 'function') {\n model.reportFailure(copyLocale(locale?.getSnapshot().active) === 'zh'\n ? '当前版本无法扩展工作区菜单,已保留原菜单。' : 'Could not extend the workspace menu. The original menu has been preserved.')\n return () => {}\n }\n return slots.inject(PICKER_SLOT, () => {\n let mirror: StoredEntry | undefined, stopMirror = () => {}, restored = false\n const failureMessage = () => copyLocale(locale?.getSnapshot().active) === 'zh'\n ? '当前版本无法扩展工作区菜单,已保留原菜单。' : 'Could not extend the workspace menu. The original menu has been preserved.'\n const renderPicker = (props: PickerProps) => <TemporaryWorkspacePicker {...props} model={model} createWorkspace={createWorkspace} locale={locale}\n getDirectoryFlow={() => mirror} subscribeFlow={listener => slots.subscribe(DIRECTORY_SLOT, listener)} />\n const stopPicker = slots.register({ name: PICKER_SLOT, priority: -10, locale: 'workspace',\n children: { [TEMP_WORKSPACE_FLOW_SLOT]: { kind: 'single', scope: 'root' } },\n }, renderPicker)\n const stopErrors = slots.onEntryError?.((key, entry) => {\n if (restored || (key !== TEMP_WORKSPACE_FLOW_SLOT && !(key === PICKER_SLOT && entry.component === renderPicker))) return\n restored = true; stopMirror(); mirror = undefined; stopPicker()\n model.reportFailure(failureMessage())\n }) ?? (() => {})\n const sync = () => {\n if (restored) return\n const next = slots.entriesOfSlot(DIRECTORY_SLOT)[0]\n if (next === mirror) return\n stopMirror(); stopMirror = () => {}; mirror = undefined\n if (next === undefined) return\n const spec = slots.spec(DIRECTORY_SLOT)\n if (spec?.kind !== 'single' || spec.scope !== 'root' || typeof next.component !== 'function'\n || next.children !== undefined || next.store !== undefined || next.locale !== undefined || next.select !== undefined) {\n restored = true; stopPicker()\n model.reportFailure(failureMessage())\n return\n }\n try {\n stopMirror = slots.register({ name: TEMP_WORKSPACE_FLOW_SLOT, ...next.inject ? { inject: next.inject } : {} }, next.component)\n mirror = next\n } catch (error) {\n restored = true; stopPicker()\n model.reportFailure(error instanceof Error ? error.message : 'Could not extend the workspace picker')\n }\n }\n const stopSource = slots.subscribe(DIRECTORY_SLOT, sync)\n sync()\n return () => { restored = true; stopErrors(); stopSource(); stopMirror(); stopPicker() }\n })\n}\n\n/** Standard conversation hero owner share; some published type graphs omit its merge. */\ntype PickerProps = Pick<WorkspacePickerProps, 'useWorkspaces'> & {\n open: boolean\n anchorRef?: RefObject<HTMLElement | null>\n selectedId?: string\n onPick(workspaceId: string): void\n onClose(): void\n t(key: string): string\n renderSlot(key: typeof TEMP_WORKSPACE_FLOW_SLOT, owner: DirectoryFlowOwnerProps): ReactNode\n}\n\nfunction TemporaryWorkspacePicker(props: PickerProps & {\n model: TemporaryWorkspaceModel; createWorkspace(path: string): Promise<{ workspaceId: string }>\n getDirectoryFlow(): StoredEntry | undefined; subscribeFlow(listener: () => void): () => void\n locale?: { getSnapshot(): { active: string }; subscribe(listener: () => void): () => void }\n}) {\n const workspaces = props.useWorkspaces(snapshot => snapshot)\n const state = useSyncExternalStore(props.model.subscribe, props.model.getSnapshot, props.model.getSnapshot)\n const source = useSyncExternalStore(props.subscribeFlow, props.getDirectoryFlow, props.getDirectoryFlow)\n const available = source !== undefined\n const locale = copyLocale(useSyncExternalStore(listener => props.locale?.subscribe(listener) ?? (() => {}),\n () => props.locale?.getSnapshot().active ?? 'en', () => 'en'))\n const [flowOpen, setFlowOpen] = useState(false), [adopting, setAdopting] = useState(false)\n const [failure, setFailure] = useState<string>()\n const epoch = useRef(0)\n useEffect(() => () => { epoch.current++ }, [])\n useEffect(() => { epoch.current++; setFlowOpen(false); setAdopting(false) }, [source])\n const busy = flowOpen || adopting || state.creating\n const getAnchorRect = useCallback(() => props.anchorRef?.current?.getBoundingClientRect() ?? null, [props.anchorRef])\n const openDirectory = () => { props.onClose(); setFailure(undefined); setFlowOpen(true) }\n return <>\n <Menu open={props.open} anchor={null} portal getAnchorRect={getAnchorRect} selectedId={props.selectedId}\n onClose={props.onClose} items={workspaces.items.map(workspace => ({ id: workspace.workspaceId,\n // The standard registry's first-use title is language-neutral; all user titles stay verbatim.\n label: workspace.title === 'default-workspace' ? props.t('workspace.defaultName') : workspace.title,\n icon: <IconFolderCloseRegular size={16} />, disabled: busy }))}\n footer={[\n ...available ? [{ id: '::add-workspace', label: props.t('menu.addWorkspace'), icon: <IconPlusOutlineRegular size={16} />, disabled: busy }] : [],\n { id: '::temporary-workspace', label: uiText(locale, 'tempWorkspace'), icon: <FreeChatIcon size={16} />, disabled: busy },\n ]}\n onSelect={id => {\n if (id === '::add-workspace') openDirectory()\n else if (id === '::temporary-workspace') { props.onClose(); void props.model.create() }\n else props.onPick(id as never)\n }} />\n {props.open && workspaces.phase === 'pending' && <span role=\"status\">{props.t('picker.loading')}</span>}\n {props.renderSlot(TEMP_WORKSPACE_FLOW_SLOT, {\n open: flowOpen, busy: adopting,\n onCancel: () => { epoch.current++; setFlowOpen(false); setAdopting(false) },\n onError: message => { epoch.current++; setFlowOpen(false); setAdopting(false); setFailure(message) },\n onPicked: path => {\n if (adopting) return\n const ticket = ++epoch.current\n setAdopting(true)\n void props.createWorkspace(path).then(workspace => {\n if (ticket !== epoch.current) return\n setFlowOpen(false); props.onPick(workspace.workspaceId as never)\n }, error => {\n if (ticket !== epoch.current) return\n setFlowOpen(false); setFailure(error instanceof Error ? error.message : String(error))\n }).finally(() => { if (ticket === epoch.current) setAdopting(false) })\n },\n })}\n <Modal open={failure !== undefined} title={props.t('folderError.title')} closeLabel={props.t('close')}\n onClose={() => setFailure(undefined)} footer={<>\n <Button variant=\"outline\" onClick={() => setFailure(undefined)}>{props.t('cancel')}</Button>\n <Button variant=\"primary\" disabled={!available} onClick={openDirectory}>{props.t('folderError.retry')}</Button>\n </>}><p role=\"alert\">{failure}</p></Modal>\n </>\n}\n\nexport function TemporaryWorkspaceNotice({ model, locale }: { model: TemporaryWorkspaceModel; locale: CopyLocale }) {\n const state = useSyncExternalStore(model.subscribe, model.getSnapshot, model.getSnapshot)\n return <Modal open={state.failure !== undefined} title={uiText(locale, 'createFailed')}\n closeLabel={uiText(locale, 'close')} onClose={model.dismissFailure} footer={<>\n <Button variant=\"outline\" onClick={model.dismissFailure}>{uiText(locale, 'close')}</Button>\n <Button variant=\"primary\" disabled={state.creating} onClick={() => { void model.create() }}>{uiText(locale, 'retry')}</Button>\n </>}><p role=\"alert\">{state.failure}</p></Modal>\n}\n","import { TEMP_WORKSPACE_CHANNEL } from './contracts.ts'\n\nexport interface TemporaryWorkspaceHost {\n beginNavigation(): AbortSignal\n allocate(requestId: string, signal: AbortSignal): Promise<{ requestId: string; path: string }>\n createWorkspace(path: string): Promise<{ workspaceId: string }>\n renameWorkspace(workspaceId: string, title: string): Promise<unknown>\n openWorkspace(workspaceId: string, beforeOpen: () => void): Promise<void>\n}\n\nexport interface TemporaryWorkspaceSnapshot {\n readonly creating: boolean\n readonly failure?: string\n}\n\nexport function createTemporaryWorkspaceModel(host: TemporaryWorkspaceHost, ids = () => crypto.randomUUID(), label = () => 'Temporary Workspace') {\n const lifetime = new AbortController(), listeners = new Set<() => void>()\n let snapshot: TemporaryWorkspaceSnapshot = { creating: false }\n let pending: { requestId: string; title: string; path?: string; workspaceId?: string; named?: boolean } | undefined\n const publish = (next: TemporaryWorkspaceSnapshot) => {\n if (lifetime.signal.aborted) return\n snapshot = next\n for (const listener of listeners) listener()\n }\n return {\n getSnapshot: () => snapshot,\n subscribe(listener: () => void) { listeners.add(listener); return () => { listeners.delete(listener) } },\n dismissFailure() { publish({ creating: snapshot.creating }) },\n reportFailure(failure: string) { publish({ ...snapshot, failure }) },\n async create() {\n if (snapshot.creating || lifetime.signal.aborted) return\n // Capture before allocation/adoption so late completion cannot steal a newer navigation.\n const signal = AbortSignal.any([host.beginNavigation(), lifetime.signal])\n const action = pending ??= { requestId: ids(), title: label() }\n let opening = false\n publish({ creating: true })\n try {\n signal.throwIfAborted()\n if (action.path === undefined) {\n const allocated = await host.allocate(action.requestId, signal)\n if (allocated.requestId !== action.requestId || !allocated.path) throw new Error('Invalid temporary workspace response')\n action.path = allocated.path\n }\n signal.throwIfAborted()\n if (action.workspaceId === undefined) action.workspaceId = (await host.createWorkspace(action.path)).workspaceId\n signal.throwIfAborted()\n if (!action.named) {\n await host.renameWorkspace(action.workspaceId, `${action.title} ${action.requestId.slice(0, 8)}`)\n action.named = true\n }\n signal.throwIfAborted()\n opening = true\n await host.openWorkspace(action.workspaceId, () => lifetime.signal.throwIfAborted())\n // openWorkspace starts its own fenced navigation, invalidating our earlier signal.\n if (!lifetime.signal.aborted) pending = undefined\n } catch (error) {\n if (!lifetime.signal.aborted && (opening ? !(error instanceof Error && error.name === 'AbortError') : !signal.aborted)) {\n publish({ creating: false, failure: error instanceof Error ? error.message : 'Could not create the temporary workspace' })\n }\n } finally {\n publish({ ...snapshot, creating: false })\n }\n },\n cancel() { lifetime.abort(); listeners.clear() },\n }\n}\n\nexport type TemporaryWorkspaceModel = ReturnType<typeof createTemporaryWorkspaceModel>\n\nexport function bindTemporaryWorkspaceHost(ctx: {\n layout: { beginNavigation(): AbortSignal }\n connection: { rpc: { call(channel: string, endpoint: string, payload: unknown, signal?: AbortSignal): Promise<unknown> } }\n workspaces: { create(input: { path: string }): Promise<{ workspaceId: string }>; rename(workspaceId: string, title: string): Promise<unknown> }\n uiWorkspace: { openWorkspace(workspaceId: string, beforeOpen?: () => void): Promise<void> }\n}): TemporaryWorkspaceHost {\n return {\n beginNavigation: () => ctx.layout.beginNavigation(),\n async allocate(requestId, signal) {\n const raw = await ctx.connection.rpc.call(TEMP_WORKSPACE_CHANNEL, 'temporary.allocate', { requestId }, signal)\n const response = raw as { ok?: boolean; value?: { requestId: string; path: string }; error?: { message?: string } }\n if (response?.ok !== true || typeof response.value?.path !== 'string' || typeof response.value.requestId !== 'string') {\n throw new Error(response?.error?.message ?? 'Could not allocate the temporary workspace')\n }\n return response.value\n },\n createWorkspace: path => ctx.workspaces.create({ path }),\n renameWorkspace: (workspaceId, title) => ctx.workspaces.rename(workspaceId, title),\n openWorkspace: (workspaceId, beforeOpen) => ctx.uiWorkspace.openWorkspace(workspaceId, beforeOpen),\n }\n}\n","/**\n * Narrow client faces the host owner still has to publish.\n * Call these only when the live service actually has the method.\n * Do not call the session remote directly: manager.create still drops `kind`,\n * and delete/retry have to update the catalog and the open selection.\n */\nimport type { OperationFailure } from './ui-copy.ts'\nimport type { SessionListSnapshot } from './free-list.ts'\n\nexport interface SessionCapabilities {\n readonly retry: boolean\n readonly freeSession: boolean\n readonly deleteSession: boolean\n}\n\nexport const UNSUPPORTED_CAPABILITIES: SessionCapabilities = {\n retry: false,\n freeSession: false,\n deleteSession: false,\n}\n\n/**\n * `inputRevision` is an opaque token from preview.\n * An eligible preview without it is not a supported retry.\n */\nexport interface RetryPreview {\n readonly branchRevision: number\n readonly inputRevision: string\n readonly eligible: boolean\n readonly reason?: string\n}\n\n/** Direct retry omits `text` so the host keeps the original attachments. */\nexport interface DirectRetryRequest {\n readonly sessionId: string\n readonly messageId: string\n readonly expectedRevision: number\n readonly expectedInputRevision: string\n readonly requestId: string\n}\n\n/** Edit sends plain text only. The host keeps attachments. */\nexport interface EditRetryRequest extends DirectRetryRequest {\n readonly text: string\n}\n\nexport interface DeleteOutcome {\n readonly phase: 'deleted' | 'cleanup-pending'\n}\n\nexport interface ObservableList {\n getSnapshot(): SessionListSnapshot\n subscribe(listener: () => void): () => void\n}\n\nexport interface SessionHost {\n readonly list: ObservableList\n capabilities?: () => Promise<unknown> | unknown\n create?: (opts: { kind: 'free' }) => Promise<unknown>\n previewRetry?: (request: { sessionId: string; messageId: string }) => Promise<unknown>\n retry?: (request: DirectRetryRequest | EditRetryRequest) => Promise<unknown>\n openSession?: (sessionId: string) => void\n deleteSession?: (sessionId: string, requestId: string) => Promise<unknown>\n}\n\ninterface RemoteFailure {\n readonly code?: string\n readonly message?: string\n readonly details?: { readonly reason?: string }\n}\n\ninterface RemoteResult {\n readonly ok: boolean\n readonly value?: unknown\n readonly error?: RemoteFailure\n}\n\nexport function isRecoverable(failure: OperationFailure): boolean {\n return failure.code === 'transport' || failure.code === 'session/delete-pending'\n}\n\nexport function readFailure(error: unknown): OperationFailure {\n if (isFailure(error)) return { code: error.code, ...error.reason === undefined ? {} : { reason: error.reason } }\n if (typeof error === 'object' && error !== null) {\n const record = error as { code?: unknown; reason?: unknown; message?: unknown; rpcError?: RemoteFailure }\n const rpc = record.rpcError\n if (typeof rpc?.code === 'string') {\n return { code: rpc.code, ...reasonOf(rpc) === undefined ? {} : { reason: reasonOf(rpc) } }\n }\n if (typeof record.code === 'string') {\n const reason = typeof record.reason === 'string' ? record.reason : undefined\n return { code: record.code, ...reason === undefined ? {} : { reason } }\n }\n }\n return { code: 'transport', reason: 'unknown' }\n}\n\nfunction isFailure(error: unknown): error is OperationFailure {\n return typeof error === 'object' && error !== null && 'code' in error && typeof (error as { code: unknown }).code === 'string'\n && (error as { name?: string }).name === 'HostOperationError'\n}\n\nexport class HostOperationError extends Error implements OperationFailure {\n override readonly name = 'HostOperationError'\n readonly reason?: string\n constructor(readonly code: string, reason?: string) {\n super(code)\n if (reason !== undefined) this.reason = reason\n }\n}\n\nfunction reasonOf(error: RemoteFailure | undefined): string | undefined {\n return typeof error?.details?.reason === 'string' ? error.details.reason : undefined\n}\n\nfunction isRemoteResult(value: unknown): value is RemoteResult {\n if (typeof value !== 'object' || value === null || !('ok' in value)) return false\n const ok = (value as { ok: unknown }).ok\n return typeof ok === 'boolean' && ('value' in value || 'error' in value)\n}\n\nexport async function unwrap(value: unknown): Promise<unknown> {\n const resolved = await value\n if (!isRemoteResult(resolved)) return resolved\n if (!resolved.ok) {\n throw new HostOperationError(resolved.error?.code ?? 'transport', reasonOf(resolved.error))\n }\n return resolved.value\n}\n\nexport async function readCapabilities(host: SessionHost): Promise<SessionCapabilities> {\n if (typeof host.capabilities !== 'function') return UNSUPPORTED_CAPABILITIES\n try {\n const value = await unwrap(host.capabilities())\n if (typeof value !== 'object' || value === null) return UNSUPPORTED_CAPABILITIES\n const record = value as Partial<SessionCapabilities>\n return {\n retry: record.retry === true,\n freeSession: record.freeSession === true,\n deleteSession: record.deleteSession === true,\n }\n } catch {\n return UNSUPPORTED_CAPABILITIES\n }\n}\n\nexport function controlsFor(capabilities: SessionCapabilities, ready: boolean, host: SessionHost): {\n create: boolean\n delete: boolean\n retry: boolean\n} {\n return {\n create: ready && capabilities.freeSession && typeof host.create === 'function',\n delete: ready && capabilities.deleteSession && typeof host.deleteSession === 'function',\n retry: ready && capabilities.retry && typeof host.previewRetry === 'function' && typeof host.retry === 'function',\n }\n}\n\nfunction sessionIdOf(value: unknown): string {\n if (typeof value === 'string' && value !== '') return value\n if (typeof value === 'object' && value !== null && typeof (value as { sessionId?: unknown }).sessionId === 'string') {\n return (value as { sessionId: string }).sessionId\n }\n throw new HostOperationError('session/lifecycle-unavailable')\n}\n\n/** Pass only `{ kind: 'free' }`. A cwd or workspace is rejected by free create, and must not be invented. */\nexport async function createFreeSession(host: SessionHost): Promise<string> {\n if (typeof host.create !== 'function') throw new HostOperationError('session/lifecycle-unavailable')\n return sessionIdOf(await unwrap(host.create({ kind: 'free' })))\n}\n\nexport async function deleteOwnedSession(host: SessionHost, sessionId: string, requestId: string): Promise<DeleteOutcome> {\n if (typeof host.deleteSession !== 'function') throw new HostOperationError('session/lifecycle-unavailable')\n const value = await unwrap(host.deleteSession(sessionId, requestId))\n if (typeof value !== 'object' || value === null) throw new HostOperationError('session/delete-pending', 'missing-outcome')\n const phase = (value as { phase?: unknown }).phase\n if (phase !== 'deleted' && phase !== 'cleanup-pending') {\n throw new HostOperationError('session/delete-pending', 'missing-outcome')\n }\n return { phase }\n}\n\nexport function directRetryRequest(input: {\n sessionId: string\n messageId: string\n expectedRevision: number\n expectedInputRevision: string\n requestId: string\n}): DirectRetryRequest {\n return {\n sessionId: input.sessionId,\n messageId: input.messageId,\n expectedRevision: input.expectedRevision,\n expectedInputRevision: input.expectedInputRevision,\n requestId: input.requestId,\n }\n}\n\nexport function editRetryRequest(input: DirectRetryRequest & { text: string }): EditRetryRequest {\n return { ...directRetryRequest(input), text: input.text }\n}\n\nexport class SubmissionLedger {\n private active = false\n private unresolved: DirectRetryRequest | EditRetryRequest | undefined\n\n get busy(): boolean {\n return this.active\n }\n\n pending(): DirectRetryRequest | EditRetryRequest | undefined {\n return this.unresolved\n }\n\n /** Resend the stored body. A non-recoverable result drops it; a lost reply keeps it. */\n async replay(execute: (body: DirectRetryRequest | EditRetryRequest) => Promise<unknown>): Promise<void> {\n const body = this.unresolved\n if (body === undefined) return\n if (this.active) throw new HostOperationError('busy', 'running')\n this.active = true\n try {\n await execute(body)\n this.unresolved = undefined\n } catch (error) {\n const failure = readFailure(error)\n if (!isRecoverable(failure) && failure.reason !== 'aborted') this.unresolved = undefined\n throw error instanceof HostOperationError ? error : new HostOperationError(failure.code, failure.reason)\n } finally {\n this.active = false\n }\n }\n\n /** First submission of a body built from the current preview. */\n async submit(body: DirectRetryRequest | EditRetryRequest, execute: () => Promise<unknown>): Promise<void> {\n if (this.active || this.unresolved !== undefined) throw new HostOperationError('busy', 'running')\n this.active = true\n try {\n await execute()\n this.unresolved = undefined\n } catch (error) {\n const failure = readFailure(error)\n this.unresolved = isRecoverable(failure) ? body : undefined\n throw error instanceof HostOperationError ? error : new HostOperationError(failure.code, failure.reason)\n } finally {\n this.active = false\n }\n }\n}\n\ninterface Listener {\n (): void\n}\n\nfunction store() {\n const listeners = new Set<Listener>()\n return {\n subscribe(listener: Listener): () => void {\n listeners.add(listener)\n return () => { listeners.delete(listener) }\n },\n emit(): void {\n for (const listener of listeners) listener()\n },\n }\n}\n\nexport interface DeleteRequestState {\n readonly sessionId: string\n readonly title: string\n readonly classification: 'free' | 'ordinary'\n readonly requestId: string\n readonly busy: boolean\n readonly failure?: OperationFailure\n}\n\nexport interface FreeChatSnapshot {\n readonly controls: ReturnType<typeof controlsFor>\n readonly capabilitiesReady: boolean\n readonly creating: boolean\n readonly notice?: OperationFailure\n readonly deleteRequest?: DeleteRequestState\n}\n\nexport interface FreeChatModel {\n subscribe(listener: Listener): () => void\n getSnapshot(): FreeChatSnapshot\n reloadCapabilities(): Promise<void>\n create(): Promise<void>\n dismissNotice(): void\n requestDelete(sessionId: string): void\n cancelDelete(): void\n confirmDelete(): Promise<void>\n cancel(): void\n}\n\nexport function createFreeChatModel(host: SessionHost, ids: () => string = () => crypto.randomUUID()): FreeChatModel {\n const events = store()\n let capabilities = UNSUPPORTED_CAPABILITIES\n let capabilitiesReady = false\n let creating = false\n let notice: OperationFailure | undefined\n let deleteRequest: DeleteRequestState | undefined\n let generation = 0\n let snapshot: FreeChatSnapshot = build()\n\n function build(): FreeChatSnapshot {\n return {\n controls: controlsFor(capabilities, capabilitiesReady, host),\n capabilitiesReady,\n creating,\n ...notice === undefined ? {} : { notice },\n ...deleteRequest === undefined ? {} : { deleteRequest },\n }\n }\n\n function publish(): void {\n snapshot = build()\n events.emit()\n }\n\n return {\n subscribe: events.subscribe,\n getSnapshot: () => snapshot,\n async reloadCapabilities() {\n capabilities = await readCapabilities(host)\n capabilitiesReady = true\n publish()\n },\n async create() {\n if (!controlsFor(capabilities, capabilitiesReady, host).create || creating) return\n const ticket = generation\n creating = true\n notice = undefined\n publish()\n try {\n const id = await createFreeSession(host)\n if (ticket !== generation) return\n if (typeof host.openSession !== 'function') throw new HostOperationError('session/lifecycle-unavailable', 'open-session')\n host.openSession(id)\n } catch (error) {\n if (ticket !== generation) return\n notice = readFailure(error)\n } finally {\n if (ticket === generation) {\n creating = false\n publish()\n }\n }\n },\n dismissNotice() {\n if (notice === undefined) return\n notice = undefined\n publish()\n },\n requestDelete(sessionId) {\n if (!controlsFor(capabilities, capabilitiesReady, host).delete) return\n const row = host.list.getSnapshot().byId[sessionId]\n deleteRequest = {\n sessionId,\n title: row?.displayTitle ?? row?.title ?? sessionId,\n classification: row?.classification === 'free' ? 'free' : 'ordinary',\n requestId: ids(),\n busy: false,\n }\n publish()\n },\n cancelDelete() {\n if (deleteRequest?.busy) return\n deleteRequest = undefined\n publish()\n },\n async confirmDelete() {\n const current = deleteRequest\n if (current === undefined || current.busy) return\n const ticket = generation\n deleteRequest = { ...current, busy: true, failure: undefined }\n publish()\n try {\n const outcome = await deleteOwnedSession(host, current.sessionId, current.requestId)\n if (ticket !== generation) return\n if (outcome.phase !== 'deleted') {\n deleteRequest = {\n ...current,\n busy: false,\n failure: { code: 'session/delete-pending', reason: 'pending' },\n }\n publish()\n return\n }\n // The host clears the open selection itself; there is no panel to jump to.\n deleteRequest = undefined\n } catch (error) {\n if (ticket !== generation) return\n const failure = readFailure(error)\n deleteRequest = { ...current, busy: false, failure }\n }\n if (ticket === generation) publish()\n },\n cancel() {\n generation += 1\n creating = false\n notice = undefined\n deleteRequest = undefined\n publish()\n },\n }\n}\n\nexport interface RetrySnapshot {\n readonly controlsRetry: boolean\n readonly busy: boolean\n readonly editing: boolean\n readonly draft: string\n readonly sessionId: string\n readonly messageId: string\n readonly failure?: OperationFailure\n}\n\nexport interface RetryModel {\n subscribe(listener: Listener): () => void\n getSnapshot(): RetrySnapshot\n load(): Promise<void>\n retry(sessionId: string, messageId: string, signal: AbortSignal): Promise<void>\n beginEdit(sessionId: string, messageId: string, text: string, signal: AbortSignal): Promise<void>\n setDraft(text: string): void\n cancelEdit(): void\n sendEdit(sessionId: string, messageId: string, signal: AbortSignal): Promise<void>\n retire(sessionId: string, messageId: string): void\n cancel(): void\n}\n\nexport function createRetryModel(host: SessionHost, ids: () => string = () => crypto.randomUUID()): RetryModel {\n const events = store()\n const ledger = new SubmissionLedger()\n let capabilities = UNSUPPORTED_CAPABILITIES\n let ready = false\n let busy = false\n let editing = false\n let draft = ''\n let failure: OperationFailure | undefined\n let expectedRevision = 0\n let expectedInputRevision = ''\n let ownerSession = ''\n let ownerMessage = ''\n let call = 0\n let snapshot: RetrySnapshot = build()\n\n function build(): RetrySnapshot {\n return {\n controlsRetry: controlsFor(capabilities, ready, host).retry,\n busy,\n editing,\n draft,\n sessionId: ownerSession,\n messageId: ownerMessage,\n ...failure === undefined ? {} : { failure },\n }\n }\n\n function publish(): void {\n snapshot = build()\n events.emit()\n }\n\n function readPreview(value: unknown): RetryPreview {\n if (typeof value !== 'object' || value === null || typeof (value as { branchRevision?: unknown }).branchRevision !== 'number') {\n throw new HostOperationError('session/lifecycle-unavailable')\n }\n const record = value as { branchRevision: number; eligible?: boolean; reason?: string; inputRevision?: unknown }\n const inputRevision = typeof record.inputRevision === 'string' ? record.inputRevision : ''\n const eligible = record.eligible === true\n if (eligible && inputRevision === '') throw new HostOperationError('session/lifecycle-unavailable', 'input-revision')\n return {\n branchRevision: record.branchRevision,\n inputRevision,\n eligible,\n ...typeof record.reason === 'string' ? { reason: record.reason } : {},\n }\n }\n\n async function preview(sessionId: string, id: string, signal: AbortSignal, ticket: number): Promise<RetryPreview | undefined> {\n if (ticket !== call || signal.aborted) return undefined\n if (typeof host.previewRetry !== 'function') throw new HostOperationError('session/lifecycle-unavailable')\n const value = await unwrap(host.previewRetry({ sessionId, messageId: id }))\n if (ticket !== call || signal.aborted) return undefined\n return readPreview(value)\n }\n\n async function callRetry(body: DirectRetryRequest | EditRetryRequest, signal: AbortSignal, ticket: number): Promise<void> {\n if (signal.aborted || ticket !== call) throw new HostOperationError('busy', 'aborted')\n if (typeof host.retry !== 'function') throw new HostOperationError('session/lifecycle-unavailable')\n await unwrap(host.retry(body))\n }\n\n function settle(): void {\n if (!ledger.busy) busy = false\n publish()\n }\n\n async function replaySame(signal: AbortSignal): Promise<void> {\n if (signal.aborted) return\n const pending = ledger.pending()\n const ticket = ++call\n busy = true\n failure = undefined\n publish()\n try {\n await ledger.replay(async body => { await callRetry(body, signal, ticket) })\n if (\n pending !== undefined\n && ticket === call\n && !signal.aborted\n && ownerSession === pending.sessionId\n && ownerMessage === pending.messageId\n ) editing = false\n } catch (error) {\n if (ticket === call && !signal.aborted) failure = readFailure(error)\n } finally {\n settle()\n }\n }\n\n function samePending(sessionId: string, id: string): boolean {\n const pending = ledger.pending()\n return pending !== undefined && pending.sessionId === sessionId && pending.messageId === id\n }\n\n return {\n subscribe: events.subscribe,\n getSnapshot: () => snapshot,\n async load() {\n capabilities = await readCapabilities(host)\n ready = true\n publish()\n },\n async retry(sessionId, id, signal) {\n if (busy || !controlsFor(capabilities, ready, host).retry || signal.aborted) return\n if (ledger.pending() !== undefined) {\n if (!samePending(sessionId, id)) return\n await replaySame(signal)\n return\n }\n const ticket = ++call\n busy = true\n failure = undefined\n editing = false\n ownerSession = sessionId\n ownerMessage = id\n publish()\n try {\n const seen = await preview(sessionId, id, signal, ticket)\n if (seen === undefined) return\n if (!seen.eligible) {\n failure = { code: 'session/retry-blocked', reason: seen.reason ?? 'unknown' }\n return\n }\n if (signal.aborted || ticket !== call) return\n expectedRevision = seen.branchRevision\n expectedInputRevision = seen.inputRevision\n const body = directRetryRequest({\n sessionId,\n messageId: id,\n expectedRevision: seen.branchRevision,\n expectedInputRevision: seen.inputRevision,\n requestId: ids(),\n })\n await ledger.submit(body, () => callRetry(body, signal, ticket))\n } catch (error) {\n if (ticket === call && !signal.aborted) failure = readFailure(error)\n } finally {\n settle()\n }\n },\n async beginEdit(sessionId, id, text, signal) {\n if (busy || !controlsFor(capabilities, ready, host).retry || signal.aborted) return\n if (ledger.pending() !== undefined) {\n if (!samePending(sessionId, id)) return\n await replaySame(signal)\n return\n }\n const ticket = ++call\n busy = true\n failure = undefined\n ownerSession = sessionId\n ownerMessage = id\n publish()\n try {\n const seen = await preview(sessionId, id, signal, ticket)\n if (seen === undefined) return\n if (!seen.eligible) {\n failure = { code: 'session/retry-blocked', reason: seen.reason ?? 'unknown' }\n return\n }\n if (signal.aborted || ticket !== call) return\n expectedRevision = seen.branchRevision\n expectedInputRevision = seen.inputRevision\n draft = text\n editing = true\n } catch (error) {\n if (ticket === call && !signal.aborted) failure = readFailure(error)\n } finally {\n settle()\n }\n },\n setDraft(text) {\n if (!editing || ownerSession === '' || ownerMessage === '') return\n draft = text\n publish()\n },\n cancelEdit() {\n if (busy) return\n editing = false\n publish()\n },\n async sendEdit(sessionId, id, signal) {\n if (signal.aborted || busy || !controlsFor(capabilities, ready, host).retry) return\n if (!editing || ownerSession !== sessionId || ownerMessage !== id) return\n if (ledger.pending() !== undefined) {\n if (!samePending(sessionId, id)) return\n await replaySame(signal)\n return\n }\n const ticket = ++call\n busy = true\n failure = undefined\n const text = draft\n publish()\n try {\n if (signal.aborted || ticket !== call) return\n const body = editRetryRequest({\n sessionId,\n messageId: id,\n expectedRevision,\n expectedInputRevision,\n requestId: ids(),\n text,\n })\n await ledger.submit(body, () => callRetry(body, signal, ticket))\n if (ticket === call && !signal.aborted) editing = false\n } catch (error) {\n if (ticket === call && !signal.aborted) failure = readFailure(error)\n } finally {\n settle()\n }\n },\n retire(sessionId, messageId) {\n if (ownerSession !== sessionId || ownerMessage !== messageId) return\n call += 1\n editing = false\n failure = undefined\n draft = ''\n if (!ledger.busy) busy = false\n publish()\n },\n cancel() {\n call += 1\n editing = false\n failure = undefined\n if (!ledger.busy) busy = false\n publish()\n },\n }\n}\n\nexport function bindHost(ctx: {\n sessions?: {\n list?: ObservableList\n capabilities?: SessionHost['capabilities']\n create?: (opts?: { workspaceId?: string; cwd?: string; sessionId?: string }) => Promise<unknown>\n previewRetry?: SessionHost['previewRetry']\n retry?: SessionHost['retry']\n }\n uiWorkspace?: {\n openSession?: SessionHost['openSession']\n deleteSession?: SessionHost['deleteSession']\n }\n}): SessionHost {\n const sessions = ctx.sessions\n const workspace = ctx.uiWorkspace\n const empty: ObservableList = {\n getSnapshot: () => ({ ids: [], byId: {}, phase: 'ready' }),\n subscribe: () => () => {},\n }\n return {\n list: sessions?.list ?? empty,\n ...typeof sessions?.capabilities === 'function' ? { capabilities: () => sessions.capabilities!() } : {},\n ...typeof sessions?.create === 'function'\n ? { create: (opts: { kind: 'free' }) => (sessions.create as (input: { kind: 'free' }) => Promise<unknown>)(opts) }\n : {},\n ...typeof sessions?.previewRetry === 'function' ? { previewRetry: request => sessions.previewRetry!(request) } : {},\n ...typeof sessions?.retry === 'function' ? { retry: request => sessions.retry!(request) } : {},\n ...typeof workspace?.openSession === 'function' ? { openSession: sessionId => workspace.openSession!(sessionId) } : {},\n ...typeof workspace?.deleteSession === 'function' ? { deleteSession: (sessionId, requestId) => workspace.deleteSession!(sessionId, requestId) } : {},\n }\n}\n","import { useEffect, useRef, useSyncExternalStore } from 'react'\nimport { Button, Modal, Tooltip } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { RetryModel } from './session-actions.ts'\nimport { FREE_CHAT_ROOT } from './styles.ts'\nimport { failureText, uiText, type CopyLocale } from './ui-copy.ts'\n\nexport function UserMessageActions(props: {\n messageId: string\n text: string\n sessionId: string\n locale: CopyLocale\n model: RetryModel\n}): React.ReactElement | null {\n const snapshot = useSyncExternalStore(props.model.subscribe, props.model.getSnapshot, props.model.getSnapshot)\n const signal = useRef<AbortController>(new AbortController())\n useEffect(() => {\n const controller = new AbortController()\n signal.current = controller\n return () => {\n controller.abort()\n props.model.retire(props.sessionId, props.messageId)\n }\n }, [props.model, props.sessionId, props.messageId])\n if (props.sessionId === '' || !snapshot.controlsRetry) return null\n const mine = snapshot.sessionId === props.sessionId && snapshot.messageId === props.messageId\n const copy = (key: Parameters<typeof uiText>[1]) => uiText(props.locale, key)\n const failure = mine ? snapshot.failure : undefined\n const editing = mine && snapshot.editing\n const draft = mine ? snapshot.draft : props.text\n return (\n <span className={`${FREE_CHAT_ROOT} dsh-free-actions`}>\n <Tooltip label={copy('retry')} side=\"bottom\">\n <Button\n size=\"sm\"\n variant=\"ghost\"\n aria-label={copy('retry')}\n disabled={snapshot.busy}\n onClick={() => { void props.model.retry(props.sessionId, props.messageId, signal.current.signal) }}\n >\n {copy('retry')}\n </Button>\n </Tooltip>\n <Tooltip label={copy('edit')} side=\"bottom\">\n <Button\n size=\"sm\"\n variant=\"ghost\"\n aria-label={copy('edit')}\n disabled={snapshot.busy}\n onClick={() => { void props.model.beginEdit(props.sessionId, props.messageId, props.text, signal.current.signal) }}\n >\n {copy('edit')}\n </Button>\n </Tooltip>\n {failure ? <span className=\"dsh-ui-error dsh-free-alert\" role=\"alert\">{failureText(props.locale, failure)}</span> : null}\n <Modal\n open={editing}\n className={FREE_CHAT_ROOT}\n title={copy('editTitle')}\n closeLabel={copy('close')}\n onClose={() => { props.model.cancelEdit() }}\n footer={(\n <>\n <Button variant=\"ghost\" disabled={snapshot.busy} onClick={() => { props.model.cancelEdit() }}>{copy('cancel')}</Button>\n <Button\n variant=\"primary\"\n data-modal-autofocus\n disabled={snapshot.busy}\n onClick={() => { void props.model.sendEdit(props.sessionId, props.messageId, signal.current.signal) }}\n >\n {copy('send')}\n </Button>\n </>\n )}\n >\n <textarea\n className=\"dsh-free-draft\"\n aria-label={copy('draft')}\n value={draft}\n onChange={event => { props.model.setDraft(event.target.value) }}\n />\n </Modal>\n </span>\n )\n}\n","import type { Context } from '@deepseek-ai/cordis'\nimport { MenuItemButton } from '@deepseek-ai/dsh-client-ui-primitives'\nimport { useState, useSyncExternalStore, type ComponentProps } from 'react'\nimport { CopyThreadShortcutNotice, writeClipboard, type HostShortcuts } from './copy-shortcut.tsx'\nimport {\n COPY_THREAD_FAILED,\n COPY_THREAD_LABEL,\n copyLocale,\n copyThreadId,\n type CopyLocale,\n} from './copy-action.ts'\nimport {\n COPY_THREAD_MENU_ID,\n COPY_THREAD_MENU_ORDER,\n COPY_THREAD_SHORTCUT_ID,\n DELETE_DIALOG_ID,\n USER_ACTIONS_ID,\n USER_ACTIONS_SLOT,\n} from './contracts.ts'\nimport { installContextMenuForwarding } from './context-menu.ts'\nimport { CreateNoticeDialog, DeleteChatDialog } from './free-panel.tsx'\nimport { installTemporaryWorkspacePicker, TemporaryWorkspaceNotice, type PickerRegistry } from './temporary-picker.tsx'\nimport { bindTemporaryWorkspaceHost, createTemporaryWorkspaceModel } from './temporary-workspace.ts'\nimport { bindHost, createFreeChatModel, createRetryModel, type FreeChatModel, type RetryModel } from './session-actions.ts'\nimport { freeChatCss } from './styles.ts'\nimport { UserMessageActions } from './user-actions.tsx'\nimport { uiText } from './ui-copy.ts'\n\nexport const name = 'dsh-session-manager-client'\nexport const inject = ['slots', 'locale', 'sessions', 'uiWorkspace', 'shortcuts', 'connection', 'workspaces', 'layout'] as const\n\ninterface LocaleService {\n getSnapshot(): { active: string }\n subscribe(listener: () => void): () => void\n register?(namespace: string, dictionaries: { zh: Record<string, string>; en: Record<string, string> }): (() => void) | void\n}\n\ninterface MenuProps {\n sessionId: string\n useMenuOpenState: () => [boolean, (open: boolean) => void]\n}\n\ninterface SlotRegistry {\n inject(key: string, callback: () => (() => void) | void): () => void\n register(spec: Record<string, unknown>, render: (props: never) => unknown): () => void\n}\n\ntype Client = Context & {\n slots: SlotRegistry\n locale?: LocaleService\n sessions?: Parameters<typeof bindHost>[0]['sessions']\n uiWorkspace?: Parameters<typeof bindHost>[0]['uiWorkspace']\n shortcuts?: HostShortcuts\n on?(name: string, listener: () => void): () => void\n}\n\nexport function CopyThreadMenuItem(props: MenuProps & {\n locale: CopyLocale\n writeText?: (value: string) => Promise<void>\n shortcut?: ComponentProps<typeof MenuItemButton>['shortcut']\n}) {\n const [failed, setFailed] = useState(false)\n const [, setMenuOpen] = props.useMenuOpenState()\n const label = failed ? COPY_THREAD_FAILED[props.locale] : COPY_THREAD_LABEL[props.locale]\n const onSelect = () => copyThreadId(props.sessionId, props.writeText ?? writeClipboard).then(() => {\n setFailed(false)\n setMenuOpen(false)\n }, () => {\n setFailed(true)\n })\n // MenuItemButton activates through the button click. A keydown wrapper here\n // would run before ui-primitives Menu.tsx applies its composition, modifier,\n // and repeat guards (packages/client/ui-primitives/src/Menu.tsx).\n return (\n <MenuItemButton separatorBefore shortcut={props.shortcut} onSelect={onSelect}>\n {label}\n </MenuItemButton>\n )\n}\n\n\nexport function apply(ctx: Context): void {\n const client = ctx as Client\n const host = bindHost(client)\n const chats = createFreeChatModel(host)\n const retries = createRetryModel(host)\n const temporaryHost = bindTemporaryWorkspaceHost(client as unknown as Parameters<typeof bindTemporaryWorkspaceHost>[0])\n const temporary = createTemporaryWorkspaceModel(temporaryHost, undefined,\n () => uiText(copyLocale(client.locale?.getSnapshot().active), 'tempWorkspace'))\n const currentLocale = () => client.locale?.getSnapshot().active\n client.effect(() => {\n const stops: Array<() => void> = []\n // The relay needs no host slot and no service; a non-browser host simply skips it.\n if (typeof document !== 'undefined') stops.push(installContextMenuForwarding(document))\n stops.push(client.slots.inject('sidebar.workspaces.session.menu.item', () => (\n client.slots.register({\n name: 'sidebar.workspaces.session.menu.item',\n id: COPY_THREAD_MENU_ID,\n order: COPY_THREAD_MENU_ORDER,\n }, props => <CopyThreadSlot locale={client.locale} shortcuts={client.shortcuts} {...props as MenuProps} />)\n )))\n stops.push(client.slots.inject('sidebar.workspaces.session.menu.item', () => (\n client.slots.register({\n name: 'sidebar.workspaces.session.menu.item',\n id: DELETE_DIALOG_ID,\n order: COPY_THREAD_MENU_ORDER + 10,\n }, props => <DeleteMenuItem locale={client.locale} model={chats} {...props as MenuProps} />)\n )))\n stops.push(installTemporaryWorkspacePicker(client.slots as unknown as PickerRegistry, temporary,\n temporaryHost.createWorkspace, client.locale))\n stops.push(client.slots.inject(USER_ACTIONS_SLOT, () => (\n client.slots.register({\n name: USER_ACTIONS_SLOT,\n id: USER_ACTIONS_ID,\n order: 10,\n inject: (sessionId: string) => ({ sessionId }),\n }, props => (\n <UserMessageActions\n messageId={(props as { messageId: string }).messageId}\n text={(props as { text: string }).text}\n sessionId={(props as { sessionId?: string }).sessionId ?? ''}\n locale={useLiveLocale(client.locale)}\n model={retries}\n />\n ))\n )))\n stops.push(client.slots.inject('shell.overlay', () => (\n client.slots.register({\n name: 'shell.overlay',\n id: DELETE_DIALOG_ID,\n order: 40,\n }, () => {\n const locale = useLiveLocale(client.locale)\n return (\n <>\n <style>{freeChatCss}</style>\n <CopyThreadShortcutNotice shortcuts={client.shortcuts} list={client.sessions?.list} locale={locale} currentLocale={currentLocale} />\n <TemporaryWorkspaceNotice model={temporary} locale={locale} />\n <DeleteChatDialog model={chats} locale={locale} />\n <CreateNoticeDialog model={chats} locale={locale} />\n </>\n )\n })\n )))\n const reset = client.on?.('connection/reset', () => {\n void chats.reloadCapabilities()\n void retries.load()\n })\n if (typeof reset === 'function') stops.push(reset)\n void chats.reloadCapabilities()\n void retries.load()\n return () => {\n chats.cancel()\n retries.cancel()\n temporary.cancel()\n for (const stop of stops) stop()\n }\n })\n}\n\nconst EMPTY_SHORTCUTS: ReturnType<HostShortcuts['catalog']['getSnapshot']> = []\n\nfunction CopyThreadSlot(props: MenuProps & { locale?: LocaleService; shortcuts?: HostShortcuts }) {\n const locale = useLiveLocale(props.locale)\n const shortcuts = useSyncExternalStore(\n listener => props.shortcuts?.catalog.subscribe(listener) ?? (() => {}),\n () => props.shortcuts?.catalog.getSnapshot() ?? EMPTY_SHORTCUTS,\n () => EMPTY_SHORTCUTS,\n )\n return <CopyThreadMenuItem sessionId={props.sessionId} useMenuOpenState={props.useMenuOpenState} locale={locale}\n shortcut={shortcuts.find(row => row.id === COPY_THREAD_SHORTCUT_ID)} />\n}\n\nfunction DeleteMenuItem(props: MenuProps & { locale?: LocaleService; model: FreeChatModel }): React.ReactElement | null {\n const locale = useLiveLocale(props.locale)\n const snapshot = useSyncExternalStore(props.model.subscribe, props.model.getSnapshot, props.model.getSnapshot)\n const [, setMenuOpen] = props.useMenuOpenState()\n if (!snapshot.controls.delete) return null\n return (\n <MenuItemButton onSelect={() => {\n props.model.requestDelete(props.sessionId)\n setMenuOpen(false)\n }}>\n {uiText(locale, 'deleteChat')}\n </MenuItemButton>\n )\n}\n\nfunction useLiveLocale(locale: LocaleService | undefined): CopyLocale {\n const active = useSyncExternalStore(\n listener => locale?.subscribe(listener) ?? (() => {}),\n () => locale?.getSnapshot().active ?? 'en',\n () => locale?.getSnapshot().active ?? 'en',\n )\n return copyLocale(active)\n}\n\nexport type { FreeChatModel, RetryModel }\n"],"mappings":"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"}
|