@klarkxy/dsh-session-manager 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/lib/client.js CHANGED
@@ -418,6 +418,17 @@ ${scope} {
418
418
  /* --- Layout scaffolding. --- */
419
419
  & .dsh-ui-stack { display: flex; flex-direction: column; gap: 12px; }
420
420
  & .dsh-ui-stack-lg { display: flex; flex-direction: column; gap: 20px; }
421
+ /* Plugin detail pages share one reading column. These are layout recipes;
422
+ * controls keep their own primitive styles. Form spacing follows the host's
423
+ * settings-form/fields.module.css and SettingsForm.module.css. */
424
+ & .dsh-ui-page { display: flex; flex-direction: column; gap: 16px; width: 100%; max-width: 760px; min-width: 0; }
425
+ & .dsh-ui-form { display: flex; flex-direction: column; gap: 0; min-width: 0; }
426
+ &.dsh-ui-form > .dsh-ui-field, & .dsh-ui-form > .dsh-ui-field { padding: 12px 0; }
427
+ & .dsh-ui-form-footer { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; padding-top: 16px; min-width: 0; }
428
+ & .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; }
429
+ @media (max-width: 560px) {
430
+ & .dsh-ui-fields-grid { grid-template-columns: minmax(0, 1fr); }
431
+ }
421
432
  & .dsh-ui-row { display: flex; align-items: center; gap: 8px; min-width: 0; }
422
433
  & .dsh-ui-row-wrap { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
423
434
  & .dsh-ui-spacer { flex: 1; min-width: 0; }
@@ -445,6 +456,9 @@ ${scope} {
445
456
  * official primitive, so this only owns the vertical rhythm. --- */
446
457
  & .dsh-ui-field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
447
458
  & .dsh-ui-field + .dsh-ui-field { border-top: 0.5px solid var(--dsw-alias-border-l2); padding-top: 12px; }
459
+ /* Grid fields share a row, so the stacked-field divider must not win later in
460
+ * the cascade. Reset it here, after the field recipe. */
461
+ & .dsh-ui-fields-grid > .dsh-ui-field { padding: 0; border: 0; }
448
462
  & .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); }
449
463
  & .dsh-ui-label-row { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
450
464
  & .dsh-ui-help { font-size: 12px; line-height: 1.6; color: var(--dsw-alias-label-secondary); }
@@ -635,7 +649,7 @@ ${scope} {
635
649
  & *, & *::before, & *::after { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; }
636
650
  }
637
651
  }
638
- `.replace(/^& (\.dsh-ui-[a-z0-9-]+)(?![+>~])/gm, (_match, className) => `&${className}, & ${className}`);
652
+ `.replace(/^& (\.dsh-ui-[a-z0-9-]+)(?=\s*\{)/gm, (_match, className) => `&${className}, & ${className}`);
639
653
  }
640
654
  //#endregion
641
655
  //#region ../dsh-model-route/src/route.ts
@@ -867,7 +881,14 @@ function useModelCatalog(load, options = {}) {
867
881
  refresh
868
882
  };
869
883
  }
870
- /** Also accepts a mapped state from a caller that owns broader async orchestration. */
884
+ /**
885
+ * Also accepts a mapped state from a caller that owns broader async orchestration.
886
+ *
887
+ * The dsh-ui-* classes carry the styling and resolve through the consuming
888
+ * plugin's own officialUiCss scope (every consumer mounts its root class, so
889
+ * e.g. `.dsh-model-hub .dsh-ui-loading` paints this); dsh-model-catalog-status
890
+ * stays as a structural hook for tests and layout, never a colour source.
891
+ */
871
892
  function ModelCatalogStatus({ state, locale }) {
872
893
  const zh = locale?.toLowerCase().startsWith("zh") === true;
873
894
  const copy = zh ? {
@@ -883,15 +904,17 @@ function ModelCatalogStatus({ state, locale }) {
883
904
  };
884
905
  if (!state.loading && !state.error && state.failures.length === 0) return null;
885
906
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
886
- className: "dsh-model-catalog-status",
907
+ className: "dsh-model-catalog-status dsh-ui-stack",
887
908
  lang: zh ? "zh" : "en",
888
909
  children: [
889
910
  state.loading ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
890
911
  role: "status",
912
+ className: "dsh-ui-loading",
891
913
  children: copy.loading
892
914
  }) : null,
893
915
  state.error ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
894
916
  role: "alert",
917
+ className: "dsh-ui-error dsh-ui-wrap",
895
918
  children: [
896
919
  copy.error,
897
920
  ": ",
@@ -900,20 +923,27 @@ function ModelCatalogStatus({ state, locale }) {
900
923
  }) : null,
901
924
  state.failures.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
902
925
  role: "status",
903
- 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: [
904
- failure.name || failure.id,
905
- ": ",
906
- failure.message
907
- ] }, `${failure.id}:${index}`)) })]
926
+ className: "dsh-ui-meta",
927
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: copy.partial }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
928
+ className: "dsh-ui-list",
929
+ children: state.failures.map((failure, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", { children: [
930
+ failure.name || failure.id,
931
+ ": ",
932
+ failure.message
933
+ ] }, `${failure.id}:${index}`))
934
+ })]
908
935
  }) : null,
