@deepseek-ai/dsh-client-ui-skill 0.1.2-rc.1 → 0.1.5-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: 6f5bd109a66b061db3ab5069b15bb4f101039e73
6
- README.zh.md: 61941ef1b5966d9155d724873b25e03d38d214e1
5
+ README.md: 7a524ce1821dc97eaa1b4a67dbe0f956e0da5c87
6
+ README.zh.md: 68e6697a51214a8c21002a59f1b60fc685b935e1
package/README.md CHANGED
@@ -9,7 +9,7 @@ English | [中文](README.zh.md)
9
9
 
10
10
  ## Summary
11
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.
12
+ `dsh-client-ui-skill` lets users invoke a skill by choosing it from the `/` suggestions or typing `/name` directly. The same literal command loads the skill consistently from the Web composer, TUI, and ACP, while a name shared with a host command continues to resolve as that command. Skill calls appear in the conversation as expandable `Instructions` cards whose settled contents remain stable when the installed skill catalog changes.
13
13
 
14
14
  ## Table of Contents
15
15
 
@@ -29,7 +29,7 @@ Type `/` in the composer and pick a skill from the suggestions, or type `/name`
29
29
 
30
30
  ### What the source offers
31
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.
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 rank through the `/` menu's shared name ranker, `rankByName` from ui-primitives: the query matches a case-insensitive ordered subsequence of the skill name, prefix hits rank first, and ties keep the host order ([ranking decision](../../../.agents/notes/archived/feature/2026-08-04-web-slash-command-fuzzy-discovery.md)). A failed `skills/list` call is logged and folded into a silent menu-group drop — the menu shows only pending/ready states.
33
33
 
34
34
  ### The skill tool row
35
35
 
@@ -43,7 +43,7 @@ A collapsed row renders the skill glyph, `Skill` title, and requested skill name
43
43
  <details>
44
44
  <summary>Implementation internals — click to expand</summary>
45
45
 
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)).
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/archived/architecture/2026-07-25-web-input-machine-and-slash-pipeline.md)).
47
47
 
48
48
  ### Candidate flow
49
49
 
@@ -65,7 +65,7 @@ These pages cover the input machinery, the tool row host, and the host-side skil
65
65
  - [ui-input-trigger](../ui-input-trigger/README.md) — the inline suggestion machinery the source registers into.
66
66
  - [ui-tool](../ui-tool/README.md) — the tool-call presentation layer hosting the `tool.call.toolview` slot.
67
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.
68
+ - [Web input machine and slash pipeline](../../../.agents/notes/archived/architecture/2026-07-25-web-input-machine-and-slash-pipeline.md) — how references and commands share the input machine.
69
69
 
70
70
  -----
71
71
 
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:建议菜单从 `skills/list` Remote 提供用户可调用的 skill 候选,选择一项会落下字面文本 `/name `,宿主随后将其加载为 skill 的指令。加载是确定性的:宿主的 pre-step 边界(`dsh-tool-skill`)识别发出消息中以空白为界的 `/name` token,并为每个入口注入渲染后的 `<skill_content>`,因此菜单 pick、手动键入的 token 与 TUI/ACP 提示词都以同一种方式加载 skill。已结算的 skill 调用在对话中渲染为可展开的 `Instructions` 卡片,只从冻结的调用/结果切片派生。
12
+ `dsh-client-ui-skill` 让用户通过 `/` 建议选择或直接键入 `/name` 来调用 skill。同一条字面命令可以从 Web 编辑器、TUI ACP 一致地加载 skill;如果名称与宿主命令相同,它仍会解析为该命令。skill 调用在对话中显示为可展开的 `Instructions` 卡片;即使已安装的 skill 目录发生变化,卡片落定后的内容仍保持稳定。
13
13
 
14
14
  ## 目录
15
15
 
@@ -29,7 +29,7 @@ kind: "package-reference"
29
29
 
30
30
  ### source 提供什么
31
31
 
