@zosmaai/pi-llm-wiki 0.11.4 → 0.11.6

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 (62) hide show
  1. package/README.de.md +8 -0
  2. package/README.es.md +8 -0
  3. package/README.fr.md +8 -0
  4. package/README.hi.md +8 -0
  5. package/README.ja.md +8 -0
  6. package/README.ko.md +8 -0
  7. package/README.md +8 -0
  8. package/README.pt.md +8 -0
  9. package/README.ru.md +8 -0
  10. package/README.zh.md +8 -0
  11. package/assets/wiki-dashboard.png +0 -0
  12. package/commands/wiki-ingest.md +1 -0
  13. package/commands/wiki-req.md +1 -0
  14. package/commands/wiki-retro.md +1 -0
  15. package/dist/extensions/llm-wiki/lib/dashboard-command.js +86 -0
  16. package/dist/extensions/llm-wiki/lib/dashboard.js +175 -0
  17. package/dist/extensions/llm-wiki/lib/guardrails.js +30 -1
  18. package/dist/extensions/llm-wiki/lib/host.js +21 -1
  19. package/dist/extensions/llm-wiki/lib/ingest-worker.js +44 -20
  20. package/dist/extensions/llm-wiki/lib/knowledge-document.js +20 -2
  21. package/dist/extensions/llm-wiki/lib/knowledge-links.js +133 -27
  22. package/dist/extensions/llm-wiki/lib/metadata.js +6 -6
  23. package/dist/extensions/llm-wiki/lib/observation.js +22 -3
  24. package/dist/extensions/llm-wiki/lib/retro.js +38 -4
  25. package/dist/extensions/llm-wiki/lib/runtime.js +2 -2
  26. package/dist/extensions/llm-wiki/lib/settings-command.js +377 -0
  27. package/dist/extensions/llm-wiki/lib/task-config.js +100 -1
  28. package/dist/extensions/llm-wiki/lib/tools.js +47 -8
  29. package/dist/mcp/index.js +2 -1
  30. package/dist/mcp/operations.js +21 -2
  31. package/docs/api.md +24 -1
  32. package/docs/commands.md +6 -1
  33. package/docs/configuration.md +11 -0
  34. package/docs/obsidian.md +6 -6
  35. package/docs/superpowers/plans/2026-08-09-qmd-retrieval-phase-1-quality-baseline-and-compatibility.md +1520 -0
  36. package/docs/superpowers/plans/2026-08-27-wikilink-resolver-normalization.md +735 -0
  37. package/docs/superpowers/plans/2026-08-29-wikilink-gate-ensure-page-retro.md +642 -0
  38. package/docs/superpowers/plans/2026-08-29-wikilink-write-validation.md +695 -0
  39. package/docs/superpowers/roadmaps/2026-08-09-qmd-retrieval-roadmap.md +448 -0
  40. package/docs/superpowers/specs/2026-08-08-qmd-retrieval-design.md +806 -0
  41. package/extensions/llm-wiki/index.ts +4 -0
  42. package/extensions/llm-wiki/lib/dashboard-command.ts +106 -0
  43. package/extensions/llm-wiki/lib/dashboard.ts +210 -0
  44. package/extensions/llm-wiki/lib/guardrails.ts +26 -1
  45. package/extensions/llm-wiki/lib/host.ts +21 -1
  46. package/extensions/llm-wiki/lib/ingest-worker.ts +64 -27
  47. package/extensions/llm-wiki/lib/knowledge-document.ts +21 -2
  48. package/extensions/llm-wiki/lib/knowledge-links.ts +208 -35
  49. package/extensions/llm-wiki/lib/metadata.ts +10 -6
  50. package/extensions/llm-wiki/lib/observation.ts +23 -3
  51. package/extensions/llm-wiki/lib/retro.ts +48 -4
  52. package/extensions/llm-wiki/lib/runtime.ts +2 -2
  53. package/extensions/llm-wiki/lib/settings-command.ts +483 -0
  54. package/extensions/llm-wiki/lib/task-config.ts +138 -0
  55. package/extensions/llm-wiki/lib/tools.ts +62 -8
  56. package/mcp/index.ts +12 -1
  57. package/mcp/operations.ts +32 -2
  58. package/package.json +4 -4
  59. package/prompts/wiki-ingest.md +1 -0
  60. package/prompts/wiki-req.md +1 -0
  61. package/prompts/wiki-retro.md +1 -0
  62. package/skills/llm-wiki/SKILL.md +11 -1
package/README.de.md CHANGED
@@ -125,7 +125,9 @@ Das Ergebnis ist ein Wiki, das wächst, während du Quellen erfasst, Fragen stel
125
125
  | `wiki_search` | Search the generated wiki registry |
126
126
  | `wiki_lint` | Deterministic health checks (orphans, gaps, contradictions, auto-fix) |
127
127
  | `wiki_status` | Show counts, source states, and recent activity |
128
+ | `wiki_observe` | Aktuelle Sitzung als zeitgestempelte, durchsuchbare Beobachtung im wiki vermerken |
128
129
  | `wiki_rebuild_meta` | Force a full metadata rebuild (registry, backlinks, index, log) |
130
+ | `wiki_reindex_embeddings` | Semantische Embeddings neuer oder veralteter Seiten aktualisieren (no-op ohne Embedding-Provider) |
129
131
  | `wiki_log_event` | Append a structured event to the wiki activity log |
130
132
  | `wiki_watch` | Print a `crontab` line for automatic wiki updates (daily / weekly / hourly) — does not install it |
131
133
  | `wiki_capture_trajectory` _(opt-in)_ | Capture the completed task's tool-call trajectory (agent working-memory) |
@@ -147,10 +149,16 @@ Das Ergebnis ist ein Wiki, das wächst, während du Quellen erfasst, Fragen stel
147
149
  | `/wiki-status` | Show a concise operational summary |
148
150
  | `/wiki-digest [--period daily\|weekly]` | Generate a digest of recent activity |
