dsh-tiddlywiki 0.26.7 → 0.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -2
- package/package.json +7 -2
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
- **TiddlyWiki 天生适合当文档中心**:卡片化组织(标签 / 双向链接 / 一键成文 / 一个文件夹就是整个 wiki)、纯文本 git 仓库天然可迁移可备份。它能是你的**私人笔记本**、**GTD 工具**、**Agent 的记忆库**,甚至让 AI 帮你把电子书导入 TW 来阅读批注——**TW + DSH 能做到的唯一限制,只是人类的想象力**。
|
|
16
16
|
- **人会参与**:完整 TW 5 编辑器内嵌在 DSH 里,随时翻、随时改、随时批注。文档不是 Agent 写给你的黑盒,而是**方便人类参与的文档中心**。
|
|
17
|
-
- **Agent 也能进**:Agent 用
|
|
17
|
+
- **Agent 也能进**:Agent 用 15 个 `tiddlywiki_*` 工具读写;TW 里「发送给 Agent」把笔记一键注入某个会话;每个会话顶部自动汇总它读写过的 wiki 笔记。**切换会话、方案终结、多轮合作,成果最终都回到文档里**——文档成为跨会话、跨 Agent 的公共底座。
|
|
18
18
|
- **AI 填平 TiddlyWiki 的门槛**:TW 功能强大但上手有门槛,这正是 AI 擅长的——让 Agent 按你的习惯定制首页、标签体系、样式与工作流。曾经要折腾 Obsidian / Logseq 插件体系才能搭出来的个人知识库,现在**一句话就能初始化一整套开箱即用的文档中心**。
|
|
19
19
|
|
|
20
20
|
> Obsidian、Logseq 也能做到其中一部分,但**从没有像这样一站式地顺畅**:编辑器、工具、会话、同步、主题全部在同一个界面里闭环。
|
|
@@ -419,6 +419,7 @@ lib/ # 预构建产物(发布含 lib/**,提交入库;
|
|
|
419
419
|
|
|
420
420
|
> 最近几个主要版本的一句话记录(完整变更见 [Releases](https://github.com/bbqisbbq/dsh-tiddlywiki/releases) / git log)。
|
|
421
421
|
|
|
422
|
+
- **v0.27.0**(2026-09-28):**重新定位:从「AI 记忆工具」改写成「你和 Agent 共用的本地文档中心」——纯元数据 + 文档发布,运行时行为零变化。** 触发原因:生态里「记忆 / 知识库」这一格已挤进 30+ 个插件(最大的 `MemOS` 已 11,603★),而本插件真正的差异从来不是「更自动的记忆」,而是**人机共用同一份纯文本文件**:人能读、能改、能审计、能随时带走,Agent 用同一套工具读写它。本次把这件事搬上门口那块招牌:① `package.json` 的 `description` 由英文功能清单改为双语定位,并明确写出**不是自动记忆插件、不做后台抓取**,`keywords` 补 `knowledge-management` / `local-first` / `journal` / `publishing` / `wechat`;② GitHub topics 同步补位,便于目录站归类;③ 修正 README 一处过时数字(「Agent 用 10 个工具」→ 15 个)。**无代码改动**——「装完空手能用」(自动建库 + 起步 seed + 快速开始 7 步)自 v0.22.0 起就已具备,本次只是把它讲清楚。
|
|
422
423
|
- **v0.26.7**(2026-09-26):**修「DSH 桌面版里 TW 面板没有『添加条目』按钮」——嵌入式 TW 被渲染在自定义 scheme 上,于是它根本没有同步器**。现象(用户报障,桌面版):TW 面板能看能搜,但页面控件里 **添加条目 / 添加日志 / 添加图片 / 导入 / 条目管理器** 整排不见,单条笔记的 **编辑 / 克隆 / 删除** 也不见,像装了个只读版 TW。**根因不在本插件,而在 TW 内核的一处协议判定 + 桌面版新增的渲染 scheme**:TiddlyWiki 自己的 TiddlyWeb sync adaptor 只在**文档协议以 `http` 开头**时才导出自己(`plugins/tiddlywiki/tiddlyweb/tiddlywebadaptor.js`:`if($tw.browser && document.location.protocol.substr(0,4) === "http")`);而桌面版用自定义 scheme `dsh-app:` 渲染界面(已在本机运行中的 Electron 渲染进程命令行里核实 `--standard-schemes=dsh-app --secure-schemes=dsh-app …`),于是 iframe 里的 TW **没有 syncadaptor → 没有 `$tw.syncer`**:`$:/status/IsReadOnly` 永远没人写,TW 自己的只读样式表 `$:/plugins/tiddlywiki/tiddlyweb/readonly`(`<$reveal … default="yes">`,**状态未知即当只读**)就把那批按钮 `display:none` 掉;同时 saver 退化成本地 `dirtyTracking`,**在那儿做的编辑根本存不回 wiki**。实测复现(不依赖桌面版):把同一份 wiki 页面用 `file://` 打开(同样非 http),+ 同样消失——所以这不是「按钮坏了」,而是「这个文档里 TW 没有同步器」。**修复思路:让嵌入式 TW 跑在真正的 http origin 上**。① 宿主 `/status` / `/edit` / `/session/summary` 在原有相对字段旁,新增**绝对孪生字段** `twProxyAbsolute` / `twUrlAbsolute`(`absoluteHostBase()`,由请求 `Host` 头推导;脏头一律拒绝 `/^[A-Za-z0-9.\-[\]:]+$/`,避免把路径/凭据拼进回给浏览器的 URL);② 客户端新增 `resolveTwUrl()`(`endpoints.ts`)——**页面本身是 http(s) 时继续走相对路径**(loopback / 局域网 / Tailscale / 域名 / HTTPS 行为一字不变,绝不把 https 页面改源),**只有页面不是 http(s) 时**才改用宿主回环 http 基址,于是桌面版 iframe 里 TW 的协议变成 `http:`,sync adaptor 正常加载、同步器回来、按钮与保存一起复原;③ 随之而来的跨源:桌面版下 TW frame 与宿主页面不同源,`tw-frame.ts` 的 hash 导航把「读跨源 `$tw` 抛 SecurityError」包进 try/catch 并直接走整页兜底(不再冒泡、链接不丢),`theme-sync` 本就是 best-effort 跨源静默。守门:新增 `scripts/verify-tw-origin.mjs`(7 条:Host 头推导 / 脏头拒绝 / http(s) 忽略绝对基址 / `dsh-app:`+`file:` 采用绝对基址 / 老服务端不回归 / 两处接线断言 / 跨源兜底源码断言),`verify-frame-surface` 再增 2 条行为单测(`dsh-app:` 页面必须把 frame 指到宿主 http 基址、且 http 页面仍用同源相对地址;跨源 frame 读 `$tw` 抛错时必须整页兜底)。**注意**:这修的是「TW 被非 http(s) 文档嵌入」;「在浏览器里直连 TW 子端口(`http://127.0.0.1:<port>/`)」是另一回事——那样 TW 的 API 基址会被指到 DSH 代理前缀而 404,同样显示成只读,请一律用 DSH 同源入口(面板 / 右侧栏知识库 tab / `<DSH origin>/dsh-tiddlywiki/tw/`)。
|
|
423
424
|
- **v0.26.6**(2026-09-26):**修 `tiddlywiki_append` 的 `heading` 在 CRLF 笔记上完全失效、且静默回退到文末**(作者本机知识库的一篇 25KB / 454 行长笔记上连续踩两次后定位到源码)。现象:对这篇笔记连做两次带 `heading` 的 append,内容**全部**落到了文末,而回执照样打印「段落「X」」——看起来完全成功。**根因**:`insertIntoSection` 用 `base.split('\n')`,而 CRLF 正文的**每一行结尾都留着 `\r`**;JS 里 `(.*)` **不匹配 `\r`**、`$` 也**不匹配 `\r` 之前的位置**,于是 `/^#{1,6}\s+(.*)$/` 对**每一个**标题都匹配失败 ⇒ `start < 0` ⇒ 走「追加到文末」的回退分支。**只在 CRLF 笔记上复现**(纯 LF 笔记一切正常),所以它看起来像偶发;落盘文件的「**376 个 CRLF + 78 个裸 LF**」混合行尾正是走过该分支的签名(`lines.join('\n')` 保留每行原有 `\r`、只把新块用 `\n` 接上)。**修复三处**:① 标题匹配前**只**剥掉行尾 `\r`(原文行尾一个字节都不动;**没有**改成 `split(/\r?\n/)`——那会让每次 append 都把整篇重写成 LF,炸出全文件 diff);② 新块按**文档自己的行尾**写入(`base.includes('\r\n')` 判定),CRLF 笔记不再越写越乱;③ `insertIntoSection` 改为返回 `{ text, matched }`,`tiddlywiki_append` 把它作为 **`headingMatched`** 一并返回,未命中时回执改为「⚠️ 未找到标题「X」,已改为追加到文末」——**不再把「定位失败」伪装成「写进了那一节」**(Agent 因此完全无法自检,这是本 bug 最坑的一点)。顺带把 `heading` 的真实落点语义写进 schema:实为「该标题之后、**下一个任意级别标题之前**」,标题后紧跟子标题时落在两者之间(=章节开头),并非 schema 原先暗示的「整节末尾」。守门:`verify-tools` +4 条 E2E(CRLF 正文的笔记必须 `headingMatched=true` 且标记落在目标段内、段内不得混入裸 LF;未命中必须 `headingMatched=false` 且回执含「未找到标题」、不得再宣称写进该段落;命中时的反向保护;wikitext `!` 标题同样可定位),**已反向验证**(撤掉 lib 里的行尾 CR 剥离即红 1 条)。
|
|
424
425
|
- **v0.26.5**(2026-09-23):**修 P0:`fields` 参数被按字符拆成几十个垃圾字段**(用户实测复现两次后报障)。现象:`tiddlywiki_put` / `batch_put` / `append` 传 `fields: {"review-after":"2026-12-22"}` 后,条目上出现 `0={`、`1="`、`2=r`… 几十个**单字符字段**,真正的自定义字段**一个都没写进去**;又因为 `fields.type` 是**改内容类型的唯一入口**,这期间也无法把条目写成 wikitext / `text/css`。**根因两层**:① 参数 schema 声明为 `{type:'json'}`,而 DSH 的 schema 里 `type:'json'` 是**纯注解**——编译后连 `type` 都没有(`src/sdk.ts` 的 `compileValue`),模型收不到「这是个对象」的信息,于是把 JSON 当**字符串**发来;② 新建笔记 + 自动工作区标记走 `withWorkspaceMark()` 的 `{ ...(fields ?? {}) }`,而**展开字符串是按字符展开**的(`{...'{"r"'}` → `{0:'{',1:'"',2:'r'…}`),这些索引键随后被当成自定义字段写入;旧 `applyCustomFields()` 对非对象又是**静默 return**,所以全程没有任何报错。**修复(三处)**:① 三个写工具的 `fields` schema 改成真正的 `object` + `additionalProperties: true`(模型能直接看到类型);② 新增 `normalizeFieldsArg()`(`write-policy.ts`)——对象原样返回、`undefined`/`null`/空串视同未给(保留基底)、**JSON 字符串解析成对象**(兼容仍按字符串发参的模型)、数组/数字/解析不出对象的字符串**明确抛错**;`defineTool` 相应新增 `normalizeArgs` 钩子,让归一化跑在 schema 预校验**之前**(放到之后会被「must be an object」先拦掉,兼容层就没机会生效);③ `applyCustomFields()` 遇到非对象**抛错**而不是静默忽略,`withWorkspaceMark()` 只为已归一化的对象做展开。守门:`verify-write-policy` +5 条纯函数(字符串解析 / 对象原样 / 三种坏输入拒绝 / 字符串在 `buildWriteTiddler` 处被拦 / 归一化后无索引键),`verify-tools` +4 条 E2E(三个工具的 schema 必须 `type:object`、按字符串发参仍写对字段且不产生 `0=` 垃圾、坏输入明确报错且不留半成品条目、`append`/`batch_put` 走同一套归一化)。**注意**:本次修复只影响写入端;已被写进条目的垃圾字段需要重建该条目(`fields` 只能覆盖、不能删除单个字段),本机知识库已扫描确认无残留。
|
|
@@ -539,4 +540,4 @@ npm publish # 版本号在 package.json;文件白名单见 files 字段
|
|
|
539
540
|
- **GitHub**:https://github.com/bbqisbbq/dsh-tiddlywiki
|
|
540
541
|
- **npm**:`dsh-tiddlywiki`(https://www.npmjs.com/package/dsh-tiddlywiki)
|
|
541
542
|
- 说明笔记、首页、示例文档、样式等预置内容由 seed 机制写入 wiki(见 [🧩 初始化](#-初始化一次性预置-seed哪些必备哪些可有可无))
|
|
542
|
-
- MIT;Node ≥ 22;GitHub topics:`dsh` `dsh-plugin` `tiddlywiki` `knowledge-base` `note-taking` `git-sync` `agent-tools` 等
|
|
543
|
+
- MIT;Node ≥ 22;GitHub topics:`dsh` `dsh-plugin` `tiddlywiki` `knowledge-base` `knowledge-management` `note-taking` `journal` `git-sync` `local-first` `agent-tools` `publishing` `wechat` 等
|
package/package.json
CHANGED
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-tiddlywiki",
|
|
3
|
-
"description": "TiddlyWiki 5
|
|
4
|
-
"version": "0.
|
|
3
|
+
"description": "把 TiddlyWiki 5 变成你和 Agent 共用的本地文档中心(纯文本 + git):你在 DSH 界面里阅读、写作、记日记,Agent 用 15 个 tiddlywiki_* 工具读写同一批笔记;每条笔记都是你能读、能改、能审计、能随时带走的文件——不是自动记忆插件,不做后台抓取。可选一键发布到微信公众号草稿箱。 Turn TiddlyWiki 5 into a document center you and your agent share, in plain text under git — a knowledge base you can read, edit, audit and take with you, not an auto-memory plugin. Mounts via the official dsh plugin system; no DSH source changes.",
|
|
4
|
+
"version": "0.27.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"dsh",
|
|
8
8
|
"dsh-plugin",
|
|
9
9
|
"tiddlywiki",
|
|
10
10
|
"knowledge-base",
|
|
11
|
+
"knowledge-management",
|
|
11
12
|
"note-taking",
|
|
12
13
|
"notes",
|
|
14
|
+
"journal",
|
|
13
15
|
"wiki",
|
|
14
16
|
"git-sync",
|
|
17
|
+
"local-first",
|
|
15
18
|
"agent-tools",
|
|
19
|
+
"publishing",
|
|
20
|
+
"wechat",
|
|
16
21
|
"plugin"
|
|
17
22
|
],
|
|
18
23
|
"author": {
|