@zosmaai/pi-llm-wiki 0.6.6 β†’ 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -20,6 +20,8 @@ Turn raw sources (URLs, PDFs, markdown, JSON, XML) into a durable, interlinked,
20
20
  pi install npm:@zosmaai/pi-llm-wiki
21
21
  ```
22
22
 
23
+ The extension will proactively suggest creating a wiki on your first session. Alternatively:
24
+
23
25
  ```
24
26
  /wiki-init "AI Engineering"
25
27
  /wiki-ingest
@@ -54,6 +56,7 @@ The result is a wiki that **compounds** as you capture sources, ask questions, a
54
56
  | πŸ“Š **Dashboard** | `wiki_status` β€” counts, source states, recent activity |
55
57
  | πŸ€– **Auto-update watch** | `wiki_watch` β€” schedule periodic discovery + ingest |
56
58
  | 🧠 **Auto-recall** | Wiki searched automatically before every turn β€” relevant pages injected into context |
59
+ | πŸ“ **Auto-bootstrap** | Extension suggests creating a wiki when none exists in the current directory |
57
60
  | πŸ’Ύ **Auto-capture** | `wiki_retro` β€” save atomic insights from completed tasks with one call |
58
61
  | 🌐 **MCP Server** | Use with Claude Code, Cursor, Windsurf via stdio MCP transport |
59
62
  | πŸ“ **Obsidian-friendly** | Folder-qualified wikilinks, stable source-ID citations, compatible vault |
@@ -1,5 +1,5 @@
1
- import { existsSync } from "node:fs";
2
- import { join } from "node:path";
1
+ import { existsSync, readFileSync, writeFileSync } from "node:fs";
2
+ import { basename, join } from "node:path";
3
3
  import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
4
4
  import { installGuardrails } from "./lib/guardrails.js";
5
5
  import { formatRecallContext, registerWikiRecall, searchWiki } from "./lib/recall.js";
@@ -16,7 +16,13 @@ import {
16
16
  registerWikiStatus,
17
17
  registerWikiWatch,
18
18
  } from "./lib/tools.js";
19
- import { resolveVaultPaths } from "./lib/utils.js";
19
+ import {
20
+ ensureVaultStructure,
21
+ fmtDate,
22
+ getVaultPaths,
23
+ resolveVaultPaths,
24
+ writeJson,
25
+ } from "./lib/utils.js";
20
26
 
21
27
  /**
22
28
  * @zosmaai/pi-llm-wiki β€” LLM Wiki extension for Pi
@@ -34,9 +40,6 @@ import { resolveVaultPaths } from "./lib/utils.js";
34
40
  * - wiki_recall tool available for explicit deep searches
35
41
  */
36
42
 
