@timmeck/marketing-brain 0.5.2 → 1.1.1
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/README.md +8 -4
- package/dist/cli/commands/doctor.js +1 -1
- package/dist/cli/commands/setup.js +92 -7
- package/dist/cli/commands/setup.js.map +1 -1
- package/dist/cli/commands/status.js +0 -1
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/cli/commands/suggest.js +1 -0
- package/dist/cli/commands/suggest.js.map +1 -1
- package/dist/cli/ipc-helper.d.ts +1 -1
- package/dist/cli/ipc-helper.js +1 -1
- package/dist/cli/ipc-helper.js.map +1 -1
- package/dist/dashboard/renderer.js +0 -1
- package/dist/dashboard/renderer.js.map +1 -1
- package/dist/dashboard/server.d.ts +6 -12
- package/dist/dashboard/server.js +14 -119
- package/dist/dashboard/server.js.map +1 -1
- package/dist/db/migrations/008_ab_tests.d.ts +2 -0
- package/dist/db/migrations/008_ab_tests.js +36 -0
- package/dist/db/migrations/008_ab_tests.js.map +1 -0
- package/dist/db/migrations/index.js +2 -0
- package/dist/db/migrations/index.js.map +1 -1
- package/dist/db/repositories/ab-test.repository.d.ts +45 -0
- package/dist/db/repositories/ab-test.repository.js +94 -0
- package/dist/db/repositories/ab-test.repository.js.map +1 -0
- package/dist/db/repositories/post.repository.js +1 -1
- package/dist/embeddings/engine.d.ts +35 -0
- package/dist/embeddings/engine.js +162 -0
- package/dist/embeddings/engine.js.map +1 -0
- package/dist/hooks/post-tool-use.js +1 -1
- package/dist/hooks/post-tool-use.js.map +1 -1
- package/dist/ipc/router.d.ts +14 -1
- package/dist/ipc/router.js +73 -1
- package/dist/ipc/router.js.map +1 -1
- package/dist/learning/confidence-scorer.d.ts +0 -1
- package/dist/learning/confidence-scorer.js +0 -2
- package/dist/learning/confidence-scorer.js.map +1 -1
- package/dist/learning/learning-engine.js +4 -4
- package/dist/learning/learning-engine.js.map +1 -1
- package/dist/learning/pattern-extractor.d.ts +27 -0
- package/dist/learning/pattern-extractor.js +346 -0
- package/dist/learning/pattern-extractor.js.map +1 -0
- package/dist/marketing-core.d.ts +2 -0
- package/dist/marketing-core.js +36 -6
- package/dist/marketing-core.js.map +1 -1
- package/dist/mcp/tools.d.ts +1 -1
- package/dist/mcp/tools.js +34 -0
- package/dist/mcp/tools.js.map +1 -1
- package/dist/services/ab-test.service.d.ts +29 -0
- package/dist/services/ab-test.service.js +143 -0
- package/dist/services/ab-test.service.js.map +1 -0
- package/dist/services/calendar.service.d.ts +28 -0
- package/dist/services/calendar.service.js +211 -0
- package/dist/services/calendar.service.js.map +1 -0
- package/dist/services/post.service.js +1 -1
- package/dist/services/post.service.js.map +1 -1
- package/dist/utils/__tests__/paths.test.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"learning-engine.js","sourceRoot":"","sources":["../../src/learning/learning-engine.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"learning-engine.js","sourceRoot":"","sources":["../../src/learning/learning-engine.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAUtE,MAAM,OAAO,cAAe,SAAQ,kBAAkB;IAE1C;IACA;IACA;IACA;IACA;IACA;IANV,YACU,MAAsB,EACtB,QAAwB,EACxB,cAAoC,EACpC,QAAwB,EACxB,YAAgC,EAChC,cAA8B;QAEtC,KAAK,CAAC,MAAM,CAAC,CAAC;QAPN,WAAM,GAAN,MAAM,CAAgB;QACtB,aAAQ,GAAR,QAAQ,CAAgB;QACxB,mBAAc,GAAd,cAAc,CAAsB;QACpC,aAAQ,GAAR,QAAQ,CAAgB;QACxB,iBAAY,GAAZ,YAAY,CAAoB;QAChC,mBAAc,GAAd,cAAc,CAAgB;IAGxC,CAAC;IAED,QAAQ;QACN,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;QAC5C,MAAM,MAAM,GAAwB;YAClC,YAAY,EAAE,CAAC;YACf,YAAY,EAAE,CAAC;YACf,iBAAiB,EAAE,CAAC;YACpB,eAAe,EAAE,CAAC;YAClB,cAAc,EAAE,CAAC;SAClB,CAAC;QAEF,uCAAuC;QACvC,MAAM,CAAC,YAAY,IAAI,IAAI,CAAC,qBAAqB,EAAE,CAAC;QACpD,MAAM,CAAC,YAAY,IAAI,IAAI,CAAC,qBAAqB,EAAE,CAAC;QACpD,MAAM,CAAC,YAAY,IAAI,IAAI,CAAC,uBAAuB,EAAE,CAAC;QAEtD,oDAAoD;QACpD,MAAM,CAAC,iBAAiB,GAAG,IAAI,CAAC,wBAAwB,EAAE,CAAC;QAE3D,6CAA6C;QAC7C,MAAM,CAAC,YAAY,GAAG,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAElD,uBAAuB;QACvB,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,CAAC;QAC7C,MAAM,CAAC,eAAe,GAAG,KAAK,CAAC,OAAO,CAAC;QACvC,MAAM,CAAC,cAAc,GAAG,KAAK,CAAC,MAAM,CAAC;QAErC,wBAAwB;QACxB,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAExB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,4BAA4B,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACvE,OAAO,MAAM,CAAC;IAChB,CAAC;IAEO,qBAAqB;QAC3B,IAAI,OAAO,GAAG,CAAC,CAAC;QAChB,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;QAErD,uBAAuB;QACvB,MAAM,WAAW,GAAwD,EAAE,CAAC;QAE5E,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;YAC/B,IAAI,CAAC,IAAI,CAAC,YAAY;gBAAE,SAAS;YACjC,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,QAAQ,EAAE,CAAC;YACpD,MAAM,GAAG,GAAG,IAAI,CAAC,cAAc,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACzD,IAAI,CAAC,GAAG;gBAAE,SAAS;YAEnB,MAAM,KAAK,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;YACnC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;gBAAE,WAAW,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;YACtE,WAAW,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;YAC1B,WAAW,CAAC,IAAI,CAAC,CAAC,QAAQ,IAAI,KAAK,CAAC;QACtC,CAAC;QAED,wBAAwB;QACxB,KAAK,MAAM,CAAC,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;YACnD,IAAI,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,cAAc;gBAAE,SAAS;YACtD,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC;QAC9B,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC;aACtC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC;aACxD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC;QAEnD,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;YACtB,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YAC1B,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YAE1C,IAAI,QAAQ,IAAI,SAAS,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,EAAE,CAAC;gBAC9E,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;oBACnB,OAAO,EAAE,aAAa,QAAQ,CAAC,CAAC,CAAC,GAAG;oBACpC,cAAc,EAAE,gBAAgB,QAAQ,CAAC,CAAC,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,iBAAiB,SAAS,CAAC,CAAC,CAAC,KAAK;oBAClK,UAAU,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC;iBAC/D,CAAC,CAAC;gBACH,OAAO,EAAE,CAAC;YACZ,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAEO,qBAAqB;QAC3B,IAAI,OAAO,GAAG,CAAC,CAAC;QAChB,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;QAErD,MAAM,aAAa,GAAwD,EAAE,CAAC;QAE9E,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;YAC/B,MAAM,GAAG,GAAG,IAAI,CAAC,cAAc,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACzD,IAAI,CAAC,GAAG;gBAAE,SAAS;YAEnB,MAAM,KAAK,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;YACnC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC;gBAAE,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;YACxF,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,CAAC;YACnC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,QAAQ,IAAI,KAAK,CAAC;QAC/C,CAAC;QAED,KAAK,MAAM,CAAC,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC;YACrD,IAAI,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,cAAc;gBAAE,SAAS;YACtD,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC;QAC9B,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC;aAC1C,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC;aACxD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC;QAEnD,IAAI,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;YACtC,MAAM,CAAC,UAAU,EAAE,QAAQ,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;YAC1C,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;gBACnB,OAAO,EAAE,eAAe,UAAU,EAAE;gBACpC,cAAc,EAAE,GAAG,UAAU,kBAAkB,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,iCAAiC;gBAC5G,UAAU,EAAE,WAAW,CAAC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC;aAC5D,CAAC,CAAC;YACH,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAEO,uBAAuB;QAC7B,IAAI,OAAO,GAAG,CAAC,CAAC;QAChB,MAAM,aAAa,GAAG,IAAI,CAAC,cAAc,CAAC,aAAa,EAAE,CAAC;QAE1D,IAAI,aAAa,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;YAC9B,MAAM,OAAO,GAAG,CAAC,CAA+B,EAAE,EAAE,CAAC,eAAe,CAAC;gBACnE,KAAK,EAAE,CAAC,CAAC,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC,YAAY;gBAC5C,MAAM,EAAE,CAAC,CAAC,UAAU,EAAE,WAAW,EAAE,CAAC,CAAC,eAAe,EAAE,MAAM,EAAE,CAAC,CAAC,UAAU;aAC3E,CAAC,CAAC;YACH,MAAM,MAAM,GAAG,CAAC,GAAG,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;YAC1E,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;YACvB,IAAI,IAAI,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;gBAC1D,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;oBACnB,OAAO,EAAE,iBAAiB,IAAI,CAAC,QAAQ,EAAE;oBACzC,cAAc,EAAE,GAAG,IAAI,CAAC,QAAQ,qCAAqC,IAAI,CAAC,UAAU,eAAe,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS;oBACrI,UAAU,EAAE,WAAW,CAAC,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;iBAC9F,CAAC,CAAC;gBACH,OAAO,EAAE,CAAC;YACZ,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAEO,wBAAwB;QAC9B,IAAI,OAAO,GAAG,CAAC,CAAC;QAChB,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAElD,KAAK,MAAM,QAAQ,IAAI,UAAU,EAAE,CAAC;YAClC,IAAI,CAAC,QAAQ,CAAC,OAAO;gBAAE,SAAS;YAChC,MAAM,GAAG,GAAG,IAAI,CAAC,cAAc,CAAC,eAAe,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YAClE,IAAI,CAAC,GAAG;gBAAE,SAAS;YAEnB,MAAM,KAAK,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;YACnC,uCAAuC;YACvC,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,GAAG,GAAG,CAAC,CAAC;YAEjD,IAAI,IAAI,CAAC,GAAG,CAAC,aAAa,GAAG,QAAQ,CAAC,UAAU,CAAC,GAAG,IAAI,EAAE,CAAC;gBACzD,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,UAAU,EAAE,aAAa,EAAE,CAAC,CAAC;gBACrE,OAAO,EAAE,CAAC;YACZ,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAEO,oBAAoB;QAC1B,IAAI,OAAO,GAAG,CAAC,CAAC;QAChB,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;QAEtC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,MAAM,CAAC,cAAc;gBAAE,SAAS;YAE9D,MAAM,aAAa,GAAG,WAAW,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;YAE1E,IAAI,aAAa,GAAG,IAAI,CAAC,MAAM,CAAC,cAAc,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBAC9D,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,UAAU,EAAE,aAAa,EAAE,CAAC,CAAC;gBACxE,OAAO,EAAE,CAAC;YACZ,CAAC;iBAAM,IAAI,IAAI,CAAC,GAAG,CAAC,aAAa,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,IAAI,EAAE,CAAC;gBAC5D,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,UAAU,EAAE,aAAa,EAAE,CAAC,CAAC;gBAC7D,OAAO,EAAE,CAAC;YACZ,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAEO,gBAAgB;QACtB,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;QAE9C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACtC,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC3D,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC;gBACpB,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC;gBAEpB,6EAA6E;gBAC7E,IAAI,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC;oBAC9B,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;oBAChH,IAAI,WAAW,GAAG,GAAG,EAAE,CAAC;wBACtB,IAAI,CAAC,cAAc,CAAC,UAAU,CAC5B,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAC1B,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAC1B,YAAY,CACb,CAAC;oBACJ,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type Database from 'better-sqlite3';
|
|
2
|
+
export interface ContentPattern {
|
|
3
|
+
pattern: string;
|
|
4
|
+
category: 'timing' | 'format' | 'content' | 'platform';
|
|
5
|
+
confidence: number;
|
|
6
|
+
sampleSize: number;
|
|
7
|
+
avgEngagement: number;
|
|
8
|
+
baselineEngagement: number;
|
|
9
|
+
multiplier: number;
|
|
10
|
+
}
|
|
11
|
+
export declare class PatternExtractor {
|
|
12
|
+
private db;
|
|
13
|
+
private logger;
|
|
14
|
+
constructor(db: Database.Database);
|
|
15
|
+
extractPatterns(): ContentPattern[];
|
|
16
|
+
private getPostsWithEngagement;
|
|
17
|
+
private computeBaseline;
|
|
18
|
+
private extractTimingPatterns;
|
|
19
|
+
private extractFormatPatterns;
|
|
20
|
+
private extractPlatformPatterns;
|
|
21
|
+
private extractContentPatterns;
|
|
22
|
+
/**
|
|
23
|
+
* Compute confidence based on sample size relative to total, and effect magnitude.
|
|
24
|
+
* Higher sample sizes and larger effects yield higher confidence.
|
|
25
|
+
*/
|
|
26
|
+
private computeConfidence;
|
|
27
|
+
}
|
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
import { getLogger } from '../utils/logger.js';
|
|
2
|
+
import { engagementScore } from './confidence-scorer.js';
|
|
3
|
+
const DAY_NAMES = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
|
|
4
|
+
export class PatternExtractor {
|
|
5
|
+
db;
|
|
6
|
+
logger = getLogger();
|
|
7
|
+
constructor(db) {
|
|
8
|
+
this.db = db;
|
|
9
|
+
}
|
|
10
|
+
extractPatterns() {
|
|
11
|
+
const patterns = [];
|
|
12
|
+
const rows = this.getPostsWithEngagement();
|
|
13
|
+
if (rows.length < 3) {
|
|
14
|
+
this.logger.info('PatternExtractor: not enough posts with engagement data');
|
|
15
|
+
return [];
|
|
16
|
+
}
|
|
17
|
+
const baseline = this.computeBaseline(rows);
|
|
18
|
+
patterns.push(...this.extractTimingPatterns(rows, baseline));
|
|
19
|
+
patterns.push(...this.extractFormatPatterns(rows, baseline));
|
|
20
|
+
patterns.push(...this.extractPlatformPatterns(rows, baseline));
|
|
21
|
+
patterns.push(...this.extractContentPatterns(rows, baseline));
|
|
22
|
+
const filtered = patterns.filter(p => p.sampleSize >= 3 && p.confidence >= 0.5);
|
|
23
|
+
this.logger.info(`PatternExtractor: extracted ${filtered.length} patterns from ${rows.length} posts`);
|
|
24
|
+
return filtered;
|
|
25
|
+
}
|
|
26
|
+
getPostsWithEngagement() {
|
|
27
|
+
const stmt = this.db.prepare(`
|
|
28
|
+
SELECT p.id, p.platform, p.content, p.format, p.hashtags, p.published_at,
|
|
29
|
+
e.likes, e.comments, e.shares, e.impressions, e.clicks, e.saves
|
|
30
|
+
FROM posts p
|
|
31
|
+
INNER JOIN (
|
|
32
|
+
SELECT post_id, MAX(timestamp) as max_ts FROM engagement GROUP BY post_id
|
|
33
|
+
) latest ON latest.post_id = p.id
|
|
34
|
+
INNER JOIN engagement e ON e.post_id = p.id AND e.timestamp = latest.max_ts
|
|
35
|
+
WHERE p.status = 'published'
|
|
36
|
+
ORDER BY p.published_at DESC
|
|
37
|
+
LIMIT 500
|
|
38
|
+
`);
|
|
39
|
+
return stmt.all();
|
|
40
|
+
}
|
|
41
|
+
computeBaseline(rows) {
|
|
42
|
+
if (rows.length === 0)
|
|
43
|
+
return 0;
|
|
44
|
+
const total = rows.reduce((sum, r) => sum + engagementScore(r), 0);
|
|
45
|
+
return total / rows.length;
|
|
46
|
+
}
|
|
47
|
+
extractTimingPatterns(rows, baseline) {
|
|
48
|
+
const patterns = [];
|
|
49
|
+
// Day-of-week analysis
|
|
50
|
+
const dayBuckets = {};
|
|
51
|
+
// Hour-of-day analysis
|
|
52
|
+
const hourBuckets = {};
|
|
53
|
+
for (const row of rows) {
|
|
54
|
+
if (!row.published_at)
|
|
55
|
+
continue;
|
|
56
|
+
const date = new Date(row.published_at);
|
|
57
|
+
const day = date.getDay();
|
|
58
|
+
const hour = date.getHours();
|
|
59
|
+
const score = engagementScore(row);
|
|
60
|
+
if (!dayBuckets[day])
|
|
61
|
+
dayBuckets[day] = { scores: [], total: 0 };
|
|
62
|
+
dayBuckets[day].scores.push(score);
|
|
63
|
+
dayBuckets[day].total++;
|
|
64
|
+
if (!hourBuckets[hour])
|
|
65
|
+
hourBuckets[hour] = { scores: [], total: 0 };
|
|
66
|
+
hourBuckets[hour].scores.push(score);
|
|
67
|
+
hourBuckets[hour].total++;
|
|
68
|
+
}
|
|
69
|
+
// Day-of-week patterns
|
|
70
|
+
for (const [dayStr, data] of Object.entries(dayBuckets)) {
|
|
71
|
+
const day = Number(dayStr);
|
|
72
|
+
const avg = data.scores.reduce((s, v) => s + v, 0) / data.total;
|
|
73
|
+
const multiplier = baseline > 0 ? avg / baseline : 1;
|
|
74
|
+
if (multiplier >= 1.3 && data.total >= 3) {
|
|
75
|
+
patterns.push({
|
|
76
|
+
pattern: `Posts on ${DAY_NAMES[day]} get ${multiplier.toFixed(1)}x engagement`,
|
|
77
|
+
category: 'timing',
|
|
78
|
+
confidence: this.computeConfidence(data.total, rows.length, multiplier),
|
|
79
|
+
sampleSize: data.total,
|
|
80
|
+
avgEngagement: avg,
|
|
81
|
+
baselineEngagement: baseline,
|
|
82
|
+
multiplier,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
// Hour-of-day patterns: group into morning/afternoon/evening
|
|
87
|
+
const timeBlocks = {
|
|
88
|
+
'early morning (6-9am)': { scores: [], total: 0 },
|
|
89
|
+
'morning (9am-12pm)': { scores: [], total: 0 },
|
|
90
|
+
'afternoon (12-5pm)': { scores: [], total: 0 },
|
|
91
|
+
'evening (5-9pm)': { scores: [], total: 0 },
|
|
92
|
+
'night (9pm-12am)': { scores: [], total: 0 },
|
|
93
|
+
};
|
|
94
|
+
for (const [hourStr, data] of Object.entries(hourBuckets)) {
|
|
95
|
+
const hour = Number(hourStr);
|
|
96
|
+
let block;
|
|
97
|
+
if (hour >= 6 && hour < 9)
|
|
98
|
+
block = 'early morning (6-9am)';
|
|
99
|
+
else if (hour >= 9 && hour < 12)
|
|
100
|
+
block = 'morning (9am-12pm)';
|
|
101
|
+
else if (hour >= 12 && hour < 17)
|
|
102
|
+
block = 'afternoon (12-5pm)';
|
|
103
|
+
else if (hour >= 17 && hour < 21)
|
|
104
|
+
block = 'evening (5-9pm)';
|
|
105
|
+
else
|
|
106
|
+
block = 'night (9pm-12am)';
|
|
107
|
+
timeBlocks[block].scores.push(...data.scores);
|
|
108
|
+
timeBlocks[block].total += data.total;
|
|
109
|
+
}
|
|
110
|
+
for (const [block, data] of Object.entries(timeBlocks)) {
|
|
111
|
+
if (data.total < 3)
|
|
112
|
+
continue;
|
|
113
|
+
const avg = data.scores.reduce((s, v) => s + v, 0) / data.total;
|
|
114
|
+
const multiplier = baseline > 0 ? avg / baseline : 1;
|
|
115
|
+
if (multiplier >= 1.3) {
|
|
116
|
+
patterns.push({
|
|
117
|
+
pattern: `Posts in the ${block} get ${multiplier.toFixed(1)}x engagement`,
|
|
118
|
+
category: 'timing',
|
|
119
|
+
confidence: this.computeConfidence(data.total, rows.length, multiplier),
|
|
120
|
+
sampleSize: data.total,
|
|
121
|
+
avgEngagement: avg,
|
|
122
|
+
baselineEngagement: baseline,
|
|
123
|
+
multiplier,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return patterns;
|
|
128
|
+
}
|
|
129
|
+
extractFormatPatterns(rows, baseline) {
|
|
130
|
+
const patterns = [];
|
|
131
|
+
// Content length analysis
|
|
132
|
+
const shortPosts = [];
|
|
133
|
+
const mediumPosts = [];
|
|
134
|
+
const longPosts = [];
|
|
135
|
+
// Format type analysis
|
|
136
|
+
const formatBuckets = {};
|
|
137
|
+
for (const row of rows) {
|
|
138
|
+
const score = engagementScore(row);
|
|
139
|
+
// Length buckets
|
|
140
|
+
if (row.content.length < 280)
|
|
141
|
+
shortPosts.push(score);
|
|
142
|
+
else if (row.content.length < 1000)
|
|
143
|
+
mediumPosts.push(score);
|
|
144
|
+
else
|
|
145
|
+
longPosts.push(score);
|
|
146
|
+
// Format type
|
|
147
|
+
if (!formatBuckets[row.format])
|
|
148
|
+
formatBuckets[row.format] = [];
|
|
149
|
+
formatBuckets[row.format].push(score);
|
|
150
|
+
}
|
|
151
|
+
// Length patterns
|
|
152
|
+
const lengthBuckets = [
|
|
153
|
+
{ name: 'Short posts (<280 chars)', scores: shortPosts },
|
|
154
|
+
{ name: 'Medium posts (280-1000 chars)', scores: mediumPosts },
|
|
155
|
+
{ name: 'Long posts (>1000 chars)', scores: longPosts },
|
|
156
|
+
];
|
|
157
|
+
for (const bucket of lengthBuckets) {
|
|
158
|
+
if (bucket.scores.length < 3)
|
|
159
|
+
continue;
|
|
160
|
+
const avg = bucket.scores.reduce((s, v) => s + v, 0) / bucket.scores.length;
|
|
161
|
+
const multiplier = baseline > 0 ? avg / baseline : 1;
|
|
162
|
+
if (multiplier >= 1.2) {
|
|
163
|
+
patterns.push({
|
|
164
|
+
pattern: `${bucket.name} outperform average by ${multiplier.toFixed(1)}x`,
|
|
165
|
+
category: 'format',
|
|
166
|
+
confidence: this.computeConfidence(bucket.scores.length, rows.length, multiplier),
|
|
167
|
+
sampleSize: bucket.scores.length,
|
|
168
|
+
avgEngagement: avg,
|
|
169
|
+
baselineEngagement: baseline,
|
|
170
|
+
multiplier,
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
// Format type patterns
|
|
175
|
+
for (const [format, scores] of Object.entries(formatBuckets)) {
|
|
176
|
+
if (scores.length < 3)
|
|
177
|
+
continue;
|
|
178
|
+
const avg = scores.reduce((s, v) => s + v, 0) / scores.length;
|
|
179
|
+
const multiplier = baseline > 0 ? avg / baseline : 1;
|
|
180
|
+
if (multiplier >= 1.2) {
|
|
181
|
+
patterns.push({
|
|
182
|
+
pattern: `${format} posts outperform average by ${multiplier.toFixed(1)}x`,
|
|
183
|
+
category: 'format',
|
|
184
|
+
confidence: this.computeConfidence(scores.length, rows.length, multiplier),
|
|
185
|
+
sampleSize: scores.length,
|
|
186
|
+
avgEngagement: avg,
|
|
187
|
+
baselineEngagement: baseline,
|
|
188
|
+
multiplier,
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
return patterns;
|
|
193
|
+
}
|
|
194
|
+
extractPlatformPatterns(rows, baseline) {
|
|
195
|
+
const patterns = [];
|
|
196
|
+
const platformBuckets = {};
|
|
197
|
+
for (const row of rows) {
|
|
198
|
+
if (!platformBuckets[row.platform])
|
|
199
|
+
platformBuckets[row.platform] = [];
|
|
200
|
+
platformBuckets[row.platform].push(engagementScore(row));
|
|
201
|
+
}
|
|
202
|
+
// Compare platforms against each other
|
|
203
|
+
const platformAvgs = Object.entries(platformBuckets)
|
|
204
|
+
.filter(([, scores]) => scores.length >= 3)
|
|
205
|
+
.map(([platform, scores]) => ({
|
|
206
|
+
platform,
|
|
207
|
+
avg: scores.reduce((s, v) => s + v, 0) / scores.length,
|
|
208
|
+
count: scores.length,
|
|
209
|
+
}))
|
|
210
|
+
.sort((a, b) => b.avg - a.avg);
|
|
211
|
+
for (const pdata of platformAvgs) {
|
|
212
|
+
const multiplier = baseline > 0 ? pdata.avg / baseline : 1;
|
|
213
|
+
if (multiplier >= 1.2) {
|
|
214
|
+
patterns.push({
|
|
215
|
+
pattern: `${pdata.platform} outperforms average by ${multiplier.toFixed(1)}x`,
|
|
216
|
+
category: 'platform',
|
|
217
|
+
confidence: this.computeConfidence(pdata.count, rows.length, multiplier),
|
|
218
|
+
sampleSize: pdata.count,
|
|
219
|
+
avgEngagement: pdata.avg,
|
|
220
|
+
baselineEngagement: baseline,
|
|
221
|
+
multiplier,
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
// Cross-platform comparison (best vs worst)
|
|
226
|
+
if (platformAvgs.length >= 2) {
|
|
227
|
+
const best = platformAvgs[0];
|
|
228
|
+
const worst = platformAvgs[platformAvgs.length - 1];
|
|
229
|
+
if (worst.avg > 0) {
|
|
230
|
+
const crossMultiplier = best.avg / worst.avg;
|
|
231
|
+
if (crossMultiplier >= 1.5) {
|
|
232
|
+
patterns.push({
|
|
233
|
+
pattern: `${best.platform} outperforms ${worst.platform} by ${crossMultiplier.toFixed(1)}x`,
|
|
234
|
+
category: 'platform',
|
|
235
|
+
confidence: this.computeConfidence(Math.min(best.count, worst.count), rows.length, crossMultiplier),
|
|
236
|
+
sampleSize: best.count + worst.count,
|
|
237
|
+
avgEngagement: best.avg,
|
|
238
|
+
baselineEngagement: worst.avg,
|
|
239
|
+
multiplier: crossMultiplier,
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
return patterns;
|
|
245
|
+
}
|
|
246
|
+
extractContentPatterns(rows, baseline) {
|
|
247
|
+
const patterns = [];
|
|
248
|
+
const questionPosts = [];
|
|
249
|
+
const nonQuestionPosts = [];
|
|
250
|
+
const hashtagPosts = [];
|
|
251
|
+
const noHashtagPosts = [];
|
|
252
|
+
const ctaPosts = [];
|
|
253
|
+
const nonCtaPosts = [];
|
|
254
|
+
const ctaPatterns = /\b(check out|click|subscribe|follow|join|sign up|learn more|get started|try|grab|download)\b/i;
|
|
255
|
+
for (const row of rows) {
|
|
256
|
+
const score = engagementScore(row);
|
|
257
|
+
// Questions
|
|
258
|
+
if (row.content.includes('?')) {
|
|
259
|
+
questionPosts.push(score);
|
|
260
|
+
}
|
|
261
|
+
else {
|
|
262
|
+
nonQuestionPosts.push(score);
|
|
263
|
+
}
|
|
264
|
+
// Hashtags
|
|
265
|
+
if (row.hashtags && row.hashtags.trim().length > 0) {
|
|
266
|
+
hashtagPosts.push(score);
|
|
267
|
+
}
|
|
268
|
+
else {
|
|
269
|
+
noHashtagPosts.push(score);
|
|
270
|
+
}
|
|
271
|
+
// Call-to-action
|
|
272
|
+
if (ctaPatterns.test(row.content)) {
|
|
273
|
+
ctaPosts.push(score);
|
|
274
|
+
}
|
|
275
|
+
else {
|
|
276
|
+
nonCtaPosts.push(score);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
// Question pattern
|
|
280
|
+
if (questionPosts.length >= 3 && nonQuestionPosts.length >= 3) {
|
|
281
|
+
const qAvg = questionPosts.reduce((s, v) => s + v, 0) / questionPosts.length;
|
|
282
|
+
const nqAvg = nonQuestionPosts.reduce((s, v) => s + v, 0) / nonQuestionPosts.length;
|
|
283
|
+
const multiplier = nqAvg > 0 ? qAvg / nqAvg : 1;
|
|
284
|
+
if (multiplier >= 1.2) {
|
|
285
|
+
patterns.push({
|
|
286
|
+
pattern: `Posts with questions get ${multiplier.toFixed(1)}x more engagement`,
|
|
287
|
+
category: 'content',
|
|
288
|
+
confidence: this.computeConfidence(questionPosts.length, rows.length, multiplier),
|
|
289
|
+
sampleSize: questionPosts.length,
|
|
290
|
+
avgEngagement: qAvg,
|
|
291
|
+
baselineEngagement: baseline,
|
|
292
|
+
multiplier,
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
// Hashtag pattern
|
|
297
|
+
if (hashtagPosts.length >= 3 && noHashtagPosts.length >= 3) {
|
|
298
|
+
const hAvg = hashtagPosts.reduce((s, v) => s + v, 0) / hashtagPosts.length;
|
|
299
|
+
const nhAvg = noHashtagPosts.reduce((s, v) => s + v, 0) / noHashtagPosts.length;
|
|
300
|
+
const multiplier = nhAvg > 0 ? hAvg / nhAvg : 1;
|
|
301
|
+
if (multiplier >= 1.2) {
|
|
302
|
+
patterns.push({
|
|
303
|
+
pattern: `Posts with hashtags get ${multiplier.toFixed(1)}x more engagement`,
|
|
304
|
+
category: 'content',
|
|
305
|
+
confidence: this.computeConfidence(hashtagPosts.length, rows.length, multiplier),
|
|
306
|
+
sampleSize: hashtagPosts.length,
|
|
307
|
+
avgEngagement: hAvg,
|
|
308
|
+
baselineEngagement: baseline,
|
|
309
|
+
multiplier,
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
// CTA pattern
|
|
314
|
+
if (ctaPosts.length >= 3 && nonCtaPosts.length >= 3) {
|
|
315
|
+
const cAvg = ctaPosts.reduce((s, v) => s + v, 0) / ctaPosts.length;
|
|
316
|
+
const ncAvg = nonCtaPosts.reduce((s, v) => s + v, 0) / nonCtaPosts.length;
|
|
317
|
+
const multiplier = ncAvg > 0 ? cAvg / ncAvg : 1;
|
|
318
|
+
if (multiplier >= 1.2) {
|
|
319
|
+
patterns.push({
|
|
320
|
+
pattern: `Posts with calls-to-action get ${multiplier.toFixed(1)}x more engagement`,
|
|
321
|
+
category: 'content',
|
|
322
|
+
confidence: this.computeConfidence(ctaPosts.length, rows.length, multiplier),
|
|
323
|
+
sampleSize: ctaPosts.length,
|
|
324
|
+
avgEngagement: cAvg,
|
|
325
|
+
baselineEngagement: baseline,
|
|
326
|
+
multiplier,
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
return patterns;
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Compute confidence based on sample size relative to total, and effect magnitude.
|
|
334
|
+
* Higher sample sizes and larger effects yield higher confidence.
|
|
335
|
+
*/
|
|
336
|
+
computeConfidence(sampleSize, totalSize, multiplier) {
|
|
337
|
+
// Sample coverage factor (0-1): more data → higher confidence
|
|
338
|
+
const coverage = Math.min(1, sampleSize / Math.max(1, totalSize));
|
|
339
|
+
// Sample size factor: minimum 3, scales up to ~30
|
|
340
|
+
const sizeFactor = Math.min(1, Math.log(sampleSize + 1) / Math.log(30));
|
|
341
|
+
// Effect factor: larger effects are more likely real
|
|
342
|
+
const effectFactor = Math.min(1, (multiplier - 1) / 2);
|
|
343
|
+
return Math.min(1, (coverage * 0.3 + sizeFactor * 0.4 + effectFactor * 0.3));
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
//# sourceMappingURL=pattern-extractor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pattern-extractor.js","sourceRoot":"","sources":["../../src/learning/pattern-extractor.ts"],"names":[],"mappings":"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"}
|
package/dist/marketing-core.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export declare class MarketingCore {
|
|
|
8
8
|
private researchEngine;
|
|
9
9
|
private crossBrain;
|
|
10
10
|
private notifier;
|
|
11
|
+
private subscriptionManager;
|
|
11
12
|
private config;
|
|
12
13
|
private configPath?;
|
|
13
14
|
private restarting;
|
|
@@ -16,5 +17,6 @@ export declare class MarketingCore {
|
|
|
16
17
|
private cleanup;
|
|
17
18
|
restart(): void;
|
|
18
19
|
stop(): void;
|
|
20
|
+
private setupCrossBrainSubscriptions;
|
|
19
21
|
private setupEventListeners;
|
|
20
22
|
}
|
package/dist/marketing-core.js
CHANGED
|
@@ -3,7 +3,7 @@ import fs from 'node:fs';
|
|
|
3
3
|
import { loadConfig } from './config.js';
|
|
4
4
|
import { createLogger, getLogger } from './utils/logger.js';
|
|
5
5
|
import { getEventBus } from './utils/events.js';
|
|
6
|
-
import { createConnection } from '
|
|
6
|
+
import { createConnection } from '@timmeck/brain-core';
|
|
7
7
|
import { runMigrations } from './db/migrations/index.js';
|
|
8
8
|
// Repositories
|
|
9
9
|
import { PostRepository } from './db/repositories/post.repository.js';
|
|
@@ -17,6 +17,7 @@ import { SynapseRepository } from './db/repositories/synapse.repository.js';
|
|
|
17
17
|
import { InsightRepository } from './db/repositories/insight.repository.js';
|
|
18
18
|
import { MemoryRepository } from './db/repositories/memory.repository.js';
|
|
19
19
|
import { SessionRepository } from './db/repositories/session.repository.js';
|
|
20
|
+
import { ABTestRepository } from './db/repositories/ab-test.repository.js';
|
|
20
21
|
// Services
|
|
21
22
|
import { PostService } from './services/post.service.js';
|
|
22
23
|
import { CampaignService } from './services/campaign.service.js';
|
|
@@ -28,23 +29,26 @@ import { SynapseService } from './services/synapse.service.js';
|
|
|
28
29
|
import { AnalyticsService } from './services/analytics.service.js';
|
|
29
30
|
import { InsightService } from './services/insight.service.js';
|
|
30
31
|
import { MemoryService } from './services/memory.service.js';
|
|
32
|
+
import { ABTestService } from './services/ab-test.service.js';
|
|
33
|
+
import { CalendarService } from './services/calendar.service.js';
|
|
31
34
|
// Synapses
|
|
32
35
|
import { SynapseManager } from './synapses/synapse-manager.js';
|
|
33
36
|
// Engines
|
|
34
37
|
import { LearningEngine } from './learning/learning-engine.js';
|
|
38
|
+
import { PatternExtractor } from './learning/pattern-extractor.js';
|
|
35
39
|
import { ResearchEngine } from './research/research-engine.js';
|
|
36
40
|
// IPC
|
|
37
41
|
import { IpcRouter } from './ipc/router.js';
|
|
38
|
-
import { IpcServer } from '
|
|
42
|
+
import { IpcServer } from '@timmeck/brain-core';
|
|
39
43
|
// API
|
|
40
44
|
import { ApiServer } from './api/server.js';
|
|
41
45
|
// MCP HTTP
|
|
42
46
|
import { McpHttpServer } from './mcp/http-server.js';
|
|
43
47
|
// Dashboard
|
|
44
|
-
import {
|
|
48
|
+
import { createMarketingDashboardServer } from './dashboard/server.js';
|
|
45
49
|
import { renderDashboard } from './dashboard/renderer.js';
|
|
46
50
|
// Cross-Brain
|
|
47
|
-
import { CrossBrainClient, CrossBrainNotifier } from '@timmeck/brain-core';
|
|
51
|
+
import { CrossBrainClient, CrossBrainNotifier, CrossBrainSubscriptionManager } from '@timmeck/brain-core';
|
|
48
52
|
export class MarketingCore {
|
|
49
53
|
db = null;
|
|
50
54
|
ipcServer = null;
|
|
@@ -55,6 +59,7 @@ export class MarketingCore {
|
|
|
55
59
|
researchEngine = null;
|
|
56
60
|
crossBrain = null;
|
|
57
61
|
notifier = null;
|
|
62
|
+
subscriptionManager = null;
|
|
58
63
|
config = null;
|
|
59
64
|
configPath;
|
|
60
65
|
restarting = false;
|
|
@@ -89,10 +94,14 @@ export class MarketingCore {
|
|
|
89
94
|
const insightRepo = new InsightRepository(this.db);
|
|
90
95
|
const memoryRepo = new MemoryRepository(this.db);
|
|
91
96
|
const sessionRepo = new SessionRepository(this.db);
|
|
97
|
+
const abTestRepo = new ABTestRepository(this.db);
|
|
92
98
|
// 6. Synapse Manager
|
|
93
99
|
const synapseManager = new SynapseManager(synapseRepo, config.synapses);
|
|
94
100
|
// 7. Services
|
|
95
101
|
const memoryService = new MemoryService(memoryRepo, sessionRepo, synapseManager);
|
|
102
|
+
const patternExtractor = new PatternExtractor(this.db);
|
|
103
|
+
const abTestService = new ABTestService(abTestRepo);
|
|
104
|
+
const calendarService = new CalendarService(this.db);
|
|
96
105
|
const services = {
|
|
97
106
|
post: new PostService(postRepo, engagementRepo, synapseManager),
|
|
98
107
|
campaign: new CampaignService(campaignRepo, postRepo, engagementRepo, synapseManager),
|
|
@@ -104,6 +113,9 @@ export class MarketingCore {
|
|
|
104
113
|
analytics: new AnalyticsService(postRepo, engagementRepo, campaignRepo, strategyRepo, ruleRepo, templateRepo, insightRepo, synapseManager, memoryRepo, sessionRepo),
|
|
105
114
|
insight: new InsightService(insightRepo, synapseManager),
|
|
106
115
|
memory: memoryService,
|
|
116
|
+
patternExtractor,
|
|
117
|
+
abTest: abTestService,
|
|
118
|
+
calendar: calendarService,
|
|
107
119
|
};
|
|
108
120
|
// 8. Learning Engine
|
|
109
121
|
this.learningEngine = new LearningEngine(config.learning, postRepo, engagementRepo, ruleRepo, strategyRepo, synapseManager);
|
|
@@ -119,10 +131,14 @@ export class MarketingCore {
|
|
|
119
131
|
// 10. Cross-Brain Client + Notifier
|
|
120
132
|
this.crossBrain = new CrossBrainClient('marketing-brain');
|
|
121
133
|
this.notifier = new CrossBrainNotifier(this.crossBrain, 'marketing-brain');
|
|
134
|
+
// 10b. Cross-Brain Subscription Manager
|
|
135
|
+
this.subscriptionManager = new CrossBrainSubscriptionManager('marketing-brain');
|
|
122
136
|
// 11. IPC Server
|
|
123
137
|
const router = new IpcRouter(services);
|
|
124
|
-
this.ipcServer = new IpcServer(router, config.ipc.pipeName);
|
|
138
|
+
this.ipcServer = new IpcServer(router, config.ipc.pipeName, 'marketing-brain', 'marketing-brain');
|
|
125
139
|
this.ipcServer.start();
|
|
140
|
+
// Wire subscription manager into IPC router
|
|
141
|
+
router.setSubscriptionManager(this.subscriptionManager, this.ipcServer);
|
|
126
142
|
// 12. MCP HTTP Server (SSE for Cursor/Windsurf/Cline)
|
|
127
143
|
if (config.mcpHttp.enabled) {
|
|
128
144
|
this.mcpHttpServer = new McpHttpServer(config.mcpHttp.port, router);
|
|
@@ -148,7 +164,7 @@ export class MarketingCore {
|
|
|
148
164
|
rule: services.rule,
|
|
149
165
|
synapse: services.synapse,
|
|
150
166
|
};
|
|
151
|
-
this.dashboardServer =
|
|
167
|
+
this.dashboardServer = createMarketingDashboardServer({
|
|
152
168
|
port: config.dashboard.port,
|
|
153
169
|
getDashboardHtml: () => {
|
|
154
170
|
try {
|
|
@@ -166,6 +182,8 @@ export class MarketingCore {
|
|
|
166
182
|
}
|
|
167
183
|
// 13. Event listeners (synapse wiring)
|
|
168
184
|
this.setupEventListeners(synapseManager);
|
|
185
|
+
// 13b. Cross-Brain Event Subscriptions
|
|
186
|
+
this.setupCrossBrainSubscriptions();
|
|
169
187
|
// 14. PID file
|
|
170
188
|
const pidPath = path.join(path.dirname(config.dbPath), 'marketing-brain.pid');
|
|
171
189
|
fs.writeFileSync(pidPath, String(process.pid));
|
|
@@ -196,6 +214,7 @@ export class MarketingCore {
|
|
|
196
214
|
catch { /* best effort */ }
|
|
197
215
|
}
|
|
198
216
|
cleanup() {
|
|
217
|
+
this.subscriptionManager?.disconnectAll();
|
|
199
218
|
this.researchEngine?.stop();
|
|
200
219
|
this.learningEngine?.stop();
|
|
201
220
|
this.dashboardServer?.stop();
|
|
@@ -210,6 +229,7 @@ export class MarketingCore {
|
|
|
210
229
|
this.dashboardServer = null;
|
|
211
230
|
this.learningEngine = null;
|
|
212
231
|
this.researchEngine = null;
|
|
232
|
+
this.subscriptionManager = null;
|
|
213
233
|
}
|
|
214
234
|
restart() {
|
|
215
235
|
if (this.restarting)
|
|
@@ -238,6 +258,16 @@ export class MarketingCore {
|
|
|
238
258
|
logger.info('Marketing Brain daemon stopped');
|
|
239
259
|
process.exit(0);
|
|
240
260
|
}
|
|
261
|
+
setupCrossBrainSubscriptions() {
|
|
262
|
+
if (!this.subscriptionManager)
|
|
263
|
+
return;
|
|
264
|
+
const logger = getLogger();
|
|
265
|
+
// Subscribe to brain: error:reported events for project health context
|
|
266
|
+
this.subscriptionManager.subscribe('brain', ['error:reported'], (event, data) => {
|
|
267
|
+
logger.info(`[cross-brain] Received ${event} from brain`, { data });
|
|
268
|
+
// TODO: deeper integration — adjust content tone/urgency based on project health
|
|
269
|
+
});
|
|
270
|
+
}
|
|
241
271
|
setupEventListeners(synapseManager) {
|
|
242
272
|
const bus = getEventBus();
|
|
243
273
|
const notifier = this.notifier;
|