dsh-remember 0.2.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/client.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","names":["FIELD_SPECS: readonly FieldSpec[]","scope: ScopeView","loadCatalog: (() => Promise<CatalogModel[]>) | null","fields: FieldState[]","plan: Array<{ field: string; clear: boolean; value?: unknown }>","BORDER","name","t: (key: string) => string","state: CardState","styleInjected","t: (key: string) => string","panelStyle: Record<string, unknown>","scope: Element | null","EMPTY_TEXTS: Texts","ZH: Record<string, string>","EN: Record<string, string>","sidebarRight: ClientContext['sidebarRight']"],"sources":["../src/client/store.ts","../src/client/memory-card.ts","../src/client/sidebar-action.ts","../src/client/citation-stripper.ts","../src/client/memory-viewer.ts","../src/client/index.ts"],"sourcesContent":["/** Minimal observable snapshot store (useSyncExternalStore-compatible). */\nexport class SnapshotStore<S> {\n private snapshot: S\n private readonly listeners = new Set<() => void>()\n\n constructor(initial: S) {\n this.snapshot = initial\n }\n\n getSnapshot = (): S => this.snapshot\n\n subscribe = (listener: () => void): (() => void) => {\n this.listeners.add(listener)\n return () => {\n this.listeners.delete(listener)\n }\n }\n\n set(next: S): void {\n if (Object.is(next, this.snapshot)) return\n this.snapshot = next\n for (const listener of [...this.listeners]) listener()\n }\n}\n","/**\n * The memory settings page: a staged-edit form over the `memory` settings\n * namespace, rendered as its own Settings section. Draft text is what a save\n * would store, and each field shows whether the user layer carries it.\n * Rendered with plain createElement — no JSX transform in this bundle.\n */\n\nimport { createElement, useEffect, useRef, useState } from 'react'\n\nimport { SnapshotStore } from './store.ts'\nimport type { CatalogModel, ScopeView } from './types.ts'\n\nlet pageStyleInjected = false\n\n/** Interactive styles (inline styles cannot express :hover/:focus). */\nfunction ensurePageStyles(): void {\n if (pageStyleInjected || typeof document === 'undefined') return\n if (document.querySelector('style[data-dsh-memory-page]') != null) {\n pageStyleInjected = true\n return\n }\n const tag = document.createElement('style')\n tag.dataset.dshMemoryPage = 'true'\n tag.textContent = [\n '@keyframes dsh-memory-pulse { 0% { opacity: 0.35; transform: scale(0.8); } 50% { opacity: 1; transform: scale(1.08); } 100% { opacity: 0.35; transform: scale(0.8); } }',\n '.dshm-btn { transition: border-color 150ms ease, background 150ms ease, color 150ms ease, opacity 150ms ease, transform 100ms ease; }',\n '.dshm-btn:hover:not(:disabled) { border-color: var(--dsw-alias-brand-primary, #4b7bec); opacity: 1; background: rgba(75, 123, 236, 0.10); }',\n '.dshm-btn:active:not(:disabled) { transform: translateY(1px); }',\n '.dshm-btn:focus-visible { outline: 2px solid rgba(75, 123, 236, 0.5); outline-offset: 1px; }',\n '.dshm-input { transition: border-color 150ms ease, box-shadow 150ms ease, background 150ms ease; outline: none; }',\n '.dshm-input:hover:not(:disabled) { border-color: rgba(128, 128, 128, 0.45); }',\n '.dshm-input:focus { border-color: var(--dsw-alias-brand-primary, #4b7bec); box-shadow: 0 0 0 3px rgba(75, 123, 236, 0.18); background: var(--dsw-alias-bg-base, transparent); }',\n '.dshm-row + .dshm-row { border-top: 1px solid var(--dsw-alias-border-l2, rgba(128, 128, 128, 0.12)); }',\n // Switch: DSH's Switch primitive spec (36x20 track, 16px thumb), keyed off\n // aria-checked so the paint cannot disagree with assistive state.\n '.dshm-switch { box-sizing: border-box; position: relative; flex: 0 0 auto; width: 36px; height: 20px; padding: 2px; border: 0; border-radius: 10px; corner-shape: round; background: var(--dsw-alias-border-l3, rgba(128, 128, 128, 0.45)); cursor: pointer; }',\n '.dshm-switch[aria-checked=\"true\"] { background: var(--dsw-alias-brand-primary, #4b7bec); }',\n '.dshm-switch:disabled { cursor: default; opacity: 0.5; }',\n '.dshm-switch:focus-visible { outline: 2px solid var(--dsw-alias-brand-primary, #4b7bec); outline-offset: 2px; }',\n '.dshm-thumb { display: block; width: 16px; height: 16px; border-radius: 50%; corner-shape: round; background: var(--dsw-alias-label-primary-foreground, #fff); transition: transform 120ms ease; }',\n '.dshm-switch[aria-checked=\"true\"] .dshm-thumb { transform: translateX(16px); }',\n '.dshm-advanced-head { transition: background 120ms ease; border-radius: 8px; }',\n '.dshm-advanced-head:hover { background: rgba(128, 128, 128, 0.07); }',\n ].join('\\n')\n document.head.appendChild(tag)\n pageStyleInjected = true\n}\n\nexport type FieldKind = 'string' | 'number' | 'boolean' | 'list' | 'model'\n\nexport interface FieldSpec {\n field: string\n kind: FieldKind\n group: string\n}\n\n/**\n * Every MemoryPluginConfig field, grouped for display. `advanced` collects the\n * knobs a routine user never touches (paths, backoff/retry tuning, the\n * consolidator denylist) behind a collapsed section.\n */\nexport const FIELD_SPECS: readonly FieldSpec[] = [\n { field: 'enabled', kind: 'boolean', group: 'general' },\n { field: 'generateMemories', kind: 'boolean', group: 'general' },\n { field: 'useMemories', kind: 'boolean', group: 'general' },\n { field: 'extractModel', kind: 'model', group: 'models' },\n { field: 'consolidationModel', kind: 'model', group: 'models' },\n { field: 'scanIntervalMinutes', kind: 'number', group: 'schedule' },\n { field: 'minRolloutIdleHours', kind: 'number', group: 'schedule' },\n { field: 'maxSessionAgeDays', kind: 'number', group: 'schedule' },\n { field: 'maxUnusedDays', kind: 'number', group: 'schedule' },\n { field: 'summaryTokenLimit', kind: 'number', group: 'recall' },\n { field: 'redactSecrets', kind: 'boolean', group: 'recall' },\n { field: 'workspaceDir', kind: 'string', group: 'advanced' },\n { field: 'dbPath', kind: 'string', group: 'advanced' },\n { field: 'phase2TimeoutMinutes', kind: 'number', group: 'advanced' },\n { field: 'phase2SuccessCooldownSeconds', kind: 'number', group: 'advanced' },\n { field: 'phase1RetryBackoffMinutes', kind: 'number', group: 'advanced' },\n { field: 'phase1MaxRetries', kind: 'number', group: 'advanced' },\n { field: 'phase1MaxPerCycle', kind: 'number', group: 'advanced' },\n { field: 'phase1MaxConcurrency', kind: 'number', group: 'advanced' },\n { field: 'extractInputContextRatio', kind: 'number', group: 'advanced' },\n { field: 'maxRolloutSummaries', kind: 'number', group: 'advanced' },\n { field: 'consolidatorDenyPatterns', kind: 'list', group: 'advanced' },\n]\n\nconst FIELD_ORDER = new Map(FIELD_SPECS.map((spec, index) => [spec.field, index]))\n\ninterface FieldState {\n spec: FieldSpec\n text: string\n overridden: boolean\n invalid: boolean\n}\n\nexport interface CardState {\n available: boolean\n writable: boolean\n dirty: boolean\n invalid: boolean\n saving: boolean\n failed: boolean\n catalogStatus: 'unavailable' | 'loading' | 'ready' | 'error'\n catalogModels: CatalogModel[]\n fields: FieldState[]\n}\n\ninterface StagedEdit {\n text: string\n clear: boolean\n}\n\n/** Debounce between the last edit and its automatic commit. */\nconst AUTOSAVE_DELAY_MS = 500\n\nfunction formatValue(spec: FieldSpec, value: unknown): string {\n if (value === undefined || value === null) return ''\n if (spec.kind === 'boolean') return value === true ? 'true' : 'false'\n if (spec.kind === 'list') return Array.isArray(value) ? value.join(', ') : ''\n return String(value)\n}\n\nfunction parseValue(spec: FieldSpec, text: string): { ok: boolean; value?: unknown } {\n const trimmed = text.trim()\n if (spec.kind === 'boolean') {\n if (trimmed === 'true') return { ok: true, value: true }\n if (trimmed === 'false') return { ok: true, value: false }\n return { ok: false }\n }\n if (trimmed === '') return { ok: true, value: undefined } // clear\n if (spec.kind === 'number') {\n const parsed = Number(trimmed)\n return Number.isFinite(parsed) ? { ok: true, value: parsed } : { ok: false }\n }\n if (spec.kind === 'list') {\n const items = trimmed.split(',').map((item) => item.trim()).filter((item) => item !== '')\n return items.length > 0 ? { ok: true, value: items } : { ok: true, value: undefined }\n }\n return { ok: true, value: trimmed }\n}\n\nexport class MemoryCardController {\n private readonly staged = new Map<string, StagedEdit>()\n private readonly store: SnapshotStore<CardState>\n private saving = false\n private failed = false\n private autosaveTimer: ReturnType<typeof setTimeout> | null = null\n private catalogStatus: 'unavailable' | 'loading' | 'ready' | 'error'\n private catalogModels: CatalogModel[] = []\n\n constructor(\n private readonly scope: ScopeView,\n private readonly loadCatalog: (() => Promise<CatalogModel[]>) | null,\n ) {\n this.catalogStatus = loadCatalog == null ? 'unavailable' : 'loading'\n this.store = new SnapshotStore(this.project())\n scope.subscribe(() => {\n this.store.set(this.project())\n })\n if (loadCatalog != null) void this.refreshCatalog()\n }\n\n /** Re-query the Host model catalog (exposed as a page action). */\n async refreshCatalog(): Promise<void> {\n if (this.loadCatalog == null) return\n this.catalogStatus = 'loading'\n this.publish()\n try {\n this.catalogModels = await this.loadCatalog()\n this.catalogStatus = 'ready'\n } catch {\n this.catalogStatus = 'error'\n }\n this.publish()\n }\n\n /** The observable page snapshot source for the section's hooks seat. */\n pageStore(): SnapshotStore<CardState> {\n return this.store\n }\n\n inject(): Record<string, unknown> {\n return {\n hooks: { memoryPage: this.store },\n edit: (field: string, text: string) => {\n this.staged.set(field, { text, clear: false })\n this.failed = false\n this.publish()\n this.scheduleAutosave()\n },\n resetField: (field: string) => {\n const spec = this.specOf(field)\n const base = (this.scope.getSnapshot().base as Record<string, unknown> | undefined)?.[field]\n this.staged.set(field, { text: formatValue(spec, base), clear: true })\n this.failed = false\n this.publish()\n this.scheduleAutosave()\n },\n refreshCatalog: () => {\n void this.refreshCatalog()\n },\n }\n }\n\n /** Auto-commit pending edits once typing pauses (checkbox/select/reset included). */\n private scheduleAutosave(): void {\n if (this.autosaveTimer != null) clearTimeout(this.autosaveTimer)\n this.autosaveTimer = setTimeout(() => {\n this.autosaveTimer = null\n void this.save()\n }, AUTOSAVE_DELAY_MS)\n }\n\n private specOf(field: string): FieldSpec {\n const spec = FIELD_SPECS.find((candidate) => candidate.field === field)\n if (spec == null) throw new Error(`memory page has no field ${field}`)\n return spec\n }\n\n private project(): CardState {\n const snapshot = this.scope.getSnapshot()\n const section = (snapshot.value ?? {}) as Record<string, unknown>\n const user = snapshot.user as Record<string, unknown> | undefined\n const fields: FieldState[] = [...FIELD_SPECS]\n .sort((a, b) => (FIELD_ORDER.get(a.field) ?? 0) - (FIELD_ORDER.get(b.field) ?? 0))\n .map((spec) => {\n const staged = this.staged.get(spec.field)\n if (staged === undefined) {\n return {\n spec,\n text: formatValue(spec, section[spec.field]),\n overridden: user !== undefined && Object.hasOwn(user, spec.field),\n invalid: false,\n }\n }\n const parsed = parseValue(spec, staged.text)\n return {\n spec,\n text: staged.text,\n overridden: staged.clear ? false : parsed.ok && parsed.value !== undefined,\n invalid: !staged.clear && !parsed.ok,\n }\n })\n return {\n available: snapshot.status === 'ready',\n writable: snapshot.writable,\n dirty: this.plan(fields).length > 0,\n invalid: fields.some((field) => field.invalid),\n saving: this.saving,\n failed: this.failed,\n catalogStatus: this.catalogStatus,\n catalogModels: this.catalogModels,\n fields,\n }\n }\n\n /** Staged edits a save would perform, in field order. */\n private plan(fields: FieldState[]): Array<{ field: string; clear: boolean; value?: unknown }> {\n const section = (this.scope.getSnapshot().value ?? {}) as Record<string, unknown>\n const plan: Array<{ field: string; clear: boolean; value?: unknown }> = []\n for (const field of fields) {\n const staged = this.staged.get(field.spec.field)\n if (staged === undefined) continue\n if (staged.clear) {\n if (field.overridden) plan.push({ field: field.spec.field, clear: true })\n continue\n }\n const parsed = parseValue(field.spec, staged.text)\n if (!parsed.ok) continue\n if (formatValue(field.spec, section[field.spec.field]) === staged.text.trim()) continue\n if (parsed.value === undefined) {\n plan.push({ field: field.spec.field, clear: true })\n } else {\n plan.push({ field: field.spec.field, clear: false, value: parsed.value })\n }\n }\n return plan\n }\n\n private async save(): Promise<void> {\n const fields = this.project().fields\n const plan = this.plan(fields)\n if (plan.length === 0 || plan.some((item) => !item.clear && item.value === undefined)) return\n if (this.saving) {\n // A write is crossing the wire; retry the just-staged edit after it lands.\n this.scheduleAutosave()\n return\n }\n this.saving = true\n this.failed = false\n this.publish()\n let landed = true\n for (const item of plan) {\n try {\n if (item.clear) await this.scope.unset(item.field)\n else await this.scope.set(item.field, item.value)\n } catch {\n landed = false\n }\n }\n // Drop only the committed keys: edits staged while the write was in\n // flight keep their own pending autosave.\n if (landed) for (const item of plan) this.staged.delete(item.field)\n this.saving = false\n this.failed = !landed\n this.publish()\n }\n\n private publish(): void {\n this.store.set(this.project())\n }\n}\n\n// ── styling ─────────────────────────────────────────────────────────────────\n\nconst ACCENT = 'var(--dsw-alias-brand-primary, #4b7bec)'\nconst BORDER = 'var(--dsw-alias-border-l2, rgba(128, 128, 128, 0.2))'\nconst DANGER = '#e05561'\nconst MUTED = 'var(--dsw-alias-label-secondary, rgba(128, 128, 128, 0.9))'\n\nfunction sectionStyle(): Record<string, unknown> {\n return { marginTop: 26 }\n}\n\nfunction sectionHeaderStyle(): Record<string, unknown> {\n return {\n fontSize: 11,\n fontWeight: 650,\n letterSpacing: 1.1,\n textTransform: 'uppercase',\n opacity: 0.5,\n margin: '0 2px 2px',\n }\n}\n\nfunction rowStyle(): Record<string, unknown> {\n return {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 20,\n minHeight: 34,\n padding: '9px 2px',\n }\n}\n\nfunction labelStackStyle(): Record<string, unknown> {\n return { display: 'flex', flexDirection: 'column', gap: 2, minWidth: 0 }\n}\n\nfunction inputStyle(invalid: boolean): Record<string, unknown> {\n return {\n width: 230,\n boxSizing: 'border-box',\n padding: '6px 10px',\n fontSize: 12.5,\n borderRadius: 8,\n border: `1px solid ${invalid ? DANGER : BORDER}`,\n background: 'var(--dsw-alias-fill-tertiary, rgba(128, 128, 128, 0.06))',\n color: 'inherit',\n textAlign: 'left',\n }\n}\n\nfunction ghostButtonStyle(disabled: boolean): Record<string, unknown> {\n return {\n fontSize: 12,\n padding: '4px 12px',\n borderRadius: 8,\n cursor: disabled ? 'default' : 'pointer',\n border: `1px solid ${BORDER}`,\n background: 'transparent',\n color: 'inherit',\n opacity: disabled ? 0.4 : 0.8,\n }\n}\n\nfunction primaryButtonStyle(disabled: boolean): Record<string, unknown> {\n // Shell button tokens: a filled primary, not a washed-out translucent tint.\n return {\n fontSize: 12,\n padding: '4px 14px',\n borderRadius: 8,\n cursor: disabled ? 'default' : 'pointer',\n border: '1px solid transparent',\n background: disabled ? 'transparent' : 'var(--dsw-alias-button-info-fill, #4d6bfe)',\n color: disabled ? 'inherit' : 'var(--dsw-alias-label-primary-inverted, #fff)',\n fontWeight: 600,\n opacity: disabled ? 0.4 : 1,\n }\n}\n\nfunction badgeStyle(): Record<string, unknown> {\n return {\n fontSize: 10,\n padding: '1px 7px',\n borderRadius: 999,\n background: 'var(--dsw-alias-state-business-tertiary, rgba(75, 123, 236, 0.14))',\n color: ACCENT,\n whiteSpace: 'nowrap',\n }\n}\n\n// ── components ──────────────────────────────────────────────────────────────\n\n/** Toggle switch for boolean fields (replaces the bare checkbox). */\nfunction Switch(props: { on: boolean; disabled: boolean; label?: string; onToggle: (next: boolean) => void }) {\n return createElement('button', {\n type: 'button',\n role: 'switch',\n 'aria-checked': props.on,\n 'aria-label': props.label,\n disabled: props.disabled,\n className: 'dshm-switch',\n onClick: () => props.onToggle(!props.on),\n }, createElement('span', { className: 'dshm-thumb' }))\n}\n\nfunction FieldRow(props: {\n t: (key: string) => string\n state: FieldState\n disabled: boolean\n catalogModels?: CatalogModel[]\n onEdit: (text: string) => void\n onReset: () => void\n}) {\n const { t, state, disabled } = props\n const hint = hintText(t, state.spec.field)\n let control\n if (state.spec.kind === 'boolean') {\n control = createElement(Switch, {\n on: state.text === 'true',\n disabled,\n label: t(`field_${state.spec.field}`),\n onToggle: (next: boolean) => props.onEdit(next ? 'true' : 'false'),\n })\n } else if (state.spec.kind === 'model') {\n control = createElement(ModelSelect, {\n t,\n state,\n catalogModels: props.catalogModels ?? [],\n disabled,\n onEdit: props.onEdit,\n })\n } else {\n control = createElement('input', {\n type: 'text',\n value: state.text,\n disabled,\n spellCheck: false,\n className: 'dshm-input',\n onChange: (event: { target: { value: string } }) => {\n props.onEdit(event.target.value)\n },\n style: inputStyle(state.invalid),\n })\n }\n return createElement('div', { key: state.spec.field, className: 'dshm-row', style: rowStyle() },\n createElement('div', { style: labelStackStyle() },\n createElement('span', { style: { fontSize: 13 } }, fieldLabel(t, state.spec.field)),\n hint !== ''\n ? createElement('span', { style: { fontSize: 11.5, opacity: 0.5 } }, hint)\n : null,\n ),\n createElement('div', { style: { display: 'flex', alignItems: 'center', gap: 8, flexShrink: 0 } },\n state.overridden ? createElement('span', { style: badgeStyle() }, t('overridden')) : null,\n state.overridden\n ? createElement('button', {\n type: 'button',\n disabled,\n className: 'dshm-btn',\n onClick: props.onReset,\n style: ghostButtonStyle(disabled),\n }, t('reset'))\n : null,\n control,\n ),\n )\n}\n\n/** Dropdown over the Host model catalog; empty value = deployment default. */\nfunction ModelSelect(props: {\n t: (key: string) => string\n state: FieldState\n catalogModels: CatalogModel[]\n disabled: boolean\n onEdit: (text: string) => void\n}) {\n const { t, state, catalogModels } = props\n const current = state.text\n const options = [createElement('option', { key: '__default__', value: '' }, t('modelDefault'))]\n for (const model of catalogModels) {\n const value = `${model.provider}/${model.model}`\n options.push(createElement('option', { key: value, value }, `${model.modelName} · ${model.providerName}`))\n }\n if (current !== '' && !catalogModels.some((model) => `${model.provider}/${model.model}` === current)) {\n options.push(createElement('option', { key: current, value: current }, current))\n }\n return createElement('select', {\n value: current,\n disabled: props.disabled,\n className: 'dshm-input',\n onChange: (event: { target: { value: string } }) => {\n props.onEdit(event.target.value)\n },\n style: inputStyle(false),\n }, options)\n}\n\ninterface CommandsView {\n set(field: string, value: unknown): Promise<void>\n}\n\n/** Upper bound for an import traveling base64 through the settings mirror. */\nconst IMPORT_LIMIT_BYTES = 32 * 1024 * 1024\n\n/** Save bundle bytes: native save dialog where available, download fallback. */\nasync function saveBundleFile(name: string, base64: string): Promise<void> {\n const binary = atob(base64)\n const bytes = new Uint8Array(binary.length)\n for (let index = 0; index < binary.length; index += 1) bytes[index] = binary.charCodeAt(index)\n const picker = (window as unknown as {\n showSaveFilePicker?: (options: { suggestedName: string }) => Promise<{\n createWritable: () => Promise<{ write: (data: Uint8Array) => Promise<void>; close: () => Promise<void> }>\n }>\n }).showSaveFilePicker\n if (picker != null) {\n try {\n const handle = await picker.call(window, { suggestedName: name })\n const writable = await handle.createWritable()\n await writable.write(bytes)\n await writable.close()\n return\n } catch (error) {\n if ((error as { name?: string })?.name === 'AbortError') return\n // picker failed for another reason — fall through to the download path\n }\n }\n const url = URL.createObjectURL(new Blob([bytes]))\n const anchor = document.createElement('a')\n anchor.href = url\n anchor.download = name\n anchor.click()\n setTimeout(() => URL.revokeObjectURL(url), 1_000)\n}\n\n/**\n * Import/export entry: export asks the host for the bundle and saves it via\n * the browser's file dialog; import reads a picked file and ships it base64\n * through the memory-commands channel. Outcomes come back as `transfer:`-\n * prefixed status detail lines.\n */\nfunction TransferSection(props: {\n t: (key: string) => string\n commands?: CommandsView\n statusDetail?: string\n exportBundle?: { name: string; data: string; at: number }\n}) {\n const { t, commands } = props\n const [requested, setRequested] = useState<'export' | 'import' | null>(null)\n const [localError, setLocalError] = useState('')\n const fileInput = useRef<HTMLInputElement | null>(null)\n const lastExportAt = useRef(0)\n\n const send = (action: string, path = '', payload = ''): void => {\n if (commands == null) return\n void (async () => {\n // Order matters: path/payload/action must land before the timestamp trigger.\n await commands.set('path', path)\n await commands.set('payload', payload)\n await commands.set('action', action)\n await commands.set('requestedAt', Date.now())\n })()\n }\n\n // A fresh export bundle arrived from the host: save it once per exportAt.\n const bundleAt = props.exportBundle?.at ?? 0\n useEffect(() => {\n const bundle = props.exportBundle\n if (bundle == null || bundle.data === '' || bundle.at <= lastExportAt.current) return undefined\n lastExportAt.current = bundle.at\n void saveBundleFile(bundle.name, bundle.data).finally(() => send('export-done'))\n return undefined\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [bundleAt])\n\n const pickImport = (event: { target: { files?: FileList | null; value: string } }): void => {\n const file = event.target.files?.[0]\n event.target.value = ''\n if (file == null) return\n if (file.size > IMPORT_LIMIT_BYTES) {\n setLocalError(t('transfer_tooBig'))\n return\n }\n setLocalError('')\n setRequested('import')\n const reader = new FileReader()\n reader.onload = () => {\n const result = String(reader.result ?? '')\n send('import', '', result.slice(result.indexOf(',') + 1))\n }\n reader.onerror = () => setLocalError(t('transfer_readFailed'))\n reader.readAsDataURL(file)\n }\n\n const feedback = localError !== ''\n ? localError\n : props.statusDetail?.startsWith('transfer:') === true\n ? props.statusDetail.slice('transfer:'.length).trim()\n : null\n const feedbackIsError = feedback != null && (localError !== '' || /fail|need|must|unsupported|error/iu.test(feedback))\n\n const transferRow = (labelKey: string, descKey: string, action: 'export' | 'import') =>\n createElement('div', { className: 'dshm-row', style: rowStyle() },\n createElement('div', { style: labelStackStyle() },\n createElement('span', { style: { fontSize: 13 } }, t(labelKey)),\n createElement('span', { style: { fontSize: 11.5, opacity: 0.5 } }, t(descKey)),\n ),\n createElement('button', {\n type: 'button',\n disabled: commands == null,\n className: 'dshm-btn',\n onClick: () => {\n setLocalError('')\n setRequested(action)\n if (action === 'export') send('export')\n else fileInput.current?.click()\n },\n style: primaryButtonStyle(commands == null),\n }, t(`transfer_${action}`)),\n )\n\n return createElement('section', { style: sectionStyle() },\n createElement('h3', { style: sectionHeaderStyle() }, t('group_transfer')),\n createElement('div', { style: { borderTop: `1px solid ${BORDER}` } },\n transferRow('transfer_exportLabel', 'transfer_exportDesc', 'export'),\n transferRow('transfer_importLabel', 'transfer_importDesc', 'import'),\n ),\n createElement('input', {\n type: 'file',\n accept: '.json,.gz,.dshmem',\n ref: fileInput,\n style: { display: 'none' },\n onChange: pickImport,\n }),\n createElement('div', { style: { minHeight: 18, margin: '4px 2px 0' } },\n feedback != null\n ? createElement('span', { style: { fontSize: 12, color: feedbackIsError ? DANGER : 'inherit', opacity: feedbackIsError ? 1 : 0.8 } }, feedback)\n : requested != null\n ? createElement('span', { style: { fontSize: 12, opacity: 0.55 } }, t('transfer_requested'))\n : null,\n ),\n )\n}\n\n/** Collapsible section for the expert knobs (paths, retry tuning, denylist). */\nfunction AdvancedSection(props: {\n t: (key: string) => string\n fields: FieldState[]\n disabled: boolean\n onEdit: (field: string, text: string) => void\n onReset: (field: string) => void\n}) {\n const [open, setOpen] = useState(false)\n const { t } = props\n return createElement('section', { style: sectionStyle() },\n createElement('button', {\n type: 'button',\n className: 'dshm-advanced-head',\n onClick: () => setOpen(!open),\n style: {\n display: 'flex', alignItems: 'center', gap: 6, width: '100%',\n padding: '4px 6px 4px 2px', border: 'none', background: 'transparent',\n color: 'inherit', cursor: 'pointer', textAlign: 'left',\n },\n },\n createElement('span', {\n style: {\n fontSize: 9, opacity: 0.55, display: 'inline-block',\n transform: open ? 'rotate(90deg)' : 'none',\n transition: 'transform 150ms ease',\n },\n }, '▶'),\n createElement('span', { style: { ...sectionHeaderStyle(), margin: 0 } }, t('group_advanced')),\n !open\n ? createElement('span', { style: { fontSize: 11, opacity: 0.4 } }, `${props.fields.length}`)\n : null,\n ),\n open\n ? createElement('div', { style: { borderTop: `1px solid ${BORDER}` } },\n ...props.fields.map((field) => createElement(FieldRow, {\n key: field.spec.field,\n t,\n state: field,\n disabled: props.disabled,\n onEdit: (text: string) => props.onEdit(field.spec.field, text),\n onReset: () => props.onReset(field.spec.field),\n })),\n )\n : null,\n )\n}\n\nfunction fieldLabel(t: (key: string) => string, field: string): string {\n return t(`field_${field}`)\n}\n\nfunction hintText(t: (key: string) => string, field: string): string {\n const hint = t(`hint_${field}`)\n return hint === `hint_${field}` ? '' : hint\n}\n\n/**\n * The dedicated Memory settings page (occupies one `settings.section` seat):\n * live status banner, divided-list sections with catalog-backed model pickers\n * and toggle switches, transfer actions, and a collapsed advanced section.\n * Render failures surface inline instead of blanking the panel.\n */\nexport function MemorySettingsPage(props: Record<string, any>) {\n try {\n return renderMemoryPage(props)\n } catch (error) {\n return createElement('div', {\n style: { fontSize: 12.5, color: DANGER, maxWidth: 640, whiteSpace: 'pre-wrap' },\n }, `memory settings page error: ${String(error)}`)\n }\n}\n\nfunction renderMemoryPage(props: Record<string, any>) {\n if (props.useMemoryPage == null) {\n return createElement('div', { style: { fontSize: 13, opacity: 0.6 } }, 'renderer did not bind the memory page hook')\n }\n ensurePageStyles()\n const t: (key: string) => string = props.t\n const state: CardState = props.useMemoryPage((value: CardState) => value)\n const statusSnapshot = props.useMemoryStatus != null\n ? props.useMemoryStatus((value: unknown) => value) as\n | { status: string; value?: { phase?: string; detail?: string; updatedAt?: number } }\n | undefined\n : undefined\n if (!state.available) {\n return createElement('div', { style: { fontSize: 13, opacity: 0.6 } }, t('unavailable'))\n }\n const disabled = !state.writable\n\n const status = statusSnapshot?.status === 'ready' ? statusSnapshot.value : undefined\n const viewSnapshot = props.useMemoryView != null\n ? props.useMemoryView((value: unknown) => value) as\n | { status: string; value?: { exportName?: string; exportData?: string; exportAt?: number } }\n | undefined\n : undefined\n const viewValue = viewSnapshot?.status === 'ready' ? viewSnapshot.value : undefined\n const exportBundle = viewValue != null && (viewValue.exportData ?? '') !== ''\n ? { name: viewValue.exportName ?? 'memory.dshmem', data: viewValue.exportData as string, at: viewValue.exportAt ?? 0 }\n : undefined\n const active = status?.phase === 'phase1' || status?.phase === 'phase2'\n const statusLabel = active\n ? (status?.phase === 'phase1' ? t('phase1') : t('phase2'))\n : t('statusIdle')\n\n const groups = new Map<string, FieldState[]>()\n for (const field of state.fields) {\n const list = groups.get(field.spec.group) ?? []\n list.push(field)\n groups.set(field.spec.group, list)\n }\n\n const fieldSection = (group: string) => {\n const fields = groups.get(group)\n if (fields == null || fields.length === 0) return null\n return createElement('section', { key: group, style: sectionStyle() },\n createElement('div', { style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', margin: '0 2px 2px' } },\n createElement('h3', { style: { ...sectionHeaderStyle(), margin: 0 } }, t(`group_${group}`)),\n group === 'models'\n ? createElement('button', {\n type: 'button',\n className: 'dshm-btn',\n onClick: props.refreshCatalog,\n style: { ...ghostButtonStyle(false), border: 'none', padding: '2px 6px', fontSize: 11.5 },\n }, state.catalogStatus === 'loading' ? t('catalogLoading') : t('catalogRefresh'))\n : null,\n ),\n group === 'models' && state.catalogStatus === 'error'\n ? createElement('div', { style: { fontSize: 11.5, color: DANGER, margin: '0 2px 4px' } }, t('catalogError'))\n : null,\n createElement('div', { style: { borderTop: `1px solid ${BORDER}` } },\n ...fields.map((field) => createElement(FieldRow, {\n key: field.spec.field,\n t,\n state: field,\n disabled,\n catalogModels: state.catalogModels,\n onEdit: (text: string) => props.edit(field.spec.field, text),\n onReset: () => props.resetField(field.spec.field),\n })),\n ),\n )\n }\n\n return createElement('div', { style: { maxWidth: 640, paddingBottom: 32 } },\n createElement('h2', { style: { fontSize: 19, fontWeight: 650, margin: '0 0 4px', letterSpacing: 0.2 } }, t('title')),\n createElement('p', { style: { fontSize: 13, opacity: 0.6, margin: '0 0 18px', lineHeight: 1.5 } }, t('intro')),\n // status banner\n createElement('div', {\n style: {\n border: `1px solid ${active ? ACCENT : BORDER}`,\n borderRadius: 10,\n padding: '10px 14px',\n display: 'flex', alignItems: 'center', gap: 10,\n background: active ? 'rgba(75, 123, 236, 0.07)' : 'transparent',\n transition: 'border-color 200ms ease, background 200ms ease',\n },\n },\n createElement('span', {\n style: {\n width: 8, height: 8, borderRadius: '50%', flexShrink: 0,\n background: active ? ACCENT : MUTED,\n animation: active ? 'dsh-memory-pulse 1.4s ease-in-out infinite' : undefined,\n },\n }),\n createElement('span', { style: { fontSize: 12.5, fontWeight: 600, flexShrink: 0 } }, statusLabel),\n status?.detail\n ? createElement('span', { style: { fontSize: 12, opacity: 0.6, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' } }, status.detail)\n : null,\n createElement('span', { style: { fontSize: 11, opacity: 0.4, marginLeft: 'auto', flexShrink: 0 } },\n status?.updatedAt ? new Date(status.updatedAt).toLocaleTimeString() : ''),\n ),\n fieldSection('general'),\n fieldSection('models'),\n fieldSection('schedule'),\n fieldSection('recall'),\n createElement(TransferSection, { t, commands: props.commands, statusDetail: status?.detail, exportBundle }),\n createElement(AdvancedSection, {\n t,\n fields: groups.get('advanced') ?? [],\n disabled,\n onEdit: (field: string, text: string) => props.edit(field, text),\n onReset: (field: string) => props.resetField(field),\n }),\n // Auto-save status line (no manual save/discard): edits commit on pause.\n createElement('div', { style: { display: 'flex', alignItems: 'center', gap: 10, marginTop: 14, minHeight: 22 } },\n state.saving ? createElement('span', { style: { fontSize: 12, opacity: 0.6 } }, t('saving')) : null,\n state.failed ? createElement('span', { style: { fontSize: 12, color: DANGER } }, t('failed')) : null,\n state.invalid ? createElement('span', { style: { fontSize: 12, color: DANGER } }, t('invalid')) : null,\n !state.writable ? createElement('span', { style: { fontSize: 12, opacity: 0.6 } }, t('readOnly')) : null,\n ),\n )\n}\n","/**\n * The memory entry in `sidebar.footer.action` — the fixed home of the status\n * surface, in the same seat as DSH's own Cordis panel. The trigger is a footer\n * row (a 36px circle in the collapsed rail) and the panel opens above it:\n * `position: fixed` with an offset measured from the trigger, because the\n * sidebar clips overflow and a 320px surface would otherwise be cut off.\n *\n * Reads the `memory-status` namespace through the client settings mirror\n * (phase/preview arrive via the forwarded settings/document-updated event —\n * no custom RPC) and acts through the `memory-commands` namespace the host\n * watches. Every action lives in the panel.\n */\n\nimport { createElement, useEffect, useLayoutEffect, useRef, useState } from 'react'\nimport type { ScopeView } from './types.ts'\n\ntype SelectorHook = (selector: (value: unknown) => unknown) => unknown\n\nlet styleInjected = false\n\n/** Inject the widget stylesheet once per document (factory-execution side effect). */\nfunction ensureStyles(): void {\n if (styleInjected || typeof document === 'undefined') return\n if (document.querySelector('style[data-dsh-memory-float]') != null) {\n styleInjected = true\n return\n }\n const tag = document.createElement('style')\n tag.dataset.dshMemoryFloat = 'true'\n tag.textContent = [\n '@keyframes dsh-memory-pulse { 0% { opacity: 0.35; transform: scale(0.8); } 50% { opacity: 1; transform: scale(1.08); } 100% { opacity: 0.35; transform: scale(0.8); } }',\n '@keyframes dsh-memory-pop-in { from { opacity: 0; transform: translateY(6px) scale(0.96); } to { opacity: 1; transform: none; } }',\n // Trigger: the Settings trigger row's own geometry (42px row, 36px rail\n // cell, 8px icon inset) so the two foot rows line up.\n '.dshm-layer { position: relative; flex: 1 1 auto; display: flex; align-items: center; min-width: 0; width: calc(100% + 4px); height: 42px; margin: 4px -2px; }',\n '.dshm-layer[data-rail=\"true\"] { flex: none; width: 36px; height: 36px; margin: 8px 0 0; }',\n '.dshm-foot { flex: 1; display: flex; align-items: center; gap: 8px; min-width: 0; height: 42px; margin: 0; padding: 0 10px 0 8px; box-sizing: border-box; border: none; border-radius: 12px; background: transparent; color: var(--dsw-alias-label-primary, #eee); font-family: inherit; font-size: 14px; line-height: 22px; cursor: pointer; overflow: hidden; transition: background 150ms ease; }',\n '.dshm-foot:hover, .dshm-foot[data-open=\"true\"] { background: var(--dsw-alias-interactive-bg-hover, rgba(128,128,128,0.12)); }',\n '.dshm-layer[data-rail=\"true\"] .dshm-foot { flex: none; justify-content: center; gap: 0; width: 36px; height: 36px; padding: 0; border-radius: 50%; }',\n '.dshm-icon { position: relative; display: inline-flex; flex: none; align-items: center; justify-content: center; }',\n '.dshm-dot { position: absolute; right: -1px; bottom: -1px; width: 7px; height: 7px; border-radius: 50%; background: var(--dsw-alias-brand-primary, #4b7bec); animation: dsh-memory-pulse 1.4s ease-in-out infinite; }',\n '.dshm-foot-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }',\n '.dshm-foot-state { flex: none; margin-left: auto; font-size: 12px; line-height: 16px; color: var(--dsw-alias-label-tertiary, rgba(128,128,128,0.9)); }',\n '.dshm-foot-state[data-active=\"true\"] { color: var(--dsw-alias-brand-primary, #4b7bec); }',\n '.dshm-foot-state[data-paused=\"true\"] { color: var(--dsw-alias-state-error-primary, #e05561); }',\n '.dshm-panel { animation: dsh-memory-pop-in 160ms ease; }',\n '.dshm-btn { transition: border-color 150ms ease, background 150ms ease, opacity 150ms ease, transform 100ms ease; }',\n '.dshm-btn:hover:not(:disabled) { border-color: var(--dsw-alias-brand-primary, #4b7bec); opacity: 1; background: rgba(75, 123, 236, 0.12); }',\n '.dshm-btn:active:not(:disabled) { transform: translateY(1px); }',\n '.dshm-preview::-webkit-scrollbar { width: 6px; }',\n '.dshm-preview::-webkit-scrollbar-thumb { background: rgba(128,128,128,0.35); border-radius: 3px; }',\n // Switch: DSH's own Switch primitive spec (36x20 track, 16px thumb), keyed\n // off aria-checked so the paint cannot disagree with assistive state.\n '.dshm-switch { box-sizing: border-box; position: relative; flex: 0 0 auto; width: 36px; height: 20px; padding: 2px; border: 0; border-radius: 10px; corner-shape: round; background: var(--dsw-alias-border-l3, rgba(128,128,128,0.45)); cursor: pointer; }',\n '.dshm-switch[aria-checked=\"true\"] { background: var(--dsw-alias-brand-primary, #4b7bec); }',\n '.dshm-switch:disabled { cursor: default; opacity: 0.5; }',\n '.dshm-switch:focus-visible { outline: 2px solid var(--dsw-alias-brand-primary, #4b7bec); outline-offset: 2px; }',\n '.dshm-thumb { display: block; width: 16px; height: 16px; border-radius: 50%; corner-shape: round; background: var(--dsw-alias-label-primary-foreground, #fff); transition: transform 120ms ease; }',\n '.dshm-switch[aria-checked=\"true\"] .dshm-thumb { transform: translateX(16px); }',\n '.dshm-toggle-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 3px 0; }',\n ].join('\\n')\n document.head.appendChild(tag)\n styleInjected = true\n}\n\nexport interface FloatStatus {\n phase: string\n detail: string\n summaryPreview: string\n updatedAt: number\n}\n\ninterface ActionProps {\n t: (key: string) => string\n /** Owner prop of `sidebar.footer.action`: false while the sidebar is a rail. */\n wide?: boolean\n useMemoryStatus?: SelectorHook\n commands?: ScopeView\n settings?: ScopeView\n /** Opens the standalone memory viewer page (right sidebar tab). */\n openViewer?: () => void\n}\n\n/** The footer action component (slot component props: t + hooks + scopes). */\nexport function MemoryFooterAction(props: ActionProps) {\n try {\n return renderAction(props)\n } catch {\n return null\n }\n}\n\nfunction renderAction(props: ActionProps) {\n if (props.useMemoryStatus == null) return null\n ensureStyles()\n const t: (key: string) => string = props.t\n const wide = props.wide !== false\n\n const statusSnapshot = props.useMemoryStatus((value: unknown) => value) as\n | { status: string; value?: Partial<FloatStatus> }\n | undefined\n const status = statusSnapshot?.status === 'ready' ? statusSnapshot.value ?? {} : {}\n const phase = status.phase ?? 'idle'\n const active = phase === 'phase1' || phase === 'phase2'\n const phaseLabel = active\n ? (phase === 'phase1' ? t('phase1') : t('phase2'))\n : t('statusIdle')\n\n // Settings mirror for the quick toggles.\n const settingsSnapshot = useScopeSnapshot(props.settings)\n const settings = (settingsSnapshot?.value ?? {}) as Record<string, unknown>\n const settingsWritable = settingsSnapshot?.writable === true\n const scheduled = settings.generateMemories !== false\n\n const [open, setOpen] = useState(false)\n const rootRef = useRef<HTMLElement | null>(null)\n const [anchor, setAnchor] = useState<{ left: number; bottom: number } | undefined>(undefined)\n\n // The sidebar clips overflow, so the panel is position: fixed and hugs the\n // trigger through a measured offset instead of document flow.\n useLayoutEffect(() => {\n if (!open) return undefined\n const place = (): void => {\n const rect = rootRef.current?.getBoundingClientRect()\n if (rect != null) setAnchor({ left: rect.left, bottom: window.innerHeight - rect.top + 8 })\n }\n place()\n window.addEventListener('resize', place)\n return () => { window.removeEventListener('resize', place) }\n }, [open, wide])\n\n useEffect(() => {\n if (!open) return undefined\n const onPointerDown = (event: Event): void => {\n const root = rootRef.current\n const target = event.target\n if (root != null && target instanceof Node && root.contains(target)) return\n setOpen(false)\n }\n const onKeyDown = (event: KeyboardEvent): void => {\n if (event.key === 'Escape') setOpen(false)\n }\n document.addEventListener('pointerdown', onPointerDown, true)\n document.addEventListener('keydown', onKeyDown)\n return () => {\n document.removeEventListener('pointerdown', onPointerDown, true)\n document.removeEventListener('keydown', onKeyDown)\n }\n }, [open])\n\n const sendCommand = (action: string): void => {\n const commands = props.commands\n if (commands == null) return\n // Ordered: the host watch fires on the timestamp, so the action must land first.\n void (async () => {\n await commands.set('action', action)\n await commands.set('requestedAt', Date.now())\n })()\n }\n\n const toggleSetting = (field: string, value: unknown): void => {\n void props.settings?.set(field, value)\n }\n\n // The glyph carries the activity dot so the rail (icon only) still shows it.\n const icon = (size: number): unknown => createElement('span', { className: 'dshm-icon' },\n createElement(MemoryIcon, { size }),\n active ? createElement('span', { className: 'dshm-dot' }) : null,\n )\n\n // ── trigger ──────────────────────────────────────────────────────────────\n const trigger = createElement('button', {\n type: 'button',\n className: 'dshm-foot',\n 'data-open': open ? 'true' : 'false',\n 'aria-expanded': open,\n 'aria-label': t('nav'),\n title: `${t('nav')} — ${scheduled ? phaseLabel : t('pausedBadge')}`,\n onClick: () => setOpen((value) => !value),\n },\n icon(wide ? 16 : 18),\n wide ? createElement('span', { className: 'dshm-foot-label' }, t('nav')) : null,\n wide\n ? createElement('span', {\n className: 'dshm-foot-state',\n 'data-active': active ? 'true' : undefined,\n 'data-paused': scheduled ? undefined : 'true',\n }, scheduled ? phaseLabel : t('pausedBadge'))\n : null,\n )\n\n const layer = (...children: unknown[]): unknown => createElement('div', {\n ref: rootRef as never,\n className: 'dshm-layer',\n 'data-rail': wide ? undefined : 'true',\n }, ...children)\n\n if (!open) return layer(trigger)\n\n // ── panel: fixed above the trigger ───────────────────────────────────────\n const panelStyle: Record<string, unknown> = {\n position: 'fixed',\n zIndex: 40,\n width: 320,\n maxWidth: 'calc(100vw - 24px)',\n left: anchor?.left ?? 8,\n bottom: anchor?.bottom ?? 56,\n visibility: anchor == null ? 'hidden' : undefined,\n borderRadius: 14,\n overflow: 'hidden',\n background: 'var(--dsw-alias-bg-layer-3, rgba(20, 22, 28, 0.92))',\n backdropFilter: 'blur(14px)',\n WebkitBackdropFilter: 'blur(14px)',\n color: 'var(--dsw-alias-label-primary, #eee)',\n border: `1px solid ${BORDER}`,\n boxShadow: '0 10px 32px rgba(0,0,0,0.42)',\n }\n\n const preview = status.summaryPreview ?? ''\n\n return layer(\n trigger,\n createElement('div', { className: 'dshm-panel', style: panelStyle },\n createElement('div', {\n style: {\n display: 'flex', alignItems: 'center', gap: 8, padding: '10px 12px',\n background: 'var(--dsw-alias-fill-tertiary, rgba(128,128,128,0.08))',\n borderBottom: `1px solid ${BORDER}`,\n },\n },\n icon(16),\n createElement('span', { style: { fontSize: 12.5, fontWeight: 600, flex: 1 } }, t('title')),\n createElement('button', {\n type: 'button',\n className: 'dshm-btn',\n title: t('minimize'),\n onClick: () => setOpen(false),\n style: {\n fontSize: 11, padding: '1px 8px', borderRadius: 6, cursor: 'pointer',\n border: `1px solid ${BORDER}`, background: 'transparent', color: 'inherit', opacity: 0.75,\n },\n }, t('minimize')),\n ),\n createElement('div', { style: { padding: '10px 12px' } },\n createElement('div', { style: { display: 'flex', alignItems: 'center', gap: 8 } },\n createElement('span', { style: { fontSize: 12, fontWeight: 600 } }, phaseLabel),\n createElement('span', { style: { fontSize: 11, opacity: 0.45, marginLeft: 'auto' } },\n status.updatedAt ? new Date(status.updatedAt).toLocaleTimeString() : ''),\n ),\n status.detail !== ''\n ? createElement('div', { style: { fontSize: 11.5, opacity: 0.7, marginTop: 4 } }, status.detail)\n : null,\n createElement('div', {\n style: {\n display: 'flex', flexDirection: 'column', gap: 5, marginTop: 10,\n paddingTop: 10, borderTop: `1px solid ${BORDER}`,\n },\n },\n ...([\n ['enabled', 'field_enabled'],\n ['generateMemories', 'field_generateMemories'],\n ['useMemories', 'field_useMemories'],\n ] as const).map(([field, labelKey]) => createElement('div', {\n key: field,\n className: 'dshm-toggle-row',\n },\n createElement('span', { style: { fontSize: 12, opacity: 0.85 } }, t(labelKey)),\n createElement('button', {\n type: 'button',\n role: 'switch',\n 'aria-checked': settings[field] === true,\n 'aria-label': t(labelKey),\n className: 'dshm-switch',\n disabled: !settingsWritable,\n onClick: () => toggleSetting(field, settings[field] !== true),\n }, createElement('span', { className: 'dshm-thumb' })),\n )),\n ),\n preview !== ''\n ? createElement('div', {\n className: 'dshm-preview',\n style: {\n marginTop: 10, padding: '8px 10px', borderRadius: 8,\n background: 'var(--dsw-alias-fill-tertiary, rgba(128,128,128,0.08))',\n border: `1px solid ${BORDER}`,\n fontSize: 11, lineHeight: 1.5, opacity: 0.85,\n maxHeight: 130, overflowY: 'auto',\n whiteSpace: 'pre-wrap', wordBreak: 'break-word',\n },\n }, preview)\n : null,\n ),\n createElement('div', {\n style: {\n display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 6,\n padding: '10px 12px 12px', borderTop: `1px solid ${BORDER}`,\n },\n },\n createElement('div', { style: { gridColumn: '1 / -1' } },\n actionButton(t('menuRunNow'), () => sendCommand('run-cycle'), true, true),\n ),\n props.openViewer != null\n ? actionButton(t('menuViewMemory'), () => props.openViewer?.(), false, true)\n : null,\n actionButton(scheduled ? t('menuPause') : t('menuResume'), () => sendCommand('toggle-schedule'), false, true),\n createElement('div', { style: { gridColumn: '1 / -1' } },\n actionButton(t('menuOpenFolder'), () => sendCommand('open-folder'), false, true),\n ),\n ),\n ),\n )\n}\n\nfunction actionButton(label: string, onClick: () => void, primary = false, stretch = false) {\n return createElement('button', {\n type: 'button',\n onClick,\n className: 'dshm-btn',\n style: {\n width: stretch ? '100%' : undefined,\n ...(primary\n ? {\n fontSize: 11.5, padding: '5px 10px', borderRadius: 7, cursor: 'pointer', fontWeight: 600,\n border: '1px solid transparent',\n background: 'var(--dsw-alias-button-info-fill, #4d6bfe)',\n color: 'var(--dsw-alias-label-primary-inverted, #fff)',\n }\n : {\n fontSize: 11.5, padding: '5px 10px', borderRadius: 7, cursor: 'pointer',\n border: `1px solid ${BORDER}`, background: 'transparent', color: 'inherit', opacity: 0.85,\n }),\n },\n }, label)\n}\n\n/** The memory glyph, inlined from ui-primitives' IconDatabaseOutline16: the\n * browser bundle externalizes react only, so host icons cannot be imported. */\nfunction MemoryIcon({ size }: { size: number }) {\n return createElement('svg', {\n width: size, height: size, viewBox: '0 0 16 16', fill: 'none',\n xmlns: 'http://www.w3.org/2000/svg', 'aria-hidden': 'true', focusable: 'false',\n },\n createElement('ellipse', { cx: 8, cy: 3.6, rx: 5.75, ry: 2.4, stroke: 'currentColor', strokeWidth: 1.25 }),\n createElement('path', { d: 'M2.25 3.6V12.3A5.75 2.4 0 0 0 13.75 12.3V3.6', stroke: 'currentColor', strokeWidth: 1.25 }),\n createElement('path', { d: 'M2.25 7.95A5.75 2.4 0 0 0 13.75 7.95', stroke: 'currentColor', strokeWidth: 1.25 }),\n )\n}\n\nfunction useScopeSnapshot(scope: ScopeView | undefined): { status: string; value?: unknown; writable?: boolean } | undefined {\n const [snapshot, setSnapshot] = useState<{ status: string; value?: unknown; writable?: boolean } | undefined>(\n () => scope?.getSnapshot(),\n )\n useEffect(() => {\n if (scope == null) return undefined\n setSnapshot(scope.getSnapshot())\n return scope.subscribe(() => {\n setSnapshot(scope.getSnapshot())\n })\n }, [scope])\n return snapshot\n}\n\nconst BORDER = 'var(--dsw-alias-border-l2, rgba(255,255,255,0.14))'\n","/**\n * Hides the <dsh-mem-citation> block from the rendered chat. The host-side\n * citation loop consumes it from the session log; this stripper keeps the raw\n * XML out of the visible transcript.\n *\n * Implementation: a MutationObserver watches for the marker; when found, the\n * text is truncated at the marker up to (and including) the end tag. React\n * may restore the text on re-render — the observer just strips it again.\n */\n\nconst MARKER_OPEN = '<dsh-mem-citation>'\nconst MARKER_CLOSE = '</dsh-mem-citation>'\n\n/** Strip the citation block inside one element. Returns true when it cut. */\nfunction stripWithin(root: Element): boolean {\n const full = root.textContent ?? ''\n const start = full.indexOf(MARKER_OPEN)\n if (start < 0) return false\n const endIndex = full.indexOf(MARKER_CLOSE, start)\n const cutEnd = endIndex < 0 ? full.length : endIndex + MARKER_CLOSE.length\n\n // Remove the contiguous [start, cutEnd) range from the concatenated text,\n // tracking how earlier cuts shift the range left.\n let rangeStart = start\n let rangeEnd = cutEnd\n let cut = false\n const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT)\n let offset = 0\n let node = walker.nextNode() as Text | null\n while (node != null) {\n const length = node.data.length\n const nodeEnd = offset + length\n if (nodeEnd > rangeStart && offset < rangeEnd) {\n const localStart = Math.max(0, rangeStart - offset)\n const localEnd = Math.min(length, rangeEnd - offset)\n node.data = node.data.slice(0, localStart) + node.data.slice(localEnd)\n rangeEnd -= localEnd - localStart\n cut = true\n }\n offset += node.data.length\n if (offset >= rangeEnd && cut) break\n node = walker.nextNode() as Text | null\n }\n return cut\n}\n\nfunction sweep(root: ParentNode): void {\n const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT)\n let node = walker.nextNode() as Text | null\n while (node != null) {\n const next = walker.nextNode() as Text | null\n if (node.data.includes(MARKER_OPEN)) {\n // The block may span sibling elements; climb a few levels to cover it.\n let scope: Element | null = node.parentElement\n for (let depth = 0; depth < 4 && scope != null; depth += 1) {\n if (stripWithin(scope)) break\n scope = scope.parentElement\n }\n }\n node = next\n }\n}\n\n/** Install the stripper; returns a disposer. No-ops outside a document. */\nexport function installCitationStripper(): () => void {\n if (typeof document === 'undefined') return () => {}\n let pending = false\n const schedule = (): void => {\n if (pending) return\n pending = true\n // Batch bursts of stream mutations into one sweep per frame.\n requestAnimationFrame(() => {\n pending = false\n try {\n sweep(document.body)\n } catch {\n // Best effort: a strip failure must never break the chat.\n }\n })\n }\n const observer = new MutationObserver((mutations) => {\n for (const mutation of mutations) {\n const target = mutation.target\n if (\n (target.nodeType === Node.TEXT_NODE && (target as Text).data.includes(MARKER_OPEN))\n || (target instanceof Element && (target.textContent ?? '').includes(MARKER_OPEN))\n ) {\n schedule()\n return\n }\n }\n })\n observer.observe(document.body, { childList: true, subtree: true, characterData: true })\n sweep(document.body)\n return () => observer.disconnect()\n}\n","/**\n * The standalone memory viewer: a right-sidebar page tab (same public path as\n * ui-sidebar-files) with three views — overview dashboard (stats, most-cited,\n * and the searchable records table), summary (original / translated), and the\n * MEMORY.md registry.\n *\n * Data arrives through the `memory-view` / `memory-status` settings mirrors:\n * a registration's `inject.hooks` compartment is synthesized by the slot\n * framework into `use<Name>` selector hooks (the same face the float uses for\n * `useMemoryStatus`). The large texts travel gzip+base64 in `blobs` and are\n * decoded with DecompressionStream. Actions go back through the\n * `memory-commands` namespace.\n */\n\nimport { createElement, useEffect, useState } from 'react'\nimport type { ScopeView } from './types.ts'\n\nexport const MEMORY_VIEWER_KIND = 'dsh-memory'\nexport const MEMORY_VIEWER_ID = 'dsh-remember/viewer'\n\ntype ReactNode = ReturnType<typeof createElement> | string | null\ntype SelectorHook = (selector: (value: unknown) => unknown) => unknown\n\ninterface RecordStat {\n sessionId: string\n workspacePath: string\n rolloutSlug: string\n sourceUpdatedAt: number\n generatedAt: number\n usageCount: number\n lastUsage: number | null\n selectedForPhase2: boolean\n rawLength: number\n summaryLength: number\n}\n\n/** Published namespace section (texts compressed). */\ninterface ViewState {\n blobs: string\n records: string\n translatedStale: boolean\n translating: boolean\n updatedAt: number\n}\n\ninterface Texts {\n summary: string\n index: string\n translatedSummary: string\n translatedIndex: string\n failed: boolean\n}\n\ninterface StatusState {\n phase?: string\n detail?: string\n updatedAt?: number\n}\n\ninterface ViewerProps {\n t: (key: string) => string\n useMemoryView?: SelectorHook\n useMemoryStatus?: SelectorHook\n commands?: ScopeView\n}\n\nconst EMPTY_TEXTS: Texts = { summary: '', index: '', translatedSummary: '', translatedIndex: '', failed: false }\n\nlet styleInjected = false\n\nfunction ensureViewerStyles(): void {\n if (styleInjected || typeof document === 'undefined') return\n if (document.querySelector('style[data-dsh-memory-viewer]') != null) {\n styleInjected = true\n return\n }\n const tag = document.createElement('style')\n tag.dataset.dshMemoryViewer = 'true'\n tag.textContent = [\n '.dshmv-root { display: flex; flex-direction: column; height: 100%; min-height: 0; box-sizing: border-box; padding: 10px 14px 14px; color: var(--dsw-alias-label-primary, #1f2329); font-size: 13px; }',\n '.dshmv-tabs { display: flex; gap: 2px; flex: 0 0 auto; margin-bottom: 10px; border-bottom: 0.5px solid var(--dsw-alias-border-l2, rgba(0,0,0,0.1)); }',\n '.dshmv-tab { padding: 6px 12px; font-size: 12.5px; cursor: pointer; border: none; background: none; color: inherit; opacity: 0.55; border-bottom: 2px solid transparent; transition: opacity 140ms ease, border-color 140ms ease; }',\n '.dshmv-tab:hover { opacity: 0.85; }',\n '.dshmv-tab[data-active=\"true\"] { opacity: 1; border-bottom-color: var(--dsw-alias-brand-primary, #4d6bfe); font-weight: 600; }',\n '.dshmv-toolbar { display: flex; align-items: center; gap: 10px; flex: 0 0 auto; margin-bottom: 12px; flex-wrap: wrap; }',\n '.dshmv-status { margin-left: auto; font-size: 11px; color: var(--dsw-alias-label-tertiary, rgba(0,0,0,0.45)); }',\n '.dshmv-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; }',\n '.dshmv-body[data-fill=\"true\"] { display: flex; flex-direction: column; overflow: hidden; }',\n '.dshmv-body::-webkit-scrollbar { width: 8px; }',\n '.dshmv-body::-webkit-scrollbar-thumb { background: var(--dsw-alias-scrollbar-bg-l2, rgba(0,0,0,0.2)); border-radius: 4px; }',\n '.dshmv-switch-row { display: inline-flex; align-items: center; gap: 8px; font-size: 12px; color: inherit; padding: 3px 8px; border-radius: 8px; border: 0.5px solid transparent; background: none; cursor: pointer; transition: background 150ms ease, opacity 150ms ease; }',\n '.dshmv-switch-row:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover, rgba(0,0,0,0.05)); }',\n '.dshmv-switch-row:disabled { opacity: 0.45; cursor: default; }',\n // Switch: DSH's Switch primitive spec (36x20 track, 16px thumb), keyed off\n // aria-checked so the paint cannot disagree with assistive state.\n '.dshmv-switch { box-sizing: border-box; position: relative; display: inline-block; flex: 0 0 auto; width: 36px; height: 20px; padding: 2px; border: 0; border-radius: 10px; corner-shape: round; background: var(--dsw-alias-border-l3, rgba(0,0,0,0.2)); transition: background 160ms ease; }',\n '.dshmv-switch[aria-checked=\"true\"] { background: var(--dsw-alias-brand-primary, #4d6bfe); }',\n '.dshmv-thumb { display: block; width: 16px; height: 16px; border-radius: 50%; corner-shape: round; background: var(--dsw-alias-label-primary-foreground, #fff); transition: transform 120ms ease; }',\n '.dshmv-switch[aria-checked=\"true\"] .dshmv-thumb { transform: translateX(16px); }',\n '.dshmv-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(118px, 1fr)); gap: 10px; margin-bottom: 14px; }',\n '.dshmv-card { padding: 10px 12px; border-radius: 10px; border: 0.5px solid var(--dsw-alias-border-l2, rgba(0,0,0,0.1)); background: var(--dsw-alias-fill-tertiary, rgba(0,0,0,0.04)); }',\n '.dshmv-card-num { font-size: 20px; font-weight: 700; font-variant-numeric: tabular-nums; }',\n '.dshmv-card-label { font-size: 11px; color: var(--dsw-alias-label-tertiary, rgba(0,0,0,0.45)); margin-top: 2px; }',\n '.dshmv-md { white-space: pre-wrap; word-break: break-word; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 12px; line-height: 1.6; padding: 12px; border-radius: 10px; border: 0.5px solid var(--dsw-alias-border-l2, rgba(0,0,0,0.1)); background: var(--dsw-alias-fill-tertiary, rgba(0,0,0,0.04)); }',\n '.dshmv-md-fill { flex: 1 1 auto; min-height: 0; overflow: auto; }',\n '.dshmv-scroll-fill { flex: 1 1 auto; min-height: 0; overflow: auto; }',\n '.dshmv-fill { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }',\n '.dshmv-btn { font-size: 12px; padding: 4px 12px; border-radius: 7px; cursor: pointer; border: 0.5px solid var(--dsw-alias-border-l3, rgba(0,0,0,0.2)); background: transparent; color: inherit; transition: border-color 150ms ease, background 150ms ease, transform 100ms ease; }',\n '.dshmv-btn:hover:not(:disabled) { border-color: var(--dsw-alias-brand-primary, #4d6bfe); background: var(--dsw-alias-interactive-bg-hover, rgba(0,0,0,0.05)); }',\n '.dshmv-btn:active:not(:disabled) { transform: translateY(1px); }',\n '.dshmv-btn:disabled { opacity: 0.4; cursor: default; }',\n '.dshmv-btn-primary { border-color: transparent; background: var(--dsw-alias-button-info-fill, #4d6bfe); color: var(--dsw-alias-label-primary-inverted, #fff); font-weight: 600; }',\n '.dshmv-btn-primary:hover:not(:disabled) { border-color: transparent; background: var(--dsw-alias-button-info-hover, #3f5ae0); }',\n '.dshmv-btn-danger { border-color: transparent; background: var(--dsw-alias-state-error-primary, #d54941); color: var(--dsw-alias-label-primary-inverted, #fff); font-weight: 600; }',\n '.dshmv-btn-danger:hover:not(:disabled) { border-color: transparent; filter: brightness(1.08); }',\n '.dshmv-confirm { display: inline-flex; align-items: center; gap: 6px; padding: 2px 6px 2px 10px; border-radius: 8px; background: rgba(213,73,65,0.12); }',\n '.dshmv-confirm-text { font-size: 11.5px; color: var(--dsw-alias-state-error-primary, #d54941); }',\n '.dshmv-badge { font-size: 10.5px; padding: 1px 8px; border-radius: 999px; }',\n '.dshmv-badge-stale { background: rgba(224,172,68,0.16); color: var(--dsw-alias-state-warn-primary, #b7791f); }',\n '.dshmv-badge-ok { background: rgba(84,196,138,0.16); color: var(--dsw-alias-state-success-primary, #2f9e63); }',\n '.dshmv-search { width: 100%; box-sizing: border-box; font-size: 12px; padding: 6px 10px; border-radius: 8px; border: 0.5px solid var(--dsw-alias-border-l3, rgba(0,0,0,0.18)); background: var(--dsw-alias-bg-layer-1, transparent); color: inherit; margin-bottom: 10px; outline: none; }',\n '.dshmv-search:focus { border-color: var(--dsw-alias-brand-primary, #4d6bfe); }',\n '.dshmv-table { width: 100%; border-collapse: collapse; font-size: 12px; }',\n '.dshmv-table th { text-align: left; font-weight: 600; font-size: 11px; color: var(--dsw-alias-label-tertiary, rgba(0,0,0,0.45)); padding: 6px 8px; border-bottom: 0.5px solid var(--dsw-alias-border-l2, rgba(0,0,0,0.1)); }',\n '.dshmv-table td { padding: 6px 8px; border-bottom: 0.5px solid var(--dsw-alias-border-l1, rgba(0,0,0,0.06)); vertical-align: top; }',\n '.dshmv-table tr:hover td { background: var(--dsw-alias-interactive-bg-hover, rgba(0,0,0,0.04)); }',\n '.dshmv-usage { display: flex; align-items: center; gap: 6px; }',\n '.dshmv-usage-bar { height: 5px; border-radius: 3px; background: var(--dsw-alias-brand-primary, #4d6bfe); min-width: 2px; transition: width 200ms ease; }',\n '.dshmv-empty { color: var(--dsw-alias-label-tertiary, rgba(0,0,0,0.45)); padding: 24px 0; text-align: center; font-size: 12px; }',\n '.dshmv-mono { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 11px; color: var(--dsw-alias-label-tertiary, rgba(0,0,0,0.45)); }',\n '.dshmv-section { margin: 2px 0 8px; font-size: 12px; font-weight: 600; color: var(--dsw-alias-label-secondary, rgba(0,0,0,0.65)); }',\n '.dshmv-toprow { display: flex; align-items: center; gap: 10px; padding: 7px 10px; border-radius: 8px; border: 0.5px solid var(--dsw-alias-border-l2, rgba(0,0,0,0.1)); background: var(--dsw-alias-fill-tertiary, rgba(0,0,0,0.04)); margin-bottom: 6px; }',\n '.dshmv-toprow-name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; font-size: 12px; }',\n '.dshmv-toprow-meta { flex: 0 0 auto; font-size: 11px; color: var(--dsw-alias-label-tertiary, rgba(0,0,0,0.45)); font-variant-numeric: tabular-nums; }',\n ].join('\\n')\n document.head.appendChild(tag)\n styleInjected = true\n}\n\n/** Read one namespace mirror through its selector hook (framework-synthesized). */\nfunction useMirror<T>(hook: SelectorHook | undefined): Partial<T> {\n const snapshot = hook?.((value: unknown) => value) as { status?: string; value?: Partial<T> } | undefined\n return snapshot?.status === 'ready' ? snapshot.value ?? {} : {}\n}\n\n/** Decode the gzip+base64 texts; DecompressionStream is the only browser dependency. */\nfunction useBlobs(encoded: string | undefined): Texts {\n const [texts, setTexts] = useState<Texts>(EMPTY_TEXTS)\n useEffect(() => {\n if (encoded == null || encoded === '') {\n setTexts(EMPTY_TEXTS)\n return undefined\n }\n let cancelled = false\n void decodeBlobs(encoded)\n .then((next) => { if (!cancelled) setTexts(next) })\n .catch(() => { if (!cancelled) setTexts({ ...EMPTY_TEXTS, failed: true }) })\n return () => { cancelled = true }\n }, [encoded])\n return texts\n}\n\nasync function decodeBlobs(encoded: string): Promise<Texts> {\n if (typeof DecompressionStream === 'undefined') return { ...EMPTY_TEXTS, failed: true }\n const binary = atob(encoded)\n const bytes = new Uint8Array(binary.length)\n for (let index = 0; index < binary.length; index += 1) bytes[index] = binary.charCodeAt(index)\n const stream = new DecompressionStream('gzip')\n const writer = stream.writable.getWriter()\n void writer.write(bytes)\n void writer.close()\n const parsed = JSON.parse(await new Response(stream.readable).text()) as Partial<Texts>\n return {\n summary: parsed.summary ?? '',\n index: parsed.index ?? '',\n translatedSummary: parsed.translatedSummary ?? '',\n translatedIndex: parsed.translatedIndex ?? '',\n failed: false,\n }\n}\n\ntype TabId = 'overview' | 'summary' | 'index'\n\n/** Viewer body (slot component). */\nexport function MemoryViewerBody(props: ViewerProps) {\n try {\n return renderViewer(props)\n } catch {\n return null\n }\n}\n\nfunction renderViewer(props: ViewerProps) {\n ensureViewerStyles()\n const t = props.t\n const view = useMirror<ViewState>(props.useMemoryView)\n const status = useMirror<StatusState>(props.useMemoryStatus)\n const texts = useBlobs(view.blobs)\n const [tab, setTab] = useState<TabId>('overview')\n const [showTranslated, setShowTranslated] = useState(false)\n const [confirmingRebuild, setConfirmingRebuild] = useState(false)\n\n const records = parseRecords(view.records)\n const hasTranslation = texts.translatedSummary !== ''\n const translating = view.translating === true\n const sendCommand = (action: string, arg = '', force = false): void => {\n const commands = props.commands\n if (commands == null) return\n void (async () => {\n if (arg !== '') await commands.set('arg', arg)\n if (force) await commands.set('force', true)\n await commands.set('action', action)\n await commands.set('requestedAt', Date.now())\n })()\n }\n\n return createElement('div', { className: 'dshmv-root' },\n // tabs first: the action row sits below them, not against the pane header\n createElement('div', { className: 'dshmv-tabs' },\n ...(['overview', 'summary', 'index'] as const).map((id) => createElement('button', {\n key: id,\n type: 'button',\n className: 'dshmv-tab',\n 'data-active': tab === id ? 'true' : 'false',\n onClick: () => setTab(id),\n }, t(`viewer_tab_${id}`))),\n ),\n createElement('div', { className: 'dshmv-toolbar' },\n createElement('button', {\n type: 'button',\n className: 'dshmv-btn',\n onClick: () => sendCommand('refresh-view'),\n }, t('viewer_refresh')),\n // The switch is a pure view toggle; fetching a translation is the\n // separate action button below it.\n createElement('button', {\n type: 'button',\n role: 'switch',\n 'aria-checked': showTranslated && hasTranslation,\n disabled: !hasTranslation || translating,\n className: 'dshmv-switch-row',\n onClick: () => setShowTranslated((value) => !value),\n },\n createElement('span', null, t('viewer_showTranslated')),\n createElement('span', {\n className: 'dshmv-switch',\n 'aria-checked': showTranslated && hasTranslation ? 'true' : 'false',\n }, createElement('span', { className: 'dshmv-thumb' })),\n ),\n createElement('button', {\n type: 'button',\n className: translating ? 'dshmv-btn' : 'dshmv-btn dshmv-btn-primary',\n disabled: translating || texts.summary === '',\n onClick: () => sendCommand('translate-memory', currentLang()),\n }, translating\n ? `${t('viewer_translating')}${progressLabel(status.detail) === '' ? '' : ` ${progressLabel(status.detail)}`}`\n : hasTranslation ? t('viewer_retranslate') : t('viewer_translate')),\n // Two-step confirm: the destructive full rebuild never fires on one click.\n confirmingRebuild\n ? createElement('span', { className: 'dshmv-confirm' },\n createElement('span', { className: 'dshmv-confirm-text' }, t('viewer_rebuildConfirm')),\n createElement('button', {\n type: 'button',\n className: 'dshmv-btn dshmv-btn-danger',\n disabled: translating || texts.summary === '',\n onClick: () => {\n setConfirmingRebuild(false)\n sendCommand('translate-memory', currentLang(), true)\n },\n }, t('viewer_confirm')),\n createElement('button', {\n type: 'button',\n className: 'dshmv-btn',\n onClick: () => setConfirmingRebuild(false),\n }, t('viewer_cancel')),\n )\n : createElement('button', {\n type: 'button',\n className: 'dshmv-btn',\n disabled: translating || texts.summary === '',\n onClick: () => setConfirmingRebuild(true),\n }, t('viewer_rebuild')),\n showTranslated && hasTranslation && view.translatedStale === true\n ? createElement('span', { className: 'dshmv-badge dshmv-badge-stale' }, t('viewer_stale'))\n : null,\n showTranslated && hasTranslation && view.translatedStale !== true\n ? createElement('span', { className: 'dshmv-badge dshmv-badge-ok' }, t('viewer_fresh'))\n : null,\n createElement('span', { className: 'dshmv-status' }, status.detail ?? ''),\n ),\n createElement('div', {\n className: 'dshmv-body',\n // Every tab fills the pane; its content block does the scrolling.\n 'data-fill': 'true',\n },\n tab === 'overview' ? createElement(OverviewView, { t, texts, showTranslated, status, records })\n : tab === 'summary' ? createElement(SummaryView, { t, texts, showTranslated })\n : renderIndex(t, texts, showTranslated),\n ),\n )\n}\n\n/** Overview dashboard: stat cards, status, most-cited, and the records table. */\nfunction OverviewView(props: {\n t: (k: string) => string\n texts: Texts\n showTranslated: boolean\n status: Partial<StatusState>\n records: RecordStat[]\n}) {\n const { t, texts, showTranslated, status, records } = props\n const [query, setQuery] = useState('')\n const totalUsage = records.reduce((sum, record) => sum + record.usageCount, 0)\n const consolidated = records.filter((record) => record.selectedForPhase2).length\n const topCited = records\n .filter((record) => record.usageCount > 0)\n .sort((a, b) => b.usageCount - a.usageCount)\n .slice(0, 5)\n const phase = status.phase ?? 'idle'\n const active = phase === 'phase1' || phase === 'phase2'\n const needle = query.trim().toLowerCase()\n const filtered = needle === ''\n ? records\n : records.filter((record) =>\n record.sessionId.toLowerCase().includes(needle)\n || record.rolloutSlug.toLowerCase().includes(needle)\n || record.workspacePath.toLowerCase().includes(needle))\n const maxUsage = Math.max(1, ...records.map((record) => record.usageCount))\n const card = (num: ReactNode, label: string): ReactNode => createElement('div', { className: 'dshmv-card', key: label },\n createElement('div', { className: 'dshmv-card-num' }, num),\n createElement('div', { className: 'dshmv-card-label' }, label),\n )\n return createElement('div', { className: 'dshmv-scroll-fill' },\n createElement('div', { className: 'dshmv-cards' },\n card(records.length, t('viewer_stat_records')),\n card(consolidated, t('viewer_stat_consolidated')),\n card(totalUsage, t('viewer_stat_citations')),\n card(formatBytes(texts.summary.length), t('viewer_stat_summarySize')),\n card(formatBytes(texts.index.length), t('viewer_stat_indexSize')),\n ),\n createElement('div', { style: { display: 'flex', alignItems: 'center', gap: 8, marginBottom: 10 } },\n createElement('span', {\n className: `dshmv-badge ${active ? 'dshmv-badge-stale' : 'dshmv-badge-ok'}`,\n }, active ? (phase === 'phase1' ? t('phase1') : t('phase2')) : t('statusIdle')),\n status.updatedAt != null && status.updatedAt > 0\n ? createElement('span', { className: 'dshmv-mono' }, new Date(status.updatedAt).toLocaleString())\n : null,\n showTranslated ? createElement('span', { className: 'dshmv-badge dshmv-badge-ok' }, t('viewer_badgeTranslated')) : null,\n ),\n records.length === 0\n ? null\n : createElement('div', { className: 'dshmv-section' }, t('viewer_topCited')),\n ...topCited.map((record) => createElement('div', { className: 'dshmv-toprow', key: record.sessionId },\n createElement('span', { className: 'dshmv-toprow-name' }, record.rolloutSlug || record.sessionId.slice(0, 8)),\n createElement('span', { className: 'dshmv-toprow-meta' },\n `${record.usageCount} · ${formatTime(record.lastUsage ?? record.sourceUpdatedAt)}`),\n )),\n records.length > 0 && topCited.length === 0\n ? createElement('div', { className: 'dshmv-empty' }, t('viewer_noCitations'))\n : null,\n records.length === 0\n ? null\n : createElement('div', { className: 'dshmv-section', style: { marginTop: 14 } }, t('viewer_tab_records')),\n records.length === 0\n ? null\n : createElement('input', {\n className: 'dshmv-search',\n placeholder: t('viewer_search'),\n value: query,\n onChange: (event: { target: { value: string } }) => setQuery(event.target.value),\n }),\n records.length === 0\n ? createElement('div', { className: 'dshmv-empty' }, t('viewer_empty'))\n : createElement('table', { className: 'dshmv-table' },\n createElement('thead', null, createElement('tr', null,\n createElement('th', null, t('viewer_col_session')),\n createElement('th', null, t('viewer_col_usage')),\n createElement('th', null, t('viewer_col_updated')),\n )),\n createElement('tbody', null,\n ...filtered.map((record) => createElement('tr', { key: record.sessionId },\n createElement('td', null,\n createElement('div', { style: { fontWeight: 600 } },\n record.rolloutSlug || record.sessionId.slice(0, 8)),\n createElement('div', { className: 'dshmv-mono' }, record.workspacePath),\n ),\n createElement('td', null,\n createElement('div', { className: 'dshmv-usage' },\n createElement('span', {\n className: 'dshmv-usage-bar',\n style: { width: `${Math.round((record.usageCount / maxUsage) * 48)}px` },\n }),\n createElement('span', null, String(record.usageCount)),\n ),\n record.lastUsage != null\n ? createElement('div', { className: 'dshmv-mono' },\n `${t('viewer_col_lastUsed')}: ${formatTime(record.lastUsage)}`)\n : null,\n ),\n createElement('td', { className: 'dshmv-mono' }, formatTime(record.sourceUpdatedAt)),\n )),\n ),\n ),\n )\n}\n\nfunction SummaryView(props: { t: (k: string) => string; texts: Texts; showTranslated: boolean }) {\n const { t, texts, showTranslated } = props\n const text = showTranslated && texts.translatedSummary !== '' ? texts.translatedSummary : texts.summary\n return text !== ''\n ? createElement('div', { className: 'dshmv-md dshmv-md-fill' }, text)\n : createElement('div', { className: 'dshmv-empty dshmv-fill' }, texts.failed ? t('viewer_decodeFailed') : t('viewer_empty'))\n}\n\nfunction renderIndex(t: (k: string) => string, texts: Texts, showTranslated: boolean): ReactNode {\n const text = showTranslated && texts.translatedIndex !== '' ? texts.translatedIndex : texts.index\n return text !== ''\n ? createElement('div', { className: 'dshmv-md dshmv-md-fill' }, text)\n : createElement('div', { className: 'dshmv-empty dshmv-fill' }, texts.failed ? t('viewer_decodeFailed') : t('viewer_empty'))\n}\n\n/** Title chip for the viewer tab. */\nexport function MemoryViewerTitle(props: { t: (key: string) => string }) {\n return createElement('span', null, props.t('viewer_title'))\n}\n\n/** 'N/M' extracted from the host's `translate: N/M chunks` status line. */\nfunction progressLabel(detail: string | undefined): string {\n return /translate:\\s*(\\d+\\/\\d+)/.exec(detail ?? '')?.[1] ?? ''\n}\n\nfunction parseRecords(raw: string | undefined): RecordStat[] {\n if (raw == null || raw === '') return []\n try {\n const parsed = JSON.parse(raw) as unknown\n return Array.isArray(parsed) ? parsed as RecordStat[] : []\n } catch {\n return []\n }\n}\n\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`\n return `${(bytes / 1024).toFixed(1)} KB`\n}\n\nfunction formatTime(unixSeconds: number): string {\n if (!Number.isFinite(unixSeconds) || unixSeconds <= 0) return '—'\n return new Date(unixSeconds * 1000).toLocaleString()\n}\n\n/** Current UI language tag for the translate command (`zh` vs `en`). */\nfunction currentLang(): string {\n try {\n return (navigator.language || 'zh').toLowerCase().startsWith('zh') ? 'zh' : 'en'\n } catch {\n return 'zh'\n }\n}\n","/**\n * Browser half of dsh-remember: contributes the Settings → Plugins card\n * for the `memory` namespace and the memory entry in the sidebar footer.\n * Registered lazily via slots.inject so composition order never matters.\n */\n\nimport { MemoryCardController, MemorySettingsPage } from './memory-card.ts'\nimport { MemoryFooterAction } from './sidebar-action.ts'\nimport { installCitationStripper } from './citation-stripper.ts'\nimport { MEMORY_VIEWER_ID, MEMORY_VIEWER_KIND, MemoryViewerBody, MemoryViewerTitle } from './memory-viewer.ts'\nimport type { CatalogModel, ClientContext } from './types.ts'\n\nexport const name = 'dsh-remember'\n\n/** Required browser services (cordis fiber inject). */\nexport const inject = ['slots', 'locale', 'settingsScope', 'remote', 'remote.session']\n\nconst NS = 'dsh-memory'\n\nconst ZH: Record<string, string> = {\n nav: '记忆',\n title: '记忆系统',\n intro: '空闲会话自动提取、整理为可检索的文件型记忆库,并在对话中按需召回。',\n unavailable: '此部署未提供记忆设置(命名空间不可用)。',\n group_general: '通用',\n group_models: '模型',\n group_schedule: '调度与保留',\n group_recall: '召回注入',\n group_transfer: '导入 / 导出',\n group_advanced: '高级',\n field_enabled: '启用记忆系统',\n field_generateMemories: '自动生成记忆',\n field_useMemories: '注入记忆摘要',\n field_workspaceDir: '记忆工作区目录',\n field_dbPath: 'SQLite 数据库路径',\n field_extractModel: '提取模型 (provider/model)',\n field_consolidationModel: '整理模型 (provider/model)',\n field_scanIntervalMinutes: '扫描间隔(分钟)',\n field_minRolloutIdleHours: '会话静置阈值(小时)',\n field_maxSessionAgeDays: '会话最大年龄(天)',\n field_maxUnusedDays: '未用记忆保留(天)',\n field_maxRolloutSummaries: 'rollout 摘要上限',\n field_phase2SuccessCooldownSeconds: '整理成功冷却(秒)',\n field_phase2TimeoutMinutes: '整理超时(分钟)',\n field_phase1RetryBackoffMinutes: '提取重试退避(分钟)',\n field_phase1MaxRetries: '提取重试次数',\n field_phase1MaxPerCycle: '每轮提取上限',\n field_phase1MaxConcurrency: '提取并发数',\n field_consolidatorDenyPatterns: '整理器额外工具黑名单(正则)',\n field_summaryTokenLimit: '摘要注入 token 上限',\n field_extractInputContextRatio: '提取上下文占比',\n field_redactSecrets: '提取时脱敏密钥',\n hint_workspaceDir: '留空使用 ~/.dsh-memory/memories',\n hint_dbPath: '留空使用 ~/.dsh-memory/memories.sqlite',\n hint_extractModel: '留空使用默认模型',\n hint_consolidationModel: '留空使用默认模型',\n hint_extractInputContextRatio: '0.1 – 0.95',\n hint_consolidatorDenyPatterns: '整理器默认只开放 read/write/edit/glob/grep;这里的正则在白名单之上再拒绝',\n overridden: '已覆盖',\n reset: '重置',\n save: '保存',\n discard: '放弃',\n saving: '保存中…',\n failed: '保存失败',\n invalid: '存在无效输入',\n readOnly: '此文档不可写',\n statusIdle: '空闲',\n modelDefault: '跟随默认模型',\n catalogRefresh: '刷新模型目录',\n catalogLoading: '模型目录加载中…',\n catalogError: '模型目录加载失败,可重试或直接填写 provider/model',\n done: '记忆已更新',\n minimize: '最小化',\n menuExpand: '展开',\n pausedBadge: '已暂停',\n menuRunNow: '立即整理一次',\n menuViewMemory: '查看记忆',\n menuPause: '暂停自动调度',\n menuResume: '恢复自动调度',\n menuOpenFolder: '打开记忆文件夹',\n phase1: '记忆提取中',\n phase2: '记忆整理中',\n processing: '记忆处理中',\n transfer_exportLabel: '导出记忆',\n transfer_exportDesc: '保存为单个 bundle 文件,位置在浏览器里选',\n transfer_importLabel: '导入记忆',\n transfer_importDesc: '选择一个 bundle 文件合并进当前记忆库',\n transfer_export: '导出',\n transfer_import: '导入',\n transfer_requested: '已发送,结果见上方状态栏',\n transfer_tooBig: '文件超过 32 MB,请改用 memory_export 工具直接导出到磁盘',\n transfer_readFailed: '文件读取失败',\n viewer_title: '记忆浏览',\n viewer_refresh: '刷新',\n viewer_translate: '翻译记忆',\n viewer_translating: '翻译中…',\n viewer_tab_overview: '概览',\n viewer_tab_summary: '摘要',\n viewer_tab_index: '注册表',\n viewer_tab_records: '记录',\n viewer_stat_records: '记忆记录',\n viewer_stat_consolidated: '已整理',\n viewer_stat_citations: '被引用次数',\n viewer_stat_summarySize: '摘要大小',\n viewer_stat_indexSize: '注册表大小',\n viewer_topCited: '最常引用',\n viewer_noCitations: '还没有引用记录',\n viewer_original: '显示原文',\n viewer_translated: '显示译文',\n viewer_showTranslated: '显示译文',\n viewer_badgeTranslated: '译文',\n viewer_rebuild: '重建译文',\n viewer_rebuildConfirm: '忽略缓存全文重翻?',\n viewer_confirm: '确认',\n viewer_cancel: '取消',\n viewer_retranslate: '重新翻译',\n viewer_stale: '译文已过期',\n viewer_fresh: '译文为最新',\n viewer_empty: '暂无内容',\n viewer_decodeFailed: '记忆内容解码失败(浏览器不支持 DecompressionStream)',\n viewer_search: '搜索会话 / 路径…',\n viewer_col_session: '会话',\n viewer_col_usage: '引用',\n viewer_col_updated: '更新时间',\n viewer_col_lastUsed: '最近引用',\n}\n\nconst EN: Record<string, string> = {\n nav: 'Memory',\n title: 'Memory',\n intro: 'Idle sessions are extracted automatically, consolidated into a searchable file-based memory library, and recalled on demand.',\n unavailable: 'Memory settings are unavailable in this deployment (namespace not served).',\n group_general: 'General',\n group_models: 'Models',\n group_schedule: 'Scheduling & retention',\n group_recall: 'Recall injection',\n group_transfer: 'Import / Export',\n group_advanced: 'Advanced',\n field_enabled: 'Enable memory system',\n field_generateMemories: 'Generate memories automatically',\n field_useMemories: 'Inject memory summary',\n field_workspaceDir: 'Memory workspace directory',\n field_dbPath: 'SQLite database path',\n field_extractModel: 'Extraction model (provider/model)',\n field_consolidationModel: 'Consolidation model (provider/model)',\n field_scanIntervalMinutes: 'Scan interval (minutes)',\n field_minRolloutIdleHours: 'Session idle threshold (hours)',\n field_maxSessionAgeDays: 'Max session age (days)',\n field_maxUnusedDays: 'Unused memory retention (days)',\n field_maxRolloutSummaries: 'Rollout summary cap',\n field_phase2SuccessCooldownSeconds: 'Consolidation cooldown (seconds)',\n field_phase2TimeoutMinutes: 'Consolidation timeout (minutes)',\n field_phase1RetryBackoffMinutes: 'Extraction retry backoff (minutes)',\n field_phase1MaxRetries: 'Extraction retries',\n field_phase1MaxPerCycle: 'Extractions per cycle',\n field_phase1MaxConcurrency: 'Extraction concurrency',\n field_consolidatorDenyPatterns: 'Extra consolidator tool denies (regex)',\n field_summaryTokenLimit: 'Summary injection token cap',\n field_extractInputContextRatio: 'Extraction context ratio',\n field_redactSecrets: 'Redact secrets during extraction',\n hint_workspaceDir: 'Empty = ~/.dsh-memory/memories',\n hint_dbPath: 'Empty = ~/.dsh-memory/memories.sqlite',\n hint_extractModel: 'Empty = deployment default model',\n hint_consolidationModel: 'Empty = deployment default model',\n hint_extractInputContextRatio: '0.1 – 0.95',\n hint_consolidatorDenyPatterns: 'The consolidator only gets read/write/edit/glob/grep; these regexes deny more on top of the whitelist',\n overridden: 'overridden',\n reset: 'reset',\n save: 'Save',\n discard: 'Discard',\n saving: 'Saving…',\n failed: 'Save failed',\n invalid: 'Invalid input',\n readOnly: 'This document is read-only',\n statusIdle: 'Idle',\n modelDefault: 'Follow default model',\n catalogRefresh: 'Refresh models',\n catalogLoading: 'Loading model catalog…',\n catalogError: 'Model catalog failed to load — retry or type provider/model directly',\n done: 'Memory updated',\n minimize: 'Minimize',\n menuExpand: 'Expand',\n pausedBadge: 'Paused',\n menuRunNow: 'Run now',\n menuViewMemory: 'View memories',\n menuPause: 'Pause scheduling',\n menuResume: 'Resume scheduling',\n menuOpenFolder: 'Open memory folder',\n phase1: 'Extracting memories',\n phase2: 'Consolidating memories',\n processing: 'Memory processing',\n transfer_exportLabel: 'Export memory',\n transfer_exportDesc: 'Save as a single bundle file — pick the location in the browser',\n transfer_importLabel: 'Import memory',\n transfer_importDesc: 'Pick a bundle file to merge into the current memory store',\n transfer_export: 'Export',\n transfer_import: 'Import',\n transfer_requested: 'Sent — result appears in the status bar above',\n transfer_tooBig: 'File exceeds 32 MB — use the memory_export tool to write it to disk instead',\n transfer_readFailed: 'Failed to read the file',\n viewer_title: 'Memory',\n viewer_refresh: 'Refresh',\n viewer_translate: 'Translate memory',\n viewer_translating: 'Translating…',\n viewer_tab_overview: 'Overview',\n viewer_tab_summary: 'Summary',\n viewer_tab_index: 'Registry',\n viewer_tab_records: 'Records',\n viewer_stat_records: 'Records',\n viewer_stat_consolidated: 'Consolidated',\n viewer_stat_citations: 'Citations',\n viewer_stat_summarySize: 'Summary size',\n viewer_stat_indexSize: 'Registry size',\n viewer_topCited: 'Most cited',\n viewer_noCitations: 'No citations yet',\n viewer_original: 'Show original',\n viewer_translated: 'Show translation',\n viewer_showTranslated: 'Translation',\n viewer_badgeTranslated: 'Translated',\n viewer_rebuild: 'Rebuild',\n viewer_rebuildConfirm: 'Ignore cache and retranslate everything?',\n viewer_confirm: 'Confirm',\n viewer_cancel: 'Cancel',\n viewer_retranslate: 'Re-translate',\n viewer_stale: 'Translation stale',\n viewer_fresh: 'Up to date',\n viewer_empty: 'Nothing here yet',\n viewer_decodeFailed: 'Could not decode memory content (browser lacks DecompressionStream)',\n viewer_search: 'Search sessions or paths…',\n viewer_col_session: 'Session',\n viewer_col_usage: 'Citations',\n viewer_col_updated: 'Updated',\n viewer_col_lastUsed: 'Last used',\n}\n\n/** Activate the browser half: register the Memory settings page and the status pill. */\nexport function apply(ctx: ClientContext): void {\n ctx.effect(() => ctx.locale.register(NS, { zh: ZH, en: EN }), 'dsh-memory: dictionaries')\n // Keep the raw citation XML out of the visible transcript (the host-side\n // citation loop reads it from the session log regardless).\n ctx.effect(() => installCitationStripper(), 'dsh-memory: citation stripper')\n\n const cardScope = ctx.settingsScope.bind({ namespace: 'memory' })\n const statusScope = ctx.settingsScope.bind({ namespace: 'memory-status' })\n const commandsScope = ctx.settingsScope.bind({ namespace: 'memory-commands' })\n const viewerScope = ctx.settingsScope.bind({ namespace: 'memory-view' })\n const card = new MemoryCardController(cardScope, catalogLoader(ctx))\n // Bound closures: detached scope methods may rely on `this`.\n const statusSource = {\n getSnapshot: () => statusScope.getSnapshot(),\n subscribe: (listener: () => void) => statusScope.subscribe(listener),\n }\n const viewSource = {\n getSnapshot: () => viewerScope.getSnapshot(),\n subscribe: (listener: () => void) => viewerScope.subscribe(listener),\n }\n const commandsView = {\n set: (field: string, value: unknown) => commandsScope.set(field, value),\n unset: (field: string) => commandsScope.unset(field),\n }\n const memoryView = {\n set: (field: string, value: unknown) => cardScope.set(field, value),\n unset: (field: string) => cardScope.unset(field),\n getSnapshot: () => cardScope.getSnapshot(),\n subscribe: (listener: () => void) => cardScope.subscribe(listener),\n }\n\n // Standalone viewer page: a right-sidebar tab (ui-sidebar-right is optional\n // in the composition, so the whole registration waits on the service).\n let sidebarRight: ClientContext['sidebarRight']\n ctx.inject(['sidebarRightTabs', 'sidebarRight'], (sctx) => {\n sidebarRight = sctx.sidebarRight\n const tabTitle = (): string => ctx.locale.bind(NS)('viewer_title')\n sctx.effect(() => sctx.sidebarRightTabs?.register({\n id: MEMORY_VIEWER_ID,\n kind: MEMORY_VIEWER_KIND,\n title: tabTitle,\n }), 'dsh-memory: viewer tab type')\n sctx.effect(() => sctx.slots.inject('sidebar.right.pane.tab', () => sctx.slots.register(\n {\n name: 'sidebar.right.pane.tab',\n key: MEMORY_VIEWER_ID,\n locale: NS,\n inject: () => ({\n hooks: { memoryView: viewSource, memoryStatus: statusSource },\n commands: commandsView,\n }),\n },\n MemoryViewerBody,\n )), 'dsh-memory: viewer tab body')\n sctx.effect(() => sctx.slots.inject('sidebar.right.pane.tab.title', () => sctx.slots.register(\n { name: 'sidebar.right.pane.tab.title', key: MEMORY_VIEWER_ID, locale: NS },\n MemoryViewerTitle,\n )), 'dsh-memory: viewer tab title')\n })\n const openViewer = (): void => {\n try {\n sidebarRight?.openTab(MEMORY_VIEWER_KIND, {})\n } catch {\n // the pane can fail to open only when the sidebar service is gone\n }\n }\n // Own Settings → Memory page (independent section in the settings sidebar).\n ctx.slots.inject('settings.section', () => ctx.slots.register(\n {\n name: 'settings.section',\n id: 'memory',\n order: 16,\n label: () => t_nav(ctx),\n locale: NS,\n inject: () => ({\n // The controller face carries edit/resetField/refreshCatalog; the\n // renderer binds them as plain props, and the hooks compartment as\n // useMemoryPage/useMemoryStatus/useMemoryView selector hooks.\n ...card.inject(),\n commands: commandsView,\n hooks: {\n memoryPage: card.pageStore(),\n memoryStatus: statusSource,\n memoryView: viewSource,\n },\n }),\n },\n MemorySettingsPage,\n ))\n\n ctx.slots.inject('sidebar.footer.action', () => ctx.slots.register(\n {\n name: 'sidebar.footer.action',\n id: 'dsh-memory-status',\n order: 10,\n locale: NS,\n inject: () => ({\n hooks: { memoryStatus: statusSource },\n commands: commandsView,\n settings: memoryView,\n openViewer,\n }),\n },\n MemoryFooterAction,\n ))\n}\n\nfunction t_nav(ctx: ClientContext): string {\n const t = ctx.locale.bind(NS)\n return t('nav')\n}\n\n/** Query the Host model catalog and flatten it into selectable routes. */\nfunction catalogLoader(ctx: ClientContext): (() => Promise<CatalogModel[]>) | null {\n const call = ctx.remote?.session?.modelCatalog\n if (call == null) return null\n return async (): Promise<CatalogModel[]> => {\n const result = await call.call(ctx.remote!.session!)\n if (!result?.ok || result.value == null) {\n throw new Error('model catalog unavailable')\n }\n const catalog = result.value as {\n groups: Array<{ id: string; name: string; models: Array<{ id: string; name: string }> }>\n }\n return catalog.groups.flatMap((group) => group.models.map((model) => ({\n provider: group.id,\n providerName: group.name,\n model: model.id,\n modelName: model.name,\n })))\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"client.js","names":["FIELD_SPECS: readonly FieldSpec[]","scope: ScopeView","loadCatalog: (() => Promise<CatalogModel[]>) | null","fields: FieldState[]","plan: Array<{ field: string; clear: boolean; value?: unknown }>","BORDER","name","t: (key: string) => string","state: CardState","name","result: RemoteResult<MemoryCommandResult>","dispose: () => Promise<void>","styleInjected","t: (key: string) => string","panelStyle: Record<string, unknown>","scope: Element | null","EMPTY_TEXTS: Texts","ZH: Record<string, string>","EN: Record<string, string>","dispose: (() => Promise<void>) | undefined","sidebarRight: ClientContext['sidebarRight']"],"sources":["../src/client/store.ts","../src/client/memory-card.ts","../src/client/remote.ts","../src/client/sidebar-action.ts","../src/client/citation-stripper.ts","../src/client/memory-viewer.ts","../src/client/index.ts"],"sourcesContent":["/** Minimal observable snapshot store (useSyncExternalStore-compatible). */\nexport class SnapshotStore<S> {\n private snapshot: S\n private readonly listeners = new Set<() => void>()\n\n constructor(initial: S) {\n this.snapshot = initial\n }\n\n getSnapshot = (): S => this.snapshot\n\n subscribe = (listener: () => void): (() => void) => {\n this.listeners.add(listener)\n return () => {\n this.listeners.delete(listener)\n }\n }\n\n set(next: S): void {\n if (Object.is(next, this.snapshot)) return\n this.snapshot = next\n for (const listener of [...this.listeners]) listener()\n }\n}\n","/**\n * The memory settings page: a staged-edit form over the `memory` settings\n * namespace, rendered as its own Settings section. Draft text is what a save\n * would store, and each field shows whether the user layer carries it.\n * Rendered with plain createElement — no JSX transform in this bundle.\n */\n\nimport { createElement, useRef, useState } from 'react'\n\nimport { SnapshotStore } from './store.ts'\nimport type { CatalogModel, CommandRunner, ScopeView } from './types.ts'\n\nlet pageStyleInjected = false\n\n/** Interactive styles (inline styles cannot express :hover/:focus). */\nfunction ensurePageStyles(): void {\n if (pageStyleInjected || typeof document === 'undefined') return\n if (document.querySelector('style[data-dsh-memory-page]') != null) {\n pageStyleInjected = true\n return\n }\n const tag = document.createElement('style')\n tag.dataset.dshMemoryPage = 'true'\n tag.textContent = [\n '@keyframes dsh-memory-pulse { 0% { opacity: 0.35; transform: scale(0.8); } 50% { opacity: 1; transform: scale(1.08); } 100% { opacity: 0.35; transform: scale(0.8); } }',\n '.dshm-btn { transition: border-color 150ms ease, background 150ms ease, color 150ms ease, opacity 150ms ease, transform 100ms ease; }',\n '.dshm-btn:hover:not(:disabled) { border-color: var(--dsw-alias-brand-primary, #4b7bec); opacity: 1; background: rgba(75, 123, 236, 0.10); }',\n '.dshm-btn:active:not(:disabled) { transform: translateY(1px); }',\n '.dshm-btn:focus-visible { outline: 2px solid rgba(75, 123, 236, 0.5); outline-offset: 1px; }',\n '.dshm-input { transition: border-color 150ms ease, box-shadow 150ms ease, background 150ms ease; outline: none; }',\n '.dshm-input:hover:not(:disabled) { border-color: rgba(128, 128, 128, 0.45); }',\n '.dshm-input:focus { border-color: var(--dsw-alias-brand-primary, #4b7bec); box-shadow: 0 0 0 3px rgba(75, 123, 236, 0.18); background: var(--dsw-alias-bg-base, transparent); }',\n '.dshm-row + .dshm-row { border-top: 1px solid var(--dsw-alias-border-l2, rgba(128, 128, 128, 0.12)); }',\n // Switch: DSH's Switch primitive spec (36x20 track, 16px thumb), keyed off\n // aria-checked so the paint cannot disagree with assistive state.\n '.dshm-switch { box-sizing: border-box; position: relative; flex: 0 0 auto; width: 36px; height: 20px; padding: 2px; border: 0; border-radius: 10px; corner-shape: round; background: var(--dsw-alias-border-l3, rgba(128, 128, 128, 0.45)); cursor: pointer; }',\n '.dshm-switch[aria-checked=\"true\"] { background: var(--dsw-alias-brand-primary, #4b7bec); }',\n '.dshm-switch:disabled { cursor: default; opacity: 0.5; }',\n '.dshm-switch:focus-visible { outline: 2px solid var(--dsw-alias-brand-primary, #4b7bec); outline-offset: 2px; }',\n '.dshm-thumb { display: block; width: 16px; height: 16px; border-radius: 50%; corner-shape: round; background: var(--dsw-alias-label-primary-foreground, #fff); transition: transform 120ms ease; }',\n '.dshm-switch[aria-checked=\"true\"] .dshm-thumb { transform: translateX(16px); }',\n '.dshm-advanced-head { transition: background 120ms ease; border-radius: 8px; }',\n '.dshm-advanced-head:hover { background: rgba(128, 128, 128, 0.07); }',\n ].join('\\n')\n document.head.appendChild(tag)\n pageStyleInjected = true\n}\n\nexport type FieldKind = 'string' | 'number' | 'boolean' | 'list' | 'model'\n\nexport interface FieldSpec {\n field: string\n kind: FieldKind\n group: string\n}\n\n/**\n * Every MemoryPluginConfig field, grouped for display. `advanced` collects the\n * knobs a routine user never touches (paths, backoff/retry tuning, the\n * consolidator denylist) behind a collapsed section.\n */\nexport const FIELD_SPECS: readonly FieldSpec[] = [\n { field: 'enabled', kind: 'boolean', group: 'general' },\n { field: 'generateMemories', kind: 'boolean', group: 'general' },\n { field: 'useMemories', kind: 'boolean', group: 'general' },\n { field: 'extractModel', kind: 'model', group: 'models' },\n { field: 'consolidationModel', kind: 'model', group: 'models' },\n { field: 'scanIntervalMinutes', kind: 'number', group: 'schedule' },\n { field: 'minRolloutIdleHours', kind: 'number', group: 'schedule' },\n { field: 'maxSessionAgeDays', kind: 'number', group: 'schedule' },\n { field: 'maxUnusedDays', kind: 'number', group: 'schedule' },\n { field: 'summaryTokenLimit', kind: 'number', group: 'recall' },\n { field: 'redactSecrets', kind: 'boolean', group: 'recall' },\n { field: 'workspaceDir', kind: 'string', group: 'advanced' },\n { field: 'dbPath', kind: 'string', group: 'advanced' },\n { field: 'phase2TimeoutMinutes', kind: 'number', group: 'advanced' },\n { field: 'phase2SuccessCooldownSeconds', kind: 'number', group: 'advanced' },\n { field: 'phase1RetryBackoffMinutes', kind: 'number', group: 'advanced' },\n { field: 'phase1MaxRetries', kind: 'number', group: 'advanced' },\n { field: 'phase1MaxPerCycle', kind: 'number', group: 'advanced' },\n { field: 'phase1MaxConcurrency', kind: 'number', group: 'advanced' },\n { field: 'extractInputContextRatio', kind: 'number', group: 'advanced' },\n { field: 'maxRolloutSummaries', kind: 'number', group: 'advanced' },\n { field: 'consolidatorDenyPatterns', kind: 'list', group: 'advanced' },\n]\n\nconst FIELD_ORDER = new Map(FIELD_SPECS.map((spec, index) => [spec.field, index]))\n\ninterface FieldState {\n spec: FieldSpec\n text: string\n overridden: boolean\n invalid: boolean\n}\n\nexport interface CardState {\n available: boolean\n writable: boolean\n dirty: boolean\n invalid: boolean\n saving: boolean\n failed: boolean\n catalogStatus: 'unavailable' | 'loading' | 'ready' | 'error'\n catalogModels: CatalogModel[]\n fields: FieldState[]\n}\n\ninterface StagedEdit {\n text: string\n clear: boolean\n}\n\n/** Debounce between the last edit and its automatic commit. */\nconst AUTOSAVE_DELAY_MS = 500\n\nfunction formatValue(spec: FieldSpec, value: unknown): string {\n if (value === undefined || value === null) return ''\n if (spec.kind === 'boolean') return value === true ? 'true' : 'false'\n if (spec.kind === 'list') return Array.isArray(value) ? value.join(', ') : ''\n return String(value)\n}\n\nfunction parseValue(spec: FieldSpec, text: string): { ok: boolean; value?: unknown } {\n const trimmed = text.trim()\n if (spec.kind === 'boolean') {\n if (trimmed === 'true') return { ok: true, value: true }\n if (trimmed === 'false') return { ok: true, value: false }\n return { ok: false }\n }\n if (trimmed === '') return { ok: true, value: undefined } // clear\n if (spec.kind === 'number') {\n const parsed = Number(trimmed)\n return Number.isFinite(parsed) ? { ok: true, value: parsed } : { ok: false }\n }\n if (spec.kind === 'list') {\n const items = trimmed.split(',').map((item) => item.trim()).filter((item) => item !== '')\n return items.length > 0 ? { ok: true, value: items } : { ok: true, value: undefined }\n }\n return { ok: true, value: trimmed }\n}\n\nexport class MemoryCardController {\n private readonly staged = new Map<string, StagedEdit>()\n private readonly store: SnapshotStore<CardState>\n private saving = false\n private failed = false\n private autosaveTimer: ReturnType<typeof setTimeout> | null = null\n private catalogStatus: 'unavailable' | 'loading' | 'ready' | 'error'\n private catalogModels: CatalogModel[] = []\n\n constructor(\n private readonly scope: ScopeView,\n private readonly loadCatalog: (() => Promise<CatalogModel[]>) | null,\n ) {\n this.catalogStatus = loadCatalog == null ? 'unavailable' : 'loading'\n this.store = new SnapshotStore(this.project())\n scope.subscribe(() => {\n this.store.set(this.project())\n })\n if (loadCatalog != null) void this.refreshCatalog()\n }\n\n /** Re-query the Host model catalog (exposed as a page action). */\n async refreshCatalog(): Promise<void> {\n if (this.loadCatalog == null) return\n this.catalogStatus = 'loading'\n this.publish()\n try {\n this.catalogModels = await this.loadCatalog()\n this.catalogStatus = 'ready'\n } catch {\n this.catalogStatus = 'error'\n }\n this.publish()\n }\n\n /** The observable page snapshot source for the section's hooks seat. */\n pageStore(): SnapshotStore<CardState> {\n return this.store\n }\n\n inject(): Record<string, unknown> {\n return {\n hooks: { memoryPage: this.store },\n edit: (field: string, text: string) => {\n this.staged.set(field, { text, clear: false })\n this.failed = false\n this.publish()\n this.scheduleAutosave()\n },\n resetField: (field: string) => {\n const spec = this.specOf(field)\n const base = (this.scope.getSnapshot().base as Record<string, unknown> | undefined)?.[field]\n this.staged.set(field, { text: formatValue(spec, base), clear: true })\n this.failed = false\n this.publish()\n this.scheduleAutosave()\n },\n refreshCatalog: () => {\n void this.refreshCatalog()\n },\n }\n }\n\n /** Auto-commit pending edits once typing pauses (checkbox/select/reset included). */\n private scheduleAutosave(): void {\n if (this.autosaveTimer != null) clearTimeout(this.autosaveTimer)\n this.autosaveTimer = setTimeout(() => {\n this.autosaveTimer = null\n void this.save()\n }, AUTOSAVE_DELAY_MS)\n }\n\n private specOf(field: string): FieldSpec {\n const spec = FIELD_SPECS.find((candidate) => candidate.field === field)\n if (spec == null) throw new Error(`memory page has no field ${field}`)\n return spec\n }\n\n private project(): CardState {\n const snapshot = this.scope.getSnapshot()\n const section = (snapshot.value ?? {}) as Record<string, unknown>\n const user = snapshot.user as Record<string, unknown> | undefined\n const fields: FieldState[] = [...FIELD_SPECS]\n .sort((a, b) => (FIELD_ORDER.get(a.field) ?? 0) - (FIELD_ORDER.get(b.field) ?? 0))\n .map((spec) => {\n const staged = this.staged.get(spec.field)\n if (staged === undefined) {\n return {\n spec,\n text: formatValue(spec, section[spec.field]),\n overridden: user !== undefined && Object.hasOwn(user, spec.field),\n invalid: false,\n }\n }\n const parsed = parseValue(spec, staged.text)\n return {\n spec,\n text: staged.text,\n overridden: staged.clear ? false : parsed.ok && parsed.value !== undefined,\n invalid: !staged.clear && !parsed.ok,\n }\n })\n return {\n available: snapshot.status === 'ready',\n writable: snapshot.writable,\n dirty: this.plan(fields).length > 0,\n invalid: fields.some((field) => field.invalid),\n saving: this.saving,\n failed: this.failed,\n catalogStatus: this.catalogStatus,\n catalogModels: this.catalogModels,\n fields,\n }\n }\n\n /** Staged edits a save would perform, in field order. */\n private plan(fields: FieldState[]): Array<{ field: string; clear: boolean; value?: unknown }> {\n const section = (this.scope.getSnapshot().value ?? {}) as Record<string, unknown>\n const plan: Array<{ field: string; clear: boolean; value?: unknown }> = []\n for (const field of fields) {\n const staged = this.staged.get(field.spec.field)\n if (staged === undefined) continue\n if (staged.clear) {\n if (field.overridden) plan.push({ field: field.spec.field, clear: true })\n continue\n }\n const parsed = parseValue(field.spec, staged.text)\n if (!parsed.ok) continue\n if (formatValue(field.spec, section[field.spec.field]) === staged.text.trim()) continue\n if (parsed.value === undefined) {\n plan.push({ field: field.spec.field, clear: true })\n } else {\n plan.push({ field: field.spec.field, clear: false, value: parsed.value })\n }\n }\n return plan\n }\n\n private async save(): Promise<void> {\n const fields = this.project().fields\n const plan = this.plan(fields)\n if (plan.length === 0 || plan.some((item) => !item.clear && item.value === undefined)) return\n if (this.saving) {\n // A write is crossing the wire; retry the just-staged edit after it lands.\n this.scheduleAutosave()\n return\n }\n this.saving = true\n this.failed = false\n this.publish()\n let landed = true\n for (const item of plan) {\n try {\n if (item.clear) await this.scope.unset(item.field)\n else await this.scope.set(item.field, item.value)\n } catch {\n landed = false\n }\n }\n // Drop only the committed keys: edits staged while the write was in\n // flight keep their own pending autosave.\n if (landed) for (const item of plan) this.staged.delete(item.field)\n this.saving = false\n this.failed = !landed\n this.publish()\n }\n\n private publish(): void {\n this.store.set(this.project())\n }\n}\n\n// ── styling ─────────────────────────────────────────────────────────────────\n\nconst ACCENT = 'var(--dsw-alias-brand-primary, #4b7bec)'\nconst BORDER = 'var(--dsw-alias-border-l2, rgba(128, 128, 128, 0.2))'\nconst DANGER = '#e05561'\nconst MUTED = 'var(--dsw-alias-label-secondary, rgba(128, 128, 128, 0.9))'\n\nfunction sectionStyle(): Record<string, unknown> {\n return { marginTop: 26 }\n}\n\nfunction sectionHeaderStyle(): Record<string, unknown> {\n return {\n fontSize: 11,\n fontWeight: 650,\n letterSpacing: 1.1,\n textTransform: 'uppercase',\n opacity: 0.5,\n margin: '0 2px 2px',\n }\n}\n\nfunction rowStyle(): Record<string, unknown> {\n return {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 20,\n minHeight: 34,\n padding: '9px 2px',\n }\n}\n\nfunction labelStackStyle(): Record<string, unknown> {\n return { display: 'flex', flexDirection: 'column', gap: 2, minWidth: 0 }\n}\n\nfunction inputStyle(invalid: boolean): Record<string, unknown> {\n return {\n width: 230,\n boxSizing: 'border-box',\n padding: '6px 10px',\n fontSize: 12.5,\n borderRadius: 8,\n border: `1px solid ${invalid ? DANGER : BORDER}`,\n background: 'var(--dsw-alias-fill-tertiary, rgba(128, 128, 128, 0.06))',\n color: 'inherit',\n textAlign: 'left',\n }\n}\n\nfunction ghostButtonStyle(disabled: boolean): Record<string, unknown> {\n return {\n fontSize: 12,\n padding: '4px 12px',\n borderRadius: 8,\n cursor: disabled ? 'default' : 'pointer',\n border: `1px solid ${BORDER}`,\n background: 'transparent',\n color: 'inherit',\n opacity: disabled ? 0.4 : 0.8,\n }\n}\n\nfunction primaryButtonStyle(disabled: boolean): Record<string, unknown> {\n // Shell button tokens: a filled primary, not a washed-out translucent tint.\n return {\n fontSize: 12,\n padding: '4px 14px',\n borderRadius: 8,\n cursor: disabled ? 'default' : 'pointer',\n border: '1px solid transparent',\n background: disabled ? 'transparent' : 'var(--dsw-alias-button-info-fill, #4d6bfe)',\n color: disabled ? 'inherit' : 'var(--dsw-alias-label-primary-inverted, #fff)',\n fontWeight: 600,\n opacity: disabled ? 0.4 : 1,\n }\n}\n\nfunction badgeStyle(): Record<string, unknown> {\n return {\n fontSize: 10,\n padding: '1px 7px',\n borderRadius: 999,\n background: 'var(--dsw-alias-state-business-tertiary, rgba(75, 123, 236, 0.14))',\n color: ACCENT,\n whiteSpace: 'nowrap',\n }\n}\n\n// ── components ──────────────────────────────────────────────────────────────\n\n/** Toggle switch for boolean fields (replaces the bare checkbox). */\nfunction Switch(props: { on: boolean; disabled: boolean; label?: string; onToggle: (next: boolean) => void }) {\n return createElement('button', {\n type: 'button',\n role: 'switch',\n 'aria-checked': props.on,\n 'aria-label': props.label,\n disabled: props.disabled,\n className: 'dshm-switch',\n onClick: () => props.onToggle(!props.on),\n }, createElement('span', { className: 'dshm-thumb' }))\n}\n\nfunction FieldRow(props: {\n t: (key: string) => string\n state: FieldState\n disabled: boolean\n catalogModels?: CatalogModel[]\n onEdit: (text: string) => void\n onReset: () => void\n}) {\n const { t, state, disabled } = props\n const hint = hintText(t, state.spec.field)\n let control\n if (state.spec.kind === 'boolean') {\n control = createElement(Switch, {\n on: state.text === 'true',\n disabled,\n label: t(`field_${state.spec.field}`),\n onToggle: (next: boolean) => props.onEdit(next ? 'true' : 'false'),\n })\n } else if (state.spec.kind === 'model') {\n control = createElement(ModelSelect, {\n t,\n state,\n catalogModels: props.catalogModels ?? [],\n disabled,\n onEdit: props.onEdit,\n })\n } else {\n control = createElement('input', {\n type: 'text',\n value: state.text,\n disabled,\n spellCheck: false,\n className: 'dshm-input',\n onChange: (event: { target: { value: string } }) => {\n props.onEdit(event.target.value)\n },\n style: inputStyle(state.invalid),\n })\n }\n return createElement('div', { key: state.spec.field, className: 'dshm-row', style: rowStyle() },\n createElement('div', { style: labelStackStyle() },\n createElement('span', { style: { fontSize: 13 } }, fieldLabel(t, state.spec.field)),\n hint !== ''\n ? createElement('span', { style: { fontSize: 11.5, opacity: 0.5 } }, hint)\n : null,\n ),\n createElement('div', { style: { display: 'flex', alignItems: 'center', gap: 8, flexShrink: 0 } },\n state.overridden ? createElement('span', { style: badgeStyle() }, t('overridden')) : null,\n state.overridden\n ? createElement('button', {\n type: 'button',\n disabled,\n className: 'dshm-btn',\n onClick: props.onReset,\n style: ghostButtonStyle(disabled),\n }, t('reset'))\n : null,\n control,\n ),\n )\n}\n\n/** Dropdown over the Host model catalog; empty value = deployment default. */\nfunction ModelSelect(props: {\n t: (key: string) => string\n state: FieldState\n catalogModels: CatalogModel[]\n disabled: boolean\n onEdit: (text: string) => void\n}) {\n const { t, state, catalogModels } = props\n const current = state.text\n const options = [createElement('option', { key: '__default__', value: '' }, t('modelDefault'))]\n for (const model of catalogModels) {\n const value = `${model.provider}/${model.model}`\n options.push(createElement('option', { key: value, value }, `${model.modelName} · ${model.providerName}`))\n }\n if (current !== '' && !catalogModels.some((model) => `${model.provider}/${model.model}` === current)) {\n options.push(createElement('option', { key: current, value: current }, current))\n }\n return createElement('select', {\n value: current,\n disabled: props.disabled,\n className: 'dshm-input',\n onChange: (event: { target: { value: string } }) => {\n props.onEdit(event.target.value)\n },\n style: inputStyle(false),\n }, options)\n}\n\n/** Upper bound for an import traveling base64 through the host remote. */\nconst IMPORT_LIMIT_BYTES = 32 * 1024 * 1024\n\n/** Save bundle bytes: native save dialog where available, download fallback. */\nasync function saveBundleFile(name: string, base64: string): Promise<void> {\n const binary = atob(base64)\n const bytes = new Uint8Array(binary.length)\n for (let index = 0; index < binary.length; index += 1) bytes[index] = binary.charCodeAt(index)\n const picker = (window as unknown as {\n showSaveFilePicker?: (options: { suggestedName: string }) => Promise<{\n createWritable: () => Promise<{ write: (data: Uint8Array) => Promise<void>; close: () => Promise<void> }>\n }>\n }).showSaveFilePicker\n if (picker != null) {\n try {\n const handle = await picker.call(window, { suggestedName: name })\n const writable = await handle.createWritable()\n await writable.write(bytes)\n await writable.close()\n return\n } catch (error) {\n if ((error as { name?: string })?.name === 'AbortError') return\n // picker failed for another reason — fall through to the download path\n }\n }\n const url = URL.createObjectURL(new Blob([bytes]))\n const anchor = document.createElement('a')\n anchor.href = url\n anchor.download = name\n anchor.click()\n setTimeout(() => URL.revokeObjectURL(url), 1_000)\n}\n\n/**\n * Import/export entry: export returns the bundle from the host and saves it\n * through the browser's file dialog; import reads a picked file and hands the\n * bytes back to the host. Outcomes come back as `transfer:`-prefixed status\n * detail lines.\n */\nfunction TransferSection(props: {\n t: (key: string) => string\n commands?: CommandRunner\n statusDetail?: string\n}) {\n const { t, commands } = props\n const [requested, setRequested] = useState<'export' | 'import' | null>(null)\n const [localError, setLocalError] = useState('')\n const fileInput = useRef<HTMLInputElement | null>(null)\n\n const exportBundle = async (): Promise<void> => {\n if (commands == null) return\n setLocalError('')\n setRequested('export')\n try {\n const result = await commands.run({ action: 'export' })\n if (result.bundle != null && result.bundle.data !== '') {\n await saveBundleFile(result.bundle.name, result.bundle.data)\n return\n }\n if (!result.ok) setLocalError(result.detail)\n } catch (error) {\n setLocalError(String(error))\n }\n }\n\n const importBundle = async (payload: string): Promise<void> => {\n if (commands == null) return\n setLocalError('')\n setRequested('import')\n try {\n const result = await commands.run({ action: 'import', payload })\n if (!result.ok) setLocalError(result.detail)\n } catch (error) {\n setLocalError(String(error))\n }\n }\n\n const pickImport = (event: { target: { files?: FileList | null; value: string } }): void => {\n const file = event.target.files?.[0]\n event.target.value = ''\n if (file == null) return\n if (file.size > IMPORT_LIMIT_BYTES) {\n setLocalError(t('transfer_tooBig'))\n return\n }\n const reader = new FileReader()\n reader.onload = () => {\n const result = String(reader.result ?? '')\n void importBundle(result.slice(result.indexOf(',') + 1))\n }\n reader.onerror = () => setLocalError(t('transfer_readFailed'))\n reader.readAsDataURL(file)\n }\n\n const feedback = localError !== ''\n ? localError\n : props.statusDetail?.startsWith('transfer:') === true\n ? props.statusDetail.slice('transfer:'.length).trim()\n : null\n const feedbackIsError = feedback != null && (localError !== '' || /fail|need|must|unsupported|error/iu.test(feedback))\n\n const transferRow = (labelKey: string, descKey: string, action: 'export' | 'import') =>\n createElement('div', { className: 'dshm-row', style: rowStyle() },\n createElement('div', { style: labelStackStyle() },\n createElement('span', { style: { fontSize: 13 } }, t(labelKey)),\n createElement('span', { style: { fontSize: 11.5, opacity: 0.5 } }, t(descKey)),\n ),\n createElement('button', {\n type: 'button',\n disabled: commands == null,\n className: 'dshm-btn',\n onClick: () => {\n setLocalError('')\n setRequested(action)\n if (action === 'export') void exportBundle()\n else fileInput.current?.click()\n },\n style: primaryButtonStyle(commands == null),\n }, t(`transfer_${action}`)),\n )\n\n return createElement('section', { style: sectionStyle() },\n createElement('h3', { style: sectionHeaderStyle() }, t('group_transfer')),\n createElement('div', { style: { borderTop: `1px solid ${BORDER}` } },\n transferRow('transfer_exportLabel', 'transfer_exportDesc', 'export'),\n transferRow('transfer_importLabel', 'transfer_importDesc', 'import'),\n ),\n createElement('input', {\n type: 'file',\n accept: '.json,.gz,.dshmem',\n ref: fileInput,\n style: { display: 'none' },\n onChange: pickImport,\n }),\n createElement('div', { style: { minHeight: 18, margin: '4px 2px 0' } },\n feedback != null\n ? createElement('span', { style: { fontSize: 12, color: feedbackIsError ? DANGER : 'inherit', opacity: feedbackIsError ? 1 : 0.8 } }, feedback)\n : requested != null\n ? createElement('span', { style: { fontSize: 12, opacity: 0.55 } }, t('transfer_requested'))\n : null,\n ),\n )\n}\n\n/** Collapsible section for the expert knobs (paths, retry tuning, denylist). */\nfunction AdvancedSection(props: {\n t: (key: string) => string\n fields: FieldState[]\n disabled: boolean\n onEdit: (field: string, text: string) => void\n onReset: (field: string) => void\n}) {\n const [open, setOpen] = useState(false)\n const { t } = props\n return createElement('section', { style: sectionStyle() },\n createElement('button', {\n type: 'button',\n className: 'dshm-advanced-head',\n onClick: () => setOpen(!open),\n style: {\n display: 'flex', alignItems: 'center', gap: 6, width: '100%',\n padding: '4px 6px 4px 2px', border: 'none', background: 'transparent',\n color: 'inherit', cursor: 'pointer', textAlign: 'left',\n },\n },\n createElement('span', {\n style: {\n fontSize: 9, opacity: 0.55, display: 'inline-block',\n transform: open ? 'rotate(90deg)' : 'none',\n transition: 'transform 150ms ease',\n },\n }, '▶'),\n createElement('span', { style: { ...sectionHeaderStyle(), margin: 0 } }, t('group_advanced')),\n !open\n ? createElement('span', { style: { fontSize: 11, opacity: 0.4 } }, `${props.fields.length}`)\n : null,\n ),\n open\n ? createElement('div', { style: { borderTop: `1px solid ${BORDER}` } },\n ...props.fields.map((field) => createElement(FieldRow, {\n key: field.spec.field,\n t,\n state: field,\n disabled: props.disabled,\n onEdit: (text: string) => props.onEdit(field.spec.field, text),\n onReset: () => props.onReset(field.spec.field),\n })),\n )\n : null,\n )\n}\n\nfunction fieldLabel(t: (key: string) => string, field: string): string {\n return t(`field_${field}`)\n}\n\nfunction hintText(t: (key: string) => string, field: string): string {\n const hint = t(`hint_${field}`)\n return hint === `hint_${field}` ? '' : hint\n}\n\n/**\n * The dedicated Memory settings page: live status banner, divided-list sections\n * with catalog-backed model pickers and toggle switches, transfer actions, and a\n * collapsed advanced section. Rendered both as its own `settings.section` seat\n * and inside the plugin page's `plugins.bundle.config` seat, where `embedded`\n * drops the heading the page already supplies.\n * Render failures surface inline instead of blanking the panel.\n */\nexport function MemorySettingsPage(props: Record<string, any>) {\n try {\n return renderMemoryPage(props)\n } catch (error) {\n return createElement('div', {\n style: { fontSize: 12.5, color: DANGER, maxWidth: 640, whiteSpace: 'pre-wrap' },\n }, `memory settings page error: ${String(error)}`)\n }\n}\n\nfunction renderMemoryPage(props: Record<string, any>) {\n if (props.useMemoryPage == null) {\n return createElement('div', { style: { fontSize: 13, opacity: 0.6 } }, 'renderer did not bind the memory page hook')\n }\n ensurePageStyles()\n const t: (key: string) => string = props.t\n const state: CardState = props.useMemoryPage((value: CardState) => value)\n const statusSnapshot = props.useMemoryStatus != null\n ? props.useMemoryStatus((value: unknown) => value) as\n | { status: string; value?: { phase?: string; detail?: string; updatedAt?: number } }\n | undefined\n : undefined\n if (!state.available) {\n return createElement('div', { style: { fontSize: 13, opacity: 0.6 } }, t('unavailable'))\n }\n const disabled = !state.writable\n\n const status = statusSnapshot?.status === 'ready' ? statusSnapshot.value : undefined\n const active = status?.phase === 'phase1' || status?.phase === 'phase2'\n const statusLabel = active\n ? (status?.phase === 'phase1' ? t('phase1') : t('phase2'))\n : t('statusIdle')\n\n const groups = new Map<string, FieldState[]>()\n for (const field of state.fields) {\n const list = groups.get(field.spec.group) ?? []\n list.push(field)\n groups.set(field.spec.group, list)\n }\n\n const fieldSection = (group: string) => {\n const fields = groups.get(group)\n if (fields == null || fields.length === 0) return null\n return createElement('section', { key: group, style: sectionStyle() },\n createElement('div', { style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', margin: '0 2px 2px' } },\n createElement('h3', { style: { ...sectionHeaderStyle(), margin: 0 } }, t(`group_${group}`)),\n group === 'models'\n ? createElement('button', {\n type: 'button',\n className: 'dshm-btn',\n onClick: props.refreshCatalog,\n style: { ...ghostButtonStyle(false), border: 'none', padding: '2px 6px', fontSize: 11.5 },\n }, state.catalogStatus === 'loading' ? t('catalogLoading') : t('catalogRefresh'))\n : null,\n ),\n group === 'models' && state.catalogStatus === 'error'\n ? createElement('div', { style: { fontSize: 11.5, color: DANGER, margin: '0 2px 4px' } }, t('catalogError'))\n : null,\n createElement('div', { style: { borderTop: `1px solid ${BORDER}` } },\n ...fields.map((field) => createElement(FieldRow, {\n key: field.spec.field,\n t,\n state: field,\n disabled,\n catalogModels: state.catalogModels,\n onEdit: (text: string) => props.edit(field.spec.field, text),\n onReset: () => props.resetField(field.spec.field),\n })),\n ),\n )\n }\n\n const embedded = props.embedded === true\n return createElement('div', { style: { maxWidth: embedded ? undefined : 640, paddingBottom: embedded ? 0 : 32 } },\n embedded\n ? null\n : createElement('h2', { style: { fontSize: 19, fontWeight: 650, margin: '0 0 4px', letterSpacing: 0.2 } }, t('title')),\n embedded\n ? null\n : createElement('p', { style: { fontSize: 13, opacity: 0.6, margin: '0 0 18px', lineHeight: 1.5 } }, t('intro')),\n // status banner\n createElement('div', {\n style: {\n border: `1px solid ${active ? ACCENT : BORDER}`,\n borderRadius: 10,\n padding: '10px 14px',\n display: 'flex', alignItems: 'center', gap: 10,\n background: active ? 'rgba(75, 123, 236, 0.07)' : 'transparent',\n transition: 'border-color 200ms ease, background 200ms ease',\n },\n },\n createElement('span', {\n style: {\n width: 8, height: 8, borderRadius: '50%', flexShrink: 0,\n background: active ? ACCENT : MUTED,\n animation: active ? 'dsh-memory-pulse 1.4s ease-in-out infinite' : undefined,\n },\n }),\n createElement('span', { style: { fontSize: 12.5, fontWeight: 600, flexShrink: 0 } }, statusLabel),\n status?.detail\n ? createElement('span', { style: { fontSize: 12, opacity: 0.6, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' } }, status.detail)\n : null,\n createElement('span', { style: { fontSize: 11, opacity: 0.4, marginLeft: 'auto', flexShrink: 0 } },\n status?.updatedAt ? new Date(status.updatedAt).toLocaleTimeString() : ''),\n ),\n fieldSection('general'),\n fieldSection('models'),\n fieldSection('schedule'),\n fieldSection('recall'),\n createElement(TransferSection, { t, commands: props.commands, statusDetail: status?.detail }),\n createElement(AdvancedSection, {\n t,\n fields: groups.get('advanced') ?? [],\n disabled,\n onEdit: (field: string, text: string) => props.edit(field, text),\n onReset: (field: string) => props.resetField(field),\n }),\n // Auto-save status line (no manual save/discard): edits commit on pause.\n createElement('div', { style: { display: 'flex', alignItems: 'center', gap: 10, marginTop: 14, minHeight: 22 } },\n state.saving ? createElement('span', { style: { fontSize: 12, opacity: 0.6 } }, t('saving')) : null,\n state.failed ? createElement('span', { style: { fontSize: 12, color: DANGER } }, t('failed')) : null,\n state.invalid ? createElement('span', { style: { fontSize: 12, color: DANGER } }, t('invalid')) : null,\n !state.writable ? createElement('span', { style: { fontSize: 12, opacity: 0.6 } }, t('readOnly')) : null,\n ),\n )\n}\n","/**\n * Browser-side binding of the Host `memory` remote.\n *\n * DSH 0.2 dropped the client `settingsScope` service, so the two halves talk\n * through the Typert gateway instead: this module mounts the client half of\n * the manifest (`src/typert.ts` describes the host face) and exposes the\n * namespace as small snapshot stores the existing components already know how\n * to consume (`ScopeView` / selector hooks).\n */\n\nimport type {\n ClientContext,\n CommandRunner,\n MemoryCommandRequest,\n MemoryCommandResult,\n ScopeSnapshot,\n ScopeView,\n} from './types.ts'\n\nexport interface MemoryStatusPayload {\n phase: string\n detail: string\n summaryPreview: string\n updatedAt: number\n}\n\nexport interface MemoryConfigPayload {\n value: Record<string, unknown>\n base: Record<string, unknown>\n user: Record<string, unknown>\n revision: number\n}\n\nexport interface MemoryViewPayload {\n blobs: string\n records: string\n translatedStale: boolean\n translating: boolean\n updatedAt: number\n}\n\ninterface RemoteFailure {\n code?: string\n message?: string\n}\n\ntype RemoteResult<T> = { ok: true; value: T } | { ok: false; error: RemoteFailure }\n\n/** The namespace service the gateway installs as `remote.memory`. */\ninterface MemoryRemote {\n getStatus(): Promise<RemoteResult<MemoryStatusPayload>>\n getConfig(): Promise<RemoteResult<MemoryConfigPayload>>\n updateConfig(patch: Record<string, unknown>): Promise<RemoteResult<MemoryConfigPayload>>\n unsetConfig(field: string): Promise<RemoteResult<MemoryConfigPayload>>\n getView(): Promise<RemoteResult<MemoryViewPayload>>\n runCommand(request: MemoryCommandRequest): Promise<RemoteResult<MemoryCommandResult>>\n}\n\n/**\n * Result codecs exist only to satisfy the strict-codec contract; the gateway\n * already delivered parsed JSON, so the browser side does no re-parsing.\n */\nconst passthrough = (name: string) => ({\n mode: 'strict' as const,\n typeSymbol: `dsh-remember#${name}`,\n create: () => ({ parse: <T>(value: unknown): T => value as T }),\n})\n\nconst jsonParameter = (name: string, typeName: string) => ({\n name,\n wire: name,\n source: 'json' as const,\n codec: passthrough(typeName),\n})\n\nconst descriptor = (method: string, parameters: ReturnType<typeof jsonParameter>[], resultName: string) => ({\n id: `dsh-remember#memory/${method}`,\n service: 'memory',\n namespace: 'memory',\n method,\n invocation: { kind: 'direct' as const },\n parameters,\n result: passthrough(resultName),\n})\n\n/** Mirrors MEMORY_INVOCATIONS in src/typert.ts (method names and wires must match). */\nconst CONTRIBUTION = {\n package: 'dsh-remember',\n descriptors: [\n descriptor('getStatus', [], 'MemoryStatus'),\n descriptor('getConfig', [], 'ConfigSnapshot'),\n descriptor('updateConfig', [jsonParameter('patch', 'ConfigPatch')], 'ConfigSnapshot'),\n descriptor('unsetConfig', [jsonParameter('field', 'ConfigField')], 'ConfigSnapshot'),\n descriptor('getView', [], 'MemoryView'),\n descriptor('runCommand', [jsonParameter('request', 'CommandRequest')], 'CommandResult'),\n ],\n}\n\nconst STATUS_POLL_MS = 2_500\nconst CONFIG_POLL_MS = 15_000\nconst VIEW_POLL_MS = 5_000\n\n/** A snapshot store with change notification, in the Shape components expect. */\nclass BridgeStore<T> {\n private snapshot: ScopeSnapshot<T>\n private readonly listeners = new Set<() => void>()\n /** Fired when the subscriber count crosses zero; used for lazy polling. */\n onActiveChange: ((active: boolean) => void) | undefined\n\n constructor(initial: ScopeSnapshot<T>) {\n this.snapshot = initial\n }\n\n readonly getSnapshot = (): ScopeSnapshot<T> => this.snapshot\n\n readonly subscribe = (listener: () => void): (() => void) => {\n this.listeners.add(listener)\n if (this.listeners.size === 1) this.onActiveChange?.(true)\n return () => {\n this.listeners.delete(listener)\n if (this.listeners.size === 0) this.onActiveChange?.(false)\n }\n }\n\n set(snapshot: ScopeSnapshot<T>): void {\n this.snapshot = snapshot\n for (const listener of this.listeners) listener()\n }\n}\n\nconst loadingSnapshot = <T>(): ScopeSnapshot<T> => ({\n status: 'loading',\n value: undefined,\n base: undefined,\n user: undefined,\n revision: undefined,\n writable: false,\n mode: 'host',\n})\n\nconst unavailableSnapshot = <T>(): ScopeSnapshot<T> => ({\n status: 'unavailable',\n value: undefined,\n base: undefined,\n user: undefined,\n revision: undefined,\n writable: false,\n mode: 'host',\n})\n\nfunction failureDetail(error: RemoteFailure | undefined): string {\n if (error == null) return 'memory host call failed'\n return `${error.code ?? 'error'}: ${error.message ?? 'unknown failure'}`\n}\n\n/**\n * Owns the mounted namespace plus the snapshot stores. Created synchronously\n * (slots need it immediately) and attached once `$mount` resolves.\n */\nexport class MemoryBridge {\n private remote: MemoryRemote | null = null\n private statusTimer: ReturnType<typeof setInterval> | undefined\n private configTimer: ReturnType<typeof setInterval> | undefined\n private viewTimer: ReturnType<typeof setInterval> | undefined\n\n private readonly configStore = new BridgeStore<Record<string, unknown>>(loadingSnapshot())\n private readonly statusStore = new BridgeStore<MemoryStatusPayload>(loadingSnapshot())\n private readonly viewStore = new BridgeStore<MemoryViewPayload>(loadingSnapshot())\n\n /** Settings page scope: `set`/`unset` persist config overrides on the host. */\n readonly configScope: ScopeView = {\n getSnapshot: () => this.configStore.getSnapshot(),\n subscribe: (listener) => this.configStore.subscribe(listener),\n set: async (field, value) => {\n await this.updateConfig({ [field]: value })\n },\n unset: async (field) => {\n await this.unsetConfig(field)\n },\n }\n\n /** Selector-hook source for the sidebar pill and the status banner. */\n readonly statusSource: { getSnapshot: () => ScopeSnapshot<MemoryStatusPayload>; subscribe: (l: () => void) => () => void } = {\n getSnapshot: () => this.statusStore.getSnapshot(),\n subscribe: (listener) => this.statusStore.subscribe(listener),\n }\n\n /** Selector-hook source for the viewer page (polls only while mounted). */\n readonly viewSource: { getSnapshot: () => ScopeSnapshot<MemoryViewPayload>; subscribe: (l: () => void) => () => void } = {\n getSnapshot: () => this.viewStore.getSnapshot(),\n subscribe: (listener) => this.viewStore.subscribe(listener),\n }\n\n /** The single action runner every widget uses. */\n readonly commands: CommandRunner = {\n run: (request) => this.runCommand(request),\n }\n\n constructor() {\n this.viewStore.onActiveChange = (active) => {\n if (active) {\n void this.refreshView()\n this.viewTimer = setInterval(() => { void this.refreshView() }, VIEW_POLL_MS)\n } else {\n this.stopTimer(this.viewTimer)\n this.viewTimer = undefined\n }\n }\n }\n\n attach(remote: MemoryRemote): void {\n this.remote = remote\n void this.refreshStatus()\n void this.refreshConfig()\n this.statusTimer = setInterval(() => { void this.refreshStatus() }, STATUS_POLL_MS)\n this.configTimer = setInterval(() => { void this.refreshConfig() }, CONFIG_POLL_MS)\n }\n\n detach(): void {\n this.stopTimer(this.statusTimer)\n this.stopTimer(this.configTimer)\n this.stopTimer(this.viewTimer)\n this.statusTimer = undefined\n this.configTimer = undefined\n this.viewTimer = undefined\n this.remote = null\n }\n\n async updateConfig(patch: Record<string, unknown>): Promise<void> {\n const remote = this.requireRemote()\n const result = await remote.updateConfig(patch)\n if (!result.ok) throw new Error(failureDetail(result.error))\n this.applyConfig(result.value)\n void this.refreshStatus()\n }\n\n async unsetConfig(field: string): Promise<void> {\n const remote = this.requireRemote()\n const result = await remote.unsetConfig(field)\n if (!result.ok) throw new Error(failureDetail(result.error))\n this.applyConfig(result.value)\n }\n\n async runCommand(request: MemoryCommandRequest): Promise<MemoryCommandResult> {\n const remote = this.remote\n if (remote == null) return { ok: false, detail: 'memory host unavailable' }\n let result: RemoteResult<MemoryCommandResult>\n try {\n result = await remote.runCommand(request)\n } catch (error) {\n return { ok: false, detail: String(error) }\n }\n if (!result.ok) return { ok: false, detail: failureDetail(result.error) }\n if (result.value.view !== undefined) this.applyView(result.value.view)\n else void this.refreshView()\n void this.refreshStatus()\n void this.refreshConfig()\n return result.value\n }\n\n async refreshView(): Promise<void> {\n const remote = this.remote\n if (remote == null) return\n try {\n const result = await remote.getView()\n if (!result.ok) throw new Error(failureDetail(result.error))\n this.applyView(result.value)\n } catch {\n this.viewStore.set(unavailableSnapshot())\n }\n }\n\n private applyView(view: MemoryViewPayload): void {\n this.viewStore.set({\n status: 'ready',\n value: view,\n base: undefined,\n user: undefined,\n revision: view.updatedAt,\n writable: false,\n mode: 'host',\n })\n }\n\n private applyConfig(config: MemoryConfigPayload): void {\n this.configStore.set({\n status: 'ready',\n value: config.value,\n base: config.base,\n user: config.user,\n revision: config.revision,\n writable: true,\n mode: 'host',\n })\n }\n\n private async refreshConfig(): Promise<void> {\n const remote = this.remote\n if (remote == null) return\n try {\n const result = await remote.getConfig()\n if (!result.ok) throw new Error(failureDetail(result.error))\n this.applyConfig(result.value)\n } catch {\n this.configStore.set(unavailableSnapshot())\n }\n }\n\n private async refreshStatus(): Promise<void> {\n const remote = this.remote\n if (remote == null) return\n try {\n const result = await remote.getStatus()\n if (!result.ok) throw new Error(failureDetail(result.error))\n const status = result.value\n this.statusStore.set({\n status: 'ready',\n value: status,\n base: undefined,\n user: undefined,\n revision: status.updatedAt,\n writable: false,\n mode: 'host',\n })\n } catch {\n this.statusStore.set(unavailableSnapshot())\n }\n }\n\n private requireRemote(): MemoryRemote {\n if (this.remote == null) throw new Error('memory host unavailable')\n return this.remote\n }\n\n private stopTimer(timer: ReturnType<typeof setInterval> | undefined): void {\n if (timer !== undefined) clearInterval(timer)\n }\n}\n\n/**\n * Mount the contribution and hand the resulting namespace to the bridge.\n * Returns the disposer the caller runs from its effect cleanup.\n */\nexport async function mountMemoryBridge(bridge: MemoryBridge, ctx: ClientContext): Promise<() => Promise<void>> {\n const remote = ctx.remote\n if (remote == null || typeof remote.$mount !== 'function') {\n throw new Error('the remote service is not available in this composition')\n }\n let dispose: () => Promise<void>\n try {\n dispose = await remote.$mount(CONTRIBUTION)\n } catch (error) {\n throw new Error(`mounting the memory remote contribution failed: ${String(error)}`)\n }\n const namespace = ctx.get('remote.memory') as MemoryRemote | undefined\n if (namespace == null) {\n await dispose()\n throw new Error('remote.memory is missing after mounting the contribution')\n }\n bridge.attach(namespace)\n return async () => {\n bridge.detach()\n await dispose()\n }\n}\n","/**\n * The memory entry in `sidebar.footer.action` — the fixed home of the status\n * surface, in the same seat as DSH's own Cordis panel. The trigger is a footer\n * row (a 36px circle in the collapsed rail) and the panel opens above it:\n * `position: fixed` with an offset measured from the trigger, because the\n * sidebar clips overflow and a 320px surface would otherwise be cut off.\n *\n * Reads status and config through the `memory` remote namespace (polls\n * `getStatus`), and acts through `runCommand`. Every action lives in the\n * panel.\n */\n\nimport { createElement, useEffect, useLayoutEffect, useRef, useState } from 'react'\nimport type { CommandRunner, ScopeView } from './types.ts'\n\ntype SelectorHook = (selector: (value: unknown) => unknown) => unknown\n\nlet styleInjected = false\n\n/** Inject the widget stylesheet once per document (factory-execution side effect). */\nfunction ensureStyles(): void {\n if (styleInjected || typeof document === 'undefined') return\n if (document.querySelector('style[data-dsh-memory-float]') != null) {\n styleInjected = true\n return\n }\n const tag = document.createElement('style')\n tag.dataset.dshMemoryFloat = 'true'\n tag.textContent = [\n '@keyframes dsh-memory-pulse { 0% { opacity: 0.35; transform: scale(0.8); } 50% { opacity: 1; transform: scale(1.08); } 100% { opacity: 0.35; transform: scale(0.8); } }',\n '@keyframes dsh-memory-pop-in { from { opacity: 0; transform: translateY(6px) scale(0.96); } to { opacity: 1; transform: none; } }',\n // Trigger: the Settings trigger row's own geometry (42px row, 36px rail\n // cell, 8px icon inset) so the two foot rows line up.\n '.dshm-layer { position: relative; flex: 1 1 auto; display: flex; align-items: center; min-width: 0; width: calc(100% + 4px); height: 42px; margin: 4px -2px; }',\n '.dshm-layer[data-rail=\"true\"] { flex: none; width: 36px; height: 36px; margin: 8px 0 0; }',\n '.dshm-foot { flex: 1; display: flex; align-items: center; gap: 8px; min-width: 0; height: 42px; margin: 0; padding: 0 10px 0 8px; box-sizing: border-box; border: none; border-radius: 12px; background: transparent; color: var(--dsw-alias-label-primary, #eee); font-family: inherit; font-size: 14px; line-height: 22px; cursor: pointer; overflow: hidden; transition: background 150ms ease; }',\n '.dshm-foot:hover, .dshm-foot[data-open=\"true\"] { background: var(--dsw-alias-interactive-bg-hover, rgba(128,128,128,0.12)); }',\n '.dshm-layer[data-rail=\"true\"] .dshm-foot { flex: none; justify-content: center; gap: 0; width: 36px; height: 36px; padding: 0; border-radius: 50%; }',\n '.dshm-icon { position: relative; display: inline-flex; flex: none; align-items: center; justify-content: center; }',\n '.dshm-dot { position: absolute; right: -1px; bottom: -1px; width: 7px; height: 7px; border-radius: 50%; background: var(--dsw-alias-brand-primary, #4b7bec); animation: dsh-memory-pulse 1.4s ease-in-out infinite; }',\n '.dshm-foot-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }',\n '.dshm-foot-state { flex: none; margin-left: auto; font-size: 12px; line-height: 16px; color: var(--dsw-alias-label-tertiary, rgba(128,128,128,0.9)); }',\n '.dshm-foot-state[data-active=\"true\"] { color: var(--dsw-alias-brand-primary, #4b7bec); }',\n '.dshm-foot-state[data-paused=\"true\"] { color: var(--dsw-alias-state-error-primary, #e05561); }',\n '.dshm-panel { animation: dsh-memory-pop-in 160ms ease; }',\n '.dshm-btn { transition: border-color 150ms ease, background 150ms ease, opacity 150ms ease, transform 100ms ease; }',\n '.dshm-btn:hover:not(:disabled) { border-color: var(--dsw-alias-brand-primary, #4b7bec); opacity: 1; background: rgba(75, 123, 236, 0.12); }',\n '.dshm-btn:active:not(:disabled) { transform: translateY(1px); }',\n '.dshm-preview::-webkit-scrollbar { width: 6px; }',\n '.dshm-preview::-webkit-scrollbar-thumb { background: rgba(128,128,128,0.35); border-radius: 3px; }',\n // Switch: DSH's own Switch primitive spec (36x20 track, 16px thumb), keyed\n // off aria-checked so the paint cannot disagree with assistive state.\n '.dshm-switch { box-sizing: border-box; position: relative; flex: 0 0 auto; width: 36px; height: 20px; padding: 2px; border: 0; border-radius: 10px; corner-shape: round; background: var(--dsw-alias-border-l3, rgba(128,128,128,0.45)); cursor: pointer; }',\n '.dshm-switch[aria-checked=\"true\"] { background: var(--dsw-alias-brand-primary, #4b7bec); }',\n '.dshm-switch:disabled { cursor: default; opacity: 0.5; }',\n '.dshm-switch:focus-visible { outline: 2px solid var(--dsw-alias-brand-primary, #4b7bec); outline-offset: 2px; }',\n '.dshm-thumb { display: block; width: 16px; height: 16px; border-radius: 50%; corner-shape: round; background: var(--dsw-alias-label-primary-foreground, #fff); transition: transform 120ms ease; }',\n '.dshm-switch[aria-checked=\"true\"] .dshm-thumb { transform: translateX(16px); }',\n '.dshm-toggle-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 3px 0; }',\n ].join('\\n')\n document.head.appendChild(tag)\n styleInjected = true\n}\n\nexport interface FloatStatus {\n phase: string\n detail: string\n summaryPreview: string\n updatedAt: number\n}\n\ninterface ActionProps {\n t: (key: string) => string\n /** Owner prop of `sidebar.footer.action`: false while the sidebar is a rail. */\n wide?: boolean\n useMemoryStatus?: SelectorHook\n commands?: CommandRunner\n settings?: ScopeView\n /** Opens the standalone memory viewer page (right sidebar tab). */\n openViewer?: () => void\n}\n\n/** The footer action component (slot component props: t + hooks + scopes). */\nexport function MemoryFooterAction(props: ActionProps) {\n try {\n return renderAction(props)\n } catch {\n return null\n }\n}\n\nfunction renderAction(props: ActionProps) {\n if (props.useMemoryStatus == null) return null\n ensureStyles()\n const t: (key: string) => string = props.t\n const wide = props.wide !== false\n\n const statusSnapshot = props.useMemoryStatus((value: unknown) => value) as\n | { status: string; value?: Partial<FloatStatus> }\n | undefined\n const status = statusSnapshot?.status === 'ready' ? statusSnapshot.value ?? {} : {}\n const phase = status.phase ?? 'idle'\n const active = phase === 'phase1' || phase === 'phase2'\n const phaseLabel = active\n ? (phase === 'phase1' ? t('phase1') : t('phase2'))\n : t('statusIdle')\n\n // Settings mirror for the quick toggles.\n const settingsSnapshot = useScopeSnapshot(props.settings)\n const settings = (settingsSnapshot?.value ?? {}) as Record<string, unknown>\n const settingsWritable = settingsSnapshot?.writable === true\n const scheduled = settings.generateMemories !== false\n\n const [open, setOpen] = useState(false)\n const rootRef = useRef<HTMLElement | null>(null)\n const [anchor, setAnchor] = useState<{ left: number; bottom: number } | undefined>(undefined)\n\n // The sidebar clips overflow, so the panel is position: fixed and hugs the\n // trigger through a measured offset instead of document flow.\n useLayoutEffect(() => {\n if (!open) return undefined\n const place = (): void => {\n const rect = rootRef.current?.getBoundingClientRect()\n if (rect != null) setAnchor({ left: rect.left, bottom: window.innerHeight - rect.top + 8 })\n }\n place()\n window.addEventListener('resize', place)\n return () => { window.removeEventListener('resize', place) }\n }, [open, wide])\n\n useEffect(() => {\n if (!open) return undefined\n const onPointerDown = (event: Event): void => {\n const root = rootRef.current\n const target = event.target\n if (root != null && target instanceof Node && root.contains(target)) return\n setOpen(false)\n }\n const onKeyDown = (event: KeyboardEvent): void => {\n if (event.key === 'Escape') setOpen(false)\n }\n document.addEventListener('pointerdown', onPointerDown, true)\n document.addEventListener('keydown', onKeyDown)\n return () => {\n document.removeEventListener('pointerdown', onPointerDown, true)\n document.removeEventListener('keydown', onKeyDown)\n }\n }, [open])\n\n const sendCommand = (action: string): void => {\n const commands = props.commands\n if (commands == null) return\n void commands.run({ action })\n }\n\n const toggleSetting = (field: string, value: unknown): void => {\n void props.settings?.set(field, value)\n }\n\n // The glyph carries the activity dot so the rail (icon only) still shows it.\n const icon = (size: number): unknown => createElement('span', { className: 'dshm-icon' },\n createElement(MemoryIcon, { size }),\n active ? createElement('span', { className: 'dshm-dot' }) : null,\n )\n\n // ── trigger ──────────────────────────────────────────────────────────────\n const trigger = createElement('button', {\n type: 'button',\n className: 'dshm-foot',\n 'data-open': open ? 'true' : 'false',\n 'aria-expanded': open,\n 'aria-label': t('nav'),\n title: `${t('nav')} — ${scheduled ? phaseLabel : t('pausedBadge')}`,\n onClick: () => setOpen((value) => !value),\n },\n icon(wide ? 16 : 18),\n wide ? createElement('span', { className: 'dshm-foot-label' }, t('nav')) : null,\n wide\n ? createElement('span', {\n className: 'dshm-foot-state',\n 'data-active': active ? 'true' : undefined,\n 'data-paused': scheduled ? undefined : 'true',\n }, scheduled ? phaseLabel : t('pausedBadge'))\n : null,\n )\n\n const layer = (...children: unknown[]): unknown => createElement('div', {\n ref: rootRef as never,\n className: 'dshm-layer',\n 'data-rail': wide ? undefined : 'true',\n }, ...children)\n\n if (!open) return layer(trigger)\n\n // ── panel: fixed above the trigger ───────────────────────────────────────\n const panelStyle: Record<string, unknown> = {\n position: 'fixed',\n zIndex: 40,\n width: 320,\n maxWidth: 'calc(100vw - 24px)',\n left: anchor?.left ?? 8,\n bottom: anchor?.bottom ?? 56,\n visibility: anchor == null ? 'hidden' : undefined,\n borderRadius: 14,\n overflow: 'hidden',\n background: 'var(--dsw-alias-bg-layer-3, rgba(20, 22, 28, 0.92))',\n backdropFilter: 'blur(14px)',\n WebkitBackdropFilter: 'blur(14px)',\n color: 'var(--dsw-alias-label-primary, #eee)',\n border: `1px solid ${BORDER}`,\n boxShadow: '0 10px 32px rgba(0,0,0,0.42)',\n }\n\n const preview = status.summaryPreview ?? ''\n\n return layer(\n trigger,\n createElement('div', { className: 'dshm-panel', style: panelStyle },\n createElement('div', {\n style: {\n display: 'flex', alignItems: 'center', gap: 8, padding: '10px 12px',\n background: 'var(--dsw-alias-fill-tertiary, rgba(128,128,128,0.08))',\n borderBottom: `1px solid ${BORDER}`,\n },\n },\n icon(16),\n createElement('span', { style: { fontSize: 12.5, fontWeight: 600, flex: 1 } }, t('title')),\n createElement('button', {\n type: 'button',\n className: 'dshm-btn',\n title: t('minimize'),\n onClick: () => setOpen(false),\n style: {\n fontSize: 11, padding: '1px 8px', borderRadius: 6, cursor: 'pointer',\n border: `1px solid ${BORDER}`, background: 'transparent', color: 'inherit', opacity: 0.75,\n },\n }, t('minimize')),\n ),\n createElement('div', { style: { padding: '10px 12px' } },\n createElement('div', { style: { display: 'flex', alignItems: 'center', gap: 8 } },\n createElement('span', { style: { fontSize: 12, fontWeight: 600 } }, phaseLabel),\n createElement('span', { style: { fontSize: 11, opacity: 0.45, marginLeft: 'auto' } },\n status.updatedAt ? new Date(status.updatedAt).toLocaleTimeString() : ''),\n ),\n status.detail !== ''\n ? createElement('div', { style: { fontSize: 11.5, opacity: 0.7, marginTop: 4 } }, status.detail)\n : null,\n createElement('div', {\n style: {\n display: 'flex', flexDirection: 'column', gap: 5, marginTop: 10,\n paddingTop: 10, borderTop: `1px solid ${BORDER}`,\n },\n },\n ...([\n ['enabled', 'field_enabled'],\n ['generateMemories', 'field_generateMemories'],\n ['useMemories', 'field_useMemories'],\n ] as const).map(([field, labelKey]) => createElement('div', {\n key: field,\n className: 'dshm-toggle-row',\n },\n createElement('span', { style: { fontSize: 12, opacity: 0.85 } }, t(labelKey)),\n createElement('button', {\n type: 'button',\n role: 'switch',\n 'aria-checked': settings[field] === true,\n 'aria-label': t(labelKey),\n className: 'dshm-switch',\n disabled: !settingsWritable,\n onClick: () => toggleSetting(field, settings[field] !== true),\n }, createElement('span', { className: 'dshm-thumb' })),\n )),\n ),\n preview !== ''\n ? createElement('div', {\n className: 'dshm-preview',\n style: {\n marginTop: 10, padding: '8px 10px', borderRadius: 8,\n background: 'var(--dsw-alias-fill-tertiary, rgba(128,128,128,0.08))',\n border: `1px solid ${BORDER}`,\n fontSize: 11, lineHeight: 1.5, opacity: 0.85,\n maxHeight: 130, overflowY: 'auto',\n whiteSpace: 'pre-wrap', wordBreak: 'break-word',\n },\n }, preview)\n : null,\n ),\n createElement('div', {\n style: {\n display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 6,\n padding: '10px 12px 12px', borderTop: `1px solid ${BORDER}`,\n },\n },\n createElement('div', { style: { gridColumn: '1 / -1' } },\n actionButton(t('menuRunNow'), () => sendCommand('run-cycle'), true, true),\n ),\n props.openViewer != null\n ? actionButton(t('menuViewMemory'), () => props.openViewer?.(), false, true)\n : null,\n actionButton(scheduled ? t('menuPause') : t('menuResume'), () => sendCommand('toggle-schedule'), false, true),\n createElement('div', { style: { gridColumn: '1 / -1' } },\n actionButton(t('menuOpenFolder'), () => sendCommand('open-folder'), false, true),\n ),\n ),\n ),\n )\n}\n\nfunction actionButton(label: string, onClick: () => void, primary = false, stretch = false) {\n return createElement('button', {\n type: 'button',\n onClick,\n className: 'dshm-btn',\n style: {\n width: stretch ? '100%' : undefined,\n ...(primary\n ? {\n fontSize: 11.5, padding: '5px 10px', borderRadius: 7, cursor: 'pointer', fontWeight: 600,\n border: '1px solid transparent',\n background: 'var(--dsw-alias-button-info-fill, #4d6bfe)',\n color: 'var(--dsw-alias-label-primary-inverted, #fff)',\n }\n : {\n fontSize: 11.5, padding: '5px 10px', borderRadius: 7, cursor: 'pointer',\n border: `1px solid ${BORDER}`, background: 'transparent', color: 'inherit', opacity: 0.85,\n }),\n },\n }, label)\n}\n\n/** The memory glyph, inlined from ui-primitives' IconDatabaseOutline16: the\n * browser bundle externalizes react only, so host icons cannot be imported. */\nfunction MemoryIcon({ size }: { size: number }) {\n return createElement('svg', {\n width: size, height: size, viewBox: '0 0 16 16', fill: 'none',\n xmlns: 'http://www.w3.org/2000/svg', 'aria-hidden': 'true', focusable: 'false',\n },\n createElement('ellipse', { cx: 8, cy: 3.6, rx: 5.75, ry: 2.4, stroke: 'currentColor', strokeWidth: 1.25 }),\n createElement('path', { d: 'M2.25 3.6V12.3A5.75 2.4 0 0 0 13.75 12.3V3.6', stroke: 'currentColor', strokeWidth: 1.25 }),\n createElement('path', { d: 'M2.25 7.95A5.75 2.4 0 0 0 13.75 7.95', stroke: 'currentColor', strokeWidth: 1.25 }),\n )\n}\n\nfunction useScopeSnapshot(scope: ScopeView | undefined): { status: string; value?: unknown; writable?: boolean } | undefined {\n const [snapshot, setSnapshot] = useState<{ status: string; value?: unknown; writable?: boolean } | undefined>(\n () => scope?.getSnapshot(),\n )\n useEffect(() => {\n if (scope == null) return undefined\n setSnapshot(scope.getSnapshot())\n return scope.subscribe(() => {\n setSnapshot(scope.getSnapshot())\n })\n }, [scope])\n return snapshot\n}\n\nconst BORDER = 'var(--dsw-alias-border-l2, rgba(255,255,255,0.14))'\n","/**\n * Hides the <dsh-mem-citation> block from the rendered chat. The host-side\n * citation loop consumes it from the session log; this stripper keeps the raw\n * XML out of the visible transcript.\n *\n * Implementation: a MutationObserver watches for the marker; when found, the\n * text is truncated at the marker up to (and including) the end tag. React\n * may restore the text on re-render — the observer just strips it again.\n */\n\nconst MARKER_OPEN = '<dsh-mem-citation>'\nconst MARKER_CLOSE = '</dsh-mem-citation>'\n\n/** Strip the citation block inside one element. Returns true when it cut. */\nfunction stripWithin(root: Element): boolean {\n const full = root.textContent ?? ''\n const start = full.indexOf(MARKER_OPEN)\n if (start < 0) return false\n const endIndex = full.indexOf(MARKER_CLOSE, start)\n const cutEnd = endIndex < 0 ? full.length : endIndex + MARKER_CLOSE.length\n\n // Remove the contiguous [start, cutEnd) range from the concatenated text,\n // tracking how earlier cuts shift the range left.\n let rangeStart = start\n let rangeEnd = cutEnd\n let cut = false\n const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT)\n let offset = 0\n let node = walker.nextNode() as Text | null\n while (node != null) {\n const length = node.data.length\n const nodeEnd = offset + length\n if (nodeEnd > rangeStart && offset < rangeEnd) {\n const localStart = Math.max(0, rangeStart - offset)\n const localEnd = Math.min(length, rangeEnd - offset)\n node.data = node.data.slice(0, localStart) + node.data.slice(localEnd)\n rangeEnd -= localEnd - localStart\n cut = true\n }\n offset += node.data.length\n if (offset >= rangeEnd && cut) break\n node = walker.nextNode() as Text | null\n }\n return cut\n}\n\nfunction sweep(root: ParentNode): void {\n const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT)\n let node = walker.nextNode() as Text | null\n while (node != null) {\n const next = walker.nextNode() as Text | null\n if (node.data.includes(MARKER_OPEN)) {\n // The block may span sibling elements; climb a few levels to cover it.\n let scope: Element | null = node.parentElement\n for (let depth = 0; depth < 4 && scope != null; depth += 1) {\n if (stripWithin(scope)) break\n scope = scope.parentElement\n }\n }\n node = next\n }\n}\n\n/** Install the stripper; returns a disposer. No-ops outside a document. */\nexport function installCitationStripper(): () => void {\n if (typeof document === 'undefined') return () => {}\n let pending = false\n const schedule = (): void => {\n if (pending) return\n pending = true\n // Batch bursts of stream mutations into one sweep per frame.\n requestAnimationFrame(() => {\n pending = false\n try {\n sweep(document.body)\n } catch {\n // Best effort: a strip failure must never break the chat.\n }\n })\n }\n const observer = new MutationObserver((mutations) => {\n for (const mutation of mutations) {\n const target = mutation.target\n if (\n (target.nodeType === Node.TEXT_NODE && (target as Text).data.includes(MARKER_OPEN))\n || (target instanceof Element && (target.textContent ?? '').includes(MARKER_OPEN))\n ) {\n schedule()\n return\n }\n }\n })\n observer.observe(document.body, { childList: true, subtree: true, characterData: true })\n sweep(document.body)\n return () => observer.disconnect()\n}\n","/**\n * The standalone memory viewer: a right-sidebar page tab (same public path as\n * ui-sidebar-files) with three views — overview dashboard (stats, most-cited,\n * and the searchable records table), summary (original / translated), and the\n * MEMORY.md registry.\n *\n * Data arrives through the `memory` remote namespace: a registration's\n * `inject.hooks` compartment is synthesized by the slot framework into\n * `use<Name>` selector hooks (the same face the float uses for\n * `useMemoryStatus`). The large texts travel gzip+base64 in `blobs` and are\n * decoded with DecompressionStream. Actions go back through\n * `remote.memory.runCommand`.\n */\n\nimport { createElement, useEffect, useState } from 'react'\nimport type { CommandRunner } from './types.ts'\n\nexport const MEMORY_VIEWER_KIND = 'dsh-memory'\nexport const MEMORY_VIEWER_ID = 'dsh-remember/viewer'\n\ntype ReactNode = ReturnType<typeof createElement> | string | null\ntype SelectorHook = (selector: (value: unknown) => unknown) => unknown\n\ninterface RecordStat {\n sessionId: string\n workspacePath: string\n rolloutSlug: string\n sourceUpdatedAt: number\n generatedAt: number\n usageCount: number\n lastUsage: number | null\n selectedForPhase2: boolean\n rawLength: number\n summaryLength: number\n}\n\n/** Published namespace section (texts compressed). */\ninterface ViewState {\n blobs: string\n records: string\n translatedStale: boolean\n translating: boolean\n updatedAt: number\n}\n\ninterface Texts {\n summary: string\n index: string\n translatedSummary: string\n translatedIndex: string\n failed: boolean\n}\n\ninterface StatusState {\n phase?: string\n detail?: string\n updatedAt?: number\n}\n\ninterface ViewerProps {\n t: (key: string) => string\n useMemoryView?: SelectorHook\n useMemoryStatus?: SelectorHook\n commands?: CommandRunner\n}\n\nconst EMPTY_TEXTS: Texts = { summary: '', index: '', translatedSummary: '', translatedIndex: '', failed: false }\n\nlet styleInjected = false\n\nfunction ensureViewerStyles(): void {\n if (styleInjected || typeof document === 'undefined') return\n if (document.querySelector('style[data-dsh-memory-viewer]') != null) {\n styleInjected = true\n return\n }\n const tag = document.createElement('style')\n tag.dataset.dshMemoryViewer = 'true'\n tag.textContent = [\n '.dshmv-root { display: flex; flex-direction: column; height: 100%; min-height: 0; box-sizing: border-box; padding: 10px 14px 14px; color: var(--dsw-alias-label-primary, #1f2329); font-size: 13px; }',\n '.dshmv-tabs { display: flex; gap: 2px; flex: 0 0 auto; margin-bottom: 10px; border-bottom: 0.5px solid var(--dsw-alias-border-l2, rgba(0,0,0,0.1)); }',\n '.dshmv-tab { padding: 6px 12px; font-size: 12.5px; cursor: pointer; border: none; background: none; color: inherit; opacity: 0.55; border-bottom: 2px solid transparent; transition: opacity 140ms ease, border-color 140ms ease; }',\n '.dshmv-tab:hover { opacity: 0.85; }',\n '.dshmv-tab[data-active=\"true\"] { opacity: 1; border-bottom-color: var(--dsw-alias-brand-primary, #4d6bfe); font-weight: 600; }',\n '.dshmv-toolbar { display: flex; align-items: center; gap: 10px; flex: 0 0 auto; margin-bottom: 12px; flex-wrap: wrap; }',\n '.dshmv-status { margin-left: auto; font-size: 11px; color: var(--dsw-alias-label-tertiary, rgba(0,0,0,0.45)); }',\n '.dshmv-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; }',\n '.dshmv-body[data-fill=\"true\"] { display: flex; flex-direction: column; overflow: hidden; }',\n '.dshmv-body::-webkit-scrollbar { width: 8px; }',\n '.dshmv-body::-webkit-scrollbar-thumb { background: var(--dsw-alias-scrollbar-bg-l2, rgba(0,0,0,0.2)); border-radius: 4px; }',\n '.dshmv-switch-row { display: inline-flex; align-items: center; gap: 8px; font-size: 12px; color: inherit; padding: 3px 8px; border-radius: 8px; border: 0.5px solid transparent; background: none; cursor: pointer; transition: background 150ms ease, opacity 150ms ease; }',\n '.dshmv-switch-row:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover, rgba(0,0,0,0.05)); }',\n '.dshmv-switch-row:disabled { opacity: 0.45; cursor: default; }',\n // Switch: DSH's Switch primitive spec (36x20 track, 16px thumb), keyed off\n // aria-checked so the paint cannot disagree with assistive state.\n '.dshmv-switch { box-sizing: border-box; position: relative; display: inline-block; flex: 0 0 auto; width: 36px; height: 20px; padding: 2px; border: 0; border-radius: 10px; corner-shape: round; background: var(--dsw-alias-border-l3, rgba(0,0,0,0.2)); transition: background 160ms ease; }',\n '.dshmv-switch[aria-checked=\"true\"] { background: var(--dsw-alias-brand-primary, #4d6bfe); }',\n '.dshmv-thumb { display: block; width: 16px; height: 16px; border-radius: 50%; corner-shape: round; background: var(--dsw-alias-label-primary-foreground, #fff); transition: transform 120ms ease; }',\n '.dshmv-switch[aria-checked=\"true\"] .dshmv-thumb { transform: translateX(16px); }',\n '.dshmv-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(118px, 1fr)); gap: 10px; margin-bottom: 14px; }',\n '.dshmv-card { padding: 10px 12px; border-radius: 10px; border: 0.5px solid var(--dsw-alias-border-l2, rgba(0,0,0,0.1)); background: var(--dsw-alias-fill-tertiary, rgba(0,0,0,0.04)); }',\n '.dshmv-card-num { font-size: 20px; font-weight: 700; font-variant-numeric: tabular-nums; }',\n '.dshmv-card-label { font-size: 11px; color: var(--dsw-alias-label-tertiary, rgba(0,0,0,0.45)); margin-top: 2px; }',\n '.dshmv-md { white-space: pre-wrap; word-break: break-word; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 12px; line-height: 1.6; padding: 12px; border-radius: 10px; border: 0.5px solid var(--dsw-alias-border-l2, rgba(0,0,0,0.1)); background: var(--dsw-alias-fill-tertiary, rgba(0,0,0,0.04)); }',\n '.dshmv-md-fill { flex: 1 1 auto; min-height: 0; overflow: auto; }',\n '.dshmv-scroll-fill { flex: 1 1 auto; min-height: 0; overflow: auto; }',\n '.dshmv-fill { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }',\n '.dshmv-btn { font-size: 12px; padding: 4px 12px; border-radius: 7px; cursor: pointer; border: 0.5px solid var(--dsw-alias-border-l3, rgba(0,0,0,0.2)); background: transparent; color: inherit; transition: border-color 150ms ease, background 150ms ease, transform 100ms ease; }',\n '.dshmv-btn:hover:not(:disabled) { border-color: var(--dsw-alias-brand-primary, #4d6bfe); background: var(--dsw-alias-interactive-bg-hover, rgba(0,0,0,0.05)); }',\n '.dshmv-btn:active:not(:disabled) { transform: translateY(1px); }',\n '.dshmv-btn:disabled { opacity: 0.4; cursor: default; }',\n '.dshmv-btn-primary { border-color: transparent; background: var(--dsw-alias-button-info-fill, #4d6bfe); color: var(--dsw-alias-label-primary-inverted, #fff); font-weight: 600; }',\n '.dshmv-btn-primary:hover:not(:disabled) { border-color: transparent; background: var(--dsw-alias-button-info-hover, #3f5ae0); }',\n '.dshmv-btn-danger { border-color: transparent; background: var(--dsw-alias-state-error-primary, #d54941); color: var(--dsw-alias-label-primary-inverted, #fff); font-weight: 600; }',\n '.dshmv-btn-danger:hover:not(:disabled) { border-color: transparent; filter: brightness(1.08); }',\n '.dshmv-confirm { display: inline-flex; align-items: center; gap: 6px; padding: 2px 6px 2px 10px; border-radius: 8px; background: rgba(213,73,65,0.12); }',\n '.dshmv-confirm-text { font-size: 11.5px; color: var(--dsw-alias-state-error-primary, #d54941); }',\n '.dshmv-badge { font-size: 10.5px; padding: 1px 8px; border-radius: 999px; }',\n '.dshmv-badge-stale { background: rgba(224,172,68,0.16); color: var(--dsw-alias-state-warn-primary, #b7791f); }',\n '.dshmv-badge-ok { background: rgba(84,196,138,0.16); color: var(--dsw-alias-state-success-primary, #2f9e63); }',\n '.dshmv-search { width: 100%; box-sizing: border-box; font-size: 12px; padding: 6px 10px; border-radius: 8px; border: 0.5px solid var(--dsw-alias-border-l3, rgba(0,0,0,0.18)); background: var(--dsw-alias-bg-layer-1, transparent); color: inherit; margin-bottom: 10px; outline: none; }',\n '.dshmv-search:focus { border-color: var(--dsw-alias-brand-primary, #4d6bfe); }',\n '.dshmv-table { width: 100%; border-collapse: collapse; font-size: 12px; }',\n '.dshmv-table th { text-align: left; font-weight: 600; font-size: 11px; color: var(--dsw-alias-label-tertiary, rgba(0,0,0,0.45)); padding: 6px 8px; border-bottom: 0.5px solid var(--dsw-alias-border-l2, rgba(0,0,0,0.1)); }',\n '.dshmv-table td { padding: 6px 8px; border-bottom: 0.5px solid var(--dsw-alias-border-l1, rgba(0,0,0,0.06)); vertical-align: top; }',\n '.dshmv-table tr:hover td { background: var(--dsw-alias-interactive-bg-hover, rgba(0,0,0,0.04)); }',\n '.dshmv-usage { display: flex; align-items: center; gap: 6px; }',\n '.dshmv-usage-bar { height: 5px; border-radius: 3px; background: var(--dsw-alias-brand-primary, #4d6bfe); min-width: 2px; transition: width 200ms ease; }',\n '.dshmv-empty { color: var(--dsw-alias-label-tertiary, rgba(0,0,0,0.45)); padding: 24px 0; text-align: center; font-size: 12px; }',\n '.dshmv-mono { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 11px; color: var(--dsw-alias-label-tertiary, rgba(0,0,0,0.45)); }',\n '.dshmv-section { margin: 2px 0 8px; font-size: 12px; font-weight: 600; color: var(--dsw-alias-label-secondary, rgba(0,0,0,0.65)); }',\n '.dshmv-toprow { display: flex; align-items: center; gap: 10px; padding: 7px 10px; border-radius: 8px; border: 0.5px solid var(--dsw-alias-border-l2, rgba(0,0,0,0.1)); background: var(--dsw-alias-fill-tertiary, rgba(0,0,0,0.04)); margin-bottom: 6px; }',\n '.dshmv-toprow-name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; font-size: 12px; }',\n '.dshmv-toprow-meta { flex: 0 0 auto; font-size: 11px; color: var(--dsw-alias-label-tertiary, rgba(0,0,0,0.45)); font-variant-numeric: tabular-nums; }',\n ].join('\\n')\n document.head.appendChild(tag)\n styleInjected = true\n}\n\n/** Read one namespace mirror through its selector hook (framework-synthesized). */\nfunction useMirror<T>(hook: SelectorHook | undefined): Partial<T> {\n const snapshot = hook?.((value: unknown) => value) as { status?: string; value?: Partial<T> } | undefined\n return snapshot?.status === 'ready' ? snapshot.value ?? {} : {}\n}\n\n/** Decode the gzip+base64 texts; DecompressionStream is the only browser dependency. */\nfunction useBlobs(encoded: string | undefined): Texts {\n const [texts, setTexts] = useState<Texts>(EMPTY_TEXTS)\n useEffect(() => {\n if (encoded == null || encoded === '') {\n setTexts(EMPTY_TEXTS)\n return undefined\n }\n let cancelled = false\n void decodeBlobs(encoded)\n .then((next) => { if (!cancelled) setTexts(next) })\n .catch(() => { if (!cancelled) setTexts({ ...EMPTY_TEXTS, failed: true }) })\n return () => { cancelled = true }\n }, [encoded])\n return texts\n}\n\nasync function decodeBlobs(encoded: string): Promise<Texts> {\n if (typeof DecompressionStream === 'undefined') return { ...EMPTY_TEXTS, failed: true }\n const binary = atob(encoded)\n const bytes = new Uint8Array(binary.length)\n for (let index = 0; index < binary.length; index += 1) bytes[index] = binary.charCodeAt(index)\n const stream = new DecompressionStream('gzip')\n const writer = stream.writable.getWriter()\n void writer.write(bytes)\n void writer.close()\n const parsed = JSON.parse(await new Response(stream.readable).text()) as Partial<Texts>\n return {\n summary: parsed.summary ?? '',\n index: parsed.index ?? '',\n translatedSummary: parsed.translatedSummary ?? '',\n translatedIndex: parsed.translatedIndex ?? '',\n failed: false,\n }\n}\n\ntype TabId = 'overview' | 'summary' | 'index'\n\n/** Viewer body (slot component). */\nexport function MemoryViewerBody(props: ViewerProps) {\n try {\n return renderViewer(props)\n } catch {\n return null\n }\n}\n\nfunction renderViewer(props: ViewerProps) {\n ensureViewerStyles()\n const t = props.t\n const view = useMirror<ViewState>(props.useMemoryView)\n const status = useMirror<StatusState>(props.useMemoryStatus)\n const texts = useBlobs(view.blobs)\n const [tab, setTab] = useState<TabId>('overview')\n const [showTranslated, setShowTranslated] = useState(false)\n const [confirmingRebuild, setConfirmingRebuild] = useState(false)\n\n const records = parseRecords(view.records)\n const hasTranslation = texts.translatedSummary !== ''\n const translating = view.translating === true\n const sendCommand = (action: string, arg = '', force = false): void => {\n const commands = props.commands\n if (commands == null) return\n void commands.run({ action, arg: arg === '' ? undefined : arg, force: force || undefined })\n }\n\n return createElement('div', { className: 'dshmv-root' },\n // tabs first: the action row sits below them, not against the pane header\n createElement('div', { className: 'dshmv-tabs' },\n ...(['overview', 'summary', 'index'] as const).map((id) => createElement('button', {\n key: id,\n type: 'button',\n className: 'dshmv-tab',\n 'data-active': tab === id ? 'true' : 'false',\n onClick: () => setTab(id),\n }, t(`viewer_tab_${id}`))),\n ),\n createElement('div', { className: 'dshmv-toolbar' },\n createElement('button', {\n type: 'button',\n className: 'dshmv-btn',\n onClick: () => sendCommand('refresh-view'),\n }, t('viewer_refresh')),\n // The switch is a pure view toggle; fetching a translation is the\n // separate action button below it.\n createElement('button', {\n type: 'button',\n role: 'switch',\n 'aria-checked': showTranslated && hasTranslation,\n disabled: !hasTranslation || translating,\n className: 'dshmv-switch-row',\n onClick: () => setShowTranslated((value) => !value),\n },\n createElement('span', null, t('viewer_showTranslated')),\n createElement('span', {\n className: 'dshmv-switch',\n 'aria-checked': showTranslated && hasTranslation ? 'true' : 'false',\n }, createElement('span', { className: 'dshmv-thumb' })),\n ),\n createElement('button', {\n type: 'button',\n className: translating ? 'dshmv-btn' : 'dshmv-btn dshmv-btn-primary',\n disabled: translating || texts.summary === '',\n onClick: () => sendCommand('translate-memory', currentLang()),\n }, translating\n ? `${t('viewer_translating')}${progressLabel(status.detail) === '' ? '' : ` ${progressLabel(status.detail)}`}`\n : hasTranslation ? t('viewer_retranslate') : t('viewer_translate')),\n // Two-step confirm: the destructive full rebuild never fires on one click.\n confirmingRebuild\n ? createElement('span', { className: 'dshmv-confirm' },\n createElement('span', { className: 'dshmv-confirm-text' }, t('viewer_rebuildConfirm')),\n createElement('button', {\n type: 'button',\n className: 'dshmv-btn dshmv-btn-danger',\n disabled: translating || texts.summary === '',\n onClick: () => {\n setConfirmingRebuild(false)\n sendCommand('translate-memory', currentLang(), true)\n },\n }, t('viewer_confirm')),\n createElement('button', {\n type: 'button',\n className: 'dshmv-btn',\n onClick: () => setConfirmingRebuild(false),\n }, t('viewer_cancel')),\n )\n : createElement('button', {\n type: 'button',\n className: 'dshmv-btn',\n disabled: translating || texts.summary === '',\n onClick: () => setConfirmingRebuild(true),\n }, t('viewer_rebuild')),\n showTranslated && hasTranslation && view.translatedStale === true\n ? createElement('span', { className: 'dshmv-badge dshmv-badge-stale' }, t('viewer_stale'))\n : null,\n showTranslated && hasTranslation && view.translatedStale !== true\n ? createElement('span', { className: 'dshmv-badge dshmv-badge-ok' }, t('viewer_fresh'))\n : null,\n createElement('span', { className: 'dshmv-status' }, status.detail ?? ''),\n ),\n createElement('div', {\n className: 'dshmv-body',\n // Every tab fills the pane; its content block does the scrolling.\n 'data-fill': 'true',\n },\n tab === 'overview' ? createElement(OverviewView, { t, texts, showTranslated, status, records })\n : tab === 'summary' ? createElement(SummaryView, { t, texts, showTranslated })\n : renderIndex(t, texts, showTranslated),\n ),\n )\n}\n\n/** Overview dashboard: stat cards, status, most-cited, and the records table. */\nfunction OverviewView(props: {\n t: (k: string) => string\n texts: Texts\n showTranslated: boolean\n status: Partial<StatusState>\n records: RecordStat[]\n}) {\n const { t, texts, showTranslated, status, records } = props\n const [query, setQuery] = useState('')\n const totalUsage = records.reduce((sum, record) => sum + record.usageCount, 0)\n const consolidated = records.filter((record) => record.selectedForPhase2).length\n const topCited = records\n .filter((record) => record.usageCount > 0)\n .sort((a, b) => b.usageCount - a.usageCount)\n .slice(0, 5)\n const phase = status.phase ?? 'idle'\n const active = phase === 'phase1' || phase === 'phase2'\n const needle = query.trim().toLowerCase()\n const filtered = needle === ''\n ? records\n : records.filter((record) =>\n record.sessionId.toLowerCase().includes(needle)\n || record.rolloutSlug.toLowerCase().includes(needle)\n || record.workspacePath.toLowerCase().includes(needle))\n const maxUsage = Math.max(1, ...records.map((record) => record.usageCount))\n const card = (num: ReactNode, label: string): ReactNode => createElement('div', { className: 'dshmv-card', key: label },\n createElement('div', { className: 'dshmv-card-num' }, num),\n createElement('div', { className: 'dshmv-card-label' }, label),\n )\n return createElement('div', { className: 'dshmv-scroll-fill' },\n createElement('div', { className: 'dshmv-cards' },\n card(records.length, t('viewer_stat_records')),\n card(consolidated, t('viewer_stat_consolidated')),\n card(totalUsage, t('viewer_stat_citations')),\n card(formatBytes(texts.summary.length), t('viewer_stat_summarySize')),\n card(formatBytes(texts.index.length), t('viewer_stat_indexSize')),\n ),\n createElement('div', { style: { display: 'flex', alignItems: 'center', gap: 8, marginBottom: 10 } },\n createElement('span', {\n className: `dshmv-badge ${active ? 'dshmv-badge-stale' : 'dshmv-badge-ok'}`,\n }, active ? (phase === 'phase1' ? t('phase1') : t('phase2')) : t('statusIdle')),\n status.updatedAt != null && status.updatedAt > 0\n ? createElement('span', { className: 'dshmv-mono' }, new Date(status.updatedAt).toLocaleString())\n : null,\n showTranslated ? createElement('span', { className: 'dshmv-badge dshmv-badge-ok' }, t('viewer_badgeTranslated')) : null,\n ),\n records.length === 0\n ? null\n : createElement('div', { className: 'dshmv-section' }, t('viewer_topCited')),\n ...topCited.map((record) => createElement('div', { className: 'dshmv-toprow', key: record.sessionId },\n createElement('span', { className: 'dshmv-toprow-name' }, record.rolloutSlug || record.sessionId.slice(0, 8)),\n createElement('span', { className: 'dshmv-toprow-meta' },\n `${record.usageCount} · ${formatTime(record.lastUsage ?? record.sourceUpdatedAt)}`),\n )),\n records.length > 0 && topCited.length === 0\n ? createElement('div', { className: 'dshmv-empty' }, t('viewer_noCitations'))\n : null,\n records.length === 0\n ? null\n : createElement('div', { className: 'dshmv-section', style: { marginTop: 14 } }, t('viewer_tab_records')),\n records.length === 0\n ? null\n : createElement('input', {\n className: 'dshmv-search',\n placeholder: t('viewer_search'),\n value: query,\n onChange: (event: { target: { value: string } }) => setQuery(event.target.value),\n }),\n records.length === 0\n ? createElement('div', { className: 'dshmv-empty' }, t('viewer_empty'))\n : createElement('table', { className: 'dshmv-table' },\n createElement('thead', null, createElement('tr', null,\n createElement('th', null, t('viewer_col_session')),\n createElement('th', null, t('viewer_col_usage')),\n createElement('th', null, t('viewer_col_updated')),\n )),\n createElement('tbody', null,\n ...filtered.map((record) => createElement('tr', { key: record.sessionId },\n createElement('td', null,\n createElement('div', { style: { fontWeight: 600 } },\n record.rolloutSlug || record.sessionId.slice(0, 8)),\n createElement('div', { className: 'dshmv-mono' }, record.workspacePath),\n ),\n createElement('td', null,\n createElement('div', { className: 'dshmv-usage' },\n createElement('span', {\n className: 'dshmv-usage-bar',\n style: { width: `${Math.round((record.usageCount / maxUsage) * 48)}px` },\n }),\n createElement('span', null, String(record.usageCount)),\n ),\n record.lastUsage != null\n ? createElement('div', { className: 'dshmv-mono' },\n `${t('viewer_col_lastUsed')}: ${formatTime(record.lastUsage)}`)\n : null,\n ),\n createElement('td', { className: 'dshmv-mono' }, formatTime(record.sourceUpdatedAt)),\n )),\n ),\n ),\n )\n}\n\nfunction SummaryView(props: { t: (k: string) => string; texts: Texts; showTranslated: boolean }) {\n const { t, texts, showTranslated } = props\n const text = showTranslated && texts.translatedSummary !== '' ? texts.translatedSummary : texts.summary\n return text !== ''\n ? createElement('div', { className: 'dshmv-md dshmv-md-fill' }, text)\n : createElement('div', { className: 'dshmv-empty dshmv-fill' }, texts.failed ? t('viewer_decodeFailed') : t('viewer_empty'))\n}\n\nfunction renderIndex(t: (k: string) => string, texts: Texts, showTranslated: boolean): ReactNode {\n const text = showTranslated && texts.translatedIndex !== '' ? texts.translatedIndex : texts.index\n return text !== ''\n ? createElement('div', { className: 'dshmv-md dshmv-md-fill' }, text)\n : createElement('div', { className: 'dshmv-empty dshmv-fill' }, texts.failed ? t('viewer_decodeFailed') : t('viewer_empty'))\n}\n\n/** Title chip for the viewer tab. */\nexport function MemoryViewerTitle(props: { t: (key: string) => string }) {\n return createElement('span', null, props.t('viewer_title'))\n}\n\n/** 'N/M' extracted from the host's `translate: N/M chunks` status line. */\nfunction progressLabel(detail: string | undefined): string {\n return /translate:\\s*(\\d+\\/\\d+)/.exec(detail ?? '')?.[1] ?? ''\n}\n\nfunction parseRecords(raw: string | undefined): RecordStat[] {\n if (raw == null || raw === '') return []\n try {\n const parsed = JSON.parse(raw) as unknown\n return Array.isArray(parsed) ? parsed as RecordStat[] : []\n } catch {\n return []\n }\n}\n\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`\n return `${(bytes / 1024).toFixed(1)} KB`\n}\n\nfunction formatTime(unixSeconds: number): string {\n if (!Number.isFinite(unixSeconds) || unixSeconds <= 0) return '—'\n return new Date(unixSeconds * 1000).toLocaleString()\n}\n\n/** Current UI language tag for the translate command (`zh` vs `en`). */\nfunction currentLang(): string {\n try {\n return (navigator.language || 'zh').toLowerCase().startsWith('zh') ? 'zh' : 'en'\n } catch {\n return 'zh'\n }\n}\n","/**\n * Browser half of dsh-remember: contributes the Settings → Plugins card\n * for the `memory` namespace and the memory entry in the sidebar footer.\n * Registered lazily via slots.inject so composition order never matters.\n */\n\nimport { MemoryCardController, MemorySettingsPage } from './memory-card.ts'\nimport { MemoryBridge, mountMemoryBridge } from './remote.ts'\nimport { MemoryFooterAction } from './sidebar-action.ts'\nimport { installCitationStripper } from './citation-stripper.ts'\nimport { MEMORY_VIEWER_ID, MEMORY_VIEWER_KIND, MemoryViewerBody, MemoryViewerTitle } from './memory-viewer.ts'\nimport type { CatalogModel, ClientContext } from './types.ts'\n\nexport const name = 'dsh-remember'\n\n/** Required browser services (cordis fiber inject). */\nexport const inject = ['slots', 'locale', 'remote']\n\nconst NS = 'dsh-memory'\n\nconst ZH: Record<string, string> = {\n nav: '记忆',\n title: '记忆系统',\n intro: '空闲会话自动提取、整理为可检索的文件型记忆库,并在对话中按需召回。',\n unavailable: '此部署未提供记忆设置(命名空间不可用)。',\n group_general: '通用',\n group_models: '模型',\n group_schedule: '调度与保留',\n group_recall: '召回注入',\n group_transfer: '导入 / 导出',\n group_advanced: '高级',\n field_enabled: '启用记忆系统',\n field_generateMemories: '自动生成记忆',\n field_useMemories: '注入记忆摘要',\n field_workspaceDir: '记忆工作区目录',\n field_dbPath: 'SQLite 数据库路径',\n field_extractModel: '提取模型 (provider/model)',\n field_consolidationModel: '整理模型 (provider/model)',\n field_scanIntervalMinutes: '扫描间隔(分钟)',\n field_minRolloutIdleHours: '会话静置阈值(小时)',\n field_maxSessionAgeDays: '会话最大年龄(天)',\n field_maxUnusedDays: '未用记忆保留(天)',\n field_maxRolloutSummaries: 'rollout 摘要上限',\n field_phase2SuccessCooldownSeconds: '整理成功冷却(秒)',\n field_phase2TimeoutMinutes: '整理超时(分钟)',\n field_phase1RetryBackoffMinutes: '提取重试退避(分钟)',\n field_phase1MaxRetries: '提取重试次数',\n field_phase1MaxPerCycle: '每轮提取上限',\n field_phase1MaxConcurrency: '提取并发数',\n field_consolidatorDenyPatterns: '整理器额外工具黑名单(正则)',\n field_summaryTokenLimit: '摘要注入 token 上限',\n field_extractInputContextRatio: '提取上下文占比',\n field_redactSecrets: '提取时脱敏密钥',\n hint_workspaceDir: '留空使用 ~/.dsh-memory/memories',\n hint_dbPath: '留空使用 ~/.dsh-memory/memories.sqlite',\n hint_extractModel: '留空使用默认模型',\n hint_consolidationModel: '留空使用默认模型',\n hint_extractInputContextRatio: '0.1 – 0.95',\n hint_consolidatorDenyPatterns: '整理器默认只开放 read/write/edit/glob/grep;这里的正则在白名单之上再拒绝',\n overridden: '已覆盖',\n reset: '重置',\n save: '保存',\n discard: '放弃',\n saving: '保存中…',\n failed: '保存失败',\n invalid: '存在无效输入',\n readOnly: '此文档不可写',\n statusIdle: '空闲',\n modelDefault: '跟随默认模型',\n catalogRefresh: '刷新模型目录',\n catalogLoading: '模型目录加载中…',\n catalogError: '模型目录加载失败,可重试或直接填写 provider/model',\n done: '记忆已更新',\n minimize: '最小化',\n menuExpand: '展开',\n pausedBadge: '已暂停',\n menuRunNow: '立即整理一次',\n menuViewMemory: '查看记忆',\n menuPause: '暂停自动调度',\n menuResume: '恢复自动调度',\n menuOpenFolder: '打开记忆文件夹',\n phase1: '记忆提取中',\n phase2: '记忆整理中',\n processing: '记忆处理中',\n transfer_exportLabel: '导出记忆',\n transfer_exportDesc: '保存为单个 bundle 文件,位置在浏览器里选',\n transfer_importLabel: '导入记忆',\n transfer_importDesc: '选择一个 bundle 文件合并进当前记忆库',\n transfer_export: '导出',\n transfer_import: '导入',\n transfer_requested: '已发送,结果见上方状态栏',\n transfer_tooBig: '文件超过 32 MB,请改用 memory_export 工具直接导出到磁盘',\n transfer_readFailed: '文件读取失败',\n viewer_title: '记忆浏览',\n viewer_refresh: '刷新',\n viewer_translate: '翻译记忆',\n viewer_translating: '翻译中…',\n viewer_tab_overview: '概览',\n viewer_tab_summary: '摘要',\n viewer_tab_index: '注册表',\n viewer_tab_records: '记录',\n viewer_stat_records: '记忆记录',\n viewer_stat_consolidated: '已整理',\n viewer_stat_citations: '被引用次数',\n viewer_stat_summarySize: '摘要大小',\n viewer_stat_indexSize: '注册表大小',\n viewer_topCited: '最常引用',\n viewer_noCitations: '还没有引用记录',\n viewer_original: '显示原文',\n viewer_translated: '显示译文',\n viewer_showTranslated: '显示译文',\n viewer_badgeTranslated: '译文',\n viewer_rebuild: '重建译文',\n viewer_rebuildConfirm: '忽略缓存全文重翻?',\n viewer_confirm: '确认',\n viewer_cancel: '取消',\n viewer_retranslate: '重新翻译',\n viewer_stale: '译文已过期',\n viewer_fresh: '译文为最新',\n viewer_empty: '暂无内容',\n viewer_decodeFailed: '记忆内容解码失败(浏览器不支持 DecompressionStream)',\n viewer_search: '搜索会话 / 路径…',\n viewer_col_session: '会话',\n viewer_col_usage: '引用',\n viewer_col_updated: '更新时间',\n viewer_col_lastUsed: '最近引用',\n}\n\nconst EN: Record<string, string> = {\n nav: 'Memory',\n title: 'Memory',\n intro: 'Idle sessions are extracted automatically, consolidated into a searchable file-based memory library, and recalled on demand.',\n unavailable: 'Memory settings are unavailable in this deployment (namespace not served).',\n group_general: 'General',\n group_models: 'Models',\n group_schedule: 'Scheduling & retention',\n group_recall: 'Recall injection',\n group_transfer: 'Import / Export',\n group_advanced: 'Advanced',\n field_enabled: 'Enable memory system',\n field_generateMemories: 'Generate memories automatically',\n field_useMemories: 'Inject memory summary',\n field_workspaceDir: 'Memory workspace directory',\n field_dbPath: 'SQLite database path',\n field_extractModel: 'Extraction model (provider/model)',\n field_consolidationModel: 'Consolidation model (provider/model)',\n field_scanIntervalMinutes: 'Scan interval (minutes)',\n field_minRolloutIdleHours: 'Session idle threshold (hours)',\n field_maxSessionAgeDays: 'Max session age (days)',\n field_maxUnusedDays: 'Unused memory retention (days)',\n field_maxRolloutSummaries: 'Rollout summary cap',\n field_phase2SuccessCooldownSeconds: 'Consolidation cooldown (seconds)',\n field_phase2TimeoutMinutes: 'Consolidation timeout (minutes)',\n field_phase1RetryBackoffMinutes: 'Extraction retry backoff (minutes)',\n field_phase1MaxRetries: 'Extraction retries',\n field_phase1MaxPerCycle: 'Extractions per cycle',\n field_phase1MaxConcurrency: 'Extraction concurrency',\n field_consolidatorDenyPatterns: 'Extra consolidator tool denies (regex)',\n field_summaryTokenLimit: 'Summary injection token cap',\n field_extractInputContextRatio: 'Extraction context ratio',\n field_redactSecrets: 'Redact secrets during extraction',\n hint_workspaceDir: 'Empty = ~/.dsh-memory/memories',\n hint_dbPath: 'Empty = ~/.dsh-memory/memories.sqlite',\n hint_extractModel: 'Empty = deployment default model',\n hint_consolidationModel: 'Empty = deployment default model',\n hint_extractInputContextRatio: '0.1 – 0.95',\n hint_consolidatorDenyPatterns: 'The consolidator only gets read/write/edit/glob/grep; these regexes deny more on top of the whitelist',\n overridden: 'overridden',\n reset: 'reset',\n save: 'Save',\n discard: 'Discard',\n saving: 'Saving…',\n failed: 'Save failed',\n invalid: 'Invalid input',\n readOnly: 'This document is read-only',\n statusIdle: 'Idle',\n modelDefault: 'Follow default model',\n catalogRefresh: 'Refresh models',\n catalogLoading: 'Loading model catalog…',\n catalogError: 'Model catalog failed to load — retry or type provider/model directly',\n done: 'Memory updated',\n minimize: 'Minimize',\n menuExpand: 'Expand',\n pausedBadge: 'Paused',\n menuRunNow: 'Run now',\n menuViewMemory: 'View memories',\n menuPause: 'Pause scheduling',\n menuResume: 'Resume scheduling',\n menuOpenFolder: 'Open memory folder',\n phase1: 'Extracting memories',\n phase2: 'Consolidating memories',\n processing: 'Memory processing',\n transfer_exportLabel: 'Export memory',\n transfer_exportDesc: 'Save as a single bundle file — pick the location in the browser',\n transfer_importLabel: 'Import memory',\n transfer_importDesc: 'Pick a bundle file to merge into the current memory store',\n transfer_export: 'Export',\n transfer_import: 'Import',\n transfer_requested: 'Sent — result appears in the status bar above',\n transfer_tooBig: 'File exceeds 32 MB — use the memory_export tool to write it to disk instead',\n transfer_readFailed: 'Failed to read the file',\n viewer_title: 'Memory',\n viewer_refresh: 'Refresh',\n viewer_translate: 'Translate memory',\n viewer_translating: 'Translating…',\n viewer_tab_overview: 'Overview',\n viewer_tab_summary: 'Summary',\n viewer_tab_index: 'Registry',\n viewer_tab_records: 'Records',\n viewer_stat_records: 'Records',\n viewer_stat_consolidated: 'Consolidated',\n viewer_stat_citations: 'Citations',\n viewer_stat_summarySize: 'Summary size',\n viewer_stat_indexSize: 'Registry size',\n viewer_topCited: 'Most cited',\n viewer_noCitations: 'No citations yet',\n viewer_original: 'Show original',\n viewer_translated: 'Show translation',\n viewer_showTranslated: 'Translation',\n viewer_badgeTranslated: 'Translated',\n viewer_rebuild: 'Rebuild',\n viewer_rebuildConfirm: 'Ignore cache and retranslate everything?',\n viewer_confirm: 'Confirm',\n viewer_cancel: 'Cancel',\n viewer_retranslate: 'Re-translate',\n viewer_stale: 'Translation stale',\n viewer_fresh: 'Up to date',\n viewer_empty: 'Nothing here yet',\n viewer_decodeFailed: 'Could not decode memory content (browser lacks DecompressionStream)',\n viewer_search: 'Search sessions or paths…',\n viewer_col_session: 'Session',\n viewer_col_usage: 'Citations',\n viewer_col_updated: 'Updated',\n viewer_col_lastUsed: 'Last used',\n}\n\n/** Activate the browser half: register the Memory settings page and the status pill. */\nexport function apply(ctx: ClientContext): void {\n try {\n activate(ctx)\n } catch (error) {\n // A throw here aborts the whole web boot (the renderer reports\n // <entry>: failed), so surface the real cause before rethrowing.\n console.error('[dsh-memory] activation failed', error)\n throw error\n }\n}\n\nfunction activate(ctx: ClientContext): void {\n ctx.effect(() => ctx.locale.register(NS, { zh: ZH, en: EN }), 'dsh-memory: dictionaries')\n // Keep the raw citation XML out of the visible transcript (the host-side\n // citation loop reads it from the session log regardless).\n ctx.effect(() => installCitationStripper(), 'dsh-memory: citation stripper')\n\n const bridge = new MemoryBridge()\n // `$mount` is async while slot registrations are not: the bridge starts with\n // loading snapshots and fills them in as soon as the namespace is installed.\n ctx.effect(() => {\n let dispose: (() => Promise<void>) | undefined\n let cancelled = false\n void mountMemoryBridge(bridge, ctx)\n .then((mounted) => {\n if (cancelled) {\n void mounted()\n return\n }\n dispose = mounted\n })\n .catch((error) => {\n console.warn('[dsh-memory] memory remote unavailable:', error)\n })\n return () => {\n cancelled = true\n if (dispose != null) void dispose()\n }\n }, 'dsh-memory: memory remote')\n\n const card = new MemoryCardController(bridge.configScope, catalogLoader(ctx))\n const statusSource = bridge.statusSource\n const viewSource = bridge.viewSource\n const commandsView = bridge.commands\n const memoryView = bridge.configScope\n\n // Standalone viewer page: a right-sidebar tab (ui-sidebar-right is optional\n // in the composition, so the whole registration waits on the service).\n let sidebarRight: ClientContext['sidebarRight']\n ctx.inject(['sidebarRightTabs', 'sidebarRight'], (sctx) => {\n sidebarRight = sctx.sidebarRight\n const tabTitle = (): string => ctx.locale.bind(NS)('viewer_title')\n sctx.effect(() => sctx.sidebarRightTabs?.register({\n id: MEMORY_VIEWER_ID,\n kind: MEMORY_VIEWER_KIND,\n title: tabTitle,\n }), 'dsh-memory: viewer tab type')\n sctx.effect(() => sctx.slots.inject('sidebar.right.pane.tab', () => sctx.slots.register(\n {\n name: 'sidebar.right.pane.tab',\n key: MEMORY_VIEWER_ID,\n locale: NS,\n inject: () => ({\n hooks: { memoryView: viewSource, memoryStatus: statusSource },\n commands: commandsView,\n }),\n },\n MemoryViewerBody,\n )), 'dsh-memory: viewer tab body')\n sctx.effect(() => sctx.slots.inject('sidebar.right.pane.tab.title', () => sctx.slots.register(\n { name: 'sidebar.right.pane.tab.title', key: MEMORY_VIEWER_ID, locale: NS },\n MemoryViewerTitle,\n )), 'dsh-memory: viewer tab title')\n })\n const openViewer = (): void => {\n try {\n sidebarRight?.openTab(MEMORY_VIEWER_KIND, {})\n } catch {\n // the pane can fail to open only when the sidebar service is gone\n }\n }\n // The settings page is one component with two seats: the standalone\n // settings section and the plugin manager's per-bundle page.\n const pageFace = (embedded: boolean) => () => ({\n // The controller face carries edit/resetField/refreshCatalog; the\n // renderer binds them as plain props, and the hooks compartment as\n // useMemoryPage/useMemoryStatus/useMemoryView selector hooks.\n ...card.inject(),\n commands: commandsView,\n embedded,\n hooks: {\n memoryPage: card.pageStore(),\n memoryStatus: statusSource,\n memoryView: viewSource,\n },\n })\n\n // Own Settings → Memory page (independent section in the settings sidebar).\n ctx.slots.inject('settings.section', () => ctx.slots.register(\n {\n name: 'settings.section',\n id: 'memory',\n order: 16,\n label: () => t_nav(ctx),\n locale: NS,\n inject: pageFace(false),\n },\n MemorySettingsPage,\n ))\n\n // Plugins → dsh-remember page: keyed by the bundle's package name. The\n // plugin manager declares this slot as a child of its own page, so the\n // registration waits until that page exists.\n ctx.slots.inject('plugins.bundle.config', () => ctx.slots.register(\n {\n name: 'plugins.bundle.config',\n key: 'dsh-remember',\n locale: NS,\n inject: pageFace(true),\n },\n MemorySettingsPage,\n ))\n\n ctx.slots.inject('sidebar.footer.action', () => ctx.slots.register(\n {\n name: 'sidebar.footer.action',\n id: 'dsh-memory-status',\n order: 10,\n locale: NS,\n inject: () => ({\n hooks: { memoryStatus: statusSource },\n commands: commandsView,\n settings: memoryView,\n openViewer,\n }),\n },\n MemoryFooterAction,\n ))\n}\n\nfunction t_nav(ctx: ClientContext): string {\n const t = ctx.locale.bind(NS)\n return t('nav')\n}\n\n/** `remote.session` namespace (the session controller client half). */\ninterface SessionRemote {\n modelCatalog?: {\n call(session: unknown): Promise<{ ok: boolean; value?: unknown; error?: unknown }>\n }\n}\n\n/**\n * The catalog is optional: `remote.session` is not in `inject`, because a\n * composition without the session controller must still activate the panel\n * (users can type `provider/model` by hand). Looking the service up through\n * `ctx.get` keeps activation independent of the controller's ordering.\n */\nfunction lookupSession(ctx: ClientContext): SessionRemote | null {\n try {\n const value = ctx.get('remote.session')\n return typeof value === 'object' && value !== null ? value as SessionRemote : null\n } catch {\n return null\n }\n}\n\n/** Query the Host model catalog and flatten it into selectable routes. */\nfunction catalogLoader(ctx: ClientContext): (() => Promise<CatalogModel[]>) | null {\n const session = lookupSession(ctx)\n const call = session?.modelCatalog\n if (call == null) return null\n return async (): Promise<CatalogModel[]> => {\n const result = await call.call(session)\n if (!result?.ok || result.value == null) {\n throw new Error('model catalog unavailable')\n }\n const catalog = result.value as {\n groups: Array<{ id: string; name: string; models: Array<{ id: string; name: string }> }>\n }\n return catalog.groups.flatMap((group) => group.models.map((model) => ({\n provider: group.id,\n providerName: group.name,\n model: model.id,\n modelName: model.name,\n })))\n }\n}\n"],"mappings":"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"}