32
- 普通会话的候选来自 `skills/list` Remote;宿主提供每一个用户可调用的 skill,`modelInvocable: false` 的条目(即 `disable-model-invocation` skill,此路径是其唯一入口)会以当前语言把仅限用户标记作为描述前缀带上。结果按 `startsWith(query)` 过滤。`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
 
@@ -43,7 +43,7 @@ kind: "package-reference"
43
43
  <details>
44
44
  <summary>实现细节——点击展开</summary>
45
45
 
46
- source 不实现任何裁决钩子,也没有引用 codec:pick 落下字面文本,发出的提示词中也是同一段字面文本,因此确定性在宿主侧([slash 流水线笔记](../../../.agents/notes/implemented/architecture/2026-07-25-web-input-machine-and-slash-pipeline.zh.md))。
46
+ source 不实现任何裁决钩子,也没有引用 codec:pick 落下字面文本,发出的提示词中也是同一段字面文本,因此确定性在宿主侧([slash 流水线笔记](../../../.agents/notes/archived/architecture/2026-07-25-web-input-machine-and-slash-pipeline.md))。
47
47
 
48
48
  ### 候选流程
49
49
 
@@ -65,7 +65,7 @@ source 不实现任何裁决钩子,也没有引用 codec:pick 落下字面
65
65
  - [ui-input-trigger](../ui-input-trigger/README.zh.md)——该 source 注册进的行内建议机制。
66
66
  - [ui-tool](../ui-tool/README.zh.md)——承载 `tool.call.toolview` slot 的工具调用展示层。
67
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)——引用与命令如何共享输入机器。
68
+ - [Web 输入机器与 slash 流水线](../../../.agents/notes/archived/architecture/2026-07-25-web-input-machine-and-slash-pipeline.md)——引用与命令如何共享输入机器。
69
69
 
70
70
  -----
71
71
 
package/lib/client.js CHANGED
@@ -4,9 +4,9 @@ window.__ModuleLoader__.load({
4
4
  var module = { exports: {} };
5
5
  var exports = module.exports;
6
6
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
7
+ let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
7
8
  let react_jsx_runtime = require("react/jsx-runtime");
8
9
  let react = require("react");
9
- let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
10
10
  //#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-skill/src/client/SkillRow.module.css.mjs
11
11
  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
12
  const tagId = "@deepseek-ai/dsh-client-ui-skill/SkillRow.module.css";
@@ -285,7 +285,7 @@ window.__ModuleLoader__.load({
285
285
  async candidates(session, { query, signal }) {
286
286
  const skills = await fetchCatalog(session.sessionId);
287
287
  if (signal.aborted) return [];
288
- return skills.filter((skill) => skill.name.startsWith(query)).map((skill) => ({
288
+ return (0, _deepseek_ai_dsh_client_ui_primitives.rankByName)(skills, query).map((skill) => ({
289
289
  name: skill.name,
290
290
  description: skill.modelInvocable ? skill.description : `${t("menu.userOnly")} · ${skill.description}`
291
291
  }));
@@ -4,7 +4,7 @@
4
4
  * projection's sessionId (sessions are always agent-backed; the host
5
5
  * resolves cwd from the session header). A pick lands the literal `/name `
6
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);
7
+ * see .agents/notes/archived/architecture/2026-07-25-web-input-machine-and-slash-pipeline.md);
8
8
  * determinism
9
9
  * lives host-side — the pre-step boundary (`dsh-tool-skill`) recognizes a
10
10
  * leading `/name` naming a user-invocable skill and injects the rendered
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.2-rc.1",
4
+ "version": "0.1.5-alpha.1",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -47,17 +47,17 @@
47
47
  "@types/react": "~18.3.1",
48
48
  "react": "^18.2.0",
49
49
  "react-dom": "^18.2.0",
50
- "@deepseek-ai/dsh-api-remotes": "^0.1.2-rc.1",
51
- "@deepseek-ai/dsh-client-connection": "^0.1.2-rc.1",
52
- "@deepseek-ai/dsh-client-locale": "^0.1.2-rc.1",
53
- "@deepseek-ai/dsh-client-test-runtime": "^0.1.2-rc.1",
54
- "@deepseek-ai/dsh-client-ui-primitives": "^0.1.2-rc.1",
55
- "@deepseek-ai/dsh-api-session-controller": "^0.1.2-rc.1",
56
- "@deepseek-ai/dsh-client-ui-slots": "^0.1.2-rc.1",
57
- "@deepseek-ai/dsh-client-ui-renderer": "^0.1.2-rc.1",
58
- "@deepseek-ai/dsh-client-ui-tool": "^0.1.2-rc.1",
59
- "@deepseek-ai/dsh-client-ui-input-trigger": "^0.1.2-rc.1",
60
- "@deepseek-ai/dsh-session": "^0.1.2-rc.1",
50
+ "@deepseek-ai/dsh-api-remotes": "^0.1.5-alpha.1",
51
+ "@deepseek-ai/dsh-api-session-controller": "^0.1.5-alpha.1",
52
+ "@deepseek-ai/dsh-client-connection": "^0.1.5-alpha.1",
53
+ "@deepseek-ai/dsh-client-locale": "^0.1.5-alpha.1",
54
+ "@deepseek-ai/dsh-client-test-runtime": "^0.1.5-alpha.1",
55
+ "@deepseek-ai/dsh-client-ui-primitives": "^0.1.5-alpha.1",
56
+ "@deepseek-ai/dsh-client-ui-input-trigger": "^0.1.5-alpha.1",
57
+ "@deepseek-ai/dsh-client-ui-renderer": "^0.1.5-alpha.1",
58
+ "@deepseek-ai/dsh-client-ui-slots": "^0.1.5-alpha.1",
59
+ "@deepseek-ai/dsh-client-ui-tool": "^0.1.5-alpha.1",
60
+ "@deepseek-ai/dsh-session": "^0.1.5-alpha.1",
61
61
  "@deepseek-ai/cordis": "^4.0.2"
62
62
  },
63
63
  "files": [