@timmeck/brain-core 2.16.0 → 2.17.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 (35) hide show
  1. package/dist/codegen/code-generator.d.ts +42 -0
  2. package/dist/codegen/code-generator.js +225 -0
  3. package/dist/codegen/code-generator.js.map +1 -0
  4. package/dist/codegen/code-miner.d.ts +45 -0
  5. package/dist/codegen/code-miner.js +243 -0
  6. package/dist/codegen/code-miner.js.map +1 -0
  7. package/dist/codegen/context-builder.d.ts +15 -0
  8. package/dist/codegen/context-builder.js +137 -0
  9. package/dist/codegen/context-builder.js.map +1 -0
  10. package/dist/codegen/index.d.ts +5 -0
  11. package/dist/codegen/index.js +5 -0
  12. package/dist/codegen/index.js.map +1 -0
  13. package/dist/codegen/pattern-extractor.d.ts +25 -0
  14. package/dist/codegen/pattern-extractor.js +222 -0
  15. package/dist/codegen/pattern-extractor.js.map +1 -0
  16. package/dist/codegen/types.d.ts +127 -0
  17. package/dist/codegen/types.js +3 -0
  18. package/dist/codegen/types.js.map +1 -0
  19. package/dist/index.d.ts +6 -1
  20. package/dist/index.js +6 -1
  21. package/dist/index.js.map +1 -1
  22. package/dist/prediction/types.d.ts +1 -1
  23. package/dist/research/adapters/index.d.ts +1 -0
  24. package/dist/research/adapters/index.js +1 -0
  25. package/dist/research/adapters/index.js.map +1 -1
  26. package/dist/research/adapters/scanner-adapter.d.ts +14 -0
  27. package/dist/research/adapters/scanner-adapter.js +209 -0
  28. package/dist/research/adapters/scanner-adapter.js.map +1 -0
  29. package/dist/research/data-miner.d.ts +3 -1
  30. package/dist/research/data-miner.js +79 -69
  31. package/dist/research/data-miner.js.map +1 -1
  32. package/dist/research/research-orchestrator.d.ts +9 -1
  33. package/dist/research/research-orchestrator.js +41 -2
  34. package/dist/research/research-orchestrator.js.map +1 -1
  35. package/package.json +1 -1
