@dsh-workbench/shared 0.1.1 → 0.1.3

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.
Files changed (95) hide show
  1. package/dist/api/workbench-contract.d.ts +1 -1
  2. package/dist/components/ApprovalDetail.css +4 -0
  3. package/dist/components/ApprovalDetail.d.ts +1 -0
  4. package/dist/components/ApprovalDetail.js +5 -1
  5. package/dist/components/CardHead.css +92 -0
  6. package/dist/components/CardHead.d.ts +1 -0
  7. package/dist/components/CardHead.js +9 -7
  8. package/dist/components/ChoiceGroup.css +75 -0
  9. package/dist/components/ChoiceGroup.d.ts +1 -0
  10. package/dist/components/ChoiceGroup.js +1 -0
  11. package/dist/components/LongTaskRow.css +53 -0
  12. package/dist/components/LongTaskRow.d.ts +3 -0
  13. package/dist/components/LongTaskRow.js +11 -11
  14. package/dist/components/MockStrip.css +39 -0
  15. package/dist/components/MockStrip.d.ts +1 -0
  16. package/dist/components/MockStrip.js +1 -0
  17. package/dist/components/ResourceStates.css +111 -0
  18. package/dist/components/ResourceStates.d.ts +2 -1
  19. package/dist/components/ResourceStates.js +1 -0
  20. package/dist/components/SaveBar.css +7 -0
  21. package/dist/components/SaveBar.d.ts +1 -0
  22. package/dist/components/SaveBar.js +4 -2
  23. package/dist/components/TextField.css +22 -0
  24. package/dist/components/TextField.d.ts +6 -0
  25. package/dist/components/TextField.js +5 -0
  26. package/dist/components/icons.d.ts +0 -12
  27. package/dist/components/icons.js +0 -61
  28. package/dist/host/http.js +5 -29
  29. package/dist/host/provision.d.ts +18 -1
  30. package/dist/host/provision.js +73 -0
  31. package/dist/host.d.ts +6 -0
  32. package/dist/host.js +6 -0
  33. package/dist/i18n/en.js +126 -1
  34. package/dist/i18n/index.d.ts +129 -4
  35. package/dist/i18n/zh.d.ts +128 -3
  36. package/dist/i18n/zh.js +128 -3
  37. package/dist/index.d.ts +1 -1
  38. package/dist/index.js +1 -1
  39. package/package.json +5 -3
  40. package/src/api/workbench-contract.ts +5 -1
  41. package/src/components/ApprovalDetail.css +4 -0
  42. package/src/components/ApprovalDetail.tsx +11 -1
  43. package/src/components/CardHead.css +92 -0
  44. package/src/components/CardHead.tsx +43 -31
  45. package/src/components/ChoiceGroup.css +75 -0
  46. package/src/components/ChoiceGroup.tsx +1 -0
  47. package/src/components/LongTaskRow.css +53 -0
  48. package/src/components/LongTaskRow.tsx +52 -13
  49. package/src/components/MockStrip.css +39 -0
  50. package/src/components/MockStrip.tsx +1 -0
  51. package/src/components/ResourceStates.css +111 -0
  52. package/src/components/ResourceStates.tsx +2 -1
  53. package/src/components/SaveBar.css +7 -0
  54. package/src/components/SaveBar.tsx +8 -5
  55. package/src/components/TextField.css +22 -0
  56. package/src/components/TextField.tsx +17 -0
  57. package/src/components/icons.tsx +0 -164
  58. package/src/host/__tests__/provision.test.ts +90 -0
  59. package/src/host/http.ts +5 -33
  60. package/src/host/provision.ts +87 -0
  61. package/src/host.ts +6 -0
  62. package/src/i18n/en.ts +127 -1
  63. package/src/i18n/zh.ts +128 -4
  64. package/src/index.ts +1 -1
  65. package/dist/components/StateDot.d.ts +0 -5
  66. package/dist/components/StateDot.js +0 -10
  67. package/dist/host/__tests__/fakes.d.ts +0 -41
  68. package/dist/host/__tests__/fakes.js +0 -76
  69. package/dist/host/__tests__/preflight-fixtures.d.ts +0 -19
  70. package/dist/host/__tests__/preflight-fixtures.js +0 -47
  71. package/dist/host/context-inject.d.ts +0 -24
  72. package/dist/host/context-inject.js +0 -74
  73. package/dist/host/events.d.ts +0 -9
  74. package/dist/host/events.js +0 -70
  75. package/dist/host/mount-units.d.ts +0 -52
  76. package/dist/host/mount-units.js +0 -186
  77. package/dist/host/preflight.d.ts +0 -58
  78. package/dist/host/preflight.js +0 -233
  79. package/dist/host/probe-cache.d.ts +0 -6
  80. package/dist/host/probe-cache.js +0 -19
  81. package/dist/host/probe-libs.d.ts +0 -45
  82. package/dist/host/probe-libs.js +0 -61
  83. package/dist/host/probe-units.d.ts +0 -17
  84. package/dist/host/probe-units.js +0 -102
  85. package/dist/host/probe-verdict.d.ts +0 -7
  86. package/dist/host/probe-verdict.js +0 -143
  87. package/dist/host/tool-scope.d.ts +0 -32
  88. package/dist/host/tool-scope.js +0 -84
  89. package/dist/host/unit-readiness.d.ts +0 -7
  90. package/dist/host/unit-readiness.js +0 -5
  91. package/dist/host/unit-registry.d.ts +0 -9
  92. package/dist/host/unit-registry.js +0 -33
  93. package/dist/host/version-range.d.ts +0 -2
  94. package/dist/host/version-range.js +0 -73
  95. package/src/components/StateDot.tsx +0 -31
