projscan 3.0.8 → 3.1.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.
- package/PRIVACY.md +14 -0
- package/README.md +71 -70
- package/TELEMETRY.md +100 -0
- package/dist/analyzers/securityCheck.d.ts +4 -1
- package/dist/analyzers/securityCheck.js +5 -1
- package/dist/analyzers/securityCheck.js.map +1 -1
- package/dist/cli/_shared.js +44 -0
- package/dist/cli/_shared.js.map +1 -1
- package/dist/cli/commands/feedback.js +3 -1
- package/dist/cli/commands/feedback.js.map +1 -1
- package/dist/cli/commands/init.js +33 -1
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/privacyCheck.d.ts +1 -0
- package/dist/cli/commands/privacyCheck.js +66 -0
- package/dist/cli/commands/privacyCheck.js.map +1 -0
- package/dist/cli/commands/telemetry.d.ts +1 -0
- package/dist/cli/commands/telemetry.js +131 -0
- package/dist/cli/commands/telemetry.js.map +1 -0
- package/dist/cli/index.js +4 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/core/adoption.d.ts +1 -1
- package/dist/core/adoption.js +7 -0
- package/dist/core/adoption.js.map +1 -1
- package/dist/core/auditRunner.js +4 -0
- package/dist/core/auditRunner.js.map +1 -1
- package/dist/core/embeddings.js +3 -0
- package/dist/core/embeddings.js.map +1 -1
- package/dist/core/issueEngine.d.ts +5 -1
- package/dist/core/issueEngine.js +16 -3
- package/dist/core/issueEngine.js.map +1 -1
- package/dist/core/preflight.js +28 -7
- package/dist/core/preflight.js.map +1 -1
- package/dist/core/privacy.d.ts +59 -0
- package/dist/core/privacy.js +129 -0
- package/dist/core/privacy.js.map +1 -0
- package/dist/core/repositoryScanner.d.ts +2 -0
- package/dist/core/repositoryScanner.js +88 -5
- package/dist/core/repositoryScanner.js.map +1 -1
- package/dist/core/sessionResources.js +7 -7
- package/dist/core/sessionResources.js.map +1 -1
- package/dist/core/start.js +42 -1
- package/dist/core/start.js.map +1 -1
- package/dist/core/telemetry.d.ts +114 -0
- package/dist/core/telemetry.js +451 -0
- package/dist/core/telemetry.js.map +1 -0
- package/dist/core/upgradePreview.js +10 -4
- package/dist/core/upgradePreview.js.map +1 -1
- package/dist/core/watcher.js +2 -4
- package/dist/core/watcher.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp/server.js +5 -2
- package/dist/mcp/server.js.map +1 -1
- package/dist/projscan-sbom.cdx.json +6 -6
- package/dist/tool-manifest.json +2 -2
- package/dist/types.d.ts +50 -0
- package/dist/utils/changedFiles.js +5 -4
- package/dist/utils/changedFiles.js.map +1 -1
- package/dist/utils/config.js +15 -0
- package/dist/utils/config.js.map +1 -1
- package/dist/utils/fileWalker.js +1 -1
- package/dist/utils/fileWalker.js.map +1 -1
- package/dist/utils/formatSupport.d.ts +6 -0
- package/dist/utils/formatSupport.js +6 -0
- package/dist/utils/formatSupport.js.map +1 -1
- package/package.json +4 -2
package/PRIVACY.md
CHANGED
|
@@ -8,8 +8,12 @@ projscan is part of the Baseframe Labs family of products (https://www.baseframe
|
|
|
8
8
|
|
|
9
9
|
By default, projscan runs on your machine and reads files in the repository where you run it. It does not upload source code, dependency data, scan results, telemetry, or usage analytics to a projscan service.
|
|
10
10
|
|
|
11
|
+
Inside a Git repository, projscan uses Git's own visible-file boundary by default: tracked files plus untracked files that are not excluded by `.gitignore`, `.git/info/exclude`, or global Git excludes. Files hidden by Git ignore rules are not scanned unless you explicitly opt in with `--include-ignored` or `scan.includeIgnored: true`. Non-Git folders fall back to projscan's built-in local noise ignores.
|
|
12
|
+
|
|
11
13
|
projscan may write local files when you ask it to, such as `.projscan-cache/`, `.projscan-feedback.json`, baselines, handoff files, generated policies, generated GitHub Actions, or reports.
|
|
12
14
|
|
|
15
|
+
Run `projscan privacy-check` to see the current telemetry status, offline status, scan root, ignore boundary, ignored-file count, `.env` content-scanning status, plugin execution status, local write surfaces, report-export sensitivity, and network-capable endpoints.
|
|
16
|
+
|
|
13
17
|
## Commands that can involve network access
|
|
14
18
|
|
|
15
19
|
Some workflows can involve network access because they call external tooling or package managers:
|
|
@@ -18,14 +22,24 @@ Some workflows can involve network access because they call external tooling or
|
|
|
18
22
|
- `projscan audit` shells out to npm audit behavior for the current project
|
|
19
23
|
- commands or modes that explicitly ask for registry checks may contact the configured package registry
|
|
20
24
|
- semantic search can download an optional local embedding model when the optional `@xenova/transformers` peer is installed and the user opts into semantic mode
|
|
25
|
+
|
|
26
|
+
Set `PROJSCAN_OFFLINE=1`, pass `--offline`, or set `scan.offline: true` to block projscan's known network-capable features: telemetry sending, `projscan audit`, registry checks, and optional semantic model loading. This does not prevent npm or npx from contacting the registry before projscan starts.
|
|
21
27
|
- local analyzer or reporter plugins can do anything their code does; only enable plugins you trust
|
|
22
28
|
|
|
23
29
|
## Environment variables and secrets
|
|
24
30
|
|
|
25
31
|
projscan may pass `process.env` to child processes such as Git or npm so those tools work normally. projscan does not intentionally inspect `.env` values, API keys, session tokens, or private credentials for telemetry or product analytics.
|
|
26
32
|
|
|
33
|
+
`.env*` files are path-only by default. If a `.env` file is tracked by Git, projscan can flag that filename as risky, but it does not read the `.env` file contents for secret-pattern detection unless you explicitly opt in with `--scan-env-values` or `scan.scanEnvValues: true`.
|
|
34
|
+
|
|
27
35
|
Security analyzers may flag committed secret-looking strings in repository files. Those findings stay in local output unless you choose to copy, save, or publish them.
|
|
28
36
|
|
|
37
|
+
## Optional telemetry
|
|
38
|
+
|
|
39
|
+
Telemetry is off by default. Users can opt in with `projscan telemetry enable` or through the interactive `projscan init team` prompt. When enabled, projscan sends only anonymous product-health events: command category, success/failure, duration bucket, version/platform, setup booleans, repeat-use buckets, and optional feedback buckets. It does not send source code, file paths, repository names, branch names, package names, usernames, email addresses, raw findings, secrets, environment values, or scan reports.
|
|
40
|
+
|
|
41
|
+
See `TELEMETRY.md` for the full allowlist, controls, endpoint, and environment variables.
|
|
42
|
+
|
|
29
43
|
## Feedback artifacts
|
|
30
44
|
|
|
31
45
|
`projscan feedback` creates local JSON evidence about reviewer usefulness, minutes saved, prevented bad edits, false positives, owner clarity, next-command clarity, and repeat PR use. Treat that artifact as team data. Do not commit it if it contains private PR URLs, reviewer handles, or internal notes you do not want public.
|
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/v3.0
|
|
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.1.0/docs/GUIDE.md) · [Roadmap](https://github.com/abhiyoheswaran1/projscan/blob/v3.1.0/docs/ROADMAP.md)
|
|
13
13
|
|
|
14
|
-
<img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v3.0
|
|
14
|
+
<img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v3.1.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
|
|
|
@@ -27,13 +27,13 @@ For teams, projscan turns that context into a repeatable PR habit. `projscan ini
|
|
|
27
27
|
|
|
28
28
|
The local plugin platform lets teams add project-specific findings and render `doctor`, `analyze`, and `ci` in their own voice without changing the scan pipeline. Humans get the same information through the CLI.
|
|
29
29
|
|
|
30
|
-
**Everything is
|
|
30
|
+
**Everything is local-first. No source upload. No API keys. `.gitignore` is respected by default. `.env` values are path-only unless explicitly enabled. Anonymous product telemetry is off by default and only runs after explicit opt-in.**
|
|
31
31
|
|
|
32
32
|
```bash
|
|
33
33
|
npx projscan
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
-
<img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v3.0
|
|
36
|
+
<img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v3.1.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/v3.0
|
|
44
|
+
<img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v3.1.0/docs/npx%20projscan%20doctor.gif" alt="npx projscan doctor" width="700">
|
|
45
45
|
|
|
46
46
|
## Install
|
|
47
47
|
|
|
@@ -57,59 +57,45 @@ npx projscan
|
|
|
57
57
|
|
|
58
58
|
## Quick Start
|
|
59
59
|
|
|
60
|
-
Run inside
|
|
60
|
+
Run this path first inside a repository:
|
|
61
61
|
|
|
62
62
|
```bash
|
|
63
|
-
projscan
|
|
64
|
-
projscan start
|
|
65
|
-
projscan
|
|
66
|
-
projscan
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
projscan
|
|
73
|
-
projscan
|
|
74
|
-
projscan
|
|
75
|
-
projscan
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
projscan
|
|
82
|
-
projscan
|
|
83
|
-
projscan
|
|
84
|
-
projscan
|
|
85
|
-
projscan
|
|
86
|
-
projscan doctor # Health check, including security and supply-chain risks
|
|
87
|
-
projscan hotspots # Rank files by risk (churn × complexity × issues × ownership)
|
|
88
|
-
projscan semantic-graph --format json # Stable v3 file/function/package/symbol graph
|
|
89
|
-
projscan dataflow --format json # Focused direct, propagated, and bridge dataflow risks
|
|
90
|
-
projscan search <query> # BM25-ranked search (content + symbols + path)
|
|
91
|
-
projscan file <path> # Drill into a file - purpose, risk, ownership, issues
|
|
92
|
-
projscan fix # Auto-fix detected issues
|
|
93
|
-
projscan ci # CI health gate (exits 1 on low score)
|
|
94
|
-
projscan ci --changed-only # Gate only on this PR's diff
|
|
95
|
-
projscan ci --format sarif # SARIF 2.1.0 for GitHub Code Scanning
|
|
96
|
-
projscan outdated # Declared-vs-installed drift (offline)
|
|
97
|
-
projscan audit # npm audit, normalized + SARIF-ready
|
|
98
|
-
projscan upgrade <pkg> # Preview upgrade impact (local CHANGELOG + importers)
|
|
99
|
-
projscan coverage # Coverage × hotspots - scariest untested files
|
|
100
|
-
projscan diff # Compare health + hotspot trends against a baseline
|
|
101
|
-
projscan diagram # Architecture visualization
|
|
102
|
-
projscan structure # Directory tree
|
|
103
|
-
projscan mcp # Run as an MCP server for AI coding agents
|
|
104
|
-
projscan plugin list # Discover local analyzer/reporter plugins
|
|
105
|
-
projscan plugin init --kind analyzer --name policy
|
|
106
|
-
projscan plugin test .projscan-plugins/policy.projscan-plugin.json
|
|
107
|
-
PROJSCAN_PLUGINS_PREVIEW=1 projscan doctor --reporter team-radar
|
|
63
|
+
projscan privacy-check # Show exactly what can be read, written, or contacted
|
|
64
|
+
projscan start # First-60-seconds workflow orientation
|
|
65
|
+
projscan preflight --format json # Proceed/caution/block safety gate
|
|
66
|
+
projscan evidence-pack --pr-comment # Reviewer-ready PR evidence
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
For MCP clients:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
projscan first-run
|
|
73
|
+
projscan init mcp --client all
|
|
74
|
+
projscan mcp doctor --client codex
|
|
75
|
+
projscan mcp
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
For team rollout after the first local run is trusted:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
projscan init team --team security
|
|
82
|
+
projscan telemetry explain
|
|
83
|
+
projscan feedback init --output .projscan-feedback.json
|
|
84
|
+
projscan dogfood --repo ../api --repo ../web --repo ../worker --feedback .projscan-feedback.json --format json
|
|
85
|
+
projscan trial --repo ../api --repo ../web --repo ../worker --feedback .projscan-feedback.json --format json
|
|
108
86
|
```
|
|
109
87
|
|
|
110
|
-
|
|
88
|
+
For maintainers changing trust-sensitive behavior:
|
|
111
89
|
|
|
112
|
-
|
|
90
|
+
```bash
|
|
91
|
+
npm run test:trust-smoke
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
The full command catalog is below. Most users should start with the four-command path above instead of scanning the catalog.
|
|
95
|
+
|
|
96
|
+
<img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v3.1.0/docs/npx%20projscan%20--help.gif" alt="npx projscan --help" width="700">
|
|
97
|
+
|
|
98
|
+
For a comprehensive walkthrough, see the **[Full Guide](https://github.com/abhiyoheswaran1/projscan/blob/v3.1.0/docs/GUIDE.md)**.
|
|
113
99
|
|
|
114
100
|
## Commands
|
|
115
101
|
|
|
@@ -132,6 +118,8 @@ For a comprehensive walkthrough, see the **[Full Guide](https://github.com/abhiy
|
|
|
132
118
|
| `projscan evidence-pack` | Assemble approval evidence from planning, bug-hunt, workplan, preflight, trust calibration, First Fix, owner routing, and baseline trend memory |
|
|
133
119
|
| `projscan trial` | Produce one adoption-readiness report from onboarding, dogfood, feedback, trust signals, and website proof |
|
|
134
120
|
| `projscan feedback` | Capture measured reviewer feedback: minutes saved, prevented bad edits, false positives, and repeat PR use |
|
|
121
|
+
| `projscan privacy-check` | Verify the local trust boundary: telemetry, offline mode, scan root, .gitignore handling, ignored-file count, .env content scanning, and network-capable endpoints |
|
|
122
|
+
| `projscan telemetry` | Explicit default-off telemetry controls: status, enable, disable, and explain |
|
|
135
123
|
| `projscan dogfood` | Evaluate 1+ real repos for PR-comment readiness, repeat-use readiness, MCP readiness, and reviewer feedback prompts |
|
|
136
124
|
| `projscan regression-plan` | Build a smoke, focused, or full regression matrix from product risk signals |
|
|
137
125
|
| `projscan handoff` | Concise next-agent handoff from the current workplan |
|
|
@@ -173,31 +161,31 @@ projscan --help
|
|
|
173
161
|
<details>
|
|
174
162
|
<summary><strong>projscan structure</strong> - Directory tree with file counts</summary>
|
|
175
163
|
|
|
176
|
-
<img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v3.0
|
|
164
|
+
<img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v3.1.0/docs/npx%20projscan%20structure.gif" alt="npx projscan structure" width="700">
|
|
177
165
|
</details>
|
|
178
166
|
|
|
179
167
|
<details>
|
|
180
168
|
<summary><strong>projscan diagram</strong> - Architecture visualization</summary>
|
|
181
169
|
|
|
182
|
-
<img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v3.0
|
|
170
|
+
<img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v3.1.0/docs/npx%20projscan%20diagram.gif" alt="npx projscan diagram" width="700">
|
|
183
171
|
</details>
|
|
184
172
|
|
|
185
173
|
<details>
|
|
186
174
|
<summary><strong>projscan dependencies</strong> - Dependency analysis</summary>
|
|
187
175
|
|
|
188
|
-
<img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v3.0
|
|
176
|
+
<img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v3.1.0/docs/npx%20projscan%20dependencies.gif" alt="npx projscan dependencies" width="700">
|
|
189
177
|
</details>
|
|
190
178
|
|
|
191
179
|
<details>
|
|
192
180
|
<summary><strong>projscan explain</strong> - File explanation</summary>
|
|
193
181
|
|
|
194
|
-
<img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v3.0
|
|
182
|
+
<img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v3.1.0/docs/npx%20projscan%20explain.gif" alt="npx projscan explain" width="700">
|
|
195
183
|
</details>
|
|
196
184
|
|
|
197
185
|
<details>
|
|
198
186
|
<summary><strong>projscan badge</strong> - Health badge generation</summary>
|
|
199
187
|
|
|
200
|
-
<img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v3.0
|
|
188
|
+
<img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v3.1.0/docs/npx%20projscan%20badge.gif" alt="npx projscan badge" width="700">
|
|
201
189
|
</details>
|
|
202
190
|
|
|
203
191
|
### Output Formats
|
|
@@ -219,7 +207,7 @@ Run `projscan help` for the generated command-by-command support matrix.
|
|
|
219
207
|
|
|
220
208
|
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.
|
|
221
209
|
|
|
222
|
-
**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
|
|
210
|
+
**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.1.0/docs/2.0-MIGRATION.md), then use [Plugin Authoring](https://github.com/abhiyoheswaran1/projscan/blob/v3.1.0/docs/PLUGIN-AUTHORING.md), the [Plugin Gallery](https://github.com/abhiyoheswaran1/projscan/blob/v3.1.0/docs/PLUGIN-GALLERY.md), and the [manifest schema](https://github.com/abhiyoheswaran1/projscan/blob/v3.1.0/docs/plugin.schema.json) as the stable contract.
|
|
223
211
|
|
|
224
212
|
```bash
|
|
225
213
|
projscan plugin list
|
|
@@ -228,9 +216,9 @@ PROJSCAN_PLUGINS_PREVIEW=1 projscan doctor --reporter team-radar
|
|
|
228
216
|
PROJSCAN_PLUGINS_PREVIEW=1 projscan ci --reporter team-radar --min-score 80
|
|
229
217
|
```
|
|
230
218
|
|
|
231
|
-
<img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v3.0
|
|
219
|
+
<img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v3.1.0/docs/projscan-reporter-plugin.gif" alt="projscan local reporter plugin rendering a team health report" width="700">
|
|
232
220
|
|
|
233
|
-
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
|
|
221
|
+
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.1.0/docs/PLUGIN-AUTHORING.md) for manifest shape, `render(context)`, validation, and the trust model.
|
|
234
222
|
|
|
235
223
|
### Options
|
|
236
224
|
|
|
@@ -238,6 +226,9 @@ Reporter plugins are intentionally CLI-only. MCP tools keep returning structured
|
|
|
238
226
|
|------|-------------|
|
|
239
227
|
| `--format <type>` | Output format: console, json, markdown, sarif, html (command-dependent) |
|
|
240
228
|
| `--config <path>` | Path to a `.projscanrc` config file |
|
|
229
|
+
| `--include-ignored` | Explicitly include files hidden by Git ignore rules |
|
|
230
|
+
| `--scan-env-values` | Explicitly read `.env*` contents during secret checks |
|
|
231
|
+
| `--offline` | Block projscan network-capable features for this run |
|
|
241
232
|
| `--changed-only` | Scope to files changed vs base ref (ci/analyze/doctor) |
|
|
242
233
|
| `--base-ref <ref>` | Git base ref for `--changed-only` (default: origin/main) |
|
|
243
234
|
| `--reporter <name>` | Render `doctor`, `analyze`, or `ci` with a local reporter plugin |
|
|
@@ -361,10 +352,10 @@ projscan reads your source code so it can be useful; it does not send your sourc
|
|
|
361
352
|
|
|
362
353
|
### What projscan does NOT do
|
|
363
354
|
|
|
364
|
-
- **Send your source code off-machine.**
|
|
355
|
+
- **Send your source code off-machine.** File contents stay local; AST analysis runs in-process. The only projscan-owned network path is explicit opt-in telemetry, and those events are anonymous product-health buckets, not code or scan results.
|
|
365
356
|
- **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.
|
|
366
357
|
- **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.
|
|
367
|
-
- **Phone home
|
|
358
|
+
- **Phone home silently.** Telemetry is off by default. If you explicitly opt in with `projscan telemetry enable` or the interactive `projscan init team` prompt, projscan sends only anonymous product-health events; it never sends source code, file paths, repo names, branch names, package names, usernames, raw findings, or secrets. See [TELEMETRY.md](TELEMETRY.md).
|
|
368
359
|
- **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.
|
|
369
360
|
|
|
370
361
|
### What projscan DOES do, and what it costs
|
|
@@ -375,6 +366,7 @@ projscan reads your source code so it can be useful; it does not send your sourc
|
|
|
375
366
|
| 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 |
|
|
376
367
|
| Spawn `npm audit` | `audit` only | yes — by `npm`, not by projscan | runs against your local lockfile |
|
|
377
368
|
| Scan supply-chain IOCs | `doctor`, `preflight`, release validation | no | checks manifests, lockfiles, hidden editor hooks, and suspicious install-time payloads against bundled indicators |
|
|
369
|
+
| Anonymous telemetry | only after `projscan telemetry enable` or accepting the `projscan init team` prompt | yes — projscan-owned, default off | sends product-health buckets only; see [TELEMETRY.md](TELEMETRY.md) |
|
|
378
370
|
| Load local plugins | only with `PROJSCAN_PLUGINS_PREVIEW=1` | no | imports local JS modules declared in `.projscan-plugins/`; only enable plugins you trust |
|
|
379
371
|
| Load wasm grammars | first parse of a non-JS file | no | served from `dist/grammars/` inside the package; no fetch |
|
|
380
372
|
| 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 |
|
|
@@ -391,7 +383,7 @@ If you read projscan's [Socket report](https://socket.dev/npm/package/projscan),
|
|
|
391
383
|
### Audit it yourself
|
|
392
384
|
|
|
393
385
|
- **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.
|
|
394
|
-
- **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
|
|
386
|
+
- **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.1.0/docs/STABILITY.md).
|
|
395
387
|
- **Run it offline:** `npm install -g projscan` followed by anything except `audit` and `--mode semantic` works without network.
|
|
396
388
|
- **Drop privilege further:** in CI, run projscan in a sandbox that disallows network egress; everything except `audit` will pass.
|
|
397
389
|
|
|
@@ -442,7 +434,7 @@ projscan ci --changed-only # Gate only on this PR's diff
|
|
|
442
434
|
projscan ci --format sarif > projscan.sarif # SARIF for Code Scanning
|
|
443
435
|
```
|
|
444
436
|
|
|
445
|
-
<img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v3.0
|
|
437
|
+
<img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v3.1.0/docs/npx%20projscan%20ci%20--min-score%2070.gif" alt="npx projscan ci --min-score 70" width="700">
|
|
446
438
|
|
|
447
439
|
### GitHub Action (recommended)
|
|
448
440
|
|
|
@@ -490,6 +482,11 @@ Drop a `.projscanrc.json` at your repo root to set defaults - CLI flags always w
|
|
|
490
482
|
"minScore": 80,
|
|
491
483
|
"baseRef": "origin/main",
|
|
492
484
|
"ignore": ["**/fixtures/**", "**/generated/**"],
|
|
485
|
+
"scan": {
|
|
486
|
+
"includeIgnored": false,
|
|
487
|
+
"scanEnvValues": false,
|
|
488
|
+
"offline": false
|
|
489
|
+
},
|
|
493
490
|
"disableRules": ["missing-editorconfig", "large-*"],
|
|
494
491
|
"severityOverrides": {
|
|
495
492
|
"missing-prettier": "info"
|
|
@@ -506,12 +503,15 @@ Fields:
|
|
|
506
503
|
- `minScore` - default `ci` threshold (0–100)
|
|
507
504
|
- `baseRef` - default base ref for `--changed-only`
|
|
508
505
|
- `ignore` - extra glob patterns added to the built-in ignore list
|
|
506
|
+
- `scan.includeIgnored` - opt into scanning files hidden by Git ignore rules
|
|
507
|
+
- `scan.scanEnvValues` - opt into reading `.env*` contents during secret checks
|
|
508
|
+
- `scan.offline` - block projscan network-capable features by default
|
|
509
509
|
- `disableRules` - silence rules by id; supports wildcard `prefix-*`
|
|
510
510
|
- `severityOverrides` - remap a rule's severity (`info` / `warning` / `error`)
|
|
511
511
|
- `hotspots.limit` / `hotspots.since` - defaults for the `hotspots` command
|
|
512
512
|
- `monorepo.importPolicy` - cross-package import allow/deny rules in monorepos *(0.14+)*
|
|
513
513
|
|
|
514
|
-
See [`docs/GUIDE.md` → Configuration](https://github.com/abhiyoheswaran1/projscan/blob/v3.0
|
|
514
|
+
See [`docs/GUIDE.md` → Configuration](https://github.com/abhiyoheswaran1/projscan/blob/v3.1.0/docs/GUIDE.md#configuration-projscanrc) for the full reference (field types, validation behavior, embedding config in `package.json`, monorepo `importPolicy` semantics).
|
|
515
515
|
|
|
516
516
|
## Tracking Health Over Time
|
|
517
517
|
|
|
@@ -524,7 +524,7 @@ projscan diff # Compare against baseline
|
|
|
524
524
|
projscan diff --format markdown # Markdown diff for PRs
|
|
525
525
|
```
|
|
526
526
|
|
|
527
|
-
<img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v3.0
|
|
527
|
+
<img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v3.1.0/docs/npx%20projscan%20diff%20--save-baseline.gif" alt="npx projscan diff --save-baseline" width="700">
|
|
528
528
|
|
|
529
529
|
## Hotspots - Where to Fix First
|
|
530
530
|
|
|
@@ -613,7 +613,7 @@ Coverage is also automatically joined into `projscan hotspots` when one of those
|
|
|
613
613
|
|
|
614
614
|
**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.
|
|
615
615
|
|
|
616
|
-
<img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v3.0
|
|
616
|
+
<img src="https://raw.githubusercontent.com/abhiyoheswaran1/projscan/v3.1.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">
|
|
617
617
|
|
|
618
618
|
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.
|
|
619
619
|
|
|
@@ -810,7 +810,7 @@ Capability is advertised under `experimental.fileChanged` on `initialize` so cli
|
|
|
810
810
|
- **`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`.
|
|
811
811
|
- **`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.2, review surfaces hardened `newDataflowRisks`, compact `graphEvidence`, and graph-readiness gates for safer handoff.
|
|
812
812
|
|
|
813
|
-
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
|
|
813
|
+
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.1.0/docs/PLUGIN-AUTHORING.md).
|
|
814
814
|
|
|
815
815
|
### Context-window budgeting
|
|
816
816
|
|
|
@@ -887,10 +887,11 @@ Contributions are welcome. Please read [CONTRIBUTING.md](CONTRIBUTING.md) before
|
|
|
887
887
|
- Disclaimer: [DISCLAIMER.md](DISCLAIMER.md)
|
|
888
888
|
- Security policy: [SECURITY.md](SECURITY.md)
|
|
889
889
|
- Privacy notice: [PRIVACY.md](PRIVACY.md)
|
|
890
|
+
- Telemetry policy: [TELEMETRY.md](TELEMETRY.md)
|
|
890
891
|
- Trademark and brand policy: [TRADEMARKS.md](TRADEMARKS.md)
|
|
891
892
|
- Third-party notices: [THIRD-PARTY-NOTICES.md](THIRD-PARTY-NOTICES.md)
|
|
892
893
|
|
|
893
|
-
projscan is free and open source. The CLI and MCP server are local-first and do not upload source code
|
|
894
|
+
projscan is free and open source. The CLI and MCP server are local-first and do not upload source code or scan results to a projscan service. Anonymous product telemetry is default-off and only runs after explicit opt-in.
|
|
894
895
|
|
|
895
896
|
<p align="center">
|
|
896
897
|
<a href="https://www.baseframelabs.com" target="_blank" rel="noopener" title="Part of Baseframe Labs">
|
package/TELEMETRY.md
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# projscan telemetry
|
|
2
|
+
|
|
3
|
+
projscan telemetry is **off by default**. The CLI and MCP server do not send usage data unless a user explicitly opts in with `projscan telemetry enable` or accepts the prompt shown by `projscan init team` in an interactive terminal.
|
|
4
|
+
|
|
5
|
+
## Controls
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
projscan telemetry status
|
|
9
|
+
projscan telemetry explain
|
|
10
|
+
projscan telemetry enable
|
|
11
|
+
projscan telemetry disable
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
`projscan telemetry disable` turns telemetry off, clears the local queue, and removes the anonymous id.
|
|
15
|
+
|
|
16
|
+
## What is collected when enabled
|
|
17
|
+
|
|
18
|
+
Only anonymous product-health events are collected:
|
|
19
|
+
|
|
20
|
+
- command category and command name, such as `doctor`, `review`, `preflight`, or `dogfood`
|
|
21
|
+
- success or failure
|
|
22
|
+
- duration bucket, not exact command timing
|
|
23
|
+
- projscan version
|
|
24
|
+
- Node major version and operating-system platform
|
|
25
|
+
- whether CI, MCP setup, GitHub PR automation, or team bootstrap appears configured
|
|
26
|
+
- repeat-use buckets, such as run-count and active-day ranges
|
|
27
|
+
- optional feedback buckets from `projscan feedback add`, such as minutes-saved range, useful yes/no, prevented-bad-edit yes/no, and whether a false positive was reported
|
|
28
|
+
|
|
29
|
+
## What is never collected
|
|
30
|
+
|
|
31
|
+
projscan telemetry does **not** collect:
|
|
32
|
+
|
|
33
|
+
- source code
|
|
34
|
+
- file paths
|
|
35
|
+
- repository names
|
|
36
|
+
- branch names
|
|
37
|
+
- package names
|
|
38
|
+
- usernames or email addresses
|
|
39
|
+
- raw findings or scan output
|
|
40
|
+
- secrets or environment variable values
|
|
41
|
+
|
|
42
|
+
The implementation builds events from a fixed allowlist. It does not serialize scan reports, command arguments, file lists, dependency names, or analyzer findings.
|
|
43
|
+
|
|
44
|
+
## Storage and sending
|
|
45
|
+
|
|
46
|
+
Opt-in state is stored in the user config directory, or in `PROJSCAN_TELEMETRY_HOME` when set. Events are queued locally as JSONL and sent best-effort to:
|
|
47
|
+
|
|
48
|
+
```text
|
|
49
|
+
https://www.baseframelabs.com/api/projscan/telemetry
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
The endpoint can be overridden with `PROJSCAN_TELEMETRY_ENDPOINT`. Set `PROJSCAN_TELEMETRY_DISABLED=1` to force telemetry off in CI or managed environments. Set `PROJSCAN_TELEMETRY_NO_NETWORK=1` to keep enabled telemetry queued locally without sending network requests. Set `PROJSCAN_OFFLINE=1` or pass `--offline` to skip telemetry recording and sending for the run as part of projscan's broader no-network guard.
|
|
53
|
+
|
|
54
|
+
## Endpoint payload
|
|
55
|
+
|
|
56
|
+
The client posts JSON with this shape:
|
|
57
|
+
|
|
58
|
+
```json
|
|
59
|
+
{
|
|
60
|
+
"schemaVersion": 1,
|
|
61
|
+
"events": [
|
|
62
|
+
{
|
|
63
|
+
"schemaVersion": 1,
|
|
64
|
+
"eventId": "evt_<random-uuid>",
|
|
65
|
+
"eventType": "command_run",
|
|
66
|
+
"anonymousId": "psn_<random-uuid>",
|
|
67
|
+
"occurredAt": "2026-06-01T00:00:00.000Z",
|
|
68
|
+
"commandCategory": "doctor",
|
|
69
|
+
"commandName": "doctor",
|
|
70
|
+
"status": "success",
|
|
71
|
+
"durationBucket": "1-5s",
|
|
72
|
+
"version": "3.0.9",
|
|
73
|
+
"nodeMajor": 22,
|
|
74
|
+
"platform": "darwin",
|
|
75
|
+
"ci": false,
|
|
76
|
+
"setup": {
|
|
77
|
+
"githubActionConfigured": false,
|
|
78
|
+
"mcpConfigured": false,
|
|
79
|
+
"teamInitConfigured": false
|
|
80
|
+
},
|
|
81
|
+
"repeatUse": {
|
|
82
|
+
"runCountBucket": "2-5",
|
|
83
|
+
"activeDaysBucket": "1"
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
]
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Feedback events use `eventType: "feedback_outcome"` and add a `feedback` object containing only buckets or booleans.
|
|
91
|
+
|
|
92
|
+
## Why this exists
|
|
93
|
+
|
|
94
|
+
Public download counts and stars do not show whether projscan actually helps engineers. Opt-in telemetry answers product-health questions such as whether teams finish setup, connect MCP, generate PR evidence, keep using projscan on later PRs, and report false positives. Outcome value still comes from explicit reviewer feedback:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
projscan feedback add --minutes-saved 12 --prevented-bad-edit true --false-positive-rule owner:vague
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Telemetry can show repeat use. Feedback explains whether that use was valuable.
|
|
@@ -1,2 +1,5 @@
|
|
|
1
1
|
import type { FileEntry, Issue } from '../types.js';
|
|
2
|
-
export
|
|
2
|
+
export interface SecurityCheckOptions {
|
|
3
|
+
scanEnvValues?: boolean;
|
|
4
|
+
}
|
|
5
|
+
export declare function check(rootPath: string, files: FileEntry[], options?: SecurityCheckOptions): Promise<Issue[]>;
|
|
@@ -23,7 +23,10 @@ const SECRET_PATTERNS = [
|
|
|
23
23
|
pattern: /(?:password|secret|api_key|apikey|token|auth)\s*[=:]\s*['"][^'"]{8,}['"]/i,
|
|
24
24
|
},
|
|
25
25
|
];
|
|
26
|
-
|
|
26
|
+
function isEnvLikeFile(relativePath) {
|
|
27
|
+
return path.basename(relativePath).startsWith('.env');
|
|
28
|
+
}
|
|
29
|
+
export async function check(rootPath, files, options = {}) {
|
|
27
30
|
const issues = [];
|
|
28
31
|
// Detection 1: Sensitive .env files
|
|
29
32
|
for (const file of files) {
|
|
@@ -63,6 +66,7 @@ export async function check(rootPath, files) {
|
|
|
63
66
|
}
|
|
64
67
|
// Detection 3: Hardcoded secrets in file contents
|
|
65
68
|
const filesToScan = files.filter((f) => f.sizeBytes <= MAX_FILE_SIZE &&
|
|
69
|
+
(options.scanEnvValues === true || !isEnvLikeFile(f.relativePath)) &&
|
|
66
70
|
(SCANNABLE_EXTENSIONS.has(f.extension) ||
|
|
67
71
|
path.basename(f.relativePath).startsWith('.env')));
|
|
68
72
|
// 1.9+ — was Promise.all unbounded; on a 50K-file repo that opens
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"securityCheck.js","sourceRoot":"","sources":["../../src/analyzers/securityCheck.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,2BAA2B,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAG1F,MAAM,gBAAgB,GAAG,gBAAgB,CAAC;AAC1C,MAAM,iBAAiB,GAAG,CAAC,UAAU,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;AAE/D,MAAM,iBAAiB,GAAG,CAAC,QAAQ,EAAE,YAAY,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC;AACzE,MAAM,sBAAsB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAEhE,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAC;IACnC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC5C,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM;IAC3C,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM;IACzC,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,OAAO;IAC9C,MAAM,EAAE,MAAM;CACf,CAAC,CAAC;AAEH,MAAM,aAAa,GAAG,GAAG,GAAG,IAAI,CAAC,CAAC,SAAS;AAE3C,MAAM,eAAe,GAAwC;IAC3D,EAAE,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,kBAAkB,EAAE;IACvD,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,0BAA0B,EAAE;IAC7D,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,0BAA0B,EAAE;IAC5D,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,+CAA+C,EAAE;IACjF;QACE,IAAI,EAAE,gBAAgB;QACtB,OAAO,EAAE,2EAA2E;KACrF;CACF,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,QAAgB,EAAE,KAAkB;
|
|
1
|
+
{"version":3,"file":"securityCheck.js","sourceRoot":"","sources":["../../src/analyzers/securityCheck.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/_shared.js
CHANGED
|
@@ -8,6 +8,8 @@ import { explainFile as explainProjectFile } from '../core/fileInspector.js';
|
|
|
8
8
|
import { setLogLevel } from '../utils/logger.js';
|
|
9
9
|
import { showBanner, showCompactBanner } from '../utils/banner.js';
|
|
10
10
|
import { loadConfig } from '../utils/config.js';
|
|
11
|
+
import { recordCommandTelemetry } from '../core/telemetry.js';
|
|
12
|
+
import { enableOfflineMode } from '../core/privacy.js';
|
|
11
13
|
import { getChangedFiles } from '../utils/changedFiles.js';
|
|
12
14
|
import { OUTPUT_FORMATS, formatList, getCommandFormatSupport } from '../utils/formatSupport.js';
|
|
13
15
|
import { resolveReporterPlugin, renderReporterPlugin, } from '../core/plugins.js';
|
|
@@ -20,8 +22,44 @@ program
|
|
|
20
22
|
.version(pkg.version)
|
|
21
23
|
.option('--format <type>', `output format: ${formatList()} (command-dependent)`, 'console')
|
|
22
24
|
.option('--config <path>', 'path to .projscanrc config file')
|
|
25
|
+
.option('--include-ignored', 'explicitly include files ignored by .gitignore')
|
|
26
|
+
.option('--scan-env-values', 'explicitly read .env* file contents during secret checks')
|
|
27
|
+
.option('--offline', 'block all projscan network-capable features for this run')
|
|
23
28
|
.option('--verbose', 'enable verbose output')
|
|
24
29
|
.option('--quiet', 'suppress non-essential output');
|
|
30
|
+
let activeTelemetryRun = null;
|
|
31
|
+
program.hook('preAction', (_thisCommand, actionCommand) => {
|
|
32
|
+
const opts = program.opts();
|
|
33
|
+
if (opts.offline)
|
|
34
|
+
enableOfflineMode();
|
|
35
|
+
if (opts.includeIgnored)
|
|
36
|
+
process.env.PROJSCAN_INCLUDE_IGNORED = '1';
|
|
37
|
+
if (opts.scanEnvValues)
|
|
38
|
+
process.env.PROJSCAN_SCAN_ENV_VALUES = '1';
|
|
39
|
+
activeTelemetryRun = { commandName: commandPath(actionCommand), startedAt: Date.now() };
|
|
40
|
+
});
|
|
41
|
+
program.hook('postAction', async (_thisCommand, actionCommand) => {
|
|
42
|
+
const run = activeTelemetryRun ?? { commandName: commandPath(actionCommand), startedAt: Date.now() };
|
|
43
|
+
activeTelemetryRun = null;
|
|
44
|
+
await recordCommandTelemetry({
|
|
45
|
+
commandName: run.commandName,
|
|
46
|
+
status: 'success',
|
|
47
|
+
durationMs: Date.now() - run.startedAt,
|
|
48
|
+
rootPath: getRootPath(),
|
|
49
|
+
version: pkg.version,
|
|
50
|
+
}).catch(() => undefined);
|
|
51
|
+
});
|
|
52
|
+
function commandPath(actionCommand) {
|
|
53
|
+
const parts = [];
|
|
54
|
+
let current = actionCommand;
|
|
55
|
+
while (current && current.name() !== 'projscan') {
|
|
56
|
+
const name = current.name();
|
|
57
|
+
if (name)
|
|
58
|
+
parts.unshift(name);
|
|
59
|
+
current = current.parent ?? null;
|
|
60
|
+
}
|
|
61
|
+
return parts.join(' ') || actionCommand.name() || 'unknown';
|
|
62
|
+
}
|
|
25
63
|
export function getFormat() {
|
|
26
64
|
const opts = program.opts();
|
|
27
65
|
const f = opts.format;
|
|
@@ -52,6 +90,12 @@ export async function loadProjectConfig() {
|
|
|
52
90
|
const explicit = typeof opts.config === 'string' ? opts.config : undefined;
|
|
53
91
|
try {
|
|
54
92
|
const { config, source } = await loadConfig(getRootPath(), explicit);
|
|
93
|
+
if (config.scan?.offline)
|
|
94
|
+
enableOfflineMode();
|
|
95
|
+
if (config.scan?.includeIgnored)
|
|
96
|
+
process.env.PROJSCAN_INCLUDE_IGNORED = '1';
|
|
97
|
+
if (config.scan?.scanEnvValues)
|
|
98
|
+
process.env.PROJSCAN_SCAN_ENV_VALUES = '1';
|
|
55
99
|
if (source && !opts.quiet && getFormat() === 'console') {
|
|
56
100
|
console.error(chalk.dim(` [config: ${path.relative(getRootPath(), source) || source}]`));
|
|
57
101
|
}
|