projscan 2.9.0 → 3.0.1
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/README.md +31 -23
- package/dist/cli/commands/dataflow.d.ts +1 -0
- package/dist/cli/commands/dataflow.js +81 -0
- package/dist/cli/commands/dataflow.js.map +1 -0
- package/dist/cli/commands/semanticGraph.d.ts +1 -0
- package/dist/cli/commands/semanticGraph.js +55 -0
- package/dist/cli/commands/semanticGraph.js.map +1 -0
- package/dist/cli/index.js +4 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/core/agentBrief.js +31 -1
- package/dist/core/agentBrief.js.map +1 -1
- package/dist/core/dataflow.d.ts +11 -0
- package/dist/core/dataflow.js +277 -0
- package/dist/core/dataflow.js.map +1 -0
- package/dist/core/dataflowFilters.d.ts +10 -0
- package/dist/core/dataflowFilters.js +44 -0
- package/dist/core/dataflowFilters.js.map +1 -0
- package/dist/core/graphCorpus.d.ts +5 -0
- package/dist/core/graphCorpus.js +46 -0
- package/dist/core/graphCorpus.js.map +1 -0
- package/dist/core/impact.js +34 -0
- package/dist/core/impact.js.map +1 -1
- package/dist/core/intent.d.ts +1 -1
- package/dist/core/intent.js +16 -0
- package/dist/core/intent.js.map +1 -1
- package/dist/core/issueEngine.js +25 -1
- package/dist/core/issueEngine.js.map +1 -1
- package/dist/core/plugins.d.ts +10 -3
- package/dist/core/plugins.js +2 -2
- package/dist/core/plugins.js.map +1 -1
- package/dist/core/prDiff.js +25 -1
- package/dist/core/prDiff.js.map +1 -1
- package/dist/core/preflight.js +75 -6
- package/dist/core/preflight.js.map +1 -1
- package/dist/core/regressionPlan.js +2 -0
- package/dist/core/regressionPlan.js.map +1 -1
- package/dist/core/review.js +109 -3
- package/dist/core/review.js.map +1 -1
- package/dist/core/reviewDataflow.d.ts +6 -0
- package/dist/core/reviewDataflow.js +21 -0
- package/dist/core/reviewDataflow.js.map +1 -0
- package/dist/core/semanticGraph.d.ts +7 -0
- package/dist/core/semanticGraph.js +167 -0
- package/dist/core/semanticGraph.js.map +1 -0
- package/dist/core/taint.d.ts +5 -5
- package/dist/core/taint.js +35 -6
- package/dist/core/taint.js.map +1 -1
- package/dist/core/watcher.d.ts +2 -2
- package/dist/core/watcher.js +103 -17
- package/dist/core/watcher.js.map +1 -1
- package/dist/core/workplan.js +8 -8
- package/dist/core/workplan.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp/tools/costSummary.js +2 -0
- package/dist/mcp/tools/costSummary.js.map +1 -1
- package/dist/mcp/tools/dataflow.d.ts +2 -0
- package/dist/mcp/tools/dataflow.js +69 -0
- package/dist/mcp/tools/dataflow.js.map +1 -0
- package/dist/mcp/tools/semanticGraph.d.ts +2 -0
- package/dist/mcp/tools/semanticGraph.js +40 -0
- package/dist/mcp/tools/semanticGraph.js.map +1 -0
- package/dist/mcp/tools.js +4 -0
- package/dist/mcp/tools.js.map +1 -1
- package/dist/projscan-sbom.cdx.json +6 -6
- package/dist/tool-manifest.json +63 -3
- package/dist/types.d.ts +144 -3
- package/dist/utils/formatSupport.d.ts +2 -0
- package/dist/utils/formatSupport.js +2 -0
- package/dist/utils/formatSupport.js.map +1 -1
- package/docs/PLUGIN-AUTHORING.md +11 -3
- package/docs/PLUGIN-GALLERY.md +8 -0
- package/docs/examples/plugins/graph-context.mjs +27 -0
- package/docs/examples/plugins/graph-context.projscan-plugin.json +8 -0
- package/package.json +4 -3
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/
|
|
12
|
+
[AI Agent Quick Start](#ai-agent-integration-mcp) · [CLI Quick Start](#quick-start) · [Commands](#commands) · [Full Guide](https://github.com/abhiyoheswaran1/projscan/blob/v3.0.1/docs/GUIDE.md) · [Roadmap](https://github.com/abhiyoheswaran1/projscan/blob/v3.0.1/docs/ROADMAP.md)
|
|
13
13
|
|
|
14
|
-
<img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/
|
|
14
|
+
<img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v3.0.1/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 structured MCP tools. It can run a preflight safety gate before edits or merge, including supply-chain IOC evidence, query
|
|
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 a stable v3 semantic graph, detect bridge-helper dataflow risks, 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 and bridge-dataflow 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/
|
|
36
|
+
<img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v3.0.1/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/
|
|
44
|
+
<img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v3.0.1/docs/npx%20projscan%20doctor.gif" alt="npx projscan doctor" width="700">
|
|
45
45
|
|
|
46
46
|
## Install
|
|
47
47
|
|
|
@@ -75,6 +75,8 @@ projscan handoff # Concise next-agent handoff
|
|
|
75
75
|
projscan preflight --format json # Agent safety gate with supply-chain evidence
|
|
76
76
|
projscan doctor # Health check, including security and supply-chain risks
|
|
77
77
|
projscan hotspots # Rank files by risk (churn × complexity × issues × ownership)
|
|
78
|
+
projscan semantic-graph --format json # Stable v3 file/function/package/symbol graph
|
|
79
|
+
projscan dataflow --format json # Focused direct, propagated, and bridge dataflow risks
|
|
78
80
|
projscan search <query> # BM25-ranked search (content + symbols + path)
|
|
79
81
|
projscan file <path> # Drill into a file - purpose, risk, ownership, issues
|
|
80
82
|
projscan fix # Auto-fix detected issues
|
|
@@ -95,9 +97,9 @@ projscan plugin test .projscan-plugins/policy.projscan-plugin.json
|
|
|
95
97
|
PROJSCAN_PLUGINS_PREVIEW=1 projscan doctor --reporter team-radar
|
|
96
98
|
```
|
|
97
99
|
|
|
98
|
-
<img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/
|
|
100
|
+
<img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v3.0.1/docs/npx%20projscan%20--help.gif" alt="npx projscan --help" width="700">
|
|
99
101
|
|
|
100
|
-
For a comprehensive walkthrough, see the **[Full Guide](https://github.com/abhiyoheswaran1/projscan/blob/
|
|
102
|
+
For a comprehensive walkthrough, see the **[Full Guide](https://github.com/abhiyoheswaran1/projscan/blob/v3.0.1/docs/GUIDE.md)**.
|
|
101
103
|
|
|
102
104
|
## Commands
|
|
103
105
|
|
|
@@ -118,6 +120,8 @@ For a comprehensive walkthrough, see the **[Full Guide](https://github.com/abhiy
|
|
|
118
120
|
| `projscan doctor` | Health check - missing tooling, architecture smells, security and supply-chain risks |
|
|
119
121
|
| `projscan preflight` | Agent safety gate - `proceed`, `caution`, or `block` with health, change, plugin, and supply-chain evidence |
|
|
120
122
|
| `projscan hotspots` | Rank files by risk - churn × complexity × issues × ownership |
|
|
123
|
+
| `projscan semantic-graph` | Stable v3 graph contract - files, functions, packages, symbols, imports, exports, definitions, and calls |
|
|
124
|
+
| `projscan dataflow` | Focused direct, propagated, and bridge source-to-sink dataflow risks |
|
|
121
125
|
| `projscan search <query>` | **BM25-ranked search** - content + symbols + path, with excerpts |
|
|
122
126
|
| `projscan file <path>` | Drill into a file - purpose, risk, ownership, related issues |
|
|
123
127
|
| `projscan fix` | Auto-fix issues (ESLint, Prettier, Vitest, .editorconfig) |
|
|
@@ -151,31 +155,31 @@ projscan --help
|
|
|
151
155
|
<details>
|
|
152
156
|
<summary><strong>projscan structure</strong> - Directory tree with file counts</summary>
|
|
153
157
|
|
|
154
|
-
<img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/
|
|
158
|
+
<img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v3.0.1/docs/npx%20projscan%20structure.gif" alt="npx projscan structure" width="700">
|
|
155
159
|
</details>
|
|
156
160
|
|
|
157
161
|
<details>
|
|
158
162
|
<summary><strong>projscan diagram</strong> - Architecture visualization</summary>
|
|
159
163
|
|
|
160
|
-
<img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/
|
|
164
|
+
<img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v3.0.1/docs/npx%20projscan%20diagram.gif" alt="npx projscan diagram" width="700">
|
|
161
165
|
</details>
|
|
162
166
|
|
|
163
167
|
<details>
|
|
164
168
|
<summary><strong>projscan dependencies</strong> - Dependency analysis</summary>
|
|
165
169
|
|
|
166
|
-
<img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/
|
|
170
|
+
<img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v3.0.1/docs/npx%20projscan%20dependencies.gif" alt="npx projscan dependencies" width="700">
|
|
167
171
|
</details>
|
|
168
172
|
|
|
169
173
|
<details>
|
|
170
174
|
<summary><strong>projscan explain</strong> - File explanation</summary>
|
|
171
175
|
|
|
172
|
-
<img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/
|
|
176
|
+
<img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v3.0.1/docs/npx%20projscan%20explain.gif" alt="npx projscan explain" width="700">
|
|
173
177
|
</details>
|
|
174
178
|
|
|
175
179
|
<details>
|
|
176
180
|
<summary><strong>projscan badge</strong> - Health badge generation</summary>
|
|
177
181
|
|
|
178
|
-
<img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/
|
|
182
|
+
<img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v3.0.1/docs/npx%20projscan%20badge.gif" alt="npx projscan badge" width="700">
|
|
179
183
|
</details>
|
|
180
184
|
|
|
181
185
|
### Output Formats
|
|
@@ -197,7 +201,7 @@ Run `projscan help` for the generated command-by-command support matrix.
|
|
|
197
201
|
|
|
198
202
|
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.
|
|
199
203
|
|
|
200
|
-
**2.0 upgrade notes:** migrating from 1.x or authoring plugins? Start with the [2.0 Migration Guide](https://github.com/abhiyoheswaran1/projscan/blob/
|
|
204
|
+
**2.0 upgrade notes:** migrating from 1.x or authoring plugins? Start with the [2.0 Migration Guide](https://github.com/abhiyoheswaran1/projscan/blob/v3.0.1/docs/2.0-MIGRATION.md), then use [Plugin Authoring](https://github.com/abhiyoheswaran1/projscan/blob/v3.0.1/docs/PLUGIN-AUTHORING.md), the [Plugin Gallery](https://github.com/abhiyoheswaran1/projscan/blob/v3.0.1/docs/PLUGIN-GALLERY.md), and the [manifest schema](https://github.com/abhiyoheswaran1/projscan/blob/v3.0.1/docs/plugin.schema.json) as the stable contract.
|
|
201
205
|
|
|
202
206
|
```bash
|
|
203
207
|
projscan plugin list
|
|
@@ -206,9 +210,9 @@ PROJSCAN_PLUGINS_PREVIEW=1 projscan doctor --reporter team-radar
|
|
|
206
210
|
PROJSCAN_PLUGINS_PREVIEW=1 projscan ci --reporter team-radar --min-score 80
|
|
207
211
|
```
|
|
208
212
|
|
|
209
|
-
<img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/
|
|
213
|
+
<img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v3.0.1/docs/projscan-reporter-plugin.gif" alt="projscan local reporter plugin rendering a team health report" width="700">
|
|
210
214
|
|
|
211
|
-
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/
|
|
215
|
+
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/v3.0.1/docs/PLUGIN-AUTHORING.md) for manifest shape, `render(context)`, validation, and the trust model.
|
|
212
216
|
|
|
213
217
|
### Options
|
|
214
218
|
|
|
@@ -369,7 +373,7 @@ If you read projscan's [Socket report](https://socket.dev/npm/package/projscan),
|
|
|
369
373
|
### Audit it yourself
|
|
370
374
|
|
|
371
375
|
- **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.
|
|
372
|
-
- **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/
|
|
376
|
+
- **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/v3.0.1/docs/STABILITY.md).
|
|
373
377
|
- **Run it offline:** `npm install -g projscan` followed by anything except `audit` and `--mode semantic` works without network.
|
|
374
378
|
- **Drop privilege further:** in CI, run projscan in a sandbox that disallows network egress; everything except `audit` will pass.
|
|
375
379
|
|
|
@@ -407,7 +411,7 @@ projscan ci --changed-only # Gate only on this PR's diff
|
|
|
407
411
|
projscan ci --format sarif > projscan.sarif # SARIF for Code Scanning
|
|
408
412
|
```
|
|
409
413
|
|
|
410
|
-
<img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/
|
|
414
|
+
<img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v3.0.1/docs/npx%20projscan%20ci%20--min-score%2070.gif" alt="npx projscan ci --min-score 70" width="700">
|
|
411
415
|
|
|
412
416
|
### GitHub Action (recommended)
|
|
413
417
|
|
|
@@ -476,7 +480,7 @@ Fields:
|
|
|
476
480
|
- `hotspots.limit` / `hotspots.since` - defaults for the `hotspots` command
|
|
477
481
|
- `monorepo.importPolicy` - cross-package import allow/deny rules in monorepos *(0.14+)*
|
|
478
482
|
|
|
479
|
-
See [`docs/GUIDE.md` → Configuration](https://github.com/abhiyoheswaran1/projscan/blob/
|
|
483
|
+
See [`docs/GUIDE.md` → Configuration](https://github.com/abhiyoheswaran1/projscan/blob/v3.0.1/docs/GUIDE.md#configuration-projscanrc) for the full reference (field types, validation behavior, embedding config in `package.json`, monorepo `importPolicy` semantics).
|
|
480
484
|
|
|
481
485
|
## Tracking Health Over Time
|
|
482
486
|
|
|
@@ -489,7 +493,7 @@ projscan diff # Compare against baseline
|
|
|
489
493
|
projscan diff --format markdown # Markdown diff for PRs
|
|
490
494
|
```
|
|
491
495
|
|
|
492
|
-
<img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/
|
|
496
|
+
<img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v3.0.1/docs/npx%20projscan%20diff%20--save-baseline.gif" alt="npx projscan diff --save-baseline" width="700">
|
|
493
497
|
|
|
494
498
|
## Hotspots - Where to Fix First
|
|
495
499
|
|
|
@@ -578,7 +582,7 @@ Coverage is also automatically joined into `projscan hotspots` when one of those
|
|
|
578
582
|
|
|
579
583
|
**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.
|
|
580
584
|
|
|
581
|
-
<img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/
|
|
585
|
+
<img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v3.0.1/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">
|
|
582
586
|
|
|
583
587
|
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.
|
|
584
588
|
|
|
@@ -706,6 +710,8 @@ Capability is advertised under `experimental.fileChanged` on `initialize` so cli
|
|
|
706
710
|
### What agents can ask
|
|
707
711
|
|
|
708
712
|
- *"Who imports `src/auth/jwt.ts`?"* → `projscan_graph { file, direction: "importers" }`
|
|
713
|
+
- *"Give me the whole agent-safe graph contract."* → `projscan_semantic_graph`
|
|
714
|
+
- *"Did this wrapper connect a source reader to a dangerous sink?"* → `projscan_dataflow`
|
|
709
715
|
- *"Where is `runAudit` defined?"* → `projscan_search { query: "runAudit", scope: "symbols" }`
|
|
710
716
|
- *"Which files implement auth?"* → `projscan_search { query: "auth", scope: "content" }`
|
|
711
717
|
- *"What are the scariest untested files?"* → `projscan_coverage`
|
|
@@ -720,10 +726,12 @@ Capability is advertised under `experimental.fileChanged` on `initialize` so cli
|
|
|
720
726
|
- *"How do I plan the next six product lines?"* → `projscan_release_train`
|
|
721
727
|
- *"How do I wire projscan into this MCP client?"* → `projscan_adoption { action: "mcp_config", client: "codex" }`
|
|
722
728
|
|
|
723
|
-
### The
|
|
729
|
+
### The 39 MCP tools
|
|
724
730
|
|
|
725
731
|
**Structural (0.6.0 / 0.11 / 0.13 / 0.14 / 0.15 - agent-native):**
|
|
726
732
|
- **`projscan_graph`** - query the AST-based code graph. Directions: `imports`, `exports`, `importers`, `symbol_defs`, `package_importers`. Millisecond responses on a warm cache.
|
|
733
|
+
- **`projscan_semantic_graph`** *(3.0)* - stable v3 semantic graph contract with file, function, package, and symbol nodes plus `defines`, `imports`, `imports_package`, `exports`, and `calls` edges.
|
|
734
|
+
- **`projscan_dataflow`** *(3.0)* - focused direct, propagated, and bridge source-to-sink dataflow risks. Defaults suppress test-file paths, broad readFile/writeFile noise, and JavaScript RegExp.exec false positives; opt into those with `include_tests` / `include_broad_file_io` or the matching CLI flags.
|
|
727
735
|
- **`projscan_search`** - fast search across `symbols` (exported names), `files` (path substring), or `content` (source substring with line + excerpt). Sub-file mode (`sub_file: true`) embeds per-function for sharper semantic results *(0.15)*.
|
|
728
736
|
- **`projscan_coupling`** *(0.11)* - per-file fan-in / fan-out / instability + circular-import cycles (Tarjan SCC). Filter by `direction: cycles_only | high_fan_in | high_fan_out`.
|
|
729
737
|
- **`projscan_pr_diff`** *(0.11)* - structural diff between two git refs. Returns added/removed/modified files with explicit lists of exports, imports, and call sites that changed, plus ΔCC and Δfan-in.
|
|
@@ -767,9 +775,9 @@ Capability is advertised under `experimental.fileChanged` on `initialize` so cli
|
|
|
767
775
|
**Operator (1.6):**
|
|
768
776
|
- **`projscan_workspace_graph`** *(1.6)* - cross-repo intelligence over sibling repos registered with `projscan workspace add`. Subactions: `list` (registered repos + parsed-file + export counts), `graph` (every symbol exported by ≥ 2 repos — the candidate refactor / API contract surface), `file_importers` (given a file in one repo, every other repo whose graph imports it). Read-only.
|
|
769
777
|
- **`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`.
|
|
770
|
-
- **`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**.
|
|
778
|
+
- **`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**. In 3.0.1, review also surfaces hardened `newDataflowRisks` plus compact `graphEvidence` for graph-backed handoff.
|
|
771
779
|
|
|
772
|
-
For analyzer and reporter plugin authoring, manifest validation, `--reporter <name>`, and the trust model, see [Plugin Authoring](https://github.com/abhiyoheswaran1/projscan/blob/
|
|
780
|
+
Analyzer plugins can optionally read graph/dataflow context through `check(rootPath, files, context)` while staying on manifest schema v1. The packaged `graph-context` example shows `context.getSemanticGraph()` and `context.getDataflow()` in a real analyzer. For analyzer and reporter plugin authoring, manifest validation, `--reporter <name>`, and the trust model, see [Plugin Authoring](https://github.com/abhiyoheswaran1/projscan/blob/v3.0.1/docs/PLUGIN-AUTHORING.md).
|
|
773
781
|
|
|
774
782
|
### Context-window budgeting
|
|
775
783
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function registerDataflow(): void;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { assertFormatSupported, getRootPath, loadProjectConfig, maybeCompactBanner, program, setupLogLevel, } from '../_shared.js';
|
|
3
|
+
import { scanRepository } from '../../core/repositoryScanner.js';
|
|
4
|
+
import { buildCodeGraph } from '../../core/codeGraph.js';
|
|
5
|
+
import { computeDataflow } from '../../core/dataflow.js';
|
|
6
|
+
export function registerDataflow() {
|
|
7
|
+
program
|
|
8
|
+
.command('dataflow')
|
|
9
|
+
.description('Detect direct, propagated, and bridge source-to-sink dataflow risks')
|
|
10
|
+
.option('--source <name...>', 'add a custom source name (repeatable)')
|
|
11
|
+
.option('--sink <name...>', 'add a custom sink name (repeatable)')
|
|
12
|
+
.option('--max-risks <count>', 'maximum risks to return', parsePositiveInt)
|
|
13
|
+
.option('--include-tests', 'include dataflow risks that touch test files')
|
|
14
|
+
.option('--include-broad-file-io', 'include broad readFile/writeFile-style default risks')
|
|
15
|
+
.action(async (cmdOpts) => {
|
|
16
|
+
setupLogLevel();
|
|
17
|
+
maybeCompactBanner();
|
|
18
|
+
const format = assertFormatSupported('dataflow');
|
|
19
|
+
try {
|
|
20
|
+
const rootPath = getRootPath();
|
|
21
|
+
const config = await loadProjectConfig();
|
|
22
|
+
const scan = await scanRepository(rootPath, { ignore: config.ignore });
|
|
23
|
+
const graph = await buildCodeGraph(rootPath, scan.files);
|
|
24
|
+
const sources = [...(config.taint?.sources ?? []), ...(cmdOpts.source ?? [])];
|
|
25
|
+
const sinks = [...(config.taint?.sinks ?? []), ...(cmdOpts.sink ?? [])];
|
|
26
|
+
const maxRisks = Math.max(1, Math.min(500, cmdOpts.maxRisks ?? 50));
|
|
27
|
+
const report = computeDataflow(graph, { sources, sinks }, {
|
|
28
|
+
includeTests: cmdOpts.includeTests === true,
|
|
29
|
+
includeBroadFileIo: cmdOpts.includeBroadFileIo === true,
|
|
30
|
+
});
|
|
31
|
+
const shaped = {
|
|
32
|
+
...report,
|
|
33
|
+
risks: report.risks.slice(0, maxRisks),
|
|
34
|
+
truncated: report.risks.length > maxRisks || report.truncated,
|
|
35
|
+
};
|
|
36
|
+
if (format === 'json') {
|
|
37
|
+
console.log(JSON.stringify(shaped, null, 2));
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
printDataflow(shaped);
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
console.error(chalk.red(err instanceof Error ? err.message : String(err)));
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
function printDataflow(report) {
|
|
49
|
+
console.log('');
|
|
50
|
+
console.log(chalk.bold('Dataflow risks'));
|
|
51
|
+
console.log(chalk.dim('────────────────────────────────────────'));
|
|
52
|
+
if (!report.available) {
|
|
53
|
+
console.log(` ${chalk.yellow('!')} ${report.reason ?? 'unavailable'}`);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
if (report.riskCount === 0) {
|
|
57
|
+
console.log(' No dataflow risks detected.');
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
console.log(` ${chalk.bold(report.riskCount)} risk(s) detected:`);
|
|
61
|
+
console.log('');
|
|
62
|
+
for (const risk of report.risks) {
|
|
63
|
+
printRisk(risk);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
function printRisk(risk) {
|
|
67
|
+
const where = risk.bridgeFn ? `${risk.bridgeFn}: ` : '';
|
|
68
|
+
console.log(` ${chalk.red('●')} ${where}${chalk.bold(risk.source)} → ${chalk.bold(risk.sink)}`);
|
|
69
|
+
console.log(` ${chalk.dim('kind:')} ${risk.kind} (${risk.confidence})`);
|
|
70
|
+
console.log(` ${chalk.dim('path:')} ${risk.path.join(' → ')}`);
|
|
71
|
+
console.log(` ${chalk.dim('files:')} ${risk.files.join(', ')}`);
|
|
72
|
+
console.log('');
|
|
73
|
+
}
|
|
74
|
+
function parsePositiveInt(value) {
|
|
75
|
+
const parsed = Number.parseInt(value, 10);
|
|
76
|
+
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
77
|
+
throw new Error('value must be a positive integer');
|
|
78
|
+
}
|
|
79
|
+
return parsed;
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=dataflow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dataflow.js","sourceRoot":"","sources":["../../../src/cli/commands/dataflow.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function registerSemanticGraph(): void;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { assertFormatSupported, getRootPath, loadProjectConfig, maybeCompactBanner, program, setupLogLevel, } from '../_shared.js';
|
|
3
|
+
import { scanRepository } from '../../core/repositoryScanner.js';
|
|
4
|
+
import { buildCodeGraph } from '../../core/codeGraph.js';
|
|
5
|
+
import { buildSemanticGraph } from '../../core/semanticGraph.js';
|
|
6
|
+
export function registerSemanticGraph() {
|
|
7
|
+
program
|
|
8
|
+
.command('semantic-graph')
|
|
9
|
+
.description('Render the stable v3 semantic graph for agents and automation')
|
|
10
|
+
.option('--max-nodes <count>', 'maximum graph nodes to return', parsePositiveInt)
|
|
11
|
+
.option('--max-edges <count>', 'maximum graph edges to return', parsePositiveInt)
|
|
12
|
+
.action(async (cmdOpts) => {
|
|
13
|
+
setupLogLevel();
|
|
14
|
+
maybeCompactBanner();
|
|
15
|
+
const format = assertFormatSupported('semantic-graph');
|
|
16
|
+
try {
|
|
17
|
+
const rootPath = getRootPath();
|
|
18
|
+
const config = await loadProjectConfig();
|
|
19
|
+
const scan = await scanRepository(rootPath, { ignore: config.ignore });
|
|
20
|
+
const graph = await buildCodeGraph(rootPath, scan.files);
|
|
21
|
+
const report = buildSemanticGraph(graph, {
|
|
22
|
+
maxNodes: cmdOpts.maxNodes,
|
|
23
|
+
maxEdges: cmdOpts.maxEdges,
|
|
24
|
+
});
|
|
25
|
+
if (format === 'json') {
|
|
26
|
+
console.log(JSON.stringify(report, null, 2));
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
printSemanticGraph(report);
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
console.error(chalk.red(err instanceof Error ? err.message : String(err)));
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
function printSemanticGraph(report) {
|
|
38
|
+
console.log('');
|
|
39
|
+
console.log(chalk.bold('Semantic graph'));
|
|
40
|
+
console.log(chalk.dim('────────────────────────────────────────'));
|
|
41
|
+
console.log(` Schema: v${report.schemaVersion}`);
|
|
42
|
+
console.log(` Files: ${report.metrics.totalFiles}`);
|
|
43
|
+
console.log(` Functions: ${report.metrics.totalFunctions}`);
|
|
44
|
+
console.log(` Packages: ${report.metrics.totalPackages}`);
|
|
45
|
+
console.log(` Nodes: ${report.nodes.length}${report.truncated ? ' (truncated)' : ''}`);
|
|
46
|
+
console.log(` Edges: ${report.edges.length}`);
|
|
47
|
+
}
|
|
48
|
+
function parsePositiveInt(value) {
|
|
49
|
+
const parsed = Number.parseInt(value, 10);
|
|
50
|
+
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
51
|
+
throw new Error('value must be a positive integer');
|
|
52
|
+
}
|
|
53
|
+
return parsed;
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=semanticGraph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"semanticGraph.js","sourceRoot":"","sources":["../../../src/cli/commands/semanticGraph.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/index.js
CHANGED
|
@@ -24,6 +24,7 @@ import { registerAudit } from './commands/audit.js';
|
|
|
24
24
|
import { registerUpgrade } from './commands/upgrade.js';
|
|
25
25
|
import { registerSearch } from './commands/search.js';
|
|
26
26
|
import { registerCoverage } from './commands/coverage.js';
|
|
27
|
+
import { registerSemanticGraph } from './commands/semanticGraph.js';
|
|
27
28
|
import { registerMcp } from './commands/mcp.js';
|
|
28
29
|
import { registerSession } from './commands/session.js';
|
|
29
30
|
import { registerMemory } from './commands/memory.js';
|
|
@@ -32,6 +33,7 @@ import { registerApplyFix } from './commands/applyFix.js';
|
|
|
32
33
|
import { registerInit } from './commands/init.js';
|
|
33
34
|
import { registerInstallHook } from './commands/installHook.js';
|
|
34
35
|
import { registerTaint } from './commands/taint.js';
|
|
36
|
+
import { registerDataflow } from './commands/dataflow.js';
|
|
35
37
|
import { registerBadge } from './commands/badge.js';
|
|
36
38
|
import { registerPlugin } from './commands/plugin.js';
|
|
37
39
|
import { registerPreflight } from './commands/preflight.js';
|
|
@@ -68,6 +70,7 @@ registerAudit();
|
|
|
68
70
|
registerUpgrade();
|
|
69
71
|
registerSearch();
|
|
70
72
|
registerCoverage();
|
|
73
|
+
registerSemanticGraph();
|
|
71
74
|
registerMcp();
|
|
72
75
|
registerSession();
|
|
73
76
|
registerMemory();
|
|
@@ -76,6 +79,7 @@ registerApplyFix();
|
|
|
76
79
|
registerInit();
|
|
77
80
|
registerInstallHook();
|
|
78
81
|
registerTaint();
|
|
82
|
+
registerDataflow();
|
|
79
83
|
registerBadge();
|
|
80
84
|
registerPlugin();
|
|
81
85
|
registerPreflight();
|
package/dist/cli/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
|
package/dist/core/agentBrief.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { analyzeHotspots } from './hotspotAnalyzer.js';
|
|
2
|
+
import { buildCodeGraph } from './codeGraph.js';
|
|
3
|
+
import { computeDataflow } from './dataflow.js';
|
|
4
|
+
import { buildSemanticGraph } from './semanticGraph.js';
|
|
2
5
|
import { collectIssues } from './issueEngine.js';
|
|
3
6
|
import { scanRepository } from './repositoryScanner.js';
|
|
4
7
|
import { buildRiskNow } from './sessionResources.js';
|
|
@@ -12,9 +15,10 @@ export async function computeAgentBrief(rootPath, options = {}) {
|
|
|
12
15
|
const scan = await scanRepository(rootPath, { ignore: configResult.config.ignore });
|
|
13
16
|
const issues = applyConfigToIssues(await collectIssues(rootPath, scan.files), configResult.config);
|
|
14
17
|
const health = calculateScore(issues);
|
|
15
|
-
const [riskNow, hotspots] = await Promise.all([
|
|
18
|
+
const [riskNow, hotspots, graphContext] = await Promise.all([
|
|
16
19
|
safeRiskNow(rootPath),
|
|
17
20
|
safeHotspots(rootPath, scan.files, issues, maxItems),
|
|
21
|
+
safeGraphContext(rootPath, scan.files),
|
|
18
22
|
]);
|
|
19
23
|
const allFocus = rankFocus([
|
|
20
24
|
...issues.slice(0, maxItems * 2).map(issueToFocus),
|
|
@@ -34,6 +38,7 @@ export async function computeAgentBrief(rootPath, options = {}) {
|
|
|
34
38
|
topDirectories: topDirectories(scan.files),
|
|
35
39
|
touchedFiles: riskNow.touchedFiles.slice(0, 12),
|
|
36
40
|
conflicts: riskNow.conflicts.length,
|
|
41
|
+
...(graphContext ? { graph: graphContext } : {}),
|
|
37
42
|
},
|
|
38
43
|
focus,
|
|
39
44
|
guardrails,
|
|
@@ -41,6 +46,31 @@ export async function computeAgentBrief(rootPath, options = {}) {
|
|
|
41
46
|
...(allFocus.length > focus.length || riskNow.touchedFiles.length > 12 ? { truncated: true } : {}),
|
|
42
47
|
};
|
|
43
48
|
}
|
|
49
|
+
async function safeGraphContext(rootPath, files) {
|
|
50
|
+
try {
|
|
51
|
+
const graph = await buildCodeGraph(rootPath, files);
|
|
52
|
+
const semantic = buildSemanticGraph(graph, { maxNodes: 5_000, maxEdges: 10_000 });
|
|
53
|
+
const dataflow = computeDataflow(graph, { sources: [], sinks: [] });
|
|
54
|
+
return {
|
|
55
|
+
schemaVersion: 1,
|
|
56
|
+
totalFunctions: semantic.metrics.totalFunctions,
|
|
57
|
+
totalPackages: semantic.metrics.totalPackages,
|
|
58
|
+
totalCallEdges: semantic.edges.filter((edge) => edge.kind === 'calls').length,
|
|
59
|
+
dataflowRisks: dataflow.riskCount,
|
|
60
|
+
topPackages: topPackagesByImporters(graph),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function topPackagesByImporters(graph) {
|
|
68
|
+
return [...graph.packageImporters.entries()]
|
|
69
|
+
.map(([name, importers]) => ({ name, count: importers.size }))
|
|
70
|
+
.sort((a, b) => b.count - a.count || a.name.localeCompare(b.name))
|
|
71
|
+
.slice(0, 5)
|
|
72
|
+
.map((entry) => entry.name);
|
|
73
|
+
}
|
|
44
74
|
async function safeRiskNow(rootPath) {
|
|
45
75
|
try {
|
|
46
76
|
return await buildRiskNow(rootPath);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agentBrief.js","sourceRoot":"","sources":["../../src/core/agentBrief.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"agentBrief.js","sourceRoot":"","sources":["../../src/core/agentBrief.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { CodeGraph } from './codeGraph.js';
|
|
2
|
+
import { type TaintConfig } from './taint.js';
|
|
3
|
+
import type { DataflowReport } from '../types.js';
|
|
4
|
+
export interface DataflowOptions {
|
|
5
|
+
maxDepth?: number;
|
|
6
|
+
/** Include risks whose path touches test files. Default false for signal. */
|
|
7
|
+
includeTests?: boolean;
|
|
8
|
+
/** Include broad default readFile/writeFile-style risks. Custom sources/sinks still report. */
|
|
9
|
+
includeBroadFileIo?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare function computeDataflow(graph: CodeGraph, config?: TaintConfig, options?: DataflowOptions): DataflowReport;
|