pi-para 0.5.2 → 0.5.5

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 (175) hide show
  1. package/ARCHITECTURE.md +160 -0
  2. package/CHANGELOG.md +29 -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/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 +4 -4
  12. package/dist/capture.d.ts.map +1 -1
  13. package/dist/capture.js +1 -1
  14. package/dist/capture.js.map +1 -1
  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 +2 -9
  20. package/dist/cli.d.ts.map +1 -1
  21. package/dist/cli.js +135 -29
  22. package/dist/cli.js.map +1 -1
  23. package/dist/commands.d.ts +3 -3
  24. package/dist/commands.d.ts.map +1 -1
  25. package/dist/commands.js +189 -256
  26. package/dist/commands.js.map +1 -1
  27. package/dist/config.d.ts +104 -0
  28. package/dist/config.d.ts.map +1 -0
  29. package/dist/config.js +242 -0
  30. package/dist/config.js.map +1 -0
  31. package/dist/context.d.ts +4 -2
  32. package/dist/context.d.ts.map +1 -1
  33. package/dist/context.js +29 -7
  34. package/dist/context.js.map +1 -1
  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 +1 -1
  40. package/dist/daemon.d.ts.map +1 -1
  41. package/dist/doctor.d.ts +20 -0
  42. package/dist/doctor.d.ts.map +1 -0
  43. package/dist/doctor.js +171 -0
  44. package/dist/doctor.js.map +1 -0
  45. package/dist/gepa/index.js +1 -1
  46. package/dist/gepa/index.js.map +1 -1
  47. package/dist/index.d.ts +3 -3
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +102 -37
  50. package/dist/index.js.map +1 -1
  51. package/dist/maintainer.d.ts +2 -2
  52. package/dist/maintainer.d.ts.map +1 -1
  53. package/dist/maintainer.js +2 -2
  54. package/dist/maintainer.js.map +1 -1
  55. package/dist/model-resolver.d.ts +30 -0
  56. package/dist/model-resolver.d.ts.map +1 -0
  57. package/dist/model-resolver.js +71 -0
  58. package/dist/model-resolver.js.map +1 -0
  59. package/dist/paths.d.ts +20 -0
  60. package/dist/paths.d.ts.map +1 -0
  61. package/dist/paths.js +33 -0
  62. package/dist/paths.js.map +1 -0
  63. package/dist/processor.d.ts +2 -2
  64. package/dist/processor.d.ts.map +1 -1
  65. package/dist/processor.js +2 -2
  66. package/dist/processor.js.map +1 -1
  67. package/dist/qmd-providers.d.ts +12 -0
  68. package/dist/qmd-providers.d.ts.map +1 -0
  69. package/dist/qmd-providers.js +45 -0
  70. package/dist/qmd-providers.js.map +1 -0
  71. package/dist/query.d.ts +1 -1
  72. package/dist/query.d.ts.map +1 -1
  73. package/dist/query.js +14 -1
  74. package/dist/query.js.map +1 -1
  75. package/dist/repair.d.ts +11 -0
  76. package/dist/repair.d.ts.map +1 -0
  77. package/dist/repair.js +41 -0
  78. package/dist/repair.js.map +1 -0
  79. package/dist/scheduler/controls.d.ts +35 -0
  80. package/dist/scheduler/controls.d.ts.map +1 -0
  81. package/dist/scheduler/controls.js +98 -0
  82. package/dist/scheduler/controls.js.map +1 -0
  83. package/dist/scheduler/index.d.ts +48 -0
  84. package/dist/scheduler/index.d.ts.map +1 -0
  85. package/dist/scheduler/index.js +193 -0
  86. package/dist/scheduler/index.js.map +1 -0
  87. package/dist/scheduler/leases.d.ts +22 -0
  88. package/dist/scheduler/leases.d.ts.map +1 -0
  89. package/dist/scheduler/leases.js +74 -0
  90. package/dist/scheduler/leases.js.map +1 -0
  91. package/dist/scheduler/session-capture.d.ts +33 -0
  92. package/dist/scheduler/session-capture.d.ts.map +1 -0
  93. package/dist/scheduler/session-capture.js +108 -0
  94. package/dist/scheduler/session-capture.js.map +1 -0
  95. package/dist/scheduler/state.d.ts +56 -0
  96. package/dist/scheduler/state.d.ts.map +1 -0
  97. package/dist/scheduler/state.js +210 -0
  98. package/dist/scheduler/state.js.map +1 -0
  99. package/dist/session-tools.d.ts +1 -1
  100. package/dist/session-tools.d.ts.map +1 -1
  101. package/dist/settings.d.ts +19 -0
  102. package/dist/settings.d.ts.map +1 -0
  103. package/dist/settings.js +106 -0
  104. package/dist/settings.js.map +1 -0
  105. package/dist/setup.d.ts +29 -0
  106. package/dist/setup.d.ts.map +1 -0
  107. package/dist/setup.js +90 -0
  108. package/dist/setup.js.map +1 -0
  109. package/dist/status.d.ts +22 -0
  110. package/dist/status.d.ts.map +1 -0
  111. package/dist/status.js +93 -0
  112. package/dist/status.js.map +1 -0
  113. package/dist/store.d.ts +23 -8
  114. package/dist/store.d.ts.map +1 -1
  115. package/dist/store.js +89 -34
  116. package/dist/store.js.map +1 -1
  117. package/dist/summarize.d.ts +6 -2
  118. package/dist/summarize.d.ts.map +1 -1
  119. package/dist/summarize.js +60 -25
  120. package/dist/summarize.js.map +1 -1
  121. package/dist/templates/prompts.d.ts +1 -1
  122. package/dist/templates/prompts.d.ts.map +1 -1
  123. package/dist/templates/prompts.js +1 -1
  124. package/dist/tools.d.ts +5 -5
  125. package/dist/tools.d.ts.map +1 -1
  126. package/dist/tools.js +243 -78
  127. package/dist/tools.js.map +1 -1
  128. package/dist/wiki-tool-guidance.d.ts +6 -0
  129. package/dist/wiki-tool-guidance.d.ts.map +1 -0
  130. package/dist/wiki-tool-guidance.js +70 -0
  131. package/dist/wiki-tool-guidance.js.map +1 -0
  132. package/dist/wiki.d.ts +6 -1
  133. package/dist/wiki.d.ts.map +1 -1
  134. package/dist/wiki.js +88 -19
  135. package/dist/wiki.js.map +1 -1
  136. package/package.json +80 -15
  137. package/scripts/install.ps1 +44 -0
  138. package/scripts/install.sh +62 -0
  139. package/scripts/smoke-install.mjs +61 -0
  140. package/skills/para/SKILL.md +1 -1
  141. package/skills/setup/SKILL.md +1 -1
  142. package/src/atomic-write.ts +17 -0
  143. package/src/capture.ts +4 -4
  144. package/src/cli-legacy.ts +43 -0
  145. package/src/cli.ts +133 -28
  146. package/src/commands.ts +203 -243
  147. package/src/config.ts +355 -0
  148. package/src/context.ts +29 -14
  149. package/src/credentials.ts +100 -0
  150. package/src/daemon.ts +1 -1
  151. package/src/doctor.ts +204 -0
  152. package/src/gepa/index.ts +1 -1
  153. package/src/index.ts +119 -40
  154. package/src/maintainer.ts +4 -4
  155. package/src/model-resolver.ts +96 -0
  156. package/src/paths.ts +48 -0
  157. package/src/processor.ts +4 -4
  158. package/src/qmd-providers.ts +63 -0
  159. package/src/query.ts +15 -1
  160. package/src/repair.ts +49 -0
  161. package/src/scheduler/controls.ts +125 -0
  162. package/src/scheduler/index.ts +210 -0
  163. package/src/scheduler/leases.ts +98 -0
  164. package/src/scheduler/session-capture.ts +146 -0
  165. package/src/scheduler/state.ts +304 -0
  166. package/src/session-tools.ts +1 -1
  167. package/src/settings.ts +126 -0
  168. package/src/setup.ts +116 -0
  169. package/src/status.ts +115 -0
  170. package/src/store.ts +116 -31
  171. package/src/summarize.ts +72 -16
  172. package/src/templates/prompts.ts +1 -1
  173. package/src/tools.ts +280 -90
  174. package/src/wiki-tool-guidance.ts +84 -0
  175. package/src/wiki.ts +98 -26
