sigmap 3.3.1 → 3.3.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 +42 -0
- package/README.md +92 -43
- package/gen-context.config.json.example +1 -1
- package/gen-context.js +81 -18
- package/package.json +2 -1
- package/packages/adapters/codex.js +74 -0
- package/packages/adapters/copilot.js +36 -1
- package/packages/adapters/gemini.js +36 -1
- package/packages/adapters/index.js +2 -2
- package/packages/cli/package.json +1 -1
- package/packages/core/package.json +1 -1
- package/src/mcp/server.js +1 -1
package/AGENTS.md
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# SigMap — AGENTS.md
|
|
2
|
+
|
|
3
|
+
Instructions for Codex-style agents working in this repository.
|
|
4
|
+
|
|
5
|
+
## Append Strategy (Required)
|
|
6
|
+
|
|
7
|
+
When writing generated signature content, never overwrite human-written notes above the marker.
|
|
8
|
+
|
|
9
|
+
Use this marker block for all appendable context files:
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
## Auto-generated signatures
|
|
13
|
+
<!-- Updated by gen-context.js -->
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
### Files that must use append-under-marker
|
|
17
|
+
|
|
18
|
+
1. `CLAUDE.md`
|
|
19
|
+
2. `.github/copilot-instructions.md`
|
|
20
|
+
3. `.github/gemini-context.md`
|
|
21
|
+
|
|
22
|
+
### Safe write procedure
|
|
23
|
+
|
|
24
|
+
1. Read existing file (or start with empty string if file does not exist).
|
|
25
|
+
2. Find the marker `## Auto-generated signatures`.
|
|
26
|
+
3. If marker exists: keep everything above marker unchanged; replace only marker-and-below with new generated block.
|
|
27
|
+
4. If marker does not exist: append marker + generated block to the end.
|
|
28
|
+
5. Never modify human content above marker.
|
|
29
|
+
|
|
30
|
+
### Legacy cleanup rule
|
|
31
|
+
|
|
32
|
+
If an existing generated file has no marker but contains prior SigMap-generated content headers, replace the full legacy generated content with marker + new generated block.
|
|
33
|
+
|
|
34
|
+
## Verification
|
|
35
|
+
|
|
36
|
+
After changing write logic, run:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
node test/integration/multi-output.test.js
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Expected: all tests pass, including append-preservation cases.
|
package/README.md
CHANGED
|
@@ -1,38 +1,62 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
|
|
3
|
+
<img src="docs-vp/.vitepress/public/logo.svg" alt="SigMap logo" width="64" height="84" />
|
|
4
|
+
|
|
3
5
|
<h1>⚡ SigMap</h1>
|
|
4
6
|
|
|
5
|
-
<p><strong>
|
|
7
|
+
<p><strong>WITHOUT SIGMAP, YOUR AI IS GUESSING.</strong><br>
|
|
8
|
+
<strong>It sees 8% of your codebase and invents the rest.</strong></p>
|
|
9
|
+
|
|
10
|
+
<p><sub>Run one command. Force every answer to come from real code.</sub></p>
|
|
11
|
+
|
|
12
|
+
</div>
|
|
6
13
|
|
|
7
|
-
<
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
</p>
|
|
14
|
+
<div align="center">
|
|
15
|
+
<img src="docs/impact-banner.svg" alt="SigMap — 6× better answers, 97% fewer tokens, 2× fewer prompts" width="760" />
|
|
16
|
+
</div>
|
|
11
17
|
|
|
12
|
-
|
|
18
|
+
```sh
|
|
19
|
+
npx sigmap # 10 seconds. zero config. your AI never reads the wrong file again.
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
<details>
|
|
23
|
+
<summary><strong>Trust signals</strong></summary>
|
|
24
|
+
|
|
25
|
+
<div align="center">
|
|
13
26
|
|
|
14
|
-
<!-- Status -->
|
|
15
27
|
[](https://www.npmjs.com/package/sigmap)
|
|
16
28
|
[](https://github.com/manojmallick/sigmap/actions/workflows/ci.yml)
|
|
17
29
|
[](package.json)
|
|
18
|
-
[](https://github.com/manojmallick/sigmap/commits/main)
|
|
19
|
-
|
|
20
|
-
<!-- Meta -->
|
|
21
30
|
[](LICENSE)
|
|
22
|
-
[](https://nodejs.org)
|
|
23
|
-
[](https://www.npmjs.com/package/sigmap)
|
|
24
|
-
[](https://github.com/manojmallick/sigmap/stargazers)
|
|
25
|
-
|
|
26
|
-
<!-- Links -->
|
|
27
|
-
[](https://manojmallick.github.io/sigmap)
|
|
28
|
-
[](CHANGELOG.md)
|
|
29
|
-
[](CONTRIBUTING.md)
|
|
30
31
|
[](https://marketplace.visualstudio.com/items?itemName=manojmallick.sigmap)
|
|
31
32
|
[](https://plugins.jetbrains.com/plugin/31109-sigmap--ai-context-engine/)
|
|
32
|
-
[](https://manojmallick.github.io/sigmap)
|
|
34
|
+
[](https://github.com/manojmallick/sigmap/stargazers)
|
|
33
35
|
|
|
34
36
|
</div>
|
|
35
37
|
|
|
38
|
+
</details>
|
|
39
|
+
|
|
40
|
+
<details>
|
|
41
|
+
<summary><strong>Full benchmark breakdown →</strong></summary>
|
|
42
|
+
|
|
43
|
+
<br/>
|
|
44
|
+
|
|
45
|
+
<div align="center">
|
|
46
|
+
<img src="docs/comparison-chart.svg" alt="SigMap benchmark — before vs after across 3 RAG quality metrics" width="700" />
|
|
47
|
+
<br/><sub><a href="https://manojmallick.github.io/sigmap/guide/task-benchmark.html">80 tasks · 16 real repos · no LLM API · <strong>full methodology →</strong></a></sub>
|
|
48
|
+
</div>
|
|
49
|
+
|
|
50
|
+
| | Without SigMap | With SigMap |
|
|
51
|
+
|---|:---:|:---:|
|
|
52
|
+
| Task success | 10% | **59%** |
|
|
53
|
+
| Prompts per task | 2.84 | **1.54** |
|
|
54
|
+
| Tokens per session | ~80,000 | **~2,000** |
|
|
55
|
+
| Right file found | 13.7% | **87.5%** |
|
|
56
|
+
| Hallucination risk | 92% | **0%** |
|
|
57
|
+
|
|
58
|
+
</details>
|
|
59
|
+
|
|
36
60
|
---
|
|
37
61
|
|
|
38
62
|
## Table of contents
|
|
@@ -67,7 +91,7 @@ SigMap scans your source files and extracts only the **function and class signat
|
|
|
67
91
|
Your codebase
|
|
68
92
|
│
|
|
69
93
|
▼
|
|
70
|
-
|
|
94
|
+
sigmap ─────────► extracts signatures from 21 languages
|
|
71
95
|
│
|
|
72
96
|
▼
|
|
73
97
|
.github/copilot-instructions.md ◄── auto-read by Copilot / Claude / Cursor
|
|
@@ -90,6 +114,31 @@ AI agent session starts with full context
|
|
|
90
114
|
|
|
91
115
|
> **97% fewer tokens. The same codebase understanding.**
|
|
92
116
|
|
|
117
|
+
### Benchmark: real-world repos
|
|
118
|
+
|
|
119
|
+
Reproduced with `node scripts/run-benchmark.mjs` on public repos:
|
|
120
|
+
|
|
121
|
+
| Repo | Language | Raw tokens | After SigMap | Reduction |
|
|
122
|
+
|------|----------|------------|--------------|-----------|
|
|
123
|
+
| express | JavaScript | 15.5K | 201 | **98.7%** |
|
|
124
|
+
| flask | Python | 84.8K | 3.4K | **96.0%** |
|
|
125
|
+
| gin | Go | 172.8K | 5.7K | **96.7%** |
|
|
126
|
+
| spring-petclinic | Java | 77.0K | 634 | **99.2%** |
|
|
127
|
+
| rails | Ruby | 1.5M | 7.1K | **99.5%** |
|
|
128
|
+
| axios | TypeScript | 31.7K | 1.5K | **95.2%** |
|
|
129
|
+
| rust-analyzer | Rust | 3.5M | 5.9K | **99.8%** |
|
|
130
|
+
| abseil-cpp | C++ | 2.3M | 6.3K | **99.7%** |
|
|
131
|
+
| serilog | C# | 113.7K | 5.8K | **94.9%** |
|
|
132
|
+
| riverpod | Dart | 682.7K | 6.5K | **99.0%** |
|
|
133
|
+
| okhttp | Kotlin | 31.3K | 1.4K | **95.5%** |
|
|
134
|
+
| laravel | PHP | 1.7M | 7.2K | **99.6%** |
|
|
135
|
+
| akka | Scala | 790.5K | 7.1K | **99.1%** |
|
|
136
|
+
| vapor | Swift | 171.2K | 6.4K | **96.3%** |
|
|
137
|
+
| vue-core | Vue | 404.2K | 8.8K | **97.8%** |
|
|
138
|
+
| svelte | Svelte | 438.2K | 8.0K | **98.2%** |
|
|
139
|
+
|
|
140
|
+
**Average: 99.3% reduction across 16 languages.** See [`benchmarks/reports/token-reduction.md`](benchmarks/reports/token-reduction.md) or reproduce with `node scripts/run-benchmark.mjs`.
|
|
141
|
+
|
|
93
142
|
---
|
|
94
143
|
|
|
95
144
|
## ⚡ Installation
|
|
@@ -250,8 +299,6 @@ No npm, no `node_modules`. Drop `gen-context.js` into any project and run it dir
|
|
|
250
299
|
|
|
251
300
|
</details>
|
|
252
301
|
|
|
253
|
-
> **Note:** When using the single-file download, replace `sigmap` with `node gen-context.js` in all commands below.
|
|
254
|
-
|
|
255
302
|
---
|
|
256
303
|
|
|
257
304
|
## 🚀 Features
|
|
@@ -266,17 +313,19 @@ sigmap --adapter claude # → CLAUDE.md (appended below marker)
|
|
|
266
313
|
sigmap --adapter cursor # → .cursorrules
|
|
267
314
|
sigmap --adapter windsurf # → .windsurfrules
|
|
268
315
|
sigmap --adapter openai # → .github/openai-context.md
|
|
269
|
-
sigmap --adapter gemini # → .github/gemini-context.md
|
|
316
|
+
sigmap --adapter gemini # → .github/gemini-context.md (appended below marker)
|
|
317
|
+
sigmap --adapter codex # → AGENTS.md (appended below marker)
|
|
270
318
|
```
|
|
271
319
|
|
|
272
320
|
| Adapter | Output file | AI assistant |
|
|
273
321
|
|---|---|---|
|
|
274
|
-
| `copilot` | `.github/copilot-instructions.md` | GitHub Copilot |
|
|
322
|
+
| `copilot` | `.github/copilot-instructions.md` (append) | GitHub Copilot |
|
|
275
323
|
| `claude` | `CLAUDE.md` (append) | Claude / Claude Code |
|
|
276
324
|
| `cursor` | `.cursorrules` | Cursor |
|
|
277
325
|
| `windsurf` | `.windsurfrules` | Windsurf |
|
|
278
326
|
| `openai` | `.github/openai-context.md` | Any OpenAI model |
|
|
279
|
-
| `gemini` | `.github/gemini-context.md` | Google Gemini |
|
|
327
|
+
| `gemini` | `.github/gemini-context.md` (append) | Google Gemini |
|
|
328
|
+
| `codex` | `AGENTS.md` (append) | OpenAI Codex |
|
|
280
329
|
|
|
281
330
|
Configure multiple adapters at once in `gen-context.config.json`:
|
|
282
331
|
|
|
@@ -342,7 +391,7 @@ npm install -g sigmap # install globally
|
|
|
342
391
|
|
|
343
392
|
### Generate context
|
|
344
393
|
|
|
345
|
-
|
|
394
|
+
Once installed, run from your project root:
|
|
346
395
|
|
|
347
396
|
```bash
|
|
348
397
|
sigmap # generate once and exit
|
|
@@ -374,17 +423,17 @@ npx repomix --compress # deep dive sessions
|
|
|
374
423
|
|
|
375
424
|
## 🧩 VS Code extension
|
|
376
425
|
|
|
377
|
-
The
|
|
426
|
+
The official SigMap VS Code extension keeps your context fresh without any manual commands. Install it once and it runs silently in the background.
|
|
378
427
|
|
|
379
428
|
| Feature | Detail |
|
|
380
429
|
|---|---|
|
|
381
430
|
| **Status bar item** | Shows health grade (`A`/`B`/`C`/`D`) + time since last regen; refreshes every 60 s |
|
|
382
431
|
| **Stale notification** | Warns when `copilot-instructions.md` is > 24 h old; one-click regeneration |
|
|
383
|
-
| **Regenerate command** | `SigMap: Regenerate Context` — runs `
|
|
432
|
+
| **Regenerate command** | `SigMap: Regenerate Context` — runs `sigmap` in the integrated terminal |
|
|
384
433
|
| **Open context command** | `SigMap: Open Context File` — opens `.github/copilot-instructions.md` |
|
|
385
|
-
| **Script path setting** | `sigmap.scriptPath` — override
|
|
434
|
+
| **Script path setting** | `sigmap.scriptPath` — override the path to the `sigmap` binary or `gen-context.js` |
|
|
386
435
|
|
|
387
|
-
|
|
436
|
+
Activates on startup (`onStartupFinished`) — loads within 3 s, never blocks editor startup.
|
|
388
437
|
|
|
389
438
|
**Install:** [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=manojmallick.sigmap) | [Open VSX Registry](https://open-vsx.org/extension/manojmallick/sigmap)
|
|
390
439
|
|
|
@@ -392,12 +441,12 @@ Activate on startup (`onStartupFinished`) — loads within 3 s, never blocks edi
|
|
|
392
441
|
|
|
393
442
|
## 🔧 JetBrains plugin
|
|
394
443
|
|
|
395
|
-
The
|
|
444
|
+
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.
|
|
396
445
|
|
|
397
446
|
| Feature | Detail |
|
|
398
447
|
|---|---|
|
|
399
448
|
| **Status bar widget** | Shows health grade (`A`-`F`) + time since last regen; updates every 60 s |
|
|
400
|
-
| **Regenerate action** | `Tools → SigMap → Regenerate Context` or **Ctrl+Alt+G** — runs `
|
|
449
|
+
| **Regenerate action** | `Tools → SigMap → Regenerate Context` or **Ctrl+Alt+G** — runs `sigmap` |
|
|
401
450
|
| **Open context action** | `Tools → SigMap → Open Context File` — opens `.github/copilot-instructions.md` |
|
|
402
451
|
| **View roadmap action** | `Tools → SigMap → View Roadmap` — opens roadmap in browser |
|
|
403
452
|
| **One-click regen** | Click status bar widget to regenerate context instantly |
|
|
@@ -495,7 +544,7 @@ Recently committed files are **hot** (auto-injected). Everything else is **cold*
|
|
|
495
544
|
Start the MCP server on stdio:
|
|
496
545
|
|
|
497
546
|
```bash
|
|
498
|
-
|
|
547
|
+
sigmap --mcp
|
|
499
548
|
```
|
|
500
549
|
|
|
501
550
|
### Available tools
|
|
@@ -576,11 +625,11 @@ sigmap --help Usage information
|
|
|
576
625
|
### Task classification — `--suggest-tool`
|
|
577
626
|
|
|
578
627
|
```bash
|
|
579
|
-
|
|
628
|
+
sigmap --suggest-tool "security audit of the auth module"
|
|
580
629
|
# tier : powerful
|
|
581
630
|
# models : claude-opus-4-6, gpt-5-4, gemini-2-5-pro
|
|
582
631
|
|
|
583
|
-
|
|
632
|
+
sigmap --suggest-tool "fix a typo in the yaml config" --json
|
|
584
633
|
# {"tier":"fast","label":"Fast (low-cost)","models":"claude-haiku-4-5, ...","costHint":"~$0.0008 / 1K tokens"}
|
|
585
634
|
```
|
|
586
635
|
|
|
@@ -646,7 +695,7 @@ build/
|
|
|
646
695
|
test/fixtures/
|
|
647
696
|
```
|
|
648
697
|
|
|
649
|
-
Run `
|
|
698
|
+
Run `sigmap --init` to scaffold both files in one step.
|
|
650
699
|
|
|
651
700
|
### Output targets
|
|
652
701
|
|
|
@@ -676,14 +725,14 @@ If `output` is omitted, the default `.github/copilot-instructions.md` is used.
|
|
|
676
725
|
|
|
677
726
|
```bash
|
|
678
727
|
# Append run metrics to .context/usage.ndjson
|
|
679
|
-
|
|
728
|
+
sigmap --track
|
|
680
729
|
|
|
681
730
|
# Structured JSON report for CI (exits 1 if over budget)
|
|
682
|
-
|
|
731
|
+
sigmap --report --json
|
|
683
732
|
# { "version": "2.0.0", "finalTokens": 3200, "reductionPct": 92.4, "overBudget": false }
|
|
684
733
|
|
|
685
734
|
# Composite health score
|
|
686
|
-
|
|
735
|
+
sigmap --health
|
|
687
736
|
# score: 95/100 (grade A) | reduction: 91.2% | 1 day since regen | 47 runs
|
|
688
737
|
```
|
|
689
738
|
|
|
@@ -695,9 +744,9 @@ Copy `examples/self-healing-github-action.yml` to `.github/workflows/` to auto-r
|
|
|
695
744
|
|
|
696
745
|
```yaml
|
|
697
746
|
- name: SigMap health check
|
|
698
|
-
run:
|
|
747
|
+
run: sigmap --health --json
|
|
699
748
|
- name: Regenerate context
|
|
700
|
-
run:
|
|
749
|
+
run: sigmap
|
|
701
750
|
```
|
|
702
751
|
|
|
703
752
|
📖 Full guide: [docs/readmes/ENTERPRISE_SETUP.md](docs/readmes/ENTERPRISE_SETUP.md)
|
|
@@ -705,7 +754,7 @@ Copy `examples/self-healing-github-action.yml` to `.github/workflows/` to auto-r
|
|
|
705
754
|
### Prompt caching — 60% API cost reduction
|
|
706
755
|
|
|
707
756
|
```bash
|
|
708
|
-
|
|
757
|
+
sigmap --format cache
|
|
709
758
|
# Writes: .github/copilot-instructions.cache.json
|
|
710
759
|
# Format: { type: 'text', text: '...', cache_control: { type: 'ephemeral' } }
|
|
711
760
|
```
|
|
@@ -840,7 +889,7 @@ sigmap/
|
|
|
840
889
|
|
|
841
890
|
| Principle | Implementation |
|
|
842
891
|
|---|---|
|
|
843
|
-
| **Zero npm dependencies** | `
|
|
892
|
+
| **Zero npm dependencies** | `npx sigmap` on any machine — no install required. Or use the standalone binary for zero Node.js dependency. |
|
|
844
893
|
| **Never throw** | All extractors return `[]` on any error — the run always completes |
|
|
845
894
|
| **Deterministic** | No AI or LLM involved in extraction — only regex + Node built-ins |
|
|
846
895
|
| **Repomix is a companion** | Use both tools; SigMap never replaces Repomix |
|
package/gen-context.js
CHANGED
|
@@ -34,7 +34,7 @@ __factories["./src/config/defaults"] = function(module, exports) {
|
|
|
34
34
|
// Output targets: 'copilot' | 'claude' | 'cursor' | 'windsurf'
|
|
35
35
|
outputs: ['copilot'],
|
|
36
36
|
|
|
37
|
-
// Adapter targets (v3.0+): replaces 'outputs'. Same names, adds 'openai' | 'gemini'.
|
|
37
|
+
// Adapter targets (v3.0+): replaces 'outputs'. Same names, adds 'openai' | 'gemini' | 'codex'.
|
|
38
38
|
// Old 'outputs' config key is still accepted and silently maps to 'adapters'.
|
|
39
39
|
adapters: null, // null means: use 'outputs' for backward compat
|
|
40
40
|
|
|
@@ -173,7 +173,7 @@ __factories["./src/config/loader"] = function(module, exports) {
|
|
|
173
173
|
if (!merged.adapters && Array.isArray(merged.outputs)) {
|
|
174
174
|
merged.adapters = merged.outputs.slice();
|
|
175
175
|
} else if (Array.isArray(merged.adapters) && !userConfig.outputs) {
|
|
176
|
-
merged.outputs = merged.adapters.filter((a) => ['copilot','claude','cursor','windsurf'].includes(a));
|
|
176
|
+
merged.outputs = merged.adapters.filter((a) => ['copilot','claude','cursor','windsurf','codex'].includes(a));
|
|
177
177
|
}
|
|
178
178
|
return merged;
|
|
179
179
|
}
|
|
@@ -3700,7 +3700,7 @@ __factories["./src/mcp/server"] = function(module, exports) {
|
|
|
3700
3700
|
|
|
3701
3701
|
const SERVER_INFO = {
|
|
3702
3702
|
name: 'sigmap',
|
|
3703
|
-
version: '3.2
|
|
3703
|
+
version: '3.3.2',
|
|
3704
3704
|
description: 'SigMap MCP server — code signatures on demand',
|
|
3705
3705
|
};
|
|
3706
3706
|
|
|
@@ -4888,7 +4888,9 @@ __factories["./src/eval/runner"] = function(module, exports) {
|
|
|
4888
4888
|
// ── ./packages/adapters/copilot (bundled) ──
|
|
4889
4889
|
__factories["./packages/adapters/copilot"] = function(module, exports) {
|
|
4890
4890
|
const path = require('path');
|
|
4891
|
+
const fs = require('fs');
|
|
4891
4892
|
const name = 'copilot';
|
|
4893
|
+
const COPILOT_MARKER = '\n\n## Auto-generated signatures\n<!-- Updated by gen-context.js -->\n';
|
|
4892
4894
|
function format(context, opts = {}) {
|
|
4893
4895
|
if (!context || typeof context !== 'string') return '';
|
|
4894
4896
|
const version = (opts && opts.version) || 'unknown';
|
|
@@ -4904,7 +4906,20 @@ __factories["./packages/adapters/copilot"] = function(module, exports) {
|
|
|
4904
4906
|
].join('\n');
|
|
4905
4907
|
}
|
|
4906
4908
|
function outputPath(cwd) { return path.join(cwd, '.github', 'copilot-instructions.md'); }
|
|
4907
|
-
|
|
4909
|
+
function write(context, cwd, opts = {}) {
|
|
4910
|
+
const filePath = outputPath(cwd);
|
|
4911
|
+
let existing = '';
|
|
4912
|
+
if (fs.existsSync(filePath)) existing = fs.readFileSync(filePath, 'utf8');
|
|
4913
|
+
const formatted = format(context, opts);
|
|
4914
|
+
const markerIdx = existing.indexOf('## Auto-generated signatures');
|
|
4915
|
+
const isLegacyGenerated = existing.includes('<!-- Generated by SigMap gen-context.js') || existing.includes('# Code signatures');
|
|
4916
|
+
const newContent = markerIdx !== -1
|
|
4917
|
+
? existing.slice(0, markerIdx) + COPILOT_MARKER.trimStart() + formatted
|
|
4918
|
+
: (isLegacyGenerated ? COPILOT_MARKER.trimStart() + formatted : existing + COPILOT_MARKER + formatted);
|
|
4919
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
4920
|
+
fs.writeFileSync(filePath, newContent, 'utf8');
|
|
4921
|
+
}
|
|
4922
|
+
module.exports = { name, format, outputPath, write };
|
|
4908
4923
|
};
|
|
4909
4924
|
|
|
4910
4925
|
// ── ./packages/adapters/claude (bundled) ──
|
|
@@ -4989,7 +5004,9 @@ __factories["./packages/adapters/openai"] = function(module, exports) {
|
|
|
4989
5004
|
// ── ./packages/adapters/gemini (bundled) ──
|
|
4990
5005
|
__factories["./packages/adapters/gemini"] = function(module, exports) {
|
|
4991
5006
|
const path = require('path');
|
|
5007
|
+
const fs = require('fs');
|
|
4992
5008
|
const name = 'gemini';
|
|
5009
|
+
const GEMINI_MARKER = '\n\n## Auto-generated signatures\n<!-- Updated by gen-context.js -->\n';
|
|
4993
5010
|
function format(context, opts = {}) {
|
|
4994
5011
|
if (!context || typeof context !== 'string') return '';
|
|
4995
5012
|
const version = (opts && opts.version) || 'unknown';
|
|
@@ -5007,12 +5024,51 @@ __factories["./packages/adapters/gemini"] = function(module, exports) {
|
|
|
5007
5024
|
].join('\n');
|
|
5008
5025
|
}
|
|
5009
5026
|
function outputPath(cwd) { return path.join(cwd, '.github', 'gemini-context.md'); }
|
|
5010
|
-
|
|
5027
|
+
function write(context, cwd, opts = {}) {
|
|
5028
|
+
const filePath = outputPath(cwd);
|
|
5029
|
+
let existing = '';
|
|
5030
|
+
if (fs.existsSync(filePath)) existing = fs.readFileSync(filePath, 'utf8');
|
|
5031
|
+
const formatted = format(context, opts);
|
|
5032
|
+
const markerIdx = existing.indexOf('## Auto-generated signatures');
|
|
5033
|
+
const isLegacyGenerated = existing.includes('<!-- Generated by SigMap gen-context.js') || existing.includes('## Code Signatures');
|
|
5034
|
+
const newContent = markerIdx !== -1
|
|
5035
|
+
? existing.slice(0, markerIdx) + GEMINI_MARKER.trimStart() + formatted
|
|
5036
|
+
: (isLegacyGenerated ? GEMINI_MARKER.trimStart() + formatted : existing + GEMINI_MARKER + formatted);
|
|
5037
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
5038
|
+
fs.writeFileSync(filePath, newContent, 'utf8');
|
|
5039
|
+
}
|
|
5040
|
+
module.exports = { name, format, outputPath, write };
|
|
5041
|
+
};
|
|
5042
|
+
|
|
5043
|
+
// ── ./packages/adapters/codex (bundled) ──
|
|
5044
|
+
__factories["./packages/adapters/codex"] = function(module, exports) {
|
|
5045
|
+
const path = require('path');
|
|
5046
|
+
const fs = require('fs');
|
|
5047
|
+
const openai = __require('./packages/adapters/openai');
|
|
5048
|
+
const name = 'codex';
|
|
5049
|
+
const CODEX_MARKER = '\n\n## Auto-generated signatures\n<!-- Updated by gen-context.js -->\n';
|
|
5050
|
+
function format(context, opts = {}) {
|
|
5051
|
+
return openai.format(context, opts);
|
|
5052
|
+
}
|
|
5053
|
+
function outputPath(cwd) { return path.join(cwd, 'AGENTS.md'); }
|
|
5054
|
+
function write(context, cwd, opts = {}) {
|
|
5055
|
+
const filePath = outputPath(cwd);
|
|
5056
|
+
let existing = '';
|
|
5057
|
+
if (fs.existsSync(filePath)) existing = fs.readFileSync(filePath, 'utf8');
|
|
5058
|
+
const formatted = format(context, opts);
|
|
5059
|
+
const markerIdx = existing.indexOf('## Auto-generated signatures');
|
|
5060
|
+
const isLegacyGenerated = existing.includes('<!-- Generated by SigMap gen-context.js') || existing.includes('## Code Signatures') || existing.includes('# Code signatures');
|
|
5061
|
+
const newContent = markerIdx !== -1
|
|
5062
|
+
? existing.slice(0, markerIdx) + CODEX_MARKER.trimStart() + formatted
|
|
5063
|
+
: (isLegacyGenerated ? CODEX_MARKER.trimStart() + formatted : existing + CODEX_MARKER + formatted);
|
|
5064
|
+
fs.writeFileSync(filePath, newContent, 'utf8');
|
|
5065
|
+
}
|
|
5066
|
+
module.exports = { name, format, outputPath, write };
|
|
5011
5067
|
};
|
|
5012
5068
|
|
|
5013
5069
|
// ── ./packages/adapters/index (bundled) ──
|
|
5014
5070
|
__factories["./packages/adapters/index"] = function(module, exports) {
|
|
5015
|
-
const ADAPTER_NAMES = ['copilot', 'claude', 'cursor', 'windsurf', 'openai', 'gemini'];
|
|
5071
|
+
const ADAPTER_NAMES = ['copilot', 'claude', 'cursor', 'windsurf', 'openai', 'gemini', 'codex'];
|
|
5016
5072
|
const _adapterCache = {};
|
|
5017
5073
|
function getAdapter(name) {
|
|
5018
5074
|
if (!name || typeof name !== 'string') return null;
|
|
@@ -5049,7 +5105,7 @@ const path = require('path');
|
|
|
5049
5105
|
const os = require('os');
|
|
5050
5106
|
const { execSync } = require('child_process');
|
|
5051
5107
|
|
|
5052
|
-
const VERSION = '3.3.
|
|
5108
|
+
const VERSION = '3.3.2';
|
|
5053
5109
|
const MARKER = '\n\n## Auto-generated signatures\n<!-- Updated by gen-context.js -->\n';
|
|
5054
5110
|
|
|
5055
5111
|
function requireSourceOrBundled(key) {
|
|
@@ -5619,6 +5675,7 @@ function resolveAdapterPath(adapter, cwd, config) {
|
|
|
5619
5675
|
if (adapter === 'claude') return path.join(cwd, 'CLAUDE.md');
|
|
5620
5676
|
if (adapter === 'cursor') return path.join(cwd, '.cursorrules');
|
|
5621
5677
|
if (adapter === 'windsurf') return path.join(cwd, '.windsurfrules');
|
|
5678
|
+
if (adapter === 'codex') return path.join(cwd, 'AGENTS.md');
|
|
5622
5679
|
|
|
5623
5680
|
return null;
|
|
5624
5681
|
}
|
|
@@ -5641,7 +5698,7 @@ function writeCacheOutput(content, cwd) {
|
|
|
5641
5698
|
function writeOutputs(content, targets, cwd, config) {
|
|
5642
5699
|
config = config || {};
|
|
5643
5700
|
// v3.0+: adapter-aware output targets
|
|
5644
|
-
const ADAPTER_TARGETS = new Set(['openai', 'gemini']);
|
|
5701
|
+
const ADAPTER_TARGETS = new Set(['copilot', 'openai', 'gemini', 'codex']);
|
|
5645
5702
|
|
|
5646
5703
|
const targetMap = {
|
|
5647
5704
|
copilot: resolveAdapterPath('copilot', cwd, config),
|
|
@@ -5654,15 +5711,21 @@ function writeOutputs(content, targets, cwd, config) {
|
|
|
5654
5711
|
writeClaude(content, cwd);
|
|
5655
5712
|
continue;
|
|
5656
5713
|
}
|
|
5657
|
-
// v3.0+ adapter targets (openai, gemini) — use bundled adapter to format + write
|
|
5714
|
+
// v3.0+ adapter targets (copilot, openai, gemini, codex) — use bundled adapter to format + write
|
|
5658
5715
|
if (ADAPTER_TARGETS.has(target)) {
|
|
5659
5716
|
try {
|
|
5660
5717
|
const adapterMod = __require('./packages/adapters/' + target);
|
|
5661
|
-
|
|
5662
|
-
|
|
5663
|
-
|
|
5664
|
-
|
|
5665
|
-
|
|
5718
|
+
if (typeof adapterMod.write === 'function') {
|
|
5719
|
+
adapterMod.write(content, cwd, { version: VERSION });
|
|
5720
|
+
const outPath = adapterMod.outputPath(cwd);
|
|
5721
|
+
console.warn(`[sigmap] wrote ${path.relative(cwd, outPath)} (appended signatures)`);
|
|
5722
|
+
} else {
|
|
5723
|
+
const formatted = adapterMod.format(content, { version: VERSION });
|
|
5724
|
+
const outPath = adapterMod.outputPath(cwd);
|
|
5725
|
+
ensureDir(outPath);
|
|
5726
|
+
fs.writeFileSync(outPath, formatted, 'utf8');
|
|
5727
|
+
console.warn(`[sigmap] wrote ${path.relative(cwd, outPath)}`);
|
|
5728
|
+
}
|
|
5666
5729
|
} catch (err) {
|
|
5667
5730
|
console.warn(`[sigmap] adapter "${target}" failed: ${err.message}`);
|
|
5668
5731
|
}
|
|
@@ -6420,8 +6483,8 @@ Strategies (set via config "strategy" key):
|
|
|
6420
6483
|
~90% fewer tokens. Best with MCP (Claude Code, Cursor).
|
|
6421
6484
|
Set "hotCommits": N to control how many commits count as hot (default 10).
|
|
6422
6485
|
|
|
6423
|
-
Adapters (v3.0+): copilot | claude | cursor | windsurf | openai | gemini
|
|
6424
|
-
Set "adapters": ["copilot","openai"] in config to write multiple adapter outputs.
|
|
6486
|
+
Adapters (v3.0+): copilot | claude | cursor | windsurf | openai | gemini | codex
|
|
6487
|
+
Set "adapters": ["copilot","openai","codex"] in config to write multiple adapter outputs.
|
|
6425
6488
|
Old "outputs" config key is still accepted (maps to adapters automatically).
|
|
6426
6489
|
|
|
6427
6490
|
Config: gen-context.config.json
|
|
@@ -6760,7 +6823,7 @@ function main() {
|
|
|
6760
6823
|
// handled here (per-repo) rather than running a single generate on the
|
|
6761
6824
|
// parent directory.
|
|
6762
6825
|
if (args.includes('--each')) {
|
|
6763
|
-
const VALID_ADAPTERS = ['copilot', 'claude', 'cursor', 'windsurf', 'openai', 'gemini'];
|
|
6826
|
+
const VALID_ADAPTERS = ['copilot', 'claude', 'cursor', 'windsurf', 'openai', 'gemini', 'codex'];
|
|
6764
6827
|
const adpIdx = args.indexOf('--adapter');
|
|
6765
6828
|
const adapterOverride = adpIdx >= 0 ? (args[adpIdx + 1] || '').trim().toLowerCase() : null;
|
|
6766
6829
|
if (adapterOverride && !VALID_ADAPTERS.includes(adapterOverride)) {
|
|
@@ -6777,7 +6840,7 @@ function main() {
|
|
|
6777
6840
|
try {
|
|
6778
6841
|
const adpIdx = args.indexOf('--adapter');
|
|
6779
6842
|
const adapterName = (args[adpIdx + 1] || '').trim().toLowerCase();
|
|
6780
|
-
const VALID_ADAPTERS = ['copilot', 'claude', 'cursor', 'windsurf', 'openai', 'gemini'];
|
|
6843
|
+
const VALID_ADAPTERS = ['copilot', 'claude', 'cursor', 'windsurf', 'openai', 'gemini', 'codex'];
|
|
6781
6844
|
if (!adapterName || adapterName.startsWith('--')) {
|
|
6782
6845
|
console.error('[sigmap] --adapter requires an adapter name');
|
|
6783
6846
|
console.error(` Valid adapters: ${VALID_ADAPTERS.join(', ')}`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sigmap",
|
|
3
|
-
"version": "3.3.
|
|
3
|
+
"version": "3.3.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": {
|
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
"src/",
|
|
37
37
|
"packages/",
|
|
38
38
|
"README.md",
|
|
39
|
+
"AGENTS.md",
|
|
39
40
|
"LICENSE",
|
|
40
41
|
"CHANGELOG.md",
|
|
41
42
|
".contextignore.example",
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Codex adapter — writes OpenAI-style context to AGENTS.md.
|
|
5
|
+
*
|
|
6
|
+
* This adapter reuses the same prompt format as the OpenAI adapter,
|
|
7
|
+
* but targets AGENTS.md so Codex-style agents can read repository guidance.
|
|
8
|
+
*
|
|
9
|
+
* Contract:
|
|
10
|
+
* format(context, opts?) → string
|
|
11
|
+
* outputPath(cwd) → string
|
|
12
|
+
* write(context, cwd, opts?) → void
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
const path = require('path');
|
|
16
|
+
const fs = require('fs');
|
|
17
|
+
const openai = require('./openai');
|
|
18
|
+
|
|
19
|
+
const name = 'codex';
|
|
20
|
+
const MARKER = '\n\n## Auto-generated signatures\n<!-- Updated by gen-context.js -->\n';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Format context using the OpenAI adapter format.
|
|
24
|
+
* @param {string} context - Raw signature context string
|
|
25
|
+
* @param {object} [opts]
|
|
26
|
+
* @returns {string}
|
|
27
|
+
*/
|
|
28
|
+
function format(context, opts = {}) {
|
|
29
|
+
return openai.format(context, opts);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Return the output file path for this adapter.
|
|
34
|
+
* @param {string} cwd - Project root
|
|
35
|
+
* @returns {string}
|
|
36
|
+
*/
|
|
37
|
+
function outputPath(cwd) {
|
|
38
|
+
return path.join(cwd, 'AGENTS.md');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Write signatures into AGENTS.md using append-under-marker.
|
|
43
|
+
* If marker exists, content above marker is preserved.
|
|
44
|
+
* If legacy generated content exists without marker, replace it cleanly.
|
|
45
|
+
* @param {string} context - Raw signature context string
|
|
46
|
+
* @param {string} cwd - Project root
|
|
47
|
+
* @param {object} [opts]
|
|
48
|
+
*/
|
|
49
|
+
function write(context, cwd, opts = {}) {
|
|
50
|
+
const filePath = outputPath(cwd);
|
|
51
|
+
let existing = '';
|
|
52
|
+
if (fs.existsSync(filePath)) {
|
|
53
|
+
existing = fs.readFileSync(filePath, 'utf8');
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const formatted = format(context, opts);
|
|
57
|
+
const markerIdx = existing.indexOf('## Auto-generated signatures');
|
|
58
|
+
|
|
59
|
+
let newContent;
|
|
60
|
+
if (markerIdx !== -1) {
|
|
61
|
+
newContent = existing.slice(0, markerIdx) + MARKER.trimStart() + formatted;
|
|
62
|
+
} else {
|
|
63
|
+
const isLegacyGenerated = existing.includes('<!-- Generated by SigMap gen-context.js')
|
|
64
|
+
|| existing.includes('## Code Signatures')
|
|
65
|
+
|| existing.includes('# Code signatures');
|
|
66
|
+
newContent = isLegacyGenerated
|
|
67
|
+
? MARKER.trimStart() + formatted
|
|
68
|
+
: existing + MARKER + formatted;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
fs.writeFileSync(filePath, newContent, 'utf8');
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
module.exports = { name, format, outputPath, write };
|
|
@@ -10,8 +10,10 @@
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
const path = require('path');
|
|
13
|
+
const fs = require('fs');
|
|
13
14
|
|
|
14
15
|
const name = 'copilot';
|
|
16
|
+
const MARKER = '\n\n## Auto-generated signatures\n<!-- Updated by gen-context.js -->\n';
|
|
15
17
|
|
|
16
18
|
/**
|
|
17
19
|
* Format context for GitHub Copilot instructions.
|
|
@@ -44,4 +46,37 @@ function outputPath(cwd) {
|
|
|
44
46
|
return path.join(cwd, '.github', 'copilot-instructions.md');
|
|
45
47
|
}
|
|
46
48
|
|
|
47
|
-
|
|
49
|
+
/**
|
|
50
|
+
* Write signatures into copilot-instructions.md using append-under-marker.
|
|
51
|
+
* If marker exists, content above marker is preserved.
|
|
52
|
+
* If legacy generated content exists without marker, replace it cleanly.
|
|
53
|
+
* @param {string} context - Raw signature context string
|
|
54
|
+
* @param {string} cwd - Project root
|
|
55
|
+
* @param {object} [opts]
|
|
56
|
+
*/
|
|
57
|
+
function write(context, cwd, opts = {}) {
|
|
58
|
+
const filePath = outputPath(cwd);
|
|
59
|
+
let existing = '';
|
|
60
|
+
if (fs.existsSync(filePath)) {
|
|
61
|
+
existing = fs.readFileSync(filePath, 'utf8');
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const formatted = format(context, opts);
|
|
65
|
+
const markerIdx = existing.indexOf('## Auto-generated signatures');
|
|
66
|
+
|
|
67
|
+
let newContent;
|
|
68
|
+
if (markerIdx !== -1) {
|
|
69
|
+
newContent = existing.slice(0, markerIdx) + MARKER.trimStart() + formatted;
|
|
70
|
+
} else {
|
|
71
|
+
const isLegacyGenerated = existing.includes('<!-- Generated by SigMap gen-context.js')
|
|
72
|
+
|| existing.includes('# Code signatures');
|
|
73
|
+
newContent = isLegacyGenerated
|
|
74
|
+
? MARKER.trimStart() + formatted
|
|
75
|
+
: existing + MARKER + formatted;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
79
|
+
fs.writeFileSync(filePath, newContent, 'utf8');
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
module.exports = { name, format, outputPath, write };
|
|
@@ -15,8 +15,10 @@
|
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
const path = require('path');
|
|
18
|
+
const fs = require('fs');
|
|
18
19
|
|
|
19
20
|
const name = 'gemini';
|
|
21
|
+
const MARKER = '\n\n## Auto-generated signatures\n<!-- Updated by gen-context.js -->\n';
|
|
20
22
|
|
|
21
23
|
/**
|
|
22
24
|
* Format context as a Gemini system instruction.
|
|
@@ -56,4 +58,37 @@ function outputPath(cwd) {
|
|
|
56
58
|
return path.join(cwd, '.github', 'gemini-context.md');
|
|
57
59
|
}
|
|
58
60
|
|
|
59
|
-
|
|
61
|
+
/**
|
|
62
|
+
* Write signatures into gemini-context.md using append-under-marker.
|
|
63
|
+
* If marker exists, content above marker is preserved.
|
|
64
|
+
* If legacy generated content exists without marker, replace it cleanly.
|
|
65
|
+
* @param {string} context - Raw signature context string
|
|
66
|
+
* @param {string} cwd - Project root
|
|
67
|
+
* @param {object} [opts]
|
|
68
|
+
*/
|
|
69
|
+
function write(context, cwd, opts = {}) {
|
|
70
|
+
const filePath = outputPath(cwd);
|
|
71
|
+
let existing = '';
|
|
72
|
+
if (fs.existsSync(filePath)) {
|
|
73
|
+
existing = fs.readFileSync(filePath, 'utf8');
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const formatted = format(context, opts);
|
|
77
|
+
const markerIdx = existing.indexOf('## Auto-generated signatures');
|
|
78
|
+
|
|
79
|
+
let newContent;
|
|
80
|
+
if (markerIdx !== -1) {
|
|
81
|
+
newContent = existing.slice(0, markerIdx) + MARKER.trimStart() + formatted;
|
|
82
|
+
} else {
|
|
83
|
+
const isLegacyGenerated = existing.includes('<!-- Generated by SigMap gen-context.js')
|
|
84
|
+
|| existing.includes('## Code Signatures');
|
|
85
|
+
newContent = isLegacyGenerated
|
|
86
|
+
? MARKER.trimStart() + formatted
|
|
87
|
+
: existing + MARKER + formatted;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
91
|
+
fs.writeFileSync(filePath, newContent, 'utf8');
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
module.exports = { name, format, outputPath, write };
|
|
@@ -11,14 +11,14 @@
|
|
|
11
11
|
|
|
12
12
|
const path = require('path');
|
|
13
13
|
|
|
14
|
-
const ADAPTER_NAMES = ['copilot', 'claude', 'cursor', 'windsurf', 'openai', 'gemini'];
|
|
14
|
+
const ADAPTER_NAMES = ['copilot', 'claude', 'cursor', 'windsurf', 'openai', 'gemini', 'codex'];
|
|
15
15
|
|
|
16
16
|
// Lazy-load adapters so unused ones don't pay any require() cost
|
|
17
17
|
const _cache = {};
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
20
|
* Load and return an adapter module by name.
|
|
21
|
-
* @param {string} name - Adapter name (copilot|claude|cursor|windsurf|openai|gemini)
|
|
21
|
+
* @param {string} name - Adapter name (copilot|claude|cursor|windsurf|openai|gemini|codex)
|
|
22
22
|
* @returns {{ name: string, format: Function, outputPath: Function }|null}
|
|
23
23
|
*/
|
|
24
24
|
function getAdapter(name) {
|
package/src/mcp/server.js
CHANGED