@klarkxy/dsh-zhihu 0.1.7 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -7
- package/docs/README.zh-CN.md +24 -6
- package/icon.svg +14 -0
- package/lib/client.js +34 -213
- package/package.json +26 -17
package/README.md
CHANGED
|
@@ -2,17 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
Zhihu search, answers, knowledge bases, and usage tracking for DSH.
|
|
4
4
|
|
|
5
|
-
[简体中文](https://github.com/klarkxy/dsh-
|
|
5
|
+
[简体中文](https://github.com/klarkxy/dsh-plugins/blob/main/plugins/dsh-zhihu/docs/README.zh-CN.md)
|
|
6
6
|
|
|
7
7
|
## Install
|
|
8
8
|
|
|
9
|
-
Requires Node.js ≥22 and DSH `0.1.7-rc.2`. No repository build is needed.
|
|
9
|
+
Requires Node.js ≥22 and DSH `0.1.7-rc.2`. No repository build is needed. Install:
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
npm install @klarkxy/dsh-zhihu
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Then load it:
|
|
10
16
|
|
|
11
17
|
```sh
|
|
12
18
|
dsh plugin --profile web add @klarkxy/dsh-zhihu
|
|
13
19
|
```
|
|
14
20
|
|
|
15
|
-
Restart DSH Web, open **
|
|
21
|
+
Restart DSH Web, open **Plugins → @klarkxy/dsh-zhihu**, and enter your Access Secret (DSH credential `ZHIHU_ACCESS_TOKEN`). Use the full scoped name; the unscoped `dsh-zhihu` package belongs to another maintainer.
|
|
16
22
|
|
|
17
23
|
To enable agent tools, add this entry to the plugin list in the agent's `agent.cordis.yml`:
|
|
18
24
|
|
|
@@ -22,14 +28,26 @@ To enable agent tools, add this entry to the plugin list in the agent's `agent.c
|
|
|
22
28
|
|
|
23
29
|
## Use
|
|
24
30
|
|
|
25
|
-
DSH Web provides search, settings, usage, and knowledge-base views.
|
|
31
|
+
DSH Web provides search, settings, usage, and knowledge-base views. Open **Plugins → @klarkxy/dsh-zhihu** for configuration, usage, knowledge bases, and search; the agent tools are included.
|
|
26
32
|
|
|
27
|
-
|
|
33
|
+
Five agent tools are available once the tools entry is enabled:
|
|
34
|
+
|
|
35
|
+
- `zhihu_search`: search within Zhihu for community evidence; results are community/reader feedback only, never canon, and never written into project files.
|
|
36
|
+
- `zhihu_global_search`: search the wider web beyond Zhihu through the open platform's global search; reference only.
|
|
37
|
+
- `zhihu_hot_list`: pull the Zhihu hot list to see current community trends; reference for topics and hotspots only.
|
|
38
|
+
- `zhihu_ask`: ask Zhihu 直答, an OpenAI-compatible AI answer service grounded in Zhihu community content; suited for research and background investigation.
|
|
39
|
+
- `zhihu_knowledge_search`: retrieve RAG fragments from Zhihu knowledge bases — public bases by default, with personal and subscription recall scopes available after you upload material on Zhihu's web side.
|
|
40
|
+
|
|
41
|
+
Usage is tracked as daily counters of calls, failures, and returned results; usage views default to the last 30 days and accept at most 90. Knowledge-base uploads are limited to 20 MB per file.
|
|
42
|
+
|
|
43
|
+
Search covers Zhihu in-site search, the wider web, the hot list, Zhihu 直答 AI answers, and public knowledge bases. Uploaded reference files are stored in Zhihu's cloud; do not upload unpublished manuscripts.
|
|
28
44
|
|
|
29
45
|
When [@klarkxy/dsh-web-search-manager](https://www.npmjs.com/package/@klarkxy/dsh-web-search-manager) is also installed in the same profile, this plugin registers **Zhihu global search** as a provider in its web search settings. Enable that provider to use Zhihu's global search through the standard web search tool with the Access Secret from Zhihu settings. The dedicated Zhihu tools work independently.
|
|
30
46
|
|
|
31
47
|
## Development
|
|
32
48
|
|
|
33
|
-
Read [contracts](https://github.com/klarkxy/dsh-
|
|
49
|
+
Read [contracts](https://github.com/klarkxy/dsh-plugins/blob/main/plugins/dsh-zhihu/src/contracts.ts) and [tools](https://github.com/klarkxy/dsh-plugins/blob/main/plugins/dsh-zhihu/src/tools.ts) for the API.
|
|
50
|
+
|
|
51
|
+
[Publishing](https://github.com/klarkxy/dsh-plugins/blob/main/docs/editor-plugin-migration.md) · [License](https://github.com/klarkxy/dsh-plugins/blob/main/plugins/dsh-zhihu/LICENSE)
|
|
34
52
|
|
|
35
|
-
|
|
53
|
+
The client accepts structural host controls and has native HTML fallbacks. Building or using this package does not require application-private UI packages. Agent tools, credentials, RPC contracts and storage identifiers are unchanged.
|
package/docs/README.zh-CN.md
CHANGED
|
@@ -2,17 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
DSH 知乎搜索、直答、知识库与用量插件。
|
|
4
4
|
|
|
5
|
-
[English](https://github.com/klarkxy/dsh-
|
|
5
|
+
[English](https://github.com/klarkxy/dsh-plugins/blob/main/plugins/dsh-zhihu/README.md)
|
|
6
6
|
|
|
7
7
|
## 安装
|
|
8
8
|
|
|
9
|
-
需要 Node.js ≥22、DSH `0.1.7-rc.2
|
|
9
|
+
需要 Node.js ≥22、DSH `0.1.7-rc.2`,无需构建本仓库。安装:
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
npm install @klarkxy/dsh-zhihu
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
然后加载:
|
|
10
16
|
|
|
11
17
|
```sh
|
|
12
18
|
dsh plugin --profile web add @klarkxy/dsh-zhihu
|
|
13
19
|
```
|
|
14
20
|
|
|
15
|
-
重启 DSH Web
|
|
21
|
+
重启 DSH Web,从「插件」打开「知乎(@klarkxy/dsh-zhihu)」填写 Access Secret(DSH 凭据 `ZHIHU_ACCESS_TOKEN`)。请使用完整 scoped 包名;无 scope 的 `dsh-zhihu` 属于其他维护者。
|
|
16
22
|
|
|
17
23
|
模型需要使用知乎工具时,在所用 `agent.cordis.yml` 的插件列表加入:
|
|
18
24
|
|
|
@@ -22,7 +28,17 @@ dsh plugin --profile web add @klarkxy/dsh-zhihu
|
|
|
22
28
|
|
|
23
29
|
## 使用
|
|
24
30
|
|
|
25
|
-
DSH Web
|
|
31
|
+
DSH Web 提供搜索、设置、用量与知识库视图。在「插件 → 知乎(@klarkxy/dsh-zhihu)」配置、查看用量、管理知识库和搜索;模型工具随插件一同提供。
|
|
32
|
+
|
|
33
|
+
启用 tools 入口后,模型可使用五个工具:
|
|
34
|
+
|
|
35
|
+
- `zhihu_search`:知乎站内搜索,拉取社区证据;结果仅作社区/读者反馈参考,不构成 canon,也不直接写入项目文件。
|
|
36
|
+
- `zhihu_global_search`:知乎开放平台全网搜索,检索站外公开网页资料;仅作参考。
|
|
37
|
+
- `zhihu_hot_list`:拉取知乎热榜,了解当前社区热点;仅作题材与热点参考。
|
|
38
|
+
- `zhihu_ask`:调用知乎直答(OpenAI 兼容的 AI 问答),基于知乎社区内容生成综合回答;适合考据与背景调研。
|
|
39
|
+
- `zhihu_knowledge_search`:检索知乎知识库(RAG 片段),默认只查公开库;在知乎网页端上传过个人资料后可加个人/订阅召回范围。
|
|
40
|
+
|
|
41
|
+
用量按日计数(调用次数、失败次数与成功调用返回的条目数),视图默认展示最近 30 天,最多可查 90 天。知识库上传单文件上限 20 MB。
|
|
26
42
|
|
|
27
43
|
可查询站内、全网、热榜、直答和公开知识库。上传的参考文件保存在知乎云端,请勿上传未发表手稿。
|
|
28
44
|
|
|
@@ -30,6 +46,8 @@ DSH Web 提供搜索、设置、用量与知识库视图。DSH Editor 在「设
|
|
|
30
46
|
|
|
31
47
|
## 开发
|
|
32
48
|
|
|
33
|
-
接口见 [contracts](https://github.com/klarkxy/dsh-
|
|
49
|
+
接口见 [contracts](https://github.com/klarkxy/dsh-plugins/blob/main/plugins/dsh-zhihu/src/contracts.ts) 与 [tools](https://github.com/klarkxy/dsh-plugins/blob/main/plugins/dsh-zhihu/src/tools.ts)。
|
|
50
|
+
|
|
51
|
+
[发布维护](https://github.com/klarkxy/dsh-plugins/blob/main/docs/editor-plugin-migration.md) · [许可证](https://github.com/klarkxy/dsh-plugins/blob/main/plugins/dsh-zhihu/LICENSE)
|
|
34
52
|
|
|
35
|
-
|
|
53
|
+
客户端接收宿主提供的结构化控件,缺失时使用原生 HTML 控件。构建和使用本包不依赖应用私有 UI 包;Agent 工具、凭据、RPC 合同和存储标识保持不变。
|
package/icon.svg
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="36" height="36" viewBox="0 0 36 36" fill="none">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="zbubble" x1="6" y1="6" x2="30" y2="28" gradientUnits="userSpaceOnUse">
|
|
4
|
+
<stop stop-color="#4D75F5"/>
|
|
5
|
+
<stop offset="1" stop-color="#8EB6FF"/>
|
|
6
|
+
</linearGradient>
|
|
7
|
+
</defs>
|
|
8
|
+
<g transform="translate(3.6 3.6) scale(.8)">
|
|
9
|
+
<path d="M6 9C6 7.3 7.3 6 9 6H27C28.7 6 30 7.3 30 9V21C30 22.7 28.7 24 27 24H20L13 30V24H9C7.3 24 6 22.7 6 21V9Z" fill="url(#zbubble)"/>
|
|
10
|
+
<path d="M11 12H25M11 12V19M25 12V19M11 19H25M18 12V19" stroke="#E0EBFF" stroke-width="2" stroke-linecap="round"/>
|
|
11
|
+
<circle cx="14.5" cy="15.5" r="1.4" fill="#65DED0"/>
|
|
12
|
+
<circle cx="21.5" cy="15.5" r="1.4" fill="#65DED0"/>
|
|
13
|
+
</g>
|
|
14
|
+
</svg>
|
package/lib/client.js
CHANGED
|
@@ -216,18 +216,15 @@ function createZhihuClientState() {
|
|
|
216
216
|
//#region src/client-styles.ts
|
|
217
217
|
const standaloneOutsideTheme = ":not(.radix-themes *)";
|
|
218
218
|
const zhihuClientStyles = `
|
|
219
|
-
|
|
220
|
-
position: var(--dsh-ext-dock-position, absolute);
|
|
221
|
-
right: var(--dsh-ext-dock-right, var(--space-4, 16px));
|
|
222
|
-
bottom: var(--dsh-ext-dock-bottom, calc(var(--space-4, 16px) + 44px));
|
|
223
|
-
pointer-events: auto;
|
|
224
|
-
}
|
|
219
|
+
|
|
225
220
|
.zhihu-settings-embed {
|
|
226
221
|
font: 400 var(--font-size-2)/1.5 var(--default-font-family);
|
|
227
222
|
color: var(--gray-12);
|
|
228
223
|
display: flex;
|
|
229
224
|
flex-direction: column;
|
|
230
225
|
min-width: 0;
|
|
226
|
+
width: 100%;
|
|
227
|
+
max-width: 760px;
|
|
231
228
|
min-height: 0;
|
|
232
229
|
gap: 0;
|
|
233
230
|
}
|
|
@@ -238,73 +235,19 @@ const zhihuClientStyles = `
|
|
|
238
235
|
padding: var(--space-4) 0 0;
|
|
239
236
|
overflow: visible;
|
|
240
237
|
}
|
|
241
|
-
.zhihu-toggle {
|
|
242
|
-
pointer-events: auto;
|
|
243
|
-
font: inherit;
|
|
244
|
-
font-family: var(--default-font-family);
|
|
245
|
-
font-size: var(--font-size-2);
|
|
246
|
-
min-height: var(--control-h, 34px);
|
|
247
|
-
color: var(--gray-11);
|
|
248
|
-
background: var(--color-panel-solid);
|
|
249
|
-
border: 1px solid var(--gray-6);
|
|
250
|
-
border-radius: 999px;
|
|
251
|
-
padding: 0 14px;
|
|
252
|
-
cursor: pointer;
|
|
253
|
-
box-shadow: var(--shadow-3);
|
|
254
|
-
}
|
|
255
|
-
.zhihu-toggle:hover { border-color: var(--accent-9); color: var(--accent-11); background: var(--gray-a3); }
|
|
256
|
-
.zhihu-toggle:focus-visible,
|
|
257
238
|
.zhihu-panel button:focus-visible,
|
|
258
239
|
.zhihu-panel input:focus-visible,
|
|
259
240
|
.zhihu-panel select:focus-visible,
|
|
260
241
|
.zhihu-panel a:focus-visible {
|
|
261
242
|
box-shadow: 0 0 0 2px var(--accent-a8);
|
|
262
243
|
}
|
|
263
|
-
|
|
264
|
-
position: absolute;
|
|
265
|
-
top: var(--dsh-ext-panel-top, auto);
|
|
266
|
-
right: 0;
|
|
267
|
-
bottom: var(--dsh-ext-panel-bottom, calc(100% + 6px));
|
|
268
|
-
z-index: 10;
|
|
269
|
-
width: min(440px, calc(100vw - 32px));
|
|
270
|
-
max-height: min(72vh, 620px);
|
|
271
|
-
display: flex;
|
|
272
|
-
flex-direction: column;
|
|
273
|
-
pointer-events: auto;
|
|
274
|
-
font-family: var(--default-font-family);
|
|
275
|
-
font-size: var(--font-size-2);
|
|
276
|
-
color: var(--gray-12);
|
|
277
|
-
background: var(--color-panel-solid);
|
|
278
|
-
border: 1px solid var(--gray-6);
|
|
279
|
-
border-radius: var(--radius-3);
|
|
280
|
-
box-shadow: var(--shadow-4);
|
|
281
|
-
overflow: hidden;
|
|
282
|
-
}
|
|
244
|
+
|
|
283
245
|
.zhihu-panel {
|
|
284
246
|
font-family: var(--default-font-family);
|
|
285
247
|
font-size: var(--font-size-2);
|
|
286
248
|
color: var(--gray-12);
|
|
287
249
|
background: var(--color-panel-solid);
|
|
288
250
|
}
|
|
289
|
-
.zhihu-panel-header {
|
|
290
|
-
display: flex;
|
|
291
|
-
align-items: center;
|
|
292
|
-
justify-content: space-between;
|
|
293
|
-
padding: var(--space-2) var(--space-3);
|
|
294
|
-
border-bottom: 1px solid var(--gray-6);
|
|
295
|
-
}
|
|
296
|
-
.zhihu-panel-title {
|
|
297
|
-
margin: 0;
|
|
298
|
-
font-size: var(--font-size-2);
|
|
299
|
-
font-weight: var(--font-weight-medium);
|
|
300
|
-
font-family: var(--default-font-family);
|
|
301
|
-
}
|
|
302
|
-
.zhihu-panel-close {
|
|
303
|
-
font: inherit; font-size: var(--font-size-2); min-height: 32px; color: var(--gray-11); background: none; border: none;
|
|
304
|
-
border-radius: var(--radius-2); padding: 0 8px; cursor: pointer;
|
|
305
|
-
}
|
|
306
|
-
.zhihu-panel-close:hover { color: var(--gray-12); background: var(--gray-a3); }
|
|
307
|
-
.zhihu-panel-close:disabled { opacity: 0.5; cursor: default; }
|
|
308
251
|
.zhihu-tabs {
|
|
309
252
|
display: inline-flex;
|
|
310
253
|
gap: 2px;
|
|
@@ -500,17 +443,13 @@ const zhihuClientStyles = `
|
|
|
500
443
|
.zhihu-dots i:nth-child(2) { animation-delay: .2s; }
|
|
501
444
|
.zhihu-dots i:nth-child(3) { animation-delay: .4s; }
|
|
502
445
|
@media (prefers-reduced-motion: reduce) {
|
|
503
|
-
.zhihu-
|
|
446
|
+
.zhihu-panel, .zhihu-panel * {
|
|
504
447
|
animation: none !important; transition: none !important;
|
|
505
448
|
transform: none !important; filter: none !important;
|
|
506
449
|
}
|
|
507
450
|
.zhihu-dots i { animation: none; }
|
|
508
451
|
}
|
|
509
|
-
/* Local tokens when
|
|
510
|
-
and --dsh-ext-* rail overrides still win inside the Theme tree. Dark
|
|
511
|
-
follows body[data-ds-dark-theme] / :root[data-theme=dark], not OS scheme. */
|
|
512
|
-
.zhihu-dock${standaloneOutsideTheme},
|
|
513
|
-
.zhihu-toggle${standaloneOutsideTheme},
|
|
452
|
+
/* Local tokens follow the host theme when the settings page is outside Radix. */
|
|
514
453
|
.zhihu-panel${standaloneOutsideTheme} {
|
|
515
454
|
|
|
516
455
|
--default-font-family: "Noto Sans SC", "PingFang SC", "Microsoft YaHei UI", system-ui, sans-serif;
|
|
@@ -572,11 +511,7 @@ const zhihuClientStyles = `
|
|
|
572
511
|
--shadow-4: 0 0 0 1px #0000000f, 0 8px 40px rgba(0, 0, 0, 0.05), 0 12px 32px -16px #0000000f;
|
|
573
512
|
color-scheme: light;
|
|
574
513
|
}
|
|
575
|
-
html:not([data-theme]) body[data-ds-dark-theme] .zhihu-dock${standaloneOutsideTheme},
|
|
576
|
-
html:not([data-theme]) body[data-ds-dark-theme] .zhihu-toggle${standaloneOutsideTheme},
|
|
577
514
|
html:not([data-theme]) body[data-ds-dark-theme] .zhihu-panel${standaloneOutsideTheme},
|
|
578
|
-
:root[data-theme="dark"] .zhihu-dock${standaloneOutsideTheme},
|
|
579
|
-
:root[data-theme="dark"] .zhihu-toggle${standaloneOutsideTheme},
|
|
580
515
|
:root[data-theme="dark"] .zhihu-panel${standaloneOutsideTheme} {
|
|
581
516
|
|
|
582
517
|
--default-font-family: "Noto Sans SC", "PingFang SC", "Microsoft YaHei UI", system-ui, sans-serif;
|
|
@@ -661,12 +596,6 @@ function zhihuQueryKeyDown(event, run) {
|
|
|
661
596
|
run.search();
|
|
662
597
|
}
|
|
663
598
|
}
|
|
664
|
-
function dockEscapeKeyDown(event, run) {
|
|
665
|
-
if (event.key !== "Escape") return;
|
|
666
|
-
event.stopPropagation();
|
|
667
|
-
if (run.loading) return;
|
|
668
|
-
run.close();
|
|
669
|
-
}
|
|
670
599
|
function hostComponentsFromRenderProps(props) {
|
|
671
600
|
if (!props || typeof props !== "object") return {};
|
|
672
601
|
const record = props;
|
|
@@ -711,10 +640,8 @@ function renderSelect(Select, props, className) {
|
|
|
711
640
|
}, option.value === "" ? "__empty" : option.value))
|
|
712
641
|
});
|
|
713
642
|
}
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
const SeatButton = (0, react.forwardRef)(function SeatButton(props, ref) {
|
|
717
|
-
const { host, variant, className, ...rest } = props;
|
|
643
|
+
/** Prefer a structurally supplied host control; standalone Web needs no private UI package. */
|
|
644
|
+
const ZhihuButton = (0, react.forwardRef)(function ZhihuButton({ host, variant, className, ...rest }, ref) {
|
|
718
645
|
if (host) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(host, {
|
|
719
646
|
ref,
|
|
720
647
|
variant,
|
|
@@ -737,9 +664,9 @@ const inject = [
|
|
|
737
664
|
"remote",
|
|
738
665
|
"remote.credentials"
|
|
739
666
|
];
|
|
740
|
-
const
|
|
667
|
+
const PACKAGE_NAME = "@klarkxy/dsh-zhihu";
|
|
741
668
|
const SLOT_ORDER = 120;
|
|
742
|
-
const SLOT_LABEL = "
|
|
669
|
+
const SLOT_LABEL = "知乎";
|
|
743
670
|
const activityDots = () => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
744
671
|
className: "zhihu-dots",
|
|
745
672
|
"aria-hidden": "true",
|
|
@@ -1101,7 +1028,7 @@ function SettingsSection(props) {
|
|
|
1101
1028
|
if (state.status === "error") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SettingsShell, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
|
|
1102
1029
|
className: "zhihu-error",
|
|
1103
1030
|
role: "alert",
|
|
1104
|
-
children: [`读取失败:${state.error} `, /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1031
|
+
children: [`读取失败:${state.error} `, /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ZhihuButton, {
|
|
1105
1032
|
host: props.Button,
|
|
1106
1033
|
className: "zhihu-button",
|
|
1107
1034
|
onClick: () => void load(),
|
|
@@ -1227,14 +1154,14 @@ function SettingsSection(props) {
|
|
|
1227
1154
|
}) : null,
|
|
1228
1155
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1229
1156
|
className: "zhihu-row",
|
|
1230
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1157
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ZhihuButton, {
|
|
1231
1158
|
host: props.Button,
|
|
1232
1159
|
variant: "danger",
|
|
1233
1160
|
className: "zhihu-button zhihu-button-danger",
|
|
1234
1161
|
disabled: busy || keyLocked || !configured,
|
|
1235
1162
|
onClick: () => void clear(),
|
|
1236
1163
|
children: busy ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react.Fragment, { children: [activityDots(), "处理中…"] }) : "清除"
|
|
1237
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1164
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ZhihuButton, {
|
|
1238
1165
|
host: props.Button,
|
|
1239
1166
|
variant: "primary",
|
|
1240
1167
|
className: "zhihu-button zhihu-button-primary",
|
|
@@ -1480,7 +1407,7 @@ function UsageSection(props) {
|
|
|
1480
1407
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
|
|
1481
1408
|
className: "zhihu-error",
|
|
1482
1409
|
role: "alert",
|
|
1483
|
-
children: [`读取失败:${state.error} `, /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1410
|
+
children: [`读取失败:${state.error} `, /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ZhihuButton, {
|
|
1484
1411
|
host: props.Button,
|
|
1485
1412
|
className: "zhihu-button",
|
|
1486
1413
|
onClick: () => void load(),
|
|
@@ -1737,7 +1664,7 @@ function KnowledgeSection(props) {
|
|
|
1737
1664
|
list.status === "error" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
|
|
1738
1665
|
className: "zhihu-error",
|
|
1739
1666
|
role: "alert",
|
|
1740
|
-
children: [`${list.failure.text} `, list.failure.kind !== "credential" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1667
|
+
children: [`${list.failure.text} `, list.failure.kind !== "credential" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ZhihuButton, {
|
|
1741
1668
|
host: props.Button,
|
|
1742
1669
|
className: "zhihu-button",
|
|
1743
1670
|
onClick: () => void load(),
|
|
@@ -1766,7 +1693,7 @@ function KnowledgeSection(props) {
|
|
|
1766
1693
|
value: base.id,
|
|
1767
1694
|
label: `${base.name}${base.isDefault ? "(默认)" : ""} · ${base.contentCount} 篇`
|
|
1768
1695
|
}))]
|
|
1769
|
-
}, "zhihu-select"), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1696
|
+
}, "zhihu-select"), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ZhihuButton, {
|
|
1770
1697
|
host: props.Button,
|
|
1771
1698
|
className: "zhihu-button",
|
|
1772
1699
|
disabled: busy,
|
|
@@ -1797,7 +1724,7 @@ function KnowledgeSection(props) {
|
|
|
1797
1724
|
disabled: busy,
|
|
1798
1725
|
onChange: (event) => setFile(event.target.files?.[0])
|
|
1799
1726
|
}, fileKey),
|
|
1800
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1727
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ZhihuButton, {
|
|
1801
1728
|
host: props.Button,
|
|
1802
1729
|
className: "zhihu-button",
|
|
1803
1730
|
disabled: busy,
|
|
@@ -1812,7 +1739,7 @@ function KnowledgeSection(props) {
|
|
|
1812
1739
|
}) : null,
|
|
1813
1740
|
list.status === "ready" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1814
1741
|
className: "zhihu-row",
|
|
1815
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1742
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ZhihuButton, {
|
|
1816
1743
|
host: props.Button,
|
|
1817
1744
|
variant: "primary",
|
|
1818
1745
|
className: "zhihu-button zhihu-button-primary",
|
|
@@ -1840,31 +1767,18 @@ const TAB_LABEL = {
|
|
|
1840
1767
|
usage: "用量",
|
|
1841
1768
|
knowledge: "知识库"
|
|
1842
1769
|
};
|
|
1843
|
-
const OVERLAY_TABS = [
|
|
1844
|
-
"search",
|
|
1845
|
-
"settings",
|
|
1846
|
-
"usage",
|
|
1847
|
-
"knowledge"
|
|
1848
|
-
];
|
|
1849
1770
|
const SETTINGS_TABS = [
|
|
1850
1771
|
"settings",
|
|
1851
1772
|
"usage",
|
|
1852
1773
|
"knowledge",
|
|
1853
1774
|
"search"
|
|
1854
1775
|
];
|
|
1855
|
-
function
|
|
1856
|
-
|
|
1857
|
-
return TAB_LABEL[tab];
|
|
1858
|
-
}
|
|
1859
|
-
function ZhihuDock(props) {
|
|
1860
|
-
const { rpc, credentials, Select, Dialog, Button, Input } = props;
|
|
1861
|
-
const surface = props.surface === "settings" ? "settings" : "overlay";
|
|
1862
|
-
const tabs = surface === "settings" ? SETTINGS_TABS : OVERLAY_TABS;
|
|
1776
|
+
function ZhihuSettings(props) {
|
|
1777
|
+
const { rpc, credentials, Select, Button, Input } = props;
|
|
1863
1778
|
const gateRef = (0, react.useRef)(null);
|
|
1864
1779
|
if (!gateRef.current) gateRef.current = createZhihuClientState();
|
|
1865
1780
|
const gate = gateRef.current;
|
|
1866
|
-
const [
|
|
1867
|
-
const [tab, setTab] = (0, react.useState)(surface === "settings" ? "settings" : "search");
|
|
1781
|
+
const [tab, setTab] = (0, react.useState)("settings");
|
|
1868
1782
|
const [query, setQuery] = (0, react.useState)("");
|
|
1869
1783
|
const [mode, setMode] = (0, react.useState)("search");
|
|
1870
1784
|
const [askModel, setAskModel] = (0, react.useState)("zhida-thinking-1p5");
|
|
@@ -1874,23 +1788,7 @@ function ZhihuDock(props) {
|
|
|
1874
1788
|
const [outcome, setOutcome] = (0, react.useState)(null);
|
|
1875
1789
|
const [revision, setRevision] = (0, react.useState)(0);
|
|
1876
1790
|
const [resultRevision, setResultRevision] = (0, react.useState)(0);
|
|
1877
|
-
const toggleRef = (0, react.useRef)(null);
|
|
1878
1791
|
const queryRef = (0, react.useRef)(null);
|
|
1879
|
-
const wasOpen = (0, react.useRef)(false);
|
|
1880
|
-
(0, react.useEffect)(() => {
|
|
1881
|
-
if (Dialog || surface === "settings") return;
|
|
1882
|
-
if (open) {
|
|
1883
|
-
wasOpen.current = true;
|
|
1884
|
-
queryRef.current?.focus();
|
|
1885
|
-
} else if (wasOpen.current) {
|
|
1886
|
-
wasOpen.current = false;
|
|
1887
|
-
toggleRef.current?.focus();
|
|
1888
|
-
}
|
|
1889
|
-
}, [
|
|
1890
|
-
open,
|
|
1891
|
-
Dialog,
|
|
1892
|
-
surface
|
|
1893
|
-
]);
|
|
1894
1792
|
(0, react.useEffect)(() => () => gate.cancel(), [gate]);
|
|
1895
1793
|
const runSearch = (0, react.useCallback)(async () => {
|
|
1896
1794
|
if (mode !== "hot" && !query.trim()) return;
|
|
@@ -1980,17 +1878,6 @@ function ZhihuDock(props) {
|
|
|
1980
1878
|
setAskModel(next);
|
|
1981
1879
|
resetToIdle();
|
|
1982
1880
|
};
|
|
1983
|
-
const closePanel = (0, react.useCallback)(() => {
|
|
1984
|
-
gate.cancel();
|
|
1985
|
-
setPhase("idle");
|
|
1986
|
-
setOpen(false);
|
|
1987
|
-
}, [gate]);
|
|
1988
|
-
const onPanelKeyDown = (event) => {
|
|
1989
|
-
dockEscapeKeyDown(event, {
|
|
1990
|
-
loading: phase === "loading",
|
|
1991
|
-
close: closePanel
|
|
1992
|
-
});
|
|
1993
|
-
};
|
|
1994
1881
|
const onQueryKeyDown = (event) => {
|
|
1995
1882
|
zhihuQueryKeyDown(event, {
|
|
1996
1883
|
disabled: isSearchDisabled(),
|
|
@@ -2021,7 +1908,7 @@ function ZhihuDock(props) {
|
|
|
2021
1908
|
buttons[next]?.focus();
|
|
2022
1909
|
buttons[next]?.click();
|
|
2023
1910
|
},
|
|
2024
|
-
children:
|
|
1911
|
+
children: SETTINGS_TABS.map((key) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ZhihuButton, {
|
|
2025
1912
|
host: Button,
|
|
2026
1913
|
type: "button",
|
|
2027
1914
|
role: "tab",
|
|
@@ -2029,7 +1916,7 @@ function ZhihuDock(props) {
|
|
|
2029
1916
|
tabIndex: tab === key ? 0 : -1,
|
|
2030
1917
|
className: "zhihu-tab",
|
|
2031
1918
|
onClick: () => onTabChange(key),
|
|
2032
|
-
children:
|
|
1919
|
+
children: TAB_LABEL[key]
|
|
2033
1920
|
}, key))
|
|
2034
1921
|
}, "tabs");
|
|
2035
1922
|
const body = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -2063,7 +1950,7 @@ function ZhihuDock(props) {
|
|
|
2063
1950
|
className: "zhihu-scopes",
|
|
2064
1951
|
role: "group",
|
|
2065
1952
|
"aria-label": "检索范围",
|
|
2066
|
-
children: SCOPE_OPTIONS.map((scope) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1953
|
+
children: SCOPE_OPTIONS.map((scope) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ZhihuButton, {
|
|
2067
1954
|
host: Button,
|
|
2068
1955
|
role: "checkbox",
|
|
2069
1956
|
"aria-checked": scopes.includes(scope.value),
|
|
@@ -2086,7 +1973,7 @@ function ZhihuDock(props) {
|
|
|
2086
1973
|
}),
|
|
2087
1974
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2088
1975
|
className: "zhihu-row",
|
|
2089
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1976
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ZhihuButton, {
|
|
2090
1977
|
host: Button,
|
|
2091
1978
|
variant: "primary",
|
|
2092
1979
|
className: "zhihu-button zhihu-button-primary",
|
|
@@ -2094,7 +1981,7 @@ function ZhihuDock(props) {
|
|
|
2094
1981
|
disabled: searchDisabled,
|
|
2095
1982
|
onClick: () => void runSearch(),
|
|
2096
1983
|
children: phase === "loading" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react.Fragment, { children: [activityDots(), "请求中…"] }) : mode === "hot" ? "获取热榜" : "搜索"
|
|
2097
|
-
}), phase === "loading" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1984
|
+
}), phase === "loading" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ZhihuButton, {
|
|
2098
1985
|
host: Button,
|
|
2099
1986
|
className: "zhihu-button",
|
|
2100
1987
|
onClick: () => {
|
|
@@ -2104,7 +1991,7 @@ function ZhihuDock(props) {
|
|
|
2104
1991
|
children: "取消"
|
|
2105
1992
|
}) : null]
|
|
2106
1993
|
}),
|
|
2107
|
-
|
|
1994
|
+
phase === "idle" && mode !== "hot" && !query.trim() ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2108
1995
|
className: "zhihu-status",
|
|
2109
1996
|
role: "status",
|
|
2110
1997
|
children: "输入关键词后搜索。"
|
|
@@ -2141,62 +2028,12 @@ function ZhihuDock(props) {
|
|
|
2141
2028
|
}) : null
|
|
2142
2029
|
]
|
|
2143
2030
|
}, "body");
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
className: "zhihu-panel-header",
|
|
2147
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
|
|
2148
|
-
className: "zhihu-panel-title",
|
|
2149
|
-
children: "知乎资料"
|
|
2150
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SeatButton, {
|
|
2151
|
-
host: Button,
|
|
2152
|
-
className: "zhihu-panel-close",
|
|
2153
|
-
disabled: phase === "loading",
|
|
2154
|
-
onClick: closePanel,
|
|
2155
|
-
children: "关闭"
|
|
2156
|
-
})]
|
|
2157
|
-
}, "header"),
|
|
2158
|
-
tablist,
|
|
2159
|
-
body
|
|
2160
|
-
];
|
|
2161
|
-
if (surface === "settings") return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2162
|
-
className: "zhihu-settings-embed",
|
|
2031
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
2032
|
+
className: "zhihu-panel zhihu-settings-embed",
|
|
2163
2033
|
"data-testid": "zhihu-settings-embed",
|
|
2164
2034
|
"aria-label": SLOT_LABEL,
|
|
2165
2035
|
children: [tablist, body]
|
|
2166
2036
|
});
|
|
2167
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2168
|
-
className: "zhihu-dock",
|
|
2169
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SeatButton, {
|
|
2170
|
-
host: Button,
|
|
2171
|
-
ref: toggleRef,
|
|
2172
|
-
className: "zhihu-toggle",
|
|
2173
|
-
"data-testid": "zhihu-open",
|
|
2174
|
-
onClick: () => setOpen(true),
|
|
2175
|
-
children: SLOT_LABEL
|
|
2176
|
-
}), Dialog ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Dialog, {
|
|
2177
|
-
open,
|
|
2178
|
-
onOpenChange: (next) => {
|
|
2179
|
-
if (!next) closePanel();
|
|
2180
|
-
else setOpen(true);
|
|
2181
|
-
},
|
|
2182
|
-
title: "知乎资料",
|
|
2183
|
-
className: "file-dialog zhihu-panel",
|
|
2184
|
-
overlayClassName: "file-dialog-overlay",
|
|
2185
|
-
dismissible: phase !== "loading",
|
|
2186
|
-
initialFocusRef: queryRef,
|
|
2187
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2188
|
-
"data-testid": "zhihu-panel",
|
|
2189
|
-
className: "zhihu-panel-inner",
|
|
2190
|
-
children: inner
|
|
2191
|
-
})
|
|
2192
|
-
}) : open ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("section", {
|
|
2193
|
-
className: "zhihu-panel",
|
|
2194
|
-
"data-testid": "zhihu-panel",
|
|
2195
|
-
"aria-label": "知乎资料",
|
|
2196
|
-
onKeyDown: onPanelKeyDown,
|
|
2197
|
-
children: inner
|
|
2198
|
-
}) : null]
|
|
2199
|
-
});
|
|
2200
2037
|
}
|
|
2201
2038
|
function apply(ctx) {
|
|
2202
2039
|
ctx.effect(() => {
|
|
@@ -2204,33 +2041,17 @@ function apply(ctx) {
|
|
|
2204
2041
|
return () => style?.remove();
|
|
2205
2042
|
}, "zhihu.styles");
|
|
2206
2043
|
const client = ctx;
|
|
2207
|
-
const
|
|
2044
|
+
const settingsRender = (props) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ZhihuSettings, {
|
|
2208
2045
|
rpc: client.connection.rpc,
|
|
2209
2046
|
credentials: wrapCredentials(client.remote.credentials),
|
|
2210
|
-
surface: "overlay",
|
|
2211
2047
|
...hostComponentsFromRenderProps(props)
|
|
2212
2048
|
});
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
rpc: client.connection.rpc,
|
|
2217
|
-
credentials: wrapCredentials(client.remote.credentials),
|
|
2218
|
-
surface: "settings",
|
|
2219
|
-
...host
|
|
2220
|
-
});
|
|
2221
|
-
};
|
|
2222
|
-
client.slots.inject("shell.overlay", () => client.slots.register({
|
|
2223
|
-
name: "shell.overlay",
|
|
2224
|
-
id: SLOT_ID,
|
|
2225
|
-
order: SLOT_ORDER,
|
|
2226
|
-
label: SLOT_LABEL
|
|
2227
|
-
}, overlayRender));
|
|
2228
|
-
client.slots.inject("dsh-editor.settings.zhihu", () => client.slots.register({
|
|
2229
|
-
name: "dsh-editor.settings.zhihu",
|
|
2230
|
-
id: SLOT_ID,
|
|
2049
|
+
ctx.effect(() => client.slots.inject("plugins.bundle.config", () => client.slots.register({
|
|
2050
|
+
name: "plugins.bundle.config",
|
|
2051
|
+
key: PACKAGE_NAME,
|
|
2231
2052
|
order: SLOT_ORDER,
|
|
2232
2053
|
label: SLOT_LABEL
|
|
2233
|
-
}, settingsRender));
|
|
2054
|
+
}, settingsRender)), "zhihu.settings");
|
|
2234
2055
|
}
|
|
2235
2056
|
//#endregion
|
|
2236
2057
|
exports.apply = apply;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@klarkxy/dsh-zhihu",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
4
4
|
"description": "Zhihu search, agent tools, knowledge bases, and usage tracking for DeepSeek Harness.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"type": "module",
|
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
"./package.json": "./package.json"
|
|
37
37
|
},
|
|
38
38
|
"files": [
|
|
39
|
+
"icon.svg",
|
|
39
40
|
"lib/*.js",
|
|
40
41
|
"lib/*.js.map",
|
|
41
42
|
"lib/*.d.ts",
|
|
@@ -63,7 +64,7 @@
|
|
|
63
64
|
"entries": [
|
|
64
65
|
{
|
|
65
66
|
"id": "zhihu",
|
|
66
|
-
"title": "
|
|
67
|
+
"title": "知乎",
|
|
67
68
|
"description": "知乎搜索、知识库与用量",
|
|
68
69
|
"feature": "zhihu",
|
|
69
70
|
"service": "zhihu"
|
|
@@ -82,24 +83,37 @@
|
|
|
82
83
|
}
|
|
83
84
|
]
|
|
84
85
|
},
|
|
86
|
+
"scripts": {
|
|
87
|
+
"build": "tsdown && node ../../scripts/editor-plugins/wrap-client.mjs @klarkxy/dsh-zhihu",
|
|
88
|
+
"typecheck": "tsc --noEmit -p tsconfig.json",
|
|
89
|
+
"test": "vitest run --root ../.. --config vitest.editor-plugins.config.ts --maxWorkers=2 plugins/dsh-zhihu/src"
|
|
90
|
+
},
|
|
85
91
|
"dependencies": {
|
|
86
|
-
"@deepseek-ai/dsh-storage-domain": "0.1.7-rc.2",
|
|
87
92
|
"zod": "^4.1.5"
|
|
88
93
|
},
|
|
89
94
|
"peerDependencies": {
|
|
90
95
|
"@deepseek-ai/cordis": "^4.0.4",
|
|
91
|
-
"@deepseek-ai/dsh-credentials": "0.1.7-rc.2",
|
|
92
|
-
"@deepseek-ai/dsh-
|
|
96
|
+
"@deepseek-ai/dsh-credentials": ">=0.1.7-rc.2",
|
|
97
|
+
"@deepseek-ai/dsh-storage-domain": ">=0.1.7-rc.2",
|
|
98
|
+
"@deepseek-ai/dsh-tools": ">=0.1.7-alpha.1"
|
|
93
99
|
},
|
|
94
100
|
"devDependencies": {
|
|
95
101
|
"@deepseek-ai/cordis": "^4.0.4",
|
|
96
102
|
"@deepseek-ai/dsh-credentials": "0.1.7-rc.2",
|
|
103
|
+
"@deepseek-ai/dsh-storage-domain": "0.1.7-rc.2",
|
|
97
104
|
"@deepseek-ai/dsh-tools": "0.1.7-rc.2",
|
|
98
105
|
"react": "^18.2.0",
|
|
99
106
|
"@types/react": "18.3.31",
|
|
100
|
-
"
|
|
107
|
+
"react-dom": "^18.2.0",
|
|
108
|
+
"@types/react-dom": "^18.3.1"
|
|
101
109
|
},
|
|
102
110
|
"peerDependenciesMeta": {
|
|
111
|
+
"@deepseek-ai/dsh-credentials": {
|
|
112
|
+
"optional": true
|
|
113
|
+
},
|
|
114
|
+
"@deepseek-ai/dsh-storage-domain": {
|
|
115
|
+
"optional": true
|
|
116
|
+
},
|
|
103
117
|
"@deepseek-ai/dsh-tools": {
|
|
104
118
|
"optional": true
|
|
105
119
|
}
|
|
@@ -116,23 +130,18 @@
|
|
|
116
130
|
],
|
|
117
131
|
"repository": {
|
|
118
132
|
"type": "git",
|
|
119
|
-
"url": "git+https://github.com/klarkxy/dsh-
|
|
120
|
-
"directory": "
|
|
133
|
+
"url": "git+https://github.com/klarkxy/dsh-plugins.git",
|
|
134
|
+
"directory": "plugins/dsh-zhihu"
|
|
121
135
|
},
|
|
122
|
-
"homepage": "https://github.
|
|
136
|
+
"homepage": "https://klarkxy.github.io/dsh-plugins/plugins/zhihu/",
|
|
123
137
|
"bugs": {
|
|
124
|
-
"url": "https://github.com/klarkxy/dsh-
|
|
138
|
+
"url": "https://github.com/klarkxy/dsh-plugins/issues"
|
|
125
139
|
},
|
|
126
140
|
"publishConfig": {
|
|
127
141
|
"access": "public",
|
|
128
142
|
"registry": "https://registry.npmjs.org/"
|
|
129
143
|
},
|
|
130
144
|
"dshRelease": {
|
|
131
|
-
"contentHash": "
|
|
132
|
-
},
|
|
133
|
-
"scripts": {
|
|
134
|
-
"build": "tsdown && node ../../scripts/wrap-client.mjs @klarkxy/dsh-zhihu",
|
|
135
|
-
"typecheck": "tsc --noEmit -p tsconfig.json",
|
|
136
|
-
"test": "vitest run --root ../.. packages/dsh-zhihu/src"
|
|
145
|
+
"contentHash": "abfa1b559afda73ac70b685e2d9bae00fbcc250806fbd1369f9f189fd040e0ca"
|
|
137
146
|
}
|
|
138
|
-
}
|
|
147
|
+
}
|