Overview
Design
Scaffold
/ingest
/query
/lint
Package
Use It
Pi Guide Wiki Guide
Build Guide

Pi × LLM Wiki

Combine Pi Agent's minimal primitives (read/write/edit/bash) with Karpathy's LLM Wiki pattern. Ship it as a Pi Package anyone can install with one command.

Why this combination works: LLM Wiki needs exactly what Pi already offers — file I/O, multi-provider LLMs, extension hooks, and session persistence. No server, no vector DB required. Just markdown files, prompt templates, and three operations.
~2 hours to build
Zero backend
200+ LLM providers
Shareable via npm
MIT license

What You'll End Up With

A Pi Package called @you/pi-llm-wiki that anyone can install and use. After they run pi install, their Pi instance gains:

  • /ingest — process a source file into wiki pages
  • /query — search the wiki and synthesize an answer
  • /lint — audit the wiki for contradictions and orphans
  • /skill:ingest-pdf — format-aware PDF ingestion
  • /skill:ingest-web — web clip ingestion via curl
  • /skill:rip-from-youtube — YouTube transcripts + metadata via yt-dlp
  • A starter AGENTS.md template for defining wiki purpose

Build It Step-by-Step

1. Design
Map Pi's primitives onto LLM Wiki operations. Understand the integration.
architecture
2. Scaffold
Create the Pi Package project structure and manifest.
setupnpm
3. /ingest
The prompt template that turns one source into 10-15 wiki pages.
templateskills
4. /query
Search via grep + synthesize with citations. File useful answers back.
searchcitations
5. /lint
Audit for contradictions, orphans, stale claims, missing cross-refs.
maintenance
6. Package
Bundle for distribution. Test locally, publish to npm or ship via git.
publish
7. Use It
Install flow, daily workflow, and optional Cloudflare Pages publishing.
workflowdeploy

The One-Sentence Pitch

Pi's minimalism is the feature, not the bug. Karpathy's pattern doesn't need pre-baked complexity — it needs composable primitives. Pi gives you read/write/edit/bash, four LLM providers, and an extension system. That's exactly enough.

Prerequisites

Pi Agent installed
npm install -g @mariozechner/pi-coding-agent
Node.js 20+
For the package workspace
An LLM key
Or Pi OAuth subscription
A git repo
Optional — for sharing via pi install git:
Integration Architecture

The Mapping

Every LLM Wiki operation maps cleanly onto a Pi primitive or extension point. No impedance mismatch.

Pi Primitive → Wiki Role

Pi Agent
LLM Wiki
read tool
Load raw source · Read existing wiki page
write tool
Create new wiki page · Overwrite overview.md
edit tool
Update existing page · Append to log.md · Fix cross-ref
bash tool
grep/find across wiki · curl for web clips · git commit
Prompt template
/ingest /query /lint — the three operations
Skill (SKILL.md)
Format-specific ingest — PDF, web, DOCX
AGENTS.md context
Schema / Purpose layer (Layer 3)
Session JSONL
Resume long ingest runs · Fork for experiments
--model flag
Cheap model for lint · smart model for synthesis
@-mentions
Reference wiki pages in prompts

System Diagram

USER INTERFACE pi /ingest pi /query pi /lint │ │ │ └─────────┼─────────┘ ┌───────────────────┐ │ Pi Agent Loop │ │ (pi-agent-core) │ └─────────┬─────────┘ ┌───────────┬───────────┼───────────┬───────────┐ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ │ read │ │write │ │ edit │ │ bash │ │skills│ └──┬───┘ └──┬───┘ └──┬───┘ └──┬───┘ └──┬───┘ │ │ │ │ │ └─────────┴──────────┼──────────┴──────────┘ ┌───────────────────┐ │ my-wiki/ │ │ AGENTS.md │ (schema) │ raw/ │ (sources) │ wiki/ │ (generated) │ index.md │ │ log.md │ │ entities/ │ │ concepts/ │ │ sources/ │ │ queries/ │ └───────────────────┘

What You Don't Need

