# dsh-tiddlywiki 使用指南

> 从 README 拆出：使用指南 / 配置 / 远程访问。

### 🤖 Agent 工具（15 个）

| 工具 | 说明 |
|---|---|
| `tiddlywiki_search` | 检索（`query` + 可选 `tags[]/tag/since/type/field/value/limit`），**按相关度排序**（标题命中 > 标签 > 正文命中次数），摘要取自**命中处上下文**而不是正文开头。v0.24.0：`query` 按空白切词、**全部词命中**才算（AND）；默认**先在工作区内查、区内 0 条才自动扩大到全库**，回执里写明实际范围 |
| `tiddlywiki_recent` | 最近修改的笔记（倒序，支持 `limit`/`since`），开工快速了解动态 |
| `tiddlywiki_list_tags` | 现有非系统 tag 及计数（已排除只挂在二进制附件上的 tag）；默认列使用最多的 200 个（`limit` 可调、上限 1000），截断时返回 `total`/`truncated` |
| `tiddlywiki_get` | 读单个 tiddler 全文（`modified` 以 ISO 返回，可直接用作 `expectedModified`） |
| `tiddlywiki_put` | 写/覆盖；**新建**未指定类型时默认 `text/markdown`（`$:/` 系统条目除外），**覆盖既有条目时保留原 `type`/tags/自定义字段**（v0.20.1，改类型要显式 `fields.type`）；`expectedModified` + `force` 提供乐观并发保护 |
| `tiddlywiki_batch_put` | 批量写入（`overwrite=false` 跳过已存在；单条失败不影响其余、逐条报错；4 路并发但结果保持入参顺序） |
| `tiddlywiki_append` | **增量追加**：`mode=append\|prepend`、`heading=某标题` 定位写入（落点 = 该标题之后、**下一个任意级别标题之前**；CRLF 行尾的笔记同样有效），写日志/批注无需读全文；标题不存在时**不报错但也不再装成功**——追加到文末并返回 `headingMatched=false` + 回执明说；与 `put` 同一套写策略（保留原 `type`/tags/自定义字段，新条目才默认 markdown），支持 `fields` 显式覆盖 |
| `tiddlywiki_rename` | 重命名 + 尽量同步其他条目里的引用；旧标题删除失败时如实回报「两份副本都在」 |
| `tiddlywiki_delete` | 删除（幂等）。默认**软删除**进 `$:/dsh-tiddlywiki/trash/`，`permanent=true` 才真删；支持 `expectedModified`/`expectedRevision`/`force` 乐观并发（读后被改动则拒绝，不把人类的新改动丢进回收站） |
| `tiddlywiki_trash` | 回收站：`action=list\|restore\|empty`（索引读不到或损坏时显式报错，绝不把回收站当空的重建） |
| `tiddlywiki_backlinks` | 反向链接：谁用 `[[标题]]`/`{{标题}}` 引用了它、谁把它当标签 |
| `tiddlywiki_attach` | 把**本机文件或公网 http(s) 地址**存成附件（图片/PDF/… 等二进制存 **`type` + base64 正文**；`text/markdown`·`text/plain`·`application/json` 等**文本**存 `type` + **纯文本正文**，这样 TW 才渲染得出来、也才搜得到 —— v0.30.22），可嵌入某篇笔记；URL 走 SSRF 守卫；**同名 tiddler 已存在时默认拒绝**（避免静默覆盖笔记），确认覆盖要传 `force: true`（tags/自定义字段仍保留） |
| `tiddlywiki_lint` | 知识库体检（**只读**）：垃圾标签 / 死链 / 空笔记 / 缺内容类型的类 Markdown 笔记 / **时效性内容**（`valid-until`·`review-after` 过期，以及「版本号或 done 标签 + 长期未改动」的**候选**，`staleAfterDays` 可调） |
| `tiddlywiki_git_sync` | `action: pull\|push\|sync` —— **作用于所有可同步的库**（v0.30.5；判定见 v0.30.58）：**「有远端」= 该库配了 `git.remote`，或它所在仓库有自己的 `origin`**（没配就自动回落，与设置页「同步」按钮同口径），两者都没有、或不在 git 仓库里的库被列出来而不是静默略过。多库各自独立仓库时逐仓库同步、**每个仓库只跑一次**（多库共用一个工作树时不会重复 pull/commit/push），一个仓库冲突不影响其余；回执逐仓库标注「哪个库 @ 哪个仓库」与**远端及其来源**（配置 / 自动识别自 origin；URL 里的凭据已剥） |
| `tiddlywiki_git_resolve` | pull 冲突后按 tiddler 二选一（`keep-local\|keep-remote`） |

