@klarkxy/dsh-magpie 0.1.0 → 0.1.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.
@@ -1 +1 @@
1
- {"version":3,"file":"client.inner.cjs","names":["useCallback","useSyncExternalStore","useState","useRef","Button","Input","Tag","Switch"],"sources":["../../dsh-plugin-kit/src/official-ui.ts","../src/contracts.ts","../src/client.tsx"],"sourcesContent":["/**\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/* Plugin detail pages share one reading column. These are layout recipes;\n * controls keep their own primitive styles. Form spacing follows the host's\n * settings-form/fields.module.css and SettingsForm.module.css. */\n& .dsh-ui-page { display: flex; flex-direction: column; gap: 16px; width: 100%; max-width: 760px; min-width: 0; }\n& .dsh-ui-form { display: flex; flex-direction: column; gap: 0; min-width: 0; }\n&.dsh-ui-form > .dsh-ui-field, & .dsh-ui-form > .dsh-ui-field { padding: 12px 0; }\n& .dsh-ui-form-footer { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; padding-top: 16px; min-width: 0; }\n& .dsh-ui-fields-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px 20px; min-width: 0; margin: 0; padding: 0; border: 0; }\n@media (max-width: 560px) {\n & .dsh-ui-fields-grid { grid-template-columns: minmax(0, 1fr); }\n}\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/* Grid fields share a row, so the stacked-field divider must not win later in\n * the cascade. Reset it here, after the field recipe. */\n& .dsh-ui-fields-grid > .dsh-ui-field { padding: 0; border: 0; }\n& .dsh-ui-label { display: flex; align-items: center; gap: 6px; font-size: 13px; line-height: 20px; font-weight: 500; color: var(--dsw-alias-label-primary); }\n& .dsh-ui-label-row { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }\n& .dsh-ui-help { font-size: 12px; line-height: 1.6; color: var(--dsw-alias-label-secondary); }\n& .dsh-ui-help p { margin: 0; }\n& .dsh-ui-help p + p { margin-top: 8px; }\n& .dsh-ui-required { color: var(--dsw-alias-state-error-primary); }\n& .dsh-ui-control { width: 100%; min-width: 0; }\n/* An invalid control is marked on the control, not only in the message. */\n& .dsh-ui-control[aria-invalid='true'] { border-color: var(--dsw-alias-state-error-primary); }\n& .dsh-ui-readonly { display: flex; flex-direction: column; gap: 4px; min-width: 0; }\n& .dsh-ui-readonly > dt { font-size: 12px; line-height: 18px; color: var(--dsw-alias-label-tertiary); }\n& .dsh-ui-readonly > dd { margin: 0; font-size: 13px; line-height: 20px; overflow-wrap: anywhere; }\n\n/* --- Buttons row. A no-op container: it exists so actions line up on the\n * trailing edge the way every native panel does. --- */\n& .dsh-ui-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding-top: 4px; }\n& .dsh-ui-actions-end { justify-content: flex-end; }\n\n/* --- Banners. A banner is a left-rail notice, the shape used for warnings,\n * deprecations and blocking instructions. --- */\n& .dsh-ui-banner {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 10px 14px;\n border: 0.5px solid var(--dsw-alias-border-l3);\n border-left: 3px solid var(--dsw-alias-state-warn-primary);\n border-radius: var(--dsw-radius-md);\n background: var(--dsw-alias-bg-layer-1);\n font-size: 13px;\n line-height: 20px;\n color: var(--dsw-alias-label-secondary);\n}\n& .dsh-ui-banner-title { font-weight: 500; color: var(--dsw-alias-state-warn-primary); }\n& .dsh-ui-banner--info { border-left-color: var(--dsw-alias-state-business-primary); }\n& .dsh-ui-banner--danger { border-left-color: var(--dsw-alias-state-error-primary); }\n& .dsh-ui-banner--success { border-left-color: var(--dsw-alias-state-success-primary); }\n& .dsh-ui-banner p { margin: 0; }\n\n/* --- Inline notice: a transient confirmation with no chrome of its own. --- */\n& .dsh-ui-notice { display: flex; align-items: center; gap: 6px; font-size: 12px; line-height: 18px; color: var(--dsw-alias-state-success-primary); }\n& .dsh-ui-notice--error { color: var(--dsw-alias-state-error-primary); }\n\n/* --- Empty and loading states. Both sit in a dashed well so an empty panel\n * reads as \"nothing here yet\" rather than as a broken layout. --- */\n& .dsh-ui-empty {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 6px;\n padding: 20px 16px;\n border: 0.5px dashed var(--dsw-alias-border-l3);\n border-radius: var(--dsw-radius-md);\n font-size: 13px;\n line-height: 20px;\n color: var(--dsw-alias-label-secondary);\n}\n& .dsh-ui-loading { display: flex; align-items: center; gap: 8px; padding: 20px 0; font-size: 13px; line-height: 20px; color: var(--dsw-alias-label-secondary); }\n\n/* --- Selectable list. A row is a button-sized target with a hover fill and\n * a selected fill; the name carries the weight, the description does not. --- */\n& .dsh-ui-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; min-width: 0; }\n& .dsh-ui-list-scroll { max-height: min(66vh, 760px); overflow-y: auto; overflow-x: hidden; }\n& .dsh-ui-list-row { border-radius: var(--dsw-radius-md); }\n& .dsh-ui-list-row:hover { background: var(--dsw-alias-interactive-bg-hover); }\n& .dsh-ui-list-row[aria-selected='true'], & .dsh-ui-list-row[data-selected] { background: var(--dsw-alias-interactive-bg-active); }\n& .dsh-ui-list-item {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 4px;\n width: 100%;\n min-width: 0;\n padding: 10px 12px;\n border: 0;\n border-radius: var(--dsw-radius-md);\n background: none;\n font: inherit;\n color: inherit;\n text-align: start;\n cursor: pointer;\n}\n& .dsh-ui-list-item:disabled { cursor: default; }\n& .dsh-ui-list-item:disabled:hover { background: none; }\n& .dsh-ui-list-name { font-size: 14px; line-height: 22px; font-weight: 500; color: var(--dsw-alias-label-primary); overflow-wrap: anywhere; }\n& .dsh-ui-list-desc { font-size: 12px; line-height: 18px; color: var(--dsw-alias-label-tertiary); }\n\n/* --- Code and structured output. Wraps rather than scrolls, because a\n * feature panel is read rather than scanned. --- */\n& .dsh-ui-code {\n padding: 10px 12px;\n border: 0.5px solid var(--dsw-alias-border-l3);\n border-radius: var(--dsw-radius-md);\n background: var(--dsw-alias-bg-layer-1);\n font-family: var(--ds-font-family-code);\n font-size: 12px;\n line-height: 20px;\n color: var(--dsw-alias-label-secondary);\n overflow-wrap: anywhere;\n white-space: pre-wrap;\n}\n& .dsh-ui-scroll { max-height: 60vh; overflow: auto; overscroll-behavior: contain; }\n\n/* --- A toggle row: label on the left, switch on the trailing edge. This is\n * layout only; the switch itself is the official primitive. --- */\n& .dsh-ui-toggle-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; min-width: 0; padding: 12px 0; }\n& .dsh-ui-toggle-row + .dsh-ui-toggle-row { border-top: 0.5px solid var(--dsw-alias-border-l2); }\n& .dsh-ui-toggle-text { display: flex; flex-direction: column; gap: 4px; min-width: 0; }\n& .dsh-ui-toggle-label { font-size: 14px; line-height: 22px; font-weight: 500; color: var(--dsw-alias-label-primary); }\n\n/* --- Floating surface: a panel anchored to a trigger. This is the material\n * a menu card is made of — the translucent fill plus its backdrop blur, with\n * the edge riding inside the prominent elevation. A plugin that hand-rolls this\n * is how tokens like --dsw-specific-menu get invented; use this instead. --- */\n& .dsh-ui-surface {\n --dsw-elevation-stroke-color: var(--dsw-alias-border-l1);\n --dsh-scrollbar-thumb: var(--dsw-alias-scrollbar-bg-l2);\n --dsh-scrollbar-thumb-hover: var(--dsw-alias-scrollbar-hover-l2);\n position: relative;\n display: flex;\n flex-direction: column;\n border: 0;\n border-radius: var(--dsw-radius-lg);\n background: var(--dsw-menu-surface-fill);\n backdrop-filter: var(--dsw-menu-backdrop-filter);\n box-shadow: var(--dsw-elevation-prominent);\n color: var(--dsw-alias-label-primary);\n font-size: 13px;\n line-height: 20px;\n min-width: 0;\n}\n& .dsh-ui-surface-body { display: flex; flex-direction: column; gap: 8px; padding: 12px 14px 14px; overflow-y: auto; }\n& .dsh-ui-surface-head { display: flex; align-items: center; gap: 8px; min-width: 0; }\n& .dsh-ui-surface-title { font-size: 14px; line-height: 22px; font-weight: 500; color: var(--dsw-alias-label-primary); }\n\n/* --- Native select. The primitives ship no select, so a plugin that offers a\n * closed list of choices keeps the platform control and matches the official\n * settings field geometry exactly (34px, 0.5px l4, radius-md, layer-3). A\n * SegmentedControl is the primitive to reach for when the choices are few\n * enough to show at once. --- */\n& .dsh-ui-select {\n box-sizing: border-box;\n width: 100%;\n min-width: 0;\n height: 34px;\n padding: 0 12px;\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: var(--dsw-radius-md);\n background: var(--dsw-alias-bg-layer-3);\n font: inherit;\n font-size: 13px;\n line-height: 1.5;\n color: var(--dsw-alias-label-primary);\n cursor: pointer;\n}\n& .dsh-ui-select:focus-visible { outline: none; border-color: var(--dsw-alias-state-business-primary); }\n& .dsh-ui-select:disabled { color: var(--dsw-alias-label-tertiary); cursor: default; }\n& .dsh-ui-select[aria-invalid='true'] { border-color: var(--dsw-alias-state-error-primary); }\n\n/* --- Native textarea. The primitives ship no textarea either, so a settings\n * prompt keeps the platform element and the same field shell as the select:\n * 0.5px l4, radius-md, layer-3, 13/1.5 type. It grows vertically instead of\n * locking to the select's 34px row. --- */\n& .dsh-ui-textarea {\n box-sizing: border-box;\n width: 100%;\n min-width: 0;\n resize: vertical;\n padding: 8px 12px;\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: var(--dsw-radius-md);\n background: var(--dsw-alias-bg-layer-3);\n font: inherit;\n font-size: 13px;\n line-height: 1.5;\n color: var(--dsw-alias-label-primary);\n}\n& .dsh-ui-textarea:focus-visible { outline: none; border-color: var(--dsw-alias-state-business-primary); }\n& .dsh-ui-textarea:disabled { color: var(--dsw-alias-label-tertiary); cursor: default; }\n& .dsh-ui-textarea::placeholder { color: var(--dsw-alias-label-dimmed); }\n& .dsh-ui-textarea[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-]+)(?=\\s*\\{)/gm, (_match, className: string) =>\n `&${className}, & ${className}`)\n}\n","export const PLUGIN_NAME = '@klarkxy/dsh-magpie'\nexport const PLUGIN_VERSION = '0.1.0'\nexport const RPC_CHANNEL = '/dsh-magpie'\n/** Wire endpoint names; the host RPC transport only admits lowercase/dotted names. */\nexport const RPC_ENDPOINTS = {\n status: 'status',\n saveConnection: 'connection.save',\n test: 'test',\n sync: 'sync',\n setOptions: 'options.set',\n disconnect: 'disconnect',\n} as const\n\n/** The three llm-pi-ai provider routes, named exactly as `magpie dsh` writes them. */\nexport const ROUTES = {\n completions: 'magpie',\n responses: 'magpie-responses',\n anthropic: 'magpie-anthropic',\n} as const\nexport type RouteKind = keyof typeof ROUTES\nexport type RouteName = (typeof ROUTES)[RouteKind]\nexport const ROUTE_NAMES: readonly RouteName[] = [ROUTES.completions, ROUTES.responses, ROUTES.anthropic]\n\n/** Settings namespaces this plugin writes through `ctx.settings`. */\nexport const NS_LLM = 'llm-pi-ai'\nexport const NS_DEFAULT_MODEL = 'agent-default-model'\nexport const NS_WEB_SEARCH = 'web-search-deepseek'\n\nexport const DEFAULT_ADDRESS = 'http://127.0.0.1:3425'\nexport const DEFAULT_KEY_REF = 'MAGPIE_GATEWAY_KEY'\n/** Placeholder bearer the local magpie accepts on loopback, matching magpie's own agent configs. */\nexport const LOOPBACK_PLACEHOLDER_KEY = 'magpie'\nexport const STREAM_IDLE_TIMEOUT_MS = 600000\nexport const GATEWAY_TIMEOUT_MS = 10000\n\nexport interface MagpieOptions {\n address: string\n apiKeyEnv: string\n syncOnStart: boolean\n defaultModel?: string\n webSearch: boolean\n webSearchModel?: string\n}\n\nexport interface GatewayInfo {\n name: string\n version?: string\n}\n\nexport interface SyncResult {\n at: string\n /** Models written per route, keyed by route name. */\n routes: Record<string, number>\n warnings: string[]\n}\n\nexport interface StatusError {\n at: string\n message: string\n}\n\n/** One model currently present in one of the three llm-pi-ai routes. */\nexport interface RouteModel {\n id: string\n name?: string\n route: RouteName\n}\n\nexport interface MagpieStatus {\n address: string\n apiKeyEnv: string\n keyConfigured: boolean\n keyWritable: boolean\n options: Omit<MagpieOptions, 'address' | 'apiKeyEnv'>\n /** Whether the active profile accepts settings writes. */\n writable: boolean\n gateway?: GatewayInfo\n syncing: boolean\n lastSync?: SyncResult\n lastError?: StatusError\n /** Models in the three magpie routes as stored in the active settings. */\n models: RouteModel[]\n}\n\nexport interface SaveConnectionInput {\n address?: string\n apiKey?: string\n clearKey?: boolean\n}\n\nexport interface SetOptionsInput {\n syncOnStart?: boolean\n defaultModel?: string | null\n webSearch?: boolean\n webSearchModel?: string | null\n}\n\nexport interface TestResult {\n gateway: GatewayInfo\n models: number\n}\n\nexport type RpcResult<T = unknown> =\n | { ok: true; value: T }\n | { ok: false; error: { code: string; message: string; details?: Record<string, unknown> } }\n","/**\n * Settings page for the magpie gateway connection. All state comes from the\n * host over the plugin RPC channel; the page only drafts the address and the\n * key field, never touches settings files itself.\n */\nimport type { Context } from '@deepseek-ai/cordis'\nimport { Button, Input, Switch, Tag } from '@deepseek-ai/dsh-client-ui-primitives'\nimport { officialUiCss } from '@klarkxy/dsh-plugin-kit/official-ui'\nimport { useCallback, useEffect, useRef, useState, useSyncExternalStore } from 'react'\nimport {\n PLUGIN_NAME, RPC_CHANNEL, RPC_ENDPOINTS,\n type MagpieStatus, type RpcResult, type TestResult,\n} from './contracts.ts'\n\nexport const name = 'dsh-magpie-client'\nexport const inject = ['slots', 'connection', 'locale'] as const\n\ninterface Client {\n connection: { rpc: { call(channel: string, endpoint: string, payload: unknown): Promise<unknown> } }\n locale?: { getSnapshot(): { active: string }; subscribe(listener: () => void): () => void }\n slots: {\n inject(key: string, callback: () => unknown): () => void\n register(spec: { name: string; key: string }, render: unknown): () => void\n }\n}\n\nconst styles = `${officialUiCss('.mgp-root')}\n.mgp-root .mgp-row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }\n.mgp-root .mgp-row > .mgp-grow { flex: 1 1 220px; }\n.mgp-root .mgp-danger { color: var(--dsw-alias-state-error-primary); }\n`\n\nconst copy = {\n zh: {\n loading: '正在读取状态…', failed: '操作失败:', retry: '重试',\n connection: '连接', address: '网关地址', addressHelp: '本机、局域网或远程的 magpie 网关,例如 http://127.0.0.1:3425。',\n key: '网关 Key', keyHelp: '非本机网关需要 Key;本机网关留空会自动使用占位 Key。',\n keyPlaceholder: '输入网关 Key', keyConfigured: '已保存', keyClear: '清除',\n test: '测试', save: '保存', saved: '已保存。',\n sync: '同步', syncNow: '立即同步', syncing: '正在同步…', syncOnStart: '启动时同步', syncOnStartHelp: '每次启动本 profile 时同步一次。',\n lastSync: '上次同步', never: '从未同步', models: (n: number) => `${n} 个模型`,\n warnings: '警告', readonlyHint: '当前 profile 的设置只读,无法写入。',\n defaultModel: '默认模型', defaultModelHelp: '把某个 magpie 模型设为新会话的默认模型。',\n keepCurrent: '不更改', webSearch: '网络搜索', webSearchHelp: '通过网关用所选模型执行网络搜索。',\n sameAsDefault: '与默认模型相同', disconnect: '断开连接', confirmDisconnect: '确认断开?',\n disconnectHelp: '移除三条 magpie 供应商路由并还原默认模型与网络搜索;已保存的 Key 保留。',\n testOk: (n: number) => `连接正常,网关返回 ${n} 个模型。`, notConnected: '尚未连接。',\n },\n en: {\n loading: 'Loading status…', failed: 'Action failed: ', retry: 'Retry',\n connection: 'Connection', address: 'Gateway address', addressHelp: 'A magpie gateway on this computer, your LAN, or elsewhere, e.g. http://127.0.0.1:3425.',\n key: 'Gateway key', keyHelp: 'Non-local gateways need a key; a local gateway uses a placeholder automatically.',\n keyPlaceholder: 'Enter gateway key', keyConfigured: 'Saved', keyClear: 'Clear',\n test: 'Test', save: 'Save', saved: 'Saved.',\n sync: 'Sync', syncNow: 'Sync now', syncing: 'Syncing…', syncOnStart: 'Sync at startup', syncOnStartHelp: 'Run one sync every time this profile starts.',\n lastSync: 'Last sync', never: 'Never synced', models: (n: number) => `${n} models`,\n warnings: 'Warnings', readonlyHint: 'Settings are read-only in this profile; nothing can be written.',\n defaultModel: 'Default model', defaultModelHelp: 'Promote a magpie model to the default for new conversations.',\n keepCurrent: \"Don't change\", webSearch: 'Web search', webSearchHelp: 'Run web search through the gateway with the selected model.',\n sameAsDefault: 'Same as default model', disconnect: 'Disconnect', confirmDisconnect: 'Confirm disconnect?',\n disconnectHelp: 'Removes the three magpie provider routes and reverts the default model and web search; the saved key is kept.',\n testOk: (n: number) => `Connection OK: the gateway returned ${n} models.`, notConnected: 'Not connected yet.',\n },\n} as const\n\ntype Copy = (typeof copy)['zh'] | (typeof copy)['en']\n\nclass RpcError extends Error {\n constructor(readonly code: string, message: string) { super(message); this.name = 'RpcError' }\n}\n\nconst SYNC_POLL_MS = 1500\n\nfunction useHostLocale(client: Client): 'zh' | 'en' {\n const subscribe = useCallback((listener: () => void) => client.locale?.subscribe(listener) ?? (() => {}), [client])\n const snapshot = useCallback(() => client.locale?.getSnapshot().active ?? 'zh', [client])\n return String(useSyncExternalStore(subscribe, snapshot, snapshot)).startsWith('zh') ? 'zh' : 'en'\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 const disarm = () => { clearTimeout(timer.current); setArmed(false) }\n return <Button variant=\"outline\" size=\"sm\" className=\"mgp-danger\" disabled={props.disabled}\n onClick={() => {\n if (!armed) { setArmed(true); timer.current = setTimeout(() => setArmed(false), 3000); return }\n disarm(); props.onConfirm()\n }}\n onBlur={disarm}>{armed ? props.confirmLabel : props.label}</Button>\n}\n\nexport function MagpieSettingsPage({ client }: { client: Client }) {\n const locale = useHostLocale(client)\n const text: Copy = copy[locale]\n const [status, setStatus] = useState<MagpieStatus>()\n const [address, setAddress] = useState('')\n const [addressDirty, setAddressDirty] = useState(false)\n const [keyDraft, setKeyDraft] = useState('')\n const [busy, setBusy] = useState<string>('')\n const [note, setNote] = useState('')\n const [error, setError] = useState('')\n const mounted = useRef(true)\n\n const call = useCallback(async <T,>(endpoint: string, payload: unknown = {}): Promise<T> => {\n const result = await client.connection.rpc.call(RPC_CHANNEL, endpoint, payload) as RpcResult<T>\n if (!result.ok) throw new RpcError(result.error.code, result.error.message)\n return result.value\n }, [client])\n\n const load = useCallback(async () => {\n try {\n const next = await call<MagpieStatus>(RPC_ENDPOINTS.status)\n if (!mounted.current) return\n setStatus(next)\n setAddress(current => addressDirty ? current : next.address)\n setError('')\n } catch (reason) {\n if (mounted.current) setError(reason instanceof Error ? reason.message : String(reason))\n }\n }, [call, addressDirty])\n\n useEffect(() => {\n mounted.current = true\n void load()\n return () => { mounted.current = false }\n }, [load])\n\n // While a sync runs, poll until it lands so counts and warnings show up.\n useEffect(() => {\n if (!status?.syncing) return\n const timer = setInterval(() => { void load() }, SYNC_POLL_MS)\n return () => clearInterval(timer)\n }, [status?.syncing, load])\n\n const action = useCallback(async (name: string, run: () => Promise<void>) => {\n if (busy) return\n setBusy(name); setNote(''); setError('')\n try { await run() }\n catch (reason) { if (mounted.current) setError(reason instanceof Error ? reason.message : String(reason)) }\n finally { if (mounted.current) setBusy('') }\n }, [busy])\n\n const refresh = (next: MagpieStatus) => { setStatus(next); setAddress(current => addressDirty ? current : next.address) }\n\n if (!status) {\n return <section className=\"mgp-root dsh-ui-page dsh-ui-form\" data-testid=\"magpie-settings\">\n {error\n ? <p role=\"alert\" className=\"dsh-ui-error\">{text.failed}{error}</p>\n : <p role=\"status\" className=\"dsh-ui-hint\">{text.loading}</p>}\n <Button variant=\"ghost\" size=\"sm\" disabled={Boolean(busy)} onClick={() => void load()}>{text.retry}</Button>\n </section>\n }\n\n const models = status.models\n const defaultChoices = models.map(model => model.id)\n if (status.options.defaultModel && !defaultChoices.includes(status.options.defaultModel)) {\n defaultChoices.unshift(status.options.defaultModel)\n }\n const modelLabel = (id: string) => {\n const found = models.find(model => model.id === id)\n return found ? `${found.name ?? id} · ${found.route}` : id\n }\n\n return <section className=\"mgp-root dsh-ui-page dsh-ui-form\" data-testid=\"magpie-settings\">\n {status.writable === false ? <p role=\"status\" className=\"dsh-ui-hint\">{text.readonlyHint}</p> : null}\n {error ? <p role=\"alert\" className=\"dsh-ui-error\">{text.failed}{error}</p> : null}\n {note ? <p role=\"status\" className=\"dsh-ui-notice\">{note}</p> : null}\n\n <article className=\"dsh-ui-card\">\n <h3 className=\"dsh-ui-label\">{text.connection}</h3>\n <label className=\"dsh-ui-field\">\n <span className=\"dsh-ui-label\">{text.address}</span>\n <Input value={addressDirty ? address : status.address}\n placeholder=\"http://127.0.0.1:3425\"\n onChange={event => { setAddress(event.target.value); setAddressDirty(true) }} />\n <span className=\"dsh-ui-help\">{text.addressHelp}</span>\n </label>\n <label className=\"dsh-ui-field\">\n <span className=\"dsh-ui-label\">{text.key} {status.keyConfigured ? <Tag tone=\"success\">{text.keyConfigured}</Tag> : null}</span>\n <span className=\"mgp-row\">\n <span className=\"mgp-grow\">\n <Input type=\"password\" value={keyDraft} placeholder={text.keyPlaceholder}\n onChange={event => setKeyDraft(event.target.value)} />\n </span>\n {status.keyConfigured ? <Button variant=\"ghost\" size=\"sm\" disabled={Boolean(busy)}\n onClick={() => void action('clear-key', async () => {\n refresh(await call<MagpieStatus>(RPC_ENDPOINTS.saveConnection, { clearKey: true }))\n setNote(text.saved)\n })}>{text.keyClear}</Button> : null}\n </span>\n <span className=\"dsh-ui-help\">{text.keyHelp}</span>\n </label>\n <div className=\"dsh-ui-form-footer mgp-row\">\n <Button variant=\"outline\" size=\"md\" disabled={Boolean(busy)} onClick={() => void action('test', async () => {\n if (addressDirty || keyDraft) {\n refresh(await call<MagpieStatus>(RPC_ENDPOINTS.saveConnection, {\n address, apiKey: keyDraft || undefined,\n }))\n setKeyDraft(''); setAddressDirty(false)\n }\n const result = await call<TestResult>(RPC_ENDPOINTS.test)\n setNote(text.testOk(result.models))\n await load()\n })}>{text.test}</Button>\n <Button variant=\"primary\" size=\"md\" disabled={Boolean(busy) || (!addressDirty && !keyDraft)} onClick={() => void action('save', async () => {\n refresh(await call<MagpieStatus>(RPC_ENDPOINTS.saveConnection, { address, apiKey: keyDraft || undefined }))\n setKeyDraft(''); setAddressDirty(false); setNote(text.saved)\n })}>{text.save}</Button>\n </div>\n </article>\n\n <article className=\"dsh-ui-card\">\n <div className=\"mgp-row\">\n <h3 className=\"dsh-ui-label mgp-grow\">{text.sync}</h3>\n <Button variant=\"outline\" size=\"md\" disabled={Boolean(busy) || status.syncing} onClick={() => void action('sync', async () => {\n refresh(await call<MagpieStatus>(RPC_ENDPOINTS.sync))\n setNote(text.saved)\n })}>{status.syncing ? text.syncing : text.syncNow}</Button>\n </div>\n <label className=\"dsh-ui-field\">\n <span className=\"mgp-row\">\n <Switch checked={status.options.syncOnStart} disabled={Boolean(busy)} label={text.syncOnStart}\n onChange={next => void action('options', async () => {\n refresh(await call<MagpieStatus>(RPC_ENDPOINTS.setOptions, { syncOnStart: next }))\n })} />\n <span className=\"dsh-ui-label\">{text.syncOnStart}</span>\n </span>\n <span className=\"dsh-ui-help\">{text.syncOnStartHelp}</span>\n </label>\n <p className=\"dsh-ui-meta\">\n {text.lastSync}: {status.lastSync\n ? `${new Date(status.lastSync.at).toLocaleString()} · ${Object.entries(status.lastSync.routes).map(([route, count]) => `${route}: ${count}`).join(' · ')}`\n : text.never}\n </p>\n {status.lastSync?.warnings.length ? <div>\n <p className=\"dsh-ui-label\">{text.warnings}</p>\n {status.lastSync.warnings.map((warning, index) => <p key={index} className=\"dsh-ui-hint\">{warning}</p>)}\n </div> : null}\n {status.lastError ? <p role=\"alert\" className=\"dsh-ui-error\">{new Date(status.lastError.at).toLocaleString()} · {status.lastError.message}</p> : null}\n {status.gateway ? <p className=\"dsh-ui-hint\">{status.gateway.name}{status.gateway.version ? ` ${status.gateway.version}` : ''} · {text.models(models.length)}</p> : null}\n </article>\n\n <article className=\"dsh-ui-card\">\n <label className=\"dsh-ui-field\">\n <span className=\"dsh-ui-label\">{text.defaultModel}</span>\n <select className=\"dsh-ui-select\" value={status.options.defaultModel ?? ''} disabled={Boolean(busy)}\n onChange={event => void action('options', async () => {\n refresh(await call<MagpieStatus>(RPC_ENDPOINTS.setOptions, { defaultModel: event.target.value || null }))\n })}>\n <option value=\"\">{text.keepCurrent}</option>\n {defaultChoices.map(id => <option key={id} value={id}>{modelLabel(id)}</option>)}\n </select>\n <span className=\"dsh-ui-help\">{text.defaultModelHelp}</span>\n </label>\n </article>\n\n <article className=\"dsh-ui-card\">\n <div className=\"mgp-row\">\n <span className=\"dsh-ui-label mgp-grow\">{text.webSearch}</span>\n <Switch checked={status.options.webSearch} disabled={Boolean(busy)} label={text.webSearch}\n onChange={next => void action('options', async () => {\n refresh(await call<MagpieStatus>(RPC_ENDPOINTS.setOptions, { webSearch: next }))\n })} />\n </div>\n <p className=\"dsh-ui-help\">{text.webSearchHelp}</p>\n {status.options.webSearch ? <label className=\"dsh-ui-field\">\n <select className=\"dsh-ui-select\" value={status.options.webSearchModel ?? ''} disabled={Boolean(busy)}\n onChange={event => void action('options', async () => {\n refresh(await call<MagpieStatus>(RPC_ENDPOINTS.setOptions, { webSearchModel: event.target.value || null }))\n })}>\n <option value=\"\">{text.sameAsDefault}</option>\n {models.map(model => <option key={model.id} value={model.id}>{model.name ?? model.id}</option>)}\n </select>\n </label> : null}\n </article>\n\n <article className=\"dsh-ui-card\">\n <div className=\"mgp-row\">\n <div className=\"mgp-grow\">\n <span className=\"dsh-ui-label\">{text.disconnect}</span>\n <p className=\"dsh-ui-help\">{text.disconnectHelp}</p>\n </div>\n <ConfirmButton label={text.disconnect} confirmLabel={text.confirmDisconnect} disabled={Boolean(busy)}\n onConfirm={() => void action('disconnect', async () => {\n refresh(await call<MagpieStatus>(RPC_ENDPOINTS.disconnect))\n setNote(text.saved)\n })} />\n </div>\n </article>\n </section>\n}\n\nexport function apply(ctx: Context): void {\n const client = ctx as unknown as Client\n ctx.effect(() => {\n if (typeof document === 'undefined') return () => {}\n const style = document.createElement('style')\n style.setAttribute('data-plugin', PLUGIN_NAME)\n style.textContent = styles\n document.head.appendChild(style)\n return () => style.remove()\n }, 'magpie.styles')\n ctx.effect(() => client.slots.inject('plugins.bundle.config', () => client.slots.register(\n { name: 'plugins.bundle.config', key: PLUGIN_NAME },\n () => <MagpieSettingsPage client={client} />,\n )), 'magpie.settings')\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"client.inner.cjs","names":["useCallback","useSyncExternalStore","useState","useRef","Button","Input","Tag","Switch"],"sources":["../../dsh-plugin-kit/src/official-ui.ts","../src/contracts.ts","../src/client.tsx"],"sourcesContent":["/**\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/* Plugin detail pages share one reading column. These are layout recipes;\n * controls keep their own primitive styles. Form spacing follows the host's\n * settings-form/fields.module.css and SettingsForm.module.css. */\n& .dsh-ui-page { display: flex; flex-direction: column; gap: 16px; width: 100%; max-width: 760px; min-width: 0; }\n& .dsh-ui-form { display: flex; flex-direction: column; gap: 0; min-width: 0; }\n&.dsh-ui-form > .dsh-ui-field, & .dsh-ui-form > .dsh-ui-field { padding: 12px 0; }\n& .dsh-ui-form-footer { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; padding-top: 16px; min-width: 0; }\n& .dsh-ui-fields-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px 20px; min-width: 0; margin: 0; padding: 0; border: 0; }\n@media (max-width: 560px) {\n & .dsh-ui-fields-grid { grid-template-columns: minmax(0, 1fr); }\n}\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/* Grid fields share a row, so the stacked-field divider must not win later in\n * the cascade. Reset it here, after the field recipe. */\n& .dsh-ui-fields-grid > .dsh-ui-field { padding: 0; border: 0; }\n& .dsh-ui-label { display: flex; align-items: center; gap: 6px; font-size: 13px; line-height: 20px; font-weight: 500; color: var(--dsw-alias-label-primary); }\n& .dsh-ui-label-row { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }\n& .dsh-ui-help { font-size: 12px; line-height: 1.6; color: var(--dsw-alias-label-secondary); }\n& .dsh-ui-help p { margin: 0; }\n& .dsh-ui-help p + p { margin-top: 8px; }\n& .dsh-ui-required { color: var(--dsw-alias-state-error-primary); }\n& .dsh-ui-control { width: 100%; min-width: 0; }\n/* An invalid control is marked on the control, not only in the message. */\n& .dsh-ui-control[aria-invalid='true'] { border-color: var(--dsw-alias-state-error-primary); }\n& .dsh-ui-readonly { display: flex; flex-direction: column; gap: 4px; min-width: 0; }\n& .dsh-ui-readonly > dt { font-size: 12px; line-height: 18px; color: var(--dsw-alias-label-tertiary); }\n& .dsh-ui-readonly > dd { margin: 0; font-size: 13px; line-height: 20px; overflow-wrap: anywhere; }\n\n/* --- Buttons row. A no-op container: it exists so actions line up on the\n * trailing edge the way every native panel does. --- */\n& .dsh-ui-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding-top: 4px; }\n& .dsh-ui-actions-end { justify-content: flex-end; }\n\n/* --- Banners. A banner is a left-rail notice, the shape used for warnings,\n * deprecations and blocking instructions. --- */\n& .dsh-ui-banner {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 10px 14px;\n border: 0.5px solid var(--dsw-alias-border-l3);\n border-left: 3px solid var(--dsw-alias-state-warn-primary);\n border-radius: var(--dsw-radius-md);\n background: var(--dsw-alias-bg-layer-1);\n font-size: 13px;\n line-height: 20px;\n color: var(--dsw-alias-label-secondary);\n}\n& .dsh-ui-banner-title { font-weight: 500; color: var(--dsw-alias-state-warn-primary); }\n& .dsh-ui-banner--info { border-left-color: var(--dsw-alias-state-business-primary); }\n& .dsh-ui-banner--danger { border-left-color: var(--dsw-alias-state-error-primary); }\n& .dsh-ui-banner--success { border-left-color: var(--dsw-alias-state-success-primary); }\n& .dsh-ui-banner p { margin: 0; }\n\n/* --- Inline notice: a transient confirmation with no chrome of its own. --- */\n& .dsh-ui-notice { display: flex; align-items: center; gap: 6px; font-size: 12px; line-height: 18px; color: var(--dsw-alias-state-success-primary); }\n& .dsh-ui-notice--error { color: var(--dsw-alias-state-error-primary); }\n\n/* --- Empty and loading states. Both sit in a dashed well so an empty panel\n * reads as \"nothing here yet\" rather than as a broken layout. --- */\n& .dsh-ui-empty {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 6px;\n padding: 20px 16px;\n border: 0.5px dashed var(--dsw-alias-border-l3);\n border-radius: var(--dsw-radius-md);\n font-size: 13px;\n line-height: 20px;\n color: var(--dsw-alias-label-secondary);\n}\n& .dsh-ui-loading { display: flex; align-items: center; gap: 8px; padding: 20px 0; font-size: 13px; line-height: 20px; color: var(--dsw-alias-label-secondary); }\n\n/* --- Selectable list. A row is a button-sized target with a hover fill and\n * a selected fill; the name carries the weight, the description does not. --- */\n& .dsh-ui-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; min-width: 0; }\n& .dsh-ui-list-scroll { max-height: min(66vh, 760px); overflow-y: auto; overflow-x: hidden; }\n& .dsh-ui-list-row { border-radius: var(--dsw-radius-md); }\n& .dsh-ui-list-row:hover { background: var(--dsw-alias-interactive-bg-hover); }\n& .dsh-ui-list-row[aria-selected='true'], & .dsh-ui-list-row[data-selected] { background: var(--dsw-alias-interactive-bg-active); }\n& .dsh-ui-list-item {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 4px;\n width: 100%;\n min-width: 0;\n padding: 10px 12px;\n border: 0;\n border-radius: var(--dsw-radius-md);\n background: none;\n font: inherit;\n color: inherit;\n text-align: start;\n cursor: pointer;\n}\n& .dsh-ui-list-item:disabled { cursor: default; }\n& .dsh-ui-list-item:disabled:hover { background: none; }\n& .dsh-ui-list-name { font-size: 14px; line-height: 22px; font-weight: 500; color: var(--dsw-alias-label-primary); overflow-wrap: anywhere; }\n& .dsh-ui-list-desc { font-size: 12px; line-height: 18px; color: var(--dsw-alias-label-tertiary); }\n\n/* --- Code and structured output. Wraps rather than scrolls, because a\n * feature panel is read rather than scanned. --- */\n& .dsh-ui-code {\n padding: 10px 12px;\n border: 0.5px solid var(--dsw-alias-border-l3);\n border-radius: var(--dsw-radius-md);\n background: var(--dsw-alias-bg-layer-1);\n font-family: var(--ds-font-family-code);\n font-size: 12px;\n line-height: 20px;\n color: var(--dsw-alias-label-secondary);\n overflow-wrap: anywhere;\n white-space: pre-wrap;\n}\n& .dsh-ui-scroll { max-height: 60vh; overflow: auto; overscroll-behavior: contain; }\n\n/* --- A toggle row: label on the left, switch on the trailing edge. This is\n * layout only; the switch itself is the official primitive. --- */\n& .dsh-ui-toggle-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; min-width: 0; padding: 12px 0; }\n& .dsh-ui-toggle-row + .dsh-ui-toggle-row { border-top: 0.5px solid var(--dsw-alias-border-l2); }\n& .dsh-ui-toggle-text { display: flex; flex-direction: column; gap: 4px; min-width: 0; }\n& .dsh-ui-toggle-label { font-size: 14px; line-height: 22px; font-weight: 500; color: var(--dsw-alias-label-primary); }\n\n/* --- Floating surface: a panel anchored to a trigger. This is the material\n * a menu card is made of — the translucent fill plus its backdrop blur, with\n * the edge riding inside the prominent elevation. A plugin that hand-rolls this\n * is how tokens like --dsw-specific-menu get invented; use this instead. --- */\n& .dsh-ui-surface {\n --dsw-elevation-stroke-color: var(--dsw-alias-border-l1);\n --dsh-scrollbar-thumb: var(--dsw-alias-scrollbar-bg-l2);\n --dsh-scrollbar-thumb-hover: var(--dsw-alias-scrollbar-hover-l2);\n position: relative;\n display: flex;\n flex-direction: column;\n border: 0;\n border-radius: var(--dsw-radius-lg);\n background: var(--dsw-menu-surface-fill);\n backdrop-filter: var(--dsw-menu-backdrop-filter);\n box-shadow: var(--dsw-elevation-prominent);\n color: var(--dsw-alias-label-primary);\n font-size: 13px;\n line-height: 20px;\n min-width: 0;\n}\n& .dsh-ui-surface-body { display: flex; flex-direction: column; gap: 8px; padding: 12px 14px 14px; overflow-y: auto; }\n& .dsh-ui-surface-head { display: flex; align-items: center; gap: 8px; min-width: 0; }\n& .dsh-ui-surface-title { font-size: 14px; line-height: 22px; font-weight: 500; color: var(--dsw-alias-label-primary); }\n\n/* --- Native select. The primitives ship no select, so a plugin that offers a\n * closed list of choices keeps the platform control and matches the official\n * settings field geometry exactly (34px, 0.5px l4, radius-md, layer-3). A\n * SegmentedControl is the primitive to reach for when the choices are few\n * enough to show at once. --- */\n& .dsh-ui-select {\n box-sizing: border-box;\n width: 100%;\n min-width: 0;\n height: 34px;\n padding: 0 12px;\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: var(--dsw-radius-md);\n background: var(--dsw-alias-bg-layer-3);\n font: inherit;\n font-size: 13px;\n line-height: 1.5;\n color: var(--dsw-alias-label-primary);\n cursor: pointer;\n}\n& .dsh-ui-select:focus-visible { outline: none; border-color: var(--dsw-alias-state-business-primary); }\n& .dsh-ui-select:disabled { color: var(--dsw-alias-label-tertiary); cursor: default; }\n& .dsh-ui-select[aria-invalid='true'] { border-color: var(--dsw-alias-state-error-primary); }\n\n/* --- Native textarea. The primitives ship no textarea either, so a settings\n * prompt keeps the platform element and the same field shell as the select:\n * 0.5px l4, radius-md, layer-3, 13/1.5 type. It grows vertically instead of\n * locking to the select's 34px row. --- */\n& .dsh-ui-textarea {\n box-sizing: border-box;\n width: 100%;\n min-width: 0;\n resize: vertical;\n padding: 8px 12px;\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: var(--dsw-radius-md);\n background: var(--dsw-alias-bg-layer-3);\n font: inherit;\n font-size: 13px;\n line-height: 1.5;\n color: var(--dsw-alias-label-primary);\n}\n& .dsh-ui-textarea:focus-visible { outline: none; border-color: var(--dsw-alias-state-business-primary); }\n& .dsh-ui-textarea:disabled { color: var(--dsw-alias-label-tertiary); cursor: default; }\n& .dsh-ui-textarea::placeholder { color: var(--dsw-alias-label-dimmed); }\n& .dsh-ui-textarea[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-]+)(?=\\s*\\{)/gm, (_match, className: string) =>\n `&${className}, & ${className}`)\n}\n","export const PLUGIN_NAME = '@klarkxy/dsh-magpie'\nexport const PLUGIN_VERSION = '0.1.0'\nexport const RPC_CHANNEL = '/dsh-magpie'\n/** Wire endpoint names; the host RPC transport only admits lowercase/dotted names. */\nexport const RPC_ENDPOINTS = {\n status: 'status',\n saveConnection: 'connection.save',\n test: 'test',\n sync: 'sync',\n setOptions: 'options.set',\n disconnect: 'disconnect',\n} as const\n\n/** The three llm-pi-ai provider routes, named exactly as `magpie dsh` writes them. */\nexport const ROUTES = {\n completions: 'magpie',\n responses: 'magpie-responses',\n anthropic: 'magpie-anthropic',\n} as const\nexport type RouteKind = keyof typeof ROUTES\nexport type RouteName = (typeof ROUTES)[RouteKind]\nexport const ROUTE_NAMES: readonly RouteName[] = [ROUTES.completions, ROUTES.responses, ROUTES.anthropic]\n\n/** Settings namespaces this plugin writes through `ctx.settings`. */\nexport const NS_LLM = 'llm-pi-ai'\nexport const NS_DEFAULT_MODEL = 'agent-default-model'\nexport const NS_WEB_SEARCH = 'web-search-deepseek'\n\nexport const DEFAULT_ADDRESS = 'http://127.0.0.1:3425'\nexport const DEFAULT_KEY_REF = 'MAGPIE_GATEWAY_KEY'\n/** Placeholder bearer the local magpie accepts on loopback, matching magpie's own agent configs. */\nexport const LOOPBACK_PLACEHOLDER_KEY = 'magpie'\nexport const STREAM_IDLE_TIMEOUT_MS = 600000\nexport const GATEWAY_TIMEOUT_MS = 10000\n\nexport interface MagpieOptions {\n address: string\n apiKeyEnv: string\n syncOnStart: boolean\n defaultModel?: string\n webSearch: boolean\n webSearchModel?: string\n}\n\nexport interface GatewayInfo {\n name: string\n version?: string\n}\n\nexport interface SyncResult {\n at: string\n /** Models written per route, keyed by route name. */\n routes: Record<string, number>\n warnings: string[]\n}\n\nexport interface StatusError {\n at: string\n message: string\n}\n\n/** One model currently present in one of the three llm-pi-ai routes. */\nexport interface RouteModel {\n id: string\n name?: string\n route: RouteName\n}\n\nexport interface MagpieStatus {\n address: string\n apiKeyEnv: string\n keyConfigured: boolean\n keyWritable: boolean\n options: Omit<MagpieOptions, 'address' | 'apiKeyEnv'>\n /** Whether the active profile accepts settings writes. */\n writable: boolean\n gateway?: GatewayInfo\n syncing: boolean\n lastSync?: SyncResult\n lastError?: StatusError\n /** Models in the three magpie routes as stored in the active settings. */\n models: RouteModel[]\n}\n\nexport interface SaveConnectionInput {\n address?: string\n apiKey?: string\n clearKey?: boolean\n}\n\nexport interface SetOptionsInput {\n syncOnStart?: boolean\n defaultModel?: string | null\n webSearch?: boolean\n webSearchModel?: string | null\n}\n\nexport interface TestResult {\n gateway: GatewayInfo\n models: number\n}\n\nexport type RpcResult<T = unknown> =\n | { ok: true; value: T }\n | { ok: false; error: { code: string; message: string; details?: Record<string, unknown> } }\n","/**\n * Magpie's group inside the native Models settings page.\n *\n * The host's `settings.models.footer` seat renders after the provider rows and\n * the add-provider button of the Models section, and it projects no label — so\n * the group carries its own visible heading. The connection pair stays open;\n * the rest (default model, web search, sync at startup, disconnect) sits behind\n * one advanced disclosure, so the models page keeps a single compact block\n * instead of a page of its own.\n *\n * All state comes from the host over the plugin RPC channel; the page only\n * drafts the address and the key field, never touches settings files itself.\n */\nimport type { Context } from '@deepseek-ai/cordis'\nimport { Button, Input, Switch, Tag } from '@deepseek-ai/dsh-client-ui-primitives'\nimport { officialUiCss } from '@klarkxy/dsh-plugin-kit/official-ui'\nimport { useCallback, useEffect, useRef, useState, useSyncExternalStore } from 'react'\nimport {\n PLUGIN_NAME, RPC_CHANNEL, RPC_ENDPOINTS,\n type MagpieStatus, type RpcResult, type TestResult,\n} from './contracts.ts'\n\nexport const name = 'dsh-magpie-client'\nexport const inject = ['slots', 'connection', 'locale'] as const\n\ninterface Client {\n connection: { rpc: { call(channel: string, endpoint: string, payload: unknown): Promise<unknown> } }\n locale?: { getSnapshot(): { active: string }; subscribe(listener: () => void): () => void }\n slots: {\n inject(key: string, callback: () => unknown): () => void\n register(spec: { name: string; id: string; order?: number }, render: unknown): () => void\n }\n}\n\nconst styles = `${officialUiCss('.mgp-root')}\n.mgp-root .mgp-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; flex-wrap: wrap; min-width: 0; }\n.mgp-root .mgp-row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }\n.mgp-root .mgp-grow { flex: 1 1 220px; min-width: 0; }\n.mgp-root .mgp-danger { color: var(--dsw-alias-state-error-primary); }\n/* The advanced disclosure: a plain details/summary, so it opens without any\n * script and keeps the keyboard behaviour the platform gives it. */\n.mgp-root .mgp-advanced { border-top: 0.5px solid var(--dsw-alias-border-l2); padding-top: 8px; min-width: 0; }\n.mgp-root .mgp-advanced > summary { display: inline-flex; align-items: center; gap: 6px; width: fit-content; cursor: pointer; list-style: none; font-size: 12px; line-height: 18px; font-weight: 500; color: var(--dsw-alias-label-secondary); }\n.mgp-root .mgp-advanced > summary::-webkit-details-marker { display: none; }\n.mgp-root .mgp-advanced > summary::before { content: ''; width: 5px; height: 5px; border-right: 1.5px solid currentcolor; border-bottom: 1.5px solid currentcolor; transform: rotate(-45deg) translate(-1px, -1px); transition: transform 120ms ease; }\n.mgp-root .mgp-advanced[open] > summary::before { transform: rotate(45deg) translate(-1px, -1px); }\n.mgp-root .mgp-advanced > summary:hover { color: var(--dsw-alias-label-primary); }\n.mgp-root .mgp-advanced-body { display: flex; flex-direction: column; gap: 12px; padding-top: 12px; min-width: 0; }\n`\n\nconst copy = {\n zh: {\n loading: '正在读取状态…', failed: '操作失败:', retry: '重试',\n title: 'Magpie', intro: '连接本机、局域网或远程的 magpie 网关,把它的模型加入本 profile 的模型列表。',\n address: '网关地址', addressHelp: '本机、局域网或远程的 magpie 网关,例如 http://127.0.0.1:3425。',\n key: '网关 Key', keyHelp: '非本机网关需要 Key;本机网关留空会自动使用占位 Key。',\n keyPlaceholder: '输入网关 Key', keyConfigured: '已保存', keyClear: '清除',\n test: '测试', save: '保存', saved: '已保存。',\n syncNow: '立即同步', syncing: '正在同步…', syncOnStart: '启动时同步', syncOnStartHelp: '每次启动本 profile 时同步一次。',\n lastSync: '上次同步', never: '从未同步', models: (n: number) => `${n} 个模型`,\n warnings: '警告', readonlyHint: '当前 profile 的设置只读,无法写入。',\n defaultModel: '默认模型', defaultModelHelp: '把某个 magpie 模型设为新会话的默认模型。',\n keepCurrent: '不更改', webSearch: '网络搜索', webSearchHelp: '通过网关用所选模型执行网络搜索。',\n sameAsDefault: '与默认模型相同', disconnect: '断开连接', confirmDisconnect: '确认断开?',\n disconnectHelp: '移除三条 magpie 供应商路由并还原默认模型与网络搜索;已保存的 Key 保留。',\n testOk: (n: number) => `连接正常,网关返回 ${n} 个模型。`, notConnected: '尚未连接。',\n advanced: '高级设置',\n },\n en: {\n loading: 'Loading status…', failed: 'Action failed: ', retry: 'Retry',\n title: 'Magpie', intro: 'Point DSH at a magpie gateway on this computer, your LAN, or elsewhere, and its models join this profile.',\n address: 'Gateway address', addressHelp: 'A magpie gateway on this computer, your LAN, or elsewhere, e.g. http://127.0.0.1:3425.',\n key: 'Gateway key', keyHelp: 'Non-local gateways need a key; a local gateway uses a placeholder automatically.',\n keyPlaceholder: 'Enter gateway key', keyConfigured: 'Saved', keyClear: 'Clear',\n test: 'Test', save: 'Save', saved: 'Saved.',\n syncNow: 'Sync now', syncing: 'Syncing…', syncOnStart: 'Sync at startup', syncOnStartHelp: 'Run one sync every time this profile starts.',\n lastSync: 'Last sync', never: 'Never synced', models: (n: number) => `${n} models`,\n warnings: 'Warnings', readonlyHint: 'Settings are read-only in this profile; nothing can be written.',\n defaultModel: 'Default model', defaultModelHelp: 'Promote a magpie model to the default for new conversations.',\n keepCurrent: \"Don't change\", webSearch: 'Web search', webSearchHelp: 'Run web search through the gateway with the selected model.',\n sameAsDefault: 'Same as default model', disconnect: 'Disconnect', confirmDisconnect: 'Confirm disconnect?',\n disconnectHelp: 'Removes the three magpie provider routes and reverts the default model and web search; the saved key is kept.',\n testOk: (n: number) => `Connection OK: the gateway returned ${n} models.`, notConnected: 'Not connected yet.',\n advanced: 'Advanced',\n },\n} as const\n\ntype Copy = (typeof copy)['zh'] | (typeof copy)['en']\n\nclass RpcError extends Error {\n constructor(readonly code: string, message: string) { super(message); this.name = 'RpcError' }\n}\n\nconst SYNC_POLL_MS = 1500\n\nfunction useHostLocale(client: Client): 'zh' | 'en' {\n const subscribe = useCallback((listener: () => void) => client.locale?.subscribe(listener) ?? (() => {}), [client])\n const snapshot = useCallback(() => client.locale?.getSnapshot().active ?? 'zh', [client])\n return String(useSyncExternalStore(subscribe, snapshot, snapshot)).startsWith('zh') ? 'zh' : 'en'\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 const disarm = () => { clearTimeout(timer.current); setArmed(false) }\n return <Button variant=\"outline\" size=\"sm\" className=\"mgp-danger\" disabled={props.disabled}\n onClick={() => {\n if (!armed) { setArmed(true); timer.current = setTimeout(() => setArmed(false), 3000); return }\n disarm(); props.onConfirm()\n }}\n onBlur={disarm}>{armed ? props.confirmLabel : props.label}</Button>\n}\n\nexport function MagpieSettingsPage({ client }: { client: Client }) {\n const locale = useHostLocale(client)\n const text: Copy = copy[locale]\n const [status, setStatus] = useState<MagpieStatus>()\n const [address, setAddress] = useState('')\n const [addressDirty, setAddressDirty] = useState(false)\n const [keyDraft, setKeyDraft] = useState('')\n const [busy, setBusy] = useState<string>('')\n const [note, setNote] = useState('')\n const [error, setError] = useState('')\n const mounted = useRef(true)\n\n const call = useCallback(async <T,>(endpoint: string, payload: unknown = {}): Promise<T> => {\n const result = await client.connection.rpc.call(RPC_CHANNEL, endpoint, payload) as RpcResult<T>\n if (!result.ok) throw new RpcError(result.error.code, result.error.message)\n return result.value\n }, [client])\n\n const load = useCallback(async () => {\n try {\n const next = await call<MagpieStatus>(RPC_ENDPOINTS.status)\n if (!mounted.current) return\n setStatus(next)\n setAddress(current => addressDirty ? current : next.address)\n setError('')\n } catch (reason) {\n if (mounted.current) setError(reason instanceof Error ? reason.message : String(reason))\n }\n }, [call, addressDirty])\n\n useEffect(() => {\n mounted.current = true\n void load()\n return () => { mounted.current = false }\n }, [load])\n\n // While a sync runs, poll until it lands so counts and warnings show up.\n useEffect(() => {\n if (!status?.syncing) return\n const timer = setInterval(() => { void load() }, SYNC_POLL_MS)\n return () => clearInterval(timer)\n }, [status?.syncing, load])\n\n const action = useCallback(async (name: string, run: () => Promise<void>) => {\n if (busy) return\n setBusy(name); setNote(''); setError('')\n try { await run() }\n catch (reason) { if (mounted.current) setError(reason instanceof Error ? reason.message : String(reason)) }\n finally { if (mounted.current) setBusy('') }\n }, [busy])\n\n const refresh = (next: MagpieStatus) => { setStatus(next); setAddress(current => addressDirty ? current : next.address) }\n\n if (!status) {\n return <section className=\"mgp-root dsh-ui-card\" data-testid=\"magpie-settings\">\n <span className=\"dsh-ui-heading\">{text.title}</span>\n {error\n ? <p role=\"alert\" className=\"dsh-ui-error\">{text.failed}{error}</p>\n : <p role=\"status\" className=\"dsh-ui-hint\">{text.loading}</p>}\n <div className=\"dsh-ui-actions\">\n <Button variant=\"ghost\" size=\"sm\" disabled={Boolean(busy)} onClick={() => void load()}>{text.retry}</Button>\n </div>\n </section>\n }\n\n const models = status.models\n const defaultChoices = models.map(model => model.id)\n if (status.options.defaultModel && !defaultChoices.includes(status.options.defaultModel)) {\n defaultChoices.unshift(status.options.defaultModel)\n }\n const modelLabel = (id: string) => {\n const found = models.find(model => model.id === id)\n return found ? `${found.name ?? id} · ${found.route}` : id\n }\n const gatewaySummary = status.gateway\n ? `${status.gateway.name}${status.gateway.version ? ` ${status.gateway.version}` : ''} · ${text.models(models.length)}`\n : text.notConnected\n\n return <section className=\"mgp-root dsh-ui-card\" data-testid=\"magpie-settings\">\n <div className=\"mgp-head\">\n <span className=\"dsh-ui-heading\">{text.title}</span>\n <span className=\"dsh-ui-meta\">{gatewaySummary}</span>\n </div>\n <p className=\"dsh-ui-help\">{text.intro}</p>\n {status.writable === false ? <p role=\"status\" className=\"dsh-ui-hint\">{text.readonlyHint}</p> : null}\n {error ? <p role=\"alert\" className=\"dsh-ui-error\">{text.failed}{error}</p> : null}\n {note ? <p role=\"status\" className=\"dsh-ui-notice\">{note}</p> : null}\n\n <div className=\"dsh-ui-fields-grid\">\n <label className=\"dsh-ui-field\">\n <span className=\"dsh-ui-label\">{text.address}</span>\n <Input value={addressDirty ? address : status.address}\n placeholder=\"http://127.0.0.1:3425\"\n onChange={event => { setAddress(event.target.value); setAddressDirty(true) }} />\n <span className=\"dsh-ui-help\">{text.addressHelp}</span>\n </label>\n <label className=\"dsh-ui-field\">\n <span className=\"dsh-ui-label\">{text.key} {status.keyConfigured ? <Tag tone=\"success\">{text.keyConfigured}</Tag> : null}</span>\n <span className=\"mgp-row\">\n <span className=\"mgp-grow\">\n <Input type=\"password\" value={keyDraft} placeholder={text.keyPlaceholder}\n onChange={event => setKeyDraft(event.target.value)} />\n </span>\n {status.keyConfigured ? <Button variant=\"ghost\" size=\"sm\" disabled={Boolean(busy)}\n onClick={() => void action('clear-key', async () => {\n refresh(await call<MagpieStatus>(RPC_ENDPOINTS.saveConnection, { clearKey: true }))\n setNote(text.saved)\n })}>{text.keyClear}</Button> : null}\n </span>\n <span className=\"dsh-ui-help\">{text.keyHelp}</span>\n </label>\n </div>\n\n <div className=\"dsh-ui-actions\">\n <Button variant=\"outline\" size=\"sm\" disabled={Boolean(busy)} onClick={() => void action('test', async () => {\n if (addressDirty || keyDraft) {\n refresh(await call<MagpieStatus>(RPC_ENDPOINTS.saveConnection, {\n address, apiKey: keyDraft || undefined,\n }))\n setKeyDraft(''); setAddressDirty(false)\n }\n const result = await call<TestResult>(RPC_ENDPOINTS.test)\n setNote(text.testOk(result.models))\n await load()\n })}>{text.test}</Button>\n <Button variant=\"primary\" size=\"sm\" disabled={Boolean(busy) || (!addressDirty && !keyDraft)} onClick={() => void action('save', async () => {\n refresh(await call<MagpieStatus>(RPC_ENDPOINTS.saveConnection, { address, apiKey: keyDraft || undefined }))\n setKeyDraft(''); setAddressDirty(false); setNote(text.saved)\n })}>{text.save}</Button>\n <Button variant=\"outline\" size=\"sm\" disabled={Boolean(busy) || status.syncing} onClick={() => void action('sync', async () => {\n refresh(await call<MagpieStatus>(RPC_ENDPOINTS.sync))\n setNote(text.saved)\n })}>{status.syncing ? text.syncing : text.syncNow}</Button>\n </div>\n\n <details className=\"mgp-advanced\">\n <summary>{text.advanced}</summary>\n <div className=\"mgp-advanced-body\">\n <label className=\"dsh-ui-field\">\n <span className=\"dsh-ui-label\">{text.defaultModel}</span>\n <select className=\"dsh-ui-select\" value={status.options.defaultModel ?? ''} disabled={Boolean(busy)}\n onChange={event => void action('options', async () => {\n refresh(await call<MagpieStatus>(RPC_ENDPOINTS.setOptions, { defaultModel: event.target.value || null }))\n })}>\n <option value=\"\">{text.keepCurrent}</option>\n {defaultChoices.map(id => <option key={id} value={id}>{modelLabel(id)}</option>)}\n </select>\n <span className=\"dsh-ui-help\">{text.defaultModelHelp}</span>\n </label>\n\n <div className=\"dsh-ui-toggle-row\">\n <span className=\"dsh-ui-toggle-text\">\n <span className=\"dsh-ui-toggle-label\">{text.webSearch}</span>\n <span className=\"dsh-ui-help\">{text.webSearchHelp}</span>\n </span>\n <Switch checked={status.options.webSearch} disabled={Boolean(busy)} label={text.webSearch}\n onChange={next => void action('options', async () => {\n refresh(await call<MagpieStatus>(RPC_ENDPOINTS.setOptions, { webSearch: next }))\n })} />\n </div>\n {status.options.webSearch ? <label className=\"dsh-ui-field\">\n <select className=\"dsh-ui-select\" value={status.options.webSearchModel ?? ''} disabled={Boolean(busy)}\n onChange={event => void action('options', async () => {\n refresh(await call<MagpieStatus>(RPC_ENDPOINTS.setOptions, { webSearchModel: event.target.value || null }))\n })}>\n <option value=\"\">{text.sameAsDefault}</option>\n {models.map(model => <option key={model.id} value={model.id}>{model.name ?? model.id}</option>)}\n </select>\n </label> : null}\n\n <div className=\"dsh-ui-toggle-row\">\n <span className=\"dsh-ui-toggle-text\">\n <span className=\"dsh-ui-toggle-label\">{text.syncOnStart}</span>\n <span className=\"dsh-ui-help\">{text.syncOnStartHelp}</span>\n </span>\n <Switch checked={status.options.syncOnStart} disabled={Boolean(busy)} label={text.syncOnStart}\n onChange={next => void action('options', async () => {\n refresh(await call<MagpieStatus>(RPC_ENDPOINTS.setOptions, { syncOnStart: next }))\n })} />\n </div>\n\n <p className=\"dsh-ui-meta\">\n {text.lastSync}: {status.lastSync\n ? `${new Date(status.lastSync.at).toLocaleString()} · ${Object.entries(status.lastSync.routes).map(([route, count]) => `${route}: ${count}`).join(' · ')}`\n : text.never}\n </p>\n {status.lastSync?.warnings.length ? <div>\n <p className=\"dsh-ui-label\">{text.warnings}</p>\n {status.lastSync.warnings.map((warning, index) => <p key={index} className=\"dsh-ui-hint\">{warning}</p>)}\n </div> : null}\n {status.lastError ? <p role=\"alert\" className=\"dsh-ui-error\">{new Date(status.lastError.at).toLocaleString()} · {status.lastError.message}</p> : null}\n\n <div className=\"mgp-row\">\n <div className=\"mgp-grow\">\n <span className=\"dsh-ui-label\">{text.disconnect}</span>\n <p className=\"dsh-ui-help\">{text.disconnectHelp}</p>\n </div>\n <ConfirmButton label={text.disconnect} confirmLabel={text.confirmDisconnect} disabled={Boolean(busy)}\n onConfirm={() => void action('disconnect', async () => {\n refresh(await call<MagpieStatus>(RPC_ENDPOINTS.disconnect))\n setNote(text.saved)\n })} />\n </div>\n </div>\n </details>\n </section>\n}\n\nexport function apply(ctx: Context): void {\n const client = ctx as unknown as Client\n ctx.effect(() => {\n if (typeof document === 'undefined') return () => {}\n const style = document.createElement('style')\n style.setAttribute('data-plugin', PLUGIN_NAME)\n style.textContent = styles\n document.head.appendChild(style)\n return () => style.remove()\n }, 'magpie.styles')\n // The Models section owns this seat: the group appears under the provider\n // rows, and the host re-runs the registration whenever that section mounts.\n // A merged group seat carries no label — the host projects none — so the\n // group renders its own heading above.\n ctx.effect(() => client.slots.inject('settings.models.footer', () => client.slots.register(\n { name: 'settings.models.footer', id: 'magpie', order: 100 },\n () => <MagpieSettingsPage client={client} />,\n )), 'magpie.settings')\n}\n"],"mappings":"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"}