@hpyperry/dsh-ref-lib 0.7.0

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.
Files changed (70) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +91 -0
  3. package/cordis.patch.yml +6 -0
  4. package/lib/client/RefLibBrowser.d.ts +35 -0
  5. package/lib/client/RefLibBrowser.d.ts.map +1 -0
  6. package/lib/client/RefLibBrowser.js +119 -0
  7. package/lib/client/RefLibBrowser.js.map +1 -0
  8. package/lib/client/RefLibDock.d.ts +44 -0
  9. package/lib/client/RefLibDock.d.ts.map +1 -0
  10. package/lib/client/RefLibDock.js +218 -0
  11. package/lib/client/RefLibDock.js.map +1 -0
  12. package/lib/client/RefLibPanel.d.ts +47 -0
  13. package/lib/client/RefLibPanel.d.ts.map +1 -0
  14. package/lib/client/RefLibPanel.js +59 -0
  15. package/lib/client/RefLibPanel.js.map +1 -0
  16. package/lib/client/data.d.ts +53 -0
  17. package/lib/client/data.d.ts.map +1 -0
  18. package/lib/client/data.js +74 -0
  19. package/lib/client/data.js.map +1 -0
  20. package/lib/client/index.d.ts +32 -0
  21. package/lib/client/index.d.ts.map +1 -0
  22. package/lib/client/index.js +80 -0
  23. package/lib/client/index.js.map +1 -0
  24. package/lib/client/layout.d.ts +34 -0
  25. package/lib/client/layout.d.ts.map +1 -0
  26. package/lib/client/layout.js +65 -0
  27. package/lib/client/layout.js.map +1 -0
  28. package/lib/client/locales.d.ts +80 -0
  29. package/lib/client/locales.d.ts.map +1 -0
  30. package/lib/client/locales.js +84 -0
  31. package/lib/client/locales.js.map +1 -0
  32. package/lib/client/styles.d.ts +15 -0
  33. package/lib/client/styles.d.ts.map +1 -0
  34. package/lib/client/styles.js +513 -0
  35. package/lib/client/styles.js.map +1 -0
  36. package/lib/client.js +1377 -0
  37. package/lib/client.js.map +1 -0
  38. package/lib/commands.d.ts +38 -0
  39. package/lib/commands.d.ts.map +1 -0
  40. package/lib/commands.js +49 -0
  41. package/lib/commands.js.map +1 -0
  42. package/lib/index.d.ts +36 -0
  43. package/lib/index.d.ts.map +1 -0
  44. package/lib/index.js +94 -0
  45. package/lib/index.js.map +1 -0
  46. package/lib/logic.d.ts +32 -0
  47. package/lib/logic.d.ts.map +1 -0
  48. package/lib/logic.js +48 -0
  49. package/lib/logic.js.map +1 -0
  50. package/lib/render.d.ts +18 -0
  51. package/lib/render.d.ts.map +1 -0
  52. package/lib/render.js +40 -0
  53. package/lib/render.js.map +1 -0
  54. package/lib/routes.d.ts +39 -0
  55. package/lib/routes.d.ts.map +1 -0
  56. package/lib/routes.js +210 -0
  57. package/lib/routes.js.map +1 -0
  58. package/lib/service.d.ts +88 -0
  59. package/lib/service.d.ts.map +1 -0
  60. package/lib/service.js +212 -0
  61. package/lib/service.js.map +1 -0
  62. package/lib/spec.d.ts +33 -0
  63. package/lib/spec.d.ts.map +1 -0
  64. package/lib/spec.js +13 -0
  65. package/lib/spec.js.map +1 -0
  66. package/lib/validate.d.ts +17 -0
  67. package/lib/validate.d.ts.map +1 -0
  68. package/lib/validate.js +35 -0
  69. package/lib/validate.js.map +1 -0
  70. package/package.json +64 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 hpyperry
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.md ADDED
@@ -0,0 +1,91 @@
1
+ # dsh-ref-lib · 只读参考库
2
+
3
+ > DeepSeek Harness(DSH)插件:给任意会话挂上**只读参考库**,agent 需要查证时
4
+ > **先在参考库里检索**——而不是凭空猜测或直接搜网。
5
+ >
6
+ > 安装:`dsh plugin --profile web add github:hpyperry/dsh-ref-lib`
7
+
8
+ ## ✨ 特性
9
+
10
+ | | 能力 | 说明 |
11
+ | --- | --- | --- |
12
+ | 🚀 | **统一入口** | 输入卡正上方的「参考库」胶囊(hero / active 常显、带数量徽标)——纯 CSS 与输入卡左缘对齐,零测量、零竞态 |
13
+ | 🎨 | **可视化面板** | 基名 + 完整路径列表、悬停高亮、危险色移除、独立的空/加载/错误态 |
14
+ | 📂 | **三种添加方式** | 应用内目录浏览器 / 系统原生选择器(按宿主能力自动适配)/ 手动输入路径(`~` 与相对路径) |
15
+ | 🧠 | **上下文注入** | 仅向配置了参考库的会话注入:库清单 + **查询优先级**(先查参考库,未覆盖再查别的)+ 只读约束;空列表零 token |
16
+ | 🔒 | **per-session 隔离** | 每个会话独立维护,会话间互不可见;sidecar JSON 持久化,重启/恢复后仍在 |
17
+ | ⚡ | **静默数据通道** | client 读写走插件自注册的 `/api/ref-lib/*` HTTP 路由——不渲染命令卡片、不执行命令、不产生用户消息 |
18
+ | 🌐 | **双语界面** | zh/en 全量本地化,随界面语言实时切换 |
19
+ | ⌨️ | **命令入口** | `/ref-lib add <path> \| list \| remove <id>`,与 UI 数据一致 |
20
+ | 🛡️ | **安全** | loopback 护栏 + 路径消毒 + 只读保证分层(沙箱强制 / 上下文软约束) |
21
+
22
+ ## 📦 安装
23
+
24
+ ```bash
25
+ # 从 GitHub 安装(`github:owner/repo` 简写,dsh plugin 负责维护 profile manifest 与依赖)
26
+ dsh plugin --profile web add github:hpyperry/dsh-ref-lib
27
+
28
+ # 本地开发期(改动即时生效):指向仓库本地路径
29
+ # dsh plugin --profile web add /path/to/ref-lib
30
+
31
+ # 重启生效
32
+ dsh --profile web
33
+ ```
34
+
35
+ > 发布到 npm 后也可直接按包名安装:`dsh plugin --profile web add @hpyperry/dsh-ref-lib`。
36
+
37
+ 卸载:`dsh plugin --profile web remove @hpyperry/dsh-ref-lib`
38
+
39
+ ## 🚀 快速开始
40
+
41
+ 1. 重启后在**输入卡正上方**看到「参考库」胶囊(新会话与具体对话均可见);
42
+ 2. 点开面板 → 添加目录(应用内浏览器 / 系统选择器 / 手动路径三选一)→ 列表出现 → 行尾垃圾桶移除;
43
+ 3. 或对话内命令:`/ref-lib add <path>`、`/ref-lib list`、`/ref-lib remove <id>`;
44
+ 4. 配置了参考库的会话,agent 会收到"先查参考库、禁止修改库内文件"的上下文指令——
45
+ 需要查证时它会先在参考库里检索。
46
+
47
+ ## ⚙️ 行为与配置
48
+
49
+ 开箱即用,无配置文件。几个可说明的行为:
50
+
51
+ | 项 | 说明 |
52
+ | --- | --- |
53
+ | 数据存储 | `<dshHome>/plugin-data/ref-lib/<sessionId>.json`(per-session sidecar,随 dsh home 持久化) |
54
+ | 目录选择后端 | 启动时自动探测:应用内目录浏览器(browse)或系统原生对话框(native);可在 profile 的 `cordis.patch.yml` 切换 `directory-picker` 行为 |
55
+ | 上下文注入 | 仅向有参考库的会话注入(`systemPrompt.context`,空列表零 token) |
56
+ | 子会话 | 无自身配置时继承父会话的参考库列表 |
57
+
58
+ ## 🛡️ 安全
59
+
60
+ - `/api/ref-lib/*` 走宿主 `ctx.webServer` 同源路由,loopback 护栏(源地址 + Host + Origin + `Sec-Fetch-Site`),恶意网页 CSRF 与 LAN 访问均被拒;
61
+ - 端点唯一的文件写入是**自己的 sidecar**(固定目录、session 隔离、原子写);`add` 只把"已存在的目录路径"记入列表,不创建/修改目标路径文件;
62
+ - **只读保证分层**:库放在 workspace 之外 → 沙箱进程级强制只读(`read-only`/`workspace-write` 模式均只读);上下文再注入软约束("禁止创建、修改或删除库内文件")。
63
+
64
+ ## ⚠️ 已知限制
65
+
66
+ - **系统原生目录选择器可能卡顿且界面语言跟随 OS**:可用「手动输入路径」绕开;或在 profile 把 `directory-picker` 切换为 `@deepseek-ai/dsh-host-directory-picker-browse`(应用内浏览器,快速且 zh/en 本地化);
67
+ - **settings 配置客户端白名单**(DSH rc.6 框架限制):第三方插件 namespace 默认不可被浏览器端读写,官方标注为 deferred work;
68
+ - UI 添加暂不支持备注(note 字段已在类型中预留);
69
+ - `/ref-lib add <path>` 的相对路径**基于当前会话工作区**解析,而非 dsh 进程启动目录。
70
+
71
+ ## 🧑‍💻 开发
72
+
73
+ ```bash
74
+ pnpm typecheck # tsc --noEmit
75
+ pnpm lint # eslint(typescript-eslint recommended)+ prettier
76
+ pnpm test # vitest(L0–L2:纯函数 / 装载 / harness 边界回归)
77
+ pnpm build # tsc(node half)+ tsdown(client bundle)→ lib/
78
+ ```
79
+
80
+ - **结构**:`src/`(node half:服务 / `/api/ref-lib/*` 路由 / `/ref-lib` 命令 / 上下文注入)+ `src/client/`(web half:dock 胶囊 / 管理面板 / 目录浏览器 / 本地化)+ `tests/`;
81
+ - **隔离开发环境**:`scripts/dev-isolate.sh`(独立 `DSH_HOME`,默认 `~/.dsh-dev`,真实 `~/.dsh` 零接触;`rm -rf` 即重置)——启动/安装/热更新/重置的完整用法见仓库 `AGENTS.md`;
82
+ - **热更新**:`src/client/*` 改动 `pnpm build:client` 后浏览器 ≤0.5s 自动热更新;node half 改动需重启 `dsh web`。
83
+
84
+ ## 📄 License
85
+
86
+ [MIT](LICENSE),与 DeepSeek Harness 一致。
87
+
88
+ ## 📚 更多
89
+
90
+ - 项目开发约定(开发规范 / 测试标准 / 开发环境):见仓库 `AGENTS.md`
91
+ - 仓库:<https://github.com/hpyperry/dsh-ref-lib>
@@ -0,0 +1,6 @@
1
+ # ref-lib 组合包(bundle)的配置层。
2
+ # 安装方式:`dsh plugin --profile web add <ref-lib 路径>`;
3
+ # 插件行按包名引用,由 Node 模块解析找到已安装的代码。
4
+ - insert:
5
+ - id: ref-lib
6
+ name: '@hpyperry/dsh-ref-lib'
@@ -0,0 +1,35 @@
1
+ /**
2
+ * 应用内目录浏览器(browse 后端可用时,「选择目录」的落地实现)。
3
+ *
4
+ * 为什么需要它:v6 起 profile 把 directory-picker 从 -auto(本机解析为 native,
5
+ * OS 对话框硬编码英文且每次拉 osascript 进程)切换为 -browse 后,
6
+ * `host.pickDirectory`(native 专用 RPC)不再可用;本组件用 `listDirectory`
7
+ * (Node stdlib 列目录,zh/en 本地化、无 OS 进程)提供等价的目录选择:
8
+ * 面包屑 + 路径编辑 + 子目录列表,点击下行进入,「选择此目录」把当前层级添加为
9
+ * 参考库。简化为单列(与官方 DirectoryBrowser 的 Miller 双列相比),
10
+ * 但覆盖添加参考库的核心路径。
11
+ * @module @hpyperry/dsh-ref-lib/src/client/RefLibBrowser
12
+ */
13
+ import type { ReactElement } from 'react';
14
+ import type { DirectoryListing } from '@deepseek-ai/dsh-client-runtime/client';
15
+ import type { TranslateNS } from '@deepseek-ai/dsh-client-ui-slots';
16
+ /** 面板组件依赖的注入面(由 RefLibDock 提供)。 */
17
+ export interface RefLibBrowserProps {
18
+ /** 对话框可见性。 */
19
+ open: boolean;
20
+ /** 关闭(Escape / 遮罩 / 取消)。 */
21
+ onClose: () => void;
22
+ /** 列出一层目录(缺省路径 = 宿主主目录);signal 中止被取代的扫描。 */
23
+ listDirectory: (path?: string, signal?: AbortSignal) => Promise<DirectoryListing>;
24
+ /** 本地化取词。 */
25
+ t: TranslateNS<'ref-lib'>;
26
+ /** 选定当前层级目录(父组件负责添加并刷新)。 */
27
+ onOpen: (path: string) => void;
28
+ }
29
+ /**
30
+ * 渲染应用内目录浏览器。
31
+ * @param props - 见 {@link RefLibBrowserProps}。
32
+ * @returns 对话框元素(关闭时 Modal 返回 null)。
33
+ */
34
+ export declare function RefLibBrowser(props: RefLibBrowserProps): ReactElement;
35
+ //# sourceMappingURL=RefLibBrowser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RefLibBrowser.d.ts","sourceRoot":"","sources":["../../src/client/RefLibBrowser.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAA;AAWzC,OAAO,KAAK,EAAkB,gBAAgB,EAAE,MAAM,wCAAwC,CAAA;AAC9F,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAA;AAEnE,mCAAmC;AACnC,MAAM,WAAW,kBAAkB;IACjC,cAAc;IACd,IAAI,EAAE,OAAO,CAAA;IACb,4BAA4B;IAC5B,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,4CAA4C;IAC5C,aAAa,EAAE,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAA;IACjF,aAAa;IACb,CAAC,EAAE,WAAW,CAAC,SAAS,CAAC,CAAA;IACzB,4BAA4B;IAC5B,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CAC/B;AAeD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,YAAY,CAqMrE"}
@@ -0,0 +1,119 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ /**
3
+ * 应用内目录浏览器(browse 后端可用时,「选择目录」的落地实现)。
4
+ *
5
+ * 为什么需要它:v6 起 profile 把 directory-picker 从 -auto(本机解析为 native,
6
+ * OS 对话框硬编码英文且每次拉 osascript 进程)切换为 -browse 后,
7
+ * `host.pickDirectory`(native 专用 RPC)不再可用;本组件用 `listDirectory`
8
+ * (Node stdlib 列目录,zh/en 本地化、无 OS 进程)提供等价的目录选择:
9
+ * 面包屑 + 路径编辑 + 子目录列表,点击下行进入,「选择此目录」把当前层级添加为
10
+ * 参考库。简化为单列(与官方 DirectoryBrowser 的 Miller 双列相比),
11
+ * 但覆盖添加参考库的核心路径。
12
+ * @module @hpyperry/dsh-ref-lib/src/client/RefLibBrowser
13
+ */
14
+ import { useEffect, useRef, useState } from 'react';
15
+ import { Button, IconChevronRightOutline14, IconEditOutline16, IconFolderClose16, IconFolderOpen16, IconLoadingOutline16, IconWarningOutline16, Modal, } from '@deepseek-ai/dsh-client-ui-primitives';
16
+ /** 面包屑展示:主目录子树内以本地化 Home 开头;之外显示完整祖先链。 */
17
+ function displayCrumbs(listing, homeLabel) {
18
+ const homeIndex = listing.crumbs.findIndex((crumb) => crumb.path === listing.home);
19
+ if (homeIndex === -1)
20
+ return listing.crumbs;
21
+ const tail = listing.crumbs.slice(homeIndex + 1);
22
+ return [{ name: homeLabel, path: listing.home, hidden: false }, ...tail];
23
+ }
24
+ /** 平台分隔符(由宿主主目录推断,绝不从键入文本推断)。 */
25
+ function separatorOf(listing) {
26
+ return listing.home.includes('\\') ? '\\' : '/';
27
+ }
28
+ /**
29
+ * 渲染应用内目录浏览器。
30
+ * @param props - 见 {@link RefLibBrowserProps}。
31
+ * @returns 对话框元素(关闭时 Modal 返回 null)。
32
+ */
33
+ export function RefLibBrowser(props) {
34
+ const { open, onClose, listDirectory, t, onOpen } = props;
35
+ const [listing, setListing] = useState(null);
36
+ const [loading, setLoading] = useState(false);
37
+ const [error, setError] = useState(null);
38
+ // 路径编辑:null = 面包屑模式;字符串 = 正在键入的草稿。
39
+ const [pathDraft, setPathDraft] = useState(null);
40
+ const seq = useRef(0);
41
+ const controller = useRef(null);
42
+ // IME 确认(Enter 选中候选)不得提交路径。
43
+ const composing = useRef(false);
44
+ /** 新意图胜出:中止在途扫描并使旧结果失效。 */
45
+ const navigate = (target) => {
46
+ controller.current?.abort();
47
+ controller.current = null;
48
+ const mine = ++seq.current;
49
+ setLoading(true);
50
+ setError(null);
51
+ const ctrl = new AbortController();
52
+ controller.current = ctrl;
53
+ listDirectory(target, ctrl.signal).then((next) => {
54
+ if (mine !== seq.current)
55
+ return;
56
+ setListing(next);
57
+ setLoading(false);
58
+ }, (cause) => {
59
+ if (mine !== seq.current)
60
+ return;
61
+ setLoading(false);
62
+ setError(cause instanceof Error ? cause.message : String(cause));
63
+ });
64
+ };
65
+ // 打开时列主目录;关闭时清理在途扫描。
66
+ useEffect(() => {
67
+ if (open) {
68
+ navigate();
69
+ }
70
+ else {
71
+ seq.current += 1;
72
+ controller.current?.abort();
73
+ controller.current = null;
74
+ setPathDraft(null);
75
+ setError(null);
76
+ }
77
+ }, [open]);
78
+ const openPathEditor = () => {
79
+ if (listing === null) {
80
+ setPathDraft('');
81
+ return;
82
+ }
83
+ const sep = separatorOf(listing);
84
+ const base = listing.path;
85
+ setPathDraft(base.endsWith(sep) ? base : base + sep);
86
+ };
87
+ const commitPath = () => {
88
+ const draft = pathDraft ?? '';
89
+ if (draft.trim() === '')
90
+ return;
91
+ navigate(draft);
92
+ setPathDraft(null);
93
+ };
94
+ const crumbs = listing === null ? [] : displayCrumbs(listing, t('browser.home'));
95
+ return (_jsx(Modal, { open: open, onClose: onClose, title: t('browser.title'), closeLabel: t('browser.cancel'), className: "reflib-browser", children: _jsxs("div", { className: "reflib-panel", children: [error !== null && (_jsxs("div", { className: "reflib-error", role: "alert", children: [_jsx(IconWarningOutline16, { size: 14, className: "reflib-errorIcon" }), _jsx("span", { children: error })] })), _jsx("div", { className: "reflib-browserPath", children: pathDraft === null ? (_jsxs(_Fragment, { children: [_jsx("span", { className: "reflib-browserCrumbs", role: "navigation", children: crumbs.map((crumb, index) => (_jsxs("span", { className: "reflib-browserCrumb", children: [index > 0 && _jsx(IconChevronRightOutline14, { size: 12, className: "reflib-browserCrumbChevron" }), _jsx("button", { type: "button", className: "reflib-browserCrumbBtn", disabled: loading, onClick: () => {
96
+ navigate(crumb.path);
97
+ }, children: crumb.name })] }, crumb.path))) }), _jsx("button", { type: "button", className: "reflib-browserEdit", "aria-label": t('browser.editPath'), title: t('browser.editPath'), disabled: loading, onClick: openPathEditor, children: _jsx(IconEditOutline16, { size: 14 }) })] })) : (_jsx("input", { className: "reflib-browserInput", value: pathDraft, "aria-label": t('browser.editPath'), placeholder: t('browser.pathPlaceholder'), autoFocus: true, disabled: loading, onChange: (event) => {
98
+ setPathDraft(event.currentTarget.value);
99
+ }, onCompositionStart: () => {
100
+ composing.current = true;
101
+ }, onCompositionEnd: () => {
102
+ composing.current = false;
103
+ }, onKeyDown: (event) => {
104
+ if (event.key === 'Enter' && !composing.current) {
105
+ event.preventDefault();
106
+ commitPath();
107
+ }
108
+ if (event.key === 'Escape') {
109
+ event.stopPropagation();
110
+ setPathDraft(null);
111
+ }
112
+ } })) }), loading ? (_jsxs("div", { className: "reflib-status", role: "status", children: [_jsx(IconLoadingOutline16, { size: 20, className: "reflib-spin reflib-statusIcon" }), _jsx("span", { className: "reflib-statusText", children: t('browser.loading') })] })) : listing !== null && listing.entries.length === 0 ? (_jsxs("div", { className: "reflib-status", children: [_jsx(IconFolderOpen16, { size: 22, className: "reflib-statusIcon" }), _jsx("span", { className: "reflib-statusText", children: t('browser.empty') })] })) : (listing !== null && (_jsx("div", { className: "reflib-browserList", children: listing.entries.map((entry) => (_jsxs("button", { type: "button", className: "reflib-browserRow", "aria-label": t('browser.enter.aria', { name: entry.name }), disabled: loading, onClick: () => {
113
+ navigate(entry.path);
114
+ }, children: [_jsx(IconFolderClose16, { size: 16, className: "reflib-browserRowIcon" }), _jsx("span", { className: "reflib-browserRowName", children: entry.name })] }, entry.path))) }))), _jsx("div", { className: "reflib-divider" }), _jsxs("div", { className: "reflib-browserFooter", children: [_jsx(Button, { variant: "outline", size: "sm", disabled: loading, onClick: onClose, children: t('browser.cancel') }), _jsx(Button, { variant: "primary", size: "sm", disabled: loading || listing === null, "aria-label": t('browser.open.aria'), onClick: () => {
115
+ if (listing !== null)
116
+ onOpen(listing.path);
117
+ }, children: t('browser.open') })] })] }) }));
118
+ }
119
+ //# sourceMappingURL=RefLibBrowser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RefLibBrowser.js","sourceRoot":"","sources":["../../src/client/RefLibBrowser.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * 参考库入口(conversation.input.dock,输入卡正上方)+ 面板状态持有者。
3
+ *
4
+ * 位置(v7):v5/v6 曾在 hero 相位把胶囊**测量定位**提入官方 hero 行(紧跟"标准
5
+ * 模式"chip 之后)。该像素测量与 hero 行的异步内容存在竞态——模式 chip 的 roster
6
+ * 经 RPC 异步挂载、Web 字体异步加载、其他插件 chip 异步加入——而重测触发面
7
+ * (hero 行/槽位出口/栈均为固定盒或 display:contents)对"行内内容变化"是盲区,
8
+ * 导致偶发与模式按钮重叠。v7 起**取消测量与绝对定位**:胶囊统一渲染在 dock 槽位
9
+ * (输入卡正上方)的独立一行,左缘经官方设计令牌(--dsh-composer-side-clearance /
10
+ * --dsh-composer-card-max-width)纯 CSS 与输入卡左缘对齐——hero/active 一致、
11
+ * 零 JS 测量、零竞态;plan/model 等工具行座位的启停不影响本行位置;与其他 dock
12
+ * 条带(todo/goal/queue)按 order 流式堆叠,天然不重叠。
13
+ *
14
+ * 数据(v4/v5):读/写经 /api/ref-lib/* 路由(静默、无命令卡片);
15
+ * 目录选择走系统原生选择器,另提供路径输入直加(绕开卡顿的原生对话框)。
16
+ * @module @hpyperry/dsh-ref-lib/src/client/RefLibDock
17
+ */
18
+ import type { ReactElement } from 'react';
19
+ import type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
20
+ import type { DirectoryListing, SessionId } from '@deepseek-ai/dsh-client-runtime/client';
21
+ import type { RefLibEntry } from '../spec.ts';
22
+ /** 面板组件依赖的注入面(apply 闭包绑定 runtime 能力)。 */
23
+ export interface RefLibDockInjected {
24
+ /** 读取会话的参考库列表(GET /api/ref-lib/list,静默)。 */
25
+ load: (sessionId: SessionId) => Promise<RefLibEntry[]>;
26
+ /** 添加一个参考库目录(POST /api/ref-lib/add,静默)。 */
27
+ add: (sessionId: SessionId, path: string) => Promise<void>;
28
+ /** 移除一个参考库条目(POST /api/ref-lib/remove,静默)。 */
29
+ remove: (sessionId: SessionId, id: string) => Promise<void>;
30
+ /** 唤起系统原生"选择文件夹"对话框;取消时返回 null。 */
31
+ pickDirectory: () => Promise<string | null>;
32
+ /** 列出一层目录(browse 后端);缺省路径 = 宿主主目录;signal 中止扫描。 */
33
+ listDirectory: (path?: string, signal?: AbortSignal) => Promise<DirectoryListing>;
34
+ }
35
+ /** 完整 props:input.dock 运行时套件 + 注入面 + 本地化 seat。 */
36
+ export type RefLibDockProps = PropsRuntime<'conversation.input.dock'> & RefLibDockInjected & PropsLocale<'ref-lib'>;
37
+ /**
38
+ * 输入卡正上方的参考库入口:胶囊按钮(图标 + 文案 + 数量徽标)唤起管理面板。
39
+ * 位置由 .reflib-dock 的纯 CSS padding 与输入卡左缘对齐,无任何 JS 测量。
40
+ * @param props - sessionId 与注入面。
41
+ * @returns 胶囊入口(+ 打开时的管理面板)。
42
+ */
43
+ export declare function RefLibDock(props: RefLibDockProps): ReactElement;
44
+ //# sourceMappingURL=RefLibDock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RefLibDock.d.ts","sourceRoot":"","sources":["../../src/client/RefLibDock.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAA;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AACjF,OAAO,KAAK,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,wCAAwC,CAAA;AAEzF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAO7C,yCAAyC;AACzC,MAAM,WAAW,kBAAkB;IACjC,4CAA4C;IAC5C,IAAI,EAAE,CAAC,SAAS,EAAE,SAAS,KAAK,OAAO,CAAC,WAAW,EAAE,CAAC,CAAA;IACtD,2CAA2C;IAC3C,GAAG,EAAE,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1D,8CAA8C;IAC9C,MAAM,EAAE,CAAC,SAAS,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC3D,mCAAmC;IACnC,aAAa,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;IAC3C,kDAAkD;IAClD,aAAa,EAAE,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAA;CAClF;AAED,kDAAkD;AAClD,MAAM,MAAM,eAAe,GAAG,YAAY,CAAC,yBAAyB,CAAC,GAAG,kBAAkB,GAAG,WAAW,CAAC,SAAS,CAAC,CAAA;AAsCnH;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,YAAY,CA4L/D"}
@@ -0,0 +1,218 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ /**
3
+ * 参考库入口(conversation.input.dock,输入卡正上方)+ 面板状态持有者。
4
+ *
5
+ * 位置(v7):v5/v6 曾在 hero 相位把胶囊**测量定位**提入官方 hero 行(紧跟"标准
6
+ * 模式"chip 之后)。该像素测量与 hero 行的异步内容存在竞态——模式 chip 的 roster
7
+ * 经 RPC 异步挂载、Web 字体异步加载、其他插件 chip 异步加入——而重测触发面
8
+ * (hero 行/槽位出口/栈均为固定盒或 display:contents)对"行内内容变化"是盲区,
9
+ * 导致偶发与模式按钮重叠。v7 起**取消测量与绝对定位**:胶囊统一渲染在 dock 槽位
10
+ * (输入卡正上方)的独立一行,左缘经官方设计令牌(--dsh-composer-side-clearance /
11
+ * --dsh-composer-card-max-width)纯 CSS 与输入卡左缘对齐——hero/active 一致、
12
+ * 零 JS 测量、零竞态;plan/model 等工具行座位的启停不影响本行位置;与其他 dock
13
+ * 条带(todo/goal/queue)按 order 流式堆叠,天然不重叠。
14
+ *
15
+ * 数据(v4/v5):读/写经 /api/ref-lib/* 路由(静默、无命令卡片);
16
+ * 目录选择走系统原生选择器,另提供路径输入直加(绕开卡顿的原生对话框)。
17
+ * @module @hpyperry/dsh-ref-lib/src/client/RefLibDock
18
+ */
19
+ import { useEffect, useRef, useState } from 'react';
20
+ import { IconFolderOpen16 } from '@deepseek-ai/dsh-client-ui-primitives';
21
+ import { RefLibApiError } from "./data.js";
22
+ import { RefLibBrowser } from "./RefLibBrowser.js";
23
+ import { RefLibPanel } from "./RefLibPanel.js";
24
+ import { ensureRefLibStyles } from "./styles.js";
25
+ /** wire 错误码 → 本地化文案键(未知码回退原始消息)。 */
26
+ const ERROR_KEYS = {
27
+ 'ref-lib/missing': 'error.missing',
28
+ 'ref-lib/not-directory': 'error.notDirectory',
29
+ 'ref-lib/unsafe': 'error.unsafe',
30
+ 'ref-lib/unknown-id': 'error.unknownId',
31
+ };
32
+ /** 把未知错误规整为可展示文案。 */
33
+ function messageOf(cause) {
34
+ return cause instanceof Error ? cause.message : String(cause);
35
+ }
36
+ /**
37
+ * 把 API 错误本地化:已知 wire code 映射为当前语言文案(带 path/id 参数),
38
+ * 其余错误原样展示服务端消息。
39
+ */
40
+ function formatError(cause, t) {
41
+ if (cause instanceof RefLibApiError) {
42
+ const key = ERROR_KEYS[cause.code];
43
+ if (key !== undefined) {
44
+ const params = cause.details.path !== undefined
45
+ ? { path: cause.details.path }
46
+ : cause.details.id !== undefined
47
+ ? { id: cause.details.id }
48
+ : undefined;
49
+ return t(key, params);
50
+ }
51
+ }
52
+ return messageOf(cause);
53
+ }
54
+ // 模块装载即注入样式(幂等);组件挂载后再兜底一次(覆盖装载早于 DOM 的情况)。
55
+ ensureRefLibStyles();
56
+ /**
57
+ * 输入卡正上方的参考库入口:胶囊按钮(图标 + 文案 + 数量徽标)唤起管理面板。
58
+ * 位置由 .reflib-dock 的纯 CSS padding 与输入卡左缘对齐,无任何 JS 测量。
59
+ * @param props - sessionId 与注入面。
60
+ * @returns 胶囊入口(+ 打开时的管理面板)。
61
+ */
62
+ export function RefLibDock(props) {
63
+ const { sessionId, load, add, remove, pickDirectory, listDirectory, t } = props;
64
+ const [open, setOpen] = useState(false);
65
+ const [libs, setLibs] = useState([]);
66
+ const [loading, setLoading] = useState(false);
67
+ const [busy, setBusy] = useState(false);
68
+ const [picking, setPicking] = useState(false);
69
+ const [removingId, setRemovingId] = useState(null);
70
+ const [error, setError] = useState(null);
71
+ // 并发读守卫:仅采纳最新一次 refresh 的结果(挂载预载与开面板刷新可能重叠)。
72
+ const seq = useRef(0);
73
+ // 目录选择能力(v6):browse(应用内浏览器,listDirectory)或 native(OS 对话框,
74
+ // pickDirectory)。探测一次并缓存;host 侧能力在单次 boot 内稳定。
75
+ const [pickerMode, setPickerMode] = useState(null);
76
+ const [browserOpen, setBrowserOpen] = useState(false);
77
+ const detectPicker = async () => {
78
+ if (pickerMode !== null)
79
+ return pickerMode;
80
+ let mode;
81
+ try {
82
+ await listDirectory(undefined, new AbortController().signal);
83
+ mode = 'browse';
84
+ }
85
+ catch {
86
+ // browse 不可用(directory-picker-unavailable)→ 回退 native 尝试;
87
+ // pickDirectory 若也不可用,由错误槽如实展示。
88
+ mode = 'native';
89
+ }
90
+ setPickerMode(mode);
91
+ return mode;
92
+ };
93
+ const refresh = async () => {
94
+ const mine = ++seq.current;
95
+ try {
96
+ const next = await load(sessionId);
97
+ if (mine !== seq.current)
98
+ return;
99
+ setLibs(next);
100
+ setError(null);
101
+ }
102
+ catch (cause) {
103
+ if (mine !== seq.current)
104
+ return;
105
+ setError(formatError(cause, t));
106
+ }
107
+ finally {
108
+ if (mine === seq.current)
109
+ setLoading(false);
110
+ }
111
+ };
112
+ // 挂载预载。依赖 sessionId:若同一 dock 实例跨会话复用(槽位按会话切换),
113
+ // 会话切换后徽标/列表随之刷新,避免停留在上一个会话的过期数据(seq 守卫防竞态)。
114
+ useEffect(() => {
115
+ ensureRefLibStyles();
116
+ void refresh();
117
+ }, [sessionId]);
118
+ useEffect(() => {
119
+ if (open) {
120
+ setLoading(true);
121
+ void refresh();
122
+ }
123
+ }, [open]);
124
+ const handleRemove = async (id) => {
125
+ setRemovingId(id);
126
+ setBusy(true);
127
+ setError(null);
128
+ try {
129
+ await remove(sessionId, id);
130
+ await refresh();
131
+ }
132
+ catch (cause) {
133
+ setError(formatError(cause, t));
134
+ }
135
+ finally {
136
+ setRemovingId(null);
137
+ setBusy(false);
138
+ }
139
+ };
140
+ const handleAddPath = async (path) => {
141
+ setBusy(true);
142
+ setError(null);
143
+ try {
144
+ await add(sessionId, path);
145
+ await refresh();
146
+ }
147
+ catch (cause) {
148
+ setError(formatError(cause, t));
149
+ // 失败时重新抛出:让面板保留输入内容供修正
150
+ throw cause;
151
+ }
152
+ finally {
153
+ setBusy(false);
154
+ }
155
+ };
156
+ /** 添加一个已选定目录并刷新列表;返回是否成功(失败时错误已入错误槽,不抛出)。 */
157
+ const addPath = async (path) => {
158
+ setBusy(true);
159
+ setError(null);
160
+ try {
161
+ await add(sessionId, path);
162
+ await refresh();
163
+ return true;
164
+ }
165
+ catch (cause) {
166
+ setError(formatError(cause, t));
167
+ return false;
168
+ }
169
+ finally {
170
+ setBusy(false);
171
+ }
172
+ };
173
+ const handleBrowse = async () => {
174
+ setError(null);
175
+ // 探测目录选择能力:browse → 应用内目录浏览器;native → 系统 OS 对话框。
176
+ let mode;
177
+ try {
178
+ mode = await detectPicker();
179
+ }
180
+ catch (cause) {
181
+ setError(formatError(cause, t));
182
+ return;
183
+ }
184
+ if (mode === 'browse') {
185
+ setBrowserOpen(true);
186
+ return;
187
+ }
188
+ setPicking(true);
189
+ try {
190
+ const picked = await pickDirectory();
191
+ if (picked !== null)
192
+ await addPath(picked);
193
+ }
194
+ catch (cause) {
195
+ setError(formatError(cause, t));
196
+ }
197
+ finally {
198
+ setPicking(false);
199
+ }
200
+ };
201
+ /** 应用内浏览器选定目录 → 添加成功才关闭(失败时错误显示在面板,浏览器保持打开便于重试)。 */
202
+ const handleBrowserPick = async (path) => {
203
+ if (await addPath(path))
204
+ setBrowserOpen(false);
205
+ };
206
+ return (_jsxs(_Fragment, { children: [_jsx("div", { className: "reflib-dock", children: _jsxs("button", { type: "button", className: "reflib-chip", "data-active": open || undefined, "aria-haspopup": "dialog", "aria-expanded": open, "aria-label": libs.length > 0 ? t('dock.count.aria', { count: String(libs.length) }) : t('dock.aria'), title: t('dock.aria'), onClick: () => {
207
+ setOpen((value) => !value);
208
+ }, children: [_jsx("span", { className: "reflib-chipIcon", children: _jsx(IconFolderOpen16, { size: 14 }) }), _jsx("span", { className: "reflib-chipLabel", children: t('dock.label') }), libs.length > 0 && _jsx("span", { className: "reflib-chipBadge", children: libs.length })] }) }), _jsx(RefLibPanel, { open: open, onClose: () => {
209
+ setOpen(false);
210
+ }, libs: libs, loading: loading, busy: busy, picking: picking, removingId: removingId, error: error, t: t, onRemove: (id) => {
211
+ void handleRemove(id);
212
+ }, onAddPath: handleAddPath, onBrowse: handleBrowse }), _jsx(RefLibBrowser, { open: browserOpen, onClose: () => {
213
+ setBrowserOpen(false);
214
+ }, listDirectory: listDirectory, t: t, onOpen: (path) => {
215
+ void handleBrowserPick(path);
216
+ } })] }));
217
+ }
218
+ //# sourceMappingURL=RefLibDock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RefLibDock.js","sourceRoot":"","sources":["../../src/client/RefLibDock.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * 参考库管理面板(Modal):列表(基名 + 全路径、移除操作)+ 添加表单。
3
+ *
4
+ * 设计(优化点 1/2):全部样式走 “--dsw-*” 设计令牌(随浅/深主题适配),
5
+ * 列表行以「基名为主行、完整路径为次行」呈现,移除为带危险 hover 的图标按钮,
6
+ * 添加为主按钮 + 路径输入(支持直接粘贴路径,绕开卡顿的系统选择器)+ 系统选择器
7
+ * 兜底;空态/加载态/错误态各有独立视觉。文案全部经 `t` 本地化(zh/en)。
8
+ * 本组件为纯展示:异步操作与错误归集由 RefLibDock 持有。
9
+ * @module @hpyperry/dsh-ref-lib/src/client/RefLibPanel
10
+ */
11
+ import type { ReactElement } from 'react';
12
+ import type { TranslateNS } from '@deepseek-ai/dsh-client-ui-slots';
13
+ import type { RefLibEntry } from '../spec.ts';
14
+ /** 面板组件依赖的注入面(由 RefLibDock 提供)。 */
15
+ export interface RefLibPanelProps {
16
+ /** 对话框可见性。 */
17
+ open: boolean;
18
+ /** 关闭(Escape / 遮罩 / 关闭按钮)。 */
19
+ onClose: () => void;
20
+ /** 当前参考库列表。 */
21
+ libs: readonly RefLibEntry[];
22
+ /** 初次加载中(列表区显示加载态)。 */
23
+ loading: boolean;
24
+ /** 任一异步操作(添加/移除)进行中:禁用全部操作。 */
25
+ busy: boolean;
26
+ /** 系统目录选择器已打开(禁用添加表单,防重复唤起)。 */
27
+ picking: boolean;
28
+ /** 正在移除的条目 id(该行显示行内 spinner)。 */
29
+ removingId: string | null;
30
+ /** 已本地化的错误文案(null 表示无错误)。 */
31
+ error: string | null;
32
+ /** 本地化取词。 */
33
+ t: TranslateNS<'ref-lib'>;
34
+ /** 移除一个条目(父组件执行异步并刷新)。 */
35
+ onRemove: (id: string) => void;
36
+ /** 按输入路径添加;失败时抛出(面板保留输入内容)。 */
37
+ onAddPath: (path: string) => Promise<void>;
38
+ /** 选择目录(按宿主能力自适应:browse 应用内浏览器 / native 系统选择器;父组件确认后添加)。 */
39
+ onBrowse: () => Promise<void>;
40
+ }
41
+ /**
42
+ * 渲染参考库管理面板。
43
+ * @param props - 见 {@link RefLibPanelProps}。
44
+ * @returns 对话框元素(关闭时 Modal 返回 null)。
45
+ */
46
+ export declare function RefLibPanel(props: RefLibPanelProps): ReactElement;
47
+ //# sourceMappingURL=RefLibPanel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RefLibPanel.d.ts","sourceRoot":"","sources":["../../src/client/RefLibPanel.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAA;AAazC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAA;AACnE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAG7C,mCAAmC;AACnC,MAAM,WAAW,gBAAgB;IAC/B,cAAc;IACd,IAAI,EAAE,OAAO,CAAA;IACb,8BAA8B;IAC9B,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,eAAe;IACf,IAAI,EAAE,SAAS,WAAW,EAAE,CAAA;IAC5B,uBAAuB;IACvB,OAAO,EAAE,OAAO,CAAA;IAChB,+BAA+B;IAC/B,IAAI,EAAE,OAAO,CAAA;IACb,gCAAgC;IAChC,OAAO,EAAE,OAAO,CAAA;IAChB,kCAAkC;IAClC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,6BAA6B;IAC7B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,aAAa;IACb,CAAC,EAAE,WAAW,CAAC,SAAS,CAAC,CAAA;IACzB,0BAA0B;IAC1B,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;IAC9B,+BAA+B;IAC/B,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1C,4DAA4D;IAC5D,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC9B;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,YAAY,CAyIjE"}