sigmap 8.8.0 → 8.8.1
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 +12 -0
- package/gen-context.js +28 -5
- package/llms-full.txt +1 -1
- package/llms.txt +1 -1
- package/package.json +2 -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,18 @@ Format: [Semantic Versioning](https://semver.org/)
|
|
|
10
10
|
|
|
11
11
|
---
|
|
12
12
|
|
|
13
|
+
## [8.8.1] — 2026-07-05
|
|
14
|
+
|
|
15
|
+
Patch release — **byte-stable context, reproducible benchmark.** Closes the determinism residual tracked in #440: `gen-context` output is now byte-identical run-to-run across all 43 benchmark repos, and the retrieval benchmark reproduces a single hit@5 (87.8%) instead of flapping 85.6–87.8%. Plus a test-count derivation fix, docs/CI serving fixes, and repo hygiene.
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
- **gen-context determinism residual — token-budget recency boost (#440, PR #444):** the recency boost stamped `mtime = Date.now()` on every recently-committed file. On repos where nearly every file is "recently changed", consecutive files often landed on the *same millisecond* — so which equal-priority files shared a millisecond (and thus fell through to the `filePath` tie-break instead of sorting by a distinct mtime) shifted run to run, swapping which files survived at the budget cutoff and making the output non-byte-stable. The `Date.now()` value wasn't just a boost: it encoded the alphabetical walk order that the budget's best-first sort relied on; the nondeterminism was only the millisecond *collisions*. Replaced it with a deterministic monotonic counter (`nextRecentMtime`) that reproduces the exact same processing-order ranking without collisions. Result: all 43 benchmark repos are byte-identical across two clean runs (excluding the `Updated:` timestamp), and retrieval hit@5 reproduces at **87.8%** with identical per-repo results. Adds an integration regression guard (`test/integration/gen-context-determinism.test.js`) that runs gen-context twice on a committed fixture and asserts byte-equality — verified to fail on the old `Date.now()` behaviour.
|
|
19
|
+
- **Derived test count after test relocation (503a6e5):** the test-count derivation globbed `tests/**/*.py`; after relocating `test_python_ast_extractor.py` into `test/` it matched neither pattern and dropped the count, failing `check:metrics` in CI. Now counts `test/**/test_*.py` (unittest-named), which matches the relocated test and excludes the fixture.
|
|
20
|
+
- **Docs / CI serving (b236e08):** serve the OG banner image and the Google Search Console verification file; run the Python extractor tests in CI.
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
- **Repo hygiene (a49e9c5):** dropped orphaned demo GIFs and a dead script; relocated a stray test from `tests/` into `test/`.
|
|
24
|
+
|
|
13
25
|
## [8.8.0] — 2026-07-05
|
|
14
26
|
|
|
15
27
|
Minor release — **the squeeze engine, exposed mid-session (D6).** The always-on squeeze engine (`src/squeeze/`) that powers `sigmap squeeze` was reachable only from the CLI on pasted input. This release exposes it as an MCP tool an agent can call *mid-session*, and adds a named CLI entry point for compressing an agent/tool *response*. Zero-dependency, offline, deterministic — the last A+ ceiling item (Machine 9→10): the engine already shipped, this just exposes it.
|
package/gen-context.js
CHANGED
|
@@ -13566,7 +13566,7 @@ __factories["./src/mcp/server"] = function(module, exports) {
|
|
|
13566
13566
|
|
|
13567
13567
|
const SERVER_INFO = {
|
|
13568
13568
|
name: 'sigmap',
|
|
13569
|
-
version: '8.8.
|
|
13569
|
+
version: '8.8.1',
|
|
13570
13570
|
description: 'SigMap MCP server — code signatures on demand',
|
|
13571
13571
|
};
|
|
13572
13572
|
|
|
@@ -18158,7 +18158,7 @@ function __tryGit(args, opts = {}) {
|
|
|
18158
18158
|
catch (_) { return ''; }
|
|
18159
18159
|
}
|
|
18160
18160
|
|
|
18161
|
-
const VERSION = '8.8.
|
|
18161
|
+
const VERSION = '8.8.1';
|
|
18162
18162
|
const MARKER = '\n\n## Auto-generated signatures\n<!-- Updated by gen-context.js -->\n';
|
|
18163
18163
|
|
|
18164
18164
|
function requireSourceOrBundled(key) {
|
|
@@ -18368,6 +18368,26 @@ function annotateCoverage(sigs, testIndex, enabled) {
|
|
|
18368
18368
|
// ---------------------------------------------------------------------------
|
|
18369
18369
|
// Token budget enforcement
|
|
18370
18370
|
// ---------------------------------------------------------------------------
|
|
18371
|
+
// Deterministic recency boost for recently-committed files so the token budget
|
|
18372
|
+
// doesn't drop them first. Previously this used `Date.now()`, which encoded the
|
|
18373
|
+
// (alphabetical) processing order as a monotonically increasing mtime — but on
|
|
18374
|
+
// repos where nearly every file is "recently changed", consecutive files often
|
|
18375
|
+
// landed on the *same* millisecond. Which files shared a millisecond (and so
|
|
18376
|
+
// fell through to the filePath tie-break instead of sorting by a distinct
|
|
18377
|
+
// mtime) shifted run to run, swapping which files survived at the budget cutoff
|
|
18378
|
+
// and making the output non-byte-stable. A monotonic integer counter preserves
|
|
18379
|
+
// the exact processing-order ranking Date.now() produced — recent files stay
|
|
18380
|
+
// ahead of non-recent ones, ordered among themselves by walk order — but is
|
|
18381
|
+
// collision-free and reproducible. RECENT_MTIME_BASE sits far above any real
|
|
18382
|
+
// filesystem mtime (ms since epoch ≈ 1.7e12) so boosted files always out-rank
|
|
18383
|
+
// non-boosted ones, and far below MAX_SAFE_INTEGER so the counter never
|
|
18384
|
+
// overflows. Call nextRecentMtime() once per boosted file, in walk order. (#440)
|
|
18385
|
+
const RECENT_MTIME_BASE = 1e15;
|
|
18386
|
+
let _recentMtimeSeq = 0;
|
|
18387
|
+
function nextRecentMtime() {
|
|
18388
|
+
return RECENT_MTIME_BASE + (_recentMtimeSeq++);
|
|
18389
|
+
}
|
|
18390
|
+
|
|
18371
18391
|
function estimateTokens(str) {
|
|
18372
18392
|
return Math.ceil(str.length / 4);
|
|
18373
18393
|
}
|
|
@@ -19348,7 +19368,7 @@ function runDiff(cwd, config, stagedOnly, baseRef) {
|
|
|
19348
19368
|
|
|
19349
19369
|
sigs = annotateCoverage(sigs, testIndex, !!config.testCoverage);
|
|
19350
19370
|
|
|
19351
|
-
fileEntries.push({ filePath, sigs, deps: extractFileDeps(filePath, content, config), content, mtime:
|
|
19371
|
+
fileEntries.push({ filePath, sigs, deps: extractFileDeps(filePath, content, config), content, mtime: nextRecentMtime() });
|
|
19352
19372
|
}
|
|
19353
19373
|
|
|
19354
19374
|
if (fileEntries.length === 0) {
|
|
@@ -19496,8 +19516,11 @@ function runGenerate(cwd, config, reportMode, reportJson = false) {
|
|
|
19496
19516
|
mtime = fs.statSync(filePath).mtimeMs;
|
|
19497
19517
|
} catch (_) {}
|
|
19498
19518
|
|
|
19499
|
-
// Boost recently committed files (give them max mtime so they aren't
|
|
19500
|
-
|
|
19519
|
+
// Boost recently committed files (give them a max mtime so they aren't
|
|
19520
|
+
// dropped first). A deterministic monotonic counter — not Date.now() — keeps
|
|
19521
|
+
// the budget selection byte-stable when many files are recent, while
|
|
19522
|
+
// preserving the original processing-order ranking (see nextRecentMtime, #440).
|
|
19523
|
+
if (recentFiles.has(filePath)) mtime = nextRecentMtime();
|
|
19501
19524
|
|
|
19502
19525
|
fileEntries.push({ filePath, sigs, deps: extractFileDeps(filePath, content, config), content, mtime });
|
|
19503
19526
|
}
|
package/llms-full.txt
CHANGED
|
@@ -11,7 +11,7 @@ ranking keeps the relevant context in scope (cutting tokens ~97% as a side
|
|
|
11
11
|
effect), with no LLM calls, embeddings, or vector database. Works with Claude,
|
|
12
12
|
Cursor, GitHub Copilot, Aider, Windsurf, local LLMs, and MCP.
|
|
13
13
|
|
|
14
|
-
# Version: 8.8.
|
|
14
|
+
# Version: 8.8.1 | Benchmark: sigmap-v8.8-main (2026-07-05)
|
|
15
15
|
# Source: auto-generated from package.json, version.json, benchmarks/latest.json, src/mcp/tools.js, src/config/defaults.js
|
|
16
16
|
# Regenerate: npm run generate:llms | Validate: npm run validate:llms
|
|
17
17
|
|
package/llms.txt
CHANGED
|
@@ -11,7 +11,7 @@ ranking keeps the relevant context in scope (cutting tokens ~97% as a side
|
|
|
11
11
|
effect), with no LLM calls, embeddings, or vector database. Works with Claude,
|
|
12
12
|
Cursor, GitHub Copilot, Aider, Windsurf, local LLMs, and MCP.
|
|
13
13
|
|
|
14
|
-
# Version: 8.8.
|
|
14
|
+
# Version: 8.8.1 | Benchmark: sigmap-v8.8-main (2026-07-05)
|
|
15
15
|
# Source: auto-generated from package.json, version.json, benchmarks/latest.json, src/mcp/tools.js, src/config/defaults.js
|
|
16
16
|
# Regenerate: npm run generate:llms | Validate: npm run validate:llms
|
|
17
17
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sigmap",
|
|
3
|
-
"version": "8.8.
|
|
3
|
+
"version": "8.8.1",
|
|
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": {
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
"test": "node test/run.js && node test/r-language.test.js",
|
|
18
18
|
"test:integration": "node test/integration/strategy.test.js && node test/integration/secret-scan.test.js && node test/integration/token-budget.test.js && node test/integration/auto-budget.test.js && node test/integration/mcp/server.test.js && node test/integration/verify-ai-output.test.js && node test/integration/memory-tools.test.js && node test/integration/squeeze.test.js && node test/integration/context-consistency.test.js && node test/integration/features/llms-current.test.js",
|
|
19
19
|
"test:integration:all": "node test/integration/all.js",
|
|
20
|
+
"test:python": "python3 test/test_python_ast_extractor.py",
|
|
20
21
|
"test:all": "node test/run.js && node test/r-language.test.js && node test/integration/strategy.test.js && node test/integration/secret-scan.test.js",
|
|
21
22
|
"generate": "node gen-context.js",
|
|
22
23
|
"watch": "node gen-context.js --watch",
|
package/src/mcp/server.js
CHANGED