sigmap 7.16.0 → 7.18.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 +18 -0
- package/gen-context.js +167 -2
- package/llms-full.txt +1 -1
- package/llms.txt +1 -1
- package/package.json +1 -1
- package/packages/cli/package.json +1 -1
- package/packages/core/package.json +1 -1
- package/src/conventions/fix.js +58 -0
- package/src/conventions/update.js +46 -0
- package/src/mcp/server.js +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,24 @@ Format: [Semantic Versioning](https://semver.org/)
|
|
|
10
10
|
|
|
11
11
|
---
|
|
12
12
|
|
|
13
|
+
## [7.18.0] — 2026-06-18
|
|
14
|
+
|
|
15
|
+
Minor release — `sigmap conventions --update` (grounded codegen, Layer 3 — completes the §4 flag set).
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
- **`sigmap conventions --update` — incremental rescan (#331):** refreshes `.context/conventions.json` only when source files have changed since the last scan; otherwise reports "up to date" and exits without recomputing. New zero-dependency, bundle-safe `src/conventions/update.js` (`changedSince`, `planUpdate`) compares source-file mtimes to the stored snapshot — `stale` when the snapshot is missing or any file is newer. The command re-extracts + rewrites when stale (reporting the changed count / "initial scan"), else skips the work. `--json` for machine output. This completes the IMPL §4 `conventions` flag set: `--conflicts`, `--inject`, `--report`, `--ci`, `--fix`, `--update`.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## [7.17.0] — 2026-06-18
|
|
23
|
+
|
|
24
|
+
Minor release — `sigmap conventions --fix` (grounded codegen, Layer 3 — completes the conventions flags).
|
|
25
|
+
|
|
26
|
+
### Added
|
|
27
|
+
- **`sigmap conventions --fix` — exhaustive rename/move checklist (#328):** the complete, actionable list of every source file whose name doesn't match the dominant convention, with full from→to paths, ready to paste into a task or PR. Distinct from `--conflicts` (a diagnostic summary with up to 3 example basenames) — `--fix` lists *every* offending file with its real path. New zero-dependency, bundle-safe `src/conventions/fix.js` (`buildFixList`) reuses `classifyNaming` + `toNamingStyle`; the command prints a checkbox checklist + count (or "no fixes needed") and is read-only (it never performs renames). `--json` for machine output. This completes the `conventions` flag set (`--conflicts`, `--inject`, `--report`, `--ci`, `--fix`).
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
13
31
|
## [7.16.0] — 2026-06-18
|
|
14
32
|
|
|
15
33
|
Minor release — LLM A/B hallucination ablation harness (grounded codegen, IMPL §9).
|
package/gen-context.js
CHANGED
|
@@ -32,6 +32,118 @@ function __require(key) {
|
|
|
32
32
|
// ── ./src/conventions/report ──
|
|
33
33
|
// ── ./src/conventions/ci ──
|
|
34
34
|
// ── ./src/eval/llm-ablation ──
|
|
35
|
+
// ── ./src/conventions/fix ──
|
|
36
|
+
// ── ./src/conventions/update ──
|
|
37
|
+
__factories["./src/conventions/update"] = function(module, exports) {
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Convention incremental rescan (IMPL.md §4 — `conventions --update`).
|
|
41
|
+
*
|
|
42
|
+
* Avoids recomputing the conventions snapshot when nothing changed: compare the
|
|
43
|
+
* source files' mtimes to the stored `.context/conventions.json` and only flag a
|
|
44
|
+
* rescan when the snapshot is missing or some file is newer. Pure (fs reads
|
|
45
|
+
* only), zero-dependency, bundle-safe.
|
|
46
|
+
*/
|
|
47
|
+
|
|
48
|
+
const fs = require('fs');
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Source files modified after a reference time.
|
|
52
|
+
* @param {string[]} files absolute paths
|
|
53
|
+
* @param {number} sinceMs epoch ms threshold
|
|
54
|
+
* @returns {string[]}
|
|
55
|
+
*/
|
|
56
|
+
function changedSince(files, sinceMs) {
|
|
57
|
+
const out = [];
|
|
58
|
+
for (const f of files || []) {
|
|
59
|
+
try { if (fs.statSync(f).mtimeMs > sinceMs) out.push(f); } catch (_) {}
|
|
60
|
+
}
|
|
61
|
+
return out;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Decide whether the conventions snapshot needs a rescan.
|
|
66
|
+
* @param {string} cwd repo root (unused but kept for signature symmetry)
|
|
67
|
+
* @param {string[]} files absolute source paths
|
|
68
|
+
* @param {string} snapshotPath path to the stored conventions.json
|
|
69
|
+
* @returns {{ snapshotExists: boolean, stale: boolean, changed: string[] }}
|
|
70
|
+
*/
|
|
71
|
+
function planUpdate(cwd, files, snapshotPath) {
|
|
72
|
+
let snapshotMs = null;
|
|
73
|
+
try { snapshotMs = fs.statSync(snapshotPath).mtimeMs; } catch (_) {}
|
|
74
|
+
const snapshotExists = snapshotMs != null;
|
|
75
|
+
if (!snapshotExists) {
|
|
76
|
+
return { snapshotExists: false, stale: true, changed: [] };
|
|
77
|
+
}
|
|
78
|
+
const changed = changedSince(files, snapshotMs);
|
|
79
|
+
return { snapshotExists: true, stale: changed.length > 0, changed };
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
module.exports = { changedSince, planUpdate };
|
|
83
|
+
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
__factories["./src/conventions/fix"] = function(module, exports) {
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Convention fix list (IMPL.md §4 — `conventions --fix`).
|
|
90
|
+
*
|
|
91
|
+
* The complete, actionable rename checklist: every scoped source file whose
|
|
92
|
+
* name doesn't match the dominant file-naming convention, with full from→to
|
|
93
|
+
* paths. Distinct from `--conflicts` (a diagnostic summary with up to 3 example
|
|
94
|
+
* basenames) — `--fix` lists *every* offending file with its real path, ready
|
|
95
|
+
* to paste into a task or PR. Pure, zero-dependency, bundle-safe.
|
|
96
|
+
*/
|
|
97
|
+
|
|
98
|
+
const path = require('path');
|
|
99
|
+
const { classifyNaming } = __require('./src/conventions/extract');
|
|
100
|
+
const { toNamingStyle } = __require('./src/conventions/conflicts');
|
|
101
|
+
|
|
102
|
+
const JS_TS_EXTS = new Set(['.js', '.jsx', '.ts', '.tsx', '.mjs', '.cjs']);
|
|
103
|
+
const PY_EXTS = new Set(['.py']);
|
|
104
|
+
const SCOPED_EXTS = new Set([...JS_TS_EXTS, ...PY_EXTS]);
|
|
105
|
+
|
|
106
|
+
const TEST_RE = /\.(test|spec)\.[jt]sx?$|(^|\/)test_|_test\.py$/;
|
|
107
|
+
|
|
108
|
+
/** Rename a file path's basename to the target naming style (keep dir + ext). */
|
|
109
|
+
function _renamePath(relPath, style) {
|
|
110
|
+
const dir = relPath.includes('/') ? relPath.slice(0, relPath.lastIndexOf('/') + 1) : '';
|
|
111
|
+
const base = relPath.includes('/') ? relPath.slice(relPath.lastIndexOf('/') + 1) : relPath;
|
|
112
|
+
const dot = base.indexOf('.');
|
|
113
|
+
const stem = dot > 0 ? base.slice(0, dot) : base;
|
|
114
|
+
const ext = dot > 0 ? base.slice(dot) : '';
|
|
115
|
+
return `${dir}${toNamingStyle(stem, style)}${ext}`;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Build the exhaustive rename checklist for the dominant file-naming convention.
|
|
120
|
+
* @param {string} cwd repo root (for relative paths)
|
|
121
|
+
* @param {string[]} files absolute source paths (e.g. from buildFileList)
|
|
122
|
+
* @param {object} conventions an `extractConventions` result (for the dominant style)
|
|
123
|
+
* @returns {{ dominant: string|null, renames: Array<{from:string,to:string,fromStyle:string}>, count: number }}
|
|
124
|
+
*/
|
|
125
|
+
function buildFixList(cwd, files, conventions) {
|
|
126
|
+
const dominant = conventions && conventions.fileNaming && conventions.fileNaming.dominant;
|
|
127
|
+
if (!dominant) return { dominant: null, renames: [], count: 0 };
|
|
128
|
+
|
|
129
|
+
const renames = [];
|
|
130
|
+
for (const f of files || []) {
|
|
131
|
+
if (!SCOPED_EXTS.has(path.extname(f).toLowerCase())) continue;
|
|
132
|
+
if (TEST_RE.test(f)) continue;
|
|
133
|
+
const base = path.basename(f);
|
|
134
|
+
const style = classifyNaming(base);
|
|
135
|
+
if (style === 'other' || style === dominant) continue;
|
|
136
|
+
const rel = path.relative(cwd, f).replace(/\\/g, '/');
|
|
137
|
+
renames.push({ from: rel, to: _renamePath(rel, dominant), fromStyle: style });
|
|
138
|
+
}
|
|
139
|
+
renames.sort((a, b) => a.from.localeCompare(b.from));
|
|
140
|
+
return { dominant, renames, count: renames.length };
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
module.exports = { buildFixList };
|
|
144
|
+
|
|
145
|
+
};
|
|
146
|
+
|
|
35
147
|
__factories["./src/eval/llm-ablation"] = function(module, exports) {
|
|
36
148
|
|
|
37
149
|
/**
|
|
@@ -7707,7 +7819,7 @@ __factories["./src/mcp/server"] = function(module, exports) {
|
|
|
7707
7819
|
|
|
7708
7820
|
const SERVER_INFO = {
|
|
7709
7821
|
name: 'sigmap',
|
|
7710
|
-
version: '7.
|
|
7822
|
+
version: '7.18.0',
|
|
7711
7823
|
description: 'SigMap MCP server — code signatures on demand',
|
|
7712
7824
|
};
|
|
7713
7825
|
|
|
@@ -13385,7 +13497,7 @@ function __tryGit(args, opts = {}) {
|
|
|
13385
13497
|
catch (_) { return ''; }
|
|
13386
13498
|
}
|
|
13387
13499
|
|
|
13388
|
-
const VERSION = '7.
|
|
13500
|
+
const VERSION = '7.18.0';
|
|
13389
13501
|
const MARKER = '\n\n## Auto-generated signatures\n<!-- Updated by gen-context.js -->\n';
|
|
13390
13502
|
|
|
13391
13503
|
function requireSourceOrBundled(key) {
|
|
@@ -16580,6 +16692,59 @@ function main() {
|
|
|
16580
16692
|
process.exit(0);
|
|
16581
16693
|
}
|
|
16582
16694
|
|
|
16695
|
+
// `--update`: incremental rescan — refresh .context/conventions.json only when stale.
|
|
16696
|
+
if (args.includes('--update')) {
|
|
16697
|
+
const { planUpdate } = requireSourceOrBundled('./src/conventions/update');
|
|
16698
|
+
const outDir = path.join(cwd, '.context');
|
|
16699
|
+
const outPath = path.join(outDir, 'conventions.json');
|
|
16700
|
+
const plan = planUpdate(cwd, files, outPath);
|
|
16701
|
+
let wrote = false;
|
|
16702
|
+
if (plan.stale) {
|
|
16703
|
+
try {
|
|
16704
|
+
fs.mkdirSync(outDir, { recursive: true });
|
|
16705
|
+
fs.writeFileSync(outPath, JSON.stringify(result, null, 2) + '\n');
|
|
16706
|
+
wrote = true;
|
|
16707
|
+
} catch (e) {
|
|
16708
|
+
console.error(`[sigmap] cannot write ${outPath}: ${e.message}`);
|
|
16709
|
+
process.exit(1);
|
|
16710
|
+
}
|
|
16711
|
+
}
|
|
16712
|
+
const payload = { stale: plan.stale, wrote, snapshotExists: plan.snapshotExists, changed: plan.changed.length, scanned: result.scannedFiles };
|
|
16713
|
+
if (jsonOut) {
|
|
16714
|
+
process.stdout.write(JSON.stringify(payload) + '\n');
|
|
16715
|
+
process.exit(0);
|
|
16716
|
+
}
|
|
16717
|
+
if (!plan.stale) {
|
|
16718
|
+
console.log(`[sigmap] conventions --update ✓ up to date — ${result.scannedFiles} files, no changes since last scan`);
|
|
16719
|
+
process.exit(0);
|
|
16720
|
+
}
|
|
16721
|
+
const how = plan.snapshotExists ? `${plan.changed.length} changed file${plan.changed.length === 1 ? '' : 's'}` : 'initial scan';
|
|
16722
|
+
console.log(`[sigmap] conventions --update rescanned (${how}) → wrote ${path.relative(cwd, outPath)}`);
|
|
16723
|
+
process.exit(0);
|
|
16724
|
+
}
|
|
16725
|
+
|
|
16726
|
+
// `--fix`: exhaustive rename checklist — every file not matching the dominant style.
|
|
16727
|
+
if (args.includes('--fix')) {
|
|
16728
|
+
const { buildFixList } = requireSourceOrBundled('./src/conventions/fix');
|
|
16729
|
+
const fixList = buildFixList(cwd, files, result);
|
|
16730
|
+
if (jsonOut) {
|
|
16731
|
+
process.stdout.write(JSON.stringify(fixList) + '\n');
|
|
16732
|
+
process.exit(0);
|
|
16733
|
+
}
|
|
16734
|
+
console.log('[sigmap] conventions --fix (TS/JS/Python)');
|
|
16735
|
+
if (!fixList.dominant) {
|
|
16736
|
+
console.log(' no dominant file-naming convention — nothing to fix');
|
|
16737
|
+
process.exit(0);
|
|
16738
|
+
}
|
|
16739
|
+
if (fixList.count === 0) {
|
|
16740
|
+
console.log(` ✓ no fixes needed — every file matches ${fixList.dominant}`);
|
|
16741
|
+
process.exit(0);
|
|
16742
|
+
}
|
|
16743
|
+
console.log(` ${fixList.count} file${fixList.count === 1 ? '' : 's'} to rename to ${fixList.dominant}:`);
|
|
16744
|
+
for (const r of fixList.renames) console.log(` - [ ] ${r.from} → ${r.to}`);
|
|
16745
|
+
process.exit(0);
|
|
16746
|
+
}
|
|
16747
|
+
|
|
16583
16748
|
// `--ci`: gate — fail when overall consistency is below a threshold (or regresses).
|
|
16584
16749
|
if (args.includes('--ci')) {
|
|
16585
16750
|
const { ciGate } = requireSourceOrBundled('./src/conventions/ci');
|
package/llms-full.txt
CHANGED
|
@@ -9,7 +9,7 @@ the files relevant to the task — cutting tokens ~97% while keeping answers
|
|
|
9
9
|
grounded. Deterministic, offline, no embeddings or vector database. Works with
|
|
10
10
|
Claude, Cursor, GitHub Copilot, Aider, Windsurf, local LLMs, and MCP.
|
|
11
11
|
|
|
12
|
-
# Version: 7.
|
|
12
|
+
# Version: 7.18.0 | Benchmark: sigmap-v7.0-main (2026-06-14)
|
|
13
13
|
# Source: auto-generated from package.json, version.json, src/mcp/tools.js, src/config/defaults.js
|
|
14
14
|
# Regenerate: npm run generate:llms | Validate: npm run validate:llms
|
|
15
15
|
|
package/llms.txt
CHANGED
|
@@ -9,7 +9,7 @@ the files relevant to the task — cutting tokens ~97% while keeping answers
|
|
|
9
9
|
grounded. Deterministic, offline, no embeddings or vector database. Works with
|
|
10
10
|
Claude, Cursor, GitHub Copilot, Aider, Windsurf, local LLMs, and MCP.
|
|
11
11
|
|
|
12
|
-
# Version: 7.
|
|
12
|
+
# Version: 7.18.0 | Benchmark: sigmap-v7.0-main (2026-06-14)
|
|
13
13
|
# Source: auto-generated from package.json, version.json, src/mcp/tools.js, src/config/defaults.js
|
|
14
14
|
# Regenerate: npm run generate:llms | Validate: npm run validate:llms
|
|
15
15
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sigmap",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.18.0",
|
|
4
4
|
"description": "97% token reduction for AI coding. Extracts function & class signatures with TF-IDF ranking to feed only the right files to Claude, Cursor, Copilot, Aider, Windsurf, local LLMs & MCP. Zero dependencies, runs offline via npx.",
|
|
5
5
|
"main": "packages/core/index.js",
|
|
6
6
|
"exports": {
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Convention fix list (IMPL.md §4 — `conventions --fix`).
|
|
5
|
+
*
|
|
6
|
+
* The complete, actionable rename checklist: every scoped source file whose
|
|
7
|
+
* name doesn't match the dominant file-naming convention, with full from→to
|
|
8
|
+
* paths. Distinct from `--conflicts` (a diagnostic summary with up to 3 example
|
|
9
|
+
* basenames) — `--fix` lists *every* offending file with its real path, ready
|
|
10
|
+
* to paste into a task or PR. Pure, zero-dependency, bundle-safe.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const path = require('path');
|
|
14
|
+
const { classifyNaming } = require('./extract');
|
|
15
|
+
const { toNamingStyle } = require('./conflicts');
|
|
16
|
+
|
|
17
|
+
const JS_TS_EXTS = new Set(['.js', '.jsx', '.ts', '.tsx', '.mjs', '.cjs']);
|
|
18
|
+
const PY_EXTS = new Set(['.py']);
|
|
19
|
+
const SCOPED_EXTS = new Set([...JS_TS_EXTS, ...PY_EXTS]);
|
|
20
|
+
|
|
21
|
+
const TEST_RE = /\.(test|spec)\.[jt]sx?$|(^|\/)test_|_test\.py$/;
|
|
22
|
+
|
|
23
|
+
/** Rename a file path's basename to the target naming style (keep dir + ext). */
|
|
24
|
+
function _renamePath(relPath, style) {
|
|
25
|
+
const dir = relPath.includes('/') ? relPath.slice(0, relPath.lastIndexOf('/') + 1) : '';
|
|
26
|
+
const base = relPath.includes('/') ? relPath.slice(relPath.lastIndexOf('/') + 1) : relPath;
|
|
27
|
+
const dot = base.indexOf('.');
|
|
28
|
+
const stem = dot > 0 ? base.slice(0, dot) : base;
|
|
29
|
+
const ext = dot > 0 ? base.slice(dot) : '';
|
|
30
|
+
return `${dir}${toNamingStyle(stem, style)}${ext}`;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Build the exhaustive rename checklist for the dominant file-naming convention.
|
|
35
|
+
* @param {string} cwd repo root (for relative paths)
|
|
36
|
+
* @param {string[]} files absolute source paths (e.g. from buildFileList)
|
|
37
|
+
* @param {object} conventions an `extractConventions` result (for the dominant style)
|
|
38
|
+
* @returns {{ dominant: string|null, renames: Array<{from:string,to:string,fromStyle:string}>, count: number }}
|
|
39
|
+
*/
|
|
40
|
+
function buildFixList(cwd, files, conventions) {
|
|
41
|
+
const dominant = conventions && conventions.fileNaming && conventions.fileNaming.dominant;
|
|
42
|
+
if (!dominant) return { dominant: null, renames: [], count: 0 };
|
|
43
|
+
|
|
44
|
+
const renames = [];
|
|
45
|
+
for (const f of files || []) {
|
|
46
|
+
if (!SCOPED_EXTS.has(path.extname(f).toLowerCase())) continue;
|
|
47
|
+
if (TEST_RE.test(f)) continue;
|
|
48
|
+
const base = path.basename(f);
|
|
49
|
+
const style = classifyNaming(base);
|
|
50
|
+
if (style === 'other' || style === dominant) continue;
|
|
51
|
+
const rel = path.relative(cwd, f).replace(/\\/g, '/');
|
|
52
|
+
renames.push({ from: rel, to: _renamePath(rel, dominant), fromStyle: style });
|
|
53
|
+
}
|
|
54
|
+
renames.sort((a, b) => a.from.localeCompare(b.from));
|
|
55
|
+
return { dominant, renames, count: renames.length };
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
module.exports = { buildFixList };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Convention incremental rescan (IMPL.md §4 — `conventions --update`).
|
|
5
|
+
*
|
|
6
|
+
* Avoids recomputing the conventions snapshot when nothing changed: compare the
|
|
7
|
+
* source files' mtimes to the stored `.context/conventions.json` and only flag a
|
|
8
|
+
* rescan when the snapshot is missing or some file is newer. Pure (fs reads
|
|
9
|
+
* only), zero-dependency, bundle-safe.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
const fs = require('fs');
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Source files modified after a reference time.
|
|
16
|
+
* @param {string[]} files absolute paths
|
|
17
|
+
* @param {number} sinceMs epoch ms threshold
|
|
18
|
+
* @returns {string[]}
|
|
19
|
+
*/
|
|
20
|
+
function changedSince(files, sinceMs) {
|
|
21
|
+
const out = [];
|
|
22
|
+
for (const f of files || []) {
|
|
23
|
+
try { if (fs.statSync(f).mtimeMs > sinceMs) out.push(f); } catch (_) {}
|
|
24
|
+
}
|
|
25
|
+
return out;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Decide whether the conventions snapshot needs a rescan.
|
|
30
|
+
* @param {string} cwd repo root (unused but kept for signature symmetry)
|
|
31
|
+
* @param {string[]} files absolute source paths
|
|
32
|
+
* @param {string} snapshotPath path to the stored conventions.json
|
|
33
|
+
* @returns {{ snapshotExists: boolean, stale: boolean, changed: string[] }}
|
|
34
|
+
*/
|
|
35
|
+
function planUpdate(cwd, files, snapshotPath) {
|
|
36
|
+
let snapshotMs = null;
|
|
37
|
+
try { snapshotMs = fs.statSync(snapshotPath).mtimeMs; } catch (_) {}
|
|
38
|
+
const snapshotExists = snapshotMs != null;
|
|
39
|
+
if (!snapshotExists) {
|
|
40
|
+
return { snapshotExists: false, stale: true, changed: [] };
|
|
41
|
+
}
|
|
42
|
+
const changed = changedSince(files, snapshotMs);
|
|
43
|
+
return { snapshotExists: true, stale: changed.length > 0, changed };
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
module.exports = { changedSince, planUpdate };
|
package/src/mcp/server.js
CHANGED