context-mem 0.1.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/.context-mem.json.example +22 -0
- package/LICENSE +21 -0
- package/README.md +213 -0
- package/dist/cli/commands/dashboard.d.ts +2 -0
- package/dist/cli/commands/dashboard.d.ts.map +1 -0
- package/dist/cli/commands/dashboard.js +55 -0
- package/dist/cli/commands/dashboard.js.map +1 -0
- package/dist/cli/commands/doctor.d.ts +2 -0
- package/dist/cli/commands/doctor.d.ts.map +1 -0
- package/dist/cli/commands/doctor.js +49 -0
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/init.d.ts +2 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +43 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/serve.d.ts +2 -0
- package/dist/cli/commands/serve.d.ts.map +1 -0
- package/dist/cli/commands/serve.js +47 -0
- package/dist/cli/commands/serve.js.map +1 -0
- package/dist/cli/commands/status.d.ts +2 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +29 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +39 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/core/budget.d.ts +11 -0
- package/dist/core/budget.d.ts.map +1 -0
- package/dist/core/budget.js +60 -0
- package/dist/core/budget.js.map +1 -0
- package/dist/core/config.d.ts +4 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +41 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/events.d.ts +19 -0
- package/dist/core/events.d.ts.map +1 -0
- package/dist/core/events.js +101 -0
- package/dist/core/events.js.map +1 -0
- package/dist/core/kernel.d.ts +46 -0
- package/dist/core/kernel.d.ts.map +1 -0
- package/dist/core/kernel.js +228 -0
- package/dist/core/kernel.js.map +1 -0
- package/dist/core/lifecycle.d.ts +19 -0
- package/dist/core/lifecycle.d.ts.map +1 -0
- package/dist/core/lifecycle.js +35 -0
- package/dist/core/lifecycle.js.map +1 -0
- package/dist/core/observe-queue.d.ts +18 -0
- package/dist/core/observe-queue.d.ts.map +1 -0
- package/dist/core/observe-queue.js +56 -0
- package/dist/core/observe-queue.js.map +1 -0
- package/dist/core/pipeline.d.ts +15 -0
- package/dist/core/pipeline.d.ts.map +1 -0
- package/dist/core/pipeline.js +114 -0
- package/dist/core/pipeline.js.map +1 -0
- package/dist/core/plugin-registry.d.ts +13 -0
- package/dist/core/plugin-registry.d.ts.map +1 -0
- package/dist/core/plugin-registry.js +67 -0
- package/dist/core/plugin-registry.js.map +1 -0
- package/dist/core/session.d.ts +14 -0
- package/dist/core/session.d.ts.map +1 -0
- package/dist/core/session.js +95 -0
- package/dist/core/session.js.map +1 -0
- package/dist/core/truncation.d.ts +11 -0
- package/dist/core/truncation.d.ts.map +1 -0
- package/dist/core/truncation.js +143 -0
- package/dist/core/truncation.js.map +1 -0
- package/dist/core/types.d.ts +230 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +50 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/utils.d.ts +4 -0
- package/dist/core/utils.d.ts.map +1 -0
- package/dist/core/utils.js +57 -0
- package/dist/core/utils.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +27 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-server/server.d.ts +5 -0
- package/dist/mcp-server/server.d.ts.map +1 -0
- package/dist/mcp-server/server.js +101 -0
- package/dist/mcp-server/server.js.map +1 -0
- package/dist/mcp-server/tools.d.ts +201 -0
- package/dist/mcp-server/tools.d.ts.map +1 -0
- package/dist/mcp-server/tools.js +618 -0
- package/dist/mcp-server/tools.js.map +1 -0
- package/dist/plugins/knowledge/knowledge-base.d.ts +23 -0
- package/dist/plugins/knowledge/knowledge-base.d.ts.map +1 -0
- package/dist/plugins/knowledge/knowledge-base.js +165 -0
- package/dist/plugins/knowledge/knowledge-base.js.map +1 -0
- package/dist/plugins/platforms/claude-code.d.ts +14 -0
- package/dist/plugins/platforms/claude-code.d.ts.map +1 -0
- package/dist/plugins/platforms/claude-code.js +52 -0
- package/dist/plugins/platforms/claude-code.js.map +1 -0
- package/dist/plugins/privacy/privacy-engine.d.ts +18 -0
- package/dist/plugins/privacy/privacy-engine.d.ts.map +1 -0
- package/dist/plugins/privacy/privacy-engine.js +72 -0
- package/dist/plugins/privacy/privacy-engine.js.map +1 -0
- package/dist/plugins/runtimes/javascript.d.ts +13 -0
- package/dist/plugins/runtimes/javascript.d.ts.map +1 -0
- package/dist/plugins/runtimes/javascript.js +102 -0
- package/dist/plugins/runtimes/javascript.js.map +1 -0
- package/dist/plugins/runtimes/python.d.ts +14 -0
- package/dist/plugins/runtimes/python.d.ts.map +1 -0
- package/dist/plugins/runtimes/python.js +127 -0
- package/dist/plugins/runtimes/python.js.map +1 -0
- package/dist/plugins/runtimes/shell.d.ts +13 -0
- package/dist/plugins/runtimes/shell.d.ts.map +1 -0
- package/dist/plugins/runtimes/shell.js +55 -0
- package/dist/plugins/runtimes/shell.js.map +1 -0
- package/dist/plugins/search/bm25.d.ts +16 -0
- package/dist/plugins/search/bm25.d.ts.map +1 -0
- package/dist/plugins/search/bm25.js +61 -0
- package/dist/plugins/search/bm25.js.map +1 -0
- package/dist/plugins/search/fts5-utils.d.ts +2 -0
- package/dist/plugins/search/fts5-utils.d.ts.map +1 -0
- package/dist/plugins/search/fts5-utils.js +12 -0
- package/dist/plugins/search/fts5-utils.js.map +1 -0
- package/dist/plugins/search/fusion.d.ts +9 -0
- package/dist/plugins/search/fusion.d.ts.map +1 -0
- package/dist/plugins/search/fusion.js +45 -0
- package/dist/plugins/search/fusion.js.map +1 -0
- package/dist/plugins/search/intent.d.ts +5 -0
- package/dist/plugins/search/intent.d.ts.map +1 -0
- package/dist/plugins/search/intent.js +49 -0
- package/dist/plugins/search/intent.js.map +1 -0
- package/dist/plugins/search/levenshtein.d.ts +17 -0
- package/dist/plugins/search/levenshtein.d.ts.map +1 -0
- package/dist/plugins/search/levenshtein.js +99 -0
- package/dist/plugins/search/levenshtein.js.map +1 -0
- package/dist/plugins/search/trigram.d.ts +16 -0
- package/dist/plugins/search/trigram.d.ts.map +1 -0
- package/dist/plugins/search/trigram.js +63 -0
- package/dist/plugins/search/trigram.js.map +1 -0
- package/dist/plugins/storage/better-sqlite3.d.ts +19 -0
- package/dist/plugins/storage/better-sqlite3.d.ts.map +1 -0
- package/dist/plugins/storage/better-sqlite3.js +82 -0
- package/dist/plugins/storage/better-sqlite3.js.map +1 -0
- package/dist/plugins/storage/content-store.d.ts +20 -0
- package/dist/plugins/storage/content-store.d.ts.map +1 -0
- package/dist/plugins/storage/content-store.js +187 -0
- package/dist/plugins/storage/content-store.js.map +1 -0
- package/dist/plugins/storage/migrations.d.ts +8 -0
- package/dist/plugins/storage/migrations.d.ts.map +1 -0
- package/dist/plugins/storage/migrations.js +252 -0
- package/dist/plugins/storage/migrations.js.map +1 -0
- package/dist/plugins/summarizers/binary-summarizer.d.ts +12 -0
- package/dist/plugins/summarizers/binary-summarizer.d.ts.map +1 -0
- package/dist/plugins/summarizers/binary-summarizer.js +43 -0
- package/dist/plugins/summarizers/binary-summarizer.js.map +1 -0
- package/dist/plugins/summarizers/build-output-summarizer.d.ts +12 -0
- package/dist/plugins/summarizers/build-output-summarizer.d.ts.map +1 -0
- package/dist/plugins/summarizers/build-output-summarizer.js +68 -0
- package/dist/plugins/summarizers/build-output-summarizer.js.map +1 -0
- package/dist/plugins/summarizers/code-summarizer.d.ts +12 -0
- package/dist/plugins/summarizers/code-summarizer.d.ts.map +1 -0
- package/dist/plugins/summarizers/code-summarizer.js +179 -0
- package/dist/plugins/summarizers/code-summarizer.js.map +1 -0
- package/dist/plugins/summarizers/csv-summarizer.d.ts +12 -0
- package/dist/plugins/summarizers/csv-summarizer.d.ts.map +1 -0
- package/dist/plugins/summarizers/csv-summarizer.js +60 -0
- package/dist/plugins/summarizers/csv-summarizer.js.map +1 -0
- package/dist/plugins/summarizers/error-summarizer.d.ts +15 -0
- package/dist/plugins/summarizers/error-summarizer.d.ts.map +1 -0
- package/dist/plugins/summarizers/error-summarizer.js +111 -0
- package/dist/plugins/summarizers/error-summarizer.js.map +1 -0
- package/dist/plugins/summarizers/git-log-summarizer.d.ts +12 -0
- package/dist/plugins/summarizers/git-log-summarizer.d.ts.map +1 -0
- package/dist/plugins/summarizers/git-log-summarizer.js +76 -0
- package/dist/plugins/summarizers/git-log-summarizer.js.map +1 -0
- package/dist/plugins/summarizers/html-summarizer.d.ts +12 -0
- package/dist/plugins/summarizers/html-summarizer.d.ts.map +1 -0
- package/dist/plugins/summarizers/html-summarizer.js +69 -0
- package/dist/plugins/summarizers/html-summarizer.js.map +1 -0
- package/dist/plugins/summarizers/json-summarizer.d.ts +12 -0
- package/dist/plugins/summarizers/json-summarizer.d.ts.map +1 -0
- package/dist/plugins/summarizers/json-summarizer.js +132 -0
- package/dist/plugins/summarizers/json-summarizer.js.map +1 -0
- package/dist/plugins/summarizers/log-summarizer.d.ts +12 -0
- package/dist/plugins/summarizers/log-summarizer.d.ts.map +1 -0
- package/dist/plugins/summarizers/log-summarizer.js +173 -0
- package/dist/plugins/summarizers/log-summarizer.js.map +1 -0
- package/dist/plugins/summarizers/markdown-summarizer.d.ts +12 -0
- package/dist/plugins/summarizers/markdown-summarizer.d.ts.map +1 -0
- package/dist/plugins/summarizers/markdown-summarizer.js +75 -0
- package/dist/plugins/summarizers/markdown-summarizer.js.map +1 -0
- package/dist/plugins/summarizers/network-summarizer.d.ts +12 -0
- package/dist/plugins/summarizers/network-summarizer.d.ts.map +1 -0
- package/dist/plugins/summarizers/network-summarizer.js +74 -0
- package/dist/plugins/summarizers/network-summarizer.js.map +1 -0
- package/dist/plugins/summarizers/shell-summarizer.d.ts +12 -0
- package/dist/plugins/summarizers/shell-summarizer.d.ts.map +1 -0
- package/dist/plugins/summarizers/shell-summarizer.js +50 -0
- package/dist/plugins/summarizers/shell-summarizer.js.map +1 -0
- package/dist/plugins/summarizers/test-output-summarizer.d.ts +12 -0
- package/dist/plugins/summarizers/test-output-summarizer.d.ts.map +1 -0
- package/dist/plugins/summarizers/test-output-summarizer.js +77 -0
- package/dist/plugins/summarizers/test-output-summarizer.js.map +1 -0
- package/dist/plugins/summarizers/typescript-error-summarizer.d.ts +12 -0
- package/dist/plugins/summarizers/typescript-error-summarizer.d.ts.map +1 -0
- package/dist/plugins/summarizers/typescript-error-summarizer.js +67 -0
- package/dist/plugins/summarizers/typescript-error-summarizer.js.map +1 -0
- package/hooks/context-mem-hook.js +77 -0
- package/hooks/dashboard-autostart.js +92 -0
- package/hooks/dashboard-stop.js +32 -0
- package/hooks/hooks.json +40 -0
- package/package.json +32 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { SummarizerPlugin, PluginConfig, SummaryResult, SummarizeOpts } from '../../core/types.js';
|
|
2
|
+
export declare class ShellSummarizer implements SummarizerPlugin {
|
|
3
|
+
name: string;
|
|
4
|
+
version: string;
|
|
5
|
+
type: "summarizer";
|
|
6
|
+
contentTypes: string[];
|
|
7
|
+
init(_config: PluginConfig): Promise<void>;
|
|
8
|
+
destroy(): Promise<void>;
|
|
9
|
+
detect(content: string): boolean;
|
|
10
|
+
summarize(content: string, _opts: SummarizeOpts): Promise<SummaryResult>;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=shell-summarizer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shell-summarizer.d.ts","sourceRoot":"","sources":["../../../src/plugins/summarizers/shell-summarizer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAMxG,qBAAa,eAAgB,YAAW,gBAAgB;IACtD,IAAI,SAAsB;IAC1B,OAAO,SAAW;IAClB,IAAI,EAAG,YAAY,CAAU;IAC7B,YAAY,WAA+B;IAErC,IAAI,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAC1C,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAE9B,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAK1B,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;CAmC/E"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ShellSummarizer = void 0;
|
|
4
|
+
const utils_js_1 = require("../../core/utils.js");
|
|
5
|
+
const KEEP_LINES = 10;
|
|
6
|
+
const MIN_LINES_TO_SUMMARIZE = 20;
|
|
7
|
+
class ShellSummarizer {
|
|
8
|
+
name = 'shell-summarizer';
|
|
9
|
+
version = '1.0.0';
|
|
10
|
+
type = 'summarizer';
|
|
11
|
+
contentTypes = ['shell', 'command-output'];
|
|
12
|
+
async init(_config) { }
|
|
13
|
+
async destroy() { }
|
|
14
|
+
detect(content) {
|
|
15
|
+
const lineCount = content.split('\n').length;
|
|
16
|
+
return lineCount >= MIN_LINES_TO_SUMMARIZE;
|
|
17
|
+
}
|
|
18
|
+
async summarize(content, _opts) {
|
|
19
|
+
const lines = content.split('\n');
|
|
20
|
+
const tokensOriginal = (0, utils_js_1.estimateTokens)(content);
|
|
21
|
+
if (lines.length < MIN_LINES_TO_SUMMARIZE) {
|
|
22
|
+
return {
|
|
23
|
+
summary: content,
|
|
24
|
+
tokens_original: tokensOriginal,
|
|
25
|
+
tokens_summarized: tokensOriginal,
|
|
26
|
+
savings_pct: 0,
|
|
27
|
+
content_type: 'shell',
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
const head = lines.slice(0, KEEP_LINES);
|
|
31
|
+
const tail = lines.slice(-KEEP_LINES);
|
|
32
|
+
const omitted = lines.length - KEEP_LINES * 2;
|
|
33
|
+
const summary = [
|
|
34
|
+
`[${lines.length} lines total]`,
|
|
35
|
+
...head,
|
|
36
|
+
`... (${omitted} lines omitted) ...`,
|
|
37
|
+
...tail,
|
|
38
|
+
].join('\n');
|
|
39
|
+
const tokensSummarized = (0, utils_js_1.estimateTokens)(summary);
|
|
40
|
+
return {
|
|
41
|
+
summary,
|
|
42
|
+
tokens_original: tokensOriginal,
|
|
43
|
+
tokens_summarized: tokensSummarized,
|
|
44
|
+
savings_pct: tokensOriginal > 0 ? Math.round((1 - tokensSummarized / tokensOriginal) * 100) : 0,
|
|
45
|
+
content_type: 'shell',
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
exports.ShellSummarizer = ShellSummarizer;
|
|
50
|
+
//# sourceMappingURL=shell-summarizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shell-summarizer.js","sourceRoot":"","sources":["../../../src/plugins/summarizers/shell-summarizer.ts"],"names":[],"mappings":";;;AACA,kDAAqD;AAErD,MAAM,UAAU,GAAG,EAAE,CAAC;AACtB,MAAM,sBAAsB,GAAG,EAAE,CAAC;AAElC,MAAa,eAAe;IAC1B,IAAI,GAAG,kBAAkB,CAAC;IAC1B,OAAO,GAAG,OAAO,CAAC;IAClB,IAAI,GAAG,YAAqB,CAAC;IAC7B,YAAY,GAAG,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC;IAE3C,KAAK,CAAC,IAAI,CAAC,OAAqB,IAAkB,CAAC;IACnD,KAAK,CAAC,OAAO,KAAmB,CAAC;IAEjC,MAAM,CAAC,OAAe;QACpB,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;QAC7C,OAAO,SAAS,IAAI,sBAAsB,CAAC;IAC7C,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,OAAe,EAAE,KAAoB;QACnD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAClC,MAAM,cAAc,GAAG,IAAA,yBAAc,EAAC,OAAO,CAAC,CAAC;QAE/C,IAAI,KAAK,CAAC,MAAM,GAAG,sBAAsB,EAAE,CAAC;YAC1C,OAAO;gBACL,OAAO,EAAE,OAAO;gBAChB,eAAe,EAAE,cAAc;gBAC/B,iBAAiB,EAAE,cAAc;gBACjC,WAAW,EAAE,CAAC;gBACd,YAAY,EAAE,OAAO;aACtB,CAAC;QACJ,CAAC;QAED,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;QACxC,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC,CAAC;QACtC,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,GAAG,UAAU,GAAG,CAAC,CAAC;QAE9C,MAAM,OAAO,GAAG;YACd,IAAI,KAAK,CAAC,MAAM,eAAe;YAC/B,GAAG,IAAI;YACP,QAAQ,OAAO,qBAAqB;YACpC,GAAG,IAAI;SACR,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEb,MAAM,gBAAgB,GAAG,IAAA,yBAAc,EAAC,OAAO,CAAC,CAAC;QAEjD,OAAO;YACL,OAAO;YACP,eAAe,EAAE,cAAc;YAC/B,iBAAiB,EAAE,gBAAgB;YACnC,WAAW,EAAE,cAAc,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,gBAAgB,GAAG,cAAc,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YAC/F,YAAY,EAAE,OAAO;SACtB,CAAC;IACJ,CAAC;CACF;AAjDD,0CAiDC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { SummarizerPlugin, PluginConfig, SummaryResult, SummarizeOpts } from '../../core/types.js';
|
|
2
|
+
export declare class TestOutputSummarizer implements SummarizerPlugin {
|
|
3
|
+
name: string;
|
|
4
|
+
version: string;
|
|
5
|
+
type: "summarizer";
|
|
6
|
+
contentTypes: string[];
|
|
7
|
+
init(_config: PluginConfig): Promise<void>;
|
|
8
|
+
destroy(): Promise<void>;
|
|
9
|
+
detect(content: string): boolean;
|
|
10
|
+
summarize(content: string, _opts: SummarizeOpts): Promise<SummaryResult>;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=test-output-summarizer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-output-summarizer.d.ts","sourceRoot":"","sources":["../../../src/plugins/summarizers/test-output-summarizer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAaxG,qBAAa,oBAAqB,YAAW,gBAAgB;IAC3D,IAAI,SAA4B;IAChC,OAAO,SAAW;IAClB,IAAI,EAAG,YAAY,CAAU;IAC7B,YAAY,WAAmB;IAEzB,IAAI,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAC1C,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAE9B,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAI1B,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;CA0D/E"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TestOutputSummarizer = void 0;
|
|
4
|
+
const utils_js_1 = require("../../core/utils.js");
|
|
5
|
+
const TEST_DETECT_PATTERN = /Tests:.*total|PASS\s|FAIL\s|test suites/i;
|
|
6
|
+
const TESTS_LINE_REGEX = /^Tests:\s*(.+)$/m;
|
|
7
|
+
const PASS_COUNT_REGEX = /(\d+)\s+passed/i;
|
|
8
|
+
const FAIL_COUNT_REGEX = /(\d+)\s+failed/i;
|
|
9
|
+
const SKIP_COUNT_REGEX = /(\d+)\s+(?:skipped|pending|todo)/i;
|
|
10
|
+
const TOTAL_COUNT_REGEX = /(\d+)\s+total/i;
|
|
11
|
+
const SUITE_COUNT_REGEX = /Test Suites:\s*.*?(\d+)\s+total/i;
|
|
12
|
+
const DURATION_REGEX = /Time:\s*([\d.]+\s*(?:ms|s|m))/i;
|
|
13
|
+
const FAILED_TEST_REGEX = /(?:FAIL|✕|✗|×)\s+(.+)/g;
|
|
14
|
+
class TestOutputSummarizer {
|
|
15
|
+
name = 'test-output-summarizer';
|
|
16
|
+
version = '1.0.0';
|
|
17
|
+
type = 'summarizer';
|
|
18
|
+
contentTypes = ['test-output'];
|
|
19
|
+
async init(_config) { }
|
|
20
|
+
async destroy() { }
|
|
21
|
+
detect(content) {
|
|
22
|
+
return TEST_DETECT_PATTERN.test(content);
|
|
23
|
+
}
|
|
24
|
+
async summarize(content, _opts) {
|
|
25
|
+
const tokensOriginal = (0, utils_js_1.estimateTokens)(content);
|
|
26
|
+
// Extract the "Tests:" line specifically to avoid matching "Test Suites:" counts
|
|
27
|
+
const testsLineMatch = content.match(TESTS_LINE_REGEX);
|
|
28
|
+
const testsLine = testsLineMatch ? testsLineMatch[1] : content;
|
|
29
|
+
const passMatch = testsLine.match(PASS_COUNT_REGEX);
|
|
30
|
+
const failMatch = testsLine.match(FAIL_COUNT_REGEX);
|
|
31
|
+
const skipMatch = testsLine.match(SKIP_COUNT_REGEX);
|
|
32
|
+
const totalMatch = testsLine.match(TOTAL_COUNT_REGEX);
|
|
33
|
+
const suiteMatch = content.match(SUITE_COUNT_REGEX);
|
|
34
|
+
const durationMatch = content.match(DURATION_REGEX);
|
|
35
|
+
const passed = passMatch ? parseInt(passMatch[1], 10) : 0;
|
|
36
|
+
const failed = failMatch ? parseInt(failMatch[1], 10) : 0;
|
|
37
|
+
const skipped = skipMatch ? parseInt(skipMatch[1], 10) : 0;
|
|
38
|
+
const total = totalMatch ? parseInt(totalMatch[1], 10) : passed + failed + skipped;
|
|
39
|
+
const suites = suiteMatch ? parseInt(suiteMatch[1], 10) : 0;
|
|
40
|
+
const duration = durationMatch ? durationMatch[1] : 'unknown';
|
|
41
|
+
// Extract failed test names (up to 10)
|
|
42
|
+
const failedTests = [];
|
|
43
|
+
let failedMatch;
|
|
44
|
+
const failedRegex = new RegExp(FAILED_TEST_REGEX.source, 'g');
|
|
45
|
+
while ((failedMatch = failedRegex.exec(content)) !== null && failedTests.length < 10) {
|
|
46
|
+
failedTests.push(failedMatch[1].trim());
|
|
47
|
+
}
|
|
48
|
+
const summaryParts = [
|
|
49
|
+
`# Test Results`,
|
|
50
|
+
'',
|
|
51
|
+
`## Counts`,
|
|
52
|
+
` Passed: ${passed}`,
|
|
53
|
+
` Failed: ${failed}`,
|
|
54
|
+
` Skipped: ${skipped}`,
|
|
55
|
+
` Total: ${total}`,
|
|
56
|
+
` Suites: ${suites}`,
|
|
57
|
+
` Duration: ${duration}`,
|
|
58
|
+
];
|
|
59
|
+
if (failedTests.length > 0) {
|
|
60
|
+
summaryParts.push('', `## Failed tests (${failedTests.length})`);
|
|
61
|
+
for (const t of failedTests) {
|
|
62
|
+
summaryParts.push(` - ${t}`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
const summary = summaryParts.join('\n');
|
|
66
|
+
const tokensSummarized = (0, utils_js_1.estimateTokens)(summary);
|
|
67
|
+
return {
|
|
68
|
+
summary,
|
|
69
|
+
tokens_original: tokensOriginal,
|
|
70
|
+
tokens_summarized: tokensSummarized,
|
|
71
|
+
savings_pct: tokensOriginal > 0 ? Math.round((1 - tokensSummarized / tokensOriginal) * 100) : 0,
|
|
72
|
+
content_type: 'test-output',
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
exports.TestOutputSummarizer = TestOutputSummarizer;
|
|
77
|
+
//# sourceMappingURL=test-output-summarizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-output-summarizer.js","sourceRoot":"","sources":["../../../src/plugins/summarizers/test-output-summarizer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { SummarizerPlugin, PluginConfig, SummaryResult, SummarizeOpts } from '../../core/types.js';
|
|
2
|
+
export declare class TypescriptErrorSummarizer implements SummarizerPlugin {
|
|
3
|
+
name: string;
|
|
4
|
+
version: string;
|
|
5
|
+
type: "summarizer";
|
|
6
|
+
contentTypes: string[];
|
|
7
|
+
init(_config: PluginConfig): Promise<void>;
|
|
8
|
+
destroy(): Promise<void>;
|
|
9
|
+
detect(content: string): boolean;
|
|
10
|
+
summarize(content: string, _opts: SummarizeOpts): Promise<SummaryResult>;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=typescript-error-summarizer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typescript-error-summarizer.d.ts","sourceRoot":"","sources":["../../../src/plugins/summarizers/typescript-error-summarizer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAMxG,qBAAa,yBAA0B,YAAW,gBAAgB;IAChE,IAAI,SAAiC;IACrC,OAAO,SAAW;IAClB,IAAI,EAAG,YAAY,CAAU;IAC7B,YAAY,WAAwB;IAE9B,IAAI,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAC1C,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAE9B,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAI1B,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;CAwD/E"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TypescriptErrorSummarizer = void 0;
|
|
4
|
+
const utils_js_1 = require("../../core/utils.js");
|
|
5
|
+
const TS_ERROR_PATTERN = /error TS\d+:/;
|
|
6
|
+
const TS_ERROR_LINE_REGEX = /^(.+?)\(\d+,\d+\):\s*error (TS\d+):\s*(.+)$/;
|
|
7
|
+
class TypescriptErrorSummarizer {
|
|
8
|
+
name = 'typescript-error-summarizer';
|
|
9
|
+
version = '1.0.0';
|
|
10
|
+
type = 'summarizer';
|
|
11
|
+
contentTypes = ['typescript-error'];
|
|
12
|
+
async init(_config) { }
|
|
13
|
+
async destroy() { }
|
|
14
|
+
detect(content) {
|
|
15
|
+
return TS_ERROR_PATTERN.test(content);
|
|
16
|
+
}
|
|
17
|
+
async summarize(content, _opts) {
|
|
18
|
+
const lines = content.split('\n');
|
|
19
|
+
const tokensOriginal = (0, utils_js_1.estimateTokens)(content);
|
|
20
|
+
const errorsPerFile = new Map();
|
|
21
|
+
const errorCodes = new Map();
|
|
22
|
+
const errorMessages = [];
|
|
23
|
+
for (const line of lines) {
|
|
24
|
+
const match = line.match(TS_ERROR_LINE_REGEX);
|
|
25
|
+
if (match) {
|
|
26
|
+
const [, file, code, message] = match;
|
|
27
|
+
errorsPerFile.set(file, (errorsPerFile.get(file) || 0) + 1);
|
|
28
|
+
errorCodes.set(code, (errorCodes.get(code) || 0) + 1);
|
|
29
|
+
if (errorMessages.length < 3) {
|
|
30
|
+
errorMessages.push(`${code}: ${message}`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const totalErrors = Array.from(errorsPerFile.values()).reduce((a, b) => a + b, 0);
|
|
35
|
+
// Sort error codes by count descending
|
|
36
|
+
const sortedCodes = Array.from(errorCodes.entries())
|
|
37
|
+
.sort((a, b) => b[1] - a[1])
|
|
38
|
+
.slice(0, 10);
|
|
39
|
+
// Sort files by error count descending
|
|
40
|
+
const sortedFiles = Array.from(errorsPerFile.entries())
|
|
41
|
+
.sort((a, b) => b[1] - a[1])
|
|
42
|
+
.slice(0, 10);
|
|
43
|
+
const summaryParts = [
|
|
44
|
+
`# TypeScript Errors: ${totalErrors} total`,
|
|
45
|
+
'',
|
|
46
|
+
`## Errors per file (top ${sortedFiles.length})`,
|
|
47
|
+
...sortedFiles.map(([file, count]) => ` ${file}: ${count}`),
|
|
48
|
+
'',
|
|
49
|
+
`## Error codes (top ${sortedCodes.length})`,
|
|
50
|
+
...sortedCodes.map(([code, count]) => ` ${code}: ${count} occurrences`),
|
|
51
|
+
'',
|
|
52
|
+
`## First errors`,
|
|
53
|
+
...errorMessages.map(m => ` - ${m}`),
|
|
54
|
+
];
|
|
55
|
+
const summary = summaryParts.join('\n');
|
|
56
|
+
const tokensSummarized = (0, utils_js_1.estimateTokens)(summary);
|
|
57
|
+
return {
|
|
58
|
+
summary,
|
|
59
|
+
tokens_original: tokensOriginal,
|
|
60
|
+
tokens_summarized: tokensSummarized,
|
|
61
|
+
savings_pct: tokensOriginal > 0 ? Math.round((1 - tokensSummarized / tokensOriginal) * 100) : 0,
|
|
62
|
+
content_type: 'typescript-error',
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
exports.TypescriptErrorSummarizer = TypescriptErrorSummarizer;
|
|
67
|
+
//# sourceMappingURL=typescript-error-summarizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typescript-error-summarizer.js","sourceRoot":"","sources":["../../../src/plugins/summarizers/typescript-error-summarizer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
// Read stdin
|
|
5
|
+
let input = '';
|
|
6
|
+
try {
|
|
7
|
+
const fs = require('fs');
|
|
8
|
+
input = fs.readFileSync(0, 'utf8');
|
|
9
|
+
} catch { process.exit(0); }
|
|
10
|
+
|
|
11
|
+
if (!input.trim()) process.exit(0);
|
|
12
|
+
|
|
13
|
+
let data;
|
|
14
|
+
try {
|
|
15
|
+
data = JSON.parse(input);
|
|
16
|
+
} catch { process.exit(0); }
|
|
17
|
+
|
|
18
|
+
const toolName = data.tool_name;
|
|
19
|
+
const toolInput = data.tool_input || {};
|
|
20
|
+
const toolOutput = data.tool_output || {};
|
|
21
|
+
|
|
22
|
+
// Classify what to observe
|
|
23
|
+
function getObservation(name, inp, out) {
|
|
24
|
+
const stdout = out.stdout || out.content || out.output || '';
|
|
25
|
+
const content = typeof stdout === 'string' ? stdout : JSON.stringify(stdout);
|
|
26
|
+
|
|
27
|
+
if (!content || content.length < 10) return null;
|
|
28
|
+
|
|
29
|
+
switch (name) {
|
|
30
|
+
case 'Bash': return { content, type: 'log', source: 'Bash' };
|
|
31
|
+
case 'Read': return { content, type: 'code', source: 'Read', filePath: inp.file_path };
|
|
32
|
+
case 'Write':
|
|
33
|
+
case 'Edit': return { content: inp.content || content, type: 'code', source: name, filePath: inp.file_path };
|
|
34
|
+
case 'Grep':
|
|
35
|
+
case 'Glob': return { content, type: 'context', source: name };
|
|
36
|
+
default: return null;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const obs = getObservation(toolName, toolInput, toolOutput);
|
|
41
|
+
if (!obs) process.exit(0);
|
|
42
|
+
|
|
43
|
+
// Strip basic private tags before sending
|
|
44
|
+
let cleaned = obs.content;
|
|
45
|
+
cleaned = cleaned.replace(/<private>[\s\S]*?<\/private>/gi, '');
|
|
46
|
+
cleaned = cleaned.replace(/<redact>[\s\S]*?<\/redact>/gi, '[REDACTED]');
|
|
47
|
+
|
|
48
|
+
if (cleaned.length < 10) process.exit(0);
|
|
49
|
+
|
|
50
|
+
// Fire-and-forget POST to MCP server
|
|
51
|
+
const http = require('http');
|
|
52
|
+
const port = parseInt(process.env.CONTEXT_MEM_PORT || '51893', 10);
|
|
53
|
+
const payload = JSON.stringify({
|
|
54
|
+
jsonrpc: '2.0',
|
|
55
|
+
method: 'tools/call',
|
|
56
|
+
params: {
|
|
57
|
+
name: 'observe',
|
|
58
|
+
arguments: {
|
|
59
|
+
content: cleaned.slice(0, 50000), // Cap at 50KB
|
|
60
|
+
type: obs.type,
|
|
61
|
+
source: obs.source,
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
const req = http.request({
|
|
67
|
+
hostname: '127.0.0.1',
|
|
68
|
+
port,
|
|
69
|
+
path: '/',
|
|
70
|
+
method: 'POST',
|
|
71
|
+
headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(payload) },
|
|
72
|
+
timeout: 500,
|
|
73
|
+
}, () => {});
|
|
74
|
+
|
|
75
|
+
req.on('error', () => {}); // Fire and forget
|
|
76
|
+
req.write(payload);
|
|
77
|
+
req.end();
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* context-mem dashboard auto-start hook
|
|
6
|
+
*
|
|
7
|
+
* Fires on SessionStart — starts the dashboard server as a background process
|
|
8
|
+
* if it's not already running.
|
|
9
|
+
*
|
|
10
|
+
* Hook type: SessionStart
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const { spawn, execSync } = require('child_process');
|
|
14
|
+
const path = require('path');
|
|
15
|
+
const fs = require('fs');
|
|
16
|
+
const net = require('net');
|
|
17
|
+
|
|
18
|
+
const PORT = parseInt(process.env.CONTEXT_MEM_DASHBOARD_PORT || '51893', 10);
|
|
19
|
+
const PROJECT_DIR = process.cwd();
|
|
20
|
+
const DB_PATH = path.join(PROJECT_DIR, '.context-mem', 'store.db');
|
|
21
|
+
const PID_FILE = path.join(PROJECT_DIR, '.context-mem', 'dashboard.pid');
|
|
22
|
+
const SERVER_SCRIPT = path.join(__dirname, '..', 'dashboard', 'server.js');
|
|
23
|
+
|
|
24
|
+
// Skip if no database
|
|
25
|
+
if (!fs.existsSync(DB_PATH)) process.exit(0);
|
|
26
|
+
|
|
27
|
+
// Skip if server script missing
|
|
28
|
+
if (!fs.existsSync(SERVER_SCRIPT)) process.exit(0);
|
|
29
|
+
|
|
30
|
+
// Check if already running via PID file
|
|
31
|
+
function isRunning(pid) {
|
|
32
|
+
try {
|
|
33
|
+
process.kill(pid, 0);
|
|
34
|
+
return true;
|
|
35
|
+
} catch {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Check if port is in use
|
|
41
|
+
function isPortInUse(port) {
|
|
42
|
+
return new Promise((resolve) => {
|
|
43
|
+
const s = net.createConnection({ port, host: '127.0.0.1' });
|
|
44
|
+
s.on('connect', () => { s.destroy(); resolve(true); });
|
|
45
|
+
s.on('error', () => resolve(false));
|
|
46
|
+
s.setTimeout(300, () => { s.destroy(); resolve(false); });
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async function main() {
|
|
51
|
+
// Check PID file
|
|
52
|
+
if (fs.existsSync(PID_FILE)) {
|
|
53
|
+
const pid = parseInt(fs.readFileSync(PID_FILE, 'utf8').trim(), 10);
|
|
54
|
+
if (pid && isRunning(pid)) {
|
|
55
|
+
// Already running
|
|
56
|
+
process.exit(0);
|
|
57
|
+
}
|
|
58
|
+
// Stale PID file
|
|
59
|
+
fs.unlinkSync(PID_FILE);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Check if port is already in use (maybe started manually)
|
|
63
|
+
if (await isPortInUse(PORT)) {
|
|
64
|
+
process.exit(0);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Start dashboard in background
|
|
68
|
+
const child = spawn('node', [
|
|
69
|
+
SERVER_SCRIPT,
|
|
70
|
+
'--port', String(PORT),
|
|
71
|
+
'--db', DB_PATH,
|
|
72
|
+
'--project', PROJECT_DIR,
|
|
73
|
+
'--no-open', // Don't auto-open browser on hook start
|
|
74
|
+
], {
|
|
75
|
+
detached: true,
|
|
76
|
+
stdio: 'ignore',
|
|
77
|
+
env: { ...process.env },
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
child.unref();
|
|
81
|
+
|
|
82
|
+
// Write PID
|
|
83
|
+
fs.mkdirSync(path.dirname(PID_FILE), { recursive: true });
|
|
84
|
+
fs.writeFileSync(PID_FILE, String(child.pid));
|
|
85
|
+
|
|
86
|
+
// Output for hook feedback
|
|
87
|
+
console.log(JSON.stringify({
|
|
88
|
+
result: `Dashboard started on port ${PORT} (pid: ${child.pid})`
|
|
89
|
+
}));
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
main().catch(() => process.exit(0));
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* context-mem dashboard stop hook
|
|
6
|
+
*
|
|
7
|
+
* Fires on Stop — gracefully shuts down the dashboard server.
|
|
8
|
+
*
|
|
9
|
+
* Hook type: Stop
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
const path = require('path');
|
|
13
|
+
const fs = require('fs');
|
|
14
|
+
|
|
15
|
+
const PROJECT_DIR = process.cwd();
|
|
16
|
+
const PID_FILE = path.join(PROJECT_DIR, '.context-mem', 'dashboard.pid');
|
|
17
|
+
|
|
18
|
+
if (!fs.existsSync(PID_FILE)) process.exit(0);
|
|
19
|
+
|
|
20
|
+
const pid = parseInt(fs.readFileSync(PID_FILE, 'utf8').trim(), 10);
|
|
21
|
+
if (!pid) {
|
|
22
|
+
fs.unlinkSync(PID_FILE);
|
|
23
|
+
process.exit(0);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
try {
|
|
27
|
+
process.kill(pid, 'SIGTERM');
|
|
28
|
+
fs.unlinkSync(PID_FILE);
|
|
29
|
+
} catch {
|
|
30
|
+
// Process already dead
|
|
31
|
+
try { fs.unlinkSync(PID_FILE); } catch {}
|
|
32
|
+
}
|
package/hooks/hooks.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"description": "context-mem hooks — observation capture and dashboard auto-start",
|
|
3
|
+
"hooks": {
|
|
4
|
+
"SessionStart": [
|
|
5
|
+
{
|
|
6
|
+
"matcher": "startup|clear|compact",
|
|
7
|
+
"hooks": [
|
|
8
|
+
{
|
|
9
|
+
"type": "command",
|
|
10
|
+
"command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/dashboard-autostart.js\"",
|
|
11
|
+
"timeout": 10
|
|
12
|
+
}
|
|
13
|
+
]
|
|
14
|
+
}
|
|
15
|
+
],
|
|
16
|
+
"PostToolUse": [
|
|
17
|
+
{
|
|
18
|
+
"matcher": "Bash|Read|Write|Edit|Grep|Glob",
|
|
19
|
+
"hooks": [
|
|
20
|
+
{
|
|
21
|
+
"type": "command",
|
|
22
|
+
"command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/context-mem-hook.js\"",
|
|
23
|
+
"timeout": 5
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
}
|
|
27
|
+
],
|
|
28
|
+
"Stop": [
|
|
29
|
+
{
|
|
30
|
+
"hooks": [
|
|
31
|
+
{
|
|
32
|
+
"type": "command",
|
|
33
|
+
"command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/dashboard-stop.js\"",
|
|
34
|
+
"timeout": 5
|
|
35
|
+
}
|
|
36
|
+
]
|
|
37
|
+
}
|
|
38
|
+
]
|
|
39
|
+
}
|
|
40
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "context-mem",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Context optimization for AI coding assistants — 90%+ token savings via summarization, search, and progressive disclosure",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"bin": {
|
|
8
|
+
"context-mem": "./dist/cli/index.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"dev": "tsc --watch",
|
|
13
|
+
"test": "node --test 'dist/tests/**/*.test.js'",
|
|
14
|
+
"test:watch": "tsc --watch & node --test --watch 'dist/tests/**/*.test.js'",
|
|
15
|
+
"lint": "tsc --noEmit",
|
|
16
|
+
"prepublishOnly": "npm run build && npm test"
|
|
17
|
+
},
|
|
18
|
+
"keywords": ["mcp", "context", "llm", "token-optimization", "claude-code", "ai-coding"],
|
|
19
|
+
"author": "Juba Kitiashvili",
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"files": ["dist", "!dist/tests", "hooks", ".context-mem.json.example"],
|
|
22
|
+
"engines": { "node": ">=18" },
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
25
|
+
"better-sqlite3": "^11.0.0"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@types/better-sqlite3": "^7.6.0",
|
|
29
|
+
"@types/node": "^20.0.0",
|
|
30
|
+
"typescript": "^5.5.0"
|
|
31
|
+
}
|
|
32
|
+
}
|