@soleri/forge 5.14.0 → 5.14.2

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 (105) hide show
  1. package/dist/index.js +0 -0
  2. package/dist/lib.d.ts +2 -0
  3. package/dist/lib.js +2 -0
  4. package/dist/lib.js.map +1 -1
  5. package/dist/skills/brain-debrief.md +47 -19
  6. package/dist/skills/brainstorming.md +19 -9
  7. package/dist/skills/code-patrol.md +21 -19
  8. package/dist/skills/context-resume.md +14 -11
  9. package/dist/skills/executing-plans.md +30 -15
  10. package/dist/skills/fix-and-learn.md +17 -14
  11. package/dist/skills/health-check.md +29 -23
  12. package/dist/skills/knowledge-harvest.md +27 -20
  13. package/dist/skills/onboard-me.md +16 -15
  14. package/dist/skills/retrospective.md +34 -18
  15. package/dist/skills/second-opinion.md +16 -9
  16. package/dist/skills/systematic-debugging.md +40 -29
  17. package/dist/skills/test-driven-development.md +45 -30
  18. package/dist/skills/vault-capture.md +31 -15
  19. package/dist/skills/vault-navigator.md +24 -13
  20. package/dist/skills/verification-before-completion.md +38 -26
  21. package/dist/skills/writing-plans.md +21 -13
  22. package/dist/templates/claude-md-template.d.ts +9 -8
  23. package/dist/templates/claude-md-template.js +29 -11
  24. package/dist/templates/claude-md-template.js.map +1 -1
  25. package/dist/templates/inject-claude-md.js +65 -25
  26. package/dist/templates/inject-claude-md.js.map +1 -1
  27. package/dist/templates/shared-rules.d.ts +10 -6
  28. package/dist/templates/shared-rules.js +242 -199
  29. package/dist/templates/shared-rules.js.map +1 -1
  30. package/dist/templates/test-facades.js +6 -4
  31. package/dist/templates/test-facades.js.map +1 -1
  32. package/package.json +1 -1
  33. package/src/lib.ts +2 -0
  34. package/src/templates/claude-md-template.ts +30 -12
  35. package/src/templates/inject-claude-md.ts +65 -25
  36. package/src/templates/shared-rules.ts +259 -210
  37. package/src/templates/test-facades.ts +6 -4
  38. package/dist/skills/skills/brain-debrief.md +0 -214
  39. package/dist/skills/skills/brainstorming.md +0 -180
  40. package/dist/skills/skills/code-patrol.md +0 -178
  41. package/dist/skills/skills/context-resume.md +0 -146
  42. package/dist/skills/skills/executing-plans.md +0 -216
  43. package/dist/skills/skills/fix-and-learn.md +0 -167
  44. package/dist/skills/skills/health-check.md +0 -231
  45. package/dist/skills/skills/knowledge-harvest.md +0 -185
  46. package/dist/skills/skills/onboard-me.md +0 -198
  47. package/dist/skills/skills/retrospective.md +0 -205
  48. package/dist/skills/skills/second-opinion.md +0 -149
  49. package/dist/skills/skills/systematic-debugging.md +0 -241
  50. package/dist/skills/skills/test-driven-development.md +0 -281
  51. package/dist/skills/skills/vault-capture.md +0 -170
  52. package/dist/skills/skills/vault-navigator.md +0 -140
  53. package/dist/skills/skills/verification-before-completion.md +0 -182
  54. package/dist/skills/skills/writing-plans.md +0 -215
  55. package/dist/templates/brain.d.ts +0 -6
  56. package/dist/templates/brain.js +0 -478
  57. package/dist/templates/brain.js.map +0 -1
  58. package/dist/templates/core-facade.d.ts +0 -6
  59. package/dist/templates/core-facade.js +0 -564
  60. package/dist/templates/core-facade.js.map +0 -1
  61. package/dist/templates/facade-factory.d.ts +0 -1
  62. package/dist/templates/facade-factory.js +0 -63
  63. package/dist/templates/facade-factory.js.map +0 -1
  64. package/dist/templates/facade-types.d.ts +0 -1
  65. package/dist/templates/facade-types.js +0 -46
  66. package/dist/templates/facade-types.js.map +0 -1
  67. package/dist/templates/intelligence-loader.d.ts +0 -1
  68. package/dist/templates/intelligence-loader.js +0 -43
  69. package/dist/templates/intelligence-loader.js.map +0 -1
  70. package/dist/templates/intelligence-types.d.ts +0 -1
  71. package/dist/templates/intelligence-types.js +0 -24
  72. package/dist/templates/intelligence-types.js.map +0 -1
  73. package/dist/templates/llm-client.d.ts +0 -7
  74. package/dist/templates/llm-client.js +0 -300
  75. package/dist/templates/llm-client.js.map +0 -1
  76. package/dist/templates/llm-key-pool.d.ts +0 -7
  77. package/dist/templates/llm-key-pool.js +0 -211
  78. package/dist/templates/llm-key-pool.js.map +0 -1
  79. package/dist/templates/llm-types.d.ts +0 -5
  80. package/dist/templates/llm-types.js +0 -161
  81. package/dist/templates/llm-types.js.map +0 -1
  82. package/dist/templates/llm-utils.d.ts +0 -5
  83. package/dist/templates/llm-utils.js +0 -260
  84. package/dist/templates/llm-utils.js.map +0 -1
  85. package/dist/templates/planner.d.ts +0 -5
  86. package/dist/templates/planner.js +0 -150
  87. package/dist/templates/planner.js.map +0 -1
  88. package/dist/templates/test-brain.d.ts +0 -6
  89. package/dist/templates/test-brain.js +0 -474
  90. package/dist/templates/test-brain.js.map +0 -1
  91. package/dist/templates/test-llm.d.ts +0 -7
  92. package/dist/templates/test-llm.js +0 -574
  93. package/dist/templates/test-llm.js.map +0 -1
  94. package/dist/templates/test-loader.d.ts +0 -5
  95. package/dist/templates/test-loader.js +0 -146
  96. package/dist/templates/test-loader.js.map +0 -1
  97. package/dist/templates/test-planner.d.ts +0 -5
  98. package/dist/templates/test-planner.js +0 -271
  99. package/dist/templates/test-planner.js.map +0 -1
  100. package/dist/templates/test-vault.d.ts +0 -5
  101. package/dist/templates/test-vault.js +0 -380
  102. package/dist/templates/test-vault.js.map +0 -1
  103. package/dist/templates/vault.d.ts +0 -5
  104. package/dist/templates/vault.js +0 -263
  105. package/dist/templates/vault.js.map +0 -1
