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 +63 -76
- package/CHANGELOG.md +18 -0
- package/README.md +5 -3
- package/gen-context.js +123 -11
- package/package.json +1 -1
- package/packages/adapters/codex.js +3 -3
- package/packages/cli/package.json +1 -1
- package/packages/core/package.json +1 -1
- package/src/extractors/typescript.js +4 -1
- package/src/mcp/server.js +1 -1
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 —
|
|
16
|
+
## changes (last 5 commits — 3 minutes ago)
|
|
27
17
|
```
|
|
28
|
-
src/
|
|
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
|
-
|
|
148
|
-
|
|
149
|
-
### src/map/route-table.js
|
|
130
|
+
### packages/adapters/codex.js
|
|
150
131
|
```
|
|
151
|
-
module.exports = {
|
|
152
|
-
function
|
|
153
|
-
function
|
|
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
|
-
|
|
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
|
-
|
|
161
|
-
|
|
162
|
-
|
|
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.
|
|
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
|
-
|
|
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.
|
|
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(
|
|
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(
|
|
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(
|
|
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() +
|
|
7836
|
+
newContent = existing.slice(0, markerIdx) + MARKER.trimStart() + sigHeader + body;
|
|
7750
7837
|
} else {
|
|
7751
|
-
newContent = existing + MARKER +
|
|
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
|
-
|
|
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 (
|
|
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
|
@@ -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
|
|
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
|
-
|
|
28
|
+
if (!context || typeof context !== 'string' || !context.trim()) return '';
|
|
29
|
+
return `# Code signatures\n\n${context}`;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
/**
|
|
@@ -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