149
151
  | `/wiki-retro` | Save atomic insights from completed tasks |
152
+ | `/wiki-model [provider/id | session]` | Modell für Hintergrund-Aufgaben setzen (ohne Argument: interaktiver Auswahlbildschirm) |
150
153
  | `/wiki-req <concept>` | Decompose a concept into atomic, traceable requirement pages |
151
154
  | `/wiki-trajectories <on\|off>` | Enable/disable agent working-memory (opt-in, off by default) |
152
155
  | `/wiki-record <title>` | Capture the completed task's trajectory (requires trajectories enabled) |
153
156
  | `/wiki-skills [query]` | Search distilled skills + past cases (requires trajectories enabled) |
157
+ | `/wiki-settings` | Interaktive Einstellungensoberfläche — alle `llm-wiki`-Einstellungen in Projekt- oder globaler Sicht anzeigen/ändern |
158
+ | `/wiki-dashboard` | Nur lesbare Vault-übersicht — Seiten je Typ, Aktualität, 7-Tage-Aktivität, Ingest-Warteschlange, Seiten ohne Backlinks, Embedding-Abdeckung |
159
+
160
+ <img src="./assets/wiki-dashboard.png" alt="wiki-dashboard: Vault-übersicht" width="100%" />
161
+
154
162
 
155
163
  ---
156
164
 
package/README.es.md CHANGED
@@ -111,7 +111,9 @@ El resultado es un wiki que **se acumula** mientras capturas fuentes, haces preg
111
111
  | `wiki_search` | Busca en el registro generado del wiki |
112
112
  | `wiki_lint` | Comprobaciones de salud deterministas (huérfanos, lagunas, contradicciones, auto-reparación) |
113
113
  | `wiki_status` | Muestra conteos, estados de fuentes y actividad reciente |
114
+ | `wiki_observe` | Registra observaciones de la sesión actual con marca de tiempo y buscables |
114
115
  | `wiki_rebuild_meta` | Fuerza una reconstrucción completa de metadatos (registro, backlinks, índice, registro) |
116
+ | `wiki_reindex_embeddings` | Refresca los embeddings semánticos de páginas nuevas o desactualizadas (no hace nada sin proveedor de embeddings) |
115
117
  | `wiki_log_event` | Adjunta un evento estructurado al registro de actividad del wiki |
116
118
  | `wiki_watch` | Imprime una línea `crontab` para actualizaciones automáticas del wiki (diaria / semanal / horaria) — no la instala |
117
119
  | `wiki_capture_trajectory` _(opcional)_ | Captura la trayectoria de llamadas de herramientas de la tarea completada (memoria de trabajo del agente) |
@@ -133,10 +135,16 @@ El resultado es un wiki que **se acumula** mientras capturas fuentes, haces preg
133
135
  | `/wiki-status` | Muestra un resumen operativo conciso |
134
136
  | `/wiki-digest [--period daily\|weekly]` | Genera un resumen de actividad reciente |
135
137
  | `/wiki-retro` | Guarda ideas atómicas de tareas completadas |
138
+ | `/wiki-model [provider/id | session]` | Fija el modelo de las tareas en segundo plano (sin argumento: selector interactivo) |
136
139
  | `/wiki-req <concept>` | Descompone un concepto en páginas de requisitos atómicas y rastreables |
137
140
  | `/wiki-trajectories <on\|off>` | Activa/desactiva la memoria de trabajo del agente (opcional, desactivada por defecto) |
138
141
  | `/wiki-record <title>` | Captura la trayectoria de la tarea completada (requiere trayectorias activadas) |
139
142
  | `/wiki-skills [query]` | Busca habilidades destiladas + casos pasados (requiere trayectorias activadas) |
143
+ | `/wiki-settings` | Pantalla interactiva de ajustes — ver/cambiar todos los ajustes `llm-wiki` en alcance de proyecto o global |
144
+ | `/wiki-dashboard` | Panel de solo lectura del vault — páginas por tipo, frescura, actividad de 7 días, cola de ingestión, páginas sin backlinks, cobertura de embeddings |
145
+
146
+ <img src="./assets/wiki-dashboard.png" alt="wiki-dashboard: panel del vault" width="100%" />
147
+
140
148
 
141
149
  ---
142
150
 
package/README.fr.md CHANGED
@@ -125,7 +125,9 @@ Le résultat est un wiki qui s'accumule au fur et à mesure que vous capturez de
125
125
  | `wiki_search` | Search the generated wiki registry |
126
126
  | `wiki_lint` | Deterministic health checks (orphans, gaps, contradictions, auto-fix) |
127
127
  | `wiki_status` | Show counts, source states, and recent activity |
128
+ | `wiki_observe` | Enregistre les observations horodatées et recherchables de la session en cours |
128
129
  | `wiki_rebuild_meta` | Force a full metadata rebuild (registry, backlinks, index, log) |
