@monotykamary/dsh-client-ui-skill 0.1.0-rc.5
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 +21 -0
- package/README.i18n.yaml +6 -0
- package/README.md +37 -0
- package/README.zh.md +37 -0
- package/lib/client.js +327 -0
- package/lib/index.js +11 -0
- package/lib/invariant.js +25 -0
- package/lib/types/client/SkillRow.d.ts +12 -0
- package/lib/types/client/index.d.ts +16 -0
- package/lib/types/client/locales.d.ts +22 -0
- package/lib/types/index.d.ts +9 -0
- package/lib/types/invariant.d.ts +16 -0
- package/package.json +85 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 DeepSeek
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
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-skill/README.md
|
|
5
|
+
README.md: 5ca3ff05e3935fc1013d786ddf081c2e8474cb52
|
|
6
|
+
README.zh.md: 023d9782f0b3fa21ac9c828902b0c3164556c18e
|
package/README.md
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# @monotykamary/dsh-client-ui-skill
|
|
2
|
+
|
|
3
|
+
English | [中文](README.zh.md)
|
|
4
|
+
|
|
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)`.
|
|
6
|
+
|
|
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.
|
|
8
|
+
|
|
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.
|
|
10
|
+
|
|
11
|
+
The `/client` exports are the plugin body (`apply`/`inject`) only; the source object is internal to the registration effect.
|
|
12
|
+
|
|
13
|
+
## Skill tool row
|
|
14
|
+
|
|
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.
|
|
16
|
+
|
|
17
|
+
## Model Experience
|
|
18
|
+
|
|
19
|
+
### User-explicit skill invocation
|
|
20
|
+
|
|
21
|
+
#### What the model sees
|
|
22
|
+
|
|
23
|
+
The user's message reaches the model verbatim, `/name` literal included. The host's pre-step boundary (`dsh-tool-skill`) then appends the canonical `<skill_content>` block — the same `renderSkillContent` output the `skill` tool returns — as injected instructions context at the end of that step's injections, closest to the model's answer. Loading is deterministic: the model receives the full body without being asked to call the `skill` tool, and the catalog tells it not to re-load an inline-injected skill.
|
|
24
|
+
|
|
25
|
+
#### Token effect
|
|
26
|
+
|
|
27
|
+
One invocation adds the rendered skill body to that turn as injected context — the same cost as the model loading the skill through the tool, paid unconditionally instead of at the model's discretion. Menu browsing and the candidate fetch add zero model tokens.
|
|
28
|
+
|
|
29
|
+
#### KV Cache effect
|
|
30
|
+
|
|
31
|
+
Append-only: the injected message lands after the reusable history prefix. This package never edits earlier request tokens.
|
|
32
|
+
|
|
33
|
+
## Known Limitations and Deferred Work
|
|
34
|
+
|
|
35
|
+
- **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).
|
|
37
|
+
- **A menu opened before the prewarm settles** shows no skill candidates for that keystroke; the next keystroke re-polls the settled cache.
|
package/README.zh.md
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# @monotykamary/dsh-client-ui-skill
|
|
2
|
+
|
|
3
|
+
[English](README.md) | 中文
|
|
4
|
+
|
|
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)` 过滤。
|
|
6
|
+
|
|
7
|
+
pick 会落下字面文本 `/name `,发出的提示词中也是同一段字面文本([slash 流水线 Agent Note](../../../.agents/notes/implemented/architecture/2026-07-25-web-input-machine-and-slash-pipeline.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` 扫描派生。
|
|
8
|
+
|
|
9
|
+
`skill.list` 失败时 `candidates` 抛出异常,slash 壳层记录日志,并静默丢弃该菜单组——菜单只显示 pending/ready 状态。
|
|
10
|
+
|
|
11
|
+
`/client` 导出接口只有插件主体(`apply`/`inject`);source 对象是注册 effect 的内部实现。
|
|
12
|
+
|
|
13
|
+
## skill 工具行
|
|
14
|
+
|
|
15
|
+
浏览器插件还会把 `skill` wire 名称注册进 `ui-tool` 的 keyed `tool.call.toolview` slot。收起的行以与 Bash 行相同的中性视觉层级显示 14 像素的 skill 文档与闪光组合图标、`Skill` 标题、分隔符和请求加载的 skill 名称;运行中的工具调用带有 transcript(文本记录)的扫光效果,失败时用错误首行替换名称,中断的工具调用则使用警告状态。已结算的行以整行作为展开入口,展开后显示一个尺寸受限的 `Instructions` 卡片,其中原样呈现持久化的工具输出;可用时还会提供标准执行轨迹的 `Inspect` 入口。该行的名称、生命周期和正文只派生自 `ui-tool` 提供的冻结的工具调用/工具结果切片,绝不读取当前 skill 目录,因此即使已安装的 skill 或其描述发生变化,回放仍保持稳定。
|
|
16
|
+
|
|
17
|
+
## 模型体验
|
|
18
|
+
|
|
19
|
+
### 用户显式 skill 调用
|
|
20
|
+
|
|
21
|
+
#### 模型看到的内容
|
|
22
|
+
|
|
23
|
+
用户消息原样到达模型,字面文本 `/name` 也包含在内。随后宿主的 pre-step 边界(`dsh-tool-skill`)把规范的 `<skill_content>` 块——与 `skill` 工具返回的 `renderSkillContent` 输出相同——作为注入的指令上下文追加在该步骤各项注入的末尾,最贴近模型的回答。加载是确定性的:模型无需被要求调用 `skill` 工具就能收到完整正文,目录也会告诉它不要重新加载已内联注入的 skill。
|
|
24
|
+
|
|
25
|
+
#### Token 影响
|
|
26
|
+
|
|
27
|
+
一次调用会把渲染后的 skill 正文作为注入上下文加进该轮次——成本与模型经由工具加载该 skill 相同,只是无条件支付,而非由模型自行裁量。浏览菜单和拉取候选不会增加任何模型 token。
|
|
28
|
+
|
|
29
|
+
#### KV Cache 影响
|
|
30
|
+
|
|
31
|
+
仅追加:注入的消息落在可复用历史前缀之后。该包绝不改写较早的请求 token。
|
|
32
|
+
|
|
33
|
+
## 已知限制与暂缓事项
|
|
34
|
+
|
|
35
|
+
- **仅含工具结果的 history 页使用通用行**:键控分派要求配对的工具调用位于运行时窗口内;分页将工具调用留在窗口外时,工具结果没有工具身份。这项客户端呈现功能不会为了恢复该身份而扩展 history 协议约定。
|
|
36
|
+
- **文本是唯一依据**:引用是普通的草稿文本;手动键入的相同 token 就是同一个引用,宿主手势边界评判的是发出的文本,而不是菜单交互。chip 视觉由 lexicon 扫描派生;没有 occurrence 身份、位置跟踪,也没有提示词协议上的结构化引用载荷(两者都是台账事项)。
|
|
37
|
+
- **预热落定之前打开的菜单**:在那次击键下不显示 skill 候选;下一次击键会重新轮询已落定的缓存。
|
package/lib/client.js
ADDED
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
window.__ModuleLoader__.load({
|
|
2
|
+
id: "@monotykamary/dsh-client-ui-skill",
|
|
3
|
+
factory: (require) => {
|
|
4
|
+
var module = { exports: {} };
|
|
5
|
+
var exports = module.exports;
|
|
6
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
7
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
8
|
+
let react = require("react");
|
|
9
|
+
let _monotykamary_dsh_client_ui_primitives = require("@monotykamary/dsh-client-ui-primitives");
|
|
10
|
+
//#region \0dsh-css:/Users/monotykamary/VCS/working-remote/open-source/deepseek-harness/packages/client/ui-skill/src/client/SkillRow.module.css.mjs
|
|
11
|
+
const css = ".HXy9aG_card{flex-direction:column;display:flex}.HXy9aG_row{align-items:center;min-width:0;height:24px;display:flex;position:relative;overflow:hidden}.HXy9aG_row[data-expandable]{cursor:pointer}.HXy9aG_card[data-state=running] .HXy9aG_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 HXy9aG_dsh-skill-row-sweep;position:absolute;inset:0 auto 0 0}@keyframes HXy9aG_dsh-skill-row-sweep{0%{left:-300px}90%,to{left:100%}}.HXy9aG_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}.HXy9aG_chevron{color:var(--dsw-alias-label-secondary)}.HXy9aG_iconIdle{opacity:1;transition:opacity .1s;display:inline-flex}.HXy9aG_chevronHover{opacity:0;margin:auto;transition:opacity .1s;position:absolute;inset:0}.HXy9aG_row:hover .HXy9aG_iconIdle{opacity:0}.HXy9aG_row:hover .HXy9aG_chevronHover{opacity:1}.HXy9aG_title{color:var(--dsw-alias-label-secondary);flex:none;font-size:14px;line-height:24px}.HXy9aG_separator{background:var(--dsw-alias-label-caption);border-radius:1px;flex:none;width:2px;height:2px;margin:0 8px}.HXy9aG_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}.HXy9aG_errorSummary{color:var(--dsw-alias-state-error-primary)}.HXy9aG_bodyWrap{flex-direction:column;display:flex}.HXy9aG_instructionsCard{border:1px 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}.HXy9aG_instructionsHeader{border-bottom:1px 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}.HXy9aG_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}.HXy9aG_instructions[data-error]{color:var(--dsw-alias-state-error-primary)}.HXy9aG_instructions::-webkit-scrollbar-thumb{background-clip:padding-box;border:2px solid #0000;border-radius:6px}.HXy9aG_instructions::-webkit-scrollbar-track{margin:6px 0}.HXy9aG_inspectButton{border:1px solid var(--dsw-alias-border-l2);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}.HXy9aG_card:hover .HXy9aG_inspectButton,.HXy9aG_inspectButton:focus-visible{opacity:1}.HXy9aG_inspectButton:hover{background:var(--dsw-alias-interactive-bg-hover-solid);color:var(--dsw-alias-label-primary)}.HXy9aG_visuallyHidden{clip:rect(0 0 0 0);white-space:nowrap;width:1px;height:1px;position:absolute;overflow:hidden}@media (prefers-reduced-motion:reduce){.HXy9aG_card[data-state=running] .HXy9aG_row:after{animation:none;display:none}.HXy9aG_iconIdle,.HXy9aG_chevronHover,.HXy9aG_inspectButton{transition:none}}";
|
|
12
|
+
const tagId = "@monotykamary/dsh-client-ui-skill/SkillRow.module.css";
|
|
13
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
14
|
+
const tag = document.createElement("style");
|
|
15
|
+
tag.dataset.plugin = "@monotykamary/dsh-client-ui-skill";
|
|
16
|
+
tag.dataset.pluginCss = tagId;
|
|
17
|
+
tag.textContent = css;
|
|
18
|
+
document.head.appendChild(tag);
|
|
19
|
+
}
|
|
20
|
+
var SkillRow_module_css_default = {
|
|
21
|
+
"visuallyHidden": "HXy9aG_visuallyHidden",
|
|
22
|
+
"leading": "HXy9aG_leading",
|
|
23
|
+
"title": "HXy9aG_title",
|
|
24
|
+
"instructionsHeader": "HXy9aG_instructionsHeader",
|
|
25
|
+
"inspectButton": "HXy9aG_inspectButton",
|
|
26
|
+
"instructions": "HXy9aG_instructions",
|
|
27
|
+
"instructionsCard": "HXy9aG_instructionsCard",
|
|
28
|
+
"row": "HXy9aG_row",
|
|
29
|
+
"bodyWrap": "HXy9aG_bodyWrap",
|
|
30
|
+
"dsh-skill-row-sweep": "HXy9aG_dsh-skill-row-sweep",
|
|
31
|
+
"chevronHover": "HXy9aG_chevronHover",
|
|
32
|
+
"summary": "HXy9aG_summary",
|
|
33
|
+
"errorSummary": "HXy9aG_errorSummary",
|
|
34
|
+
"separator": "HXy9aG_separator",
|
|
35
|
+
"iconIdle": "HXy9aG_iconIdle",
|
|
36
|
+
"card": "HXy9aG_card",
|
|
37
|
+
"chevron": "HXy9aG_chevron"
|
|
38
|
+
};
|
|
39
|
+
//#endregion
|
|
40
|
+
//#region lib/types/client/SkillRow.js
|
|
41
|
+
/** First physical line for the collapsed error summary and malformed-args fallback. */
|
|
42
|
+
function firstLine(text) {
|
|
43
|
+
const newline = text.indexOf("\n");
|
|
44
|
+
return newline === -1 ? text : text.slice(0, newline);
|
|
45
|
+
}
|
|
46
|
+
/** Skill names are the only call argument the compact row presents. */
|
|
47
|
+
function skillName(argsRaw, callId) {
|
|
48
|
+
try {
|
|
49
|
+
const parsed = JSON.parse(argsRaw);
|
|
50
|
+
if (typeof parsed === "object" && parsed !== null) {
|
|
51
|
+
const name = parsed.name;
|
|
52
|
+
if (typeof name === "string" && name !== "") return firstLine(name);
|
|
53
|
+
}
|
|
54
|
+
} catch {}
|
|
55
|
+
return argsRaw === "" ? callId : firstLine(argsRaw);
|
|
56
|
+
}
|
|
57
|
+
/** Flatten durable result blocks under the generic Tool-row text contract.
|
|
58
|
+
* Keep aligned with ui-tool's models/tool-call-model.ts `resultText`. */
|
|
59
|
+
function resultText(block) {
|
|
60
|
+
if (!("kind" in block)) return null;
|
|
61
|
+
const parts = [];
|
|
62
|
+
for (const item of block.content) parts.push(item.type === "text" ? item.text : JSON.stringify(item, null, 2));
|
|
63
|
+
if (parts.length === 0 && block.error !== void 0) parts.push(`${block.error.name}: ${block.error.code}`);
|
|
64
|
+
return parts.join("\n") || null;
|
|
65
|
+
}
|
|
66
|
+
/** Derive display state without consulting the live skill catalog. */
|
|
67
|
+
function skillRowModel(block) {
|
|
68
|
+
const settled = "kind" in block;
|
|
69
|
+
const argsRaw = (settled ? block.call?.argsRaw : block.argsRaw) ?? "";
|
|
70
|
+
const state = !settled ? "running" : block.error?.code === "interrupted" ? "stopped" : block.isError ? "error" : "ok";
|
|
71
|
+
const output = resultText(block);
|
|
72
|
+
return {
|
|
73
|
+
name: skillName(argsRaw, block.callId),
|
|
74
|
+
output,
|
|
75
|
+
errorSummary: state === "error" && output !== null ? firstLine(output) : null,
|
|
76
|
+
state
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
/** State substitution for the collapsed leading slot. */
|
|
80
|
+
function leadingFor(state) {
|
|
81
|
+
switch (state) {
|
|
82
|
+
case "error": return (0, react_jsx_runtime.jsx)(_monotykamary_dsh_client_ui_primitives.StateDot, { state: "error" });
|
|
83
|
+
case "stopped": return (0, react_jsx_runtime.jsx)(_monotykamary_dsh_client_ui_primitives.StateDot, { state: "warning" });
|
|
84
|
+
default: return (0, react_jsx_runtime.jsx)(_monotykamary_dsh_client_ui_primitives.IconSkillOutline16, { size: 14 });
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/** Leading disclosure slot: state icon at rest, chevron on hover or while open. */
|
|
88
|
+
function disclosureLeading(state, open, expandable) {
|
|
89
|
+
if (open) return (0, react_jsx_runtime.jsx)(_monotykamary_dsh_client_ui_primitives.IconChevronDownOutline14, { className: SkillRow_module_css_default.chevron });
|
|
90
|
+
const icon = leadingFor(state);
|
|
91
|
+
if (!expandable) return icon;
|
|
92
|
+
return (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)("span", {
|
|
93
|
+
className: SkillRow_module_css_default.iconIdle,
|
|
94
|
+
children: icon
|
|
95
|
+
}), (0, react_jsx_runtime.jsx)(_monotykamary_dsh_client_ui_primitives.IconChevronDownOutline14, { className: `${SkillRow_module_css_default.chevron} ${SkillRow_module_css_default.chevronHover}` })] });
|
|
96
|
+
}
|
|
97
|
+
/** Visually hidden state copy for the colour-only lifecycle cues. */
|
|
98
|
+
function stateStatus(state, t) {
|
|
99
|
+
switch (state) {
|
|
100
|
+
case "running": return t("row.running");
|
|
101
|
+
case "error": return t("row.failed");
|
|
102
|
+
case "stopped": return t("row.stopped");
|
|
103
|
+
default: return null;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Render one `skill` tool call as an accent summary and instructions disclosure.
|
|
108
|
+
* @param props - keyed toolview payload plus the skill locale seat.
|
|
109
|
+
* @returns the dedicated skill row.
|
|
110
|
+
*/
|
|
111
|
+
function SkillRow({ block, inspect, t }) {
|
|
112
|
+
const model = skillRowModel(block);
|
|
113
|
+
const [expanded, setExpanded] = (0, react.useState)(false);
|
|
114
|
+
const expandable = model.output !== null;
|
|
115
|
+
const open = expanded && expandable;
|
|
116
|
+
const status = stateStatus(model.state, t);
|
|
117
|
+
const summary = model.errorSummary ?? model.name;
|
|
118
|
+
const toggleExpand = () => {
|
|
119
|
+
setExpanded((value) => !value);
|
|
120
|
+
};
|
|
121
|
+
const toggleFromKeyboard = (event) => {
|
|
122
|
+
if (!expandable || event.key !== "Enter" && event.key !== " ") return;
|
|
123
|
+
event.preventDefault();
|
|
124
|
+
toggleExpand();
|
|
125
|
+
};
|
|
126
|
+
const disclosureProps = expandable ? {
|
|
127
|
+
role: "button",
|
|
128
|
+
tabIndex: 0,
|
|
129
|
+
"aria-expanded": open,
|
|
130
|
+
onClick: toggleExpand,
|
|
131
|
+
onKeyDown: toggleFromKeyboard
|
|
132
|
+
} : {};
|
|
133
|
+
const leading = disclosureLeading(model.state, open, expandable);
|
|
134
|
+
return (0, react_jsx_runtime.jsxs)("div", {
|
|
135
|
+
className: SkillRow_module_css_default.card,
|
|
136
|
+
"data-tool": "skill",
|
|
137
|
+
"data-state": model.state,
|
|
138
|
+
children: [(0, react_jsx_runtime.jsxs)("div", {
|
|
139
|
+
className: SkillRow_module_css_default.row,
|
|
140
|
+
"data-expandable": expandable || void 0,
|
|
141
|
+
...disclosureProps,
|
|
142
|
+
children: [
|
|
143
|
+
(0, react_jsx_runtime.jsx)("span", {
|
|
144
|
+
className: SkillRow_module_css_default.leading,
|
|
145
|
+
children: leading
|
|
146
|
+
}),
|
|
147
|
+
status !== null ? (0, react_jsx_runtime.jsx)("span", {
|
|
148
|
+
className: SkillRow_module_css_default.visuallyHidden,
|
|
149
|
+
children: status
|
|
150
|
+
}) : null,
|
|
151
|
+
(0, react_jsx_runtime.jsx)("span", {
|
|
152
|
+
className: SkillRow_module_css_default.title,
|
|
153
|
+
children: "Skill"
|
|
154
|
+
}),
|
|
155
|
+
(0, react_jsx_runtime.jsx)("span", {
|
|
156
|
+
className: SkillRow_module_css_default.separator,
|
|
157
|
+
"aria-hidden": true
|
|
158
|
+
}),
|
|
159
|
+
(0, react_jsx_runtime.jsx)("span", {
|
|
160
|
+
className: model.errorSummary === null ? SkillRow_module_css_default.summary : `${SkillRow_module_css_default.summary} ${SkillRow_module_css_default.errorSummary}`,
|
|
161
|
+
children: summary
|
|
162
|
+
})
|
|
163
|
+
]
|
|
164
|
+
}), open ? (0, react_jsx_runtime.jsxs)("div", {
|
|
165
|
+
className: SkillRow_module_css_default.bodyWrap,
|
|
166
|
+
children: [(0, react_jsx_runtime.jsxs)("section", {
|
|
167
|
+
className: SkillRow_module_css_default.instructionsCard,
|
|
168
|
+
"aria-label": t("row.instructions"),
|
|
169
|
+
children: [(0, react_jsx_runtime.jsx)("div", {
|
|
170
|
+
className: SkillRow_module_css_default.instructionsHeader,
|
|
171
|
+
children: t("row.instructions")
|
|
172
|
+
}), (0, react_jsx_runtime.jsx)("pre", {
|
|
173
|
+
className: SkillRow_module_css_default.instructions,
|
|
174
|
+
"data-error": model.state === "error" || void 0,
|
|
175
|
+
children: model.output
|
|
176
|
+
})]
|
|
177
|
+
}), inspect !== void 0 ? (0, react_jsx_runtime.jsxs)("button", {
|
|
178
|
+
type: "button",
|
|
179
|
+
className: SkillRow_module_css_default.inspectButton,
|
|
180
|
+
onClick: inspect,
|
|
181
|
+
children: [(0, react_jsx_runtime.jsx)(_monotykamary_dsh_client_ui_primitives.IconInspectOutline12, {}), "Inspect"]
|
|
182
|
+
}) : null]
|
|
183
|
+
}) : null]
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
//#endregion
|
|
187
|
+
//#region lib/types/client/locales.js
|
|
188
|
+
/** `skill` namespace dictionaries for the dedicated tool row. */
|
|
189
|
+
/** Dictionary namespace owned by this plugin. */
|
|
190
|
+
const NS = "skill";
|
|
191
|
+
/** Simplified Chinese dictionary (the key-set source of truth). */
|
|
192
|
+
const zh = {
|
|
193
|
+
"row.running": "正在加载 skill",
|
|
194
|
+
"row.failed": "skill 加载失败",
|
|
195
|
+
"row.stopped": "skill 加载已中止",
|
|
196
|
+
"row.instructions": "说明",
|
|
197
|
+
"menu.userOnly": "仅用户"
|
|
198
|
+
};
|
|
199
|
+
/** English dictionary, checked complete against the zh key set. */
|
|
200
|
+
const en = {
|
|
201
|
+
"row.running": "Loading skill",
|
|
202
|
+
"row.failed": "Skill load failed",
|
|
203
|
+
"row.stopped": "Skill load stopped",
|
|
204
|
+
"row.instructions": "Instructions",
|
|
205
|
+
"menu.userOnly": "user-only"
|
|
206
|
+
};
|
|
207
|
+
//#endregion
|
|
208
|
+
//#region lib/types/client/index.js
|
|
209
|
+
/** Required services: reference source faces plus the tool-row and locale registries. */
|
|
210
|
+
const inject = [
|
|
211
|
+
"inputTriggers",
|
|
212
|
+
"connection",
|
|
213
|
+
"sessions",
|
|
214
|
+
"slots",
|
|
215
|
+
"locale",
|
|
216
|
+
"remote"
|
|
217
|
+
];
|
|
218
|
+
/**
|
|
219
|
+
* Client plugin body: register the '/' source, dictionaries, and keyed tool row.
|
|
220
|
+
* @param ctx - client root context.
|
|
221
|
+
*/
|
|
222
|
+
function apply(ctx) {
|
|
223
|
+
ctx.effect(() => ctx.locale.register(NS, {
|
|
224
|
+
zh,
|
|
225
|
+
en
|
|
226
|
+
}), "ui-skill: dictionaries");
|
|
227
|
+
ctx.slots.inject("tool.call.toolview", () => ctx.slots.register({
|
|
228
|
+
name: "tool.call.toolview",
|
|
229
|
+
key: "skill",
|
|
230
|
+
locale: NS
|
|
231
|
+
}, SkillRow));
|
|
232
|
+
const skills = ctx.get("connection").api.skills;
|
|
233
|
+
const sessions = ctx.get("sessions");
|
|
234
|
+
const fetches = /* @__PURE__ */ new Map();
|
|
235
|
+
const lexiconListeners = /* @__PURE__ */ new Map();
|
|
236
|
+
const notifyLexicon = (sessionId) => {
|
|
237
|
+
for (const listener of [...lexiconListeners.get(sessionId) ?? []]) try {
|
|
238
|
+
listener();
|
|
239
|
+
} catch (error) {
|
|
240
|
+
console.error("[ui-skill] lexicon listener failed:", error);
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
const fetchCatalog = (sessionId) => {
|
|
244
|
+
if (sessions.subagentAddress(sessionId) !== void 0) return Promise.resolve([]);
|
|
245
|
+
const existing = fetches.get(sessionId);
|
|
246
|
+
if (existing !== void 0) return existing.promise;
|
|
247
|
+
const abort = new AbortController();
|
|
248
|
+
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}`);
|
|
251
|
+
return result.value.skills;
|
|
252
|
+
})();
|
|
253
|
+
const entry = {
|
|
254
|
+
promise,
|
|
255
|
+
abort
|
|
256
|
+
};
|
|
257
|
+
fetches.set(sessionId, entry);
|
|
258
|
+
promise.then((skills) => {
|
|
259
|
+
entry.settled = skills;
|
|
260
|
+
notifyLexicon(sessionId);
|
|
261
|
+
}, () => {
|
|
262
|
+
if (fetches.get(sessionId) === entry) fetches.delete(sessionId);
|
|
263
|
+
});
|
|
264
|
+
return promise;
|
|
265
|
+
};
|
|
266
|
+
const invalidate = (key) => {
|
|
267
|
+
const entry = fetches.get(key);
|
|
268
|
+
if (entry === void 0) return;
|
|
269
|
+
fetches.delete(key);
|
|
270
|
+
entry.abort.abort();
|
|
271
|
+
notifyLexicon(key);
|
|
272
|
+
};
|
|
273
|
+
const clearAll = () => {
|
|
274
|
+
for (const key of [...fetches.keys()]) invalidate(key);
|
|
275
|
+
};
|
|
276
|
+
const t = ctx.locale.bind(NS);
|
|
277
|
+
const source = {
|
|
278
|
+
trigger: "/",
|
|
279
|
+
name: "skill",
|
|
280
|
+
order: 2,
|
|
281
|
+
async candidates(session, { query, signal }) {
|
|
282
|
+
const skills = await fetchCatalog(session.sessionId);
|
|
283
|
+
if (signal.aborted) return [];
|
|
284
|
+
return skills.filter((skill) => skill.name.startsWith(query)).map((skill) => ({
|
|
285
|
+
name: skill.name,
|
|
286
|
+
description: skill.modelInvocable ? skill.description : `${t("menu.userOnly")} · ${skill.description}`
|
|
287
|
+
}));
|
|
288
|
+
},
|
|
289
|
+
warm(session) {
|
|
290
|
+
fetchCatalog(session.sessionId).catch(() => {});
|
|
291
|
+
},
|
|
292
|
+
lexicon(session) {
|
|
293
|
+
return fetches.get(session.sessionId)?.settled?.map((skill) => skill.name);
|
|
294
|
+
},
|
|
295
|
+
subscribeLexicon(session, listener) {
|
|
296
|
+
const key = session.sessionId;
|
|
297
|
+
const listeners = lexiconListeners.get(key) ?? /* @__PURE__ */ new Set();
|
|
298
|
+
listeners.add(listener);
|
|
299
|
+
lexiconListeners.set(key, listeners);
|
|
300
|
+
return () => {
|
|
301
|
+
listeners.delete(listener);
|
|
302
|
+
if (listeners.size === 0) lexiconListeners.delete(key);
|
|
303
|
+
};
|
|
304
|
+
},
|
|
305
|
+
onPick({ candidate }) {
|
|
306
|
+
return { text: `/${candidate.name} ` };
|
|
307
|
+
}
|
|
308
|
+
};
|
|
309
|
+
const inputTriggers = ctx.get("inputTriggers");
|
|
310
|
+
ctx.remote.$on("agent-preset/selected", invalidate);
|
|
311
|
+
ctx.on("connection/reset", clearAll);
|
|
312
|
+
ctx.effect(() => {
|
|
313
|
+
const unregister = inputTriggers.registerSource(source);
|
|
314
|
+
return () => {
|
|
315
|
+
unregister();
|
|
316
|
+
clearAll();
|
|
317
|
+
};
|
|
318
|
+
}, "ui-skill: source");
|
|
319
|
+
}
|
|
320
|
+
//#endregion
|
|
321
|
+
exports.apply = apply;
|
|
322
|
+
exports.inject = inject;
|
|
323
|
+
return module.exports;
|
|
324
|
+
}
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
//# sourceMappingURL=client.js.map
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
//#region lib/types/index.js
|
|
2
|
+
/**
|
|
3
|
+
* Skill reference plugin, node half. Pure UI plugin: the empty apply
|
|
4
|
+
* exists so the plugin appears in the host cordis.yml / Loader; the browser
|
|
5
|
+
* half ships via exports["./client"], discovered through the package.json
|
|
6
|
+
* dsh.client declaration.
|
|
7
|
+
*/
|
|
8
|
+
/** Host plugin body — no host-side behavior for this source plugin. */
|
|
9
|
+
function apply() {}
|
|
10
|
+
//#endregion
|
|
11
|
+
export { apply };
|
package/lib/invariant.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
//#region lib/types/invariant.js
|
|
2
|
+
/**
|
|
3
|
+
* Package-owned invariant companion for `@monotykamary/dsh-client-ui-skill`.
|
|
4
|
+
* @module @monotykamary/dsh-client-ui-skill/invariant
|
|
5
|
+
*/
|
|
6
|
+
const PACKAGE_NAME = "@monotykamary/dsh-client-ui-skill";
|
|
7
|
+
/** Cordis companion plugin name. */
|
|
8
|
+
const name = "client-ui-skill-invariant";
|
|
9
|
+
/** Service required before the companion can reserve package ownership. */
|
|
10
|
+
const inject = ["invariants"];
|
|
11
|
+
/**
|
|
12
|
+
* No runtime invariant: the slash source, locale dictionaries, and keyed
|
|
13
|
+
* toolview are registry-owned registrations whose disposal is proven by the
|
|
14
|
+
* HMR-safety spec. They emit no cordis events and own no cross-plugin mutable
|
|
15
|
+
* state.
|
|
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,12 @@
|
|
|
1
|
+
import type { ToolCallViewProps } from '@monotykamary/dsh-client-ui-tool/client';
|
|
2
|
+
import type { PropsLocale } from '@monotykamary/dsh-client-ui-slots';
|
|
3
|
+
/** Full row props: the toolview runtime share plus this package's locale seat. */
|
|
4
|
+
type SkillRowProps = ToolCallViewProps & PropsLocale<'skill'>;
|
|
5
|
+
/**
|
|
6
|
+
* Render one `skill` tool call as an accent summary and instructions disclosure.
|
|
7
|
+
* @param props - keyed toolview payload plus the skill locale seat.
|
|
8
|
+
* @returns the dedicated skill row.
|
|
9
|
+
*/
|
|
10
|
+
export declare function SkillRow({ block, inspect, t }: SkillRowProps): import("react").JSX.Element;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=SkillRow.d.ts.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ClientContext } from '@monotykamary/dsh-client-runtime/client';
|
|
2
|
+
import { type SkillKey } from './locales.ts';
|
|
3
|
+
declare module '@monotykamary/dsh-client-ui-slots' {
|
|
4
|
+
interface LocaleNamespaceMap {
|
|
5
|
+
/** The dedicated skill tool row's copy. */
|
|
6
|
+
skill: SkillKey;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
/** Required services: reference source faces plus the tool-row and locale registries. */
|
|
10
|
+
export declare const inject: string[];
|
|
11
|
+
/**
|
|
12
|
+
* Client plugin body: register the '/' source, dictionaries, and keyed tool row.
|
|
13
|
+
* @param ctx - client root context.
|
|
14
|
+
*/
|
|
15
|
+
export declare function apply(ctx: ClientContext): void;
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** `skill` namespace dictionaries for the dedicated tool row. */
|
|
2
|
+
/** Dictionary namespace owned by this plugin. */
|
|
3
|
+
export declare const NS = "skill";
|
|
4
|
+
/** Simplified Chinese dictionary (the key-set source of truth). */
|
|
5
|
+
export declare const zh: {
|
|
6
|
+
'row.running': string;
|
|
7
|
+
'row.failed': string;
|
|
8
|
+
'row.stopped': string;
|
|
9
|
+
'row.instructions': string;
|
|
10
|
+
'menu.userOnly': string;
|
|
11
|
+
};
|
|
12
|
+
/** The skill namespace key union. */
|
|
13
|
+
export type SkillKey = keyof typeof zh;
|
|
14
|
+
/** English dictionary, checked complete against the zh key set. */
|
|
15
|
+
export declare const en: {
|
|
16
|
+
'row.running': string;
|
|
17
|
+
'row.failed': string;
|
|
18
|
+
'row.stopped': string;
|
|
19
|
+
'row.instructions': string;
|
|
20
|
+
'menu.userOnly': string;
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=locales.d.ts.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skill reference plugin, node half. Pure UI plugin: the empty apply
|
|
3
|
+
* exists so the plugin appears in the host cordis.yml / Loader; the browser
|
|
4
|
+
* half ships via exports["./client"], discovered through the package.json
|
|
5
|
+
* dsh.client declaration.
|
|
6
|
+
*/
|
|
7
|
+
/** Host plugin body — no host-side behavior for this source plugin. */
|
|
8
|
+
export declare function apply(): void;
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Package-owned invariant companion for `@monotykamary/dsh-client-ui-skill`.
|
|
3
|
+
* @module @monotykamary/dsh-client-ui-skill/invariant
|
|
4
|
+
*/
|
|
5
|
+
import type { Context } from '@monotykamary/cordis';
|
|
6
|
+
/** Cordis companion plugin name. */
|
|
7
|
+
export declare const name = "client-ui-skill-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,85 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@monotykamary/dsh-client-ui-skill",
|
|
3
|
+
"description": "Web skill references and the dedicated skill tool row",
|
|
4
|
+
"version": "0.1.0-rc.5",
|
|
5
|
+
"publishConfig": {
|
|
6
|
+
"access": "public"
|
|
7
|
+
},
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/deepseek-ai/deepseek-harness.git",
|
|
11
|
+
"directory": "packages/client/ui-skill"
|
|
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
|
+
"@monotykamary/dsh-client-runtime",
|
|
36
|
+
"@monotykamary/dsh-client-locale",
|
|
37
|
+
"@monotykamary/dsh-client-ui-tool",
|
|
38
|
+
"@monotykamary/dsh-client-ui-input-trigger",
|
|
39
|
+
"@monotykamary/dsh-api-remotes"
|
|
40
|
+
],
|
|
41
|
+
"platform": "web"
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"license": "MIT",
|
|
45
|
+
"peerDependencies": {
|
|
46
|
+
"react": "^18.2.0",
|
|
47
|
+
"@monotykamary/dsh-api-remotes": "^0.1.0-rc.5",
|
|
48
|
+
"@monotykamary/dsh-client-connection": "^0.1.0-rc.5",
|
|
49
|
+
"@monotykamary/dsh-client-locale": "^0.1.0-rc.5",
|
|
50
|
+
"@monotykamary/dsh-client-ui-input-trigger": "^0.1.0-rc.5",
|
|
51
|
+
"@monotykamary/dsh-client-ui-tool": "^0.1.0-rc.5",
|
|
52
|
+
"@monotykamary/dsh-invariants": "^0.1.0-rc.5",
|
|
53
|
+
"@monotykamary/dsh-client-runtime": "^0.1.0-rc.5",
|
|
54
|
+
"@monotykamary/cordis": "^4.0.1",
|
|
55
|
+
"@monotykamary/dsh-client-ui-primitives": "^0.1.0-rc.5",
|
|
56
|
+
"@monotykamary/dsh-client-ui-slots": "^0.1.0-rc.5"
|
|
57
|
+
},
|
|
58
|
+
"devDependencies": {
|
|
59
|
+
"@testing-library/react": "^16.1.0",
|
|
60
|
+
"@types/react": "~18.3.1",
|
|
61
|
+
"react": "^18.2.0",
|
|
62
|
+
"react-dom": "^18.2.0",
|
|
63
|
+
"@monotykamary/dsh-client-locale": "^0.1.0-rc.5",
|
|
64
|
+
"@monotykamary/dsh-client-connection": "^0.1.0-rc.5",
|
|
65
|
+
"@monotykamary/dsh-client-runtime": "^0.1.0-rc.5",
|
|
66
|
+
"@monotykamary/dsh-client-ui-primitives": "^0.1.0-rc.5",
|
|
67
|
+
"@monotykamary/dsh-api-remotes": "^0.1.0-rc.5",
|
|
68
|
+
"@monotykamary/dsh-client-ui-input-trigger": "^0.1.0-rc.5",
|
|
69
|
+
"@monotykamary/dsh-client-ui-slots": "^0.1.0-rc.5",
|
|
70
|
+
"@monotykamary/dsh-invariants": "^0.1.0-rc.5",
|
|
71
|
+
"@monotykamary/dsh-client-test-runtime": "^0.1.0-rc.5",
|
|
72
|
+
"@monotykamary/cordis": "^4.0.1",
|
|
73
|
+
"@monotykamary/dsh-client-ui-tool": "^0.1.0-rc.5"
|
|
74
|
+
},
|
|
75
|
+
"files": [
|
|
76
|
+
"lib/index.js",
|
|
77
|
+
"lib/invariant.js",
|
|
78
|
+
"lib/client.js",
|
|
79
|
+
"lib/types/**/*.d.ts"
|
|
80
|
+
],
|
|
81
|
+
"scripts": {
|
|
82
|
+
"bundle": "tsdown",
|
|
83
|
+
"watch": "tsdown --watch"
|
|
84
|
+
}
|
|
85
|
+
}
|