@biaoo/tiangong-wiki 0.2.0 → 0.2.2

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.
Files changed (37) hide show
  1. package/README.md +39 -50
  2. package/README.zh-CN.md +39 -50
  3. package/SKILL.md +75 -107
  4. package/assets/templates/achievement.md +8 -8
  5. package/assets/templates/bridge.md +8 -8
  6. package/assets/templates/concept.md +14 -18
  7. package/assets/templates/faq.md +8 -10
  8. package/assets/templates/lesson.md +8 -8
  9. package/assets/templates/method.md +16 -8
  10. package/assets/templates/misconception.md +10 -10
  11. package/assets/templates/person.md +8 -8
  12. package/assets/templates/research-note.md +10 -10
  13. package/assets/templates/resume.md +11 -10
  14. package/assets/templates/source-summary.md +8 -12
  15. package/assets/tiangong-wiki-framework.png +0 -0
  16. package/assets/wiki.config.default.json +6 -3
  17. package/dist/commands/asset.js +21 -0
  18. package/dist/commands/skill.js +78 -0
  19. package/dist/commands/template.js +30 -0
  20. package/dist/core/cli-env.js +34 -5
  21. package/dist/core/global-config.js +61 -0
  22. package/dist/core/onboarding.js +252 -102
  23. package/dist/core/workflow-context.js +58 -21
  24. package/dist/core/workspace-skills.js +496 -60
  25. package/dist/daemon/server.js +8 -0
  26. package/dist/index.js +36 -1
  27. package/dist/operations/asset.js +81 -0
  28. package/dist/operations/query.js +25 -1
  29. package/dist/operations/template-lint.js +160 -0
  30. package/dist/utils/asset.js +75 -0
  31. package/dist/utils/errors.js +6 -0
  32. package/package.json +2 -1
  33. package/references/cli-interface.md +32 -1
  34. package/references/template-design-guide.md +125 -113
  35. package/references/{env.md → troubleshooting.md} +64 -33
  36. package/references/vault-to-wiki-instruction.md +109 -51
  37. package/references/wiki-maintenance-instruction.md +15 -15
@@ -1,16 +1,50 @@
1
- # Template 设计指南
1
+ # Template Design Guide
2
2
 
3
- 本文档定义如何为 wiki 设计新的 page type 和对应 template。适用于手动创建和 AI 自动演化(`ALLOW_TEMPLATE_EVOLUTION=true`)两种场景。
3
+ How to design a new page type and its template for the wiki. Use this guide when the current ontology cannot cleanly represent new knowledge and a new type is genuinely needed.
4
4
 
5
5
  ---
6
6
 
7
- ## 1. Template 是什么
7
+ ## When to Create a New Type vs. Use an Existing One
8
8
 
9
- 一个 template 由两部分组成:
9
+ Before creating a new type, check whether the knowledge fits an existing type:
10
10
 
11
- ### 模板文件(`templates/<type>.md`)
11
+ - **Structural difference** → new type needed (different fields, different sections)
12
+ - **Topic difference only** → use an existing type with different tags
12
13
 
13
- 定义页面的 frontmatter 字段和 body section 骨架:
14
+ Examples:
15
+ - "Environmental research note" vs. "Education research note" → same `research-note` type, different tags
16
+ - "Meeting minutes" vs. "Research note" → structurally different (participants, decisions, action items vs. research questions, literature, findings), new type needed
17
+
18
+ **Always discover the current ontology first:**
19
+
20
+ ```bash
21
+ tiangong-wiki type list --format json
22
+ tiangong-wiki type recommend --text "<summary>" --keywords "a,b,c" --limit 5 --format json
23
+ ```
24
+
25
+ If `type recommend` returns a good fit with high confidence, use that type. Only proceed with type creation when the fit is clearly poor.
26
+
27
+ ## Create vs. Propose Only
28
+
29
+ When the existing type system is not a clean fit:
30
+
31
+ - **Create the template yourself** when the need is clear, the structure is well-defined, and you can design a complete template following this guide.
32
+ - **Use `propose_only`** (in vault-to-wiki workflow) or flag for human review when:
33
+ - The knowledge domain is unfamiliar and the right structure is uncertain
34
+ - Multiple reasonable type designs exist and the choice has long-term ontology impact
35
+ - The new type would overlap significantly with existing types
36
+
37
+ See `references/vault-to-wiki-instruction.md` for how `propose_only` works in the vault workflow.
38
+
39
+ ---
40
+
41
+ ## Template Composition
42
+
43
+ A template has two parts — both are required:
44
+
45
+ ### Template File (`templates/<type>.md`)
46
+
47
+ Defines the frontmatter fields and body section skeleton:
14
48
 
