pi-para 0.5.2 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (195) hide show
  1. package/ARCHITECTURE.md +160 -0
  2. package/CHANGELOG.md +51 -0
  3. package/CONFIGURATION.md +243 -0
  4. package/README.md +140 -237
  5. package/SETUP.md +196 -112
  6. package/STRUCTURE.md +140 -0
  7. package/package.json +86 -18
  8. package/scripts/build-assets.mjs +29 -0
  9. package/scripts/install.ps1 +55 -0
  10. package/scripts/install.sh +63 -0
  11. package/scripts/smoke-install.mjs +63 -0
  12. package/skills/para/SKILL.md +1 -1
  13. package/skills/setup/SKILL.md +1 -1
  14. package/src/atomic-write.ts +17 -0
  15. package/src/capture.ts +4 -4
  16. package/src/cli-legacy.ts +43 -0
  17. package/src/cli.ts +133 -28
  18. package/src/commands.ts +203 -243
  19. package/src/config.ts +355 -0
  20. package/src/context.ts +29 -14
  21. package/src/credentials.ts +100 -0
  22. package/src/daemon.ts +1 -1
  23. package/src/doctor.ts +209 -0
  24. package/src/gepa/index.ts +1 -1
  25. package/src/index.ts +119 -40
  26. package/src/maintainer.ts +4 -4
  27. package/src/model-resolver.ts +96 -0
  28. package/src/paths.ts +48 -0
  29. package/src/processor.ts +4 -4
  30. package/src/qmd-providers.ts +63 -0
  31. package/src/query.ts +15 -1
  32. package/src/repair.ts +49 -0
  33. package/src/scheduler/controls.ts +125 -0
  34. package/src/scheduler/index.ts +210 -0
  35. package/src/scheduler/leases.ts +98 -0
  36. package/src/scheduler/session-capture.ts +146 -0
  37. package/src/scheduler/state.ts +304 -0
  38. package/src/session-tools.ts +1 -1
  39. package/src/settings.ts +126 -0
  40. package/src/setup.ts +116 -0
  41. package/src/status.ts +115 -0
  42. package/src/store.ts +116 -31
  43. package/src/summarize.ts +72 -16
  44. package/src/templates/prompts.ts +1 -1
  45. package/src/tools.ts +280 -90
  46. package/src/wiki-tool-guidance.ts +84 -0
  47. package/src/wiki.ts +98 -26
  48. package/dist/capture.d.ts +0 -34
  49. package/dist/capture.d.ts.map +0 -1
  50. package/dist/capture.js +0 -461
  51. package/dist/capture.js.map +0 -1
  52. package/dist/cli.d.ts +0 -15
  53. package/dist/cli.d.ts.map +0 -1
  54. package/dist/cli.js +0 -405
  55. package/dist/cli.js.map +0 -1
  56. package/dist/commands.d.ts +0 -15
  57. package/dist/commands.d.ts.map +0 -1
  58. package/dist/commands.js +0 -786
  59. package/dist/commands.js.map +0 -1
  60. package/dist/context.d.ts +0 -61
  61. package/dist/context.d.ts.map +0 -1
  62. package/dist/context.js +0 -289
  63. package/dist/context.js.map +0 -1
  64. package/dist/daemon.d.ts +0 -49
  65. package/dist/daemon.d.ts.map +0 -1
  66. package/dist/daemon.js +0 -226
  67. package/dist/daemon.js.map +0 -1
  68. package/dist/frontmatter.d.ts +0 -59
  69. package/dist/frontmatter.d.ts.map +0 -1
  70. package/dist/frontmatter.js +0 -170
  71. package/dist/frontmatter.js.map +0 -1
  72. package/dist/gepa/dataset.d.ts +0 -36
  73. package/dist/gepa/dataset.d.ts.map +0 -1
  74. package/dist/gepa/dataset.js +0 -148
  75. package/dist/gepa/dataset.js.map +0 -1
  76. package/dist/gepa/evaluator.d.ts +0 -51
  77. package/dist/gepa/evaluator.d.ts.map +0 -1
  78. package/dist/gepa/evaluator.js +0 -317
  79. package/dist/gepa/evaluator.js.map +0 -1
  80. package/dist/gepa/index.d.ts +0 -66
  81. package/dist/gepa/index.d.ts.map +0 -1
  82. package/dist/gepa/index.js +0 -240
  83. package/dist/gepa/index.js.map +0 -1
  84. package/dist/gepa/llm.d.ts +0 -35
  85. package/dist/gepa/llm.d.ts.map +0 -1
  86. package/dist/gepa/llm.js +0 -268
  87. package/dist/gepa/llm.js.map +0 -1
  88. package/dist/gepa/optimized/capture-prompt.txt +0 -65
  89. package/dist/gepa/optimizer.d.ts +0 -29
  90. package/dist/gepa/optimizer.d.ts.map +0 -1
  91. package/dist/gepa/optimizer.js +0 -249
  92. package/dist/gepa/optimizer.js.map +0 -1
  93. package/dist/gepa/targets.d.ts +0 -39
  94. package/dist/gepa/targets.d.ts.map +0 -1
  95. package/dist/gepa/targets.js +0 -326
  96. package/dist/gepa/targets.js.map +0 -1
  97. package/dist/gepa/types.d.ts +0 -168
  98. package/dist/gepa/types.d.ts.map +0 -1
  99. package/dist/gepa/types.js +0 -124
  100. package/dist/gepa/types.js.map +0 -1
  101. package/dist/index.d.ts +0 -21
  102. package/dist/index.d.ts.map +0 -1
  103. package/dist/index.js +0 -294
  104. package/dist/index.js.map +0 -1
  105. package/dist/ingest.d.ts +0 -88
  106. package/dist/ingest.d.ts.map +0 -1
  107. package/dist/ingest.js +0 -105
  108. package/dist/ingest.js.map +0 -1
  109. package/dist/link-discovery.d.ts +0 -40
  110. package/dist/link-discovery.d.ts.map +0 -1
  111. package/dist/link-discovery.js +0 -122
  112. package/dist/link-discovery.js.map +0 -1
  113. package/dist/link-utils.d.ts +0 -30
  114. package/dist/link-utils.d.ts.map +0 -1
  115. package/dist/link-utils.js +0 -145
  116. package/dist/link-utils.js.map +0 -1
  117. package/dist/lint.d.ts +0 -39
  118. package/dist/lint.d.ts.map +0 -1
  119. package/dist/lint.js +0 -827
  120. package/dist/lint.js.map +0 -1
  121. package/dist/maintainer.d.ts +0 -24
  122. package/dist/maintainer.d.ts.map +0 -1
  123. package/dist/maintainer.js +0 -358
  124. package/dist/maintainer.js.map +0 -1
  125. package/dist/processor.d.ts +0 -14
  126. package/dist/processor.d.ts.map +0 -1
  127. package/dist/processor.js +0 -361
  128. package/dist/processor.js.map +0 -1
  129. package/dist/query.d.ts +0 -69
  130. package/dist/query.d.ts.map +0 -1
  131. package/dist/query.js +0 -107
  132. package/dist/query.js.map +0 -1
  133. package/dist/raw.d.ts +0 -57
  134. package/dist/raw.d.ts.map +0 -1
  135. package/dist/raw.js +0 -219
  136. package/dist/raw.js.map +0 -1
  137. package/dist/redact.d.ts +0 -21
  138. package/dist/redact.d.ts.map +0 -1
  139. package/dist/redact.js +0 -143
  140. package/dist/redact.js.map +0 -1
  141. package/dist/scope.d.ts +0 -54
  142. package/dist/scope.d.ts.map +0 -1
  143. package/dist/scope.js +0 -161
  144. package/dist/scope.js.map +0 -1
  145. package/dist/scripts/bulk-link-fix.d.ts +0 -9
  146. package/dist/scripts/bulk-link-fix.d.ts.map +0 -1
  147. package/dist/scripts/bulk-link-fix.js +0 -106
  148. package/dist/scripts/bulk-link-fix.js.map +0 -1
  149. package/dist/session-tools.d.ts +0 -33
  150. package/dist/session-tools.d.ts.map +0 -1
  151. package/dist/session-tools.js +0 -211
  152. package/dist/session-tools.js.map +0 -1
  153. package/dist/state.d.ts +0 -54
  154. package/dist/state.d.ts.map +0 -1
  155. package/dist/state.js +0 -176
  156. package/dist/state.js.map +0 -1
  157. package/dist/store.d.ts +0 -56
  158. package/dist/store.d.ts.map +0 -1
  159. package/dist/store.js +0 -227
  160. package/dist/store.js.map +0 -1
  161. package/dist/summarize.d.ts +0 -56
  162. package/dist/summarize.d.ts.map +0 -1
  163. package/dist/summarize.js +0 -231
  164. package/dist/summarize.js.map +0 -1
  165. package/dist/tag-registry.d.ts +0 -56
  166. package/dist/tag-registry.d.ts.map +0 -1
  167. package/dist/tag-registry.js +0 -146
  168. package/dist/tag-registry.js.map +0 -1
  169. package/dist/templates/prompts.d.ts +0 -63
  170. package/dist/templates/prompts.d.ts.map +0 -1
  171. package/dist/templates/prompts.js +0 -260
  172. package/dist/templates/prompts.js.map +0 -1
  173. package/dist/tools.d.ts +0 -26
  174. package/dist/tools.d.ts.map +0 -1
  175. package/dist/tools.js +0 -1033
  176. package/dist/tools.js.map +0 -1
  177. package/dist/watcher.d.ts +0 -25
  178. package/dist/watcher.d.ts.map +0 -1
  179. package/dist/watcher.js +0 -84
  180. package/dist/watcher.js.map +0 -1
  181. package/dist/webui/client/dist/index.html +0 -1885
  182. package/dist/webui/server.d.ts +0 -31
  183. package/dist/webui/server.d.ts.map +0 -1
  184. package/dist/webui/server.js +0 -566
  185. package/dist/webui/server.js.map +0 -1
  186. package/dist/wiki.d.ts +0 -103
  187. package/dist/wiki.d.ts.map +0 -1
  188. package/dist/wiki.js +0 -428
  189. package/dist/wiki.js.map +0 -1
  190. package/scripts/gepa/__pycache__/dataset.cpython-313.pyc +0 -0
  191. package/scripts/gepa/__pycache__/lm_providers.cpython-313.pyc +0 -0
  192. package/scripts/gepa/__pycache__/metric.cpython-313.pyc +0 -0
  193. package/scripts/gepa/__pycache__/program.cpython-313.pyc +0 -0
  194. package/scripts/gepa/__pycache__/wiki_reader.cpython-313.pyc +0 -0
  195. package/scripts/gepa/uv.lock +0 -2241
