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

科研工作台 58catmiao/dsh-sciwork

DeepSeek Harness
58catmiao11 天前有提交已提供中文文档扫描:含敏感能力

dsh-sciwork 把「科研模式」装进 DeepSeek Harness:一个落在自己硬盘上的科研库、一套技能与一块面板。课题、图、草稿、文献、数据表、期刊档案、投稿台账各有其位,写入都经库脚本落盘并登记,面板只读为主、自己不出图…

31.5/100
综合分
2
GitHub 星标
—
npm 周下载
—/5
用户评分

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

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add 58catmiao/dsh-sciwork
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

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

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

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

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

可执行外部命令读写/删除本地文件写入剪贴板(不计风险)发起外部网络请求
查看扫描证据(共 103 处,展示前 75 条)
  • 写入剪贴板
    lib/client.js:528
    navigator.clipboard.writeText(props.text).then(
  • 写入剪贴板
    lib/client.js:3951
    navigator.clipboard.writeText(text);
  • 读取本地文件
    lib/library.js:57
    try { return (await stat(p)).isDirectory(); } catch { return false; }
  • 读取本地文件
    lib/library.js:61
    try { return (await stat(p)).isFile(); } catch { return false; }
  • 读取本地文件
    lib/library.js:65
    try { return JSON.parse(await readFile(p, 'utf8')); } catch { return fallback; }
  • 读取本地文件
    lib/library.js:88
    const items = await readdir(p, { withFileTypes: true });
  • 读取本地文件
    lib/library.js:139
    return await stat(abs);
  • 读取本地文件
    lib/library.js:218
    const info = await stat(abs);
  • 写入本地文件
    lib/library.js:283
    await copyFile(abs, backupAbs);
  • 写入本地文件
    lib/library.js:284
    await writeFile(abs, body, 'utf8');
  • 写入本地文件
    lib/library.js:317
    await mkdir(path.dirname(abs), { recursive: true });
  • 写入本地文件
    lib/library.js:318
    await writeFile(abs, body, 'utf8');
  • 读取本地文件
    lib/config.js:124
    return existsSync(cmd) ? path.resolve(cmd) : null;
  • 读取本地文件
    lib/config.js:133
    if (existsSync(candidate)) return candidate;
  • 读取本地文件
    lib/config.js:172
    for (const c of candidates) if (c && existsSync(c)) return c;
  • 读取本地文件
    lib/config.js:190
    if (explicit && existsSync(explicit)) return path.resolve(explicit);
  • 读取本地文件
    lib/config.js:195
    for (const g of guesses) if (existsSync(g)) return path.resolve(g);
  • 读取本地文件
    lib/config.js:206
    if (explicit && existsSync(explicit)) return path.resolve(explicit);
  • 执行外部命令固定命令
    lib/actions/system.js:189
    execFile('git', ['-C', dir, ...args], { timeout: timeoutMs, windowsHide: true }, (error, stdout, stderr) => {
  • 读取本地文件
    lib/actions/system.js:203
    text = await readFile(file, 'utf8');
  • 发起网络请求
    lib/actions/system.js:253
    const res = await fetch(RAW_PACKAGE, { signal: AbortSignal.timeout(timeoutMs), headers: { 'cache-control': 'no-cache' } });
  • 读取本地文件
    lib/import.js:113
    await stat(path.join(dirAbs, candidate));
  • 读取本地文件
    lib/import.js:160
    if (existsSync(inLib)) return inLib;
  • 读取本地文件
    lib/import.js:162
    return existsSync(inBundle) ? inBundle : null;
  • 执行外部命令来自配置/变量
    lib/import.js:188
    child = spawn(interpreter, [script, ...args], {
  • 写入本地文件
    lib/import.js:288
    await mkdir(dirAbs, { recursive: true });
  • 写入本地文件
    lib/import.js:293
    await writeFile(dest, buf);
  • 读取本地文件
    lib/import.js:390
    if (!existsSync(root)) return fail('not-found', `科研库根目录不存在:${root}`);
  • 读取本地文件
    lib/import.js:394
    if (!existsSync(path.join(root, 'projects', project))) {
  • 读取本地文件
    lib/import.js:467
    const info = await stat(abs).catch(() => null);
  • 写入本地文件
    lib/import.js:472
    await mkdir(dirAbs, { recursive: true });
  • 写入本地文件
    lib/import.js:483
    await copyFile(abs, dest);
  • 写入本地文件
    lib/archive.js:83
    await mkdir(path.dirname(toAbs), { recursive: true });
  • 写入本地文件
    lib/archive.js:85
    await rename(fromAbs, toAbs);
  • 写入本地文件
    lib/archive.js:88
    await copyFile(fromAbs, toAbs);
  • 删除本地文件
    lib/archive.js:89
    await unlink(fromAbs);
  • 读取本地文件
    lib/archive.js:95
    const st = await stat(abs);
  • 读取本地文件
    lib/archive.js:111
    if (!existsSync(root)) return fail('not-found', `科研库根目录不存在:${root}`);
  • 读取本地文件
    lib/archive.js:124
    for (let i = 2; existsSync(path.join(root, ARCHIVE_ROOT, id)); i += 1) id = `${baseId}-${i}`;
  • 写入本地文件
    lib/archive.js:171
    await mkdir(dirAbs, { recursive: true });
  • 写入本地文件
    lib/archive.js:172
    await writeFile(path.join(dirAbs, 'manifest.json'), JSON.stringify(manifest, null, 1), 'utf8');
  • 读取本地文件
    lib/archive.js:196
    if (!existsSync(root)) return fail('not-found', `科研库根目录不存在:${root}`);
  • 删除本地文件
    lib/archive.js:229
    await unlink(abs);
  • 写入本地文件
    lib/archive.js:239
    await mkdir(path.dirname(logAbs), { recursive: true });
  • 读取本地文件
    lib/archive.js:271
    manifest = JSON.parse(await readFile(manifestAbs, 'utf8'));
  • 读取本地文件
    lib/archive.js:285
    if (existsSync(destAbs)) {
  • 读取本地文件
    lib/rename.js:46
    try { return await stat(p); } catch { return null; }
  • 读取本地文件
    lib/rename.js:87
    try { entries = await readdir(dirAbs, { withFileTypes: true }); } catch { return; }
  • 读取本地文件
    lib/rename.js:101
    try { projects = await readdir(path.join(root, 'projects'), { withFileTypes: true }); } catch { return out; }
  • 读取本地文件
    lib/rename.js:118
    try { raw = await readFile(abs, 'utf8'); } catch { continue; }
  • 写入本地文件
    lib/rename.js:146
    await copyFile(abs, bakAbs);
  • 写入本地文件
    lib/rename.js:148
    await writeFile(abs, JSON.stringify(obj, null, 1) + eol, 'utf8');
  • 写入本地文件
    lib/rename.js:171
    for (const p of pending) await rename(p.fromAbs, p.toAbs);
  • 写入本地文件
    lib/rename.js:177
    await rename(p.fromAbs, tmpAbs);
  • 写入本地文件
    lib/rename.js:180
    for (const s of staged) await rename(s.tmpAbs, s.toAbs);
  • 读取本地文件
    lib/rename.js:215
    try { raw = await readFile(fromAbs, 'utf8'); } catch { raw = null; }
  • 读取本地文件
    lib/rename.js:231
    const members = (await readdir(dir, { withFileTypes: true })).filter((e) => e.isFile()
  • 读取本地文件
    lib/audit.js:73
    try { return (await stat(p)).isFile(); } catch { return false; }
  • 读取本地文件
    lib/audit.js:76
    try { return (await stat(p)).isDirectory(); } catch { return false; }
  • 读取本地文件
    lib/audit.js:81
    try { return JSON.parse(await readFile(p, 'utf8')); } catch { return null; }
  • 读取本地文件
    lib/audit.js:86
    try { return await readdir(dir, { withFileTypes: true }); } catch { return []; }
  • 读取本地文件
    lib/audit.js:259
    try { text = await readFile(abs, 'utf8'); } catch { continue; }
  • 发起网络请求
    lib/refmeta.js:108
    res = await fetch(url, {
  • 执行外部命令固定命令
    lib/backup.js:72
    const r = spawnSync('tar', args, { encoding: 'utf8', cwd, ...opts });
  • 读取本地文件
    lib/notes.js:141
    const exists = await stat(path.join(dirAbs, file)).then(() => true, () => false);
  • 读取本地文件
    lib/notes.js:160
    const info = await stat(dirAbs).catch(() => null);
  • 读取本地文件
    lib/notes.js:164
    const entries = await readdir(dirAbs, { withFileTypes: true });
  • 读取本地文件
    lib/notes.js:171
    const st = await stat(abs).catch(() => null);
  • 读取本地文件
    lib/notes.js:198
    const info = await stat(abs);
  • 读取本地文件
    lib/notes.js:201
    const text = await readFile(abs, 'utf8');
  • 写入本地文件
    lib/notes.js:238
    await mkdir(dirAbs, { recursive: true });
  • 写入本地文件
    lib/notes.js:249
    await copyFile(abs, `${abs}.bak`);
  • 写入本地文件
    lib/notes.js:251
    await writeFile(abs, text, 'utf8');
  • 写入本地文件
    lib/notes.js:294
    await mkdir(dirAbs, { recursive: true });
  • 写入本地文件
    lib/notes.js:305
    await rename(abs, path.join(dirAbs, target));
扫描于 2026/11/4(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

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

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
展开完整介绍(211 字)↓

dsh-sciwork 把「科研模式」装进 DeepSeek Harness:一个落在自己硬盘上的科研库、一套技能与一块面板。课题、图、草稿、文献、数据表、期刊档案、投稿台账各有其位,写入都经库脚本落盘并登记,面板只读为主、自己不出图。技能把「怎么画、怎么写、怎么引」固化成纪律:出图交给 Origin 链路,写作、引用、投稿格式各有专门技能,外加 12 份期刊档案兜底。零 npm 依赖,路径运行时解析,换台机器照样跑。

README

由 DeepSeek 最新模型翻译生成
dsh-sciwork · DSH 科研模式 给 DSH(DeepSeek Harness)装上一整套「做科研」的工作台:一个叫科研模式的智能体预设,加上一个本机的实体科研库。 版本 0.3.14 · MIT · 作者 58catmiao · 仓库 <https://github.com/58catmiao/dsh-sciwork> English: README.en.md 这是什么 dsh-sciwork 不是一个「帮你查文献」的对话框,而是一套落在你硬盘上、可被别的工具打开的科研工作台。装上它,你会同时得到四样东西: 1. 一个智能体预设「科研模式」——它把绘图、写作、文献、期刊规范四条线收进同一个工作流:先找证据,再动手;出图走 Origin 真机,稿子里引用的每一条文献都必须带 DOI 或 URL。 2. 一个本机实体科研库——一棵普通目录(课题 / 图表 / 数据 / 草稿 / 文献 / 期刊档案 / 投稿),配套一个 Python 引擎 research.py 和一个登记索引。 3. 12 份期刊投稿档案——Nature、Science、Cell、IEEE Trans、ACS、Elsevier 通用、MDPI、PLOS ONE、中文核心、CNKI 学位论文、GB/T 7714、通用学位论文,各自的数值要求、条款与出处摘要。
展开完整文档(README 剩余 1 节)
dsh-sciwork · DSH 科研模式

给 DSH(DeepSeek Harness)装上一整套「做科研」的工作台:一个叫科研模式的智能体预设,加上一个本机的实体科研库。

版本 0.3.14 · MIT · 作者 58catmiao · 仓库 <https://github.com/58catmiao/dsh-sciwork>

English: README.en.md

这是什么

dsh-sciwork 不是一个「帮你查文献」的对话框,而是一套落在你硬盘上、可被别的工具打开的科研工作台。装上它,你会同时得到四样东西:

1. 一个智能体预设「科研模式」——它把绘图、写作、文献、期刊规范四条线收进同一个工作流:先找证据,再动手;出图走 Origin 真机,稿子里引用的每一条文献都必须带 DOI 或 URL。
2. 一个本机实体科研库——一棵普通目录(课题 / 图表 / 数据 / 草稿 / 文献 / 期刊档案 / 投稿),配套一个 Python 引擎 research.py 和一个登记索引。
3. 12 份期刊投稿档案——Nature、Science、Cell、IEEE Trans、ACS、Elsevier 通用、MDPI、PLOS ONE、中文核心、CNKI 学位论文、GB/T 7714、通用学位论文,各自的数值要求、条款与出处摘要。
4. 一个「科研库」可视面板 + 一组技能——默认是工作台,旧面板七个页签一键可回,只读为主、能筛能导入能归档;技能负责把「该怎么画、该怎么写、该怎么引」固化成纪律。

权威来源永远是文件系统。 索引只是缓存,面板的写入永远走库脚本,不直接改索引。所以科研库随时可以整目录打包带迁移,也可以直接用资源管理器、Git、别的编辑器去碰。

- 宿主半边是纯 Node ESM,零 npm 依赖。
- 客户端是手写的单文件 Web 客户端,没有构建步骤。
- 出图能力依赖上游开源插件 dsh-origin-plugin(MIT,作者 Fantasality)。本仓库不包含它,只带适配技能。详见〈与 dsh-origin-plugin 的关系〉。

0.3 有什么不同

- 一条能力清单:动作登记表驱动面板、智能体工具与命令行三个入口,新能力只写一份。
- 写动作要确认:先计划(会写哪些文件、有什么 warning),再确认(一次性令牌),最后留回执;读动作不写库。
- 课题是一等公民:七阶段机 + 产物 sha256;旧库课题第一次写之前会提示迁移(先备份、幂等、可回滚)。
- 工作台默认:默认进「工作台」(v2),页头右上角一个按钮可切回旧「列表面板」(v1),选择会被记住,切换时不再丢页签。工作台按「页头(标题 + 统计 + 中文主入口)→ 指标条(课题 / 图 / 文献 / 在投)→ 跨课题待办表格 → 概览仪表 → 课题两栏」排布;仪表有今日该做、投稿倒计时、库体检、最近动态、备份,待办行可一键复制「生成指令」;页头「快速登记」按命令清单生成中文表单(文献入库 / 登记图溯源 / 记一条投稿),提交仍走「计划 → 确认 → 回执」。
- 七阶段可点选:课题详情里的阶段条改成按钮,点任一阶段即走 project.stage.set(跳阶段自动带 force,回退会把后续阶段重置为待办)。
- 面板自带配色与字体:「石墨蓝」色板 12 个 --rl- 变量(明暗两套,light-dark()),不引用宿主颜色 token,正文/次级/主色对比度 ≥ 4.5:1;字体 Noto Sans SC(回退微软雅黑 / system-ui),数字等宽对齐;表格关键列着色加粗。
- 图表页能看见真实出图目录:_ 前缀的出图文件夹(如 figures/_ZT-1100-2h_v4/)不再被当成内部目录过滤;只排除 _history / _archive / _templates / _fetched 这类明确的内部目录。

安装

三条通道,装的是同一个东西;按你手边的界面选一条。

| 通道 | 怎么装 | 说明 |
| 官方插件页(侧栏「插件」→ 添加插件) | 填 github:58catmiao/dsh-sciwork | 也可以填 ZIP 解压后的绝对路径;装完点「立即启用」 |
| 终端 | dsh plugin --profile <profile> add github:58catmiao/dsh-sciwork | dsh plugin 把参数转给 profile 里的 pnpm 执行 |
| 插件市场(「插件 → 发现」) | 先加索引 URL(见通道 3),再从「发现」页装 | 市场只读你给的索引,不自动抓 GitHub |

通道 1:官方插件页

侧栏「插件」→ 添加插件,输入框里填:

github:58catmiao/dsh-sciwork

装完对话框给一个「立即启用」;新组合包默认启用。重启 Harness 面板才出现。

通道 2:终端

dsh plugin --profile <profile> add github:58catmiao/dsh-sciwork
为什么带 github: 前缀:这个包没有发布到 npm 仓库,直接写 add dsh-sciwork 会让包管理器去 npm 找、回一个 404(或“npm 找不到这个包”)。github:58catmiao/dsh-sciwork 是从 GitHub 装,装完 profile 里会多一条 "dsh-sciwork": "github:58catmiao/dsh-sciwork"。

装完重启 Harness。

通道 3:插件市场(加索引)

DSH 的市场(插件 → 发现)不抓 GitHub、也不猜仓库名:它只读你手动填进去的索引 URL。本仓库自带一份索引(market/plugins.json,git 源、钉死到发布 commit),把这条 URL 加进市场索引即可:

https://raw.githubusercontent.com/58catmiao/dsh-sciwork/main/market/plugins.json

前提:这个市场由可选组合包 @deepseek-ai/dsh-experimental-plugin-market-bundle 提供;本机没装的话「发现」页不会出现,那就走通道 1 / 2(等价)。

第三方市场 dshmarket 用的是它自己的精选目录,读不到这份索引;想在它里面装得等它收录,或者直接走通道 1 / 2。

索引在每次发版后由 node scripts/make-market-index.mjs --commit v<版本> 重写(把版本钉到该 tag 的 commit),所以市场装到的版本是确定、可复现的。node scripts/test-install.mjs 会核对这份索引的 format 与 commit。

没有 npm / pnpm,或者上面那条命令报 npm 找不到

dsh plugin 是把参数转给 profile 里的包管理器(PNPM)执行的,所以它要求本机能跑 pnpm——有些机器上 DSH 的运行时里没有带,就会报“npm/pnpm 找不到”。这种情况不需要任何包管理器,两条退路:

退路 A(推荐):解压 ZIP + 一句话接线

1. 在 GitHub 页面点 Code → Download ZIP,解压到一个固定目录(例如 D:/apps/dsh-sciwork);
2. 在该目录里跑:

node scripts/install-plugin.mjs --profile <profile> --source .

它会做三件事:给 profile 的 package.json 加依赖行(link: 到该目录)、把 <profile>/node_modules/dsh-sciwork 链接过去、把 dsh-sciwork 加进 dsh.profile.bundles;改之前自动备份 package.json.bak-<时间戳>。加 --dry-run 可以先看会改什么。

(插件页的「添加插件」也能直接填这个解压目录的绝对路径,效果相同。)

退路 B:有 git 但没包管理器

git clone https://github.com/58catmiao/dsh-sciwork.git
cd dsh-sciwork
node scripts/install-plugin.mjs --profile <profile> --source .

装完同样要重启 Harness;验证方式是 dsh --profile <profile> --dump-config | grep -c dsh-sciwork(应大于 0)。

装完没变化 / 面板报错怎么查

| 现象 | 先查什么 |
| 命令回 404 或“找不到这个包” | 安装源写了吗?要写 github:58catmiao/dsh-sciwork(npm 上没有这个包) |
| 报 npm / pnpm 找不到 | 走上文的「退路 A」,不依赖包管理器 |
| 重启后面板还是旧的 | 面板是客户端 bundle:关掉 Harness 再打开,只刷新页面不算 |
| 面板里点「检查更新」说不是 git 工作树 | 这份安装是拷贝/链接到 ZIP 目录的,不是 git 仓库;更新要重新解压 ZIP 再跑一遍 install-plugin.mjs(从市场装的也是拷贝,同理) |
| 装了但侧栏没有「科研库」 | dsh --profile <profile> --dump-config 看有没有 name: dsh-sciwork 这一段;没有就是 bundle 没进 dsh.profile.bundles |
| 市场「发现」页里搜不到本插件 | 索引 URL 加了吗(见通道 3);市场组合包装了吗 |
| 技能没出现 | 0.3.13 起随包注册;若 ~/.dsh/skills/<名字>/SKILL.md 已存在,插件会跳过(有意为之:删掉旧目录重启即可换成包内版本) |

装完后你会多出:

- 一个 ID 为 research 的智能体预设「科研模式」(可直接在会话里选)——科研只有一个模式:课题的七阶段(选题 → 设计 → 数据 → 分析 → 成图 → 写作 → 投稿)都在这个模式里推进,阶段只是课题 project.json 里的一个字段,不再单设阶段预设;
- 侧栏多一个面板入口「科研库」(默认进工作台,页头报插件版本、可点「检查更新」);
- 一条精确注册的只读路由 /api/research/call(面板靠它取快照与执行动作);
- 六个技能:research-studio 总控、research-stages 七阶段路线、origin-plot、paper-writing、 literature-refs、journal-profile。0.3.13 起由插件激活时注册(runtime 技能),不必再手动跑 scripts/install.mjs;你自己往 ~/.dsh/skills 装过同名的,插件会跳过、不覆盖。

前置:本机有 Node(宿主半边与自检脚本用它)与一个可用的 Python 3 解释器(科研库引擎 research.py 用它)。不要求 python 出现在 PATH 上——启动器会按「显式配置 → SCIWORK_PYTHON → 库自己的 venv → Origin 插件目录的 venv → PATH」逐个探测。出图另需 Origin,见下文。

快速开始

1. 建库

先预检:不写任何文件,只报告缺什么
node scripts/install.mjs --verify-only

预检通过后建库
node scripts/install.mjs

安装脚本会建出库根目录、.research/ 引擎与索引、journals/ 期刊档案、refs/ 文献库。库根默认是 <用户目录>/Research(Windows 即 %USERPROFILE%\Research),可用环境变量 SCIWORK_LIBRARY 改。

安装脚本的可用开关:

| 开关 | 说明 |
| --verify-only | 只检查,不写任何文件。 |
| --library-root <dir> | 指定库根,覆盖配置里的 libraryRoot。 |
| --skip-library | 不铺科研库骨架(只装插件半边)。 |
| --force-skills | 目标已存在且没有 SKILL.md 时也覆盖安装技能目录。 |

库根解析顺序:--library-root / 环境变量 SCIWORK_LIBRARY(旧名 RESEARCH_LIBRARY 兼容)→ 内核 library/config.json 的 libraryRoot → <用户目录>/Research。注意库内已有的 .research/config.json 里的 libraryRoot 也会覆盖环境变量——面板与引擎优先听库自己的配置。

2. 打开面板

在 DSH 侧栏点「科研库」。默认进工作台:页头右上角写着当前库根与实时计数(课题 / 图 / 草稿 / 数据 / 文献 / 期刊档案 / 投稿 / 索引时间),下面是待办与概览;点右上角按钮可切到列表面板的七个页签。

3. 让智能体建课题

在会话里选「科研模式」预设,然后直接说:

建一个课题,叫 zt-ceremic,研究 ZrB₂-SiC 陶瓷的氧化行为。

智能体会走 research.py new-project 落目录,之后它画的每一张图、写的每一段结果,都会各自归位到该课题的 figures/、origin/、data/、drafts/ 下。你也可以在面板里点「新建课题」自己建。

4. 出图

面板自己不出图(2026-10-13 起移除)。要出图,直接跟智能体说:

把 projects/zt-ceremic/data/ 里那组 XRD 数据画成对比图,按 MDPI 的排版要求。

智能体会走 Origin 真机绘图、核验、导出,并把图的溯源信息登记回库。

面板:工作台与七个页签

侧栏「科研库」。默认是工作台(v2),页头右上角可切到列表面板(v1)。列表面板有七个页签(图表 / 草稿 / 文献 / 数据 / 期刊档案 / 投稿 / 归档),另有顶部的计数行与「命令台」弹层(两者都不是页签):

工作台(v2)一屏看全库:页头(标题 + 统计 + 快速登记 / 新建课题 / 导入数据 / 检查更新 / 刷新)、指标条(课题 / 图 / 文献 / 在投)、跨课题待办表、概览(今日该做 / 投稿倒计时 / 库体检 / 最近动态 / 备份)、课题两栏。页签行右侧的搜索框在 v2 里筛的是课题与待办:课题列表、跨课题待办、今日该做、库体检、最近动态一起过滤,顶部给命中数与「清空筛选」,空结果按种类给明确空状态(指标条始终按全库算,不随筛选变)。选中课题后,详情里还有一条本课题产物速览(图 / 草稿 / 数据 / 表 / 工程 / 文献 / 在投):数字是该课题已登记的产物数与相关文献、在投记录;点数字跳到列表页签并自动带上这个课题当筛选词,只留它的条目(数量为 0 的按钮置灰)。页头还报出插件当前版本:首屏只读本地 package.json,点「检查更新」才去 GitHub 比对,有新版本时旁边给「更新到 vX.Y.Z」——更新做到 git pull --ff-only,只对干净的 git 工作树生效,完成后提示重启 Harness。

| 页签 | 看什么 | 能做什么 |
| 计数行(面板顶部,不是页签) | 库根路径、课题/图/草稿/数据/文献/期刊档案/投稿七项实时计数、索引时间、采集警告 | 点「刷新」重取快照;点「引导」走一遍带高亮的界面导览 |
| 图表 | 已登记的图,含每条图的登记溯源(数据源、脚本、生成时间);按课题分组 | 看图、看 PDF 附带件、复制路径、归档、删除 |
| 草稿 | drafts/ 下的 Markdown 手稿 | 就地读;新建草稿;编辑保存;归档;删除 |
| 文献 | refs/refs.json 里的条目与 refs/pdf/ 下的本地 PDF 附件 | 导入(必须带 DOI 或 URL 才登记,PDF 可选)、看 PDF、归档、删除 |
| 数据 | data/ 下的数据文件(.txt/.csv/.dat 等)与按课题分组的分组头 | 预览行列、数据变换(6 个算子)、归档、删除 |
| 期刊档案 | 12 份档案的 id、严格度(high / medium / low)与更新日期 | 读条款与数值要求;筛选;归档 |
| 投稿 | submissions/ 下的投稿记录(目标刊、状态、时间线) | 读记录;筛选;归档;投稿闸门:选期刊 → 合规体检 → 导出投稿包 |
| 归档 | .research/archive/<时间戳>/ 里的批次清单 + 真删记录 | 整批 / 单文件「恢复」搬回原位;真删记录只留名字 |
| 命令台(弹层,不是页签) | research.py 的子命令清单与参数表单 | 选命令 → 填参 → 执行 → 看 stdout / stderr / JSON 结果 |

数据变换的 6 个算子:normalize(归一化)、baseline(扣基线)、smooth(平滑)、peaks(找峰)、integrate(积分)、linear(线性变换)。每次变换都会在新表旁落一份溯源记录(.research/transforms/<课题>/<表名>.json),并把产物写进课题的 tables/。
投稿闸门(0.2 新增):在「投稿」页签选一个课题与期刊档案,点「体检」得到逐条结论——图宽是否够单/双栏、分辨率够不够、格式该不该矢量、图注有没有、标题与摘要字数、参考文献与 DOI 覆盖、草稿里的引用键是否都在库里。每条标 pass / warn / fail / na,并写明依据(source)与置信度;档案没写的项一律 na,不拿默认值冒充期刊要求。点「导出投稿包」把稿件、图、数据、refs.bib 收进一个 zip(含逐文件 sha256 的 manifest 与 checklist),路径落在 submissions/packages/。体检结果与期刊档案一样,最终以刊方现行要求为准。

面板的边界,一句话说清:能看、能筛、能导入、能归档、能删、能对表格做数据变换、能做投稿前体检和打包;不出图。所有写入都经库脚本落文件并登记,面板自身不碰登记索引。

配置

配置有两层,库内 <库根>/.research/config.json 是权威;环境变量用来告诉 DSH 去哪找库、用哪个 Python。

| 环境变量 | 默认值 | 说明 |
| SCIWORK_LIBRARY | <用户目录>/Research | 科研库根目录。改这里等于换库。 |
| RESEARCH_LIBRARY | 未设置 | 旧名,兼容保留;SCIWORK_LIBRARY 优先。 |
| SCIWORK_PYTHON | 依平台探测 | 跑 research.py 用的 Python 解释器。推荐显式指向 venv 里的 python。 |
| SCIWORK_ORIGIN_PLUGIN | 未设置 | dsh-origin-plugin 所在目录,供适配技能定位它。 |

库内权威配置:

| 路径 | 说明 |
| <库根>/.research/config.json | 权威配置:库根、语言、期刊档案严格度偏好、索引设置等。 |
| <库根>/.research/index.json | 登记索引(只是缓存,可由 research.py reindex 从文件系统重建)。 |
| <库根>/.research/archive/ | 归档区。面板上的「归档」是移动到此处,可恢复。 |
| <库根>/.research/lock | 库写锁,防止并发写入互相踩。 |

目录结构

<库根>/ # 默认 <用户目录>/Research,可用 SCIWORK_LIBRARY 改 ├── projects/ │ └── <课题>/ │ ├── figures/ # 成图(导出的 png / svg / pdf / tif) │ ├── origin/ # Origin 工程文件(.opju),可在 Origin 里继续编辑 │ ├── data/ # 原始数据 │ ├── tables/ # 由数据变换派生的表 │ └── drafts/ # 该课题的手稿片段 ├── refs/ │ ├── refs.json # 文献条目(必须带 DOI 或 URL) │ └── pdf/ # 本地 PDF 附件(可选) ├── journals/ # 期刊投稿档案 ├── submissions/ # 投稿记录与时间线 └── .research/ # 引擎与元数据 ├── research.py # 库操作的唯一权威入口 ├── config.json # 权威配置 ├── index.json # 登记索引(缓存,可重建) ├── archive/ # 归档区(可恢复) ├── transforms/<课题>/ # 数据变换的溯源记录 └── lock # 写锁

登记(加文献、登记出图溯源、重建索引)永远由 research.py 做,面板不代劳。常用子命令:new-project、add-ref、register-figure、add-submission、reindex。

科研库的权威入口:research.py

库的一切结构化写入都由它完成(面板的「命令台」弹层就是它的可视化前端)。

读:

| 子命令 | 说明 |
| status | 库概况:课题数、文献数、已登记图数、期刊档案数。 |
| search <关键词> | 跨课题检索(课题 / 图 / 稿 / 数据 / 文献 / 期刊 / 投稿),可加 --kind、--project、--limit。 |
| list-projects / list-figures / list-refs / list-submissions | 分别列课题、已登记图、文献、投稿记录,各自支持筛选参数。 |
| check-citations --draft <路径> | 引用核查闸门:非零退出即代表稿子里有缺失或未核实的引用。加 --require-doi 要求每条都必须有 DOI。 |
| check-journal --project <slug> [--journal <id>] | 期刊合规体检:按期刊档案逐条比对图件尺寸/分辨率/格式、图注、标题与摘要字数、参考文献与 DOI、引用键;每条 pass/warn/fail/na,有 fail 时退出码 1。 |

写:

| 子命令 | 说明 |
| init | 建 / 修复库骨架(幂等)。 |
| new-project <slug> | 新建课题,可带 --title、--journal。 |
| add-ref | 文献入库。必须带 DOI 或 URL(引用零编造);--verified-by 记录核实方式。 |
| register-figure | 登记一张图的溯源侧车:源数据、Origin 图页、所用期刊档案、图注。 |
| add-submission / update-submission | 登记一次投稿 / 推进投稿状态与事件时间线。 |
| export-package --project <slug> [--journal <id>] | 投稿包:稿件 + 图 + 数据 + refs.bib 打 zip 到 submissions/packages/,附逐文件 sha256 的 manifest.json 与 checklist.md。 |
| reindex / export-bib | 重建库索引(递归子目录、收录正文)/ 重建 refs.bib。 |

不可逆:remove-ref 删掉一条文献登记(会先备份 refs.json)。

Windows 上库内附了一个 Python 包装器 .research/bin/py.cmd,它会按库配置挑解释器;agent 文档里给的调用示例走的就是它。想自己指定解释器,用环境变量 SCIWORK_PYTHON。

期刊档案一览

| 档案 id | 是什么 | 严格度 |
| nature | Nature 系列 | high |
| science | Science 系列 | medium |
| cell | Cell 系列 | medium |
| ieee-trans | IEEE Transactions | medium |
| acs | ACS 系列 | medium |
| elsevier-generic | Elsevier 通用 | medium |
| mdpi | MDPI 系列 | high |
| plos-one | PLOS ONE | high |
| chinese-core-journal | 中文核心期刊 | medium |
| cnki-thesis | CNKI 学位论文 | low |
| gbt-7714 | GB/T 7714 参考文献格式规范 | low |
| thesis-generic | 通用学位论文 | medium |

严格度影响默认排版与校验口径;每份档案里还有具体数值与出处摘要。回看哪份档案、怎么用,见技能 journal-profile。

技能

| 技能 | 管什么 |
| research-studio | 总入口。路由表 + 三条硬纪律 + 开工前 30 秒例行检查 + 交付前自检清单 + 如实报告(能证明什么、不能证明什么)。 |
| origin-plot | Origin 绘图纪律。数据进 Origin、四条画图路径、改图前先看现状、两个核验步骤都要做、导出交付与登记、绝不抢占用户正在使用的 Origin 会话,以及一份实测坑清单。内含 74 个 origin_ MCP 工具的用法。 |
| paper-writing | 动笔前的证据纪律、图注、Results、Discussion 结构与框架、中→英与润色、回复审稿意见(Response Letter)、交稿前自检。 |
| literature-refs | 四条硬规则、入库、检索(先有证据再入库)、稿子里怎么引用、列出与导出、与写作技能配合、常见坑。 |
| journal-profile | 期刊档案怎么读、怎么用。档案字段、给绘图/写作供参数、选刊(用户问"投哪本")、新建或更新档案、与库脚本配合、冲突与变更。 |

技能是纪律文本,不是代码:它们约束 agent 的行为,不额外引入依赖。

与 dsh-origin-plugin 的关系

- 出图能力来自 dsh-origin-plugin(MIT,作者 Fantasality),它提供 74 个 origin_* MCP 工具,负责与本机 Origin 通信。
- 本仓库不包含 dsh-origin-plugin,也不复制它的代码;dsh-sciwork 只带一份适配技能 skills/origin-plot,教 agent 按科研交付的要求去用那 74 个工具。
- skills/origin-plot/references/origin-tools.json 是派生文件:由 dsh-origin-plugin 的工具清单生成,用于离线查表(工具名 / 参数 / 用途)。
- 两者可以独立安装。不装 Origin 与 dsh-origin-plugin,dsh-sciwork 的建库、面板、写作、文献、期刊档案部分照常可用,只是「出图」这一步走不通。
- 环境变量 SCIWORK_ORIGIN_PLUGIN 用来告诉适配技能:dsh-origin-plugin 装在哪。

自检

仓库自带四个自检脚本与一个补丁预检,都不写你的正式库(写动作在隔离副本里跑,并有一道硬闸门)。前四个只要 Node;补丁预检是 Python 写的,需要一个非标准库的依赖 PyYAML:

node scripts/selftest-host.mjs # 宿主半边:路由注册、路径守卫、快照形状
node scripts/selftest-actions.mjs # 23 个动作:读/守卫检查 + 隔离副本里的写动作
node scripts/selftest-client.mjs # 客户端:七个页签的渲染、弹层、按钮与请求形状
node scripts/test-install.mjs # 安装面:随包技能、市场索引、包清单、apply 接线
python -m pip install pyyaml # 只给下一步用(CI 里有独立的 Install PyYAML 步骤)
python scripts/validate-patch.py # cordis.patch.yml 预检:预设行数、persona、插入行

想一条命令跑完全部(两周一轮的周期自检就是这么跑的),用 node scripts/cycle.mjs:它把上面这些按 CI 的顺序跑一遍,附一段只读的 git 状态,输出汇总表与退出码,并把完整报告落到 out/cycle/<日期>/(out/ 已 gitignore)。
推送到公开仓库前还有一道门禁:node scripts/check-local-info.mjs(cycle.mjs 也会跑它)。它拿这台机器的家目录、用户名、主机名、临时目录、库根等标记,去扫全部跟踪文件与全部提交信息。命中就说明仓库里带了本机信息——换成 <仓库根> / <库根> / <系统临时目录> 这类占位符再提交。

自检分两种跑法,新克隆的仓库不配库也能跑:

A. 不指向任何科研库(CI / 刚克隆的机器)

node scripts/selftest-host.mjs # 全部通过,退出码 0
node scripts/selftest-actions.mjs # 全部通过 · 0 失败 · 内容类检查自动跳过
node scripts/selftest-client.mjs # 全部通过 · 0 失败 · 内容类检查自动跳过
python scripts/validate-patch.py # ✓ 补丁预检通过

此时所有内容类检查(依赖库里真有草稿 / 图 / 数据表的部分)自动记为 SKIP 或「未运行」,脚本会打印一行说明(未运行:内容类检查需要一个可用的科研库(当前库根 …))并以退出码 0 结束——不配库不算失败。

B. 指向一个真库(数字随库内容浮动,下面是夹具库实测)

SCIWORK_LIBRARY=/path/to/Research node scripts/selftest-actions.mjs # 127 通过 · 0 失败 · 3 跳过
SCIWORK_LIBRARY=/path/to/Research node scripts/selftest-client.mjs # 230 通过 · 0 失败

- selftest-host.mjs —— 只统计通过/失败,退出码 0。唯一可能被记为「跳过」的是「图文件还在」这类依赖真实库里确实有图的检查(没有图时不判失败)。
- selftest-client.mjs —— 汇总行只有通过/失败两项;B 模式下实测 230 通过 · 0 失败,退出码 0。
- validate-patch.py —— 输出 ✓ 补丁预检通过,退出码 0。它会报预设 preset-research 的顶层行数(19 条,递归后叶子 29 条,其中 2 条按 !!js 条件禁用)、嵌套组(planning / compaction / delegation)、persona 长度,以及确认插入的 research-library 行属于宿主插件而非 agent 预设。
- selftest-actions.mjs —— 写动作段要求库根指向脚本自己新建的隔离副本(用 SCIWORK_LIBRARY 指过去即可)。若它发现 snapshot 指向的不是那个副本,会打印 FAIL 隔离闸门:snapshot 指向副本 并以退出码 2 结束,同时一个字节都不写。这是设计行为,不是插件缺陷:写动作永远在副本里跑,绝不碰你的正式库。⚠️ 0.2.1 起 SCIWORK_LIBRARY 优先于随包的 library/config.json(此前次序反了,导致本机把库指向真库时这道闸门永远拿真库当副本、写动作整节被跳过)。

文档地图

| 文件 | 内容 |
| README.md / README.en.md | 这是什么、装什么、怎么用 |
| docs/INSTALL.md | 安装与首次建库(含排错) |
| docs/ARCHITECTURE.md | 工程结构与契约:宿主动作、HTTP 端点、面板边界、路径解析、自检口径 |
| docs/RELEASE.md | 维护者手册:发版、上架插件市场、截图、干净机器验证 |
| docs/CYCLE-14D.md | 维护者手册:14 天周期的 debug / 功能更新 / 同步 GitHub(cycle.mjs、护栏、候选功能池) |
| CHANGELOG.md | 版本变更 |
| THIRD_PARTY_NOTICES.md | 第三方组件与致谢 |

许可证与致谢

License: MIT,版权归 58catmiao。许可证原文见 LICENSE。

Credits / 致谢

- Origin 绘图能力来自 dsh-origin-plugin(MIT,作者 Fantasality)。本仓库不包含它;skills/origin-plot/references/origin-tools.json 派生自它的工具清单,用于离线查表。感谢作者把这套本机 Origin 自动化开源出来。
- DSH(DeepSeek Harness) 提供了插件机制、agent 预设与工具路由,本插件是其上的扩展。
- 期刊档案是本项目自己整理的数值、条款与出处摘要,不是期刊官方文件。

关于内容版权

本仓库不包含任何受版权保护的论文原文或期刊 PDF。

- journals/ 下的 12 份期刊档案,内容是投稿要求的数值、条款与出处摘要(例如字数上限、图表要求、参考文献格式),每条尽量标注出处;遇到具体条款请以期刊官网的最新作者指南为准。
- refs/ 里登记的是你自己的文献元数据(标题、DOI、URL 等)与你自己放进 refs/pdf/ 的附件,仓库不预置任何文献全文。
- 期刊档案是辅助,不构成法律或投稿建议;因以档案替代官方指南而产生的后果,由使用者自负。

dsh-sciwork · 让科研的每一步都落在你自己的硬盘上
预览分享卡片长什么样 ↓58catmiao/dsh-sciwork
分享 · DeepSeek Harness Hub
58catmiao/dsh-sciwork

dsh-sciwork 把「科研模式」装进 DeepSeek Harness:一个落在自己硬盘上的科研库、一套技能与一块面板。课题、图、草稿、文献、数据表、期刊档案、投稿台账各有其位,写入都经库脚本落盘并登记,面板只读为主、自己不出图…

这是你的仓库?认领条目

回到顶部