The nashsu reference implementation includes extensive machinery — LanceDB vectors, Louvain clustering, sigma.js graph, Tauri desktop shell. The base pattern needs none of it. What Pi handles natively:

Search

bash grep -r with good prompting beats vector DB for wikis under ~1000 pages.

Cross-references

Standard markdown [[wikilinks]] or [text](path). Obsidian-compatible.

UI

Any markdown editor (VSCode, Obsidian, Typora) reads the wiki directly. No custom desktop app.

Persistence

Just files on disk. Version control via git. Sync via Dropbox/iCloud.

Start minimal. Get /ingest and /query working on a folder of PDFs first. Add vectors, graph, clustering only when the wiki has enough pages that grep stops being enough — that's many months of use for most users.

Design Trade-offs

DecisionRationale
Markdown files, not DBPortable, versionable, readable by any tool. Plays with Obsidian.
grep over vectorsZero dependencies. Works offline. Good enough up to ~1000 pages.
Prompt templates, not extensionsUsers can edit .md files to customize. No TypeScript needed.
Skills for formats onlyPDF, DOCX, web clips need specific parsing. Everything else is text.
AGENTS.md as schemaPi already reads it. One file defines purpose + wiki rules.
Git commits per ingestWiki history is the audit log. Revert bad ingests trivially.
Step 2

Scaffold the Package

Create the Pi Package project structure. Seven files, no build step.

Project Structure

pi-llm-wiki/ ├── package.json # npm manifest + Pi exports ├── README.md # User docs ├── LICENSE # MIT ├── prompts/ # Slash command templates │ ├── ingest.md │ ├── query.md │ └── lint.md ├── skills/ # Format-specific skills │ ├── ingest-pdf/ │ │ └── SKILL.md │ ├── ingest-web/ │ │ └── SKILL.md │ ├── ingest-docx/ │ │ └── SKILL.md │ └── rip-from-youtube/ # yt-dlp transcript ripping │ └── SKILL.md └── templates/ # Starter wiki scaffolding ├── AGENTS.md # Schema template └── initial-wiki/ ├── index.md ├── log.md └── overview.md

Create the Directory

mkdir pi-llm-wiki && cd pi-llm-wiki mkdir -p prompts skills/ingest-pdf skills/ingest-web skills/ingest-docx \ skills/rip-from-youtube templates/initial-wiki npm init -y

package.json

package.json
{ "name": "@you/pi-llm-wiki", "version": "0.1.0", "description": "LLM Wiki pattern as a Pi Package — self-maintaining knowledge base", "license": "MIT", "keywords": ["pi", "pi-package", "llm-wiki", "knowledge-base"], "pi": { "prompts": "./prompts", "skills": "./skills", "templates": "./templates" }, "files": ["prompts", "skills", "templates", "README.md", "LICENSE"], "repository": { "type": "git", "url": "https://github.com/YOU/pi-llm-wiki" } }
The pi field is what makes this a Pi Package. Pi looks for it during pi install and wires the prompts, skills, and templates into the agent's configuration. Without it, it's just an npm package.

AGENTS.md Template

This is the schema/purpose document users customize for their specific wiki. Ship a template that explains what to edit.

templates/AGENTS.md
# Wiki Purpose ## What this wiki is for [Edit: One paragraph. What knowledge are you accumulating? Who is it for?] ## Key questions [Edit: List 3-7 questions you expect to ask this wiki over time.] ## Scope - In scope: [Types of sources to ingest] - Out of scope: [Things to ignore even if mentioned] # Wiki Rules ## File layout - raw/ — immutable source documents. Pi reads, never writes. - wiki/ — LLM-generated pages. Structured as: - index.md — catalog with one-line summaries per page - log.md — chronological append-only log - overview.md — auto-updated summary - entities/ — people, orgs, projects, products - concepts/ — ideas, patterns, theories - sources/ — one page per raw source - queries/ — filed answers to past questions - synthesis/ — cross-cutting analysis pages ## Page format Every wiki page starts with YAML frontmatter: --- title: Canonical Title type: entity | concept | source | query | synthesis sources: [raw/foo.pdf, raw/bar.md] related: [[other-page]], [[another-page]] updated: 2026-04-12 --- ## Linking Use [[wiki-style]] links for internal references. Resolve to file paths on deploy. ## Tone [Edit: Neutral? Conversational? Academic? Terse?] ## Language [Edit: English? Multilingual? Something else?]

