@biaoo/tiangong-wiki 0.2.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.
Files changed (136) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +167 -0
  3. package/README.zh-CN.md +167 -0
  4. package/SKILL.md +116 -0
  5. package/agents/openai.yaml +4 -0
  6. package/assets/config.example.env +18 -0
  7. package/assets/templates/achievement.md +32 -0
  8. package/assets/templates/bridge.md +33 -0
  9. package/assets/templates/concept.md +47 -0
  10. package/assets/templates/faq.md +31 -0
  11. package/assets/templates/lesson.md +31 -0
  12. package/assets/templates/method.md +31 -0
  13. package/assets/templates/misconception.md +35 -0
  14. package/assets/templates/person.md +31 -0
  15. package/assets/templates/research-note.md +34 -0
  16. package/assets/templates/resume.md +34 -0
  17. package/assets/templates/source-summary.md +35 -0
  18. package/assets/vllm/qwen3_5_openai_developer.jinja +182 -0
  19. package/assets/wiki.config.default.json +193 -0
  20. package/dist/commands/check-config.js +77 -0
  21. package/dist/commands/create.js +32 -0
  22. package/dist/commands/daemon.js +186 -0
  23. package/dist/commands/dashboard.js +112 -0
  24. package/dist/commands/doctor.js +22 -0
  25. package/dist/commands/export-graph.js +28 -0
  26. package/dist/commands/export-index.js +31 -0
  27. package/dist/commands/find.js +36 -0
  28. package/dist/commands/fts.js +32 -0
  29. package/dist/commands/graph.js +35 -0
  30. package/dist/commands/init.js +48 -0
  31. package/dist/commands/lint.js +35 -0
  32. package/dist/commands/list.js +28 -0
  33. package/dist/commands/page-info.js +24 -0
  34. package/dist/commands/search.js +32 -0
  35. package/dist/commands/setup.js +15 -0
  36. package/dist/commands/stat.js +20 -0
  37. package/dist/commands/sync.js +38 -0
  38. package/dist/commands/template.js +71 -0
  39. package/dist/commands/type.js +88 -0
  40. package/dist/commands/vault.js +64 -0
  41. package/dist/core/agent.js +201 -0
  42. package/dist/core/cli-env.js +129 -0
  43. package/dist/core/codex-workflow.js +233 -0
  44. package/dist/core/config.js +126 -0
  45. package/dist/core/db.js +292 -0
  46. package/dist/core/embedding.js +104 -0
  47. package/dist/core/frontmatter.js +287 -0
  48. package/dist/core/indexer.js +241 -0
  49. package/dist/core/onboarding.js +967 -0
  50. package/dist/core/page-files.js +91 -0
  51. package/dist/core/paths.js +161 -0
  52. package/dist/core/presenters.js +23 -0
  53. package/dist/core/query.js +58 -0
  54. package/dist/core/runtime.js +20 -0
  55. package/dist/core/sync.js +235 -0
  56. package/dist/core/synology.js +412 -0
  57. package/dist/core/template-evolution.js +38 -0
  58. package/dist/core/vault-processing.js +742 -0
  59. package/dist/core/vault.js +594 -0
  60. package/dist/core/workflow-context.js +188 -0
  61. package/dist/core/workflow-result.js +162 -0
  62. package/dist/core/workspace-bootstrap.js +30 -0
  63. package/dist/core/workspace-skills.js +220 -0
  64. package/dist/daemon/client.js +147 -0
  65. package/dist/daemon/server.js +807 -0
  66. package/dist/daemon/state.js +53 -0
  67. package/dist/dashboard/assets/index-1FgAUZ28.css +1 -0
  68. package/dist/dashboard/assets/index-6A0PWT4X.js +154 -0
  69. package/dist/dashboard/assets/jetbrains-mono-cyrillic-400-normal-BEIGL1Tu.woff2 +0 -0
  70. package/dist/dashboard/assets/jetbrains-mono-cyrillic-400-normal-ugxPyKxw.woff +0 -0
  71. package/dist/dashboard/assets/jetbrains-mono-cyrillic-500-normal-DJqRU3vO.woff +0 -0
  72. package/dist/dashboard/assets/jetbrains-mono-cyrillic-500-normal-DmUKJPL_.woff2 +0 -0
  73. package/dist/dashboard/assets/jetbrains-mono-cyrillic-700-normal-BWTpRfYl.woff2 +0 -0
  74. package/dist/dashboard/assets/jetbrains-mono-cyrillic-700-normal-CEoEElIJ.woff +0 -0
  75. package/dist/dashboard/assets/jetbrains-mono-greek-400-normal-B9oWc5Lo.woff +0 -0
  76. package/dist/dashboard/assets/jetbrains-mono-greek-400-normal-C190GLew.woff2 +0 -0
  77. package/dist/dashboard/assets/jetbrains-mono-greek-500-normal-D7SFKleX.woff +0 -0
  78. package/dist/dashboard/assets/jetbrains-mono-greek-500-normal-JpySY46c.woff2 +0 -0
  79. package/dist/dashboard/assets/jetbrains-mono-greek-700-normal-C6CZE3T8.woff2 +0 -0
  80. package/dist/dashboard/assets/jetbrains-mono-greek-700-normal-DEigVDxa.woff +0 -0
  81. package/dist/dashboard/assets/jetbrains-mono-latin-400-normal-6-qcROiO.woff +0 -0
  82. package/dist/dashboard/assets/jetbrains-mono-latin-400-normal-V6pRDFza.woff2 +0 -0
  83. package/dist/dashboard/assets/jetbrains-mono-latin-500-normal-BWZEU5yA.woff2 +0 -0
  84. package/dist/dashboard/assets/jetbrains-mono-latin-500-normal-CJOVTJB7.woff +0 -0
  85. package/dist/dashboard/assets/jetbrains-mono-latin-700-normal-BYuf6tUa.woff2 +0 -0
  86. package/dist/dashboard/assets/jetbrains-mono-latin-700-normal-D3wTyLJW.woff +0 -0
  87. package/dist/dashboard/assets/jetbrains-mono-latin-ext-400-normal-Bc8Ftmh3.woff2 +0 -0
  88. package/dist/dashboard/assets/jetbrains-mono-latin-ext-400-normal-fXTG6kC5.woff +0 -0
  89. package/dist/dashboard/assets/jetbrains-mono-latin-ext-500-normal-Cut-4mMH.woff2 +0 -0
  90. package/dist/dashboard/assets/jetbrains-mono-latin-ext-500-normal-ckzbgY84.woff +0 -0
  91. package/dist/dashboard/assets/jetbrains-mono-latin-ext-700-normal-CZipNAKV.woff2 +0 -0
  92. package/dist/dashboard/assets/jetbrains-mono-latin-ext-700-normal-CxPITLHs.woff +0 -0
  93. package/dist/dashboard/assets/jetbrains-mono-vietnamese-400-normal-CqNFfHCs.woff +0 -0
  94. package/dist/dashboard/assets/jetbrains-mono-vietnamese-500-normal-DNRqzVM1.woff +0 -0
  95. package/dist/dashboard/assets/jetbrains-mono-vietnamese-700-normal-BDLVIk2r.woff +0 -0
  96. package/dist/dashboard/assets/space-grotesk-latin-400-normal-BnQMeOim.woff +0 -0
  97. package/dist/dashboard/assets/space-grotesk-latin-400-normal-CJ-V5oYT.woff2 +0 -0
  98. package/dist/dashboard/assets/space-grotesk-latin-500-normal-CNSSEhBt.woff +0 -0
  99. package/dist/dashboard/assets/space-grotesk-latin-500-normal-lFbtlQH6.woff2 +0 -0
  100. package/dist/dashboard/assets/space-grotesk-latin-700-normal-CwsQ-cCU.woff +0 -0
  101. package/dist/dashboard/assets/space-grotesk-latin-700-normal-RjhwGPKo.woff2 +0 -0
  102. package/dist/dashboard/assets/space-grotesk-latin-ext-400-normal-CfP_5XZW.woff2 +0 -0
  103. package/dist/dashboard/assets/space-grotesk-latin-ext-400-normal-DRPE3kg4.woff +0 -0
  104. package/dist/dashboard/assets/space-grotesk-latin-ext-500-normal-3dgZTiw9.woff +0 -0
  105. package/dist/dashboard/assets/space-grotesk-latin-ext-500-normal-DUe3BAxM.woff2 +0 -0
  106. package/dist/dashboard/assets/space-grotesk-latin-ext-700-normal-BQnZhY3m.woff2 +0 -0
  107. package/dist/dashboard/assets/space-grotesk-latin-ext-700-normal-HVCqSBdx.woff +0 -0
  108. package/dist/dashboard/assets/space-grotesk-vietnamese-400-normal-B7xT_GF5.woff2 +0 -0
  109. package/dist/dashboard/assets/space-grotesk-vietnamese-400-normal-BIWiOVfw.woff +0 -0
  110. package/dist/dashboard/assets/space-grotesk-vietnamese-500-normal-BTqKIpxg.woff +0 -0
  111. package/dist/dashboard/assets/space-grotesk-vietnamese-500-normal-BmEvtly_.woff2 +0 -0
  112. package/dist/dashboard/assets/space-grotesk-vietnamese-700-normal-DMty7AZE.woff2 +0 -0
  113. package/dist/dashboard/assets/space-grotesk-vietnamese-700-normal-Duxec5Rn.woff +0 -0
  114. package/dist/dashboard/index.html +18 -0
  115. package/dist/index.js +86 -0
  116. package/dist/operations/dashboard.js +1231 -0
  117. package/dist/operations/export.js +110 -0
  118. package/dist/operations/query.js +649 -0
  119. package/dist/operations/type-template.js +210 -0
  120. package/dist/operations/write.js +143 -0
  121. package/dist/types/config.js +1 -0
  122. package/dist/types/page.js +1 -0
  123. package/dist/utils/case.js +22 -0
  124. package/dist/utils/errors.js +26 -0
  125. package/dist/utils/fs.js +77 -0
  126. package/dist/utils/output.js +33 -0
  127. package/dist/utils/process.js +60 -0
  128. package/dist/utils/segmenter.js +24 -0
  129. package/dist/utils/slug.js +10 -0
  130. package/dist/utils/time.js +24 -0
  131. package/package.json +64 -0
  132. package/references/cli-interface.md +312 -0
  133. package/references/env.md +122 -0
  134. package/references/template-design-guide.md +271 -0
  135. package/references/vault-to-wiki-instruction.md +110 -0
  136. package/references/wiki-maintenance-instruction.md +190 -0
