npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

opencode-wiki-historian

v0.5.2

Published

opencode plugin that manages a wiki.js knowledge base with bilingual pages, genre templates, and migration tooling.

Readme

opencode-historian

OpenCode 插件:双语 wiki.js 知识库管理 / Bilingual wiki curator as an OpenCode plugin.

opencode-historian 把 wiki.js 的读写、翻译、页型规范、迁移工具打包成一个 OpenCode 插件,让 AI agent 能直接管理双语知识库。它为什么存在、文风从哪里来、怎么一句话开始用,见下文「史官宣言」。

功能一览:

  • 10 个 historian_* 工具,覆盖创建、更新、追加、翻译、搜索、阅读、地图/时间轴/维护报告、迁移、删除、移动
  • Skill v5 随插件自动注入(config hook),无需手动安装 skill 文件
  • G1 至 G6 页型契约,每种页型对应专属骨架模板(v4 新增 G6 操作手册/how-to)
  • 双语孪生页面(en/zh)自动翻译,翻译引擎可配置
  • 页面地图缓存、本地镜像、时间轴聚合视图与 maintain 维护策展报告(light/deep 两档)
  • options.sections 路径前缀白名单强制生效:配置非空时越界写入硬拒(ConfigError,请求发出前拒绝);homewiki-index_sandbox_data_meta_evidence 系统路径恒豁免;默认 [] = 不限制
  • historian_search 标签过滤:tags 1-5 个,tagsMode 默认 all(服务端 AND)、any 为客户端逐标签 fan-out 求并集
  • 顶层 home 落地页解锁:仅豁免精确顶层 home,其余保留字(login/register/graphql/healthz/_assets/favicon)与嵌套 home 照旧拒绝
  • 开工前置查阅回路(reading loop,默认关,双信号启用;v4 advisory:先查索引、update 优先、引页引日期、标注过期)+ /historian-capture 会话留痕(默认关)
  • 试点与评测均通过:pilot 7 页迁移 PASS,eval 7/7 场景首跑全过

史官宣言 / The Historian's Manifest

灵感 / Inspiration

这个插件的写作规则不是发明的,是从五种语言文化的 wiki 工程传统加一种运维文化里蒸馏出来的(调研全文见仓库内 docs/research/cross-cultural-wiki-writing-digest.md,每条主张附原文引用):

| 文化 | 给史官的贡献 | |---|---| | 中文 | 序言不可侵犯(多数读者只读序言,要点前置);可供查证(举证责任在添加内容的一方);金字塔原理的结论先行;阮一峰式行文纪律(句 ≤40 字、一文一事);企业事件复盘模板(摘要→背景→时间线→影响量化→根因→改进,改进措施是复盘最重要的部分,行动项必须带负责人、期限与验证方式) | | 英文 | WP:LEAD 导言自足、篇幅按重要性分配;Good Article 六项质量门;Diátaxis 四象限(tutorial / how-to / reference / explanation,模式混杂是文档烂的根源,参考页要像地图一样镜像系统结构);Google 技术写作"≥3 个相关字段就上表格";SRE blameless postmortem | | 德文 | 条目开头先定义、门外汉可懂、一文一概念反碎片化、禁止"杂项"小节;引证义务 Belegpflicht:"宁要格式错的引注,不要没有引注";评价必须归属到人,不带情绪(sine ira et studio) | | 法文 | 中立、非个人化、清晰、精确、易懂、有教学性六种品质;溢美词强制转成事实(用排名、奖项、销量替代"最伟大的"这类断言);耐久过滤:明天就会过时的内容不值得写 | | 俄文 | ХС/ИС 条目门槛(导言普通读者可懂、术语最少、不少于 10 行);二手权威来源优先于一手(АИ);每种观点按影响力分配篇幅、禁止虚假平衡(ВЕС);风格要求精确、简明、无歧义,同时保持内容饱和 |

