cortex-mcp 1.0.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/CHANGELOG.md +54 -0
- package/LICENSE +21 -0
- package/README.md +202 -0
- package/dist/cli/setup.d.ts +12 -0
- package/dist/cli/setup.d.ts.map +1 -0
- package/dist/cli/setup.js +293 -0
- package/dist/cli/setup.js.map +1 -0
- package/dist/config/config.d.ts +13 -0
- package/dist/config/config.d.ts.map +1 -0
- package/dist/config/config.js +33 -0
- package/dist/config/config.js.map +1 -0
- package/dist/core/event-bus.d.ts +19 -0
- package/dist/core/event-bus.d.ts.map +1 -0
- package/dist/core/event-bus.js +51 -0
- package/dist/core/event-bus.js.map +1 -0
- package/dist/db/database.d.ts +19 -0
- package/dist/db/database.d.ts.map +1 -0
- package/dist/db/database.js +254 -0
- package/dist/db/database.js.map +1 -0
- package/dist/db/event-log.d.ts +28 -0
- package/dist/db/event-log.d.ts.map +1 -0
- package/dist/db/event-log.js +87 -0
- package/dist/db/event-log.js.map +1 -0
- package/dist/db/memory-store.d.ts +65 -0
- package/dist/db/memory-store.d.ts.map +1 -0
- package/dist/db/memory-store.js +370 -0
- package/dist/db/memory-store.js.map +1 -0
- package/dist/embedding-worker.d.ts +3 -0
- package/dist/embedding-worker.d.ts.map +1 -0
- package/dist/embedding-worker.js +94 -0
- package/dist/embedding-worker.js.map +1 -0
- package/dist/hooks/cortex-run.d.ts +15 -0
- package/dist/hooks/cortex-run.d.ts.map +1 -0
- package/dist/hooks/cortex-run.js +148 -0
- package/dist/hooks/cortex-run.js.map +1 -0
- package/dist/hooks/git-capture.d.ts +21 -0
- package/dist/hooks/git-capture.d.ts.map +1 -0
- package/dist/hooks/git-capture.js +178 -0
- package/dist/hooks/git-capture.js.map +1 -0
- package/dist/hooks/git-hooks.d.ts +12 -0
- package/dist/hooks/git-hooks.d.ts.map +1 -0
- package/dist/hooks/git-hooks.js +130 -0
- package/dist/hooks/git-hooks.js.map +1 -0
- package/dist/mcp-stdio.d.ts +10 -0
- package/dist/mcp-stdio.d.ts.map +1 -0
- package/dist/mcp-stdio.js +247 -0
- package/dist/mcp-stdio.js.map +1 -0
- package/dist/memory/anticipation-engine.d.ts +19 -0
- package/dist/memory/anticipation-engine.d.ts.map +1 -0
- package/dist/memory/anticipation-engine.js +76 -0
- package/dist/memory/anticipation-engine.js.map +1 -0
- package/dist/memory/attention-ranker.d.ts +19 -0
- package/dist/memory/attention-ranker.d.ts.map +1 -0
- package/dist/memory/attention-ranker.js +97 -0
- package/dist/memory/attention-ranker.js.map +1 -0
- package/dist/memory/auto-learner.d.ts +20 -0
- package/dist/memory/auto-learner.d.ts.map +1 -0
- package/dist/memory/auto-learner.js +179 -0
- package/dist/memory/auto-learner.js.map +1 -0
- package/dist/memory/confidence-decay.d.ts +22 -0
- package/dist/memory/confidence-decay.d.ts.map +1 -0
- package/dist/memory/confidence-decay.js +54 -0
- package/dist/memory/confidence-decay.js.map +1 -0
- package/dist/memory/embedding-manager.d.ts +5 -0
- package/dist/memory/embedding-manager.d.ts.map +1 -0
- package/dist/memory/embedding-manager.js +118 -0
- package/dist/memory/embedding-manager.js.map +1 -0
- package/dist/memory/export-import.d.ts +49 -0
- package/dist/memory/export-import.d.ts.map +1 -0
- package/dist/memory/export-import.js +131 -0
- package/dist/memory/export-import.js.map +1 -0
- package/dist/memory/git-memory.d.ts +15 -0
- package/dist/memory/git-memory.d.ts.map +1 -0
- package/dist/memory/git-memory.js +178 -0
- package/dist/memory/git-memory.js.map +1 -0
- package/dist/memory/learning-rate.d.ts +24 -0
- package/dist/memory/learning-rate.d.ts.map +1 -0
- package/dist/memory/learning-rate.js +95 -0
- package/dist/memory/learning-rate.js.map +1 -0
- package/dist/memory/llm-enhancer.d.ts +54 -0
- package/dist/memory/llm-enhancer.d.ts.map +1 -0
- package/dist/memory/llm-enhancer.js +270 -0
- package/dist/memory/llm-enhancer.js.map +1 -0
- package/dist/memory/memory-cache.d.ts +5 -0
- package/dist/memory/memory-cache.d.ts.map +1 -0
- package/dist/memory/memory-cache.js +37 -0
- package/dist/memory/memory-cache.js.map +1 -0
- package/dist/memory/memory-consolidator.d.ts +14 -0
- package/dist/memory/memory-consolidator.d.ts.map +1 -0
- package/dist/memory/memory-consolidator.js +156 -0
- package/dist/memory/memory-consolidator.js.map +1 -0
- package/dist/memory/memory-decay.d.ts +10 -0
- package/dist/memory/memory-decay.d.ts.map +1 -0
- package/dist/memory/memory-decay.js +79 -0
- package/dist/memory/memory-decay.js.map +1 -0
- package/dist/memory/memory-quality.d.ts +37 -0
- package/dist/memory/memory-quality.d.ts.map +1 -0
- package/dist/memory/memory-quality.js +203 -0
- package/dist/memory/memory-quality.js.map +1 -0
- package/dist/memory/memory-ranker.d.ts +14 -0
- package/dist/memory/memory-ranker.d.ts.map +1 -0
- package/dist/memory/memory-ranker.js +68 -0
- package/dist/memory/memory-ranker.js.map +1 -0
- package/dist/memory/meta-memory.d.ts +11 -0
- package/dist/memory/meta-memory.d.ts.map +1 -0
- package/dist/memory/meta-memory.js +141 -0
- package/dist/memory/meta-memory.js.map +1 -0
- package/dist/memory/session-tracker.d.ts +39 -0
- package/dist/memory/session-tracker.d.ts.map +1 -0
- package/dist/memory/session-tracker.js +127 -0
- package/dist/memory/session-tracker.js.map +1 -0
- package/dist/memory/temporal-engine.d.ts +25 -0
- package/dist/memory/temporal-engine.d.ts.map +1 -0
- package/dist/memory/temporal-engine.js +106 -0
- package/dist/memory/temporal-engine.js.map +1 -0
- package/dist/retrieval/hybrid-retriever.d.ts +23 -0
- package/dist/retrieval/hybrid-retriever.d.ts.map +1 -0
- package/dist/retrieval/hybrid-retriever.js +120 -0
- package/dist/retrieval/hybrid-retriever.js.map +1 -0
- package/dist/scanners/architecture-graph.d.ts +30 -0
- package/dist/scanners/architecture-graph.d.ts.map +1 -0
- package/dist/scanners/architecture-graph.js +315 -0
- package/dist/scanners/architecture-graph.js.map +1 -0
- package/dist/scanners/code-verifier.d.ts +70 -0
- package/dist/scanners/code-verifier.d.ts.map +1 -0
- package/dist/scanners/code-verifier.js +374 -0
- package/dist/scanners/code-verifier.js.map +1 -0
- package/dist/scanners/context-builder.d.ts +19 -0
- package/dist/scanners/context-builder.d.ts.map +1 -0
- package/dist/scanners/context-builder.js +102 -0
- package/dist/scanners/context-builder.js.map +1 -0
- package/dist/scanners/export-map.d.ts +22 -0
- package/dist/scanners/export-map.d.ts.map +1 -0
- package/dist/scanners/export-map.js +249 -0
- package/dist/scanners/export-map.js.map +1 -0
- package/dist/scanners/file-verifier.d.ts +22 -0
- package/dist/scanners/file-verifier.d.ts.map +1 -0
- package/dist/scanners/file-verifier.js +140 -0
- package/dist/scanners/file-verifier.js.map +1 -0
- package/dist/scanners/project-scanner.d.ts +31 -0
- package/dist/scanners/project-scanner.d.ts.map +1 -0
- package/dist/scanners/project-scanner.js +398 -0
- package/dist/scanners/project-scanner.js.map +1 -0
- package/dist/security/encryption.d.ts +15 -0
- package/dist/security/encryption.d.ts.map +1 -0
- package/dist/security/encryption.js +116 -0
- package/dist/security/encryption.js.map +1 -0
- package/dist/security/feature-gate.d.ts +30 -0
- package/dist/security/feature-gate.d.ts.map +1 -0
- package/dist/security/feature-gate.js +91 -0
- package/dist/security/feature-gate.js.map +1 -0
- package/dist/security/license.d.ts +24 -0
- package/dist/security/license.d.ts.map +1 -0
- package/dist/security/license.js +168 -0
- package/dist/security/license.js.map +1 -0
- package/dist/security/rate-limiter.d.ts +20 -0
- package/dist/security/rate-limiter.d.ts.map +1 -0
- package/dist/security/rate-limiter.js +60 -0
- package/dist/security/rate-limiter.js.map +1 -0
- package/dist/server/dashboard.d.ts +3 -0
- package/dist/server/dashboard.d.ts.map +1 -0
- package/dist/server/dashboard.js +258 -0
- package/dist/server/dashboard.js.map +1 -0
- package/dist/server/mcp-handler.d.ts +12 -0
- package/dist/server/mcp-handler.d.ts.map +1 -0
- package/dist/server/mcp-handler.js +1392 -0
- package/dist/server/mcp-handler.js.map +1 -0
- package/dist/strategies/embedders/local-minilm.d.ts +35 -0
- package/dist/strategies/embedders/local-minilm.d.ts.map +1 -0
- package/dist/strategies/embedders/local-minilm.js +176 -0
- package/dist/strategies/embedders/local-minilm.js.map +1 -0
- package/dist/types.d.ts +207 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +83 -0
- package/dist/types.js.map +1 -0
- package/package.json +87 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getFeatureLimits = getFeatureLimits;
|
|
4
|
+
exports.isFeatureAllowed = isFeatureAllowed;
|
|
5
|
+
exports.canStoreMemory = canStoreMemory;
|
|
6
|
+
exports.getUpgradeMessage = getUpgradeMessage;
|
|
7
|
+
exports.formatPlanStatus = formatPlanStatus;
|
|
8
|
+
/**
|
|
9
|
+
* Feature Gate โ Enforces free/paid limits based on license.
|
|
10
|
+
*
|
|
11
|
+
* FREE plan limits:
|
|
12
|
+
* - Max 20 active memories
|
|
13
|
+
* - Basic recall only (no brain layers)
|
|
14
|
+
* - No auto-learn
|
|
15
|
+
* - No export map / architecture graph
|
|
16
|
+
* - No git memory
|
|
17
|
+
* - No contradiction detection
|
|
18
|
+
* - No confidence decay
|
|
19
|
+
*
|
|
20
|
+
* PRO plan: Everything unlocked, unlimited.
|
|
21
|
+
*/
|
|
22
|
+
const license_1 = require("./license");
|
|
23
|
+
const FREE_LIMITS = {
|
|
24
|
+
maxMemories: 20,
|
|
25
|
+
brainLayers: false,
|
|
26
|
+
autoLearn: false,
|
|
27
|
+
exportMap: false,
|
|
28
|
+
architectureGraph: false,
|
|
29
|
+
gitMemory: false,
|
|
30
|
+
contradictionDetection: false,
|
|
31
|
+
confidenceDecay: false,
|
|
32
|
+
memoryConsolidation: false,
|
|
33
|
+
attentionRanking: false,
|
|
34
|
+
anticipation: false,
|
|
35
|
+
knowledgeGaps: false,
|
|
36
|
+
temporalContext: false,
|
|
37
|
+
crossSessionThreading: false,
|
|
38
|
+
};
|
|
39
|
+
const PRO_LIMITS = {
|
|
40
|
+
maxMemories: Infinity,
|
|
41
|
+
brainLayers: true,
|
|
42
|
+
autoLearn: true,
|
|
43
|
+
exportMap: true,
|
|
44
|
+
architectureGraph: true,
|
|
45
|
+
gitMemory: true,
|
|
46
|
+
contradictionDetection: true,
|
|
47
|
+
confidenceDecay: true,
|
|
48
|
+
memoryConsolidation: true,
|
|
49
|
+
attentionRanking: true,
|
|
50
|
+
anticipation: true,
|
|
51
|
+
knowledgeGaps: true,
|
|
52
|
+
temporalContext: true,
|
|
53
|
+
crossSessionThreading: true,
|
|
54
|
+
};
|
|
55
|
+
/** Get current feature limits based on license */
|
|
56
|
+
function getFeatureLimits() {
|
|
57
|
+
return (0, license_1.isPro)() ? PRO_LIMITS : FREE_LIMITS;
|
|
58
|
+
}
|
|
59
|
+
/** Check if a specific feature is allowed */
|
|
60
|
+
function isFeatureAllowed(feature) {
|
|
61
|
+
const limits = getFeatureLimits();
|
|
62
|
+
const value = limits[feature];
|
|
63
|
+
if (typeof value === 'boolean')
|
|
64
|
+
return value;
|
|
65
|
+
return true; // numeric limits are checked separately
|
|
66
|
+
}
|
|
67
|
+
/** Check if user can store more memories */
|
|
68
|
+
function canStoreMemory(currentCount) {
|
|
69
|
+
const limits = getFeatureLimits();
|
|
70
|
+
if (currentCount >= limits.maxMemories) {
|
|
71
|
+
return {
|
|
72
|
+
allowed: false,
|
|
73
|
+
message: `[LOCKED] Free plan limit: ${limits.maxMemories} memories. Upgrade to PRO for unlimited. Set CORTEX_LICENSE_KEY or visit cortex-mcp.org`,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
return { allowed: true, message: '' };
|
|
77
|
+
}
|
|
78
|
+
/** Get upgrade message for gated features */
|
|
79
|
+
function getUpgradeMessage(feature) {
|
|
80
|
+
return `[LOCKED] "${feature}" is a PRO feature. Upgrade at cortex-mcp.org or set CORTEX_LICENSE_KEY to unlock.`;
|
|
81
|
+
}
|
|
82
|
+
/** Format plan status for display */
|
|
83
|
+
function formatPlanStatus() {
|
|
84
|
+
const license = (0, license_1.getLicense)();
|
|
85
|
+
const limits = getFeatureLimits();
|
|
86
|
+
if (license.plan === 'PRO') {
|
|
87
|
+
return `[PRO] Cortex PRO โ All features unlocked, unlimited memories.`;
|
|
88
|
+
}
|
|
89
|
+
return `[FREE] Cortex Free โ ${limits.maxMemories} memories, basic features. Upgrade: set CORTEX_LICENSE_KEY`;
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=feature-gate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feature-gate.js","sourceRoot":"","sources":["../../src/security/feature-gate.ts"],"names":[],"mappings":";;AAoEA,4CAEC;AAGD,4CAKC;AAGD,wCASC;AAGD,8CAEC;AAGD,4CASC;AA3GD;;;;;;;;;;;;;GAaG;AACH,uCAA4D;AAmB5D,MAAM,WAAW,GAAkB;IAC/B,WAAW,EAAE,EAAE;IACf,WAAW,EAAE,KAAK;IAClB,SAAS,EAAE,KAAK;IAChB,SAAS,EAAE,KAAK;IAChB,iBAAiB,EAAE,KAAK;IACxB,SAAS,EAAE,KAAK;IAChB,sBAAsB,EAAE,KAAK;IAC7B,eAAe,EAAE,KAAK;IACtB,mBAAmB,EAAE,KAAK;IAC1B,gBAAgB,EAAE,KAAK;IACvB,YAAY,EAAE,KAAK;IACnB,aAAa,EAAE,KAAK;IACpB,eAAe,EAAE,KAAK;IACtB,qBAAqB,EAAE,KAAK;CAC/B,CAAC;AAEF,MAAM,UAAU,GAAkB;IAC9B,WAAW,EAAE,QAAQ;IACrB,WAAW,EAAE,IAAI;IACjB,SAAS,EAAE,IAAI;IACf,SAAS,EAAE,IAAI;IACf,iBAAiB,EAAE,IAAI;IACvB,SAAS,EAAE,IAAI;IACf,sBAAsB,EAAE,IAAI;IAC5B,eAAe,EAAE,IAAI;IACrB,mBAAmB,EAAE,IAAI;IACzB,gBAAgB,EAAE,IAAI;IACtB,YAAY,EAAE,IAAI;IAClB,aAAa,EAAE,IAAI;IACnB,eAAe,EAAE,IAAI;IACrB,qBAAqB,EAAE,IAAI;CAC9B,CAAC;AAEF,kDAAkD;AAClD,SAAgB,gBAAgB;IAC5B,OAAO,IAAA,eAAK,GAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC;AAC9C,CAAC;AAED,6CAA6C;AAC7C,SAAgB,gBAAgB,CAAC,OAA4B;IACzD,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;IAClC,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IAC9B,IAAI,OAAO,KAAK,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAC7C,OAAO,IAAI,CAAC,CAAC,wCAAwC;AACzD,CAAC;AAED,4CAA4C;AAC5C,SAAgB,cAAc,CAAC,YAAoB;IAC/C,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;IAClC,IAAI,YAAY,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;QACrC,OAAO;YACH,OAAO,EAAE,KAAK;YACd,OAAO,EAAE,6BAA6B,MAAM,CAAC,WAAW,yFAAyF;SACpJ,CAAC;IACN,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;AAC1C,CAAC;AAED,6CAA6C;AAC7C,SAAgB,iBAAiB,CAAC,OAAe;IAC7C,OAAO,aAAa,OAAO,oFAAoF,CAAC;AACpH,CAAC;AAED,qCAAqC;AACrC,SAAgB,gBAAgB;IAC5B,MAAM,OAAO,GAAG,IAAA,oBAAU,GAAE,CAAC;IAC7B,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;IAElC,IAAI,OAAO,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QACzB,OAAO,+DAA+D,CAAC;IAC3E,CAAC;IAED,OAAO,wBAAwB,MAAM,CAAC,WAAW,4DAA4D,CAAC;AAClH,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export type Plan = 'FREE' | 'PRO';
|
|
2
|
+
export interface LicenseInfo {
|
|
3
|
+
plan: Plan;
|
|
4
|
+
key: string | null;
|
|
5
|
+
valid: boolean;
|
|
6
|
+
message: string;
|
|
7
|
+
}
|
|
8
|
+
/** Get current license status (cached after first check) */
|
|
9
|
+
export declare function getLicense(): LicenseInfo;
|
|
10
|
+
/** Force re-check license (after user enters a new key) */
|
|
11
|
+
export declare function refreshLicense(): LicenseInfo;
|
|
12
|
+
/** Check if current plan is PRO */
|
|
13
|
+
export declare function isPro(): boolean;
|
|
14
|
+
/** Check if current plan is FREE */
|
|
15
|
+
export declare function isFree(): boolean;
|
|
16
|
+
/** Generate a valid license key (for your use when selling) */
|
|
17
|
+
export declare function generateKey(email: string): string;
|
|
18
|
+
/** Validate a license key format and checksum */
|
|
19
|
+
export declare function validateKey(key: string): boolean;
|
|
20
|
+
/** Generate a key with valid checksum (for selling) */
|
|
21
|
+
export declare function generateValidKey(identifier: string): string;
|
|
22
|
+
/** Save a license key to disk */
|
|
23
|
+
export declare function saveKey(key: string): void;
|
|
24
|
+
//# sourceMappingURL=license.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"license.d.ts","sourceRoot":"","sources":["../../src/security/license.ts"],"names":[],"mappings":"AAiBA,MAAM,MAAM,IAAI,GAAG,MAAM,GAAG,KAAK,CAAC;AAElC,MAAM,WAAW,WAAW;IACxB,IAAI,EAAE,IAAI,CAAC;IACX,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACnB;AAOD,4DAA4D;AAC5D,wBAAgB,UAAU,IAAI,WAAW,CAIxC;AAED,2DAA2D;AAC3D,wBAAgB,cAAc,IAAI,WAAW,CAG5C;AAED,mCAAmC;AACnC,wBAAgB,KAAK,IAAI,OAAO,CAE/B;AAED,oCAAoC;AACpC,wBAAgB,MAAM,IAAI,OAAO,CAEhC;AAED,+DAA+D;AAC/D,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CASjD;AAED,iDAAiD;AACjD,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAoBhD;AAED,uDAAuD;AACvD,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAiB3D;AAED,iCAAiC;AACjC,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAKzC"}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.getLicense = getLicense;
|
|
37
|
+
exports.refreshLicense = refreshLicense;
|
|
38
|
+
exports.isPro = isPro;
|
|
39
|
+
exports.isFree = isFree;
|
|
40
|
+
exports.generateKey = generateKey;
|
|
41
|
+
exports.validateKey = validateKey;
|
|
42
|
+
exports.generateValidKey = generateValidKey;
|
|
43
|
+
exports.saveKey = saveKey;
|
|
44
|
+
/**
|
|
45
|
+
* License System โ Gates features behind free/paid plans.
|
|
46
|
+
*
|
|
47
|
+
* Key format: CORTEX-XXXX-XXXX-XXXX-XXXX (20 chars + dashes)
|
|
48
|
+
* Keys are validated with a simple hash check (offline-first).
|
|
49
|
+
*
|
|
50
|
+
* Environment: CORTEX_LICENSE_KEY or ~/.cortex/license file
|
|
51
|
+
*
|
|
52
|
+
* Plans:
|
|
53
|
+
* FREE: 20 memories, basic recall, no brain layers
|
|
54
|
+
* PRO: Unlimited memories, all 14 brain layers, all features
|
|
55
|
+
*/
|
|
56
|
+
const fs = __importStar(require("fs"));
|
|
57
|
+
const path = __importStar(require("path"));
|
|
58
|
+
const os = __importStar(require("os"));
|
|
59
|
+
const crypto = __importStar(require("crypto"));
|
|
60
|
+
// Secret salt for key validation (change this before publishing)
|
|
61
|
+
const KEY_SALT = 'cortex-mcp-2024-salt';
|
|
62
|
+
let cachedLicense = null;
|
|
63
|
+
/** Get current license status (cached after first check) */
|
|
64
|
+
function getLicense() {
|
|
65
|
+
if (cachedLicense)
|
|
66
|
+
return cachedLicense;
|
|
67
|
+
cachedLicense = detectLicense();
|
|
68
|
+
return cachedLicense;
|
|
69
|
+
}
|
|
70
|
+
/** Force re-check license (after user enters a new key) */
|
|
71
|
+
function refreshLicense() {
|
|
72
|
+
cachedLicense = null;
|
|
73
|
+
return getLicense();
|
|
74
|
+
}
|
|
75
|
+
/** Check if current plan is PRO */
|
|
76
|
+
function isPro() {
|
|
77
|
+
return getLicense().plan === 'PRO';
|
|
78
|
+
}
|
|
79
|
+
/** Check if current plan is FREE */
|
|
80
|
+
function isFree() {
|
|
81
|
+
return getLicense().plan === 'FREE';
|
|
82
|
+
}
|
|
83
|
+
/** Generate a valid license key (for your use when selling) */
|
|
84
|
+
function generateKey(email) {
|
|
85
|
+
const raw = crypto.createHash('sha256')
|
|
86
|
+
.update(KEY_SALT + ':' + email.toLowerCase().trim())
|
|
87
|
+
.digest('hex')
|
|
88
|
+
.slice(0, 20)
|
|
89
|
+
.toUpperCase();
|
|
90
|
+
// Format: CORTEX-XXXX-XXXX-XXXX-XXXX
|
|
91
|
+
return `CORTEX-${raw.slice(0, 4)}-${raw.slice(4, 8)}-${raw.slice(8, 12)}-${raw.slice(12, 16)}`;
|
|
92
|
+
}
|
|
93
|
+
/** Validate a license key format and checksum */
|
|
94
|
+
function validateKey(key) {
|
|
95
|
+
if (!key)
|
|
96
|
+
return false;
|
|
97
|
+
// Must match format: CORTEX-XXXX-XXXX-XXXX-XXXX
|
|
98
|
+
const pattern = /^CORTEX-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}$/;
|
|
99
|
+
if (!pattern.test(key.trim().toUpperCase()))
|
|
100
|
+
return false;
|
|
101
|
+
// Extract the raw part (remove CORTEX- and dashes)
|
|
102
|
+
const raw = key.replace(/^CORTEX-/, '').replace(/-/g, '');
|
|
103
|
+
// Validate checksum: last 4 chars must be hash of first 12
|
|
104
|
+
const payload = raw.slice(0, 12);
|
|
105
|
+
const checksum = raw.slice(12, 16);
|
|
106
|
+
const expected = crypto.createHash('md5')
|
|
107
|
+
.update(KEY_SALT + ':' + payload)
|
|
108
|
+
.digest('hex')
|
|
109
|
+
.slice(0, 4)
|
|
110
|
+
.toUpperCase();
|
|
111
|
+
return checksum === expected;
|
|
112
|
+
}
|
|
113
|
+
/** Generate a key with valid checksum (for selling) */
|
|
114
|
+
function generateValidKey(identifier) {
|
|
115
|
+
// Generate 12 random chars as payload
|
|
116
|
+
const payload = crypto.createHash('sha256')
|
|
117
|
+
.update(KEY_SALT + ':key:' + identifier + ':' + Date.now())
|
|
118
|
+
.digest('hex')
|
|
119
|
+
.slice(0, 12)
|
|
120
|
+
.toUpperCase();
|
|
121
|
+
// Generate checksum from payload
|
|
122
|
+
const checksum = crypto.createHash('md5')
|
|
123
|
+
.update(KEY_SALT + ':' + payload)
|
|
124
|
+
.digest('hex')
|
|
125
|
+
.slice(0, 4)
|
|
126
|
+
.toUpperCase();
|
|
127
|
+
const raw = payload + checksum;
|
|
128
|
+
return `CORTEX-${raw.slice(0, 4)}-${raw.slice(4, 8)}-${raw.slice(8, 12)}-${raw.slice(12, 16)}`;
|
|
129
|
+
}
|
|
130
|
+
/** Save a license key to disk */
|
|
131
|
+
function saveKey(key) {
|
|
132
|
+
const dir = path.join(os.homedir(), '.cortex');
|
|
133
|
+
if (!fs.existsSync(dir))
|
|
134
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
135
|
+
fs.writeFileSync(path.join(dir, 'license'), key.trim(), 'utf-8');
|
|
136
|
+
refreshLicense();
|
|
137
|
+
}
|
|
138
|
+
// โโโ Internal โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
139
|
+
function detectLicense() {
|
|
140
|
+
// Priority 1: Environment variable
|
|
141
|
+
const envKey = process.env.CORTEX_LICENSE_KEY?.trim();
|
|
142
|
+
if (envKey) {
|
|
143
|
+
if (validateKey(envKey)) {
|
|
144
|
+
return { plan: 'PRO', key: envKey, valid: true, message: '[OK] PRO license active (from env)' };
|
|
145
|
+
}
|
|
146
|
+
return { plan: 'FREE', key: envKey, valid: false, message: '[FAIL] Invalid license key in CORTEX_LICENSE_KEY' };
|
|
147
|
+
}
|
|
148
|
+
// Priority 2: License file at ~/.cortex/license
|
|
149
|
+
try {
|
|
150
|
+
const licFile = path.join(os.homedir(), '.cortex', 'license');
|
|
151
|
+
if (fs.existsSync(licFile)) {
|
|
152
|
+
const fileKey = fs.readFileSync(licFile, 'utf-8').trim();
|
|
153
|
+
if (validateKey(fileKey)) {
|
|
154
|
+
return { plan: 'PRO', key: fileKey, valid: true, message: '[OK] PRO license active (from ~/.cortex/license)' };
|
|
155
|
+
}
|
|
156
|
+
return { plan: 'FREE', key: fileKey, valid: false, message: '[FAIL] Invalid license key in ~/.cortex/license' };
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
catch { }
|
|
160
|
+
// No key found โ FREE plan
|
|
161
|
+
return {
|
|
162
|
+
plan: 'FREE',
|
|
163
|
+
key: null,
|
|
164
|
+
valid: false,
|
|
165
|
+
message: 'Free plan (20 memories). Upgrade: cortex-mcp.org',
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
//# sourceMappingURL=license.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"license.js","sourceRoot":"","sources":["../../src/security/license.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCA,gCAIC;AAGD,wCAGC;AAGD,sBAEC;AAGD,wBAEC;AAGD,kCASC;AAGD,kCAoBC;AAGD,4CAiBC;AAGD,0BAKC;AAnHD;;;;;;;;;;;GAWG;AACH,uCAAyB;AACzB,2CAA6B;AAC7B,uCAAyB;AACzB,+CAAiC;AAWjC,iEAAiE;AACjE,MAAM,QAAQ,GAAG,sBAAsB,CAAC;AAExC,IAAI,aAAa,GAAuB,IAAI,CAAC;AAE7C,4DAA4D;AAC5D,SAAgB,UAAU;IACtB,IAAI,aAAa;QAAE,OAAO,aAAa,CAAC;IACxC,aAAa,GAAG,aAAa,EAAE,CAAC;IAChC,OAAO,aAAa,CAAC;AACzB,CAAC;AAED,2DAA2D;AAC3D,SAAgB,cAAc;IAC1B,aAAa,GAAG,IAAI,CAAC;IACrB,OAAO,UAAU,EAAE,CAAC;AACxB,CAAC;AAED,mCAAmC;AACnC,SAAgB,KAAK;IACjB,OAAO,UAAU,EAAE,CAAC,IAAI,KAAK,KAAK,CAAC;AACvC,CAAC;AAED,oCAAoC;AACpC,SAAgB,MAAM;IAClB,OAAO,UAAU,EAAE,CAAC,IAAI,KAAK,MAAM,CAAC;AACxC,CAAC;AAED,+DAA+D;AAC/D,SAAgB,WAAW,CAAC,KAAa;IACrC,MAAM,GAAG,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC;SAClC,MAAM,CAAC,QAAQ,GAAG,GAAG,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;SACnD,MAAM,CAAC,KAAK,CAAC;SACb,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;SACZ,WAAW,EAAE,CAAC;IAEnB,qCAAqC;IACrC,OAAO,UAAU,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC;AACnG,CAAC;AAED,iDAAiD;AACjD,SAAgB,WAAW,CAAC,GAAW;IACnC,IAAI,CAAC,GAAG;QAAE,OAAO,KAAK,CAAC;IAEvB,gDAAgD;IAChD,MAAM,OAAO,GAAG,0DAA0D,CAAC;IAC3E,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAAE,OAAO,KAAK,CAAC;IAE1D,mDAAmD;IACnD,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAE1D,2DAA2D;IAC3D,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACjC,MAAM,QAAQ,GAAG,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IACnC,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC;SACpC,MAAM,CAAC,QAAQ,GAAG,GAAG,GAAG,OAAO,CAAC;SAChC,MAAM,CAAC,KAAK,CAAC;SACb,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;SACX,WAAW,EAAE,CAAC;IAEnB,OAAO,QAAQ,KAAK,QAAQ,CAAC;AACjC,CAAC;AAED,uDAAuD;AACvD,SAAgB,gBAAgB,CAAC,UAAkB;IAC/C,sCAAsC;IACtC,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC;SACtC,MAAM,CAAC,QAAQ,GAAG,OAAO,GAAG,UAAU,GAAG,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;SAC1D,MAAM,CAAC,KAAK,CAAC;SACb,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;SACZ,WAAW,EAAE,CAAC;IAEnB,iCAAiC;IACjC,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC;SACpC,MAAM,CAAC,QAAQ,GAAG,GAAG,GAAG,OAAO,CAAC;SAChC,MAAM,CAAC,KAAK,CAAC;SACb,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;SACX,WAAW,EAAE,CAAC;IAEnB,MAAM,GAAG,GAAG,OAAO,GAAG,QAAQ,CAAC;IAC/B,OAAO,UAAU,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC;AACnG,CAAC;AAED,iCAAiC;AACjC,SAAgB,OAAO,CAAC,GAAW;IAC/B,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;IAC/C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAChE,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,EAAE,GAAG,CAAC,IAAI,EAAE,EAAE,OAAO,CAAC,CAAC;IACjE,cAAc,EAAE,CAAC;AACrB,CAAC;AAED,iFAAiF;AAEjF,SAAS,aAAa;IAClB,mCAAmC;IACnC,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,IAAI,EAAE,CAAC;IACtD,IAAI,MAAM,EAAE,CAAC;QACT,IAAI,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC;YACtB,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,oCAAoC,EAAE,CAAC;QACpG,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,kDAAkD,EAAE,CAAC;IACpH,CAAC;IAED,gDAAgD;IAChD,IAAI,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;QAC9D,IAAI,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACzB,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;YACzD,IAAI,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC;gBACvB,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,kDAAkD,EAAE,CAAC;YACnH,CAAC;YACD,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,iDAAiD,EAAE,CAAC;QACpH,CAAC;IACL,CAAC;IAAC,MAAM,CAAC,CAAC,CAAC;IAEX,2BAA2B;IAC3B,OAAO;QACH,IAAI,EAAE,MAAM;QACZ,GAAG,EAAE,IAAI;QACT,KAAK,EAAE,KAAK;QACZ,OAAO,EAAE,kDAAkD;KAC9D,CAAC;AACN,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rate Limiter โ Prevents unbounded memory storage per session.
|
|
3
|
+
*
|
|
4
|
+
* Limits:
|
|
5
|
+
* - Max 30 memories stored per session (resets on server restart)
|
|
6
|
+
* - Max 100 auto_learn calls per session
|
|
7
|
+
* - Max 500 total tool calls per session
|
|
8
|
+
*/
|
|
9
|
+
export declare function checkRateLimit(operation: 'store' | 'auto_learn' | 'call'): {
|
|
10
|
+
allowed: boolean;
|
|
11
|
+
reason?: string;
|
|
12
|
+
};
|
|
13
|
+
export declare function getRateLimitStats(): {
|
|
14
|
+
storeCount: number;
|
|
15
|
+
autoLearnCount: number;
|
|
16
|
+
totalCalls: number;
|
|
17
|
+
uptime: number;
|
|
18
|
+
};
|
|
19
|
+
export declare function resetRateLimits(): void;
|
|
20
|
+
//# sourceMappingURL=rate-limiter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rate-limiter.d.ts","sourceRoot":"","sources":["../../src/security/rate-limiter.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAsBH,wBAAgB,cAAc,CAAC,SAAS,EAAE,OAAO,GAAG,YAAY,GAAG,MAAM,GAAG;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAsBhH;AAED,wBAAgB,iBAAiB,IAAI;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAOtH;AAED,wBAAgB,eAAe,IAAI,IAAI,CAOtC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Rate Limiter โ Prevents unbounded memory storage per session.
|
|
4
|
+
*
|
|
5
|
+
* Limits:
|
|
6
|
+
* - Max 30 memories stored per session (resets on server restart)
|
|
7
|
+
* - Max 100 auto_learn calls per session
|
|
8
|
+
* - Max 500 total tool calls per session
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.checkRateLimit = checkRateLimit;
|
|
12
|
+
exports.getRateLimitStats = getRateLimitStats;
|
|
13
|
+
exports.resetRateLimits = resetRateLimits;
|
|
14
|
+
const LIMITS = {
|
|
15
|
+
MAX_STORES_PER_SESSION: 30,
|
|
16
|
+
MAX_AUTO_LEARN_PER_SESSION: 100,
|
|
17
|
+
MAX_CALLS_PER_SESSION: 500,
|
|
18
|
+
};
|
|
19
|
+
let state = {
|
|
20
|
+
storeCount: 0,
|
|
21
|
+
autoLearnCount: 0,
|
|
22
|
+
totalCalls: 0,
|
|
23
|
+
sessionStart: Date.now(),
|
|
24
|
+
};
|
|
25
|
+
function checkRateLimit(operation) {
|
|
26
|
+
state.totalCalls++;
|
|
27
|
+
if (state.totalCalls > LIMITS.MAX_CALLS_PER_SESSION) {
|
|
28
|
+
return { allowed: false, reason: `Session limit reached (${LIMITS.MAX_CALLS_PER_SESSION} total calls). Restart server to reset.` };
|
|
29
|
+
}
|
|
30
|
+
if (operation === 'store') {
|
|
31
|
+
state.storeCount++;
|
|
32
|
+
if (state.storeCount > LIMITS.MAX_STORES_PER_SESSION) {
|
|
33
|
+
return { allowed: false, reason: `Memory store limit reached (${LIMITS.MAX_STORES_PER_SESSION}/session). Prevents DB bloat.` };
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (operation === 'auto_learn') {
|
|
37
|
+
state.autoLearnCount++;
|
|
38
|
+
if (state.autoLearnCount > LIMITS.MAX_AUTO_LEARN_PER_SESSION) {
|
|
39
|
+
return { allowed: false, reason: `Auto-learn limit reached (${LIMITS.MAX_AUTO_LEARN_PER_SESSION}/session).` };
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return { allowed: true };
|
|
43
|
+
}
|
|
44
|
+
function getRateLimitStats() {
|
|
45
|
+
return {
|
|
46
|
+
storeCount: state.storeCount,
|
|
47
|
+
autoLearnCount: state.autoLearnCount,
|
|
48
|
+
totalCalls: state.totalCalls,
|
|
49
|
+
uptime: Math.floor((Date.now() - state.sessionStart) / 1000),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
function resetRateLimits() {
|
|
53
|
+
state = {
|
|
54
|
+
storeCount: 0,
|
|
55
|
+
autoLearnCount: 0,
|
|
56
|
+
totalCalls: 0,
|
|
57
|
+
sessionStart: Date.now(),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=rate-limiter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rate-limiter.js","sourceRoot":"","sources":["../../src/security/rate-limiter.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;AAsBH,wCAsBC;AAED,8CAOC;AAED,0CAOC;AArDD,MAAM,MAAM,GAAG;IACX,sBAAsB,EAAE,EAAE;IAC1B,0BAA0B,EAAE,GAAG;IAC/B,qBAAqB,EAAE,GAAG;CAC7B,CAAC;AAEF,IAAI,KAAK,GAAmB;IACxB,UAAU,EAAE,CAAC;IACb,cAAc,EAAE,CAAC;IACjB,UAAU,EAAE,CAAC;IACb,YAAY,EAAE,IAAI,CAAC,GAAG,EAAE;CAC3B,CAAC;AAEF,SAAgB,cAAc,CAAC,SAA0C;IACrE,KAAK,CAAC,UAAU,EAAE,CAAC;IAEnB,IAAI,KAAK,CAAC,UAAU,GAAG,MAAM,CAAC,qBAAqB,EAAE,CAAC;QAClD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,0BAA0B,MAAM,CAAC,qBAAqB,yCAAyC,EAAE,CAAC;IACvI,CAAC;IAED,IAAI,SAAS,KAAK,OAAO,EAAE,CAAC;QACxB,KAAK,CAAC,UAAU,EAAE,CAAC;QACnB,IAAI,KAAK,CAAC,UAAU,GAAG,MAAM,CAAC,sBAAsB,EAAE,CAAC;YACnD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,+BAA+B,MAAM,CAAC,sBAAsB,+BAA+B,EAAE,CAAC;QACnI,CAAC;IACL,CAAC;IAED,IAAI,SAAS,KAAK,YAAY,EAAE,CAAC;QAC7B,KAAK,CAAC,cAAc,EAAE,CAAC;QACvB,IAAI,KAAK,CAAC,cAAc,GAAG,MAAM,CAAC,0BAA0B,EAAE,CAAC;YAC3D,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,6BAA6B,MAAM,CAAC,0BAA0B,YAAY,EAAE,CAAC;QAClH,CAAC;IACL,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAC7B,CAAC;AAED,SAAgB,iBAAiB;IAC7B,OAAO;QACH,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,cAAc,EAAE,KAAK,CAAC,cAAc;QACpC,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC;KAC/D,CAAC;AACN,CAAC;AAED,SAAgB,eAAe;IAC3B,KAAK,GAAG;QACJ,UAAU,EAAE,CAAC;QACb,cAAc,EAAE,CAAC;QACjB,UAAU,EAAE,CAAC;QACb,YAAY,EAAE,IAAI,CAAC,GAAG,EAAE;KAC3B,CAAC;AACN,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../../src/server/dashboard.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAKjD,wBAAgB,cAAc,CAAC,WAAW,EAAE,WAAW,GAAG,IAAI,CA2B7D"}
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.startDashboard = startDashboard;
|
|
37
|
+
/**
|
|
38
|
+
* Cortex Web Dashboard โ Simple localhost HTTP server for viewing memories.
|
|
39
|
+
*
|
|
40
|
+
* Starts on port 3456 (or CORTEX_PORT env var).
|
|
41
|
+
* Access at: http://localhost:3456
|
|
42
|
+
*
|
|
43
|
+
* Features:
|
|
44
|
+
* - View all active memories grouped by type
|
|
45
|
+
* - Search memories
|
|
46
|
+
* - Health check status
|
|
47
|
+
* - Export JSON download
|
|
48
|
+
*/
|
|
49
|
+
const http = __importStar(require("http"));
|
|
50
|
+
const rate_limiter_1 = require("../security/rate-limiter");
|
|
51
|
+
const PORT = parseInt(process.env.CORTEX_PORT || '3456', 10);
|
|
52
|
+
function startDashboard(memoryStore) {
|
|
53
|
+
const server = http.createServer((req, res) => {
|
|
54
|
+
const url = new URL(req.url || '/', `http://localhost:${PORT}`);
|
|
55
|
+
// CORS โ wildcard is safe here since dashboard runs on localhost only
|
|
56
|
+
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
57
|
+
if (url.pathname === '/api/memories') {
|
|
58
|
+
return apiMemories(res, memoryStore, url);
|
|
59
|
+
}
|
|
60
|
+
else if (url.pathname === '/api/health') {
|
|
61
|
+
return apiHealth(res, memoryStore);
|
|
62
|
+
}
|
|
63
|
+
else if (url.pathname === '/api/export') {
|
|
64
|
+
return apiExport(res, memoryStore);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
return serveDashboard(res, memoryStore);
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
server.listen(PORT, '127.0.0.1', () => {
|
|
71
|
+
console.log(`[cortex-mcp] Dashboard: http://localhost:${PORT}`);
|
|
72
|
+
});
|
|
73
|
+
server.on('error', (err) => {
|
|
74
|
+
if (err.code === 'EADDRINUSE') {
|
|
75
|
+
console.log(`[cortex-mcp] Dashboard port ${PORT} in use, skipping.`);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
function apiMemories(res, store, url) {
|
|
80
|
+
const type = url.searchParams.get('type');
|
|
81
|
+
const query = url.searchParams.get('q');
|
|
82
|
+
let memories = store.getActive(200);
|
|
83
|
+
if (type && type !== 'ALL') {
|
|
84
|
+
memories = memories.filter(m => m.type === type);
|
|
85
|
+
}
|
|
86
|
+
if (query) {
|
|
87
|
+
const q = query.toLowerCase();
|
|
88
|
+
memories = memories.filter(m => m.intent.toLowerCase().includes(q));
|
|
89
|
+
}
|
|
90
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
91
|
+
res.end(JSON.stringify(memories.map(m => ({
|
|
92
|
+
id: m.id,
|
|
93
|
+
type: m.type,
|
|
94
|
+
intent: m.intent,
|
|
95
|
+
reason: m.reason,
|
|
96
|
+
tags: m.tags,
|
|
97
|
+
confidence: m.confidence,
|
|
98
|
+
importance: m.importance,
|
|
99
|
+
accessCount: m.accessCount,
|
|
100
|
+
createdAt: m.createdAt,
|
|
101
|
+
age: Math.floor((Date.now() - m.createdAt) / (24 * 60 * 60 * 1000)) + 'd',
|
|
102
|
+
}))));
|
|
103
|
+
}
|
|
104
|
+
function apiHealth(res, store) {
|
|
105
|
+
const stats = (0, rate_limiter_1.getRateLimitStats)();
|
|
106
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
107
|
+
res.end(JSON.stringify({
|
|
108
|
+
status: 'healthy',
|
|
109
|
+
activeMemories: store.activeCount(),
|
|
110
|
+
...stats,
|
|
111
|
+
}));
|
|
112
|
+
}
|
|
113
|
+
function apiExport(res, store) {
|
|
114
|
+
const memories = store.getActive(5000);
|
|
115
|
+
const bundle = {
|
|
116
|
+
version: 1,
|
|
117
|
+
exportedAt: new Date().toISOString(),
|
|
118
|
+
memoryCount: memories.length,
|
|
119
|
+
memories: memories.map(m => ({
|
|
120
|
+
id: m.id, type: m.type, intent: m.intent, action: m.action,
|
|
121
|
+
reason: m.reason, tags: m.tags, confidence: m.confidence,
|
|
122
|
+
importance: m.importance, createdAt: m.createdAt,
|
|
123
|
+
})),
|
|
124
|
+
};
|
|
125
|
+
res.writeHead(200, {
|
|
126
|
+
'Content-Type': 'application/json',
|
|
127
|
+
'Content-Disposition': 'attachment; filename="cortex-memories.json"',
|
|
128
|
+
});
|
|
129
|
+
res.end(JSON.stringify(bundle, null, 2));
|
|
130
|
+
}
|
|
131
|
+
function serveDashboard(res, store) {
|
|
132
|
+
const memories = store.getActive(200);
|
|
133
|
+
const types = ['CORRECTION', 'DECISION', 'CONVENTION', 'BUG_FIX', 'INSIGHT'];
|
|
134
|
+
const emoji = {
|
|
135
|
+
CORRECTION: '๐ด', DECISION: '๐ต', CONVENTION: '๐ข',
|
|
136
|
+
BUG_FIX: '๐ ', INSIGHT: '๐ฃ',
|
|
137
|
+
};
|
|
138
|
+
const grouped = types.map(type => {
|
|
139
|
+
const items = memories.filter(m => m.type === type);
|
|
140
|
+
return { type, emoji: emoji[type] || 'โช', items };
|
|
141
|
+
}).filter(g => g.items.length > 0);
|
|
142
|
+
const stats = (0, rate_limiter_1.getRateLimitStats)();
|
|
143
|
+
const html = `<!DOCTYPE html>
|
|
144
|
+
<html lang="en">
|
|
145
|
+
<head>
|
|
146
|
+
<meta charset="UTF-8">
|
|
147
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
148
|
+
<title>๐ง Cortex Memory Dashboard</title>
|
|
149
|
+
<style>
|
|
150
|
+
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
151
|
+
body {
|
|
152
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
153
|
+
background: #0a0a0f; color: #e0e0e0; min-height: 100vh;
|
|
154
|
+
}
|
|
155
|
+
.header {
|
|
156
|
+
background: linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f3460 100%);
|
|
157
|
+
padding: 2rem; border-bottom: 1px solid #2a2a4a;
|
|
158
|
+
}
|
|
159
|
+
.header h1 { font-size: 1.8rem; color: #fff; }
|
|
160
|
+
.header .stats { display: flex; gap: 2rem; margin-top: 1rem; flex-wrap: wrap; }
|
|
161
|
+
.stat { background: rgba(255,255,255,0.05); padding: 0.8rem 1.2rem; border-radius: 8px; }
|
|
162
|
+
.stat-value { font-size: 1.5rem; font-weight: bold; color: #60a5fa; }
|
|
163
|
+
.stat-label { font-size: 0.75rem; color: #888; text-transform: uppercase; }
|
|
164
|
+
.container { max-width: 1200px; margin: 0 auto; padding: 2rem; }
|
|
165
|
+
.search {
|
|
166
|
+
width: 100%; padding: 0.8rem 1.2rem; background: #1a1a2e;
|
|
167
|
+
border: 1px solid #2a2a4a; border-radius: 8px; color: #fff;
|
|
168
|
+
font-size: 1rem; margin-bottom: 2rem; outline: none;
|
|
169
|
+
}
|
|
170
|
+
.search:focus { border-color: #60a5fa; }
|
|
171
|
+
.type-section { margin-bottom: 2rem; }
|
|
172
|
+
.type-header {
|
|
173
|
+
font-size: 1.2rem; margin-bottom: 0.8rem; padding-bottom: 0.5rem;
|
|
174
|
+
border-bottom: 1px solid #2a2a4a;
|
|
175
|
+
}
|
|
176
|
+
.memory-card {
|
|
177
|
+
background: #12121a; border: 1px solid #2a2a4a; border-radius: 8px;
|
|
178
|
+
padding: 1rem; margin-bottom: 0.5rem; transition: border-color 0.2s;
|
|
179
|
+
}
|
|
180
|
+
.memory-card:hover { border-color: #60a5fa; }
|
|
181
|
+
.memory-intent { font-weight: 500; color: #fff; }
|
|
182
|
+
.memory-meta { font-size: 0.75rem; color: #666; margin-top: 0.4rem; }
|
|
183
|
+
.memory-id { font-family: monospace; color: #4a4a6a; }
|
|
184
|
+
.memory-reason { font-style: italic; color: #888; font-size: 0.85rem; margin-top: 0.3rem; }
|
|
185
|
+
.actions { margin-top: 1rem; display: flex; gap: 0.5rem; }
|
|
186
|
+
.btn {
|
|
187
|
+
padding: 0.5rem 1rem; background: #1a1a2e; border: 1px solid #2a2a4a;
|
|
188
|
+
border-radius: 6px; color: #60a5fa; cursor: pointer; font-size: 0.85rem;
|
|
189
|
+
text-decoration: none; transition: all 0.2s;
|
|
190
|
+
}
|
|
191
|
+
.btn:hover { background: #60a5fa; color: #000; }
|
|
192
|
+
.empty { text-align: center; padding: 4rem; color: #4a4a6a; }
|
|
193
|
+
</style>
|
|
194
|
+
</head>
|
|
195
|
+
<body>
|
|
196
|
+
<div class="header">
|
|
197
|
+
<h1>๐ง Cortex Memory Dashboard</h1>
|
|
198
|
+
<div class="stats">
|
|
199
|
+
<div class="stat">
|
|
200
|
+
<div class="stat-value">${memories.length}</div>
|
|
201
|
+
<div class="stat-label">Active Memories</div>
|
|
202
|
+
</div>
|
|
203
|
+
<div class="stat">
|
|
204
|
+
<div class="stat-value">${stats.storeCount}/30</div>
|
|
205
|
+
<div class="stat-label">Session Stores</div>
|
|
206
|
+
</div>
|
|
207
|
+
<div class="stat">
|
|
208
|
+
<div class="stat-value">${Math.floor(stats.uptime / 60)}m</div>
|
|
209
|
+
<div class="stat-label">Uptime</div>
|
|
210
|
+
</div>
|
|
211
|
+
<div class="stat">
|
|
212
|
+
<div class="stat-value">โ
</div>
|
|
213
|
+
<div class="stat-label">Status</div>
|
|
214
|
+
</div>
|
|
215
|
+
</div>
|
|
216
|
+
</div>
|
|
217
|
+
<div class="container">
|
|
218
|
+
<input class="search" type="text" placeholder="๐ Search memories..." oninput="filterMemories(this.value)">
|
|
219
|
+
<div class="actions">
|
|
220
|
+
<a class="btn" href="/api/export" download>๐ฆ Export JSON</a>
|
|
221
|
+
<a class="btn" href="/api/health">๐ฅ Health API</a>
|
|
222
|
+
</div>
|
|
223
|
+
<br>
|
|
224
|
+
${grouped.length === 0 ? '<div class="empty"><h2>No memories yet</h2><p>Start using Cortex and memories will appear here.</p></div>' : ''}
|
|
225
|
+
${grouped.map(g => `
|
|
226
|
+
<div class="type-section" data-type="${g.type}">
|
|
227
|
+
<div class="type-header">${g.emoji} ${g.type} (${g.items.length})</div>
|
|
228
|
+
${g.items.map(m => {
|
|
229
|
+
const age = Math.floor((Date.now() - m.createdAt) / (24 * 60 * 60 * 1000));
|
|
230
|
+
const accessed = m.accessCount > 0 ? ` ยท accessed ${m.accessCount}x` : '';
|
|
231
|
+
return `
|
|
232
|
+
<div class="memory-card" data-search="${m.intent.toLowerCase()}">
|
|
233
|
+
<div class="memory-intent">${m.intent}</div>
|
|
234
|
+
${m.reason ? `<div class="memory-reason">${m.reason}</div>` : ''}
|
|
235
|
+
<div class="memory-meta">
|
|
236
|
+
<span class="memory-id">${m.id}</span> ยท ${age}d old${accessed}
|
|
237
|
+
ยท confidence: ${(m.confidence * 100).toFixed(0)}%
|
|
238
|
+
</div>
|
|
239
|
+
</div>`;
|
|
240
|
+
}).join('')}
|
|
241
|
+
</div>
|
|
242
|
+
`).join('')}
|
|
243
|
+
</div>
|
|
244
|
+
<script>
|
|
245
|
+
function filterMemories(q) {
|
|
246
|
+
const cards = document.querySelectorAll('.memory-card');
|
|
247
|
+
const ql = q.toLowerCase();
|
|
248
|
+
cards.forEach(c => {
|
|
249
|
+
c.style.display = c.dataset.search.includes(ql) ? '' : 'none';
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
</script>
|
|
253
|
+
</body>
|
|
254
|
+
</html>`;
|
|
255
|
+
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
256
|
+
res.end(html);
|
|
257
|
+
}
|
|
258
|
+
//# sourceMappingURL=dashboard.js.map
|