Initial Wiki Templates

templates/initial-wiki/index.md
--- title: Wiki Index type: index updated: 2026-04-12 --- # Wiki Index ## Entities (empty — populated by /ingest) ## Concepts (empty — populated by /ingest) ## Sources (empty — populated by /ingest) ## Queries (empty — populated by /query) ## Synthesis (empty — populated by /query and /lint)
templates/initial-wiki/log.md
--- title: Wiki Log type: log --- # Wiki Log ## 2026-04-12 - 00:00:00 Wiki initialized from pi-llm-wiki template

Next Steps

Scaffold completeAll directories and templates in place
Write /ingest templateNext section
Write /query templateAfter that
Write /lint templateThen finalize
Publish as npm packageSee Package section
Step 3

/ingest

The heaviest operation. One source becomes 10-15 wiki page updates. Two-phase: analyze, then write.

The Prompt Template

prompts/ingest.md
--- name: ingest description: Process a source into wiki pages (pass file path as argument) --- You are maintaining an LLM Wiki. The user will name a source file to ingest. ## Phase 1 — Analysis (don't write yet) 1. Read raw/<source> in full. 2. Read AGENTS.md to refresh yourself on this wiki's purpose. 3. Read wiki/index.md to see what already exists. 4. Identify: - Entities (people, orgs, projects, products, places) mentioned - Concepts (ideas, patterns, claims) introduced or extended - Relationships between them - Which existing wiki pages are affected - Which new pages are warranted 5. Briefly explain your plan. Wait for confirmation if the plan touches >10 pages. ## Phase 2 — Generation Execute the plan: 1. Write wiki/sources/<slug>.md — summary of the source with key extractions. 2. For each new entity/concept identified: - Write wiki/entities/<slug>.md or wiki/concepts/<slug>.md 3. For each existing page affected: - Edit it with new information, preserving existing content. - Add a citation to the source. 4. Edit wiki/index.md to catalog any new pages. 5. Edit wiki/log.md to append a timestamped entry describing what changed. 6. Bash: git add wiki/ && git commit -m "ingest: <source slug>" ## Rules - Every page has YAML frontmatter (see AGENTS.md). - Every claim traceable to a source file via sources: frontmatter. - Prefer linking to existing pages over duplicating content. - Never modify anything in raw/. - If unsure whether something warrants a page, ask. ## Output style Terse. The wiki is a reference, not an essay. One paragraph per section max.

Two-Phase Pattern

Phase 1: AnalyzeRead source + existing wiki; propose plan; wait if large
Phase 2: ExecuteWrite new pages; edit affected pages; update index + log; commit
Why two phases? The analysis phase spends context on understanding the source. The generation phase uses that understanding to make precise edits. Single-phase prompting tends to either over-write (bloated pages) or under-reference (orphans). Two phases with a visible plan is the fix.

Format-Specific Skills

Plain text and markdown sources work with Pi's built-in read tool. Other formats need a skill.

PDF Ingest Skill

skills/ingest-pdf/SKILL.md
--- name: ingest-pdf description: Extract text from a PDF and ingest it into the wiki --- # PDF Ingest ## When to use The user wants to ingest a PDF. Arguments: path to the PDF file. ## Procedure 1. Bash: extract the text to a temp markdown file: pdftotext -layout "$PDF" /tmp/pdf-text.md 2. Read /tmp/pdf-text.md and assess quality: - If text extraction is poor, try pdftoppm + vision model. - If OCR is needed, suggest ocrmypdf to the user first. 3. Once you have clean text, follow the /ingest template's two-phase workflow, treating /tmp/pdf-text.md as the source. 4. Before finishing, also Bash: cp "$PDF" raw/ so the original is preserved. 5. Reference the raw/<filename>.pdf as the source in the wiki page (not the temp file). ## Dependencies - pdftotext (from poppler-utils) — required - pdftoppm — optional, for image-based PDFs - ocrmypdf — optional, for scanned PDFs ## Notes - PDFs with heavy layout (tables, multi-column) may need --raw or --layout tuning. - If the PDF is an academic paper, use the paper's bibkey as the slug.

