konsilio 0.3.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 (80) hide show
  1. package/LICENSE.md +24 -0
  2. package/README.md +170 -0
  3. package/build/cli/history.d.ts +2 -0
  4. package/build/cli/history.js +179 -0
  5. package/build/cli/history.js.map +1 -0
  6. package/build/config.d.ts +38 -0
  7. package/build/config.js +118 -0
  8. package/build/config.js.map +1 -0
  9. package/build/container.d.ts +32 -0
  10. package/build/container.js +102 -0
  11. package/build/container.js.map +1 -0
  12. package/build/db/schema.d.ts +1 -0
  13. package/build/db/schema.js +67 -0
  14. package/build/db/schema.js.map +1 -0
  15. package/build/index.d.ts +2 -0
  16. package/build/index.js +140 -0
  17. package/build/index.js.map +1 -0
  18. package/build/konsilio.json +25 -0
  19. package/build/konsilio.schema.json +140 -0
  20. package/build/logger.d.ts +84 -0
  21. package/build/logger.js +121 -0
  22. package/build/logger.js.map +1 -0
  23. package/build/personas/expert.d.ts +33 -0
  24. package/build/personas/expert.js +46 -0
  25. package/build/personas/expert.js.map +1 -0
  26. package/build/personas/index.d.ts +9 -0
  27. package/build/personas/index.js +11 -0
  28. package/build/personas/index.js.map +1 -0
  29. package/build/personas/lead.d.ts +33 -0
  30. package/build/personas/lead.js +51 -0
  31. package/build/personas/lead.js.map +1 -0
  32. package/build/personas/schemas.d.ts +313 -0
  33. package/build/personas/schemas.js +97 -0
  34. package/build/personas/schemas.js.map +1 -0
  35. package/build/prompts/consolidation/critique.md +59 -0
  36. package/build/prompts/consolidation/decision.md +51 -0
  37. package/build/prompts/consolidation/extraction.md +46 -0
  38. package/build/prompts/consolidation/synthesis.md +42 -0
  39. package/build/prompts/expert-rules.md +50 -0
  40. package/build/prompts/personas/dev-tooling.md +27 -0
  41. package/build/prompts/personas/devops.md +26 -0
  42. package/build/prompts/personas/distributed-systems.md +28 -0
  43. package/build/prompts/personas/graph-dba.md +27 -0
  44. package/build/prompts/personas/node-fullstack.md +27 -0
  45. package/build/prompts/personas/performance.md +26 -0
  46. package/build/prompts/personas/security.md +26 -0
  47. package/build/prompts/personas/test-architect.md +29 -0
  48. package/build/prompts/personas/test-quoted.md +14 -0
  49. package/build/prompts/personas/typescript.md +26 -0
  50. package/build/prompts/personas/ux-dx.md +29 -0
  51. package/build/prompts/workflow-rules.md +3 -0
  52. package/build/server.d.ts +24 -0
  53. package/build/server.js +181 -0
  54. package/build/server.js.map +1 -0
  55. package/build/services/cache.service.d.ts +49 -0
  56. package/build/services/cache.service.js +85 -0
  57. package/build/services/cache.service.js.map +1 -0
  58. package/build/services/council.service.d.ts +111 -0
  59. package/build/services/council.service.js +361 -0
  60. package/build/services/council.service.js.map +1 -0
  61. package/build/services/database.service.d.ts +70 -0
  62. package/build/services/database.service.js +221 -0
  63. package/build/services/database.service.js.map +1 -0
  64. package/build/services/formatter.service.d.ts +52 -0
  65. package/build/services/formatter.service.js +133 -0
  66. package/build/services/formatter.service.js.map +1 -0
  67. package/build/services/index.d.ts +18 -0
  68. package/build/services/index.js +13 -0
  69. package/build/services/index.js.map +1 -0
  70. package/build/services/openrouter.service.d.ts +58 -0
  71. package/build/services/openrouter.service.js +128 -0
  72. package/build/services/openrouter.service.js.map +1 -0
  73. package/build/services/persona.service.d.ts +43 -0
  74. package/build/services/persona.service.js +93 -0
  75. package/build/services/persona.service.js.map +1 -0
  76. package/build/services/prompt.service.d.ts +59 -0
  77. package/build/services/prompt.service.js +209 -0
  78. package/build/services/prompt.service.js.map +1 -0
  79. package/konsilio.schema.json +140 -0
  80. package/package.json +68 -0
