@ariso-ai/ivan 1.0.26 → 1.0.28

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 (38) hide show
  1. package/dist/config.js +11 -11
  2. package/dist/config.js.map +1 -1
  3. package/dist/database/migrations/016_create_session_analyses_table.d.ts +3 -0
  4. package/dist/database/migrations/016_create_session_analyses_table.d.ts.map +1 -0
  5. package/dist/database/migrations/016_create_session_analyses_table.js +19 -0
  6. package/dist/database/migrations/016_create_session_analyses_table.js.map +1 -0
  7. package/dist/database/migrations/index.d.ts.map +1 -1
  8. package/dist/database/migrations/index.js +3 -1
  9. package/dist/database/migrations/index.js.map +1 -1
  10. package/dist/database.d.ts +2 -0
  11. package/dist/database.d.ts.map +1 -1
  12. package/dist/database.js +3 -0
  13. package/dist/database.js.map +1 -1
  14. package/dist/index.js +2 -1
  15. package/dist/index.js.map +1 -1
  16. package/dist/learnings/coding-sessions-command.d.ts +12 -0
  17. package/dist/learnings/coding-sessions-command.d.ts.map +1 -0
  18. package/dist/learnings/coding-sessions-command.js +274 -0
  19. package/dist/learnings/coding-sessions-command.js.map +1 -0
  20. package/dist/learnings/database.js +1 -1
  21. package/dist/learnings/database.js.map +1 -1
  22. package/dist/learnings/embeddings.d.ts.map +1 -1
  23. package/dist/learnings/embeddings.js +15 -2
  24. package/dist/learnings/embeddings.js.map +1 -1
  25. package/dist/learnings/index.d.ts +1 -1
  26. package/dist/learnings/index.d.ts.map +1 -1
  27. package/dist/learnings/index.js +23 -11
  28. package/dist/learnings/index.js.map +1 -1
  29. package/dist/learnings/install-hooks-command.js +2 -2
  30. package/dist/learnings/session-analyzer.d.ts +39 -0
  31. package/dist/learnings/session-analyzer.d.ts.map +1 -0
  32. package/dist/learnings/session-analyzer.js +339 -0
  33. package/dist/learnings/session-analyzer.js.map +1 -0
  34. package/dist/learnings/session-parser.d.ts +46 -0
  35. package/dist/learnings/session-parser.d.ts.map +1 -0
  36. package/dist/learnings/session-parser.js +235 -0
  37. package/dist/learnings/session-parser.js.map +1 -0
  38. package/package.json +2 -2