Web Clip Ingest Skill

skills/ingest-web/SKILL.md
--- name: ingest-web description: Fetch a URL, clean it with Readability, ingest as a wiki source --- # Web Clip Ingest ## When to use The user pastes a URL and wants to ingest the article/page into the wiki. ## Procedure 1. Bash: fetch the page: curl -sL "$URL" -A "Mozilla/5.0" -o /tmp/raw.html 2. Bash: extract main content with a readability CLI: npx @mozilla/readability-cli /tmp/raw.html > /tmp/clean.md (If unavailable, fall back to pandoc -f html -t markdown /tmp/raw.html.) 3. Read /tmp/clean.md. 4. Bash: generate a slug from the URL host + date: echo "$URL" | awk -F/ '{print $3}'-$(date +%Y%m%d) 5. Write raw/web/<slug>.md with YAML frontmatter: url: $URL clipped: $(date) title: $TITLE Then the cleaned body. 6. Follow the /ingest two-phase workflow from this point. ## Dependencies - curl — universal - @mozilla/readability-cli via npx — preferred - pandoc — fallback

Rip-from-YouTube Skill

Talks, lectures, podcasts, and interviews are some of the richest knowledge sources — but they're locked in video. This skill rips transcripts and metadata via yt-dlp, falls back to Whisper if captions aren't available, and feeds the result into the standard /ingest workflow.

Why YouTube matters for wikis: A 90-minute Lex Fridman interview has more synthesizable signal than most papers. A conference talk compresses a year of research. Once transcribed, these sources behave like any other text — the wiki doesn't care where the words came from.
skills/rip-from-youtube/SKILL.md
--- name: rip-from-youtube description: Rip transcript + metadata from a YouTube URL and ingest as a wiki source --- # Rip from YouTube ## When to use The user pastes a YouTube URL (watch, youtu.be, live, or shorts) and wants the video's content ingested into the wiki. Common cases: conference talks, podcast episodes, lectures, interviews, tutorials. ## Procedure ### 1. Pull metadata + auto-captions Bash: mkdir -p /tmp/yt raw/youtube yt-dlp --write-auto-sub --write-sub --sub-lang en \ --sub-format vtt --skip-download --write-info-json \ -o "/tmp/yt/%(id)s.%(ext)s" "$URL" ### 2. Convert VTT to plain text Bash: for f in /tmp/yt/*.vtt; do sed -E 's/<[^>]+>//g; /^\s*$/d; /-->/d; /^WEBVTT/d; /^Kind:/d; /^Language:/d; /^[0-9]+$/d' "$f" \ | awk '!seen[$0]++' > "${f%.vtt}.txt" done ### 3. Fallback to Whisper if no captions If no .vtt file was produced, the video has no captions available. Extract audio and transcribe: Bash: yt-dlp -x --audio-format mp3 -o "/tmp/yt/%(id)s.%(ext)s" "$URL" whisper /tmp/yt/$ID.mp3 --output_format txt --output_dir /tmp/yt/ --model base (For faster/cheaper runs, use whisper.cpp or an API like Groq's Whisper endpoint.) ### 4. Parse metadata Read /tmp/yt/$ID.info.json. Extract: - title, channel, upload_date, duration - description, tags, chapters (if present) - view_count, like_count (optional but useful for prioritization) ### 5. Generate a slug Bash: slug=$(echo "$CHANNEL-$UPLOAD_DATE-$TITLE" \ | iconv -f utf-8 -t ascii//translit \ | tr '[:upper:]' '[:lower:]' \ | tr -cs 'a-z0-9' '-' \ | sed 's/^-\|-$//g' \ | cut -c1-80) ### 6. Write the raw source Write raw/youtube/$slug.md: --- url: $URL video_id: $ID title: $TITLE channel: $CHANNEL duration: $DURATION uploaded: $UPLOAD_DATE clipped: $(date +%Y-%m-%d) chapters: [optional] --- # $TITLE **Channel:** $CHANNEL · **Duration:** $DURATION · **Uploaded:** $UPLOAD_DATE **URL:** $URL ## Description $DESCRIPTION ## Transcript <paste contents of /tmp/yt/$ID.txt here> ### 7. Ingest Follow the /ingest two-phase workflow using raw/youtube/$slug.md as the source. When writing wiki entity/concept pages, cite the video as: [[<slug>]] (YouTube, $CHANNEL, $UPLOAD_DATE) For long videos with chapters, include timestamp anchors when citing specific claims: ...argues that context engineering beats prompt engineering [[$slug#t=23m14s]] ## Dependencies - yt-dlp — required. Install: pip install -U yt-dlp or brew install yt-dlp - ffmpeg — required (yt-dlp dependency for audio extraction) - whisper or whisper.cpp — optional. Only needed for videos without captions. - iconv — optional. For slug transliteration of non-ASCII titles. ## Edge cases - Auto-captions vs manual: --write-sub gets manual; --write-auto-sub gets YouTube's ASR. Prefer manual when present; it's almost always cleaner. - Long videos (>2hr): Ingest can exceed context window. Chunk the transcript into 30-minute sections, ingest each as a sub-source (raw/youtube/$slug-part-1.md, -part-2.md, etc.), then write a parent page that links them. - Live streams: Pass --live-from-start to yt-dlp if the stream is archived. - Age-restricted / private: yt-dlp supports --cookies-from-browser firefox for authenticated access. - Non-English: Use --sub-lang all to get every available track; pick the most useful one at ingest time. ## Respect This skill is for personal knowledge work — transcripts inform your wiki, don't leave your machine. Don't use it to republish creator content.

