⚡ SigMap

Zero-dependency AI context engine — 97% token reduction

Every coding agent session starts with full codebase context at under 4K tokens.
Multiple install options. Zero runtime dependencies. Requires only Node.js 18+.

npm version Tests Zero deps Last commit

License: MIT Node.js npm GitHub Stars

Docs Changelog PRs Welcome VS Code JetBrains Open VSX


Table of contents

What it does Token reduction table, pipeline overview
Quick start Install (binary or npm), generate in 60 seconds
Standalone binaries macOS, Linux, Windows — no Node required
VS Code extension Status bar, stale alerts, commands
JetBrains plugin IntelliJ IDEA, WebStorm, PyCharm support
Languages supported 21 languages
Context strategies full / per-module / hot-cold
MCP server 8 on-demand tools
CLI reference All flags
Configuration Config file + .contextignore
Observability Health score, reports, CI
Programmatic API Use as a Node.js library
Testing Run the test suite
Project structure File-by-file map
Principles Design decisions

📖 New to SigMap? Read the Complete Getting Started Guide — token savings walkthrough, every command, VS Code plugin, and CI setup.


🔍 What it does

SigMap scans your source files and extracts only the function and class signatures — no bodies, no imports, no comments — then writes a compact context file that Copilot, Claude, Cursor, and Windsurf read automatically. Every session starts with full codebase awareness at a fraction of the token cost.

Your codebase
    │
    ▼
gen-context.js ──► extracts signatures from 21 languages
    │
    ▼
.github/copilot-instructions.md   ◄── auto-read by Copilot / Claude / Cursor
    │
    ▼
AI agent session starts with full context

Dogfooding: SigMap runs on itself — 40 JS files, 8,600 lines of code. View the generated context: .github/copilot-instructions.md

Token reduction at every stage

Stage Tokens Reduction
Raw source files ~80,000
Repomix compressed ~8,000 90%
SigMap signatures ~4,000 95%
SigMap + MCP (hot-cold) ~200 99.75%

97% fewer tokens. The same codebase understanding.


⚡ Installation

Pick the method that fits your workflow — all produce the same output.