package/dist/daemon.js DELETED
@@ -1,226 +0,0 @@
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
@@ -1 +0,0 @@
1
- {"version":3,"file":"daemon.js","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"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"}
@@ -1,59 +0,0 @@
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
@@ -1 +0,0 @@
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"}
@@ -1,170 +0,0 @@
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 { parse as parseYaml, stringify as stringifyYaml } from "yaml";
8
- // -- Schema versioning -------------------------------------------------------
9
- /** Current schema version. Bump when frontmatter/body format changes. */
10
- export const CURRENT_SCHEMA_VERSION = 1;
11
- /**
12
- * Registry of all schema migrations, ordered by `from` version.
13
- * Empty while CURRENT_SCHEMA_VERSION = 1 — add entries when bumping.
14
- */
15
- export const MIGRATIONS = [];
16
- /**
17
- * Apply all applicable migrations to bring a page up to CURRENT_SCHEMA_VERSION.
18
- *
19
- * Chains migrations sequentially: 1→2, 2→3, etc.
20
- * If `schemaVersion` is already >= CURRENT_SCHEMA_VERSION, returns as-is (no downgrade).
21
- * If `schemaVersion` is missing, defaults to 1.
22
- */
23
- export function migrateToLatest(fm, body) {
24
- let version = typeof fm.schemaVersion === "number" ? fm.schemaVersion : 1;
25
- // Don't downgrade pages ahead of current version
26
- if (version >= CURRENT_SCHEMA_VERSION) {
27
- return { fm: { ...fm, schemaVersion: version }, body };
28
- }
29
- let currentFm = { ...fm };
30
- let currentBody = body;
31
- while (version < CURRENT_SCHEMA_VERSION) {
32
- const migration = MIGRATIONS.find((m) => m.from === version);
33
- if (!migration) {
34
- // No migration path — stop at current version
35
- break;
36
- }
37
- const result = migration.migrate(currentFm, currentBody);
38
- currentFm = result.fm;
39
- currentBody = result.body;
40
- version = migration.to;
41
- }
42
- currentFm.schemaVersion = version;
43
- return { fm: currentFm, body: currentBody };
44
- }
45
- const VALID_PARA_CATEGORIES = new Set([
46
- "projects",
47
- "areas",
48
- "resources",
49
- "archives",
50
- ]);
51
- const FRONTMATTER_REGEX = /^---\n([\s\S]*?)\n?---\n?([\s\S]*)$/;
52
- // -- Functions ---------------------------------------------------------------
53
- /**
54
- * Parse YAML frontmatter from markdown content.
55
- *
56
- * Expects content starting with `---\n...\n---`. If no frontmatter block
57
- * is found, returns default frontmatter and the entire content as body.
58
- * If the YAML is malformed, throws with a descriptive error.
59
- */
60
- export function parseFrontmatter(content) {
61
- const match = content.match(FRONTMATTER_REGEX);
62
- if (!match) {
63
- return {
64
- frontmatter: validateFrontmatter({}),
65
- body: content,
66
- };
67
- }
68
- const rawYaml = match[1];
69
- const body = match[2];
70
- let parsed;
71
- try {
72
- parsed = parseYaml(rawYaml);
73
- }
74
- catch (err) {
75
- const msg = err instanceof Error ? err.message : String(err);
76
- throw new Error(`Malformed YAML frontmatter: ${msg}`);
77
- }
78
- if (parsed == null || typeof parsed !== "object") {
79
- return {
80
- frontmatter: validateFrontmatter({}),
81
- body,
82
- };
83
- }
84
- return {
85
- frontmatter: validateFrontmatter(parsed),
86
- body,
87
- };
88
- }
89
- /**
90
- * Serialize frontmatter and body back to a markdown string with YAML
91
- * frontmatter block.
92
- */
93
- export function serializeFrontmatter(frontmatter, body) {
94
- // Always write the current schema version on serialize
95
- const fmWithVersion = { ...frontmatter, schemaVersion: CURRENT_SCHEMA_VERSION };
96
- const yaml = stringifyYaml(fmWithVersion, { lineWidth: 0 }).trimEnd();
97
- return `---\n${yaml}\n---\n${body}`;
98
- }
99
- /**
100
- * Validate and normalize a raw frontmatter object into a PageFrontmatter.
101
- *
102
- * Required field: `title` (defaults to "Untitled" if missing).
103
- * All other fields get sensible defaults. Unknown fields are preserved.
104
- */
105
- export function validateFrontmatter(fm) {
106
- const now = new Date().toISOString();
107
- const title = typeof fm.title === "string" && fm.title.length > 0
108
- ? fm.title
109
- : "Untitled";
110
- const para = validateParaCategory(fm.para);
111
- const scope = toStringArray(fm.scope);
112
- const tags = toStringArray(fm.tags);
113
- const sources = toStringArray(fm.sources);
114
- const links = toStringArray(fm.links);
115
- const created = typeof fm.created === "string" && fm.created.length > 0
116
- ? fm.created
117
- : now;
118
- const updated = typeof fm.updated === "string" && fm.updated.length > 0
119
- ? fm.updated
120
- : now;
121
- const schemaVersion = typeof fm.schemaVersion === "number" ? fm.schemaVersion : 1;
122
- // Build result with known fields first, then spread unknown fields underneath.
123
- // Known fields override any unknown fields with the same name.
124
- const knownKeys = new Set([
125
- "title",
126
- "para",
127
- "scope",
128
- "tags",
129
- "sources",
130
- "created",
131
- "updated",
132
- "links",
133
- "schemaVersion",
134
- ]);
135
- const unknownFields = {};
136
- for (const [key, value] of Object.entries(fm)) {
137
- if (!knownKeys.has(key)) {
138
- unknownFields[key] = value;
139
- }
140
- }
141
- return {
142
- ...unknownFields,
143
- title,
144
- para,
145
- scope,
146
- tags,
147
- sources,
148
- created,
149
- updated,
150
- links,
151
- schemaVersion,
152
- };
153
- }
154
- // -- Helpers -----------------------------------------------------------------
155
- function validateParaCategory(value) {
156
- if (typeof value === "string" && VALID_PARA_CATEGORIES.has(value)) {
157
- return value;
158
- }
159
- return "resources";
160
- }
161
- function toStringArray(value) {
162
- if (Array.isArray(value)) {
163
- return value.filter((v) => typeof v === "string");
164
- }
165
- if (typeof value === "string") {
166
- return [value];
167
- }
168
- return [];
169
- }
170
- //# sourceMappingURL=frontmatter.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"frontmatter.js","sourceRoot":"","sources":["../src/frontmatter.ts"],"names":[],"mappings":"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"}
@@ -1,36 +0,0 @@
1
- /**
2
- * GEPA dataset extraction — builds evaluation context from wiki state and session history.
3
- *
4
- * The evaluation context gives the LLM judge grounding:
5
- * it knows about the wiki's current size, structure, common patterns,
6
- * and recent capture results to judge whether a prompt would work well.
7
- */
8
- /** Summary of the current wiki state for evaluation context. */
9
- export interface WikiContext {
10
- /** Total number of wiki pages. */
11
- totalPages: number;
12
- /** Pages per PARA category. */
13
- categoryCounts: Record<string, number>;
14
- /** Number of unique scopes. */
15
- scopeCount: number;
16
- /** Most common scopes (top 5). */
17
- topScopes: string[];
18
- /** Number of unique tags. */
19
- tagCount: number;
20
- /** Most common tags (top 10). */
21
- topTags: string[];
22
- /** Sample page titles (up to 15). */
23
- sampleTitles: string[];
24
- }
25
- /** Full evaluation context. */
26
- export interface EvalContext {
27
- /** Formatted context string for the LLM judge. */
28
- contextString: string;
29
- /** Raw wiki stats. */
30
- wikiStats: WikiContext;
31
- }
32
- /**
33
- * Build a formatted evaluation context string from wiki state.
34
- */
35
- export declare function buildEvalContext(wikiDir?: string): Promise<EvalContext>;
36
- //# sourceMappingURL=dataset.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"dataset.d.ts","sourceRoot":"","sources":["../../src/gepa/dataset.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AASH,gEAAgE;AAChE,MAAM,WAAW,WAAW;IAC1B,kCAAkC;IAClC,UAAU,EAAE,MAAM,CAAC;IAEnB,+BAA+B;IAC/B,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEvC,+BAA+B;IAC/B,UAAU,EAAE,MAAM,CAAC;IAEnB,kCAAkC;IAClC,SAAS,EAAE,MAAM,EAAE,CAAC;IAEpB,6BAA6B;IAC7B,QAAQ,EAAE,MAAM,CAAC;IAEjB,iCAAiC;IACjC,OAAO,EAAE,MAAM,EAAE,CAAC;IAElB,qCAAqC;IACrC,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,+BAA+B;AAC/B,MAAM,WAAW,WAAW;IAC1B,kDAAkD;IAClD,aAAa,EAAE,MAAM,CAAC;IAEtB,sBAAsB;IACtB,SAAS,EAAE,WAAW,CAAC;CACxB;AAyHD;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CA8B7E"}
@@ -1,148 +0,0 @@
1
- /**
2
- * GEPA dataset extraction — builds evaluation context from wiki state and session history.
3
- *
4
- * The evaluation context gives the LLM judge grounding:
5
- * it knows about the wiki's current size, structure, common patterns,
6
- * and recent capture results to judge whether a prompt would work well.
7
- */
8
- import { readFile, readdir } from "node:fs/promises";
9
- import { join } from "node:path";
10
- import { existsSync } from "node:fs";
11
- import { homedir } from "node:os";
12
- // -- Wiki state extraction ---------------------------------------------------
13
- async function extractWikiStats(wikiDir) {
14
- const categories = ["projects", "areas", "resources", "archives"];
15
- const categoryCounts = {};
16
- const allScopes = [];
17
- const allTags = [];
18
- const sampleTitles = [];
19
- let totalPages = 0;
20
- for (const cat of categories) {
21
- const catDir = join(wikiDir, cat);
22
- if (!existsSync(catDir)) {
23
- categoryCounts[cat] = 0;
24
- continue;
25
- }
26
- try {
27
- const files = await readdir(catDir);
28
- const mdFiles = files.filter((f) => f.endsWith(".md"));
29
- categoryCounts[cat] = mdFiles.length;
30
- totalPages += mdFiles.length;
31
- // Parse frontmatter from each page (lightweight — just YAML header)
32
- for (const file of mdFiles.slice(0, 30)) {
33
- try {
34
- const content = await readFile(join(catDir, file), "utf-8");
35
- const fm = parseFrontmatter(content);
36
- if (fm) {
37
- if (fm.title && sampleTitles.length < 15) {
38
- sampleTitles.push(fm.title);
39
- }
40
- if (fm.scope)
41
- allScopes.push(...fm.scope);
42
- if (fm.tags)
43
- allTags.push(...fm.tags);
44
- }
45
- }
46
- catch {
47
- // Skip unreadable pages
48
- }
49
- }
50
- }
51
- catch {
52
- categoryCounts[cat] = 0;
53
- }
54
- }
55
- const scopeCounts = countOccurrences(allScopes);
56
- const tagCounts = countOccurrences(allTags);
57
- return {
58
- totalPages,
59
- categoryCounts,
60
- scopeCount: Object.keys(scopeCounts).length,
61
- topScopes: topN(scopeCounts, 5),
62
- tagCount: Object.keys(tagCounts).length,
63
- topTags: topN(tagCounts, 10),
64
- sampleTitles,
65
- };
66
- }
67
- /** Minimal frontmatter parser — extract title, scope, tags from YAML header. */
68
- function parseFrontmatter(content) {
69
- const match = content.match(/^---\s*\n([\s\S]*?)\n---/);
70
- if (!match)
71
- return null;
72
- const yaml = match[1];
73
- const result = {};
74
- // Extract title
75
- const titleMatch = yaml.match(/^title:\s*(.+)$/m);
76
- if (titleMatch) {
77
- result.title = titleMatch[1].replace(/^["']|["']$/g, "").trim();
78
- }
79
- // Extract scope (inline array)
80
- const scopeMatch = yaml.match(/^scope:\s*\[([^\]]*)\]/m);
81
- if (scopeMatch) {
82
- result.scope = scopeMatch[1].split(",").map((s) => s.trim().replace(/^["']|["']$/g, "")).filter(Boolean);
83
- }
84
- else {
85
- // Multi-line array format
86
- const scopeSection = yaml.match(/^scope:\s*\n((?:\s+-\s+.+\n?)*)/m);
87
- if (scopeSection) {
88
- result.scope = scopeSection[1].match(/^\s+-\s+(.+)$/gm)?.map((l) => l.replace(/^\s+-\s+/, "").replace(/^["']|["']$/g, "").trim()) ?? [];
89
- }
90
- }
91
- // Extract tags (inline array)
92
- const tagsMatch = yaml.match(/^tags:\s*\[([^\]]*)\]/m);
93
- if (tagsMatch) {
94
- result.tags = tagsMatch[1].split(",").map((s) => s.trim().replace(/^["']|["']$/g, "")).filter(Boolean);
95
- }
96
- else {
97
- const tagsSection = yaml.match(/^tags:\s*\n((?:\s+-\s+.+\n?)*)/m);
98
- if (tagsSection) {
99
- result.tags = tagsSection[1].match(/^\s+-\s+(.+)$/gm)?.map((l) => l.replace(/^\s+-\s+/, "").replace(/^["']|["']$/g, "").trim()) ?? [];
100
- }
101
- }
102
- return result;
103
- }
104
- function countOccurrences(items) {
105
- const counts = {};
106
- for (const item of items) {
107
- counts[item] = (counts[item] ?? 0) + 1;
108
- }
109
- return counts;
110
- }
111
- function topN(counts, n) {
112
- return Object.entries(counts)
113
- .sort((a, b) => b[1] - a[1])
114
- .slice(0, n)
115
- .map(([key]) => key);
116
- }
117
- // -- Context building --------------------------------------------------------
118
- /**
119
- * Build a formatted evaluation context string from wiki state.
120
- */
121
- export async function buildEvalContext(wikiDir) {
122
- const dir = wikiDir ?? join(homedir(), ".pi", "wiki");
123
- const wikiStats = await extractWikiStats(dir);
124
- const lines = [
125
- "## Wiki State Summary",
126
- "",
127
- `Total pages: ${wikiStats.totalPages}`,
128
- `Categories: ${Object.entries(wikiStats.categoryCounts).map(([k, v]) => `${k}=${v}`).join(", ")}`,
129
- `Scopes: ${wikiStats.scopeCount} unique (top: ${wikiStats.topScopes.join(", ") || "none"})`,
130
- `Tags: ${wikiStats.tagCount} unique (top: ${wikiStats.topTags.slice(0, 5).join(", ") || "none"})`,
131
- "",
132
- ];
133
- if (wikiStats.sampleTitles.length > 0) {
134
- lines.push("Sample page titles:");
135
- for (const title of wikiStats.sampleTitles.slice(0, 10)) {
136
- lines.push(` - ${title}`);
137
- }
138
- lines.push("");
139
- }
140
- // Check for recent processing history
141
- const stateDbPath = join(dir, ".daemon.sqlite");
142
- if (existsSync(stateDbPath)) {
143
- lines.push("Daemon: active (session processing enabled)");
144
- }
145
- const contextString = lines.join("\n");
146
- return { contextString, wikiStats };
147
- }
148
- //# sourceMappingURL=dataset.js.map