@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.
- package/INSTALL.md +295 -0
- package/LICENSE +21 -0
- package/README.en.md +162 -0
- package/README.md +162 -0
- package/README.zh-CN.md +162 -0
- package/bin/install-skills.mjs +693 -0
- package/evals/evals.json +236 -0
- package/install-targets/claude-code.json +62 -0
- package/install-targets/codex.json +60 -0
- package/install-targets/hermes.json +60 -0
- package/install-targets/opencode.json +63 -0
- package/integrations/codex/README.md +20 -0
- package/integrations/hermes/README.md +19 -0
- package/integrations/opencode/README.md +33 -0
- package/integrations/opencode/commands/topmind-capture.md +15 -0
- package/integrations/opencode/commands/topmind-doctor.md +11 -0
- package/integrations/opencode/opencode.example.json +20 -0
- package/integrations/opencode/plugins/topmind-plugin.ts +17 -0
- package/integrations/opencode/tests/opencode-config-shape.test.mjs +63 -0
- package/package.json +70 -0
- package/scripts/build-pack.mjs +463 -0
- package/shared/capability-degradation.md +82 -0
- package/shared/document-ingest.md +117 -0
- package/shared/host-loading.md +140 -0
- package/shared/long-url-capture.md +60 -0
- package/shared/output-language.md +32 -0
- package/shared/project-model-brief.md +132 -0
- package/shared/trigger-disambiguation.md +58 -0
- package/shared/writeback-receipt.md +73 -0
- package/skills.md +39 -0
- package/topmind/SKILL.md +170 -0
- package/topmind/references/connector-resolution.md +11 -0
- package/topmind/references/multi-intent.md +17 -0
- package/topmind/references/template-categories.md +45 -0
- package/topmind-capture/SKILL.md +148 -0
- package/topmind-ledger/SKILL.md +86 -0
- package/topmind-loop/DESIGN.md +82 -0
- package/topmind-loop/SKILL.md +111 -0
- package/topmind-loop/references/scopes-and-walk.md +56 -0
- package/topmind-loop/references/state-file.md +52 -0
- package/topmind-maintain/SKILL.md +104 -0
- package/topmind-memory/SKILL.md +117 -0
- package/topmind-organize/SKILL.md +144 -0
- package/topmind-pack.json +418 -0
- package/topmind-wechat/DESIGN.md +50 -0
- package/topmind-wechat/SKILL.md +218 -0
- package/topmind-wechat/assets/themes/amber-review.json +35 -0
- package/topmind-wechat/assets/themes/graphite.json +35 -0
- package/topmind-wechat/assets/themes/minimal-ink.json +35 -0
- package/topmind-wechat/assets/themes/newsprint.json +35 -0
- package/topmind-wechat/assets/themes/tech-blue.json +35 -0
- package/topmind-wechat/references/element-spec.md +162 -0
- package/topmind-wechat/references/known-pits.md +86 -0
- package/topmind-wechat/references/theme-map.md +139 -0
- package/topmind-wechat/references/typography-rules.md +62 -0
- package/topmind-wechat/references/wechat-constraints.md +106 -0
- package/topmind-wechat/references/workflow.md +102 -0
- package/topmind-wechat/references/writing-quality.md +129 -0
- package/topmind-wechat/scripts/lint-wechat.py +446 -0
- package/topmind-wechat/scripts/md2wechat.py +1599 -0
- package/topmind-wechat/scripts/new-article.py +183 -0
- package/topmind-wechat/scripts/push-to-topstream.py +226 -0
- package/topmind-wechat/scripts/scan_ai_flavor.py +464 -0
- package/topmind-wechat/scripts/sync-mapping.py +220 -0
- package/topmind-wechat/scripts/sync-status.py +187 -0
- package/topmind-weread/SKILL.md +97 -0
- package/topmind-write/SKILL.md +116 -0
- package/topmind-x/SKILL.md +97 -0
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""sync-status.py — 同步公众号交付包的「状态 ⇄ 目录名 ⇄ 字数」。
|
|
4
|
+
|
|
5
|
+
规则(与专题 topic.md 的目录规范一致):
|
|
6
|
+
status = 草稿 → 目录名 YYYY-MM-DD-<中文名>
|
|
7
|
+
status = 定稿 / 已发布 → 目录名 YYYY-MM-DD-<中文名>-released
|
|
8
|
+
|
|
9
|
+
同时刷新 frontmatter 的 word_count(正文中文字数)。
|
|
10
|
+
|
|
11
|
+
Usage:
|
|
12
|
+
python3 sync-status.py # 扫描全部,只报告(dry-run)
|
|
13
|
+
python3 sync-status.py --apply # 实际重命名并回写字数
|
|
14
|
+
python3 sync-status.py --set 定稿 <包目录> # 改状态 + 同步目录名
|
|
15
|
+
python3 sync-status.py --base <专题目录>
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
import argparse
|
|
19
|
+
import os
|
|
20
|
+
import re
|
|
21
|
+
import sys
|
|
22
|
+
|
|
23
|
+
def _default_base():
|
|
24
|
+
"""交付包根:CLI --base → env TOPMIND_WECHAT_BASE → env TOPMIND_WORKSPACE 发现 → 惯例路径。"""
|
|
25
|
+
env = os.environ.get("TOPMIND_WECHAT_BASE") or os.environ.get("TOPMIND_WECHAT_PACKAGE_ROOT")
|
|
26
|
+
if env:
|
|
27
|
+
return os.path.abspath(os.path.expanduser(env))
|
|
28
|
+
ws = os.environ.get("TOPMIND_WORKSPACE")
|
|
29
|
+
if ws:
|
|
30
|
+
for rel in (
|
|
31
|
+
("40-创作", "2026-公众号"),
|
|
32
|
+
("20-专题", "2026-公众号"),
|
|
33
|
+
("88-交付", "2026-公众号"),
|
|
34
|
+
):
|
|
35
|
+
p = os.path.join(ws, *rel)
|
|
36
|
+
if os.path.isdir(p):
|
|
37
|
+
return p
|
|
38
|
+
return os.path.join(ws, "40-创作", "2026-公众号")
|
|
39
|
+
# 惯例:父工作区(可被 CLI 覆盖)
|
|
40
|
+
return os.path.join(
|
|
41
|
+
os.path.expanduser("~"), "TopWorkSpace", "topmind-workspace",
|
|
42
|
+
"40-创作", "2026-公众号")
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def _default_topstream():
|
|
46
|
+
env = os.environ.get("TOPSTREAM_ROOT") or os.environ.get("TOPMIND_TOPSTREAM")
|
|
47
|
+
if env:
|
|
48
|
+
return os.path.abspath(os.path.expanduser(env))
|
|
49
|
+
return os.path.join(os.path.expanduser("~"), "TopWorkSpace", "topstream")
|
|
50
|
+
|
|
51
|
+
DEFAULT_BASE = _default_base()
|
|
52
|
+
|
|
53
|
+
FINAL_STATUSES = ("定稿", "已发布")
|
|
54
|
+
VALID_STATUSES = ("草稿",) + FINAL_STATUSES
|
|
55
|
+
RELEASED_SUFFIX = "-released"
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def split_fm(text):
|
|
59
|
+
"""返回 (frontmatter, body, head, tail_sep);无 frontmatter 时 fm=None"""
|
|
60
|
+
if not text.startswith("---\n"):
|
|
61
|
+
return None, text, "", ""
|
|
62
|
+
i = text.find("\n---", 3)
|
|
63
|
+
if i < 0:
|
|
64
|
+
return None, text, "", ""
|
|
65
|
+
return text[4:i], text[i + 4:].lstrip("\n"), text[:4], text[i:i + 4]
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def get_field(fm, key):
|
|
69
|
+
m = re.search(r"^%s:\s*(.*)$" % re.escape(key), fm, re.M)
|
|
70
|
+
return m.group(1).strip().strip('"') if m else None
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def set_field(fm, key, val):
|
|
74
|
+
line = "%s: %s" % (key, val)
|
|
75
|
+
pat = re.compile(r"^%s:\s*.*$" % re.escape(key), re.M)
|
|
76
|
+
if pat.search(fm):
|
|
77
|
+
return pat.sub(line, fm, count=1)
|
|
78
|
+
return fm.rstrip("\n") + "\n" + line + "\n"
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def scan(base):
|
|
82
|
+
"""返回 [(dirname, status, word_count, needs_rename, target_name)]"""
|
|
83
|
+
rows = []
|
|
84
|
+
for name in sorted(os.listdir(base)):
|
|
85
|
+
pkg = os.path.join(base, name)
|
|
86
|
+
draft = os.path.join(pkg, "公众号稿.md")
|
|
87
|
+
if not os.path.isdir(pkg) or not os.path.exists(draft):
|
|
88
|
+
continue
|
|
89
|
+
text = open(draft, encoding="utf-8").read()
|
|
90
|
+
fm, body, head, sep = split_fm(text)
|
|
91
|
+
if fm is None:
|
|
92
|
+
rows.append((name, None, None, False, None, "无 frontmatter"))
|
|
93
|
+
continue
|
|
94
|
+
status = get_field(fm, "status") or "草稿"
|
|
95
|
+
cn = len(re.findall(r"[\u4e00-\u9fff]", body))
|
|
96
|
+
|
|
97
|
+
want_final = status in FINAL_STATUSES
|
|
98
|
+
stem = name[:-len(RELEASED_SUFFIX)] if name.endswith(RELEASED_SUFFIX) else name
|
|
99
|
+
target = stem + (RELEASED_SUFFIX if want_final else "")
|
|
100
|
+
rows.append((name, status, cn, target != name, target, ""))
|
|
101
|
+
return rows
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def apply_rename(base, name, target, draft_path, fm, body, head, new_fm):
|
|
105
|
+
"""写回 frontmatter 后重命名目录"""
|
|
106
|
+
open(draft_path, "w", encoding="utf-8").write("---\n" + new_fm + "\n---\n\n" + body)
|
|
107
|
+
if target != name:
|
|
108
|
+
os.rename(os.path.join(base, name), os.path.join(base, target))
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def main():
|
|
112
|
+
ap = argparse.ArgumentParser()
|
|
113
|
+
ap.add_argument("--base", default=DEFAULT_BASE)
|
|
114
|
+
ap.add_argument("--apply", action="store_true", help="实际执行(默认只报告)")
|
|
115
|
+
ap.add_argument("--set", metavar="STATUS", choices=VALID_STATUSES,
|
|
116
|
+
help="把指定包改成该状态(需配合包名)")
|
|
117
|
+
ap.add_argument("pkg", nargs="?", help="包目录名(配合 --set 使用)")
|
|
118
|
+
args = ap.parse_args()
|
|
119
|
+
|
|
120
|
+
if not os.path.isdir(args.base):
|
|
121
|
+
print("✗ 专题目录不存在:%s" % args.base)
|
|
122
|
+
return 1
|
|
123
|
+
|
|
124
|
+
# 单包改状态
|
|
125
|
+
if args.set:
|
|
126
|
+
if not args.pkg:
|
|
127
|
+
print("✗ --set 需要指定包目录名")
|
|
128
|
+
return 1
|
|
129
|
+
draft = os.path.join(args.base, args.pkg, "公众号稿.md")
|
|
130
|
+
if not os.path.exists(draft):
|
|
131
|
+
print("✗ 找不到:%s" % draft)
|
|
132
|
+
return 1
|
|
133
|
+
text = open(draft, encoding="utf-8").read()
|
|
134
|
+
fm, body, head, sep = split_fm(text)
|
|
135
|
+
if fm is None:
|
|
136
|
+
print("✗ 该文件无 frontmatter")
|
|
137
|
+
return 1
|
|
138
|
+
fm = set_field(fm, "status", args.set)
|
|
139
|
+
cn = len(re.findall(r"[\u4e00-\u9fff]", body))
|
|
140
|
+
fm = set_field(fm, "word_count", str(cn))
|
|
141
|
+
|
|
142
|
+
want_final = args.set in FINAL_STATUSES
|
|
143
|
+
stem = args.pkg[:-len(RELEASED_SUFFIX)] if args.pkg.endswith(RELEASED_SUFFIX) else args.pkg
|
|
144
|
+
target = stem + (RELEASED_SUFFIX if want_final else "")
|
|
145
|
+
|
|
146
|
+
if args.apply:
|
|
147
|
+
apply_rename(args.base, args.pkg, target, draft, fm, body, head, fm)
|
|
148
|
+
print("✓ %s → status=%s,目录 %s(%d 中文字)" % (
|
|
149
|
+
args.pkg, args.set, target if target != args.pkg else "不变", cn))
|
|
150
|
+
else:
|
|
151
|
+
print("[dry-run] %s → status=%s,目录将变为 %s" % (args.pkg, args.set, target))
|
|
152
|
+
return 0
|
|
153
|
+
|
|
154
|
+
rows = scan(args.base)
|
|
155
|
+
if not rows:
|
|
156
|
+
print("专题下没有交付包:%s" % args.base)
|
|
157
|
+
return 0
|
|
158
|
+
|
|
159
|
+
print("%-44s %-6s %8s %s" % ("包目录", "状态", "中文字", "待同步"))
|
|
160
|
+
print("-" * 84)
|
|
161
|
+
changed = 0
|
|
162
|
+
for name, status, cn, needs, target, note in rows:
|
|
163
|
+
if status is None:
|
|
164
|
+
print("%-44s %-6s %8s %s" % (name, "-", "-", note))
|
|
165
|
+
continue
|
|
166
|
+
flag = "→ " + target if needs else ""
|
|
167
|
+
print("%-44s %-6s %8s %s" % (name, status, cn, flag))
|
|
168
|
+
|
|
169
|
+
if args.apply:
|
|
170
|
+
draft = os.path.join(args.base, name, "公众号稿.md")
|
|
171
|
+
text = open(draft, encoding="utf-8").read()
|
|
172
|
+
fm, body, head, sep = split_fm(text)
|
|
173
|
+
fm = set_field(fm, "word_count", str(cn))
|
|
174
|
+
apply_rename(args.base, name, target, draft, fm, body, head, fm)
|
|
175
|
+
if needs:
|
|
176
|
+
changed += 1
|
|
177
|
+
|
|
178
|
+
if args.apply:
|
|
179
|
+
print("\n✓ 已刷新 %d 个包的 word_count,重命名 %d 个目录" % (len(rows), changed))
|
|
180
|
+
else:
|
|
181
|
+
pending = sum(1 for r in rows if r[3])
|
|
182
|
+
print("\n[dry-run] %d 个包目录名与状态不一致,加 --apply 执行" % pending)
|
|
183
|
+
return 0
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
if __name__ == "__main__":
|
|
187
|
+
sys.exit(main())
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: topmind-weread
|
|
3
|
+
version: 4.13.0
|
|
4
|
+
description: >-
|
|
5
|
+
同步微信读书划线/想法/统计到专题。Use when 微信读书、划线同步、weread、读书笔记。
|
|
6
|
+
Do NOT use for 普通 URL 捕获、仅整理、出稿、X.
|
|
7
|
+
action_category: connector
|
|
8
|
+
triggers:
|
|
9
|
+
- 微信读书
|
|
10
|
+
- weread
|
|
11
|
+
- 划线同步
|
|
12
|
+
- 读书笔记
|
|
13
|
+
- 阅读统计
|
|
14
|
+
- 书架
|
|
15
|
+
- weread sync
|
|
16
|
+
- sync highlights
|
|
17
|
+
tags: [weread, reading, highlights, sync, capture]
|
|
18
|
+
entrypoint: false
|
|
19
|
+
compatibility: Requires WeRead Skill API key (wrk-*). Desktop WereadService preferred; host may call gateway manually.
|
|
20
|
+
author: TopMindSpace
|
|
21
|
+
license: MIT
|
|
22
|
+
homepage: https://github.com/topmindspace/topmind
|
|
23
|
+
updated: 2026-08-15
|
|
24
|
+
degradation: ../shared/capability-degradation.md
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
# topmind WeRead
|
|
28
|
+
|
|
29
|
+
将微信读书划线/想法/统计同步为 topmind 笔记(`source_type: external-capture`)。
|
|
30
|
+
|
|
31
|
+
## When NOT to use
|
|
32
|
+
|
|
33
|
+
- 普通链接剪藏 → `topmind-capture`
|
|
34
|
+
- 发推 / X → `topmind-x`
|
|
35
|
+
- 无微信读书语义的整理/写作 → organize / write
|
|
36
|
+
|
|
37
|
+
## API(官方 Gateway)
|
|
38
|
+
|
|
39
|
+
```text
|
|
40
|
+
POST https://i.weread.qq.com/api/agent/gateway
|
|
41
|
+
Authorization: Bearer wrk-xxxxxxxx
|
|
42
|
+
Body: { "api_name": "/…", "skill_version": "1.0.4", … }
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Key:`https://weread.qq.com/r/weread-skills`(微信扫码)。
|
|
46
|
+
|
|
47
|
+
| 能力 | api_name |
|
|
48
|
+
|------|----------|
|
|
49
|
+
| 书架 | `/shelf/sync` |
|
|
50
|
+
| 搜索 | `/store/search` |
|
|
51
|
+
| 统计 | `/readdata/detail` |
|
|
52
|
+
| 书详情/进度 | `/book/info` · `/book/getprogress` |
|
|
53
|
+
| 有笔记的书 | `/user/notebooks`(`count` + `lastSort`) |
|
|
54
|
+
| 划线 | `/book/bookmarklist` |
|
|
55
|
+
| 想法 | `/review/list/mine` |
|
|
56
|
+
| 推荐 | `/book/recommend` · `/book/similar` |
|
|
57
|
+
|
|
58
|
+
## Desktop 同步策略
|
|
59
|
+
|
|
60
|
+
1. 分页拉全 notebooks(`count=100` + `lastSort`)
|
|
61
|
+
2. 仅 `noteCount + reviewCount > 0`(书签不算可导出;拉完仍空也不写专题)
|
|
62
|
+
3. 本地条数一致 → 跳过;`note_fingerprint` 二次校验
|
|
63
|
+
4. 每书:bookmarklist + 可选 `/review/list/mine`(`synckey`)
|
|
64
|
+
5. 写 `topic.md` + `划线笔记.md`(`writeConnectorNote` 经 kernel 写闸;create/update 不备份,仅 locked 等高影响才备份)
|
|
65
|
+
6. 软预算(默认 4 分钟)超时留下次
|
|
66
|
+
7. `lastSyncAt` 仅展示,不作时间过滤
|
|
67
|
+
8. `upgrade_info` 展示即可,不因新 zip 单独失败
|
|
68
|
+
|
|
69
|
+
目标类别:见 router [`../topmind/references/connector-resolution.md`](../topmind/references/connector-resolution.md)。
|
|
70
|
+
|
|
71
|
+
### 落盘形状
|
|
72
|
+
|
|
73
|
+
```text
|
|
74
|
+
{类别}/2026-书名/
|
|
75
|
+
├── topic.md # weread_book_id, synced_at, …
|
|
76
|
+
└── 划线笔记.md
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### 配置(Desktop)
|
|
80
|
+
|
|
81
|
+
`weread.enabled` · `apiKey` · `syncCategory: auto|目录` · `includeThoughts` · `syncBudgetMinutes`。
|
|
82
|
+
|
|
83
|
+
RPC:`weread.getStatus` · `testConnection` · `listNotebooks` · `syncHighlights` · stats/search 等。
|
|
84
|
+
|
|
85
|
+
## 降级
|
|
86
|
+
|
|
87
|
+
1. 无 API Key → 引导获取
|
|
88
|
+
2. API 失败 → 保留上次数据 + 错误
|
|
89
|
+
3. 单书超时 → 跳过继续
|
|
90
|
+
4. 无 Desktop → host 可手工调 Gateway;仍遵守 PROJECT-MODEL
|
|
91
|
+
|
|
92
|
+
## 保存设置
|
|
93
|
+
|
|
94
|
+
- **自动保存 (auto)**:直接写入并返回路径回执(path receipt)
|
|
95
|
+
- **需要审阅 (confirm)**:先进入目标路径/内容审阅入口再保存
|
|
96
|
+
- Host 可编码为 `writeback_mode: auto | confirm`。详见 [`../shared/writeback-receipt.md`](../shared/writeback-receipt.md)。
|
|
97
|
+
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: topmind-write
|
|
3
|
+
version: 4.13.0
|
|
4
|
+
description: >-
|
|
5
|
+
写作/润色/出稿到专题或交付层(role:delivery)。Use when 写、起草、续写、润色、出稿、交付、write、draft、deliver。
|
|
6
|
+
Do NOT use for 仅捕获、仅结构整理、只写记忆、doctor/loop、社交连接器.
|
|
7
|
+
action_category: write
|
|
8
|
+
triggers:
|
|
9
|
+
- 写
|
|
10
|
+
- 写作
|
|
11
|
+
- 起草
|
|
12
|
+
- 续写
|
|
13
|
+
- 修订
|
|
14
|
+
- 润色
|
|
15
|
+
- 交付
|
|
16
|
+
- 改写
|
|
17
|
+
- de-AI
|
|
18
|
+
- 输出
|
|
19
|
+
- 出稿
|
|
20
|
+
- 定稿
|
|
21
|
+
- 发布
|
|
22
|
+
- 导出
|
|
23
|
+
- 排版
|
|
24
|
+
- write
|
|
25
|
+
- draft
|
|
26
|
+
- deliver
|
|
27
|
+
- publish
|
|
28
|
+
- export
|
|
29
|
+
tags: [write, draft, revise, polish, deliver]
|
|
30
|
+
entrypoint: false
|
|
31
|
+
compatibility: topmind workspace. Delivery role category (often 88-交付 / 88-Delivery).
|
|
32
|
+
author: TopMindSpace
|
|
33
|
+
license: MIT
|
|
34
|
+
homepage: https://github.com/topmindspace/topmind
|
|
35
|
+
updated: 2026-09-22
|
|
36
|
+
degradation: ../shared/capability-degradation.md
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
# topmind Write
|
|
40
|
+
|
|
41
|
+
从起草到交付。输出最终内容到 **delivery 层**(role:delivery)或专题根。
|
|
42
|
+
|
|
43
|
+
## Activation checklist
|
|
44
|
+
|
|
45
|
+
1. 能定位专题时:**先读 `topic.md`(若有)**,再读焦点稿与必要笔记(不足再 organize/capture)
|
|
46
|
+
2. 起草或修订;去 AI 腔 / 适配格式
|
|
47
|
+
3. 落盘专题根或 `save-output` → delivery
|
|
48
|
+
4. 路径回执;交付勿塞进专题内 `outputs/`
|
|
49
|
+
|
|
50
|
+
## When NOT to use
|
|
51
|
+
|
|
52
|
+
- 记链接/想法 → `topmind-capture`
|
|
53
|
+
- 整理/综合证据 → `topmind-organize`
|
|
54
|
+
- 只更新「我的情况」/ 周期反思 → `topmind-memory`
|
|
55
|
+
- 清理/体检/巡检 → maintain / loop
|
|
56
|
+
- 发推 / 微信读书 → connectors
|
|
57
|
+
- **公众号 / 微信排版 / 公众号定稿发布** → `topmind-wechat`(write 族子技能)
|
|
58
|
+
|
|
59
|
+
## Writing Entry Points
|
|
60
|
+
|
|
61
|
+
Draft · Continue · Revise · Polish · Deliver — 按用户当前意图,不是固定流水线。
|
|
62
|
+
|
|
63
|
+
公众号专用:选题包 · 审校改写 · 质量三关 · 定稿 · 微信排版 — 转入 [`../topmind-wechat/SKILL.md`](../topmind-wechat/SKILL.md)。
|
|
64
|
+
|
|
65
|
+
## Workflow
|
|
66
|
+
|
|
67
|
+
1. **读序(先首页再素材)**:`topic.md`(若有)→ 焦点对象 → 仅必要笔记。无 topic.md 不强制创建,照旧扫笔记。禁止一上来 dump 整专题
|
|
68
|
+
2. 对齐目标、稳定记忆、风格、受众
|
|
69
|
+
3. 产出可用正文,少过程旁白
|
|
70
|
+
4. 按保存设置写入;锁定文件:内容编辑允许(任务级首写快照),可恢复删/归档允许,永久删仅用户。宿主若提供唯一片段替换(Desktop / Obsidian `edit_file`),中段改稿优先用它:匹配阶梯(精确→换行/空白→行级宽松),多步编辑跟 postEditWindow + contentHash/expectedHash,不要为改一段而整文件覆盖。不要编造 shell / bash 工具。
|
|
71
|
+
5. Desktop 可选影子流式:`.shadow-*.tmp`,Commit 后再原子落盘
|
|
72
|
+
|
|
73
|
+
## source_type
|
|
74
|
+
|
|
75
|
+
- AI 草稿默认 `ai-derived`
|
|
76
|
+
- 用户原文仅排版 → `user-original`
|
|
77
|
+
- 交付层文件 `source_type` 可选;专题内笔记建议必填
|
|
78
|
+
|
|
79
|
+
## Delivery Checklist
|
|
80
|
+
|
|
81
|
+
```text
|
|
82
|
+
□ 格式匹配目标
|
|
83
|
+
□ 无内部标注 / TODO / 占位符
|
|
84
|
+
□ 受众与语气匹配
|
|
85
|
+
□ source_type 正确
|
|
86
|
+
□ 路径正确(交付层 save-output;专题根 capture-note)
|
|
87
|
+
□ 交付层文件名 YYYY-MM-DD-描述.ext
|
|
88
|
+
□ 回执含路径与下一步
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
不满足则在回执标注。
|
|
92
|
+
|
|
93
|
+
## Quality Bar
|
|
94
|
+
|
|
95
|
+
具体、受众向;去 AI 套话;保用户声音。`topic.md` 风格锚点优先。
|
|
96
|
+
|
|
97
|
+
改稿按场景选工具,别混用:
|
|
98
|
+
|
|
99
|
+
| 场景 | 技能 |
|
|
100
|
+
|---|---|
|
|
101
|
+
| 中文改稿的保真边界(不新增事实、不把「可能」写成「确定」) | `humanizer-zh` |
|
|
102
|
+
| 中文 AI 味体检 / 量化评分 / pan 个人风格 | `qu-aiwei-zh` |
|
|
103
|
+
| 英文文本 | `humanizer` |
|
|
104
|
+
|
|
105
|
+
默认组合是**先 `humanizer-zh` 立边界,再 `qu-aiwei-zh` 扫描定位**。分数不够时只能删套话改表达,不许补数字或硬塞「我」。
|
|
106
|
+
|
|
107
|
+
## Capability Degradation
|
|
108
|
+
|
|
109
|
+
[`../shared/capability-degradation.md`](../shared/capability-degradation.md)。`inspect-topic` · `save-output` · `capture-note`。
|
|
110
|
+
|
|
111
|
+
## 保存设置
|
|
112
|
+
|
|
113
|
+
- **自动保存 (auto)**:直接写入并返回路径回执(path receipt)
|
|
114
|
+
- **需要审阅 (confirm)**:先进入目标路径/内容审阅入口再保存
|
|
115
|
+
- Host 可编码为 `writeback_mode: auto | confirm`。详见 [`../shared/writeback-receipt.md`](../shared/writeback-receipt.md)。
|
|
116
|
+
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: topmind-x
|
|
3
|
+
version: 4.13.0
|
|
4
|
+
description: >-
|
|
5
|
+
X/Twitter:归档/搜索(Bearer)、发帖(xurl)、Agent 可用官方 MCP。Use when 发推、推特、twitter、x.com。
|
|
6
|
+
Do NOT use for 微信读书、非 X 捕获、doctor、长文交付.
|
|
7
|
+
action_category: connector
|
|
8
|
+
triggers:
|
|
9
|
+
- 发推
|
|
10
|
+
- 推特
|
|
11
|
+
- twitter
|
|
12
|
+
- x.com
|
|
13
|
+
- 发帖
|
|
14
|
+
- 推文
|
|
15
|
+
- post tweet
|
|
16
|
+
- x platform
|
|
17
|
+
tags: [x, twitter, social, mcp, agent]
|
|
18
|
+
entrypoint: false
|
|
19
|
+
compatibility: Desktop needs Bearer (read) and/or xurl (post). Agent hosts use official X MCP + xurl bridge.
|
|
20
|
+
author: TopMindSpace
|
|
21
|
+
license: MIT
|
|
22
|
+
homepage: https://github.com/topmindspace/topmind
|
|
23
|
+
updated: 2026-08-16
|
|
24
|
+
degradation: ../shared/capability-degradation.md
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
# topmind X / Twitter
|
|
28
|
+
|
|
29
|
+
分清两个平面:
|
|
30
|
+
|
|
31
|
+
| 平面 | 接入 | 能力 |
|
|
32
|
+
|------|------|------|
|
|
33
|
+
| Agent 宿主 | 官方 MCP `https://api.x.com/mcp` + `xurl mcp` | 搜索/用户/书签等(随 scope) |
|
|
34
|
+
| Desktop 只读 | App-only Bearer → API v2 | 搜索/时间线 → 归档笔记 |
|
|
35
|
+
| Desktop 发帖 | 本机 `xurl`(用户 OAuth) | 发布;失败草稿进 Inbox |
|
|
36
|
+
|
|
37
|
+
文档:https://docs.x.com/tools/mcp
|
|
38
|
+
|
|
39
|
+
## When NOT to use
|
|
40
|
+
|
|
41
|
+
- 微信读书 → `topmind-weread`
|
|
42
|
+
- 非 X 的剪藏 → `topmind-capture`
|
|
43
|
+
- 长文交付(非推文)→ `topmind-write`
|
|
44
|
+
|
|
45
|
+
## 认证
|
|
46
|
+
|
|
47
|
+
- **Bearer**:只读;不能发帖
|
|
48
|
+
- **xurl OAuth**:Desktop 发帖
|
|
49
|
+
- **官方 MCP**:Agent 宿主;Desktop **不**内嵌 OAuth 桥
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
npx -y @xdevplatform/xurl mcp https://api.x.com/mcp
|
|
53
|
+
brew install --cask xdevplatform/tap/xurl && xurl auth oauth2
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## 与笔记整合
|
|
57
|
+
|
|
58
|
+
类别解析:[`../topmind/references/connector-resolution.md`](../topmind/references/connector-resolution.md)。
|
|
59
|
+
|
|
60
|
+
推文笔记:`source_type: external-capture`,含链接与可选 AI 摘要分隔。
|
|
61
|
+
|
|
62
|
+
## 发布工作流
|
|
63
|
+
|
|
64
|
+
起草(可 write)→ **用户确认**(即使 `writeback_mode: auto`)→ xurl 或 MCP 发布 → 可选归档。
|
|
65
|
+
|
|
66
|
+
## Desktop RPC
|
|
67
|
+
|
|
68
|
+
`x.getStatus` · `probeTools` · `testConnection` · `searchTweets` · `getTimeline` · `syncToNotes` · `postTweet`。
|
|
69
|
+
|
|
70
|
+
设置:`x.enabled` · `bearerToken` · `mcpEndpoint`(仅 Agent 文档)· `syncCategory: auto` · `autoArchivePosts`。
|
|
71
|
+
|
|
72
|
+
### Desktop 实现约定
|
|
73
|
+
|
|
74
|
+
- **读**:Bearer → 官方 `GET https://api.x.com/2/tweets/search/recent` / `GET /2/users/by/username/{handle}` + `/2/users/{id}/tweets`。无 Bearer 时走本机 xurl **同一 REST 路径**(不是自造 `timeline --user`)。
|
|
75
|
+
- **写**:`xurl -X POST /2/tweets -d '{"text":…}'`(官方);快捷 `xurl post "…"` 作回退。App-only Bearer **不能**发帖。
|
|
76
|
+
- **归档**:预览勾选后写入 `{类别}/{YYYY-主题}/`;`append` 时按 `tweet_ids` / `status/{id}` **跳过已有推文**。create/update 不备份(仅 locked 等高影响)。
|
|
77
|
+
- Desktop **不**内嵌官方 MCP OAuth 桥;`mcpEndpoint` 给 Agent 宿主配置。
|
|
78
|
+
|
|
79
|
+
## 降级
|
|
80
|
+
|
|
81
|
+
1. 无 Bearer → 不能搜索/时间线
|
|
82
|
+
2. 无 xurl → 不能发帖(草稿 Inbox)
|
|
83
|
+
3. Agent 完整能力 → 宿主接 MCP
|
|
84
|
+
4. 无通道 → 仅编辑器起草
|
|
85
|
+
|
|
86
|
+
## 安全
|
|
87
|
+
|
|
88
|
+
Bearer 加密存储;不自动关注/点赞/转发;遵守 X API 规则。
|
|
89
|
+
|
|
90
|
+
## 保存设置
|
|
91
|
+
|
|
92
|
+
- **自动保存 (auto)**:直接写入并返回路径回执(path receipt)
|
|
93
|
+
- **需要审阅 (confirm)**:先进入目标路径/内容审阅入口再保存
|
|
94
|
+
- Host 可编码为 `writeback_mode: auto | confirm`。详见 [`../shared/writeback-receipt.md`](../shared/writeback-receipt.md)。
|
|
95
|
+
|
|
96
|
+
发布动作始终二次确认(即使 auto)。
|
|
97
|
+
|