@timmeck/marketing-brain 0.2.1 → 0.4.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 (160) hide show
  1. package/Dockerfile +22 -0
  2. package/README.md +20 -3
  3. package/dashboard.html +6 -0
  4. package/dist/cli/colors.d.ts +11 -24
  5. package/dist/cli/colors.js +3 -46
  6. package/dist/cli/colors.js.map +1 -1
  7. package/dist/cli/commands/dashboard.js +15 -0
  8. package/dist/cli/commands/dashboard.js.map +1 -1
  9. package/dist/cli/commands/peers.d.ts +2 -0
  10. package/dist/cli/commands/peers.js +38 -0
  11. package/dist/cli/commands/peers.js.map +1 -0
  12. package/dist/config.js +2 -29
  13. package/dist/config.js.map +1 -1
  14. package/dist/db/connection.d.ts +1 -2
  15. package/dist/db/connection.js +1 -18
  16. package/dist/db/connection.js.map +1 -1
  17. package/dist/hooks/post-tool-use.d.ts +2 -0
  18. package/dist/hooks/post-tool-use.js +182 -0
  19. package/dist/hooks/post-tool-use.js.map +1 -0
  20. package/dist/index.js +2 -0
  21. package/dist/index.js.map +1 -1
  22. package/dist/ipc/client.d.ts +1 -13
  23. package/dist/ipc/client.js +1 -92
  24. package/dist/ipc/client.js.map +1 -1
  25. package/dist/ipc/protocol.d.ts +1 -8
  26. package/dist/ipc/protocol.js +1 -28
  27. package/dist/ipc/protocol.js.map +1 -1
  28. package/dist/ipc/router.d.ts +2 -0
  29. package/dist/ipc/router.js +30 -0
  30. package/dist/ipc/router.js.map +1 -1
  31. package/dist/ipc/server.d.ts +1 -14
  32. package/dist/ipc/server.js +1 -129
  33. package/dist/ipc/server.js.map +1 -1
  34. package/dist/learning/confidence-scorer.d.ts +1 -5
  35. package/dist/learning/confidence-scorer.js +2 -13
  36. package/dist/learning/confidence-scorer.js.map +1 -1
  37. package/dist/learning/learning-engine.d.ts +2 -5
  38. package/dist/learning/learning-engine.js +3 -20
  39. package/dist/learning/learning-engine.js.map +1 -1
  40. package/dist/marketing-core.d.ts +2 -0
  41. package/dist/marketing-core.js +22 -2
  42. package/dist/marketing-core.js.map +1 -1
  43. package/dist/mcp/server.js +5 -60
  44. package/dist/mcp/server.js.map +1 -1
  45. package/dist/mcp/tools.js +29 -0
  46. package/dist/mcp/tools.js.map +1 -1
  47. package/dist/research/research-engine.d.ts +2 -5
  48. package/dist/research/research-engine.js +3 -24
  49. package/dist/research/research-engine.js.map +1 -1
  50. package/dist/services/analytics.service.d.ts +1 -1
  51. package/dist/services/synapse.service.d.ts +10 -10
  52. package/dist/synapses/activation.d.ts +2 -13
  53. package/dist/synapses/activation.js +2 -49
  54. package/dist/synapses/activation.js.map +1 -1
  55. package/dist/synapses/decay.d.ts +2 -11
  56. package/dist/synapses/decay.js +2 -26
  57. package/dist/synapses/decay.js.map +1 -1
  58. package/dist/synapses/hebbian.d.ts +2 -13
  59. package/dist/synapses/hebbian.js +2 -34
  60. package/dist/synapses/hebbian.js.map +1 -1
  61. package/dist/synapses/pathfinder.d.ts +2 -14
  62. package/dist/synapses/pathfinder.js +2 -49
  63. package/dist/synapses/pathfinder.js.map +1 -1
  64. package/dist/synapses/synapse-manager.d.ts +7 -23
  65. package/dist/synapses/synapse-manager.js +6 -63
  66. package/dist/synapses/synapse-manager.js.map +1 -1
  67. package/dist/types/ipc.types.d.ts +1 -11
  68. package/dist/utils/events.d.ts +4 -8
  69. package/dist/utils/events.js +2 -14
  70. package/dist/utils/events.js.map +1 -1
  71. package/dist/utils/hash.d.ts +1 -1
  72. package/dist/utils/hash.js +1 -4
  73. package/dist/utils/hash.js.map +1 -1
  74. package/dist/utils/logger.d.ts +3 -2
  75. package/dist/utils/logger.js +8 -35
  76. package/dist/utils/logger.js.map +1 -1
  77. package/dist/utils/paths.d.ts +2 -1
  78. package/dist/utils/paths.js +4 -13
  79. package/dist/utils/paths.js.map +1 -1
  80. package/eslint.config.js +14 -0
  81. package/package.json +9 -2
  82. package/.github/FUNDING.yml +0 -1
  83. package/.github/workflows/ci.yml +0 -27
  84. package/.mcp.json +0 -9
  85. package/src/api/server.ts +0 -86
  86. package/src/cli/colors.ts +0 -59
  87. package/src/cli/commands/campaign.ts +0 -66
  88. package/src/cli/commands/config.ts +0 -168
  89. package/src/cli/commands/dashboard.ts +0 -165
  90. package/src/cli/commands/doctor.ts +0 -110
  91. package/src/cli/commands/export.ts +0 -40
  92. package/src/cli/commands/import.ts +0 -84
  93. package/src/cli/commands/insights.ts +0 -44
  94. package/src/cli/commands/learn.ts +0 -24
  95. package/src/cli/commands/network.ts +0 -71
  96. package/src/cli/commands/post.ts +0 -47
  97. package/src/cli/commands/query.ts +0 -108
  98. package/src/cli/commands/rules.ts +0 -27
  99. package/src/cli/commands/start.ts +0 -100
  100. package/src/cli/commands/status.ts +0 -73
  101. package/src/cli/commands/stop.ts +0 -33
  102. package/src/cli/commands/suggest.ts +0 -64
  103. package/src/cli/ipc-helper.ts +0 -22
  104. package/src/cli/update-check.ts +0 -63
  105. package/src/config.ts +0 -110
  106. package/src/dashboard/renderer.ts +0 -136
  107. package/src/dashboard/server.ts +0 -140
  108. package/src/db/connection.ts +0 -22
  109. package/src/db/migrations/001_core_schema.ts +0 -63
  110. package/src/db/migrations/002_learning_schema.ts +0 -46
  111. package/src/db/migrations/003_synapse_schema.ts +0 -27
  112. package/src/db/migrations/004_insights_schema.ts +0 -38
  113. package/src/db/migrations/005_fts_indexes.ts +0 -77
  114. package/src/db/migrations/index.ts +0 -62
  115. package/src/db/repositories/audience.repository.ts +0 -53
  116. package/src/db/repositories/campaign.repository.ts +0 -72
  117. package/src/db/repositories/engagement.repository.ts +0 -108
  118. package/src/db/repositories/insight.repository.ts +0 -100
  119. package/src/db/repositories/post.repository.ts +0 -123
  120. package/src/db/repositories/rule.repository.ts +0 -87
  121. package/src/db/repositories/strategy.repository.ts +0 -82
  122. package/src/db/repositories/synapse.repository.ts +0 -148
  123. package/src/db/repositories/template.repository.ts +0 -76
  124. package/src/index.ts +0 -69
  125. package/src/ipc/__tests__/protocol.test.ts +0 -153
  126. package/src/ipc/client.ts +0 -110
  127. package/src/ipc/protocol.ts +0 -35
  128. package/src/ipc/router.ts +0 -126
  129. package/src/ipc/server.ts +0 -140
  130. package/src/learning/confidence-scorer.ts +0 -36
  131. package/src/learning/learning-engine.ts +0 -254
  132. package/src/marketing-core.ts +0 -285
  133. package/src/mcp/server.ts +0 -72
  134. package/src/mcp/tools.ts +0 -216
  135. package/src/research/research-engine.ts +0 -226
  136. package/src/services/analytics.service.ts +0 -73
  137. package/src/services/audience.service.ts +0 -40
  138. package/src/services/campaign.service.ts +0 -80
  139. package/src/services/insight.service.ts +0 -54
  140. package/src/services/post.service.ts +0 -116
  141. package/src/services/rule.service.ts +0 -90
  142. package/src/services/strategy.service.ts +0 -53
  143. package/src/services/synapse.service.ts +0 -32
  144. package/src/services/template.service.ts +0 -50
  145. package/src/synapses/activation.ts +0 -80
  146. package/src/synapses/decay.ts +0 -38
  147. package/src/synapses/hebbian.ts +0 -68
  148. package/src/synapses/pathfinder.ts +0 -81
  149. package/src/synapses/synapse-manager.ts +0 -115
  150. package/src/types/config.types.ts +0 -79
  151. package/src/types/ipc.types.ts +0 -8
  152. package/src/types/post.types.ts +0 -156
  153. package/src/types/synapse.types.ts +0 -43
  154. package/src/utils/__tests__/hash.test.ts +0 -39
  155. package/src/utils/__tests__/paths.test.ts +0 -70
  156. package/src/utils/events.ts +0 -44
  157. package/src/utils/hash.ts +0 -5
  158. package/src/utils/logger.ts +0 -48
  159. package/src/utils/paths.ts +0 -19
  160. package/tsconfig.json +0 -18
