dsh-tiddlywiki 0.11.0 → 0.12.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 CHANGED
@@ -23,7 +23,7 @@
23
23
  | 🌗 **跟随 DSH 主题** | 嵌入式 TW(中央面板 +「在 TW 中编辑」弹窗)**自适应 DSH 深浅主题**:暗色自动切深色 palette、浅色恢复原 palette;**纯内存切换,不写回 wiki、不进 git**;设置页可关可换深色 palette |
24
24
  | 📝 **快速笔记** | 右下角「知识库」悬浮按钮 → 快速笔记卡片:**CodeMirror 6** Markdown 编辑器(语法高亮 + 撤销/重做)、文件上传、多选/自动补全 tag、**草稿自动保存(刷新不丢)**、**「🕘 最近」一键载入旧笔记**,Ctrl+Enter 保存;可整体隐藏 |
25
25
  | 🔄 **一键同步** | 「知识库」按钮 →「🔁 同步」:pull → commit → push;FAB 上的状态点实时反映 git 状态(已同步/待提交/可更新/离线) |
26
- | ⚙️ **设置页** | DSH 设置 →「TiddlyWiki 知识库」:插件/主题/语言管理与运行配置,应用后自动重启 TW;**「初始化」区块**列出所有一次性预置项(说明笔记/发送按钮/首页/同源代理基址)的实时状态,可随时手动**重新初始化** |
26
+ | ⚙️ **设置页** | DSH 设置 →「TiddlyWiki 知识库」:插件/主题/语言管理与运行配置,应用后自动重启 TW;**「初始化」区块**列出所有一次性预置项(说明笔记/发送按钮/首页/所有文章/同源代理基址)的实时状态,可随时手动**重新初始化**;**「所有文章」每页条数**可在配置里调整(实时生效,无需重新初始化) |
27
27
  | 🛡 **零摩擦生命周期** | 随 dsh 自动启停;TW 子进程崩溃自动重启(退避);端口/目录/首次 git init 全自动 |
28
28
  | 💾 **数据即备份** | wiki 文件夹本身就是一个 git 仓库;自动 commit(60s 防抖,可关),配置随 dsh-market 迁移 |
29
29
 
@@ -33,6 +33,7 @@
33
33
 
34
34
  > 最近几个主要版本的一句话更新记录(完整变更见 git log / Releases)。
35
35
 
36
+ - **v0.12.0**(2026-09-04):**新默认主页「主页」+ 「所有文章」两列分页页**。把首页拆成三页:**主页**(默认打开,`$:/DefaultTiddlers` 指向它)= 四象限待办 + 「所有标签」「所有文章」入口;**所有标签**瘦身为独立标签统计页(标签 + Agent 区块 + 回主页链接);新增 **所有文章**——全部条目分两列(🤖 Agent 撰写 / 👤 人工·人类,含 `human-edited` 的 Agent 笔记)**各自分页**展示(排除系统页、草稿与 `索引` 导航页),每页条数取配置 `ui.allArticles.pageSize`(默认 10,设置页可调、实时生效)。**所有文章**作为新 seed 进统一注册表(`all-articles`),设置页可单独/全部**重新初始化**。
36
37
  - **v0.11.0**(2026-09-04):TW「**发送给 Agent**」选择器新增**「工作模式」(Agent 预设)**——弹层顶部可选择会话挂载的 Agent 预设(如 默认/cordis/blade,来自 DSH `agentPresets`),**新建工作区/会话并发送**时以所选模式创建(`/agent/create` 新增 `mode` 参数 → `sessionController.create(agentPreset)`);已有会话显示其当前模式(`🧭` 徽标)。新增 `GET /agent/modes` 返回可用模式清单 + 部署默认。对旧宿主**向后兼容**:模式接口缺失时选择器降级为默认模式,功能不受影响。