npx — try without installing ```bash npx sigmap ``` Runs the latest version without any permanent install. Great for a quick try. npm global — install once, run anywhere ```bash npm install -g sigmap sigmap ``` Available from any directory on your machine. Standalone binaries — no Node.js, no npm Download from the latest release: * [https://github.com/manojmallick/sigmap/releases/latest](https://github.com/manojmallick/sigmap/releases/latest) Available assets: * `sigmap-darwin-arm64` (macOS Apple Silicon) * `sigmap-linux-x64` (Linux x64) * `sigmap-win32-x64.exe` (Windows x64) * `sigmap-checksums.txt` (SHA-256 checksums) macOS / Linux Run directly: ```bash chmod +x ./sigmap-darwin-arm64 # or ./sigmap-linux-x64 ./sigmap-darwin-arm64 --help ./sigmap-darwin-arm64 ``` Make it globally available in Bash/Zsh (no `./` needed): ```bash # 1) Pick a user bin dir and move/rename the binary mkdir -p "$HOME/.local/bin" mv ./sigmap-darwin-arm64 "$HOME/.local/bin/sigmap" # or sigmap-linux-x64 chmod +x "$HOME/.local/bin/sigmap" # 2) Add to PATH in your shell profile echo 'export PATH="$HOME/.local/bin:$PATH"' >> "$HOME/.zshrc" # zsh # echo 'export PATH="$HOME/.local/bin:$PATH"' >> "$HOME/.bashrc" # bash # 3) Reload shell and verify source "$HOME/.zshrc" # or: source "$HOME/.bashrc" sigmap --version ``` Windows (PowerShell) Run directly: ```powershell .\sigmap-win32-x64.exe --help .\sigmap-win32-x64.exe ``` Make it globally available: ```powershell # 1) Create a user bin directory and rename the binary New-Item -ItemType Directory -Force "$HOME\bin" | Out-Null Move-Item .\sigmap-win32-x64.exe "$HOME\bin\sigmap.exe" # 2) Add user bin to PATH (current user) [Environment]::SetEnvironmentVariable( "Path", $env:Path + ";$HOME\bin", "User" ) # 3) Restart PowerShell and verify sigmap --version ```

Optional checksum verification:

shasum -a 256 sigmap-darwin-arm64
# Compare with sigmap-checksums.txt

Full guide: docs/binaries.md

npm local — per-project, version-pinned ```bash npm install --save-dev sigmap ``` Add to `package.json` scripts for team consistency: ```json { "scripts": { "context": "sigmap", "context:watch": "sigmap --watch" } } ``` Run with `npm run context`. Version is pinned per project. Volta — team-friendly, auto-pinned version ```bash volta install sigmap sigmap ``` [Volta](https://volta.sh) pins the exact version in `package.json` — every team member runs the same version automatically without configuration. Single-file download — no npm, any machine ```bash curl -O https://raw.githubusercontent.com/manojmallick/sigmap/main/gen-context.js node gen-context.js ``` No npm, no `node_modules`. Drop `gen-context.js` into any project and run it directly. Requires only Node.js 18+. Ideal for CI, locked-down environments, or one-off use.

Note: When using the single-file download, replace sigmap with node gen-context.js in all commands below.


🚀 Features

Multi-adapter output

Generate context for any AI assistant from a single run:

sigmap --adapter copilot    # → .github/copilot-instructions.md
sigmap --adapter claude     # → CLAUDE.md (appended below marker)
sigmap --adapter cursor     # → .cursorrules
sigmap --adapter windsurf   # → .windsurfrules
sigmap --adapter openai     # → .github/openai-context.md
sigmap --adapter gemini     # → .github/gemini-context.md
Adapter Output file AI assistant
copilot .github/copilot-instructions.md GitHub Copilot
claude CLAUDE.md (append) Claude / Claude Code
cursor .cursorrules Cursor
windsurf .windsurfrules Windsurf
openai .github/openai-context.md Any OpenAI model
gemini .github/gemini-context.md Google Gemini

Configure multiple adapters at once in gen-context.config.json:

{ "outputs": ["copilot", "claude", "cursor"] }

Programmatic API

Use SigMap as a Node.js library without spawning a subprocess. See the full API reference below.

Query-aware retrieval

Find the most relevant files for any task without reading the whole codebase:

sigmap --query "authentication middleware"   # ranked file list
sigmap --query "auth" --json                 # machine-readable output
sigmap --query "auth" --top 5               # top 5 results only

Diagnostic and evaluation tools

sigmap --analyze                  # per-file: sigs, tokens, extractor, coverage
sigmap --analyze --slow           # include extraction timing
sigmap --diagnose-extractors      # self-test all 21 extractors against fixtures
sigmap --benchmark                # hit@5 and MRR retrieval quality
sigmap --benchmark --json         # machine-readable benchmark results

⚡ Quick start

Install

Standalone binary — no Node.js or npm required:

Platform Download
macOS Apple Silicon sigmap-darwin-arm64
macOS Intel sigmap-darwin-x64
Linux x64 sigmap-linux-x64
Windows x64 sigmap-win32-x64.exe
# macOS / Linux
chmod +x ./sigmap-darwin-arm64
./sigmap-darwin-arm64

See docs/binaries.md for Gatekeeper / SmartScreen notes and checksum verification.

npm (requires Node.js 18+):

npx sigmap                  # run once without installing
npm install -g sigmap       # install globally

Generate context

Download the single-file CLI and generate context immediately:

sigmap                         # generate once and exit
sigmap --watch                 # regenerate on every file save
sigmap --setup                 # generate + install git hook + start watcher
sigmap --diff                  # context for git-changed files only (PR mode)
sigmap --diff --staged         # staged files only (pre-commit check)
sigmap --health                # show context health score (grade A–D)
sigmap --mcp                   # start MCP server on stdio

Companion tool: Repomix

SigMap and Repomix are complementary, not competing:

Tool When to use
SigMap Always-on, git hooks, daily signature index (~4K tokens)
Repomix On-demand deep sessions, full file content, broader language support
sigmap --setup         # always-on context
npx repomix --compress # deep dive sessions

"SigMap for daily always-on context; Repomix for deep one-off sessions — use both."


🧩 VS Code extension

The vscode-extension/ directory contains a first-party VS Code extension that keeps you informed without any manual commands.

Feature Detail
Status bar item Shows health grade (A/B/C/D) + time since last regen; refreshes every 60 s
Stale notification Warns when copilot-instructions.md is > 24 h old; one-click regeneration
Regenerate command SigMap: Regenerate Context — runs node gen-context.js in the integrated terminal
Open context command SigMap: Open Context File — opens .github/copilot-instructions.md
Script path setting sigmap.scriptPath — override when gen-context.js is not at the project root

Activate on startup (onStartupFinished) — loads within 3 s, never blocks editor startup.

Install: VS Code Marketplace | Open VSX Registry


🔧 JetBrains plugin

The jetbrains-plugin/ directory contains a Kotlin-based plugin for JetBrains IDEs with the same core features as the VS Code extension.

Feature Detail
Status bar widget Shows health grade (A-F) + time since last regen; updates every 60 s
Regenerate action Tools → SigMap → Regenerate Context or Ctrl+Alt+G — runs node gen-context.js
Open context action Tools → SigMap → Open Context File — opens .github/copilot-instructions.md
View roadmap action Tools → SigMap → View Roadmap — opens roadmap in browser
One-click regen Click status bar widget to regenerate context instantly

Compatible with IntelliJ IDEA 2024.1+ (Community & Ultimate), WebStorm, PyCharm, GoLand, RubyMine, PhpStorm, and all other IntelliJ-based IDEs.

Install: JetBrains Marketplace | Manual setup guide


🌐 Languages supported

21 languages. All implemented with zero external dependencies — pure regex + Node built-ins.

Show all 21 languages | Language | Extensions | Extracts | | ---------- | ------------------------------ | -------------------------------------------- | | TypeScript | `.ts` `.tsx` | interfaces, classes, functions, types, enums | | JavaScript | `.js` `.jsx` `.mjs` `.cjs` | classes, functions, exports | | Python | `.py` `.pyw` | classes, methods, functions | | Java | `.java` | classes, interfaces, methods | | Kotlin | `.kt` `.kts` | classes, data classes, functions | | Go | `.go` | structs, interfaces, functions | | Rust | `.rs` | structs, impls, traits, functions | | C# | `.cs` | classes, interfaces, methods | | C/C++ | `.cpp` `.c` `.h` `.hpp` `.cc` | classes, functions, templates | | Ruby | `.rb` `.rake` | classes, modules, methods | | PHP | `.php` | classes, interfaces, functions | | Swift | `.swift` | classes, structs, protocols, functions | | Dart | `.dart` | classes, mixins, functions | | Scala | `.scala` `.sc` | objects, classes, traits, functions | | Vue | `.vue` | `` functions and components | | Svelte | `.svelte` | `<script>` functions and exports | | HTML | `.html` `.htm` | custom elements and script functions | | CSS/SCSS | `.css` `.scss` `.sass` `.less` | custom properties and keyframes | | YAML | `.yml` `.yaml` | top-level keys and pipeline jobs | | Shell | `.sh` `.bash` `.zsh` `.fish` | function declarations | | Dockerfile | `Dockerfile` `Dockerfile.*` | stages and key instructions | </details> <hr> <h2 id="context-strategies">🗂 Context strategies</h2> <blockquote> <p>Reduce always-injected tokens by 70–90%.</p> </blockquote> <p>Set <code>&quot;strategy&quot;</code> in <code>gen-context.config.json</code>:</p> <table><thead> <tr> <th>Strategy</th> <th style="text-align: right">Always-injected</th> <th style="text-align: center">Context lost?</th> <th style="text-align: center">Needs MCP?</th> <th>Best for</th> </tr> </thead><tbody> <tr> <td><code>full</code></td> <td style="text-align: right">~4,000 tokens</td> <td style="text-align: center">No</td> <td style="text-align: center">No</td> <td>Starting out, cross-module work</td> </tr> <tr> <td><code>per-module</code></td> <td style="text-align: right">~100–300 tokens</td> <td style="text-align: center">No</td> <td style="text-align: center">No</td> <td>Large codebases, module-focused sessions</td> </tr> <tr> <td><code>hot-cold</code></td> <td style="text-align: right">~200–800 tokens</td> <td style="text-align: center">Cold files only</td> <td style="text-align: center">Yes</td> <td>Claude Code / Cursor with MCP enabled</td> </tr> </tbody></table> <h3 id="full-default-works-everywhere"><code>full</code> — default, works everywhere</h3> <pre class="language-json"><code>{ &quot;strategy&quot;: &quot;full&quot; } </code></pre> <p>One file, all signatures, always injected on every question.</p> <h3 id="per-module-70-fewer-injected-tokens-zero-context-loss"><code>per-module</code> — 70% fewer injected tokens, zero context loss</h3> <pre class="language-json"><code>{ &quot;strategy&quot;: &quot;per-module&quot; } </code></pre> <p>One <code>.github/context-&lt;module&gt;.md</code> per top-level source directory, plus a tiny overview table. Load the relevant module file for focused sessions. No MCP required.</p> <pre class="language-text"><code>.github/copilot-instructions.md ← overview table, ~117 tokens (always-on) .github/context-server.md ← server/ signatures, ~2,140 tokens .github/context-web.md ← web/ signatures, ~335 tokens .github/context-desktop.md ← desktop/ signatures, ~1,583 tokens </code></pre> <h3 id="hot-cold-90-fewer-injected-tokens-requires-mcp"><code>hot-cold</code> — 90% fewer injected tokens, requires MCP</h3> <pre class="language-json"><code>{ &quot;strategy&quot;: &quot;hot-cold&quot;, &quot;hotCommits&quot;: 10 } </code></pre> <p>Recently committed files are <strong>hot</strong> (auto-injected). Everything else is <strong>cold</strong> (on-demand via MCP). Best reduction available — ~200 tokens always-on.</p> <p>📖 Full guide: <a href="docs/CONTEXT_STRATEGIES.md">docs/CONTEXT_STRATEGIES.md</a> — decision tree, scenario comparisons, migration steps.</p> <hr> <h2 id="mcp-server">🔌 MCP server</h2> <p>Start the MCP server on stdio:</p> <pre class="language-bash"><code>node gen-context.js --mcp </code></pre> <h3 id="available-tools">Available tools</h3> <table><thead> <tr> <th>Tool</th> <th>Input</th> <th>Output</th> </tr> </thead><tbody> <tr> <td><code>read_context</code></td> <td><code>{ module?: string }</code></td> <td>Signatures for one module or entire codebase</td> </tr> <tr> <td><code>search_signatures</code></td> <td><code>{ query: string }</code></td> <td>Matching signatures with file paths</td> </tr> <tr> <td><code>get_map</code></td> <td>`{ type: &quot;imports&quot;\</td> <td>&quot;classes&quot;\</td> </tr> <tr> <td><code>explain_file</code></td> <td><code>{ path: string }</code></td> <td>Signatures + imports + reverse callers for one file</td> </tr> <tr> <td><code>list_modules</code></td> <td>—</td> <td>Token-count table of all top-level module directories</td> </tr> <tr> <td><code>create_checkpoint</code></td> <td><code>{ summary: string }</code></td> <td>Write a session checkpoint to <code>.context/</code></td> </tr> <tr> <td><code>get_routing</code></td> <td>—</td> <td>Full model routing table</td> </tr> <tr> <td><code>query_context</code></td> <td><code>{ query: string, topK?: number }</code></td> <td>Files ranked by relevance to the query</td> </tr> </tbody></table> <p>Reads files on every call — no stale state, no restart needed.</p> <p>📖 Setup guide: <a href="docs/MCP_SETUP.md">docs/MCP_SETUP.md</a></p> <hr> <h2 id="cli-reference">⚙️ CLI reference</h2> <blockquote> <p>See <a href="CHANGELOG.md">CHANGELOG.md</a> for the full history.</p> </blockquote> <p>Pick your invocation style — all commands are identical, only the prefix changes:</p> <details> <summary><strong>sigmap</strong> &nbsp;(npm global install)</summary> ```text sigmap Generate once and exit sigmap --watch Generate and watch for file changes sigmap --setup Generate + install git hook + start watcher sigmap --diff Generate context for git-changed files only sigmap --diff --staged Staged files only (pre-commit check) sigmap --mcp Start MCP server on stdio sigmap --query "<text>" Rank files by relevance to a query sigmap --query "<text>" --json Ranked results as JSON sigmap --query "<text>" --top <n> Limit results to top N files (default 10) sigmap --analyze Per-file breakdown (sigs / tokens / extractor / coverage) sigmap --analyze --json Analysis as JSON sigmap --analyze --slow Include extraction timing per file sigmap --diagnose-extractors Self-test all 21 extractors against fixtures sigmap --benchmark Run retrieval quality benchmark (hit@5 / MRR) sigmap --benchmark --json Benchmark results as JSON sigmap --eval Alias for --benchmark sigmap --report Token reduction stats sigmap --report --json Structured JSON report (exits 1 if over budget) sigmap --report --history Usage log summary sigmap --report --history --json Usage history as JSON sigmap --health Composite health score (0–100, grade A–D) sigmap --health --json Machine-readable health JSON sigmap --suggest-tool "<task>" Recommend model tier for a task sigmap --suggest-tool "<task>" --json Machine-readable tier recommendation sigmap --monorepo Per-package context for monorepos (packages/, apps/, services/) sigmap --each Process each sub-repo under a parent directory sigmap --routing Include model routing hints in output sigmap --format cache Write Anthropic prompt-cache JSON sigmap --track Append run metrics to .context/usage.ndjson sigmap --init Write config + .contextignore scaffold sigmap --version Version string sigmap --help Usage information ``` </details> <details> <summary><strong>npx sigmap</strong> &nbsp;(zero install)</summary> ```text npx sigmap Generate once and exit npx sigmap --watch Generate and watch for file changes npx sigmap --setup Generate + install git hook + start watcher npx sigmap --diff Generate context for git-changed files only npx sigmap --diff --staged Staged files only (pre-commit check) npx sigmap --mcp Start MCP server on stdio npx sigmap --query "<text>" Rank files by relevance to a query npx sigmap --query "<text>" --json Ranked results as JSON npx sigmap --query "<text>" --top <n> Limit results to top N files (default 10) npx sigmap --analyze Per-file breakdown (sigs / tokens / extractor / coverage) npx sigmap --analyze --json Analysis as JSON npx sigmap --analyze --slow Include extraction timing per file npx sigmap --diagnose-extractors Self-test all 21 extractors against fixtures npx sigmap --benchmark Run retrieval quality benchmark (hit@5 / MRR) npx sigmap --benchmark --json Benchmark results as JSON npx sigmap --eval Alias for --benchmark npx sigmap --report Token reduction stats npx sigmap --report --json Structured JSON report (exits 1 if over budget) npx sigmap --report --history Usage log summary npx sigmap --report --history --json Usage history as JSON npx sigmap --health Composite health score (0–100, grade A–D) npx sigmap --health --json Machine-readable health JSON npx sigmap --suggest-tool "<task>" Recommend model tier for a task npx sigmap --suggest-tool "<task>" --json Machine-readable tier recommendation npx sigmap --monorepo Per-package context for monorepos (packages/, apps/, services/) npx sigmap --each Process each sub-repo under a parent directory npx sigmap --routing Include model routing hints in output npx sigmap --format cache Write Anthropic prompt-cache JSON npx sigmap --track Append run metrics to .context/usage.ndjson npx sigmap --init Write config + .contextignore scaffold npx sigmap --version Version string npx sigmap --help Usage information ``` </details> <details> <summary><strong>gen-context</strong> &nbsp;(bin alias)</summary> ```text gen-context Generate once and exit gen-context --watch Generate and watch for file changes gen-context --setup Generate + install git hook + start watcher gen-context --diff Generate context for git-changed files only gen-context --diff --staged Staged files only (pre-commit check) gen-context --mcp Start MCP server on stdio gen-context --query "<text>" Rank files by relevance to a query gen-context --query "<text>" --json Ranked results as JSON gen-context --query "<text>" --top <n> Limit results to top N files (default 10) gen-context --analyze Per-file breakdown (sigs / tokens / extractor / coverage) gen-context --analyze --json Analysis as JSON gen-context --analyze --slow Include extraction timing per file gen-context --diagnose-extractors Self-test all 21 extractors against fixtures gen-context --benchmark Run retrieval quality benchmark (hit@5 / MRR) gen-context --benchmark --json Benchmark results as JSON gen-context --eval Alias for --benchmark gen-context --report Token reduction stats gen-context --report --json Structured JSON report (exits 1 if over budget) gen-context --report --history Usage log summary gen-context --report --history --json Usage history as JSON gen-context --health Composite health score (0–100, grade A–D) gen-context --health --json Machine-readable health JSON gen-context --suggest-tool "<task>" Recommend model tier for a task gen-context --suggest-tool "<task>" --json Machine-readable tier recommendation gen-context --monorepo Per-package context for monorepos (packages/, apps/, services/) gen-context --each Process each sub-repo under a parent directory gen-context --routing Include model routing hints in output gen-context --format cache Write Anthropic prompt-cache JSON gen-context --track Append run metrics to .context/usage.ndjson gen-context --init Write config + .contextignore scaffold gen-context --version Version string gen-context --help Usage information ``` </details> <details> <summary><strong>node gen-context.js</strong> &nbsp;(local / no install)</summary> ```text node gen-context.js Generate once and exit node gen-context.js --watch Generate and watch for file changes node gen-context.js --setup Generate + install git hook + start watcher node gen-context.js --diff Generate context for git-changed files only node gen-context.js --diff --staged Staged files only (pre-commit check) node gen-context.js --mcp Start MCP server on stdio node gen-context.js --query "<text>" Rank files by relevance to a query node gen-context.js --query "<text>" --json Ranked results as JSON node gen-context.js --query "<text>" --top <n> Limit results to top N files (default 10) node gen-context.js --analyze Per-file breakdown (sigs / tokens / extractor / coverage) node gen-context.js --analyze --json Analysis as JSON node gen-context.js --analyze --slow Include extraction timing per file node gen-context.js --diagnose-extractors Self-test all 21 extractors against fixtures node gen-context.js --benchmark Run retrieval quality benchmark (hit@5 / MRR) node gen-context.js --benchmark --json Benchmark results as JSON node gen-context.js --eval Alias for --benchmark node gen-context.js --report Token reduction stats node gen-context.js --report --json Structured JSON report (exits 1 if over budget) node gen-context.js --report --history Usage log summary node gen-context.js --report --history --json Usage history as JSON node gen-context.js --health Composite health score (0–100, grade A–D) node gen-context.js --health --json Machine-readable health JSON node gen-context.js --suggest-tool "<task>" Recommend model tier for a task node gen-context.js --suggest-tool "<task>" --json Machine-readable tier recommendation node gen-context.js --monorepo Per-package context for monorepos (packages/, apps/, services/) node gen-context.js --each Process each sub-repo under a parent directory node gen-context.js --routing Include model routing hints in output node gen-context.js --format cache Write Anthropic prompt-cache JSON node gen-context.js --track Append run metrics to .context/usage.ndjson node gen-context.js --init Write config + .contextignore scaffold node gen-context.js --version Version string node gen-context.js --help Usage information ``` </details> <h3 id="task-classification-suggest-tool">Task classification — <code>--suggest-tool</code></h3> <pre class="language-bash"><code>node gen-context.js --suggest-tool &quot;security audit of the auth module&quot; # tier : powerful # models : claude-opus-4-6, gpt-5-4, gemini-2-5-pro node gen-context.js --suggest-tool &quot;fix a typo in the yaml config&quot; --json # {&quot;tier&quot;:&quot;fast&quot;,&quot;label&quot;:&quot;Fast (low-cost)&quot;,&quot;models&quot;:&quot;claude-haiku-4-5, ...&quot;,&quot;costHint&quot;:&quot;~$0.0008 / 1K tokens&quot;} </code></pre> <p>Tiers: <code>fast</code> (config/markup/typos) · <code>balanced</code> (features/tests/debug) · <code>powerful</code> (architecture/security/multi-file)</p> <hr> <h2 id="security-scanning">🔒 Security scanning</h2> <p>SigMap automatically redacts secrets from all extracted signatures. Ten patterns are checked on every file:</p> <table><thead> <tr> <th>Pattern</th> <th>Example match</th> </tr> </thead><tbody> <tr> <td>AWS Access Key</td> <td><code>AKIA...</code></td> </tr> <tr> <td>AWS Secret Key</td> <td>40-char base64</td> </tr> <tr> <td>GCP API Key</td> <td><code>AIza...</code></td> </tr> <tr> <td>GitHub Token</td> <td><code>ghp_...</code> <code>gho_...</code></td> </tr> <tr> <td>JWT</td> <td><code>eyJ...</code></td> </tr> <tr> <td>DB Connection String</td> <td><code>postgres://user:pass@...</code></td> </tr> <tr> <td>SSH Private Key</td> <td><code>-----BEGIN ... PRIVATE KEY-----</code></td> </tr> <tr> <td>Stripe Key</td> <td><code>sk_live_...</code> <code>sk_test_...</code></td> </tr> <tr> <td>Twilio Key</td> <td><code>SK[32 hex chars]</code></td> </tr> <tr> <td>Generic secret</td> <td><code>password = &quot;...&quot;</code>, <code>api_key: &quot;...&quot;</code></td> </tr> </tbody></table> <p>If a match is found, the signature is replaced with <code>[REDACTED — {pattern} detected in {file}]</code>. The run continues — no silent failures.</p> <hr> <h2 id="configuration">⚙️ Configuration</h2> <p>Copy <code>gen-context.config.json.example</code> to <code>gen-context.config.json</code>:</p> <pre class="language-json"><code>{ &quot;output&quot;: &quot;.github/copilot-instructions.md&quot;, &quot;srcDirs&quot;: [&quot;src&quot;, &quot;app&quot;, &quot;lib&quot;], &quot;maxTokens&quot;: 6000, &quot;outputs&quot;: [&quot;copilot&quot;], &quot;secretScan&quot;: true, &quot;strategy&quot;: &quot;full&quot;, &quot;watchDebounce&quot;: 300, &quot;tracking&quot;: false } </code></pre> <p><strong>Key fields:</strong></p> <ul> <li><strong><code>output</code></strong> — custom path for the primary markdown output file (used by <code>copilot</code> adapter). Default: <code>.github/copilot-instructions.md</code></li> <li><strong><code>outputs</code></strong> — which adapters to write to: <code>copilot</code> | <code>claude</code> | <code>cursor</code> | <code>windsurf</code></li> <li><strong><code>srcDirs</code></strong> — directories to scan (relative to project root)</li> <li><strong><code>maxTokens</code></strong> — max tokens in final output before budget enforcement</li> <li><strong><code>secretScan</code></strong> — redact secrets (AWS keys, tokens, etc.) from output</li> <li><strong><code>strategy</code></strong> — output mode: <code>full</code> (default) | <code>per-module</code> | <code>hot-cold</code></li> </ul> <p>Exclusions go in <code>.contextignore</code> (gitignore syntax). Also reads <code>.repomixignore</code> if present.</p> <pre class="language-text"><code># .contextignore node_modules/ dist/ build/ *.generated.* test/fixtures/ </code></pre> <p>Run <code>node gen-context.js --init</code> to scaffold both files in one step.</p> <h3 id="output-targets">Output targets</h3> <table><thead> <tr> <th>Key</th> <th>Output file</th> <th>Read by</th> </tr> </thead><tbody> <tr> <td><code>&quot;copilot&quot;</code></td> <td><code>.github/copilot-instructions.md</code> <em>(or custom path via <code>output</code>)</em></td> <td>GitHub Copilot</td> </tr> <tr> <td><code>&quot;claude&quot;</code></td> <td><code>CLAUDE.md</code> (appends below marker)</td> <td>Claude Code</td> </tr> <tr> <td><code>&quot;cursor&quot;</code></td> <td><code>.cursorrules</code></td> <td>Cursor</td> </tr> <tr> <td><code>&quot;windsurf&quot;</code></td> <td><code>.windsurfrules</code></td> <td>Windsurf</td> </tr> </tbody></table> <p>The <strong><code>output</code></strong> config key sets the primary output file path. It is used by the <code>copilot</code> adapter when enabled. Other adapters always write to their fixed paths.</p> <p><strong>Example:</strong></p> <pre class="language-json"><code>{ &quot;output&quot;: &quot;.context/ai-context.md&quot;, &quot;outputs&quot;: [&quot;copilot&quot;] } </code></pre> <p>This writes to <code>.context/ai-context.md</code> instead of <code>.github/copilot-instructions.md</code>.</p> <p>If <code>output</code> is omitted, the default <code>.github/copilot-instructions.md</code> is used.</p> <h2 id="observability">📊 Observability</h2> <pre class="language-bash"><code># Append run metrics to .context/usage.ndjson node gen-context.js --track # Structured JSON report for CI (exits 1 if over budget) node gen-context.js --report --json # { &quot;version&quot;: &quot;2.0.0&quot;, &quot;finalTokens&quot;: 3200, &quot;reductionPct&quot;: 92.4, &quot;overBudget&quot;: false } # Composite health score node gen-context.js --health # score: 95/100 (grade A) | reduction: 91.2% | 1 day since regen | 47 runs </code></pre> <h3 id="self-healing-ci">Self-healing CI</h3> <p>Copy <code>examples/self-healing-github-action.yml</code> to <code>.github/workflows/</code> to auto-regenerate context when:</p> <ul> <li>Context file is more than 7 days old (always active)</li> <li>Copilot acceptance rate drops below 30% (requires <code>COPILOT_API_TOKEN</code> — GitHub Enterprise)</li> </ul> <pre class="language-yaml"><code>- name: SigMap health check run: node gen-context.js --health --json - name: Regenerate context run: node gen-context.js </code></pre> <p>📖 Full guide: <a href="docs/ENTERPRISE_SETUP.md">docs/ENTERPRISE_SETUP.md</a></p> <h3 id="prompt-caching-60-api-cost-reduction">Prompt caching — 60% API cost reduction</h3> <pre class="language-bash"><code>node gen-context.js --format cache # Writes: .github/copilot-instructions.cache.json # Format: { type: &#39;text&#39;, text: &#39;...&#39;, cache_control: { type: &#39;ephemeral&#39; } } </code></pre> <p>📖 Full guide: <a href="docs/REPOMIX_CACHE.md">docs/REPOMIX_CACHE.md</a></p> <hr> <h2 id="programmatic-api">📦 Programmatic API</h2> <p>Use SigMap as a library — no CLI subprocess needed:</p> <pre class="language-javascript"><code>const { extract, rank, buildSigIndex, scan, score } = require(&#39;sigmap&#39;); // Extract signatures from source code const sigs = extract(&#39;function hello() {}&#39;, &#39;javascript&#39;); // Build an index and rank files by query const index = buildSigIndex(&#39;/path/to/project&#39;); const results = rank(&#39;authentication middleware&#39;, index); // Scan signatures for secrets before storing const { safe, redacted } = scan(sigs, &#39;src/config.ts&#39;); // Get a composite health score for a project const health = score(&#39;/path/to/project&#39;); </code></pre> <p>📖 Full API reference: <a href="packages/core/README.md">packages/core/README.md</a></p> <hr> <h2 id="testing">🧪 Testing</h2> <pre class="language-bash"><code># All 21 language extractors node test/run.js # Single language node test/run.js typescript # Regenerate expected outputs after extractor changes node test/run.js --update # Full integration suite node test/integration/all.js </code></pre> <h3 id="validation-gates">Validation gates</h3> <pre class="language-bash"><code># Gate 1 — all tests pass node test/run.js # Expected: 21/21 PASS # Gate 2 — zero external dependencies grep &quot;require(&quot; gen-context.js | grep -v &quot;^.*//.*require&quot; # Expected: only fs, path, assert, os, crypto, child_process, readline # Gate 3 — MCP server responds correctly echo &#39;{&quot;jsonrpc&quot;:&quot;2.0&quot;,&quot;method&quot;:&quot;tools/list&quot;,&quot;id&quot;:1}&#39; | node gen-context.js --mcp # Expected: valid JSON with 8 tools # Gate 4 — npm artifact is clean npm pack --dry-run # Expected: no test/, docs/, vscode-extension/ in output </code></pre> <hr> <h2 id="project-structure">📁 Project structure</h2> <pre class="language-text"><code>sigmap/ │ ├── gen-context.js ← PRIMARY ENTRY POINT — single file, zero deps ├── gen-project-map.js ← import graph, class hierarchy, route table │ ├── packages/ │ ├── core/ ← programmatic API — require(&#39;sigmap&#39;) (v2.4) │ │ └── index.js ← extract, rank, buildSigIndex, scan, score │ └── cli/ ← thin CLI wrapper / v3 compat shim (v2.4) │ ├── src/ │ ├── extractors/ ← 21 language extractors (one file per language) │ ├── retrieval/ ← query-aware ranker + tokenizer (v2.3) │ ├── eval/ ← benchmark runner + scorer (v2.1), analyzer (v2.2) │ ├── mcp/ ← MCP stdio server — 8 tools │ ├── security/ ← secret scanner — 10 patterns │ ├── routing/ ← model routing hints │ ├── tracking/ ← NDJSON usage logger │ ├── health/ ← composite health scorer │ ├── format/ ← Anthropic prompt-cache formatter │ └── config/ ← config loader + defaults │ ├── vscode-extension/ ← VS Code extension (v1.5) │ ├── package.json ← manifest — commands, settings, activation │ └── src/extension.js ← status bar, stale notification, commands │ ├── test/ │ ├── fixtures/ ← one source file per language │ ├── expected/ ← expected extractor output │ ├── run.js ← zero-dep test runner │ └── integration/ ← 20 integration test files (304 tests) │ ├── docs/ ← documentation site (GitHub Pages) │ ├── index.html ← homepage │ ├── quick-start.html │ ├── strategies.html │ ├── languages.html │ ├── roadmap.html │ └── repomix.html │ ├── scripts/ │ ├── ci-update.sh ← CI pipeline helper │ └── release.sh ← version bump + npm publish helper │ ├── examples/ │ ├── self-healing-github-action.yml │ ├── github-action.yml ← ready-to-use CI workflow │ └── claude-code-settings.json ← MCP server config example │ ├── .npmignore ← excludes docs/, test/, vscode-extension/ from publish ├── .contextignore.example ← exclusion template └── gen-context.config.json.example ← annotated config reference </code></pre> <hr> <h2 id="principles">🏗 Principles</h2> <table><thead> <tr> <th>Principle</th> <th>Implementation</th> </tr> </thead><tbody> <tr> <td><strong>Zero npm dependencies</strong></td> <td><code>node gen-context.js</code> on a blank machine with Node 18+ — nothing else required</td> </tr> <tr> <td><strong>Never throw</strong></td> <td>All extractors return <code>[]</code> on any error — the run always completes</td> </tr> <tr> <td><strong>Deterministic</strong></td> <td>No AI or LLM involved in extraction — only regex + Node built-ins</td> </tr> <tr> <td><strong>Repomix is a companion</strong></td> <td>Use both tools; SigMap never replaces Repomix</td> </tr> <tr> <td><strong>No telemetry</strong></td> <td>Never phones home; all state is files in your repo</td> </tr> <tr> <td><strong>Local-first</strong></td> <td>No cloud service, no database, no accounts</td> </tr> </tbody></table> <hr> <h2 id="contributing">🤝 Contributing</h2> <p>See <a href="CONTRIBUTING.md">CONTRIBUTING.md</a> for how to add a language extractor or new feature.</p> <p>Every extractor follows the same contract:</p> <pre class="language-javascript"><code>module.exports = { extract }; function extract(src) { // src: string → string[] if (!src || typeof src !== &#39;string&#39;) return []; // ... regex extraction only — no external dependencies ... return sigs.slice(0, 25); // never more than 25 signatures per file } </code></pre> <hr> <h2 id="support">⭐ Support</h2> <p>If SigMap saves you context or API spend, a ⭐ on <a href="https://github.com/manojmallick/sigmap">GitHub</a> helps others find it.</p> <hr> <h2 id="license">📄 License</h2> <p>MIT © 2026 <a href="https://github.com/manojmallick">Manoj Mallick</a> · Made in Amsterdam 🇳🇱</p> <hr> <div align="center"> If SigMap saves you time — a ⭐ on [GitHub](https://github.com/manojmallick/sigmap) helps others find it. **[Docs](https://manojmallick.github.io/sigmap) · [Changelog](CHANGELOG.md) · [Roadmap](https://manojmallick.github.io/sigmap/roadmap.html) · [Repomix](https://github.com/yamadashy/repomix)** </div>

Built With

Share this project:

Updates