909
- state.error || state.failures.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
910
- type: "button",
911
- size: "sm",
912
- disabled: state.loading,
913
- onClick: () => {
914
- state.refresh();
915
- },
916
- children: copy.retry
936
+ state.error || state.failures.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
937
+ className: "dsh-ui-actions",
938
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
939
+ type: "button",
940
+ size: "sm",
941
+ disabled: state.loading,
942
+ onClick: () => {
943
+ state.refresh();
944
+ },
945
+ children: copy.retry
946
+ })
917
947
  }) : null
918
948
  ]
919
949
  });
@@ -973,7 +1003,8 @@ function groupModelMenuChoices(choices, query) {
973
1003
  * Sticky group headings, subsequence ranking, highlight walking and focus
974
1004
  * hand-back all match the host. SYNC POINT: when the host's ModelSelect or
975
1005
  * ModelSelect.module.css changes, this copy must be re-transcribed; styles
976
- * below may only reference --dsw-* theme tokens, never literal colors.
1006
+ * below may only reference allowlisted theme tokens (the --dsw-* set plus the
1007
+ * host's --ds-* motion tokens), never literal colors.
977
1008
  *
978
1009
  * It statically imports the primitives, so only browser clients should load
979
1010
  * this entry; host code and node tests use the core entry (`./index.ts`).
@@ -1481,7 +1512,8 @@ function ModelMenu(props) {
1481
1512
  * sticky group headings (MenuGroup's own CSS), and the l1-stroke prominent
1482
1513
  * elevation at portal z-index 1100. The trigger mirrors the composer's 28px
1483
1514
  * model pill, chevron rotating open. MenuSurface paints fill and backdrop.
1484
- * Only --dsw-* theme tokens may appear here — a literal color is a bug.
1515
+ * Only allowlisted --dsw- and --ds- theme tokens may appear here — a literal
1516
+ * color is a bug.
1485
1517
  */
1486
1518
  const modelMenuCss = `
1487
1519
  .dsh-model-menu-root { min-width: 0; position: relative; display: inline-flex; }
@@ -1504,12 +1536,14 @@ const modelMenuCss = `
1504
1536
  display: flex;
1505
1537
  }
1506
1538
  .dsh-model-menu-trigger:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover); }
1507
- .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)); }
1539
+ .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)); }
1508
1540
  .dsh-model-menu-trigger:disabled { color: var(--dsw-alias-label-dimmed); cursor: default; }
1509
1541
  .dsh-model-menu-triggerLabel { text-overflow: ellipsis; white-space: nowrap; min-width: 0; overflow: hidden; }
1510
1542
  .dsh-model-menu-triggerEffort { text-overflow: ellipsis; white-space: nowrap; min-width: 0; color: var(--dsw-alias-label-caption); flex-shrink: 1000; overflow: hidden; }
1511
- .dsh-model-menu-chevron { color: var(--dsw-alias-label-caption); flex: none; transition: transform 0.12s; }
1543
+ .dsh-model-menu-chevron { color: var(--dsw-alias-label-caption); flex: none; transition: transform var(--ds-transition-duration) var(--ds-ease-in-out); }
1512
1544
  .dsh-model-menu-chevronOpen { transform: rotate(180deg); }
1545
+ /* Portal overlay: the host publishes no z-index token, so the card keeps the
1546
+ * native menu layer's 1100 verbatim. */
1513
1547
  .dsh-model-menu-menu {
1514
1548
  z-index: 1100;
1515
1549
  --dsw-elevation-stroke-color: var(--dsw-alias-border-l1);
@@ -1535,6 +1569,8 @@ const modelMenuCss = `
1535
1569
  .dsh-model-menu-searchWithQuery { padding-right: 34px; }
1536
1570
  .dsh-model-menu-searchRow .dsh-model-menu-search input { padding: 0; font-size: 12px; line-height: normal; }
1537
1571
  .dsh-model-menu-searchRow .dsh-model-menu-search input::placeholder { color: var(--dsw-alias-label-caption); }
1572
+ /* The clear button is a circle by geometry (border-radius: 50%), a shape the
1573
+ * radius token scale does not describe. */
1538
1574
  .dsh-model-menu-searchClear {
1539
1575
  width: 24px;
1540
1576
  height: 24px;
@@ -1703,20 +1739,6 @@ ${modelMenuCss}
1703
1739
  `;
1704
1740
  //#endregion
1705
1741
  //#region src/free-panel.tsx
1706
- function FreeChatIcon({ size }) {
1707
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
1708
- width: size,
1709
- height: size,
1710
- viewBox: "0 0 16 16",
1711
- "aria-hidden": "true",
1712
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
1713
- d: "M2.5 3.5h11v7.5h-4.2L6 13.5V11H2.5z",
1714
- fill: "none",
1715
- stroke: "currentColor",
1716
- strokeWidth: "1.2"
1717
- })
1718
- });
1719
- }
1720
1742
  /** Create failures used to surface inside the standalone panel. The panel is gone,
1721
1743
  * so they get a small overlay instead; closing it dismisses the stored notice. */