130
+ | `wiki_reindex_embeddings` | Actualise les embeddings sémantiques des pages nouvelles ou obsolètes (no-op sans fournisseur d'embeddings) |
129
131
  | `wiki_log_event` | Append a structured event to the wiki activity log |
130
132
  | `wiki_watch` | Print a `crontab` line for automatic wiki updates (daily / weekly / hourly) — does not install it |
131
133
  | `wiki_capture_trajectory` _(opt-in)_ | Capture the completed task's tool-call trajectory (agent working-memory) |
@@ -147,10 +149,16 @@ Le résultat est un wiki qui s'accumule au fur et à mesure que vous capturez de
147
149
  | `/wiki-status` | Show a concise operational summary |
148
150
  | `/wiki-digest [--period daily\|weekly]` | Generate a digest of recent activity |
149
151
  | `/wiki-retro` | Save atomic insights from completed tasks |
152
+ | `/wiki-model [provider/id | session]` | Définit le modèle des tâches en arrière-plan (sans argument : sélecteur interactif) |
150
153
  | `/wiki-req <concept>` | Decompose a concept into atomic, traceable requirement pages |
151
154
  | `/wiki-trajectories <on\|off>` | Enable/disable agent working-memory (opt-in, off by default) |
152
155
  | `/wiki-record <title>` | Capture the completed task's trajectory (requires trajectories enabled) |
153
156
  | `/wiki-skills [query]` | Search distilled skills + past cases (requires trajectories enabled) |
157
+ | `/wiki-settings` | Écran interactif des réglages — voir/modifier tous les réglages `llm-wiki` en portée projet ou globale |
158
+ | `/wiki-dashboard` | Tableau de bord en lecture seule du vault — pages par type, fraîcheur, activité sur 7 jours, file d'ingestion, pages sans backlinks, couverture d'embeddings |
159
+
160
+ <img src="./assets/wiki-dashboard.png" alt="wiki-dashboard : tableau de bord du vault" width="100%" />
161
+
154
162
 
155
163
  ---
156
164
 
package/README.hi.md CHANGED
@@ -125,7 +125,9 @@ The extension will proactively suggest creating a wiki on your first session. Al
125
125
  | `wiki_search` | Search the generated wiki registry |
126
126
  | `wiki_lint` | Deterministic health checks (orphans, gaps, contradictions, auto-fix) |
127
127
  | `wiki_status` | Show counts, source states, and recent activity |
128
+ | `wiki_observe` | चालू session की timestamped, search-able observations को wiki में दर्ज करें |
128
129
  | `wiki_rebuild_meta` | Force a full metadata rebuild (registry, backlinks, index, log) |
130
+ | `wiki_reindex_embeddings` | नई/पुरानी pages के semantic embeddings को refresh करें (बिना embedding provider के no-op) |
129
131
  | `wiki_log_event` | Append a structured event to the wiki activity log |
130
132
  | `wiki_watch` | Print a `crontab` line for automatic wiki updates (daily / weekly / hourly) — does not install it |
131
133
  | `wiki_capture_trajectory` _(opt-in)_ | Capture the completed task's tool-call trajectory (agent working-memory) |
@@ -147,10 +149,16 @@ The extension will proactively suggest creating a wiki on your first session. Al
147
149
  | `/wiki-status` | Show a concise operational summary |
148
150
  | `/wiki-digest [--period daily\|weekly]` | Generate a digest of recent activity |
149
151
  | `/wiki-retro` | Save atomic insights from completed tasks |
152
+ | `/wiki-model [provider/id | session]` | Background-task model set करें (बिना argument: interactive picker) |
150
153
  | `/wiki-req <concept>` | Decompose a concept into atomic, traceable requirement pages |
151
154
  | `/wiki-trajectories <on\|off>` | Enable/disable agent working-memory (opt-in, off by default) |
152
155
  | `/wiki-record <title>` | Capture the completed task's trajectory (requires trajectories enabled) |
153
156
  | `/wiki-skills [query]` | Search distilled skills + past cases (requires trajectories enabled) |
157
+ | `/wiki-settings` | Interactive settings screen — saare `llm-wiki` settings ko project ya global scope में dekh/change करें |
158
+ | `/wiki-dashboard` | केवल-पठन vault dashboard — पेज count/types, freshness, 7-दिवसीय activity, ingest queue, zero-backlink pages, embedding coverage |
159
+
160
+ <img src="./assets/wiki-dashboard.png" alt="wiki-dashboard: vault dashboard" width="100%" />
161
+
154
162
 
155
163
  ---
156
164
 
package/README.ja.md CHANGED
@@ -125,7 +125,9 @@ The extension will proactively suggest creating a wiki on your first session. Al
125
125
  | `wiki_search` | Search the generated wiki registry |
126
126
  | `wiki_lint` | Deterministic health checks (orphans, gaps, contradictions, auto-fix) |
127
127
  | `wiki_status` | Show counts, source states, and recent activity |
128
+ | `wiki_observe` | 現在のセッションの日時付き・検索可能な観察を wiki に記録する |
128
129
  | `wiki_rebuild_meta` | Force a full metadata rebuild (registry, backlinks, index, log) |
130
+ | `wiki_reindex_embeddings` | 新規または古いページの意味的埋め込みを再計算する(プロバイダ未設定の場合は no-op) |
129
131
  | `wiki_log_event` | Append a structured event to the wiki activity log |
130
132
  | `wiki_watch` | Print a `crontab` line for automatic wiki updates (daily / weekly / hourly) — does not install it |
131
133
  | `wiki_capture_trajectory` _(opt-in)_ | Capture the completed task's tool-call trajectory (agent working-memory) |
@@ -147,10 +149,16 @@ The extension will proactively suggest creating a wiki on your first session. Al
147
149
  | `/wiki-status` | Show a concise operational summary |
148
150
  | `/wiki-digest [--period daily\|weekly]` | Generate a digest of recent activity |
149
151
  | `/wiki-retro` | Save atomic insights from completed tasks |
152
+ | `/wiki-model [provider/id | session]` | バックグラウンドタスクのモデルを設定(引数なしで対話式ピッカー) |
150
153
  | `/wiki-req <concept>` | Decompose a concept into atomic, traceable requirement pages |
151
154
  | `/wiki-trajectories <on\|off>` | Enable/disable agent working-memory (opt-in, off by default) |
152
155
  | `/wiki-record <title>` | Capture the completed task's trajectory (requires trajectories enabled) |
153
156
  | `/wiki-skills [query]` | Search distilled skills + past cases (requires trajectories enabled) |
157
+ | `/wiki-settings` | インタラクティブな設定画面 — `llm-wiki` 設定を project/global スコープで一覧/変更 |
158
+ | `/wiki-dashboard` | 読み取り専用のVaultダッシュボード — ページ数/タイプ、鮮度、7日間のアクティビティ、ingestキュー、バックリンク0ページ、embeddingカバレッジ |
159
+
160
+ <img src="./assets/wiki-dashboard.png" alt="wiki-dashboard: Vaultヘルス画面" width="100%" />
161
+
154
162
 
155
163
  ---
156
164
 
package/README.ko.md CHANGED
@@ -125,7 +125,9 @@ The extension will proactively suggest creating a wiki on your first session. Al
125
125
  | `wiki_search` | Search the generated wiki registry |
126
126
  | `wiki_lint` | Deterministic health checks (orphans, gaps, contradictions, auto-fix) |
127
127
  | `wiki_status` | Show counts, source states, and recent activity |
128
+ | `wiki_observe` | 현재 세션의 시각이 기록된 검색 가능한 관찰을 wiki에 기록 |
128
129
  | `wiki_rebuild_meta` | Force a full metadata rebuild (registry, backlinks, index, log) |
130
+ | `wiki_reindex_embeddings` | 신규/변경된 페이지의 시맨틱 임베딩을 재인덱싱 (임베딩 제공자 미설정 시 no-op) |
129
131
  | `wiki_log_event` | Append a structured event to the wiki activity log |
130
132
  | `wiki_watch` | Print a `crontab` line for automatic wiki updates (daily / weekly / hourly) — does not install it |
131
133
  | `wiki_capture_trajectory` _(opt-in)_ | Capture the completed task's tool-call trajectory (agent working-memory) |
@@ -147,10 +149,16 @@ The extension will proactively suggest creating a wiki on your first session. Al
147
149
  | `/wiki-status` | Show a concise operational summary |
148
150
  | `/wiki-digest [--period daily\|weekly]` | Generate a digest of recent activity |
149
151
  | `/wiki-retro` | Save atomic insights from completed tasks |
152
+ | `/wiki-model [provider/id | session]` | 백그라운드 태스크 모델 설정 (인자 없으면 대화형 선택기) |
150
153
  | `/wiki-req <concept>` | Decompose a concept into atomic, traceable requirement pages |
151
154
  | `/wiki-trajectories <on\|off>` | Enable/disable agent working-memory (opt-in, off by default) |
152
155
  | `/wiki-record <title>` | Capture the completed task's trajectory (requires trajectories enabled) |
153
156
  | `/wiki-skills [query]` | Search distilled skills + past cases (requires trajectories enabled) |
157
+ | `/wiki-settings` | 대화형 설정 화면 — `llm-wiki` 설정을 project/global 스코프로 보기/변경 |
158
+ | `/wiki-dashboard` | 읽기 전용 볼트 대시보드 — 페이지 수/유형, 신선도, 7일 활동, ingest 대기열, 백링크 0 페이지, 임베딩 커버리지 |
159
+
160
+ <img src="./assets/wiki-dashboard.png" alt="wiki-dashboard: 볼트 대시보드" width="100%" />
161
+
154
162
 
155
163
  ---
156
164
 
package/README.md CHANGED
@@ -124,7 +124,9 @@ The result is a wiki that **compounds** as you capture sources, ask questions, a
124
124
  | `wiki_search` | Search the generated wiki registry |
125
125
  | `wiki_lint` | Deterministic health checks (orphans, gaps, contradictions, auto-fix) |
126
126
  | `wiki_status` | Show counts, source states, and recent activity |
127
+ | `wiki_observe` | Record timestamped, searchable observations from the current session (decisions, findings, constraints) — later distilled into pages |
127
128
  | `wiki_rebuild_meta` | Force a full metadata rebuild (registry, backlinks, index, log) |
129
+ | `wiki_reindex_embeddings` | Refresh semantic embeddings for new or stale pages (no-op if no embedding provider is configured) |
128
130
  | `wiki_log_event` | Append a structured event to the wiki activity log |
129
131
  | `wiki_watch` | Print a `crontab` line for automatic wiki updates (daily / weekly / hourly) — does not install it |
130
132
  | `wiki_capture_trajectory` _(opt-in)_ | Capture the completed task's tool-call trajectory (agent working-memory) |
@@ -146,10 +148,16 @@ The result is a wiki that **compounds** as you capture sources, ask questions, a
146
148
  | `/wiki-status` | Show a concise operational summary |
147
149
  | `/wiki-digest [--period daily\|weekly]` | Generate a digest of recent activity |
148
150
  | `/wiki-retro` | Save atomic insights from completed tasks |
151
+ | `/wiki-model [provider/id | session]` | Set the background-task model (interactive picker when run without arguments) |
149
152
  | `/wiki-req <concept>` | Decompose a concept into atomic, traceable requirement pages |
150
153
  | `/wiki-trajectories <on\|off>` | Enable/disable agent working-memory (opt-in, off by default) |
151
154
  | `/wiki-record <title>` | Capture the completed task's trajectory (requires trajectories enabled) |
152
155
  | `/wiki-skills [query]` | Search distilled skills + past cases (requires trajectories enabled) |
156
+ | `/wiki-settings` | Interactive settings screen — view and change all `llm-wiki` settings in project or global scope |
157
+ | `/wiki-dashboard` | Read-only vault dashboard — page counts/types, freshness, 7-day activity, ingest queue, zero-backlink pages, embedding coverage |
158
+
159
+ <img src="./assets/wiki-dashboard.png" alt="wiki-dashboard: read-only vault health screen" width="100%" />
160
+
153
161
 
154
162
  ---
155
163
 
package/README.pt.md CHANGED
@@ -125,7 +125,9 @@ O resultado é um wiki que se acumula conforme você captura fontes, faz pergunt
125
125
  | `wiki_search` | Search the generated wiki registry |
126
126
  | `wiki_lint` | Deterministic health checks (orphans, gaps, contradictions, auto-fix) |
127
127
  | `wiki_status` | Show counts, source states, and recent activity |
128
+ | `wiki_observe` | Registra observações datadas e pesquisáveis da sessão atual no wiki |
128
129
  | `wiki_rebuild_meta` | Force a full metadata rebuild (registry, backlinks, index, log) |
130
+ | `wiki_reindex_embeddings` | Atualiza os embeddings semânticos de páginas novas ou desatualizadas (no-op sem provedor de embeddings) |
129
131
  | `wiki_log_event` | Append a structured event to the wiki activity log |
130
132
  | `wiki_watch` | Print a `crontab` line for automatic wiki updates (daily / weekly / hourly) — does not install it |
131
133
  | `wiki_capture_trajectory` _(opt-in)_ | Capture the completed task's tool-call trajectory (agent working-memory) |
@@ -147,10 +149,16 @@ O resultado é um wiki que se acumula conforme você captura fontes, faz pergunt
147
149
  | `/wiki-status` | Show a concise operational summary |
148
150
  | `/wiki-digest [--period daily\|weekly]` | Generate a digest of recent activity |
149
151
  | `/wiki-retro` | Save atomic insights from completed tasks |
152
+ | `/wiki-model [provider/id | session]` | Define o modelo das tarefas em segundo plano (sem argumento: seletor interativo) |
150
153
  | `/wiki-req <concept>` | Decompose a concept into atomic, traceable requirement pages |
151
154
  | `/wiki-trajectories <on\|off>` | Enable/disable agent working-memory (opt-in, off by default) |
152
155
  | `/wiki-record <title>` | Capture the completed task's trajectory (requires trajectories enabled) |
153
156
  | `/wiki-skills [query]` | Search distilled skills + past cases (requires trajectories enabled) |
157
+ | `/wiki-settings` | Tela interativa de ajustes — ver/mudar todos os ajustes `llm-wiki` em escopo de projeto ou global |
158
+ | `/wiki-dashboard` | Painel somente leitura do vault — páginas por tipo, frescor, atividade de 7 dias, fila de ingestão, páginas sem backlinks, cobertura de embeddings |
159
+
160
+ <img src="./assets/wiki-dashboard.png" alt="wiki-dashboard: painel do vault" width="100%" />
161
+
154
162
 
155
163
  ---
156
164
 
package/README.ru.md CHANGED
@@ -125,7 +125,9 @@ The extension will proactively suggest creating a wiki on your first session. Al
125
125
  | `wiki_search` | Search the generated wiki registry |
126
126
  | `wiki_lint` | Deterministic health checks (orphans, gaps, contradictions, auto-fix) |
127
127
  | `wiki_status` | Show counts, source states, and recent activity |
128
+ | `wiki_observe` | Записывает во wiki атомарные наблюдения текущей сессии с временн…уткой |
128
129
  | `wiki_rebuild_meta` | Force a full metadata rebuild (registry, backlinks, index, log) |
130
+ | `wiki_reindex_embeddings` | Обновляет семантические эмбеддинги новых или устаревших страниц (no-op при отсутствии провайдера эмбеддингов) |
129
131
  | `wiki_log_event` | Append a structured event to the wiki activity log |
130
132
  | `wiki_watch` | Print a `crontab` line for automatic wiki updates (daily / weekly / hourly) — does not install it |
131
133
  | `wiki_capture_trajectory` _(opt-in)_ | Capture the completed task's tool-call trajectory (agent working-memory) |
@@ -147,10 +149,16 @@ The extension will proactively suggest creating a wiki on your first session. Al
147
149
  | `/wiki-status` | Show a concise operational summary |
148
150
  | `/wiki-digest [--period daily\|weekly]` | Generate a digest of recent activity |
149
151
  | `/wiki-retro` | Save atomic insights from completed tasks |
152
+ | `/wiki-model [provider/id | session]` | Задаёт модель для фоновых задач (без аргумента — интерактивный выбор) |
150
153
  | `/wiki-req <concept>` | Decompose a concept into atomic, traceable requirement pages |
151
154
  | `/wiki-trajectories <on\|off>` | Enable/disable agent working-memory (opt-in, off by default) |
152
155
  | `/wiki-record <title>` | Capture the completed task's trajectory (requires trajectories enabled) |
153
156
  | `/wiki-skills [query]` | Search distilled skills + past cases (requires trajectories enabled) |
157
+ | `/wiki-settings` | Интерактивный экран настроек — просмотр/изменение всех настроек `llm-wiki` в проектном или глобальном scope |
158
+ | `/wiki-dashboard` | Только чтение: страницы по типам, свежесть, активность за 7 дней, очередь ingest, страницы без backlinks, покрытие embeddings |
159
+
160
+ <img src="./assets/wiki-dashboard.png" alt="wiki-dashboard: просмотр vault" width="100%" />
161
+
154
162
 
155
163
  ---
156
164
 
package/README.zh.md CHANGED
@@ -111,7 +111,9 @@ pi install npm:@zosmaai/pi-llm-wiki
111
111
  | `wiki_search` | 搜索生成的 wiki 注册表 |
112
112
  | `wiki_lint` | 确定性健康检查(孤儿、缺口、矛盾、自动修复) |
113
113
  | `wiki_status` | 显示计数、来源状态和最近活动 |
114
+ | `wiki_observe` | 记录当前会话的带时间戳、可搜索观察 |
114
115
  | `wiki_rebuild_meta` | 强制完整元数据重建(注册表、反向链接、索引、日志) |
116
+ | `wiki_reindex_embeddings` | 为新增或过期的页面刷新语义嵌入(未配置 embedding 提供方时为空操作) |
115
117
  | `wiki_log_event` | 将结构化事件追加到 wiki 活动日志 |
116
118
  | `wiki_watch` | 打印自动 wiki 更新的 `crontab` 行(每日/每周/每小时)——不安装它 |
117
119
  | `wiki_capture_trajectory` _(可选)_ | 捕获已完成任务的工具调用轨迹(代理工作记忆) |
@@ -133,10 +135,16 @@ pi install npm:@zosmaai/pi-llm-wiki
133
135
  | `/wiki-status` | 显示简洁的操作摘要 |
134
136
  | `/wiki-digest [--period daily\|weekly]` | 生成最近活动的摘要 |
135
137
  | `/wiki-retro` | 保存已完成任务的原子洞察 |
138
+ | `/wiki-model [provider/id | session]` | 设置后台任务模型(无参数时为交互式选择器) |
136
139
  | `/wiki-req <concept>` | 将概念分解为原子、可追踪的需求页面 |
137
140
  | `/wiki-trajectories <on\|off>` | 启用/禁用代理工作记忆(可选,默认关闭) |
138
141
  | `/wiki-record <title>` | 捕获已完成任务的轨迹(需要启用轨迹) |
139
142
  | `/wiki-skills [query]` | 搜索提炼的技能+过去案例(需要启用轨迹) |
143
+ | `/wiki-settings` | 交互式设置屏幕 — 在 project/global 作用域下查看/修改全部 `llm-wiki` 设置 |
144
+ | `/wiki-dashboard` | 只读知识库仪表盘 — 页面数量/类型、新鲜度、7 日活动、入库队列、零反链页面、embedding 覆盖率 |
145
+
146
+ <img src="./assets/wiki-dashboard.png" alt="wiki-dashboard: 知识库仪表盘" width="100%" />
147
+
140
148
 
141
149
  ---
142
150
 
Binary file
@@ -33,4 +33,5 @@ $ARGUMENTS
33
33
  **Rules:**
34
34
  - Never modify files in `raw/` — source packets are immutable after capture.
35
35
  - Never fabricate information — always cite sources with `[[sources/SRC-...]]`.
36
+ - Inside Markdown table cells, write aliased wikilinks as `[[target\|alias]]`, never `[[target|alias]]`.
36
37
  - The extension auto-updates metadata — you do NOT need to manually edit `meta/` files.
@@ -53,3 +53,4 @@ Read the LLM Wiki skill at `.pi/skills/llm-wiki/SKILL.md` first to understand th
53
53
  - Use status values: `draft` → `clarified` → `active` → `implemented` → `deferred` → `rejected`
54
54
  - Use priority values: `p0` (blocking), `p1` (critical), `p2` (important), `p3` (nice-to-have)
55
55
  - Do not create requirements in `raw/` — that layer is for external source artifacts only
56
+ - Inside Markdown table cells, write aliased wikilinks as `[[target\|alias]]`, never `[[target|alias]]`.
@@ -32,3 +32,4 @@ Read the LLM Wiki skill at `.pi/skills/llm-wiki/SKILL.md` first to understand th
32
32
  - One atomic insight per `wiki_retro` call. Use multiple calls for multiple insights.
33
33
  - Don't save obvious things. Save non-obvious patterns, tradeoffs, and design decisions.
34
34
  - Always add `[[wikilinks]]` to connect the new insight with existing wiki knowledge.
35
+ - Inside Markdown table cells, write aliased wikilinks as `[[target\|alias]]`, never `[[target|alias]]`.
@@ -0,0 +1,86 @@
1
+ import { Container, Text, matchesKey } from "@mariozechner/pi-tui";
2
+ import { collectDashboardStats } from "./dashboard.js";
3
+ const TYPE_ORDER = [
4
+ "concept",
5
+ "entity",
6
+ "source",
7
+ "skill",
8
+ "analysis",
9
+ "synthesis",
10
+ "requirement",
11
+ "short",
12
+ "shared",
13
+ ];
14
+ const KIND_ORDER = ["observe", "retro", "synth", "intake"];
15
+ function orderedPairs(counts) {
16
+ const keys = Object.keys(counts);
17
+ const known = TYPE_ORDER.filter((k) => counts[k] !== undefined);
18
+ const rest = keys
19
+ .filter((k) => !TYPE_ORDER.includes(k))
20
+ .sort()
21
+ .slice(0, 3); // cap the tail: the dashboard is a glance, not a census
22
+ const all = [...known, ...rest];
23
+ if (all.length === 0)
24
+ return "—";
25
+ return all.map((k) => `${k} ${counts[k]}`).join(" · ");
26
+ }
27
+ function orderedKinds(counts) {
28
+ const keys = Object.keys(counts);
29
+ const known = KIND_ORDER.filter((k) => counts[k] !== undefined);
30
+ const rest = keys
31
+ .filter((k) => !KIND_ORDER.includes(k))
32
+ .sort()
33
+ .slice(0, 3);
34
+ return [...known, ...rest].map((k) => `${k} ${counts[k]}`).join(" · ");
35
+ }
36
+ function renderStatsLines(s) {
37
+ const emb = s.embEnabled ? `${s.embFiles}/${s.pageCount}` : "—";
38
+ return [
39
+ `Wiki Dashboard · ${s.root}`,
40
+ "",
41
+ `Pages ${s.pageCount} · ${s.sizeKB}KB · ${orderedPairs(s.byType)}`,
42
+ `Fresh last touch ${s.lastTouch || "never"} · stale(>30d) ${s.staleCount}`,
43
+ `Acts 7d ${s.last7dTotal > 0 ? orderedKinds(s.last7dByKind) : "none"} · total ${s.last7dTotal}/${s.totalEvents}`,
44
+ `Queue raw ${s.rawQueue} · emb ${emb}`,
45
+ `Links zero-backlink ${s.zeroBacklinks} · full scan: /wiki-lint`,
46
+ "",
47
+ "Esc to close",
48
+ ];
49
+ }
50
+ /** One-screen read-only TUI; handles Esc and `q`. */
51
+ export class DashboardScreen extends Container {
52
+ doneFn;
53
+ constructor(lines, close) {
54
+ super();
55
+ this.doneFn = close;
56
+ this.addChild(new Text(lines.join("\n"), 1, 1));
57
+ }
58
+ handleInput(data) {
59
+ // ponytail: matchesKey handles every terminal key shape (raw bytes,
60
+ // kitty CSI-u like \u001b[27u for Esc, ctrl combos) — a raw === "\u001b"
61
+ // check only works in terminals without the kitty keyboard protocol,
62
+ // which is exactly where Ghostty users' Esc went nowhere.
63
+ if (matchesKey(data, "escape") || matchesKey(data, "q")) {
64
+ this.doneFn();
65
+ }
66
+ }
67
+ }
68
+ /**
69
+ * Register the /wiki-dashboard command.
70
+ */
71
+ export function registerWikiDashboardCommand(pi, runtime) {
72
+ pi.registerCommand("wiki-dashboard", {
73
+ description: "Show a read-only LLM Wiki dashboard (pages, freshness, activity, queue, links, emb)",
74
+ handler: async (_args, ctx) => {
75
+ runtime.ensureConfig(ctx.cwd);
76
+ if (!ctx.hasUI) {
77
+ ctx.ui.notify("LLM Wiki: /wiki-dashboard requires an interactive UI.", "warning");
78
+ return;
79
+ }
80
+ const stats = await collectDashboardStats(ctx.cwd);
81
+ await ctx.ui.custom((_tui, _theme, _keybindings, close) => {
82
+ return new DashboardScreen(renderStatsLines(stats), close);
83
+ });
84
+ },
85
+ });
86
+ }
@@ -0,0 +1,175 @@
1
+ /**
2
+ * Read-only vault statistics for the /wiki-dashboard screen.
3
+ *
4
+ * Everything is computed from pre-existing on-disk state:
5
+ * - page tree (paths.wiki + skills dir): counts, mtimes, sizes
6
+ * - meta/registry.json: page types (values; keys can carry legacy prefix noise)
7
+ * - meta/backlinks.json: zero-inbound pages
8
+ * - meta/events.jsonl: activity stream (observes/retros/syntheses...)
9
+ * - raw/sources: pending ingest queue
10
+ * - emb/: embedding coverage
11
+ *
12
+ * No writes, no LLM calls, no new files. Pure reader.
13
+ */
14
+ import { readFile, readdir, stat } from "node:fs/promises";
15
+ import { readJson, resolveVaultPaths } from "./utils.js";
16
+ /** Directories excluded from the page walk (infrastructure, not pages). */
17
+ const SKIP_DIRS = new Set([
18
+ "templates",
19
+ "cases",
20
+ "outputs",
21
+ ".discoveries",
22
+ "raw",
23
+ "meta",
24
+ "emb",
25
+ ".git",
26
+ ]);
27
+ async function walkPages(dir, rel, out) {
28
+ try {
29
+ const entries = await readdir(dir, { withFileTypes: true });
30
+ for (const e of entries) {
31
+ const childRel = rel === "" ? e.name : `${rel}/${e.name}`;
32
+ if (e.isDirectory()) {
33
+ if (SKIP_DIRS.has(e.name))
34
+ continue;
35
+ await walkPages(`${dir}/${e.name}`, childRel, out);
36
+ continue;
37
+ }
38
+ if (!e.name.endsWith(".md"))
39
+ continue;
40
+ try {
41
+ const st = await stat(`${dir}/${e.name}`);
42
+ out.push({ rel: childRel, mtime: st.mtimeMs, bytes: st.size });
43
+ }
44
+ catch {
45
+ // unreadable file: skip
46
+ }
47
+ }
48
+ }
49
+ catch {
50
+ // missing dir (empty vault): nothing to walk
51
+ }
52
+ }
53
+ function humanAge(ms) {
54
+ const mins = Math.floor(ms / 60_000);
55
+ if (mins < 1)
56
+ return "now";
57
+ if (mins < 60)
58
+ return `${mins}m`;
59
+ const hrs = Math.floor(mins / 60);
60
+ if (hrs < 48)
61
+ return `${hrs}h`;
62
+ return `${Math.floor(hrs / 24)}d`;
63
+ }
64
+ async function readEvents(metaDir) {
65
+ const byKind = {};
66
+ let recent = 0;
67
+ let total = 0;
68
+ try {
69
+ const raw = await readFile(`${metaDir}/events.jsonl`, "utf-8");
70
+ const cutoff = Date.now() - 7 * 86400_000;
71
+ for (const line of raw.split("\n")) {
72
+ if (!line.trim())
73
+ continue;
74
+ let ev;
75
+ try {
76
+ ev = JSON.parse(line);
77
+ }
78
+ catch {
79
+ continue; // corrupted line: skip, not fatal
80
+ }
81
+ const ts = typeof ev.timestamp === "string" ? Date.parse(ev.timestamp) : Number.NaN;
82
+ const kind = typeof ev.kind === "string" && ev.kind ? ev.kind : "event";
83
+ total += 1;
84
+ if (Number.isFinite(ts) && ts >= cutoff) {
85
+ byKind[kind] = (byKind[kind] ?? 0) + 1;
86
+ recent += 1;
87
+ }
88
+ }
89
+ }
90
+ catch {
91
+ // no events file: zeros
92
+ }
93
+ return { byKind, recent, total };
94
+ }
95
+ /**
96
+ * Collect all dashboard stats for the vault reachable from `cwd`.
97
+ * Reuses the extension's own path resolution (same root the tools see).
98
+ */
99
+ export async function collectDashboardStats(cwd) {
100
+ const paths = resolveVaultPaths(cwd);
101
+ const pages = [];
102
+ await walkPages(paths.wiki, "", pages);
103
+ // skill pages register as type:skill and live under <dotWiki>/skills
104
+ try {
105
+ const st = await stat(`${paths.dotWiki}/skills`);
106
+ if (st.isDirectory()) {
107
+ await walkPages(`${paths.dotWiki}/skills`, "skills", pages);
108
+ }
109
+ }
110
+ catch {
111
+ // no skills dir: fine
112
+ }
113
+ // type map from registry values — keys may carry legacy noise, so normalize
114
+ const registry = readJson(`${paths.meta}/registry.json`, { pages: {} });
115
+ const typeByKey = {};
116
+ for (const [key, val] of Object.entries(registry.pages ?? {})) {
117
+ const norm = key.startsWith('"') ? key.slice(1) : key;
118
+ if (val?.type)
119
+ typeByKey[norm] = val.type;
120
+ }
121
+ const byType = {};
122
+ for (const p of pages) {
123
+ const slug = p.rel.endsWith(".md") ? p.rel.slice(0, -3) : p.rel;
124
+ const type = typeByKey[slug] ?? p.rel.split("/")[0] ?? "other";
125
+ byType[type] = (byType[type] ?? 0) + 1;
126
+ }
127
+ let sizeBytes = 0;
128
+ let latestMtime = 0;
129
+ const staleCutoff = Date.now() - 30 * 86400_000;
130
+ let stale = 0;
131
+ for (const p of pages) {
132
+ sizeBytes += p.bytes;
133
+ if (p.mtime > latestMtime)
134
+ latestMtime = p.mtime;
135
+ if (p.mtime < staleCutoff)
136
+ stale += 1;
137
+ }
138
+ const events = await readEvents(paths.meta);
139
+ let rawQueue = 0;
140
+ try {
141
+ const pkts = await readdir(paths.rawSources, { withFileTypes: true });
142
+ for (const e of pkts) {
143
+ if (e.isDirectory())
144
+ rawQueue += 1; // each subdirectory is one packet
145
+ }
146
+ }
147
+ catch {
148
+ // no raw/sources: empty queue
149
+ }
150
+ const backlinks = readJson(`${paths.meta}/backlinks.json`, {});
151
+ const zeroBacklinks = Object.values(backlinks).filter((v) => (v ?? []).length === 0).length;
152
+ let embFiles = 0;
153
+ try {
154
+ const embEntries = await readdir(`${paths.dotWiki}/emb`);
155
+ embFiles = embEntries.filter((f) => f.endsWith(".bin")).length;
156
+ }
157
+ catch {
158
+ // no emb dir: none
159
+ }
160
+ return {
161
+ root: paths.root,
162
+ pageCount: pages.length,
163
+ byType,
164
+ sizeKB: Math.max(1, Math.round(sizeBytes / 1024)),
165
+ lastTouch: pages.length === 0 ? "" : humanAge(Date.now() - latestMtime),
166
+ staleCount: stale,
167
+ last7dByKind: events.byKind,
168
+ last7dTotal: events.recent,
169
+ totalEvents: events.total,
170
+ rawQueue,
171
+ zeroBacklinks,
172
+ embFiles,
173
+ embEnabled: embFiles > 0,
174
+ };
175
+ }
@@ -65,11 +65,37 @@ function parseMoveDestination(line) {
65
65
  function scanPatchString(input) {
66
66
  const paths = [];
67
67
  let sawHeader = false;
68
+ let sawApplyPatchHeader = false;
69
+ let applyPatchComplete = true;
68
70
  let sectionHasMove = false;
69
71
  let complete = true;
70
72
  const stripped = input.startsWith("\uFEFF") ? input.slice(1) : input;
71
73
  for (const line of stripped.split("\n")) {
72
- const trimmed = line.replace(/\r$/, "").trim();
74
+ const raw = line.replace(/\r$/, "");
75
+ // apply_patch envelope headers (#162): matched on the raw (untrimmed)
76
+ // line so body rows (space/+/- prefixed) that quote the envelope shape
77
+ // are never mistaken for headers.
78
+ const fileOp = /^\*{3}\s+(?:update|add|delete)\s+file:\s*(\S.*)$/i.exec(raw);
79
+ if (fileOp) {
80
+ sawApplyPatchHeader = true;
81
+ const path = normalizeMutationPath(fileOp[1]);
82
+ if (path)
83
+ paths.push(path);
84
+ else
85
+ applyPatchComplete = false;
86
+ continue;
87
+ }
88
+ const moveTo = /^\*{3}\s+move\s+to:\s*(\S.*)$/i.exec(raw);
89
+ if (moveTo) {
90
+ sawApplyPatchHeader = true;
91
+ const destination = normalizeMutationPath(moveTo[1]);
92
+ if (destination)
93
+ paths.push(destination);
94
+ else
95
+ applyPatchComplete = false;
96
+ continue;
97
+ }
98
+ const trimmed = raw.trim();
73
99
  if (trimmed.startsWith("[")) {
74
100
  sawHeader = true;
75
101
  sectionHasMove = false;
@@ -90,6 +116,9 @@ function scanPatchString(input) {
90
116
  sectionHasMove = true;
91
117
  }
92
118
  }
119
+ if (sawApplyPatchHeader) {
120
+ return { paths, complete: applyPatchComplete && paths.length > 0 };
121
+ }
93
122
  return { paths, complete: sawHeader && complete };
94
123
  }
95
124
  function mergeMutationScans(target, source) {
@@ -34,7 +34,7 @@ export function detectHost() {
34
34
  if (segments.includes(".pi"))
35
35
  return "pi";
36
36
  }
37
- if (process.env.OMP_PROFILE !== undefined)
37
+ if (process.env.OMP_PROFILE)
38
38
  return "omp";
39
39
  return "pi";
40
40
  }
@@ -95,3 +95,23 @@ export function resolveProjectSettingsPath(cwd, host = detectHost()) {
95
95
  return join(foreign, "settings.json");
96
96
  return join(native, "settings.json");
97
97
  }
98
+ /**
99
+ * The global (user-level) settings file this extension writes to.
100
+ *
101
+ * Always writes to `settings.json` inside the agent dir — both hosts read it.
102
+ */
103
+ export function resolveGlobalSettingsPath(host = detectHost()) {
104
+ let agentDir = "";
105
+ try {
106
+ agentDir = getAgentDir();
107
+ }
108
+ catch {
109
+ agentDir = "";
110
+ }
111
+ if (!agentDir) {
112
+ // Fallback: ~/.pi/agent/settings.json
113
+ const home = process.env.HOME || "~";
114
+ return join(home, ".pi", "agent", "settings.json");
115
+ }
116
+ return join(agentDir, "settings.json");
117
+ }