projscan 2.0.0 → 2.2.0

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.
Files changed (120) hide show
  1. package/README.md +38 -29
  2. package/dist/analyzers/supplyChainCheck.d.ts +2 -0
  3. package/dist/analyzers/supplyChainCheck.js +400 -0
  4. package/dist/analyzers/supplyChainCheck.js.map +1 -0
  5. package/dist/cli/_shared.d.ts +1 -0
  6. package/dist/cli/_shared.js +19 -3
  7. package/dist/cli/_shared.js.map +1 -1
  8. package/dist/cli/commands/analyze.js +7 -3
  9. package/dist/cli/commands/analyze.js.map +1 -1
  10. package/dist/cli/commands/applyFix.js +2 -2
  11. package/dist/cli/commands/applyFix.js.map +1 -1
  12. package/dist/cli/commands/audit.js +2 -2
  13. package/dist/cli/commands/audit.js.map +1 -1
  14. package/dist/cli/commands/badge.js +2 -1
  15. package/dist/cli/commands/badge.js.map +1 -1
  16. package/dist/cli/commands/ci.js +3 -3
  17. package/dist/cli/commands/ci.js.map +1 -1
  18. package/dist/cli/commands/coupling.js +2 -2
  19. package/dist/cli/commands/coupling.js.map +1 -1
  20. package/dist/cli/commands/coverage.js +2 -2
  21. package/dist/cli/commands/coverage.js.map +1 -1
  22. package/dist/cli/commands/dependencies.js +2 -2
  23. package/dist/cli/commands/dependencies.js.map +1 -1
  24. package/dist/cli/commands/diagram.js +2 -2
  25. package/dist/cli/commands/diagram.js.map +1 -1
  26. package/dist/cli/commands/diff.js +2 -2
  27. package/dist/cli/commands/diff.js.map +1 -1
  28. package/dist/cli/commands/doctor.js +3 -3
  29. package/dist/cli/commands/doctor.js.map +1 -1
  30. package/dist/cli/commands/explain.js +2 -2
  31. package/dist/cli/commands/explain.js.map +1 -1
  32. package/dist/cli/commands/explainIssue.js +2 -2
  33. package/dist/cli/commands/explainIssue.js.map +1 -1
  34. package/dist/cli/commands/file.js +2 -2
  35. package/dist/cli/commands/file.js.map +1 -1
  36. package/dist/cli/commands/fix.js +2 -1
  37. package/dist/cli/commands/fix.js.map +1 -1
  38. package/dist/cli/commands/fixSuggest.js +2 -2
  39. package/dist/cli/commands/fixSuggest.js.map +1 -1
  40. package/dist/cli/commands/help.js +2 -1
  41. package/dist/cli/commands/help.js.map +1 -1
  42. package/dist/cli/commands/hotspots.js +2 -2
  43. package/dist/cli/commands/hotspots.js.map +1 -1
  44. package/dist/cli/commands/impact.js +2 -2
  45. package/dist/cli/commands/impact.js.map +1 -1
  46. package/dist/cli/commands/init.js +2 -1
  47. package/dist/cli/commands/init.js.map +1 -1
  48. package/dist/cli/commands/installHook.js +2 -1
  49. package/dist/cli/commands/installHook.js.map +1 -1
  50. package/dist/cli/commands/mcp.js +2 -1
  51. package/dist/cli/commands/mcp.js.map +1 -1
  52. package/dist/cli/commands/memory.js +5 -4
  53. package/dist/cli/commands/memory.js.map +1 -1
  54. package/dist/cli/commands/outdated.js +2 -2
  55. package/dist/cli/commands/outdated.js.map +1 -1
  56. package/dist/cli/commands/plugin.js +83 -3
  57. package/dist/cli/commands/plugin.js.map +1 -1
  58. package/dist/cli/commands/prDiff.js +2 -2
  59. package/dist/cli/commands/prDiff.js.map +1 -1
  60. package/dist/cli/commands/preflight.d.ts +1 -0
  61. package/dist/cli/commands/preflight.js +80 -0
  62. package/dist/cli/commands/preflight.js.map +1 -0
  63. package/dist/cli/commands/review.js +2 -2
  64. package/dist/cli/commands/review.js.map +1 -1
  65. package/dist/cli/commands/search.js +2 -2
  66. package/dist/cli/commands/search.js.map +1 -1
  67. package/dist/cli/commands/session.js +5 -5
  68. package/dist/cli/commands/session.js.map +1 -1
  69. package/dist/cli/commands/structure.js +2 -2
  70. package/dist/cli/commands/structure.js.map +1 -1
  71. package/dist/cli/commands/taint.js +2 -2
  72. package/dist/cli/commands/taint.js.map +1 -1
  73. package/dist/cli/commands/upgrade.js +2 -2
  74. package/dist/cli/commands/upgrade.js.map +1 -1
  75. package/dist/cli/commands/watch.js +2 -1
  76. package/dist/cli/commands/watch.js.map +1 -1
  77. package/dist/cli/commands/workspace.js +4 -2
  78. package/dist/cli/commands/workspace.js.map +1 -1
  79. package/dist/cli/commands/workspaces.js +2 -2
  80. package/dist/cli/commands/workspaces.js.map +1 -1
  81. package/dist/cli/index.js +2 -0
  82. package/dist/cli/index.js.map +1 -1
  83. package/dist/core/issueEngine.js +2 -0
  84. package/dist/core/issueEngine.js.map +1 -1
  85. package/dist/core/pluginDx.d.ts +14 -0
  86. package/dist/core/pluginDx.js +298 -0
  87. package/dist/core/pluginDx.js.map +1 -0
  88. package/dist/core/plugins.d.ts +5 -6
  89. package/dist/core/plugins.js +99 -13
  90. package/dist/core/plugins.js.map +1 -1
  91. package/dist/core/preflight.d.ts +11 -0
  92. package/dist/core/preflight.js +450 -0
  93. package/dist/core/preflight.js.map +1 -0
  94. package/dist/core/review.js +132 -3
  95. package/dist/core/review.js.map +1 -1
  96. package/dist/core/sessionResources.d.ts +6 -0
  97. package/dist/core/sessionResources.js +216 -0
  98. package/dist/core/sessionResources.js.map +1 -0
  99. package/dist/mcp/resources.js +25 -0
  100. package/dist/mcp/resources.js.map +1 -1
  101. package/dist/mcp/tools/preflight.d.ts +2 -0
  102. package/dist/mcp/tools/preflight.js +51 -0
  103. package/dist/mcp/tools/preflight.js.map +1 -0
  104. package/dist/mcp/tools.js +2 -0
  105. package/dist/mcp/tools.js.map +1 -1
  106. package/dist/projscan-sbom.cdx.json +4589 -0
  107. package/dist/reporters/htmlReporter.d.ts +2 -1
  108. package/dist/reporters/htmlReporter.js +70 -0
  109. package/dist/reporters/htmlReporter.js.map +1 -1
  110. package/dist/tool-manifest.json +33 -3
  111. package/dist/types.d.ts +141 -0
  112. package/dist/utils/banner.js +14 -4
  113. package/dist/utils/banner.js.map +1 -1
  114. package/dist/utils/fileWalker.js +4 -0
  115. package/dist/utils/fileWalker.js.map +1 -1
  116. package/dist/utils/formatSupport.d.ts +58 -0
  117. package/dist/utils/formatSupport.js +63 -0
  118. package/dist/utils/formatSupport.js.map +1 -0
  119. package/docs/PLUGIN-AUTHORING.md +30 -0
  120. package/package.json +12 -7
