sigmap 3.3.0 → 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/CHANGELOG.md +11 -0
- package/README.md +144 -84
- package/gen-context.config.json.example +1 -1
- package/gen-context.js +105 -23
- 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/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,17 @@ Format: [Semantic Versioning](https://semver.org/)
|
|
|
10
10
|
|
|
11
11
|
---
|
|
12
12
|
|
|
13
|
+
## [3.3.1] — 2026-04-10 — Patch: `--each --adapter` flag combination
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
- **`--each --adapter <name>` now works correctly** · [#37](https://github.com/manojmallick/sigmap/issues/37)
|
|
17
|
+
- Running `sigmap --each --adapter claude` (or any adapter) from a parent directory containing multiple git repos now correctly writes the chosen adapter output (e.g. `CLAUDE.md`) inside each sub-repo.
|
|
18
|
+
- Root cause: the `--adapter` handler ran before `--each` in `main()`, so `--each` was never reached when both flags were supplied together. The `--each` block is now evaluated first.
|
|
19
|
+
- `runEach()` accepts an optional `adapterOverride` parameter that merges `outputs`/`adapters` into each sub-repo's config before calling `runGenerate`, mirroring how the standalone `--adapter` flag works.
|
|
20
|
+
- Invalid adapter names passed alongside `--each` now exit non-zero with a clear error message listing valid adapters.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
13
24
|
## [3.3.0] — 2026-04-08 — Context-Aware CLI & Command Switcher
|
|
14
25
|
|
|
15
26
|
### Added
|
package/README.md
CHANGED
|
@@ -1,36 +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>
|
|
13
|
+
|
|
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>
|
|
6
17
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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">
|
|
11
26
|
|
|
12
|
-
<!-- Status -->
|
|
13
27
|
[](https://www.npmjs.com/package/sigmap)
|
|
14
|
-
[](https://github.com/manojmallick/sigmap/actions/workflows/ci.yml)
|
|
15
29
|
[](package.json)
|
|
16
|
-
[](https://github.com/manojmallick/sigmap/commits/main)
|
|
17
|
-
|
|
18
|
-
<!-- Meta -->
|
|
19
30
|
[](LICENSE)
|
|
20
|
-
[](https://nodejs.org)
|
|
21
|
-
[](https://www.npmjs.com/package/sigmap)
|
|
22
|
-
[](https://github.com/manojmallick/sigmap/stargazers)
|
|
23
|
-
|
|
24
|
-
<!-- Links -->
|
|
25
|
-
[](https://manojmallick.github.io/sigmap)
|
|
26
|
-
[](CHANGELOG.md)
|
|
27
|
-
[](CONTRIBUTING.md)
|
|
28
31
|
[](https://marketplace.visualstudio.com/items?itemName=manojmallick.sigmap)
|
|
29
32
|
[](https://plugins.jetbrains.com/plugin/31109-sigmap--ai-context-engine/)
|
|
30
|
-
[](https://manojmallick.github.io/sigmap)
|
|
34
|
+
[](https://github.com/manojmallick/sigmap/stargazers)
|
|
31
35
|
|
|
32
36
|
</div>
|
|
33
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
|
+
|
|
34
60
|
---
|
|
35
61
|
|
|
36
62
|
## Table of contents
|
|
@@ -39,7 +65,7 @@
|
|
|
39
65
|
|---|---|
|
|
40
66
|
| [What it does](#-what-it-does) | Token reduction table, pipeline overview |
|
|
41
67
|
| [Quick start](#-quick-start) | Install (binary or npm), generate in 60 seconds |
|
|
42
|
-
| [Standalone binaries](docs/binaries.md) | macOS, Linux, Windows — no Node required |
|
|
68
|
+
| [Standalone binaries](docs/readmes/binaries.md) | macOS, Linux, Windows — no Node required |
|
|
43
69
|
| [VS Code extension](#-vs-code-extension) | Status bar, stale alerts, commands |
|
|
44
70
|
| [JetBrains plugin](#-jetbrains-plugin) | IntelliJ IDEA, WebStorm, PyCharm support |
|
|
45
71
|
| [Languages supported](#-languages-supported) | 21 languages |
|
|
@@ -53,7 +79,7 @@
|
|
|
53
79
|
| [Project structure](#-project-structure) | File-by-file map |
|
|
54
80
|
| [Principles](#-principles) | Design decisions |
|
|
55
81
|
|
|
56
|
-
> 📖 **New to SigMap?** Read the **[Complete Getting Started Guide](docs/GETTING_STARTED.md)** — token savings walkthrough, every command, VS Code plugin, and CI setup.
|
|
82
|
+
> 📖 **New to SigMap?** Read the **[Complete Getting Started Guide](docs/readmes/GETTING_STARTED.md)** — token savings walkthrough, every command, VS Code plugin, and CI setup.
|
|
57
83
|
|
|
58
84
|
---
|
|
59
85
|
|
|
@@ -65,7 +91,7 @@ SigMap scans your source files and extracts only the **function and class signat
|
|
|
65
91
|
Your codebase
|
|
66
92
|
│
|
|
67
93
|
▼
|
|
68
|
-
|
|
94
|
+
sigmap ─────────► extracts signatures from 21 languages
|
|
69
95
|
│
|
|
70
96
|
▼
|
|
71
97
|
.github/copilot-instructions.md ◄── auto-read by Copilot / Claude / Cursor
|
|
@@ -88,6 +114,31 @@ AI agent session starts with full context
|
|
|
88
114
|
|
|
89
115
|
> **97% fewer tokens. The same codebase understanding.**
|
|
90
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
|
+
|
|
91
142
|
---
|
|
92
143
|
|
|
93
144
|
## ⚡ Installation
|
|
@@ -198,7 +249,7 @@ shasum -a 256 sigmap-darwin-arm64
|
|
|
198
249
|
# Compare with sigmap-checksums.txt
|
|
199
250
|
```
|
|
200
251
|
|
|
201
|
-
Full guide: [docs/binaries.md](docs/binaries.md)
|
|
252
|
+
Full guide: [docs/readmes/binaries.md](docs/readmes/binaries.md)
|
|
202
253
|
|
|
203
254
|
</details>
|
|
204
255
|
|
|
@@ -248,8 +299,6 @@ No npm, no `node_modules`. Drop `gen-context.js` into any project and run it dir
|
|
|
248
299
|
|
|
249
300
|
</details>
|
|
250
301
|
|
|
251
|
-
> **Note:** When using the single-file download, replace `sigmap` with `node gen-context.js` in all commands below.
|
|
252
|
-
|
|
253
302
|
---
|
|
254
303
|
|
|
255
304
|
## 🚀 Features
|
|
@@ -264,17 +313,19 @@ sigmap --adapter claude # → CLAUDE.md (appended below marker)
|
|
|
264
313
|
sigmap --adapter cursor # → .cursorrules
|
|
265
314
|
sigmap --adapter windsurf # → .windsurfrules
|
|
266
315
|
sigmap --adapter openai # → .github/openai-context.md
|
|
267
|
-
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)
|
|
268
318
|
```
|
|
269
319
|
|
|
270
320
|
| Adapter | Output file | AI assistant |
|
|
271
321
|
|---|---|---|
|
|
272
|
-
| `copilot` | `.github/copilot-instructions.md` | GitHub Copilot |
|
|
322
|
+
| `copilot` | `.github/copilot-instructions.md` (append) | GitHub Copilot |
|
|
273
323
|
| `claude` | `CLAUDE.md` (append) | Claude / Claude Code |
|
|
274
324
|
| `cursor` | `.cursorrules` | Cursor |
|
|
275
325
|
| `windsurf` | `.windsurfrules` | Windsurf |
|
|
276
326
|
| `openai` | `.github/openai-context.md` | Any OpenAI model |
|
|
277
|
-
| `gemini` | `.github/gemini-context.md` | Google Gemini |
|
|
327
|
+
| `gemini` | `.github/gemini-context.md` (append) | Google Gemini |
|
|
328
|
+
| `codex` | `AGENTS.md` (append) | OpenAI Codex |
|
|
278
329
|
|
|
279
330
|
Configure multiple adapters at once in `gen-context.config.json`:
|
|
280
331
|
|
|
@@ -327,7 +378,7 @@ chmod +x ./sigmap-darwin-arm64
|
|
|
327
378
|
./sigmap-darwin-arm64
|
|
328
379
|
```
|
|
329
380
|
|
|
330
|
-
See [docs/binaries.md](docs/binaries.md) for Gatekeeper / SmartScreen notes and checksum verification.
|
|
381
|
+
See [docs/readmes/binaries.md](docs/readmes/binaries.md) for Gatekeeper / SmartScreen notes and checksum verification.
|
|
331
382
|
|
|
332
383
|
**npm** (requires Node.js 18+):
|
|
333
384
|
|
|
@@ -340,7 +391,7 @@ npm install -g sigmap # install globally
|
|
|
340
391
|
|
|
341
392
|
### Generate context
|
|
342
393
|
|
|
343
|
-
|
|
394
|
+
Once installed, run from your project root:
|
|
344
395
|
|
|
345
396
|
```bash
|
|
346
397
|
sigmap # generate once and exit
|
|
@@ -372,17 +423,17 @@ npx repomix --compress # deep dive sessions
|
|
|
372
423
|
|
|
373
424
|
## 🧩 VS Code extension
|
|
374
425
|
|
|
375
|
-
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.
|
|
376
427
|
|
|
377
428
|
| Feature | Detail |
|
|
378
429
|
|---|---|
|
|
379
430
|
| **Status bar item** | Shows health grade (`A`/`B`/`C`/`D`) + time since last regen; refreshes every 60 s |
|
|
380
431
|
| **Stale notification** | Warns when `copilot-instructions.md` is > 24 h old; one-click regeneration |
|
|
381
|
-
| **Regenerate command** | `SigMap: Regenerate Context` — runs `
|
|
432
|
+
| **Regenerate command** | `SigMap: Regenerate Context` — runs `sigmap` in the integrated terminal |
|
|
382
433
|
| **Open context command** | `SigMap: Open Context File` — opens `.github/copilot-instructions.md` |
|
|
383
|
-
| **Script path setting** | `sigmap.scriptPath` — override
|
|
434
|
+
| **Script path setting** | `sigmap.scriptPath` — override the path to the `sigmap` binary or `gen-context.js` |
|
|
384
435
|
|
|
385
|
-
|
|
436
|
+
Activates on startup (`onStartupFinished`) — loads within 3 s, never blocks editor startup.
|
|
386
437
|
|
|
387
438
|
**Install:** [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=manojmallick.sigmap) | [Open VSX Registry](https://open-vsx.org/extension/manojmallick/sigmap)
|
|
388
439
|
|
|
@@ -390,19 +441,19 @@ Activate on startup (`onStartupFinished`) — loads within 3 s, never blocks edi
|
|
|
390
441
|
|
|
391
442
|
## 🔧 JetBrains plugin
|
|
392
443
|
|
|
393
|
-
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.
|
|
394
445
|
|
|
395
446
|
| Feature | Detail |
|
|
396
447
|
|---|---|
|
|
397
448
|
| **Status bar widget** | Shows health grade (`A`-`F`) + time since last regen; updates every 60 s |
|
|
398
|
-
| **Regenerate action** | `Tools → SigMap → Regenerate Context` or **Ctrl+Alt+G** — runs `
|
|
449
|
+
| **Regenerate action** | `Tools → SigMap → Regenerate Context` or **Ctrl+Alt+G** — runs `sigmap` |
|
|
399
450
|
| **Open context action** | `Tools → SigMap → Open Context File` — opens `.github/copilot-instructions.md` |
|
|
400
451
|
| **View roadmap action** | `Tools → SigMap → View Roadmap` — opens roadmap in browser |
|
|
401
452
|
| **One-click regen** | Click status bar widget to regenerate context instantly |
|
|
402
453
|
|
|
403
454
|
Compatible with **IntelliJ IDEA 2024.1+** (Community & Ultimate), **WebStorm**, **PyCharm**, **GoLand**, **RubyMine**, **PhpStorm**, and all other IntelliJ-based IDEs.
|
|
404
455
|
|
|
405
|
-
**Install:** [JetBrains Marketplace](https://plugins.jetbrains.com/plugin/31109-sigmap--ai-context-engine/) | [Manual setup guide](docs/JETBRAINS_SETUP.md)
|
|
456
|
+
**Install:** [JetBrains Marketplace](https://plugins.jetbrains.com/plugin/31109-sigmap--ai-context-engine/) | [Manual setup guide](docs/readmes/JETBRAINS_SETUP.md)
|
|
406
457
|
|
|
407
458
|
---
|
|
408
459
|
|
|
@@ -484,7 +535,7 @@ One `.github/context-<module>.md` per top-level source directory, plus a tiny ov
|
|
|
484
535
|
|
|
485
536
|
Recently committed files are **hot** (auto-injected). Everything else is **cold** (on-demand via MCP). Best reduction available — ~200 tokens always-on.
|
|
486
537
|
|
|
487
|
-
📖 Full guide: [docs/CONTEXT_STRATEGIES.md](docs/CONTEXT_STRATEGIES.md) — decision tree, scenario comparisons, migration steps.
|
|
538
|
+
📖 Full guide: [docs/readmes/CONTEXT_STRATEGIES.md](docs/readmes/CONTEXT_STRATEGIES.md) — decision tree, scenario comparisons, migration steps.
|
|
488
539
|
|
|
489
540
|
---
|
|
490
541
|
|
|
@@ -493,7 +544,7 @@ Recently committed files are **hot** (auto-injected). Everything else is **cold*
|
|
|
493
544
|
Start the MCP server on stdio:
|
|
494
545
|
|
|
495
546
|
```bash
|
|
496
|
-
|
|
547
|
+
sigmap --mcp
|
|
497
548
|
```
|
|
498
549
|
|
|
499
550
|
### Available tools
|
|
@@ -511,7 +562,7 @@ node gen-context.js --mcp
|
|
|
511
562
|
|
|
512
563
|
Reads files on every call — no stale state, no restart needed.
|
|
513
564
|
|
|
514
|
-
📖 Setup guide: [docs/MCP_SETUP.md](docs/MCP_SETUP.md)
|
|
565
|
+
📖 Setup guide: [docs/readmes/MCP_SETUP.md](docs/readmes/MCP_SETUP.md)
|
|
515
566
|
|
|
516
567
|
---
|
|
517
568
|
|
|
@@ -519,57 +570,66 @@ Reads files on every call — no stale state, no restart needed.
|
|
|
519
570
|
|
|
520
571
|
> See [CHANGELOG.md](CHANGELOG.md) for the full history.
|
|
521
572
|
|
|
573
|
+
All flags are the same regardless of how you invoke SigMap — swap the prefix to match your install:
|
|
574
|
+
|
|
575
|
+
> `sigmap` · `npx sigmap` · `gen-context` · `node gen-context.js`
|
|
576
|
+
|
|
577
|
+
<details>
|
|
578
|
+
<summary><strong>All flags</strong></summary>
|
|
579
|
+
|
|
522
580
|
```
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
581
|
+
sigmap Generate once and exit
|
|
582
|
+
sigmap --watch Generate and watch for file changes
|
|
583
|
+
sigmap --setup Generate + install git hook + start watcher
|
|
584
|
+
sigmap --diff Generate context for git-changed files only
|
|
585
|
+
sigmap --diff --staged Staged files only (pre-commit check)
|
|
586
|
+
sigmap --mcp Start MCP server on stdio
|
|
529
587
|
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
588
|
+
sigmap --query "<text>" Rank files by relevance to a query
|
|
589
|
+
sigmap --query "<text>" --json Ranked results as JSON
|
|
590
|
+
sigmap --query "<text>" --top <n> Limit results to top N files (default 10)
|
|
533
591
|
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
592
|
+
sigmap --analyze Per-file breakdown (sigs / tokens / extractor / coverage)
|
|
593
|
+
sigmap --analyze --json Analysis as JSON
|
|
594
|
+
sigmap --analyze --slow Include extraction timing per file
|
|
595
|
+
sigmap --diagnose-extractors Self-test all 21 extractors against fixtures
|
|
538
596
|
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
597
|
+
sigmap --benchmark Run retrieval quality benchmark (hit@5 / MRR)
|
|
598
|
+
sigmap --benchmark --json Benchmark results as JSON
|
|
599
|
+
sigmap --eval Alias for --benchmark
|
|
542
600
|
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
601
|
+
sigmap --report Token reduction stats
|
|
602
|
+
sigmap --report --json Structured JSON report (exits 1 if over budget)
|
|
603
|
+
sigmap --report --history Usage log summary
|
|
604
|
+
sigmap --report --history --json Usage history as JSON
|
|
547
605
|
|
|
548
|
-
|
|
549
|
-
|
|
606
|
+
sigmap --health Composite health score (0–100, grade A–D)
|
|
607
|
+
sigmap --health --json Machine-readable health JSON
|
|
550
608
|
|
|
551
|
-
|
|
552
|
-
|
|
609
|
+
sigmap --suggest-tool "<task>" Recommend model tier for a task
|
|
610
|
+
sigmap --suggest-tool "<task>" --json Machine-readable tier recommendation
|
|
553
611
|
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
612
|
+
sigmap --monorepo Per-package context for monorepos (packages/, apps/, services/)
|
|
613
|
+
sigmap --each Process each sub-repo under a parent directory
|
|
614
|
+
sigmap --routing Include model routing hints in output
|
|
615
|
+
sigmap --format cache Write Anthropic prompt-cache JSON
|
|
616
|
+
sigmap --track Append run metrics to .context/usage.ndjson
|
|
559
617
|
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
618
|
+
sigmap --init Write config + .contextignore scaffold
|
|
619
|
+
sigmap --version Version string
|
|
620
|
+
sigmap --help Usage information
|
|
563
621
|
```
|
|
622
|
+
</details>
|
|
623
|
+
|
|
564
624
|
|
|
565
625
|
### Task classification — `--suggest-tool`
|
|
566
626
|
|
|
567
627
|
```bash
|
|
568
|
-
|
|
628
|
+
sigmap --suggest-tool "security audit of the auth module"
|
|
569
629
|
# tier : powerful
|
|
570
630
|
# models : claude-opus-4-6, gpt-5-4, gemini-2-5-pro
|
|
571
631
|
|
|
572
|
-
|
|
632
|
+
sigmap --suggest-tool "fix a typo in the yaml config" --json
|
|
573
633
|
# {"tier":"fast","label":"Fast (low-cost)","models":"claude-haiku-4-5, ...","costHint":"~$0.0008 / 1K tokens"}
|
|
574
634
|
```
|
|
575
635
|
|
|
@@ -635,7 +695,7 @@ build/
|
|
|
635
695
|
test/fixtures/
|
|
636
696
|
```
|
|
637
697
|
|
|
638
|
-
Run `
|
|
698
|
+
Run `sigmap --init` to scaffold both files in one step.
|
|
639
699
|
|
|
640
700
|
### Output targets
|
|
641
701
|
|
|
@@ -665,14 +725,14 @@ If `output` is omitted, the default `.github/copilot-instructions.md` is used.
|
|
|
665
725
|
|
|
666
726
|
```bash
|
|
667
727
|
# Append run metrics to .context/usage.ndjson
|
|
668
|
-
|
|
728
|
+
sigmap --track
|
|
669
729
|
|
|
670
730
|
# Structured JSON report for CI (exits 1 if over budget)
|
|
671
|
-
|
|
731
|
+
sigmap --report --json
|
|
672
732
|
# { "version": "2.0.0", "finalTokens": 3200, "reductionPct": 92.4, "overBudget": false }
|
|
673
733
|
|
|
674
734
|
# Composite health score
|
|
675
|
-
|
|
735
|
+
sigmap --health
|
|
676
736
|
# score: 95/100 (grade A) | reduction: 91.2% | 1 day since regen | 47 runs
|
|
677
737
|
```
|
|
678
738
|
|
|
@@ -684,22 +744,22 @@ Copy `examples/self-healing-github-action.yml` to `.github/workflows/` to auto-r
|
|
|
684
744
|
|
|
685
745
|
```yaml
|
|
686
746
|
- name: SigMap health check
|
|
687
|
-
run:
|
|
747
|
+
run: sigmap --health --json
|
|
688
748
|
- name: Regenerate context
|
|
689
|
-
run:
|
|
749
|
+
run: sigmap
|
|
690
750
|
```
|
|
691
751
|
|
|
692
|
-
📖 Full guide: [docs/ENTERPRISE_SETUP.md](docs/ENTERPRISE_SETUP.md)
|
|
752
|
+
📖 Full guide: [docs/readmes/ENTERPRISE_SETUP.md](docs/readmes/ENTERPRISE_SETUP.md)
|
|
693
753
|
|
|
694
754
|
### Prompt caching — 60% API cost reduction
|
|
695
755
|
|
|
696
756
|
```bash
|
|
697
|
-
|
|
757
|
+
sigmap --format cache
|
|
698
758
|
# Writes: .github/copilot-instructions.cache.json
|
|
699
759
|
# Format: { type: 'text', text: '...', cache_control: { type: 'ephemeral' } }
|
|
700
760
|
```
|
|
701
761
|
|
|
702
|
-
📖 Full guide: [docs/REPOMIX_CACHE.md](docs/REPOMIX_CACHE.md)
|
|
762
|
+
📖 Full guide: [docs/readmes/REPOMIX_CACHE.md](docs/readmes/REPOMIX_CACHE.md)
|
|
703
763
|
|
|
704
764
|
---
|
|
705
765
|
|
|
@@ -829,7 +889,7 @@ sigmap/
|
|
|
829
889
|
|
|
830
890
|
| Principle | Implementation |
|
|
831
891
|
|---|---|
|
|
832
|
-
| **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. |
|
|
833
893
|
| **Never throw** | All extractors return `[]` on any error — the run always completes |
|
|
834
894
|
| **Deterministic** | No AI or LLM involved in extraction — only regex + Node built-ins |
|
|
835
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
|
}
|
|
@@ -6257,7 +6320,7 @@ function detectRepoDirs(cwd) {
|
|
|
6257
6320
|
return repos;
|
|
6258
6321
|
}
|
|
6259
6322
|
|
|
6260
|
-
function runEach(cwd, baseConfig) {
|
|
6323
|
+
function runEach(cwd, baseConfig, adapterOverride) {
|
|
6261
6324
|
const repos = detectRepoDirs(cwd);
|
|
6262
6325
|
if (repos.length === 0) {
|
|
6263
6326
|
console.warn('[sigmap] --each: no project subdirectories found');
|
|
@@ -6276,6 +6339,13 @@ function runEach(cwd, baseConfig) {
|
|
|
6276
6339
|
} catch (_) {
|
|
6277
6340
|
repoConfig = { ...baseConfig };
|
|
6278
6341
|
}
|
|
6342
|
+
// --adapter override: apply on top of per-repo config
|
|
6343
|
+
if (adapterOverride) {
|
|
6344
|
+
repoConfig = Object.assign({}, repoConfig, {
|
|
6345
|
+
outputs: adapterOverride === 'claude' ? ['claude'] : [adapterOverride],
|
|
6346
|
+
adapters: [adapterOverride],
|
|
6347
|
+
});
|
|
6348
|
+
}
|
|
6279
6349
|
console.warn(`[sigmap] --each: processing ${name} …`);
|
|
6280
6350
|
try {
|
|
6281
6351
|
runGenerate(repoDir, repoConfig, false);
|
|
@@ -6413,8 +6483,8 @@ Strategies (set via config "strategy" key):
|
|
|
6413
6483
|
~90% fewer tokens. Best with MCP (Claude Code, Cursor).
|
|
6414
6484
|
Set "hotCommits": N to control how many commits count as hot (default 10).
|
|
6415
6485
|
|
|
6416
|
-
Adapters (v3.0+): copilot | claude | cursor | windsurf | openai | gemini
|
|
6417
|
-
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.
|
|
6418
6488
|
Old "outputs" config key is still accepted (maps to adapters automatically).
|
|
6419
6489
|
|
|
6420
6490
|
Config: gen-context.config.json
|
|
@@ -6748,12 +6818,29 @@ function main() {
|
|
|
6748
6818
|
process.exit(0);
|
|
6749
6819
|
}
|
|
6750
6820
|
|
|
6821
|
+
// ── --each [--adapter <name>] ────────────────────────────────────────────
|
|
6822
|
+
// Must be checked before --adapter so that --each --adapter <name> is
|
|
6823
|
+
// handled here (per-repo) rather than running a single generate on the
|
|
6824
|
+
// parent directory.
|
|
6825
|
+
if (args.includes('--each')) {
|
|
6826
|
+
const VALID_ADAPTERS = ['copilot', 'claude', 'cursor', 'windsurf', 'openai', 'gemini', 'codex'];
|
|
6827
|
+
const adpIdx = args.indexOf('--adapter');
|
|
6828
|
+
const adapterOverride = adpIdx >= 0 ? (args[adpIdx + 1] || '').trim().toLowerCase() : null;
|
|
6829
|
+
if (adapterOverride && !VALID_ADAPTERS.includes(adapterOverride)) {
|
|
6830
|
+
console.error(`[sigmap] --each: unknown adapter "${adapterOverride}"`);
|
|
6831
|
+
console.error(` Valid adapters: ${VALID_ADAPTERS.join(', ')}`);
|
|
6832
|
+
process.exit(1);
|
|
6833
|
+
}
|
|
6834
|
+
runEach(cwd, config, adapterOverride || null);
|
|
6835
|
+
process.exit(0);
|
|
6836
|
+
}
|
|
6837
|
+
|
|
6751
6838
|
// ── --adapter <name> ───────────────────────────────────────────────────────
|
|
6752
6839
|
if (args.includes('--adapter')) {
|
|
6753
6840
|
try {
|
|
6754
6841
|
const adpIdx = args.indexOf('--adapter');
|
|
6755
6842
|
const adapterName = (args[adpIdx + 1] || '').trim().toLowerCase();
|
|
6756
|
-
const VALID_ADAPTERS = ['copilot', 'claude', 'cursor', 'windsurf', 'openai', 'gemini'];
|
|
6843
|
+
const VALID_ADAPTERS = ['copilot', 'claude', 'cursor', 'windsurf', 'openai', 'gemini', 'codex'];
|
|
6757
6844
|
if (!adapterName || adapterName.startsWith('--')) {
|
|
6758
6845
|
console.error('[sigmap] --adapter requires an adapter name');
|
|
6759
6846
|
console.error(` Valid adapters: ${VALID_ADAPTERS.join(', ')}`);
|
|
@@ -6867,11 +6954,6 @@ function main() {
|
|
|
6867
6954
|
process.exit(0);
|
|
6868
6955
|
}
|
|
6869
6956
|
|
|
6870
|
-
if (args.includes('--each')) {
|
|
6871
|
-
runEach(cwd, config);
|
|
6872
|
-
process.exit(0);
|
|
6873
|
-
}
|
|
6874
|
-
|
|
6875
6957
|
if (args.includes('--setup')) {
|
|
6876
6958
|
runGenerate(cwd, config, false);
|
|
6877
6959
|
installHook(cwd, scriptPath);
|
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