@@ -0,0 +1,193 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { gitCommit, rebuildIndex } from "../wiki.js";
3
+ import { reindex } from "../store.js";
4
+ import { getParaPaths } from "../paths.js";
5
+ import { acquireLease, releaseLease } from "./leases.js";
6
+ import { SchedulerStateDB } from "./state.js";
7
+ export class WikiScheduler {
8
+ wikiDir;
9
+ holderId;
10
+ state;
11
+ timer = null;
12
+ running = false;
13
+ stopped = false;
14
+ closed = false;
15
+ intervalMs;
16
+ enabled;
17
+ storeProvider;
18
+ markDirty;
19
+ handlers;
20
+ constructor(opts) {
21
+ this.wikiDir = opts.wikiDir;
22
+ this.holderId = `scheduler:${process.pid}:${randomUUID()}`;
23
+ this.state = new SchedulerStateDB(opts.dbPath ?? getParaPaths({ wikiDir: opts.wikiDir }).schedulerDbPath);
24
+ this.intervalMs = opts.intervalMs ?? 15 * 60_000;
25
+ this.enabled = opts.enabled ?? true;
26
+ this.storeProvider = opts.storeProvider ?? (() => null);
27
+ this.markDirty = opts.markDirty ?? (() => { });
28
+ this.handlers = {
29
+ "wiki-maintenance": async () => this.runWikiMaintenance(),
30
+ ...(opts.handlers ?? {}),
31
+ };
32
+ }
33
+ start() {
34
+ if (!this.enabled || this.timer || this.closed)
35
+ return;
36
+ this.stopped = false;
37
+ this.state.requeueRunning();
38
+ void this.tick();
39
+ this.timer = setInterval(() => void this.tick(), this.intervalMs);
40
+ this.timer.unref?.();
41
+ }
42
+ stop() {
43
+ this.stopped = true;
44
+ if (this.timer)
45
+ clearInterval(this.timer);
46
+ this.timer = null;
47
+ if (!this.running)
48
+ this.closeState();
49
+ }
50
+ closeState() {
51
+ if (this.closed)
52
+ return;
53
+ this.closed = true;
54
+ this.state.close();
55
+ }
56
+ enqueue(taskName, payload = {}, opts = {}) {
57
+ if (this.closed)
58
+ throw new Error("Wiki scheduler is stopped.");
59
+ return this.state.enqueue(taskName, payload, opts);
60
+ }
61
+ registerHandlers(handlers) {
62
+ this.handlers = { ...this.handlers, ...handlers };
63
+ }
64
+ async tick() {
65
+ if (!this.enabled || this.running || this.stopped || this.closed)
66
+ return 0;
67
+ this.running = true;
68
+ let processed = 0;
69
+ try {
70
+ for (;;) {
71
+ if (this.stopped)
72
+ break;
73
+ const item = this.state.claimNext();
74
+ if (!item)
75
+ break;
76
+ await this.runItem(item);
77
+ processed++;
78
+ }
79
+ }
80
+ finally {
81
+ this.running = false;
82
+ if (this.stopped)
83
+ this.closeState();
84
+ }
85
+ return processed;
86
+ }
87
+ async runItem(item) {
88
+ const handler = this.handlers[item.taskName];
89
+ const started = new Date();
90
+ if (!handler) {
91
+ this.state.fail(item.id, `Unknown scheduler task: ${item.taskName}`, { now: started, maxAttempts: 1 });
92
+ return;
93
+ }
94
+ try {
95
+ await handler(item, this);
96
+ if (this.stopped || this.closed)
97
+ return;
98
+ const finished = new Date();
99
+ this.state.complete(item.id, finished);
100
+ this.state.recordHistory(item.taskName, item.payload, "done", started, finished, finished.getTime() - started.getTime(), null);
101
+ }
102
+ catch (err) {
103
+ if (this.stopped || this.closed)
104
+ return;
105
+ const retryAt = new Date(Date.now() + Math.min(60_000, 1_000 * 2 ** item.attempts));
106
+ this.state.fail(item.id, err instanceof Error ? err.message : String(err), { retryAt, now: new Date() });
107
+ }
108
+ }
109
+ async runWikiMaintenance() {
110
+ const leaseKey = `wiki-maintenance:${this.wikiDir}`;
111
+ if (!acquireLease(this.state.db, leaseKey, this.holderId, { ttlMs: 5 * 60_000 }))
112
+ return;
113
+ try {
114
+ await rebuildIndex(this.wikiDir);
115
+ const store = this.storeProvider();
116
+ if (store)
117
+ await reindex(store);
118
+ this.markDirty();
119
+ await gitCommit(this.wikiDir, "wiki: rebuild index and refresh search");
120
+ }
121
+ finally {
122
+ releaseLease(this.state.db, leaseKey, this.holderId);
123
+ }
124
+ }
125
+ }
126
+ const schedulers = new Map();
127
+ const debounceTimers = new Map();
128
+ export function getWikiScheduler(opts) {
129
+ const key = opts.dbPath ?? getParaPaths({ wikiDir: opts.wikiDir }).schedulerDbPath;
130
+ const existing = schedulers.get(key);
131
+ if (existing) {
132
+ if (opts.handlers)
133
+ existing.registerHandlers(opts.handlers);
134
+ return existing;
135
+ }
136
+ const scheduler = new WikiScheduler(opts);
137
+ schedulers.set(key, scheduler);
138
+ return scheduler;
139
+ }
140
+ export function startWikiScheduler(opts) {
141
+ const scheduler = getWikiScheduler(opts);
142
+ scheduler.start();
143
+ return scheduler;
144
+ }
145
+ export function stopWikiScheduler(wikiDir, dbPath) {
146
+ const key = dbPath ?? getParaPaths({ wikiDir }).schedulerDbPath;
147
+ const timer = debounceTimers.get(key);
148
+ if (timer) {
149
+ clearTimeout(timer);
150
+ debounceTimers.delete(key);
151
+ }
152
+ const scheduler = schedulers.get(key);
153
+ if (!scheduler)
154
+ return;
155
+ scheduler.stop();
156
+ schedulers.delete(key);
157
+ }
158
+ export function enqueueWikiMaintenance(wikiDir, store, markDirty, opts = {}) {
159
+ const key = opts.dbPath ?? getParaPaths({ wikiDir }).schedulerDbPath;
160
+ const existingTimer = debounceTimers.get(key);
161
+ if (existingTimer)
162
+ clearTimeout(existingTimer);
163
+ const scheduler = getWikiScheduler({
164
+ wikiDir,
165
+ dbPath: opts.dbPath,
166
+ storeProvider: () => store,
167
+ markDirty,
168
+ });
169
+ const delayMs = opts.delayMs ?? 2_000;
170
+ if (delayMs <= 0) {
171
+ const id = scheduler.enqueue("wiki-maintenance", {}, { dedupeKey: "wiki-maintenance", priority: 10 });
172
+ void scheduler.tick();
173
+ return id;
174
+ }
175
+ const timer = setTimeout(() => {
176
+ debounceTimers.delete(key);
177
+ scheduler.enqueue("wiki-maintenance", {}, { dedupeKey: "wiki-maintenance", priority: 10 });
178
+ void scheduler.tick();
179
+ }, delayMs);
180
+ timer.unref?.();
181
+ debounceTimers.set(key, timer);
182
+ return null;
183
+ }
184
+ export function resetSchedulersForTests() {
185
+ for (const timer of debounceTimers.values())
186
+ clearTimeout(timer);
187
+ debounceTimers.clear();
188
+ for (const [key, scheduler] of schedulers) {
189
+ scheduler.stop();
190
+ schedulers.delete(key);
191
+ }
192
+ }
193
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/scheduler/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import Database from "better-sqlite3";
2
+ export interface LeaseRecord {
3
+ leaseKey: string;
4
+ holderId: string;
5
+ expiresAt: string;
6
+ heartbeatAt: string;
7
+ metadataJson: string | null;
8
+ }
9
+ export declare function ensureLeaseSchema(db: Database.Database): void;
10
+ export declare function createLeaseHolder(prefix?: string): string;
11
+ export declare function acquireLease(db: Database.Database, leaseKey: string, holderId: string, opts?: {
12
+ ttlMs?: number;
13
+ now?: Date;
14
+ metadata?: unknown;
15
+ }): boolean;
16
+ export declare function renewLease(db: Database.Database, leaseKey: string, holderId: string, opts?: {
17
+ ttlMs?: number;
18
+ now?: Date;
19
+ }): boolean;
20
+ export declare function releaseLease(db: Database.Database, leaseKey: string, holderId: string): boolean;
21
+ export declare function getLease(db: Database.Database, leaseKey: string): LeaseRecord | null;
22
+ //# sourceMappingURL=leases.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"leases.d.ts","sourceRoot":"","sources":["../../src/scheduler/leases.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAGtC,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,IAAI,CAU7D;AAED,wBAAgB,iBAAiB,CAAC,MAAM,SAAY,GAAG,MAAM,CAE5D;AAED,wBAAgB,YAAY,CAC1B,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAO,GAC5D,OAAO,CAgCT;AAED,wBAAgB,UAAU,CACxB,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,IAAI,CAAA;CAAO,GACxC,OAAO,CAUT;AAED,wBAAgB,YAAY,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAI/F;AAED,wBAAgB,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAQpF"}
@@ -0,0 +1,74 @@
1
+ import Database from "better-sqlite3";
2
+ import { randomUUID } from "node:crypto";
3
+ export function ensureLeaseSchema(db) {
4
+ db.exec(`
5
+ CREATE TABLE IF NOT EXISTS scheduler_leases (
6
+ lease_key TEXT PRIMARY KEY,
7
+ holder_id TEXT NOT NULL,
8
+ expires_at TEXT NOT NULL,
9
+ heartbeat_at TEXT NOT NULL,
10
+ metadata_json TEXT
11
+ );
12
+ `);
13
+ }
14
+ export function createLeaseHolder(prefix = "pi-para") {
15
+ return `${prefix}:${process.pid}:${randomUUID()}`;
16
+ }
17
+ export function acquireLease(db, leaseKey, holderId, opts = {}) {
18
+ ensureLeaseSchema(db);
19
+ const now = opts.now ?? new Date();
20
+ const ttlMs = opts.ttlMs ?? 2 * 60_000;
21
+ const expiresAt = new Date(now.getTime() + ttlMs).toISOString();
22
+ const nowIso = now.toISOString();
23
+ const metadataJson = opts.metadata === undefined ? null : JSON.stringify(opts.metadata);
24
+ db.exec("BEGIN IMMEDIATE");
25
+ try {
26
+ const current = db.prepare("SELECT holder_id, expires_at FROM scheduler_leases WHERE lease_key = ?").get(leaseKey);
27
+ const expired = !current || Date.parse(current.expires_at) <= now.getTime();
28
+ const sameHolder = current?.holder_id === holderId;
29
+ if (!expired && !sameHolder) {
30
+ db.exec("ROLLBACK");
31
+ return false;
32
+ }
33
+ db.prepare(`
34
+ INSERT OR REPLACE INTO scheduler_leases
35
+ (lease_key, holder_id, expires_at, heartbeat_at, metadata_json)
36
+ VALUES (?, ?, ?, ?, ?)
37
+ `).run(leaseKey, holderId, expiresAt, nowIso, metadataJson);
38
+ db.exec("COMMIT");
39
+ return true;
40
+ }
41
+ catch (err) {
42
+ try {
43
+ db.exec("ROLLBACK");
44
+ }
45
+ catch { }
46
+ throw err;
47
+ }
48
+ }
49
+ export function renewLease(db, leaseKey, holderId, opts = {}) {
50
+ ensureLeaseSchema(db);
51
+ const now = opts.now ?? new Date();
52
+ const expiresAt = new Date(now.getTime() + (opts.ttlMs ?? 2 * 60_000)).toISOString();
53
+ const result = db.prepare(`
54
+ UPDATE scheduler_leases
55
+ SET expires_at = ?, heartbeat_at = ?
56
+ WHERE lease_key = ? AND holder_id = ?
57
+ `).run(expiresAt, now.toISOString(), leaseKey, holderId);
58
+ return result.changes === 1;
59
+ }
60
+ export function releaseLease(db, leaseKey, holderId) {
61
+ ensureLeaseSchema(db);
62
+ const result = db.prepare("DELETE FROM scheduler_leases WHERE lease_key = ? AND holder_id = ?").run(leaseKey, holderId);
63
+ return result.changes === 1;
64
+ }
65
+ export function getLease(db, leaseKey) {
66
+ ensureLeaseSchema(db);
67
+ const row = db.prepare(`
68
+ SELECT lease_key as leaseKey, holder_id as holderId, expires_at as expiresAt,
69
+ heartbeat_at as heartbeatAt, metadata_json as metadataJson
70
+ FROM scheduler_leases WHERE lease_key = ?
71
+ `).get(leaseKey);
72
+ return row ?? null;
73
+ }
74
+ //# sourceMappingURL=leases.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"leases.js","sourceRoot":"","sources":["../../src/scheduler/leases.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ import type { Model } from "@earendil-works/pi-ai";
2
+ import type { QMDStore } from "qmd-engine";
3
+ import { StateDB } from "../state.js";
4
+ import { type ProcessResult } from "../processor.js";
5
+ import type { WikiScheduler, SchedulerTaskHandler } from "./index.js";
6
+ export interface CompletedSessionEntry {
7
+ timestamp: string;
8
+ sessionPath: string;
9
+ }
10
+ export interface CaptureSessionPayload {
11
+ sessionPath: string;
12
+ scope?: string;
13
+ }
14
+ export interface CaptureSessionDeps {
15
+ wikiDir: string;
16
+ storeProvider: () => QMDStore | null;
17
+ model?: Model<any>;
18
+ getApiKey?: (provider: string) => Promise<string | undefined>;
19
+ stateDb?: StateDB;
20
+ processor?: (sessionPath: string, wikiDir: string, store: QMDStore, scope: string, model: Model<any>, getApiKey: (provider: string) => Promise<string | undefined>) => Promise<ProcessResult>;
21
+ }
22
+ export declare function parseCompletedSessionLine(line: string): CompletedSessionEntry | null;
23
+ export declare function readCompletedSessionRegistry(wikiDir: string): Promise<CompletedSessionEntry[]>;
24
+ export declare function appendCompletedSession(wikiDir: string, sessionPath: string, timestamp?: string): Promise<CompletedSessionEntry>;
25
+ export declare function enqueueCompletedSessionsFromRegistry(scheduler: WikiScheduler, wikiDir: string, opts?: {
26
+ stateDb?: StateDB;
27
+ }): Promise<number[]>;
28
+ export declare function enqueueCompletedSessions(scheduler: WikiScheduler, entries: CompletedSessionEntry[], opts?: {
29
+ stateDb?: StateDB;
30
+ }): number[];
31
+ export declare function createCaptureSessionHandler(deps: CaptureSessionDeps): SchedulerTaskHandler;
32
+ export declare function detectScopeFromSessionPath(sessionPath: string): string;
33
+ //# sourceMappingURL=session-capture.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-capture.d.ts","sourceRoot":"","sources":["../../src/scheduler/session-capture.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EAAkB,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErE,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEtE,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,QAAQ,GAAG,IAAI,CAAC;IACrC,KAAK,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,SAAS,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAC9D,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,CACV,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,QAAQ,EACf,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EACjB,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,KACzD,OAAO,CAAC,aAAa,CAAC,CAAC;CAC7B;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,qBAAqB,GAAG,IAAI,CAMpF;AAED,wBAAsB,4BAA4B,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,EAAE,CAAC,CAQpG;AAED,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EACnB,SAAS,SAA2B,GACnC,OAAO,CAAC,qBAAqB,CAAC,CAIhC;AAED,wBAAsB,oCAAoC,CACxD,SAAS,EAAE,aAAa,EACxB,OAAO,EAAE,MAAM,EACf,IAAI,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAO,GAC/B,OAAO,CAAC,MAAM,EAAE,CAAC,CAGnB;AAED,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,aAAa,EACxB,OAAO,EAAE,qBAAqB,EAAE,EAChC,IAAI,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAO,GAC/B,MAAM,EAAE,CAYV;AAED,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,kBAAkB,GAAG,oBAAoB,CA+B1F;AAED,wBAAgB,0BAA0B,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAgBtE"}
@@ -0,0 +1,108 @@
1
+ import { appendFile, readFile } from "node:fs/promises";
2
+ import { existsSync, readFileSync } from "node:fs";
3
+ import { basename, dirname, join } from "node:path";
4
+ import { StateDB } from "../state.js";
5
+ import { processSession } from "../processor.js";
6
+ export function parseCompletedSessionLine(line) {
7
+ const trimmed = line.trim();
8
+ if (!trimmed)
9
+ return null;
10
+ const parts = trimmed.split("|", 2);
11
+ if (parts.length !== 2 || !parts[0] || !parts[1])
12
+ return null;
13
+ return { timestamp: parts[0], sessionPath: parts[1] };
14
+ }
15
+ export async function readCompletedSessionRegistry(wikiDir) {
16
+ const registryPath = join(wikiDir, ".completed-sessions");
17
+ if (!existsSync(registryPath))
18
+ return [];
19
+ const content = await readFile(registryPath, "utf-8");
20
+ return content
21
+ .split(/\r?\n/)
22
+ .map(parseCompletedSessionLine)
23
+ .filter((entry) => entry !== null);
24
+ }
25
+ export async function appendCompletedSession(wikiDir, sessionPath, timestamp = new Date().toISOString()) {
26
+ const registryPath = join(wikiDir, ".completed-sessions");
27
+ await appendFile(registryPath, `${timestamp}|${sessionPath}\n`, "utf-8");
28
+ return { timestamp, sessionPath };
29
+ }
30
+ export async function enqueueCompletedSessionsFromRegistry(scheduler, wikiDir, opts = {}) {
31
+ const entries = await readCompletedSessionRegistry(wikiDir);
32
+ return enqueueCompletedSessions(scheduler, entries, opts);
33
+ }
34
+ export function enqueueCompletedSessions(scheduler, entries, opts = {}) {
35
+ const ids = [];
36
+ for (const entry of entries) {
37
+ if (!existsSync(entry.sessionPath))
38
+ continue;
39
+ if (opts.stateDb?.isProcessed(entry.sessionPath))
40
+ continue;
41
+ ids.push(scheduler.enqueue("capture-session", { sessionPath: entry.sessionPath, scope: detectScopeFromSessionPath(entry.sessionPath) }, { dedupeKey: `capture-session:${entry.sessionPath}`, priority: 20 }));
42
+ }
43
+ return ids;
44
+ }
45
+ export function createCaptureSessionHandler(deps) {
46
+ return async (item) => {
47
+ const payload = item.payload;
48
+ if (!payload.sessionPath)
49
+ throw new Error("capture-session payload missing sessionPath");
50
+ if (!existsSync(payload.sessionPath))
51
+ throw new Error(`Session file not found: ${payload.sessionPath}`);
52
+ const store = deps.storeProvider();
53
+ if (!store)
54
+ throw new Error("QMD store unavailable for capture-session");
55
+ if (!deps.model)
56
+ throw new Error("Capture model unavailable for capture-session");
57
+ if (!deps.getApiKey)
58
+ throw new Error("API key resolver unavailable for capture-session");
59
+ const stateDb = deps.stateDb ?? new StateDB(deps.wikiDir);
60
+ const ownsState = !deps.stateDb;
61
+ const scope = payload.scope ?? detectScopeFromSessionPath(payload.sessionPath);
62
+ try {
63
+ if (stateDb.isProcessed(payload.sessionPath))
64
+ return;
65
+ const run = deps.processor ?? processSession;
66
+ const result = await run(payload.sessionPath, deps.wikiDir, store, scope, deps.model, deps.getApiKey);
67
+ if (result.skipped) {
68
+ stateDb.recordSuccess(payload.sessionPath, scope, [], []);
69
+ }
70
+ else {
71
+ stateDb.recordSuccess(payload.sessionPath, scope, result.pagesCreated, result.pagesUpdated);
72
+ }
73
+ }
74
+ catch (err) {
75
+ const message = err instanceof Error ? err.message : String(err);
76
+ stateDb.recordFailure(payload.sessionPath, scope, message);
77
+ throw err;
78
+ }
79
+ finally {
80
+ if (ownsState)
81
+ stateDb.close();
82
+ }
83
+ };
84
+ }
85
+ export function detectScopeFromSessionPath(sessionPath) {
86
+ try {
87
+ const firstLine = requireReadFirstLine(sessionPath);
88
+ const header = JSON.parse(firstLine);
89
+ if (header.cwd)
90
+ return basename(header.cwd) || "unknown";
91
+ }
92
+ catch {
93
+ // fall through to path decoding
94
+ }
95
+ const dirName = basename(dirname(sessionPath));
96
+ if (dirName.startsWith("--") && dirName.endsWith("--")) {
97
+ const inner = dirName.slice(2, -2);
98
+ const projectsIdx = inner.indexOf("projects-");
99
+ if (projectsIdx >= 0)
100
+ return inner.slice(projectsIdx + "projects-".length);
101
+ }
102
+ return "unknown";
103
+ }
104
+ function requireReadFirstLine(path) {
105
+ const content = readFileSync(path, "utf-8");
106
+ return content.split("\n")[0] ?? "";
107
+ }
108
+ //# sourceMappingURL=session-capture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-capture.js","sourceRoot":"","sources":["../../src/scheduler/session-capture.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ import Database from "better-sqlite3";
2
+ export type QueueStatus = "queued" | "running" | "done" | "failed";
3
+ export interface QueueItem<T = unknown> {
4
+ id: number;
5
+ taskName: string;
6
+ payload: T;
7
+ priority: number;
8
+ availableAt: string;
9
+ dedupeKey: string | null;
10
+ status: QueueStatus;
11
+ attempts: number;
12
+ createdAt: string;
13
+ updatedAt: string;
14
+ }
15
+ export interface EnqueueOptions {
16
+ priority?: number;
17
+ availableAt?: Date;
18
+ dedupeKey?: string;
19
+ now?: Date;
20
+ }
21
+ export interface SchedulerHistoryItem<T = unknown> {
22
+ id: number;
23
+ taskName: string;
24
+ payload: T | null;
25
+ status: string;
26
+ startedAt: string;
27
+ finishedAt: string | null;
28
+ durationMs: number | null;
29
+ error: string | null;
30
+ }
31
+ export declare class SchedulerStateDB {
32
+ readonly db: Database.Database;
33
+ constructor(dbPath?: string);
34
+ migrate(): void;
35
+ enqueue(taskName: string, payload: unknown, opts?: EnqueueOptions): number;
36
+ claimNext(now?: Date): QueueItem | null;
37
+ complete(id: number, now?: Date): void;
38
+ fail(id: number, error: string, opts?: {
39
+ retryAt?: Date;
40
+ maxAttempts?: number;
41
+ now?: Date;
42
+ }): void;
43
+ get(id: number): QueueItem | null;
44
+ list(status?: QueueStatus): QueueItem[];
45
+ requeueRunning(now?: Date): number;
46
+ retryFailed(taskName?: string, now?: Date): number;
47
+ listHistory(opts?: {
48
+ taskName?: string;
49
+ limit?: number;
50
+ }): SchedulerHistoryItem[];
51
+ getHistoryItem(id: number): SchedulerHistoryItem | null;
52
+ recordHistory(taskName: string, payload: unknown, status: string, startedAt: Date, finishedAt: Date | null, durationMs: number | null, error: string | null): void;
53
+ close(): void;
54
+ private getQueuedByDedupe;
55
+ }
56
+ //# sourceMappingURL=state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/scheduler/state.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAMtC,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEnE,MAAM,WAAW,SAAS,CAAC,CAAC,GAAG,OAAO;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,CAAC,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE,WAAW,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,IAAI,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ;AAED,MAAM,WAAW,oBAAoB,CAAC,CAAC,GAAG,OAAO;IAC/C,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,CAAC,GAAG,IAAI,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,qBAAa,gBAAgB;IAC3B,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,CAAC;gBAEnB,MAAM,SAAiC;IAOnD,OAAO,IAAI,IAAI;IA6Cf,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,GAAE,cAAmB,GAAG,MAAM;IAuB9E,SAAS,CAAC,GAAG,OAAa,GAAG,SAAS,GAAG,IAAI;IA4B7C,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,OAAa,GAAG,IAAI;IAI5C,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,GAAE;QAAE,OAAO,CAAC,EAAE,IAAI,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,IAAI,CAAA;KAAO,GAAG,IAAI;IAiBtG,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAKjC,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,EAAE;IAOvC,cAAc,CAAC,GAAG,OAAa,GAAG,MAAM;IASxC,WAAW,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,GAAG,OAAa,GAAG,MAAM;IAexD,WAAW,CAAC,IAAI,GAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,oBAAoB,EAAE;IAQrF,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,oBAAoB,GAAG,IAAI;IAKvD,aAAa,CACX,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,IAAI,EACf,UAAU,EAAE,IAAI,GAAG,IAAI,EACvB,UAAU,EAAE,MAAM,GAAG,IAAI,EACzB,KAAK,EAAE,MAAM,GAAG,IAAI,GACnB,IAAI;IAgBP,KAAK,IAAI,IAAI;IAIb,OAAO,CAAC,iBAAiB;CAQ1B"}