@deepseek-ai/dsh-client-ui-skill 0.1.1-rc.2 → 0.1.2-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 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: f2e2ec8a3061f2cd8617123013d63fad63abf237
6
- README.zh.md: 4d147f3795306edbc1e5ea38a7abc0b8d4081f63
5
+ README.md: de564bd533f6cec83bb0a55e6ebfa687fa716ee9
6
+ README.zh.md: 2408a29b83befd68785f7e7feccc588b6372a6fb
package/README.md CHANGED
@@ -1,19 +1,75 @@
1
+ ---
2
+ description: "Web skill references and the dedicated skill tool row for the dsh web client: the /-triggered skill source and the skill call card."
3
+ kind: "package-reference"
4
+ ---
5
+
1
6
  # @deepseek-ai/dsh-client-ui-skill
2
7
 
3
8
  English | [中文](README.zh.md)
4
9
 
5
- Skill invocation source, browser half: registers the `/`-trigger `skill` source into `ctx.inputTriggers`. Ordinary-session candidates come from the `skill.list` RPC addressed by the per-call `ClientSessionContext` projection's `{sessionId}`, with the host resolving `cwd` from the session header. The host serves every user-invocable skill; a `modelInvocable: false` entry (a `disable-model-invocation` skill, whose only entry point is this path) wears the user-only marker as a description prefix in the active language. 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. 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. Results filter by `startsWith(query)`.
10
+ ## Summary
11
+
12
+ `dsh-client-ui-skill` lets users invoke skills by typing `/name` in the composer: the suggestion menu offers user-invocable skills from the `skills/list` Remote, and a pick lands the literal `/name ` text that the host then loads as the skill's instructions. Loading is deterministic: the host's pre-step boundary (`dsh-tool-skill`) recognizes the whitespace-bounded `/name` token in the sent message and injects the rendered `<skill_content>` for every entry point, so a menu pick, a hand-typed token, and a TUI/ACP prompt all load the skill the same way. Settled skill calls render in the conversation as an expandable `Instructions` card, derived only from the frozen call/result slice.
13
+
14
+ ## Table of Contents
15
+
16
+ - [Use this package](#use-this-package)
17
+ - [Understand the implementation](#understand-the-implementation)
18
+ - [Further Exploration](#further-exploration)
19
+ - [Model Experience](#model-experience)
20
+ - [Known Limitations and Deferred Work](#known-limitations-and-deferred-work)
21
+ - [Dev Note](#dev-note)
22
+
23
+ -----
24
+
25
+ <a id="use-this-package"></a>
26
+ ## Use this package
27
+
28
+ Type `/` in the composer and pick a skill from the suggestions, or type `/name` directly; the sent message carries the literal text, and the host loads the skill the same way for a menu pick or a hand-typed token. A name shared with a host command still resolves to the command — adjudication claims the line client-side before it ever becomes a prompt.
29
+
30
+ ### What the source offers
31
+
32
+ Ordinary-session candidates come from the `skills/list` Remote; the host serves every user-invocable skill, and a `modelInvocable: false` entry (a `disable-model-invocation` skill, whose only entry point is this path) wears the user-only marker as a description prefix in the active language. Results filter by `startsWith(query)`. A failed `skills/list` call is logged and folded into a silent menu-group drop — the menu shows only pending/ready states.
33
+
34
+ ### The skill tool row
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, 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
+
38
+ -----
39
+
40
+ <a id="understand-the-implementation"></a>
41
+ ## Understand the implementation
42
+
43
+ <details>
44
+ <summary>Implementation internals — click to expand</summary>
6
45
 
7
- A pick lands the literal `/name ` text and the prompt ships the same literal ([slash-pipeline Agent Note](../../../.agents/notes/implemented/architecture/2026-07-25-web-input-machine-and-slash-pipeline.md)) — this source implements no adjudication hooks and no reference codec. Determinism lives host-side: the pre-step gesture boundary (`dsh-tool-skill`) recognizes whitespace-bounded `/name` tokens naming user-invocable skills anywhere in a user message and injects the rendered `<skill_content>` for every entry point, so a menu pick, a hand-typed token, and a TUI/ACP prompt all load the skill the same way. A name shared with a host command still resolves to the command: adjudication claims the line client-side before it ever becomes a prompt — deliberate precedence, matching peer products. The list RPC rides the plugin's root-context connection captured at registration — the source never reads services off a per-call argument; draft chip visuals derive from the `lexicon` scan.
46
+ The source implements no adjudication hooks and no reference codec: the pick lands literal text and the prompt ships the same literal, so determinism lives host-side ([slash pipeline note](../../../.agents/notes/implemented/architecture/2026-07-25-web-input-machine-and-slash-pipeline.md)).
8
47
 
9
- A failed `skill.list` throws from `candidates`, which the slash shell logs and folds into a silent menu-group drop — the menu shows only pending/ready states.
48
+ ### Candidate flow
10
49
 
11
- The `/client` exports are the plugin body (`apply`/`inject`) only; the source object is internal to the registration effect.
50
+ 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.
12
51
 
13
- ## Skill tool row
52
+ ### Registration
14
53
 
15
- The browser plugin also registers the `skill` wire name in `ui-tool`'s keyed `tool.call.toolview` slot. A collapsed row renders the 14-pixel skill document-and-sparkle glyph, `Skill` title, separator, and requested skill name with the same neutral hierarchy as the Bash row; 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 as one whole-row disclosure 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 remains stable when installed skills or their descriptions change.
54
+ 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.
16
55
 
56
+ </details>
57
+
58
+ -----
59
+
60
+ <a id="further-exploration"></a>
61
+ ## Further Exploration
62
+
63
+ These pages cover the input machinery, the tool row host, and the host-side skill tool.
64
+
65
+ - [ui-input-trigger](../ui-input-trigger/README.md) — the inline suggestion machinery the source registers into.
66
+ - [ui-tool](../ui-tool/README.md) — the tool-call presentation layer hosting the `tool.call.toolview` slot.
67
+ - [tool-skill](../../skill/tool-skill/README.md) — the host-side `skill` tool owning the pre-step gesture boundary.
68
+ - [Web input machine and slash pipeline](../../../.agents/notes/implemented/architecture/2026-07-25-web-input-machine-and-slash-pipeline.md) — how references and commands share the input machine.
69
+
70
+ -----
71
+
72
+ <a id="model-experience"></a>
17
73
  ## Model Experience
18
74
 
19
75
  ### User-explicit skill invocation
@@ -32,6 +88,21 @@ Append-only: the injected message lands after the reusable history prefix. This
32
88
 
33
89
  ## Known Limitations and Deferred Work
34
90
 
91
+ <a id="known-limitations-and-deferred-work"></a>
92
+
93
+
94
+ These limits define where the reference and the row fall back to generic behavior; they are current package constraints.
95
+
35
96
  - **Result-only history pages use the generic row** — keyed dispatch needs the paired call in the runtime window; pagination that leaves the call outside has no tool identity. This client presentation feature does not extend the history wire contract to recover it.
36
- - **Text is the truth** — the reference is plain draft text; a hand-typed identical token is the same reference, and the host gesture boundary judges the sent text, not the menu interaction. Chip visuals derive from the lexicon scan; no occurrence identity, position tracking, or structured reference payload on the prompt wire (both are ledger items).
97
+ - **Text is the truth** — the reference is plain draft text; a hand-typed identical token is the same reference, and the host gesture boundary judges the sent text, not the menu interaction. Chip visuals derive from the lexicon scan; no occurrence identity, position tracking, or structured reference payload exists on the prompt wire.
37
98
  - **A menu opened before the prewarm settles** shows no skill candidates for that keystroke; the next keystroke re-polls the settled cache.
99
+
100
+ <a id="dev-note"></a>
101
+ ### Dev Note
102
+
103
+ <details>
104
+ <summary>Working context for maintainers — click to expand</summary>
105
+
106
+ None.
107
+
108
+ </details>
package/README.zh.md CHANGED
@@ -1,19 +1,75 @@
1
+ ---
2
+ description: "dsh Web 客户端的 skill 引用与专属 skill 工具行:/ 触发的 skill source 与 skill 调用卡片。"
3
+ kind: "package-reference"
4
+ ---
5
+
1
6
  # @deepseek-ai/dsh-client-ui-skill
2
7
 
3
8
  [English](README.md) | 中文
4
9
 
5
- skill(技能)调用 source 的浏览器端:把 `/` 触发的 `skill` source 注册进 `ctx.inputTriggers`。普通会话的候选来自 `skill.list` RPC,以每次调用的 `ClientSessionContext` 投影中的 `{sessionId}` 寻址,host 从会话 header 解析 `cwd`。宿主提供每一个用户可调用的 skill;`modelInvocable: false` 的条目(即 `disable-model-invocation` skill,此路径是其唯一入口)会以当前语言把仅限用户标记作为描述前缀带上。由目录寻址的可继续 subagent 在客户端解析为没有 skill 候选,因为现有 skill RPC 要求会话已挂载;查看其持久化历史不得激活它。目录按普通会话缓存,拉取走 single-flight;scope 创建时的 `warm` 钩子预热该会话的缓存项,转发的 owner 事件 `agent-preset/selected` 丢弃该会话这一项(目录属于 preset,而空会话可能在预热之后才切换),`connection/reset` 清空全部缓存。结果按 `startsWith(query)` 过滤。
10
+ ## 概述
11
+
12
+ `dsh-client-ui-skill` 让用户通过在编辑器中键入 `/name` 来调用 skill:建议菜单从 `skills/list` Remote 提供用户可调用的 skill 候选,选择一项会落下字面文本 `/name `,宿主随后将其加载为 skill 的指令。加载是确定性的:宿主的 pre-step 边界(`dsh-tool-skill`)识别发出消息中以空白为界的 `/name` token,并为每个入口注入渲染后的 `<skill_content>`,因此菜单 pick、手动键入的 token 与 TUI/ACP 提示词都以同一种方式加载 skill。已结算的 skill 调用在对话中渲染为可展开的 `Instructions` 卡片,只从冻结的调用/结果切片派生。
13
+
14
+ ## 目录
15
+
16
+ - [使用本包](#use-this-package)
17
+ - [理解实现](#understand-the-implementation)
18
+ - [进一步探索](#further-exploration)
19
+ - [模型体验](#model-experience)
20
+ - [已知限制与延期工作](#known-limitations-and-deferred-work)
21
+ - [开发备注](#dev-note)
22
+
23
+ -----
24
+
25
+ <a id="use-this-package"></a>
26
+ ## 使用本包
27
+
28
+ 在编辑器中输入 `/` 并从建议中选择 skill,或直接键入 `/name`;发出的消息携带字面文本,宿主对菜单 pick 与手动键入的 token 以同样方式加载 skill。与宿主命令同名的名称仍解析为命令——裁决在客户端把该行认领走,它根本不会成为提示词。
29
+
30
+ ### source 提供什么
31
+
32
+ 普通会话的候选来自 `skills/list` Remote;宿主提供每一个用户可调用的 skill,`modelInvocable: false` 的条目(即 `disable-model-invocation` skill,此路径是其唯一入口)会以当前语言把仅限用户标记作为描述前缀带上。结果按 `startsWith(query)` 过滤。`skills/list` 调用失败时会被记录并静默丢弃该菜单组——菜单只显示 pending/ready 状态。
33
+
34
+ ### skill 工具行
35
+
36
+ 收起的行显示 skill 图标、`Skill` 标题与请求加载的 skill 名称;运行中的调用带有 transcript 的扫光效果,失败时用错误首行替换名称,中断的调用使用警告状态。已结算的行展开为一个尺寸受限的 `Instructions` 卡片,其中原样呈现持久化的工具输出;可用时还会提供标准轨迹的 `Inspect` 入口。该行的名称、生命周期与正文只派生自 ui-tool 提供的冻结调用/结果切片,绝不读取当前目录,因此即使已安装的 skill 或其描述发生变化,回放仍保持稳定。
37
+
38
+ -----
39
+
40
+ <a id="understand-the-implementation"></a>
41
+ ## 理解实现
42
+
43
+ <details>
44
+ <summary>实现细节——点击展开</summary>
6
45
 
7
- pick 会落下字面文本 `/name `,发出的提示词中也是同一段字面文本([slash 流水线 Agent Note](../../../.agents/notes/implemented/architecture/2026-07-25-web-input-machine-and-slash-pipeline.zh.md))——本 source 不实现任何裁决钩子,也没有引用 codec。确定性在宿主侧:pre-step 手势边界(`dsh-tool-skill`)识别用户消息中任意位置、以空白为界、指名用户可调用 skill 的 `/name` token,并为每个入口注入渲染后的 `<skill_content>`,因此菜单 pick、手动键入的 token 与 TUI/ACP(Agent Client Protocol)提示词都以同一种方式加载 skill。与宿主命令同名的名称仍解析为命令:裁决在客户端把该行认领走,它根本不会成为提示词——这是有意的优先级,与同类产品一致。列表 RPC 使用插件注册时捕获的根上下文连接——source 绝不从每次调用的参数上读取服务;草稿 chip 视觉由 `lexicon` 扫描派生。
46
+ source 不实现任何裁决钩子,也没有引用 codec:pick 落下字面文本,发出的提示词中也是同一段字面文本,因此确定性在宿主侧([slash 流水线笔记](../../../.agents/notes/implemented/architecture/2026-07-25-web-input-machine-and-slash-pipeline.zh.md))。
8
47
 
9
- `skill.list` 失败时 `candidates` 抛出异常,slash 壳层记录日志,并静默丢弃该菜单组——菜单只显示 pending/ready 状态。
48
+ ### 候选流程
10
49
 
11
- `/client` 导出接口只有插件主体(`apply`/`inject`);source 对象是注册 effect 的内部实现。
50
+ 目录按普通会话缓存,拉取走 single-flight;scope 创建时的 `warm` 钩子预热该会话的缓存项,转发的 owner 事件 `agent-preset/selected` 丢弃该会话这一项(目录属于 preset,而空会话可能在预热之后才切换),`connection/reset` 清空全部缓存。由目录寻址的可继续 subagent 在客户端解析为没有 skill 候选,因为现有 skill RPC 要求会话已挂载;查看其持久化历史不得激活它。列表 RPC 使用插件注册时捕获的根上下文连接;草稿 chip 视觉由 `lexicon` 扫描派生。
12
51
 
13
- ## skill 工具行
52
+ ### 注册
14
53
 
15
- 浏览器插件还会把 `skill` wire 名称注册进 `ui-tool` 的 keyed `tool.call.toolview` slot。收起的行以与 Bash 行相同的中性视觉层级显示 14 像素的 skill 文档与闪光组合图标、`Skill` 标题、分隔符和请求加载的 skill 名称;运行中的工具调用带有 transcript(文本记录)的扫光效果,失败时用错误首行替换名称,中断的工具调用则使用警告状态。已结算的行以整行作为展开入口,展开后显示一个尺寸受限的 `Instructions` 卡片,其中原样呈现持久化的工具输出;可用时还会提供标准执行轨迹的 `Inspect` 入口。该行的名称、生命周期和正文只派生自 `ui-tool` 提供的冻结的工具调用/工具结果切片,绝不读取当前 skill 目录,因此即使已安装的 skill 或其描述发生变化,回放仍保持稳定。
54
+ `/client` 导出接口只有插件主体(`apply`/`inject`);source 对象是注册 effect 的内部实现。工具行把 `skill` wire 名称注册进 ui-tool 的 keyed `tool.call.toolview` slot
16
55
 
56
+ </details>
57
+
58
+ -----
59
+
60
+ <a id="further-exploration"></a>
61
+ ## 进一步探索
62
+
63
+ 以下页面覆盖输入机制、工具行宿主与宿主侧 skill 工具。
64
+
65
+ - [ui-input-trigger](../ui-input-trigger/README.zh.md)——该 source 注册进的行内建议机制。
66
+ - [ui-tool](../ui-tool/README.zh.md)——承载 `tool.call.toolview` slot 的工具调用展示层。
67
+ - [tool-skill](../../skill/tool-skill/README.zh.md)——拥有 pre-step 手势边界的宿主侧 `skill` 工具。
68
+ - [Web 输入机器与 slash 流水线](../../../.agents/notes/implemented/architecture/2026-07-25-web-input-machine-and-slash-pipeline.zh.md)——引用与命令如何共享输入机器。
69
+
70
+ -----
71
+
72
+ <a id="model-experience"></a>
17
73
  ## 模型体验
18
74
 
19
75
  ### 用户显式 skill 调用
@@ -30,8 +86,23 @@ pick 会落下字面文本 `/name `,发出的提示词中也是同一段字面
30
86
 
31
87
  仅追加:注入的消息落在可复用历史前缀之后。该包绝不改写较早的请求 token。
32
88
 
33
- ## 已知限制与暂缓事项
89
+ ## 已知限制与延期工作
90
+
91
+ <a id="known-limitations-and-deferred-work"></a>
92
+
93
+
94
+ 这些限制定义引用与工具行何时回退到通用行为;它们是当前包约束。
34
95
 
35
96
  - **仅含工具结果的 history 页使用通用行**:键控分派要求配对的工具调用位于运行时窗口内;分页将工具调用留在窗口外时,工具结果没有工具身份。这项客户端呈现功能不会为了恢复该身份而扩展 history 协议约定。
36
- - **文本是唯一依据**:引用是普通的草稿文本;手动键入的相同 token 就是同一个引用,宿主手势边界评判的是发出的文本,而不是菜单交互。chip 视觉由 lexicon 扫描派生;没有 occurrence 身份、位置跟踪,也没有提示词协议上的结构化引用载荷(两者都是台账事项)。
97
+ - **文本是唯一依据**:引用是普通的草稿文本;手动键入的相同 token 就是同一个引用,宿主手势边界评判的是发出的文本,而不是菜单交互。chip 视觉由 lexicon 扫描派生;提示词协议上没有 occurrence 身份、位置跟踪或结构化引用载荷。
37
98
  - **预热落定之前打开的菜单**:在那次击键下不显示 skill 候选;下一次击键会重新轮询已落定的缓存。
99
+
100
+ <a id="dev-note"></a>
101
+ ### 开发备注
102
+
103
+ <details>
104
+ <summary>维护者的工作上下文——点击展开</summary>
105
+
106
+ 无。
107
+
108
+ </details>
package/lib/client.js CHANGED
@@ -150,7 +150,7 @@ window.__ModuleLoader__.load({
150
150
  }) : null,
151
151
  (0, react_jsx_runtime.jsx)("span", {
152
152
  className: SkillRow_module_css_default.title,
153
- children: "Skill"
153
+ children: t("row.title")
154
154
  }),
155
155
  (0, react_jsx_runtime.jsx)("span", {
156
156
  className: SkillRow_module_css_default.separator,
@@ -178,7 +178,7 @@ window.__ModuleLoader__.load({
178
178
  type: "button",
179
179
  className: SkillRow_module_css_default.inspectButton,
180
180
  onClick: inspect,
181
- children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconInspectOutline12, {}), "Inspect"]
181
+ children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconInspectOutline12, {}), t("row.inspect")]
182
182
  }) : null]
183
183
  }) : null]
184
184
  });
@@ -190,18 +190,22 @@ window.__ModuleLoader__.load({
190
190
  const NS = "skill";
191
191
  /** Simplified Chinese dictionary (the key-set source of truth). */
192
192
  const zh = {
193
+ "row.title": "Skill",
193
194
  "row.running": "正在加载 skill",
194
195
  "row.failed": "skill 加载失败",
195
196
  "row.stopped": "skill 加载已中止",
196
197
  "row.instructions": "说明",
198
+ "row.inspect": "查看",
197
199
  "menu.userOnly": "仅用户"
198
200
  };
199
201
  /** English dictionary, checked complete against the zh key set. */
200
202
  const en = {
203
+ "row.title": "Skill",
201
204
  "row.running": "Loading skill",
202
205
  "row.failed": "Skill load failed",
203
206
  "row.stopped": "Skill load stopped",
204
207
  "row.instructions": "Instructions",
208
+ "row.inspect": "Inspect",
205
209
  "menu.userOnly": "user-only"
206
210
  };
207
211
  //#endregion
@@ -209,11 +213,11 @@ window.__ModuleLoader__.load({
209
213
  /** Required services: reference source faces plus the tool-row and locale registries. */
210
214
  const inject = [
211
215
  "inputTriggers",
212
- "connection",
213
216
  "sessions",
214
217
  "slots",
215
218
  "locale",
216
- "remote"
219
+ "remote",
220
+ "remote.skills"
217
221
  ];
218
222
  /**
219
223
  * Client plugin body: register the '/' source, dictionaries, and keyed tool row.
@@ -229,8 +233,8 @@ window.__ModuleLoader__.load({
229
233
  key: "skill",
230
234
  locale: NS
231
235
  }, SkillRow));
232
- const skills = ctx.get("connection").api.skills;
233
- const sessions = ctx.get("sessions");
236
+ const skills = ctx.remote.skills;
237
+ const sessions = ctx.sessions;
234
238
  const fetches = /* @__PURE__ */ new Map();
235
239
  const lexiconListeners = /* @__PURE__ */ new Map();
236
240
  const notifyLexicon = (sessionId) => {
@@ -246,8 +250,8 @@ window.__ModuleLoader__.load({
246
250
  if (existing !== void 0) return existing.promise;
247
251
  const abort = new AbortController();
248
252
  const promise = (async () => {
249
- const { result } = await skills.list({ sessionId }, abort.signal);
250
- if (!result.ok) throw new Error(`skill.list failed: ${result.error.code}: ${result.error.message}`);
253
+ const result = await skills.list({ sessionId }, abort.signal);
254
+ if (!result.ok) throw new Error(`skills/list failed: ${result.error.code}: ${result.error.message}`);
251
255
  return result.value.skills;
252
256
  })();
253
257
  const entry = {
@@ -1,6 +1,5 @@
1
1
  import type { ToolCallViewProps } from '@deepseek-ai/dsh-client-ui-tool/client';
2
2
  import type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots';
3
- /** Full row props: the toolview runtime share plus this package's locale seat. */
4
3
  type SkillRowProps = ToolCallViewProps & PropsLocale<'skill'>;
5
4
  /**
6
5
  * Render one `skill` tool call as an accent summary and instructions disclosure.
@@ -1,4 +1,35 @@
1
- import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client';
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/implemented/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
+ import type { Context as ClientContext } from '@deepseek-ai/cordis';
2
33
  import { type SkillKey } from './locales.ts';
3
34
  declare module '@deepseek-ai/dsh-client-ui-slots' {
4
35
  interface LocaleNamespaceMap {
@@ -3,20 +3,24 @@
3
3
  export declare const NS = "skill";
4
4
  /** Simplified Chinese dictionary (the key-set source of truth). */
5
5
  export declare const zh: {
6
+ 'row.title': string;
6
7
  'row.running': string;
7
8
  'row.failed': string;
8
9
  'row.stopped': string;
9
10
  'row.instructions': string;
11
+ 'row.inspect': string;
10
12
  'menu.userOnly': string;
11
13
  };
12
14
  /** The skill namespace key union. */
13
15
  export type SkillKey = keyof typeof zh;
14
16
  /** English dictionary, checked complete against the zh key set. */
15
17
  export declare const en: {
18
+ 'row.title': string;
16
19
  'row.running': string;
17
20
  'row.failed': string;
18
21
  'row.stopped': string;
19
22
  'row.instructions': string;
23
+ 'row.inspect': string;
20
24
  'menu.userOnly': string;
21
25
  };
22
26
  //# sourceMappingURL=locales.d.ts.map
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.1-rc.2",
4
+ "version": "0.1.2-alpha.2",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -32,8 +32,9 @@
32
32
  "dsh": {
33
33
  "client": {
34
34
  "inject": [
35
- "@deepseek-ai/dsh-client-runtime",
35
+ "@deepseek-ai/dsh-api-session-controller",
36
36
  "@deepseek-ai/dsh-client-locale",
37
+ "@deepseek-ai/dsh-client-ui-renderer",
37
38
  "@deepseek-ai/dsh-client-ui-tool",
38
39
  "@deepseek-ai/dsh-client-ui-input-trigger",
39
40
  "@deepseek-ai/dsh-api-remotes"
@@ -43,31 +44,26 @@
43
44
  },
44
45
  "license": "MIT",
45
46
  "peerDependencies": {
46
- "@deepseek-ai/dsh-api-remotes": "^0.1.1-rc.2",
47
- "@deepseek-ai/dsh-client-connection": "^0.1.1-rc.2",
48
- "@deepseek-ai/dsh-client-locale": "^0.1.1-rc.2",
49
- "@deepseek-ai/dsh-client-runtime": "^0.1.1-rc.2",
50
- "@deepseek-ai/dsh-client-ui-input-trigger": "^0.1.1-rc.2",
51
- "@deepseek-ai/dsh-client-ui-tool": "^0.1.1-rc.2",
52
- "@deepseek-ai/dsh-invariants": "^0.1.1-rc.2",
53
- "@deepseek-ai/cordis": "^4.0.1"
47
+ "@deepseek-ai/cordis": "^4.0.2"
54
48
  },
55
49
  "devDependencies": {
56
50
  "@testing-library/react": "^16.1.0",
57
51
  "@types/react": "~18.3.1",
58
52
  "react": "^18.2.0",
59
53
  "react-dom": "^18.2.0",
60
- "@deepseek-ai/dsh-api-remotes": "^0.1.1-rc.2",
61
- "@deepseek-ai/dsh-client-locale": "^0.1.1-rc.2",
62
- "@deepseek-ai/dsh-client-runtime": "^0.1.1-rc.2",
63
- "@deepseek-ai/dsh-client-ui-primitives": "^0.1.1-rc.2",
64
- "@deepseek-ai/dsh-client-test-runtime": "^0.1.1-rc.2",
65
- "@deepseek-ai/dsh-client-connection": "^0.1.1-rc.2",
66
- "@deepseek-ai/dsh-client-ui-input-trigger": "^0.1.1-rc.2",
67
- "@deepseek-ai/dsh-client-ui-slots": "^0.1.1-rc.2",
68
- "@deepseek-ai/dsh-client-ui-tool": "^0.1.1-rc.2",
69
- "@deepseek-ai/dsh-invariants": "^0.1.1-rc.2",
70
- "@deepseek-ai/cordis": "^4.0.1"
54
+ "@deepseek-ai/dsh-api-session-controller": "^0.1.2-alpha.2",
55
+ "@deepseek-ai/dsh-api-remotes": "^0.1.2-alpha.2",
56
+ "@deepseek-ai/dsh-client-connection": "^0.1.2-alpha.2",
57
+ "@deepseek-ai/dsh-client-locale": "^0.1.2-alpha.2",
58
+ "@deepseek-ai/dsh-client-test-runtime": "^0.1.2-alpha.2",
59
+ "@deepseek-ai/dsh-client-ui-primitives": "^0.1.2-alpha.2",
60
+ "@deepseek-ai/dsh-client-ui-slots": "^0.1.2-alpha.2",
61
+ "@deepseek-ai/dsh-client-ui-tool": "^0.1.2-alpha.2",
62
+ "@deepseek-ai/dsh-client-ui-renderer": "^0.1.2-alpha.2",
63
+ "@deepseek-ai/dsh-invariants": "^0.1.2-alpha.2",
64
+ "@deepseek-ai/dsh-session": "^0.1.2-alpha.2",
65
+ "@deepseek-ai/cordis": "^4.0.2",
66
+ "@deepseek-ai/dsh-client-ui-input-trigger": "^0.1.2-alpha.2"
71
67
  },
72
68
  "files": [
73
69
  "lib/index.js",