SRE postmortem 文化单独值得点名:它把"事件"当一等文档对待,先证据后结论的证据链四段式(src/index.tsCAPTURE_COMMAND_TEMPLATE 模板)正是 /historian-capture 命令的正文契约:证据链→方法→修复手段→函数级实现,而"改进项要有负责人和可验证终态"落在了 G1 行动项表格里。

把这些文化做成插件的直接动因,是一个机构记忆问题:这台机器由一个人加一群 AI agent 操作。会话结束,终端滚动条就没了;上下文压缩,细节就丢了。部署过什么、发生过什么事故、踩过什么坑、做过什么决定,三个月后人和 AI 都无从查起。史官要解决的,就是让这台机器的历史变得可检索。

目的 / Purpose

让"这台机器上部署过什么、发生过什么、踩过什么坑、做过什么决定"成为人和 AI 都可索引、可引用、可审计的一等知识:

  • 知识落进结构化双语 wiki 页,而不是一次性的会话回复
  • 每个写操作强制回报 en + zh 双 URL(URL_MANDATEsrc/tools/shared.ts:39),引用链可回溯
  • wiki 成为任何 agent 会话开工前先查的权威来源,而不是锁在某个会话里的私有记忆

作用 / What it does

六柱页型契约,加上读写两条自动化回路:

| 能力 | 机制 | 落点 | |---|---|---| | 六柱页型 | G1 事件复盘 / G2 对比选型 / G3 清单索引 / G4 概念原理 / G5 现状账本 / G6 操作手册,写前声明页型,套固定骨架、过来源列检查 | src/templates/genres.ts,skill Phase 1.5 | | 三视图 | 地图视图(en/zh 对应关系,Locale/Twin 列)+ 时间轴视图(ISO 周分组,支持 days 窗口与 path 前缀过滤,人读周表 + 机读 weeks JSON)+ 维护策展报告(action:'maintain':双语缺口、近似重复标题、过期、孤儿候选、标签词表、章节分布;light 档只扫地图行加每 locale 一次 pages.listdeep:true 逐页读正文补新鲜度标记与 Redirect 存根识别) | historian_mapaction:'show' / 'timeline' / 'maintain' | | 迁移与评分门禁 | 存量页按骨架重排:dry-run 评分在前,apply=true 自动 pre-image 备份;每页写入后过 10 项自检门 | historian_migrateselfReviewChecklist() | | 前置查阅回路 | 向每次请求的 system 提示注入"先查 wiki"指令(单块合并:追加到最后一个 system 块,绝不产生第二条 system 消息;双信号门控:选项与本机哨兵文件同时到位才注入):v4 advisory 四条——先读 wiki-index / historian_map show 定位再 historian_search(index-first);update 优先于 create;引用页面时带 URL 与日期;发现矛盾/过期在页内标注(supersede 或复核章)而非静默覆盖,G5 账本逐行核对「上次核实于」 | readingLoop 选项(默认 false,开启需配置+哨兵双确认)+ 哨兵文件 ~/.config/opencode/historian-reading-loop.jsonsrc/index.tsexperimental.chat.system.transform 钩子 | | 主动留痕 | /historian-capture 命令把当前会话总结成 G1 事件页;开启 capture.enabled 后额外在会话空闲时弹一次提醒,仅提醒,绝不自动写页 | src/index.tsconfig / event 钩子 |

G5 现状卡回答"现在跑着什么",timeline 回答"最近两周变了什么"。比如问"service-a 现在监听哪个端口",应当命中现状账本里的一行(形如 example.com:8000,带上次核实日期与验证命令),而不是某次会话的聊天记录。这两样合起来,wiki 才从文档堆变成可查询的运维账本。

知识库要同时满足四种诉求——档案、手册、百科、知识库(速查)。六柱页型加索引层按层分工:

