sigmap 7.17.0 → 7.19.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 +146 -3
- 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/update.js +46 -0
- package/src/mcp/server.js +1 -1
- package/src/scaffold/persist.js +45 -0
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,24 @@ Format: [Semantic Versioning](https://semver.org/)
|
|
|
10
10
|
|
|
11
11
|
---
|
|
12
12
|
|
|
13
|
+
## [7.19.0] — 2026-06-18
|
|
14
|
+
|
|
15
|
+
Minor release — scaffold persistence (grounded codegen, Gap 2 §6.2).
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
- **Scaffold persistence — `.context/scaffold/latest.md` (#334):** `sigmap scaffold` now writes an accepted proposal to `.context/scaffold/latest.md` so the `create` pipeline and agents can read back the convention-matched proposal instead of re-deriving it. New zero-dependency, bundle-safe `src/scaffold/persist.js` (`renderScaffoldMarkdown`, `scaffoldPath`); the record captures the filename + naming style, export style, test file + framework, and any force-warning. Persisted in both human and `--json` modes (the JSON output gains a `persistedTo` field); a refused scaffold writes nothing.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## [7.18.0] — 2026-06-18
|
|
23
|
+
|
|
24
|
+
Minor release — `sigmap conventions --update` (grounded codegen, Layer 3 — completes the §4 flag set).
|
|
25
|
+
|
|
26
|
+
### Added
|
|
27
|
+
- **`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`.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
13
31
|
## [7.17.0] — 2026-06-18
|
|
14
32
|
|
|
15
33
|
Minor release — `sigmap conventions --fix` (grounded codegen, Layer 3 — completes the conventions flags).
|
package/gen-context.js
CHANGED
|
@@ -33,6 +33,105 @@ function __require(key) {
|
|
|
33
33
|
// ── ./src/conventions/ci ──
|
|
34
34
|
// ── ./src/eval/llm-ablation ──
|
|
35
35
|
// ── ./src/conventions/fix ──
|
|
36
|
+
// ── ./src/conventions/update ──
|
|
37
|
+
// ── ./src/scaffold/persist ──
|
|
38
|
+
__factories["./src/scaffold/persist"] = function(module, exports) {
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Scaffold persistence (IMPL.md §6.2 — 2d).
|
|
42
|
+
*
|
|
43
|
+
* Renders an accepted scaffold proposal to markdown and locates the on-disk
|
|
44
|
+
* record (`.context/scaffold/latest.md`) so the `create` pipeline and agents can
|
|
45
|
+
* read back the convention-matched proposal. Pure render; zero-dependency,
|
|
46
|
+
* bundle-safe.
|
|
47
|
+
*/
|
|
48
|
+
|
|
49
|
+
const path = require('path');
|
|
50
|
+
|
|
51
|
+
/** Path to the persisted scaffold record. */
|
|
52
|
+
function scaffoldPath(cwd) {
|
|
53
|
+
return path.join(cwd, '.context', 'scaffold', 'latest.md');
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Render an accepted scaffold decision to a markdown record.
|
|
58
|
+
* @param {object} decision a `proposeScaffold` result with `ok: true`
|
|
59
|
+
* @param {object} [opts]
|
|
60
|
+
* @param {string} [opts.timestamp] ISO timestamp (caller supplies — keeps this pure)
|
|
61
|
+
* @returns {string}
|
|
62
|
+
*/
|
|
63
|
+
function renderScaffoldMarkdown(decision, opts = {}) {
|
|
64
|
+
const d = decision || {};
|
|
65
|
+
const p = d.proposal || {};
|
|
66
|
+
const pct = (n) => `${Math.round((n || 0) * 100)}%`;
|
|
67
|
+
const lines = [
|
|
68
|
+
`# Scaffold — ${d.name || '(unnamed)'}`,
|
|
69
|
+
'',
|
|
70
|
+
`- **Conventions:** ${d.tier || 'unknown'} (${pct(d.confidence)})`,
|
|
71
|
+
`- **File:** \`${p.filename || ''}\` (${p.namingStyle || ''})`,
|
|
72
|
+
`- **Export style:** ${p.exportStyle || ''}`,
|
|
73
|
+
`- **Test file:** \`${p.testFile || ''}\`${p.testFramework ? ` (${p.testFramework})` : ''}`,
|
|
74
|
+
];
|
|
75
|
+
if (d.warning) lines.push(`- **Warning:** ${d.warning}`);
|
|
76
|
+
lines.push('');
|
|
77
|
+
lines.push(`<sub>Generated by \`sigmap scaffold\`${opts.timestamp ? ` · ${opts.timestamp}` : ''}.</sub>`);
|
|
78
|
+
lines.push('');
|
|
79
|
+
return lines.join('\n');
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
module.exports = { scaffoldPath, renderScaffoldMarkdown };
|
|
83
|
+
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
__factories["./src/conventions/update"] = function(module, exports) {
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Convention incremental rescan (IMPL.md §4 — `conventions --update`).
|
|
90
|
+
*
|
|
91
|
+
* Avoids recomputing the conventions snapshot when nothing changed: compare the
|
|
92
|
+
* source files' mtimes to the stored `.context/conventions.json` and only flag a
|
|
93
|
+
* rescan when the snapshot is missing or some file is newer. Pure (fs reads
|
|
94
|
+
* only), zero-dependency, bundle-safe.
|
|
95
|
+
*/
|
|
96
|
+
|
|
97
|
+
const fs = require('fs');
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Source files modified after a reference time.
|
|
101
|
+
* @param {string[]} files absolute paths
|
|
102
|
+
* @param {number} sinceMs epoch ms threshold
|
|
103
|
+
* @returns {string[]}
|
|
104
|
+
*/
|
|
105
|
+
function changedSince(files, sinceMs) {
|
|
106
|
+
const out = [];
|
|
107
|
+
for (const f of files || []) {
|
|
108
|
+
try { if (fs.statSync(f).mtimeMs > sinceMs) out.push(f); } catch (_) {}
|
|
109
|
+
}
|
|
110
|
+
return out;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Decide whether the conventions snapshot needs a rescan.
|
|
115
|
+
* @param {string} cwd repo root (unused but kept for signature symmetry)
|
|
116
|
+
* @param {string[]} files absolute source paths
|
|
117
|
+
* @param {string} snapshotPath path to the stored conventions.json
|
|
118
|
+
* @returns {{ snapshotExists: boolean, stale: boolean, changed: string[] }}
|
|
119
|
+
*/
|
|
120
|
+
function planUpdate(cwd, files, snapshotPath) {
|
|
121
|
+
let snapshotMs = null;
|
|
122
|
+
try { snapshotMs = fs.statSync(snapshotPath).mtimeMs; } catch (_) {}
|
|
123
|
+
const snapshotExists = snapshotMs != null;
|
|
124
|
+
if (!snapshotExists) {
|
|
125
|
+
return { snapshotExists: false, stale: true, changed: [] };
|
|
126
|
+
}
|
|
127
|
+
const changed = changedSince(files, snapshotMs);
|
|
128
|
+
return { snapshotExists: true, stale: changed.length > 0, changed };
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
module.exports = { changedSince, planUpdate };
|
|
132
|
+
|
|
133
|
+
};
|
|
134
|
+
|
|
36
135
|
__factories["./src/conventions/fix"] = function(module, exports) {
|
|
37
136
|
|
|
38
137
|
/**
|
|
@@ -7769,7 +7868,7 @@ __factories["./src/mcp/server"] = function(module, exports) {
|
|
|
7769
7868
|
|
|
7770
7869
|
const SERVER_INFO = {
|
|
7771
7870
|
name: 'sigmap',
|
|
7772
|
-
version: '7.
|
|
7871
|
+
version: '7.19.0',
|
|
7773
7872
|
description: 'SigMap MCP server — code signatures on demand',
|
|
7774
7873
|
};
|
|
7775
7874
|
|
|
@@ -13447,7 +13546,7 @@ function __tryGit(args, opts = {}) {
|
|
|
13447
13546
|
catch (_) { return ''; }
|
|
13448
13547
|
}
|
|
13449
13548
|
|
|
13450
|
-
const VERSION = '7.
|
|
13549
|
+
const VERSION = '7.19.0';
|
|
13451
13550
|
const MARKER = '\n\n## Auto-generated signatures\n<!-- Updated by gen-context.js -->\n';
|
|
13452
13551
|
|
|
13453
13552
|
function requireSourceOrBundled(key) {
|
|
@@ -16642,6 +16741,37 @@ function main() {
|
|
|
16642
16741
|
process.exit(0);
|
|
16643
16742
|
}
|
|
16644
16743
|
|
|
16744
|
+
// `--update`: incremental rescan — refresh .context/conventions.json only when stale.
|
|
16745
|
+
if (args.includes('--update')) {
|
|
16746
|
+
const { planUpdate } = requireSourceOrBundled('./src/conventions/update');
|
|
16747
|
+
const outDir = path.join(cwd, '.context');
|
|
16748
|
+
const outPath = path.join(outDir, 'conventions.json');
|
|
16749
|
+
const plan = planUpdate(cwd, files, outPath);
|
|
16750
|
+
let wrote = false;
|
|
16751
|
+
if (plan.stale) {
|
|
16752
|
+
try {
|
|
16753
|
+
fs.mkdirSync(outDir, { recursive: true });
|
|
16754
|
+
fs.writeFileSync(outPath, JSON.stringify(result, null, 2) + '\n');
|
|
16755
|
+
wrote = true;
|
|
16756
|
+
} catch (e) {
|
|
16757
|
+
console.error(`[sigmap] cannot write ${outPath}: ${e.message}`);
|
|
16758
|
+
process.exit(1);
|
|
16759
|
+
}
|
|
16760
|
+
}
|
|
16761
|
+
const payload = { stale: plan.stale, wrote, snapshotExists: plan.snapshotExists, changed: plan.changed.length, scanned: result.scannedFiles };
|
|
16762
|
+
if (jsonOut) {
|
|
16763
|
+
process.stdout.write(JSON.stringify(payload) + '\n');
|
|
16764
|
+
process.exit(0);
|
|
16765
|
+
}
|
|
16766
|
+
if (!plan.stale) {
|
|
16767
|
+
console.log(`[sigmap] conventions --update ✓ up to date — ${result.scannedFiles} files, no changes since last scan`);
|
|
16768
|
+
process.exit(0);
|
|
16769
|
+
}
|
|
16770
|
+
const how = plan.snapshotExists ? `${plan.changed.length} changed file${plan.changed.length === 1 ? '' : 's'}` : 'initial scan';
|
|
16771
|
+
console.log(`[sigmap] conventions --update rescanned (${how}) → wrote ${path.relative(cwd, outPath)}`);
|
|
16772
|
+
process.exit(0);
|
|
16773
|
+
}
|
|
16774
|
+
|
|
16645
16775
|
// `--fix`: exhaustive rename checklist — every file not matching the dominant style.
|
|
16646
16776
|
if (args.includes('--fix')) {
|
|
16647
16777
|
const { buildFixList } = requireSourceOrBundled('./src/conventions/fix');
|
|
@@ -16810,8 +16940,20 @@ function main() {
|
|
|
16810
16940
|
const conventions = extractConventions(cwd, buildFileList(cwd, config));
|
|
16811
16941
|
const decision = proposeScaffold(name, conventions, { threshold, ext, force });
|
|
16812
16942
|
|
|
16943
|
+
// §6.2 (2d): persist an accepted proposal so `create`/agents can read it back.
|
|
16944
|
+
let persistedTo = null;
|
|
16945
|
+
if (decision.ok) {
|
|
16946
|
+
const { scaffoldPath, renderScaffoldMarkdown } = requireSourceOrBundled('./src/scaffold/persist');
|
|
16947
|
+
const outPath = scaffoldPath(cwd);
|
|
16948
|
+
try {
|
|
16949
|
+
fs.mkdirSync(path.dirname(outPath), { recursive: true });
|
|
16950
|
+
fs.writeFileSync(outPath, renderScaffoldMarkdown(decision, { timestamp: new Date().toISOString() }));
|
|
16951
|
+
persistedTo = path.relative(cwd, outPath) || outPath;
|
|
16952
|
+
} catch (_) {}
|
|
16953
|
+
}
|
|
16954
|
+
|
|
16813
16955
|
if (jsonOut) {
|
|
16814
|
-
process.stdout.write(JSON.stringify(decision) + '\n');
|
|
16956
|
+
process.stdout.write(JSON.stringify({ ...decision, persistedTo }) + '\n');
|
|
16815
16957
|
process.exit(decision.ok ? 0 : 1);
|
|
16816
16958
|
}
|
|
16817
16959
|
|
|
@@ -16823,6 +16965,7 @@ function main() {
|
|
|
16823
16965
|
console.log(` file: ${p.filename} (${p.namingStyle})`);
|
|
16824
16966
|
console.log(` export style: ${p.exportStyle}`);
|
|
16825
16967
|
console.log(` test file: ${p.testFile}${p.testFramework ? ` (${p.testFramework})` : ''}`);
|
|
16968
|
+
if (persistedTo) console.log(`\n → wrote ${persistedTo}`);
|
|
16826
16969
|
process.exit(0);
|
|
16827
16970
|
}
|
|
16828
16971
|
|
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.19.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.19.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.19.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,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
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Scaffold persistence (IMPL.md §6.2 — 2d).
|
|
5
|
+
*
|
|
6
|
+
* Renders an accepted scaffold proposal to markdown and locates the on-disk
|
|
7
|
+
* record (`.context/scaffold/latest.md`) so the `create` pipeline and agents can
|
|
8
|
+
* read back the convention-matched proposal. Pure render; zero-dependency,
|
|
9
|
+
* bundle-safe.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
const path = require('path');
|
|
13
|
+
|
|
14
|
+
/** Path to the persisted scaffold record. */
|
|
15
|
+
function scaffoldPath(cwd) {
|
|
16
|
+
return path.join(cwd, '.context', 'scaffold', 'latest.md');
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Render an accepted scaffold decision to a markdown record.
|
|
21
|
+
* @param {object} decision a `proposeScaffold` result with `ok: true`
|
|
22
|
+
* @param {object} [opts]
|
|
23
|
+
* @param {string} [opts.timestamp] ISO timestamp (caller supplies — keeps this pure)
|
|
24
|
+
* @returns {string}
|
|
25
|
+
*/
|
|
26
|
+
function renderScaffoldMarkdown(decision, opts = {}) {
|
|
27
|
+
const d = decision || {};
|
|
28
|
+
const p = d.proposal || {};
|
|
29
|
+
const pct = (n) => `${Math.round((n || 0) * 100)}%`;
|
|
30
|
+
const lines = [
|
|
31
|
+
`# Scaffold — ${d.name || '(unnamed)'}`,
|
|
32
|
+
'',
|
|
33
|
+
`- **Conventions:** ${d.tier || 'unknown'} (${pct(d.confidence)})`,
|
|
34
|
+
`- **File:** \`${p.filename || ''}\` (${p.namingStyle || ''})`,
|
|
35
|
+
`- **Export style:** ${p.exportStyle || ''}`,
|
|
36
|
+
`- **Test file:** \`${p.testFile || ''}\`${p.testFramework ? ` (${p.testFramework})` : ''}`,
|
|
37
|
+
];
|
|
38
|
+
if (d.warning) lines.push(`- **Warning:** ${d.warning}`);
|
|
39
|
+
lines.push('');
|
|
40
|
+
lines.push(`<sub>Generated by \`sigmap scaffold\`${opts.timestamp ? ` · ${opts.timestamp}` : ''}.</sub>`);
|
|
41
|
+
lines.push('');
|
|
42
|
+
return lines.join('\n');
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
module.exports = { scaffoldPath, renderScaffoldMarkdown };
|