@timmeck/brain 1.8.1 → 1.8.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 (162) hide show
  1. package/BRAIN_PLAN.md +3324 -3324
  2. package/LICENSE +21 -21
  3. package/dist/cli/commands/dashboard.js +595 -595
  4. package/dist/dashboard/server.js +25 -25
  5. package/dist/db/migrations/001_core_schema.js +115 -115
  6. package/dist/db/migrations/002_learning_schema.js +33 -33
  7. package/dist/db/migrations/003_code_schema.js +48 -48
  8. package/dist/db/migrations/004_synapses_schema.js +52 -52
  9. package/dist/db/migrations/005_fts_indexes.js +73 -73
  10. package/dist/db/migrations/007_feedback.js +8 -8
  11. package/dist/db/migrations/008_git_integration.js +33 -33
  12. package/dist/db/migrations/009_embeddings.js +3 -3
  13. package/dist/db/repositories/antipattern.repository.js +3 -3
  14. package/dist/db/repositories/code-module.repository.js +32 -32
  15. package/dist/db/repositories/notification.repository.js +3 -3
  16. package/dist/db/repositories/project.repository.js +21 -21
  17. package/dist/db/repositories/rule.repository.js +24 -24
  18. package/dist/db/repositories/solution.repository.js +50 -50
  19. package/dist/db/repositories/synapse.repository.js +18 -18
  20. package/dist/db/repositories/terminal.repository.js +24 -24
  21. package/dist/ipc/server.d.ts +8 -0
  22. package/dist/ipc/server.js +67 -1
  23. package/dist/ipc/server.js.map +1 -1
  24. package/dist/matching/error-matcher.js +5 -5
  25. package/dist/matching/fingerprint.js +6 -1
  26. package/dist/matching/fingerprint.js.map +1 -1
  27. package/dist/services/error.service.js +4 -3
  28. package/dist/services/error.service.js.map +1 -1
  29. package/dist/services/git.service.js +14 -14
  30. package/package.json +49 -49
  31. package/src/api/server.ts +395 -395
  32. package/src/brain.ts +266 -266
  33. package/src/cli/colors.ts +116 -116
  34. package/src/cli/commands/config.ts +169 -169
  35. package/src/cli/commands/dashboard.ts +755 -755
  36. package/src/cli/commands/doctor.ts +118 -118
  37. package/src/cli/commands/explain.ts +83 -83
  38. package/src/cli/commands/export.ts +31 -31
  39. package/src/cli/commands/import.ts +199 -199
  40. package/src/cli/commands/insights.ts +65 -65
  41. package/src/cli/commands/learn.ts +24 -24
  42. package/src/cli/commands/modules.ts +53 -53
  43. package/src/cli/commands/network.ts +67 -67
  44. package/src/cli/commands/projects.ts +42 -42
  45. package/src/cli/commands/query.ts +120 -120
  46. package/src/cli/commands/start.ts +62 -62
  47. package/src/cli/commands/status.ts +75 -75
  48. package/src/cli/commands/stop.ts +34 -34
  49. package/src/cli/ipc-helper.ts +22 -22
  50. package/src/cli/update-check.ts +63 -63
  51. package/src/code/fingerprint.ts +87 -87
  52. package/src/code/parsers/generic.ts +29 -29
  53. package/src/code/parsers/python.ts +54 -54
  54. package/src/code/parsers/typescript.ts +65 -65
  55. package/src/code/registry.ts +60 -60
  56. package/src/dashboard/server.ts +142 -142
  57. package/src/db/connection.ts +22 -22
  58. package/src/db/migrations/001_core_schema.ts +120 -120
  59. package/src/db/migrations/002_learning_schema.ts +38 -38
  60. package/src/db/migrations/003_code_schema.ts +53 -53
  61. package/src/db/migrations/004_synapses_schema.ts +57 -57
  62. package/src/db/migrations/005_fts_indexes.ts +78 -78
  63. package/src/db/migrations/006_synapses_phase3.ts +17 -17
  64. package/src/db/migrations/007_feedback.ts +13 -13
  65. package/src/db/migrations/008_git_integration.ts +38 -38
  66. package/src/db/migrations/009_embeddings.ts +8 -8
  67. package/src/db/repositories/antipattern.repository.ts +66 -66
  68. package/src/db/repositories/code-module.repository.ts +142 -142
  69. package/src/db/repositories/notification.repository.ts +66 -66
  70. package/src/db/repositories/project.repository.ts +93 -93
  71. package/src/db/repositories/rule.repository.ts +108 -108
  72. package/src/db/repositories/solution.repository.ts +154 -154
  73. package/src/db/repositories/synapse.repository.ts +153 -153
  74. package/src/db/repositories/terminal.repository.ts +101 -101
  75. package/src/embeddings/engine.ts +238 -238
  76. package/src/index.ts +63 -63
  77. package/src/ipc/client.ts +118 -118
  78. package/src/ipc/protocol.ts +35 -35
  79. package/src/ipc/router.ts +133 -133
  80. package/src/ipc/server.ts +176 -110
  81. package/src/learning/decay.ts +46 -46
  82. package/src/learning/pattern-extractor.ts +90 -90
  83. package/src/learning/rule-generator.ts +74 -74
  84. package/src/matching/error-matcher.ts +5 -5
  85. package/src/matching/fingerprint.ts +34 -29
  86. package/src/matching/similarity.ts +61 -61
  87. package/src/matching/tfidf.ts +74 -74
  88. package/src/matching/tokenizer.ts +41 -41
  89. package/src/mcp/auto-detect.ts +93 -93
  90. package/src/mcp/http-server.ts +140 -140
  91. package/src/mcp/server.ts +73 -73
  92. package/src/parsing/error-parser.ts +28 -28
  93. package/src/parsing/parsers/compiler.ts +93 -93
  94. package/src/parsing/parsers/generic.ts +28 -28
  95. package/src/parsing/parsers/go.ts +97 -97
  96. package/src/parsing/parsers/node.ts +69 -69
  97. package/src/parsing/parsers/python.ts +62 -62
  98. package/src/parsing/parsers/rust.ts +50 -50
  99. package/src/parsing/parsers/shell.ts +42 -42
  100. package/src/parsing/types.ts +47 -47
  101. package/src/research/gap-analyzer.ts +135 -135
  102. package/src/research/insight-generator.ts +123 -123
  103. package/src/research/research-engine.ts +116 -116
  104. package/src/research/synergy-detector.ts +126 -126
  105. package/src/research/template-extractor.ts +130 -130
  106. package/src/research/trend-analyzer.ts +127 -127
  107. package/src/services/code.service.ts +271 -271
  108. package/src/services/error.service.ts +4 -3
  109. package/src/services/git.service.ts +132 -132
  110. package/src/services/notification.service.ts +41 -41
  111. package/src/services/synapse.service.ts +59 -59
  112. package/src/services/terminal.service.ts +81 -81
  113. package/src/synapses/activation.ts +80 -80
  114. package/src/synapses/decay.ts +38 -38
  115. package/src/synapses/hebbian.ts +69 -69
  116. package/src/synapses/pathfinder.ts +81 -81
  117. package/src/synapses/synapse-manager.ts +109 -109
  118. package/src/types/code.types.ts +52 -52
  119. package/src/types/error.types.ts +67 -67
  120. package/src/types/ipc.types.ts +8 -8
  121. package/src/types/mcp.types.ts +53 -53
  122. package/src/types/research.types.ts +28 -28
  123. package/src/types/solution.types.ts +30 -30
  124. package/src/utils/events.ts +45 -45
  125. package/src/utils/hash.ts +5 -5
  126. package/src/utils/logger.ts +48 -48
  127. package/src/utils/paths.ts +19 -19
  128. package/tests/e2e/test_code_intelligence.py +1015 -0
  129. package/tests/e2e/test_error_memory.py +451 -0
  130. package/tests/e2e/test_full_integration.py +534 -0
  131. package/tests/fixtures/code-modules/modules.ts +83 -83
  132. package/tests/fixtures/errors/go.ts +9 -9
  133. package/tests/fixtures/errors/node.ts +24 -24
  134. package/tests/fixtures/errors/python.ts +21 -21
  135. package/tests/fixtures/errors/rust.ts +25 -25
  136. package/tests/fixtures/errors/shell.ts +15 -15
  137. package/tests/fixtures/solutions/solutions.ts +27 -27
  138. package/tests/helpers/setup-db.ts +52 -52
  139. package/tests/integration/code-flow.test.ts +86 -86
  140. package/tests/integration/error-flow.test.ts +83 -83
  141. package/tests/integration/ipc-flow.test.ts +166 -166
  142. package/tests/integration/learning-cycle.test.ts +82 -82
  143. package/tests/integration/synapse-flow.test.ts +117 -117
  144. package/tests/unit/code/analyzer.test.ts +58 -58
  145. package/tests/unit/code/fingerprint.test.ts +51 -51
  146. package/tests/unit/code/scorer.test.ts +55 -55
  147. package/tests/unit/learning/confidence-scorer.test.ts +60 -60
  148. package/tests/unit/learning/decay.test.ts +45 -45
  149. package/tests/unit/learning/pattern-extractor.test.ts +50 -50
  150. package/tests/unit/matching/error-matcher.test.ts +69 -69
  151. package/tests/unit/matching/fingerprint.test.ts +47 -47
  152. package/tests/unit/matching/similarity.test.ts +65 -65
  153. package/tests/unit/matching/tfidf.test.ts +71 -71
  154. package/tests/unit/matching/tokenizer.test.ts +83 -83
  155. package/tests/unit/parsing/parsers.test.ts +113 -113
  156. package/tests/unit/research/gap-analyzer.test.ts +45 -45
  157. package/tests/unit/research/trend-analyzer.test.ts +45 -45
  158. package/tests/unit/synapses/activation.test.ts +80 -80
  159. package/tests/unit/synapses/decay.test.ts +27 -27
  160. package/tests/unit/synapses/hebbian.test.ts +96 -96
  161. package/tests/unit/synapses/pathfinder.test.ts +72 -72
  162. package/tsconfig.json +18 -18