37
38
  - **v0.10.0**(2026-09-04):**统一 seed 注册表**——把「与 dsh 联动、需要 wiki 预置」的全部一次性项收进 `SEED_DEFS`(说明笔记、发送给 Agent 按钮、**首页「所有标签/标签笔记」**、**TW 前端同源代理基址**),首次启动只写缺失、不覆盖用户内容;设置页新增「**初始化**」区块:列出每项实时状态 + 手动「**重新初始化**」(force 重写内置内容,含缺失项补齐与 TW 前端基址修复)。新装用户开箱即有**首页**(四象限待办 + 标签统计 + Agent 区块),不再手工放 tiddler。配套文档:[🧩 初始化小节](#🧩-初始化一次性预置) + [docs/seed-initialization.md](docs/seed-initialization.md)。
38
39
  - **v0.9.0**(2026-09-04):TW「**发送给 Agent**」按钮随插件**首次启动自动写入 wiki**(ONE-SHOT:只写一次、用户可删可改不复活)——新装用户开箱即用,无需手工往 wiki 塞插件 bundle;消息格式更新:**去掉 `【TiddlyWiki 笔记一键发送】` 前缀**,并**附加待办说明**告知 Agent 这是用户提前编辑在 wiki 中的待办事项、不清楚应主动提问。
@@ -59,7 +60,7 @@ dsh plugin --profile web add github:bbqisbbq/dsh-tiddlywiki
59
60
  dsh plugin --profile web add link:/path/to/your/dsh-tiddlywiki
60
61
  ```
61
62
 
62
- 首次启动会自动完成:**初始化 wiki 目录**、**`git init` 并提交基线**、把「与 dsh 联动、需要 wiki 预置」的一次性项写入 wiki(**统一 seed 注册表**,见「初始化」):向 wiki **写入一次**「dsh-tiddlywiki 插件说明」笔记(tag `docs`)、**写入一次**「发送给 Agent」TW 按钮插件(`$:/plugins/dsh/send-to-agent`)、**写入首页**「所有标签 / 标签笔记」(四象限待办 + 标签统计 + Agent 区块)、把 `$:/config/tiddlyweb/host` 指向同源代理。它们都是 ONE-SHOT:只写缺失、不覆盖你的改动、删掉重启也不会自动恢复——需要时可在设置页「**初始化**」区块手动「重新初始化」(force 重写内置内容)。
63
+ 首次启动会自动完成:**初始化 wiki 目录**、**`git init` 并提交基线**、把「与 dsh 联动、需要 wiki 预置」的一次性项写入 wiki(**统一 seed 注册表**,见「初始化」):向 wiki **写入一次**「dsh-tiddlywiki 插件说明」笔记(tag `docs`)、**写入一次**「发送给 Agent」TW 按钮插件(`$:/plugins/dsh/send-to-agent`)、**写入默认主页**「主页 / 所有标签 / 标签笔记」(四象限待办 + 入口 + 标签统计 + Agent 区块,并把 `$:/DefaultTiddlers` 指向主页)、**写入「所有文章」两列分页页**、把 `$:/config/tiddlyweb/host` 指向同源代理。它们都是 ONE-SHOT:只写缺失、不覆盖你的改动、删掉重启也不会自动恢复——需要时可在设置页「**初始化**」区块手动「重新初始化」(force 重写内置内容)。
63
64
 
64
65
  ---
65
66
 
@@ -148,7 +149,7 @@ dsh plugin --profile web add link:/path/to/your/dsh-tiddlywiki
148
149
  | 插件管理 | 自带官方插件勾选(可搜索)→ 应用并自动重启 TW |
149
150
  | 主题管理 | 自带主题**多选加载 + 单选活动** → 应用并自动重启 TW |
150
151
  | 语言管理 | 自带官方语言包勾选(含 zh-Hans 简体)→ 应用并自动重启 TW |
151
- | **初始化** | 一次性预置项实时状态(说明笔记/发送按钮/首页/同源代理基址)→ 每项「重新初始化」+ 「全部重新初始化」 |
152
+ | **初始化** | 一次性预置项实时状态(说明笔记/发送按钮/首页/所有文章/同源代理基址)→ 每项「重新初始化」+ 「全部重新初始化」 |
152
153
 
153
154
  - 配置写入 wiki 内的 `$:/plugins/dsh-tiddlywiki/config` tiddler(JSON),随 git 同步,作为 **cordis `config:` 块之上的覆盖层**(tiddler 优先)。
154
155
  - git 类配置修改后**重启 dsh web 生效**(bootstrap 时读取)。
@@ -169,13 +170,14 @@ dsh plugin --profile web add link:/path/to/your/dsh-tiddlywiki
169
170
  |---|---|---|---|
170
171
  | `doc-note` | 「dsh-tiddlywiki 插件说明」笔记(tag `docs`) | 新手引导 | marker 门控:只写一次,删掉重启不复活 |
171
172
  | `send-to-agent` | 「发送给 Agent」TW 按钮插件 `$:/plugins/dsh/send-to-agent` | 一键把笔记注入 dsh 会话的入口 | 同上 |
172
- | `home-index` | 首页「所有标签 / 标签笔记」 | **系统提示承诺的首页**:四象限待办 + 标签统计 + **Agent 区块**(纯 Agent / Agent+人工 分区,主标签列表排除 `agent-written`) | 同上 |
173
+ | `home-index` | 默认主页「主页 / 所有标签 / 标签笔记」+ `$:/DefaultTiddlers` → 主页 | **系统提示承诺的首页**:四象限待办 + 「所有标签」「所有文章」入口 + 标签统计 + **Agent 区块**(纯 Agent / Agent+人工 分区,主标签列表排除 `agent-written`) | 同上 |
174
+ | `all-articles` | 「所有文章」——两列(🤖 Agent 撰写 / 👤 人工·人类)各自分页 | 全部条目的分栏总览;每页条数实时读 `ui.allArticles.pageSize`(设置页可调) | 同上 |
173
175
  | `tw-web-host` | `$:/config/tiddlyweb/host` → `/dsh-tiddlywiki/tw/` | 嵌入式 TW 编辑器的同源代理 API 基址(远程访问模式前提) | 非 force = 缺失/旧默认才写、用户自定义保留;force = 强制写回代理基址 |
174
176
 
175
177
  **用法**:
176
178
  - **查看状态**:设置页 →「初始化」→ 每项一个状态点(✓ 已就绪 / ✗ 缺失)+ 说明。
177
179
  - **重新初始化单项**:点该项「重新初始化」——force 重写内置内容(覆盖你对该 tiddler 的改动)并重记 marker,用于「我把首页改坏了想恢复模板」「按钮被我删了想补回」等场景。
178
- - **全部重新初始化**:底部「全部重新初始化」一键重跑全部四项。
180
+ - **全部重新初始化**:底部「全部重新初始化」一键重跑全部五项。
179
181
  - **为什么删掉重启不会自动恢复**:ONE-SHOT marker(`$:/plugins/dsh-tiddlywiki/seed-*`)记录「已提供过」,之后归用户所有——想恢复请手动「重新初始化」,而非依赖重启。
180
182
 
181
183
  详细设计(后台 API、force 语义、如何重新生成内置常量)见 [docs/seed-initialization.md](docs/seed-initialization.md)。
@@ -265,8 +267,8 @@ node scripts/verify-seeds-admin.mjs # 可选:全新 wiki + 真实 HTTP
265
267
  # 改了 wiki 里的 $:/plugins/dsh/send-to-agent bundle 后,重新生成内置常量:
266
268
  node scripts/gen-seed-send-to-agent.mjs '<wiki>/tiddlers/$__plugins_dsh_send-to-agent.json' src/host/seed-send-to-agent.ts && npm run build
267
269
 
268
- # 改了 wiki 首页「所有标签 / 标签笔记」后,重新生成内置 seed 常量:
269
- node scripts/gen-seed-home.mjs '<wiki>/tiddlers/所有标签.tid' '<wiki>/tiddlers/标签笔记.tid' src/host/seed-home.ts && npm run build
270
+ # 改了 wiki 首页「主页 / 所有标签 / 标签笔记」后,重新生成内置 seed 常量:
271
+ node scripts/gen-seed-home.mjs '<wiki>/tiddlers/主页.tid' '<wiki>/tiddlers/所有标签.tid' '<wiki>/tiddlers/标签笔记.tid' src/host/seed-home.ts && npm run build
270
272
  ```
271
273
 
272
274
  **产物约定**(发布必守):`lib/` 内**零** `@deepseek-ai` 运行时 import(`src/sdk.ts` 自实现 `defineTool` / `dshHomePath`,类型用结构接口)。发布前用 `grep -r "@deepseek-ai" lib/` 验证。
@@ -325,8 +327,9 @@ src/
325
327
  │ ├── config.ts # ConfigStore:cordis config 基底 + 配置 tiddler 覆盖层
326
328
  │ ├── seed-notes.ts # seed: 首次一次性写入「插件说明」笔记(支持 force)
327
329
  │ ├── seed-send-to-agent.ts # seed: 首次一次性写入「发送给 Agent」TW 按钮插件(bundle 内嵌常量,支持 force)
328
- │ ├── seed-home.ts # seed: 首页「所有标签/标签笔记」(生成自 wiki .tid,支持 force)
329
- │ ├── seeds.ts # 统一 seed 注册表:doc-note / send-to-agent / home-index / tw-web-host,check + run(force)
330
+ │ ├── seed-home.ts # seed: 默认主页「主页/所有标签/标签笔记」+ $:/DefaultTiddlers(生成自 wiki .tid,支持 force)
331
+ │ ├── seed-all-articles.ts # seed: 「所有文章」两列分页页(支持 force
332
+ │ ├── seeds.ts # 统一 seed 注册表:doc-note / send-to-agent / home-index / all-articles / tw-web-host,check + run(force)
330
333
  │ └── tools.ts # 5 个工具(列表式注册,可扩展)
331
334
  └── client/
332
335
  ├── index.ts # client 入口(纯 DOM + settings.section 注册,永不 throw)
@@ -347,7 +350,7 @@ src/
347
350
 
348
351
  - **GitHub(公开)**:https://github.com/bbqisbbq/dsh-tiddlywiki
349
352
  - **npm**:`dsh-tiddlywiki`(https://www.npmjs.com/package/dsh-tiddlywiki)
350
- - **说明笔记**:插件在**首次启动**时把「与 dsh 联动、需要 wiki 预置」的一次性项写入 wiki(**统一 seed 注册表**,见 [🧩 初始化](#🧩-初始化一次性预置)):`dsh-tiddlywiki 插件说明` 笔记(tag `docs`)、「发送给 Agent」按钮插件(`$:/plugins/dsh/send-to-agent`)、首页「所有标签/标签笔记」、`$:/config/tiddlyweb/host` 同源代理基址——都只写一次、手动编辑不被覆盖、**删除后重启不会自动恢复**(一次性标记;清空 wiki 重装会再写入;设置页「初始化」可手动重新初始化)。
353
+ - **说明笔记**:插件在**首次启动**时把「与 dsh 联动、需要 wiki 预置」的一次性项写入 wiki(**统一 seed 注册表**,见 [🧩 初始化](#🧩-初始化一次性预置)):`dsh-tiddlywiki 插件说明` 笔记(tag `docs`)、「发送给 Agent」按钮插件(`$:/plugins/dsh/send-to-agent`)、默认主页「主页/所有标签/标签笔记」+ `$:/DefaultTiddlers`、「所有文章」两列分页页、`$:/config/tiddlyweb/host` 同源代理基址——都只写一次、手动编辑不被覆盖、**删除后重启不会自动恢复**(一次性标记;清空 wiki 重装会再写入;设置页「初始化」可手动重新初始化)。
351
354
 
352
355
  **可被检索的标准字段**(为 GitHub / npm / 搜索引擎发现):
353
356
 
@@ -1,6 +1,6 @@
1
1
  # 统一 seed 注册表 & 后台「重新初始化」
2
2
 
3
- > 本文档说明 dsh-tiddlywiki **v0.10.0** 引入的「一次性预置」机制:哪些东西需要随插件初始化写入 wiki、它们与 dsh 的联动关系、ONE-SHOT / force 语义、后台 API 与设置页操作,以及开发时如何重新生成内置常量。
3
+ > 本文档说明 dsh-tiddlywiki **v0.12.0** 引入/完善的「一次性预置」机制:哪些东西需要随插件初始化写入 wiki、它们与 dsh 的联动关系、ONE-SHOT / force 语义、后台 API 与设置页操作,以及开发时如何重新生成内置常量。
4
4
 
5
5
  ---
6
6
 
@@ -11,7 +11,8 @@
11
11
  | 联动功能 | 依赖的 wiki 预置 | 缺失时的表现 |
12
12
  |---|---|---|
13
13
  | 一键发送给 Agent | `$:/plugins/dsh/send-to-agent` 按钮插件 | TW 工具栏没有「发送给 Agent」按钮,后端路由在但无入口 |
14
- | 首页(Agent 区块 / 标签统计) | 「所有标签」「标签笔记」两个 tiddler | 系统提示承诺的「首页把 Agent 笔记单独列在 Agent 区块、主标签列表只统计人类笔记」完全不存在 |
14
+ | 首页(待办四象限 / 标签统计 / Agent 区块) | 「主页」「所有标签」「标签笔记」三个 tiddler + `$:/DefaultTiddlers` → 主页 | 系统提示承诺的「首页把 Agent 笔记单独列在 Agent 区块、主标签列表只统计人类笔记」完全不存在;TW 打开的是 GettingStarted |
15
+ | 所有文章(两列分页总览) | 「所有文章」tiddler | 没有一键总览全部条目的入口 |
15
16
  | 嵌入式 TW 编辑器 | `$:/config/tiddlyweb/host` 指向同源代理 | iframe 里的 TW 前端 API 基址指向错误的 origin,编辑/保存失效 |
16
17
  | 新手引导 | 「dsh-tiddlywiki 插件说明」笔记 | 新用户没有入门说明 |
17
18
 
@@ -37,12 +38,13 @@ interface SeedDef {
37
38
  |---|---|---|---|
38
39
  | `doc-note` | `seed-notes.ts` → `seedDocNote` | 「dsh-tiddlywiki 插件说明」(tag `docs`) | `$:/plugins/dsh-tiddlywiki/seed-doc-note` |
39
40
  | `send-to-agent` | `seed-send-to-agent.ts` → `seedSendToAgent` | `$:/plugins/dsh/send-to-agent` 按钮 bundle(`application/json`) | `$:/plugins/dsh-tiddlywiki/seed-send-to-agent` |
40
- | `home-index` | `seed-home.ts` → `seedHomeIndex` | 「所有标签」+「标签笔记」(tag `索引`) | `$:/plugins/dsh-tiddlywiki/seed-home-index` |
41
+ | `home-index` | `seed-home.ts` → `seedHomeIndex` | 「主页」+「所有标签」+「标签笔记」(tag `索引`),并把 `$:/DefaultTiddlers` 指向 `[[主页]]` | `$:/plugins/dsh-tiddlywiki/seed-home-index` |
42
+ | `all-articles` | `seed-all-articles.ts` → `seedAllArticles` | 「所有文章」(tag `索引`)——两列分页总览,每页条数实时读 `ui.allArticles.pageSize`(默认 10) | `$:/plugins/dsh-tiddlywiki/seed-all-articles` |
41
43
  | `tw-web-host` | `seeds.ts` 内联 | `$:/config/tiddlyweb/host` → `/dsh-tiddlywiki/tw/` | 无 marker(ensure 型,见 §4) |
42
44
 
43
45
  ### 统一入口(`src/index.ts` 导出)
44
46
 
45
- - `runAllSeeds(ctx)` —— **启动路径**:四项全部非 force 执行(只写缺失)。启动时序在 `configStore.load()` 之后、`bootstrapGit()` 之前,保证 seed 写入的内容进入首次 git 提交。
47
+ - `runAllSeeds(ctx)` —— **启动路径**:五项全部非 force 执行(只写缺失)。启动时序在 `configStore.load()` 之后、`bootstrapGit()` 之前,保证 seed 写入的内容进入首次 git 提交。
46
48
  - `checkAllSeeds(ctx)` —— 返回每项当前状态数组(设置页「初始化」区块数据源)。
47
49
  - `runSeedById(ctx, id?, force)` —— 单跑(`id` 指定)或全跑(`id` 为 `undefined`);`force` 为手动「重新初始化」;未知 `id` 返回显式错误结果而非抛异常。
48
50
 
@@ -52,7 +54,7 @@ interface SeedDef {
52
54
 
53
55
  **核心原则:seed 只提供一次,之后内容归用户所有。**
54
56
 
55
- - **marker 门控**(doc-note / send-to-agent / home-index):首次执行写入内容 + 写 marker;此后只要 marker 在,seed 就**不再写**(无论目标 tiddler 是否存在)。
57
+ - **marker 门控**(doc-note / send-to-agent / home-index / all-articles):首次执行写入内容 + 写 marker;此后只要 marker 在,seed 就**不再写**(无论目标 tiddler 是否存在)。
56
58
  - **用户删除 tiddler 后,重启不会复活**(marker 仍在)——这是刻意的:用户删掉 = 不想要。
57
59
  - **用户编辑过 tiddler,永远不会被启动 seed 覆盖**(marker 在,seed 根本不触碰)。
58
60
  - **升级兼容**:老 wiki 已有这些 tiddler(旧版本手工放的)时,首次执行只补写 marker、不覆盖现有内容,从这一刻起同样归用户所有。
@@ -71,7 +73,8 @@ interface SeedDef {
71
73
 
72
74
  典型使用场景:
73
75
 
74
- - 「我把首页改坏了,想恢复成模板」→ `home-index` 重新初始化;
76
+ - 「我把首页改坏了,想恢复成模板」→ `home-index` 重新初始化(恢复主页/所有标签/标签笔记 + `$:/DefaultTiddlers` → 主页);
77
+ - 「所有文章页被删了 / 改坏了」→ `all-articles` 重新初始化;
75
78
  - 「发送给 Agent 按钮被我删了 / 改坏了」→ `send-to-agent` 重新初始化;
76
79
  - 「TW 编辑器打不开,疑似 `$:/config/tiddlyweb/host` 被改错」→ `tw-web-host` 重新初始化(force 强制写回代理基址);
77
80
  - 「刚装完发现 wiki 里缺了说明/首页」→ 对应项重新初始化或「全部重新初始化」。
@@ -92,10 +95,11 @@ interface SeedDef {
92
95
  {
93
96
  "ok": true,
94
97
  "items": [
95
- { "id": "doc-note", "title": "插件说明笔记", "description": "…", "present": true, "detail": "已存在" },
96
- { "id": "send-to-agent", "title": "「发送给 Agent」按钮", "description": "…", "present": true, "detail": "已存在" },
97
- { "id": "home-index", "title": "首页(所有标签 / 标签笔记)", "description": "…", "present": false, "detail": "缺失:所有标签" },
98
- { "id": "tw-web-host", "title": "TW 前端 API 基址(同源代理)", "description": "…", "present": true, "detail": "已指向 /dsh-tiddlywiki/tw/" }
98
+ { "id": "doc-note", "title": "插件说明笔记", "description": "…", "present": true, "detail": "已存在" },
99
+ { "id": "send-to-agent", "title": "「发送给 Agent」按钮", "description": "…", "present": true, "detail": "已存在" },
100
+ { "id": "home-index", "title": "首页(主页 / 所有标签 / 标签笔记)", "description": "…", "present": false, "detail": "缺失:主页" },
101
+ { "id": "all-articles", "title": "所有文章(两列分页总览)", "description": "…", "present": true, "detail": "已存在" },
102
+ { "id": "tw-web-host", "title": "TW 前端 API 基址(同源代理)", "description": "…", "present": true, "detail": "已指向 /dsh-tiddlywiki/tw/" }
99
103
  ]
100
104
  }
101
105
  ```
@@ -136,7 +140,7 @@ DSH 设置 →「TiddlyWiki 知识库」→ 最底部「**初始化(一次性
136
140
 
137
141
  - 顶部状态行:`共 N 项,M 项已就绪`;
138
142
  - 每项一行:状态点(✓ 已就绪 / ✗ 缺失)+ 名称 + 实时详情(如缺失了哪个 tiddler)+ 「重新初始化」按钮;
139
- - 底部:「**全部重新初始化**」按钮(force 全部四项)。
143
+ - 底部:「**全部重新初始化**」按钮(force 全部五项)。
140
144
 
141
145
  前端源码:`src/client/settings-page.ts` 的 `renderSeedsSection`;样式 `src/client/styles.ts`(状态点 `ok` / `missing`)。
142
146
 
@@ -150,8 +154,11 @@ DSH 设置 →「TiddlyWiki 知识库」→ 最底部「**初始化(一次性
150
154
  # 改了 wiki 里的「发送给 Agent」按钮 bundle($:/plugins/dsh/send-to-agent):
151
155
  node scripts/gen-seed-send-to-agent.mjs '<wiki>/tiddlers/$__plugins_dsh_send-to-agent.json' src/host/seed-send-to-agent.ts
152
156
 
153
- # 改了 wiki 首页(所有标签 / 标签笔记):
154
- node scripts/gen-seed-home.mjs '<wiki>/tiddlers/所有标签.tid' '<wiki>/tiddlers/标签笔记.tid' src/host/seed-home.ts
157
+ # 改了 wiki 首页(主页 / 所有标签 / 标签笔记):
158
+ node scripts/gen-seed-home.mjs '<wiki>/tiddlers/主页.tid' '<wiki>/tiddlers/所有标签.tid' '<wiki>/tiddlers/标签笔记.tid' src/host/seed-home.ts
159
+
160
+ # 「所有文章」页的内容维护在 src/host/seed-all-articles.ts 的 ALL_ARTICLES_TEXT
161
+ # (来源:<wiki>/tiddlers/所有文章.tid;改 wiki 页后同步手工更新该常量)。
155
162
 
156
163
  # 重新生成后务必:
157
164
  npm run typecheck && npm run build && npm run selftest
@@ -28009,6 +28009,8 @@ function renderConfigSection(body, config, refresh) {
28009
28009
  checkField("ui.showSyncButton", "显示「知识库」按钮里的「同步」入口与 git 状态点", ui.showSyncButton !== false);
28010
28010
  checkField("ui.followDshTheme", "嵌入式 TW 跟随 DSH 深浅主题(暗色时自动切深色 palette,不写回 wiki)", ui.followDshTheme !== false);
28011
28011
  textField("ui.darkPalette", "暗色时 TW palette(tiddler 标题)", typeof ui.darkPalette === "string" && ui.darkPalette.length > 0 ? ui.darkPalette : "$:/palettes/CupertinoDark");
28012
+ const allArticles = ui.allArticles ?? {};
28013
+ numField("ui.allArticles.pageSize", "「所有文章」每页条数", typeof allArticles.pageSize === "number" ? allArticles.pageSize : 10);
28012
28014
  const save = make("button", "dsh-tw-settings-btn dsh-tw-settings-primary", "保存配置");
28013
28015
  save.type = "button";
28014
28016
  save.addEventListener("click", () => {
@@ -28018,14 +28020,16 @@ function renderConfigSection(body, config, refresh) {
28018
28020
  for (const field of fields) {
28019
28021
  if (!field.changed()) continue;
28020
28022
  const parts = field.key.split(".");
28021
- if (parts.length === 1) {
28022
- const key = parts[0];
28023
- if (key !== void 0) patch[key] = field.read();
28024
- } else {
28025
- const [top, rest] = parts;
28026
- const obj = patch[top] ?? {};
28027
- obj[rest] = field.read();
28028
- patch[top] = obj;
28023
+ let node = patch;
28024
+ for (let i = 0; i < parts.length; i++) {
28025
+ const part = parts[i];
28026
+ if (part === void 0) break;
28027
+ if (i === parts.length - 1) node[part] = field.read();
28028
+ else {
28029
+ const child = node[part] ?? {};
28030
+ node[part] = child;
28031
+ node = child;
28032
+ }
28029
28033
  }
28030
28034
  }
28031
28035
  try {
package/lib/client.js CHANGED
@@ -28015,6 +28015,8 @@ function renderConfigSection(body, config, refresh) {
28015
28015
  checkField("ui.showSyncButton", "显示「知识库」按钮里的「同步」入口与 git 状态点", ui.showSyncButton !== false);
28016
28016
  checkField("ui.followDshTheme", "嵌入式 TW 跟随 DSH 深浅主题(暗色时自动切深色 palette,不写回 wiki)", ui.followDshTheme !== false);
28017
28017
  textField("ui.darkPalette", "暗色时 TW palette(tiddler 标题)", typeof ui.darkPalette === "string" && ui.darkPalette.length > 0 ? ui.darkPalette : "$:/palettes/CupertinoDark");
28018
+ const allArticles = ui.allArticles ?? {};
28019
+ numField("ui.allArticles.pageSize", "「所有文章」每页条数", typeof allArticles.pageSize === "number" ? allArticles.pageSize : 10);
28018
28020
  const save = make("button", "dsh-tw-settings-btn dsh-tw-settings-primary", "保存配置");
28019
28021
  save.type = "button";
28020
28022
  save.addEventListener("click", () => {
@@ -28024,14 +28026,16 @@ function renderConfigSection(body, config, refresh) {
28024
28026
  for (const field of fields) {
28025
28027
  if (!field.changed()) continue;
28026
28028
  const parts = field.key.split(".");
28027
- if (parts.length === 1) {
28028
- const key = parts[0];
28029
- if (key !== void 0) patch[key] = field.read();
28030
- } else {
28031
- const [top, rest] = parts;
28032
- const obj = patch[top] ?? {};
28033
- obj[rest] = field.read();
28034
- patch[top] = obj;
28029
+ let node = patch;
28030
+ for (let i = 0; i < parts.length; i++) {
28031
+ const part = parts[i];
28032
+ if (part === void 0) break;
28033
+ if (i === parts.length - 1) node[part] = field.read();
28034
+ else {
28035
+ const child = node[part] ?? {};
28036
+ node[part] = child;
28037
+ node = child;
28038
+ }
28035
28039
  }
28036
28040
  }
28037
28041
  try {
package/lib/index.js CHANGED
@@ -2233,23 +2233,35 @@ async function seedSendToAgent(client, opts) {
2233
2233
  //#region src/host/seed-home.ts
2234
2234
  /** One-time marker: presence means "the home was offered once — hands off". */
2235
2235
  const HOME_INDEX_MARKER_TITLE = "$:/plugins/dsh-tiddlywiki/seed-home-index";
2236
+ /** The $:/DefaultTiddlers body so 主页 opens by default in fresh wikis. */
2237
+ const HOME_DEFAULT_TIDDLERS = "[[主页]]";
2236
2238
  /** The home tiddlers, exactly as seeded (user-owned afterwards). */
2237
- const HOME_INDEX_ITEMS = [{
2238
- "title": "所有标签",
2239
- "tags": ["索引"],
2240
- "type": "text/vnd.tiddlywiki",
2241
- "text": "\\whitespace trim\n\n\\define tag-count() [all[tiddlers]!is[system]!tag[agent-written]tag<currentTiddler>count[]]\n\\define tag-list() [all[tiddlers]!is[system]!tag[agent-written]tags[]!prefix[$:/tags/]!match[索引]]\n\n\\define agent-notes-pure() [all[tiddlers]!is[system]tag[agent-written]!tag[human-edited]count[]]\n\\define agent-notes-mixed() [all[tiddlers]!is[system]tag[agent-written]tag[human-edited]count[]]\n\\define agent-tags-pure() [all[tiddlers]!is[system]tag[agent-written]!tag[human-edited]tags[]!prefix[$:/tags/]!match[索引]!match[agent-written]!match[human-edited]]\n\\define agent-tags-mixed() [all[tiddlers]!is[system]tag[agent-written]tag[human-edited]tags[]!prefix[$:/tags/]!match[索引]!match[agent-written]!match[human-edited]]\n\\define agent-count-pure() [all[tiddlers]!is[system]tag[agent-written]!tag[human-edited]tag<currentTiddler>count[]]\n\\define agent-count-mixed() [all[tiddlers]!is[system]tag[agent-written]tag[human-edited]tag<currentTiddler>count[]]\n\n\\define quadrant-board()\n<div style=\"display:grid; grid-template-columns:1fr 1fr; gap:10px; margin-top:8px;\">\n<div style=\"border:1px solid rgba(128,128,128,0.22); border-radius:10px; padding:8px 12px; background:linear-gradient(135deg,#e74c3c1a,transparent);\">\n<div style=\"font-weight:700; margin-bottom:6px;\">🔴 重要 · 紧急 <span style=\"color:#888; font-weight:400; font-size:0.82em;\">{{{[tag[todo]!tag[done]field:q[q1]count[]]}}} 件</span></div>\n<$list filter=\"[tag[todo]!tag[done]field:q[q1]sort[modified]]\">\n<div style=\"display:flex; gap:6px; align-items:baseline; padding:3px 0; border-bottom:1px dashed rgba(128,128,128,0.15);\">\n<$checkbox tiddler=<<currentTiddler>> tag=\"done\"/>\n<$link to=<<currentTiddler>> style=\"flex:1;\"><$view field=\"title\"/></$link>\n<$list filter=\"[<currentTiddler>get[due]compare:date:lt<today>]\"><span style=\"color:#c0392b; font-size:0.78em;\">逾期</span></$list>\n<$list filter=\"[<currentTiddler>get[due]!is[blank]]\"><span style=\"color:#888; font-size:0.8em;\"><$view field=\"due\" format=\"date\" template=\"MM-DD\"/></span></$list>\n</div>\n</$list>\n<$list filter=\"[tag[todo]!tag[done]field:q[q1]!count[]]\"><div style=\"color:#aaa; font-size:0.85em;\">(暂无)</div></$list>\n</div>\n<div style=\"border:1px solid rgba(128,128,128,0.22); border-radius:10px; padding:8px 12px; background:linear-gradient(135deg,#3498db1a,transparent);\">\n<div style=\"font-weight:700; margin-bottom:6px;\">🔵 重要 · 不紧急 <span style=\"color:#888; font-weight:400; font-size:0.82em;\">{{{[tag[todo]!tag[done]field:q[q2]count[]]}}} 件</span></div>\n<$list filter=\"[tag[todo]!tag[done]field:q[q2]sort[modified]]\">\n<div style=\"display:flex; gap:6px; align-items:baseline; padding:3px 0; border-bottom:1px dashed rgba(128,128,128,0.15);\">\n<$checkbox tiddler=<<currentTiddler>> tag=\"done\"/>\n<$link to=<<currentTiddler>> style=\"flex:1;\"><$view field=\"title\"/></$link>\n<$list filter=\"[<currentTiddler>get[due]compare:date:lt<today>]\"><span style=\"color:#c0392b; font-size:0.78em;\">逾期</span></$list>\n<$list filter=\"[<currentTiddler>get[due]!is[blank]]\"><span style=\"color:#888; font-size:0.8em;\"><$view field=\"due\" format=\"date\" template=\"MM-DD\"/></span></$list>\n</div>\n</$list>\n<$list filter=\"[tag[todo]!tag[done]field:q[q2]!count[]]\"><div style=\"color:#aaa; font-size:0.85em;\">(暂无)</div></$list>\n</div>\n<div style=\"border:1px solid rgba(128,128,128,0.22); border-radius:10px; padding:8px 12px; background:linear-gradient(135deg,#f39c121a,transparent);\">\n<div style=\"font-weight:700; margin-bottom:6px;\">🟠 紧急 · 不重要 <span style=\"color:#888; font-weight:400; font-size:0.82em;\">{{{[tag[todo]!tag[done]field:q[q3]count[]]}}} 件</span></div>\n<$list filter=\"[tag[todo]!tag[done]field:q[q3]sort[modified]]\">\n<div style=\"display:flex; gap:6px; align-items:baseline; padding:3px 0; border-bottom:1px dashed rgba(128,128,128,0.15);\">\n<$checkbox tiddler=<<currentTiddler>> tag=\"done\"/>\n<$link to=<<currentTiddler>> style=\"flex:1;\"><$view field=\"title\"/></$link>\n<$list filter=\"[<currentTiddler>get[due]compare:date:lt<today>]\"><span style=\"color:#c0392b; font-size:0.78em;\">逾期</span></$list>\n<$list filter=\"[<currentTiddler>get[due]!is[blank]]\"><span style=\"color:#888; font-size:0.8em;\"><$view field=\"due\" format=\"date\" template=\"MM-DD\"/></span></$list>\n</div>\n</$list>\n<$list filter=\"[tag[todo]!tag[done]field:q[q3]!count[]]\"><div style=\"color:#aaa; font-size:0.85em;\">(暂无)</div></$list>\n</div>\n<div style=\"border:1px solid rgba(128,128,128,0.22); border-radius:10px; padding:8px 12px; background:linear-gradient(135deg,#95a5a61a,transparent);\">\n<div style=\"font-weight:700; margin-bottom:6px;\">⚪ 不重要 · 不紧急 <span style=\"color:#888; font-weight:400; font-size:0.82em;\">{{{[tag[todo]!tag[done]field:q[q4]count[]]}}} 件</span></div>\n<$list filter=\"[tag[todo]!tag[done]field:q[q4]sort[modified]]\">\n<div style=\"display:flex; gap:6px; align-items:baseline; padding:3px 0; border-bottom:1px dashed rgba(128,128,128,0.15);\">\n<$checkbox tiddler=<<currentTiddler>> tag=\"done\"/>\n<$link to=<<currentTiddler>> style=\"flex:1;\"><$view field=\"title\"/></$link>\n<$list filter=\"[<currentTiddler>get[due]compare:date:lt<today>]\"><span style=\"color:#c0392b; font-size:0.78em;\">逾期</span></$list>\n<$list filter=\"[<currentTiddler>get[due]!is[blank]]\"><span style=\"color:#888; font-size:0.8em;\"><$view field=\"due\" format=\"date\" template=\"MM-DD\"/></span></$list>\n</div>\n</$list>\n<$list filter=\"[tag[todo]!tag[done]field:q[q4]!count[]]\"><div style=\"color:#aaa; font-size:0.85em;\">(暂无)</div></$list>\n</div>\n</div>\n\\end\n\n<$set name=\"today\" value=<<now \"YYYY0MM0DD\">>>\n\n!! ✅ 待办 · 四象限\n\n<div class=\"tc-message-box\">输入一行要事、选好象限,点「➕ 添加」即建任务(默认 Q2 重要·不紧急)。你输入的这句话会直接成为任务标题,首页一目了然。点任务左侧方框即完成(自动加 <code>done</code> 标签并从看板消失)。给任意笔记打上 <code>todo</code> 标签也会被收集到下方「未分类」,补填 <code>q</code> 字段即进入象限。</div>\n\n<div style=\"display:flex; gap:6px; flex-wrap:wrap; align-items:center; margin:10px 0;\">\n<$edit-text tiddler=\"$:/state/todo/title\" tag=\"input\" placeholder=\"快速添加:写一句要做的事,选象限后点 ➕…\" style=\"flex:1; min-width:220px; padding:6px 10px; border-radius:6px; border:1px solid rgba(128,128,128,0.3);\"/>\n<$select tiddler=\"$:/state/todo/quadrant\" default=\"q2\" style=\"padding:6px 10px; border-radius:6px; border:1px solid rgba(128,128,128,0.3);\">\n<option value=\"q1\">Q1 重要·紧急</option>\n<option value=\"q2\">Q2 重要·不紧急</option>\n<option value=\"q3\">Q3 紧急·不重要</option>\n<option value=\"q4\">Q4 不重要·不紧急</option>\n</$select>\n<$button class=\"tc-btn-invisible\" style=\"padding:6px 14px; border-radius:6px; border:1px solid rgba(128,128,128,0.35); font-weight:600;\">\n<$list filter=\"[{$:/state/todo/title}!is[blank]]\">\n<$action-createtiddler $basetitle={{{[{$:/state/todo/title}]}}} tags=\"todo\" text={{{[{$:/state/todo/title}]}}} q={{{[{$:/state/todo/quadrant}!is[blank]else[q2]]}}}/>\n<$action-setfield $tiddler=\"$:/state/todo/title\" text=\"\"/>\n</$list>\n➕ 添加\n</$button>\n</div>\n\n<div style=\"margin:6px 0; color:#555;\">📅 今日到期 <b>{{{[tag[todo]!tag[done]field:due<today>count[]]}}}</b> 件 · ⏰ 已逾期 <b>{{{[tag[todo]!tag[done]get[due]compare:date:lt<today>count[]]}}}</b> 件</div>\n\n<<quadrant-board>>\n\n<$list filter=\"[tag[todo]!tag[done]!has[q]count[]!match[0]]\">\n<div style=\"margin-top:10px; border:1px dashed rgba(128,128,128,0.35); border-radius:10px; padding:8px 12px;\">\n<div style=\"font-weight:700; margin-bottom:6px;\">📥 未分类 <span style=\"color:#888; font-weight:400; font-size:0.82em;\">{{{[tag[todo]!tag[done]!has[q]count[]]}}} 件</span></div>\n<$list filter=\"[tag[todo]!tag[done]!has[q]sort[modified]]\">\n<div style=\"display:flex; gap:6px; align-items:baseline; padding:3px 0; border-bottom:1px dashed rgba(128,128,128,0.15);\">\n<$checkbox tiddler=<<currentTiddler>> tag=\"done\"/>\n<$link to=<<currentTiddler>> style=\"flex:1;\"><$view field=\"title\"/></$link>\n<$list filter=\"[<currentTiddler>get[due]compare:date:lt<today>]\"><span style=\"color:#c0392b; font-size:0.78em;\">逾期</span></$list>\n</div>\n</$list>\n</div>\n</$list>\n\n</$set>\n\n!! 🏷 所有标签\n\n<div class=\"tc-message-box\">按笔记数量从多到少排序,仅统计人类笔记(Agent 撰写的笔记已排除,见下方「🤖 Agent 撰写的标签」)。点击标签,查看包含该标签的所有笔记。</div>\n\n<div style=\"margin-top:12px;\">\n<$list filter=\"[subfilter<tag-list>] +[!sortsub:number<tag-count>]\">\n<$set name=\"count\" value={{{ [subfilter<tag-count>] }}}>\n<div style=\"padding:7px 2px; border-bottom:1px solid rgba(128,128,128,0.15);\">\n<$button set=\"$:/state/tag\" setTo=<<currentTiddler>> class=\"tc-btn-invisible tc-tiddlylink\" style=\"width:100%; text-align:left;\">\n<$action-navigate $to=\"标签笔记\"/>\n<span style=\"font-weight:600; font-size:1.05em;\"><<currentTiddler>></span>\n<span style=\"color:#888; font-size:0.85em; margin-left:8px;\"><<count>> 篇</span>\n</$button>\n</div>\n</$set>\n</$list>\n</div>\n\n!! 🤖 Agent 撰写的标签\n\n<div class=\"tc-message-box\">以下标签来自带有 <code>agent-written</code> 标签(由 Agent 撰写)的笔记,与上方主列表分开统计。若某篇 Agent 笔记又被人类编辑过,请给它补打 <code>human-edited</code> 标签,即归入下方「Agent + 人工」档。</div>\n\n<div style=\"font-weight:700; margin:8px 0 4px;\">🦾 纯 Agent <span style=\"color:#888; font-weight:400; font-size:0.82em;\">{{{[subfilter<agent-notes-pure>]}}} 篇</span></div>\n<div style=\"margin-left:10px;\">\n<$list filter=\"[subfilter<agent-tags-pure>] +[!sortsub:number<agent-count-pure>]\">\n<$set name=\"count\" value={{{ [subfilter<agent-count-pure>] }}}>\n<div style=\"padding:7px 2px; border-bottom:1px solid rgba(128,128,128,0.15);\">\n<$button set=\"$:/state/tag\" setTo=<<currentTiddler>> class=\"tc-btn-invisible tc-tiddlylink\" style=\"width:100%; text-align:left;\">\n<$action-navigate $to=\"标签笔记\"/>\n<span style=\"font-weight:600; font-size:1.05em;\"><<currentTiddler>></span>\n<span style=\"color:#888; font-size:0.85em; margin-left:8px;\"><<count>> 篇</span>\n</$button>\n</div>\n</$set>\n</$list>\n<$list filter=\"[subfilter<agent-tags-pure>!count[]]\"><div style=\"color:#aaa; font-size:0.85em;\">(暂无纯 Agent 笔记)</div></$list>\n</div>\n\n<div style=\"font-weight:700; margin:10px 0 4px;\">🤝 Agent + 人工 <span style=\"color:#888; font-weight:400; font-size:0.82em;\">{{{[subfilter<agent-notes-mixed>]}}} 篇</span></div>\n<div style=\"margin-left:10px;\">\n<$list filter=\"[subfilter<agent-tags-mixed>] +[!sortsub:number<agent-count-mixed>]\">\n<$set name=\"count\" value={{{ [subfilter<agent-count-mixed>] }}}>\n<div style=\"padding:7px 2px; border-bottom:1px solid rgba(128,128,128,0.15);\">\n<$button set=\"$:/state/tag\" setTo=<<currentTiddler>> class=\"tc-btn-invisible tc-tiddlylink\" style=\"width:100%; text-align:left;\">\n<$action-navigate $to=\"标签笔记\"/>\n<span style=\"font-weight:600; font-size:1.05em;\"><<currentTiddler>></span>\n<span style=\"color:#888; font-size:0.85em; margin-left:8px;\"><<count>> 篇</span>\n</$button>\n</div>\n</$set>\n</$list>\n<$list filter=\"[subfilter<agent-tags-mixed>!count[]]\"><div style=\"color:#aaa; font-size:0.85em;\">(暂无「Agent + 人工」笔记)</div></$list>\n</div>"
2242
- }, {
2243
- "title": "标签笔记",
2244
- "tags": ["索引"],
2245
- "type": "text/vnd.tiddlywiki",
2246
- "text": "\\whitespace trim\n\n<$set name=\"sel\" value={{{ [{$:/state/tag}] }}}>\n\n!! 标签:<<sel>>\n\n<div class=\"tc-message-box\">包含标签 <strong><<sel>></strong> 的所有笔记(自动收集,按最近修改排序)。</div>\n\n<ul>\n<$list filter=\"[all[tiddlers]!is[system]!has[draft.of]tag<sel>] +[!sort[modified]]\">\n<li><$link to=<<currentTiddler>>><$view field=\"title\"/></$link><span style=\"color:#aaa; font-size:0.85em;\"> · <$view field=\"modified\" format=\"relativedate\"/></span></li>\n</$list>\n</ul>\n\n</$set>\n"
2247
- }];
2239
+ const HOME_INDEX_ITEMS = [
2240
+ {
2241
+ "title": "主页",
2242
+ "tags": ["索引"],
2243
+ "type": "text/vnd.tiddlywiki",
2244
+ "text": "\\whitespace trim\n\n\\define quadrant-board()\n<div style=\"display:grid; grid-template-columns:1fr 1fr; gap:10px; margin-top:8px;\">\n<div style=\"border:1px solid rgba(128,128,128,0.22); border-radius:10px; padding:8px 12px; background:linear-gradient(135deg,#e74c3c1a,transparent);\">\n<div style=\"font-weight:700; margin-bottom:6px;\">🔴 重要 · 紧急 <span style=\"color:#888; font-weight:400; font-size:0.82em;\">{{{[tag[todo]!tag[done]field:q[q1]count[]]}}} 件</span></div>\n<$list filter=\"[tag[todo]!tag[done]field:q[q1]sort[modified]]\">\n<div style=\"display:flex; gap:6px; align-items:baseline; padding:3px 0; border-bottom:1px dashed rgba(128,128,128,0.15);\">\n<$checkbox tiddler=<<currentTiddler>> tag=\"done\"/>\n<$link to=<<currentTiddler>> style=\"flex:1;\"><$view field=\"title\"/></$link>\n<$list filter=\"[<currentTiddler>get[due]compare:date:lt<today>]\"><span style=\"color:#c0392b; font-size:0.78em;\">逾期</span></$list>\n<$list filter=\"[<currentTiddler>get[due]!is[blank]]\"><span style=\"color:#888; font-size:0.8em;\"><$view field=\"due\" format=\"date\" template=\"MM-DD\"/></span></$list>\n</div>\n</$list>\n<$list filter=\"[tag[todo]!tag[done]field:q[q1]!count[]]\"><div style=\"color:#aaa; font-size:0.85em;\">(暂无)</div></$list>\n</div>\n<div style=\"border:1px solid rgba(128,128,128,0.22); border-radius:10px; padding:8px 12px; background:linear-gradient(135deg,#3498db1a,transparent);\">\n<div style=\"font-weight:700; margin-bottom:6px;\">🔵 重要 · 不紧急 <span style=\"color:#888; font-weight:400; font-size:0.82em;\">{{{[tag[todo]!tag[done]field:q[q2]count[]]}}} 件</span></div>\n<$list filter=\"[tag[todo]!tag[done]field:q[q2]sort[modified]]\">\n<div style=\"display:flex; gap:6px; align-items:baseline; padding:3px 0; border-bottom:1px dashed rgba(128,128,128,0.15);\">\n<$checkbox tiddler=<<currentTiddler>> tag=\"done\"/>\n<$link to=<<currentTiddler>> style=\"flex:1;\"><$view field=\"title\"/></$link>\n<$list filter=\"[<currentTiddler>get[due]compare:date:lt<today>]\"><span style=\"color:#c0392b; font-size:0.78em;\">逾期</span></$list>\n<$list filter=\"[<currentTiddler>get[due]!is[blank]]\"><span style=\"color:#888; font-size:0.8em;\"><$view field=\"due\" format=\"date\" template=\"MM-DD\"/></span></$list>\n</div>\n</$list>\n<$list filter=\"[tag[todo]!tag[done]field:q[q2]!count[]]\"><div style=\"color:#aaa; font-size:0.85em;\">(暂无)</div></$list>\n</div>\n<div style=\"border:1px solid rgba(128,128,128,0.22); border-radius:10px; padding:8px 12px; background:linear-gradient(135deg,#f39c121a,transparent);\">\n<div style=\"font-weight:700; margin-bottom:6px;\">🟠 紧急 · 不重要 <span style=\"color:#888; font-weight:400; font-size:0.82em;\">{{{[tag[todo]!tag[done]field:q[q3]count[]]}}} 件</span></div>\n<$list filter=\"[tag[todo]!tag[done]field:q[q3]sort[modified]]\">\n<div style=\"display:flex; gap:6px; align-items:baseline; padding:3px 0; border-bottom:1px dashed rgba(128,128,128,0.15);\">\n<$checkbox tiddler=<<currentTiddler>> tag=\"done\"/>\n<$link to=<<currentTiddler>> style=\"flex:1;\"><$view field=\"title\"/></$link>\n<$list filter=\"[<currentTiddler>get[due]compare:date:lt<today>]\"><span style=\"color:#c0392b; font-size:0.78em;\">逾期</span></$list>\n<$list filter=\"[<currentTiddler>get[due]!is[blank]]\"><span style=\"color:#888; font-size:0.8em;\"><$view field=\"due\" format=\"date\" template=\"MM-DD\"/></span></$list>\n</div>\n</$list>\n<$list filter=\"[tag[todo]!tag[done]field:q[q3]!count[]]\"><div style=\"color:#aaa; font-size:0.85em;\">(暂无)</div></$list>\n</div>\n<div style=\"border:1px solid rgba(128,128,128,0.22); border-radius:10px; padding:8px 12px; background:linear-gradient(135deg,#95a5a61a,transparent);\">\n<div style=\"font-weight:700; margin-bottom:6px;\">⚪ 不重要 · 不紧急 <span style=\"color:#888; font-weight:400; font-size:0.82em;\">{{{[tag[todo]!tag[done]field:q[q4]count[]]}}} 件</span></div>\n<$list filter=\"[tag[todo]!tag[done]field:q[q4]sort[modified]]\">\n<div style=\"display:flex; gap:6px; align-items:baseline; padding:3px 0; border-bottom:1px dashed rgba(128,128,128,0.15);\">\n<$checkbox tiddler=<<currentTiddler>> tag=\"done\"/>\n<$link to=<<currentTiddler>> style=\"flex:1;\"><$view field=\"title\"/></$link>\n<$list filter=\"[<currentTiddler>get[due]compare:date:lt<today>]\"><span style=\"color:#c0392b; font-size:0.78em;\">逾期</span></$list>\n<$list filter=\"[<currentTiddler>get[due]!is[blank]]\"><span style=\"color:#888; font-size:0.8em;\"><$view field=\"due\" format=\"date\" template=\"MM-DD\"/></span></$list>\n</div>\n</$list>\n<$list filter=\"[tag[todo]!tag[done]field:q[q4]!count[]]\"><div style=\"color:#aaa; font-size:0.85em;\">(暂无)</div></$list>\n</div>\n</div>\n\\end\n\n<$set name=\"today\" value=<<now \"YYYY0MM0DD\">>>\n\n!! 🏠 主页\n\n<div class=\"tc-message-box\">你的待办看板(四象限)与知识库入口。快速添加一行要事、选象限即建任务;点左侧方框即完成。下方入口直达所有标签统计与所有文章列表。</div>\n\n<div style=\"display:flex; gap:8px; flex-wrap:wrap; margin:8px 0;\">\n<$button class=\"tc-btn-invisible tc-tiddlylink\" style=\"padding:6px 16px; border:1px solid rgba(128,128,128,0.35); border-radius:8px; font-weight:600;\">\n<$action-navigate $to=\"所有标签\"/>\n🏷 所有标签\n</$button>\n<$button class=\"tc-btn-invisible tc-tiddlylink\" style=\"padding:6px 16px; border:1px solid rgba(128,128,128,0.35); border-radius:8px; font-weight:600;\">\n<$action-navigate $to=\"所有文章\"/>\n📚 所有文章\n</$button>\n</div>\n\n!! ✅ 待办 · 四象限\n\n<div class=\"tc-message-box\">输入一行要事、选好象限,点「➕ 添加」即建任务(默认 Q2 重要·不紧急)。你输入的这句话会直接成为任务标题,首页一目了然。点任务左侧方框即完成(自动加 <code>done</code> 标签并从看板消失)。给任意笔记打上 <code>todo</code> 标签也会被收集到下方「未分类」,补填 <code>q</code> 字段即进入象限。</div>\n\n<div style=\"display:flex; gap:6px; flex-wrap:wrap; align-items:center; margin:10px 0;\">\n<$edit-text tiddler=\"$:/state/todo/title\" tag=\"input\" placeholder=\"快速添加:写一句要做的事,选象限后点 ➕…\" style=\"flex:1; min-width:220px; padding:6px 10px; border-radius:6px; border:1px solid rgba(128,128,128,0.3);\"/>\n<$select tiddler=\"$:/state/todo/quadrant\" default=\"q2\" style=\"padding:6px 10px; border-radius:6px; border:1px solid rgba(128,128,128,0.3);\">\n<option value=\"q1\">Q1 重要·紧急</option>\n<option value=\"q2\">Q2 重要·不紧急</option>\n<option value=\"q3\">Q3 紧急·不重要</option>\n<option value=\"q4\">Q4 不重要·不紧急</option>\n</$select>\n<$button class=\"tc-btn-invisible\" style=\"padding:6px 14px; border-radius:6px; border:1px solid rgba(128,128,128,0.35); font-weight:600;\">\n<$list filter=\"[{$:/state/todo/title}!is[blank]]\">\n<$action-createtiddler $basetitle={{{[{$:/state/todo/title}]}}} tags=\"todo\" text={{{[{$:/state/todo/title}]}}} q={{{[{$:/state/todo/quadrant}!is[blank]else[q2]]}}}/>\n<$action-setfield $tiddler=\"$:/state/todo/title\" text=\"\"/>\n</$list>\n➕ 添加\n</$button>\n</div>\n\n<div style=\"margin:6px 0; color:#555;\">📅 今日到期 <b>{{{[tag[todo]!tag[done]field:due<today>count[]]}}}</b> 件 · ⏰ 已逾期 <b>{{{[tag[todo]!tag[done]get[due]compare:date:lt<today>count[]]}}}</b> 件</div>\n\n<<quadrant-board>>\n\n<$list filter=\"[tag[todo]!tag[done]!has[q]count[]!match[0]]\">\n<div style=\"margin-top:10px; border:1px dashed rgba(128,128,128,0.35); border-radius:10px; padding:8px 12px;\">\n<div style=\"font-weight:700; margin-bottom:6px;\">📥 未分类 <span style=\"color:#888; font-weight:400; font-size:0.82em;\">{{{[tag[todo]!tag[done]!has[q]count[]]}}} 件</span></div>\n<$list filter=\"[tag[todo]!tag[done]!has[q]sort[modified]]\">\n<div style=\"display:flex; gap:6px; align-items:baseline; padding:3px 0; border-bottom:1px dashed rgba(128,128,128,0.15);\">\n<$checkbox tiddler=<<currentTiddler>> tag=\"done\"/>\n<$link to=<<currentTiddler>> style=\"flex:1;\"><$view field=\"title\"/></$link>\n<$list filter=\"[<currentTiddler>get[due]compare:date:lt<today>]\"><span style=\"color:#c0392b; font-size:0.78em;\">逾期</span></$list>\n</div>\n</$list>\n</div>\n</$list>\n\n</$set>\n"
2245
+ },
2246
+ {
2247
+ "title": "所有标签",
2248
+ "tags": ["索引"],
2249
+ "type": "text/vnd.tiddlywiki",
2250
+ "text": "\\whitespace trim\n\n\\define tag-count() [all[tiddlers]!is[system]!tag[agent-written]tag<currentTiddler>count[]]\n\\define tag-list() [all[tiddlers]!is[system]!tag[agent-written]tags[]!prefix[$:/tags/]!match[索引]]\n\n\\define agent-notes-pure() [all[tiddlers]!is[system]tag[agent-written]!tag[human-edited]count[]]\n\\define agent-notes-mixed() [all[tiddlers]!is[system]tag[agent-written]tag[human-edited]count[]]\n\\define agent-tags-pure() [all[tiddlers]!is[system]tag[agent-written]!tag[human-edited]tags[]!prefix[$:/tags/]!match[索引]!match[agent-written]!match[human-edited]]\n\\define agent-tags-mixed() [all[tiddlers]!is[system]tag[agent-written]tag[human-edited]tags[]!prefix[$:/tags/]!match[索引]!match[agent-written]!match[human-edited]]\n\\define agent-count-pure() [all[tiddlers]!is[system]tag[agent-written]!tag[human-edited]tag<currentTiddler>count[]]\n\\define agent-count-mixed() [all[tiddlers]!is[system]tag[agent-written]tag[human-edited]tag<currentTiddler>count[]]\n\n<$button class=\"tc-btn-invisible tc-tiddlylink\" style=\"margin:6px 0; padding:4px 10px; border:1px solid rgba(128,128,128,0.3); border-radius:6px; font-size:0.9em;\">\n<$action-navigate $to=\"主页\"/>\n← 回主页\n</$button>\n\n!! 🏷 所有标签\n\n<div class=\"tc-message-box\">按笔记数量从多到少排序,仅统计人类笔记(Agent 撰写的笔记已排除,见下方「🤖 Agent 撰写的标签」)。点击标签,查看包含该标签的所有笔记。</div>\n\n<div style=\"margin-top:12px;\">\n<$list filter=\"[subfilter<tag-list>] +[!sortsub:number<tag-count>]\">\n<$set name=\"count\" value={{{ [subfilter<tag-count>] }}}>\n<div style=\"padding:7px 2px; border-bottom:1px solid rgba(128,128,128,0.15);\">\n<$button set=\"$:/state/tag\" setTo=<<currentTiddler>> class=\"tc-btn-invisible tc-tiddlylink\" style=\"width:100%; text-align:left;\">\n<$action-navigate $to=\"标签笔记\"/>\n<span style=\"font-weight:600; font-size:1.05em;\"><<currentTiddler>></span>\n<span style=\"color:#888; font-size:0.85em; margin-left:8px;\"><<count>> 篇</span>\n</$button>\n</div>\n</$set>\n</$list>\n</div>\n\n!! 🤖 Agent 撰写的标签\n\n<div class=\"tc-message-box\">以下标签来自带有 <code>agent-written</code> 标签(由 Agent 撰写)的笔记,与上方主列表分开统计。若某篇 Agent 笔记又被人类编辑过,请给它补打 <code>human-edited</code> 标签,即归入下方「Agent + 人工」档。</div>\n\n<div style=\"font-weight:700; margin:8px 0 4px;\">🦾 纯 Agent <span style=\"color:#888; font-weight:400; font-size:0.82em;\">{{{[subfilter<agent-notes-pure>]}}} 篇</span></div>\n<div style=\"margin-left:10px;\">\n<$list filter=\"[subfilter<agent-tags-pure>] +[!sortsub:number<agent-count-pure>]\">\n<$set name=\"count\" value={{{ [subfilter<agent-count-pure>] }}}>\n<div style=\"padding:7px 2px; border-bottom:1px solid rgba(128,128,128,0.15);\">\n<$button set=\"$:/state/tag\" setTo=<<currentTiddler>> class=\"tc-btn-invisible tc-tiddlylink\" style=\"width:100%; text-align:left;\">\n<$action-navigate $to=\"标签笔记\"/>\n<span style=\"font-weight:600; font-size:1.05em;\"><<currentTiddler>></span>\n<span style=\"color:#888; font-size:0.85em; margin-left:8px;\"><<count>> 篇</span>\n</$button>\n</div>\n</$set>\n</$list>\n<$list filter=\"[subfilter<agent-tags-pure>!count[]]\"><div style=\"color:#aaa; font-size:0.85em;\">(暂无纯 Agent 笔记)</div></$list>\n</div>\n\n<div style=\"font-weight:700; margin:10px 0 4px;\">🤝 Agent + 人工 <span style=\"color:#888; font-weight:400; font-size:0.82em;\">{{{[subfilter<agent-notes-mixed>]}}} 篇</span></div>\n<div style=\"margin-left:10px;\">\n<$list filter=\"[subfilter<agent-tags-mixed>] +[!sortsub:number<agent-count-mixed>]\">\n<$set name=\"count\" value={{{ [subfilter<agent-count-mixed>] }}}>\n<div style=\"padding:7px 2px; border-bottom:1px solid rgba(128,128,128,0.15);\">\n<$button set=\"$:/state/tag\" setTo=<<currentTiddler>> class=\"tc-btn-invisible tc-tiddlylink\" style=\"width:100%; text-align:left;\">\n<$action-navigate $to=\"标签笔记\"/>\n<span style=\"font-weight:600; font-size:1.05em;\"><<currentTiddler>></span>\n<span style=\"color:#888; font-size:0.85em; margin-left:8px;\"><<count>> 篇</span>\n</$button>\n</div>\n</$set>\n</$list>\n<$list filter=\"[subfilter<agent-tags-mixed>!count[]]\"><div style=\"color:#aaa; font-size:0.85em;\">(暂无「Agent + 人工」笔记)</div></$list>\n</div>\n"
2251
+ },
2252
+ {
2253
+ "title": "标签笔记",
2254
+ "tags": ["索引"],
2255
+ "type": "text/vnd.tiddlywiki",
2256
+ "text": "\\whitespace trim\n\n<$set name=\"sel\" value={{{ [{$:/state/tag}] }}}>\n\n!! 标签:<<sel>>\n\n<div class=\"tc-message-box\">包含标签 <strong><<sel>></strong> 的所有笔记(自动收集,按最近修改排序)。</div>\n\n<ul>\n<$list filter=\"[all[tiddlers]!is[system]!has[draft.of]tag<sel>] +[!sort[modified]]\">\n<li><$link to=<<currentTiddler>>><$view field=\"title\"/></$link><span style=\"color:#aaa; font-size:0.85em;\"> · <$view field=\"modified\" format=\"relativedate\"/></span></li>\n</$list>\n</ul>\n\n</$set>\n"
2257
+ }
2258
+ ];
2248
2259
  /**
2249
2260
  * Seed the home/index tiddlers exactly once per wiki (mirrors the doc-note
2250
- * one-shot policy). With `force` the tiddlers are overwritten with the built-in
2251
- * content and the marker is (re)written — the settings page uses this for
2252
- * "重新初始化". Returns whether anything was written this call. Never throws.
2261
+ * one-shot policy). Also writes $:/DefaultTiddlers [[主页]] so the new home
2262
+ * opens by default. With `force` the tiddlers are overwritten with the
2263
+ * built-in content and the marker is (re)written the settings page uses this
2264
+ * for "重新初始化". Returns whether anything was written this call. Never throws.
2253
2265
  */
2254
2266
  async function seedHomeIndex(client, opts) {
2255
2267
  const force = opts?.force === true;
@@ -2269,6 +2281,17 @@ async function seedHomeIndex(client, opts) {
2269
2281
  wrote = true;
2270
2282
  }
2271
2283
  }
2284
+ const dt = await client.get("$:/DefaultTiddlers").catch(() => void 0);
2285
+ const dtText = typeof dt?.text === "string" ? dt.text.trim() : "";
2286
+ if (force || dt === void 0 || dtText === "GettingStarted" || dtText === "[[GettingStarted]]") {
2287
+ await client.put({
2288
+ title: "$:/DefaultTiddlers",
2289
+ text: HOME_DEFAULT_TIDDLERS,
2290
+ type: "text/vnd.tiddlywiki",
2291
+ tags: []
2292
+ });
2293
+ wrote = true;
2294
+ }
2272
2295
  await client.put({
2273
2296
  title: HOME_INDEX_MARKER_TITLE,
2274
2297
  text: "seeded-once",
@@ -2278,6 +2301,143 @@ async function seedHomeIndex(client, opts) {
2278
2301
  return wrote;
2279
2302
  }
2280
2303
  //#endregion
2304
+ //#region src/host/seed-all-articles.ts
2305
+ /** One-time marker: presence means "the page was offered once — hands off". */
2306
+ const ALL_ARTICLES_MARKER_TITLE = "$:/plugins/dsh-tiddlywiki/seed-all-articles";
2307
+ /** The 所有文章 page title. */
2308
+ const ALL_ARTICLES_TITLE = "所有文章";
2309
+ /** The page body, exactly as seeded (user-owned afterwards). */
2310
+ const ALL_ARTICLES_TEXT = `\\whitespace trim
2311
+
2312
+ \\define page-size() [{$:/plugins/dsh-tiddlywiki/config}jsonget[ui],[allArticles],[pageSize]else[10]]
2313
+ \\define agent-list() [all[tiddlers]!is[system]!has[draft.of]!tag[索引]tag[agent-written]!tag[human-edited]!sort[modified]]
2314
+ \\define human-list() [all[tiddlers]!is[system]!has[draft.of]!tag[索引]!tag[agent-written]] [all[tiddlers]!is[system]!has[draft.of]!tag[索引]tag[agent-written]tag[human-edited]] +[!sort[modified]]
2315
+
2316
+ <$button class="tc-btn-invisible tc-tiddlylink" style="margin:6px 0; padding:4px 10px; border:1px solid rgba(128,128,128,0.3); border-radius:6px; font-size:0.9em;">
2317
+ <$action-navigate $to="主页"/>
2318
+ ← 回主页
2319
+ </$button>
2320
+
2321
+ !! 📚 所有文章
2322
+
2323
+ <div class="tc-message-box">分两列汇总全部 wiki 条目(不含系统页、草稿与带 <code>索引</code> 标签的导航页):左列 🤖 Agent 撰写(带 <code>agent-written</code> 且未被人工编辑);右列 👤 人工 / 人类(不含 <code>agent-written</code> 的人类笔记 + 被人工编辑过的 <code>human-edited</code> 条目,即使带 <code>agent-written</code>)。两列各自分页,每页条数可在插件设置里调整。</div>
2324
+
2325
+ <div style="display:grid; grid-template-columns:1fr 1fr; gap:12px; margin-top:8px;">
2326
+ <div style="border:1px solid rgba(128,128,128,0.22); border-radius:10px; padding:10px 12px;">
2327
+ <div style="font-weight:700; margin-bottom:6px;">🤖 Agent 撰写 <span style="color:#888; font-weight:400; font-size:0.82em;">{{{[subfilter<agent-list>count[]]}}} 篇</span></div>
2328
+ <$set name="page" tiddler="$:/state/dsh/all-articles/page/agent" emptyValue="0">
2329
+ <$set name="ps" value={{{ [subfilter<page-size>] }}}>
2330
+ <$set name="total" value={{{ [subfilter<agent-list>count[]] }}}>
2331
+ <$set name="last" value={{{ [<total>] +[divide<ps>] +[ceil[0]] +[subtract[1]] +[max[0]] }}}>
2332
+ <$set name="pagec" value={{{ [<page>] +[min<last>] +[max[0]] }}}>
2333
+ <$set name="offset" value={{{ [<pagec>] +[multiply<ps>] }}}>
2334
+ <div>
2335
+ <$list filter="[subfilter<agent-list>] +[rest<offset>] +[first<ps>]">
2336
+ <div style="display:flex; gap:6px; align-items:baseline; padding:3px 0; border-bottom:1px dashed rgba(128,128,128,0.15);">
2337
+ <$link to=<<currentTiddler>> style="flex:1;"><$view field="title"/></$link>
2338
+ <span style="color:#aaa; font-size:0.82em;"><$view field="modified" format="relativedate"/></span>
2339
+ </div>
2340
+ </$list>
2341
+ <$list filter="[subfilter<agent-list>count[]] +[match[0]]"><div style="color:#aaa; font-size:0.85em;">(暂无)</div></$list>
2342
+ </div>
2343
+ <$list filter="[<total>!match[0]]">
2344
+ <div style="display:flex; gap:8px; align-items:center; margin-top:8px;">
2345
+ <$list filter="[<pagec>compare:number:gt[0]]">
2346
+ <$button class="tc-btn-invisible" style="padding:2px 10px; border:1px solid rgba(128,128,128,0.35); border-radius:6px;">
2347
+ <$action-setfield $tiddler="$:/state/dsh/all-articles/page/agent" $field="text" $value={{{ [<pagec>] +[subtract[1]] +[max[0]] }}}/>
2348
+ ◀ 上一页
2349
+ </$button>
2350
+ </$list>
2351
+ <span style="color:#888; font-size:0.85em;">第 {{{ [<pagec>] +[add[1]] }}} / {{{ [<total>] +[divide<ps>] +[ceil[0]] }}} 页</span>
2352
+ <$list filter="[<pagec>compare:number:lt<last>]">
2353
+ <$button class="tc-btn-invisible" style="padding:2px 10px; border:1px solid rgba(128,128,128,0.35); border-radius:6px;">
2354
+ <$action-setfield $tiddler="$:/state/dsh/all-articles/page/agent" $field="text" $value={{{ [<pagec>] +[add[1]] +[min<last>] }}}/>
2355
+ 下一页 ▶
2356
+ </$button>
2357
+ </$list>
2358
+ </div>
2359
+ </$list>
2360
+ </$set>
2361
+ </$set>
2362
+ </$set>
2363
+ </$set>
2364
+ </$set>
2365
+ </$set>
2366
+ </div>
2367
+ <div style="border:1px solid rgba(128,128,128,0.22); border-radius:10px; padding:10px 12px;">
2368
+ <div style="font-weight:700; margin-bottom:6px;">👤 人工 / 人类 <span style="color:#888; font-weight:400; font-size:0.82em;">{{{[subfilter<human-list>count[]]}}} 篇</span></div>
2369
+ <$set name="page" tiddler="$:/state/dsh/all-articles/page/human" emptyValue="0">
2370
+ <$set name="ps" value={{{ [subfilter<page-size>] }}}>
2371
+ <$set name="total" value={{{ [subfilter<human-list>count[]] }}}>
2372
+ <$set name="last" value={{{ [<total>] +[divide<ps>] +[ceil[0]] +[subtract[1]] +[max[0]] }}}>
2373
+ <$set name="pagec" value={{{ [<page>] +[min<last>] +[max[0]] }}}>
2374
+ <$set name="offset" value={{{ [<pagec>] +[multiply<ps>] }}}>
2375
+ <div>
2376
+ <$list filter="[subfilter<human-list>] +[rest<offset>] +[first<ps>]">
2377
+ <div style="display:flex; gap:6px; align-items:baseline; padding:3px 0; border-bottom:1px dashed rgba(128,128,128,0.15);">
2378
+ <$link to=<<currentTiddler>> style="flex:1;"><$view field="title"/></$link>
2379
+ <span style="color:#aaa; font-size:0.82em;"><$view field="modified" format="relativedate"/></span>
2380
+ </div>
2381
+ </$list>
2382
+ <$list filter="[subfilter<human-list>count[]] +[match[0]]"><div style="color:#aaa; font-size:0.85em;">(暂无)</div></$list>
2383
+ </div>
2384
+ <$list filter="[<total>!match[0]]">
2385
+ <div style="display:flex; gap:8px; align-items:center; margin-top:8px;">
2386
+ <$list filter="[<pagec>compare:number:gt[0]]">
2387
+ <$button class="tc-btn-invisible" style="padding:2px 10px; border:1px solid rgba(128,128,128,0.35); border-radius:6px;">
2388
+ <$action-setfield $tiddler="$:/state/dsh/all-articles/page/human" $field="text" $value={{{ [<pagec>] +[subtract[1]] +[max[0]] }}}/>
2389
+ ◀ 上一页
2390
+ </$button>
2391
+ </$list>
2392
+ <span style="color:#888; font-size:0.85em;">第 {{{ [<pagec>] +[add[1]] }}} / {{{ [<total>] +[divide<ps>] +[ceil[0]] }}} 页</span>
2393
+ <$list filter="[<pagec>compare:number:lt<last>]">
2394
+ <$button class="tc-btn-invisible" style="padding:2px 10px; border:1px solid rgba(128,128,128,0.35); border-radius:6px;">
2395
+ <$action-setfield $tiddler="$:/state/dsh/all-articles/page/human" $field="text" $value={{{ [<pagec>] +[add[1]] +[min<last>] }}}/>
2396
+ 下一页 ▶
2397
+ </$button>
2398
+ </$list>
2399
+ </div>
2400
+ </$list>
2401
+ </$set>
2402
+ </$set>
2403
+ </$set>
2404
+ </$set>
2405
+ </$set>
2406
+ </$set>
2407
+ </div>
2408
+ </div>
2409
+ `;
2410
+ /**
2411
+ * Seed the 所有文章 page exactly once per wiki (mirrors the doc-note one-shot
2412
+ * policy). With `opts.force` the page is overwritten with the built-in content
2413
+ * and the marker is (re)written — the settings page uses this for
2414
+ * "重新初始化". Returns whether the page was written this call. Never throws.
2415
+ */
2416
+ async function seedAllArticles(client, opts) {
2417
+ const force = opts?.force === true;
2418
+ if (!force) {
2419
+ if (await client.get("$:/plugins/dsh-tiddlywiki/seed-all-articles").catch(() => void 0) !== void 0) return false;
2420
+ }
2421
+ const existing = await client.get(ALL_ARTICLES_TITLE).catch(() => void 0);
2422
+ let wrote = false;
2423
+ if (force || existing === void 0) {
2424
+ await client.put({
2425
+ title: ALL_ARTICLES_TITLE,
2426
+ text: ALL_ARTICLES_TEXT,
2427
+ type: "text/vnd.tiddlywiki",
2428
+ tags: ["索引"]
2429
+ });
2430
+ wrote = true;
2431
+ }
2432
+ await client.put({
2433
+ title: ALL_ARTICLES_MARKER_TITLE,
2434
+ text: "seeded-once",
2435
+ type: "text/plain",
2436
+ tags: []
2437
+ }).catch(() => void 0);
2438
+ return wrote;
2439
+ }
2440
+ //#endregion
2281
2441
  //#region src/host/seeds.ts
2282
2442
  const presentOf = (ctx, title) => ctx.client.get(title).then((t) => t !== void 0).catch(() => false);
2283
2443
  /** The full registry, in display order. */
@@ -2350,15 +2510,15 @@ const SEED_DEFS = [
2350
2510
  },
2351
2511
  {
2352
2512
  id: "home-index",
2353
- title: "首页(所有标签 / 标签笔记)",
2354
- description: "首页:四象限待办 + 标签统计 + Agent 区块(纯 Agent / Agent+人工)。系统提示承诺的首页由这里 seed。",
2513
+ title: "首页(主页 / 所有标签 / 标签笔记)",
2514
+ description: "默认主页:四象限待办 + 「所有标签」「所有文章」入口;所有标签:标签统计 + Agent 区块(纯 Agent / Agent+人工);标签笔记:按标签浏览。系统提示承诺的首页由这里 seed,主页同时写入 $:/DefaultTiddlers。",
2355
2515
  check: async (ctx) => {
2356
2516
  const missing = [];
2357
2517
  for (const item of HOME_INDEX_ITEMS) if (!await presentOf(ctx, item.title)) missing.push(item.title);
2358
2518
  return {
2359
2519
  id: "home-index",
2360
- title: "首页(所有标签 / 标签笔记)",
2361
- description: "首页:四象限待办 + 标签统计 + Agent 区块(纯 Agent / Agent+人工)。系统提示承诺的首页由这里 seed。",
2520
+ title: "首页(主页 / 所有标签 / 标签笔记)",
2521
+ description: "默认主页:四象限待办 + 「所有标签」「所有文章」入口;所有标签:标签统计 + Agent 区块(纯 Agent / Agent+人工);标签笔记:按标签浏览。系统提示承诺的首页由这里 seed,主页同时写入 $:/DefaultTiddlers。",
2362
2522
  present: missing.length === 0,
2363
2523
  detail: missing.length === 0 ? "已存在" : `缺失:${missing.join("、")}`
2364
2524
  };
@@ -2382,6 +2542,39 @@ const SEED_DEFS = [
2382
2542
  }
2383
2543
  }
2384
2544
  },
2545
+ {
2546
+ id: "all-articles",
2547
+ title: "所有文章(两列分页总览)",
2548
+ description: "「所有文章」——全部条目分两列(🤖 Agent 撰写 / 👤 人工·人类)各自分页展示。每页条数取插件设置 ui.allArticles.pageSize(默认 10)。",
2549
+ check: async (ctx) => {
2550
+ const present = await presentOf(ctx, ALL_ARTICLES_TITLE);
2551
+ return {
2552
+ id: "all-articles",
2553
+ title: "所有文章(两列分页总览)",
2554
+ description: "「所有文章」——全部条目分两列(🤖 Agent 撰写 / 👤 人工·人类)各自分页展示。每页条数取插件设置 ui.allArticles.pageSize(默认 10)。",
2555
+ present,
2556
+ detail: present ? "已存在" : "缺失"
2557
+ };
2558
+ },
2559
+ run: async (ctx, force) => {
2560
+ try {
2561
+ const wrote = await seedAllArticles(ctx.client, { force });
2562
+ return {
2563
+ id: "all-articles",
2564
+ ok: true,
2565
+ wrote,
2566
+ detail: wrote ? force ? "已重新初始化" : "已写入" : force ? "内容已是最新(未重写)" : "已存在,跳过"
2567
+ };
2568
+ } catch (err) {
2569
+ return {
2570
+ id: "all-articles",
2571
+ ok: false,
2572
+ wrote: false,
2573
+ error: err instanceof Error ? err.message : String(err)
2574
+ };
2575
+ }
2576
+ }
2577
+ },
2385
2578
  {
2386
2579
  id: "tw-web-host",
2387
2580
  title: "TW 前端 API 基址(同源代理)",
@@ -3890,6 +4083,6 @@ function apply(ctx, rawConfig = {}) {
3890
4083
  }, "dsh-tiddlywiki: host teardown");
3891
4084
  }
3892
4085
  //#endregion
3893
- export { AutoCommitter, ConfigStore, DOC_NOTE_TAG, DOC_NOTE_TEXT, DOC_NOTE_TITLE, GitFace, HOME_INDEX_ITEMS, HOME_INDEX_MARKER_TITLE, PATH_PREFIX, SEED_DEFS, SEND_TO_AGENT_BUNDLE_TEXT, SEND_TO_AGENT_MARKER_TITLE, SEND_TO_AGENT_PLUGIN_TITLE, TW_PROXY_PATH, TW_PROXY_PREFIX, TW_WEB_HOST_DEFAULT, TW_WEB_HOST_TIDDLER, TiddlyWebClient, WikiServer, apply, bundledCatalog, checkAllSeeds, deepMerge, defineTool, dshHomePath, ensureLanguage, ensureTwWebHost, inject, name, normalizeThemes, openInTwEditor, readWikiInfo, registerAdminRoutes, registerRoutes, registerTiddlywikiTools, resolveTwRoot, runAllSeeds, runSeedById, seedDocNote, seedHomeIndex, seedSendToAgent, writeWikiInfo };
4086
+ export { ALL_ARTICLES_MARKER_TITLE, ALL_ARTICLES_TEXT, ALL_ARTICLES_TITLE, AutoCommitter, ConfigStore, DOC_NOTE_TAG, DOC_NOTE_TEXT, DOC_NOTE_TITLE, GitFace, HOME_DEFAULT_TIDDLERS, HOME_INDEX_ITEMS, HOME_INDEX_MARKER_TITLE, PATH_PREFIX, SEED_DEFS, SEND_TO_AGENT_BUNDLE_TEXT, SEND_TO_AGENT_MARKER_TITLE, SEND_TO_AGENT_PLUGIN_TITLE, TW_PROXY_PATH, TW_PROXY_PREFIX, TW_WEB_HOST_DEFAULT, TW_WEB_HOST_TIDDLER, TiddlyWebClient, WikiServer, apply, bundledCatalog, checkAllSeeds, deepMerge, defineTool, dshHomePath, ensureLanguage, ensureTwWebHost, inject, name, normalizeThemes, openInTwEditor, readWikiInfo, registerAdminRoutes, registerRoutes, registerTiddlywikiTools, resolveTwRoot, runAllSeeds, runSeedById, seedAllArticles, seedDocNote, seedHomeIndex, seedSendToAgent, writeWikiInfo };
3894
4087
 
3895
4088
  //# sourceMappingURL=index.js.map