@deepseek-ai/dsh-client-ui-skill 0.1.5-rc.2 → 0.1.6-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.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: 7a524ce1821dc97eaa1b4a67dbe0f956e0da5c87
6
- README.zh.md: 68e6697a51214a8c21002a59f1b60fc685b935e1
5
+ README.md: a1e9e7047f102f2610160905727450833b540082
6
+ README.zh.md: d7669b11fc7249c857e20f3c52f93b8bfd214281
package/README.md CHANGED
@@ -35,6 +35,8 @@ Ordinary-session candidates come from the `skills/list` Remote; the host serves
35
35
 
36
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, and interrupted calls use the warning state. A settled row expands into a bounded `Instructions` card containing the exact durable tool output, with the standard trajectory `Inspect` affordance when available. 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
+ 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
+
38
40
  -----
39
41
 
40
42
  <a id="understand-the-implementation"></a>
@@ -107,4 +109,4 @@ None.
107
109
 
108
110
  </details>
109
111
 
110
- **Runtime invariant:** No companion is published. The slash source, locale dictionaries, and keyed toolview are registry-owned registrations whose disposal is proven by the HMR-safety spec. They emit no cordis events and own no cross-plugin mutable state.
112
+ **Runtime invariant:** No companion is published. The slash source, locale dictionaries, and keyed toolview are registry-owned registrations whose disposal is proven by the HMR-safety spec. They emit no Cordis events and own no cross-plugin mutable state.
package/README.zh.md CHANGED
@@ -9,7 +9,7 @@ kind: "package-reference"
9
9
 
10
10
  ## 概述
11
11
 
12
- `dsh-client-ui-skill` 让用户通过 `/` 建议选择或直接键入 `/name` 来调用 skill。同一条字面命令可以从 Web 编辑器、TUI 和 ACP 一致地加载 skill;如果名称与宿主命令相同,它仍会解析为该命令。skill 调用在对话中显示为可展开的 `Instructions` 卡片;即使已安装的 skill 目录发生变化,卡片落定后的内容仍保持稳定。
12
+ `dsh-client-ui-skill` 让用户通过 `/` 建议选择或直接键入 `/name` 来调用 skill(技能)。同一条字面命令可以从 Web 编辑器、TUI 和 ACP(Agent Client Protocol)一致地加载 skill;如果名称与宿主命令相同,它仍会解析为该命令。skill 调用在对话中显示为可展开的 `Instructions` 卡片;即使已安装的 skill 目录发生变化,卡片落定后的内容仍保持稳定。
13
13
 
14
14
  ## 目录
15
15
 
@@ -29,11 +29,13 @@ kind: "package-reference"
29
29
 
30
30
  ### source 提供什么
31
31
 
32
- 普通会话的候选来自 `skills/list` Remote;宿主提供每一个用户可调用的 skill,`modelInvocable: false` 的条目(即 `disable-model-invocation` skill,此路径是其唯一入口)会以当前语言把仅限用户标记作为描述前缀带上。结果经 `/` 菜单共享的名字排序器(ui-primitives 的 `rankByName`)排名:查询作为不区分大小写的有序子序列匹配 skill 名,前缀命中排最前,同分保持宿主顺序([排名决策](../../../.agents/notes/archived/feature/2026-08-04-web-slash-command-fuzzy-discovery.md))。`skills/list` 调用失败时会被记录并静默丢弃该菜单组——菜单只显示 pending/ready 状态。
32
+ 普通会话的候选来自 `skills/list` Remote;宿主提供每一个用户可调用的 skill,`modelInvocable: false` 的条目(即 `disable-model-invocation` skill,此路径是其唯一入口)会以当前语言把仅限用户标记作为描述前缀带上。结果经 `/` 菜单共享的名字排序器(ui-primitives 的 `rankByName`)排名:查询作为不区分大小写的有序子序列匹配 skill 名,前缀命中排最前,同分保持宿主顺序([排名决策](../../../.agents/notes/archived/feature/2026-08-04-web-slash-command-fuzzy-discovery.md))。`skills/list` 调用失败时会被记录并静默丢弃该菜单组——菜单只显示 pending/ready 状态。
33
33
 
34
34
  ### skill 工具行
35
35
 
