DeepSeek Harness Plugin Hub

Publish and manage complete Harness Profiles. Discover Plugins for your next setup.

Explore

PluginsPresetsDocsNews

Community

Publish a pluginContactReport an issue

Resources

Plugin Hub on GitHubDeepSeek HarnessSystem statusPrivacy notice
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

Independent and unofficial. Not affiliated with, authorized by, or endorsed by DeepSeek.

History Fictionologists — DSH Plugin for DeepSeek Harness
DeepSeek Harness Plugin Hub
ProfilesPluginsCategoriesNewsDocsSign inManage Profiles
ProfilesPluginsCategoriesNewsDocsSign in
← Plugins
H

dsh-history-fictionologists

History Fictionologists

DSH Fictional Historian: A fan-made plugin based on the official universe of Honkai: Star Rail (/gs)—the Genius Maker generates sci-fi inspiration, Historical Anthology writes short stories, Interstellar Historical News broadcasts fictional news, Planet Maker generates new planets based on the “Plan

The plugin will be installed here. Keep web if you are unsure.

npx -y @deepseek-ai/dsh plugin --profile web add github:Kaede0614/dsh-history-fictionologists#3fe16c9686830c9cef6e81ef7bd323b57dc2248a
READMECompatibilityVersions

Description

DSH Fictional Historian: A fan-made plugin based on the official universe of Honkai: Star Rail (/gs)—the Genius Maker generates sci-fi inspiration, Historical Anthology writes short stories, Interstellar Historical News broadcasts fictional news, Planet Maker generates new planets based on the “Planet List,” and Fictional Differential Equations invents new equations (name + detailed setting, evenly distributed across five types of narrative subjects); incrementally fetches and locally caches data from 12 biligame Wiki sources.

Compatibility and provenance

History Fictionologists is published as dsh-history-fictionologists and currently resolves to version 0.6.0. The Hub verifies its manifest and preserves the exact installation source for reproducible installs.

DSH compatibility
*
Runtime surfaces
any
Release source
github
Registry updated
10/1/2026

Versions

0.6.0stable
10/1/2026
0.5.0stable
9/29/2026
0.3.0stable
9/27/2026
Show 1 more versionCollapse versions
0.2.0stable
9/25/2026

Related plugins

Loading related plugins…

Latest
0.6.0
DSH
*
HMR
Process restart
Tree shaking
Safe tree shaking not declared
Unpacked size
Unavailable
Files
Unavailable
Surface
any
License
MIT
Source
github
GitHub
★ 0
Weekly downloads
0
Last push
10/1/2026
View source ↗
README badge

Click the badge to copy Markdown for your README.

Do you maintain this Plugin?Claim benefit · Priority security scan

Verify the GitHub repository declared in package.json to manage this listing. After you claim it, Hub will prioritize a security scan of the current version and publish the result when it passes.

Claim this Plugin →
Report an issue

Related plugins

More verified plugins in search-research.

