@klarkxy/dsh-current-title 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -27,12 +27,12 @@ Titles update automatically. Under **Plugins → Auto Title** you can:
27
27
  - pick a title model (empty follows the current session model);
28
28
  - regenerate the title of the open session.
29
29
 
30
- If the model list cannot load, or some providers fail, use **Retry** beside the model picker. Retrying keeps your saved model and prompt draft.
30
+ If the model list cannot load, or some providers fail, use **Retry** beside the model picker; retrying keeps your saved model and prompt draft.
31
31
 
32
32
  ## Limits
33
33
 
34
- - Each title costs one model call, using the model's lowest supported reasoning effort; failed generations keep the existing title.
35
- - Cancellation and timeouts wait for the model call to stop. A provider that does not honor cancellation can delay completion.
34
+ - Each title costs one model call at the model's lowest supported reasoning effort; a failed generation keeps the existing title.
35
+ - Cancellation and timeouts wait for the model call to stop; a provider that ignores cancellation can delay completion.
36
36
  - Turning the plugin off hands titles back to the built-in DSH title feature.
37
37
 
38
38
  ## License
@@ -27,12 +27,12 @@ dsh plugin --profile web add @klarkxy/dsh-current-title
27
27
  - 选择标题模型(留空跟随当前会话模型);
28
28
  - 重新生成当前会话的标题。
29
29
 
30
- 模型列表加载失败或部分提供商不可用时,可在模型选择器旁点击「重试」。重试会保留已保存的模型和提示词草稿。
30
+ 模型列表加载失败或部分提供商不可用时,可在模型选择器旁点击「重试」;重试会保留已保存的模型和提示词草稿。
31
31
 
32
32
  ## 限制
33
33
 
34
- - 每次生成标题会调用一次模型,使用模型支持的最低思考强度;生成失败时保留原标题。
35
- - 取消和超时会等待模型调用真正停止;提供商不响应取消时,完成时间可能延后。
34
+ - 每次生成标题调用一次模型,使用模型支持的最低思考强度;生成失败时保留原标题。
35
+ - 取消和超时会等待模型调用停止;提供商不响应取消时,完成时间可能延后。
36
36
  - 关闭插件后,标题交还给 DSH 自带的标题功能。
37
37
 
38
38
  ## 许可证
@@ -292,6 +292,17 @@ ${scope} {
292
292
  /* --- Layout scaffolding. --- */
293
293
  & .dsh-ui-stack { display: flex; flex-direction: column; gap: 12px; }
294
294
  & .dsh-ui-stack-lg { display: flex; flex-direction: column; gap: 20px; }
295
+ /* Plugin detail pages share one reading column. These are layout recipes;
296
+ * controls keep their own primitive styles. Form spacing follows the host's
297
+ * settings-form/fields.module.css and SettingsForm.module.css. */
298
+ & .dsh-ui-page { display: flex; flex-direction: column; gap: 16px; width: 100%; max-width: 760px; min-width: 0; }
299
+ & .dsh-ui-form { display: flex; flex-direction: column; gap: 0; min-width: 0; }
300
+ &.dsh-ui-form > .dsh-ui-field, & .dsh-ui-form > .dsh-ui-field { padding: 12px 0; }
301
+ & .dsh-ui-form-footer { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; padding-top: 16px; min-width: 0; }
302
+ & .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; }
303
+ @media (max-width: 560px) {
304
+ & .dsh-ui-fields-grid { grid-template-columns: minmax(0, 1fr); }
305
+ }
295
306
  & .dsh-ui-row { display: flex; align-items: center; gap: 8px; min-width: 0; }
296
307
  & .dsh-ui-row-wrap { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
297
308
  & .dsh-ui-spacer { flex: 1; min-width: 0; }
@@ -319,6 +330,9 @@ ${scope} {
319
330
  * official primitive, so this only owns the vertical rhythm. --- */
320
331
  & .dsh-ui-field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
321
332
  & .dsh-ui-field + .dsh-ui-field { border-top: 0.5px solid var(--dsw-alias-border-l2); padding-top: 12px; }
333
+ /* Grid fields share a row, so the stacked-field divider must not win later in
334
+ * the cascade. Reset it here, after the field recipe. */
335
+ & .dsh-ui-fields-grid > .dsh-ui-field { padding: 0; border: 0; }
322
336
  & .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); }
323
337
  & .dsh-ui-label-row { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
324
338
  & .dsh-ui-help { font-size: 12px; line-height: 1.6; color: var(--dsw-alias-label-secondary); }
@@ -509,7 +523,7 @@ ${scope} {
509
523
  & *, & *::before, & *::after { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; }
510
524
  }
511
525
  }
