@deepseek-ai/dsh-client-ui-skill 0.1.6-alpha.2 → 0.1.7-alpha.2
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.i18n.yaml +2 -2
- package/README.md +3 -1
- package/README.zh.md +3 -1
- package/lib/client.js +25 -24
- package/lib/types/client/index.d.ts +6 -0
- package/package.json +16 -16
package/README.i18n.yaml
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
|
3
3
|
# after editing either side, bring the other along and re-record with:
|
|
4
4
|
# pnpm run verify-translation-pairing --write packages/client/ui-skill/README.md
|
|
5
|
-
README.md:
|
|
6
|
-
README.zh.md:
|
|
5
|
+
README.md: fdd8cb7fddb54cf73d897bb278086428d0e41214
|
|
6
|
+
README.zh.md: 2090711d5f91bf1efba2f8e19d8d361f9ffb99d9
|
package/README.md
CHANGED
|
@@ -33,7 +33,7 @@ Ordinary-session candidates come from the `skills/list` Remote; the host serves
|
|
|
33
33
|
|
|
34
34
|
### The skill tool row
|
|
35
35
|
|
|
36
|
-
A collapsed row renders the skill glyph, `Skill` title, and requested skill name; running calls carry the transcript shimmer, failures replace the name with the first error line
|
|
36
|
+
A collapsed row renders the skill glyph, `Skill` title, and requested skill name on the same secondary font-size axis, line height, row height, and glyph scaling as ordinary Tool rows. Every lifecycle state retains the ordinary skill glyph; running calls carry the transcript shimmer, while failures replace the name with the first error line and interruptions retain their explicit status text. A settled row expands into a bounded `Instructions` card containing the exact durable tool output, with the standard trajectory `Inspect` affordance when available; this expanded card keeps its own typography. The row derives its name, lifecycle, and body only from the frozen call/result slice supplied by ui-tool, never from the current catalog, so replay stays stable when installed skills or their descriptions change.
|
|
37
37
|
|
|
38
38
|
Hovering over `/name` highlights the entire reference. Clicking a known skill opens its provider-supplied `SKILL.md` path in the right Sidebar while keeping the token editable. An uncached click shares the per-Session catalog fetch and opens when it completes, retaining the clicked Session address. Preset changes, connection resets, and plugin disposal cancel pending previews; a later click fetches the current catalog again. Skills without a file path remain invocable but have no file preview.
|
|
39
39
|
|
|
@@ -51,6 +51,8 @@ The source implements no adjudication hooks and no reference codec: the pick lan
|
|
|
51
51
|
|
|
52
52
|
Catalogs cache per ordinary session with a single-flight fetch; the scope-birth `warm` hook prewarms the session's entry, the forwarded `agent-preset/selected` owner event drops that one session's entry (the catalog belongs to the preset, and a blank session may switch after the warm), and `connection/reset` clears everything. Catalog-addressed continuable children resolve no skill candidates locally because the existing skill RPC requires an attached session; viewing their persisted history must not activate them. The list RPC rides the plugin's root-context connection captured at registration; draft chip visuals derive from the `lexicon` scan.
|
|
53
53
|
|
|
54
|
+
Each catalog fetch requires an existing retained Client Session and waits for its initial history open to succeed before sending `skills/list`. A temporary `skillCatalog` reference holds that Session until the fetch settles. An unretained Session or a failed open rejects without sending the RPC; preset invalidation, connection reset, and plugin disposal also cancel a pending history wait.
|
|
55
|
+
|
|
54
56
|
### Registration
|
|
55
57
|
|
|
56
58
|
The `/client` exports are the plugin body (`apply`/`inject`) only; the source object is internal to the registration effect. The tool row registers the `skill` wire name in ui-tool's keyed `tool.call.toolview` slot.
|
package/README.zh.md
CHANGED
|
@@ -33,7 +33,7 @@ kind: "package-reference"
|
|
|
33
33
|
|
|
34
34
|
### skill 工具行
|
|
35
35
|
|
|
36
|
-
收起的行显示 skill 图标、`Skill` 标题与请求加载的 skill
|
|
36
|
+
收起的行显示 skill 图标、`Skill` 标题与请求加载的 skill 名称,并与普通工具行使用相同的 secondary 字号轴、行高、行高度和图标缩放。所有生命周期状态都保留普通 skill 图标;运行中的调用带有 transcript(文本记录)的扫光效果,失败时以错误首行替换名称,中断则保留明确状态文本。已结算的行展开为一个尺寸受限的 `Instructions` 卡片,其中原样呈现持久化的工具输出;可用时还会提供标准轨迹的 `Inspect` 入口,展开卡片保留自身排版。该行的名称、生命周期与正文只派生自 ui-tool 提供的冻结调用/结果切片,绝不读取当前目录,因此即使已安装的 skill 或其描述发生变化,回放仍保持稳定。
|
|
37
37
|
|
|
38
38
|
鼠标移入 `/name` 时,背景覆盖整个引用。点击已知 skill 会在右侧栏打开提供方给出的 `SKILL.md` 路径,同时保留文本的可编辑性。缓存未就绪时,点击复用该 Session 的目录请求,在完成后按点击时的 Session 地址打开预览。切换预设、重置连接和插件释放会取消待处理的预览;后续点击重新获取当前目录。没有文件路径的 skill 仍可调用,但没有文件预览。
|
|
39
39
|
|
|
@@ -51,6 +51,8 @@ source 不实现任何裁决钩子,也没有引用 codec:pick 落下字面
|
|
|
51
51
|
|
|
52
52
|
目录按普通会话缓存,拉取走 single-flight;scope 创建时的 `warm` 钩子预热该会话的缓存项,转发的 owner 事件 `agent-preset/selected` 丢弃该会话这一项(目录属于 preset,而空会话可能在预热之后才切换),`connection/reset` 清空全部缓存。由目录寻址的可继续 subagent 在客户端解析为没有 skill 候选,因为现有 skill RPC 要求会话已挂载;查看其持久化历史不得激活它。列表 RPC 使用插件注册时捕获的根上下文连接;草稿 chip 视觉由 `lexicon` 扫描派生。
|
|
53
53
|
|
|
54
|
+
每次目录拉取都要求客户端已持有该会话,并等待首次历史打开成功后才发送 `skills/list`。临时的 `skillCatalog` 引用持续持有会话,直到拉取结束。未被持有的会话或打开失败会直接拒绝,不发送 RPC;预设失效、连接重置和插件释放也会取消正在等待的历史打开。
|
|
55
|
+
|
|
54
56
|
### 注册
|
|
55
57
|
|
|
56
58
|
`/client` 导出接口只有插件主体(`apply`/`inject`);source 对象是注册 effect 的内部实现。工具行把 `skill` wire 名称注册进 ui-tool 的 keyed `tool.call.toolview` slot。
|
package/lib/client.js
CHANGED
|
@@ -66,7 +66,7 @@ window.__ModuleLoader__.load({
|
|
|
66
66
|
}
|
|
67
67
|
//#endregion
|
|
68
68
|
//#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-skill/src/client/SkillRow.module.css.mjs
|
|
69
|
-
const css = ".iWrAna_card{flex-direction:column;display:flex}.iWrAna_row{align-items:center;min-width:0;
|
|
69
|
+
const css = ".iWrAna_card{flex-direction:column;display:flex}.iWrAna_row{height:calc(24px + var(--dsh-content-font-delta,0px));align-items:center;min-width:0;display:flex;position:relative;overflow:hidden}.iWrAna_row[data-expandable]{cursor:pointer}.iWrAna_card[data-state=running] .iWrAna_row:after{content:\"\";background:linear-gradient(90deg, transparent 0%, color-mix(in srgb, var(--dsw-alias-bg-base) 60%, transparent) 55%, transparent 100%);pointer-events:none;width:300px;animation:2.6s ease-out infinite iWrAna_dsh-skill-row-sweep;position:absolute;inset:0 auto 0 0}@keyframes iWrAna_dsh-skill-row-sweep{0%{left:-300px}90%,to{left:100%}}.iWrAna_leading{width:calc(16px + var(--dsh-content-font-delta,0px));height:calc(16px + var(--dsh-content-font-delta,0px));color:var(--dsw-alias-label-tertiary);flex:none;justify-content:center;align-items:center;margin-right:6px;display:inline-flex;position:relative}.iWrAna_leading svg{width:calc(14px + var(--dsh-content-font-delta,0px));height:calc(14px + var(--dsh-content-font-delta,0px))}.iWrAna_chevron{color:var(--dsw-alias-label-secondary)}.iWrAna_iconIdle{opacity:1;transition:opacity .1s;display:inline-flex}.iWrAna_chevronHover{opacity:0;margin:auto;transition:opacity .1s;position:absolute;inset:0}.iWrAna_row:hover .iWrAna_iconIdle{opacity:0}.iWrAna_row:hover .iWrAna_chevronHover{opacity:1}.iWrAna_title{font-size:var(--dsh-content-font-size-secondary,13px);line-height:calc(24px + var(--dsh-content-font-delta,0px));color:var(--dsw-alias-label-secondary);flex:none}.iWrAna_separator{background:var(--dsw-alias-label-caption);border-radius:1px;flex:none;width:2px;height:2px;margin:0 8px}.iWrAna_summary{text-overflow:ellipsis;white-space:nowrap;min-width:0;font-size:var(--dsh-content-font-size-secondary,13px);line-height:calc(24px + var(--dsh-content-font-delta,0px));color:var(--dsw-alias-label-tertiary);flex:auto;overflow:hidden}.iWrAna_errorSummary{color:var(--dsw-alias-state-error-primary)}.iWrAna_stoppedSummary{color:var(--dsw-alias-state-warn-label)}.iWrAna_bodyWrap{flex-direction:column;display:flex}.iWrAna_instructionsCard{border:.5px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-markdown-code-block);border-radius:12px;flex-direction:column;max-height:260px;margin:4px 0 4px 4px;display:flex;overflow:hidden}.iWrAna_instructionsHeader{border-bottom:.5px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-markdown-code-block-banner);color:var(--dsw-alias-label-caption);text-transform:uppercase;letter-spacing:.04em;flex:none;padding:8px 12px;font-size:11px;font-weight:500;line-height:16px}.iWrAna_instructions{white-space:pre-wrap;overflow-wrap:anywhere;min-height:0;font:var(--dsw-font-markdown-code-block-small);color:var(--dsw-alias-label-secondary);margin:0;padding:10px 12px 12px;overflow:auto}.iWrAna_instructions[data-error]{color:var(--dsw-alias-state-error-primary)}.iWrAna_instructions::-webkit-scrollbar-thumb{background-clip:padding-box;border:2px solid #0000;border-radius:6px}.iWrAna_instructions::-webkit-scrollbar-track{margin:6px 0}.iWrAna_inspectButton{border:.5px solid var(--dsw-alias-border-l4);corner-shape:round;background:var(--dsw-alias-bg-base);color:var(--dsw-alias-label-secondary);cursor:pointer;opacity:0;border-radius:999px;align-self:flex-start;align-items:center;gap:4px;margin:4px 0 2px 4px;padding:2px 8px;font-size:11px;line-height:16px;transition:opacity .1s;display:inline-flex}.iWrAna_card:hover .iWrAna_inspectButton,.iWrAna_inspectButton:focus-visible{opacity:1}.iWrAna_inspectButton:hover{background:var(--dsw-alias-interactive-bg-hover-solid);color:var(--dsw-alias-label-primary)}.iWrAna_visuallyHidden{clip:rect(0 0 0 0);white-space:nowrap;width:1px;height:1px;position:absolute;overflow:hidden}@media (prefers-reduced-motion:reduce){.iWrAna_card[data-state=running] .iWrAna_row:after{animation:none;display:none}.iWrAna_iconIdle,.iWrAna_chevronHover,.iWrAna_inspectButton{transition:none}}";
|
|
70
70
|
const tagId = "@deepseek-ai/dsh-client-ui-skill/SkillRow.module.css";
|
|
71
71
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
72
72
|
const tag = document.createElement("style");
|
|
@@ -90,6 +90,7 @@ window.__ModuleLoader__.load({
|
|
|
90
90
|
"leading": "iWrAna_leading",
|
|
91
91
|
"row": "iWrAna_row",
|
|
92
92
|
"separator": "iWrAna_separator",
|
|
93
|
+
"stoppedSummary": "iWrAna_stoppedSummary",
|
|
93
94
|
"summary": "iWrAna_summary",
|
|
94
95
|
"title": "iWrAna_title",
|
|
95
96
|
"visuallyHidden": "iWrAna_visuallyHidden"
|
|
@@ -134,30 +135,21 @@ window.__ModuleLoader__.load({
|
|
|
134
135
|
state
|
|
135
136
|
};
|
|
136
137
|
}
|
|
137
|
-
/** State substitution for the collapsed leading slot. */
|
|
138
|
-
function leadingFor(state) {
|
|
139
|
-
switch (state) {
|
|
140
|
-
case "error": return (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.StateDot, { state: "error" });
|
|
141
|
-
case "stopped": return (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.StateDot, { state: "warning" });
|
|
142
|
-
default: return (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconSkillOutline16, { size: 14 });
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
138
|
/** Leading disclosure slot: state icon at rest, chevron on hover or while open. */
|
|
146
|
-
function disclosureLeading(
|
|
147
|
-
if (open) return (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.
|
|
148
|
-
const icon =
|
|
139
|
+
function disclosureLeading(open, expandable) {
|
|
140
|
+
if (open) return (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutlineRegular, { className: SkillRow_module_css_default.chevron });
|
|
141
|
+
const icon = (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconSkillOutlineRegular, { size: 14 });
|
|
149
142
|
if (!expandable) return icon;
|
|
150
143
|
return (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)("span", {
|
|
151
144
|
className: SkillRow_module_css_default.iconIdle,
|
|
152
145
|
children: icon
|
|
153
|
-
}), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.
|
|
146
|
+
}), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutlineRegular, { className: `${SkillRow_module_css_default.chevron} ${SkillRow_module_css_default.chevronHover}` })] });
|
|
154
147
|
}
|
|
155
|
-
/** Visually hidden state copy for the
|
|
148
|
+
/** Visually hidden state copy for the color-only running sweep and error tone. */
|
|
156
149
|
function stateStatus(state, t) {
|
|
157
150
|
switch (state) {
|
|
158
151
|
case "running": return t("row.running");
|
|
159
152
|
case "error": return t("row.failed");
|
|
160
|
-
case "stopped": return t("row.stopped");
|
|
161
153
|
default: return null;
|
|
162
154
|
}
|
|
163
155
|
}
|
|
@@ -172,7 +164,7 @@ window.__ModuleLoader__.load({
|
|
|
172
164
|
const expandable = model.output !== null;
|
|
173
165
|
const open = expanded && expandable;
|
|
174
166
|
const status = stateStatus(model.state, t);
|
|
175
|
-
const summary = model.errorSummary ?? model.name;
|
|
167
|
+
const summary = model.state === "stopped" ? t("row.stopped") : model.errorSummary ?? model.name;
|
|
176
168
|
const toggleExpand = () => {
|
|
177
169
|
setExpanded((value) => !value);
|
|
178
170
|
};
|
|
@@ -188,7 +180,7 @@ window.__ModuleLoader__.load({
|
|
|
188
180
|
onClick: toggleExpand,
|
|
189
181
|
onKeyDown: toggleFromKeyboard
|
|
190
182
|
} : {};
|
|
191
|
-
const leading = disclosureLeading(
|
|
183
|
+
const leading = disclosureLeading(open, expandable);
|
|
192
184
|
return (0, react_jsx_runtime.jsxs)("div", {
|
|
193
185
|
className: SkillRow_module_css_default.card,
|
|
194
186
|
"data-tool": "skill",
|
|
@@ -215,7 +207,7 @@ window.__ModuleLoader__.load({
|
|
|
215
207
|
"aria-hidden": true
|
|
216
208
|
}),
|
|
217
209
|
(0, react_jsx_runtime.jsx)("span", {
|
|
218
|
-
className: model.
|
|
210
|
+
className: `${SkillRow_module_css_default.summary}${model.state === "error" ? ` ${SkillRow_module_css_default.errorSummary}` : model.state === "stopped" ? ` ${SkillRow_module_css_default.stoppedSummary}` : ""}`,
|
|
219
211
|
children: summary
|
|
220
212
|
})
|
|
221
213
|
]
|
|
@@ -236,7 +228,7 @@ window.__ModuleLoader__.load({
|
|
|
236
228
|
type: "button",
|
|
237
229
|
className: SkillRow_module_css_default.inspectButton,
|
|
238
230
|
onClick: inspect,
|
|
239
|
-
children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.
|
|
231
|
+
children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconInspectOutlineRegular, {}), t("row.inspect")]
|
|
240
232
|
}) : null]
|
|
241
233
|
}) : null]
|
|
242
234
|
});
|
|
@@ -248,7 +240,7 @@ window.__ModuleLoader__.load({
|
|
|
248
240
|
const NS = "skill";
|
|
249
241
|
/** Simplified Chinese dictionary (the key-set source of truth). */
|
|
250
242
|
const zh = {
|
|
251
|
-
"row.title": "
|
|
243
|
+
"row.title": "加载技能",
|
|
252
244
|
"row.running": "正在加载 skill",
|
|
253
245
|
"row.failed": "skill 加载失败",
|
|
254
246
|
"row.stopped": "skill 加载已中止",
|
|
@@ -308,10 +300,19 @@ window.__ModuleLoader__.load({
|
|
|
308
300
|
if (existing !== void 0) return existing;
|
|
309
301
|
const abort = new AbortController();
|
|
310
302
|
const promise = (async () => {
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
303
|
+
if (sessions.binding(sessionId) === void 0) throw new Error(`skill catalog requires a retained session "${sessionId}"`);
|
|
304
|
+
return sessions.using(sessionId, {
|
|
305
|
+
source: "skillCatalog",
|
|
306
|
+
signal: abort.signal
|
|
307
|
+
}, async (reference) => {
|
|
308
|
+
abort.signal.throwIfAborted();
|
|
309
|
+
const state = reference.binding.session.getSnapshot();
|
|
310
|
+
if (state.openState !== "open") throw state.openError ?? /* @__PURE__ */ new Error(`session "${sessionId}" is not open`);
|
|
311
|
+
const result = await skills.list({ sessionId }, abort.signal);
|
|
312
|
+
abort.signal.throwIfAborted();
|
|
313
|
+
if (!result.ok) throw new Error(`skills/list failed: ${result.error.code}: ${result.error.message}`);
|
|
314
|
+
return result.value.skills;
|
|
315
|
+
});
|
|
315
316
|
})();
|
|
316
317
|
const entry = {
|
|
317
318
|
promise,
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import type { Context as ClientContext } from '@deepseek-ai/cordis';
|
|
2
2
|
import { type SkillKey } from './locales.ts';
|
|
3
|
+
declare module '@deepseek-ai/dsh-api-session-controller/client' {
|
|
4
|
+
interface SessionReferenceSourceMap {
|
|
5
|
+
/** A skill-catalog fetch waiting for initial history and its RPC result. */
|
|
6
|
+
skillCatalog: unknown;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
3
9
|
declare module '@deepseek-ai/dsh-client-ui-slots' {
|
|
4
10
|
interface LocaleNamespaceMap {
|
|
5
11
|
/** The dedicated skill tool row's copy. */
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepseek-ai/dsh-client-ui-skill",
|
|
3
3
|
"description": "Web skill references and the dedicated skill tool row",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.7-alpha.2",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -41,27 +41,27 @@
|
|
|
41
41
|
},
|
|
42
42
|
"license": "MIT",
|
|
43
43
|
"peerDependencies": {
|
|
44
|
-
"@deepseek-ai/cordis": "
|
|
44
|
+
"@deepseek-ai/cordis": "~4.0.4"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@testing-library/react": "^16.1.0",
|
|
48
48
|
"@types/react": "~18.3.1",
|
|
49
49
|
"react": "^18.2.0",
|
|
50
50
|
"react-dom": "^18.2.0",
|
|
51
|
-
"@deepseek-ai/dsh-api-remotes": "
|
|
52
|
-
"@deepseek-ai/dsh-api-session-controller": "
|
|
53
|
-
"@deepseek-ai/dsh-client-connection": "
|
|
54
|
-
"@deepseek-ai/dsh-client-locale": "
|
|
55
|
-
"@deepseek-ai/dsh-client-test-runtime": "
|
|
56
|
-
"@deepseek-ai/dsh-client-ui-primitives": "
|
|
57
|
-
"@deepseek-ai/dsh-client-ui-
|
|
58
|
-
"@deepseek-ai/dsh-client-ui-
|
|
59
|
-
"@deepseek-ai/dsh-
|
|
60
|
-
"@deepseek-ai/
|
|
61
|
-
"@deepseek-ai/dsh-
|
|
62
|
-
"@deepseek-ai/
|
|
63
|
-
"@deepseek-ai/dsh-client-ui-
|
|
64
|
-
"@deepseek-ai/dsh-
|
|
51
|
+
"@deepseek-ai/dsh-api-remotes": "0.1.7-alpha.2",
|
|
52
|
+
"@deepseek-ai/dsh-api-session-controller": "0.1.7-alpha.2",
|
|
53
|
+
"@deepseek-ai/dsh-client-connection": "0.1.7-alpha.2",
|
|
54
|
+
"@deepseek-ai/dsh-client-locale": "0.1.7-alpha.2",
|
|
55
|
+
"@deepseek-ai/dsh-client-test-runtime": "0.1.7-alpha.2",
|
|
56
|
+
"@deepseek-ai/dsh-client-ui-primitives": "0.1.7-alpha.2",
|
|
57
|
+
"@deepseek-ai/dsh-client-ui-slots": "0.1.7-alpha.2",
|
|
58
|
+
"@deepseek-ai/dsh-client-ui-tool": "0.1.7-alpha.2",
|
|
59
|
+
"@deepseek-ai/dsh-session": "0.1.7-alpha.2",
|
|
60
|
+
"@deepseek-ai/cordis": "~4.0.4",
|
|
61
|
+
"@deepseek-ai/dsh-client-ui-sidebar-right": "0.1.7-alpha.2",
|
|
62
|
+
"@deepseek-ai/dsh-util-workspace-path": "0.1.7-alpha.2",
|
|
63
|
+
"@deepseek-ai/dsh-client-ui-input-trigger": "0.1.7-alpha.2",
|
|
64
|
+
"@deepseek-ai/dsh-client-ui-renderer": "0.1.7-alpha.2"
|
|
65
65
|
},
|
|
66
66
|
"files": [
|
|
67
67
|
"lib/index.js",
|