Ab Wechat Scrapedsh-ab-wechat-scrape--- description: "The out-of-tree wechat_scrape tool: retrieves WeChat official-account articles, filters promotional blocks, and saves each as a Markdown file, for maintainers of this machine's dsh profiles." kind: "package-reference" ---Ab Market Researchdsh-ab-market-researchAn out-of-tree DeepSeek Harness plugin: the trade_search tool (multi-round aspect-broadening query planning, publisher-tier ranking, source diversity, JSON snapshot) and its browser card in one package.Weknora@wxg-prc-cpg/dsh-weknoraWeKnora knowledge retrieval tools for DeepSeek Harness (dsh): semantic search, document reading and RAG/agent answers over your own knowledge bases.Free Searchdsh-free-searchFree web search for DeepSeek Harness: 24 engines (Bing/DuckDuckGo/AnySearch/SearXNG/Exa/Tavily/Keenable/Firecrawl/Parallel keyless; Zhihu global/site via MCP and Perplexity/SerpBase/DeepSeek/You.com/Baidu/Kimi/Aliyun/Doubao with key; OpenAI/Gemini/Claude

README

dsh-history-fictionologists · 虚构史学家

基于《崩坏:星穹铁道》官方世界观进行二次创作的 DSH 插件。 触发命令:/gs。风格基调:太空轻喜剧 + 一本正经地胡说八道。

核心参考游戏内「差分宇宙 · 方程一览」的想象力与命名逻辑: 用最严肃的格式包装最离谱的内容。


能力清单(前置条件)

能力触发方式前置条件
/gs 三步交互入口在 DSH Web 输入框输入 /gs插件已装入 profile 的 bundles,进程已重启
gs_setup 缓存状态与更新建议模型调用(/gs 第 2 步)无
gs_update 增量抓取 12 个 Wiki 数据源模型调用需要联网;本机可访问 wiki.biligame.com
gs_read 读取世界观条目模型调用至少成功抓取过一次(缓存存在)
gs_missions 既有故事目录(避让冲突)模型调用工作区存在 hsr-missions/
gs_digest 命名逻辑 / 书架风格 / 播报格式素材模型调用equation、broadcast-template 需缓存;mission-digest、book-digest 需 hsr-missions/
gs_planets 「星球列表」(原始 27 颗 + 已并入)模型调用(功能 4 第 1 步)无(原始列表编译在插件里,不需要网络)
gs_planet_save 把新星球并入列表模型调用(用户答「加入」后)工作区可写
gs_planet_reset 重置回原始 27 颗模型调用(用户确认后带 confirm: true)工作区可写;不带 confirm 只报告状态
gs_equation_save 虚构差分方程落盘(逐条校验后写入)模型调用(功能 5)工作区可写;既有方程缓存存在时叠加重名检查
gs_save 成品落盘模型调用工作区可写
系统提示「语言风格总则 + 星神纪律」自动注入无

降级行为(已实测):缓存目录不存在时 gs_setup / gs_read 仍返回合法结果(hasCache:false、 recommendation:"update"),不会抛错;/gs 在缺少子模块时仍能启动并如实报告状态; planet-list.json 缺失、损坏或字段非法时,星球列表一律退回插件内置的 27 颗原始列表并在 warnings 里说明(test/planets.test.mjs 覆盖)。


安装

本插件通过 GitHub / AtomGit 仓库与 Release 附件 双平台分发。它不在 npm registry 上—— package.json 里的 private: true 是刻意留的,防止这份二创包被误发到公共 registry。

# 方式 A(推荐):下载 Release 附件里的 tarball,再从本地路径安装
dsh plugin --profile web add C:\Users\<你>\Downloads\dsh-history-fictionologists-0.3.0.tgz

# 方式 B:AtomGit 仓库直装(国内网络更稳)
dsh plugin --profile web add https://atomgit.com/Scombriformes/dsh-history-fictionologists

# 方式 C:GitHub 仓库直装
dsh plugin --profile web add github:Kaede0614/dsh-history-fictionologists

# 方式 D:本地开发(junction 安装,改源码立即生效)
dsh plugin --profile web add link:<你的仓库路径>

AtomGit 是分发镜像,不是主仓:package.json 的 repository / homepage / bugs 仍指向 GitHub。发布流程与两个平台的 API 差异见 docs/atomgit-description.md。

dsh plugin 是 profile 目录下 pnpm 的透传封装,所以本地 tarball 路径、github: 简写 都由 pnpm 解析;dsh plugin add ... 会重解析整棵依赖树,装进一个干净 profile 最稳。

安装后 必须进程级重启 DSH(新增 bundles 行只在启动时组合;Ctrl+Shift+R 热重载不生效)。

验证是否装载:

dsh --profile web --dump-config | Select-String history-fictionologists

应当看到一行 - id: dsh-history-fictionologists。

仓库里有什么 / 没有什么

内容
有lib/(插件本体)、test/(204 个离线用例)、scripts/check.mjs、docs/、_evidence/(自证与独立复核证据)、BRIEF.md(实现规格)、cordis.patch.yml、hsr-worldview-cache/user-canon.json(手工维护的裁定层)
没有hsr-missions/(游戏原始剧本文本,约 20 MB,版权归米哈游)、hsr-worldview-cache/*.json(gs_update 可重新抓取)、_probe/(4.9 MB 原始渲染 HTML)、hsr-stories/ 与 hsr-broadcasts/(本机成品)

被忽略的目录仍留在你的工作区里,只是不进版本库(见 .gitignore)。

功能 2 / 3 依赖工作区的 hsr-missions/:没有它插件照样装载, gs_missions 会如实降级报告「目录缺失」,gs_digest 的 mission-digest / book-digest 同理 (这条降级有 test/missions.test.mjs 覆盖)。要用全功能,请自备并放到 <工作区>/hsr-missions/:

trailblaze_missions.json          5 幕 / 18 系列 / 147 个开拓任务
adventure_other_tasks_full.json   7 章 / 33 个冒险任务
books_without_amphoreus.json      498 本书(「书架」风格参考)
sr-开拓续闻-完整/                  7 个系列 / 52 个开拓续闻任务

怎么触发

  1. 在 DSH Web 的输入框输入 /gs(可以附带主题,例如 /gs 欢愉命途的荒诞点子)。
  2. 插件会:
    • 本地读取缓存与既有故事状态,不发一次模型请求;
    • 把「三步交互协议」作为一条 plugin 来源的用户消息交给当前 agent;
    • 返回一行简短回执。
  3. 模型据此依次弹出:
    • 第 1 步 · 功能选择:1 神人制造机 / 2 构史文集 / 3 星际构史播报 / 4 星球制造机(单选弹窗);
    • 第 2 步 · 世界观数据更新策略:Y 访问网页重新抓取 / N 使用本地缓存;
    • 第 3 步 · 执行所选功能。功能 4 执行完还会再问两件事(见下)。

第 2 步的引导规则

  • 本地无缓存 → 不问 Y/N,直接抓取,并告知「本地无缓存,已自动抓取」。
  • 缓存较新(距上次更新 < recentGuardDays,默认 7 天)→ 即使选 Y,也先确认一句 「数据较新,确认需要重新抓取吗?」。
  • 选 Y → gs_update 增量更新:先比对页面 revid,没变化的数据集直接跳过。
  • 抓取失败(网络异常 / 被反爬拦截)→ 自动回退本地缓存,并明确告知 「更新失败,已使用缓存数据」。

五种功能

功能 1 · 神人制造机

生成 3–5 条全新科幻灵感(默认 4 条),输出格式(与功能 5 的方程共用同一套 Markdown 版式):

## 灵感名称

〔人物·职业/身份〕命途归属:〈主命途〉/〈次命途〉

详细设定:……(约 100–200 字,须带荒诞感。首句就交代「谁 / 在哪 / 干什么」,
原「一句话简介」并入本段,不再单列)

可能的故事方向:……

版式修订:名称写成 ## 二级标题、不再用【】包裹(功能 5 的校验器把方括号判为游戏机制语言); 名称与后面三段之间各空一行;「一句话简介」取消,其内容并入「详细设定」首句—— 两个功能各一套版式时,落盘文件里的标题层级也跟着乱;统一后功能 1 的灵感与功能 5 的方程 可以直接拼进同一份文档。

星神纪律(0.1.1):命途归属只是气质标签——星神与令使不出场,只能是背景、传闻与缺席; 已陨/失踪的星神(贪饕、繁育、秩序、不朽、纯美、开拓)绝不写成在世、现身或归来。 正文写神人自己的职业、麻烦与出路:荒诞来自「命途概念 × 市井生活」的错位,不是「他和星神很熟」。

功能 2 · 构史文集

先读 hsr-missions 的既有故事避免冲突,参考「书架」书籍风格,默认约 2000 字短篇 (可指定字数)。荒诞但不轻浮,喜剧底色下可有一丝温情或哲思。

功能 3 · 星际构史播报

约 800–1200 字、3–5 条新闻,格式固定(报头人声随机,其余逐字照用):

(音乐)

〈报头人声,女声或男声随机〉:这里是星际和平播报,观众朋友们晚上好。
〈另一位〉:晚上好。
〈报头人声〉:欢迎收听今天的星际和平播报节目:

〈另一位〉:……
〈报头人声〉:……
〈另一位〉:……

〈轮到的那一位〉:本次播报到此结束,请在指定时间收听下一周期的星际和平播报。
(音乐)

口径:不写「第X条消息」这类序号前缀;「晚上好」之后必须有过渡句;报头人声可女声可男声(随机), 选定后全篇严格交替;报道对象是星球、地区、派系与它们身上发生的事件,不是某个普通个人的轶事。 虚构文本必须足够科幻、足够太空、充满想象力——不是对已有故事的重组。

功能 4 · 星球制造机(0.3.0)

参照「星球列表」造新的星球:列表里的星球只提供世界观坐标与语感,新星球不得与其重名, 也不得把既有星球改个说法再交一遍。默认 3 颗(config.planetCount 可调,范围 1–10)。输出格式:

【星域名(English Name)】
一句话简介:……(不超过 40 字,写成「地点词条」而不是广告词)
详细设定:……(约 60–160 字:靠什么活着、谁在管事、当地人最大的麻烦是什么)
可能的故事方向:……(一到两句话)

生成结束后固定问两件事(模型不会替你决定):

询问答「要」时发生什么答「不要」时发生什么
① 是否把这批新星球加入「星球列表」,供下次参考?gs_planet_save 把这批星球并入列表,下次生成会看到它们不写盘,本次结果不影响以后的生成
② 是否把「星球列表」重置回原始 27 颗(清除已并入的新星球)?gs_planet_reset(confirm=true) 清空增量,满意与不满意的批次一起清掉什么也不做

「重置」是破坏性操作:gs_planet_reset 不带 confirm: true 时只回报当前状态、绝不改文件, 所以模型必须先经你确认才能真的清空。清除的粒度为「全部新增」——只想清掉一部分,请手工编辑 planet-list.json 的 added 数组(见下一节)。

「星球列表」是什么

  • **原始列表(27 颗)**编译在插件里(lib/planets.mjs 的 PLANET_BASELINE_SOURCE),所以「重置回原始」永远拿得回底本——即使工作区文件被删掉或写坏。
  • 已并入的新星球写在 <工作区>/hsr-worldview-cache/planet-list.json 的 added[], 与 user-canon.json 同理:gs_update 只重写 <数据集>.json,永不碰这个文件。
  • 判定重名按「星球名或英文名去空格后同名、且英文名不区分大小写」,且原始列表优先: 与原始列表同名的候选会被拒绝并在 rejected 里说明撞的是哪一颗(例如 ARIVANTA 撞「阿丽万塔」, 或候选的 en 字段撞上原始英文名);不会覆写你的原始设定。与已有增量同名的条目会被更新, 便于修正上一轮不满意的描述。
  • 一次最多并入 20 颗(MAX_BATCH)。超出的候选不会写入,但会出现在返回值的 overflow: {count, names} 与 warnings 里——模型必须如实转告你,而不是说「都加进去了」。 增量列表总上限 200 颗,到顶后拒绝写入并提示先重置。
  • 「出处」标注(visited 已探访 / mentioned 文本提及 / ruined 已毁或失去开拓意义 / unknown / other)是本插件加的,只用于给模型分组参考,不改变用户原文一个字。

功能 5 · 虚构差分方程(0.5.0 新增;0.6.0 修订版式与配额)

写法与版式完全同「神人制造机」(## 名称 + 〔主题类别〕命途归属 + 详细设定 + 可能的故事方向)。 区别只有一条——叙事对象不限于人物,五类主题大致均分:

主题类别既有 212 条方程里的占比本功能的目标
人物·职业/身份59.0%(125 条)不再是主体,每批最多 1–2 条
生物·物种/衍生体14.6%(31 条)每批至少 1 条,条数不设上限(鱼鸟比例不作要求)
装置·器物/场所9.4%(20 条)每批至少 1 条
抽象概念·现象/事件9.0%(19 条)每批至少 1 条
派系·机构/组织8.0%(17 条)每批至少 1 条,且必须新造机构名

默认 6 条(config.equationCount,3–10);推荐配额是 人物 1 / 生物 2 / 装置 1 / 概念 1 / 派系 1——生物类条数不设上限,想多写生物就把份额分给它 (5 条同样合法:每类各 1 条)。输出格式:

## 方程名称

〔主题类别〕命途归属:〈主命途〉/〈次命途〉

详细设定:……(约 120–220 字,须带荒诞感)

可能的故事方向:……(一到两句话)
  • 正文不写游戏机制:不出现方括号符号、百分比、暴击 / 护盾 / 战技点 / 终结技 / 削韧 / 回合等 机制语言(校验器会拒收)。
  • 命途白名单 14 个(0.6.0 起含 贪饕):欢愉 / 智识 / 繁育 / 毁灭 / 虚无 / 巡猎 / 记忆 / 存护 / 丰饶 / 同谐 / 贪饕 / 均衡 / 开拓 / 终末。加命途只为可写吞噬、饥饿、永无餍足这类题材, 不放宽星神纪律——奥博洛斯 仍在拒收词表里,只能以旧传闻 / 遗物 / 过期教条出现。
  • 生物类专项:名字不少于 3 字,不得沿用既有构词(蠧役 / 残嗣 / 虫帝 / 王虫 / 巨人 …); 生物类条数不设上限(五类里唯一豁免「单类 ≤2」的类别);鱼类 / 鸟类的数量与比例 不作任何要求(2026-09-30 删除鱼鸟比重限制);只剩「虫类 ≤ 四成」一条提示级口径。
  • 落盘:gs_equation_save 逐条校验后写入 <工作区>/hsr-stories/equations/, 同一目录里再写一份 -equations.md 自检记录(五类配比、生物构成、被拒原因)。 与既有 212 条方程的重名检查依赖缓存;缓存缺失时降级为「跳过重名检查」并在 warnings 里说明。
  • 规则实现集中在 lib/equations.mjs,完整口径见 docs/fiction-equation.md。

世界观数据

已发生的故事(本地,无需抓取)

工作区 hsr-missions/:

文件内容
sr-开拓续闻-完整/7 个系列 / 52 个「开拓续闻」任务(含完整台词稿)
trailblaze_missions.json5 幕 / 18 系列 / 147 个开拓任务
adventure_other_tasks_full.json7 章 / 33 个冒险任务
books_without_amphoreus.json498 本书(「书架」风格参考)

功能 2 / 3 生成前必须读它,避免与既有事件冲突(功能 1 与功能 4 不需要)。

背景设定(12 个 Wiki 数据源,需联网抓取)

id页面抓取内容过滤
relics遗器图鉴每套遗器的「遗器来历」(各部位 *故事)—
lightcones光锥图鉴每个光锥的「光锥故事」—
consumables消耗品筛选每个消耗品的「介绍」排除所属地区=翁法罗斯
decorations装饰一览每个装饰的「介绍」—
aeons星神每个星神的介绍—
factions派系每个派系的内容—
terms专有名词每个专有名词的内容—
simuniverse模拟宇宙「模拟宇宙图鉴 → 星神」里的开发日志—
curios奇物一览(差分)每个奇物的介绍/效果—
events事件一览每个事件的内容排除模式含「千面英雄」
equations方程一览每个方程的内容(效果全文)排除模式含「千面英雄」
broadcast星际和平播报全部内容—

抓取礼仪:相邻请求间隔 ≥ requestIntervalMs(默认 2000 ms),带浏览器 UA 与 Referer, 非 JSON 响应(WAF 会返回 HTTP 567 的错误页)走指数退避重试,重试耗尽则保留旧缓存并如实上报。


缓存目录

<工作区>/hsr-worldview-cache/

hsr-worldview-cache/
├── index.json          # 每个数据集的状态:lastUpdated / count / revisionId / ok / error
├── equations.json      # 每个数据集一个文件,字段见下
├── aeons.json
├── factions.json
├── terms.json
├── relics.json
├── lightcones.json
├── consumables.json
├── decorations.json
├── curios.json
├── events.json
├── simuniverse.json
├── broadcast.json
├── user-canon.json     # 用户设定补充(手工维护,抓取永不改写)
└── planet-list.json    # 「星球列表」增量(功能 4 写入;重置=清空 added[])

planet-list.json 结构(baseline 是原始 27 颗的快照,仅供人工核对;程序只读 added[]):

{
  "schema": "dsh-history-fictionologists/planet-list@1",
  "updatedAt": "2026-09-27T10:00:00.000Z",
  "baselineCount": 27,
  "addedCount": 1,
  "baseline": [ { "name": "阿丽万塔", "en": "Arivanta", "description": "…", "source": "visited" } ],
  "added": [
    { "id": "added-1", "name": "洛珂萨", "en": "Loxa", "description": "…", "source": "mentioned",
      "addedAt": "2026-09-27T10:00:00.000Z" }
  ]
}

单个缓存文件结构:

{
  "dataset": "equations",
  "title": "方程一览",
  "url": "https://wiki.biligame.com/sr/方程一览",
  "lastUpdated": "2026-09-26T02:00:00.000Z",
  "revisionId": 12345,
  "pageSha": "…",
  "count": 212,
  "excludedCount": 112,
  "entries": [ { "name": "…", "content": "…" } ],
  "warnings": []
}

提示:每个缓存文件都带 lastUpdated 时间戳。删掉整个目录就是彻底重置; 想强制重抓某一天数据,用 gs_update 的 force: true(或删掉对应的单个 json 文件)。

工作区解析优先级:插件 config.workspace → DSH_HISTORY_FICTIONOLOGISTS_WORKSPACE → DSH_WORKSPACE → 当前工作目录(或其上层含 hsr-missions 的目录)→ 插件包所在目录。

用户设定补充(user-canon.json)

缓存是「抓来的事实」,你自己的设定裁定是另一层——它优先于缓存。

  • 位置:<工作区>/hsr-worldview-cache/user-canon.json,手工维护。gs_update 只重写 <数据集>.json,永远不会碰这个文件(所以裁定不会被下一次抓取抹掉)。
  • 生效方式:gs_read 结果末尾附上「用户设定补充」区块,并明确标注「冲突时以此为准」; gs_setup 报告条数与更新时间;系统提示的「语言风格总则」也写明了它的优先级。
  • 作用域:dataset 写数据集 id 时只在该数据集生效(aeons / aeon 都认), 写 "*" 或省略则对全部数据集生效;match 是触发关键词(命中 gs_read 的 query, 或与该数据集返回的条目同屏出现时带出);query 为空时,该数据集名下的裁定一律带出。
  • note 必填:没有 note 的条目会被忽略并告警——空口裁定不算设定。
{
  "schema": "dsh-history-fictionologists/user-canon@1",
  "updatedAt": "2026-09-26T03:30:00.000Z",
  "entries": [
    {
      "dataset": "aeons",
      "match": ["贪饕", "奥博洛斯"],
      "name": "「贪饕」,奥博洛斯",
      "status": "已镇压(不得写成在世/失踪待返/即将归来)",
      "note": "奥博洛斯早已四分五裂、被镇压。缓存里的「已失踪无影」只是旧传闻,不得当作现状。",
      "source": "用户评审(2026-09-26)"
    }
  ]
}

文件缺失 = 没有裁定(正常状态);文件损坏或 JSON 非法 = 降级为「0 条 + 告警」, 不影响缓存读取与其它工具。读取逻辑在 lib/usercanon.mjs, 测试在 test/usercanon.test.mjs。


成品落在哪

类型目录
短篇小说(功能 2)<工作区>/hsr-stories/<时间戳>-<标题>.md
星际和平播报(功能 3)<工作区>/hsr-broadcasts/<时间戳>-<标题>.md
灵感(功能 1)<工作区>/hsr-stories/inspirations/<时间戳>-<标题>.md

文件带 YAML front-matter(kind / title / createdAt / generator)。 把 config.saveOutputs 设为 false 可关闭落盘。


配置项

在 profile 的 cordis.patch.yml 里按 id 覆盖(整行 config 会被替换,所以要把需要的键都写上):

- id: dsh-history-fictionologists
  config:
    workspace: ''            # 留空自动解析
    requestIntervalMs: 2000  # 相邻 Wiki 请求最小间隔(毫秒)
    requestTimeoutMs: 30000
    maxRetries: 3
    staleAfterDays: 7        # 超过该天数即建议重新抓取
    recentGuardDays: 7       # 不足该天数时,选 Y 也先确认一次
    defaultStoryWords: 2000
    defaultBroadcastWords: 1000
    inspirationCount: 4      # 3–5
    planetCount: 3           # 星球制造机默认颗数(1–10)
    equationCount: 6         # 虚构差分方程默认条数(3–10;生物类不设上限,其余四类单类最多 2 条)
    saveOutputs: true
    userAgent: 'Mozilla/5.0 …'

目录结构(插件本体)

dsh-history-fictionologists/
├── package.json            # dsh.bundle.patch 指向 cordis.patch.yml;main = lib/shell.js
├── cordis.patch.yml        # bundle 挂载声明
├── lib/
│   ├── shell.js            # 插件外壳:/gs 命令、10 个工具、风格提示词、Config(包入口)
│   ├── resolve.js          # @deepseek-ai/* 可选依赖的多 base 解析链
│   ├── paths.js            # 工作区 / 缓存 / 成品目录解析
│   ├── missions.js         # hsr-missions 读取与索引
│   ├── digest.js           # 命名逻辑 / 书架风格 / 播报格式素材
│   ├── usercanon.mjs       # 用户设定补充(优先于抓取缓存)
│   ├── planets.mjs         # 原始 27 颗星球底本 + 增量列表读写/重置
│   └── wiki/               # 12 个数据源的抓取与解析
│       ├── datasets.mjs    # 数据源登记表(含单复数 id 别名)
│       ├── client.mjs      # 限流 / 重试 / WAF 识别
│       ├── html.mjs        # 通用 HTML 解析
│       ├── wikitext.mjs    # {{模板|字段=值}} 解析
│       ├── extract.mjs     # 12 个抽取器
│       ├── cache.mjs       # 原子缓存 + revid 短路
│       └── index.mjs       # status / update / read / sampleAll
├── test/                   # node:test:离线重放 + mock ctx + 宿主校验器一致性(无网络)
├── docs/DESIGN.md          # 数据源结构实测记录(抓取选择器依据)
└── CHANGELOG.md

入口文件叫 lib/shell.js 而不是惯用的 lib/index.js:一次编辑事故把后者写成了非 UTF-8 字节,文件系统观察策略(正确地)拒绝再覆写一个读不出来的路径,于是安全修复是换一个 干净文件名并把 package.json 的 main/exports 指过去。行为与 index.js 完全等价。


故障排查

现象原因 / 处理
输入 /gs 没有补全、没有反应bundles 行未生效:确认 --dump-config 里有该行,然后进程级重启
--dump-config 报告跳过该 bundle报的是原因(多半是解析不到包)。确认 node_modules/dsh-history-fictionologists 链接或已 dsh plugin add
--dump-config 报错、整棵插件树崩Config 被导出成普通对象(本插件已规避;若你改过 lib/shell.js 请检查)
工具「静默消失」@deepseek-ai/* 解析失败。node -e "import('./lib/resolve.js').then(m=>console.log(m.resolutionReport()))" 看解析链
工具报 returned invalid output某个工具返回值违反了它自己声明的 schema(例如可选键出现了 null)。跑 node --test test/host-validator.test.mjs 会直接指出是哪一个
抓取全部失败网络不通,或请求过于频繁被 WAF(HTTP 567)拦截。调大 requestIntervalMs 后重试
模型说「未读取到数据」先跑一次 gs_update;或检查 config.workspace 是否指向了正确的工作区
想看抓取细节缓存目录的 index.json 里有每个数据集的 ok / error / count / revisionId
功能 4 生成的星球没进列表看 gs_planet_save 返回里的 rejected:与原始 27 颗重名的候选会被拒绝(故意不覆写原始设定)
「星球列表」被清空或写坏原始 27 颗编译在插件里,不会丢:调用 gs_planet_reset(confirm=true) 即可重建文件
模型没问「是否并入 / 是否重置」这两问同时写在系统提示与 /gs 协议文本里;直接提醒它「按功能 4 的收尾问两件事」

自检命令

cd <你的仓库路径>
node scripts/check.mjs    # 首选:语法检查全部模块 + 跑全套测试(约 1.5 秒)
node --test               # 只跑测试(Node 自动发现 test/ 下所有 *.test.mjs)
node _evidence/e2e-wiring.mjs     # 真实 Wiki 上跑通工具接线(会联网,约 15 秒)
node _evidence/run-extract.mjs --live   # 12 个数据源真机抓取取证(会联网,约 60 秒)
node _evidence/verify-gs-e2e.mjs  # 隔离实例里端到端验证 /gs(约 15 秒)

为什么不用 npm test:这台机器上 PATH 里只有 npm.ps1,而 PowerShell 执行策略禁止运行它, 所以 npm test 在 PowerShell 里直接报 running scripts is disabled(用 cmd /c "npm test" 可以跑通)。 另外 node --test test/ 这种带斜杠的写法在 Node 24 上会失败(Cannot find module ...\test: Node 不会替 npm script 展开 glob),所以 package.json 的 test 用的是裸 node --test 自动发现。 为了让自检不依赖 npm,才把检查逻辑放进 scripts/check.mjs。

测试分层(每一层都补上一层的盲区):

层文件能证明什么证明不了什么
契约test/plugin.test.mjs注册物齐全(10 工具 / 1 命令 / 1 section)、/gs handler 在异常与降级输入下不抛、规范 JSON返回值是否符合 output.schema(mock 不校验)
宿主校验test/host-validator.test.mjs用宿主自己的 validateJsonSchemaValue 校验全部工具(含新增的功能 5)的降级路径;含元测试证明该断言会失败;含 args 层拒绝、卸载/重载与 stub 接缝的隔离断言真实进程内的注册成功
解析test/wiki.test.mjs12 个抽取器对真实 HTML 的选择器正确性(离线重放)+ revid 短路 + WAF 重试 + 注入时钟的确定性限流断言真机网络行为
连续性test/missions.test.mjshsr-missions 三种 JSON 的读取、截断上界、缺失降级—
星球列表(0.3.0)test/planets.test.mjs原始 27 颗与用户原文逐条一致、读取降级、重名规则(原始优先 + 星球名/英文名 + 大小写不敏感)、超限候选不静默丢弃、截断有告警、原子写、重置、上限、三个星球工具的 schema/渲染/无损 JSON、/gs 协议的两问真机上模型是否照做(那取决于模型)
虚构差分方程(0.5.0;0.6.0 修订)test/equations.test.mjs五类配比(每类 ≥1;非生物类 ≤2,生物类不设上限)、鱼鸟比例已无任何判定、命途白名单含贪饕且点名奥博洛斯仍被拒、生物命名(≥3 字 / 不得沿用既有构词)、星神纪律、机制语言拒收、与既有 212 条方程的重名、逐条落盘与自检记录、saveOutputs=false 与缓存缺失降级真机上模型是否照做(那取决于模型)

全部离线(每个 new WikiClient 都注入了假 fetch,套件里 globalThis.fetch 一次都不会被调用)。 需要联网的验证在 _evidence/(run-extract.mjs --live、cache-roundtrip.mjs、e2e-wiring.mjs)。

在哪台机器上跑得出什么

test/ 里有一层用例重放本地夹具(_probe/html/*.html)与真实语料(hsr-missions/)—— 这两份数据按体积与版权考虑不进版本库(见 .gitignore)。所以同一套用例在不同检出里给出的数字不同:

检出命令结果
作者工作区(_probe/ 与 hsr-missions/ 都在)node --test204 用例 / 203 pass / 0 fail / 1 skip(2026-10-01 实测;唯一 skip 是「缓存已存在时不再跑降级断言」)
全新克隆(两者都不在)node --test用例总数相同,其中「重放 _probe/ 夹具 / 依赖 hsr-missions/」的那些显式 skip(每一条都带原因)

第一行那个数字在本机(受限沙箱)是由逐文件 node test/<name>.test.mjs 直跑汇总的: 沙箱禁止 node --test 为每个测试文件 spawn 子进程(EPERM)。跑的是同一批文件、同一套断言。

夹具/语料缺失导致的每一条 skip 都带原因,直接印在输出里,例如:

﹣ update: unknown ids and a broken client degrade into failed[] # _probe/html/遗器图鉴.html,
  _probe/html/光锥图鉴.html, _probe/html/消耗品筛选.html, _probe/html/装饰一览.html (+8 more)
  are not in this checkout (see .gitignore)

设计口径:夹具缺失 → 显式 skip;从不静默通过,也从不弱化断言。 所有与磁盘无关的用例(client: 限流与 WAF 重试、HTML/wikitext 解析、合成缓存降级、 gs_* 工具输出的规范 JSON 与宿主校验器一致性、test/planets.test.mjs 的全部 22 条、 test/equations.test.mjs 的全部 27 条……) 在任何检出里都照跑。

唯一的例外是 test/host-validator.test.mjs:这一层要解析宿主的 validateJsonSchemaValue,所以前置条件是本机装过 dsh(解析基座见 lib/resolve.js)。没装时它是硬失败而不是 skip—— 实测 10 fail / 2 pass / 0 skip。这是刻意的:这一层存在的意义正是证明其余断言不是恒真的, 让它静默跳过就等于把「已验证」变成一句空话。装上 dsh 后这 10 条照跑。

想要全量(含夹具与语料层):把 _probe/(docs/DESIGN.md 里有每个页面的抓取依据)与 hsr-missions/ 准备好,或直接在作者工作区里跑。

最关键的一条产品证据(可复现):node _evidence/check-prompt-section.mjs

它从隔离实例的真实会话日志里解析出注入记录,证明模型确实收到了这份指导,而不只是「插件注册成功」:

record type=system/message  role=system  chars=3500   <- 整条组装后的系统提示
风格总则本体 = 725 字符(= 抓取当次的 __internals.STYLE_GUIDE.length,与日志内容逐字节一致)
gs_* tools in the request tool list: gs_digest, gs_missions, gs_read, gs_save, gs_setup, gs_update
  YES  章节标题 / 风格总则 / 功能 1 四个字段 / 功能 2(2000 字·荒诞但不轻浮)
  YES  功能 3(女声·男声·(音乐)·结束语·800–1200 字)/「不得凭空编造与既有设定冲突的事实」

即:风格总则(本体 725 字,0.1.0 版)与当时三个功能的逐字格式进入了那条 3500 字的组装后系统提示, 6 个 gs_* 工具同时出现在请求的工具列表里。 输出在 _evidence/prompt-section-injection.txt。

口径提醒(复核者 R3-5 纠正,我先前表述有夸大):3500 是整条系统提示的长度,不是风格总则的长度。 复核者另做了更强的一致性检查:日志里的风格文本 includes(STYLE_GUIDE) === true,即与抓取当次的源码逐字节一致。

版本提醒:上面这段是 0.1.0 的快照,当时 STYLE_GUIDE 为 725 字符。此后每次改提示词长度都会变: 0.1.1(加入「星神纪律」)为 1161 字符 / 55 行,0.2.1 为 1291 字符 / 57 行, 当前源码(0.3.0,加入「星球制造机」格式与两问纪律)为 1748 字符 / 72 行。 _evidence/prompt-section-injection.txt 仍是 0.1.0 那次抓取,对 0.3.0 已过期; 要刷新它需要在隔离实例里重跑 node _evidence/check-prompt-section.mjs(本机日常实例不重启)。 0.3.0 这条链路由 test/planets.test.mjs 的两条离线断言兜底:系统提示总则里必须出现星球格式与两问, /gs 协议文本里必须出现四个功能与两问。

开发/取证目录(不属于插件运行时,不随包发布)

目录内容
_probe/抓取前的结构侦察产物:12 个页面的原始渲染 HTML、结构普查文本、真实 wikitext 样本。是 docs/DESIGN.md 里每条选择器的原始证据
_evidence/自证与复核证据:离线重放报告、真机抓取日志、缓存往返日志、接线检查、端到端验证脚本与输出、独立复核报告 review-shell.md
BRIEF.md实现规格(数据源结构实测记录 + 接口契约)。有勘误表,见文件头的回填说明

隔离实例端到端验证(绝不动你自己的 ~/.dsh):

node _evidence/verify-gs-e2e.mjs          # 默认路径,约 15 秒
node _evidence/verify-gs-e2e.mjs --model  # 额外让模型真调一次 gs_setup(隔离 home 无模型路由,会超时)
# 1) 建一个临时 DSH_HOME + web profile(bundles 含本插件)
# 2) 起 dsh --profile web --port 3081 --no-open
# 3) 用启动 token 换签名 cookie
# 4) session/create → commands/list(确认 /gs 出现)→ commands/execute "/gs"
# 5) 收尾:taskkill 自己的子进程树 + 杀掉「测试端口」的持有者

诚实边界:--model 那一步在隔离 home 里必然超时——启动 token 与模型路由都属于你自己的实例, 隔离 home 两者都没有(实测:prompt 被接受后 180 秒内会话日志始终为空)。该契约因此由 test/host-validator.test.mjs(用宿主同一个校验函数,离线)与你实例里那次真实调用共同覆盖: 插件首次装好后模型确实调到了 gs_setup,而正是那一次暴露了 lastUpdated: null 的 schema bug。

⚠️ 收尾只用 taskkill /PID <自己的子进程> /T 加「测试端口持有者」。不要改成 Get-Process node | Stop-Process——开发过程中这么写了一次,把用户正在使用的 dsh 实例 一起杀掉了(已修正,教训记在 _evidence/verify-gs-e2e.ps1 文件头与脚本注释里)。


版权

插件源代码与文档以 MIT 许可发布,见 LICENSE。 NOTICE 另外声明了第三方归属:《崩坏:星穹铁道》的游戏文本与世界观设定版权归 米哈游(HoYoverse),Wiki 页面文本版权归 Bwiki 编辑者;MIT 不覆盖这些素材。

原始文本版权归米哈游(HoYoverse)及 Bwiki 编辑者所有。本插件产出的内容属于非营利性二创, 米哈游对二创持开放态度。仅供个人学习、检索与研究使用。