Testing the Template

# With a fresh wiki directory mkdir my-wiki && cd my-wiki cp -r ../pi-llm-wiki/templates/initial-wiki/* wiki/ cp ../pi-llm-wiki/templates/AGENTS.md . mkdir raw && mv ~/some-paper.pdf raw/ # Edit AGENTS.md to define wiki purpose pi "Help me fill in AGENTS.md for a wiki about distributed systems papers" # Run ingest pi /ingest raw/some-paper.pdf
First ingest is the hardest. With no existing wiki pages, the LLM has no anchors to cross-reference. Subsequent ingests get progressively easier as the graph densifies — this is the compounding effect working in your favor.
Step 4

/query

Search the wiki, synthesize with citations, optionally file the answer back as a new page.

The Prompt Template

prompts/query.md
--- name: query description: Answer a question using the wiki, with citations --- You are answering a question using the wiki in wiki/. ## Phase 1 — Search 1. Read AGENTS.md to refresh wiki purpose. 2. Read wiki/index.md to see the topic layout. 3. Bash: grep for the question's key terms: grep -rli "<term>" wiki/ | head -20 4. For each candidate page, Read it. 5. Follow [[wikilinks]] and related: frontmatter to adjacent pages. 6. Stop when you have enough to answer (typically 3-7 pages). ## Phase 2 — Answer Synthesize an answer with: - Inline citations like [[page-slug]] for every non-trivial claim. - A "Sources" section at the bottom listing which wiki pages were used. - A "Gaps" section noting what you couldn't answer from the wiki. ## Phase 3 — File it If the question is substantive (not trivially obvious from one page): 1. Ask the user if they want this query filed as a wiki page. 2. If yes: Write wiki/queries/<slug>.md with the question and your answer. 3. Edit wiki/index.md to list the new query page. 4. Edit referenced pages to add a back-link in their related: frontmatter. 5. Bash: git add wiki/ && git commit -m "query: <slug>" ## Rules - Never invent claims not supported by wiki pages. Say "not in wiki" instead. - Distinguish direct citations (page says X) from inference (pages A+B imply X). - Prefer concise answers over exhaustive ones. Link to pages for depth. - When the wiki is clearly missing information, suggest sources to ingest.

