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 +11 -0
- package/gen-context.js +53 -5
- package/package.json +1 -1
- package/src/extractors/python.js +15 -1
- package/src/extractors/typescript.js +19 -1
- package/src/mcp/server.js +1 -1
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,
|
|
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,
|
|
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.
|
|
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
|
-
//
|
|
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
|
-
|
|
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
package/src/extractors/python.js
CHANGED
|
@@ -63,7 +63,21 @@ function extract(src) {
|
|
|
63
63
|
sigs.push(`${asyncKw}def ${m[2]}(${params})${retStr}${hintStr}`);
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
|
|
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
|
-
|
|
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