15
49
  ```yaml
16
50
  ---
@@ -29,16 +63,16 @@ updatedAt: 2026-04-06
29
63
 
30
64
  ## Section 1
31
65
 
32
- 引导性提示文本,告诉作者这一节该写什么。
66
+ Guiding prompt that tells the author what to write in this section.
33
67
 
34
68
  ## Section 2
35
69
 
36
70
  ...
37
71
  ```
38
72
 
39
- ### 配置注册(`wiki.config.json` `templates.<type>`)
73
+ ### Config Registration (`wiki.config.json` under `templates.<type>`)
40
74
 
41
- 定义该类型的索引行为:
75
+ Defines how the type is indexed:
42
76
 
43
77
  ```json
44
78
  {
@@ -49,57 +83,42 @@ updatedAt: 2026-04-06
49
83
  }
50
84
  ```
51
85
 
52
- 两者缺一不可。模板文件定义"写什么",配置注册定义"怎么索引"
86
+ The template file defines "what to write"; the config registration defines "how to index".
53
87
 
54
88
  ---
55
89
 
56
- ## 2. 何时需要新 Type
90
+ ## Frontmatter Field Design
57
91
 
58
- 创建新 type 之前,先确认现有类型是否能覆盖:
92
+ ### Common Fields (inherited automatically)
59
93
 
60
- - 这类知识的**结构**是否与现有类型有本质差异?(字段不同、section 不同)
61
- - 还是仅仅是**主题**不同?(同样的结构,只是内容领域不同)
62
-
63
- **主题差异用 tags 区分,结构差异才建新 type。**
64
-
65
- 示例判断:
66
- - "环境领域的研究笔记" vs "教育领域的研究笔记" → 用 `research-note` + 不同 tags
67
- - "会议纪要" vs "研究笔记" → 结构不同(参会人、决议、待办 vs 研究问题、文献、发现),需要新 type
68
-
69
- ---
70
-
71
- ## 3. Frontmatter 字段设计
72
-
73
- ### 通用字段(不需要设计,自动继承)
74
-
75
- 所有 type 共享以下字段,模板中必须包含:
94
+ All types share these fields — always include them in the template:
76
95
 
77
96
  ```yaml
78
97
  pageType, title, nodeId, status, visibility,
79
98
  sourceRefs, relatedPages, tags, createdAt, updatedAt
80
99
  ```
81
100
 
82
- ### Type-specific 字段设计原则
101
+ ### Type-Specific Field Principles
83
102
 
84
- 1. **只加对查询或分类有意义的字段**。如果一个字段只在 body 中出现,不需要放进 frontmatter
85
- 2. **字段值应该是短文本或枚举**,不是长段落。长内容放 body section
86
- 3. **字段命名使用 camelCase**,系统会自动映射为 snake_case 列名
87
- 4. **不要重复通用字段的语义**。比如不要加 `category` 字段,用 `tags` 代替
103
+ 1. **Only add fields that serve querying or classification.** If a field only appears in the body, it does not belong in frontmatter.
104
+ 2. **Field values should be short text or enums**, not long paragraphs. Long content belongs in body sections.
105
+ 3. **Use camelCase for field names** — the system maps them to snake_case column names automatically.
106
+ 4. **Do not duplicate common field semantics.** For example, do not add a `category` field when `tags` already serves that purpose.
88
107
 
89
- ### 字段放哪一层
108
+ ### Where to Register Each Field
90
109
 
91
- | 问题 | 放在 | 原因 |
110
+ | Question | Register in | Reason |
92
111
  | --- | --- | --- |