36
- 收起的行显示 skill 图标、`Skill` 标题与请求加载的 skill 名称;运行中的调用带有 transcript 的扫光效果,失败时用错误首行替换名称,中断的调用使用警告状态。已结算的行展开为一个尺寸受限的 `Instructions` 卡片,其中原样呈现持久化的工具输出;可用时还会提供标准轨迹的 `Inspect` 入口。该行的名称、生命周期与正文只派生自 ui-tool 提供的冻结调用/结果切片,绝不读取当前目录,因此即使已安装的 skill 或其描述发生变化,回放仍保持稳定。
36
+ 收起的行显示 skill 图标、`Skill` 标题与请求加载的 skill 名称;运行中的调用带有 transcript(文本记录)的扫光效果,失败时用错误首行替换名称,中断的调用使用警告状态。已结算的行展开为一个尺寸受限的 `Instructions` 卡片,其中原样呈现持久化的工具输出;可用时还会提供标准轨迹的 `Inspect` 入口。该行的名称、生命周期与正文只派生自 ui-tool 提供的冻结调用/结果切片,绝不读取当前目录,因此即使已安装的 skill 或其描述发生变化,回放仍保持稳定。
37
+
38
+ 鼠标移入 `/name` 时,背景覆盖整个引用。点击已知 skill 会在右侧栏打开提供方给出的 `SKILL.md` 路径,同时保留文本的可编辑性。缓存未就绪时,点击复用该 Session 的目录请求,在完成后按点击时的 Session 地址打开预览。切换预设、重置连接和插件释放会取消待处理的预览;后续点击重新获取当前目录。没有文件路径的 skill 仍可调用,但没有文件预览。
37
39
 
38
40
  -----
39
41
 
@@ -51,7 +53,7 @@ source 不实现任何裁决钩子,也没有引用 codec:pick 落下字面
51
53
 
52
54
  ### 注册
53
55
 
54
- `/client` 导出接口只有插件主体(`apply`/`inject`);source 对象是注册 effect 的内部实现。工具行把 `skill` wire 名称注册进 ui-tool 的 keyed `tool.call.toolview` slot。
56
+ `/client` 导出接口只有插件主体(`apply`/`inject`);source 对象是注册 effect 的内部实现。工具行把 `skill` wire 名称注册进 ui-tool 的 keyed `tool.call.toolview` slot。
55
57
 
56
58
  </details>
57
59
 
@@ -107,4 +109,4 @@ source 不实现任何裁决钩子,也没有引用 codec:pick 落下字面
107
109
 
108
110
  </details>
109
111
 