@@ -1,14 +1,2 @@
1
- import type { NodeType, SynapseRecord } from '../types/synapse.types.js';
2
- import type { SynapseRepository } from '../db/repositories/synapse.repository.js';
3
- export interface PathNode {
4
- type: NodeType;
5
- id: number;
6
- }
7
- export interface SynapsePath {
8
- from: PathNode;
9
- to: PathNode;
10
- synapses: SynapseRecord[];
11
- totalWeight: number;
12
- hops: number;
13
- }
14
- export declare function findPath(repo: SynapseRepository, from: PathNode, to: PathNode, maxDepth?: number): SynapsePath | null;
1
+ export { findPath } from '@timmeck/brain-core';
2
+ export type { PathNode, SynapsePath } from '@timmeck/brain-core';
@@ -1,50 +1,3 @@
1
- export function findPath(repo, from, to, maxDepth = 5) {
2
- const visited = new Set();
3
- const queue = [{ node: from, path: [], totalWeight: 1.0 }];
4
- let bestPath = null;
5
- while (queue.length > 0) {
6
- const current = queue.shift();
7
- const key = `${current.node.type}:${current.node.id}`;
8
- if (visited.has(key))
9
- continue;
10
- visited.add(key);
11
- if (current.node.type === to.type && current.node.id === to.id) {
12
- if (!bestPath || current.totalWeight > bestPath.totalWeight) {
13
- bestPath = {
14
- from,
15
- to,
16
- synapses: current.path,
17
- totalWeight: current.totalWeight,
18
- hops: current.path.length,
19
- };
20
- }
21
- continue;
22
- }
23
- if (current.path.length >= maxDepth)
24
- continue;
25
- const outgoing = repo.getOutgoing(current.node.type, current.node.id);
26
- for (const synapse of outgoing) {
27
- const targetKey = `${synapse.target_type}:${synapse.target_id}`;
28
- if (!visited.has(targetKey)) {
29
- queue.push({
30
- node: { type: synapse.target_type, id: synapse.target_id },
31
- path: [...current.path, synapse],
32
- totalWeight: current.totalWeight * synapse.weight,
33
- });
34
- }
35
- }
36
- const incoming = repo.getIncoming(current.node.type, current.node.id);
37
- for (const synapse of incoming) {
38
- const sourceKey = `${synapse.source_type}:${synapse.source_id}`;
39
- if (!visited.has(sourceKey)) {
40
- queue.push({
41
- node: { type: synapse.source_type, id: synapse.source_id },
42
- path: [...current.path, synapse],
43
- totalWeight: current.totalWeight * synapse.weight,
44
- });
45
- }
46
- }
47
- }
48
- return bestPath;
49
- }
1
+ // Re-export from brain-core
2
+ export { findPath } from '@timmeck/brain-core';
50
3
  //# sourceMappingURL=pathfinder.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pathfinder.js","sourceRoot":"","sources":["../../src/synapses/pathfinder.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pathfinder.js","sourceRoot":"","sources":["../../src/synapses/pathfinder.ts"],"names":[],"mappings":"AAAA,4BAA4B;AAC5B,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC"}
