@dawn0608/dsh-skill-manager 0.1.6 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/client.js CHANGED
@@ -1355,7 +1355,7 @@ __export(index_exports, {
1355
1355
  inject: () => inject
1356
1356
  });
1357
1357
  module.exports = __toCommonJS(index_exports);
1358
- var import_react7 = require("react");
1358
+ var import_react8 = require("react");
1359
1359
 
1360
1360
  // ../../src/client/host-controls.js
1361
1361
  var import_react = require("react");
@@ -29763,7 +29763,7 @@ function parseSelector(selector, defaultTagName) {
29763
29763
  // ../../node_modules/hastscript/lib/create-h.js
29764
29764
  function createH(schema, defaultTagName, caseSensitive) {
29765
29765
  const adjust = caseSensitive ? createAdjustMap(caseSensitive) : void 0;
29766
- function h9(selector, properties, ...children) {
29766
+ function h10(selector, properties, ...children) {
29767
29767
  let node2;
29768
29768
  if (selector === null || selector === void 0) {
29769
29769
  node2 = { type: "root", children: [] };
@@ -29794,7 +29794,7 @@ function createH(schema, defaultTagName, caseSensitive) {
29794
29794
  }
29795
29795
  return node2;
29796
29796
  }
29797
- return h9;
29797
+ return h10;
29798
29798
  }
29799
29799
  function isChild(value) {
29800
29800
  if (value === null || typeof value !== "object" || Array.isArray(value)) {
@@ -37333,7 +37333,7 @@ function S2(a2, v2, N = null) {
37333
37333
  c = true;
37334
37334
  }, skip() {
37335
37335
  c = true;
37336
- } }, { type: f2 } = e, u2 = v2["*"], h9 = v2[f2], R3 = typeof u2 == "function" ? u2 : u2?.enter, P3 = typeof h9 == "function" ? h9 : h9?.enter;
37336
+ } }, { type: f2 } = e, u2 = v2["*"], h10 = v2[f2], R3 = typeof u2 == "function" ? u2 : u2?.enter, P3 = typeof h10 == "function" ? h10 : h10?.enter;
37337
37337
  if (R3?.(d2, N), P3?.(d2, N), !c) switch (f2) {
37338
37338
  case "AbsenceFunction":
37339
37339
  case "Alternative":
@@ -37364,7 +37364,7 @@ function S2(a2, v2, N = null) {
37364
37364
  default:
37365
37365
  throw new Error(`Unexpected node type "${f2}"`);
37366
37366
  }
37367
- return h9?.exit?.(d2, N), u2?.exit?.(d2, N), i3;
37367
+ return h10?.exit?.(d2, N), u2?.exit?.(d2, N), i3;
37368
37368
  }
37369
37369
  return n(a2), a2;
37370
37370
  }
@@ -40322,6 +40322,9 @@ function DetailDocument({ state, labels, onRetry }) {
40322
40322
  // ../../src/client/host-controls.css
40323
40323
  var host_controls_default = "/* Adapted from DeepSeek Harness ui-primitives 0.2.2-rc.1, MIT. See THIRD_PARTY_NOTICES.md. */\n/* The on/off appearance keys off aria-checked rather than a parallel class, so\n * the visual state cannot disagree with the state assistive technology reads.\n *\n * The capsule track and circular thumb opt out of the global superellipse. */\n.dshui_switch_switch {\n box-sizing: border-box;\n position: relative;\n flex: 0 0 auto;\n width: 36px;\n height: 20px;\n padding: 2px;\n border: 0;\n border-radius: 999px;\n corner-shape: round;\n background: var(--dsw-alias-border-l3);\n cursor: pointer;\n}\n\n.dshui_switch_switch[aria-checked='true'] {\n background: var(--dsw-alias-brand-primary);\n}\n\n.dshui_switch_switch:disabled {\n cursor: default;\n opacity: 0.5;\n}\n\n.dshui_switch_switch:focus-visible {\n outline: var(--dsw-focus-ring-width) solid var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));\n outline-offset: 2px;\n}\n\n.dshui_switch_thumb {\n display: block;\n width: 16px;\n height: 16px;\n border-radius: 50%;\n corner-shape: round;\n background: var(--dsw-alias-label-primary-foreground);\n transition: transform 120ms ease;\n}\n\n.dshui_switch_switch[aria-checked='false'] .dshui_switch_thumb {\n background: var(--dsw-alias-switch-thumb);\n}\n\n.dshui_switch_switch[aria-checked='true'] .dshui_switch_thumb {\n transform: translateX(16px);\n}\n\n/* Capsule geometry is fixed: a tag reads as one size everywhere, and only its\n * palette varies. Tone colors ride background/border/color so a render site can\n * still position the tag with its own class without touching the palette. */\n.dshui_tag_tag {\n display: inline-flex;\n align-items: center;\n border-radius: 999px;\n corner-shape: round;\n padding: 1px 8px;\n font-size: 11px;\n line-height: 17px;\n font-weight: 500;\n white-space: nowrap;\n}\n\n.dshui_tag_tag[data-tone='outline'] {\n border: 0.5px solid var(--dsw-alias-border-l4);\n color: var(--dsw-alias-label-tertiary);\n}\n\n.dshui_tag_tag[data-tone='solid'] {\n background: var(--dsw-alias-label-primary);\n color: var(--dsw-alias-bg-layer-3);\n}\n\n.dshui_tag_tag[data-tone='neutral'] {\n background: var(--dsw-alias-bg-module-platform);\n color: var(--dsw-alias-label-secondary);\n}\n\n.dshui_tag_tag[data-tone='quiet'] {\n color: var(--dsw-alias-label-tertiary);\n}\n\n/* Status tones tint their own color for the fill, so a palette change moves\n * fill and text together and neither needs a second token. The tint is 10%,\n * except `warning`, which keeps the 12% the plugin inventory's conditional\n * tag shipped with \u2014 matching it is what makes this a pure consolidation. */\n.dshui_tag_tag[data-tone='success'] {\n background: color-mix(in srgb, var(--dsw-alias-state-success-primary) 10%, transparent);\n color: var(--dsw-alias-state-success-primary);\n}\n\n.dshui_tag_tag[data-tone='info'] {\n background: color-mix(in srgb, var(--dsw-alias-state-business-primary) 10%, transparent);\n color: var(--dsw-alias-state-business-primary);\n}\n\n.dshui_tag_tag[data-tone='warning'] {\n background: color-mix(in srgb, var(--dsw-alias-state-warn-primary) 12%, transparent);\n color: var(--dsw-alias-state-warn-primary);\n}\n\n.dshui_tag_tag[data-tone='danger'] {\n background: color-mix(in srgb, var(--dsw-alias-state-error-primary) 10%, transparent);\n color: var(--dsw-alias-state-error-primary);\n}\n\n.dshui_input_wrap {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n height: 32px;\n padding: 0 8px;\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: var(--dsw-radius-md);\n background: var(--dsw-alias-bg-layer-1);\n}\n\n.dshui_input_wrap:focus-within {\n border-color: var(--dsw-alias-state-business-primary);\n}\n\n.dshui_input_icon {\n display: inline-flex;\n width: 16px;\n height: 16px;\n align-items: center;\n justify-content: center;\n color: var(--dsw-alias-label-tertiary);\n}\n\n.dshui_input_input {\n flex: 1;\n min-width: 0;\n border: none;\n outline: none;\n background: transparent;\n font-size: 14px;\n line-height: 22px;\n color: var(--dsw-alias-label-primary);\n}\n\n.dshui_input_input::placeholder {\n color: var(--dsw-alias-label-dimmed);\n}\n\n/* Button sizes share the global control-radius scale. */\n.dshui_button_button {\n box-sizing: border-box;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 4px;\n border: none;\n border-radius: var(--dsw-radius-md);\n cursor: pointer;\n font-size: 14px;\n line-height: 22px;\n color: var(--dsw-alias-label-primary);\n background: transparent;\n padding: 0 14px;\n}\n\n.dshui_button_button:disabled {\n cursor: not-allowed;\n opacity: 0.4;\n}\n\n.dshui_button_md {\n height: 36px;\n}\n\n/* Compact controls retain their dimensions across filled and outlined variants. */\n.dshui_button_sm {\n height: 28px;\n font-size: 12px;\n line-height: 18px;\n padding: 0 10px;\n border-radius: var(--dsw-radius-sm);\n}\n\n.dshui_button_primary {\n background: var(--dsw-alias-button-primary-fill);\n color: var(--dsw-alias-label-primary-foreground);\n}\n\n@media (hover: hover) {\n .dshui_button_primary:hover:not(:disabled) {\n background: var(--dsw-alias-button-primary-hover);\n }\n\n .dshui_button_ghost:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover);\n }\n}\n\n.dshui_button_ghost:active:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-active);\n}\n\n/* The transparent border preserves layout; the inset stroke stays complete at fractional widths. */\n.dshui_button_outline {\n border: 0.5px solid transparent;\n background: transparent;\n box-shadow: inset 0 0 0 var(--dsh-hairline-width, 0.5px) var(--dsh-button-outline-color, var(--dsw-alias-border-l3));\n}\n\n@media (hover: hover) {\n .dshui_button_outline:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover);\n }\n}\n\n.dshui_button_toolbar {\n background: var(--dsw-alias-button-tool-bar-fill);\n}\n\n@media (hover: hover) {\n .dshui_button_toolbar:hover:not(:disabled) {\n background: var(--dsw-alias-button-tool-bar-hover);\n }\n}\n\n.dshui_button_icon {\n display: inline-flex;\n width: 16px;\n height: 16px;\n align-items: center;\n justify-content: center;\n}\n\n/* Solid states keep the 10px layout slot but paint one 6px currentColor core. */\n.dshui_state_dot {\n position: relative;\n display: inline-block;\n flex: none;\n}\n\n.dshui_state_dot::after {\n content: '';\n position: absolute;\n inset: 20%;\n border-radius: 50%;\n corner-shape: round;\n background: currentColor;\n}\n\n.dshui_state_dot[data-state='done'] {\n color: var(--dsw-alias-state-success-primary);\n}\n\n.dshui_state_dot[data-state='warning'] {\n color: var(--dsw-alias-state-warn-primary);\n}\n\n.dshui_state_dot[data-state='error'] {\n color: var(--dsw-alias-state-error-primary);\n}\n\n/* Idle is the absence of activity and uses the theme's neutral state step. */\n.dshui_state_dot[data-state='idle'] {\n color: var(--dsw-alias-state-idle-primary);\n}\n\n/* Ongoing is the sole non-dot state: a quiet full ring sits behind a centered\n * breathing arc while the complete glyph rotates continuously. Both animations\n * share one 1.5s period so pinning their start times aligns them together. */\n.dshui_state_spinner {\n flex: none;\n color: var(--dsw-alias-label-tertiary);\n}\n\n.dshui_state_spinnerMotion {\n transform-origin: center;\n animation: dshui-state-dot-spin 1.5s linear infinite;\n}\n\n.dshui_state_spinnerTrack,\n.dshui_state_spinnerArc {\n fill: none;\n stroke: currentColor;\n stroke-width: 2;\n stroke-linecap: round;\n}\n\n.dshui_state_spinnerTrack {\n opacity: 0.25;\n}\n\n.dshui_state_spinnerArc {\n stroke-dasharray: 12 150;\n animation: dshui-state-dot-dash 1.5s ease-in-out infinite;\n}\n\n@keyframes dshui-state-dot-spin {\n to { transform: rotate(360deg); }\n}\n\n@keyframes dshui-state-dot-dash {\n 0% {\n stroke-dasharray: 12 150;\n stroke-dashoffset: 0;\n }\n\n 50% {\n stroke-dasharray: 24 150;\n stroke-dashoffset: -6;\n }\n\n 100% {\n stroke-dasharray: 12 150;\n stroke-dashoffset: 0;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .dshui_state_spinnerMotion,\n .dshui_state_spinnerArc {\n animation: none;\n }\n\n .dshui_state_spinnerArc {\n stroke-dasharray: 18 150;\n stroke-dashoffset: -3;\n }\n}\n\n.dshui_state_step { display: inline-flex; flex: none; align-items: center; justify-content: center; box-sizing: border-box; border-radius: 50%; corner-shape: round; border: 1.5px solid var(--dsw-alias-label-tertiary); color: var(--dsw-alias-label-primary-foreground); }\n.dshui_state_step[data-state='done'] { border-color: var(--dsw-alias-state-success-primary); background: var(--dsw-alias-state-success-primary); }\n.dshui_state_step[data-state='error'] { border-color: var(--dsw-alias-state-error-primary); background: var(--dsw-alias-state-error-primary); }\n.dshui_state_step[data-state='warning'] { border-color: var(--dsw-alias-state-warn-primary); }\n";
40324
40324
 
40325
+ // ../../src/client/host-modal.css
40326
+ var host_modal_default = "/* Native Modal geometry, with the existing browser dialog top layer. */\n.dshui_modal {\n position: fixed;\n width: min(380px, calc(100vw - 48px));\n max-width: none;\n max-height: calc(100dvh - 2 * max(24px, var(--dsh-frame-overlay-top, 24px)));\n margin: auto;\n padding: 0 0 24px;\n overflow: auto;\n box-sizing: border-box;\n border: 0;\n border-radius: var(--dsw-radius-panel);\n background: var(--dsw-alias-bg-layer-2);\n color: var(--dsw-alias-label-primary);\n box-shadow: var(--dsw-elevation-prominent);\n animation: dshui-modal-enter var(--ds-transition-duration) var(--ds-ease-in-out);\n}\n.dshui_modal[open] { display: flex; flex-direction: column; gap: 20px; }\n.dshui_modal:focus { outline: none; }\n.dshui_modal::backdrop {\n inset: var(--dsh-frame-chrome-top, 0px) 0 0;\n background: var(--dsw-alias-bg-mask-1);\n backdrop-filter: var(--dsw-mask-blur);\n animation: dshui-modal-enter var(--ds-transition-duration) var(--ds-ease-in-out);\n}\n.dshui_modalContent { display: flex; flex-direction: column; width: 100%; }\n.dshui_modalHeader {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n padding: 22px 14px 12px 24px;\n}\n.dshui_modalHeader h2 { margin: 0; font-size: 16px; line-height: 24px; font-weight: 500; }\n.dshui_modalClose {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border: none;\n border-radius: var(--dsw-radius-sm);\n background: transparent;\n cursor: pointer;\n color: var(--dsw-alias-label-secondary);\n}\n.dshui_modalClose:disabled { cursor: not-allowed; opacity: 0.4; }\n.dshui_modalClose:focus-visible {\n outline: 1px solid var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));\n outline-offset: 2px;\n}\n@media (hover: hover) {\n .dshui_modalClose:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover); }\n}\n.dshui_modalDescription { margin: 0; padding: 0 24px; font-size: 14px; line-height: 22px; overflow-wrap: anywhere; }\n.dshui_modalBody { display: flex; flex-direction: column; min-width: 0; margin-top: 20px; padding: 0 24px; }\n.dshui_modalActions { display: flex; align-items: center; justify-content: flex-end; gap: 8px; padding: 0 24px; }\n.dshui_modalDangerButton {\n --dsw-alias-button-primary-fill: var(--dsw-alias-state-error-primary);\n --dsw-alias-button-primary-hover: var(--dsw-alias-state-error-primary);\n}\n@keyframes dshui-modal-enter { from { opacity: 0; } to { opacity: 1; } }\n@media (prefers-reduced-motion: reduce) { .dshui_modal, .dshui_modal::backdrop { animation: none; } }\n";
40327
+
40325
40328
  // ../../src/client/host-document.css
40326
40329
  var host_document_default = "/* Native DetailDocument and Markdown styles, Harness 0.2.2-rc.1 (MIT). See THIRD_PARTY_NOTICES.md. */\n.dshdoc_detail_section {\n display: flex;\n flex-direction: column;\n gap: 12px;\n min-width: 0;\n}\n\n.dshdoc_detail_document {\n min-width: 0;\n /* A long README scrolls inside the section instead of pushing the page's later sections out of reach. */\n max-height: min(560px, 60vh);\n overflow-y: auto;\n /* Horizontal rules separate the document from its neighbors; a full frame would clash with the images' own corners. */\n border-block: 0.5px solid var(--dsw-alias-border-l1);\n /* Keep the scrollbar off the text and the text width independent of overflow. */\n scrollbar-gutter: stable;\n padding: 12px 0;\n overflow-wrap: anywhere;\n}\n\n.dshdoc_detail_document:focus-visible {\n outline: var(--dsw-focus-ring-width) solid var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));\n outline-offset: 3px;\n}\n\n.dshdoc_detail_failure {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.dshdoc_detail_error {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n margin: 0;\n font-size: 13px;\n line-height: 20px;\n color: var(--dsw-alias-state-error-primary);\n}\n\n.dshdoc_detail_skeleton {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.dshdoc_detail_bar {\n display: block;\n height: 12px;\n border-radius: var(--dsw-radius-xs);\n background: var(--dsw-alias-bg-skeleton);\n animation: dshdoc-detail-skeleton 2s cubic-bezier(0.36, 0, 0.64, 1) infinite;\n}\n\n.dshdoc_detail_long { width: min(480px, 90%); }\n.dshdoc_detail_short { width: min(240px, 50%); }\n\n@keyframes dshdoc-detail-skeleton {\n 0% { opacity: 1; }\n 40% { opacity: 0.6; }\n 80%, 100% { opacity: 1; }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .dshdoc_detail_bar { animation: none; }\n}\n\n/* Visual baseline: deepsuite `@deepseek/md` markdown.css, adapted to CSS\n Modules. Cite pills and header anchors are absent (no matching DOM).\n Token names match that sheet. */\n\n.dshdoc_md_markdown {\n min-width: 0;\n overflow-wrap: anywhere;\n font: var(--dsw-font-markdown-base);\n color: var(--dsw-alias-label-primary);\n}\n\n.dshdoc_md_markdown strong {\n font-weight: 600;\n}\n\n.dshdoc_md_markdown h1 {\n font: var(--dsw-font-markdown-h1);\n margin: 32px 0 16px;\n}\n\n.dshdoc_md_markdown h2 {\n font: var(--dsw-font-markdown-h2);\n margin: 32px 0 16px;\n}\n\n.dshdoc_md_markdown h3 {\n font: var(--dsw-font-markdown-h3);\n margin: 32px 0 16px;\n}\n\n.dshdoc_md_markdown h4 {\n font: var(--dsw-font-markdown-h4);\n margin: 16px 0;\n}\n\n.dshdoc_md_markdown :where(h5, h6) {\n font: var(--dsw-font-markdown-base-strong);\n margin: 16px 0;\n}\n\n.dshdoc_md_markdown :where(h1, h2, h3, h4, h5, h6) strong {\n font-weight: inherit;\n}\n\n.dshdoc_md_markdown p {\n margin: 16px 0;\n}\n\n/* Tighten h4\u2013h6 against a following list (design: 8px gap). */\n.dshdoc_md_markdown :where(h4, h5, h6) + :where(ul, ol) {\n margin-top: 8px;\n}\n\n.dshdoc_md_markdown :where(h4, h5, h6):has(+ :where(ul, ol)) {\n margin-bottom: 8px;\n}\n\n.dshdoc_md_markdown a,\n.dshdoc_md_markdown .dshdoc_md_fileLink {\n /* deepsuite markdown.css uses brand-text (blue in newDesign); this sheet\n keeps design-platform brand-text as near-black, so links use the\n dedicated link alias instead. */\n color: var(--dsw-alias-link);\n font-weight: 500;\n transition: box-shadow var(--ds-transition-duration) var(--ds-ease-in-out);\n position: relative;\n text-decoration: none;\n /* Transparent hit-area padding; literal zero-alpha only (no painted color). */\n border-left: 3px solid rgb(255 255 255 / 0);\n border-right: 3px solid rgb(255 255 255 / 0);\n border-top: 2px solid rgb(255 255 255 / 0);\n border-bottom: 2px solid rgb(255 255 255 / 0);\n margin-left: -3px;\n margin-right: -3px;\n}\n\n.dshdoc_md_markdown a:focus {\n outline: none;\n text-decoration: underline dotted var(--dsw-alias-link);\n text-underline-offset: 3px;\n}\n\n@media (hover: hover) {\n .dshdoc_md_markdown a:hover {\n outline: none;\n text-decoration: underline dotted var(--dsw-alias-link);\n text-underline-offset: 3px;\n }\n}\n\n.dshdoc_md_markdown a:focus-visible,\n.dshdoc_md_fileMention:focus-visible {\n box-shadow: 0 0 0 2px var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));\n}\n\n/* Leading link-category glyph inside anchors, file mentions, and\n URL-promoted inline code: outline glyphs ride the link's currentColor.\n 1.1em keeps the glyph proportional to the surrounding text's size (it\n shrinks with the code chip's 0.875em); the small negative offset seats\n its optical center on the cap height. */\n.dshdoc_md_linkIcon {\n flex: none;\n width: 1.1em;\n height: 1.1em;\n vertical-align: -0.25em;\n margin-right: 5px;\n}\n\n.dshdoc_md_markdown :where(ul, ol) {\n margin: 16px 0;\n padding-left: 18px;\n}\n\n.dshdoc_md_markdown li:not(:first-child) {\n margin-top: 6px;\n}\n\n.dshdoc_md_markdown li > :where(ul, ol) {\n margin-top: 4px;\n}\n\n.dshdoc_md_markdown li::marker {\n line-height: 24px;\n color: var(--dsw-alias-label-secondary);\n}\n\n/* Nested ol under ul/ol: markers inside (models sometimes emit this shape). */\n.dshdoc_md_markdown :where(ul, ol) ol {\n list-style-position: inside;\n padding-left: 0;\n}\n\n.dshdoc_md_markdown :where(ul, ol) ol li p {\n display: inline;\n}\n\n.dshdoc_md_markdown li > p {\n margin: 8px 0;\n}\n\n.dshdoc_md_markdown li > *:first-child {\n margin-top: 0;\n}\n\n/* Keep list-nested code-block vertical margins (design: +4px vs other last children). */\n.dshdoc_md_markdown li > *:last-child:not(.md-code-block) {\n margin-bottom: 0;\n}\n\n.dshdoc_md_markdown hr {\n display: block;\n border: none;\n height: 0.5px;\n margin: 32px 0;\n background: var(--dsw-alias-border-l2);\n}\n\n.dshdoc_md_markdown blockquote {\n border-left: 2px solid var(--dsw-alias-label-caption);\n margin: 16px 0 0;\n padding-left: 14px;\n}\n\n.dshdoc_md_markdown pre {\n margin: 16px 0;\n font-family: var(--ds-font-family-code);\n overflow: auto;\n}\n\n.dshdoc_md_markdown :not(pre) > code {\n display: inline-flex;\n align-items: center;\n box-sizing: border-box;\n font: var(--dsw-font-markdown-code);\n font-family: var(--ds-font-family-code);\n font-size: 0.875em !important;\n background-color: var(--dsw-alias-markdown-inline-code);\n border: 0.5px solid var(--dsw-alias-border-l1);\n border-radius: var(--dsw-radius-sm);\n padding: 0 5px;\n}\n\n.dshdoc_md_markdown :where(h1, h2, h3, h4, h5, h6) code {\n font: inherit;\n font-family: var(--ds-font-family-code);\n}\n\n.dshdoc_md_markdown .katex-display {\n max-width: 100%;\n overflow-x: auto;\n overflow-y: hidden;\n}\n\n.dshdoc_md_markdown input[type='checkbox'] {\n margin: 0 8px 0 0;\n accent-color: var(--dsw-alias-label-secondary);\n}\n\n.dshdoc_md_tableScroll {\n max-width: 100%;\n overflow-x: auto;\n overscroll-behavior-x: contain;\n}\n\n/* Hover-capable inputs reveal a wide table's bar on hover or keyboard focus.\n Other inputs keep native horizontal scrolling. Chromium never repaints state-conditioned\n scrollbar STYLES (neither hover-conditioned `::-webkit-scrollbar*` rules\n nor a :hover `scrollbar-color` change reaches the painted bar), so the\n toggle is `overflow-x` itself \u2014 a layout change repaints reliably. The\n resting padding matches the themed bar's height on the WebKit scrollbar\n path. There, `scroll` reserves that height even when the table fits.\n Other engines and overlay scrollbars may reserve a different height.\n Wheel and trackpad scrolling need the pointer over the table, which is\n already the hover that re-enables scrolling. */\n.dshdoc_md_tableScroll.md-table-wide:focus-visible {\n overflow-x: scroll;\n padding-bottom: 0;\n}\n\n@media (hover: hover) {\n .dshdoc_md_tableScroll.md-table-wide {\n overflow-x: hidden;\n padding-bottom: var(--dsh-scrollbar-width, 5px);\n }\n\n .dshdoc_md_tableScroll.md-table-wide:hover {\n overflow-x: scroll;\n padding-bottom: 0;\n }\n}\n\n/* Chromium keyboard-focuses scrollable containers by default; the ring uses\n the sheet's link focus color. */\n.dshdoc_md_tableScroll:focus-visible {\n outline: none;\n box-shadow: 0 0 0 2px var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));\n}\n\n/* Many-column tables (the renderer's `md-table-wide` hook) keep their\n natural width and scroll inside the wrapper; a hosting layout may widen\n the wrapper through the hook (deepsuite chat TableWrapper parity). */\n.dshdoc_md_tableScroll table {\n border-collapse: collapse;\n width: max-content;\n max-width: max-content;\n}\n\n/* Tables under four columns, and any table inside a blockquote, fill the\n column instead: cells wrap down to their minimum readable width, and the\n wrapper's scroll only remains for the below-floor case (deepsuite chat\n parity: `.dshdoc_md_wrapper:not(:has(th:nth-child(4), td:nth-child(4)))`). */\n.dshdoc_md_tableFill table {\n width: 100%;\n max-width: none;\n}\n\n.dshdoc_md_tableScroll th {\n text-align: start;\n padding: 10px 16px;\n border-bottom: 0.5px solid var(--dsw-alias-border-l3);\n border-top: none;\n font: var(--dsw-font-markdown-table-head);\n max-width: 320px;\n max-width: min(30vw, 320px);\n min-width: 100px;\n}\n\n.dshdoc_md_tableScroll td {\n padding: 10px 16px;\n border-bottom: 0.5px solid var(--dsw-alias-border-l2);\n font: var(--dsw-font-markdown-table);\n max-width: 320px;\n max-width: min(30vw, 320px);\n min-width: 100px;\n}\n\n.dshdoc_md_tableScroll th:first-child,\n.dshdoc_md_tableScroll td:first-child {\n padding-left: 0;\n}\n\n.dshdoc_md_tableScroll td:last-child {\n padding-right: 0;\n}\n\n.dshdoc_md_tableScroll table code {\n font-size: 11px;\n}\n\n.dshdoc_md_markdown > *:first-child,\n.dshdoc_md_markdown p:first-child {\n margin-top: 0 !important;\n}\n\n.dshdoc_md_markdown > *:last-child,\n.dshdoc_md_markdown p:last-child {\n margin-bottom: 0 !important;\n}\n\n.dshdoc_md_imageAlt {\n color: var(--dsw-alias-label-tertiary);\n font-style: italic;\n}\n\n.dshdoc_md_image {\n display: block;\n width: auto;\n max-width: 100%;\n height: auto;\n margin: 0;\n border-radius: var(--dsw-radius-md);\n background: var(--dsw-alias-bg-base);\n object-fit: contain;\n}\n\n/* Inline file mention: the same link language this sheet gives anchors (and\n thereby URL-promoted inline code) \u2014 link-blue at rest, dotted underline only\n on hover/focus. An underline at rest reads badly inside the code chip, where\n it collides with monospace descenders and the pill background. */\n.dshdoc_md_fileMention {\n margin: 0;\n padding: 0;\n border: none;\n background: none;\n font: inherit;\n font-weight: 500;\n color: var(--dsw-alias-link);\n text-decoration: none;\n cursor: pointer;\n}\n\n.dshdoc_md_fileLink {\n max-width: 100%;\n text-align: inherit;\n}\n\n.dshdoc_md_fileMention:focus {\n outline: none;\n text-decoration: underline dotted var(--dsw-alias-link);\n text-underline-offset: 3px;\n}\n\n@media (hover: hover) {\n .dshdoc_md_fileMention:hover {\n outline: none;\n text-decoration: underline dotted var(--dsw-alias-link);\n text-underline-offset: 3px;\n }\n}\n\n.dshdoc_md_compact {\n max-width: 100%;\n font-size: var(--dsh-content-font-size-secondary, 13px);\n line-height: calc(20px + var(--dsh-content-font-delta-secondary, 0px));\n color: var(--dsw-alias-label-tertiary);\n}\n\n.dshdoc_md_compact :is(h1, h2, h3, h4, h5, h6) {\n margin: 8px 0 4px;\n font: inherit;\n font-weight: 600;\n color: inherit;\n}\n\n.dshdoc_md_compact :is(p, ul, ol, blockquote) {\n margin: 4px 0;\n}\n\n.dshdoc_md_compact li:not(:first-child) {\n margin-top: 2px;\n}\n\n.dshdoc_md_compact li > p {\n margin: 4px 0;\n}\n\n.dshdoc_md_compact li::marker {\n line-height: inherit;\n color: inherit;\n}\n\n.dshdoc_md_compact blockquote {\n padding-left: 8px;\n}\n\n.dshdoc_md_compact hr {\n margin: 8px 0;\n}\n\n.dshdoc_md_compact a,\n.dshdoc_md_compact .dshdoc_md_fileMention {\n font-weight: inherit;\n color: inherit;\n text-decoration: underline dotted;\n}\n\n.dshdoc_md_compact a:focus,\n.dshdoc_md_compact .dshdoc_md_fileMention:focus {\n text-decoration-color: currentColor;\n}\n\n@media (hover: hover) {\n .dshdoc_md_compact a:hover,\n .dshdoc_md_compact .dshdoc_md_fileMention:hover {\n text-decoration-color: currentColor;\n }\n}\n\n.dshdoc_md_compact :not(pre) > code {\n display: inline;\n font: inherit;\n font-family: var(--ds-font-family-code);\n font-size: 1em !important;\n border-radius: var(--dsw-radius-xs);\n padding: 0 3px;\n box-decoration-break: clone;\n}\n\n.dshdoc_md_markdown.dshdoc_md_compact .md-code-block {\n margin: 4px 0;\n color: inherit;\n}\n\n.dshdoc_md_compact .md-code-block > :has(> [data-code-block-banner]) {\n position: static;\n z-index: auto;\n}\n\n/* Shiki writes token colors inline; compact code uses the surrounding text color. */\n.dshdoc_md_compact pre,\n.dshdoc_md_compact pre :is(code, span) {\n color: inherit !important;\n}\n\n.dshdoc_md_markdown.dshdoc_md_compact .dshdoc_md_tableScroll {\n width: 100%;\n max-width: 100%;\n margin: 4px 0;\n padding-left: 0;\n}\n\n.dshdoc_md_markdown.dshdoc_md_compact .dshdoc_md_tableScroll > table {\n z-index: auto;\n}\n\n.dshdoc_md_compact :is(th, td) {\n padding: 4px 8px;\n font: inherit;\n}\n\n.dshdoc_md_compact th {\n font-weight: 600;\n}\n\n.dshdoc_md_compact .katex {\n font-size: 1em;\n}\n\n/* Keep KaTeX's inline baseline and scroll the containing block only when needed. */\n.dshdoc_md_compact :is(p, h1, h2, h3, h4, h5, h6, ul, ol):has(.katex) {\n overflow-x: auto;\n overflow-y: hidden;\n /* KaTeX descenders can paint one pixel below a fractional line-box edge. */\n padding-bottom: 1px;\n}\n\n.dshdoc_md_compact .katex-display {\n margin: 4px 0;\n}\n\n.dshdoc_md_imageButton {\n display: inline-block;\n max-width: 100%;\n padding: 0;\n border: 0;\n border-radius: var(--dsw-radius-sm);\n background: transparent;\n vertical-align: middle;\n cursor: zoom-in;\n}\n.dshdoc_md_imageButton .dshdoc_md_image { max-width: min(100%, 640px); max-height: 360px; }\n.dshdoc_md_imageButton:focus-visible { outline: var(--dsw-focus-ring-width) solid var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary)); outline-offset: 3px; }\n.dshdoc_md_previewName {\n display: block;\n margin-top: 8px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: var(--dsw-alias-label-secondary);\n font-size: 12px;\n line-height: 18px;\n}\n\n/* CodeCard/CodeBlock and Tooltip adapted from Harness 0.2.2-rc.1 (MIT).\n Keep only the document toolbar and portal tooltip used by this plugin. */\n.dshdoc_code_block {\n --dsl-code-block-background: var(--dsw-alias-markdown-code-block);\n position: relative;\n margin: 16px 0;\n color: var(--dsw-alias-label-primary);\n background: var(--dsl-code-block-background);\n border-radius: var(--dsw-radius-lg);\n font: var(--dsw-font-markdown-code-block);\n}\n.dshdoc_code_block:not(:last-child) { margin-bottom: 11px; }\n.dshdoc_code_bannerWrap {\n position: sticky;\n top: 0;\n z-index: 6;\n background-color: var(--dsw-alias-bg-base);\n border-top-left-radius: inherit;\n border-top-right-radius: inherit;\n}\n.dshdoc_code_header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding: 10px 18px 8px 22px;\n background: var(--dsl-code-block-background, var(--dsw-alias-markdown-code-block));\n border-top-left-radius: inherit;\n border-top-right-radius: inherit;\n color: var(--dsw-alias-label-secondary);\n font: 11px/18px var(--dsw-font-family);\n}\n.dshdoc_code_heading { display: flex; align-items: baseline; gap: 12px; min-width: 0; }\n.dshdoc_code_language { color: var(--dsw-alias-label-tertiary); flex: none; font-family: var(--ds-font-family-code); }\n.dshdoc_code_actions { display: flex; align-items: center; gap: 4px; flex: none; }\n.dshdoc_code_action {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n padding: 0;\n border: 0;\n border-radius: var(--dsw-radius-sm);\n color: var(--dsw-alias-label-secondary);\n background: transparent;\n cursor: pointer;\n}\n@media (hover: hover) {\n .dshdoc_code_action:hover { background: var(--dsw-alias-interactive-bg-hover); }\n}\n.dshdoc_code_action:focus-visible {\n outline: 1px solid var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));\n outline-offset: 2px;\n}\n.dshdoc_code_content { display: contents; }\n.dshdoc_code_block :where(pre) {\n font: var(--dsw-font-markdown-code-block);\n padding: 6px 22px 20px;\n margin: 0 !important;\n overflow-x: auto;\n white-space: pre-wrap;\n word-break: normal;\n overflow-wrap: anywhere;\n background: var(--dsl-code-block-background);\n border-bottom-left-radius: var(--dsw-radius-lg);\n border-bottom-right-radius: var(--dsw-radius-lg);\n}\n.dshdoc_code_block :where(pre) code { font: inherit; background: none; padding: 0; }\n.dshdoc_code_card[data-code-wrap='false'] :where(pre) { white-space: pre; overflow-wrap: normal; }\n.dshui_tooltip_bubble {\n display: inline-flex;\n align-items: safe center;\n gap: 8px;\n position: fixed;\n z-index: 1100;\n width: max-content;\n box-sizing: border-box;\n max-width: min(50vw, calc(100vw - 24px));\n max-height: calc(100vh - 24px);\n overflow: auto;\n padding: 3px 7px;\n border-radius: var(--dsw-radius-sm);\n background: var(--dsw-alias-tooltip-bg);\n color: var(--dsw-static-neutral-bluish-00);\n font-size: 13px;\n line-height: 20px;\n white-space: pre-line;\n overflow-wrap: break-word;\n pointer-events: none;\n animation: dshui-tooltip-in 150ms var(--ds-ease-in-out);\n}\n.dshui_tooltip_label { min-width: 0; }\n@keyframes dshui-tooltip-in { from { opacity: 0; } }\n@media (prefers-reduced-motion: reduce) { .dshui_tooltip_bubble { animation: none; } }\n";
40327
40330
 
@@ -40371,9 +40374,6 @@ var DICTS = {
40371
40374
  saving: "Saving\u2026",
40372
40375
  invalid: "The request is invalid.",
40373
40376
  conflict: "The skill catalog changed. Wait for the list to refresh and try again.",
40374
- sharedConflict: "A shared skill has conflicting settings or a matching name in another location.",
40375
- sharedUnavailable: "Shared skill sync is unavailable. Check the background service and its log.",
40376
- sharedStopped: "The shared skill background service has stopped or is not responding.",
40377
40377
  "not-found": "This skill could not be found.",
40378
40378
  unavailable: "Could not read from or connect to Harness.",
40379
40379
  forbidden: "This page does not have permission to perform the action.",
@@ -40417,9 +40417,6 @@ var DICTS = {
40417
40417
  saving: "\u6B63\u5728\u4FDD\u5B58\u2026",
40418
40418
  invalid: "\u8BF7\u6C42\u65E0\u6548\u3002",
40419
40419
  conflict: "\u6280\u80FD\u5217\u8868\u5DF2\u53D8\u5316\u3002\u8BF7\u7B49\u5F85\u5217\u8868\u5237\u65B0\u540E\u91CD\u8BD5\u3002",
40420
- sharedConflict: "\u5171\u4EAB\u6280\u80FD\u5B58\u5728\u8BBE\u7F6E\u51B2\u7A81\u6216\u540C\u540D\u6761\u76EE\u3002",
40421
- sharedUnavailable: "\u5171\u4EAB\u6280\u80FD\u540C\u6B65\u4E0D\u53EF\u7528\uFF0C\u8BF7\u68C0\u67E5\u540E\u53F0\u670D\u52A1\u53CA\u5176\u65E5\u5FD7\u3002",
40422
- sharedStopped: "\u5171\u4EAB\u6280\u80FD\u540E\u53F0\u670D\u52A1\u5DF2\u505C\u6B62\u6216\u672A\u54CD\u5E94\u3002",
40423
40420
  "not-found": "\u627E\u4E0D\u5230\u6B64\u6280\u80FD\u3002",
40424
40421
  unavailable: "\u65E0\u6CD5\u8FDE\u63A5 Harness \u6216\u8BFB\u53D6\u6570\u636E\u3002",
40425
40422
  forbidden: "\u5F53\u524D\u9875\u9762\u6CA1\u6709\u6267\u884C\u6B64\u64CD\u4F5C\u7684\u6743\u9650\u3002",
@@ -40442,7 +40439,7 @@ function createTranslator(locale) {
40442
40439
  }
40443
40440
 
40444
40441
  // src/client/page.js
40445
- var import_react6 = require("react");
40442
+ var import_react7 = require("react");
40446
40443
 
40447
40444
  // src/client/api.js
40448
40445
  var SkillError = class extends Error {
@@ -40523,7 +40520,7 @@ function createCatalog(send = request) {
40523
40520
  }
40524
40521
  if (result.complete) {
40525
40522
  hasCompleteCatalog = true;
40526
- publish({ skills: result.skills, listError: result.syncError ?? null });
40523
+ publish({ skills: result.skills, listError: null });
40527
40524
  } else if (!hasCompleteCatalog) {
40528
40525
  publish({ skills: result.skills, listError: "incomplete" });
40529
40526
  } else {
@@ -40596,8 +40593,11 @@ function createCatalog(send = request) {
40596
40593
  }
40597
40594
 
40598
40595
  // src/client/dialog.js
40596
+ var import_react6 = require("react");
40597
+
40598
+ // ../../src/client/host-modal.js
40599
40599
  var import_react5 = require("react");
40600
- function Modal({ title, closeLabel, description, footer: footer2, busy, close: close2, children }) {
40600
+ function Modal({ title, closeLabel, description, footer: footer2, busy, close: close2, fallbackFocus, children }) {
40601
40601
  const ref = (0, import_react5.useRef)(null);
40602
40602
  const titleId = (0, import_react5.useId)();
40603
40603
  const descriptionId = (0, import_react5.useId)();
@@ -40608,13 +40608,14 @@ function Modal({ title, closeLabel, description, footer: footer2, busy, close: c
40608
40608
  dialog.querySelector("[data-initial-focus]")?.focus();
40609
40609
  return () => {
40610
40610
  dialog.close();
40611
- if (previous4?.isConnected && !previous4.closest("[inert], [hidden]")) previous4.focus({ preventScroll: true });
40611
+ const focusTarget = previous4?.isConnected && !previous4.closest("[inert], [hidden]") ? previous4 : fallbackFocus?.current;
40612
+ focusTarget?.focus({ preventScroll: true });
40612
40613
  };
40613
- }, []);
40614
+ }, [fallbackFocus]);
40614
40615
  return (0, import_react5.createElement)(
40615
40616
  "dialog",
40616
40617
  {
40617
- className: "dshskill_dialog",
40618
+ className: "dshui_modal",
40618
40619
  ref,
40619
40620
  "aria-labelledby": titleId,
40620
40621
  "aria-describedby": descriptionId,
@@ -40625,31 +40626,33 @@ function Modal({ title, closeLabel, description, footer: footer2, busy, close: c
40625
40626
  },
40626
40627
  (0, import_react5.createElement)(
40627
40628
  "div",
40628
- { className: "dshskill_dialogContent" },
40629
+ { className: "dshui_modalContent" },
40629
40630
  (0, import_react5.createElement)(
40630
40631
  "div",
40631
- { className: "dshskill_dialogHeader" },
40632
+ { className: "dshui_modalHeader" },
40632
40633
  (0, import_react5.createElement)("h2", { id: titleId }, title),
40633
40634
  (0, import_react5.createElement)(
40634
40635
  "button",
40635
- { type: "button", className: "dshskill_dialogClose", "aria-label": closeLabel, disabled: busy, onClick: () => {
40636
+ { type: "button", className: "dshui_modalClose", "aria-label": closeLabel, disabled: busy, onClick: () => {
40636
40637
  if (!busy) close2();
40637
40638
  } },
40638
40639
  (0, import_react5.createElement)(IconCloseOutlineRegular, { size: 14 })
40639
40640
  )
40640
40641
  ),
40641
- (0, import_react5.createElement)("p", { id: descriptionId, className: "dshskill_dialogDescription" }, description),
40642
+ (0, import_react5.createElement)("p", { id: descriptionId, className: "dshui_modalDescription" }, description),
40642
40643
  children
40643
40644
  ),
40644
- (0, import_react5.createElement)("div", { className: "dshskill_dialogActions" }, footer2)
40645
+ (0, import_react5.createElement)("div", { className: "dshui_modalActions" }, footer2)
40645
40646
  );
40646
40647
  }
40648
+
40649
+ // src/client/dialog.js
40647
40650
  function Feedback({ error, busy, translate }) {
40648
- return (0, import_react5.createElement)(
40651
+ return (0, import_react6.createElement)(
40649
40652
  "div",
40650
40653
  { className: "dshskill_feedback" },
40651
- busy && (0, import_react5.createElement)("p", { role: "status" }, translate("saving")),
40652
- error && (0, import_react5.createElement)("p", { className: "dshskill_error", role: "alert" }, translate(error))
40654
+ busy && (0, import_react6.createElement)("p", { role: "status" }, translate("saving")),
40655
+ error && (0, import_react6.createElement)("p", { className: "dshskill_error", role: "alert" }, translate(error))
40653
40656
  );
40654
40657
  }
40655
40658
  function RemoveDialog({ skill, translate: t, store, busy, error, close: close2, removed }) {
@@ -40658,14 +40661,14 @@ function RemoveDialog({ skill, translate: t, store, busy, error, close: close2,
40658
40661
  const ok3 = await store.mutate({ action: "remove", id: skill.id });
40659
40662
  if (ok3) removed();
40660
40663
  }
40661
- return (0, import_react5.createElement)(Modal, {
40664
+ return (0, import_react6.createElement)(Modal, {
40662
40665
  title: t("uninstallTitle"),
40663
40666
  closeLabel: t("close"),
40664
40667
  busy,
40665
40668
  close: close2,
40666
40669
  description: t("uninstallHint", { name: skill.name }),
40667
40670
  footer: [
40668
- (0, import_react5.createElement)(Button, {
40671
+ (0, import_react6.createElement)(Button, {
40669
40672
  key: "cancel",
40670
40673
  variant: "outline",
40671
40674
  "data-initial-focus": "",
@@ -40674,25 +40677,25 @@ function RemoveDialog({ skill, translate: t, store, busy, error, close: close2,
40674
40677
  if (!busy) close2();
40675
40678
  }
40676
40679
  }, t("cancel")),
40677
- (0, import_react5.createElement)(Button, { key: "confirm", variant: "primary", className: "dshskill_dangerButton", disabled: busy, onClick: remove }, t("uninstall"))
40680
+ (0, import_react6.createElement)(Button, { key: "confirm", variant: "primary", className: "dshui_modalDangerButton", disabled: busy, onClick: remove }, t("uninstall"))
40678
40681
  ]
40679
- }, (busy || error) && (0, import_react5.createElement)("div", { className: "dshskill_dialogBody" }, (0, import_react5.createElement)(Feedback, { error, busy, translate: t })));
40682
+ }, (busy || error) && (0, import_react6.createElement)("div", { className: "dshui_modalBody" }, (0, import_react6.createElement)(Feedback, { error, busy, translate: t })));
40680
40683
  }
40681
40684
 
40682
40685
  // src/client/page.js
40683
40686
  var GROUPS = ["builtin", "self", "third-party"];
40684
40687
  function SkillToggle({ skill, busy, saving, store, translate: t, controls }) {
40685
40688
  const { StateDot: StateDot2, Switch: Switch2 } = controls;
40686
- return (0, import_react6.createElement)(
40689
+ return (0, import_react7.createElement)(
40687
40690
  "span",
40688
40691
  { className: "dshskill_toggle" },
40689
- (0, import_react6.createElement)(
40692
+ (0, import_react7.createElement)(
40690
40693
  "span",
40691
40694
  { className: "dshskill_toggleProgress", role: "status" },
40692
- (0, import_react6.createElement)("span", { className: "dshskill_progressAnnouncement" }, saving ? t("saving") : ""),
40693
- saving && (0, import_react6.createElement)(StateDot2, { state: "ongoing" })
40695
+ (0, import_react7.createElement)("span", { className: "dshskill_progressAnnouncement" }, saving ? t("saving") : ""),
40696
+ saving && (0, import_react7.createElement)(StateDot2, { state: "ongoing" })
40694
40697
  ),
40695
- (0, import_react6.createElement)(Switch2, {
40698
+ (0, import_react7.createElement)(Switch2, {
40696
40699
  checked: skill.enabled,
40697
40700
  label: t("switchLabel", { name: skill.name }),
40698
40701
  disabled: busy,
@@ -40704,32 +40707,32 @@ function SkillToggle({ skill, busy, saving, store, translate: t, controls }) {
40704
40707
  }
40705
40708
  function CatalogRows({ skills, query, translate: t, busy, savingId, store, openDetail, controls }) {
40706
40709
  const { SkillEmblem: SkillEmblem2, Tag: Tag2 } = controls;
40707
- const headingId = (0, import_react6.useId)();
40710
+ const headingId = (0, import_react7.useId)();
40708
40711
  const term = query.trim().toLocaleLowerCase();
40709
40712
  const visible = skills.filter((skill) => !term || [skill.name, skill.description].some((text10) => text10?.toLocaleLowerCase().includes(term)));
40710
- if (!visible.length) return (0, import_react6.createElement)("p", { className: "dshskill_muted", role: "status" }, t(term ? "noMatch" : "empty"));
40711
- return (0, import_react6.createElement)("div", { className: "dshskill_groups" }, GROUPS.map((group) => {
40713
+ if (!visible.length) return (0, import_react7.createElement)("p", { className: "dshskill_muted", role: "status" }, t(term ? "noMatch" : "empty"));
40714
+ return (0, import_react7.createElement)("div", { className: "dshskill_groups" }, GROUPS.map((group) => {
40712
40715
  const entries = visible.filter((skill) => (skill.origin ?? "third-party") === group);
40713
40716
  if (!entries.length) return null;
40714
40717
  const id = headingId + group;
40715
- return (0, import_react6.createElement)(
40718
+ return (0, import_react7.createElement)(
40716
40719
  "section",
40717
40720
  { key: group, className: "dshskill_group", "aria-labelledby": id },
40718
- (0, import_react6.createElement)("h2", { id }, t(group)),
40719
- (0, import_react6.createElement)("ul", { className: "dshskill_rows" }, entries.map((skill) => {
40721
+ (0, import_react7.createElement)("h2", { id }, t(group)),
40722
+ (0, import_react7.createElement)("ul", { className: "dshskill_rows" }, entries.map((skill) => {
40720
40723
  const descriptionId = skill.description ? headingId + "-" + skill.id : void 0;
40721
40724
  const saving = savingId === skill.id;
40722
- return (0, import_react6.createElement)(
40725
+ return (0, import_react7.createElement)(
40723
40726
  "li",
40724
40727
  { key: skill.id, className: "dshskill_row" },
40725
- (0, import_react6.createElement)("span", { className: "dshskill_icon" }, (0, import_react6.createElement)(SkillEmblem2, { size: 24 })),
40726
- (0, import_react6.createElement)(
40728
+ (0, import_react7.createElement)("span", { className: "dshskill_icon" }, (0, import_react7.createElement)(SkillEmblem2, { size: 24 })),
40729
+ (0, import_react7.createElement)(
40727
40730
  "div",
40728
40731
  { className: "dshskill_rowText" },
40729
- (0, import_react6.createElement)(
40732
+ (0, import_react7.createElement)(
40730
40733
  "div",
40731
40734
  { className: "dshskill_titleRow" },
40732
- (0, import_react6.createElement)("button", {
40735
+ (0, import_react7.createElement)("button", {
40733
40736
  type: "button",
40734
40737
  className: "dshskill_rowButton",
40735
40738
  "data-skill-id": skill.id,
@@ -40737,11 +40740,11 @@ function CatalogRows({ skills, query, translate: t, busy, savingId, store, openD
40737
40740
  "aria-describedby": descriptionId,
40738
40741
  onClick: () => openDetail(skill)
40739
40742
  }, skill.name),
40740
- skill.shadowed && (0, import_react6.createElement)(Tag2, { className: "dshskill_badge" }, t("shadowed"))
40743
+ skill.shadowed && (0, import_react7.createElement)(Tag2, { className: "dshskill_badge" }, t("shadowed"))
40741
40744
  ),
40742
- descriptionId && (0, import_react6.createElement)("span", { className: "dshskill_description", id: descriptionId }, skill.description)
40745
+ descriptionId && (0, import_react7.createElement)("span", { className: "dshskill_description", id: descriptionId }, skill.description)
40743
40746
  ),
40744
- typeof skill.enabled === "boolean" && (0, import_react6.createElement)(SkillToggle, { skill, busy, saving, store, translate: t, controls })
40747
+ skill.group === "imported" && typeof skill.enabled === "boolean" && (0, import_react7.createElement)(SkillToggle, { skill, busy, saving, store, translate: t, controls })
40745
40748
  );
40746
40749
  }))
40747
40750
  );
@@ -40749,9 +40752,9 @@ function CatalogRows({ skills, query, translate: t, busy, savingId, store, openD
40749
40752
  }
40750
40753
  function SkillDetail({ skill, titleRef, translate: t, busy, saving, back, openRemove, controls, store }) {
40751
40754
  const { BackIcon, Button: Button3, SkillDocument: SkillDocument2, SkillEmblem: SkillEmblem2, Tag: Tag2, TrashIcon } = controls;
40752
- const [preview, setPreview] = (0, import_react6.useState)(null);
40753
- const [attempt, setAttempt] = (0, import_react6.useState)(0);
40754
- (0, import_react6.useEffect)(() => {
40755
+ const [preview, setPreview] = (0, import_react7.useState)(null);
40756
+ const [attempt, setAttempt] = (0, import_react7.useState)(0);
40757
+ (0, import_react7.useEffect)(() => {
40755
40758
  const pending = new AbortController();
40756
40759
  request(
40757
40760
  { action: "detail", workspaceId: null, id: skill.id },
@@ -40764,52 +40767,52 @@ function SkillDetail({ skill, titleRef, translate: t, busy, saving, back, openRe
40764
40767
  return () => pending.abort();
40765
40768
  }, [skill.id, attempt]);
40766
40769
  const imported = skill.group === "imported";
40767
- const canToggle = typeof skill.enabled === "boolean";
40770
+ const canToggle = skill.group === "imported" && typeof skill.enabled === "boolean";
40768
40771
  const origin = preview?.origin ?? skill.origin;
40769
40772
  const repository = origin === "third-party" ? preview?.repository : void 0;
40770
40773
  const repositoryLabel = repository?.replace(/^https:\/\/(?:github\.com\/)?/, "").replace(/\/$/, "");
40771
40774
  const originLabel = t(origin ? "origin-" + origin : imported ? "imported" : "unknownOrigin");
40772
- return (0, import_react6.createElement)(
40775
+ return (0, import_react7.createElement)(
40773
40776
  "div",
40774
40777
  { className: "dshskill_detail" },
40775
- (0, import_react6.createElement)(
40778
+ (0, import_react7.createElement)(
40776
40779
  "header",
40777
40780
  { className: "dshskill_detailTop" },
40778
- (0, import_react6.createElement)(
40781
+ (0, import_react7.createElement)(
40779
40782
  "button",
40780
40783
  { type: "button", className: "dshskill_back", "aria-label": t("back"), onClick: back },
40781
- (0, import_react6.createElement)(BackIcon, { className: "dshskill_backIcon", "aria-hidden": true }),
40782
- (0, import_react6.createElement)("span", null, t("title"))
40784
+ (0, import_react7.createElement)(BackIcon, { className: "dshskill_backIcon", "aria-hidden": true }),
40785
+ (0, import_react7.createElement)("span", null, t("title"))
40783
40786
  ),
40784
- (0, import_react6.createElement)(
40787
+ (0, import_react7.createElement)(
40785
40788
  "div",
40786
40789
  { className: "dshskill_detailHead" },
40787
- (0, import_react6.createElement)("span", { className: "dshskill_icon", "aria-hidden": true }, (0, import_react6.createElement)(SkillEmblem2, { branded: true, size: 36 })),
40788
- (imported || canToggle) && (0, import_react6.createElement)(
40790
+ (0, import_react7.createElement)("span", { className: "dshskill_icon", "aria-hidden": true }, (0, import_react7.createElement)(SkillEmblem2, { branded: true, size: 36 })),
40791
+ (imported || canToggle) && (0, import_react7.createElement)(
40789
40792
  "div",
40790
40793
  { className: "dshskill_detailActions" },
40791
- imported && (0, import_react6.createElement)(Button3, {
40794
+ imported && (0, import_react7.createElement)(Button3, {
40792
40795
  type: "button",
40793
40796
  variant: "outline",
40794
40797
  size: "sm",
40795
40798
  className: "dshskill_detailUninstall",
40796
- icon: (0, import_react6.createElement)(TrashIcon, { size: 13 }),
40799
+ icon: (0, import_react7.createElement)(TrashIcon, { size: 13 }),
40797
40800
  disabled: busy,
40798
40801
  "aria-label": t("uninstallLabel", { name: skill.name }),
40799
40802
  onClick: openRemove
40800
40803
  }, t("uninstall")),
40801
- canToggle && (0, import_react6.createElement)(SkillToggle, { skill, busy, saving, store, translate: t, controls })
40804
+ canToggle && (0, import_react7.createElement)(SkillToggle, { skill, busy, saving, store, translate: t, controls })
40802
40805
  )
40803
40806
  )
40804
40807
  ),
40805
- (0, import_react6.createElement)(
40808
+ (0, import_react7.createElement)(
40806
40809
  "div",
40807
40810
  { className: "dshskill_detailMain" },
40808
- (0, import_react6.createElement)(
40811
+ (0, import_react7.createElement)(
40809
40812
  "div",
40810
40813
  { className: "dshskill_detailTitleRow" },
40811
- (0, import_react6.createElement)("h1", { ref: titleRef, tabIndex: -1, title: skill.name }, skill.name),
40812
- repository ? (0, import_react6.createElement)(
40814
+ (0, import_react7.createElement)("h1", { ref: titleRef, tabIndex: -1, title: skill.name }, skill.name),
40815
+ repository ? (0, import_react7.createElement)(
40813
40816
  "a",
40814
40817
  {
40815
40818
  className: "dshskill_detailAttribution dshskill_repository",
@@ -40819,20 +40822,20 @@ function SkillDetail({ skill, titleRef, translate: t, busy, saving, back, openRe
40819
40822
  title: repositoryLabel,
40820
40823
  "aria-label": t("openRepository", { repository: repositoryLabel })
40821
40824
  },
40822
- (0, import_react6.createElement)("span", { className: "dshskill_attributionText" }, repositoryLabel),
40823
- (0, import_react6.createElement)("span", { "aria-hidden": true }, "\u2197")
40824
- ) : (0, import_react6.createElement)(
40825
+ (0, import_react7.createElement)("span", { className: "dshskill_attributionText" }, repositoryLabel),
40826
+ (0, import_react7.createElement)("span", { "aria-hidden": true }, "\u2197")
40827
+ ) : (0, import_react7.createElement)(
40825
40828
  Tag2,
40826
40829
  { className: "dshskill_detailAttribution", tone: "neutral" },
40827
- (0, import_react6.createElement)("span", { className: "dshskill_attributionText", title: originLabel }, originLabel)
40830
+ (0, import_react7.createElement)("span", { className: "dshskill_attributionText", title: originLabel }, originLabel)
40828
40831
  )
40829
40832
  ),
40830
- skill.description && (0, import_react6.createElement)("p", { className: "dshskill_detailDescription" }, skill.description)
40833
+ skill.description && (0, import_react7.createElement)("p", { className: "dshskill_detailDescription" }, skill.description)
40831
40834
  ),
40832
- (0, import_react6.createElement)(
40835
+ (0, import_react7.createElement)(
40833
40836
  "div",
40834
40837
  { className: "dshskill_detailSections" },
40835
- (0, import_react6.createElement)(SkillDocument2, { preview, translate: t, onRetry: () => {
40838
+ (0, import_react7.createElement)(SkillDocument2, { preview, translate: t, onRetry: () => {
40836
40839
  setPreview(null);
40837
40840
  setAttempt((value) => value + 1);
40838
40841
  } })
@@ -40844,20 +40847,20 @@ function createPage(locale, controls, createStore = createCatalog) {
40844
40847
  const subscribeLocale = (listener) => locale.subscribe(listener);
40845
40848
  const localeVersion = () => locale.getSnapshot().revision;
40846
40849
  return function SkillsPage() {
40847
- (0, import_react6.useSyncExternalStore)(subscribeLocale, localeVersion, localeVersion);
40848
- const [store] = (0, import_react6.useState)(createStore);
40849
- const state = (0, import_react6.useSyncExternalStore)(store.subscribe, store.getSnapshot, store.getSnapshot);
40850
- const [query, setQuery] = (0, import_react6.useState)("");
40851
- const [detail, setDetail] = (0, import_react6.useState)(null);
40852
- const [confirmRemoval, setConfirmRemoval] = (0, import_react6.useState)(false);
40853
- const pageRef = (0, import_react6.useRef)(null);
40854
- const titleRef = (0, import_react6.useRef)(null);
40855
- const returnTo = (0, import_react6.useRef)(null);
40856
- (0, import_react6.useEffect)(() => {
40850
+ (0, import_react7.useSyncExternalStore)(subscribeLocale, localeVersion, localeVersion);
40851
+ const [store] = (0, import_react7.useState)(createStore);
40852
+ const state = (0, import_react7.useSyncExternalStore)(store.subscribe, store.getSnapshot, store.getSnapshot);
40853
+ const [query, setQuery] = (0, import_react7.useState)("");
40854
+ const [detail, setDetail] = (0, import_react7.useState)(null);
40855
+ const [confirmRemoval, setConfirmRemoval] = (0, import_react7.useState)(false);
40856
+ const pageRef = (0, import_react7.useRef)(null);
40857
+ const titleRef = (0, import_react7.useRef)(null);
40858
+ const returnTo = (0, import_react7.useRef)(null);
40859
+ (0, import_react7.useEffect)(() => {
40857
40860
  store.start();
40858
40861
  return () => store.stop();
40859
40862
  }, [store]);
40860
- (0, import_react6.useLayoutEffect)(() => {
40863
+ (0, import_react7.useLayoutEffect)(() => {
40861
40864
  if (detail) {
40862
40865
  pageRef.current.scrollTop = 0;
40863
40866
  titleRef.current.focus({ preventScroll: true });
@@ -40888,13 +40891,13 @@ function createPage(locale, controls, createStore = createCatalog) {
40888
40891
  }
40889
40892
  const { skills, busy, savingId, listError, mutationError } = state;
40890
40893
  const currentSkill = detail && (skills?.find((skill) => skill.id === detail.id) ?? detail);
40891
- return (0, import_react6.createElement)(
40894
+ return (0, import_react7.createElement)(
40892
40895
  "div",
40893
40896
  { className: "dshskill_page", "data-detail": currentSkill ? "" : void 0, ref: pageRef },
40894
- (0, import_react6.createElement)(
40897
+ (0, import_react7.createElement)(
40895
40898
  "div",
40896
40899
  { className: "dshskill_content" },
40897
- currentSkill ? (0, import_react6.createElement)(SkillDetail, {
40900
+ currentSkill ? (0, import_react7.createElement)(SkillDetail, {
40898
40901
  skill: currentSkill,
40899
40902
  titleRef,
40900
40903
  translate: t,
@@ -40907,42 +40910,42 @@ function createPage(locale, controls, createStore = createCatalog) {
40907
40910
  store.clearMutationError();
40908
40911
  setConfirmRemoval(true);
40909
40912
  }
40910
- }) : (0, import_react6.createElement)(
40913
+ }) : (0, import_react7.createElement)(
40911
40914
  "div",
40912
40915
  { className: "dshskill_catalog" },
40913
- (0, import_react6.createElement)(
40916
+ (0, import_react7.createElement)(
40914
40917
  "header",
40915
40918
  { className: "dshskill_header" },
40916
- (0, import_react6.createElement)("h1", { ref: titleRef, tabIndex: -1 }, t("title")),
40917
- (0, import_react6.createElement)(controls.Input, {
40919
+ (0, import_react7.createElement)("h1", { ref: titleRef, tabIndex: -1 }, t("title")),
40920
+ (0, import_react7.createElement)(controls.Input, {
40918
40921
  className: "dshskill_search",
40919
40922
  type: "search",
40920
- icon: (0, import_react6.createElement)(controls.SearchIcon, { size: 14 }),
40923
+ icon: (0, import_react7.createElement)(controls.SearchIcon, { size: 14 }),
40921
40924
  "aria-label": t("search"),
40922
40925
  placeholder: t("search"),
40923
40926
  value: query,
40924
40927
  onChange: (event) => setQuery(event.currentTarget.value)
40925
40928
  })
40926
40929
  ),
40927
- listError && (0, import_react6.createElement)("p", { role: "alert", className: "dshskill_error" }, t(listError)),
40928
- skills === null ? !listError && (0, import_react6.createElement)("p", { role: "status", className: "dshskill_muted" }, t("loading")) : (0, import_react6.createElement)(CatalogRows, { skills, query, translate: t, busy, savingId, store, openDetail, controls })
40930
+ listError && (0, import_react7.createElement)("p", { role: "alert", className: "dshskill_error" }, t(listError)),
40931
+ skills === null ? !listError && (0, import_react7.createElement)("p", { role: "status", className: "dshskill_muted" }, t("loading")) : (0, import_react7.createElement)(CatalogRows, { skills, query, translate: t, busy, savingId, store, openDetail, controls })
40929
40932
  ),
40930
- !confirmRemoval && busy && !savingId && (0, import_react6.createElement)("p", { role: "status", className: "dshskill_muted" }, t("saving")),
40931
- !confirmRemoval && mutationError && (0, import_react6.createElement)("p", { role: "alert", className: "dshskill_error" }, t(mutationError)),
40932
- confirmRemoval && (0, import_react6.createElement)(RemoveDialog, { skill: currentSkill, translate: t, store, busy, error: mutationError, close: closeDialog, removed })
40933
+ !confirmRemoval && busy && !savingId && (0, import_react7.createElement)("p", { role: "status", className: "dshskill_muted" }, t("saving")),
40934
+ !confirmRemoval && mutationError && (0, import_react7.createElement)("p", { role: "alert", className: "dshskill_error" }, t(mutationError)),
40935
+ confirmRemoval && (0, import_react7.createElement)(RemoveDialog, { skill: currentSkill, translate: t, store, busy, error: mutationError, close: closeDialog, removed })
40933
40936
  )
40934
40937
  );
40935
40938
  };
40936
40939
  }
40937
40940
 
40938
40941
  // src/client/style.css
40939
- var style_default = ".dshskill_emblem {\n display: inline-block;\n flex-shrink: 0;\n background-color: currentColor;\n mask-position: center;\n mask-repeat: no-repeat;\n mask-size: 150%;\n}\n\n.dshskill_page {\n --skill-hover: var(--dsw-alias-interactive-bg-hover);\n height: 100%;\n min-width: 0;\n min-height: 0;\n overflow: auto;\n padding: 28px clamp(24px, 4vw, 48px) 48px;\n box-sizing: border-box;\n color: var(--dsw-alias-label-primary);\n background: var(--dsw-alias-bg-base);\n font-size: 13px;\n line-height: 20px;\n}\n\nhtml[data-platform='darwin'] .dshskill_page {\n padding-top: calc(28px + var(--dsh-frame-top-clearance, 0px));\n}\n\n.dshskill_page[data-detail] {\n scrollbar-gutter: stable;\n}\n\n.dshskill_content {\n max-width: 960px;\n margin-inline: auto;\n}\n\n.dshskill_page :where(h1, h2, p, ul):not(:where(.dshskill_detailSections *)) {\n margin: 0;\n}\n\n.dshskill_header h1,\n.dshskill_detailMain h1 {\n font-size: 20px;\n line-height: 28px;\n font-weight: 500;\n overflow-wrap: anywhere;\n}\n\n.dshskill_group h2 {\n font-size: 14px;\n line-height: 22px;\n font-weight: 500;\n}\n\n.dshskill_catalog {\n display: flex;\n flex-direction: column;\n gap: 32px;\n}\n\n.dshskill_header {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n}\n\n.dshskill_header > div {\n min-width: 0;\n max-width: 100%;\n}\n\n@media (hover: hover) {\n .dshskill_row:hover { background: var(--skill-hover); }\n}\n\n.dshskill_search {\n box-sizing: border-box;\n width: 200px;\n max-width: 100%;\n min-width: 0;\n}\n\n.dshskill_search input::placeholder {\n color: var(--dsw-alias-label-secondary);\n}\n\n.dshskill_page :where(.dshskill_back, .dshskill_header h1, .dshskill_detailMain h1, .dshskill_repository):focus-visible {\n outline: var(--dsw-focus-ring-width, 2px) solid var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));\n outline-offset: 2px;\n}\n\n.dshskill_groups,\n.dshskill_group,\n.dshskill_rows {\n display: flex;\n flex-direction: column;\n}\n\n.dshskill_groups {\n gap: 32px;\n}\n\n.dshskill_group {\n gap: 8px;\n}\n\n.dshskill_rows {\n gap: 2px;\n padding: 0;\n list-style: none;\n}\n\n.dshskill_row {\n position: relative;\n display: flex;\n align-items: center;\n gap: 14px;\n min-width: 0;\n margin-inline: -8px;\n padding: 8px;\n border-radius: var(--dsw-radius-xl, 12px);\n line-height: normal;\n}\n\n.dshskill_row:active {\n background: var(--dsw-alias-interactive-bg-active);\n}\n\n.dshskill_rowButton {\n max-width: 100%;\n border: 0;\n padding: 0;\n background: transparent;\n color: inherit;\n font: inherit;\n font-size: 14px;\n line-height: 20px;\n font-weight: 500;\n text-align: start;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n cursor: pointer;\n}\n\n.dshskill_rowButton::after {\n position: absolute;\n inset: 0;\n border-radius: var(--dsw-radius-xl, 12px);\n content: '';\n}\n\n.dshskill_rowButton:focus-visible {\n outline: none;\n}\n\n.dshskill_rowButton:focus-visible::after {\n outline: var(--dsw-focus-ring-width, 2px) solid var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));\n outline-offset: 2px;\n}\n\n.dshskill_icon {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: 48px;\n height: 48px;\n border: 0.5px solid var(--dsw-alias-border-l3);\n border-radius: var(--dsw-radius-lg, 8px);\n color: var(--dsw-alias-label-secondary);\n}\n\n.dshskill_rowText {\n display: flex;\n flex: 1;\n flex-direction: column;\n gap: 4px;\n min-width: 0;\n}\n\n.dshskill_titleRow {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 8px;\n min-width: 0;\n}\n\n.dshskill_muted {\n color: var(--dsw-alias-label-secondary);\n}\n\n.dshskill_description {\n display: -webkit-box;\n -webkit-box-orient: vertical;\n -webkit-line-clamp: 1;\n overflow: hidden;\n color: var(--dsw-alias-label-tertiary);\n font-size: 13px;\n line-height: 18px;\n}\n\n.dshskill_badge {\n height: 18px;\n padding: 0 7px;\n font-size: 10px;\n line-height: 1;\n}\n\n.dshskill_toggle {\n display: inline-flex;\n flex: none;\n align-items: center;\n gap: 8px;\n}\n\n.dshskill_row .dshskill_toggle {\n position: relative;\n z-index: 1;\n}\n\n.dshskill_toggleProgress {\n display: inline-flex;\n width: 14px;\n height: 14px;\n}\n\n.dshskill_toggleProgress > svg {\n width: 100%;\n height: 100%;\n}\n\n.dshskill_progressAnnouncement {\n position: absolute;\n clip-path: inset(50%);\n width: 1px;\n height: 1px;\n overflow: hidden;\n white-space: nowrap;\n}\n\n.dshskill_error {\n color: var(--dsw-alias-state-error-primary);\n}\n\n.dshskill_detailTop,\n.dshskill_detailMain,\n.dshskill_detailSections {\n display: flex;\n flex-direction: column;\n min-width: 0;\n}\n\n.dshskill_back {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 0;\n border: 0;\n background: transparent;\n color: var(--dsw-alias-label-tertiary);\n font: inherit;\n font-size: 12.5px;\n line-height: normal;\n cursor: pointer;\n}\n\n.dshskill_back:hover {\n color: var(--dsw-alias-label-primary);\n}\n\n.dshskill_backIcon {\n transform: rotate(90deg);\n}\n\n.dshskill_detailHead {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n margin-top: 32px;\n}\n\n.dshskill_detailActions {\n display: flex;\n align-items: center;\n gap: 16px;\n}\n\n.dshskill_detailActions .dshskill_detailUninstall {\n color: var(--dsw-alias-state-error-primary);\n --dsh-button-outline-color: color-mix(in srgb, var(--dsw-alias-state-error-primary) 30%, transparent);\n --dsw-alias-interactive-bg-hover: color-mix(in srgb, var(--dsw-alias-state-error-primary) 8%, transparent);\n}\n\n.dshskill_detailMain {\n gap: 8px;\n margin-top: 20px;\n}\n\n.dshskill_detailTitleRow {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 0;\n white-space: nowrap;\n}\n\n.dshskill_detailTitleRow h1,\n.dshskill_attributionText {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.dshskill_detailTitleRow .dshskill_detailAttribution {\n box-sizing: border-box;\n flex: none;\n min-width: 0;\n max-width: 45%;\n /* Balance the smaller attribution text against the title's visible glyphs. */\n translate: 0 1px;\n}\n\n.dshskill_repository {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n color: var(--dsw-alias-label-secondary);\n font-size: 12px;\n line-height: 18px;\n position: relative;\n text-decoration: none;\n}\n\n.dshskill_repository::after {\n position: absolute;\n inset-inline: 0;\n bottom: 0;\n height: 1px;\n background: currentColor;\n content: '';\n}\n\n.dshskill_repository > [aria-hidden] { flex: none; }\n\n.dshskill_detailDescription {\n color: var(--dsw-alias-label-secondary);\n font-size: 14px;\n line-height: 22px;\n overflow-wrap: anywhere;\n}\n\n.dshskill_detailSections {\n gap: 32px;\n margin-top: 32px;\n}\n\n/* Native Modal geometry, with the existing browser dialog top layer. */\n.dshskill_dialog {\n position: fixed;\n width: min(380px, calc(100vw - 48px));\n max-width: none;\n max-height: calc(100dvh - 2 * max(24px, var(--dsh-frame-overlay-top, 24px)));\n margin: auto;\n padding: 0 0 24px;\n overflow: auto;\n box-sizing: border-box;\n border: 0;\n border-radius: var(--dsw-radius-panel);\n background: var(--dsw-alias-bg-layer-2);\n color: var(--dsw-alias-label-primary);\n box-shadow: var(--dsw-elevation-prominent);\n animation: dshskill-modal-enter var(--ds-transition-duration) var(--ds-ease-in-out);\n}\n.dshskill_dialog[open] { display: flex; flex-direction: column; gap: 20px; }\n.dshskill_dialog:focus { outline: none; }\n.dshskill_dialog::backdrop {\n inset: var(--dsh-frame-chrome-top, 0px) 0 0;\n background: var(--dsw-alias-bg-mask-1);\n backdrop-filter: var(--dsw-mask-blur);\n animation: dshskill-modal-enter var(--ds-transition-duration) var(--ds-ease-in-out);\n}\n.dshskill_dialogContent { display: flex; flex-direction: column; width: 100%; }\n.dshskill_dialogHeader {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n padding: 22px 14px 12px 24px;\n}\n.dshskill_dialogHeader h2 { margin: 0; font-size: 16px; line-height: 24px; font-weight: 500; }\n.dshskill_dialogClose {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border: none;\n border-radius: var(--dsw-radius-sm);\n background: transparent;\n cursor: pointer;\n color: var(--dsw-alias-label-secondary);\n}\n.dshskill_dialogClose:disabled { cursor: not-allowed; opacity: 0.4; }\n.dshskill_dialogClose:focus-visible {\n outline: 1px solid var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));\n outline-offset: 2px;\n}\n@media (hover: hover) {\n .dshskill_dialogClose:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover); }\n}\n.dshskill_dialogDescription { margin: 0; padding: 0 24px; font-size: 14px; line-height: 22px; overflow-wrap: anywhere; }\n.dshskill_dialogBody { display: flex; flex-direction: column; min-width: 0; margin-top: 20px; padding: 0 24px; }\n.dshskill_dialogActions { display: flex; align-items: center; justify-content: flex-end; gap: 8px; padding: 0 24px; }\n.dshskill_dangerButton {\n --dsw-alias-button-primary-fill: var(--dsw-alias-state-error-primary);\n --dsw-alias-button-primary-hover: var(--dsw-alias-state-error-primary);\n}\n@keyframes dshskill-modal-enter { from { opacity: 0; } to { opacity: 1; } }\n@media (prefers-reduced-motion: reduce) { .dshskill_dialog, .dshskill_dialog::backdrop { animation: none; } }\n\n@media (max-width: 767px) {\n .dshskill_page:not([data-detail]) {\n padding-inline: 20px;\n }\n}\n";
40942
+ var style_default = ".dshskill_emblem {\n display: inline-block;\n flex-shrink: 0;\n background-color: currentColor;\n mask-position: center;\n mask-repeat: no-repeat;\n mask-size: 150%;\n}\n\n.dshskill_page {\n --skill-hover: var(--dsw-alias-interactive-bg-hover);\n height: 100%;\n min-width: 0;\n min-height: 0;\n overflow: auto;\n padding: 28px clamp(24px, 4vw, 48px) 48px;\n box-sizing: border-box;\n color: var(--dsw-alias-label-primary);\n background: var(--dsw-alias-bg-base);\n font-size: 13px;\n line-height: 20px;\n}\n\nhtml[data-platform='darwin'] .dshskill_page {\n padding-top: calc(28px + var(--dsh-frame-top-clearance, 0px));\n}\n\n.dshskill_page[data-detail] {\n scrollbar-gutter: stable;\n}\n\n.dshskill_content {\n max-width: 960px;\n margin-inline: auto;\n}\n\n.dshskill_page :where(h1, h2, p, ul):not(:where(.dshskill_detailSections *)) {\n margin: 0;\n}\n\n.dshskill_header h1,\n.dshskill_detailMain h1 {\n font-size: 20px;\n line-height: 28px;\n font-weight: 500;\n overflow-wrap: anywhere;\n}\n\n.dshskill_group h2 {\n font-size: 14px;\n line-height: 22px;\n font-weight: 500;\n}\n\n.dshskill_catalog {\n display: flex;\n flex-direction: column;\n gap: 32px;\n}\n\n.dshskill_header {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n}\n\n.dshskill_header > div {\n min-width: 0;\n max-width: 100%;\n}\n\n@media (hover: hover) {\n .dshskill_row:hover { background: var(--skill-hover); }\n}\n\n.dshskill_search {\n box-sizing: border-box;\n width: 200px;\n max-width: 100%;\n min-width: 0;\n}\n\n.dshskill_search input::placeholder {\n color: var(--dsw-alias-label-secondary);\n}\n\n.dshskill_page :where(.dshskill_back, .dshskill_header h1, .dshskill_detailMain h1, .dshskill_repository):focus-visible {\n outline: var(--dsw-focus-ring-width, 2px) solid var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));\n outline-offset: 2px;\n}\n\n.dshskill_groups,\n.dshskill_group,\n.dshskill_rows {\n display: flex;\n flex-direction: column;\n}\n\n.dshskill_groups {\n gap: 32px;\n}\n\n.dshskill_group {\n gap: 8px;\n}\n\n.dshskill_rows {\n gap: 2px;\n padding: 0;\n list-style: none;\n}\n\n.dshskill_row {\n position: relative;\n display: flex;\n align-items: center;\n gap: 14px;\n min-width: 0;\n margin-inline: -8px;\n padding: 8px;\n border-radius: var(--dsw-radius-xl, 12px);\n line-height: normal;\n}\n\n.dshskill_row:active {\n background: var(--dsw-alias-interactive-bg-active);\n}\n\n.dshskill_rowButton {\n max-width: 100%;\n border: 0;\n padding: 0;\n background: transparent;\n color: inherit;\n font: inherit;\n font-size: 14px;\n line-height: 20px;\n font-weight: 500;\n text-align: start;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n cursor: pointer;\n}\n\n.dshskill_rowButton::after {\n position: absolute;\n inset: 0;\n border-radius: var(--dsw-radius-xl, 12px);\n content: '';\n}\n\n.dshskill_rowButton:focus-visible {\n outline: none;\n}\n\n.dshskill_rowButton:focus-visible::after {\n outline: var(--dsw-focus-ring-width, 2px) solid var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));\n outline-offset: 2px;\n}\n\n.dshskill_icon {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: 48px;\n height: 48px;\n border: 0.5px solid var(--dsw-alias-border-l3);\n border-radius: var(--dsw-radius-lg, 8px);\n color: var(--dsw-alias-label-secondary);\n}\n\n.dshskill_rowText {\n display: flex;\n flex: 1;\n flex-direction: column;\n gap: 4px;\n min-width: 0;\n}\n\n.dshskill_titleRow {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 8px;\n min-width: 0;\n}\n\n.dshskill_muted {\n color: var(--dsw-alias-label-secondary);\n}\n\n.dshskill_description {\n display: -webkit-box;\n -webkit-box-orient: vertical;\n -webkit-line-clamp: 1;\n overflow: hidden;\n color: var(--dsw-alias-label-tertiary);\n font-size: 13px;\n line-height: 18px;\n}\n\n.dshskill_badge {\n height: 18px;\n padding: 0 7px;\n font-size: 10px;\n line-height: 1;\n}\n\n.dshskill_toggle {\n display: inline-flex;\n flex: none;\n align-items: center;\n gap: 8px;\n}\n\n.dshskill_row .dshskill_toggle {\n position: relative;\n z-index: 1;\n}\n\n.dshskill_toggleProgress {\n display: inline-flex;\n width: 14px;\n height: 14px;\n}\n\n.dshskill_toggleProgress > svg {\n width: 100%;\n height: 100%;\n}\n\n.dshskill_progressAnnouncement {\n position: absolute;\n clip-path: inset(50%);\n width: 1px;\n height: 1px;\n overflow: hidden;\n white-space: nowrap;\n}\n\n.dshskill_error {\n color: var(--dsw-alias-state-error-primary);\n}\n\n.dshskill_detailTop,\n.dshskill_detailMain,\n.dshskill_detailSections {\n display: flex;\n flex-direction: column;\n min-width: 0;\n}\n\n.dshskill_back {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 0;\n border: 0;\n background: transparent;\n color: var(--dsw-alias-label-tertiary);\n font: inherit;\n font-size: 12.5px;\n line-height: normal;\n cursor: pointer;\n}\n\n.dshskill_back:hover {\n color: var(--dsw-alias-label-primary);\n}\n\n.dshskill_backIcon {\n transform: rotate(90deg);\n}\n\n.dshskill_detailHead {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n margin-top: 32px;\n}\n\n.dshskill_detailActions {\n display: flex;\n align-items: center;\n gap: 16px;\n}\n\n.dshskill_detailActions .dshskill_detailUninstall {\n color: var(--dsw-alias-state-error-primary);\n --dsh-button-outline-color: color-mix(in srgb, var(--dsw-alias-state-error-primary) 30%, transparent);\n --dsw-alias-interactive-bg-hover: color-mix(in srgb, var(--dsw-alias-state-error-primary) 8%, transparent);\n}\n\n.dshskill_detailMain {\n gap: 8px;\n margin-top: 20px;\n}\n\n.dshskill_detailTitleRow {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 0;\n white-space: nowrap;\n}\n\n.dshskill_detailTitleRow h1,\n.dshskill_attributionText {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.dshskill_detailTitleRow .dshskill_detailAttribution {\n box-sizing: border-box;\n flex: none;\n min-width: 0;\n max-width: 45%;\n /* Balance the smaller attribution text against the title's visible glyphs. */\n translate: 0 1px;\n}\n\n.dshskill_repository {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n color: var(--dsw-alias-label-secondary);\n font-size: 12px;\n line-height: 18px;\n position: relative;\n text-decoration: none;\n}\n\n.dshskill_repository::after {\n position: absolute;\n inset-inline: 0;\n bottom: 0;\n height: 1px;\n background: currentColor;\n content: '';\n}\n\n.dshskill_repository > [aria-hidden] { flex: none; }\n\n.dshskill_detailDescription {\n color: var(--dsw-alias-label-secondary);\n font-size: 14px;\n line-height: 22px;\n overflow-wrap: anywhere;\n}\n\n.dshskill_detailSections {\n gap: 32px;\n margin-top: 32px;\n}\n\n@media (max-width: 767px) {\n .dshskill_page:not([data-detail]) {\n padding-inline: 20px;\n }\n}\n";
40940
40943
 
40941
40944
  // src/client/index.js
40942
40945
  var inject = ["slots", "locale"];
40943
40946
  function SkillEmblem({ size = 16, branded = false } = {}) {
40944
- if (branded) return (0, import_react7.createElement)("img", { src: icon_default, width: size, height: size, alt: "" });
40945
- return (0, import_react7.createElement)("span", {
40947
+ if (branded) return (0, import_react8.createElement)("img", { src: icon_default, width: size, height: size, alt: "" });
40948
+ return (0, import_react8.createElement)("span", {
40946
40949
  className: "dshskill_emblem",
40947
40950
  "aria-hidden": true,
40948
40951
  style: { width: size, height: size, maskImage: `url(${JSON.stringify(icon_default)})` }
@@ -40961,7 +40964,7 @@ function SkillDocument({ preview, translate: t, onRetry }) {
40961
40964
  footnotes: t("footnotes")
40962
40965
  });
40963
40966
  const state = preview === null ? void 0 : preview.error ? { status: "error", message: t(preview.error) } : { status: "ready", markdown: preview.body };
40964
- return (0, import_react7.createElement)(DetailDocument, { state: detailDocumentState(state), labels, onRetry });
40967
+ return (0, import_react8.createElement)(DetailDocument, { state: detailDocumentState(state), labels, onRetry });
40965
40968
  }
40966
40969
  function apply(ctx) {
40967
40970
  ctx.effect(() => ctx.locale.register(NS, DICTS), "skill-manager: dictionaries");
@@ -40969,6 +40972,7 @@ function apply(ctx) {
40969
40972
  const style2 = document.createElement("style");
40970
40973
  style2.dataset.plugin = "@dawn0608/dsh-skill-manager";
40971
40974
  style2.textContent = `${host_controls_default}
40975
+ ${host_modal_default}
40972
40976
  ${host_document_default}
40973
40977
  ${katex_min_default}
40974
40978
  ${style_default}`;