**知识库同步纪律**：
1. 开工先 `tiddlywiki_git_sync action=pull`（rebase + autostash，真冲突会 abort 并报文件）。
2. 冲突后用 `tiddlywiki_git_resolve` 二选一解决，再重新 sync（**绝不自动覆盖**）。
3. 收工 `tiddlywiki_git_sync action=sync`（pull → commit → push）。**它与「同步」按钮的区别**（v0.30.5；v0.30.58 起口径对齐）：工具作用于**所有**可同步的库（一次一个仓库，各自独立成败），而设置页/FAB 的「同步」按钮只作用于**当前那个库**（它带着 `?wiki=`）。**「可同步」两边现在同源** —— 该库配了 `git.remote`，或它所在仓库有自己的 `origin`（v0.30.58 前工具只认前者，于是界面点得动、工具却回「没有任何知识库配置了 git.remote」）。多库各有仓库时，冲突回执会写清是哪个库，解决时把那个库的 id 传给 `tiddlywiki_git_resolve wiki=<id>`。

> 🛡 **带着冲突绝不提交**（v0.23.4）：`commit` 之前会探测「进行中的 rebase / 未合并路径 / **工作树里残留的冲突标记**」，命中就**拒绝提交**（`/sync` 返回 409 + 文件名、自动提交只上报一次、`/status` 与设置页状态行显示「冲突未解决（N 个文件，已阻止提交）」）。这条守卫来自真实事故：autostash 重新应用冲突后 `rebase --abort` 已无事可 abort，冲突标记留在工作树里被自动提交**永久写进了 git 历史**（连带插件自己解析不了配置）。**删冲突标记的方式**：解决后 `tiddlywiki_git_resolve`（或手动编辑掉 `<<<<<<<`/`=======`/`>>>>>>>` 三行）再 sync。
>
> ⚙️ **配置文件坏了会拒绝保存**（v0.23.4）：若 `$:/plugins/dsh-tiddlywiki/config` 不是合法 JSON（最典型就是残留冲突标记），设置页保存会**被拒绝**并在页面顶部显示红色横幅——而不是像以前那样拿空配置合并、把你其余的设置（`prompt.extra`/`git.remote`/`ui.*`…）一次抹掉。修好该 tiddler（或删掉它回落 `config:` 块）后即可正常保存。

> 🔍 **检索/最近跳过二进制附件**（v0.16.20）：`search`/`recent` 在**服务端**只取文本 tiddler（无 `type` 字段或 `text/*`），图片/音频/视频/PDF/zip 等二进制 tiddler（base64 正文）不参与检索、不出现在结果里——大 wiki（如数千张书籍扫描页图）从此从 515MB/17s 降到 ~0.4s，也不会被同名书页图刷屏。`get` 对二进制 tiddler 只返回元数据（`binary=true` + 类型/大小 + 链接），不返回 base64 正文。

> ⚠️ `fields.type` 是 TW 的**内容类型保留字段**（`text/markdown` 等），业务分类请放 `tags`，别写进 `fields.type`。
>
> 🧾 **`fields` 必须是对象**（v0.26.5）：三个写工具的 `fields` 参数是 `object`（如 `{"review-after":"2026-12-22"}`），**不要传字符串**。工具层会宽容地把 JSON 字符串解析成对象（兼容旧行为），但数组 / 解析不出对象的字符串会**明确报错**——早期版本曾把字符串按字符拆成 `0={`、`1="`… 几十个垃圾字段写进条目，真正的字段反而没写进去；碰到这种历史条目只能重建（`fields` 只能覆盖、不能删除单个字段）。

> 🕰 **过期内容怎么淘汰**（v0.24.0）：很多笔记是**阶段性**的（版本记录、部署步骤、排期、临时方案、一次性口令），过一段时间就不适用了。策略是**声明时效 + 人工决定，插件绝不自动删**：写这类笔记时带 `valid-until: YYYY-MM-DD`（硬过期）或 `review-after: YYYY-MM-DD`（该复查）；被取代时写 `superseded-by: [[新笔记]]` 并打 `superseded` 标签，**旧笔记保留**（wiki 是 git 仓库，留着的成本几乎为零，删错的成本很高）。`tiddlywiki_lint` 的 `stale` 检查会**只报告**三类：`stale-expired`（`valid-until` 已过）、`stale-review`（`review-after` 已到）、`stale-candidates`（带版本号或 `done` 标签且长期未改动——**明确标注是候选，不是判定**）。要清理就自己用 `tiddlywiki_delete`（默认进回收站，可恢复）。

> 🏷 **新建笔记自动标工作区**（v0.24.0，可用 `note.workspaceMark: false` 关闭）：`put`/`batch_put`/`append` **新建**条目时会自动带上 **`ws/<项目名>` 标签 + `workspace` 字段**，项目名取自当前会话的工作目录（`C:\work\alpha` → `ws/alpha`）。于是 `tiddlywiki_search` 默认就能「先在本项目里找」，而 `field: workspace, value: <项目名>` 可以精确按项目过滤。**不需要也不应该手动加**这两个标记（会在 `agent-written` 之外重复）；内容明显属于**另一个**项目时，显式传 `fields: {"workspace": "那个项目"}` 即可（显式值优先，不会被自动值覆盖）。为什么标签要带 `ws/` 前缀：裸项目名会和真实业务标签撞车——作者库里 `dsh-tiddlywiki` 这个标签已挂着 2510 篇导入的书籍章节，去掉前缀会让「在工作区内搜索」返回那 2510 篇。

