The local catalog layer of the PKM library: it only reads and writes Markdown and YAML frontmatter within the vault, backfills missing to-read records, and generates three overviews that can be browsed in Obsidian. It does not call the WeRead API, does not require third-party skills, and will not stop due to missing WeRead configuration.
Customer-readable description
What this skill can do
This skill is suitable for organizing a local library based on existing book cards or reading records. It generates a library overview and a reading records overview according to the classification field of the book cards, and can also idempotently backfill books that "have book cards but no reading records" as "to-read" records, and generate views grouped by type.
| Customer wants | Skill will do | Customer can see |
|---|---|---|
| Backfill to-read records | Scan book cards and reading records, create missing records, skip if the target already exists | Number created, skipped, and failed |
| Regenerate library overview | Read local book cards and generate a nested classification view | Output files and bibliography statistics |
| Update reading records overview | Summarize the 7-state reading lifecycle based on book card classification | Status, classification, and processing statistics |
| Library organization | Execute backfill and generation of the three views in sequence | Receipt for each stage and repeatable execution results |
How customers use it
- Use natural language to explain that you want to backfill to-read records, update a certain overview, or organize the entire library.
- Provide
--vault <path>, or set it in the private configurationOBSIDIAN_VAULT; noWEREAD_API_KEYor WeRead login state is required. - The generation script supports
--output <path>preview; after confirming the content, omit this parameter to write back to the vault. - After execution, verify the actual output and statistics; all scripts can be safely run repeatedly.
Dependencies and installation
Install this skill:
npx skills add soia-team/soia-open-skills -g -a '*' -s soia-pkm-library-book-catalog -y
The only runtime dependencies are Python 3 and Markdown files in the local vault; it does not depend on WeRead,weread-skills、WEREAD_API_KEY, the network, or additional pip packages.
Private configuration path:
~/.config/soia-skills/soia-open-skills/soia-pkm/soia-pkm-library-book-catalog/config.yml
SOIA_PKM_LIBRARY_BOOK_CATALOG_CONFIG_FILE=<custom-config-path>
SOIA_PKM_LIBRARY_BOOK_CATALOG_ENV_FILE=<compat-config-path>
Example:
env:
OBSIDIAN_VAULT: "<vault-path>"
For compatibility with older invocation methods, the script also accepts SOIA_PKM_LIBRARY_CONFIG_FILE and SOIA_PKM_LIBRARY_ENV_FILE; new configurations should preferentially use the catalog-specific names above. The configuration only stores local paths and does not commit private data.
Logs and completion receipts
Each run outputs the scan scope, the number created/updated/skipped/failed, output categories, and next-step suggestions. Logs involving the vault only report generalized locations and resource categories, and do not print keys or unnecessary local absolute paths. At the end, the actual file changes and verification method must be stated.
What it can do
| Script | Function | When to run |
|---|---|---|
backfill_reading_records.py |
Batch-create "to-read" records for books that have book cards but no reading records | When you want to align book cards with reading records |
gen_library_md.py |
Generate a library overview by primary/secondary classification | After book cards change |
gen_records_md.py |
Generate a reading record overview based on the authoritative book card categories and the 7-state status | After reading records change |
gen_genre_library_md.py |
Generate a library overview by single-level type | When a type view is needed |
How to run
The following commands are executed from this skill's scripts/ directory:
python3 backfill_reading_records.py --vault <vault-path>
python3 gen_library_md.py --vault <vault-path> --output <preview-path>
python3 gen_records_md.py --vault <vault-path> --output <preview-path>
python3 gen_genre_library_md.py --vault <vault-path> --base <vault-book-library-dir> --output <preview-path>
After confirming the preview, remove --output to write back to the vault. All scripts share the following parameterization conventions:
--vault <path>orOBSIDIAN_VAULT: vault root directory, command line takes precedence.--base <relpath>: the library's path relative to the vault; pass it explicitly according to the actual library, without relying on a fixed personal directory name.--config <json>: override category, status, icon, or field passthrough settings (supported by specific scripts).- Private configuration is loaded using
SOIA_PKM_LIBRARY_BOOK_CATALOG_CONFIG_FILE, a compatible alias, or the default configuration path; it will not override environment variables already present in the process.
Directory contract and upstream relationships
The library directory is determined by --base , and its core structure is:
<base>/
├── 00_图书馆/
│ └── 书目/<分类目录>/<书名>.md
└── 阅读记录/
├── 想读/ 待读/ 计划读/ 在读/
├── 暂停/ 搁置/ 完成/
└── 阅读记录-总览.md
The book card's category/subcategory is the authoritative source for categories; reading records look up book cards via book: "[[书名]]" . Book cards that no record points to are the backfill_reading_records.py pending-backfill objects. The generation scripts read local Markdown and do not request data from remote sources.
soia-pkm-library-weread-sync is an optional upstream: it can first persist WeRead data as book cards, reading records, and machine sections, which this skill then consumes as local files. catalog can also independently process existing local data, and can still run without installing the upstream sync skill.
Write and idempotency boundaries
- Markdown views are product feature files of the vault, and by default are written back to the library directory located by
--base. - The three
gen_*scripts support--output <path>preview to avoid directly overwriting the overview file. backfill_reading_records.pyonly creates when the target record does not exist; existing files are skipped and user records are not overwritten.- The scripts do not create network caches, do not write external state, and do not call providers; the temporary preview path is passed in by the user via
--output, and temporary files are managed by the caller.
Boundaries and exceptions
| Scenario | Handling |
|---|---|
| Vault not specified | Exit and prompt to pass --vault or set OBSIDIAN_VAULT |
| Library directory does not exist | Output a locatable missing-directory prompt and exit, without fabricating an overview |
| Target to-read record already exists | Skip, without overwriting existing content |
| Book card is missing a title or category | Categorize using the script defaults and prompt in the log |
| Local book title cannot be looked up | Skip and print a warning, without interrupting batch organization |
| Want to confirm generated content | Use --output to output to a temporary preview file |
Post-completion receipt
After completion, you must report: the scripts and scope of this run, the counts of scanned/created/updated/skipped/failed items, the resource categories actually written, the preview or write-back verification results, and any issues requiring user handling. Do not treat "the command returned 0" alone as evidence that the content is correct; at minimum, check that the output exists and contains the expected title or statistics.