| 层诉求 | 回答的问题 | 对应页型 | 承载机制 | |---|---|---|---| | 档案 | 发生过什么、现在跑着什么 | G1 事件复盘 + G5 现状账本 | G1 时间线带来源列;G5 每行带「上次核实于」+ 验证命令 | | 手册 | 怎么把一件事做完 | G6 操作手册 | 目标句式标题、步骤三段(动作+预期结果+失败处置)、上次核实+复核周期 | | 百科 | 它是什么、为什么 | G4 概念原理 | 概念定义 → 图示 → 示例 | | 知识库(速查) | 该选哪个、去哪查 | G2 对比选型 + G3 清单索引 | 对比表带来源列;可勾选检查项 | | 索引层 | 从哪读起 | ——(不是页型) | wiki-index 人策展目录 + historian_map 的 show/timeline/maintain |

使用方式 / Usage

端到端最短路径(适配你自己 wiki 的六步完整指南见 skills/historian/references/adapting-your-own-wiki.md):

  1. 安装opencode.json[c]plugin 数组加 "opencode-wiki-historian"(npm 发布后)或 "file:///home/<you>/workspace/opencode-historian"(本地开发),细节见下文「安装」。

  2. 配置:最小三个选项;翻译腿可以不配,双语孪生会优雅降级为 pending:

    ["opencode-wiki-historian", {
      "baseUrl": "http://<your-wiki>:3000",
      "apiKeyPath": "~/.wiki-key",
      "sections": ["team-notes/"]
    }]
  3. 口述写史:对 opencode 说自然语言,史官完成分诊→放置→页型→骨架→自检→写入,并回报双语 URL:

    service-a 今天 OOM 重启,根因是缓存没设上限,已加告警,记下来。

    → 分诊为事件复盘,声明 G1 → historian_page_creategenre: "G1")→ 回报 http://<your-wiki>:3000/team-notes/<slug> 与它的 /zh/ 孪生页。

  4. 检索与整理historian_search 按主题查,可按标签过滤(tags 1-5 个,tagsMode 默认 all 即服务端 AND,any 为客户端逐标签 fan-out 并集);historian_mapshow 看双语地图、timeline(可选 days / path)看最近变动、maintain(可选 deep:true)出维护策展报告;存量页不合规用 historian_migrate 先 dry-run 再 apply。

  5. 开关:reading loop 默认 false,开启需配置+哨兵双确认,两步缺一不可:

    1. 插件二元组第二参数写 "readingLoop": true["opencode-wiki-historian", { "readingLoop": true }]

    2. 人工写入本机哨兵文件(agent 不能自我启用):

      cat > ~/.config/opencode/historian-reading-loop.json <<'EOF'
      {"version":1,"confirmed":true}
      EOF

    任一信号缺失即不注入;配置已开而哨兵缺失时,插件加载期会打一条提示(给出哨兵路径与内容),不会静默失灵。删除哨兵文件即刻回退,无需改配置。想要空闲留痕提醒就 "capture": { "enabled": true }/historian-capture 命令本身与开关无关、始终注册。

解耦声明 / Decoupling

插件与任何一台机器的 wiki 内容零耦合:

  • sections 默认空列表 = 不设路径前缀限制,实际写权限由 wiki.js token 的 page rules 决定;包内不携带任何真实主机、真实章节分类学或页面数据
  • 翻译腿零内置地址:解析链只有 translate.endpoint 选项 → 环境变量 HISTORIAN_TRANSLATE_ENDPOINT → 未配置,未配置时孪生降级 pending,不发任何网络请求
  • tools/privacy-audit.mjsnpm pack 清单里的每个随包文件跑隐私红线 regex(真实主机 / 本机路径 / 本机章节名 / 密钥形态 / 个人身份),任何命中即非零退出、拦住发布;已接入 prepublishOnly(build → test → audit)
  • 随包文本里的示例全部占位符化:http://<your-wiki>:3000team-notes/example.com

仓库 / Repository