@@ -1,478 +0,0 @@
1
- /**
2
- * Generates the brain.ts source file for a new agent.
3
- * The Brain provides a local, zero-dependency intelligence layer:
4
- * TF-IDF scoring, auto-tagging, duplicate detection, and search feedback.
5
- */
6
- export function generateBrain() {
7
- return BRAIN_TEMPLATE;
8
- }
9
- const BRAIN_TEMPLATE = [
10
- "import type { Vault } from '../vault/vault.js';",
11
- "import type { SearchResult } from '../vault/vault.js';",
12
- "import type { IntelligenceEntry } from '../intelligence/types.js';",
13
- '',
14
- '// ─── Types ───────────────────────────────────────────────────────────',
15
- '',
16
- 'export interface ScoringWeights {',
17
- ' semantic: number;',
18
- ' severity: number;',
19
- ' recency: number;',
20
- ' tagOverlap: number;',
21
- ' domainMatch: number;',
22
- '}',
23
- '',
24
- 'export interface ScoreBreakdown {',
25
- ' semantic: number;',
26
- ' severity: number;',
27
- ' recency: number;',
28
- ' tagOverlap: number;',
29
- ' domainMatch: number;',
30
- ' total: number;',
31
- '}',
32
- '',
33
- 'export interface RankedResult {',
34
- ' entry: IntelligenceEntry;',
35
- ' score: number;',
36
- ' breakdown: ScoreBreakdown;',
37
- '}',
38
- '',
39
- 'export interface SearchOptions {',
40
- ' domain?: string;',
41
- ' type?: string;',
42
- ' severity?: string;',
43
- ' limit?: number;',
44
- ' tags?: string[];',
45
- '}',
46
- '',
47
- 'export interface CaptureResult {',
48
- ' captured: boolean;',
49
- ' id: string;',
50
- ' autoTags: string[];',
51
- ' duplicate?: { id: string; similarity: number };',
52
- ' blocked?: boolean;',
53
- '}',
54
- '',
55
- 'export interface BrainStats {',
56
- ' vocabularySize: number;',
57
- ' feedbackCount: number;',
58
- ' weights: ScoringWeights;',
59
- '}',
60
- '',
61
- 'export interface QueryContext {',
62
- ' query: string;',
63
- ' domain?: string;',
64
- ' tags?: string[];',
65
- '}',
66
- '',
67
- 'type SparseVector = Map<string, number>;',
68
- '',
69
- '// ─── Stopwords ─────────────────────────────────────────────────────',
70
- '',
71
- 'const STOPWORDS = new Set([',
72
- " 'a', 'an', 'the', 'and', 'or', 'but', 'in', 'on', 'at', 'to', 'for',",
73
- " 'of', 'with', 'by', 'from', 'as', 'is', 'was', 'are', 'were', 'been',",
74
- " 'be', 'have', 'has', 'had', 'do', 'does', 'did', 'will', 'would', 'could',",
75
- " 'should', 'may', 'might', 'shall', 'can', 'need', 'must', 'it', 'its',",
76
- " 'this', 'that', 'these', 'those', 'i', 'you', 'he', 'she', 'we', 'they',",
77
- " 'me', 'him', 'her', 'us', 'them', 'my', 'your', 'his', 'our', 'their',",
78
- " 'what', 'which', 'who', 'whom', 'when', 'where', 'why', 'how', 'all',",
79
- " 'each', 'every', 'both', 'few', 'more', 'most', 'other', 'some', 'such',",
80
- " 'no', 'not', 'only', 'same', 'so', 'than', 'too', 'very', 'just',",
81
- " 'because', 'if', 'then', 'else', 'about', 'up', 'out', 'into',",
82
- ']);',
83
- '',
84
- '// ─── Text Processing (pure functions) ────────────────────────────',
85
- '',
86
- 'function tokenize(text: string): string[] {',
87
- ' return text',
88
- ' .toLowerCase()',
89
- " .replace(/[^a-z0-9\\s-]/g, ' ')",
90
- ' .split(/\\s+/)',
91
- ' .filter((t) => t.length > 2 && !STOPWORDS.has(t));',
92
- '}',
93
- '',
94
- 'function calculateTf(tokens: string[]): SparseVector {',
95
- ' const tf: SparseVector = new Map();',
96
- ' for (const token of tokens) {',
97
- ' tf.set(token, (tf.get(token) ?? 0) + 1);',
98
- ' }',
99
- ' // Normalize by document length',
100
- ' const len = tokens.length || 1;',
101
- ' for (const [term, count] of tf) {',
102
- ' tf.set(term, count / len);',
103
- ' }',
104
- ' return tf;',
105
- '}',
106
- '',
107
- 'function calculateTfIdf(tokens: string[], vocabulary: Map<string, number>): SparseVector {',
108
- ' const tf = calculateTf(tokens);',
109
- ' const tfidf: SparseVector = new Map();',
110
- ' for (const [term, tfValue] of tf) {',
111
- ' const idf = vocabulary.get(term) ?? 0;',
112
- ' if (idf > 0) {',
113
- ' tfidf.set(term, tfValue * idf);',
114
- ' }',
115
- ' }',
116
- ' return tfidf;',
117
- '}',
118
- '',
119
- 'function cosineSimilarity(a: SparseVector, b: SparseVector): number {',
120
- ' let dot = 0;',
121
- ' let normA = 0;',
122
- ' let normB = 0;',
123
- ' for (const [term, valA] of a) {',
124
- ' normA += valA * valA;',
125
- ' const valB = b.get(term);',
126
- ' if (valB !== undefined) {',
127
- ' dot += valA * valB;',
128
- ' }',
129
- ' }',
130
- ' for (const [, valB] of b) {',
131
- ' normB += valB * valB;',
132
- ' }',
133
- ' const denom = Math.sqrt(normA) * Math.sqrt(normB);',
134
- ' return denom === 0 ? 0 : dot / denom;',
135
- '}',
136
- '',
137
- 'function jaccardSimilarity(a: string[], b: string[]): number {',
138
- ' if (a.length === 0 && b.length === 0) return 0;',
139
- ' const setA = new Set(a);',
140
- ' const setB = new Set(b);',
141
- ' let intersection = 0;',
142
- ' for (const item of setA) {',
143
- ' if (setB.has(item)) intersection++;',
144
- ' }',
145
- ' const union = new Set([...a, ...b]).size;',
146
- ' return union === 0 ? 0 : intersection / union;',
147
- '}',
148
- '',
149
- '// ─── Severity scoring ──────────────────────────────────────────────',
150
- '',
151
- 'const SEVERITY_SCORES: Record<string, number> = {',
152
- ' critical: 1.0,',
153
- ' warning: 0.7,',
154
- ' suggestion: 0.4,',
155
- '};',
156
- '',
157
- '// ─── Brain Class ─────────────────────────────────────────────────',
158
- '',
159
- 'const DEFAULT_WEIGHTS: ScoringWeights = {',
160
- ' semantic: 0.40,',
161
- ' severity: 0.15,',
162
- ' recency: 0.15,',
163
- ' tagOverlap: 0.15,',
164
- ' domainMatch: 0.15,',
165
- '};',
166
- '',
167
- 'const WEIGHT_BOUND = 0.15;',
168
- 'const FEEDBACK_THRESHOLD = 30;',
169
- 'const DUPLICATE_BLOCK_THRESHOLD = 0.8;',
170
- 'const DUPLICATE_WARN_THRESHOLD = 0.6;',
171
- 'const RECENCY_HALF_LIFE_DAYS = 365;',
172
- '',
173
- 'export class Brain {',
174
- ' private vault: Vault;',
175
- ' private vocabulary: Map<string, number> = new Map();',
176
- ' private weights: ScoringWeights = { ...DEFAULT_WEIGHTS };',
177
- '',
178
- ' constructor(vault: Vault) {',
179
- ' this.vault = vault;',
180
- ' this.rebuildVocabulary();',
181
- ' this.recomputeWeights();',
182
- ' }',
183
- '',
184
- ' intelligentSearch(query: string, options?: SearchOptions): RankedResult[] {',
185
- ' const limit = options?.limit ?? 10;',
186
- ' // Get raw FTS5 results with higher limit for re-ranking',
187
- ' const rawResults = this.vault.search(query, {',
188
- ' domain: options?.domain,',
189
- ' type: options?.type,',
190
- ' severity: options?.severity,',
191
- ' limit: Math.max(limit * 3, 30),',
192
- ' });',
193
- '',
194
- ' if (rawResults.length === 0) return [];',
195
- '',
196
- ' const queryTokens = tokenize(query);',
197
- ' const queryTags = options?.tags ?? [];',
198
- ' const queryDomain = options?.domain;',
199
- ' const now = Math.floor(Date.now() / 1000);',
200
- '',
201
- ' const ranked = rawResults.map((result) => {',
202
- ' const entry = result.entry;',
203
- ' const breakdown = this.scoreEntry(entry, queryTokens, queryTags, queryDomain, now);',
204
- ' return { entry, score: breakdown.total, breakdown };',
205
- ' });',
206
- '',
207
- ' ranked.sort((a, b) => b.score - a.score);',
208
- ' return ranked.slice(0, limit);',
209
- ' }',
210
- '',
211
- " enrichAndCapture(entry: Partial<IntelligenceEntry> & { id: string; type: IntelligenceEntry['type']; domain: string; title: string; severity: IntelligenceEntry['severity']; description: string }): CaptureResult {",
212
- ' // Auto-tag',
213
- ' const autoTags = this.generateTags(entry.title, entry.description, entry.context);',
214
- ' const mergedTags = Array.from(new Set([...(entry.tags ?? []), ...autoTags]));',
215
- '',
216
- ' // Duplicate detection: compare against top 50 FTS5 matches for the title',
217
- ' const duplicate = this.detectDuplicate(entry.title, entry.domain);',
218
- '',
219
- ' if (duplicate && duplicate.similarity >= DUPLICATE_BLOCK_THRESHOLD) {',
220
- ' return {',
221
- ' captured: false,',
222
- ' id: entry.id,',
223
- ' autoTags,',
224
- ' duplicate,',
225
- ' blocked: true,',
226
- ' };',
227
- ' }',
228
- '',
229
- ' // Proceed with capture',
230
- ' const fullEntry: IntelligenceEntry = {',
231
- ' id: entry.id,',
232
- ' type: entry.type,',
233
- ' domain: entry.domain,',
234
- ' title: entry.title,',
235
- ' severity: entry.severity,',
236
- ' description: entry.description,',
237
- ' context: entry.context,',
238
- ' example: entry.example,',
239
- ' counterExample: entry.counterExample,',
240
- ' why: entry.why,',
241
- ' tags: mergedTags,',
242
- ' appliesTo: entry.appliesTo,',
243
- ' };',
244
- '',
245
- ' this.vault.add(fullEntry);',
246
- ' this.updateVocabularyIncremental(fullEntry);',
247
- '',
248
- ' const result: CaptureResult = {',
249
- ' captured: true,',
250
- ' id: entry.id,',
251
- ' autoTags,',
252
- ' };',
253
- '',
254
- ' if (duplicate && duplicate.similarity >= DUPLICATE_WARN_THRESHOLD) {',
255
- ' result.duplicate = duplicate;',
256
- ' }',
257
- '',
258
- ' return result;',
259
- ' }',
260
- '',
261
- " recordFeedback(query: string, entryId: string, action: 'accepted' | 'dismissed'): void {",
262
- ' const db = this.vault.getDb();',
263
- " db.prepare('INSERT INTO brain_feedback (query, entry_id, action) VALUES (?, ?, ?)').run(query, entryId, action);",
264
- ' this.recomputeWeights();',
265
- ' }',
266
- '',
267
- ' getRelevantPatterns(context: QueryContext): RankedResult[] {',
268
- ' return this.intelligentSearch(context.query, {',
269
- ' domain: context.domain,',
270
- ' tags: context.tags,',
271
- ' });',
272
- ' }',
273
- '',
274
- ' rebuildVocabulary(): void {',
275
- ' const entries = this.vault.list({ limit: 100000 });',
276
- ' const docCount = entries.length;',
277
- ' if (docCount === 0) {',
278
- ' this.vocabulary.clear();',
279
- ' this.persistVocabulary();',
280
- ' return;',
281
- ' }',
282
- '',
283
- ' const termDocFreq = new Map<string, number>();',
284
- ' for (const entry of entries) {',
285
- " const text = [entry.title, entry.description, entry.context ?? '', entry.tags.join(' ')].join(' ');",
286
- ' const tokens = new Set(tokenize(text));',
287
- ' for (const token of tokens) {',
288
- ' termDocFreq.set(token, (termDocFreq.get(token) ?? 0) + 1);',
289
- ' }',
290
- ' }',
291
- '',
292
- ' this.vocabulary.clear();',
293
- ' for (const [term, df] of termDocFreq) {',
294
- ' const idf = Math.log((docCount + 1) / (df + 1)) + 1;',
295
- ' this.vocabulary.set(term, idf);',
296
- ' }',
297
- '',
298
- ' this.persistVocabulary();',
299
- ' }',
300
- '',
301
- ' getStats(): BrainStats {',
302
- ' const db = this.vault.getDb();',
303
- " const feedbackCount = (db.prepare('SELECT COUNT(*) as count FROM brain_feedback').get() as { count: number }).count;",
304
- ' return {',
305
- ' vocabularySize: this.vocabulary.size,',
306
- ' feedbackCount,',
307
- ' weights: { ...this.weights },',
308
- ' };',
309
- ' }',
310
- '',
311
- ' getVocabularySize(): number {',
312
- ' return this.vocabulary.size;',
313
- ' }',
314
- '',
315
- ' // ─── Private methods ─────────────────────────────────────────────',
316
- '',
317
- ' private scoreEntry(',
318
- ' entry: IntelligenceEntry,',
319
- ' queryTokens: string[],',
320
- ' queryTags: string[],',
321
- ' queryDomain: string | undefined,',
322
- ' now: number',
323
- ' ): ScoreBreakdown {',
324
- ' // 1. Semantic (TF-IDF cosine similarity)',
325
- ' let semantic = 0;',
326
- ' if (this.vocabulary.size > 0 && queryTokens.length > 0) {',
327
- " const entryText = [entry.title, entry.description, entry.context ?? '', entry.tags.join(' ')].join(' ');",
328
- ' const entryTokens = tokenize(entryText);',
329
- ' const queryVec = calculateTfIdf(queryTokens, this.vocabulary);',
330
- ' const entryVec = calculateTfIdf(entryTokens, this.vocabulary);',
331
- ' semantic = cosineSimilarity(queryVec, entryVec);',
332
- ' }',
333
- '',
334
- ' // 2. Severity',
335
- ' const severity = SEVERITY_SCORES[entry.severity] ?? 0.4;',
336
- '',
337
- ' // 3. Recency (exponential decay over 1 year)',
338
- ' const entryAge = now - (entry as unknown as { created_at?: number }).created_at!;',
339
- ' const halfLifeSeconds = RECENCY_HALF_LIFE_DAYS * 86400;',
340
- ' const recency = entryAge > 0 ? Math.exp(-0.693 * entryAge / halfLifeSeconds) : 1;',
341
- '',
342
- ' // 4. Tag overlap (Jaccard)',
343
- ' const tagOverlap = queryTags.length > 0 ? jaccardSimilarity(queryTags, entry.tags) : 0;',
344
- '',
345
- ' // 5. Domain match',
346
- ' const domainMatch = queryDomain && entry.domain === queryDomain ? 1.0 : 0;',
347
- '',
348
- ' const total =',
349
- ' this.weights.semantic * semantic +',
350
- ' this.weights.severity * severity +',
351
- ' this.weights.recency * recency +',
352
- ' this.weights.tagOverlap * tagOverlap +',
353
- ' this.weights.domainMatch * domainMatch;',
354
- '',
355
- ' return { semantic, severity, recency, tagOverlap, domainMatch, total };',
356
- ' }',
357
- '',
358
- ' private generateTags(title: string, description: string, context?: string): string[] {',
359
- " const text = [title, description, context ?? ''].join(' ');",
360
- ' const tokens = tokenize(text);',
361
- ' if (tokens.length === 0) return [];',
362
- '',
363
- ' // Score tokens by TF-IDF',
364
- ' const tf = calculateTf(tokens);',
365
- ' const scored: Array<[string, number]> = [];',
366
- ' for (const [term, tfValue] of tf) {',
367
- ' const idf = this.vocabulary.get(term) ?? 1;',
368
- ' scored.push([term, tfValue * idf]);',
369
- ' }',
370
- '',
371
- ' scored.sort((a, b) => b[1] - a[1]);',
372
- ' return scored.slice(0, 5).map(([term]) => term);',
373
- ' }',
374
- '',
375
- ' private detectDuplicate(title: string, domain: string): { id: string; similarity: number } | null {',
376
- ' let candidates: SearchResult[];',
377
- ' try {',
378
- ' candidates = this.vault.search(title, { domain, limit: 50 });',
379
- ' } catch {',
380
- ' return null;',
381
- ' }',
382
- ' if (candidates.length === 0) return null;',
383
- '',
384
- ' const titleTokens = tokenize(title);',
385
- ' if (titleTokens.length === 0) return null;',
386
- ' const titleVec = calculateTfIdf(titleTokens, this.vocabulary);',
387
- ' if (titleVec.size === 0) {',
388
- ' // Fallback: use raw TF for comparison when vocabulary is empty',
389
- ' const titleTf = calculateTf(titleTokens);',
390
- ' let bestMatch: { id: string; similarity: number } | null = null;',
391
- ' for (const candidate of candidates) {',
392
- ' const candidateTokens = tokenize(candidate.entry.title);',
393
- ' const candidateTf = calculateTf(candidateTokens);',
394
- ' const sim = cosineSimilarity(titleTf, candidateTf);',
395
- ' if (!bestMatch || sim > bestMatch.similarity) {',
396
- ' bestMatch = { id: candidate.entry.id, similarity: sim };',
397
- ' }',
398
- ' }',
399
- ' return bestMatch;',
400
- ' }',
401
- '',
402
- ' let bestMatch: { id: string; similarity: number } | null = null;',
403
- ' for (const candidate of candidates) {',
404
- " const candidateText = [candidate.entry.title, candidate.entry.description].join(' ');",
405
- ' const candidateTokens = tokenize(candidateText);',
406
- ' const candidateVec = calculateTfIdf(candidateTokens, this.vocabulary);',
407
- ' const sim = cosineSimilarity(titleVec, candidateVec);',
408
- ' if (!bestMatch || sim > bestMatch.similarity) {',
409
- ' bestMatch = { id: candidate.entry.id, similarity: sim };',
410
- ' }',
411
- ' }',
412
- ' return bestMatch;',
413
- ' }',
414
- '',
415
- ' private updateVocabularyIncremental(entry: IntelligenceEntry): void {',
416
- " const text = [entry.title, entry.description, entry.context ?? '', entry.tags.join(' ')].join(' ');",
417
- ' const tokens = new Set(tokenize(text));',
418
- ' const totalDocs = this.vault.stats().totalEntries;',
419
- '',
420
- ' for (const token of tokens) {',
421
- ' const currentDocCount = (this.vocabulary.has(token)) ? Math.round((totalDocs) / Math.exp(this.vocabulary.get(token)! - 1)) + 1 : 1;',
422
- ' const newIdf = Math.log((totalDocs + 1) / (currentDocCount + 1)) + 1;',
423
- ' this.vocabulary.set(token, newIdf);',
424
- ' }',
425
- '',
426
- ' this.persistVocabulary();',
427
- ' }',
428
- '',
429
- ' private persistVocabulary(): void {',
430
- ' const db = this.vault.getDb();',
431
- " db.exec('DELETE FROM brain_vocabulary');",
432
- ' if (this.vocabulary.size === 0) return;',
433
- " const insert = db.prepare('INSERT INTO brain_vocabulary (term, idf, doc_count) VALUES (?, ?, ?)');",
434
- ' const tx = db.transaction(() => {',
435
- ' for (const [term, idf] of this.vocabulary) {',
436
- ' insert.run(term, idf, 1);',
437
- ' }',
438
- ' });',
439
- ' tx();',
440
- ' }',
441
- '',
442
- ' private recomputeWeights(): void {',
443
- ' const db = this.vault.getDb();',
444
- " const feedbackCount = (db.prepare('SELECT COUNT(*) as count FROM brain_feedback').get() as { count: number }).count;",
445
- ' if (feedbackCount < FEEDBACK_THRESHOLD) {',
446
- ' this.weights = { ...DEFAULT_WEIGHTS };',
447
- ' return;',
448
- ' }',
449
- '',
450
- ' // Count accepted vs dismissed feedback',
451
- ' const accepted = (db.prepare("SELECT COUNT(*) as count FROM brain_feedback WHERE action = \'accepted\'").get() as { count: number }).count;',
452
- ' const acceptRate = feedbackCount > 0 ? accepted / feedbackCount : 0.5;',
453
- '',
454
- ' // High accept rate -> increase semantic weight, decrease others',
455
- ' // Low accept rate -> decrease semantic weight, increase others',
456
- ' const semanticDelta = (acceptRate - 0.5) * WEIGHT_BOUND * 2;',
457
- '',
458
- ' const newWeights = { ...DEFAULT_WEIGHTS };',
459
- ' newWeights.semantic = clamp(DEFAULT_WEIGHTS.semantic + semanticDelta, DEFAULT_WEIGHTS.semantic - WEIGHT_BOUND, DEFAULT_WEIGHTS.semantic + WEIGHT_BOUND);',
460
- '',
461
- ' // Redistribute remaining weight evenly across other dimensions',
462
- ' const remaining = 1.0 - newWeights.semantic;',
463
- ' const otherSum = DEFAULT_WEIGHTS.severity + DEFAULT_WEIGHTS.recency + DEFAULT_WEIGHTS.tagOverlap + DEFAULT_WEIGHTS.domainMatch;',
464
- ' const scale = remaining / otherSum;',
465
- ' newWeights.severity = DEFAULT_WEIGHTS.severity * scale;',
466
- ' newWeights.recency = DEFAULT_WEIGHTS.recency * scale;',
467
- ' newWeights.tagOverlap = DEFAULT_WEIGHTS.tagOverlap * scale;',
468
- ' newWeights.domainMatch = DEFAULT_WEIGHTS.domainMatch * scale;',
469
- '',
470
- ' this.weights = newWeights;',
471
- ' }',
472
- '}',
473
- '',
474
- 'function clamp(value: number, min: number, max: number): number {',
475
- ' return Math.max(min, Math.min(max, value));',
476
- '}',
477
- ].join('\n');
478
- //# sourceMappingURL=brain.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"brain.js","sourceRoot":"","sources":["../../src/templates/brain.ts"],"names":[],"mappings":"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"}
@@ -1,6 +0,0 @@
1
- import type { AgentConfig } from '../types.js';
2
- /**
3
- * Generate the core facade that every agent gets — vault stats, search all,
4
- * health, identity, plus activation system (activate, deactivate, inject_claude_md, setup).
5
- */
6
- export declare function generateCoreFacade(config: AgentConfig): string;