🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

知识画布 NeoHotaru/dsh-knowledge-canvas

DeepSeek Harnessv0.4.5
NeoHotaru6 天前有提交已提供中文文档扫描:含敏感能力

给 DeepSeek Harness 的知识库:模型靠判断去取,而不是靠相似度。

36.7/100
综合分
10
GitHub 星标
1,656
npm 周下载
—/5
用户评分

数据截至 2026/10/26 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add dsh-knowledge-canvas
npm 源 · dsh-knowledge-canvas 的发布者账号已校验与本仓库一致

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么
dsh 原生插件 · skill
装得上吗
本站已在 dsh 0.2.1-rc.2 下真实安装成功
非静态推断
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 6 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查✓ 自动检查通过
展开查看检查明细 ↓

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

✓npm 包dsh-knowledge-canvas @ 0.4.5
✓Node 引擎未声明 engines.node
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/30 21:11:19

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

读写/删除本地文件发起外部网络请求
查看扫描证据(共 59 处,展示前 57 条)
  • 读取本地文件
    index.js:249
    names = readdirSync(dir).filter((name) => name.endsWith('.json')
  • 读取本地文件
    index.js:256
    const base = JSON.parse(readFileSync(join(dir, name), 'utf8'))
  • 发起网络请求
    client.js:163
    const response = await fetch(PREFIX + '/assetBytes', {
  • 发起网络请求
    client.js:4733
    const response = await fetch(PREFIX + '/' + action, {
  • 发起网络请求
    client.js:5212
    const policyResponse = await fetch(PREFIX + '/state?session=' + encodeURIComponent(sessionId), { signal: controller.signal });
  • 发起网络请求
    client.js:6294
    const response = await fetch(PREFIX + '/workspaces');
  • 发起网络请求
    client.js:6311
    const response = await fetch(PREFIX + '/attachmentMode', {
  • 发起网络请求
    client.js:6336
    const response = await fetch(PREFIX + '/selection', {
  • 读取本地文件
    lib/tools.js:110
    size = (await stat(inside)).size
  • 读取本地文件
    lib/tools.js:582
    const raw = JSON.parse(await readFile(path, 'utf8'))
  • 写入本地文件
    lib/tools.js:595
    await writeFile(path, JSON.stringify({ version: 1, enabled }, null, 2) + '\n', 'utf8')
  • 读取本地文件
    lib/tools.js:659
    files.push({ data: readFileSync(resolve(cwd, '.dsh-knowledge', rel)), mediaType: IMAGE_MIME[suffix], name: rel.split('/').pop() })
  • 写入本地文件
    lib/tools.js:784
    await mkdir(dirname(file), { recursive: true })
  • 写入本地文件
    lib/tools.js:785
    await appendFile(file, activityRecord(activityStamp(), sessionId, tool, what, 'running') + '\n', 'utf8')
  • 写入本地文件
    lib/tools.js:813
    await mkdir(dirname(file), { recursive: true })
  • 写入本地文件
    lib/tools.js:814
    await appendFile(file, line + '\n', 'utf8')
  • 读取本地文件
    lib/seed.js:447
    const exists = await stat(dir).then(() => true, () => false)
  • 写入本地文件
    lib/seed.js:450
    await mkdir(dir, { recursive: true })
  • 读取本地文件
    lib/seed.js:501
    if (await stat(fixed).then(() => true, () => false)) return fixed
  • 读取本地文件
    lib/seed.js:505
    names = await readdir(dir)
  • 读取本地文件
    lib/seed.js:515
    const candidate = JSON.parse(await readFile(join(dir, name), 'utf8'))
  • 读取本地文件
    lib/seed.js:533
    if (!(await stat(dir).then(() => true, () => false))) return null
  • 读取本地文件
    lib/seed.js:539
    base = JSON.parse(await readFile(path, 'utf8'))
  • 读取本地文件
    lib/routes.js:341
    text = await readFile(file, 'utf8')
  • 读取本地文件
    lib/routes.js:747
    const bytes = await readFile(join(cwd, '.dsh-knowledge', rel))
  • 读取本地文件
    lib/routes.js:761
    const bytes = await readFile(join(here, '..', 'assets', action))
  • 读取本地文件
    lib/routes.js:836
    const bytes = await readFile(join(cwd, '.dsh-knowledge', rel))
  • 写入本地文件
    lib/state.js:33
    await mkdir(dirname(path), { recursive: true })
  • 写入本地文件
    lib/state.js:37
    await writeFile(temporary, JSON.stringify(value, null, 2) + '\n', 'utf8')
  • 写入本地文件
    lib/state.js:40
    await rename(temporary, path)
  • 删除本地文件
    lib/state.js:51
    await rm(temporary, { force: true }).catch(() => {})
  • 读取本地文件
    lib/state.js:75
    return JSON.parse(await readFile(path, 'utf8'))
  • 写入本地文件
    lib/state.js:124
    await mkdir(dirname(path), { recursive: true })
  • 写入本地文件
    lib/state.js:287
    await mkdir(dirname(path), { recursive: true })
  • 写入本地文件
    lib/log.js:21
    appendFileSync(LOG_PATH, `${stamp} ${line}\n`, 'utf8')
  • 读取本地文件
    lib/inject.js:44
    return existsSync(join(workspace, '.dsh-knowledge', '.no-action-notes'))
  • 读取本地文件
    lib/inject.js:107
    if (existsSync(join(at, '.dsh-knowledge'))) return at
  • 读取本地文件
    lib/attachments.js:15
    const bytes = readFileSync(absolute)
  • 写入本地文件
    lib/store.js:89
    await mkdir(removedDir(cwd), { recursive: true })
  • 写入本地文件
    lib/store.js:90
    await rename(pathFor(cwd, id), target)
  • 读取本地文件
    lib/store.js:99
    names = await readdir(dir)
  • 读取本地文件
    lib/store.js:111
    const raw = await readFile(join(dir, name), 'utf8')
  • 读取本地文件
    lib/store.js:127
    text = await readFile(path, 'utf8')
  • 写入本地文件
    lib/store.js:140
    await mkdir(join(path, '..'), { recursive: true })
  • 写入本地文件
    lib/store.js:143
    await writeFile(path, isDiary(id) ? seal(id, base) : JSON.stringify(base, null, 2) + '\n', 'utf8')
  • 写入本地文件
    lib/store.js:482
    await mkdir(dir, { recursive: true })
  • 读取本地文件
    lib/store.js:485
    if (!existsSync(target)) await writeFile(target, bytes)
  • 写入本地文件
    lib/store.js:485
    if (!existsSync(target)) await writeFile(target, bytes)
  • 读取本地文件
    lib/store.js:491
    const bytes = await readFile(sourcePath)
  • 读取本地文件
    lib/store.js:668
    const size = statSync(absolute).size
  • 读取本地文件
    lib/diary-replies.js:30
    try { text = await readFile(path, 'utf8') } catch (error) {
  • 写入本地文件
    lib/diary-replies.js:42
    await mkdir(dirname(path), { recursive: true })
  • 写入本地文件
    lib/diary-replies.js:45
    await writeFile(temporary, seal(baseId, journal), 'utf8')
  • 写入本地文件
    lib/diary-replies.js:46
    await rename(temporary, path)
  • 删除本地文件
    lib/diary-replies.js:48
    await rm(temporary, { force: true }).catch(() => {})
  • 读取本地文件
    lib/workspaces.js:19
    return statSync(path).isDirectory()
  • 读取本地文件
    lib/workspaces.js:74
    names = readdirSync(root)
扫描于 2026/11/1(0 天前) · 范围 入口闭包 + 全包扫描 · 来源 npm 发布包

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

DeepSeek Harness 的树状知识库:右侧画布可手动编辑,模型也能用工具读写。节点带一行触发语,说明何时生效;知识库可整份注入,也可只注入索引。

v0.4.52026-10-24
修复全新 npm 安装后 Harness 启动失败的问题(#11)。前端模块现在使用与发布包一致的注册名 dsh-knowledge-canvas,避免宿主补载脚本时重复注册。 保留知识库文件、现有接口和标签页标识,无需迁移数据。新增模块名称一致性发布检查和打包安装回归测试。 已在纯净官方 Harness 0.2.1-rc.2 网页宿主复现旧版故障,并验证修复包首次启动、冷重启、知识库面板及文件哈希保持。完整本地检查通过;报告者的 Electron 桌面封装尚未单独回放,不将网页宿主验证等同于桌面验证。 升级:pnpm add dsh-knowledge-canvas@0.4.5,保持 profile 中只启用一次 dsh-knowledge-canvas,重启 Harness。
v0.4.42026-10-23
缩小画布时,节点不再因宽度计算不一致而互相堆叠。 · 标题模式按知识库/单节点设置的真实宽度参与自动排版。 · 排版、节点绘制和连线共用有效尺寸。 · 保留手动摆放的位置;不新增模型调用,不改变知识正文和注入策略。 验证:完整本地检查与打包门禁通过;GitHub Windows/Linux × Node22/24全部通过。同一13节点样本在45%缩放下从7对矩形相交变为0对,94%和65%缩放也无相交。
v0.4.32026-10-23
· 折叠子树 · 标题小箭头和右键菜单收起/展开分支,显示已收起的后代数量;支持嵌套折叠和全部展开。 · 搜索、按ID定位和未读跳转会展开祖先路径,不展开目标本身或无关分支。 · 折叠保留节点位置;需要收紧空隙时,可主动整理可见节点,隐藏节点保留原坐标。 · 折叠状态按工作区和知识库保存,与模型读取、全文/按需注入及附件策略独立。隐藏端点的关联线一起隐藏,不接到其他节点。 · 正在编辑的子节点须先保存或取消,才能折叠上级;保存失败回滚到已确认状态,删除节点清理残留设置。 验证:Windows/Linux × Node22/24四组CI全部通过;完整回归、真实tarball干净安装及独立浏览器中的箭头、菜单、键盘、刷新恢复、路径定位、坐标保持和编辑保护通过。没有声称FPS提升或token节省。折叠操作不新增模型调用;教程v21正常更新说明文字。 PR #9
数据来自仓库的 GitHub Release,可能与插件实际版本不一致。

README

由 DeepSeek 最新模型翻译生成
dsh-knowledge-canvas English · 简体中文 · 使用手册 给 DeepSeek Harness 的知识库:模型靠判断去取,而不是靠相似度。 主要功能 - 知识画布:编辑节点、父子关系和关联线,支持四种布局与节点尺寸调整。 - 收起与查找:折叠暂时不用的分支,搜索时展开目标路径;长文可滚动,缩成标题后可悬停预览。 - 分层注入:知识库设置全文或按需默认方式,单个节点可覆盖。 - 改动审核:查看模型新增、修改、删除的内容,以及节点读写调用记录。 - 日记与回复:按会话保存日记,以日记本视图阅读,并从侧栏回复。 - 节点附件:存放图片和文件,按工作区选择按需或必须读取附件。 完整使用手册 · 版本变更记录 · GitHub Releases 问题 你把一件事讲清楚了,下一段对话它还是不知道 —— 或者更糟,它以为知道,而那条已经过时了。 这不是上下文长度的问题。在一个工作区里实测过: $ node report-kb-use.mjs 50 tool call(s) in the log, 1 session(s) 写 13 次(ops / …) 读 1 次(read-animation) ⚠ 先写后读:第一次写入之前没有读过 写进去 13 次,读出来 1 次 —— 而那次读的还是另一个库。知识被记录了,而没有被用。
展开完整文档(README 剩余 1 节)
dsh-knowledge-canvas

English · 简体中文 · 使用手册

给 DeepSeek Harness 的知识库:模型靠判断去取,而不是靠相似度。

主要功能

- 知识画布:编辑节点、父子关系和关联线,支持四种布局与节点尺寸调整。
- 收起与查找:折叠暂时不用的分支,搜索时展开目标路径;长文可滚动,缩成标题后可悬停预览。
- 分层注入:知识库设置全文或按需默认方式,单个节点可覆盖。
- 改动审核:查看模型新增、修改、删除的内容,以及节点读写调用记录。
- 日记与回复:按会话保存日记,以日记本视图阅读,并从侧栏回复。
- 节点附件:存放图片和文件,按工作区选择按需或必须读取附件。

完整使用手册 · 版本变更记录 · GitHub Releases

问题

你把一件事讲清楚了,下一段对话它还是不知道 —— 或者更糟,它以为知道,而那条已经过时了。

这不是上下文长度的问题。在一个工作区里实测过:

$ node report-kb-use.mjs
50 tool call(s) in the log, 1 session(s)
写 13 次(ops / …)
读 1 次(read-animation) ⚠ 先写后读:第一次写入之前没有读过

写进去 13 次,读出来 1 次 —— 而那次读的还是另一个库。知识被记录了,而没有被用。记录是免费的:模型顺手就写了。用才是难的 —— 要用它,得先知道它存在,还得知道哪一条现在还算数。

它哪里不一样

这不是"带搜索框的笔记应用"。四个决定,其余都是它们的推论。

一、触发器行,而不是向量索引

每个节点正文的最后一行写它什么时候适用:

什么时候该想起它:<这个节点适用的情形>

按需模式下,系统提示携带标题、层级和触发器等索引信息,正文由模型调用工具读取;全文模式则会注入正文。触发器的作用是:

- 没有嵌入、没有向量库、没有相似度阈值。 检索是模型在判断,而它判断的依据是一句人写的话
- 一个节点能不能被找到,取决于写它的人有没有说清"什么时候"。 这就是全部的赌注:知识库难的不是存,是被查阅;而被查阅是写法的性质
- 没写的节点会被标出来。 索引里显示 (无触发器),而写工具在你写下的那一刻就告诉你 —— 因为一个全是找不到的节点的库,看起来和一个健康的库一模一样

二、索引是一棵树,不是一堆片段

父子关系本身是信息 ——"这条属于那个主题"。索引按层级展开,所以模型读到的是一套结构,而不是一把碎片。一个全是平级的库也是好库;而一个什么都不挂在任何东西下面的库,通常是失误。

三、审核标记在每一种模式下都保留

模型做的每处改动带 [新增] / [修改] / [已废弃],直到你审过。全文注入时也保留 —— 而那正是最容易丢的地方,也确实丢过:一个测试会话发现它分不出哪些段落还没被审。

四、它会告诉你到底有没有用

report-kb-use.mjs 读插件的 activity.log,回答:这个会话里读了几次、写了几次、以及第一次写入之前有没有读过。上面"问题"里那个数字就是这么来的 —— 也是这个插件不声称任何它没量过的东西的原因。

装

npm(推荐):包名 dsh-knowledge-canvas,在 DSH 的「添加插件」里填它。

手动安装时,在对应profile目录执行 pnpm add dsh-knowledge-canvas@latest,还必须将 dsh-knowledge-canvas 加入该profile的 dsh.profile.bundles(保留已有条目)。仅加入dependencies不会应用插件补丁。安装或升级后重启DSH。

从源码:

// profiles/desktop/package.json
"dependencies": { "dsh-knowledge-canvas": "link:<仓库路径>" },
"dsh": { "profile": { "bundles": [ ..., "dsh-knowledge-canvas" ] } }

本仓库、发布包与前端模块注册名均使用 dsh-knowledge-canvas。内部 Cordis id、标签页标识、路由及数据目录保留旧标识以兼容现有数据;不要把这些内部标识当成安装包名。

面板上能做什么

认位置

| 位置 | 是什么 |
| 顶上那排 | 搜索框、已读计数、刷新 |
| 每个库一行 | 标题、已读进度、一个开关(这个会话读不读它)、⋯ 菜单(改名、删除、颜色、导出) |
| 画布工具栏 | 缩放、适应、宽度(整库默认宽度,不是单个节点)、形状、颜色、布局 |
| 左下「定位到…」 | 输入 id 直接跳到那个节点,不用肉眼找 |

手势

| 动作 | 结果 |
| 单击节点 | 打开编辑器;再点一次关闭 |
| Enter / 空格(聚焦时) | 同上,键盘可达 |
| Shift+Enter | 开始连线;在目标上按 Enter 完成 |
| 拖动节点 | 移动;位置写进 layout.json |
| 按住约 0.26 秒再拖 | 画关联线(橙色),不是改父子关系 |
| Alt + 拖动节点 | 把目标变成它的父节点(灰线) |
| 右键节点 | 菜单:新建子节点 / 看修改历史 |
| 右键空白画布 | 菜单:新建父节点(顶层) |
| 拖出画布到输入框 | 把这个节点交给对话 |
| 节点右下角三个把手 | 改宽、改高、同时改 |

节点宽高有三层含义:这个节点的宽度 → 整库默认宽度 → 画布缩放。工具栏那个「宽度」改的是第二层。

视图与布局

四种布局:分层、放射、阶梯、紧凑。切换布局重算默认摆放,手动位置仍由你控制。

点标题箭头或右键菜单可折叠子树;嵌套折叠会保留,搜索、定位和未读跳转会展开目标的祖先路径。工具栏支持全部展开,以及主动整理可见节点。折叠只改变画布显示,不限制模型读取或注入。

长文正文可独立滚动,并提供编辑入口。缩小到只显示标题时,悬停或聚焦节点会出现阅读预览。

模型工具

| 工具 | 用途 |
| knowledge_read | 读一个库或一个节点;不给 base 时列出所有库 |
| knowledge_create_base | 建库,自带一个根节点。建完立刻可用,不需要再 knowledge_select |
| knowledge_write_node | 写或改一个节点。返回里带着刚建出来的节点 id,可以直接拿它当 parent |
| knowledge_link | 连两个节点,必须写一句"为什么相关",那句注释会出现在对方的视图里 |
| knowledge_unlink | 断开一条关联;节点不动,只去掉那条虚线 |
| knowledge_remove_node | 标记移除(不删数据,可还原) |
| knowledge_select | 开关某个库对本会话是否可见 |
| knowledge_remove_base | 把一个库标记为移除(可恢复,不是删文件) |
| knowledge_show_images | 把一个节点挂的图片作为图片交给模型(按需模式下可单独调用;必须读取模式随节点返回图片) |

为什么是这个形状:模型拿到的东西必须可核对。每个节点的正文最后一行写「什么时候该想起它:…」,那一行被抽出来放大纲里 —— 所以模型按场景匹配,而不是按向量相似度猜。它读错了,你能在画布上直接看见并改掉。

设置:按工作区

设置 → 知识库,每个工作区一块:

- 这个工作区的路径(一眼确认你在改哪个)
- 记录调用过程 —— 打开后模型每调一次工具都会记一条,面板顶上显示「正在检索 n3(知识库插件的教程)」。默认关。
- 每个库一个 按需索引 / 全文注入 选择(前者给标题和要点,后者把正文也塞进去);面板上那一行的开关是另一件事:这个会话读不读它

每个库有全文或按需的默认方式,单个节点可在编辑器或右键菜单中选择覆盖或跟随默认。覆写按工作区共享,仅作用于所选节点。按需索引仍有上下文成本;全文额度和超额行为见使用手册。附件读取策略独立设置。

工作区列表 = 会话里出现过的目录 ∪ 磁盘上有 .dsh-knowledge/ 的目录。后者从 $DSH_HOME/sessions/ 的目录名还原(那里每个会话一个目录,名字就是工作区路径,分隔符换成了 -),所以重启之后不会只剩一个工作区。

日记模式(可选)

给不想整理笔记、只想有人记得的人。面板顶上打开,按会话生效。

打开之后,那个会话在聊到一个段落时会自己写一篇 —— 写到属于它自己的那个库,不按天,也不在别的会话里写。

- 每个会话一份 diary-<哈希>.json。开关是会话级的,数据也是:同工作区的另一个会话既看不到它,也读不到它。
- 落盘是密文(AES-256-GCM)。模型 cat 那个文件只会看到 base64。
- 提示词只给约定,不给口吻。 人设由你的预设决定,插件不替你写信。

日记默认以日记本视图打开,支持按月目录、前后篇切换和修改记录;需要编辑时可切回画布。书页底部可直接回复,回复会连同该篇的正文节选送入当前会话,不替换聊天输入框中的草稿。回复记录与日记正文分开保存。

它不做什么

边界比功能更该写清楚:

- 不是聊天记录。 它不自动记录对话,只记你或模型显式写进去的东西。
- 不同步到云端。 全部在 <工作区>/.dsh-knowledge/ 下,普通 JSON,可以用记事本打开、提交进 git、整个拷走。没有账号、没有服务器。
- 日记的加密挡的是"顺手看见",不是"想读的人"。 密钥由库名派生,读过这份源码的人可以解开。要挡住会翻文件的模型,需要密钥不落盘(口令或系统凭据),那是另一个设计。
- 不替你写人设。 日记模式注入的是一段写作约定,不是语气。
- 不做全文检索。 搜索框搜的是标题和正文的子串,没有倒排索引,也没有向量。

文件长在哪

<工作区>/.dsh-knowledge/ ├── <库 id>.json 每个库一个文件:节点、连线、seed 指纹 ├── selection.json 这个工作区默认读哪些库、怎么注入、记录调用过程 ├── layout.json 位置、宽度、形状、颜色 ├── .sessions/<id>.json 这一个会话自己的开关(含日记) └── activity.log 工具调用记录(仅当「记录调用过程」打开)

- 宿主(index.js、lib/)负责:注入点、工具、路由、种子教程、日记约定。
- 面板(client.js)负责:画布、手势、编辑器、设置页。它直接读这些 JSON 文件,不走宿主的接口 —— 所以"面板看不到某个库"时,先查它自己读到了什么,而不是查宿主。
- 大纲在每次模型调用前组装,只放标题、要点和触发行;正文要模型主动 knowledge_read。

给改代码的人

- npm run check:all 跑四样:标识符、精灵图宽高比、公开树检查、以及存储/路由/工具三层断言(数目以运行输出为准)。
- 改了手势,就改教程里对应那句(lib/seed.js 顶层的操作表),否则教程会描述一个不存在的操作。
- 旧工作区的教程按内容认(谁的节点 id 与种子重合过半,谁就是教程),不是按文件名 —— 这一条是被三个工作区用三种文件名教育出来的。

第一次用

① 装完重启一次 → 侧边栏出现「知识库」 ② 展开「怎么用这个知识库」→ 那就是教程,讲的就是这个面板 ③ 随便找一段对话,跟模型说:"把刚才的结论写进知识库" → 它会调 knowledge_write_node,节点出现在画布上 ④ 在画布上拖动它、给它连一条线、改一遍正文 ⑤ 下一段对话里问它一件旧事 —— 如果它读了,面板顶上会出现「正在检索 xxx(id)」(这需要先在设置里打开「记录调用过程」)

判断它有没有用的那个数字:node report-kb-use.mjs —— 它数日志里"写了几次、读了几次",以及第一次写入之前有没有读过。

常见问题

面板里看不到某个库。 先看那个库的开关,再看你所在的会话有没有自己的开关(面板顶上「开关作用于 默认 / 仅本会话」)。会话级的列表是一份快照;新建的库会被自动补进去,但手工关掉的不会自己回来。

日记在别的会话里也能看见。 不该。日记按会话隔离,四层都过滤:大纲、面板、工具、以及提示词。如果还看得见,查那个会话的 .sessions/<id>.json 里 diary 是不是 true —— 那份文件属于那个会话,它看见了就是它开着。

改完代码没生效。 分两半:改的是 client.js(面板)→ 刷新页面,必要时硬刷新;改的是 index.js / lib/(宿主)→ 重启 DSH。混在一起猜会浪费很多次重启。

发布之后 registry.npmjs.org 上查不到新版本。
npm 的自动审查没结束,版本状态是 Validating。这期间 tarball 是 404 —— 404 不等于没发出去。等它变成 Published 再判断。

教程没更新。 教程只在工作区第一次使用时种下,之后靠"种子版本"和"内容指纹"升级;而且它按内容认教程(节点 id 与种子重合过半的就是它),所以你把那个库改了名也不影响升级。

开发

npm run check:all # 4 项检查 + 断言全绿

改 index.js / lib/* 后必须重启 Harness(宿主那一半在进程启动时加载一次);改 client.js 后刷新页面即可。

许可

MIT

附件

节点的正文下面可以挂文件:粘贴截图、拖进虚线框、或者点「+ 添加附件」选。图片直接画在卡片里(限高 160 px,点开看原图),其它文件显示成 📎 文件名,点开在新标签查看。

附件按内容存放在 .dsh-knowledge/assets/,同一份文件挂两次只存一份。在 DSH「设置 → 知识库」中,每个工作区可选择附件读取方式:

- 按需读取(默认):knowledge_read 返回节点正文和附件清单,不自动发送图片或附件正文。模型可用同一工具的 attachment 参数读取指定附件;文本支持 offset / limit(字符数,每次最多 8,000)。图片也可使用 knowledge_show_images。
- 必须读取:读取节点或整库时自动返回可解析的文本、Office 内容和图片。每份文本最多 8,000 字符,每次最多 6 张图片;超过限制会提示续读方式。图片会增加视觉 token 消耗,选择此模式不会保证模型一定理解或采用附件。

此选项独立于「全文注入/按需索引」,不会把图片自动塞进系统提示词。PDF、压缩包等尚不支持文本提取的附件会列出路径;缺失文件或图像传递失败会明确提示。手动把节点拖进对话时,仍按会话附件发送,不受该工具设置控制。

例如:knowledge_read({"base":"notes","node":"n1","attachment":"assets/0123456789abcdef.txt","offset":8000,"limit":2000})。附件必须由该节点引用,不能读取任意路径。
预览分享卡片长什么样 ↓NeoHotaru/dsh-knowledge-canvas
分享 · DeepSeek Harness Hub
NeoHotaru/dsh-knowledge-canvas

给 DeepSeek Harness 的知识库:模型靠判断去取,而不是靠相似度。

回到顶部