源代码仓库由维护者自管;本包的公开分发渠道是 npm registry(opencode-wiki-historian)。 Source repository is managed by the maintainer; the public distribution channel for this package is the npm registry (opencode-wiki-historian).

安装 / Installation

两种安装方式经过实测验证。

方式一:npm 包(推荐(发布后))

opencode.jsonopencode.jsoncplugin 数组中添加包名:

{
  "plugin": ["opencode-wiki-historian"]
}

注:npm 包名为 opencode-wiki-historian(opencode-historian 已被注册表上一无关同名包占用);仓库与插件 id 仍为 opencode-historian。

发布准备状态:包已按 0.1.0 打包就绪(npm pack 验证通过),npm 发布需账号 2FA 一次性完成(npm publish --access public --otp=<code>)。在发布完成前,方式二 file:// 为当前可用安装路径。

方式二:本地路径(开发用)

用绝对路径指向本地构建目录:

{
  "plugin": ["file:///home/<you>/workspace/opencode-historian"]
}

此方式已通过 opencode run 验证,10 个 historian 工具全部注册成功(.qa/12.txt)。

安装后验证

插件注入的 skill 会注册 /historian 命令。验证方法:

opencode run --command historian --message "historian_map show"

如果工具列表中出现 historian_page_create 等 10 个工具,安装成功。

升级提示:如果你之前使用过 historian v2 的扁平 skill 文件(如 ~/.config/opencode/skills/historian.md),需要先重命名为 historian.md.v2-disabled 或移到别处。插件通过 config hook 自动注入 v5 skill,两个同名 skill 不能共存。

配置 / Configuration

插件支持元组形式传入选项:

{
  "plugin": [
    ["opencode-wiki-historian", {
      "baseUrl": "http://your-wiki:3000",
      "apiKeyPath": "~/.wiki-key",
      "translate": {
        "endpoint": "https://<your-anthropic-compatible-gateway>/v1",
        "model": "qwen3.7-plus",
        "apiKey": "<YOUR_KEY>",
        "providerKey": "my-provider"
      },
      "sections": ["team-notes", "infra"],
      "locales": ["en", "zh"]
    }]
  ]
}

不传选项时等同 ["opencode-wiki-historian"],使用全部默认值。插件包内不携带任何特定机器的配置(章节分类学、翻译网关地址均已清空为通用默认)。

选项全表

| 字段 | 类型 | 默认值 | 说明 | |---|---|---|---| | baseUrl | string | http://localhost:3000 | wiki.js GraphQL 端点 | | apiKeyPath | string | ~/.wikijs-api-key | wiki API key 文件路径(tilde 在读取时展开) | | translate.endpoint | string | 未配置(见下方链) | 翻译 API 端点 | | translate.model | string | qwen3.7-plus | 翻译模型 | | translate.apiKey | string | 见下方链 | 翻译 API 密钥 | | translate.providerKey | string | 未配置 | jsonc 兜底腿读取的 provider 名;须显式设置才会启用该腿 | | sections | string[] | [](不限制) | 写入路径前缀白名单。v4 起强制生效:非空时 create/update/append/delete/move(目标路径) 在发出请求前做 sectionGuard 检查,越界返回 ConfigErrorhomewiki-index_sandbox_data_meta_evidence 恒豁免;按首路径段匹配、区分大小写 | | locales | string[] | ["en", "zh"] | 启用的语言列表 | | readingLoop | boolean | false | 开工前置查阅 advisory,向每次请求注入"先查 wiki"提示;默认 false,true 需配置+哨兵双确认(见「使用方式」开关步骤);单块合并追加到最后一个 system 块,绝不产生第二条 system 消息,vLLM 等拒绝多条 system 的严格后端同样安全 | | capture.enabled | boolean | false | 开启后会话空闲时弹一次 /historian-capture 留痕提醒;仅提醒,不自动写页 |