512
- `.replace(/^& (\.dsh-ui-[a-z0-9-]+)(?![+>~])/gm, (_match, className) => `&${className}, & ${className}`);
526
+ `.replace(/^& (\.dsh-ui-[a-z0-9-]+)(?=\s*\{)/gm, (_match, className) => `&${className}, & ${className}`);
513
527
  }
514
528
  //#endregion
515
529
  //#region ../dsh-plugin-kit/src/contracts.ts
@@ -953,7 +967,14 @@ function useModelCatalog(load, options = {}) {
953
967
  refresh
954
968
  };
955
969
  }
956
- /** Also accepts a mapped state from a caller that owns broader async orchestration. */
970
+ /**
971
+ * Also accepts a mapped state from a caller that owns broader async orchestration.
972
+ *
973
+ * The dsh-ui-* classes carry the styling and resolve through the consuming
974
+ * plugin's own officialUiCss scope (every consumer mounts its root class, so
975
+ * e.g. `.dsh-model-hub .dsh-ui-loading` paints this); dsh-model-catalog-status
976
+ * stays as a structural hook for tests and layout, never a colour source.
977
+ */
957
978
  function ModelCatalogStatus({ state, locale }) {
958
979
  const zh = locale?.toLowerCase().startsWith("zh") === true;
959
980
  const copy = zh ? {
@@ -969,15 +990,17 @@ function ModelCatalogStatus({ state, locale }) {
969
990
  };
970
991
  if (!state.loading && !state.error && state.failures.length === 0) return null;
971
992
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
972
- className: "dsh-model-catalog-status",
993
+ className: "dsh-model-catalog-status dsh-ui-stack",
973
994
  lang: zh ? "zh" : "en",
974
995
  children: [
975
996
  state.loading ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
976
997
  role: "status",
998
+ className: "dsh-ui-loading",
977
999
  children: copy.loading
978
1000
  }) : null,
979
1001
  state.error ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
980
1002
  role: "alert",
1003
+ className: "dsh-ui-error dsh-ui-wrap",
981
1004
  children: [
982
1005
  copy.error,
983
1006
  ": ",
@@ -986,20 +1009,27 @@ function ModelCatalogStatus({ state, locale }) {
986
1009
  }) : null,
987
1010
  state.failures.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
988
1011
  role: "status",
989
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: copy.partial }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", { children: state.failures.map((failure, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", { children: [
990
- failure.name || failure.id,
991
- ": ",
992
- failure.message
993
- ] }, `${failure.id}:${index}`)) })]
1012
+ className: "dsh-ui-meta",
1013
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: copy.partial }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
1014
+ className: "dsh-ui-list",
1015
+ children: state.failures.map((failure, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", { children: [
1016
+ failure.name || failure.id,
1017
+ ": ",
1018
+ failure.message
1019
+ ] }, `${failure.id}:${index}`))
1020
+ })]
994
1021
  }) : null,
995
- state.error || state.failures.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
996
- type: "button",
997
- size: "sm",
998
- disabled: state.loading,
999
- onClick: () => {
1000
- state.refresh();
1001
- },
1002
- children: copy.retry
1022
+ state.error || state.failures.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1023
+ className: "dsh-ui-actions",
1024
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
1025
+ type: "button",
1026
+ size: "sm",
1027
+ disabled: state.loading,
1028
+ onClick: () => {
1029
+ state.refresh();
1030
+ },
1031
+ children: copy.retry
1032
+ })
1003
1033
  }) : null
1004
1034
  ]
1005
1035
  });
@@ -1019,7 +1049,8 @@ function ModelCatalogStatus({ state, locale }) {
1019
1049
  * Sticky group headings, subsequence ranking, highlight walking and focus
1020
1050
  * hand-back all match the host. SYNC POINT: when the host's ModelSelect or
1021
1051
  * ModelSelect.module.css changes, this copy must be re-transcribed; styles
1022
- * below may only reference --dsw-* theme tokens, never literal colors.
1052
+ * below may only reference allowlisted theme tokens (the --dsw-* set plus the
1053
+ * host's --ds-* motion tokens), never literal colors.
1023
1054
  *
1024
1055
  * It statically imports the primitives, so only browser clients should load
1025
1056
  * this entry; host code and node tests use the core entry (`./index.ts`).
@@ -1527,7 +1558,8 @@ function ModelMenu(props) {
1527
1558
  * sticky group headings (MenuGroup's own CSS), and the l1-stroke prominent
1528
1559
  * elevation at portal z-index 1100. The trigger mirrors the composer's 28px
1529
1560
  * model pill, chevron rotating open. MenuSurface paints fill and backdrop.
1530
- * Only --dsw-* theme tokens may appear here — a literal color is a bug.
1561
+ * Only allowlisted --dsw- and --ds- theme tokens may appear here — a literal
1562
+ * color is a bug.
1531
1563
  */
1532
1564
  const modelMenuCss = `
1533
1565
  .dsh-model-menu-root { min-width: 0; position: relative; display: inline-flex; }
@@ -1550,12 +1582,14 @@ const modelMenuCss = `
1550
1582
  display: flex;
1551
1583
  }
1552
1584
  .dsh-model-menu-trigger:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover); }
1553
- .dsh-model-menu-trigger:focus-visible:not([data-selection-focus]) { box-shadow: 0 0 0 2px var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary)); }
1585
+ .dsh-model-menu-trigger:focus-visible:not([data-selection-focus]) { box-shadow: 0 0 0 var(--dsw-focus-ring-width) var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary)); }
1554
1586
  .dsh-model-menu-trigger:disabled { color: var(--dsw-alias-label-dimmed); cursor: default; }