Search Strategy

The bash grep approach is deliberately simple. For wikis under ~1000 pages, ripgrep across markdown is faster and more precise than vector DBs.

# Basic keyword search rg -li "term" wiki/ # Multi-term with context rg -i -C2 "term1|term2" wiki/ # Scoped to one section rg -li "term" wiki/entities/ # Find pages linking to a specific page rg -l "\[\[my-page\]\]" wiki/ # Find orphan pages (nothing links to them) comm -23 \ <(find wiki -name "*.md" -printf "%f\n" | sed 's/\.md$//' | sort) \ <(rg -o '\[\[([^\]]+)\]\]' -r '$1' wiki/ | sort -u)

Citation Format

Every claim in the answer should cite its source wiki page:

# Example answer format Claude 4.6 Opus was released in [[anthropic-timeline]] with a 1M context window [[claude-context-limits]]. It introduced native tool calling via the Messages API [[claude-tool-use]] and deprecated the legacy Completions endpoint [[api-migration]]. ## Sources - [[anthropic-timeline]] — release dates - [[claude-context-limits]] — context window specs - [[claude-tool-use]] — tool calling docs - [[api-migration]] — deprecation notices ## Gaps - The wiki has no pages on pricing for 1M context. - No information on regional availability. - Consider ingesting: the Anthropic pricing blog post.

Filing Queries Back

This is the compounding mechanism. A good query answer doesn't evaporate when the user reads it. It becomes a page future queries can cite. Over months of use, wiki/queries/ becomes the wiki's most referenced folder — a distilled layer of human-interesting conclusions.

Example Query Page

wiki/queries/claude-46-changes.md
--- title: What changed in Claude 4.6? type: query asked: 2026-04-12 sources: [[anthropic-timeline]], [[claude-context-limits]], [[claude-tool-use]] related: [[claude-36-release]], [[claude-37-release]] --- # What changed in Claude 4.6? Three headline changes: 1. 1M context — up from 200K [[claude-context-limits]]. 2. Native tool use via Messages API [[claude-tool-use]]. 3. Completions deprecated in favor of Messages [[api-migration]]. ## Gaps identified - Pricing for 1M context not documented in wiki. - Suggested ingest: https://anthropic.com/pricing
Step 5

/lint

Audit the wiki for contradictions, orphans, stale claims, and broken cross-references. Run on a schedule or after large ingest batches.

The Prompt Template

prompts/lint.md
--- name: lint description: Audit wiki health — contradictions, orphans, stale claims, broken refs --- You are running a health check on the wiki in wiki/. ## Audit Checklist Run these checks, log issues to wiki/lint-report.md (overwrite each time). ### 1. Broken links Bash: for link in $(rg -o '\[\[([^\]]+)\]\]' -r '$1' wiki/ | sort -u); do if ! find wiki -name "$link.md" -print -quit | grep -q .; then echo "BROKEN: $link" fi done ### 2. Orphan pages Bash: find pages nothing links to (from previous section). Flag any that are not in wiki/sources/ or wiki/log.md. ### 3. Stale sources frontmatter Bash: for each page's sources: frontmatter, verify the raw file exists: while read -r page src; do test -f "raw/$src" || echo "MISSING SOURCE: $page -> $src" done < <(grep -l "^sources:" wiki/ -r ...) ### 4. Contradiction scan (LLM step) For each entity/concept page, Read it and: - Identify claims that are specific, falsifiable, and dated. - Bash: rg for the entity name across wiki/ to find claims elsewhere. - Flag any pairs that appear to contradict. ### 5. Catalog drift Bash: compare wiki/index.md listings against actual files: diff <(ls wiki/entities/ | sed 's/\.md$//') \ <(grep -oP '(?<=entities/)\w+' wiki/index.md | sort -u) ### 6. Missing cross-references For the top-20 most-referenced entities, check they link to each other where sources indicate relationships. ## Output Write wiki/lint-report.md with sections: - Broken links (exact, auto-fixable) - Orphans (needs human decision) - Missing sources (ingest gone wrong) - Possible contradictions (needs human judgment) - Catalog drift (safe to auto-fix) - Suggested links (optional improvements) ## Auto-fix policy - Broken link to nonexistent page → ask user: stub or remove the link? - Catalog drift → ask user to confirm, then auto-fix. - Orphan in queries/ → leave alone (query pages are often orphans). - Orphan in entities/ or concepts/ → suggest linking from index.md. - Contradictionsnever auto-fix. Human must resolve.

