sigmap 6.7.0 → 6.9.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/AGENTS.md +48 -55
- package/CHANGELOG.md +20 -0
- package/README.md +2 -2
- package/gen-context.js +14 -5
- package/package.json +1 -1
- package/packages/cli/package.json +1 -1
- package/packages/core/package.json +1 -1
- package/src/eval/usefulness-scorer.js +66 -0
- package/src/mcp/server.js +1 -1
package/AGENTS.md
CHANGED
|
@@ -56,13 +56,6 @@ Use this marker block for all appendable context files:
|
|
|
56
56
|
| To query by topic | `sigmap --query "<topic>"` |
|
|
57
57
|
|
|
58
58
|
Always run `sigmap ask` or `sigmap --query` before searching for files relevant to a task.
|
|
59
|
-
## changes (last 5 commits — 8 minutes ago)
|
|
60
|
-
```
|
|
61
|
-
src/plan/planner.js +createPlan
|
|
62
|
-
src/retrieval/ranker.js +_computePenalty +_computeHubs +_isHub ~scoreFile
|
|
63
|
-
src/session/memory.js +sessionPath +loadSession +saveSession +mergeSessionContext
|
|
64
|
-
```
|
|
65
|
-
|
|
66
59
|
## packages
|
|
67
60
|
|
|
68
61
|
### packages/cli/index.js
|
|
@@ -580,11 +573,6 @@ function exportWeights(cwd, outputPath)
|
|
|
580
573
|
function importWeights(cwd, importPath, replace)
|
|
581
574
|
```
|
|
582
575
|
|
|
583
|
-
### src/config/defaults.js
|
|
584
|
-
```
|
|
585
|
-
module.exports = { DEFAULTS }
|
|
586
|
-
```
|
|
587
|
-
|
|
588
576
|
### src/config/loader.js
|
|
589
577
|
```
|
|
590
578
|
module.exports = { loadConfig, loadBaseConfig }
|
|
@@ -595,37 +583,6 @@ function loadConfig(cwd) → object
|
|
|
595
583
|
function deepClone(obj)
|
|
596
584
|
```
|
|
597
585
|
|
|
598
|
-
### src/discovery/source-root-registry.js
|
|
599
|
-
```
|
|
600
|
-
module.exports = { REGISTRY }
|
|
601
|
-
```
|
|
602
|
-
|
|
603
|
-
### src/discovery/source-root-resolver.js
|
|
604
|
-
```
|
|
605
|
-
module.exports = { resolveSourceRoots }
|
|
606
|
-
function resolveSourceRoots(cwd, opts = {})
|
|
607
|
-
function _detectMonorepo(cwd)
|
|
608
|
-
function _enumerateCandidates(cwd, isMonorepo, ignorePatterns, excludeList)
|
|
609
|
-
function _applySpecialRules(scored, cwd, primaryFw, fwEntry, frameworks)
|
|
610
|
-
function _dedupeNested(scored)
|
|
611
|
-
function _computeConfidence(frameworks, languages, scoredCount)
|
|
612
|
-
```
|
|
613
|
-
|
|
614
|
-
### src/discovery/language-detector.js
|
|
615
|
-
```
|
|
616
|
-
module.exports = { detectLanguages }
|
|
617
|
-
function detectLanguages(cwd)
|
|
618
|
-
function _walkDepth(dir, depth, extCount)
|
|
619
|
-
```
|
|
620
|
-
|
|
621
|
-
### src/discovery/source-root-scorer.js
|
|
622
|
-
```
|
|
623
|
-
module.exports = { scoreCandidate, getRecentlyChangedDirs, ROOT_ENTRYPOINTS }
|
|
624
|
-
function getRecentlyChangedDirs(cwd)
|
|
625
|
-
function scoreCandidate(dirName, fullPath, context)
|
|
626
|
-
function _countSourceFiles(dir, depth)
|
|
627
|
-
```
|
|
628
|
-
|
|
629
586
|
### src/discovery/framework-detector.js
|
|
630
587
|
```
|
|
631
588
|
module.exports = { detectFrameworks }
|
|
@@ -636,6 +593,13 @@ function _existsAnywhere(cwd, filename, maxDepth)
|
|
|
636
593
|
function _walkFind(dir, name, depth)
|
|
637
594
|
```
|
|
638
595
|
|
|
596
|
+
### src/discovery/language-detector.js
|
|
597
|
+
```
|
|
598
|
+
module.exports = { detectLanguages }
|
|
599
|
+
function detectLanguages(cwd)
|
|
600
|
+
function _walkDepth(dir, depth, extCount)
|
|
601
|
+
```
|
|
602
|
+
|
|
639
603
|
### src/discovery/sigmapignore.js
|
|
640
604
|
```
|
|
641
605
|
module.exports = { loadIgnorePatterns, matchesIgnorePattern }
|
|
@@ -643,19 +607,9 @@ function loadIgnorePatterns(cwd)
|
|
|
643
607
|
function matchesIgnorePattern(dirName, patterns)
|
|
644
608
|
```
|
|
645
609
|
|
|
646
|
-
### src/
|
|
647
|
-
```
|
|
648
|
-
module.exports = { createPlan }
|
|
649
|
-
function createPlan(goal, cwd, config)
|
|
650
|
-
```
|
|
651
|
-
|
|
652
|
-
### src/mcp/server.js
|
|
610
|
+
### src/discovery/source-root-registry.js
|
|
653
611
|
```
|
|
654
|
-
module.exports = {
|
|
655
|
-
function respond(id, result)
|
|
656
|
-
function respondError(id, code, message)
|
|
657
|
-
function dispatch(msg, cwd)
|
|
658
|
-
function start(cwd)
|
|
612
|
+
module.exports = { REGISTRY }
|
|
659
613
|
```
|
|
660
614
|
|
|
661
615
|
### src/retrieval/ranker.js
|
|
@@ -673,6 +627,12 @@ function formatRankJSON(results, query) → object
|
|
|
673
627
|
function detectIntent(query)
|
|
674
628
|
```
|
|
675
629
|
|
|
630
|
+
### src/plan/planner.js
|
|
631
|
+
```
|
|
632
|
+
module.exports = { createPlan }
|
|
633
|
+
function createPlan(goal, cwd, config)
|
|
634
|
+
```
|
|
635
|
+
|
|
676
636
|
### src/session/memory.js
|
|
677
637
|
```
|
|
678
638
|
module.exports = { loadSession, saveSession, mergeSessionContext, clearSession }
|
|
@@ -682,3 +642,36 @@ function saveSession(cwd, { intent, topFiles, query })
|
|
|
682
642
|
function mergeSessionContext(scores, session, currentIntent)
|
|
683
643
|
function clearSession(cwd)
|
|
684
644
|
```
|
|
645
|
+
|
|
646
|
+
### src/config/defaults.js
|
|
647
|
+
```
|
|
648
|
+
module.exports = { DEFAULTS }
|
|
649
|
+
```
|
|
650
|
+
|
|
651
|
+
### src/discovery/source-root-scorer.js
|
|
652
|
+
```
|
|
653
|
+
module.exports = { scoreCandidate, getRecentlyChangedDirs, ROOT_ENTRYPOINTS, JVM_PATH_PATTERN }
|
|
654
|
+
function getRecentlyChangedDirs(cwd)
|
|
655
|
+
function scoreCandidate(dirName, fullPath, context)
|
|
656
|
+
function _countSourceFiles(dir, depth)
|
|
657
|
+
```
|
|
658
|
+
|
|
659
|
+
### src/discovery/source-root-resolver.js
|
|
660
|
+
```
|
|
661
|
+
module.exports = { resolveSourceRoots }
|
|
662
|
+
function resolveSourceRoots(cwd, opts = {})
|
|
663
|
+
function _detectMonorepo(cwd)
|
|
664
|
+
function _enumerateCandidates(cwd, isMonorepo, ignorePatterns, excludeList)
|
|
665
|
+
function _applySpecialRules(scored, cwd, primaryFw, fwEntry, frameworks)
|
|
666
|
+
function _dedupeNested(scored)
|
|
667
|
+
function _computeConfidence(frameworks, languages, scoredCount)
|
|
668
|
+
```
|
|
669
|
+
|
|
670
|
+
### src/mcp/server.js
|
|
671
|
+
```
|
|
672
|
+
module.exports = { start }
|
|
673
|
+
function respond(id, result)
|
|
674
|
+
function respondError(id, code, message)
|
|
675
|
+
function dispatch(msg, cwd)
|
|
676
|
+
function start(cwd)
|
|
677
|
+
```
|
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,26 @@ Format: [Semantic Versioning](https://semver.org/)
|
|
|
10
10
|
|
|
11
11
|
---
|
|
12
12
|
|
|
13
|
+
## [6.9.0] — 2026-05-03
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- **Task metadata for segmentation** — All 18 benchmark repositories now tagged with language, repo type (framework/library/tool/application), and size class (small/medium/large) to enable segmented benchmark analysis.
|
|
18
|
+
- **Benchmark methodology documentation** — Comprehensive guide explaining what SigMap measures (retrieval accuracy, task success, prompt reduction, token reduction), why these metrics matter, and how the 90-task test set was selected and evaluated.
|
|
19
|
+
- **Answer usefulness evaluation** — New metric tracking whether retrieved context actually enabled correct answers, scored in three tiers: fully-useful (rank 1), partially-useful (ranks 2-5), not-useful (not retrieved). Complements task success proxy with granular answer quality assessment.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## [6.8.0] — 2026-05-03
|
|
24
|
+
|
|
25
|
+
### Added
|
|
26
|
+
|
|
27
|
+
- **Session memory with 4-hour TTL** — Store intent, top-ranked files, and last query in `.context/session.json` to enable context carry-forward across multiple `sigmap ask` calls. Session expires after 4 hours, preventing stale context fixation.
|
|
28
|
+
- **`sigmap ask --followup` flag** — Carry context from previous session with intent-aware boosting: +0.2 score for same intent, +0.1 for topic switch (different intent). Never reduces scores, only adds contextual signals.
|
|
29
|
+
- **`sigmap plan "<goal>"` command** — Analyze change impact before editing: rank files by confidence level (inspect first vs. likely to change), compute impact radius using dependency graph, identify affected tests. Outputs human-readable table or JSON.
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
13
33
|
## [6.7.0] — 2026-05-03
|
|
14
34
|
|
|
15
35
|
### Added
|
package/README.md
CHANGED
|
@@ -52,7 +52,7 @@ Works with Copilot, Claude, Cursor, Windsurf, and any LLM.
|
|
|
52
52
|
|
|
53
53
|
| Without SigMap | With SigMap |
|
|
54
54
|
|---|---|
|
|
55
|
-
| ❌ Guessing which files are relevant | ✅ Right file in context —
|
|
55
|
+
| ❌ Guessing which files are relevant | ✅ Right file in context — 80% of the time |
|
|
56
56
|
| ❌ Sending the full repo to your AI | ✅ Minimal context — only what matters |
|
|
57
57
|
| ❌ Embeddings / vector DB required | ✅ Grounded answers, no infra needed |
|
|
58
58
|
|
|
@@ -76,7 +76,7 @@ Ask → Rank → Context → Validate → Judge → Learn
|
|
|
76
76
|
## Benchmark
|
|
77
77
|
|
|
78
78
|
```
|
|
79
|
-
Benchmark : sigmap-v6.
|
|
79
|
+
Benchmark : sigmap-v6.8-main
|
|
80
80
|
Date : 2026-04-30
|
|
81
81
|
|
|
82
82
|
Hit@5 : 80.0% (baseline 13.6% — 5.9× lift)
|
package/gen-context.js
CHANGED
|
@@ -5387,7 +5387,7 @@ __factories["./src/mcp/server"] = function(module, exports) {
|
|
|
5387
5387
|
|
|
5388
5388
|
const SERVER_INFO = {
|
|
5389
5389
|
name: 'sigmap',
|
|
5390
|
-
version: '6.
|
|
5390
|
+
version: '6.9.0',
|
|
5391
5391
|
description: 'SigMap MCP server — code signatures on demand',
|
|
5392
5392
|
};
|
|
5393
5393
|
|
|
@@ -7855,7 +7855,7 @@ const path = require('path');
|
|
|
7855
7855
|
const os = require('os');
|
|
7856
7856
|
const { execSync } = require('child_process');
|
|
7857
7857
|
|
|
7858
|
-
const VERSION = '6.
|
|
7858
|
+
const VERSION = '6.9.0';
|
|
7859
7859
|
const MARKER = '\n\n## Auto-generated signatures\n<!-- Updated by gen-context.js -->\n';
|
|
7860
7860
|
|
|
7861
7861
|
function requireSourceOrBundled(key) {
|
|
@@ -9900,10 +9900,19 @@ function main() {
|
|
|
9900
9900
|
|
|
9901
9901
|
// v4.2: `sigmap ask "<query>"` — unified pipeline
|
|
9902
9902
|
if (args[0] === 'ask') {
|
|
9903
|
-
|
|
9903
|
+
// v6.8: Handle --followup flag which may appear before or after query
|
|
9904
|
+
let query = args[1];
|
|
9905
|
+
if (query === '--followup' && args[2]) {
|
|
9906
|
+
query = args[2];
|
|
9907
|
+
} else if (query && query.startsWith('--') && query !== '--json' && query !== '--model') {
|
|
9908
|
+
// Allow --json and --model but not other flags as query
|
|
9909
|
+
console.error('[sigmap] Usage: sigmap ask "<query>" [--followup] [--json] [--model <name>]');
|
|
9910
|
+
console.error(' Example: sigmap ask "fix the login bug" --followup');
|
|
9911
|
+
process.exit(1);
|
|
9912
|
+
}
|
|
9904
9913
|
if (!query || query.startsWith('--')) {
|
|
9905
|
-
console.error('[sigmap] Usage: sigmap ask "<query>"');
|
|
9906
|
-
console.error(' Example: sigmap ask "fix the login bug"');
|
|
9914
|
+
console.error('[sigmap] Usage: sigmap ask "<query>" [--followup] [--json] [--model <name>]');
|
|
9915
|
+
console.error(' Example: sigmap ask "fix the login bug" --followup');
|
|
9907
9916
|
process.exit(1);
|
|
9908
9917
|
}
|
|
9909
9918
|
|
package/package.json
CHANGED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
module.exports = { scoreUsefulness, computeUsefulnessStats };
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Score answer usefulness based on:
|
|
7
|
+
* 1. Whether right file was retrieved (retrieval hit)
|
|
8
|
+
* 2. Whether retrieved context covered the answer (coverage)
|
|
9
|
+
* 3. Confidence in answer quality (from ranking score)
|
|
10
|
+
*/
|
|
11
|
+
function scoreUsefulness(taskResult, rankingScore) {
|
|
12
|
+
const { hitRank } = taskResult;
|
|
13
|
+
|
|
14
|
+
// Tier 1: File not retrieved — context cannot be useful
|
|
15
|
+
if (hitRank === -1 || hitRank > 5) {
|
|
16
|
+
return {
|
|
17
|
+
tier: 'not-useful',
|
|
18
|
+
score: 0.0,
|
|
19
|
+
reason: 'expected file not in top 5'
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Tier 2: File retrieved but not top ranking — partially useful
|
|
24
|
+
if (hitRank > 1) {
|
|
25
|
+
return {
|
|
26
|
+
tier: 'partially-useful',
|
|
27
|
+
score: rankingScore * 0.5, // Partial usefulness
|
|
28
|
+
reason: `file ranked #${hitRank}`
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Tier 3: File at top of ranking — fully useful
|
|
33
|
+
return {
|
|
34
|
+
tier: 'fully-useful',
|
|
35
|
+
score: rankingScore, // Full usefulness
|
|
36
|
+
reason: 'file ranked first'
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function computeUsefulnessStats(taskResults) {
|
|
41
|
+
const tiers = {
|
|
42
|
+
'fully-useful': 0,
|
|
43
|
+
'partially-useful': 0,
|
|
44
|
+
'not-useful': 0
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
let totalScore = 0;
|
|
48
|
+
let count = 0;
|
|
49
|
+
|
|
50
|
+
taskResults.forEach(result => {
|
|
51
|
+
const usefulness = scoreUsefulness(result, result.rankingScore || 1.0);
|
|
52
|
+
tiers[usefulness.tier]++;
|
|
53
|
+
totalScore += usefulness.score;
|
|
54
|
+
count++;
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
return {
|
|
58
|
+
fully_useful: tiers['fully-useful'],
|
|
59
|
+
partially_useful: tiers['partially-useful'],
|
|
60
|
+
not_useful: tiers['not-useful'],
|
|
61
|
+
fully_useful_pct: count > 0 ? (tiers['fully-useful'] / count * 100).toFixed(1) : 0,
|
|
62
|
+
partially_useful_pct: count > 0 ? (tiers['partially-useful'] / count * 100).toFixed(1) : 0,
|
|
63
|
+
not_useful_pct: count > 0 ? (tiers['not-useful'] / count * 100).toFixed(1) : 0,
|
|
64
|
+
average_usefulness_score: count > 0 ? (totalScore / count).toFixed(3) : 0
|
|
65
|
+
};
|
|
66
|
+
}
|
package/src/mcp/server.js
CHANGED