sigmap 3.5.1 → 3.6.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 CHANGED
@@ -12,31 +12,17 @@ Use this marker block for all appendable context files:
12
12
  ## Auto-generated signatures
13
13
  <!-- Updated by gen-context.js -->
14
14
  You are a coding assistant with full knowledge of this codebase.
15
- Below are the code signatures extracted by SigMap v3.5.0 on 2026-04-14T21:58:46.968Z.
15
+ Below are the code signatures extracted by SigMap v3.5.1 on 2026-04-14T23:05:11.451Z.
16
16
 
17
17
  Use these signatures to answer questions about the code accurately.
18
18
 
19
19
  ## Code Signatures
20
20
 
21
- <!-- Generated by SigMap gen-context.js v3.5.0 -->
21
+ <!-- Generated by SigMap gen-context.js v3.5.1 -->
22
22
  <!-- DO NOT EDIT below the marker line — run gen-context.js to regenerate -->
23
23
 
24
24
  # Code signatures
25
25
 
26
- ## changes (last 5 commits — 19 minutes ago)
27
- ```
28
- src/config/loader.js ~detectAutoSrcDirs
29
- src/eval/analyzer.js ~isDockerfile
30
- src/extractors/markdown.js +extract
31
- src/extractors/patterns.js +extract +implementing
32
- src/extractors/properties.js +extract
33
- src/extractors/python_dataclass.js +extract +definitions
34
- src/extractors/toml.js +extract
35
- src/extractors/typescript_react.js +extract +declarations
36
- src/extractors/vue_sfc.js +extract
37
- src/extractors/xml.js +attributes +extract
38
- ```
39
-
40
26
  ## packages
41
27
 
42
28
  ### packages/core/index.js
@@ -99,6 +85,14 @@ function adapt(context, adapterName, opts = {}) → string
99
85
  function outputsToAdapters(outputs) → string[]
100
86
  ```
101
87
 
88
+ ### packages/adapters/llm-full.js
89
+ ```
90
+ module.exports = { name: 'llm-full', format, outputPath, write }
91
+ function outputPath(cwd)
92
+ function format(context, opts)
93
+ function write(context, cwd, opts)
94
+ ```
95
+
102
96
  ### packages/adapters/openai.js
103
97
  ```
104
98
  module.exports = { name, format, outputPath }
@@ -167,12 +161,6 @@ function formatAnalysisTable(stats, showSlow) → string
167
161
  function formatAnalysisJSON(stats) → object
168
162
  ```
169
163
 
170
- ### src/extractors/graphql.js
171
- ```
172
- module.exports = { extract }
173
- function extract(src) → string[]
174
- ```
175
-
176
164
  ### src/extractors/markdown.js
177
165
  ```
178
166
  module.exports = { extract }
@@ -191,32 +179,12 @@ module.exports = { extract }
191
179
  function extract(src) → string[]
192
180
  ```
193
181
 
194
- ### src/extractors/protobuf.js
195
- ```
196
- module.exports = { extract }
197
- function extract(src) → string[]
198
- ```
199
-
200
182
  ### src/extractors/python_dataclass.js
201
183
  ```
202
184
  module.exports = { extract }
203
185
  function extract(src) → string[]
204
186
  ```
205
187
 
206
- ### src/extractors/sql.js
207
- ```
208
- module.exports = { extract }
209
- function extract(src) → string[]
210
- function _cleanName(raw)
211
- function _normalizeParams(raw)
212
- ```
213
-
214
- ### src/extractors/terraform.js
215
- ```
216
- module.exports = { extract }
217
- function extract(src) → string[]
218
- ```
219
-
220
188
  ### src/extractors/toml.js
221
189
  ```
222
190
  module.exports = { extract }
@@ -333,6 +301,12 @@ module.exports = { extract }
333
301
  function extract(src) → string[]
334
302
  ```
335
303
 
304
+ ### src/extractors/generic.js
305
+ ```
306
+ module.exports = { extract }
307
+ function extract(src)
308
+ ```
309
+
336
310
  ### src/extractors/go.js
337
311
  ```
338
312
  module.exports = { extract }
@@ -342,6 +316,12 @@ function extractInterfaceMethods(block)
342
316
  function normalizeParams(params)
343
317
  ```
344
318
 
319
+ ### src/extractors/graphql.js
320
+ ```
321
+ module.exports = { extract }
322
+ function extract(src) → string[]
323
+ ```
324
+
345
325
  ### src/extractors/html.js
346
326
  ```