translate.endpoint 解析链(优先级从高到低):translate.endpoint 选项 → 环境变量 HISTORIAN_TRANSLATE_ENDPOINT → 未配置。包内内置任何网关地址;未配置时翻译调用直接以 translate.endpoint not configured 失败(见降级行为)。

sections 默认为空列表 = 不限制路径前缀(任意合法路径可写,实际权限由 wiki.js token 的 page rules 决定)。按机器通过选项传入白名单,例如 ["team-notes", "infra", "ops"]。传入非空列表即强制生效(v4):五个写入工具先过 sectionGuardsrc/tools/shared.ts),不在白名单内的路径直接以 ConfigError 拒绝、不发任何写请求;报错信息会点名越界的首段并提示把它加进 sections。两个细节:匹配按首路径段、区分大小写,doc 授权 docdoc/x 但不授权 docs/x;配置项首尾斜杠可省。homewiki-index_sandbox_data_meta_evidence 是插件自记账与索引胶水所需,恒豁免。

API Key 获取优先级

翻译 API keytranslate.apiKey),按优先级:

  1. 配置对象中的 translate.apiKey 字段
  2. 环境变量 DASHSCOPE_API_KEY
  3. opencode jsonc 配置中 provider["<translate.providerKey>"].options.apiKey(仅当显式设置 translate.providerKey 时读取;包内不内置默认 provider 名)
  4. 均无则抛出 ConfigError('missing-translation-key')

wiki.js API key,按优先级:

  1. apiKeyPath 指向的文件内容
  2. 环境变量 WIKIJS_API_KEY
  3. 均无则抛出 ConfigError('missing-wiki-api-key')

降级行为

key 缺失时 ConfigError 记录一次日志,插件工具全部禁用,opencode 正常启动不受影响。translate.endpoint 未配置时双语孪生功能降级为 pending 状态(twinReason: 'translate.endpoint not configured — ...'),创建页面只写入请求 locale 的内容,不会发起任何翻译网络请求。

已知限制

| 现象 | 定性 | 说明 | |---|---|---| | 裸配置未传 translate 选项(三段 key 链 translate.apiKeyDASHSCOPE_API_KEYtranslate.providerKey 全缺)时插件工具全部禁用 | by design | 翻译腿是写操作的前提,缺 key 时宁可整体禁用也不静默半成品;配置按上方选项全表补齐即恢复。缺配置时的部分降级(工具照常注册、仅翻译调用失败)在议 | | 自进化驱动(readingLoop + capture)默认关闭,作者本机也尚未点亮 | 状态如实 | 两个开关缺省均为 falsesrc/config.ts:100 DEFAULT_READING_LOOPsrc/config.ts:102 DEFAULT_CAPTURE_ENABLED),readingLoop 还需配置+哨兵双确认。v0.4.0 发布仍待人工 2FA 步骤(npm publish 需 OTP),本机启用要等发布落地后进行;回路代码与测试已就绪,但在真正点亮之前本文档不假装它在跑 |

wiki.js 前置检查 / Prerequisites

安装插件前,确认 wiki.js 实例已完成以下配置。本插件不自动执行任何管理端操作。

多语言

  • Admin > General > Multilingual:启用 namespacing
  • Active Namespaces 包含 enzh
  • zh 命名空间是语言切换器和 URL 路由的前提

API Token

  • Admin > API Access 创建 token
  • 需要的 scope:write:pagesdelete:pagesmanage:pagesmanage:system
  • 将 token 写入 apiKeyPath 文件或设为 WIKIJS_API_KEY 环境变量

页面权限

  • Admin > Groups 中对应组的 page rules 必须覆盖插件 sections 配置的路径前缀
  • 路径不在 page rules 范围内会触发 PermissionError(评测场景 R-b 验证)

主题与显示

  • wiki.js 自动生成目录(TOC),通过 Admin > Theme 配置位置,页面内容里不要{{toc}}
  • 自定义 CSS/HTML 注入入口在 Admin > Theme
  • 建议关闭评论功能,避免知识库页面被评论干扰

