PKM closed loop'ssupport · library segment: maintain the "book" data line that is independent of article excerpts — synchronization, completion, and overview generation for the library catalog + reading records.
Customer-visible introduction
This skill syncs the bookshelf, reading progress, highlights, and thoughts from WeChat Reading to the Obsidian library, and maintains the local library overview, reading records overview, and category views. Customers can understand it as a tool for "turning WeChat Reading into their own long-term reading archive."
Customer-visible results include:
- The WeChat Reading bookshelf is synced into Obsidian book cards.
- Read / currently reading books generate reading records.
- A single book's highlights, thoughts, chapter table of contents, and reading progress are added to the reading record or book card.
- The three Markdown views — library overview, reading records overview, and by-type overview — are regenerated.
- Each run outputs progress, success/skipped/failed counts, write locations, and next-step suggestions in the terminal, making it easy for customers to judge "what exactly was done."
What it can do
7 mechanical-layer scripts (no LLM judgment, purely deterministic operations), covering the complete chain of library maintenance:
| Script | Function | When to run |
|---|---|---|
sync_weread_to_library.py |
WeChat Reading read books → library book cards + reading records (new) | When you want to sync the latest reading status |
sync_weread_highlights.py |
WeChat Reading highlights/thoughts → existing reading records (append machine section) | When you want to sync highlight notes |
enrich_book_details.py <书名>... |
Fill in details for a single book (introduction/chapters/progress/similar books) | When you want to dig deeper into a book's details |
backfill_reading_records.py |
Books with book cards but no reading records → batch-create "to-read" records | When you want the library and reading record counts to align |
gen_library_md.py |
Regenerate the library overview (nested primary + secondary categories) | After book cards change |
gen_records_md.py |
Regenerate the reading records overview (book card authoritative categories + 7-state lifecycle status) | After reading records change |
gen_genre_library_md.py |
Regenerate the library overview grouped by type (single-level type grouping, no secondary nesting) | After book cards change (e.g., a child's library scenario) |
First-time installation and configuration
1. Install the SOIA self-built skill
npx skills add soia-team/soia-open-skills
2. Install the official WeChat Reading skill (sync-type scripts strongly depend on it)
npx skills add Tencent/WeChatReading -g
After installation, at least one entry point should exist:
ls -ld .agents/skills/weread-skills ~/.gemini/antigravity-cli/skills/weread-skills ~/.agents/skills/weread-skills ~/.codex/skills/weread-skills ~/.claude/skills/weread-skills
3. Obtain WEREAD_API_KEY
Open the official WeChat Reading Skill page:https://weread.qq.com/r/weread-skills, log in to WeChat Reading, and obtain the API Key.
4. Write the local private configuration
Configuration file path:
~/.config/soia-skills/soia-open-skills/soia-pkm/soia-pkm-library/config.yml
Example:
env:
OBSIDIAN_VAULT: "/你的/vault/绝对路径"
WEREAD_API_KEY: "<微信读书官方页面给你的 API Key>"
The secret key is only placed in the private config.yml or process environment, and is not written into the vault, articles, logs, README, or open-source skill repository.
How to run
cd skills/soia-pkm-library/scripts
# 1. 同步微信读书书架:书架 → 书卡 + 阅读记录
python3 sync_weread_to_library.py --vault <vault-path> # 已读书目 → 书卡 + 阅读记录
# 2. 同步划线 / 想法:先预览,再按需全量或单本
python3 sync_weread_highlights.py # 列 noteCount 前 30(预览)
python3 sync_weread_highlights.py --all # 全量同步划线/想法
python3 sync_weread_highlights.py 三体 失控 # 按书名同步
# 3. 补单本书详情 / 批量补全
python3 enrich_book_details.py 系统之美
python3 enrich_book_details.py --all
# 4. 补建待读记录(图书馆有卡、但没阅读记录的书)
python3 backfill_reading_records.py
# 5. 重生成三份总览
python3 gen_library_md.py
python3 gen_records_md.py
python3 gen_genre_library_md.py --base <vault-book-library-dir>
All scripts share the same set of parameterized conventions:
--vault <path>orOBSIDIAN_VAULTenv: vault root directory (choose one,--vaulttakes priority).--base <relpath>: Path of the library relative to the vault. By default it corresponds to "Personal Library" (gen_genre_library_md.pyBy default it corresponds to the "Kids Library" scenario; you can use--baseto switch to the personal library).Do not hardcode this default value in the body text—the vault may restructure its directory layout in the future; just pass whichever library you need via--baseto override it.--config <json>: Override the script's built-in defaults for the category table/status table/field table (category mapping, secondary sorting, status icons, passthrough fields, etc.). The JSON structure matches the keys of theDEFAULT_*constant in the script, so you don't need to change code—just change the config.--output <path>(only 3gen_*scripts): Write the generated result to the specified file instead of overwriting the overview file in the vault, for dry-run previews.- Private config loading: The script automatically reads
$SOIA_PKM_LIBRARY_CONFIG_FILE(or the compatible alias$SOIA_PKM_LIBRARY_ENV_FILE) as well as the default path~/.config/soia-skills/soia-open-skills/soia-pkm/soia-pkm-library/config.yml. The config file uses a YAMLenv:mapping; keep secrets only in these private files, not in the vault and not in the open-source skill repository. - Private config files only record the local values corresponding to variable names; documentation and open-source repositories keep only the variable names, not the real values.
Customer-visible logs and summary
When executing this skill, the terminal output is the customer-visible log. All scripts must comply with the following:
- At the start, explain what is being done, e.g. "Fetching WeRead bookshelf" "N books to sync".
- During the process, output key progress, e.g. current book title, bookId, number of highlights, number of thoughts, files written.
- At the end, output summary numbers, e.g. new book cards, updated records, succeeded, skipped, failed.
- At the end, output next-step suggestions, e.g. regenerate
gen_library_md.py/gen_records_md.py。 - When dependencies or keys are missing, you must output actionable remediation steps, not just an error.
Example of customer-visible output:
拉取微信读书书架...
书架共 123 本
=== 同步完成 ===
新增书卡: 4
新增已完成记录: 2
新增在读记录: 1
下一步:
python3 gen_library_md.py
python3 gen_records_md.py
When WEREAD_API_KEY is missing, you must prompt the customer to obtain it from the official page:
未设置 WEREAD_API_KEY:请先去微信读书官方 Skill 页面申请/获取 API Key:
请打开 https://weread.qq.com/r/weread-skills 登录微信读书获取 WEREAD_API_KEY;
强依赖 weread-skills 状态:已安装;
拿到后放到私有 config.yml,不要写入 vault 或开源 skill 仓库
WEREAD_API_KEY Why it will not be initialized automatically
- The current sync pipeline calls the WeRead Agent API Gateway:
https://i.weread.qq.com/api/agent/gateway。 - The authentication method for this pipeline is an explicit
Authorization: Bearer <WEREAD_API_KEY>, not something automatically exchanged from WeRead cookies, browser login state, or app session. - During initialization, I only saw
WEREAD_COOKIE/WEREAD_COOKIE_B64/WEREAD_VIDthese old fields in the old config, and they were empty; there was no migratableWEREAD_API_KEY。 - So the skill can only help you initialize the
config.ymlstructure; it cannot forge a key for you, nor will it pass off an old cookie as a Bearer key.
WEREAD_API_KEY How to apply
The official WeRead Skill page provides a self-service entry point:https://weread.qq.com/r/weread-skills. The page explains that after installing the Skill, you can obtain the API Key by logging in to WeRead.
Before executing WeRead sync, do two things first:
- Check whether the dependency skill is installed: at least one of the workspace's
.agents/skills/weread-skills、~/.gemini/antigravity-cli/skills/weread-skills、~/.agents/skills/weread-skills、~/.codex/skills/weread-skillsor~/.claude/skills/weread-skillsexists. - If it is not installed, first run the official installation command:
npx skills add Tencent/WeChatReading -g。 - Open
https://weread.qq.com/r/weread-skills, log in to WeRead and obtain the API Key. - After getting the key, write it to
~/.config/soia-skills/soia-open-skills/soia-pkm/soia-pkm-library/config.yml。 - The syntax is as follows:
env:
OBSIDIAN_VAULT: "/你的/vault/绝对路径"
WEREAD_API_KEY: "<微信读书官方页面给你的 API Key>"
If WEREAD_API_KEYis missing, sync-type scripts must prompt the user to obtain it from https://weread.qq.com/r/weread-skills , rather than having the user look for the internal gateway maintainer.
Directory contract
This skill relies on the library following the structure below (the specific directory name is determined by --base and is described below using relative paths, which does not represent a hard-coded absolute path):
<base>/
├── 00_图书馆/
│ └── 书目/<分类目录>/<书名>.md # 书卡:客观信息(title/author/category/bookId/...)
└── 阅读记录/
├── 想读/ ┐
├── 待读/ │
├── 计划读/ │ 7 态生命周期(按阅读推进顺序)
├── 在读/ │ 状态由阅读记录 frontmatter 的 `status` 字段决定,
├── 暂停/ │ 与所在子目录名无强绑定——脚本按 frontmatter 归类统计,
├── 搁置/ │ 子目录只是人工归档习惯
└── 完成/ ┘
- The book card is thecategory authoritative source(
category/subcategory); reading records look up the book card to get the category, without using their own old fields. - Reading records look up the book card via
book: "[[书名]]"; a book card that no record points to is "to be supplemented" (thebackfill_reading_records.pycriterion). sync_weread_highlights.py's machine section (## 📌 划线/## 💭 想法) is overwritten as a whole; user handwritten notes must be placed in the### 用户笔记sub-block within the section (the script will preserve it).
Strong dependency: weread-skills
Sync-type scripts (sync_weread_to_library.py / sync_weread_highlights.py / enrich_book_details.py) strongly depend on the official WeRead weread-skills, and directly call the WeRead Agent API Gateway (https://i.weread.qq.com/api/agent/gateway). Before executing a sync, the following must be satisfied:
weread-skillsis installed: at least one of the workspace's.agents/skills/weread-skills、~/.gemini/antigravity-cli/skills/weread-skills、~/.agents/skills/weread-skills、~/.codex/skills/weread-skillsor~/.claude/skills/weread-skillsexists.WEREAD_API_KEYhas been written into the privateconfig.yml'senv.WEREAD_API_KEY, or is provided by the process environment.OBSIDIAN_VAULTis configured, or passed in via the command line--vault <path>。- The local machine can access
https://i.weread.qq.com/api/agent/gateway。 - The runtime environment has Python 3; the scripts only use the Python standard library and the
scripts/library_env.pybundled with this skill, and do not require additional pip dependencies.
Local generation/completion-type scripts (backfill_reading_records.py / gen_library_md.py / gen_records_md.py / gen_genre_library_md.py) do not call the WeRead API, so they do not need WEREAD_API_KEY; they only depend on Python 3, the vault path, and local markdown files.
Third-party skill relationships must be explained according to the following criteria, to avoid misreading the "third-party skill overview" as runtime dependencies:
| Third-party skill | Relationship to soia-pkm-library relationship with |
|---|---|
weread-skills (Tencent/WeChatReading) |
Strong dependency: WeRead sync-type scripts must first check that it is installed |
huashu-weread-advisor |
Non-dependency: reading advisor / recommendation / review upper-layer workflows, which can consume the synced bookshelf and notes data, but this skill does not call it |
book-to-skill |
Non-dependency: document/book-to-skill tool, with no runtime relationship to library sync |
find-skills |
Non-dependency: skill discovery/installation auxiliary tool, with no runtime relationship to library sync |
Before executing a sync, you should check whether the strongly dependent skill is installed. Recommended check paths:
ls -ld .agents/skills/weread-skills ~/.gemini/antigravity-cli/skills/weread-skills ~/.agents/skills/weread-skills ~/.codex/skills/weread-skills ~/.claude/skills/weread-skills
If none of the above entry points exist, prompt the user to install it first according to the official page:
npx skills add Tencent/WeChatReading -g
If weread-skillsis missing, sync-type scripts must exit directly and prompt to install the official skill; if WEREAD_API_KEYis missing, sync-type scripts must prompt the user to go to https://weread.qq.com/r/weread-skills to log in to WeRead and obtain an API Key.
Boundary statement
The division of labor with adjacent skills, stated clearly in one sentence:
huashu-weread-advisor: Advisor AI layer—makes personalized recommendations/advanced book lists/review articles based on the bookshelf + notes; this skill only handles data sync and persistence, and does not make any "what to read/how to read" judgments.soia-pkm-reading-plan: Schedule planning—organizes a batch of books into an executable reading plan with a schedule; this skill does not make plans, and only ensures that library data (bibliography/reading records/overview) is fresh and aligned.soia-pkm-alipan-curator: Cloud drive resource catalog—takes stock of/organizes resources in Alibaba Cloud Drive and persists them into an Obsidian index; this skill only handles the "book" data line and does not touch the cloud drive.
Exception handling
| Scenario | Handling |
|---|---|
Not set WEREAD_API_KEY |
Sync-type script errors out (exit 1), prompts the user to go to https://weread.qq.com/r/weread-skills to log in to WeRead and obtain the API Key, then put it into the private config.yml |
Not specified --vault and no OBSIDIAN_VAULT env |
errors out, prompts to pass --vault or in the private config.yml settings |
| The book title cannot find a corresponding file in the library/reading records | Skip and print a warning without interrupting the batch process (--all mode) |
| WeRead book title does not match the local file name (including subtitle/collection suffix) | sync_weread_highlights.py prioritizes exact matching by bookId exact match, title matching is the fallback |
| Want to do a dry run to preview the generated result without overwriting the original vault files | 3 gen_* scripts all support --output <临时路径> |
completion receipt
Complex sync tasks must first complete a forward test: use a small scope or fixture input to verify additions, updates, skips, failures, and output content, then expand to the full scope; a command returning 0 does not mean the data is complete.
After executingmustoutput to the user (do not do it silently):
- What was done — a one-sentence summary of the action performed this time, for example "synced the WeRead bookshelf and added 4 book cards".
- Customer-visible log summary — transcribe or summarize the key numbers at the end of the script: success / skipped / failed / added / updated counts.
- File changes — list the created / modified / moved files (full paths); if no files were changed, state "no files changed".
- Issues encountered — missing key, dependencies not installed, a certain book's record not found, API failure, etc. must all be stated clearly, along with the next repair path.
- Next steps — optional follow-up suggestions, such as regenerating the overview, syncing highlights, supplementing single book details, or connecting to
soia-pkm-reading-plan。
Recommended receipt format:
已完成:同步微信读书书架。
日志摘要:
- 书架共 123 本
- 新增书卡 4 张
- 新增已完成记录 2 条
- 新增在读记录 1 条
- 失败 0 条
文件变更:
- /path/to/vault/40_图书视频馆/30_个人书库/00_图书馆/书目/...
- /path/to/vault/40_图书视频馆/30_个人书库/阅读记录/...
下一步:
- 运行 `python3 gen_library_md.py`
- 运行 `python3 gen_records_md.py`