### 🧠 注入的系统提示词（可配置）

插件会往每个会话的系统提示词里注入一段「TiddlyWiki 持久知识库」约定（**设置页 → 系统提示词**）：

| 配置 | 作用 |
|---|---|
| `prompt.enabled` | 关掉后本插件不注入任何文本 |
| `prompt.mode` | `slim`（**默认**，v0.29.0 起约 1.0KB）：只保留工具 schema 表达不了的约定（**同步时机**、写入被拒后重读而不用 `force`、时效标注 `valid-until`/`review-after`/`superseded-by`、淘汰权归人、`human-edited`、可点击链接格式、todo 约定）。与工具 description 逐字重复的句子**不再复述**（工作区标记、先窄后宽检索、多词 AND、tags/type 保留规则都在对应工具的 schema 里，`verify-prompt.mjs` 会在 schema 侧逐条守住"从提示词删 ≠ 丢了"）；`full`：额外附一份**参数索引**，由工具注册表在运行时生成，因此永远不会与真实工具脱节 |
| `prompt.extra` | 追加在末尾的自定义规范（团队 / 个人偏好），始终生效 |
| `prompt.override` | 非空时整段取代内置文本（`extra` 仍会追加）——想完全自写提示词时用 |

保存后**不用重启 dsh web**：host 会即时重新注册 prompt section，当前会话从**下一步**起就使用新文本（DSH 的 `system-prompt/change` 会更新历史里的系统消息）。设置页的「预览注入文本（按表单当前值）」按钮会把**表单里此刻的值**（含还没保存的形态切换 / extra / override / 停用开关）发给 host 实时拼成全文——所见即「保存后会注入的内容」，顶部还会标注「含未保存的修改」；预览是只读的，不会替你保存（v0.22.7 之前它只读**已保存**的配置，所以切换形态后不点保存直接预览会看到逐字节相同的旧文本，容易被读成「两种形态没差别」）。

> 🗂 **多库下这段提示词是"按会话求值"的**（v0.28.0 起就是这样，v0.28.8 复核确认）：section 的文本是一个**函数**，DSH 每次装配系统提示词时把该会话的 agent 传进来，插件据此读那个会话的**作用域库**，并从**那个库自己**的 `$:/plugins/dsh-tiddlywiki/config` 里取 `prompt.*`。所以在输入框上方把知识库从 A 换成 B，**下一步**注入的就是 B 的提示词（连 B 自己的 `extra` / `override` 一起换）——不需要重启，也不需要新开会话。单库安装（可见库 ≤ 1）时那行"当前知识库"说明整段**不注入**，文本与升级前逐字节相同。

> 为什么默认精简：v0.20.1 之前这段提示词里手抄了一份**工具参数清单**，最后一次同步停在 v0.19.0，而 v0.19.4 / v0.19.5 / v0.20.1 都改过工具参数——模型因此看到 6 处过期签名（`delete` 缺并发令牌、`append` 缺 `fields`、`attach` 缺覆盖保护、`batch_put` 缺 `overwrite`、`trash` 缺 `title`/`limit`、`list_tags` 缺 `limit`）。v0.21.0 起：默认形态不再复述参数（工具 description 才是唯一事实），`full` 形态的目录改为**运行时生成**，并新增 `scripts/verify-prompt.mjs` 守门（slim 不得出现参数清单 / full 的每个工具与每个参数都必须在场 / 两种形态都必须保留治理约定块）。

### 🧑‍💻 界面操作

