@timmeck/brain-core 2.36.56 → 2.36.58

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 (152) hide show
  1. package/README.md +6 -0
  2. package/command-center.html +133 -2
  3. package/dist/action/__tests__/action-bridge.test.d.ts +1 -0
  4. package/dist/action/__tests__/action-bridge.test.js +145 -0
  5. package/dist/action/__tests__/action-bridge.test.js.map +1 -0
  6. package/dist/action/__tests__/content-handler.test.d.ts +1 -0
  7. package/dist/action/__tests__/content-handler.test.js +100 -0
  8. package/dist/action/__tests__/content-handler.test.js.map +1 -0
  9. package/dist/action/__tests__/trade-handler.test.d.ts +1 -0
  10. package/dist/action/__tests__/trade-handler.test.js +165 -0
  11. package/dist/action/__tests__/trade-handler.test.js.map +1 -0
  12. package/dist/action/action-bridge.d.ts +95 -0
  13. package/dist/action/action-bridge.js +242 -0
  14. package/dist/action/action-bridge.js.map +1 -0
  15. package/dist/action/handlers/content-handler.d.ts +23 -0
  16. package/dist/action/handlers/content-handler.js +30 -0
  17. package/dist/action/handlers/content-handler.js.map +1 -0
  18. package/dist/action/handlers/index.d.ts +4 -0
  19. package/dist/action/handlers/index.js +3 -0
  20. package/dist/action/handlers/index.js.map +1 -0
  21. package/dist/action/handlers/trade-handler.d.ts +43 -0
  22. package/dist/action/handlers/trade-handler.js +43 -0
  23. package/dist/action/handlers/trade-handler.js.map +1 -0
  24. package/dist/action/index.d.ts +4 -0
  25. package/dist/action/index.js +3 -0
  26. package/dist/action/index.js.map +1 -0
  27. package/dist/agent-training/__tests__/agent-trainer.test.d.ts +1 -0
  28. package/dist/agent-training/__tests__/agent-trainer.test.js +158 -0
  29. package/dist/agent-training/__tests__/agent-trainer.test.js.map +1 -0
  30. package/dist/agent-training/__tests__/sub-agent-factory.test.d.ts +1 -0
  31. package/dist/agent-training/__tests__/sub-agent-factory.test.js +100 -0
  32. package/dist/agent-training/__tests__/sub-agent-factory.test.js.map +1 -0
  33. package/dist/agent-training/__tests__/sub-agent.test.d.ts +1 -0
  34. package/dist/agent-training/__tests__/sub-agent.test.js +102 -0
  35. package/dist/agent-training/__tests__/sub-agent.test.js.map +1 -0
  36. package/dist/agent-training/index.d.ts +4 -0
  37. package/dist/agent-training/index.js +2 -0
  38. package/dist/agent-training/index.js.map +1 -1
  39. package/dist/agent-training/sub-agent-factory.d.ts +36 -0
  40. package/dist/agent-training/sub-agent-factory.js +128 -0
  41. package/dist/agent-training/sub-agent-factory.js.map +1 -0
  42. package/dist/agent-training/sub-agent.d.ts +57 -0
  43. package/dist/agent-training/sub-agent.js +135 -0
  44. package/dist/agent-training/sub-agent.js.map +1 -0
  45. package/dist/chat/__tests__/chat-engine.test.d.ts +1 -0
  46. package/dist/chat/__tests__/chat-engine.test.js +128 -0
  47. package/dist/chat/__tests__/chat-engine.test.js.map +1 -0
  48. package/dist/chat/chat-engine.d.ts +55 -0
  49. package/dist/chat/chat-engine.js +186 -0
  50. package/dist/chat/chat-engine.js.map +1 -0
  51. package/dist/chat/index.d.ts +2 -0
  52. package/dist/chat/index.js +2 -0
  53. package/dist/chat/index.js.map +1 -0
  54. package/dist/codegen/__tests__/code-forge.test.d.ts +1 -0
  55. package/dist/codegen/__tests__/code-forge.test.js +105 -0
  56. package/dist/codegen/__tests__/code-forge.test.js.map +1 -0
  57. package/dist/codegen/code-forge.d.ts +87 -0
  58. package/dist/codegen/code-forge.js +211 -0
  59. package/dist/codegen/code-forge.js.map +1 -0
  60. package/dist/codegen/index.d.ts +2 -0
  61. package/dist/codegen/index.js +1 -0
  62. package/dist/codegen/index.js.map +1 -1
  63. package/dist/content/__tests__/auto-publisher.test.d.ts +1 -0
  64. package/dist/content/__tests__/auto-publisher.test.js +125 -0
  65. package/dist/content/__tests__/auto-publisher.test.js.map +1 -0
  66. package/dist/content/__tests__/content-forge.test.d.ts +1 -0
  67. package/dist/content/__tests__/content-forge.test.js +117 -0
  68. package/dist/content/__tests__/content-forge.test.js.map +1 -0
  69. package/dist/content/auto-publisher.d.ts +51 -0
  70. package/dist/content/auto-publisher.js +147 -0
  71. package/dist/content/auto-publisher.js.map +1 -0
  72. package/dist/content/content-forge.d.ts +106 -0
  73. package/dist/content/content-forge.js +232 -0
  74. package/dist/content/content-forge.js.map +1 -0
  75. package/dist/content/index.d.ts +4 -0
  76. package/dist/content/index.js +3 -0
  77. package/dist/content/index.js.map +1 -0
  78. package/dist/creative/__tests__/creative-engine.test.d.ts +1 -0
  79. package/dist/creative/__tests__/creative-engine.test.js +151 -0
  80. package/dist/creative/__tests__/creative-engine.test.js.map +1 -0
  81. package/dist/cross-brain/__tests__/signal-router.test.d.ts +1 -0
  82. package/dist/cross-brain/__tests__/signal-router.test.js +159 -0
  83. package/dist/cross-brain/__tests__/signal-router.test.js.map +1 -0
  84. package/dist/cross-brain/signal-router.d.ts +57 -0
  85. package/dist/cross-brain/signal-router.js +148 -0
  86. package/dist/cross-brain/signal-router.js.map +1 -0
  87. package/dist/dashboard/__tests__/command-center-server.test.js +31 -0
  88. package/dist/dashboard/__tests__/command-center-server.test.js.map +1 -1
  89. package/dist/dashboard/command-center-server.d.ts +11 -0
  90. package/dist/dashboard/command-center-server.js +72 -0
  91. package/dist/dashboard/command-center-server.js.map +1 -1
  92. package/dist/dream/__tests__/dream-engine.test.d.ts +1 -0
  93. package/dist/dream/__tests__/dream-engine.test.js +184 -0
  94. package/dist/dream/__tests__/dream-engine.test.js.map +1 -0
  95. package/dist/feedback/__tests__/feedback-router.test.d.ts +1 -0
  96. package/dist/feedback/__tests__/feedback-router.test.js +173 -0
  97. package/dist/feedback/__tests__/feedback-router.test.js.map +1 -0
  98. package/dist/feedback/feedback-router.d.ts +53 -0
  99. package/dist/feedback/feedback-router.js +193 -0
  100. package/dist/feedback/feedback-router.js.map +1 -0
  101. package/dist/feedback/index.d.ts +2 -0
  102. package/dist/feedback/index.js +1 -0
  103. package/dist/feedback/index.js.map +1 -1
  104. package/dist/goals/__tests__/goal-engine.test.d.ts +1 -0
  105. package/dist/goals/__tests__/goal-engine.test.js +203 -0
  106. package/dist/goals/__tests__/goal-engine.test.js.map +1 -0
  107. package/dist/guardrails/__tests__/guardrail-engine.test.d.ts +1 -0
  108. package/dist/guardrails/__tests__/guardrail-engine.test.js +343 -0
  109. package/dist/guardrails/__tests__/guardrail-engine.test.js.map +1 -0
  110. package/dist/index.d.ts +16 -0
  111. package/dist/index.js +13 -0
  112. package/dist/index.js.map +1 -1
  113. package/dist/metacognition/__tests__/auto-experiment-engine.test.d.ts +1 -0
  114. package/dist/metacognition/__tests__/auto-experiment-engine.test.js +218 -0
  115. package/dist/metacognition/__tests__/auto-experiment-engine.test.js.map +1 -0
  116. package/dist/metacognition/__tests__/evolution-engine.test.d.ts +1 -0
  117. package/dist/metacognition/__tests__/evolution-engine.test.js +473 -0
  118. package/dist/metacognition/__tests__/evolution-engine.test.js.map +1 -0
  119. package/dist/metacognition/__tests__/parameter-registry.test.d.ts +1 -0
  120. package/dist/metacognition/__tests__/parameter-registry.test.js +223 -0
  121. package/dist/metacognition/__tests__/parameter-registry.test.js.map +1 -0
  122. package/dist/prediction/__tests__/prediction-engine.test.d.ts +1 -0
  123. package/dist/prediction/__tests__/prediction-engine.test.js +244 -0
  124. package/dist/prediction/__tests__/prediction-engine.test.js.map +1 -0
  125. package/dist/research/research-orchestrator.d.ts +12 -0
  126. package/dist/research/research-orchestrator.js +109 -0
  127. package/dist/research/research-orchestrator.js.map +1 -1
  128. package/dist/sandbox/__tests__/code-sandbox.test.d.ts +1 -0
  129. package/dist/sandbox/__tests__/code-sandbox.test.js +182 -0
  130. package/dist/sandbox/__tests__/code-sandbox.test.js.map +1 -0
  131. package/dist/scanner/__tests__/signal-scanner.test.d.ts +1 -0
  132. package/dist/scanner/__tests__/signal-scanner.test.js +142 -0
  133. package/dist/scanner/__tests__/signal-scanner.test.js.map +1 -0
  134. package/dist/self-modification/__tests__/self-modification-engine.test.d.ts +1 -0
  135. package/dist/self-modification/__tests__/self-modification-engine.test.js +255 -0
  136. package/dist/self-modification/__tests__/self-modification-engine.test.js.map +1 -0
  137. package/dist/strategy/__tests__/strategy-forge.test.d.ts +1 -0
  138. package/dist/strategy/__tests__/strategy-forge.test.js +190 -0
  139. package/dist/strategy/__tests__/strategy-forge.test.js.map +1 -0
  140. package/dist/strategy/__tests__/strategy-mutator.test.d.ts +1 -0
  141. package/dist/strategy/__tests__/strategy-mutator.test.js +141 -0
  142. package/dist/strategy/__tests__/strategy-mutator.test.js.map +1 -0
  143. package/dist/strategy/index.d.ts +4 -0
  144. package/dist/strategy/index.js +3 -0
  145. package/dist/strategy/index.js.map +1 -0
  146. package/dist/strategy/strategy-forge.d.ts +114 -0
  147. package/dist/strategy/strategy-forge.js +296 -0
  148. package/dist/strategy/strategy-forge.js.map +1 -0
  149. package/dist/strategy/strategy-mutator.d.ts +42 -0
  150. package/dist/strategy/strategy-mutator.js +140 -0
  151. package/dist/strategy/strategy-mutator.js.map +1 -0
  152. package/package.json +1 -1