93
- | 需要 `tiangong-wiki find --<field>` 过滤? | `columns` | SQLite 索引列,支持结构化查询 |
94
- | 需要出现在 `tiangong-wiki search` / `tiangong-wiki fts` 的摘要中? | `summaryFields` | 纳入 summary_text 用于检索 |
95
- | 需要生成 edge(关联到其他页面/节点)? | `edges` | 写入 edges 表,支持 graph 遍历 |
96
- | 只是页面内的补充信息? | 仅写在 frontmatter | 存入 `pages.extra` JSON,不建列 |
112
+ | Need `tiangong-wiki find --<field>` filtering? | `columns` | Creates a SQLite indexed column for structured queries |
113
+ | Should appear in `search` / `fts` summaries? | `summaryFields` | Included in `summary_text` for retrieval |
114
+ | Generates an edge to another page/node? | `edges` | Written to the edges table for graph traversal |
115
+ | Just supplementary page info? | Still must be declared | Current implementation rejects undeclared fields — register in `columns`, `edges`, or `commonEdges` |
97
116
 
98
117
  ---
99
118
 
100
- ## 4. Columns 设计
119
+ ## Columns Design
101
120
 
102
- `columns` 中的字段会在 `pages` 表上建列和索引,支持 `tiangong-wiki find` 的结构化过滤。
121
+ Fields in `columns` become indexed columns on the `pages` table, supporting `tiangong-wiki find` filtering.
103
122
 
104
123
  ```json
105
124
  "columns": {
@@ -108,18 +127,18 @@ sourceRefs, relatedPages, tags, createdAt, updatedAt
108
127
  }
109
128
  ```
110
129
 
111
- **设计要点**:
112
-
113
- - 类型目前只支持 `"text"`
114
- - 只有需要频繁按值过滤的字段才值得建列
115
- - 不同 type columns 共存于同一张 `pages` 表,非该类型的页面该列值为 NULL
116
- - 列名全局唯一 如果两个 type 都有 `severity` 字段,它们共享同一个列
130
+ Key points:
131
+ - Column type is currently only `"text"`
132
+ - Only fields that need frequent value-based filtering are worth indexing
133
+ - Different types share the same `pages` table — columns from other types are NULL
134
+ - Column names are globally unique — if two types both have `severity`, they share one column
135
+ - Every type-specific frontmatter field must be declared in at least `columns`, `edges`, or `commonEdges`; otherwise lint reports `unregistered_fields`
117
136
 
118
137
  ---
119
138
 
120
- ## 5. Edges 设计
139
+ ## Edges Design
121
140
 
122
- `edges` 定义 frontmatter 中的数组字段如何生成 graph 边。
141
+ `edges` defines how frontmatter array fields generate graph edges.
123
142
 
124
143
  ```json
125
144
  "edges": {
@@ -130,75 +149,68 @@ sourceRefs, relatedPages, tags, createdAt, updatedAt
130
149
  }
131
150
  ```
132
151
 
133
- **三个字段**:
134
-
135
- | 字段 | 必填 | 说明 |
152
+ | Field | Required | Description |
136
153
  | --- | --- | --- |
137
- | `edgeType` | | edge 类型标识,写入 `edges.edge_type` |
138
- | `resolve` | | 目标匹配方式:`"nodeId"` 匹配 `pages.node_id`;`"path"` 匹配 `pages.id` |
139
- | `match` | | 正则前置过滤,仅匹配的值参与 resolve |
140
-
141
- **设计要点**:
154
+ | `edgeType` | Yes | Edge type identifier, written to `edges.edge_type` |
155
+ | `resolve` | Yes | Target matching: `"nodeId"` matches `pages.node_id`; `"path"` matches `pages.id` |
156
+ | `match` | No | Regex pre-filter — only matching values participate in resolve |
142
157
 
143
- - 只有**指向其他页面或节点**的数组字段才需要定义 edge
144
- - `edgeType` 应该表达语义关系(`prerequisite`, `corrects`, `bridges_from`),不是字段名
145
- - `resolve: "nodeId"` 适用于引用知识图谱中的概念节点
146
- - `resolve: "path"` 适用于引用具体的页面文件路径
147
- - `commonEdges`(`relatedPages`, `sourceRefs`)已全局生效,template 中不需要重复定义
158
+ Key points:
159
+ - Only array fields **pointing to other pages or nodes** need edge definitions
160
+ - `edgeType` should express a semantic relationship (`prerequisite`, `corrects`, `bridges_from`), not just the field name
161
+ - `commonEdges` (`relatedPages`, `sourceRefs`) are global — do not redefine them in templates
148
162
 
149
163
  ---
150
164
 