- **📤 发送给 Agent**：TW 工具栏按钮（首次启动自动写入 wiki，ONE-SHOT）。弹层可选**附加说明**（位于消息末尾）、**工作模式**（Agent 预设）、**权限**（权限预设），按工作区分组选会话或新建。消息自带待办说明。
- **🧭 中央列编辑器**：侧边栏「TiddlyWiki」开关（显示名可改 `ui.sidebarLabel`，保存后即时生效，v0.22.8）。**多库模式下没有这个配置项**（v0.28.7）：侧边栏变成每个知识库各占一行、各用自己在「知识库列表」里配的**显示名**，统一名称已无意义，所以设置页只在单库模式渲染该字段。
- **🗂️ 右侧边栏 Tab**（v0.16.21）：DSH 新右侧栏展开后，首页会出现「**TiddlyWiki 知识库**」入口盒，点击即在右侧栏以 tab 形式打开完整 TW 编辑器——**与聊天并排**，适合边聊边查/边记。由 `ui.showRightbarTab` 控制（默认开）；老版本 DSH（无右侧栏）自动跳过。
- **🧩 Better Sidebar 共存**：装了 [dsh-better-sidebar](https://github.com/omdsh-dev/DSH-better-sidebar) 时，插件只做 UI 共存（中央 TW 面板的 z-index 自动压在其侧边栏展开/收起按钮之下，按钮始终可点）。**v0.17.0 起不再向 dsh-better-sidebar 注册「TiddlyWiki 知识库」tab**（旧版可用 `ui.showBetterSidebarTab` 关闭）——该 tab 的 kind 会与其它注册方冲突报 `tab kind "dsh-tiddlywiki" is already registered`。右侧边栏入口请用上面的 **右侧边栏 Tab**（DSH 原生 rightbar）。
- **📝 快速笔记**：输入框上方快捷按钮（`ui.showQuickNoteDock`）或 FAB；`ui.quickNoteMode` 选打开方式——**native**（默认，直达 TW 原生编辑页，草稿自动续写）或 **card**（CodeMirror 6 Markdown 高亮、文件上传、多选 tag、草稿自动保存、「🕘 最近」载入、Ctrl+Enter 保存）。**v0.22.6**：原生编辑弹窗里用 TW 的「🗑 删除」把笔记删掉后不会再变成打不开的白板——再点一次「快速笔记」就会重新载入编辑器；card 模式底部操作条改成「按钮文字永不折行、放不下时整组换行」，窄卡片里不再把「✏️ 在 TW 中编辑」压成两行。
- **📌 本地剪藏桥**（可选，v0.16.24+/v0.16.25 支持图片）：DSH 设置 → 常规配置 → 勾选「**启用本地剪藏桥**」（保存后立即生效）——DSH 即监听 `127.0.0.1:8618` 接收剪藏请求。浏览器书签栏新建书签，把知识库文档里的 JS 代码粘贴为地址，点一下弹出**浮层**：确认/修改标题与划线文字、勾选页面图片（封面自动标出）→「剪藏」即写入 wiki。文字成笔记（默认 `clip` 标签、正文含来源与选中文字、重名自动 `（2）` 去重）；**图片由 DSH 本机下载字节存为二进制附件**（`clip-url`/`clip-note` 溯源字段，笔记内 `[img[标题]]` 内嵌展示；某张下载失败自动降级为链接），全部随 wiki 自动 git commit。「📚 插件文档」栏的 `本地剪藏桥（书签小工具）` seed 文档含完整步骤、书签代码、安全说明与 curl 用法。安全：桥只监听 127.0.0.1 + Host 白名单防 DNS rebinding；**强烈建议设 `bridge.token`**（非空时校验书签的 `x-clip-token` 头，防止任意网页往 wiki 里塞内容）。图片附件按设计不参与 `search`/`recent`（避免刷屏），`get` 只回元数据。**v0.28.8 起可指定写进哪个库**：`bridge.wiki`（设置页里是「剪藏写入」下拉，只在多库时才有意义）——**不指定 = 写进知识库列表里带 ★ 的那个库**（下拉里那一项直接显示那个库的名字 +「（默认）」，v0.28.12 起不再出现「默认库」这种无名选项）；填了某个库的 id 就固定写它，与你在 GUI 里看的那个库无关（剪藏来自浏览器书签，没有"当前会话"可以跟随）。填了一个不存在的 id 时**不静默改落点**：`/clip` 回执带 `wiki` 字段说明实际落在哪，插件日志里也会提示一次。**v0.30.62 起落点规则收严**：填的库**已登记但没在运行** ⇒ 剪藏直接失败（503）并**点名那个库**，不会偷偷写进默认库（书签的成功提示现在也会显示实际写进的库 id）；只有 id **不在清单里**（已移出/打错）才回落默认库。⚠️ 这一组是**插件级**设置（整插件一个监听端口、一个写入目标，读取它的是默认库那份配置）⇒ 设置页只在**没选中具体库**时露出它，多库下选中某个库再改它是**不生效**的。
- **🏠 首页（初始化 home-index 后）**：待办四象限（`todo` 标签 + `q` 字段拖放分类）+ 快速记笔记（完整编辑器，勾选「同时加入待办」即建任务）+「所有标签 / 所有文章」入口 +「📚 插件文档」栏（自动收录所有带 `dsh-docs` 标签的 seed 文档）。
- **📚 会话知识库 Tab**：会话顶部 Tab（`ui.tabLabel` 改名、`ui.showSessionTab` 关闭），自动汇总本会话读写过的 wiki 笔记（写入 volatile `$:/temp`，不落盘不进 git），**TW 原生渲染**（v0.16.19 起 `/tw/render` 片段管线，与回复流工具卡同链路），链接点击直达中央 TW 面板，不可编辑。
- **🌗 跟随 DSH 主题**：内嵌 TW 随 DSH 深浅切换 palette，纯内存不写回 wiki（`ui.followDshTheme`/`ui.darkPalette`）。
- **🔧 知识库 FAB**：统一入口（TW 面板开关/重载、快速笔记、同步、TW 服务状态悬停 tip）。同步拉取到新内容会自动重启 TW（同端口）。
- **⚙️ 设置页**：DSH 设置 →「TiddlyWiki 知识库」：状态/重启、**知识库位置（可切换）**、常规配置、插件/主题/语言管理（**自带官方插件**的离线启停；经 TW 面板装的第三方插件以只读小节列出，见 v0.26.0）、**初始化**（seed 状态与重新初始化）。配置写入 `$:/plugins/dsh-tiddlywiki/config` tiddler，覆盖 cordis `config:` 块（tiddler 优先）。**v0.28.8 起分页**：多库模式下页面分成「**总览** / **本库配置** / **全局**」三个 tab——原来十几块面板从上到下挤在一页里，既看不出哪些是"改这个库"、哪些是"改整个插件"，改完也找不到退出口。现在：① 点某个库那一行的「**配置**」进入「本库配置」tab，按钮变成「**退出配置**」（再点一次回到总览，不用滚回页面顶部）；② 顶部「**配置作用域**」条一直显示正在改哪个库；③ 单库安装**没有 tab 条**，就是现在这一页，逐字不变。

### 🗂 多知识库（同时在线，v0.28.0）

默认是**单库模式**：一个知识库、一个 TW 子进程，一切与以前完全一样。要同时用多个库：

1. **加第二个库**：设置页 →「TiddlyWiki 知识库」→ **知识库列表** → 填根目录 + 文件夹名（+ 显示名）→
   「添加知识库」。目录不存在会自动 `--init server` 建一个全新知识库；已存在的目录直接接管。
2. **切到多库模式**：同一区块的「运行模式」选 **多库**。此后清单里的库都可用；标了「开局自启」的
   随 DSH 一起启动，其余在你打开或选中它时启动（**每个库一个 TW 子进程，约 150 MB**）。
3. **在界面里用它**：右下角「知识库」按钮的菜单会列出所有库（● 当前），点一个就切过去并打开它的
   编辑器；每个库的编辑器走自己的同源地址 `/dsh-tiddlywiki/tw/<id>/`，**不会串台**。
4. **告诉 Agent 用哪个库**：输入框上方会出现「知识库」下拉（**只在可见库多于一个时出现**），选择是
   **按会话**的，存在 `$DSH_HOME/dsh-tiddlywiki/sessions.json`，跨 `dsh web` 重启仍在。选一个没在跑的
   库会自动把它启动（工具是同步解析作用域的，所以"选中"这一步必须顺手起它）。
5. **让某个库对 Agent 隐身**：知识库列表里点该行的「**对 Agent 隐身**」。隐身 = Agent 永远碰不到它：
   不进选择器、不进注入提示词、检索 / lint / 反向链接都不含它。人仍然照常用 —— 适合书籍语料、导入归档。
6. **想拆分现有的库**：见 [拆分知识库](./wiki-split.md)，那里有一段**可以直接复制给 Agent 的话**。

细节：

- **每个库有自己的一套设置**：笔记标签、语言、主题、`prompt.*` 都在该库自己的
  `$:/plugins/dsh-tiddlywiki/config` 里。设置页顶部会显示「**配置作用域**：…」，点某个库那一行的
  「配置」即可改它的设置 —— 作用域不说清就会出现"改了但不生效"。**v0.28.8 起按模式分流**：多库时
  「插件管理（自带官方插件）/ 主题管理 / 语言管理 / 初始化」这些**per-库**的面板收进「**本库配置**」
  tab，只有你点了某个库的「配置」之后才出现（此前它们和全局项混在同一页，看着像"所有库共用一个设置"）；
  「总览」tab 只放名册与全局项（端口、git 默认、桥、微信发布…）。单库模式仍是原来的一页。
- **git 按仓库生效**：多个库可以共用**一个**仓库（例如「工作」+「个人」放在 `D:/notes/` 下的两个子
  目录），也可以各自独立仓库。共用仓库时**只有一个自动提交者**（`git add -A` 会作用于整个工作树），
  `git.*` 以该仓库下**列表里第一个库**为准、配置不一致时打印警告；pull 之后**只重启内容真的变了的库**。
- **快速笔记的目标库**：卡片里有一个「写入」下拉，**默认跟随你在 GUI 里看的那个库**（右下角菜单切换焦点库，它就跟着变）；在里面手动选过之后，这张卡片就不再被焦点带走。改目标库是**整张卡片一起换**——标签建议、最近列表、附件上传、保存、以及随后弹出的 TW 编辑器都会落到同一个库。目标库没在运行时卡片会先提示你，而不是等你写完再失败。
- **左侧边栏每个库一行**（v0.28.3 起，点击语义见 v0.28.13）：每个**在运行**的库一个入口行，用自己的显示名与图标（在「知识库列表」里改），**当前面板显示的那个库高亮**。**点另一个库 = 立刻切过去**（面板保持打开，不会先关掉让你再点一次）；点**当前那个库** = 收起面板 —— 入口同时也是开关。没在运行的库不在这一列（它们仍可从右下角「知识库」菜单启动）。
- **切库为什么需要等一下**（v0.28.14）：切换 = 在同一个 iframe 里**换成另一个库的整份 TW 文档**（一个 iframe 只能装一个编辑器）。本机实测这份文档是 **9.9 MB / 29.9 MB / 28 MB**，而且 TW 自己回 `Cache-Control: no-store`、没有 ETag —— **缓存不了也预取不了**，所以每次切换都要真下载解析一遍。这一版做了三件事让它不"看起来卡住"：① 点击**立即**开始换（不再先等一次 `/status`，那次往返在这台机器上要 300–400 ms，因为 host 每次都要跑最多 5 个 git 进程）；② 侧边栏的选中高亮即时跟上，且不再重复请求 `/status`；③ TW 界面底部显示 **`正在载入知识库「个人」…`**，新文档到达即收起（另有 15 秒兜底）。**剩下的等待是 TW 文档大小决定的**，不是可以再优化的延迟。
- **「移出列表」不删目录**：只是让插件不再管理它，内容原样保留。
- **界面语言（v0.30.6）**：设置页的 `uiLanguage`（`zh` 默认 / `en`）现在**同时驱动两半** —— TW 子进程的界面**和插件自己的界面**（右下角「知识库」FAB、侧边栏入口、输入框上方那一行、快速笔记卡片与编辑器弹窗、工具卡片、会话「知识库」Tab、设置页、全部 toast）。改完保存：TW 面板内的界面随子进程重启生效，插件自己的界面**刷新页面**即生效（客户端在 `localStorage` 缓存了语言，刷新后首屏就是对的）。
- **每个库一个图标**（v0.28.8）：知识库列表每行的图标是个**弹出式网格**——里面是 **DSH 官方的 36 个图标**（与侧边栏/工具栏那套同源，深浅主题都对）、本插件自绘的 8 个（书籍 / 公文包 / 首页 / 笔记本 / 烧瓶 / 地球 / 星标 / 归档），外加一组 emoji 快捷选择；图标多了按 **48 个一页**翻页。选中即写入 `wikis.json` 的 `icon` 字段。当前值若不在候选里（比如你手写的短 emoji）会原样保留，不会被候选列表抹掉。**v0.28.8 同时修了一个真 bug**：此前选了图标界面会立刻变回默认 —— `/admin/wikis` 的读取视图漏了 `icon` 字段，于是"写进去了、读回来是 undefined"，看起来就是没生效（现在有守门钉死这个字段，反向验证过）。
- **还没发过消息的新会话也能选库**（v0.28.8，v0.28.11 修）：选择器此前只长在输入框上方；新会话（空白页，输入框还没出现）时它会挂到**预设/模式选择旁边**那一格（`conversation.input.selector.context`）。实现是**声明感知**的：DSH 声明了那一格才注入，**声明不到就一直留在 dock 里那一行**——不会再"2 秒后回落到 dock"另注册一个（那个回落会在新会话里同时出现两个选择器，v0.28.11 已删除）。
- **会话「知识库」Tab 在多库下按会话作用域取数**（v0.28.8）：汇总只统计**该会话作用域那个库**里的笔记；不这样做就会出现"A 库的笔记标题在 B 库里渲染成空白卡片"。
- **桌面版（DSH Desktop）**（v0.28.8）：TW 子进程需要真正的 `node`。以前直接拿 `process.execPath` —— 在桌面版里那是 Electron 可执行文件，TW 根本起不来。现在先按 `DSH_TIDDLYWIKI_NODE` 环境变量、再 `where node` / `which node`、最后才回落 `process.execPath`；解析结果缓存，并在启动日志里写明用了哪个。
- **清单文件**：`$DSH_HOME/dsh-tiddlywiki/wikis.json`（在每本 wiki 之外，所以它不会随某个库被搬走）。
  手写时注意：`id` 只能用小写字母/数字加 `._-`，且不能是 `status`/`files`/`recipes`/`render` 这类与 TW
  根路径撞名的保留字；两个库不能指向同一目录，**也不能互相嵌套**（外层库的 `git add -A` 会把内层内容
  一起提交，插件会直接拒绝这种登记）。

### 📍 知识库位置（可切换，v0.22.0）

设置页顶部「**知识库位置（可切换）**」区块显示当前实际服务的文件夹、这个位置**是怎么决定的**（指针文件 / cordis 配置 / 默认值）、指针文件路径，以及**同目录下其它看起来像 wiki 的文件夹**（含 `tiddlywiki.info`）的快捷填入按钮。

- **换一个位置**：填根目录（绝对路径，支持 `$DSH_HOME` / `${VAR}` / `%VAR%`）+ 文件夹名 → 「切换到这个位置」。host 会停掉 TW → 释放自动提交与监听 → 指向新目录 → 起 TW → 重载新 wiki 的配置 tiddler → 跑核心 seed（markdown 插件 / 发送给 Agent / 渲染路由 / 同源代理 / 语言）→ 重新武装自动提交；**选中即被记住**（写进 `$DSH_HOME/dsh-tiddlywiki/location.json`），重启 dsh web 后仍在新知识库。
- **新建一个知识库**：目标文件夹若还没有 `tiddlywiki.info`，插件会照常自动 `--init server` 建一个全新的（**别填已有的普通笔记目录**——它会被初始化）。
- **恢复为配置默认**：删除指针文件并（必要时）切回 `config.wikiRoot` / `config.wiki`。
- **安全语义**：指针文件在任何 wiki **之外**（若存在 wiki 自己的配置 tiddler 里，切到新 wiki 就会把这个选择一起丢掉——鸡生蛋）；指针文件损坏/非法时**明确报告并回退到配置默认**，不会静默乱跑；切换**失败会回滚**到原来的知识库，并告诉你是「已回滚」还是「回滚也失败了」；同刻只允许一个切换（并发请求直接拒绝）。
- **注意**：切换期间正在跑的 Agent 工具调用会失败（TW 在重启），界面上按钮会禁用并显示「切换中…（重启 TW）」。

`wikiRoot` / `wiki` 现在只是**默认值**——运行中的实际位置以指针文件优先。这也是为什么它能不改 cordis、不重装就切。

### 🧩 初始化（一次性预置 seed）：哪些「必备」，哪些「可有可无」

seed 是把「wiki 里预置内容」随插件分发的机制：**ONE-SHOT（只写缺失）+ 安全跳过（同名 tiddler 已存在绝不覆盖你的数据）**，需要时可「重新初始化」恢复、可「反初始化」移除。详细见 [docs/seed-initialization.md](seed-initialization.md)。

| 层级 | seed | 说明 | 首次安装 |
|---|---|---|---|
| 🔒 **核心**（功能必需，不可移除） | `send-to-agent` | TW 工具栏「发送给 Agent」按钮插件 | 自动写 |
| | `render-route` | 原生渲染路由（回复流卡片 / 链接直达依赖） | 自动写 |
| | `tw-web-host` | TW 前端 API 基址 → 同源代理（内嵌编辑器前提） | 自动写 |
| 📖 **起步**（默认写、可移除，**想要完整体验建档案**） | `doc-note` | 「dsh-tiddlywiki 插件说明」笔记 | 自动写 |
| | `starter-docs` | 「示例与文档」：主题汇总页·模板 + 教程 + 三个示例主题页（日志/决策记录/排障） | 自动写 |
| 🎀 **可选**（默认不写、设置页手动、可移除，**可有可无**） | `home-index` | 首页（四象限待办 + 快速记笔记 + 所有标签/所有文章 + 📚 文档栏）——文档中心的「门面」 | 手动 |
| | `all-articles` | 「所有文章」两列分页总览（🤖 Agent / 👤 人工） | 手动 |
| | `ui-styles` | 自定义样式 5 张（编辑器美化 / 窄屏侧栏 / menubar 加高 / 批注弹窗等） | 手动 |
| | `menubar-theme` | menubar 顶栏跟随 DSH 主题换色 | 手动 |
| | `clip-bridge` | 「本地剪藏桥（书签小工具）」使用说明——含书签代码 / 启用步骤 / 安全说明（真功能在插件运行时代码里，此 seed 只预置文档） | 手动 |

- **想获得完整插件体验**：核心 3 项首次安装就有；再补 `home-index`（首页）+ `starter-docs`（示例文档）即是一个开箱即用的文档中心。
- **一个可选项都不想要**：完全不影响功能——设置页「反初始化」即可，核心项受保护不可移除。
- **文档怎么扩散到更多**：以后插件新增的任何说明 / 教程 / 模板类内容都走 seed 并带 **`dsh-docs`** 标签——首页「📚 插件文档」栏自动收录，你无需任何配置。
- **内置内容更新了怎么办**（v0.22.0）：seed 标记里记着**内容哈希**，设置页据此显示两个提示 chip——「**⬆ 有更新**」（内置内容比你 wiki 里预置的更新，可点「更新到内置版本」取用）与「**✏️ 本地已修改**」（这篇是你的内容，重新初始化会覆盖它，会先二次确认）。升级插件后旧 wiki 的标记没有哈希，会显示「更新检测尚未启用（重新初始化一次即可）」，**不会**把老标记误判成「你改过」；重新初始化一次即升级标记。**绝不自动改写你的 wiki**——更新只在你点的时候发生。

---


插件行默认配置（缺省即默认，无需手动配置）：

```yaml
- id: dsh-tiddlywiki
  config:
    wikiRoot: "$DSH_HOME/tiddlywiki"   # 默认位置；运行中可被设置页「知识库位置」覆盖（指针文件优先，v0.22.0）
    wiki: "main"                       # 文件夹名（"." = 直接用 wikiRoot 这个目录）
    port: 0                            # 0 = 自动探测空闲端口
    git:
      autoCommit: true
      debounceMs: 60000
      remote: ""                       # 空 = 仅本地 commit；填了才 push
      branch: "main"
    note:
      tag: "inbox"                     # 快速笔记默认 tag
      workspaceMark: true              # v0.24.0：新建笔记自动带 ws/<项目名> 标签 + workspace 字段（项目名取自会话工作目录）
    startup:
      readyTimeoutMs: 60000            # TW 启动就绪窗口（v0.22.5，5s–600s；超出只警告并继续等，硬上限 = 3×，仍未就绪才判失败）
    prompt:
      enabled: true                    # false = 本插件不注入任何提示词
      mode: "slim"                     # slim（默认：只留约定）/ full（+ 由工具注册表实时生成的参数索引）
      extra: ""                        # 追加在提示词末尾的自定义规范（团队/个人偏好）
      override: ""                     # 非空时整段取代内置文本（extra 仍会追加）
    bridge:
      enabled: false                   # 本地剪藏桥（书签小工具）；保存后立即生效
      port: 8618                       # 监听端口（127.0.0.1；改后需重启 dsh web 才绑定新端口）
      token: ""                        # 可选加固：非空时校验书签的 x-clip-token 头（默认不设——任意页面可建笔记，系统项拒收）
      tag: "clip"                      # 剪藏笔记默认 tag
      wiki: ""                         # 剪藏写进哪个库（v0.28.8）：空 = 知识库列表里带 ★ 的那个库；多库时可钉死到某个 id
    ui:
      showQuickNote: true              # FAB 里显示快速笔记入口
      showQuickNoteDock: true          # 输入框上方快捷按钮
      quickNoteMode: "native"          # native=TW 原生编辑页 / card=Markdown 卡片
      sidebarLabel: "TiddlyWiki"       # 侧边栏入口显示名（仅单库模式；多库下每库各用自己 wikis.json 的 label）
      showPanelStatus: true
      showSyncButton: true
      followDshTheme: true             # 跟随 DSH 深浅主题
      darkPalette: "$:/palettes/CupertinoDark"
      tabLabel: "知识库"               # 会话 Tab 名
      showSessionTab: true
      showRightbarTab: true            # DSH 右侧边栏提供 TiddlyWiki 入口/Tab
      sendToAgent: { enabled: true }
    uiLanguage: ""                     # 留空不干预；"zh-Hans" 自动启用简体
    auth:
      username: ""                     # 默认 loopback 匿名；暴露到非回环才需要
      password: ""                     # 非空时插件内置客户端/就绪探测/浏览器代理都带 Basic 认证（v0.18.0 起真正可用）
```

> **运行时配置**：设置页写入的 `$:/plugins/dsh-tiddlywiki/config` tiddler 是 `config:` 块之上的覆盖层（tiddler 优先、随 wiki git 同步），改 note tag / git / ui 开关 / **注入提示词（`prompt.*`）** 都无需动 cordis；**提示词改动保存后立即生效**（section 即时重注册，当前会话下一步生效），剪藏桥端口改动仍需重启 dsh web 重新绑定监听；**`startup.readyTimeoutMs` 对下一次 TW 启动/重启生效**（v0.22.5）。
>
> **知识库位置是三层**（v0.22.0）：指针文件 `$DSH_HOME/dsh-tiddlywiki/location.json` > `config:` 块的 `wikiRoot`/`wiki` > 内置默认（`$DSH_HOME/tiddlywiki` + `main`）。`wikiRoot`/`wiki` 因此是「默认位置」而不是「唯一位置」——设置页切过的位置存在指针文件里（一个在 wiki 之外的文件），所以要换回配置值就点「恢复为配置默认」。

---


TW 子进程只监听 **127.0.0.1 回环**；Agent 工具/快速笔记/同步都走 DSH 宿主进程→回环 TW，不受访问入口影响。浏览器里的 TW 编辑器 iframe 经**同源代理** `<DSH origin>/dsh-tiddlywiki/tw/` 访问（v0.6.0 起），所以通过 Tailscale / 内网 / 域名 / HTTPS 访问 DSH 时编辑器照常工作，且 TW 重启不打断编辑中的内容。

---

