{"version":3,"file":"client.inner.cjs","names":["useSyncExternalStore","useCallback","useRef","captured","useState","useRef","Button","PathLabel","Tag","useId","SegmentedTabs","Checkbox"],"sources":["../../dsh-plugin-kit/src/client-utils.ts","../../dsh-plugin-kit/src/model-menu.ts","../../dsh-plugin-kit/src/official-ui.ts","../src/contracts.ts","../src/rpc-result.ts","../src/skills.ts","../src/review-lifetime.ts","../src/client.tsx"],"sourcesContent":["import { useCallback, useEffect, useRef, useSyncExternalStore } from 'react'\n\nexport interface NativeSurfaceClient {\n  sessions: {\n    binding?(sessionId: string): { eventSource: { subscribe(listener: () => void): () => void } } | undefined\n  }\n  uiWorkspace: { current?: { getSnapshot(): { sessionId: string } | undefined; subscribe(listener: () => void): () => void } }\n  uiSession: { adapter: { current: { getSnapshot(): { key?: string }; subscribe(listener: () => void): () => void } } }\n  locale: { getSnapshot(): { active: string }; subscribe(listener: () => void): () => void }\n  connection?: { generation?: { subscribe(listener: () => void): () => void } }\n}\n\n/** The Editor retains its manuscript session separately; native DSH exposes the main-view binding. */\nexport function selectedSessionId(client: Pick<NativeSurfaceClient, 'uiWorkspace' | 'uiSession'>): string {\n  const workspace = client.uiWorkspace?.current\n  return workspace\n    ? workspace.getSnapshot()?.sessionId ?? ''\n    : client.uiSession.adapter.current.getSnapshot().key ?? ''\n}\n\n/**\n * Owner props are data the host composed, never a Cordis context: reading an\n * undeclared property off one throws instead of returning undefined, which\n * would crash the slot entry and abdicate its cell for good. Tolerate a\n * throwing read so a mistaken prop degrades to \"not supplied\".\n */\nfunction read(source: unknown, key: string): unknown {\n  if (source === null || typeof source !== 'object') return undefined\n  try {\n    return (source as Record<string, unknown>)[key]\n  } catch {\n    return undefined\n  }\n}\n\nfunction readString(source: unknown, key: string): string | undefined {\n  const value = read(source, key)\n  return typeof value === 'string' ? value : undefined\n}\n\n/** Owner props win; native settings only supplies close, so resolve its selected session. */\nexport function useNativeSeat(client: NativeSurfaceClient, props?: unknown) {\n  const current = useSyncExternalStore(\n    useCallback((fn: () => void) => (client.uiWorkspace?.current ?? client.uiSession.adapter.current).subscribe(fn), [client]),\n    useCallback(() => selectedSessionId(client), [client]),\n    () => '',\n  )\n  const language = useSyncExternalStore(\n    useCallback((fn: () => void) => client.locale.subscribe(fn), [client]),\n    useCallback(() => client.locale.getSnapshot().active, [client]),\n    () => 'en',\n  )\n  const sessionId = readString(props, 'sessionId') ?? readString(read(props, 'owner'), 'sessionId') ?? current\n  const requestedLocale = read(props, 'locale') ?? read(read(props, 'owner'), 'locale') ?? language\n  return { sessionId, locale: (String(requestedLocale).startsWith('zh') ? 'zh' : 'en') as 'zh' | 'en',\n    hidden: read(props, 'hidden') === true || read(read(props, 'owner'), 'hidden') === true }\n}\n\n/** Refresh on native log boundaries/reconnect/focus. Read-only settling is bounded to an observed job. */\nexport function useFeatureRefresh(\n  client: NativeSurfaceClient, sessionId: string, refresh: () => void,\n  working = false, enabled = true,\n): void {\n  const refreshRef = useRef(refresh)\n  refreshRef.current = refresh\n  useEffect(() => {\n    if (!enabled) return\n    let timer: ReturnType<typeof setTimeout> | undefined\n    const queue = () => {\n      if (typeof document !== 'undefined' && document.visibilityState === 'hidden') return\n      clearTimeout(timer)\n      timer = setTimeout(() => refreshRef.current(), 150)\n    }\n    const source = sessionId ? client.sessions.binding?.(sessionId)?.eventSource : undefined\n    const stopEvents = source?.subscribe(queue)\n    const stopConnection = client.connection?.generation?.subscribe(queue)\n    const visibility = () => { if (document.visibilityState === 'visible') queue() }\n    window.addEventListener('focus', queue)\n    document.addEventListener('visibilitychange', visibility)\n    // Details are collapsed by default; opening an existing panel must get current state.\n    document.addEventListener('toggle', queue, true)\n    return () => {\n      clearTimeout(timer)\n      stopEvents?.(); stopConnection?.()\n      window.removeEventListener('focus', queue)\n      document.removeEventListener('visibilitychange', visibility)\n      document.removeEventListener('toggle', queue, true)\n    }\n  }, [client, sessionId, enabled])\n  useEffect(() => {\n    if (!enabled || !working) return\n    let delay = 250\n    const until = Date.now() + 300_000\n    let timer: ReturnType<typeof setTimeout>\n    const tick = () => {\n      if (Date.now() >= until) return\n      if (document.visibilityState !== 'hidden') refreshRef.current()\n      delay = Math.min(delay * 2, 2000)\n      timer = setTimeout(tick, delay)\n    }\n    timer = setTimeout(tick, delay)\n    return () => clearTimeout(timer)\n  }, [client, sessionId, working, enabled])\n}\n","/**\n * Shared plugin-page model menu.\n *\n * A feature plugin's own settings row exposes a model select. An empty\n * selection means the host default chat model for that feature's own call.\n *\n * Browser-safe and React-optional: pure helpers live here so hosts and clients\n * share one catalog contract without bundling React into the host build.\n */\nimport { useEffect, useState } from 'react'\nimport type { ModelRoute } from './contracts.ts'\n\n/** One selectable model. `efforts` are the advertised reasoning efforts. */\nexport interface ModelMenuChoice {\n  readonly provider: string\n  readonly model: string\n  readonly label: string\n  readonly efforts: ReadonlyArray<{ id: string; name: string }>\n}\n\n/** The stored selection. Empty provider/model means \"follow the default\". */\nexport type ModelMenuRoute = ModelRoute\n\n/** The catalog face this helper needs; stays structural so hosts may add more. */\nexport interface ModelCatalogClient {\n  readonly remote?: {\n    readonly session?: { readonly modelCatalog?: () => Promise<unknown> }\n  }\n}\n\nconst KEY_SEPARATOR = '\\u001f'\n\nexport function modelMenuChoiceKey(provider: string, model: string): string {\n  return provider && model ? `${provider}${KEY_SEPARATOR}${model}` : ''\n}\n\nexport function parseModelMenuChoiceKey(value: string): { provider: string; model: string } | undefined {\n  const index = value.indexOf(KEY_SEPARATOR)\n  if (index <= 0) return undefined\n  const provider = value.slice(0, index)\n  const model = value.slice(index + KEY_SEPARATOR.length)\n  if (!provider || !model) return undefined\n  return { provider, model }\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | undefined {\n  return value && typeof value === 'object' && !Array.isArray(value) ? value as Record<string, unknown> : undefined\n}\n\nfunction asText(value: unknown): string | undefined {\n  return typeof value === 'string' && value.trim() ? value.trim() : undefined\n}\n\nfunction parseEffort(value: unknown): { id: string; name: string } | undefined {\n  const row = asRecord(value)\n  const id = row ? asText(row.id) : undefined\n  if (!id) return undefined\n  return { id, name: row ? asText(row.name) ?? id : id }\n}\n\n/** Parse the host session catalog into flat choices, keeping a saved route selectable. */\nexport function parseModelMenuChoices(value: unknown, bound?: ModelMenuRoute): ModelMenuChoice[] {\n  const envelope = asRecord(value)\n  // Host remote calls resolve to a result envelope ({ ok, value }); older hosts\n  // and unit tests hand over the bare catalog. Accept both.\n  const root = (envelope && envelope.ok === true ? asRecord(envelope.value) : undefined) ?? envelope ?? {}\n  const groups = Array.isArray(root.groups) ? root.groups : []\n  const choices: ModelMenuChoice[] = []\n  for (const group of groups) {\n    const groupRow = asRecord(group)\n    const provider = groupRow ? asText(groupRow.id) : undefined\n    if (!provider || !groupRow || !Array.isArray(groupRow.models)) continue\n    const providerName = asText(groupRow.name) ?? provider\n    for (const entry of groupRow.models) {\n      const modelRow = asRecord(entry)\n      const model = modelRow ? asText(modelRow.id) : undefined\n      if (!model || !modelRow) continue\n      const name = asText(modelRow.name) ?? model\n      const reasoning = asRecord(modelRow.reasoning)\n      const efforts = reasoning && Array.isArray(reasoning.efforts)\n        ? reasoning.efforts.flatMap(effort => { const parsed = parseEffort(effort); return parsed ? [parsed] : [] })\n        : []\n      choices.push({ provider, model, label: `${providerName} / ${name}`, efforts })\n    }\n  }\n  if (bound?.provider && bound.model && !choices.some(item => item.provider === bound.provider && item.model === bound.model)) {\n    choices.push({ provider: bound.provider, model: bound.model, label: `${bound.provider} / ${bound.model}`, efforts: [] })\n  }\n  return choices\n}\n\n/** An empty saved route means no explicit model. */\nexport function modelMenuOverride(route: ModelMenuRoute | undefined): ModelRoute | undefined {\n  const provider = route?.provider?.trim()\n  const model = route?.model?.trim()\n  if (!provider || !model) return undefined\n  const effort = route?.reasoningEffort?.trim()\n  return effort ? { provider, model, reasoningEffort: effort } : { provider, model }\n}\n\nexport function normalizeModelMenuRoute(value: unknown): ModelMenuRoute {\n  const row = asRecord(value)\n  if (!row) return { provider: '', model: '' }\n  const provider = asText(row.provider) ?? ''\n  const model = asText(row.model) ?? ''\n  const effort = asText(row.reasoningEffort)\n  if (!provider || !model || provider.length > 250 || model.length > 250) return { provider: '', model: '' }\n  return effort && effort.length <= 80 ? { provider, model, reasoningEffort: effort } : { provider, model }\n}\n\n/** Load the host catalog once per mount and republish whenever it answers. */\nexport function useModelMenuChoices(client: ModelCatalogClient, bound?: ModelMenuRoute): ModelMenuChoice[] {\n  const [choices, setChoices] = useState<ModelMenuChoice[]>([])\n  useEffect(() => {\n    if (typeof document === 'undefined') return\n    let live = true\n    const load = () => {\n      void client.remote?.session?.modelCatalog?.()\n        ?.then(value => { if (live) setChoices(parseModelMenuChoices(value, bound)) })\n        .catch(() => { if (live) setChoices([]) })\n    }\n    load()\n    return () => { live = false }\n  }, [client, bound?.provider, bound?.model])\n  return choices\n}\n\n/** Reasoning-effort options for one choice; the saved value stays selectable. */\nexport function modelMenuEffortOptions(\n  choice: ModelMenuChoice | undefined,\n  current?: string,\n): Array<{ id: string; name: string }> {\n  const listed = (choice?.efforts ?? []).map(item => ({ ...item }))\n  if (current && !listed.some(item => item.id === current)) listed.push({ id: current, name: current })\n  return listed\n}\n","/**\n * Shared contract that keeps every plugin's browser-side UI on the official\n * DeepSeek Harness Web design language.\n *\n * Two rules produce that language, and both are load-bearing here:\n *\n * 1. Colour, radius, elevation and focus come from the host theme's real\n *    `--dsw-*` tokens, written under their own names. Plugins never invent a\n *    token, never alias the official ones behind a private palette (a private\n *    alias is just a second, diverging theme), and never carries a literal\n *    fallback — the host publishes light and dark, and a literal would pin one\n *    of them. The only non-colour custom properties used are the host's own\n *    content-font axis and frame clearance.\n *\n * 2. Anything the host already ships is used, not reimplemented. Controls come\n *    from `@deepseek-ai/dsh-client-ui-primitives` (`Button`, `Input`,\n *    `Checkbox`, `Switch`, `Tag`, `Pill`, `SegmentedControl`, `Menu`, `Modal`,\n *    `Tooltip`, `Toast`, `DisclosureRow`, `StateDot`, `PathLabel`, the settings\n *    form suite). This module only styles what primitives do not cover: page\n *    scaffolding, field layout, banners, empty states and scroll regions.\n *\n * The metrics below are transcribed from the primitives' own CSS modules so a\n * feature panel lines up pixel-for-pixel with a native one: the 14/22 body and\n * 13/20 compact type tiers, the 0.5px hairline scale, and the elevation family\n * that draws a surface's edge in its shadow (`border: 0`) instead of a border.\n */\n\n/**\n * Every `--dsw-*` token this repo is allowed to reference, grouped by role.\n *\n * Plugins may only colour through this list. It is exported so the guard test\n * can fail a build when a stylesheet reaches for anything else — the failure\n * mode this prevents is silent: an unknown token resolves to nothing, so a\n * border disappears or a label inherits the wrong colour with no error anywhere.\n */\nexport const OFFICIAL_THEME_TOKENS = {\n  /** Surfaces, from the page up to the topmost nested card. */\n  surface: [\n    '--dsw-alias-bg-base',\n    '--dsw-alias-bg-layer-1',\n    '--dsw-alias-bg-layer-2',\n    '--dsw-alias-bg-layer-3',\n    '--dsw-alias-bg-layer-4',\n    '--dsw-alias-bg-module-platform',\n    '--dsw-alias-bg-overlay',\n  ],\n  /** Hairlines. l1 is near-invisible on a menu surface, so menus use l2+. */\n  border: ['--dsw-alias-border-l1', '--dsw-alias-border-l2', '--dsw-alias-border-l3', '--dsw-alias-border-l4'],\n  /** Text. `caption` is menu shortcut text, `dimmed` is placeholder text. */\n  label: [\n    '--dsw-alias-label-primary',\n    '--dsw-alias-label-secondary',\n    '--dsw-alias-label-tertiary',\n    '--dsw-alias-label-caption',\n    '--dsw-alias-label-dimmed',\n    '--dsw-alias-label-error',\n    '--dsw-alias-label-primary-foreground',\n  ],\n  /** Interactive fills. The `-danger` hover belongs to destructive rows. */\n  interactive: [\n    '--dsw-alias-interactive-bg-hover',\n    '--dsw-alias-interactive-bg-active',\n    '--dsw-alias-interactive-bg-hover-danger',\n  ],\n  /** Accent and status. `business` is the focus ring's default colour. */\n  accent: [\n    '--dsw-alias-brand-primary',\n    '--dsw-alias-button-primary-fill',\n    '--dsw-alias-button-primary-hover',\n    '--dsw-alias-button-tool-bar-fill',\n    '--dsw-alias-button-tool-bar-hover',\n    '--dsw-alias-button-ghost-active-fill',\n    '--dsw-alias-button-ghost-active-border',\n  ],\n  state: [\n    '--dsw-alias-state-business-primary',\n    '--dsw-alias-state-success-primary',\n    '--dsw-alias-state-warn-primary',\n    '--dsw-alias-state-error-primary',\n    '--dsw-alias-state-idle-primary',\n  ],\n  /** Corner scale: sm 8, md 12, lg the large card, panel the modal. */\n  radius: ['--dsw-radius-sm', '--dsw-radius-md', '--dsw-radius-lg', '--dsw-radius-panel'],\n  /** An elevated surface draws its edge in the shadow, so it keeps border: 0. */\n  elevation: [\n    '--dsw-elevation-soft',\n    '--dsw-elevation-stroke',\n    '--dsw-elevation-stroke-color',\n    '--dsw-elevation-panel',\n    '--dsw-elevation-prominent',\n  ],\n  /** Floats, masks and scrollbars. */\n  overlay: [\n    '--dsw-menu-surface-fill',\n    '--dsw-menu-backdrop-filter',\n    '--dsw-mask-blur',\n    '--dsw-alias-bg-mask-1',\n    '--dsw-alias-menu-icon',\n    '--dsw-alias-scrollbar-bg-l2',\n    '--dsw-alias-scrollbar-hover-l2',\n    '--dsw-shadow-lv3',\n  ],\n  /** Motion, focus and type axis, published by the host rather than by a component. */\n  system: [\n    '--dsw-focus-ring-width',\n    '--dsw-focus-ring-color',\n    '--dsw-font-markdown-code-font-family',\n    '--ds-transition-duration',\n    '--ds-ease-in-out',\n    '--ds-font-family-code',\n    '--dsh-scrollbar-thumb',\n    '--dsh-scrollbar-thumb-hover',\n    '--dsh-content-font-size-secondary',\n    '--dsh-content-font-delta',\n    '--dsh-frame-top-clearance',\n  ],\n} as const\n\n/** Every official token name, flat. Used by the token guard test. */\nexport const OFFICIAL_THEME_TOKEN_NAMES: readonly string[] = Object.values(OFFICIAL_THEME_TOKENS).flat()\n\n/** The elevation steps a surface can be raised by, softest first. */\nexport type OfficialElevation = 'soft' | 'stroke' | 'panel' | 'prominent'\n\n/**\n * The host's focus ring shorthand, verbatim. Writing this per control is how\n * rings drift apart; a stylesheet that draws its own focus style should use\n * {@link officialFocus} instead. The colour fallback is the host's own default.\n */\nexport const OFFICIAL_FOCUS_RING =\n  'var(--dsw-focus-ring-width) solid var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary))'\n\n/**\n * A complete `outline` declaration at the official geometry. `offset` defaults\n * to the 2px the native controls use; the host's inline field rules sit at 1px\n * and a segmented tab pulls the ring inside itself at -2px.\n */\nexport function officialFocus(offset = '2px'): string {\n  return `outline: ${OFFICIAL_FOCUS_RING}; outline-offset: ${offset}`\n}\n\n/**\n * An elevated surface. The host draws a raised surface's edge inside its\n * shadow rather than as a border, so a card sets `border: 0` and takes the edge\n * from the elevation — which is also why its border stays off the alias-border\n * set that a flat, non-elevated rule would use.\n */\nexport function officialElevation(level: OfficialElevation): string {\n  return `border: 0; box-shadow: var(--dsw-elevation-${level})`\n}\n\n/**\n * An elevated surface whose edge should read as a specific hairline. Rebinding\n * the stroke colour is how a menu card picks l1 while a panel picks l3, without\n * the two growing apart by hand.\n */\nexport function officialStrokedElevation(level: OfficialElevation, color: string): string {\n  return `--dsw-elevation-stroke-color: ${color}; ${officialElevation(level)}`\n}\n\n/**\n * The shared stylesheet for a plugin UI, scoped under that plugin's root class.\n *\n * Scoping is what keeps this safe to always-bundle into every client: the rules\n * can only match inside the plugin's own subtree, so two plugins can both mount\n * `dsh-ui-card` without either styling the other's markup.\n *\n * Each recipe matches the root element *and* its descendants, because the\n * commonest arrangement is one element that is both — a surface that carries\n * the root class and `dsh-ui-card`, or a portaled dialog that is the root and\n * the `dsh-ui-surface`. A descendant-only scope would silently leave those\n * unstyled, with no error anywhere.\n *\n * A caveat worth knowing: `Modal` and `Menu` portal to `document.body`, so their\n * content leaves the plugin's subtree entirely. A portaled surface therefore\n * needs its own root class on an element inside the portal.\n *\n * Only patterns that primitives do not provide live here. If a control appears\n * below that `Button`/`Input`/`Switch`/`Tag`/`Menu` already covers, that is a\n * bug in this file: use the primitive and delete the recipe.\n */\nexport function officialUiCss(roots: string | readonly string[]): string {\n  // One plugin often mounts several unrelated surfaces (a settings seat, a chat\n  // card, a header menu), so the caller names every root. The rules below are\n  // nested under a single selector list and use `&`, which the browser expands\n  // per root — so one stylesheet covers all of them without duplicating itself.\n  const scope = (typeof roots === 'string' ? [roots] : roots).map(root => `.${root}`).join(', ')\n  const sheet = `\n/* Official DSH Web UI contract. Generated by @klarkxy/dsh-plugin-kit/official-ui.\n * Do not hand-edit the copy inside a plugin: change this module so every plugin\n * moves together. Scope: ${scope} */\n/* The scope rule below stays open for the whole sheet: every rule after it\n * nests with the parent selector, so one stylesheet can cover several unrelated\n * roots without leaking into a neighbouring plugin. Its closing brace is last. */\n${scope} {\n  color: var(--dsw-alias-label-primary);\n  font-family: inherit;\n  font-size: 14px;\n  line-height: 22px;\n  min-width: 0;\n\n& *, & *::before, & *::after { box-sizing: border-box; }\n& h1, & h2, & h3, & h4, & p, & figure { margin: 0; }\n/* Keyboard focus only: pointer input keeps the native resting appearance. The\n * ring needs no radius of its own — the outline already follows the control's\n * own border-radius, and overriding it here would flatten every control. */\n& :focus-visible { ${officialFocus()}; }\n& [hidden] { display: none !important; }\n\n/* --- Type tiers. The same 14/22 and 13/20 steps the primitives use. --- */\n& .dsh-ui-title { font-size: 16px; line-height: 24px; font-weight: 500; color: var(--dsw-alias-label-primary); }\n& .dsh-ui-heading { font-size: 14px; line-height: 22px; font-weight: 500; color: var(--dsw-alias-label-primary); }\n& .dsh-ui-compact { font-size: 13px; line-height: 20px; color: var(--dsw-alias-label-primary); }\n& .dsh-ui-meta { font-size: 12px; line-height: 18px; color: var(--dsw-alias-label-secondary); }\n& .dsh-ui-hint { font-size: 12px; line-height: 18px; color: var(--dsw-alias-label-tertiary); }\n& .dsh-ui-error { font-size: 12px; line-height: 18px; color: var(--dsw-alias-state-error-primary); }\n& .dsh-ui-warn { color: var(--dsw-alias-state-warn-primary); }\n& .dsh-ui-success { color: var(--dsw-alias-state-success-primary); }\n& .dsh-ui-muted { color: var(--dsw-alias-label-tertiary); }\n& .dsh-ui-truncate { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n& .dsh-ui-wrap { min-width: 0; overflow-wrap: anywhere; }\n\n/* --- Layout scaffolding. --- */\n& .dsh-ui-stack { display: flex; flex-direction: column; gap: 12px; }\n& .dsh-ui-stack-lg { display: flex; flex-direction: column; gap: 20px; }\n& .dsh-ui-row { display: flex; align-items: center; gap: 8px; min-width: 0; }\n& .dsh-ui-row-wrap { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }\n& .dsh-ui-spacer { flex: 1; min-width: 0; }\n/* A 0.5px l2 rule is the host's section divider; reserve the same rhythm. */\n& .dsh-ui-divider { height: 0.5px; background: var(--dsw-alias-border-l2); }\n& .dsh-ui-section { display: flex; flex-direction: column; gap: 12px; padding-top: 16px; border-top: 0.5px solid var(--dsw-alias-border-l2); }\n\n/* --- Card: a raised surface whose edge lives in the shadow. --- */\n& .dsh-ui-card {\n  ${officialElevation('stroke')}\n  display: flex;\n  flex-direction: column;\n  gap: 12px;\n  padding: 16px;\n  border-radius: var(--dsw-radius-lg);\n  background: var(--dsw-alias-bg-layer-1);\n  color: var(--dsw-alias-label-primary);\n  min-width: 0;\n}\n& .dsh-ui-card--flat { border: 0.5px solid var(--dsw-alias-border-l3); box-shadow: none; }\n& .dsh-ui-card--nested { background: var(--dsw-alias-bg-layer-2); }\n& .dsh-ui-card--plain { background: none; }\n\n/* --- Field: label, control, help, error. The control itself is an\n * official primitive, so this only owns the vertical rhythm. --- */\n& .dsh-ui-field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }\n& .dsh-ui-field + .dsh-ui-field { border-top: 0.5px solid var(--dsw-alias-border-l2); padding-top: 12px; }\n& .dsh-ui-label { display: flex; align-items: center; gap: 6px; font-size: 13px; line-height: 20px; font-weight: 500; color: var(--dsw-alias-label-primary); }\n& .dsh-ui-label-row { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }\n& .dsh-ui-help { font-size: 12px; line-height: 1.6; color: var(--dsw-alias-label-secondary); }\n& .dsh-ui-help p { margin: 0; }\n& .dsh-ui-help p + p { margin-top: 8px; }\n& .dsh-ui-required { color: var(--dsw-alias-state-error-primary); }\n& .dsh-ui-control { width: 100%; min-width: 0; }\n/* An invalid control is marked on the control, not only in the message. */\n& .dsh-ui-control[aria-invalid='true'] { border-color: var(--dsw-alias-state-error-primary); }\n& .dsh-ui-readonly { display: flex; flex-direction: column; gap: 4px; min-width: 0; }\n& .dsh-ui-readonly > dt { font-size: 12px; line-height: 18px; color: var(--dsw-alias-label-tertiary); }\n& .dsh-ui-readonly > dd { margin: 0; font-size: 13px; line-height: 20px; overflow-wrap: anywhere; }\n\n/* --- Buttons row. A no-op container: it exists so actions line up on the\n * trailing edge the way every native panel does. --- */\n& .dsh-ui-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding-top: 4px; }\n& .dsh-ui-actions-end { justify-content: flex-end; }\n\n/* --- Banners. A banner is a left-rail notice, the shape used for warnings,\n * deprecations and blocking instructions. --- */\n& .dsh-ui-banner {\n  display: flex;\n  flex-direction: column;\n  gap: 8px;\n  padding: 10px 14px;\n  border: 0.5px solid var(--dsw-alias-border-l3);\n  border-left: 3px solid var(--dsw-alias-state-warn-primary);\n  border-radius: var(--dsw-radius-md);\n  background: var(--dsw-alias-bg-layer-1);\n  font-size: 13px;\n  line-height: 20px;\n  color: var(--dsw-alias-label-secondary);\n}\n& .dsh-ui-banner-title { font-weight: 500; color: var(--dsw-alias-state-warn-primary); }\n& .dsh-ui-banner--info { border-left-color: var(--dsw-alias-state-business-primary); }\n& .dsh-ui-banner--danger { border-left-color: var(--dsw-alias-state-error-primary); }\n& .dsh-ui-banner--success { border-left-color: var(--dsw-alias-state-success-primary); }\n& .dsh-ui-banner p { margin: 0; }\n\n/* --- Inline notice: a transient confirmation with no chrome of its own. --- */\n& .dsh-ui-notice { display: flex; align-items: center; gap: 6px; font-size: 12px; line-height: 18px; color: var(--dsw-alias-state-success-primary); }\n& .dsh-ui-notice--error { color: var(--dsw-alias-state-error-primary); }\n\n/* --- Empty and loading states. Both sit in a dashed well so an empty panel\n * reads as \"nothing here yet\" rather than as a broken layout. --- */\n& .dsh-ui-empty {\n  display: flex;\n  flex-direction: column;\n  align-items: flex-start;\n  gap: 6px;\n  padding: 20px 16px;\n  border: 0.5px dashed var(--dsw-alias-border-l3);\n  border-radius: var(--dsw-radius-md);\n  font-size: 13px;\n  line-height: 20px;\n  color: var(--dsw-alias-label-secondary);\n}\n& .dsh-ui-loading { display: flex; align-items: center; gap: 8px; padding: 20px 0; font-size: 13px; line-height: 20px; color: var(--dsw-alias-label-secondary); }\n\n/* --- Selectable list. A row is a button-sized target with a hover fill and\n * a selected fill; the name carries the weight, the description does not. --- */\n& .dsh-ui-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; min-width: 0; }\n& .dsh-ui-list-scroll { max-height: min(66vh, 760px); overflow-y: auto; overflow-x: hidden; }\n& .dsh-ui-list-row { border-radius: var(--dsw-radius-md); }\n& .dsh-ui-list-row:hover { background: var(--dsw-alias-interactive-bg-hover); }\n& .dsh-ui-list-row[aria-selected='true'], & .dsh-ui-list-row[data-selected] { background: var(--dsw-alias-interactive-bg-active); }\n& .dsh-ui-list-item {\n  display: flex;\n  flex-direction: column;\n  align-items: flex-start;\n  gap: 4px;\n  width: 100%;\n  min-width: 0;\n  padding: 10px 12px;\n  border: 0;\n  border-radius: var(--dsw-radius-md);\n  background: none;\n  font: inherit;\n  color: inherit;\n  text-align: start;\n  cursor: pointer;\n}\n& .dsh-ui-list-item:disabled { cursor: default; }\n& .dsh-ui-list-item:disabled:hover { background: none; }\n& .dsh-ui-list-name { font-size: 14px; line-height: 22px; font-weight: 500; color: var(--dsw-alias-label-primary); overflow-wrap: anywhere; }\n& .dsh-ui-list-desc { font-size: 12px; line-height: 18px; color: var(--dsw-alias-label-tertiary); }\n\n/* --- Code and structured output. Wraps rather than scrolls, because a\n * feature panel is read rather than scanned. --- */\n& .dsh-ui-code {\n  padding: 10px 12px;\n  border: 0.5px solid var(--dsw-alias-border-l3);\n  border-radius: var(--dsw-radius-md);\n  background: var(--dsw-alias-bg-layer-1);\n  font-family: var(--ds-font-family-code, ui-monospace, 'Cascadia Mono', Consolas, monospace);\n  font-size: 12px;\n  line-height: 20px;\n  color: var(--dsw-alias-label-secondary);\n  overflow-wrap: anywhere;\n  white-space: pre-wrap;\n}\n& .dsh-ui-scroll { max-height: 60vh; overflow: auto; overscroll-behavior: contain; }\n\n/* --- A toggle row: label on the left, switch on the trailing edge. This is\n * layout only; the switch itself is the official primitive. --- */\n& .dsh-ui-toggle-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; min-width: 0; padding: 12px 0; }\n& .dsh-ui-toggle-row + .dsh-ui-toggle-row { border-top: 0.5px solid var(--dsw-alias-border-l2); }\n& .dsh-ui-toggle-text { display: flex; flex-direction: column; gap: 4px; min-width: 0; }\n& .dsh-ui-toggle-label { font-size: 14px; line-height: 22px; font-weight: 500; color: var(--dsw-alias-label-primary); }\n\n/* --- Floating surface: a panel anchored to a trigger. This is the material\n * a menu card is made of — the translucent fill plus its backdrop blur, with\n * the edge riding inside the prominent elevation. A plugin that hand-rolls this\n * is how tokens like --dsw-specific-menu get invented; use this instead. --- */\n& .dsh-ui-surface {\n  --dsw-elevation-stroke-color: var(--dsw-alias-border-l1);\n  --dsh-scrollbar-thumb: var(--dsw-alias-scrollbar-bg-l2);\n  --dsh-scrollbar-thumb-hover: var(--dsw-alias-scrollbar-hover-l2);\n  position: relative;\n  display: flex;\n  flex-direction: column;\n  border: 0;\n  border-radius: var(--dsw-radius-lg);\n  background: var(--dsw-menu-surface-fill);\n  backdrop-filter: var(--dsw-menu-backdrop-filter);\n  box-shadow: var(--dsw-elevation-prominent);\n  color: var(--dsw-alias-label-primary);\n  font-size: 13px;\n  line-height: 20px;\n  min-width: 0;\n}\n& .dsh-ui-surface-body { display: flex; flex-direction: column; gap: 8px; padding: 12px 14px 14px; overflow-y: auto; }\n& .dsh-ui-surface-head { display: flex; align-items: center; gap: 8px; min-width: 0; }\n& .dsh-ui-surface-title { font-size: 14px; line-height: 22px; font-weight: 500; color: var(--dsw-alias-label-primary); }\n\n/* --- Native select. The primitives ship no select, so a plugin that offers a\n * closed list of choices keeps the platform control and matches the official\n * settings field geometry exactly (34px, 0.5px l4, radius-md, layer-3). A\n * SegmentedControl is the primitive to reach for when the choices are few\n * enough to show at once. --- */\n& .dsh-ui-select {\n  box-sizing: border-box;\n  width: 100%;\n  min-width: 0;\n  height: 34px;\n  padding: 0 12px;\n  border: 0.5px solid var(--dsw-alias-border-l4);\n  border-radius: var(--dsw-radius-md);\n  background: var(--dsw-alias-bg-layer-3);\n  font: inherit;\n  font-size: 13px;\n  line-height: 1.5;\n  color: var(--dsw-alias-label-primary);\n  cursor: pointer;\n}\n& .dsh-ui-select:focus-visible { outline: none; border-color: var(--dsw-alias-state-business-primary); }\n& .dsh-ui-select:disabled { color: var(--dsw-alias-label-tertiary); cursor: default; }\n& .dsh-ui-select[aria-invalid='true'] { border-color: var(--dsw-alias-state-error-primary); }\n\n/* Long panels scroll inside themselves instead of growing the host page. */\n& .dsh-ui-panel { display: flex; flex-direction: column; gap: 16px; min-width: 0; }\n& .dsh-ui-panel-wide { max-width: 100%; }\n\n@media (prefers-reduced-motion: reduce) {\n  & *, & *::before, & *::after { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; }\n}\n}\n`\n  // Widen every recipe from \"a descendant of the root\" to \"the root, or one of\n  // its descendants\". Written as a transform rather than by hand so no recipe\n  // can be added later with only the descendant form. The pattern is narrow on\n  // purpose: a leading `&` followed by one recipe class and no combinator, so\n  // sibling and child rules such as `.dsh-ui-field + .dsh-ui-field` keep their\n  // own meaning and are left alone.\n  return sheet.replace(/^& (\\.dsh-ui-[a-z0-9-]+)(?![+>~])/gm, (_match, className: string) =>\n    `&${className}, & ${className}`)\n}\n","/** Own records plus reexported frozen AI/Memory interfaces. */\nimport {\n  CHAT_EVENTS_SLOT as FROZEN_CHAT_EVENTS_SLOT,\n  projectIdFromCwd as sharedProjectIdFromCwd,\n} from '@klarkxy/dsh-plugin-kit/contracts'\nimport type {\n  EvidenceRef,\n  KnowledgeKind,\n  KnowledgeScope,\n  MemoryMutationOptions,\n  MemoryQuery,\n  MemoryRecord,\n  MemoryService,\n  NewMemoryRecord,\n  ProducerMessageSource,\n  RpcResult,\n} from '@klarkxy/dsh-plugin-kit/contracts'\n\nexport type {\n  EvidenceRef,\n  KnowledgeKind,\n  KnowledgeScope,\n  MemoryMutationOptions,\n  MemoryQuery,\n  MemoryRecord,\n  MemoryService,\n  NewMemoryRecord,\n  ProducerMessageSource,\n  RpcResult,\n}\n\nexport const CHAT_EVENTS_SLOT = FROZEN_CHAT_EVENTS_SLOT\nexport const projectIdFromCwd = sharedProjectIdFromCwd\nexport const SELF_IMPROVEMENT_RPC_CHANNEL = '/dsh-self-improvement'\nexport const SELF_IMPROVEMENT_PLUGIN = '@klarkxy/dsh-self-improvement'\nexport const SELF_IMPROVEMENT_REVIEW_SERVICE = 'dshSelfImprovementReview'\nexport const SELF_IMPROVEMENT_SOURCE_KIND = 'plugin:@klarkxy/dsh-self-improvement' as const\n/** Production activate identity. Core owns the scoped pluginName regex. */\nexport const SELF_IMPROVEMENT_ACTIVATE_ID = SELF_IMPROVEMENT_PLUGIN\nexport const EXTRACT_PURPOSE = 'self-improvement.extract'\nexport const LESSON_INJECTION_SECTION = 'dsh-self-improvement:lessons'\nexport const LESSON_SCHEMA_TAG = 'lesson-schema:1'\nexport const LESSON_SCHEMA_VERSION = 1\nexport const MAX_INJECTED_LESSONS = 5\nexport const MAX_INJECTION_TOKENS = 800\nexport const MAX_PROJECT_ID_CHARS = 32_768\nexport const MAX_RECALL_QUERY_CHARS = 200\n/** Plugin-page settings row key. */\nexport const SETTINGS_KEY = 'current'\n\n/** Plugin-page model selection. Empty provider/model means \"follow the default\". */\nexport interface SelfImprovementModelRoute {\n  readonly provider: string\n  readonly model: string\n  readonly reasoningEffort?: string\n}\n\nexport interface SelfImprovementSettings {\n  readonly revision: number\n  readonly model: SelfImprovementModelRoute\n}\n\nexport const defaultModelRoute = (): SelfImprovementModelRoute => ({ provider: '', model: '' })\nexport const defaultSettings = (): SelfImprovementSettings => ({ revision: 0, model: defaultModelRoute() })\n\n/** Untrusted stored routes collapse to the default so a bad row never breaks a run. */\nexport function normalizeModelRoute(value: unknown): SelfImprovementModelRoute {\n  if (!value || typeof value !== 'object' || Array.isArray(value)) return defaultModelRoute()\n  const row = value as Record<string, unknown>\n  const provider = typeof row.provider === 'string' ? row.provider.trim() : ''\n  const model = typeof row.model === 'string' ? row.model.trim() : ''\n  if (!provider || !model || provider.length > 250 || model.length > 250) return defaultModelRoute()\n  const effort = typeof row.reasoningEffort === 'string' ? row.reasoningEffort.trim() : ''\n  return effort && effort.length <= 80 ? { provider, model, reasoningEffort: effort } : { provider, model }\n}\n\nexport type SkillStatus = 'preview' | 'accepted' | 'rejected' | 'revoked'\nexport type SkillExportState = 'none' | 'recorded' | 'revoked'\nexport interface SkillAuditEntry { at: number; action: string; detail?: string }\nexport interface SkillSourceRef {\n  id: string\n  revision: number\n  status: MemoryRecord['status']\n  scope: KnowledgeScope\n  expiresAt?: number\n}\nexport interface SkillRecord {\n  id: string\n  revision: number\n  status: SkillStatus\n  lessonIds: string[]\n  sources: SkillSourceRef[]\n  title: string\n  markdown: string\n  createdAt: number\n  updatedAt: number\n  exportState: SkillExportState\n  exportedAt?: number\n  exportRevokedAt?: number\n  exportFilename?: string\n  audit: SkillAuditEntry[]\n}\nexport interface SessionWatermark {\n  sessionId: string\n  seq: number\n  projectId?: string\n  updatedAt: number\n}\n\nexport type LessonTriggerKind = 'human-correction' | 'human-instruction' | 'human-feedback' | 'tool-recovery' | 'verified-tool-fix' | 'manual'\nexport interface LessonTrigger {\n  kind: LessonTriggerKind\n  evidence: EvidenceRef[]\n  titleHint: string\n  contentHint: string\n  toolName?: string\n}\n\nexport interface LessonInjectPayload {\n  source: ProducerMessageSource & {\n    kind: typeof SELF_IMPROVEMENT_SOURCE_KIND\n    plugin: typeof SELF_IMPROVEMENT_PLUGIN\n    form: 'snapshot'\n    sections: Array<{ name: string; text: string }>\n  }\n  content: Array<{ type: 'text'; text: string }>\n}\n\nexport interface PreStepEnter { kind: 'enter'; messages: unknown[]; startsRequestSeries?: true }\nexport type PreStepDecision = { kind: 'reject' } | PreStepEnter\n\nexport interface ReviewSnapshot {\n  memoryAvailable: boolean\n  memoryMessage?: string\n  projectId?: string\n  generation: number\n  storageFailed: boolean\n  lessons: MemoryRecord[]\n  skills: SkillRecord[]\n  /** True while an extract for this session (or any session, if none requested) is queued or in flight. */\n  extracting?: boolean\n}\n\nexport function evidenceWatermark(refs: readonly EvidenceRef[]): string {\n  return [...refs].map(ref => `${ref.sessionId}:${ref.seq}:${ref.kind}`).sort().join('|')\n}\n\nexport function sessionCwd(session: unknown): string | undefined {\n  if (!session || typeof session !== 'object') return undefined\n  const row = session as { meta?: { cwd?: unknown }; header?: { cwd?: unknown } }\n  const cwd = row.meta?.cwd ?? row.header?.cwd\n  return typeof cwd === 'string' ? cwd : undefined\n}\n\nexport function fail(code: string, message: string): RpcResult<never> {\n  return { ok: false, error: { code, message } }\n}\n\nexport const MEMORY_UNAVAILABLE_MESSAGE = '记忆服务不可用。请先单独启用「长期记忆」插件；启用经验学习不会自动打开记忆。'\nexport const MEMORY_UNAVAILABLE_MESSAGE_EN = 'Memory is unavailable. Enable the Long-term Memory plugin separately; turning on Experience Learning does not enable Long-term Memory.'\n","import type { RpcResult } from './contracts.ts'\n\nexport function unwrap<T>(result: RpcResult<T>): T {\n  if (!result.ok) throw new Error(result.error.message)\n  return result.value\n}\n","import { SELF_IMPROVEMENT_PLUGIN, type MemoryRecord, type SkillRecord, type SkillSourceRef } from './contracts.ts'\nimport { isExpired, lessonScopeLabel } from './recall.ts'\n\nfunction yamlScalar(value: string | number | boolean): string {\n  if (typeof value === 'number' || typeof value === 'boolean') return String(value)\n  return JSON.stringify(value)\n}\n\nexport function skillDownloadName(id: string, title: string): string {\n  const slug = title.replace(/[^\\p{L}\\p{N}]+/gu, '-').replace(/^-+|-+$/g, '').slice(0, 40) || 'skill'\n  const safe = id.replace(/[^a-zA-Z0-9_-]/g, '').slice(0, 12) || 'id'\n  return `self-improvement-${slug}-${safe}.md`\n}\n\nexport function skillNameFromTitle(title: string): string {\n  return title.replace(/[^\\p{L}\\p{N}]+/gu, '-').replace(/^-+|-+$/g, '').slice(0, 64).toLowerCase() || 'self-improvement-lesson'\n}\n\nexport function skillDescriptionFromLessons(lessons: readonly MemoryRecord[]): string {\n  const first = lessons[0]\n  const line = (first ? `${first.title}: ${first.content}` : 'Accepted self-improvement lessons.')\n    .replace(/[\\r\\n]+/g, ' ')\n    .trim()\n  return line.slice(0, 200) || 'Accepted self-improvement lessons.'\n}\n\nexport function skillSourcesFromLessons(lessons: readonly MemoryRecord[]): SkillSourceRef[] {\n  return lessons.map(lesson => ({\n    id: lesson.id,\n    revision: lesson.revision,\n    status: lesson.status,\n    scope: lesson.scope,\n    expiresAt: lesson.expiresAt,\n  }))\n}\n\nexport function sourcesMatchLive(\n  sources: readonly SkillSourceRef[],\n  lessons: readonly MemoryRecord[],\n  now: number,\n): boolean {\n  if (sources.length === 0) return false\n  const byId = new Map(lessons.map(lesson => [lesson.id, lesson]))\n  for (const source of sources) {\n    const live = byId.get(source.id)\n    if (!live || live.kind !== 'lesson') return false\n    if (live.revision !== source.revision) return false\n    if (live.status !== 'active' || source.status !== 'active') return false\n    if (isExpired(live, now)) return false\n    if (live.scope.kind !== source.scope.kind) return false\n    if (live.scope.kind === 'project' && source.scope.kind === 'project' && live.scope.projectId !== source.scope.projectId) {\n      return false\n    }\n  }\n  return true\n}\n\nfunction provenanceYaml(lessons: readonly MemoryRecord[]): string[] {\n  const lines: string[] = ['provenance:']\n  for (const lesson of lessons) {\n    lines.push(`  - lessonId: ${yamlScalar(lesson.id)}`)\n    lines.push(`    revision: ${lesson.revision}`)\n    lines.push(`    scope: ${yamlScalar(lessonScopeLabel(lesson))}`)\n    lines.push(`    status: ${yamlScalar(lesson.status)}`)\n    lines.push('    evidence:')\n    if (lesson.evidence.length === 0) {\n      lines.push('      []')\n      continue\n    }\n    for (const ref of lesson.evidence) {\n      lines.push(`      - sessionId: ${yamlScalar(ref.sessionId)}`)\n      lines.push(`        seq: ${ref.seq}`)\n      lines.push(`        kind: ${yamlScalar(ref.kind)}`)\n    }\n  }\n  return lines\n}\n\nexport function renderSkillMarkdown(lessons: readonly MemoryRecord[], generatedAt: number): string {\n  const title = skillTitleFromLessons(lessons)\n  const scopes = [...new Set(lessons.map(lessonScopeLabel))]\n  const lines = [\n    '---',\n    `name: ${yamlScalar(skillNameFromTitle(title))}`,\n    `description: ${yamlScalar(skillDescriptionFromLessons(lessons))}`,\n    'source: self-improvement',\n    `plugin: ${yamlScalar(SELF_IMPROVEMENT_PLUGIN)}`,\n    `generatedAt: ${generatedAt}`,\n    ...provenanceYaml(lessons),\n    '---',\n    '',\n    `# ${title.replace(/[\\r\\n]+/g, ' ')}`,\n    '',\n    '## Instructions',\n    '',\n    'Follow these accepted lessons for the scoped work below. They are a reusable skill proposal. They are not a user request and do not authorize edits to AGENTS.md, scripts, or plugins.',\n    '',\n    `Scope: ${scopes.join(', ') || 'unspecified'}.`,\n    '',\n  ]\n  for (const lesson of lessons) {\n    lines.push(`### ${lesson.title.replace(/[\\r\\n]+/g, ' ')}`)\n    lines.push('')\n    lines.push(lesson.content.replace(/\\r\\n/g, '\\n').trim())\n    lines.push('')\n    if (lesson.exceptions.length) {\n      lines.push('Exceptions for this lesson:')\n      for (const item of lesson.exceptions) lines.push(`- ${item.replace(/[\\r\\n]+/g, ' ')}`)\n      lines.push('')\n    }\n  }\n  lines.push('Downloading this Markdown is a local save of the proposal. It does not install the skill.')\n  lines.push('')\n  return lines.join('\\n')\n}\n\nexport function skillTitleFromLessons(lessons: readonly MemoryRecord[]): string {\n  if (lessons.length === 1) return lessons[0]!.title.slice(0, 160)\n  return `技能草稿（${lessons.length} 条经验）`\n}\n\nexport interface SkillFrontmatter {\n  name: string\n  description: string\n  source: string\n  plugin: string\n  generatedAt: number\n  provenance: Array<{\n    lessonId: string\n    revision: number\n    scope: string\n    status: string\n    evidence: Array<{ sessionId: string; seq: number; kind: string }>\n  }>\n}\n\nfunction parseYamlValue(raw: string): string | number | boolean {\n  const trimmed = raw.trim()\n  if (trimmed === '[]') return trimmed\n  if (trimmed === 'true' || trimmed === 'false') return trimmed === 'true'\n  if (/^-?\\d+(?:\\.\\d+)?$/.test(trimmed)) return Number(trimmed)\n  if (trimmed.startsWith('\"')) {\n    try { return JSON.parse(trimmed) as string } catch { return trimmed.slice(1, -1) }\n  }\n  return trimmed\n}\n\n/** Parses the YAML subset this package emits (quoted scalars, nested provenance lists). */\nexport function parseSkillFrontmatter(markdown: string): SkillFrontmatter {\n  const match = markdown.match(/^---\\r?\\n([\\s\\S]*?)\\r?\\n---\\r?\\n/)\n  if (!match) throw new Error('missing YAML frontmatter')\n  const body = match[1]!\n  const seen = new Set<string>()\n  let name = ''\n  let description = ''\n  let source = ''\n  let plugin = ''\n  let generatedAt = 0\n  const provenance: SkillFrontmatter['provenance'] = []\n  let current: SkillFrontmatter['provenance'][number] | undefined\n  let evidence: { sessionId: string; seq: number; kind: string } | undefined\n  for (const rawLine of body.split(/\\r?\\n/)) {\n    if (!rawLine.trim() || rawLine.trim() === '[]') {\n      if (rawLine.trim() === '[]' && current && current.evidence.length === 0) continue\n      continue\n    }\n    const keyMatch = rawLine.match(/^([A-Za-z][A-Za-z0-9]*)\\s*:\\s*(.*)$/)\n    if (keyMatch && !rawLine.startsWith(' ')) {\n      const key = keyMatch[1]!\n      if (seen.has(key) && key !== 'provenance') throw new Error(`duplicate YAML key ${key}`)\n      seen.add(key)\n      const value = parseYamlValue(keyMatch[2] ?? '')\n      if (key === 'name') name = String(value)\n      else if (key === 'description') description = String(value)\n      else if (key === 'source') source = String(value)\n      else if (key === 'plugin') plugin = String(value)\n      else if (key === 'generatedAt') generatedAt = Number(value)\n      continue\n    }\n    const item = rawLine.match(/^\\s{2}-\\s+lessonId:\\s*(.*)$/)\n    if (item) {\n      current = { lessonId: String(parseYamlValue(item[1] ?? '')), revision: 0, scope: '', status: '', evidence: [] }\n      provenance.push(current)\n      evidence = undefined\n      continue\n    }\n    if (!current) continue\n    const field = rawLine.match(/^\\s{4}(revision|scope|status|evidence)\\s*:\\s*(.*)$/)\n    if (field) {\n      const key = field[1]!\n      if (key === 'revision') current.revision = Number(parseYamlValue(field[2] ?? ''))\n      else if (key === 'scope') current.scope = String(parseYamlValue(field[2] ?? ''))\n      else if (key === 'status') current.status = String(parseYamlValue(field[2] ?? ''))\n      continue\n    }\n    const evidenceItem = rawLine.match(/^\\s{6}-\\s+sessionId:\\s*(.*)$/)\n    if (evidenceItem) {\n      evidence = { sessionId: String(parseYamlValue(evidenceItem[1] ?? '')), seq: 0, kind: '' }\n      current.evidence.push(evidence)\n      continue\n    }\n    const evidenceField = rawLine.match(/^\\s{8}(seq|kind)\\s*:\\s*(.*)$/)\n    if (evidenceField && evidence) {\n      if (evidenceField[1] === 'seq') evidence.seq = Number(parseYamlValue(evidenceField[2] ?? ''))\n      else evidence.kind = String(parseYamlValue(evidenceField[2] ?? ''))\n    }\n  }\n  if (!name || !description) throw new Error('skill frontmatter needs name and description')\n  return { name, description, source, plugin, generatedAt, provenance }\n}\n\nexport function downloadMarkdown(\n  filename: string,\n  markdown: string,\n  doc: Pick<Document, 'createElement' | 'body'> | undefined = typeof document === 'undefined' ? undefined : document,\n): boolean {\n  if (!doc) return false\n  const blob = new Blob([markdown], { type: 'text/markdown;charset=utf-8' })\n  const url = URL.createObjectURL(blob)\n  const anchor = doc.createElement('a')\n  anchor.href = url\n  anchor.setAttribute('download', filename)\n  anchor.rel = 'noopener'\n  doc.body.appendChild(anchor)\n  anchor.click()\n  anchor.remove()\n  URL.revokeObjectURL(url)\n  return true\n}\n\nexport function exportRevocationCopy(locale: 'zh' | 'en'): string {\n  return locale === 'en'\n    ? 'Export record revoked. Already downloaded files are not recalled.'\n    : '已撤销下载记录。已下载的文件不会被收回或删除。'\n}\n\nexport function skillExportStateLabel(record: Pick<SkillRecord, 'exportState'>, locale: 'zh' | 'en'): string {\n  if (record.exportState === 'recorded') return locale === 'en' ? 'Download recorded' : '已记录下载'\n  if (record.exportState === 'revoked') return locale === 'en' ? 'Download record revoked' : '已撤销下载记录'\n  return locale === 'en' ? 'Not downloaded' : '未下载'\n}\n","import type { ReviewSnapshot, RpcResult, SkillRecord } from './contracts.ts'\nimport { unwrap } from './rpc-result.ts'\nimport { downloadMarkdown } from './skills.ts'\n\nexport type ReviewGenerationGate = {\n  current: () => number\n  next: () => number\n  isCurrent: (token: number) => boolean\n}\n\nexport function createReviewGeneration(start = 0): ReviewGenerationGate {\n  let current = start\n  return {\n    current: () => current,\n    next: () => {\n      current += 1\n      return current\n    },\n    isCurrent: token => token === current,\n  }\n}\n\nexport function reviewRequestStillCurrent(input: {\n  token: number\n  gate: Pick<ReviewGenerationGate, 'isCurrent'>\n  signal: AbortSignal\n  sessionId: string\n  viewSessionId: string\n}): boolean {\n  return input.gate.isCurrent(input.token)\n    && !input.signal.aborted\n    && input.sessionId === input.viewSessionId\n}\n\nexport type ReviewRequest = {\n  sessionId: string\n  token: number\n  signal: AbortSignal\n  controller: AbortController\n}\n\n/** Capture session, generation token, and abort lifetime before the first await. */\nexport function beginReviewRequest(\n  gate: ReviewGenerationGate,\n  sessionId: string,\n  previous?: AbortController | null,\n): ReviewRequest {\n  previous?.abort()\n  const controller = new AbortController()\n  const captured = sessionId\n  const token = gate.next()\n  return { sessionId: captured, token, signal: controller.signal, controller }\n}\n\nexport function disposeReviewRequest(gate: ReviewGenerationGate, controller: AbortController): void {\n  controller.abort()\n  gate.next()\n}\n\nexport type ReviewRpc = (endpoint: string, payload: unknown, signal?: AbortSignal) => Promise<unknown>\n\nexport function shouldSkipReviewRefresh(input: { busy: boolean; editing?: boolean }): boolean {\n  return input.busy || input.editing === true\n}\n\nexport async function loadReviewSnapshot(input: {\n  rpc: ReviewRpc\n  sessionId: string\n  token: number\n  gate: Pick<ReviewGenerationGate, 'isCurrent'>\n  signal: AbortSignal\n  viewSessionId: () => string\n}): Promise<ReviewSnapshot | undefined> {\n  const captured = input.sessionId\n  const raw = await input.rpc('status', { sessionId: captured }, input.signal)\n  if (!reviewRequestStillCurrent({\n    token: input.token, gate: input.gate, signal: input.signal, sessionId: captured, viewSessionId: input.viewSessionId(),\n  })) return undefined\n  return unwrap(raw as RpcResult<ReviewSnapshot>)\n}\n\n/** Read-only status peek; uses an independent signal so it cannot abort an in-flight write. */\nexport async function peekReviewSnapshot(input: {\n  rpc: ReviewRpc\n  sessionId: string\n  token: number\n  gate: Pick<ReviewGenerationGate, 'isCurrent'>\n  viewSessionId: () => string\n  busy: () => boolean\n  editing?: () => boolean\n}): Promise<ReviewSnapshot | undefined> {\n  if (shouldSkipReviewRefresh({ busy: input.busy(), editing: input.editing?.() === true })) return undefined\n  const token = input.token\n  if (!input.gate.isCurrent(token) || token === 0) return undefined\n  const next = await loadReviewSnapshot({\n    rpc: input.rpc,\n    sessionId: input.sessionId,\n    token,\n    gate: input.gate,\n    signal: new AbortController().signal,\n    viewSessionId: input.viewSessionId,\n  })\n  if (!next) return undefined\n  if (shouldSkipReviewRefresh({ busy: input.busy(), editing: input.editing?.() === true })) return undefined\n  return next\n}\n\nexport async function exportSkillIfCurrent(input: {\n  rpc: ReviewRpc\n  sessionId: string\n  token: number\n  gate: Pick<ReviewGenerationGate, 'isCurrent'>\n  signal: AbortSignal\n  viewSessionId: () => string\n  record: Pick<SkillRecord, 'id' | 'revision'>\n  download?: typeof downloadMarkdown\n}): Promise<'recorded' | 'stale'> {\n  const captured = input.sessionId\n  const still = () => reviewRequestStillCurrent({\n    token: input.token, gate: input.gate, signal: input.signal, sessionId: captured, viewSessionId: input.viewSessionId(),\n  })\n  const prepared = unwrap(await input.rpc('skill.export', {\n    id: input.record.id, expectedRevision: input.record.revision, sessionId: captured,\n  }, input.signal) as RpcResult<{ filename: string; markdown: string; skill: SkillRecord }>)\n  if (!still()) return 'stale'\n  const download = input.download ?? downloadMarkdown\n  const started = download(prepared.filename, prepared.markdown)\n  if (!still()) return 'stale'\n  if (!started) throw new Error('未能开始下载。')\n  unwrap(await input.rpc('skill.exported', {\n    id: prepared.skill.id, expectedRevision: prepared.skill.revision, filename: prepared.filename, sessionId: captured,\n  }, input.signal) as RpcResult<SkillRecord>)\n  if (!still()) return 'stale'\n  return 'recorded'\n}\n","import type { Context } from '@deepseek-ai/cordis'\nimport { Button, Checkbox, PathLabel, SegmentedTabs, Tag, type TagTone } from '@deepseek-ai/dsh-client-ui-primitives'\nimport { useFeatureRefresh, useNativeSeat, type NativeSurfaceClient } from '@klarkxy/dsh-plugin-kit/client-utils'\nimport {\n  modelMenuChoiceKey, modelMenuEffortOptions, normalizeModelMenuRoute, parseModelMenuChoiceKey, parseModelMenuChoices,\n  type ModelMenuChoice, type ModelMenuRoute,\n} from '@klarkxy/dsh-plugin-kit/model-menu'\nimport { officialUiCss } from '@klarkxy/dsh-plugin-kit/official-ui'\nimport { useEffect, useId, useRef, useState } from 'react'\nimport {\n  MEMORY_UNAVAILABLE_MESSAGE, MEMORY_UNAVAILABLE_MESSAGE_EN,\n  SELF_IMPROVEMENT_PLUGIN, SELF_IMPROVEMENT_REVIEW_SERVICE, SELF_IMPROVEMENT_RPC_CHANNEL,\n  defaultSettings, type MemoryRecord, type ReviewSnapshot, type RpcResult, type SelfImprovementSettings,\n  type SkillRecord,\n} from './contracts.ts'\nimport {\n  beginReviewRequest, createReviewGeneration, disposeReviewRequest, exportSkillIfCurrent,\n  loadReviewSnapshot, peekReviewSnapshot, reviewRequestStillCurrent,\n} from './review-lifetime.ts'\nimport { unwrap } from './rpc-result.ts'\nimport { exportRevocationCopy, skillExportStateLabel } from './skills.ts'\n\nexport const name = 'dsh-self-improvement-client'\nexport const inject = ['slots', 'connection', 'remote', 'remote.session', 'sessions', 'locale', 'uiWorkspace', 'uiSession'] as const\nexport { unwrap }\nexport {\n  beginReviewRequest, createReviewGeneration, disposeReviewRequest, exportSkillIfCurrent,\n  loadReviewSnapshot, peekReviewSnapshot, reviewRequestStillCurrent, shouldSkipReviewRefresh,\n} from './review-lifetime.ts'\n\ntype Client = NativeSurfaceClient & {\n  connection: {\n    rpc: { call(channel: string, endpoint: string, payload: unknown, signal?: AbortSignal): Promise<unknown> }\n    generation?: { subscribe(listener: () => void): () => void }\n  }\n  remote?: { session?: { modelCatalog?: () => Promise<unknown> } }\n  slots: {\n    inject(key: string, callback: () => unknown): () => void\n    register(spec: { name: string; id: string; label: string; order: number } | { name: string; key: string }, render: unknown): () => void\n  }\n}\n\nexport type SeatProps = { sessionId: string; locale: 'zh' | 'en'; hidden: boolean }\n\nexport function parseSeatProps(props: unknown): SeatProps {\n  const row = props && typeof props === 'object' ? props as Record<string, unknown> : {}\n  const nested = row.owner && typeof row.owner === 'object' ? row.owner as Record<string, unknown> : undefined\n  const sessionId = typeof row.sessionId === 'string' && row.sessionId\n    ? row.sessionId\n    : typeof nested?.sessionId === 'string' ? nested.sessionId : ''\n  const locale = row.locale === 'en' || nested?.locale === 'en' ? 'en' : 'zh'\n  const hidden = row.hidden === true || nested?.hidden === true\n  return { sessionId, locale, hidden }\n}\n\nexport function memoryUnavailableCopy(locale: 'zh' | 'en'): string {\n  return locale === 'en' ? MEMORY_UNAVAILABLE_MESSAGE_EN : MEMORY_UNAVAILABLE_MESSAGE\n}\n\nfunction statusLabel(status: MemoryRecord['status'], locale: 'zh' | 'en'): string {\n  const zh = { candidate: '候选', active: '已生效', rejected: '已拒绝', superseded: '已替代', revoked: '已撤销', deleted: '已删除' }\n  const en = { candidate: 'Candidate', active: 'Active', rejected: 'Rejected', superseded: 'Superseded', revoked: 'Revoked', deleted: 'Deleted' }\n  return (locale === 'en' ? en : zh)[status]\n}\n\nexport function skillStatusLabel(status: SkillRecord['status'], locale: 'zh' | 'en'): string {\n  const zh = { preview: '草稿', accepted: '已接受', rejected: '已拒绝', revoked: '已撤销' }\n  const en = { preview: 'Draft', accepted: 'Accepted', rejected: 'Rejected', revoked: 'Revoked' }\n  return (locale === 'en' ? en : zh)[status]\n}\n\n/** Readable evidence line: where it came from and a short session id instead of the full raw id. */\nexport function evidenceLabel(ref: MemoryRecord['evidence'][number], locale: 'zh' | 'en'): string {\n  const kinds = {\n    user: ['你的消息', 'Your message'], tool: ['工具结果', 'Tool result'], turn: ['对话回合', 'Chat turn'], manual: ['手动添加', 'Added manually'],\n  } as const\n  const kind = kinds[ref.kind]?.[locale === 'en' ? 1 : 0] ?? ref.kind\n  if (ref.kind === 'manual') return kind\n  const session = ref.sessionId.length > 8 ? ref.sessionId.slice(0, 8) : ref.sessionId\n  return locale === 'en' ? `${kind} #${ref.seq} · session ${session}` : `${kind} #${ref.seq} · 会话 ${session}`\n}\n\n/** A record's lifecycle reads as a state, so it wears the tag of that state. */\nfunction statusTone(status: MemoryRecord['status'] | SkillRecord['status']): TagTone {\n  switch (status) {\n    case 'active':\n    case 'accepted': return 'success'\n    case 'candidate':\n    case 'preview': return 'info'\n    case 'rejected': return 'warning'\n    case 'revoked': return 'danger'\n    default: return 'quiet'\n  }\n}\n\nconst emptySnapshot = (): ReviewSnapshot => ({\n  memoryAvailable: false, memoryMessage: MEMORY_UNAVAILABLE_MESSAGE,\n  generation: 0, storageFailed: false, lessons: [], skills: [],\n})\n\nfunction LessonEvidence({ record, locale }: { record: MemoryRecord; locale: 'zh' | 'en' }) {\n  return record.evidence.length === 0\n    ? <p className=\"dsh-ui-hint\">{locale === 'en' ? 'No evidence recorded.' : '没有记录依据。'}</p>\n    : <ul className=\"si-evidence\" aria-label={locale === 'en' ? 'Evidence' : '依据'}>\n      {record.evidence.map(ref => (\n        <li key={`${ref.sessionId}:${ref.seq}:${ref.kind}`} title={`${ref.kind} · ${ref.sessionId}#${ref.seq}`}>\n          {evidenceLabel(ref, locale)}{ref.excerpt ? ` — ${ref.excerpt}` : ''}\n        </li>\n      ))}\n    </ul>\n}\n\nfunction ConfirmButton(props: { label: string; confirmLabel: string; disabled?: boolean; onConfirm(): void }) {\n  const [armed, setArmed] = useState(false)\n  const timer = useRef<ReturnType<typeof setTimeout>>(undefined)\n  useEffect(() => () => clearTimeout(timer.current), [])\n  function disarm() {\n    clearTimeout(timer.current)\n    setArmed(false)\n  }\n  return <Button variant=\"outline\" size=\"sm\" className=\"si-danger\" disabled={props.disabled} data-armed={armed || undefined}\n    onClick={() => {\n      if (!armed) {\n        setArmed(true)\n        timer.current = setTimeout(() => setArmed(false), 3000)\n        return\n      }\n      disarm()\n      props.onConfirm()\n    }}\n    onBlur={disarm}>{armed ? props.confirmLabel : props.label}</Button>\n}\n\nfunction LessonList(props: {\n  lessons: MemoryRecord[]\n  locale: 'zh' | 'en'\n  busy: boolean\n  projectId?: string\n  onAccept(record: MemoryRecord): void\n  onPromote(record: MemoryRecord): void\n  onReject(record: MemoryRecord): void\n  onRevoke(record: MemoryRecord): void\n}) {\n  const { lessons, locale, busy, projectId, onAccept, onPromote, onReject, onRevoke } = props\n  if (lessons.length === 0) {\n    return <p className=\"dsh-ui-empty\">{locale === 'en' ? 'No methods yet.' : '还没有经验。'}</p>\n  }\n  return <ol className=\"si-list\">\n    {lessons.map(record => {\n      const candidate = record.status === 'candidate'\n      const active = record.status === 'active'\n      const foreignProject = record.scope.kind === 'project' && Boolean(projectId) && record.scope.projectId !== projectId\n      const scope = record.scope.kind === 'global'\n        ? (locale === 'en' ? 'Global' : '全局')\n        : <PathLabel path={record.scope.projectId} className=\"dsh-ui-truncate\" />\n      return <li key={record.id} className=\"si-card dsh-ui-card dsh-ui-card--flat\" data-status={record.status}>\n        <header className=\"dsh-ui-row-wrap\">\n          <h3 className=\"dsh-ui-title\">{record.title}</h3>\n          <span className=\"dsh-ui-row\">\n            <Tag tone={statusTone(record.status)}>{statusLabel(record.status, locale)}</Tag>\n            <span className=\"dsh-ui-meta dsh-ui-row\">· {scope}</span>\n          </span>\n        </header>\n        <p className=\"dsh-ui-compact dsh-ui-wrap\">{record.content}</p>\n        <LessonEvidence record={record} locale={locale} />\n        <div className=\"dsh-ui-actions\">\n          {candidate && !foreignProject ? <Button variant=\"outline\" size=\"sm\" disabled={busy} onClick={() => onAccept(record)}>\n            {locale === 'en' ? 'Accept in scope' : '在本范围采纳'}\n          </Button> : null}\n          {active && record.scope.kind === 'project' && !foreignProject ? <Button variant=\"outline\" size=\"sm\" disabled={busy} onClick={() => onPromote(record)}>\n            {locale === 'en' ? 'Promote to global' : '提升为全局'}\n          </Button> : null}\n          {candidate ? <ConfirmButton disabled={busy}\n            label={locale === 'en' ? 'Reject' : '拒绝'}\n            confirmLabel={locale === 'en' ? 'Confirm reject?' : '确认拒绝？'}\n            onConfirm={() => onReject(record)} /> : null}\n          {active ? <ConfirmButton disabled={busy}\n            label={locale === 'en' ? 'Revoke' : '撤销'}\n            confirmLabel={locale === 'en' ? 'Confirm revoke?' : '确认撤销？'}\n            onConfirm={() => onRevoke(record)} /> : null}\n          {foreignProject\n            ? <p className=\"dsh-ui-hint\">{locale === 'en' ? 'From another project; it can’t be changed here.' : '来自其他项目的经验，此处不能操作。'}</p>\n            : null}\n        </div>\n      </li>\n    })}\n  </ol>\n}\n\nfunction SkillList(props: {\n  skills: SkillRecord[]\n  locale: 'zh' | 'en'\n  busy: boolean\n  onAccept(record: SkillRecord): void\n  onReject(record: SkillRecord): void\n  onRevoke(record: SkillRecord): void\n  onExport(record: SkillRecord): void\n  onUnexport(record: SkillRecord): void\n}) {\n  const { skills, locale, busy } = props\n  if (skills.length === 0) {\n    return <p className=\"dsh-ui-empty\">{locale === 'en' ? 'No skill drafts.' : '没有技能草稿。'}</p>\n  }\n  return <ol className=\"si-list\">\n    {skills.map(record => (\n      <li key={record.id} className=\"si-card dsh-ui-card dsh-ui-card--flat\" data-skill-status={record.status} data-export={record.exportState}>\n        <header className=\"dsh-ui-row-wrap\">\n          <h3 className=\"dsh-ui-title\">{record.title}</h3>\n          <span className=\"dsh-ui-row\">\n            <Tag tone={statusTone(record.status)}>{skillStatusLabel(record.status, locale)}</Tag>\n            <span className=\"dsh-ui-meta\">· {skillExportStateLabel(record, locale)}</span>\n          </span>\n        </header>\n        <pre className=\"dsh-ui-code si-preview\">{record.markdown}</pre>\n        <div className=\"dsh-ui-actions\">\n          {record.status === 'preview' ? <Button variant=\"outline\" size=\"sm\" disabled={busy} onClick={() => props.onAccept(record)}>\n            {locale === 'en' ? 'Accept draft' : '接受草稿'}\n          </Button> : null}\n          {record.status === 'preview' ? <ConfirmButton disabled={busy}\n            label={locale === 'en' ? 'Reject draft' : '拒绝草稿'}\n            confirmLabel={locale === 'en' ? 'Confirm reject?' : '确认拒绝？'}\n            onConfirm={() => props.onReject(record)} /> : null}\n          {record.status === 'accepted' || record.status === 'preview' ? <Button variant=\"outline\" size=\"sm\" disabled={busy} onClick={() => props.onExport(record)}>\n            {locale === 'en' ? 'Download Markdown' : '下载 Markdown'}\n          </Button> : null}\n          {record.exportState === 'recorded' ? <ConfirmButton disabled={busy}\n            label={locale === 'en' ? 'Revoke download record' : '撤销下载记录'}\n            confirmLabel={locale === 'en' ? 'Confirm revoke?' : '确认撤销？'}\n            onConfirm={() => props.onUnexport(record)} /> : null}\n          {record.status === 'accepted' ? <ConfirmButton disabled={busy}\n            label={locale === 'en' ? 'Revoke skill' : '撤销技能'}\n            confirmLabel={locale === 'en' ? 'Confirm revoke?' : '确认撤销？'}\n            onConfirm={() => props.onRevoke(record)} /> : null}\n        </div>\n      </li>\n    ))}\n  </ol>\n}\n\nexport function ReviewPanel({ client, sessionId, locale }: {\n  client: Client\n  sessionId: string\n  locale: 'zh' | 'en'\n}) {\n  const tabsId = useId()\n  const gate = useRef(createReviewGeneration())\n  const sessionRef = useRef(sessionId)\n  const workRef = useRef<AbortController | null>(null)\n  sessionRef.current = sessionId\n  const [tab, setTab] = useState<'lessons' | 'skills'>('lessons')\n  const [snapshot, setSnapshot] = useState<ReviewSnapshot>()\n  const [busy, setBusy] = useState(false)\n  const [note, setNote] = useState('')\n  const [error, setError] = useState('')\n  const [selected, setSelected] = useState<string[]>([])\n  const busyRef = useRef(false)\n  busyRef.current = busy\n\n  function rpc(endpoint: string, payload: unknown, signal?: AbortSignal): Promise<unknown> {\n    return client.connection.rpc.call(SELF_IMPROVEMENT_RPC_CHANNEL, endpoint, payload, signal)\n  }\n  async function call<T>(endpoint: string, payload: unknown = {}): Promise<T> {\n    return unwrap(await rpc(endpoint, payload) as RpcResult<T>)\n  }\n\n  useEffect(() => {\n    const request = beginReviewRequest(gate.current, sessionId, workRef.current)\n    workRef.current = request.controller\n    setError('')\n    setNote('')\n    void loadReviewSnapshot({\n      rpc,\n      sessionId: request.sessionId,\n      token: request.token,\n      gate: gate.current,\n      signal: request.signal,\n      viewSessionId: () => sessionRef.current,\n    }).then(next => {\n      if (next === undefined) return\n      setSnapshot(next)\n    }).catch(cause => {\n      if (!reviewRequestStillCurrent({\n        token: request.token,\n        gate: gate.current,\n        signal: request.signal,\n        sessionId: request.sessionId,\n        viewSessionId: sessionRef.current,\n      })) return\n      setError(cause instanceof Error ? cause.message : (locale === 'en' ? 'Unable to read Experience Learning state.' : '无法读取经验学习状态。'))\n    })\n    return () => disposeReviewRequest(gate.current, workRef.current ?? request.controller)\n  }, [client, sessionId, locale])\n\n  useFeatureRefresh(client, sessionId, () => {\n    void peekReviewSnapshot({\n      rpc, sessionId: sessionRef.current, token: gate.current.current(), gate: gate.current,\n      viewSessionId: () => sessionRef.current, busy: () => busyRef.current, editing: () => false,\n    }).then(next => { if (next) setSnapshot(next) }).catch(() => {})\n  }, snapshot?.extracting === true, true)\n\n  async function action(run: (ctx: { sessionId: string; token: number; signal: AbortSignal }) => Promise<void>) {\n    const request = beginReviewRequest(gate.current, sessionId, workRef.current)\n    workRef.current = request.controller\n    setBusy(true); setNote(''); setError('')\n    const still = () => reviewRequestStillCurrent({\n      token: request.token,\n      gate: gate.current,\n      signal: request.signal,\n      sessionId: request.sessionId,\n      viewSessionId: sessionRef.current,\n    })\n    try {\n      await run({ sessionId: request.sessionId, token: request.token, signal: request.signal })\n    } catch (cause) {\n      if (!still()) return\n      setError(cause instanceof Error ? cause.message : (locale === 'en' ? 'Action failed.' : '操作失败。'))\n      const next = await loadReviewSnapshot({\n        rpc,\n        sessionId: request.sessionId,\n        token: request.token,\n        gate: gate.current,\n        signal: request.signal,\n        viewSessionId: () => sessionRef.current,\n      }).catch(() => undefined)\n      if (next && still()) setSnapshot(next)\n    } finally {\n      if (still()) setBusy(false)\n    }\n  }\n\n  const data = snapshot ?? emptySnapshot()\n  const visibleLessons = data.lessons\n\n  const body = <>\n    {error ? <p role=\"alert\" className=\"dsh-ui-error dsh-ui-wrap\">{error}</p> : null}\n    {note ? <p role=\"status\" className=\"dsh-ui-notice\">{note}</p> : null}\n    {data.storageFailed ? <p role=\"alert\" className=\"dsh-ui-banner dsh-ui-banner--danger\">{locale === 'en' ? 'Save failed; previous state was kept.' : '保存失败，已保留上一次成功的状态。'}</p> : null}\n    {data.memoryAvailable ? null : <p role=\"alert\" className=\"dsh-ui-banner dsh-ui-banner--danger\">{memoryUnavailableCopy(locale)}</p>}\n    <SegmentedTabs<'lessons' | 'skills'>\n      value={tab}\n      onChange={setTab}\n      label={locale === 'en' ? 'Experience Learning' : '经验学习'}\n      items={[\n        {\n          value: 'lessons',\n          label: locale === 'en' ? 'Methods' : '经验',\n          id: `${tabsId}-lessons-tab`,\n          panelId: `${tabsId}-lessons-panel`,\n        },\n        {\n          value: 'skills',\n          label: locale === 'en' ? 'Skill drafts' : '技能草稿',\n          id: `${tabsId}-skills-tab`,\n          panelId: `${tabsId}-skills-panel`,\n        },\n      ]}\n    />\n    <div role=\"tabpanel\" id={`${tabsId}-lessons-panel`}\n      aria-labelledby={`${tabsId}-lessons-tab`} hidden={tab !== 'lessons'} tabIndex={0}>\n      <p className=\"dsh-ui-help\">{locale === 'en'\n        ? 'Requested methods apply at once; observed ones need acceptance. Vocabulary and recent activity belong to Long-term Memory.'\n        : '明确要求的做法直接生效，观察到的须先采纳；用语与近期状态由长期记忆管理。'}</p>\n      {sessionId ? <div className=\"dsh-ui-actions\"><Button variant=\"primary\" size=\"md\" disabled={busy || !data.memoryAvailable} onClick={() => void action(async ctx => {\n        if (!reviewRequestStillCurrent({\n          token: ctx.token, gate: gate.current, signal: ctx.signal, sessionId: ctx.sessionId, viewSessionId: sessionRef.current,\n        })) return\n        await call('extract', { sessionId: ctx.sessionId })\n        const next = await loadReviewSnapshot({\n          rpc, sessionId: ctx.sessionId, token: ctx.token, gate: gate.current, signal: ctx.signal, viewSessionId: () => sessionRef.current,\n        })\n        if (!next) return\n        setSnapshot(next)\n        setNote(locale === 'en' ? 'Attempted extraction from explicit evidence.' : '已按明确依据尝试摘录。')\n      })}>{locale === 'en' ? 'Extract from session' : '从本会话摘录'}</Button></div> : null}\n      <LessonList\n        lessons={visibleLessons}\n        locale={locale}\n        busy={busy || !data.memoryAvailable}\n        projectId={data.projectId}\n        onAccept={record => void action(async ctx => {\n          await call('accept', { id: record.id, expectedRevision: record.revision, scope: 'project', sessionId: ctx.sessionId })\n          const next = await loadReviewSnapshot({\n            rpc, sessionId: ctx.sessionId, token: ctx.token, gate: gate.current, signal: ctx.signal, viewSessionId: () => sessionRef.current,\n          })\n          if (next) setSnapshot(next)\n        })}\n        onPromote={record => void action(async ctx => {\n          await call('accept', { id: record.id, expectedRevision: record.revision, scope: 'global', sessionId: ctx.sessionId })\n          const next = await loadReviewSnapshot({\n            rpc, sessionId: ctx.sessionId, token: ctx.token, gate: gate.current, signal: ctx.signal, viewSessionId: () => sessionRef.current,\n          })\n          if (next) setSnapshot(next)\n        })}\n        onReject={record => void action(async ctx => {\n          await call('reject', { id: record.id, expectedRevision: record.revision, sessionId: ctx.sessionId })\n          const next = await loadReviewSnapshot({\n            rpc, sessionId: ctx.sessionId, token: ctx.token, gate: gate.current, signal: ctx.signal, viewSessionId: () => sessionRef.current,\n          })\n          if (next) setSnapshot(next)\n        })}\n        onRevoke={record => void action(async ctx => {\n          await call('revoke', { id: record.id, expectedRevision: record.revision, sessionId: ctx.sessionId })\n          const next = await loadReviewSnapshot({\n            rpc, sessionId: ctx.sessionId, token: ctx.token, gate: gate.current, signal: ctx.signal, viewSessionId: () => sessionRef.current,\n          })\n          if (next) setSnapshot(next)\n        })}\n      />\n    </div>\n    <div role=\"tabpanel\" id={`${tabsId}-skills-panel`} aria-labelledby={`${tabsId}-skills-tab`} hidden={tab !== 'skills'} tabIndex={0}>\n      {skillManagement()}\n    </div>\n  </>\n\n  function skillManagement() {\n    return <>\n      <fieldset className=\"si-lessons\" disabled={busy || !data.memoryAvailable}>\n        <legend className=\"dsh-ui-label\">{locale === 'en' ? 'From active methods' : '选取已生效的经验'}</legend>\n        {data.lessons.filter(record => record.status === 'active').map(record => (\n          <Checkbox key={record.id} className=\"si-lesson-option\"\n            checked={selected.includes(record.id)}\n            disabled={busy || !data.memoryAvailable}\n            label={record.title}\n            onChange={next => setSelected(current => next ? [...current, record.id] : current.filter(id => id !== record.id))} />\n        ))}\n        {data.lessons.some(record => record.status === 'active') ? null\n          : <p className=\"dsh-ui-hint\">{locale === 'en' ? 'No active methods yet.' : '还没有已生效的经验。'}</p>}\n      </fieldset>\n      <div className=\"dsh-ui-actions\">\n        <Button variant=\"primary\" size=\"md\" disabled={busy || selected.length === 0 || !data.memoryAvailable} onClick={() => void action(async ctx => {\n          await call('skill.preview', { lessonIds: selected, sessionId: ctx.sessionId })\n          const next = await loadReviewSnapshot({\n            rpc, sessionId: ctx.sessionId, token: ctx.token, gate: gate.current, signal: ctx.signal, viewSessionId: () => sessionRef.current,\n          })\n          if (!next) return\n          setSnapshot(next)\n          setTab('skills')\n        })}>{locale === 'en' ? 'Preview skill Markdown' : '预览技能 Markdown'}</Button>\n      </div>\n      <SkillList\n        skills={data.skills}\n        locale={locale}\n        busy={busy}\n        onAccept={record => void action(async ctx => {\n          await call('skill.accept', { id: record.id, expectedRevision: record.revision, sessionId: ctx.sessionId })\n          const next = await loadReviewSnapshot({\n            rpc, sessionId: ctx.sessionId, token: ctx.token, gate: gate.current, signal: ctx.signal, viewSessionId: () => sessionRef.current,\n          })\n          if (next) setSnapshot(next)\n        })}\n        onReject={record => void action(async ctx => {\n          await call('skill.reject', { id: record.id, expectedRevision: record.revision, sessionId: ctx.sessionId })\n          const next = await loadReviewSnapshot({\n            rpc, sessionId: ctx.sessionId, token: ctx.token, gate: gate.current, signal: ctx.signal, viewSessionId: () => sessionRef.current,\n          })\n          if (next) setSnapshot(next)\n        })}\n        onRevoke={record => void action(async ctx => {\n          await call('skill.revoke', { id: record.id, expectedRevision: record.revision, sessionId: ctx.sessionId })\n          const next = await loadReviewSnapshot({\n            rpc, sessionId: ctx.sessionId, token: ctx.token, gate: gate.current, signal: ctx.signal, viewSessionId: () => sessionRef.current,\n          })\n          if (next) setSnapshot(next)\n        })}\n        onExport={record => void action(async ctx => {\n          const result = await exportSkillIfCurrent({\n            rpc, sessionId: ctx.sessionId, token: ctx.token, gate: gate.current, signal: ctx.signal,\n            viewSessionId: () => sessionRef.current, record,\n          })\n          if (result !== 'recorded') return\n          const next = await loadReviewSnapshot({\n            rpc, sessionId: ctx.sessionId, token: ctx.token, gate: gate.current, signal: ctx.signal, viewSessionId: () => sessionRef.current,\n          })\n          if (!next) return\n          setSnapshot(next)\n          setNote(locale === 'en' ? 'Browser download started. Destination is chosen in the save dialog.' : '已开始浏览器下载，保存位置由系统对话框决定。')\n        })}\n        onUnexport={record => void action(async ctx => {\n          await call('skill.unexport', { id: record.id, expectedRevision: record.revision, sessionId: ctx.sessionId })\n          const next = await loadReviewSnapshot({\n            rpc, sessionId: ctx.sessionId, token: ctx.token, gate: gate.current, signal: ctx.signal, viewSessionId: () => sessionRef.current,\n          })\n          if (!next) return\n          setSnapshot(next)\n          setNote(exportRevocationCopy(locale))\n        })}\n      />\n    </>\n  }\n\n  return <section className=\"si-settings dsh-ui-panel\" data-testid=\"self-improvement-settings\" data-session={sessionId || undefined}>\n    {sessionId ? body : <p className=\"dsh-ui-empty\">{locale === 'en'\n      ? 'Open a session to review methods for its project.'\n      : '打开会话后可审阅其项目经验。'}</p>}\n  </section>\n}\n\n/* The contract owns the type tiers, the card, the field, the button row, the\n * banner and the focus ring. What is left is this panel's own geometry: the\n * reading width, the stacked record cards, the evidence indent, the lesson\n * picker's option list and the scroll box around a skill's Markdown. */\nconst styles = `${officialUiCss('si-root')}\n.si-root { max-width: 760px; }\n.si-list { margin: 0; padding: 0; list-style: none; display: grid; gap: 8px; }\n.si-evidence {\n  margin: 0;\n  padding-inline-start: 18px;\n  display: grid;\n  gap: 2px;\n  font-size: 12px;\n  line-height: 18px;\n  color: var(--dsw-alias-label-tertiary);\n  overflow-wrap: anywhere;\n}\n.si-preview { margin: 0; max-height: 240px; overflow: auto; }\n.si-lessons {\n  margin: 0;\n  border: 0;\n  border-top: 0.5px solid var(--dsw-alias-border-l2);\n  padding: 12px 0 0;\n  display: grid;\n  gap: 6px;\n  min-width: 0;\n}\n.si-lessons > legend { padding: 0 8px 0 0; }\n.si-lesson-option { padding: 2px 0; }\n/* A destructive row only shows its colour once the pointer is on it or the\n * two-step confirmation is armed; the resting appearance stays the outlined\n * one every other action uses. */\n.si-danger:hover:not(:disabled),\n.si-danger[data-armed] {\n  color: var(--dsw-alias-state-error-primary);\n  border-color: var(--dsw-alias-state-error-primary);\n}\n.si-danger:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover-danger); }\n`\n\nexport function reviewPanelKey(sessionId: string, locale: 'zh' | 'en'): string {\n  return `${sessionId}:${locale}`\n}\n\n/** Plugin-page model menu for the one extraction purpose this plugin registers. */\nexport function SelfImprovementModelMenu({ client, locale }: { client: Client; locale: 'zh' | 'en' }) {\n  const optionsId = useId()\n  const [settings, setSettings] = useState<SelfImprovementSettings>()\n  const [choices, setChoices] = useState<ModelMenuChoice[]>([])\n  const [busy, setBusy] = useState(false)\n  const [error, setError] = useState('')\n  const [note, setNote] = useState('')\n  const route: ModelMenuRoute = settings?.model ?? defaultSettings().model\n  const selected = choices.find(item => item.provider === route.provider && item.model === route.model)\n  const efforts = modelMenuEffortOptions(selected, route.reasoningEffort)\n\n  // Load once per client/locale. Saving must not refetch: the catalog is parsed\n  // against the saved route read here, and later saves only update `settings`.\n  useEffect(() => {\n    let live = true\n    void (async () => {\n      let saved: ModelMenuRoute = defaultSettings().model\n      try {\n        const next = unwrap(await client.connection.rpc.call(SELF_IMPROVEMENT_RPC_CHANNEL, 'settings', {}) as RpcResult<SelfImprovementSettings>)\n        if (!live) return\n        setSettings(next)\n        saved = next.model\n      } catch (cause) {\n        if (live) setError(cause instanceof Error && cause.message ? cause.message : (locale === 'en' ? 'Unable to load settings.' : '无法读取设置。'))\n      }\n      try {\n        const value = await client.remote?.session?.modelCatalog?.()\n        if (live) setChoices(parseModelMenuChoices(value, saved))\n      } catch {\n        if (live) setChoices([])\n      }\n    })()\n    return () => { live = false }\n  }, [client, locale])\n\n  async function save(next: ModelMenuRoute): Promise<void> {\n    if (!settings) return\n    setBusy(true); setError(''); setNote('')\n    try {\n      const value = await client.connection.rpc.call(SELF_IMPROVEMENT_RPC_CHANNEL, 'settings.update', {\n        expectedRevision: settings.revision, model: normalizeModelMenuRoute(next),\n      })\n      setSettings(unwrap(value as RpcResult<SelfImprovementSettings>))\n      setNote(locale === 'en' ? 'Saved.' : '已保存。')\n    } catch (cause) {\n      setError(cause instanceof Error && cause.message ? cause.message : (locale === 'en' ? 'Unable to save settings.' : '无法保存设置。'))\n    } finally {\n      setBusy(false)\n    }\n  }\n\n  return <section className=\"si-model dsh-ui-stack\" data-testid=\"self-improvement-model\">\n    {error && <p role=\"alert\" className=\"dsh-ui-error\">{error}</p>}\n    {note && <p role=\"status\" className=\"dsh-ui-notice\">{note}</p>}\n    <label className=\"dsh-ui-field\" htmlFor={optionsId}>\n      <span className=\"dsh-ui-label\">{locale === 'en' ? 'Extraction model' : '摘录模型'}</span>\n      <select\n        id={optionsId}\n        className=\"dsh-ui-select\"\n        value={modelMenuChoiceKey(route.provider, route.model)}\n        disabled={busy || !settings}\n        onChange={event => {\n          const key = event.target.value\n          if (!key) { void save({ provider: '', model: '' }); return }\n          const parsed = parseModelMenuChoiceKey(key)\n          if (parsed) void save(parsed)\n        }}\n      >\n        <option value=\"\">{locale === 'en' ? 'Default model' : '默认模型'}</option>\n        {choices.map(choice => (\n          <option key={modelMenuChoiceKey(choice.provider, choice.model)} value={modelMenuChoiceKey(choice.provider, choice.model)}>\n            {choice.label}\n          </option>\n        ))}\n      </select>\n    </label>\n    {selected && efforts.length > 0 && (\n      <label className=\"dsh-ui-field\" htmlFor={`${optionsId}-effort`}>\n        <span className=\"dsh-ui-label\">{locale === 'en' ? 'Reasoning effort' : '思考强度'}</span>\n        <select\n          id={`${optionsId}-effort`}\n          className=\"dsh-ui-select\"\n          value={route.reasoningEffort ?? ''}\n          disabled={busy}\n          onChange={event => void save({ ...route, reasoningEffort: event.target.value || undefined })}\n        >\n          <option value=\"\">{locale === 'en' ? 'Default' : '默认'}</option>\n          {efforts.map(effort => <option key={effort.id} value={effort.id}>{effort.name}</option>)}\n        </select>\n      </label>\n    )}\n    <p className=\"dsh-ui-hint\">{locale === 'en'\n      ? 'Leave empty to use the current session model, then the host default chat model.'\n      : '留空则用当前会话模型，再回落到宿主默认对话模型。'}</p>\n  </section>\n}\n\n/** Plugin page seat: the model menu works without a session. */\nexport function SelfImprovementSettingsSeat({ client }: { client: Client }) {\n  const seat = useNativeSeat(client, {})\n  return <section className=\"si-settings si-root dsh-ui-panel\" data-testid=\"self-improvement-settings\">\n    <SelfImprovementModelMenu client={client} locale={seat.locale} />\n    <SelfImprovementSettings client={client} props={{ sessionId: seat.sessionId, locale: seat.locale }} />\n  </section>\n}\n\nexport function SelfImprovementSettings({ client, props }: { client: Client; props: unknown }) {\n  const seat = useNativeSeat(client, props)\n  return <ReviewPanel key={reviewPanelKey(seat.sessionId, seat.locale)} client={client} sessionId={seat.sessionId} locale={seat.locale} />\n}\n\ndeclare module '@deepseek-ai/cordis' {\n  interface Context {\n    dshSelfImprovementReview: { render(props: unknown): unknown }\n  }\n}\n\nexport function apply(ctx: Context): void {\n  const client = ctx as unknown as Client\n  ctx.provide(SELF_IMPROVEMENT_REVIEW_SERVICE, {\n    render: (props: unknown) => <SelfImprovementSettings client={client} props={props} />,\n  })\n  ctx.effect(() => client.slots.inject('plugins.bundle.config', () => client.slots.register(\n    { name: 'plugins.bundle.config', key: SELF_IMPROVEMENT_PLUGIN },\n    () => <SelfImprovementSettingsSeat client={client} />,\n  )), 'self-improvement.settings')\n  ctx.effect(() => {\n    if (typeof document === 'undefined') return () => {}\n    const style = document.createElement('style')\n    style.setAttribute('data-plugin', '@klarkxy/dsh-self-improvement')\n    style.textContent = styles\n    document.head.appendChild(style)\n    return () => style.remove()\n  }, 'self-improvement.styles')\n}\n"],"mappings":"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"}