1722
1744
  function CreateNoticeDialog(props) {
@@ -1914,7 +1936,7 @@ function TemporaryWorkspacePicker(props) {
1914
1936
  }] : [], {
1915
1937
  id: "::temporary-workspace",
1916
1938
  label: uiText(locale, "tempWorkspace"),
1917
- icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FreeChatIcon, { size: 16 }),
1939
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconNewChatOutlineRegular, { size: 16 }),
1918
1940
  disabled: busy
1919
1941
  }],
1920
1942
  onSelect: (id) => {
@@ -1927,6 +1949,7 @@ function TemporaryWorkspacePicker(props) {
1927
1949
  }),
1928
1950
  props.open && workspaces.phase === "pending" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1929
1951
  role: "status",
1952
+ className: `dsh-free-chat dsh-ui-loading`,
1930
1953
  children: props.t("picker.loading")
1931
1954
  }),
1932
1955
  props.renderSlot(TEMP_WORKSPACE_FLOW_SLOT, {
@@ -1962,6 +1985,7 @@ function TemporaryWorkspacePicker(props) {
1962
1985
  }),
1963
1986
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
1964
1987
  open: failure !== void 0,
1988
+ className: FREE_CHAT_ROOT,
1965
1989
  title: props.t("folderError.title"),
1966
1990
  closeLabel: props.t("close"),
1967
1991
  onClose: () => setFailure(void 0),
@@ -1986,6 +2010,7 @@ function TemporaryWorkspaceNotice({ model, locale }) {
1986
2010
  const state = (0, react.useSyncExternalStore)(model.subscribe, model.getSnapshot, model.getSnapshot);
1987
2011
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
1988
2012
  open: state.failure !== void 0,
2013
+ className: FREE_CHAT_ROOT,
1989
2014
  title: uiText(locale, "createFailed"),
1990
2015
  closeLabel: uiText(locale, "close"),
1991
2016
  onClose: model.dismissFailure,
@@ -3618,7 +3643,7 @@ function SessionManagerSettings(props) {
3618
3643
  });
3619
3644
  };
3620
3645
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3621
- className: `${FREE_CHAT_ROOT} dsh-ui-panel`,
3646
+ className: `${FREE_CHAT_ROOT} dsh-ui-page`,
3622
3647
  children: [
3623
3648
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
3624
3649
  className: "dsh-ui-card",
@@ -3885,7 +3910,7 @@ function SessionManagerSettings(props) {
3885
3910
  ]
3886
3911
  }),
3887
3912
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3888
- className: "dsh-ui-actions",
3913
+ className: "dsh-ui-form-footer",
3889
3914
  children: [
3890
3915
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
3891
3916
  variant: "primary",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@klarkxy/dsh-session-manager",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "Find and read DeepSeek Harness sessions across working directories, use temporary workspaces, continue with one tap on an empty composer, and get a welcome-back recap after time away.",
5
5
  "icon": "./icon.svg",
6
6
  "license": "SEE LICENSE IN LICENSE",
@@ -56,8 +56,8 @@
56
56
  }
57
57
  },
58
58
  "dependencies": {
59
- "@klarkxy/dsh-model-route": "0.2.5",
60
- "@klarkxy/dsh-plugin-kit": "0.4.0",
59
+ "@klarkxy/dsh-model-route": "0.2.6",
60
+ "@klarkxy/dsh-plugin-kit": "0.5.0",
61
61
  "zod": "^4.1.5"
62
62
  },
63
63
  "scripts": {
@@ -143,6 +143,6 @@
143
143
  },
144
144
  "homepage": "https://klarkxy.github.io/dsh-plugins/plugins/session-manager/",
145
145
  "dshRelease": {
146
- "contentHash": "3f0d4a096c191e9cad78a0792f36032994f6c75fd311d8d3fad8bf23ab4eb980"
146
+ "contentHash": "3bdb7b63d41e93d5dd9aeea4c4b818ad880174033d3035a1281295f329fbae63"
147
147
  }
148
148
  }