@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.
- package/Dockerfile +22 -0
- package/README.md +20 -3
- package/dashboard.html +6 -0
- package/dist/cli/colors.d.ts +11 -24
- package/dist/cli/colors.js +3 -46
- package/dist/cli/colors.js.map +1 -1
- package/dist/cli/commands/dashboard.js +15 -0
- package/dist/cli/commands/dashboard.js.map +1 -1
- package/dist/cli/commands/peers.d.ts +2 -0
- package/dist/cli/commands/peers.js +38 -0
- package/dist/cli/commands/peers.js.map +1 -0
- package/dist/config.js +2 -29
- package/dist/config.js.map +1 -1
- package/dist/db/connection.d.ts +1 -2
- package/dist/db/connection.js +1 -18
- package/dist/db/connection.js.map +1 -1
- package/dist/hooks/post-tool-use.d.ts +2 -0
- package/dist/hooks/post-tool-use.js +182 -0
- package/dist/hooks/post-tool-use.js.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/ipc/client.d.ts +1 -13
- package/dist/ipc/client.js +1 -92
- package/dist/ipc/client.js.map +1 -1
- package/dist/ipc/protocol.d.ts +1 -8
- package/dist/ipc/protocol.js +1 -28
- package/dist/ipc/protocol.js.map +1 -1
- package/dist/ipc/router.d.ts +2 -0
- package/dist/ipc/router.js +30 -0
- package/dist/ipc/router.js.map +1 -1
- package/dist/ipc/server.d.ts +1 -14
- package/dist/ipc/server.js +1 -129
- package/dist/ipc/server.js.map +1 -1
- package/dist/learning/confidence-scorer.d.ts +1 -5
- package/dist/learning/confidence-scorer.js +2 -13
- package/dist/learning/confidence-scorer.js.map +1 -1
- package/dist/learning/learning-engine.d.ts +2 -5
- package/dist/learning/learning-engine.js +3 -20
- package/dist/learning/learning-engine.js.map +1 -1
- package/dist/marketing-core.d.ts +2 -0
- package/dist/marketing-core.js +22 -2
- package/dist/marketing-core.js.map +1 -1
- package/dist/mcp/server.js +5 -60
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tools.js +29 -0
- package/dist/mcp/tools.js.map +1 -1
- package/dist/research/research-engine.d.ts +2 -5
- package/dist/research/research-engine.js +3 -24
- package/dist/research/research-engine.js.map +1 -1
- package/dist/services/analytics.service.d.ts +1 -1
- package/dist/services/synapse.service.d.ts +10 -10
- package/dist/synapses/activation.d.ts +2 -13
- package/dist/synapses/activation.js +2 -49
- package/dist/synapses/activation.js.map +1 -1
- package/dist/synapses/decay.d.ts +2 -11
- package/dist/synapses/decay.js +2 -26
- package/dist/synapses/decay.js.map +1 -1
- package/dist/synapses/hebbian.d.ts +2 -13
- package/dist/synapses/hebbian.js +2 -34
- package/dist/synapses/hebbian.js.map +1 -1
- package/dist/synapses/pathfinder.d.ts +2 -14
- package/dist/synapses/pathfinder.js +2 -49
- package/dist/synapses/pathfinder.js.map +1 -1
- package/dist/synapses/synapse-manager.d.ts +7 -23
- package/dist/synapses/synapse-manager.js +6 -63
- package/dist/synapses/synapse-manager.js.map +1 -1
- package/dist/types/ipc.types.d.ts +1 -11
- package/dist/utils/events.d.ts +4 -8
- package/dist/utils/events.js +2 -14
- package/dist/utils/events.js.map +1 -1
- package/dist/utils/hash.d.ts +1 -1
- package/dist/utils/hash.js +1 -4
- package/dist/utils/hash.js.map +1 -1
- package/dist/utils/logger.d.ts +3 -2
- package/dist/utils/logger.js +8 -35
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/paths.d.ts +2 -1
- package/dist/utils/paths.js +4 -13
- package/dist/utils/paths.js.map +1 -1
- package/eslint.config.js +14 -0
- package/package.json +9 -2
- package/.github/FUNDING.yml +0 -1
- package/.github/workflows/ci.yml +0 -27
- package/.mcp.json +0 -9
- package/src/api/server.ts +0 -86
- package/src/cli/colors.ts +0 -59
- package/src/cli/commands/campaign.ts +0 -66
- package/src/cli/commands/config.ts +0 -168
- package/src/cli/commands/dashboard.ts +0 -165
- package/src/cli/commands/doctor.ts +0 -110
- package/src/cli/commands/export.ts +0 -40
- package/src/cli/commands/import.ts +0 -84
- package/src/cli/commands/insights.ts +0 -44
- package/src/cli/commands/learn.ts +0 -24
- package/src/cli/commands/network.ts +0 -71
- package/src/cli/commands/post.ts +0 -47
- package/src/cli/commands/query.ts +0 -108
- package/src/cli/commands/rules.ts +0 -27
- package/src/cli/commands/start.ts +0 -100
- package/src/cli/commands/status.ts +0 -73
- package/src/cli/commands/stop.ts +0 -33
- package/src/cli/commands/suggest.ts +0 -64
- package/src/cli/ipc-helper.ts +0 -22
- package/src/cli/update-check.ts +0 -63
- package/src/config.ts +0 -110
- package/src/dashboard/renderer.ts +0 -136
- package/src/dashboard/server.ts +0 -140
- package/src/db/connection.ts +0 -22
- package/src/db/migrations/001_core_schema.ts +0 -63
- package/src/db/migrations/002_learning_schema.ts +0 -46
- package/src/db/migrations/003_synapse_schema.ts +0 -27
- package/src/db/migrations/004_insights_schema.ts +0 -38
- package/src/db/migrations/005_fts_indexes.ts +0 -77
- package/src/db/migrations/index.ts +0 -62
- package/src/db/repositories/audience.repository.ts +0 -53
- package/src/db/repositories/campaign.repository.ts +0 -72
- package/src/db/repositories/engagement.repository.ts +0 -108
- package/src/db/repositories/insight.repository.ts +0 -100
- package/src/db/repositories/post.repository.ts +0 -123
- package/src/db/repositories/rule.repository.ts +0 -87
- package/src/db/repositories/strategy.repository.ts +0 -82
- package/src/db/repositories/synapse.repository.ts +0 -148
- package/src/db/repositories/template.repository.ts +0 -76
- package/src/index.ts +0 -69
- package/src/ipc/__tests__/protocol.test.ts +0 -153
- package/src/ipc/client.ts +0 -110
- package/src/ipc/protocol.ts +0 -35
- package/src/ipc/router.ts +0 -126
- package/src/ipc/server.ts +0 -140
- package/src/learning/confidence-scorer.ts +0 -36
- package/src/learning/learning-engine.ts +0 -254
- package/src/marketing-core.ts +0 -285
- package/src/mcp/server.ts +0 -72
- package/src/mcp/tools.ts +0 -216
- package/src/research/research-engine.ts +0 -226
- package/src/services/analytics.service.ts +0 -73
- package/src/services/audience.service.ts +0 -40
- package/src/services/campaign.service.ts +0 -80
- package/src/services/insight.service.ts +0 -54
- package/src/services/post.service.ts +0 -116
- package/src/services/rule.service.ts +0 -90
- package/src/services/strategy.service.ts +0 -53
- package/src/services/synapse.service.ts +0 -32
- package/src/services/template.service.ts +0 -50
- package/src/synapses/activation.ts +0 -80
- package/src/synapses/decay.ts +0 -38
- package/src/synapses/hebbian.ts +0 -68
- package/src/synapses/pathfinder.ts +0 -81
- package/src/synapses/synapse-manager.ts +0 -115
- package/src/types/config.types.ts +0 -79
- package/src/types/ipc.types.ts +0 -8
- package/src/types/post.types.ts +0 -156
- package/src/types/synapse.types.ts +0 -43
- package/src/utils/__tests__/hash.test.ts +0 -39
- package/src/utils/__tests__/paths.test.ts +0 -70
- package/src/utils/events.ts +0 -44
- package/src/utils/hash.ts +0 -5
- package/src/utils/logger.ts +0 -48
- package/src/utils/paths.ts +0 -19
- package/tsconfig.json +0 -18
|
@@ -1,14 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
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
|
|
2
|
-
|
|
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":"
|
|
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
|
|
2
|
-
import type {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
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 {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
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":"
|
|
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
|
|
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';
|
package/dist/utils/events.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export
|
|
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
|
|
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;
|
package/dist/utils/events.js
CHANGED
|
@@ -1,17 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export class TypedEventBus extends
|
|
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() {
|
package/dist/utils/events.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/utils/events.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
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"}
|
package/dist/utils/hash.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export
|
|
1
|
+
export { sha256 } from '@timmeck/brain-core';
|
package/dist/utils/hash.js
CHANGED
package/dist/utils/hash.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hash.js","sourceRoot":"","sources":["../../src/utils/hash.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"hash.js","sourceRoot":"","sources":["../../src/utils/hash.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC"}
|
package/dist/utils/logger.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import
|
|
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
|
|
9
|
+
export { getLogger, resetLogger };
|
package/dist/utils/logger.js
CHANGED
|
@@ -1,39 +1,12 @@
|
|
|
1
|
-
import
|
|
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
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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
|
package/dist/utils/logger.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
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"}
|
package/dist/utils/paths.d.ts
CHANGED
package/dist/utils/paths.js
CHANGED
|
@@ -1,18 +1,9 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
package/dist/utils/paths.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
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"}
|
package/eslint.config.js
ADDED
|
@@ -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.
|
|
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
|
}
|
package/.github/FUNDING.yml
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
github: timmeck
|
package/.github/workflows/ci.yml
DELETED
|
@@ -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
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
|
-
}
|