pi-para 0.6.0 → 0.6.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 (213) hide show
  1. package/ARCHITECTURE.md +0 -9
  2. package/CHANGELOG.md +22 -0
  3. package/CONFIGURATION.md +5 -23
  4. package/README.md +7 -31
  5. package/SETUP.md +5 -3
  6. package/STRUCTURE.md +0 -9
  7. package/dist/atomic-write.d.ts +2 -0
  8. package/dist/atomic-write.d.ts.map +1 -0
  9. package/dist/atomic-write.js +18 -0
  10. package/dist/atomic-write.js.map +1 -0
  11. package/dist/capture.d.ts +34 -0
  12. package/dist/capture.d.ts.map +1 -0
  13. package/dist/capture.js +461 -0
  14. package/dist/capture.js.map +1 -0
  15. package/dist/cli-legacy.d.ts +4 -0
  16. package/dist/cli-legacy.d.ts.map +1 -0
  17. package/dist/cli-legacy.js +41 -0
  18. package/dist/cli-legacy.js.map +1 -0
  19. package/dist/cli.d.ts +8 -0
  20. package/dist/cli.d.ts.map +1 -0
  21. package/dist/cli.js +427 -0
  22. package/dist/cli.js.map +1 -0
  23. package/dist/commands.d.ts +15 -0
  24. package/dist/commands.d.ts.map +1 -0
  25. package/dist/commands.js +791 -0
  26. package/dist/commands.js.map +1 -0
  27. package/dist/config.d.ts +94 -0
  28. package/dist/config.d.ts.map +1 -0
  29. package/dist/config.js +228 -0
  30. package/dist/config.js.map +1 -0
  31. package/dist/context.d.ts +63 -0
  32. package/dist/context.d.ts.map +1 -0
  33. package/dist/context.js +311 -0
  34. package/dist/context.js.map +1 -0
  35. package/dist/credentials.d.ts +27 -0
  36. package/dist/credentials.d.ts.map +1 -0
  37. package/dist/credentials.js +85 -0
  38. package/dist/credentials.js.map +1 -0
  39. package/dist/daemon.d.ts +49 -0
  40. package/dist/daemon.d.ts.map +1 -0
  41. package/dist/daemon.js +226 -0
  42. package/dist/daemon.js.map +1 -0
  43. package/dist/doctor.d.ts +20 -0
  44. package/dist/doctor.d.ts.map +1 -0
  45. package/dist/doctor.js +197 -0
  46. package/dist/doctor.js.map +1 -0
  47. package/dist/frontmatter.d.ts +59 -0
  48. package/dist/frontmatter.d.ts.map +1 -0
  49. package/dist/frontmatter.js +170 -0
  50. package/dist/frontmatter.js.map +1 -0
  51. package/dist/index.d.ts +21 -0
  52. package/dist/index.d.ts.map +1 -0
  53. package/dist/index.js +357 -0
  54. package/dist/index.js.map +1 -0
  55. package/dist/ingest.d.ts +88 -0
  56. package/dist/ingest.d.ts.map +1 -0
  57. package/dist/ingest.js +105 -0
  58. package/dist/ingest.js.map +1 -0
  59. package/dist/link-discovery.d.ts +40 -0
  60. package/dist/link-discovery.d.ts.map +1 -0
  61. package/dist/link-discovery.js +122 -0
  62. package/dist/link-discovery.js.map +1 -0
  63. package/dist/link-utils.d.ts +30 -0
  64. package/dist/link-utils.d.ts.map +1 -0
  65. package/dist/link-utils.js +145 -0
  66. package/dist/link-utils.js.map +1 -0
  67. package/dist/lint.d.ts +39 -0
  68. package/dist/lint.d.ts.map +1 -0
  69. package/dist/lint.js +827 -0
  70. package/dist/lint.js.map +1 -0
  71. package/dist/maintainer.d.ts +24 -0
  72. package/dist/maintainer.d.ts.map +1 -0
  73. package/dist/maintainer.js +358 -0
  74. package/dist/maintainer.js.map +1 -0
  75. package/dist/model-resolver.d.ts +30 -0
  76. package/dist/model-resolver.d.ts.map +1 -0
  77. package/dist/model-resolver.js +71 -0
  78. package/dist/model-resolver.js.map +1 -0
  79. package/dist/paths.d.ts +20 -0
  80. package/dist/paths.d.ts.map +1 -0
  81. package/dist/paths.js +33 -0
  82. package/dist/paths.js.map +1 -0
  83. package/dist/processor.d.ts +14 -0
  84. package/dist/processor.d.ts.map +1 -0
  85. package/dist/processor.js +361 -0
  86. package/dist/processor.js.map +1 -0
  87. package/dist/qmd-providers.d.ts +12 -0
  88. package/dist/qmd-providers.d.ts.map +1 -0
  89. package/dist/qmd-providers.js +45 -0
  90. package/dist/qmd-providers.js.map +1 -0
  91. package/dist/query.d.ts +69 -0
  92. package/dist/query.d.ts.map +1 -0
  93. package/dist/query.js +120 -0
  94. package/dist/query.js.map +1 -0
  95. package/dist/raw.d.ts +57 -0
  96. package/dist/raw.d.ts.map +1 -0
  97. package/dist/raw.js +219 -0
  98. package/dist/raw.js.map +1 -0
  99. package/dist/redact.d.ts +21 -0
  100. package/dist/redact.d.ts.map +1 -0
  101. package/dist/redact.js +143 -0
  102. package/dist/redact.js.map +1 -0
  103. package/dist/repair.d.ts +11 -0
  104. package/dist/repair.d.ts.map +1 -0
  105. package/dist/repair.js +41 -0
  106. package/dist/repair.js.map +1 -0
  107. package/dist/scheduler/controls.d.ts +35 -0
  108. package/dist/scheduler/controls.d.ts.map +1 -0
  109. package/dist/scheduler/controls.js +98 -0
  110. package/dist/scheduler/controls.js.map +1 -0
  111. package/dist/scheduler/index.d.ts +70 -0
  112. package/dist/scheduler/index.d.ts.map +1 -0
  113. package/dist/scheduler/index.js +245 -0
  114. package/dist/scheduler/index.js.map +1 -0
  115. package/dist/scheduler/leases.d.ts +22 -0
  116. package/dist/scheduler/leases.d.ts.map +1 -0
  117. package/dist/scheduler/leases.js +74 -0
  118. package/dist/scheduler/leases.js.map +1 -0
  119. package/dist/scheduler/session-capture.d.ts +33 -0
  120. package/dist/scheduler/session-capture.d.ts.map +1 -0
  121. package/dist/scheduler/session-capture.js +108 -0
  122. package/dist/scheduler/session-capture.js.map +1 -0
  123. package/dist/scheduler/state.d.ts +56 -0
  124. package/dist/scheduler/state.d.ts.map +1 -0
  125. package/dist/scheduler/state.js +210 -0
  126. package/dist/scheduler/state.js.map +1 -0
  127. package/dist/scope.d.ts +54 -0
  128. package/dist/scope.d.ts.map +1 -0
  129. package/dist/scope.js +161 -0
  130. package/dist/scope.js.map +1 -0
  131. package/dist/scripts/bulk-link-fix.d.ts +9 -0
  132. package/dist/scripts/bulk-link-fix.d.ts.map +1 -0
  133. package/dist/scripts/bulk-link-fix.js +106 -0
  134. package/dist/scripts/bulk-link-fix.js.map +1 -0
  135. package/dist/session-tools.d.ts +33 -0
  136. package/dist/session-tools.d.ts.map +1 -0
  137. package/dist/session-tools.js +211 -0
  138. package/dist/session-tools.js.map +1 -0
  139. package/dist/settings.d.ts +37 -0
  140. package/dist/settings.d.ts.map +1 -0
  141. package/dist/settings.js +176 -0
  142. package/dist/settings.js.map +1 -0
  143. package/dist/setup.d.ts +29 -0
  144. package/dist/setup.d.ts.map +1 -0
  145. package/dist/setup.js +90 -0
  146. package/dist/setup.js.map +1 -0
  147. package/dist/state.d.ts +54 -0
  148. package/dist/state.d.ts.map +1 -0
  149. package/dist/state.js +176 -0
  150. package/dist/state.js.map +1 -0
  151. package/dist/status.d.ts +22 -0
  152. package/dist/status.d.ts.map +1 -0
  153. package/dist/status.js +93 -0
  154. package/dist/status.js.map +1 -0
  155. package/dist/store.d.ts +71 -0
  156. package/dist/store.d.ts.map +1 -0
  157. package/dist/store.js +282 -0
  158. package/dist/store.js.map +1 -0
  159. package/dist/summarize.d.ts +60 -0
  160. package/dist/summarize.d.ts.map +1 -0
  161. package/dist/summarize.js +266 -0
  162. package/dist/summarize.js.map +1 -0
  163. package/dist/tag-registry.d.ts +56 -0
  164. package/dist/tag-registry.d.ts.map +1 -0
  165. package/dist/tag-registry.js +146 -0
  166. package/dist/tag-registry.js.map +1 -0
  167. package/dist/templates/prompts.d.ts +51 -0
  168. package/dist/templates/prompts.d.ts.map +1 -0
  169. package/dist/templates/prompts.js +203 -0
  170. package/dist/templates/prompts.js.map +1 -0
  171. package/dist/tools.d.ts +26 -0
  172. package/dist/tools.d.ts.map +1 -0
  173. package/dist/tools.js +1198 -0
  174. package/dist/tools.js.map +1 -0
  175. package/dist/watcher.d.ts +25 -0
  176. package/dist/watcher.d.ts.map +1 -0
  177. package/dist/watcher.js +84 -0
  178. package/dist/watcher.js.map +1 -0
  179. package/dist/webui/client/dist/index.html +1885 -0
  180. package/dist/webui/server.d.ts +31 -0
  181. package/dist/webui/server.d.ts.map +1 -0
  182. package/dist/webui/server.js +566 -0
  183. package/dist/webui/server.js.map +1 -0
  184. package/dist/wiki-tool-guidance.d.ts +6 -0
  185. package/dist/wiki-tool-guidance.d.ts.map +1 -0
  186. package/dist/wiki-tool-guidance.js +70 -0
  187. package/dist/wiki-tool-guidance.js.map +1 -0
  188. package/dist/wiki.d.ts +108 -0
  189. package/dist/wiki.d.ts.map +1 -0
  190. package/dist/wiki.js +497 -0
  191. package/dist/wiki.js.map +1 -0
  192. package/package.json +2 -1
  193. package/scripts/build-assets.mjs +1 -13
  194. package/skills/setup/SKILL.md +1 -1
  195. package/src/cli.ts +0 -70
  196. package/src/commands.ts +78 -3
  197. package/src/config.ts +0 -25
  198. package/src/doctor.ts +21 -1
  199. package/src/index.ts +16 -38
  200. package/src/scheduler/index.ts +64 -0
  201. package/src/settings.ts +88 -0
  202. package/src/setup.ts +1 -1
  203. package/src/templates/prompts.ts +0 -56
  204. package/scripts/gepa/dataset.py +0 -192
  205. package/scripts/gepa/lm_providers.py +0 -472
  206. package/scripts/gepa/metric.py +0 -279
  207. package/scripts/gepa/optimize.py +0 -367
  208. package/scripts/gepa/program.py +0 -99
  209. package/scripts/gepa/pyproject.toml +0 -19
  210. package/scripts/gepa/run-all.sh +0 -53
  211. package/scripts/gepa/wiki_reader.py +0 -113
  212. package/src/gepa/index.ts +0 -287
  213. package/src/gepa/optimized/capture-prompt.txt +0 -65