151
- ## 6. SummaryFields 设计
165
+ ## SummaryFields Design
152
166
 
153
- `summaryFields` 中的字段值会拼接进 `pages.summary_text`,用于语义搜索和全文检索。
167
+ Fields in `summaryFields` are concatenated into `pages.summary_text` for semantic search and full-text search.
154
168
 
155
169
  ```json
156
170
  "summaryFields": ["confidence", "masteryLevel", "prerequisites"]
157
171
  ```
158
172
 
159
- **设计要点**:
160
-
161
- - 选择能帮助检索的字段 如果知道 `domain: "环境工程"` 能帮搜索找到这个页面,就加进去
162
- - 不要放长文本字段,summary_text 应保持简洁
163
- - `defaultSummaryFields`(`title`, `tags`)自动包含,不需要重复
173
+ Key points:
174
+ - Choose fields that help retrieval — e.g., `domain: "environmental engineering"` helps search find the page
175
+ - Avoid long-text fields; `summary_text` should stay concise
176
+ - `defaultSummaryFields` (`title`, `tags`) are included automatically
177
+ - `summaryFields` only controls inclusion in `summary_text` — the field itself must still be declared in `columns`, `edges`, or `commonEdges`
164
178
 
165
179
  ---
166
180
 
167
- ## 7. Body Section 设计
168
-
169
- Body section 是模板文件中 frontmatter 之后的 Markdown 骨架,引导作者(人或 AI)写出结构化内容。
181
+ ## Body Section Design
170
182
 
171
- **设计原则**:
183
+ Body sections are the Markdown skeleton after frontmatter, guiding the author (human or AI) to write structured content.
172
184
 
173
- 1. **每个 section 用 `##` 标题** 开头
174
- 2. **写一句引导性提示**,告诉作者这一节的目的和期望内容,不是模板占位符
175
- 3. **提示语应该是具体的引导**,不是"在此处填写内容"这样的泛泛之词
176
- 4. **Section 数量控制在 3-6 个** 太少缺乏结构,太多增加写作负担
177
- 5. **Section 之间应该有逻辑递进**比如从"是什么""为什么重要""如何使用"
185
+ Principles:
186
+ 1. **Each section starts with `##`**
187
+ 2. **Write a specific guiding prompt** that explains the purpose and expected content
188
+ 3. **Keep section count to 36**too few lacks structure, too many adds burden
189
+ 4. **Sections should have logical progression** e.g., "what it is""why it matters""how to use it"
178
190
 
179
- **好的提示语示例**:
191
+ Good prompt example:
180
192
 
181
193
  ```markdown
182
- ## 核心理解
194
+ ## Core Understanding
183
195
 
184
- 用两到四句话说明这个概念到底是什么,以及它为什么值得记住。
196
+ In two to four sentences, explain what this concept is and why it is worth remembering.
185
197
  ```
186
198
 
187
- **差的提示语示例**:
199
+ Bad prompt example:
188
200
 
189
201
  ```markdown
190
- ## 内容
202
+ ## Content
191
203
 
192
- <!-- 在此处填写内容 -->
204
+ <!-- Fill in content here -->
193
205
  ```
194
206
 
195
207
  ---
196
208
 
197
- ## 8. 完整示例
209
+ ## Complete Example
198
210
 
199
- 假设需要设计一个 `meeting-note` 类型:
211
+ Designing a `meeting-note` type:
200
212
 
201
- ### 模板文件 `templates/meeting-note.md`
213
+ ### Template File `templates/meeting-note.md`
202
214
 
203
215
  ```yaml
204
216
  ---
@@ -217,24 +229,24 @@ participants: []
217
229
  decisions: []
218
230
  ---
219
231
 
220
- ## 背景
232
+ ## Background
221
233
 
222
- 简要说明这次会议的目的和上下文,让没参加的人能快速理解为什么开这个会。
234
+ Briefly explain the purpose and context of this meeting so someone who did not attend can quickly understand why it was held.
223
235
 
224
- ## 关键讨论
236
+ ## Key Discussion
225
237
 
226
- 记录会上最重要的讨论点和不同意见,重点是分歧和最终共识,不是流水账。
238
+ Record the most important discussion points and disagreements. Focus on conflicts and final consensus, not a chronological transcript.
227
239
 
228
- ## 决议
240
+ ## Decisions
229
241
 
230
- 列出会议达成的具体决定,每条决议应该是可执行的,不是模糊的方向。
242
+ List specific decisions reached. Each decision should be actionable, not a vague direction.
231
243
 
232
- ## 后续待办
244
+ ## Follow-up Actions
233
245
 
234
- 列出需要跟进的行动项,标注负责人和预期完成时间。
246
+ List action items with owners and expected completion dates.
235
247
  ```
