sigmap 2.2.0 → 2.4.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/CHANGELOG.md +48 -0
- package/README.md +60 -16
- package/gen-context.js +193 -3
- package/package.json +7 -1
- package/packages/cli/index.js +63 -0
- package/packages/cli/package.json +26 -0
- package/packages/core/README.md +133 -0
- package/packages/core/index.js +215 -0
- package/packages/core/package.json +28 -0
- package/src/config/defaults.js +8 -0
- package/src/mcp/handlers.js +28 -1
- package/src/mcp/server.js +3 -2
- package/src/mcp/tools.js +24 -0
- package/src/retrieval/ranker.js +242 -0
- package/src/retrieval/tokenizer.js +54 -0
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# sigmap-core
|
|
2
|
+
|
|
3
|
+
Programmatic API for [SigMap](https://manojmallick.github.io/sigmap/) — zero-dependency code signature extraction, ranked retrieval, secret scanning, and project health scoring.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install sigmap # installs the full package (CLI + core)
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
`require('sigmap')` resolves to this library via the root `exports` field.
|
|
12
|
+
|
|
13
|
+
## Quick start
|
|
14
|
+
|
|
15
|
+
```js
|
|
16
|
+
const { extract, rank, buildSigIndex, scan, score } = require('sigmap');
|
|
17
|
+
|
|
18
|
+
// 1. Extract signatures from any source file
|
|
19
|
+
const sigs = extract('function hello() { return "world"; }', 'javascript');
|
|
20
|
+
// → ['function hello()']
|
|
21
|
+
|
|
22
|
+
// 2. Scan for secrets before storing signatures
|
|
23
|
+
const { safe, redacted } = scan(sigs, 'src/utils.js');
|
|
24
|
+
|
|
25
|
+
// 3. Build an index from the generated context file
|
|
26
|
+
const index = buildSigIndex('/path/to/your/project');
|
|
27
|
+
|
|
28
|
+
// 4. Rank files against a query
|
|
29
|
+
const results = rank('add a new language extractor', index, { topK: 5 });
|
|
30
|
+
// → [{ file: 'src/extractors/python.js', score: 3.5, sigs: [...], tokens: 42 }, ...]
|
|
31
|
+
|
|
32
|
+
// 5. Check project health
|
|
33
|
+
const health = score('/path/to/your/project');
|
|
34
|
+
// → { score: 92, grade: 'A', strategy: 'full', ... }
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## API reference
|
|
38
|
+
|
|
39
|
+
### `extract(src, language)` → `string[]`
|
|
40
|
+
|
|
41
|
+
Extract code signatures from source text.
|
|
42
|
+
|
|
43
|
+
| Param | Type | Description |
|
|
44
|
+
|---|---|---|
|
|
45
|
+
| `src` | `string` | Raw file content |
|
|
46
|
+
| `language` | `string` | Language name (`'typescript'`, `'python'`, etc.) **or** a file path/name with a recognised extension |
|
|
47
|
+
|
|
48
|
+
Returns an array of signature strings. Never throws — returns `[]` on any error.
|
|
49
|
+
|
|
50
|
+
**Supported languages:** typescript, javascript, python, java, kotlin, go, rust, csharp, cpp, ruby, php, swift, dart, scala, vue, svelte, html, css, yaml, shell, dockerfile (21 total)
|
|
51
|
+
|
|
52
|
+
```js
|
|
53
|
+
// By language name
|
|
54
|
+
extract(src, 'python');
|
|
55
|
+
|
|
56
|
+
// By file path (extension is used to detect language)
|
|
57
|
+
extract(src, 'src/server.ts');
|
|
58
|
+
extract(src, 'Dockerfile');
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
### `rank(query, sigIndex, opts?)` → `Result[]`
|
|
64
|
+
|
|
65
|
+
Rank all files in a signature index against a natural-language query.
|
|
66
|
+
|
|
67
|
+
| Param | Type | Description |
|
|
68
|
+
|---|---|---|
|
|
69
|
+
| `query` | `string` | Natural language or keyword query |
|
|
70
|
+
| `sigIndex` | `Map<string, string[]>` | File → signatures map (from `buildSigIndex`) |
|
|
71
|
+
| `opts.topK` | `number` | Max files to return (default: `10`) |
|
|
72
|
+
| `opts.weights` | `object` | Override default scoring weights |
|
|
73
|
+
| `opts.recencySet` | `Set<string>` | Files to boost with `recencyBoost` multiplier |
|
|
74
|
+
|
|
75
|
+
Each result: `{ file: string, score: number, sigs: string[], tokens: number }`
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
### `buildSigIndex(cwd)` → `Map<string, string[]>`
|
|
80
|
+
|
|
81
|
+
Build a file→signatures map from the generated `.github/copilot-instructions.md`.
|
|
82
|
+
Requires `node gen-context.js` to have been run first.
|
|
83
|
+
|
|
84
|
+
```js
|
|
85
|
+
const index = buildSigIndex('/path/to/project');
|
|
86
|
+
// → Map { 'src/extractors/python.js' => ['class Extractor', ' def extract(src)'], ... }
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
### `scan(sigs, filePath)` → `{ safe: string[], redacted: boolean }`
|
|
92
|
+
|
|
93
|
+
Scan signature strings for secrets (AWS keys, GitHub tokens, DB connection strings, etc.) and redact any matches.
|
|
94
|
+
|
|
95
|
+
```js
|
|
96
|
+
const { safe, redacted } = scan(
|
|
97
|
+
['const SECRET = "ghp_abc123xyz..."'],
|
|
98
|
+
'src/config.ts'
|
|
99
|
+
);
|
|
100
|
+
// safe → ['[REDACTED — GitHub Token detected in src/config.ts]']
|
|
101
|
+
// redacted → true
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
**Detected patterns:** AWS Access Key, AWS Secret Key, GCP API Key, GitHub Token, JWT Token, DB Connection String, SSH Private Key, Stripe Key, Twilio Key, Generic Secret
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
### `score(cwd)` → `HealthResult`
|
|
109
|
+
|
|
110
|
+
Compute a composite health score for the SigMap installation in a project.
|
|
111
|
+
|
|
112
|
+
```js
|
|
113
|
+
const health = score('/path/to/project');
|
|
114
|
+
// {
|
|
115
|
+
// score: 92,
|
|
116
|
+
// grade: 'A', // A ≥90 | B ≥75 | C ≥60 | D <60
|
|
117
|
+
// strategy: 'full',
|
|
118
|
+
// tokenReductionPct: 97.2,
|
|
119
|
+
// daysSinceRegen: 0.1,
|
|
120
|
+
// totalRuns: 48,
|
|
121
|
+
// overBudgetRuns: 0,
|
|
122
|
+
// }
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Migration from v2.3 and earlier
|
|
126
|
+
|
|
127
|
+
`require('sigmap')` was not available before v2.4. The programmatic API is new — no migration needed for CLI usage.
|
|
128
|
+
|
|
129
|
+
All existing CLI flags (`--generate`, `--watch`, `--mcp`, `--query`, `--analyze`, `--benchmark`, `--health`, …) are unchanged.
|
|
130
|
+
|
|
131
|
+
## Zero dependencies
|
|
132
|
+
|
|
133
|
+
This package has zero runtime npm dependencies. It uses only Node.js built-ins: `fs`, `path`.
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* sigmap-core — public programmatic API
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* const { extract, rank, scan, score } = require('sigmap');
|
|
8
|
+
*
|
|
9
|
+
* All functions are zero-dependency and never throw.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
const path = require('path');
|
|
13
|
+
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
// Language extractor registry
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
const EXT_MAP = {
|
|
18
|
+
'.ts': 'typescript', '.tsx': 'typescript',
|
|
19
|
+
'.js': 'javascript', '.jsx': 'javascript', '.mjs': 'javascript', '.cjs': 'javascript',
|
|
20
|
+
'.py': 'python', '.pyw': 'python',
|
|
21
|
+
'.java': 'java',
|
|
22
|
+
'.kt': 'kotlin', '.kts': 'kotlin',
|
|
23
|
+
'.go': 'go',
|
|
24
|
+
'.rs': 'rust',
|
|
25
|
+
'.cs': 'csharp',
|
|
26
|
+
'.cpp': 'cpp', '.c': 'cpp', '.h': 'cpp', '.hpp': 'cpp', '.cc': 'cpp',
|
|
27
|
+
'.rb': 'ruby', '.rake': 'ruby',
|
|
28
|
+
'.php': 'php',
|
|
29
|
+
'.swift': 'swift',
|
|
30
|
+
'.dart': 'dart',
|
|
31
|
+
'.scala': 'scala', '.sc': 'scala',
|
|
32
|
+
'.vue': 'vue',
|
|
33
|
+
'.svelte': 'svelte',
|
|
34
|
+
'.html': 'html', '.htm': 'html',
|
|
35
|
+
'.css': 'css', '.scss': 'css', '.sass': 'css', '.less': 'css',
|
|
36
|
+
'.yml': 'yaml', '.yaml': 'yaml',
|
|
37
|
+
'.sh': 'shell', '.bash': 'shell', '.zsh': 'shell', '.fish': 'shell',
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const SRC_ROOT = path.resolve(__dirname, '..', '..', 'src');
|
|
41
|
+
|
|
42
|
+
function _resolveExtractor(language) {
|
|
43
|
+
const extPath = path.join(SRC_ROOT, 'extractors', language + '.js');
|
|
44
|
+
try {
|
|
45
|
+
return require(extPath);
|
|
46
|
+
} catch (_) {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// ---------------------------------------------------------------------------
|
|
52
|
+
// extract(src, language) → string[]
|
|
53
|
+
// ---------------------------------------------------------------------------
|
|
54
|
+
/**
|
|
55
|
+
* Extract code signatures from source text for the given language.
|
|
56
|
+
*
|
|
57
|
+
* @param {string} src - Raw source file content
|
|
58
|
+
* @param {string} language - Language name (e.g. 'typescript', 'python')
|
|
59
|
+
* OR a file path/name with a recognised extension
|
|
60
|
+
* @returns {string[]} Array of signature strings (never throws)
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* const sigs = extract('function hello() {}', 'javascript');
|
|
64
|
+
* // → ['function hello()']
|
|
65
|
+
*
|
|
66
|
+
* const sigs2 = extract(src, 'src/server.ts');
|
|
67
|
+
* // → detected as typescript via extension
|
|
68
|
+
*/
|
|
69
|
+
function extract(src, language) {
|
|
70
|
+
if (!src || typeof src !== 'string') return [];
|
|
71
|
+
if (!language || typeof language !== 'string') return [];
|
|
72
|
+
|
|
73
|
+
// If language looks like a file path, derive language from extension
|
|
74
|
+
let lang = language;
|
|
75
|
+
if (language.includes('.') || language.includes('/') || language.includes('\\')) {
|
|
76
|
+
const ext = path.extname(language).toLowerCase();
|
|
77
|
+
const base = path.basename(language);
|
|
78
|
+
if (base === 'Dockerfile' || base.startsWith('Dockerfile.')) {
|
|
79
|
+
lang = 'dockerfile';
|
|
80
|
+
} else {
|
|
81
|
+
lang = EXT_MAP[ext] || null;
|
|
82
|
+
}
|
|
83
|
+
if (!lang) return [];
|
|
84
|
+
} else {
|
|
85
|
+
// Normalise e.g. 'JavaScript' → 'javascript'
|
|
86
|
+
lang = language.toLowerCase();
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const mod = _resolveExtractor(lang);
|
|
90
|
+
if (!mod || typeof mod.extract !== 'function') return [];
|
|
91
|
+
|
|
92
|
+
try {
|
|
93
|
+
const result = mod.extract(src);
|
|
94
|
+
return Array.isArray(result) ? result : [];
|
|
95
|
+
} catch (_) {
|
|
96
|
+
return [];
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// ---------------------------------------------------------------------------
|
|
101
|
+
// rank(query, sigIndex, opts?) → { file, score, sigs, tokens }[]
|
|
102
|
+
// ---------------------------------------------------------------------------
|
|
103
|
+
/**
|
|
104
|
+
* Rank files in a signature index against a natural-language query.
|
|
105
|
+
*
|
|
106
|
+
* @param {string} query - Natural language or keyword query
|
|
107
|
+
* @param {Map<string, string[]>} sigIndex - File → signatures map
|
|
108
|
+
* @param {object} [opts]
|
|
109
|
+
* @param {number} [opts.topK=10] - Maximum results to return
|
|
110
|
+
* @param {number} [opts.recencyBoost] - Score multiplier for recent files
|
|
111
|
+
* @param {Set<string>} [opts.recencySet] - Set of file paths considered recent
|
|
112
|
+
* @param {object} [opts.weights] - Override default scoring weights
|
|
113
|
+
* @returns {{ file: string, score: number, sigs: string[], tokens: number }[]}
|
|
114
|
+
*
|
|
115
|
+
* @example
|
|
116
|
+
* const { rank, buildSigIndex } = require('sigmap');
|
|
117
|
+
* const index = buildSigIndex('/path/to/project');
|
|
118
|
+
* const results = rank('add a new language extractor', index, { topK: 5 });
|
|
119
|
+
*/
|
|
120
|
+
function rank(query, sigIndex, opts) {
|
|
121
|
+
try {
|
|
122
|
+
const { rank: _rank } = require(path.join(SRC_ROOT, 'retrieval', 'ranker.js'));
|
|
123
|
+
return _rank(query, sigIndex, opts);
|
|
124
|
+
} catch (_) {
|
|
125
|
+
return [];
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// ---------------------------------------------------------------------------
|
|
130
|
+
// buildSigIndex(cwd) → Map<string, string[]>
|
|
131
|
+
// ---------------------------------------------------------------------------
|
|
132
|
+
/**
|
|
133
|
+
* Build a file→signatures index from the generated context file.
|
|
134
|
+
* Requires gen-context.js to have been run first.
|
|
135
|
+
*
|
|
136
|
+
* @param {string} cwd - Project root directory
|
|
137
|
+
* @returns {Map<string, string[]>}
|
|
138
|
+
*/
|
|
139
|
+
function buildSigIndex(cwd) {
|
|
140
|
+
try {
|
|
141
|
+
const { buildSigIndex: _build } = require(path.join(SRC_ROOT, 'retrieval', 'ranker.js'));
|
|
142
|
+
return _build(cwd);
|
|
143
|
+
} catch (_) {
|
|
144
|
+
return new Map();
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// ---------------------------------------------------------------------------
|
|
149
|
+
// scan(sigs, filePath) → { safe: string[], redacted: boolean }
|
|
150
|
+
// ---------------------------------------------------------------------------
|
|
151
|
+
/**
|
|
152
|
+
* Scan an array of signature strings for secrets and redact any matches.
|
|
153
|
+
*
|
|
154
|
+
* @param {string[]} sigs - Signature strings to scan
|
|
155
|
+
* @param {string} filePath - Source file path (used in redaction message)
|
|
156
|
+
* @returns {{ safe: string[], redacted: boolean }}
|
|
157
|
+
*
|
|
158
|
+
* @example
|
|
159
|
+
* const { safe, redacted } = scan(['const KEY = "AKIAEXAMPLE123..."'], 'config.js');
|
|
160
|
+
* // redacted === true — key was replaced with [REDACTED — AWS Access Key ...]
|
|
161
|
+
*/
|
|
162
|
+
function scan(sigs, filePath) {
|
|
163
|
+
try {
|
|
164
|
+
const { scan: _scan } = require(path.join(SRC_ROOT, 'security', 'scanner.js'));
|
|
165
|
+
return _scan(sigs, filePath);
|
|
166
|
+
} catch (_) {
|
|
167
|
+
return { safe: Array.isArray(sigs) ? sigs : [], redacted: false };
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// ---------------------------------------------------------------------------
|
|
172
|
+
// score(cwd) → { score, grade, ... }
|
|
173
|
+
// ---------------------------------------------------------------------------
|
|
174
|
+
/**
|
|
175
|
+
* Compute a composite health score for the project at cwd.
|
|
176
|
+
*
|
|
177
|
+
* @param {string} cwd - Project root directory
|
|
178
|
+
* @returns {{
|
|
179
|
+
* score: number,
|
|
180
|
+
* grade: 'A'|'B'|'C'|'D',
|
|
181
|
+
* strategy: string,
|
|
182
|
+
* tokenReductionPct: number|null,
|
|
183
|
+
* daysSinceRegen: number|null,
|
|
184
|
+
* totalRuns: number,
|
|
185
|
+
* overBudgetRuns: number,
|
|
186
|
+
* }}
|
|
187
|
+
*
|
|
188
|
+
* @example
|
|
189
|
+
* const health = score('/path/to/project');
|
|
190
|
+
* console.log(health.grade); // 'A'
|
|
191
|
+
*/
|
|
192
|
+
function score(cwd) {
|
|
193
|
+
try {
|
|
194
|
+
const { score: _score } = require(path.join(SRC_ROOT, 'health', 'scorer.js'));
|
|
195
|
+
return _score(cwd);
|
|
196
|
+
} catch (_) {
|
|
197
|
+
return { score: 0, grade: 'D', strategy: 'full', tokenReductionPct: null, daysSinceRegen: null, totalRuns: 0, overBudgetRuns: 0 };
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// ---------------------------------------------------------------------------
|
|
202
|
+
// Exports
|
|
203
|
+
// ---------------------------------------------------------------------------
|
|
204
|
+
module.exports = {
|
|
205
|
+
/** Extract signatures from source text */
|
|
206
|
+
extract,
|
|
207
|
+
/** Rank project files against a query */
|
|
208
|
+
rank,
|
|
209
|
+
/** Build a signature index from the generated context file */
|
|
210
|
+
buildSigIndex,
|
|
211
|
+
/** Scan signatures for secrets (redacts matches) */
|
|
212
|
+
scan,
|
|
213
|
+
/** Compute project health score */
|
|
214
|
+
score,
|
|
215
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "sigmap-core",
|
|
3
|
+
"version": "2.4.0",
|
|
4
|
+
"description": "SigMap core library — zero-dependency code signature extraction, retrieval, and security scanning",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"sigmap",
|
|
8
|
+
"ai-context",
|
|
9
|
+
"code-signatures",
|
|
10
|
+
"extraction",
|
|
11
|
+
"retrieval",
|
|
12
|
+
"zero-dependency"
|
|
13
|
+
],
|
|
14
|
+
"author": {
|
|
15
|
+
"name": "Manoj Mallick",
|
|
16
|
+
"url": "https://github.com/manojmallick"
|
|
17
|
+
},
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "https://github.com/manojmallick/sigmap.git",
|
|
21
|
+
"directory": "packages/core"
|
|
22
|
+
},
|
|
23
|
+
"homepage": "https://manojmallick.github.io/sigmap/",
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"engines": {
|
|
26
|
+
"node": ">=18.0.0"
|
|
27
|
+
}
|
|
28
|
+
}
|
package/src/config/defaults.js
CHANGED
|
@@ -92,6 +92,14 @@ const DEFAULTS = {
|
|
|
92
92
|
|
|
93
93
|
// Add reverse dependency usage hints on file headings (opt-in)
|
|
94
94
|
impactRadius: false,
|
|
95
|
+
|
|
96
|
+
// Query-aware retrieval settings (v2.3)
|
|
97
|
+
retrieval: {
|
|
98
|
+
// Maximum number of files to return for --query
|
|
99
|
+
topK: 10,
|
|
100
|
+
// Multiplier applied to recently-changed files (>1 boosts them up)
|
|
101
|
+
recencyBoost: 1.5,
|
|
102
|
+
},
|
|
95
103
|
};
|
|
96
104
|
|
|
97
105
|
module.exports = { DEFAULTS };
|
package/src/mcp/handlers.js
CHANGED
|
@@ -430,4 +430,31 @@ function listModules(args, cwd) {
|
|
|
430
430
|
].join('\n');
|
|
431
431
|
}
|
|
432
432
|
|
|
433
|
-
|
|
433
|
+
/**
|
|
434
|
+
* query_context({ query, topK? }) → string
|
|
435
|
+
*
|
|
436
|
+
* Ranks context-file entries by relevance to the query and returns the
|
|
437
|
+
* top-K most relevant files with their signatures and scores.
|
|
438
|
+
*/
|
|
439
|
+
function queryContext(args, cwd) {
|
|
440
|
+
if (!args || !args.query) return 'Missing required argument: query';
|
|
441
|
+
|
|
442
|
+
const contextPath = path.join(cwd, CONTEXT_FILE);
|
|
443
|
+
if (!fs.existsSync(contextPath)) {
|
|
444
|
+
return 'No context file found. Run: node gen-context.js';
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
try {
|
|
448
|
+
const { rank, buildSigIndex, formatRankTable } = require('../retrieval/ranker');
|
|
449
|
+
const index = buildSigIndex(cwd);
|
|
450
|
+
if (index.size === 0) return 'No signatures indexed. Run: node gen-context.js';
|
|
451
|
+
|
|
452
|
+
const topK = Math.min(Math.max(1, parseInt(args.topK, 10) || 10), 25);
|
|
453
|
+
const results = rank(args.query, index, { topK });
|
|
454
|
+
return formatRankTable(results, args.query);
|
|
455
|
+
} catch (err) {
|
|
456
|
+
return `_query_context failed: ${err.message}_`;
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
module.exports = { readContext, searchSignatures, getMap, createCheckpoint, getRouting, explainFile, listModules, queryContext };
|
package/src/mcp/server.js
CHANGED
|
@@ -14,11 +14,11 @@
|
|
|
14
14
|
|
|
15
15
|
const readline = require('readline');
|
|
16
16
|
const { TOOLS } = require('./tools');
|
|
17
|
-
const { readContext, searchSignatures, getMap, createCheckpoint, getRouting, explainFile, listModules } = require('./handlers');
|
|
17
|
+
const { readContext, searchSignatures, getMap, createCheckpoint, getRouting, explainFile, listModules, queryContext } = require('./handlers');
|
|
18
18
|
|
|
19
19
|
const SERVER_INFO = {
|
|
20
20
|
name: 'sigmap',
|
|
21
|
-
version: '2.
|
|
21
|
+
version: '2.4.0',
|
|
22
22
|
description: 'SigMap MCP server — code signatures on demand',
|
|
23
23
|
};
|
|
24
24
|
|
|
@@ -73,6 +73,7 @@ function dispatch(msg, cwd) {
|
|
|
73
73
|
else if (name === 'get_routing') text = getRouting(args, cwd);
|
|
74
74
|
else if (name === 'explain_file') text = explainFile(args, cwd);
|
|
75
75
|
else if (name === 'list_modules') text = listModules(args, cwd);
|
|
76
|
+
else if (name === 'query_context') text = queryContext(args, cwd);
|
|
76
77
|
else {
|
|
77
78
|
respondError(id, -32601, `Unknown tool: ${name}`);
|
|
78
79
|
return;
|
package/src/mcp/tools.js
CHANGED
|
@@ -120,6 +120,30 @@ const TOOLS = [
|
|
|
120
120
|
required: [],
|
|
121
121
|
},
|
|
122
122
|
},
|
|
123
|
+
{
|
|
124
|
+
name: 'query_context',
|
|
125
|
+
description:
|
|
126
|
+
'Rank and return the most relevant files for a specific task or question. ' +
|
|
127
|
+
'Uses keyword + symbol + path scoring to surface only the top-K files relevant ' +
|
|
128
|
+
'to the query — much cheaper than reading all context. ' +
|
|
129
|
+
'Returns ranked file list with signatures and relevance scores.',
|
|
130
|
+
inputSchema: {
|
|
131
|
+
type: 'object',
|
|
132
|
+
properties: {
|
|
133
|
+
query: {
|
|
134
|
+
type: 'string',
|
|
135
|
+
description:
|
|
136
|
+
'Natural language task description or keyword(s) to rank files against. ' +
|
|
137
|
+
'E.g. "add a new language extractor", "fix secret scanning", "auth module".',
|
|
138
|
+
},
|
|
139
|
+
topK: {
|
|
140
|
+
type: 'number',
|
|
141
|
+
description: 'Maximum number of files to return (default: 10, max: 25).',
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
required: ['query'],
|
|
145
|
+
},
|
|
146
|
+
},
|
|
123
147
|
];
|
|
124
148
|
|
|
125
149
|
module.exports = { TOOLS };
|