sigmap 6.0.0 → 6.0.2

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
@@ -11,21 +11,12 @@ 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 v5.7.0 on 2026-04-17T21:17:18.905Z.
16
-
17
- Use these signatures to answer questions about the code accurately.
18
-
19
- ## Code Signatures
20
-
21
- <!-- Generated by SigMap gen-context.js v5.7.0 -->
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 — 7 minutes ago)
16
+ ## changes (last 5 commits — 3 minutes ago)
27
17
  ```
28
- src/analysis/coverage-score.js ~coverageScore ~_walk
18
+ src/extractors/typescript.js ~extractInterfaceMembers ~extractClassMembers
19
+ packages/adapters/codex.js ~format
29
20
  ```
30
21
 
31
22
  ## packages
@@ -36,14 +27,6 @@ module.exports = { CLI_ENTRY, run }
36
27
  function run(argv, cwd) → void
37
28
  ```
38
29
 
39
- ### packages/adapters/codex.js
40
- ```
41
- module.exports = { name, format, outputPath, write }
42
- function format(context, opts = {}) → string
43
- function outputPath(cwd) → string
44
- function write(context, cwd, opts = {})
45
- ```
46
-
47
30
  ### packages/adapters/index.js
48
31
  ```
49
32
  module.exports = { getAdapter, listAdapters, adapt, outputsToAdapters }