236
248
 
237
- ### 配置注册
249
+ ### Config Registration
238
250
 
239
251
  ```json
240
252
  "meeting-note": {
@@ -247,25 +259,25 @@ decisions: []
247
259
  }
248
260
  ```
249
261
 
250
- **设计决策说明**:
251
-
252
- - `meetingDate` 建列需要按日期过滤查找
253
- - `participants` 不建列 查参会人用 `tiangong-wiki fts` 搜索 summary_text 即可
254
- - `participants` `decisions` 放入 summaryFields 帮助搜索命中
255
- - `decisions` 不建 edge决议是文本,不是指向其他页面的引用
256
- - Body 4 个 section — 背景 → 讨论 → 决议 → 待办,逻辑递进
262
+ Design rationale:
263
+ - `meetingDate` as column — needed for date-based filtering
264
+ - `participants` not a column searching via `tiangong-wiki fts` on summary_text is sufficient
265
+ - `participants` and `decisions` in summaryFields helps search hits
266
+ - `decisions` not an edge — decisions are text, not references to other pages
267
+ - 4 body sectionsbackground → discussion → decisions → follow-up, logical progression
257
268
 
258
269
  ---
259
270
 
260
- ## 9. 检查清单
271
+ ## Checklist
261
272
 
262
- 设计完 template 后,用以下问题自检:
273
+ After designing a template, verify:
263
274
 
264
- - [ ] type 的结构是否与所有现有 type 都有本质差异?
265
- - [ ] 每个 frontmatter 字段都有明确的查询或分类用途?
266
- - [ ] 需要 `tiangong-wiki find` 过滤的字段都放进了 `columns`?
267
- - [ ] 生成 graph 边的数组字段都定义了 `edges`?
268
- - [ ] `summaryFields` 包含了有助于检索的关键字段?
269
- - [ ] Body section 数量在 3-6 个之间,有逻辑递进?
270
- - [ ] Section 提示语具体而非泛泛?
271
- - [ ] 通过 `tiangong-wiki template create --type <type> --title <title>` 创建后,可以 `tiangong-wiki sync` + `tiangong-wiki lint` 无 error?
275
+ - [ ] The new type is structurally different from all existing types (not just topically different)?
276
+ - [ ] Every frontmatter field has a clear querying or classification purpose?
277
+ - [ ] Fields needing `tiangong-wiki find` filtering are in `columns`?
278
+ - [ ] Array fields generating graph edges are defined in `edges`?
279
+ - [ ] `summaryFields` includes key fields that aid retrieval?
280
+ - [ ] Every type-specific frontmatter field is declared in `columns`, `edges`, or `commonEdges`?
281
+ - [ ] Body has 3–6 sections with logical progression?
282
+ - [ ] Section prompts are specific, not generic placeholders?
283
+ - [ ] After creating a test page with `tiangong-wiki create --type <type> --title <title>`, both `tiangong-wiki lint` and `tiangong-wiki sync` pass with no errors?
@@ -1,10 +1,30 @@
1
- # Environment Variables
1
+ # Troubleshooting
2
2
 
3
- All configuration is managed through `.wiki.env` (created by `tiangong-wiki setup`). Variables can also be set in shell environment or a `.env` file.
3
+ Diagnosis and configuration reference for the wiki skill. Start with `tiangong-wiki doctor` for automated health checks.
4
+
5
+ ---
6
+
7
+ ## Quick Diagnosis
8
+
9
+ ```bash
10
+ # Run the built-in diagnostic
11
+ tiangong-wiki doctor
12
+
13
+ # Check configuration validity
14
+ tiangong-wiki check-config
15
+
16
+ # Check workspace health
17
+ tiangong-wiki stat
18
+ tiangong-wiki lint
19
+ ```
4
20
 
5
21
  ---
6
22
 