package/README.md CHANGED
@@ -9,9 +9,9 @@
9
9
 
10
10
  **Agent-first code intelligence.** An MCP server that lets AI coding agents (Claude Code, Codex, Cursor, Gemini, Windsurf, Cline, Continue, Zed — any MCP-aware client) query your codebase — with a CLI for humans and a local plugin layer for team-specific policy and reporting.
11
11
 
12
- [AI Agent Quick Start](#ai-agent-integration-mcp) · [CLI Quick Start](#quick-start) · [Commands](#commands) · [Full Guide](https://github.com/abhiyoheswaran1/projscan/blob/v2.0.0/docs/GUIDE.md) · [Roadmap](https://github.com/abhiyoheswaran1/projscan/blob/v2.0.0/docs/ROADMAP.md)
12
+ [AI Agent Quick Start](#ai-agent-integration-mcp) · [CLI Quick Start](#quick-start) · [Commands](#commands) · [Full Guide](https://github.com/abhiyoheswaran1/projscan/blob/v2.2.0/docs/GUIDE.md) · [Roadmap](https://github.com/abhiyoheswaran1/projscan/blob/v2.2.0/docs/ROADMAP.md)
13
13
 
14
- <img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v2.0.0/docs/projscan-reporter-plugin.png" alt="projscan reporter plugin running in a macOS-style terminal window with a team health summary" width="700">
14
+ <img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v2.2.0/docs/projscan-reporter-plugin.png" alt="projscan reporter plugin running in a macOS-style terminal window with a team health summary" width="700">
15
15
 
16
16
  </div>
17
17
 
@@ -21,7 +21,7 @@
21
21
 
22
22
  AI coding agents are becoming the primary interface to code. Today, when you ask your agent *"which files implement auth?"* or *"what breaks if I bump React from 18 to 19?"* - it either guesses from names, or it shells out to grep and reads raw output not built for it.
23
23
 
24
- **projscan is the first code-intelligence tool built for agents, not for humans.** Your agent gets a fast, AST-accurate, context-budget-aware view of your codebase through 28 structured MCP tools. It can query the import graph, find symbol definitions, preview upgrades, rank hotspots, diff structural changes between refs, surface coupling/cycle hotspots, get an **intent-grounded** one-call PR review (now with new-taint-flow detection that *blocks* unsafe merges, plus an optional natural-language intent arg that labels each finding expected / unexpected / out-of-scope), request structured fix-action prompts for any open issue and **mechanically apply** the safe ones with rollback, ask "what breaks if I change this?" via transitive blast-radius analysis (across registered sibling repos too), surface source-to-sink taint flows, share a durable session across multiple agent invocations, and learn from how you use it — quieting accumulated noise on this specific repo over time without ever phoning home.
24
+ **projscan is the first code-intelligence tool built for agents, not for humans.** Your agent gets a fast, AST-accurate, context-budget-aware view of your codebase through structured MCP tools. It can run a preflight safety gate before edits or merge, including supply-chain IOC evidence, query the import graph, find symbol definitions, preview upgrades, rank hotspots, diff structural changes between refs, surface coupling/cycle hotspots, get an **intent-grounded** one-call PR review (now with new-taint-flow detection that *blocks* unsafe merges, plus an optional natural-language intent arg that labels each finding expected / unexpected / out-of-scope), request structured fix-action prompts for any open issue and **mechanically apply** the safe ones with rollback, ask "what breaks if I change this?" via transitive blast-radius analysis (across registered sibling repos too), surface source-to-sink taint flows, share a durable session across multiple agent invocations, and learn from how you use it — quieting accumulated noise on this specific repo over time without ever phoning home.
25
25
 
26
26
  The stable local plugin platform turns that same pipeline into a team substrate: analyzer plugins add project-specific findings, and reporter plugins render `doctor`, `analyze`, and `ci` in your team's own voice without changing the underlying scan.
27
27
 
@@ -33,7 +33,7 @@ Humans get the same thing through the CLI.
33
33
  npx projscan
34
34
  ```
35
35
 
36
- <img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v2.0.0/docs/projscan-reporter-plugin.gif" alt="projscan doctor rendered through a local reporter plugin in a macOS-style terminal window" width="700">
36
+ <img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v2.2.0/docs/projscan-reporter-plugin.gif" alt="projscan doctor rendered through a local reporter plugin in a macOS-style terminal window" width="700">
37
37
 
38
38
  Run `projscan doctor` for a focused health check:
39
39
 
@@ -41,7 +41,7 @@ Run `projscan doctor` for a focused health check:
41
41
  npx projscan doctor
42
42
  ```
43
43
 
44
- <img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v2.0.0/docs/npx%20projscan%20doctor.gif" alt="npx projscan doctor" width="700">
44
+ <img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v2.2.0/docs/npx%20projscan%20doctor.gif" alt="npx projscan doctor" width="700">
45
45
 
46
46
  ## Install
47
47
 
@@ -61,7 +61,8 @@ Run inside any repository:
61
61
 
62
62
  ```bash
63
63
  projscan # Full project analysis
64
- projscan doctor # Health check
64
+ projscan preflight --format json # Agent safety gate with supply-chain evidence
65
+ projscan doctor # Health check, including security and supply-chain risks
65
66
  projscan hotspots # Rank files by risk (churn × complexity × issues × ownership)
66
67
  projscan search <query> # BM25-ranked search (content + symbols + path)
67
68
  projscan file <path> # Drill into a file - purpose, risk, ownership, issues
@@ -78,19 +79,22 @@ projscan diagram # Architecture visualization
78
79
  projscan structure # Directory tree
79
80
  projscan mcp # Run as an MCP server for AI coding agents
80
81
  projscan plugin list # Discover local analyzer/reporter plugins
82
+ projscan plugin init --kind analyzer --name policy
83
+ projscan plugin test .projscan-plugins/policy.projscan-plugin.json
81
84
  PROJSCAN_PLUGINS_PREVIEW=1 projscan doctor --reporter team-radar
82
85
  ```
83
86
 
84
- <img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v2.0.0/docs/npx%20projscan%20--help.gif" alt="npx projscan --help" width="700">
87
+ <img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v2.2.0/docs/npx%20projscan%20--help.gif" alt="npx projscan --help" width="700">
85
88
 
86
- For a comprehensive walkthrough, see the **[Full Guide](https://github.com/abhiyoheswaran1/projscan/blob/v2.0.0/docs/GUIDE.md)**.
89
+ For a comprehensive walkthrough, see the **[Full Guide](https://github.com/abhiyoheswaran1/projscan/blob/v2.2.0/docs/GUIDE.md)**.
87
90
 
88
91
  ## Commands
89
92
 
90
93
  | Command | Description |
91
94
  |---------|-------------|
92
95
  | `projscan analyze` | Full analysis - languages, frameworks, dependencies, issues |
93
- | `projscan doctor` | Health check - missing tooling, architecture smells, security risks |
96
+ | `projscan doctor` | Health check - missing tooling, architecture smells, security and supply-chain risks |
97
+ | `projscan preflight` | Agent safety gate - `proceed`, `caution`, or `block` with health, change, plugin, and supply-chain evidence |
94
98
  | `projscan hotspots` | Rank files by risk - churn × complexity × issues × ownership |
95
99
  | `projscan search <query>` | **BM25-ranked search** - content + symbols + path, with excerpts |
96
100
  | `projscan file <path>` | Drill into a file - purpose, risk, ownership, related issues |
@@ -111,7 +115,7 @@ For a comprehensive walkthrough, see the **[Full Guide](https://github.com/abhiy
111
115
  | `projscan workspace` | *(1.6)* Register sibling repos for cross-repo intelligence (`add` / `list` / `remove`) |
112
116
  | `projscan apply-fix <id>` | *(1.6)* Mechanically execute the safe fix templates with rollback (default dry-run) |
113
117
  | `projscan taint` | *(1.6)* Source-to-sink reachability over the call graph |
114
- | `projscan plugin` | Discover and validate local analyzer/reporter plugins |
118
+ | `projscan plugin` | Discover, scaffold, validate, and test local analyzer/reporter plugins |
115
119
  | `projscan mcp` | Run as an MCP server for AI coding agents (Claude Code, Codex, Cursor, Gemini, Windsurf, …) |
116
120
 
117
121
  To see all commands and options, run:
@@ -125,50 +129,53 @@ projscan --help
125
129
  <details>
126
130
  <summary><strong>projscan structure</strong> - Directory tree with file counts</summary>
127
131
 
128
- <img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v2.0.0/docs/npx%20projscan%20structure.gif" alt="npx projscan structure" width="700">
132
+ <img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v2.2.0/docs/npx%20projscan%20structure.gif" alt="npx projscan structure" width="700">
129
133
  </details>
130
134
 
131
135
  <details>
132
136
  <summary><strong>projscan diagram</strong> - Architecture visualization</summary>
133
137
 
134
- <img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v2.0.0/docs/npx%20projscan%20diagram.gif" alt="npx projscan diagram" width="700">
138
+ <img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v2.2.0/docs/npx%20projscan%20diagram.gif" alt="npx projscan diagram" width="700">
135
139
  </details>
136
140
 
137
141
  <details>
138
142
  <summary><strong>projscan dependencies</strong> - Dependency analysis</summary>
139
143
 
140
- <img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v2.0.0/docs/npx%20projscan%20dependencies.gif" alt="npx projscan dependencies" width="700">
144
+ <img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v2.2.0/docs/npx%20projscan%20dependencies.gif" alt="npx projscan dependencies" width="700">
141
145
  </details>
142
146
 
143
147
  <details>
144
148
  <summary><strong>projscan explain</strong> - File explanation</summary>
145
149
 
146
- <img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v2.0.0/docs/npx%20projscan%20explain.gif" alt="npx projscan explain" width="700">
150
+ <img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v2.2.0/docs/npx%20projscan%20explain.gif" alt="npx projscan explain" width="700">
147
151
  </details>
148
152
 
149
153
  <details>
150
154
  <summary><strong>projscan badge</strong> - Health badge generation</summary>
151
155
 
152
- <img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v2.0.0/docs/npx%20projscan%20badge.gif" alt="npx projscan badge" width="700">
156
+ <img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v2.2.0/docs/npx%20projscan%20badge.gif" alt="npx projscan badge" width="700">
153
157
  </details>
154
158
 
155
159
  ### Output Formats
156
160
 
157
- All commands support `--format` for different output targets:
161
+ Commands accept `--format` for different output targets. Supported formats are command-dependent; unsupported combinations fail clearly instead of falling back to another renderer.
158
162
 
159
163
  ```bash
160
164
  projscan analyze --format json # Machine-readable JSON
165
+ projscan analyze --format html # Self-contained HTML report
161
166
  projscan doctor --format markdown # Markdown for docs/PRs
162
167
  projscan ci --format sarif # SARIF 2.1.0 for GitHub Code Scanning
163
168
  ```
164
169
 
165
- Formats: `console` (default), `json`, `markdown`, `sarif`
170
+ Formats: `console` (default), `json`, `markdown`, `sarif`, `html`
171
+
172
+ Run `projscan help` for the generated command-by-command support matrix.
166
173
 
167
174
  ### Plugin Platform
168
175
 
169
176
  projscan can load local plugins from `.projscan-plugins/` when `PROJSCAN_PLUGINS_PREVIEW=1` is set. The environment flag is kept for explicit local-code opt-in. Analyzer plugins emit normal projscan issues; reporter plugins render supported CLI commands with team-specific output.
170
177
 
171
- **2.0 upgrade notes:** migrating from 1.x or authoring plugins? Start with the [2.0 Migration Guide](https://github.com/abhiyoheswaran1/projscan/blob/v2.0.0/docs/2.0-MIGRATION.md), then use [Plugin Authoring](https://github.com/abhiyoheswaran1/projscan/blob/v2.0.0/docs/PLUGIN-AUTHORING.md) and the [manifest schema](https://github.com/abhiyoheswaran1/projscan/blob/v2.0.0/docs/plugin.schema.json) as the stable contract.
178
+ **2.0 upgrade notes:** migrating from 1.x or authoring plugins? Start with the [2.0 Migration Guide](https://github.com/abhiyoheswaran1/projscan/blob/v2.2.0/docs/2.0-MIGRATION.md), then use [Plugin Authoring](https://github.com/abhiyoheswaran1/projscan/blob/v2.2.0/docs/PLUGIN-AUTHORING.md) and the [manifest schema](https://github.com/abhiyoheswaran1/projscan/blob/v2.2.0/docs/plugin.schema.json) as the stable contract.
172
179
 
173
180
  ```bash
174
181
  projscan plugin list
@@ -177,15 +184,15 @@ PROJSCAN_PLUGINS_PREVIEW=1 projscan doctor --reporter team-radar
177
184
  PROJSCAN_PLUGINS_PREVIEW=1 projscan ci --reporter team-radar --min-score 80
178
185
  ```
179
186
 
180
- <img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v2.0.0/docs/projscan-reporter-plugin.gif" alt="projscan local reporter plugin rendering a team health report" width="700">
187
+ <img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v2.2.0/docs/projscan-reporter-plugin.gif" alt="projscan local reporter plugin rendering a team health report" width="700">
181
188
 
182
- Reporter plugins are intentionally CLI-only. MCP tools keep returning structured JSON-compatible payloads so agents can reason over stable data, while humans can get a polished local report for their team. Custom presentation, team-branded summaries, and white-label reports belong in reporter plugins rather than new core HTML theming flags. See [Plugin Authoring](https://github.com/abhiyoheswaran1/projscan/blob/v2.0.0/docs/PLUGIN-AUTHORING.md) for manifest shape, `render(context)`, validation, and the trust model.
189
+ Reporter plugins are intentionally CLI-only. MCP tools keep returning structured JSON-compatible payloads so agents can reason over stable data, while humans can get a polished local report for their team. Custom presentation, team-branded summaries, and white-label reports belong in reporter plugins rather than new core HTML theming flags. See [Plugin Authoring](https://github.com/abhiyoheswaran1/projscan/blob/v2.2.0/docs/PLUGIN-AUTHORING.md) for manifest shape, `render(context)`, validation, and the trust model.
183
190
 
184
191
  ### Options
185
192
 
186
193
  | Flag | Description |
187
194
  |------|-------------|
188
- | `--format <type>` | Output format: console, json, markdown, sarif |
195
+ | `--format <type>` | Output format: console, json, markdown, sarif, html (command-dependent) |
189
196
  | `--config <path>` | Path to a `.projscanrc` config file |
190
197
  | `--changed-only` | Scope to files changed vs base ref (ci/analyze/doctor) |
191
198
  | `--base-ref <ref>` | Git base ref for `--changed-only` (default: origin/main) |
@@ -312,7 +319,7 @@ projscan reads your source code so it can be useful; it does not send your sourc
312
319
 
313
320
  - **Send your source code off-machine.** Zero network calls in any code path projscan owns. File contents stay local; AST analysis runs in-process.
314
321
  - **Read environment variables for secrets.** `process.env` is forwarded to child processes (`git`, `npm`) so they can find their `PATH` — we never inspect `.env` values, API keys, or session tokens.
315
- - **Execute user input dynamically.** No `eval`, no `new Function(...)`, no shell-string composition. The two `await import('...')` sites in our code (`core/embeddings.ts` and `core/review.ts`) take literal string arguments and exist for lazy-loading optional code paths, not for running user-supplied code.
322
+ - **Execute command-line arguments as code.** Core CLI and MCP arguments are parsed as data, and projscan does not compose shell strings from user input. Local plugins are the explicit trust boundary: when `PROJSCAN_PLUGINS_PREVIEW=1` is set, projscan imports local modules declared in `.projscan-plugins/*.projscan-plugin.json` and runs their `check` / `render` exports.
316
323
  - **Phone home with telemetry.** The opt-in JSONL telemetry shipped in 0.11 was removed entirely in 0.12. Future telemetry, if any, will be remote-sink-with-dashboard and explicitly opt-in.
317
324
  - **Modify your repo without an explicit command.** `projscan fix` is the only command that writes to source files, and only when invoked. The cache directory `.projscan-cache/` is local-only and gitignored.
318
325
 
@@ -323,6 +330,8 @@ projscan reads your source code so it can be useful; it does not send your sourc
323
330
  | Read source files | every command | no | parses with tree-sitter / Babel; results cached at `.projscan-cache/` |
324
331
  | Spawn `git` | `hotspots`, `pr-diff`, `review`, `diff` | git itself may fetch if you run `git fetch` separately; **projscan never invokes `git fetch`** | `env: process.env` is passed so `git` can find its config |
325
332
  | Spawn `npm audit` | `audit` only | yes — by `npm`, not by projscan | runs against your local lockfile |
333
+ | Scan supply-chain IOCs | `doctor`, `preflight`, release validation | no | checks manifests, lockfiles, hidden editor hooks, and suspicious install-time payloads against bundled indicators |
334
+ | Load local plugins | only with `PROJSCAN_PLUGINS_PREVIEW=1` | no | imports local JS modules declared in `.projscan-plugins/`; only enable plugins you trust |
326
335
  | Load wasm grammars | first parse of a non-JS file | no | served from `dist/grammars/` inside the package; no fetch |
327
336
  | Build embeddings | semantic search opt-in only | yes — by `@xenova/transformers`, on first use | model cached locally after first download; remove the peer dep to remove this code path entirely |
328
337
 
@@ -331,14 +340,14 @@ projscan reads your source code so it can be useful; it does not send your sourc
331
340
  If you read projscan's [Socket report](https://socket.dev/npm/package/projscan), you'll see four supply-chain alerts. Here's a one-line answer to each:
332
341
 
333
342
  - **"Network access"** — comes from `web-tree-sitter`'s internal API surface; we feed it local wasm files at `dist/grammars/`. No outbound traffic.
334
- - **"Dynamic require"** — two static `await import('literal-string')` sites for optional code paths. No user-input-driven require.
343
+ - **"Dynamic require" / runtime import** — optional dependencies lazy-load from literal module names; opt-in local plugins load validated manifest module paths under `.projscan-plugins/`. Plugin execution is local code execution by design, gated by `PROJSCAN_PLUGINS_PREVIEW=1`.
335
344
  - **"Environment variable access"** — `env: process.env` is forwarded to child processes (`git`, `npm audit`). We don't read env contents.
336
345
  - **"URL strings"** — the strings are documentation references (`github.com`, `registry.npmjs.org`) shown in error messages and CHANGELOGs, not runtime fetch targets.
337
346
 
338
347
  ### Audit it yourself
339
348
 
340
349
  - **Source is open** at [github.com/abhiyoheswaran1/projscan](https://github.com/abhiyoheswaran1/projscan). The npm tarball matches the `dist/` produced by `npm run build` at the matching tag.
341
- - **Public API surface is locked** by `scripts/check-stability.mjs`, which runs in CI on every PR and fails on any rename or removal of an MCP tool, CLI command, or exit code. See [`docs/STABILITY.md`](https://github.com/abhiyoheswaran1/projscan/blob/v2.0.0/docs/STABILITY.md).
350
+ - **Public API surface is locked** by `scripts/check-stability.mjs`, which runs in CI on every PR and fails on any rename or removal of an MCP tool, CLI command, or exit code. See [`docs/STABILITY.md`](https://github.com/abhiyoheswaran1/projscan/blob/v2.2.0/docs/STABILITY.md).
342
351
  - **Run it offline:** `npm install -g projscan` followed by anything except `audit` and `--mode semantic` works without network.
343
352
  - **Drop privilege further:** in CI, run projscan in a sandbox that disallows network egress; everything except `audit` will pass.
344
353
 
@@ -376,7 +385,7 @@ projscan ci --changed-only # Gate only on this PR's diff
376
385
  projscan ci --format sarif > projscan.sarif # SARIF for Code Scanning
377
386
  ```
378
387
 
379
- <img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v2.0.0/docs/npx%20projscan%20ci%20--min-score%2070.gif" alt="npx projscan ci --min-score 70" width="700">
388
+ <img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v2.2.0/docs/npx%20projscan%20ci%20--min-score%2070.gif" alt="npx projscan ci --min-score 70" width="700">
380
389
 
381
390
  ### GitHub Action (recommended)
382
391
 
@@ -445,7 +454,7 @@ Fields:
445
454
  - `hotspots.limit` / `hotspots.since` - defaults for the `hotspots` command
446
455
  - `monorepo.importPolicy` - cross-package import allow/deny rules in monorepos *(0.14+)*
447
456
 
448
- See [`docs/GUIDE.md` → Configuration](https://github.com/abhiyoheswaran1/projscan/blob/v2.0.0/docs/GUIDE.md#configuration-projscanrc) for the full reference (field types, validation behavior, embedding config in `package.json`, monorepo `importPolicy` semantics).
457
+ See [`docs/GUIDE.md` → Configuration](https://github.com/abhiyoheswaran1/projscan/blob/v2.2.0/docs/GUIDE.md#configuration-projscanrc) for the full reference (field types, validation behavior, embedding config in `package.json`, monorepo `importPolicy` semantics).
449
458
 
450
459
  ## Tracking Health Over Time
451
460
 
@@ -458,7 +467,7 @@ projscan diff # Compare against baseline
458
467
  projscan diff --format markdown # Markdown diff for PRs
459
468
  ```
460
469
 
461
- <img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v2.0.0/docs/npx%20projscan%20diff%20--save-baseline.gif" alt="npx projscan diff --save-baseline" width="700">
470
+ <img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v2.2.0/docs/npx%20projscan%20diff%20--save-baseline.gif" alt="npx projscan diff --save-baseline" width="700">
462
471
 
463
472
  ## Hotspots - Where to Fix First
464
473
 
@@ -547,7 +556,7 @@ Coverage is also automatically joined into `projscan hotspots` when one of those
547
556
 
548
557
  **This is the primary way to use projscan.** `projscan mcp` starts an [MCP](https://modelcontextprotocol.io) server over stdio so AI coding agents can query your codebase with real structural accuracy - not regex, not grep.
549
558
 
550
- <img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v2.0.0/docs/projscan-agent-demo.gif" alt="projscan answering two agent questions: what breaks if I rename buildCodeGraph (impact analysis with definitions, direct callers, transitive reach), and where should I fix first (ranked hotspots with cyclomatic complexity)" width="700">
559
+ <img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v2.2.0/docs/projscan-agent-demo.gif" alt="projscan answering two agent questions: what breaks if I rename buildCodeGraph (impact analysis with definitions, direct callers, transitive reach), and where should I fix first (ranked hotspots with cyclomatic complexity)" width="700">
551
560
 
552
561
  Two questions an agent asks; structural answers in milliseconds. *"What breaks if I rename `buildCodeGraph`?"* → 31 direct callers, 97 files reachable. *"Where should I fix first?"* → ranked hotspots with AST cyclomatic complexity, churn, and ownership signals.
553
562
 
@@ -722,7 +731,7 @@ Capability is advertised under `experimental.fileChanged` on `initialize` so cli
722
731
  - **`projscan_apply_fix`** *(1.6)* - mechanically execute the safe fix templates. Default is dry-run; pass `confirm: true` to write. Atomic writes, per-apply rollback record at `.projscan-cache/rollbacks/<id>.json`. Reverse with `action: "rollback", rollback_id: ...`. Six templates supported at this release: `unused-dependency-*`, `missing-test-framework`, `missing-eslint`, `missing-prettier`, `missing-editorconfig`, `missing-readme`.
723
732
  - **`projscan_taint`** *(1.6)* - source-to-sink reachability over the per-function call graph. Built-in defaults cover common JS / Python sources (`process.env`, `req.body`, etc.) and sinks (`exec`, `eval`, `db.query`, etc.). Project-specific names go in `.projscanrc.json` `taint`. `projscan_review` automatically diffs taint flows between base and head and **blocks any PR that introduces a new flow**.
724
733
 
725
- For analyzer and reporter plugin authoring, manifest validation, `--reporter <name>`, and the trust model, see [Plugin Authoring](https://github.com/abhiyoheswaran1/projscan/blob/v2.0.0/docs/PLUGIN-AUTHORING.md).
734
+ For analyzer and reporter plugin authoring, manifest validation, `--reporter <name>`, and the trust model, see [Plugin Authoring](https://github.com/abhiyoheswaran1/projscan/blob/v2.2.0/docs/PLUGIN-AUTHORING.md).
726
735
 
727
736
  ### Context-window budgeting
728
737
 
@@ -0,0 +1,2 @@
1
+ import type { FileEntry, Issue } from '../types.js';
2
+ export declare function check(rootPath: string, files: FileEntry[]): Promise<Issue[]>;