sigmap 2.0.0-beta.5 → 2.0.0-beta.6

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 CHANGED
@@ -6,6 +6,17 @@ Format: [Semantic Versioning](https://semver.org/)
6
6
 
7
7
  ---
8
8
 
9
+ ## [2.0.0-beta.6] — 2026-04-04
10
+
11
+ ### Changed
12
+ - Prerelease version bumped from `2.0.0-beta.5` to `2.0.0-beta.6` across CLI, MCP server info, root package metadata, and VS Code extension metadata.
13
+
14
+ ### Validation gate
15
+ - 21/21 extractor tests passed
16
+ - 17/17 integration suites passed (including v2plus 3/3)
17
+
18
+ ---
19
+
9
20
  ## [2.0.0-beta.5] — 2026-04-03
10
21
 
11
22
  ### Changed
package/gen-context.js CHANGED
@@ -983,8 +983,26 @@ __factories["./src/extractors/python"] = function(module, exports) {
983
983
  const retStr = retType ? ` \u2192 ${retType}` : '';
984
984
  sigs.push(`${asyncKw}def ${m[2]}(${params})${retStr}`);
985
985
  }
986
+
987
+ // FastAPI router endpoints: @router.METHOD("path") + async def name(...)
988
+ const lines = noComments.split('\n');
989
+ for (let i = 0; i < lines.length - 1; i++) {
990
+ const decLine = lines[i].trim();
991
+ const rm = decLine.match(/^@\w+\.(get|post|put|patch|delete|head)\s*\(\s*['"]([^'"]+)['"]/);
992
+ if (!rm) continue;
993
+ // Find the next non-empty, non-decorator line that starts the function
994
+ for (let j = i + 1; j < Math.min(i + 6, lines.length); j++) {
995
+ const fl = lines[j].trim();
996
+ const fm = fl.match(/^(?:async\s+)?def\s+(\w+)/);
997
+ if (fm) {
998
+ sigs.push(`${rm[1].toUpperCase()} ${rm[2]} → ${fm[1]}()`);
999
+ break;
1000
+ }
1001
+ if (fl && !fl.startsWith('@') && !fl.startsWith('#')) break;
1002
+ }
1003
+ }
986
1004
 
987
- return sigs.slice(0, 25);
1005
+ return sigs.slice(0, 30);
988
1006
  }
989
1007
 
990
1008
  function extractClassMethods(stripped, startIndex) {
@@ -1562,8 +1580,36 @@ __factories["./src/extractors/typescript"] = function(module, exports) {
1562
1580
  const params = normalizeParams(m[2]);
1563
1581
  sigs.push(`export const ${m[1]} = ${asyncKw}(${params}) =>`);
1564
1582
  }
1583
+
1584
+ // Zustand stores: export const useXxxStore = create<State>()(...)
1585
+ for (const m of stripped.matchAll(/^export\s+const\s+(use\w+Store)\s*=\s*create(?:<[^>]*>)?\s*\(/gm)) {
1586
+ // Extract the State interface name from create<StateName>
1587
+ const stateType = m[0].match(/create<([\w]+)>/)?.[1] || '';
1588
+ sigs.push(`export const ${m[1]} = create<${stateType}>(...)`);
1589
+ // Extract action/state keys from the embedded interface in same file
1590
+ const ifaceRe = new RegExp(`interface\\s+${stateType}\\s*\\{([\\s\\S]*?)\\}`);
1591
+ const ifm = stripped.match(ifaceRe);
1592
+ if (ifm) {
1593
+ for (const fm of ifm[1].matchAll(/^\s+(\w+)\s*(?:\([^)]*\))?\s*:/gm)) {
1594
+ sigs.push(` ${fm[1]}`);
1595
+ }
1596
+ }
1597
+ }
1598
+
1599
+ // API client objects: export default { method: async (...) => ... }
1600
+ // Pattern: const xxxApi = { methodName: async ... }
1601
+ for (const m of stripped.matchAll(/^(?:export\s+default\s+|const\s+)(\w*[Aa]pi\w*)\s*=\s*\{/gm)) {
1602
+ const apiName = m[1];
1603
+ const start = m.index + m[0].length;
1604
+ const block = extractBlock(stripped, start);
1605
+ const methods = [];
1606
+ for (const mm of block.matchAll(/^\s+(\w+)\s*:\s*(?:async\s+)?(?:\([^)]*\)|\w+)\s*=>/gm)) {
1607
+ methods.push(mm[1]);
1608
+ }
1609
+ if (methods.length) sigs.push(`${apiName}: { ${methods.join(', ')} }`);
1610
+ }
1565
1611
 
1566
- return sigs.slice(0, 25);
1612
+ return sigs.slice(0, 35);
1567
1613
  }
1568
1614
 
1569
1615
  function extractBlock(src, startIndex) {
@@ -3520,7 +3566,7 @@ const path = require('path');
3520
3566
  const os = require('os');
3521
3567
  const { execSync } = require('child_process');
3522
3568
 
3523
- const VERSION = '2.0.0-beta.5';
3569
+ const VERSION = '2.0.0-beta.6';
3524
3570
  const MARKER = '\n\n## Auto-generated signatures\n<!-- Updated by gen-context.js -->\n';
3525
3571
 
3526
3572
  function requireSourceOrBundled(key) {
@@ -3919,9 +3965,11 @@ function buildChangesSection(cwd, config, fileEntries) {
3919
3965
  }
3920
3966
  const plus = [...diff.matchAll(/^\+.*(?:def\s+|function\s+|class\s+|func\s+)(\w+)/gm)].map((m) => `+${m[1]}`);
3921
3967
  const modDef = [...diff.matchAll(/^-.*(?:def\s+|function\s+|class\s+|func\s+)(\w+)/gm)].map((m) => `~${m[1]}`);
3922
- // Also extract function names from @@ hunk headers (catches body-only changes like added comments/lines)
3968
+ // Hunk headers (Python/Go/Java: git shows enclosing func in @@ ... @@ context)
3923
3969
  const modCtx = [...diff.matchAll(/^@@[^@]*@@\s+(?:(?:async|export|public|private|static)\s+)*(?:def|function|class|func)\s+(\w+)/gm)].map((m) => `~${m[1]}`);
3924
- const delta = [...new Set([...plus, ...modDef, ...modCtx])].slice(0, 4).join(' ');
3970
+ // Context lines (TS/JS: git doesn't detect funcname, so scan the unchanged lines adjacent to hunks)
3971
+ const ctxFn = [...diff.matchAll(/^ +(?:export\s+)?(?:async\s+)?(?:default\s+)?(?:function\s+(\w+)|class\s+(\w+))/gm)].map((m) => `~${m[1] || m[2]}`);
3972
+ const delta = [...new Set([...plus, ...modDef, ...modCtx, ...ctxFn])].slice(0, 4).join(' ');
3925
3973
  if (delta) {
3926
3974
  hasDelta = true;
3927
3975
  lines.push(`${rel.padEnd(45)} ${delta}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sigmap",
3
- "version": "2.0.0-beta.5",
3
+ "version": "2.0.0-beta.6",
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
  "bin": {
@@ -63,7 +63,21 @@ function extract(src) {
63
63
  sigs.push(`${asyncKw}def ${m[2]}(${params})${retStr}${hintStr}`);
64
64
  }
65
65
 
66
- return sigs.slice(0, 25);
66
+ // FastAPI router endpoints: @router.METHOD("path") + async def name(...)
67
+ const lines = noComments.split('\n');
68
+ for (let i = 0; i < lines.length - 1; i++) {
69
+ const decLine = lines[i].trim();
70
+ const rm = decLine.match(/^@\w+\.(get|post|put|patch|delete|head)\s*\(\s*['"]([^'"]+)['"]/);
71
+ if (!rm) continue;
72
+ for (let j = i + 1; j < Math.min(i + 6, lines.length); j++) {
73
+ const fl = lines[j].trim();
74
+ const fm = fl.match(/^(?:async\s+)?def\s+(\w+)/);
75
+ if (fm) { sigs.push(`${rm[1].toUpperCase()} ${rm[2]} → ${fm[1]}()`); break; }
76
+ if (fl && !fl.startsWith('@') && !fl.startsWith('#')) break;
77
+ }
78
+ }
79
+
80
+ return sigs.slice(0, 30);
67
81
  }
68
82
 
69
83
  function extractClassMethods(stripped, startIndex) {
@@ -99,7 +99,25 @@ function extract(src) {
99
99
  }
100
100
  }
101
101
 
102
- return sigs.slice(0, 25);
102
+ // Zustand stores: export const useXxxStore = create<State>()(...)
103
+ for (const m of stripped.matchAll(/^export\s+const\s+(use\w+Store)\s*=\s*create(?:<[^>]*>)?\s*\(/gm)) {
104
+ const stateType = m[0].match(/create<([\w]+)>/)?.[1] || '';
105
+ sigs.push(`export const ${m[1]} = create<${stateType}>(...)`);
106
+ const ifaceRe = new RegExp(`interface\\s+${stateType}\\s*\\{([\\s\\S]*?)\\}`);
107
+ const ifm = stripped.match(ifaceRe);
108
+ if (ifm) {
109
+ for (const fm of ifm[1].matchAll(/^\s+(\w+)\s*(?:\([^)]*\))?\s*:/gm)) sigs.push(` ${fm[1]}`);
110
+ }
111
+ }
112
+
113
+ // API client objects: const xxxApi = { method: async () => {} }
114
+ for (const m of stripped.matchAll(/^(?:export\s+default\s+|const\s+)(\w*[Aa]pi\w*)\s*=\s*\{/gm)) {
115
+ const block = extractBlock(stripped, m.index + m[0].length);
116
+ const methods = [...block.matchAll(/^\s+(\w+)\s*:\s*(?:async\s+)?(?:\([^)]*\)|\w+)\s*=>/gm)].map(mm => mm[1]);
117
+ if (methods.length) sigs.push(`${m[1]}: { ${methods.join(', ')} }`);
118
+ }
119
+
120
+ return sigs.slice(0, 35);
103
121
  }
104
122
 
105
123
  function extractBlock(src, startIndex) {
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: '2.0.0-beta.5',
21
+ version: '2.0.0-beta.6',
22
22
  description: 'SigMap MCP server — code signatures on demand',
23
23
  };
24
24