fallow 2.98.0 → 2.100.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/README.md +17 -0
- package/package.json +9 -9
- package/schema.json +18 -2
- package/skills/fallow/SKILL.md +5 -4
- package/skills/fallow/references/cli-reference.md +61 -11
- package/types/output-contract.d.ts +317 -63
package/README.md
CHANGED
|
@@ -88,6 +88,23 @@ Fallow gives AI agents structured repo truth instead of forcing them to infer ev
|
|
|
88
88
|
|
|
89
89
|
Every issue in `--format json` carries a machine-actionable `actions` array with an `auto_fixable` flag so agents can self-correct.
|
|
90
90
|
|
|
91
|
+
### MCP server
|
|
92
|
+
|
|
93
|
+
Agents that speak MCP can launch the bundled `fallow-mcp` server. Installed as a devDependency, the binary lives in `node_modules/.bin/` and is not on your `PATH`, so launch it through your package manager's runner:
|
|
94
|
+
|
|
95
|
+
```json
|
|
96
|
+
{
|
|
97
|
+
"mcpServers": {
|
|
98
|
+
"fallow": {
|
|
99
|
+
"command": "npx",
|
|
100
|
+
"args": ["fallow-mcp"]
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Swap `npx` for `pnpm exec` / `yarn` / `bunx` to match your package manager. If `fallow-mcp` is installed globally (on your `PATH`), `"command": "fallow-mcp"` works directly. See the [MCP integration guide](https://docs.fallow.tools/integrations/mcp).
|
|
107
|
+
|
|
91
108
|
## Framework support
|
|
92
109
|
|
|
93
110
|
122 built-in plugins covering Next.js, Nuxt, Remix, Qwik, SvelteKit, Gatsby, Astro, Angular, NestJS, AdonisJS, Ember, Expo Router, Vite, Webpack, Vitest, Jest, Playwright, Cypress, Storybook, ESLint, TypeScript, Tailwind, UnoCSS, Prisma, Drizzle, Convex, Turborepo, Hardhat, and many more. Auto-detected from your `package.json`.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fallow",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.100.0",
|
|
4
4
|
"description": "Deterministic codebase intelligence for TypeScript and JavaScript. Quality, risk, architecture, dependencies, duplication, and safe cleanup evidence for humans, CI, and agents. Optional runtime intelligence layer (Fallow Runtime) adds production execution evidence. Rust-native, sub-second, zero-config framework support.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -83,13 +83,13 @@
|
|
|
83
83
|
"@tanstack/intent": "0.0.42"
|
|
84
84
|
},
|
|
85
85
|
"optionalDependencies": {
|
|
86
|
-
"@fallow-cli/darwin-arm64": "2.
|
|
87
|
-
"@fallow-cli/darwin-x64": "2.
|
|
88
|
-
"@fallow-cli/linux-x64-gnu": "2.
|
|
89
|
-
"@fallow-cli/linux-arm64-gnu": "2.
|
|
90
|
-
"@fallow-cli/linux-x64-musl": "2.
|
|
91
|
-
"@fallow-cli/linux-arm64-musl": "2.
|
|
92
|
-
"@fallow-cli/win32-arm64-msvc": "2.
|
|
93
|
-
"@fallow-cli/win32-x64-msvc": "2.
|
|
86
|
+
"@fallow-cli/darwin-arm64": "2.100.0",
|
|
87
|
+
"@fallow-cli/darwin-x64": "2.100.0",
|
|
88
|
+
"@fallow-cli/linux-x64-gnu": "2.100.0",
|
|
89
|
+
"@fallow-cli/linux-arm64-gnu": "2.100.0",
|
|
90
|
+
"@fallow-cli/linux-x64-musl": "2.100.0",
|
|
91
|
+
"@fallow-cli/linux-arm64-musl": "2.100.0",
|
|
92
|
+
"@fallow-cli/win32-arm64-msvc": "2.100.0",
|
|
93
|
+
"@fallow-cli/win32-x64-msvc": "2.100.0"
|
|
94
94
|
}
|
|
95
95
|
}
|
package/schema.json
CHANGED
|
@@ -178,6 +178,7 @@
|
|
|
178
178
|
"coverage-gaps": "off",
|
|
179
179
|
"feature-flags": "off",
|
|
180
180
|
"stale-suppressions": "warn",
|
|
181
|
+
"require-suppression-reason": "off",
|
|
181
182
|
"unused-catalog-entries": "warn",
|
|
182
183
|
"empty-catalog-groups": "warn",
|
|
183
184
|
"unresolved-catalog-references": "error",
|
|
@@ -234,7 +235,7 @@
|
|
|
234
235
|
"default": []
|
|
235
236
|
},
|
|
236
237
|
"rulePacks": {
|
|
237
|
-
"description": "Paths to declarative rule-pack files (JSON or JSONC), relative to the\nproject root. Each pack declares `banned-call
|
|
238
|
+
"description": "Paths to declarative rule-pack files (JSON or JSONC), relative to the\nproject root. Each pack declares `banned-call`, `banned-import`, or\n`banned-effect` rules that report as `policy-violation` findings. Packs\nare pure data: no project code is executed. Invalid or missing packs\nfail config load.",
|
|
238
239
|
"type": "array",
|
|
239
240
|
"items": {
|
|
240
241
|
"type": "string"
|
|
@@ -1046,7 +1047,7 @@
|
|
|
1046
1047
|
"default": "error"
|
|
1047
1048
|
},
|
|
1048
1049
|
"unused-component-props": {
|
|
1049
|
-
"description": "Vue `<script setup>` `defineProps
|
|
1050
|
+
"description": "Vue `<script setup>` `defineProps`, Svelte 5 `$props()`, or React\ndeclared prop referenced nowhere inside its own component. The\nsingle-component dead-input direction. Defaults to `warn`, not `error`: a\nprop can be part of a deliberately-stable public component API, so\nanalyzer confidence is lower; warn encodes that without failing CI.",
|
|
1050
1051
|
"$ref": "#/$defs/Severity",
|
|
1051
1052
|
"default": "error"
|
|
1052
1053
|
},
|
|
@@ -1139,6 +1140,11 @@
|
|
|
1139
1140
|
"$ref": "#/$defs/Severity",
|
|
1140
1141
|
"default": "warn"
|
|
1141
1142
|
},
|
|
1143
|
+
"require-suppression-reason": {
|
|
1144
|
+
"description": "Opt-in suppression hygiene rule: when enabled, every `fallow-ignore-*`\ncomment and `@expected-unused` tag must carry a `-- <reason>` suffix.",
|
|
1145
|
+
"$ref": "#/$defs/Severity",
|
|
1146
|
+
"default": "off"
|
|
1147
|
+
},
|
|
1142
1148
|
"unused-catalog-entries": {
|
|
1143
1149
|
"$ref": "#/$defs/Severity",
|
|
1144
1150
|
"default": "warn"
|
|
@@ -1939,6 +1945,16 @@
|
|
|
1939
1945
|
}
|
|
1940
1946
|
]
|
|
1941
1947
|
},
|
|
1948
|
+
"require-suppression-reason": {
|
|
1949
|
+
"anyOf": [
|
|
1950
|
+
{
|
|
1951
|
+
"$ref": "#/$defs/Severity"
|
|
1952
|
+
},
|
|
1953
|
+
{
|
|
1954
|
+
"type": "null"
|
|
1955
|
+
}
|
|
1956
|
+
]
|
|
1957
|
+
},
|
|
1942
1958
|
"unused-catalog-entries": {
|
|
1943
1959
|
"anyOf": [
|
|
1944
1960
|
{
|
package/skills/fallow/SKILL.md
CHANGED
|
@@ -95,6 +95,7 @@ Route by intent before reaching for the big analysis commands. Same matrix as `f
|
|
|
95
95
|
| `fallow` | Run full codebase analysis: cleanup + duplication + health (default) | `--only`, `--skip`, `--production`, `--production-dead-code`, `--production-health`, `--production-dupes`, `--ci`, `--fail-on-issues`, `--group-by`, `--summary`, `--fail-on-regression`, `--tolerance`, `--regression-baseline`, `--save-regression-baseline`, `--score`, `--trend`, `--save-snapshot`, `--include-entry-exports` |
|
|
96
96
|
| `dead-code` | Dead code analysis (`check` is an alias) | `--unused-exports`, `--changed-since`, `--changed-workspaces`, `--production`, `--file`, `--include-entry-exports`, `--stale-suppressions`, `--ci`, `--group-by`, `--summary`, `--fail-on-regression`, `--tolerance`, `--regression-baseline`, `--save-regression-baseline` |
|
|
97
97
|
| `watch` | Watch for changes and re-run analysis | `--no-clear` |
|
|
98
|
+
| `inspect` | Compose one evidence bundle for a file or exported symbol | `--file <path>`, `--symbol <file>:<export>` |
|
|
98
99
|
| `fix` | Auto-remove unused exports/deps | `--dry-run`, `--yes` (required in non-TTY) |
|
|
99
100
|
| `init` | Generate config file, AGENTS.md agent guide, or pre-commit hook | `--toml`, `--agents`, `--hooks`, `--branch` |
|
|
100
101
|
| `hooks` | Inspect, install, or remove fallow-managed Git and agent hooks | `status`, `install --target git`, `install --target agent`, `uninstall --target git`, `uninstall --target agent` |
|
|
@@ -150,7 +151,7 @@ Run `fallow <command> --help` for the full flag list per command (see also refer
|
|
|
150
151
|
| `boundary-violation` | `--boundary-violations` | - | `// fallow-ignore-next-line boundary-violation` | Imports crossing architecture zone boundaries. Presets: `layered`, `hexagonal`, `feature-sliced`, `bulletproof`; `autoDiscover` can create one zone per feature directory; per-rule `allowTypeOnly: [zones]` admits `import type` / `export type` crossings while still blocking value imports. Optional sections: `boundaries.coverage.requireAllFiles` reports unzoned source files (`allowUnmatched` globs exempt intentional ones), and `boundaries.calls.forbidden` bans callee patterns per zone (segment-aware and import-resolved, so `child_process.*` covers `node:child_process` named/namespace/default imports; direct callees only, zoned files only). The whole family shares the `boundary-violation` rule and suppression token (`boundary-call-violation` and `boundary-call-violations` accepted as aliases); start the rule at `warn` for a staged rollout |
|
|
151
152
|
| `boundary-coverage` | - | - | `// fallow-ignore-file boundary-violation` | Source file matches no configured architecture boundary zone; Requires boundaries.coverage.requireAllFiles |
|
|
152
153
|
| `boundary-call-violation` | - | - | `// fallow-ignore-next-line boundary-call-violation` | Zoned file calls a callee its zone forbids; Requires boundaries.calls.forbidden patterns |
|
|
153
|
-
| `policy-violation` | `--policy-violations` | - | `// fallow-ignore-next-line policy-violation` | Calls or
|
|
154
|
+
| `policy-violation` | `--policy-violations` | - | `// fallow-ignore-next-line policy-violation` | Calls, imports, or catalogue-derived effects banned by a declarative rule pack (`rulePacks` config key lists standalone JSON/JSONC files of `banned-call`, `banned-import`, and `banned-effect` rules; pure data, no project code executes). Findings identified as `<pack>/<rule-id>`. Default `warn` master; per-rule `severity` overrides per finding and the exit gate reads the effective severity. Invalid or missing packs fail config load with exit 2. `fallow rule-pack-schema` prints the pack JSON Schema. Use the scoped token to suppress one rule; bare `policy-violation` still covers every pack rule on the line or file. |
|
|
154
155
|
| `stale-suppression` | `--stale-suppressions` | - | - | `fallow-ignore` comments or `@expected-unused` JSDoc tags that no longer match any issue |
|
|
155
156
|
| `unused-catalog-entry` | `--unused-catalog-entries` | yes | - | `pnpm-workspace.yaml` entries no workspace package.json references via `catalog:` (default `warn`) |
|
|
156
157
|
| `empty-catalog-group` | `--empty-catalog-groups` | - | - | Named `catalogs.<name>:` groups in `pnpm-workspace.yaml` with no entries. Top-level `catalog:` placeholders are ignored. Default `warn`. |
|
|
@@ -172,8 +173,8 @@ Run `fallow <command> --help` for the full flag list per command (see also refer
|
|
|
172
173
|
| `prop-drilling` | - | - | `// fallow-ignore-next-line prop-drilling` | A React/Preact prop is forwarded unchanged through 3+ pass-through components to a distant consumer; Opt-in: set rules.prop-drilling to warn or error to enable. Defaults to off. |
|
|
173
174
|
| `thin-wrapper` | - | - | `// fallow-ignore-next-line thin-wrapper` | A React/Preact component whose whole body is a single spread-forwarded child render (a candidate for inlining); Opt-in: set rules.thin-wrapper to warn or error to enable. Defaults to off. |
|
|
174
175
|
| `duplicate-prop-shape` | - | - | `// fallow-ignore-next-line duplicate-prop-shape` | Three or more React/Preact components across two or more files declare an identical prop-name set (a missing shared Props type); Opt-in: set rules.duplicate-prop-shape to warn or error to enable. Defaults to off. |
|
|
175
|
-
| `route-collision` | - | - | - | Two or more Next.js App Router route files resolve to the same URL |
|
|
176
|
-
| `dynamic-segment-name-conflict` | - | - | - | Sibling Next.js dynamic route segments use different slug names at the same position |
|
|
176
|
+
| `route-collision` | - | - | `// fallow-ignore-file route-collision` | Two or more Next.js App Router route files resolve to the same URL |
|
|
177
|
+
| `dynamic-segment-name-conflict` | - | - | `// fallow-ignore-file dynamic-segment-name-conflict` | Sibling Next.js dynamic route segments use different slug names at the same position |
|
|
177
178
|
| `high-cyclomatic-complexity` | `--complexity` | - | `// fallow-ignore-next-line complexity` | Function has high cyclomatic complexity |
|
|
178
179
|
| `high-cognitive-complexity` | `--complexity` | - | `// fallow-ignore-next-line complexity` | Function has high cognitive complexity |
|
|
179
180
|
| `high-complexity` | `--complexity` | - | `// fallow-ignore-next-line complexity` | Function exceeds both complexity thresholds |
|
|
@@ -198,7 +199,7 @@ When using fallow via MCP (`fallow-mcp`), the following tools are available:
|
|
|
198
199
|
| Tool | Kind | License | Key params | Description |
|
|
199
200
|
|---|---|---|---|---|
|
|
200
201
|
| `code_execute` | composition | free | `code`, `timeout_ms`, `max_output_bytes` | Bounded read-only Code Mode for composing multiple fallow analysis calls in one JavaScript snippet. The snippet receives `{ fallow, root }`, returns JSON-serializable data, and can call read-only helpers such as `fallow.projectInfo`, `fallow.audit`, `fallow.checkHealth`, and `fallow.run(tool, params)` for the same allowlist. Mutating fix tools are not exposed. The sandbox has no filesystem, network, imports, `eval`, `Function`, `process`, `require`, `Deno`, `Bun`, or shell access. Params: `code`, optional `root`, `timeout_ms` (capped at 30000), and `max_output_bytes` (capped at 4000000). |
|
|
201
|
-
| `analyze` | analysis | free | `issue_types`, `production`, `workspace`, `baseline`, `group_by`, `file` | Full dead code analysis (unused files/exports/types/dependencies/members + circular dependencies + re-export cycles (barrel files that form a structural loop, silently breaking re-exports) + boundary violations + rule-pack policy violations (banned calls and
|
|
202
|
+
| `analyze` | analysis | free | `issue_types`, `production`, `workspace`, `baseline`, `group_by`, `file` | Full dead code analysis (unused files/exports/types/dependencies/members + circular dependencies + re-export cycles (barrel files that form a structural loop, silently breaking re-exports) + boundary violations + rule-pack policy violations (banned calls, imports, and catalogue-derived effects declared via the `rulePacks` config key) + stale suppressions). Private type leaks are an opt-in API hygiene check via `issue_types: ["private-type-leaks"]`. Set `boundary_violations: true` as a convenience alias for `issue_types: ["boundary-violations"]`. Set `group_by` to `"owner"`, `"directory"`, `"package"`, or `"section"` to partition results. The `section` mode reads GitLab CODEOWNERS `[Section]` headers and emits `owners` metadata per group |
|
|
202
203
|
| `check_changed` | analysis | free | `since`, `baseline`, `fail_on_regression` | Incremental analysis of files changed since a git ref |
|
|
203
204
|
| `security_candidates` | analysis | free | `gate`, `surface`, `changed_since`, `paths` | Unverified local security candidates, not confirmed vulnerabilities (`fallow security --format json`). Read `security_findings[]` for category, CWE, severity, evidence, trace, optional `reachability`, blind-spot counters, and optional `unresolved_callee_diagnostics` samples for dynamic callee follow-up. `severity` is a review-priority tier, not a verified vulnerability verdict. Each finding also carries an agent-actionable `candidate` (`source_kind`/`sink`/`boundary`), where URL-category sinks may include `url_shape` (`fixed-origin-dynamic-path` or `dynamic-origin`), an optional `taint_flow` source-to-sink triple, and a stable `finding_id` (equal to the SARIF fingerprint) for cross-run correlation; there is no `impact` field (deciding exploitability is the agent's job). Set `surface: true` to include top-level `attack_surface[]` entries with defensive-boundary prompts for a verifier. Set `gate` to `new` for changed-line candidates or `newly-reachable` for candidates that became reachable from entry points; `newly-reachable` requires `changed_since`. `reachability.untrusted_source_trace` is module-level import context only and does not prove value flow; `reachability.taint_confidence` tiers each reachable candidate as `arg-level` (sink argument traces to a same-module source read, strong) or `module-level` (only the module is import-reachable from a source, weak), so tier from this field instead of the evidence text. Verify trace, reachability context, severity, and evidence before editing code. Supports `root`, `config`, `workspace`, `paths`, `changed_since`, `changed_workspaces`, `surface`, `gate`, `no_cache`, and `threads`; `paths` forwards repeated `fallow security --file` filters for finding anchors, trace hops, untrusted-source reachability trace hops, and unresolved-callee diagnostics. See <https://docs.fallow.tools/cli/security-agent-verification> for the verifier packet and verdict recipe. Inherits `FALLOW_DIFF_FILE` from the server environment for line-level diff scoping; raise `FALLOW_TIMEOUT_SECS` for large repos. |
|
|
204
205
|
| `inspect_target` | analysis | free | `target`, `production` | Compose one evidence bundle for a file or exported symbol. File targets use `target: { type: "file", file }`; symbol targets use `target: { type: "symbol", file, export_name }`. Returns `kind: "inspect_target"`, normalized target identity, `trace_file`, optional `trace_export`, file-scoped dead-code actions, duplication groups filtered to the file, complexity findings filtered to the file, and security candidates scoped to the file. Evidence sections carry `status` and `scope`; symbol targets warn when supporting evidence is file-scoped. Supports `root`, `config`, `production`, `workspace`, `no_cache`, and `threads`; `production` applies to trace, dead-code, and health evidence only. Raise `FALLOW_TIMEOUT_SECS` for large repos. |
|
|
@@ -16,6 +16,7 @@ Complete command and flag specifications for all fallow CLI commands.
|
|
|
16
16
|
- [`audit`: Changed-File Quality Gate](#audit-changed-file-quality-gate)
|
|
17
17
|
- [`flags`: Feature Flag Detection](#flags-feature-flag-detection)
|
|
18
18
|
- [`security`: Security Candidate Detection](#security-security-candidate-detection)
|
|
19
|
+
- [`inspect`: Target Evidence Bundle](#inspect-target-evidence-bundle)
|
|
19
20
|
- [`explain`: Rule Explanation](#explain-rule-explanation)
|
|
20
21
|
- [`schema`: CLI Introspection](#schema-cli-introspection)
|
|
21
22
|
- [`config-schema`: Config JSON Schema](#config-schema-config-json-schema)
|
|
@@ -77,7 +78,7 @@ Common global flags for this command: [`--format`](#global-flags), [`--quiet`](#
|
|
|
77
78
|
| `--circular-deps` | Circular dependencies |
|
|
78
79
|
| `--re-export-cycles` | Re-export cycles (`kind: multi-node` for barrel files re-exporting from each other in a loop, `kind: self-loop` for a barrel re-exporting from itself). File-scoped finding; chain propagation through the loop is a no-op so imports may silently come up empty. Distinct from `--circular-deps` (runtime cycles). |
|
|
79
80
|
| `--boundary-violations` | Boundary violations (imports crossing architecture zone boundaries, unzoned source files when `boundaries.coverage.requireAllFiles` is set, and forbidden calls from `boundaries.calls.forbidden`; suppression token `boundary-violation`, with `boundary-call-violation` and `boundary-call-violations` accepted as aliases for the whole family) |
|
|
80
|
-
| `--policy-violations` | Rule-pack policy violations (banned calls and
|
|
81
|
+
| `--policy-violations` | Rule-pack policy violations (banned calls, imports, and catalogue-derived effects declared via the `rulePacks` config key) |
|
|
81
82
|
| `--stale-suppressions` | Stale suppression comments or `@expected-unused` JSDoc tags |
|
|
82
83
|
| `--unused-catalog-entries` | Unused pnpm catalog entries |
|
|
83
84
|
| `--empty-catalog-groups` | Empty named pnpm catalog groups |
|
|
@@ -504,7 +505,7 @@ fallow health --format json --quiet --trend
|
|
|
504
505
|
{
|
|
505
506
|
"kind": "health",
|
|
506
507
|
"schema_version": 7,
|
|
507
|
-
"version": "2.
|
|
508
|
+
"version": "2.100.0",
|
|
508
509
|
"elapsed_ms": 32,
|
|
509
510
|
"summary": {
|
|
510
511
|
"files_analyzed": 482,
|
|
@@ -891,7 +892,7 @@ fallow audit \
|
|
|
891
892
|
{
|
|
892
893
|
"kind": "audit",
|
|
893
894
|
"schema_version": 7,
|
|
894
|
-
"version": "2.
|
|
895
|
+
"version": "2.100.0",
|
|
895
896
|
"command": "audit",
|
|
896
897
|
"verdict": "fail",
|
|
897
898
|
"changed_files_count": 12,
|
|
@@ -966,7 +967,7 @@ fallow flags --format json --quiet --workspace my-package
|
|
|
966
967
|
```json
|
|
967
968
|
{
|
|
968
969
|
"schema_version": 7,
|
|
969
|
-
"version": "2.
|
|
970
|
+
"version": "2.100.0",
|
|
970
971
|
"elapsed_ms": 116,
|
|
971
972
|
"feature_flags": [],
|
|
972
973
|
"total_flags": 0
|
|
@@ -1066,7 +1067,7 @@ fallow security --gate newly-reachable --changed-since origin/main
|
|
|
1066
1067
|
{
|
|
1067
1068
|
"kind": "security",
|
|
1068
1069
|
"schema_version": "4",
|
|
1069
|
-
"version": "2.
|
|
1070
|
+
"version": "2.100.0",
|
|
1070
1071
|
"elapsed_ms": 42,
|
|
1071
1072
|
"config": {
|
|
1072
1073
|
"rules": {
|
|
@@ -1095,7 +1096,7 @@ fallow security --gate newly-reachable --changed-since origin/main
|
|
|
1095
1096
|
{
|
|
1096
1097
|
"kind": "security",
|
|
1097
1098
|
"schema_version": "4",
|
|
1098
|
-
"version": "2.
|
|
1099
|
+
"version": "2.100.0",
|
|
1099
1100
|
"elapsed_ms": 42,
|
|
1100
1101
|
"config": {
|
|
1101
1102
|
"rules": {
|
|
@@ -1159,6 +1160,55 @@ Every finding also carries an agent-actionable `candidate { source_kind, sink, b
|
|
|
1159
1160
|
|
|
1160
1161
|
---
|
|
1161
1162
|
|
|
1163
|
+
## `inspect`: Target Evidence Bundle
|
|
1164
|
+
|
|
1165
|
+
Compose one evidence bundle before editing a file or exported symbol. This is the CLI equivalent of the MCP `inspect_target` tool.
|
|
1166
|
+
|
|
1167
|
+
### Usage
|
|
1168
|
+
|
|
1169
|
+
```bash
|
|
1170
|
+
fallow inspect --file src/api.ts --format json --quiet
|
|
1171
|
+
fallow inspect --symbol src/api.ts:fetchUser --format json --quiet
|
|
1172
|
+
```
|
|
1173
|
+
|
|
1174
|
+
### Target Flags
|
|
1175
|
+
|
|
1176
|
+
| Flag | Description |
|
|
1177
|
+
|------|-------------|
|
|
1178
|
+
| `--file <PATH>` | Inspect one project-relative file |
|
|
1179
|
+
| `--symbol <FILE:EXPORT>` | Inspect one exported symbol. Supporting dead-code, duplication, complexity, and security evidence is file-scoped in the first version |
|
|
1180
|
+
|
|
1181
|
+
Common global flags: `--format`, `--quiet`, `--root`, `--config`, `--workspace`, `--production`, `--no-cache`, `--threads`.
|
|
1182
|
+
|
|
1183
|
+
### JSON Output Structure
|
|
1184
|
+
|
|
1185
|
+
```json
|
|
1186
|
+
{
|
|
1187
|
+
"kind": "inspect_target",
|
|
1188
|
+
"target": { "type": "file", "file": "src/api.ts" },
|
|
1189
|
+
"identity": {
|
|
1190
|
+
"file": "src/api.ts",
|
|
1191
|
+
"is_reachable": true,
|
|
1192
|
+
"is_entry_point": false,
|
|
1193
|
+
"export_count": 3,
|
|
1194
|
+
"import_count": 2,
|
|
1195
|
+
"imported_by_count": 1
|
|
1196
|
+
},
|
|
1197
|
+
"evidence": {
|
|
1198
|
+
"trace_file": { "status": "ok", "scope": "file", "data": {} },
|
|
1199
|
+
"dead_code": { "status": "ok", "scope": "file", "data": {} },
|
|
1200
|
+
"duplication": { "status": "ok", "scope": "project_filtered_to_file", "data": {} },
|
|
1201
|
+
"complexity": { "status": "ok", "scope": "project_filtered_to_file", "data": {} },
|
|
1202
|
+
"security": { "status": "ok", "scope": "file", "data": {} }
|
|
1203
|
+
},
|
|
1204
|
+
"warnings": []
|
|
1205
|
+
}
|
|
1206
|
+
```
|
|
1207
|
+
|
|
1208
|
+
Each evidence section carries `status` and `scope`. Non-fatal child-analysis failures become section-level errors and warnings, so callers can still use the remaining evidence.
|
|
1209
|
+
|
|
1210
|
+
---
|
|
1211
|
+
|
|
1162
1212
|
## `explain`: Rule Explanation
|
|
1163
1213
|
|
|
1164
1214
|
Print rule rationale, examples, fix guidance, and docs URL for one issue type without running analysis.
|
|
@@ -1645,7 +1695,7 @@ Set `FALLOW_FORMAT=json` and `FALLOW_QUIET=1` in your agent environment to avoid
|
|
|
1645
1695
|
| `human` | Colored terminal output | Interactive use |
|
|
1646
1696
|
| `json` | Machine-readable JSON | Agent integration, CI pipelines |
|
|
1647
1697
|
| `sarif` | Static Analysis Results Interchange Format | GitHub Code Scanning, SARIF-compatible tools |
|
|
1648
|
-
| `compact` | Grep-friendly: `
|
|
1698
|
+
| `compact` | Grep-friendly: one issue per line. Dupes lines include `code-duplication:path:start-end:fingerprint=dup:<id>,...` | Quick filtering |
|
|
1649
1699
|
| `markdown` | Markdown tables | Documentation, PR comments |
|
|
1650
1700
|
| `codeclimate` / `gitlab-codequality` | CodeClimate JSON array | GitLab Code Quality, CodeClimate-compatible tools |
|
|
1651
1701
|
| `pr-comment-github` / `pr-comment-gitlab` | Sticky PR/MR comment markdown with HTML-comment marker for upsert | Posted by the action / template `comment.sh` scripts |
|
|
@@ -1712,7 +1762,7 @@ The HTTP layer mirrors the bash `gh_api_retry` / `curl_retry` helpers: `FALLOW_A
|
|
|
1712
1762
|
{
|
|
1713
1763
|
"kind": "dead-code",
|
|
1714
1764
|
"schema_version": 7,
|
|
1715
|
-
"version": "2.
|
|
1765
|
+
"version": "2.100.0",
|
|
1716
1766
|
"elapsed_ms": 45,
|
|
1717
1767
|
"total_issues": 12,
|
|
1718
1768
|
"entry_points": {
|
|
@@ -1872,7 +1922,7 @@ When `--baseline` is used in combined output, the JSON includes a `baseline_delt
|
|
|
1872
1922
|
{
|
|
1873
1923
|
"kind": "dupes",
|
|
1874
1924
|
"schema_version": 7,
|
|
1875
|
-
"version": "2.
|
|
1925
|
+
"version": "2.100.0",
|
|
1876
1926
|
"elapsed_ms": 82,
|
|
1877
1927
|
"total_clones": 15,
|
|
1878
1928
|
"total_lines_duplicated": 230,
|
|
@@ -1916,11 +1966,11 @@ When running `fallow` with no subcommand (all analyses), the JSON output combine
|
|
|
1916
1966
|
{
|
|
1917
1967
|
"kind": "combined",
|
|
1918
1968
|
"schema_version": 7,
|
|
1919
|
-
"version": "2.
|
|
1969
|
+
"version": "2.100.0",
|
|
1920
1970
|
"elapsed_ms": 159,
|
|
1921
1971
|
"check": {
|
|
1922
1972
|
"schema_version": 7,
|
|
1923
|
-
"version": "2.
|
|
1973
|
+
"version": "2.100.0",
|
|
1924
1974
|
"elapsed_ms": 45,
|
|
1925
1975
|
"total_issues": 12,
|
|
1926
1976
|
"unused_files": [],
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
|
-
* Schemas for the JSON output of fallow commands. Object-shaped envelopes covered by the `FallowOutput` contract carry a top-level `kind` discriminator (for example `dead-code`, `dead-code-grouped`, `health`, `dupes`, `combined`, `audit`, `explain`, `impact`, `security`, `coverage-setup`, `coverage-analyze`, `list-boundaries`, `review-envelope`, and `review-reconcile`). Consumers should branch on `kind` instead of probing for unique field presence. `--legacy-envelope` removes only the document-root `kind` for one compatibility cycle. `CodeClimateOutput` is a bare JSON array (per the Code Climate / GitLab Code Quality spec) and stays a sibling root branch discriminated by checking whether the document root is an array.
|
|
28
|
+
* Schemas for the JSON output of fallow commands. Object-shaped envelopes covered by the `FallowOutput` contract carry a top-level `kind` discriminator (for example `dead-code`, `dead-code-grouped`, `health`, `dupes`, `combined`, `audit`, `explain`, `inspect_target`, `impact`, `security`, `coverage-setup`, `coverage-analyze`, `list-boundaries`, `review-envelope`, and `review-reconcile`). Consumers should branch on `kind` instead of probing for unique field presence. `--legacy-envelope` removes only the document-root `kind` for one compatibility cycle. `CodeClimateOutput` is a bare JSON array (per the Code Climate / GitLab Code Quality spec) and stays a sibling root branch discriminated by checking whether the document root is an array.
|
|
29
29
|
*/
|
|
30
30
|
export type FallowJsonOutput = (FallowOutput | CodeClimateOutput)
|
|
31
31
|
/**
|
|
@@ -51,6 +51,8 @@ export type FallowOutput = ((AuditOutput & {
|
|
|
51
51
|
kind: "audit"
|
|
52
52
|
}) | (ExplainOutput & {
|
|
53
53
|
kind: "explain"
|
|
54
|
+
}) | (InspectOutput & {
|
|
55
|
+
kind: "inspect_target"
|
|
54
56
|
}) | (ReviewEnvelopeOutput & {
|
|
55
57
|
kind: "review-envelope"
|
|
56
58
|
}) | (ReviewReconcileOutput & {
|
|
@@ -75,6 +77,10 @@ kind: "impact"
|
|
|
75
77
|
kind: "impact-cross-repo"
|
|
76
78
|
}) | ((SecurityOutput | SecuritySummaryOutput) & {
|
|
77
79
|
kind: "security"
|
|
80
|
+
}) | (SecuritySurvivorsOutput & {
|
|
81
|
+
kind: "security-survivors"
|
|
82
|
+
}) | (SecurityBlindSpotsOutput & {
|
|
83
|
+
kind: "security-blind-spots"
|
|
78
84
|
}) | (CheckOutput & {
|
|
79
85
|
kind: "dead-code"
|
|
80
86
|
}) | (CombinedOutput & {
|
|
@@ -138,10 +144,12 @@ export type AuditGate = ("new-only" | "all")
|
|
|
138
144
|
* Current per-instance flips:
|
|
139
145
|
*
|
|
140
146
|
* - `remove-catalog-entry` (`unused-catalog-entries`): `true` only when the
|
|
141
|
-
* finding's `hardcoded_consumers` array is empty
|
|
142
|
-
* package still pins a hardcoded
|
|
143
|
-
*
|
|
144
|
-
*
|
|
147
|
+
* finding's `hardcoded_consumers` array is empty and the source is
|
|
148
|
+
* `pnpm-workspace.yaml`. When a workspace package still pins a hardcoded
|
|
149
|
+
* version of the same package, `fallow fix` skips the entry to avoid
|
|
150
|
+
* breaking `pnpm install`. Bun `package.json` catalog entries are also
|
|
151
|
+
* emitted with `auto_fixable: false` because the current fixer is
|
|
152
|
+
* YAML-only.
|
|
145
153
|
* - `remove-dependency` vs `move-dependency` (dependency findings): when the
|
|
146
154
|
* finding's `used_in_workspaces` array is non-empty, the primary action
|
|
147
155
|
* flips to `move-dependency` with `auto_fixable: false` (`fallow fix` will
|
|
@@ -172,7 +180,7 @@ export type IssueAction = (FixAction | SuppressLineAction | SuppressFileAction |
|
|
|
172
180
|
* Discriminant string for [`FixAction`]. Kebab-case per the JSON output
|
|
173
181
|
* contract.
|
|
174
182
|
*/
|
|
175
|
-
export type FixActionType = ("remove-export" | "delete-file" | "remove-dependency" | "move-dependency" | "remove-enum-member" | "remove-class-member" | "resolve-import" | "install-dependency" | "remove-duplicate" | "move-to-dev" | "refactor-cycle" | "refactor-re-export-cycle" | "refactor-boundary" | "export-type" | "remove-catalog-entry" | "remove-empty-catalog-group" | "update-catalog-reference" | "add-catalog-entry" | "remove-catalog-reference" | "remove-dependency-override" | "fix-dependency-override" | "resolve-policy-violation" | "move-to-server-module" | "split-mixed-barrel" | "hoist-directive" | "wire-server-action" | "provide-inject" | "use-load-data" | "render-component" | "use-component-prop" | "emit-component-event" | "wire-svelte-event" | "resolve-route-collision" | "resolve-dynamic-segment-name-conflict")
|
|
183
|
+
export type FixActionType = ("remove-export" | "delete-file" | "remove-dependency" | "move-dependency" | "remove-enum-member" | "remove-class-member" | "resolve-import" | "install-dependency" | "remove-duplicate" | "move-to-dev" | "refactor-cycle" | "refactor-re-export-cycle" | "refactor-boundary" | "export-type" | "remove-catalog-entry" | "remove-empty-catalog-group" | "update-catalog-reference" | "add-catalog-entry" | "remove-catalog-reference" | "remove-dependency-override" | "fix-dependency-override" | "resolve-policy-violation" | "move-to-server-module" | "split-mixed-barrel" | "hoist-directive" | "wire-server-action" | "provide-inject" | "use-load-data" | "render-component" | "use-component-prop" | "emit-component-event" | "wire-svelte-event" | "resolve-route-collision" | "resolve-dynamic-segment-name-conflict" | "add-suppression-reason" | "remove-stale-suppression")
|
|
176
184
|
/**
|
|
177
185
|
* Singleton discriminant for [`SuppressLineAction`].
|
|
178
186
|
*/
|
|
@@ -237,7 +245,7 @@ export type ReExportCycleKind = ("multi-node" | "self-loop")
|
|
|
237
245
|
/**
|
|
238
246
|
* Which rule-pack rule kind produced a [`PolicyViolation`].
|
|
239
247
|
*/
|
|
240
|
-
export type PolicyRuleKind = ("banned-call" | "banned-import")
|
|
248
|
+
export type PolicyRuleKind = ("banned-call" | "banned-import" | "banned-effect")
|
|
241
249
|
/**
|
|
242
250
|
* Effective severity of a single [`PolicyViolation`]. Per-rule `severity`
|
|
243
251
|
* overrides the `rules."policy-violation"` master; `off` rules emit nothing,
|
|
@@ -253,6 +261,10 @@ export type SuppressionOrigin = ({
|
|
|
253
261
|
* The issue kind token from the comment (e.g., "unused-exports"), or None for blanket.
|
|
254
262
|
*/
|
|
255
263
|
issue_kind?: (string | null)
|
|
264
|
+
/**
|
|
265
|
+
* Human-authored reason after `--`, when present.
|
|
266
|
+
*/
|
|
267
|
+
reason?: (string | null)
|
|
256
268
|
/**
|
|
257
269
|
* Whether this was a file-level suppression.
|
|
258
270
|
*/
|
|
@@ -272,6 +284,10 @@ type: "comment"
|
|
|
272
284
|
* The name of the export that was tagged.
|
|
273
285
|
*/
|
|
274
286
|
export_name: string
|
|
287
|
+
/**
|
|
288
|
+
* Human-authored reason after `--`, when present.
|
|
289
|
+
*/
|
|
290
|
+
reason?: (string | null)
|
|
275
291
|
type: "jsdoc_tag"
|
|
276
292
|
})
|
|
277
293
|
/**
|
|
@@ -563,6 +579,10 @@ export type RefactoringTargetActionType = ("apply-refactoring" | "suppress-line"
|
|
|
563
579
|
* Direction of a metric's change, semantically (improving/declining/stable).
|
|
564
580
|
*/
|
|
565
581
|
export type TrendDirection = ("improving" | "declining" | "stable")
|
|
582
|
+
/**
|
|
583
|
+
* Detector status codes for framework health observability.
|
|
584
|
+
*/
|
|
585
|
+
export type FrameworkHealthDetectorStatus = ("active" | "disabled_by_config" | "abstained" | "not_checked")
|
|
566
586
|
/**
|
|
567
587
|
* Discriminant for [`CssCandidateAction::kind`].
|
|
568
588
|
*/
|
|
@@ -571,6 +591,17 @@ export type CssCandidateActionType = ("verify-unused" | "verify-undefined" | "co
|
|
|
571
591
|
* Discriminant for [`UnusedAtRule::kind`].
|
|
572
592
|
*/
|
|
573
593
|
export type UnusedAtRuleKind = ("property-registration" | "layer")
|
|
594
|
+
export type InspectTargetDescriptor = ({
|
|
595
|
+
file: string
|
|
596
|
+
type: "file"
|
|
597
|
+
} | {
|
|
598
|
+
file: string
|
|
599
|
+
export_name: string
|
|
600
|
+
type: "symbol"
|
|
601
|
+
})
|
|
602
|
+
export type InspectIdentity = (InspectFileIdentity | InspectSymbolIdentity)
|
|
603
|
+
export type InspectSectionStatus = ("ok" | "error")
|
|
604
|
+
export type InspectEvidenceScope = ("symbol" | "file" | "project_filtered_to_file")
|
|
574
605
|
/**
|
|
575
606
|
* Singleton GitHub review-event marker.
|
|
576
607
|
*/
|
|
@@ -720,6 +751,18 @@ export type SkippedSecurityCalleeReason = ("computed-member" | "dynamic-dispatch
|
|
|
720
751
|
* Syntactic expression shape for a skipped security callee.
|
|
721
752
|
*/
|
|
722
753
|
export type SkippedSecurityCalleeExpressionKind = ("static-member-expression" | "computed-member-expression" | "identifier" | "other")
|
|
754
|
+
/**
|
|
755
|
+
* The `fallow security survivors --format json` schema version.
|
|
756
|
+
*/
|
|
757
|
+
export type SecuritySurvivorsSchemaVersion = "2"
|
|
758
|
+
/**
|
|
759
|
+
* Verifier verdict status accepted by `fallow security survivors`.
|
|
760
|
+
*/
|
|
761
|
+
export type SecurityVerifierVerdictStatus = ("survivor" | "dismissed" | "needs-human-review")
|
|
762
|
+
/**
|
|
763
|
+
* The `fallow security blind-spots --format json` schema version.
|
|
764
|
+
*/
|
|
765
|
+
export type SecurityBlindSpotsSchemaVersion = "1"
|
|
723
766
|
/**
|
|
724
767
|
* Discriminator value for [`CodeClimateIssue::kind`].
|
|
725
768
|
*/
|
|
@@ -1021,7 +1064,8 @@ boundary_coverage_violations?: BoundaryCoverageViolationFinding[]
|
|
|
1021
1064
|
*/
|
|
1022
1065
|
boundary_call_violations?: BoundaryCallViolationFinding[]
|
|
1023
1066
|
/**
|
|
1024
|
-
* Banned calls and
|
|
1067
|
+
* Banned calls, imports, and catalogue-derived effects matched by
|
|
1068
|
+
* declarative rule packs
|
|
1025
1069
|
* (`rulePacks` config). Wrapped in [`PolicyViolationFinding`] so each
|
|
1026
1070
|
* entry carries a typed `actions` array natively. Each finding carries
|
|
1027
1071
|
* its effective per-rule severity.
|
|
@@ -1032,24 +1076,25 @@ policy_violations?: PolicyViolationFinding[]
|
|
|
1032
1076
|
*/
|
|
1033
1077
|
stale_suppressions?: StaleSuppression[]
|
|
1034
1078
|
/**
|
|
1035
|
-
* Entries in
|
|
1036
|
-
*
|
|
1037
|
-
*
|
|
1079
|
+
* Entries in package manager catalog sections not referenced by any
|
|
1080
|
+
* workspace package via the catalog: protocol. Supports
|
|
1081
|
+
* `pnpm-workspace.yaml` catalogs and Bun root `package.json` catalogs.
|
|
1082
|
+
* Wrapped in [`UnusedCatalogEntryFinding`] so each entry carries a typed
|
|
1038
1083
|
* `actions` array natively, with per-instance `auto_fixable` derived
|
|
1039
|
-
* from `hardcoded_consumers
|
|
1084
|
+
* from `hardcoded_consumers` and the catalog source file.
|
|
1040
1085
|
*/
|
|
1041
1086
|
unused_catalog_entries?: UnusedCatalogEntryFinding[]
|
|
1042
1087
|
/**
|
|
1043
|
-
* Named groups under
|
|
1044
|
-
*
|
|
1045
|
-
*
|
|
1088
|
+
* Named groups under package manager catalogs sections that declare no
|
|
1089
|
+
* package entries. The top-level catalog: map is not reported. Wrapped in
|
|
1090
|
+
* [`EmptyCatalogGroupFinding`].
|
|
1046
1091
|
*/
|
|
1047
1092
|
empty_catalog_groups?: EmptyCatalogGroupFinding[]
|
|
1048
1093
|
/**
|
|
1049
1094
|
* Workspace package.json references to catalogs (`catalog:` or
|
|
1050
|
-
* `catalog:<name>`) that do not declare the consumed package.
|
|
1051
|
-
* will error until the named catalog grows to include the
|
|
1052
|
-
* reference is switched / removed. Wrapped in
|
|
1095
|
+
* `catalog:<name>`) that do not declare the consumed package. The package
|
|
1096
|
+
* manager install will error until the named catalog grows to include the
|
|
1097
|
+
* package or the reference is switched / removed. Wrapped in
|
|
1053
1098
|
* [`UnresolvedCatalogReferenceFinding`] with the discriminated
|
|
1054
1099
|
* `add-catalog-entry` / `update-catalog-reference` primary at position 0.
|
|
1055
1100
|
*/
|
|
@@ -1121,8 +1166,8 @@ route_collisions?: RouteCollisionFinding[]
|
|
|
1121
1166
|
*/
|
|
1122
1167
|
dynamic_segment_name_conflicts?: DynamicSegmentNameConflictFinding[]
|
|
1123
1168
|
/**
|
|
1124
|
-
* Vue `<script setup>` `defineProps
|
|
1125
|
-
*
|
|
1169
|
+
* Vue `<script setup>` `defineProps`, Svelte 5 `$props()`, and React props
|
|
1170
|
+
* referenced nowhere in their own component. Wrapped in
|
|
1126
1171
|
* [`UnusedComponentPropFinding`] so each entry carries a typed `actions`
|
|
1127
1172
|
* array natively. Default severity is `warn`.
|
|
1128
1173
|
*/
|
|
@@ -1292,7 +1337,7 @@ unprovided_injects?: number
|
|
|
1292
1337
|
*/
|
|
1293
1338
|
unrendered_components?: number
|
|
1294
1339
|
/**
|
|
1295
|
-
* Vue
|
|
1340
|
+
* Vue, Svelte, or React props referenced nowhere inside their own component.
|
|
1296
1341
|
*/
|
|
1297
1342
|
unused_component_props?: number
|
|
1298
1343
|
/**
|
|
@@ -1365,7 +1410,8 @@ boundary_coverage_violations?: number
|
|
|
1365
1410
|
*/
|
|
1366
1411
|
boundary_call_violations?: number
|
|
1367
1412
|
/**
|
|
1368
|
-
* Banned calls and
|
|
1413
|
+
* Banned calls, imports, and catalogue-derived effects matched by
|
|
1414
|
+
* declarative rule packs.
|
|
1369
1415
|
*/
|
|
1370
1416
|
policy_violations?: number
|
|
1371
1417
|
/**
|
|
@@ -1452,11 +1498,12 @@ type: FixActionType
|
|
|
1452
1498
|
* FINDING, not per action type: the same `type` may carry
|
|
1453
1499
|
* `auto_fixable: true` on one finding and `auto_fixable: false` on
|
|
1454
1500
|
* another when per-instance guards in the applier discriminate (e.g.
|
|
1455
|
-
* `remove-catalog-entry` flips on `hardcoded_consumers
|
|
1456
|
-
* dependency action flips between
|
|
1457
|
-
* `move-dependency` on `used_in_workspaces`).
|
|
1458
|
-
* each individual action, not on `type`. See the
|
|
1459
|
-
* enum-level docs for the full list of per-instance
|
|
1501
|
+
* `remove-catalog-entry` flips on `hardcoded_consumers` and catalog
|
|
1502
|
+
* source file, the primary dependency action flips between
|
|
1503
|
+
* `remove-dependency` / `move-dependency` on `used_in_workspaces`).
|
|
1504
|
+
* Filter on this bool of each individual action, not on `type`. See the
|
|
1505
|
+
* [`IssueAction`] enum-level docs for the full list of per-instance
|
|
1506
|
+
* flips.
|
|
1460
1507
|
*/
|
|
1461
1508
|
auto_fixable: boolean
|
|
1462
1509
|
/**
|
|
@@ -2122,7 +2169,7 @@ introduced?: (AuditIntroduced | null)
|
|
|
2122
2169
|
*/
|
|
2123
2170
|
export interface TestOnlyDependencyFinding {
|
|
2124
2171
|
/**
|
|
2125
|
-
* Production dependency that is only imported by test files
|
|
2172
|
+
* Production dependency that is only imported by test files, consider
|
|
2126
2173
|
* moving to devDependencies.
|
|
2127
2174
|
*/
|
|
2128
2175
|
package_name: string
|
|
@@ -2364,12 +2411,12 @@ introduced?: (AuditIntroduced | null)
|
|
|
2364
2411
|
}
|
|
2365
2412
|
/**
|
|
2366
2413
|
* Wire-shape envelope for a [`PolicyViolation`] finding. Carries actions for
|
|
2367
|
-
* replacing the banned call or
|
|
2414
|
+
* replacing the banned call, import, or effect, or suppressing it with a scoped
|
|
2368
2415
|
* `policy-violation:<pack>/<rule-id>` token.
|
|
2369
2416
|
*/
|
|
2370
2417
|
export interface PolicyViolationFinding {
|
|
2371
2418
|
/**
|
|
2372
|
-
* The source file containing the banned call or
|
|
2419
|
+
* The source file containing the banned call, import, or effectful usage.
|
|
2373
2420
|
*/
|
|
2374
2421
|
path: string
|
|
2375
2422
|
/**
|
|
@@ -2392,8 +2439,8 @@ rule_id: string
|
|
|
2392
2439
|
kind: PolicyRuleKind
|
|
2393
2440
|
/**
|
|
2394
2441
|
* What matched: the written callee path for `banned-call` (e.g.
|
|
2395
|
-
* `cp.exec`),
|
|
2396
|
-
* `moment/locale/nl`)
|
|
2442
|
+
* `cp.exec`), the raw import specifier for `banned-import` (e.g.
|
|
2443
|
+
* `moment/locale/nl`), or `<effect>: <callee>` for `banned-effect`.
|
|
2397
2444
|
*/
|
|
2398
2445
|
matched: string
|
|
2399
2446
|
severity: PolicyViolationSeverity
|
|
@@ -2428,12 +2475,20 @@ line: number
|
|
|
2428
2475
|
*/
|
|
2429
2476
|
col: number
|
|
2430
2477
|
origin: SuppressionOrigin
|
|
2478
|
+
/**
|
|
2479
|
+
* True when `rules.require-suppression-reason` reported a suppression
|
|
2480
|
+
* comment or tag that has no reason.
|
|
2481
|
+
*/
|
|
2482
|
+
missing_reason?: boolean
|
|
2483
|
+
/**
|
|
2484
|
+
* Suggested next steps. Always emitted.
|
|
2485
|
+
*/
|
|
2486
|
+
actions: IssueAction[]
|
|
2431
2487
|
}
|
|
2432
2488
|
/**
|
|
2433
2489
|
* Wire-shape envelope for an [`UnusedCatalogEntry`] finding. Per-instance
|
|
2434
|
-
* `auto_fixable` flips to `false` when `hardcoded_consumers` is non-empty
|
|
2435
|
-
* the
|
|
2436
|
-
* the same package via a hardcoded version range.
|
|
2490
|
+
* `auto_fixable` flips to `false` when `hardcoded_consumers` is non-empty or
|
|
2491
|
+
* the source is not `pnpm-workspace.yaml`.
|
|
2437
2492
|
*/
|
|
2438
2493
|
export interface UnusedCatalogEntryFinding {
|
|
2439
2494
|
/**
|
|
@@ -2441,16 +2496,16 @@ export interface UnusedCatalogEntryFinding {
|
|
|
2441
2496
|
*/
|
|
2442
2497
|
entry_name: string
|
|
2443
2498
|
/**
|
|
2444
|
-
* Catalog group: `"default"` for the
|
|
2445
|
-
*
|
|
2499
|
+
* Catalog group: `"default"` for the default catalog map, or the named
|
|
2500
|
+
* catalog key for entries declared under `catalogs.<name>`.
|
|
2446
2501
|
*/
|
|
2447
2502
|
catalog_name: string
|
|
2448
2503
|
/**
|
|
2449
|
-
* Path to
|
|
2504
|
+
* Path to the catalog source file, relative to the analyzed root.
|
|
2450
2505
|
*/
|
|
2451
2506
|
path: string
|
|
2452
2507
|
/**
|
|
2453
|
-
* 1-based line number of the catalog entry within
|
|
2508
|
+
* 1-based line number of the catalog entry within the source file.
|
|
2454
2509
|
*/
|
|
2455
2510
|
line: number
|
|
2456
2511
|
/**
|
|
@@ -2472,20 +2527,20 @@ introduced?: (AuditIntroduced | null)
|
|
|
2472
2527
|
}
|
|
2473
2528
|
/**
|
|
2474
2529
|
* Wire-shape envelope for an [`EmptyCatalogGroup`] finding. Carries a
|
|
2475
|
-
*
|
|
2476
|
-
* suppress.
|
|
2530
|
+
* `remove-empty-catalog-group` primary. YAML-sourced findings also include a
|
|
2531
|
+
* YAML-comment suppress action.
|
|
2477
2532
|
*/
|
|
2478
2533
|
export interface EmptyCatalogGroupFinding {
|
|
2479
2534
|
/**
|
|
2480
|
-
* Catalog group name declared under the
|
|
2535
|
+
* Catalog group name declared under the `catalogs` map.
|
|
2481
2536
|
*/
|
|
2482
2537
|
catalog_name: string
|
|
2483
2538
|
/**
|
|
2484
|
-
* Path to
|
|
2539
|
+
* Path to the catalog source file, relative to the analyzed root.
|
|
2485
2540
|
*/
|
|
2486
2541
|
path: string
|
|
2487
2542
|
/**
|
|
2488
|
-
* 1-based line number of the empty group header within
|
|
2543
|
+
* 1-based line number of the empty group header within the source file.
|
|
2489
2544
|
*/
|
|
2490
2545
|
line: number
|
|
2491
2546
|
/**
|
|
@@ -2531,10 +2586,10 @@ path: string
|
|
|
2531
2586
|
*/
|
|
2532
2587
|
line: number
|
|
2533
2588
|
/**
|
|
2534
|
-
* Other catalogs
|
|
2535
|
-
*
|
|
2536
|
-
*
|
|
2537
|
-
*
|
|
2589
|
+
* Other catalogs in the same catalog source that DO declare this package.
|
|
2590
|
+
* Empty when no catalog has the package. Sorted lexicographically. Lets
|
|
2591
|
+
* agents and humans decide whether to switch the reference to a different
|
|
2592
|
+
* catalog or to add the entry to the named catalog.
|
|
2538
2593
|
*/
|
|
2539
2594
|
available_in_catalogs?: string[]
|
|
2540
2595
|
/**
|
|
@@ -2956,11 +3011,11 @@ introduced?: (AuditIntroduced | null)
|
|
|
2956
3011
|
*/
|
|
2957
3012
|
export interface UnusedComponentPropFinding {
|
|
2958
3013
|
/**
|
|
2959
|
-
* The
|
|
3014
|
+
* The component file declaring the unused prop.
|
|
2960
3015
|
*/
|
|
2961
3016
|
path: string
|
|
2962
3017
|
/**
|
|
2963
|
-
* The component name
|
|
3018
|
+
* The component name.
|
|
2964
3019
|
*/
|
|
2965
3020
|
component_name: string
|
|
2966
3021
|
/**
|
|
@@ -3900,6 +3955,11 @@ health_trend?: (HealthTrend | null)
|
|
|
3900
3955
|
* back to the report root.
|
|
3901
3956
|
*/
|
|
3902
3957
|
actions_meta?: (HealthActionsMeta | null)
|
|
3958
|
+
/**
|
|
3959
|
+
* Optional framework-specific detector coverage. Present only when the
|
|
3960
|
+
* health run already needed the dead-code analysis output.
|
|
3961
|
+
*/
|
|
3962
|
+
framework_health?: (FrameworkHealthDiagnostics | null)
|
|
3903
3963
|
/**
|
|
3904
3964
|
* Structural CSS analytics (specificity hotspots, `!important` density,
|
|
3905
3965
|
* over-complex selectors, deep nesting). Present only with `--css`.
|
|
@@ -5537,6 +5597,37 @@ reason: string
|
|
|
5537
5597
|
*/
|
|
5538
5598
|
scope: string
|
|
5539
5599
|
}
|
|
5600
|
+
/**
|
|
5601
|
+
* Framework-specific health detector coverage surfaced for agent consumers.
|
|
5602
|
+
*/
|
|
5603
|
+
export interface FrameworkHealthDiagnostics {
|
|
5604
|
+
/**
|
|
5605
|
+
* Detected framework IDs, sorted and deduplicated.
|
|
5606
|
+
*/
|
|
5607
|
+
detected_frameworks: string[]
|
|
5608
|
+
/**
|
|
5609
|
+
* Detector coverage for the detected frameworks.
|
|
5610
|
+
*/
|
|
5611
|
+
detectors: FrameworkHealthDetector[]
|
|
5612
|
+
}
|
|
5613
|
+
/**
|
|
5614
|
+
* Status for one framework-specific health detector.
|
|
5615
|
+
*/
|
|
5616
|
+
export interface FrameworkHealthDetector {
|
|
5617
|
+
/**
|
|
5618
|
+
* Rule or detector ID, matching fallow's stable rule names where possible.
|
|
5619
|
+
*/
|
|
5620
|
+
id: string
|
|
5621
|
+
/**
|
|
5622
|
+
* Framework ID that made this detector relevant.
|
|
5623
|
+
*/
|
|
5624
|
+
framework: string
|
|
5625
|
+
status: FrameworkHealthDetectorStatus
|
|
5626
|
+
/**
|
|
5627
|
+
* Stable reason code for non-active statuses.
|
|
5628
|
+
*/
|
|
5629
|
+
reason?: (string | null)
|
|
5630
|
+
}
|
|
5540
5631
|
/**
|
|
5541
5632
|
* Structural CSS analytics surfaced by `fallow health --css`.
|
|
5542
5633
|
*/
|
|
@@ -6330,6 +6421,45 @@ example: string
|
|
|
6330
6421
|
how_to_fix: string
|
|
6331
6422
|
docs: string
|
|
6332
6423
|
}
|
|
6424
|
+
/**
|
|
6425
|
+
* Envelope emitted by `fallow inspect --format json`.
|
|
6426
|
+
*/
|
|
6427
|
+
export interface InspectOutput {
|
|
6428
|
+
target: InspectTargetDescriptor
|
|
6429
|
+
identity: InspectIdentity
|
|
6430
|
+
evidence: InspectEvidence
|
|
6431
|
+
warnings: string[]
|
|
6432
|
+
}
|
|
6433
|
+
export interface InspectFileIdentity {
|
|
6434
|
+
file: string
|
|
6435
|
+
is_reachable?: unknown
|
|
6436
|
+
is_entry_point?: unknown
|
|
6437
|
+
export_count?: (number | null)
|
|
6438
|
+
import_count?: (number | null)
|
|
6439
|
+
imported_by_count?: (number | null)
|
|
6440
|
+
}
|
|
6441
|
+
export interface InspectSymbolIdentity {
|
|
6442
|
+
file: string
|
|
6443
|
+
export_name: string
|
|
6444
|
+
file_reachable?: unknown
|
|
6445
|
+
is_entry_point?: unknown
|
|
6446
|
+
is_used?: unknown
|
|
6447
|
+
reason?: unknown
|
|
6448
|
+
}
|
|
6449
|
+
export interface InspectEvidence {
|
|
6450
|
+
trace_file: InspectEvidenceSection
|
|
6451
|
+
trace_export?: (InspectEvidenceSection | null)
|
|
6452
|
+
dead_code: InspectEvidenceSection
|
|
6453
|
+
duplication: InspectEvidenceSection
|
|
6454
|
+
complexity: InspectEvidenceSection
|
|
6455
|
+
security: InspectEvidenceSection
|
|
6456
|
+
}
|
|
6457
|
+
export interface InspectEvidenceSection {
|
|
6458
|
+
status: InspectSectionStatus
|
|
6459
|
+
scope: InspectEvidenceScope
|
|
6460
|
+
message?: (string | null)
|
|
6461
|
+
data?: unknown
|
|
6462
|
+
}
|
|
6333
6463
|
/**
|
|
6334
6464
|
* Envelope emitted by `fallow --format review-github` / `review-gitlab`.
|
|
6335
6465
|
*/
|
|
@@ -6684,6 +6814,11 @@ health_trend?: (HealthTrend | null)
|
|
|
6684
6814
|
* back to the report root.
|
|
6685
6815
|
*/
|
|
6686
6816
|
actions_meta?: (HealthActionsMeta | null)
|
|
6817
|
+
/**
|
|
6818
|
+
* Optional framework-specific detector coverage. Present only when the
|
|
6819
|
+
* health run already needed the dead-code analysis output.
|
|
6820
|
+
*/
|
|
6821
|
+
framework_health?: (FrameworkHealthDiagnostics | null)
|
|
6687
6822
|
/**
|
|
6688
6823
|
* Structural CSS analytics (specificity hotspots, `!important` density,
|
|
6689
6824
|
* over-complex selectors, deep nesting). Present only with `--css`.
|
|
@@ -7106,7 +7241,8 @@ boundary_coverage_violations?: BoundaryCoverageViolationFinding[]
|
|
|
7106
7241
|
*/
|
|
7107
7242
|
boundary_call_violations?: BoundaryCallViolationFinding[]
|
|
7108
7243
|
/**
|
|
7109
|
-
* Banned calls and
|
|
7244
|
+
* Banned calls, imports, and catalogue-derived effects matched by
|
|
7245
|
+
* declarative rule packs
|
|
7110
7246
|
* (`rulePacks` config). Wrapped in [`PolicyViolationFinding`] so each
|
|
7111
7247
|
* entry carries a typed `actions` array natively. Each finding carries
|
|
7112
7248
|
* its effective per-rule severity.
|
|
@@ -7117,24 +7253,25 @@ policy_violations?: PolicyViolationFinding[]
|
|
|
7117
7253
|
*/
|
|
7118
7254
|
stale_suppressions?: StaleSuppression[]
|
|
7119
7255
|
/**
|
|
7120
|
-
* Entries in
|
|
7121
|
-
*
|
|
7122
|
-
*
|
|
7256
|
+
* Entries in package manager catalog sections not referenced by any
|
|
7257
|
+
* workspace package via the catalog: protocol. Supports
|
|
7258
|
+
* `pnpm-workspace.yaml` catalogs and Bun root `package.json` catalogs.
|
|
7259
|
+
* Wrapped in [`UnusedCatalogEntryFinding`] so each entry carries a typed
|
|
7123
7260
|
* `actions` array natively, with per-instance `auto_fixable` derived
|
|
7124
|
-
* from `hardcoded_consumers
|
|
7261
|
+
* from `hardcoded_consumers` and the catalog source file.
|
|
7125
7262
|
*/
|
|
7126
7263
|
unused_catalog_entries?: UnusedCatalogEntryFinding[]
|
|
7127
7264
|
/**
|
|
7128
|
-
* Named groups under
|
|
7129
|
-
*
|
|
7130
|
-
*
|
|
7265
|
+
* Named groups under package manager catalogs sections that declare no
|
|
7266
|
+
* package entries. The top-level catalog: map is not reported. Wrapped in
|
|
7267
|
+
* [`EmptyCatalogGroupFinding`].
|
|
7131
7268
|
*/
|
|
7132
7269
|
empty_catalog_groups?: EmptyCatalogGroupFinding[]
|
|
7133
7270
|
/**
|
|
7134
7271
|
* Workspace package.json references to catalogs (`catalog:` or
|
|
7135
|
-
* `catalog:<name>`) that do not declare the consumed package.
|
|
7136
|
-
* will error until the named catalog grows to include the
|
|
7137
|
-
* reference is switched / removed. Wrapped in
|
|
7272
|
+
* `catalog:<name>`) that do not declare the consumed package. The package
|
|
7273
|
+
* manager install will error until the named catalog grows to include the
|
|
7274
|
+
* package or the reference is switched / removed. Wrapped in
|
|
7138
7275
|
* [`UnresolvedCatalogReferenceFinding`] with the discriminated
|
|
7139
7276
|
* `add-catalog-entry` / `update-catalog-reference` primary at position 0.
|
|
7140
7277
|
*/
|
|
@@ -7206,8 +7343,8 @@ route_collisions?: RouteCollisionFinding[]
|
|
|
7206
7343
|
*/
|
|
7207
7344
|
dynamic_segment_name_conflicts?: DynamicSegmentNameConflictFinding[]
|
|
7208
7345
|
/**
|
|
7209
|
-
* Vue `<script setup>` `defineProps
|
|
7210
|
-
*
|
|
7346
|
+
* Vue `<script setup>` `defineProps`, Svelte 5 `$props()`, and React props
|
|
7347
|
+
* referenced nowhere in their own component. Wrapped in
|
|
7211
7348
|
* [`UnusedComponentPropFinding`] so each entry carries a typed `actions`
|
|
7212
7349
|
* array natively. Default severity is `warn`.
|
|
7213
7350
|
*/
|
|
@@ -8162,6 +8299,123 @@ coverage_unavailable: number
|
|
|
8162
8299
|
runtime_unknown: number
|
|
8163
8300
|
not_collected: number
|
|
8164
8301
|
}
|
|
8302
|
+
/**
|
|
8303
|
+
* The `fallow security survivors --format json` envelope.
|
|
8304
|
+
*/
|
|
8305
|
+
export interface SecuritySurvivorsOutput {
|
|
8306
|
+
schema_version: SecuritySurvivorsSchemaVersion
|
|
8307
|
+
version: ToolVersion
|
|
8308
|
+
elapsed_ms: ElapsedMs
|
|
8309
|
+
summary: SecuritySurvivorsSummary
|
|
8310
|
+
/**
|
|
8311
|
+
* Verifier-retained candidates keyed by finding id.
|
|
8312
|
+
*/
|
|
8313
|
+
survivors: {
|
|
8314
|
+
[k: string]: SecuritySurvivor
|
|
8315
|
+
}
|
|
8316
|
+
/**
|
|
8317
|
+
* Ambiguous candidates keyed by finding id. These are not dismissed and are
|
|
8318
|
+
* kept explicit so queues can decide whether to include them.
|
|
8319
|
+
*/
|
|
8320
|
+
needs_human_review: {
|
|
8321
|
+
[k: string]: SecuritySurvivor
|
|
8322
|
+
}
|
|
8323
|
+
}
|
|
8324
|
+
/**
|
|
8325
|
+
* Aggregate counts for survivor rendering.
|
|
8326
|
+
*/
|
|
8327
|
+
export interface SecuritySurvivorsSummary {
|
|
8328
|
+
candidates: number
|
|
8329
|
+
verdicts: number
|
|
8330
|
+
survivors: number
|
|
8331
|
+
dismissed: number
|
|
8332
|
+
needs_human_review: number
|
|
8333
|
+
unverdicted: number
|
|
8334
|
+
}
|
|
8335
|
+
/**
|
|
8336
|
+
* One verifier-retained candidate row.
|
|
8337
|
+
*/
|
|
8338
|
+
export interface SecuritySurvivor {
|
|
8339
|
+
/**
|
|
8340
|
+
* Stable candidate id from `security_findings[].finding_id`.
|
|
8341
|
+
*/
|
|
8342
|
+
finding_id: string
|
|
8343
|
+
verdict: SecurityVerifierVerdictStatus
|
|
8344
|
+
/**
|
|
8345
|
+
* Short verifier reason.
|
|
8346
|
+
*/
|
|
8347
|
+
reason?: (string | null)
|
|
8348
|
+
/**
|
|
8349
|
+
* Short verifier rationale.
|
|
8350
|
+
*/
|
|
8351
|
+
rationale?: (string | null)
|
|
8352
|
+
/**
|
|
8353
|
+
* Optional verifier-provided confidence or review priority.
|
|
8354
|
+
*/
|
|
8355
|
+
confidence?: (string | null)
|
|
8356
|
+
/**
|
|
8357
|
+
* Optional verifier-provided impact statement.
|
|
8358
|
+
*/
|
|
8359
|
+
impact?: (string | null)
|
|
8360
|
+
/**
|
|
8361
|
+
* Optional verifier-owned remediation direction.
|
|
8362
|
+
*/
|
|
8363
|
+
fix_direction?: (string | null)
|
|
8364
|
+
candidate: SecurityFinding
|
|
8365
|
+
}
|
|
8366
|
+
/**
|
|
8367
|
+
* The `fallow security blind-spots --format json` envelope.
|
|
8368
|
+
*/
|
|
8369
|
+
export interface SecurityBlindSpotsOutput {
|
|
8370
|
+
schema_version: SecurityBlindSpotsSchemaVersion
|
|
8371
|
+
version: ToolVersion
|
|
8372
|
+
elapsed_ms: ElapsedMs
|
|
8373
|
+
summary: SecurityBlindSpotsSummary
|
|
8374
|
+
/**
|
|
8375
|
+
* Grouped unresolved callee diagnostics, derived from existing samples.
|
|
8376
|
+
*/
|
|
8377
|
+
groups: SecurityBlindSpotGroup[]
|
|
8378
|
+
}
|
|
8379
|
+
/**
|
|
8380
|
+
* Aggregate counts for blind-spot output.
|
|
8381
|
+
*/
|
|
8382
|
+
export interface SecurityBlindSpotsSummary {
|
|
8383
|
+
unresolved_edge_files: number
|
|
8384
|
+
unresolved_callee_sites: number
|
|
8385
|
+
sampled_callee_sites: number
|
|
8386
|
+
}
|
|
8387
|
+
/**
|
|
8388
|
+
* One actionable blind-spot group.
|
|
8389
|
+
*/
|
|
8390
|
+
export interface SecurityBlindSpotGroup {
|
|
8391
|
+
reason: SkippedSecurityCalleeReason
|
|
8392
|
+
expression_kind: SkippedSecurityCalleeExpressionKind
|
|
8393
|
+
/**
|
|
8394
|
+
* Count in the bounded diagnostic sample.
|
|
8395
|
+
*/
|
|
8396
|
+
sampled_count: number
|
|
8397
|
+
/**
|
|
8398
|
+
* Top files in this bounded diagnostic sample.
|
|
8399
|
+
*/
|
|
8400
|
+
files: SecurityBlindSpotFile[]
|
|
8401
|
+
/**
|
|
8402
|
+
* Suggested next action for this group.
|
|
8403
|
+
*/
|
|
8404
|
+
suggestion: string
|
|
8405
|
+
}
|
|
8406
|
+
/**
|
|
8407
|
+
* One file inside a blind-spot group.
|
|
8408
|
+
*/
|
|
8409
|
+
export interface SecurityBlindSpotFile {
|
|
8410
|
+
/**
|
|
8411
|
+
* Project-relative source path.
|
|
8412
|
+
*/
|
|
8413
|
+
path: string
|
|
8414
|
+
/**
|
|
8415
|
+
* Count in the bounded diagnostic sample.
|
|
8416
|
+
*/
|
|
8417
|
+
sampled_count: number
|
|
8418
|
+
}
|
|
8165
8419
|
/**
|
|
8166
8420
|
* Bare `fallow --format json` envelope.
|
|
8167
8421
|
*/
|