7
- ## Core
23
+ ## Environment Variables
24
+
25
+ All configuration is managed through `.wiki.env` (created by `tiangong-wiki setup`). Variables can also be set in shell environment or a `.env` file.
26
+
27
+ ### Core
8
28
 
9
29
  | Variable | Required | Description |
10
30
  | --- | --- | --- |
@@ -14,7 +34,7 @@ All configuration is managed through `.wiki.env` (created by `tiangong-wiki setu
14
34
  | `WIKI_TEMPLATES_PATH` | Yes | Path to the templates directory |
15
35
  | `WIKI_SYNC_INTERVAL` | No | Auto-sync interval in seconds (default: `86400`) |
16
36
 
17
- ## Vault
37
+ ### Vault
18
38
 
19
39
  | Variable | Required | Description |
20
40
  | --- | --- | --- |
@@ -23,7 +43,7 @@ All configuration is managed through `.wiki.env` (created by `tiangong-wiki setu
23
43
  | `VAULT_HASH_MODE` | No | Hash mode for change detection (`content` or `mtime`, default: `mtime`) |
24
44
  | `VAULT_SYNOLOGY_REMOTE_PATH` | If `synology` | Remote path on Synology NAS |
25
45
 
26
- ## Synology (when `VAULT_SOURCE=synology`)
46
+ ### Synology (when `VAULT_SOURCE=synology`)
27
47
 
28
48
  | Variable | Required | Description |
29
49
  | --- | --- | --- |
@@ -33,7 +53,7 @@ All configuration is managed through `.wiki.env` (created by `tiangong-wiki setu
33
53
  | `SYNOLOGY_VERIFY_SSL` | No | Verify SSL certificates (default: `true`) |
34
54
  | `SYNOLOGY_READONLY` | No | Read-only mode (default: `false`) |
35
55
 
36
- ## Embedding
56
+ ### Embedding
37
57
 
38
58
  | Variable | Required | Description |
39
59
  | --- | --- | --- |
@@ -42,9 +62,9 @@ All configuration is managed through `.wiki.env` (created by `tiangong-wiki setu
42
62
  | `EMBEDDING_MODEL` | Yes | Embedding model name |
43
63
  | `EMBEDDING_DIMENSIONS` | No | Vector dimensions (default: model-dependent) |
44
64
 
45
- ## Agent (Agentic Workflow)
65
+ ### Agent (Agentic Workflow)
46
66
 
47
- The agent uses [Codex SDK](https://www.npmjs.com/package/@openai/codex-sdk) to process vault items. When `WIKI_AGENT_BASE_URL` is set, a custom `model_provider` is injected to override any global `~/.codex/config.toml` settings, ensuring requests go to the correct endpoint.
67
+ The agent uses [Codex SDK](https://www.npmjs.com/package/@openai/codex-sdk) to process vault items. When `WIKI_AGENT_BASE_URL` is set, a custom `model_provider` is injected to override any global `~/.codex/config.toml` settings.
48
68
 
49
69
  | Variable | Required | Description |
50
70
  | --- | --- | --- |
@@ -55,9 +75,38 @@ The agent uses [Codex SDK](https://www.npmjs.com/package/@openai/codex-sdk) to p
55
75
  | `WIKI_AGENT_BATCH_SIZE` | No | Max concurrent vault items per batch (default: `5`) |
56
76
  | `WIKI_PARSER_SKILLS` | No | Comma-separated parser skill list (e.g. `pdf,docx,pptx,xlsx`) |
57
77
 
58
- ### OpenAI (default)
78
+ ---
79
+
80
+ ## Common Issues
81
+
82
+ ### "WIKI_PATH is not set" or config errors
83
+
84
+ Run `tiangong-wiki setup` to create `.wiki.env` with all required paths. Verify with `tiangong-wiki check-config`.
85
+
86
+ ### Semantic search returns no results
87
+
88
+ `tiangong-wiki search` and `tiangong-wiki type recommend` (with embeddings) require `EMBEDDING_*` variables. If not configured, use `tiangong-wiki fts` (full-text search) or `tiangong-wiki find` (metadata filter) instead.
89
+
90
+ ### Index out of sync
59
91
 
60
- No special setup required. Set `WIKI_AGENT_BASE_URL` to `https://api.openai.com/v1` (or leave empty) and provide your API key.
92
+ Run `tiangong-wiki sync` to rebuild. For a single page: `tiangong-wiki sync --path <page-id>`.
93
+
94
+ ### Lint errors after page edits
95
+
96
+ Always run `tiangong-wiki lint --path <page-id> --format json` after mutations. Common lint issues:
97
+ - Missing required frontmatter fields for the page type
98
+ - Broken `sourceRefs` pointing to non-existent pages
99
+ - Orphan pages with no graph connections
100
+
101
+ ### Parser skills not found
102
+
103
+ Parser skills must be installed under `<workspace-root>/.agents/skills/`. Run `tiangong-wiki skill` to inspect installed skills. Use `tiangong-wiki skill update --all` to update.
104
+
105
+ ---
106
+
107
+ ## LLM Provider Setup
108
+
109
+ ### OpenAI (default)
61
110
 
62
111
  ```env
63
112
  WIKI_AGENT_ENABLED=true
@@ -65,9 +114,9 @@ WIKI_AGENT_API_KEY=sk-...
65
114
  WIKI_AGENT_MODEL=gpt-5.4
66
115
  ```
67
116
 
68
- ### vLLM
117
+ ### vLLM (self-hosted)
69
118
 
70
- vLLM can serve as a self-hosted LLM provider via its OpenAI-compatible API. Wiki's agentic workflow communicates through the [Responses API](https://platform.openai.com/docs/api-reference/responses) (`/v1/responses`), which requires vLLM **v0.8.5+**.
119
+ Requires vLLM **v0.8.5+** for Responses API support (`/v1/responses`).
71
120
 
72
121
  ```env
73
122
  WIKI_AGENT_ENABLED=true
@@ -78,19 +127,9 @@ WIKI_AGENT_MODEL=Qwen/Qwen3.5-397B-A17B-GPTQ-Int4
78
127
 
79
128
  #### Chat template: `developer` role support
80
129
 
81
- The Codex CLI sends `developer`-role messages (the OpenAI equivalent of `system` that can appear mid-conversation). Most model chat templates only recognize `system`, `user`, `assistant`, and `tool` — they will reject `developer` with:
130
+ The Codex CLI sends `developer`-role messages. Most model chat templates only recognize `system`, `user`, `assistant`, and `tool` — they will reject `developer` with `400 Bad Request: "Unexpected message role."`.
82
131
 
83
- ```
84
- 400 Bad Request: "Unexpected message role."
85
- ```
86
-
87
- **Fix:** Use a modified chat template that maps `developer` → `system`. A ready-to-use template for Qwen3.5 is included at:
88
-
89
- ```
90
- assets/vllm/qwen3_5_openai_developer.jinja
91
- ```
92
-
93
- Launch vLLM with the custom template:
132
+ **Fix:** Use a modified chat template that maps `developer` → `system`. A ready-to-use template for Qwen3.5 is at `assets/vllm/qwen3_5_openai_developer.jinja`.
94
133
 
95
134
  ```bash
96
135
  vllm serve <model> \
@@ -98,17 +137,11 @@ vllm serve <model> \
98
137
  --port 7730
99
138
  ```
100
139
 
101
- The template is derived from the official Qwen3.5 template with a single semantic change: `developer` messages are treated as `system` messages. Key modifications:
102
-
103
- 1. **Instruction prefix detection** — counts both `system` and `developer` at the start of the conversation (line 56)
104
- 2. **Role normalization** — `developer` → `system` throughout the conversation loop (lines 111, 160, 166)
105
-
106
- > For other model families (LLaMA, Mistral, etc.), apply the same pattern: find `message.role == "system"` checks in the template and extend them to also match `"developer"`.
140
+ For other model families, apply the same pattern: extend `message.role == "system"` checks to also match `"developer"`.
107
141
 
108
142
  #### Verifying vLLM compatibility
109
143
 
110
144
  ```bash
111
- # Test the /v1/responses endpoint directly
112
145
  curl -s http://<host>:<port>/v1/responses \
113
146
  -H "Content-Type: application/json" \
114
147
  -H "Authorization: Bearer <token>" \
@@ -118,5 +151,3 @@ curl -s http://<host>:<port>/v1/responses \
118
151
  "reasoning": {"effort": "low"}
119
152
  }' | head -c 500
120
153
  ```
121
-
122
- A successful response returns a JSON object with `output` containing the model's reply.