sigmap 4.2.0 → 4.3.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 +14 -0
- package/gen-context.js +92 -2
- package/package.json +1 -1
- package/packages/cli/package.json +1 -1
- package/packages/core/package.json +1 -1
- package/src/mcp/server.js +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,20 @@ Format: [Semantic Versioning](https://semver.org/)
|
|
|
10
10
|
|
|
11
11
|
---
|
|
12
12
|
|
|
13
|
+
## [4.3.0] — 2026-04-16
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- **`sigmap validate`** — validates config (srcDirs exist, exclude patterns, maxTokens range), computes coverage as sig-index size / total source files, warns when coverage < 70%, exits 1 on hard errors. Optional `--query "<q>"` checks that PascalCase/camelCase symbols in the query appear in top-5 ranked context. Supports `--json`.
|
|
18
|
+
- **`sigmap --ci [--min-coverage N] [--json]`** — GitHub Actions exit gate: exits 0 when coverage ≥ threshold (default 80%), exits 1 otherwise. Uses sig-index vs source file count for a budget-aware coverage metric. Ready for `npx sigmap --ci` in CI workflows.
|
|
19
|
+
- **`extractQuerySymbols(query)`** — internal helper that extracts PascalCase and camelCase identifiers from a query string for symbol-level coverage checks in `sigmap validate`.
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
- **`sigmap ask`** — now emits a stderr warning when coverage < 70%, pointing users to `sigmap validate` for diagnosis.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
13
27
|
## [4.2.0] — 2026-04-16
|
|
14
28
|
|
|
15
29
|
### Added
|
package/gen-context.js
CHANGED
|
@@ -4654,7 +4654,7 @@ __factories["./src/mcp/server"] = function(module, exports) {
|
|
|
4654
4654
|
|
|
4655
4655
|
const SERVER_INFO = {
|
|
4656
4656
|
name: 'sigmap',
|
|
4657
|
-
version: '4.
|
|
4657
|
+
version: '4.3.0',
|
|
4658
4658
|
description: 'SigMap MCP server — code signatures on demand',
|
|
4659
4659
|
};
|
|
4660
4660
|
|
|
@@ -6262,7 +6262,7 @@ const path = require('path');
|
|
|
6262
6262
|
const os = require('os');
|
|
6263
6263
|
const { execSync } = require('child_process');
|
|
6264
6264
|
|
|
6265
|
-
const VERSION = '4.
|
|
6265
|
+
const VERSION = '4.3.0';
|
|
6266
6266
|
const MARKER = '\n\n## Auto-generated signatures\n<!-- Updated by gen-context.js -->\n';
|
|
6267
6267
|
|
|
6268
6268
|
function requireSourceOrBundled(key) {
|
|
@@ -8004,6 +8004,10 @@ function getIntentWeights(intent) {
|
|
|
8004
8004
|
return base;
|
|
8005
8005
|
}
|
|
8006
8006
|
|
|
8007
|
+
function extractQuerySymbols(query) {
|
|
8008
|
+
return (query.match(/\b[A-Z][a-zA-Z]+|[a-z]+(?:[A-Z][a-z]+)+\b/g) || []);
|
|
8009
|
+
}
|
|
8010
|
+
|
|
8007
8011
|
function main() {
|
|
8008
8012
|
const args = process.argv.slice(2);
|
|
8009
8013
|
|
|
@@ -8132,6 +8136,9 @@ function main() {
|
|
|
8132
8136
|
riskLevel, contextPath: path.relative(cwd, outPath),
|
|
8133
8137
|
}) + '\n');
|
|
8134
8138
|
} else {
|
|
8139
|
+
if (coveragePct < 70) {
|
|
8140
|
+
process.stderr.write(`[sigmap] ⚠ coverage ${coveragePct}% — consider running: sigmap validate\n`);
|
|
8141
|
+
}
|
|
8135
8142
|
const bar = '─'.repeat(44);
|
|
8136
8143
|
console.log([
|
|
8137
8144
|
bar,
|
|
@@ -8247,6 +8254,65 @@ function main() {
|
|
|
8247
8254
|
process.exit(0);
|
|
8248
8255
|
}
|
|
8249
8256
|
|
|
8257
|
+
// v4.3: `sigmap validate` — config + coverage + optional query symbol check
|
|
8258
|
+
if (args[0] === 'validate') {
|
|
8259
|
+
const issues = [];
|
|
8260
|
+
const warnings = [];
|
|
8261
|
+
|
|
8262
|
+
// Config checks
|
|
8263
|
+
for (const d of (config.srcDirs || [])) {
|
|
8264
|
+
if (!fs.existsSync(path.join(cwd, d)))
|
|
8265
|
+
issues.push(`srcDir '${d}' does not exist`);
|
|
8266
|
+
}
|
|
8267
|
+
if ((config.exclude || []).some((p) => p === 'src/**'))
|
|
8268
|
+
issues.push(`exclude pattern 'src/**' will exclude all source files`);
|
|
8269
|
+
if ((config.maxTokens || 0) < 1000)
|
|
8270
|
+
warnings.push(`maxTokens ${config.maxTokens} is very low — consider ≥ 4000`);
|
|
8271
|
+
if ((config.maxTokens || 0) > 50000)
|
|
8272
|
+
warnings.push(`maxTokens ${config.maxTokens} is very high — may exceed LLM context windows`);
|
|
8273
|
+
|
|
8274
|
+
// Coverage check: files actually in context vs total source files
|
|
8275
|
+
const { buildSigIndex: valBuildSigIndex } = requireSourceOrBundled('./src/retrieval/ranker');
|
|
8276
|
+
const valSigIndex = valBuildSigIndex(cwd);
|
|
8277
|
+
const valTotal = buildFileList(cwd, config).length;
|
|
8278
|
+
const coveragePct = valTotal > 0 ? Math.round((valSigIndex.size / valTotal) * 100) : 0;
|
|
8279
|
+
if (coveragePct < 70)
|
|
8280
|
+
warnings.push(`coverage ${coveragePct}% is below recommended 70% — increase maxTokens or expand srcDirs`);
|
|
8281
|
+
|
|
8282
|
+
// Optional query symbol check
|
|
8283
|
+
const valQueryIdx = args.indexOf('--query');
|
|
8284
|
+
if (valQueryIdx !== -1) {
|
|
8285
|
+
const q = (args[valQueryIdx + 1] || '').trim();
|
|
8286
|
+
if (q && !q.startsWith('--')) {
|
|
8287
|
+
try {
|
|
8288
|
+
const { rank, buildSigIndex } = requireSourceOrBundled('./src/retrieval/ranker');
|
|
8289
|
+
const ranked = rank(q, buildSigIndex(cwd), { topK: 5 });
|
|
8290
|
+
const symbols = extractQuerySymbols(q);
|
|
8291
|
+
const missing = symbols.filter((sym) =>
|
|
8292
|
+
!ranked.some((r) => r.sigs && r.sigs.some((s) => s.toLowerCase().includes(sym.toLowerCase())))
|
|
8293
|
+
);
|
|
8294
|
+
if (missing.length > 0)
|
|
8295
|
+
warnings.push(`query "${q}" references symbols not in top-5 context: ${missing.join(', ')}`);
|
|
8296
|
+
else if (symbols.length > 0)
|
|
8297
|
+
console.log(`[sigmap] ✓ query coverage OK — all ${symbols.length} symbols found`);
|
|
8298
|
+
} catch (_) {}
|
|
8299
|
+
}
|
|
8300
|
+
}
|
|
8301
|
+
|
|
8302
|
+
if (args.includes('--json')) {
|
|
8303
|
+
process.stdout.write(JSON.stringify({ valid: issues.length === 0, issues, warnings, coverage: coveragePct }) + '\n');
|
|
8304
|
+
} else {
|
|
8305
|
+
for (const w of warnings) console.warn(`[sigmap] ⚠ ${w}`);
|
|
8306
|
+
if (issues.length === 0) {
|
|
8307
|
+
console.log(`[sigmap] ✓ config valid coverage: ${coveragePct}%`);
|
|
8308
|
+
} else {
|
|
8309
|
+
for (const iss of issues) console.error(`[sigmap] ✗ ${iss}`);
|
|
8310
|
+
process.exit(1);
|
|
8311
|
+
}
|
|
8312
|
+
}
|
|
8313
|
+
process.exit(0);
|
|
8314
|
+
}
|
|
8315
|
+
|
|
8250
8316
|
// Feature 6: `sigmap sync` — write all outputs + llms.txt + print compact diff
|
|
8251
8317
|
if (args[0] === 'sync') {
|
|
8252
8318
|
try {
|
|
@@ -8912,6 +8978,30 @@ function main() {
|
|
|
8912
8978
|
process.exit(0);
|
|
8913
8979
|
}
|
|
8914
8980
|
|
|
8981
|
+
// v4.3: `--ci [--min-coverage N] [--json]` — GitHub Actions exit gate
|
|
8982
|
+
if (args.includes('--ci')) {
|
|
8983
|
+
const minCovIdx = args.indexOf('--min-coverage');
|
|
8984
|
+
const minCoverage = minCovIdx !== -1 ? Math.max(0, Math.min(100, parseInt(args[minCovIdx + 1], 10) || 80)) : 80;
|
|
8985
|
+
|
|
8986
|
+
// Coverage = files actually in context / total source files
|
|
8987
|
+
const { buildSigIndex: ciBuildSigIndex } = requireSourceOrBundled('./src/retrieval/ranker');
|
|
8988
|
+
const ciSigIndex = ciBuildSigIndex(cwd);
|
|
8989
|
+
const ciTotal = buildFileList(cwd, config).length;
|
|
8990
|
+
const coveragePct = ciTotal > 0 ? Math.round((ciSigIndex.size / ciTotal) * 100) : 0;
|
|
8991
|
+
|
|
8992
|
+
const pass = coveragePct >= minCoverage;
|
|
8993
|
+
|
|
8994
|
+
if (args.includes('--json')) {
|
|
8995
|
+
process.stdout.write(JSON.stringify({ pass, coverage: coveragePct, threshold: minCoverage }) + '\n');
|
|
8996
|
+
} else if (pass) {
|
|
8997
|
+
console.log(`[sigmap] ✓ CI gate passed — coverage ${coveragePct}% ≥ ${minCoverage}%`);
|
|
8998
|
+
} else {
|
|
8999
|
+
console.error(`[sigmap] ✗ CI gate FAILED — coverage ${coveragePct}% < ${minCoverage}%`);
|
|
9000
|
+
console.error(` Fix: increase maxTokens or expand srcDirs in gen-context.config.json`);
|
|
9001
|
+
}
|
|
9002
|
+
process.exit(pass ? 0 : 1);
|
|
9003
|
+
}
|
|
9004
|
+
|
|
8915
9005
|
// Default: generate once
|
|
8916
9006
|
runGenerate(cwd, config, false);
|
|
8917
9007
|
}
|
package/package.json
CHANGED
package/src/mcp/server.js
CHANGED