@@ -0,0 +1,31 @@
1
+ ---
2
+ pageType: method
3
+ title: Method Title
4
+ nodeId: method-slug
5
+ status: draft
6
+ visibility: private
7
+ sourceRefs: []
8
+ relatedPages: []
9
+ tags: []
10
+ createdAt: 2026-04-06
11
+ updatedAt: 2026-04-06
12
+ domain:
13
+ effectiveness:
14
+ applicableTo: []
15
+ ---
16
+
17
+ ## 方法描述
18
+
19
+ 先用一段完整的话解释这套方法的目标、输入、输出和基本流程。
20
+
21
+ ## 适用场景
22
+
23
+ 说明这套方法在什么问题、约束和前置条件下最值得使用。
24
+
25
+ ## 不适用场景
26
+
27
+ 写出哪些边界条件会让这套方法失效,避免未来被误用。
28
+
29
+ ## 使用记录
30
+
31
+ 记录真实使用过它的场景、结果、指标或反馈,支撑 effectiveness 的判断。
@@ -0,0 +1,35 @@
1
+ ---
2
+ pageType: misconception
3
+ title: Misconception Title
4
+ nodeId: misconception-slug
5
+ status: draft
6
+ visibility: private
7
+ sourceRefs: []
8
+ relatedPages: []
9
+ tags: []
10
+ createdAt: 2026-04-06
11
+ updatedAt: 2026-04-06
12
+ severity: medium
13
+ resolvedAt:
14
+ correctedConcepts: []
15
+ ---
16
+
17
+ ## 原来的理解(错误)
18
+
19
+ 准确写下当时错误的理解,不要提前替它辩护或修正。
20
+
21
+ ## 为什么错了
22
+
23
+ 说明哪条证据、哪个反例或哪个推理步骤暴露了原理解的问题。
24
+
25
+ ## 正确理解
26
+
27
+ 用清晰的语言写出现在确认正确的理解,并指出关键差异。
28
+
29
+ ## 转折点
30
+
31
+ 记录让你真正完成认知切换的瞬间、材料或实验结果。
32
+
33
+ ## 防止复发
34
+
35
+ 写下未来再次遇到相似问题时,应该用什么检查点防止重复犯错。
@@ -0,0 +1,31 @@
1
+ ---
2
+ pageType: person
3
+ title: Person Name
4
+ nodeId: person-slug
5
+ status: draft
6
+ visibility: private
7
+ sourceRefs: []
8
+ relatedPages: []
9
+ tags: []
10
+ createdAt: 2026-04-06
11
+ updatedAt: 2026-04-06
12
+ role:
13
+ context:
14
+ contact:
15
+ ---
16
+
17
+ ## 基本信息
18
+
19
+ 写清楚这个人的身份、角色、与你的关系以及为什么值得长期记录。
20
+
21
+ ## 共事内容
22
+
23
+ 说明你们在哪些项目、主题或情境中有过协作、交流或影响。
24
+
25
+ ## 从他/她那学到的
26
+
27
+ 记录这个人带来的关键认知、做事方式、提醒或可复用的经验。
28
+
29
+ ## 备忘
30
+
31
+ 写下未来互动时需要记住的事项,例如偏好、待跟进事项或联系线索。
@@ -0,0 +1,34 @@
1
+ ---
2
+ pageType: research-note
3
+ title: Research Note Title
4
+ nodeId: research-note-slug
5
+ status: draft
6
+ visibility: private
7
+ sourceRefs: []
8
+ relatedPages: []
9
+ tags: []
10
+ createdAt: 2026-04-06
11
+ updatedAt: 2026-04-06
12
+ researchTopic:
13
+ stage:
14
+ ---
15
+
16
+ ## 研究问题
17
+
18
+ 明确写下当前真正要回答的问题,以及为什么这个问题值得继续研究。
19
+
20
+ ## 已读文献
21
+
22
+ 汇总已经读过的来源、它们分别提供了什么线索,以及哪些结论彼此冲突。
23
+
24
+ ## 当前理解
25
+
26
+ 用你自己的话总结目前的工作假设、解释框架或初步结论。
27
+
28
+ ## 开放问题
29
+
30
+ 列出尚未解决的疑点、反例、数据缺口或需要验证的推断。
31
+
32
+ ## 下一步
33
+
34
+ 说明下一轮最值得做的阅读、实验、访谈或验证动作。
@@ -0,0 +1,34 @@
1
+ ---
2
+ pageType: resume
3
+ title: Resume Title
4
+ nodeId: resume-slug
5
+ status: draft
6
+ visibility: private
7
+ sourceRefs: []
8
+ relatedPages: []
9
+ tags: []
10
+ createdAt: 2026-04-06
11
+ updatedAt: 2026-04-06
12
+ targetAudience:
13
+ lastReviewedAt:
14
+ ---
15
+
16
+ ## 基本信息
17
+
18
+ 先写出这份 resume 面向谁、主打什么定位,以及希望读者一眼记住什么。
19
+
20
+ ## 教育/工作背景
21
+
22
+ 按与你的目标最相关的顺序整理教育、工作或长期项目背景,而不是机械罗列。
23
+
24
+ ## 核心技能
25
+
26
+ 写出最能支撑当前目标 audience 的技能、能力证据和熟练程度。
27
+
28
+ ## 项目经历
29
+
30
+ 挑选最有代表性的项目,说明问题、动作、结果以及你的具体贡献。
31
+
32
+ ## 荣誉与成就
33
+
34
+ 汇总最能增强可信度的 achievement、奖项、认证或公开证明材料。
@@ -0,0 +1,35 @@
1
+ ---
2
+ pageType: source-summary
3
+ title: Source Summary Title
4
+ nodeId: source-summary-slug
5
+ status: draft
6
+ visibility: private
7
+ sourceRefs: []
8
+ relatedPages: []
9
+ tags: []
10
+ createdAt: 2026-04-06
11
+ updatedAt: 2026-04-06
12
+ sourceType:
13
+ vaultPath:
14
+ keyFindings: []
15
+ ---
16
+
17
+ ## 来源信息
18
+
19
+ 交代这份来源是什么、来自哪里、为什么值得被单独消化成 wiki 页面。
20
+
21
+ ## 核心内容
22
+
23
+ 用结构化段落总结这份来源的主题、结构和主要论点,而不是只写一句话。
24
+
25
+ ## 关键结论
26
+
27
+ 列出对后续决策、学习或项目推进最重要的结论与发现。
28
+
29
+ ## 与已有知识的关系
30
+
31
+ 说明这份来源会补强、修正或挑战哪些现有 concept、method 或 lesson 页面。
32
+
33
+ ## 重要引用
34
+
35
+ 摘录最值得回看的句子、数据点、章节或页码线索,帮助以后快速回源。
@@ -0,0 +1,182 @@
1
+ {#-
2
+ Derived from the official Qwen3.5 chat template.
3
+ Local change: normalize OpenAI "developer" messages to Qwen "system".
4
+ -#}
5
+ {%- set image_count = namespace(value=0) %}
6
+ {%- set video_count = namespace(value=0) %}
7
+ {%- set ns = namespace(
8
+ instruction_prefix_count=0,
9
+ seen_non_instruction=false,
10
+ multi_step_tool=true,
11
+ last_query_index=messages|length - 1
12
+ ) %}
13
+ {%- macro render_content(content, do_vision_count, is_system_content=false) %}
14
+ {%- if content is string %}
15
+ {{- content }}
16
+ {%- elif content is iterable and content is not mapping %}
17
+ {%- for item in content %}
18
+ {%- if 'image' in item or 'image_url' in item or item.type == 'image' %}
19
+ {%- if is_system_content %}
20
+ {{- raise_exception('System/developer message cannot contain images.') }}
21
+ {%- endif %}
22
+ {%- if do_vision_count %}
23
+ {%- set image_count.value = image_count.value + 1 %}
24
+ {%- endif %}
25
+ {%- if add_vision_id %}
26
+ {{- 'Picture ' ~ image_count.value ~ ': ' }}
27
+ {%- endif %}
28
+ {{- '<|vision_start|><|image_pad|><|vision_end|>' }}
29
+ {%- elif 'video' in item or item.type == 'video' %}
30
+ {%- if is_system_content %}
31
+ {{- raise_exception('System/developer message cannot contain videos.') }}
32
+ {%- endif %}
33
+ {%- if do_vision_count %}
34
+ {%- set video_count.value = video_count.value + 1 %}
35
+ {%- endif %}
36
+ {%- if add_vision_id %}
37
+ {{- 'Video ' ~ video_count.value ~ ': ' }}
38
+ {%- endif %}
39
+ {{- '<|vision_start|><|video_pad|><|vision_end|>' }}
40
+ {%- elif 'text' in item %}
41
+ {{- item.text }}
42
+ {%- else %}
43
+ {{- raise_exception('Unexpected item type in content.') }}
44
+ {%- endif %}
45
+ {%- endfor %}
46
+ {%- elif content is none or content is undefined %}
47
+ {{- '' }}
48
+ {%- else %}
49
+ {{- raise_exception('Unexpected content type.') }}
50
+ {%- endif %}
51
+ {%- endmacro %}
52
+ {%- if not messages %}
53
+ {{- raise_exception('No messages provided.') }}
54
+ {%- endif %}
55
+ {%- for message in messages %}
56
+ {%- if not ns.seen_non_instruction and (message.role == 'system' or message.role == 'developer') %}
57
+ {%- set ns.instruction_prefix_count = ns.instruction_prefix_count + 1 %}
58
+ {%- else %}
59
+ {%- set ns.seen_non_instruction = true %}
60
+ {%- endif %}
61
+ {%- endfor %}
62
+ {%- if tools and tools is iterable and tools is not mapping %}
63
+ {{- '<|im_start|>system\n' }}
64
+ {{- "# Tools\n\nYou have access to the following functions:\n\n<tools>" }}
65
+ {%- for tool in tools %}
66
+ {{- "\n" }}
67
+ {{- tool | tojson }}
68
+ {%- endfor %}
69
+ {{- "\n</tools>" }}
70
+ {{- '\n\nIf you choose to call a function ONLY reply in the following format with NO suffix:\n\n<tool_call>\n<function=example_function_name>\n<parameter=example_parameter_1>\nvalue_1\n</parameter>\n<parameter=example_parameter_2>\nThis is the value for the second parameter\nthat can span\nmultiple lines\n</parameter>\n</function>\n</tool_call>\n\n<IMPORTANT>\nReminder:\n- Function calls MUST follow the specified format: an inner <function=...></function> block must be nested within <tool_call></tool_call> XML tags\n- Required parameters MUST be specified\n- You may provide optional reasoning for your function call in natural language BEFORE the function call, but NOT after\n- If there is no function call available, answer the question like normal with your current knowledge and do not tell the user about function calls\n</IMPORTANT>' }}
71
+ {%- if ns.instruction_prefix_count > 0 %}
72
+ {%- for instruction in messages[:ns.instruction_prefix_count] %}
73
+ {%- set content = render_content(instruction.content, false, true)|trim %}
74
+ {%- if content %}
75
+ {{- '\n\n' + content }}
76
+ {%- endif %}
77
+ {%- endfor %}
78
+ {%- endif %}
79
+ {{- '<|im_end|>\n' }}
80
+ {%- else %}
81
+ {%- if ns.instruction_prefix_count > 0 %}
82
+ {{- '<|im_start|>system\n' }}
83
+ {%- for instruction in messages[:ns.instruction_prefix_count] %}
84
+ {%- set content = render_content(instruction.content, false, true)|trim %}
85
+ {%- if content %}
86
+ {%- if not loop.first %}
87
+ {{- '\n\n' }}
88
+ {%- endif %}
89
+ {{- content }}
90
+ {%- endif %}
91
+ {%- endfor %}
92
+ {{- '<|im_end|>\n' }}
93
+ {%- endif %}
94
+ {%- endif %}
95
+ {%- for message in messages[::-1] %}
96
+ {%- set index = (messages|length - 1) - loop.index0 %}
97
+ {%- if ns.multi_step_tool and message.role == "user" %}
98
+ {%- set content = render_content(message.content, false)|trim %}
99
+ {%- if not(content.startswith('<tool_response>') and content.endswith('</tool_response>')) %}
100
+ {%- set ns.multi_step_tool = false %}
101
+ {%- set ns.last_query_index = index %}
102
+ {%- endif %}
103
+ {%- endif %}
104
+ {%- endfor %}
105
+ {%- if ns.multi_step_tool %}
106
+ {{- raise_exception('No user query found in messages.') }}
107
+ {%- endif %}
108
+ {%- set conversation = messages[ns.instruction_prefix_count:] %}
109
+ {%- set last_query_conv_index = ns.last_query_index - ns.instruction_prefix_count %}
110
+ {%- for message in conversation %}
111
+ {%- set role = 'system' if message.role == 'developer' else message.role %}
112
+ {%- set content = render_content(message.content, true, role == 'system')|trim %}
113
+ {%- if role == "system" %}
114
+ {{- raise_exception('System/developer messages must appear before the first user/assistant/tool message.') }}
115
+ {%- elif role == "user" %}
116
+ {{- '<|im_start|>' + role + '\n' + content + '<|im_end|>' + '\n' }}
117
+ {%- elif role == "assistant" %}
118
+ {%- set reasoning_content = '' %}
119
+ {%- if message.reasoning_content is string %}
120
+ {%- set reasoning_content = message.reasoning_content %}
121
+ {%- else %}
122
+ {%- if '</think>' in content %}
123
+ {%- set reasoning_content = content.split('</think>')[0].rstrip('\n').split('<think>')[-1].lstrip('\n') %}
124
+ {%- set content = content.split('</think>')[-1].lstrip('\n') %}
125
+ {%- endif %}
126
+ {%- endif %}
127
+ {%- set reasoning_content = reasoning_content|trim %}
128
+ {%- if loop.index0 > last_query_conv_index %}
129
+ {{- '<|im_start|>' + role + '\n<think>\n' + reasoning_content + '\n</think>\n\n' + content }}
130
+ {%- else %}
131
+ {{- '<|im_start|>' + role + '\n' + content }}
132
+ {%- endif %}
133
+ {%- if message.tool_calls and message.tool_calls is iterable and message.tool_calls is not mapping %}
134
+ {%- for tool_call in message.tool_calls %}
135
+ {%- if tool_call.function is defined %}
136
+ {%- set tool_call = tool_call.function %}
137
+ {%- endif %}
138
+ {%- if loop.first %}
139
+ {%- if content|trim %}
140
+ {{- '\n\n<tool_call>\n<function=' + tool_call.name + '>\n' }}
141
+ {%- else %}
142
+ {{- '<tool_call>\n<function=' + tool_call.name + '>\n' }}
143
+ {%- endif %}
144
+ {%- else %}
145
+ {{- '\n<tool_call>\n<function=' + tool_call.name + '>\n' }}
146
+ {%- endif %}
147
+ {%- if tool_call.arguments is defined %}
148
+ {%- for args_name, args_value in tool_call.arguments|items %}
149
+ {{- '<parameter=' + args_name + '>\n' }}
150
+ {%- set args_value = args_value | tojson | safe if args_value is mapping or (args_value is sequence and args_value is not string) else args_value | string %}
151
+ {{- args_value }}
152
+ {{- '\n</parameter>\n' }}
153
+ {%- endfor %}
154
+ {%- endif %}
155
+ {{- '</function>\n</tool_call>' }}
156
+ {%- endfor %}
157
+ {%- endif %}
158
+ {{- '<|im_end|>\n' }}
159
+ {%- elif role == "tool" %}
160
+ {%- if loop.previtem and ('system' if loop.previtem.role == 'developer' else loop.previtem.role) != "tool" %}
161
+ {{- '<|im_start|>user' }}
162
+ {%- endif %}
163
+ {{- '\n<tool_response>\n' }}
164
+ {{- content }}
165
+ {{- '\n</tool_response>' }}
166
+ {%- if not loop.last and ('system' if loop.nextitem.role == 'developer' else loop.nextitem.role) != "tool" %}
167
+ {{- '<|im_end|>\n' }}
168
+ {%- elif loop.last %}
169
+ {{- '<|im_end|>\n' }}
170
+ {%- endif %}
171
+ {%- else %}
172
+ {{- raise_exception('Unexpected message role.') }}
173
+ {%- endif %}
174
+ {%- endfor %}
175
+ {%- if add_generation_prompt %}
176
+ {{- '<|im_start|>assistant\n' }}
177
+ {%- if enable_thinking is defined and enable_thinking is false %}
178
+ {{- '<think>\n\n</think>\n\n' }}
179
+ {%- else %}
180
+ {{- '<think>\n' }}
181
+ {%- endif %}
182
+ {%- endif %}
@@ -0,0 +1,193 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "customColumns": {},
4
+ "defaultSummaryFields": [
5
+ "title",
6
+ "tags"
7
+ ],
8
+ "vaultFileTypes": [
9
+ "md",
10
+ "txt",
11
+ "pdf",
12
+ "docx",
13
+ "pptx",
14
+ "xlsx",
15
+ "csv",
16
+ "json",
17
+ "yaml",
18
+ "yml"
19
+ ],
20
+ "commonEdges": {
21
+ "relatedPages": {
22
+ "edgeType": "related",
23
+ "resolve": "path"
24
+ },
25
+ "sourceRefs": {
26
+ "edgeType": "sourced_from",
27
+ "resolve": "path",
28
+ "match": "\\.md$"
29
+ }
30
+ },
31
+ "templates": {
32
+ "concept": {
33
+ "file": "templates/concept.md",
34
+ "columns": {
35
+ "confidence": "text",
36
+ "masteryLevel": "text"
37
+ },
38
+ "edges": {
39
+ "prerequisites": {
40
+ "edgeType": "prerequisite",
41
+ "resolve": "nodeId"
42
+ }
43
+ },
44
+ "summaryFields": [
45
+ "confidence",
46
+ "masteryLevel",
47
+ "prerequisites"
48
+ ]
49
+ },
50
+ "misconception": {
51
+ "file": "templates/misconception.md",
52
+ "columns": {
53
+ "severity": "text",
54
+ "resolvedAt": "text"
55
+ },
56
+ "edges": {
57
+ "correctedConcepts": {
58
+ "edgeType": "corrects",
59
+ "resolve": "nodeId"
60
+ }
61
+ },
62
+ "summaryFields": [
63
+ "severity",
64
+ "correctedConcepts"
65
+ ]
66
+ },
67
+ "bridge": {
68
+ "file": "templates/bridge.md",
69
+ "columns": {
70
+ "fromCourse": "text",
71
+ "toCourse": "text",
72
+ "transferType": "text"
73
+ },
74
+ "edges": {
75
+ "fromConcepts": {
76
+ "edgeType": "bridges_from",
77
+ "resolve": "nodeId"
78
+ },
79
+ "toConcepts": {
80
+ "edgeType": "bridges_to",
81
+ "resolve": "nodeId"
82
+ }
83
+ },
84
+ "summaryFields": [
85
+ "fromCourse",
86
+ "toCourse",
87
+ "transferType"
88
+ ]
89
+ },
90
+ "source-summary": {
91
+ "file": "templates/source-summary.md",
92
+ "columns": {
93
+ "sourceType": "text",
94
+ "vaultPath": "text"
95
+ },
96
+ "edges": {},
97
+ "summaryFields": [
98
+ "sourceType",
99
+ "keyFindings"
100
+ ]
101
+ },
102
+ "lesson": {
103
+ "file": "templates/lesson.md",
104
+ "columns": {
105
+ "context": "text",
106
+ "severity": "text",
107
+ "actionable": "text"
108
+ },
109
+ "edges": {},
110
+ "summaryFields": [
111
+ "context",
112
+ "severity"
113
+ ]
114
+ },
115
+ "method": {
116
+ "file": "templates/method.md",
117
+ "columns": {
118
+ "domain": "text",
119
+ "effectiveness": "text"
120
+ },
121
+ "edges": {},
122
+ "summaryFields": [
123
+ "domain",
124
+ "applicableTo",
125
+ "effectiveness"
126
+ ]
127
+ },
128
+ "person": {
129
+ "file": "templates/person.md",
130
+ "columns": {
131
+ "role": "text",
132
+ "context": "text",
133
+ "contact": "text"
134
+ },
135
+ "edges": {},
136
+ "summaryFields": [
137
+ "role",
138
+ "context",
139
+ "contact"
140
+ ]
141
+ },
142
+ "achievement": {
143
+ "file": "templates/achievement.md",
144
+ "columns": {
145
+ "achievementType": "text",
146
+ "date": "text",
147
+ "issuer": "text",
148
+ "verifiable": "text"
149
+ },
150
+ "edges": {},
151
+ "summaryFields": [
152
+ "achievementType",
153
+ "date",
154
+ "issuer",
155
+ "verifiable"
156
+ ]
157
+ },
158
+ "resume": {
159
+ "file": "templates/resume.md",
160
+ "columns": {
161
+ "targetAudience": "text",
162
+ "lastReviewedAt": "text"
163
+ },
164
+ "edges": {},
165
+ "summaryFields": [
166
+ "targetAudience",
167
+ "lastReviewedAt"
168
+ ]
169
+ },
170
+ "research-note": {
171
+ "file": "templates/research-note.md",
172
+ "columns": {
173
+ "researchTopic": "text",
174
+ "stage": "text"
175
+ },
176
+ "edges": {},
177
+ "summaryFields": [
178
+ "researchTopic",
179
+ "stage"
180
+ ]
181
+ },
182
+ "faq": {
183
+ "file": "templates/faq.md",
184
+ "columns": {
185
+ "frequency": "text"
186
+ },
187
+ "edges": {},
188
+ "summaryFields": [
189
+ "frequency"
190
+ ]
191
+ }
192
+ }
193
+ }
@@ -0,0 +1,77 @@
1
+ import path from "node:path";
2
+ import { loadRuntimeConfig } from "../core/runtime.js";
3
+ import { EmbeddingClient } from "../core/embedding.js";
4
+ import { getWikiAgentStatus } from "../core/vault-processing.js";
5
+ import { resolveTemplateFilePath } from "../core/config.js";
6
+ import { AppError } from "../utils/errors.js";
7
+ import { ensureTextOrJson, formatKeyValueLines, writeJson, writeText } from "../utils/output.js";
8
+ import { pathExistsSync } from "../utils/fs.js";
9
+ export function registerCheckConfigCommand(program) {
10
+ program
11
+ .command("check-config")
12
+ .description("Validate environment variables, config, templates, and optionally the embedding endpoint")
13
+ .option("--probe", "Probe the embedding endpoint when configured")
14
+ .option("--format <format>", "Output format: text or json", "text")
15
+ .action(async (options) => {
16
+ const format = ensureTextOrJson(options.format);
17
+ const { paths, config } = loadRuntimeConfig(process.env);
18
+ const embeddingClient = EmbeddingClient.fromEnv(process.env);
19
+ const wikiAgent = getWikiAgentStatus(process.env);
20
+ if (wikiAgent.enabled && wikiAgent.missing.length > 0) {
21
+ throw new AppError(`WIKI_AGENT_ENABLED=true but missing required settings: ${wikiAgent.missing.join(", ")}`, "config");
22
+ }
23
+ const templateChecks = Object.keys(config.templates).map((pageType) => {
24
+ const templatePath = resolveTemplateFilePath(config, paths.wikiRoot, pageType);
25
+ return {
26
+ pageType,
27
+ templatePath,
28
+ exists: pathExistsSync(templatePath),
29
+ };
30
+ });
31
+ let probe = "skipped";
32
+ if (options.probe && embeddingClient) {
33
+ await embeddingClient.probe();
34
+ probe = "ok";
35
+ }
36
+ else if (options.probe) {
37
+ probe = "not_configured";
38
+ }
39
+ const payload = {
40
+ wikiPath: paths.wikiPath,
41
+ vaultPath: paths.vaultPath,
42
+ dbPath: paths.dbPath,
43
+ configPath: paths.configPath,
44
+ templatesPath: paths.templatesPath,
45
+ configVersion: config.configVersion,
46
+ embeddingConfigured: embeddingClient !== null,
47
+ agentProcessing: wikiAgent,
48
+ probe,
49
+ templateChecks,
50
+ };
51
+ if (format === "json") {
52
+ writeJson(payload);
53
+ return;
54
+ }
55
+ writeText([
56
+ "tiangong-wiki check-config",
57
+ formatKeyValueLines({
58
+ wikiPath: paths.wikiPath,
59
+ vaultPath: paths.vaultPath,
60
+ dbPath: paths.dbPath,
61
+ configPath: paths.configPath,
62
+ templatesPath: paths.templatesPath,
63
+ embeddingConfigured: embeddingClient !== null,
64
+ agentEnabled: wikiAgent.enabled,
65
+ agentConfigured: wikiAgent.configured,
66
+ agentBaseUrl: wikiAgent.baseUrl ?? "",
67
+ agentModel: wikiAgent.model ?? "",
68
+ agentBatchSize: wikiAgent.batchSize,
69
+ agentWorkflowTimeoutSeconds: wikiAgent.workflowTimeoutSeconds,
70
+ agentMissing: wikiAgent.missing.join(", "),
71
+ probe,
72
+ }),
73
+ "",
74
+ ...templateChecks.map((entry) => `${entry.exists ? "OK" : "MISSING"} ${entry.pageType} -> ${path.relative(paths.wikiRoot, entry.templatePath)}`),
75
+ ].join("\n"));
76
+ });
77
+ }
@@ -0,0 +1,32 @@
1
+ import { executeServerBackedOperation, requestDaemonJson } from "../daemon/client.js";
2
+ import { createPage } from "../operations/write.js";
3
+ import { writeJson } from "../utils/output.js";
4
+ export function registerCreateCommand(program) {
5
+ program
6
+ .command("create")
7
+ .description("Create a new wiki page from a registered template and index it immediately")
8
+ .requiredOption("--type <pageType>", "Registered pageType")
9
+ .requiredOption("--title <title>", "Page title")
10
+ .option("--node-id <nodeId>", "Optional nodeId")
11
+ .action(async (options) => {
12
+ const result = await executeServerBackedOperation({
13
+ kind: "write",
14
+ local: () => createPage(process.env, {
15
+ type: options.type,
16
+ title: options.title,
17
+ nodeId: options.nodeId ?? undefined,
18
+ }),
19
+ remote: (endpoint) => requestDaemonJson({
20
+ endpoint,
21
+ method: "POST",
22
+ path: "/create",
23
+ body: {
24
+ type: options.type,
25
+ title: options.title,
26
+ nodeId: options.nodeId ?? undefined,
27
+ },
28
+ }),
29
+ });
30
+ writeJson(result);
31
+ });
32
+ }