pi-para 0.5.2

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.
Files changed (198) hide show
  1. package/CHANGELOG.md +214 -0
  2. package/README.md +305 -0
  3. package/SETUP.md +171 -0
  4. package/dist/capture.d.ts +34 -0
  5. package/dist/capture.d.ts.map +1 -0
  6. package/dist/capture.js +461 -0
  7. package/dist/capture.js.map +1 -0
  8. package/dist/cli.d.ts +15 -0
  9. package/dist/cli.d.ts.map +1 -0
  10. package/dist/cli.js +405 -0
  11. package/dist/cli.js.map +1 -0
  12. package/dist/commands.d.ts +15 -0
  13. package/dist/commands.d.ts.map +1 -0
  14. package/dist/commands.js +786 -0
  15. package/dist/commands.js.map +1 -0
  16. package/dist/context.d.ts +61 -0
  17. package/dist/context.d.ts.map +1 -0
  18. package/dist/context.js +289 -0
  19. package/dist/context.js.map +1 -0
  20. package/dist/daemon.d.ts +49 -0
  21. package/dist/daemon.d.ts.map +1 -0
  22. package/dist/daemon.js +226 -0
  23. package/dist/daemon.js.map +1 -0
  24. package/dist/frontmatter.d.ts +59 -0
  25. package/dist/frontmatter.d.ts.map +1 -0
  26. package/dist/frontmatter.js +170 -0
  27. package/dist/frontmatter.js.map +1 -0
  28. package/dist/gepa/dataset.d.ts +36 -0
  29. package/dist/gepa/dataset.d.ts.map +1 -0
  30. package/dist/gepa/dataset.js +148 -0
  31. package/dist/gepa/dataset.js.map +1 -0
  32. package/dist/gepa/evaluator.d.ts +51 -0
  33. package/dist/gepa/evaluator.d.ts.map +1 -0
  34. package/dist/gepa/evaluator.js +317 -0
  35. package/dist/gepa/evaluator.js.map +1 -0
  36. package/dist/gepa/index.d.ts +66 -0
  37. package/dist/gepa/index.d.ts.map +1 -0
  38. package/dist/gepa/index.js +240 -0
  39. package/dist/gepa/index.js.map +1 -0
  40. package/dist/gepa/llm.d.ts +35 -0
  41. package/dist/gepa/llm.d.ts.map +1 -0
  42. package/dist/gepa/llm.js +268 -0
  43. package/dist/gepa/llm.js.map +1 -0
  44. package/dist/gepa/optimized/capture-prompt.txt +65 -0
  45. package/dist/gepa/optimizer.d.ts +29 -0
  46. package/dist/gepa/optimizer.d.ts.map +1 -0
  47. package/dist/gepa/optimizer.js +249 -0
  48. package/dist/gepa/optimizer.js.map +1 -0
  49. package/dist/gepa/targets.d.ts +39 -0
  50. package/dist/gepa/targets.d.ts.map +1 -0
  51. package/dist/gepa/targets.js +326 -0
  52. package/dist/gepa/targets.js.map +1 -0
  53. package/dist/gepa/types.d.ts +168 -0
  54. package/dist/gepa/types.d.ts.map +1 -0
  55. package/dist/gepa/types.js +124 -0
  56. package/dist/gepa/types.js.map +1 -0
  57. package/dist/index.d.ts +21 -0
  58. package/dist/index.d.ts.map +1 -0
  59. package/dist/index.js +294 -0
  60. package/dist/index.js.map +1 -0
  61. package/dist/ingest.d.ts +88 -0
  62. package/dist/ingest.d.ts.map +1 -0
  63. package/dist/ingest.js +105 -0
  64. package/dist/ingest.js.map +1 -0
  65. package/dist/link-discovery.d.ts +40 -0
  66. package/dist/link-discovery.d.ts.map +1 -0
  67. package/dist/link-discovery.js +122 -0
  68. package/dist/link-discovery.js.map +1 -0
  69. package/dist/link-utils.d.ts +30 -0
  70. package/dist/link-utils.d.ts.map +1 -0
  71. package/dist/link-utils.js +145 -0
  72. package/dist/link-utils.js.map +1 -0
  73. package/dist/lint.d.ts +39 -0
  74. package/dist/lint.d.ts.map +1 -0
  75. package/dist/lint.js +827 -0
  76. package/dist/lint.js.map +1 -0
  77. package/dist/maintainer.d.ts +24 -0
  78. package/dist/maintainer.d.ts.map +1 -0
  79. package/dist/maintainer.js +358 -0
  80. package/dist/maintainer.js.map +1 -0
  81. package/dist/processor.d.ts +14 -0
  82. package/dist/processor.d.ts.map +1 -0
  83. package/dist/processor.js +361 -0
  84. package/dist/processor.js.map +1 -0
  85. package/dist/query.d.ts +69 -0
  86. package/dist/query.d.ts.map +1 -0
  87. package/dist/query.js +107 -0
  88. package/dist/query.js.map +1 -0
  89. package/dist/raw.d.ts +57 -0
  90. package/dist/raw.d.ts.map +1 -0
  91. package/dist/raw.js +219 -0
  92. package/dist/raw.js.map +1 -0
  93. package/dist/redact.d.ts +21 -0
  94. package/dist/redact.d.ts.map +1 -0
  95. package/dist/redact.js +143 -0
  96. package/dist/redact.js.map +1 -0
  97. package/dist/scope.d.ts +54 -0
  98. package/dist/scope.d.ts.map +1 -0
  99. package/dist/scope.js +161 -0
  100. package/dist/scope.js.map +1 -0
  101. package/dist/scripts/bulk-link-fix.d.ts +9 -0
  102. package/dist/scripts/bulk-link-fix.d.ts.map +1 -0
  103. package/dist/scripts/bulk-link-fix.js +106 -0
  104. package/dist/scripts/bulk-link-fix.js.map +1 -0
  105. package/dist/session-tools.d.ts +33 -0
  106. package/dist/session-tools.d.ts.map +1 -0
  107. package/dist/session-tools.js +211 -0
  108. package/dist/session-tools.js.map +1 -0
  109. package/dist/state.d.ts +54 -0
  110. package/dist/state.d.ts.map +1 -0
  111. package/dist/state.js +176 -0
  112. package/dist/state.js.map +1 -0
  113. package/dist/store.d.ts +56 -0
  114. package/dist/store.d.ts.map +1 -0
  115. package/dist/store.js +227 -0
  116. package/dist/store.js.map +1 -0
  117. package/dist/summarize.d.ts +56 -0
  118. package/dist/summarize.d.ts.map +1 -0
  119. package/dist/summarize.js +231 -0
  120. package/dist/summarize.js.map +1 -0
  121. package/dist/tag-registry.d.ts +56 -0
  122. package/dist/tag-registry.d.ts.map +1 -0
  123. package/dist/tag-registry.js +146 -0
  124. package/dist/tag-registry.js.map +1 -0
  125. package/dist/templates/prompts.d.ts +63 -0
  126. package/dist/templates/prompts.d.ts.map +1 -0
  127. package/dist/templates/prompts.js +260 -0
  128. package/dist/templates/prompts.js.map +1 -0
  129. package/dist/tools.d.ts +26 -0
  130. package/dist/tools.d.ts.map +1 -0
  131. package/dist/tools.js +1033 -0
  132. package/dist/tools.js.map +1 -0
  133. package/dist/watcher.d.ts +25 -0
  134. package/dist/watcher.d.ts.map +1 -0
  135. package/dist/watcher.js +84 -0
  136. package/dist/watcher.js.map +1 -0
  137. package/dist/webui/client/dist/index.html +1885 -0
  138. package/dist/webui/server.d.ts +31 -0
  139. package/dist/webui/server.d.ts.map +1 -0
  140. package/dist/webui/server.js +566 -0
  141. package/dist/webui/server.js.map +1 -0
  142. package/dist/wiki.d.ts +103 -0
  143. package/dist/wiki.d.ts.map +1 -0
  144. package/dist/wiki.js +428 -0
  145. package/dist/wiki.js.map +1 -0
  146. package/package.json +142 -0
  147. package/scripts/gepa/__pycache__/dataset.cpython-313.pyc +0 -0
  148. package/scripts/gepa/__pycache__/lm_providers.cpython-313.pyc +0 -0
  149. package/scripts/gepa/__pycache__/metric.cpython-313.pyc +0 -0
  150. package/scripts/gepa/__pycache__/program.cpython-313.pyc +0 -0
  151. package/scripts/gepa/__pycache__/wiki_reader.cpython-313.pyc +0 -0
  152. package/scripts/gepa/dataset.py +192 -0
  153. package/scripts/gepa/lm_providers.py +472 -0
  154. package/scripts/gepa/metric.py +279 -0
  155. package/scripts/gepa/optimize.py +367 -0
  156. package/scripts/gepa/program.py +99 -0
  157. package/scripts/gepa/pyproject.toml +19 -0
  158. package/scripts/gepa/run-all.sh +53 -0
  159. package/scripts/gepa/uv.lock +2241 -0
  160. package/scripts/gepa/wiki_reader.py +113 -0
  161. package/skills/para/SKILL.md +77 -0
  162. package/skills/setup/SKILL.md +20 -0
  163. package/src/capture.ts +563 -0
  164. package/src/cli.ts +416 -0
  165. package/src/commands.ts +878 -0
  166. package/src/context.ts +390 -0
  167. package/src/daemon.ts +288 -0
  168. package/src/frontmatter.ts +219 -0
  169. package/src/gepa/index.ts +287 -0
  170. package/src/gepa/optimized/capture-prompt.txt +65 -0
  171. package/src/index.ts +384 -0
  172. package/src/ingest.ts +177 -0
  173. package/src/link-discovery.ts +170 -0
  174. package/src/link-utils.ts +169 -0
  175. package/src/lint.ts +1018 -0
  176. package/src/maintainer.ts +404 -0
  177. package/src/processor.ts +415 -0
  178. package/src/python/__pycache__/minimax_lm.cpython-312.pyc +0 -0
  179. package/src/python/minimax_lm.py +198 -0
  180. package/src/python/rlm_capture.py +215 -0
  181. package/src/query.ts +148 -0
  182. package/src/raw.ts +276 -0
  183. package/src/redact.ts +159 -0
  184. package/src/scope.ts +214 -0
  185. package/src/scripts/bulk-link-fix.ts +126 -0
  186. package/src/session-tools.ts +260 -0
  187. package/src/state.ts +271 -0
  188. package/src/store.ts +288 -0
  189. package/src/summarize.ts +273 -0
  190. package/src/tag-registry.ts +157 -0
  191. package/src/templates/index.md +17 -0
  192. package/src/templates/prompts.ts +274 -0
  193. package/src/templates/schema.md +116 -0
  194. package/src/tools.ts +1293 -0
  195. package/src/watcher.ts +101 -0
  196. package/src/webui/client/dist/index.html +1885 -0
  197. package/src/webui/server.ts +765 -0
  198. package/src/wiki.ts +550 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,214 @@
