@deepseek-ai/dsh-client-ui-settings 0.0.1-rc.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/LICENSE +28 -0
- package/README.i18n.yaml +6 -0
- package/README.md +19 -0
- package/README.zh.md +19 -0
- package/lib/client.js +326 -0
- package/lib/index.js +6 -0
- package/lib/invariant.js +25 -0
- package/lib/types/client/SettingsRoot.d.ts +8 -0
- package/lib/types/client/contract/slots.d.ts +152 -0
- package/lib/types/client/index.d.ts +25 -0
- package/lib/types/index.d.ts +4 -0
- package/lib/types/invariant.d.ts +16 -0
- package/package.json +77 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
BSD 3-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026, DeepSeek
|
|
4
|
+
|
|
5
|
+
Redistribution and use in source and binary forms, with or without
|
|
6
|
+
modification, are permitted provided that the following conditions are met:
|
|
7
|
+
|
|
8
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
|
9
|
+
list of conditions and the following disclaimer.
|
|
10
|
+
|
|
11
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
12
|
+
this list of conditions and the following disclaimer in the documentation
|
|
13
|
+
and/or other materials provided with the distribution.
|
|
14
|
+
|
|
15
|
+
3. Neither the name of the copyright holder nor the names of its
|
|
16
|
+
contributors may be used to endorse or promote products derived from
|
|
17
|
+
this software without specific prior written permission.
|
|
18
|
+
|
|
19
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
20
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
21
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
22
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
23
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
24
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
25
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
26
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
27
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
28
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
package/README.i18n.yaml
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
|
|
2
|
+
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
|
3
|
+
# after editing either side, bring the other along and re-record with:
|
|
4
|
+
# pnpm run verify-translation-pairing --write packages/client/ui-settings/README.md
|
|
5
|
+
README.md: 785f0417f00ec8eb1f8c9273b4d81f8ca5ca1810
|
|
6
|
+
README.zh.md: 239987e379aaabd2edbfc9e09cd2fc8cef7a685e
|
package/README.md
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# @deepseek-ai/dsh-client-ui-settings
|
|
2
|
+
|
|
3
|
+
English | [中文](README.zh.md)
|
|
4
|
+
|
|
5
|
+
Settings shell plugin: a pure composition face. It occupies `sidebar.settings` with the trigger chrome and modal settings panel, and declares the slots registrants fill: `settings.trigger` / `settings.header` / `settings.close` (chrome content), `settings.action` (ordered content-header actions), `settings.section` (one page per feature), and `settings.onboarding` (ordered feature-owned pages in a full-viewport stage). The shell ships no copy of its own — all text arrives from registrants (ui-settings-general owns chrome, General, and the product notice; features own their actions, sections, rows, and conditional onboarding pages). Nav labels may be locale-following thunks, so the nav projection resolves them through `resolveSlotLabel` and re-renders on the section ledger bump or the locale revision (an optional `ctx.get('locale')` read; no hard locale dependency).
|
|
6
|
+
|
|
7
|
+
The shell projects the onboarding ledger into ascending order and mounts exactly one page at a time; the takeover chrome (body-level stage, mask, app-root `inert`) belongs to the step itself through ui-primitives' `OnboardingSurface`, so a mounted step still resolving its private facts renders null and neither paints nor blocks anything — the shell shows no empty stage while a step decides. The active registrant receives its id, `complete()`, and an `openSection(id)` callback; completing or skipping transfers ownership to the next entry. Registrants own durable completion, capability readiness, copy, mutations, and the surface wrap, so independently registered flows cannot stack and the shell does not become a second configuration fact source.
|
|
8
|
+
|
|
9
|
+
## Model Experience
|
|
10
|
+
|
|
11
|
+
None, as the settings shell serves browser UI composition; nothing here reaches a model request.
|
|
12
|
+
|
|
13
|
+
#### KV Cache effect
|
|
14
|
+
|
|
15
|
+
None; this package neither assembles nor sends a provider request.
|
|
16
|
+
|
|
17
|
+
## Known Limitations and Deferred Work
|
|
18
|
+
|
|
19
|
+
- **Panel is browser-preference scope only** — host-side settings surfaces (permission mode, tool-call mode) have no RPC backing yet; their skeletons live in ui-settings-general.
|
package/README.zh.md
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# @deepseek-ai/dsh-client-ui-settings
|
|
2
|
+
|
|
3
|
+
[English](README.md) | 中文
|
|
4
|
+
|
|
5
|
+
设置外壳插件:一个纯组合表层。它以触发控件和模态设置面板占用 `sidebar.settings`,并声明由注册方填充的 slot:`settings.trigger`/`settings.header`/`settings.close`(界面框架内容)、`settings.action`(内容标题栏中的有序操作)、`settings.section`(每项功能一页)和 `settings.onboarding`(由各功能持有、显示在全视口展示层中的有序页面)。外壳不自带文案:所有文本都来自注册方(ui-settings-general 拥有界面框架、「通用」分区和产品声明;各功能拥有各自的操作、分区、行和条件式首次使用引导页面)。导航 label 可以是跟随语言的 thunk,因此导航投影经 `resolveSlotLabel` 解析,并在分区账本更新或 locale revision 变化时重新渲染(`ctx.get('locale')` 可选读取,无硬 locale 依赖)。
|
|
6
|
+
|
|
7
|
+
外壳将首次使用引导记录按升序投影,每次只挂载一个页面;接管界面框架(body 层级的展示层、遮罩、应用根节点 `inert`)经 ui-primitives 的 `OnboardingSurface` 由步骤自身持有,因此已挂载但仍在判定私有事实的步骤渲染 null 时不绘制也不阻塞任何内容——步骤判定期间外壳不会露出空白展示层。当前注册方会收到该条目的 id、`complete()` 和 `openSection(id)` 回调;完成或跳过当前页面后,所有权转交给下一项。持久化完成状态、能力就绪状态、文案、变更操作以及展示层包装均由注册方持有,因此独立注册的流程无法堆叠,外壳也不会成为第二个配置事实来源。
|
|
8
|
+
|
|
9
|
+
## 模型体验
|
|
10
|
+
|
|
11
|
+
无。设置外壳为浏览器 UI 提供组合能力;这里没有任何内容进入模型请求。
|
|
12
|
+
|
|
13
|
+
#### KV Cache 影响
|
|
14
|
+
|
|
15
|
+
无;该包既不组装也不发送提供方请求。
|
|
16
|
+
|
|
17
|
+
## 已知限制与暂缓事项
|
|
18
|
+
|
|
19
|
+
- **面板仅涵盖浏览器偏好设置**:宿主侧设置表层(权限模式、工具调用模式)尚无 RPC 支撑;其骨架位于 ui-settings-general。
|
package/lib/client.js
ADDED
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
window.__ModuleLoader__.load({
|
|
2
|
+
id: "@deepseek-ai/dsh-client-ui-settings",
|
|
3
|
+
factory: (require) => {
|
|
4
|
+
var module = { exports: {} };
|
|
5
|
+
var exports = module.exports;
|
|
6
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
7
|
+
let _deepseek_ai_dsh_client_ui_slots = require("@deepseek-ai/dsh-client-ui-slots");
|
|
8
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
9
|
+
let react = require("react");
|
|
10
|
+
let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
11
|
+
//#region ../../../node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs
|
|
12
|
+
function r(e) {
|
|
13
|
+
var t, f, n = "";
|
|
14
|
+
if ("string" == typeof e || "number" == typeof e) n += e;
|
|
15
|
+
else if ("object" == typeof e) if (Array.isArray(e)) {
|
|
16
|
+
var o = e.length;
|
|
17
|
+
for (t = 0; t < o; t++) e[t] && (f = r(e[t])) && (n && (n += " "), n += f);
|
|
18
|
+
} else for (f in e) e[f] && (n && (n += " "), n += f);
|
|
19
|
+
return n;
|
|
20
|
+
}
|
|
21
|
+
function clsx() {
|
|
22
|
+
for (var e, t, f = 0, n = "", o = arguments.length; f < o; f++) (e = arguments[f]) && (t = r(e)) && (n && (n += " "), n += t);
|
|
23
|
+
return n;
|
|
24
|
+
}
|
|
25
|
+
//#endregion
|
|
26
|
+
//#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-settings/src/client/SettingsRoot.module.css.mjs
|
|
27
|
+
const css = ".Gph0iW_trigger{cursor:pointer;width:100%;height:49px;color:var(--dsw-alias-label-primary);background:0 0;border:none;border-radius:12px;flex:none;align-items:center;gap:8px;margin:8px 0 0;padding:0 2px 0 6px;font-family:inherit;font-size:14px;display:flex;overflow:hidden}.Gph0iW_trigger:hover{background:var(--dsw-alias-interactive-bg-hover)}.Gph0iW_trigger.Gph0iW_rail{border-radius:50%;justify-content:center;gap:0;width:36px;height:36px;margin:18px 0 10px;padding:0}.Gph0iW_triggerLabel{white-space:nowrap;overflow:hidden}.Gph0iW_overlay{z-index:1000;justify-content:center;align-items:center;display:flex;position:fixed;inset:0}.Gph0iW_mask{background:var(--dsw-alias-bg-mask-1);backdrop-filter:var(--dsw-mask-blur);position:absolute;inset:0}.Gph0iW_panel{z-index:1;background:var(--dsw-alias-bg-layer-2);width:800px;max-width:calc(100vw - 48px);height:min(800px,100vh - 48px);box-shadow:var(--dsw-shadow-lv3);--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);border-radius:24px;display:flex;position:relative;overflow:hidden}.Gph0iW_nav{box-sizing:border-box;flex-direction:column;flex:none;gap:18px;width:188px;padding:22px 12px 0;display:flex}.Gph0iW_navTitle{color:var(--dsw-alias-label-primary);padding:0 12px;font-size:16px;font-weight:500;line-height:24px}.Gph0iW_navList{flex-direction:column;gap:4px;display:flex}.Gph0iW_navCell{box-sizing:border-box;cursor:pointer;height:40px;color:var(--dsw-alias-label-primary);text-align:left;background:0 0;border:none;border-radius:12px;align-items:center;gap:8px;padding:9px 16px 9px 12px;font-family:inherit;font-size:14px;font-weight:400;line-height:22px;display:flex}.Gph0iW_navCell:hover{background:var(--dsw-specific-sidebar-nav-item-hover)}.Gph0iW_navCell.Gph0iW_active{background:var(--dsw-specific-sidebar-nav-item-active)}.Gph0iW_navIcon{flex:none}.Gph0iW_navLabel{white-space:nowrap;text-overflow:ellipsis;flex:1;min-width:0;overflow:hidden}.Gph0iW_content{flex-direction:column;flex:1;min-width:0;display:flex}.Gph0iW_header{box-sizing:border-box;flex:none;justify-content:space-between;align-items:flex-start;gap:8px;height:54px;padding:20px 14px 8px 10px;display:flex}.Gph0iW_actions{justify-content:flex-end;align-items:center;gap:8px;min-width:0;margin-left:auto;display:flex}.Gph0iW_close{cursor:pointer;width:28px;height:28px;color:var(--dsw-alias-label-primary);background:0 0;border:none;border-radius:28px;justify-content:center;align-items:center;padding:0;display:inline-flex}.Gph0iW_close:hover{background:var(--dsw-alias-interactive-bg-hover)}.Gph0iW_options{flex:1;min-height:0;padding:0 24px 8px;overflow-y:auto}.Gph0iW_hiddenLabel{clip:rect(0 0 0 0);white-space:nowrap;width:1px;height:1px;position:absolute;overflow:hidden}";
|
|
28
|
+
const tagId = "@deepseek-ai/dsh-client-ui-settings/SettingsRoot.module.css";
|
|
29
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
30
|
+
const tag = document.createElement("style");
|
|
31
|
+
tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-settings";
|
|
32
|
+
tag.dataset.pluginCss = tagId;
|
|
33
|
+
tag.textContent = css;
|
|
34
|
+
document.head.appendChild(tag);
|
|
35
|
+
}
|
|
36
|
+
var SettingsRoot_module_css_default = {
|
|
37
|
+
"hiddenLabel": "Gph0iW_hiddenLabel",
|
|
38
|
+
"active": "Gph0iW_active",
|
|
39
|
+
"panel": "Gph0iW_panel",
|
|
40
|
+
"navList": "Gph0iW_navList",
|
|
41
|
+
"header": "Gph0iW_header",
|
|
42
|
+
"nav": "Gph0iW_nav",
|
|
43
|
+
"trigger": "Gph0iW_trigger",
|
|
44
|
+
"navCell": "Gph0iW_navCell",
|
|
45
|
+
"content": "Gph0iW_content",
|
|
46
|
+
"rail": "Gph0iW_rail",
|
|
47
|
+
"overlay": "Gph0iW_overlay",
|
|
48
|
+
"navTitle": "Gph0iW_navTitle",
|
|
49
|
+
"triggerLabel": "Gph0iW_triggerLabel",
|
|
50
|
+
"mask": "Gph0iW_mask",
|
|
51
|
+
"navIcon": "Gph0iW_navIcon",
|
|
52
|
+
"actions": "Gph0iW_actions",
|
|
53
|
+
"close": "Gph0iW_close",
|
|
54
|
+
"navLabel": "Gph0iW_navLabel",
|
|
55
|
+
"options": "Gph0iW_options"
|
|
56
|
+
};
|
|
57
|
+
//#endregion
|
|
58
|
+
//#region lib/types/client/SettingsRoot.js
|
|
59
|
+
/**
|
|
60
|
+
* Settings shell root: the sidebar-foot trigger row plus the centered modal
|
|
61
|
+
* panel (figma 501:29947, 1080x700) with the section nav rail. The shell is
|
|
62
|
+
* a pure composition face — every piece of text (trigger label, panel title,
|
|
63
|
+
* close label, sections) arrives from registrants through slots; accessible
|
|
64
|
+
* names resolve to that content (trigger: its own text; dialog:
|
|
65
|
+
* aria-labelledby the title node; close: visually-hidden slot text). Modal
|
|
66
|
+
* open state and the active section id are component-local viewing state;
|
|
67
|
+
* the onboarding coordinator mounts exactly one ordered registrant while the
|
|
68
|
+
* sessions-derived empty-Hero fact is active — the takeover chrome
|
|
69
|
+
* (OnboardingSurface) belongs to the step, so a mounted-but-deciding step
|
|
70
|
+
* paints nothing here.
|
|
71
|
+
*/
|
|
72
|
+
/** Nav glyph by section id; unknown ids fall back to the settings gear. */
|
|
73
|
+
function navIcon(id) {
|
|
74
|
+
if (id === "models") return (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconDataOutline16, {
|
|
75
|
+
className: SettingsRoot_module_css_default.navIcon,
|
|
76
|
+
size: 16
|
|
77
|
+
});
|
|
78
|
+
if (id === "agent-presets") return (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconThinkOutline16, {
|
|
79
|
+
className: SettingsRoot_module_css_default.navIcon,
|
|
80
|
+
size: 16
|
|
81
|
+
});
|
|
82
|
+
return (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconSettingsOutline16, {
|
|
83
|
+
className: SettingsRoot_module_css_default.navIcon,
|
|
84
|
+
size: 16
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* The modal layer: full-viewport mask + centered panel. Close paths: the
|
|
89
|
+
* header button, a mask click, and document-level Escape (mounted only while
|
|
90
|
+
* open, so the listener lifetime is the panel's).
|
|
91
|
+
*/
|
|
92
|
+
function SettingsPanel({ rows, renderSlot, activeId, onSelect, onClose }) {
|
|
93
|
+
const active = rows.find((r) => r.id === activeId)?.id ?? rows[0]?.id;
|
|
94
|
+
const titleId = (0, react.useId)();
|
|
95
|
+
(0, react.useEffect)(() => {
|
|
96
|
+
const onKeyDown = (e) => {
|
|
97
|
+
if (e.key === "Escape") onClose();
|
|
98
|
+
};
|
|
99
|
+
document.addEventListener("keydown", onKeyDown);
|
|
100
|
+
return () => {
|
|
101
|
+
document.removeEventListener("keydown", onKeyDown);
|
|
102
|
+
};
|
|
103
|
+
}, [onClose]);
|
|
104
|
+
const closeButton = (0, react.useRef)(null);
|
|
105
|
+
(0, react.useEffect)(() => {
|
|
106
|
+
closeButton.current?.focus();
|
|
107
|
+
}, []);
|
|
108
|
+
return (0, react_jsx_runtime.jsxs)("div", {
|
|
109
|
+
className: SettingsRoot_module_css_default.overlay,
|
|
110
|
+
role: "presentation",
|
|
111
|
+
children: [(0, react_jsx_runtime.jsx)("div", {
|
|
112
|
+
className: SettingsRoot_module_css_default.mask,
|
|
113
|
+
"aria-hidden": "true",
|
|
114
|
+
onClick: onClose
|
|
115
|
+
}), (0, react_jsx_runtime.jsxs)("div", {
|
|
116
|
+
className: SettingsRoot_module_css_default.panel,
|
|
117
|
+
role: "dialog",
|
|
118
|
+
"aria-modal": "true",
|
|
119
|
+
"aria-labelledby": titleId,
|
|
120
|
+
children: [(0, react_jsx_runtime.jsxs)("nav", {
|
|
121
|
+
className: SettingsRoot_module_css_default.nav,
|
|
122
|
+
children: [(0, react_jsx_runtime.jsx)("div", {
|
|
123
|
+
className: SettingsRoot_module_css_default.navTitle,
|
|
124
|
+
id: titleId,
|
|
125
|
+
children: renderSlot("settings.header", {})
|
|
126
|
+
}), (0, react_jsx_runtime.jsx)("div", {
|
|
127
|
+
className: SettingsRoot_module_css_default.navList,
|
|
128
|
+
children: rows.map((row) => (0, react_jsx_runtime.jsxs)("button", {
|
|
129
|
+
type: "button",
|
|
130
|
+
className: clsx(SettingsRoot_module_css_default.navCell, row.id === active && SettingsRoot_module_css_default.active),
|
|
131
|
+
"aria-current": row.id === active ? "true" : void 0,
|
|
132
|
+
onClick: () => {
|
|
133
|
+
onSelect(row.id);
|
|
134
|
+
},
|
|
135
|
+
children: [navIcon(row.id), (0, react_jsx_runtime.jsx)("span", {
|
|
136
|
+
className: SettingsRoot_module_css_default.navLabel,
|
|
137
|
+
children: row.label
|
|
138
|
+
})]
|
|
139
|
+
}, row.id))
|
|
140
|
+
})]
|
|
141
|
+
}), (0, react_jsx_runtime.jsxs)("div", {
|
|
142
|
+
className: SettingsRoot_module_css_default.content,
|
|
143
|
+
children: [(0, react_jsx_runtime.jsxs)("div", {
|
|
144
|
+
className: SettingsRoot_module_css_default.header,
|
|
145
|
+
children: [(0, react_jsx_runtime.jsx)("div", {
|
|
146
|
+
className: SettingsRoot_module_css_default.actions,
|
|
147
|
+
children: renderSlot("settings.action", {})
|
|
148
|
+
}), (0, react_jsx_runtime.jsxs)("button", {
|
|
149
|
+
ref: closeButton,
|
|
150
|
+
type: "button",
|
|
151
|
+
className: SettingsRoot_module_css_default.close,
|
|
152
|
+
onClick: onClose,
|
|
153
|
+
children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconCloseOutline16, { size: 14 }), (0, react_jsx_runtime.jsx)("span", {
|
|
154
|
+
className: SettingsRoot_module_css_default.hiddenLabel,
|
|
155
|
+
children: renderSlot("settings.close", {})
|
|
156
|
+
})]
|
|
157
|
+
})]
|
|
158
|
+
}), (0, react_jsx_runtime.jsx)("div", {
|
|
159
|
+
className: SettingsRoot_module_css_default.options,
|
|
160
|
+
children: active !== void 0 && renderSlot("settings.section", { close: onClose }, { only: active })
|
|
161
|
+
})]
|
|
162
|
+
})]
|
|
163
|
+
})]
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Render the settings trigger and panel.
|
|
168
|
+
* @param props - composed slot props (contract/slots.ts).
|
|
169
|
+
* @returns the settings shell element tree.
|
|
170
|
+
*/
|
|
171
|
+
function SettingsRoot(props) {
|
|
172
|
+
const { wide, useSections, useOnboardingSteps, useSessions, renderSlot } = props;
|
|
173
|
+
const [open, setOpen] = (0, react.useState)(false);
|
|
174
|
+
const [activeId, setActiveId] = (0, react.useState)(void 0);
|
|
175
|
+
const [completedOnboarding, setCompletedOnboarding] = (0, react.useState)(() => /* @__PURE__ */ new Set());
|
|
176
|
+
const close = (0, react.useCallback)(() => {
|
|
177
|
+
setOpen(false);
|
|
178
|
+
setActiveId(void 0);
|
|
179
|
+
}, []);
|
|
180
|
+
const openSection = (0, react.useCallback)((id) => {
|
|
181
|
+
setActiveId(id);
|
|
182
|
+
setOpen(true);
|
|
183
|
+
}, []);
|
|
184
|
+
const rows = useSections((s) => s);
|
|
185
|
+
const onboardingSteps = useOnboardingSteps((s) => s);
|
|
186
|
+
const onboardingActive = useSessions((state) => state.phase === "ready" && (state.current === void 0 || state.byId[state.current]?.blank === true));
|
|
187
|
+
const onboardingStep = onboardingActive ? onboardingSteps.find((step) => !completedOnboarding.has(step.id)) : void 0;
|
|
188
|
+
(0, react.useEffect)(() => {
|
|
189
|
+
if (onboardingActive) return;
|
|
190
|
+
setCompletedOnboarding(/* @__PURE__ */ new Set());
|
|
191
|
+
}, [onboardingActive]);
|
|
192
|
+
const completeOnboardingStep = (0, react.useCallback)((id) => {
|
|
193
|
+
setCompletedOnboarding((previous) => {
|
|
194
|
+
if (previous.has(id)) return previous;
|
|
195
|
+
return new Set([...previous, id]);
|
|
196
|
+
});
|
|
197
|
+
}, []);
|
|
198
|
+
return (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
199
|
+
(0, react_jsx_runtime.jsx)("button", {
|
|
200
|
+
type: "button",
|
|
201
|
+
className: clsx(SettingsRoot_module_css_default.trigger, !wide && SettingsRoot_module_css_default.rail),
|
|
202
|
+
"aria-haspopup": "dialog",
|
|
203
|
+
"aria-expanded": open,
|
|
204
|
+
onClick: () => {
|
|
205
|
+
setOpen(true);
|
|
206
|
+
},
|
|
207
|
+
children: renderSlot("settings.trigger", { wide })
|
|
208
|
+
}),
|
|
209
|
+
open && (0, react_jsx_runtime.jsx)(SettingsPanel, {
|
|
210
|
+
rows,
|
|
211
|
+
renderSlot,
|
|
212
|
+
activeId,
|
|
213
|
+
onSelect: setActiveId,
|
|
214
|
+
onClose: close
|
|
215
|
+
}),
|
|
216
|
+
onboardingStep !== void 0 && renderSlot("settings.onboarding", {
|
|
217
|
+
stepId: onboardingStep.id,
|
|
218
|
+
complete: () => {
|
|
219
|
+
completeOnboardingStep(onboardingStep.id);
|
|
220
|
+
},
|
|
221
|
+
openSection
|
|
222
|
+
}, { only: onboardingStep.id })
|
|
223
|
+
] });
|
|
224
|
+
}
|
|
225
|
+
//#endregion
|
|
226
|
+
//#region lib/types/client/index.js
|
|
227
|
+
/**
|
|
228
|
+
* Required services (cordis fiber inject). The target slot is declared by
|
|
229
|
+
* ui-sidebar's apply, whose activation order relative to this one is NOT
|
|
230
|
+
* constrained (dsh.client.inject edges are informational); registration
|
|
231
|
+
* depends on the slot through `slots.inject()`.
|
|
232
|
+
*/
|
|
233
|
+
const inject = ["slots"];
|
|
234
|
+
/**
|
|
235
|
+
* Register the settings shell into `sidebar.settings` once the declaration is
|
|
236
|
+
* on the ledger.
|
|
237
|
+
* @param ctx - client root context.
|
|
238
|
+
*/
|
|
239
|
+
function apply(ctx) {
|
|
240
|
+
let rowsVersion = -1;
|
|
241
|
+
let rowsRevision = -1;
|
|
242
|
+
let rows = [];
|
|
243
|
+
let onboardingVersion = -1;
|
|
244
|
+
let onboardingSteps = [];
|
|
245
|
+
const localeRevision = () => ctx.get("locale")?.getSnapshot().revision ?? 0;
|
|
246
|
+
const injected = () => ({ hooks: {
|
|
247
|
+
sections: {
|
|
248
|
+
getSnapshot: () => {
|
|
249
|
+
const version = ctx.slots.getVersion("settings.section");
|
|
250
|
+
const revision = localeRevision();
|
|
251
|
+
if (version !== rowsVersion || revision !== rowsRevision) {
|
|
252
|
+
rowsVersion = version;
|
|
253
|
+
rowsRevision = revision;
|
|
254
|
+
rows = ctx.slots.entries("settings.section").map((e) => ({
|
|
255
|
+
/* v8 ignore next -- list-slot registration requires id (SlotCore rejects an entry without one) */
|
|
256
|
+
id: e.options.id ?? "",
|
|
257
|
+
order: e.options.order ?? 0,
|
|
258
|
+
label: (0, _deepseek_ai_dsh_client_ui_slots.resolveSlotLabel)(e.options.label) ?? ""
|
|
259
|
+
})).sort((a, b) => a.order - b.order);
|
|
260
|
+
}
|
|
261
|
+
return rows;
|
|
262
|
+
},
|
|
263
|
+
subscribe: (listener) => {
|
|
264
|
+
const offLedger = ctx.slots.subscribe("settings.section", listener);
|
|
265
|
+
const offLocale = ctx.get("locale")?.subscribe(listener);
|
|
266
|
+
return () => {
|
|
267
|
+
offLedger();
|
|
268
|
+
offLocale?.();
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
},
|
|
272
|
+
onboardingSteps: {
|
|
273
|
+
getSnapshot: () => {
|
|
274
|
+
const version = ctx.slots.getVersion("settings.onboarding");
|
|
275
|
+
if (version !== onboardingVersion) {
|
|
276
|
+
onboardingVersion = version;
|
|
277
|
+
onboardingSteps = ctx.slots.entries("settings.onboarding").map((e) => ({
|
|
278
|
+
/* v8 ignore next -- list-slot registration requires id */
|
|
279
|
+
id: e.options.id ?? "",
|
|
280
|
+
order: e.options.order ?? 0
|
|
281
|
+
})).sort((a, b) => a.order - b.order);
|
|
282
|
+
}
|
|
283
|
+
return onboardingSteps;
|
|
284
|
+
},
|
|
285
|
+
subscribe: (listener) => ctx.slots.subscribe("settings.onboarding", listener)
|
|
286
|
+
}
|
|
287
|
+
} });
|
|
288
|
+
ctx.slots.inject("sidebar.settings", () => ctx.slots.register({
|
|
289
|
+
name: "sidebar.settings",
|
|
290
|
+
children: {
|
|
291
|
+
"settings.trigger": {
|
|
292
|
+
kind: "single",
|
|
293
|
+
scope: "root"
|
|
294
|
+
},
|
|
295
|
+
"settings.header": {
|
|
296
|
+
kind: "single",
|
|
297
|
+
scope: "root"
|
|
298
|
+
},
|
|
299
|
+
"settings.action": {
|
|
300
|
+
kind: "list",
|
|
301
|
+
scope: "root"
|
|
302
|
+
},
|
|
303
|
+
"settings.close": {
|
|
304
|
+
kind: "single",
|
|
305
|
+
scope: "root"
|
|
306
|
+
},
|
|
307
|
+
"settings.section": {
|
|
308
|
+
kind: "list",
|
|
309
|
+
scope: "root"
|
|
310
|
+
},
|
|
311
|
+
"settings.onboarding": {
|
|
312
|
+
kind: "list",
|
|
313
|
+
scope: "root"
|
|
314
|
+
}
|
|
315
|
+
},
|
|
316
|
+
inject: injected
|
|
317
|
+
}, SettingsRoot));
|
|
318
|
+
}
|
|
319
|
+
//#endregion
|
|
320
|
+
exports.apply = apply;
|
|
321
|
+
exports.inject = inject;
|
|
322
|
+
return module.exports;
|
|
323
|
+
}
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
//# sourceMappingURL=client.js.map
|
package/lib/index.js
ADDED
package/lib/invariant.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
//#region lib/types/invariant.js
|
|
2
|
+
/**
|
|
3
|
+
* Package-owned invariant companion for `@deepseek-ai/dsh-client-ui-settings`.
|
|
4
|
+
* @module @deepseek-ai/dsh-client-ui-settings/invariant
|
|
5
|
+
*/
|
|
6
|
+
const PACKAGE_NAME = "@deepseek-ai/dsh-client-ui-settings";
|
|
7
|
+
/** Cordis companion plugin name. */
|
|
8
|
+
const name = "client-ui-settings-invariant";
|
|
9
|
+
/** Service required before the companion can reserve package ownership. */
|
|
10
|
+
const inject = ["invariants"];
|
|
11
|
+
/**
|
|
12
|
+
* No runtime invariant: a presentation shell projecting the settings.section
|
|
13
|
+
* ledger into navigation — it emits no cordis events and owns no cross-plugin
|
|
14
|
+
* mutable relation; slot declaration/registration conflicts already fail loud
|
|
15
|
+
* in the slot core at load time.
|
|
16
|
+
*/
|
|
17
|
+
const install = () => {};
|
|
18
|
+
/**
|
|
19
|
+
* Register this package's invariant companion.
|
|
20
|
+
* @param ctx - Cordis context carrying the invariant service.
|
|
21
|
+
* @returns the installed registration's disposer after setup succeeds.
|
|
22
|
+
*/
|
|
23
|
+
const apply = (ctx) => Promise.resolve(ctx.invariants.register(PACKAGE_NAME, install));
|
|
24
|
+
//#endregion
|
|
25
|
+
export { apply, inject, name };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { SettingsRootComponentProps } from './contract/slots.ts';
|
|
2
|
+
/**
|
|
3
|
+
* Render the settings trigger and panel.
|
|
4
|
+
* @param props - composed slot props (contract/slots.ts).
|
|
5
|
+
* @returns the settings shell element tree.
|
|
6
|
+
*/
|
|
7
|
+
export declare function SettingsRoot(props: SettingsRootComponentProps): import("react").JSX.Element;
|
|
8
|
+
//# sourceMappingURL=SettingsRoot.d.ts.map
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Settings shell slot contract — the canonical home of every settings slot
|
|
3
|
+
* type. The shell is a pure composition face with zero copy of its own: it
|
|
4
|
+
* occupies the sidebar-owned `sidebar.settings` hole and declares the slots
|
|
5
|
+
* below; ALL text (trigger label, panel title, header actions, close aria,
|
|
6
|
+
* section content) arrives from registrants. A feature owns its settings surface — adding a
|
|
7
|
+
* setting never means editing the shell; copy that belongs to no single
|
|
8
|
+
* feature (chrome, the General section) is owned by ui-settings-general.
|
|
9
|
+
*/
|
|
10
|
+
import type { HostObservable, InjectFace, PropsRenderSlots, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
|
|
11
|
+
declare module '@deepseek-ai/dsh-client-ui-slots' {
|
|
12
|
+
interface SlotMap {
|
|
13
|
+
/**
|
|
14
|
+
* The sidebar-foot trigger row content: icon + label, supplied as slot
|
|
15
|
+
* content (the accessible name comes from the content — rail state
|
|
16
|
+
* renders the label visually hidden). The shell renders the button
|
|
17
|
+
* chrome and owns open state. Absent contribution degrades to an
|
|
18
|
+
* icon-only button without an accessible name (broken-composition state;
|
|
19
|
+
* the shipped composition always registers the seat).
|
|
20
|
+
*/
|
|
21
|
+
'settings.trigger': {
|
|
22
|
+
kind: 'single';
|
|
23
|
+
scope: 'root';
|
|
24
|
+
owner: SettingsTriggerOwnerProps;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* The panel title text seat. Content renders inside the nav heading row;
|
|
28
|
+
* the dialog's accessible name points at that node via aria-labelledby.
|
|
29
|
+
* Absent contribution leaves the heading empty.
|
|
30
|
+
*/
|
|
31
|
+
'settings.header': {
|
|
32
|
+
kind: 'single';
|
|
33
|
+
scope: 'root';
|
|
34
|
+
owner: SettingsHeaderOwnerProps;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Optional actions rendered in the content-column header before Close.
|
|
38
|
+
* Registrants own visibility, behavior, copy, and failure presentation;
|
|
39
|
+
* the shell supplies only the ordered render site.
|
|
40
|
+
*/
|
|
41
|
+
'settings.action': {
|
|
42
|
+
kind: 'list';
|
|
43
|
+
scope: 'root';
|
|
44
|
+
owner: SettingsHeaderOwnerProps;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* The close button's visually-hidden label text (the button itself —
|
|
48
|
+
* icon, geometry, focus — is shell chrome). Absent contribution leaves
|
|
49
|
+
* the button without an accessible name (broken-composition state).
|
|
50
|
+
*/
|
|
51
|
+
'settings.close': {
|
|
52
|
+
kind: 'single';
|
|
53
|
+
scope: 'root';
|
|
54
|
+
owner: SettingsHeaderOwnerProps;
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* One settings page per list entry. Registrant options carry the nav
|
|
58
|
+
* identity: `id` (section key, drives `only` filtering), `order` (nav
|
|
59
|
+
* position), `label` (registrant-localized display text — the registrant
|
|
60
|
+
* re-registers with fresh text on locale change, so the shell never
|
|
61
|
+
* subscribes locale state; the ledger bump doubles as the shell's
|
|
62
|
+
* re-render trigger). Sections render inside the panel content column.
|
|
63
|
+
* (`settings.general.item`, declared by ui-settings-general's General
|
|
64
|
+
* entry, is typed in the locale package — the common dependency of every
|
|
65
|
+
* item registrant; the shell neither declares nor renders it.)
|
|
66
|
+
*/
|
|
67
|
+
'settings.section': {
|
|
68
|
+
kind: 'list';
|
|
69
|
+
scope: 'root';
|
|
70
|
+
owner: SettingsSectionOwnerProps;
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Root-scoped onboarding steps contributed by settings features. The
|
|
74
|
+
* shell mounts one ordered step at a time; the active registrant either
|
|
75
|
+
* completes itself or keeps ownership until the user completes its sole
|
|
76
|
+
* path. Registrants own readiness, copy, dialog behavior, AND the
|
|
77
|
+
* takeover chrome: a step wraps its visible content in the
|
|
78
|
+
* OnboardingSurface primitive (mask, opaque stage, `#root` inert) and
|
|
79
|
+
* renders null while its private facts are still loading — the shell
|
|
80
|
+
* paints no chrome of its own, so a mounted-but-deciding step shows and
|
|
81
|
+
* blocks nothing (prevents a white flash on reload: a bare unwrapped step
|
|
82
|
+
* would render without mask or stage).
|
|
83
|
+
*/
|
|
84
|
+
'settings.onboarding': {
|
|
85
|
+
kind: 'list';
|
|
86
|
+
scope: 'root';
|
|
87
|
+
owner: SettingsOnboardingOwnerProps;
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/** Owner share of the trigger content seat: the sidebar column state. */
|
|
92
|
+
export interface SettingsTriggerOwnerProps {
|
|
93
|
+
/** Whether the sidebar renders wide content (false = 56px rail, icon only). */
|
|
94
|
+
wide: boolean;
|
|
95
|
+
}
|
|
96
|
+
/** Owner share of the header title seat (the shell supplies nothing). */
|
|
97
|
+
export interface SettingsHeaderOwnerProps {
|
|
98
|
+
/** Marker field: header owner props are intentionally empty. */
|
|
99
|
+
children?: never;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Owner share of a settings section entry. The shell owns modal visibility
|
|
103
|
+
* and navigation; a section's data arrives through its own inject faces and
|
|
104
|
+
* stores. `close` is the one shell affordance a section receives, for flows
|
|
105
|
+
* that leave settings altogether (starting a session from a section) — the
|
|
106
|
+
* onboarding coordinator's `openSection`/`complete` precedent, inverted.
|
|
107
|
+
*/
|
|
108
|
+
export interface SettingsSectionOwnerProps {
|
|
109
|
+
/** Close the settings panel (the shell owns the open state). */
|
|
110
|
+
close: () => void;
|
|
111
|
+
}
|
|
112
|
+
/** Owner share of the currently active settings-backed onboarding step. */
|
|
113
|
+
export interface SettingsOnboardingOwnerProps {
|
|
114
|
+
/** Stable id of the step currently selected by the coordinator. */
|
|
115
|
+
stepId: string;
|
|
116
|
+
/** Complete or skip this step and transfer ownership to the next entry. */
|
|
117
|
+
complete: () => void;
|
|
118
|
+
/** Open the settings panel directly on one registered section. */
|
|
119
|
+
openSection: (id: string) => void;
|
|
120
|
+
}
|
|
121
|
+
/** One nav row projected from a settings.section registration's options. */
|
|
122
|
+
export interface SettingsSectionRow {
|
|
123
|
+
id: string;
|
|
124
|
+
order: number;
|
|
125
|
+
label: string;
|
|
126
|
+
}
|
|
127
|
+
/** One ordered onboarding step projected from a slot registration. */
|
|
128
|
+
export interface SettingsOnboardingStep {
|
|
129
|
+
id: string;
|
|
130
|
+
order: number;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Registrant-private injected share of the settings shell (assembled in
|
|
134
|
+
* apply): the ledger's nav-row projection as a hooks-compartment source —
|
|
135
|
+
* the shell reads no locale state and subscribes through the bound hook.
|
|
136
|
+
*/
|
|
137
|
+
export type SettingsRootInjected = {
|
|
138
|
+
hooks: {
|
|
139
|
+
/** settings.section ledger projected into ordered nav rows. */
|
|
140
|
+
sections: HostObservable<readonly SettingsSectionRow[]>;
|
|
141
|
+
/** settings.onboarding ledger projected into coordinator order. */
|
|
142
|
+
onboardingSteps: HostObservable<readonly SettingsOnboardingStep[]>;
|
|
143
|
+
};
|
|
144
|
+
};
|
|
145
|
+
/**
|
|
146
|
+
* Full component props of the settings shell root: the sidebar owner share
|
|
147
|
+
* (wide/rail state) plus the declared render shares and the injected face
|
|
148
|
+
* (hooks compartment bound to useSections). No store is registered — modal
|
|
149
|
+
* open state and active section id are component-local viewing state.
|
|
150
|
+
*/
|
|
151
|
+
export type SettingsRootComponentProps = PropsRuntime<'sidebar.settings'> & PropsRenderSlots<'settings.trigger' | 'settings.header' | 'settings.action' | 'settings.close' | 'settings.section' | 'settings.onboarding'> & InjectFace<SettingsRootInjected>;
|
|
152
|
+
//# sourceMappingURL=slots.d.ts.map
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Settings shell plugin, browser half. A pure composition face: occupies the
|
|
3
|
+
* sidebar-owned `sidebar.settings` hole with the trigger chrome + modal
|
|
4
|
+
* panel, declares its chrome, section, and onboarding slots, and projects the
|
|
5
|
+
* section ledger into panel navigation. The shell ships no copy; it reads the
|
|
6
|
+
* optional locale revision only to resolve registrant-owned nav-label thunks.
|
|
7
|
+
* ui-settings-general owns the chrome and General content; features own their
|
|
8
|
+
* rows, sections, and onboarding pages. Export discipline: packages/client/AGENTS.md.
|
|
9
|
+
*/
|
|
10
|
+
import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client';
|
|
11
|
+
export type { SettingsHeaderOwnerProps, SettingsRootComponentProps, SettingsRootInjected, SettingsOnboardingOwnerProps, SettingsOnboardingStep, SettingsSectionOwnerProps, SettingsSectionRow, SettingsTriggerOwnerProps, } from './contract/slots.ts';
|
|
12
|
+
/**
|
|
13
|
+
* Required services (cordis fiber inject). The target slot is declared by
|
|
14
|
+
* ui-sidebar's apply, whose activation order relative to this one is NOT
|
|
15
|
+
* constrained (dsh.client.inject edges are informational); registration
|
|
16
|
+
* depends on the slot through `slots.inject()`.
|
|
17
|
+
*/
|
|
18
|
+
export declare const inject: string[];
|
|
19
|
+
/**
|
|
20
|
+
* Register the settings shell into `sidebar.settings` once the declaration is
|
|
21
|
+
* on the ledger.
|
|
22
|
+
* @param ctx - client root context.
|
|
23
|
+
*/
|
|
24
|
+
export declare function apply(ctx: ClientContext): void;
|
|
25
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Package-owned invariant companion for `@deepseek-ai/dsh-client-ui-settings`.
|
|
3
|
+
* @module @deepseek-ai/dsh-client-ui-settings/invariant
|
|
4
|
+
*/
|
|
5
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
6
|
+
/** Cordis companion plugin name. */
|
|
7
|
+
export declare const name = "client-ui-settings-invariant";
|
|
8
|
+
/** Service required before the companion can reserve package ownership. */
|
|
9
|
+
export declare const inject: string[];
|
|
10
|
+
/**
|
|
11
|
+
* Register this package's invariant companion.
|
|
12
|
+
* @param ctx - Cordis context carrying the invariant service.
|
|
13
|
+
* @returns the installed registration's disposer after setup succeeds.
|
|
14
|
+
*/
|
|
15
|
+
export declare const apply: (ctx: Context) => Promise<() => void>;
|
|
16
|
+
//# sourceMappingURL=invariant.d.ts.map
|
package/package.json
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@deepseek-ai/dsh-client-ui-settings",
|
|
3
|
+
"description": "Settings shell plugin: sidebar trigger, modal panel, feature sections, and an ordered full-page onboarding stage",
|
|
4
|
+
"version": "0.0.1-rc.1",
|
|
5
|
+
"publishConfig": {
|
|
6
|
+
"access": "restricted"
|
|
7
|
+
},
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/deepseek-ai/deepseek-harness.git",
|
|
11
|
+
"directory": "packages/client/ui-settings"
|
|
12
|
+
},
|
|
13
|
+
"type": "module",
|
|
14
|
+
"main": "lib/index.js",
|
|
15
|
+
"types": "lib/types/index.d.ts",
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./lib/types/index.d.ts",
|
|
19
|
+
"default": "./lib/index.js"
|
|
20
|
+
},
|
|
21
|
+
"./invariant": {
|
|
22
|
+
"types": "./lib/types/invariant.d.ts",
|
|
23
|
+
"default": "./lib/invariant.js"
|
|
24
|
+
},
|
|
25
|
+
"./client": {
|
|
26
|
+
"types": "./lib/types/client/index.d.ts",
|
|
27
|
+
"default": "./lib/client.js"
|
|
28
|
+
},
|
|
29
|
+
"./src/*": "./src/*",
|
|
30
|
+
"./package.json": "./package.json"
|
|
31
|
+
},
|
|
32
|
+
"dsh": {
|
|
33
|
+
"client": {
|
|
34
|
+
"inject": [
|
|
35
|
+
"@deepseek-ai/dsh-client-runtime",
|
|
36
|
+
"@deepseek-ai/dsh-client-ui-sidebar"
|
|
37
|
+
],
|
|
38
|
+
"platform": "web"
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"license": "BSD-3-Clause",
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"clsx": "^2.0.0"
|
|
44
|
+
},
|
|
45
|
+
"peerDependencies": {
|
|
46
|
+
"react": "^18.2.0",
|
|
47
|
+
"react-dom": "^18.2.0",
|
|
48
|
+
"@deepseek-ai/dsh-client-runtime": "^0.0.1-rc.1",
|
|
49
|
+
"@deepseek-ai/dsh-client-ui-primitives": "^0.0.1-rc.1",
|
|
50
|
+
"@deepseek-ai/dsh-client-ui-slots": "^0.0.1-rc.1",
|
|
51
|
+
"@deepseek-ai/dsh-invariants": "^0.0.1-rc.1",
|
|
52
|
+
"@deepseek-ai/cordis": "^4.0.1-rc.1"
|
|
53
|
+
},
|
|
54
|
+
"devDependencies": {
|
|
55
|
+
"@types/react-dom": "~18.3.0",
|
|
56
|
+
"@types/react": "~18.3.1",
|
|
57
|
+
"react": "^18.2.0",
|
|
58
|
+
"react-dom": "^18.2.0",
|
|
59
|
+
"@deepseek-ai/dsh-client-locale": "^0.0.1-rc.1",
|
|
60
|
+
"@deepseek-ai/dsh-client-runtime": "^0.0.1-rc.1",
|
|
61
|
+
"@deepseek-ai/dsh-client-ui-primitives": "^0.0.1-rc.1",
|
|
62
|
+
"@deepseek-ai/dsh-client-ui-sidebar": "^0.0.1-rc.1",
|
|
63
|
+
"@deepseek-ai/dsh-client-ui-slots": "^0.0.1-rc.1",
|
|
64
|
+
"@deepseek-ai/dsh-invariants": "^0.0.1-rc.1",
|
|
65
|
+
"@deepseek-ai/cordis": "^4.0.1-rc.1"
|
|
66
|
+
},
|
|
67
|
+
"files": [
|
|
68
|
+
"lib/index.js",
|
|
69
|
+
"lib/invariant.js",
|
|
70
|
+
"lib/client.js",
|
|
71
|
+
"lib/types/**/*.d.ts"
|
|
72
|
+
],
|
|
73
|
+
"scripts": {
|
|
74
|
+
"bundle": "tsdown",
|
|
75
|
+
"watch": "tsdown --watch"
|
|
76
|
+
}
|
|
77
|
+
}
|