@@ -0,0 +1,274 @@
1
+ // CLI handler for `ivan learn coding-sessions`.
2
+ // Orchestrates the full pipeline: parse → analyze → store → rebuild.
3
+ import chalk from 'chalk';
4
+ import ora from 'ora';
5
+ import fs from 'fs';
6
+ import path from 'path';
7
+ import { discoverSessionFiles, parseSessionFile } from './session-parser.js';
8
+ import { SessionAnalyzer } from './session-analyzer.js';
9
+ import { writeLearningRecords } from './learning-writer.js';
10
+ import { rebuildLearningsDatabase } from './builder.js';
11
+ import { loadCanonicalRecords } from './parser.js';
12
+ import { resolveCanonicalLearningsPath } from './paths.js';
13
+ import { ensureLearningsDirectories, resolveLearningsRepositoryContext } from './repository.js';
14
+ import { DatabaseManager } from '../database.js';
15
+ /** Commander action handler for `ivan learn coding-sessions`. */
16
+ export async function runCodingSessionsCommand(options) {
17
+ const repoPath = path.resolve(options.repo);
18
+ if (options.reset) {
19
+ await handleReset(repoPath);
20
+ return;
21
+ }
22
+ // Ensure .ivan/ directory and learnings DB exist
23
+ const context = resolveLearningsRepositoryContext(repoPath);
24
+ ensureLearningsDirectories(context);
25
+ // Run main DB migrations for session_analyses table
26
+ const dbManager = new DatabaseManager();
27
+ await dbManager.runMigrations();
28
+ try {
29
+ // Stage 1: Discover and parse sessions
30
+ const spinner = ora('Discovering Claude Code sessions...').start();
31
+ const sessionFiles = discoverSessionFiles({
32
+ project: options.project,
33
+ recentDays: options.recent ? parseInt(options.recent) : undefined
34
+ });
35
+ spinner.succeed(`Found ${sessionFiles.length} session files${options.project ? ` (project: ${options.project})` : ''}`);
36
+ if (sessionFiles.length === 0) {
37
+ console.log(chalk.yellow('No sessions found to analyze.'));
38
+ return;
39
+ }
40
+ // Check which sessions are already analyzed (unless --force)
41
+ // Uses composite key (session_id|file_size|mtime) so modified transcripts get re-analyzed
42
+ const alreadyAnalyzed = options.force
43
+ ? new Map()
44
+ : loadAnalyzedSessions(dbManager);
45
+ // Parse sessions
46
+ const parseSpinner = ora('Parsing session transcripts...').start();
47
+ const digests = [];
48
+ let skippedAlready = 0;
49
+ let skippedLowSignal = 0;
50
+ for (const file of sessionFiles) {
51
+ const cached = alreadyAnalyzed.get(file.sessionId);
52
+ if (cached) {
53
+ const stat = fs.statSync(file.filePath);
54
+ if (cached.fileSize === stat.size &&
55
+ cached.fileModifiedAt === stat.mtime.toISOString()) {
56
+ skippedAlready++;
57
+ continue;
58
+ }
59
+ }
60
+ try {
61
+ const digest = await parseSessionFile(file.filePath, file.projectPath, file.sessionId);
62
+ if (digest) {
63
+ digests.push(digest);
64
+ }
65
+ else {
66
+ skippedLowSignal++;
67
+ }
68
+ }
69
+ catch {
70
+ // Skip unparseable sessions
71
+ skippedLowSignal++;
72
+ }
73
+ }
74
+ parseSpinner.succeed(`Parsed ${digests.length} qualifying sessions (${skippedAlready} cached, ${skippedLowSignal} low-signal)`);
75
+ if (digests.length === 0) {
76
+ if (skippedAlready > 0) {
77
+ console.log(chalk.green('All sessions already analyzed. Nothing to do.'));
78
+ }
79
+ else {
80
+ console.log(chalk.yellow('No sessions with sufficient signal to analyze (all filtered as low-signal).'));
81
+ }
82
+ return;
83
+ }
84
+ // Dry run: show what would be analyzed
85
+ if (options.dryRun) {
86
+ console.log('');
87
+ console.log(chalk.blue.bold('Dry run — sessions that would be analyzed:'));
88
+ console.log('');
89
+ for (const d of digests) {
90
+ const title = d.aiTitle ?? 'Untitled';
91
+ const proj = extractProjectName(d.projectPath);
92
+ console.log(` ${chalk.cyan(proj)} ${chalk.white(title)} (${d.userMessages.length} user msgs, correction density: ${(d.dynamics.correctionDensity * 100).toFixed(0)}%)`);
93
+ }
94
+ console.log('');
95
+ console.log(`Total: ${digests.length} sessions would be sent to GPT-5.5`);
96
+ return;
97
+ }
98
+ // Stage 2: Analyze with GPT-5.5
99
+ const analyzer = new SessionAnalyzer();
100
+ const analysisResults = [];
101
+ let totalPatterns = 0;
102
+ let totalExamples = 0;
103
+ console.log('');
104
+ const analyzeSpinner = ora(`Analyzing session 1/${digests.length} with GPT-5.5...`).start();
105
+ for (let i = 0; i < digests.length; i++) {
106
+ const digest = digests[i];
107
+ analyzeSpinner.text = `Analyzing session ${i + 1}/${digests.length}: ${digest.aiTitle ?? 'Untitled'}`;
108
+ try {
109
+ const analysis = await analyzer.analyzeSession(digest);
110
+ analysisResults.push({ analysis, digest });
111
+ totalPatterns += analysis.patterns.length;
112
+ totalExamples += analysis.exampleInteractions.length;
113
+ // Track in main DB
114
+ saveSessionAnalysis(dbManager, digest, analysis);
115
+ }
116
+ catch (err) {
117
+ const msg = err instanceof Error ? err.message : String(err);
118
+ analyzeSpinner.warn(`Failed to analyze session ${digest.sessionId}: ${msg}`);
119
+ analyzeSpinner.start();
120
+ }
121
+ }
122
+ analyzeSpinner.succeed(`Analyzed ${analysisResults.length} sessions: ${totalPatterns} thinking patterns, ${totalExamples} example interactions`);
123
+ if (totalPatterns === 0 && totalExamples === 0) {
124
+ console.log(chalk.yellow('No thinking patterns or example interactions found.'));
125
+ return;
126
+ }
127
+ // Stage 3: Store as learning records
128
+ const storeSpinner = ora('Storing patterns and examples...').start();
129
+ // Convert analyses to learning records (paired to avoid index misalignment)
130
+ const newRecords = analysisResults.flatMap(({ analysis, digest }) => analyzer.analysisToLearningRecords(analysis, digest));
131
+ // Merge: keep all existing records except those being replaced by new ones
132
+ const newRecordIds = new Set(newRecords.map((r) => r.id));
133
+ const existingRecords = loadExistingRecords(repoPath, newRecordIds);
134
+ const mergedRecords = [...existingRecords, ...newRecords];
135
+ writeLearningRecords(repoPath, mergedRecords);
136
+ storeSpinner.succeed(`Stored ${newRecords.length} thinking patterns (${mergedRecords.length} total learnings)`);
137
+ // Stage 4: Rebuild SQLite with embeddings
138
+ const rebuildSpinner = ora('Rebuilding database with embeddings...').start();
139
+ try {
140
+ const result = await rebuildLearningsDatabase(repoPath);
141
+ rebuildSpinner.succeed(`Database rebuilt: ${result.learningCount} learnings, ${result.embeddingsGenerated} new embeddings`);
142
+ }
143
+ catch (err) {
144
+ const msg = err instanceof Error ? err.message : String(err);
145
+ rebuildSpinner.fail(`Rebuild failed: ${msg}`);
146
+ return;
147
+ }
148
+ // Summary (only on full success)
149
+ console.log('');
150
+ console.log(chalk.green.bold('Coding sessions analysis complete'));
151
+ printPatternSummary(analysisResults.map((r) => r.analysis));
152
+ }
153
+ finally {
154
+ dbManager.close();
155
+ }
156
+ }
157
+ /**
158
+ * Reads existing learning records, excluding any whose ID is in `replaceIds`.
159
+ * This preserves both PR-derived records AND previously cached session-derived
160
+ * records from earlier runs, only replacing records that were just re-generated.
161
+ */
162
+ function loadExistingRecords(repoPath, replaceIds) {
163
+ const filePath = resolveCanonicalLearningsPath(path.resolve(repoPath), 'lessons.jsonl');
164
+ if (!fs.existsSync(filePath))
165
+ return [];
166
+ const dataset = loadCanonicalRecords(repoPath);
167
+ return dataset.learnings.filter((r) => !replaceIds.has(r.id));
168
+ }
169
+ function loadAnalyzedSessions(dbManager) {
170
+ try {
171
+ const db = dbManager.getDatabase();
172
+ const rows = db
173
+ .prepare('SELECT session_id, file_size, file_modified_at FROM session_analyses')
174
+ .all();
175
+ const map = new Map();
176
+ for (const r of rows) {
177
+ map.set(r.session_id, {
178
+ fileSize: r.file_size,
179
+ fileModifiedAt: r.file_modified_at
180
+ });
181
+ }
182
+ return map;
183
+ }
184
+ catch {
185
+ return new Map();
186
+ }
187
+ }
188
+ function saveSessionAnalysis(dbManager, digest, analysis) {
189
+ try {
190
+ // Redact user_message from example interactions before persisting
191
+ const sanitizedAnalysis = {
192
+ ...analysis,
193
+ exampleInteractions: analysis.exampleInteractions.map((e) => ({
194
+ context: e.context,
195
+ derived_question: e.derived_question,
196
+ when_to_ask: e.when_to_ask,
197
+ confidence: e.confidence
198
+ }))
199
+ };
200
+ const db = dbManager.getDatabase();
201
+ db.prepare(`INSERT OR REPLACE INTO session_analyses
202
+ (session_id, project_path, file_path, file_size, file_modified_at,
203
+ ai_title, session_timestamp, pattern_count, analysis_json, analyzed_at)
204
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(digest.sessionId, digest.projectPath, digest.filePath, digest.fileSize, digest.fileModifiedAt, digest.aiTitle, digest.timestamp, analysis.patterns.length, JSON.stringify(sanitizedAnalysis), new Date().toISOString());
205
+ }
206
+ catch {
207
+ // Non-critical — continue even if tracking fails
208
+ }
209
+ }
210
+ function extractProjectName(projectPath) {
211
+ // Convert "-Users-erkang-Repos-ariso-agents" to "agents"
212
+ const parts = projectPath.split('-').filter(Boolean);
213
+ return parts[parts.length - 1] ?? projectPath;
214
+ }
215
+ function printPatternSummary(analyses) {
216
+ const byKind = {};
217
+ let exampleCount = 0;
218
+ for (const analysis of analyses) {
219
+ for (const pattern of analysis.patterns) {
220
+ byKind[pattern.kind] = (byKind[pattern.kind] ?? 0) + 1;
221
+ }
222
+ exampleCount += analysis.exampleInteractions.length;
223
+ }
224
+ if (Object.keys(byKind).length === 0 && exampleCount === 0)
225
+ return;
226
+ const labels = {
227
+ thinking_architecture: 'Architecture',
228
+ thinking_product: 'Product & UX',
229
+ thinking_quality: 'Quality & Debugging',
230
+ thinking_process: 'Process & Decisions'
231
+ };
232
+ if (Object.keys(byKind).length > 0) {
233
+ console.log(chalk.blue('Thinking patterns:'));
234
+ for (const [kind, count] of Object.entries(byKind).sort((a, b) => b[1] - a[1])) {
235
+ console.log(` ${labels[kind] ?? kind}: ${count}`);
236
+ }
237
+ }
238
+ if (exampleCount > 0) {
239
+ console.log(chalk.blue(`Example interactions: ${exampleCount}`));
240
+ }
241
+ }
242
+ async function handleReset(repoPath) {
243
+ // Remove session-derived records from lessons.jsonl
244
+ const filePath = resolveCanonicalLearningsPath(path.resolve(repoPath), 'lessons.jsonl');
245
+ if (fs.existsSync(filePath)) {
246
+ const dataset = loadCanonicalRecords(repoPath);
247
+ const nonSessionRecords = dataset.learnings.filter((r) => r.source_type !== 'coding_session');
248
+ writeLearningRecords(repoPath, nonSessionRecords);
249
+ console.log(chalk.green(`Removed session-derived learnings. ${nonSessionRecords.length} PR-derived learnings preserved.`));
250
+ }
251
+ // Clear session_analyses table
252
+ const dbManager = new DatabaseManager();
253
+ try {
254
+ await dbManager.runMigrations();
255
+ const db = dbManager.getDatabase();
256
+ db.prepare('DELETE FROM session_analyses').run();
257
+ console.log(chalk.green('Cleared session analysis cache.'));
258
+ }
259
+ catch {
260
+ // Table might not exist yet
261
+ }
262
+ finally {
263
+ dbManager.close();
264
+ }
265
+ // Rebuild
266
+ try {
267
+ await rebuildLearningsDatabase(repoPath);
268
+ console.log(chalk.green('Database rebuilt.'));
269
+ }
270
+ catch {
271
+ // OK if rebuild fails
272
+ }
273
+ }
274
+ //# sourceMappingURL=coding-sessions-command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coding-sessions-command.js","sourceRoot":"","sources":["../../src/learnings/coding-sessions-command.ts"],"names":[],"mappings":"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"}
@@ -40,7 +40,7 @@ export async function createFreshLearningsDatabase(repoPath, dbPath) {
40
40
  export function openLearningsDatabase(repoPath, options = {}) {
41
41
  const dbPath = getLearningsDbPath(repoPath);
42
42
  if (!fs.existsSync(dbPath)) {
43
- throw new Error(`Missing ${dbPath}. Run "ivan learnings rebuild --repo ${path.resolve(repoPath)}" first.`);
43
+ throw new Error(`Missing ${dbPath}. Run "ivan learn rebuild --repo ${path.resolve(repoPath)}" first.`);
44
44
  }
45
45
  const sqlite = new BetterSqlite3(dbPath, {
46
46
  readonly: options.readonly ?? false,
@@ -1 +1 @@
1
- {"version":3,"file":"database.js","sourceRoot":"","sources":["../../src/learnings/database.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,uFAAuF;AACvF,yFAAyF;AAEzF,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,aAAa,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAC/C,OAAO,KAAK,SAAS,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AA8BtE,0FAA0F;AAC1F,MAAM,UAAU,kBAAkB,CAAC,QAAgB;IACjD,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,0BAA0B,CAAC,CAAC;AACvE,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAChD,QAAgB,EAChB,MAAe;IAEf,MAAM,cAAc,GAAG,MAAM,IAAI,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IAC9D,4BAA4B,CAAC,cAAc,CAAC,CAAC;IAE7C,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAChE,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,cAAc,CAAC,CAAC;IACjD,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACvB,MAAM,CAAC,MAAM,CAAC,uBAAuB,CAAC,CAAC;IACvC,MAAM,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;IAEnC,MAAM,EAAE,GAAG,IAAI,MAAM,CAAoB;QACvC,OAAO,EAAE,IAAI,aAAa,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;KACjD,CAAC,CAAC;IACH,MAAM,IAAI,gBAAgB,CAAC,EAAE,EAAE,mBAAmB,CAAC,CAAC,aAAa,EAAE,CAAC;IACpE,OAAO,EAAE,CAAC;AACZ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CACnC,QAAgB,EAChB,UAAkC,EAAE;IAEpC,MAAM,MAAM,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IAC5C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CACb,WAAW,MAAM,wCAAwC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAC1F,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,MAAM,EAAE;QACvC,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,KAAK;QACnC,aAAa,EAAE,IAAI;KACpB,CAAC,CAAC;IACH,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACvB,MAAM,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;IAEnC,OAAO,IAAI,MAAM,CAAoB;QACnC,OAAO,EAAE,IAAI,aAAa,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;KACjD,CAAC,CAAC;AACL,CAAC;AAED,4GAA4G;AAC5G,SAAS,4BAA4B,CAAC,MAAc;IAClD,KAAK,MAAM,SAAS,IAAI,CAAC,MAAM,EAAE,GAAG,MAAM,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,EAAE,CAAC;QACnE,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC7B,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"database.js","sourceRoot":"","sources":["../../src/learnings/database.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,uFAAuF;AACvF,yFAAyF;AAEzF,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,aAAa,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAC/C,OAAO,KAAK,SAAS,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AA8BtE,0FAA0F;AAC1F,MAAM,UAAU,kBAAkB,CAAC,QAAgB;IACjD,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,0BAA0B,CAAC,CAAC;AACvE,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAChD,QAAgB,EAChB,MAAe;IAEf,MAAM,cAAc,GAAG,MAAM,IAAI,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IAC9D,4BAA4B,CAAC,cAAc,CAAC,CAAC;IAE7C,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAChE,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,cAAc,CAAC,CAAC;IACjD,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACvB,MAAM,CAAC,MAAM,CAAC,uBAAuB,CAAC,CAAC;IACvC,MAAM,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;IAEnC,MAAM,EAAE,GAAG,IAAI,MAAM,CAAoB;QACvC,OAAO,EAAE,IAAI,aAAa,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;KACjD,CAAC,CAAC;IACH,MAAM,IAAI,gBAAgB,CAAC,EAAE,EAAE,mBAAmB,CAAC,CAAC,aAAa,EAAE,CAAC;IACpE,OAAO,EAAE,CAAC;AACZ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CACnC,QAAgB,EAChB,UAAkC,EAAE;IAEpC,MAAM,MAAM,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IAC5C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CACb,WAAW,MAAM,oCAAoC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,UAAU,CACtF,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,MAAM,EAAE;QACvC,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,KAAK;QACnC,aAAa,EAAE,IAAI;KACpB,CAAC,CAAC;IACH,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACvB,MAAM,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;IAEnC,OAAO,IAAI,MAAM,CAAoB;QACnC,OAAO,EAAE,IAAI,aAAa,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;KACjD,CAAC,CAAC;AACL,CAAC;AAED,4GAA4G;AAC5G,SAAS,4BAA4B,CAAC,MAAc;IAClD,KAAK,MAAM,SAAS,IAAI,CAAC,MAAM,EAAE,GAAG,MAAM,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,EAAE,CAAC;QACnE,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC7B,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"embeddings.d.ts","sourceRoot":"","sources":["../../src/learnings/embeddings.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD,eAAO,MAAM,eAAe,2BAA2B,CAAC;AACxD,eAAO,MAAM,oBAAoB,OAAO,CAAC;AAQzC;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,CAU1E;AAED;;;GAGG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAM/D;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CASrE"}
1
+ {"version":3,"file":"embeddings.d.ts","sourceRoot":"","sources":["../../src/learnings/embeddings.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD,eAAO,MAAM,eAAe,2BAA2B,CAAC;AACxD,eAAO,MAAM,oBAAoB,OAAO,CAAC;AAsBzC;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,CAU1E;AAED;;;GAGG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAM/D;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CASrE"}
@@ -2,12 +2,25 @@
2
2
  // Requires OPENAI_API_KEY in the environment.
3
3
  // Embeddings are cached in JSONL source files so the API is only called once per record.
4
4
  import OpenAI from 'openai';
5
+ import { ConfigManager } from '../config.js';
5
6
  export const EMBEDDING_MODEL = 'text-embedding-3-small';
6
7
  export const EMBEDDING_DIMENSIONS = 1536;
7
8
  let _client;
8
9
  function getClient() {
9
- if (!_client)
10
- _client = new OpenAI();
10
+ if (!_client) {
11
+ const envKey = process.env['OPENAI_API_KEY'];
12
+ if (envKey) {
13
+ _client = new OpenAI();
14
+ }
15
+ else {
16
+ const config = new ConfigManager().getConfig();
17
+ const apiKey = config?.openaiApiKey;
18
+ if (!apiKey) {
19
+ throw new Error('No OpenAI API key found. Set OPENAI_API_KEY or run "ivan reconfigure".');
20
+ }
21
+ _client = new OpenAI({ apiKey });
22
+ }
23
+ }
11
24
  return _client;
12
25
  }
13
26
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"embeddings.js","sourceRoot":"","sources":["../../src/learnings/embeddings.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,8CAA8C;AAC9C,yFAAyF;AAEzF,OAAO,MAAM,MAAM,QAAQ,CAAC;AAG5B,MAAM,CAAC,MAAM,eAAe,GAAG,wBAAwB,CAAC;AACxD,MAAM,CAAC,MAAM,oBAAoB,GAAG,IAAI,CAAC;AAEzC,IAAI,OAA2B,CAAC;AAChC,SAAS,SAAS;IAChB,IAAI,CAAC,OAAO;QAAE,OAAO,GAAG,IAAI,MAAM,EAAE,CAAC;IACrC,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,yBAAyB,CAAC,QAAwB;IAChE,MAAM,SAAS,GAAG;QAChB,QAAQ,CAAC,IAAI;QACb,QAAQ,CAAC,KAAK;QACd,QAAQ,CAAC,SAAS;QAClB,QAAQ,CAAC,SAAS;QAClB,QAAQ,CAAC,aAAa;KACvB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAElB,OAAO,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC9B,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,IAAY;IAC1C,MAAM,QAAQ,GAAG,MAAM,SAAS,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC;QACnD,KAAK,EAAE,eAAe;QACtB,KAAK,EAAE,IAAI;KACZ,CAAC,CAAC;IACH,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACpC,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,KAAe;IAC9C,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAClC,MAAM,QAAQ,GAAG,MAAM,SAAS,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC;QACnD,KAAK,EAAE,eAAe;QACtB,KAAK,EAAE,KAAK;KACb,CAAC,CAAC;IACH,OAAO,QAAQ,CAAC,IAAI;SACjB,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;SACjC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;AAC7B,CAAC"}
1
+ {"version":3,"file":"embeddings.js","sourceRoot":"","sources":["../../src/learnings/embeddings.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,8CAA8C;AAC9C,yFAAyF;AAEzF,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAG7C,MAAM,CAAC,MAAM,eAAe,GAAG,wBAAwB,CAAC;AACxD,MAAM,CAAC,MAAM,oBAAoB,GAAG,IAAI,CAAC;AAEzC,IAAI,OAA2B,CAAC;AAChC,SAAS,SAAS;IAChB,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;QAC7C,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,GAAG,IAAI,MAAM,EAAE,CAAC;QACzB,CAAC;aAAM,CAAC;YACN,MAAM,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC,SAAS,EAAE,CAAC;YAC/C,MAAM,MAAM,GAAG,MAAM,EAAE,YAAY,CAAC;YACpC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM,IAAI,KAAK,CACb,wEAAwE,CACzE,CAAC;YACJ,CAAC;YACD,OAAO,GAAG,IAAI,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,yBAAyB,CAAC,QAAwB;IAChE,MAAM,SAAS,GAAG;QAChB,QAAQ,CAAC,IAAI;QACb,QAAQ,CAAC,KAAK;QACd,QAAQ,CAAC,SAAS;QAClB,QAAQ,CAAC,SAAS;QAClB,QAAQ,CAAC,aAAa;KACvB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAElB,OAAO,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC9B,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,IAAY;IAC1C,MAAM,QAAQ,GAAG,MAAM,SAAS,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC;QACnD,KAAK,EAAE,eAAe;QACtB,KAAK,EAAE,IAAI;KACZ,CAAC,CAAC;IACH,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACpC,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,KAAe;IAC9C,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAClC,MAAM,QAAQ,GAAG,MAAM,SAAS,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC;QACnD,KAAK,EAAE,eAAe;QACtB,KAAK,EAAE,KAAK;KACb,CAAC,CAAC;IACH,OAAO,QAAQ,CAAC,IAAI;SACjB,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;SACjC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;AAC7B,CAAC"}
@@ -3,7 +3,7 @@ import { initLearningsStore } from './init-command.js';
3
3
  import { installLearningsHooks } from './install-hooks-command.js';
4
4
  import { queryLearnings } from './query.js';
5
5
  import { rebuildLearningsDatabase } from './builder.js';
6
- /** Registers the `learnings` subcommand tree (init, rebuild, query, ingest-pr, ingest-repo, install-hooks) on `program`. */
6
+ /** Registers the `learn` subcommand tree on `program`. */
7
7
  export declare function registerLearningsCommands(program: Command): void;
8
8
  export { initLearningsStore, installLearningsHooks, queryLearnings, rebuildLearningsDatabase };
9
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/learnings/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,kBAAkB,EAAkB,MAAM,mBAAmB,CAAC;AAGvE,OAAO,EACL,qBAAqB,EAEtB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE5C,OAAO,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAGxD,4HAA4H;AAC5H,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAiEhE;AAED,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,cAAc,EACd,wBAAwB,EACzB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/learnings/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,kBAAkB,EAAkB,MAAM,mBAAmB,CAAC;AAGvE,OAAO,EACL,qBAAqB,EAEtB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE5C,OAAO,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAIxD,0DAA0D;AAC1D,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAgFhE;AAED,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,cAAc,EACd,wBAAwB,EACzB,CAAC"}
@@ -1,4 +1,4 @@
1
- // Entry point for the `learnings` command group.
1
+ // Entry point for the `learn` command group.
2
2
  // Registers all subcommands on the Commander program and re-exports the public API
3
3
  // used by other parts of ivan (task executor, hooks, etc.).
4
4
  import { initLearningsStore, runInitCommand } from './init-command.js';
@@ -9,47 +9,59 @@ import { queryLearnings } from './query.js';
9
9
  import { runQueryCommand } from './query-command.js';
10
10
  import { rebuildLearningsDatabase } from './builder.js';
11
11
  import { runRebuildCommand } from './rebuild-command.js';
12
- /** Registers the `learnings` subcommand tree (init, rebuild, query, ingest-pr, ingest-repo, install-hooks) on `program`. */
12
+ import { runCodingSessionsCommand } from './coding-sessions-command.js';
13
+ /** Registers the `learn` subcommand tree on `program`. */
13
14
  export function registerLearningsCommands(program) {
14
- const learnings = program
15
- .command('learnings')
16
- .description('Manage repo-local learnings records and derived .ivan/db.sqlite');
17
- learnings
15
+ const learn = program
16
+ .command('learn')
17
+ .alias('learnings')
18
+ .description('Learn from PRs, coding sessions, and repo history');
19
+ learn
18
20
  .command('init')
19
21
  .description('Initialize canonical learnings storage in the target repository')
20
22
  .requiredOption('--repo <path>', 'Repository root path')
21
23
  .action(runInitCommand);
22
- learnings
24
+ learn
23
25
  .command('rebuild')
24
26
  .description('Rebuild <repo>/.ivan/db.sqlite from canonical learnings records')
25
27
  .requiredOption('--repo <path>', 'Repository root path')
26
28
  .option('--if-stale', 'Skip rebuild if .ivan/db.sqlite is already up to date')
27
29
  .action(runRebuildCommand);
28
- learnings
30
+ learn
29
31
  .command('query')
30
32
  .description('Query the local .ivan/db.sqlite without live GitHub access')
31
33
  .requiredOption('--repo <path>', 'Repository root path')
32
34
  .requiredOption('--text <text>', 'Search text')
33
35
  .option('--limit <number>', 'Maximum learnings to return', '5')
34
36
  .action(runQueryCommand);
35
- learnings
37
+ learn
36
38
  .command('ingest-pr')
37
39
  .description('Fetch GitHub PR evidence and write canonical evidence records')
38
40
  .requiredOption('--repo <path>', 'Repository root path')
39
41
  .requiredOption('--pr <number>', 'Pull request number')
40
42
  .action(runIngestPrCommand);
41
- learnings
43
+ learn
42
44
  .command('ingest-repo')
43
45
  .description('Fetch evidence for all PRs in a repo and extract learnings in one pass')
44
46
  .requiredOption('--repo <path>', 'Repository root path')
45
47
  .option('--limit <number>', 'Maximum number of PRs to ingest', '100')
46
48
  .option('--state <state>', 'PR state to fetch: open, closed, merged, or all', 'merged')
47
49
  .action(runIngestRepoCommand);
48
- learnings
50
+ learn
49
51
  .command('install-hooks')
50
52
  .description('Install Claude Code hook scripts for UserPromptSubmit and PostToolUse(Edit|Write|MultiEdit)')
51
53
  .requiredOption('--repo <path>', 'Repository root path')
52
54
  .action(runInstallHooksCommand);
55
+ learn
56
+ .command('coding-sessions')
57
+ .description('Analyze local Claude Code sessions to extract thinking patterns and example interactions')
58
+ .requiredOption('--repo <path>', 'Repository root path')
59
+ .option('--project <name>', 'Only analyze sessions from a specific project')
60
+ .option('--recent <days>', 'Only analyze sessions from the last N days')
61
+ .option('--dry-run', 'Show what would be analyzed without making API calls')
62
+ .option('--force', 'Re-analyze all sessions, ignoring cache')
63
+ .option('--reset', 'Clear session analysis cache and session-derived learnings')
64
+ .action(runCodingSessionsCommand);
53
65
  }
54
66
  export { initLearningsStore, installLearningsHooks, queryLearnings, rebuildLearningsDatabase };
55
67
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/learnings/index.ts"],"names":[],"mappings":"AAAA,iDAAiD;AACjD,mFAAmF;AACnF,4DAA4D;AAG5D,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACvB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAEzD,4HAA4H;AAC5H,MAAM,UAAU,yBAAyB,CAAC,OAAgB;IACxD,MAAM,SAAS,GAAG,OAAO;SACtB,OAAO,CAAC,WAAW,CAAC;SACpB,WAAW,CACV,iEAAiE,CAClE,CAAC;IAEJ,SAAS;SACN,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CACV,iEAAiE,CAClE;SACA,cAAc,CAAC,eAAe,EAAE,sBAAsB,CAAC;SACvD,MAAM,CAAC,cAAc,CAAC,CAAC;IAE1B,SAAS;SACN,OAAO,CAAC,SAAS,CAAC;SAClB,WAAW,CACV,iEAAiE,CAClE;SACA,cAAc,CAAC,eAAe,EAAE,sBAAsB,CAAC;SACvD,MAAM,CACL,YAAY,EACZ,uDAAuD,CACxD;SACA,MAAM,CAAC,iBAAiB,CAAC,CAAC;IAE7B,SAAS;SACN,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,4DAA4D,CAAC;SACzE,cAAc,CAAC,eAAe,EAAE,sBAAsB,CAAC;SACvD,cAAc,CAAC,eAAe,EAAE,aAAa,CAAC;SAC9C,MAAM,CAAC,kBAAkB,EAAE,6BAA6B,EAAE,GAAG,CAAC;SAC9D,MAAM,CAAC,eAAe,CAAC,CAAC;IAE3B,SAAS;SACN,OAAO,CAAC,WAAW,CAAC;SACpB,WAAW,CACV,+DAA+D,CAChE;SACA,cAAc,CAAC,eAAe,EAAE,sBAAsB,CAAC;SACvD,cAAc,CAAC,eAAe,EAAE,qBAAqB,CAAC;SACtD,MAAM,CAAC,kBAAkB,CAAC,CAAC;IAE9B,SAAS;SACN,OAAO,CAAC,aAAa,CAAC;SACtB,WAAW,CACV,wEAAwE,CACzE;SACA,cAAc,CAAC,eAAe,EAAE,sBAAsB,CAAC;SACvD,MAAM,CAAC,kBAAkB,EAAE,iCAAiC,EAAE,KAAK,CAAC;SACpE,MAAM,CACL,iBAAiB,EACjB,iDAAiD,EACjD,QAAQ,CACT;SACA,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAEhC,SAAS;SACN,OAAO,CAAC,eAAe,CAAC;SACxB,WAAW,CACV,6FAA6F,CAC9F;SACA,cAAc,CAAC,eAAe,EAAE,sBAAsB,CAAC;SACvD,MAAM,CAAC,sBAAsB,CAAC,CAAC;AACpC,CAAC;AAED,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,cAAc,EACd,wBAAwB,EACzB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/learnings/index.ts"],"names":[],"mappings":"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"}
@@ -171,7 +171,7 @@ if [[ -z "$repo" || -z "$prompt" ]]; then
171
171
  exit 0
172
172
  fi
173
173
 
174
- output="$("$ivan_entry" learnings query --repo "$repo" --text "$prompt" --limit 3 2>>"$log_dir/query.stderr")" || true
174
+ output="$("$ivan_entry" learn query --repo "$repo" --text "$prompt" --limit 3 2>>"$log_dir/query.stderr")" || true
175
175
 
176
176
  if [[ -z "$output" || "$output" == *"No learnings matched that query."* ]]; then
177
177
  exit 0
@@ -211,7 +211,7 @@ fi
211
211
 
212
212
  query_text="recent file changes after tool: $tool_name; input: $tool_input"
213
213
 
214
- output="$("$ivan_entry" learnings query --repo "$repo" --text "$query_text" --limit 3 2>>"$log_dir/query.stderr")" || true
214
+ output="$("$ivan_entry" learn query --repo "$repo" --text "$query_text" --limit 3 2>>"$log_dir/query.stderr")" || true
215
215
 
216
216
  if [[ -z "$output" || "$output" == *"No learnings matched that query."* ]]; then
217
217
  exit 0
@@ -0,0 +1,39 @@
1
+ import type { LearningRecord } from './record-types.js';
2
+ import type { SessionDigest } from './session-parser.js';
3
+ export interface SessionAnalysis {
4
+ sessionId: string;
5
+ hasSignal: boolean;
6
+ sessionTopic: string;
7
+ patterns: ExtractedPattern[];
8
+ exampleInteractions: ExtractedInteraction[];
9
+ }
10
+ interface ExtractedPattern {
11
+ statement: string;
12
+ kind: 'thinking_architecture' | 'thinking_product' | 'thinking_quality' | 'thinking_process';
13
+ confidence: number;
14
+ rationale: string | null;
15
+ applicability: string | null;
16
+ }
17
+ interface ExtractedInteraction {
18
+ context: string;
19
+ user_message: string;
20
+ derived_question: string;
21
+ when_to_ask: string;
22
+ confidence: number;
23
+ }
24
+ export declare class SessionAnalyzer {
25
+ private client;
26
+ private getClient;
27
+ /**
28
+ * Analyzes a single session digest and extracts thinking patterns + example interactions.
29
+ */
30
+ analyzeSession(digest: SessionDigest): Promise<SessionAnalysis>;
31
+ /**
32
+ * Converts analysis results into LearningRecord objects ready for storage.
33
+ * Both thinking patterns and example interactions become learning records.
34
+ * Each record is tagged with its source project for relevance filtering.
35
+ */
36
+ analysisToLearningRecords(analysis: SessionAnalysis, digest: SessionDigest): LearningRecord[];
37
+ }
38
+ export {};
39
+ //# sourceMappingURL=session-analyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-analyzer.d.ts","sourceRoot":"","sources":["../../src/learnings/session-analyzer.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAIzD,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,gBAAgB,EAAE,CAAC;IAC7B,mBAAmB,EAAE,oBAAoB,EAAE,CAAC;CAC7C;AAED,UAAU,gBAAgB;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EACA,uBAAuB,GACvB,kBAAkB,GAClB,kBAAkB,GAClB,kBAAkB,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,UAAU,oBAAoB;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAgJD,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAuB;IAErC,OAAO,CAAC,SAAS;IAoBjB;;OAEG;IACG,cAAc,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,eAAe,CAAC;IAqDrE;;;;OAIG;IACH,yBAAyB,CACvB,QAAQ,EAAE,eAAe,EACzB,MAAM,EAAE,aAAa,GACpB,cAAc,EAAE;CAkEpB"}