@senoldogann/context-manager 0.1.20 → 0.1.21

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.
Files changed (3) hide show
  1. package/README.md +142 -51
  2. package/bin/ccm.js +96 -1
  3. package/package.json +3 -5
package/README.md CHANGED
@@ -2,81 +2,172 @@
2
2
 
3
3
  > 🧠 The Neural Backbone for Autonomous AI Agents
4
4
 
5
- This is the Node.js wrapper for the **Cognitive Codebase Matrix (CCM)**. It allows you to run the CCM CLI and MCP server without manually installing Rust or building from source.
5
+ **Node.js wrapper for Cognitive Codebase Matrix (CCM)** - Enables AI agents to understand and navigate your codebase with surgical precision.
6
+
7
+ [![npm](https://img.shields.io/npm/v/@senoldogann/context-manager?color=orange)](https://www.npmjs.com/package/@senoldogann/context-manager)
8
+ [![MCP](https://img.shields.io/badge/MCP-Compatible-blue)](https://modelcontextprotocol.io/)
9
+ [![Rust](https://img.shields.io/badge/Built%20With-Rust-orange.svg)](https://www.rust-lang.org/)
10
+
11
+ ---
6
12
 
7
13
  ## 🚀 Quick Start
8
14
 
9
- > [!IMPORTANT]
10
- > **Prerequisite:** This tool relies on local AI models. You must have **[Ollama](https://ollama.com)** installed and running.
11
- > CCM will **automatically pull** the required embedding model (`nomic-embed-text`) if missing, but the Ollama engine itself is required.
15
+ ### Prerequisites
16
+
17
+ 1. **Node.js** 16+ installed
18
+ 2. **Ollama** installed and running (for local embeddings)
19
+ - Download: https://ollama.com
20
+ - Pull required model: `ollama pull mxbai-embed-large`
12
21
 
13
- ### 🔒 Privacy by Default
14
- CCM uses a **Local-First** architecture by default. This means:
15
- * Your code is **never** sent to 3rd party servers (OpenAI, Anthropic, etc.).
16
- * All vector operations (Embedding) happen on your local machine.
17
- * You can safely use it for internal or confidential projects.
22
+ ### Installation
18
23
 
19
- The easiest way to get started. This will automatically add CCM to your Claude or Antigravity configuration:
20
24
  ```bash
25
+ # 1. Install and configure for Claude Desktop, Antigravity, Cursor, etc.
21
26
  npx @senoldogann/context-manager install
27
+
28
+ # 2. Index your project
29
+ npx @senoldogann/context-manager index --path .
22
30
  ```
23
31
 
24
- ### 2. Index your Project (Automatic)
25
- CCM now implements **Lazy Indexing**. You don't actually need to run this command; the MCP server will automatically index your project the first time you or your AI agent run a query.
32
+ **That's it!** Restart your AI editor and start asking questions about your code.
33
+
34
+ ---
35
+
36
+ ## 📖 What is CCM?
37
+
38
+ CCM transforms static source code into a dynamic, queryable Knowledge Graph:
39
+
40
+ - **🔍 Semantic Search** - Find code by meaning ("where is auth logic?")
41
+ - **🧠 Graph Navigation** - Understand relationships ("who calls this function?")
42
+ - **📍 Cursor Context** - Get relevant code based on your position
43
+
44
+ ---
45
+
46
+ ## 🔧 Commands
47
+
48
+ The npm wrapper downloads pre-built binaries and passes commands through:
49
+
50
+ | Command | Description |
51
+ |---------|-------------|
52
+ | `npx @senoldogann/context-manager install` | Auto-configure MCP for editors |
53
+ | `npx @senoldogann/context-manager index --path <dir>` | Index a project |
54
+ | `npx @senoldogann/context-manager query --text "..."` | Search codebase |
55
+ | `npx @senoldogann/context-manager mcp` | Run MCP server directly |
56
+ | `npx @senoldogann/context-manager eval --tasks <file>` | Run evaluation tasks |
57
+
58
+ ### Options
26
59
 
27
- If you still want to index manually:
28
60
  ```bash
29
- npx @senoldogann/context-manager index --path .
30
- ```
61
+ # Watch mode - auto-reindex on file changes
62
+ npx @senoldogann/context-manager index --path . --watch
31
63
 
32
- ## ⚒️ Manual Configuration (Alternative)
33
-
34
- If you prefer to configure your AI editor manually without the `install` command, add this to your `mcp_config.json`:
35
-
36
- ```json
37
- {
38
- "mcpServers": {
39
- "context-manager": {
40
- "command": "npx",
41
- "args": ["-y", "@senoldogann/context-manager", "mcp"],
42
- "env": {
43
- "RUST_LOG": "info"
44
- }
45
- }
46
- }
47
- }
64
+ # Custom database path
65
+ npx @senoldogann/context-manager index --path . --db-path /custom/path
48
66
  ```
49
67
 
50
- ## 💡 Pro-Tip: Enforcing CCM Usage
51
- To ensure your AI agent (Claude, Cursor, etc.) always uses CCM for deep analysis, add this to your **Custom Instructions** or **System Prompt**:
68
+ ---
69
+
70
+ ## 🔒 Privacy by Default
52
71
 
53
- > "You are an expert architect. For any question about the codebase, DO NOT guess. Use the `context-manager` tools to explore the Graph and Vector store. Always prioritize `search_code` to find entry points and `read_graph` to navigate dependencies before proposing any code changes."
72
+ CCM uses a **Local-First** architecture:
73
+
74
+ - ✅ Your code **never** leaves your machine
75
+ - ✅ All embeddings run locally via Ollama
76
+ - ✅ No external API calls (unless you configure OpenAI)
54
77
 
55
78
  ---
56
79
 
57
- ## 🇹🇷 Türkçe Özet
80
+ ## ⚙️ Configuration
58
81
 
59
- Bu paket, **Cognitive Codebase Matrix (CCM)** için Node.js wrapper'ıdır. Rust kurulumuna gerek kalmadan CCM araçlarını kullanmanızı sağlar.
82
+ ### Environment Variables
60
83
 
61
- **Hızlı Kurulum:**
62
- ```bash
63
- npx @senoldogann/context-manager install
64
- npx @senoldogann/context-manager index --path .
84
+ Create `~/.ccm/.env`:
85
+
86
+ ```ini
87
+ # Local (Recommended)
88
+ EMBEDDING_PROVIDER=ollama
89
+ EMBEDDING_HOST=http://127.0.0.1:11434
90
+ EMBEDDING_MODEL=mxbai-embed-large
91
+
92
+ # Cloud (Optional)
93
+ EMBEDDING_PROVIDER=openai
94
+ EMBEDDING_API_KEY=sk-your-key
95
+ EMBEDDING_MODEL=text-embedding-3-small
96
+
97
+ # Networking & Limits
98
+ EMBEDDING_TIMEOUT_SECS=30
99
+ CCM_MAX_FILE_BYTES=2097152
100
+
101
+ # MCP Security
102
+ CCM_ALLOWED_ROOTS=/Users/you/projects:/Users/you/sandbox
103
+ CCM_REQUIRE_ALLOWED_ROOTS=0
104
+
105
+ # MCP Runtime
106
+ CCM_MCP_ENGINE_CACHE_SIZE=8
107
+ CCM_MCP_DEBUG=0
108
+
109
+ # Optional: disable embeddings entirely (semantic search disabled)
110
+ CCM_DISABLE_EMBEDDER=0
111
+
112
+ # Optional: embed data files (md/json/yaml) into vector search
113
+ CCM_EMBED_DATA_FILES=0
114
+
115
+ # Binary checksum verification (0 = enforce, 1 = bypass)
116
+ CCM_ALLOW_UNVERIFIED_BINARIES=0
65
117
  ```
66
118
 
119
+ **Production Tip:** Set `CCM_ALLOWED_ROOTS` and enable `CCM_REQUIRE_ALLOWED_ROOTS=1` to restrict MCP access.
120
+
121
+ ---
122
+
123
+ ## 🤖 Usage in AI
124
+
125
+ Once configured, ask your AI agent:
126
+
127
+ > "Search for the authentication flow in this codebase."
128
+
129
+ > "Read the graph for `UserService` and show me its callers."
130
+
131
+ > "What functions call `parse_config`?"
132
+
67
133
  ---
68
134
 
69
- ## 📦 What this package does
70
- This package is a lightweight wrapper that:
71
- 1. Detects your OS and CPU architecture.
72
- 2. Downloads the pre-built Rust binaries from GitHub Releases if not already present.
73
- 3. Automatically manages your global index and persistence in `~/.ccm`.
135
+ ## 📦 For Developers
136
+
137
+ This package handles:
138
+
139
+ 1. OS/architecture detection
140
+ 2. Binary download from GitHub Releases
141
+ 3. Global persistence in `~/.ccm`
142
+
143
+ ### ✅ Binary Integrity
144
+
145
+ Downloads are verified against `checksums.txt` from the GitHub Release.
146
+ If the manifest is missing or a mismatch occurs, you can set `CCM_ALLOW_UNVERIFIED_BINARIES=1` to bypass verification (not recommended).
147
+
148
+ ### 📄 Data Files in Search
149
+
150
+ By default, data files (`.md`, `.json`, `.yaml`) are indexed but not embedded.
151
+ Enable `CCM_EMBED_DATA_FILES=1` to include them in semantic search.
74
152
 
75
- For more details, visit the [Main Repository](https://github.com/senoldogann/LLM-Context-Manager).
153
+ **Source:** https://github.com/senoldogann/LLM-Context-Manager
76
154
 
77
- ### 🆕 v0.1.15 Updates
78
- * **Lazy Indexing:** Automatic project indexing on first query. No background hogging.
79
- * **Universal Support:** Falls back to generic text indexing for ALL file types.
80
- * **Zero-Config:** Improved project root detection and cross-platform binary handling.
155
+ ---
156
+
157
+ ## 📝 Changelog
158
+
159
+ ### v0.1.21
160
+ - ✅ Release checksums (`checksums.txt`) for binary integrity
161
+ - ✅ MCP allowlist with optional strict enforcement
162
+ - ✅ Data file embedding is optional (`CCM_EMBED_DATA_FILES`)
163
+ - ✅ CLI/MCP integration tests
164
+
165
+ ### v0.1.20
166
+ - ✅ 100% evaluation pass rate
167
+ - ✅ Hybrid scoring (graph + semantic)
168
+ - ✅ Lazy indexing support
169
+ - ✅ Watch mode for auto-reindexing
170
+
171
+ ---
81
172
 
82
- Built with ❤️ in **Rust**.
173
+ Built with ❤️ in **Rust**
package/bin/ccm.js CHANGED
@@ -5,10 +5,18 @@ const path = require('path');
5
5
  const fs = require('fs');
6
6
  const os = require('os');
7
7
  const https = require('https');
8
+ const crypto = require('crypto');
8
9
 
9
- const VERSION = "0.1.20";
10
+ const VERSION = "0.1.21";
10
11
  const REPO = 'senoldogann/LLM-Context-Manager';
11
12
  const BIN_DIR = path.join(os.homedir(), '.ccm', 'bin');
13
+ const CHECKSUMS_FILE = 'checksums.txt';
14
+ let checksumCache = null;
15
+
16
+ function allowUnverifiedBinaries() {
17
+ const raw = process.env.CCM_ALLOW_UNVERIFIED_BINARIES || process.env.CCM_SKIP_CHECKSUM || '';
18
+ return ['1', 'true', 'yes'].includes(raw.toLowerCase());
19
+ }
12
20
 
13
21
  async function installMcp() {
14
22
  const configPaths = [];
@@ -88,6 +96,7 @@ async function getBinaryFor(commandName) {
88
96
 
89
97
  const binFilename = `${commandName}-v${VERSION}-${target}`;
90
98
  const binPath = path.join(BIN_DIR, binFilename);
99
+ const remoteFilename = `${commandName}-${target}`;
91
100
 
92
101
  // If file exists, ensure it is executable
93
102
  if (fs.existsSync(binPath)) {
@@ -110,6 +119,7 @@ async function getBinaryFor(commandName) {
110
119
 
111
120
  try {
112
121
  await downloadFile(url, tmpPath);
122
+ await verifyChecksum(tmpPath, [remoteFilename, binFilename]);
113
123
  fs.chmodSync(tmpPath, '755');
114
124
  fs.renameSync(tmpPath, binPath);
115
125
  } catch (err) {
@@ -163,6 +173,91 @@ function downloadFile(url, dest) {
163
173
  });
164
174
  }
165
175
 
176
+ function downloadText(url) {
177
+ return new Promise((resolve, reject) => {
178
+ https.get(url, (response) => {
179
+ if (response.statusCode === 302 || response.statusCode === 301) {
180
+ return downloadText(response.headers.location).then(resolve).catch(reject);
181
+ }
182
+ if (response.statusCode !== 200) {
183
+ return reject(new Error(`Failed to download: ${response.statusCode}`));
184
+ }
185
+ let data = '';
186
+ response.setEncoding('utf8');
187
+ response.on('data', (chunk) => {
188
+ data += chunk;
189
+ });
190
+ response.on('end', () => resolve(data));
191
+ }).on('error', reject);
192
+ });
193
+ }
194
+
195
+ async function getChecksums() {
196
+ if (checksumCache) return checksumCache;
197
+
198
+ const url = `https://github.com/${REPO}/releases/download/v${VERSION}/${CHECKSUMS_FILE}`;
199
+ try {
200
+ const text = await downloadText(url);
201
+ checksumCache = parseChecksums(text);
202
+ return checksumCache;
203
+ } catch (err) {
204
+ return null;
205
+ }
206
+ }
207
+
208
+ function parseChecksums(text) {
209
+ const map = new Map();
210
+ for (const line of text.split('\n')) {
211
+ const trimmed = line.trim();
212
+ if (!trimmed) continue;
213
+ const parts = trimmed.split(/\s+/);
214
+ if (parts.length < 2) continue;
215
+ const hash = parts[0].toLowerCase();
216
+ const filename = parts[parts.length - 1].replace(/^\*/, '');
217
+ map.set(filename, hash);
218
+ }
219
+ return map;
220
+ }
221
+
222
+ function sha256File(filePath) {
223
+ return new Promise((resolve, reject) => {
224
+ const hash = crypto.createHash('sha256');
225
+ const stream = fs.createReadStream(filePath);
226
+ stream.on('error', reject);
227
+ stream.on('data', (data) => hash.update(data));
228
+ stream.on('end', () => resolve(hash.digest('hex')));
229
+ });
230
+ }
231
+
232
+ async function verifyChecksum(filePath, candidates) {
233
+ const checksums = await getChecksums();
234
+ if (!checksums) {
235
+ if (allowUnverifiedBinaries()) {
236
+ console.warn('[CCM] Checksum manifest not found. Proceeding without verification.');
237
+ return;
238
+ }
239
+ throw new Error('Checksum manifest not found. Set CCM_ALLOW_UNVERIFIED_BINARIES=1 to bypass.');
240
+ }
241
+
242
+ const expected = candidates
243
+ .map((name) => [name, `${name}.exe`])
244
+ .flat()
245
+ .map((name) => checksums.get(name))
246
+ .find(Boolean);
247
+ if (!expected) {
248
+ if (allowUnverifiedBinaries()) {
249
+ console.warn('[CCM] Checksum not found for binary. Proceeding without verification.');
250
+ return;
251
+ }
252
+ throw new Error('Checksum not found for binary. Set CCM_ALLOW_UNVERIFIED_BINARIES=1 to bypass.');
253
+ }
254
+
255
+ const actual = await sha256File(filePath);
256
+ if (actual !== expected) {
257
+ throw new Error(`Checksum mismatch. Expected ${expected}, got ${actual}`);
258
+ }
259
+ }
260
+
166
261
  async function main() {
167
262
  try {
168
263
  const binPath = await getBinary();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@senoldogann/context-manager",
3
- "version": "0.1.20",
3
+ "version": "0.1.21",
4
4
  "description": "LLM Context Manager MCP Server & CLI wrapper using npx",
5
5
  "main": "bin/ccm.js",
6
6
  "bin": {
@@ -20,10 +20,8 @@
20
20
  ],
21
21
  "author": "dogan",
22
22
  "license": "MIT",
23
- "dependencies": {
24
- "node-fetch": "^3.3.1"
25
- },
23
+ "dependencies": {},
26
24
  "engines": {
27
25
  "node": ">=16.0.0"
28
26
  }
29
- }
27
+ }