@@ -1,5 +1,5 @@
1
1
  import type { PluginRelease } from '../api/unit.js';
2
- export type ProvisionAction = 'install' | 'update' | 'uninstall' | 'update-dependency';
2
+ export type ProvisionAction = 'install' | 'update' | 'uninstall' | 'update-dependency' | 'install-bundle' | 'update-bundle' | 'remove-bundle' | 'cancel-install';
3
3
  export interface PluginStatePayload {
4
4
  readonly name: string;
5
5
  readonly status: 'ok' | 'outdated' | 'missing';
@@ -0,0 +1,4 @@
1
+
2
+ .wb-approvalCommand {
3
+ max-width: 100%;
4
+ }
@@ -1,5 +1,6 @@
1
1
  import type { Translate } from '../api/dsh-client.js';
2
2
  import type { UnitClientFace } from '../components/board-module.js';
3
+ import './ApprovalDetail.css';
3
4
  interface ToolCallRoot {
4
5
  readonly callId?: string;
5
6
  readonly name?: string;
@@ -1,4 +1,6 @@
1
1
  import { h } from '../lib/react.js';
2
+ import { CodeBlock } from '@deepseek-ai/dsh-client-ui-primitives';
3
+ import './ApprovalDetail.css';
2
4
  function callOf(snapshot, callId) {
3
5
  if (callId === undefined)
4
6
  return undefined;
@@ -29,5 +31,7 @@ export function ApprovalDetail(props) {
29
31
  const owner = (props.units ?? []).find((face) => face.approval?.tools.includes(input.tool) === true);
30
32
  if (owner?.approval !== undefined)
31
33
  return h(owner.approval.render, { input: input, t: t });
32
- return command === '' ? null : h("code", { className: "wb-approvalCommand" }, command);
34
+ if (command === '')
35
+ return null;
36
+ return (h(CodeBlock, { code: command, className: "wb-approvalCommand", copyLabel: t('blocker.copy'), copiedLabel: t('env.copied') }));
33
37
  }
@@ -0,0 +1,92 @@
1
+
2
+ .wb-cardHead {
3
+ display: flex;
4
+ align-items: center;
5
+ gap: var(--wb-len-6);
6
+ flex: none;
7
+ padding: var(--wb-len-8) var(--wb-len-10) var(--wb-len-8) var(--wb-len-20);
8
+ border-bottom: 0.5px solid var(--dsw-alias-border-l2);
9
+ background: var(--dsw-alias-bg-layer-2);
10
+ }
11
+
12
+ .wb-cardTitle {
13
+ margin: 0;
14
+ font-size: var(--dsw-font-xxs-12-font-size);
15
+ line-height: var(--wb-line-18);
16
+ font-weight: 600;
17
+ color: var(--dsw-alias-label-secondary);
18
+ }
19
+
20
+ .wb-cardMeta {
21
+ font-size: var(--dsw-font-xxxs-11-font-size);
22
+ line-height: var(--wb-line-16);
23
+ color: var(--dsw-alias-label-tertiary);
24
+ min-width: 0;
25
+ overflow: hidden;
26
+ text-overflow: ellipsis;
27
+ white-space: nowrap;
28
+ }
29
+
30
+ .wb-cardMeta::before {
31
+ content: '\00b7';
32
+ margin-right: var(--wb-len-6);
33
+ color: var(--dsw-alias-label-tertiary);
34
+ }
35
+
36
+ .wb-cardOpen {
37
+ display: inline-flex;
38
+ align-items: center;
39
+ justify-content: center;
40
+ box-sizing: border-box;
41
+ margin-left: auto;
42
+ flex: none;
43
+ width: var(--wb-len-22);
44
+ height: var(--wb-len-22);
45
+ padding: var(--wb-len-4);
46
+ border-radius: var(--wb-radius-6);
47
+ color: var(--dsw-alias-label-tertiary);
48
+ }
49
+
50
+ .wb-cardOpen ~ .wb-cardRefresh {
51
+ margin-left: 0;
52
+ }
53
+
54
+ .wb-cardOpen:hover {
55
+ color: var(--dsw-alias-label-primary);
56
+ }
57
+
58
+ .wb-cardRefresh {
59
+ margin-left: auto;
60
+ flex: none;
61
+ width: var(--wb-len-22);
62
+ height: var(--wb-len-22);
63
+ padding: var(--wb-len-4);
64
+ border-radius: var(--wb-radius-6);
65
+ color: var(--dsw-alias-label-tertiary);
66
+ }
67
+
68
+ .wb-cardRefresh:hover:not(:disabled) {
69
+ color: var(--dsw-alias-label-primary);
70
+ }
71
+
72
+ .wb-cardRefresh:disabled {
73
+ cursor: default;
74
+ opacity: 1;
75
+ }
76
+
77
+ .wb-cardGear {
78
+ flex: none;
79
+ width: var(--wb-len-22);
80
+ height: var(--wb-len-22);
81
+ padding: var(--wb-len-3);
82
+ border-radius: var(--wb-radius-6);
83
+ color: var(--dsw-alias-label-tertiary);
84
+ }
85
+
86
+ .wb-cardGear:hover:not(:disabled) {
87
+ color: var(--dsw-alias-label-primary);
88
+ }
89
+
90
+ .wb-cardRefresh.wb-spinning svg {
91
+ animation: wb-spin var(--wb-dur-0-9) linear infinite;
92
+ }
@@ -1,5 +1,6 @@
1
1
  import type { ReactNode } from '../lib/react.js';
2
2
  import type { Translate } from '../api/dsh-client.js';
3
+ import './CardHead.css';
3
4
  export interface CardHeadProps {
4
5
  readonly t: Translate;
5
6
  readonly title: string;
@@ -1,14 +1,16 @@
1
- import { IconRefresh, IconRightUp, IconSettings } from '../components/icons.js';
1
+ import { Button, IconRefreshOutlineRegular, IconRightUpOutlineRegular, IconSettingsOutlineRegular, Tooltip, } from '@deepseek-ai/dsh-client-ui-primitives';
2
2
  import { h } from '../lib/react.js';
3
+ import './CardHead.css';
3
4
  export function CardHead({ t, title, meta, refreshing, onRefresh, gear, gearOpen, onToggleGear, platformHref, platform, platformTitle, }) {
4
5
  const refreshLabel = refreshing ? t('rightbar.refreshing') : t('rightbar.refresh');
5
6
  return (h("header", { className: "wb-cardHead" },
6
7
  h("h2", { className: "wb-cardTitle" }, title),
7
8
  meta === undefined ? null : h("span", { className: "wb-cardMeta" }, meta),
8
- platformHref === undefined || platform === undefined ? null : (h("a", { className: "wb-iconButton wb-cardOpen", href: platformHref, target: "_blank", rel: "noreferrer noopener", title: platformTitle ?? platform, "aria-label": platform },
9
- h(IconRightUp, { size: 14 }))),
10
- h("button", { type: "button", className: `wb-iconButton wb-cardRefresh${refreshing ? ' wb-spinning' : ''}`, "aria-label": refreshLabel, title: refreshLabel, disabled: refreshing, onClick: onRefresh },
11
- h(IconRefresh, { size: 14 })),
12
- gear === undefined || onToggleGear === undefined ? null : (h("button", { type: "button", className: `wb-iconButton wb-cardGear${gearOpen === true ? ' wb-iconButtonActive' : ''}`, "aria-label": gear, "aria-expanded": gearOpen === true, title: gear, onClick: onToggleGear },
13
- h(IconSettings, { size: 15 })))));
9
+ platformHref === undefined || platform === undefined ? null : (h(Tooltip, { label: platformTitle ?? platform },
10
+ h("a", { className: "wb-iconButton wb-cardOpen", href: platformHref, target: "_blank", rel: "noreferrer noopener", "aria-label": platform },
11
+ h(IconRightUpOutlineRegular, { size: 14 })))),
12
+ h(Tooltip, { label: refreshLabel },
13
+ h(Button, { type: "button", size: "sm", variant: "ghost", className: `wb-cardRefresh${refreshing ? ' wb-spinning' : ''}`, "aria-label": refreshLabel, disabled: refreshing, icon: h(IconRefreshOutlineRegular, { size: 14 }), onClick: onRefresh })),
14
+ gear === undefined || onToggleGear === undefined ? null : (h(Tooltip, { label: gear },
15
+ h(Button, { type: "button", size: "sm", variant: "ghost", className: `wb-cardGear${gearOpen === true ? ' wb-iconButtonActive' : ''}`, "aria-label": gear, "aria-expanded": gearOpen === true, icon: h(IconSettingsOutlineRegular, { size: 15 }), onClick: onToggleGear })))));
14
16
  }
@@ -0,0 +1,75 @@
1
+
2
+ .wb-choiceMenu {
3
+ display: flex;
4
+ flex-direction: column;
5
+ gap: var(--wb-len-2);
6
+ padding: var(--wb-len-4);
7
+ border: 0.5px solid var(--dsw-alias-border-l3);
8
+ border-radius: var(--dsw-radius-md);
9
+ background: transparent;
10
+ }
11
+
12
+ .wb-choiceOption {
13
+ display: flex;
14
+ align-items: center;
15
+ gap: var(--wb-len-6);
16
+ min-height: var(--wb-len-30);
17
+ padding: var(--wb-len-6) var(--wb-len-8);
18
+ border-radius: var(--dsw-radius-md);
19
+ cursor: pointer;
20
+ font-size: var(--dsw-font-xs-13-font-size);
21
+ line-height: var(--wb-line-20);
22
+ color: var(--dsw-alias-label-primary);
23
+ }
24
+
25
+ .wb-choiceOption:hover {
26
+ background: var(--dsw-alias-interactive-bg-hover);
27
+ }
28
+
29
+ .wb-choiceLabel {
30
+ flex: 1;
31
+ min-width: 0;
32
+ overflow: hidden;
33
+ text-overflow: ellipsis;
34
+ white-space: nowrap;
35
+ }
36
+
37
+ .wb-radio {
38
+ appearance: none;
39
+ -webkit-appearance: none;
40
+ flex: none;
41
+ box-sizing: border-box;
42
+ width: var(--wb-len-12);
43
+ height: var(--wb-len-12);
44
+ margin: 0;
45
+ border: 1px solid var(--dsw-alias-border-l3);
46
+ border-radius: 50%;
47
+ corner-shape: round;
48
+ background-color: transparent;
49
+ cursor: pointer;
50
+ transition:
51
+ background-color var(--wb-dur-0-12) ease, border-color var(--wb-dur-0-12) ease;
52
+ }
53
+
54
+ .wb-radio:not(:checked):hover {
55
+ border-color: var(--dsw-alias-label-tertiary);
56
+ }
57
+
58
+ .wb-radio:checked {
59
+ border-color: var(--dsw-alias-brand-primary);
60
+ background-image: radial-gradient(
61
+ circle at center,
62
+ var(--dsw-alias-brand-primary) 0 3px,
63
+ transparent 3px
64
+ );
65
+ }
66
+
67
+ .wb-radio:disabled {
68
+ cursor: default;
69
+ opacity: 0.5;
70
+ }
71
+
72
+ .wb-radio:focus-visible {
73
+ outline: var(--dsw-focus-ring-width, var(--wb-len-2)) solid var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));
74
+ outline-offset: 2px;
75
+ }
@@ -1,4 +1,5 @@
1
1
  import type { ReactNode } from '../lib/react.js';
