@topmindspace/topmind-skills 4.13.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 (68) hide show
  1. package/INSTALL.md +295 -0
  2. package/LICENSE +21 -0
  3. package/README.en.md +162 -0
  4. package/README.md +162 -0
  5. package/README.zh-CN.md +162 -0
  6. package/bin/install-skills.mjs +693 -0
  7. package/evals/evals.json +236 -0
  8. package/install-targets/claude-code.json +62 -0
  9. package/install-targets/codex.json +60 -0
  10. package/install-targets/hermes.json +60 -0
  11. package/install-targets/opencode.json +63 -0
  12. package/integrations/codex/README.md +20 -0
  13. package/integrations/hermes/README.md +19 -0
  14. package/integrations/opencode/README.md +33 -0
  15. package/integrations/opencode/commands/topmind-capture.md +15 -0
  16. package/integrations/opencode/commands/topmind-doctor.md +11 -0
  17. package/integrations/opencode/opencode.example.json +20 -0
  18. package/integrations/opencode/plugins/topmind-plugin.ts +17 -0
  19. package/integrations/opencode/tests/opencode-config-shape.test.mjs +63 -0
  20. package/package.json +70 -0
  21. package/scripts/build-pack.mjs +463 -0
  22. package/shared/capability-degradation.md +82 -0
  23. package/shared/document-ingest.md +117 -0
  24. package/shared/host-loading.md +140 -0
  25. package/shared/long-url-capture.md +60 -0
  26. package/shared/output-language.md +32 -0
  27. package/shared/project-model-brief.md +132 -0
  28. package/shared/trigger-disambiguation.md +58 -0
  29. package/shared/writeback-receipt.md +73 -0
  30. package/skills.md +39 -0
  31. package/topmind/SKILL.md +170 -0
  32. package/topmind/references/connector-resolution.md +11 -0
  33. package/topmind/references/multi-intent.md +17 -0
  34. package/topmind/references/template-categories.md +45 -0
  35. package/topmind-capture/SKILL.md +148 -0
  36. package/topmind-ledger/SKILL.md +86 -0
  37. package/topmind-loop/DESIGN.md +82 -0
  38. package/topmind-loop/SKILL.md +111 -0
  39. package/topmind-loop/references/scopes-and-walk.md +56 -0
  40. package/topmind-loop/references/state-file.md +52 -0
  41. package/topmind-maintain/SKILL.md +104 -0
  42. package/topmind-memory/SKILL.md +117 -0
  43. package/topmind-organize/SKILL.md +144 -0
  44. package/topmind-pack.json +418 -0
  45. package/topmind-wechat/DESIGN.md +50 -0
  46. package/topmind-wechat/SKILL.md +218 -0
  47. package/topmind-wechat/assets/themes/amber-review.json +35 -0
  48. package/topmind-wechat/assets/themes/graphite.json +35 -0
  49. package/topmind-wechat/assets/themes/minimal-ink.json +35 -0
  50. package/topmind-wechat/assets/themes/newsprint.json +35 -0
  51. package/topmind-wechat/assets/themes/tech-blue.json +35 -0
  52. package/topmind-wechat/references/element-spec.md +162 -0
  53. package/topmind-wechat/references/known-pits.md +86 -0
  54. package/topmind-wechat/references/theme-map.md +139 -0
  55. package/topmind-wechat/references/typography-rules.md +62 -0
  56. package/topmind-wechat/references/wechat-constraints.md +106 -0
  57. package/topmind-wechat/references/workflow.md +102 -0
  58. package/topmind-wechat/references/writing-quality.md +129 -0
  59. package/topmind-wechat/scripts/lint-wechat.py +446 -0
  60. package/topmind-wechat/scripts/md2wechat.py +1599 -0
  61. package/topmind-wechat/scripts/new-article.py +183 -0
  62. package/topmind-wechat/scripts/push-to-topstream.py +226 -0
  63. package/topmind-wechat/scripts/scan_ai_flavor.py +464 -0
  64. package/topmind-wechat/scripts/sync-mapping.py +220 -0
  65. package/topmind-wechat/scripts/sync-status.py +187 -0
  66. package/topmind-weread/SKILL.md +97 -0
  67. package/topmind-write/SKILL.md +116 -0
  68. package/topmind-x/SKILL.md +97 -0