@@ -0,0 +1,42 @@
1
+ import type Database from 'better-sqlite3';
2
+ import type { ContextBuilder } from './context-builder.js';
3
+ import type { ResearchJournal } from '../research/journal.js';
4
+ import type { KnowledgeDistiller } from '../research/knowledge-distiller.js';
5
+ import type { ThoughtStream } from '../consciousness/thought-stream.js';
6
+ import type { CodeGeneratorConfig, GenerationRequest, GenerationResult, GenerationRecord, GenerationStatus, CodeGeneratorSummary } from './types.js';
7
+ export declare function runCodeGeneratorMigration(db: Database.Database): void;
8
+ export declare class CodeGenerator {
9
+ private db;
10
+ private brainName;
11
+ private apiKey;
12
+ private model;
13
+ private maxTokens;
14
+ private maxPerHour;
15
+ private contextBuilder;
16
+ private journal;
17
+ private knowledgeDistiller;
18
+ private thoughtStream;
19
+ private recentGenerations;
20
+ private log;
21
+ constructor(db: Database.Database, config: CodeGeneratorConfig);
22
+ setContextBuilder(builder: ContextBuilder): void;
23
+ setJournal(journal: ResearchJournal): void;
24
+ setKnowledgeDistiller(distiller: KnowledgeDistiller): void;
25
+ setThoughtStream(stream: ThoughtStream): void;
26
+ /** Generate code using Claude API with brain knowledge as context. */
27
+ generate(request: GenerationRequest): Promise<GenerationResult>;
28
+ /** Approve a generated code. */
29
+ approve(id: number, notes?: string): GenerationRecord | null;
30
+ /** Reject a generated code. */
31
+ reject(id: number, notes?: string): GenerationRecord | null;
32
+ /** Get a generation by ID. */
33
+ get(id: number): GenerationResult | null;
34
+ /** Get a generation record with review fields. */
35
+ getRecord(id: number): GenerationRecord | null;
36
+ /** List generations with optional filters. */
37
+ list(status?: GenerationStatus, limit?: number): GenerationResult[];
38
+ /** Get summary stats. */
39
+ getSummary(): CodeGeneratorSummary;
40
+ private callClaudeApi;
41
+ private cleanupRateLimit;
42
+ }
@@ -0,0 +1,225 @@
1
+ import { getLogger } from '../utils/logger.js';
2
+ // ── Migration ────────────────────────────────────────────
3
+ export function runCodeGeneratorMigration(db) {
4
+ db.exec(`
5
+ CREATE TABLE IF NOT EXISTS code_generations (
6
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
7
+ task TEXT NOT NULL,
8
+ trigger TEXT NOT NULL DEFAULT 'manual',
9
+ status TEXT NOT NULL DEFAULT 'generating',
10
+ context_summary TEXT DEFAULT '',
11
+ principles_used INTEGER DEFAULT 0,
12
+ anti_patterns_used INTEGER DEFAULT 0,
13
+ patterns_used INTEGER DEFAULT 0,
14
+ generated_code TEXT,
15
+ generated_explanation TEXT,
16
+ target_file TEXT,
17
+ language TEXT DEFAULT 'typescript',
18
+ validation_passed INTEGER,
19
+ validation_errors TEXT,
20
+ review_notes TEXT,
21
+ tokens_used INTEGER DEFAULT 0,
22
+ generation_time_ms INTEGER DEFAULT 0,
23
+ model_used TEXT DEFAULT '',
24
+ created_at TEXT DEFAULT (datetime('now')),
25
+ completed_at TEXT,
26
+ reviewed_at TEXT
27
+ );
28
+ `);
29
+ }
30
+ // ── CodeGenerator ────────────────────────────────────────
31
+ export class CodeGenerator {
32
+ db;
33
+ brainName;
34
+ apiKey;
35
+ model;
36
+ maxTokens;
37
+ maxPerHour;
38
+ contextBuilder = null;
39
+ journal = null;
40
+ knowledgeDistiller = null;
41
+ thoughtStream = null;
42
+ recentGenerations = [];
43
+ log = getLogger();
44
+ constructor(db, config) {
45
+ this.db = db;
46
+ this.brainName = config.brainName;
47
+ this.apiKey = config.apiKey ?? process.env.ANTHROPIC_API_KEY ?? null;
48
+ this.model = config.model ?? 'claude-sonnet-4-20250514';
49
+ this.maxTokens = config.maxTokens ?? 4096;
50
+ this.maxPerHour = config.maxPerHour ?? 10;
51
+ runCodeGeneratorMigration(db);
52
+ }
53
+ setContextBuilder(builder) { this.contextBuilder = builder; }
54
+ setJournal(journal) { this.journal = journal; }
55
+ setKnowledgeDistiller(distiller) { this.knowledgeDistiller = distiller; }
56
+ setThoughtStream(stream) { this.thoughtStream = stream; }
57
+ /** Generate code using Claude API with brain knowledge as context. */
58
+ async generate(request) {
59
+ if (!this.apiKey) {
60
+ throw new Error('ANTHROPIC_API_KEY not configured — CodeGenerator requires an API key');
61
+ }
62
+ // Rate limiting
63
+ this.cleanupRateLimit();
64
+ if (this.recentGenerations.length >= this.maxPerHour) {
65
+ throw new Error(`Rate limit exceeded: max ${this.maxPerHour} generations per hour`);
66
+ }
67
+ const ts = this.thoughtStream;
68
+ ts?.emit('code_generator', 'analyzing', `Generating code: ${request.task.substring(0, 80)}...`);
69
+ const startTime = Date.now();
70
+ // Build context from brain knowledge
71
+ let contextSummary = '';
72
+ let principlesUsed = 0;
73
+ let antiPatternsUsed = 0;
74
+ let patternsUsed = 0;
75
+ let systemPrompt = request.task;
76
+ if (this.contextBuilder) {
77
+ const ctx = this.contextBuilder.build(request);
78
+ systemPrompt = ctx.systemPrompt;
79
+ principlesUsed = ctx.principlesUsed;
80
+ antiPatternsUsed = ctx.antiPatternsUsed;
81
+ patternsUsed = ctx.patternsUsed;
82
+ contextSummary = `${principlesUsed} principles, ${antiPatternsUsed} anti-patterns, ${patternsUsed} patterns, ~${ctx.totalTokensEstimate} tokens`;
83
+ }
84
+ // Insert initial record
85
+ const insertResult = this.db.prepare(`
86
+ INSERT INTO code_generations (task, trigger, status, context_summary, principles_used, anti_patterns_used, patterns_used, target_file, language, model_used)
87
+ VALUES (?, ?, 'generating', ?, ?, ?, ?, ?, ?, ?)
88
+ `).run(request.task, request.trigger ?? 'manual', contextSummary, principlesUsed, antiPatternsUsed, patternsUsed, request.target_file ?? null, request.language ?? 'typescript', this.model);
89
+ const id = Number(insertResult.lastInsertRowid);
90
+ try {
91
+ // Call Claude API
92
+ ts?.emit('code_generator', 'analyzing', `Calling Claude API (${this.model})...`);
93
+ const { code, explanation, tokensUsed } = await this.callClaudeApi(systemPrompt, request.task);
94
+ const generationTime = Date.now() - startTime;
95
+ // Update record with results
96
+ this.db.prepare(`
97
+ UPDATE code_generations
98
+ SET status = 'generated', generated_code = ?, generated_explanation = ?,
99
+ tokens_used = ?, generation_time_ms = ?, completed_at = datetime('now')
100
+ WHERE id = ?
101
+ `).run(code, explanation, tokensUsed, generationTime, id);
102
+ this.recentGenerations.push(Date.now());
103
+ ts?.emit('code_generator', 'discovering', `Code generated (${tokensUsed} tokens, ${generationTime}ms)`, 'notable');
104
+ // Journal the generation
105
+ this.journal?.recordDiscovery(`Code generated: ${request.task.substring(0, 60)}`, `CodeGenerator produced ${code?.length ?? 0} chars of ${request.language ?? 'typescript'} code. ${contextSummary}`, { id, trigger: request.trigger, tokensUsed, generationTime }, 'notable');
106
+ return this.get(id);
107
+ }
108
+ catch (err) {
109
+ const generationTime = Date.now() - startTime;
110
+ this.db.prepare(`
111
+ UPDATE code_generations
112
+ SET status = 'failed', generated_explanation = ?, generation_time_ms = ?, completed_at = datetime('now')
113
+ WHERE id = ?
114
+ `).run(err.message, generationTime, id);
115
+ ts?.emit('code_generator', 'analyzing', `Generation failed: ${err.message}`);
116
+ this.log.error(`[code-generator] Generation failed: ${err.message}`);
117
+ return this.get(id);
118
+ }
119
+ }
120
+ /** Approve a generated code. */
121
+ approve(id, notes) {
122
+ this.db.prepare(`
123
+ UPDATE code_generations SET status = 'approved', review_notes = ?, reviewed_at = datetime('now')
124
+ WHERE id = ? AND status IN ('generated', 'pending_review')
125
+ `).run(notes ?? null, id);
126
+ const record = this.getRecord(id);
127
+ if (record && record.status === 'approved') {
128
+ this.journal?.recordDiscovery(`Code approved: ${record.task.substring(0, 60)}`, `Generation #${id} approved.${notes ? ` Notes: ${notes}` : ''}`, { id, task: record.task }, 'notable');
129
+ this.thoughtStream?.emit('code_generator', 'discovering', `Code #${id} approved`, 'notable');
130
+ }
131
+ return record;
132
+ }
133
+ /** Reject a generated code. */
134
+ reject(id, notes) {
135
+ this.db.prepare(`
136
+ UPDATE code_generations SET status = 'rejected', review_notes = ?, reviewed_at = datetime('now')
137
+ WHERE id = ? AND status IN ('generated', 'pending_review')
138
+ `).run(notes ?? null, id);
139
+ const record = this.getRecord(id);
140
+ if (record && record.status === 'rejected') {
141
+ this.journal?.recordExperiment(`Code rejected: ${record.task.substring(0, 60)}`, 'rejected', { id, task: record.task, notes }, false);
142
+ }
143
+ return record;
144
+ }
145
+ /** Get a generation by ID. */
146
+ get(id) {
147
+ return this.db.prepare('SELECT * FROM code_generations WHERE id = ?').get(id);
148
+ }
149
+ /** Get a generation record with review fields. */
150
+ getRecord(id) {
151
+ return this.db.prepare('SELECT * FROM code_generations WHERE id = ?').get(id);
152
+ }
153
+ /** List generations with optional filters. */
154
+ list(status, limit = 20) {
155
+ if (status) {
156
+ return this.db.prepare('SELECT * FROM code_generations WHERE status = ? ORDER BY id DESC LIMIT ?').all(status, limit);
157
+ }
158
+ return this.db.prepare('SELECT * FROM code_generations ORDER BY id DESC LIMIT ?').all(limit);
159
+ }
160
+ /** Get summary stats. */
161
+ getSummary() {
162
+ const total = this.db.prepare('SELECT COUNT(*) as c FROM code_generations').get().c;
163
+ const byStatusRows = this.db.prepare('SELECT status, COUNT(*) as c FROM code_generations GROUP BY status').all();
164
+ const byStatus = {};
165
+ for (const r of byStatusRows)
166
+ byStatus[r.status] = r.c;
167
+ const byTriggerRows = this.db.prepare('SELECT trigger, COUNT(*) as c FROM code_generations GROUP BY trigger').all();
168
+ const byTrigger = {};
169
+ for (const r of byTriggerRows)
170
+ byTrigger[r.trigger] = r.c;
171
+ const tokens = this.db.prepare('SELECT COALESCE(SUM(tokens_used), 0) as t FROM code_generations').get().t;
172
+ const avgTime = this.db.prepare('SELECT COALESCE(AVG(generation_time_ms), 0) as a FROM code_generations WHERE status != \'generating\'').get().a;
173
+ const approved = (byStatus['approved'] ?? 0);
174
+ const rejected = (byStatus['rejected'] ?? 0);
175
+ const reviewed = approved + rejected;
176
+ const last = this.db.prepare('SELECT MAX(created_at) as t FROM code_generations').get();
177
+ return {
178
+ total_generations: total,
179
+ by_status: byStatus,
180
+ by_trigger: byTrigger,
181
+ total_tokens_used: tokens,
182
+ avg_generation_time_ms: Math.round(avgTime),
183
+ approval_rate: reviewed > 0 ? approved / reviewed : 0,
184
+ last_generation_at: last.t,
185
+ };
186
+ }
187
+ // ── Private ──────────────────────────────────────────────
188
+ async callClaudeApi(systemPrompt, userMessage) {
189
+ // Use raw fetch to Anthropic API — avoids @anthropic-ai/sdk dependency
190
+ const response = await fetch('https://api.anthropic.com/v1/messages', {
191
+ method: 'POST',
192
+ headers: {
193
+ 'Content-Type': 'application/json',
194
+ 'x-api-key': this.apiKey,
195
+ 'anthropic-version': '2023-06-01',
196
+ },
197
+ body: JSON.stringify({
198
+ model: this.model,
199
+ max_tokens: this.maxTokens,
200
+ system: systemPrompt,
201
+ messages: [{ role: 'user', content: userMessage }],
202
+ }),
203
+ });
204
+ if (!response.ok) {
205
+ const err = await response.text();
206
+ throw new Error(`Anthropic API error (${response.status}): ${err.substring(0, 200)}`);
207
+ }
208
+ const data = await response.json();
209
+ const text = data.content
210
+ ?.filter(block => block.type === 'text')
211
+ .map(block => block.text ?? '')
212
+ .join('\n') ?? '';
213
+ const tokensUsed = (data.usage?.input_tokens ?? 0) + (data.usage?.output_tokens ?? 0);
214
+ // Parse code block from response
215
+ const codeMatch = text.match(/```(?:\w+)?\n([\s\S]*?)```/);
216
+ const code = codeMatch ? codeMatch[1].trim() : text;
217
+ const explanation = text.replace(/```(?:\w+)?\n[\s\S]*?```/g, '').trim() || null;
218
+ return { code, explanation, tokensUsed };
219
+ }
220
+ cleanupRateLimit() {
221
+ const oneHourAgo = Date.now() - 3_600_000;
222
+ this.recentGenerations = this.recentGenerations.filter(t => t > oneHourAgo);
223
+ }
224
+ }
225
+ //# sourceMappingURL=code-generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-generator.js","sourceRoot":"","sources":["../../src/codegen/code-generator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ import type Database from 'better-sqlite3';
2
+ import type { CodeMinerConfig, RepoContent, CodeMinerSummary } from './types.js';
3
+ export declare function runCodeMinerMigration(db: Database.Database): void;
4
+ export declare class CodeMiner {
5
+ private db;
6
+ private githubToken;
7
+ private maxRepos;
8
+ private batchSize;
9
+ private delayMs;
10
+ private aborted;
11
+ private mining;
12
+ private lastMinedAt;
13
+ private log;
14
+ constructor(db: Database.Database, config?: CodeMinerConfig);
15
+ /** Bootstrap: fetch contents for all signal+breakout repos that haven't been mined yet. */
16
+ bootstrap(): Promise<{
17
+ mined: number;
18
+ errors: number;
19
+ }>;
20
+ /** Incremental: fetch contents for new/changed top repos. */
21
+ mine(): Promise<{
22
+ mined: number;
23
+ errors: number;
24
+ }>;
25
+ /** Fetch README, package.json, and root tree for a single repo. */
26
+ fetchRepoContents(fullName: string): Promise<Array<{
27
+ path: string;
28
+ content: string | null;
29
+ }>>;
30
+ /** Get stored content for a repo. */
31
+ getRepoContent(repoId: number, filePath: string): RepoContent | null;
32
+ /** Aggregate: which npm packages are used most across mined repos. */
33
+ getTopDependencies(limit?: number): Array<{
34
+ name: string;
35
+ count: number;
36
+ }>;
37
+ /** Analyze package.json for architecture patterns (scripts, engines, type). */
38
+ getArchitecturePatterns(): Record<string, number>;
39
+ /** Stats summary. */
40
+ getSummary(): CodeMinerSummary;
41
+ /** Abort an in-progress mining operation. */
42
+ abort(): void;
43
+ private mineRepos;
44
+ private delay;
45
+ }
@@ -0,0 +1,243 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { getLogger } from '../utils/logger.js';
3
+ // ── Migration ────────────────────────────────────────────
4
+ export function runCodeMinerMigration(db) {
5
+ db.exec(`
6
+ CREATE TABLE IF NOT EXISTS repo_contents (
7
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
8
+ repo_id INTEGER NOT NULL,
9
+ file_path TEXT NOT NULL,
10
+ content TEXT,
11
+ content_hash TEXT,
12
+ fetched_at TEXT DEFAULT (datetime('now')),
13
+ UNIQUE(repo_id, file_path)
14
+ );
15
+ CREATE INDEX IF NOT EXISTS idx_repo_contents_repo ON repo_contents(repo_id);
16
+ `);
17
+ }
18
+ // ── CodeMiner ────────────────────────────────────────────
19
+ export class CodeMiner {
20
+ db;
21
+ githubToken;
22
+ maxRepos;
23
+ batchSize;
24
+ delayMs;
25
+ aborted = false;
26
+ mining = false;
27
+ lastMinedAt = null;
28
+ log = getLogger();
29
+ constructor(db, config = {}) {
30
+ this.db = db;
31
+ this.githubToken = config.githubToken ?? process.env.GITHUB_TOKEN ?? null;
32
+ this.maxRepos = config.maxRepos ?? 50;
33
+ this.batchSize = config.batchSize ?? 50;
34
+ this.delayMs = config.delayMs ?? 1200;
35
+ runCodeMinerMigration(db);
36
+ }
37
+ /** Bootstrap: fetch contents for all signal+breakout repos that haven't been mined yet. */
38
+ async bootstrap() {
39
+ if (!this.githubToken) {
40
+ this.log.info('[code-miner] No GITHUB_TOKEN — skipping bootstrap');
41
+ return { mined: 0, errors: 0 };
42
+ }
43
+ const unmined = this.db.prepare(`
44
+ SELECT sr.id, sr.full_name
45
+ FROM scanned_repos sr
46
+ WHERE sr.signal_level IN ('breakout', 'signal')
47
+ AND sr.id NOT IN (SELECT DISTINCT repo_id FROM repo_contents)
48
+ ORDER BY sr.signal_score DESC
49
+ LIMIT ?
50
+ `).all(this.maxRepos);
51
+ if (unmined.length === 0) {
52
+ this.log.info('[code-miner] Bootstrap: all top repos already mined');
53
+ return { mined: 0, errors: 0 };
54
+ }
55
+ this.log.info(`[code-miner] Bootstrap: mining ${unmined.length} repos`);
56
+ return this.mineRepos(unmined);
57
+ }
58
+ /** Incremental: fetch contents for new/changed top repos. */
59
+ async mine() {
60
+ if (this.mining || !this.githubToken) {
61
+ return { mined: 0, errors: 0 };
62
+ }
63
+ const newRepos = this.db.prepare(`
64
+ SELECT sr.id, sr.full_name
65
+ FROM scanned_repos sr
66
+ WHERE sr.signal_level IN ('breakout', 'signal')
67
+ AND sr.id NOT IN (SELECT DISTINCT repo_id FROM repo_contents)
68
+ ORDER BY sr.signal_score DESC
69
+ LIMIT ?
70
+ `).all(this.batchSize);
71
+ if (newRepos.length === 0)
72
+ return { mined: 0, errors: 0 };
73
+ return this.mineRepos(newRepos);
74
+ }
75
+ /** Fetch README, package.json, and root tree for a single repo. */
76
+ async fetchRepoContents(fullName) {
77
+ if (!this.githubToken)
78
+ return [];
79
+ const results = [];
80
+ const headers = {
81
+ Authorization: `token ${this.githubToken}`,
82
+ Accept: 'application/vnd.github.v3+json',
83
+ 'User-Agent': 'brain-ecosystem-code-miner',
84
+ };
85
+ // 1. README
86
+ try {
87
+ const readmeRes = await fetch(`https://api.github.com/repos/${fullName}/readme`, { headers });
88
+ if (readmeRes.ok) {
89
+ const data = await readmeRes.json();
90
+ if (data.content && data.encoding === 'base64') {
91
+ const decoded = Buffer.from(data.content, 'base64').toString('utf-8');
92
+ results.push({ path: 'README.md', content: decoded.substring(0, 100_000) });
93
+ }
94
+ }
95
+ }
96
+ catch { /* skip */ }
97
+ await this.delay();
98
+ // 2. package.json
99
+ try {
100
+ const pkgRes = await fetch(`https://api.github.com/repos/${fullName}/contents/package.json`, { headers });
101
+ if (pkgRes.ok) {
102
+ const data = await pkgRes.json();
103
+ if (data.content && data.encoding === 'base64') {
104
+ const decoded = Buffer.from(data.content, 'base64').toString('utf-8');
105
+ results.push({ path: 'package.json', content: decoded.substring(0, 100_000) });
106
+ }
107
+ }
108
+ }
109
+ catch { /* skip */ }
110
+ await this.delay();
111
+ // 3. Root directory listing
112
+ try {
113
+ const treeRes = await fetch(`https://api.github.com/repos/${fullName}/contents`, { headers });
114
+ if (treeRes.ok) {
115
+ const items = await treeRes.json();
116
+ const listing = items.map(i => `${i.type === 'dir' ? 'd' : 'f'} ${i.name}${i.size ? ` (${i.size}B)` : ''}`).join('\n');
117
+ results.push({ path: 'tree', content: listing });
118
+ }
119
+ }
120
+ catch { /* skip */ }
121
+ return results;
122
+ }
123
+ /** Get stored content for a repo. */
124
+ getRepoContent(repoId, filePath) {
125
+ return this.db.prepare('SELECT * FROM repo_contents WHERE repo_id = ? AND file_path = ?').get(repoId, filePath);
126
+ }
127
+ /** Aggregate: which npm packages are used most across mined repos. */
128
+ getTopDependencies(limit = 20) {
129
+ const rows = this.db.prepare(`
130
+ SELECT content FROM repo_contents WHERE file_path = 'package.json' AND content IS NOT NULL
131
+ `).all();
132
+ const counts = new Map();
133
+ for (const row of rows) {
134
+ try {
135
+ const pkg = JSON.parse(row.content);
136
+ const deps = { ...(pkg.dependencies ?? {}), ...(pkg.devDependencies ?? {}) };
137
+ for (const name of Object.keys(deps)) {
138
+ counts.set(name, (counts.get(name) ?? 0) + 1);
139
+ }
140
+ }
141
+ catch { /* skip invalid JSON */ }
142
+ }
143
+ return [...counts.entries()]
144
+ .sort((a, b) => b[1] - a[1])
145
+ .slice(0, limit)
146
+ .map(([name, count]) => ({ name, count }));
147
+ }
148
+ /** Analyze package.json for architecture patterns (scripts, engines, type). */
149
+ getArchitecturePatterns() {
150
+ const rows = this.db.prepare(`
151
+ SELECT content FROM repo_contents WHERE file_path = 'package.json' AND content IS NOT NULL
152
+ `).all();
153
+ const patterns = {};
154
+ for (const row of rows) {
155
+ try {
156
+ const pkg = JSON.parse(row.content);
157
+ if (pkg.type === 'module')
158
+ patterns['esm'] = (patterns['esm'] ?? 0) + 1;
159
+ if (pkg.type === 'commonjs' || !pkg.type)
160
+ patterns['cjs'] = (patterns['cjs'] ?? 0) + 1;
161
+ const scripts = pkg.scripts;
162
+ if (scripts) {
163
+ if (scripts.test?.includes('vitest'))
164
+ patterns['vitest'] = (patterns['vitest'] ?? 0) + 1;
165
+ if (scripts.test?.includes('jest'))
166
+ patterns['jest'] = (patterns['jest'] ?? 0) + 1;
167
+ if (scripts.build?.includes('tsc'))
168
+ patterns['tsc'] = (patterns['tsc'] ?? 0) + 1;
169
+ if (scripts.build?.includes('esbuild'))
170
+ patterns['esbuild'] = (patterns['esbuild'] ?? 0) + 1;
171
+ if (scripts.build?.includes('rollup'))
172
+ patterns['rollup'] = (patterns['rollup'] ?? 0) + 1;
173
+ }
174
+ const deps = pkg.dependencies;
175
+ if (deps?.typescript || pkg.devDependencies?.typescript) {
176
+ patterns['typescript'] = (patterns['typescript'] ?? 0) + 1;
177
+ }
178
+ }
179
+ catch { /* skip */ }
180
+ }
181
+ return patterns;
182
+ }
183
+ /** Stats summary. */
184
+ getSummary() {
185
+ const total = this.db.prepare('SELECT COUNT(DISTINCT repo_id) as c FROM repo_contents').get();
186
+ const contents = this.db.prepare('SELECT COUNT(*) as c FROM repo_contents').get();
187
+ const size = this.db.prepare('SELECT COALESCE(SUM(LENGTH(content)), 0) as s FROM repo_contents').get();
188
+ const last = this.db.prepare('SELECT MAX(fetched_at) as t FROM repo_contents').get();
189
+ const byFile = this.db.prepare('SELECT file_path, COUNT(*) as count FROM repo_contents GROUP BY file_path').all();
190
+ return {
191
+ total_repos_mined: total.c,
192
+ total_contents: contents.c,
193
+ total_size_bytes: size.s,
194
+ last_mined_at: last.t,
195
+ by_file: byFile,
196
+ };
197
+ }
198
+ /** Abort an in-progress mining operation. */
199
+ abort() {
200
+ this.aborted = true;
201
+ }
202
+ // ── Private ──────────────────────────────────────────────
203
+ async mineRepos(repos) {
204
+ this.mining = true;
205
+ this.aborted = false;
206
+ let mined = 0;
207
+ let errors = 0;
208
+ const upsert = this.db.prepare(`
209
+ INSERT INTO repo_contents (repo_id, file_path, content, content_hash)
210
+ VALUES (?, ?, ?, ?)
211
+ ON CONFLICT(repo_id, file_path) DO UPDATE SET
212
+ content = excluded.content,
213
+ content_hash = excluded.content_hash,
214
+ fetched_at = datetime('now')
215
+ `);
216
+ for (const repo of repos) {
217
+ if (this.aborted)
218
+ break;
219
+ try {
220
+ const contents = await this.fetchRepoContents(repo.full_name);
221
+ for (const item of contents) {
222
+ const hash = item.content ? createHash('sha256').update(item.content).digest('hex') : null;
223
+ upsert.run(repo.id, item.path, item.content, hash);
224
+ }
225
+ mined++;
226
+ this.log.debug(`[code-miner] Mined ${repo.full_name}: ${contents.length} files`);
227
+ }
228
+ catch (err) {
229
+ errors++;
230
+ this.log.error(`[code-miner] Error mining ${repo.full_name}: ${err.message}`);
231
+ }
232
+ await this.delay();
233
+ }
234
+ this.mining = false;
235
+ this.lastMinedAt = new Date().toISOString();
236
+ this.log.info(`[code-miner] Batch complete: ${mined} mined, ${errors} errors`);
237
+ return { mined, errors };
238
+ }
239
+ delay() {
240
+ return new Promise(resolve => setTimeout(resolve, this.delayMs));
241
+ }
242
+ }
243
+ //# sourceMappingURL=code-miner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-miner.js","sourceRoot":"","sources":["../../src/codegen/code-miner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { KnowledgeDistiller } from '../research/knowledge-distiller.js';
2
+ import type { ResearchJournal } from '../research/journal.js';
3
+ import type { PatternExtractor } from './pattern-extractor.js';
4
+ import type { SignalScanner } from '../scanner/signal-scanner.js';
5
+ import type { ContextBuilderConfig, BuiltContext, GenerationRequest } from './types.js';
6
+ export declare class ContextBuilder {
7
+ private knowledgeDistiller;
8
+ private journal;
9
+ private patternExtractor;
10
+ private signalScanner;
11
+ private config;
12
+ constructor(knowledgeDistiller?: KnowledgeDistiller | null, journal?: ResearchJournal | null, patternExtractor?: PatternExtractor | null, signalScanner?: SignalScanner | null, config?: ContextBuilderConfig);
13
+ /** Build the complete system prompt from brain knowledge. */
14
+ build(request: GenerationRequest): BuiltContext;
15
+ }