@@ -0,0 +1,232 @@
1
+ import { getLogger } from '../utils/logger.js';
2
+ // ── Migration ──────────────────────────────────────────────
3
+ export function runContentForgeMigration(db) {
4
+ db.exec(`
5
+ CREATE TABLE IF NOT EXISTS content_pieces (
6
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
7
+ source_type TEXT NOT NULL,
8
+ source_id INTEGER,
9
+ platform TEXT NOT NULL DEFAULT 'bluesky',
10
+ title TEXT NOT NULL,
11
+ body TEXT NOT NULL,
12
+ hashtags TEXT DEFAULT '[]',
13
+ scheduled_for TEXT,
14
+ status TEXT DEFAULT 'draft',
15
+ engagement TEXT,
16
+ created_at TEXT DEFAULT (datetime('now'))
17
+ );
18
+ CREATE INDEX IF NOT EXISTS idx_content_status ON content_pieces(status);
19
+ CREATE INDEX IF NOT EXISTS idx_content_platform ON content_pieces(platform);
20
+ CREATE INDEX IF NOT EXISTS idx_content_scheduled ON content_pieces(scheduled_for);
21
+ `);
22
+ }
23
+ // ── Engine ──────────────────────────────────────────────────
24
+ export class ContentForge {
25
+ db;
26
+ config;
27
+ log = getLogger();
28
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
29
+ llmService = null;
30
+ socialService = null;
31
+ actionBridge = null;
32
+ // Prepared statements
33
+ stmtInsert;
34
+ stmtGetById;
35
+ stmtUpdateStatus;
36
+ stmtSetSchedule;
37
+ stmtSetEngagement;
38
+ stmtGetByStatus;
39
+ stmtGetSchedule;
40
+ stmtGetBest;
41
+ stmtCountByStatus;
42
+ stmtAvgEngagement;
43
+ constructor(db, config) {
44
+ this.db = db;
45
+ this.config = {
46
+ brainName: config.brainName,
47
+ defaultPlatform: config.defaultPlatform ?? 'bluesky',
48
+ maxDraftsPerCycle: config.maxDraftsPerCycle ?? 5,
49
+ };
50
+ runContentForgeMigration(db);
51
+ this.stmtInsert = db.prepare(`
52
+ INSERT INTO content_pieces (source_type, source_id, platform, title, body, hashtags, status)
53
+ VALUES (?, ?, ?, ?, ?, ?, 'draft')
54
+ `);
55
+ this.stmtGetById = db.prepare(`SELECT * FROM content_pieces WHERE id = ?`);
56
+ this.stmtUpdateStatus = db.prepare(`UPDATE content_pieces SET status = ? WHERE id = ?`);
57
+ this.stmtSetSchedule = db.prepare(`UPDATE content_pieces SET scheduled_for = ?, status = 'scheduled' WHERE id = ?`);
58
+ this.stmtSetEngagement = db.prepare(`UPDATE content_pieces SET engagement = ? WHERE id = ?`);
59
+ this.stmtGetByStatus = db.prepare(`SELECT * FROM content_pieces WHERE status = ? ORDER BY created_at DESC LIMIT ?`);
60
+ this.stmtGetSchedule = db.prepare(`SELECT * FROM content_pieces WHERE status = 'scheduled' ORDER BY scheduled_for ASC`);
61
+ this.stmtGetBest = db.prepare(`SELECT * FROM content_pieces WHERE status = 'published' AND engagement IS NOT NULL ORDER BY json_extract(engagement, '$.likes') + json_extract(engagement, '$.reposts') + json_extract(engagement, '$.replies') DESC LIMIT ?`);
62
+ this.stmtCountByStatus = db.prepare(`SELECT status, COUNT(*) as count FROM content_pieces GROUP BY status`);
63
+ this.stmtAvgEngagement = db.prepare(`SELECT AVG(json_extract(engagement, '$.likes') + json_extract(engagement, '$.reposts') + json_extract(engagement, '$.replies')) as avg FROM content_pieces WHERE status = 'published' AND engagement IS NOT NULL`);
64
+ }
65
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
66
+ setLLMService(service) { this.llmService = service; }
67
+ setSocialService(service) { this.socialService = service; }
68
+ setActionBridge(bridge) { this.actionBridge = bridge; }
69
+ /** Generate content from an insight */
70
+ generateFromInsight(insight, platform) {
71
+ const plat = platform ?? this.config.defaultPlatform;
72
+ const title = insight.insight.substring(0, 80);
73
+ const body = insight.insight;
74
+ const hashtags = this.extractHashtags(body);
75
+ return this.storePiece('insight', insight.id, plat, title, body, hashtags);
76
+ }
77
+ /** Generate content from a mission report */
78
+ generateFromMission(mission, platform) {
79
+ const plat = platform ?? this.config.defaultPlatform;
80
+ const title = `Research: ${mission.topic.substring(0, 60)}`;
81
+ const body = mission.summary ?? mission.topic;
82
+ const hashtags = this.extractHashtags(body);
83
+ return this.storePiece('mission', mission.id, plat, title, body, hashtags);
84
+ }
85
+ /** Generate content from a tech trend */
86
+ generateFromTrend(trend, platform) {
87
+ const plat = platform ?? this.config.defaultPlatform;
88
+ const title = `Trend: ${trend.name}`;
89
+ const body = trend.description ?? trend.name;
90
+ const hashtags = [trend.category ?? 'tech', trend.name.toLowerCase().replace(/\s+/g, '')];
91
+ return this.storePiece('trend', undefined, plat, title, body, hashtags);
92
+ }
93
+ /** Generate content from a principle */
94
+ generateFromPrinciple(principle, platform) {
95
+ const plat = platform ?? this.config.defaultPlatform;
96
+ const title = principle.statement.substring(0, 80);
97
+ const body = principle.statement;
98
+ const hashtags = [principle.domain ?? 'knowledge'].filter(Boolean);
99
+ return this.storePiece('principle', principle.id, plat, title, body, hashtags);
100
+ }
101
+ /** Schedule a piece for later publication */
102
+ schedule(pieceId, when) {
103
+ const row = this.stmtGetById.get(pieceId);
104
+ if (!row)
105
+ throw new Error(`Content #${pieceId} not found`);
106
+ this.stmtSetSchedule.run(when, pieceId);
107
+ this.log.info(`[content-forge] Scheduled #${pieceId} for ${when}`);
108
+ }
109
+ /** Publish immediately */
110
+ async publishNow(pieceId) {
111
+ const row = this.stmtGetById.get(pieceId);
112
+ if (!row)
113
+ throw new Error(`Content #${pieceId} not found`);
114
+ if (!this.socialService) {
115
+ this.stmtUpdateStatus.run('failed', pieceId);
116
+ return { success: false };
117
+ }
118
+ try {
119
+ const result = await this.socialService.post(row.platform, row.body);
120
+ this.stmtUpdateStatus.run('published', pieceId);
121
+ this.log.info(`[content-forge] Published #${pieceId} on ${row.platform}`);
122
+ return { success: true, postId: result.id };
123
+ }
124
+ catch (err) {
125
+ this.stmtUpdateStatus.run('failed', pieceId);
126
+ this.log.warn(`[content-forge] Publish failed for #${pieceId}: ${err.message}`);
127
+ return { success: false };
128
+ }
129
+ }
130
+ /** Get scheduled content */
131
+ getSchedule() {
132
+ return this.stmtGetSchedule.all().map(deserializeContent);
133
+ }
134
+ /** Record engagement metrics */
135
+ recordEngagement(pieceId, metrics) {
136
+ this.stmtSetEngagement.run(JSON.stringify(metrics), pieceId);
137
+ }
138
+ /** Get best performing published content */
139
+ getBestPerforming(limit) {
140
+ return this.stmtGetBest.all(limit ?? 10).map(deserializeContent);
141
+ }
142
+ /** Get optimal posting time for a platform (placeholder — learns from engagement data) */
143
+ getOptimalTime(platform) {
144
+ // Simple heuristic: best engagement windows by platform
145
+ const defaults = {
146
+ bluesky: '10:00',
147
+ reddit: '08:00',
148
+ telegram: '12:00',
149
+ discord: '18:00',
150
+ };
151
+ return defaults[platform] ?? '10:00';
152
+ }
153
+ /** Get content pieces by status */
154
+ getByStatus(status, limit) {
155
+ return this.stmtGetByStatus.all(status, limit ?? 50).map(deserializeContent);
156
+ }
157
+ /** Get a single piece by ID */
158
+ getPiece(id) {
159
+ const row = this.stmtGetById.get(id);
160
+ return row ? deserializeContent(row) : null;
161
+ }
162
+ /** Auto-schedule a piece at optimal time and create ActionBridge publish proposal */
163
+ autoScheduleAndPublish(pieceId) {
164
+ const piece = this.getPiece(pieceId);
165
+ if (!piece)
166
+ return;
167
+ const optimalTime = this.getOptimalTime(piece.platform);
168
+ const today = new Date().toISOString().split('T')[0];
169
+ this.schedule(pieceId, `${today}T${optimalTime}:00Z`);
170
+ if (this.actionBridge) {
171
+ this.actionBridge.propose({
172
+ source: 'creative',
173
+ type: 'publish_content',
174
+ title: `Publish: ${piece.title}`,
175
+ description: `Auto-scheduled content #${pieceId} for ${piece.platform}`,
176
+ confidence: 0.85,
177
+ payload: { pieceId, platform: piece.platform, title: piece.title },
178
+ });
179
+ }
180
+ }
181
+ /** Get status overview */
182
+ getStatus() {
183
+ const counts = this.stmtCountByStatus.all();
184
+ const countMap = {};
185
+ for (const c of counts)
186
+ countMap[c.status] = c.count;
187
+ const avgRow = this.stmtAvgEngagement.get();
188
+ return {
189
+ drafts: countMap['draft'] ?? 0,
190
+ scheduled: countMap['scheduled'] ?? 0,
191
+ published: countMap['published'] ?? 0,
192
+ avgEngagement: avgRow?.avg ?? 0,
193
+ };
194
+ }
195
+ // ── Private ──────────────────────────────────────────────
196
+ storePiece(sourceType, sourceId, platform, title, body, hashtags) {
197
+ const result = this.stmtInsert.run(sourceType, sourceId ?? null, platform, title, body, JSON.stringify(hashtags));
198
+ const id = Number(result.lastInsertRowid);
199
+ this.log.info(`[content-forge] Created #${id}: ${title} (${sourceType}→${platform})`);
200
+ return { id, sourceType, sourceId, platform, title, body, hashtags, status: 'draft' };
201
+ }
202
+ extractHashtags(text) {
203
+ const words = text.toLowerCase().split(/\s+/);
204
+ const tags = [];
205
+ for (const w of words) {
206
+ if (w.startsWith('#'))
207
+ tags.push(w.replace(/[^a-z0-9]/g, ''));
208
+ }
209
+ if (tags.length === 0) {
210
+ // Extract key terms
211
+ const keywords = words.filter(w => w.length > 5).slice(0, 3);
212
+ return keywords;
213
+ }
214
+ return tags.slice(0, 5);
215
+ }
216
+ }
217
+ function deserializeContent(row) {
218
+ return {
219
+ id: row.id,
220
+ sourceType: row.source_type,
221
+ sourceId: row.source_id ?? undefined,
222
+ platform: row.platform,
223
+ title: row.title,
224
+ body: row.body,
225
+ hashtags: JSON.parse(row.hashtags || '[]'),
226
+ scheduledFor: row.scheduled_for ?? undefined,
227
+ status: row.status,
228
+ engagement: row.engagement ? JSON.parse(row.engagement) : undefined,
229
+ createdAt: row.created_at,
230
+ };
231
+ }
232
+ //# sourceMappingURL=content-forge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-forge.js","sourceRoot":"","sources":["../../src/content/content-forge.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAqC/C,8DAA8D;AAE9D,MAAM,UAAU,wBAAwB,CAAC,EAAqB;IAC5D,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;GAiBP,CAAC,CAAC;AACL,CAAC;AAED,+DAA+D;AAE/D,MAAM,OAAO,YAAY;IACN,EAAE,CAAoB;IACtB,MAAM,CAA+B;IACrC,GAAG,GAAG,SAAS,EAAE,CAAC;IAEnC,8DAA8D;IACtD,UAAU,GAAQ,IAAI,CAAC;IACvB,aAAa,GAAoF,IAAI,CAAC;IACtG,YAAY,GAAmE,IAAI,CAAC;IAE5F,sBAAsB;IACL,UAAU,CAAC;IACX,WAAW,CAAC;IACZ,gBAAgB,CAAC;IACjB,eAAe,CAAC;IAChB,iBAAiB,CAAC;IAClB,eAAe,CAAC;IAChB,eAAe,CAAC;IAChB,WAAW,CAAC;IACZ,iBAAiB,CAAC;IAClB,iBAAiB,CAAC;IAEnC,YAAY,EAAqB,EAAE,MAA0B;QAC3D,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,MAAM,GAAG;YACZ,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,eAAe,EAAE,MAAM,CAAC,eAAe,IAAI,SAAS;YACpD,iBAAiB,EAAE,MAAM,CAAC,iBAAiB,IAAI,CAAC;SACjD,CAAC;QACF,wBAAwB,CAAC,EAAE,CAAC,CAAC;QAE7B,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC,OAAO,CAAC;;;KAG5B,CAAC,CAAC;QACH,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC,OAAO,CAAC,2CAA2C,CAAC,CAAC;QAC3E,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC,OAAO,CAAC,mDAAmD,CAAC,CAAC;QACxF,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC,OAAO,CAAC,gFAAgF,CAAC,CAAC;QACpH,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC,OAAO,CAAC,uDAAuD,CAAC,CAAC;QAC7F,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC,OAAO,CAAC,gFAAgF,CAAC,CAAC;QACpH,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC,OAAO,CAAC,oFAAoF,CAAC,CAAC;QACxH,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC,OAAO,CAAC,8NAA8N,CAAC,CAAC;QAC9P,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC,OAAO,CAAC,sEAAsE,CAAC,CAAC;QAC5G,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC,OAAO,CAAC,kNAAkN,CAAC,CAAC;IAC1P,CAAC;IAED,8DAA8D;IAC9D,aAAa,CAAC,OAAY,IAAU,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,CAAC,CAAC;IAChE,gBAAgB,CAAC,OAAiF,IAAU,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC,CAAC,CAAC;IAC3I,eAAe,CAAC,MAA+D,IAAU,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,CAAC,CAAC;IAEtH,uCAAuC;IACvC,mBAAmB,CAAC,OAA+D,EAAE,QAAmC;QACtH,MAAM,IAAI,GAAG,QAAQ,IAAI,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC;QACrD,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC/C,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC;QAC7B,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;QAC5C,OAAO,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;IAC7E,CAAC;IAED,6CAA6C;IAC7C,mBAAmB,CAAC,OAAyD,EAAE,QAAmC;QAChH,MAAM,IAAI,GAAG,QAAQ,IAAI,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC;QACrD,MAAM,KAAK,GAAG,aAAa,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;QAC5D,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,KAAK,CAAC;QAC9C,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;QAC5C,OAAO,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;IAC7E,CAAC;IAED,yCAAyC;IACzC,iBAAiB,CAAC,KAAgE,EAAE,QAAmC;QACrH,MAAM,IAAI,GAAG,QAAQ,IAAI,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC;QACrD,MAAM,KAAK,GAAG,UAAU,KAAK,CAAC,IAAI,EAAE,CAAC;QACrC,MAAM,IAAI,GAAG,KAAK,CAAC,WAAW,IAAI,KAAK,CAAC,IAAI,CAAC;QAC7C,MAAM,QAAQ,GAAG,CAAC,KAAK,CAAC,QAAQ,IAAI,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC;QAC1F,OAAO,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;IAC1E,CAAC;IAED,wCAAwC;IACxC,qBAAqB,CAAC,SAA8D,EAAE,QAAmC;QACvH,MAAM,IAAI,GAAG,QAAQ,IAAI,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC;QACrD,MAAM,KAAK,GAAG,SAAS,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACnD,MAAM,IAAI,GAAG,SAAS,CAAC,SAAS,CAAC;QACjC,MAAM,QAAQ,GAAG,CAAC,SAAS,CAAC,MAAM,IAAI,WAAW,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACnE,OAAO,IAAI,CAAC,UAAU,CAAC,WAAW,EAAE,SAAS,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;IACjF,CAAC;IAED,6CAA6C;IAC7C,QAAQ,CAAC,OAAe,EAAE,IAAY;QACpC,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAA2B,CAAC;QACpE,IAAI,CAAC,GAAG;YAAE,MAAM,IAAI,KAAK,CAAC,YAAY,OAAO,YAAY,CAAC,CAAC;QAC3D,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACxC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,8BAA8B,OAAO,QAAQ,IAAI,EAAE,CAAC,CAAC;IACrE,CAAC;IAED,0BAA0B;IAC1B,KAAK,CAAC,UAAU,CAAC,OAAe;QAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAA2B,CAAC;QACpE,IAAI,CAAC,GAAG;YAAE,MAAM,IAAI,KAAK,CAAC,YAAY,OAAO,YAAY,CAAC,CAAC;QAE3D,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;YACxB,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAC7C,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QAC5B,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;YACrE,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;YAChD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,8BAA8B,OAAO,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;YAC1E,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC;QAC9C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAC7C,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,uCAAuC,OAAO,KAAM,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;YAC3F,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QAC5B,CAAC;IACH,CAAC;IAED,4BAA4B;IAC5B,WAAW;QACT,OAAQ,IAAI,CAAC,eAAe,CAAC,GAAG,EAAmB,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;IAC9E,CAAC;IAED,gCAAgC;IAChC,gBAAgB,CAAC,OAAe,EAAE,OAA0B;QAC1D,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC;IAC/D,CAAC;IAED,4CAA4C;IAC5C,iBAAiB,CAAC,KAAc;QAC9B,OAAQ,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAkB,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;IACrF,CAAC;IAED,0FAA0F;IAC1F,cAAc,CAAC,QAAgB;QAC7B,wDAAwD;QACxD,MAAM,QAAQ,GAA2B;YACvC,OAAO,EAAE,OAAO;YAChB,MAAM,EAAE,OAAO;YACf,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,OAAO;SACjB,CAAC;QACF,OAAO,QAAQ,CAAC,QAAQ,CAAC,IAAI,OAAO,CAAC;IACvC,CAAC;IAED,mCAAmC;IACnC,WAAW,CAAC,MAAc,EAAE,KAAc;QACxC,OAAQ,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,IAAI,EAAE,CAAkB,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;IACjG,CAAC;IAED,+BAA+B;IAC/B,QAAQ,CAAC,EAAU;QACjB,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAA2B,CAAC;QAC/D,OAAO,GAAG,CAAC,CAAC,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC9C,CAAC;IAED,qFAAqF;IACrF,sBAAsB,CAAC,OAAe;QACpC,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACrC,IAAI,CAAC,KAAK;YAAE,OAAO;QAEnB,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACxD,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACrD,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI,WAAW,MAAM,CAAC,CAAC;QAEtD,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC;gBACxB,MAAM,EAAE,UAAU;gBAClB,IAAI,EAAE,iBAAiB;gBACvB,KAAK,EAAE,YAAY,KAAK,CAAC,KAAK,EAAE;gBAChC,WAAW,EAAE,2BAA2B,OAAO,QAAQ,KAAK,CAAC,QAAQ,EAAE;gBACvE,UAAU,EAAE,IAAI;gBAChB,OAAO,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE;aACnE,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,0BAA0B;IAC1B,SAAS;QACP,MAAM,MAAM,GAAG,IAAI,CAAC,iBAAiB,CAAC,GAAG,EAA8C,CAAC;QACxF,MAAM,QAAQ,GAA2B,EAAE,CAAC;QAC5C,KAAK,MAAM,CAAC,IAAI,MAAM;YAAE,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC;QAErD,MAAM,MAAM,GAAG,IAAI,CAAC,iBAAiB,CAAC,GAAG,EAA4B,CAAC;QAEtE,OAAO;YACL,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC;YAC9B,SAAS,EAAE,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC;YACrC,SAAS,EAAE,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC;YACrC,aAAa,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;SAChC,CAAC;IACJ,CAAC;IAED,4DAA4D;IAEpD,UAAU,CAAC,UAAsC,EAAE,QAA4B,EAAE,QAAkC,EAAE,KAAa,EAAE,IAAY,EAAE,QAAkB;QAC1K,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,UAAU,EAAE,QAAQ,IAAI,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;QAClH,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;QAC1C,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,4BAA4B,EAAE,KAAK,KAAK,KAAK,UAAU,IAAI,QAAQ,GAAG,CAAC,CAAC;QACtF,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;IACxF,CAAC;IAEO,eAAe,CAAC,IAAY;QAClC,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC9C,MAAM,IAAI,GAAa,EAAE,CAAC;QAC1B,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;YACtB,IAAI,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC;gBAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC,CAAC;QAChE,CAAC;QACD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,oBAAoB;YACpB,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC7D,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC1B,CAAC;CACF;AAkBD,SAAS,kBAAkB,CAAC,GAAe;IACzC,OAAO;QACL,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,UAAU,EAAE,GAAG,CAAC,WAAyC;QACzD,QAAQ,EAAE,GAAG,CAAC,SAAS,IAAI,SAAS;QACpC,QAAQ,EAAE,GAAG,CAAC,QAAoC;QAClD,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,IAAI,IAAI,CAAC;QAC1C,YAAY,EAAE,GAAG,CAAC,aAAa,IAAI,SAAS;QAC5C,MAAM,EAAE,GAAG,CAAC,MAAgC;QAC5C,UAAU,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS;QACnE,SAAS,EAAE,GAAG,CAAC,UAAU;KAC1B,CAAC;AACJ,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { ContentForge, runContentForgeMigration } from './content-forge.js';
2
+ export type { ContentPiece, ContentEngagement, ContentForgeConfig, ContentForgeStatus, } from './content-forge.js';
3
+ export { AutoPublisher } from './auto-publisher.js';
4
+ export type { AutoPublisherConfig, AutoPublisherStats } from './auto-publisher.js';
@@ -0,0 +1,3 @@
1
+ export { ContentForge, runContentForgeMigration } from './content-forge.js';
2
+ export { AutoPublisher } from './auto-publisher.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/content/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAM5E,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,151 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
+ import Database from 'better-sqlite3';
3
+ vi.mock('../../utils/logger.js', () => ({
4
+ getLogger: () => ({ info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() }),
5
+ }));
6
+ import { CreativeEngine, runCreativeMigration } from '../creative-engine.js';
7
+ describe('CreativeEngine', () => {
8
+ let db;
9
+ beforeEach(() => { db = new Database(':memory:'); });
10
+ afterEach(() => { db.close(); });
11
+ it('creates an instance without errors', () => {
12
+ const engine = new CreativeEngine(db, { brainName: 'test' });
13
+ expect(engine).toBeDefined();
14
+ });
15
+ it('getStatus returns initial empty state', () => {
16
+ const engine = new CreativeEngine(db, { brainName: 'test' });
17
+ const status = engine.getStatus();
18
+ expect(status.totalInsights).toBe(0);
19
+ expect(status.byType).toEqual({});
20
+ expect(status.byStatus).toEqual({});
21
+ expect(status.topInsights).toEqual([]);
22
+ });
23
+ it('crossPollinate returns empty array without distiller', () => {
24
+ const engine = new CreativeEngine(db, { brainName: 'test' });
25
+ const result = engine.crossPollinate();
26
+ expect(result).toEqual([]);
27
+ });
28
+ it('crossPollinate returns insights when distiller provides multi-domain principles', () => {
29
+ const engine = new CreativeEngine(db, { brainName: 'test', overlapThreshold: 1.0 });
30
+ engine.setKnowledgeDistiller({
31
+ distill: () => ({
32
+ principles: [
33
+ { statement: 'caching improves performance significantly', domain: 'engineering' },
34
+ { statement: 'diversification reduces portfolio variance', domain: 'finance' },
35
+ { statement: 'redundancy prevents catastrophic system failure', domain: 'engineering' },
36
+ { statement: 'hedging minimizes downside exposure risk', domain: 'finance' },
37
+ ],
38
+ }),
39
+ });
40
+ const insights = engine.crossPollinate();
41
+ expect(insights.length).toBeGreaterThan(0);
42
+ expect(insights[0].type).toBe('cross_pollination');
43
+ expect(insights[0].status).toBe('raw');
44
+ expect(insights[0].noveltyScore).toBeGreaterThan(0);
45
+ expect(insights[0].id).toBeGreaterThan(0);
46
+ // Verify stored in DB
47
+ const status = engine.getStatus();
48
+ expect(status.totalInsights).toBe(insights.length);
49
+ expect(status.byType['cross_pollination']).toBe(insights.length);
50
+ });
51
+ it('findAnalogies returns empty array without distiller', () => {
52
+ const engine = new CreativeEngine(db, { brainName: 'test' });
53
+ const result = engine.findAnalogies('some concept');
54
+ expect(result).toEqual([]);
55
+ });
56
+ it('findAnalogies finds structurally similar principles', () => {
57
+ const engine = new CreativeEngine(db, { brainName: 'test' });
58
+ engine.setKnowledgeDistiller({
59
+ distill: () => ({
60
+ principles: [
61
+ { statement: 'caching improves response times significantly', domain: 'engineering' },
62
+ { statement: 'caching improves database query performance', domain: 'databases' },
63
+ { statement: 'something completely unrelated', domain: 'art' },
64
+ ],
65
+ }),
66
+ });
67
+ const analogies = engine.findAnalogies('caching improves application performance');
68
+ expect(analogies.length).toBeGreaterThan(0);
69
+ for (const a of analogies) {
70
+ expect(a.concept).toBe('caching improves application performance');
71
+ expect(a.similarity).toBeGreaterThan(0.1);
72
+ expect(a.similarity).toBeLessThan(0.6);
73
+ expect(a.explanation).toContain('Shared concepts');
74
+ }
75
+ });
76
+ it('getInsights returns empty list initially', () => {
77
+ const engine = new CreativeEngine(db, { brainName: 'test' });
78
+ const insights = engine.getInsights();
79
+ expect(insights).toEqual([]);
80
+ });
81
+ it('getInsights returns stored insights after crossPollinate', () => {
82
+ const engine = new CreativeEngine(db, { brainName: 'test', overlapThreshold: 1.0 });
83
+ engine.setKnowledgeDistiller({
84
+ distill: () => ({
85
+ principles: [
86
+ { statement: 'parallel processing speeds computation', domain: 'computing' },
87
+ { statement: 'teamwork divides workload effectively', domain: 'management' },
88
+ ],
89
+ }),
90
+ });
91
+ engine.crossPollinate();
92
+ const insights = engine.getInsights();
93
+ expect(insights.length).toBeGreaterThan(0);
94
+ expect(insights[0].id).toBeDefined();
95
+ expect(insights[0].createdAt).toBeDefined();
96
+ expect(insights[0].sourceA.domain).toBeDefined();
97
+ expect(insights[0].sourceB.domain).toBeDefined();
98
+ });
99
+ it('getInsights filters by status', () => {
100
+ const engine = new CreativeEngine(db, { brainName: 'test', overlapThreshold: 1.0 });
101
+ engine.setKnowledgeDistiller({
102
+ distill: () => ({
103
+ principles: [
104
+ { statement: 'abstraction hides complexity behind interfaces', domain: 'software' },
105
+ { statement: 'delegation assigns responsibility to subordinates', domain: 'leadership' },
106
+ ],
107
+ }),
108
+ });
109
+ engine.crossPollinate();
110
+ const raw = engine.getInsights(20, 'raw');
111
+ expect(raw.length).toBeGreaterThan(0);
112
+ const tested = engine.getInsights(20, 'tested');
113
+ expect(tested).toEqual([]);
114
+ });
115
+ it('migration is idempotent', () => {
116
+ const engine = new CreativeEngine(db, { brainName: 'test', overlapThreshold: 1.0 });
117
+ engine.setKnowledgeDistiller({
118
+ distill: () => ({
119
+ principles: [
120
+ { statement: 'monitoring detects anomalies early', domain: 'ops' },
121
+ { statement: 'early diagnosis improves treatment outcomes', domain: 'medicine' },
122
+ ],
123
+ }),
124
+ });
125
+ engine.crossPollinate();
126
+ // Running migration again should not destroy data
127
+ runCreativeMigration(db);
128
+ const status = engine.getStatus();
129
+ expect(status.totalInsights).toBeGreaterThan(0);
130
+ });
131
+ it('getStatus reflects insights by type and status', () => {
132
+ const engine = new CreativeEngine(db, { brainName: 'test' });
133
+ // Manually insert insights of different types
134
+ db.prepare(`
135
+ INSERT INTO creative_insights (type, source_a_domain, source_a_principle, source_b_domain, source_b_principle, insight, novelty_score, plausibility, status)
136
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
137
+ `).run('cross_pollination', 'domA', 'prinA', 'domB', 'prinB', 'insight1', 0.8, 0.5, 'raw');
138
+ db.prepare(`
139
+ INSERT INTO creative_insights (type, source_a_domain, source_a_principle, source_b_domain, source_b_principle, insight, novelty_score, plausibility, status)
140
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
141
+ `).run('imagination', 'domC', 'prinC', 'domD', 'prinD', 'insight2', 0.9, 0.6, 'tested');
142
+ const status = engine.getStatus();
143
+ expect(status.totalInsights).toBe(2);
144
+ expect(status.byType['cross_pollination']).toBe(1);
145
+ expect(status.byType['imagination']).toBe(1);
146
+ expect(status.byStatus['raw']).toBe(1);
147
+ expect(status.byStatus['tested']).toBe(1);
148
+ expect(status.topInsights.length).toBe(2);
149
+ });
150
+ });
151
+ //# sourceMappingURL=creative-engine.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"creative-engine.test.js","sourceRoot":"","sources":["../../../src/creative/__tests__/creative-engine.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,159 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
+ import Database from 'better-sqlite3';
3
+ vi.mock('../../utils/logger.js', () => ({
4
+ getLogger: () => ({ info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() }),
5
+ }));
6
+ import { CrossBrainSignalRouter, runSignalRouterMigration } from '../signal-router.js';
7
+ describe('CrossBrainSignalRouter', () => {
8
+ let db;
9
+ beforeEach(() => { db = new Database(':memory:'); });
10
+ afterEach(() => { db.close(); });
11
+ it('creates and runs migration', () => {
12
+ const router = new CrossBrainSignalRouter(db, 'test-brain');
13
+ const status = router.getStatus();
14
+ expect(status.totalSignals).toBe(0);
15
+ expect(status.handlerCount).toBe(0);
16
+ });
17
+ it('emits a signal and persists it', async () => {
18
+ const router = new CrossBrainSignalRouter(db, 'trading-brain');
19
+ const id = await router.emit({
20
+ targetBrain: 'marketing-brain',
21
+ signalType: 'trade_signal',
22
+ payload: { symbol: 'BTC', direction: 'bullish' },
23
+ confidence: 0.8,
24
+ });
25
+ expect(id).toMatch(/^sig-/);
26
+ const history = router.getHistory();
27
+ expect(history).toHaveLength(1);
28
+ expect(history[0].sourceBrain).toBe('trading-brain');
29
+ expect(history[0].targetBrain).toBe('marketing-brain');
30
+ expect(history[0].signalType).toBe('trade_signal');
31
+ expect(history[0].payload.symbol).toBe('BTC');
32
+ });
33
+ it('handles incoming signals and dispatches to handlers', async () => {
34
+ const router = new CrossBrainSignalRouter(db, 'marketing-brain');
35
+ const handler = vi.fn();
36
+ router.onSignal('trade_signal', handler);
37
+ await router.handleIncoming({
38
+ id: 'sig-test-1',
39
+ sourceBrain: 'trading-brain',
40
+ targetBrain: 'marketing-brain',
41
+ signalType: 'trade_signal',
42
+ payload: { symbol: 'ETH', direction: 'bearish' },
43
+ confidence: 0.7,
44
+ timestamp: Date.now(),
45
+ processed: false,
46
+ });
47
+ expect(handler).toHaveBeenCalledOnce();
48
+ expect(handler.mock.calls[0][0].payload.symbol).toBe('ETH');
49
+ });
50
+ it('registers multiple handlers for same signal type', async () => {
51
+ const router = new CrossBrainSignalRouter(db, 'test-brain');
52
+ const handler1 = vi.fn();
53
+ const handler2 = vi.fn();
54
+ router.onSignal('trade_signal', handler1);
55
+ router.onSignal('trade_signal', handler2);
56
+ await router.handleIncoming({
57
+ id: 'sig-test-2',
58
+ sourceBrain: 'other-brain',
59
+ targetBrain: 'test-brain',
60
+ signalType: 'trade_signal',
61
+ payload: {},
62
+ confidence: 0.5,
63
+ timestamp: Date.now(),
64
+ processed: false,
65
+ });
66
+ expect(handler1).toHaveBeenCalledOnce();
67
+ expect(handler2).toHaveBeenCalledOnce();
68
+ });
69
+ it('handles handler errors gracefully', async () => {
70
+ const router = new CrossBrainSignalRouter(db, 'test-brain');
71
+ router.onSignal('bad_signal', () => { throw new Error('Handler crash'); });
72
+ // Should not throw
73
+ await router.handleIncoming({
74
+ id: 'sig-test-3',
75
+ sourceBrain: 'other',
76
+ targetBrain: 'test-brain',
77
+ signalType: 'bad_signal',
78
+ payload: {},
79
+ confidence: 0.5,
80
+ timestamp: Date.now(),
81
+ processed: false,
82
+ });
83
+ });
84
+ it('processQueue processes unprocessed signals', async () => {
85
+ const router = new CrossBrainSignalRouter(db, 'test-brain');
86
+ const handler = vi.fn();
87
+ router.onSignal('test_signal', handler);
88
+ // Directly insert an unprocessed signal
89
+ await router.emit({ targetBrain: 'test-brain', signalType: 'test_signal', payload: { x: 1 } });
90
+ const processed = await router.processQueue();
91
+ expect(processed).toBe(1);
92
+ expect(handler).toHaveBeenCalledOnce();
93
+ });
94
+ it('marks signals as processed', async () => {
95
+ const router = new CrossBrainSignalRouter(db, 'test-brain');
96
+ await router.emit({ targetBrain: 'test-brain', signalType: 'test', payload: {} });
97
+ await router.processQueue();
98
+ // Second process should find nothing
99
+ const processed = await router.processQueue();
100
+ expect(processed).toBe(0);
101
+ });
102
+ it('getStatus returns signal counts by type', async () => {
103
+ const router = new CrossBrainSignalRouter(db, 'brain');
104
+ await router.emit({ targetBrain: 'marketing', signalType: 'trade_signal', payload: {} });
105
+ await router.emit({ targetBrain: 'marketing', signalType: 'trade_signal', payload: {} });
106
+ await router.emit({ targetBrain: 'trading', signalType: 'engagement_signal', payload: {} });
107
+ const status = router.getStatus();
108
+ expect(status.totalSignals).toBe(3);
109
+ expect(status.byType).toHaveLength(2);
110
+ });
111
+ it('getHistory respects limit', async () => {
112
+ const router = new CrossBrainSignalRouter(db, 'brain');
113
+ for (let i = 0; i < 5; i++) {
114
+ await router.emit({ targetBrain: 'other', signalType: 'sig', payload: { i } });
115
+ }
116
+ expect(router.getHistory(3)).toHaveLength(3);
117
+ expect(router.getHistory()).toHaveLength(5);
118
+ });
119
+ it('emits with notifier when set', async () => {
120
+ const router = new CrossBrainSignalRouter(db, 'brain');
121
+ const notifier = { notifyPeer: vi.fn().mockResolvedValue(undefined), notify: vi.fn() };
122
+ router.setNotifier(notifier);
123
+ await router.emit({ targetBrain: 'marketing-brain', signalType: 'test', payload: { foo: 'bar' } });
124
+ expect(notifier.notifyPeer).toHaveBeenCalledOnce();
125
+ expect(notifier.notifyPeer.mock.calls[0][0]).toBe('marketing-brain');
126
+ expect(notifier.notifyPeer.mock.calls[0][1]).toBe('signal:test');
127
+ });
128
+ it('handles notifier failure gracefully', async () => {
129
+ const router = new CrossBrainSignalRouter(db, 'brain');
130
+ const notifier = { notifyPeer: vi.fn().mockRejectedValue(new Error('offline')), notify: vi.fn() };
131
+ router.setNotifier(notifier);
132
+ // Should not throw
133
+ const id = await router.emit({ targetBrain: 'offline-brain', signalType: 'test', payload: {} });
134
+ expect(id).toMatch(/^sig-/);
135
+ });
136
+ it('handles duplicate incoming signal IDs', async () => {
137
+ const router = new CrossBrainSignalRouter(db, 'brain');
138
+ const signal = {
139
+ id: 'sig-dup-1',
140
+ sourceBrain: 'other',
141
+ targetBrain: 'brain',
142
+ signalType: 'test',
143
+ payload: {},
144
+ confidence: 0.5,
145
+ timestamp: Date.now(),
146
+ processed: false,
147
+ };
148
+ await router.handleIncoming(signal);
149
+ // Second call with same ID should not throw
150
+ await router.handleIncoming(signal);
151
+ });
152
+ it('migration is idempotent', () => {
153
+ const router = new CrossBrainSignalRouter(db, 'brain');
154
+ runSignalRouterMigration(db); // Run again
155
+ const status = router.getStatus();
156
+ expect(status.totalSignals).toBe(0);
157
+ });
158
+ });
159
+ //# sourceMappingURL=signal-router.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signal-router.test.js","sourceRoot":"","sources":["../../../src/cross-brain/__tests__/signal-router.test.ts"],"names":[],"mappings":"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"}