What Lint Catches

Broken Links

[[missing-page]] where missing-page.md doesn't exist. Often from renamed pages.

Orphan Pages

Entity and concept pages nothing links to. Sign of a failed ingest or abandoned topic.

Missing Sources

Frontmatter references raw/foo.pdf but the file was deleted. Wiki page is now unmoored.

Contradictions

"Founded 2018" on one page, "Founded 2019" on another. The expensive check — run monthly, not daily.

Stale Claims

Pages older than 12 months with specific, time-sensitive claims (prices, release dates, headcounts).

Catalog Drift

wiki/index.md lists pages that were deleted, or omits pages that exist.

Running Lint

# Interactive lint run pi /lint # Non-interactive (for cron) pi -p --tools read,bash,write,edit "/lint" # With cheap model (lint doesn't need Opus) pi --model openai/gpt-4o-mini "/lint"
Use a cheap model for lint. The audit is mostly pattern matching and cross-referencing — not deep synthesis. GPT-4o-mini or Claude Haiku 4.5 runs lint at 1/20th the cost of Opus with near-equal quality.

Scheduled Lint (Optional)

Run lint automatically after each week of ingests:

# Add to crontab crontab -e # Run every Sunday at 9am 0 9 * * 0 cd /path/to/my-wiki && \ pi --model openai/gpt-4o-mini -p "/lint" \ | tee .llm-wiki/lint-$(date +\%F).log
Step 6

Package & Publish

Bundle for distribution. Three shipping options: git, npm, or GitHub Pages for a landing page.

Test Locally First

# From inside the pi-llm-wiki/ directory pi install . # Verify prompts are registered pi list # Expected output: pi-llm-wiki (local) prompts: ingest, query, lint skills: ingest-pdf, ingest-web, ingest-docx templates: AGENTS.md, initial-wiki/

End-to-End Smoke Test

# Create a test wiki mkdir -p /tmp/test-wiki && cd /tmp/test-wiki # Bootstrap from template cp -r ~/.pi/agent/packages/pi-llm-wiki/templates/initial-wiki wiki cp ~/.pi/agent/packages/pi-llm-wiki/templates/AGENTS.md . mkdir raw # Add a source echo "# Test Note\nClaude 4.6 Opus has 1M context." > raw/test.md # Run ingest git init && pi "/ingest raw/test.md" # Verify wiki/ was populated ls wiki/entities/ wiki/sources/

Option A — Ship via Git

Fastest for internal use or early iteration. Push to GitHub, others install directly.

git init git add -A git commit -m "initial release" git remote add origin git@github.com:YOU/pi-llm-wiki.git git push -u origin main # Users install with: pi install git:github.com/YOU/pi-llm-wiki

Option B — Publish to npm

Best for broad distribution. Versioned, discoverable, updatable.

# First time: create npm account npm adduser # Publish (scope must exist on npm) npm publish --access public # Users install with: pi install npm:@you/pi-llm-wiki # Release a new version npm version patch # or minor/major git push --follow-tags npm publish
Scoped package names are free on npm as long as you publish with --access public. Use @yourname/pi-llm-wiki to avoid collisions with other authors.

Option C — Landing Page on Cloudflare Pages

Ship a static marketing/docs page alongside the package. Same aesthetic as this guide.

# Add a docs/ directory to the repo mkdir docs # Add index.html (single-file docs SPA — reuse this template!) # Deploy wrangler pages project create pi-llm-wiki --production-branch=main wrangler pages deploy docs --project-name=pi-llm-wiki --commit-dirty=true # Live at: https://pi-llm-wiki.pages.dev/

