UNPKG

@zosmaai/pi-llm-wiki

Version:

Self-maintaining LLM Wiki for Pi — Karpathy-pattern knowledge base with immutable source capture, automated ingestion, search, linting, and Obsidian-compatible vault. auto-updating personal & company wiki.

467 lines (334 loc) 15.7 kB
# API Reference All tools registered by the extension. Parameters marked `?` are optional. 13 tools are always registered. The 3 agent-trajectory tools (`wiki_capture_trajectory`, `wiki_distill_skills`, `wiki_recall_skill`) are **opt-in, off by default** (issue #80) — they are only registered when `llm-wiki.trajectories` is `true`; enable with `/wiki-trajectories on`. --- ## wiki_bootstrap Initialize a new LLM Wiki vault with the 4-layer architecture. Creates config, templates, schema, and metadata scaffolding. **Parameters** | Name | Type | Required | Description | |------|------|----------|-------------| | `topic` | `string` | | Main topic of the wiki | | `mode` | `string` | | `"personal"` or `"company"` (default: `"personal"`) | | `root` | `string` | | Root directory to bootstrap in (default: current working directory) | **Returns** ``` details: { root: string, mode: string, topic: string } ``` Confirmation text includes the vault path, directory layout, and a prompt to capture the first source. --- ## wiki_capture_source Capture a URL, local file, or pasted text into an immutable source packet and skeleton source page. Provide exactly one of `url`, `file_path`, or `text`. **Parameters** | Name | Type | Required | Description | |------|------|----------|-------------| | `url` | `string` | | URL to fetch and capture | | `file_path` | `string` | | Absolute or relative path to a local file (PDF, md, txt, html, XML, JSON) | | `text` | `string` | | Pasted text content to capture directly | | `title` | `string` | | Title override (used for `text` captures; inferred from URL/file otherwise) | **Returns** ``` details: { sourceId: string, // e.g. "SRC-2026-06-03-001" packetPath: string, // path to raw/sources/SRC-.../ sourcePagePath: string, // path to wiki/sources/SRC-....md (skeleton) extractedPreview: string // first 300 chars of extracted content } ``` Errors with `isError: true` if no vault exists or no source input is provided. --- ## wiki_ingest Return a batch of uningested source packets for the LLM to synthesize. Does not write anything itself the model reads the returned extracted content, fills in the skeleton source page, and creates entity/concept pages. **Parameters** | Name | Type | Required | Description | |------|------|----------|-------------| | `source_id` | `string` | | Process a specific source ID only; leave empty to get the next unprocessed batch | | `batch_size` | `number` | | Max sources to return (default: `3`, max: `5`) | **Returns** ``` details: { batch: string[], // source IDs in this batch, e.g. ["SRC-2026-06-03-001"] remaining: number // sources still waiting after this batch } ``` Each batch entry includes the source title, char count, and the path to read (`raw/sources/{id}/extracted.md`). Returns a "all sources ingested" message with `{ ingested, total }` when nothing is pending. --- ## wiki_ensure_page Resolve or safely create a canonical wiki page. Returns immediately if the page already exists (no overwrite). Uses a built-in template when `content` is not provided. **Parameters** | Name | Type | Required | Description | |------|------|----------|-------------| | `type` | `string` | | Page type: `"entity"`, `"concept"`, `"synthesis"`, `"analysis"`, `"requirement"`, `"skill"`, or `"case"` | | `title` | `string` | | Human-readable page title; auto-slugified to a kebab-case filename | | `content` | `string` | | Full markdown content for the page; if omitted, the type-appropriate template is used | **Returns** ``` details: { path: string, created: boolean } ``` `created: false` means the page already existed and was not modified. --- ## wiki_recall Search both the personal (`~/.llm-wiki/`) and project (`.llm-wiki/`) vaults for pages relevant to a query. Uses chunk-level scoring, weighted field matching, and pseudo-relevance feedback. Also called automatically before every agent turn. **Parameters** | Name | Type | Required | Description | |------|------|----------|-------------| | `query` | `string` | | Search query use the user's full request or key terms | | `max_results` | `number` | | Maximum pages to return (default: `5`, max: `10`) | **Returns** ``` details: { query: string, matches: Array<{ id: string, // folder-qualified page ID, e.g. "concepts/rag" title: string, type: string, // "source" | "entity" | "concept" | "synthesis" | "analysis" preview: string, // best-matching chunk or page intro (~200 chars) path: string, // absolute filesystem path to the .md file score: number, // relevance score (higher = better) vaultLabel?: string // "📓 personal" when result is from the personal vault }> } ``` Returns empty `matches: []` with a hint to use `wiki_retro` when the wiki has no matching pages. --- ## wiki_search Exact keyword search across the generated registry. Faster and simpler than `wiki_recall` no scoring, no PRF, no vault layering. Use for lookups when you already know what you're looking for. **Parameters** | Name | Type | Required | Description | |------|------|----------|-------------| | `query` | `string` | | Search term matched against page IDs, titles, and types | | `type` | `string` | | Filter results to a specific page type (e.g. `"concept"`, `"entity"`) | **Returns** ``` details: { query: string, matches: Array<{ id: string, title: string, type: string }> } ``` --- ## wiki_retro Save an atomic insight from a completed task as a single lightweight markdown file in `wiki/sources/`. Does not create a full source packet. Rebuilds metadata immediately so the insight is searchable in the same session. **Parameters** | Name | Type | Required | Description | |------|------|----------|-------------| | `slug` | `string` | | Unique kebab-case identifier (e.g. `"jwt-revocation-pattern"`). Used as the filename and for lookups. | | `title` | `string` | | Short descriptive title, 60 chars max. Noun phrase, not a sentence. | | `body` | `string` | | Markdown content explaining what was learned. Include `[[wikilinks]]` to related pages. | | `category` | `string` | | Optional grouping label (e.g. `"frontend"`, `"architecture"`, `"devops"`, `"bugfix"`) | **Returns** ``` details: { slug: string, title: string, category: string | null } ``` --- ## wiki_observe Record a timestamped, relevance-rated observation during a session. Saved to `wiki/sources/` with `status: observation`. Immediately searchable via `wiki_recall`. Intended for mid-session capture; use `wiki_retro` for end-of-task summaries. **Parameters** | Name | Type | Required | Description | |------|------|----------|-------------| | `title` | `string` | | Short descriptive title, ≤80 chars. Noun phrase, not a sentence. | | `content` | `string` | | Plain prose: what happened, was decided, or was learned. Preserve specifics (file paths, function names, error messages, numbers). | | `relevance` | `"low" \| "medium" \| "high" \| "critical"` | | Retention priority. `low` = routine; `medium` = task context; `high` = non-trivial decisions; `critical` = persistent identity/preference or completed work that must not be redone. | | `tags` | `string` | | Space-separated tags for categorisation (e.g. `"auth backend migration"`) | | `source_context` | `string` | | What was being worked on (e.g. `"Adding authentication module"`) | **Returns** ``` details: { slug: string, title: string, relevance: string, tags: string | null } ``` The slug is auto-generated as `obs-YYYY-MM-DD-{title-slug}`. --- ## wiki_lint Deterministic health check of the wiki. Scans for orphan pages (no inbound links), missing pages (linked but not created), and contradiction markers. Optionally auto-creates stub pages for knowledge gaps cited in two or more pages. **Parameters** | Name | Type | Required | Description | |------|------|----------|-------------| | `auto_fix` | `boolean` | | When `true`, auto-creates stub concept pages for gaps mentioned in ≥2 pages (default: `false`) | **Returns** ``` details: { pages: number, orphans: number, missingPages: number, contradictions: number, reportPath: string, // path to the generated lint report .md file gaps: number // knowledge gaps tracked in .discoveries/gaps.json } ``` The lint report is written to `.llm-wiki/outputs/lint-YYYY-MM-DD.md`. Contradictions are flagged by the presence of `⚠️ **Contradiction` markers in page content and always require human review. --- ## wiki_status Report wiki health and statistics from the generated registry. Reads pre-built metadata does not scan files directly. **Parameters** None. **Returns** ``` details: { topic: string, mode: string, // "personal" or "company" totalPages: number, byType: Record<string, number>, // e.g. { concept: 4, entity: 2, source: 7 } orphans: number, gaps: number, health: "✅ Good" | "⚠️ Warning" | "🔴 Empty" } ``` Health is `"⚠️ Warning"` when orphan count exceeds 5, `"🔴 Empty"` when the registry has no pages. --- ## wiki_rebuild_meta Force a full synchronous rebuild of all generated metadata: `registry.json`, `backlinks.json`, `index.md`, `log.md`. Use when metadata appears out of sync with actual wiki files. **Parameters** None. **Returns** ``` details: { pageCount: number } ``` --- ## wiki_log_event Append a structured event to `meta/events.jsonl` and regenerate `meta/log.md`. Every event is timestamped automatically. **Parameters** | Name | Type | Required | Description | |------|------|----------|-------------| | `kind` | `string` | | Event kind label (e.g. `"ingest"`, `"query"`, `"decision"`, `"integrate"`) | | `details` | `object` | | Arbitrary additional fields to store alongside the event | **Returns** ``` details: { kind: string } ``` --- ## wiki_watch Print a ready-to-paste **POSIX crontab line** that runs the full wiki cycle (discover ingest lint) on a schedule by invoking `pi -p "/wiki-run"` headlessly under `/bin/bash -lc` so the user's shell profile (and the `pi` binary on npm-global / bun / nvm PATH) is imported. **Does not schedule anything directly** it returns the command for the user to install with `crontab -e`. Calling agents should surface the output verbatim and avoid claiming the schedule is active. **Parameters** | Name | Type | Required | Description | |------|------|----------|-------------| | `interval` | `string` | | `"daily"` (8:00 AM), `"weekly"` (Monday 9:00 AM), `"hourly"`, or `"stop"` (prints crontab removal instructions) | **Returns** ``` details: { interval: string, cronSchedule: string, // 5-field POSIX expression, e.g. "0 8 * * *" label: string, // e.g. "Daily at 8:00 AM" cronLine: string, // full crontab line, tagged "# llm-wiki-autoupdate" installed: false // tool never installs always false } ``` Output is appended to `~/.llm-wiki/cron.log` (the directory is created by the cron line itself via `mkdir -p`). On systems without `/bin/bash`, replace the wrapper with `/bin/sh -c` and ensure `pi` is in cron's PATH yourself. When `interval` is `"stop"`, returns `details: { action: "stop_instructions" }` with instructions for removing the line via `crontab -e` (look for the `# llm-wiki-autoupdate` tag). --- ## wiki_capture_trajectory Capture the just-completed task's tool-call trajectory into an immutable packet (`raw/trajectories/TRJ-*`) with a self-contained summary (`extracted.md`). The working-memory counterpart to `wiki_capture_source`. By default the trajectory is auto-extracted from the live session; pass `steps` to override. **Opt-in** (issue #80): only available when `llm-wiki.trajectories` is enabled (`/wiki-trajectories on`). **Parameters** | Name | Type | Required | Description | |------|------|----------|-------------| | `title` | `string` | | Short descriptive title for the task (≤60 chars). Inferred from the prompt if omitted. | | `task` | `string` | | The task/prompt that started the work. Inferred from the session if omitted. | | `outcome` | `string` | | `"success"` (default), `"failure"`, or `"partial"` recorded in the packet manifest | | `steps` | `array` | | Explicit trajectory steps (tool-call history). Omit to auto-extract from the live session. | | `model` | `string` | | Model that ran the task. Inferred from the session if omitted. | **Returns** ``` details: { trajectoryId: string, // e.g. "TRJ-2026-06-07-001" packetPath: string, // path to raw/trajectories/TRJ-*/ (packet.json + extracted.md) stepCount: number } ``` Errors with `isError: true` if no vault exists, or with `error: "empty_trajectory"` when no trajectory can be extracted and no `steps` are provided. --- ## wiki_distill_skills Return a batch of captured trajectories that have not yet been distilled into `skill` pages. Does not write anything itself the model reads each packet and synthesizes reusable skill pages (via `wiki_ensure_page(type="skill")`) that cite the trajectory IDs. A trajectory counts as "distilled" once a `skills/` page links to it. **Parameters** | Name | Type | Required | Description | |------|------|----------|-------------| | `trajectory_id` | `string` | | Distill a specific trajectory only; omit for all undistilled | | `batch_size` | `number` | | Max trajectories to return (default: `3`, max: `5`) | **Returns** ``` details: { batch: string[], // trajectory IDs in this batch, e.g. ["TRJ-2026-06-07-001"] remaining: number // undistilled trajectories still waiting after this batch } ``` Each batch entry includes the title, step/tool-call counts, and paths to read (`raw/trajectories/{id}/packet.json` and `extracted.md`). Returns an "all trajectories distilled" message with `{ distilled, total }` when nothing is pending. --- ## wiki_recall_skill Search distilled `skill` pages and past `case` pages for patterns relevant to the current task answers "have I done something like this before?". Filters layered recall (`searchWikiLayered`) to skill/case pages. Call at the START of a task. **Parameters** | Name | Type | Required | Description | |------|------|----------|-------------| | `query` | `string` | | Search query use the task description or key terms | | `kind` | `string` | | `"skill"`, `"case"`, or `"any"` (default) | | `max_results` | `number` | | Maximum pages to return (default: `5`, max: `10`) | **Returns** ``` details: { query: string, kind: string, matches: Array<{ id: string, // folder-qualified page ID, e.g. "skills/jwt-revocation" title: string, type: string, // "skill" | "case" preview: string, path: string, score: number, vaultLabel?: string // "📓 personal" when result is from the personal vault }> } ``` Returns empty `matches: []` with a hint to capture work via `wiki_capture_trajectory` / `wiki_distill_skills` when nothing matches. --- ## Error Shape All tools return `isError: true` in their result when a hard error occurs (no vault found, missing required input). The `text` content will contain a human-readable explanation. Check for `isError` before using `details`. ```ts { content: [{ type: "text", text: string }], details: { error: string }, isError: true } ``` The most common error is **"No wiki found run wiki_bootstrap first"**, returned by every tool except `wiki_bootstrap` itself when `.llm-wiki/config.json` does not exist in the resolved vault root.