dsh-hypatia-auto-memory 1.1.0 → 2.0.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 +54 -15
- package/README.zh-CN.md +40 -13
- package/lib/client.js +289 -10
- package/lib/client.js.map +1 -1
- package/package.json +6 -1
- package/src/cascade.js +39 -19
- package/src/client/SettingsCard.module.css +83 -0
- package/src/client/SettingsCard.tsx +160 -15
- package/src/client/consolidation-models.ts +151 -1
- package/src/client/locales.ts +26 -4
- package/src/config.js +20 -3
- package/src/consolidator.js +130 -86
- package/src/index.js +14 -6
- package/src/model-log.js +64 -15
- package/src/reasoning.js +209 -0
- package/src/recall.js +14 -3
- package/src/writer.js +7 -3
package/lib/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","names":["useState","useMemo","useRef","useCallback","css","Input","Button","css","MarkdownText","useState","useMemo","useRef","useCallback","createElement"],"sources":["../src/client/consolidation-models.ts","../src/client/shelves.ts","../src/client/locales.ts","../src/client/SettingsCard.tsx","../src/client/memory-client.ts","../src/client/MemoryView.tsx","../src/client/plugin-card-seat.ts","../src/client/index.tsx"],"sourcesContent":["/** Model-directory projection shared by the consolidation settings card. */\n\nimport type { ModelProviderGroup } from '@deepseek-ai/dsh-api-remotes/client'\n\n/** One exact provider/model route used for a consolidation attempt. */\nexport interface ConsolidationModelRoute {\n provider: string\n model: string\n}\n\n/** One catalog route, including stored routes no longer advertised by an adapter. */\nexport interface ConsolidationModelCandidate extends ConsolidationModelRoute {\n key: string\n providerName: string\n modelName: string\n available: boolean\n selected: boolean\n}\n\n/** One catalog response retained by the settings card. */\nexport interface ConsolidationModelCatalog {\n groups: readonly ModelProviderGroup[]\n partial: boolean\n}\n\n/** Load the current Host model directory for the settings card. */\nexport type LoadConsolidationModelCatalog = () => Promise<ConsolidationModelCatalog>\n\n/** Stable opaque key for one exact route. */\nexport function consolidationModelKey(route: ConsolidationModelRoute): string {\n return `${route.provider}\\0${route.model}`\n}\n\n/**\n * Join the live model directory with selected routes that disappeared from it.\n * Disappeared routes remain visible so users can remove them deliberately.\n */\nexport function consolidationModelCandidates(\n groups: readonly ModelProviderGroup[],\n stored: readonly ConsolidationModelRoute[],\n selected: ReadonlySet<string>,\n): ConsolidationModelCandidate[] {\n const storedByKey = new Map(stored.map(route => [consolidationModelKey(route), route]))\n const candidates = groups.flatMap(group => group.models.map((model): ConsolidationModelCandidate => {\n const route = { provider: group.id, model: model.id }\n const key = consolidationModelKey(route)\n storedByKey.delete(key)\n return {\n ...route,\n key,\n providerName: group.name,\n modelName: model.name,\n available: true,\n selected: selected.has(key),\n }\n }))\n for (const route of storedByKey.values()) {\n const key = consolidationModelKey(route)\n candidates.push({\n ...route,\n key,\n providerName: route.provider,\n modelName: route.model,\n available: false,\n selected: selected.has(key),\n })\n }\n return candidates\n}\n","/**\n * Shelf choices for the settings card.\n *\n * The Host serves `hypatia list` from the Memory tab's route family\n * (`GET /api/dsh-hypatia-auto-memory/shelves`, see `src/memory-api.js`); the\n * fetch itself lives in `memory-client.ts`. Until dsh 0.1.7 this listing rode\n * a read-only settings namespace, which the settings overhaul removed.\n *\n * Zero runtime imports, so the parsing half is unit-tested under `node:test`.\n */\n\n/** Shelf hypatia uses when none is named. */\nexport const DEFAULT_SHELF = 'default'\n\n/** One shelf as `hypatia list` reports it. */\nexport interface ShelfInfo {\n name: string\n path: string\n connected: boolean\n}\n\n/** The Host's latest listing; `error` is non-empty when it could not list. */\nexport interface ShelfInventory {\n shelves: ShelfInfo[]\n error: string\n}\n\n/** Load the Host's latest listing for the settings card. */\nexport type LoadShelfInventory = () => Promise<ShelfInventory>\n\n/** One dropdown option. */\nexport interface ShelfChoice {\n name: string\n path: string\n /** False for a shelf that is registered but not connected. */\n connected: boolean\n /** False for a stored value the listing no longer reports. */\n listed: boolean\n}\n\n/**\n * Every shelf the dropdown offers: the listing, plus the stored and composed\n * values when the listing does not carry them, so the current choice always\n * renders and never silently changes to the first option.\n * @param shelves - the Host's listing.\n * @param keep - values that must stay selectable (current draft, stored, composed).\n * @returns options, listed shelves first in listing order.\n */\nexport function shelfChoices(shelves: readonly ShelfInfo[], keep: readonly string[]): ShelfChoice[] {\n const choices: ShelfChoice[] = shelves.map(shelf => ({ ...shelf, listed: true }))\n for (const name of keep) {\n if (name === '' || choices.some(choice => choice.name === name)) continue\n choices.push({ name, path: '', connected: false, listed: false })\n }\n return choices\n}\n","/** `hypatia-auto-memory` namespace dictionaries. */\n\n/** Dictionary namespace owned by this plugin. */\nexport const NS = 'hypatia-auto-memory'\n\n/** Simplified Chinese dictionary and key source of truth. */\nexport const zh = {\n loading: '正在加载 {ns} 设置…',\n unavailable: '当前上下文不可用 {ns} 设置。',\n title: 'Hypatia Auto Memory',\n description:\n '自动将对话轮次记录到 Hypatia,并在新内容足够多时通过独立模型路由进行后台整合。',\n enable: '启用自动记忆',\n autoApprove: '自动批准模型发起的 hypatia 命令',\n autoApproveHint: '仅限不含管道、重定向、命令串联的纯 hypatia 调用;插件自身的写入不经过此路径。关闭后模型每次检索都会弹出批准框。保存后采集器会自动重启以应用新值。',\n shelf: '记忆写入的 shelf',\n shelfHint: '插件的记录、整合与会话开始时的规则预加载都读写这个 shelf;不是 default 时,会话开头会提示模型为 hypatia 命令加上 --shelf。保存后采集器会自动重启,改写到新的 shelf。每个 shelf 的记录进度单独保存,切回原来的 shelf 会从上次的位置继续;切到新的 shelf 后,每个有活动的会话会把完整历史重新记录进去并整合一遍(会消耗模型调用)。列表来自 hypatia list,打开本页时按需读取。',\n shelfLoading: '正在读取 hypatia list…',\n shelfLoadFailed: '无法读取 shelf 列表。',\n shelfListingFailed: 'hypatia list 执行失败,列表可能已过时:{message}',\n shelfDisconnected: '未连接',\n shelfOptionStatus: '({status})',\n shelfNotListed: '不在 hypatia list 中',\n shelfDisconnectedWarning: 'shelf {shelf} 已注册但未连接,写入会失败。',\n shelfNotListedWarning: 'hypatia 没有注册 shelf {shelf},写入会失败;请先执行 hypatia connect <目录> --name {shelf}。',\n consolidationTitle: '整合候选模型',\n modelSelectionHint: '选择一个或多个模型。每次整合尝试(含重试)会按所选顺序轮转;未选择时只记录对话,不执行整合。',\n modelCatalogLoading: '正在读取可用模型…',\n modelCatalogFailed: '无法读取可用模型。',\n modelCatalogPartial: '部分提供方未能返回模型目录。',\n modelCatalogEmpty: '当前没有可选择的模型。',\n selectedModels: '用于轮转的模型',\n unavailableModels: '不可用或未再声明的模型',\n modelUnavailable: '当前不可用',\n retry: '重试',\n checkEveryTurns: '两次整合至少间隔 N 轮',\n minNewTokens: '最小新增 token 数',\n cascadeBatchSize: '归档批量',\n dedupMaxDistance: '关联距离上限',\n cascadeHint: '每积累这么多同层摘要,就归档为上一层的一条;关联距离上限决定新记忆要多接近既有条目才值得判定关系。',\n limitsTitle: '单次整合体量',\n limitsHint: '输入预算决定送入模型的对话长度(超出部分截断保留最近内容);输出预算需容纳摘要与全部工作单元,过小会导致整合失败。',\n maxInputTokens: '输入预算(token)',\n maxOutputTokens: '输出预算(token)',\n maxWorkUnitsPerRun: '每次最多提取工作单元数',\n recallPreload: '召回:会话开始时预加载规则与禁忌',\n advancedHint:\n '高级字段(二进制、收集器上限、队列调优)可在「设置 → 插件」的本插件页,或 profile patch 的 {ns} 条目 config 下编辑。',\n reset: '重置',\n discard: '放弃',\n save: '保存',\n saving: '保存中…',\n saveFailed: '保存失败:{message}',\n readOnly: '只读:当前上下文不可写入设置文档。',\n unsaved: '未保存',\n viewMemory: '记忆',\n memoryTitle: '本会话的记忆',\n memoryUpdatedAt: '状态更新于 {time}',\n memoryRefresh: '刷新',\n memoryLoading: '正在读取记忆状态…',\n memoryNoSnapshot: '插件还没有发布记忆状态。启用后完成一轮对话再回来看看。',\n memoryLoadFailed: '无法读取记忆状态:{message}',\n memoryUnknown: '这个会话还没有记忆记录。第一轮对话结束后会开始记录。',\n memoryLogged: '对话记录',\n memorySeqValue: '第 {seq} 条事件',\n memoryConsolidated: '摘要整合',\n memoryCaughtUp: '已结清',\n memoryBehind: '较记录落后 {behind} 条',\n memoryPending: '待整合内容',\n memoryPendingValue: '约 {tokens} token',\n memorySessionNode: '会话节点',\n memorySessionNodeYes: '已建立',\n memorySessionNodeNo: '未建立(宿主未提供会话摘要)',\n memoryBelongTo: '已链接消息',\n memoryBelongToValue: '{count} 条',\n memoryDeferred: '等待会话载入的任务',\n memoryFailedTitle: '失败任务',\n memoryFailedItem: '{kind} 连续失败 {attempts} 次',\n memoryContentTitle: '记忆内容',\n memoryContentFailed: '无法读取 shelf 中的记忆内容:{message}',\n memorySummariesTitle: '跨度摘要',\n memoryWorkUnitsTitle: '工作单元',\n memoryNoSummaries: '这个会话还没有产生摘要。整合运行后会出现在这里。',\n memoryNoWorkUnits: '这个会话还没有提炼出工作单元。',\n memoryCount: '显示 {shown} / 共 {total}',\n memoryTier: '{level} 级',\n memoryWorkUnit: '工作单元',\n memoryEntryExpand: '展开',\n memoryEntryCollapse: '收起',\n memoryEntryEmpty: '这条条目的正文为空,或已超过展示上限。',\n memoryCopyCode: '复制',\n memoryCopiedCode: '已复制',\n memoryFootnotes: '脚注',\n memoryTruncated: '内容超出展示上限,较早的条目或过长的正文已被截断。',\n memoryHint: '诊断视图:原始 msg-* 对话正文不在此显示,需要时让 Agent 通过 hypatia 检索。状态每 5 秒重读一次;「状态更新于」是宿主最近一次看到这些状态发生变化的时间(首次读取也算一次),不变说明这段时间没有新进展。两个条数都按会话日志的事件序号计(含工具调用,不是消息条数),所以它们之差就是还没总结的部分。',\n} as const satisfies Record<string, string>\n\n/** Key domain of the `hypatia-auto-memory` namespace. */\nexport type AutoMemoryLocaleKey = keyof typeof zh\n\n/** English dictionary checked against the Chinese key set. */\nexport const en = {\n loading: 'Loading {ns} settings…',\n unavailable: '{ns} settings are not available in this context.',\n title: 'Hypatia Auto Memory',\n description:\n 'Auto-memory logs conversation turns into Hypatia and runs background consolidation on a dedicated model route.',\n enable: 'Enable auto-memory',\n autoApprove: \"Auto-approve the agent's own hypatia commands\",\n autoApproveHint: 'Only plain hypatia calls with no pipe, redirect or chaining; this plugin\\'s own writes never take that path. With it off, every retrieval raises an approval prompt. Saving a change restarts the collector to apply it.',\n shelf: 'Memory shelf',\n shelfHint: 'Logging, consolidation and the session-start rules preload all read and write this shelf; when it is not default, each session is told to pass --shelf to its hypatia commands. Saving a change restarts the collector on the new shelf. Progress is kept per shelf, so switching back resumes where that shelf left off; on a new shelf, each session is logged from its start the next time it is active, and consolidated again (model calls). Choices come from hypatia list, read on demand when this page opens.',\n shelfLoading: 'Reading hypatia list…',\n shelfLoadFailed: 'Unable to load the shelf list.',\n shelfListingFailed: 'hypatia list failed; the list may be stale: {message}',\n shelfDisconnected: 'not connected',\n shelfOptionStatus: ' ({status})',\n shelfNotListed: 'not in hypatia list',\n shelfDisconnectedWarning: 'Shelf {shelf} is registered but not connected; writes will fail.',\n shelfNotListedWarning: 'hypatia has no shelf named {shelf}; writes will fail until you run hypatia connect <dir> --name {shelf}.',\n consolidationTitle: 'Consolidation candidate models',\n modelSelectionHint: 'Choose one or more models. Every consolidation attempt, including a retry, rotates through this order; without a selection, conversations continue logging but consolidation stays idle.',\n modelCatalogLoading: 'Loading available models…',\n modelCatalogFailed: 'Unable to load available models.',\n modelCatalogPartial: 'Some providers did not return a model catalog.',\n modelCatalogEmpty: 'No models are currently available.',\n selectedModels: 'Models used for rotation',\n unavailableModels: 'Unavailable or no longer advertised',\n modelUnavailable: 'Unavailable',\n retry: 'Retry',\n checkEveryTurns: 'Minimum turns between consolidations',\n minNewTokens: 'Min new tokens',\n cascadeBatchSize: 'Archive batch',\n dedupMaxDistance: 'Relation distance',\n cascadeHint: 'Every batch of same-tier summaries is archived into one entry a tier up. Relation distance is how near a new memory must be to an existing one to be worth judging a relationship.',\n limitsTitle: 'Per-run consolidation size',\n limitsHint: 'The input budget caps how much conversation is sent to the model (overflow keeps the most recent content); the output budget must fit the summary plus every work unit — too small and consolidation fails.',\n maxInputTokens: 'Input budget (tokens)',\n maxOutputTokens: 'Output budget (tokens)',\n maxWorkUnitsPerRun: 'Max work units per run',\n recallPreload: 'Recall: preload rules & taboos at session start',\n advancedHint:\n 'Advanced fields (binaries, collector caps, queue tuning) can be edited in Settings → Plugins under this plugin, or under the {ns} entry\\'s config in the profile patch.',\n reset: 'Reset',\n discard: 'Discard',\n save: 'Save',\n saving: 'Saving…',\n saveFailed: 'Save failed: {message}',\n readOnly: 'Read-only: settings document is not writable in this context.',\n unsaved: 'Unsaved',\n viewMemory: 'Memory',\n memoryTitle: 'This session\\'s memory',\n memoryUpdatedAt: 'State updated {time}',\n memoryRefresh: 'Refresh',\n memoryLoading: 'Reading memory status…',\n memoryNoSnapshot: 'The plugin has not published a status snapshot yet. Enable it, finish a turn, and come back.',\n memoryLoadFailed: 'Unable to read memory status: {message}',\n memoryUnknown: 'This session has no memory record yet. Logging starts once the first turn ends.',\n memoryLogged: 'Conversation log',\n memorySeqValue: 'event {seq}',\n memoryConsolidated: 'Summarisation',\n memoryCaughtUp: 'caught up',\n memoryBehind: '{behind} events behind the log',\n memoryPending: 'Waiting to summarise',\n memoryPendingValue: '~{tokens} tokens',\n memorySessionNode: 'Session node',\n memorySessionNodeYes: 'created',\n memorySessionNodeNo: 'not created (the Host supplied no session summary)',\n memoryBelongTo: 'Linked messages',\n memoryBelongToValue: '{count}',\n memoryDeferred: 'Tasks waiting for the session to load',\n memoryFailedTitle: 'Failed tasks',\n memoryFailedItem: '{kind} failed {attempts} times',\n memoryContentTitle: 'Memory content',\n memoryContentFailed: 'Unable to read memory content from the shelf: {message}',\n memorySummariesTitle: 'Span summaries',\n memoryWorkUnitsTitle: 'Work units',\n memoryNoSummaries: 'This session has produced no summary yet. They appear here once consolidation runs.',\n memoryNoWorkUnits: 'This session has yielded no work units yet.',\n memoryCount: 'showing {shown} of {total}',\n memoryTier: 'tier {level}',\n memoryWorkUnit: 'work unit',\n memoryEntryExpand: 'Expand',\n memoryEntryCollapse: 'Collapse',\n memoryEntryEmpty: 'This entry has no body, or it exceeded the display cap.',\n memoryCopyCode: 'Copy',\n memoryCopiedCode: 'Copied',\n memoryFootnotes: 'Footnotes',\n memoryTruncated: 'Content exceeded the display cap: earlier entries or over-long bodies were cut.',\n memoryHint: 'Diagnostic view: raw msg-* conversation text is not shown here — ask the agent to retrieve it through hypatia. Status is re-read every 5 seconds; the timestamp is when the Host last saw that state change (the first read counts as one), so an unchanged one means nothing new happened. Both counts index the session log\\'s event sequence (tool calls included, not messages), so their difference is what is left to summarise.',\n} satisfies Record<AutoMemoryLocaleKey, string>\n","/**\n * Configuration card for the `hypatia-auto-memory` namespace, rendered on\n * whichever seat the harness offers (see `plugin-card-seat.ts`).\n *\n * The card owns its disclosure state and stages edits until Save. Its visual\n * treatment mirrors the DSH plugin-settings cards while remaining bundle-local.\n */\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport { Button, Input } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { SettingsPathOpView } from '@deepseek-ai/dsh-api-remotes/client'\nimport type { ConfigForm, ConfigFormSnapshot } from '@deepseek-ai/dsh-client-ui-settings/client'\nimport {\n consolidationModelCandidates,\n consolidationModelKey,\n type ConsolidationModelCandidate,\n type ConsolidationModelRoute,\n type LoadConsolidationModelCatalog,\n} from './consolidation-models'\nimport { DEFAULT_SHELF, shelfChoices, type LoadShelfInventory, type ShelfInfo } from './shelves'\nimport css from './SettingsCard.module.css'\nimport { NS } from './locales'\nimport './slot-contract'\n\nconst DEFAULT_CONSOLIDATION = {\n models: [] as ConsolidationModelRoute[],\n maxInputTokens: 16000,\n maxOutputTokens: 2000,\n timeoutMs: 120000,\n checkEveryTurns: 5,\n minNewTokens: 3000,\n maxWorkUnitsPerRun: 3,\n adjudicate: true,\n dedupMaxDistance: 0.45,\n cascade: { enabled: true, batchSize: 16 },\n}\n\nexport interface ConfigShape {\n enabled?: boolean\n autoApprove?: boolean\n shelf?: string\n consolidation?: typeof DEFAULT_CONSOLIDATION\n recall?: { preloadRulesTaboos?: boolean }\n}\n\n/** JSON value one `set` operation carries; the draft's fields are JSON-shaped. */\ntype FieldValue = Extract<SettingsPathOpView, { op: 'set' }>['value']\n\nfunction getSnapshotValue<T>(form: ConfigForm<T>): ConfigFormSnapshot<T> {\n return form.getSnapshot()\n}\n\nfunction subscribe(form: ConfigForm<unknown>, cb: () => void) {\n return form.subscribe(cb)\n}\n\nfunction sectionValue<T>(snap: ConfigFormSnapshot<T>): T | undefined {\n return snap.value ?? (snap.base as T | undefined) ?? undefined\n}\n\nfunction useScopeValue<T>(form: ConfigForm<T>) {\n const [snap, setSnap] = useState(() => getSnapshotValue(form))\n useEffect(() => {\n setSnap(getSnapshotValue(form))\n return subscribe(form as ConfigForm<unknown>, () => setSnap(getSnapshotValue(form)))\n }, [form])\n const value = useMemo(() => sectionValue(snap), [snap])\n return { snap, value }\n}\n\nfunction same(a: unknown, b: unknown): boolean {\n return JSON.stringify(a) === JSON.stringify(b)\n}\n\nexport type SettingsCardProps = {\n scope: ConfigForm<ConfigShape>\n loadModelCatalog: LoadConsolidationModelCatalog\n loadShelfInventory: LoadShelfInventory\n} & PropsLocale<typeof NS>\n\nexport function SettingsCard({ scope, loadModelCatalog, loadShelfInventory, t }: SettingsCardProps) {\n const { snap, value } = useScopeValue(scope)\n const disabled = !snap.writable\n const base = useMemo(() => (snap.base ?? {}) as ConfigShape, [snap.base])\n\n const resolved: ConfigShape = useMemo(() => (value ?? base ?? {\n enabled: true,\n autoApprove: true,\n shelf: DEFAULT_SHELF,\n consolidation: DEFAULT_CONSOLIDATION,\n recall: { preloadRulesTaboos: true },\n }), [value, base])\n\n const [draft, setDraft] = useState(resolved)\n const [saving, setSaving] = useState(false)\n const [error, setError] = useState<string | null>(null)\n const [catalogStatus, setCatalogStatus] = useState<'idle' | 'loading' | 'ready' | 'error'>('idle')\n const [catalogGroups, setCatalogGroups] = useState<Parameters<typeof consolidationModelCandidates>[0]>([])\n const [catalogPartial, setCatalogPartial] = useState(false)\n const catalogGeneration = useRef(0)\n const [shelfStatus, setShelfStatus] = useState<'idle' | 'loading' | 'ready' | 'error'>('idle')\n const [shelves, setShelves] = useState<ShelfInfo[]>([])\n const [shelfListingError, setShelfListingError] = useState('')\n const shelfGeneration = useRef(0)\n\n useEffect(() => {\n setDraft(resolved)\n }, [resolved])\n\n const dirty = useMemo(() => !same(draft, resolved), [draft, resolved])\n const consolidation = draft.consolidation ?? DEFAULT_CONSOLIDATION\n const recall = draft.recall ?? { preloadRulesTaboos: true }\n const saveBlocked = disabled || !dirty || saving\n\n const updateConsolidation = useCallback((patch: Partial<typeof DEFAULT_CONSOLIDATION>) => {\n setDraft((prev) => ({\n ...prev,\n consolidation: { ...(prev.consolidation ?? DEFAULT_CONSOLIDATION), ...patch },\n }))\n }, [])\n\n const loadCatalog = useCallback(async () => {\n const generation = ++catalogGeneration.current\n setCatalogStatus('loading')\n setCatalogPartial(false)\n try {\n const catalog = await loadModelCatalog()\n if (generation !== catalogGeneration.current) return\n setCatalogGroups(catalog.groups)\n setCatalogPartial(catalog.partial)\n setCatalogStatus('ready')\n } catch {\n if (generation !== catalogGeneration.current) return\n setCatalogStatus('error')\n }\n }, [loadModelCatalog])\n\n // The tab panel mounts the card when the tab is first shown, so \"on mount\"\n // is \"when the user opens this plugin's settings\".\n useEffect(() => {\n void loadCatalog()\n return () => { catalogGeneration.current += 1 }\n }, [loadCatalog])\n\n const loadShelves = useCallback(async () => {\n const generation = ++shelfGeneration.current\n setShelfStatus('loading')\n try {\n const inventory = await loadShelfInventory()\n if (generation !== shelfGeneration.current) return\n setShelves(inventory.shelves)\n setShelfListingError(inventory.error)\n setShelfStatus('ready')\n } catch {\n if (generation !== shelfGeneration.current) return\n setShelfStatus('error')\n }\n }, [loadShelfInventory])\n\n useEffect(() => {\n void loadShelves()\n return () => { shelfGeneration.current += 1 }\n }, [loadShelves])\n\n const draftShelf = draft.shelf ?? DEFAULT_SHELF\n const baseShelf = base.shelf ?? DEFAULT_SHELF\n const choices = useMemo(\n () => shelfChoices(shelves, [draftShelf, resolved.shelf ?? DEFAULT_SHELF, baseShelf]),\n [shelves, draftShelf, resolved.shelf, baseShelf],\n )\n const chosen = choices.find(choice => choice.name === draftShelf)\n\n const candidates = useMemo(() => {\n const models = consolidation.models ?? []\n return consolidationModelCandidates(\n catalogGroups,\n models,\n new Set(models.map(consolidationModelKey)),\n )\n }, [catalogGroups, consolidation.models])\n\n const toggleModel = useCallback((candidate: ConsolidationModelCandidate) => {\n if (disabled || saving) return\n setDraft((current) => {\n const currentConsolidation = current.consolidation ?? DEFAULT_CONSOLIDATION\n const currentModels = currentConsolidation.models ?? []\n const key = consolidationModelKey(candidate)\n const selected = currentModels.some(route => consolidationModelKey(route) === key)\n const models = selected\n ? currentModels.filter(route => consolidationModelKey(route) !== key)\n : [...currentModels, { provider: candidate.provider, model: candidate.model }]\n return {\n ...current,\n consolidation: { ...currentConsolidation, models },\n }\n })\n }, [disabled, saving])\n\n const discard = useCallback(() => {\n setDraft(resolved)\n setError(null)\n }, [resolved])\n\n const save = useCallback(async () => {\n if (saveBlocked) return\n setSaving(true)\n setError(null)\n try {\n const ops: SettingsPathOpView[] = []\n const setField = (field: keyof ConfigShape, value: unknown) => {\n ops.push({ op: 'set', path: [field], value: value as FieldValue })\n }\n if (!same(draft.enabled, resolved.enabled)) setField('enabled', draft.enabled)\n if (!same(draft.autoApprove, resolved.autoApprove)) setField('autoApprove', draft.autoApprove)\n if (!same(draft.shelf, resolved.shelf)) setField('shelf', draft.shelf)\n if (!same(draft.consolidation, resolved.consolidation)) setField('consolidation', draft.consolidation)\n if (!same(draft.recall, resolved.recall)) setField('recall', draft.recall)\n // One atomic mutation: the Host validates and commits every changed\n // field together, so a refusal (a concurrent edit, a value the schema\n // rejects) saves nothing rather than half the form. ConfigForm resolves\n // false on refusal instead of rejecting, and reloads the saved values.\n if (ops.length > 0 && !await scope.mutate(ops)) {\n throw new Error('the Host refused the change; nothing was saved')\n }\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err)\n // eslint-disable-next-line no-console\n console.error(`[${NS}] save failed:`, err)\n setError(message)\n } finally {\n setSaving(false)\n }\n }, [draft, resolved, saveBlocked, scope])\n\n if (snap.status === 'loading') {\n return <p className={css.status}>{t('loading', { ns: NS })}</p>\n }\n if (snap.status === 'unavailable') {\n return <p className={css.status}>{t('unavailable', { ns: NS })}</p>\n }\n\n const availableGroups = new Map<string, {\n providerName: string\n candidates: ConsolidationModelCandidate[]\n }>()\n const unavailable: ConsolidationModelCandidate[] = []\n for (const candidate of candidates) {\n if (!candidate.available) {\n unavailable.push(candidate)\n continue\n }\n const group = availableGroups.get(candidate.provider)\n if (group === undefined) {\n availableGroups.set(candidate.provider, {\n providerName: candidate.providerName,\n candidates: [candidate],\n })\n } else {\n group.candidates.push(candidate)\n }\n }\n\n const renderCandidate = (candidate: ConsolidationModelCandidate) => (\n <label key={candidate.key} className={css.model}>\n <input\n type=\"checkbox\"\n checked={candidate.selected}\n disabled={disabled || saving}\n onChange={() => toggleModel(candidate)}\n />\n <span>\n <span className={css.modelName}>{candidate.modelName}</span>\n <span className={css.route}>{`${candidate.providerName} · ${candidate.provider}/${candidate.model}`}</span>\n </span>\n {!candidate.available ? <span className={css.unavailable}>{t('modelUnavailable')}</span> : null}\n </label>\n )\n\n return (\n <section className={css.card} aria-label={t('title')}>\n <div className={css.header}>\n <span className={css.headText}>\n <span className={css.name}>{t('title')}</span>\n <span className={css.description}>{t('description')}</span>\n </span>\n {dirty ? <span className={css.pending}>{t('unsaved')}</span> : null}\n </div>\n\n <div className={css.body}>\n {!snap.writable ? <p className={css.readOnly} role=\"status\">{t('readOnly')}</p> : null}\n\n <div className={css.field}>\n <div className={css.fieldHead}>\n <label className={css.label} htmlFor=\"ham-enabled\">{t('enable')}</label>\n {draft.enabled !== (base.enabled ?? true) ? (\n <button\n type=\"button\"\n className={css.reset}\n disabled={disabled}\n onClick={() => setDraft((current) => ({ ...current, enabled: base.enabled ?? true }))}\n >\n {t('reset')}\n </button>\n ) : null}\n </div>\n <button\n id=\"ham-enabled\"\n type=\"button\"\n role=\"switch\"\n aria-checked={draft.enabled ?? true}\n aria-label={t('enable')}\n className={`${css.switch} ${draft.enabled ?? true ? css.switchOn : ''}`}\n disabled={disabled}\n onClick={() => setDraft((current) => ({ ...current, enabled: !(current.enabled ?? true) }))}\n >\n <span className={css.switchThumb} />\n </button>\n </div>\n\n <div className={css.field}>\n <div className={css.fieldHead}>\n <label className={css.label} htmlFor=\"ham-autoApprove\">{t('autoApprove')}</label>\n {(draft.autoApprove ?? true) !== (base.autoApprove ?? true) ? (\n <button\n type=\"button\"\n className={css.reset}\n disabled={disabled}\n onClick={() => setDraft((current) => ({ ...current, autoApprove: base.autoApprove ?? true }))}\n >\n {t('reset')}\n </button>\n ) : null}\n </div>\n <button\n id=\"ham-autoApprove\"\n type=\"button\"\n role=\"switch\"\n aria-checked={draft.autoApprove ?? true}\n aria-label={t('autoApprove')}\n className={`${css.switch} ${draft.autoApprove ?? true ? css.switchOn : ''}`}\n disabled={disabled}\n onClick={() => setDraft((current) => ({ ...current, autoApprove: !(current.autoApprove ?? true) }))}\n >\n <span className={css.switchThumb} />\n </button>\n <p className={css.hint}>{t('autoApproveHint')}</p>\n </div>\n\n <div className={css.field}>\n <div className={css.fieldHead}>\n <label className={css.label} htmlFor=\"ham-shelf\">{t('shelf')}</label>\n {draftShelf !== baseShelf ? (\n <button\n type=\"button\"\n className={css.reset}\n disabled={disabled}\n onClick={() => setDraft((current) => ({ ...current, shelf: baseShelf }))}\n >\n {t('reset')}\n </button>\n ) : null}\n </div>\n <select\n id=\"ham-shelf\"\n className={css.select}\n value={draftShelf}\n disabled={disabled || saving}\n onChange={(event) => {\n const shelf = event.target.value\n setDraft((current) => ({ ...current, shelf }))\n }}\n >\n {choices.map(choice => (\n <option key={choice.name} value={choice.name}>\n {choice.name}\n {choice.path !== '' ? ` — ${choice.path}` : ''}\n {!choice.listed\n ? t('shelfOptionStatus', { status: t('shelfNotListed') })\n : !choice.connected ? t('shelfOptionStatus', { status: t('shelfDisconnected') }) : ''}\n </option>\n ))}\n </select>\n {shelfStatus === 'loading' ? <p className={css.notice} role=\"status\">{t('shelfLoading')}</p> : null}\n {shelfStatus === 'error' ? (\n <div className={css.catalogError} role=\"alert\">\n <span>{t('shelfLoadFailed')}</span>\n <button type=\"button\" disabled={saving} onClick={() => { void loadShelves() }}>{t('retry')}</button>\n </div>\n ) : null}\n {shelfStatus === 'ready' && shelfListingError !== '' ? (\n <p className={css.notice} role=\"status\">{t('shelfListingFailed', { message: shelfListingError })}</p>\n ) : null}\n {shelfStatus === 'ready' && shelfListingError === '' && chosen !== undefined && (!chosen.listed || !chosen.connected) ? (\n <p className={css.warning} role=\"status\">{t(chosen.listed ? 'shelfDisconnectedWarning' : 'shelfNotListedWarning', { shelf: chosen.name })}</p>\n ) : null}\n <p className={css.hint}>{t('shelfHint')}</p>\n </div>\n\n <section className={css.group} aria-labelledby=\"ham-consolidation-title\">\n <h3 id=\"ham-consolidation-title\" className={css.groupTitle}>{t('consolidationTitle')}</h3>\n <p className={css.hint}>{t('modelSelectionHint')}</p>\n\n <div className={css.modelSelection}>\n {catalogStatus === 'loading' ? <p className={css.notice} role=\"status\">{t('modelCatalogLoading')}</p> : null}\n {catalogStatus === 'error' ? (\n <div className={css.catalogError} role=\"alert\">\n <span>{t('modelCatalogFailed')}</span>\n <button type=\"button\" disabled={saving} onClick={() => { void loadCatalog() }}>{t('retry')}</button>\n </div>\n ) : null}\n {catalogPartial ? <p className={css.notice}>{t('modelCatalogPartial')}</p> : null}\n {candidates.length > 0 ? (\n <fieldset className={css.models}>\n <legend>{t('selectedModels')}</legend>\n {[...availableGroups].map(([provider, group]) => (\n <div key={provider} className={css.modelGroup}>\n <div className={css.providerName}>{group.providerName}</div>\n {group.candidates.map(renderCandidate)}\n </div>\n ))}\n {unavailable.length > 0 ? (\n <div className={css.modelGroup}>\n <div className={css.providerName}>{t('unavailableModels')}</div>\n {unavailable.map(renderCandidate)}\n </div>\n ) : null}\n </fieldset>\n ) : catalogStatus === 'ready' ? <p className={css.notice}>{t('modelCatalogEmpty')}</p> : null}\n </div>\n\n <div className={css.pairedFields}>\n <div className={css.field}>\n <div className={css.fieldHead}>\n <label className={css.label} htmlFor=\"ham-checkEveryTurns\">{t('checkEveryTurns')}</label>\n {consolidation.checkEveryTurns !== (base.consolidation?.checkEveryTurns ?? DEFAULT_CONSOLIDATION.checkEveryTurns) ? (\n <button\n type=\"button\"\n className={css.reset}\n disabled={disabled}\n onClick={() => updateConsolidation({ checkEveryTurns: base.consolidation?.checkEveryTurns ?? DEFAULT_CONSOLIDATION.checkEveryTurns })}\n >\n {t('reset')}\n </button>\n ) : null}\n </div>\n <Input\n id=\"ham-checkEveryTurns\"\n className={css.input}\n type=\"number\"\n min={1}\n value={consolidation.checkEveryTurns}\n disabled={disabled}\n onChange={(event) => updateConsolidation({ checkEveryTurns: Number(event.target.value) })}\n />\n </div>\n <div className={css.field}>\n <div className={css.fieldHead}>\n <label className={css.label} htmlFor=\"ham-minNewTokens\">{t('minNewTokens')}</label>\n {consolidation.minNewTokens !== (base.consolidation?.minNewTokens ?? DEFAULT_CONSOLIDATION.minNewTokens) ? (\n <button\n type=\"button\"\n className={css.reset}\n disabled={disabled}\n onClick={() => updateConsolidation({ minNewTokens: base.consolidation?.minNewTokens ?? DEFAULT_CONSOLIDATION.minNewTokens })}\n >\n {t('reset')}\n </button>\n ) : null}\n </div>\n <Input\n id=\"ham-minNewTokens\"\n className={css.input}\n type=\"number\"\n min={0}\n value={consolidation.minNewTokens}\n disabled={disabled}\n onChange={(event) => updateConsolidation({ minNewTokens: Number(event.target.value) })}\n />\n </div>\n </div>\n\n <div className={css.pairedFields}>\n <div className={css.field}>\n <div className={css.fieldHead}>\n <label className={css.label} htmlFor=\"ham-cascadeBatchSize\">{t('cascadeBatchSize')}</label>\n {(consolidation.cascade?.batchSize ?? DEFAULT_CONSOLIDATION.cascade.batchSize)\n !== (base.consolidation?.cascade?.batchSize ?? DEFAULT_CONSOLIDATION.cascade.batchSize) ? (\n <button\n type=\"button\"\n className={css.reset}\n disabled={disabled}\n onClick={() => updateConsolidation({\n cascade: {\n ...(consolidation.cascade ?? DEFAULT_CONSOLIDATION.cascade),\n batchSize: base.consolidation?.cascade?.batchSize ?? DEFAULT_CONSOLIDATION.cascade.batchSize,\n },\n })}\n >\n {t('reset')}\n </button>\n ) : null}\n </div>\n <Input\n id=\"ham-cascadeBatchSize\"\n className={css.input}\n type=\"number\"\n min={2}\n value={consolidation.cascade?.batchSize ?? DEFAULT_CONSOLIDATION.cascade.batchSize}\n disabled={disabled}\n onChange={(event) => updateConsolidation({\n cascade: {\n ...(consolidation.cascade ?? DEFAULT_CONSOLIDATION.cascade),\n batchSize: Number(event.target.value),\n },\n })}\n />\n </div>\n <div className={css.field}>\n <div className={css.fieldHead}>\n <label className={css.label} htmlFor=\"ham-dedupMaxDistance\">{t('dedupMaxDistance')}</label>\n {(consolidation.dedupMaxDistance ?? DEFAULT_CONSOLIDATION.dedupMaxDistance)\n !== (base.consolidation?.dedupMaxDistance ?? DEFAULT_CONSOLIDATION.dedupMaxDistance) ? (\n <button\n type=\"button\"\n className={css.reset}\n disabled={disabled}\n onClick={() => updateConsolidation({\n dedupMaxDistance: base.consolidation?.dedupMaxDistance ?? DEFAULT_CONSOLIDATION.dedupMaxDistance,\n })}\n >\n {t('reset')}\n </button>\n ) : null}\n </div>\n <Input\n id=\"ham-dedupMaxDistance\"\n className={css.input}\n type=\"number\"\n min={0}\n step={0.05}\n value={consolidation.dedupMaxDistance ?? DEFAULT_CONSOLIDATION.dedupMaxDistance}\n disabled={disabled}\n onChange={(event) => updateConsolidation({ dedupMaxDistance: Number(event.target.value) })}\n />\n </div>\n </div>\n <p className={css.hint}>{t('cascadeHint')}</p>\n\n <h4 className={css.limitsTitle}>{t('limitsTitle')}</h4>\n <p className={css.hint}>{t('limitsHint')}</p>\n <div className={css.pairedFields}>\n <div className={css.field}>\n <div className={css.fieldHead}>\n <label className={css.label} htmlFor=\"ham-maxInputTokens\">{t('maxInputTokens')}</label>\n {consolidation.maxInputTokens !== (base.consolidation?.maxInputTokens ?? DEFAULT_CONSOLIDATION.maxInputTokens) ? (\n <button\n type=\"button\"\n className={css.reset}\n disabled={disabled}\n onClick={() => updateConsolidation({ maxInputTokens: base.consolidation?.maxInputTokens ?? DEFAULT_CONSOLIDATION.maxInputTokens })}\n >\n {t('reset')}\n </button>\n ) : null}\n </div>\n <Input\n id=\"ham-maxInputTokens\"\n className={css.input}\n type=\"number\"\n min={1000}\n step={1000}\n value={consolidation.maxInputTokens}\n disabled={disabled}\n onChange={(event) => updateConsolidation({ maxInputTokens: Number(event.target.value) })}\n />\n </div>\n <div className={css.field}>\n <div className={css.fieldHead}>\n <label className={css.label} htmlFor=\"ham-maxOutputTokens\">{t('maxOutputTokens')}</label>\n {consolidation.maxOutputTokens !== (base.consolidation?.maxOutputTokens ?? DEFAULT_CONSOLIDATION.maxOutputTokens) ? (\n <button\n type=\"button\"\n className={css.reset}\n disabled={disabled}\n onClick={() => updateConsolidation({ maxOutputTokens: base.consolidation?.maxOutputTokens ?? DEFAULT_CONSOLIDATION.maxOutputTokens })}\n >\n {t('reset')}\n </button>\n ) : null}\n </div>\n <Input\n id=\"ham-maxOutputTokens\"\n className={css.input}\n type=\"number\"\n min={200}\n step={200}\n value={consolidation.maxOutputTokens}\n disabled={disabled}\n onChange={(event) => updateConsolidation({ maxOutputTokens: Number(event.target.value) })}\n />\n </div>\n <div className={css.field}>\n <div className={css.fieldHead}>\n <label className={css.label} htmlFor=\"ham-maxWorkUnitsPerRun\">{t('maxWorkUnitsPerRun')}</label>\n {consolidation.maxWorkUnitsPerRun !== (base.consolidation?.maxWorkUnitsPerRun ?? DEFAULT_CONSOLIDATION.maxWorkUnitsPerRun) ? (\n <button\n type=\"button\"\n className={css.reset}\n disabled={disabled}\n onClick={() => updateConsolidation({ maxWorkUnitsPerRun: base.consolidation?.maxWorkUnitsPerRun ?? DEFAULT_CONSOLIDATION.maxWorkUnitsPerRun })}\n >\n {t('reset')}\n </button>\n ) : null}\n </div>\n <Input\n id=\"ham-maxWorkUnitsPerRun\"\n className={css.input}\n type=\"number\"\n min={1}\n max={10}\n value={consolidation.maxWorkUnitsPerRun}\n disabled={disabled}\n onChange={(event) => updateConsolidation({ maxWorkUnitsPerRun: Number(event.target.value) })}\n />\n </div>\n </div>\n </section>\n\n <div className={css.field}>\n <div className={css.fieldHead}>\n <label className={css.label} htmlFor=\"ham-preloadRulesTaboos\">{t('recallPreload')}</label>\n {(recall.preloadRulesTaboos ?? true) !== (base.recall?.preloadRulesTaboos ?? true) ? (\n <button\n type=\"button\"\n className={css.reset}\n disabled={disabled}\n onClick={() => setDraft((current) => ({\n ...current,\n recall: {\n ...(current.recall ?? { preloadRulesTaboos: true }),\n preloadRulesTaboos: base.recall?.preloadRulesTaboos ?? true,\n },\n }))}\n >\n {t('reset')}\n </button>\n ) : null}\n </div>\n <button\n id=\"ham-preloadRulesTaboos\"\n type=\"button\"\n role=\"switch\"\n aria-checked={recall.preloadRulesTaboos ?? true}\n aria-label={t('recallPreload')}\n className={`${css.switch} ${recall.preloadRulesTaboos ?? true ? css.switchOn : ''}`}\n disabled={disabled}\n onClick={() => setDraft((current) => ({\n ...current,\n recall: {\n ...(current.recall ?? { preloadRulesTaboos: true }),\n preloadRulesTaboos: !(current.recall?.preloadRulesTaboos ?? true),\n },\n }))}\n >\n <span className={css.switchThumb} />\n </button>\n </div>\n\n <p className={css.advancedHint}>{t('advancedHint', { ns: NS })}</p>\n {error ? <p className={css.error} role=\"status\">{t('saveFailed', { message: error })}</p> : null}\n\n <div className={css.footer}>\n <Button\n variant=\"outline\"\n size=\"sm\"\n disabled={!dirty || saving}\n onClick={discard}\n >\n {t('discard')}\n </Button>\n <Button\n variant=\"primary\"\n size=\"sm\"\n disabled={saveBlocked}\n onClick={save}\n >\n {saving ? t('saving') : t('save')}\n </Button>\n </div>\n </div>\n </section>\n )\n}\n","/**\n * The Memory tab's read side: one same-origin request per refresh.\n *\n * The Host half serves it from `/api/dsh-hypatia-auto-memory/session`\n * (see `src/memory-api.js`), which is parameterized by session and authenticates\n * itself — unlike a settings namespace, it can answer for the one session the\n * tab is bound to instead of shipping every session's state to the browser.\n *\n * Zero runtime imports beyond `fetch`, so the parsing half is unit-tested under\n * `node:test` like `shelves.ts`.\n */\n\nimport type { LoadShelfInventory, ShelfInfo, ShelfInventory } from './shelves'\n\n/** Route prefix the Host claims; the tab appends `/session`. */\nexport const MEMORY_API_PREFIX = '/api/dsh-hypatia-auto-memory'\n\n/** One task that exhausted its attempts. */\nexport interface FailedMemoryTask {\n kind: string\n sessionId: string\n attempts: number\n error: string\n}\n\n/** What the Host derived for one session out of the state tables. */\nexport interface SessionMemoryStatus {\n sessionId: string\n /** False when the Host has no row and no task for this session yet. */\n known: boolean\n loggedSeq: number\n consolidatedSeq: number\n /** True when consolidation has covered everything logged. */\n caughtUp: boolean\n pendingTokens: number\n sessionNode: boolean\n belongTo: number\n deferred: number\n failed: number\n failedTasks: FailedMemoryTask[]\n error: string\n}\n\n/** One distilled entry: a span summary or a work unit. */\nexport interface MemoryEntry {\n name: string\n /** Markdown body, already capped by the Host. */\n markdown: string\n /** Archive tier, summaries only; 1 condenses messages. */\n level: number\n createdAt: string\n}\n\n/**\n * The shelf half of a response.\n *\n * Kept as one object rather than spread across the payload so \"the Host did not\n * read the shelf\" is representable: the five-second poll asks for status only,\n * and a reader that cannot tell that apart from \"the shelf is empty\" wipes the\n * content it already showed.\n */\nexport interface MemoryContent {\n summaries: MemoryEntry[]\n workUnits: MemoryEntry[]\n /** How many the shelf holds, before the response caps. */\n summaryCount: number\n workUnitCount: number\n /** True when a cap dropped entries or cut a body short. */\n truncated: boolean\n /** Non-empty when the shelf could not be read; the status half is still valid. */\n error: string\n}\n\n/** One response from the Host. */\nexport interface MemoryPayload {\n session: SessionMemoryStatus\n /** Epoch milliseconds the Host last saw this session's status change. */\n updatedAt: number\n /** Absent when this response carried status only. */\n content: MemoryContent | undefined\n}\n\n/** Read one session's memory. `content` also asks the Host to read the shelf. */\nexport type FetchMemory = (sessionId: string, options: { content: boolean }) => Promise<MemoryPayload>\n\n/**\n * The URL one refresh reads.\n * @param sessionId - the session the tab is bound to.\n * @param content - whether to ask the Host to read the shelf as well.\n * @returns a same-origin path with its query.\n */\nexport function memoryUrl(sessionId: string, content: boolean): string {\n const query = new URLSearchParams({ session: sessionId })\n if (content) query.set('content', '1')\n return `${MEMORY_API_PREFIX}/session?${query.toString()}`\n}\n\n/** Fetch one session's memory from the Host. */\nexport const fetchMemory: FetchMemory = async (sessionId, { content }) => {\n const response = await fetch(memoryUrl(sessionId, content), {\n method: 'GET',\n credentials: 'same-origin',\n headers: { accept: 'application/json' },\n })\n const body: unknown = await response.json().catch(() => undefined)\n if (!response.ok) {\n const message = isRecord(body) && typeof body.error === 'string' ? body.error : `HTTP ${String(response.status)}`\n throw new Error(message)\n }\n const payload = parseMemoryPayload(body, sessionId)\n if (payload === undefined) throw new Error('the Host returned an unreadable memory payload')\n return payload\n}\n\n/**\n * Fetch the shelf listing for the settings card.\n *\n * Rides the same self-authenticating route family as the Memory tab — the\n * settings page passes the same loopback / same-origin checks — because the\n * 0.1.7 settings domain no longer lets a Host plugin publish a dynamic,\n * non-config namespace for the card to read.\n */\nexport const fetchShelves: LoadShelfInventory = async () => {\n const response = await fetch(`${MEMORY_API_PREFIX}/shelves`, {\n method: 'GET',\n credentials: 'same-origin',\n headers: { accept: 'application/json' },\n })\n const body: unknown = await response.json().catch(() => undefined)\n if (!response.ok) {\n const message = isRecord(body) && typeof body.error === 'string' ? body.error : `HTTP ${String(response.status)}`\n throw new Error(message)\n }\n const inventory = parseShelfInventory(body)\n if (inventory === undefined) throw new Error('the Host returned an unreadable shelf listing')\n return inventory\n}\n\n/**\n * Read the Host's `/shelves` answer into the card's shape, defensively.\n * @param value - the parsed response body.\n * @returns the listing, or undefined when the body is not one.\n */\nexport function parseShelfInventory(value: unknown): ShelfInventory | undefined {\n if (!isRecord(value)) return undefined\n return {\n shelves: Array.isArray(value.shelves)\n ? value.shelves.flatMap((shelf): ShelfInfo[] => {\n if (!isRecord(shelf) || typeof shelf.name !== 'string' || shelf.name === '') return []\n return [{\n name: shelf.name,\n path: typeof shelf.path === 'string' ? shelf.path : '',\n connected: shelf.connected === true,\n }]\n })\n : [],\n error: str(value.error),\n }\n}\n\n/**\n * Session-log events that are recorded but not yet consolidated.\n *\n * Both watermarks index the same log, so their difference is exactly the work\n * consolidation still owes. Clamped at zero: a consolidation run may cover a\n * range the logging watermark has not caught up to yet, which is not a backlog.\n *\n * @param session - the session half of a payload.\n * @returns the gap in session-log events.\n */\nexport function consolidationGap(session: SessionMemoryStatus): number {\n return Math.max(0, session.loggedSeq - session.consolidatedSeq)\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction num(value: unknown): number {\n return typeof value === 'number' && Number.isFinite(value) ? value : 0\n}\n\nfunction str(value: unknown): string {\n return typeof value === 'string' ? value : ''\n}\n\nfunction parseFailedTasks(value: unknown): FailedMemoryTask[] {\n if (!Array.isArray(value)) return []\n return value.flatMap((entry): FailedMemoryTask[] => isRecord(entry)\n ? [{\n kind: str(entry.kind),\n sessionId: str(entry.sessionId),\n attempts: num(entry.attempts),\n error: str(entry.error),\n }]\n : [])\n}\n\nfunction parseEntries(value: unknown): MemoryEntry[] {\n if (!Array.isArray(value)) return []\n return value.flatMap((entry): MemoryEntry[] => {\n if (!isRecord(entry)) return []\n const name = str(entry.name)\n if (name === '') return []\n return [{\n name,\n markdown: str(entry.markdown),\n level: num(entry.level) || 1,\n createdAt: str(entry.createdAt),\n }]\n })\n}\n\n/**\n * Read the Host's answer into the tab's shape, defensively.\n *\n * A malformed field falls back to its zero value rather than reaching the DOM;\n * a payload with no usable `session` is rejected outright, because rendering a\n * panel of zeros for a session the Host never answered about would be a lie.\n *\n * A status-only answer parses to `content: undefined` — never to empty lists,\n * which is what made the five-second poll erase the shelf content. The Host also\n * states which half it sent (`content`), and that flag is what this prefers; the\n * key sniffing beside it keeps a bundle built after the flag from misreading a\n * Host that predates it, so the fix does not need a profile restart to land.\n *\n * @param value - the parsed response body.\n * @param sessionId - the session that was asked for.\n * @returns the payload, or undefined when the body is not one.\n */\nexport function parseMemoryPayload(value: unknown, sessionId: string): MemoryPayload | undefined {\n if (!isRecord(value) || !isRecord(value.session)) return undefined\n const session = value.session\n const carried = value.content === true\n || Object.hasOwn(value, 'summaries')\n || Object.hasOwn(value, 'contentError')\n return {\n session: {\n sessionId: str(session.sessionId) || sessionId,\n known: session.known === true,\n loggedSeq: num(session.loggedSeq),\n consolidatedSeq: num(session.consolidatedSeq),\n caughtUp: session.caughtUp === true,\n pendingTokens: num(session.pendingTokens),\n sessionNode: session.sessionNode === true,\n belongTo: num(session.belongTo),\n deferred: num(session.deferred),\n failed: num(session.failed),\n failedTasks: parseFailedTasks(session.failedTasks),\n error: str(session.error),\n },\n updatedAt: num(value.updatedAt),\n content: carried\n ? {\n summaries: parseEntries(value.summaries),\n workUnits: parseEntries(value.workUnits),\n summaryCount: num(value.summaryCount),\n workUnitCount: num(value.workUnitCount),\n truncated: value.truncated === true,\n error: str(value.contentError),\n }\n : undefined,\n }\n}\n\n/**\n * Fold a new answer onto the one on screen.\n *\n * Status is always the newest. Content is only replaced by an answer that\n * carried content, so the poll cannot erase it. An answer whose shelf read\n * failed keeps the content already shown — entries, counts and the truncation\n * flag together, so the header still describes the list under it — and records\n * the error beside it, because a transient hypatia failure should not blank\n * what the reader was looking at.\n *\n * @param previous - the payload on screen, if any.\n * @param next - the answer just parsed.\n * @returns the payload to render.\n */\nexport function mergeMemory(\n previous: MemoryPayload | undefined,\n next: MemoryPayload,\n): MemoryPayload {\n if (next.content === undefined) return { ...next, content: previous?.content }\n // A failed read keeps whatever was on screen — the entries AND the counts that\n // describe them — and replaces only the reason. The guard must not consult the\n // previous error: on the SECOND consecutive failure it is already set, and\n // testing for it fell through to the zeroed answer, blanking the panel the\n // first failure had deliberately preserved.\n if (next.content.error !== '' && previous?.content !== undefined) {\n return { ...next, content: { ...previous.content, error: next.content.error } }\n }\n return next\n}\n","/**\n * The conversation's Memory tab: what this session has been remembered as, what\n * it was remembered into, and what is stuck.\n *\n * Three sections, in the order a reader wants them: the pipeline's status\n * (watermarks, backlog, failures), then the span summaries consolidation\n * produced, then the work units derived from them. Bodies render through the\n * shell's own `MarkdownText`, so a summary reads exactly like assistant Markdown\n * elsewhere in the GUI and costs no bundle weight.\n *\n * Raw `msg-*` entries are deliberately absent: they hold the conversation\n * verbatim, the reader just wrote them, and the agent is the right reader for\n * them (see `src/memory-api.js` for the same rule on the Host side).\n *\n * Status is polled; content is fetched only when it can have changed — on mount,\n * on a session switch, on a manual refresh, and whenever consolidation advances\n * the session's watermark. Reading the shelf costs hypatia round trips, and\n * consolidation is the only thing that changes it.\n */\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport { MarkdownText } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots'\nimport {\n consolidationGap,\n mergeMemory,\n type FetchMemory,\n type MemoryEntry,\n type MemoryPayload,\n} from './memory-client'\nimport { NS } from './locales'\nimport css from './MemoryView.module.css'\nimport './slot-contract'\n\n/** How often the tab re-reads the status half while it is on screen. */\nconst POLL_MS = 5000\n\nexport type MemoryViewProps = {\n /** The session this tab is bound to; supplied by the session-scoped slot. */\n sessionId: string\n fetch: FetchMemory\n} & PropsLocale<typeof NS>\n\n/** Local wall-clock stamp for the freshness line. */\nfunction formatTime(epochMs: number): string {\n if (!Number.isFinite(epochMs) || epochMs <= 0) return '—'\n return new Date(epochMs).toLocaleTimeString()\n}\n\n/**\n * hypatia stamps `created_at` as `YYYY-MM-DD HH:MM:SS.ffffff`; the microseconds\n * are noise in a row that is 11px tall, so the tab shows down to the minute.\n * Slice rather than `new Date`: the space-separated form is not the ISO shape\n * every engine is required to parse.\n */\nfunction formatEntryTime(stamp: string): string {\n return stamp.length >= 16 ? stamp.slice(0, 16).replace('T', ' ') : stamp\n}\n\n/** The first non-empty line of a body, for a collapsed row's preview. */\nfunction firstLine(markdown: string): string {\n for (const line of markdown.split('\\n')) {\n const trimmed = line.replace(/^[#>\\-*\\s]+/, '').trim()\n if (trimmed !== '') return trimmed\n }\n return ''\n}\n\n/** One collapsible distilled entry. */\nfunction Entry({ entry, badge, open, onToggle, labels, t }: {\n entry: MemoryEntry\n badge: string\n open: boolean\n onToggle: () => void\n labels: { code: { copyLabel: string; copiedLabel: string }; footnotes: string }\n t: MemoryViewProps['t']\n}) {\n return (\n <li className={css.entry}>\n <button type=\"button\" className={css.entryHead} aria-expanded={open} onClick={onToggle}>\n <span className={css.entryName}>{entry.name}</span>\n <span className={css.entryMeta}>\n <span className={css.badge}>{badge}</span>\n {entry.createdAt !== '' ? <span className={css.entryTime}>{formatEntryTime(entry.createdAt)}</span> : null}\n <span className={css.entryToggle}>{open ? t('memoryEntryCollapse') : t('memoryEntryExpand')}</span>\n </span>\n </button>\n {open\n ? (\n <div className={css.entryBody}>\n {entry.markdown === ''\n ? <p className={css.status}>{t('memoryEntryEmpty')}</p>\n : <MarkdownText text={entry.markdown} labels={labels} />}\n </div>\n )\n : <p className={css.entryPreview}>{firstLine(entry.markdown)}</p>}\n </li>\n )\n}\n\nexport function MemoryView({ sessionId, fetch, t }: MemoryViewProps) {\n const [payload, setPayload] = useState<MemoryPayload | undefined>(undefined)\n const [loading, setLoading] = useState(true)\n const [error, setError] = useState('')\n /**\n * The entries the reader opened, by name. Absent means closed, which is the\n * default: a toggle survives the poll that replaces the payload, and an entry\n * a later poll adds starts closed rather than inheriting a neighbour's state.\n */\n const [overrides, setOverrides] = useState<Readonly<Record<string, boolean>>>({})\n /** The watermark whose content is already in hand, so a poll never re-reads it. */\n const [contentAt, setContentAt] = useState<number | undefined>(undefined)\n\n const copyLabel = t('memoryCopyCode')\n const copiedLabel = t('memoryCopiedCode')\n const footnotes = t('memoryFootnotes')\n // MarkdownText caches its render against the labels identity, so this must be\n // one object per locale, not a fresh one per render.\n const labels = useMemo(\n () => ({ code: { copyLabel, copiedLabel }, footnotes }),\n [copyLabel, copiedLabel, footnotes],\n )\n\n /**\n * The session the tab is showing now. A request outlives the session it was\n * made for — a slow shelf read, or a poll already in flight at a switch — and\n * its answer must be dropped rather than folded into the next session's view.\n */\n const activeSession = useRef(sessionId)\n\n const load = useCallback(async (content: boolean) => {\n const current = () => activeSession.current === sessionId\n try {\n const next = await fetch(sessionId, { content })\n if (!current()) return\n // Folded, not assigned: a status-only poll must not erase the shelf\n // content it did not ask for (see `mergeMemory`).\n setPayload((previous) => mergeMemory(previous, next))\n setError('')\n if (content) setContentAt(next.session.consolidatedSeq)\n } catch (failure) {\n if (!current()) return\n setError(failure instanceof Error ? failure.message : String(failure))\n } finally {\n if (current()) setLoading(false)\n }\n }, [fetch, sessionId])\n\n // A session switch starts over: the previous session's content and the\n // previous session's collapsed rows must not leak into this one.\n useEffect(() => {\n activeSession.current = sessionId\n setPayload(undefined)\n setOverrides({})\n setContentAt(undefined)\n setLoading(true)\n void load(true)\n }, [load, sessionId])\n\n useEffect(() => {\n const timer = setInterval(() => {\n // A hidden tab has nobody reading it; the panel is a snapshot, not a stream.\n if (typeof document !== 'undefined' && document.visibilityState === 'hidden') return\n void load(false)\n }, POLL_MS)\n return () => clearInterval(timer)\n }, [load])\n\n // Consolidation is the only thing that changes the shelf, so a watermark that\n // moved is the signal to read it again.\n useEffect(() => {\n const at = payload?.session.consolidatedSeq\n if (at === undefined || contentAt === undefined) return\n if (at !== contentAt) void load(true)\n }, [payload?.session.consolidatedSeq, contentAt, load])\n\n const toggle = useCallback((name: string, open: boolean) => {\n setOverrides((current) => ({ ...current, [name]: !open }))\n }, [])\n\n const session = payload?.session\n const content = payload?.content\n const summaries = content?.summaries ?? []\n const workUnits = content?.workUnits ?? []\n\n // Every entry starts closed and previews its first line: the list stays\n // scannable at any length, and the bodies are one click away. `overrides`\n // holds what the reader opened, so a poll that replaces the payload does not\n // close it again.\n const renderEntries = (entries: MemoryEntry[], kind: 'summary' | 'workUnit') => (\n <ul className={css.entries}>\n {entries.map((entry) => {\n const open = overrides[entry.name] === true\n return (\n <Entry\n key={entry.name}\n entry={entry}\n badge={kind === 'summary' ? t('memoryTier', { level: String(entry.level) }) : t('memoryWorkUnit')}\n open={open}\n onToggle={() => toggle(entry.name, open)}\n labels={labels}\n t={t}\n />\n )\n })}\n </ul>\n )\n\n return (\n // Opts into the composer overlay the way the trajectory ledger does: the\n // view owns its scroller and gets the full height, with the composer\n // floating over it. Without the marker the Conversation shell seats the\n // composer below a short panel instead.\n <div className={css.panel} data-conversation-composer-overlay=\"\">\n <div className={css.column}>\n <header className={css.head}>\n <h2 className={css.title}>{t('memoryTitle')}</h2>\n <div className={css.headMeta}>\n <span className={css.updated}>{t('memoryUpdatedAt', { time: formatTime(payload?.updatedAt ?? 0) })}</span>\n <button type=\"button\" className={css.refresh} onClick={() => { void load(true) }}>\n {t('memoryRefresh')}\n </button>\n </div>\n </header>\n\n {error !== '' ? <p className={css.error} role=\"status\">{t('memoryLoadFailed', { message: error })}</p> : null}\n\n {loading && payload === undefined\n ? <p className={css.status}>{t('memoryLoading')}</p>\n : session === undefined\n ? <p className={css.status}>{t('memoryNoSnapshot')}</p>\n : !session.known\n ? <p className={css.status}>{t('memoryUnknown')}</p>\n : (\n <section className={css.group} aria-label={t('memoryTitle')}>\n <dl className={css.rows}>\n <div className={css.row}>\n <dt className={css.label}>{t('memoryLogged')}</dt>\n <dd className={css.value}>{t('memorySeqValue', { seq: String(session.loggedSeq) })}</dd>\n </div>\n <div className={css.row}>\n <dt className={css.label}>{t('memoryConsolidated')}</dt>\n <dd className={css.value}>\n {t('memorySeqValue', { seq: String(session.consolidatedSeq) })}\n {/* Quantified, not a bare \"pending\": a reader has to know HOW\n far behind to judge whether to wait. */}\n <span className={session.caughtUp ? css.calm : css.busy}>\n {session.caughtUp\n ? t('memoryCaughtUp')\n : t('memoryBehind', { behind: String(consolidationGap(session)) })}\n </span>\n </dd>\n </div>\n <div className={css.row}>\n <dt className={css.label}>{t('memoryPending')}</dt>\n <dd className={css.value}>{t('memoryPendingValue', { tokens: String(session.pendingTokens) })}</dd>\n </div>\n <div className={css.row}>\n <dt className={css.label}>{t('memorySessionNode')}</dt>\n <dd className={css.value}>\n {session.sessionNode ? t('memorySessionNodeYes') : t('memorySessionNodeNo')}\n </dd>\n </div>\n <div className={css.row}>\n <dt className={css.label}>{t('memoryBelongTo')}</dt>\n <dd className={css.value}>{t('memoryBelongToValue', { count: String(session.belongTo) })}</dd>\n </div>\n {session.deferred > 0 ? (\n <div className={css.row}>\n <dt className={css.label}>{t('memoryDeferred')}</dt>\n <dd className={css.value}>{String(session.deferred)}</dd>\n </div>\n ) : null}\n </dl>\n </section>\n )}\n\n {session !== undefined && (session.failed > 0 || session.failedTasks.length > 0) ? (\n <section className={css.group} aria-label={t('memoryFailedTitle')}>\n <h3 className={css.groupTitle}>{t('memoryFailedTitle')}</h3>\n <ul className={css.failures}>\n {session.failedTasks.map((task, index) => (\n <li key={`${task.kind}-${String(index)}`} className={css.failure}>\n <span className={css.failureKind}>\n {t('memoryFailedItem', { kind: task.kind, attempts: String(task.attempts) })}\n </span>\n {task.error !== '' ? <span className={css.failureError}>{task.error}</span> : null}\n </li>\n ))}\n {session.failedTasks.length === 0 ? <li className={css.failure}>{session.error}</li> : null}\n </ul>\n </section>\n ) : null}\n\n {content !== undefined && content.error !== '' ? (\n <section className={css.group} aria-label={t('memoryContentTitle')}>\n <h3 className={css.groupTitle}>{t('memoryContentTitle')}</h3>\n <p className={css.error} role=\"status\">{t('memoryContentFailed', { message: content.error })}</p>\n </section>\n ) : null}\n\n {content !== undefined ? (\n <>\n <section className={css.group} aria-label={t('memorySummariesTitle')}>\n <h3 className={css.groupTitle}>\n {t('memorySummariesTitle')}\n <span className={css.count}>\n {t('memoryCount', { shown: String(summaries.length), total: String(content.summaryCount) })}\n </span>\n </h3>\n {summaries.length === 0\n ? <p className={css.status}>{t('memoryNoSummaries')}</p>\n : renderEntries(summaries, 'summary')}\n </section>\n\n <section className={css.group} aria-label={t('memoryWorkUnitsTitle')}>\n <h3 className={css.groupTitle}>\n {t('memoryWorkUnitsTitle')}\n <span className={css.count}>\n {t('memoryCount', { shown: String(workUnits.length), total: String(content.workUnitCount) })}\n </span>\n </h3>\n {workUnits.length === 0\n ? <p className={css.status}>{t('memoryNoWorkUnits')}</p>\n : renderEntries(workUnits, 'workUnit')}\n </section>\n\n {content.truncated ? <p className={css.hint}>{t('memoryTruncated')}</p> : null}\n <p className={css.hint}>{t('memoryHint')}</p>\n </>\n ) : null}\n </div>\n </div>\n )\n}\n","/**\n * Which seat the settings card occupies on the harness that is running.\n *\n * dsh 0.1.7 moved a bundle's own configuration out of Settings. The sidebar's\n * Plugins page owns it now, and `plugins.bundle.config` — keyed by the bundle's\n * package name — is the seat that page renders on the bundle's own page. The\n * Settings section still declares `settings.plugins.tab`, and it is the only\n * seat a deployment whose profile does not mount the plugin manager page has.\n *\n * Three facts about the slot registry shape this module:\n *\n * - The harness declares the official seats before an external plugin's\n * `apply()` runs, so the first attempt normally succeeds. It is a plain\n * `register`, never a declaration probe: `register` is the operation the\n * registry validates, and a probe would answer for a different question —\n * \"is this key declared?\" is true even in the deployment whose whole point is\n * the other seat.\n * - `register` throws for an undeclared seat. That refusal is the fallback\n * signal, so the seats are tried rather than predicted.\n * - `slots/changed` is emitted synchronously from inside both `register` and a\n * disposer, so an unguarded reconcile re-enters itself mid-move and registers\n * the card twice into the seat it is leaving (\"already has an entry for key\n * …\"). The latch below is what prevents that.\n *\n * The card is therefore in exactly one seat at any time: the official one when\n * the harness renders it, the Settings tab otherwise, and the Settings entry is\n * disposed before the official one is taken. This module holds the policy and\n * no client-SDK import, so the moves are unit-tested with a fake registry.\n *\n * @module dsh-hypatia-auto-memory/client/plugin-card-seat\n */\n\n/** The official keyed seat on the sidebar Plugins page, keyed by bundle package name. */\nexport const BUNDLE_CONFIG_SEAT = 'plugins.bundle.config'\n\n/** The list seat inside Settings → Built-in plugins, declared by the Settings section. */\nexport const SETTINGS_TAB_SEAT = 'settings.plugins.tab'\n\n/** The slice of the client slot registry this module uses. */\nexport interface SeatRegistry {\n /**\n * Contribute one entry, or throw when the seat is not declared.\n * @param key - declared slot key to inject a contribution into.\n * @param callback - runs while that declaration is live; returns its disposer.\n * @returns idempotent disposer for the wait and the active contribution.\n */\n inject(key: string, callback: () => () => void): () => void\n}\n\n/** The slice of the browser plugin context this module uses. */\nexport interface SeatHost {\n readonly slots: SeatRegistry\n /** Subscribe to the registry's change event; absent on a host that has no event bus. */\n on?(event: 'slots/changed', listener: (key: string) => void): (() => void) | undefined\n}\n\n/** How to install one card into each seat, each throwing when that seat is not declared. */\nexport interface PluginCardSeats {\n /** The official keyed seat; the caller keys it by bundle package name. */\n readonly official: () => (() => void) | undefined\n /** The Settings tab; the caller passes its list-seat id, label and locale. */\n readonly settingsTab: () => (() => void) | undefined\n /**\n * Called once per seat that a registration attempt refused, for a diagnostic.\n * The official seat is expected to refuse while it is not declared yet, so a\n * deployment that renders it never reports anything here.\n */\n readonly onRefused?: (seat: string, error: unknown) => void\n}\n\n/**\n * Install one card into the seat this harness renders, following the harness if\n * the seat becomes available later.\n *\n * @param host - the client context's slot registry and event bus.\n * @param seats - the two seat contributions and an optional refusal diagnostic.\n * @returns one disposer that removes the card and stops watching.\n */\nexport function installPluginCard(host: SeatHost, seats: PluginCardSeats): () => void {\n /** The live official registration, while the card occupies that seat. */\n let official: (() => void) | undefined\n /** The live Settings-tab registration, while the card occupies that seat instead. */\n let settingsTab: (() => void) | undefined\n /** Set by the returned disposer: every later reconcile is a no-op. */\n let stopped = false\n /** Re-entrancy latch: the registry emits `slots/changed` from inside register and dispose. */\n let reconciling = false\n const refused = new Set<string>()\n\n /** One registration attempt, reporting its refusal once instead of on every retry. */\n const attempt = (seat: string, register: () => (() => void) | undefined): (() => void) | undefined => {\n try {\n return register()\n } catch (error) {\n if (!refused.has(seat)) {\n refused.add(seat)\n seats.onRefused?.(seat, error)\n }\n return undefined\n }\n }\n\n /** Take the official seat when it is declared, retiring the Settings fallback first. */\n const reconcile = (): void => {\n if (stopped || reconciling || official !== undefined) return\n reconciling = true\n try {\n const dispose = attempt(BUNDLE_CONFIG_SEAT, seats.official)\n if (dispose === undefined) return\n official = dispose\n const previous = settingsTab\n settingsTab = undefined\n previous?.()\n } finally {\n reconciling = false\n }\n }\n\n reconcile()\n\n // The fallback claims the Settings tab only while the official seat is absent.\n // Its declaration arrives when the Settings section mounts, which is after the\n // shell has declared the official seats — so on a harness that renders the\n // Plugins page this callback finds `official` already live and contributes\n // nothing.\n const stopWaiting = host.slots.inject(SETTINGS_TAB_SEAT, () => {\n if (stopped || official !== undefined || settingsTab !== undefined) return () => {}\n const dispose = attempt(SETTINGS_TAB_SEAT, seats.settingsTab)\n if (dispose === undefined) return () => {}\n settingsTab = dispose\n // The registration above emits `slots/changed`, so a reconcile can have taken\n // the official seat before this assignment: the card would then sit in two\n // seats. Re-check instead of assuming which ran first.\n if (official !== undefined) {\n settingsTab = undefined\n dispose()\n return () => {}\n }\n return () => {\n const current = settingsTab\n settingsTab = undefined\n current?.()\n }\n })\n\n const stopWatching = host.on?.('slots/changed', () => { reconcile() })\n\n return () => {\n stopped = true\n stopWatching?.()\n stopWaiting()\n const officialDispose = official\n official = undefined\n officialDispose?.()\n const settingsDispose = settingsTab\n settingsTab = undefined\n settingsDispose?.()\n }\n}\n","/**\n * Browser half of dsh-hypatia-auto-memory: contributes the configuration card\n * for the `hypatia-auto-memory` namespace, and a per-session Memory tab beside\n * the conversation's Chat and Trajectory tabs.\n *\n * The card's seat depends on the harness: the sidebar Plugins page owns a\n * bundle's configuration from dsh 0.1.7 on, and the Settings tab is the fallback\n * for a deployment that does not render that page. `plugin-card-seat.ts` makes\n * that choice and keeps the card in one seat.\n *\n * The Host plugin already registers the schema and namespace; this half only\n * renders the form and routes edits through `ctx.configForms`. The Memory tab\n * reads the Host's read-only status namespace (see `src/memory-status.js`).\n */\n\nimport type { Context } from '@deepseek-ai/cordis'\nimport type {} from '@deepseek-ai/dsh-api-remotes/client'\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\nimport type { LocaleRuntime } from '@deepseek-ai/dsh-client-locale/client'\nimport type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { ConfigForms } from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-renderer/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings-plugins/client'\n// Type-only: the 'conversation.view' SlotMap row is declared by the conversation\n// shell, so the registration below only type-checks with its merge in the program.\nimport type {} from '@deepseek-ai/dsh-client-ui-conversation/client'\nimport { createElement } from 'react'\nimport { SettingsCard } from './SettingsCard'\nimport type { ConfigShape } from './SettingsCard'\nimport type { LoadConsolidationModelCatalog } from './consolidation-models'\nimport { MemoryView } from './MemoryView'\nimport { fetchMemory, fetchShelves } from './memory-client'\nimport type { LoadShelfInventory } from './shelves'\nimport { BUNDLE_CONFIG_SEAT, SETTINGS_TAB_SEAT, installPluginCard } from './plugin-card-seat'\nimport { en, NS, zh } from './locales'\n\n/** The bundle's npm package name: the key the official seat identifies it by. */\nconst BUNDLE_NAME = 'dsh-hypatia-auto-memory'\n\nconst APPLY_CLAIM = '__dshHypatiaAutoMemoryApplied'\n\nfunction claimApply(): boolean {\n const scope = globalThis as Record<string, unknown>\n if (scope[APPLY_CLAIM] === true) return false\n scope[APPLY_CLAIM] = true\n return true\n}\n\nfunction releaseApply(): void {\n delete (globalThis as Record<string, unknown>)[APPLY_CLAIM]\n}\n\n/**\n * Required client services: slots, locale, the Host model catalog, and the\n * settings domain's shared configuration forms (the 0.1.7 successor of the\n * removed `settingsScope` service). Each Remote namespace is its own service,\n * so `remote.session` must be declared here or reading it throws.\n */\nexport const inject = ['slots', 'configForms', 'locale', 'remote', 'remote.session']\n\n/** Mount the browser half. */\nexport function apply(ctx: Context): void {\n if (!claimApply()) return\n\n // Resolve through ctx.get with an explicit type rather than ctx.configForms:\n // the settings package's cordis Context merge only applies when its types\n // resolve to the same cordis module identity, which is not guaranteed for an\n // npm-installed plugin (symlinked workspace checkouts diverge).\n const configForms = ctx.get('configForms') as ConfigForms\n const form = configForms.get<ConfigShape>(NS)\n\n // Resolve through ctx.get with an explicit type rather than ctx.locale: the\n // locale package's cordis Context merge only applies when its types resolve\n // to the same cordis module identity, which is not guaranteed for an\n // npm-installed plugin (symlinked workspace checkouts diverge).\n const locale = ctx.get('locale') as unknown as LocaleRuntime\n ctx.effect(() => locale.register(NS, { zh, en }), 'dsh-hypatia-auto-memory: locale dictionaries')\n // Bound before either registration below: the plugins tab label and the\n // Memory tab label both read through it so they follow the active locale\n // without re-registration, exactly as ui-trajectory's does.\n const t = locale.bind(NS)\n\n const loadModelCatalog: LoadConsolidationModelCatalog = async () => {\n const response = await ctx.remote.session.modelCatalog()\n if (!response.ok) throw new Error(`${response.error.code}: ${response.error.message}`)\n return {\n groups: response.value.groups,\n partial: response.value.failures.length > 0,\n }\n }\n // The shelf listing comes from the Host's own route family: the 0.1.7\n // settings document only projects plugin Config forms, so the read-only\n // inventory namespace this used to ride can no longer be published.\n const loadShelfInventory: LoadShelfInventory = fetchShelves\n const renderCard = (props: PropsLocale<typeof NS>) => createElement(SettingsCard, {\n scope: form,\n loadModelCatalog,\n loadShelfInventory,\n ...props,\n })\n // The card exists only while the Host serves our namespace; whileServed owns\n // the watch and hands us a disposer for whichever seat is live. Both\n // registrations are written plainly and the installer catches the refusal an\n // undeclared seat throws — a harness without the Plugins page answers that way.\n const unregister = ctx.effect(() => configForms.whileServed([NS], () =>\n installPluginCard(ctx, {\n official: () => ctx.slots.register(\n { name: BUNDLE_CONFIG_SEAT, key: BUNDLE_NAME, locale: NS },\n renderCard,\n ),\n settingsTab: () => ctx.slots.register(\n { name: SETTINGS_TAB_SEAT, id: NS, label: () => t('title'), locale: NS },\n renderCard,\n ),\n onRefused: (seat, error) => {\n console.warn(`[${BUNDLE_NAME}] configuration card refused by slot \"${seat}\"`, error)\n },\n }),\n ), 'dsh-hypatia-auto-memory: configuration card seat')\n\n // The Memory tab's data: one same-origin request to the route family this\n // plugin's Host half registers (see `src/memory-api.js`) — the same family\n // the shelf listing above rides — parameterized by the session the tab is\n // bound to.\n const unregisterMemoryView = ctx.slots.inject('conversation.view', () =>\n ctx.slots.register(\n {\n name: 'conversation.view',\n id: 'memory',\n // After Chat (0) and Trajectory (10).\n order: 20,\n locale: NS,\n label: () => t('viewMemory'),\n inject: () => ({ fetch: fetchMemory }),\n },\n MemoryView,\n ),\n )\n\n ctx.effect(() => () => {\n unregister()\n unregisterMemoryView()\n releaseApply()\n })\n}\n"],"mappings":";;;;;;;;;;;EA6BA,SAAgB,sBAAsB,OAAwC;GAC5E,OAAO,GAAG,MAAM,SAAS,IAAI,MAAM;EACrC;;;;;EAMA,SAAgB,6BACd,QACA,QACA,UAC+B;GAC/B,MAAM,cAAc,IAAI,IAAI,OAAO,KAAI,UAAS,CAAC,sBAAsB,KAAK,GAAG,KAAK,CAAC,CAAC;GACtF,MAAM,aAAa,OAAO,SAAQ,UAAS,MAAM,OAAO,KAAK,UAAuC;IAClG,MAAM,QAAQ;KAAE,UAAU,MAAM;KAAI,OAAO,MAAM;IAAG;IACpD,MAAM,MAAM,sBAAsB,KAAK;IACvC,YAAY,OAAO,GAAG;IACtB,OAAO;KACL,GAAG;KACH;KACA,cAAc,MAAM;KACpB,WAAW,MAAM;KACjB,WAAW;KACX,UAAU,SAAS,IAAI,GAAG;IAC5B;GACF,CAAC,CAAC;GACF,KAAK,MAAM,SAAS,YAAY,OAAO,GAAG;IACxC,MAAM,MAAM,sBAAsB,KAAK;IACvC,WAAW,KAAK;KACd,GAAG;KACH;KACA,cAAc,MAAM;KACpB,WAAW,MAAM;KACjB,WAAW;KACX,UAAU,SAAS,IAAI,GAAG;IAC5B,CAAC;GACH;GACA,OAAO;EACT;;;;;;;;;ECpBA,SAAgB,aAAa,SAA+B,MAAwC;GAClG,MAAM,UAAyB,QAAQ,KAAI,WAAU;IAAE,GAAG;IAAO,QAAQ;GAAK,EAAE;GAChF,KAAK,MAAM,QAAQ,MAAM;IACvB,IAAI,SAAS,MAAM,QAAQ,MAAK,WAAU,OAAO,SAAS,IAAI,GAAG;IACjE,QAAQ,KAAK;KAAE;KAAM,MAAM;KAAI,WAAW;KAAO,QAAQ;IAAM,CAAC;GAClE;GACA,OAAO;EACT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ECpDA,MAAa,KAAK;;EAGlB,MAAa,KAAK;GAChB,SAAS;GACT,aAAa;GACb,OAAO;GACP,aACE;GACF,QAAQ;GACR,aAAa;GACb,iBAAiB;GACjB,OAAO;GACP,WAAW;GACX,cAAc;GACd,iBAAiB;GACjB,oBAAoB;GACpB,mBAAmB;GACnB,mBAAmB;GACnB,gBAAgB;GAChB,0BAA0B;GAC1B,uBAAuB;GACvB,oBAAoB;GACpB,oBAAoB;GACpB,qBAAqB;GACrB,oBAAoB;GACpB,qBAAqB;GACrB,mBAAmB;GACnB,gBAAgB;GAChB,mBAAmB;GACnB,kBAAkB;GAClB,OAAO;GACP,iBAAiB;GACjB,cAAc;GACd,kBAAkB;GAClB,kBAAkB;GAClB,aAAa;GACb,aAAa;GACb,YAAY;GACZ,gBAAgB;GAChB,iBAAiB;GACjB,oBAAoB;GACpB,eAAe;GACf,cACE;GACF,OAAO;GACP,SAAS;GACT,MAAM;GACN,QAAQ;GACR,YAAY;GACZ,UAAU;GACV,SAAS;GACT,YAAY;GACZ,aAAa;GACb,iBAAiB;GACjB,eAAe;GACf,eAAe;GACf,kBAAkB;GAClB,kBAAkB;GAClB,eAAe;GACf,cAAc;GACd,gBAAgB;GAChB,oBAAoB;GACpB,gBAAgB;GAChB,cAAc;GACd,eAAe;GACf,oBAAoB;GACpB,mBAAmB;GACnB,sBAAsB;GACtB,qBAAqB;GACrB,gBAAgB;GAChB,qBAAqB;GACrB,gBAAgB;GAChB,mBAAmB;GACnB,kBAAkB;GAClB,oBAAoB;GACpB,qBAAqB;GACrB,sBAAsB;GACtB,sBAAsB;GACtB,mBAAmB;GACnB,mBAAmB;GACnB,aAAa;GACb,YAAY;GACZ,gBAAgB;GAChB,mBAAmB;GACnB,qBAAqB;GACrB,kBAAkB;GAClB,gBAAgB;GAChB,kBAAkB;GAClB,iBAAiB;GACjB,iBAAiB;GACjB,YAAY;EACd;;EAMA,MAAa,KAAK;GAChB,SAAS;GACT,aAAa;GACb,OAAO;GACP,aACE;GACF,QAAQ;GACR,aAAa;GACb,iBAAiB;GACjB,OAAO;GACP,WAAW;GACX,cAAc;GACd,iBAAiB;GACjB,oBAAoB;GACpB,mBAAmB;GACnB,mBAAmB;GACnB,gBAAgB;GAChB,0BAA0B;GAC1B,uBAAuB;GACvB,oBAAoB;GACpB,oBAAoB;GACpB,qBAAqB;GACrB,oBAAoB;GACpB,qBAAqB;GACrB,mBAAmB;GACnB,gBAAgB;GAChB,mBAAmB;GACnB,kBAAkB;GAClB,OAAO;GACP,iBAAiB;GACjB,cAAc;GACd,kBAAkB;GAClB,kBAAkB;GAClB,aAAa;GACb,aAAa;GACb,YAAY;GACZ,gBAAgB;GAChB,iBAAiB;GACjB,oBAAoB;GACpB,eAAe;GACf,cACE;GACF,OAAO;GACP,SAAS;GACT,MAAM;GACN,QAAQ;GACR,YAAY;GACZ,UAAU;GACV,SAAS;GACT,YAAY;GACZ,aAAa;GACb,iBAAiB;GACjB,eAAe;GACf,eAAe;GACf,kBAAkB;GAClB,kBAAkB;GAClB,eAAe;GACf,cAAc;GACd,gBAAgB;GAChB,oBAAoB;GACpB,gBAAgB;GAChB,cAAc;GACd,eAAe;GACf,oBAAoB;GACpB,mBAAmB;GACnB,sBAAsB;GACtB,qBAAqB;GACrB,gBAAgB;GAChB,qBAAqB;GACrB,gBAAgB;GAChB,mBAAmB;GACnB,kBAAkB;GAClB,oBAAoB;GACpB,qBAAqB;GACrB,sBAAsB;GACtB,sBAAsB;GACtB,mBAAmB;GACnB,mBAAmB;GACnB,aAAa;GACb,YAAY;GACZ,gBAAgB;GAChB,mBAAmB;GACnB,qBAAqB;GACrB,kBAAkB;GAClB,gBAAgB;GAChB,kBAAkB;GAClB,iBAAiB;GACjB,iBAAiB;GACjB,YAAY;EACd;;;;;;;;;;ECrKA,MAAM,wBAAwB;GAC5B,QAAQ,CAAC;GACT,gBAAgB;GAChB,iBAAiB;GACjB,WAAW;GACX,iBAAiB;GACjB,cAAc;GACd,oBAAoB;GACpB,YAAY;GACZ,kBAAkB;GAClB,SAAS;IAAE,SAAS;IAAM,WAAW;GAAG;EAC1C;EAaA,SAAS,iBAAoB,MAA4C;GACvE,OAAO,KAAK,YAAY;EAC1B;EAEA,SAAS,UAAU,MAA2B,IAAgB;GAC5D,OAAO,KAAK,UAAU,EAAE;EAC1B;EAEA,SAAS,aAAgB,MAA4C;GACnE,OAAO,KAAK,SAAU,KAAK,QAA0B,KAAA;EACvD;EAEA,SAAS,cAAiB,MAAqB;GAC7C,MAAM,CAAC,MAAM,YAAA,GAAWA,MAAAA,SAAAA,OAAe,iBAAiB,IAAI,CAAC;GAC7D,CAAA,GAAA,MAAA,UAAA,OAAgB;IACd,QAAQ,iBAAiB,IAAI,CAAC;IAC9B,OAAO,UAAU,YAAmC,QAAQ,iBAAiB,IAAI,CAAC,CAAC;GACrF,GAAG,CAAC,IAAI,CAAC;GAET,OAAO;IAAE;IAAM,QAAA,GADDC,MAAAA,QAAAA,OAAc,aAAa,IAAI,GAAG,CAAC,IAAI,CAClC;GAAE;EACvB;EAEA,SAAS,KAAK,GAAY,GAAqB;GAC7C,OAAO,KAAK,UAAU,CAAC,MAAM,KAAK,UAAU,CAAC;EAC/C;EAQA,SAAgB,aAAa,EAAE,OAAO,kBAAkB,oBAAoB,KAAwB;GAClG,MAAM,EAAE,MAAM,UAAU,cAAc,KAAK;GAC3C,MAAM,WAAW,CAAC,KAAK;GACvB,MAAM,QAAA,GAAOA,MAAAA,QAAAA,OAAe,KAAK,QAAQ,CAAC,GAAmB,CAAC,KAAK,IAAI,CAAC;GAExE,MAAM,YAAA,GAAwBA,MAAAA,QAAAA,OAAe,SAAS,QAAQ;IAC5D,SAAS;IACT,aAAa;IACb,OAAA;IACA,eAAe;IACf,QAAQ,EAAE,oBAAoB,KAAK;GACrC,GAAI,CAAC,OAAO,IAAI,CAAC;GAEjB,MAAM,CAAC,OAAO,aAAA,GAAYD,MAAAA,SAAAA,CAAS,QAAQ;GAC3C,MAAM,CAAC,QAAQ,cAAA,GAAaA,MAAAA,SAAAA,CAAS,KAAK;GAC1C,MAAM,CAAC,OAAO,aAAA,GAAYA,MAAAA,SAAAA,CAAwB,IAAI;GACtD,MAAM,CAAC,eAAe,qBAAA,GAAoBA,MAAAA,SAAAA,CAAiD,MAAM;GACjG,MAAM,CAAC,eAAe,qBAAA,GAAoBA,MAAAA,SAAAA,CAA6D,CAAC,CAAC;GACzG,MAAM,CAAC,gBAAgB,sBAAA,GAAqBA,MAAAA,SAAAA,CAAS,KAAK;GAC1D,MAAM,qBAAA,GAAoBE,MAAAA,OAAAA,CAAO,CAAC;GAClC,MAAM,CAAC,aAAa,mBAAA,GAAkBF,MAAAA,SAAAA,CAAiD,MAAM;GAC7F,MAAM,CAAC,SAAS,eAAA,GAAcA,MAAAA,SAAAA,CAAsB,CAAC,CAAC;GACtD,MAAM,CAAC,mBAAmB,yBAAA,GAAwBA,MAAAA,SAAAA,CAAS,EAAE;GAC7D,MAAM,mBAAA,GAAkBE,MAAAA,OAAAA,CAAO,CAAC;GAEhC,CAAA,GAAA,MAAA,UAAA,OAAgB;IACd,SAAS,QAAQ;GACnB,GAAG,CAAC,QAAQ,CAAC;GAEb,MAAM,SAAA,GAAQD,MAAAA,QAAAA,OAAc,CAAC,KAAK,OAAO,QAAQ,GAAG,CAAC,OAAO,QAAQ,CAAC;GACrE,MAAM,gBAAgB,MAAM,iBAAiB;GAC7C,MAAM,SAAS,MAAM,UAAU,EAAE,oBAAoB,KAAK;GAC1D,MAAM,cAAc,YAAY,CAAC,SAAS;GAE1C,MAAM,uBAAA,GAAsBE,MAAAA,YAAAA,EAAa,UAAiD;IACxF,UAAU,UAAU;KAClB,GAAG;KACH,eAAe;MAAE,GAAI,KAAK,iBAAiB;MAAwB,GAAG;KAAM;IAC9E,EAAE;GACJ,GAAG,CAAC,CAAC;GAEL,MAAM,eAAA,GAAcA,MAAAA,YAAAA,CAAY,YAAY;IAC1C,MAAM,aAAa,EAAE,kBAAkB;IACvC,iBAAiB,SAAS;IAC1B,kBAAkB,KAAK;IACvB,IAAI;KACF,MAAM,UAAU,MAAM,iBAAiB;KACvC,IAAI,eAAe,kBAAkB,SAAS;KAC9C,iBAAiB,QAAQ,MAAM;KAC/B,kBAAkB,QAAQ,OAAO;KACjC,iBAAiB,OAAO;IAC1B,QAAQ;KACN,IAAI,eAAe,kBAAkB,SAAS;KAC9C,iBAAiB,OAAO;IAC1B;GACF,GAAG,CAAC,gBAAgB,CAAC;GAIrB,CAAA,GAAA,MAAA,UAAA,OAAgB;IACd,YAAiB;IACjB,aAAa;KAAE,kBAAkB,WAAW;IAAE;GAChD,GAAG,CAAC,WAAW,CAAC;GAEhB,MAAM,eAAA,GAAcA,MAAAA,YAAAA,CAAY,YAAY;IAC1C,MAAM,aAAa,EAAE,gBAAgB;IACrC,eAAe,SAAS;IACxB,IAAI;KACF,MAAM,YAAY,MAAM,mBAAmB;KAC3C,IAAI,eAAe,gBAAgB,SAAS;KAC5C,WAAW,UAAU,OAAO;KAC5B,qBAAqB,UAAU,KAAK;KACpC,eAAe,OAAO;IACxB,QAAQ;KACN,IAAI,eAAe,gBAAgB,SAAS;KAC5C,eAAe,OAAO;IACxB;GACF,GAAG,CAAC,kBAAkB,CAAC;GAEvB,CAAA,GAAA,MAAA,UAAA,OAAgB;IACd,YAAiB;IACjB,aAAa;KAAE,gBAAgB,WAAW;IAAE;GAC9C,GAAG,CAAC,WAAW,CAAC;GAEhB,MAAM,aAAa,MAAM,SAAA;GACzB,MAAM,YAAY,KAAK,SAAA;GACvB,MAAM,WAAA,GAAUF,MAAAA,QAAAA,OACR,aAAa,SAAS;IAAC;IAAY,SAAS,SAAA;IAAwB;GAAS,CAAC,GACpF;IAAC;IAAS;IAAY,SAAS;IAAO;GAAS,CACjD;GACA,MAAM,SAAS,QAAQ,MAAK,WAAU,OAAO,SAAS,UAAU;GAEhE,MAAM,cAAA,GAAaA,MAAAA,QAAAA,OAAc;IAC/B,MAAM,SAAS,cAAc,UAAU,CAAC;IACxC,OAAO,6BACL,eACA,QACA,IAAI,IAAI,OAAO,IAAI,qBAAqB,CAAC,CAC3C;GACF,GAAG,CAAC,eAAe,cAAc,MAAM,CAAC;GAExC,MAAM,eAAA,GAAcE,MAAAA,YAAAA,EAAa,cAA2C;IAC1E,IAAI,YAAY,QAAQ;IACxB,UAAU,YAAY;KACpB,MAAM,uBAAuB,QAAQ,iBAAiB;KACtD,MAAM,gBAAgB,qBAAqB,UAAU,CAAC;KACtD,MAAM,MAAM,sBAAsB,SAAS;KAE3C,MAAM,SADW,cAAc,MAAK,UAAS,sBAAsB,KAAK,MAAM,GACxD,IAClB,cAAc,QAAO,UAAS,sBAAsB,KAAK,MAAM,GAAG,IAClE,CAAC,GAAG,eAAe;MAAE,UAAU,UAAU;MAAU,OAAO,UAAU;KAAM,CAAC;KAC/E,OAAO;MACL,GAAG;MACH,eAAe;OAAE,GAAG;OAAsB;MAAO;KACnD;IACF,CAAC;GACH,GAAG,CAAC,UAAU,MAAM,CAAC;GAErB,MAAM,WAAA,GAAUA,MAAAA,YAAAA,OAAkB;IAChC,SAAS,QAAQ;IACjB,SAAS,IAAI;GACf,GAAG,CAAC,QAAQ,CAAC;GAEb,MAAM,QAAA,GAAOA,MAAAA,YAAAA,CAAY,YAAY;IACnC,IAAI,aAAa;IACjB,UAAU,IAAI;IACd,SAAS,IAAI;IACb,IAAI;KACF,MAAM,MAA4B,CAAC;KACnC,MAAM,YAAY,OAA0B,UAAmB;MAC7D,IAAI,KAAK;OAAE,IAAI;OAAO,MAAM,CAAC,KAAK;OAAU;MAAoB,CAAC;KACnE;KACA,IAAI,CAAC,KAAK,MAAM,SAAS,SAAS,OAAO,GAAG,SAAS,WAAW,MAAM,OAAO;KAC7E,IAAI,CAAC,KAAK,MAAM,aAAa,SAAS,WAAW,GAAG,SAAS,eAAe,MAAM,WAAW;KAC7F,IAAI,CAAC,KAAK,MAAM,OAAO,SAAS,KAAK,GAAG,SAAS,SAAS,MAAM,KAAK;KACrE,IAAI,CAAC,KAAK,MAAM,eAAe,SAAS,aAAa,GAAG,SAAS,iBAAiB,MAAM,aAAa;KACrG,IAAI,CAAC,KAAK,MAAM,QAAQ,SAAS,MAAM,GAAG,SAAS,UAAU,MAAM,MAAM;KAKzE,IAAI,IAAI,SAAS,KAAK,CAAC,MAAM,MAAM,OAAO,GAAG,GAC3C,MAAM,IAAI,MAAM,gDAAgD;IAEpE,SAAS,KAAc;KACrB,MAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;KAE/D,QAAQ,MAAM,IAAI,GAAG,iBAAiB,GAAG;KACzC,SAAS,OAAO;IAClB,UAAU;KACR,UAAU,KAAK;IACjB;GACF,GAAG;IAAC;IAAO;IAAU;IAAa;GAAK,CAAC;GAExC,IAAI,KAAK,WAAW,WAClB,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;IAAG,WAAWC,gCAAI;IAAS,UAAA,EAAE,WAAW,EAAE,IAAI,GAAG,CAAC;GAAK,CAAA;GAEhE,IAAI,KAAK,WAAW,eAClB,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;IAAG,WAAWA,gCAAI;IAAS,UAAA,EAAE,eAAe,EAAE,IAAI,GAAG,CAAC;GAAK,CAAA;GAGpE,MAAM,kCAAkB,IAAI,IAGzB;GACH,MAAM,cAA6C,CAAC;GACpD,KAAK,MAAM,aAAa,YAAY;IAClC,IAAI,CAAC,UAAU,WAAW;KACxB,YAAY,KAAK,SAAS;KAC1B;IACF;IACA,MAAM,QAAQ,gBAAgB,IAAI,UAAU,QAAQ;IACpD,IAAI,UAAU,KAAA,GACZ,gBAAgB,IAAI,UAAU,UAAU;KACtC,cAAc,UAAU;KACxB,YAAY,CAAC,SAAS;IACxB,CAAC;SAED,MAAM,WAAW,KAAK,SAAS;GAEnC;GAEA,MAAM,mBAAmB,cACvB,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;IAA2B,WAAWA,gCAAI;IAA1C,UAAA;KACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;MACE,MAAK;MACL,SAAS,UAAU;MACnB,UAAU,YAAY;MACtB,gBAAgB,YAAY,SAAS;KACtC,CAAA;KACD,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;MAAM,WAAWA,gCAAI;MAAY,UAAA,UAAU;KAAgB,CAAA,GAC3D,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;MAAM,WAAWA,gCAAI;MAAQ,UAAA,GAAG,UAAU,aAAa,KAAK,UAAU,SAAS,GAAG,UAAU;KAAc,CAAA,CACtG,EAAA,CAAA;KACL,CAAC,UAAU,YAAY,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;MAAM,WAAWA,gCAAI;MAAc,UAAA,EAAE,kBAAkB;KAAQ,CAAA,IAAI;IACtF;GAZK,GAAA,UAAU,GAYf;GAGT,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,WAAD;IAAS,WAAWA,gCAAI;IAAM,cAAY,EAAE,OAAO;IAAnD,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;KAAK,WAAWA,gCAAI;KAApB,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;MAAM,WAAWA,gCAAI;MAArB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;OAAM,WAAWA,gCAAI;OAAO,UAAA,EAAE,OAAO;MAAQ,CAAA,GAC7C,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;OAAM,WAAWA,gCAAI;OAAc,UAAA,EAAE,aAAa;MAAQ,CAAA,CACtD;KACL,CAAA,GAAA,QAAQ,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;MAAM,WAAWA,gCAAI;MAAU,UAAA,EAAE,SAAS;KAAQ,CAAA,IAAI,IAC5D;IAEL,CAAA,GAAA,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;KAAK,WAAWA,gCAAI;KAApB,UAAA;MACG,CAAC,KAAK,WAAW,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;OAAG,WAAWA,gCAAI;OAAU,MAAK;OAAU,UAAA,EAAE,UAAU;MAAK,CAAA,IAAI;MAElF,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,WAAWA,gCAAI;OAApB,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,gCAAI;QAApB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;SAAO,WAAWA,gCAAI;SAAO,SAAQ;SAAe,UAAA,EAAE,QAAQ;QAAS,CAAA,GACtE,MAAM,aAAa,KAAK,WAAW,QAClC,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SACE,MAAK;SACL,WAAWA,gCAAI;SACL;SACV,eAAe,UAAU,aAAa;UAAE,GAAG;UAAS,SAAS,KAAK,WAAW;SAAK,EAAE;SAEnF,UAAA,EAAE,OAAO;QACJ,CAAA,IACN,IACD;OACL,CAAA,GAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QACE,IAAG;QACH,MAAK;QACL,MAAK;QACL,gBAAc,MAAM,WAAW;QAC/B,cAAY,EAAE,QAAQ;QACtB,WAAW,GAAGA,gCAAI,OAAO,GAAG,MAAM,WAAW,OAAOA,gCAAI,WAAW;QACzD;QACV,eAAe,UAAU,aAAa;SAAE,GAAG;SAAS,SAAS,EAAE,QAAQ,WAAW;QAAM,EAAE;QAE1F,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAM,WAAWA,gCAAI,YAAc,CAAA;OAC7B,CAAA,CACL;;MAEL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,WAAWA,gCAAI;OAApB,UAAA;QACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;SAAK,WAAWA,gCAAI;SAApB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;UAAO,WAAWA,gCAAI;UAAO,SAAQ;UAAmB,UAAA,EAAE,aAAa;SAAS,CAAA,IAC9E,MAAM,eAAe,WAAW,KAAK,eAAe,QACpD,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UACE,MAAK;UACL,WAAWA,gCAAI;UACL;UACV,eAAe,UAAU,aAAa;WAAE,GAAG;WAAS,aAAa,KAAK,eAAe;UAAK,EAAE;UAE3F,UAAA,EAAE,OAAO;SACJ,CAAA,IACN,IACD;;QACL,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SACE,IAAG;SACH,MAAK;SACL,MAAK;SACL,gBAAc,MAAM,eAAe;SACnC,cAAY,EAAE,aAAa;SAC3B,WAAW,GAAGA,gCAAI,OAAO,GAAG,MAAM,eAAe,OAAOA,gCAAI,WAAW;SAC7D;SACV,eAAe,UAAU,aAAa;UAAE,GAAG;UAAS,aAAa,EAAE,QAAQ,eAAe;SAAM,EAAE;SAElG,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAM,WAAWA,gCAAI,YAAc,CAAA;QAC7B,CAAA;QACR,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;SAAG,WAAWA,gCAAI;SAAO,UAAA,EAAE,iBAAiB;QAAK,CAAA;OAC9C;;MAEL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,WAAWA,gCAAI;OAApB,UAAA;QACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;SAAK,WAAWA,gCAAI;SAApB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;UAAO,WAAWA,gCAAI;UAAO,SAAQ;UAAa,UAAA,EAAE,OAAO;SAAS,CAAA,GACnE,eAAe,YACd,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UACE,MAAK;UACL,WAAWA,gCAAI;UACL;UACV,eAAe,UAAU,aAAa;WAAE,GAAG;WAAS,OAAO;UAAU,EAAE;UAEtE,UAAA,EAAE,OAAO;SACJ,CAAA,IACN,IACD;;QACL,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SACE,IAAG;SACH,WAAWA,gCAAI;SACf,OAAO;SACP,UAAU,YAAY;SACtB,WAAW,UAAU;UACnB,MAAM,QAAQ,MAAM,OAAO;UAC3B,UAAU,aAAa;WAAE,GAAG;WAAS;UAAM,EAAE;SAC/C;SAEC,UAAA,QAAQ,KAAI,WACX,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;UAA0B,OAAO,OAAO;UAAxC,UAAA;WACG,OAAO;WACP,OAAO,SAAS,KAAK,MAAM,OAAO,SAAS;WAC3C,CAAC,OAAO,SACL,EAAE,qBAAqB,EAAE,QAAQ,EAAE,gBAAgB,EAAE,CAAC,IACtD,CAAC,OAAO,YAAY,EAAE,qBAAqB,EAAE,QAAQ,EAAE,mBAAmB,EAAE,CAAC,IAAI;UAC/E;SANK,GAAA,OAAO,IAMZ,CACT;QACK,CAAA;QACP,gBAAgB,YAAY,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;SAAG,WAAWA,gCAAI;SAAQ,MAAK;SAAU,UAAA,EAAE,cAAc;QAAK,CAAA,IAAI;QAC9F,gBAAgB,UACf,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;SAAK,WAAWA,gCAAI;SAAc,MAAK;SAAvC,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAA,UAAO,EAAE,iBAAiB,EAAQ,CAAA,GAClC,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAQ,MAAK;UAAS,UAAU;UAAQ,eAAe;WAAE,YAAiB;UAAE;UAAI,UAAA,EAAE,OAAO;SAAU,CAAA,CAChG;QACH,CAAA,IAAA;QACH,gBAAgB,WAAW,sBAAsB,KAChD,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;SAAG,WAAWA,gCAAI;SAAQ,MAAK;SAAU,UAAA,EAAE,sBAAsB,EAAE,SAAS,kBAAkB,CAAC;QAAK,CAAA,IAClG;QACH,gBAAgB,WAAW,sBAAsB,MAAM,WAAW,KAAA,MAAc,CAAC,OAAO,UAAU,CAAC,OAAO,aACzG,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;SAAG,WAAWA,gCAAI;SAAS,MAAK;SAAU,UAAA,EAAE,OAAO,SAAS,6BAA6B,yBAAyB,EAAE,OAAO,OAAO,KAAK,CAAC;QAAK,CAAA,IAC3I;QACJ,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;SAAG,WAAWA,gCAAI;SAAO,UAAA,EAAE,WAAW;QAAK,CAAA;OACxC;;MAEL,iBAAA,GAAA,kBAAA,KAAA,CAAC,WAAD;OAAS,WAAWA,gCAAI;OAAO,mBAAgB;OAA/C,UAAA;QACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;SAAI,IAAG;SAA0B,WAAWA,gCAAI;SAAa,UAAA,EAAE,oBAAoB;QAAM,CAAA;QACzF,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;SAAG,WAAWA,gCAAI;SAAO,UAAA,EAAE,oBAAoB;QAAK,CAAA;QAEpD,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;SAAK,WAAWA,gCAAI;SAApB,UAAA;UACG,kBAAkB,YAAY,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;WAAG,WAAWA,gCAAI;WAAQ,MAAK;WAAU,UAAA,EAAE,qBAAqB;UAAK,CAAA,IAAI;UACvG,kBAAkB,UACjB,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;WAAK,WAAWA,gCAAI;WAAc,MAAK;WAAvC,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAA,UAAO,EAAE,oBAAoB,EAAQ,CAAA,GACrC,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;YAAQ,MAAK;YAAS,UAAU;YAAQ,eAAe;aAAE,YAAiB;YAAE;YAAI,UAAA,EAAE,OAAO;WAAU,CAAA,CAChG;UACH,CAAA,IAAA;UACH,iBAAiB,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;WAAG,WAAWA,gCAAI;WAAS,UAAA,EAAE,qBAAqB;UAAK,CAAA,IAAI;UAC5E,WAAW,SAAS,IACnB,iBAAA,GAAA,kBAAA,KAAA,CAAC,YAAD;WAAU,WAAWA,gCAAI;WAAzB,UAAA;YACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD,EAAA,UAAS,EAAE,gBAAgB,EAAU,CAAA;YACpC,CAAC,GAAG,eAAe,CAAC,CAAC,KAAK,CAAC,UAAU,WACpC,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;aAAoB,WAAWA,gCAAI;aAAnC,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;cAAK,WAAWA,gCAAI;cAAe,UAAA,MAAM;aAAkB,CAAA,GAC1D,MAAM,WAAW,IAAI,eAAe,CAClC;YAHK,GAAA,QAGL,CACN;YACA,YAAY,SAAS,IACpB,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;aAAK,WAAWA,gCAAI;aAApB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;cAAK,WAAWA,gCAAI;cAAe,UAAA,EAAE,mBAAmB;aAAO,CAAA,GAC9D,YAAY,IAAI,eAAe,CAC7B;YACH,CAAA,IAAA;WACI;UACR,CAAA,IAAA,kBAAkB,UAAU,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;WAAG,WAAWA,gCAAI;WAAS,UAAA,EAAE,mBAAmB;UAAK,CAAA,IAAI;SACtF;;QAEL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;SAAK,WAAWA,gCAAI;SAApB,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;UAAK,WAAWA,gCAAI;UAApB,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;WAAK,WAAWA,gCAAI;WAApB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;YAAO,WAAWA,gCAAI;YAAO,SAAQ;YAAuB,UAAA,EAAE,iBAAiB;WAAS,CAAA,GACvF,cAAc,qBAAqB,KAAK,eAAe,mBAAmB,sBAAsB,mBAC/F,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;YACE,MAAK;YACL,WAAWA,gCAAI;YACL;YACV,eAAe,oBAAoB,EAAE,iBAAiB,KAAK,eAAe,mBAAmB,sBAAsB,gBAAgB,CAAC;YAEnI,UAAA,EAAE,OAAO;WACJ,CAAA,IACN,IACD;UACL,CAAA,GAAA,iBAAA,GAAA,kBAAA,IAAA,CAACC,sCAAAA,OAAD;WACE,IAAG;WACH,WAAWD,gCAAI;WACf,MAAK;WACL,KAAK;WACL,OAAO,cAAc;WACX;WACV,WAAW,UAAU,oBAAoB,EAAE,iBAAiB,OAAO,MAAM,OAAO,KAAK,EAAE,CAAC;UACzF,CAAA,CACE;SACL,CAAA,GAAA,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;UAAK,WAAWA,gCAAI;UAApB,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;WAAK,WAAWA,gCAAI;WAApB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;YAAO,WAAWA,gCAAI;YAAO,SAAQ;YAAoB,UAAA,EAAE,cAAc;WAAS,CAAA,GACjF,cAAc,kBAAkB,KAAK,eAAe,gBAAgB,sBAAsB,gBACzF,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;YACE,MAAK;YACL,WAAWA,gCAAI;YACL;YACV,eAAe,oBAAoB,EAAE,cAAc,KAAK,eAAe,gBAAgB,sBAAsB,aAAa,CAAC;YAE1H,UAAA,EAAE,OAAO;WACJ,CAAA,IACN,IACD;UACL,CAAA,GAAA,iBAAA,GAAA,kBAAA,IAAA,CAACC,sCAAAA,OAAD;WACE,IAAG;WACH,WAAWD,gCAAI;WACf,MAAK;WACL,KAAK;WACL,OAAO,cAAc;WACX;WACV,WAAW,UAAU,oBAAoB,EAAE,cAAc,OAAO,MAAM,OAAO,KAAK,EAAE,CAAC;UACtF,CAAA,CACE;SACF,CAAA,CAAA;;QAEL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;SAAK,WAAWA,gCAAI;SAApB,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;UAAK,WAAWA,gCAAI;UAApB,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;WAAK,WAAWA,gCAAI;WAApB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;YAAO,WAAWA,gCAAI;YAAO,SAAQ;YAAwB,UAAA,EAAE,kBAAkB;WAAS,CAAA,IACxF,cAAc,SAAS,aAAa,sBAAsB,QAAQ,gBAC7D,KAAK,eAAe,SAAS,aAAa,sBAAsB,QAAQ,aAC3E,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;YACE,MAAK;YACL,WAAWA,gCAAI;YACL;YACV,eAAe,oBAAoB,EACjC,SAAS;aACP,GAAI,cAAc,WAAW,sBAAsB;aACnD,WAAW,KAAK,eAAe,SAAS,aAAa,sBAAsB,QAAQ;YACrF,EACF,CAAC;YAEA,UAAA,EAAE,OAAO;WACJ,CAAA,IACN,IACH;UACL,CAAA,GAAA,iBAAA,GAAA,kBAAA,IAAA,CAACC,sCAAAA,OAAD;WACE,IAAG;WACH,WAAWD,gCAAI;WACf,MAAK;WACL,KAAK;WACL,OAAO,cAAc,SAAS,aAAa,sBAAsB,QAAQ;WAC/D;WACV,WAAW,UAAU,oBAAoB,EACvC,SAAS;YACP,GAAI,cAAc,WAAW,sBAAsB;YACnD,WAAW,OAAO,MAAM,OAAO,KAAK;WACtC,EACF,CAAC;UACF,CAAA,CACE;SACL,CAAA,GAAA,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;UAAK,WAAWA,gCAAI;UAApB,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;WAAK,WAAWA,gCAAI;WAApB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;YAAO,WAAWA,gCAAI;YAAO,SAAQ;YAAwB,UAAA,EAAE,kBAAkB;WAAS,CAAA,IACxF,cAAc,oBAAoB,sBAAsB,uBACnD,KAAK,eAAe,oBAAoB,sBAAsB,oBACjE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;YACE,MAAK;YACL,WAAWA,gCAAI;YACL;YACV,eAAe,oBAAoB,EACjC,kBAAkB,KAAK,eAAe,oBAAoB,sBAAsB,iBAClF,CAAC;YAEA,UAAA,EAAE,OAAO;WACJ,CAAA,IACN,IACH;UACL,CAAA,GAAA,iBAAA,GAAA,kBAAA,IAAA,CAACC,sCAAAA,OAAD;WACE,IAAG;WACH,WAAWD,gCAAI;WACf,MAAK;WACL,KAAK;WACL,MAAM;WACN,OAAO,cAAc,oBAAoB,sBAAsB;WACrD;WACV,WAAW,UAAU,oBAAoB,EAAE,kBAAkB,OAAO,MAAM,OAAO,KAAK,EAAE,CAAC;UAC1F,CAAA,CACE;SACF,CAAA,CAAA;;QACL,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;SAAG,WAAWA,gCAAI;SAAO,UAAA,EAAE,aAAa;QAAK,CAAA;QAE7C,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;SAAI,WAAWA,gCAAI;SAAc,UAAA,EAAE,aAAa;QAAM,CAAA;QACtD,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;SAAG,WAAWA,gCAAI;SAAO,UAAA,EAAE,YAAY;QAAK,CAAA;QAC5C,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;SAAK,WAAWA,gCAAI;SAApB,UAAA;UACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;WAAK,WAAWA,gCAAI;WAApB,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;YAAK,WAAWA,gCAAI;YAApB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;aAAO,WAAWA,gCAAI;aAAO,SAAQ;aAAsB,UAAA,EAAE,gBAAgB;YAAS,CAAA,GACrF,cAAc,oBAAoB,KAAK,eAAe,kBAAkB,sBAAsB,kBAC7F,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;aACE,MAAK;aACL,WAAWA,gCAAI;aACL;aACV,eAAe,oBAAoB,EAAE,gBAAgB,KAAK,eAAe,kBAAkB,sBAAsB,eAAe,CAAC;aAEhI,UAAA,EAAE,OAAO;YACJ,CAAA,IACN,IACD;WACL,CAAA,GAAA,iBAAA,GAAA,kBAAA,IAAA,CAACC,sCAAAA,OAAD;YACE,IAAG;YACH,WAAWD,gCAAI;YACf,MAAK;YACL,KAAK;YACL,MAAM;YACN,OAAO,cAAc;YACX;YACV,WAAW,UAAU,oBAAoB,EAAE,gBAAgB,OAAO,MAAM,OAAO,KAAK,EAAE,CAAC;WACxF,CAAA,CACE;;UACL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;WAAK,WAAWA,gCAAI;WAApB,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;YAAK,WAAWA,gCAAI;YAApB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;aAAO,WAAWA,gCAAI;aAAO,SAAQ;aAAuB,UAAA,EAAE,iBAAiB;YAAS,CAAA,GACvF,cAAc,qBAAqB,KAAK,eAAe,mBAAmB,sBAAsB,mBAC/F,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;aACE,MAAK;aACL,WAAWA,gCAAI;aACL;aACV,eAAe,oBAAoB,EAAE,iBAAiB,KAAK,eAAe,mBAAmB,sBAAsB,gBAAgB,CAAC;aAEnI,UAAA,EAAE,OAAO;YACJ,CAAA,IACN,IACD;WACL,CAAA,GAAA,iBAAA,GAAA,kBAAA,IAAA,CAACC,sCAAAA,OAAD;YACE,IAAG;YACH,WAAWD,gCAAI;YACf,MAAK;YACL,KAAK;YACL,MAAM;YACN,OAAO,cAAc;YACX;YACV,WAAW,UAAU,oBAAoB,EAAE,iBAAiB,OAAO,MAAM,OAAO,KAAK,EAAE,CAAC;WACzF,CAAA,CACE;;UACL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;WAAK,WAAWA,gCAAI;WAApB,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;YAAK,WAAWA,gCAAI;YAApB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;aAAO,WAAWA,gCAAI;aAAO,SAAQ;aAA0B,UAAA,EAAE,oBAAoB;YAAS,CAAA,GAC7F,cAAc,wBAAwB,KAAK,eAAe,sBAAsB,sBAAsB,sBACrG,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;aACE,MAAK;aACL,WAAWA,gCAAI;aACL;aACV,eAAe,oBAAoB,EAAE,oBAAoB,KAAK,eAAe,sBAAsB,sBAAsB,mBAAmB,CAAC;aAE5I,UAAA,EAAE,OAAO;YACJ,CAAA,IACN,IACD;WACL,CAAA,GAAA,iBAAA,GAAA,kBAAA,IAAA,CAACC,sCAAAA,OAAD;YACE,IAAG;YACH,WAAWD,gCAAI;YACf,MAAK;YACL,KAAK;YACL,KAAK;YACL,OAAO,cAAc;YACX;YACV,WAAW,UAAU,oBAAoB,EAAE,oBAAoB,OAAO,MAAM,OAAO,KAAK,EAAE,CAAC;WAC5F,CAAA,CACE;;SACF;;OACE;;MAET,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,WAAWA,gCAAI;OAApB,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,gCAAI;QAApB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;SAAO,WAAWA,gCAAI;SAAO,SAAQ;SAA0B,UAAA,EAAE,eAAe;QAAS,CAAA,IACvF,OAAO,sBAAsB,WAAW,KAAK,QAAQ,sBAAsB,QAC3E,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SACE,MAAK;SACL,WAAWA,gCAAI;SACL;SACV,eAAe,UAAU,aAAa;UACpC,GAAG;UACH,QAAQ;WACN,GAAI,QAAQ,UAAU,EAAE,oBAAoB,KAAK;WACjD,oBAAoB,KAAK,QAAQ,sBAAsB;UACzD;SACF,EAAE;SAED,UAAA,EAAE,OAAO;QACJ,CAAA,IACN,IACD;OACL,CAAA,GAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QACE,IAAG;QACH,MAAK;QACL,MAAK;QACL,gBAAc,OAAO,sBAAsB;QAC3C,cAAY,EAAE,eAAe;QAC7B,WAAW,GAAGA,gCAAI,OAAO,GAAG,OAAO,sBAAsB,OAAOA,gCAAI,WAAW;QACrE;QACV,eAAe,UAAU,aAAa;SACpC,GAAG;SACH,QAAQ;UACN,GAAI,QAAQ,UAAU,EAAE,oBAAoB,KAAK;UACjD,oBAAoB,EAAE,QAAQ,QAAQ,sBAAsB;SAC9D;QACF,EAAE;QAEF,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAM,WAAWA,gCAAI,YAAc,CAAA;OAC7B,CAAA,CACL;;MAEL,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;OAAG,WAAWA,gCAAI;OAAe,UAAA,EAAE,gBAAgB,EAAE,IAAI,GAAG,CAAC;MAAK,CAAA;MACjE,QAAQ,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;OAAG,WAAWA,gCAAI;OAAO,MAAK;OAAU,UAAA,EAAE,cAAc,EAAE,SAAS,MAAM,CAAC;MAAK,CAAA,IAAI;MAE5F,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,WAAWA,gCAAI;OAApB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAACE,sCAAAA,QAAD;QACE,SAAQ;QACR,MAAK;QACL,UAAU,CAAC,SAAS;QACpB,SAAS;QAER,UAAA,EAAE,SAAS;OACN,CAAA,GACR,iBAAA,GAAA,kBAAA,IAAA,CAACA,sCAAAA,QAAD;QACE,SAAQ;QACR,MAAK;QACL,UAAU;QACV,SAAS;QAER,UAAA,SAAS,EAAE,QAAQ,IAAI,EAAE,MAAM;OAC1B,CAAA,CACL;;KACF;IACE,CAAA,CAAA;;EAEb;;;;ECvqBA,MAAa,oBAAoB;;;;;;;EA4EjC,SAAgB,UAAU,WAAmB,SAA0B;GACrE,MAAM,QAAQ,IAAI,gBAAgB,EAAE,SAAS,UAAU,CAAC;GACxD,IAAI,SAAS,MAAM,IAAI,WAAW,GAAG;GACrC,OAAO,GAAG,kBAAkB,WAAW,MAAM,SAAS;EACxD;;EAGA,MAAa,cAA2B,OAAO,WAAW,EAAE,cAAc;GACxE,MAAM,WAAW,MAAM,MAAM,UAAU,WAAW,OAAO,GAAG;IAC1D,QAAQ;IACR,aAAa;IACb,SAAS,EAAE,QAAQ,mBAAmB;GACxC,CAAC;GACD,MAAM,OAAgB,MAAM,SAAS,KAAK,CAAC,CAAC,YAAY,KAAA,CAAS;GACjE,IAAI,CAAC,SAAS,IAAI;IAChB,MAAM,UAAU,SAAS,IAAI,KAAK,OAAO,KAAK,UAAU,WAAW,KAAK,QAAQ,QAAQ,OAAO,SAAS,MAAM;IAC9G,MAAM,IAAI,MAAM,OAAO;GACzB;GACA,MAAM,UAAU,mBAAmB,MAAM,SAAS;GAClD,IAAI,YAAY,KAAA,GAAW,MAAM,IAAI,MAAM,gDAAgD;GAC3F,OAAO;EACT;;;;;;;;;EAUA,MAAa,eAAmC,YAAY;GAC1D,MAAM,WAAW,MAAM,MAAM,GAAG,kBAAkB,WAAW;IAC3D,QAAQ;IACR,aAAa;IACb,SAAS,EAAE,QAAQ,mBAAmB;GACxC,CAAC;GACD,MAAM,OAAgB,MAAM,SAAS,KAAK,CAAC,CAAC,YAAY,KAAA,CAAS;GACjE,IAAI,CAAC,SAAS,IAAI;IAChB,MAAM,UAAU,SAAS,IAAI,KAAK,OAAO,KAAK,UAAU,WAAW,KAAK,QAAQ,QAAQ,OAAO,SAAS,MAAM;IAC9G,MAAM,IAAI,MAAM,OAAO;GACzB;GACA,MAAM,YAAY,oBAAoB,IAAI;GAC1C,IAAI,cAAc,KAAA,GAAW,MAAM,IAAI,MAAM,+CAA+C;GAC5F,OAAO;EACT;;;;;;EAOA,SAAgB,oBAAoB,OAA4C;GAC9E,IAAI,CAAC,SAAS,KAAK,GAAG,OAAO,KAAA;GAC7B,OAAO;IACL,SAAS,MAAM,QAAQ,MAAM,OAAO,IAChC,MAAM,QAAQ,SAAS,UAAuB;KAC5C,IAAI,CAAC,SAAS,KAAK,KAAK,OAAO,MAAM,SAAS,YAAY,MAAM,SAAS,IAAI,OAAO,CAAC;KACrF,OAAO,CAAC;MACN,MAAM,MAAM;MACZ,MAAM,OAAO,MAAM,SAAS,WAAW,MAAM,OAAO;MACpD,WAAW,MAAM,cAAc;KACjC,CAAC;IACH,CAAC,IACD,CAAC;IACL,OAAO,IAAI,MAAM,KAAK;GACxB;EACF;;;;;;;;;;;EAYA,SAAgB,iBAAiB,SAAsC;GACrE,OAAO,KAAK,IAAI,GAAG,QAAQ,YAAY,QAAQ,eAAe;EAChE;EAEA,SAAS,SAAS,OAAkD;GAClE,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;EAC5E;EAEA,SAAS,IAAI,OAAwB;GACnC,OAAO,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,IAAI,QAAQ;EACvE;EAEA,SAAS,IAAI,OAAwB;GACnC,OAAO,OAAO,UAAU,WAAW,QAAQ;EAC7C;EAEA,SAAS,iBAAiB,OAAoC;GAC5D,IAAI,CAAC,MAAM,QAAQ,KAAK,GAAG,OAAO,CAAC;GACnC,OAAO,MAAM,SAAS,UAA8B,SAAS,KAAK,IAC9D,CAAC;IACC,MAAM,IAAI,MAAM,IAAI;IACpB,WAAW,IAAI,MAAM,SAAS;IAC9B,UAAU,IAAI,MAAM,QAAQ;IAC5B,OAAO,IAAI,MAAM,KAAK;GACxB,CAAC,IACD,CAAC,CAAC;EACR;EAEA,SAAS,aAAa,OAA+B;GACnD,IAAI,CAAC,MAAM,QAAQ,KAAK,GAAG,OAAO,CAAC;GACnC,OAAO,MAAM,SAAS,UAAyB;IAC7C,IAAI,CAAC,SAAS,KAAK,GAAG,OAAO,CAAC;IAC9B,MAAM,OAAO,IAAI,MAAM,IAAI;IAC3B,IAAI,SAAS,IAAI,OAAO,CAAC;IACzB,OAAO,CAAC;KACN;KACA,UAAU,IAAI,MAAM,QAAQ;KAC5B,OAAO,IAAI,MAAM,KAAK,KAAK;KAC3B,WAAW,IAAI,MAAM,SAAS;IAChC,CAAC;GACH,CAAC;EACH;;;;;;;;;;;;;;;;;;EAmBA,SAAgB,mBAAmB,OAAgB,WAA8C;GAC/F,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC,SAAS,MAAM,OAAO,GAAG,OAAO,KAAA;GACzD,MAAM,UAAU,MAAM;GACtB,MAAM,UAAU,MAAM,YAAY,QAC7B,OAAO,OAAO,OAAO,WAAW,KAChC,OAAO,OAAO,OAAO,cAAc;GACxC,OAAO;IACL,SAAS;KACP,WAAW,IAAI,QAAQ,SAAS,KAAK;KACrC,OAAO,QAAQ,UAAU;KACzB,WAAW,IAAI,QAAQ,SAAS;KAChC,iBAAiB,IAAI,QAAQ,eAAe;KAC5C,UAAU,QAAQ,aAAa;KAC/B,eAAe,IAAI,QAAQ,aAAa;KACxC,aAAa,QAAQ,gBAAgB;KACrC,UAAU,IAAI,QAAQ,QAAQ;KAC9B,UAAU,IAAI,QAAQ,QAAQ;KAC9B,QAAQ,IAAI,QAAQ,MAAM;KAC1B,aAAa,iBAAiB,QAAQ,WAAW;KACjD,OAAO,IAAI,QAAQ,KAAK;IAC1B;IACA,WAAW,IAAI,MAAM,SAAS;IAC9B,SAAS,UACL;KACE,WAAW,aAAa,MAAM,SAAS;KACvC,WAAW,aAAa,MAAM,SAAS;KACvC,cAAc,IAAI,MAAM,YAAY;KACpC,eAAe,IAAI,MAAM,aAAa;KACtC,WAAW,MAAM,cAAc;KAC/B,OAAO,IAAI,MAAM,YAAY;IAC/B,IACA,KAAA;GACN;EACF;;;;;;;;;;;;;;;EAgBA,SAAgB,YACd,UACA,MACe;GACf,IAAI,KAAK,YAAY,KAAA,GAAW,OAAO;IAAE,GAAG;IAAM,SAAS,UAAU;GAAQ;GAM7E,IAAI,KAAK,QAAQ,UAAU,MAAM,UAAU,YAAY,KAAA,GACrD,OAAO;IAAE,GAAG;IAAM,SAAS;KAAE,GAAG,SAAS;KAAS,OAAO,KAAK,QAAQ;IAAM;GAAE;GAEhF,OAAO;EACT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EClQA,MAAM,UAAU;;EAShB,SAAS,WAAW,SAAyB;GAC3C,IAAI,CAAC,OAAO,SAAS,OAAO,KAAK,WAAW,GAAG,OAAO;GACtD,OAAO,IAAI,KAAK,OAAO,CAAC,CAAC,mBAAmB;EAC9C;;;;;;;EAQA,SAAS,gBAAgB,OAAuB;GAC9C,OAAO,MAAM,UAAU,KAAK,MAAM,MAAM,GAAG,EAAE,CAAC,CAAC,QAAQ,KAAK,GAAG,IAAI;EACrE;;EAGA,SAAS,UAAU,UAA0B;GAC3C,KAAK,MAAM,QAAQ,SAAS,MAAM,IAAI,GAAG;IACvC,MAAM,UAAU,KAAK,QAAQ,eAAe,EAAE,CAAC,CAAC,KAAK;IACrD,IAAI,YAAY,IAAI,OAAO;GAC7B;GACA,OAAO;EACT;;EAGA,SAAS,MAAM,EAAE,OAAO,OAAO,MAAM,UAAU,QAAQ,KAOpD;GACD,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD;IAAI,WAAWC,8BAAI;IAAnB,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;KAAQ,MAAK;KAAS,WAAWA,8BAAI;KAAW,iBAAe;KAAM,SAAS;KAA9E,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;MAAM,WAAWA,8BAAI;MAAY,UAAA,MAAM;KAAW,CAAA,GAClD,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;MAAM,WAAWA,8BAAI;MAArB,UAAA;OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,WAAWA,8BAAI;QAAQ,UAAA;OAAY,CAAA;OACxC,MAAM,cAAc,KAAK,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,WAAWA,8BAAI;QAAY,UAAA,gBAAgB,MAAM,SAAS;OAAQ,CAAA,IAAI;OACtG,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,WAAWA,8BAAI;QAAc,UAAA,OAAO,EAAE,qBAAqB,IAAI,EAAE,mBAAmB;OAAQ,CAAA;MAC9F;KACA,CAAA,CAAA;IACP,CAAA,GAAA,OAEG,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;KAAK,WAAWA,8BAAI;KACjB,UAAA,MAAM,aAAa,KAChB,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;MAAG,WAAWA,8BAAI;MAAS,UAAA,EAAE,kBAAkB;KAAK,CAAA,IACpD,iBAAA,GAAA,kBAAA,IAAA,CAACC,sCAAAA,cAAD;MAAc,MAAM,MAAM;MAAkB;KAAS,CAAA;IACtD,CAAA,IAEL,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;KAAG,WAAWD,8BAAI;KAAe,UAAA,UAAU,MAAM,QAAQ;IAAK,CAAA,CAChE;;EAER;EAEA,SAAgB,WAAW,EAAE,WAAW,OAAO,KAAsB;GACnE,MAAM,CAAC,SAAS,eAAA,GAAcE,MAAAA,SAAAA,CAAoC,KAAA,CAAS;GAC3E,MAAM,CAAC,SAAS,eAAA,GAAcA,MAAAA,SAAAA,CAAS,IAAI;GAC3C,MAAM,CAAC,OAAO,aAAA,GAAYA,MAAAA,SAAAA,CAAS,EAAE;;;;;;GAMrC,MAAM,CAAC,WAAW,iBAAA,GAAgBA,MAAAA,SAAAA,CAA4C,CAAC,CAAC;;GAEhF,MAAM,CAAC,WAAW,iBAAA,GAAgBA,MAAAA,SAAAA,CAA6B,KAAA,CAAS;GAExE,MAAM,YAAY,EAAE,gBAAgB;GACpC,MAAM,cAAc,EAAE,kBAAkB;GACxC,MAAM,YAAY,EAAE,iBAAiB;GAGrC,MAAM,UAAA,GAASC,MAAAA,QAAAA,QACN;IAAE,MAAM;KAAE;KAAW;IAAY;IAAG;GAAU,IACrD;IAAC;IAAW;IAAa;GAAS,CACpC;;;;;;GAOA,MAAM,iBAAA,GAAgBC,MAAAA,OAAAA,CAAO,SAAS;GAEtC,MAAM,QAAA,GAAOC,MAAAA,YAAAA,CAAY,OAAO,YAAqB;IACnD,MAAM,gBAAgB,cAAc,YAAY;IAChD,IAAI;KACF,MAAM,OAAO,MAAM,MAAM,WAAW,EAAE,QAAQ,CAAC;KAC/C,IAAI,CAAC,QAAQ,GAAG;KAGhB,YAAY,aAAa,YAAY,UAAU,IAAI,CAAC;KACpD,SAAS,EAAE;KACX,IAAI,SAAS,aAAa,KAAK,QAAQ,eAAe;IACxD,SAAS,SAAS;KAChB,IAAI,CAAC,QAAQ,GAAG;KAChB,SAAS,mBAAmB,QAAQ,QAAQ,UAAU,OAAO,OAAO,CAAC;IACvE,UAAU;KACR,IAAI,QAAQ,GAAG,WAAW,KAAK;IACjC;GACF,GAAG,CAAC,OAAO,SAAS,CAAC;GAIrB,CAAA,GAAA,MAAA,UAAA,OAAgB;IACd,cAAc,UAAU;IACxB,WAAW,KAAA,CAAS;IACpB,aAAa,CAAC,CAAC;IACf,aAAa,KAAA,CAAS;IACtB,WAAW,IAAI;IACf,KAAU,IAAI;GAChB,GAAG,CAAC,MAAM,SAAS,CAAC;GAEpB,CAAA,GAAA,MAAA,UAAA,OAAgB;IACd,MAAM,QAAQ,kBAAkB;KAE9B,IAAI,OAAO,aAAa,eAAe,SAAS,oBAAoB,UAAU;KAC9E,KAAU,KAAK;IACjB,GAAG,OAAO;IACV,aAAa,cAAc,KAAK;GAClC,GAAG,CAAC,IAAI,CAAC;GAIT,CAAA,GAAA,MAAA,UAAA,OAAgB;IACd,MAAM,KAAK,SAAS,QAAQ;IAC5B,IAAI,OAAO,KAAA,KAAa,cAAc,KAAA,GAAW;IACjD,IAAI,OAAO,WAAW,KAAU,IAAI;GACtC,GAAG;IAAC,SAAS,QAAQ;IAAiB;IAAW;GAAI,CAAC;GAEtD,MAAM,UAAA,GAASA,MAAAA,YAAAA,EAAa,MAAc,SAAkB;IAC1D,cAAc,aAAa;KAAE,GAAG;MAAU,OAAO,CAAC;IAAK,EAAE;GAC3D,GAAG,CAAC,CAAC;GAEL,MAAM,UAAU,SAAS;GACzB,MAAM,UAAU,SAAS;GACzB,MAAM,YAAY,SAAS,aAAa,CAAC;GACzC,MAAM,YAAY,SAAS,aAAa,CAAC;GAMzC,MAAM,iBAAiB,SAAwB,SAC7C,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;IAAI,WAAWL,8BAAI;IAChB,UAAA,QAAQ,KAAK,UAAU;KACtB,MAAM,OAAO,UAAU,MAAM,UAAU;KACvC,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;MAES;MACP,OAAO,SAAS,YAAY,EAAE,cAAc,EAAE,OAAO,OAAO,MAAM,KAAK,EAAE,CAAC,IAAI,EAAE,gBAAgB;MAC1F;MACN,gBAAgB,OAAO,MAAM,MAAM,IAAI;MAC/B;MACL;KACJ,GAPM,MAAM,IAOZ;IAEL,CAAC;GACC,CAAA;GAGN,OAKE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;IAAK,WAAWA,8BAAI;IAAO,sCAAmC;IAC5D,UAAA,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;KAAK,WAAWA,8BAAI;KAApB,UAAA;MACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;OAAQ,WAAWA,8BAAI;OAAvB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;QAAI,WAAWA,8BAAI;QAAQ,UAAA,EAAE,aAAa;OAAM,CAAA,GAChD,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,8BAAI;QAApB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;SAAM,WAAWA,8BAAI;SAAU,UAAA,EAAE,mBAAmB,EAAE,MAAM,WAAW,SAAS,aAAa,CAAC,EAAE,CAAC;QAAQ,CAAA,GACzG,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,MAAK;SAAS,WAAWA,8BAAI;SAAS,eAAe;UAAE,KAAU,IAAI;SAAE;SAC5E,UAAA,EAAE,eAAe;QACZ,CAAA,CACL;OACC,CAAA,CAAA;;MAEP,UAAU,KAAK,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;OAAG,WAAWA,8BAAI;OAAO,MAAK;OAAU,UAAA,EAAE,oBAAoB,EAAE,SAAS,MAAM,CAAC;MAAK,CAAA,IAAI;MAExG,WAAW,YAAY,KAAA,IACpB,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;OAAG,WAAWA,8BAAI;OAAS,UAAA,EAAE,eAAe;MAAK,CAAA,IACjD,YAAY,KAAA,IACV,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;OAAG,WAAWA,8BAAI;OAAS,UAAA,EAAE,kBAAkB;MAAK,CAAA,IACpD,CAAC,QAAQ,QACP,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;OAAG,WAAWA,8BAAI;OAAS,UAAA,EAAE,eAAe;MAAK,CAAA,IAEjD,iBAAA,GAAA,kBAAA,IAAA,CAAC,WAAD;OAAS,WAAWA,8BAAI;OAAO,cAAY,EAAE,aAAa;OACxD,UAAA,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD;QAAI,WAAWA,8BAAI;QAAnB,UAAA;SACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;UAAK,WAAWA,8BAAI;UAApB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;WAAI,WAAWA,8BAAI;WAAQ,UAAA,EAAE,cAAc;UAAM,CAAA,GACjD,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;WAAI,WAAWA,8BAAI;WAAQ,UAAA,EAAE,kBAAkB,EAAE,KAAK,OAAO,QAAQ,SAAS,EAAE,CAAC;UAAM,CAAA,CACpF;;SACL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;UAAK,WAAWA,8BAAI;UAApB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;WAAI,WAAWA,8BAAI;WAAQ,UAAA,EAAE,oBAAoB;UAAM,CAAA,GACvD,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD;WAAI,WAAWA,8BAAI;WAAnB,UAAA,CACG,EAAE,kBAAkB,EAAE,KAAK,OAAO,QAAQ,eAAe,EAAE,CAAC,GAG7D,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;YAAM,WAAW,QAAQ,WAAWA,8BAAI,OAAOA,8BAAI;YAChD,UAAA,QAAQ,WACL,EAAE,gBAAgB,IAClB,EAAE,gBAAgB,EAAE,QAAQ,OAAO,iBAAiB,OAAO,CAAC,EAAE,CAAC;WAC/D,CAAA,CACJ;UACD,CAAA,CAAA;;SACL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;UAAK,WAAWA,8BAAI;UAApB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;WAAI,WAAWA,8BAAI;WAAQ,UAAA,EAAE,eAAe;UAAM,CAAA,GAClD,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;WAAI,WAAWA,8BAAI;WAAQ,UAAA,EAAE,sBAAsB,EAAE,QAAQ,OAAO,QAAQ,aAAa,EAAE,CAAC;UAAM,CAAA,CAC/F;;SACL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;UAAK,WAAWA,8BAAI;UAApB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;WAAI,WAAWA,8BAAI;WAAQ,UAAA,EAAE,mBAAmB;UAAM,CAAA,GACtD,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;WAAI,WAAWA,8BAAI;WAChB,UAAA,QAAQ,cAAc,EAAE,sBAAsB,IAAI,EAAE,qBAAqB;UACxE,CAAA,CACD;;SACL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;UAAK,WAAWA,8BAAI;UAApB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;WAAI,WAAWA,8BAAI;WAAQ,UAAA,EAAE,gBAAgB;UAAM,CAAA,GACnD,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;WAAI,WAAWA,8BAAI;WAAQ,UAAA,EAAE,uBAAuB,EAAE,OAAO,OAAO,QAAQ,QAAQ,EAAE,CAAC;UAAM,CAAA,CAC1F;;SACJ,QAAQ,WAAW,IAClB,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;UAAK,WAAWA,8BAAI;UAApB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;WAAI,WAAWA,8BAAI;WAAQ,UAAA,EAAE,gBAAgB;UAAM,CAAA,GACnD,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;WAAI,WAAWA,8BAAI;WAAQ,UAAA,OAAO,QAAQ,QAAQ;UAAM,CAAA,CACrD;SACH,CAAA,IAAA;QACF;;MACG,CAAA;MAGhB,YAAY,KAAA,MAAc,QAAQ,SAAS,KAAK,QAAQ,YAAY,SAAS,KAC5E,iBAAA,GAAA,kBAAA,KAAA,CAAC,WAAD;OAAS,WAAWA,8BAAI;OAAO,cAAY,EAAE,mBAAmB;OAAhE,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;QAAI,WAAWA,8BAAI;QAAa,UAAA,EAAE,mBAAmB;OAAM,CAAA,GAC3D,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD;QAAI,WAAWA,8BAAI;QAAnB,UAAA,CACG,QAAQ,YAAY,KAAK,MAAM,UAC9B,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD;SAA0C,WAAWA,8BAAI;SAAzD,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;UAAM,WAAWA,8BAAI;UAClB,UAAA,EAAE,oBAAoB;WAAE,MAAM,KAAK;WAAM,UAAU,OAAO,KAAK,QAAQ;UAAE,CAAC;SACvE,CAAA,GACL,KAAK,UAAU,KAAK,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;UAAM,WAAWA,8BAAI;UAAe,UAAA,KAAK;SAAY,CAAA,IAAI,IAC5E;QALK,GAAA,GAAG,KAAK,KAAK,GAAG,OAAO,KAAK,GAKjC,CACL,GACA,QAAQ,YAAY,WAAW,IAAI,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;SAAI,WAAWA,8BAAI;SAAU,UAAA,QAAQ;QAAU,CAAA,IAAI,IACrF;OACG,CAAA,CAAA;MACP,CAAA,IAAA;MAEH,YAAY,KAAA,KAAa,QAAQ,UAAU,KAC1C,iBAAA,GAAA,kBAAA,KAAA,CAAC,WAAD;OAAS,WAAWA,8BAAI;OAAO,cAAY,EAAE,oBAAoB;OAAjE,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;QAAI,WAAWA,8BAAI;QAAa,UAAA,EAAE,oBAAoB;OAAM,CAAA,GAC5D,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;QAAG,WAAWA,8BAAI;QAAO,MAAK;QAAU,UAAA,EAAE,uBAAuB,EAAE,SAAS,QAAQ,MAAM,CAAC;OAAK,CAAA,CACzF;MACP,CAAA,IAAA;MAEH,YAAY,KAAA,IACX,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA;OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,WAAD;QAAS,WAAWA,8BAAI;QAAO,cAAY,EAAE,sBAAsB;QAAnE,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD;SAAI,WAAWA,8BAAI;SAAnB,UAAA,CACG,EAAE,sBAAsB,GACzB,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;UAAM,WAAWA,8BAAI;UAClB,UAAA,EAAE,eAAe;WAAE,OAAO,OAAO,UAAU,MAAM;WAAG,OAAO,OAAO,QAAQ,YAAY;UAAE,CAAC;SACtF,CAAA,CACJ;QACH,CAAA,GAAA,UAAU,WAAW,IAClB,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;SAAG,WAAWA,8BAAI;SAAS,UAAA,EAAE,mBAAmB;QAAK,CAAA,IACrD,cAAc,WAAW,SAAS,CAC/B;;OAET,iBAAA,GAAA,kBAAA,KAAA,CAAC,WAAD;QAAS,WAAWA,8BAAI;QAAO,cAAY,EAAE,sBAAsB;QAAnE,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD;SAAI,WAAWA,8BAAI;SAAnB,UAAA,CACG,EAAE,sBAAsB,GACzB,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;UAAM,WAAWA,8BAAI;UAClB,UAAA,EAAE,eAAe;WAAE,OAAO,OAAO,UAAU,MAAM;WAAG,OAAO,OAAO,QAAQ,aAAa;UAAE,CAAC;SACvF,CAAA,CACJ;QACH,CAAA,GAAA,UAAU,WAAW,IAClB,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;SAAG,WAAWA,8BAAI;SAAS,UAAA,EAAE,mBAAmB;QAAK,CAAA,IACrD,cAAc,WAAW,UAAU,CAChC;;OAER,QAAQ,YAAY,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;QAAG,WAAWA,8BAAI;QAAO,UAAA,EAAE,iBAAiB;OAAK,CAAA,IAAI;OAC1E,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;QAAG,WAAWA,8BAAI;QAAO,UAAA,EAAE,YAAY;OAAK,CAAA;MAC5C,EAAA,CAAA,IACA;KACD;;GACF,CAAA;EAET;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EC7SA,MAAa,qBAAqB;;EAGlC,MAAa,oBAAoB;;;;;;;;;EA0CjC,SAAgB,kBAAkB,MAAgB,OAAoC;;GAEpF,IAAI;;GAEJ,IAAI;;GAEJ,IAAI,UAAU;;GAEd,IAAI,cAAc;GAClB,MAAM,0BAAU,IAAI,IAAY;;GAGhC,MAAM,WAAW,MAAc,aAAuE;IACpG,IAAI;KACF,OAAO,SAAS;IAClB,SAAS,OAAO;KACd,IAAI,CAAC,QAAQ,IAAI,IAAI,GAAG;MACtB,QAAQ,IAAI,IAAI;MAChB,MAAM,YAAY,MAAM,KAAK;KAC/B;KACA;IACF;GACF;;GAGA,MAAM,kBAAwB;IAC5B,IAAI,WAAW,eAAe,aAAa,KAAA,GAAW;IACtD,cAAc;IACd,IAAI;KACF,MAAM,UAAU,QAAQ,oBAAoB,MAAM,QAAQ;KAC1D,IAAI,YAAY,KAAA,GAAW;KAC3B,WAAW;KACX,MAAM,WAAW;KACjB,cAAc,KAAA;KACd,WAAW;IACb,UAAU;KACR,cAAc;IAChB;GACF;GAEA,UAAU;GAOV,MAAM,cAAc,KAAK,MAAM,OAAO,yBAAyB;IAC7D,IAAI,WAAW,aAAa,KAAA,KAAa,gBAAgB,KAAA,GAAW,aAAa,CAAC;IAClF,MAAM,UAAU,QAAQ,mBAAmB,MAAM,WAAW;IAC5D,IAAI,YAAY,KAAA,GAAW,aAAa,CAAC;IACzC,cAAc;IAId,IAAI,aAAa,KAAA,GAAW;KAC1B,cAAc,KAAA;KACd,QAAQ;KACR,aAAa,CAAC;IAChB;IACA,aAAa;KACX,MAAM,UAAU;KAChB,cAAc,KAAA;KACd,UAAU;IACZ;GACF,CAAC;GAED,MAAM,eAAe,KAAK,KAAK,uBAAuB;IAAE,UAAU;GAAE,CAAC;GAErE,aAAa;IACX,UAAU;IACV,eAAe;IACf,YAAY;IACZ,MAAM,kBAAkB;IACxB,WAAW,KAAA;IACX,kBAAkB;IAClB,MAAM,kBAAkB;IACxB,cAAc,KAAA;IACd,kBAAkB;GACpB;EACF;;;;ECzHA,MAAM,cAAc;EAEpB,MAAM,cAAc;EAEpB,SAAS,aAAsB;GAC7B,MAAM,QAAQ;GACd,IAAI,MAAM,iBAAiB,MAAM,OAAO;GACxC,MAAM,eAAe;GACrB,OAAO;EACT;EAEA,SAAS,eAAqB;GAC5B,OAAQ,WAAuC;EACjD;;;;;;;EAQA,MAAa,SAAS;GAAC;GAAS;GAAe;GAAU;GAAU;EAAgB;;EAGnF,SAAgB,MAAM,KAAoB;GACxC,IAAI,CAAC,WAAW,GAAG;GAMnB,MAAM,cAAc,IAAI,IAAI,aAAa;GACzC,MAAM,OAAO,YAAY,IAAiB,EAAE;GAM5C,MAAM,SAAS,IAAI,IAAI,QAAQ;GAC/B,IAAI,aAAa,OAAO,SAAS,IAAI;IAAE;IAAI;GAAG,CAAC,GAAG,8CAA8C;GAIhG,MAAM,IAAI,OAAO,KAAK,EAAE;GAExB,MAAM,mBAAkD,YAAY;IAClE,MAAM,WAAW,MAAM,IAAI,OAAO,QAAQ,aAAa;IACvD,IAAI,CAAC,SAAS,IAAI,MAAM,IAAI,MAAM,GAAG,SAAS,MAAM,KAAK,IAAI,SAAS,MAAM,SAAS;IACrF,OAAO;KACL,QAAQ,SAAS,MAAM;KACvB,SAAS,SAAS,MAAM,SAAS,SAAS;IAC5C;GACF;GAIA,MAAM,qBAAyC;GAC/C,MAAM,cAAc,WAAA,GAAkCM,MAAAA,cAAAA,CAAc,cAAc;IAChF,OAAO;IACP;IACA;IACA,GAAG;GACL,CAAC;GAKD,MAAM,aAAa,IAAI,aAAa,YAAY,YAAY,CAAC,EAAE,SAC7D,kBAAkB,KAAK;IACrB,gBAAgB,IAAI,MAAM,SACxB;KAAE,MAAM;KAAoB,KAAK;KAAa,QAAQ;IAAG,GACzD,UACF;IACA,mBAAmB,IAAI,MAAM,SAC3B;KAAE,MAAM;KAAmB,IAAI;KAAI,aAAa,EAAE,OAAO;KAAG,QAAQ;IAAG,GACvE,UACF;IACA,YAAY,MAAM,UAAU;KAC1B,QAAQ,KAAK,IAAI,YAAY,wCAAwC,KAAK,IAAI,KAAK;IACrF;GACF,CAAC,CACH,GAAG,kDAAkD;GAMrD,MAAM,uBAAuB,IAAI,MAAM,OAAO,2BAC5C,IAAI,MAAM,SACR;IACE,MAAM;IACN,IAAI;IAEJ,OAAO;IACP,QAAQ;IACR,aAAa,EAAE,YAAY;IAC3B,eAAe,EAAE,OAAO,YAAY;GACtC,GACA,UACF,CACF;GAEA,IAAI,mBAAmB;IACrB,WAAW;IACX,qBAAqB;IACrB,aAAa;GACf,CAAC;EACH"}
|
|
1
|
+
{"version":3,"file":"client.js","names":["useState","useMemo","useRef","useCallback","css","Input","Button","css","MarkdownText","useState","useMemo","useRef","useCallback","createElement"],"sources":["../src/client/consolidation-models.ts","../src/client/shelves.ts","../src/client/locales.ts","../src/client/SettingsCard.tsx","../src/client/memory-client.ts","../src/client/MemoryView.tsx","../src/client/plugin-card-seat.ts","../src/client/index.tsx"],"sourcesContent":["/**\n * Model-directory projection shared by the consolidation settings card.\n *\n * Two projections of the same data, deliberately kept apart: the CATALOG one\n * (every advertised route, in directory order, with a `selected` flag) is the\n * pool a user picks from, and the ORDERED one (the stored array as-is) is the\n * priority list consolidation actually reads. Directory order must never leak\n * into the latter — it did, and the card then showed a rotation order the\n * configuration did not have.\n */\n\nimport type { ModelProviderGroup } from '@deepseek-ai/dsh-api-remotes/client'\n\n/**\n * Adapter-owned reasoning metadata for one catalog model. Derived from the\n * catalog type rather than re-declared, so a change upstream cannot drift from\n * what the card renders: `efforts` is the vocabulary the adapter accepts, in its\n * own preferred display order, and `defaultEffort` (optional) is what the\n * adapter materializes when a caller omits an effort.\n */\nexport type ConsolidationModelReasoning = NonNullable<ModelProviderGroup['models'][number]['reasoning']>\n\n/** One exact provider/model route used for a consolidation attempt. */\nexport interface ConsolidationModelRoute {\n provider: string\n model: string\n /**\n * Optional thinking level for this route. Absent means \"follow the purpose\n * policy\", which is what every call did before the field existed: extraction\n * and adjudication ask for no reasoning where the route allows it, and the\n * archive call leaves the adapter's own default in place.\n *\n * The vocabulary is adapter-owned and opaque, so the card only ever offers\n * what this model's catalog entry declares.\n */\n reasoningEffort?: string\n}\n\n/** One catalog route, including stored routes no longer advertised by an adapter. */\nexport interface ConsolidationModelCandidate extends ConsolidationModelRoute {\n key: string\n providerName: string\n modelName: string\n available: boolean\n selected: boolean\n /** Absent for a route the catalog no longer advertises. */\n reasoning?: ConsolidationModelReasoning\n}\n\n/** One row of the thinking-level picker. */\nexport interface ReasoningEffortChoice {\n /** Stable key for React and for tests. */\n key: string\n /** Value to store; `undefined` means \"follow the purpose policy\". */\n effort: string | undefined\n /** Adapter-provided display name; the card supplies its own label when absent. */\n name?: string\n /** The stored value is no longer declared by this route. */\n stale?: boolean\n}\n\n/** One catalog response retained by the settings card. */\nexport interface ConsolidationModelCatalog {\n groups: readonly ModelProviderGroup[]\n partial: boolean\n}\n\n/** Load the current Host model directory for the settings card. */\nexport type LoadConsolidationModelCatalog = () => Promise<ConsolidationModelCatalog>\n\n/** Stable opaque key for one exact route. */\nexport function consolidationModelKey(route: ConsolidationModelRoute): string {\n return `${route.provider}\\0${route.model}`\n}\n\n/**\n * Move one entry of the priority list, returning a new array.\n *\n * The stored `consolidation.models` array IS the priority order, so this is the\n * only thing a reorder has to do: reorder the array. `to` is clamped instead of\n * rejected, so a click that cannot move anything (the first row's \"up\") is a\n * no-op rather than an error. A no-op returns the ORIGINAL reference, which lets\n * a caller use identity to skip the state update.\n *\n * @param models - Priority-ordered routes; not mutated.\n * @param from - Index to move.\n * @param to - Target index, clamped into `models`.\n */\nexport function moveConsolidationModel(\n models: ConsolidationModelRoute[],\n from: number,\n to: number,\n): ConsolidationModelRoute[] {\n if (!Number.isInteger(from) || from < 0 || from >= models.length) return models\n if (!Number.isFinite(to)) return models\n const target = Math.min(Math.max(0, Math.trunc(to)), models.length - 1)\n if (target === from) return models\n const next = [...models]\n const [moved] = next.splice(from, 1)\n next.splice(target, 0, moved)\n return next\n}\n\n/**\n * The stored routes in their configured (priority) order, each resolved to its\n * catalog entry for a display name, an availability flag and the reasoning\n * levels the route declares.\n *\n * `consolidationModelCandidates` already guarantees every stored route appears —\n * taken from the catalog, or appended as unavailable — so the candidate list is\n * a lookup table for this. A route that somehow is not in it is still shown,\n * named by its raw ids and marked unavailable, because dropping it from the\n * priority list would hide a configured route from the only UI that can remove\n * it.\n *\n * `reasoningEffort` is taken from the STORED route, never from the catalog: the\n * catalog describes what a model can do, the stored route is what the user chose.\n */\nexport function orderedConsolidationModels(\n stored: readonly ConsolidationModelRoute[],\n candidates: readonly ConsolidationModelCandidate[],\n): ConsolidationModelCandidate[] {\n const byKey = new Map(candidates.map(candidate => [candidate.key, candidate]))\n return stored.map((route) => {\n const key = consolidationModelKey(route)\n const base = byKey.get(key) ?? {\n ...route,\n key,\n providerName: route.provider,\n modelName: route.model,\n available: false,\n selected: true,\n }\n return { ...base, reasoningEffort: route.reasoningEffort }\n })\n}\n\n/**\n * The thinking-level options for one route, in the order they are offered.\n *\n * Two rules, both about not inventing a vocabulary this plugin does not own:\n *\n * - The list comes from the route's own declared `efforts`, in the adapter's\n * preferred order, labelled with the adapter's own names. Nothing is\n * hard-coded — the ids are opaque, and a level one adapter accepts is not one\n * another does.\n * - \"Follow the purpose policy\" (`undefined`) is always first and is what an\n * absent field stores. It is NOT the same as the adapter's `defaultEffort`:\n * omitting the field lets the plugin's own per-purpose policy apply, which for\n * extraction and adjudication means asking for no reasoning at all.\n *\n * A stored value the route no longer declares is appended and flagged rather\n * than dropped, so the card can show what is actually configured instead of\n * silently rewriting it — and so a route whose catalog entry disappeared still\n * displays its setting.\n *\n * @param reasoning - The route's catalog metadata; absent when the catalog does\n * not advertise the route, or the model declares no reasoning control.\n * @param stored - The configured value, if any.\n */\nexport function reasoningEffortChoices(\n reasoning: ConsolidationModelReasoning | undefined,\n stored: string | undefined,\n): ReasoningEffortChoice[] {\n const efforts = Array.isArray(reasoning?.efforts) ? reasoning.efforts : []\n const choices: ReasoningEffortChoice[] = [{ key: 'purpose', effort: undefined }]\n for (const effort of efforts) {\n const id = typeof effort?.id === 'string' ? effort.id : ''\n if (id === '') continue\n const name = typeof effort.name === 'string' && effort.name !== '' ? effort.name : id\n choices.push({ key: `effort:${id}`, effort: id, name })\n }\n const value = typeof stored === 'string' ? stored.trim() : ''\n if (value !== '' && !efforts.some(effort => effort?.id === value)) {\n choices.push({ key: `stale:${value}`, effort: value, stale: true })\n }\n return choices\n}\n\n/**\n * Join the live model directory with selected routes that disappeared from it.\n * Disappeared routes remain visible so users can remove them deliberately.\n */\nexport function consolidationModelCandidates(\n groups: readonly ModelProviderGroup[],\n stored: readonly ConsolidationModelRoute[],\n selected: ReadonlySet<string>,\n): ConsolidationModelCandidate[] {\n const storedByKey = new Map(stored.map(route => [consolidationModelKey(route), route]))\n const candidates = groups.flatMap(group => group.models.map((model): ConsolidationModelCandidate => {\n const route = { provider: group.id, model: model.id }\n const key = consolidationModelKey(route)\n storedByKey.delete(key)\n return {\n ...route,\n key,\n providerName: group.name,\n modelName: model.name,\n available: true,\n selected: selected.has(key),\n // The adapter-owned vocabulary this route accepts, straight from the\n // catalog the card already loaded — no extra request, and no client-side\n // guess at what \"low\" or \"high\" mean.\n ...model.reasoning === undefined ? {} : { reasoning: model.reasoning },\n }\n }))\n for (const route of storedByKey.values()) {\n const key = consolidationModelKey(route)\n candidates.push({\n ...route,\n key,\n providerName: route.provider,\n modelName: route.model,\n available: false,\n selected: selected.has(key),\n })\n }\n return candidates\n}\n","/**\n * Shelf choices for the settings card.\n *\n * The Host serves `hypatia list` from the Memory tab's route family\n * (`GET /api/dsh-hypatia-auto-memory/shelves`, see `src/memory-api.js`); the\n * fetch itself lives in `memory-client.ts`. Until dsh 0.1.7 this listing rode\n * a read-only settings namespace, which the settings overhaul removed.\n *\n * Zero runtime imports, so the parsing half is unit-tested under `node:test`.\n */\n\n/** Shelf hypatia uses when none is named. */\nexport const DEFAULT_SHELF = 'default'\n\n/** One shelf as `hypatia list` reports it. */\nexport interface ShelfInfo {\n name: string\n path: string\n connected: boolean\n}\n\n/** The Host's latest listing; `error` is non-empty when it could not list. */\nexport interface ShelfInventory {\n shelves: ShelfInfo[]\n error: string\n}\n\n/** Load the Host's latest listing for the settings card. */\nexport type LoadShelfInventory = () => Promise<ShelfInventory>\n\n/** One dropdown option. */\nexport interface ShelfChoice {\n name: string\n path: string\n /** False for a shelf that is registered but not connected. */\n connected: boolean\n /** False for a stored value the listing no longer reports. */\n listed: boolean\n}\n\n/**\n * Every shelf the dropdown offers: the listing, plus the stored and composed\n * values when the listing does not carry them, so the current choice always\n * renders and never silently changes to the first option.\n * @param shelves - the Host's listing.\n * @param keep - values that must stay selectable (current draft, stored, composed).\n * @returns options, listed shelves first in listing order.\n */\nexport function shelfChoices(shelves: readonly ShelfInfo[], keep: readonly string[]): ShelfChoice[] {\n const choices: ShelfChoice[] = shelves.map(shelf => ({ ...shelf, listed: true }))\n for (const name of keep) {\n if (name === '' || choices.some(choice => choice.name === name)) continue\n choices.push({ name, path: '', connected: false, listed: false })\n }\n return choices\n}\n","/** `hypatia-auto-memory` namespace dictionaries. */\n\n/** Dictionary namespace owned by this plugin. */\nexport const NS = 'hypatia-auto-memory'\n\n/** Simplified Chinese dictionary and key source of truth. */\nexport const zh = {\n loading: '正在加载 {ns} 设置…',\n unavailable: '当前上下文不可用 {ns} 设置。',\n title: 'Hypatia Auto Memory',\n description:\n '自动将对话轮次记录到 Hypatia,并在新内容足够多时通过独立模型路由进行后台整合。',\n enable: '启用自动记忆',\n autoApprove: '自动批准模型发起的 hypatia 命令',\n autoApproveHint: '仅限不含管道、重定向、命令串联的纯 hypatia 调用;插件自身的写入不经过此路径。关闭后模型每次检索都会弹出批准框。保存后采集器会自动重启以应用新值。',\n shelf: '记忆写入的 shelf',\n shelfHint: '插件的记录、整合与会话开始时的规则预加载都读写这个 shelf;不是 default 时,会话开头会提示模型为 hypatia 命令加上 --shelf。保存后采集器会自动重启,改写到新的 shelf。每个 shelf 的记录进度单独保存,切回原来的 shelf 会从上次的位置继续;切到新的 shelf 后,每个有活动的会话会把完整历史重新记录进去并整合一遍(会消耗模型调用)。列表来自 hypatia list,打开本页时按需读取。',\n shelfLoading: '正在读取 hypatia list…',\n shelfLoadFailed: '无法读取 shelf 列表。',\n shelfListingFailed: 'hypatia list 执行失败,列表可能已过时:{message}',\n shelfDisconnected: '未连接',\n shelfOptionStatus: '({status})',\n shelfNotListed: '不在 hypatia list 中',\n shelfDisconnectedWarning: 'shelf {shelf} 已注册但未连接,写入会失败。',\n shelfNotListedWarning: 'hypatia 没有注册 shelf {shelf},写入会失败;请先执行 hypatia connect <目录> --name {shelf}。',\n consolidationTitle: '整合候选模型',\n modelSelectionHint: '选择一个或多个模型并决定优先级。列表自上而下即优先级:每次整合先用最上面那条,该次尝试失败时,重试会依次降级到下一条(可用的备选条数受队列重试次数限制)。未选择时只记录对话,不执行整合。',\n modelCatalogLoading: '正在读取可用模型…',\n modelCatalogFailed: '无法读取可用模型。',\n modelCatalogPartial: '部分提供方未能返回模型目录。',\n modelCatalogEmpty: '当前没有可选择的模型。',\n selectedModels: '优先级顺序(自上而下)',\n selectedModelsEmpty: '还没有选择模型。',\n availableModels: '可选模型',\n unavailableModels: '不可用或未再声明的模型',\n modelUnavailable: '当前不可用',\n moveUp: '上移',\n moveDown: '下移',\n remove: '移除',\n reasoningEffort: '思考程度',\n reasoningFollowPurpose: '跟随用途策略',\n reasoningUnavailable: '该路由未声明思考档位,无法设置',\n reasoningStale: '该路由已不再声明',\n reasoningDefault: '未指定时该路由默认为:{effort}',\n reasoningBudgetHint: '思考程度决定该模型思考多久。选「跟随用途策略」时,摘要与裁决会尽量关闭思考(两者都是机械变换,思考只花掉输出预算),归档则沿用模型自己的默认档位。显式选了档位就会覆盖上述策略;非关闭档位与正文共用输出预算,插件会自动追加余量,但高强度档位仍建议同步调大输出预算。档位由模型自己声明,未声明的值会在调用时被忽略并记一条警告。',\n retry: '重试',\n checkEveryTurns: '两次整合至少间隔 N 轮',\n minNewTokens: '最小新增 token 数',\n cascadeBatchSize: '归档批量',\n dedupMaxDistance: '关联距离上限',\n cascadeHint: '每积累这么多同层摘要,就归档为上一层的一条;关联距离上限决定新记忆要多接近既有条目才值得判定关系。',\n limitsTitle: '单次整合体量',\n limitsHint: '输入预算决定送入模型的对话长度(超出部分截断保留最近内容);输出预算需容纳摘要与全部工作单元,过小会导致整合失败。',\n maxInputTokens: '输入预算(token)',\n maxOutputTokens: '输出预算(token)',\n maxWorkUnitsPerRun: '每次最多提取工作单元数',\n recallPreload: '召回:会话开始时预加载规则与禁忌',\n advancedHint:\n '高级字段(二进制、收集器上限、队列调优)可在「设置 → 插件」的本插件页,或 profile patch 的 {ns} 条目 config 下编辑。',\n reset: '重置',\n discard: '放弃',\n save: '保存',\n saving: '保存中…',\n saveFailed: '保存失败:{message}',\n readOnly: '只读:当前上下文不可写入设置文档。',\n unsaved: '未保存',\n viewMemory: '记忆',\n memoryTitle: '本会话的记忆',\n memoryUpdatedAt: '状态更新于 {time}',\n memoryRefresh: '刷新',\n memoryLoading: '正在读取记忆状态…',\n memoryNoSnapshot: '插件还没有发布记忆状态。启用后完成一轮对话再回来看看。',\n memoryLoadFailed: '无法读取记忆状态:{message}',\n memoryUnknown: '这个会话还没有记忆记录。第一轮对话结束后会开始记录。',\n memoryLogged: '对话记录',\n memorySeqValue: '第 {seq} 条事件',\n memoryConsolidated: '摘要整合',\n memoryCaughtUp: '已结清',\n memoryBehind: '较记录落后 {behind} 条',\n memoryPending: '待整合内容',\n memoryPendingValue: '约 {tokens} token',\n memorySessionNode: '会话节点',\n memorySessionNodeYes: '已建立',\n memorySessionNodeNo: '未建立(宿主未提供会话摘要)',\n memoryBelongTo: '已链接消息',\n memoryBelongToValue: '{count} 条',\n memoryDeferred: '等待会话载入的任务',\n memoryFailedTitle: '失败任务',\n memoryFailedItem: '{kind} 连续失败 {attempts} 次',\n memoryContentTitle: '记忆内容',\n memoryContentFailed: '无法读取 shelf 中的记忆内容:{message}',\n memorySummariesTitle: '跨度摘要',\n memoryWorkUnitsTitle: '工作单元',\n memoryNoSummaries: '这个会话还没有产生摘要。整合运行后会出现在这里。',\n memoryNoWorkUnits: '这个会话还没有提炼出工作单元。',\n memoryCount: '显示 {shown} / 共 {total}',\n memoryTier: '{level} 级',\n memoryWorkUnit: '工作单元',\n memoryEntryExpand: '展开',\n memoryEntryCollapse: '收起',\n memoryEntryEmpty: '这条条目的正文为空,或已超过展示上限。',\n memoryCopyCode: '复制',\n memoryCopiedCode: '已复制',\n memoryFootnotes: '脚注',\n memoryTruncated: '内容超出展示上限,较早的条目或过长的正文已被截断。',\n memoryHint: '诊断视图:原始 msg-* 对话正文不在此显示,需要时让 Agent 通过 hypatia 检索。状态每 5 秒重读一次;「状态更新于」是宿主最近一次看到这些状态发生变化的时间(首次读取也算一次),不变说明这段时间没有新进展。两个条数都按会话日志的事件序号计(含工具调用,不是消息条数),所以它们之差就是还没总结的部分。',\n} as const satisfies Record<string, string>\n\n/** Key domain of the `hypatia-auto-memory` namespace. */\nexport type AutoMemoryLocaleKey = keyof typeof zh\n\n/** English dictionary checked against the Chinese key set. */\nexport const en = {\n loading: 'Loading {ns} settings…',\n unavailable: '{ns} settings are not available in this context.',\n title: 'Hypatia Auto Memory',\n description:\n 'Auto-memory logs conversation turns into Hypatia and runs background consolidation on a dedicated model route.',\n enable: 'Enable auto-memory',\n autoApprove: \"Auto-approve the agent's own hypatia commands\",\n autoApproveHint: 'Only plain hypatia calls with no pipe, redirect or chaining; this plugin\\'s own writes never take that path. With it off, every retrieval raises an approval prompt. Saving a change restarts the collector to apply it.',\n shelf: 'Memory shelf',\n shelfHint: 'Logging, consolidation and the session-start rules preload all read and write this shelf; when it is not default, each session is told to pass --shelf to its hypatia commands. Saving a change restarts the collector on the new shelf. Progress is kept per shelf, so switching back resumes where that shelf left off; on a new shelf, each session is logged from its start the next time it is active, and consolidated again (model calls). Choices come from hypatia list, read on demand when this page opens.',\n shelfLoading: 'Reading hypatia list…',\n shelfLoadFailed: 'Unable to load the shelf list.',\n shelfListingFailed: 'hypatia list failed; the list may be stale: {message}',\n shelfDisconnected: 'not connected',\n shelfOptionStatus: ' ({status})',\n shelfNotListed: 'not in hypatia list',\n shelfDisconnectedWarning: 'Shelf {shelf} is registered but not connected; writes will fail.',\n shelfNotListedWarning: 'hypatia has no shelf named {shelf}; writes will fail until you run hypatia connect <dir> --name {shelf}.',\n consolidationTitle: 'Consolidation candidate models',\n modelSelectionHint: 'Choose one or more models and set their priority. The list is read top-down: every consolidation starts on the first route, and each failed attempt degrades to the next one (how many fallbacks a task can reach is bounded by the queue\\'s retry limit). Without a selection, conversations continue logging but consolidation stays idle.',\n modelCatalogLoading: 'Loading available models…',\n modelCatalogFailed: 'Unable to load available models.',\n modelCatalogPartial: 'Some providers did not return a model catalog.',\n modelCatalogEmpty: 'No models are currently available.',\n selectedModels: 'Priority order (top first)',\n selectedModelsEmpty: 'No model selected yet.',\n availableModels: 'Available models',\n unavailableModels: 'Unavailable or no longer advertised',\n modelUnavailable: 'Unavailable',\n moveUp: 'Move up',\n moveDown: 'Move down',\n remove: 'Remove',\n reasoningEffort: 'Reasoning effort',\n reasoningFollowPurpose: 'Follow the purpose policy',\n reasoningUnavailable: 'This route declares no reasoning levels',\n reasoningStale: 'no longer declared by this route',\n reasoningDefault: 'Without one, this route defaults to: {effort}',\n reasoningBudgetHint: 'Reasoning effort is how long the model may think. On \"follow the purpose policy\", summaries and adjudication ask for no reasoning where the route allows it — both are mechanical transforms, so thinking only spends the output budget — while the archive call keeps the model\\'s own default. Choosing a level explicitly overrides that policy; any level other than off shares the output budget with the answer, so the plugin adds its thinking allowance, and a high level is still worth pairing with a larger output budget. Levels are declared by the model itself, and one it does not declare is dropped at call time with a warning.',\n retry: 'Retry',\n checkEveryTurns: 'Minimum turns between consolidations',\n minNewTokens: 'Min new tokens',\n cascadeBatchSize: 'Archive batch',\n dedupMaxDistance: 'Relation distance',\n cascadeHint: 'Every batch of same-tier summaries is archived into one entry a tier up. Relation distance is how near a new memory must be to an existing one to be worth judging a relationship.',\n limitsTitle: 'Per-run consolidation size',\n limitsHint: 'The input budget caps how much conversation is sent to the model (overflow keeps the most recent content); the output budget must fit the summary plus every work unit — too small and consolidation fails.',\n maxInputTokens: 'Input budget (tokens)',\n maxOutputTokens: 'Output budget (tokens)',\n maxWorkUnitsPerRun: 'Max work units per run',\n recallPreload: 'Recall: preload rules & taboos at session start',\n advancedHint:\n 'Advanced fields (binaries, collector caps, queue tuning) can be edited in Settings → Plugins under this plugin, or under the {ns} entry\\'s config in the profile patch.',\n reset: 'Reset',\n discard: 'Discard',\n save: 'Save',\n saving: 'Saving…',\n saveFailed: 'Save failed: {message}',\n readOnly: 'Read-only: settings document is not writable in this context.',\n unsaved: 'Unsaved',\n viewMemory: 'Memory',\n memoryTitle: 'This session\\'s memory',\n memoryUpdatedAt: 'State updated {time}',\n memoryRefresh: 'Refresh',\n memoryLoading: 'Reading memory status…',\n memoryNoSnapshot: 'The plugin has not published a status snapshot yet. Enable it, finish a turn, and come back.',\n memoryLoadFailed: 'Unable to read memory status: {message}',\n memoryUnknown: 'This session has no memory record yet. Logging starts once the first turn ends.',\n memoryLogged: 'Conversation log',\n memorySeqValue: 'event {seq}',\n memoryConsolidated: 'Summarisation',\n memoryCaughtUp: 'caught up',\n memoryBehind: '{behind} events behind the log',\n memoryPending: 'Waiting to summarise',\n memoryPendingValue: '~{tokens} tokens',\n memorySessionNode: 'Session node',\n memorySessionNodeYes: 'created',\n memorySessionNodeNo: 'not created (the Host supplied no session summary)',\n memoryBelongTo: 'Linked messages',\n memoryBelongToValue: '{count}',\n memoryDeferred: 'Tasks waiting for the session to load',\n memoryFailedTitle: 'Failed tasks',\n memoryFailedItem: '{kind} failed {attempts} times',\n memoryContentTitle: 'Memory content',\n memoryContentFailed: 'Unable to read memory content from the shelf: {message}',\n memorySummariesTitle: 'Span summaries',\n memoryWorkUnitsTitle: 'Work units',\n memoryNoSummaries: 'This session has produced no summary yet. They appear here once consolidation runs.',\n memoryNoWorkUnits: 'This session has yielded no work units yet.',\n memoryCount: 'showing {shown} of {total}',\n memoryTier: 'tier {level}',\n memoryWorkUnit: 'work unit',\n memoryEntryExpand: 'Expand',\n memoryEntryCollapse: 'Collapse',\n memoryEntryEmpty: 'This entry has no body, or it exceeded the display cap.',\n memoryCopyCode: 'Copy',\n memoryCopiedCode: 'Copied',\n memoryFootnotes: 'Footnotes',\n memoryTruncated: 'Content exceeded the display cap: earlier entries or over-long bodies were cut.',\n memoryHint: 'Diagnostic view: raw msg-* conversation text is not shown here — ask the agent to retrieve it through hypatia. Status is re-read every 5 seconds; the timestamp is when the Host last saw that state change (the first read counts as one), so an unchanged one means nothing new happened. Both counts index the session log\\'s event sequence (tool calls included, not messages), so their difference is what is left to summarise.',\n} satisfies Record<AutoMemoryLocaleKey, string>\n","/**\n * Configuration card for the `hypatia-auto-memory` namespace, rendered on\n * whichever seat the harness offers (see `plugin-card-seat.ts`).\n *\n * The card owns its disclosure state and stages edits until Save. Its visual\n * treatment mirrors the DSH plugin-settings cards while remaining bundle-local.\n */\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport { Button, Input } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { SettingsPathOpView } from '@deepseek-ai/dsh-api-remotes/client'\nimport type { ConfigForm, ConfigFormSnapshot } from '@deepseek-ai/dsh-client-ui-settings/client'\nimport {\n consolidationModelCandidates,\n consolidationModelKey,\n moveConsolidationModel,\n orderedConsolidationModels,\n reasoningEffortChoices,\n type ConsolidationModelCandidate,\n type ConsolidationModelRoute,\n type LoadConsolidationModelCatalog,\n type ReasoningEffortChoice,\n} from './consolidation-models'\nimport { DEFAULT_SHELF, shelfChoices, type LoadShelfInventory, type ShelfInfo } from './shelves'\nimport css from './SettingsCard.module.css'\nimport { NS } from './locales'\nimport './slot-contract'\n\nconst DEFAULT_CONSOLIDATION = {\n models: [] as ConsolidationModelRoute[],\n maxInputTokens: 16000,\n maxOutputTokens: 2000,\n timeoutMs: 120000,\n checkEveryTurns: 5,\n minNewTokens: 3000,\n maxWorkUnitsPerRun: 3,\n adjudicate: true,\n dedupMaxDistance: 0.45,\n cascade: { enabled: true, batchSize: 16 },\n}\n\nexport interface ConfigShape {\n enabled?: boolean\n autoApprove?: boolean\n shelf?: string\n consolidation?: typeof DEFAULT_CONSOLIDATION\n recall?: { preloadRulesTaboos?: boolean }\n}\n\n/** JSON value one `set` operation carries; the draft's fields are JSON-shaped. */\ntype FieldValue = Extract<SettingsPathOpView, { op: 'set' }>['value']\n\nfunction getSnapshotValue<T>(form: ConfigForm<T>): ConfigFormSnapshot<T> {\n return form.getSnapshot()\n}\n\nfunction subscribe(form: ConfigForm<unknown>, cb: () => void) {\n return form.subscribe(cb)\n}\n\nfunction sectionValue<T>(snap: ConfigFormSnapshot<T>): T | undefined {\n return snap.value ?? (snap.base as T | undefined) ?? undefined\n}\n\nfunction useScopeValue<T>(form: ConfigForm<T>) {\n const [snap, setSnap] = useState(() => getSnapshotValue(form))\n useEffect(() => {\n setSnap(getSnapshotValue(form))\n return subscribe(form as ConfigForm<unknown>, () => setSnap(getSnapshotValue(form)))\n }, [form])\n const value = useMemo(() => sectionValue(snap), [snap])\n return { snap, value }\n}\n\nfunction same(a: unknown, b: unknown): boolean {\n return JSON.stringify(a) === JSON.stringify(b)\n}\n\nexport type SettingsCardProps = {\n scope: ConfigForm<ConfigShape>\n loadModelCatalog: LoadConsolidationModelCatalog\n loadShelfInventory: LoadShelfInventory\n} & PropsLocale<typeof NS>\n\nexport function SettingsCard({ scope, loadModelCatalog, loadShelfInventory, t }: SettingsCardProps) {\n const { snap, value } = useScopeValue(scope)\n const disabled = !snap.writable\n const base = useMemo(() => (snap.base ?? {}) as ConfigShape, [snap.base])\n\n const resolved: ConfigShape = useMemo(() => (value ?? base ?? {\n enabled: true,\n autoApprove: true,\n shelf: DEFAULT_SHELF,\n consolidation: DEFAULT_CONSOLIDATION,\n recall: { preloadRulesTaboos: true },\n }), [value, base])\n\n const [draft, setDraft] = useState(resolved)\n const [saving, setSaving] = useState(false)\n const [error, setError] = useState<string | null>(null)\n const [catalogStatus, setCatalogStatus] = useState<'idle' | 'loading' | 'ready' | 'error'>('idle')\n const [catalogGroups, setCatalogGroups] = useState<Parameters<typeof consolidationModelCandidates>[0]>([])\n const [catalogPartial, setCatalogPartial] = useState(false)\n const catalogGeneration = useRef(0)\n const [shelfStatus, setShelfStatus] = useState<'idle' | 'loading' | 'ready' | 'error'>('idle')\n const [shelves, setShelves] = useState<ShelfInfo[]>([])\n const [shelfListingError, setShelfListingError] = useState('')\n const shelfGeneration = useRef(0)\n\n useEffect(() => {\n setDraft(resolved)\n }, [resolved])\n\n const dirty = useMemo(() => !same(draft, resolved), [draft, resolved])\n const consolidation = draft.consolidation ?? DEFAULT_CONSOLIDATION\n const recall = draft.recall ?? { preloadRulesTaboos: true }\n const saveBlocked = disabled || !dirty || saving\n\n const updateConsolidation = useCallback((patch: Partial<typeof DEFAULT_CONSOLIDATION>) => {\n setDraft((prev) => ({\n ...prev,\n consolidation: { ...(prev.consolidation ?? DEFAULT_CONSOLIDATION), ...patch },\n }))\n }, [])\n\n const loadCatalog = useCallback(async () => {\n const generation = ++catalogGeneration.current\n setCatalogStatus('loading')\n setCatalogPartial(false)\n try {\n const catalog = await loadModelCatalog()\n if (generation !== catalogGeneration.current) return\n setCatalogGroups(catalog.groups)\n setCatalogPartial(catalog.partial)\n setCatalogStatus('ready')\n } catch {\n if (generation !== catalogGeneration.current) return\n setCatalogStatus('error')\n }\n }, [loadModelCatalog])\n\n // The tab panel mounts the card when the tab is first shown, so \"on mount\"\n // is \"when the user opens this plugin's settings\".\n useEffect(() => {\n void loadCatalog()\n return () => { catalogGeneration.current += 1 }\n }, [loadCatalog])\n\n const loadShelves = useCallback(async () => {\n const generation = ++shelfGeneration.current\n setShelfStatus('loading')\n try {\n const inventory = await loadShelfInventory()\n if (generation !== shelfGeneration.current) return\n setShelves(inventory.shelves)\n setShelfListingError(inventory.error)\n setShelfStatus('ready')\n } catch {\n if (generation !== shelfGeneration.current) return\n setShelfStatus('error')\n }\n }, [loadShelfInventory])\n\n useEffect(() => {\n void loadShelves()\n return () => { shelfGeneration.current += 1 }\n }, [loadShelves])\n\n const draftShelf = draft.shelf ?? DEFAULT_SHELF\n const baseShelf = base.shelf ?? DEFAULT_SHELF\n const choices = useMemo(\n () => shelfChoices(shelves, [draftShelf, resolved.shelf ?? DEFAULT_SHELF, baseShelf]),\n [shelves, draftShelf, resolved.shelf, baseShelf],\n )\n const chosen = choices.find(choice => choice.name === draftShelf)\n\n const candidates = useMemo(() => {\n const models = consolidation.models ?? []\n return consolidationModelCandidates(\n catalogGroups,\n models,\n new Set(models.map(consolidationModelKey)),\n )\n }, [catalogGroups, consolidation.models])\n\n // The draft's own order, NOT the catalog's: this list is what the Host reads\n // as the priority order, so it has to show the stored array verbatim.\n const selectedModels = useMemo(\n () => orderedConsolidationModels(consolidation.models ?? [], candidates),\n [consolidation.models, candidates],\n )\n\n const toggleModel = useCallback((candidate: ConsolidationModelCandidate) => {\n if (disabled || saving) return\n setDraft((current) => {\n const currentConsolidation = current.consolidation ?? DEFAULT_CONSOLIDATION\n const currentModels = currentConsolidation.models ?? []\n const key = consolidationModelKey(candidate)\n const selected = currentModels.some(route => consolidationModelKey(route) === key)\n const models = selected\n ? currentModels.filter(route => consolidationModelKey(route) !== key)\n : [...currentModels, { provider: candidate.provider, model: candidate.model }]\n return {\n ...current,\n consolidation: { ...currentConsolidation, models },\n }\n })\n }, [disabled, saving])\n\n /**\n * Reorder one entry of the priority list. A no-op move leaves the draft\n * untouched (the mover returns the original array), so the \"unsaved\" badge\n * does not light up for a click that changed nothing.\n */\n const moveModel = useCallback((from: number, to: number) => {\n if (disabled || saving) return\n setDraft((current) => {\n const currentConsolidation = current.consolidation ?? DEFAULT_CONSOLIDATION\n const currentModels = currentConsolidation.models ?? []\n const models = moveConsolidationModel(currentModels, from, to)\n if (models === currentModels) return current\n return {\n ...current,\n consolidation: { ...currentConsolidation, models },\n }\n })\n }, [disabled, saving])\n\n /**\n * Set or clear one route's thinking level. Clearing REMOVES the key rather\n * than storing `undefined`, so the saved patch carries only what the user\n * chose and nothing reading the profile can confuse \"not configured\" with\n * \"configured as nothing\".\n */\n const setModelEffort = useCallback((index: number, effort: string | undefined) => {\n if (disabled || saving) return\n setDraft((current) => {\n const currentConsolidation = current.consolidation ?? DEFAULT_CONSOLIDATION\n const currentModels = currentConsolidation.models ?? []\n if (index < 0 || index >= currentModels.length) return current\n const models = currentModels.map((route, at) => {\n if (at !== index) return route\n if (effort === undefined) {\n const cleared = { ...route }\n delete cleared.reasoningEffort\n return cleared\n }\n return { ...route, reasoningEffort: effort }\n })\n return {\n ...current,\n consolidation: { ...currentConsolidation, models },\n }\n })\n }, [disabled, saving])\n\n /** Display label for one thinking-level option, in the card's own words. */\n const effortChoiceLabel = useCallback((choice: ReasoningEffortChoice): string => {\n if (choice.effort === undefined) return t('reasoningFollowPurpose')\n const name = choice.name ?? choice.effort\n // A value the route no longer declares is shown, not hidden: rewriting the\n // user's configuration behind their back is worse than showing a stale one.\n return choice.stale === true ? `${name} · ${t('reasoningStale')}` : name\n }, [t])\n\n /**\n * What the adapter does when no effort is sent. Only a hint: this plugin\n * cannot pin it, because omitting the field is what lets its own per-purpose\n * policy apply.\n */\n const routeDefaultLabel = useCallback((candidate: ConsolidationModelCandidate): string | undefined => {\n const reasoning = candidate.reasoning\n const fallback = reasoning?.defaultEffort\n if (reasoning === undefined || fallback === undefined) return undefined\n const named = reasoning.efforts.find(effort => effort.id === fallback)\n return t('reasoningDefault', { effort: named?.name ?? fallback })\n }, [t])\n\n const discard = useCallback(() => {\n setDraft(resolved)\n setError(null)\n }, [resolved])\n\n const save = useCallback(async () => {\n if (saveBlocked) return\n setSaving(true)\n setError(null)\n try {\n const ops: SettingsPathOpView[] = []\n const setField = (field: keyof ConfigShape, value: unknown) => {\n ops.push({ op: 'set', path: [field], value: value as FieldValue })\n }\n if (!same(draft.enabled, resolved.enabled)) setField('enabled', draft.enabled)\n if (!same(draft.autoApprove, resolved.autoApprove)) setField('autoApprove', draft.autoApprove)\n if (!same(draft.shelf, resolved.shelf)) setField('shelf', draft.shelf)\n if (!same(draft.consolidation, resolved.consolidation)) setField('consolidation', draft.consolidation)\n if (!same(draft.recall, resolved.recall)) setField('recall', draft.recall)\n // One atomic mutation: the Host validates and commits every changed\n // field together, so a refusal (a concurrent edit, a value the schema\n // rejects) saves nothing rather than half the form. ConfigForm resolves\n // false on refusal instead of rejecting, and reloads the saved values.\n if (ops.length > 0 && !await scope.mutate(ops)) {\n throw new Error('the Host refused the change; nothing was saved')\n }\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err)\n // eslint-disable-next-line no-console\n console.error(`[${NS}] save failed:`, err)\n setError(message)\n } finally {\n setSaving(false)\n }\n }, [draft, resolved, saveBlocked, scope])\n\n if (snap.status === 'loading') {\n return <p className={css.status}>{t('loading', { ns: NS })}</p>\n }\n if (snap.status === 'unavailable') {\n return <p className={css.status}>{t('unavailable', { ns: NS })}</p>\n }\n\n const availableGroups = new Map<string, {\n providerName: string\n candidates: ConsolidationModelCandidate[]\n }>()\n const unavailable: ConsolidationModelCandidate[] = []\n for (const candidate of candidates) {\n if (!candidate.available) {\n unavailable.push(candidate)\n continue\n }\n const group = availableGroups.get(candidate.provider)\n if (group === undefined) {\n availableGroups.set(candidate.provider, {\n providerName: candidate.providerName,\n candidates: [candidate],\n })\n } else {\n group.candidates.push(candidate)\n }\n }\n\n const renderCandidate = (candidate: ConsolidationModelCandidate) => (\n <label key={candidate.key} className={css.model}>\n <input\n type=\"checkbox\"\n checked={candidate.selected}\n disabled={disabled || saving}\n onChange={() => toggleModel(candidate)}\n />\n <span>\n <span className={css.modelName}>{candidate.modelName}</span>\n <span className={css.route}>{`${candidate.providerName} · ${candidate.provider}/${candidate.model}`}</span>\n </span>\n {!candidate.available ? <span className={css.unavailable}>{t('modelUnavailable')}</span> : null}\n </label>\n )\n\n return (\n <section className={css.card} aria-label={t('title')}>\n <div className={css.header}>\n <span className={css.headText}>\n <span className={css.name}>{t('title')}</span>\n <span className={css.description}>{t('description')}</span>\n </span>\n {dirty ? <span className={css.pending}>{t('unsaved')}</span> : null}\n </div>\n\n <div className={css.body}>\n {!snap.writable ? <p className={css.readOnly} role=\"status\">{t('readOnly')}</p> : null}\n\n <div className={css.field}>\n <div className={css.fieldHead}>\n <label className={css.label} htmlFor=\"ham-enabled\">{t('enable')}</label>\n {draft.enabled !== (base.enabled ?? true) ? (\n <button\n type=\"button\"\n className={css.reset}\n disabled={disabled}\n onClick={() => setDraft((current) => ({ ...current, enabled: base.enabled ?? true }))}\n >\n {t('reset')}\n </button>\n ) : null}\n </div>\n <button\n id=\"ham-enabled\"\n type=\"button\"\n role=\"switch\"\n aria-checked={draft.enabled ?? true}\n aria-label={t('enable')}\n className={`${css.switch} ${draft.enabled ?? true ? css.switchOn : ''}`}\n disabled={disabled}\n onClick={() => setDraft((current) => ({ ...current, enabled: !(current.enabled ?? true) }))}\n >\n <span className={css.switchThumb} />\n </button>\n </div>\n\n <div className={css.field}>\n <div className={css.fieldHead}>\n <label className={css.label} htmlFor=\"ham-autoApprove\">{t('autoApprove')}</label>\n {(draft.autoApprove ?? true) !== (base.autoApprove ?? true) ? (\n <button\n type=\"button\"\n className={css.reset}\n disabled={disabled}\n onClick={() => setDraft((current) => ({ ...current, autoApprove: base.autoApprove ?? true }))}\n >\n {t('reset')}\n </button>\n ) : null}\n </div>\n <button\n id=\"ham-autoApprove\"\n type=\"button\"\n role=\"switch\"\n aria-checked={draft.autoApprove ?? true}\n aria-label={t('autoApprove')}\n className={`${css.switch} ${draft.autoApprove ?? true ? css.switchOn : ''}`}\n disabled={disabled}\n onClick={() => setDraft((current) => ({ ...current, autoApprove: !(current.autoApprove ?? true) }))}\n >\n <span className={css.switchThumb} />\n </button>\n <p className={css.hint}>{t('autoApproveHint')}</p>\n </div>\n\n <div className={css.field}>\n <div className={css.fieldHead}>\n <label className={css.label} htmlFor=\"ham-shelf\">{t('shelf')}</label>\n {draftShelf !== baseShelf ? (\n <button\n type=\"button\"\n className={css.reset}\n disabled={disabled}\n onClick={() => setDraft((current) => ({ ...current, shelf: baseShelf }))}\n >\n {t('reset')}\n </button>\n ) : null}\n </div>\n <select\n id=\"ham-shelf\"\n className={css.select}\n value={draftShelf}\n disabled={disabled || saving}\n onChange={(event) => {\n const shelf = event.target.value\n setDraft((current) => ({ ...current, shelf }))\n }}\n >\n {choices.map(choice => (\n <option key={choice.name} value={choice.name}>\n {choice.name}\n {choice.path !== '' ? ` — ${choice.path}` : ''}\n {!choice.listed\n ? t('shelfOptionStatus', { status: t('shelfNotListed') })\n : !choice.connected ? t('shelfOptionStatus', { status: t('shelfDisconnected') }) : ''}\n </option>\n ))}\n </select>\n {shelfStatus === 'loading' ? <p className={css.notice} role=\"status\">{t('shelfLoading')}</p> : null}\n {shelfStatus === 'error' ? (\n <div className={css.catalogError} role=\"alert\">\n <span>{t('shelfLoadFailed')}</span>\n <button type=\"button\" disabled={saving} onClick={() => { void loadShelves() }}>{t('retry')}</button>\n </div>\n ) : null}\n {shelfStatus === 'ready' && shelfListingError !== '' ? (\n <p className={css.notice} role=\"status\">{t('shelfListingFailed', { message: shelfListingError })}</p>\n ) : null}\n {shelfStatus === 'ready' && shelfListingError === '' && chosen !== undefined && (!chosen.listed || !chosen.connected) ? (\n <p className={css.warning} role=\"status\">{t(chosen.listed ? 'shelfDisconnectedWarning' : 'shelfNotListedWarning', { shelf: chosen.name })}</p>\n ) : null}\n <p className={css.hint}>{t('shelfHint')}</p>\n </div>\n\n <section className={css.group} aria-labelledby=\"ham-consolidation-title\">\n <h3 id=\"ham-consolidation-title\" className={css.groupTitle}>{t('consolidationTitle')}</h3>\n <p className={css.hint}>{t('modelSelectionHint')}</p>\n\n <div className={css.modelSelection}>\n {catalogStatus === 'loading' ? <p className={css.notice} role=\"status\">{t('modelCatalogLoading')}</p> : null}\n {catalogStatus === 'error' ? (\n <div className={css.catalogError} role=\"alert\">\n <span>{t('modelCatalogFailed')}</span>\n <button type=\"button\" disabled={saving} onClick={() => { void loadCatalog() }}>{t('retry')}</button>\n </div>\n ) : null}\n {catalogPartial ? <p className={css.notice}>{t('modelCatalogPartial')}</p> : null}\n {candidates.length > 0 ? (\n <>\n <fieldset className={css.models}>\n <legend>{t('selectedModels')}</legend>\n {selectedModels.length === 0 ? (\n <p className={css.notice}>{t('selectedModelsEmpty')}</p>\n ) : selectedModels.map((candidate, index) => (\n <div key={candidate.key} className={css.selectedRow}>\n <span className={css.order}>{index + 1}</span>\n <span className={css.selectedText}>\n <span className={css.modelName}>{candidate.modelName}</span>\n <span className={css.route}>{`${candidate.providerName} · ${candidate.provider}/${candidate.model}`}</span>\n </span>\n <select\n className={css.effort}\n aria-label={`${t('reasoningEffort')}: ${candidate.modelName}`}\n title={candidate.reasoning === undefined\n ? t('reasoningUnavailable')\n : routeDefaultLabel(candidate) ?? t('reasoningFollowPurpose')}\n value={candidate.reasoningEffort ?? ''}\n disabled={disabled || saving || candidate.reasoning === undefined}\n onChange={(event) => setModelEffort(index, event.target.value === '' ? undefined : event.target.value)}\n >\n {reasoningEffortChoices(candidate.reasoning, candidate.reasoningEffort).map(choice => (\n <option key={choice.key} value={choice.effort ?? ''}>{effortChoiceLabel(choice)}</option>\n ))}\n </select>\n {!candidate.available ? <span className={css.unavailable}>{t('modelUnavailable')}</span> : null}\n <span className={css.rowActions}>\n <button\n type=\"button\"\n className={css.move}\n title={t('moveUp')}\n aria-label={`${t('moveUp')}: ${candidate.modelName}`}\n disabled={disabled || saving || index === 0}\n onClick={() => moveModel(index, index - 1)}\n >\n ↑\n </button>\n <button\n type=\"button\"\n className={css.move}\n title={t('moveDown')}\n aria-label={`${t('moveDown')}: ${candidate.modelName}`}\n disabled={disabled || saving || index === selectedModels.length - 1}\n onClick={() => moveModel(index, index + 1)}\n >\n ↓\n </button>\n <button\n type=\"button\"\n className={css.move}\n title={t('remove')}\n aria-label={`${t('remove')}: ${candidate.modelName}`}\n disabled={disabled || saving}\n onClick={() => toggleModel(candidate)}\n >\n ×\n </button>\n </span>\n </div>\n ))}\n </fieldset>\n\n <fieldset className={css.models}>\n <legend>{t('availableModels')}</legend>\n {[...availableGroups].map(([provider, group]) => (\n <div key={provider} className={css.modelGroup}>\n <div className={css.providerName}>{group.providerName}</div>\n {group.candidates.map(renderCandidate)}\n </div>\n ))}\n {unavailable.length > 0 ? (\n <div className={css.modelGroup}>\n <div className={css.providerName}>{t('unavailableModels')}</div>\n {unavailable.map(renderCandidate)}\n </div>\n ) : null}\n </fieldset>\n </>\n ) : catalogStatus === 'ready' ? <p className={css.notice}>{t('modelCatalogEmpty')}</p> : null}\n <p className={css.hint}>{t('reasoningBudgetHint')}</p>\n </div>\n\n <div className={css.pairedFields}>\n <div className={css.field}>\n <div className={css.fieldHead}>\n <label className={css.label} htmlFor=\"ham-checkEveryTurns\">{t('checkEveryTurns')}</label>\n {consolidation.checkEveryTurns !== (base.consolidation?.checkEveryTurns ?? DEFAULT_CONSOLIDATION.checkEveryTurns) ? (\n <button\n type=\"button\"\n className={css.reset}\n disabled={disabled}\n onClick={() => updateConsolidation({ checkEveryTurns: base.consolidation?.checkEveryTurns ?? DEFAULT_CONSOLIDATION.checkEveryTurns })}\n >\n {t('reset')}\n </button>\n ) : null}\n </div>\n <Input\n id=\"ham-checkEveryTurns\"\n className={css.input}\n type=\"number\"\n min={1}\n value={consolidation.checkEveryTurns}\n disabled={disabled}\n onChange={(event) => updateConsolidation({ checkEveryTurns: Number(event.target.value) })}\n />\n </div>\n <div className={css.field}>\n <div className={css.fieldHead}>\n <label className={css.label} htmlFor=\"ham-minNewTokens\">{t('minNewTokens')}</label>\n {consolidation.minNewTokens !== (base.consolidation?.minNewTokens ?? DEFAULT_CONSOLIDATION.minNewTokens) ? (\n <button\n type=\"button\"\n className={css.reset}\n disabled={disabled}\n onClick={() => updateConsolidation({ minNewTokens: base.consolidation?.minNewTokens ?? DEFAULT_CONSOLIDATION.minNewTokens })}\n >\n {t('reset')}\n </button>\n ) : null}\n </div>\n <Input\n id=\"ham-minNewTokens\"\n className={css.input}\n type=\"number\"\n min={0}\n value={consolidation.minNewTokens}\n disabled={disabled}\n onChange={(event) => updateConsolidation({ minNewTokens: Number(event.target.value) })}\n />\n </div>\n </div>\n\n <div className={css.pairedFields}>\n <div className={css.field}>\n <div className={css.fieldHead}>\n <label className={css.label} htmlFor=\"ham-cascadeBatchSize\">{t('cascadeBatchSize')}</label>\n {(consolidation.cascade?.batchSize ?? DEFAULT_CONSOLIDATION.cascade.batchSize)\n !== (base.consolidation?.cascade?.batchSize ?? DEFAULT_CONSOLIDATION.cascade.batchSize) ? (\n <button\n type=\"button\"\n className={css.reset}\n disabled={disabled}\n onClick={() => updateConsolidation({\n cascade: {\n ...(consolidation.cascade ?? DEFAULT_CONSOLIDATION.cascade),\n batchSize: base.consolidation?.cascade?.batchSize ?? DEFAULT_CONSOLIDATION.cascade.batchSize,\n },\n })}\n >\n {t('reset')}\n </button>\n ) : null}\n </div>\n <Input\n id=\"ham-cascadeBatchSize\"\n className={css.input}\n type=\"number\"\n min={2}\n value={consolidation.cascade?.batchSize ?? DEFAULT_CONSOLIDATION.cascade.batchSize}\n disabled={disabled}\n onChange={(event) => updateConsolidation({\n cascade: {\n ...(consolidation.cascade ?? DEFAULT_CONSOLIDATION.cascade),\n batchSize: Number(event.target.value),\n },\n })}\n />\n </div>\n <div className={css.field}>\n <div className={css.fieldHead}>\n <label className={css.label} htmlFor=\"ham-dedupMaxDistance\">{t('dedupMaxDistance')}</label>\n {(consolidation.dedupMaxDistance ?? DEFAULT_CONSOLIDATION.dedupMaxDistance)\n !== (base.consolidation?.dedupMaxDistance ?? DEFAULT_CONSOLIDATION.dedupMaxDistance) ? (\n <button\n type=\"button\"\n className={css.reset}\n disabled={disabled}\n onClick={() => updateConsolidation({\n dedupMaxDistance: base.consolidation?.dedupMaxDistance ?? DEFAULT_CONSOLIDATION.dedupMaxDistance,\n })}\n >\n {t('reset')}\n </button>\n ) : null}\n </div>\n <Input\n id=\"ham-dedupMaxDistance\"\n className={css.input}\n type=\"number\"\n min={0}\n step={0.05}\n value={consolidation.dedupMaxDistance ?? DEFAULT_CONSOLIDATION.dedupMaxDistance}\n disabled={disabled}\n onChange={(event) => updateConsolidation({ dedupMaxDistance: Number(event.target.value) })}\n />\n </div>\n </div>\n <p className={css.hint}>{t('cascadeHint')}</p>\n\n <h4 className={css.limitsTitle}>{t('limitsTitle')}</h4>\n <p className={css.hint}>{t('limitsHint')}</p>\n <div className={css.pairedFields}>\n <div className={css.field}>\n <div className={css.fieldHead}>\n <label className={css.label} htmlFor=\"ham-maxInputTokens\">{t('maxInputTokens')}</label>\n {consolidation.maxInputTokens !== (base.consolidation?.maxInputTokens ?? DEFAULT_CONSOLIDATION.maxInputTokens) ? (\n <button\n type=\"button\"\n className={css.reset}\n disabled={disabled}\n onClick={() => updateConsolidation({ maxInputTokens: base.consolidation?.maxInputTokens ?? DEFAULT_CONSOLIDATION.maxInputTokens })}\n >\n {t('reset')}\n </button>\n ) : null}\n </div>\n <Input\n id=\"ham-maxInputTokens\"\n className={css.input}\n type=\"number\"\n min={1000}\n step={1000}\n value={consolidation.maxInputTokens}\n disabled={disabled}\n onChange={(event) => updateConsolidation({ maxInputTokens: Number(event.target.value) })}\n />\n </div>\n <div className={css.field}>\n <div className={css.fieldHead}>\n <label className={css.label} htmlFor=\"ham-maxOutputTokens\">{t('maxOutputTokens')}</label>\n {consolidation.maxOutputTokens !== (base.consolidation?.maxOutputTokens ?? DEFAULT_CONSOLIDATION.maxOutputTokens) ? (\n <button\n type=\"button\"\n className={css.reset}\n disabled={disabled}\n onClick={() => updateConsolidation({ maxOutputTokens: base.consolidation?.maxOutputTokens ?? DEFAULT_CONSOLIDATION.maxOutputTokens })}\n >\n {t('reset')}\n </button>\n ) : null}\n </div>\n <Input\n id=\"ham-maxOutputTokens\"\n className={css.input}\n type=\"number\"\n min={200}\n step={200}\n value={consolidation.maxOutputTokens}\n disabled={disabled}\n onChange={(event) => updateConsolidation({ maxOutputTokens: Number(event.target.value) })}\n />\n </div>\n <div className={css.field}>\n <div className={css.fieldHead}>\n <label className={css.label} htmlFor=\"ham-maxWorkUnitsPerRun\">{t('maxWorkUnitsPerRun')}</label>\n {consolidation.maxWorkUnitsPerRun !== (base.consolidation?.maxWorkUnitsPerRun ?? DEFAULT_CONSOLIDATION.maxWorkUnitsPerRun) ? (\n <button\n type=\"button\"\n className={css.reset}\n disabled={disabled}\n onClick={() => updateConsolidation({ maxWorkUnitsPerRun: base.consolidation?.maxWorkUnitsPerRun ?? DEFAULT_CONSOLIDATION.maxWorkUnitsPerRun })}\n >\n {t('reset')}\n </button>\n ) : null}\n </div>\n <Input\n id=\"ham-maxWorkUnitsPerRun\"\n className={css.input}\n type=\"number\"\n min={1}\n max={10}\n value={consolidation.maxWorkUnitsPerRun}\n disabled={disabled}\n onChange={(event) => updateConsolidation({ maxWorkUnitsPerRun: Number(event.target.value) })}\n />\n </div>\n </div>\n </section>\n\n <div className={css.field}>\n <div className={css.fieldHead}>\n <label className={css.label} htmlFor=\"ham-preloadRulesTaboos\">{t('recallPreload')}</label>\n {(recall.preloadRulesTaboos ?? true) !== (base.recall?.preloadRulesTaboos ?? true) ? (\n <button\n type=\"button\"\n className={css.reset}\n disabled={disabled}\n onClick={() => setDraft((current) => ({\n ...current,\n recall: {\n ...(current.recall ?? { preloadRulesTaboos: true }),\n preloadRulesTaboos: base.recall?.preloadRulesTaboos ?? true,\n },\n }))}\n >\n {t('reset')}\n </button>\n ) : null}\n </div>\n <button\n id=\"ham-preloadRulesTaboos\"\n type=\"button\"\n role=\"switch\"\n aria-checked={recall.preloadRulesTaboos ?? true}\n aria-label={t('recallPreload')}\n className={`${css.switch} ${recall.preloadRulesTaboos ?? true ? css.switchOn : ''}`}\n disabled={disabled}\n onClick={() => setDraft((current) => ({\n ...current,\n recall: {\n ...(current.recall ?? { preloadRulesTaboos: true }),\n preloadRulesTaboos: !(current.recall?.preloadRulesTaboos ?? true),\n },\n }))}\n >\n <span className={css.switchThumb} />\n </button>\n </div>\n\n <p className={css.advancedHint}>{t('advancedHint', { ns: NS })}</p>\n {error ? <p className={css.error} role=\"status\">{t('saveFailed', { message: error })}</p> : null}\n\n <div className={css.footer}>\n <Button\n variant=\"outline\"\n size=\"sm\"\n disabled={!dirty || saving}\n onClick={discard}\n >\n {t('discard')}\n </Button>\n <Button\n variant=\"primary\"\n size=\"sm\"\n disabled={saveBlocked}\n onClick={save}\n >\n {saving ? t('saving') : t('save')}\n </Button>\n </div>\n </div>\n </section>\n )\n}\n","/**\n * The Memory tab's read side: one same-origin request per refresh.\n *\n * The Host half serves it from `/api/dsh-hypatia-auto-memory/session`\n * (see `src/memory-api.js`), which is parameterized by session and authenticates\n * itself — unlike a settings namespace, it can answer for the one session the\n * tab is bound to instead of shipping every session's state to the browser.\n *\n * Zero runtime imports beyond `fetch`, so the parsing half is unit-tested under\n * `node:test` like `shelves.ts`.\n */\n\nimport type { LoadShelfInventory, ShelfInfo, ShelfInventory } from './shelves'\n\n/** Route prefix the Host claims; the tab appends `/session`. */\nexport const MEMORY_API_PREFIX = '/api/dsh-hypatia-auto-memory'\n\n/** One task that exhausted its attempts. */\nexport interface FailedMemoryTask {\n kind: string\n sessionId: string\n attempts: number\n error: string\n}\n\n/** What the Host derived for one session out of the state tables. */\nexport interface SessionMemoryStatus {\n sessionId: string\n /** False when the Host has no row and no task for this session yet. */\n known: boolean\n loggedSeq: number\n consolidatedSeq: number\n /** True when consolidation has covered everything logged. */\n caughtUp: boolean\n pendingTokens: number\n sessionNode: boolean\n belongTo: number\n deferred: number\n failed: number\n failedTasks: FailedMemoryTask[]\n error: string\n}\n\n/** One distilled entry: a span summary or a work unit. */\nexport interface MemoryEntry {\n name: string\n /** Markdown body, already capped by the Host. */\n markdown: string\n /** Archive tier, summaries only; 1 condenses messages. */\n level: number\n createdAt: string\n}\n\n/**\n * The shelf half of a response.\n *\n * Kept as one object rather than spread across the payload so \"the Host did not\n * read the shelf\" is representable: the five-second poll asks for status only,\n * and a reader that cannot tell that apart from \"the shelf is empty\" wipes the\n * content it already showed.\n */\nexport interface MemoryContent {\n summaries: MemoryEntry[]\n workUnits: MemoryEntry[]\n /** How many the shelf holds, before the response caps. */\n summaryCount: number\n workUnitCount: number\n /** True when a cap dropped entries or cut a body short. */\n truncated: boolean\n /** Non-empty when the shelf could not be read; the status half is still valid. */\n error: string\n}\n\n/** One response from the Host. */\nexport interface MemoryPayload {\n session: SessionMemoryStatus\n /** Epoch milliseconds the Host last saw this session's status change. */\n updatedAt: number\n /** Absent when this response carried status only. */\n content: MemoryContent | undefined\n}\n\n/** Read one session's memory. `content` also asks the Host to read the shelf. */\nexport type FetchMemory = (sessionId: string, options: { content: boolean }) => Promise<MemoryPayload>\n\n/**\n * The URL one refresh reads.\n * @param sessionId - the session the tab is bound to.\n * @param content - whether to ask the Host to read the shelf as well.\n * @returns a same-origin path with its query.\n */\nexport function memoryUrl(sessionId: string, content: boolean): string {\n const query = new URLSearchParams({ session: sessionId })\n if (content) query.set('content', '1')\n return `${MEMORY_API_PREFIX}/session?${query.toString()}`\n}\n\n/** Fetch one session's memory from the Host. */\nexport const fetchMemory: FetchMemory = async (sessionId, { content }) => {\n const response = await fetch(memoryUrl(sessionId, content), {\n method: 'GET',\n credentials: 'same-origin',\n headers: { accept: 'application/json' },\n })\n const body: unknown = await response.json().catch(() => undefined)\n if (!response.ok) {\n const message = isRecord(body) && typeof body.error === 'string' ? body.error : `HTTP ${String(response.status)}`\n throw new Error(message)\n }\n const payload = parseMemoryPayload(body, sessionId)\n if (payload === undefined) throw new Error('the Host returned an unreadable memory payload')\n return payload\n}\n\n/**\n * Fetch the shelf listing for the settings card.\n *\n * Rides the same self-authenticating route family as the Memory tab — the\n * settings page passes the same loopback / same-origin checks — because the\n * 0.1.7 settings domain no longer lets a Host plugin publish a dynamic,\n * non-config namespace for the card to read.\n */\nexport const fetchShelves: LoadShelfInventory = async () => {\n const response = await fetch(`${MEMORY_API_PREFIX}/shelves`, {\n method: 'GET',\n credentials: 'same-origin',\n headers: { accept: 'application/json' },\n })\n const body: unknown = await response.json().catch(() => undefined)\n if (!response.ok) {\n const message = isRecord(body) && typeof body.error === 'string' ? body.error : `HTTP ${String(response.status)}`\n throw new Error(message)\n }\n const inventory = parseShelfInventory(body)\n if (inventory === undefined) throw new Error('the Host returned an unreadable shelf listing')\n return inventory\n}\n\n/**\n * Read the Host's `/shelves` answer into the card's shape, defensively.\n * @param value - the parsed response body.\n * @returns the listing, or undefined when the body is not one.\n */\nexport function parseShelfInventory(value: unknown): ShelfInventory | undefined {\n if (!isRecord(value)) return undefined\n return {\n shelves: Array.isArray(value.shelves)\n ? value.shelves.flatMap((shelf): ShelfInfo[] => {\n if (!isRecord(shelf) || typeof shelf.name !== 'string' || shelf.name === '') return []\n return [{\n name: shelf.name,\n path: typeof shelf.path === 'string' ? shelf.path : '',\n connected: shelf.connected === true,\n }]\n })\n : [],\n error: str(value.error),\n }\n}\n\n/**\n * Session-log events that are recorded but not yet consolidated.\n *\n * Both watermarks index the same log, so their difference is exactly the work\n * consolidation still owes. Clamped at zero: a consolidation run may cover a\n * range the logging watermark has not caught up to yet, which is not a backlog.\n *\n * @param session - the session half of a payload.\n * @returns the gap in session-log events.\n */\nexport function consolidationGap(session: SessionMemoryStatus): number {\n return Math.max(0, session.loggedSeq - session.consolidatedSeq)\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction num(value: unknown): number {\n return typeof value === 'number' && Number.isFinite(value) ? value : 0\n}\n\nfunction str(value: unknown): string {\n return typeof value === 'string' ? value : ''\n}\n\nfunction parseFailedTasks(value: unknown): FailedMemoryTask[] {\n if (!Array.isArray(value)) return []\n return value.flatMap((entry): FailedMemoryTask[] => isRecord(entry)\n ? [{\n kind: str(entry.kind),\n sessionId: str(entry.sessionId),\n attempts: num(entry.attempts),\n error: str(entry.error),\n }]\n : [])\n}\n\nfunction parseEntries(value: unknown): MemoryEntry[] {\n if (!Array.isArray(value)) return []\n return value.flatMap((entry): MemoryEntry[] => {\n if (!isRecord(entry)) return []\n const name = str(entry.name)\n if (name === '') return []\n return [{\n name,\n markdown: str(entry.markdown),\n level: num(entry.level) || 1,\n createdAt: str(entry.createdAt),\n }]\n })\n}\n\n/**\n * Read the Host's answer into the tab's shape, defensively.\n *\n * A malformed field falls back to its zero value rather than reaching the DOM;\n * a payload with no usable `session` is rejected outright, because rendering a\n * panel of zeros for a session the Host never answered about would be a lie.\n *\n * A status-only answer parses to `content: undefined` — never to empty lists,\n * which is what made the five-second poll erase the shelf content. The Host also\n * states which half it sent (`content`), and that flag is what this prefers; the\n * key sniffing beside it keeps a bundle built after the flag from misreading a\n * Host that predates it, so the fix does not need a profile restart to land.\n *\n * @param value - the parsed response body.\n * @param sessionId - the session that was asked for.\n * @returns the payload, or undefined when the body is not one.\n */\nexport function parseMemoryPayload(value: unknown, sessionId: string): MemoryPayload | undefined {\n if (!isRecord(value) || !isRecord(value.session)) return undefined\n const session = value.session\n const carried = value.content === true\n || Object.hasOwn(value, 'summaries')\n || Object.hasOwn(value, 'contentError')\n return {\n session: {\n sessionId: str(session.sessionId) || sessionId,\n known: session.known === true,\n loggedSeq: num(session.loggedSeq),\n consolidatedSeq: num(session.consolidatedSeq),\n caughtUp: session.caughtUp === true,\n pendingTokens: num(session.pendingTokens),\n sessionNode: session.sessionNode === true,\n belongTo: num(session.belongTo),\n deferred: num(session.deferred),\n failed: num(session.failed),\n failedTasks: parseFailedTasks(session.failedTasks),\n error: str(session.error),\n },\n updatedAt: num(value.updatedAt),\n content: carried\n ? {\n summaries: parseEntries(value.summaries),\n workUnits: parseEntries(value.workUnits),\n summaryCount: num(value.summaryCount),\n workUnitCount: num(value.workUnitCount),\n truncated: value.truncated === true,\n error: str(value.contentError),\n }\n : undefined,\n }\n}\n\n/**\n * Fold a new answer onto the one on screen.\n *\n * Status is always the newest. Content is only replaced by an answer that\n * carried content, so the poll cannot erase it. An answer whose shelf read\n * failed keeps the content already shown — entries, counts and the truncation\n * flag together, so the header still describes the list under it — and records\n * the error beside it, because a transient hypatia failure should not blank\n * what the reader was looking at.\n *\n * @param previous - the payload on screen, if any.\n * @param next - the answer just parsed.\n * @returns the payload to render.\n */\nexport function mergeMemory(\n previous: MemoryPayload | undefined,\n next: MemoryPayload,\n): MemoryPayload {\n if (next.content === undefined) return { ...next, content: previous?.content }\n // A failed read keeps whatever was on screen — the entries AND the counts that\n // describe them — and replaces only the reason. The guard must not consult the\n // previous error: on the SECOND consecutive failure it is already set, and\n // testing for it fell through to the zeroed answer, blanking the panel the\n // first failure had deliberately preserved.\n if (next.content.error !== '' && previous?.content !== undefined) {\n return { ...next, content: { ...previous.content, error: next.content.error } }\n }\n return next\n}\n","/**\n * The conversation's Memory tab: what this session has been remembered as, what\n * it was remembered into, and what is stuck.\n *\n * Three sections, in the order a reader wants them: the pipeline's status\n * (watermarks, backlog, failures), then the span summaries consolidation\n * produced, then the work units derived from them. Bodies render through the\n * shell's own `MarkdownText`, so a summary reads exactly like assistant Markdown\n * elsewhere in the GUI and costs no bundle weight.\n *\n * Raw `msg-*` entries are deliberately absent: they hold the conversation\n * verbatim, the reader just wrote them, and the agent is the right reader for\n * them (see `src/memory-api.js` for the same rule on the Host side).\n *\n * Status is polled; content is fetched only when it can have changed — on mount,\n * on a session switch, on a manual refresh, and whenever consolidation advances\n * the session's watermark. Reading the shelf costs hypatia round trips, and\n * consolidation is the only thing that changes it.\n */\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport { MarkdownText } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots'\nimport {\n consolidationGap,\n mergeMemory,\n type FetchMemory,\n type MemoryEntry,\n type MemoryPayload,\n} from './memory-client'\nimport { NS } from './locales'\nimport css from './MemoryView.module.css'\nimport './slot-contract'\n\n/** How often the tab re-reads the status half while it is on screen. */\nconst POLL_MS = 5000\n\nexport type MemoryViewProps = {\n /** The session this tab is bound to; supplied by the session-scoped slot. */\n sessionId: string\n fetch: FetchMemory\n} & PropsLocale<typeof NS>\n\n/** Local wall-clock stamp for the freshness line. */\nfunction formatTime(epochMs: number): string {\n if (!Number.isFinite(epochMs) || epochMs <= 0) return '—'\n return new Date(epochMs).toLocaleTimeString()\n}\n\n/**\n * hypatia stamps `created_at` as `YYYY-MM-DD HH:MM:SS.ffffff`; the microseconds\n * are noise in a row that is 11px tall, so the tab shows down to the minute.\n * Slice rather than `new Date`: the space-separated form is not the ISO shape\n * every engine is required to parse.\n */\nfunction formatEntryTime(stamp: string): string {\n return stamp.length >= 16 ? stamp.slice(0, 16).replace('T', ' ') : stamp\n}\n\n/** The first non-empty line of a body, for a collapsed row's preview. */\nfunction firstLine(markdown: string): string {\n for (const line of markdown.split('\\n')) {\n const trimmed = line.replace(/^[#>\\-*\\s]+/, '').trim()\n if (trimmed !== '') return trimmed\n }\n return ''\n}\n\n/** One collapsible distilled entry. */\nfunction Entry({ entry, badge, open, onToggle, labels, t }: {\n entry: MemoryEntry\n badge: string\n open: boolean\n onToggle: () => void\n labels: { code: { copyLabel: string; copiedLabel: string }; footnotes: string }\n t: MemoryViewProps['t']\n}) {\n return (\n <li className={css.entry}>\n <button type=\"button\" className={css.entryHead} aria-expanded={open} onClick={onToggle}>\n <span className={css.entryName}>{entry.name}</span>\n <span className={css.entryMeta}>\n <span className={css.badge}>{badge}</span>\n {entry.createdAt !== '' ? <span className={css.entryTime}>{formatEntryTime(entry.createdAt)}</span> : null}\n <span className={css.entryToggle}>{open ? t('memoryEntryCollapse') : t('memoryEntryExpand')}</span>\n </span>\n </button>\n {open\n ? (\n <div className={css.entryBody}>\n {entry.markdown === ''\n ? <p className={css.status}>{t('memoryEntryEmpty')}</p>\n : <MarkdownText text={entry.markdown} labels={labels} />}\n </div>\n )\n : <p className={css.entryPreview}>{firstLine(entry.markdown)}</p>}\n </li>\n )\n}\n\nexport function MemoryView({ sessionId, fetch, t }: MemoryViewProps) {\n const [payload, setPayload] = useState<MemoryPayload | undefined>(undefined)\n const [loading, setLoading] = useState(true)\n const [error, setError] = useState('')\n /**\n * The entries the reader opened, by name. Absent means closed, which is the\n * default: a toggle survives the poll that replaces the payload, and an entry\n * a later poll adds starts closed rather than inheriting a neighbour's state.\n */\n const [overrides, setOverrides] = useState<Readonly<Record<string, boolean>>>({})\n /** The watermark whose content is already in hand, so a poll never re-reads it. */\n const [contentAt, setContentAt] = useState<number | undefined>(undefined)\n\n const copyLabel = t('memoryCopyCode')\n const copiedLabel = t('memoryCopiedCode')\n const footnotes = t('memoryFootnotes')\n // MarkdownText caches its render against the labels identity, so this must be\n // one object per locale, not a fresh one per render.\n const labels = useMemo(\n () => ({ code: { copyLabel, copiedLabel }, footnotes }),\n [copyLabel, copiedLabel, footnotes],\n )\n\n /**\n * The session the tab is showing now. A request outlives the session it was\n * made for — a slow shelf read, or a poll already in flight at a switch — and\n * its answer must be dropped rather than folded into the next session's view.\n */\n const activeSession = useRef(sessionId)\n\n const load = useCallback(async (content: boolean) => {\n const current = () => activeSession.current === sessionId\n try {\n const next = await fetch(sessionId, { content })\n if (!current()) return\n // Folded, not assigned: a status-only poll must not erase the shelf\n // content it did not ask for (see `mergeMemory`).\n setPayload((previous) => mergeMemory(previous, next))\n setError('')\n if (content) setContentAt(next.session.consolidatedSeq)\n } catch (failure) {\n if (!current()) return\n setError(failure instanceof Error ? failure.message : String(failure))\n } finally {\n if (current()) setLoading(false)\n }\n }, [fetch, sessionId])\n\n // A session switch starts over: the previous session's content and the\n // previous session's collapsed rows must not leak into this one.\n useEffect(() => {\n activeSession.current = sessionId\n setPayload(undefined)\n setOverrides({})\n setContentAt(undefined)\n setLoading(true)\n void load(true)\n }, [load, sessionId])\n\n useEffect(() => {\n const timer = setInterval(() => {\n // A hidden tab has nobody reading it; the panel is a snapshot, not a stream.\n if (typeof document !== 'undefined' && document.visibilityState === 'hidden') return\n void load(false)\n }, POLL_MS)\n return () => clearInterval(timer)\n }, [load])\n\n // Consolidation is the only thing that changes the shelf, so a watermark that\n // moved is the signal to read it again.\n useEffect(() => {\n const at = payload?.session.consolidatedSeq\n if (at === undefined || contentAt === undefined) return\n if (at !== contentAt) void load(true)\n }, [payload?.session.consolidatedSeq, contentAt, load])\n\n const toggle = useCallback((name: string, open: boolean) => {\n setOverrides((current) => ({ ...current, [name]: !open }))\n }, [])\n\n const session = payload?.session\n const content = payload?.content\n const summaries = content?.summaries ?? []\n const workUnits = content?.workUnits ?? []\n\n // Every entry starts closed and previews its first line: the list stays\n // scannable at any length, and the bodies are one click away. `overrides`\n // holds what the reader opened, so a poll that replaces the payload does not\n // close it again.\n const renderEntries = (entries: MemoryEntry[], kind: 'summary' | 'workUnit') => (\n <ul className={css.entries}>\n {entries.map((entry) => {\n const open = overrides[entry.name] === true\n return (\n <Entry\n key={entry.name}\n entry={entry}\n badge={kind === 'summary' ? t('memoryTier', { level: String(entry.level) }) : t('memoryWorkUnit')}\n open={open}\n onToggle={() => toggle(entry.name, open)}\n labels={labels}\n t={t}\n />\n )\n })}\n </ul>\n )\n\n return (\n // Opts into the composer overlay the way the trajectory ledger does: the\n // view owns its scroller and gets the full height, with the composer\n // floating over it. Without the marker the Conversation shell seats the\n // composer below a short panel instead.\n <div className={css.panel} data-conversation-composer-overlay=\"\">\n <div className={css.column}>\n <header className={css.head}>\n <h2 className={css.title}>{t('memoryTitle')}</h2>\n <div className={css.headMeta}>\n <span className={css.updated}>{t('memoryUpdatedAt', { time: formatTime(payload?.updatedAt ?? 0) })}</span>\n <button type=\"button\" className={css.refresh} onClick={() => { void load(true) }}>\n {t('memoryRefresh')}\n </button>\n </div>\n </header>\n\n {error !== '' ? <p className={css.error} role=\"status\">{t('memoryLoadFailed', { message: error })}</p> : null}\n\n {loading && payload === undefined\n ? <p className={css.status}>{t('memoryLoading')}</p>\n : session === undefined\n ? <p className={css.status}>{t('memoryNoSnapshot')}</p>\n : !session.known\n ? <p className={css.status}>{t('memoryUnknown')}</p>\n : (\n <section className={css.group} aria-label={t('memoryTitle')}>\n <dl className={css.rows}>\n <div className={css.row}>\n <dt className={css.label}>{t('memoryLogged')}</dt>\n <dd className={css.value}>{t('memorySeqValue', { seq: String(session.loggedSeq) })}</dd>\n </div>\n <div className={css.row}>\n <dt className={css.label}>{t('memoryConsolidated')}</dt>\n <dd className={css.value}>\n {t('memorySeqValue', { seq: String(session.consolidatedSeq) })}\n {/* Quantified, not a bare \"pending\": a reader has to know HOW\n far behind to judge whether to wait. */}\n <span className={session.caughtUp ? css.calm : css.busy}>\n {session.caughtUp\n ? t('memoryCaughtUp')\n : t('memoryBehind', { behind: String(consolidationGap(session)) })}\n </span>\n </dd>\n </div>\n <div className={css.row}>\n <dt className={css.label}>{t('memoryPending')}</dt>\n <dd className={css.value}>{t('memoryPendingValue', { tokens: String(session.pendingTokens) })}</dd>\n </div>\n <div className={css.row}>\n <dt className={css.label}>{t('memorySessionNode')}</dt>\n <dd className={css.value}>\n {session.sessionNode ? t('memorySessionNodeYes') : t('memorySessionNodeNo')}\n </dd>\n </div>\n <div className={css.row}>\n <dt className={css.label}>{t('memoryBelongTo')}</dt>\n <dd className={css.value}>{t('memoryBelongToValue', { count: String(session.belongTo) })}</dd>\n </div>\n {session.deferred > 0 ? (\n <div className={css.row}>\n <dt className={css.label}>{t('memoryDeferred')}</dt>\n <dd className={css.value}>{String(session.deferred)}</dd>\n </div>\n ) : null}\n </dl>\n </section>\n )}\n\n {session !== undefined && (session.failed > 0 || session.failedTasks.length > 0) ? (\n <section className={css.group} aria-label={t('memoryFailedTitle')}>\n <h3 className={css.groupTitle}>{t('memoryFailedTitle')}</h3>\n <ul className={css.failures}>\n {session.failedTasks.map((task, index) => (\n <li key={`${task.kind}-${String(index)}`} className={css.failure}>\n <span className={css.failureKind}>\n {t('memoryFailedItem', { kind: task.kind, attempts: String(task.attempts) })}\n </span>\n {task.error !== '' ? <span className={css.failureError}>{task.error}</span> : null}\n </li>\n ))}\n {session.failedTasks.length === 0 ? <li className={css.failure}>{session.error}</li> : null}\n </ul>\n </section>\n ) : null}\n\n {content !== undefined && content.error !== '' ? (\n <section className={css.group} aria-label={t('memoryContentTitle')}>\n <h3 className={css.groupTitle}>{t('memoryContentTitle')}</h3>\n <p className={css.error} role=\"status\">{t('memoryContentFailed', { message: content.error })}</p>\n </section>\n ) : null}\n\n {content !== undefined ? (\n <>\n <section className={css.group} aria-label={t('memorySummariesTitle')}>\n <h3 className={css.groupTitle}>\n {t('memorySummariesTitle')}\n <span className={css.count}>\n {t('memoryCount', { shown: String(summaries.length), total: String(content.summaryCount) })}\n </span>\n </h3>\n {summaries.length === 0\n ? <p className={css.status}>{t('memoryNoSummaries')}</p>\n : renderEntries(summaries, 'summary')}\n </section>\n\n <section className={css.group} aria-label={t('memoryWorkUnitsTitle')}>\n <h3 className={css.groupTitle}>\n {t('memoryWorkUnitsTitle')}\n <span className={css.count}>\n {t('memoryCount', { shown: String(workUnits.length), total: String(content.workUnitCount) })}\n </span>\n </h3>\n {workUnits.length === 0\n ? <p className={css.status}>{t('memoryNoWorkUnits')}</p>\n : renderEntries(workUnits, 'workUnit')}\n </section>\n\n {content.truncated ? <p className={css.hint}>{t('memoryTruncated')}</p> : null}\n <p className={css.hint}>{t('memoryHint')}</p>\n </>\n ) : null}\n </div>\n </div>\n )\n}\n","/**\n * Which seat the settings card occupies on the harness that is running.\n *\n * dsh 0.1.7 moved a bundle's own configuration out of Settings. The sidebar's\n * Plugins page owns it now, and `plugins.bundle.config` — keyed by the bundle's\n * package name — is the seat that page renders on the bundle's own page. The\n * Settings section still declares `settings.plugins.tab`, and it is the only\n * seat a deployment whose profile does not mount the plugin manager page has.\n *\n * Three facts about the slot registry shape this module:\n *\n * - The harness declares the official seats before an external plugin's\n * `apply()` runs, so the first attempt normally succeeds. It is a plain\n * `register`, never a declaration probe: `register` is the operation the\n * registry validates, and a probe would answer for a different question —\n * \"is this key declared?\" is true even in the deployment whose whole point is\n * the other seat.\n * - `register` throws for an undeclared seat. That refusal is the fallback\n * signal, so the seats are tried rather than predicted.\n * - `slots/changed` is emitted synchronously from inside both `register` and a\n * disposer, so an unguarded reconcile re-enters itself mid-move and registers\n * the card twice into the seat it is leaving (\"already has an entry for key\n * …\"). The latch below is what prevents that.\n *\n * The card is therefore in exactly one seat at any time: the official one when\n * the harness renders it, the Settings tab otherwise, and the Settings entry is\n * disposed before the official one is taken. This module holds the policy and\n * no client-SDK import, so the moves are unit-tested with a fake registry.\n *\n * @module dsh-hypatia-auto-memory/client/plugin-card-seat\n */\n\n/** The official keyed seat on the sidebar Plugins page, keyed by bundle package name. */\nexport const BUNDLE_CONFIG_SEAT = 'plugins.bundle.config'\n\n/** The list seat inside Settings → Built-in plugins, declared by the Settings section. */\nexport const SETTINGS_TAB_SEAT = 'settings.plugins.tab'\n\n/** The slice of the client slot registry this module uses. */\nexport interface SeatRegistry {\n /**\n * Contribute one entry, or throw when the seat is not declared.\n * @param key - declared slot key to inject a contribution into.\n * @param callback - runs while that declaration is live; returns its disposer.\n * @returns idempotent disposer for the wait and the active contribution.\n */\n inject(key: string, callback: () => () => void): () => void\n}\n\n/** The slice of the browser plugin context this module uses. */\nexport interface SeatHost {\n readonly slots: SeatRegistry\n /** Subscribe to the registry's change event; absent on a host that has no event bus. */\n on?(event: 'slots/changed', listener: (key: string) => void): (() => void) | undefined\n}\n\n/** How to install one card into each seat, each throwing when that seat is not declared. */\nexport interface PluginCardSeats {\n /** The official keyed seat; the caller keys it by bundle package name. */\n readonly official: () => (() => void) | undefined\n /** The Settings tab; the caller passes its list-seat id, label and locale. */\n readonly settingsTab: () => (() => void) | undefined\n /**\n * Called once per seat that a registration attempt refused, for a diagnostic.\n * The official seat is expected to refuse while it is not declared yet, so a\n * deployment that renders it never reports anything here.\n */\n readonly onRefused?: (seat: string, error: unknown) => void\n}\n\n/**\n * Install one card into the seat this harness renders, following the harness if\n * the seat becomes available later.\n *\n * @param host - the client context's slot registry and event bus.\n * @param seats - the two seat contributions and an optional refusal diagnostic.\n * @returns one disposer that removes the card and stops watching.\n */\nexport function installPluginCard(host: SeatHost, seats: PluginCardSeats): () => void {\n /** The live official registration, while the card occupies that seat. */\n let official: (() => void) | undefined\n /** The live Settings-tab registration, while the card occupies that seat instead. */\n let settingsTab: (() => void) | undefined\n /** Set by the returned disposer: every later reconcile is a no-op. */\n let stopped = false\n /** Re-entrancy latch: the registry emits `slots/changed` from inside register and dispose. */\n let reconciling = false\n const refused = new Set<string>()\n\n /** One registration attempt, reporting its refusal once instead of on every retry. */\n const attempt = (seat: string, register: () => (() => void) | undefined): (() => void) | undefined => {\n try {\n return register()\n } catch (error) {\n if (!refused.has(seat)) {\n refused.add(seat)\n seats.onRefused?.(seat, error)\n }\n return undefined\n }\n }\n\n /** Take the official seat when it is declared, retiring the Settings fallback first. */\n const reconcile = (): void => {\n if (stopped || reconciling || official !== undefined) return\n reconciling = true\n try {\n const dispose = attempt(BUNDLE_CONFIG_SEAT, seats.official)\n if (dispose === undefined) return\n official = dispose\n const previous = settingsTab\n settingsTab = undefined\n previous?.()\n } finally {\n reconciling = false\n }\n }\n\n reconcile()\n\n // The fallback claims the Settings tab only while the official seat is absent.\n // Its declaration arrives when the Settings section mounts, which is after the\n // shell has declared the official seats — so on a harness that renders the\n // Plugins page this callback finds `official` already live and contributes\n // nothing.\n const stopWaiting = host.slots.inject(SETTINGS_TAB_SEAT, () => {\n if (stopped || official !== undefined || settingsTab !== undefined) return () => {}\n const dispose = attempt(SETTINGS_TAB_SEAT, seats.settingsTab)\n if (dispose === undefined) return () => {}\n settingsTab = dispose\n // The registration above emits `slots/changed`, so a reconcile can have taken\n // the official seat before this assignment: the card would then sit in two\n // seats. Re-check instead of assuming which ran first.\n if (official !== undefined) {\n settingsTab = undefined\n dispose()\n return () => {}\n }\n return () => {\n const current = settingsTab\n settingsTab = undefined\n current?.()\n }\n })\n\n const stopWatching = host.on?.('slots/changed', () => { reconcile() })\n\n return () => {\n stopped = true\n stopWatching?.()\n stopWaiting()\n const officialDispose = official\n official = undefined\n officialDispose?.()\n const settingsDispose = settingsTab\n settingsTab = undefined\n settingsDispose?.()\n }\n}\n","/**\n * Browser half of dsh-hypatia-auto-memory: contributes the configuration card\n * for the `hypatia-auto-memory` namespace, and a per-session Memory tab beside\n * the conversation's Chat and Trajectory tabs.\n *\n * The card's seat depends on the harness: the sidebar Plugins page owns a\n * bundle's configuration from dsh 0.1.7 on, and the Settings tab is the fallback\n * for a deployment that does not render that page. `plugin-card-seat.ts` makes\n * that choice and keeps the card in one seat.\n *\n * The Host plugin already registers the schema and namespace; this half only\n * renders the form and routes edits through `ctx.configForms`. The Memory tab\n * reads the Host's read-only status namespace (see `src/memory-status.js`).\n */\n\nimport type { Context } from '@deepseek-ai/cordis'\nimport type {} from '@deepseek-ai/dsh-api-remotes/client'\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\nimport type { LocaleRuntime } from '@deepseek-ai/dsh-client-locale/client'\nimport type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { ConfigForms } from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-renderer/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings-plugins/client'\n// Type-only: the 'conversation.view' SlotMap row is declared by the conversation\n// shell, so the registration below only type-checks with its merge in the program.\nimport type {} from '@deepseek-ai/dsh-client-ui-conversation/client'\nimport { createElement } from 'react'\nimport { SettingsCard } from './SettingsCard'\nimport type { ConfigShape } from './SettingsCard'\nimport type { LoadConsolidationModelCatalog } from './consolidation-models'\nimport { MemoryView } from './MemoryView'\nimport { fetchMemory, fetchShelves } from './memory-client'\nimport type { LoadShelfInventory } from './shelves'\nimport { BUNDLE_CONFIG_SEAT, SETTINGS_TAB_SEAT, installPluginCard } from './plugin-card-seat'\nimport { en, NS, zh } from './locales'\n\n/** The bundle's npm package name: the key the official seat identifies it by. */\nconst BUNDLE_NAME = 'dsh-hypatia-auto-memory'\n\nconst APPLY_CLAIM = '__dshHypatiaAutoMemoryApplied'\n\nfunction claimApply(): boolean {\n const scope = globalThis as Record<string, unknown>\n if (scope[APPLY_CLAIM] === true) return false\n scope[APPLY_CLAIM] = true\n return true\n}\n\nfunction releaseApply(): void {\n delete (globalThis as Record<string, unknown>)[APPLY_CLAIM]\n}\n\n/**\n * Required client services: slots, locale, the Host model catalog, and the\n * settings domain's shared configuration forms (the 0.1.7 successor of the\n * removed `settingsScope` service). Each Remote namespace is its own service,\n * so `remote.session` must be declared here or reading it throws.\n */\nexport const inject = ['slots', 'configForms', 'locale', 'remote', 'remote.session']\n\n/** Mount the browser half. */\nexport function apply(ctx: Context): void {\n if (!claimApply()) return\n\n // Resolve through ctx.get with an explicit type rather than ctx.configForms:\n // the settings package's cordis Context merge only applies when its types\n // resolve to the same cordis module identity, which is not guaranteed for an\n // npm-installed plugin (symlinked workspace checkouts diverge).\n const configForms = ctx.get('configForms') as ConfigForms\n const form = configForms.get<ConfigShape>(NS)\n\n // Resolve through ctx.get with an explicit type rather than ctx.locale: the\n // locale package's cordis Context merge only applies when its types resolve\n // to the same cordis module identity, which is not guaranteed for an\n // npm-installed plugin (symlinked workspace checkouts diverge).\n const locale = ctx.get('locale') as unknown as LocaleRuntime\n ctx.effect(() => locale.register(NS, { zh, en }), 'dsh-hypatia-auto-memory: locale dictionaries')\n // Bound before either registration below: the plugins tab label and the\n // Memory tab label both read through it so they follow the active locale\n // without re-registration, exactly as ui-trajectory's does.\n const t = locale.bind(NS)\n\n const loadModelCatalog: LoadConsolidationModelCatalog = async () => {\n const response = await ctx.remote.session.modelCatalog()\n if (!response.ok) throw new Error(`${response.error.code}: ${response.error.message}`)\n return {\n groups: response.value.groups,\n partial: response.value.failures.length > 0,\n }\n }\n // The shelf listing comes from the Host's own route family: the 0.1.7\n // settings document only projects plugin Config forms, so the read-only\n // inventory namespace this used to ride can no longer be published.\n const loadShelfInventory: LoadShelfInventory = fetchShelves\n const renderCard = (props: PropsLocale<typeof NS>) => createElement(SettingsCard, {\n scope: form,\n loadModelCatalog,\n loadShelfInventory,\n ...props,\n })\n // The card exists only while the Host serves our namespace; whileServed owns\n // the watch and hands us a disposer for whichever seat is live. Both\n // registrations are written plainly and the installer catches the refusal an\n // undeclared seat throws — a harness without the Plugins page answers that way.\n const unregister = ctx.effect(() => configForms.whileServed([NS], () =>\n installPluginCard(ctx, {\n official: () => ctx.slots.register(\n { name: BUNDLE_CONFIG_SEAT, key: BUNDLE_NAME, locale: NS },\n renderCard,\n ),\n settingsTab: () => ctx.slots.register(\n { name: SETTINGS_TAB_SEAT, id: NS, label: () => t('title'), locale: NS },\n renderCard,\n ),\n onRefused: (seat, error) => {\n console.warn(`[${BUNDLE_NAME}] configuration card refused by slot \"${seat}\"`, error)\n },\n }),\n ), 'dsh-hypatia-auto-memory: configuration card seat')\n\n // The Memory tab's data: one same-origin request to the route family this\n // plugin's Host half registers (see `src/memory-api.js`) — the same family\n // the shelf listing above rides — parameterized by the session the tab is\n // bound to.\n const unregisterMemoryView = ctx.slots.inject('conversation.view', () =>\n ctx.slots.register(\n {\n name: 'conversation.view',\n id: 'memory',\n // After Chat (0) and Trajectory (10).\n order: 20,\n locale: NS,\n label: () => t('viewMemory'),\n inject: () => ({ fetch: fetchMemory }),\n },\n MemoryView,\n ),\n )\n\n ctx.effect(() => () => {\n unregister()\n unregisterMemoryView()\n releaseApply()\n })\n}\n"],"mappings":"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"}
|