37
- // Track whether we already suggested bootstrapping this session
38
- let bootstrapSuggested = false;
39
-
40
43
  export default function (pi: ExtensionAPI) {
41
44
  registerWikiBootstrap(pi);
42
45
  registerWikiCaptureSource(pi);
@@ -53,43 +56,107 @@ export default function (pi: ExtensionAPI) {
53
56
 
54
57
  installGuardrails(pi);
55
58
 
59
+ // Track if wiki was just auto-created and needs topic inference
60
+ let needsTopicInference = false;
61
+
56
62
  pi.on("session_start", async (_event, ctx) => {
57
- bootstrapSuggested = false;
58
63
  const paths = resolveVaultPaths(process.cwd());
59
64
  if (!existsSync(join(paths.dotWiki, "config.json"))) {
60
- ctx.ui.setStatus("llm-wiki", "πŸ“ No wiki β€” call wiki_bootstrap to enable");
65
+ // Silently create the wiki vault β€” no UI prompts
66
+ // Topic/mode will be inferred from user's first prompt via before_agent_start
67
+ const root = paths.root;
68
+ const vaultPaths = getVaultPaths(root);
69
+ ensureVaultStructure(vaultPaths);
70
+
71
+ writeJson(join(vaultPaths.dotWiki, "config.json"), {
72
+ name: "pending",
73
+ mode: "personal",
74
+ topic: "pending",
75
+ created: fmtDate(),
76
+ version: "1.0",
77
+ });
78
+
79
+ const schema = [
80
+ "# LLM Wiki Schema",
81
+ "",
82
+ "## Ownership Rules",
83
+ "",
84
+ "| Path | Owner | Rule |",
85
+ "|------|-------|------|",
86
+ "| raw/** | extension | immutable after capture |",
87
+ "| wiki/** | model + user | editable knowledge pages |",
88
+ "| meta/* | extension | auto-generated |",
89
+ "| . | human + explicit request | operating rules |",
90
+ ].join("\n");
91
+ writeFileSync(join(vaultPaths.dotWiki, "WIKI_SCHEMA.md"), schema, "utf-8");
92
+
93
+ needsTopicInference = true;
94
+ ctx.ui.setStatus("llm-wiki", "🧠 Wiki created (inferring topic from first prompt…)");
61
95
  return;
62
96
  }
97
+
63
98
  ctx.ui.setStatus("llm-wiki", "🧠 LLM Wiki (12 tools, auto-recall active)");
64
99
  });
65
100
 
66
- // ─── Auto-recall hook ──────────────────────────────
67
- // Before each agent turn, search the wiki for pages relevant
68
- // to the user's prompt and inject them as system context.
101
+ // ─── Auto-recall + topic inference hook ─────────────
102
+ // Before each agent turn:
103
+ // 1. If wiki was just auto-created, inject a directive to infer topic/mode
104
+ // from the user's first prompt and update config via wiki_bootstrap.
105
+ // 2. Search wiki for relevant pages and inject as system context.
69
106
  pi.on("before_agent_start", async (event, _ctx) => {
70
107
  const paths = resolveVaultPaths(process.cwd());
71
108
  if (!existsSync(join(paths.dotWiki, "config.json"))) {
72
- // No wiki β€” suggest bootstrap on first turn only
73
- if (!bootstrapSuggested) {
74
- bootstrapSuggested = true;
75
- return {
76
- systemPrompt: `${event.systemPrompt}\n\nπŸ“ No LLM Wiki found in this directory. On your first response, use ask_user to offer the user creating one via wiki_bootstrap. After suggesting once, do not repeat.`,
77
- };
78
- }
79
109
  return;
80
110
  }
81
111
 
82
112
  const prompt = event.prompt || "";
83
- if (!prompt.trim()) return;
113
+ let injectedContext = event.systemPrompt || "";
114
+
115
+ // Topic inference on first turn after auto-creation
116
+ if (needsTopicInference && prompt.trim()) {
117
+ needsTopicInference = false;
84
118
 
85
- const results = searchWiki(paths, prompt);
86
- if (results.length === 0) return;
119
+ // Gather project context clues for topic inference
120
+ const cwd = process.cwd();
121
+ const dirName = basename(cwd);
122
+ let projectHints = `Project directory: "${dirName}" (path: ${cwd})`;
87
123
 
88
- const context = formatRecallContext(results);
89
- if (!context) return;
124
+ try {
125
+ const pkgPath = join(cwd, "package.json");
126
+ if (existsSync(pkgPath)) {
127
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
128
+ projectHints += `\nPackage: ${pkg.name || "unknown"} v${pkg.version || "?"}`;
129
+ if (pkg.description) projectHints += `\nDescription: ${pkg.description}`;
130
+ }
131
+ } catch {
132
+ // ignore
133
+ }
134
+
135
+ injectedContext += `
136
+
137
+ ## Wiki Setup Required
138
+ The LLM Wiki was just auto-created but needs its topic and mode configured. Before responding to the user, analyze their prompt and this project's context to infer:
139
+ - **topic**: What is this wiki about? (e.g. "React app", "personal notes", "startup finances")
140
+ - **mode**: "personal" or "company" based on whether this looks like work or personal use
141
+
142
+ Project context hints:
143
+ ${projectHints}
144
+
145
+ Then call wiki_bootstrap with the inferred topic and mode to finalize the setup. This is a one-time step.`;
146
+ }
147
+
148
+ // Auto-recall: search wiki for relevant pages
149
+ if (prompt.trim()) {
150
+ const results = searchWiki(paths, prompt);
151
+ if (results.length > 0) {
152
+ const recallContext = formatRecallContext(results);
153
+ if (recallContext) {
154
+ injectedContext += `\n\n${recallContext}`;
155
+ }
156
+ }
157
+ }
90
158
 
91
- return {
92
- systemPrompt: `${event.systemPrompt}\n\n${context}`,
93
- };
159
+ if (injectedContext === event.systemPrompt) return;
160
+ return { systemPrompt: injectedContext };
94
161
  });
95
162
  }
@@ -147,8 +147,8 @@ export function registerWikiRecall(pi: ExtensionAPI): void {
147
147
  Type.Number({ description: "Max results (default: 5, max: 10)", default: 5 }),
148
148
  ),
149
149
  }),
150
- async execute(_toolCallId, params) {
151
- const paths = resolveVaultPaths(process.cwd());
150
+ async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
151
+ const paths = resolveVaultPaths(ctx.cwd ?? process.cwd());
152
152
 
153
153
  if (!existsSync(join(paths.dotWiki, "config.json"))) {
154
154
  return {
@@ -151,8 +151,8 @@ export function registerWikiRetro(pi: ExtensionAPI): void {
151
151
  }),
152
152
  ),
153
153
  }),
