sigmap 6.0.1 → 6.0.3
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/AGENTS.md +19 -29
- package/CHANGELOG.md +19 -0
- package/README.md +1 -1
- package/gen-context.js +97 -10
- package/package.json +1 -1
- package/packages/cli/package.json +1 -1
- package/packages/core/package.json +1 -1
- package/src/learning/weights.js +32 -0
- package/src/mcp/server.js +1 -1
package/AGENTS.md
CHANGED
|
@@ -11,19 +11,9 @@ Use this marker block for all appendable context files:
|
|
|
11
11
|
```
|
|
12
12
|
## Auto-generated signatures
|
|
13
13
|
<!-- Updated by gen-context.js -->
|
|
14
|
-
You are a coding assistant with full knowledge of this codebase.
|
|
15
|
-
Below are the code signatures extracted by SigMap v6.0.1 on 2026-04-21T10:54:32.005Z.
|
|
16
|
-
|
|
17
|
-
Use these signatures to answer questions about the code accurately.
|
|
18
|
-
|
|
19
|
-
## Code Signatures
|
|
20
|
-
|
|
21
|
-
<!-- Generated by SigMap gen-context.js v6.0.1 -->
|
|
22
|
-
<!-- DO NOT EDIT below the marker line — run gen-context.js to regenerate -->
|
|
23
|
-
|
|
24
14
|
# Code signatures
|
|
25
15
|
|
|
26
|
-
## changes (last 5 commits —
|
|
16
|
+
## changes (last 5 commits — 3 minutes ago)
|
|
27
17
|
```
|
|
28
18
|
src/extractors/typescript.js ~extractInterfaceMembers ~extractClassMembers
|
|
29
19
|
packages/adapters/codex.js ~format
|
|
@@ -610,14 +600,6 @@ function coverageScore(cwd, fileEntries, config)
|
|
|
610
600
|
function _walk(dir, excludeSet, out)
|
|
611
601
|
```
|
|
612
602
|
|
|
613
|
-
### src/tracking/logger.js
|
|
614
|
-
```
|
|
615
|
-
module.exports = { logRun, readLog, summarize }
|
|
616
|
-
function logRun(entry, cwd)
|
|
617
|
-
function readLog(cwd) → object[]
|
|
618
|
-
function summarize(entries) → object
|
|
619
|
-
```
|
|
620
|
-
|
|
621
603
|
### src/cache/sig-cache.js
|
|
622
604
|
```
|
|
623
605
|
module.exports = { loadCache, saveCache, getChangedFiles, updateCacheEntries }
|
|
@@ -628,16 +610,6 @@ function getChangedFiles(files, cache) → { changed: string[], unch
|
|
|
628
610
|
function updateCacheEntries(cache, extracted)
|
|
629
611
|
```
|
|
630
612
|
|
|
631
|
-
### src/extractors/typescript.js
|
|
632
|
-
```
|
|
633
|
-
module.exports = { extract }
|
|
634
|
-
function extract(src) → string[]
|
|
635
|
-
function extractBlock(src, startIndex)
|
|
636
|
-
function extractInterfaceMembers(block)
|
|
637
|
-
function extractClassMembers(block)
|
|
638
|
-
function normalizeParams(params)
|
|
639
|
-
```
|
|
640
|
-
|
|
641
613
|
### src/mcp/handlers.js
|
|
642
614
|
```
|
|
643
615
|
module.exports = { readContext, searchSignatures, getMap, createCheckpoint, getRouting, explainFile, listModules, queryContext, getImpact }
|
|
@@ -664,6 +636,24 @@ function formatRankJSON(results, query) → object
|
|
|
664
636
|
function detectIntent(query)
|
|
665
637
|
```
|
|
666
638
|
|
|
639
|
+
### src/tracking/logger.js
|
|
640
|
+
```
|
|
641
|
+
module.exports = { logRun, readLog, summarize }
|
|
642
|
+
function logRun(entry, cwd)
|
|
643
|
+
function readLog(cwd) → object[]
|
|
644
|
+
function summarize(entries) → object
|
|
645
|
+
```
|
|
646
|
+
|
|
647
|
+
### src/extractors/typescript.js
|
|
648
|
+
```
|
|
649
|
+
module.exports = { extract }
|
|
650
|
+
function extract(src) → string[]
|
|
651
|
+
function extractBlock(src, startIndex)
|
|
652
|
+
function extractInterfaceMembers(block)
|
|
653
|
+
function extractClassMembers(block)
|
|
654
|
+
function normalizeParams(params)
|
|
655
|
+
```
|
|
656
|
+
|
|
667
657
|
### src/mcp/server.js
|
|
668
658
|
```
|
|
669
659
|
module.exports = { start }
|
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,25 @@ Format: [Semantic Versioning](https://semver.org/)
|
|
|
10
10
|
|
|
11
11
|
---
|
|
12
12
|
|
|
13
|
+
## [6.0.3] — 2026-04-21
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- **`--coverage` CLI flag** — enables test coverage annotation (`✓`/`✗` per function) at runtime without editing config; sets `testCoverage: true` on the loaded config before any run path.
|
|
18
|
+
- **`sigmap weights --export [file]`** — writes learned weights JSON to a file path, or prints to stdout if no path given (pipe-friendly for CI and team sharing).
|
|
19
|
+
- **`sigmap weights --import <file> [--replace]`** — merges imported weights into the local `.context/weights.json`; `--replace` discards existing weights and takes the imported set entirely. Incoming values are sanitized and clamped.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## [6.0.2] — 2026-04-21
|
|
24
|
+
|
|
25
|
+
### Fixed
|
|
26
|
+
|
|
27
|
+
- **Duplicate adapter headers (#104, #96)** — `writeOutputs()` now strips the `formatOutput()` preamble (`<!-- Generated... -->` + `# Code signatures`) before passing content to adapters, preventing double headers on every run. Introduces `stripFormatHeader()` helper applied to all adapter paths including `writeClaude()`.
|
|
28
|
+
- **Bundled codex factory (#96)** — the inline `__factories["./packages/adapters/codex"]` in `gen-context.js` was still delegating to `openai.format()` after the source-file fix in v6.0.1. Now uses clean `# Code signatures\n\n` + context, matching the source adapter.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
13
32
|
## [6.0.1] — 2026-04-21
|
|
14
33
|
|
|
15
34
|
### Fixed
|
package/README.md
CHANGED
|
@@ -147,7 +147,7 @@ volta install sigmap
|
|
|
147
147
|
| `windsurf` | `.windsurfrules` | Windsurf |
|
|
148
148
|
| `openai` | `.github/openai-context.md` | OpenAI models |
|
|
149
149
|
| `gemini` | `.github/gemini-context.md` | Google Gemini |
|
|
150
|
-
| `codex` | `AGENTS.md` | OpenAI Codex |
|
|
150
|
+
| `codex` | `AGENTS.md` | OpenAI Codex · OpenCode |
|
|
151
151
|
|
|
152
152
|
```bash
|
|
153
153
|
sigmap --adapter copilot # default
|
package/gen-context.js
CHANGED
|
@@ -5327,11 +5327,42 @@ __factories["./src/learning/weights"] = function(module, exports) {
|
|
|
5327
5327
|
if (fs.existsSync(outPath)) fs.unlinkSync(outPath);
|
|
5328
5328
|
}
|
|
5329
5329
|
|
|
5330
|
+
function exportWeights(cwd, outputPath) {
|
|
5331
|
+
const weights = loadWeights(cwd);
|
|
5332
|
+
const json = JSON.stringify(weights, null, 2) + '\n';
|
|
5333
|
+
if (outputPath) {
|
|
5334
|
+
fs.mkdirSync(path.dirname(path.resolve(outputPath)), { recursive: true });
|
|
5335
|
+
fs.writeFileSync(outputPath, json, 'utf8');
|
|
5336
|
+
} else {
|
|
5337
|
+
process.stdout.write(json);
|
|
5338
|
+
}
|
|
5339
|
+
return weights;
|
|
5340
|
+
}
|
|
5341
|
+
|
|
5342
|
+
function importWeights(cwd, importPath, replace) {
|
|
5343
|
+
let incoming;
|
|
5344
|
+
try {
|
|
5345
|
+
incoming = JSON.parse(fs.readFileSync(importPath, 'utf8'));
|
|
5346
|
+
} catch (err) {
|
|
5347
|
+
throw new Error('Cannot read weights file: ' + err.message);
|
|
5348
|
+
}
|
|
5349
|
+
const sanitized = sanitizeWeights(cwd, incoming);
|
|
5350
|
+
if (replace) {
|
|
5351
|
+
saveWeights(cwd, sanitized);
|
|
5352
|
+
return sanitized;
|
|
5353
|
+
}
|
|
5354
|
+
const existing = loadWeights(cwd);
|
|
5355
|
+
const merged = Object.assign({}, existing, sanitized);
|
|
5356
|
+
saveWeights(cwd, merged);
|
|
5357
|
+
return merged;
|
|
5358
|
+
}
|
|
5359
|
+
|
|
5330
5360
|
module.exports = {
|
|
5331
5361
|
BASELINE, DECAY, MAX_MULT, MIN_MULT,
|
|
5332
5362
|
weightsPath, clampMultiplier, normalizeFile,
|
|
5333
5363
|
loadWeights, saveWeights, updateWeights,
|
|
5334
5364
|
boostFiles, penalizeFiles, resetWeights,
|
|
5365
|
+
exportWeights, importWeights,
|
|
5335
5366
|
};
|
|
5336
5367
|
};
|
|
5337
5368
|
|
|
@@ -5356,7 +5387,7 @@ __factories["./src/mcp/server"] = function(module, exports) {
|
|
|
5356
5387
|
|
|
5357
5388
|
const SERVER_INFO = {
|
|
5358
5389
|
name: 'sigmap',
|
|
5359
|
-
version: '6.0.
|
|
5390
|
+
version: '6.0.3',
|
|
5360
5391
|
description: 'SigMap MCP server — code signatures on demand',
|
|
5361
5392
|
};
|
|
5362
5393
|
|
|
@@ -6866,11 +6897,11 @@ __factories["./packages/adapters/gemini"] = function(module, exports) {
|
|
|
6866
6897
|
__factories["./packages/adapters/codex"] = function(module, exports) {
|
|
6867
6898
|
const path = require('path');
|
|
6868
6899
|
const fs = require('fs');
|
|
6869
|
-
const openai = __require('./packages/adapters/openai');
|
|
6870
6900
|
const name = 'codex';
|
|
6871
6901
|
const CODEX_MARKER = '\n\n## Auto-generated signatures\n<!-- Updated by gen-context.js -->\n';
|
|
6872
6902
|
function format(context, opts = {}) {
|
|
6873
|
-
|
|
6903
|
+
if (!context || typeof context !== 'string' || !context.trim()) return '';
|
|
6904
|
+
return '# Code signatures\n\n' + context;
|
|
6874
6905
|
}
|
|
6875
6906
|
function outputPath(cwd) { return path.join(cwd, 'AGENTS.md'); }
|
|
6876
6907
|
function write(context, cwd, opts = {}) {
|
|
@@ -7074,7 +7105,7 @@ const path = require('path');
|
|
|
7074
7105
|
const os = require('os');
|
|
7075
7106
|
const { execSync } = require('child_process');
|
|
7076
7107
|
|
|
7077
|
-
const VERSION = '6.0.
|
|
7108
|
+
const VERSION = '6.0.3';
|
|
7078
7109
|
const MARKER = '\n\n## Auto-generated signatures\n<!-- Updated by gen-context.js -->\n';
|
|
7079
7110
|
|
|
7080
7111
|
function requireSourceOrBundled(key) {
|
|
@@ -7762,13 +7793,17 @@ function writeOutputs(content, targets, cwd, config) {
|
|
|
7762
7793
|
if (ADAPTER_TARGETS.has(target)) {
|
|
7763
7794
|
try {
|
|
7764
7795
|
const adapterMod = __require('./packages/adapters/' + target);
|
|
7796
|
+
// Adapters add their own header via format() — strip the formatOutput() header
|
|
7797
|
+
// so the content body (## src, ## deps, etc.) is passed without a pre-existing
|
|
7798
|
+
// header, preventing duplicate "# Code signatures" blocks on every run.
|
|
7799
|
+
const adapterContent = stripFormatHeader(content);
|
|
7765
7800
|
// copilot: honour config.output custom path (redirects away from default .github/copilot-instructions.md)
|
|
7766
7801
|
if (target === 'copilot') {
|
|
7767
7802
|
const outPath = resolveAdapterPath('copilot', cwd, config);
|
|
7768
7803
|
const defaultPath = path.join(cwd, '.github', 'copilot-instructions.md');
|
|
7769
7804
|
if (outPath !== defaultPath) {
|
|
7770
7805
|
// custom path: format and write directly (no append logic)
|
|
7771
|
-
const formatted = adapterMod.format(
|
|
7806
|
+
const formatted = adapterMod.format(adapterContent, { version: VERSION });
|
|
7772
7807
|
ensureDir(outPath);
|
|
7773
7808
|
fs.writeFileSync(outPath, formatted, 'utf8');
|
|
7774
7809
|
console.warn(`[sigmap] wrote ${path.relative(cwd, outPath)}`);
|
|
@@ -7776,11 +7811,11 @@ function writeOutputs(content, targets, cwd, config) {
|
|
|
7776
7811
|
}
|
|
7777
7812
|
}
|
|
7778
7813
|
if (typeof adapterMod.write === 'function') {
|
|
7779
|
-
adapterMod.write(
|
|
7814
|
+
adapterMod.write(adapterContent, cwd, { version: VERSION });
|
|
7780
7815
|
const outPath = adapterMod.outputPath(cwd);
|
|
7781
7816
|
console.warn(`[sigmap] wrote ${path.relative(cwd, outPath)} (appended signatures)`);
|
|
7782
7817
|
} else {
|
|
7783
|
-
const formatted = adapterMod.format(
|
|
7818
|
+
const formatted = adapterMod.format(adapterContent, { version: VERSION });
|
|
7784
7819
|
const outPath = adapterMod.outputPath(cwd);
|
|
7785
7820
|
ensureDir(outPath);
|
|
7786
7821
|
fs.writeFileSync(outPath, formatted, 'utf8');
|
|
@@ -7802,18 +7837,36 @@ function writeOutputs(content, targets, cwd, config) {
|
|
|
7802
7837
|
}
|
|
7803
7838
|
}
|
|
7804
7839
|
|
|
7840
|
+
// Strip the formatOutput() header block before passing content to adapters.
|
|
7841
|
+
// formatOutput() prepends "<!-- Generated... -->\n\n# Code signatures\n\n" which
|
|
7842
|
+
// is the raw-file header. Adapters add their own header via format(), so passing
|
|
7843
|
+
// pre-headered content produces duplicate headers on every run.
|
|
7844
|
+
function stripFormatHeader(content) {
|
|
7845
|
+
if (!content || typeof content !== 'string') return content;
|
|
7846
|
+
// Header ends after "# Code signatures\n\n" (with blank line)
|
|
7847
|
+
const marker = '\n# Code signatures\n';
|
|
7848
|
+
const idx = content.indexOf(marker);
|
|
7849
|
+
if (idx === -1) return content;
|
|
7850
|
+
// Skip past the marker line and one blank line
|
|
7851
|
+
const afterMarker = content.slice(idx + marker.length);
|
|
7852
|
+
return afterMarker.startsWith('\n') ? afterMarker.slice(1) : afterMarker;
|
|
7853
|
+
}
|
|
7854
|
+
|
|
7805
7855
|
function writeClaude(content, cwd) {
|
|
7806
7856
|
const claudePath = path.join(cwd, 'CLAUDE.md');
|
|
7807
7857
|
let existing = '';
|
|
7808
7858
|
if (fs.existsSync(claudePath)) {
|
|
7809
7859
|
existing = fs.readFileSync(claudePath, 'utf8');
|
|
7810
7860
|
}
|
|
7861
|
+
// Strip the formatOutput() header — CLAUDE.md gets its own header via the MARKER
|
|
7862
|
+
const body = stripFormatHeader(content);
|
|
7863
|
+
const sigHeader = '# Code signatures\n\n';
|
|
7811
7864
|
const markerIdx = existing.indexOf('## Auto-generated signatures');
|
|
7812
7865
|
let newContent;
|
|
7813
7866
|
if (markerIdx !== -1) {
|
|
7814
|
-
newContent = existing.slice(0, markerIdx) + MARKER.trimStart() +
|
|
7867
|
+
newContent = existing.slice(0, markerIdx) + MARKER.trimStart() + sigHeader + body;
|
|
7815
7868
|
} else {
|
|
7816
|
-
newContent = existing + MARKER +
|
|
7869
|
+
newContent = existing + MARKER + sigHeader + body;
|
|
7817
7870
|
}
|
|
7818
7871
|
fs.writeFileSync(claudePath, newContent, 'utf8');
|
|
7819
7872
|
console.warn(`[sigmap] wrote CLAUDE.md (appended signatures)`);
|
|
@@ -8960,6 +9013,11 @@ function main() {
|
|
|
8960
9013
|
config.srcDirs = ['.'];
|
|
8961
9014
|
}
|
|
8962
9015
|
|
|
9016
|
+
// --coverage: enable test coverage annotation without editing config
|
|
9017
|
+
if (args.includes('--coverage')) {
|
|
9018
|
+
config.testCoverage = true;
|
|
9019
|
+
}
|
|
9020
|
+
|
|
8963
9021
|
// ── --output <file> — parse early so every subsequent block can use it ─────
|
|
8964
9022
|
// Resolves the custom output path and merges it into config.customOutput.
|
|
8965
9023
|
// Also persists the resolved relative path to gen-context.config.json so
|
|
@@ -9282,7 +9340,36 @@ function main() {
|
|
|
9282
9340
|
|
|
9283
9341
|
// v5.2: `sigmap weights` — explain learned ranking multipliers
|
|
9284
9342
|
if (args[0] === 'weights') {
|
|
9285
|
-
const { loadWeights } = requireSourceOrBundled('./src/learning/weights');
|
|
9343
|
+
const { loadWeights, exportWeights, importWeights } = requireSourceOrBundled('./src/learning/weights');
|
|
9344
|
+
|
|
9345
|
+
if (args.includes('--export')) {
|
|
9346
|
+
const exportIdx = args.indexOf('--export');
|
|
9347
|
+
const maybeFile = args[exportIdx + 1];
|
|
9348
|
+
const exportFile = (maybeFile && !maybeFile.startsWith('--')) ? maybeFile : null;
|
|
9349
|
+
exportWeights(cwd, exportFile);
|
|
9350
|
+
if (exportFile) console.warn(`[sigmap] weights exported to ${exportFile}`);
|
|
9351
|
+
process.exit(0);
|
|
9352
|
+
}
|
|
9353
|
+
|
|
9354
|
+
if (args.includes('--import')) {
|
|
9355
|
+
const importIdx = args.indexOf('--import');
|
|
9356
|
+
const importFile = args[importIdx + 1];
|
|
9357
|
+
if (!importFile || importFile.startsWith('--')) {
|
|
9358
|
+
console.error('[sigmap] --import requires a file path');
|
|
9359
|
+
process.exit(1);
|
|
9360
|
+
}
|
|
9361
|
+
const replace = args.includes('--replace');
|
|
9362
|
+
try {
|
|
9363
|
+
const result = importWeights(cwd, importFile, replace);
|
|
9364
|
+
const count = Object.keys(result).length;
|
|
9365
|
+
console.warn(`[sigmap] weights ${replace ? 'replaced' : 'merged'} from ${importFile} — ${count} file(s) with non-baseline weights`);
|
|
9366
|
+
} catch (err) {
|
|
9367
|
+
console.error(`[sigmap] weights import failed: ${err.message}`);
|
|
9368
|
+
process.exit(1);
|
|
9369
|
+
}
|
|
9370
|
+
process.exit(0);
|
|
9371
|
+
}
|
|
9372
|
+
|
|
9286
9373
|
const weights = loadWeights(cwd);
|
|
9287
9374
|
const entries = Object.entries(weights).sort(([, a], [, b]) => b - a || 0);
|
|
9288
9375
|
|
package/package.json
CHANGED
package/src/learning/weights.js
CHANGED
|
@@ -121,6 +121,36 @@ function resetWeights(cwd) {
|
|
|
121
121
|
if (fs.existsSync(outPath)) fs.unlinkSync(outPath);
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
+
function exportWeights(cwd, outputPath) {
|
|
125
|
+
const weights = loadWeights(cwd);
|
|
126
|
+
const json = JSON.stringify(weights, null, 2) + '\n';
|
|
127
|
+
if (outputPath) {
|
|
128
|
+
fs.mkdirSync(path.dirname(path.resolve(outputPath)), { recursive: true });
|
|
129
|
+
fs.writeFileSync(outputPath, json, 'utf8');
|
|
130
|
+
} else {
|
|
131
|
+
process.stdout.write(json);
|
|
132
|
+
}
|
|
133
|
+
return weights;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function importWeights(cwd, importPath, replace) {
|
|
137
|
+
let incoming;
|
|
138
|
+
try {
|
|
139
|
+
incoming = JSON.parse(fs.readFileSync(importPath, 'utf8'));
|
|
140
|
+
} catch (err) {
|
|
141
|
+
throw new Error(`Cannot read weights file: ${err.message}`);
|
|
142
|
+
}
|
|
143
|
+
const sanitized = sanitizeWeights(cwd, incoming);
|
|
144
|
+
if (replace) {
|
|
145
|
+
saveWeights(cwd, sanitized);
|
|
146
|
+
return sanitized;
|
|
147
|
+
}
|
|
148
|
+
const existing = loadWeights(cwd);
|
|
149
|
+
const merged = Object.assign({}, existing, sanitized);
|
|
150
|
+
saveWeights(cwd, merged);
|
|
151
|
+
return merged;
|
|
152
|
+
}
|
|
153
|
+
|
|
124
154
|
module.exports = {
|
|
125
155
|
BASELINE,
|
|
126
156
|
DECAY,
|
|
@@ -135,4 +165,6 @@ module.exports = {
|
|
|
135
165
|
boostFiles,
|
|
136
166
|
penalizeFiles,
|
|
137
167
|
resetWeights,
|
|
168
|
+
exportWeights,
|
|
169
|
+
importWeights,
|
|
138
170
|
};
|
package/src/mcp/server.js
CHANGED