中文页面在哪看 / Viewing Chinese Pages

中文页面的 URL 格式:

http://<host>/zh/<path>

例如 ops/deploy-checklist 的中文版在 http://<host>/zh/ops/deploy-checklist。英文版不带 locale 前缀:http://<host>/ops/deploy-checklist

语言切换器出现在页面右上角的前提是 namespacing 已开启且 zh 在 Active Namespaces 里。看不到切换器时,检查 Admin > General > Multilingual 设置。

工具返回值:每个写入操作的结果都会同时回显 en 和 zh 的 URL,格式如:

en: http://<host>/ops/example
zh: http://<host>/zh/ops/example

地图视图historian_map show 输出包含 Locale 和 Twin 列,展示每个路径的双语对应关系。本地镜像文件保存在 ~/.config/opencode/historian-map.jsongetMap 读取,带过期秒数);_meta/page-map 是 wiki 端的缓存页,由 historian_map refresh 写入。

时间轴视图historian_map action:'timeline' 把镜像行按 ISO 周分组(可选 days 窗口与 path 前缀过滤),输出人读周表 + 机读 weeks JSON,回答"最近哪些页面变过"。

维护视图historian_map action:'maintain' 输出策展报告——双语缺口、近似重复标题、过期页面、孤儿/扩散候选、标签词表、章节分布。默认 light 档只扫地图行加每个 locale 一次 pages.listdeep:true 逐页读正文,补新鲜度标记与 Redirect 存根识别。

写作质量体系 / Quality System

G1 至 G6 页型

插件根据内容形态把每页归入六种页型之一,每种有专属骨架模板:

| 页型 | 用途 | 骨架结构 | |---|---|---| | G1 事件复盘 | 故障、踩坑、事后分析 | 时间线 → 根因 → 影响 → 行动项 → 教训,附来源列 | | G2 对比 | 技术选型、方案比较 | 来源声明 + 对比表格 + 结论 | | G3 清单 | 操作步骤、检查项 | 可勾选的检查项列表 | | G4 概念 | 架构说明、原理讲解 | 概念定义 → 图示 → 示例 | | G5 现状账本 | 此刻的部署/运行态,回答"现在跑着什么" | 状态块 → 部署物清单(每行带「上次核实于」+ 验证命令)→ 失效策略,禁止叙事正文 | | G6 操作手册 | how-to,回答"怎么把一件事做完",目标句式标题 | 前置条件 → 操作步骤(每步含预期结果+失败处置)→ 回退 → 元数据表(上次核实 + 复核周期)→ 相关页面 |

10 项自检门

每页写入后过一遍自检清单(源码 src/templates/genres.ts selfReviewChecklist(),参考文件 skills/historian/references/rules.md + genres.md)。dry-run 阶段评 1–8,apply 后评 9–10。genre-specific 条目对不匹配的页型记 N/A=PASS;G5 页的第 4–6 项换成账本变体(G5_CHECKLIST_VARIANTS),G6 页换成手册变体(G6_CHECKLIST_VARIANTS):第 4 项要求标题是目标句式 "How to X" / "如何/怎么做X",第 5 项要求每条操作步骤三段(动作 + 预期结果 + 失败处置),第 6 项要求元数据表含「上次核实」与「复核周期」行:

  1. 导言占比 10–15%:导言 ≈ 正文的 10–15%,每个重要小节在导言至少占一句
  2. 句长上限:中文句 ≤20 字、英文句 ≤25 词
  3. 表格判据:≥3 字段的结构化枚举入表,成对数据用描述列表
  4. 对比表来源列(G2):对比表/枚举表每行有来源列,行序固定、无合并单元格;G5 变体:部署物清单每行带「上次核实于」列
  5. 时间线来源列(G1):时间线每行有来源列,仅日志可证事实;G5 变体:验证方法含可执行复核命令
  6. 行动项五要素(G1):类型|负责人|期限|验证|状态 五列,措施是行内容;G5 变体:无叙事正文,只有状态块 + 表格
  7. 无杂项筐:除 参见/附录 之外没有 "其他/杂项" 类 catch-all 小节
  8. 无溢美词:领先/强大/灵活/高效 等 bare claim 改事实或删除
  9. 双语 URL 已回报(写后核销):报告含 /en/ 与 /zh/ 两个可访问 URL
  10. 孪生已建或 zh_status:pending 声明(写后核销):twin created OR zh_status pending recorded and declared in report