154
- async execute(_toolCallId, params) {
155
- const paths = resolveVaultPaths(process.cwd());
154
+ async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
155
+ const paths = resolveVaultPaths(ctx.cwd ?? process.cwd());
156
156
 
157
157
  if (!existsSync(join(paths.dotWiki, "config.json"))) {
158
158
  return {
@@ -28,8 +28,8 @@ import {
28
28
  * All LLM Wiki custom tools.
29
29
  */
30
30
 
31
- function getPaths(cwd = process.cwd()): VaultPaths {
32
- return resolveVaultPaths(cwd);
31
+ function getPaths(cwd?: string): VaultPaths {
32
+ return resolveVaultPaths(cwd ?? process.cwd());
33
33
  }
34
34
 
35
35
  function requireVault(paths: VaultPaths): { ok: true } | { ok: false; reason: string } {
@@ -58,7 +58,7 @@ export function registerWikiBootstrap(pi: ExtensionAPI): void {
58
58
  ),
59
59
  }),
60
60
  async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
61
- const root = params.root ? params.root : (ctx.cwd ?? process.cwd());
61
+ const root = params.root ?? ctx.cwd ?? process.cwd();
62
62
  const mode = params.mode || "personal";
63
63
  const paths = getVaultPaths(root);
64
64
 
@@ -121,6 +121,7 @@ export function registerWikiBootstrap(pi: ExtensionAPI): void {
121
121
  type: "text",
122
122
  text: [
123
123
  `βœ… Wiki bootstrapped at \`${paths.root}\``,
124
+ "**Scope:** project-local",
124
125
  "",
125
126
  "**Structure:**",
126
127
  "- .llm-wiki/raw/sources/ β€” immutable source packets",
@@ -158,8 +159,8 @@ export function registerWikiCaptureSource(pi: ExtensionAPI): void {
158
159
  text: Type.Optional(Type.String({ description: "Pasted text content" })),
159
160
  title: Type.Optional(Type.String({ description: "Title for pasted text" })),
160
161
  }),
161
- async execute(_toolCallId, params, signal) {
162
- const paths = getPaths();
162
+ async execute(_toolCallId, params, signal, _onUpdate, ctx) {
163
+ const paths = getPaths(ctx.cwd);
163
164
  const vaultCheck = requireVault(paths);
164
165
  if (!vaultCheck.ok) {
165
166
  return {
@@ -239,8 +240,8 @@ export function registerWikiIngest(pi: ExtensionAPI): void {
239
240
  Type.Number({ description: "Max sources to return (default: 3, max: 5)", default: 3 }),
240
241
  ),
241
242
  }),
242
- async execute(_toolCallId, params) {
243
- const paths = getPaths();
243
+ async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
244
+ const paths = getPaths(ctx.cwd);
244
245
  const vaultCheck = requireVault(paths);
245
246
  if (!vaultCheck.ok) {
246
247
  return {
@@ -377,8 +378,8 @@ export function registerWikiEnsurePage(pi: ExtensionAPI): void {
377
378
  Type.String({ description: "Optional initial content (otherwise uses template)" }),
378
379
  ),
379
380
  }),
380
- async execute(_toolCallId, params) {
381
- const paths = getPaths();
381
+ async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
382
+ const paths = getPaths(ctx.cwd);
382
383
  const vaultCheck = requireVault(paths);
383
384
  if (!vaultCheck.ok) {
384
385
  return {
@@ -523,8 +524,8 @@ export function registerWikiSearch(pi: ExtensionAPI): void {
523
524
  query: Type.String({ description: "Search term" }),
524
525
  type: Type.Optional(Type.String({ description: "Filter by page type" })),
525
526
  }),
526
- async execute(_toolCallId, params) {
527
- const paths = getPaths();
527
+ async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
528
+ const paths = getPaths(ctx.cwd);
528
529
  const registry = readJson<Registry>(join(paths.meta, "registry.json"), {
529
530
  version: "1.0",
530
531
  last_updated: "",
@@ -586,8 +587,8 @@ export function registerWikiLint(pi: ExtensionAPI): void {
586
587
  Type.Boolean({ description: "Auto-fix orphans and missing pages", default: false }),
587
588
  ),
588
589
  }),
589
- async execute(_toolCallId, params) {
590
- const paths = getPaths();
590
+ async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
591
+ const paths = getPaths(ctx.cwd);
591
592
  const vaultCheck = requireVault(paths);
592
593
  if (!vaultCheck.ok) {
593
594
  return {
@@ -741,8 +742,8 @@ export function registerWikiStatus(pi: ExtensionAPI): void {
741
742
  promptSnippet: "Report wiki health and stats",
742
743
  promptGuidelines: ["Use wiki_status for a quick overview."],
743
744
  parameters: Type.Object({}),
744
- async execute() {
745
- const paths = getPaths();
745
+ async execute(_toolCallId, _params, _signal, _onUpdate, ctx) {
746
+ const paths = getPaths(ctx.cwd);
746
747
  const vaultCheck = requireVault(paths);
747
748
  if (!vaultCheck.ok) {
748
749
  return {
@@ -818,8 +819,8 @@ export function registerWikiRebuildMeta(pi: ExtensionAPI): void {
818
819
  promptSnippet: "Rebuild all wiki metadata",
819
820
  promptGuidelines: ["Use wiki_rebuild_meta if metadata seems out of sync."],
820
821
  parameters: Type.Object({}),
821
- async execute() {
822
- const paths = getPaths();
822
+ async execute(_toolCallId, _params, _signal, _onUpdate, ctx) {
823
+ const paths = getPaths(ctx.cwd);
823
824
  const vaultCheck = requireVault(paths);
824
825
  if (!vaultCheck.ok) {
825
826
  return {
@@ -864,8 +865,8 @@ export function registerWikiLogEvent(pi: ExtensionAPI): void {
864
865
  kind: Type.String({ description: "Event kind (e.g., ingest, query, decision)" }),
865
866
  details: Type.Optional(Type.Object({}, { description: "Additional event fields" })),
866
867
  }),
867
- async execute(_toolCallId, params) {
868
- const paths = getPaths();
868
+ async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
869
+ const paths = getPaths(ctx.cwd);
869
870
  const vaultCheck = requireVault(paths);
870
871
  if (!vaultCheck.ok) {
871
872
  return {
@@ -904,7 +905,7 @@ export function registerWikiWatch(pi: ExtensionAPI): void {
904
905
  parameters: Type.Object({
905
906
  interval: Type.String({ description: "daily, weekly, hourly, or stop" }),
906
907
  }),
907
- async execute(_toolCallId, params) {
908
+ async execute(_toolCallId, params, _signal, _onUpdate, _ctx) {
908
909
  if (params.interval === "stop") {
909
910
  return {
910
911
  content: [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zosmaai/pi-llm-wiki",
3
- "version": "0.6.6",
3
+ "version": "0.7.0",
4
4
  "description": "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.",
5
5
  "keywords": [
6
6
  "pi",
@@ -15,13 +15,14 @@ $ARGUMENTS
15
15
 
16
16
  ## Steps
17
17
 
18
- 1. Read `wiki/LOG.md` β€” filter entries since last digest
19
- 2. Read pages created/updated in that period
18
+ 1. Call `wiki_status()` to get current stats (page count, orphans, gaps, health).
19
+ 2. Read `.llm-wiki/meta/log.md` for recent events since the last digest period.
20
20
  3. Summarize:
21
- - New sources ingested
22
- - New pages created
23
- - Key insights or connections
21
+ - New sources captured
22
+ - New pages created or updated
23
+ - Key insights or connections made
24
24
  - Knowledge gaps identified
25
- - Health trends
26
- 4. Save β†’ `outputs/digest-YYYY-MM-DD.md`
27
- 5. Report concise digest
25
+ - Health trends (improving, stable, declining)
26
+ 4. Save the digest to `.llm-wiki/outputs/digest-YYYY-MM-DD.md` using the `write` tool.
27
+ 5. Call `wiki_log_event(kind=digest)` to record this digest was generated.
28
+ 6. Report a concise digest to the user.
@@ -7,27 +7,24 @@ topLevelCli: true
7
7
 
8
8
  # /wiki-discover
9
9
 
10
- Find new source material for the wiki by searching the web.
10
+ Find new source material for the wiki by searching the web and capturing them as source packets.
11
11
 
12
12
  ## User Arguments
13
13
 
14
14
  $ARGUMENTS
15
15
 
16
- Read the LLM Wiki skill at `.pi/skills/llm-wiki/SKILL.md` first. Also read `config.yaml` for topics and feeds.
17
-
18
16
  ## Steps
19
17
 
20
- 1. Read `.llm-wiki/config.yaml` β†’ extract topics, keywords, feeds
21
- 2. Read `.llm-wiki/.discoveries/gaps.json` β†’ knowledge gaps to fill
22
- 3. Read `.llm-wiki/.discoveries/history.json` β†’ already-fetched URLs
23
- 4. Search for new sources:
24
- - Web search each topic + latest keywords
25
- - Search for gaps from `.llm-wiki/.discoveries/gaps.json`
26
- - If `--topic` specified, focus search on that topic
27
- 5. For each promising result:
28
- a. Fetch full content
29
- b. Save to `.llm-wiki/raw/articles/YYYY-MM-DD-slug.md` with frontmatter (title, url, discovered, topic)
30
- 6. Update `.llm-wiki/.discoveries/history.json`
31
- 7. Report: "Discovered [N] new sources. Run `/wiki-ingest` to process them."
32
-
33
- **Rules:** Max 5-10 sources. Skip ads, listicles, duplicates. Prefer in-depth analysis.
18
+ 1. Call `wiki_status()` to get the current topic and mode from the wiki config.
19
+ 2. Use `wiki_search(query=<topic>)` to find existing pages and identify what's already covered.
20
+ 3. Search the web for new sources:
21
+ - If `--topic` is specified in `$ARGUMENTS`, focus on that topic
22
+ - Otherwise, search for the wiki's main topic + "latest", "news", "update"
23
+ 4. For each promising result (max 5-10):
24
+ a. Call `wiki_capture_source(url=<url>)` to capture it as an immutable source packet
25
+ b. Skip ads, listicles, and duplicates β€” prefer in-depth analysis
26
+ 5. Report: "Discovered [N] new sources captured as packets. Run `/wiki-ingest` to synthesize them into knowledge pages."
27
+
28
+ **Rules:**
29
+ - Do NOT manually save files to `raw/` β€” always use `wiki_capture_source`.
30
+ - The extension handles manifest, extraction, and skeleton page creation automatically.
@@ -1,34 +1,33 @@
1
1
  ---
2
- description: Process new source files in raw/ and update the wiki. Creates summaries, entities, concepts, and cross-references.
3
- argument-hint: "[path]"
2
+ description: Process new source packets and synthesize them into wiki knowledge pages.
3
+ argument-hint: "[source_id]"
4
4
  section: LLM Wiki
5
5
  topLevelCli: true
6
6
  ---
7
7
 
8
8
  # /wiki-ingest
9
9
 
10
- Process new files in `.llm-wiki/raw/` and integrate them into the wiki.
10
+ Process uningested source packets and synthesize them into wiki knowledge pages.
11
11
 
12
12
  ## User Arguments
13
13
 
14
14
  $ARGUMENTS
15
15
 
16
- Read the LLM Wiki skill at `.pi/skills/llm-wiki/SKILL.md` first to understand the full schema, page formats, and conventions.
17
-
18
16
  ## Steps
19
17
 
20
- 1. Read `.llm-wiki/config.yaml` and `.llm-wiki/.discoveries/history.json`
21
- 2. If a specific path is given (e.g., `/wiki-ingest .llm-wiki/raw/articles/my-file.md`), process just that file
22
- 3. If no path given, scan all files in `.llm-wiki/raw/` (respecting `.gitignore` β€” skip any matched files) and find ones not in history
23
- 4. For each new source:
24
- a. Read the full content
25
- b. Briefly discuss with the user: "This is about [topic]. Key points: [summary]. Any specific emphasis?"
26
- c. Create/update pages in `.llm-wiki/wiki/sources/`, `.llm-wiki/wiki/entities/`, `.llm-wiki/wiki/concepts/`
27
- d. Add `[[wikilinks]]` cross-references between related pages
28
- e. Flag any contradictions with existing wiki content
29
- 5. Update `.llm-wiki/wiki/INDEX.md` with all new/updated pages
30
- 6. Append to `.llm-wiki/wiki/LOG.md`
31
- 7. Update `.llm-wiki/.discoveries/history.json`
32
- 8. Report: "Ingested [N] sources β†’ [M] pages created/updated. [X] contradictions flagged."
33
-
34
- **Rules:** Never modify raw/ files. Never fabricate information. Always cite sources.
18
+ 1. Call `wiki_ingest(source_id=<id if provided>, batch_size=3)` to get sources needing synthesis.
19
+ 2. If the tool reports "All sources ingested", inform the user and stop.
20
+ 3. For each source in the returned batch:
21
+ a. Read the extracted text from `raw/sources/<SOURCE_ID>/extracted.md`
22
+ b. Update the skeleton source page in `wiki/sources/` with a proper summary, key entities, and concepts
23
+ c. Use `wiki_ensure_page(type=entity, title=<name>)` for each new entity (people, orgs, tools, products)
24
+ d. Use `wiki_ensure_page(type=concept, title=<name>)` for each new concept (ideas, patterns, frameworks)
25
+ e. Add `[[wikilinks]]` cross-references between related pages
26
+ f. Flag any contradictions with existing wiki content using `⚠️ **Contradiction**` markers
27
+ 4. After processing the batch, call `wiki_rebuild_meta` to update metadata.
28
+ 5. Report: "Ingested [N] sources β†’ [M] pages created/updated. [X] contradictions flagged."
29
+
30
+ **Rules:**
31
+ - Never modify files in `raw/` β€” source packets are immutable after capture.
32
+ - Never fabricate information β€” always cite sources with `[[sources/SRC-...]]`.
33
+ - The extension auto-updates metadata β€” you do NOT need to manually edit `meta/` files.
@@ -7,28 +7,24 @@ topLevelCli: true
7
7
 
8
8
  # /wiki-init
9
9
 
10
- Initialize a new LLM Wiki in the current directory.
10
+ Initialize a new LLM Wiki vault using the `wiki_bootstrap` tool.
11
11
 
12
12
  ## User Arguments
13
13
 
14
14
  $ARGUMENTS
15
15
 
16
- Read the LLM Wiki skill at `.pi/skills/llm-wiki/SKILL.md` (or wherever the skill is installed) first to understand the full schema and conventions.
17
-
18
16
  ## Steps
19
17
 
20
- 1. Ask the user for the wiki topic and mode (`personal` or `company`)
21
- 2. Create the directory structure:
22
- - `.llm-wiki/raw/articles/`, `.llm-wiki/raw/papers/`, `.llm-wiki/raw/notes/`, `.llm-wiki/raw/assets/`
23
- - `.llm-wiki/wiki/entities/`, `.llm-wiki/wiki/concepts/`, `.llm-wiki/wiki/sources/`, `.llm-wiki/wiki/syntheses/`, `.llm-wiki/wiki/changes/`
24
- - `.llm-wiki/outputs/`
25
- - `.llm-wiki/.discoveries/`
26
- 3. Create `.llm-wiki/config.yaml` with the topic, mode, and default settings
27
- 4. Create `.llm-wiki/wiki/INDEX.md` with section headings organized by page type
28
- 5. Create `.llm-wiki/wiki/LOG.md` with initial entry
29
- 6. Create `.llm-wiki/wiki/DASHBOARD.md` with Dataview queries for Obsidian
30
- 7. Create `.gitignore` to exclude `.llm-wiki/outputs/` from version control if desired
31
- 8. Initialize git repo if not already present
32
- 9. Report the structure and suggest first steps: "Drop sources into `.llm-wiki/raw/` and run `/wiki-ingest`"
33
-
34
- If `--mode company`, add the `change_detection: true` flag to config.yaml and add a `.llm-wiki/wiki/decisions/` folder.
18
+ 1. If the user provided a topic in `$ARGUMENTS`, use it. Otherwise, ask the user for the wiki **topic**.
19
+ 2. Determine mode: default to `personal`; use `company` if the user specifies `--mode company` or requests it.
20
+ 3. Call `wiki_bootstrap(topic=<topic>, mode=<mode>)` to create the vault.
21
+ 4. Report the result and suggest next steps:
22
+ - "Use `wiki_capture_source` to add your first source (URL, file, or text)."
23
+ - "Run `/wiki-ingest` after capturing sources to synthesize them into knowledge pages."
24
+
25
+ **Do NOT manually create directories or files.** The `wiki_bootstrap` tool handles all scaffolding including:
26
+ - `.llm-wiki/raw/sources/` β€” immutable source packets
27
+ - `.llm-wiki/wiki/` β€” editable knowledge pages
28
+ - `.llm-wiki/meta/` β€” auto-generated metadata
29
+ - `.llm-wiki/config.json` β€” vault configuration
30
+ - `.llm-wiki/WIKI_SCHEMA.md` β€” operating rules
@@ -13,21 +13,13 @@ Run a comprehensive health check on the wiki.
13
13
 
14
14
  $ARGUMENTS
15
15
 
16
- Read the LLM Wiki skill at `.pi/skills/llm-wiki/SKILL.md` first to understand the full schema and conventions.
17
-
18
16
  ## Steps
19
17
 
20
- 1. Scan all files in `.llm-wiki/wiki/` (respecting `.gitignore` β€” skip any matched files)
21
- 2. Check for:
22
- - **Contradictions:** Conflicting claims between pages
23
- - **Orphans:** Pages with zero inbound `[[wikilinks]]`
24
- - **Missing pages:** `[[links]]` pointing to non-existent files
25
- - **Stale claims:** Info superseded by newer sources
26
- - **Broken raw links:** References to `.llm-wiki/raw/` files that don't exist
27
- - **Knowledge gaps:** Topics mentioned but lacking their own page
28
- - **Quality:** Pages under 3 lines, pages with no sources or cross-refs
29
- 3. If `--fix` flag is present: auto-fix broken links, create missing pages for frequently-linked concepts, add cross-refs to orphans. Flag contradictions for human decision.
30
- 4. Save report β†’ `.llm-wiki/outputs/lint-YYYY-MM-DD.md`
31
- 5. Update `.llm-wiki/.discoveries/gaps.json`
32
- 6. Append to `.llm-wiki/wiki/LOG.md`
33
- 7. Report key findings
18
+ 1. Determine if auto-fix is requested: set `auto_fix=true` if `$ARGUMENTS` contains `--fix`, otherwise `false`.
19
+ 2. Call `wiki_lint(auto_fix=<true/false>)` to run the health check.
20
+ 3. Present the lint report to the user, including:
21
+ - Page count, orphans, missing pages, contradictions
22
+ - Knowledge gaps found
23
+ - Any auto-fixes applied
24
+ 4. If contradictions are found, flag them for human review β€” do NOT auto-resolve contradictions.
25
+ 5. If knowledge gaps are identified, suggest creating pages for frequently-mentioned topics.
@@ -13,24 +13,25 @@ Ask a question and get an answer synthesized from wiki content.
13
13
 
14
14
  $ARGUMENTS
15
15
 
16
- Read the LLM Wiki skill at `.pi/skills/llm-wiki/SKILL.md` first to understand the full schema and conventions.
17
-
18
16
  ## Steps
19
17
 
20
- 1. Read `wiki/INDEX.md` to find pages relevant to the question
21
- 2. Read those pages in full (don't stop at 1-2 pages β€” get thorough context)
22
- 3. Synthesize an answer with `[[wikilink]]` citations to specific wiki pages
23
- 4. If the answer reveals a new connection or analysis, save it as a synthesis page in `wiki/syntheses/`
24
- 5. Append to `wiki/LOG.md`
18
+ 1. Call `wiki_recall(query=<question>)` to find relevant wiki pages.
19
+ 2. Read the full content of each matching page using the `read` tool.
20
+ 3. Synthesize an answer with `[[wikilink]]` citations to specific wiki pages.
21
+ 4. If the answer reveals a new connection or analysis worth preserving:
22
+ - Call `wiki_ensure_page(type=synthesis, title=<title>, content=<content>)` to save it
23
+ 5. Call `wiki_log_event(kind=query, details={question: <question>})` to log the query.
25
24
 
26
- **Rules:** Answer ONLY from wiki content, not from general knowledge. If the wiki lacks information, say so clearly and suggest what sources would help fill the gap.
25
+ **Rules:**
26
+ - Answer ONLY from wiki content, not from general knowledge.
27
+ - If the wiki lacks information, say so clearly and suggest what sources would help fill the gap.
27
28
 
28
29
  **Example:**
29
30
 
30
31
  ```
31
32
  /wiki-query What are the key differences between RAG and LLM Wiki?
32
- β†’ Reads INDEX.md, finds pages on RAG and LLM Wiki patterns
33
- β†’ Reads both pages
34
- β†’ Synthesizes a comparison table with [[wikilink]] citations
35
- β†’ Saves as wiki/syntheses/rag-vs-llm-wiki.md
33
+ β†’ Calls wiki_recall(query="RAG LLM Wiki differences")
34
+ β†’ Reads matching pages
35
+ β†’ Synthesizes a comparison with [[wikilink]] citations
36
+ β†’ Saves as synthesis page via wiki_ensure_page(type=synthesis, ...)
36
37
  ```
@@ -13,27 +13,17 @@ Run the complete wiki maintenance cycle: discover new sources, ingest them, and
13
13
 
14
14
  $ARGUMENTS
15
15
 
16
- Read the LLM Wiki skill at `.pi/skills/llm-wiki/SKILL.md` first.
17
-
18
16
  ## Steps
19
17
 
20
- 1. Run `/wiki-discover` β†’ find new sources
21
- 2. Run `/wiki-ingest` β†’ process all new files
22
- 3. Run `/wiki-lint` β†’ health check
23
- 4. If critical gaps found β†’ optionally one more discover+ingest cycle
24
- 5. Save summary β†’ `outputs/run-YYYY-MM-DD.md`
25
- 6. Report final summary
18
+ 1. **Discover:** Use web search to find new sources on the wiki's topic, then capture each with `wiki_capture_source(url=<url>)` (max 5-10).
19
+ 2. **Ingest:** Call `wiki_ingest(batch_size=3)` and process returned sources β€” read extracted.md, update source pages, create entity/concept pages, add cross-references.
20
+ 3. **Lint:** Call `wiki_lint(auto_fix=false)` to run a health check.
21
+ 4. If critical gaps found β†’ optionally run one more discover+ingest cycle.
22
+ 5. Save summary to `.llm-wiki/outputs/run-YYYY-MM-DD.md` using the `write` tool.
23
+ 6. Report final summary.
26
24
 
27
25
  ### Scheduling
28
26
 
29
- If `--schedule daily` is used, use `schedule_prompt` to set up daily runs:
30
-
31
- ```
32
- schedule_prompt action=add schedule="0 0 8 * * *" prompt="Run /wiki-run for the LLM Wiki"
33
- ```
34
-
35
- If `--schedule weekly` is used:
27
+ If `--schedule` is provided, call `wiki_watch(interval=<daily|weekly>)` to set up automatic updates.
36
28
 
37
- ```
38
- schedule_prompt action=add schedule="0 0 9 * * 1" prompt="Run /wiki-run for the LLM Wiki"
39
- ```
29
+ If `--schedule hourly` is provided, call `wiki_watch(interval=hourly)`.
@@ -11,23 +11,6 @@ Show a quick overview of wiki health and statistics.
11
11
 
12
12
  ## Steps
13
13
 
14
- 1. Count sources in `.llm-wiki/raw/` (recursive, respecting `.gitignore`)
15
- 2. Count pages in `.llm-wiki/wiki/` (by type: entities, concepts, sources, syntheses, respecting `.gitignore`)
16
- 3. Check `.llm-wiki/wiki/LOG.md` for last ingest, lint, and discover dates
17
- 4. Check for orphan pages (zero inbound links)
18
- 5. Read `.llm-wiki/.discoveries/gaps.json` for known gaps
19
- 6. Report:
20
-
21
- ```
22
- πŸ“Š LLM Wiki Status
23
- ══════════════════
24
- Wiki Root: [topic1], [topic2]
25
- Mode: Personal | Company
26
- Sources: [N] files
27
- Wiki Pages: [N] total ([E] entities, [C] concepts, [S] sources, [Y] syntheses)
28
- Last Ingest: YYYY-MM-DD
29
- Last Lint: YYYY-MM-DD
30
- Orphans: [N]
31
- Knowledge Gaps: [N]
32
- Health: βœ… Good | ⚠️ Warning | πŸ”΄ Needs Attention
33
- ```
14
+ 1. Call `wiki_status()` to get the current wiki health report.
15
+ 2. Present the results to the user.
16
+ 3. If health shows warnings (orphans > 5, many gaps), suggest running `/wiki-lint` for a detailed analysis.
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  name: llm-wiki
3
3
  description: Build and maintain a persistent, interlinked Obsidian-compatible markdown wiki using Karpathy's LLM Wiki pattern. Extension-backed with auto-generated metadata, guardrails, and 12 custom tools.
4
+ whenToUse: At the START of every task, the extension auto-recalls relevant wiki pages β€” no manual action needed. After completing any meaningful task, call wiki_retro to save insights for future sessions. Invoke proactively β€” do not wait for the user to ask.
4
5
  ---
5
6
 
6
7
  # LLM Wiki for Pi
@@ -58,9 +59,11 @@ WIKI_ROOT/
58
59
  | **Recall wiki knowledge** | Never happens | **Auto-search before every turn** |
59
60
  | **Save task insights** | Manual capture | `wiki_retro` β€” one tool call |
60
61
 
61
- ## πŸ”„ Auto-Recall (New)
62
+ ## πŸ”„ Proactive Wiki Usage
62
63
 
63
- **The extension now automatically searches the wiki before every user turn.**
64
+ ### At Task Start β€” Auto-Recall (Automatic)
65
+
66
+ **The extension automatically searches the wiki before every user turn.**
64
67
 
65
68
  When you send a prompt, the extension:
66
69
  1. Extracts key terms from your request
@@ -71,7 +74,20 @@ When you send a prompt, the extension:
71
74
  **This means the wiki works as an automatic second brain.**
72
75
  You don't need to remember to search β€” relevant knowledge is surfaced automatically.
73
76
 
74
- ### Manual recall for deeper searches
77
+ ### At Task End β€” Save Insights (Proactive)
78
+
79
+ After completing any meaningful task, call `wiki_retro` to save key insights:
80
+ - Non-obvious bug fixes or workarounds
81
+ - Architectural decisions and their rationale
82
+ - Tool/library gotchas you discovered
83
+ - Patterns worth remembering for future sessions
84
+
85
+ **Do not wait for the user to ask.** Save insights proactively β€” one atomic insight per call.
86
+
87
+ ```wiki_retro(slug="kebab-case-slug", title="Brief descriptive title", body="Insight in your own words with [[wikilinks]]")
88
+ ```
89
+
90
+ ### Manual Recall for Deeper Searches
75
91
 
76
92
  If the auto-recall doesn't find enough context, call `wiki_recall` explicitly:
77
93
 
@@ -81,13 +97,16 @@ wiki_recall(query="specific terms...", max_results=10)
81
97
 
82
98
  This gives you more control over the search terms and returns content previews.
83
99
 
84
- ### No Wiki Yet
100
+ ### Auto-Bootstrap (New)
85
101
 
86
- If the extension injects a "No LLM Wiki found" hint, use `ask_user` to offer creating one:
102
+ **The extension now creates the wiki vault automatically on startup β€” no user prompt needed.**
87
103
 
88
- > "No LLM Wiki found in this directory. Would you like to create one? It gives you a linked knowledge base with automatic recall."
104
+ When you start in a directory without a wiki, the extension silently creates `.llm-wiki/` with placeholder config. On your first turn, it injects a directive asking you to:
105
+ 1. Analyze the user's prompt and project context
106
+ 2. Infer a topic (e.g. "React app", "startup finances")
107
+ 3. Call `wiki_bootstrap(topic="...", mode="personal|company")` to finalize setup
89
108
 
90
- If the user agrees, call `wiki_bootstrap(topic="...", mode="personal")`. Suggest only once per session.
109
+ This is a one-time step β€” after bootstrap, normal auto-recall takes over.
91
110
 
92
111
  ## Available Tools
93
112