@@ -144,21 +127,15 @@ function score(cwd) → { * score: number, * grad
144
127
  function adapt(context, adapterName, opts = {}) → string
145
128
  ```
146
129
 
147
- ## src
148
-
149
- ### src/map/route-table.js
130
+ ### packages/adapters/codex.js
150
131
  ```
151
- module.exports = { analyze }
152
- function shouldSkipFile(rel)
153
- function analyze(files, cwd)
132
+ module.exports = { name, format, outputPath, write }
133
+ function format(context, opts = {}) → string
134
+ function outputPath(cwd) → string
135
+ function write(context, cwd, opts = {})
154
136
  ```
155
137
 
156
- ### src/routing/classifier.js
157
- ```
158
- module.exports = { classify, classifyAll }
159
- function classify(filePath, sigs) → 'fast'|'balanced'|'powerf
160
- function classifyAll(fileEntries, cwd) → { fast: string[], balance
161
- ```
138
+ ## src
162
139
 
163
140
  ### src/routing/hints.js
164
141
  ```
@@ -177,14 +154,6 @@ module.exports = { scan }
177
154
  function scan(signatures, filePath) → { safe: string[], redacte
178
155
  ```
179
156
 
180
- ### src/tracking/logger.js
181
- ```
182
- module.exports = { logRun, readLog, summarize }
183
- function logRun(entry, cwd)
184
- function readLog(cwd) → object[]
185
- function summarize(entries) → object
186
- ```
187
-
188
157
  ### src/extractors/cpp.js
189
158
  ```
190
159
  module.exports = { extract }
@@ -344,16 +313,6 @@ module.exports = { extractTodos }
344
313
  function extractTodos(src) → {line:number, tag:string,
345
314
  ```
346
315
 
347
- ### src/extractors/typescript.js
348
- ```
349
- module.exports = { extract }
350
- function extract(src) → string[]
351
- function extractBlock(src, startIndex)
352
- function extractInterfaceMembers(block)
353
- function extractClassMembers(block)
354
- function normalizeParams(params)
355
- ```
356
-
357
316
  ### src/extractors/vue.js
358
317
  ```
359
318
  module.exports = { extract }
@@ -607,32 +566,6 @@ function penalizeFiles(cwd, files, amount = 0.10)
607
566
  function resetWeights(cwd)
608
567
  ```
609
568
 
610
- ### src/mcp/handlers.js
611
- ```
612
- module.exports = { readContext, searchSignatures, getMap, createCheckpoint, getRouting, explainFile, listModules, queryContext, getImpact }
613
- function readContext(args, cwd)
614
- function searchSignatures(args, cwd)
615
- function getMap(args, cwd)
616
- function createCheckpoint(args, cwd)
617
- function getRouting(args, cwd)
618
- function explainFile(args, cwd)
619
- function listModules(args, cwd)
620
- function queryContext(args, cwd)
621
- function getImpact(args, cwd)
622
- ```
623
-
624
- ### src/retrieval/ranker.js
625
- ```
626
- module.exports = { rank, buildSigIndex, scoreFile, formatRankTable, formatRankJSON, DEFAULT_WEIGHTS, detectIntent }
627
- function scoreFile(filePath, sigs, queryTokens, weights) → number
628
- function rank(query, sigIndex, opts) → { file: string, score: nu
629
- function _parseContextFile(contextPath) → Map<string, string[]>
630
- function buildSigIndex(cwd, opts) → Map<string, string[]>
631
- function formatRankTable(results, query) → string
632
- function formatRankJSON(results, query) → object
633
- function detectIntent(query)
634
- ```
635
-
636
569
  ### src/format/benchmark-report.js
637
570
  ```
638
571
  module.exports = { loadBenchmarkReports, buildBenchmarkSummary, generateBenchmarkReportHtml, writeBenchmarkReport }
@@ -667,6 +600,60 @@ function coverageScore(cwd, fileEntries, config)
667
600
  function _walk(dir, excludeSet, out)
668
601
  ```
669
602
 
603
+ ### src/cache/sig-cache.js
604
+ ```
605
+ module.exports = { loadCache, saveCache, getChangedFiles, updateCacheEntries }
606
+ function cachePath(cwd)
607
+ function loadCache(cwd, currentVersion) → Map<string, { mtime: numb
608
+ function saveCache(cwd, currentVersion, cache)
609
+ function getChangedFiles(files, cache) → { changed: string[], unch
610
+ function updateCacheEntries(cache, extracted)
611
+ ```
612
+
613
+ ### src/mcp/handlers.js
614
+ ```
615
+ module.exports = { readContext, searchSignatures, getMap, createCheckpoint, getRouting, explainFile, listModules, queryContext, getImpact }
616
+ function readContext(args, cwd)
617
+ function searchSignatures(args, cwd)
618
+ function getMap(args, cwd)
619
+ function createCheckpoint(args, cwd)
620
+ function getRouting(args, cwd)
621
+ function explainFile(args, cwd)
622
+ function listModules(args, cwd)
623
+ function queryContext(args, cwd)
624
+ function getImpact(args, cwd)
625
+ ```
626
+
627
+ ### src/retrieval/ranker.js
628
+ ```
629
+ module.exports = { rank, buildSigIndex, scoreFile, formatRankTable, formatRankJSON, DEFAULT_WEIGHTS, detectIntent }
630
+ function scoreFile(filePath, sigs, queryTokens, weights) → number
631
+ function rank(query, sigIndex, opts) → { file: string, score: nu
632
+ function _parseContextFile(contextPath) → Map<string, string[]>
633
+ function buildSigIndex(cwd, opts) → Map<string, string[]>
634
+ function formatRankTable(results, query) → string
635
+ function formatRankJSON(results, query) → object
636
+ function detectIntent(query)
637
+ ```
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
+
670
657
  ### src/mcp/server.js
671
658
  ```
672
659
  module.exports = { start }
package/CHANGELOG.md CHANGED
@@ -10,6 +10,24 @@ Format: [Semantic Versioning](https://semver.org/)
10
10
 
11
11
  ---
12
12
 
13
+ ## [6.0.2] — 2026-04-21
14
+
15
+ ### Fixed
16
+
17
+ - **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()`.
18
+ - **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.
19
+
20
+ ---
21
+
22
+ ## [6.0.1] — 2026-04-21
23
+
24
+ ### Fixed
25
+
26
+ - **TypeScript extractor guard clauses (#97)** — `extractClassMembers` now skips control-flow keywords (`if`, `for`, `while`, `switch`, `do`, `try`, `catch`, `finally`, `else`) that were incorrectly emitted as method signatures when they appeared inside class bodies.
27
+ - **Codex/AGENTS.md adapter preamble (#96)** — `packages/adapters/codex.js` no longer delegates to the OpenAI adapter. Output is now clean `# Code signatures\n\n<context>` markdown with no "You are a coding assistant…" preamble, no HTML comment metadata block, and no duplicate headers.
28
+
29
+ ---
30
+
13
31
  ## [6.0.0] — 2026-04-19
14
32
 
15
33
  ### Added
package/README.md CHANGED
@@ -157,9 +157,11 @@ sigmap --adapter cursor
157
157
 
158
158
  **IDE extensions:**
159
159
 
160
- - [VS Code extension](https://marketplace.visualstudio.com/items?itemName=manojmallick.sigmap) status bar health grade, stale alerts, one-click regen
161
- - [JetBrains plugin](https://plugins.jetbrains.com/plugin/31109-sigmap--ai-context-engine/) — IntelliJ IDEA, WebStorm, PyCharm, GoLand
162
- - [Neovim plugin](https://github.com/manojmallick/sigmap.nvim) `:SigMap`, `:SigMapQuery`, statusline widget
160
+ | IDE | Install | Source | Features |
161
+ |-----|---------|--------|----------|
162
+ | **VS Code** | [Marketplace](https://marketplace.visualstudio.com/items?itemName=manojmallick.sigmap) · [Open VSX](https://open-vsx.org/extension/manojmallick/sigmap) | [github.com/manojmallick/sigmap-vscode](https://github.com/manojmallick/sigmap-vscode) | Status bar health grade, stale context alerts, one-click regen |
163
+ | **JetBrains** | [Marketplace](https://plugins.jetbrains.com/plugin/31109-sigmap--ai-context-engine/) | [github.com/manojmallick/sigmap-jetbrains](https://github.com/manojmallick/sigmap-jetbrains) | IntelliJ IDEA, WebStorm, PyCharm, GoLand — tool window + actions |
164
+ | **Neovim** | lazy.nvim / packer / vim-plug | [github.com/manojmallick/sigmap.nvim](https://github.com/manojmallick/sigmap.nvim) | `:SigMap`, `:SigMapQuery` float window, statusline widget |
163
165
 
164
166
  **MCP server** — 9 on-demand tools for Claude Code and Cursor:
165
167
 
package/gen-context.js CHANGED
@@ -4520,6 +4520,71 @@ __factories["./src/map/route-table"] = function(module, exports) {
4520
4520
 
4521
4521
  };
4522
4522
 
4523
+ // ── ./src/cache/sig-cache ──
4524
+ __factories["./src/cache/sig-cache"] = function(module, exports) {
4525
+ 'use strict';
4526
+
4527
+ const fs = require('fs');
4528
+ const path = require('path');
4529
+
4530
+ const CACHE_FILE = '.sigmap-cache.json';
4531
+
4532
+ function cachePath(cwd) {
4533
+ return path.join(cwd, CACHE_FILE);
4534
+ }
4535
+
4536
+ function loadCache(cwd, currentVersion) {
4537
+ try {
4538
+ const raw = fs.readFileSync(cachePath(cwd), 'utf8');
4539
+ const data = JSON.parse(raw);
4540
+ if (data.sigmapVersion !== currentVersion) return new Map();
4541
+ return new Map(Object.entries(data.entries || {}));
4542
+ } catch (_) {
4543
+ return new Map();
4544
+ }
4545
+ }
4546
+
4547
+ function saveCache(cwd, currentVersion, cache) {
4548
+ try {
4549
+ const data = {
4550
+ sigmapVersion: currentVersion,
4551
+ entries: Object.fromEntries(cache),
4552
+ };
4553
+ fs.writeFileSync(cachePath(cwd), JSON.stringify(data), 'utf8');
4554
+ } catch (_) {}
4555
+ }
4556
+
4557
+ function getChangedFiles(files, cache) {
4558
+ const changed = [];
4559
+ const unchanged = [];
4560
+ for (const f of files) {
4561
+ try {
4562
+ const mtime = fs.statSync(f).mtimeMs;
4563
+ const cached = cache.get(f);
4564
+ if (!cached || cached.mtime !== mtime) {
4565
+ changed.push(f);
4566
+ } else {
4567
+ unchanged.push(f);
4568
+ }
4569
+ } catch (_) {
4570
+ changed.push(f);
4571
+ }
4572
+ }
4573
+ return { changed, unchanged };
4574
+ }
4575
+
4576
+ function updateCacheEntries(cache, extracted) {
4577
+ for (const { file, sigs } of extracted) {
4578
+ try {
4579
+ const mtime = fs.statSync(file).mtimeMs;
4580
+ cache.set(file, { mtime, sigs });
4581
+ } catch (_) {}
4582
+ }
4583
+ }
4584
+
4585
+ module.exports = { loadCache, saveCache, getChangedFiles, updateCacheEntries };
4586
+ };
4587
+
4523
4588
  // ── ./src/graph/builder ──
4524
4589
  __factories["./src/graph/builder"] = function(module, exports) {
4525
4590
  'use strict';
@@ -5291,7 +5356,7 @@ __factories["./src/mcp/server"] = function(module, exports) {
5291
5356
 
5292
5357
  const SERVER_INFO = {
5293
5358
  name: 'sigmap',
5294
- version: '6.0.0',
5359
+ version: '6.0.2',
5295
5360
  description: 'SigMap MCP server — code signatures on demand',
5296
5361
  };
5297
5362
 
@@ -6801,11 +6866,11 @@ __factories["./packages/adapters/gemini"] = function(module, exports) {
6801
6866
  __factories["./packages/adapters/codex"] = function(module, exports) {
6802
6867
  const path = require('path');
6803
6868
  const fs = require('fs');
6804
- const openai = __require('./packages/adapters/openai');
6805
6869
  const name = 'codex';
6806
6870
  const CODEX_MARKER = '\n\n## Auto-generated signatures\n<!-- Updated by gen-context.js -->\n';
6807
6871
  function format(context, opts = {}) {
6808
- return openai.format(context, opts);
6872
+ if (!context || typeof context !== 'string' || !context.trim()) return '';
6873
+ return '# Code signatures\n\n' + context;
6809
6874
  }
6810
6875
  function outputPath(cwd) { return path.join(cwd, 'AGENTS.md'); }
6811
6876
  function write(context, cwd, opts = {}) {
@@ -7009,7 +7074,7 @@ const path = require('path');
7009
7074
  const os = require('os');
7010
7075
  const { execSync } = require('child_process');
7011
7076
 
7012
- const VERSION = '6.0.0';
7077
+ const VERSION = '6.0.2';
7013
7078
  const MARKER = '\n\n## Auto-generated signatures\n<!-- Updated by gen-context.js -->\n';
7014
7079
 
7015
7080
  function requireSourceOrBundled(key) {
@@ -7697,13 +7762,17 @@ function writeOutputs(content, targets, cwd, config) {
7697
7762
  if (ADAPTER_TARGETS.has(target)) {
7698
7763
  try {
7699
7764
  const adapterMod = __require('./packages/adapters/' + target);
7765
+ // Adapters add their own header via format() — strip the formatOutput() header
7766
+ // so the content body (## src, ## deps, etc.) is passed without a pre-existing
7767
+ // header, preventing duplicate "# Code signatures" blocks on every run.
7768
+ const adapterContent = stripFormatHeader(content);
7700
7769
  // copilot: honour config.output custom path (redirects away from default .github/copilot-instructions.md)
7701
7770
  if (target === 'copilot') {
7702
7771
  const outPath = resolveAdapterPath('copilot', cwd, config);
7703
7772
  const defaultPath = path.join(cwd, '.github', 'copilot-instructions.md');
7704
7773
  if (outPath !== defaultPath) {
7705
7774
  // custom path: format and write directly (no append logic)
7706
- const formatted = adapterMod.format(content, { version: VERSION });
7775
+ const formatted = adapterMod.format(adapterContent, { version: VERSION });
7707
7776
  ensureDir(outPath);
7708
7777
  fs.writeFileSync(outPath, formatted, 'utf8');
7709
7778
  console.warn(`[sigmap] wrote ${path.relative(cwd, outPath)}`);
@@ -7711,11 +7780,11 @@ function writeOutputs(content, targets, cwd, config) {
7711
7780
  }
7712
7781
  }
7713
7782
  if (typeof adapterMod.write === 'function') {
7714
- adapterMod.write(content, cwd, { version: VERSION });
7783
+ adapterMod.write(adapterContent, cwd, { version: VERSION });
7715
7784
  const outPath = adapterMod.outputPath(cwd);
7716
7785
  console.warn(`[sigmap] wrote ${path.relative(cwd, outPath)} (appended signatures)`);
7717
7786
  } else {
7718
- const formatted = adapterMod.format(content, { version: VERSION });
7787
+ const formatted = adapterMod.format(adapterContent, { version: VERSION });
7719
7788
  const outPath = adapterMod.outputPath(cwd);
7720
7789
  ensureDir(outPath);
7721
7790
  fs.writeFileSync(outPath, formatted, 'utf8');
@@ -7737,18 +7806,36 @@ function writeOutputs(content, targets, cwd, config) {
7737
7806
  }
7738
7807
  }
7739
7808
 
7809
+ // Strip the formatOutput() header block before passing content to adapters.
7810
+ // formatOutput() prepends "<!-- Generated... -->\n\n# Code signatures\n\n" which
7811
+ // is the raw-file header. Adapters add their own header via format(), so passing
7812
+ // pre-headered content produces duplicate headers on every run.
7813
+ function stripFormatHeader(content) {
7814
+ if (!content || typeof content !== 'string') return content;
7815
+ // Header ends after "# Code signatures\n\n" (with blank line)
7816
+ const marker = '\n# Code signatures\n';
7817
+ const idx = content.indexOf(marker);
7818
+ if (idx === -1) return content;
7819
+ // Skip past the marker line and one blank line
7820
+ const afterMarker = content.slice(idx + marker.length);
7821
+ return afterMarker.startsWith('\n') ? afterMarker.slice(1) : afterMarker;
7822
+ }
7823
+
7740
7824
  function writeClaude(content, cwd) {
7741
7825
  const claudePath = path.join(cwd, 'CLAUDE.md');
7742
7826
  let existing = '';
7743
7827
  if (fs.existsSync(claudePath)) {
7744
7828
  existing = fs.readFileSync(claudePath, 'utf8');
7745
7829
  }
7830
+ // Strip the formatOutput() header — CLAUDE.md gets its own header via the MARKER
7831
+ const body = stripFormatHeader(content);
7832
+ const sigHeader = '# Code signatures\n\n';
7746
7833
  const markerIdx = existing.indexOf('## Auto-generated signatures');
7747
7834
  let newContent;
7748
7835
  if (markerIdx !== -1) {
7749
- newContent = existing.slice(0, markerIdx) + MARKER.trimStart() + content;
7836
+ newContent = existing.slice(0, markerIdx) + MARKER.trimStart() + sigHeader + body;
7750
7837
  } else {
7751
- newContent = existing + MARKER + content;
7838
+ newContent = existing + MARKER + sigHeader + body;
7752
7839
  }
7753
7840
  fs.writeFileSync(claudePath, newContent, 'utf8');
7754
7841
  console.warn(`[sigmap] wrote CLAUDE.md (appended signatures)`);
@@ -8844,10 +8931,30 @@ function main() {
8844
8931
  }
8845
8932
 
8846
8933
  const invokedFrom = process.cwd();
8847
- const cwd = resolveProjectRoot(invokedFrom);
8934
+
8935
+ // --cwd <dir>: restrict scanning to that directory instead of the project root
8936
+ const cwdFlagIdx = args.indexOf('--cwd');
8937
+ const cwdFlag = cwdFlagIdx !== -1 ? (args[cwdFlagIdx + 1] || '').trim() : null;
8938
+ if (cwdFlag !== null && (!cwdFlag || cwdFlag.startsWith('--'))) {
8939
+ console.error('[sigmap] --cwd requires a directory path');
8940
+ process.exit(1);
8941
+ }
8942
+ const cwd = cwdFlag
8943
+ ? path.resolve(invokedFrom, cwdFlag)
8944
+ : resolveProjectRoot(invokedFrom);
8848
8945
  const scriptPath = process.argv[1] || path.join(invokedFrom, 'gen-context.js');
8849
8946
 
8850
- if (cwd !== invokedFrom) {
8947
+ if (cwdFlag) {
8948
+ if (!fs.existsSync(cwd)) {
8949
+ console.error(`[sigmap] --cwd directory does not exist: ${cwd}`);
8950
+ process.exit(1);
8951
+ }
8952
+ if (!fs.statSync(cwd).isDirectory()) {
8953
+ console.error(`[sigmap] --cwd must be a directory, not a file: ${cwd}`);
8954
+ process.exit(1);
8955
+ }
8956
+ console.warn(`[sigmap] --cwd: restricting scan to ${cwd}`);
8957
+ } else if (cwd !== invokedFrom) {
8851
8958
  console.warn(`[sigmap] using project root: ${cwd}`);
8852
8959
  }
8853
8960
 
@@ -8870,6 +8977,11 @@ function main() {
8870
8977
 
8871
8978
  const config = loadConfig(cwd);
8872
8979
 
8980
+ // --cwd restricts scanning: override srcDirs so only the given directory is scanned
8981
+ if (cwdFlag) {
8982
+ config.srcDirs = ['.'];
8983
+ }
8984
+
8873
8985
  // ── --output <file> — parse early so every subsequent block can use it ─────
8874
8986
  // Resolves the custom output path and merges it into config.customOutput.
8875
8987
  // Also persists the resolved relative path to gen-context.config.json so
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sigmap",
3
- "version": "6.0.0",
3
+ "version": "6.0.2",
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": {
@@ -14,19 +14,19 @@
14
14
 
15
15
  const path = require('path');
16
16
  const fs = require('fs');
17
- const openai = require('./openai');
18
17
 
19
18
  const name = 'codex';
20
19
  const MARKER = '\n\n## Auto-generated signatures\n<!-- Updated by gen-context.js -->\n';
21
20
 
22
21
  /**
23
- * Format context using the OpenAI adapter format.
22
+ * Format context for AGENTS.md clean markdown, no LLM preamble.
24
23
  * @param {string} context - Raw signature context string
25
24
  * @param {object} [opts]
26
25
  * @returns {string}
27
26
  */
28
27
  function format(context, opts = {}) {
29
- return openai.format(context, opts);
28
+ if (!context || typeof context !== 'string' || !context.trim()) return '';
29
+ return `# Code signatures\n\n${context}`;
30
30
  }
31
31
 
32
32
  /**
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sigmap-cli",
3
- "version": "6.0.0",
3
+ "version": "6.0.2",
4
4
  "description": "SigMap CLI wrapper — thin adapter for programmatic CLI invocation",
5
5
  "main": "index.js",
6
6
  "keywords": [
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sigmap-core",
3
- "version": "6.0.0",
3
+ "version": "6.0.2",
4
4
  "description": "SigMap core library — zero-dependency code signature extraction, retrieval, and security scanning",
5
5
  "main": "index.js",
6
6
  "keywords": [
@@ -146,11 +146,14 @@ function extractInterfaceMembers(block) {
146
146
  return members.slice(0, 8);
147
147
  }
148
148
 
149
+ const _CTRL_KEYWORDS = new Set(['if', 'for', 'while', 'switch', 'do', 'try', 'catch', 'finally', 'else', 'return']);
150
+
149
151
  function extractClassMembers(block) {
150
152
  const members = [];
151
- // Public methods (skip private/protected/_ prefixed)
153
+ // Public methods (skip private/protected/_ prefixed and control-flow keywords)
152
154
  const methodRe = /^\s+(?:public\s+|static\s+|async\s+|override\s+)*(\w+)\s*(?:<[^(]*>)?\s*\(([^)]*)\)(?:\s*:\s*[^{;]+)?\s*\{/gm;
153
155
  for (const m of block.matchAll(methodRe)) {
156
+ if (_CTRL_KEYWORDS.has(m[1])) continue;
154
157
  if (/^(private|protected|_)/.test(m[1])) continue;
155
158
  if (m[1] === 'constructor') { members.push(`constructor(${normalizeParams(m[2])})`); continue; }
156
159
  const isAsync = m[0].includes('async ') ? 'async ' : '';
package/src/mcp/server.js CHANGED
@@ -18,7 +18,7 @@ const { readContext, searchSignatures, getMap, createCheckpoint, getRouting, exp
18
18
 
19
19
  const SERVER_INFO = {
20
20
  name: 'sigmap',
21
- version: '6.0.0',
21
+ version: '6.0.2',
22
22
  description: 'SigMap MCP server — code signatures on demand',
23
23
  };
24
24