SYN 20 规则

更细的 20 条写作规则散布在 skills/historian/references/ 目录下各参考文件中,agent 加载 skill 时自动读取。

前台 / 后台 / 证据三层 / Three Content Tiers

wiki 内容按读者分三层,工具按层执行不同语义(historian_page_createtier 参数):

| 层 | 位置 | 职责 | |---|---|---| | 前台 (front) | 主题章节的 G1-G6 页 | 人写人读的知识页;双语孪生、进索引;只放提炼后的内容与链接 | | 后台 (backstage) | _meta/ 页 + 本地镜像文件 | 机器记账:page-map 缓存页、迁移 checkpoint、reading loop 哨兵文件;不参与人读正文 | | 证据 (evidence) | _evidence/ | 超 10 行原始件(日志、转写、大 diff)的归宿:单语 en、不发布(匿名访问 404 是 by design),人类页面只链接不复制 |

用法示例:

// 大段原始材料先落证据页,再在人读页附录里给链接
historian_page_create({ path: "_evidence/<topic>--<yyyymmdd>", tier: "evidence", content: "<原始件全文>" })
  • 软提醒语义(soft advisory):写前台页时若内容含超过 30 行的围栏代码块,工具结果附一条 advisory,提示把原始件搬到 _evidence/ 页、正文改放决定性摘录(每段 ≤10 行)+ 证据页链接 + 外部链接(commit/PR/告警)。提醒归提醒,写入永不阻断;证据层页自身不跑这项检查。
  • 镜像与快照页分工:本地镜像 ~/.config/opencode/historian-map.json 是活查询的唯一来源(historian_map show 直接读它);_meta/page-map wiki 页是审计账本,historian_map refresh 每次提交一个新修订,wiki 的页面历史即全库变更时间线。

wiki.js 用法与定制化 / Usage Guide

Markdown 速查