@@ -0,0 +1,361 @@
1
+ /**
2
+ * Council Service - Two-Stage Consulting Pipeline
3
+ *
4
+ * Stage 1: Expert Analysis (parallel, prose output)
5
+ * Stage 2: Formatting (convert prose to structured JSON via FormatterService)
6
+ * Stage 3: Extraction (extract claims from expert reports)
7
+ * Stage 4: Critique (identify contradictions and weaknesses)
8
+ * Stage 5: Decision (accept/reject findings)
9
+ * Stage 6: Synthesis (assemble final blueprint)
10
+ */
11
+ import { randomUUID } from 'node:crypto';
12
+ import { ExtractionPhaseOutputSchema, CritiquePhaseOutputSchema, DecisionPhaseOutputSchema } from '../personas/schemas.js';
13
+ /**
14
+ * CouncilService - Orchestrates two-stage expert analysis and consolidation
15
+ */
16
+ export class CouncilService {
17
+ deps;
18
+ constructor(deps) {
19
+ this.deps = deps;
20
+ }
21
+ /**
22
+ * Resolve the model for a specific persona using 3-tier resolution:
23
+ * 1. Per-run override (personaModelsOverride)
24
+ * 2. Persona-level default (config.personaModels)
25
+ * 3. Global default (config.models.experts)
26
+ */
27
+ resolvePersonaModel(personaId, options) {
28
+ // Tier 1: Per-run override
29
+ if (options?.personaModelsOverride?.[personaId]) {
30
+ return options.personaModelsOverride[personaId];
31
+ }
32
+ // Tier 2: Persona-level default in config
33
+ if (this.deps.config.personaModels?.[personaId]) {
34
+ return this.deps.config.personaModels[personaId];
35
+ }
36
+ // Tier 3: Global default
37
+ return this.deps.config.models.experts;
38
+ }
39
+ /**
40
+ * Resolve the effective token limit for a role
41
+ */
42
+ resolveMaxTokens(role, options) {
43
+ if (role === 'experts' && options?.maxTokensOverride?.experts) {
44
+ return options.maxTokensOverride.experts;
45
+ }
46
+ if (role === 'lead' && options?.maxTokensOverride?.lead) {
47
+ return options.maxTokensOverride.lead;
48
+ }
49
+ return this.deps.config.maxTokens[role];
50
+ }
51
+ /**
52
+ * Run a council analysis with two-stage consolidation
53
+ */
54
+ async run(params, options, correlationId) {
55
+ const log = correlationId ? this.deps.logger.withCorrelationId(correlationId) : this.deps.logger;
56
+ const totalStart = Date.now();
57
+ const sessionId = correlationId ?? randomUUID();
58
+ log.info('Starting council session', { sessionId, draftPlanLength: params.draftPlan.length });
59
+ if (!params.draftPlan.trim())
60
+ throw new Error('draft_plan cannot be empty');
61
+ if (params.draftPlan.length > this.deps.config.maxDraftPlanLength) {
62
+ throw new Error(`draft_plan too long (${params.draftPlan.length}/${this.deps.config.maxDraftPlanLength} chars)`);
63
+ }
64
+ // Resolve effective personas: per-run override or config defaults
65
+ const effectivePersonaIds = options?.personaOverride ?? this.deps.config.enabledPersonaIds;
66
+ // Resolve consolidation model: per-run override or config default
67
+ const consolidationModel = options?.consolidationModelOverride ?? this.deps.config.models.lead;
68
+ // Create personas with per-persona model resolution (3-tier)
69
+ const personas = effectivePersonaIds.map((id) => {
70
+ const model = this.resolvePersonaModel(id, options);
71
+ return this.deps.personaService.createExpert(id, model);
72
+ });
73
+ if (personas.length < 2)
74
+ throw new Error(`At least 2 personas required. Found: ${effectivePersonaIds.join(', ')}`);
75
+ // Stage 1: Expert Analysis (parallel, prose output)
76
+ log.debug('Stage 1: Expert Analysis (prose)');
77
+ const userMessage = this.buildUserMessage(params);
78
+ const expertPromises = personas.map((p) => {
79
+ const model = this.resolvePersonaModel(p.id, options);
80
+ const maxTokens = this.resolveMaxTokens('experts', options);
81
+ return this.callExpert(p, model, userMessage, this.deps.config.timeouts.expertMs, maxTokens, log);
82
+ });
83
+ const expertResults = await Promise.allSettled(expertPromises);
84
+ const successfulProseReports = [];
85
+ const failedExperts = [];
86
+ for (let i = 0; i < expertResults.length; i++) {
87
+ const result = expertResults[i];
88
+ if (result.status === 'fulfilled')
89
+ successfulProseReports.push(result.value);
90
+ else
91
+ failedExperts.push(`${personas[i].emoji} ${personas[i].name}: ${result.reason}`);
92
+ }
93
+ if (successfulProseReports.length < 2)
94
+ throw new Error(`Too many expert failures. ${failedExperts.join('\n')}`);
95
+ log.debug('Expert prose analysis complete', { succeeded: successfulProseReports.length, failed: failedExperts.length });
96
+ // Stage 2: Format prose to structured JSON
97
+ log.debug('Stage 2: Formatting prose to structured JSON');
98
+ const formatStart = Date.now();
99
+ const formatResults = await Promise.allSettled(successfulProseReports.map((r) => this.deps.formatterService.formatProse(r.prose, r.persona.id, correlationId)));
100
+ const successfulReports = [];
101
+ const formattingErrors = [];
102
+ let formatSuccessCount = 0;
103
+ for (let i = 0; i < formatResults.length; i++) {
104
+ const result = formatResults[i];
105
+ const proseReport = successfulProseReports[i];
106
+ if (result.status === 'fulfilled') {
107
+ const formatResult = result.value;
108
+ successfulReports.push({
109
+ personaId: proseReport.persona.id,
110
+ personaName: proseReport.persona.name,
111
+ personaEmoji: proseReport.persona.emoji,
112
+ structuredOutput: formatResult.output,
113
+ rawContent: formatResult.originalProse,
114
+ durationMs: proseReport.durationMs + formatResult.durationMs,
115
+ modelUsed: this.deps.config.models.formatter
116
+ });
117
+ formatSuccessCount++;
118
+ }
119
+ else {
120
+ formattingErrors.push(`${proseReport.persona.name}: ${result.reason}`);
121
+ }
122
+ }
123
+ const totalFormattingTimeMs = Date.now() - formatStart;
124
+ const formattingDetails = {
125
+ totalFormattingTimeMs,
126
+ formattingSuccessRate: formatSuccessCount / successfulProseReports.length,
127
+ formattingErrors
128
+ };
129
+ log.debug('Formatting complete', { successRate: formattingDetails.formattingSuccessRate, errors: formattingErrors.length });
130
+ if (successfulReports.length < 2)
131
+ throw new Error(`Too many expert failures after formatting. ${failedExperts.join('\n')}`);
132
+ log.info('Expert analysis complete', { succeeded: successfulReports.length, failed: failedExperts.length });
133
+ // Stage 3: Extraction
134
+ log.debug('Stage 3: Extraction');
135
+ const extractionOutput = await this.runExtractionPhase(successfulReports, consolidationModel, log);
136
+ // Stage 4: Critique
137
+ log.debug('Stage 4: Critique');
138
+ const critiqueOutput = await this.runCritiquePhase(successfulReports, extractionOutput, params, consolidationModel, log);
139
+ // Stage 5: Decision
140
+ log.debug('Stage 5: Decision');
141
+ const decisionOutput = await this.runDecisionPhase(successfulReports, critiqueOutput, consolidationModel, log);
142
+ // Stage 6: Synthesis
143
+ log.debug('Stage 6: Synthesis');
144
+ const synthesisOutput = await this.runSynthesisPhase(successfulReports, decisionOutput, params, consolidationModel, log);
145
+ // Build model summary: show which models were used per persona
146
+ const modelSummary = personas.map(p => {
147
+ const model = this.resolvePersonaModel(p.id, options);
148
+ return `${p.id}:${model}`;
149
+ }).join(', ');
150
+ const totalDurationMs = Date.now() - totalStart;
151
+ let output = failedExperts.length > 0 ? `> ⚠️ ${failedExperts.length} expert(s) failed\n\n` : '';
152
+ output += `> 📝 Formatted: ${(formattingDetails.formattingSuccessRate * 100).toFixed(0)}% success (${(formattingDetails.totalFormattingTimeMs / 1000).toFixed(1)}s)\n`;
153
+ output += `> 👑 Council: ${successfulReports.length} experts [${modelSummary}] → 4-phase consolidation (${consolidationModel})\n`;
154
+ output += `> ⏱️ ${(totalDurationMs / 1000).toFixed(1)}s | Accepted: ${decisionOutput.acceptedCount} | Rejected: ${decisionOutput.rejectedCount}\n\n---\n\n`;
155
+ output += synthesisOutput.blueprint;
156
+ const result = {
157
+ sessionId,
158
+ expertReports: successfulReports,
159
+ extractionOutput,
160
+ critiqueOutput,
161
+ decisionOutput,
162
+ synthesisOutput,
163
+ finalBlueprint: output,
164
+ consolidationModel,
165
+ totalDurationMs,
166
+ formattingDetails
167
+ };
168
+ try {
169
+ this.deps.databaseService.saveCouncilResult(result, params.draftPlan, params.techStack, params.contextConstraints, correlationId);
170
+ }
171
+ catch (err) {
172
+ log.warn('Failed to save to database', { error: err instanceof Error ? err.message : String(err) });
173
+ }
174
+ log.info('Council session complete', { sessionId, totalDurationMs });
175
+ return result;
176
+ }
177
+ /**
178
+ * Call an expert persona for prose analysis
179
+ */
180
+ async callExpert(persona, model, userMessage, timeoutMs, maxTokens, log) {
181
+ const start = Date.now();
182
+ const messages = [
183
+ { role: 'system', content: persona.systemPrompt },
184
+ { role: 'user', content: userMessage }
185
+ ];
186
+ try {
187
+ const rawContent = await this.deps.openRouterService.call({
188
+ model,
189
+ messages,
190
+ maxTokens,
191
+ temperature: 0.3,
192
+ timeoutMs
193
+ });
194
+ log.debug('Expert prose analysis complete', { personaId: persona.id, model, contentLength: rawContent.length });
195
+ return { persona, prose: rawContent, durationMs: Date.now() - start };
196
+ }
197
+ catch (err) {
198
+ log.error('Expert analysis failed', { personaId: persona.id, model, error: err instanceof Error ? err.message : String(err) });
199
+ throw new Error(`${persona.name} failed: ${err instanceof Error ? err.message : String(err)}`);
200
+ }
201
+ }
202
+ /**
203
+ * Stage 3: Extraction - Extract structured claims from expert reports
204
+ */
205
+ async runExtractionPhase(reports, model, log) {
206
+ const lead = this.deps.personaService.createLead('extraction');
207
+ const expertReportsText = reports.map(r => `## ${r.personaEmoji} ${r.personaName}\n\n${JSON.stringify(r.structuredOutput, null, 2)}`).join('\n\n---\n\n');
208
+ const messages = [
209
+ { role: 'system', content: lead.systemPrompt },
210
+ { role: 'user', content: `Extract all findings from these expert reports:\n\n${expertReportsText}` }
211
+ ];
212
+ const rawOutput = await this.deps.openRouterService.call({
213
+ model,
214
+ messages,
215
+ maxTokens: this.deps.config.maxTokens.lead,
216
+ temperature: 0.2,
217
+ timeoutMs: this.deps.config.timeouts.leadMs
218
+ });
219
+ const cleaned = this.cleanJsonOutput(rawOutput);
220
+ try {
221
+ const parsed = JSON.parse(cleaned);
222
+ const output = ExtractionPhaseOutputSchema.parse(parsed);
223
+ log.debug('Extraction complete', { totalFindings: output.totalFindings });
224
+ return output;
225
+ }
226
+ catch (err) {
227
+ log.error('Failed to parse extraction JSON', {
228
+ rawLength: rawOutput.length,
229
+ cleanedLength: cleaned.length,
230
+ rawPreview: rawOutput.slice(0, 500),
231
+ error: err instanceof Error ? err.message : String(err)
232
+ });
233
+ throw new Error(`Extraction phase: failed to parse JSON. ${err instanceof Error ? err.message : String(err)}`);
234
+ }
235
+ }
236
+ /**
237
+ * Stage 4: Critique - Analyze for contradictions and weaknesses
238
+ */
239
+ async runCritiquePhase(reports, extraction, params, model, log) {
240
+ const lead = this.deps.personaService.createLead('critique');
241
+ const context = `## Original Draft Plan\n\n${params.draftPlan}\n\n## Extracted Claims\n\n${JSON.stringify(extraction, null, 2)}`;
242
+ const messages = [
243
+ { role: 'system', content: lead.systemPrompt },
244
+ { role: 'user', content: context }
245
+ ];
246
+ const rawOutput = await this.deps.openRouterService.call({
247
+ model,
248
+ messages,
249
+ maxTokens: this.deps.config.maxTokens.lead,
250
+ temperature: 0.3,
251
+ timeoutMs: this.deps.config.timeouts.leadMs
252
+ });
253
+ const cleaned = this.cleanJsonOutput(rawOutput);
254
+ try {
255
+ const parsed = JSON.parse(cleaned);
256
+ const output = CritiquePhaseOutputSchema.parse(parsed);
257
+ log.debug('Critique complete', { contradictions: output.contradictions.length, unsupportedClaims: output.unsupportedClaims.length });
258
+ return output;
259
+ }
260
+ catch (err) {
261
+ log.error('Failed to parse critique JSON', {
262
+ rawLength: rawOutput.length,
263
+ cleanedLength: cleaned.length,
264
+ rawPreview: rawOutput.slice(0, 500),
265
+ error: err instanceof Error ? err.message : String(err)
266
+ });
267
+ throw new Error(`Critique phase: failed to parse JSON. ${err instanceof Error ? err.message : String(err)}`);
268
+ }
269
+ }
270
+ /**
271
+ * Stage 5: Decision - Accept/reject findings explicitly
272
+ */
273
+ async runDecisionPhase(reports, critique, model, log) {
274
+ const lead = this.deps.personaService.createLead('decision');
275
+ const allFindings = reports.flatMap(r => r.structuredOutput.findings);
276
+ const context = `## All Findings\n\n${JSON.stringify(allFindings, null, 2)}\n\n## Critique Analysis\n\n${JSON.stringify(critique, null, 2)}`;
277
+ const messages = [
278
+ { role: 'system', content: lead.systemPrompt },
279
+ { role: 'user', content: context }
280
+ ];
281
+ const rawOutput = await this.deps.openRouterService.call({
282
+ model,
283
+ messages,
284
+ maxTokens: this.deps.config.maxTokens.lead,
285
+ temperature: 0.2,
286
+ timeoutMs: this.deps.config.timeouts.leadMs
287
+ });
288
+ const cleaned = this.cleanJsonOutput(rawOutput);
289
+ try {
290
+ const parsed = JSON.parse(cleaned);
291
+ const output = DecisionPhaseOutputSchema.parse(parsed);
292
+ log.debug('Decision complete', { accepted: output.acceptedCount, rejected: output.rejectedCount });
293
+ return output;
294
+ }
295
+ catch (err) {
296
+ log.error('Failed to parse decision JSON', {
297
+ rawLength: rawOutput.length,
298
+ cleanedLength: cleaned.length,
299
+ rawPreview: rawOutput.slice(0, 500),
300
+ error: err instanceof Error ? err.message : String(err)
301
+ });
302
+ throw new Error(`Decision phase: failed to parse JSON. ${err instanceof Error ? err.message : String(err)}`);
303
+ }
304
+ }
305
+ /**
306
+ * Stage 6: Synthesis - Assemble final blueprint from accepted findings
307
+ */
308
+ async runSynthesisPhase(reports, decision, params, model, log) {
309
+ const lead = this.deps.personaService.createLead('synthesis');
310
+ const acceptedFindingIds = new Set(decision.decisions.filter(d => d.action === 'ACCEPT').map(d => d.findingId));
311
+ const acceptedFindings = [];
312
+ const attributions = {};
313
+ for (const report of reports) {
314
+ for (const finding of report.structuredOutput.findings) {
315
+ if (acceptedFindingIds.has(finding.id)) {
316
+ acceptedFindings.push(finding);
317
+ attributions[finding.id] = report.personaId;
318
+ }
319
+ }
320
+ }
321
+ const context = `## Original Draft Plan\n\n${params.draftPlan}\n\n${params.techStack ? `## Tech Stack\n\n${params.techStack}\n\n` : ''}## Accepted Findings\n\n${JSON.stringify(acceptedFindings, null, 2)}\n\n## Attributions\n\n${JSON.stringify(attributions, null, 2)}`;
322
+ const messages = [
323
+ { role: 'system', content: lead.systemPrompt },
324
+ { role: 'user', content: context }
325
+ ];
326
+ const blueprint = await this.deps.openRouterService.call({
327
+ model,
328
+ messages,
329
+ maxTokens: 8192,
330
+ temperature: 0.4,
331
+ timeoutMs: this.deps.config.timeouts.leadMs
332
+ });
333
+ log.debug('Synthesis complete', { acceptedFindings: acceptedFindings.length });
334
+ return { blueprint, acceptedFindings, attributions };
335
+ }
336
+ /**
337
+ * Build user message for expert analysis
338
+ */
339
+ buildUserMessage(params) {
340
+ let msg = `## Draft Plan\n\n${params.draftPlan}`;
341
+ if (params.techStack)
342
+ msg += `\n\n## Tech Stack\n\n${params.techStack}`;
343
+ if (params.contextConstraints)
344
+ msg += `\n\n## Context Constraints\n\n${params.contextConstraints}`;
345
+ return msg;
346
+ }
347
+ /**
348
+ * Clean JSON output from LLM responses (strip markdown code fences)
349
+ */
350
+ cleanJsonOutput(raw) {
351
+ let cleaned = raw.trim();
352
+ if (cleaned.startsWith('```json')) {
353
+ cleaned = cleaned.replace(/^```json\s*/, '').replace(/\s*```$/, '');
354
+ }
355
+ else if (cleaned.startsWith('```')) {
356
+ cleaned = cleaned.replace(/^```\s*/, '').replace(/\s*```$/, '');
357
+ }
358
+ return cleaned;
359
+ }
360
+ }
361
+ //# sourceMappingURL=council.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"council.service.js","sourceRoot":"","sources":["../../src/services/council.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Database Service
3
+ *
4
+ * Provides SQLite database operations for session persistence using sql.js (WASM).
5
+ * Designed for dependency injection to enable testing.
6
+ */
7
+ import type { Logger } from '../logger.js';
8
+ import type { CouncilResult } from '../personas/schemas.js';
9
+ export interface DatabaseServiceConfig {
10
+ dbPath: string;
11
+ maxHistorySessions?: number;
12
+ }
13
+ export interface SessionSummary {
14
+ id: string;
15
+ created_at: string;
16
+ draft_plan_summary: string | null;
17
+ tech_stack: string | null;
18
+ }
19
+ /**
20
+ * DatabaseService - Handles SQLite persistence via sql.js (WASM)
21
+ *
22
+ * Uses an in-memory database that is loaded from / saved to disk.
23
+ * All queries run against the in-memory copy; changes are persisted
24
+ * explicitly after writes.
25
+ */
26
+ export declare class DatabaseService {
27
+ private db;
28
+ private readonly dbPath;
29
+ private readonly maxHistorySessions;
30
+ private readonly logger;
31
+ private constructor();
32
+ /**
33
+ * Factory method to create and initialize the DatabaseService.
34
+ * Async because sql.js WASM loading and DB file reading are async.
35
+ */
36
+ static create(config: DatabaseServiceConfig, logger: Logger, schema: string): Promise<DatabaseService>;
37
+ /**
38
+ * Initialize database: load WASM, read existing DB file (or create new), apply schema
39
+ */
40
+ private initialize;
41
+ /**
42
+ * Persist the in-memory database to disk
43
+ */
44
+ private save;
45
+ /**
46
+ * Check database health
47
+ */
48
+ checkHealth(): {
49
+ status: 'healthy' | 'unhealthy';
50
+ latencyMs: number;
51
+ error?: string;
52
+ };
53
+ /**
54
+ * Save a council session result
55
+ */
56
+ saveCouncilResult(result: CouncilResult, draftPlan: string, techStack?: string, constraints?: string, correlationId?: string): void;
57
+ /**
58
+ * Get recent sessions
59
+ */
60
+ getRecentSessions(limit?: number): SessionSummary[];
61
+ /**
62
+ * Get a session's blueprint
63
+ */
64
+ getSessionBlueprint(sessionId: string): string | null;
65
+ /**
66
+ * Close database (no-op for sql.js, but we clear the reference)
67
+ */
68
+ close(): void;
69
+ private pruneOldSessions;
70
+ }