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

催更姬 mistnest/dsh-cuigengji-plugin

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

催更姬:给大肥鱼一个小说工作台。写正文、理设定、画情节,和 AI 一起讨论、续写与改稿。

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

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

自动兼容检查未通过:engines.node 要求 >=24,不满足 Node 22.19.0。以下命令仍可尝试,但可能失败。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add mistnest/dsh-cuigengji-plugin
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

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

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

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查需源码安装

engines.node 要求 >=24,不满足 Node 22.19.0

展开查看检查明细 ↓

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

✓npm 包dsh-cuigengji-plugin @ 0.5.0
✗Node 引擎要求 >=24 · 基线 Node 22.19 不满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明

源码安装时若 pnpm 拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑。

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/28 06:40:46

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

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

可执行外部命令读写/删除本地文件
查看扫描证据(共 99 处,展示前 91 条)
  • 写入本地文件
    runtime/index.js:50
    await mkdir(join(store.root, "audit"), { recursive: true, mode: 448 });
  • 写入本地文件
    runtime/index.js:51
    await appendFile(join(store.root, "audit", file), JSON.stringify({ time: ( new Date()).toISOString(), ...value }) + "\n", { mode: 384 });
  • 读取本地文件
    runtime/adapters/dsh/rename-installation.js:11
    const stat = await lstat(path).catch((error) => {
  • 读取本地文件
    runtime/adapters/dsh/rename-installation.js:17
    return readFile(path, "utf8");
  • 执行外部命令来自配置/变量
    runtime/adapters/dsh/rename-installation.js:25
    const result = spawnSync(powershell, ["-NoProfile", "-NonInteractive", "-Command", command], {
  • 读取本地文件
    runtime/adapters/dsh/rename-installation.js:38
    const stat = await lstat(profile);
  • 写入本地文件
    runtime/adapters/dsh/rename-installation.js:78
    await mkdir(backup, { recursive: true, mode: 448 });
  • 写入本地文件
    runtime/adapters/dsh/rename-installation.js:80
    await writeFile(join(backup, `${index}.original`), files[index].before, { flag: "wx", mode: 384 });
  • 写入本地文件
    runtime/adapters/dsh/rename-installation.js:82
    await writeFile(join(backup, "manifest.json"), JSON.stringify({
  • 读取本地文件
    runtime/adapters/dsh/rename-installation.js:96
    const invokedFile = process.argv[1] ? await realpath(resolve(process.argv[1])).catch(() => null) : null;
  • 读取本地文件
    runtime/adapters/dsh/rename-installation.js:97
    if (invokedFile === await realpath(fileURLToPath(import.meta.url))) {
  • 读取本地文件
    runtime/adapters/dsh/skills.js:12
    const shared = readFileSync(new URL("../../../skills/cuigengji-project/SKILL.md", import.meta.url), "utf8");
  • 读取本地文件
    runtime/adapters/dsh/skills.js:15
    const task = readFileSync(new URL(`../../../skills/${name}/SKILL.md`, import.meta.url), "utf8");
  • 读取本地文件
    runtime/adapters/dsh/guidance.js:6
    const skill = (name) => body(readFileSync(skillPath(name), "utf8"));
  • 读取本地文件
    runtime/adapters/dsh/rpc.js:5
    const manifest = JSON.parse(readFileSync(new URL("../../../package.json", import.meta.url), "utf8"));
  • 读取本地文件
    runtime/application/libraries/service.js:62
    const stat = await lstat(path);
  • 读取本地文件
    runtime/application/libraries/service.js:64
    names = await readdir(path);
  • 读取本地文件
    runtime/application/libraries/service.js:73
    if ((await readdir(path)).includes("transaction.pending.json")) return { path, kind: "existing", exists: true, recoveryPending: true };
  • 读取本地文件
    runtime/application/libraries/service.js:88
    const source = await realpath(old.store.root), target = await this.inspect(args.path);
  • 写入本地文件
    runtime/application/libraries/service.js:89
    await mkdir(target.path, { recursive: true });
  • 读取本地文件
    runtime/application/libraries/service.js:90
    const destination = await realpath(target.path);
  • 读取本地文件
    runtime/application/libraries/service.js:106
    if ((await readdir(destination)).length) return fail("DIRECTORY_NOT_EMPTY", "\u76EE\u6807\u6587\u4EF6\u5939\u5DF2\u6709\u5185\u5BB9\uFF0C\u8FC1\u79FB\
  • 执行外部命令来自配置/变量
    runtime/application/pet/desktop.js:35
    this.launch = options.launch || (() => spawn(join(process.env.SystemRoot || "C:\\Windows", "System32", "WindowsPowerShell", "v1.0", "powershell.exe"),
  • 读取本地文件
    runtime/application/pet/desktop.js:58
    const value = JSON.parse(await readFile(join(this.root, "pet-desktop.json"), "utf8"));
  • 写入本地文件
    runtime/application/pet/desktop.js:88
    await mkdir(this.root, { recursive: true });
  • 写入本地文件
    runtime/application/pet/desktop.js:90
    await writeFile(temporary, saved, { mode: 384 });
  • 写入本地文件
    runtime/application/pet/desktop.js:91
    await rename(temporary, path);
  • 写入本地文件
    runtime/application/store.js:194
    await writeFile(join(this.root, `before-planning-${hash(migrationNovelId)}.json`), JSON.stringify({ format: "cuigengji", schemaVersion: 1, novel: migr
  • 读取本地文件
    runtime/application/backup/workspace.js:32
    const entries = await readdir(join(this.store.root, dir), { withFileTypes: true }).catch((e) => {
  • 读取本地文件
    runtime/application/backup/workspace.js:39
    const content2 = await readFile(join(this.store.root, path), "utf8");
  • 写入本地文件
    runtime/application/backup/workspace.js:121
    await mkdir(backupDir, { recursive: true });
  • 写入本地文件
    runtime/application/backup/workspace.js:122
    await writeFile(join(backupDir, "workspace.json"), JSON.stringify({ state, files: await this.files(state.activity) }), { flag: "wx", mode: 384 });
  • 读取本地文件
    runtime/application/backup/workspace.js:129
    old = await readFile(path, "utf8");
  • 写入本地文件
    runtime/application/transfer/service.js:124
    await mkdir(backupDir, { recursive: true, mode: 448 });
  • 写入本地文件
    runtime/application/transfer/service.js:125
    await writeFile(join(backupDir, "workspace.json"), JSON.stringify(this.workData.archive(state, await this.workData.files())), { flag: "wx", mode: 384
  • 读取本地文件
    runtime/application/maintenance/upgrade.js:8
    const packageVersion = JSON.parse(readFileSync(new URL("../../../package.json", import.meta.url), "utf8")).version;
  • 读取本地文件
    runtime/infrastructure/persistence/upgrade-backup.js:13
    return parseJsonFile(await readFile(path, "utf8"), path);
  • 读取本地文件
    runtime/infrastructure/persistence/upgrade-backup.js:21
    await lstat(path);
  • 写入本地文件
    runtime/infrastructure/persistence/upgrade-backup.js:42
    await mkdir(dirname(path), { recursive: true, mode: 448 });
  • 写入本地文件
    runtime/infrastructure/persistence/upgrade-backup.js:50
    await rename(temporary, path);
  • 读取本地文件
    runtime/infrastructure/persistence/upgrade-backup.js:69
    for await (const chunk of createReadStream(path)) sha.update(chunk);
  • 读取本地文件
    runtime/infrastructure/persistence/upgrade-backup.js:76
    const stat = await lstat(source);
  • 读取本地文件
    runtime/infrastructure/persistence/upgrade-backup.js:78
    const link = await readlink(source);
  • 写入本地文件
    runtime/infrastructure/persistence/upgrade-backup.js:84
    await mkdir(target, { recursive: true, mode: 448 });
  • 读取本地文件
    runtime/infrastructure/persistence/upgrade-backup.js:86
    for (const name of (await readdir(source)).sort()) {
  • 写入本地文件
    runtime/infrastructure/persistence/upgrade-backup.js:95
    await copyFile(source, target);
  • 写入本地文件
    runtime/infrastructure/persistence/upgrade-backup.js:108
    await mkdir(path, { recursive: true, mode: 448 });
  • 读取本地文件
    runtime/infrastructure/persistence/project-store.js:57
    return readFile(join(this.root, path), "utf8");
  • 读取本地文件
    runtime/infrastructure/persistence/project-store.js:87
    return readdir(join(this.root, "novels")).catch((error) => {
  • 读取本地文件
    runtime/infrastructure/persistence/project-store.js:93
    const list = async (path) => (await readdir(join(this.root, base, path), { recursive: true }).catch((error) => {
  • 写入本地文件
    runtime/infrastructure/persistence/project-store.js:113
    await mkdir(checkpoint, { recursive: true, mode: 448 });
  • 写入本地文件
    runtime/infrastructure/persistence/project-store.js:140
    await mkdir(checkpoint, { recursive: true, mode: 448 });
  • 写入本地文件
    runtime/infrastructure/persistence/project-store.js:180
    await mkdir(directory, { recursive: true, mode: 448 });
  • 写入本地文件
    runtime/infrastructure/persistence/project-store.js:182
    await writeFile(join(directory, "store.json"), source, { flag: "wx", mode: 384 });
  • 写入本地文件
    runtime/infrastructure/persistence/project-store.js:183
    await writeFile(join(directory, "migration.json"), JSON.stringify({ from: 1, to: 5, sourceSha256: digest(source), novelIds: Object.keys(state.novels),
  • 读取本地文件
    runtime/infrastructure/persistence/project-store.js:411
    const projects = await readdir(join(this.root, "novels")).catch((error) => {
  • 读取本地文件
    runtime/infrastructure/persistence/project-store.js:442
    const files = await readdir(join(this.root, "runtime", "requests")).catch((error) => {
  • 写入本地文件
    runtime/infrastructure/persistence/file-transaction.js:38
    await mkdir(dirname(target), { recursive: true, mode: 448 });
  • 写入本地文件
    runtime/infrastructure/persistence/file-transaction.js:47
    await rename(temporary, target);
  • 删除本地文件
    runtime/infrastructure/persistence/file-transaction.js:53
    await unlink(target).catch((error) => {
  • 读取本地文件
    runtime/infrastructure/persistence/file-transaction.js:60
    if (digest(await readFile(target, "utf8")) === entry.sha256) return;
  • 读取本地文件
    runtime/infrastructure/persistence/file-transaction.js:68
    const info = await lstat(this.path(relative));
  • 读取本地文件
    runtime/infrastructure/persistence/file-transaction.js:70
    const project = parseJsonFile(await readFile(join(this.path(relative), "project.json"), "utf8"), `${relative}/project.json`);
  • 读取本地文件
    runtime/infrastructure/persistence/file-transaction.js:76
    await lstat(this.path(relative));
  • 写入本地文件
    runtime/infrastructure/persistence/file-transaction.js:105
    await rename(this.path(move.from), this.path(move.to));
  • 写入本地文件
    runtime/infrastructure/persistence/file-transaction.js:130
    await mkdir(dirname(stage), { recursive: true, mode: 448 });
  • 写入本地文件
    runtime/infrastructure/persistence/file-transaction.js:131
    await rename(this.path(removal.path), stage);
  • 读取本地文件
    runtime/infrastructure/persistence/file-transaction.js:138
    journal = parseJsonFile(await readFile(this.journal, "utf8"), "transaction.pending.json");
  • 读取本地文件
    runtime/infrastructure/persistence/file-transaction.js:157
    const content = await readFile(this.path(entry.stage), "utf8");
  • 删除本地文件
    runtime/infrastructure/persistence/file-transaction.js:180
    await unlink(this.journal);
  • 删除本地文件递归
    runtime/infrastructure/persistence/file-transaction.js:182
    await rm(this.path(`runtime/transactions/${journal.id}`), { recursive: true, force: true });
  • 删除本地文件递归
    runtime/infrastructure/persistence/file-transaction.js:216
    if (entry.isDirectory() && /^[a-f0-9-]{36}$/.test(entry.name)) await rm(this.path(`runtime/transactions/${entry.name}`), { recursive: true, force: tru
  • 写入本地文件
    runtime/infrastructure/persistence/atomic-store.js:25
    await mkdir(this.root, { recursive: true, mode: 448 });
  • 写入本地文件
    runtime/infrastructure/persistence/atomic-store.js:32
    await mkdir(lock);
  • 写入本地文件
    runtime/infrastructure/persistence/atomic-store.js:35
    await writeFile(join(lock, "owner"), String(process.pid), { flag: "wx", mode: 384 });
  • 删除本地文件
    runtime/infrastructure/persistence/atomic-store.js:37
    await rmdir(lock).catch(() => {
  • 删除本地文件
    runtime/infrastructure/persistence/atomic-store.js:42
    await unlink(join(lock, "owner"));
  • 删除本地文件
    runtime/infrastructure/persistence/atomic-store.js:43
    await rmdir(lock);
  • 读取本地文件
    runtime/infrastructure/persistence/atomic-store.js:56
    const pid = Number(await readFile(join(lock, "owner"), "utf8"));
  • 写入本地文件
    runtime/infrastructure/persistence/atomic-store.js:64
    await mkdir(claim);
  • 读取本地文件
    runtime/infrastructure/persistence/atomic-store.js:65
    const latest = Number(await readFile(join(lock, "owner"), "utf8"));
  • 写入本地文件
    runtime/infrastructure/persistence/atomic-store.js:68
    await rename(lock, abandoned);
  • 删除本地文件
    runtime/infrastructure/persistence/atomic-store.js:69
    await unlink(join(abandoned, "owner"));
  • 删除本地文件
    runtime/infrastructure/persistence/atomic-store.js:70
    await rmdir(join(abandoned, "reclaim"));
  • 删除本地文件
    runtime/infrastructure/persistence/atomic-store.js:71
    await rmdir(abandoned);
  • 读取本地文件
    runtime/infrastructure/persistence/atomic-store.js:87
    const pending = parseJsonFile(await readFile(this.pending, "utf8"), "store.pending.json");
  • 写入本地文件
    runtime/infrastructure/persistence/atomic-store.js:89
    await rename(this.pending, this.file);
  • 读取本地文件
    runtime/infrastructure/persistence/atomic-store.js:94
    const state = parseJsonFile(await readFile(this.file, "utf8"), "store.json");
  • 写入本地文件
    src/application/store.js:178
    await writeFile(join(this.root, `before-planning-${hash(migrationNovelId)}.json`), JSON.stringify({format:'cuigengji',schemaVersion:1,novel:migrationN
  • 写入本地文件
    src/index.js:52
    try {await store.transaction.recover(); await mkdir(join(store.root,'audit'), {recursive:true,mode:0o700}); await appendFile(join(store.root,'audit',f
  • 写入本地文件
    src/index.js:52
    try {await store.transaction.recover(); await mkdir(join(store.root,'audit'), {recursive:true,mode:0o700}); await appendFile(join(store.root,'audit',f
扫描于 2026/11/3(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

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

依赖的 DSH / Cordis 模块
@deepseek-ai/dsh@deepseek-ai/dsh-atomic-write@deepseek-ai/dsh-client-connection@deepseek-ai/dsh-client-store@deepseek-ai/dsh-client-ui-sidebar-right@deepseek-ai/dsh-mcp-client@deepseek-ai/dsh-skill@deepseek-ai/dsh-system-prompt@deepseek-ai/dsh-tools@deepseek-ai/cordis@deepseek-ai/schemastery
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

界面预览

3 张 · 点击查看大图

功能亮点

  • 写正文
  • 讨论后续情节
  • 整理人物与世界设定

给大肥鱼一个小说工作台:一起写正文、讨论后续情节、整理人物与世界设定,让长篇创作更贴近你的想法。

README

由 DeepSeek 最新模型翻译生成
催更姬让大肥鱼成为你的小说写作助手写正文 · 推敲情节 · 整理人物与世界在 DSH 里,和 AI 一起把故事写下去。 开始使用 ·看视频演示 ·视频教程 正文写到一半,想和 AI 商量下一步,却又得重新解释人物和前情。 催更姬是 DeepSeek Harness(DSH) 的小说写作插件。把正文、情节规划、人物和世界设定放在同一个工作台里,让你和 AI 围着同一份作品资料讨论、续写和修改。 装进 DSH,开始写 使用 DSH Windows 桌面版 0.2.0-rc.2 或更新版本,无需另装 Git、Node.js 或编译源码。 1. 打开 DSH 的「插件 → 添加插件」。 2. 在「包名或地址」填入下方内容,「安装源」保持默认或选择 npm 官方源 / 中国大陆镜像源。 3. 安装后按提示重启,从左侧「催更姬」进入,创建或选择作品。 dsh-cuigengji-plugin@0.5.0 请保留版本号,避免宿主将不带版本的包名解析到旧版。「安装源」用于下载依赖,保持为包源即可。 详细安装步骤 · 备用成品包 · 更新与数据迁移 也可以把安装与更新指南交给 Agent,由它处理安装、备份和升级检查。0.5.0 已实际验收 DSH 0.2.1-rc.2;更新插件会自动备份、迁移并校验原有作品。
展开完整文档(README 剩余 1 节)
催更姬让大肥鱼成为你的小说写作助手写正文 · 推敲情节 · 整理人物与世界在 DSH 里,和 AI 一起把故事写下去。

开始使用 ·看视频演示 ·视频教程

正文写到一半,想和 AI 商量下一步,却又得重新解释人物和前情。

催更姬是 DeepSeek Harness(DSH) 的小说写作插件。把正文、情节规划、人物和世界设定放在同一个工作台里,让你和 AI 围着同一份作品资料讨论、续写和修改。

装进 DSH,开始写

使用 DSH Windows 桌面版 0.2.0-rc.2 或更新版本,无需另装 Git、Node.js 或编译源码。

1. 打开 DSH 的「插件 → 添加插件」。
2. 在「包名或地址」填入下方内容,「安装源」保持默认或选择 npm 官方源 / 中国大陆镜像源。
3. 安装后按提示重启,从左侧「催更姬」进入,创建或选择作品。

dsh-cuigengji-plugin@0.5.0

请保留版本号,避免宿主将不带版本的包名解析到旧版。「安装源」用于下载依赖,保持为包源即可。

详细安装步骤 · 备用成品包 · 更新与数据迁移

也可以把安装与更新指南交给 Agent,由它处理安装、备份和升级检查。0.5.0 已实际验收 DSH 0.2.1-rc.2;更新插件会自动备份、迁移并校验原有作品。

视频与教程

第一次接触 DSH 或 AI 写作,可以跟着「催更姬从零上手」系列开始:

| 想了解什么 | 视频 | 时长 |
| 安装 DSH 和催更姬 | 从零上手①:只会网页版 AI?先把 DSH 和插件装好 | 2:28 |
| 理解长篇写作中的问题与插件思路 | 从零上手②:AI 会润色,为什么写长篇就跑偏? | 6:28 |
| 看看工作台怎样操作 | v0.4.0 功能演示:写作、规划与数据管理 | 2:31 |

更多教程、版本演示和「从零开始 AI 写作」系列,见 B 站主页 · 催更姬VibeWriting。视频中的版本以标题和画面标注为准,当前安装步骤以安装说明为准。

从一个想法,到一部小说

写正文,随时和大肥鱼商量

在聊天旁边直接写稿。按卷、章节整理作品,自动保存、查看字数、调整顺序,写好的内容可以排版和复制;改得不满意,还能回看正文历史版本。

正文工作台:章节目录、字数统计与正文编辑

把情节摊开,一起推敲

把主角的行动、支线的交汇、尚未决定的走向放到画布上,用卡片、连线、讨论框和便签慢慢理清。大场面可以单独开一页推演,作者和 AI 都能维护这张图。

规划画布:多条情节动线交汇,讨论框和便签留下待定想法

人物和世界,随用随查

把人物动机、关系、地点和世界规则整理成角色卡与世界书,支持分组、搜索和关系图。写到相关情节时,AI 可以查阅、补充这些资料,让后续推进有据可依。

设定工作台:人物、世界书、分组与关系图

以上截图使用虚构演示作品。

| 还有这些写作工具 | 能帮你做什么 |
| 每本作品的写作预设 | 保存文风、视角等写作要求,启用后提供给绑定作品的 AI 会话。 |
| 酒馆资料导入 | 接着用已有的角色卡、世界书和提示词预设,导入后继续整理。 |
| 导入、导出与备份 | 带走整本作品,或选择章节、设定分组、规划页与预设;也能备份整个工作库。 |

为什么正文之外,还需要这些资料?

一部小说像一座冰山。正文是读者看见的部分,水面之下,还有人物的动机、没揭开的伏笔、世界的规则,以及你对后续故事的安排。

催更姬给 AI 提供查阅和维护这些资料的工具,让讨论留下来,下次能接着推进。资料按需要读取,写作要求跟着作品走,帮助减少长篇创作中的人物变味、伏笔断掉和情节跑偏。

就像身边多了随时可以讨论的编辑:一起琢磨人物,推敲下一章怎么走。故事由你做主,大肥鱼陪你写下去。

交流与支持

- B 站 · 催更姬VibeWriting:观看教程、功能演示,关注后续更新。
- QQ 交流群:1026457465,欢迎分享作品体验、反馈问题和讨论后续功能。
- 爱发电 · 支持催更姬:欢迎合作与投喂,每一份支持都会化作 token,帮助催更姬继续成长。
- 提交问题或建议:带上 DSH 与插件版本、操作步骤,更方便定位问题。

文档与开源

使用文档 · 更新记录 · 源码与贡献 · 架构说明

作品保存在独立的数据目录里,插件升级与源码更换不会把小说混进代码。实际位置可在「设置 → 数据与备份」中查看或切换,备份范围见数据管理说明。

本仓库提供正式版源码、构建产物、使用文档与合成测试样例。源码采用 MIT 许可证;小说内容和自行导入的资料属于各自作者。
预览分享卡片长什么样 ↓mistnest/dsh-cuigengji-plugin
分享 · DeepSeek Harness Hub
mistnest/dsh-cuigengji-plugin

催更姬:给大肥鱼一个小说工作台。写正文、理设定、画情节,和 AI 一起讨论、续写与改稿。

这是你的仓库?认领条目

回到顶部