347
327
  module.exports = { extract }
@@ -396,6 +376,12 @@ function diffSignatures(baseSigs, currentSigs) → {added:string[], removed:
396
376
  function extractName(sig)
397
377
  ```
398
378
 
379
+ ### src/extractors/protobuf.js
380
+ ```
381
+ module.exports = { extract }
382
+ function extract(src) → string[]
383
+ ```
384
+
399
385
  ### src/extractors/python.js
400
386
  ```
401
387
  module.exports = { extract }
@@ -443,6 +429,14 @@ module.exports = { extract }
443
429
  function extract(src) → string[]
444
430
  ```
445
431
 
432
+ ### src/extractors/sql.js
433
+ ```
434
+ module.exports = { extract }
435
+ function extract(src) → string[]
436
+ function _cleanName(raw)
437
+ function _normalizeParams(raw)
438
+ ```
439
+
446
440
  ### src/extractors/svelte.js
447
441
  ```
448
442
  module.exports = { extract }
@@ -461,6 +455,12 @@ function normalizeParams(params)
461
455
  function extractArrowType(str)
462
456
  ```
463
457
 
458
+ ### src/extractors/terraform.js
459
+ ```
460
+ module.exports = { extract }
461
+ function extract(src) → string[]
462
+ ```
463
+
464
464
  ### src/extractors/todos.js
465
465
  ```
466
466
  module.exports = { extractTodos }
@@ -518,6 +518,22 @@ function generateDashboardHtml(cwd, health)
518
518
  function renderHistoryCharts(cwd, health)
519
519
  ```
520
520
 
521
+ ### src/format/llm-txt.js
522
+ ```
523
+ module.exports = { format, outputPath }
524
+ function outputPath(cwd)
525
+ function format(context, cwd, version)
526
+ ```
527
+
528
+ ### src/format/llms-txt.js
529
+ ```
530
+ module.exports = { format, outputPath }
531
+ function outputPath(cwd)
532
+ function getShortCommit(cwd)
533
+ function detectVersion(cwd)
534
+ function format(context, cwd, writtenFiles, sigmapVersion)
535
+ ```
536
+
521
537
  ### src/graph/builder.js
522
538
  ```
523
539
  module.exports = { build, buildFromCwd, extractFileDeps }
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  <div align="center">
2
2
 
3
- <img src="docs-vp/.vitepress/public/logo.svg" alt="SigMap logo" width="64" height="84" />
3
+ <img src="assets/logo.png" alt="SigMap logo" width="80" height="80" />
4
4
 
5
5
  <h1>⚡ SigMap</h1>
6
6
 
@@ -456,6 +456,10 @@ Activates on startup (`onStartupFinished`) — loads within 3 s, never blocks ed
456
456
 
457
457
  The official SigMap JetBrains plugin brings the same features to IntelliJ-based IDEs. Install it from the JetBrains Marketplace and it works identically to the VS Code extension.
458
458
 
459
+ <div align="center">
460
+ <img src="assets/intelij.gif" alt="SigMap JetBrains plugin — status bar health grade, regenerate action, and context auto-refresh in IntelliJ IDEA" width="700" />
461
+ </div>
462
+
459
463
  | Feature | Detail |
460
464
  |---|---|
461
465
  | **Status bar widget** | Shows health grade (`A`-`F`) + time since last regen; updates every 60 s |
package/gen-context.js CHANGED
@@ -6040,7 +6040,7 @@ const path = require('path');
6040
6040
  const os = require('os');
6041
6041
  const { execSync } = require('child_process');
6042
6042
 
6043
- const VERSION = '3.5.1';
6043
+ const VERSION = '3.6.0';
6044
6044
  const MARKER = '\n\n## Auto-generated signatures\n<!-- Updated by gen-context.js -->\n';
6045
6045
 
6046
6046
  function requireSourceOrBundled(key) {
@@ -6270,12 +6270,13 @@ function applyTokenBudget(fileEntries, maxTokens) {
6270
6270
  // Sort by drop priority (drop first = index 0)
6271
6271
  const withPriority = fileEntries.map((e) => {
6272
6272
  let priority = 0;
6273
- if (isGeneratedFile(e.filePath)) priority = 10;
6274
- else if (isMockFile(e.filePath)) priority = 9;
6275
- else if (isTestFile(e.filePath)) priority = 8;
6276
- else if (isConfigFile(e.filePath)) priority = 6;
6273
+ let dropReason = 'budget: low recency';
6274
+ if (isGeneratedFile(e.filePath)) { priority = 10; dropReason = 'budget: generated file'; }
6275
+ else if (isMockFile(e.filePath)) { priority = 9; dropReason = 'budget: mock file'; }
6276
+ else if (isTestFile(e.filePath)) { priority = 8; dropReason = 'budget: test file'; }
6277
+ else if (isConfigFile(e.filePath)) { priority = 6; dropReason = 'budget: config file'; }
6277
6278
  else priority = 4;
6278
- return { ...e, priority };
6279
+ return { ...e, priority, dropReason };
6279
6280
  });
6280
6281
 
6281
6282
  // Within same priority, sort by mtime ascending (oldest first = drop first)
@@ -6285,20 +6286,27 @@ function applyTokenBudget(fileEntries, maxTokens) {
6285
6286
  });
6286
6287
 
6287
6288
  const kept = [];
6288
- let dropped = 0;
6289
+ const verboseDropped = [];
6289
6290
  // Iterate forward: highest drop-priority files (generated=10, mock=9, test=8) are at index 0
6290
6291
  // Drop those first until we're under budget, then keep everything else
6291
6292
  for (const entry of withPriority) {
6292
6293
  const entryTokens = estimateTokens(entry.sigs.join('\n'));
6293
6294
  if (total > effectiveBudget) {
6294
6295
  total -= entryTokens;
6295
- dropped++;
6296
+ verboseDropped.push({ filePath: entry.filePath, reason: entry.dropReason });
6296
6297
  } else {
6297
6298
  kept.push(entry);
6298
6299
  }
6299
6300
  }
6300
- if (dropped > 0) {
6301
- console.warn(`[sigmap] budget: dropped ${dropped} files to stay under ${maxTokens} tokens`);
6301
+ if (verboseDropped.length > 0) {
6302
+ console.warn(`[sigmap] budget: dropped ${verboseDropped.length} files to stay under ${maxTokens} tokens`);
6303
+ // Feature 7: --verbose — print per-file drop reason
6304
+ if (process.argv.includes('--verbose')) {
6305
+ for (const { filePath, reason } of verboseDropped) {
6306
+ console.warn(`[sigmap] dropped: ${path.relative(process.cwd(), filePath)} — ${reason}`);
6307
+ }
6308
+ console.warn(`[sigmap] included: ${kept.length} files, dropped: ${verboseDropped.length}`);
6309
+ }
6302
6310
  }
6303
6311
  return kept;
6304
6312
  }
@@ -7628,6 +7636,87 @@ function main() {
7628
7636
  process.exit(0);
7629
7637
  }
7630
7638
 
7639
+ // Feature 1: `sigmap explain <file>` — why a file is included or excluded
7640
+ if (args[0] === 'explain' || args.includes('--explain')) {
7641
+ const target = args[0] === 'explain'
7642
+ ? args[1]
7643
+ : args[args.indexOf('--explain') + 1];
7644
+
7645
+ if (!target || target.startsWith('--')) {
7646
+ console.error('[sigmap] Usage: sigmap explain <file>');
7647
+ process.exit(1);
7648
+ }
7649
+
7650
+ const absPath = path.resolve(cwd, target);
7651
+ const rel = path.relative(cwd, absPath);
7652
+ const jsonOut = args.includes('--json');
7653
+
7654
+ // 1. Check .contextignore
7655
+ const ignorePatterns = loadIgnorePatterns(cwd);
7656
+ const ignored = matchesIgnore(rel.replace(/\\/g, '/'), ignorePatterns);
7657
+ if (ignored) {
7658
+ if (jsonOut) {
7659
+ process.stdout.write(JSON.stringify({ status: 'excluded', reason: '.contextignore', fix: `remove the pattern or add '!${rel}' as an exception` }) + '\n');
7660
+ } else {
7661
+ console.log(`[sigmap] ${rel} — EXCLUDED`);
7662
+ console.log(` Reason: matched .contextignore`);
7663
+ console.log(` Fix: remove the pattern or add '!${rel}' as an exception`);
7664
+ }
7665
+ process.exit(0);
7666
+ }
7667
+
7668
+ // 2. Check srcDirs membership
7669
+ const inSrcDirs = (config.srcDirs || []).some(d => absPath.startsWith(path.resolve(cwd, d)));
7670
+ if (!inSrcDirs) {
7671
+ if (jsonOut) {
7672
+ process.stdout.write(JSON.stringify({ status: 'excluded', reason: 'not in srcDirs', srcDirs: config.srcDirs, fix: 'add the containing directory to srcDirs in gen-context.config.json' }) + '\n');
7673
+ } else {
7674
+ console.log(`[sigmap] ${rel} — EXCLUDED`);
7675
+ console.log(` Reason: not under any srcDir (${(config.srcDirs || []).join(', ')})`);
7676
+ console.log(` Fix: add the containing directory to srcDirs in gen-context.config.json`);
7677
+ }
7678
+ process.exit(0);
7679
+ }
7680
+
7681
+ // 3. Detect extractor and extract sigs
7682
+ const base = path.basename(absPath);
7683
+ const ext = path.extname(base).toLowerCase();
7684
+ let extractorName = EXT_MAP[ext] || null;
7685
+ if (!extractorName && isDockerfile(base)) extractorName = 'dockerfile';
7686
+ if (!extractorName) extractorName = 'generic';
7687
+
7688
+ let sigs = [];
7689
+ if (fs.existsSync(absPath)) {
7690
+ try {
7691
+ const content = fs.readFileSync(absPath, 'utf8');
7692
+ const extractor = getExtractor(extractorName);
7693
+ if (extractor) sigs = extractor.extract(content).slice(0, config.maxSigsPerFile || 25);
7694
+ } catch (_) {}
7695
+ }
7696
+
7697
+ if (!sigs.length) {
7698
+ if (jsonOut) {
7699
+ process.stdout.write(JSON.stringify({ status: 'excluded', reason: 'no signatures', extractor: extractorName, fix: 'check that the file contains function/class definitions' }) + '\n');
7700
+ } else {
7701
+ console.log(`[sigmap] ${rel} — EXCLUDED`);
7702
+ console.log(` Reason: no extractable signatures (extractor: ${extractorName})`);
7703
+ console.log(` Fix: check that the file contains function/class definitions`);
7704
+ }
7705
+ process.exit(0);
7706
+ }
7707
+
7708
+ // 4. Included
7709
+ if (jsonOut) {
7710
+ process.stdout.write(JSON.stringify({ status: 'included', extractor: extractorName, signatures: sigs.length, preview: sigs.slice(0, 3), sigs }) + '\n');
7711
+ } else {
7712
+ console.log(`[sigmap] ${rel} — INCLUDED`);
7713
+ console.log(` Extractor : ${extractorName}`);
7714
+ console.log(` Signatures: ${sigs.length}`);
7715
+ console.log(` Preview : ${sigs.slice(0, 3).join(' · ')}`);
7716
+ }
7717
+ process.exit(0);
7718
+ }
7719
+
7631
7720
  if (args.includes('--init')) {
7632
7721
  writeInitConfig(cwd);
7633
7722
  process.exit(0);
@@ -7637,7 +7726,14 @@ function main() {
7637
7726
  const { score } = __require('./src/health/scorer');
7638
7727
  const result = score(cwd);
7639
7728
  if (args.includes('--json')) {
7640
- process.stdout.write(JSON.stringify(result) + '\n');
7729
+ // Feature 3 (VS Code) + Feature 5 (JetBrains): emit tokens + reduction for plugins
7730
+ const ctxPath = path.join(cwd, '.github', 'copilot-instructions.md');
7731
+ let tokens = 0;
7732
+ let reduction = result.tokenReductionPct || 0;
7733
+ if (fs.existsSync(ctxPath)) {
7734
+ try { tokens = estimateTokens(fs.readFileSync(ctxPath, 'utf8')); } catch (_) {}
7735
+ }
7736
+ process.stdout.write(JSON.stringify({ ...result, tokens, reduction }) + '\n');
7641
7737
  } else {
7642
7738
  console.log('[sigmap] health:');
7643
7739
  console.log(` score : ${result.score}/100 (grade ${result.grade})`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sigmap",
3
- "version": "3.5.1",
3
+ "version": "3.6.0",
4
4
  "description": "Zero-dependency AI context engine — 97% token reduction. No npm install. Runs on Node 18+.",
5
5
  "main": "gen-context.js",
6
6
  "exports": {