1
+ # Changelog
2
+
3
+ ## [0.5.2] — 2026-05-02
4
+
5
+ ### Added
6
+ - **Configurable teacher/student/judge models** for GEPA optimization
7
+ - `gepa.studentModel`: runs proxy (default: `claude-sonnet-4`) — fast, cheap, ~460 calls/target
8
+ - `gepa.teacherModel`: proposes mutations (default: `claude-opus-4-6`) — smart, creative, ~30 calls/target
9
+ - `gepa.judgeModel`: scores output (default: same as student) — fast, cheap
10
+ - CLI flags: `--student-model`, `--teacher-model`, `--judge-model` (+ `--model`/`--reflection-model` shorthands)
11
+ - All GEPA settings persisted in `config.json` and overridable via CLI
12
+ - `run-all.sh` helper script for sequential target optimization with proper token refresh
13
+ - OAuth token auto-refresh in `AnthropicOAuthLM` (prevents 401 on long runs)
14
+
15
+ ## [0.5.1] — 2026-05-01
16
+
17
+ ### Added
18
+ - **Bundled GEPA-optimized prompts** — ship pre-optimized `capture-prompt` with the package (32.4% improvement over baseline: 0.582 → 0.770)
19
+ - `getPrompt()` resolution order: user-generated → bundled optimized → original constant
20
+ - `gepa.useOptimized` defaults to `true` so users get optimized prompts out of the box
21
+ - Build copies `src/gepa/optimized/*.txt` into `dist/gepa/optimized/` automatically
22
+
23
+ ## [0.5.0] — 2026-05-01
24
+
25
+ ### Added
26
+ - **GEPA prompt optimizer** — automatically optimize all pi-para prompts, tool instructions, and skill guidelines using DSPy GEPA (Genetic-Pareto optimizer)
27
+ - 22 optimization targets: 12 prompt templates, 8 tool instructions, 2 skills
28
+ - Runs via `uv` with custom `dspy.BaseLM` subclasses — no litellm dependency
29
+ - Custom `AnthropicOAuthLM` with Claude Code billing headers and user-agent for free OAuth usage
30
+ - Custom `MiniMaxLM` (Anthropic-compatible API) and `OpenRouterLM` (OpenAI-compatible API)
31
+ - LLM-as-judge metric scoring on 6 dimensions: structure, PARA compliance, cross-references, security, completeness, actionability
32
+ - Trainset built from real wiki pages (no synthetic data)
33
+ - Side-by-side deployment: optimized prompts saved to `~/.pi/wiki/gepa/optimized/`, toggled via `config.gepa.useOptimized`
34
+ - API keys extracted from `~/.pi/agent/auth.json` and passed as env vars to `uv` subprocess
35
+ - `PromptProxy` DSPy Module: 1 LLM call per eval instead of full agent loop (10-50 calls)
36
+ - Version history per target in `~/.pi/wiki/gepa/history/`
37
+ - **CLI commands**: `pi-para-daemon gepa optimize|list|targets|compare`
38
+ - **`getPrompt(name)`** function in `src/templates/prompts.ts` — loads GEPA-optimized version at runtime when `config.gepa.useOptimized` is true
39
+ - **`gepa` config section** in `ParaConfig` with `useOptimized` toggle
40
+
41
+ ## [0.4.5] — 2026-04-30
42
+
43
+ ### Fixed
44
+ - **Daemon model change now auto-restarts daemon** — changing the daemon model via `/wiki-settings` → `[Daemon]` now automatically runs `systemctl --user restart pi-para-daemon` so the new model takes effect immediately
45
+ - **qmd FK constraint fix (v2.3.2)** — `deleteInactiveDocuments` now cleans up `document_links` and `document_metadata` before deleting inactive docs, fixing the second FK violation that blocked store opening
46
+
47
+ ## [0.4.4] — 2026-04-29
48
+
49
+ ### Fixed
50
+ - **Lazy store retry** — if qmd store fails to open at session start (db locked, transient error), retries automatically on first tool use instead of staying disabled for the entire session
51
+ - Store proxy intercepts calls when `storeDisabled` is true and attempts `openStore()` before throwing
52
+ - On successful retry, marks context dirty so wiki context is rebuilt
53
+ - Prevents guard against concurrent retry attempts
54
+
55
+ ## [0.4.3] — 2026-04-29
56
+
57
+ ### Added
58
+ - **Mid-session capture on compaction** — registers session for daemon capture when auto/manual compaction fires
59
+ - Hooks into `session_compact` event — fires after context compaction
60
+ - Compaction signals the session has accumulated enough content that details are about to be compressed
61
+ - Perfect capture trigger: knowledge is captured before details are lost in the summary
62
+ - Shows status line feedback: "wiki: capture queued (compaction)"
63
+ - Works alongside existing `session_shutdown` capture — sessions now captured at both compaction and quit
64
+
65
+ ### Fixed
66
+ - Skill name mismatch: `skills/setup/SKILL.md` name field changed from `pi-para-setup` to `setup` to match directory
67
+
68
+ ## [0.4.2] — 2026-04-29
69
+
70
+ ### Added
71
+ - **Configurable graph-boosted search** — `searchGraphBoost` setting in `config.json`
72
+ - Previously hardcoded to `true` in `store.ts`
73
+ - Now controllable via `/wiki-settings` → `[Search]` → `Graph boost: true/false`
74
+ - Threads through the full pipeline: `config` → `registerTools` → `createQueryExecute` → `queryWiki` → `searchWiki` → `store.searchLex`
75
+ - `WikiSearchOptions.graphBoost` and `QueryOptions.graphBoost` added to public interfaces
76
+ - Default remains `true` (1-hop wikilink expansion after BM25 search)
77
+ - `/wiki-settings` `[Search]` now opens a submenu with `Limit` and `Graph boost` options
78
+
79
+ ### Changed
80
+ - README updated: 8 tools (added `wiki_migrate`), 11 commands (added `/wiki-migrate`, `/wiki-project`), `searchGraphBoost` in config example, 301 tests
81
+
82
+ ## [0.4.1] — 2026-04-29
83
+
84
+ ### Added
85
+ - Web UI graph: scope filter dropdown + max nodes slider
86
+
87
+ ## [0.4.0] — 2026-04-29
88
+
89
+ ### Added
90
+ - **Schema versioning & migration** — future-proof wiki format evolution
91
+ - `schemaVersion` integer field in frontmatter (defaults to 1 for existing pages)
92
+ - Migration registry in `frontmatter.ts` — chain of `from→to` transforms
93
+ - `migrateToLatest()` applies all pending migrations sequentially
94
+ - `wiki_migrate` tool (LLM-callable) for batch migration
95
+ - `/wiki-migrate` command — migrates all pages, reports count
96
+ - Lint check #15: `schema-version` — flags pages below current version, auto-fixes
97
+ - **qmd graph-boosted search** (requires @picassio/qmd 2.3.0)
98
+ - `document_links` edge table tracks `[[wikilinks]]` between pages
99
+ - 1-hop graph expansion after BM25 search — surfaces wikilink-connected pages
100
+ - `graphBoost: true` in `searchWiki()` — related pages appear in results even without text match
101
+ - `extractWikilinks()` exported from qmd for reuse
102
+ - **Scale resilience** — tested for 500+ page wikis
103
+ - Code-generated `index.md` via `rebuildIndex()` — deterministic, no LLM generation needed
104
+ - Tiered context injection — max 40 scope-filtered pages in system prompt, rest via `wiki_query`
105
+ - Page summary cache in SQLite — `buildContext()` reads cache instead of N disk reads
106
+ - Web UI pagination — `?page=N&limit=50` on `/api/pages`, `?maxNodes=100` on graph endpoint
107
+ - **PARA project lifecycle**
108
+ - `/wiki-project <name> <goal>` — creates structured project page with goal, status checklist, end condition
109
+ - `/wiki-project done <name>` — archives completed project
110
+ - Maintenance agent reviews projects for completion signals, suggests archiving
111
+ - Maintenance agent updates areas with latest health metrics
112
+ - **PARA active skill** (`skills/para/SKILL.md`)
113
+ - Behavioral guidelines for actively using wiki during work (not just passive capture)
114
+ - Covers: consult before planning, write during work, search when debugging, check conventions when reviewing
115
+ - PARA category decision guide — when to use projects/ vs areas/ vs resources/
116
+
117
+ ### Changed
118
+ - `wiki_write` no longer accepts `indexContent` — index is auto-rebuilt from disk after every write
119
+ - `wiki_move` auto-rebuilds index after moving pages
120
+ - Capture and ingest prompts no longer instruct LLM to generate index
121
+ - Context injection sorts pages by recency, caps at 40 pages with overflow note
122
+
123
+ ### Dependencies
124
+ - Requires @picassio/qmd ≥2.3.0 (graph boost support)
125
+
126
+ ## [0.3.2] — 2026-04-29
127
+
128
+ ### Added
129
+ - **Wiki freshness verification system** — prevents LLM from blindly trusting stale wiki content
130
+ - `formatFreshness()` in `query.ts` computes age-based freshness tiers for every page
131
+ - 5 tiers: ✅ FRESH (<7d), ✅ Recent (7-14d), ⚠️ AGING (14-30d), ⚠️ STALE (30-90d), 🚨 VERY STALE (>90d)
132
+ - `wiki_query` results now include `Updated: ... | ⚠️ STALE — 45 days old` per result
133
+ - `wiki_read` output includes freshness indicator in header line
134
+ - `QUERY_PROMPT` gains "FRESHNESS VERIFICATION (critical)" section with 5 verification rules
135
+ - `wiki_query` and `wiki_read` `promptGuidelines` instruct LLM to verify AGING/STALE pages
136
+ - Context injection adds system prompt reminder about the self-healing loop
137
+ - Maintenance agent gains task #6: staleness review for pages >30 days old making code/config claims
138
+ - `INGEST_PROMPT` gains rule #9: check existing Key Facts accuracy when updating pages
139
+ - **Self-healing loop** — when LLM discovers wiki content is wrong during verification, it fixes the page immediately with `wiki_write(mode: 'edit')`, so future queries get correct answers
140
+
141
+ ## [0.3.0] — 2026-04-28
142
+
143
+ ### Added
144
+ - **Web Wiki UI** — React SPA served by daemon at configurable port
145
+ - Design system: Inter font, 4px grid, semantic color tokens, dark/light toggle
146
+ - Full accessibility: ARIA labels, focus rings, keyboard nav, skip links, reduced motion
147
+ - 18 Lucide-style SVG icons (replaced all emojis)
148
+ - Scope filter dropdown, debounced search, loading states, toast notifications
149
+ - D3 force graph with legend (full-width), breadcrumbs, card-based layouts
150
+ - Graph view: `main-wide` class for full-width display
151
+ - **Secret redaction** (`redact.ts`) — strips API keys, tokens, passwords from all wiki writes
152
+ - 14 pattern types (OpenRouter, OpenAI, Anthropic, MiniMax, GitHub, AWS, Jina, Bearer, YAML, env vars)
153
+ - Runs on every write path: tools.ts, processor.ts, webui server, lint auto-fix
154
+ - **Shared link utilities** (`link-utils.ts`) — centralized `extractWikilinks`, `autoLinkSlugs`, `syncFrontmatterLinks`
155
+ - Replaces 4 duplicate implementations across codebase
156
+ - Protected regions: fenced code, inline code, URLs, headings
157
+ - Longest-slug-first matching, first-occurrence-only linking
158
+ - **Tag registry** (`tag-registry.ts`) — canonical tag normalization + scope validation
159
+ - Alias mapping (capture→session-capture, para→pi-para, etc.)
160
+ - Removes scope-tag duplicates, enforces kebab-case
161
+ - Scope normalization: project-agnostic, extracts kebab prefix from multi-word scopes
162
+ - **LLM maintenance agent** (`maintainer.ts`) — replaces code-based maintenance
163
+ - Runs every 30 min via daemon with wiki_list, wiki_read, wiki_query, wiki_write, wiki_merge, wiki_lint tools
164
+ - Intelligent duplicate detection & merging, link discovery, category review, tag cleanup
165
+ - **Git auto-commit** (`wiki.ts`) — every wiki mutation committed with descriptive message
166
+ - Auto-initializes git repo in wiki directory
167
+ - Commit points: wiki_write, wiki_move, daemon capture, maintenance, webui PUT
168
+ - **Edit mode** for `wiki_write` — surgical `oldText→newText` replacements (like pi's edit tool)
169
+ - **Lint checks 11-14**: link-sync, tag-health, secrets, category-misuse
170
+ - **Scope filter** in web UI — dropdown to filter pages by project scope
171
+ - **`/wiki-daemon status`** — reads state DB directly (instant, no subprocess)
172
+ - **`/wiki-settings`** — provider/model picker from pi's auth storage
173
+
174
+ ### Changed
175
+ - **Web server moved to daemon** — eliminates port conflicts between pi sessions
176
+ - Extension just checks if daemon server is running, shows URL in status bar
177
+ - **`/wiki-capture`** — queues to daemon for background processing (non-blocking)
178
+ - **Daemon uses pi's auth.json** — OAuth token refresh for Anthropic, configurable model via `/wiki-settings`
179
+ - **Daemon scope detection** — reads session header first, falls back to `projects-` prefix extraction (fixes `agent-board` → `board` bug)
180
+ - **Capture prompts** — stronger dedup guidance ("search wiki_query FIRST, update existing pages")
181
+ - **PARA category prompts** — "resources/ for almost everything" across all prompt layers
182
+ - **Schema.md** — expanded with category decision rules, scope/tag format rules, ✅/❌ examples, secrets policy
183
+ - **systemd service** — `bash -lc` login shell (works with mise, nvm, fnm, volta, system node)
184
+
185
+ ### Fixed
186
+ - 2 wiki pages contained live API keys — redacted
187
+ - 38 pages had empty `links: []` — bulk fix added wikilinks
188
+ - 9 tags had spaces — normalized to kebab-case
189
+ - 26 scope-tag duplicates — removed
190
+ - 14 multi-word scope values — cleaned (LLM wrote topic descriptions as scope)
191
+ - 11 pages in projects/ were reference docs — moved to resources/
192
+ - Duplicate pages merged (pi-para-web-wiki-ui, pi-para-extension-architecture, etc.)
193
+ - Graph view confined to 860px — now full-width
194
+ - Scroll container nesting — separated `.main-scroll` from `.main`
195
+
196
+ ## [0.2.0] — 2026-04-27
197
+
198
+ ### Added
199
+ - Web wiki UI — server + React SPA client
200
+ - Daemon (`pi-para-daemon`) for background session capture
201
+ - Interactive `/wiki-settings` with nested menus
202
+ - Configurable via `~/.pi/wiki/config.json`
203
+
204
+ ## [0.1.0] — 2026-04-06
205
+
206
+ ### Added
207
+ - PARA-structured wiki at `~/.pi/wiki/`
208
+ - 7 LLM tools: `wiki_ingest`, `wiki_query`, `wiki_write`, `wiki_read`, `wiki_move`, `wiki_lint`, `wiki_summarize`
209
+ - 7 slash commands: `/wiki`, `/wiki-ingest`, `/wiki-lint`, `/wiki-capture`, `/wiki-scope`, `/wiki-search`, `/wiki-summarize`
210
+ - Auto-capture on session shutdown
211
+ - Project scope detection
212
+ - Context injection with caching
213
+ - 10 lint checks with auto-fix
214
+ - Hybrid search via `@picassio/qmd`
package/README.md ADDED
@@ -0,0 +1,305 @@
1
+ # pi-para
2
+
3
+ A [pi](https://github.com/badlogic/pi-mono) extension that maintains a persistent, LLM-curated personal knowledge base structured by the [PARA method](https://fortelabs.com/blog/para/) (Projects, Areas, Resources, Archives). Inspired by [Karpathy's LLM wiki pattern](https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f).
4
+
5
+ The LLM writes and maintains the wiki autonomously. You provide sources and ask questions. Search powered by [@picassio/qmd](https://github.com/picassio/qmd-1).
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ pi install @picassio/pi-para
11
+ ```
12
+
13
+ Start pi — the extension loads automatically. Wiki directory is created on first session.
14
+
15
+ ## Features
16
+
17
+ ### Wiki Tools (8)
18
+
19
+ | Tool | Description |
20
+ |------|-------------|
21
+ | `wiki_ingest` | Ingest a URL, file, or text into the wiki |
22
+ | `wiki_query` | Search the wiki with scope filtering, graph boost, freshness indicators |
23
+ | `wiki_write` | Create or update wiki pages |
24
+ | `wiki_read` | Read a specific wiki page + freshness indicator |
25
+ | `wiki_move` | Move pages between PARA categories |
26
+ | `wiki_lint` | Run health checks and auto-fix |
27
+ | `wiki_summarize` | Summarize pages, categories, or entire wiki |
28
+ | `wiki_migrate` | Batch-migrate all pages to current schema version |
29
+
30
+ ### Commands (11)
31
+
32
+ | Command | Description |
33
+ |---------|-------------|
34
+ | `/wiki` | Status overview (scope, pages, log) |
35
+ | `/wiki-search <query>` | Search the wiki |
36
+ | `/wiki-ingest <url>` | Quick ingest |
37
+ | `/wiki-capture [topic]` | Ask LLM to save knowledge via wiki_write |
38
+ | `/wiki-scope` | Show or override project scope |
39
+ | `/wiki-lint` | Run health checks |
40
+ | `/wiki-summarize [target]` | Summarize wiki content |
41
+ | `/wiki-settings` | Interactive settings (search, context, daemon, web UI, providers) |
42
+ | `/wiki-daemon <cmd>` | Manage background capture daemon |
43
+ | `/wiki-migrate` | Migrate all pages to current schema version |
44
+ | `/wiki-project <name> <goal>` | Create or archive (`done`) a project page |
45
+
46
+ ### Web Wiki UI
47
+
48
+ Browser-based wiki viewer, editor, and graph visualization.
49
+
50
+ ```
51
+ /wiki-settings → [WebWiki] → Enabled: true
52
+ ```
53
+
54
+ Access at `http://<LAN-IP>:10973`. Features:
55
+ - Page tree by PARA category (sidebar)
56
+ - Markdown viewer with clickable `[[wikilinks]]`
57
+ - Inline page editor
58
+ - D3 force-directed graph view (page relationships)
59
+ - Search
60
+ - Move pages between categories
61
+ - Activity log and session digests
62
+ - Mobile-first responsive design, dark/light theme
63
+
64
+ ### GEPA Prompt Optimizer
65
+
66
+ Automatically optimize all pi-para prompts, tool instructions, and skill guidelines using [DSPy GEPA](https://arxiv.org/abs/2507.19457) (Genetic-Pareto optimizer). Runs via `uv` with custom LLM providers — no litellm.
67
+
68
+ ```bash
69
+ # List all 22 optimization targets
70
+ pi-para-daemon gepa targets
71
+
72
+ # Optimize a single target (uses config defaults: sonnet student + opus teacher)
73
+ pi-para-daemon gepa optimize --target capture-prompt
74
+
75
+ # Optimize all targets sequentially
76
+ bash scripts/gepa/run-all.sh
77
+
78
+ # Override models via CLI
79
+ pi-para-daemon gepa optimize --target skill-para \
80
+ --student-model anthropic/claude-sonnet-4-20250514 \
81
+ --teacher-model anthropic/claude-opus-4-6 \
82
+ --judge-model anthropic/claude-sonnet-4-20250514
83
+
84
+ # Shorthand (--model = student, --reflection-model = teacher)
85
+ pi-para-daemon gepa optimize --model anthropic/claude-sonnet-4-20250514 --reflection-model anthropic/claude-opus-4-6
86
+
87
+ # See results
88
+ pi-para-daemon gepa list
89
+
90
+ # Compare original vs optimized
91
+ pi-para-daemon gepa compare --target capture-prompt
92
+ ```
93
+
94
+ **How it works:**
95
+
96
+ 1. TypeScript extracts all prompt/tool/skill texts from source files
97
+ 2. Calls `uv run scripts/gepa/optimize.py` with API keys from `~/.pi/agent/auth.json`
98
+ 3. Python builds a trainset from real wiki pages (93 pages → 30 train / 20 val)
99
+ 4. DSPy GEPA evolves each instruction using a lightweight proxy module (1 LLM call per eval, not 10-50)
100
+ 5. **Teacher** (Opus) proposes instruction mutations based on metric feedback
101
+ 6. **Student** (Sonnet) runs the proxy to generate output from the instruction
102
+ 7. **Judge** (Sonnet) scores on 6 dimensions: structure, PARA compliance, cross-references, security, completeness, actionability
103
+ 8. Optimized prompts saved to `~/.pi/wiki/gepa/optimized/`
104
+
105
+ **Teacher/Student/Judge pattern** (DSPy GEPA):
106
+
107
+ | Role | Default Model | What It Does | Calls/target |
108
+ |------|---------------|--------------|--------|
109
+ | **Student** | `claude-sonnet-4` | Runs proxy (generates wiki output) | ~460 |
110
+ | **Teacher** | `claude-opus-4-6` | Proposes mutations via reflection | ~30 |
111
+ | **Judge** | `claude-sonnet-4` | Scores output (LLM-as-judge metric) | ~460 |
112
+
113
+ **22 optimization targets:**
114
+
115
+ | Category | Targets |
116
+ |----------|--------|
117
+ | Prompt templates (12) | System, ingest, query, capture (×3), maintenance, processor, summarize, iterative, overview, lint |
118
+ | Tool instructions (8) | wiki_ingest, wiki_query, wiki_write, wiki_read, wiki_move, wiki_lint, wiki_migrate, wiki_summarize |
119
+ | Skills (2) | para (active PARA workflow), setup (installation guide) |
120
+
121
+ **LLM providers** (custom `dspy.BaseLM` subclasses, no litellm):
122
+
123
+ | Provider | Auth | Notes |
124
+ |----------|------|-------|
125
+ | Anthropic | OAuth token from `auth.json` | Claude Code billing headers + user-agent, auto token refresh |
126
+ | MiniMax | API key | Via Anthropic-compatible API |
127
+ | OpenRouter | API key | Via OpenAI-compatible API |
128
+
129
+ **Configuration** (`~/.pi/wiki/config.json`):
130
+
131
+ ```json
132
+ {
133
+ "gepa": {
134
+ "useOptimized": true,
135
+ "studentModel": "anthropic/claude-sonnet-4-20250514",
136
+ "teacherModel": "anthropic/claude-opus-4-6",
137
+ "judgeModel": null,
138
+ "auto": "light",
139
+ "threads": 2,
140
+ "seed": 42
141
+ }
142
+ }
143
+ ```
144
+
145
+ - `useOptimized: true` — load optimized prompts at runtime (enabled by default)
146
+ - `studentModel` — fast model for running proxy + judging (Sonnet recommended)
147
+ - `teacherModel` — smart model for proposing mutations (Opus recommended)
148
+ - `judgeModel` — model for scoring output (defaults to studentModel if null)
149
+ - All settings overridable via CLI flags
150
+
151
+ When `useOptimized` is enabled, `getPrompt(name)` checks: user-generated → bundled optimized → original. Originals are always preserved.
152
+
153
+ **Budget presets:**
154
+
155
+ | Preset | Rollouts | Time estimate | When to use |
156
+ |--------|----------|---------------|-------------|
157
+ | `light` | ~460 | 1-2 hours | Quick sanity check |
158
+ | `medium` | ~1500 | 4-6 hours | Everyday optimization |
159
+ | `heavy` | ~5000 | 12-24 hours | Final tuning |
160
+
161
+ **Prerequisites:** `uv` (Python package manager). DSPy + anthropic SDK installed automatically on first run.
162
+
163
+ ### Background Capture Daemon
164
+
165
+ Processes session files in the background after you quit pi:
166
+
167
+ ```bash
168
+ # Via extension command
169
+ /wiki-daemon start
170
+ /wiki-daemon status
171
+
172
+ # Via CLI
173
+ pi-para-daemon start
174
+ pi-para-daemon process-recent --hours 24
175
+ ```
176
+
177
+ The daemon uses an Agent with session exploration tools (session_slice, session_search, session_stats) to iteratively explore sessions of any size and extract knowledge.
178
+
179
+ Auto-starts via systemd on Linux — run `./setup.sh` once for daemon service setup.
180
+
181
+ ## Architecture
182
+
183
+ ```
184
+ ~/.pi/wiki/
185
+ ├── config.json # all settings (context, search, daemon, web UI, gepa)
186
+ ├── schema.md # PARA conventions
187
+ ├── index.md # page catalog (auto-rebuilt)
188
+ ├── log.md # activity log
189
+ ├── sessions.md # session digest log
190
+ ├── .completed-sessions # daemon registry
191
+ ├── .daemon.sqlite # daemon state
192
+ ├── .qmd.sqlite # search index
193
+ ├── projects/ # active, goal-defined work
194
+ ├── areas/ # ongoing responsibilities
195
+ ├── resources/ # reference material
196
+ ├── archives/ # completed/deprecated
197
+ ├── raw/ # immutable source material
198
+ └── gepa/ # GEPA optimizer state
199
+ ├── input/ # targets.json (generated per run)
200
+ ├── output/ # results.json (GEPA output)
201
+ ├── optimized/ # deployed optimized prompts (*.txt)
202
+ └── history/ # version history per target
203
+ ```
204
+
205
+ **Python scripts (GEPA optimizer):**
206
+
207
+ ```
208
+ scripts/gepa/
209
+ ├── pyproject.toml # uv project (dspy, anthropic, openai deps)
210
+ ├── optimize.py # Main entry — runs DSPy GEPA
211
+ ├── lm_providers.py # Custom BaseLM: AnthropicOAuthLM, MiniMaxLM, OpenRouterLM
212
+ ├── program.py # PromptProxy DSPy Module (1 LLM call per eval)
213
+ ├── metric.py # LLM-as-judge metric (6 dimensions)
214
+ ├── dataset.py # Build train/val from real wiki pages
215
+ └── wiki_reader.py # Read wiki pages from disk
216
+ ```
217
+
218
+ ### How it works
219
+
220
+ 1. **During a session** — LLM uses wiki tools (query, write, ingest). Context injection provides wiki knowledge on every turn.
221
+ 2. **On /quit** — session registered in `.completed-sessions` (instant, <10ms)
222
+ 3. **Background** — daemon picks up session, Agent explores with tools, writes wiki pages
223
+ 4. **Next session** — new wiki pages appear in context injection
224
+
225
+ ### Freshness Verification
226
+
227
+ Every `wiki_query` and `wiki_read` result includes a freshness indicator based on the page's last-updated date:
228
+
229
+ | Age | Indicator | LLM Behavior |
230
+ |-----|-----------|---------------|
231
+ | < 7 days | ✅ FRESH | Trust normally |
232
+ | 7-14 days | ✅ Recent | Trust normally |
233
+ | 14-30 days | ⚠️ AGING | Verify claims about code/configs before trusting |
234
+ | 30-90 days | ⚠️ STALE | Verify before trusting |
235
+ | > 90 days | 🚨 VERY STALE | Likely outdated, verify everything |
236
+
237
+ The LLM is instructed to:
238
+ - **Verify** stale claims by checking actual code, configs, or files
239
+ - **Self-heal** — fix incorrect wiki pages via `wiki_write(mode: 'edit')` when it discovers they're wrong
240
+ - **Flag uncertainty** — tell the user when a claim can't be verified (e.g. external services)
241
+
242
+ ### Configuration
243
+
244
+ All settings via `/wiki-settings` interactive menu, or edit `~/.pi/wiki/config.json`:
245
+
246
+ ```json
247
+ {
248
+ "contextMaxTokens": 4000,
249
+ "searchLimit": 10,
250
+ "searchGraphBoost": true,
251
+ "lintAutoFix": true,
252
+ "lintStaleDays": 90,
253
+ "daemonModel": null,
254
+ "webWiki": { "enabled": true, "host": "0.0.0.0", "port": 10973 },
255
+ "gepa": { "useOptimized": false }
256
+ }
257
+ ```
258
+
259
+ Search providers in `~/.config/qmd/index.yml`:
260
+
261
+ ```yaml
262
+ providers:
263
+ embed:
264
+ url: https://openrouter.ai/api/v1
265
+ key: sk-or-...
266
+ model: openai/text-embedding-3-small
267
+ chat:
268
+ url: https://api.minimaxi.com/anthropic
269
+ key: sk-cp-...
270
+ model: MiniMax-M2.7-highspeed
271
+ api: anthropic
272
+ ```
273
+
274
+ ### Optional: Enhanced search
275
+
276
+ ```bash
277
+ npm install -g @picassio/qmd
278
+ ```
279
+
280
+ Without qmd: BM25 keyword search. With qmd + providers: hybrid BM25 + vector + rerank.
281
+
282
+ ## Obsidian Compatibility
283
+
284
+ The wiki is a directory of markdown files with YAML frontmatter and `[[wikilinks]]`. Open `~/.pi/wiki/` as an Obsidian vault for graph view, Dataview queries, and manual editing.
285
+
286
+ ## Development
287
+
288
+ ```bash
289
+ git clone https://github.com/picassio/pi-para.git
290
+ cd pi-para
291
+ npm install
292
+ npm run check # TypeScript check
293
+ npm test # Run tests (301 tests)
294
+ npm run build # Compile to dist/
295
+
296
+ # Dev mode: symlink extension
297
+ ln -sf $(pwd) ~/.pi/agent/extensions/pi-para
298
+
299
+ # Run daemon locally
300
+ npx tsx src/cli.ts start
301
+ ```
302
+
303
+ ## License
304
+
305
+ MIT
package/SETUP.md ADDED
@@ -0,0 +1,171 @@
1
+ # pi-para Setup Instructions
2
+
3
+ > This file is designed to be read by pi (the AI agent). Ask pi: "read SETUP.md and set up pi-para"
4
+
5
+ ## Prerequisites
6
+
7
+ - pi (coding agent) installed and working
8
+ - Node.js available (`node --version`)
9
+ - Internet access for npm
10
+
11
+ ## Step 1: Install the extension
12
+
13
+ ```bash
14
+ pi install @picassio/pi-para
15
+ ```
16
+
17
+ Verify it loaded — restart pi and check extensions list. You should see `pi-para` in the `[Extensions]` section.
18
+
19
+ ## Step 2: Install qmd search engine (recommended)
20
+
21
+ qmd provides hybrid search (BM25 + vector + rerank). Without it, wiki search uses BM25 keyword matching only.
22
+
23
+ ```bash
24
+ npm install -g @picassio/qmd
25
+ ```
26
+
27
+ Verify: `qmd --version` should print a version number.
28
+
29
+ ## Step 3: Configure search providers
30
+
31
+ Create `~/.config/qmd/index.yml` with your API providers. Choose based on what keys you have:
32
+
33
+ ### Option A: OpenRouter (embedding) + MiniMax CN (chat)
34
+
35
+ ```yaml
36
+ providers:
37
+ embed:
38
+ url: https://openrouter.ai/api/v1
39
+ key: YOUR_OPENROUTER_KEY
40
+ model: openai/text-embedding-3-small
41
+ dims: 768
42
+ chat:
43
+ url: https://api.minimaxi.com/anthropic
44
+ key: YOUR_MINIMAX_CN_KEY
45
+ model: MiniMax-M2.7-highspeed
46
+ api: anthropic
47
+ ```
48
+
49
+ ### Option B: OpenAI only
50
+
51
+ ```yaml
52
+ providers:
53
+ embed:
54
+ url: https://api.openai.com/v1
55
+ key: YOUR_OPENAI_KEY
56
+ model: text-embedding-3-small
57
+ dims: 1536
58
+ chat:
59
+ url: https://api.openai.com/v1
60
+ key: YOUR_OPENAI_KEY
61
+ model: gpt-4o-mini
62
+ ```
63
+
64
+ ### Option C: No providers (BM25 only)
65
+
66
+ Skip this step. Wiki search works with keyword matching. No API keys needed.
67
+
68
+ ## Step 4: Configure daemon LLM (optional)
69
+
70
+ Edit `~/.pi/wiki/config.json` (created after first pi session) and set `daemonModel`:
71
+
72
+ ```json
73
+ {
74
+ "daemonModel": "anthropic/claude-sonnet-4"
75
+ }
76
+ ```
77
+
78
+ If null, the daemon auto-detects from:
79
+ 1. Pi's API keys (ANTHROPIC_API_KEY, OPENAI_API_KEY, etc.)
80
+ 2. qmd chat provider from Step 3
81
+
82
+ ## Step 5: Start the background capture daemon
83
+
84
+ ### Linux (systemd — recommended)
85
+
86
+ Run the setup script from the pi-para install directory:
87
+
88
+ ```bash
89
+ # Find the install path
90
+ PARA_DIR="$(npm root -g)/@picassio/pi-para"
91
+ # Or if installed via pi:
92
+ # PARA_DIR="$HOME/.pi/agent/packages/npm/@picassio/pi-para"
93
+
94
+ cd "$PARA_DIR"
95
+
96
+ # Install tsx if not present
97
+ npm install tsx 2>/dev/null
98
+
99
+ # Create systemd user service
100
+ mkdir -p ~/.config/systemd/user
101
+ NODE_BIN="$(dirname "$(which node)")"
102
+
103
+ cat > ~/.config/systemd/user/pi-para-daemon.service << EOF
104
+ [Unit]
105
+ Description=pi-para knowledge capture daemon
106
+ After=network.target
107
+
108
+ [Service]
109
+ Type=simple
110
+ WorkingDirectory=$PARA_DIR
111
+ ExecStart=$PARA_DIR/node_modules/.bin/tsx src/cli.ts start
112
+ Restart=on-failure
113
+ RestartSec=10
114
+ Environment=HOME=$HOME
115
+ Environment=PATH=$NODE_BIN:$HOME/.local/bin:/usr/local/bin:/usr/bin:/bin
116
+
117
+ [Install]
118
+ WantedBy=default.target
119
+ EOF
120
+
121
+ # Enable, start, and survive SSH logout
122
+ systemctl --user daemon-reload
123
+ systemctl --user enable pi-para-daemon
124
+ systemctl --user start pi-para-daemon
125
+ sudo loginctl enable-linger $USER
126
+ ```
127
+
128
+ Verify: `systemctl --user status pi-para-daemon`
129
+
130
+ ### macOS / Manual
131
+
132
+ ```bash
133
+ cd "$PARA_DIR" && npx tsx src/cli.ts start
134
+ ```
135
+
136
+ Keep the terminal open, or use a process manager like pm2.
137
+
138
+ ## Step 6: Verify everything works
139
+
140
+ In pi, run these commands:
141
+
142
+ 1. `/wiki-settings` — should show config, search engine status, providers, daemon status
143
+ 2. `/wiki` — should show "Pages: 0 total" (empty wiki)
144
+ 3. Say: "save to wiki: this is a test page" — should create a page
145
+ 4. `/wiki` — should show "Pages: 1 total"
146
+ 5. Say: "search the wiki for test" — should find the test page
147
+
148
+ ## Troubleshooting
149
+
150
+ ### Extension not loading
151
+ - Check: `pi list` should show `@picassio/pi-para`
152
+ - Try: `pi -e npm:@picassio/pi-para` for a quick test
153
+
154
+ ### qmd not found
155
+ - Check: `which qmd` and `qmd --version`
156
+ - Install: `npm install -g @picassio/qmd`
157
+
158
+ ### Search not working (no results)
159
+ - BM25 works immediately after `wiki_write`
160
+ - Vector search needs providers configured in `~/.config/qmd/index.yml`
161
+ - Check: `/wiki-settings` shows providers
162
+
163
+ ### Daemon not running
164
+ - Check: `systemctl --user status pi-para-daemon`
165
+ - Logs: `journalctl --user -u pi-para-daemon -n 20`
166
+ - Manual start: `cd <pi-para-dir> && npx tsx src/cli.ts start`
167
+
168
+ ### Vulkan/CMake errors in logs
169
+ - These are from qmd's node-llama-cpp dependency (safe to ignore)
170
+ - They only appear if no API providers configured
171
+ - Fix: configure providers in `~/.config/qmd/index.yml`