@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.
- package/LICENSE +21 -0
- package/README.md +91 -0
- package/cordis.patch.yml +6 -0
- package/lib/client/RefLibBrowser.d.ts +35 -0
- package/lib/client/RefLibBrowser.d.ts.map +1 -0
- package/lib/client/RefLibBrowser.js +119 -0
- package/lib/client/RefLibBrowser.js.map +1 -0
- package/lib/client/RefLibDock.d.ts +44 -0
- package/lib/client/RefLibDock.d.ts.map +1 -0
- package/lib/client/RefLibDock.js +218 -0
- package/lib/client/RefLibDock.js.map +1 -0
- package/lib/client/RefLibPanel.d.ts +47 -0
- package/lib/client/RefLibPanel.d.ts.map +1 -0
- package/lib/client/RefLibPanel.js +59 -0
- package/lib/client/RefLibPanel.js.map +1 -0
- package/lib/client/data.d.ts +53 -0
- package/lib/client/data.d.ts.map +1 -0
- package/lib/client/data.js +74 -0
- package/lib/client/data.js.map +1 -0
- package/lib/client/index.d.ts +32 -0
- package/lib/client/index.d.ts.map +1 -0
- package/lib/client/index.js +80 -0
- package/lib/client/index.js.map +1 -0
- package/lib/client/layout.d.ts +34 -0
- package/lib/client/layout.d.ts.map +1 -0
- package/lib/client/layout.js +65 -0
- package/lib/client/layout.js.map +1 -0
- package/lib/client/locales.d.ts +80 -0
- package/lib/client/locales.d.ts.map +1 -0
- package/lib/client/locales.js +84 -0
- package/lib/client/locales.js.map +1 -0
- package/lib/client/styles.d.ts +15 -0
- package/lib/client/styles.d.ts.map +1 -0
- package/lib/client/styles.js +513 -0
- package/lib/client/styles.js.map +1 -0
- package/lib/client.js +1377 -0
- package/lib/client.js.map +1 -0
- package/lib/commands.d.ts +38 -0
- package/lib/commands.d.ts.map +1 -0
- package/lib/commands.js +49 -0
- package/lib/commands.js.map +1 -0
- package/lib/index.d.ts +36 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +94 -0
- package/lib/index.js.map +1 -0
- package/lib/logic.d.ts +32 -0
- package/lib/logic.d.ts.map +1 -0
- package/lib/logic.js +48 -0
- package/lib/logic.js.map +1 -0
- package/lib/render.d.ts +18 -0
- package/lib/render.d.ts.map +1 -0
- package/lib/render.js +40 -0
- package/lib/render.js.map +1 -0
- package/lib/routes.d.ts +39 -0
- package/lib/routes.d.ts.map +1 -0
- package/lib/routes.js +210 -0
- package/lib/routes.js.map +1 -0
- package/lib/service.d.ts +88 -0
- package/lib/service.d.ts.map +1 -0
- package/lib/service.js +212 -0
- package/lib/service.js.map +1 -0
- package/lib/spec.d.ts +33 -0
- package/lib/spec.d.ts.map +1 -0
- package/lib/spec.js +13 -0
- package/lib/spec.js.map +1 -0
- package/lib/validate.d.ts +17 -0
- package/lib/validate.d.ts.map +1 -0
- package/lib/validate.js +35 -0
- package/lib/validate.js.map +1 -0
- package/package.json +64 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* 参考库管理面板(Modal):列表(基名 + 全路径、移除操作)+ 添加表单。
|
|
4
|
+
*
|
|
5
|
+
* 设计(优化点 1/2):全部样式走 “--dsw-*” 设计令牌(随浅/深主题适配),
|
|
6
|
+
* 列表行以「基名为主行、完整路径为次行」呈现,移除为带危险 hover 的图标按钮,
|
|
7
|
+
* 添加为主按钮 + 路径输入(支持直接粘贴路径,绕开卡顿的系统选择器)+ 系统选择器
|
|
8
|
+
* 兜底;空态/加载态/错误态各有独立视觉。文案全部经 `t` 本地化(zh/en)。
|
|
9
|
+
* 本组件为纯展示:异步操作与错误归集由 RefLibDock 持有。
|
|
10
|
+
* @module @hpyperry/dsh-ref-lib/src/client/RefLibPanel
|
|
11
|
+
*/
|
|
12
|
+
import { useEffect, useState } from 'react';
|
|
13
|
+
import { Button, IconFolderOpen16, IconLoadingOutline16, IconPlusOutline16, IconSearchOutline16, IconTrashOutline16, IconWarningOutline16, Input, Modal, Tooltip, } from '@deepseek-ai/dsh-client-ui-primitives';
|
|
14
|
+
import { libBasename } from "./data.js";
|
|
15
|
+
/**
|
|
16
|
+
* 渲染参考库管理面板。
|
|
17
|
+
* @param props - 见 {@link RefLibPanelProps}。
|
|
18
|
+
* @returns 对话框元素(关闭时 Modal 返回 null)。
|
|
19
|
+
*/
|
|
20
|
+
export function RefLibPanel(props) {
|
|
21
|
+
const { open, onClose, libs, loading, busy, picking, removingId, error, t, onRemove, onAddPath, onBrowse } = props;
|
|
22
|
+
const [draft, setDraft] = useState('');
|
|
23
|
+
// 面板关闭时清空输入草稿:每次打开都是干净的添加表单(失败保留输入的行为只限于面板打开期间)。
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
if (!open)
|
|
26
|
+
setDraft('');
|
|
27
|
+
}, [open]);
|
|
28
|
+
const handleSubmit = async () => {
|
|
29
|
+
const trimmed = draft.trim();
|
|
30
|
+
if (trimmed === '')
|
|
31
|
+
return;
|
|
32
|
+
try {
|
|
33
|
+
await onAddPath(trimmed);
|
|
34
|
+
setDraft('');
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
/* 错误由父组件在统一错误槽展示;输入保留以便修正 */
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
return (_jsx(Modal, { open: open, onClose: onClose, title: t('panel.title'), closeLabel: t('panel.close'), description: t('panel.description', { count: String(libs.length) }), 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 })] })), 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('list.loading') })] })) : libs.length === 0 ? (_jsxs("div", { className: "reflib-status", children: [_jsx(IconFolderOpen16, { size: 22, className: "reflib-statusIcon" }), _jsx("span", { className: "reflib-statusText", children: t('list.empty') }), _jsx("span", { className: "reflib-statusHint", children: t('list.empty.hint') })] })) : (_jsx("div", { className: "reflib-list", children: libs.map((entry) => {
|
|
41
|
+
const name = libBasename(entry.path);
|
|
42
|
+
const removing = removingId === entry.id;
|
|
43
|
+
return (_jsxs("div", { className: "reflib-row", "data-removing": removing || undefined, children: [_jsx(IconFolderOpen16, { size: 16, className: "reflib-rowIcon" }), _jsxs("div", { className: "reflib-rowBody", children: [_jsx("span", { className: "reflib-rowName", title: entry.path, children: name }), _jsx("span", { className: "reflib-rowPath", title: entry.path, children: entry.path })] }), _jsx(Tooltip, { label: t('list.remove'), side: "top", delayMs: 400, children: _jsx("button", { type: "button", className: "reflib-rowRemove", "aria-label": t('list.remove.aria', { name }), disabled: busy || removingId !== null, onClick: () => {
|
|
44
|
+
onRemove(entry.id);
|
|
45
|
+
}, children: removing ? (_jsx(IconLoadingOutline16, { size: 14, className: "reflib-spin" })) : (_jsx(IconTrashOutline16, { size: 14 })) }) })] }, entry.id));
|
|
46
|
+
}) })), _jsx("div", { className: "reflib-divider" }), _jsxs("div", { className: "reflib-add", children: [_jsx("span", { className: "reflib-addLabel", children: t('add.label') }), _jsx(Button, { variant: "primary", className: "reflib-addBrowseMain", icon: _jsx(IconSearchOutline16, { size: 16 }), disabled: busy || picking, onClick: () => {
|
|
47
|
+
void onBrowse();
|
|
48
|
+
}, children: t('add.browse') }), _jsxs("div", { className: "reflib-addManual", children: [_jsx("span", { className: "reflib-addManualLabel", children: t('add.manual') }), _jsxs("div", { className: "reflib-addRow", children: [_jsx(Input, { className: "reflib-addInputWrap", value: draft, placeholder: t('add.placeholder'), "aria-label": t('add.label'), disabled: busy || picking, onChange: (event) => {
|
|
49
|
+
setDraft(event.currentTarget.value);
|
|
50
|
+
}, onKeyDown: (event) => {
|
|
51
|
+
if (event.key === 'Enter' && !event.nativeEvent.isComposing) {
|
|
52
|
+
event.preventDefault();
|
|
53
|
+
void handleSubmit();
|
|
54
|
+
}
|
|
55
|
+
} }), _jsx(Button, { variant: "primary", size: "sm", icon: _jsx(IconPlusOutline16, { size: 14 }), disabled: busy || picking || draft.trim() === '', onClick: () => {
|
|
56
|
+
void handleSubmit();
|
|
57
|
+
}, children: t('add.submit') })] })] }), _jsx("span", { className: "reflib-addHint", children: t('add.hint') })] })] }) }));
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=RefLibPanel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RefLibPanel.js","sourceRoot":"","sources":["../../src/client/RefLibPanel.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* client 端数据纯函数:/api/ref-lib/* 路由响应解析、错误码解析与路径展示。
|
|
3
|
+
* 独立于 React / runtime,便于单元测试。
|
|
4
|
+
*
|
|
5
|
+
* v5:路由错误响应新增 wire code(ref-lib/missing 等),client 据此把
|
|
6
|
+
* node 端的中文错误消息映射为当前语言的本地化文案(优化点 2 的语言适配)。
|
|
7
|
+
* @module @hpyperry/dsh-ref-lib/src/client/data
|
|
8
|
+
*/
|
|
9
|
+
import type { RefLibEntry } from '../spec.ts';
|
|
10
|
+
/** 路由错误载荷里的附加字段。 */
|
|
11
|
+
export interface RefLibApiErrorDetails {
|
|
12
|
+
/** 出错的目录路径(missing/not-directory/unsafe)。 */
|
|
13
|
+
readonly path?: string;
|
|
14
|
+
/** 未找到的条目 id(unknown-id)。 */
|
|
15
|
+
readonly id?: string;
|
|
16
|
+
}
|
|
17
|
+
/** 带 wire code 的 API 错误:code 用于本地化文案映射,message 为原始消息兜底。 */
|
|
18
|
+
export declare class RefLibApiError extends Error {
|
|
19
|
+
readonly code: string;
|
|
20
|
+
readonly details: RefLibApiErrorDetails;
|
|
21
|
+
/**
|
|
22
|
+
* @param code - wire 错误码(如 ref-lib/missing)。
|
|
23
|
+
* @param message - 服务端原始错误消息。
|
|
24
|
+
* @param details - 附加字段(path/id)。
|
|
25
|
+
*/
|
|
26
|
+
constructor(code: string, message: string, details?: RefLibApiErrorDetails);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* 从失败的 /api/ref-lib/* 响应体解析错误码;无 code 的畸形体返回 null。
|
|
30
|
+
* @param value - 非 2xx 响应体(可为任意 JSON)。
|
|
31
|
+
* @returns 错误码 + 原始消息 + 附加字段;无法解析时为 null。
|
|
32
|
+
*/
|
|
33
|
+
export declare function parseApiErrorPayload(value: unknown): {
|
|
34
|
+
code: string;
|
|
35
|
+
message: string;
|
|
36
|
+
details: RefLibApiErrorDetails;
|
|
37
|
+
} | null;
|
|
38
|
+
/**
|
|
39
|
+
* 从 /api/ref-lib/list 路由响应({ libs: [...] })解析参考库列表;
|
|
40
|
+
* 缺失/畸形返回空列表。
|
|
41
|
+
* @param value - 路由响应体。
|
|
42
|
+
* @returns 当前参考库列表。
|
|
43
|
+
*/
|
|
44
|
+
export declare function parseLibsPayload(value: unknown): RefLibEntry[];
|
|
45
|
+
/**
|
|
46
|
+
* 提取目录路径的展示用基名(列表行主行的可读标题)。
|
|
47
|
+
* 兼容 POSIX 与 Windows 分隔符;去掉尾部分隔符后取最后一段;
|
|
48
|
+
* 根路径(/、C:\)原样返回。
|
|
49
|
+
* @param path - 规范化绝对路径。
|
|
50
|
+
* @returns 基名(如 /a/b/core → core)。
|
|
51
|
+
*/
|
|
52
|
+
export declare function libBasename(path: string): string;
|
|
53
|
+
//# sourceMappingURL=data.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data.d.ts","sourceRoot":"","sources":["../../src/client/data.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAG7C,oBAAoB;AACpB,MAAM,WAAW,qBAAqB;IACpC,6CAA6C;IAC7C,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;IACtB,6BAA6B;IAC7B,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,2DAA2D;AAC3D,qBAAa,cAAe,SAAQ,KAAK;IAOrC,QAAQ,CAAC,IAAI,EAAE,MAAM;IAErB,QAAQ,CAAC,OAAO,EAAE,qBAAqB;IARzC;;;;OAIG;gBAEQ,IAAI,EAAE,MAAM,EACrB,OAAO,EAAE,MAAM,EACN,OAAO,GAAE,qBAA0B;CAK/C;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG;IACpD,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,qBAAqB,CAAA;CAC/B,GAAG,IAAI,CAcP;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,EAAE,CAK9D;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAOhD"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* client 端数据纯函数:/api/ref-lib/* 路由响应解析、错误码解析与路径展示。
|
|
3
|
+
* 独立于 React / runtime,便于单元测试。
|
|
4
|
+
*
|
|
5
|
+
* v5:路由错误响应新增 wire code(ref-lib/missing 等),client 据此把
|
|
6
|
+
* node 端的中文错误消息映射为当前语言的本地化文案(优化点 2 的语言适配)。
|
|
7
|
+
* @module @hpyperry/dsh-ref-lib/src/client/data
|
|
8
|
+
*/
|
|
9
|
+
import { isRefLibEntry } from "../validate.js";
|
|
10
|
+
/** 带 wire code 的 API 错误:code 用于本地化文案映射,message 为原始消息兜底。 */
|
|
11
|
+
export class RefLibApiError extends Error {
|
|
12
|
+
code;
|
|
13
|
+
details;
|
|
14
|
+
/**
|
|
15
|
+
* @param code - wire 错误码(如 ref-lib/missing)。
|
|
16
|
+
* @param message - 服务端原始错误消息。
|
|
17
|
+
* @param details - 附加字段(path/id)。
|
|
18
|
+
*/
|
|
19
|
+
constructor(code, message, details = {}) {
|
|
20
|
+
super(message);
|
|
21
|
+
this.code = code;
|
|
22
|
+
this.details = details;
|
|
23
|
+
this.name = 'RefLibApiError';
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* 从失败的 /api/ref-lib/* 响应体解析错误码;无 code 的畸形体返回 null。
|
|
28
|
+
* @param value - 非 2xx 响应体(可为任意 JSON)。
|
|
29
|
+
* @returns 错误码 + 原始消息 + 附加字段;无法解析时为 null。
|
|
30
|
+
*/
|
|
31
|
+
export function parseApiErrorPayload(value) {
|
|
32
|
+
if (typeof value !== 'object' || value === null)
|
|
33
|
+
return null;
|
|
34
|
+
const { error, code, path, id } = value;
|
|
35
|
+
if (typeof code !== 'string' || code === '')
|
|
36
|
+
return null;
|
|
37
|
+
const details = {
|
|
38
|
+
...(typeof path === 'string' ? { path } : {}),
|
|
39
|
+
...(typeof id === 'string' ? { id } : {}),
|
|
40
|
+
};
|
|
41
|
+
return { code, message: typeof error === 'string' ? error : code, details };
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* 从 /api/ref-lib/list 路由响应({ libs: [...] })解析参考库列表;
|
|
45
|
+
* 缺失/畸形返回空列表。
|
|
46
|
+
* @param value - 路由响应体。
|
|
47
|
+
* @returns 当前参考库列表。
|
|
48
|
+
*/
|
|
49
|
+
export function parseLibsPayload(value) {
|
|
50
|
+
if (typeof value !== 'object' || value === null)
|
|
51
|
+
return [];
|
|
52
|
+
const libs = value.libs;
|
|
53
|
+
if (!Array.isArray(libs))
|
|
54
|
+
return [];
|
|
55
|
+
return libs.filter(isRefLibEntry);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* 提取目录路径的展示用基名(列表行主行的可读标题)。
|
|
59
|
+
* 兼容 POSIX 与 Windows 分隔符;去掉尾部分隔符后取最后一段;
|
|
60
|
+
* 根路径(/、C:\)原样返回。
|
|
61
|
+
* @param path - 规范化绝对路径。
|
|
62
|
+
* @returns 基名(如 /a/b/core → core)。
|
|
63
|
+
*/
|
|
64
|
+
export function libBasename(path) {
|
|
65
|
+
const trimmed = path.replace(/[\\/]+$/, '');
|
|
66
|
+
if (trimmed === '')
|
|
67
|
+
return path;
|
|
68
|
+
// Windows 盘符根(C:)不是基名,原样返回带分隔符的根路径(C:\\)。
|
|
69
|
+
if (/^[A-Za-z]:$/.test(trimmed))
|
|
70
|
+
return path;
|
|
71
|
+
const idx = Math.max(trimmed.lastIndexOf('/'), trimmed.lastIndexOf('\\'));
|
|
72
|
+
return idx === -1 ? trimmed : trimmed.slice(idx + 1);
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=data.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data.js","sourceRoot":"","sources":["../../src/client/data.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAU9C,2DAA2D;AAC3D,MAAM,OAAO,cAAe,SAAQ,KAAK;IAO5B;IAEA;IARX;;;;OAIG;IACH,YACW,IAAY,EACrB,OAAe,EACN,UAAiC,EAAE;QAE5C,KAAK,CAAC,OAAO,CAAC,CAAA;QAJL,SAAI,GAAJ,IAAI,CAAQ;QAEZ,YAAO,GAAP,OAAO,CAA4B;QAG5C,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAA;IAC9B,CAAC;CACF;AAED;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAAc;IAKjD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,IAAI,CAAA;IAC5D,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,KAKjC,CAAA;IACD,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,EAAE;QAAE,OAAO,IAAI,CAAA;IACxD,MAAM,OAAO,GAA0B;QACrC,GAAG,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7C,GAAG,CAAC,OAAO,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC1C,CAAA;IACD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,CAAA;AAC7E,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,EAAE,CAAA;IAC1D,MAAM,IAAI,GAAI,KAA4B,CAAC,IAAI,CAAA;IAC/C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,CAAA;IACnC,OAAO,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,CAAA;AACnC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAA;IAC3C,IAAI,OAAO,KAAK,EAAE;QAAE,OAAO,IAAI,CAAA;IAC/B,0CAA0C;IAC1C,IAAI,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAA;IAC5C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAA;IACzE,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAA;AACtD,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ref-lib client 插件(浏览器端):在输入框上方(conversation.input.dock)
|
|
3
|
+
* 注册「参考库」入口,提供 per-session 的 UI 交互式管理。
|
|
4
|
+
*
|
|
5
|
+
* 入口位置(v7):注册在输入框上方(conversation.input.dock)槽位,胶囊渲染在
|
|
6
|
+
* 输入卡正上方的独立一行,经 CSS 令牌与输入卡左缘对齐——hero(新会话)与 active
|
|
7
|
+
* (具体对话)统一可见、零测量、零竞态,新建会话一开始即可注入参考库。
|
|
8
|
+
*
|
|
9
|
+
* 数据通道(v4/v5):client 经**普通同源 fetch** 访问插件在宿主 `ctx.webServer`
|
|
10
|
+
* 上自注册的 /api/ref-lib/* HTTP 路由(node 端读写 sidecar)——静默双向、
|
|
11
|
+
* 不渲染命令卡片、不执行命令、不产生用户消息。路由 loopback-only 护栏见
|
|
12
|
+
* `src/routes.ts`。目录选择走 `ctx.workspaces.pickDirectory()`(host 原生 OS
|
|
13
|
+
* 选择器),另提供路径输入直加(优化点 2:绕开卡顿的原生对话框)。
|
|
14
|
+
* 文案经 `ctx.locale` 全量本地化(zh/en,优化点 2)。
|
|
15
|
+
* @module @hpyperry/dsh-ref-lib/src/client
|
|
16
|
+
*/
|
|
17
|
+
import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client';
|
|
18
|
+
import { type RefLibKey } from './locales.ts';
|
|
19
|
+
/** 所需服务(cordis fiber inject)。 */
|
|
20
|
+
export declare const inject: string[];
|
|
21
|
+
declare module '@deepseek-ai/dsh-client-ui-slots' {
|
|
22
|
+
interface LocaleNamespaceMap {
|
|
23
|
+
/** ref-lib 面板/入口文案。 */
|
|
24
|
+
'ref-lib': RefLibKey;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* 注册输入框上方的「参考库」入口与管理面板。
|
|
29
|
+
* @param ctx - client 根上下文。
|
|
30
|
+
*/
|
|
31
|
+
export declare function apply(ctx: ClientContext): void;
|
|
32
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAa,MAAM,wCAAwC,CAAA;AAStF,OAAO,EAAU,KAAK,SAAS,EAAE,MAAM,cAAc,CAAA;AAErD,iCAAiC;AACjC,eAAO,MAAM,MAAM,UAAoC,CAAA;AAKvD,OAAO,QAAQ,kCAAkC,CAAC;IAChD,UAAU,kBAAkB;QAC1B,uBAAuB;QACvB,SAAS,EAAE,SAAS,CAAA;KACrB;CACF;AAgCD;;;GAGG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CAiC9C"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ref-lib client 插件(浏览器端):在输入框上方(conversation.input.dock)
|
|
3
|
+
* 注册「参考库」入口,提供 per-session 的 UI 交互式管理。
|
|
4
|
+
*
|
|
5
|
+
* 入口位置(v7):注册在输入框上方(conversation.input.dock)槽位,胶囊渲染在
|
|
6
|
+
* 输入卡正上方的独立一行,经 CSS 令牌与输入卡左缘对齐——hero(新会话)与 active
|
|
7
|
+
* (具体对话)统一可见、零测量、零竞态,新建会话一开始即可注入参考库。
|
|
8
|
+
*
|
|
9
|
+
* 数据通道(v4/v5):client 经**普通同源 fetch** 访问插件在宿主 `ctx.webServer`
|
|
10
|
+
* 上自注册的 /api/ref-lib/* HTTP 路由(node 端读写 sidecar)——静默双向、
|
|
11
|
+
* 不渲染命令卡片、不执行命令、不产生用户消息。路由 loopback-only 护栏见
|
|
12
|
+
* `src/routes.ts`。目录选择走 `ctx.workspaces.pickDirectory()`(host 原生 OS
|
|
13
|
+
* 选择器),另提供路径输入直加(优化点 2:绕开卡顿的原生对话框)。
|
|
14
|
+
* 文案经 `ctx.locale` 全量本地化(zh/en,优化点 2)。
|
|
15
|
+
* @module @hpyperry/dsh-ref-lib/src/client
|
|
16
|
+
*/
|
|
17
|
+
import { parseApiErrorPayload, parseLibsPayload, RefLibApiError } from "./data.js";
|
|
18
|
+
import { RefLibDock } from "./RefLibDock.js";
|
|
19
|
+
import { zh, en } from "./locales.js";
|
|
20
|
+
/** 所需服务(cordis fiber inject)。 */
|
|
21
|
+
export const inject = ['slots', 'workspaces', 'locale'];
|
|
22
|
+
/** 本插件文案命名空间。 */
|
|
23
|
+
const NS = 'ref-lib';
|
|
24
|
+
/**
|
|
25
|
+
* 一条对宿主 /api/ref-lib 路由族的 JSON 调用;失败时优先抛出带 wire code 的
|
|
26
|
+
* RefLibApiError(用于本地化),无 code 时回退普通 Error。
|
|
27
|
+
*/
|
|
28
|
+
async function api(path, payload, method = 'POST') {
|
|
29
|
+
const res = await fetch('/api/ref-lib' + path, payload === undefined
|
|
30
|
+
? undefined
|
|
31
|
+
: {
|
|
32
|
+
method,
|
|
33
|
+
headers: { 'content-type': 'application/json' },
|
|
34
|
+
body: JSON.stringify(payload),
|
|
35
|
+
});
|
|
36
|
+
let body = null;
|
|
37
|
+
try {
|
|
38
|
+
body = await res.json();
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
/* non-JSON error body */
|
|
42
|
+
}
|
|
43
|
+
if (!res.ok) {
|
|
44
|
+
const parsed = parseApiErrorPayload(body);
|
|
45
|
+
if (parsed !== null)
|
|
46
|
+
throw new RefLibApiError(parsed.code, parsed.message, parsed.details);
|
|
47
|
+
const message = body?.error ?? 'HTTP ' + res.status;
|
|
48
|
+
throw new Error(typeof message === 'string' ? message : String(message));
|
|
49
|
+
}
|
|
50
|
+
return body;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* 注册输入框上方的「参考库」入口与管理面板。
|
|
54
|
+
* @param ctx - client 根上下文。
|
|
55
|
+
*/
|
|
56
|
+
export function apply(ctx) {
|
|
57
|
+
// 注册本插件文案命名空间(zh/en 逐键对齐,编译期校验)。
|
|
58
|
+
ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'ref-lib: dictionaries');
|
|
59
|
+
const injected = () => ({
|
|
60
|
+
load: async (sessionId) => parseLibsPayload(await api(`/list?session=${encodeURIComponent(sessionId)}`, undefined, 'GET')),
|
|
61
|
+
add: async (sessionId, path) => {
|
|
62
|
+
await api('/add', { session: sessionId, path });
|
|
63
|
+
},
|
|
64
|
+
remove: async (sessionId, id) => {
|
|
65
|
+
await api('/remove', { session: sessionId, id });
|
|
66
|
+
},
|
|
67
|
+
pickDirectory: () => ctx.workspaces.pickDirectory(),
|
|
68
|
+
listDirectory: (path, signal) => ctx.workspaces.listDirectory(path, signal),
|
|
69
|
+
});
|
|
70
|
+
ctx.slots.inject('conversation.input.dock', () => ctx.slots.register({
|
|
71
|
+
name: 'conversation.input.dock',
|
|
72
|
+
id: 'ref-lib',
|
|
73
|
+
// 排在最后面(goal 10 / queue 20 / git-graph 100 等之后):不与其他插件
|
|
74
|
+
// 的 dock 入口抢位置;独立一行流式堆叠,天然不重叠。
|
|
75
|
+
order: 200,
|
|
76
|
+
locale: NS,
|
|
77
|
+
inject: injected,
|
|
78
|
+
}, RefLibDock));
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ref-lib client 布局工具:hero 行测量定位用(优化点 1.1 的"排在模式之后")。
|
|
3
|
+
*
|
|
4
|
+
* paintedRight:求一棵子树里最右可见(painted)元素的右缘,排除整棵 exclude
|
|
5
|
+
* 子树(含其所有子孙)。注意排除必须覆盖整个子树——只排除根节点会让其子节点
|
|
6
|
+
* 泄漏进统计:hero 相位把胶囊绝对定位进官方 hero 行时,若把胶囊自身的右缘计入,
|
|
7
|
+
* 徽标数量变化使胶囊变宽会触发重测,导致胶囊每次添加后右移(v5.2 修复)。
|
|
8
|
+
* @module @dsh-plugins/ref-lib/src/client/layout
|
|
9
|
+
*/
|
|
10
|
+
/** paintedRight 需要的最小节点形状(真实 Element 结构上满足,便于单测注入假 DOM)。 */
|
|
11
|
+
interface PaintedNode {
|
|
12
|
+
readonly children: Iterable<PaintedNode>;
|
|
13
|
+
getBoundingClientRect(): {
|
|
14
|
+
readonly width: number;
|
|
15
|
+
readonly height: number;
|
|
16
|
+
readonly right: number;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* 一棵子树里最右的可见元素右缘(排除整棵 exclude 子树);无可见节点返回 null。
|
|
21
|
+
* 官方 hero 行的直接子节点可能是 display:contents 的 slot 出口,可见边界必须递归
|
|
22
|
+
* 查找(先例:dsh-web-ui 的 git-graph BranchChip)。
|
|
23
|
+
* @param root - 遍历起点(其自身不计入)。
|
|
24
|
+
* @param exclude - 需要整体排除的子树(如本插件的胶囊锚点)。
|
|
25
|
+
* @returns 最右可见元素右缘,或 null。
|
|
26
|
+
*/
|
|
27
|
+
export declare function paintedRight(root: PaintedNode, exclude?: PaintedNode): number | null;
|
|
28
|
+
/** 把重复的放置更新合并到一帧(观察器突发同帧只测一次;无 rAF 时同步执行)。 */
|
|
29
|
+
export declare function frameScheduler(update: () => void): {
|
|
30
|
+
schedule: () => void;
|
|
31
|
+
cancel: () => void;
|
|
32
|
+
};
|
|
33
|
+
export {};
|
|
34
|
+
//# sourceMappingURL=layout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../src/client/layout.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,4DAA4D;AAC5D,UAAU,WAAW;IACnB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAA;IACxC,qBAAqB,IAAI;QAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAA;CACrG;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,IAAI,CAepF;AAED,8CAA8C;AAC9C,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,IAAI,GAAG;IAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,IAAI,CAAA;CAAE,CAwB/F"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ref-lib client 布局工具:hero 行测量定位用(优化点 1.1 的"排在模式之后")。
|
|
3
|
+
*
|
|
4
|
+
* paintedRight:求一棵子树里最右可见(painted)元素的右缘,排除整棵 exclude
|
|
5
|
+
* 子树(含其所有子孙)。注意排除必须覆盖整个子树——只排除根节点会让其子节点
|
|
6
|
+
* 泄漏进统计:hero 相位把胶囊绝对定位进官方 hero 行时,若把胶囊自身的右缘计入,
|
|
7
|
+
* 徽标数量变化使胶囊变宽会触发重测,导致胶囊每次添加后右移(v5.2 修复)。
|
|
8
|
+
* @module @dsh-plugins/ref-lib/src/client/layout
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* 一棵子树里最右的可见元素右缘(排除整棵 exclude 子树);无可见节点返回 null。
|
|
12
|
+
* 官方 hero 行的直接子节点可能是 display:contents 的 slot 出口,可见边界必须递归
|
|
13
|
+
* 查找(先例:dsh-web-ui 的 git-graph BranchChip)。
|
|
14
|
+
* @param root - 遍历起点(其自身不计入)。
|
|
15
|
+
* @param exclude - 需要整体排除的子树(如本插件的胶囊锚点)。
|
|
16
|
+
* @returns 最右可见元素右缘,或 null。
|
|
17
|
+
*/
|
|
18
|
+
export function paintedRight(root, exclude) {
|
|
19
|
+
let right = null;
|
|
20
|
+
const visit = (node) => {
|
|
21
|
+
if (node !== root && node !== exclude) {
|
|
22
|
+
const rect = node.getBoundingClientRect();
|
|
23
|
+
if (rect.width > 0 && rect.height > 0) {
|
|
24
|
+
right = right === null ? rect.right : Math.max(right, rect.right);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
// 排除整棵子树:不进其子孙,避免锚点自身(含数量徽标)宽度变化影响定位
|
|
28
|
+
if (node === exclude)
|
|
29
|
+
return;
|
|
30
|
+
for (const child of node.children)
|
|
31
|
+
visit(child);
|
|
32
|
+
};
|
|
33
|
+
visit(root);
|
|
34
|
+
return right;
|
|
35
|
+
}
|
|
36
|
+
/** 把重复的放置更新合并到一帧(观察器突发同帧只测一次;无 rAF 时同步执行)。 */
|
|
37
|
+
export function frameScheduler(update) {
|
|
38
|
+
let pending = false;
|
|
39
|
+
let frame = null;
|
|
40
|
+
const flush = () => {
|
|
41
|
+
pending = false;
|
|
42
|
+
frame = null;
|
|
43
|
+
update();
|
|
44
|
+
};
|
|
45
|
+
return {
|
|
46
|
+
schedule: () => {
|
|
47
|
+
if (pending)
|
|
48
|
+
return;
|
|
49
|
+
pending = true;
|
|
50
|
+
if (typeof requestAnimationFrame === 'function') {
|
|
51
|
+
frame = requestAnimationFrame(flush);
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
flush();
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
cancel: () => {
|
|
58
|
+
pending = false;
|
|
59
|
+
if (frame !== null)
|
|
60
|
+
cancelAnimationFrame(frame);
|
|
61
|
+
frame = null;
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=layout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layout.js","sourceRoot":"","sources":["../../src/client/layout.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAQH;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAC,IAAiB,EAAE,OAAqB;IACnE,IAAI,KAAK,GAAkB,IAAI,CAAA;IAC/B,MAAM,KAAK,GAAG,CAAC,IAAiB,EAAQ,EAAE;QACxC,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;YACtC,MAAM,IAAI,GAAG,IAAI,CAAC,qBAAqB,EAAE,CAAA;YACzC,IAAI,IAAI,CAAC,KAAK,GAAG,CAAC,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACtC,KAAK,GAAG,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAA;YACnE,CAAC;QACH,CAAC;QACD,qCAAqC;QACrC,IAAI,IAAI,KAAK,OAAO;YAAE,OAAM;QAC5B,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ;YAAE,KAAK,CAAC,KAAK,CAAC,CAAA;IACjD,CAAC,CAAA;IACD,KAAK,CAAC,IAAI,CAAC,CAAA;IACX,OAAO,KAAK,CAAA;AACd,CAAC;AAED,8CAA8C;AAC9C,MAAM,UAAU,cAAc,CAAC,MAAkB;IAC/C,IAAI,OAAO,GAAG,KAAK,CAAA;IACnB,IAAI,KAAK,GAAkB,IAAI,CAAA;IAC/B,MAAM,KAAK,GAAG,GAAS,EAAE;QACvB,OAAO,GAAG,KAAK,CAAA;QACf,KAAK,GAAG,IAAI,CAAA;QACZ,MAAM,EAAE,CAAA;IACV,CAAC,CAAA;IACD,OAAO;QACL,QAAQ,EAAE,GAAG,EAAE;YACb,IAAI,OAAO;gBAAE,OAAM;YACnB,OAAO,GAAG,IAAI,CAAA;YACd,IAAI,OAAO,qBAAqB,KAAK,UAAU,EAAE,CAAC;gBAChD,KAAK,GAAG,qBAAqB,CAAC,KAAK,CAAC,CAAA;YACtC,CAAC;iBAAM,CAAC;gBACN,KAAK,EAAE,CAAA;YACT,CAAC;QACH,CAAC;QACD,MAAM,EAAE,GAAG,EAAE;YACX,OAAO,GAAG,KAAK,CAAA;YACf,IAAI,KAAK,KAAK,IAAI;gBAAE,oBAAoB,CAAC,KAAK,CAAC,CAAA;YAC/C,KAAK,GAAG,IAAI,CAAA;QACd,CAAC;KACF,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ref-lib client 本地化字典(zh 为键集唯一来源,en 与之逐键对齐)。
|
|
3
|
+
*
|
|
4
|
+
* 语言适配(优化点 2):面板、入口胶囊与添加表单的全部文案经
|
|
5
|
+
* `ctx.locale.register(NS, { zh, en })` 注册,槽位注册声明 `locale: NS`,
|
|
6
|
+
* 组件经框架注入的 `t` seat 取词(活动语言实时切换,缺省回退 zh)。
|
|
7
|
+
* 键对等由 `satisfies Record<RefLibKey, string>` 在编译期强制。
|
|
8
|
+
* @module @hpyperry/dsh-ref-lib/src/client/locales
|
|
9
|
+
*/
|
|
10
|
+
/** 简体中文字典(键集唯一来源)。 */
|
|
11
|
+
export declare const zh: {
|
|
12
|
+
'dock.label': string;
|
|
13
|
+
'dock.aria': string;
|
|
14
|
+
'dock.count.aria': string;
|
|
15
|
+
'panel.title': string;
|
|
16
|
+
'panel.close': string;
|
|
17
|
+
'panel.description': string;
|
|
18
|
+
'list.remove': string;
|
|
19
|
+
'list.remove.aria': string;
|
|
20
|
+
'list.empty': string;
|
|
21
|
+
'list.empty.hint': string;
|
|
22
|
+
'list.loading': string;
|
|
23
|
+
'add.label': string;
|
|
24
|
+
'add.placeholder': string;
|
|
25
|
+
'add.submit': string;
|
|
26
|
+
'add.manual': string;
|
|
27
|
+
'add.browse': string;
|
|
28
|
+
'add.hint': string;
|
|
29
|
+
'browser.title': string;
|
|
30
|
+
'browser.home': string;
|
|
31
|
+
'browser.open': string;
|
|
32
|
+
'browser.open.aria': string;
|
|
33
|
+
'browser.enter.aria': string;
|
|
34
|
+
'browser.editPath': string;
|
|
35
|
+
'browser.pathPlaceholder': string;
|
|
36
|
+
'browser.empty': string;
|
|
37
|
+
'browser.loading': string;
|
|
38
|
+
'browser.cancel': string;
|
|
39
|
+
'error.missing': string;
|
|
40
|
+
'error.notDirectory': string;
|
|
41
|
+
'error.unsafe': string;
|
|
42
|
+
'error.unknownId': string;
|
|
43
|
+
};
|
|
44
|
+
/** ref-lib 命名空间的键集。 */
|
|
45
|
+
export type RefLibKey = keyof typeof zh;
|
|
46
|
+
/** 英文词典,与 zh 键集逐键对齐(编译期校验)。 */
|
|
47
|
+
export declare const en: {
|
|
48
|
+
'dock.label': string;
|
|
49
|
+
'dock.aria': string;
|
|
50
|
+
'dock.count.aria': string;
|
|
51
|
+
'panel.title': string;
|
|
52
|
+
'panel.close': string;
|
|
53
|
+
'panel.description': string;
|
|
54
|
+
'list.remove': string;
|
|
55
|
+
'list.remove.aria': string;
|
|
56
|
+
'list.empty': string;
|
|
57
|
+
'list.empty.hint': string;
|
|
58
|
+
'list.loading': string;
|
|
59
|
+
'add.label': string;
|
|
60
|
+
'add.placeholder': string;
|
|
61
|
+
'add.submit': string;
|
|
62
|
+
'add.manual': string;
|
|
63
|
+
'add.browse': string;
|
|
64
|
+
'add.hint': string;
|
|
65
|
+
'browser.title': string;
|
|
66
|
+
'browser.home': string;
|
|
67
|
+
'browser.open': string;
|
|
68
|
+
'browser.open.aria': string;
|
|
69
|
+
'browser.enter.aria': string;
|
|
70
|
+
'browser.editPath': string;
|
|
71
|
+
'browser.pathPlaceholder': string;
|
|
72
|
+
'browser.empty': string;
|
|
73
|
+
'browser.loading': string;
|
|
74
|
+
'browser.cancel': string;
|
|
75
|
+
'error.missing': string;
|
|
76
|
+
'error.notDirectory': string;
|
|
77
|
+
'error.unsafe': string;
|
|
78
|
+
'error.unknownId': string;
|
|
79
|
+
};
|
|
80
|
+
//# sourceMappingURL=locales.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"locales.d.ts","sourceRoot":"","sources":["../../src/client/locales.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,sBAAsB;AACtB,eAAO,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqCmB,CAAA;AAElC,uBAAuB;AACvB,MAAM,MAAM,SAAS,GAAG,MAAM,OAAO,EAAE,CAAA;AAEvC,+BAA+B;AAC/B,eAAO,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkCsB,CAAA"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ref-lib client 本地化字典(zh 为键集唯一来源,en 与之逐键对齐)。
|
|
3
|
+
*
|
|
4
|
+
* 语言适配(优化点 2):面板、入口胶囊与添加表单的全部文案经
|
|
5
|
+
* `ctx.locale.register(NS, { zh, en })` 注册,槽位注册声明 `locale: NS`,
|
|
6
|
+
* 组件经框架注入的 `t` seat 取词(活动语言实时切换,缺省回退 zh)。
|
|
7
|
+
* 键对等由 `satisfies Record<RefLibKey, string>` 在编译期强制。
|
|
8
|
+
* @module @hpyperry/dsh-ref-lib/src/client/locales
|
|
9
|
+
*/
|
|
10
|
+
/** 简体中文字典(键集唯一来源)。 */
|
|
11
|
+
export const zh = {
|
|
12
|
+
// ── 输入框上方入口胶囊(conversation.input.dock)──
|
|
13
|
+
'dock.label': '参考库',
|
|
14
|
+
'dock.aria': '管理只读参考库',
|
|
15
|
+
'dock.count.aria': '参考库,共 {count} 个',
|
|
16
|
+
// ── 管理面板 ──
|
|
17
|
+
'panel.title': '参考库',
|
|
18
|
+
'panel.close': '关闭',
|
|
19
|
+
'panel.description': '共 {count} 个只读参考库:供 agent 读取参考,禁止修改其中文件',
|
|
20
|
+
'list.remove': '移除',
|
|
21
|
+
'list.remove.aria': '移除参考库 {name}',
|
|
22
|
+
'list.empty': '还没有参考库',
|
|
23
|
+
'list.empty.hint': '在下方输入目录路径,或点击「选择目录」从系统选择',
|
|
24
|
+
'list.loading': '正在加载…',
|
|
25
|
+
// ── 添加表单 ──
|
|
26
|
+
'add.label': '添加参考库',
|
|
27
|
+
'add.placeholder': '输入目录路径(支持 ~ 与相对)',
|
|
28
|
+
'add.submit': '添加',
|
|
29
|
+
'add.manual': '或手动输入路径',
|
|
30
|
+
'add.browse': '选择目录',
|
|
31
|
+
'add.hint': '目录仅作只读参考;位于工作区之外时由系统强制只读',
|
|
32
|
+
// ── 应用内目录浏览器(browse 后端)──
|
|
33
|
+
'browser.title': '选择目录',
|
|
34
|
+
'browser.home': '主目录',
|
|
35
|
+
'browser.open': '选择此目录',
|
|
36
|
+
'browser.open.aria': '添加当前目录为参考库',
|
|
37
|
+
'browser.enter.aria': '进入目录 {name}',
|
|
38
|
+
'browser.editPath': '编辑路径',
|
|
39
|
+
'browser.pathPlaceholder': '输入绝对路径,回车跳转',
|
|
40
|
+
'browser.empty': '该目录下没有子目录',
|
|
41
|
+
'browser.loading': '加载中…',
|
|
42
|
+
'browser.cancel': '取消',
|
|
43
|
+
// ── 错误映射(wire code → 本地化文案)──
|
|
44
|
+
'error.missing': '目录不存在:{path}',
|
|
45
|
+
'error.notDirectory': '不是目录:{path}',
|
|
46
|
+
'error.unsafe': '路径包含控制字符,已拒绝:{path}',
|
|
47
|
+
'error.unknownId': '未找到参考库条目:{id}',
|
|
48
|
+
};
|
|
49
|
+
/** 英文词典,与 zh 键集逐键对齐(编译期校验)。 */
|
|
50
|
+
export const en = {
|
|
51
|
+
'dock.label': 'Reference Library',
|
|
52
|
+
'dock.aria': 'Manage read-only reference libraries',
|
|
53
|
+
'dock.count.aria': 'Reference library, {count} total',
|
|
54
|
+
'panel.title': 'Reference Library',
|
|
55
|
+
'panel.close': 'Close',
|
|
56
|
+
'panel.description': '{count} read-only reference libraries: the agent may read them for reference, but must not modify any files',
|
|
57
|
+
'list.remove': 'Remove',
|
|
58
|
+
'list.remove.aria': 'Remove reference library {name}',
|
|
59
|
+
'list.empty': 'No reference libraries yet',
|
|
60
|
+
'list.empty.hint': 'Enter a directory path below, or click “Choose directory” to pick one',
|
|
61
|
+
'list.loading': 'Loading…',
|
|
62
|
+
'add.label': 'Add a reference library',
|
|
63
|
+
'add.placeholder': 'Enter a directory path (~ or relative)',
|
|
64
|
+
'add.submit': 'Add',
|
|
65
|
+
'add.manual': 'or enter a path manually',
|
|
66
|
+
'add.browse': 'Choose directory',
|
|
67
|
+
'add.hint': 'Directories are read-only references; outside the workspace they are enforced read-only by the system',
|
|
68
|
+
// ── In-app directory browser (browse backend) ──
|
|
69
|
+
'browser.title': 'Select Directory',
|
|
70
|
+
'browser.home': 'Home',
|
|
71
|
+
'browser.open': 'Select this folder',
|
|
72
|
+
'browser.open.aria': 'Add the current directory as a reference library',
|
|
73
|
+
'browser.enter.aria': 'Open folder {name}',
|
|
74
|
+
'browser.editPath': 'Edit path',
|
|
75
|
+
'browser.pathPlaceholder': 'Type an absolute path and press Enter',
|
|
76
|
+
'browser.empty': 'No subdirectories here',
|
|
77
|
+
'browser.loading': 'Loading…',
|
|
78
|
+
'browser.cancel': 'Cancel',
|
|
79
|
+
'error.missing': 'Directory does not exist: {path}',
|
|
80
|
+
'error.notDirectory': 'Not a directory: {path}',
|
|
81
|
+
'error.unsafe': 'Path contains control characters and was rejected: {path}',
|
|
82
|
+
'error.unknownId': 'Reference library entry not found: {id}',
|
|
83
|
+
};
|
|
84
|
+
//# sourceMappingURL=locales.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"locales.js","sourceRoot":"","sources":["../../src/client/locales.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,sBAAsB;AACtB,MAAM,CAAC,MAAM,EAAE,GAAG;IAChB,0CAA0C;IAC1C,YAAY,EAAE,KAAK;IACnB,WAAW,EAAE,SAAS;IACtB,iBAAiB,EAAE,iBAAiB;IACpC,aAAa;IACb,aAAa,EAAE,KAAK;IACpB,aAAa,EAAE,IAAI;IACnB,mBAAmB,EAAE,wCAAwC;IAC7D,aAAa,EAAE,IAAI;IACnB,kBAAkB,EAAE,cAAc;IAClC,YAAY,EAAE,QAAQ;IACtB,iBAAiB,EAAE,0BAA0B;IAC7C,cAAc,EAAE,OAAO;IACvB,aAAa;IACb,WAAW,EAAE,OAAO;IACpB,iBAAiB,EAAE,kBAAkB;IACrC,YAAY,EAAE,IAAI;IAClB,YAAY,EAAE,SAAS;IACvB,YAAY,EAAE,MAAM;IACpB,UAAU,EAAE,0BAA0B;IACtC,2BAA2B;IAC3B,eAAe,EAAE,MAAM;IACvB,cAAc,EAAE,KAAK;IACrB,cAAc,EAAE,OAAO;IACvB,mBAAmB,EAAE,YAAY;IACjC,oBAAoB,EAAE,aAAa;IACnC,kBAAkB,EAAE,MAAM;IAC1B,yBAAyB,EAAE,aAAa;IACxC,eAAe,EAAE,WAAW;IAC5B,iBAAiB,EAAE,MAAM;IACzB,gBAAgB,EAAE,IAAI;IACtB,+BAA+B;IAC/B,eAAe,EAAE,cAAc;IAC/B,oBAAoB,EAAE,aAAa;IACnC,cAAc,EAAE,qBAAqB;IACrC,iBAAiB,EAAE,eAAe;CACF,CAAA;AAKlC,+BAA+B;AAC/B,MAAM,CAAC,MAAM,EAAE,GAAG;IAChB,YAAY,EAAE,mBAAmB;IACjC,WAAW,EAAE,sCAAsC;IACnD,iBAAiB,EAAE,kCAAkC;IACrD,aAAa,EAAE,mBAAmB;IAClC,aAAa,EAAE,OAAO;IACtB,mBAAmB,EACjB,6GAA6G;IAC/G,aAAa,EAAE,QAAQ;IACvB,kBAAkB,EAAE,iCAAiC;IACrD,YAAY,EAAE,4BAA4B;IAC1C,iBAAiB,EAAE,uEAAuE;IAC1F,cAAc,EAAE,UAAU;IAC1B,WAAW,EAAE,yBAAyB;IACtC,iBAAiB,EAAE,wCAAwC;IAC3D,YAAY,EAAE,KAAK;IACnB,YAAY,EAAE,0BAA0B;IACxC,YAAY,EAAE,kBAAkB;IAChC,UAAU,EAAE,uGAAuG;IACnH,kDAAkD;IAClD,eAAe,EAAE,kBAAkB;IACnC,cAAc,EAAE,MAAM;IACtB,cAAc,EAAE,oBAAoB;IACpC,mBAAmB,EAAE,kDAAkD;IACvE,oBAAoB,EAAE,oBAAoB;IAC1C,kBAAkB,EAAE,WAAW;IAC/B,yBAAyB,EAAE,uCAAuC;IAClE,eAAe,EAAE,wBAAwB;IACzC,iBAAiB,EAAE,UAAU;IAC7B,gBAAgB,EAAE,QAAQ;IAC1B,eAAe,EAAE,kCAAkC;IACnD,oBAAoB,EAAE,yBAAyB;IAC/C,cAAc,EAAE,2DAA2D;IAC3E,iBAAiB,EAAE,yCAAyC;CACzB,CAAA"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ref-lib client 样式注入:在文档头挂一张本插件专属的 <style data-plugin> 标签。
|
|
3
|
+
*
|
|
4
|
+
* 为什么不用 CSS Modules:ref-lib 的 tsdown 配置未移植 core 的 lightningcss
|
|
5
|
+
* CSS-Modules 插件(避免新增 native 依赖与构建面),而内联 style 无法表达
|
|
6
|
+
* hover/媒体查询/动画。因此采用运行时注入单张样式表——与 loader 的清理契约
|
|
7
|
+
* 兼容(`data-plugin` 标签在插件卸载/HMR 时由 loader 移除,重新物化时本模块
|
|
8
|
+
* 重新注入,幂等)。类名统一 `reflib-` 前缀防碰撞;颜色/字号/圆角全部走
|
|
9
|
+
* `--dsw-*` 设计令牌,随主题(浅色/深色)自动适配——这是"字体显示不一致、
|
|
10
|
+
* 没有设计感"的根因修复之一(旧实现硬编码 #d33 等,不随主题变化)。
|
|
11
|
+
* @module @hpyperry/dsh-ref-lib/src/client/styles
|
|
12
|
+
*/
|
|
13
|
+
/** 注入/确保样式表存在(幂等;HMR 重执行时旧标签已被 loader 移除,重新注入)。 */
|
|
14
|
+
export declare function ensureRefLibStyles(): void;
|
|
15
|
+
//# sourceMappingURL=styles.d.ts.map
|