@@ -0,0 +1,418 @@
1
+ {
2
+ "schema_version": 1,
3
+ "name": "topmind",
4
+ "label": "topmind",
5
+ "description": "topmind skill pack: single daily entry topmind + progressive disclosure (shared/ + references/), Agent Skills open-standard aligned, capture-first template-driven categories, optional weread/x connectors and optional ledger (记账). File-system-first content truth; UTR optional.",
6
+ "daily_entry": "topmind",
7
+ "version": "4.13.0",
8
+ "updated": "2026-09-23",
9
+ "license": "MIT",
10
+ "locales": {
11
+ "default": "zh-CN",
12
+ "available": [
13
+ "zh-CN"
14
+ ],
15
+ "overlay_mechanism": "Skill dirs may contain locales/{locale}/ with overlay files; installer applies overlay at install time when --locale is specified. No overlay is shipped yet; --locale falls back to the base (zh-CN) files."
16
+ },
17
+ "homepage": "https://github.com/topmindspace/topmind-skills#readme",
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "https://github.com/topmindspace/topmind-skills.git"
21
+ },
22
+ "bugs": {
23
+ "url": "https://github.com/topmindspace/topmind-skills/issues"
24
+ },
25
+ "keywords": [
26
+ "skill-pack",
27
+ "personal-knowledge",
28
+ "capture-first",
29
+ "category-first",
30
+ "topic-emerges",
31
+ "file-system-truth",
32
+ "agent-skills",
33
+ "portable",
34
+ "markdown-only",
35
+ "anthropic-skills",
36
+ "cursor-rules",
37
+ "obsidian-friendly"
38
+ ],
39
+ "metadata": {
40
+ "license": "MIT",
41
+ "authors": [
42
+ {
43
+ "name": "TopMindSpace",
44
+ "github": "topmindspace"
45
+ }
46
+ ],
47
+ "repository": "https://github.com/topmindspace/topmind-skills",
48
+ "homepage": "https://github.com/topmindspace/topmind-skills#readme",
49
+ "issues": "https://github.com/topmindspace/topmind-skills/issues",
50
+ "keywords": [
51
+ "skill-pack",
52
+ "personal-knowledge",
53
+ "capture-first",
54
+ "category-first",
55
+ "topic-emerges",
56
+ "file-system-truth",
57
+ "agent-skills",
58
+ "portable",
59
+ "markdown-only",
60
+ "anthropic-skills",
61
+ "cursor-rules",
62
+ "obsidian-friendly"
63
+ ],
64
+ "compatibility": {
65
+ "hosts": [
66
+ "opencode",
67
+ "hermes",
68
+ "codex",
69
+ "claude-code",
70
+ "mcp",
71
+ "obsidian"
72
+ ],
73
+ "runtime": "pure-markdown",
74
+ "optional_dependencies": {
75
+ "utr": "node >= 18, optional deterministic CLI/MCP commands",
76
+ "desktop": "Electron, optional GUI client (topmind-desktop/)"
77
+ }
78
+ },
79
+ "content_schema": {
80
+ "_disambiguation_note": "The frontmatter `action_category` key refers to the action-skill taxonomy (capture|organize|write|memory|maintain|loop|router|connector). User note frontmatter has a `category` field, but there it means the physical category directory name (e.g. template-defined name like research category). Different keys, different meanings — no collision.",
81
+ "frontmatter_required_fields": [
82
+ "name",
83
+ "version",
84
+ "description",
85
+ "action_category",
86
+ "triggers"
87
+ ],
88
+ "frontmatter_optional_fields": [
89
+ "tags",
90
+ "entrypoint",
91
+ "degradation",
92
+ "author",
93
+ "license",
94
+ "homepage",
95
+ "updated",
96
+ "compatibility"
97
+ ],
98
+ "frontmatter_description_rules": [
99
+ "max 1024 characters (Agent Skills open standard)",
100
+ "structure: what it does + Use when (zh/en phrases) + Do NOT use (negative boundary)",
101
+ "include when-to-use triggers (zh/en phrases users actually say)",
102
+ "include when-not-to-use boundaries to reduce false activation",
103
+ "description is the progressive-disclosure discovery signal",
104
+ "sub-skills must not use over-broad phrasing that steals sibling activation",
105
+ "router prefers multi-intent/ambiguous; single clear verbs prefer action skills"
106
+ ],
107
+ "progressive_disclosure": {
108
+ "discovery": "name + description only (~100 tokens/skill)",
109
+ "activation": "full SKILL.md body when matched",
110
+ "resources": "shared/*.md and skill references/* loaded on demand",
111
+ "host_loading": "skills/shared/host-loading.md",
112
+ "shared_must_be_sibling": "install shared/ next to skill dirs so ../shared/ resolves"
113
+ },
114
+ "frontmatter_action_categories": [
115
+ "capture",
116
+ "organize",
117
+ "write",
118
+ "memory",
119
+ "maintain",
120
+ "loop",
121
+ "router",
122
+ "connector"
123
+ ]
124
+ }
125
+ },
126
+ "entry_files": [
127
+ "topmind/SKILL.md",
128
+ "topmind-capture/SKILL.md",
129
+ "topmind-organize/SKILL.md",
130
+ "topmind-write/SKILL.md",
131
+ "topmind-memory/SKILL.md",
132
+ "topmind-maintain/SKILL.md",
133
+ "topmind-loop/SKILL.md",
134
+ "topmind-weread/SKILL.md",
135
+ "topmind-x/SKILL.md",
136
+ "topmind-ledger/SKILL.md",
137
+ "topmind-wechat/SKILL.md"
138
+ ],
139
+ "skills": [
140
+ {
141
+ "id": "topmind",
142
+ "path": "topmind",
143
+ "role": "router",
144
+ "human_facing": true
145
+ },
146
+ {
147
+ "id": "topmind-capture",
148
+ "path": "topmind-capture",
149
+ "role": "capture",
150
+ "human_facing": false
151
+ },
152
+ {
153
+ "id": "topmind-organize",
154
+ "path": "topmind-organize",
155
+ "role": "organize",
156
+ "human_facing": false
157
+ },
158
+ {
159
+ "id": "topmind-write",
160
+ "path": "topmind-write",
161
+ "role": "write",
162
+ "human_facing": false
163
+ },
164
+ {
165
+ "id": "topmind-memory",
166
+ "path": "topmind-memory",
167
+ "role": "memory",
168
+ "human_facing": false
169
+ },
170
+ {
171
+ "id": "topmind-maintain",
172
+ "path": "topmind-maintain",
173
+ "role": "maintain",
174
+ "human_facing": false
175
+ },
176
+ {
177
+ "id": "topmind-loop",
178
+ "path": "topmind-loop",
179
+ "role": "loop",
180
+ "human_facing": false
181
+ },
182
+ {
183
+ "id": "topmind-weread",
184
+ "path": "topmind-weread",
185
+ "role": "connector",
186
+ "human_facing": false,
187
+ "optional": true
188
+ },
189
+ {
190
+ "id": "topmind-x",
191
+ "path": "topmind-x",
192
+ "role": "connector",
193
+ "human_facing": false,
194
+ "optional": true
195
+ },
196
+ {
197
+ "id": "topmind-ledger",
198
+ "path": "topmind-ledger",
199
+ "role": "memory",
200
+ "human_facing": false,
201
+ "optional": true
202
+ },
203
+ {
204
+ "id": "topmind-wechat",
205
+ "path": "topmind-wechat",
206
+ "role": "write",
207
+ "human_facing": false,
208
+ "optional": true,
209
+ "parent_skill": "topmind-write",
210
+ "note": "write-family sub-skill for WeChat MP articles (not a daily front door)"
211
+ }
212
+ ],
213
+ "product_contract": {
214
+ "capture_first": true,
215
+ "category_first": true,
216
+ "topic_emerges": true,
217
+ "action_first": true,
218
+ "single_user_entry": true,
219
+ "content_truth": "topmind-workspace/categories-and-topics",
220
+ "inbox_role": "unassigned-capture",
221
+ "topic_role": "assigned-work",
222
+ "loose_note_role": "unfiled-but-categorized"
223
+ },
224
+ "category_slots": {
225
+ "_mode": "template-driven-dynamic-discovery",
226
+ "_templates": [
227
+ "stream",
228
+ "balanced",
229
+ "research",
230
+ "periodic"
231
+ ],
232
+ "_default_template": "stream",
233
+ "_note": "默认 stream(Inbox+动态+交付+归档)。topmind.yaml contract v4 含 stream.packing / memory.layers。解析 lib/workspace-model.mjs + stream-period.mjs。"
234
+ },
235
+ "category_roles": [
236
+ "buffer",
237
+ "loose-stream",
238
+ "deep-work",
239
+ "fallback",
240
+ "reference",
241
+ "delivery",
242
+ "system"
243
+ ],
244
+ "category_rules": [
245
+ "dynamic_discovery: {NN}[- ]{Name}/ 自发现;属性 overrides > extensions > template > deep-work",
246
+ "config_v4: categories.extensions 用户扩展类;categories.overrides 含 hidden;contract_version 4",
247
+ "workspace_model: Skills/UTR/Desktop 同一语义;list-categories 返回 CategoryDescriptor",
248
+ "no_overlap: 同一内容/主题只能在一个大类下,按内容性质判定",
249
+ "stream_packing: stream.packing=weekly|daily|monthly|atom;默认 weekly 周期本 append",
250
+ "core_memory: memory.dir + profileFile(默认 profile.md)可配置记忆目录",
251
+ "topic_emerges: 默认不建专题;反复出现时建议升专题",
252
+ "template_flat_default: specialBehavior='flat-default' 的类别默认平铺(持续流),强主题才专题化",
253
+ "template_catch_all: catchAll=true 的类别每 retentionDays 天清理一次(默认 30)",
254
+ "template_reference_only: referenceOnly=true 的类别只放反复引用的素材",
255
+ "category_naming_stable: 大类名不轻易改;改走 renameCategory(目录+frontmatter+config)",
256
+ "hidden_categories: overrides.hidden 侧栏/索引/connector 默认跳过,不删盘",
257
+ "spaced_numbering: 10/20/30/40/50/60 间隔便于插入自定义槽位",
258
+ "connector_hints: 模板 connectorHints;可被 connectorDefaults 覆盖"
259
+ ],
260
+ "topic_naming": {
261
+ "format": "YYYY-主题",
262
+ "style": "kebab-case",
263
+ "project_id_field_renamed_to": "topic",
264
+ "deprecated_field": "project_type"
265
+ },
266
+ "writeback_modes": [
267
+ "auto",
268
+ "confirm"
269
+ ],
270
+ "surfaces": [
271
+ "codex",
272
+ "hermes",
273
+ "opencode",
274
+ "claude-code",
275
+ "desktop",
276
+ "mcp",
277
+ "obsidian"
278
+ ],
279
+ "portable_contract": {
280
+ "requires_desktop": false,
281
+ "requires_utr": false,
282
+ "content_truth": "topmind-workspace/categories-and-topics",
283
+ "host_may_provide": [
284
+ "skills",
285
+ "cli",
286
+ "mcp",
287
+ "commands",
288
+ "plugins",
289
+ "desktop"
290
+ ],
291
+ "host_must_not": [
292
+ "change-content-truth",
293
+ "add-daily-entrypoints",
294
+ "fork-skill-semantics",
295
+ "persist-content-in-agent-state",
296
+ "introduce-legacy-project-naming",
297
+ "introduce-project_type-field"
298
+ ]
299
+ },
300
+ "install_targets": [
301
+ {
302
+ "id": "opencode",
303
+ "path": "install-targets/opencode.json"
304
+ },
305
+ {
306
+ "id": "hermes",
307
+ "path": "install-targets/hermes.json"
308
+ },
309
+ {
310
+ "id": "codex",
311
+ "path": "install-targets/codex.json"
312
+ },
313
+ {
314
+ "id": "claude-code",
315
+ "path": "install-targets/claude-code.json"
316
+ }
317
+ ],
318
+ "utr": {
319
+ "optional": true,
320
+ "canonical_external_surface": "topmind-cli-or-mcp",
321
+ "degradation": "host-file-tools primary; optional UTR accelerate; conversation-only fallback. See PRODUCT-BOUNDARIES.md",
322
+ "command_domains": [
323
+ "workspace-read",
324
+ "workspace-write",
325
+ "workspace-transform",
326
+ "workspace-maintain",
327
+ "contract",
328
+ "memory",
329
+ "lifecycle",
330
+ "derived"
331
+ ],
332
+ "kind_naming_legacy": "Domain names (workspace-read / workspace-write / workspace-transform / workspace-maintain / contract / memory / lifecycle / derived) are stable identifiers. Command names follow the topic-and-category vocabulary.",
333
+ "command_vocabulary": {
334
+ "workspace-read": [
335
+ "list-categories",
336
+ "list-topics",
337
+ "inspect-topic",
338
+ "list-topic-files",
339
+ "list-inbox",
340
+ "list-recent-captures",
341
+ "list-safety-receipts"
342
+ ],
343
+ "workspace-write": [
344
+ "create-topic",
345
+ "capture-note",
346
+ "save-output",
347
+ "update-topic"
348
+ ],
349
+ "workspace-transform": [
350
+ "plan-inbox-routing",
351
+ "normalize-note-metadata",
352
+ "migrate-v4"
353
+ ],
354
+ "workspace-maintain": [
355
+ "doctor-workspace",
356
+ "archive-topic",
357
+ "archive-stream-year",
358
+ "restore-safety-receipt",
359
+ "cleanup-empty-dirs"
360
+ ],
361
+ "contract": [
362
+ "validate",
363
+ "ensure",
364
+ "reseed"
365
+ ],
366
+ "memory": [
367
+ "promote",
368
+ "digest",
369
+ "append-profile",
370
+ "append-topic"
371
+ ],
372
+ "lifecycle": [
373
+ "scan"
374
+ ],
375
+ "derived": [
376
+ "rebuild"
377
+ ]
378
+ },
379
+ "command_count": 28,
380
+ "mcp_default_count": 19,
381
+ "command_exposure": {
382
+ "primary": [
383
+ "workspace-read.list-categories",
384
+ "workspace-read.list-topics",
385
+ "workspace-read.inspect-topic",
386
+ "workspace-read.list-topic-files",
387
+ "workspace-read.list-inbox",
388
+ "workspace-write.create-topic",
389
+ "workspace-write.capture-note",
390
+ "workspace-write.save-output",
391
+ "workspace-transform.plan-inbox-routing",
392
+ "workspace-maintain.doctor-workspace",
393
+ "contract.validate",
394
+ "memory.promote",
395
+ "memory.digest",
396
+ "memory.append-profile",
397
+ "memory.append-topic"
398
+ ],
399
+ "danger": [
400
+ "workspace-maintain.archive-topic",
401
+ "workspace-maintain.archive-stream-year",
402
+ "workspace-maintain.restore-safety-receipt",
403
+ "contract.reseed"
404
+ ],
405
+ "advanced": [
406
+ "workspace-read.list-recent-captures",
407
+ "workspace-read.list-safety-receipts",
408
+ "workspace-write.update-topic",
409
+ "workspace-transform.normalize-note-metadata",
410
+ "workspace-transform.migrate-v4",
411
+ "workspace-maintain.cleanup-empty-dirs",
412
+ "lifecycle.scan",
413
+ "derived.rebuild",
414
+ "contract.ensure"
415
+ ]
416
+ }
417
+ }
418
+ }
@@ -0,0 +1,50 @@
1
+ # topmind-wechat · 技能侧设计摘要
2
+
3
+ > 全案见 [`docs/wechat-studio-DESIGN.md`](../../../docs/wechat-studio-DESIGN.md)。本文只记技能包边界。
4
+
5
+ ## 定位
6
+
7
+ - write 族**子技能**(`action_category: write` · `entrypoint: false` · pack `optional: true`)
8
+ - 不是日常前台:由 `topmind` / `topmind-write` 在「公众号 / 微信排版」意图下路由
9
+ - 能力真源:`scripts/*.py`(stdlib)+ `references/*` + `assets/themes/*`(5 套,含 `amber-review`)
10
+
11
+ ## 路径解析
12
+
13
+ `--base` → `TOPMIND_WECHAT_BASE` → `{TOPMIND_WORKSPACE}/40-创作|20-专题/{year}-公众号`;topstream 可选(`TOPSTREAM_ROOT`)。
14
+ **禁止**把 `/Users/...` 写进脚本默认值(`~/TopWorkSpace/...` 惯例兜底允许)。
15
+
16
+ ## 三条路径
17
+
18
+ - **forward**:`notes/*.md` → 公众号稿(`source_file`)
19
+ - **reverse**:选题原创 → 公众号稿 → 可选回推(`target_file: pending`;回推**必须** `--assets`)
20
+ - **站外拉取**:在线精选站/转载整合 → 仍用 `reverse` + `pending`(站外源不进 notes)
21
+
22
+ ## 质量三关 + 排版关
23
+
24
+ 事实 / 逻辑 / 文字(scan_ai_flavor ≥85 + 报告腔四症状)→ lint 0 error → md2wechat `--embed-images`。
25
+
26
+ Desktop / 移动伴面只实现**约束子集**;完整语义以本目录 Python 为准。
27
+
28
+ ## references 索引
29
+
30
+ | 文件 | 管什么 |
31
+ |------|--------|
32
+ | `workflow.md` | 流程/状态机/路径/站外拉取 |
33
+ | `known-pits.md` | 实操坑 |
34
+ | `element-spec.md` | 元素 → HTML 渲染规格 |
35
+ | `theme-map.md` | 主题键 ↔ 题材映射 |
36
+ | `wechat-constraints.md` | 平台硬约束(转换产物) |
37
+ | `typography-rules.md` | 阅读节奏/段长 |
38
+ | `writing-quality.md` | 质量三关 |
39
+
40
+ ## 已知分叉与对拍要求
41
+
42
+ | 项 | 真源 | Desktop 子集 | 要求 |
43
+ |----|------|--------------|------|
44
+ | max-item | lint-wechat.py **70** | `WECHAT_MAX_ITEM` | 必须同值 |
45
+ | AI 结构扣分 | scan_ai_flavor.structural | `structuralDeduction()` | 同规则 |
46
+ | stat 管道行 | md2wechat 非 `\|` 丢弃 | wechat-format 同 | 同语义 |
47
+ | embed-images | `--embed-images` | `WechatService.exportViaScript` **优先**;否则 `embedLocalImagesWithChecklist` | 同效果 + 上传清单 |
48
+ | 导出真源 | `md2wechat.py` | 有 Python + 脚本时走 `wechat.exportViaScript` | 内置为回退 |
49
+
50
+ 改动任一侧规则时,**同一次改动**更新另一侧并跑 `tests/plugin-wechat-ui.test.mjs` 对拍断言。
@@ -0,0 +1,218 @@
1
+ ---
2
+ name: topmind-wechat
3
+ version: 4.13.0
4
+ description: >-
5
+ 公众号文章全生命周期子技能(write 族):交付包、审校改写、质量三关、状态同步、微信内联排版与发布清单。
6
+ 支持 forward(底稿→公众号)、reverse(选题原创→回推)、站外拉取(在线精选站→reverse+pending)三条路径;
7
+ 内置五套主题、代码高亮、宽表卡片化、前言导读、尾部签名、外链脚注、--embed-images。
8
+ Use when 写公众号、公众号排版、微信排版、定稿、发公众号、公众号交付包、wechat format、mp format。
9
+ Do NOT use for 只改错别字(直接编辑)、小红书/知乎(平台约束不同)、纯网页发布、长文通用润色(走 topmind-write)。
10
+ action_category: write
11
+ triggers:
12
+ - 公众号
13
+ - 微信排版
14
+ - 公众号排版
15
+ - 公众号稿
16
+ - 排版这篇文章
17
+ - 定稿
18
+ - 发公众号
19
+ - 公众号交付
20
+ - wechat
21
+ - mp format
22
+ tags: [wechat, typography, formatting, publishing, markdown, write]
23
+ entrypoint: false
24
+ author: TopMindSpace
25
+ license: MIT
26
+ homepage: https://github.com/topmindspace/topmind
27
+ updated: 2026-09-23
28
+ degradation: ../shared/capability-degradation.md
29
+ compatibility: topmind workspace. Writes via UTR workspace-write / Desktop WorkspaceService. Scripts need Python 3 stdlib only.
30
+ ---
31
+
32
+ # topmind-wechat · 公众号创作子技能
33
+
34
+ `topmind-write` 的**公众号专用子技能**。管一篇公众号文章从选题/底稿到发布清单的完整生命周期。
35
+
36
+ ```
37
+ 选题/底稿 → 创作 → 质量三关 → 定稿(状态+目录) → 排版 → 发布清单 →(可选)回推 notes
38
+ ```
39
+
40
+ > **不是并列前台。** 用户说「写一篇长文」→ `topmind-write`;明确公众号/微信排版才进本技能。
41
+
42
+ ## 脚本(真源)
43
+
44
+ | 脚本 | 用途 |
45
+ |------|------|
46
+ | `scripts/new-article.py` | 建交付包(骨架稿 + frontmatter + images/diagrams) |
47
+ | `scripts/sync-status.py` | 状态 ⇄ 目录名 ⇄ 字数(草稿 / 定稿 / 已发布) |
48
+ | `scripts/sync-mapping.py` | 映射一致性(frontmatter + 目录 + 可选 notes + topic 总表) |
49
+ | `scripts/push-to-topstream.py` | 可选回推:公众号稿降级为纯 Markdown notes |
50
+ | `scripts/lint-wechat.py` | 排版体检 + 自动修复(中英文间距、段长、AI 腔…) |
51
+ | `scripts/md2wechat.py` | Markdown → 全内联 HTML;**必加 `--embed-images`** |
52
+ | `scripts/scan_ai_flavor.py` | 中文去 AI 味扫描(与 `qu-aiwei-zh` 同源) |
53
+
54
+ ```bash
55
+ # 路径解析:CLI --base/--workspace → env TOPMIND_WECHAT_BASE / TOPMIND_WORKSPACE / TOPSTREAM_ROOT → 惯例
56
+ export TOPMIND_WORKSPACE=/path/to/workspace # 推荐
57
+ python3 scripts/new-article.py --slug demo --title "标题" --direction reverse
58
+ python3 scripts/lint-wechat.py --input <包>/公众号稿.md --fix
59
+ python3 scripts/scan_ai_flavor.py <包>/公众号稿.md # 目标 ≥85
60
+ python3 scripts/md2wechat.py --input <包>/公众号稿.md --out-dir <包> --slug demo \
61
+ --asset-root <素材根> --embed-images
62
+ python3 scripts/sync-status.py --set 定稿 <包> --apply
63
+ ```
64
+
65
+ 细节见 [`references/workflow.md`](references/workflow.md) · [`references/known-pits.md`](references/known-pits.md)。
66
+
67
+ ## 路径默认
68
+
69
+ | 用途 | 解析 |
70
+ |------|------|
71
+ | 交付包根 | `--base` → `TOPMIND_WECHAT_BASE` → `{ws}/40-创作/2026-公众号` 或 `{ws}/20-专题/2026-公众号` |
72
+ | 工作区 | `TOPMIND_WORKSPACE` |
73
+ | 底稿/回推 | `--topstream` → `TOPSTREAM_ROOT` → 可选;不存在则跳过 notes 校验 |
74
+ | 终稿交付 | 可 `save-output` 拷贝到 role:delivery(`88-交付/`),包仍留在创作类专题 |
75
+
76
+ ## 三条路径
77
+
78
+ ### forward(底稿 → 公众号)
79
+
80
+ ```
81
+ 底稿 notes/*.md → 审校改写 → 质量三关 → 定稿 → 排版 → 发布
82
+ ```
83
+
84
+ `new-article.py --direction forward --source-file notes/xxx.md`
85
+
86
+ ### reverse(选题原创)
87
+
88
+ ```
89
+ 选题包 → 调研素材 → 多轮改稿 → 三关 → 定稿 → 排版 → 发布 →(可选)push-to-topstream
90
+ ```
91
+
92
+ `new-article.py --direction reverse`(`target_file: pending`)
93
+
94
+ ### 站外拉取(转载整合 / 在线精选站)
95
+
96
+ 源不在本工作区、也不在 topstream `notes/` 时,**仍落 `reverse` + `target_file: pending`**。
97
+ **不要用 `forward`**:它要求 `source_file` 以 `notes/` 开头且文件真实存在,站外源必然过不了 `sync-mapping.py`。
98
+
99
+ ```bash
100
+ python3 scripts/new-article.py --slug <中文短名> --title "<标题>" --direction reverse
101
+ ```
102
+
103
+ 取源坑(Next.js 站点):正文在 RSC 载荷里,优先 `GET /api/notes/<id>`;图片在 `/api/uploads/<hash>`,记 hash→本地名映射;同图双 hash 用 `md5` 去重。差异与口径写进包内 `README.md`。
104
+
105
+ **回推纪律**:notes 保持纯 Markdown。`::: 容器` / 徽章 / `==高亮==` 只进公众号稿。回推**务必带 `--assets`**(否则 GitHub 上 `images/` 死链):
106
+
107
+ ```bash
108
+ python3 scripts/push-to-topstream.py <包> --target notes/xxx.md --assets # dry-run
109
+ python3 scripts/push-to-topstream.py <包> --target notes/xxx.md --assets --apply \
110
+ --asset-names "00-封面.jpg=01-cover.jpg,…"
111
+ ```
112
+
113
+ ## 交付包与状态
114
+
115
+ ```text
116
+ YYYY-MM-DD-<中文短名> # 草稿
117
+ YYYY-MM-DD-<中文短名>-released # 定稿 / 已发布
118
+ ├── 公众号稿.md # 唯一改稿入口
119
+ ├── <slug>-公众号版.html # 浏览器打开 → 复制正文 → 粘贴后台
120
+ ├── 图片上传清单.md
121
+ ├── images/ diagrams/
122
+ └── README.md # 包说明(可选)
123
+ ```
124
+
125
+ **frontmatter(映射真源)**
126
+
127
+ ```yaml
128
+ status: 草稿 # 草稿 | 定稿 | 已发布
129
+ direction: reverse # forward | reverse
130
+ source_file: "" # forward 填 notes/xxx.md
131
+ target_file: pending # reverse:pending | notes/xxx.md
132
+ word_count: 0 # 纯中文字数,sync-status 维护
133
+ ```
134
+
135
+ 状态与目录名**不要手改**:
136
+
137
+ ```bash
138
+ python3 scripts/sync-status.py --set 定稿 <包> --apply
139
+ ```
140
+
141
+ ## 质量三关(定稿前必过)
142
+
143
+ ### 关 1 · 事实
144
+
145
+ - 承重数字回**一手来源**;厂商口径 / 据报道 分开写
146
+ - 查不到一手来源的传闻**删**
147
+ - 改稿续写:正文已有数字**回源重核**(上一轮文本最不可信)
148
+ - 多口径(主轮/复跑)显式拆开;表格从数据源生成,禁止手抄
149
+ - 外部工具改过的稿:**先核数字再动文字**;「比值对但绝对值错」= 全段重核
150
+
151
+ ### 关 2 · 逻辑
152
+
153
+ - 单边结论旁配反方证据
154
+ - 结构前后一致;同一事实多处同值
155
+
156
+ ### 关 3 · 文字(去 AI 味)
157
+
158
+ ```bash
159
+ python3 scripts/scan_ai_flavor.py <包>/公众号稿.md # ≥85(人话)
160
+ ```
161
+
162
+ - 删套话/黑话/工程圈行话;降调段末加粗金句
163
+ - **满分 ≠ 有人味**:再查「段末金句癖 / 节奏过分整齐 / 没有场景与我 / 报告体标注」
164
+ - **口语化 ≠ 有人味**:删社交垫词(元叙述、空转过渡、姿态句)
165
+ - 判据:**这句话删掉之后,读者少知道了什么?**
166
+
167
+ 详见 [`references/writing-quality.md`](references/writing-quality.md)。
168
+
169
+ ## 排版要点(写稿时)
170
+
171
+ - 开头 150 字内钩子;单段 ≤110 字;列表项 ≤70 字
172
+ - 二级标题序号化;容器:`::: stat|pull|note|tip|warn|danger|dialogue`
173
+ - **`::: stat` 内必须是 `数值 | 说明` 管道行**,否则静默丢弃
174
+ - 评测稿:**图承担数据,正文只解读**;健康密度 **300–450 字/图**
175
+ - 个股用词红线:禁用 买入/推荐/目标价…;文末投资声明
176
+
177
+ 更多:[`references/typography-rules.md`](references/typography-rules.md) · [`references/wechat-constraints.md`](references/wechat-constraints.md)。
178
+
179
+ ## 排版与导出(必读)
180
+
181
+ ```bash
182
+ python3 scripts/md2wechat.py \
183
+ --input <包>/公众号稿.md --out-dir <包> --slug <slug> \
184
+ --asset-root <素材根> --embed-images \
185
+ [--theme assets/themes/minimal-ink.json]
186
+ ```
187
+
188
+ 1. **永远 `--embed-images`**,否则粘贴丢图(相对路径被序列化成 file://)
189
+ 2. **图片 basename 铁律**:正文引用名 = `images/` 目标名;禁止两套同名图共处
190
+ 3. 合规自检出现 `✗` 改生成器,不要手改 HTML
191
+
192
+ 坑清单:[`references/known-pits.md`](references/known-pits.md)。
193
+
194
+ ## 主题
195
+
196
+ | 文件 | 风格 | 适用 |
197
+ |------|------|------|
198
+ | `assets/themes/minimal-ink.json`(默认) | 黑白灰 + 砖红 | 深度研析 / 观点 / 随笔 |
199
+ | `assets/themes/tech-blue.json` | 科技蓝 | AI/技术 |
200
+ | `assets/themes/newsprint.json` | 报纸衬线 | 人文评论 |
201
+ | `assets/themes/graphite.json` | 石墨克制 | 严肃报告 |
202
+ | `assets/themes/amber-review.json` | 琥珀评测 | 产品评测 |
203
+
204
+ `md2wechat.py --list-themes` 看全部;`--theme genre:评测` 可按题材自动选。
205
+ 渲染规格见 [`references/element-spec.md`](references/element-spec.md) · 主题映射见 [`references/theme-map.md`](references/theme-map.md)。
206
+
207
+ **平台红线速查**(详见 [`references/wechat-constraints.md`](references/wechat-constraints.md)):禁 `div`/`pre`/`h1`/`figure`/`thead`/flex/float/gradient/shadow;表格 `table-layout` 不写 fixed;列数 ≥4 转卡片。
208
+
209
+ ## 与 Desktop「公众号创作」
210
+
211
+ Desktop mini-app(`topmind-wechat` 插件)是本技能的**可视化工作流伴面**:包列表 → 改稿 → 三关 → 预览 → 导出。写回仍走 WorkspaceService;脚本语义以本技能为准。
212
+
213
+ ## When NOT to use
214
+
215
+ - 只想改几个句子 → 直接编辑
216
+ - 小红书 / 知乎 / 掘金 → 平台约束不同
217
+ - 通用长文交付 → `topmind-write`
218
+ - 只去 AI 味不排版 → 中文走 `humanizer-zh`(先立保真边界)+ `qu-aiwei-zh`(再扫描定位);英文走 `humanizer`