| 元素 | 写法 | 说明 | |---|---|---| | 提示框 | > 内容\n{.is-info} | .is-info / .is-warning / .is-danger / .is-success | | 紧凑表格 | 标准 markdown + {.dense} | 减小行距 | | 脚注 | [^n] 正文 + [^n]: 内容 底部 | wiki.js 原生支持 | | 定义列表 | term\n: definition | 术语表用 | | 数学公式 | $...$ 行内、$$...$$ 块 | KaTeX 渲染,默认开启 | | 流程图 | ```mermaid 代码块 | mermaid 渲染,默认开启 | | 标签页 | {tabset} + ## Tab Name | 多标签内容切换 |

禁用项

  • {{toc}}(目录由主题配置自动生成)
  • ::: 容器(wiki.js 不解析)
  • YAML frontmatter(API 创建页面不经过 frontmatter 解析)

API 陷阱与插件应对

wiki.js GraphQL API 有 9 个常见陷阱。插件在内部处理了每一个(详见 skills/historian/references/wikijs-guide.md,原始报告路径 docs/research/wikijs-2x-report.md):

| 陷阱 | 插件应对 | |---|---| | pages.update 是整页替换,不是增量合并 | 工具内部做 read-modify-write | | pages.create 返回值缺部分字段 | 创建后立即 readback 拿完整数据 | | responseResult 嵌套结构,需取 .id | 解析层统一提取,上层拿到的是直接值 | | 空 content 被拒绝 | 引擎 pre-check ContentEmptyError;不传 content 时走 template-only 模式,不发 GraphQL 写请求 | | 移动页面不能用 update 改路径 | 用独立的 pages.move mutation | | singleByPath 必须传 locale | 所有查询强制带 locale 参数 | | 上传附件字段名必须是 mediaUpload | 内部固定字段名(src/wiki/assets.ts) | | isPublished: false 的页面匿名访问报 404/403 | 创建草稿时在工具输出中标注 | | 路径不能以 locale 前缀开头 | validatePath 拒绝 zh/... 形式的输入 |

从 historian v2 迁移 / Migrating from v2

旧版 historian v2 依赖 /opt/wiki-ops/ 下的 Python 脚本(wiki-ops.pywiki-biling.py)。插件完全替代了这些脚本。旧脚本保留在原位不动(标记 LEGACY),不需要删除。

命令映射表

| wiki-ops.py 子命令 | historian 工具 | 备注 | |---|---|---| | list | historian_map (show) | 地图缓存替代全量列表 | | read <id> | historian_read (path) | 改用 path 定位,不再用数字 ID | | append <id> <file> | historian_page_append | 直接传 section 内容,不用写临时文件 | | create "Title" "path" <file> | historian_page_create | content 参数直接传,可省文件 | | rebuild-tree | historian_map (refresh) | 从 wiki 重建地图缓存 | | search "keyword" | historian_search (kind=title) | 标题搜索 | | search-content "keyword" | historian_search (kind=content) | 全文搜索 | | fetch <id> / fetch-paths <path> | historian_read | 按 path + locale 读取 | | cache-read | historian_map (show) | 本地镜像 | | cache-refresh | historian_map (refresh) | 重建缓存 | | delete <id> --confirm | historian_delete | confirm 参数必须为 "yes" |

| wiki-biling.py 子命令 | historian 工具 | 备注 | |---|---|---| | create-bilingual | historian_page_create (twin=true) | twin 默认开启 | | append-bilingual | historian_page_append + sectionZh | sectionZh 参数携带中文内容 | | translate-snippet | historian_translate_snippet | 纯本地翻译,不写 wiki | | status | historian_map (show) | 双语状态在地图中展示 | | checkpoint | migrate store 文件 | 迁移进度持久化 | | run / run --path | historian_migrate (apply=true) | 支持 dry-run(apply=false) |

升级步骤

  1. 重命名旧 skill 文件:mv ~/.config/opencode/skills/historian.md ~/.config/opencode/skills/historian.md.v2-disabled
  2. opencode.json[c]plugin 数组中添加 opencode-wiki-historian
  3. 重启 opencode,/historian 命令可用即表示 v5 skill 已注入

运维 / Operations

迁移工具

historian_migrate 把现有页面重新格式化为对应页型骨架:

  1. 先 dry-runapply=false(默认),查看骨架预览和自检评分
  2. 再 applyapply=true,引擎在首次写入前自动生成 pre-image 备份
  3. 回滚:读备份 JSON,用 historian_page_update 推回原始内容

备份文件位于 results/pilot-backup-*.json。迁移进度存储在 ~/.config/opencode/historian-migrate.json,支持断点续跑。

评测框架

harness repo(与本插件仓库同工作区)提供 7 个行为验收场景,覆盖创建、追加、重叠整合、整理、价值门控、G1 格式、zh URL 报告。v3 插件评测结果:7/7 PASS,51/58 适用分,G=1,零重试(results/2026-09-02-v3-plugin.md)。

开发 / Development

npm run build       # tsc 编译到 dist/
npm test            # vitest run(493 tests, 20 files)
npm pack --dry-run  # 检查打包文件列表

打包文件(files 字段):distskills。加上 npm 自动包含的 README.mdLICENSEtools/(pilot-run、finish-publish、install-skill)为仓库开发工具,不随包分发。

许可证

MIT