From zkfy
Auto-maintained vault catalog at .claude/index.md grouping all notes by domain with enriched metadata and a Keyword Index for fast retrieval. Use when you need to rebuild index, update index, or generate a vault catalog.
npx claudepluginhub jasonsie/zkfy --plugin zkfyThis skill uses the workspace's default tool permissions.
Generate and maintain `.claude/index.md` (relative to vault root) — a structured catalog of all Zettelkasten notes grouped by domain, with enriched metadata and a Keyword Index for fast Tier 0 lookup by vault-search.
Mandates invoking relevant skills via tools before any response in coding sessions. Covers access, priorities, and adaptations for Claude Code, Copilot CLI, Gemini CLI.
Share bugs, ideas, or general feedback.
Generate and maintain .claude/index.md (relative to vault root) — a structured catalog of all Zettelkasten notes grouped by domain, with enriched metadata and a Keyword Index for fast Tier 0 lookup by vault-search.
$ARGUMENTS — [--full | --append <note-path>] [--vault PATH]
. — current working directory, i.e., run from inside your vault)If no flag provided, default to --full.
.claude/index.md follows this structure:
# Vault Index
Generated: 2026-04-08 | Notes: 317 | Domains: 7
## cs (142 notes)
- [[CS-Algorithm-Backtracking]] — Backtracking pattern for constraint satisfaction | cats:CS sub:algorithm,backtracking tags:design-pattern aka:Backtracking,回溯法
- [[CS-Binary-Search-Tree]] — BST operations and balancing | cats:CS sub:data-structure,tree tags:reference aka:BST,Binary Search Tree,二元搜尋樹
## web (89 notes)
- [[Web-React-Hooks]] — React hook patterns and lifecycle | cats:Web sub:react,hooks tags:state-management aka:React Hooks,useState,useEffect
## ai (45 notes)
- [[AI-Multi-Agent-Patterns]] — Multi-agent orchestration strategies | cats:AI sub:multi-agent,workflow tags:architecture aka:Multi-Agent,多代理
## principle (20 notes)
...
## Keyword Index
- algorithm: [[CS-Algorithm-Backtracking]], [[CS-Algorithm-DP]], [[CS-Algorithm-BFS]]
- react: [[Web-React-Hooks]], [[Web-React-Server-Components]], [[Web-React-Performance]]
- 前端: [[Web-Frontend-Career-Path]], [[Web-React-Hooks]]
- security: [[Web-XSS-Prevention]], [[CS-Auth-JWT-Patterns]]
Each entry format: - [[Filename-Without-Extension]] — <abstract excerpt> | cats:<categories> sub:<sub-categories> tags:<tags> aka:<aliases>
cats: — primary + secondary categories (Title Case, comma-separated)sub: — topic-level sub-categories (lowercase-kebab, comma-separated)tags: — cross-cutting controlled vocab tags (comma-separated)aka: — aliases including CJK translations (comma-separated)Scan top-level directories under vault root:
*/ under vault root to list all top-level directoriesy.template/, row/, x.temp/, docs/, zz.original-source/, .obsidian/, .claude/, .agents/, .prompts/, .github/, .instructions/, 000.Index/111.cs/ → cs, 222.web/ → web, 333.ai/ → ainotes/ → notes, journal/ → journal (no prefix to strip)^\d+\. if present{folder_name → domain_label}. Sort domains alphabetically.Execute the note-scanner script to get structured vault data:
python3 .claude/skills/note-scanner/scripts/note_scanner.py .
Working directory: vault root. Parse the JSON output.
If the script is not found or fails, fall back to manual scanning (Step 1b).
If the scanner script is unavailable, scan manually:
**/*.md under vault rooty.template/, row/, x.temp/, docs/, zz.original-source/, .obsidian/, .claude/, .agents/, .prompts/, .github/, .instructions/, 000.Index/For each note, Read the first 30 lines and extract:
.md extensionother### Abstract (truncate to 80 chars). If Abstract section is missing, use the first content line after frontmatter closes (---).Categories: field, comma-separated Title CaseSub-Categories: field, comma-separated lowercase-kebabtags: field, comma-separatedAliases: field, comma-separated (preserve CJK characters)# Vault Index with generated date, total note count, and domain count (domains with >0 notes)## <domain> (<N> notes) followed by sorted entries- [[<Filename>]] — <abstract excerpt> | cats:<categories> sub:<sub-categories> tags:<tags> aka:<aliases>
(no abstract)cats:/sub:/tags:/aka: field that is emptyAfter all domain sections, generate a ## Keyword Index section:
Collect all keywords across every note:
tags (e.g., security, interview-prep)Sub-Categories (e.g., xss, algorithm)Aliases — including CJK terms (e.g., XSS, 跨站腳本攻擊)Categories (lowercased, e.g., web, cs)Build inverted index: keyword → [list of note filenames]
Filter: Only include keywords that appear in 2 or more notes (single-note keywords are discoverable via entry scan)
Sort: Alphabetically by keyword. CJK keywords sort after ASCII.
Format each line:
- <keyword>: [[Note-A]], [[Note-B]], [[Note-C]]
Cap: If a keyword maps to >20 notes, truncate to top 20 alphabetically and append (and N more)
Concatenate: header + domain sections + Keyword Index section.
Write the complete content to .claude/index.md.
Report:
✅ Vault index rebuilt
📄 File: .claude/index.md
📊 Notes: <total> | Domains: <count> | Keywords: <keyword-count>
Read the note at the given path. If the file doesn't exist → error:
❌ Note not found: <path>
Same extraction as full rebuild Step 2 — filename, domain (via Step 0 domain discovery), abstract, categories, sub-categories, tags, aliases.
Read .claude/index.md. If it doesn't exist → run --full rebuild instead and report:
📋 Index not found — running full rebuild instead
## <domain>)## Keyword Index section[[Filename]] to its list if not already presentRecount notes per domain and total. Update the header line:
Generated: <today> | Notes: <new-total> | Domains: <new-count> | Keywords: <keyword-count>
Write the updated .claude/index.md.
Report:
✅ Index updated: [[<Filename>]] added to <domain>
📄 File: .claude/index.md
📊 Notes: <total> | Domains: <count> | Keywords: <keyword-count>
Index doesn't exist (--append mode):
--full rebuildNote path invalid or file missing:
Domain not recognized (folder not in domain map):
other sectionNote scanner script not found:
Empty vault (no notes found):
Duplicate entry (--append with existing note):
No Aliases / CJK terms:
aka: field from entry; skip in Keyword Index