@@ -1,23 +1,10 @@
1
- import type { SynapsesConfig } from '../types/config.types.js';
2
- import type { SynapseType, SynapseRecord, NetworkStats } from '../types/synapse.types.js';
3
- import type { SynapseRepository } from '../db/repositories/synapse.repository.js';
4
- import { type NodeRef } from './hebbian.js';
5
- import { type ActivationResult } from './activation.js';
6
- import { type SynapsePath } from './pathfinder.js';
7
- export declare class SynapseManager {
8
- private repo;
9
- private config;
10
- private logger;
11
- constructor(repo: SynapseRepository, config: SynapsesConfig);
12
- strengthen(source: NodeRef, target: NodeRef, synapseType: SynapseType, context?: Record<string, unknown>): SynapseRecord;
13
- weaken(synapseId: number, factor?: number): void;
14
- find(source: NodeRef, target: NodeRef, synapseType: SynapseType): SynapseRecord | undefined;
15
- activate(startNode: NodeRef, maxDepth?: number, minWeight?: number): ActivationResult[];
16
- findPath(from: NodeRef, to: NodeRef, maxDepth?: number): SynapsePath | null;
17
- runDecay(): {
18
- decayed: number;
19
- pruned: number;
20
- };
1
+ import { BaseSynapseManager } from '@timmeck/brain-core';
2
+ import type { ActivationResult } from '@timmeck/brain-core';
3
+ /**
4
+ * Marketing-brain-specific SynapseManager.
5
+ * Extends BaseSynapseManager with post-context domain methods.
6
+ */
7
+ export declare class SynapseManager extends BaseSynapseManager {
21
8
  getPostContext(postId: number): {
22
9
  campaigns: ActivationResult[];
23
10
  similarPosts: ActivationResult[];
@@ -26,7 +13,4 @@ export declare class SynapseManager {
26
13
  templates: ActivationResult[];
27
14
  insights: ActivationResult[];
28
15
  };
29
- getStrongestSynapses(limit?: number): SynapseRecord[];
30
- getDiverseSynapses(perType?: number): SynapseRecord[];
31
- getNetworkStats(): NetworkStats;
32
16
  }
@@ -1,51 +1,9 @@
1
- import { strengthen, weaken } from './hebbian.js';
2
- import { decayAll } from './decay.js';
3
- import { spreadingActivation } from './activation.js';
4
- import { findPath } from './pathfinder.js';
5
- import { getLogger } from '../utils/logger.js';
6
- export class SynapseManager {
7
- repo;
8
- config;
9
- logger = getLogger();
10
- constructor(repo, config) {
11
- this.repo = repo;
12
- this.config = config;
13
- }
14
- strengthen(source, target, synapseType, context) {
15
- this.logger.debug(`Strengthening synapse ${source.type}:${source.id} --${synapseType}--> ${target.type}:${target.id}`);
16
- return strengthen(this.repo, source, target, synapseType, {
17
- initialWeight: this.config.initialWeight,
18
- learningRate: this.config.learningRate,
19
- pruneThreshold: this.config.pruneThreshold,
20
- }, context);
21
- }
22
- weaken(synapseId, factor = 0.5) {
23
- this.logger.debug(`Weakening synapse ${synapseId} by factor ${factor}`);
24
- weaken(this.repo, synapseId, {
25
- initialWeight: this.config.initialWeight,
26
- learningRate: this.config.learningRate,
27
- pruneThreshold: this.config.pruneThreshold,
28
- }, factor);
29
- }
30
- find(source, target, synapseType) {
31
- return this.repo.findBySourceTarget(source.type, source.id, target.type, target.id, synapseType);
32
- }
33
- activate(startNode, maxDepth, minWeight) {
34
- return spreadingActivation(this.repo, startNode, maxDepth ?? this.config.maxDepth, minWeight ?? this.config.minActivationWeight);
35
- }
36
- findPath(from, to, maxDepth) {
37
- return findPath(this.repo, from, to, maxDepth ?? this.config.maxDepth + 2);
38
- }
39
- runDecay() {
40
- this.logger.info('Running synapse decay cycle');
41
- const result = decayAll(this.repo, {
42
- decayHalfLifeDays: this.config.decayHalfLifeDays,
43
- decayAfterDays: this.config.decayAfterDays,
44
- pruneThreshold: this.config.pruneThreshold,
45
- });
46
- this.logger.info(`Decay complete: ${result.decayed} decayed, ${result.pruned} pruned`);
47
- return result;
48
- }
1
+ import { BaseSynapseManager } from '@timmeck/brain-core';
2
+ /**
3
+ * Marketing-brain-specific SynapseManager.
4
+ * Extends BaseSynapseManager with post-context domain methods.
5
+ */
6
+ export class SynapseManager extends BaseSynapseManager {
49
7
  getPostContext(postId) {
50
8
  const all = this.activate({ type: 'post', id: postId });
51
9
  return {
@@ -57,20 +15,5 @@ export class SynapseManager {
57
15
  insights: all.filter(a => a.node.type === 'insight'),
58
16
  };
59
17
  }
60
- getStrongestSynapses(limit = 20) {
61
- return this.repo.topByWeight(limit);
62
- }
63
- getDiverseSynapses(perType = 25) {
64
- return this.repo.topDiverse(perType);
65
- }
66
- getNetworkStats() {
67
- return {
68
- totalNodes: this.repo.countNodes(),
69
- totalSynapses: this.repo.totalCount(),
70
- avgWeight: this.repo.avgWeight(),
71
- nodesByType: {},
72
- synapsesByType: this.repo.countByType(),
73
- };
74
- }
75
18
  }
76
19
  //# sourceMappingURL=synapse-manager.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"synapse-manager.js","sourceRoot":"","sources":["../../src/synapses/synapse-manager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"synapse-manager.js","sourceRoot":"","sources":["../../src/synapses/synapse-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAGzD;;;GAGG;AACH,MAAM,OAAO,cAAe,SAAQ,kBAAkB;IACpD,cAAc,CAAC,MAAc;QAQ3B,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;QACxD,OAAO;YACL,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,UAAU,CAAC;YACtD,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC;YACrD,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,UAAU,CAAC;YACvD,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC;YAC9C,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,UAAU,CAAC;YACtD,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC;SACrD,CAAC;IACJ,CAAC;CACF"}
@@ -1,11 +1 @@
1
- export interface IpcMessage {
2
- id: string;
3
- type: 'request' | 'response' | 'notification';
4
- method?: string;
5
- params?: unknown;
6
- result?: unknown;
7
- error?: {
8
- code: number;
9
- message: string;
10
- };
11
- }
1
+ export type { IpcMessage } from '@timmeck/brain-core';
@@ -1,5 +1,5 @@
1
- import { EventEmitter } from 'node:events';
2
- export interface MarketingEvents {
1
+ import { TypedEventBus as GenericEventBus } from '@timmeck/brain-core';
2
+ export type MarketingEvents = {
3
3
  'post:created': {
4
4
  postId: number;
5
5
  campaignId: number | null;
@@ -46,12 +46,8 @@ export interface MarketingEvents {
46
46
  synapseId: number;
47
47
  newWeight: number;
48
48
  };
49
- }
49
+ };
50
50
  export type MarketingEventName = keyof MarketingEvents;
51
- export declare class TypedEventBus extends EventEmitter {
52
- emit<K extends MarketingEventName>(event: K, data: MarketingEvents[K]): boolean;
53
- on<K extends MarketingEventName>(event: K, listener: (data: MarketingEvents[K]) => void): this;
54
- once<K extends MarketingEventName>(event: K, listener: (data: MarketingEvents[K]) => void): this;
55
- off<K extends MarketingEventName>(event: K, listener: (data: MarketingEvents[K]) => void): this;
51
+ export declare class TypedEventBus extends GenericEventBus<MarketingEvents> {
56
52
  }
57
53
  export declare function getEventBus(): TypedEventBus;
@@ -1,17 +1,5 @@
1
- import { EventEmitter } from 'node:events';
2
- export class TypedEventBus extends EventEmitter {
3
- emit(event, data) {
4
- return super.emit(event, data);
5
- }
6
- on(event, listener) {
7
- return super.on(event, listener);
8
- }
9
- once(event, listener) {
10
- return super.once(event, listener);
11
- }
12
- off(event, listener) {
13
- return super.off(event, listener);
14
- }
1
+ import { TypedEventBus as GenericEventBus } from '@timmeck/brain-core';
2
+ export class TypedEventBus extends GenericEventBus {
15
3
  }
16
4
  let busInstance = null;
17
5
  export function getEventBus() {
@@ -1 +1 @@
1
- {"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/utils/events.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAkB3C,MAAM,OAAO,aAAc,SAAQ,YAAY;IAC7C,IAAI,CAA+B,KAAQ,EAAE,IAAwB;QACnE,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IACjC,CAAC;IAED,EAAE,CAA+B,KAAQ,EAAE,QAA4C;QACrF,OAAO,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACnC,CAAC;IAED,IAAI,CAA+B,KAAQ,EAAE,QAA4C;QACvF,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACrC,CAAC;IAED,GAAG,CAA+B,KAAQ,EAAE,QAA4C;QACtF,OAAO,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACpC,CAAC;CACF;AAED,IAAI,WAAW,GAAyB,IAAI,CAAC;AAE7C,MAAM,UAAU,WAAW;IACzB,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,WAAW,GAAG,IAAI,aAAa,EAAE,CAAC;IACpC,CAAC;IACD,OAAO,WAAW,CAAC;AACrB,CAAC"}
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/utils/events.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,IAAI,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAkBvE,MAAM,OAAO,aAAc,SAAQ,eAAgC;CAAG;AAEtE,IAAI,WAAW,GAAyB,IAAI,CAAC;AAE7C,MAAM,UAAU,WAAW;IACzB,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,WAAW,GAAG,IAAI,aAAa,EAAE,CAAC;IACpC,CAAC;IACD,OAAO,WAAW,CAAC;AACrB,CAAC"}
@@ -1 +1 @@
1
- export declare function sha256(input: string): string;
1
+ export { sha256 } from '@timmeck/brain-core';
@@ -1,5 +1,2 @@
1
- import { createHash } from 'node:crypto';
2
- export function sha256(input) {
3
- return createHash('sha256').update(input).digest('hex');
4
- }
1
+ export { sha256 } from '@timmeck/brain-core';
5
2
  //# sourceMappingURL=hash.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"hash.js","sourceRoot":"","sources":["../../src/utils/hash.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,UAAU,MAAM,CAAC,KAAa;IAClC,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC1D,CAAC"}
1
+ {"version":3,"file":"hash.js","sourceRoot":"","sources":["../../src/utils/hash.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC"}
@@ -1,8 +1,9 @@
1
- import winston from 'winston';
1
+ import { getLogger, resetLogger } from '@timmeck/brain-core';
2
+ import type winston from 'winston';
2
3
  export declare function createLogger(opts?: {
3
4
  level?: string;
4
5
  file?: string;
5
6
  maxSize?: number;
6
7
  maxFiles?: number;
7
8
  }): winston.Logger;
8
- export declare function getLogger(): winston.Logger;
9
+ export { getLogger, resetLogger };
@@ -1,39 +1,12 @@
1
- import winston from 'winston';
2
- import path from 'node:path';
1
+ import { createLogger as coreCreateLogger, getLogger, resetLogger } from '@timmeck/brain-core';
3
2
  import { getDataDir } from './paths.js';
4
- const { combine, timestamp, printf, colorize } = winston.format;
5
- const logFormat = printf(({ level, message, timestamp, ...meta }) => {
6
- const metaStr = Object.keys(meta).length ? ` ${JSON.stringify(meta)}` : '';
7
- return `${timestamp} [${level}]${metaStr} ${message}`;
8
- });
9
- let loggerInstance = null;
10
3
  export function createLogger(opts) {
11
- if (loggerInstance)
12
- return loggerInstance;
13
- const level = opts?.level ?? process.env['MARKETING_BRAIN_LOG_LEVEL'] ?? 'info';
14
- const logFile = opts?.file ?? path.join(getDataDir(), 'marketing-brain.log');
15
- const maxSize = opts?.maxSize ?? 10 * 1024 * 1024;
16
- const maxFiles = opts?.maxFiles ?? 3;
17
- const transports = [
18
- new winston.transports.File({
19
- filename: logFile,
20
- maxsize: maxSize,
21
- maxFiles,
22
- format: combine(timestamp(), logFormat),
23
- }),
24
- ];
25
- if (process.env['NODE_ENV'] !== 'production') {
26
- transports.push(new winston.transports.Console({
27
- format: combine(colorize(), timestamp(), logFormat),
28
- }));
29
- }
30
- loggerInstance = winston.createLogger({ level, transports });
31
- return loggerInstance;
32
- }
33
- export function getLogger() {
34
- if (!loggerInstance) {
35
- return createLogger();
36
- }
37
- return loggerInstance;
4
+ return coreCreateLogger({
5
+ ...opts,
6
+ envVar: 'MARKETING_BRAIN_LOG_LEVEL',
7
+ defaultFilename: 'marketing-brain.log',
8
+ dataDir: opts?.file ? undefined : getDataDir(),
9
+ });
38
10
  }
11
+ export { getLogger, resetLogger };
39
12
  //# sourceMappingURL=logger.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;AAEhE,MAAM,SAAS,GAAG,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE;IAClE,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3E,OAAO,GAAG,SAAS,KAAK,KAAK,IAAI,OAAO,IAAI,OAAO,EAAE,CAAC;AACxD,CAAC,CAAC,CAAC;AAEH,IAAI,cAAc,GAA0B,IAAI,CAAC;AAEjD,MAAM,UAAU,YAAY,CAAC,IAA6E;IACxG,IAAI,cAAc;QAAE,OAAO,cAAc,CAAC;IAE1C,MAAM,KAAK,GAAG,IAAI,EAAE,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,IAAI,MAAM,CAAC;IAChF,MAAM,OAAO,GAAG,IAAI,EAAE,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,qBAAqB,CAAC,CAAC;IAC7E,MAAM,OAAO,GAAG,IAAI,EAAE,OAAO,IAAI,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;IAClD,MAAM,QAAQ,GAAG,IAAI,EAAE,QAAQ,IAAI,CAAC,CAAC;IAErC,MAAM,UAAU,GAAwB;QACtC,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC;YAC1B,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,OAAO;YAChB,QAAQ;YACR,MAAM,EAAE,OAAO,CAAC,SAAS,EAAE,EAAE,SAAS,CAAC;SACxC,CAAC;KACH,CAAC;IAEF,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,YAAY,EAAE,CAAC;QAC7C,UAAU,CAAC,IAAI,CACb,IAAI,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC;YAC7B,MAAM,EAAE,OAAO,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,EAAE,SAAS,CAAC;SACpD,CAAC,CACH,CAAC;IACJ,CAAC;IAED,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC;IAC7D,OAAO,cAAc,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,SAAS;IACvB,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,OAAO,YAAY,EAAE,CAAC;IACxB,CAAC;IACD,OAAO,cAAc,CAAC;AACxB,CAAC"}
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,IAAI,gBAAgB,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAE/F,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,MAAM,UAAU,YAAY,CAAC,IAA6E;IACxG,OAAO,gBAAgB,CAAC;QACtB,GAAG,IAAI;QACP,MAAM,EAAE,2BAA2B;QACnC,eAAe,EAAE,qBAAqB;QACtC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,EAAE;KAC/C,CAAC,CAAC;AACL,CAAC;AAED,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,CAAC"}
@@ -1,3 +1,4 @@
1
- export declare function normalizePath(filePath: string): string;
1
+ import { normalizePath } from '@timmeck/brain-core';
2
+ export { normalizePath };
2
3
  export declare function getDataDir(): string;
3
4
  export declare function getPipeName(name?: string): string;
@@ -1,18 +1,9 @@
1
- import path from 'node:path';
2
- import os from 'node:os';
3
- export function normalizePath(filePath) {
4
- return filePath.replace(/\\/g, '/');
5
- }
1
+ import { normalizePath, getDataDir as coreGetDataDir, getPipeName as coreGetPipeName } from '@timmeck/brain-core';
2
+ export { normalizePath };
6
3
  export function getDataDir() {
7
- const envDir = process.env['MARKETING_BRAIN_DATA_DIR'];
8
- if (envDir)
9
- return path.resolve(envDir);
10
- return path.join(os.homedir(), '.marketing-brain');
4
+ return coreGetDataDir('MARKETING_BRAIN_DATA_DIR', '.marketing-brain');
11
5
  }
12
6
  export function getPipeName(name = 'marketing-brain') {
13
- if (process.platform === 'win32') {
14
- return `\\\\.\\pipe\\${name}`;
15
- }
16
- return path.join(os.tmpdir(), `${name}.sock`);
7
+ return coreGetPipeName(name);
17
8
  }
18
9
  //# sourceMappingURL=paths.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AAEzB,MAAM,UAAU,aAAa,CAAC,QAAgB;IAC5C,OAAO,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AACtC,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;IACvD,IAAI,MAAM;QAAE,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACxC,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,kBAAkB,CAAC,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,OAAe,iBAAiB;IAC1D,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,OAAO,gBAAgB,IAAI,EAAE,CAAC;IAChC,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,GAAG,IAAI,OAAO,CAAC,CAAC;AAChD,CAAC"}
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,UAAU,IAAI,cAAc,EAAE,WAAW,IAAI,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAElH,OAAO,EAAE,aAAa,EAAE,CAAC;AAEzB,MAAM,UAAU,UAAU;IACxB,OAAO,cAAc,CAAC,0BAA0B,EAAE,kBAAkB,CAAC,CAAC;AACxE,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,OAAe,iBAAiB;IAC1D,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC"}
@@ -0,0 +1,14 @@
1
+ import tseslint from 'typescript-eslint';
2
+
3
+ export default tseslint.config(
4
+ ...tseslint.configs.recommended,
5
+ {
6
+ ignores: ['dist/', 'node_modules/', '**/*.js', '**/*.d.ts'],
7
+ },
8
+ {
9
+ rules: {
10
+ '@typescript-eslint/no-explicit-any': 'warn',
11
+ '@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_' }],
12
+ },
13
+ },
14
+ );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@timmeck/marketing-brain",
3
- "version": "0.2.1",
3
+ "version": "0.4.0",
4
4
  "description": "Self-learning marketing intelligence system with Hebbian synapse network",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -10,7 +10,10 @@
10
10
  "scripts": {
11
11
  "build": "tsc",
12
12
  "dev": "tsx src/index.ts",
13
- "test": "vitest"
13
+ "test": "vitest",
14
+ "lint": "eslint src/",
15
+ "lint:fix": "eslint src/ --fix",
16
+ "test:coverage": "vitest --coverage"
14
17
  },
15
18
  "keywords": [
16
19
  "marketing-intelligence",
@@ -25,6 +28,7 @@
25
28
  "license": "MIT",
26
29
  "dependencies": {
27
30
  "@modelcontextprotocol/sdk": "^1.0.0",
31
+ "@timmeck/brain-core": "^1.1.0",
28
32
  "better-sqlite3": "^11.7.0",
29
33
  "chalk": "^5.6.2",
30
34
  "commander": "^13.0.0",
@@ -33,8 +37,11 @@
33
37
  "devDependencies": {
34
38
  "@types/better-sqlite3": "^7.6.12",
35
39
  "@types/node": "^22.0.0",
40
+ "@vitest/coverage-v8": "^3.2.4",
41
+ "eslint": "^9.39.3",
36
42
  "tsx": "^4.19.0",
37
43
  "typescript": "^5.7.0",
44
+ "typescript-eslint": "^8.56.1",
38
45
  "vitest": "^3.0.0"
39
46
  }
40
47
  }
@@ -1 +0,0 @@
1
- github: timmeck
@@ -1,27 +0,0 @@
1
- name: CI
2
-
3
- on:
4
- push:
5
- branches: [main]
6
- pull_request:
7
- branches: [main]
8
-
9
- jobs:
10
- build:
11
- runs-on: ubuntu-latest
12
-
13
- steps:
14
- - uses: actions/checkout@v4
15
-
16
- - uses: actions/setup-node@v4
17
- with:
18
- node-version: 20
19
- cache: npm
20
-
21
- - run: npm ci
22
-
23
- - run: npm run build
24
-
25
- - name: Run tests
26
- run: npm test
27
- if: ${{ hashFiles('vitest.config.*', 'src/**/*.test.ts', 'tests/**/*.test.ts') != '' }}
package/.mcp.json DELETED
@@ -1,9 +0,0 @@
1
- {
2
- "mcpServers": {
3
- "marketing-brain": {
4
- "command": "npx",
5
- "args": ["tsx", "src/index.ts", "mcp-server"],
6
- "cwd": "C:/Users/mecklenburg/Desktop/marketing-brain"
7
- }
8
- }
9
- }
package/src/api/server.ts DELETED
@@ -1,86 +0,0 @@
1
- import http from 'node:http';
2
- import { getLogger } from '../utils/logger.js';
3
- import type { IpcRouter } from '../ipc/router.js';
4
-
5
- interface ApiServerOptions {
6
- port: number;
7
- router: IpcRouter;
8
- apiKey?: string;
9
- }
10
-
11
- export class ApiServer {
12
- private server: http.Server | null = null;
13
- private logger = getLogger();
14
-
15
- constructor(private opts: ApiServerOptions) {}
16
-
17
- start(): void {
18
- this.server = http.createServer((req, res) => {
19
- // CORS
20
- res.setHeader('Access-Control-Allow-Origin', '*');
21
- res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
22
- res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
23
-
24
- if (req.method === 'OPTIONS') {
25
- res.writeHead(204);
26
- res.end();
27
- return;
28
- }
29
-
30
- // Auth check
31
- if (this.opts.apiKey) {
32
- const auth = req.headers.authorization;
33
- if (!auth || auth !== `Bearer ${this.opts.apiKey}`) {
34
- res.writeHead(401, { 'Content-Type': 'application/json' });
35
- res.end(JSON.stringify({ error: 'Unauthorized' }));
36
- return;
37
- }
38
- }
39
-
40
- // Health check
41
- if (req.url === '/api/v1/health') {
42
- res.writeHead(200, { 'Content-Type': 'application/json' });
43
- res.end(JSON.stringify({ status: 'ok', service: 'marketing-brain' }));
44
- return;
45
- }
46
-
47
- // Methods list
48
- if (req.url === '/api/v1/methods') {
49
- res.writeHead(200, { 'Content-Type': 'application/json' });
50
- res.end(JSON.stringify({ methods: this.opts.router.listMethods() }));
51
- return;
52
- }
53
-
54
- // RPC endpoint
55
- if (req.url === '/api/v1/rpc' && req.method === 'POST') {
56
- let body = '';
57
- req.on('data', chunk => { body += chunk; });
58
- req.on('end', () => {
59
- try {
60
- const { method, params } = JSON.parse(body);
61
- const result = this.opts.router.handle(method, params);
62
- res.writeHead(200, { 'Content-Type': 'application/json' });
63
- res.end(JSON.stringify({ result }));
64
- } catch (err) {
65
- res.writeHead(400, { 'Content-Type': 'application/json' });
66
- res.end(JSON.stringify({ error: err instanceof Error ? err.message : String(err) }));
67
- }
68
- });
69
- return;
70
- }
71
-
72
- res.writeHead(404, { 'Content-Type': 'application/json' });
73
- res.end(JSON.stringify({ error: 'Not Found' }));
74
- });
75
-
76
- this.server.listen(this.opts.port, () => {
77
- this.logger.info(`API server listening on port ${this.opts.port}`);
78
- });
79
- }
80
-
81
- stop(): void {
82
- this.server?.close();
83
- this.server = null;
84
- this.logger.info('API server stopped');
85
- }
86
- }
package/src/cli/colors.ts DELETED
@@ -1,59 +0,0 @@
1
- import chalk from 'chalk';
2
-
3
- export const c = {
4
- blue: chalk.hex('#5b9cff'),
5
- purple: chalk.hex('#b47aff'),
6
- cyan: chalk.hex('#47e5ff'),
7
- green: chalk.hex('#3dffa0'),
8
- red: chalk.hex('#ff5577'),
9
- orange: chalk.hex('#ffb347'),
10
- dim: chalk.hex('#8b8fb0'),
11
- dimmer: chalk.hex('#4a4d6e'),
12
-
13
- label: chalk.hex('#8b8fb0'),
14
- value: chalk.white.bold,
15
- heading: chalk.hex('#5b9cff').bold,
16
- success: chalk.hex('#3dffa0').bold,
17
- error: chalk.hex('#ff5577').bold,
18
- warn: chalk.hex('#ffb347').bold,
19
- info: chalk.hex('#47e5ff'),
20
- };
21
-
22
- export const icons = {
23
- megaphone: '📣',
24
- check: '✓',
25
- cross: '✗',
26
- arrow: '→',
27
- dot: '●',
28
- bar: '█',
29
- barLight: '░',
30
- dash: '─',
31
- star: '★',
32
- bolt: '⚡',
33
- chart: '📊',
34
- post: '📝',
35
- campaign: '🎯',
36
- synapse: '🔗',
37
- insight: '💡',
38
- rule: '📏',
39
- template: '📋',
40
- warn: '⚠',
41
- error: '❌',
42
- ok: '✅',
43
- clock: '⏱',
44
- };
45
-
46
- export function header(title: string, icon?: string): string {
47
- const prefix = icon ? `${icon} ` : '';
48
- const line = c.dimmer(icons.dash.repeat(40));
49
- return `\n${line}\n${prefix}${c.heading(title)}\n${line}`;
50
- }
51
-
52
- export function keyValue(key: string, value: string | number, indent = 2): string {
53
- const pad = ' '.repeat(indent);
54
- return `${pad}${c.label(key + ':')} ${c.value(String(value))}`;
55
- }
56
-
57
- export function divider(width = 40): string {
58
- return c.dimmer(icons.dash.repeat(width));
59
- }