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,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"storage": "auto",
|
|
3
|
+
"plugins": {
|
|
4
|
+
"summarizers": ["shell", "json", "error", "log", "code"],
|
|
5
|
+
"search": ["bm25", "trigram"],
|
|
6
|
+
"runtimes": ["javascript", "python"]
|
|
7
|
+
},
|
|
8
|
+
"privacy": {
|
|
9
|
+
"strip_tags": true,
|
|
10
|
+
"redact_patterns": []
|
|
11
|
+
},
|
|
12
|
+
"token_economics": true,
|
|
13
|
+
"lifecycle": {
|
|
14
|
+
"ttl_days": 30,
|
|
15
|
+
"max_db_size_mb": 500,
|
|
16
|
+
"max_observations": 50000,
|
|
17
|
+
"cleanup_schedule": "on_startup",
|
|
18
|
+
"preserve_types": ["decision", "commit"]
|
|
19
|
+
},
|
|
20
|
+
"port": 51893,
|
|
21
|
+
"db_path": ".context-mem/store.db"
|
|
22
|
+
}
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Juba Kitiashvili
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
# context-mem
|
|
2
|
+
|
|
3
|
+
> Context optimization for AI coding assistants — 99% token savings, zero configuration, no LLM dependency.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/context-mem)
|
|
6
|
+
[]()
|
|
7
|
+
[](LICENSE)
|
|
8
|
+
[]()
|
|
9
|
+
|
|
10
|
+
AI coding assistants waste 60–80% of their context window on raw tool outputs — full npm logs, verbose test results, uncompressed JSON. This means shorter sessions, lost context, and repeated work.
|
|
11
|
+
|
|
12
|
+
**context-mem** captures tool outputs via hooks, compresses them using 14 content-aware summarizers, stores everything in local SQLite with full-text search, and serves compressed context back through the [MCP protocol](https://modelcontextprotocol.io). No LLM calls, no cloud, no cost.
|
|
13
|
+
|
|
14
|
+
## How It Compares
|
|
15
|
+
|
|
16
|
+
| | context-mem | claude-mem | context-mode | Context7 |
|
|
17
|
+
|---|---|---|---|---|
|
|
18
|
+
| **Approach** | 14 specialized summarizers | LLM-based compression | Sandbox + intent filter | External docs injection |
|
|
19
|
+
| **Token Savings** | 99% (benchmarked) | ~95% (claimed) | 98% (claimed) | N/A |
|
|
20
|
+
| **Search** | BM25 + Trigram + Fuzzy | Basic recall | BM25 + Trigram + Fuzzy | Doc lookup |
|
|
21
|
+
| **LLM Calls** | None (free, deterministic) | Every observation ($$$) | None | None |
|
|
22
|
+
| **Knowledge Base** | 5 categories, relevance decay | No | No | No |
|
|
23
|
+
| **Budget Management** | Configurable limits + overflow | No | Basic throttling | No |
|
|
24
|
+
| **Event Tracking** | P1–P4, error-fix detection | No | Session events only | No |
|
|
25
|
+
| **Dashboard** | Real-time web UI | No | No | No |
|
|
26
|
+
| **Session Continuity** | Snapshot save/restore | Partial | Yes | No |
|
|
27
|
+
| **Content Types** | 14 specialized detectors | Generic LLM | Generic sandbox | Docs only |
|
|
28
|
+
| **Privacy** | Fully local, tag stripping | Local | Local | Cloud |
|
|
29
|
+
| **License** | MIT | AGPL-3.0 | Elastic v2 | Open |
|
|
30
|
+
|
|
31
|
+
## Quick Start
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npm install -g context-mem
|
|
35
|
+
cd your-project
|
|
36
|
+
context-mem init
|
|
37
|
+
context-mem serve
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Runtime Context Optimization (benchmark-verified)
|
|
41
|
+
|
|
42
|
+
| Mechanism | How it works | Savings |
|
|
43
|
+
|---|---|---|
|
|
44
|
+
| **Content summarizer** | Auto-detects 14 content types, produces statistical summaries | **97–100%** per output |
|
|
45
|
+
| **Index + Search** | FTS5 BM25 retrieval returns only relevant chunks, code preserved exactly | **80%** per search |
|
|
46
|
+
| **Smart truncation** | 4-tier fallback: JSON schema → Pattern → Head/Tail → Binary hash | **83–100%** per output |
|
|
47
|
+
| **Session snapshots** | Captures full session state in <2 KB | **~50%** vs log replay |
|
|
48
|
+
| **Budget enforcement** | Throttling at 80% prevents runaway token consumption | Prevents overflow |
|
|
49
|
+
|
|
50
|
+
**Result:** In a full coding session, **99% of tool output tokens are eliminated** — leaving 99.6% of your context window free for actual problem solving. See **[BENCHMARK.md](docs/benchmarks/results.md)** for complete results.
|
|
51
|
+
|
|
52
|
+
### Headline Numbers
|
|
53
|
+
|
|
54
|
+
| Scenario | Raw | Compressed | Savings |
|
|
55
|
+
|---|---|---|---|
|
|
56
|
+
| Full coding session (50 tools) | 365.5 KB | 3.2 KB | **99%** |
|
|
57
|
+
| 14 content types (555.9 KB) | 555.9 KB | 5.6 KB | **99%** |
|
|
58
|
+
| Index + Search (6 scenarios) | 38.9 KB | 8.0 KB | **80%** |
|
|
59
|
+
| BM25 search latency | — | 0.3ms avg | **3,342 ops/s** |
|
|
60
|
+
| Trigram search latency | — | 0.008ms avg | **120,122 ops/s** |
|
|
61
|
+
|
|
62
|
+
<sup>Verified on Apple M3 Pro, Node.js v22.22.0, 555.9 KB real-world test data across 21 scenarios.</sup>
|
|
63
|
+
|
|
64
|
+
## What Gets Compressed
|
|
65
|
+
|
|
66
|
+
14 summarizers detect content type automatically and apply the optimal compression:
|
|
67
|
+
|
|
68
|
+
| Content Type | Example | Strategy |
|
|
69
|
+
|---|---|---|
|
|
70
|
+
| Shell output | npm install, build logs | Command + exit code + error extraction |
|
|
71
|
+
| JSON | API responses, configs | Schema extraction (keys + types, no values) |
|
|
72
|
+
| Errors | Stack traces, crashes | Error type + message + top frames |
|
|
73
|
+
| Test results | Jest, Vitest | Pass/fail/skip counts + failure details |
|
|
74
|
+
| TypeScript errors | `error TS2345:` | Error count by file + top error codes |
|
|
75
|
+
| Build output | Webpack, Vite, Next.js | Routes + bundle sizes + warnings |
|
|
76
|
+
| Git log | Commits, diffs | Commit count + authors + date range |
|
|
77
|
+
| CSV/TSV | Data files, analytics | Row/column count + headers + aggregation |
|
|
78
|
+
| Markdown | Docs, READMEs | Heading tree + code blocks + links |
|
|
79
|
+
| HTML | Web pages | Title + nav + headings + forms |
|
|
80
|
+
| Network | HTTP logs, access logs | Method/status distribution |
|
|
81
|
+
| Code | Source files | Function/class signatures |
|
|
82
|
+
| Log files | App logs, access logs | Level distribution + error extraction |
|
|
83
|
+
| Binary | Images, compiled files | SHA256 hash + byte count |
|
|
84
|
+
|
|
85
|
+
## Features
|
|
86
|
+
|
|
87
|
+
**Search** — 3-layer hybrid: BM25 full-text → trigram fuzzy → Levenshtein typo-tolerant. Sub-millisecond latency with intent classification.
|
|
88
|
+
|
|
89
|
+
**Knowledge Base** — Save and search patterns, decisions, errors, APIs, components. Time-decay relevance scoring with automatic archival.
|
|
90
|
+
|
|
91
|
+
**Budget Management** — Session token limits with three overflow strategies: aggressive truncation, warn, hard stop.
|
|
92
|
+
|
|
93
|
+
**Event Tracking** — P1–P4 priority events with automatic error→fix detection.
|
|
94
|
+
|
|
95
|
+
**Session Snapshots** — Save/restore session state across restarts with progressive trimming.
|
|
96
|
+
|
|
97
|
+
**Dashboard** — Real-time web UI at `http://localhost:51893` — token economics, observations, search, knowledge base, events, system health.
|
|
98
|
+
|
|
99
|
+
<p align="center">
|
|
100
|
+
<img src="docs/screenshots/dashboard-overview.png" width="600" alt="Dashboard — token economics and observation stats" />
|
|
101
|
+
</p>
|
|
102
|
+
<p align="center">
|
|
103
|
+
<img src="docs/screenshots/dashboard-middle.png" width="600" alt="Dashboard — event stream, session snapshots, activity" />
|
|
104
|
+
</p>
|
|
105
|
+
|
|
106
|
+
**Privacy** — Everything local. `<private>` tag stripping, custom regex redaction. No telemetry, no cloud.
|
|
107
|
+
|
|
108
|
+
## Architecture
|
|
109
|
+
|
|
110
|
+
```
|
|
111
|
+
Tool Output → Hook Capture → Pipeline → Summarizer (14 types) → SQLite + FTS5
|
|
112
|
+
↓ ↓
|
|
113
|
+
SHA256 Dedup 3-Layer Search
|
|
114
|
+
↓ ↓
|
|
115
|
+
4-Tier Truncation Progressive Disclosure
|
|
116
|
+
↓
|
|
117
|
+
AI Assistant ← MCP Server
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## MCP Tools
|
|
121
|
+
|
|
122
|
+
<details>
|
|
123
|
+
<summary>17 tools available via MCP protocol</summary>
|
|
124
|
+
|
|
125
|
+
| Tool | Description |
|
|
126
|
+
|---|---|
|
|
127
|
+
| `observe` | Store an observation with auto-summarization |
|
|
128
|
+
| `search` | Hybrid search across all observations |
|
|
129
|
+
| `get` | Retrieve full observation by ID |
|
|
130
|
+
| `timeline` | Reverse-chronological observation list |
|
|
131
|
+
| `stats` | Token economics for current session |
|
|
132
|
+
| `summarize` | Summarize content without storing |
|
|
133
|
+
| `configure` | Update runtime configuration |
|
|
134
|
+
| `execute` | Run code snippets (JS/Python) |
|
|
135
|
+
| `index_content` | Index content with code-aware chunking |
|
|
136
|
+
| `search_content` | Search indexed content chunks |
|
|
137
|
+
| `save_knowledge` | Save to knowledge base |
|
|
138
|
+
| `search_knowledge` | Search knowledge base |
|
|
139
|
+
| `budget_status` | Current budget usage |
|
|
140
|
+
| `budget_configure` | Set budget limits |
|
|
141
|
+
| `restore_session` | Restore session from snapshot |
|
|
142
|
+
| `emit_event` | Emit a context event |
|
|
143
|
+
| `query_events` | Query events with filters |
|
|
144
|
+
|
|
145
|
+
</details>
|
|
146
|
+
|
|
147
|
+
## CLI Commands
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
context-mem init # Initialize in current project
|
|
151
|
+
context-mem serve # Start MCP server (stdio)
|
|
152
|
+
context-mem status # Show database stats
|
|
153
|
+
context-mem doctor # Run health checks
|
|
154
|
+
context-mem dashboard # Open web dashboard
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Configuration
|
|
158
|
+
|
|
159
|
+
<details>
|
|
160
|
+
<summary>.context-mem.json</summary>
|
|
161
|
+
|
|
162
|
+
```json
|
|
163
|
+
{
|
|
164
|
+
"storage": "auto",
|
|
165
|
+
"plugins": {
|
|
166
|
+
"summarizers": ["shell", "json", "error", "log", "code"],
|
|
167
|
+
"search": ["bm25", "trigram"],
|
|
168
|
+
"runtimes": ["javascript", "python"]
|
|
169
|
+
},
|
|
170
|
+
"privacy": {
|
|
171
|
+
"strip_tags": true,
|
|
172
|
+
"redact_patterns": []
|
|
173
|
+
},
|
|
174
|
+
"token_economics": true,
|
|
175
|
+
"lifecycle": {
|
|
176
|
+
"ttl_days": 30,
|
|
177
|
+
"max_db_size_mb": 500,
|
|
178
|
+
"max_observations": 50000,
|
|
179
|
+
"cleanup_schedule": "on_startup",
|
|
180
|
+
"preserve_types": ["decision", "commit"]
|
|
181
|
+
},
|
|
182
|
+
"port": 51893,
|
|
183
|
+
"db_path": ".context-mem/store.db"
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
</details>
|
|
188
|
+
|
|
189
|
+
## Documentation
|
|
190
|
+
|
|
191
|
+
| Doc | Description |
|
|
192
|
+
|---|---|
|
|
193
|
+
| [Benchmark Results](docs/benchmarks/results.md) | Full benchmark suite — 21 scenarios, 7 parts |
|
|
194
|
+
| [Configuration Guide](.context-mem.json.example) | All config options with defaults |
|
|
195
|
+
|
|
196
|
+
## Available On
|
|
197
|
+
|
|
198
|
+
- **npm** — `npm install -g context-mem`
|
|
199
|
+
|
|
200
|
+
## License
|
|
201
|
+
|
|
202
|
+
MIT — use it however you want.
|
|
203
|
+
|
|
204
|
+
## Author
|
|
205
|
+
|
|
206
|
+
[Juba Kitiashvili](https://github.com/JubaKitiworworashvili)
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
<p align="center">
|
|
211
|
+
<b>context-mem — 99% less noise, 100% more context</b><br/>
|
|
212
|
+
<a href="https://github.com/JubaKitiworworashvili/context-mem">Star this repo</a> · <a href="https://github.com/JubaKitiworworashvili/context-mem/fork">Fork it</a> · <a href="https://github.com/JubaKitiworworashvili/context-mem/issues">Report an issue</a>
|
|
213
|
+
</p>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/dashboard.ts"],"names":[],"mappings":"AAIA,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAmD7D"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.dashboard = dashboard;
|
|
7
|
+
const node_child_process_1 = require("node:child_process");
|
|
8
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
9
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
10
|
+
async function dashboard(args) {
|
|
11
|
+
const projectDir = process.cwd();
|
|
12
|
+
const dbPath = node_path_1.default.join(projectDir, '.context-mem', 'store.db');
|
|
13
|
+
if (!node_fs_1.default.existsSync(dbPath)) {
|
|
14
|
+
console.error('No database found. Run `context-mem init` first.');
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
const serverScript = node_path_1.default.join(__dirname, '..', '..', '..', 'dashboard', 'server.js');
|
|
18
|
+
if (!node_fs_1.default.existsSync(serverScript)) {
|
|
19
|
+
console.error('Dashboard server not found at:', serverScript);
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
const port = args.includes('--port') ? args[args.indexOf('--port') + 1] : '51893';
|
|
23
|
+
const background = args.includes('--bg') || args.includes('--background');
|
|
24
|
+
const noOpen = args.includes('--no-open');
|
|
25
|
+
const spawnArgs = [serverScript, '--port', port, '--db', dbPath, '--project', projectDir];
|
|
26
|
+
if (noOpen)
|
|
27
|
+
spawnArgs.push('--no-open');
|
|
28
|
+
if (background) {
|
|
29
|
+
// Detached background process
|
|
30
|
+
const child = (0, node_child_process_1.spawn)('node', spawnArgs, {
|
|
31
|
+
detached: true,
|
|
32
|
+
stdio: 'ignore',
|
|
33
|
+
env: { ...process.env },
|
|
34
|
+
});
|
|
35
|
+
child.unref();
|
|
36
|
+
// Write PID for later cleanup
|
|
37
|
+
const pidFile = node_path_1.default.join(projectDir, '.context-mem', 'dashboard.pid');
|
|
38
|
+
node_fs_1.default.writeFileSync(pidFile, String(child.pid));
|
|
39
|
+
console.log(`context-mem dashboard started (pid: ${child.pid}, port: ${port})`);
|
|
40
|
+
console.log(` URL: http://127.0.0.1:${port}`);
|
|
41
|
+
console.log(` PID: ${pidFile}`);
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
// Foreground — blocks until ctrl-c
|
|
45
|
+
const child = (0, node_child_process_1.spawn)('node', spawnArgs, {
|
|
46
|
+
stdio: 'inherit',
|
|
47
|
+
env: { ...process.env },
|
|
48
|
+
});
|
|
49
|
+
child.on('exit', (code) => process.exit(code ?? 0));
|
|
50
|
+
// Forward signals
|
|
51
|
+
process.on('SIGTERM', () => child.kill('SIGTERM'));
|
|
52
|
+
process.on('SIGINT', () => child.kill('SIGINT'));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=dashboard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dashboard.js","sourceRoot":"","sources":["../../../src/cli/commands/dashboard.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/doctor.ts"],"names":[],"mappings":"AAGA,wBAAsB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAyC3D"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.doctor = doctor;
|
|
7
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
9
|
+
async function doctor(_args) {
|
|
10
|
+
const projectDir = process.cwd();
|
|
11
|
+
const checks = [];
|
|
12
|
+
// 1. SQLite available
|
|
13
|
+
try {
|
|
14
|
+
const { BetterSqlite3Storage } = await import('../../plugins/storage/better-sqlite3.js');
|
|
15
|
+
const s = new BetterSqlite3Storage();
|
|
16
|
+
await s.init({});
|
|
17
|
+
checks.push({ name: 'SQLite (better-sqlite3)', status: 'ok', detail: 'Available' });
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
checks.push({ name: 'SQLite (better-sqlite3)', status: 'fail', detail: 'Not available' });
|
|
21
|
+
}
|
|
22
|
+
// 2. Database exists
|
|
23
|
+
const dbPath = node_path_1.default.join(projectDir, '.context-mem', 'store.db');
|
|
24
|
+
if (node_fs_1.default.existsSync(dbPath)) {
|
|
25
|
+
checks.push({ name: 'Database', status: 'ok', detail: dbPath });
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
checks.push({ name: 'Database', status: 'warn', detail: 'Not found — run `context-mem init`' });
|
|
29
|
+
}
|
|
30
|
+
// 3. Config file
|
|
31
|
+
const configPath = node_path_1.default.join(projectDir, '.context-mem.json');
|
|
32
|
+
if (node_fs_1.default.existsSync(configPath)) {
|
|
33
|
+
checks.push({ name: 'Config', status: 'ok', detail: configPath });
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
checks.push({ name: 'Config', status: 'warn', detail: 'Using defaults' });
|
|
37
|
+
}
|
|
38
|
+
// 4. Node.js version
|
|
39
|
+
const nodeVersion = process.version;
|
|
40
|
+
const major = parseInt(nodeVersion.slice(1));
|
|
41
|
+
checks.push({ name: 'Node.js', status: major >= 18 ? 'ok' : 'fail', detail: nodeVersion });
|
|
42
|
+
// Print results
|
|
43
|
+
console.log('context-mem doctor\n');
|
|
44
|
+
for (const check of checks) {
|
|
45
|
+
const icon = check.status === 'ok' ? '[OK]' : check.status === 'warn' ? '[WARN]' : '[FAIL]';
|
|
46
|
+
console.log(` ${icon} ${check.name}: ${check.detail}`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=doctor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../../src/cli/commands/doctor.ts"],"names":[],"mappings":";;;;;AAGA,wBAyCC;AA5CD,sDAAyB;AACzB,0DAA6B;AAEtB,KAAK,UAAU,MAAM,CAAC,KAAe;IAC1C,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IACjC,MAAM,MAAM,GAA4E,EAAE,CAAC;IAE3F,sBAAsB;IACtB,IAAI,CAAC;QACH,MAAM,EAAE,oBAAoB,EAAE,GAAG,MAAM,MAAM,CAAC,yCAAyC,CAAC,CAAC;QACzF,MAAM,CAAC,GAAG,IAAI,oBAAoB,EAAE,CAAC;QACrC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjB,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,yBAAyB,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC;IACtF,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,yBAAyB,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC,CAAC;IAC5F,CAAC;IAED,qBAAqB;IACrB,MAAM,MAAM,GAAG,mBAAI,CAAC,IAAI,CAAC,UAAU,EAAE,cAAc,EAAE,UAAU,CAAC,CAAC;IACjE,IAAI,iBAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1B,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAClE,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,oCAAoC,EAAE,CAAC,CAAC;IAClG,CAAC;IAED,iBAAiB;IACjB,MAAM,UAAU,GAAG,mBAAI,CAAC,IAAI,CAAC,UAAU,EAAE,mBAAmB,CAAC,CAAC;IAC9D,IAAI,iBAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC9B,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;IACpE,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,CAAC,CAAC;IAC5E,CAAC;IAED,qBAAqB;IACrB,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;IACpC,MAAM,KAAK,GAAG,QAAQ,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7C,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC;IAE3F,gBAAgB;IAChB,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;IACpC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC;QAC5F,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IAC1D,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"AAGA,wBAAsB,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAsCzD"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.init = init;
|
|
7
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
9
|
+
async function init(_args) {
|
|
10
|
+
const projectDir = process.cwd();
|
|
11
|
+
const configPath = node_path_1.default.join(projectDir, '.context-mem.json');
|
|
12
|
+
if (node_fs_1.default.existsSync(configPath)) {
|
|
13
|
+
console.log('context-mem already initialized (found .context-mem.json)');
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
// Create default config
|
|
17
|
+
const config = {
|
|
18
|
+
storage: 'auto',
|
|
19
|
+
plugins: { summarizers: ['shell', 'json', 'error', 'log', 'code'], search: ['bm25', 'trigram'] },
|
|
20
|
+
privacy: { strip_tags: true, redact_patterns: [] },
|
|
21
|
+
token_economics: true,
|
|
22
|
+
lifecycle: { ttl_days: 30, max_observations: 50000, cleanup_schedule: 'on_startup' },
|
|
23
|
+
db_path: '.context-mem/store.db',
|
|
24
|
+
};
|
|
25
|
+
node_fs_1.default.writeFileSync(configPath, JSON.stringify(config, null, 2) + '\n');
|
|
26
|
+
// Create .context-mem directory
|
|
27
|
+
const dbDir = node_path_1.default.join(projectDir, '.context-mem');
|
|
28
|
+
if (!node_fs_1.default.existsSync(dbDir))
|
|
29
|
+
node_fs_1.default.mkdirSync(dbDir, { recursive: true });
|
|
30
|
+
// Add to .gitignore if exists
|
|
31
|
+
const gitignorePath = node_path_1.default.join(projectDir, '.gitignore');
|
|
32
|
+
if (node_fs_1.default.existsSync(gitignorePath)) {
|
|
33
|
+
const content = node_fs_1.default.readFileSync(gitignorePath, 'utf8');
|
|
34
|
+
if (!content.includes('.context-mem')) {
|
|
35
|
+
node_fs_1.default.appendFileSync(gitignorePath, '\n# context-mem\n.context-mem/\n');
|
|
36
|
+
console.log('Added .context-mem/ to .gitignore');
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
console.log('Initialized context-mem in', projectDir);
|
|
40
|
+
console.log('Config: .context-mem.json');
|
|
41
|
+
console.log('Database: .context-mem/store.db');
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":";;;;;AAGA,oBAsCC;AAzCD,sDAAyB;AACzB,0DAA6B;AAEtB,KAAK,UAAU,IAAI,CAAC,KAAe;IACxC,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IACjC,MAAM,UAAU,GAAG,mBAAI,CAAC,IAAI,CAAC,UAAU,EAAE,mBAAmB,CAAC,CAAC;IAE9D,IAAI,iBAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,2DAA2D,CAAC,CAAC;QACzE,OAAO;IACT,CAAC;IAED,wBAAwB;IACxB,MAAM,MAAM,GAAG;QACb,OAAO,EAAE,MAAM;QACf,OAAO,EAAE,EAAE,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE;QAChG,OAAO,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,eAAe,EAAE,EAAE,EAAE;QAClD,eAAe,EAAE,IAAI;QACrB,SAAS,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,gBAAgB,EAAE,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE;QACpF,OAAO,EAAE,uBAAuB;KACjC,CAAC;IAEF,iBAAE,CAAC,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAErE,gCAAgC;IAChC,MAAM,KAAK,GAAG,mBAAI,CAAC,IAAI,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;IACpD,IAAI,CAAC,iBAAE,CAAC,UAAU,CAAC,KAAK,CAAC;QAAE,iBAAE,CAAC,SAAS,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEpE,8BAA8B;IAC9B,MAAM,aAAa,GAAG,mBAAI,CAAC,IAAI,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;IAC1D,IAAI,iBAAE,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;QACjC,MAAM,OAAO,GAAG,iBAAE,CAAC,YAAY,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;QACvD,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;YACtC,iBAAE,CAAC,cAAc,CAAC,aAAa,EAAE,kCAAkC,CAAC,CAAC;YACrE,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;QACnD,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,4BAA4B,EAAE,UAAU,CAAC,CAAC;IACtD,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;IACzC,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;AACjD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/serve.ts"],"names":[],"mappings":"AAKA,wBAAsB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA2C1D"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.serve = serve;
|
|
4
|
+
const kernel_js_1 = require("../../core/kernel.js");
|
|
5
|
+
const server_js_1 = require("../../mcp-server/server.js");
|
|
6
|
+
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
7
|
+
async function serve(_args) {
|
|
8
|
+
const projectDir = process.cwd();
|
|
9
|
+
const kernel = new kernel_js_1.Kernel(projectDir);
|
|
10
|
+
try {
|
|
11
|
+
await kernel.start();
|
|
12
|
+
}
|
|
13
|
+
catch (err) {
|
|
14
|
+
console.error(`context-mem: Failed to start kernel — ${err.message}`);
|
|
15
|
+
console.error('Run `context-mem init` to set up the project, or `context-mem doctor` to diagnose.');
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
const toolKernel = {
|
|
19
|
+
pipeline: kernel.pipeline,
|
|
20
|
+
search: kernel.getSearchFusion(),
|
|
21
|
+
storage: kernel.getStorage(),
|
|
22
|
+
registry: kernel.registry,
|
|
23
|
+
sessionId: kernel.session.session_id,
|
|
24
|
+
config: kernel.getConfig(),
|
|
25
|
+
budgetManager: kernel.getBudgetManager(),
|
|
26
|
+
eventTracker: kernel.getEventTracker(),
|
|
27
|
+
sessionManager: kernel.getSessionManager(),
|
|
28
|
+
contentStore: kernel.getContentStore(),
|
|
29
|
+
knowledgeBase: kernel.getKnowledgeBase(),
|
|
30
|
+
};
|
|
31
|
+
const server = (0, server_js_1.createMcpServer)(toolKernel);
|
|
32
|
+
const transport = new stdio_js_1.StdioServerTransport();
|
|
33
|
+
try {
|
|
34
|
+
await server.connect(transport);
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
console.error(`context-mem: Failed to connect MCP transport — ${err.message}`);
|
|
38
|
+
await kernel.stop();
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
console.error('context-mem: MCP server started (stdio)');
|
|
42
|
+
// Graceful shutdown
|
|
43
|
+
const shutdown = async () => { await kernel.stop(); process.exit(0); };
|
|
44
|
+
process.on('SIGTERM', shutdown);
|
|
45
|
+
process.on('SIGINT', shutdown);
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=serve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serve.js","sourceRoot":"","sources":["../../../src/cli/commands/serve.ts"],"names":[],"mappings":";;AAKA,sBA2CC;AAhDD,oDAA8C;AAC9C,0DAA6D;AAC7D,wEAAiF;AAG1E,KAAK,UAAU,KAAK,CAAC,KAAe;IACzC,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IACjC,MAAM,MAAM,GAAG,IAAI,kBAAM,CAAC,UAAU,CAAC,CAAC;IAEtC,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,yCAA0C,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QACjF,OAAO,CAAC,KAAK,CAAC,oFAAoF,CAAC,CAAC;QACpG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,UAAU,GAAe;QAC7B,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,MAAM,EAAE,MAAM,CAAC,eAAe,EAAE;QAChC,OAAO,EAAE,MAAM,CAAC,UAAU,EAAE;QAC5B,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,SAAS,EAAE,MAAM,CAAC,OAAO,CAAC,UAAU;QACpC,MAAM,EAAE,MAAM,CAAC,SAAS,EAAE;QAC1B,aAAa,EAAE,MAAM,CAAC,gBAAgB,EAAE;QACxC,YAAY,EAAE,MAAM,CAAC,eAAe,EAAE;QACtC,cAAc,EAAE,MAAM,CAAC,iBAAiB,EAAE;QAC1C,YAAY,EAAE,MAAM,CAAC,eAAe,EAAE;QACtC,aAAa,EAAE,MAAM,CAAC,gBAAgB,EAAE;KACzC,CAAC;IAEF,MAAM,MAAM,GAAG,IAAA,2BAAe,EAAC,UAAU,CAAC,CAAC;IAC3C,MAAM,SAAS,GAAG,IAAI,+BAAoB,EAAE,CAAC;IAE7C,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAClC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,kDAAmD,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QAC1F,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAEzD,oBAAoB;IACpB,MAAM,QAAQ,GAAG,KAAK,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACvE,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAChC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;AACjC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/status.ts"],"names":[],"mappings":"AAIA,wBAAsB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAuB3D"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.status = status;
|
|
7
|
+
const kernel_js_1 = require("../../core/kernel.js");
|
|
8
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
9
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
10
|
+
async function status(_args) {
|
|
11
|
+
const projectDir = process.cwd();
|
|
12
|
+
const dbPath = node_path_1.default.join(projectDir, '.context-mem', 'store.db');
|
|
13
|
+
if (!node_fs_1.default.existsSync(dbPath)) {
|
|
14
|
+
console.log('No database found. Run `context-mem init` first.');
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
const kernel = new kernel_js_1.Kernel(projectDir);
|
|
18
|
+
await kernel.start();
|
|
19
|
+
const stats = await kernel.stats();
|
|
20
|
+
const dbSize = node_fs_1.default.statSync(dbPath).size;
|
|
21
|
+
console.log(`context-mem status
|
|
22
|
+
Database: ${dbPath} (${(dbSize / 1024).toFixed(1)} KB)
|
|
23
|
+
Session: ${stats.session_id}
|
|
24
|
+
Observations: ${stats.observations_stored}
|
|
25
|
+
Tokens saved: ${stats.tokens_saved} (${stats.savings_percentage}%)
|
|
26
|
+
Searches: ${stats.searches_performed}`);
|
|
27
|
+
await kernel.stop();
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../../src/cli/commands/status.ts"],"names":[],"mappings":";;;;;AAIA,wBAuBC;AA3BD,oDAA8C;AAC9C,sDAAyB;AACzB,0DAA6B;AAEtB,KAAK,UAAU,MAAM,CAAC,KAAe;IAC1C,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IACjC,MAAM,MAAM,GAAG,mBAAI,CAAC,IAAI,CAAC,UAAU,EAAE,cAAc,EAAE,UAAU,CAAC,CAAC;IAEjE,IAAI,CAAC,iBAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,kDAAkD,CAAC,CAAC;QAChE,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,kBAAM,CAAC,UAAU,CAAC,CAAC;IACtC,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IAErB,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IACnC,MAAM,MAAM,GAAG,iBAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC;IAExC,OAAO,CAAC,GAAG,CAAC;cACA,MAAM,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;aACtC,KAAK,CAAC,UAAU;kBACX,KAAK,CAAC,mBAAmB;kBACzB,KAAK,CAAC,YAAY,KAAK,KAAK,CAAC,kBAAkB;cACnD,KAAK,CAAC,kBAAkB,EAAE,CAAC,CAAC;IAExC,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;AACtB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const serve_js_1 = require("./commands/serve.js");
|
|
5
|
+
const init_js_1 = require("./commands/init.js");
|
|
6
|
+
const status_js_1 = require("./commands/status.js");
|
|
7
|
+
const doctor_js_1 = require("./commands/doctor.js");
|
|
8
|
+
const dashboard_js_1 = require("./commands/dashboard.js");
|
|
9
|
+
const command = process.argv[2];
|
|
10
|
+
const args = process.argv.slice(3);
|
|
11
|
+
switch (command) {
|
|
12
|
+
case 'serve':
|
|
13
|
+
(0, serve_js_1.serve)(args);
|
|
14
|
+
break;
|
|
15
|
+
case 'init':
|
|
16
|
+
(0, init_js_1.init)(args);
|
|
17
|
+
break;
|
|
18
|
+
case 'status':
|
|
19
|
+
(0, status_js_1.status)(args);
|
|
20
|
+
break;
|
|
21
|
+
case 'doctor':
|
|
22
|
+
(0, doctor_js_1.doctor)(args);
|
|
23
|
+
break;
|
|
24
|
+
case 'dashboard':
|
|
25
|
+
(0, dashboard_js_1.dashboard)(args);
|
|
26
|
+
break;
|
|
27
|
+
default:
|
|
28
|
+
console.log(`context-mem v0.1.0 — Context optimization for AI coding assistants
|
|
29
|
+
|
|
30
|
+
Usage:
|
|
31
|
+
context-mem serve Start MCP server (stdio transport)
|
|
32
|
+
context-mem init Initialize context-mem in current project
|
|
33
|
+
context-mem status Show database stats and session info
|
|
34
|
+
context-mem doctor Run health checks
|
|
35
|
+
context-mem dashboard Open real-time dashboard (web UI)
|
|
36
|
+
`);
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";;;AACA,kDAA4C;AAC5C,gDAA0C;AAC1C,oDAA8C;AAC9C,oDAA8C;AAC9C,0DAAoD;AAEpD,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAChC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAEnC,QAAQ,OAAO,EAAE,CAAC;IAChB,KAAK,OAAO;QAAE,IAAA,gBAAK,EAAC,IAAI,CAAC,CAAC;QAAC,MAAM;IACjC,KAAK,MAAM;QAAE,IAAA,cAAI,EAAC,IAAI,CAAC,CAAC;QAAC,MAAM;IAC/B,KAAK,QAAQ;QAAE,IAAA,kBAAM,EAAC,IAAI,CAAC,CAAC;QAAC,MAAM;IACnC,KAAK,QAAQ;QAAE,IAAA,kBAAM,EAAC,IAAI,CAAC,CAAC;QAAC,MAAM;IACnC,KAAK,WAAW;QAAE,IAAA,wBAAS,EAAC,IAAI,CAAC,CAAC;QAAC,MAAM;IACzC;QACE,OAAO,CAAC,GAAG,CAAC;;;;;;;;CAQf,CAAC,CAAC;QACC,MAAM;AACV,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { StoragePlugin, BudgetConfig, BudgetStatus } from './types.js';
|
|
2
|
+
export declare class BudgetManager {
|
|
3
|
+
private storage;
|
|
4
|
+
constructor(storage: StoragePlugin);
|
|
5
|
+
configure(config: Partial<BudgetConfig>): void;
|
|
6
|
+
check(sessionId: string): BudgetStatus;
|
|
7
|
+
record(_sessionId: string, _bytes: number): void;
|
|
8
|
+
getStatus(sessionId: string): BudgetStatus;
|
|
9
|
+
getConfig(): BudgetConfig;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=budget.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"budget.d.ts","sourceRoot":"","sources":["../../src/core/budget.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAoB,MAAM,YAAY,CAAC;AAE9F,qBAAa,aAAa;IACZ,OAAO,CAAC,OAAO;gBAAP,OAAO,EAAE,aAAa;IAE1C,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,IAAI;IAe9C,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY;IAoBtC,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAKhD,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY;IAI1C,SAAS,IAAI,YAAY;CAkB1B"}
|