com um clique
kb-compile
Compile all uncompiled raw/ content into the wiki. Writes source summaries, creates/updates concept articles with Obsidian backlinks, and updates the index. Run after /kb-ingest to process new content.
Menu
Compile all uncompiled raw/ content into the wiki. Writes source summaries, creates/updates concept articles with Obsidian backlinks, and updates the index. Run after /kb-ingest to process new content.
Scan vault raw/ folder for hyperlinks embedded in markdown notes; POST each unseen URL to LuminaVault server /v1/capture/safari so Hermes ingests + memorizes. Usage: /kb-vacuum [folder=raw/]
Generate daily Reddit and X/Twitter marketing content from the AI Cohort scoreboard, with automatic fallback to the most recent available data when today's file is missing.
Configuration, maintenance, and troubleshooting of AI Cohort scoreboard scripts including vault path setup and script updates.
Build and deliver periodic content digests (news, stock, entertainment) to multiple platforms: save to vault Raw/ and print full markdown to stdout for cron-based delivery.
Capture external content (X/Twitter articles, web posts) and ingest into Obsidian vault Raw/ with automatic theme detection, summarization, and structured frontmatter. Handles X/fixupx links via multi-strategy extraction (direct fetch → r.jina.ai → nitter fallback).
Weekly founder content research and production engine that transforms trending news into ready-to-use content assets.
| name | kb-compile |
| description | Compile all uncompiled raw/ content into the wiki. Writes source summaries, creates/updates concept articles with Obsidian backlinks, and updates the index. Run after /kb-ingest to process new content. |
| trigger | /kb-compile |
| metadata | {"capability":"medium"} |
Use compile_wiki.py — ignore the manifest. The vault at /opt/data/obsidian-vault/FACorreia is Syncthing-managed (not git). Both /opt/data/home/obsidian-vault/FACorreia and /opt/data/obsidian-vault/FACorreia resolve to the same location.
python3 /opt/data/obsidian-vault/FACorreia/scripts/compile_wiki.py --root /opt/data/obsidian-vault/FACorreia
Key facts:
AI, Books, Business, Careers, Dev, Health, Hermes, HermesPortfolio, NBA, News, Sports, Stocks, Swift, TV and Movies, Tech, WWE, XFeed, YouTube, uncategorized.kb/manifest.json exists but is stale (~4 entries vs 300+ raw files). Ignore it.git commit silently.Clippings/ directory exists with loose markdown files, move them to the correct raw/<Topic>/ subdirectory before compiling. Read YAML frontmatter tags or topic fields, or infer from filename/content (YouTube → appropriate topic directory, X/Twitter threads → Stocks or News, App Store/indie dev → Business, etc.). See references/clippings-relocation.md for the pattern.Check if {KB_PATH}/Clippings/ exists and contains files:
ls {KB_PATH}/Clippings/*.md 2>/dev/null
For each clipping file, read its YAML frontmatter and move it to the appropriate raw/<Topic>/ subdirectory. Infer topic from tags, topic, source, or filename patterns. After moving, delete the empty Clippings/ directory.
Run:
cat ~/.claude/kb-config.json
Extract kb_path. Expand ~ to the actual home directory path.
Set this as KB_PATH for all subsequent steps.
Run:
cat {KB_PATH}/.kb/manifest.json 2>/dev/null || echo "No manifest found"
Note: In this environment the manifest tracks only ~4 of 300+ raw files. It will almost always report 0 uncompiled entries even when hundreds exist. The compile_wiki.py script performs its own filesystem scan. If the manifest shows uncompiled entries, process them per the steps below — but do NOT treat 0 uncompiled entries as meaning the vault is fully compiled.
Run:
cat {KB_PATH}/wiki/index.md
Keep this in memory — you will append to it throughout this process.
For each file at {RAW_KEY} with status: uncompiled, do the following sub-steps in order.
Read {KB_PATH}/{RAW_KEY} using the Read tool.
Parse the YAML frontmatter to get source, ingested_at, and type.
The content below the frontmatter block is the main body.
Derive SOURCE_SLUG from {RAW_KEY}: take the filename portion without extension.
Example: raw/web/abs-1706-03762.md → SOURCE_SLUG = abs-1706-03762
Write to {KB_PATH}/wiki/sources/{SOURCE_SLUG}.md:
---
source: {value of `source` from raw frontmatter}
ingested_at: {value of `ingested_at` from raw frontmatter}
type: {value of `type` from raw frontmatter}
tags: [{3–8 lowercase tags you assign based on content, comma-separated, e.g. ml, transformers, attention}]
---
# {Title: infer from content, URL, or filename}
## Summary
{2–4 sentence summary of the source's main contribution, argument, or subject matter}
## Key Concepts
{Bulleted list of 3–8 key concepts this source covers, each formatted as [[concepts/{concept-slug}]] — {brief description}}
## Notable Details
{Any specific facts, figures, quotes, findings, or techniques worth preserving verbatim}
## Backlinks
- Source file: [[{RAW_KEY without .md extension}]]
From the Key Concepts list you wrote in 4b, extract each concept slug (the part inside [[concepts/{concept-slug}]]).
For each concept slug:
If {KB_PATH}/wiki/concepts/{concept-slug}.md does NOT exist:
Create it:
---
tags: [{relevant tags from the source}]
---
# {Concept Name (title-case of slug, e.g. attention-mechanism → Attention Mechanism)}
{2–4 paragraph article explaining this concept clearly. Write it as a standalone reference: define the concept, explain why it matters, describe how it works, and note any important variants or related ideas. Assume the reader knows the field but is encountering this concept for the first time.}
## Sources
- [[sources/{SOURCE_SLUG}]]
If {KB_PATH}/wiki/concepts/{concept-slug}.md DOES exist:
Read it. Then update it:
- [[sources/{SOURCE_SLUG}]] to the ## Sources section if not already presentFor each new concept article created in 4c (skip if the concept entry already exists in the index):
Append under ## Concepts:
- [[concepts/{concept-slug}]] — {one-line description of the concept}
For the source summary (skip if already in index):
Append under ## Sources:
- [[sources/{SOURCE_SLUG}]] — {one-line description: what this source is and its main contribution}
Only add entries not already present. Check by scanning existing index content.
Update the entry for {RAW_KEY} in the in-memory manifest JSON:
"{RAW_KEY}": {
\"status\": \"compiled\",
\"ingested_at\": \"{original ingested_at}\",
\"compiled_at\": \"{current UTC ISO timestamp}\",
\"source\": \"{original source}\",
\"type\": \"{original type}\",
\"wiki_articles\": [\"sources/{SOURCE_SLUG}.md\", \"concepts/{slug1}.md\", \"concepts/{slug2}.md\"],
\"tags\": [\"{tags you assigned in 4b}\"]
}
After processing all uncompiled files:
wiki/index.md back to disk (with all appended entries){KB_PATH}/.kb/manifest.jsonIf kb_search.py exists in {KB_PATH}, rebuild the search index:
python3 {KB_PATH}/kb_search.py --rebuild
If the file doesn't exist (first run before search tool is installed), skip this step silently.
cd {KB_PATH} && git add -A && git commit -m "kb: compile {N} source(s) into wiki"
PITFALL: The vault at /opt/data/obsidian-vault/FACorreia is Syncthing-managed, NOT a git repo. If git commit fails with "fatal: not a git repository", this is expected behavior. Syncthing handles file synchronization. Skip the commit silently.
Where N is the count of files just compiled.
Invoke the /kb-reflect skill to discover connections across newly compiled content.
[Existing content...]
Symptom: The compilation script runs but finds 0 files to compile, even though there are files in the raw directory.
Cause: The script expects the raw directory to be named Raw (capitalized), but the actual vault uses raw (lowercase). This mismatch can occur if the script was installed with a different convention or if the vault structure was manually changed.
Solution: Update the script's configuration to use the correct path. The configuration is in the compile_wiki.py script:
Open the script:
nano /root/.hermes/home/.hermes/scripts/compile_wiki.py
Find the configuration section (around lines 14-18):
VAULT_ROOT = "/opt/data/obsidian-vault/FACorreia" RAW_DIR = os.path.join(VAULT_ROOT, "raw") WIKI_DIR = os.path.join(VAULT_ROOT, "wiki")
3. Change `"Raw"` to `"raw"` and `"_wiki"` to `"wiki"` (if needed):
```python
RAW_DIR = os.path.join(VAULT_ROOT, "raw")
WIKI_DIR = os.path.join(VAULT_ROOT, "wiki")
Prevention: Ensure the script matches the actual vault structure. The Hermes knowledge base at /opt/data/obsidian-vault/FACorreia uses lowercase raw/ and wiki/ directories.
The most common issue when running kb-compile is permission problems with the vault directory. The vault at /opt/data/obsidian-vault/FACorreia is often owned by root:root with permissions drwxr-x---, which prevents the hermes user from accessing it.
Symptoms:
ls: cannot access '/opt/data/obsidian-vault/FACorreia': Permission deniedpython3: can't open file '~/.hermes/obsidian-vault/FACorreia/Raw/file.md': [Errno 13] Permission deniedSolution: Change ownership of the vault directory to the hermes user.
Using the Makefile (recommended):
cd /opt/data
make fix-permissions
This executes: docker compose exec -u root hermes chown -R hermes:hermes /opt/data
Manual chown (if Docker is not running):
sudo chown -R hermes:hermes /opt/data/obsidian-vault/FACorreia
After fixing permissions, verify access:
ls -la /opt/data/obsidian-vault/FACorreia
ls ~/.hermes/obsidian-vault/FACorreia/Raw/
If make fix-permissions fails with "Cannot connect to the Docker daemon", start Docker:
sudo systemctl start docker
If the vault directory is missing, you may need to set it up:
~/.hermes/scripts/setup-obsidian-vault.sh
Compiled {N} file(s):
- {RAW_KEY_1} → wiki/sources/{slug1}.md, wiki/concepts/...
- {RAW_KEY_2} → wiki/sources/{slug2}.md, wiki/concepts/...
/opt/data/obsidian-vault/FACorreia/scripts/compile_wiki.py