README Checklist

The README is what users see first on npm and GitHub. Cover:

  • One-sentence pitch (“personal knowledge base that builds itself”)
  • 30-second install + first ingest example
  • Link to the full docs site (Option C above)
  • What LLM providers work (inherits from Pi — all 20+)
  • License (MIT) and contribution note

Version Strategy

VersionWhat Changed
0.1.0Initial release — ingest/query/lint working on text + PDF
0.2.0Added ingest-web skill, web clip support
0.3.0Added ingest-docx, ingest-audio (Whisper-based)
1.0.0Stable schema.md format, backwards-compat guarantee
1.x.xNew skills, templates, and ancillary commands
2.0.0If you ever need to break the AGENTS.md format
Step 7

Use It

From cold install to a living knowledge base. End-to-end workflow plus optional publishing.

Install Flow

# 1. Make sure Pi is installed npm install -g @mariozechner/pi-coding-agent # 2. Authenticate once pi /login # OAuth via subscription # OR export ANTHROPIC_API_KEY=sk-ant-... # 3. Install your package pi install npm:@you/pi-llm-wiki # 4. Verify pi list

Create Your First Wiki

1. Make a directorymkdir research-wiki && cd research-wiki
2. Bootstrap from templateUse Pi to copy AGENTS.md and initial-wiki/ into place
3. Customize AGENTS.mdDefine wiki purpose, scope, and key questions
4. Git initgit init && git add -A && git commit -m "init"
5. Add sourcesDrop PDFs, notes, web clips into raw/
6. Ingestpi "/ingest raw/paper.pdf" — watch the wiki appear
7. Querypi "/query what are the main findings?"

Daily Workflow

Morning

Drop the day's reading into raw/. Run /ingest on each source.

Research

Ask questions with /query. File substantive answers as pages.

Weekly

Run /lint on Sunday morning. Resolve flagged items over coffee.

Monthly

Read wiki/log.md. Notice what themes emerged. Adjust AGENTS.md if needed.

Backup

The wiki is git. Push nightly. No separate backup needed.

Browse

Open the wiki folder in Obsidian or VS Code. Native markdown, no custom app.

Publish the Wiki (Optional)

Push the wiki/ folder to Cloudflare Pages for a public knowledge base. Wikilinks convert to real HTML links during build.

# Convert wikilinks to HTML-compatible links pi "Convert all [[page]] links in wiki/ to markdown [text](./page.md) format, preserving anchor text where provided via [[page|text]] syntax" # Render with a static site generator (any will do) npx mdbook build wiki --dest docs-site # OR npx @11ty/eleventy --input=wiki --output=docs-site # Deploy wrangler pages project create my-wiki --production-branch=main wrangler pages deploy docs-site --project-name=my-wiki --commit-dirty=true # Public at: https://my-wiki.pages.dev/
Public wikis are the endgame. The knowledge you've accumulated becomes a living resource others can read. Changelog-as-blog, research-notes-as-reference, competitive-intel-as-public-tracker — all valid patterns.

Cost Estimate

OperationModelTypical Cost
/ingest (10-page PDF)Claude Sonnet 4.6~$0.05-0.15
/ingest (web clip)Claude Sonnet 4.6~$0.01-0.05
/query (simple)Claude Sonnet 4.6~$0.01-0.03
/query (deep synthesis)Claude Opus 4.6~$0.10-0.30
/lint (500-page wiki)GPT-4o-mini~$0.02-0.05
Subscription auth is basically free. Via Pi's /login, Claude Pro and ChatGPT Plus subscribers use their existing quota — no per-call charges for most usage.

What's Next

Pi Agent Deep Dive
Extensions, skills, customization
LLM Wiki Pattern
Karpathy's original + nashsu's impl
pi-mono Source
Build your own Pi Package
Karpathy's Gist
The original spec
pi-llm-wiki-guide
8 sections
Pi × LLM Wiki
MIT
pi-llm-wiki-guide.pages.dev/#home