package/dist/daemon.js ADDED
@@ -0,0 +1,226 @@
1
+ /**
2
+ * Main daemon loop — watches for completed sessions and processes them.
3
+ */
4
+ import { existsSync } from "node:fs";
5
+ import { join } from "node:path";
6
+ import { homedir } from "node:os";
7
+ import { openStore, closeStore } from "./store.js";
8
+ import { StateDB } from "./state.js";
9
+ import { RegistryWatcher } from "./watcher.js";
10
+ import { processSession } from "./processor.js";
11
+ import { runMaintenance } from "./maintainer.js";
12
+ import { startServer } from "./webui/server.js";
13
+ export class Daemon {
14
+ config;
15
+ state;
16
+ watcher;
17
+ store = null;
18
+ queue = [];
19
+ processing = false;
20
+ running = false;
21
+ maintenanceTimer = null;
22
+ maintenanceRunning = false;
23
+ webServer = null;
24
+ constructor(config) {
25
+ this.config = config;
26
+ this.state = new StateDB(config.wikiDir);
27
+ this.watcher = new RegistryWatcher(config.wikiDir, (entries) => this.onNewEntries(entries), config.pollIntervalMs ?? 5000);
28
+ }
29
+ /** Start the daemon. */
30
+ async start() {
31
+ console.log(`[daemon] Starting — wiki: ${this.config.wikiDir}`);
32
+ // Open qmd store
33
+ try {
34
+ this.store = await openStore(this.config.wikiDir);
35
+ console.log("[daemon] qmd store opened");
36
+ }
37
+ catch (err) {
38
+ console.error(`[daemon] Failed to open store: ${err instanceof Error ? err.message : err}`);
39
+ this.store = null;
40
+ }
41
+ this.running = true;
42
+ this.state.setState("daemon_started_at", new Date().toISOString());
43
+ this.state.setState("daemon_pid", String(process.pid));
44
+ // Start watching
45
+ this.watcher.start();
46
+ // Process any unprocessed sessions from registry
47
+ const existing = this.watcher.getAllEntries();
48
+ const unprocessed = existing.filter((e) => !this.state.isProcessed(e.sessionPath));
49
+ if (unprocessed.length > 0) {
50
+ console.log(`[daemon] Found ${unprocessed.length} unprocessed session(s)`);
51
+ this.onNewEntries(unprocessed);
52
+ }
53
+ // Start periodic maintenance (link discovery + lint)
54
+ const maintenanceMs = this.config.maintenanceIntervalMs ?? 30 * 60 * 1000;
55
+ this.maintenanceTimer = setInterval(() => this.runMaintenancePass(), maintenanceMs);
56
+ // Run first maintenance after a delay to let the store warm up
57
+ setTimeout(() => this.runMaintenancePass(), 60_000);
58
+ // Start web wiki server if enabled
59
+ if (this.config.webWiki?.enabled) {
60
+ try {
61
+ this.webServer = startServer(this.config.wikiDir, this.store, this.config.webWiki);
62
+ console.log(`[daemon] Web wiki: ${this.webServer.url}`);
63
+ }
64
+ catch (err) {
65
+ console.error(`[daemon] Web wiki failed: ${err instanceof Error ? err.message : String(err)}`);
66
+ }
67
+ }
68
+ console.log(`[daemon] Running (maintenance every ${Math.round(maintenanceMs / 60000)}m). Press Ctrl+C to stop.`);
69
+ }
70
+ /** Stop the daemon. */
71
+ async stop() {
72
+ console.log("[daemon] Stopping...");
73
+ this.running = false;
74
+ this.watcher.stop();
75
+ if (this.maintenanceTimer) {
76
+ clearInterval(this.maintenanceTimer);
77
+ this.maintenanceTimer = null;
78
+ }
79
+ // Stop web wiki server
80
+ if (this.webServer) {
81
+ try {
82
+ await this.webServer.close();
83
+ console.log("[daemon] Web wiki stopped");
84
+ }
85
+ catch { }
86
+ this.webServer = null;
87
+ }
88
+ if (this.store) {
89
+ try {
90
+ await closeStore(this.store);
91
+ }
92
+ catch { }
93
+ this.store = null;
94
+ }
95
+ this.state.close();
96
+ console.log("[daemon] Stopped.");
97
+ }
98
+ /** Get the web server URL (if running). */
99
+ getWebUrl() {
100
+ return this.webServer?.url ?? null;
101
+ }
102
+ /** Process a single session file (for CLI `process` command). */
103
+ async processOne(sessionPath) {
104
+ if (!existsSync(sessionPath)) {
105
+ console.error(`[daemon] Session file not found: ${sessionPath}`);
106
+ return;
107
+ }
108
+ if (!this.store) {
109
+ try {
110
+ this.store = await openStore(this.config.wikiDir);
111
+ }
112
+ catch (err) {
113
+ console.error(`[daemon] Failed to open store: ${err instanceof Error ? err.message : err}`);
114
+ return;
115
+ }
116
+ }
117
+ const scope = detectScopeFromPath(sessionPath);
118
+ console.log(`[daemon] Processing: ${sessionPath} (scope: ${scope})`);
119
+ try {
120
+ const result = await processSession(sessionPath, this.config.wikiDir, this.store, scope, this.config.model, this.config.getApiKey);
121
+ if (result.skipped) {
122
+ console.log(`[daemon] Skipped: ${result.reason}`);
123
+ this.state.recordSuccess(sessionPath, scope, [], []);
124
+ }
125
+ else {
126
+ console.log(`[daemon] Done: ${result.pagesCreated.length} created, ${result.pagesUpdated.length} updated`);
127
+ this.state.recordSuccess(sessionPath, scope, result.pagesCreated, result.pagesUpdated);
128
+ }
129
+ }
130
+ catch (err) {
131
+ const msg = err instanceof Error ? err.message : String(err);
132
+ console.error(`[daemon] Failed: ${msg}`);
133
+ this.state.recordFailure(sessionPath, scope, msg);
134
+ }
135
+ }
136
+ /** Handle new entries from the registry watcher. */
137
+ onNewEntries(entries) {
138
+ // Filter already-processed
139
+ const newEntries = entries.filter((e) => existsSync(e.sessionPath) && !this.state.isProcessed(e.sessionPath));
140
+ if (newEntries.length === 0)
141
+ return;
142
+ console.log(`[daemon] Queued ${newEntries.length} session(s) for processing`);
143
+ this.queue.push(...newEntries);
144
+ this.processQueue();
145
+ }
146
+ /** Process queued sessions sequentially. */
147
+ async processQueue() {
148
+ if (this.processing || !this.running)
149
+ return;
150
+ this.processing = true;
151
+ while (this.queue.length > 0 && this.running) {
152
+ const entry = this.queue.shift();
153
+ await this.processOne(entry.sessionPath);
154
+ }
155
+ this.processing = false;
156
+ }
157
+ /** Run periodic maintenance via LLM agent. */
158
+ async runMaintenancePass() {
159
+ if (this.maintenanceRunning || !this.running || !this.store)
160
+ return;
161
+ this.maintenanceRunning = true;
162
+ try {
163
+ console.log("[daemon] Running maintenance agent...");
164
+ const result = await runMaintenance(this.config.wikiDir, this.store, this.config.model, this.config.getApiKey);
165
+ console.log(`[daemon] Maintenance done: ${result.pagesUpdated} updated, ${result.pagesMerged} merged`);
166
+ if (result.summary) {
167
+ // Log first 200 chars of summary
168
+ console.log(`[daemon] Summary: ${result.summary.slice(0, 200)}`);
169
+ }
170
+ }
171
+ catch (err) {
172
+ console.error(`[daemon] Maintenance error: ${err instanceof Error ? err.message : String(err)}`);
173
+ }
174
+ this.maintenanceRunning = false;
175
+ }
176
+ /** Get processing history. */
177
+ getHistory(scope, limit) {
178
+ return this.state.getHistory(scope, limit);
179
+ }
180
+ /** Get failed sessions. */
181
+ getFailed() {
182
+ return this.state.getFailed();
183
+ }
184
+ /** Retry all failed sessions. */
185
+ async retryFailed() {
186
+ const failed = this.state.getFailed();
187
+ if (failed.length === 0) {
188
+ console.log("[daemon] No failed sessions to retry.");
189
+ return;
190
+ }
191
+ console.log(`[daemon] Retrying ${failed.length} failed session(s)...`);
192
+ for (const session of failed) {
193
+ await this.processOne(session.sessionPath);
194
+ }
195
+ }
196
+ }
197
+ /** Extract project scope from session path or header. */
198
+ function detectScopeFromPath(sessionPath) {
199
+ // 1. Try reading the session header — most reliable, has the real cwd
200
+ try {
201
+ const { readFileSync } = require("node:fs");
202
+ const firstLine = readFileSync(sessionPath, "utf-8").split("\n")[0];
203
+ const header = JSON.parse(firstLine);
204
+ if (header.cwd) {
205
+ const parts = header.cwd.split("/");
206
+ return parts[parts.length - 1] ?? "unknown";
207
+ }
208
+ }
209
+ catch { }
210
+ // 2. Fallback: decode from directory name
211
+ // Path format: ~/.pi/agent/sessions/--home-ubuntu-projects-pi-mono--/file.jsonl
212
+ // The dir name encodes the cwd path with / replaced by -
213
+ // But project names can contain hyphens, so we can't just replace all - with /
214
+ // Instead, find the last segment after "projects-" which is the project name
215
+ const dirName = sessionPath.split("/").slice(-2, -1)[0] ?? "";
216
+ if (dirName.startsWith("--") && dirName.endsWith("--")) {
217
+ const inner = dirName.slice(2, -2); // e.g. "home-ubuntu-projects-agent-board"
218
+ // Look for "projects-" marker — everything after it is the project name
219
+ const projectsIdx = inner.indexOf("projects-");
220
+ if (projectsIdx >= 0) {
221
+ return inner.slice(projectsIdx + "projects-".length); // "agent-board"
222
+ }
223
+ }
224
+ return "unknown";
225
+ }
226
+ //# sourceMappingURL=daemon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon.js","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ export type DoctorStatus = "ok" | "warn" | "error";
2
+ export interface DoctorCheck {
3
+ name: string;
4
+ status: DoctorStatus;
5
+ message: string;
6
+ fixable?: boolean;
7
+ }
8
+ export interface DoctorOptions {
9
+ homeDir?: string;
10
+ fix?: boolean;
11
+ validateQmd?: boolean;
12
+ testCaptureModel?: boolean;
13
+ }
14
+ export interface DoctorResult {
15
+ ok: boolean;
16
+ checks: DoctorCheck[];
17
+ }
18
+ export declare function runDoctor(options?: DoctorOptions): Promise<DoctorResult>;
19
+ export declare function formatDoctorResult(result: DoctorResult): string;
20
+ //# sourceMappingURL=doctor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../src/doctor.ts"],"names":[],"mappings":"AAWA,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,MAAM,GAAG,OAAO,CAAC;AAEnD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,YAAY,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB;AAED,wBAAsB,SAAS,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,YAAY,CAAC,CAuClF;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAO/D"}
package/dist/doctor.js ADDED
@@ -0,0 +1,197 @@
1
+ import { existsSync, statSync } from "node:fs";
2
+ import { initWiki } from "./wiki.js";
3
+ import { loadParaConfig } from "./config.js";
4
+ import { readSecretStore, resolveCredentialRef } from "./credentials.js";
5
+ import { getParaPaths } from "./paths.js";
6
+ import { openStore, closeStore } from "./store.js";
7
+ import { createPiModelRegistry, getCaptureSelection, resolveSelectedModel } from "./model-resolver.js";
8
+ import { SchedulerStateDB } from "./scheduler/state.js";
9
+ import { ensureGeneratedStateGitignore, fixSecretPermissions, missingGeneratedStateGitignorePatterns } from "./repair.js";
10
+ export async function runDoctor(options = {}) {
11
+ const checks = [];
12
+ const loaded = await loadParaConfig({ homeDir: options.homeDir, migrate: options.fix ?? false });
13
+ const paths = getParaPaths({ homeDir: options.homeDir, wikiDir: loaded.config.wiki.dir });
14
+ checks.push(checkExists("config", paths.userConfigPath, "warn"));
15
+ checks.push(checkExists("pi-settings", paths.piSettingsPath, "warn"));
16
+ if (options.fix)
17
+ await initWiki(paths.wikiDir);
18
+ checks.push(checkExists("wiki-dir", paths.wikiDir, "warn", true));
19
+ const schedulerCheck = checkScheduler(paths.schedulerDbPath);
20
+ checks.push(schedulerCheck);
21
+ if (options.fix) {
22
+ fixSecretPermissions(paths.secretsPath);
23
+ await ensureGeneratedStateGitignore(paths.wikiDir);
24
+ }
25
+ checks.push(await checkSecrets(paths.secretsPath));
26
+ checks.push(await checkGeneratedStateGitignore(paths.wikiDir));
27
+ checks.push(...await checkProviderDiagnostics(loaded.config, paths.secretsPath, options));
28
+ if (options.validateQmd !== false) {
29
+ checks.push(await checkQmd(paths.wikiDir, loaded.config, paths.secretsPath));
30
+ }
31
+ const backlogPath = `${paths.wikiDir}/.completed-sessions`;
32
+ if (existsSync(backlogPath)) {
33
+ checks.push({
34
+ name: "capture-backlog",
35
+ status: "warn",
36
+ message: ".completed-sessions exists; startup catch-up will process queued entries once capture task is enabled",
37
+ });
38
+ }
39
+ else {
40
+ checks.push({ name: "capture-backlog", status: "ok", message: "no completed-session registry found" });
41
+ }
42
+ return { ok: checks.every((check) => check.status !== "error"), checks };
43
+ }
44
+ export function formatDoctorResult(result) {
45
+ const lines = ["pi-para doctor"];
46
+ for (const check of result.checks) {
47
+ const icon = check.status === "ok" ? "✓" : check.status === "warn" ? "⚠" : "✗";
48
+ lines.push(` ${icon} ${check.name}: ${check.message}`);
49
+ }
50
+ return lines.join("\n");
51
+ }
52
+ function checkExists(name, path, missingStatus, fixable = false) {
53
+ return existsSync(path)
54
+ ? { name, status: "ok", message: path }
55
+ : { name, status: missingStatus, message: `${path} not found`, fixable };
56
+ }
57
+ function checkScheduler(dbPath) {
58
+ try {
59
+ const db = new SchedulerStateDB(dbPath);
60
+ const queued = db.list("queued").length;
61
+ db.close();
62
+ return { name: "scheduler", status: "ok", message: `${dbPath} (${queued} queued)` };
63
+ }
64
+ catch (err) {
65
+ return { name: "scheduler", status: "error", message: err instanceof Error ? err.message : String(err) };
66
+ }
67
+ }
68
+ async function checkSecrets(secretsPath) {
69
+ try {
70
+ const store = await readSecretStore(secretsPath);
71
+ if (!existsSync(secretsPath))
72
+ return { name: "secrets", status: "ok", message: "no local pi-para secrets configured" };
73
+ // POSIX mode bits are meaningless on Windows/NTFS — stat reports 666 and
74
+ // chmod is a no-op, so a permissions warning there is a false positive.
75
+ if (process.platform === "win32") {
76
+ return { name: "secrets", status: "ok", message: `${Object.keys(store.secrets).length} local secret(s) (POSIX permission check skipped on Windows)` };
77
+ }
78
+ const mode = statSync(secretsPath).mode & 0o777;
79
+ if (mode & 0o077) {
80
+ return { name: "secrets", status: "warn", message: `${secretsPath} permissions are too open (${mode.toString(8)})`, fixable: true };
81
+ }
82
+ return { name: "secrets", status: "ok", message: `${Object.keys(store.secrets).length} local secret(s), permissions ${mode.toString(8)}` };
83
+ }
84
+ catch (err) {
85
+ return { name: "secrets", status: "error", message: err instanceof Error ? err.message : String(err) };
86
+ }
87
+ }
88
+ async function checkGeneratedStateGitignore(wikiDir) {
89
+ try {
90
+ const missing = missingGeneratedStateGitignorePatterns(wikiDir);
91
+ if (missing.length > 0) {
92
+ return { name: "gitignore", status: "warn", message: `missing generated-state ignores: ${missing.join(", ")}`, fixable: true };
93
+ }
94
+ return { name: "gitignore", status: "ok", message: "generated SQLite/state files are ignored" };
95
+ }
96
+ catch (err) {
97
+ return { name: "gitignore", status: "error", message: err instanceof Error ? err.message : String(err) };
98
+ }
99
+ }
100
+ async function checkProviderDiagnostics(config, secretsPath, options) {
101
+ const checks = [];
102
+ if (config.qmd.providerConfig === "legacy-qmd-compatible") {
103
+ checks.push({ name: "qmd-providers", status: "warn", message: "using legacy QMD provider config compatibility mode" });
104
+ }
105
+ else {
106
+ checks.push({ name: "qmd-providers", status: "ok", message: "using pi-para provider profiles" });
107
+ }
108
+ if (!config.qmd.embedEnabled) {
109
+ checks.push({ name: "qmd-embedding", status: "ok", message: "embedding disabled" });
110
+ }
111
+ else if (config.qmd.embedding) {
112
+ checks.push(await checkCredentialProfile("qmd-embedding", config.qmd.embedding, secretsPath));
113
+ }
114
+ else {
115
+ checks.push({ name: "qmd-embedding", status: "warn", message: "embedding enabled but no pi-para embedding profile is configured" });
116
+ }
117
+ if (config.qmd.rerank) {
118
+ checks.push(await checkCredentialProfile("qmd-rerank", config.qmd.rerank, secretsPath));
119
+ }
120
+ else {
121
+ checks.push({ name: "qmd-rerank", status: "ok", message: "rerank disabled" });
122
+ }
123
+ checks.push(await checkCaptureModel(config, secretsPath, options.testCaptureModel === true));
124
+ return checks;
125
+ }
126
+ async function checkCredentialProfile(name, profile, secretsPath) {
127
+ const label = `${profile.provider}/${profile.model ?? "model not set"}`;
128
+ if (profile.credentialRef === "none") {
129
+ return { name, status: "ok", message: `${label} uses no credential` };
130
+ }
131
+ const resolved = await resolveCredentialRef(profile.credentialRef, { secretsPath });
132
+ if (!resolved.ok) {
133
+ return { name, status: "warn", message: `${label} credential missing: ${resolved.error}` };
134
+ }
135
+ return { name, status: "ok", message: `${label} credential available via ${resolved.source}` };
136
+ }
137
+ async function checkCaptureModel(config, secretsPath, testModel) {
138
+ const selection = getCaptureSelection(config);
139
+ if (!testModel) {
140
+ if (selection === "auto")
141
+ return { name: "capture-model", status: "ok", message: "auto selection; run doctor --test-capture-model to resolve" };
142
+ return checkCredentialProfile("capture-model", selection, secretsPath);
143
+ }
144
+ try {
145
+ const registry = await createPiModelRegistry();
146
+ if (!registry)
147
+ return { name: "capture-model", status: "warn", message: "Pi model registry unavailable" };
148
+ const model = resolveSelectedModel(selection, registry.modelRegistry, { preferredModelSpec: "anthropic/claude-sonnet-4-20250514" });
149
+ if (!model)
150
+ return { name: "capture-model", status: "warn", message: "no capture model resolved" };
151
+ const getKey = selection === "auto"
152
+ ? () => registry.modelRegistry.getApiKeyForProvider(model.provider)
153
+ : () => resolveCredentialRef(selection.credentialRef, { secretsPath, authStorage: registry.authStorage }).then((r) => r.value);
154
+ const key = await getKey();
155
+ return key
156
+ ? { name: "capture-model", status: "ok", message: `${model.provider}/${model.id} credential available` }
157
+ : { name: "capture-model", status: "warn", message: `${model.provider}/${model.id} resolved but credential is missing` };
158
+ }
159
+ catch (err) {
160
+ return { name: "capture-model", status: "warn", message: err instanceof Error ? err.message : String(err) };
161
+ }
162
+ }
163
+ async function checkQmd(wikiDir, config, secretsPath) {
164
+ try {
165
+ const store = await openStore(wikiDir, {
166
+ paraConfig: { ...config, qmd: { ...config.qmd, embedEnabled: false } },
167
+ secretsPath,
168
+ });
169
+ let embedInfo = "";
170
+ let pending = 0;
171
+ let hasVectorIndex = false;
172
+ try {
173
+ const status = await store.getStatus();
174
+ hasVectorIndex = Boolean(status.hasVectorIndex);
175
+ pending = status.needsEmbedding ?? 0;
176
+ const profile = config.qmd.embedding;
177
+ const endpointHost = profile?.baseUrl ? new URL(profile.baseUrl).host : "default";
178
+ const adapter = profile ? `${profile.provider}/${profile.model ?? "model not set"} at ${endpointHost}` : "no embedding profile";
179
+ embedInfo = ` — vector index: ${hasVectorIndex ? "yes" : "no"}, pending embeddings: ${pending}, embed: ${adapter}`;
180
+ }
181
+ catch {
182
+ // status probe is best-effort
183
+ }
184
+ await closeStore(store);
185
+ // Pending embeddings are expected transient state — the background
186
+ // qmd-embed scheduler task drains them while a Pi session is open — so
187
+ // report the numbers without failing the check.
188
+ const note = config.qmd.embedEnabled !== false && !hasVectorIndex && pending > 0
189
+ ? " (background qmd-embed task will process these while a Pi session is open)"
190
+ : "";
191
+ return { name: "qmd-sdk", status: "ok", message: `store opened and updated with pi-para provider profiles${embedInfo}${note}` };
192
+ }
193
+ catch (err) {
194
+ return { name: "qmd-sdk", status: "error", message: err instanceof Error ? err.message : String(err), fixable: false };
195
+ }
196
+ }
197
+ //# sourceMappingURL=doctor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../src/doctor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * YAML frontmatter parsing and serialization for wiki pages.
3
+ *
4
+ * Handles the `---\n...\n---` frontmatter block in markdown files.
5
+ * Uses the `yaml` package for robust parsing. Preserves unknown fields.
6
+ */
7
+ import type { PageFrontmatter } from "./wiki.js";
8
+ /** Current schema version. Bump when frontmatter/body format changes. */
9
+ export declare const CURRENT_SCHEMA_VERSION = 1;
10
+ /** A migration transforms pages from one schema version to the next. */
11
+ export interface Migration {
12
+ from: number;
13
+ to: number;
14
+ migrate: (fm: Record<string, unknown>, body: string) => {
15
+ fm: Record<string, unknown>;
16
+ body: string;
17
+ };
18
+ description: string;
19
+ }
20
+ /**
21
+ * Registry of all schema migrations, ordered by `from` version.
22
+ * Empty while CURRENT_SCHEMA_VERSION = 1 — add entries when bumping.
23
+ */
24
+ export declare const MIGRATIONS: Migration[];
25
+ /**
26
+ * Apply all applicable migrations to bring a page up to CURRENT_SCHEMA_VERSION.
27
+ *
28
+ * Chains migrations sequentially: 1→2, 2→3, etc.
29
+ * If `schemaVersion` is already >= CURRENT_SCHEMA_VERSION, returns as-is (no downgrade).
30
+ * If `schemaVersion` is missing, defaults to 1.
31
+ */
32
+ export declare function migrateToLatest(fm: Record<string, unknown>, body: string): {
33
+ fm: Record<string, unknown>;
34
+ body: string;
35
+ };
36
+ /**
37
+ * Parse YAML frontmatter from markdown content.
38
+ *
39
+ * Expects content starting with `---\n...\n---`. If no frontmatter block
40
+ * is found, returns default frontmatter and the entire content as body.
41
+ * If the YAML is malformed, throws with a descriptive error.
42
+ */
43
+ export declare function parseFrontmatter(content: string): {
44
+ frontmatter: PageFrontmatter;
45
+ body: string;
46
+ };
47
+ /**
48
+ * Serialize frontmatter and body back to a markdown string with YAML
49
+ * frontmatter block.
50
+ */
51
+ export declare function serializeFrontmatter(frontmatter: PageFrontmatter, body: string): string;
52
+ /**
53
+ * Validate and normalize a raw frontmatter object into a PageFrontmatter.
54
+ *
55
+ * Required field: `title` (defaults to "Untitled" if missing).
56
+ * All other fields get sensible defaults. Unknown fields are preserved.
57
+ */
58
+ export declare function validateFrontmatter(fm: Record<string, unknown>): PageFrontmatter;
59
+ //# sourceMappingURL=frontmatter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frontmatter.d.ts","sourceRoot":"","sources":["../src/frontmatter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAgB,MAAM,WAAW,CAAC;AAI/D,yEAAyE;AACzE,eAAO,MAAM,sBAAsB,IAAI,CAAC;AAExC,wEAAwE;AACxE,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,KAAK;QAAE,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACtG,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,eAAO,MAAM,UAAU,EAAE,SAAS,EAAO,CAAC;AAE1C;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC3B,IAAI,EAAE,MAAM,GACX;IAAE,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAyB/C;AAaD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG;IACjD,WAAW,EAAE,eAAe,CAAC;IAC7B,IAAI,EAAE,MAAM,CAAC;CACd,CA+BA;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,eAAe,EAC5B,IAAI,EAAE,MAAM,GACX,MAAM,CAKR;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC1B,eAAe,CAyDjB"}