110
- **运行时不变式:** 不发布伴生入口。slash source、locale dictionary 与 keyed toolview 都由 registry 持有,HMR 测试覆盖释放;它们不发出 Cordis 事件或持有跨插件可变状态。
112
+ **运行时不变式:** 不发布伴生入口。slash source、locale dictionary 与 keyed toolview 都是由注册表持有的注册项,其释放行为已由 HMR(热模块替换)安全规范证明;它们不发出 Cordis 事件或持有跨插件可变状态。
package/lib/client.js CHANGED
@@ -7,6 +7,64 @@ window.__ModuleLoader__.load({
7
7
  let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
8
8
  let react_jsx_runtime = require("react/jsx-runtime");
9
9
  let react = require("react");
10
+ //#region ../../util/workspace-path/src/file-address.ts
11
+ /** The scheme and type every file address opens with. */
12
+ const FILE_ADDRESS_PREFIX = "dsh-resource://file/";
13
+ /** Component-encode one id or path segment, keeping `:` literal for drive letters. */
14
+ function encodeSegment(segment) {
15
+ return encodeURIComponent(segment).replace(/%3A/gi, ":");
16
+ }
17
+ /** Encode a `/`-separated path segment by segment. */
18
+ function encodePath(path) {
19
+ return path.split("/").map(encodeSegment).join("/");
20
+ }
21
+ /**
22
+ * Build the address of a file read through one Session.
23
+ * @param sessionId - the Session whose Host workspace resolves the path.
24
+ * @param path - absolute or workspace-relative path; backslashes are normalized to `/`, and leading `./` prefixes are dropped.
25
+ * @returns the `dsh-resource://file/session/<sessionId>/<path>` address.
26
+ */
27
+ function sessionFileAddress(sessionId, path) {
28
+ const normalized = path.replace(/\\/g, "/").replace(/^(?:\.\/)+/, "");
29
+ return `${FILE_ADDRESS_PREFIX}session/${encodeSegment(sessionId)}/${encodePath(normalized)}`;
30
+ }
31
+ //#endregion
32
+ //#region ../../util/workspace-path/src/index.ts
33
+ /**
34
+ * Browser-safe Workspace path and display helpers.
35
+ * @module @deepseek-ai/dsh-util-workspace-path
36
+ */
37
+ /** Whether a path uses a Windows drive or UNC prefix. */
38
+ function isWindowsStylePath(value) {
39
+ return /^[A-Za-z]:[/\\]/.test(value) || value.startsWith("\\\\");
40
+ }
41
+ /**
42
+ * Whether a path is absolute in either spelling the Host accepts: POSIX (`/a/b`) or Windows drive or UNC.
43
+ * @param path - the path to classify.
44
+ * @returns `true` for an absolute path; `false` for a Workspace-relative one.
45
+ */
46
+ function isAbsoluteWorkspacePath(path) {
47
+ return path.startsWith("/") || isWindowsStylePath(path);
48
+ }
49
+ /**
50
+ * The address for a path as a caller holds it: a relative path, or an absolute
51
+ * path inside the Session's workspace, becomes a `session`-scoped address; an
52
+ * absolute path outside it, or one whose workspace root is unknown, keeps its
53
+ * absolute path in that Session's address.
54
+ * @param sessionId - the Session the path is read in.
55
+ * @param cwd - that Session's workspace root, when known.
56
+ * @param path - absolute or workspace-relative path, in either separator spelling.
57
+ * @returns the `dsh-resource://file/…` address.
58
+ */
59
+ function fileAddressFor(sessionId, cwd, path) {
60
+ const normalized = path.replace(/\\/g, "/");
61
+ if (!isAbsoluteWorkspacePath(normalized)) return sessionFileAddress(sessionId, normalized);
62
+ const root = cwd === void 0 ? "" : cwd.replace(/\\/g, "/").replace(/\/+$/, "");
63
+ if (root !== "" && normalized === root) return sessionFileAddress(sessionId, "");
64
+ if (root !== "" && normalized.startsWith(`${root}/`)) return sessionFileAddress(sessionId, normalized.slice(root.length + 1));
65
+ return sessionFileAddress(sessionId, normalized);
66
+ }
67
+ //#endregion
10
68
  //#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-skill/src/client/SkillRow.module.css.mjs
11
69
  const css = ".iWrAna_card{flex-direction:column;display:flex}.iWrAna_row{align-items:center;min-width:0;height:24px;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:16px;height:16px;color:var(--dsw-alias-label-tertiary);flex:none;justify-content:center;align-items:center;margin-right:6px;display:inline-flex;position:relative}.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{color:var(--dsw-alias-label-secondary);flex:none;font-size:14px;line-height:24px}.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;color:var(--dsw-alias-label-tertiary);flex:auto;font-size:14px;line-height:24px;overflow:hidden}.iWrAna_errorSummary{color:var(--dsw-alias-state-error-primary)}.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}}";
12
70
  const tagId = "@deepseek-ai/dsh-client-ui-skill/SkillRow.module.css";
@@ -217,7 +275,8 @@ window.__ModuleLoader__.load({
217
275
  "slots",
218
276
  "locale",
219
277
  "remote",
220
- "remote.skills"
278
+ "remote.skills",
279
+ "sidebarRight"
221
280
  ];
222
281
  /**
223
282
  * Client plugin body: register the '/' source, dictionaries, and keyed tool row.
@@ -245,12 +304,12 @@ window.__ModuleLoader__.load({
245
304
  }
246
305
  };
247
306
  const fetchCatalog = (sessionId) => {
248
- if (sessions.subagentAddress(sessionId) !== void 0) return Promise.resolve([]);
249
307
  const existing = fetches.get(sessionId);
250
- if (existing !== void 0) return existing.promise;
308
+ if (existing !== void 0) return existing;
251
309
  const abort = new AbortController();
252
310
  const promise = (async () => {
253
311
  const result = await skills.list({ sessionId }, abort.signal);
312
+ abort.signal.throwIfAborted();
254
313
  if (!result.ok) throw new Error(`skills/list failed: ${result.error.code}: ${result.error.message}`);
255
314
  return result.value.skills;
256
315
  })();
@@ -265,7 +324,7 @@ window.__ModuleLoader__.load({
265
324
  }, () => {
266
325
  if (fetches.get(sessionId) === entry) fetches.delete(sessionId);
267
326
  });
268
- return promise;
327
+ return entry;
269
328
  };
270
329
  const invalidate = (key) => {
271
330
  const entry = fetches.get(key);
@@ -283,7 +342,8 @@ window.__ModuleLoader__.load({
283
342
  name: "skill",
284
343
  order: 2,
285
344
  async candidates(session, { query, signal }) {
286
- const skills = await fetchCatalog(session.sessionId);
345
+ if (sessions.subagentAddress(session.sessionId) !== void 0) return [];
346
+ const skills = await fetchCatalog(session.sessionId).promise;
287
347
  if (signal.aborted) return [];
288
348
  return (0, _deepseek_ai_dsh_client_ui_primitives.rankByName)(skills, query).map((skill) => ({
289
349
  name: skill.name,
@@ -291,7 +351,8 @@ window.__ModuleLoader__.load({
291
351
  }));
292
352
  },
293
353
  warm(session) {
294
- fetchCatalog(session.sessionId).catch(() => {});
354
+ if (sessions.subagentAddress(session.sessionId) !== void 0) return;
355
+ fetchCatalog(session.sessionId).promise.catch(() => {});
295
356
  },
296
357
  lexicon(session) {
297
358
  return fetches.get(session.sessionId)?.settled?.map((skill) => skill.name);
@@ -306,6 +367,25 @@ window.__ModuleLoader__.load({
306
367
  if (listeners.size === 0) lexiconListeners.delete(key);
307
368
  };
308
369
  },
370
+ openReference(session, { ref }) {
371
+ if (sessions.subagentAddress(session.sessionId) !== void 0) return false;
372
+ const cwd = sessions.list.getSnapshot().byId[session.sessionId]?.cwd;
373
+ const open = (catalog) => {
374
+ const path = catalog.find((skill) => `/${skill.name}` === ref)?.path;
375
+ if (path === void 0) return false;
376
+ ctx.sidebarRight.openResource(fileAddressFor(session.sessionId, cwd, path));
377
+ return true;
378
+ };
379
+ const settled = fetches.get(session.sessionId)?.settled;
380
+ if (settled !== void 0) return open(settled);
381
+ const entry = fetchCatalog(session.sessionId);
382
+ entry.promise.then((catalog) => {
383
+ if (!entry.abort.signal.aborted) open(catalog);
384
+ }).catch((error) => {
385
+ if (!entry.abort.signal.aborted) console.error("[ui-skill] reference preview failed:", error);
386
+ });
387
+ return true;
388
+ },
309
389
  onPick({ candidate }) {
310
390
  return { text: `/${candidate.name} ` };
311
391
  }
@@ -1,34 +1,3 @@
1
- /**
2
- * Skill reference plugin, browser half: registers the '/' skill source —
3
- * candidates from the `skills/list` Remote addressed by the per-call session
4
- * projection's sessionId (sessions are always agent-backed; the host
5
- * resolves cwd from the session header). A pick lands the literal `/name `
6
- * text and the prompt ships the same literal (plain-text-reference decision;
7
- * see .agents/notes/archived/architecture/2026-07-25-web-input-machine-and-slash-pipeline.md);
8
- * determinism
9
- * lives host-side — the pre-step boundary (`dsh-tool-skill`) recognizes a
10
- * leading `/name` naming a user-invocable skill and injects the rendered
11
- * body for every entry point, including `disable-model-invocation` skills the
12
- * model-side catalog never lists (issue #1470). The RPC rides the plugin's
13
- * root-context Remote captured at registration — the source never reads
14
- * services off a per-call argument. Draft chip visuals derive from
15
- * the lexicon scan; this source implements no reference codec.
16
- *
17
- * Catalog fetches are cached per session (the small twin of the ui-commands
18
- * directory): the per-keystroke candidates re-poll filters a settled
19
- * snapshot locally, so one session costs one RPC. The scope-birth warm hook
20
- * prewarms the session's key; a preset switch drops that one key (the
21
- * catalog is the preset's, and a blank session may switch after the warm);
22
- * connection/reset clears everything — the host
23
- * catalog may differ across generations. A shared in-flight fetch
24
- * deliberately outlives any single menu interaction: closing the menu must
25
- * not kill the prewarm other consumers will hit, so it carries its own
26
- * abort (fired only on invalidation/teardown) while a candidates caller
27
- * with an aborted signal just returns early.
28
- *
29
- * This browser half also owns the `skill` keyed toolview: a replay-stable
30
- * accent row derived only from each logged call/result slice.
31
- */
32
1
  import type { Context as ClientContext } from '@deepseek-ai/cordis';
33
2
  import { type SkillKey } from './locales.ts';
34
3
  declare module '@deepseek-ai/dsh-client-ui-slots' {
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.5-rc.2",
4
+ "version": "0.1.6-alpha.1",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -33,7 +33,8 @@
33
33
  "@deepseek-ai/dsh-client-ui-renderer",
34
34
  "@deepseek-ai/dsh-client-ui-tool",
35
35
  "@deepseek-ai/dsh-client-ui-input-trigger",
36
- "@deepseek-ai/dsh-api-remotes"
36
+ "@deepseek-ai/dsh-api-remotes",
37
+ "@deepseek-ai/dsh-client-ui-sidebar-right"
37
38
  ],
38
39
  "platform": "web"
39
40
  }
@@ -47,18 +48,20 @@
47
48
  "@types/react": "~18.3.1",
48
49
  "react": "^18.2.0",
49
50
  "react-dom": "^18.2.0",
50
- "@deepseek-ai/dsh-api-remotes": "^0.1.5-rc.2",
51
- "@deepseek-ai/dsh-api-session-controller": "^0.1.5-rc.2",
52
- "@deepseek-ai/dsh-client-connection": "^0.1.5-rc.2",
53
- "@deepseek-ai/dsh-client-locale": "^0.1.5-rc.2",
54
- "@deepseek-ai/dsh-client-test-runtime": "^0.1.5-rc.2",
55
- "@deepseek-ai/dsh-client-ui-primitives": "^0.1.5-rc.2",
56
- "@deepseek-ai/dsh-client-ui-renderer": "^0.1.5-rc.2",
57
- "@deepseek-ai/dsh-client-ui-input-trigger": "^0.1.5-rc.2",
58
- "@deepseek-ai/dsh-client-ui-slots": "^0.1.5-rc.2",
59
- "@deepseek-ai/dsh-client-ui-tool": "^0.1.5-rc.2",
60
- "@deepseek-ai/dsh-session": "^0.1.5-rc.2",
61
- "@deepseek-ai/cordis": "^4.0.2"
51
+ "@deepseek-ai/dsh-api-remotes": "^0.1.6-alpha.1",
52
+ "@deepseek-ai/dsh-api-session-controller": "^0.1.6-alpha.1",
53
+ "@deepseek-ai/dsh-client-connection": "^0.1.6-alpha.1",
54
+ "@deepseek-ai/dsh-client-locale": "^0.1.6-alpha.1",
55
+ "@deepseek-ai/dsh-client-test-runtime": "^0.1.6-alpha.1",
56
+ "@deepseek-ai/dsh-client-ui-primitives": "^0.1.6-alpha.1",
57
+ "@deepseek-ai/dsh-client-ui-renderer": "^0.1.6-alpha.1",
58
+ "@deepseek-ai/dsh-client-ui-tool": "^0.1.6-alpha.1",
59
+ "@deepseek-ai/dsh-client-ui-input-trigger": "^0.1.6-alpha.1",
60
+ "@deepseek-ai/dsh-session": "^0.1.6-alpha.1",
61
+ "@deepseek-ai/dsh-client-ui-slots": "^0.1.6-alpha.1",
62
+ "@deepseek-ai/cordis": "^4.0.2",
63
+ "@deepseek-ai/dsh-client-ui-sidebar-right": "^0.1.6-alpha.1",
64
+ "@deepseek-ai/dsh-util-workspace-path": "^0.1.6-alpha.1"
62
65
  },
63
66
  "files": [
64
67
  "lib/index.js",