2
+ import './ChoiceGroup.css';
2
3
  export interface ChoiceGroupOption {
3
4
  readonly value: string;
4
5
  readonly label: ReactNode;
@@ -1,4 +1,5 @@
1
1
  import { Fragment, h } from '../lib/react.js';
2
+ import './ChoiceGroup.css';
2
3
  export function ChoiceGroup({ label, name, value, options, disabled, onChange }) {
3
4
  return (h("div", { className: "wb-choiceMenu", role: "radiogroup", "aria-label": label }, options.map((option) => (h(Fragment, { key: option.value },
4
5
  h("label", { className: "wb-choiceOption" },
@@ -0,0 +1,53 @@
1
+
2
+ .wb-longTask {
3
+ padding-top: var(--wb-len-12);
4
+ border-top: 0.5px solid var(--dsw-alias-border-l2);
5
+ display: flex;
6
+ flex-direction: column;
7
+ gap: var(--wb-len-2);
8
+ }
9
+
10
+ .wb-longTaskHead {
11
+ display: flex;
12
+ align-items: center;
13
+ gap: var(--wb-len-6);
14
+ margin: 0;
15
+ }
16
+
17
+ .wb-longTaskLink {
18
+ flex: none;
19
+ display: inline-flex;
20
+ align-items: center;
21
+ gap: var(--wb-len-2);
22
+ text-decoration: none;
23
+ white-space: nowrap;
24
+ }
25
+
26
+ .wb-longTaskHeadline {
27
+ margin: 0;
28
+ font-size: var(--dsw-font-xxs-12-font-size);
29
+ line-height: var(--wb-line-18);
30
+ white-space: pre-wrap;
31
+ overflow-wrap: anywhere;
32
+ color: var(--dsw-alias-label-secondary);
33
+ }
34
+
35
+ .wb-longTaskProblem {
36
+ margin: 0;
37
+ font-size: var(--dsw-font-xxxs-11-font-size);
38
+ line-height: var(--wb-line-16);
39
+ color: var(--dsw-alias-state-error-primary);
40
+ overflow-wrap: anywhere;
41
+ }
42
+
43
+ .wb-longTaskDump {
44
+ margin: var(--wb-len-2) 0 0;
45
+ font-size: var(--dsw-font-xxxs-11-font-size);
46
+ color: var(--dsw-alias-label-tertiary);
47
+ }
48
+
49
+ .wb-longTaskDump pre {
50
+ margin: var(--wb-len-4) 0 0;
51
+ max-height: var(--wb-len-220);
52
+ overflow: auto;
53
+ }
@@ -1,4 +1,5 @@
1
1
  import { type LongTaskStatus } from '../api/long-task.js';
2
+ import './LongTaskRow.css';
2
3
  export interface LongTaskRowLink {
3
4
  readonly href: string;
4
5
  readonly text: string;
@@ -12,5 +13,7 @@ export interface LongTaskRowProps {
12
13
  readonly raw?: string | undefined;
13
14
  readonly stepsTitle?: string | undefined;
14
15
  readonly rawTitle?: string | undefined;
16
+ readonly copyLabel?: string | undefined;
17
+ readonly copiedLabel?: string | undefined;
15
18
  }
16
19
  export declare function LongTaskRow(props: LongTaskRowProps): JSX.Element;
@@ -1,13 +1,15 @@
1
1
  import { longTaskDot } from '../api/long-task.js';
2
- import { Fragment, h } from '../lib/react.js';
3
- import { IconRightUp } from './icons.js';
4
- import { StateDot } from './StateDot.js';
2
+ import { Fragment, h, useState } from '../lib/react.js';
3
+ import { CodeBlock, DisclosureRow, IconCodeOutlineRegular, IconFlatListOutlineRegular, IconRightUpOutlineRegular, StateDot, } from '@deepseek-ai/dsh-client-ui-primitives';
4
+ import './LongTaskRow.css';
5
5
  function RowLink({ href, text }) {
6
- return (h("a", { className: "wb-linkButton wb-longTaskLink", href: href, target: "_blank", rel: "noreferrer noopener" },
6
+ return (h("a", { className: "wb-longTaskLink", href: href, target: "_blank", rel: "noreferrer noopener" },
7
7
  text,
8
- h(IconRightUp, { size: 12 })));
8
+ h(IconRightUpOutlineRegular, { size: 12 })));
9
9
  }
10
10
  export function LongTaskRow(props) {
11
+ const [stepsOpen, setStepsOpen] = useState(false);
12
+ const [rawOpen, setRawOpen] = useState(false);
11
13
  const failed = props.status === 'failed';
12
14
  const problem = props.problem ?? '';
13
15
  const raw = (props.raw ?? '').trim();
@@ -19,10 +21,8 @@ export function LongTaskRow(props) {
19
21
  (props.links ?? []).map((link) => (h(RowLink, { href: link.href, key: `${link.text}@${link.href}`, text: link.text })))),
20
22
  problem === '' ? null : h("p", { className: "wb-longTaskProblem" }, problem),
21
23
  !failed ? null : (h(Fragment, null,
22
- steps.length === 0 || props.stepsTitle === undefined ? null : (h("details", { className: "wb-longTaskDump" },
23
- h("summary", null, props.stepsTitle),
24
- h("pre", null, steps.join('\n')))),
25
- raw === '' || props.rawTitle === undefined ? null : (h("details", { className: "wb-longTaskDump" },
26
- h("summary", null, props.rawTitle),
27
- h("pre", null, raw)))))));
24
+ steps.length === 0 || props.stepsTitle === undefined ? null : (h(DisclosureRow, { className: "wb-longTaskDump", icon: h(IconFlatListOutlineRegular, { size: 14 }), title: props.stepsTitle, open: stepsOpen, expandable: true, expandOnRowClick: true, previewChevron: true, onToggle: () => setStepsOpen(!stepsOpen) },
25
+ h(CodeBlock, { code: steps.join('\n'), className: "wb-longTaskDump", showHeader: props.copyLabel !== undefined, copyLabel: props.copyLabel ?? '', copiedLabel: props.copiedLabel ?? '' }))),
26
+ raw === '' || props.rawTitle === undefined ? null : (h(DisclosureRow, { className: "wb-longTaskDump", icon: h(IconCodeOutlineRegular, { size: 14 }), title: props.rawTitle, open: rawOpen, expandable: true, expandOnRowClick: true, previewChevron: true, onToggle: () => setRawOpen(!rawOpen) },
27
+ h(CodeBlock, { code: raw, className: "wb-longTaskDump", showHeader: props.copyLabel !== undefined, copyLabel: props.copyLabel ?? '', copiedLabel: props.copiedLabel ?? '' })))))));
28
28
  }
@@ -0,0 +1,39 @@
1
+
2
+ .wb-mockStrip {
3
+ display: flex;
4
+ flex-wrap: wrap;
5
+ gap: var(--wb-len-4);
6
+ padding: var(--wb-len-8) var(--wb-len-12);
7
+ border-bottom: 0.5px solid var(--dsw-alias-border-l2);
8
+ flex: none;
9
+ }
10
+
11
+ .wb-mockNote {
12
+ flex: 1 0 100%;
13
+ font-size: var(--wb-font-10);
14
+ line-height: var(--wb-line-14);
15
+ color: var(--dsw-alias-label-tertiary);
16
+ }
17
+
18
+ .wb-mockChip {
19
+ flex: none;
20
+ padding: var(--wb-len-2) var(--wb-len-7);
21
+ border: 0.5px solid var(--dsw-alias-border-l2);
22
+ border-radius: var(--wb-radius-pill);
23
+ corner-shape: round;
24
+ background: transparent;
25
+ font-size: var(--wb-font-10);
26
+ line-height: var(--wb-line-14);
27
+ color: var(--dsw-alias-label-secondary);
28
+ cursor: pointer;
29
+ }
30
+
31
+ .wb-mockChip:hover {
32
+ color: var(--dsw-alias-label-primary);
33
+ }
34
+
35
+ .wb-mockChipOn {
36
+ border-color: transparent;
37
+ background: var(--dsw-alias-brand-primary);
38
+ color: var(--dsw-alias-label-primary-foreground);
39
+ }
@@ -1,3 +1,4 @@
1
+ import './MockStrip.css';
1
2
  export declare function MockStrip({ mocks, index, onPick, note, real, }: {
2
3
  readonly mocks: readonly {
3
4
  readonly id: string;
@@ -1,4 +1,5 @@
1
1
  import { h } from '../lib/react.js';
2
+ import './MockStrip.css';
2
3
  export function MockStrip({ mocks, index, onPick, note, real, }) {
3
4
  return (h("div", { className: "wb-mockStrip" },
4
5
  h("span", { className: "wb-mockNote" }, note ?? '夹具:只切状态,不发请求'),
@@ -0,0 +1,111 @@
1
+
2
+ .wb-centered.wb-centeredCompact {
3
+ flex: none;
4
+ min-height: 0;
5
+ gap: var(--wb-len-8);
6
+ padding: var(--wb-len-20) var(--wb-len-16);
7
+ }
8
+
9
+ .wb-centered.wb-centeredCompact .wb-centeredHero {
10
+ margin-bottom: var(--wb-len-4);
11
+ }
12
+
13
+ .wb-skeleton {
14
+ display: flex;
15
+ flex-direction: column;
16
+ }
17
+
18
+ .wb-skeletonRow {
19
+ display: flex;
20
+ flex-direction: column;
21
+ gap: var(--wb-len-8);
22
+ padding: var(--wb-len-8);
23
+ border-radius: var(--dsw-radius-md);
24
+ }
25
+
26
+ .wb-skeletonRow + .wb-skeletonRow::before {
27
+ content: '';
28
+ align-self: stretch;
29
+ height: var(--wb-len-0-5);
30
+ margin: 0 var(--wb-len-8) var(--wb-len-neg-0-5);
31
+ background: var(--dsw-alias-border-l2);
32
+ }
33
+
34
+ .wb-skeletonBar {
35
+ display: block;
36
+ height: var(--wb-len-13);
37
+ border-radius: var(--dsw-radius-xs);
38
+ background: var(--dsw-alias-bg-skeleton);
39
+ animation: wb-skeleton-pulse var(--wb-dur-1-4) var(--ds-ease-in-out) infinite;
40
+ }
41
+
42
+ .wb-skeletonBarTitle {
43
+ width: 62%;
44
+ }
45
+
46
+ .wb-skeletonBarMeta {
47
+ width: 32%;
48
+ height: var(--wb-len-10);
49
+ }
50
+
51
+ .wb-skeletonRow:nth-child(2n) .wb-skeletonBarTitle {
52
+ width: 74%;
53
+ }
54
+
55
+ .wb-skeletonRow:nth-child(3n) .wb-skeletonBarTitle {
56
+ width: 52%;
57
+ }
58
+
59
+ @keyframes wb-skeleton-pulse {
60
+ 50% {
61
+ opacity: 0.45;
62
+ }
63
+ }
64
+
65
+ .wb-centered {
66
+ box-sizing: border-box;
67
+ display: flex;
68
+ flex-direction: column;
69
+ justify-content: center;
70
+ align-items: center;
71
+ gap: var(--wb-len-14);
72
+ flex: 1;
73
+ min-height: var(--wb-len-240);
74
+ padding: 0 var(--wb-len-24) var(--wb-len-24);
75
+ text-align: center;
76
+ }
77
+
78
+ .wb-centeredHero {
79
+ display: flex;
80
+ margin-bottom: var(--wb-len-16);
81
+ color: var(--dsw-alias-label-dimmed);
82
+ }
83
+
84
+ .wb-centeredTitle {
85
+ font-size: var(--dsw-font-s-14-font-size);
86
+ line-height: var(--wb-line-22);
87
+ color: var(--dsw-alias-label-primary);
88
+ }
89
+
90
+ .wb-centeredHint {
91
+ max-width: var(--wb-len-300);
92
+ font-size: var(--dsw-font-xxs-12-font-size);
93
+ line-height: var(--wb-line-18);
94
+ color: var(--dsw-alias-label-tertiary);
95
+ }
96
+
97
+ .wb-centeredDetail {
98
+ max-width: var(--wb-len-320);
99
+ font-family: var(--ds-font-family-code, monospace);
100
+ font-size: var(--dsw-font-xxxs-11-font-size);
101
+ line-height: var(--wb-line-16);
102
+ color: var(--dsw-alias-label-dimmed);
103
+ word-break: break-all;
104
+ }
105
+
106
+ .wb-centeredAction {
107
+ display: flex;
108
+ justify-content: center;
109
+ gap: var(--wb-len-8);
110
+ margin-top: var(--wb-len-2);
111
+ }
@@ -1,10 +1,11 @@
1
1
  import type { ReactNode } from 'react';
2
+ import './ResourceStates.css';
2
3
  export declare function SkeletonRows({ rows }: {
3
4
  rows?: number;
4
5
  }): JSX.Element;
5
6
  export interface CenteredStateProps {
6
7
  icon: ReactNode;
7
- title: string;
8
+ title: ReactNode;
8
9
  hint?: string;
9
10
  detail?: string;
10
11
  action?: ReactNode;
@@ -1,4 +1,5 @@
1
1
  import { h } from '../lib/react.js';
2
+ import './ResourceStates.css';
2
3
  export function SkeletonRows({ rows = 4 }) {
3
4
  return (h("div", { className: "wb-skeleton", "aria-hidden": "true" }, Array.from({ length: rows }, (_, index) => (h("span", { key: index, className: "wb-skeletonRow" },
4
5
  h("span", { className: "wb-skeletonBar wb-skeletonBarTitle" }),
@@ -0,0 +1,7 @@
1
+
2
+ .wb-formActions {
3
+ display: flex;
4
+ align-items: center;
5
+ justify-content: flex-end;
6
+ gap: var(--wb-len-8);
7
+ }
@@ -1,3 +1,4 @@
1
+ import './SaveBar.css';
1
2
  export interface SaveBarProps {
2
3
  readonly busy: boolean;
3
4
  readonly disabled?: boolean | undefined;
@@ -1,6 +1,8 @@
1
+ import { Button } from '@deepseek-ai/dsh-client-ui-primitives';
1
2
  import { h } from '../lib/react.js';
3
+ import './SaveBar.css';
2
4
  export function SaveBar({ busy, disabled, labels, onCancel, onSave }) {
3
5
  return (h("div", { className: "wb-formActions" },
4
- h("button", { type: "button", className: "wb-linkButton", onClick: onCancel, disabled: busy }, labels.cancel),
5
- h("button", { type: "button", className: "wb-primaryButton", onClick: onSave, disabled: busy || disabled === true }, busy ? labels.saving : labels.save)));
6
+ h(Button, { type: "button", size: "sm", variant: "ghost", onClick: onCancel, disabled: busy }, labels.cancel),
7
+ h(Button, { type: "button", size: "sm", variant: "primary", onClick: onSave, disabled: busy || disabled === true }, busy ? labels.saving : labels.save)));
6
8
  }
@@ -0,0 +1,22 @@
1
+ .wb-textField {
2
+ box-sizing: border-box;
3
+ border: 0.5px solid var(--dsw-alias-border-l4);
4
+ border-radius: var(--dsw-radius-md);
5
+ background: var(--dsw-alias-bg-layer-3);
6
+ font: var(--dsw-font-xs-13);
7
+ color: var(--dsw-alias-label-primary);
8
+ outline: none;
9
+ }
10
+
11
+ .wb-textField:focus {
12
+ border-color: var(--dsw-alias-state-business-primary);
13
+ box-shadow: inset 0 0 0 0.5px var(--dsw-alias-state-business-primary);
14
+ }
15
+
16
+ .wb-textField[aria-invalid='true'] {
17
+ border-color: var(--dsw-alias-state-error-primary);
18
+ }
19
+
20
+ .wb-textField[aria-invalid='true']:focus {
21
+ box-shadow: inset 0 0 0 0.5px var(--dsw-alias-state-error-primary);
22
+ }
@@ -0,0 +1,6 @@
1
+ import type { InputHTMLAttributes } from 'react';
2
+ import './TextField.css';
3
+ export interface TextFieldProps extends InputHTMLAttributes<HTMLInputElement> {
4
+ readonly invalid?: boolean;
5
+ }
6
+ export declare function TextField({ invalid, className, ...rest }: TextFieldProps): JSX.Element;
@@ -0,0 +1,5 @@
1
+ import './TextField.css';
2
+ import { h } from '../lib/react.js';
3
+ export function TextField({ invalid = false, className, ...rest }) {
4
+ return (h("input", { ...rest, className: className === undefined ? 'wb-textField' : `wb-textField ${className}`, "aria-invalid": invalid || undefined }));
5
+ }
@@ -1,18 +1,6 @@
1
1
  export interface IconProps {
2
2
  size?: number;
3
3
  }
4
- export declare function IconPanelLeft({ size }: IconProps): JSX.Element;
5
- export declare function IconFolder({ size }: IconProps): JSX.Element;
6
- export declare function IconFolderOpen({ size }: IconProps): JSX.Element;
7
- export declare function IconChevronDown({ size }: IconProps): JSX.Element;
8
- export declare function IconPlus({ size }: IconProps): JSX.Element;
9
- export declare function IconEllipsis({ size }: IconProps): JSX.Element;
10
- export declare function IconSettings({ size }: IconProps): JSX.Element;
11
- export declare function IconPin({ size }: IconProps): JSX.Element;
12
- export declare function IconCheck({ size }: IconProps): JSX.Element;
13
- export declare function IconNewChat({ size }: IconProps): JSX.Element;
14
- export declare function IconRefresh({ size }: IconProps): JSX.Element;
15
- export declare function IconRightUp({ size }: IconProps): JSX.Element;
16
4
  export declare function IconConversation({ size }: IconProps): JSX.Element;
17
5
  export declare function IconBrandMark({ size }: IconProps): JSX.Element;
18
6
  export declare function IconModules({ size }: IconProps): JSX.Element;