给 DeepSeek Harness 用的本地文件夹知识库插件:把公司资料目录建成一个中文可用的检索索引,写方案 /…
30.4/100
综合分
1
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/10/3 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
自动兼容检查有告警:未发布到 npm registry,仅可从源码安装。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add wu81313-lab/dsh-company-kb该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:已验证
是什么
dsh 原生插件 · search
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
更新放缓:最近一次提交在 33 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查⚠ 装前注意未发布到 npm registry,仅可从源码安装
展开查看检查明细 ↓
以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。
✗npm 包dsh-company-kb(未发布到 npm,仅可源码安装)
✓Node 引擎要求 ^22.19.0 || >=24.0.0 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明
验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/3 12:26:39
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 41 处,展示前 40 条)
- 读取本地文件lib/index.js:19
const pkg = JSON.parse(readFileSync(url, 'utf8')); - 发起网络请求lib/client.js:33
const response = await fetch(`${API}${path}`, { - 读取本地文件lib/core.js:87
ok = existsSync(root) && statSync(root).isDirectory(); - 读取本地文件lib/core.js:87
ok = existsSync(root) && statSync(root).isDirectory(); - 读取本地文件lib/core.js:198
if (!existsSync(target)) { - 读取本地文件lib/web.js:68
const size = statSync(path).size; - 读取本地文件lib/web.js:82
createReadStream(path, { start, end }).pipe(res); - 读取本地文件lib/web.js:87
createReadStream(path).pipe(res); - 读取本地文件lib/web.js:238
const stat = statSync(target.path); - 读取本地文件lib/web.js:242
buffer: readFileSync(target.path), - 读取本地文件lib/web.js:270
const stat = statSync(target.path); - 读取本地文件lib/settings.js:89
mtime = statSync(settingsPath).mtimeMs; - 读取本地文件lib/settings.js:100
cachedRaw = JSON.parse(readFileSync(settingsPath, 'utf8')); - 写入本地文件lib/settings.js:116
mkdirSync(dirname(settingsPath), { recursive: true }); - 写入本地文件lib/settings.js:118
writeFileSync(tmp, `${JSON.stringify(next, null, 2)}\n`, 'utf8'); - 写入本地文件lib/settings.js:119
renameSync(tmp, settingsPath); - 写入本地文件lib/store.js:54
mkdirSync(dirname(databasePath), { recursive: true }); - 读取本地文件lib/store.js:445
databaseBytes = statSync(databasePath).size; - 读取本地文件lib/store.js:447
if (existsSync(wal)) databaseBytes += statSync(wal).size; - 读取本地文件lib/store.js:447
if (existsSync(wal)) databaseBytes += statSync(wal).size; - 删除本地文件递归lib/ocr.js:28
try { rmSync(dir, { recursive: true, force: true }); } catch { } - 写入本地文件lib/ocr.js:31
writeFileSync(jobPath, JSON.stringify({ jobs }), 'utf8'); - 执行外部命令来自配置/变量lib/ocr.js:37
execFile( - 读取本地文件lib/ocr.js:44
parsed = JSON.parse(readFileSync(outPath, 'utf8')); - 读取本地文件lib/scan.js:49
rootStat = statSync(absolute); - 读取本地文件lib/scan.js:63
entries = readdirSync(current.dir, { withFileTypes: true }); - 读取本地文件lib/scan.js:81
info = statSync(absolutePath); - 读取本地文件lib/scan.js:104
return createHash('sha1').update(readFileSync(path)).digest('hex'); - 执行外部命令固定命令lib/open.js:28
const child = spawn('explorer.exe', [verbatimArg], { - 执行外部命令固定命令lib/open.js:45
const child = spawn('powershell.exe', [ - 读取本地文件lib/extract/index.js:40
const result = extractDocx(readFileSync(path)); - 读取本地文件lib/extract/index.js:44
const result = extractXlsx(readFileSync(path)); - 读取本地文件lib/extract/index.js:48
const result = extractPptx(readFileSync(path)); - 删除本地文件递归lib/extract/media.js:47
try { rmSync(dir, { recursive: true, force: true }); } catch { } - 读取本地文件lib/extract/media.js:53
const zip = readZip(readFileSync(path)); - 写入本地文件lib/extract/media.js:54
mkdirSync(dir, { recursive: true }); - 写入本地文件lib/extract/media.js:74
writeFileSync(target, data); - 读取本地文件lib/extract/text.js:45
const buffer = readFileSync(path); - 读取本地文件lib/cli.mjs:19
const text = readFileSync(patchPath, 'utf8'); - 读取本地文件lib/selftest.mjs:16
const text = readFileSync(fileURLToPath(new URL('../cordis.patch.yml', import.meta.url)), 'utf8');
扫描于 2026/11/2(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
功能亮点
- 本地文件夹建索引
- 中文混合检索
- Web面板
DSH 本地文件夹知识库:手动同步的 SQLite FTS5 索引,中文混合检索(BM25 + CJK 二元组 + 三元组,RRF),显式调用门控,外加一个 Web 面板。
README
由 DeepSeek 最新模型翻译生成dsh-company-kb
给 DeepSeek Harness 用的本地文件夹知识库插件:把公司资料目录建成一个中文可用的检索索引,写方案 / 投标 / 核政策时按需调用;只在用户明确点名时检索,只在用户手动触发时同步。
- 索引对象:本地任意目录(在面板「设置」页填 roots),只读,插件永不写入
- 检索方式:中文分词 BM25 + 中文二字组合 + trigram 子串 → RRF 融合(全离线,零外部服务)
- 文档预览:.docx / .xlsx / .pptx 由插件自己解析成带排版的 HTML(Word 保留标题/表格/图片, Excel 是真表格网格,PPT 是分页卡片)——不启动 Office、不转 PDF、不写临时文件
- 图里的字也能搜:文档内嵌图片(架构图、界面截图)走 OCR,按 sha1 缓存,重建不重复识别
- 同步方式:纯手动(面板按钮 / 明确要求 / 命令行),没有任何定时器
- 交付形态:5 个模型工具 + Web 面板(侧边栏底部面板入口 / 会话开关 / 设置页)+ company-kb 技能
安装
环境要求:DSH 0.1.5 及以上,Node.js ^22.19.0 || >=24.0.0;OCR 与旧版 Office 抽取需要 Windows(可选,缺了不影响其它格式)。
展开完整文档(README 剩余 1 节)
dsh-company-kb
给 DeepSeek Harness 用的本地文件夹知识库插件:把公司资料目录建成一个中文可用的检索索引,写方案 / 投标 / 核政策时按需调用;只在用户明确点名时检索,只在用户手动触发时同步。
- 索引对象:本地任意目录(在面板「设置」页填 roots),只读,插件永不写入
- 检索方式:中文分词 BM25 + 中文二字组合 + trigram 子串 → RRF 融合(全离线,零外部服务)
- 文档预览:.docx / .xlsx / .pptx 由插件自己解析成带排版的 HTML(Word 保留标题/表格/图片, Excel 是真表格网格,PPT 是分页卡片)——不启动 Office、不转 PDF、不写临时文件
- 图里的字也能搜:文档内嵌图片(架构图、界面截图)走 OCR,按 sha1 缓存,重建不重复识别
- 同步方式:纯手动(面板按钮 / 明确要求 / 命令行),没有任何定时器
- 交付形态:5 个模型工具 + Web 面板(侧边栏底部面板入口 / 会话开关 / 设置页)+ company-kb 技能
安装
环境要求:DSH 0.1.5 及以上,Node.js ^22.19.0 || >=24.0.0;OCR 与旧版 Office 抽取需要 Windows(可选,缺了不影响其它格式)。
方式一:从 GitHub 安装(pnpm 原生支持 git 源)
dsh plugin --profile <你的 profile> add github:wu81313-lab/dsh-company-kb
方式二:克隆到 profile 的 plugins/ 目录后按本地目录安装
cd <DSH_HOME>/profiles/<你的 profile>
git clone https://github.com/wu81313-lab/dsh-company-kb.git plugins/dsh-company-kb
dsh plugin --profile <你的 profile> add ./plugins/dsh-company-kb
确认 package.json 的 dsh.profile.bundles 含本行,并校验组合树
dsh --profile <你的 profile> --dump-config | findstr company-kb
重启 profile(宿主侧改动需要重启),然后刷新页面(客户端 bundle 需要刷新)
安装后打开「设置 → 插件 → 本地知识库」填好资料目录,再点面板「立即同步」建库。
卸载:dsh plugin --profile <你的 profile> remove dsh-company-kb,再从 dsh.profile.bundles 移除该行;数据目录 ~/.dsh/local-kb 可整体删除,知识库原文件夹自始至终零改动。
快速上手
1. 先在「设置 → 插件 → 本地知识库」填好资料目录(roots),然后首次建库(二选一):
- 打开左栏「本地知识库」→ 点「立即同步」(首次约 1–5 分钟,含扫描件 OCR)
- 或在终端:node lib/cli.mjs index
2. 在对话里点名使用:
- 用知识库查一下 XX 政策的条款要求
- 按 模板/技术方案书模板.docx 写一份 XX 项目方案
- 或点输入框右侧的「知识库 已关」开关
3. 资料更新后手动同步:面板「立即同步」,或说"同步一下知识库",或 node lib/cli.mjs index。
不点名、不打开开关,检索工具会直接返回一段说明而不会去查资料。
目录结构
lib/
index.js Cordis 插件入口:装配内核、注册工具、注入状态提示段、挂载 Web API core.js 内核:设置 + 索引库 + OCR 桥 + 同步引擎的组合,供工具/面板/CLI 共用 store.js SQLite(node:sqlite) + 双 FTS5 索引 + RRF 融合检索 segment.js 中文分词、二字组合、FTS 查询构造与转义 bigram.js 中文相邻二字组合(解决分词器把"袋线瓶线"切碎的问题) chunk.js 分块:标题面包屑、页码、重叠、超长段落切分 scan.js 同步引擎:遍历 diff → 抽取 → 写库;手动触发,无定时器 gate.js 显式调用门禁(触发词 / 路径点名 / 会话开关 / 同步意图) prompt.js 状态提示段(未启用 / 已启用 / 尚未建库 / 索引已过期) tools.js kb_search / kb_read / kb_list / kb_status / kb_session web.js 宿主 HTTP API(同源,供面板调用) ocr.js OCR / Word 助手桥(临时文件传参,不用管道) ocr-helper.ps1 Windows PowerShell 5.1 + WinRT:PDF 渲染、图片 OCR、Word COM open.js 用系统默认程序打开 / 在资源管理器中定位(explorer /select + 前台提权) focus-helper.ps1 把资源管理器窗口提到前台(后台进程默认不许抢前台,靠 AttachThreadInput 提权) settings.js 运行时设置(settings.json,热生效) client.js 客户端 bundle(手写 __ModuleLoader__ + React.createElement) render/ 文档预览:docx → 排版化 HTML、xlsx → 表格网格、pptx → 分页卡片(零依赖) cli.mjs 命令行:status / probe / index / search / read / list selftest.mjs 验收自测:抽取覆盖率 + 15 条金标查询 extract/ zip / docx / xlsx / pptx / text / media(零第三方依赖) test/ node --test 单测(门禁、分词、分块、索引、HTTP、手动同步语义、面板渲染、文档预览) skills/company-kb/ 技能:检索流程与引用规则数据目录(可整体删除):%USERPROFILE%\.dsh\local-kb\ → index.sqlite、settings.json
工具
| 工具 | 作用 |
| kb_search | 混合检索,返回文件相对路径、标题层级、页码、docId 与高亮片段;可按 dir / ext / days 限定范围 |
| kb_read | 读某个文件的抽取正文(分页);二进制文件只返回完整路径。传 open:true 则用本机默认程序打开原文件 |
| kb_list | 浏览目录(名称/大小/字数/状态),不确定资料在哪时用 |
| kb_status | 状态、失败清单、体检结果、面板接口状态;action=now/rebuild 手动同步,progress 看进度 |
| kb_session | 本会话开关(on/off/status),只有在用户明确要求时才该调用 |
Web 面板
挂在 DSH 自己的 Web 服务下(同源路由 /company-kb-api/,仅回环可访问,不开新端口):
- 侧边栏底部「本地知识库」(在「设置」按钮上方,独占一行):索引概况(文件数/字符/检索片段/上次同步/失败/待同步变化)、立即同步、重建索引、中止、进度条、搜索(含原文预览与失败清单)、同步记录
- 搜索框下面有筛选行:类型(Word / Excel / PPT / PDF / 图片 / 文本)、时间(近 30/90 天/一年)、目录,比如"只看近 90 天的投标文件"。
- 「未抽取正文的文件」清单里每项都能单独重抽,也可以一次「全部重抽」——只重抽这几个文件,不是整库重建。
- 面板分「搜索」「同步记录」两个页签;/company-kb-api/tree 与 kb_list 工具仍可用于浏览目录,只是不再占用面板页签。
- 该入口挂在 sidebar.footer.action(与「上下文洞察」同一个行容器),插件把这一行改成竖排,于是「上下文洞察」/「本地知识库」/「设置」各占一行、不会互相挤压、标签也不会被截成「本…」。
宿主的类名是 CSS Module 哈希(每次构建都会变),所以规则写成 后缀匹配 + :has() 兜底
([class="_footerActions"]:has(.dslkb-foot));侧栏收窄成图标条时自动退回圆形图标形态。
- 原文预览(点搜索结果或「同步记录」里的文件名即打开):
- 「用本机程序打开」= 交给系统默认程序,等价于双击:.docx/.doc → WPS/Word,.xlsx → WPS/Excel,.pptx → PowerPoint,.pdf → PDF 阅读器;.dwg 等图纸同理。打开后你可以直接在里面查看甚至编辑(原文件本身仍是你的,插件不参与写入)。
- 「在文件夹中显示」= 在资源管理器中定位该文件,并把资源管理器窗口提到前台(focus-helper.ps1)。
- 图片与 PDF 在面板内直接渲染(/raw 直出原文件)。
- .docx / .xlsx / .pptx 走排版预览(/preview):插件解析文件结构渲染成 HTML —— Word 保留标题层级、加粗斜体、列表、表格、内嵌图片;Excel 渲染成真正的表格网格(行号列标、合并单元格、多工作表、日期/百分比/千分位格式);PPT 渲染成分页卡片。可随时切到「抽取正文」看纯文本。
这一路不启动 Office、不转 PDF:79MB 的投标 docx 渲染 3935 段 + 38 表 + 287 图只需 210ms。
旧版 .doc/.xls/.ppt 是二进制格式,仍只显示抽取的文字。
- 从检索结果点开的文档会自动滚到第一处命中并高亮,上方有「命中 N 处 / 上一处 / 下一处」;高亮做在服务端渲染阶段(只作用于已转义的纯文本),不会碰坏文档结构。
- 「重建索引」防误触:点它会先弹出确认框(写清代价与影响、并强调原文件不会被修改),点「确认重建」才开始;Esc 或点遮罩可取消。
- 每次操作都有可见反馈:开始后在按钮下方出现「已开始…」横幅 + 进度条,跑完变成「✓ 重建完成:新增 102|耗时 54.2s|内嵌图片 575 张」这样的结果横幅(20 秒后自动消失)。
- 预览区可自由调整:拖中间的竖条改左右宽度(26%–80%)、拖预览右下沿改高度(320–1200px),也可以直接点「紧凑 / 标准 / 加高 / 满屏」;满屏会隐藏结果列表、预览占满窗口(Esc 退出)。
双击手柄或按 Home 恢复默认;手柄支持方向键微调。选择记在浏览器 localStorage,刷新后仍在。
- 预览右上角还有「新标签页」:把渲染好的整页丢给浏览器,用整屏看长文档。
- 输入框右侧「知识库」开关:切换本会话是否允许检索(等价于点名)
- 设置 → 插件 → 本地知识库:根目录、同步方式、显式调用、路径点名、trigram、旧版 Office 处理、触发词(全部热生效,不用重启)
面板不可用时(例如客户端 bundle 没加载)工具与索引照常工作。
配置
行配置在 cordis.patch.yml(启动默认值),运行时覆盖在 ~/.dsh/local-kb/settings.json(面板写入,热生效)。
| 键 | 默认 | 说明 |
| roots | [] | 索引根目录,数组,可多个;为空时同步会提示"尚未配置索引根目录" |
| autoSync | 'off' | 'off' 纯手动;'watch' 文件变化即增量同步(事件驱动,仍无定时器) |
| stalenessHint | true | 打开面板/查状态时做一次 stat 体检,只报"有多少文件变了",不动库 |
| explicitOnly | true | 未点名不许检索 |
| pathTriggers | true | 消息里出现库内文件名/目录名也算点名 |
| triggers | 知识库 / 资料库 / 公司资料 / 公司知识库 / /kb … | 点名触发词,可改 |
| include / excludeDirs / excludeGlobs | 常见文本与 Office 格式 | 决定抽取范围(不匹配的文件只登记元数据) |
| maxFileBytes | 256MB | 本地解析保险丝;PDF/图片走 OCR 不受它限制 |
| legacyDoc | 'word-com' | 旧版 .doc/.xls 用本机 Word 取正文;设 'skip' 则只按文件名检索 |
| trigram | true | 子串索引(更全,占用更大) |
| chunkChars / chunkOverlap | 900 / 150 | 分块大小与重叠 |
| topK / maxChunksPerDoc | 8 / 3 | 返回条数与单文件最大块数 |
| ocrWidth / maxOcrPagesPerFile | 1600 / 60 | OCR 渲染宽度与单文件页数上限 |
| ocrEmbeddedImages | true | 识别文档内嵌图片里的文字(架构图/截图也能搜到) |
| embeddedImageMinBytes | 20KB | 小于这个体积的图按 logo/图标跳过 |
| maxEmbeddedImagesPerFile | 40 | 单文件最多识别多少张内嵌图 |
| exposeWeb / webPath | true / /company-kb-api | 面板 API 开关与路径 |
手动同步模型(本插件与"自动同步"的边界)
- 索引只在三种显式触发下变化:面板按钮 / 用户明确要求(kb_status action=now,同样过门禁)/ CLI。
- 启动不扫描:只打开数据库、校验 schema,并做一次"体检"(stat 比对,只报告差异)。
- 检索结果与状态卡会提示"索引之后有 N 个文件变化",提醒你手动同步,但绝不偷偷重建。
- 每次同步按文件单事务提交:中止、断电、DSH 重启都不会留下半写的块,下次同步自然续做。
- 同步摘要(新增/更新/删除/跳过/失败/耗时)写入 sync_log,面板「同步记录」可查;每条记录下面还会逐文件列出这次到底同步了哪些内容(新增 / 更新 / 删除 / 失败四组,带相对路径;新增与更新的文件可一键在资源管理器中定位)。老记录没有明细,就只显示摘要。
「立即同步」与「重建索引」的区别
| | 立即同步(平时用这个) | 重建索引 |
| 做什么 | 遍历目录,按 大小 + 修改时间 找出变化,只抽取这些文件 | 先清空索引,再把所有文件重新抽取一遍 |
| 耗时 | 通常几十毫秒~几秒 | 全量重抽,含扫描件 OCR 与旧版 Office:本机 102 个文件约 3.5 分钟 |
| 适合 | 日常资料更新后 | 改过影响索引本身的设置(trigram 开关、分块大小/重叠、OCR 页数上限、旧版 Office 抽取方式);调整过 roots/排除规则后想让历史文件按新规则重来;升级插件后想把新的解析规则应用到所有文件;怀疑索引与磁盘不一致 |
| 副作用 | 无 | 重建期间检索结果会变少甚至为空(索引被清空后逐步补回),所以别在正查资料时点;可随时「中止」,下次同步续做 |
| 相同点 | 都只动插件自己的索引库(docs / chunks / 两张 FTS 表),从不碰知识库里的原文件;同步记录、会话开关、设置都不会被清掉 | |
一句话:改了资料 → 立即同步;改了设置或想让老文件彻底重来 → 重建索引。
内嵌图片 OCR(图里的字)
- 有正文的 Office 文档也会抽内嵌图片做 OCR:架构图标签、界面截图、表格截图里的字本来完全搜不到。
- 三个刹车:小于 embeddedImageMinBytes(默认 20KB)的图当 logo 跳过;单文件最多 maxEmbeddedImagesPerFile(默认 40)张;结果按图片内容 sha1 缓存,重建索引时同一张图不再重复识别。
- 第一次开启会慢一些(本机语料 34 个文件 / 668 张图,约 6 分钟),之后重建只需要几秒。
- 新开的开关不需要整库重建:插件给每个文档记了 media_ocr 标记,下次普通同步会把还没做过的 Office 文件逐个补做一次。
- 识别出来的文字会带 【图片N】 前缀单独成块,引用时能看出"这段来自图片"。
只重抽某几个文件
同步记录里失败的文件(needs_ocr / needs_conversion / 抽取报错)可以在面板上单独重抽,不必整库重建;命令行等价动作是 POST /company-kb-api/resync {"rels":["某个文件.docx"]}。
日志里这次同步会记成 同步(retry),明细照常列出改了哪些文件。
为什么这样检索
| 技术选择 | 原因(均为实测) |
| 预分词后写入 FTS | SQLite unicode61 不切中文:原文直索 MATCH '追溯' 命中 0 条,分词后可命中并 BM25 排序 |
| 加中文二字组合 | Intl.Segmenter 把"袋线瓶线"切成 袋\|线\|瓶\|线,单字被丢弃后检索失败;补二字组合后 2 字查询走正常词元 |
| trigram 子串路 | 覆盖分词切不准的场合;2 字查询 trigram MATCH 无效,因此 1 字查询才退化为 LIKE |
| RRF 融合 | BM25 是负分、子串路是名次,量纲不同不能直接相加;RRF 只看名次 |
| 每文件最多 3 块 | 避免一份文件刷满结果,保证结果覆盖多个来源 |
| 全离线 | 公司资料不出本机:不调用任何外部 API、不装服务、不开端口 |
抽取能力
| 格式 | 方式 |
| .docx .xlsx .pptx | 自解析 ZIP + XML(表格按行、表名/幻灯片作标题),零第三方依赖 |
| .md .txt .csv .json .log … | 直读,带 UTF-8/UTF-16/GB18030/Big5 编码探测 |
| .pdf | Windows.Data.Pdf 渲染到内存 → Windows 内置中文 OCR(zh-cn),逐页标记 |
| .png .jpg … | 直接 Windows OCR |
| 纯图片 docx | 正文为空时抽出内嵌图片单独 OCR(架构图、截图型文档) |
| .doc .xls | 本机 Word COM(晚绑定、禁用宏、只读、一份文件一批 + 超时隔离) |
| .dwg .apk .zip … | 只登记元数据,结果里给出完整路径供其它工具打开 |
OCR / Word 都不可用时不会报错中断:相应文件标为 needs_ocr / needs_conversion 并在状态里列出。
故障排查
| 现象 | 处理 |
| 面板显示"面板连接失败" | 先跑 kb_status 看"面板接口"一行:已注册 = 接口正常(多半是没刷新页面);未注册:运行时没有 webServer 服务 = 宿主启动顺序问题(本插件会轮询等服务出现,最多 30 秒,若仍失败说明该 profile 没有 webServer 行);注册失败: xxx = 按错误信息定位 |
| 面板接口路径被占用 | 改 webPath(默认 /company-kb-api)后重启;重复注册会由 webServer 抛 duplicate 错误并记录在本插件的状态里 |
| 检索说"尚未建库" | 还没手动同步过:点面板「立即同步」或 node lib/cli.mjs index |
| 搜不到刚放进去的资料 | 这是手动同步模型:先同步(结果里会提示"索引之后有 N 个文件变化") |
| 某个文件没有正文 | kb_status 看失败清单:needs_ocr(扫描件/纯图片)、needs_conversion(旧版 Office)、metadata(二进制或超限) |
| 点「在文件夹中显示 / 用本机程序打开」没反应 | 四个已知坑:Node 给 /select,路径 自动加引号后 explorer 解析不了、detached 进程不弹窗、windowsHide 会把 explorer 自己创建的窗口藏起来、窗口开在浏览器后面(Windows 不允许后台进程抢前台,看起来就像没反应)。前三个已按"手动拼 /select,"完整路径" + windowsVerbatimArguments + 不 detach + 不隐藏"修掉;第四个由 focus-helper.ps1 在定位后把窗口提到前台(AttachThreadInput 提权)。可用 node test/reveal-probe.mjs "<文件路径>" reveal 复现,再用 PowerShell 对比前台窗口标题验证 |
| 排查时想确认窗口到底有没有弹出 | 用 PowerShell 枚举可见窗口对比前后即可;不要用 $js \| node 把含中文路径的脚本从 stdin 喂进去——管道按本地代码页转码,中文路径会变乱码,容易误判"无效" |
| Word 提取偶发卡死 | 已按"一份文件一批 + 75s 超时"隔离;仍频繁出现可设 legacyDoc: 'skip',或在设置页关掉 |
| 排版预览和原件长得不一样 | 这是阅读还原而不是像素级排版:字体度量、分页、文本框/SmartArt/公式/图表不还原(内容不会丢,降级成普通文字)。要看原样请点「用本机程序打开」 |
| 预览里图片不显示 | 预览图片走 /media 从压缩包里直接读(不落盘)。若某张图是"链接式"引用(r:link 而非 r:embed)则取不到——这属于原文件本身引用了外部图片 |
| 预览渲染很慢或空白 | .docx/.xlsx/.pptx 才走排版预览;旧版 .doc/.xls/.ppt 是二进制格式,只看得到抽取的文字。可用 node test/render-probe.mjs "<文件路径>" 看渲染统计与告警 |
| 索引体积过大 | 设置页关掉 trigram 后重建;或删除 ~/.dsh/local-kb 重新建库 |
| 预览窗口太小 / 想记不住尺寸 | 拖竖条改宽度、拖预览右下沿改高度,或点「紧凑/标准/加高/满屏」;选择存在浏览器 localStorage(键 dslkb.layout.v1),清掉浏览器数据会回到默认。窄窗口(≤1100px)会自动改为上下堆叠,此时竖向拖拽不可用,高度仍可调 |
| 内嵌图片 OCR 太慢 | 设置页把「单文件最多识别」调小、或把「KB 以下跳过」调大;也可以直接关掉开关。缓存按图片 sha1 命中,重建不会重复识别 |
| 搜不到图里的字 | 确认「识别文档内嵌图片里的文字」是开着的,然后跑一次同步(插件会自动补做没做过的 Office 文件) |
| 从检索结果打开文档没滚到命中处 | 只有 .docx/.xlsx/.pptx 的排版预览支持高亮;旧版 .doc/.xls 只有纯文本,图片文字(【图片N】)也不在正文流里 |
验收
node --test test/*.test.mjs # 77 项单测:门禁/分词/分块/索引/HTTP/面板渲染/文档预览/内嵌图片 OCR/重抽/预览布局/回环校验
node lib/selftest.mjs --rebuild # 全量重建 + 抽取覆盖率 + 15 条金标查询
node lib/cli.mjs status # 状态与失败清单
node lib/cli.mjs search "关键词"
单测里 手动同步语义 一项是这套设计的核心保证:新增文件后直接检索必须搜不到,手动同步后才搜得到,删除后同步即消失。
安全边界
- 插件对知识库目录只读:只调用读操作,从不写入、移动或删除其中任何文件。
- /preview 只读解析已在索引中、且位于配置根目录之内的文件,渲染结果放进 iframe(沙箱 + CSP:禁止脚本、禁止外部请求),文档里的文本一律转义。
- 唯一的写入目标是 ~/.dsh/local-kb/(索引库与设置)与系统临时目录(OCR 中间文件,用完即删)。
- Web API 挂在 DSH 自身站点下(默认 127.0.0.1:8080),能力仅"读索引 + 触发同步 + 读写插件设置
+ 打开/直出已在索引中且位于配置根目录之内的文件";接口只接受回环 Host(挡 DNS rebinding)。
若把 DSH 暴露到公网,该接口与 DSH 本身同权,请用反向代理加登录保护。
- /open、/reveal、/raw 都先经 resolveOriginal() 校验:文件必须在索引里、路径必须落在 roots 之内、且磁盘上确实存在,否则一律 403/404;打开动作是"只读打开"(把文件交给关联程序),插件不写入原文件。
- Word 提取以 AutomationSecurity = 3(强制禁用宏)只读打开文档。
License
MIT © wu81313-lab预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
wu81313-lab/dsh-company-kb
给 DeepSeek Harness 用的本地文件夹知识库插件:把公司资料目录建成一个中文可用的检索索引,写方案 /…
相关插件 · 搜索 / 抓取
LLM 知识平台Tencent/WeKnora
概览 ·快速开始 ·新特性 ·功能 ·客户端 ·文档 ·开发
★ 36,161已汉化DSH
72.1
智能体记忆系统MemTensor/MemOS
MemOS 2.0 Stardust星尘
★ 12,195已汉化DSH
71.2
跨代理记忆库zilliztech/memsearch
跨平台语义记忆,专为 AI 编程智能体打造。
★ 2,799已汉化DSH
70.9
技能语料库EverMind-AI/SkillCorpus
SkillCorpus 能给你什么
★ 694已汉化DSH
69.7
代码图谱记忆syncable-dev/memtrace-public
你的智能体值得拥有结构化记忆。
★ 509已汉化MCP
67.9
AnySearch 搜索插件anysearch-team/anysearch-dsh
AnySearch 网页搜索服务商,为 DeepSeek Harness(DSH)提供高级搜索工具
★ 457已汉化DSH
66.6