@zosmaai/pi-llm-wiki 0.5.0 → 0.6.1
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/CHANGELOG.md +40 -0
- package/README.md +89 -52
- package/docs/architecture.md +30 -26
- package/docs/commands.md +1 -1
- package/docs/configuration.md +1 -1
- package/docs/obsidian.md +5 -5
- package/extensions/llm-wiki/index.ts +38 -12
- package/extensions/llm-wiki/lib/guardrails.ts +8 -18
- package/extensions/llm-wiki/lib/recall.ts +207 -0
- package/extensions/llm-wiki/lib/retro.ts +196 -0
- package/extensions/llm-wiki/lib/tools.ts +11 -10
- package/extensions/llm-wiki/lib/utils.ts +48 -8
- package/mcp/index.ts +487 -0
- package/package.json +9 -2
- package/prompts/wiki-discover.md +6 -6
- package/prompts/wiki-ingest.md +8 -8
- package/prompts/wiki-init.md +11 -11
- package/prompts/wiki-lint.md +5 -5
- package/prompts/wiki-status.md +4 -4
- package/skills/llm-wiki/SKILL.md +67 -30
- package/skills/llm-wiki/templates/pages/source.md +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,46 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.7.0] - 2026-05-13
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- **Wiki vault restructured under `.llm-wiki/`** (Issue #22, PR #23 by @arjun-zosma): All wiki content now lives in a single `.llm-wiki/` subdirectory — cleaner repo isolation, easier gitignore, zero directory name collisions.
|
|
9
|
+
- **Backward compatibility**: Old vaults (`.wiki/config.json` sentinel) are auto-detected and continue to work. New vaults use `.llm-wiki/config.json`.
|
|
10
|
+
- **`detectVaultFormat()`** utility: Returns `"new"`, `"legacy"`, or `"none"` for any directory.
|
|
11
|
+
- **`resolveVaultPaths()`** utility: Auto-detects vault format and returns correct paths.
|
|
12
|
+
- **`getLegacyVaultPaths()`** utility: Returns old-style paths for migration support.
|
|
13
|
+
- **Migration script** (`scripts/migrate-llm-wiki.js`): One-time tool to move old vaults to new layout. Supports `--dry-run` and `--force` flags.
|
|
14
|
+
- **5 new backward-compatibility tests**: Verify new format detection, legacy format detection, auto-resolution, and no-vault handling.
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
- `resolveVaultRoot()` now checks for `.llm-wiki/config.json` first, then falls back to `.wiki/config.json`.
|
|
18
|
+
- `getVaultPaths()` returns paths under `.llm-wiki/`:
|
|
19
|
+
- `raw/` → `.llm-wiki/raw/`, `wiki/` → `.llm-wiki/wiki/`, `meta/` → `.llm-wiki/meta/`
|
|
20
|
+
- `.wiki/` → `.llm-wiki/` (config directly in the dot-dir)
|
|
21
|
+
- `outputs/` → `.llm-wiki/outputs/`, `.discoveries/` → `.llm-wiki/.discoveries/`
|
|
22
|
+
- `isProtectedPath()` now takes `VaultPaths` instead of `root` string.
|
|
23
|
+
- `wiki_bootstrap` creates new `.llm-wiki/` layout by default.
|
|
24
|
+
- MCP server updated with own copy of path detection logic.
|
|
25
|
+
- All templates, prompts, documentation, and tests updated to reflect new layout.
|
|
26
|
+
|
|
27
|
+
### Migration
|
|
28
|
+
- Run `node scripts/migrate-llm-wiki.js` in your wiki root to migrate from the old layout.
|
|
29
|
+
- Old `.wiki/` directory is preserved as a forwarding marker (`.wiki/MIGRATED_TO_LLM_WIKI.md`).
|
|
30
|
+
- No data loss — all content is moved, nothing deleted.
|
|
31
|
+
|
|
32
|
+
## [0.6.0] - 2026-05-11
|
|
33
|
+
|
|
34
|
+
### Added
|
|
35
|
+
- **Phase 1 — Auto-recall** (PR #19 by @arjun-zosma): New `wiki_recall` tool for explicit searches. Extension now auto-searches wiki before every user turn via `before_agent_start` hook. Matching pages injected as "Relevant Wiki Knowledge" into system prompt. 8 new tests.
|
|
36
|
+
- **Phase 2 — Auto-capture** (PR #20 by @arjun-zosma): New `wiki_retro` tool for saving atomic insights from completed tasks. Creates source packets with manifest, extracted text, and source page. 4 new tests.
|
|
37
|
+
- **Phase 3 — MCP Server** (PR #21 by @arjun-zosma): Standalone MCP server using `@modelcontextprotocol/server` (v2 SDK) with stdio transport. Exposes 5 tools: wiki_recall, wiki_search, wiki_status, wiki_retro, wiki_capture_source. Cross-platform reach to Claude Code, Cursor, Windsurf.
|
|
38
|
+
- **12 extension tools** (up from 10): wiki_recall (auto at turn start) and wiki_retro (manual at task end)
|
|
39
|
+
- **SKILL.md**: Auto-Recall section, wiki_recall + wiki_retro tool docs, "Task → Capture → Retro" workflow
|
|
40
|
+
|
|
41
|
+
### Changed
|
|
42
|
+
- Extension registers 12 tools instead of 10
|
|
43
|
+
- Status bar now shows "12 tools, auto-recall active"
|
|
44
|
+
|
|
5
45
|
## [0.5.0] - 2026-05-11
|
|
6
46
|
|
|
7
47
|
### Added
|
package/README.md
CHANGED
|
@@ -53,6 +53,9 @@ The result is a wiki that **compounds** as you capture sources, ask questions, a
|
|
|
53
53
|
| 🩺 **Mechanical linting** | Orphans, broken links, duplicate aliases, coverage gaps, stale captures |
|
|
54
54
|
| 📊 **Dashboard** | `wiki_status` — counts, source states, recent activity |
|
|
55
55
|
| 🤖 **Auto-update watch** | `wiki_watch` — schedule periodic discovery + ingest |
|
|
56
|
+
| 🧠 **Auto-recall** | Wiki searched automatically before every turn — relevant pages injected into context |
|
|
57
|
+
| 💾 **Auto-capture** | `wiki_retro` — save atomic insights from completed tasks with one call |
|
|
58
|
+
| 🌐 **MCP Server** | Use with Claude Code, Cursor, Windsurf via stdio MCP transport |
|
|
56
59
|
| 📝 **Obsidian-friendly** | Folder-qualified wikilinks, stable source-ID citations, compatible vault |
|
|
57
60
|
| 🛡️ **Guardrails** | Blocks direct edits to raw sources and generated metadata |
|
|
58
61
|
| 🔧 **Configurable PDF extraction** | MarkItDown timeout via `WIKI_MARKITDOWN_TIMEOUT_MS` env var |
|
|
@@ -66,6 +69,8 @@ The result is a wiki that **compounds** as you capture sources, ask questions, a
|
|
|
66
69
|
|------|-------------|
|
|
67
70
|
| `wiki_bootstrap` | Initialize a new wiki vault with config, templates, schema, and metadata |
|
|
68
71
|
| `wiki_capture_source` | Capture a URL, local file, or pasted text into an immutable source packet |
|
|
72
|
+
| `wiki_recall` | 🔄 **Auto-called at turn start** — search wiki for task-relevant pages |
|
|
73
|
+
| `wiki_retro` | Save atomic insights from completed tasks into the wiki |
|
|
69
74
|
| `wiki_ingest` | Process uningested source packets into wiki pages (batch) |
|
|
70
75
|
| `wiki_ensure_page` | Resolve or safely create entity / concept / synthesis / analysis pages |
|
|
71
76
|
| `wiki_search` | Search the generated wiki registry |
|
|
@@ -104,11 +109,13 @@ Initialize an llm wiki here for AI research.
|
|
|
104
109
|
This calls `wiki_bootstrap` and creates:
|
|
105
110
|
|
|
106
111
|
```
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
+
.llm-wiki/
|
|
113
|
+
├── config.json
|
|
114
|
+
├── templates/
|
|
115
|
+
├── raw/
|
|
116
|
+
├── wiki/
|
|
117
|
+
├── meta/
|
|
118
|
+
└── WIKI_SCHEMA.md
|
|
112
119
|
```
|
|
113
120
|
|
|
114
121
|
### 2) Capture a source
|
|
@@ -128,7 +135,7 @@ Capture these notes into the wiki: ...pasted text...
|
|
|
128
135
|
### 3) Integrate the source
|
|
129
136
|
|
|
130
137
|
1. Capture the source
|
|
131
|
-
2. Read
|
|
138
|
+
2. Read `.llm-wiki/wiki/sources/SRC-*.md`
|
|
132
139
|
3. Update that source page
|
|
133
140
|
4. Search for impacted canonical pages with `wiki_search`
|
|
134
141
|
5. Create missing pages with `wiki_ensure_page`
|
|
@@ -153,45 +160,47 @@ Answer the question and file the result as an analysis page.
|
|
|
153
160
|
|
|
154
161
|
```
|
|
155
162
|
my-wiki/
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
│
|
|
161
|
-
│
|
|
162
|
-
│
|
|
163
|
-
├─
|
|
164
|
-
│
|
|
165
|
-
│
|
|
166
|
-
|
|
167
|
-
│ ├─
|
|
168
|
-
│
|
|
169
|
-
├─
|
|
170
|
-
│ ├─
|
|
171
|
-
│
|
|
172
|
-
|
|
173
|
-
│ ├─
|
|
174
|
-
│ ├─
|
|
175
|
-
│
|
|
176
|
-
├─ .
|
|
177
|
-
│ ├─
|
|
178
|
-
│ └─
|
|
179
|
-
└─ WIKI_SCHEMA.md
|
|
163
|
+
└─ .llm-wiki/
|
|
164
|
+
├─ config.json # Vault config
|
|
165
|
+
├─ templates/ # Page templates
|
|
166
|
+
├─ raw/
|
|
167
|
+
│ └─ sources/
|
|
168
|
+
│ └─ SRC-2026-05-11-001/
|
|
169
|
+
│ ├─ manifest.json
|
|
170
|
+
│ ├─ original/ # Original artifact
|
|
171
|
+
│ ├─ extracted.md # Normalized text
|
|
172
|
+
│ └─ attachments/
|
|
173
|
+
├─ wiki/
|
|
174
|
+
│ ├─ sources/ # Source pages (what each source says)
|
|
175
|
+
│ ├─ concepts/ # Concepts and recurring ideas
|
|
176
|
+
│ ├─ entities/ # People, orgs, products, papers, systems
|
|
177
|
+
│ ├─ syntheses/ # Cross-source theses and tensions
|
|
178
|
+
│ └─ analyses/ # Durable filed answers from queries
|
|
179
|
+
├─ meta/
|
|
180
|
+
│ ├─ registry.json # Auto-generated search index
|
|
181
|
+
│ ├─ backlinks.json
|
|
182
|
+
│ ├─ index.md
|
|
183
|
+
│ ├─ events.jsonl # Append-only event log
|
|
184
|
+
│ ├─ log.md
|
|
185
|
+
│ └─ lint-report.md
|
|
186
|
+
└─ WIKI_SCHEMA.md # Operating manual
|
|
180
187
|
```
|
|
181
188
|
|
|
182
189
|
### Ownership Model
|
|
183
190
|
|
|
184
191
|
| Path | Owner | Rule |
|
|
185
192
|
|------|-------|------|
|
|
186
|
-
|
|
|
187
|
-
|
|
188
|
-
|
|
|
189
|
-
|
|
|
190
|
-
|
|
|
191
|
-
|
|
|
192
|
-
|
|
|
193
|
-
|
|
|
194
|
-
|
|
|
193
|
+
| Path | Owner | Rule |
|
|
194
|
+
|------|-------|------|
|
|
195
|
+
| `.llm-wiki/raw/**` | Extension tools | Immutable after capture |
|
|
196
|
+
| `.llm-wiki/wiki/**` | Model + user | Editable knowledge pages |
|
|
197
|
+
| `.llm-wiki/meta/registry.json` | Extension | Generated |
|
|
198
|
+
| `.llm-wiki/meta/backlinks.json` | Extension | Generated |
|
|
199
|
+
| `.llm-wiki/meta/index.md` | Extension | Generated |
|
|
200
|
+
| `.llm-wiki/meta/events.jsonl` | Extension / tool | Append-only |
|
|
201
|
+
| `.llm-wiki/meta/log.md` | Extension | Generated from events |
|
|
202
|
+
| `.llm-wiki/meta/lint-report.md` | Extension | Generated |
|
|
203
|
+
| `.llm-wiki/WIKI_SCHEMA.md` | Human + explicit request | Operating manual |
|
|
195
204
|
|
|
196
205
|
---
|
|
197
206
|
|
|
@@ -219,15 +228,15 @@ Stable source-page IDs keep provenance stable even if titles change.
|
|
|
219
228
|
|
|
220
229
|
The extension **blocks** direct tool-call edits to:
|
|
221
230
|
|
|
222
|
-
-
|
|
223
|
-
-
|
|
224
|
-
-
|
|
225
|
-
-
|
|
226
|
-
-
|
|
227
|
-
-
|
|
228
|
-
-
|
|
231
|
+
- `.llm-wiki/raw/**` — immutable source artifacts
|
|
232
|
+
- `.llm-wiki/meta/registry.json`
|
|
233
|
+
- `.llm-wiki/meta/backlinks.json`
|
|
234
|
+
- `.llm-wiki/meta/events.jsonl`
|
|
235
|
+
- `.llm-wiki/meta/index.md`
|
|
236
|
+
- `.llm-wiki/meta/log.md`
|
|
237
|
+
- `.llm-wiki/meta/lint-report.md`
|
|
229
238
|
|
|
230
|
-
If the model directly edits
|
|
239
|
+
If the model directly edits `.llm-wiki/wiki/**` using Pi's built-in `write` or `edit` tools, the extension **automatically rebuilds** generated metadata at the end of the agent turn.
|
|
231
240
|
|
|
232
241
|
---
|
|
233
242
|
|
|
@@ -236,7 +245,7 @@ If the model directly edits `wiki/**` using Pi's built-in `write` or `edit` tool
|
|
|
236
245
|
Each captured source is stored as a structured packet:
|
|
237
246
|
|
|
238
247
|
```
|
|
239
|
-
raw/sources/SRC-YYYY-MM-DD-NNN/
|
|
248
|
+
.llm-wiki/raw/sources/SRC-YYYY-MM-DD-NNN/
|
|
240
249
|
├─ manifest.json # Capture metadata (title, URL, format, timestamp)
|
|
241
250
|
├─ original/ # Original artifact (preserved as-is)
|
|
242
251
|
├─ extracted.md # Normalized text (PDF→md, XML→md, JSON→md, etc.)
|
|
@@ -247,6 +256,34 @@ This preserves both the **original artifact** and a **normalized extracted view*
|
|
|
247
256
|
|
|
248
257
|
---
|
|
249
258
|
|
|
259
|
+
## MCP Server
|
|
260
|
+
|
|
261
|
+
Use the wiki from **any MCP-compatible tool** — Claude Code, Cursor, Windsurf, and others.
|
|
262
|
+
|
|
263
|
+
The package ships a standalone MCP server exposing 5 wiki tools over stdio:
|
|
264
|
+
|
|
265
|
+
| Tool | Description |
|
|
266
|
+
|------|-------------|
|
|
267
|
+
| `wiki_recall` | Search wiki for task-relevant pages |
|
|
268
|
+
| `wiki_search` | Full registry search |
|
|
269
|
+
| `wiki_status` | Wiki stats (page counts, type breakdown) |
|
|
270
|
+
| `wiki_retro` | Save atomic insights |
|
|
271
|
+
| `wiki_capture_source` | Capture text as a source packet |
|
|
272
|
+
|
|
273
|
+
### Usage
|
|
274
|
+
|
|
275
|
+
```bash
|
|
276
|
+
# Auto-discovered by pi:
|
|
277
|
+
pi install npm:@zosmaai/pi-llm-wiki
|
|
278
|
+
|
|
279
|
+
# Standalone with any MCP client:
|
|
280
|
+
WIKI_ROOT=~/my-wiki node node_modules/@zosmaai/pi-llm-wiki/mcp/index.js
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
Set `WIKI_ROOT` to your wiki vault directory. If unset, the server auto-detects from the current working directory.
|
|
284
|
+
|
|
285
|
+
---
|
|
286
|
+
|
|
250
287
|
## Skill Behavior
|
|
251
288
|
|
|
252
289
|
The bundled `llm-wiki` skill teaches the model to:
|
|
@@ -266,10 +303,10 @@ The bundled `llm-wiki` skill teaches the model to:
|
|
|
266
303
|
Four layers with clear ownership:
|
|
267
304
|
|
|
268
305
|
```
|
|
269
|
-
raw/sources/SRC-*/ # Immutable source packets (extension-owned)
|
|
270
|
-
wiki/ # Editable knowledge pages (you + LLM)
|
|
271
|
-
meta/ # Auto-generated registry, backlinks, index, log
|
|
272
|
-
.wiki/
|
|
306
|
+
.llm-wiki/raw/sources/SRC-*/ # Immutable source packets (extension-owned)
|
|
307
|
+
.llm-wiki/wiki/ # Editable knowledge pages (you + LLM)
|
|
308
|
+
.llm-wiki/meta/ # Auto-generated registry, backlinks, index, log
|
|
309
|
+
.llm-wiki/ # Config and templates
|
|
273
310
|
```
|
|
274
311
|
|
|
275
312
|
Read [docs/architecture.md](docs/architecture.md) for the full design document.
|
package/docs/architecture.md
CHANGED
|
@@ -4,43 +4,47 @@
|
|
|
4
4
|
|
|
5
5
|
```
|
|
6
6
|
WIKI_ROOT/
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
│
|
|
12
|
-
├──
|
|
13
|
-
│ ├──
|
|
14
|
-
│
|
|
15
|
-
|
|
16
|
-
│ ├──
|
|
17
|
-
│
|
|
18
|
-
├──
|
|
19
|
-
│ ├──
|
|
20
|
-
│
|
|
21
|
-
|
|
22
|
-
│ ├──
|
|
23
|
-
│
|
|
24
|
-
|
|
25
|
-
├──
|
|
26
|
-
└──
|
|
7
|
+
└── .llm-wiki/ # All wiki content under one dot-dir
|
|
8
|
+
├── config.json # Vault config
|
|
9
|
+
├── templates/ # Page templates
|
|
10
|
+
├── raw/sources/SRC-*/ # Immutable source packets (extension-owned)
|
|
11
|
+
│ ├── manifest.json # Capture metadata
|
|
12
|
+
│ ├── original/ # Original artifact
|
|
13
|
+
│ ├── extracted.md # Normalized markdown
|
|
14
|
+
│ └── attachments/ # Downloaded images, PDFs
|
|
15
|
+
├── wiki/ # Editable knowledge pages (you + LLM)
|
|
16
|
+
│ ├── sources/ # One summary per source
|
|
17
|
+
│ ├── entities/ # People, orgs, tools, products
|
|
18
|
+
│ ├── concepts/ # Ideas, patterns, frameworks
|
|
19
|
+
│ ├── syntheses/ # Cross-cutting analyses
|
|
20
|
+
│ └── analyses/ # Durable query answers
|
|
21
|
+
├── meta/ # Auto-generated (extension-owned)
|
|
22
|
+
│ ├── registry.json # Master page catalog
|
|
23
|
+
│ ├── backlinks.json # Inbound link map
|
|
24
|
+
│ ├── index.md # Human-readable catalog
|
|
25
|
+
│ ├── log.md # Activity log
|
|
26
|
+
│ └── events.jsonl # Structured event stream
|
|
27
|
+
├── outputs/ # Generated artifacts
|
|
28
|
+
└── .discoveries/ # Discovery tracking
|
|
27
29
|
```
|
|
28
30
|
|
|
29
31
|
## Ownership Rules
|
|
30
32
|
|
|
31
33
|
| Path | Owner | Rule |
|
|
32
34
|
| --------- | ------------------------ | ------------------------ |
|
|
33
|
-
|
|
|
34
|
-
|
|
|
35
|
-
|
|
|
36
|
-
| `.wiki
|
|
35
|
+
| Path | Owner | Rule |
|
|
36
|
+
| --------------------- | ------------------------ | ------------------------ |
|
|
37
|
+
| `.llm-wiki/raw/**` | Extension | Immutable after capture |
|
|
38
|
+
| `.llm-wiki/wiki/**` | Model + user | Editable knowledge pages |
|
|
39
|
+
| `.llm-wiki/meta/**` | Extension | Auto-generated |
|
|
40
|
+
| `.llm-wiki/` | Human + explicit request | Operating rules |
|
|
37
41
|
|
|
38
42
|
## Source Packet Format
|
|
39
43
|
|
|
40
44
|
Each captured source becomes a packet:
|
|
41
45
|
|
|
42
46
|
```
|
|
43
|
-
raw/sources/SRC-YYYY-MM-DD-NNN/
|
|
47
|
+
.llm-wiki/raw/sources/SRC-YYYY-MM-DD-NNN/
|
|
44
48
|
manifest.json
|
|
45
49
|
original/
|
|
46
50
|
extracted.md
|
|
@@ -62,4 +66,4 @@ raw/sources/SRC-YYYY-MM-DD-NNN/
|
|
|
62
66
|
|
|
63
67
|
## Guardrails
|
|
64
68
|
|
|
65
|
-
The extension blocks direct edits to
|
|
69
|
+
The extension blocks direct edits to `.llm-wiki/raw/**` and `.llm-wiki/meta/**`. Metadata rebuilds automatically after `.llm-wiki/wiki/**` edits.
|
package/docs/commands.md
CHANGED
|
@@ -36,7 +36,7 @@ The extension registers 10 tools the LLM can call directly:
|
|
|
36
36
|
|
|
37
37
|
1. `wiki_capture_source(url="...")` — creates packet + skeleton
|
|
38
38
|
2. `wiki_ingest()` — get batch of sources needing synthesis
|
|
39
|
-
3. Read
|
|
39
|
+
3. Read `.llm-wiki/raw/sources/SRC-*/extracted.md`
|
|
40
40
|
4. Update skeleton source page with summary, entities, concepts
|
|
41
41
|
5. `wiki_ensure_page(type="entity", title="...")` for each entity
|
|
42
42
|
6. Add `[[wikilinks]]` between related pages
|
package/docs/configuration.md
CHANGED
package/docs/obsidian.md
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
## Setup
|
|
4
4
|
|
|
5
|
-
1. Open
|
|
6
|
-
2. The extension generates
|
|
7
|
-
3.
|
|
5
|
+
1. Open `.llm-wiki/wiki/` as an Obsidian vault
|
|
6
|
+
2. The extension generates `.llm-wiki/meta/index.md` as a browsable catalog
|
|
7
|
+
3. `.llm-wiki/meta/backlinks.json` is available for graph plugins
|
|
8
8
|
|
|
9
9
|
## Recommended Plugins
|
|
10
10
|
|
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
|
|
15
15
|
## Web Clipper
|
|
16
16
|
|
|
17
|
-
Use [Obsidian Web Clipper](https://obsidian.md/clipper) to save articles directly into
|
|
17
|
+
Use [Obsidian Web Clipper](https://obsidian.md/clipper) to save articles directly into `.llm-wiki/raw/articles/`.
|
|
18
18
|
|
|
19
19
|
## Dataview Dashboard
|
|
20
20
|
|
|
21
|
-
The extension creates
|
|
21
|
+
The extension creates `.llm-wiki/meta/index.md` with page listings. For custom dashboards, use Dataview queries against frontmatter fields like `type`, `domain`, `category`, `sources`.
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
1
3
|
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
2
4
|
import { installGuardrails } from "./lib/guardrails.js";
|
|
5
|
+
import { formatRecallContext, registerWikiRecall, searchWiki } from "./lib/recall.js";
|
|
6
|
+
import { registerWikiRetro } from "./lib/retro.js";
|
|
3
7
|
import {
|
|
4
8
|
registerWikiBootstrap,
|
|
5
9
|
registerWikiCaptureSource,
|
|
@@ -12,25 +16,22 @@ import {
|
|
|
12
16
|
registerWikiStatus,
|
|
13
17
|
registerWikiWatch,
|
|
14
18
|
} from "./lib/tools.js";
|
|
19
|
+
import { resolveVaultPaths } from "./lib/utils.js";
|
|
15
20
|
|
|
16
21
|
/**
|
|
17
22
|
* @zosmaai/pi-llm-wiki — LLM Wiki extension for Pi
|
|
18
23
|
*
|
|
19
|
-
* Registers
|
|
20
|
-
* -
|
|
21
|
-
* - wiki_capture_source Capture URL/file/text into source packet
|
|
22
|
-
* - wiki_ingest Get batch of sources needing synthesis
|
|
23
|
-
* - wiki_ensure_page Create canonical page from template
|
|
24
|
-
* - wiki_search Search generated registry
|
|
25
|
-
* - wiki_lint Health check with auto-fix
|
|
26
|
-
* - wiki_status Instant stats from registry
|
|
27
|
-
* - wiki_rebuild_meta Force metadata rebuild
|
|
28
|
-
* - wiki_log_event Append event and regenerate log
|
|
29
|
-
* - wiki_watch Schedule auto-updates
|
|
24
|
+
* Registers 11 custom tools and installs guardrails:
|
|
25
|
+
* All 10 original tools + wiki_recall (auto-recall at session start)
|
|
30
26
|
*
|
|
31
27
|
* Guardrails:
|
|
32
28
|
* - Blocks direct edits to raw/** and meta/**
|
|
33
29
|
* - Auto-rebuilds metadata after wiki/** edits
|
|
30
|
+
*
|
|
31
|
+
* Auto-recall:
|
|
32
|
+
* - before_agent_start hook searches wiki for pages relevant to user prompt
|
|
33
|
+
* - Injects matching knowledge as system context
|
|
34
|
+
* - wiki_recall tool available for explicit deep searches
|
|
34
35
|
*/
|
|
35
36
|
|
|
36
37
|
export default function (pi: ExtensionAPI) {
|
|
@@ -44,10 +45,35 @@ export default function (pi: ExtensionAPI) {
|
|
|
44
45
|
registerWikiRebuildMeta(pi);
|
|
45
46
|
registerWikiLogEvent(pi);
|
|
46
47
|
registerWikiWatch(pi);
|
|
48
|
+
registerWikiRecall(pi);
|
|
49
|
+
registerWikiRetro(pi);
|
|
47
50
|
|
|
48
51
|
installGuardrails(pi);
|
|
49
52
|
|
|
50
53
|
pi.on("session_start", async (_event, ctx) => {
|
|
51
|
-
ctx.ui.setStatus("llm-wiki", "🧠 LLM Wiki (
|
|
54
|
+
ctx.ui.setStatus("llm-wiki", "🧠 LLM Wiki (11 tools, auto-recall active)");
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// ─── Auto-recall hook ──────────────────────────────
|
|
58
|
+
// Before each agent turn, search the wiki for pages relevant
|
|
59
|
+
// to the user's prompt and inject them as system context.
|
|
60
|
+
pi.on("before_agent_start", async (event, _ctx) => {
|
|
61
|
+
const paths = resolveVaultPaths(process.cwd());
|
|
62
|
+
if (!existsSync(join(paths.dotWiki, "config.json"))) {
|
|
63
|
+
return; // No wiki vault — nothing to recall
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const prompt = event.prompt || "";
|
|
67
|
+
if (!prompt.trim()) return;
|
|
68
|
+
|
|
69
|
+
const results = searchWiki(paths, prompt);
|
|
70
|
+
if (results.length === 0) return;
|
|
71
|
+
|
|
72
|
+
const context = formatRecallContext(results);
|
|
73
|
+
if (!context) return;
|
|
74
|
+
|
|
75
|
+
return {
|
|
76
|
+
systemPrompt: `${event.systemPrompt}\n\n${context}`,
|
|
77
|
+
};
|
|
52
78
|
});
|
|
53
79
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { isToolCallEventType } from "@mariozechner/pi-coding-agent";
|
|
2
2
|
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
3
3
|
import { rebuildMetadataLight } from "./metadata.js";
|
|
4
|
-
import { isProtectedPath,
|
|
4
|
+
import { isProtectedPath, resolveVaultPaths } from "./utils.js";
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Guardrails and auto-rebuild hooks for the LLM Wiki extension.
|
|
@@ -15,8 +15,8 @@ export function installGuardrails(pi: ExtensionAPI): void {
|
|
|
15
15
|
pi.on("tool_call", async (event) => {
|
|
16
16
|
if (isToolCallEventType("write", event)) {
|
|
17
17
|
const path = event.input.path as string;
|
|
18
|
-
const
|
|
19
|
-
const check = isProtectedPath(path,
|
|
18
|
+
const paths = resolveVaultPaths(process.cwd());
|
|
19
|
+
const check = isProtectedPath(path, paths);
|
|
20
20
|
if (check.protected) {
|
|
21
21
|
return { block: true, reason: check.reason };
|
|
22
22
|
}
|
|
@@ -24,8 +24,8 @@ export function installGuardrails(pi: ExtensionAPI): void {
|
|
|
24
24
|
|
|
25
25
|
if (isToolCallEventType("edit", event)) {
|
|
26
26
|
const path = event.input.path as string;
|
|
27
|
-
const
|
|
28
|
-
const check = isProtectedPath(path,
|
|
27
|
+
const paths = resolveVaultPaths(process.cwd());
|
|
28
|
+
const check = isProtectedPath(path, paths);
|
|
29
29
|
if (check.protected) {
|
|
30
30
|
return { block: true, reason: check.reason };
|
|
31
31
|
}
|
|
@@ -36,8 +36,8 @@ export function installGuardrails(pi: ExtensionAPI): void {
|
|
|
36
36
|
pi.on("tool_result", async (event) => {
|
|
37
37
|
if (event.toolName === "write" || event.toolName === "edit") {
|
|
38
38
|
const path = event.input.path as string;
|
|
39
|
-
const
|
|
40
|
-
const wikiPath = `${
|
|
39
|
+
const paths = resolveVaultPaths(process.cwd());
|
|
40
|
+
const wikiPath = `${paths.wiki}/`;
|
|
41
41
|
if (path?.startsWith(wikiPath)) {
|
|
42
42
|
pendingRebuild = true;
|
|
43
43
|
}
|
|
@@ -49,17 +49,7 @@ export function installGuardrails(pi: ExtensionAPI): void {
|
|
|
49
49
|
if (pendingRebuild) {
|
|
50
50
|
pendingRebuild = false;
|
|
51
51
|
try {
|
|
52
|
-
const
|
|
53
|
-
const paths = {
|
|
54
|
-
root,
|
|
55
|
-
raw: `${root}/raw`,
|
|
56
|
-
rawSources: `${root}/raw/sources`,
|
|
57
|
-
wiki: `${root}/wiki`,
|
|
58
|
-
meta: `${root}/meta`,
|
|
59
|
-
dotWiki: `${root}/.wiki`,
|
|
60
|
-
outputs: `${root}/outputs`,
|
|
61
|
-
discoveries: `${root}/.discoveries`,
|
|
62
|
-
};
|
|
52
|
+
const paths = resolveVaultPaths(process.cwd());
|
|
63
53
|
rebuildMetadataLight(paths);
|
|
64
54
|
} catch {
|
|
65
55
|
// Silently fail — metadata rebuild is best-effort
|