1555
1587
  .dsh-model-menu-triggerLabel { text-overflow: ellipsis; white-space: nowrap; min-width: 0; overflow: hidden; }
1556
1588
  .dsh-model-menu-triggerEffort { text-overflow: ellipsis; white-space: nowrap; min-width: 0; color: var(--dsw-alias-label-caption); flex-shrink: 1000; overflow: hidden; }
1557
- .dsh-model-menu-chevron { color: var(--dsw-alias-label-caption); flex: none; transition: transform 0.12s; }
1589
+ .dsh-model-menu-chevron { color: var(--dsw-alias-label-caption); flex: none; transition: transform var(--ds-transition-duration) var(--ds-ease-in-out); }
1558
1590
  .dsh-model-menu-chevronOpen { transform: rotate(180deg); }
1591
+ /* Portal overlay: the host publishes no z-index token, so the card keeps the
1592
+ * native menu layer's 1100 verbatim. */
1559
1593
  .dsh-model-menu-menu {
1560
1594
  z-index: 1100;
1561
1595
  --dsw-elevation-stroke-color: var(--dsw-alias-border-l1);
@@ -1581,6 +1615,8 @@ const modelMenuCss = `
1581
1615
  .dsh-model-menu-searchWithQuery { padding-right: 34px; }
1582
1616
  .dsh-model-menu-searchRow .dsh-model-menu-search input { padding: 0; font-size: 12px; line-height: normal; }
1583
1617
  .dsh-model-menu-searchRow .dsh-model-menu-search input::placeholder { color: var(--dsw-alias-label-caption); }
1618
+ /* The clear button is a circle by geometry (border-radius: 50%), a shape the
1619
+ * radius token scale does not describe. */
1584
1620
  .dsh-model-menu-searchClear {
1585
1621
  width: 24px;
1586
1622
  height: 24px;
@@ -2075,7 +2111,7 @@ function TitleSettings(props) {
2075
2111
  });
2076
2112
  }
2077
2113
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
2078
- className: "current-title-settings ct-root dsh-ui-panel",
2114
+ className: "current-title-settings ct-root dsh-ui-page",
2079
2115
  lang: seat.locale,
2080
2116
  "data-testid": "current-title-settings",
2081
2117
  children: [
@@ -2341,10 +2377,11 @@ function TitleSettings(props) {
2341
2377
  ]
2342
2378
  });
2343
2379
  }
2344
- const styles = `${officialUiCss("ct-root")}${modelMenuCss}
2345
- .ct-root { max-width: 760px; }
2346
- .ct-prompt { min-height: 96px; }
2380
+ const currentTitleOwnCss = `
2381
+ .ct-root .ct-prompt { min-height: 96px; }
2347
2382
  `;
2383
+ const currentTitleStyles = `${officialUiCss("ct-root")}${modelMenuCss}${currentTitleOwnCss}`;
2384
+ const styles = currentTitleStyles;
2348
2385
  function apply(ctx) {
2349
2386
  const client = ctx;
2350
2387
  const packageName = "@klarkxy/dsh-current-title";
@@ -2389,6 +2426,8 @@ exports.TitleSettings = TitleSettings;
2389
2426
  exports.apply = apply;
2390
2427
  exports.applyMarkerFromStatus = applyMarkerFromStatus;
2391
2428
  exports.createTitleClientMarker = createTitleClientMarker;
2429
+ exports.currentTitleOwnCss = currentTitleOwnCss;
2430
+ exports.currentTitleStyles = currentTitleStyles;
2392
2431
  exports.disposeTitleClientMarker = disposeTitleClientMarker;
2393
2432
  exports.inject = inject;
2394
2433
  exports.name = name;