@@ -1,93 +1,93 @@
1
- import type Database from 'better-sqlite3';
2
- import type { Statement } from 'better-sqlite3';
3
-
4
- export interface ProjectRecord {
5
- id: number;
6
- name: string;
7
- path: string | null;
8
- language: string | null;
9
- framework: string | null;
10
- created_at: string;
11
- updated_at: string;
12
- }
13
-
14
- type CreateProjectData = Omit<ProjectRecord, 'id' | 'created_at' | 'updated_at'>;
15
- type UpdateProjectData = Partial<Omit<ProjectRecord, 'id' | 'created_at'>>;
16
-
17
- export class ProjectRepository {
18
- private stmts: Record<string, Statement>;
19
-
20
- constructor(private db: Database.Database) {
21
- this.stmts = {
22
- create: this.db.prepare(`
23
- INSERT INTO projects (name, path, language, framework)
24
- VALUES (@name, @path, @language, @framework)
25
- `),
26
- getById: this.db.prepare(`
27
- SELECT * FROM projects WHERE id = ?
28
- `),
29
- update: this.db.prepare(`
30
- UPDATE projects
31
- SET name = COALESCE(@name, name),
32
- path = COALESCE(@path, path),
33
- language = COALESCE(@language, language),
34
- framework = COALESCE(@framework, framework),
35
- updated_at = datetime('now')
36
- WHERE id = @id
37
- `),
38
- delete: this.db.prepare(`
39
- DELETE FROM projects WHERE id = ?
40
- `),
41
- findByName: this.db.prepare(`
42
- SELECT * FROM projects WHERE name = ?
43
- `),
44
- findByPath: this.db.prepare(`
45
- SELECT * FROM projects WHERE path = ?
46
- `),
47
- getAll: this.db.prepare(`
48
- SELECT * FROM projects ORDER BY name
49
- `),
50
- };
51
- }
52
-
53
- create(data: CreateProjectData): number {
54
- const result = this.stmts.create.run({
55
- name: data.name,
56
- path: data.path ?? null,
57
- language: data.language ?? null,
58
- framework: data.framework ?? null,
59
- });
60
- return result.lastInsertRowid as number;
61
- }
62
-
63
- getById(id: number): ProjectRecord | undefined {
64
- return this.stmts.getById.get(id) as ProjectRecord | undefined;
65
- }
66
-
67
- update(id: number, data: UpdateProjectData): void {
68
- this.stmts.update.run({
69
- id,
70
- name: data.name ?? null,
71
- path: data.path ?? null,
72
- language: data.language ?? null,
73
- framework: data.framework ?? null,
74
- updated_at: data.updated_at ?? null,
75
- });
76
- }
77
-
78
- delete(id: number): void {
79
- this.stmts.delete.run(id);
80
- }
81
-
82
- findByName(name: string): ProjectRecord | undefined {
83
- return this.stmts.findByName.get(name) as ProjectRecord | undefined;
84
- }
85
-
86
- findByPath(path: string): ProjectRecord | undefined {
87
- return this.stmts.findByPath.get(path) as ProjectRecord | undefined;
88
- }
89
-
90
- getAll(): ProjectRecord[] {
91
- return this.stmts.getAll.all() as ProjectRecord[];
92
- }
93
- }
1
+ import type Database from 'better-sqlite3';
2
+ import type { Statement } from 'better-sqlite3';
3
+
4
+ export interface ProjectRecord {
5
+ id: number;
6
+ name: string;
7
+ path: string | null;
8
+ language: string | null;
9
+ framework: string | null;
10
+ created_at: string;
11
+ updated_at: string;
12
+ }
13
+
14
+ type CreateProjectData = Omit<ProjectRecord, 'id' | 'created_at' | 'updated_at'>;
15
+ type UpdateProjectData = Partial<Omit<ProjectRecord, 'id' | 'created_at'>>;
16
+
17
+ export class ProjectRepository {
18
+ private stmts: Record<string, Statement>;
19
+
20
+ constructor(private db: Database.Database) {
21
+ this.stmts = {
22
+ create: this.db.prepare(`
23
+ INSERT INTO projects (name, path, language, framework)
24
+ VALUES (@name, @path, @language, @framework)
25
+ `),
26
+ getById: this.db.prepare(`
27
+ SELECT * FROM projects WHERE id = ?
28
+ `),
29
+ update: this.db.prepare(`
30
+ UPDATE projects
31
+ SET name = COALESCE(@name, name),
32
+ path = COALESCE(@path, path),
33
+ language = COALESCE(@language, language),
34
+ framework = COALESCE(@framework, framework),
35
+ updated_at = datetime('now')
36
+ WHERE id = @id
37
+ `),
38
+ delete: this.db.prepare(`
39
+ DELETE FROM projects WHERE id = ?
40
+ `),
41
+ findByName: this.db.prepare(`
42
+ SELECT * FROM projects WHERE name = ?
43
+ `),
44
+ findByPath: this.db.prepare(`
45
+ SELECT * FROM projects WHERE path = ?
46
+ `),
47
+ getAll: this.db.prepare(`
48
+ SELECT * FROM projects ORDER BY name
49
+ `),
50
+ };
51
+ }
52
+
53
+ create(data: CreateProjectData): number {
54
+ const result = this.stmts.create.run({
55
+ name: data.name,
56
+ path: data.path ?? null,
57
+ language: data.language ?? null,
58
+ framework: data.framework ?? null,
59
+ });
60
+ return result.lastInsertRowid as number;
61
+ }
62
+
63
+ getById(id: number): ProjectRecord | undefined {
64
+ return this.stmts.getById.get(id) as ProjectRecord | undefined;
65
+ }
66
+
67
+ update(id: number, data: UpdateProjectData): void {
68
+ this.stmts.update.run({
69
+ id,
70
+ name: data.name ?? null,
71
+ path: data.path ?? null,
72
+ language: data.language ?? null,
73
+ framework: data.framework ?? null,
74
+ updated_at: data.updated_at ?? null,
75
+ });
76
+ }
77
+
78
+ delete(id: number): void {
79
+ this.stmts.delete.run(id);
80
+ }
81
+
82
+ findByName(name: string): ProjectRecord | undefined {
83
+ return this.stmts.findByName.get(name) as ProjectRecord | undefined;
84
+ }
85
+
86
+ findByPath(path: string): ProjectRecord | undefined {
87
+ return this.stmts.findByPath.get(path) as ProjectRecord | undefined;
88
+ }
89
+
90
+ getAll(): ProjectRecord[] {
91
+ return this.stmts.getAll.all() as ProjectRecord[];
92
+ }
93
+ }
@@ -1,108 +1,108 @@
1
- import type Database from 'better-sqlite3';
2
- import type { Statement } from 'better-sqlite3';
3
-
4
- export interface RuleRecord {
5
- id: number;
6
- pattern: string;
7
- action: string;
8
- description: string | null;
9
- confidence: number;
10
- occurrences: number;
11
- active: number;
12
- project_id: number | null;
13
- created_at: string;
14
- updated_at: string;
15
- }
16
-
17
- type CreateRuleData = Omit<RuleRecord, 'id' | 'confidence' | 'occurrences' | 'active' | 'created_at' | 'updated_at'> & {
18
- confidence?: number;
19
- occurrences?: number;
20
- active?: number;
21
- };
22
- type UpdateRuleData = Partial<Omit<RuleRecord, 'id' | 'created_at'>>;
23
-
24
- export class RuleRepository {
25
- private stmts: Record<string, Statement>;
26
-
27
- constructor(private db: Database.Database) {
28
- this.stmts = {
29
- create: this.db.prepare(`
30
- INSERT INTO rules (pattern, action, description, confidence, occurrences, active, project_id)
31
- VALUES (@pattern, @action, @description, @confidence, @occurrences, @active, @project_id)
32
- `),
33
- getById: this.db.prepare(`
34
- SELECT * FROM rules WHERE id = ?
35
- `),
36
- update: this.db.prepare(`
37
- UPDATE rules
38
- SET pattern = COALESCE(@pattern, pattern),
39
- action = COALESCE(@action, action),
40
- description = COALESCE(@description, description),
41
- confidence = COALESCE(@confidence, confidence),
42
- occurrences = COALESCE(@occurrences, occurrences),
43
- active = COALESCE(@active, active),
44
- project_id = COALESCE(@project_id, project_id),
45
- updated_at = datetime('now')
46
- WHERE id = @id
47
- `),
48
- delete: this.db.prepare(`
49
- DELETE FROM rules WHERE id = ?
50
- `),
51
- findActiveAll: this.db.prepare(`
52
- SELECT * FROM rules WHERE active = 1 ORDER BY confidence DESC
53
- `),
54
- findActiveByProject: this.db.prepare(`
55
- SELECT * FROM rules WHERE active = 1 AND (project_id = ? OR project_id IS NULL) ORDER BY confidence DESC
56
- `),
57
- findByPattern: this.db.prepare(`
58
- SELECT * FROM rules WHERE pattern = ?
59
- `),
60
- };
61
- }
62
-
63
- create(data: CreateRuleData): number {
64
- const result = this.stmts.create.run({
65
- pattern: data.pattern,
66
- action: data.action,
67
- description: data.description ?? null,
68
- confidence: data.confidence ?? 0.5,
69
- occurrences: data.occurrences ?? 0,
70
- active: data.active ?? 1,
71
- project_id: data.project_id ?? null,
72
- });
73
- return result.lastInsertRowid as number;
74
- }
75
-
76
- getById(id: number): RuleRecord | undefined {
77
- return this.stmts.getById.get(id) as RuleRecord | undefined;
78
- }
79
-
80
- update(id: number, data: UpdateRuleData): void {
81
- this.stmts.update.run({
82
- id,
83
- pattern: data.pattern ?? null,
84
- action: data.action ?? null,
85
- description: data.description ?? null,
86
- confidence: data.confidence ?? null,
87
- occurrences: data.occurrences ?? null,
88
- active: data.active ?? null,
89
- project_id: data.project_id ?? null,
90
- updated_at: data.updated_at ?? null,
91
- });
92
- }
93
-
94
- delete(id: number): void {
95
- this.stmts.delete.run(id);
96
- }
97
-
98
- findActive(projectId?: number): RuleRecord[] {
99
- if (projectId !== undefined) {
100
- return this.stmts.findActiveByProject.all(projectId) as RuleRecord[];
101
- }
102
- return this.stmts.findActiveAll.all() as RuleRecord[];
103
- }
104
-
105
- findByPattern(pattern: string): RuleRecord[] {
106
- return this.stmts.findByPattern.all(pattern) as RuleRecord[];
107
- }
108
- }
1
+ import type Database from 'better-sqlite3';
2
+ import type { Statement } from 'better-sqlite3';
3
+
4
+ export interface RuleRecord {
5
+ id: number;
6
+ pattern: string;
7
+ action: string;
8
+ description: string | null;
9
+ confidence: number;
10
+ occurrences: number;
11
+ active: number;
12
+ project_id: number | null;
13
+ created_at: string;
14
+ updated_at: string;
15
+ }
16
+
17
+ type CreateRuleData = Omit<RuleRecord, 'id' | 'confidence' | 'occurrences' | 'active' | 'created_at' | 'updated_at'> & {
18
+ confidence?: number;
19
+ occurrences?: number;
20
+ active?: number;
21
+ };
22
+ type UpdateRuleData = Partial<Omit<RuleRecord, 'id' | 'created_at'>>;
23
+
24
+ export class RuleRepository {
25
+ private stmts: Record<string, Statement>;
26
+
27
+ constructor(private db: Database.Database) {
28
+ this.stmts = {
29
+ create: this.db.prepare(`
30
+ INSERT INTO rules (pattern, action, description, confidence, occurrences, active, project_id)
31
+ VALUES (@pattern, @action, @description, @confidence, @occurrences, @active, @project_id)
32
+ `),
33
+ getById: this.db.prepare(`
34
+ SELECT * FROM rules WHERE id = ?
35
+ `),
36
+ update: this.db.prepare(`
37
+ UPDATE rules
38
+ SET pattern = COALESCE(@pattern, pattern),
39
+ action = COALESCE(@action, action),
40
+ description = COALESCE(@description, description),
41
+ confidence = COALESCE(@confidence, confidence),
42
+ occurrences = COALESCE(@occurrences, occurrences),
43
+ active = COALESCE(@active, active),
44
+ project_id = COALESCE(@project_id, project_id),
45
+ updated_at = datetime('now')
46
+ WHERE id = @id
47
+ `),
48
+ delete: this.db.prepare(`
49
+ DELETE FROM rules WHERE id = ?
50
+ `),
51
+ findActiveAll: this.db.prepare(`
52
+ SELECT * FROM rules WHERE active = 1 ORDER BY confidence DESC
53
+ `),
54
+ findActiveByProject: this.db.prepare(`
55
+ SELECT * FROM rules WHERE active = 1 AND (project_id = ? OR project_id IS NULL) ORDER BY confidence DESC
56
+ `),
57
+ findByPattern: this.db.prepare(`
58
+ SELECT * FROM rules WHERE pattern = ?
59
+ `),
60
+ };
61
+ }
62
+
63
+ create(data: CreateRuleData): number {
64
+ const result = this.stmts.create.run({
65
+ pattern: data.pattern,
66
+ action: data.action,
67
+ description: data.description ?? null,
68
+ confidence: data.confidence ?? 0.5,
69
+ occurrences: data.occurrences ?? 0,
70
+ active: data.active ?? 1,
71
+ project_id: data.project_id ?? null,
72
+ });
73
+ return result.lastInsertRowid as number;
74
+ }
75
+
76
+ getById(id: number): RuleRecord | undefined {
77
+ return this.stmts.getById.get(id) as RuleRecord | undefined;
78
+ }
79
+
80
+ update(id: number, data: UpdateRuleData): void {
81
+ this.stmts.update.run({
82
+ id,
83
+ pattern: data.pattern ?? null,
84
+ action: data.action ?? null,
85
+ description: data.description ?? null,
86
+ confidence: data.confidence ?? null,
87
+ occurrences: data.occurrences ?? null,
88
+ active: data.active ?? null,
89
+ project_id: data.project_id ?? null,
90
+ updated_at: data.updated_at ?? null,
91
+ });
92
+ }
93
+
94
+ delete(id: number): void {
95
+ this.stmts.delete.run(id);
96
+ }
97
+
98
+ findActive(projectId?: number): RuleRecord[] {
99
+ if (projectId !== undefined) {
100
+ return this.stmts.findActiveByProject.all(projectId) as RuleRecord[];
101
+ }
102
+ return this.stmts.findActiveAll.all() as RuleRecord[];
103
+ }
104
+
105
+ findByPattern(pattern: string): RuleRecord[] {
106
+ return this.stmts.findByPattern.all(pattern) as RuleRecord[];
107
+ }
108
+ }